irfpy.mima.fov
¶
FOV module for IMA
SimpleFOV
provides the simplest fov geometry, namely
the equally separted solid angle. This is independent of
the energy. So that in the low energy part it does not
provide good vector.
IMA Frame
There is always a confusion. In SPICE, there are two (not identical)
frames: MEX_ASPERA_IMA
and MEX_ASPERA_IMAS
.
In this module, MEX_ASPERA_IMAS
to be the IMA frame,
since most of the internal document looks to follow the definition of IMAS.
Anyway both are rigidly fixed, but the axis is different (also focul point).
From the MEX_V11.TF, the following is the definition.
-Z s/c side view ("main engine" side):
--------------------------------------
+Xsc
-Y Solar Array ^ +Y Solar Array
._________________ .______|______. .________________.
| \ | | | / |
| \ | | | / |
| | | |+Zsc | | |
| +Zimas |+Yimas x------->o| |
| +Xima |+Zima +Ysc . |
| <----o +Zimau | \ |
._________________/ <----o__________. \_________________.
+Ximau | |' `.
V /|________\
+Ximas V HGA
+Yima +Yimau
+Zsc is into the page
+Zima, +Zimau, and +Yimas
are out of the page
-Z s/c side view ("main engine" side) -- zoom in:
-------------------------------------------------
-- ^ +Xsc
| \ |
| \__ |
| \_________ |
| \ |
| \ x------->
IMA |._____________. \ +Zsc +Ysc
Aperture || o o | \
.___________________. | \____
+Zimas | | +Yimas | | \
+Xima | | +Zima | | \
<-------o | | | \
| | | | | | IMA |
| | | | | | Mounting \
.___|_______________. | plate |
| || o <-------o | |
+Ximas V |. +Ximau ___|_. /
+Yima | | | "Main Engine"
.____________|_______________/ Deck
|
+Yimau V
In addition, the instrument numbering is as follows:
This diagram illustrates in-plane (azimuthal) IMA sector layout:
+Yimas
^ +Zima
| A# indicate the azimuthal
V5 | V4 sector "#" position in
V6 ....|.... V3 the sensor assembly.
.' A13 | A12 `.
V7 .' A14 | A11`. V2 V# indicate the "#" sector
. A15 | A10. view direction.
V8 . | . V1
.A0 | A9. +Ximas For example, for
. o--------------> +Yima Sector "11" the view
.A1 / +Zimas A8. direction is the vector
V9 . / +Xima . V0 emanating from the
.A2 / A7. aperture center through
V10 . / A6 . V15 the point designated
`. / A4 A5 .' by "V11".
V11 ......... ' V14
/ V12 V13
V
Azimuthal sector "11"
view direction
This diagram illustrates cross-plane (polar) IMA sector layout:
+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
See also http://aspera-3.irf.se/Members/futaana/illustration/FovAspera3.png
- irfpy.mima.fov.get_azimuth_angle(azim_nr, direction='look')[source]¶
Return the azimuthal angle.
The origin is -x direction of s/c frame. Increase toward -z s/c. Note that the definition is 180-degrees opposite from the definition of IMA Bible.
- Parameters
azim_nr – Azimuthal number, extended to floating point without bounds.
direction – The direction of azimuth angle.
- Returns
Angle.
- class irfpy.mima.fov.SimpleFOV[source]¶
Bases:
object
Field of view for equally spaced solid angle.
The FOV class reporesents the simplest geometric FOV for MEX/IMA. The IMAS frame, according to SPICE, is used. The benefit of using geometric FOV is the simplest handling, intuitive understanding, no dependence on energy or mode, allowance of floating-point elevation steps, quick implementation and easily vectorized. In addition, inverse solution (from vector knowing sensor ID) can be uniquely determined. The drawback is that the FOV does not (necessarily) represent the actual IMA FOV. Particularly for low energy steps, the elevation scan did not apply, so that the diverge is not accepatble for serious science. In this case, one have to use
TableFOV
.- viewvector_imasframe(azim_nr, elev_nr)[source]¶
Return the viewing vector for IMAS frame
For azimuth, viewing channel 0 is -11.25 deg from +Ximas toward +Yimas (so that -Y direction in principle). Direction 1 is +11.25 deg. Thus azimuth angle is \(-11.25 + 22.5 \times az\)
For elevation, the viewing angle for 0 is -42.1875 deg from X,Yimas plane toward +Zimas Increasing number will increase by 5.625 deg. Thus, elevation angle is \(-42.1875 + 5.625 \times el\).
>>> fov = SimpleFOV()
The azimuth 0.5 and elevation 7.5 specifies the x direction looking.
>>> print(fov.viewvector_imasframe(0.5, 7.5)) [1. 0. 0.]
If you change the azimuth to 4.5, this is y axis.
>>> viewdir = fov.viewvector_imasframe(4.5, 7.5) >>> print('{0[0]:.2f} {0[1]:.2f} {0[2]:.2f}'.format(viewdir)) 0.00 1.00 0.00
The view vector for the elevation -0.5 is the loweredge, namely, -45 degrees in azimuth.
>>> viewdir = fov.viewvector_imasframe(0.5, -0.5) >>> print('{0[0]:.2f} {0[1]:.2f} {0[2]:.2f}'.format(viewdir)) 0.71 0.00 -0.71
If the elevation step -10 is given, this is out of the elevation range. Masked array is returned.
>>> viewdir = fov.viewvector_imasframe(0.5, -10) >>> print(viewdir) [-- -- --]
The last sample shows the masked array, when the elevtion number is out of range. The azimuthal number is periodic.
>>> viewdir = fov.viewvector_imasframe(16.5, 7.5) # Should be the same as (0.5, 7.5), ie, x axis >>> print('{0[0]:.2f} {0[1]:.2f} {0[2]:.2f}'.format(viewdir)) 1.00 -0.00 0.00
One can get the velocity vector from
velocityvector_imasframe()
, which is just a negated array ofviewvector_imasframe()
.>>> viewdir = fov.viewvector_imasframe(1, -0.5) >>> print('{0[0]:.2f} {0[1]:.2f} {0[2]:.2f}'.format(viewdir)) 0.69 0.14 -0.71
>>> veldir = fov.velocityvector_imasframe(1, -0.5) >>> print('{0[0]:.2f} {0[1]:.2f} {0[2]:.2f}'.format(veldir)) -0.69 -0.14 0.71
If the shapes for the arguments are the same, you can use arrays as input.
- velocityvector_imasframe(azim_nr, elev_nr)[source]¶
Return the velocity vector for IMAS frame
Mathematically identical to minus of
viewvector_imasframe()
.
- numbering_imasframe(viewvector)[source]¶
Return the (az, el) tuple corresponding view vector.
The viewvecotr in IMAS frame is converted to the numbering of az and el. Here,
az
should range from -0.5 to 15.5.el
should range from -8.5 to 23.5, while -0.5 to 15.5 is only detectable.>>> fov = SimpleFOV()
>>> viewvec = [1, 0, 0] >>> print(fov.numbering_imasframe(viewvec)) [0.5 7.5]
>>> viewvec = [np.sqrt(0.5), 0, -np.sqrt(0.5)] >>> print(fov.numbering_imasframe(viewvec)) [ 0.5 -0.5]
>>> viewvec = [0, 1, 0] >>> print(fov.numbering_imasframe(viewvec)) [4.5 7.5]
>>> viewvec = [0, 0, 1] >>> print(fov.numbering_imasframe(viewvec)[1]) 23.5
You may give (3, N) shaped array. Then, you may get (2, N) shaped array, with (az, el) for axis 0.
>>> viewvec = [[1, 0, 1, 0], [0, 1, 0, -1], [-1, -1, 1, 1]] >>> print(fov.numbering_imasframe(viewvec)) [[ 0.5 4.5 0.5 12.5] [-0.5 -0.5 15.5 15.5]]
- shadow_mask()[source]¶
Return the pre-defined angular mask.
- Returns
(A16, P16) shaped boolean array. True for channel with mask, False for free mask.
Discussion in Futaana et al., 2010. Phobos paper.
>>> mask_table = SimpleFOV().shadow_mask() >>> mask_table.shape (16, 16) >>> mask_table[0, 0] # Azimuth=0, elevation=0 is shadowed by SC True >>> mask_table[2, 10] # Azimuth=2, elevation=10 is free False >>> mask_table[12, :].all() # For azimuth=12, all elevation is blocked. True
- shadow_mask_corners(phase=0)[source]¶
Return corner index as a (N, 2)-shaped array.
The corner index, in the (N, 2)-shaped array. By connecting the element of array, you may get the envelope of the shadow mask.
- Parameters
phase – The phase of the index. If the phase is 0 (default), the azimuthal index varies from (-8.5 to 1.5). If the phase 1 1, the azimuthal index varies from (7.5 to 17.5). This is prepared since the envelope crosses the boundary between the channels of 15 and 0.
>>> fov = SimpleFOV() >>> corners = fov.shadow_mask_corners() >>> print(corners.shape) (21, 2) >>> print(corners[0]) # The start point of the envelope, which is azimuth -8.5 and elevation -0.5. [-8.5 -0.5]
- class irfpy.mima.fov.TableFOV[source]¶
Bases:
object
FOV information from the table provided from Andrei
The information is from ima_info.nc file provided from Andrei in Nov 2014. The FOV information is in ImaElev variable, with the size of (ImaNTables=4, ImaEnerDim=96, ImaElevDim=16).
Therefore, the
viewvector_imasframe()
or other method should take table_id argument.table_id=0, Default table in PROM
table_id=1, updated in 2006. in EEPROM=0
table id=2, updated in 2009. in EEPROM=15
table id=3, for fast scan. EEPROM=13
In addition, energy and elevation steps should be given by the integer with the range 0–95 and 0–15 respectively. It is allowed to have float values for azimuthal directions.
>>> fov = TableFOV() # Create table based FOV. >>> simplefov = SimpleFOV() # Create geometric based FOV for comparison.
For table=0, azimuth=0.5, elevation=10, and energy step = 15, the looking direction in IMA frame is obtained by as follows.
>>> print(fov.viewvector_imasframe(0, 0.5, 10, 15)) [0.977415... 0. 0.21132... ]
You can compare with the results from the simple FOV.
>>> print(simplefov.viewvector_imasframe(0.5, 10)) [0.97003... 0. 0.24298...]
If the view angle does not make sense, [nan, nan, nan] array will be returend.
>>> print(fov.viewvector_imasframe(0, 0.5, 3, 80)) [nan nan nan]
>>> viewdir = fov.viewvector_imasframe(1, 4.5, 0, 21) # This is the lower edge of el=0, ie, around -45 deg. >>> print('{0[0]:.2f} {0[1]:.2f} {0[2]:.2f}'.format(viewdir)) 0.00 0.74 -0.67
One can get the velocity vector from
velocityvector_imasframe()
, which is just a negated array ofviewvector_imasframe()
.>>> veldir = fov.velocityvector_imasframe(1, 4.5, 0, 21) >>> print('{0[0]:.2f} {0[1]:.2f} {0[2]:.2f}'.format(veldir)) -0.00 -0.74 0.67
- promsection_to_tableid = {0: 0, 'PROM': 0, 1: 1, 'EEPROM_00': 1, 16: 2, 'EEPROM_15': 2, 15: 2, 'EEPROM_14': 2, 14: 3, 'EEPROM_13': 3}¶
Dictionary showing the PROM section index to the table ID.
PROM-section is the booting software section. It defines the energy / direction table. MEX/IMA has 1 PROM and 16 EEPROM (0 to 15). PROM is representedted by 0, while EEPROM is represented with increment by 1 (PROM is 0, EEPROM_00 is 1, EEPROM_01 is 2, and so on).
On the other hand, some ground software uses “table_id”, where
irfpy
follows this custom.Todo
A new implementation directly handle the table according to the data (ImaPacket) is needed. Similar implementation in
irfpy.mima.energy
- viewvector_imasframe(table_id, azim_nr, elev_nr, ene_nr)[source]¶
View vector in IMAS frame is returned.
- Parameters
table_id – Table number. So far 0 to 3 is supported.
azim_nr – Azimuthal step
elev_nr – Elevation step
ene_nr – Energy step
- Returns
View vector in IMAS frame. If no viewing direction is defined, [nan, nan, nan] is returned.
Vectorization is not supported.
- shadow_mask()[source]¶
This method is not implemented. Use
shadow_mask3d()
.
- shadow_mask3d(table_id)[source]¶
Return a table, with a shape of (A16, E96, P16), where the shadow_mask is embedded.
- Parameters
table_id – The table ID
- Returns
(A16, E96, P16) boolean array showing the shadow mask. True is masked.
>>> tableFov = TableFOV() >>> mask0 = tableFov.shadow_mask3d(0) >>> print(mask0.shape) (16, 96, 16) >>> print(mask0[10, 32, 5]) # Azimuth=10, energy=32, elevation=5 True >>> print(mask0[7, 32, 5]) # Azimuth=7, energy=32, elevation=5 False
- elev_table¶
Elevation table in np.array format.
The elevation table read from the ima_info.nc. The shape is (ntalbe=4, enestep=96, elevstep=16)