;+ ; NAME: ; XTETIMES ; ; PURPOSE: ; Return photon times from XTE PCU data that satisfy Module and Channel ; selection filters. ; ; CATEGORY: ; XTE. ; ; CALLING SEQUENCE: ; ; Result = XTETIMES( File, [Modules [, Channels]] ) ; ; INPUTS: ; File: Name of the XTE PCU data file in FITS format. ; ; OPTIONAL INPUTS: ; Modules: Scalar or array specifying the PCU detector module(s) photons ; should be selected from. Must be in the range, [0,4]. ; (Default = [0,1,2,3,4] ; ; Channels: Scalar or array specifying the PCU energy channel(s) photons ; should be selected from. The channel assignments are defined ; in the configuration routine associated with the data, ; (e.g. E_1ms_128M_0_8s -> E1MS128M.PRO). ; OUTPUTS: ; Array of photon times, [LONARR(nts)], which satisfy the Modules and ; Channels filter(s). ; ; OPTIONAL OUTPUT KEYWORD PARAMETERS: ; ; OEVENT: Corresponding event bytes containing the ; detector module and energy channel information. ; ; ODATAMODE:The configuration of the XTE data, (e.g. E_4us_4B_0_1s) ; ; OTIMEDEL: Time resolution or UNITS of the returned time array in SECONDS. ; ; OSTART: Time of the first photon (zero offset). ; ; MODIFICATION HISTORY: ; Written by: Han Wen, August 1996. ;- function XTETIMES, File, Modules, Channels, OEVENT=Event, $ OTIMEDEL=Timedel, ODATAMODE=Datamode, OSTART=Ostart ; Check parameters nmod = N_ELEMENTS(Modules) nchan = N_ELEMENTS(Channels) if (nmod gt 0) then begin mmax = MAX(Modules,MIN=mmin) if (mmin lt 0) or (mmax gt 4) then message,$ 'Module filter out of range, must be [0-4].' endif ; Open XTE FITS file fxbopen, lu, File, 1, header & n = N_ELEMENTS(header) ; Extract parameters from header ; > number of rows tok = 'Number of rows' & tokL = '=' & tokR = '/' p = STRPOS(header,tok) & i = (WHERE(p ne -1))(0) pL = STRPOS(header(i),tokL) & pR = STRPOS(header(i),tokR) str = STRMID(header(i),pL+1,pR-pL-1) nrow = LONG(str) ; > time resolution tok = 'TIMEDEL' & tokL = '=' & tokR = '/' p = STRPOS(header,tok) & i = (WHERE(p ne -1))(0) pL = STRPOS(header(i),tokL) & pR = STRPOS(header(i),tokR) str = STRMID(header(i),pL+1,pR-pL-1) timedel = DOUBLE(str) ; > max time in an event word tok = 'T[0.0:' & tokL = '{' & tokR = '}' p = STRPOS(header,tok) & i = (WHERE(p ne -1))(0) str = STRMID(header(i),p(i),1000)+header(i+1) pL = STRPOS(str,tokL) & pR = STRPOS(str,tokR) str = STRMID(str,pL+1,pR-pL-1) ninterval = 2L^LONG(str) ; > configuration tok = 'DATAMODE' & tokL = '=' & tokR = '/' p = STRPOS(header,tok) & i = (WHERE(p ne -1))(0) pL = STRPOS(header(i),tokL) & pR = STRPOS(header(i),tokR) str = STRMID(header(i),pL+1,pR-pL-1) datamode = STRTRIM(str,2) datamode = STRMID(datamode,1,STRLEN(datamode)-2) tok = '_' & config = datamode for i=0,3 do STRREPLACE, config, tok, '' config = STRMID(config,0,8) nblock = 100000L nj = long(nrow/nblock) + 1 tlast = 0L ; Break up FITS read into nj chunks to save memory for j=0L,nj-1 do begin rows = [1+j*nblock, (j+1)*nblock < nrow] print,'Processing FITS rows: ',STRTRIM(j,2),'/',STRTRIM(nj-1,2),$ ' no.s: ',ARR2STR(rows) fxbread, lu, ts, 'Time', rows if (j eq 0) then t00 = ts(0) ts = ts - t00 ts = TEMPORARY(ts)/timedel ts = long(TEMPORARY(ts)) fxbread, lu, bytes, 'Event', rows CALL_PROCEDURE, config, bytes, M, D10, C10, tck ; Find all rows where M[1]{1} key is set h = WHERE( M eq 1,nmask) if (nmask eq 0) then begin print,'No photon times found with M[1]{1} tok.' goto, NO_TIMES endif ncurr= rows(1) - rows(0) + 1 ; "Unroll" or "un-MOD" the times encoded in the Event words M127 = 127 tck = LONG(TEMPORARY(tck)) h127 = WHERE( (REFORM(bytes(0,*)) eq M127) and $ ((REFORM(bytes(1,*)) and 3) eq 0), n127 ) if (n127 gt 0) then begin if (h127(0) ne 0) then begin k1 = 0 k2 = h127(0) - 1 tck(k1:k2) = tck(k1:k2) + tlast endif dh = h127(1:*) - h127 hh = WHERE( dh gt 1, n_unMOD ) & n_unMOD = n_unMOD + 1 for k= 0,n_unMOD-2 do begin k1 = h127(hh(k)) + 1 k2 = h127(hh(k)+1) - 1 tck(k1:k2) = tck(k1:k2) + ts(k1-1) endfor k1 = h127(n127-1) + 1 tlast= ts( k1-1 ) if (k1 lt ncurr) then tck(k1:*) = tck(k1:*) + tlast endif bytes = REFORM(bytes(0,*),/OVERWRITE) ; Remove all rows where M[1]{1} key is NOT set if (nmask ne ncurr) then begin ts = ts(h) D10 = D10(h) C10 = C10(h) bytes= bytes(h) tck = tck(h) endif ; Check the times array, ts with the times encoded into the Event words CORRECT: diff = tck - ts hbad = WHERE( diff ne 0, nbad ) if (nbad gt 0) then begin i = hbad(0) case i of 0 : rng = [i,i+1] nmask-1 : rng = [i-1,i] else : rng = [i-1,i,i+1] endcase dt1 = ts(rng) - ts((rng-1) > 0) dt2 = tck(rng) - tck((rng-1)> 0) tck = ts + diff corr = ts(hbad(0)) - tck(hbad(0)) ncorr= corr / FLOAT(ninterval) print, 'WARNING: Rollover correction error!' print, 'index: ',STRTRIM(i,2) print, 'PCA #: ',ARR2STR(d10(rng)) print, 'tck : ',ARR2STR(tck(rng)) print, 'dts : ',ARR2STR(dt1) print, 'dtsck: ',ARR2STR(dt2) print, 'corr : ',ARR2STR(corr),', ncorr:',STRTRIM(ncorr,2) tck(i:*) = tck(i:*) + corr goto, CORRECT endif ; Apply detector module and energy channel filters b = BYTARR( nmask ) if ((nmod+nchan) gt 0) then begin for i=0,nmod-1 do b = b or (D10 eq Modules(i)) for i=0,nchan-1 do b = b or (C10 eq Channels(i)) h = WHERE(b eq 1,nfilter) if (nfilter gt 0) then begin ts = ts(h) bytes = bytes(h) endif else begin print,'No photon times found satisfying filter.' goto, NO_TIMES endelse endif if (N_ELEMENTS(times) eq 0) $ then begin times = TEMPORARY(ts) event = TEMPORARY(bytes) endif else begin times = [times, TEMPORARY(ts)] event = [event, TEMPORARY(bytes) ] endelse NO_TIMES: endfor Ostart = t00/timedel fxbclose,lu if (N_ELEMENTS(times) eq 0) then times = -1 return, times end