''' ELS energy module.
ELS energy module used for scientific works.
**Difference with bible**
:mod:`irfpy.vels.bible.energy` also provides energy module for VEX/ELS.
The :mod:`irfpy.vels.bible.energy` module provides usually lower level access,
so it is recommended to use this module for ordinary use.
.. warning::
Energy of ELS data is not simple.
Strictly speaking, it is anode dependent and time dependent.
However, one may want to use energy table as simple as possible,
especially for "loose" analysis or quick look implementation.
The functions including "default" returns such energy table.
Approach is using *calibration* (or reference) values of HV setting
together with median of anode.
If one want to refer to the time-dependent monitor value of HV setting
for energy calculation, you must use
:meth:`irfpy.vels.scidata.ElsCountData.get_energy`.
'''
import numpy as np
from irfpy.vels.bible import energy as bible_energy
[docs]def get_default_table_128(fill_flyback=np.nan):
''' Return a default energy step for E128 mode.
:keyword fill_flyback: Normally highest energy index should not be used because
this is the flyback channel. This keyword can set what value
is filled in the highest energy index.
:returns: Energy table. Index=0 is highest energy.
:rtype: ``np.MaskedArray``
.. note::
If you want the flyback energy, you may use ``fill_flyback=0.8``.
Note that the index order of energy table is opposite from the
implementation of :mod:`irfpy.vels.bible.energy`.
In this method low index is high energy.
>>> etbl = get_default_table_128()
>>> print(etbl.shape)
(128,)
>>> print('%.1f' % etbl[0])
30495.6
>>> print(etbl[127])
nan
'''
# First, get the table from bible. This is 128, 16 array.
# The, take median in anode direction.
etbl = np.median(bible_energy.get_table_128(fill_flyback=fill_flyback), axis=1)
etbl = etbl[::-1] # Reverse.
return etbl
[docs]def get_default_bound_128():
""" Return the energy bounds.
The default 128 step energy bounds are returned. This is easily used for ``pcolormesh`` routines.
:returns: Energy bounds. (129,) array.
>>> ebounds = get_default_bound_128()
>>> print(ebounds.shape)
(129,)
>>> print('{:.2f}'.format(ebounds[0]))
31562.97
"""
etbl = get_default_table_128(fill_flyback=0.8) # This is the central energy
ebound = np.sqrt(etbl[1:] * etbl[:-1]) # The boundary is average in log space
eboundh = [etbl[0] * 1.035, ] # Highest energy. 3.5% is from 7% energy resolution
eboundl = [etbl[-1] / 1.035, ] # Lowest energy. 3.5% is just for convention.
return np.concatenate([eboundh, ebound, eboundl])
[docs]def get_default_range_128():
''' Return the energy range for E128 mode.
The energy range is returned as 2x128 array.
The bounds are defined by the log-average between the neighboring bins.
:returns: Energy range as 2x128 array. [0, :] is for the lower energy
and [1, :] is for the higher energy.
Float values are returned for the last energy steps.
This should be masked by user later.
:rtype: ``ndarray`` with shape of (2, 128)
>>> erange = get_default_range_32_as_128()
>>> print(erange.shape)
(2, 128)
'''
etbl = get_default_table_128(fill_flyback=0.8) # Assuming the last channel's energy
ebound = np.sqrt(etbl[1:] * etbl[:-1]) # Boundaries for 127 channels
eboundh = [etbl[0] * 1.035, ]
eboundl = [etbl[-1] / 1.035, ]
bound_low = np.concatenate([ebound, eboundl])
bound_high = np.concatenate([eboundh, ebound])
bound = np.array([bound_low, bound_high])
return bound
[docs]def get_default_table_32(fill_flyback=np.nan):
''' Return a default energy step for E32 mode.
See also :meth:`get_default_table_128` function.
>>> etbl = get_default_table_32()
>>> print(etbl.shape)
(32,)
>>> print('%.1f' % etbl[0])
239.4
>>> print(etbl[31])
nan
'''
etbl = np.median(bible_energy.get_table_32(fill_flyback=fill_flyback), axis=1)
etbl = etbl[::-1] # Reverse
return etbl
[docs]def get_default_bound_32():
""" Return the energy bounds.
The default 32 step energy bounds are returned. This is easily used for ``pcolormesh`` routines.
:returns: Energy bounds. (33,) array.
>>> ebounds = get_default_bound_32()
>>> print(ebounds.shape)
(33,)
>>> print('{:.2f}'.format(ebounds[0]))
247.78
"""
etbl = get_default_table_32(fill_flyback=0.8) # This is the central energy
ebound = np.sqrt(etbl[1:] * etbl[:-1]) # The boundary is average in log space
eboundh = [etbl[0] * 1.035, ] # Highest energy. 3.5% is from 7% energy resolution
eboundl = [etbl[-1] / 1.035, ] # Lowest energy. 3.5% is just for convention.
return np.concatenate([eboundh, ebound, eboundl])
[docs]def get_default_range_32():
''' Return the energy range for E32 mode.
The energy range is returned as 2x32 array.
The bounds are defined by the log-average between the neighboring bins.
:returns: Energy range as 2x32 array. [0, :] is for the lower energy
and [1, :] is for the higher energy.
Float values are returned for the last energy steps.
This should be masked by user later.
:rtype: ``ndarray`` with shape of (2, 32)
>>> erange = get_default_range_32()
>>> print(erange.shape)
(2, 32)
'''
etbl = get_default_table_32(fill_flyback=8.0) # Assuming the last channel's energy
ebound = np.sqrt(etbl[1:] * etbl[:-1]) # Boundaries for 31 channels
eboundh = [etbl[0] * 1.035, ]
eboundl = [etbl[-1] / 1.035, ]
bound_low = np.concatenate([ebound, eboundl])
bound_high = np.concatenate([eboundh, ebound])
bound = np.array([bound_low, bound_high])
return bound
[docs]def get_default_table_32_as_128(fill_flyback=np.nan):
''' Return a defaut energy step for E32 mode, but in 128 element.
The energy value is for 32 energy mode, but returns (128,) element array.
The save values are repeated 4 times.
See also :meth:`get_default_table_32`.
>>> etbl = get_default_table_32_as_128()
>>> print(etbl.shape)
(128,)
>>> print('%.1f' % etbl[0])
239.4
>>> print(etbl[31])
nan
>>> print('%.1f' % etbl[64])
239.4
>>> print(etbl[127])
nan
'''
etbl = get_default_table_32()
etbl = np.concatenate((etbl, etbl, etbl, etbl))
return etbl
[docs]def get_default_range_32_as_128():
''' Return a default energy range for E32 mode but in 128 element.
See also :meth:`get_default_range_32`.
>>> erange = get_default_range_32_as_128()
>>> print(erange.shape)
(2, 128)
'''
etbl = get_default_range_32()
etbl = np.concatenate((etbl, etbl, etbl, etbl), axis=1)
return etbl
import unittest
import doctest
[docs]def doctests():
return unittest.TestSuite((
doctest.DocTestSuite(),
))
if __name__ == '__main__':
unittest.main(defaultTest='doctests')