Source code for ecpi.common.mission.observation

'''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()