'''Position attitude ECLAIRs
#TODO: to remove replace by data flow
'''
import logging
import numpy as np
import astropy.time as astrotime
import astropy.table as astt
import astropy.units as u
from ecpi.common.mission.time import convert_mjd_in_svomref_seconds
from ecpi.common.instru.model_effect import ECLAIRsDetectorEffect,\
ECLAIRsDetectorEffectDefault
[docs]class EclairsObservation(object):
"""
Observation of the ECLAIRs instrument
"""
def __init__(self, t_0, t_1, eclairs_attitude, position, velocity,
dpix: ECLAIRsDetectorEffect):
"""**constructor**
:param t_0: time of the beginning of the observation in s from mjdref
:type t_0: float or string(isot)
:param t_1: time of the end of the observation in s from mjdref
:type t_1: float or string(isot)
:param eclairs_attitude: attitude of the ECLAIRs instrument [ra, dec, ori] in degrees
:type eclairs_attitude: [float, float, float]
:param position: [X, Y, Z] in km in J2000
:type position: [float, float, float]
:param velocity: [Vx, Vy, Vz] in km/s
:type velocity: [float, float, float]
:param dpix: detector effects
:type dpix: ECLAIRsDetectorEffect
"""
self.logger = logging.getLogger(__name__)
self.logger.info('creating an instance of EclairsObservation')
self.error_code = "OK"
self.error_message = "I love it when a plan comes together."
self.start_time, self.end_time = self.check_times(t_0, t_1)
self.gti_table = 0
self.obs_time = 0
self.attitude = self.check_eclairs_attitude(eclairs_attitude)
self.position = position
self.velocity = velocity
self.dpix = dpix
def __repr__(self):
return f"""
EclairsObservation object
=========================
Starting time (s): {self.start_time}
Ending time (s): {self.end_time}
Observation time (s): {self.obs_time}
Pointing/Orientation (all in deg): {self.attitude}
Position (km): {self.position}
Velocity (km/s): {self.velocity}
"""
[docs] def check_times(self, start_time, end_time):
"""check input times parameters
check format and that start_time < end_time
:param start_time: starting time of the observation
:type start_time: any (should be float (in s from mjdref) or string (isot))
:param end_time: ending time of the observation
:type end_time: any (should be float (in s from mjdref) or string (isot))
:return: start_time in s from mjdref, end_time in s from mjdref
:rtype: float, float
"""
# try de conversion car les requetes serveurs transforment les float en str
try:
start_time = float(start_time)
end_time = float(end_time)
except:
pass
if isinstance(start_time, (str)):
try:
start_time = convert_mjd_in_svomref_seconds(astrotime.Time(start_time, \
format='isot', \
scale='tt').mjd)
except:
self.error_code = "ConfigError"
msg = "InputParamsError : start_time as a string must be in isot format"
self.error_message = msg
return start_time, end_time
if not (isinstance(start_time, (int, float)) and start_time >= 0):
self.error_code = "ConfigError"
self.error_message = "InputParamsError : start_time as a float must be in s from mjdref"
return start_time, end_time
if isinstance(end_time, (str)):
try:
end_time = convert_mjd_in_svomref_seconds(astrotime.Time(end_time, format='isot', \
scale='tt').mjd)
except:
self.error_code = "ConfigError"
msg = "InputParamsError : end_time as a string must be in isot format"
self.error_message = msg
return start_time, end_time
if not (isinstance(end_time, (int, float)) and end_time > 0):
self.error_code = "ConfigError"
self.error_message = "InputParamsError : end_time as a float must be in s from mjdref"
elif (end_time < start_time):
self.error_code = "ConfigError"
self.error_message = "InputParamsError : end_time must be higher than start_time"
return start_time, end_time
[docs] def check_eclairs_attitude(self, eclairs_attitude):
"""check the ECLAIRs attitude parameter
:param eclairs_attitude: ECLAIRs attitude (RA, DEC, orientation) GCRF
:type eclairs_attitude: any (should be array[float, float, float] in degrees)
"""
if eclairs_attitude is not None:
try:
eclairs_attitude = np.array(eclairs_attitude)
except:
self.error_code = "ConfigError"
self.error_message = \
"InputParamsError : input ECLAIRs attitude must be [RA, DEC, ori]"
if not isinstance(eclairs_attitude, (np.ndarray)):
self.error_code = "ConfigError"
self.error_message = \
"InputParamsError : input ECLAIRs attitude must be [RA, DEC, ori]"
elif eclairs_attitude.shape[0] != 3 and eclairs_attitude.dtype != np.float:
self.error_code = "ConfigError"
self.error_message = \
"InputParamsError : input ECLAIRs attitude must be [RA, DEC, ori] as float"
return eclairs_attitude
[docs] def gti_compute(self):
"""compute the good time interval between start_time and t_end
.. warning:: no computation is implemented now. GTI=[start_time, end_time]
generate a table of GTI (self.gti_table)
"""
self.name_col = ('TSTART', 'TSTOP')
meta_col = {'TSTART' : 'Universal Time in s from mjdref',
'TSTOP' : 'Universal Time in s from mjdref'
}
dtype_col = ('f8', 'f8')
self.gti_table = astt.Table([[self.start_time], [self.end_time]],
names=self.name_col, meta=meta_col, dtype=dtype_col)
self.gti_table['TSTART'].unit = u.s
self.gti_table['TSTOP'].unit = u.s
self._observation_time()
def _observation_time(self):
"""
compute the total observation time from gti table
observation time is in s
"""
self.obs_time = self.gti_table['TSTOP'].sum() - self.gti_table['TSTART'].sum()
[docs]class EclairsObservationImag(EclairsObservation):
"""
Simplified observation of the ECLAIRs instrument (use only for imag)
"""
def __init__(self, t_0, t_1, eclairs_attitude):
"""**constructor**
:param t_0: time of the beginning of the observation in s from mjdref
:type t_0: float or string(isot)
:param t_1: time of the end of the observation in s from mjdref
:type t_1: float or string(isot)
:param eclairs_attitude: attitude of the ECLAIRs instrument [ra, dec, ori] in degrees
:type eclairs_attitude: [float, float, float]
"""
self.error_code = "OK"
self.error_message = "I love it when a plan comes together."
self.start_time, self.end_time = self.check_times(t_0, t_1)
self.gti_table = 0
try:
self.obs_time = t_1 - t_0
except:
self.obs_time = 0
self.attitude = self.check_eclairs_attitude(eclairs_attitude)
self.dpix = ECLAIRsDetectorEffectDefault()