# Licensed under a 3-clause BSD style license - see LICENSE.rst"""Time related utility functions."""importnumpyasnpimportastropy.unitsasufromastropy.timeimportTime,TimeDelta__all__=["absolute_time","time_ref_from_dict","time_ref_to_dict","time_relative_to_ref",]TIME_KEYWORDS=["MJDREFI","MJDREFF","TIMEUNIT","TIMESYS","TIMEREF"]# TODO: implement and document this properly.# see https://github.com/gammapy/gammapy/issues/284TIME_REF_FERMI=Time("2001-01-01T00:00:00")# Default time ref used for GTIsTIME_REF_DEFAULT=Time("2000-01-01T00:00:00",scale="tt")#: Default epoch gammapy uses for FITS files (MJDREF)#: 0 MJD, TTDEFAULT_EPOCH=Time(0,format="mjd",scale="tt")deftime_to_fits(time,epoch=None,unit=u.s):"""Convert time to fits format. Times are stored as duration since an epoch in FITS. Parameters ---------- time : `~astropy.time.Time` time to be converted epoch : `astropy.time.Time` epoch to use for the time. The corresponding keywords must be stored in the same FITS header. If None, `DEFAULT_EPOCH` will be used. unit : `astropy.time.Time` If None, `DEFAULT_EPOCH` will be used. Should be stored as `TIMEUNIT` in the same FITS header. Returns ------- time : astropy.units.Quantity Duration since epoch """ifepochisNone:epoch=DEFAULT_EPOCHreturn(time-epoch).to(unit)deftime_to_fits_header(time,epoch=None,unit=u.s):"""Convert time to fits header format. Times are stored as duration since an epoch in FITS. Parameters ---------- time : `~astropy.time.Time` time to be converted epoch : `astropy.time.Time` epoch to use for the time. The corresponding keywords must be stored in the same FITS header. If None, `DEFAULT_EPOCH` will be used. unit : `astropy.time.Time` If None, `DEFAULT_EPOCH` will be used. Should be stored as `TIMEUNIT` in the same FITS header. Returns ------- header_entry : tuple(float, string) a float / comment tuple with the time and unit """ifepochisNone:epoch=DEFAULT_EPOCHtime=time_to_fits(time,epoch)returntime.to_value(unit),unit.to_string("fits")
[docs]deftime_ref_from_dict(meta,format="mjd",scale="tt"):"""Calculate the time reference from metadata. Parameters ---------- meta : dict FITS time standard header info format: str Format of the `~astropy.time.Time` information scale: str Scale of the `~astropy.time.Time` information Returns ------- time : `~astropy.time.Time` Time object with ``format='MJD'`` """# Note: the float call here is to make sure we use 64-bitmjd=float(meta["MJDREFI"])+float(meta["MJDREFF"])scale=meta.get("TIMESYS",scale).lower()returnTime(mjd,format=format,scale=scale)
[docs]deftime_ref_to_dict(time=None,scale="tt"):"""Convert the epoch to the relevant FITS header keywords Parameters ---------- time : `~astropy.time.Time` The reference epoch for storing time in FITS. scale: str Scale of the `~astropy.time.Time` information Returns ------- meta : dict FITS time standard header info """iftimeisNone:time=DEFAULT_EPOCHmjd=Time(time,scale=scale).mjdi=np.floor(mjd).astype(np.int64)f=mjd-ireturndict(MJDREFI=i,MJDREFF=f,TIMESYS=scale)
[docs]deftime_relative_to_ref(time,meta):"""Convert a time using an existing reference. The time reference is built as MJDREFI + MJDREFF in units of MJD. The time will be converted to seconds after the reference. Parameters ---------- time : `~astropy.time.Time` time to be converted meta : dict dictionary with the keywords ``MJDREFI`` and ``MJDREFF`` Returns ------- time_delta : `~astropy.time.TimeDelta` time in seconds after the reference """time_ref=time_ref_from_dict(meta)returnTimeDelta(time-time_ref,format="sec")
[docs]defabsolute_time(time_delta,meta):"""Convert a MET into human readable date and time. Parameters ---------- time_delta : `~astropy.time.TimeDelta` time in seconds after the MET reference meta : dict dictionary with the keywords ``MJDREFI`` and ``MJDREFF`` Returns ------- time : `~astropy.time.Time` absolute time with ``format='ISOT'`` and ``scale='UTC'`` """time=time_ref_from_dict(meta)+time_deltareturnTime(time.utc.isot)
defextract_time_info(row):"""Extract the timing metadata from an event file header Parameters ---------- row : dict dictionary with all the metadata of an event file Returns ------- time_row : dict dictionary with only the time metadata """time_row={}fornameinTIME_KEYWORDS:time_row[name]=row[name]returntime_rowdefunique_time_info(rows):"""Check if the time information are identical between all metadata dictionaries Parameters ---------- rows : list list of dictionaries with a list of time metadata from different observations Returns ------- status : bool True if the time metadata are identical between observations """iflen(rows)<=1:returnTruefirst_obs=rows[0]forrowinrows[1:]:fornameinTIME_KEYWORDS:iffirst_obs[name]!=row[name]orrow[name]isNone:returnFalsereturnTrue