# tofu.geom package¶

The geometry module of tofu

Provides classes to model the 3D geometry of: * the vacuum vessel and structural elements * LOS * apertures and detectors

## tofu.geom._GG module¶

`tofu.geom._GG.``CoordShift`()

Check the shape of an array of points coordinates and/or converts from 2D to 3D, 3D to 2D, cylindrical to cartesian… (CrossRef is an angle (Tor) or a distance (X for Lin))

`tofu.geom._GG.``comp_dist_los_circle`()

This function computes the intersection of a Ray (or Line Of Sight) and a circle in 3D. It returns kmin and dist. Where kmin is the coefficient such that the ray of origin O = [ori1, ori2, ori3] and of directional vector D = [dir1, dir2, dir3] is closest to the circle

P = O + kmin * D. And distance the distance between the two closest points (line closest and circle closest) The variable norm_dir is the squared norm of the direction of the ray. Params ===== ray_vdir: (3) double array

ray’s director vector V such that P in Ray iff P(t) = O + t*V

ray_orig(3) double array

ray’s origin coordinates O such that P in Ray iff P(t) = O + t*V

radius r of horizontal circle centered in (0,0,circ_z)

circ_zdouble

3rd coordinate of horizontal circle centered in (0,0,circ_z) of radius r

norm_dirdouble (optional)

If for computation reasons it makes sense, you can pass the norm of the director vector

Returns

• result (double (2) array) –

• result will contain the k coefficient to find the line point closest

closest point - result will contain the DISTANCE from line closest point to circle to the circle

• This is the PYTHON function, use only if you need this computation from

• Python, if you need it from cython, use dist_los_circle_core

`tofu.geom._GG.``comp_dist_los_circle_vec`()

This function computes the intersection of a Ray (or Line Of Sight) and a circle in 3D. It returns kmin, the coefficient such that the ray of origin O = [ori1, ori2, ori3] and of directional vector D = [dir1, dir2, dir3] is closest to the circle of radius radius and centered (0, 0, circ_z) at the point P = O + kmin * D. The variable norm_dir is the squared norm of the direction of the ray. This is the vectorial version, we expect the directions and origins to be: dirs = [[dir1_los1, dir2_los1, dir3_los1], [dir1_los2,…] oris = [[ori1_los1, ori2_los1, ori3_los1], [ori1_los2,…] :returns: * res ((2, nlos, ncircles)) – res = [res_k, res_d] where res_k is a (nlos, ncircles) numpy array

with the k coefficients for each LOS where the minimum distance to each circle is reached is met for each circle, and res_d is a (nlos, ncircles) numpy array with the distance between each LOS to each circle

• This is the PYTHON function, use only if you need this computation from

• Python, if you need it from cython, use dist_los_circle_core

`tofu.geom._GG.``comp_dist_los_vpoly`()

This function computes the distance (and the associated k) between nlos Rays (or LOS) and an IN structure (a polygon extruded around the axis (0,0,1), eg. a flux surface). For more details on the algorithm please see PDF: <name_of_pdf>.pdf #TODO

ray_orig(3, nlos) double array

LOS origin points coordinates

ray_vdir(3, nlos) double array

LOS normalized direction vector

ves_poly(2, num_vertex) double array

Coordinates of the vertices of the Polygon defining the 2D poloidal cut of the Vessel

eps_<val>double

Small value, acceptance of error

Returns

• kmin_vpoly ((nlos) double array) – Of the form [k_0, k_1, …, k_n], where k_i is the coefficient such that the i-th ray (LOS) is closest to the extruded polygon at the point P_i = orig[i] + kmin[i] * vdir[i]

• dist_vpoly ((nlos) double array) – distance[i] is the distance from P_i to the extruded polygon.

— This is the PYTHON function, use only if you need this computation from Python, if you need it from cython, use simple_dist_los_vpoly_core

`tofu.geom._GG.``comp_dist_los_vpoly_vec`()

This function computes the distance (and the associated k) between nlos Rays (or LOS) and several IN structures (polygons extruded around the axis (0,0,1), eg. flux surfaces). For more details on the algorithm please see PDF: <name_of_pdf>.pdf #TODO

nvpolyint

Number of flux surfaces

nlosint

Number of LOS

ray_orig(3, nlos) double array

LOS origin points coordinates

ray_vdir(3, nlos) double array

LOS normalized direction vector

ves_poly(num_pol, 2, num_vertex) double array

Coordinates of the vertices of the Polygon defining the 2D poloidal cut of the different IN surfaces WARNING : we suppose all poly are nested in each other,

from inner to outer

eps_<val>double

Small value, acceptance of error

Returns

• kmin_vpoly ((npoly, nlos) double array) – Of the form [k_00, k_01, …, k_0n, k_10, k_11, …, k_1n, …] where k_ij is the coefficient for the j-th flux surface such that the i-th ray (LOS) is closest to the extruded polygon at the point P_i = orig[i] + kmin[i] * vdir[i]

• dist_vpoly ((npoly, nlos) double array) – distance[i * num_poly + j] is the distance from P_i to the i-th extruded poly.

— This is the PYTHON function, use only if you need this computation from Python, if you need it from cython, use comp_dist_los_vpoly_vec_core

`tofu.geom._GG.``is_close_los_vpoly_vec`()

This function tests if the distance between nlos Rays (or LOS) and several IN structures (polygons extruded around the axis (0,0,1), eg. flux surfaces) is smaller than epsilon. For more details on the algorithm please see PDF: <name_of_pdf>.pdf #TODO

nvpolyint

Number of flux surfaces

nlosint

Number of LOS

ray_orig(3, nlos) double array

LOS origin points coordinates

ray_vdir(3, nlos) double array

LOS normalized direction vector

ves_poly(num_pol, 2, num_vertex) double array

Coordinates of the vertices of the Polygon defining the 2D poloidal cut of the different IN surfaces WARNING : we suppose all poly are nested in each other,

and the first one is the smallest one

epsilondouble

Value for testing if distance < epsilon

eps_<val>double

Small value, acceptance of error

Returns

are_close ((npoly * nlos) bool array) – are_close[i * num_poly + j] indicates if distance between i-th LOS and j-th poly are closer than epsilon. (True if distance<epsilon)

— This is the PYTHON function, use only if you need this computation from Python, if you need it from cython, use is_close_los_vpoly_vec_core

`tofu.geom._GG.``is_close_los_circle`()

This function checks if at maximum a LOS is at a distance epsilon form a cirlce The result is True when distance < epsilon — This is the PYTHON function, use only if you need this computation from Python, if you need it from cython, use is_los_close_circle_core

`tofu.geom._GG.``is_close_los_circle_vec`()

This function checks if at maximum a LOS is at a distance epsilon form a cirlce. Vectorial version The result is True when distance < epsilon — This is the PYTHON function, use only if you need this computation from Python, if you need it from cython, use is_los_close_circle_core

`tofu.geom._GG.``which_los_closer_vpoly_vec`()
nvpolyint

Number of flux surfaces

nlosint

Number of LOS

ray_orig(3, nlos) double array

LOS origin points coordinates

ray_vdir(3, nlos) double array

LOS direction vector

ves_poly(num_pol, 2, num_vertex) double array

Coordinates of the vertices of the Polygon defining the 2D poloidal cut of the different IN surfaces WARNING : we suppose all poly are nested in each other,

and the first one is the smallest one

eps_<val>double

Small value, acceptance of error

Returns

ind_close_los ((npoly) int array) – Of the form [ind_0, ind_1, …, ind_(npoly-1)] where ind_i is the coefficient for the i-th flux surface such that the ind_i-th ray (LOS) is closest to the extruded polygon among all other LOS without going over it.

— This is the PYTHON function, use only if you need this computation from Python, if you need it from cython, use which_los_closer_vpoly_vec_core

`tofu.geom._GG.``which_vpoly_closer_los_vec`()
nvpolyint

Number of flux surfaces

nlosint

Number of LOS

ray_orig(3, nlos) double array

LOS origin points coordinates

ray_vdir(3, nlos) double array

LOS direction vector

ves_poly(num_pol, 2, num_vertex) double array

Coordinates of the vertices of the Polygon defining the 2D poloidal cut of the different IN surfaces WARNING : we suppose all poly are nested in each other,

and the first one is the smallest one

eps_<val>double

Small value, acceptance of error

Returns

ind_close_los ((nlos) int array) – Of the form [ind_0, ind_1, …, ind_(nlos-1)] where ind_i is the coefficient for the i-th LOS (ray) such that the ind_i-th poly (flux surface) is closest to the LOS among all other poly without going over it.

— This is the PYTHON function, use only if you need this computation from Python, if you need it from cython, use which_vpoly_closer_los_vec_core

`tofu.geom._GG.``LOS_sino_findRootkPMin_Tor`()

Rendre “vectoriel” sur LOS et sur les cercles (deux boucles “for”) intersection ligne et cercle double uParN : composante de u parallel au plan (x,y)

double uN : uz double Sca : ??? produit scalaire … ? double RZ0 : Grand rayon du cercle double RZ1 : Z => cercle est centré au point (0, 0, RZ1) et rayon RZ0 double ScaP : …. ? double DParN : D origine de LOS…. ? N => norme de la composante du vecteur OD double kOut : kmax où on peut trouver un résultat double D0, double D1, double D2 : composantes de D (origine LOS) double u0, double u1, double u2 : composantes de U (direction LOS) str Mode=’LOS’ : si LOS pas de sol après kmax)

::: Faire une fonction double mais qui renvoit QUE un tableau de bool avec true si la distance est plus petite qu’un certain eps, false sinon. TODO: ……….. @LM

`tofu.geom._GG.``Poly_isClockwise`()

Assuming 2D closed Poly ! http://www.faqs.org/faqs/graphics/algorithms-faq/ Find the lowest vertex (or, if there is more than one vertex with the same lowest coordinate, the rightmost of those vertices) and then take the cross product of the edges before and after it. Both methods are O(n) for n vertices, but it does seem a waste to add up the total area when a single cross product (of just the right edges) suffices. Code for this is available at ftp://cs.smith.edu/pub/code/polyorient.C (2K).

`tofu.geom._GG.``Poly_VolAngTor`()
`tofu.geom._GG.``poly_area`()
`tofu.geom._GG.``poly_area_and_barycenter`()
`tofu.geom._GG.``Sino_ImpactEnv`()

Computes impact parameters of a Tor enveloppe (a Tor is a closed 2D polygon)

D. VEZINET, Aug. 2014 :param RZ: (2,) array indicating the reference impact point :type RZ: np.ndarray :param Poly: (2,N) array containing the coordinatesof a closed polygon :type Poly: np.ndarray :param NP: Number of indicating the number of points used for discretising theta between 0 and pi :type NP: int

Returns

theta

`tofu.geom._GG.``ConvertImpact_Theta2Xi`()
`tofu.geom._GG.``discretize_line1d`()

Discretize a 1D segment LMin-LMax. If mode is “abs” (absolute), then the segment will be discretized in cells each of size dstep. Else, if mode is “rel” (relative), the meshing step is relative to the segments norm (ie. the actual discretization step will be (LMax - LMin)/dstep). It is possible to only one to discretize the segment on a sub-domain. If so, the sub-domain limits are given in DL. :param LMinMax: Gives the limits LMin and LMax of the segment. LMinMax = [LMin, LMax] :type LMinMax: (2)-double array :param dstep: Step of discretization, can be absolute (default) or relative :type dstep: double :param DL: Sub domain of discretization. If not None and if Lim, LMinMax = DL

(can be only on one limit and can be bigger or smaller than original). Actual desired limits

Parameters
• Lim ((optional) bool) – Indicated if the subdomain should be taken into account

• mode ((optional) string) – If mode is “abs” (absolute), then the segment will be discretized in cells each of size dstep. Else, if “rel” (relative), the meshing step is relative to the segments norm (the actual discretization step will be (LMax - LMin)/dstep).

• margin ((optional) double) – Margin value for cell length

Returns

• ldiscret (double array) – array of the discretized coordinates on the segment of desired limits

• resolution (double) – step of discretization

• lindex (int array) – array of the indices corresponding to ldiscret with respects to the original segment LMinMax (if no DL, from 0 to N-1)

• N (int64) – Number of points on LMinMax segment

`tofu.geom._GG.``discretize_segment2d`()

Discretizes a 2D segment where the 1st coordinates are defined in LMinMax1 and the second ones in LMinMax2. The refinement in x is defined by dstep1, and dstep2 defines the resolution on y. Optionnally you can give a VPoly to which the discretized in which the segment has to be included. This function is basically a generalization of discretize_line1d. :param LMinMax1: Gives the limits LMin and LMax of the x coordinates of the segment.

LMinMax1 = [xmin, xmax]

Parameters
• LMinMax2 ((2)-double array) – Gives the limits LMin and LMax of the y coordinates of the segment. LMinMax2 = [ymin, ymax]

• or dstep2 (dstep1) – Step of discretization, can be absolute (default) or relative

• or D2 (D1) – Sub domain of discretization. If not None and if Lim, LMinMax = DL (can be only on one limit and can be bigger or smaller than original). Actual desired limits

• mode ((optional) string) – If mode is “abs” (absolute), then the segment will be discretized in cells each of size dstep. Else, if “rel” (relative), the meshing step is relative to the segments norm (the actual discretization step will be (LMax - LMin)/dstep).

• margin ((optional) double) – Margin value for cell length

• VPoly ((optional) 2d double array) – If present, we check that the discretized segment is included in the path defined by VPoly.

Returns

• ldiscret (double 2d array) – array of the discretized coordinates on the segment of desired limits

• resolution (double array) – step of discretization on 2d (typically resolution-on-x*resolution-on-y)

• lindex (int array) – array of the indices corresponding to ldiscret with respects to the original segment LMinMax (if no DL, from 0 to N-1)

• resol1 (double) – Smallest resolution on x

• resol2 (double) – Smallest resolution on y

`tofu.geom._GG.``discretize_vpoly`()

Discretizes a VPoly (2D polygon of a cross section in (R,Z) coordinates). The refinement on R and Z is defined dL. Optionnally you can give a coefficient (DIn) and the normal vectors going inwards the VPoly (VIn), and the result will be slightly shifted inwards (or outwards if DIn<0) of DIn*VIn. :param VPoly: Coordinates of the vertices of the Polygon defining the 2D poloidal

cut of the Vessel

Parameters
• dL (double) – Step of discretization, can be absolute (default) or relative

• or D2 (D1) – Sub domain of discretization. (can be only on one limit and can be bigger or smaller than original). Actual desired limits

• mode ((optional) string) – If mode is “abs” (absolute), then the segment will be discretized in cells each of size dstep. Else, if “rel” (relative), the meshing step is relative to the segments norm

• margin ((optional) double) – Margin value for cell length

Returns

• return PtsCross, resol, ind_arr, N_arr, Rref_arr, VPolybis

• PtsCross (double 2d array) – array of the discretized coordinates of the VPoly

• resol (double 1d array) – step of discretization on 2d

• ind_arr (int 1d array) – array of the indices corresponding to ldiscret with respects to the original VPoly

• N_arr (int 1d array) – number of cells on each segment of the VPoly

• Rref_arr (double 1d array) – reference Radius coordinates, not shifted even if DIn <> 0. If DIn == 0, then Rref_arr = PtsCross[0, …]

• VPolybis

`tofu.geom._GG.``LOS_Calc_PInOut_VesStruct`()

Computes the entry and exit point of all provided LOS for the provided vessel polygon (toroidal or linear) with its associated structures. Return the normal vector at impact and the index of the impact segment

ray_orig(3, nlos) double array

LOS origin points coordinates

ray_vdir(3, nlos) double array

LOS normalized direction vector

ves_poly(2, num_vertex) double array

Coordinates of the vertices of the Polygon defining the 2D poloidal cut of the Vessel

ves_norm(2, num_vertex-1) double array

Normal vectors going “inwards” of the edges of the Polygon defined by ves_poly

nstructint

Total number of structures (counting each limited structure as one)

ves_limsarray

Contains the limits min and max of vessel

lstruct_polylist

List of coordinates of the vertices of all structures on poloidal plane

lstruct_limslist

List of limits of all structures

lstruct_nlimarray of ints

List of number of limits for all structures

lstruct_normlist

List of coordinates of “inwards” normal vectors of the polygon of all the structures

rmindouble

Minimal radius of vessel to take into consideration

eps_<val>double

Small value, acceptance of error

vtypestring

Type of vessel (“Tor” or “Lin”)

forbidbool

Should we forbid values behind visible radius ? (see rmin)

testbool

Should we run tests ?

The num_threads argument indicates how many threads the team should consist of. If not given, OpenMP will decide how many threads to use. Typically this is the number of cores available on the machine.

Returns

• coeff_inter_in ((nlos) array) – scalars level of “in” intersection of the LOS (if k=0 at origin)

• coeff_inter_out ((nlos) array) – scalars level of “out” intersection of the LOS (if k=0 at origin)

• vperp_out ((3, nlos) array) – Coordinates of the normal vector of impact of the LOS (NaN if none)

• ind_inter_out ((3, nlos)) – Index of structure impacted by LOS: ind_inter_out[:,ind_los]=(i,j,k) where k is the index of edge impacted on the j-th sub structure of the structure number i. If the LOS impacted the vessel i=j=0

`tofu.geom._GG.``LOS_Calc_kMinkMax_VesStruct`()

Computes the entry and exit point of all provided LOS for the provided polygons (toroidal or linear) of IN structures (non-solid, or empty inside for the LOS). Attention: the surfaces can be limited, but they all have to have the same limits defined by (ves_lims) Return the set of kmin / kmax for each In struct and for each LOS

ray_orig(3, nlos) double array

LOS origin points coordinates

ray_vdir(3, nlos) double array

LOS normalized direction vector

num_surfint

number of surfaxes, aka ‘in’ structures or ‘vessels’

ves_poly(num_surf, 2, num_vertex) double array

Coordinates of the vertices of the Polygon defining the 2D poloidal cut of the in structures

ves_norm(num_surf, 2, num_vertex-1) double array

Normal vectors going “inwards” of the edges of the Polygon defined by ves_poly

ves_limsarray

Contains the limits min and max of vessel

rmindouble

Minimal radius of vessel to take into consideration

eps<val>double

Small value, acceptance of error

vtypestring

Type of vessel (“Tor” or “Lin”)

forbidbool

Should we forbid values behind visible radius ? (see rmin)

testbool

Should we run tests ?

The num_threads argument indicates how many threads the team should consist of. If not given, OpenMP will decide how many threads to use. Typically this is the number of cores available on the machine.

Returns

• coeff_inter_in ((num_surf, nlos) array) – scalars level of “in” intersection of the LOS (if k=0 at origin) for each surface [kmin(surf0, los0), kmin(surf0, los1), …, kmin(surf1, los0),….]

• coeff_inter_out ((num_surf, nlos) array) – scalars level of “out” intersection of the LOS (if k=0 at origin) for each surface [kmax(surf0, los0), kmax(surf0, los1), …, kmax(surf1, los0),….]

`tofu.geom._GG.``LOS_isVis_PtFromPts_VesStruct`()

Return an array of booleans indicating whether each point in pts is visible from the point P = [pt0, pt1, pt2] considering vignetting a given configuration.

k optional argument : distance between points and P ray_orig = np.tile(np.r_[pt0,pt1,pt2], (npts,1)).T ray_vdir = (pts-ray_orig)/k

`tofu.geom._GG.``LOS_areVis_PtsFromPts_VesStruct`()

Return an array of booleans indicating whether each point in pts is visible from the point P = [pt0, pt1, pt2] considering vignetting a given configuration.

k optional argument : distance between points and P ray_orig = np.tile(np.r_[pt0,pt1,pt2], (npts,1)).T ray_vdir = (pts-ray_orig)/k

`tofu.geom._GG.``LOS_get_sample`()

Return the sampled line, with the specified method - ‘sum’ : return N segments centers - ‘simps’: return N+1 egdes, N even (for scipy.integrate.simps) - ‘romb’ : return N+1 edges, N+1 = 2**k+1 (for scipy.integrate.romb)

The dmethod defines if the discretization step given is absolute (‘abs’) or relative (‘rel’)

dL: double or list of doubles

If dL is a single double: discretization step for all LOS. Else dL should be a list of size nlos with the discretization step for each nlos.

los_lims: (2, nlos) double array

For each nlos, it given the maximum and minimum limits of the ray

dmethod: string

type of discretization step: ‘abs’ for absolute or ‘rel’ for relative

method: string

method of quadrature on the LOS

Test: bool

to indicate if tests should be done or not

k, res, lind = Los_get_sample(…) nbrepet = np.r_[lind, np.diff(lind), k.size - lind[-1]] kus = k * np.repeat(ray_vdir, nbrepet, axis=1) Pts = np.repeat(ray_orig, nbrepet, axis=1) + kus

`tofu.geom._GG.``LOS_calc_signal`()

Compute the synthetic signal, minimizing either function calls or memory Params ===== func : python function st. func(pts, t=None, vect=None) => data

with ptsndarray (3, npts) - points where function is evaluated

vect : ndarray(3, npts) - if anisotropic signal vector of emiss. t: ndarray(m) - times where to compute the function

returns: datandarray(nt,nraf) if nt = 1, the array must be 2D

values of func at pts, at given time

func is the function to be integrated along the LOS

ray_orig: ndarray (3, nlos) LOS origins ray_vdir: ndarray (3, nlos) LOS directional vector res: double or list of doubles

If res is a single double: discretization step for all LOS. Else res should be a list of size nlos with the discretization step for each nlos.

lims: (2, nlos) double array

For each nlos, it given the maximum and minimum limits of the ray

dmethod: string

type of discretization step: ‘abs’ for absolute or ‘rel’ for relative

method: string

method of quadrature on the LOS

anibool

to indicate if emission is anisotropic or not

tNone or array-like

times where to integrate

minimize: string

“calls” : we use algorithm to minimize the calls to ‘func’ (default) “memory”: we use algorithm to minimize memory used “hybrid”: a mix of both methods

Testbool

we test if the inputs are giving in a proper way.

number of threads if we want to parallelize the code.

`tofu.geom._GG.``LOS_sino`()
`tofu.geom._GG.``integrate1d`()

Generic integration method [‘sum’,’simps’,’romb’]

Not used internally Useful when the sampling points need to be interpolated via equilibrium

`tofu.geom._GG.``triangulate_by_earclipping`()
`tofu.geom._GG.``vignetting`()
ray_orig(3, nlos) double array

LOS origin points coordinates

ray_vdir(3, nlos) double array

LOS normalized direction vector

vignett_poly(num_vign, 3, num_vertex) double list of arrays

Coordinates of the vertices of the Polygon defining the 3D vignett. POLY CLOSED

lnvert(num_vign) long array

Number of vertices for each vignett (without counting the rebound)

Returns

goes_through ((num_vign, nlos) bool array) – Indicates for each vignett if each LOS wents through or not

`tofu.geom._GG.``Dust_calc_SolidAngle`()

Compute the solid angle of a moving particle of varying radius as seen from any number of pixed points

Can be done w/o the approximation that r<<d If Ves (and optionally LSPoly) are provided, takes into account vignetting

## tofu.geom._comp module¶

This module is the computational part of the geometrical module of ToFu

`tofu.geom._comp.``LOS_CrossProj`(VType, Ds, us, kOuts, proj='All', multi=False, num_threads=16, return_pts=False, Test=True)[source]

Compute the parameters to plot the poloidal projection of the LOS

`tofu.geom._comp.``LOS_PRMin`(Ds, us, kOut=None, Eps=1e-12, squeeze=True, Test=True)[source]

Compute the point on the LOS where the major radius is minimum

`tofu.geom._comp.``LOS_calc_signal`(ff, D, u, dL, DL=None, dLMode='abs', method='romb', Test=True)[source]
`tofu.geom._comp.``LOS_get_sample`(D, u, dL, DL=None, dLMode='abs', method='sum', Test=True)[source]

Return the sampled line, with the specified method

‘linspace’: return the N+1 edges, including the first and last point ‘sum’ : return the N middle of the segments ‘simps’: return the N+1 egdes, where N has to be even

(scipy.simpson requires an even number of intervals)

‘romb’return the N+1 edges, where N+1 = 2**k+1

(fed to scipy.romb for integration)

`tofu.geom._comp.``calc_solidangle_particle`(traj, pts, r=1.0, config=None, approx=True, aniso=False, block=True)[source]

Compute the solid angle subtended by a particle along a trajectory

The particle has radius r, and trajectory (array of points) traj It is observed from pts (array of points)

traj and pts are (3,N) and (3,M) arrays of cartesian coordinates

approx = True => use approximation aniso = True => return also unit vector of emission block = True consider LOS collisions (with Ves, Struct…)

if block:

config = config used for LOS collisions

sang: np.ndarray

(N,M) Array of floats, solid angles

`tofu.geom._comp.``calc_solidangle_particle_integ`(traj, r=1.0, config=None, approx=True, block=True, res=0.01)[source]

## tofu.geom._comp_optics module¶

`tofu.geom._comp_optics.``CrystBragg_get_noute1e2_from_psitheta`(nout, e1, e2, psi, theta, e1e2=True)[source]
`tofu.geom._comp_optics.``CrystBragg_sample_outline_Rays`(center, nout, e1, e2, rcurve, extenthalf, bragg, phi)[source]
`tofu.geom._comp_optics.``CrystBragg_sample_outline_plot_sphrect`(center, nout, e1, e2, rcurve, extenthalf, res=None)[source]
`tofu.geom._comp_optics.``CrystBragg_sample_outline_sphrect`(dpsi, dtheta, npsi=None, ntheta=None)[source]
`tofu.geom._comp_optics.``calc_braggphi_from_xixjpts`(det_cent, det_ei, det_ej, summit, nin, e1, e2, xi=None, xj=None, pts=None)[source]
`tofu.geom._comp_optics.``calc_psidthetaphi_from_pts_lamb`(pts, center, rcurve, bragg, nlamb, npts, nout, e1, e2, extenthalf, ntheta=None)[source]
`tofu.geom._comp_optics.``calc_xixj_from_braggphi`(summit, det_cent, det_nout, det_ei, det_ej, nout, e1, e2, bragg, phi)[source]
`tofu.geom._comp_optics.``checkformat_vectang`(Z, nn, frame_cent, frame_ang)[source]
`tofu.geom._comp_optics.``get_approx_detector_rel`(rcurve, bragg, tangent_to_rowland=None)[source]
`tofu.geom._comp_optics.``get_bragg_from_lamb`(lamb, d, n=None)[source]

n*lamb = 2d*sin(bragg)

`tofu.geom._comp_optics.``get_det_abs_from_rel`(det_dist, n_crystdet_rel, det_nout_rel, det_ei_rel, summit, nout, e1, e2, ddist=None, di=None, dj=None, dtheta=None, dpsi=None, tilt=None)[source]
`tofu.geom._comp_optics.``get_e1e2_detectorplane`(nn, nIn)[source]
`tofu.geom._comp_optics.``get_lamb_from_bragg`(bragg, d, n=None)[source]

n*lamb = 2d*sin(bragg)

`tofu.geom._comp_optics.``get_lambphifit`(lamb, phi, nxi, nxj)[source]

## tofu.geom._core module¶

This module is the geometrical part of the ToFu general package It includes all functions and object classes necessary for tomography on Tokamaks

class `tofu.geom._core.``PlasmaDomain`(Poly=None, Type=None, Lim=None, pos=None, extent=None, Id=None, Name=None, Exp=None, shot=None, sino_RefPt=None, sino_nP=50, Clock=False, arrayorder='C', fromdict=None, sep=None, SavePath='/home/lasofivec/tofu/doc/source', SavePath_Include=['Mod', 'Cls', 'Type', 'Exp', 'Deg', 'Diag', 'Name', 'shot'], color=None)[source]

Bases: `tofu.geom._core.StructIn`

class `tofu.geom._core.``Ves`(Poly=None, Type=None, Lim=None, pos=None, extent=None, Id=None, Name=None, Exp=None, shot=None, sino_RefPt=None, sino_nP=50, Clock=False, arrayorder='C', fromdict=None, sep=None, SavePath='/home/lasofivec/tofu/doc/source', SavePath_Include=['Mod', 'Cls', 'Type', 'Exp', 'Deg', 'Diag', 'Name', 'shot'], color=None)[source]

Bases: `tofu.geom._core.StructIn`

class `tofu.geom._core.``PFC`(Poly=None, Type=None, Lim=None, pos=None, extent=None, Id=None, Name=None, Exp=None, shot=None, sino_RefPt=None, sino_nP=50, Clock=False, arrayorder='C', fromdict=None, sep=None, SavePath='/home/lasofivec/tofu/doc/source', SavePath_Include=['Mod', 'Cls', 'Type', 'Exp', 'Deg', 'Diag', 'Name', 'shot'], color=None)[source]

Bases: `tofu.geom._core.StructOut`

class `tofu.geom._core.``CoilPF`(nturns=None, superconducting=None, active=None, **kwdargs)[source]

Bases: `tofu.geom._core.StructOut`

property `current`
property `dmag`
property `nturns`
`set_current`(current=None)[source]

Set the current circulating on the coil (A)

`set_dmag`(superconducting=None, nturns=None, active=None)[source]
`strip`(strip=0)[source]

Remove non-essential attributes to save memory / disk usage

Useful to save a very compressed version of the object The higher strip => the more stripped the object Use strip=0 to recover all atributes

See the difference by doing:

> self.get_nbytes() > self.strip(-1) > self.get_nbytes()

Parameters

strip (int) –

Flag indicating how much to strip from the object

0: Make complete (retrieve all attributes) 1: Remove dsino and dmag expendables 2: Remove also dgeom, dphys and dmisc expendables

-1: Equivalent to strip=2

class `tofu.geom._core.``CoilCS`(nturns=None, superconducting=None, active=None, **kwdargs)[source]
class `tofu.geom._core.``Config`(lStruct=None, Lim=None, dextraprop=None, Id=None, Name=None, Exp=None, shot=None, Type=None, SavePath='/home/lasofivec/tofu/doc/source', SavePath_Include=['Mod', 'Cls', 'Type', 'Exp', 'Deg', 'Diag', 'Name', 'shot'], fromdict=None, sep=None)[source]
property `Lim`
`add_Struct`(struct=None, Cls=None, Name=None, Poly=None, shot=None, Lim=None, Type=None, dextraprop=None)[source]

Add a Struct instance to the config

An already existing Struct subclass instance can be added Or it will be created from the (Cls,Name,Poly,Lim) keyword args

`add_extraprop`(key, val)[source]
property `dStruct`
property `dextraprop`
property `dsino`
`fdistfromwall`(r, z, phi)[source]

Return a callable (function) for detecting trajectory collisions with wall

The function is continuous wrt time and space It takes into account all Struct in Config, including non-axisymmetric ones

It is desined for iterative root-finding algorithms and is thus called for a unique position

`get_color`()[source]

Return the array of rgba colors (same order as lStruct)

`get_kwdargs_LOS_isVis`()[source]
`get_reflections`(indout, u=None, vperp=None)[source]
`get_summary`(sep=' ', line='-', just='l', table_sep=None, verb=True, return_=False)[source]

Summary description of the object content

`isInside`(pts, In='(X, Y, Z)', log='any')[source]

Return a 2D array of bool

Equivalent to applying isInside to each Struct Check self.lStruct.isInside? for details

Arg log determines how Struct with multiple Limits are treated
• ‘all’ : True only if pts belong to all elements

• ‘any’ : True if pts belong to any element

property `lStruct`

Return the list of Struct that was used for creation

As tofu objects or SavePath+SaveNames (according to strip status)

property `lStructIn`

Return the list of StructIn contained in self.lStruct

As tofu objects or SavePath+SaveNames (according to strip status)

property `nLim`
property `nStruct`
`plot`(lax=None, proj='all', element='P', dLeg={'bbox_to_anchor': (1.01, 1), 'borderaxespad': 0.0, 'frameon': False, 'loc': 2, 'ncol': 1, 'prop': {'size': 10}}, indices=False, Lim=None, Nstep=None, draw=True, fs=None, wintit=None, tit=None, Test=True)[source]
`plot_phithetaproj_dist`(refpt=None, ntheta=None, nphi=None, theta=None, phi=None, cmap=None, invertx=None, ax=None, fs=None, tit=None, wintit=None, draw=None)[source]
`plot_sino`(ax=None, dP=None, Ang='theta', AngUnit='rad', Sketch=True, dLeg={'bbox_to_anchor': (1.01, 1), 'borderaxespad': 0.0, 'frameon': False, 'loc': 2, 'ncol': 1, 'prop': {'size': 10}}, draw=True, fs=None, wintit=None, tit=None, Test=True)[source]
`remove_Struct`(Cls=None, Name=None)[source]
`save_to_imas`(shot=None, run=None, refshot=None, refrun=None, user=None, tokamak=None, version=None, occ=None, dryrun=False, verb=True, description_2d=None)[source]
`set_colors_random`(cmap=<matplotlib.colors.ListedColormap object>)[source]
`set_dsino`(RefPt, nP=50)[source]
`strip`(strip=0, force=False, verb=True)[source]

Remove non-essential attributes to save memory / disk usage

Useful to save a very compressed version of the object The higher strip => the more stripped the object Use strip=0 to recover all atributes

See the difference by doing:

> self.get_nbytes() > self.strip(-1) > self.get_nbytes()

Parameters

strip (int) –

Flag indicating how much to strip from the object

0: Make complete (retrieve all attributes) 1: apply strip(1) to objects in self.lStruct 2: apply strip(2) to objects in self.lStruct 3: replace objects in self.lStruct by SavePath + SaveName

-1: Equivalent to strip=3

class `tofu.geom._core.``Rays`(dgeom=None, lOptics=None, Etendues=None, Surfaces=None, config=None, dchans=None, dX12='geom', Id=None, Name=None, Exp=None, shot=None, Diag=None, sino_RefPt=None, fromdict=None, sep=None, method='optimized', SavePath='/home/lasofivec/tofu/doc/source', color=None)[source]

Parent class of rays (ray-tracing), LOS, CamLOS1D and CamLOS2D

Focused on optimizing the computation time for many rays.

Each ray is defined by a starting point (D) and a unit vector(u). If a vessel (Ves) and structural elements (LStruct) are provided, the intersection points are automatically computed.

Methods for plootting, computing synthetic signal are provided.

Parameters
• Id (str / `ID`) – A name string or a `ID` to identify this instance, if a string is provided, it is fed to `ID`

• Du (iterable) –

Iterable of len=2, containing 2 np.ndarrays represnting, for N rays:
• Ds: a (3,N) array of the (X,Y,Z) coordinates of starting points

• us: a (3,N) array of the (X,Y,Z) coordinates of the unit vectors

• Ves (None / `Ves`) – A `Ves` instance to be associated to the rays

• LStruct (None / `Struct` / list) – A `Struct` instance or list of such, for obstructions

• Sino_RefPt (None / np.ndarray) –

Iterable of len=2 with the coordinates of the sinogram reference point
• (R,Z) coordinates if the vessel is of Type ‘Tor’

• (Y,Z) coordinates if the vessel is of Type ‘Lin’

• Exp (None / str) –

Experiment to which the LOS belongs:
• if both Exp and Ves are provided: Exp==Ves.Id.Exp

• if Ves is provided but not Exp: Ves.Id.Exp is used

• Diag (None / str) – Diagnostic to which the LOS belongs

• shot (None / int) – Shot number from which this LOS is valid

• SavePath (None / str) – If provided, default saving path of the object

property `D`
property `Etendues`
property `Surfaces`
`add_reflections`(Type=None, nb=None)[source]

Add relfected LOS to the camera

Reflected LOS can be of 3 types:
• ‘speculiar’: standard mirror-like reflection

• ‘diffusive’: random reflection

• ‘ccube’: corner-cube reflection (ray goes back its way)

As opposed to self.get_reflections_as_cam(), the reflected rays are stored in the camera object

`calc_kInkOut_Isoflux`(lPoly, lVIn=None, Lim=None, kInOut=True)[source]

Calculate the intersection points of each ray with each isoflux

The isofluxes are provided as a list of 2D closed polygons

The intersections are the inward and outward intersections They are retruned as two np.ndarrays: kIn and kOut Each array contains the length parameter along the ray for each isoflux

`calc_length_in_isoflux`(lPoly, lVIn=None, Lim=None, kInOut=True)[source]

Return the length of each LOS inside each isoflux

Uses self.calc_kInkOut_Isoflux() to compute the linear abscissa (k) of the entry points (kIn) and exit points (kOut) for each LOS

The isofluxes must be provided as a list of polygons

The length is returned as a (nPoly, nLOS) 2d array

`calc_min_geom_radius`(axis)[source]

Return the minimum geom. radius of each LOS, from an arbitrary axis

The axis mut be provided as a (R,Z) iterable Uses self.set_dsino()

p: np.ndarray

(nLOS,) array of minimal radius (or impact parameter)

theta: np.ndarray

(nLOS,) array of associated theta with respect to axis

pts: np.ndarray

(3,nLOS) array of (X,Y,Z) coordinates of associated points on LOS

`calc_min_rho_from_Plasma2D`(plasma, t=None, log='min', res=None, resMode='abs', method='sum', quant=None, ref1d=None, ref2d=None, interp_t=None, interp_space=None, fill_value=nan, pts=False, Test=True)[source]

Return the min/max value of scalar field quant for each LOS

Typically used to get the minimal normalized minor radius But can be used for any quantity available in plasma if:

• it is a 2d profile

• it is a 1d profile that can be interpolated on a 2d mesh

Currently sample each LOS with desired resolution and returns the absolute min/max interpolated value (and associated point)

See self.get_sample() for details on sampling arguments:
• res, resMode, method

See Plasma2D.interp_pts2profile() for details on interpolation args:
• t, quant, q2dref, q1dref, interp_t, interp_space, fill_value

val: np.ndarray

(nt, nLOS) array of min/max values

pts: np.ndarray

(nt, nLOS, 3) array of (X,Y,Z) coordinates of associated points Only returned if pts = True

t: np.ndarray

(nt,) array of time steps at which the interpolations were made

`calc_signal`(func, t=None, ani=None, fkwdargs={}, Brightness=True, res=None, DL=None, resMode='abs', method='sum', minimize='calls', num_threads=16, reflections=True, coefs=None, coefs_reflect=None, ind=None, returnas=<class 'object'>, plot=True, dataname=None, fs=None, dmargin=None, wintit=None, invert=True, units=None, draw=True, connect=True, newcalc=True)[source]

Return the line-integrated emissivity

Beware, by default, Brightness=True and it is only a line-integral !

Indeed, to get the received power, you need an estimate of the Etendue (previously set using self.set_Etendues()) and use Brightness=False.

Hence, if Brightness=True and if the emissivity is provided in W/m3 (resp. W/m3/sr), => the method returns W/m2 (resp. W/m2/sr) The line is sampled using `get_sample()`,

Except func, arguments common to `get_sample()`

Parameters
• func (callable) –

The user-provided emissivity function Shall take at least:

func(pts, t=None, vect=None)

where:
• pts : (3,N) np.ndarray, (X,Y,Z) coordinates of points

• t : None / (nt,) np.ndarray, time vector

• vect: None / (3,N) np.ndarray, unit direction vectors (X,Y,Z)

Should return at least:
• val : (N,) np.ndarray, local emissivity values

• method (string, the integral can be computed using 3 different methods) –

• ‘sum’: A numpy.sum() on the local values (x segments) DEFAULT

• ’simps’: using `scipy.integrate.simps()`

• ’romb’: using `scipy.integrate.romb()`

• minimize (string, method to minimize for computation optimization) –

• “calls”: minimal number of calls to func (default)

• ”memory”: slowest method, to use only if “out of memory” error

• ”hybrid”: mix of before-mentioned methods.

Returns

• sig (np.ndarray) – The computed signal, a 1d or 2d array depending on whether a time vector was provided.

• units (str) – Units of the result

`calc_signal_from_Plasma2D`(plasma2d, t=None, newcalc=True, quant=None, ref1d=None, ref2d=None, q2dR=None, q2dPhi=None, q2dZ=None, Type=None, Brightness=True, interp_t='nearest', interp_space=None, fill_value=None, res=None, DL=None, resMode='abs', method='sum', minimize='calls', num_threads=16, reflections=True, coefs=None, coefs_reflect=None, ind=None, returnas=<class 'object'>, plot=True, dataname=None, fs=None, dmargin=None, wintit=None, invert=True, units=None, draw=True, connect=True)[source]
`check_ff`(ff, t=None, ani=None)[source]
`compute_dgeom`(extra=True, show_debug_plot=True)[source]

Compute dictionnary of geometrical attributes (dgeom)

Parameters

show_debug_plot (bool) – In case some lines of sight have no visibility inside the tokamak, they will be considered invalid. tofu will issue a warning with their indices and if show_debug_plot is True, try to plot a 3d figure to help understand why these los have no visibility

property `config`
property `dchans`
property `dgeom`
property `dsino`
`get_inspector`(ff)[source]
`get_reflections_as_cam`(Type=None, Name=None, nb=None)[source]

Return a camera made of reflected LOS

Reflected LOS can be of 3 types:
• ‘speculiar’: standard mirror-like reflection

• ‘diffusive’: random reflection

• ‘ccube’: corner-cube reflection (ray goes back its way)

As opposed to self.add_reflections(), the reflected rays are return as an independent camera (CamLOS1D)

`get_sample`(res=None, resMode='abs', DL=None, method='sum', ind=None, pts=False, compact=True, num_threads=10, Test=True)[source]

Return a linear sampling of the LOS

The LOS is sampled into a series a points and segments lengths The resolution (segments length) is <= res The sampling can be done according to different methods It is possible to sample only a subset of the LOS

Parameters
• res (float) – Desired resolution

• resMode (str) –

Flag indicating res should be understood as:
• ’abs’: an absolute distance in meters

• ’rel’: a relative distance (fraction of the LOS length)

• DL (None / iterable) – The fraction [L1;L2] of the LOS that should be sampled, where L1 and L2 are distances from the starting point of the LOS (LOS.D) DL can be an iterable of len()==2 (identical to all los), or a (2,nlos) array

• method (str) –

Flag indicating which to use for sampling:
• ’sum’: the LOS is sampled into N segments of equal length,
where N is the smallest int such that:
• segment length <= resolution(res,resMode)

The points returned are the center of each segment

• ’simps’: the LOS is sampled into N segments of equal length,
where N is the smallest int such that:
• segment length <= resolution(res,resMode)

• N is even

The points returned are the egdes of each segment

• ’romb’: the LOS is sampled into N segments of equal length,
where N is the smallest int such that:
• segment length <= resolution(res,resMode)

• N = 2^k + 1

The points returned are the egdes of each segment

• ind (None / iterable of int) – indices of the LOS to be sampled

• pts (bool) – Flag indicating whether to return only the abscissa parameter k (False) or the 3D pts coordinates (True)

• compact (bool) – Flag incating whether to retrun the sampled pts of all los in a single concatenated array (True) or splitted into a list of nlos arrays)

Returns

• k (np.ndarray) –

if pts == False:
A (npts,) array of the abscissa parameters

(i.e.: points distances from the LOS starting points)

In order to get the 3D cartesian coordinates of pts do:

if pts == True:

A (3,npts) array of the sampled points 3D cartesian coordinates

• reseff (np.ndarray) – A (nlos,) array of the effective resolution (<= res input), as an absolute distance

• ind (np.ndarray) – A (nlos-1,) array of integere indices (where to split k to separate the points of each los). e.g.: lk = np.split(k,ind)

`get_subset`(indch=None, Name=None)[source]

Return an instance which is a sub-set of the camera

The subset is the same camera but with only the LOS selected by indch It can be assigned a new Name (str), or the same one (True)

`get_touch_colors`(ind=None, dElt=None, cbck=(0.8, 0.8, 0.8), rgba=True)[source]
`get_touch_dict`(ind=None, out=<class 'bool'>)[source]

Get a dictionnary of Cls_Name struct with indices of Rays touching

Only includes Struct object with compute = True

(as returned by self.lStruct__computeInOut_computeInOut)

Also return the associated colors If in is not None, the indices for each Struct are split between:

• indok : rays touching Struct and in ind

• indout: rays touching Struct but not in ind

property `indStruct_computeInOut`
property `isInPoloidalPlane`
property `isPinhole`
property `kIn`
property `kMin`
property `kOut`
property `lOptics`
`move`(param)[source]

Set new position to desired param according to default movement

Can only be used if default movement was set before See self.set_move()

property `nRays`
property `pinhole`
`plot`(lax=None, proj='all', reflections=True, Lplot='Tot', element='L', element_config='P', Leg='', dL=None, dPtD={'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, dPtI={'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, dPtO={'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, dPtR={'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, dPtP={'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, dLeg={'bbox_to_anchor': (1.01, 1), 'borderaxespad': 0.0, 'frameon': False, 'loc': 2, 'ncol': 1, 'prop': {'size': 10}}, multi=False, ind=None, fs=None, tit=None, wintit=None, draw=True, Test=True)[source]

Plot the Rays / LOS, in the chosen projection(s)

Optionnally also plot associated `Ves` and Struct The plot can also include:

• special points

• the unit directing vector

Parameters
• lax (list / plt.Axes) – The axes for plotting (list of 2 axes if Proj=’All’) If None a new figure with new axes is created

• proj (str) –

Flag specifying the kind of projection:
• ’Cross’ : cross-section

• ’Hor’ : horizontal

• ’All’ : both cross-section and horizontal (on 2 axes)

• ’3d’ : a (matplotlib) 3d plot

• projections (bool) – Flag indicating whether to plot also the reflected rays Assuming some reflected rays are present (self.add_reflections())

• element (str) –

Flag specifying which elements to plot Each capital letter corresponds to an element:

• ’L’: LOS

• ’D’: Starting point of the LOS

• ’I’: Input point (i.e.: where the LOS enters the Vessel)

• ’O’: Output point (i.e.: where the LOS exits the Vessel)

• ’R’: Point of minimal major radius R (only if Ves.Type=’Tor’)

• ’P’: Point of used for impact parameter (i.e.: with minimal

distance to reference point Sino_RefPt)

• Lplot (str) –

Flag specifying the length to plot:
• ’Tot’: total length, from starting point (D) to output point

• ’In’ : only the in-vessel fraction (from input to output)

• element_config (str) – Fed to self.config.plot()

• Leg (str) – Legend, if Leg=’’ the LOS name is used

• dL (dict / None) – Dictionary of properties for plotting the lines Fed to plt.Axes.plot(), set to default if None

• dPtD (dict) – Dictionary of properties for plotting point ‘D’

• dPtI (dict) – Dictionary of properties for plotting point ‘I’

• dPtO (dict) – Dictionary of properties for plotting point ‘O’

• dPtR (dict) – Dictionary of properties for plotting point ‘R’

• dPtP (dict) – Dictionary of properties for plotting point ‘P’

• dLeg (dict or None) – Dictionary of properties for plotting the legend Fed to plt.legend(), the legend is not plotted if None

• draw (bool) – Flag indicating whether fig.canvas.draw() shall be called

• a4 (bool) – Flag indicating whether to plot the figure in a4 dimensions

• Test (bool) –

• a4 – Flag indicating whether to plot the figure in a4 dimensions

• Test

• a4 – Flag indicating whether to plot the figure in a4 dimensions

• Test

• a4 – Flag indicating whether to plot the figure in a4 dimensions

• Test

• Test – Flag indicating whether the inputs should be tested for conformity

Returns

La (list / plt.Axes) – Handles of the axes used for plotting (list if Proj=’All’)

`plot_sino`(ax=None, element='LV', Sketch=True, Ang='theta', AngUnit='rad', Leg=None, dL={'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, dVes={'edgecolor': (0.8, 0.8, 0.8, 1.0), 'facecolor': (0.8, 0.8, 0.8, 1.0), 'linestyle': 'solid', 'linewidth': 1}, dLeg={'bbox_to_anchor': (1.01, 1), 'borderaxespad': 0.0, 'frameon': False, 'loc': 2, 'ncol': 1, 'prop': {'size': 10}}, ind=None, multi=False, fs=None, tit=None, wintit=None, draw=True, Test=True)[source]

Plot the LOS in projection space (sinogram)

Plot the Rays in projection space (cf. sinograms) as points. Can also optionnally plot the associated `Ves`

Can plot the conventional projection-space (in 2D in a cross-section), or a 3D extrapolation of it, where the third coordinate is provided by the angle that the LOS makes with the cross-section plane (useful in case of multiple LOS with a partially tangential view)

Parameters
• Proj (str) –

Flag indicating whether to plot:
• ’Cross’: a classic sinogram (vessel cross-section)

• ’3d’: an extended 3D version (‘3d’), with an additional angle

• ax (None / plt.Axes) – The axes on which to plot, if None a new figure is created

• Elt (str) –

Flag indicating which elements to plot (one per capital letter):
• ’L’: LOS

• ’V’: Vessel

• Ang (str) –

Flag indicating which angle to use for the impact parameter:
• ’xi’: the angle of the line itself

• ’theta’: its impact parameter (theta)

• AngUnit (str) –

Flag for the angle units to be displayed:

• ’deg’: for degrees

• Sketch (bool) – Flag indicating whether to plot a skecth with angles definitions

• dL (dict) – Dictionary of properties for plotting the Rays points

• dV (dict) – Dictionary of properties for plotting the vessel envelopp

• dLeg (None / dict) – Dictionary of properties for plotting the legend The legend is not plotted if None

• draw (bool) – Flag indicating whether to draw the figure

• a4 (bool) – Flag indicating whether the figure should be a4

• Test (bool) – Flag indicating whether the inputs shall be tested for conformity

Returns

ax (plt.Axes) – The axes used to plot

`plot_touch`(key=None, quant='lengths', invert=None, ind=None, Bck=True, fs=None, wintit=None, tit=None, connect=True, draw=True)[source]

Interactive plot of the camera and the structures it touches

The camera LOS are plotted in poloidal and horizontal projections The associated Config is also plotted The plot shows which strutural element is touched by each LOS

In addition, an extra quantity is plotted, depending on quant:
• ‘lengths’ (default): the length of each LOS

• ‘angles’the angle of incidence of each LOS
(with respect to the normal of the surface touched,

useful for assessing reflection probabilities)

• ‘indices’: the index of each LOS

(useful for checking numbering)

• ‘Etendues’: the etendue associated to each LOS (user-provided)

• ‘Surfaces’: the surfaces associated to each LOS (user-provided)

`rotate_around_3daxis`(angle=None, axis=None, return_copy=None, diag=None, name=None, dchans=None)[source]

Rotate the instance around the provided 3d axis

`rotate_around_torusaxis`(angle=None, return_copy=None, diag=None, name=None, dchans=None)[source]

Rotate the instance around the torus axis

`rotate_in_cross_section`(angle=None, axis_rz=None, phi=None, return_copy=None, diag=None, name=None, dchans=None)[source]

Rotate the instance in the cross-section

`select`(key=None, val=None, touch=None, log='any', out=<class 'int'>)[source]

Return the indices of the rays matching selection criteria

The criterion can be of two types:
• a key found in self.dchans, with a matching value

• a touch tuple (indicating which element in self.config is touched

by the desired rays)

Parameters
• key (None / str) – A key to be found in self.dchans

• val (int / str / float / list of such) – The value to be matched If a list of values is provided, the behaviour depends on log

• log (str) –

A flag indicating which behaviour to use when val is a list
• any : Returns indices of rays matching any value in val

• all : Returns indices of rays matching all values in val

• not : Returns indices of rays matching None of the val

• touch (None / str / int / tuple) –

Used if key is None Tuple that can be of len()=1, 2 or 3 Tuple indicating you want the rays that are touching some specific elements of self.config:

• touchstr / int or list of such

str : a ‘Cls_Name’ string indicating the element int : the index of the element in self.config.lStruct

• touchint / list of int

Indices of the desired segments on the polygon (i.e.: of the cross-section polygon of the above element)

• touchint / list of int

Indices, if relevant, of the toroidal / linear unit Only relevant when the element has noccur>1

In this case only log=’not’ has an effect

• out (str) –

Flag indicating whether to return:
• bool : a (nRays,) boolean array of indices

• inta (N,) array of int indices (N=number of matching

rays)

Returns

ind (np.ndarray) – The array of matching rays

`set_Etendues`(val)[source]
`set_Surfaces`(val)[source]
`set_dX12`(dX12=None)[source]
`set_dchans`(dchans=None)[source]
`set_dconfig`(config=None, calcdgeom=True)[source]
`set_dsino`(RefPt=None, extra=True)[source]
`set_move`(move=None, param=None, **kwdargs)[source]

Set the default movement parameters

A default movement can be set for the instance, it can be any of the pre-implemented movement (rotations or translations) This default movement is the one that will be called when using self.move()

Specify the type of movement via the name of the method (passed as a str to move)

Specify, for the geometry of the instance at the time of defining this default movement, the current value of the associated movement parameter (angle / distance). This is used to set an arbitrary difference for user who want to use absolute position values The desired incremental movement to be performed when calling self.move will be deduced by substracting the stored param value to the provided param value. Just set the current param value to 0 if you don’t care about a custom absolute reference.

kwdargs must be a parameters relevant to the chosen method (axis, direction…)

e.g.:
self.set_move(move=’rotate_around_3daxis’,

param=0., axis=([0.,0.,0.], [1.,0.,0.]))

self.set_move(move=’translate_3d’,

param=0., direction=[0.,1.,0.])

`strip`(strip=0, verb=True)[source]

Remove non-essential attributes to save memory / disk usage

Useful to save a very compressed version of the object The higher strip => the more stripped the object Use strip=0 to recover all atributes

See the difference by doing:

> self.get_nbytes() > self.strip(-1) > self.get_nbytes()

Parameters

strip (int) –

Flag indicating how much to strip from the object

0: Make complete (retrieve all attributes) 1: dgeom w/o pts + config.strip(1) 2: dgeom w/o pts + config.strip(2) + dsino empty 3: dgeom w/o pts + config.strip(3) + dsino empty 4: dgeom w/o pts + config=pathfile + dsino empty

-1: Equivalent to strip=4

`translate_3d`(distance=None, direction=None, return_copy=None, diag=None, name=None, dchans=None)[source]

Translate the instance in provided direction

`translate_in_cross_section`(distance=None, direction_rz=None, phi=None, return_copy=None, diag=None, name=None, dchans=None)[source]

Translate the instance in the cross-section

property `u`
class `tofu.geom._core.``CamLOS1D`(dgeom=None, lOptics=None, Etendues=None, Surfaces=None, config=None, dchans=None, dX12='geom', Id=None, Name=None, Exp=None, shot=None, Diag=None, sino_RefPt=None, fromdict=None, sep=None, method='optimized', SavePath='/home/lasofivec/tofu/doc/source', color=None)[source]
`get_summary`(sep=' ', line='-', just='l', table_sep=None, verb=True, return_=False)[source]
`save_to_imas`(ids=None, shot=None, run=None, refshot=None, refrun=None, user=None, tokamak=None, version=None, occ=None, dryrun=False, deep=True, restore_size=True, verb=True, config_description_2d=None, config_occ=None)[source]
class `tofu.geom._core.``CamLOS2D`(dgeom=None, lOptics=None, Etendues=None, Surfaces=None, config=None, dchans=None, dX12='geom', Id=None, Name=None, Exp=None, shot=None, Diag=None, sino_RefPt=None, fromdict=None, sep=None, method='optimized', SavePath='/home/lasofivec/tofu/doc/source', color=None)[source]
property `dX12`
`get_X12plot`(plot='imshow')[source]
`get_summary`(sep=' ', line='-', just='l', table_sep=None, verb=True, return_=False)[source]

## tofu.geom._core_optics module¶

This module is the geometrical part of the ToFu general package It includes all functions and object classes necessary for tomography on Tokamaks

class `tofu.geom._core_optics.``CrystalBragg`(dgeom=None, dmat=None, dbragg=None, Id=None, Name=None, Exp=None, Diag=None, shot=None, fromdict=None, sep=None, SavePath='/home/lasofivec/tofu/doc/source', SavePath_Include=['Mod', 'Cls', 'Type', 'Exp', 'Deg', 'Diag', 'Name', 'shot'], color=None)[source]

A class defining crystals for Bragg diffraction

A crystal can be of Type flat, cylindrical or spherical It is characterized by its:

• geometry (Type, dimensions, curvature radii and position/orientation)

• Material and lattice

• Bragg parameters (angle vs lambda)

Parameters
• Id (str / tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()

• dgeom (dict) –

An array (2,N) or (N,2) defining the contour of the vacuum vessel in a

cross-section, if not closed, will be closed automatically

dspectral: str

Flag indicating whether the vessel will be a torus (‘Tor’) or a linear device (‘Lin’)

• SavePath (None / str) – If provided, forces the default saving path of the object to the provided value

property `Type`

Return the type of structure

`calc_johannerror`(xi=None, xj=None, err=None, det_cent=None, det_ei=None, det_ej=None, n=None, lpsi=None, ltheta=None, plot=True, fs=None, cmap=None, vmin=None, vmax=None, tit=None, wintit=None)[source]

Plot the johann error

The johann error is the error (scattering) induced by defocalization

due to finite crystal dimensions

There is a johann error on wavelength (lamb => loss of spectral

resolution) and on directionality (phi)

If provided, lpsi and ltheta are taken as normalized variations with

respect to the crystal summit and to its extenthalf. Typical values are:

• lpsi = [-1, 1, 1, -1]

• ltheta = [-1, -1, 1, 1]

They must have the same len()

`calc_phibragg_from_pts`(pts, dtheta=None, dpsi=None)[source]
`calc_phibragg_from_pts_on_summit`(pts, n=None)[source]

Return the bragg angle and phi of pts from crystal summit

The pts are provided as a (x, y, z) coordinates array The bragg angle and phi are computed from the crystal’s summit

`calc_phibragg_from_xixj`(xi, xj, n=None, det_cent=None, det_ei=None, det_ej=None, dtheta=None, psi=None, plot=True, ax=None, **kwdargs)[source]
`calc_thetapsi_from_lambpts`(pts=None, lamb=None, n=None, ntheta=None)[source]
`calc_xixj_from_phibragg`(phi=None, bragg=None, lamb=None, n=None, theta=None, psi=None, det_cent=None, det_nout=None, det_ei=None, det_ej=None, data=None, plot=True, ax=None)[source]

Assuming crystal’s summit as frame origin

According to , this assumes a local frame centered on the crystal

These calculations are independent from the tokamak’s frame:

The origin of the local frame is the crystal’s summit The (O, ez) axis is the crystal’s normal The crystal is tangent to (O, ex, ey)

Z: float

Detector’s plane intersection with (O, ez) axis

n: np.ndarray

(3,) array containing local (x,y,z) coordinates of the plane’s normal vector

property `center`
property `dbragg`

Return the polygon defining the structure cross-section

property `dgeom`
property `dmat`

Return the polygon defining the structure cross-section

property `dmisc`
property `e1`
property `e2`
`get_Rays_envelop`(phi=None, bragg=None, lamb=None, n=None, returnas=<class 'object'>, config=None, name=None)[source]
`get_Rays_from_summit`(phi=None, bragg=None, lamb=None, n=None, returnas=<class 'object'>, config=None, name=None)[source]
`get_bragg_from_lamb`(lamb, n=None)[source]

Braggs’ law: n*lamb = 2dsin(bragg)

`get_color`()[source]
`get_detector_approx`(bragg=None, lamb=None, rcurve=None, n=None, ddist=None, di=None, dj=None, dtheta=None, dpsi=None, tilt=None, tangent_to_rowland=None, plot=False)[source]

Return approximate ideal detector geometry

Assumes infinitesimal and ideal crystal Assumes detector center tangential to Rowland circle Assumes detector center matching lamb (m) / bragg (rad)

Detector described by center position, and (nout, ei, ej) unit vectors By convention, nout = np.cross(ei, ej) Vectors (ei, ej) define an orthogonal frame in the detector’s plane

det_cent: np.ndarray

(3,) array of (x, y, z) coordinates of detector center

det_nout: np.ndarray
(3,) array of (x, y, z) coordinates of unit vector

perpendicular to detector’ surface oriented towards crystal

det_ei: np.ndarray
(3,) array of (x, y, z) coordinates of unit vector

defining first coordinate in detector’s plane

det_ej: np.ndarray
(3,) array of (x, y, z) coordinates of unit vector

defining second coordinate in detector’s plane

`get_lamb_avail_from_pts`(pts)[source]
`get_lamb_from_bragg`(bragg, n=None)[source]

Braggs’ law: n*lamb = 2dsin(bragg)

`get_local_noute1e2`(theta, psi)[source]

Return (nout, e1, e2) associated to pts on the crystal’s surface

All points on the spherical crystal’s surface are identified
by (theta, psi) coordinates, where:
• theta = np.pi/2 for the center

• psi = 0 for the center

They are the spherical coordinates from a sphere centered on the crystal’s center of curvature.

Return the pts themselves and the 3 perpendicular unti vectors

(nout, e1, e2), where nout is towards the outside of the sphere and nout = np.cross(e1, e2)

summit: np.ndarray

(3,) array of (x, y, z) coordinates of the points on the surface

nout: np.ndarray

(3,) array of (x, y, z) coordinates of outward unit vector

e1: np.ndarray

(3,) array of (x, y, z) coordinates of first unit vector

e2: np.ndarray

(3,) array of (x, y, z) coordinates of second unit vector

`get_phi_from_magaxis_summit`(r, z, lamb=None, bragg=None, n=None)[source]
`get_rockingcurve_func`(lamb=None, n=None)[source]
`get_summary`(sep=' ', line='-', just='l', table_sep=None, verb=True, return_=False)[source]

Summary description of the object content

`move`(param)[source]

Set new position to desired param according to default movement

Can only be used if default movement was set before See self.set_move()

property `nin`
property `nout`
`plot`(lax=None, proj=None, res=None, element=None, color=None, det_cent=None, det_nout=None, det_ei=None, det_ej=None, dP=None, dI=None, dBs=None, dBv=None, dVect=None, dIHor=None, dBsHor=None, dBvHor=None, dleg=None, draw=True, fs=None, wintit=None, Test=True)[source]
`plot_data_fit2d`(xi=None, xj=None, data=None, mask=None, det_cent=None, det_ei=None, det_ej=None, theta=None, psi=None, n=None, nlamb=None, lamb0=None, forcelamb=False, deg=None, knots=None, nbsplines=None, method=None, max_nfev=None, xtol=None, ftol=None, gtol=None, loss=None, verbose=0, debug=None, plot=True, fs=None, dlines=None, dmoments=None, cmap=None, vmin=None, vmax=None)[source]
`plot_data_vs_lambphi`(xi=None, xj=None, data=None, mask=None, det_cent=None, det_ei=None, det_ej=None, theta=None, psi=None, n=None, nlambfit=None, nphifit=None, magaxis=None, npaxis=None, plot=True, fs=None, cmap=None, vmin=None, vmax=None)[source]
`plot_line_from_pts_on_det`(lamb=None, pts=None, xi_bounds=None, xj_bounds=None, nphi=None, det_cent=None, det_nout=None, det_ei=None, det_ej=None, johann=False, lpsi=None, ltheta=None, rocking=False, fs=None, dmargin=None, wintit=None, tit=None)[source]

Visualize the de-focusing by ray-tracing of chosen lamb

`plot_line_tracing_on_det`(lamb=None, n=None, xi_bounds=None, xj_bounds=None, nphi=None, det_cent=None, det_nout=None, det_ei=None, det_ej=None, johann=False, lpsi=None, ltheta=None, rocking=False, fs=None, dmargin=None, wintit=None, tit=None)[source]

Visualize the de-focusing by ray-tracing of chosen lamb

`plot_rockingcurve`(lamb=None, fs=None, ax=None)[source]
property `rockingcurve`
`rotate_around_3daxis`(angle=None, axis=None, return_copy=None, diag=None, name=None, shot=None)[source]

Rotate the instance around the provided 3d axis

`rotate_around_torusaxis`(angle=None, return_copy=None, diag=None, name=None, shot=None)[source]

Rotate the instance around the torus axis

`rotate_in_cross_section`(angle=None, axis_rz=None, phi=None, return_copy=None, diag=None, name=None, shot=None)[source]

Rotate the instance in the cross-section

`sample_outline_Rays`(res=None)[source]
`sample_outline_plot`(res=None)[source]
`set_color`(col)[source]
`set_dbragg`(dbragg=None)[source]
`set_dgeom`(dgeom=None)[source]
`set_dmat`(dmat=None)[source]
`set_move`(move=None, param=None, **kwdargs)[source]

Set the default movement parameters

A default movement can be set for the instance, it can be any of the pre-implemented movement (rotations or translations) This default movement is the one that will be called when using self.move()

Specify the type of movement via the name of the method (passed as a str to move)

Specify, for the geometry of the instance at the time of defining this default movement, the current value of the associated movement parameter (angle / distance). This is used to set an arbitrary difference for user who want to use absolute position values The desired incremental movement to be performed when calling self.move will be deduced by substracting the stored param value to the provided param value. Just set the current param value to 0 if you don’t care about a custom absolute reference.

kwdargs must be a parameters relevant to the chosen method (axis, direction…)

e.g.:
self.set_move(move=’rotate_around_3daxis’,

param=0., axis=([0.,0.,0.], [1.,0.,0.]))

self.set_move(move=’translate_3d’,

param=0., direction=[0.,1.,0.])

`strip`(strip=0)[source]

Remove non-essential attributes to save memory / disk usage

Useful to save a very compressed version of the object The higher strip => the more stripped the object Use strip=0 to recover all atributes

See the difference by doing:

> self.get_nbytes() > self.strip(-1) > self.get_nbytes()

Parameters

strip (int) –

Flag indicating how much to strip from the object

0: Make complete (retrieve all attributes) 1: Remove nothing

-1: Equivalent to strip=1

property `summit`
`translate_3d`(distance=None, direction=None, return_copy=None, diag=None, name=None, shot=None)[source]

Translate the instance in provided direction

`translate_in_cross_section`(distance=None, direction_rz=None, phi=None, return_copy=None, diag=None, name=None, shot=None)[source]

Translate the instance in the cross-section

## tofu.geom._def module¶

This module stores all the default setting of ToFu Including in particular computing parameters, dictionnaries and figures

`tofu.geom._def.``LOSdict` = {'Elt': 'LDIORP', 'EltVes': '', 'Lax': None, 'Ldict': {'c': 'k', 'lw': 2}, 'Leg': '', 'LegDict': {'bbox_to_anchor': (1.01, 1), 'borderaxespad': 0.0, 'frameon': False, 'loc': 2, 'ncol': 1, 'prop': {'size': 10}}, 'Lplot': 'Tot', 'MdictD': {'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, 'MdictI': {'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, 'MdictO': {'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, 'MdictP': {'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, 'MdictR': {'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, 'Proj': 'All', 'Test': True, 'Vesdict': {'Elt': 'PIBsBvV', 'Lax': None, 'Lim': [1.5707963267948966, 6.283185307179586], 'Nstep': 50, 'Proj': 'All', 'Test': True, 'dBs': {'c': 'b', 'ls': 'dashed', 'marker': 'x', 'markersize': 8, 'mew': 2}, 'dBsHor': {'c': 'b', 'ls': 'dashed'}, 'dBv': {'c': 'g', 'ls': 'dashed', 'marker': 'x', 'markersize': 8, 'mew': 2}, 'dBvHor': {'c': 'g', 'ls': 'dashed'}, 'dI': {'c': 'k', 'ls': 'dashed', 'marker': 'x', 'markersize': 8, 'mew': 2}, 'dIHor': {'c': 'k', 'ls': 'dashed'}, 'dLeg': {'bbox_to_anchor': (1.01, 1), 'borderaxespad': 0.0, 'frameon': False, 'loc': 2, 'ncol': 1, 'prop': {'size': 10}}, 'dP': {'c': 'k', 'lw': 2}, 'dVect': {'color': 'r', 'scale': 10}, 'draw': True}, 'draw': True}

# ————– Figures ————————

def Plot_Lens_Alone_DefAxes(fs=None, wintit=’tofu’):

axCol, fdpi = ‘w’, 80 if fs is None:

fs = (20,8)

elif type(fs) is str and fs==’a4’:

fs = (11.69,8.27)

f = plt.figure(facecolor=”w”, figsize=fs, dpi=fdpi) axPos = [0.05, 0.1, 0.9, 0.85] ax = f.add_axes(axPos,facecolor=axCol) ax.set_xlabel(r”x (m)”) ax.set_ylabel(r”y (m)”) return ax

# ———— Computing settings —————

DetSpanRMinMargin = 0.9 DetSpanNEdge = 5 DetSpanNRad = 5

DetConeNEdge = 8 DetConeNRad = 6

DetPreConedX12 = [0.01, 0.01] DetPreConedX12Mode = ‘abs’ DetPreConeds = 0.01 DetPreConedsMode = ‘abs’ DetPreConeMarginS = 0.002

DetConeDX = 0.002 DetConeDRY = 0.0025 # 0.0025 DetConeDTheta = np.pi/1024. # 512. DetConeDZ = 0.0025 # 0.0025 #DetConeNTheta = 25 # 25 #DetConeNZ = 50 # 50

DetConeRefdMax = 0.02

DetEtendMethod = ‘quad’ DetEtenddX12 = [0.01, 0.01] DetEtenddX12Mode = ‘rel’ DetEtendepsrel = 1.e-3 DetEtendRatio = 0.02 DetCalcEtendColis = False

DetCalcSAngVectColis = True DetCalcSAngVectCone = True

DetSynthEpsrel = 1.e-4 DetSynthdX12 = [0.005, 0.005] DetSynthdX12Mode = ‘abs’ DetSynthds = 0.005 DetSynthdsMode = ‘abs’ DetSynthMarginS = 0.001

# — Plotting dictionaries and parameters ——

ApPd = {‘c’:’k’,’lw’:2,’ls’:’solid’} ApVd = {‘color’:’r’,’lw’:2,’ls’:’solid’} DetPd = {‘c’:’k’,’lw’:2,’ls’:’solid’} DetVd = {‘color’:’r’,’lw’:2,’ls’:’solid’} DetSAngPld = {‘cmap’:plt.cm.YlOrRd,’lw’:0.,’rstride’:1,’cstride’:1, ‘antialiased’:False, ‘edgecolor’:’None’} DetSangPlContd = {‘linewidths’:0.} DetConed = {‘edgecolors’:’k’, ‘facecolors’:(0.8,0.8,0.8,0.2), ‘alpha’:0.2, ‘linewidths’:0., ‘linestyles’:’-‘, ‘antialiaseds’:False} DetImpd = {‘ls’:’solid’,’c’:’k’,’lw’:1}

ApLVin = 0.1 DetSAngPlRa = 0.5 DetSAngPldX12 = [0.025,0.025] DetSAngPldX12Mode = ‘rel’ DetSAngPlRatio = 0.01 DetEtendOnLOSNP = 20 DetEtendOnLOSModes = [‘trapz’] DetEtendOnLOSLd = {‘ls’:’solid’,’c’:’k’,’lw’:2}

DetSAngPlot = ‘Int’ DetSAngPlotMode = ‘scatter’ DetSAngPlotd = {‘cmap’:plt.cm.YlOrRd} DetSAngPlotLvl = 20

DetSliceAGdR = 0.005 DetSliceAGdY = 0.005 DetSliceAGdX = 0.01 DetSliceAGdTheta = np.pi/512. DetSliceAGdZ = 0.005 DetSliceNbd = {‘scatter’:{‘cmap’:plt.cm.Greys,’marker’:’s’,’edgecolors’:’None’,’s’:10},

‘contour’:{‘cmap’:plt.cm.Greys}, ‘contourf’:{‘cmap’:plt.cm.Greys}, ‘imshow’:{‘cmap’:plt.cm.Greys}}

‘contour’:{‘cmap’:plt.cm.YlOrRd, ‘vmin’:0}, ‘contourf’:{‘cmap’:plt.cm.YlOrRd, ‘vmin’:0}, ‘imshow’:{‘cmap’:plt.cm.YlOrRd, ‘vmin’:0}}

DetPolProjNTheta = 50 DetPolProjNZ = 25 DetSAngColis = True

GDetEtendMdA = {‘ls’:’None’,’c’:’k’,’lw’:2,’marker’:’+’} GDetEtendMdR = {‘ls’:’None’,’c’:’b’,’lw’:2,’marker’:’x’} GDetEtendMdS = {‘ls’:’None’,’c’:’g’,’lw’:2,’marker’:’o’} GDetEtendMdP = {‘ls’:’None’,’c’:’r’,’lw’:2,’marker’:’*’}

GDetSigd = {‘ls’:’solid’,’c’:’k’,’lw’:2,’marker’:’+’}

Apertdict = dict(Lax=None, Proj=’All’, Elt=’PV’, EltVes=’’, Leg=’’, LVIn=ApLVin, Pdict=ApPd, Vdict=ApVd, Vesdict=Vesdict, LegDict=TorLegd, draw=True, Test=True) #Detdict =

# ————– Figures ————————

def Plot_SAng_Plane_DefAxes(fs=None, wintit=’tofu’):

axCol, fdpi = ‘w’, 80 if fs is None:

fs = (16,8) if Mode.lower()==’all’ else (6,8)

elif type(fs) is str and fs==’a4’:

fs = (11.69,8.27) if Mode.lower()==’all’ else (8.27,11.69)

f = plt.figure(facecolor=”w”, figsize=fs, dpi=fdpi) (fW,fH,fdpi,axCol) = (11.69,8.27,80,’w’) if a4 else (10,8,80,’w’) axPos = [0.05, 0.05, 0.9, 0.9] f = plt.figure(facecolor=”w”,figsize=(fW,fH),dpi=fdpi) ax = f.add_axes(axPos,facecolor=axCol,projection=’3d’) ax.set_xlabel(r”X1 (m)”) ax.set_ylabel(r”X2 (m)”) ax.set_zlabel(r”\$Omega\$ (sr)”) return ax

def Plot_Etendue_AlongLOS_DefAxes(kMode=’rel’,fs=None, wintit=’tofu’):

axCol, fdpi = ‘w’, 80 if fs is None:

fs = (16,8) if Mode.lower()==’all’ else (6,8)

elif type(fs) is str and fs==’a4’:

fs = (11.69,8.27) if Mode.lower()==’all’ else (8.27,11.69)

f = plt.figure(facecolor=”w”, figsize=fs, dpi=fdpi) (fW,fH,fdpi,axCol) = (11.69,8.27,80,’w’) if a4 else (14,8,80,’w’) axPos = [0.06, 0.08, 0.70, 0.86] f = plt.figure(facecolor=”w”,figsize=(fW,fH),dpi=fdpi) ax = f.add_axes(axPos,frameon=True,facecolor=axCol) if kMode.lower()==’rel’:

else:

ax.set_xlabel(r”Length (m)”)

ax.set_ylabel(r”Etendue (\$sr.m^2\$)”) return ax

def Plot_CrossSlice_SAngNb_DefAxes(VType=’Tor’, fs=None, wintit=’tofu’):

axCol, fdpi = ‘w’, 80 if fs is None:

fs = (16,8) if Mode.lower()==’all’ else (6,8)

elif type(fs) is str and fs==’a4’:

fs = (11.69,8.27) if Mode.lower()==’all’ else (8.27,11.69)

f = plt.figure(facecolor=”w”, figsize=fs, dpi=fdpi) (fW,fH,fdpi,axCol) = (11.69,8.27,80,’w’) if a4 else (15,8,80,’w’) f = plt.figure(facecolor=”w”,figsize=(fW,fH),dpi=fdpi) axSAng = f.add_axes([0.05, 0.06, 0.40, 0.85],frameon=True,facecolor=axCol) axNb = f.add_axes([0.60, 0.06, 0.40, 0.85],frameon=True,facecolor=axCol) if VType==’Tor’:

axSAng.set_xlabel(r”R (m)”), axNb.set_xlabel(r”R (m)”)

elif VType==’Lin’:

axSAng.set_xlabel(r”Y (m)”), axNb.set_xlabel(r”Y (m)”)

def Plot_HorSlice_SAngNb_DefAxes(fs=None, wintit=’tofu’):

axCol, fdpi = ‘w’, 80 if fs is None:

fs = (16,8) if Mode.lower()==’all’ else (6,8)

elif type(fs) is str and fs==’a4’:

fs = (11.69,8.27) if Mode.lower()==’all’ else (8.27,11.69)

f = plt.figure(facecolor=”w”, figsize=fs, dpi=fdpi) (fW,fH,fdpi,axCol) = (11.69,8.27,80,’w’) if a4 else (15,8,80,’w’) f = plt.figure(facecolor=”w”,figsize=(fW,fH),dpi=fdpi) axSAng = f.add_axes([0.07, 0.12, 0.35, 0.8],frameon=True,facecolor=axCol) axNb = f.add_axes([0.55, 0.12, 0.35, 0.8],frameon=True,facecolor=axCol) axSAng.set_xlabel(r”X (m)”), axSAng.set_ylabel(r”Y (m)”) axNb.set_xlabel(r”X (m)”), axNb.set_ylabel(r”Y (m)”) axSAng.set_aspect(aspect=”equal”, adjustable=’datalim’) axNb.set_aspect(aspect=”equal”, adjustable=’datalim’) return axSAng, axNb

def Plot_Etendues_GDetect_DefAxes(fs=None, wintit=’tofu’):

axCol, fdpi = ‘w’, 80 if fs is None:

fs = (16,8) if Mode.lower()==’all’ else (6,8)

elif type(fs) is str and fs==’a4’:

fs = (11.69,8.27) if Mode.lower()==’all’ else (8.27,11.69)

f = plt.figure(facecolor=”w”, figsize=fs, dpi=fdpi) (fW,fH,fdpi,axCol) = (11.69,8.27,80,’w’) if a4 else (18,8,80,’w’) f = plt.figure(facecolor=”w”,figsize=(fW,fH),dpi=fdpi) ax = f.add_axes([0.05,0.1,0.85,0.80],frameon=True,facecolor=axCol) ax.set_xlabel(r””) ax.set_ylabel(r”Etendue (sr.m^2)”) return ax

def Plot_Sig_GDetect_DefAxes(fs=None, wintit=’tofu’):

axCol, fdpi = ‘w’, 80 if fs is None:

fs = (16,8) if Mode.lower()==’all’ else (6,8)

elif type(fs) is str and fs==’a4’:

fs = (11.69,8.27) if Mode.lower()==’all’ else (8.27,11.69)

f = plt.figure(facecolor=”w”, figsize=fs, dpi=fdpi) (fW,fH,fdpi,axCol) = (11.69,8.27,80,’w’) if a4 else (18,8,80,’w’) f = plt.figure(facecolor=”w”,figsize=(fW,fH),dpi=fdpi) ax = f.add_axes([0.05,0.1,0.85,0.80],frameon=True,facecolor=axCol) ax.set_xlabel(r””) ax.set_ylabel(r”Signal (W)”) return ax

#Ldict_mlab_Def = {‘color’:(0.,0.,0.),’tube_radius’:None} #Mdict_mlab_Def = {‘color’:(0.,0.,0.),’line_width’:1,’mode’:’sphere’} #Dict_3D_mlab_Tor_Def = {‘color’:(0.8,0.8,0.8),’opacity’:0.15,’transparent’:False,’scale_factor’:0.1}

def Plot_GDetect_Resolution_DefAxes(VType=’Tor’, fs=None, wintit=’tofu’):

axCol, fdpi = ‘w’, 80 if fs is None:

fs = (16,8) if Mode.lower()==’all’ else (6,8)

elif type(fs) is str and fs==’a4’:

fs = (11.69,8.27) if Mode.lower()==’all’ else (8.27,11.69)

f = plt.figure(facecolor=”w”, figsize=fs, dpi=fdpi) axCol = “w” (fW,fH) = (11.69,8.27) if a4 else (16,10) f = plt.figure(figsize=(fW,fH),facecolor=axCol) ax1 = f.add_axes([0.05, 0.06, 0.32, 0.80], frameon=True, facecolor=axCol) ax2 = f.add_axes([0.50, 0.55, 0.47, 0.40], frameon=True, facecolor=axCol) ax3 = f.add_axes([0.50, 0.06, 0.47, 0.40], frameon=True, facecolor=axCol) X1 = r”R (m)” if VType==’Tor’ else r”Y (m)” ax1.set_xlabel(X1) ax1.set_ylabel(r”Z (m)”) ax2.set_xlabel(r”size (a.u.)”) ax2.set_ylabel(r”Signal (mW)”) ax3.set_xlabel(r”Channels index (from 0)”) ax3.set_ylabel(r”Signal (mW)”) ax1.set_aspect(aspect=’equal’,adjustable=’datalim’) return ax1, ax2, ax3

`tofu.geom._def.``Plot_3D_plt_Tor_DefAxes`(fs=None, wintit='tofu')[source]
`tofu.geom._def.``Plot_Impact_DefAxes`(Proj, Ang='theta', AngUnit='rad', fs=None, wintit='tofu', Sketch=True)[source]
`tofu.geom._def.``Plot_LOSProj_DefAxes`(Mode, Type='Tor', fs=None, wintit='tofu')[source]

## tofu.geom._plot module¶

`tofu.geom._plot.``Config_phithetaproj_dist`(config, refpt, dist, indStruct, distonly=False, cmap=None, vmin=None, vmax=None, invertx=None, ax=None, fs=None, cbck=(0.8, 0.8, 0.8, 0.8), tit=None, wintit=None, legend=None, draw=None)[source]
`tofu.geom._plot.``GLOS_plot_Sino`(GLos, Proj='Cross', ax=None, Elt='LV', Sketch=True, Ang='theta', AngUnit='rad', Leg=None, dL={'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, dVes={'edgecolor': (0.8, 0.8, 0.8, 1.0), 'facecolor': (0.8, 0.8, 0.8, 1.0), 'linestyle': 'solid', 'linewidth': 1}, dLeg={'bbox_to_anchor': (1.01, 1), 'borderaxespad': 0.0, 'frameon': False, 'loc': 2, 'ncol': 1, 'prop': {'size': 10}}, ind=None, multi=False, draw=True, fs=None, tit=None, wintit=None, Test=True)[source]
`tofu.geom._plot.``Get_FieldsFrom_LLOS`(L, Fields)[source]
`tofu.geom._plot.``Plot_Impact_3DPoly`(T, Leg='', ax=None, Ang='theta', AngUnit='rad', Pdict={'color': (0.8, 0.8, 0.8, 0.4), 'linestyle': 'solid', 'linewidth': 0}, dLeg={'bbox_to_anchor': (1.01, 1), 'borderaxespad': 0.0, 'frameon': False, 'loc': 2, 'ncol': 1, 'prop': {'size': 10}}, draw=True, fs=None, wintit='tofu-1.4.6-2-g7a0d42d4 report issues / requests at https://github.com/ToFuProject/tofu/issues', Test=True)[source]

Plotting the toroidal projection of a Ves instance

D. VEZINET, Aug. 2014 Inputs :

T A Ves instance Leg A str (the legend label to be used if T is not a Ves instance) ax A plt.Axes instance (if given) on which to plot the projection space, otherwise (‘None’) a new figure/axes is created Dict A dictionnary specifying the style of the boundary polygon plot dLeg A dictionnary specifying the style of the legend box

Outputs :

ax The plt.Axes instance on which the poloidal plot was performed

`tofu.geom._plot.``Plot_Impact_PolProjPoly`(lS, Leg='', ax=None, Ang='theta', AngUnit='rad', Sketch=True, dP=None, dLeg={'bbox_to_anchor': (1.01, 1), 'borderaxespad': 0.0, 'frameon': False, 'loc': 2, 'ncol': 1, 'prop': {'size': 10}}, draw=True, fs=None, wintit=None, tit=None, Test=True)[source]

Plotting the toroidal projection of a Ves instance

D. VEZINET, Aug. 2014 Inputs :

T A Ves instance Leg A str (the legend label to be used if T is not a Ves instance) ax A plt.Axes instance (if given) on which to plot the projection space, otherwise (‘None’) a new figure/axes is created Dict A dictionnary specifying the style of the boundary polygon plot dLeg A dictionnary specifying the style of the legend box

Outputs :

ax The plt.Axes instance on which the poloidal plot was performed

`tofu.geom._plot.``Rays_plot`(GLos, Lax=None, Proj='all', reflections=True, Lplot='Tot', element='LDIORP', element_config='P', Leg=None, dL=None, dPtD={'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, dPtI={'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, dPtO={'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, dPtR={'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, dPtP={'c': 'k', 'ls': 'None', 'lw': 2, 'marker': 'x', 'markersize': 8, 'mew': 2}, dLeg={'bbox_to_anchor': (1.01, 1), 'borderaxespad': 0.0, 'frameon': False, 'loc': 2, 'ncol': 1, 'prop': {'size': 10}}, multi=False, draw=True, fs=None, wintit=None, tit=None, Test=True, ind=None)[source]
`tofu.geom._plot.``Rays_plot_touch`(cam, key=None, ind=None, quant='lengths', cdef='k', invert=None, Bck=True, cbck=(0.8, 0.8, 0.8), Lplot='In', incch=[1, 10], ms=4, cmap='touch', vmin=None, vmax=None, fmt_ch='02.0f', labelpad=0, dmargin=None, nchMax=4, lcch=[(0.8392156862745098, 0.15294117647058825, 0.1568627450980392), (0.5803921568627451, 0.403921568627451, 0.7411764705882353), (0.5490196078431373, 0.33725490196078434, 0.29411764705882354), (1.0, 0.596078431372549, 0.5882352941176471), (0.7725490196078432, 0.6901960784313725, 0.8352941176470589), (0.7686274509803922, 0.611764705882353, 0.5803921568627451)], fs=None, wintit=None, tit=None, fontsize=8, draw=True, connect=True)[source]
`tofu.geom._plot.``Struct_plot`(lS, lax=None, proj='all', element=None, dP=None, dI=None, dBs=None, dBv=None, dVect=None, dIHor=None, dBsHor=None, dBvHor=None, Lim=None, Nstep=None, dLeg=None, indices=False, draw=True, fs=None, wintit=None, tit=None, Test=True)[source]

Plot the projections of a list of Struct subclass instances

D. VEZINET, Aug. 2014 Inputs :

V A Ves instance Nstep An int (the number of points for evaluation of theta by np.linspace) axP A plt.Axes instance (if given) on which to plot the poloidal projection, otherwise (‘None’) a new figure/axes is created axT A plt.Axes instance (if given) on which to plot the toroidal projection, otherwise (‘None’) a new figure/axes is created Tdict A dictionnary specifying the style of the polygon plot dLeg A dictionnary specifying the style of the legend box (if None => no legend)

Outputs :

axP The plt.Axes instance on which the poloidal plot was performed axT The plt.Axes instance on which the toroidal plot was performed

## tofu.geom._plot_optics module¶

`tofu.geom._plot_optics.``CrystalBragg_plot`(cryst, lax=None, proj=None, res=None, element=None, color=None, dP=None, det_cent=None, det_nout=None, det_ei=None, det_ej=None, dI=None, dBs=None, dBv=None, dVect=None, dIHor=None, dBsHor=None, dBvHor=None, dleg=None, indices=False, draw=True, fs=None, wintit=None, tit=None, Test=True)[source]
`tofu.geom._plot_optics.``CrystalBragg_plot_approx_detector_params`(Rrow, bragg, d, Z, frame_cent, nn)[source]
`tofu.geom._plot_optics.``CrystalBragg_plot_braggangle_from_xixj`(xi=None, xj=None, bragg=None, angle=None, ax=None, plot=None, braggunits='rad', angunits='rad', **kwdargs)[source]
`tofu.geom._plot_optics.``CrystalBragg_plot_data_vs_fit`(xi, xj, bragg, lamb, phi, data, mask=None, lambfit=None, phifit=None, spect1d=None, dfit1d=None, dfit2d=None, lambfitbins=None, cmap=None, vmin=None, vmax=None, fs=None, dmargin=None, angunits='deg', dmoments=None)[source]
`tofu.geom._plot_optics.``CrystalBragg_plot_data_vs_lambphi`(xi, xj, bragg, lamb, phi, data, lambfit=None, phifit=None, spect1d=None, vertsum1d=None, lambax=None, phiax=None, cmap=None, vmin=None, vmax=None, fs=None, dmargin=None, angunits='deg')[source]
`tofu.geom._plot_optics.``CrystalBragg_plot_johannerror`(xi, xj, lamb, phi, err_lamb, err_phi, cmap=None, vmin=None, vmax=None, fs=None, dmargin=None, wintit=None, tit=None, angunits='deg', err=None)[source]
`tofu.geom._plot_optics.``CrystalBragg_plot_line_tracing_on_det`(lamb, xi, xj, xi_err, xj_err, det=None, johann=None, rocking=None, fs=None, dmargin=None, wintit=None, tit=None)[source]
`tofu.geom._plot_optics.``CrystalBragg_plot_rockingcurve`(Rmax=None, sigma=None, bragg=None, delta_bragg=None, npts=None)[source]
`tofu.geom._plot_optics.``CrystalBragg_plot_xixj_from_braggangle`(bragg=None, xi=None, xj=None, data=None, ax=None)[source]

## tofu.geom.utils module¶

`tofu.geom.utils.``coords_transform`(pts, coords_in='11', coords_out='11')[source]
`tofu.geom.utils.``get_nIne1e2`(P, nIn=None, e1=None, e2=None)[source]
`tofu.geom.utils.``get_X12fromflat`(X12, x12u=None, nx12=None)[source]
`tofu.geom.utils.``compute_RaysCones`(Ds, us, angs=0.03490658503988659, nP=40)[source]
`tofu.geom.utils.``get_available_config`(dconfig={'AUG-V1': {'Exp': 'AUG', 'PFC': ['D2cdome', 'D2cdomL', 'D2cdomR', 'D2ci1', 'D2ci2', 'D2cTPib', 'D2cTPic', 'D2cTPi', 'D2dBG2', 'D2dBl1', 'D2dBl2', 'D2dBl3', 'D2dBu1', 'D2dBu2', 'D2dBu3', 'D2dBu4', 'D3BG10', 'D3BG1', 'ICRHa', 'LIM09', 'PClow', 'PCup', 'SBi', 'TPLT1', 'TPLT2', 'TPLT3', 'TPLT4', 'TPLT5', 'TPRT2', 'TPRT3', 'TPRT4', 'TPRT5'], 'Ves': ['VESiR']}, 'DEMO-2019': {'Exp': 'DEMO', 'PFC': ['LimiterUpperV0', 'LimiterEquatV0', 'BlanketInnerV0', 'BlanketOuterV0', 'DivertorV0'], 'Ves': ['V0']}, 'ITER-V1': {'Exp': 'ITER', 'Ves': ['V0']}, 'ITER-V2': {'Exp': 'ITER', 'PFC': ['BLK01', 'BLK02', 'BLK03', 'BLK04', 'BLK05', 'BLK06', 'BLK07', 'BLK08', 'BLK09', 'BLK10', 'BLK11', 'BLK12', 'BLK13', 'BLK14', 'BLK15', 'BLK16', 'BLK17', 'BLK18', 'Div1', 'Div2', 'Div3', 'Div4', 'Div5', 'Div6'], 'Ves': ['V1']}, 'JET-V0': {'Exp': 'JET', 'Ves': ['V0']}, 'NSTX-V0': {'Exp': 'NSTX', 'Ves': ['V0']}, 'TOMAS-V0': {'Exp': 'TOMAS', 'PFC': ['LimiterV0', 'AntennaV0'], 'Ves': ['V0']}, 'WEST-Sep': {'Exp': 'WEST', 'PlasmaDomain': ['Sep']}, 'WEST-V1': {'Exp': 'WEST', 'Ves': ['V1']}, 'WEST-V2': {'Exp': 'WEST', 'PFC': ['BaffleV0', 'DivUpV1', 'DivLowITERV1'], 'Ves': ['V2']}, 'WEST-V3': {'Exp': 'WEST', 'PFC': ['BaffleV1', 'DivUpV2', 'DivLowITERV2', 'BumperInnerV1', 'BumperOuterV1', 'IC1V1', 'IC2V1', 'IC3V1'], 'Ves': ['V2']}, 'WEST-V4': {'Exp': 'WEST', 'PFC': ['BaffleV2', 'DivUpV3', 'DivLowITERV3', 'BumperInnerV3', 'BumperOuterV3', 'IC1V1', 'IC2V1', 'IC3V1', 'LH1V1', 'LH2V1', 'RippleV1', 'VDEV0'], 'Ves': ['V2']}}, dconfig_shortcuts={'A1': 'WEST-V1', 'A2': 'ITER-V1', 'A3': 'WEST-Sep', 'AUG': 'AUG-V1', 'B1': 'WEST-V2', 'B2': 'WEST-V3', 'B3': 'WEST-V4', 'B4': 'ITER-V2', 'DEMO': 'DEMO-2019', 'ITER': 'ITER-V2', 'JET': 'JET-V0', 'NSTX': 'NSTX-V0', 'TOMAS': 'TOMAS-V0', 'WEST': 'WEST-V4'}, verb=True, returnas=False)[source]

Print a table showing all pre-defined config

Each pre-defined config in tofu can be called by its unique name or by a series of shortcuts / alterantive names refereing to the same unique name. this feature is useful for retro-compatibility and for making sure a standard name always refers to the latest (most detailed) available version of the geometry.

Can also return the table as str

No input arg needed:
```>>> import tofu as tf
>>> tf.geom.utils.get_available_config()
```
`tofu.geom.utils.``create_config`(case=None, Exp='Dummy', Type='Tor', Lim=None, Bump_posextent=[0.7853981633974483, 0.7853981633974483], R=None, r=None, elong=None, Dshape=None, divlow=None, divup=None, nP=None, returnas='object', SavePath='./', path='/home/lasofivec/tofu/tofu/geom/inputs')[source]

Create easily a tofu.geom.Config object

In tofu, a Config (short for geometrical configuration) refers to the 3D geometry of a fusion device. It includes, at least, a simple 2D polygon describing the first wall of the fusion chamber, and can also include other structural elements (tiles, limiters…) that can be non-axisymmetric.

To create a simple Config, provide either the name of a reference test case, of a set of geometrical parameters (major radius, elongation…).

This is just a tool for fast testing, if you want to create a custom config, use directly tofu.geom.Config and provide the parameters you want.

Parameters
• case (str) – The name of a reference test case, if provided, this arguments is sufficient, the others are ignored

• Exp (str) – The name of the experiment

• Type (str) – The type of configuration (toroidal ‘Tor’ or linear ‘Lin’)

• Lim_Bump (list) – The angular (poloidal) limits, in the cross-section of the extension of the outer bumper

• R (float) – The major radius of the center of the cross-section

• r (float) – The minor radius of the cross-section

• elong (float) – An elongation parameter (in [-1;1])

• Dshape (float) – A parameter specifying the D-shape of the cross-section (in [-1;1])

• divlow (bool) – A flag specifying whether to include a lower divertor-like shape

• divup (bool) – A flag specifying whether to include an upper divertor-like shape

• nP (int) – Number of points used to describe the cross-section polygon

• out (str) –

FLag indicating whether to return:
• ’dict’ : the polygons as a dictionary of np.ndarrays

• ’object’: the configuration as a tofu.geom.Config instance

Returns

conf (tofu.geom.Config / dict) –

Depending on the value of parameter out, either:
• the tofu.geom.Config object created

• a dictionary of the polygons and their pos/extent (if any)

`tofu.geom.utils.``create_CamLOS1D`(case=None, nD=1, Etendues=None, Surfaces=None, dchans=None, Exp=None, Diag=None, Name=None, color=None, P=None, F=0.1, D12=0.1, N12=100, method=None, angs=[-3.141592653589793, 0.0, 0.0], nIn=None, VType='Tor', dcam={'V1': {'D12': [0.3, 0.1], 'F': 0.1, 'N12': [1, 1], 'P': [1.5, -3.2, 0.0], 'nIn': [-0.5, 1.0, 0.0]}, 'V10': {'D12': [0.3, 0.1], 'F': 0.1, 'N12': [5, 2], 'P': [1.5, 3.2, 0.0], 'nIn': [-0.5, -1.0, 0.0]}, 'V100': {'D12': [0.3, 0.1], 'F': 0.1, 'N12': [20, 5], 'P': [1.5, 3.2, 0.0], 'nIn': [-0.5, -1.0, 0.0]}, 'V1000': {'D12': [0.3, 0.1], 'F': 0.1, 'N12': [50, 20], 'P': [1.5, 3.2, 0.0], 'nIn': [-0.5, -1.0, 0.0]}, 'V10000': {'D12': [0.3, 0.1], 'F': 0.1, 'N12': [125, 80], 'P': [1.5, 3.2, 0.0], 'nIn': [-0.5, -1.0, 0.0]}, 'V100000': {'D12': [0.3, 0.1], 'F': 0.1, 'N12': [500, 200], 'P': [1.5, 3.2, 0.0], 'nIn': [-0.5, -1.0, 0.0]}, 'V1000000': {'D12': [0.3, 0.1], 'F': 0.1, 'N12': [1600, 625], 'P': [1.5, 3.2, 0.0], 'nIn': [-0.5, -1.0, 0.0]}, 'VA1': {'D12': [0.4, 0.3], 'F': 0.1, 'N12': [1, 1], 'P': [4.9, -6.9, 0.0], 'nIn': [-0.75, 1.0, 0.0]}, 'VA10': {'D12': [0.4, 0.3], 'F': 0.1, 'N12': [5, 2], 'P': [4.9, -6.9, 0.0], 'nIn': [-0.75, 1.0, 0.0]}, 'VA100': {'D12': [0.4, 0.3], 'F': 0.1, 'N12': [20, 5], 'P': [4.9, -6.9, 0.0], 'nIn': [-0.75, 1.0, 0.0]}, 'VA1000': {'D12': [0.4, 0.3], 'F': 0.1, 'N12': [50, 20], 'P': [4.9, -6.9, 0.0], 'nIn': [-0.75, 1.0, 0.0]}, 'VA10000': {'D12': [0.4, 0.3], 'F': 0.1, 'N12': [125, 80], 'P': [4.9, -6.9, 0.0], 'nIn': [-0.75, 1.0, 0.0]}, 'VA100000': {'D12': [0.4, 0.3], 'F': 0.1, 'N12': [500, 200], 'P': [4.9, -6.9, 0.0], 'nIn': [-0.75, 1.0, 0.0]}, 'VA1000000': {'D12': [0.4, 0.3], 'F': 0.1, 'N12': [1600, 625], 'P': [4.9, -6.9, 0.0], 'nIn': [-0.75, 1.0, 0.0]}, 'testV': {'D12': [0.3, 0.1], 'F': 0.4, 'N12': [1600, 625], 'P': [1.5, 3.2, 0.0], 'nIn': [-0.5, -1.0, 0.0]}}, defRY=None, Lim=None, config=None, out=<class 'object'>, SavePath='./')[source]

Create a pinhole CamLOS1D

In tofu, a CamLOS is a camera described as a set of Lines of Sight (LOS), as opposed to a Cam, where the Volume of Sight (VOS) of all pixels are computed in 3D. The CamLOS is then a simplified approximation of the Cam. It can be:

• 1D : like when all LOS are included in a common plane

• 2D : like a regular everyday camera, producing a 2D image

For a pinhole camera, all LOS pass through a common point (pinhole)

This function provides an easy way to create a pinhole CamLOS1D In tofu, LOS are described as semi-lines using:

• a starting point (D)

• a unit vector (u)

All coordinates are 3D cartesian (X,Y,Z)

Here, you simply need to provide, either:
• the name of a standard test case

• a set of geometrical parameters:
• P: pinhole, throught the camera axis passes

• F: focal length

• D12 : dimensiosn perpendicular to the camera axis

• N12 : number of pixels (LOS)

• angs: 3 angles defining the orientation of the camera

The computed set of LOS, optionnaly associated to a Config, can then be returned as:

• a tofu object (i.e.: a CamLOS1D)

• a set of starting points (D) and unit vectors (u)

• a set of starting points (D), a pinhole, and and the coordinates of D

in the camera frame

`tofu.geom.utils.``create_CamLOS2D`(case=None, nD=1, Etendues=None, Surfaces=None, dchans=None, Exp=None, Diag=None, Name=None, color=None, P=None, F=0.1, D12=0.1, N12=100, method=None, angs=[-3.141592653589793, 0.0, 0.0], nIn=None, VType='Tor', dcam={'V1': {'D12': [0.3, 0.1], 'F': 0.1, 'N12': [1, 1], 'P': [1.5, -3.2, 0.0], 'nIn': [-0.5, 1.0, 0.0]}, 'V10': {'D12': [0.3, 0.1], 'F': 0.1, 'N12': [5, 2], 'P': [1.5, 3.2, 0.0], 'nIn': [-0.5, -1.0, 0.0]}, 'V100': {'D12': [0.3, 0.1], 'F': 0.1, 'N12': [20, 5], 'P': [1.5, 3.2, 0.0], 'nIn': [-0.5, -1.0, 0.0]}, 'V1000': {'D12': [0.3, 0.1], 'F': 0.1, 'N12': [50, 20], 'P': [1.5, 3.2, 0.0], 'nIn': [-0.5, -1.0, 0.0]}, 'V10000': {'D12': [0.3, 0.1], 'F': 0.1, 'N12': [125, 80], 'P': [1.5, 3.2, 0.0], 'nIn': [-0.5, -1.0, 0.0]}, 'V100000': {'D12': [0.3, 0.1], 'F': 0.1, 'N12': [500, 200], 'P': [1.5, 3.2, 0.0], 'nIn': [-0.5, -1.0, 0.0]}, 'V1000000': {'D12': [0.3, 0.1], 'F': 0.1, 'N12': [1600, 625], 'P': [1.5, 3.2, 0.0], 'nIn': [-0.5, -1.0, 0.0]}, 'VA1': {'D12': [0.4, 0.3], 'F': 0.1, 'N12': [1, 1], 'P': [4.9, -6.9, 0.0], 'nIn': [-0.75, 1.0, 0.0]}, 'VA10': {'D12': [0.4, 0.3], 'F': 0.1, 'N12': [5, 2], 'P': [4.9, -6.9, 0.0], 'nIn': [-0.75, 1.0, 0.0]}, 'VA100': {'D12': [0.4, 0.3], 'F': 0.1, 'N12': [20, 5], 'P': [4.9, -6.9, 0.0], 'nIn': [-0.75, 1.0, 0.0]}, 'VA1000': {'D12': [0.4, 0.3], 'F': 0.1, 'N12': [50, 20], 'P': [4.9, -6.9, 0.0], 'nIn': [-0.75, 1.0, 0.0]}, 'VA10000': {'D12': [0.4, 0.3], 'F': 0.1, 'N12': [125, 80], 'P': [4.9, -6.9, 0.0], 'nIn': [-0.75, 1.0, 0.0]}, 'VA100000': {'D12': [0.4, 0.3], 'F': 0.1, 'N12': [500, 200], 'P': [4.9, -6.9, 0.0], 'nIn': [-0.75, 1.0, 0.0]}, 'VA1000000': {'D12': [0.4, 0.3], 'F': 0.1, 'N12': [1600, 625], 'P': [4.9, -6.9, 0.0], 'nIn': [-0.75, 1.0, 0.0]}, 'testV': {'D12': [0.3, 0.1], 'F': 0.4, 'N12': [1600, 625], 'P': [1.5, 3.2, 0.0], 'nIn': [-0.5, -1.0, 0.0]}}, defRY=None, Lim=None, config=None, out=<class 'object'>, SavePath='./')[source]

Create a pinhole CamLOS2D

In tofu, a CamLOS is a camera described as a set of Lines of Sight (LOS), as opposed to a Cam, where the Volume of Sight (VOS) of all pixels are computed in 3D. The CamLOS is then a simplified approximation of the Cam. It can be:

• 1D : like when all LOS are included in a common plane

• 2D : like a regular everyday camera, producing a 2D image

For a pinhole camera, all LOS pass through a common point (pinhole)

This function provides an easy way to create a pinhole CamLOS2D In tofu, LOS are described as semi-lines using:

• a starting point (D)

• a unit vector (u)

All coordinates are 3D cartesian (X,Y,Z)

Here, you simply need to provide, either:
• the name of a standard test case

• a set of geometrical parameters:
• P: pinhole, throught the camera axis passes

• F: focal length

• D12 : dimensiosn perpendicular to the camera axis

• N12 : number of pixels (LOS)

• angs: 3 angles defining the orientation of the camera

The computed set of LOS, optionnaly associated to a Config, can then be returned as:

• a tofu object (i.e.: a CamLOS2D)

• a set of starting points (D) and unit vectors (u)

• a set of starting points (D), a pinhole, and and the coordinates of D

in the camera frame