;+ ; ; NAME: ; spex_any_specfile__define ; ; PURPOSE: ; Provides read_data method for data from any instrument. You must set the ospex control parameter spex_file_reader to the base name ; of the routines to call to read the spectrum and srm files ('_data' and '_drm' will be appended to the base name). ; ; Method: ; When the input file is set via the spex_specfile parameter, spex_data::set tries to determine the type of data in the file, and sets ; the data strategy to that data type (e.g. if the header 'INSTR' keyword is RHESSI, and there's an extension named 'RATE', then the ; strategy is set to 'SPEX_HESSI_SPECFILE', and the spex_hessi_specfile::read_data is called to read the rhessi spectrum file using the routine ; read_hessi_4_ospex). If the type of file can not be determined, the data strategy is set to SPEX_ANY_SPECFILE. Spex_any_specfile::read_data ; will call a routine specified by the control parameter spex_file_reader. The user must set that parameter explicitly to a string that is the ; base name of the routines to read the spectrum and, if needed, the SRM file. E.G. ; o->set,spex_file_reader='stx_read' ; means the user has provided a routine called stx_read_data and, if needed, stx_read_drm. ; ; The xxx_data routine must have the following keyword arguments ; FILES - (INPUT) Scalar or vector string of file names to read ; DATA_STR - (OUTPUT) Structure containing info read from file (described below) ; ERR_CODE - (OUTPUT) 0 means success reading file(s). 1 means failure ; ERR_MSG - (OUTPUT) string containing error message if any. '' means no error. ; ; The DATA_STR structure returned by the xxx_data routine must contain these fields: ; data_str = { $ ; START_TIME: start_time, $ start time of file in anytim format ; END_TIME: end_time, $ end time of file in anytim format ; RCOUNTS: rcounts, $ [nenergy,ntime] count data ; ERCOUNTS: ercounts, $ [nenergy,ntime] error in count data ; UT_EDGES: ut_edges, $ [2,ntime] edges of time bins in anytim format ; UNITS: units, $ units of rcounts, usually 'counts' ; AREA: area, $ effective detector area in cm^2 ; LTIME: ltime, $ [nenergy,ntime] livetimes ; CT_EDGES: ct_edges, $ [2,nenergy] edges of energy bins in keV ; data_name: data_name, $ string name of data, e.g. 'RHESSI' ; TITLE: title, $ string title of data, e.g. 'RHESSI SPECTRUM' ; RESPFILE: respfile, $ string name of corresponding SRM file, or blank string ; OR [nedges_out, nedges_in] numeric array of DRM values ; OR structure containing fields drm ([nedges_out, nedges_in]), edges_in, and edges_out ; detused: detused, $ string of detector names ; atten_states: atten_states, $ [ntime] array of filter states, or scalar -1 if doesn't apply ; deconvolved: deconvolved, $ If 1, original data is already photons ; pseudo_livetime: pseudo_livetime, $ if 1, livetime isn't a real livetime ; xyoffset: xyoffset } [2] x,y location of source on Sun ; ; ; The xxx_drm routine is needed only if the RESPFILE value returned by the xxx_data routine did not contain the DRM values (i.e. ; RESPFILE was not numeric or a structure). In that case, RESPFILE was either the name of the DRM file or a blank string. IF a blank ; string, then the user must explicitly set the DRM FILE name via the spex_drmfile parameter. ; The xxx_drm routine must have the following keyword arguments ; FILE - (INPUT) string of file name to read ; ERR_CODE - (OUTPUT) 0 means success reading file(s). 1 means failure ; ERR_MSG - (OUTPUT) string containing error message if any. '' means no error. ; and the following positional argument ; DRM_STR - (OUTPUT) Structure containing info read from DRM file (described below) ; ; The DRM_STR structure returned by the xxx_drm routine must contain these fields: ; drm_str = { $ ; EDGES_OUT: edges_out, $ [2,nedges_out] count energy edges in keV ; PH_EDGES: ph_edges, $ [2,nedges_in] photon energy edges in keV ; AREA: area, $ detector area in cm^2 ; DRM: drm, $ [nedges_out,nedges_in,nfilter] DRM matrix for each filter state ; SEPDETS: sepdets, $ 1 if separate detectors ; data_name: data_name, $ string name of data, e.g. 'RHESSI' ; filter: atten_state, $ [nfilter] value of filter states ; detused: detused } string of detectors used, e.g. '1F 3F 4F 5F 6F 8F 9F' ; ; CATEGORY: ; SPECTRAL FITTING, SPEX ; ; CALLING SEQUENCE: ; ; CALLS: ; ; INPUTS: ; ; OUTPUTS: ; ; INPUT KEYWORDS: ; ; OUTPUT KEYWORDS: ; ; PROCEDURE: ; ; Written 09-Oct-2014, Kim Tolbert ; ; Modification History: ; 24-Nov-2014, Kim. Get name of read procedure from spex_file_reader control parameter, and then use call_procedure ; ;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------ pro spex_any_specfile::read_data, file_index=file_index, $ spectrum, errors, livetime, $ spex_respinfo, spex_file_time, spex_ut_edges, spex_ct_edges, $ spex_area, spex_title, spex_detectors, $ spex_interval_filter, spex_units, spex_data_name, $ spex_deconvolved, spex_pseudo_livetime, spex_data_pos, $ err_code=err_code, _extra=_extra reader = self -> get(/spex_file_reader) + '_data' which, reader, out=out if out eq '' then begin message, /cont, 'Input file was not recognized and no routine to read files has been provided. ' message, /cont, ' (looking for ' + reader + ')' message, /cont, ' You must set spex_file_reader parameter to base name of routine to read data and drm files.' err_code = 1 return endif file = self -> get( /spex_specfile ) checkvar, file_index, 0 file = file[file_index] err_msg = '' message, /cont, 'Using routine ' + reader + ' to read data.' call_procedure, reader, $ FILES = file, $ _EXTRA = _ref_extra, $ data_str = ds, $ ERR_CODE = err_code, $ ERR_MSG = err_msg if err_msg[0] ne '' then begin ;if not spex_get_nointeractive() then xmessage,err_msg else print,err_msg message, err_msg, /cont if err_code then return endif spectrum = ds.rcounts errors = ds.ercounts livetime = ds.ltime spex_file_time = utime([ds.start_time, ds.end_time]) spex_ut_edges = ds.ut_edges spex_respinfo = ds.respfile spex_ct_edges = ds.ct_edges spex_area = ds.area[0] spex_title = ds.title spex_detectors = ds.detused spex_units = ds.units spex_interval_filter = ds.atten_states spex_data_name = ds.data_name spex_deconvolved = ds.deconvolved spex_pseudo_livetime = ds.pseudo_livetime spex_data_pos = ds.xyoffset end ;------------------------------------------------------------------------------ pro spex_any_specfile__define self = {spex_any_specfile, $ INHERITS spex_data_strategy } END