FUNCTION make_xrt_filt_contam, input1, channels, intype=intype, $ verbose=verbose, quiet=quiet, $ qabort=qabort, qstop=qstop ; ========================================================================= ;+ ; PROJECT: ; Solar-B / XRT ; ; NAME: ; ; MAKE_XRT_FILT_CONTAM ; ; CATEGORY: ; ; Instrument response ; ; PURPOSE: ; ; Produce the filter contamination transmission functions for a set of ; XRT x-ray channels. Takes thicknesses as input, or index arrays or ; image times that are converted to thicknesses. This program is a ; subroutine of --- interface convenience was not a ; design goal. ; ; CALLING SEQUENCE: ; ; Result = MAKE_XRT_FILT_CONTAM( input1, channels [,intype=intype] ; [,/verbose] [,/quiet] [,qabort=qabort] [,/qstop] ) ; ; INPUTS: ; ; INPUT1 - [Mandatory] index structure array, (default); ; OR pair of thicknesses [CCD,filter1+2]; ; (two element float array); ; OR time of observation (string) ; To calculate the contamination transmission, a pair of ; layer thicknesses must be provided (in Angstroms). ; The default mode is to assume that INPUT1 is an ; index structure, from which the filter and time ; information to calculate thickensses can be extracted. ; Alternately, a pair of layer thicknesses [CCD,filter1+2] ; or a time may be provided. Times must be ; provided in a string format that SSWIDL will recognize. ; If thicknesses or times are provided, INTYPE must ; be set to 1 or 2 respectively (see INTYPE below). ; CHANNELS - [Mandatory] (structure array, ; {XRT_chn_config_vNNNN} [Nthicknesses]) ; This is an array of structures of type ; "XRT_chn_config" and with a structure name ; of the form {XRT_chn_config_vNNNN}. For a ; more complete description of this complicated ; structure, see the XRT Analysis Guide. The ; base set of channels is provided in the XRT SSWIDL ; tree by a file with a pathname like this: ; $SSW_XRT/idl/response/channels/xrt_channels_vNNNN.geny ; That file is automatically found, read, and passed ; to if ; is used as the interface, as intended. ; ; KEYWORDS: ; ; INTYPE - [Optional] (integer scalar) This keyword is set to: ; = 0: INPUT1 is an index structure (Default) ; = 1: INPUT1 is a 2 element vector of paired thicknesses ; [CCD, filter1+2] (in Angstroms). ; = 2: INPUT1 is a time of an XRT image ; ( format). ; [Mandatory] if input is thicknesses or image times. ; /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: ; ; Return - [Mandatory] (structure array, ; (FCONTAM) {XRT_filt_contam_vNNNN} [Nthicknesses]) ; This structure contains data and information ; about the filter contamination layer for a given ; thickness. The thickness varies with time between ; filter bakeouts and acts like an extra absorption layer, ; so the transmission factor must be included when ; calculating the effective area for each XRT ; channel for any given image or point in time. ; ; Here is a listing of the fields of the "XRT_filt_contam" ; structure. Descriptions are provided further ; down.: ; ; FCONTAM {XRT_filt_contam_vNNNN} ; - TYPE (string scalar) ; - FCTM_STR_VERSION (string scalar) ; - FCTM_STR_DESCR (string scalar) ; - FILTER1 (string scalar) ; - FILTER2 (string scalar) ; - NAME (string scalar) ; - LONG_NAME (string scalar) ; - MATERIAL (string scalar) ; - DENS (float scalar) ; - DENS_UNITS (string scalar) ; - THICK (float scalar) ; - THICK_UNITS (string scalar) ; - THICK_TIME (string scalar) ; - WAVE (float array, [Nwave]) ; - WAVE_UNITS (string scalar) ; - TRANS (float array, [Nwave]) ; - LENGTH (long scalar) ; - DATA_FILES (string array, [5]) ; - HISTORY (string array, [3]) ; - COMMENTS (string array, [5]) ; ; Here are descriptions of the fields in the ; "XRT_contam" structure.: ; ; TYPE: (string scalar) ; [Default value = 'XRT_filt_contam'.] ; This is the generic name of the structure ; that contains the contamination functions ; and information. The version of the structure ; definition might evolve, but the TYPE should ; remain constant. See FCTM_STR_VERSION. The ; value is initialized at creation. This field ; should NOT be changed. ; FCTM_STR_VERSION: (string scalar) ; [The default value = 'XRT_filt_contam_vNNNN', ; where NNNN is a 4-digit number.] ; This is the version number of the "XRT_filt_contam" ; structure definition. In addition to being ; recorded in this field, this is also the ; "unique structure name" in the IDL sense. ; The value is initialized at creation. This ; field should NOT be changed. ; FCTM_STR_DESCR: (string scalar) ; This is a sentence or two that describes the ; purpose of this structure type. This field ; should NOT be changed. ; FILTER1: (string scalar) ; This is the name of the FW1 filter used ; in the calculation. ; FILTER2: (string scalar) ; This is the name of the FW2 filter used ; in the calculation. ; NAME: (string scalar) ; This is a name for this contamination layer ; thickness. This string should concisely ; identify the contamination layer (although ; it may not be unique). Some programs may ; refer to this string, so its usage should ; be regularized. (Compare to LONG_NAME.) This ; field MAY be changed, but the default is ; recommended. ; LONG_NAME: (string scalar) ; This is a longer string for the name for ; this contamination layer thickness. This ; field should not be referred to by software; ; it is intended to provide a more informative ; description for humans. This field MAY be ; changed, but the default is recommended. ; MATERIAL: (string scalar) ; Name of substance or chemical compound forming ; the contamination layer. (NAME may or may ; not specify the substance's identity. MATERIAL ; should always specify the substance's ; identity.) ; DENS: (float scalar) ; Density of the contamination material named ; in the MATERIAL tag, and that was used to ; calculate the transmission function. The ; value must be consistent with the units named ; in DENS_UNITS. ; DENS_UNITS: (string scalar) ; Units of the value in the DENS tag. The units ; must be 'g cm^-3' (so that other programs ; can reliably interpret DENS). ; THICK: (float scalar) ; Thickness of the contamination material named ; in the MATERIAL tag, and that was used to ; calculate the transmission function. The ; value must be consistent with the units named ; in THICK_UNITS. ; THICK_UNITS: (string scalar) ; Units of the value in the THICK tag. The ; units must be 'Angstroms' (so that other ; programs can reliably interpret THICK). ; THICK_TIME: (string scalar) ; This is the mission time for which the ; contamination thickness (tag THICK) was ; calculated, as specified by INPUT1 and keyword ; INTYPE=0. It is possible that the thickness ; was asserted independent of a mission time ; (using INPUT1 and INTYPE=1), in which case ; the THICK_TIME tag may have an empty string ; value (''). The value should be in a string ; time format recognized by SSWIDL. ; WAVE: (float array, [Nwave]) ; The wavelength abscissa of the transmission ; function (see TRANS) for the specified ; thickness of the contamination layer. The ; values must make a montonically increasing ; sequence of floating point numbers, starting ; from the first address of the array. If the ; sequence is shorter than the length of this ; array, then all addresses after the sequence ; ends should have a value of zero. The sequence ; length is recorded in the LENGTH tag. The ; values must be consistent with the units ; named in WAVE_UNITS. ; WAVE_UNITS: (string scalar) ; Units of the value in the WAVE tag. The units ; must be 'Angstroms' (so that other programs ; can reliably interpret WAVE). ; TRANS: (float array, [Nwave]) ; The dimensionless transmission as a function ; of wavelength for the specified thickness ; of the contamination layer. The values must ; make a sequence of floating point numbers, ; starting from the first address of the array, ; and should correspond in position to values ; of WAVE. If the sequence is shorter than the ; length of this array, then all addresses ; after the sequence ends should have a value ; of zero. The sequence length is recorded in ; the LENGTH tag. ; LENGTH: (long scalar) ; The length of the paired sequences of WAVE ; and TRANS, indicating how much of those ; arrays contains useful information. E.g.: ; IDL> len = contam[0].length ; IDL> plot, contam[0].wave[0:len-1], $ ; IDL> contam[0].trans[0:len-1] ; DATA_FILES: (string array, [5]) ; This is a list of filenames of reference ; data that were used in the specification of ; the contamination. It is primarily intended ; for listing any files that might be important ; for reference purposes. This field should ; NOT be changed, but empty strings may be ; added to. ; HISTORY: (string array, [3]) ; This text array is for XRT programs to record ; any instance in which they have modified the ; content of the "XRT_filt_contam" type of structure ; for this particular contamination description. ; On creation, a line is added for the creation ; of the "XRT_filt_contam" structure in ; . An entry string is ; composed of (a) a program name, (b) the ; program's version/date, (c) colon separator, ; (d) Timestamp (in parentheses) of when the ; program completed the described action, and ; (e) a summation of what the program created ; or modified in the "XRT_filt_contam" structure. ; Values are inserted starting at the lowest ; address of this array. Remaining unused ; addresses are filled with the empty string. ; Filled strings should NOT be overwritten. ; Users should use the COMMENTS field to add ; their own notations to this structure. ; COMMENTS: (string array, [5]) ; A tag for adding notations regarding this ; specific contamination layer and thickness. ; Users and programs are encouraged to put ; content in the lower addresses, and assign ; empty strings {''} to the higher, unused ; addresses. ; ; QABORT - [Optional] (Boolean) Indicates whether the program ; exited gracefully without completing. (Might be ; useful for calling programs.) ; 0: Program ran to completion. ; 1: Program aborted before completion. ; ; EXAMPLES: ; ; This program is a subroutine of . ; ; 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") ; ; ; 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 = 'v2009-Nov-20' ;--- (S.Saar) Written, based largely on ; ; ;- ; ========================================================================= ; === 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 = 'MAKE_XRT_FILT_CONTAM' prognul = ' ' ;=== 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. qtype = keyword_set(intype) qstop = keyword_set(qstop) qabort = 0B if qtype eq 0 then intype=0 ; default is index ;=== Some basic program values. if intype eq 1 then c=2 else c=1 nthicks = n_elements(input1)/c nch = n_elements(channels) ps=path_sep() contam_dir = get_logenv('$SSW_XRT') + ps + 'idl' + ps + 'response' $ + ps + 'contam' + ps ;; In this next bit, we define some structure templates ;; that will be used further on. ;=== Define the {XRT_filt_contam} stucture. fctm_str_version = 'XRT_FILT_CONTAM_V0001' fctm_str = create_struct(name=fctm_str_version, $ 'type', 'XRT_FILT_CONTAM', $ 'fctm_str_version', fctm_str_version, $ 'fctm_str_descr', 'Provides description of a filter ' $ + 'contamination layer for an XRT ' $ + 'channel.', $ 'filter1', '', $ 'filter2', '', $ 'name', 'DEHP', $ 'long_name', 'Bis(2-ethylhexyl)phthalate filter' $ + ' contamination layer', $ 'material', 'DEHP', $ 'dens', 0.0, $ 'dens_units', 'g cm^-3', $ 'thick', 0.0, $ 'thick_units', 'Angstroms', $ 'thick_time', '', $ 'wave', fltarr(5000), $ 'wave_units', 'Angstroms', $ 'trans', fltarr(5000), $ 'length', 0L, $ 'data_files', strarr(5), $ 'history', strarr(3), $ 'comments', strarr(5) ) if q_vb then print, prognam+': Performing initial setup... OK' ; === Check inputs =============================== if q_vb then print, prognam+': Checking inputs...' ;=== Check that some input has been given. if (n_params() ne 2) then begin if (not q_qt) then box_message, $ [prognam+': There should be exactly two input parameters:', $ prognul+' INPUT1 and CHANNELS. See program header. Aborting...' ] qabort = 1B return, 0 endif ;stop ;=== Check type of INPUT1. ;; If INPUT1 is an array of thicknesses... case 1 of (intype eq 0): begin ; abort if input1 not a structure if datatype(input1[0]) ne 'STC' then begin if (not q_qt) then box_message, $ [prognam+': INPUT1 must be a structure if INTYPE=0 ', $ prognul+'or undefined. See program header. Aborting...' ] qabort = 1B return, 0 endif end (intype eq 1): begin ;; If INPUT1 is not a number array, then abort. if (is_number(input1[0]) eq 0B) then begin if (not q_qt) then box_message, $ [prognam+': INPUT1 is not a number array, ', $ prognul+' inconsistent with input keyword INTYPE=1.', $ prognul+' See program header. Aborting...' ] qabort = 1B return, 0 endif end else: begin ;; Else if INPUT1 is (assumed) an array of times... ;; If INPUT1 is not a string array, then abort. if (datatype(input1[0]) ne 'STR') then begin if (not q_qt) then box_message, $ [prognam+': INPUT1 is not a string array, ', $ prognul+' inconsistent with input keyword INTYPE=2.', $ prognul+' See program header. Aborting...' ] qabort = 1B return, 0 endif ;; Standardize times to CCSDS format. ;; If entry format is unrecognizable to SSWIDL, ;; then the output will be in internal structure format ;; instead of being in string format. times = anytim2utc(input1, /ccsds) if (datatype(times) ne 'STR') then begin if (not q_qt) then box_message, $ [prognam+': INPUT1 does not contain times in a format', $ prognul+' recognizable by .', $ prognul+' See program header. Aborting...' ] qabort = 1B return, 0 endif end endcase if q_vb then print, prognam+': Checking inputs... OK' ; === Get thicknesses, if necessary. ============= if q_vb then print, prognam+': Checking contamination thicknesses...' case 1 of (intype eq 0): begin ; input is index thicks=fltarr(nthicks) fthicks=thicks for j=0,nthicks-1 do begin thicks(j)=xrt_time2contam(index=input1(j),filter=fthickj) fthicks(j)=fthickj endfor filt1=input1.ec_fw1_ filt2=input1.ec_fw2_ times=input1.date_obs cthicks=thicks-fthicks end (intype eq 1): begin ; input is thicks ;; If thicknesses input, then set empty times... thicks = total(input1,1) ; sum individual thicknesses fthicks=reform(input1(1,*)) cthicks=reform(input1(0,*)) filt1=channels.fp_filter1.name filt2=channels.fp_filter2.name times=strarr(nthicks) ; *** new add end else: begin ; input was times thicks=fltarr(nch) fthicks=thicks for j=0,nch-1 do begin xrt_chan2fw, channels[j], fw1, fw2 thicks(j)=xrt_time2contam(fw1,fw2,input1(0),filter=fthickj) fthicks(j)=fthickj endfor cthicks=thicks - fthicks filt1=channels.fp_filter1.name filt2=channels.fp_filter2.name end endcase ;; Else if times input, then solve thicknesses... ; thicks = xrt_time2contam(0,0,times,) ; endelse if q_vb then print, prognam+': Checking contamination thicknesses... OK' ; === Initialize the output structure array. ================= if q_vb then print, prognam+': Initializing output array...' ;=== Prepare the {XRT_filt_contam_ref} structure array. fcontam = replicate(fctm_str, nthicks) fcontam.long_name = fcontam.long_name + '; thickness = ' $ + strcompress(fthicks,/rem) + ' ' + $ fcontam.thick_units fcontam.filter1 = filt1 fcontam.filter2 = filt2 fcontam.thick = fthicks fcontam.thick_time = times if q_vb then print, prognam+': Initializing output array... OK' ; === Calculate contamination transmissions. ================= if q_vb then print, prognam+': Calculating the transmissions...' ;; Just solve each thickness once. (all are typically different...) thick_list = fthicks[uniq(fthicks, sort(fthicks))] ; thick_list=fthicks n_list = n_elements(thick_list) ;; Set some variable names for . densities = 1 n_files = 1 for i_list = 0,(n_list-1) do begin if q_vb then print, prognam+': Working on ' + $ strcompress(i_list+1,/rem) + ' of ' + $ strcompress(n_list,/rem) + ' thicknesses.' ss1 = where(fthicks eq thick_list[i_list], count1) multifilt, wave, trans, 'DEHP', fthicks[ss1[0]], 1.0, $ densities=densities, n_files=n_files, caldir=contam_dir len = n_elements(wave) numfiles = n_elements(n_files) ;; Load results of into FCONTAM. ;; Use matrix tricks to avoid loops. fcontam[ss1].dens = densities[0] fcontam[ss1].length = len fcontam[ss1].wave[0:len-1] = wave # (intarr(count1)+1) fcontam[ss1].trans[0:len-1] = trans # (intarr(count1)+1) for ii = 0,(numfiles-1) do fcontam[ss1].data_files[ii] = n_files[ii] endfor ;; (i_list, loop over thick_list) if q_vb then print, prognam+': Calculating the transmissions... OK' ; === Finish ===================================== get_utc, utc, /stime hist_string = prognam+' '+progver+': ('+utc+' UTC) Generated {' $ + fcontam.type+'} structure with name "' + fcontam.name+'".' fcontam.history[0] = hist_string if q_vb then box_message, prognam+': ... Finished.' if qstop then stop return, fcontam END ;======================================================================