'''SWIM field of view module
'''
import os
import sys
import logging
from irfpy.util.vector3d import Vector3d
from numpy import *
[docs]class SwimFov:
''' SwimFov class is for SWIM field of view class.
This is an abstract class, and therefore, you have to instance as follows.
SwimFov.getInstance(8, 'SWIM') # SWIM with nD=8 with SWIM coordinate system.
SwimFov.getInstance(coords='SC') # SWIM with nD=16(default) with spacecraft coordinate system.
@todo I do not like this implementation. So I want to re-implement.
'''
def __init__(self, *args, **kwds):
'''Constructor with specification of number of deflector.
@param Number of directions
'''
raise NotImplementedError()
[docs] @classmethod
def getInstance(self, nDef=16, coords='SWIM', version=2):
'''Create an instance of derived class.
@param[in] nDef Number of deflection bins.
@param[in] coords Coordinate system. 'SC' or 'SWIM'
@param[in] version FoV table version.
'''
c=coords.lower();
logging.info('# SWIM FoV table version %d is used'%(version))
if c in ('swim'):
logging.debug("SWIM in SWIM instanced.")
if version == 0:
return SwimFovSwimV0(nDef)
elif version == 1:
return SwimFovSwimV1(nDef)
elif version == 2:
return SwimFovSwimV2(nDef)
else:
raise RuntimeError('SwimFov in SWIM coords version %d is not supported.'%version)
elif c in ('sc'):
logging.debug("SWIM in SC instanced.")
if version == 0:
return SwimFovScV0(nDef)
elif version == 1:
return SwimFovScV1(nDef)
elif version == 2:
return SwimFovScV2(nDef)
else:
raise RuntimeError('SwimFov in SC coords version %d is not supported.'%version)
else:
raise RuntimeError('Coordinate system undefined (%s).'%coords)
[docs] def getDirection(self, index):
'''Get a viewing vector of the specified index bin. Vector3d instance.
@param[in] index Index of the bin of which one wants to know the direction.
@retval Vector (irfpy.util.vector3d.Vector3d instance) The viewing vector of the corresponding bin.
'''
raise NotImplementedError()
def _SwimFovTableV0():
''' Angle of the central direction for 16 separated bins. Version 0, which is geometric center.
'''
_angle_list=(arange(16)+0.5)*(180./16)
_angle_list=_angle_list * pi / 180.
return _angle_list
def _SwimFovTableV1():
''' Angle of the central direction for 16 separated bins. Version 1, which is from Martin's cal report.
'''
_angle_list=array([-63,-53,-44,-34,-25,-15,-7,0,8,16,26,35,45,54,66,75], dtype=double) + 90
_angle_list=_angle_list * pi / 180.
return _angle_list
def _SwimFovTableV2():
''' Angle of the central direction for 16 separated bins. Version 1, which is from Martin's cal report.
'''
_angle_list=array([-64,-54,-44,-34,-25,-16,-8,0,8,16,25,34,44,54,64,75], dtype=double) + 90
_angle_list=_angle_list * pi / 180.
return _angle_list
def _Rebin(_angle_list, ndefl):
if ndefl==16:
alist=_angle_list
elif ndefl==8:
alist=[average(_angle_list[2*i:2*(i+1)]) for i in range(8)]
elif ndefl==4:
alist=[average(_angle_list[4*i:4*(i+1)]) for i in range(4)]
elif ndefl==2:
alist=[average(_angle_list[8*i:8*(i+1)]) for i in range(2)]
elif ndefl==1:
alist=[average(_angle_list)]
else:
raise RuntimeError('Number of deflection=%d is not supported.'%nD)
return alist
class _SwimFovSwimFromTable(SwimFov):
def __init__(self, nD):
self.ndefl=nD
def getTable(self):
raise NotImplementedError()
def getDirection(self, index):
if index<0 or index>=self.ndefl:
raise RuntimeError('Specified index=%d is not valid.'%index)
ang=self.getTable()[index];
x=sin(ang)
y=cos(ang)
return Vector3d(x,y,0)
[docs]class SwimFovSwimV0(_SwimFovSwimFromTable):
'''SWIM FoV concrete class in SWIM coordinate system, version 0.
Version 0 table is based on the geometry mapping in the document CHA-SARA-DS-0017-I1R0, but not exactly true...
The SWIM has in fact 16 channels. The FoV plane (=180 deg) was assumed to be separated into the same size, i.e. 11.25 deg.
Each bins are corresponding to each direction.
Therefore, angle is [5.625, 16.875, ..., 174.375].
The SWIM coordinate system is defined as: Xswim=Zsc, Yswim=Xsc, Zswim=Ysc.
The lower index number points toward nadir (+Xsc). This means that the index 0 bin is mostly parallel to +Yswim (=+Xsc),
index 7 and 8 bins are mostly parallel to +Xswim(=+Zsc). +Zswim(=+Ysc) component is always zero.
'''
def __init__(self, nD):
_SwimFovSwimFromTable.__init__(self, nD)
_angle_list=_SwimFovTableV0()
logging.debug('Angle list=%s'%str(_angle_list))
self.alist=_Rebin(_angle_list, nD)
logging.debug('Angle list down-sized=%s'%str(self.alist))
[docs] def getTable(self):
return self.alist
[docs]class SwimFovSwimV1(_SwimFovSwimFromTable):
'''SWIM FoV concrete class in SWIM coordinate system based on the table of version 1.
Version 1 table is based on the calibration by Martin Wieser (SARA_binning_parameters.ods).
Detailed description on the coordinate system is in SwimFovSwimV0.
'''
def __init__(self, nD):
_SwimFovSwimFromTable.__init__(self, nD)
_angle_list=_SwimFovTableV1()
self.alist=_Rebin(_angle_list, nD)
[docs] def getTable(self):
return self.alist
[docs]class SwimFovSwimV2(_SwimFovSwimFromTable):
'''SWIM FoV concrete class in SWIM coordinate system based on the table of version 2.
Version 2 table is based on a draft calibration report issues in June 2009.
Detailed description on the coordinate system is in SwimFovSwimV0.
'''
def __init__(self, nD):
_SwimFovSwimFromTable.__init__(self, nD)
_angle_list=_SwimFovTableV2()
self.alist=_Rebin(_angle_list, nD)
[docs] def getTable(self):
return self.alist
[docs]class SwimFovScV0(SwimFov):
'''SWIM FoV concrete class in Sc coordinate system, version 0.
Version 0 table is based on the geometry mapping in the document CHA-SARA-DS-0017-I1R0, but not exactly true...
@sa SwimFovSwimV0 class.
@todo refactor. Swim coords to Sc coords conversion can be other class?
'''
def __init__(self, nD):
_angle_list=_SwimFovTableV0()
logging.debug('Angle list=%s'%str(_angle_list))
self.ndefl=nD
self.alist=_Rebin(_angle_list, nD)
logging.debug('Angle list down-sized=%s'%str(self.alist))
[docs] def getDirection(self, index):
if index<0 or index>=self.ndefl:
raise RuntimeError('Specified index=%d is not valid.'%index)
ang=self.alist[index]
x=cos(ang)
z=sin(ang)
return Vector3d(x,0,z)
[docs]class SwimFovScV1(SwimFov):
''' Swim FoV implementation in SC coordinate system version 1.
'''
def __init__(self, nD):
_angle_list = _SwimFovTableV1()
self.ndefl=nD
self.alist=_Rebin(_angle_list, nD)
logging.debug('Angle list down sized=%s'%str(self.alist))
[docs] def getDirection(self, index):
if index<0 or index >= self.ndefl:
raise RuntimeError('Specified index=%d is not valid.'%index)
ang=self.alist[index]
x=cos(ang)
z=sin(ang)
return Vector3d(x,0,z)
[docs]class SwimFovScV2(SwimFov):
''' Swim FoV implementation in SC coordinate system version 2.
'''
def __init__(self, nD):
_angle_list = _SwimFovTableV2()
self.ndefl=nD
self.alist=_Rebin(_angle_list, nD)
logging.debug('Angle list down sized=%s'%str(self.alist))
[docs] def getDirection(self, index):
if index<0 or index >= self.ndefl:
raise RuntimeError('Specified index=%d is not valid.'%index)
ang=self.alist[index]
x=cos(ang)
z=sin(ang)
return Vector3d(x,0,z)