Source code for irfpy.swim.SwimEnergy

''' Implementation of Swim energy table class.

All the Swim energy class should be a derived class of EnergyTable class.
Normally one can get the table by table() method refering to the version number.
Current version of the energy table is 2, which is from a draft of SWIM calibartion report issued in June 2009.
Version 1 of energy table is also available, which is from a calibration data on January 2009.

USAGE:
>>> from irfpy.swim.SwimEnergy import EnergyTable
>>> etbl=EnergyTable.table(version=2)
>>> print(etbl.getTable()[0])
109.0
'''

import sys
import os
import logging
from numpy import *

[docs]def eV2kms(eV, m_per_q=1): '''Convert electron volts to velocity. Input eV should be scalar or ndarray. @param eV Energy of particle in electron volt. @param m_per_q Mass per charge in the unit of AMU and elementary charge. ''' q=1.60217646e-19 m=1.67262158e-27 return sqrt(2*q/m/m_per_q)*sqrt(eV) *1e-3 ## in km/s
[docs]def eV2Joule(eV): ''' Convert electron volts to Joule ''' q=1.60217646e-19 return eV*q
[docs]class EnergyTable: '''Abstract class of energy table of SWIM. ''' def __init__(self): raise NotImplementedError
[docs] def getTable(self, *arg, **kwds): ''' Obtain the energy table in eV. For SWIM, 16 energy steps are obtained. 16-element ndarray is returned. ''' raise NotImplementedError
[docs] def getBounds(self, *arg, **kwds): ''' Obtain the bounds of energies between steps are returned. Since SWIM has 16 energy steps, 17-element ndarray is returned. ''' raise NotImplementedrror
[docs] def getRange(self, *arg, **kwds): ''' Obtain 2x16 ndarray, which shows upper and lower boundary of 16 energy steps. ret[0][:] is the lower bound and ret[1][:] is the upper bound. ''' raise NotImplementedError
[docs] def getFwhmRange(self, *arg, **kwds): ''' Obtain 2x16 ndarray, which shows upper and lower boundary of 16 energy steps considering FWHM. Similar to getRange(), but this method is intened to return the actual energy step considering FWHM which is ideally determined by calibration. ''' raise NotImplementedError
[docs] @classmethod def table(self, version=2): ''' Used to obtain a instance of EnergyTable. ''' if version == 1: return EnergyTableV1() elif version == 2: return EnergyTableV2() else: print("Not supported version of new Table %s"%(str(version)), file=sys.stderr)
class _EnergyTableFromLookup(EnergyTable): '''Implementation of energy table of SWIM. This table is based on CHA-SARA-DS-0003-I1R6.xls ''' def __init__(self): pass def getTable(self, *arg, **kwds): """ Get a energy table in eV/q. The returned value is 16 energy steps. """ raise NotImplementedError('This must be implemented in concrete classes.') def getBounds(self, *arg, **kwds): """ Get a boundary of each energy steps in eV/q. The returned array is 17 energy steps. """ lgen=log(self.getTable()) bnd=zeros(17) # 0-th data is... bnd[0] = lgen[0]-(lgen[1]-lgen[0])/2 # 1-15 data for i in range(1,16): bnd[i] = lgen[i-1]+(lgen[i]-lgen[i-1])/2 # 16 data bnd[16] = lgen[14]+(lgen[15]-lgen[14])/2*3 return exp(bnd) def getRange(self, *arg, **kwds): """ Get a 2x16 array to get an ideal energy range. """ bnd = self.getBounds() rng = zeros((2,16)) for i in range(16): rng[0][i] = bnd[i] rng[1][i] = bnd[i+1] return rng def getFwhmRange(self, *arg, **kwds): """ Get a 2x16 array to get an energy range of FWHM for 16 channels. For this version, FWHM is computed independent of energy steps. Here, FWHM=7% is used for calculation as default, but one can specify the constant by fwhm keyword. Keywords: fwhm=<val> Specify the full width half maximum compared with the central energy. Default is 0.07. """ if 'fwhm' in kwds: fwhm=double(kwds['fwhm']) else: fwhm=0.07 logging.info("FWHM is %f"%fwhm) p = fwhm # FWHM x0 = (sqrt(p*p+4)-p)/2. x1 = x0+p rng = zeros((2,16)) e0 = self.getTable() for i in range(16): rng[0][i] = e0[i]*x0 rng[1][i] = e0[i]*x1 return rng
[docs]class EnergyTableV1(_EnergyTableFromLookup): ''' Implementation of version 1 of the SWIM energy table Version 1 is based on a XLS file obtained in the commissioning phase. ''' def __init__(self): pass
[docs] def getTable(self, *arg, **kwds): """ Get a energy table in eV/q. The returned value is 16 energy steps. """ return array([106,132,165,206,258,322,403,503,629,786,983,1229,1536,1920,2400,3000], double)
[docs]class EnergyTableV2(_EnergyTableFromLookup): ''' Implementation of version 2 of the SWIM energy table Version 2 is based on a draft calibration report issued in June 2009. ''' def __init__(self): pass
[docs] def getTable(self, *arg, **kwds): """ Get a energy table in eV/q. The returned value is 16 energy steps. """ return array([109,136,169,210,262,327,408,509,636,794,992,1240,1549,1935,2418,3022], double)