;+ ; NAME: ; smei_buf_getframe ; PURPOSE: ; Extracts individual frames from all *.buf files in the specified ; source directory. ; CATEGORY: ; camera/idl/buf ; CALLING SEQUENCE: FUNCTION smei_buf_getframe, trange, $ source = source , $ camera = camera , $ count = count , $ dups_too= dups_too , $ usedb = usedb , $ silent = silent ; INPUTS: ; trange array[n]; type: time structure ; n=0: if not specified than all frames in all L1A files in ; 'source' are extracted. ; n=1: extract frame for specified time ; n=2: extract all frames between trange[0] and trange[1] ; n>2: extract frames for specified times ; OPTIONAL INPUT PARAMETERS: ; source=source scalar, array; type: string ; scalar: source directory containing L1A *.buf files ; array : list of fully-qualified names of L1A files ; camera=camera scalar, array[2], array[3] ; numbers 1, 2, or 3, identifying the cameras to be extracted ; if 'camera' not set then all cameras are extracted. ; /usedb if set then an attempt is made to find a file pointer in the ; first L1A file to be accessed close to trange[0] (by ; looking for nearby frames in the SMEI data base). ; (this is primarily used to replace corrupted frames in the ; SMEI data base). ; OUTPUTS: ; hdr array; type: smei_frm_hdr structure ; OPTIONAL OUTPUT PARAMETERS: ; count=count scalar; type: integer ; # frames returned in 'hdr' ; INCLUDE: @compile_opt.pro ; On error, return to caller ; CALLS: ; InitVar, IsType, IsTime, CheckDir, FindAllFiles, smei_buf_read, boost ; TimeSet, TimeUnit, TimeGet, where_common, TimeOp, TimeLimits ; smei_property, destroyvar, smei_getfile ; EXTERNAL: ; smei_buf_hdr__define, smei_frm_hdr__define ; PROCEDURE: ; Frame headers are stored in the same order as they are read from the ; L1A files, i.e. there will be contiguous groups of frames from each ; L1A files. Each L1A file appears to be chronological, but subsequent ; files overlap (because of the double dump?). As a result the frame ; header array as a whole (from more than one L1A file) is probably not ; chronological. ; MODIFICATION HISTORY: ; MAR-2003, Paul Hick (UCSD/CASS; pphick@ucsd.edu) ;- InitVar, dups_too, /key InitVar, usedb , /key InitVar, silent , 0 InitVar, source, getenv('CDRD') IF source[0] EQ '' THEN source = '/media/cdrecorder' bad_result = {smei_frm_hdr} usec = TimeUnit(/sec) ; Check for .buf files in source directory CASE CheckDir(source[0]) OF 0: BEGIN buf_file = source count = n_elements(buf_file) END 1: buf_file = FindAllFiles('*.buf', path=source, count=count) ENDCASE IF count EQ 0 THEN BEGIN message, /info, 'no *.buf files found in '+source RETURN, bad_result ENDIF IF IsTime(trange) THEN BEGIN IF n_elements(trange) NE 2 THEN BEGIN tall = trange trange = TimeLimits(trange, /bounds) ENDIF message, /info, 'extracting time range '+strjoin(TimeGet(trange,/_ydoy,upto=usec),' - ') ; If trange is set then limit the files to be accessed to files containing ; data inside time range hdr = replicate( {smei_buf_hdr}, count ) FOR i=0L,count-1 DO $ IF smei_buf_read(buf_file[i], /get_file_header, file_header=tmp) THEN $ hdr[i] = tmp print ;tmp = where(TimeOp(/subtract, trange[0], hdr.ut_stop , use ) LT 0 AND $ ; TimeOp(/subtract, trange[1], hdr.ut_start, usec ) GT 0 , count) tmp = where(TimeOp(/subtract, trange[0], hdr.ut_stop , usec ) LE 0 AND $ TimeOp(/subtract, trange[1], hdr.ut_start, usec ) GE 0 , count) IF count EQ 0 THEN BEGIN message, /info, 'no files with frames in this time range' RETURN, bad_result ENDIF buf_file = buf_file[tmp] trunc_time = trange[1] IF usedb THEN BEGIN tmp = smei_getfile(TimeOp(/subtract,trange[0],TimeSet(/diff,[61,1],usec)), camera=camera, count=cnt, /get_hdr ) IF cnt NE 0 THEN BEGIN tmp = tmp[cnt-1] ; Check one minute period prior to trange[0] for frames in the SMEI database ; If a frame is found then the L1A pointer for that frame will be used to jump ; into the L1A file(s) buf_file (in smei_buf_read). FOR i=0,n_elements(buf_file)-1 DO BEGIN IF smei_property(tmp,/l1a_file) EQ GetFileSpec(buf_file[i],part='name') THEN BEGIN pointer = smei_property(tmp,/l1a_pntr) message, /info, smei_property(tmp,/name)+'@'+strcompress(pointer,/rem)+' in '+smei_property(tmp,/l1a_file) buf_file = buf_file[i] count = 1 break ENDIF ELSE $ message, /info, hide_env(buf_file[i])+', no location in SMEI data base found' ENDFOR ENDIF print, buf_file ENDIF ENDIF ; Read all frame headers destroyvar, hdr ; Don't remove !! FOR i=0L,count-1 DO BEGIN IF smei_buf_read(buf_file[i], frame_headers=tmp, trunc_time=trunc_time,start_pointer=pointer, silent=silent) THEN BEGIN boost, hdr, tmp cnt = n_elements(tmp) IF cnt GT 1 THEN BEGIN dt = smei_property(tmp,/time) dt = TimeOp(/subtract, dt, dt[0], usec) dt = where( dt[1:cnt-1] LT dt[0:cnt-2], cnt ) IF cnt NE 0 THEN BEGIN message, /info, 'file not in chronological order: '+buf_file[i] FOR j=0,cnt-1 DO print, '>>>>> ', strjoin( $ TimeGet( smei_property(tmp[dt[j]:dt[j]+1],/time), /_ydoy, upto=usec )+ $ ' ('+strcompress(tmp[dt[j]:dt[j]+1].frame_nr,/rem)+')' $ ,' - ') ENDIF ENDIF ENDIF ENDFOR count = n_elements(hdr) IF count EQ 0 THEN BEGIN message, /info, 'no frames found. Bummer, should not have happened' RETURN, bad_result ENDIF thdr = smei_property(hdr, /time) IF IsTime(trange) THEN BEGIN ; If trange is set only retain headers inside time range tmp = where(TimeOp(/subtract, thdr, trange[0], usec ) GE 0 AND $ TimeOp(/subtract, thdr, trange[1], usec ) LE 0, count) IF count EQ 0 THEN BEGIN message, /info, 'no frames in this time range' RETURN, bad_result ENDIF hdr = hdr [tmp] thdr = thdr[tmp] IF IsType(tall, /defined) THEN BEGIN tmp = where_common( TimeOp(/subtract,thdr,thdr[0],usec), TimeOp(/subtract,tall,thdr[0],usec), count=count ) IF count EQ 0 THEN BEGIN message, /info, 'none of the frames found' RETURN, bad_result ENDIF hdr = hdr [tmp] thdr = thdr[tmp] trange = tall ENDIF ENDIF ; Check for cameras IF IsType(camera, /defined) THEN BEGIN tmp = where_common(hdr.camera, camera, count=count) IF count EQ 0 THEN BEGIN message, /info, 'no frames for cameras '+strjoin( strcompress(camera,/rem), ' or ' ) RETURN, bad_result ENDIF hdr = hdr [tmp] thdr = thdr[tmp] ENDIF IF count GT 1 AND NOT dups_too THEN BEGIN nhdr = count ; The L1A files appear to be in chronological order, but subsequent files overlap. ; Each frame appears to be present twice in different L1A files (probably we are getting ; both telemetry dumps). ; Eliminate the double entries here. I'm not sure which frame is retained by ; the IDL uniq function (probably the last). ; Compare camera and time of frames. tmp = TimeGet(thdr, /_ydoy, upto=usec)+'_'+strcompress(hdr.camera,/rem) tmp = uniq(tmp, sort(tmp)) count = n_elements(tmp) message, /info, strcompress(nhdr-count,/rem)+' dups;'+ $ strcompress(count)+'/'+strcompress(nhdr,/rem)+' frames remain' ; The sort operation maintains the original order of the entries in hdr. ; Headers are grouped by file making extraction of frames by smei_buf_read faster. tmp = tmp[sort(tmp)] hdr = hdr [tmp] thdr = thdr[tmp] ENDIF RETURN, hdr & END