;+ ; NAME: ; smei_buf_get ; PURPOSE: ; Extracts data area for specified frames ; CATEGORY: ; camera/idl/buf ; CALLING SEQUENCE: PRO smei_buf_get, frame_headers, source=source, destination=destination, $ nic=nic, fits=fits, ptr_data=ptr_data, gzip=gzip, $ trange=trange, count=count, silent=silent, _extra=_extra ; INPUTS: ; frame_headers array; type: smei_frm_hdr structure ; frame header array (as returned by smei_buf_getframe) ; OPTIONAL INPUT PARAMETERS: ; trange=trange array[n]; type: time structure ; time info for tracking down SMEI frames. ; See href=smei_buf_getframe= for more information. ; source=source scalar; type: string; default: /media/cdrecorder ; directory where the L1A files are located. ; If trange is used this is passed to smei_buf_getframe. ; If frame_headers is specified than this is added to ; frame_headers.l1a_file (which does not include a ; directory). ; destination=destination ; scalar; type: string ; directory into which to write the individual frame files ; Output files have form c#frm_YYYY_DDD_HHMMSS (for padded ; frames) or c#roi_YYYY_DDD_HHMMSS (for unpadded ROI ; frames). # is the camera number (1,2 or 3). ; /nic if set (and a valid destination is specified) then frame are ; written in NIC file format (i.e. the data are stored in ; the same way as for the TMO data, but the trailer has ; a totally different structure) ; /fits if set (and a valid destination is specified) then a fits ; file is written ; (at this point the frame headers are not written into ; the fits file. ; /split_dir if writing out lots and lots of frames it is probably better ; to distribute the frames over multiple directories. ; If /split_dir is set then each day of data is split in ; 4-hour intervals over 6 directories with names ; destination/YYYY_DDD/HH with HH=00,04,08,12,16,20 ; If the output keyword ptr_data is set, and /nic, /fits are not set ; then the frame data ar returned as a heap variable. ; ; /overwrite will unconditionally overwrite existing files when ; writing individual frames to disk ; /gzip gzip directories ; OPTIONAL OUTPUT PARAMETERS: ; count=count # frames found ; ; ptr_data=ptr_data ; array; type: pointer ; the frame data corresponding to 'hdr' ; i.e. *ptr_data[i] is the 2D frame data array. ; INCLUDE: @compile_opt.pro ; On error, return to caller ; CALLS: ; InitVar, IsType, CheckDir, TimeUnit, TimeGet, smei_setup_roi ; smei_buf_getframe, smei_buf_read, smei_buf_gzip, txt_read ; smei_frm_write, smei_buf_prep, smei_property, IsTime ; TimeSet, hide_env ; EXAMPLE: ; The most efficient way to replace a damaged frame in the SMEI database from a DVD ; is the following command: ; smei_buf_get, timeset('2005_006_160819'), cam=2, /fits, dest=getenv('TUB'), /usedb ; This requires that the proper DVD is mounted on /media/cdrecorder (specify ; source= to override the default) and that the SMEI database is accessible. ; Note: dest='SMEIDB?' will NOT work. ; PROCEDURE: ; If either /fits or /nic is set then data are saved to binary files in ; the destination directory (no pointer data will be returned). ; ; File names will have the form c#frm_YYYY_DDD_HHMMSS.ext: ; # = camera id (1,2 or 3) ; ext = 'fts' or 'nic' ; ; If neither /nic nor /fits is specified then data can be extracted in ; ptr_data. ; ; /fits SET: ; ; Writes bare fits file (no extra frame header info is put in the file yet, ; just the data are stored). ; ; /nic SET (obsolete; we don't use .nic files anymore): ; ; A 512 byte trailer is added after the data array. ; The first 3 bytes are the characters 'buf' (to distinguish these ; files from e.g. the TMO data files). The next 256 is the unmodified ; header from the original frame (except for byte swapping to put the ; data in native machine format. ; ; MODIFICATION HISTORY: ; MAR-2003, Paul Hick (UCSD/CASS) ; MAY-2005, Paul Hick (UCSD/CASS; pphick@ucsd.edu) ; Changed default source from /media/cdrecorder to /media/CDROM ;- InitVar, gzip, /key InitVar, nic , /key InitVar, fits, /key InitVar, source, '/media/CDROM' InitVar, silent, 0 write_frames = nic OR fits ; Make sure the destination directory exists, if specified. IF write_frames THEN BEGIN write_frames = IsType(destination, /defined) CASE write_frames OF 0: BEGIN message, /info, 'no destination directory' RETURN END 1: BEGIN IF destination NE 'SMEIDB?' THEN BEGIN write_frames = CheckDir(destination) IF NOT write_frames THEN BEGIN message, /info, 'non-existent destination: '+hide_env(destination) RETURN ENDIF ENDIF END ENDCASE time_file = filepath(root=getenv('HOME'),'l1a_last_frame.txt') CASE txt_read(time_file, last_time) OF 0: last_time = TimeSet(yr=2003, doy=1) ; Pre-launch date 1: last_time = TimeSet(last_time) ENDCASE frm_count = lonarr(4) ENDIF ; If a time range is specified, go get the matching frame headers ; (overwriting any frame headers specified in input). IF IsTime(frame_headers) THEN IF IsType(trange,/undefined) THEN trange = frame_headers IF IsTime(trange) THEN BEGIN frame_headers = smei_buf_getframe(trange, source=source, _extra=_extra, count=count, silent=silent) IF count EQ 0 THEN RETURN ENDIF IF NOT IsType(frame_headers, /structure) THEN $ RETURN IF smei_property(frame_headers[0],/l1a_file) EQ '' THEN $ RETURN count = n_elements(frame_headers) CASE write_frames OF 0: BEGIN IF IsType(ptr_data, /pointer) THEN ptr_free, ptr_data ptr_data = ptrarr(count, /allocate_heap) END 1: message, /info, 'writing '+(['nic','fits'])[fits]+' files' ENDCASE need_gzip = 0L FOR i=0L,count-1 DO BEGIN hdri = frame_headers[i] ; Decide whether or no go get the data. ; - Only write unsigned integer data to .nic file ; At this point hdri.fullframe is still zero for the ROI data. frame_ok = 1-nic OR hdri.bitpix EQ 16 IF frame_ok THEN BEGIN IF write_frames THEN BEGIN frm_file = smei_buf_prep(hdri, destination, nic=nic, $ fits=fits, last_dir=last_dir, filelist=filelist, $ _extra=_extra, count=frm_count, last_time=last_time,$ gzip=gzip, need_gzip=need_gzip) frame_ok = frm_file NE '' ENDIF IF frame_ok THEN BEGIN l1a_file = filepath(root=source,smei_property(hdri,/l1a_file)+'.buf') IF smei_buf_read(l1a_file, hdri.l1a_pntr, /get_next_frame, $ frame_nr=hdri.frame_nr, frame_data=frame_data, $ frame_headers=new_frame_hdr) THEN BEGIN ; smei_buf_read will pad ROI data to a 2D frame. Some fields in ; the frame header (frame_x, frame_y, n_data_values and ; full_frame) are updated accordingly. We pick up the updated ; frame header here. frame_headers[i] = new_frame_hdr hdri = new_frame_hdr ; Write frames is true only if one of the write keywords (/nic ; or /fits) were set and a valid destination was specified. CASE write_frames OF 0: *ptr_data [i] = frame_data 1: BEGIN IF frm_file NE '' THEN BEGIN smei_frm_write, hdri, frame_data, frm_file, count=frm_count need_gzip += 1L ENDIF END ENDCASE ENDIF ENDIF ENDIF ENDFOR tmp = smei_buf_read(/force_close) ; Close the last file smei_setup_roi, /destroy IF gzip THEN smei_buf_gzip, last_dir, need_gzip IF write_frames THEN BEGIN IF IsType(frm_count,/defined) THEN $ message, /info, $ 'total:' +strcompress(frm_count[0]+frm_count[1])+' frames'+$ '; write' +strcompress(frm_count[0])+ $ '; skip' +strcompress(frm_count[1])+ $ '; insert'+strcompress(frm_count[2])+ $ '; clone' +strcompress(frm_count[3]) openw, /get_lun, iu, time_file printf, iu, TimeGet(last_time,/ydoy,upto=TimeUnit(/sec)) free_lun, iu ENDIF RETURN & END