irfpy.vima.fov
¶
Field of view of VEX/IMA
VEX/IMA field of view is handled in this module.
Warning
The function get_elevation_table()
(and get_elevation_table_v2()
) contains
a critical bug for the version before v4.4.1a3.
The users must upgrade to v4.5 or later.
pip install --find-links=https://irfpy.irf.se/sdist irfpy.aspera -U
There are two types of approach.
Geometric FOV (a.k.a Simple FOV)
Table FOV
The geometric FOV is calculated under the assumption that the elevaion and azimuth angles are equally separated in the angular space. It is also the approach that is used for SPICE. Benefits are an intuitive calculation of the angles as well as an easy inverse calculation (from a vector to the bin).
The table FOV approach is using tables produced for setting of the instrument. It is not separated in a regular grid, but provides more accurate way of careful analyses.
Both approches are provided by this module.
The geometric FOV can be started from
>>> gfov = SimpleFOV()
and the table FOV from
>>> tfov = TableFOV()
For any methods in the table FOV, the table id should be provided as an argument.
There are two elevation tables, 2
and 3
.
They are corresponding to the energy tables version 1
and 3
, respectively.
To get the viewing direction, you can do as follows.
>>> print(gfov.viewvector_imasframe(5, 7)) # Azim=5, Elev=7
[ 0.83046807 0.55490102 -0.04906767]
>>> print(tfov.viewvector_imasframe(2, 5, 7, 30)) # Table v2, Azim=5, Elev=7, EneStep=30
[ 0.83047695 0.55490696 -0.04884977]
>>> print(tfov.viewvector_imasframe(3, 5, 7, 30)) # Table v3, Azim=5, Elev=7, Enestep=30
[ 0.83079978 0.55512266 -0.04013179]
These vectors are in the so-called IMAS frame. The name comes from SPICE.
General notice
Warning
It is known that the fov table has been swapped for the version before 4.1.1a3. At the release of v4.2.0, the energy table has been fixed.
The FOV is sometimes confusing. Users should be careful about
What coordinate system is used.
Whether the looking or velocity direction is needed.
Definition of zero-angle, and which direction it increases.
The coordinate system is (sometimes) defined arbitrarily. In particular,
What is the definition of zero angle?
What is the plus, and minus?
The unit is in degrees or in radians?
Original documents may sometimes not include enough information or even sometimes wrongly described. Be careful!!
The looking or velocity directions make the results completely anti-parallel. The original documents sometimes lack the definition.
Below, be careful about all the issues above, and if you find any problems or difficulties, please ask to the developers for clarification and debugging.
Relation to SPICE
This irfpy.vima.fov
module has no dependency on SPICE. However,
SPICE is a good tool to investigate the sensor looking/coming directions.
But note that the SPICE kernel only support the “geometric” polar direction, i.e. energy-independent.
See irfpy.vexpvat.vexspice
module.
- irfpy.vima.fov.get_azimuth_angle(azim_nr, direction='look')[source]¶
Return the azimuthal angle corresponding to the index.
The derivation is simply:
\[\Phi = 78.75 - 22.5 imes \mathrm{Index}\]for looking direction. It indicates that
Index 3.5 is zero degrees.
Index 7.5 is -90 degrees.
- Parameters
azim_nr – Azimuthal index number. The index number is generalized to the real number, and to below zero or above 15. For example, index 0 means the center direction of the bin 0. Index 3.5 gives the direction between 3 and 4.
direction – Either ‘look’ or ‘velocity’.
- Returns
The azimuthal angle. definition follows the IMA bible.
>>> get_azimuth_angle(0) 78.75 >>> get_azimuth_angle(3.5) 0.0 >>> get_azimuth_angle(3.5, direction='velocity') 180.0
- irfpy.vima.fov.get_elevation_geometric(elev_nr, direction='look')[source]¶
Return the “geometric” elevation angle corresponding to the index.
zero angle is defined as the middle plane of the scanning electrode. Positive toward higher elevation index for looking angle.
- Parameters
elev_nr – Elevation index number. Floating values are allowed.
direction – Either ‘look’ or ‘velocity’.
- Returns
The elevation angle.
- irfpy.vima.fov.get_elevation_table(elev_idx, energy_idx, elevation_table_version, direction='look')[source]¶
Elevation angle based on the table provided in IMA bible.
The elevation table depends not only the elevation index, but also the energy step. This function returns the elevation angle as a function of the elevation index and energy index.
The elevation table depends on the energy table. Two elevation tables are prepared, namely versions 2 and 3. The elevation table version 2 corresponds to energy table version 1. The elevation table version 3 corresponds to energy table version 3. For energy table version, see also
irfpy.vima.energy
module.In addition, “-1” will give you a geometric table (
get_elevation_geometric()
)- Parameters
elev_idx – Elevation index. -1, 2, or 3.
energy_idx – Energy index.
elevation_table_version – Energy table version, either
2
or3
.direction – Either ‘look’ or ‘velocity’.
- Returns
The elevation angle. If “invalid” (non-measurable case), masked value is returned.
>>> print(get_elevation_table(2, 40, '2', direction='look')) -30.8 >>> print(get_elevation_table(2, 40, 2, direction='velocity')) 30.8
>>> print(get_elevation_table(2, 55, '3', direction='look')) -26.3 >>> print(get_elevation_table(2, 55, 3, direction='velocity')) 26.3 >>> print(get_elevation_table(0, 0, '3')) --
- irfpy.vima.fov.get_elevation_table_v2(elev_index, energy_index, direction='look')[source]¶
Elevation angle based on the table provided in IMA bible. Version 2, corr. to energy table v1.
See details in
get_elevation_table()
function, which calls this function withenergy_table_version
to be2
.- Parameters
elev_index – Elevation index.
energy_index – Energy index.
direction – Either ‘look’ or ‘velocity’.
- Returns
The corresponding angle. If “invalid” (non-measurable case), masked value is returned.
>>> print(get_elevation_table_v2(2, 40, direction='look')) -30.8
- irfpy.vima.fov.get_elevation_table_v3(elev_index, energy_index, direction='look')[source]¶
Elevation angle based on the table provided in IMA bible. Version 3 Fov table corresponds to energy table v3.
See details in
get_elevation_table()
function, which calls this function withenergy_table_version
to be3
.- Parameters
elev_index – Elevation index.
energy_index – Energy index.
direction – Either ‘look’ or ‘velocity’.
- Returns
The corresponding angle. If “invalid” (non-measurable case), masked value is returned.
>>> print(get_elevation_table_v3(3, 45)) -23.2 >>> print(get_elevation_table_v3(3, 45, direction='velocity')) 23.2 >>> print(get_elevation_table_v3(0, 0)) --
- irfpy.vima.fov.get_shadow_mask()[source]¶
Return the shadow mask index.
Shadow mask is implemented in the on-board computer.
- Returns
(A16, P16) table with boolean.
- Return type
np.array with each element as boolean. True bins are blocked.
You can get a boolean array as follows:
>>> shadow_mask = get_shadow_mask() >>> print(shadow_mask.shape) (16, 16)
For example, (A=12, P=1) is masked.
>>> print(shadow_mask[12, 1]) True
On the other hand, (A=1, P=12) is unmasked.
>>> print(shadow_mask[1, 12]) False
The original code in the IMA software is as follows.
int shadow[16] = // Entrance index. {0x02CF, // 0 0x04CF, // 1 0x04CF, // 2 0x04CF, // 3 0x04CF, // 4 0x04CF, // 5 0x03CF, // 6 0x12CF, // 7 0x22FF, // 8 0xFF00, // 9 0xFF00, // 10 0x00EF, // 11 0x00EF, // 12 0x00EF, // 13 0x00EF, // 14 0x00EF // 15};
- irfpy.vima.fov.edge_shadow_mask()[source]¶
Return a list of index of edge of the shadow mask.
- Returns
A tuple with two element.
((a0, a1, a2, ...), (p0, p1, p2, ...))
a0
andp0
is the azimuth/polar index of the first point, and follows…
>>> alist, plist = edge_shadow_mask() >>> import matplotlib.pyplot as plt >>> plt.plot(alist, plist)
- class irfpy.vima.fov.TableFOV[source]¶
Bases:
object
The class represents the FoV based on the setting tables.
table id=2, Default table, called v2. (
get_elevation_table_v2()
).table id=3, Updated table, called v3. (
get_elevation_table_v3()
).
>>> tfov = TableFOV() >>> sfov = SimpleFOV()
For higher energies, the
TableFOV
andSimpleFOV
returns very similar values.For Azimuth=8, Elev=2, for Estep=10.
>>> tv = tfov.viewvector_imasframe(2, 8, 2, 10) # For v2, estep=10 >>> tv3 = tfov.viewvector_imasframe(3, 8, 2, 10) # For v3 >>> sv = sfov.viewvector_imasframe(8, 2)
>>> print('{vv[0]:.3f} {vv[1]:.3f} {vv[2]:.3f}'.format(vv=tv)) -0.168 0.842 -0.512 >>> print('{vv[0]:.3f} {vv[1]:.3f} {vv[2]:.3f}'.format(vv=tv3)) -0.168 0.843 -0.511 >>> print('{vv[0]:.3f} {vv[1]:.3f} {vv[2]:.3f}'.format(vv=sv)) -0.167 0.841 -0.514
However, for lower energies, the value deviate, in particular for v3.
>>> tv = tfov.viewvector_imasframe(2, 8, 2, 75) # For v2, estep=75 >>> tv3 = tfov.viewvector_imasframe(3, 8, 2, 75) # For v3 >>> sv = sfov.viewvector_imasframe(8, 2)
>>> print('{vv[0]:.3f} {vv[1]:.3f} {vv[2]:.3f}'.format(vv=tv)) -0.168 0.846 -0.506 >>> print('{vv[0]:.3f} {vv[1]:.3f} {vv[2]:.3f}'.format(vv=tv3)) -0.195 0.979 -0.052 >>> print('{vv[0]:.3f} {vv[1]:.3f} {vv[2]:.3f}'.format(vv=sv)) -0.167 0.841 -0.514
For outside the aperutre (elev>45 or elev<45 degrees), corresponding vector values are returned if
only_in_fov
keyword is set to True.>>> tv3 = tfov.viewvector_imasframe(3, 2, 15, 80) # For elevation 15, energy 80. It is masked. >>> print(tv3) [-- -- --]
>>> tv3 = tfov.viewvector_imasframe(3, 2, 15, 80, only_in_fov=False) # For elevation 15, energy 80. It is masked. >>> print(tv3) [ 0.09700817 -0.06481879 0.99317065]
For low energies (negative energy steps), the masked value will be returned.
>>> tv3 = tfov.viewvector_imasframe(3, 8, 2, 95) >>> print(tv3) [-- -- --]
- azimuth_angle(azim_nr, direction='look', normalize=True)[source]¶
Return the azimuthal angle.
- The definition is
0 degrees is along the x-axis of IMAS, the azimuth index 3.5 (looking)
90 degrees is along the y-axis of IMAS, the azimuth index 7.5 (looking)
The definition is different from the IMA bible (
get_azimuth_angle()
).- Parameters
azim_nr – Azimuthal index.
direction – “look” or “velocity”.
normalize – If True, the angle is always in the range of (0, 360). If False, the angles are not necesarrily in this range, but proportional to azim_nr.
- Returns
Angle in degrees.
>>> fov = TableFOV() >>> print(fov.azimuth_angle(3.5)) 0.0 >>> print(fov.azimuth_angle(7.5)) 90.0 >>> print(fov.azimuth_angle(7.5, direction='velocity')) 270.0
- class irfpy.vima.fov.SimpleFOV[source]¶
Bases:
object
This class represents the Simple Field-of-View, i.e., the geometric FoV.
>>> fov = SimpleFOV()
The definition follows the SPICE. Usually, IMA refers to the system “IMAS”.
For example, looking (viewing) vector for azimuthal channel 11.5 and elevation channel 7.5 is along the along -Ximas.
>>> vv = fov.viewvector_imasframe(11.5, 7.5) >>> print('{vv[0]:.2f} {vv[1]:.2f} {vv[2]:.2f}'.format(vv=vv)) -1.00 0.00 0.00
The looking vector for azumuth channle 7.5 and elevation channel 15.5 is X_imas = 0, Y_imas = +sqrt(2) / 2, and Z_imas = +sqrt(2) / 2
>>> vv = fov.viewvector_imasframe(7.5, 15.5) >>> print('{vv[0]:.2f} {vv[1]:.2f} {vv[2]:.2f}'.format(vv=vv)) 0.00 0.71 0.71
Of course the velocity vectors are opposite in sign.
>>> vv = fov.velocityvector_imasframe(11.5, 7.5) >>> print('{vv[0]:.2f} {vv[1]:.2f} {vv[2]:.2f}'.format(vv=vv)) 1.00 -0.00 -0.00
>>> vv = fov.velocityvector_imasframe(7.5, 15.5) >>> print('{vv[0]:.2f} {vv[1]:.2f} {vv[2]:.2f}'.format(vv=vv)) -0.00 -0.71 -0.71
+Yimas ^ +Zima | A# indicate the azimuthal V8 | V7 sector "#" position in V9 ....|.... V6 the sensor assembly. .' A0 | A15 `. V10.' A1 | A14`. V5 V# indicate the "#" sector . A2 | A13. view direction. V11. | . V4 .A3 | A12. +Ximas For example, for . o--------------> +Yima Sector "14" the view .A4 / +Zimas A11. direction is the vector V12. / +Xima . V3 emanating from the .A5 / A10. aperture center through V13 . / A9 . V2 the point designated `. / A7 A8 .' by "V14". V14 ......... ' V1 / V15 V0 V Azimuthal sector "14" view direction
+Yimas +Zima Polar Sector "3" ^ ^ view dir. A# indicate the polar V8 | V7 / sector "#" position in .----|----. V3 the sensor assembly. V15 ,-' P8|P7 `/. V0 .' | P3 `. `.P15 | / P0.' V# indicate the "#" sector `. | / .' view direction. `. | / .' `. | / .' For example, for polar `. |/+Ximas Sector "3" the view <-------------`o'+Yima direction is the vector +Zimas .' `. emanating from the +Xima .' `. aperture center through .' `. the point designated .' `. by "V2". .'P15 P0`. `. .' V15 `-. P8 P7 ,-' V0 `---------' V8 V7
- viewvector_imasframe(azim_nr, elev_nr)[source]¶
Return the viewing vector of the given indexes in the IMAS frame
According to the definition, the x-axis is for the azimuth index 3.5 and elevation index 7.5. The y-axis is for the azimuth index 7.5 and elevation index 7.5. The z-axis is for the elevation index 23.5.
- Parameters
azim_nr – Azimuthal index.
elev_nr – Elevation index.
- Returns
A vector (viewing vector in the IMAS frame).
>>> fov = SimpleFOV() >>> print(fov.viewvector_imasframe(3.5, 7.5)) [1. 0. 0.] >>> print('{f[0]:.1f} {f[1]:.1f} {f[2]:.1f}'.format(f=fov.viewvector_imasframe(7.5, 7.5))) 0.0 1.0 0.0
- velocityvector_imasframe(azim_nr, elev_nr)[source]¶
Return the velocity vectors in the IMAS frame.
- Parameters
azim_nr – Azim index
elev_nr – Elev index
- Returns
Velocity vector, i.e., minus
viewvector_imasframe()
- elevation_angle(elev_nr, direction='look')[source]¶
Return the elevation angle, with respective to x-y plane of IMAS frame.
- Parameters
elev_nr – Elevation index.
direction – “look” for looking direction, “velocity” for the velocity direction.
- Returns
The angle in degrees.
The looking direction of elevation index 0 is -42.1875 degrees.
>>> fov = SimpleFOV() >>> print(fov.elevation_angle(0)) -42.1875
The velocity of particle in the elevation index 0 is 42.1875 degrees.
>>> print(fov.elevation_angle(0, direction='velocity')) 42.1875
The looking direction of elevation index 7.5 is 0 degrees.
>>> print(fov.elevation_angle(7.5)) 0.0
- azimuth_angle(azim_nr, direction='look', normalize=True)[source]¶
Return the azimuthal angle.
- The definition is
0 degrees is along the x-axis of IMAS, the azimuth index 3.5 (looking)
90 degrees is along the y-axis of IMAS, the azimuth index 7.5 (looking)
The definition is different from the IMA bible (
get_azimuth_angle()
).- Parameters
azim_nr – Azimuthal index.
direction – “look” or “velocity”.
normalize – If True, the angle is always in the range of (0, 360). If False, the angles are not necesarrily in this range, but proportional to azim_nr.
- Returns
Angle in degrees.
>>> fov = SimpleFOV() >>> print(fov.azimuth_angle(3.5)) 0.0 >>> print(fov.azimuth_angle(7.5)) 90.0 >>> print(fov.azimuth_angle(7.5, direction='velocity')) 270.0