''' IMA/ICA mode for MEX, VEX, and Rosetta.
IMA has 40 selectable mode defined at the time of operation.
The mode defines, for a primary purpose, the binning parameter
(i.e., how many bins are used for data retrieval).
The mode 24 (:attr:`M24`) was generally used for MEX, and later half of VEX operation.
The mode 25 (:attr:`M25`) was generally used for the first half of VEX mission.
:attr:`M` provides the list of the mode object.
You may also use the synonim, ``Mnn``.
>>> print(M24)
<IMA:Mode-24 (Exm-0) M32/A16/E96/P16>
>>> print(M[24])
<IMA:Mode-24 (Exm-0) M32/A16/E96/P16>
>>> print(M24 == M[24])
True
You may get the binning parameter using :attr:`m`, :attr:`a`, :attr:`e`, and :attr:`p` as follows:
>>> print(M24.e)
96
>>> print(M24.p, M25.p)
16 8
>>> print(M25.m, M25.a, M25.e, M25.p)
32 16 96 8
The mode is defined in the ``The ICA-IMA TC/TM data formats and related software aspects``
by Hans Borg.
*Useful function*
If you want to prepare a new array that has the same shape of the specific mode, you can use
:func:`get_zeros_array3d` or :func:`get_zeros_array2d` method.
>>> arr25 = M25.get_zeros_array3d()
>>> print(arr25.shape)
(32, 16, 96, 8)
*IRFPY extension*
After a long operation, the IMA operation mode became more and more complex.
There are several update of the onboard software, and in particular for the introduction of
fast scan (24s time resolution), the fast scan cannot repreesnted by the exsiting table.
IRF extends the table, thus, as follows.
::
M40: "IRFPY_fast24s". M32/A16/E32/P6
M41: "IRFPY_fast24s_emul". M32/A16/E64/P16, but [:, :, 32:, 6:] will be masked.
'''
import numpy as _np
__element = ['Name', 'Index', 'Mass', 'Azimuth', 'Energy', 'Polar', 'Maxset']
### Name Idx Mas Az Ene Pol Maxsets
_modelist = [['Idle', 0, -1, -1, -1, -1, -1],
['Void', 1, -1, -1, -1, -1, -1],
['Mspo', 2, 2, 1, 32, 1, 15],
['Void', 3, -1, -1, -1, -1, -1],
['Msis', 4, 6, 1, 96, 1, 5],
['Mexm', 5, 32, 1, 96, 1, 5],
['Void', 6, -1, -1, -1, -1, -1],
['Void', 7, -1, -1, -1, -1, -1],
['Nrm-0', 8, 6, 16, 96, 16, -1],
['Nrm-1', 9, 6, 16, 96, 8, -1],
['Nrm-2', 10, 6, 16, 96, 4, -1],
['Nrm-3', 11, 6, 16, 96, 2, -1],
['Nrm-4', 12, 6, 8, 96, 2, -1],
['Nrm-5', 13, 6, 4, 96, 2, -1],
['Nrm-6', 14, 3, 4, 96, 2, -1],
['Nrm-7', 15, 3, 4, 96, 1, -1],
['Har-0', 16, 16, 16, 96, 16, -1],
['Har-1', 17, 16, 16, 96, 8, -1],
['Har-2', 18, 16, 16, 96, 4, -1],
['Har-3', 19, 8, 16, 96, 4, -1],
['Har-4', 20, 4, 16, 96, 4, -1],
['Har-5', 21, 2, 16, 96, 4, -1],
['Har-6', 22, 2, 8, 96, 4, -1],
['Har-7', 23, 2, 8, 96, 2, -1],
['Exm-0', 24, 32, 16, 96, 16, -1],
['Exm-1', 25, 32, 16, 96, 8, -1],
['Exm-2', 26, 32, 16, 96, 4, -1],
['Exm-3', 27, 32, 16, 96, 2, -1],
['Exm-4', 28, 32, 8, 96, 2, -1],
['Exm-5', 29, 32, 4, 96, 2, -1],
['Exm-6', 30, 32, 2, 96, 2, -1],
['Exm-7', 31, 32, 2, 96, 1, -1],
['Test', 32, -1, -1, -1, -1, -1],
['Cal1', 33, -1, -1, -1, -1, -1],
['Cal2', 34, -1, -1, -1, -1, -1],
['Fake', 35, -1, -1, -1, -1, -1],
['Void', 36, -1, -1, -1, -1, -1],
['Void', 37, -1, -1, -1, -1, -1],
['Void', 38, -1, -1, -1, -1, -1],
['Void', 39, -1, -1, -1, -1, -1],
['IRFPY_fast24', 40, 32, 16, 32, 6, -1],
['IRFPY_fast24_emul', 41, 32, 16, 96, 16, -1],
]
[docs]class Mode:
''' Mode class.
Users are note recommended to instance this class.
Use :attr:`M` [nn] or ``Mnn`` for practical use.
>>> print(M24)
<IMA:Mode-24 (Exm-0) M32/A16/E96/P16>
If entry is not defined, -1 is filled.
'''
def __init__(self, index):
l = _modelist[index]
self.name = l[0]
''' Name of the mode'''
self.i = self.index = l[1]
''' Index number of the mode'''
self.m = self.mass = l[2]
''' Mass number of the mode'''
self.a = self.azim = l[3]
''' Azimuth number of the mode'''
self.e = self.energy = l[4]
''' Energy number of the mode'''
self.p = self.polar = self.elev = l[5]
''' Polar number of the mode'''
self.maxset = l[6]
''' Maxset of the mode'''
[docs] def get_zeros_array2d(self):
""" Return an array fitting to the mode filled by zero.
:returns: An array, with the shape of
(:attr:`m`, :attr:`a`, :attr:`e`),
with values initialized by zero.
>>> arr = M24.get_zeros_array2d()
>>> print(arr.shape) # The array shape is for mode 24
(32, 16, 96)
>>> print((arr == 0).all()) # All elements are zero
True
"""
return _np.zeros([self.m, self.a, self.e])
[docs] def get_zeros_array3d(self):
""" Return an array fitting to the mode filled by zero.
:returns: An array, with the shape of
(:attr:`m`, :attr:`a`, :attr:`e`, :attr:`p`),
with values initialized by zero.
>>> arr = M24.get_zeros_array3d()
>>> print(arr.shape) # The array shape is for mode 24
(32, 16, 96, 16)
>>> print((arr == 0).all()) # All elements are zero
True
"""
return _np.zeros([self.m, self.a, self.e, self.p])
def __repr__(self):
return "<IMA:Mode-%02d (%5s) M%2d/A%2d/E%2d/P%2d>" % (
self.i, self.name, self.m, self.a, self.e, self.p)
def __eq__(self, other):
try:
return (self.name == other.name and self.i == other.i
and self.m == other.m and self.a == other.a and
self.e == other.e and self.p == other.p and self.maxset == other.maxset)
except:
return self == Mode(other) # If the rhs is int.
M = [Mode(i) for i in range(len(_modelist))]
''' List of mode object. Index is the mode number.
'''
M00 = M0 = M[0]
M01 = M1 = M[1]
M02 = M2 = M[2]
M03 = M3 = M[3]
M04 = M4 = M[4]
M05 = M5 = M[5]
M06 = M6 = M[6]
M07 = M7 = M[7]
M08 = M8 = M[8]
M09 = M9 = M[9]
M10 = M[10]
M11 = M[11]
M12 = M[12]
M13 = M[13]
M14 = M[14]
M15 = M[15]
M16 = M[16]
M17 = M[17]
M18 = M[18]
M19 = M[19]
M20 = M[20]
M21 = M[21]
M22 = M[22]
M23 = M[23]
M24 = M[24]
''' Mode 24, which is the full mode, and generally used.
'''
M25 = M[25]
''' Mode 25, with elevation is half (8 polar).
'''
M26 = M[26]
M27 = M[27]
M28 = M[28]
M29 = M[29]
M30 = M[30]
M31 = M[31]
M32 = M[32]
M33 = M[33]
M34 = M[34]
M35 = M[35]
M36 = M[36]
M37 = M[37]
M38 = M[38]
M39 = M[39]
M40 = M[40]
""" Mode 40, extended by IRFPY. Fast 24s mode. EEPROM=13.
"""
M41 = M[41]
""" Mode 41, extended by IRFPY. Fast 24s mode. EEPROM=13. Emulating the full mode.
This is used to express the fast24s mode (EEPROM=13).
The contents should be the same to :attr:`M40`, but the shape of the
matrix and the binning parameters are emulating :attr:`M24` (full mode).
This may be used for data analysis equivalent to the existing code assuming the
matrix size as :attr:`M24`.
"""
[docs]def model(index):
''' Return the list expression of the corresponding mode
'''
return _modelist[index][:]
[docs]def moded(index):
''' Return the dictionary expression of the corresponding mode
'''
lis = _modelist[index]
d = {}
for c, l in zip(__element, lis):
d[c] = l
return d