88
99import numpy as np
1010from astropy .io import fits
11+ import astropy .units as u
1112from astropy .table import Table
1213from astropy .logger import AstropyUserWarning
1314import matplotlib .pyplot as plt
@@ -741,6 +742,7 @@ def __init__(
741742 gtistring = None ,
742743 additional_columns = None ,
743744 data_kind = "events" ,
745+ ** kwargs ,
744746 ):
745747 self .fname = fname
746748 self ._data = fits .open (self .fname )
@@ -757,6 +759,8 @@ def __init__(
757759 f"{ data_kind } is an unknown data kind."
758760 )
759761 self .data_kind = data_kind
762+ self .high_precision = kwargs .pop ("high_precision" , None )
763+
760764 if additional_columns is None and self .detector_key != "NONE" :
761765 additional_columns = [self .detector_key ]
762766 elif self .detector_key != "NONE" :
@@ -765,8 +769,12 @@ def __init__(
765769
766770 if self .energy_column == "EBOUNDS" :
767771 self .edata_hdu = self ._data ["EBOUNDS" ]
772+ self .emin = kwargs .pop ("emin" , None )
773+ self .emax = kwargs .pop ("emax" , None )
768774 self .gti_file = gti_file
769775 self ._read_gtis (self .gti_file )
776+ if kwargs != {}:
777+ warnings .warn (f"Unrecognized keywords: { list (kwargs .keys ())} " )
770778
771779 @property
772780 def time (self ):
@@ -843,12 +851,6 @@ def _transform_slice_into_events(self, data):
843851 if self ._mission_specific_processing is not None :
844852 data = self ._mission_specific_processing (data , header = self .header , hduname = self .hduname )
845853
846- # Set the times
847- setattr (
848- new_ts ,
849- self .main_array_attr ,
850- data [self .time_column ][:] + self .timezero ,
851- )
852854 # Get conversion function PI->Energy
853855 try :
854856 pi_energy_func = get_rough_conversion_function (
@@ -865,15 +867,32 @@ def _transform_slice_into_events(self, data):
865867 ehigher = self .edata_hdu .data ["E_MAX" ]
866868 emid = elower + (ehigher - elower ) / 2.0
867869
868- energy = np .array ([emid [c ] for c in channels ])
870+ self .emin = np .min (elower ) if self .emin is None else self .emin
871+ self .emax = np .max (ehigher ) if self .emax is None else self .emax
869872
873+ energy = np .array ([emid [c ] for c in channels ])
870874 if (
871875 hasattr (self .edata_hdu .columns ["E_MIN" ], "unit" )
872876 and (unit := self .edata_hdu .columns ["E_MIN" ].unit ) is not None
873877 ):
874878 conversion = (1 * u .Unit (unit )).to (u .keV ).value
875- new_ts .energy = energy * conversion
876- new_ts .pi = channels
879+
880+ if isinstance (self .emin , u .Quantity ):
881+ self .emin = self .emin .to (u .keV ).value
882+ if isinstance (self .emax , u .Quantity ):
883+ self .emax = self .emax .to (u .keV ).value
884+
885+ if self .emin > self .emax :
886+ self .emin , self .emax = self .emax , self .emin
887+
888+ mask = (energy > self .emin ) & (energy < self .emax )
889+ energy = energy [mask ]
890+ channels = channels [mask ]
891+
892+ time_dtype = np .float128 if self .high_precision is True else np .float64
893+
894+ new_ts .energy = np .asanyarray (energy * conversion , dtype = np .float64 )
895+ new_ts .pi = np .asanyarray (channels , dtype = time_dtype )
877896 else :
878897 if self .energy_column in data .dtype .names :
879898 conversion = 1
@@ -888,6 +907,16 @@ def _transform_slice_into_events(self, data):
888907 if pi_energy_func is not None :
889908 new_ts .energy = pi_energy_func (new_ts .pi )
890909
910+ if "mask" not in locals ():
911+ mask = np .ones (data [self .time_column ].shape , dtype = bool )
912+
913+ # Set the times
914+ setattr (
915+ new_ts ,
916+ self .main_array_attr ,
917+ data [self .time_column ][mask ] + self .timezero ,
918+ )
919+
891920 det_numbers = None
892921 if self .detector_key is not None and self .detector_key in data .dtype .names :
893922 new_ts .detector_id = data [self .detector_key ]
0 commit comments