PRO mk_xrt_spec_genx, specname, wave, temp, spec, data_files, $ comments=comments, infile=infile, outfile=outfile, $ outvar=outvar, apec=apec, verbose=verbose, $ quiet=quiet, qabort=qabort, qstop=qstop ; ========================================================================= ;+ ; PROJECT: ; Solar-B / XRT ; ; NAME: ; ; MK_XRT_SPEC_GENX ; ; CATEGORY: ; ; Instrument response ; ; PURPOSE: ; ; This program helps users put a spectral emission model into a ; structure format that other XRT routines will expect. The benefit ; is that the routines which calculate the XRT x-ray responses may be ; used in a modular manner with the user's choice of spectral ; emission codes. ; ; CALLING SEQUENCE: ; ; MK_XRT_SPEC_GENX, specname, wave, temp, spec, data_files, ; [,infile=infile] [,outfile=outfile] [,outvar=outvar] ; [,/apec] [,/verbose] [,/quiet] [,qabort=qabort] [,/qstop] ; ; INPUTS: ; ; SPECNAME - [Mandatory, param or INFILE] (string scalar) ; This will be the name/ID given to this spectral model. ; It should be sufficiently distinctive to be ; searched on. ; WAVE - [Mandatory, param or INFILE] (float array, ; [Nwavelengths]) This is a 1D array of monotonically ; increasing wavelengths. Units = 'Angstroms'. Must ; correlate to the SPEC array. Maximum length is 5000. ; TEMP - [Mandatory, param or INFILE] (float array, ; [Ntemperatures]) This is a 1D array of monotonically ; increasing temperatures. Units = 'log K'. Must ; correlate to the SPEC array. Maximum length is 50. ; SPEC - [Mandatory, param or INFILE] ; (float array, [Nwavelengths, Ntemperatures]) ; This is a 2D array of a spectral emission model. ; Units = 'ph cm^3 s^-1 sr^-1 A^-1'. This variable ; is dependent on WAVE and TEMP. Therefore, it has ; the same restrictions on dimension lengths ; (Nwave le 5000, Ntemp le 50). ; DATA_FILES - [Mandatory, param or INFILE] ; (string scalar or array, [N le 5]) ; These are the source files for the model. If INFILE ; is used, then DATA_FILES = INFILE. ; COMMENTS - [Optional, param or INFILE] ; (string scalar or array, [N le 5]) ; There is a field in the generated structure to ; store comments. ; ; KEYWORDS: ; ; INFILE - [Optional] (string scalar) ; The mandatory inputs may be passed in as a file. ; The file format should be 'genx', such that the ; file may be read with the command. ; The mandatory inputs (except DATA_FILES) must be ; stored in a specific order. Here is the command used ; to read this file: ; IDL> restgenx, file=infile, specname, wave, temp, spec ; The stored inputs must still match the units ; given above. By default for this option, ; DATA_FILES = INFILE. See Note #2. ; /APEC - [Optional] (Boolean) Indicates a special INFILE case ; for APEC models. See Note #2. ; /VERBOSE - [Optional] (Boolean) If set, print out extra ; information. Overrides "/quiet" (see Note #3). ; /QUIET - [Optional] (Boolean) If set, suppress messages ; (see Note #3). ; /QSTOP - [Optional] (Boolean) For debugging. ; ; OUTPUTS: ; ; OUTFILE - [Optional] (string scalar) ; (NB: Either OUTFILE or OUTVAR should be used in ; order to catch the result.) ; Write the constructed spectral emission model ; structure to a specified "genx" file. The extension ; ".geny" will be automatically appended to the ; filename. See OUTVAR for structure description. ; OUTVAR - [Optional] (named variable) ; (NB: Either OUTFILE or OUTVAR should be used in ; order to catch the result.) ; Return the constructed spectral emission model ; structure. ; TYPE STRING 'spectrum' ; NAME STRING ; WAVE FLOAT Array[5000] ; WAVE_UNITS STRING 'Angstroms' ; WLENGTH LONG ; TEMP FLOAT Array[50] ; TEMP_UNITS STRING 'log K' ; TLENGTH LONG ; SPEC FLOAT Array[5000, 50] ; SPEC_UNITS STRING 'ph cm^3 s^-1 sr^-1 A^-1' ; DATA_FILES STRING Array[5] ; HISTORY STRING Array[5] ; COMMENTS STRING Array[5] ; 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: ; ; Provide inputs directly, get output immediately: ; IDL> spec_str = 1 ; IDL> mk_xrt_spec_genx, specname, wave, temp, spec, data_files, $ ; IDL> outvar=spec_str ; ; Provide inputs in a file, write output to a file: ; IDL> mk_xrt_spec_genx, infile='my_input.genx', outfile='the_output' ; IDL> $ls the_output.geny ; ; COMMON BLOCKS: ; ; none ; ; NOTES: ; ; 1) APEC spectra are generated with an implicit column EM of ; 3.1437917e+27 [cm^-5]. The units of spec are correctly given as ; 'ph cm^-2 s^-1 sr^-1 A^-1'. This factor is taken out in this ; program to generalize the spectral emission model. ; ; 2) This routine is part of a modular approach to calculating ; the XRT response functions. A user may use this routine ; to put a spectral emission code into a standardized format ; that related XRT routines will understand. Most spectral model ; codes/atomic databases can generate the required ; inputs in some defined file format and structure. If the file ; format, contents, and corrections are defined for a given ; code/database, then these can be added to this code as a ; special case. See the usage of the APEC keyword as an example. ; Contact the XRT team to nominate additional cases which would ; be of common benefit. ; ; 3) 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") ; ; CONTACT: ; ; Comments, feedback, and bug reports regarding this routine may be ; directed to this email address: ; xrt_manager ~at~ head.cfa.harvard.edu ; ; MODIFICATION HISTORY: ; progver = 'v2007-May-16' ;--- (M.Weber) Written. (Based on heavily on ; earlier work, though.) ; ;- ; ========================================================================= ; === Initial setup ============================== ;=== Set Booleans which control print statements. ;=== Keyword "verbose" overrules "quiet". q_vb = keyword_set(verbose) q_qt = keyword_set(quiet) and (q_vb eq 0) ;=== Initialize program constants. prognam = 'MK_XRT_SPEC_GENX' prognul = ' ' apec_em_factor = (1.0D+44) / ((2.46*725.0*1.0E+5)^2.) ;; = 3.1437917e+27 [cm^-5] See Note #1. ;=== Announce version of program. if q_vb then box_message, prognam+': Running ' + progver + '.' if q_vb then print, prognam+': Performing initial setup...' ;=== Set some keyword Booleans. qinfile = keyword_set(infile) qoutfile = keyword_set(outfile) qapec = keyword_set(apec) qstop = keyword_set(qstop) qabort = 0B if (not keyword_set(comments)) then comments = '' if q_vb then print, prognul+' ...OK' ; === Check inputs =============================== if q_vb then print, prognam+': Checking inputs...' if ((n_params() ne 5) and (qinfile eq 0)) then begin if (not q_qt) then box_message, prognam+': Insufficient inputs.' $ + 'See program header. Aborting...' qabort = 1B return endif if ((n_params() eq 5) and (qinfile)) then begin if (q_qt eq 0) then box_message, [prognam+': Conflicting inputs. ' $ + 'See program header.', prognul+' Using the provided ' $ + 'parameters...'] qinfile = 0B return endif if qinfile then begin if ((datatype(infile) ne 'STR') or (n_elements(infile) ne 1)) then begin if (q_qt eq 0) then box_message, [prognam+': INFILE not a scalar ' $ + 'string. Aborting...'] qabort = 1B return endif if (not file_exist(infile)) then begin if (q_qt eq 0) then box_message, [prognam+': Cannot find INFILE. ' $ + 'Aborting...'] qabort = 1B return endif endif if qoutfile then begin if ((datatype(outfile) ne 'STR') or (n_elements(outfile) ne 1)) then begin if (q_qt eq 0) then box_message, [prognam+': OUTFILE not a scalar ' $ + 'string.', prognul+' Proceeding, but will not write to OUTFILE...'] qoutfile = 0B return endif endif if q_vb then print, prognul+' ...OK' ; === Read infile, apply corrections ============= if qinfile then begin if q_vb then print, prognam+': Reading INFILE...' ;=== This section provides a way to read in spectral models ;=== from the principal atomic databases. See Note #2. case 1 of qapec: begin ;; APEC case. restgen, file=infile, wave, spec, spec_units, temp spec = spec / apec_em_factor ;; See Note #1. comments = '' wlen = n_elements(wave) tlen = n_elements(temp) clen = n_elements(comments) ;=== Extract base of filename for specname. pos1 = rstrpos(infile, '/') pos2 = rstrpos(infile, '.') specname = strmid(infile, pos1+1, pos2-pos1-1) end else: begin ;; Generic case. Requires vars have correct units! restgenx, file=infile, wave, temp, spec, specname wlen = n_elements(wave) tlen = n_elements(temp) end endcase data_files = infile if q_vb then print, prognul+' ...OK' endif ; === Generate spectrum structure ================ if q_vb then print, prognam+': Generating spectrum structure...' outvar = {type:'spectrum', name:'', $ wave:fltarr(5000), wave_units:'Angstroms', wlength:1L, $ temp:fltarr(50), temp_units:'log K', tlength:1L, $ spec:fltarr(5000,50), spec_units:'ph cm^3 s^-1 sr^-1 A^-1', $ data_files:strarr(5), history:strarr(5), comments:strarr(5) } ndfil = n_elements(data_files) outvar.name = specname outvar.wave[0:wlen-1] = wave outvar.wlength = wlen outvar.temp[0:tlen-1] = temp outvar.tlength = tlen outvar.spec[0:wlen-1,0:tlen-1] = spec outvar.data_files[0:ndfil-1] = data_files outvar.comments[0:clen-1] = comments if q_vb then print, prognul+' ...OK' ; === Finish ===================================== get_utc, utc, /stime outvar.history[0] = prognam+' (' + progver + '): Generated at ' + utc $ + ' UTC.' if qoutfile then begin if q_vb then print, prognam+': Writing OUTFILE...' savegenx, file=outfile, outvar if q_vb then print, prognul+' ...OK' endif if q_vb then print, prognam+': ...Finished.' if qstop then stop END ;======================================================================