''' A module to convert between lse and me frames.
Conversion between LSE frame and ME frame.
For frame conversions, also refer to :ref:`frame_conversion`.
This is based on a pre-calculated conversion file,
specified in ``[cy1orb]`` ``convlse2me`` entry.
Contact Futaana for the datefile.
The simple use is just calling :func:`lse2me` and :func:`me2lse`.
'''
import logging
import urllib.request
import urllib.parse
import urllib.error
import gzip
import numpy
from irfpy.util.irfpyrc import Rc
from irfpy.util.utc import convert
from irfpy.util.julday import Julday, JdSeries
from irfpy.util.vector3d import Vector3d
[docs]class ConversionMatrixInFile:
def __init__(self, rcfile=None):
rc=Rc()
if rcfile is not None:
rc.append(rcfile)
self.convser=None
self.convfile = rc.get('cy1orb', 'convlse2me')
if self.convfile is None:
errmsg = '!!!! In the rc file, [cy1orb]/convlse2me is not found.'
logging.error(errmsg)
raise RuntimeError(errmsg)
logging.debug('File: %s'%self.convfile)
[docs] def loadfile(self):
''' Read a data from file spcified in cy1orb/convlse2me field of irfpyrc.
'''
self.fn,st = urllib.request.urlretrieve(self.convfile)
logging.info('File retr: %s'%self.fn)
logging.debug(st)
f=gzip.GzipFile(self.fn, 'r')
# Actual reading part
self.convser = JdSeries()
for line in f:
if line[0] == '#':
continue
var=[float(i) for i in line.rstrip().split()]
conv = numpy.array([ [var[2], var[3], var[4]], [var[5], var[6], var[7]], [var[8], var[9], var[10]] ])
self.convser.add(Julday( var[0] ), conv)
f.close()
[docs] def getVectorMeNeighbor(self, jd, vecLse):
''' Get a ME frame vector correspoinding to the LSE vector.
The conversion from LSE to ME is done. The time resolution of the conversion matrix is 1 hour,
so, the error of the order of 1 degrees should be admitted. (~ 360 deg / 30 day / 24 hr)
Because the JdSeries.getNeighbor() method is used, the execution time is not quite fast.
'''
t=convert(jd, Julday)
mat = self.convser.getNeighbor(t)
m = mat.getData() # numpy 3x3 array
if isinstance(vecLse, Vector3d):
v = numpy.array([vecLse.x, vecLse.y, vecLse.z])
else:
v = numpy.array(vecLse) # numpy 3 array
return numpy.dot(m.transpose(),v)
[docs] def getMatrixLse2MeNeighbor(self, jd):
''' Get LSE->ME conversion matrix
'''
t = convert(jd, Julday)
mat = self.convser.getNeighbor(t)
m = mat.getData()
return m.T
[docs] def getMatrixMe2LseNeighbor(self, jd):
t = convert(jd, Julday)
mat = self.convser.getNeighbor(t)
m = mat.getData()
return m
[docs] def getVectorLseNeighbor(self, jd, vecMe):
''' Get a LSE frame vector correspoinding to the ME vector.
The conversion from ME to LSE is done. The time resolution of the conversion matrix is 1 hour,
so, the error of the order of 1 degrees should be admitted. (~ 360 deg / 30 day / 24 hr)
Because the JdSeries.getNeighbor() method is used, the execution time is not quite fast.
'''
t=convert(jd, Julday)
mat = self.convser.getNeighbor(t)
m = mat.getData()
if isinstance(vecMe, Vector3d):
v = numpy.array([vecMe.x, vecMe.y, vecMe.z])
else:
v=numpy.array(vecMe)
return numpy.dot(m, v)
__tblser = None
[docs]def lse2me_matrix(jd):
''' Interface to get a matrix of LSE2ME conversion
'''
global __tblser
if __tblser is None:
logging.info('Loading the data of LSE<->ME conversion in module level')
__tblser = ConversionMatrixInFile()
__tblser.loadfile()
return __tblser.getMatrixLse2MeNeighbor(jd)
[docs]def me2lse_matrix(jd):
global __tblser
if __tblser is None:
logging.info('Loading the data of LSE<->ME conversion in module level')
__tblser = ConversionMatrixInFile()
__tblser.loadfile()
return __tblser.getMatrixMe2LseNeighbor(jd)
[docs]def lse2me(jd, vec_lse):
''' Convert LSE to ME for the given time.
:param jd: Time.
:type jd: ``datetime.datetime`` instance is recommended. ``irfpy.util.julday.Julday`` is also supported.
:param vec_me: Vector in LSE frame.
:type vec_me: ``numpy.array`` is recommended, while ``irfpy.util.vector3d.Vector3d`` is supported.
:return: A corresponding vector in ME frame.
:rtype: ``numpy.array``
'''
global __tblser
if __tblser is None:
logging.info('Loading the data of LSE<->ME conversion in module level')
__tblser = ConversionMatrixInFile()
__tblser.loadfile()
return __tblser.getVectorMeNeighbor(jd, vec_lse)
[docs]def me2lse(jd, vec_me):
''' Convert ME to LSE for the given time.
:param jd: Time.
:type jd: ``datetime.datetime`` instance is recommended. ``irfpy.util.julday.Julday`` is also supported.
:param vec_me: Vector in ME frame.
:type vec_me: ``numpy.array`` is recommended, while ``irfpy.util.vector3d.Vector3d`` is supported.
:return: A corresponding vector in LSE frame.
:rtype: ``numpy.array``
'''
global __tblser
if __tblser is None:
logging.info('Loading the data of LSE<->ME conversion in module level')
__tblser = ConversionMatrixInFile()
__tblser.loadfile()
return __tblser.getVectorLseNeighbor(jd, vec_me)