;+ ; ; NAME: ; spex_fermi_gbm_specfile__define ; ; PURPOSE: ; Provides read_data method for the Fermi GBM instrument. ; NOTE: This procedure is based on spex_hessi_specfile__define. ; ; ; CATEGORY: ; SPECTRAL FITTING, SPEX - messenger ; ; CALLING SEQUENCE: ; ; CALLS: ; ; INPUTS: ; ; OUTPUTS: ; ; INPUT KEYWORDS: ; ; OUTPUT KEYWORDS: ; ; PROCEDURE: ; ; Written 26-Feb-2009, Kim Tolbert ; ; Modification History: ; 08-Feb-2010, Kim. Use TZERO4 instead of TSTART for base time. Works for daily & trigger. ; 08-Jun-2010, RAS, Use quality field to set bad points to 0, ; spec.exposure becomes (1.-spec.quality)*spec.exposure ; 07-Jul-2010, Kim. Added code to locate and set correct rsp file for input file and accum time. ; 18-feb-2011 richard.schwartz@nasa.gov, gbm_fix_counter_overflow inserted to fix counter overflow ; in counts and exposure ; 08-Aug-2011, Kim. Use flare_time, not accum_time, when searching for rsp file over network ; 10-Aug-2011, Kim. Added spex_def_eband arg to read_data, and compute spex_def_eband ; 28-Sep-2011, Kim. Error in read_data - leap seconds were not being added because of error - TZERO4 ; is no longer the base time when mrdfits is called with /dscale. It's set to 0. , so # leap sec was ; calculated as 0 (instead of -1 or -2). So times in spex_ut_edges were high by the number ; of leap seconds since 2001 to time of data (1 in Dec 2005, and 1 in Dec 2008) ; ;------------------------------------------------------------------------------ pro spex_fermi_gbm_specfile_test, o o = obj_new( 'spex_fermi_gbm_specfile' ) o->set, spex_specfile = 'D:\Analysis\working\fermig\2008-12-11\glg_cspec_n5_081211_v00.pha' data = o->getdata() end ;------------------------------------------------------------------------------ pro spex_fermi_gbm_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, spex_def_eband=spex_def_eband, $ err_code=err_code file = self -> get( /spex_specfile ) checkvar, file_index, 0 file = file[file_index] ;message, /cont, 'Reading ' + file + ' ...' a = mrdfits (file, 0, header, /silent) ; ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ; spec = mrdfits(file,1) ; spex_gbm_fits2drm, FILE='C:\Analysis\working\fermig\GL_NaI_0_9_1e12_0inc.rsp', drm_str ;; spex_gbm_fits2drm, FILE='C:\Analysis\working\fermig\GL_NaI_30_9_1e12_30inc.rsp', drm_str ; spectrum=float(spec.counts) ; errors=sqrt(spectrum) ; nen=128 ; livetime = fltarr(nen)+100 ; spex_respinfo='' ; spex_file_time = ['1-jan-2009 01:00:00', '1-jan-2009 01:01:40'] ; spex_ut_edges = anytim(spex_file_time) ; spex_ct_edges = drm_str.edges_out ; spex_area = 126. ; spex_title = 'FERMI GBM' ; spex_detectors = 'Sim' ; spex_interval_filter = -1 ; spex_units = 'counts' ; spex_data_name = 'FERMI GBM' ; spex_deconvolved = 0 ; spex_pseudo_livetime = 0 ; spex_data_pos = [0.,0.] ; return ; ; ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ebounds = mrdfits(file, 1, ehdr, /silent) spec = mrdfits(file,2, shdr, /silent,/dscale) gti = mrdfits(file,3,ghdr, /silent) ; spec should be obtained using mrdfits(file, 2, shdr, /dscale) because we need spec.time and spec.endtime in double gbm_fix_counter_overflow, spec, ebounds ;ras, 18-feb-2011 spectrum = float(spec.counts) errors = sqrt(spectrum) nen = n_elements(spec[0].counts) ; livetime = (intarr(nen)+1) # spec.exposure livetime = (fltarr(nen)+1.0) # (spec.exposure*(1.0-spec.quality)) ;bad points have quality flag set to 1 ; spex_file_time = [anytim( fxpar( header, 'DATE-OBS' ), /vms), anytim( fxpar( header, 'DATE-END' ), /vms)] ; start_time = anytim(mjd2any(fxpar(header, 'MJDREFI') + fxpar(header,'MJDREFF')) + fxpar(header,'TSTART'), /date) ; ; for trigger files, TRIGTIME equals TZERO4, but for daily files, TSTART doesn't match TZERO4. But for both ; times seem to be relative to TZERO4. Check this with fermi people. ; start_time = anytim(mjd2any(fxpar(shdr, 'MJDREFI') + fxpar(shdr,'MJDREFF')) + fxpar(shdr,'TZERO4')) ;; that was wrong, so use trigtime for trigger files, tstart for non-trigger files ; stime = fxpar(shdr, 'TRIGTIME', count=yes_trig) ; if ~yes_trig then stime = fxpar(shdr,'TZERO4') ; start_time = anytim(mjd2any(fxpar(shdr, 'MJDREFI') + fxpar(shdr,'MJDREFF')) + stime) ; OK this is it. TZERO4 is base time for both trigger and daily files. Add TZERO4 to MJDREFI and then ; add the number of leap seconds that have occurred since MJDREFI time ; ref_utc = mjd2any(fxpar(shdr, 'MJDREFI')) ; UTC reference time in sec since 79/1/1, ignore MJDREFF (TT) ; base_sec = fxpar(shdr,'TZERO4') ; sec = ref_utc + base_sec ; this is elapsed sec since UTC reference time of 2001. ; ; Compute # leap seconds that happened since reference time and add to sec ; ref_tai = anytim(ref_utc,/tai) ; sec_tai = anytim(sec, /tai) ; leap_sec = (ref_tai - ref_utc) - (sec_tai - sec) ; start_time = sec + leap_sec ; base time to add time arrays to ; spex_ut_edges = start_time + transpose([[spec.time], [spec.endtime]]) ; The above was wrong because once we added /dscale to the mrdfits call, TZERO4 in the header is set to 0, so ; the base_sec was 0, so leap_sec was always 0. so times were high by number of leap seconds. ref_utc = mjd2any(fxpar(shdr, 'MJDREFI')) ; UTC reference time (1-jan-2001) in sec since 79/1/1, ignore MJDREFF (TT) stime = spec.time + ref_utc etime = spec.endtime + ref_utc nleap = fermi_nleap_sec(stime[0]) spex_ut_edges = transpose([[stime], [etime]]) + nleap spex_file_time = minmax(spex_ut_edges) spex_ct_edges = transpose([[ebounds.e_min], [ebounds.e_max]]) spex_area = 126. spex_title = 'FERMI GBM' spex_detectors = fxpar(header, 'DETNAM') spex_interval_filter = -1 spex_units = 'counts' spex_data_name = 'FERMI GBM' spex_deconvolved = 0 spex_pseudo_livetime = 0 spex_data_pos = [0.,0.] spex_respinfo='' ; if user's accum time is within the input file time (should normally be!), then find any local rsp files ; and see if they have the correct detector and time for the input file. If not, then look across network ; at rsp archive and download file. accum_time = self->get(/spex_accum_time) if has_overlap(spex_file_time, accum_time) then begin rspfiles = file_search('*.{rsp,rsp2}',/full) ; look for either rsp or rsp2 files in local dir fgbm_obj = obj_new('spex_fermi_gbm') det = fgbm_obj->file2det(file) ; time2rsp returns string like '_n1_bn100612_0054', which is det, date, time that must be in rsp file name ; also returns time of flare found. Use that time when searching across network since files are named by flare times rspstring = fgbm_obj->time2rsp(accum_time, det, flare_time=flare_time, status=status) if status eq 1 then begin ; found flare in accum_time interval ; First search in local directory q = where (stregex(file_basename(rspfiles), rspstring, /bool), count) if count gt 0 then begin spex_respinfo = rspfiles[q[0]] endif else begin ; Search over network. Find url over network and copy to local dir url = fgbm_obj->search(flare_time,/rsp, count=count, /copy, file=copyfiles) if count gt 0 then q = where (stregex(file_basename(copyfiles), rspstring, /bool), count) if count gt 0 then spex_respinfo = copyfiles[q[0]] endelse endif endif ; set default ebands differently for BGO and NAI detectors edg = minmax(spex_ct_edges) bgo = strpos(spex_detectors, 'BGO') ne -1 spex_def_eband = bgo ? [300,1000,2000,7000,30000] : [4.5,15,25,50,100,300,600,2000] spex_def_eband = get_edges(spex_def_eband, /edges_2) q = where (spex_def_eband[1,*] gt edg[0] and spex_def_eband[0,*] lt edg[1], count) if count gt 1 then spex_def_eband = spex_def_eband[*,q] ; FIX AREA, DATA_POS, UT_EDGES !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! end ;------------------------------------------------------------------------------ pro spex_fermi_gbm_specfile__define self = {spex_fermi_gbm_specfile, $ INHERITS spex_data_strategy } END