PRO write_xrt, index, data, archive=archive, outdir=outdir, $ outfile=outfile, paths_only=paths_only, $ out_paths=out_paths, make_dir=make_dir, verbose=verbose, $ quiet=quiet, qabort=qabort, qstop=qstop ; ========================================================================= ;+ ; PROJECT: ; Solar-B / XRT ; ; NAME: ; WRITE_XRT ; ; CATEGORY: ; File I/O. ; ; PURPOSE: ; Write Level-1 XRT data image files. ; ; CALLING SEQUENCE: ; ; WRITE_XRT, index, data $ ; [,/archive] [,outdir=outdir] [,outfile=outfile] $ ; [,/paths_only] [,/make_dir] [,out_paths=out_paths] $ ; [,/verbose] [,/quiet] [,/qstop] [,qabort=qabort] ; ; INPUTS: ; ; INDEX - [Mandatory] (structure, or structure array, [Nimg]) ; The XRT data keywords. These come from the ; Level-0 FITS files in the header. ; DATA - [Mandatory*] (number array, [Nx,Ny,Nimg]) ; (*This keyword is mandatory UNLESS the PATHS_ONLY ; switch is used.) This is the data-cube paired to ; "index". ; ; KEYWORDS: ; ; /ARCHIVE - [Optional] (Boolean) ; If set, the FITS files will be written into the site ; XRT data archive with the standard filename format. ; ARCHIVE overrides OUTDIR and OUTFILE. ; OUTDIR - [Optional] (string scalar) ; Specifies the fully qualified output directory. ; Default = the current working directory. ; OUTDIR overrides ONLINE. ; OUTFILE - [Optional] (string array, [Nimg]) ; Specifies the output filenames. Default = follow ; the XRT filename standard for Level-1 FITS files: ; L1_XRTyyymmdd_hhmmss.s.fits . ; /PATHS_ONLY - [Optional] (Boolean) ; If set, just return OUT_PATHS but don't write any ; files. ; /MAKE_DIR - [Optional] (Boolean) ; If set, create implied directories if they do not ; exist. ; /VERBOSE - [Optional] (Boolean) If set, print out extra ; information. Overrides "/quiet" (see Note #1). ; /QUIET - [Optional] (Boolean) If set, suppress messages ; (see Note #1). ; /QSTOP - [Optional] (Boolean) For debugging. ; ; OUTPUTS: ; ; This program will write Level-1 FITS files for the input data ; (unless the PATHS_ONLY switch is used). There will be one image per ; file. By default, the files will be written into the current working ; directory, but file-paths can be modified with keywords. ; ; OUT_PATHS - [Optional] (string array, [Nimg]) ; List of implied/derived full file-paths for the ; output. ; QABORT - [Optional] (Boolean) Indicates that the program ; exited gracefully without completing. (Might be ; useful for calling programs.) ; 0: Program ran to completion. ; 1: Program aborted before completion. ; ; EXAMPLES: ; ; Write Level-1 data-cube into current directory: ; IDL> write_xrt, index, data ; ; Write Level-1 data-cube into the site XRT archive: ; IDL> write_xrt, index, data, /archive ; ; Get the output filenames without writing the files: ; IDL> write_xrt, index, data, /paths_only, out_paths ; ; COMMON BLOCKS: ; ; none ; ; NOTES: ; ; 1) There are three levels of verbosity. ; a) "verbose" = highest priority. All errors and messages are ; displayed. ("if q_vb") ; b) "quiet" = lower priority. No errors or messages are ; displayed. ("if q_qt") ; c) neither = lowest priority. All errors and some messages are ; displayed. ("if not q_qt") ; ; 2) If the /ARCHIVE switch is used, then the standard archive path ; and standard filename format will be followed. This overrides ; OUTDIR and OUTFILE. If /ARCHIVE is not used, then OUTDIR and ; OUTFILE are used if they are given. If OUTDIR is not given, ; then the current working directory is used. If OUTFILE is not ; given, then standard format filenames are used. The OUTDIR and ; OUTFILE keywords operate independently. If they are both given, ; then OUTDIR+OUTFILE will be used. ; ; 3) Obviously, /MAKE_DIR cannot create directories if you don't ; have permission on that filesystem to create those directories. ; ; MODIFICATION HISTORY: ; progver = 'v2007-Apr-10' ;--- (M.Weber, J.Cirtain (SAO)) Written. (Based on ; , 2007-Jan-09.) progver = 'v2007-May-20' ;--- (K.Reeves (SAO)) Fixed bug with transposing ; "dir_ends" when it is a scalar (one file). progver = 'v2007-Jun-13' ;--- (M.Weber (SAO)) Removed contraint on ; data level. progver = 'v2011-Jan-06; ;--- (S.Saar (SAO)) added check for length of ; history lines, wrapping as needed ; ;- ; ========================================================================= ;=== Initial setup ======================================= ;=== Set Booleans which control print statements. ;=== Keyword "verbose" overrules "quiet". q_vb = keyword_set(verbose) q_qt = keyword_set(quiet) and (not q_vb) ;=== Initialize program constants. prognam='WRITE_XRT' prognam_len = strlen(prognam) prognam_nul = strmid(' ', $ 0, prognam_len) ;=== Announce version of . if q_vb then box_message, prognam+': Running ' + prognam + $ ' ' + progver + '.' if q_vb then print, prognam+': Performing initial setup...' ;=== Set some keyword Booleans. q_archive = keyword_set(archive) q_outfile = keyword_set(outfile) q_outdir = keyword_set(outdir) q_nowrite = keyword_set(paths_only) q_makedir = keyword_set(make_dir) qstop = keyword_set(qstop) qabort = 0B ;=== Other useful stuff. n_ind = n_elements(index) pdelim = get_delim() if q_vb then print, prognam_nul+' ...OK' ;=== Check inputs ======================================== if q_vb then print, prognam+': Checking inputs...' ;=== Check number of inputs. if (n_params() ne 2) then begin if (not q_qt) then box_message, prognam+': Need to provide both ' $ + 'INDEX and DATA. Aborting.' qabort = 1B return endif ;=== Check index structure for XRT ID. if not required_tags(index, 'date_obs,ec_fw1') then begin if (not q_qt) then box_message, prognam+': This is not an XRT index ' $ + 'structure. Aborting.' qabort = 1B return endif if q_vb then print, prognam_nul+' ...OK' ;=== Generate filenames ================================== if q_vb then print, prognam+': Generating filenames...' ;=== If going into the archive, then follow standard format. if q_archive then begin out_paths = xrt_index2filename(index, /archive_path) ;=== If NOT going into the archive, then proceed. endif else begin ;=== Use filenames if given. if q_outfile then begin out_paths = outfile endif else begin out_paths = xrt_index2filename(index) endelse ;=== Use directories if given. if q_outdir then begin out_paths = outdir + pdelim + temporary(out_paths) endif else begin out_paths = curdir() + pdelim + temporary(out_paths) endelse endelse if q_vb then print, prognam_nul+' ...OK' ;=== Make directories, as necessary ====================== if q_vb then print, prognam+': Checking whether directories exist...' ;=== Make sorted list of unique directory paths. dir_ends = strpos(out_paths, pdelim, /reverse_search) if n_elements(dir_ends) eq 1 then tr_dir_ends = dir_ends $ else tr_dir_ends = transpose(dir_ends) dir_trunc = strmid(out_paths, 0, tr_dir_ends) uniq_dirs = dir_trunc(uniq(dir_trunc, sort(dir_trunc))) dirs_need = where(1 - file_exist(uniq_dirs), need_count) ;=== If some directories do not exist... if (need_count ne 0) then begin ;=== If didn't ask to create directories, then abort. if not q_makedir then begin if (not q_qt) then begin box_message, [prognam+': Some of the directories do not exist. ' $ +'Check OUT_PATHS to see', prognam_nul+' a list of all ' $ +'directories. Use /MAKE_DIR to automatically', $ prognam_nul+' create these directories. Aborting.'] endif qabort = 1B return endif else begin ;=== If asked to create directories, then do so. if q_vb then print, prognam+': Making directories...' for ii = 0, (need_count-1) do begin mk_dir, uniq_dirs(dirs_need[ii]), verbose=q_vb endfor if q_vb then print, prognam_nul+': ...OK' endelse endif if q_vb then print, $ prognam_nul+' ...OK' ;=== Write files ========================================= if not q_nowrite then begin if q_vb then print, prognam+': Writing FITS files...' ;=== check index.history for lines > FITS limit (72) and wrap if needed hist0=index.history sizh0=size(hist0) if max(strlen(hist0)) gt 72 then begin ; if some history lines too long hist=history_wrap(hist0) ; wrap them onto new lines nhist=n_elements(hist) ; count new number of lines if sizh0(0) eq 2 then nim=sizh0(2) else nim=1 ; find number of images hlen=nhist/nim ; new # history lines/image hlen0=n_elements(hist0)/nim ; old # history lines/image for jj=0, nim-1 do begin ; for each image index histj=hist(jj*hlen:(jj+1)*hlen-1) index_outj=index(jj) index_outj.history = histj(0:hlen0-1) ; replace hlen0 history lines update_history,index_outj,histj(hlen0:*),/noroutine ; update new lines if jj eq 0 then index_out=index_outj else $ index_out=[index_out,index_outj] endfor endif else index_out=index mwritefits, index_out, data, outfile=out_paths, /flat_fits, $ loud=q_vb, quiet=q_qt if q_vb then print, prognam_nul+' ...OK' endif ;; (not q_nowrite) ;=== Finish ============================================== if q_vb then box_message, prognam+': Finished.' END ;======================================================================