Open Didou09 opened 2 years ago
Hey Didier, wanted to flag this error I get when I run essentially this same code you provided, but edit dgeom
to dgeom{'Type' : 'flat'}
. Seems to be an issue with sample_outline_plot()
having an if statement with instructions only for the spherical crystal. In general, I get the sense from reading the source code that all the plotting tools are optimized for the spherical crystal. Isn't surprising.
I wanted to start with a flat crystal because I expected it to be so simple everything already worked. If you're aware of a workaround then feel to let me know. I'd have to deal with the same plotting upgrades for the cylindrical crystal and would like to validate my math in the limit of the crystal becoming flat, so not an inconvenience if you'd just recommend getting the plotting for both to work
No problem, will try to handle this tomorrow morning
@Didou09 I'm going to make some changes in the ray-tracing calculations to handle flat and cylindrical crystal reflections. This will be focusing on functions such as get_local_noute1e2()
, get_rays_from_cryst()
, _get_rays_from_cryst()
, and calc_raytracing_from_lambpts()
. I won't change much that's already there for the spherical crystal. Just encompass what's there with an if statement based on the geometry.
I will need to change how the code handles points on the crystal surface as it's hardcoded to be in terms of two rotational distances (dtheta, psi) from the summit, so native to spherical. The cylindrical crystal will do something similar, but in terms of a rotational and translational distance (will define the cylinder axis to be along e1) while the flat will be in terms of two translational variables (along e1, e2). Since these variables are often passed within many functions, I think it might be easiest to group these variables into a single dictionary to be passed around with the variables contained returning to their original usage within the relevant geometry.
Motivations:
Main routines to update:
The CrystalBragg class is defined in
tofu/geom/_core_optics.py
Don't be frightened away by the look of the class, it was coded quite some time away and there is some legacy code in there, but I'll help and all this will be refactored / cleaned-up / harmonized on the mid-term (some of my initial ideas turned out not so useful and others need implementing).
The main methods to start with are:
set_dgeom()
, which calls_check_optics._checkformat_dgeom()
set_dmat()
, which calls_check_optics._checkformat_dmat()
set_dbragg()
, which calls_check_optics._checkformat_dbragg()
These are called at instanciation.
sample_outline_plot()
: samples the outline of the crystal, for plottingget_local_noute1e2()
: compute, for each ray impacting the crystal, the local unit vectors defining a direct orthonormal frame (nout, e1, e2) locally at each impact point, taking into acccount the local curvature and optionally a miscut._get_rays_from_cryst()
andget_rays_from_cryst()
: used for ray-tracingsplit()
: to split the crystal in halves (useful only for WEST, low-priority)plot()
: plottingcalc_meridional_sagital_focus()
: get meridional / sagital distances from summitcalc_xixj_from_braggphi()
: compute the local coordinates on a detector (xi
,xj
) of rays coming from the crystal to the detector.plot_line_on_det_tracing()
:calc_johannerror()
: rayt-tracing on the whole surface of the crystal, to a detector, and computation of the maximum wavelength discrepancy for each pixel.get_lamb_avail_from_pts()
: for each poits in the plasma, compute the wavelength interval that is accessible as seen from the cryst + detector pair.calc_raytracing_from_lambpts()
: ray-tracing from plasma points at given wavelengthsThere are other methods, but these are the main ones (we'll see later if we add some more). There are quite a few, but I think that if the lower-level ones are correctly handled, most of the upper-level ones will work automatically, so actually I don't think there is so much work.
get_detector_ideal()
: compute the position of an ideally-positionned detector for a given wavelenght (and a given source position, the real detector position is usually a small variation in the neighbourhood if that ideal detector)You will find methods about rocking curve and fitting, no need to look at these for the moment (the ones about rocking curves are within the scope of issue #654.
Suggestions:
Issue656_CylindricalCrystal
to address this issueCurrent use of the CrystalBragg class:
A
CrystalBragg
instance is defined based on 3 dictionaries:dgeom
: holds the purely geometrical parameters (type of geometry, position, orientation with unit vectors, dimensions as half-extent, ...)dmat
: holds everything specific to the material of the crystal (formula, density, mesh symmetry, mesh lengths and angles, Miller indices of the cut, optional miscut angles, orientation of the lattice - if there is a miscut and the lattice is not parallel to the optical surface - with unit vectors...)dbragg
: holds everything specific to bragg diffraction (tabulated rocking curve, wavelength of reference...)All positions / unit vectors in tofu are always defined in
(X, Y, Z)
cartesian coordinates taken from the absolute frame of the tokamak (where, at a toroidal angle ofphi = 0
, the unit vector ofX
equals the unit vector ofR
).Some of the quantities in these dictionaries do not need to be provided by the user and are instead automatically computed from others (ex: unit vectors of the lattice orientation are computed for the values of miscut angles
alpha
andbeta
, which are 0 by default).In addition to the 3 disctionnary, the current version of tofu asks for an
Exp
(name of the tokamak, in upper case),Diag
(name fo the diagnostic) and aName
(name of that particular crystal, in case your diagnostic has several crystals). This may evolve in the future.Direct copy-pasting into an ipython console should work for all the snippets below, provided you don't include the
In [1]:
.The crystal is oriented in 3d using a direct orthonormal base (nout, e1, e2) at its summit
Typically one of the unit vectors is horizontal (here
e1
).Instanciation and use:
Plotting: the plotting method (
plot()
) provides a static figure with:This method will have to be adapted for cylindrical crystal because by default it plots a rowland circle. It returns a dict of axes, and may raise some harmless warnings.
Optionally, it can include the plot of a detector (defined using a dict with center position
cent
, unit vectors (nout
,ei
,ej
) and 2doutline
as(2, npts)
array), I recommend you save it as .npz and load it when needed (in a near-future a specific class will be created).Optionnaly you can also add ray-tracing from pts in the plasma at chosen wavelength.
The ray-tracing is computed for the grid {all pts} x {all lamb}. Coloring is done:
rays_color='pts'
, default)rays_color='lamb'
)