FUNCTION make_xrt_wave_resp, index=index, $ contam_thick=contam_thick, $ contam_time=contam_time, $ chn_filename=chn_filename, $ outfile=outfile, el_units=el_units, $ verbose=verbose, quiet=quiet, $ qabort=qabort, qstop=qstop ; ========================================================================= ;+ ; PROJECT: ; Solar-B / XRT ; ; NAME: ; ; MAKE_XRT_WAVE_RESP ; ; CATEGORY: ; ; Instrument response ; ; PURPOSE: ; ; Produce the effective areas and spectral responses for a ; set of XRT x-ray channels, accounting for some thickness ; of the CCD contamination layer. The spectral response is ; directly calculated from the effective area, and both are ; functions of wavelength. ; ; CALLING SEQUENCE: ; ; Result = MAKE_XRT_WAVE_RESP( { [index=index] OR ; [contam_thick=contam_thick] OR ; [contam_time=contam_time] } ; [,chn_filename=chn_filename] [,outfile=outfile] ; [,/el_units] [,/verbose] [,/quiet] [,qabort=qabort] ; [,/qstop] ) ; ; INPUTS: ; ; INDEX - [Optional*] (structure array, [Nimages]) ; (*) ONE (and only one) of these three inputs MUST ; be specified: {INDEX, CONTAM_THICK, CONTAM_TIME}. ; This structure must be a standard XRT data ; "index" array, such as is produced by the ; Level-1 reformatter (). (See ; the XRT Analysis Guide for a more detailed ; description of this structure.) If input is ; provided through this choice of keyword, ; then the image times will be used to determine ; contamination thicknesses and x-ray channels. ; (See the description of the "Return" output ; and Note #1.) ; CONTAM_THICK - [Optional*] (two element vector) [CCD,filter1+2] ; (*) ONE (and only one) of these three inputs MUST ; be specified: {INDEX, CONTAM_THICK, CONTAM_TIME}. ; This input keyword may be used to specify a ; single pair of contamination layer thicknesses (in ; Angstroms). Thicknesses must be given as ; [CCD thickness, combined filter1+2 thickness], ; where filter1+2 indicates the filters in filter ; wheel 1 and 2. The "Return" output will provide ; the responses for all of the XRT x-ray ; channels using this thickness. (See the ; description of the "Return" output and Note #1.) ; CONTAM_TIME - [Optional*] (string scalar) ; (*) ONE (and only one) of these three inputs MUST ; be specified: {INDEX, CONTAM_THICK, CONTAM_TIME}. ; This input must be in a time format that is ; recognizable by the SSWIDL program ; . This input keyword may ; be used to specify a single "mission time", ; which will be used to specify a unique ; contamination thickness. The "Return" output ; will provide the responses for all of the ; XRT x-ray channels using this thickness. ; (See the description of the "Return" output ; and Note #1.) ; CHN_FILENAME - [Optional] (string scalar) ; A filename of the form "xrt_channels_vNNNN.geny", ; where NNNN is a 4-digit version number. These ; files are the XRT channel configuration files ; distributed by the XRT Team. The default ; behavior (i.e., if CHN_FILENAME is not used) ; will be to get the latest, most correct file. ; (Older versions are distributed in case ; earlier analysis must be recreated.) The ; input may be a full or relative pathname. ; If it is a relative pathname, the program ; will first look in $SSW_XRT/idl/response/channels/, ; and then look in the current working directory. ; OUTFILE - [Optional] (string scalar) ; Write the constructed wave response structure ; to the specified file, using . ; The extension ".geny" will be automatically ; appended to the filename. See "Return" output ; for structure description. ; ; KEYWORDS: ; ; /EL_UNITS - [Optional] (Boolean) If set, then the units of ; the spectral response (in the SPEC_RESP array ; output) will be [el cm^2 sr ph^-1 pix^-1]. ; Otherwise, the default is to produce the ; the response in units of [DN cm^2 sr ph^-1 pix^-1]. ; /VERBOSE - [Optional] (Boolean) If set, print out extra ; information. Overrides "/quiet" (see Note #4). ; /QUIET - [Optional] (Boolean) If set, suppress messages ; (see Note #4). ; /QSTOP - [Optional] (Boolean) For debugging. ; ; ; OUTPUTS: ; ; Return - [Mandatory] (structure array, ; (WAVE_RESP) {XRT_wave_resp_vNNNN} [Nchannels]) ; This structure contains data and information about ; the effective areas and spectral response functions ; for a set of XRT x-ray channels. This is the input ; that describes the instrument response. ; ; Here is a listing of the fields of the {XRT_wave_resp} ; structure. Descriptions are provided further down.: ; ; WAVE_RESP {XRT_wave_resp_vNNNN} ; - TYPE (string scalar) ; - WRS_STR_VERSION (string scalar) ; - WRS_STR_DESCR (string scalar) ; - NAME (string scalar) ; - CONFG (structure scalar, {XRT_chn_config_ref_vNNNN}) ; - CONTAM (structure scalar, {XRT_contam_ref_vNNNN}) ; - FCONTAM (structure scalar, {XRT_filt_contam_ref_vNNNN}) ; - EFFAR (structure scalar, {XRT_eff_area_vNNNN}) ; - SPRSP (structure scalar, {XRT_spec_resp_vNNNN}) ; - HISTORY (string array, [3]) ; - COMMENTS (string array, [5]) ; ; Here are descriptions of the fields in the ; {XRT_wave_resp} structure.: ; ; TYPE: (string scalar) ; [Default value = 'XRT_wave_resp'.] ; This is the generic name of the structure ; that contains the wavelength response ; functions and information. The version ; of the structure definition might evolve, ; but the TYPE should remain constant. See ; WRS_STR_VERSION. This field should NOT ; be changed. ; WRS_STR_VERSION: (string scalar) ; [Default value = 'XRT_wave_resp_vNNNN', ; where NNNN is a 4-digit number.] This ; is the version number of the "XRT_wave_resp" ; structure definition. In addition to ; being recorded in this field, this is ; also the "unique structure name" in the ; IDL sense. This field should NOT be changed. ; WRS_STR_DESCR: (string scalar) ; This is a sentence or two that describes ; the purpose of this structure type. This ; field should NOT be changed. ; NAME: (string scalar) ; This is a name for these wavelength ; responses for this channel and contamination ; thickness. On creation, it inherits the ; name of the EFF_AREA structure that was ; used to create it. This string concisely ; identifies these dependent wavelength ; responses (although it may not be unique). ; This field MAY be changed, but the default ; is recommended. ; CONFG: (structure scalar, {XRT_chn_config_ref_vNNNN}) ; This structure contains information about ; the instrument components and the history ; of their role in the processing that has ; been performed on this channel to produce ; this temperature response function. ; Large arrays (such as the ; channel transmission function) have been ; abridged, but there should be sufficient ; information in this structure to recover ; or reproduce the corresponding full ; channel structure (of type "XRT_chn_config"). ; 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 . ; ; Here is a listing of the top-level fields ; of the "XRT_chn_config" structure. ; ; CONFG {XRT_chn_config_ref_vNNNN} ; - TYPE (string scalar) ; - CHN_STR_VERSION (string scalar) ; - CHN_STR_DESCR (string scalar) ; - NAME (string scalar) ; - LONG_NAME (string scalar) ; - OBSERVATORY (string scalar) ; - INSTRUMENT (string scalar) ; - GEOM (structure scalar,{XRT_geometry_vNNNN}) ; - EN_FILTER (structure scalar,{XRT_filter_ref_vNNNN}) ; - MIRROR1 (structure scalar,{XRT_mirror_ref_vNNNN}) ; - MIRROR2 (structure scalar,{XRT_mirror_ref_vNNNN}) ; - FP_FILTER1 (structure scalar,{XRT_filter_ref_vNNNN}) ; - FP_FILTER2 (structure scalar,{XRT_filter_ref_vNNNN}) ; - CCD (structure scalar,{XRT_ccd_ref_vNNNN}) ; - CONFIG_FILENAME (string scalar) ; - HISTORY (string array, [3]) ; - COMMENTS (string array, [5]) ; ; CONTAM: (structure scalar, {XRT_contam_ref_vNNNN}) ; This structure contains information about ; the particular thickness of the CCD ; contamination layer (which affects the ; response of the channel) and the history ; of its processing. Large arrays (such ; as the contamination's transmission ; function) have been abridged, but there ; should be sufficient information in this ; structure to recover or reproduce the ; corresponding full contamination structure ; (of type "XRT_contam"). More information ; about the content of this "XRT_contam_ref" ; type of structure may be found in the ; XRT Analysis Guide or in the program ; header of . ; ; Here is a listing of the fields of the ; "XRT_contam_ref" structure. ; ; CONTAM {XRT_contam_ref_vNNNN} ; - TYPE (string scalar) ; - CTM_STR_VERSION (string scalar) ; - CTM_STR_DESCR (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) ; - DATA_FILES (string array, [5]) ; - HISTORY (string array, [3]) ; - COMMENTS (string array, [5]) ; FCONTAM: (structure scalar, {XRT_filt_contam_ref_vNNNN}) ; This structure contains information about ; the particular thickness of the combined filter ; contamination layer (which affects the ; response of the channel) and the history ; of its processing. Large arrays (such ; as the contamination's transmission ; function) have been abridged, but there ; should be sufficient information in this ; structure to recover or reproduce the ; corresponding full contamination structure ; (of type "XRT_filt_contam"). More information ; about the content of this "XRT_filt_contam_ref" ; type of structure may be found in the ; XRT Analysis Guide or in the program ; header of . ; ; Here is a listing of the fields of the ; "XRT_filt_contam_ref" structure. ; ; FCONTAM {XRT_filt_contam_ref_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) ; - DATA_FILES (string array, [5]) ; - HISTORY (string array, [3]) ; - COMMENTS (string array, [5]) ; ; EFFAR: (structure scalar, {XRT_eff_area_vNNNN}) ; This structure contains information about ; the channel's effective area and about ; the history of its processing. More ; information about the content of this ; "XRT_eff_area" type of structure may be ; found in the XRT Analysis Guide or in ; the program header of . ; ; Here is a listing of the fields of the ; "XRT_eff_area" structure. ; ; EFF_AREAS {XRT_eff_area_vNNNN} ; - TYPE (string scalar) ; - EFF_STR_VERSION (string scalar) ; - EFF_STR_DESCR (string scalar) ; - NAME (string scalar) ; - WAVE (float array, [Nwave]) ; - WAVE_UNITS (string scalar) ; - EFF_AREA (float array, [Nwave]) ; - EFF_AREA_UNITS (string scalar) ; - LENGTH (long scalar) ; - HISTORY (string array, [3]) ; - COMMENTS (string array, [5]) ; ; SPRSP: (structure scalar, {XRT_spec_resp_vNNNN}) ; This structure contains information about ; the channel's spectral response and about ; the history of its processing. More ; information about the content of this ; "XRT_spec_resp" type of structure may be ; found in the XRT Analysis Guide or in ; the program header of . ; ; Here is a listing of the fields of the ; "XRT_spec_resp" structure. ; ; SPEC_RESP {XRT_spec_resp_vNNNN} ; - TYPE (string scalar) ; - SRS_STR_VERSION (string scalar) ; - SRS_STR_DESCR (string scalar) ; - NAME (string scalar) ; - WAVE (float array, [Nwave]) ; - WAVE_UNITS (string scalar) ; - SPEC_RESP (float array, [Nwave]) ; - SPEC_RESP_UNITS (string scalar) ; - LENGTH (long scalar) ; - GAIN_USED (float scalar) ; - HISTORY (string array, [3]) ; - COMMENTS (string array, [5]) ; ; 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_temp_resp" ; structure for this particular channel. ; On creation, a line is added for the ; creation of the "XRT_temp_resp" 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_temp_resp" 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 the ; temperature response described for this ; XRT channel. 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: ; ; Basic usage #1 (for a datacube INDEX, DATA): ; IDL> help, data, index ; IDL> w_resp = make_xrt_wave_resp(index=index) ; IDL> help, w_resp ; IDL> help, w_resp, w_resp.effar, w_resp.sprsp, /st ; ; Basic usage #2 (for all channels with single pair of contamination ; thicknesses): ; IDL> w_resp = make_xrt_wave_resp(contam_thick=[1000,500.]) ;; Angstroms ; IDL> help, w_resp ; IDL> help, w_resp, w_resp.effar, w_resp.sprsp, /st ; ; Basic usage #3 (for all channels at single mission time): ; IDL> ctime = '2007-May-25 10:00:00' ; IDL> w_resp = make_xrt_wave_resp(contam_time=ctime) ; IDL> help, w_resp ; IDL> help, w_resp, w_resp.effar, w_resp.sprsp, /st ; ; Plotting the effective area for the 3rd image: ; IDL> ichn = 2 ; IDL> print, w_resp[ichn].effar.name ; IDL> wlen = w_resp[ichn].effar.length ; IDL> plot, w_resp[ichn].effar.wave[0:wlen-1], $ ; IDL> w_resp[ichn].effar.eff_area[0:wlen-1] ; ; Check the x-ray channel ID and contamination thickness: ; (This info should be in w_resp[ichn].name, too.) ; IDL> print, w_resp[ichn].confg.name ; IDL> print, w_resp[ichn].contam.thick, $ ; IDL> w_resp[ichn].contam.thick_units ; ; COMMON BLOCKS: ; ; none ; ; NOTES: ; ; 1) A discussion of the input and output modalities. ; ; One (and only one) of the following three input keywords ; MUST be used: {INDEX, CONTAM_THICK, CONTAM_TIME}. These ; are used to input information about the contamination ; thicknesses and x-ray channels for which the effective ; areas and spectral responses will be calculated. This ; choice also affects the "Return" output. ; ; Input modes: ; ; A) Contamination time: INDEX or CONTAM_TIME may be used ; to indicate times during the mission which may be ; correlated to specific contamination thicknesses. ; ; B) Contamination thickness: CONTAM_THICK may be used to ; indicate an explicit contamination thicknesses, without ; reference to any mission time. ; ; Output modes: ; ; C) "Image series": If INDEX is used to specify a sequence ; (of length Nimages) of image times paired to x-ray ; channels, then the "Return" output will be an array ; (of length Nimages) of "XRT_wave_resp" structures ; corresponding to those images. For example, if INDEX ; represents 100 "Al-poly" images, then the output array ; will represent the "Al-poly" response functions for ; those 100 contamination times. ; ; D) "All channels": If CONTAM_THICK is used to specify a ; single pair [CCD,filter1+2] of contamination thicknesses, or ; if CONTAM_TIME is used to specify a single contamination time, ; then the "Return" output will be an array (of length Nchannel) ; of "XRT_wave_resp" structures corresponding to the ; set of XRT x-ray channels, all using that single ; contamination thickness pair. For example, there are 9 ; "single filter" x-ray channels, so the output array ; will represent all 9 channels with a single contamination ; thickness pair applied. ; ; Please note that it is NOT possible to generate an "all ; channels" output array for more than one contamination ; thickness. In other words, it is not currently possible ; to directly create a 2-dim output array of lengths ; [Nimages, Nchannels]. (That functionality might be ; implemented in the future.) However, this can easily be ; created by the user by calling ; in a loop. However, the output structures have several ; arrays of size fltarr(5000), so one should be careful ; about calculating responses for very large datasets. ; ; ; 2) This version of the program assumes the pixel size is ; that of a "full-resolution" XRT CCD pixel. It does not yet ; account for any pixel summing ("image binning"). ; ; 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") ; ; 4) This routine replaces and deprecates and ; . Those older routines can not account ; for recent updates to the calibrations, including the ; CCD and filter contamination layers in particular. ; ; 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 = 'v2008-Sep-01' ;--- (M.Weber) Written. Takes over calculations ; previously performed by ; and --- those ; routines are deprecated. progver = 'v2008-Oct-01' ;--- (M.Weber) Reviewed version. progver = 'v2008-Nov-21' ;--- (M.Weber) Changed path separator from ; forward slash to path_sep(). progver = 'v2009-Nov-20' ;--- (S.Saar) Updated program to include filter ; contamination. ; progver = 'v2012-March-16' ;--- (K. Reeves) Added channel filename to output if verbose is set. ; ; ;- ; ========================================================================= ; === 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_WAVE_RESP' 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. qindex = keyword_set(index) qctthick = keyword_set(contam_thick) qcttime = keyword_set(contam_time) qchnfile = keyword_set(chn_filename) qoutfile = keyword_set(outfile) qelunits = keyword_set(el_units) qstop = keyword_set(qstop) qabort = 0B intype = qctthick + qcttime*2 ;=== Some basic program values. ps = path_sep() chn_dir = get_logenv('$SSW_XRT') + ps + 'idl' + ps + 'response' $ + ps + 'channels' + ps chn_pattern = 'xrt_channels_v[0-9][0-9][0-9][0-9].geny' ;=== Identify some tagnames that will need to exist ;=== in some input structures. BE CAREFUL about redefining ;=== this program's output structures ==> these arrays ;=== might need to be updated. idx_tagnames = ['DATE_OBS', 'EC_FW1_', 'EC_FW2_'] geo_tagnames = ['type', 'geo_str_version', 'geo_str_descr', 'name', $ 'long_name', 'foc_len', 'foc_len_units', $ 'aperture_area', 'aperture_area_units', $ 'data_files', 'history', 'comments' ] chn_tagnames = ['type', 'chn_str_version', 'chn_str_descr', 'name', $ 'long_name', 'observatory', 'instrument', 'geom', $ 'en_filter', 'mirror1', 'mirror2', 'fp_filter1', $ 'fp_filter2', 'ccd', 'config_filename', $ 'history', 'comments' ] ;; In this next bit, we define some structure templates ;; that will be used further on. ;=== Define the {XRT_filter_ref} stucture. flt_str_version = 'XRT_FILTER_REF_V0001' flt_ref = create_struct(name=flt_str_version, $ 'type', 'XRT_FILTER_REF', $ 'flt_str_version', flt_str_version, $ 'flt_str_descr', 'Specifies a filter configuration, ' $ + 'without the transmission function.', $ 'name', '', $ 'long_name', '', $ 'material', strarr(4), $ 'thick', fltarr(4), $ 'thick_units', '', $ 'dens', fltarr(4), $ 'dens_units', '', $ 'substrate', '', $ 'mesh_trans', 0.0, $ 'data_files', strarr(5), $ 'history', strarr(3), $ 'comments', strarr(5) ) flt_tagnames = tag_names(flt_ref) ;=== Define the {XRT_mirror_ref} stucture. mir_str_version = 'XRT_MIRROR_REF_V0001' mir_ref = create_struct(name=mir_str_version, $ 'type', 'XRT_MIRROR_REF', $ 'mir_str_version', mir_str_version, $ 'mir_str_descr', 'Specifies a mirror configuration, ' $ + 'without the reflection function.', $ 'name', '', $ 'long_name', '', $ 'material', '', $ 'dens', 0.0, $ 'dens_units', '', $ 'graze_angle', 0.0, $ 'graze_angle_units', '', $ 'data_files', strarr(5), $ 'history', strarr(3), $ 'comments', strarr(5) ) mir_tagnames = tag_names(mir_ref) ;=== Define the {XRT_ccd_ref} stucture. ccd_str_version = 'XRT_CCD_REF_V0001' ccd_ref = create_struct(name=ccd_str_version, $ 'type', 'XRT_CCD_REF', $ 'ccd_str_version', ccd_str_version, $ 'ccd_str_descr', 'Specifies a CCD configuration, ' $ + 'without the Q.E. function.', $ 'name', '', $ 'long_name', '', $ 'ev_per_el', 0.0, $ 'ev_per_el_units', '', $ 'full_well', 0.0, $ 'full_well_units', '', $ 'gain_l', 0.0, $ 'gain_r', 0.0, $ 'gain_units', '', $ 'pixel_size', 0.0, $ 'pixel_size_units', '', $ 'data_files', strarr(5), $ 'history', strarr(3), $ 'comments', strarr(5) ) ccd_tagnames = tag_names(ccd_ref) ;; NOTE: The {XRT_chn_config_ref} structure gets defined later ;; in this program, because it must inherit a substructure from ;; a variable that doesn't exist at this point. 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 ;=== to determine the contamination. if ( (qindex + qctthick + qcttime) ne 1) then begin if (not q_qt) then box_message, $ [prognam+': One (and only one) of these keywords must be input:',$ prognul+' INDEX, CONTAM_THICK, or CONTAM_TIME.', $ prognul+' See program header. Aborting...' ] qabort = 1B return, 0 endif ;=== Check type of INDEX. if qindex then begin if (datatype(index) ne 'STC') then begin if (not q_qt) then box_message, $ [prognam+': Input INDEX must be a structure. ', $ prognul+' See program header. Aborting...' ] qabort = 1B return, 0 endif else begin if not required_tags(index[0], idx_tagnames) then begin if (not q_qt) then box_message, $ [prognam+': Input INDEX does not have required tags:', $ prognul+' ' + idx_tagnames, $ prognul+' See program header. Aborting...' ] qabort = 1B return, 0 endif endelse endif ;=== Check type of CONTAM_THICK. if qctthick then begin if ( (n_elements(contam_thick) ne 2) or $ (is_number(contam_thick[0]) ne 1) ) then begin if (not q_qt) then box_message, $ [prognam+': Input CONTAM_THICK must be an array of two numbers.', $ prognul+' See program header. Aborting...' ] qabort = 1B return, 0 endif endif ;=== Check type of CONTAM_TIME. if qcttime then begin if ( (n_elements(contam_time) ne 1) or $ (datatype(contam_time[0]) ne 'STR') ) then begin if (not q_qt) then box_message, $ [prognam+': Input CONTAM_TIME must be a scalar string.', $ prognul+' See program header. Aborting...' ] qabort = 1B return, 0 endif endif ;=== Check type of CHN_FILENAME. if qchnfile then begin if ( (n_elements(chn_filename) ne 1) or $ (datatype(chn_filename[0]) ne 'STR') ) then begin if (not q_qt) then box_message, $ [prognam+': Input CHN_FILENAME must be a scalar string.', $ prognul+' See program header. Aborting...' ] qabort = 1B return, 0 endif endif ;=== Check type of OUTFILE. if qoutfile then begin if ( (n_elements(outfile) ne 1) or $ (datatype(outfile[0]) ne 'STR') ) then begin if (q_qt eq 0) then box_message, $ [prognam+': Output OUTFILE has wrong type. ', $ prognul+' See program header.', $ prognul+' Proceeding, but will not write to OUTFILE...'] qoutfile = 0B endif endif if q_vb then print, prognam+': Checking inputs... OK' ; === Find the channels file. ======================== if q_vb then print, prognam+': Looking for channels file...' ;; If a channel filename was passed in... if qchnfile then begin ;; If a full pathname was passed in... if (strmid(chn_filename,0,1) eq '/') then begin search1 = file_search(chn_filename+'.geny', count=count1) if (count1 eq 1) then begin actual_filename = chn_filename ;; If cannot find the file... endif else begin if (not q_qt) then box_message, $ [prognam+': Cannot find file in input CHN_FILENAME:', $ chn_filename+'.geny', $ prognul+' Check file location. Aborting...' ] qabort = 1B return, 0 endelse ;; Else if a relative pathname was passed in... endif else begin ;; Look first in default channels directory... search2 = file_search(chn_dir + chn_filename+'.geny', count=count2) if (count2 eq 1) then begin actual_filename = chn_dir + chn_filename ;; Look second in pwd. endif else begin search3 = file_search(chn_filename+'.geny', count=count3) if (count3 eq 1) then begin actual_filename = chn_filename ;; Else if cannot find file in either location... endif else begin if (not q_qt) then box_message, $ [prognam+': Cannot find file in input CHN_FILENAME', $ prognul+' in either of these locations:', $ chn_dir + chn_filename+'.geny', $ './' + chn_filename+'.geny', $ prognul+' See program header and check file location.', $ prognul+' Aborting...' ] qabort = 1B return, 0 endelse endelse endelse ;; Else if a channel filename was NOT passed in... endif else begin ;; Look for files in default channels directory... search4 = file_search(chn_dir + chn_pattern, count=count4) ;; If cannot find expected files... if (count4 eq 0) then begin if (not q_qt) then box_message, $ [prognam+': Cannot find any expected files of this type:', $ chn_pattern, $ prognul+' in the expected location:', $ '$SSW_XRT/idl/response/channels/', $ prognul+' See program header and check that your XRT tree', $ prognul+' has this directory and these files, or use the', $ prognul+' CHN_FILENAME input to specify an XRT channel file.', $ prognul+' Aborting...' ] qabort = 1B return, 0 ;; Else if can find expected files, then identify latest version. endif else begin namestart = rstrpos(search4, '/') version_nos = long(strmid(search4,namestart[0]+16,4)) ss_max = where(version_nos eq max(version_nos)) actual_filename = search4[ss_max[0]] endelse endelse if q_vb then begin print, prognam+': Looking for channels file... OK ' print, prognam+': channel file: ' + actual_filename endif ; === Read the channels file ========================= ; === and check the contents. ======================== if q_vb then print, prognam+': Reading the channels file...' restgenx, file=actual_filename, channels, /quiet ;; If CHANNELS isn't a structure... if (datatype(channels[0]) ne 'STC') then begin if (not q_qt) then begin box_message, [prognam+': This channel file does not contain the ' $ +'expected fields:'] print, actual_filename box_message,[prognam+': See program header & check the file contents. ', $ prognul+'The CHN_FILENAME input may be used to specify', $ prognul+' an alternate XRT channel file. Aborting...' ] endif qabort = 1B return, 0 endif ;; If CHANNELS doesn't have the necessary content... ;; Only checking for tagnames. Not worrying whether all ;; the tags and substructures have the right type of ;; content. Can add those checks if it becomes a problem. ;; If the channels structure doesn't have required fields... if not required_tags(channels[0], chn_tagnames) then begin qabort = 1B ;; Else if the channels substructures don't have required fields... endif else begin if ( (not required_tags(channels[0].geom, geo_tagnames)) or $ (not required_tags(channels[0].en_filter, flt_tagnames)) or $ (not required_tags(channels[0].mirror1, mir_tagnames)) or $ (not required_tags(channels[0].mirror2, mir_tagnames)) or $ (not required_tags(channels[0].fp_filter1, flt_tagnames)) or $ (not required_tags(channels[0].fp_filter2, flt_tagnames)) or $ (not required_tags(channels[0].ccd, ccd_tagnames)) $ ) then qabort = 1B endelse ;; If any of the channel tagnames aren't correct, then abort... if qabort then begin if (not q_qt) then begin box_message, [prognam+': This channel file does not contain the ' $ +'expected fields:'] print, actual_filename box_message, [prognam+': See program header and check the file contents.', $ prognul+' The CHN_FILENAME input may be used to specify', $ prognul+' an alternate XRT channel file. Aborting...'] endif return, 0 endif if q_vb then print, prognam+': Reading the channels file... OK' ; === Sort channels. =========================== ;; If a single contamination thickness or time was input, ;; then there will be "Nchannels" effective areas calculated--- ;; one for each XRT channel. The result is a response for ;; every XRT channel with that single contamination thickness. ;; If, instead, a datacube's index of length "Ndata" was input, ;; then the result will match each image's time to a thickness, ;; and the result will be one response matched to each image's channel. ;; These three inputs have already been tested to be mutually exclusive: ;; INDEX, CONTAM_TIME, CONTAM_THICK. if q_vb then print, prognam+': Sorting the channels...' case 1 of qcttime: begin nchn = n_elements(channels) input1 = replicate(contam_time, nchn) end qctthick: begin nchn = n_elements(channels) input1 = rebin(contam_thick, 2, nchn) end qindex: begin nchn = n_elements(index) input1 = index ;; Re-sort CHANNELS to match INDEX array. chn_filts = channels.fp_filter1.name + channels.fp_filter2.name idx_filts = repchar(index.ec_fw1_ + index.ec_fw2_, '_', '-') ss_match = lonarr(nchn) for ii = 0,(nchn-1) do begin ss_match[ii] = (where(chn_filts eq idx_filts[ii]))[0] endfor channels = (temporary(channels))[ss_match] end endcase if q_vb then print, prognam+': Sorting the channels... OK' ; === Get effective areas. =========================== if q_vb then print, prognam+': Getting effective areas...' effar = make_xrt_ea(input1, channels, intype=intype, $ contam=contam, fcontam=fcontam, verbose=verbose, $ quiet=quiet, qabort=qabort, qstop=qstop ) ;; Check whether subroutine succeeded. if qabort then begin if (not q_qt) then box_message, $ [prognam+': The subroutine MAKE_XRT_EA.PRO aborted.', $ prognul+' Aborting...' ] qabort = 1B return, 0 endif if q_vb then print, prognam+': Getting effective areas... OK' ; === Get spectral responses. ======================== if q_vb then print, prognam+': Getting spectral responses...' sprsp = make_xrt_sr(effar, channels, $ verbose=verbose, quiet=quiet, $ qabort=qabort, qstop=qstop ) ;; Check whether subroutine succeeded. if qabort then begin if (not q_qt) then box_message, $ [prognam+': The subroutine MAKE_XRT_SR.PRO aborted.', $ prognul+' Aborting...' ] qabort = 1B return, 0 endif if q_vb then print, prognam+': Getting spectral responses... OK' ; === Finish defining and initializing the ========= ; === structure definitions for the output. ======== if q_vb then print, prognam+': Initializing output substructures...' ;=== Define the {XRT_chn_config_ref} stucture. ccr_str_version = 'XRT_CHN_CONFIG_REF_V0001' ccr_ref = create_struct(name=ccr_str_version, $ 'type', 'XRT_CHN_CONFIG_REF', $ 'ccr_str_version', ccr_str_version, $ 'ccr_str_descr', 'Specifies an XRT instrument ' $ + 'configuration, without the ' $ + 'transmission function.', $ 'name', '', $ 'long_name', '', $ 'observatory', '', $ 'instrument', '', $ 'geom', channels[0].geom, $ 'en_filter', flt_ref, $ 'mirror1', mir_ref, $ 'mirror2', mir_ref, $ 'fp_filter1', flt_ref, $ 'fp_filter2', flt_ref, $ 'ccd', ccd_ref, $ 'config_filename', '', $ 'history', strarr(3), $ 'comments', strarr(5) ) ;=== Define the {XRT_wave_resp} stucture. **** added fcontam tag wrs_str_version = 'XRT_WAVE_RESP_V0002' wrs_ref = create_struct(name=wrs_str_version, $ 'type', 'XRT_WAVE_RESP', $ 'wrs_str_version', wrs_str_version, $ 'wrs_str_descr', 'Provides effective area and spectral ' $ + 'response function for an XRT channel, ' $ + 'for given thicknesses of the CCD ' $ + 'and filter contamination layers.', $ 'name', '', $ 'confg', ccr_ref, $ 'contam', contam[0], $ 'fcontam', fcontam[0], $ 'effar', effar[0], $ 'sprsp', sprsp[0], $ 'history', strarr(3), $ 'comments', strarr(5) ) ;=== Prepare the {XRT_wave_resp} stucture array. wave_resp = replicate(wrs_ref, nchn) wave_resp.name = channels.name confg = wave_resp.confg confg.name = channels.name confg.long_name = channels.long_name confg.observatory = channels.observatory confg.instrument = channels.instrument confg.config_filename = channels.config_filename confg.history = channels.history confg.comments = channels.comments copy_struct, channels.geom, confg, select='geom', /recur_to copy_struct, channels.en_filter, confg, select='en_filter', /recur_to copy_struct, channels.mirror1, confg, select='mirror1', /recur_to copy_struct, channels.mirror2, confg, select='mirror2', /recur_to copy_struct, channels.fp_filter1, confg, select='fp_filter1', /recur_to copy_struct, channels.fp_filter2, confg, select='fp_filter2', /recur_to copy_struct, channels.ccd, confg, select='ccd', /recur_to copy_struct, confg, wave_resp, select='confg', /recur_to copy_struct, contam, wave_resp, select='contam', /recur_to copy_struct, fcontam, wave_resp, select='fcontam', /recur_to copy_struct, effar, wave_resp, select='effar', /recur_to copy_struct, sprsp, wave_resp, select='sprsp', /recur_to if q_vb then print, prognam+': Initializing output substructures... OK' ; === Deal with units ============================ ;; If there was no request to maintain "el..." units, ;; then convert to "DN..." units for the SPEC_RESP. if (qelunits eq 0) then begin if q_vb then print, prognam+': Converting units...' ;; The gain choices for each channel structure... gain_options = [[channels.ccd.gain_r],[channels.ccd.gain_l]] ;; If there's an INDEX, then use that to figure out ;; which gains to use. if qindex then begin ;; Use index.ccd_read to pick an option for each channel structure. ;; This leaves a 1D array of gains. gain_choices = index.ccd_read ;; 0=R, 1=L readout port. ;; Else if there's no INDEX, then just assume default port. endif else begin ;; Just assume default port, which is the Right port. gain_choices = lonarr(nchn) ;; 0=R readout port endelse ;; Make the 1D list of gain values to use. gains = gain_options[lindgen(nchn), gain_choices] ;; Apply gain values to SPEC_RESP. for ii = 0,(nchn-1) do begin wave_resp[ii].sprsp.spec_resp = wave_resp[ii].sprsp.spec_resp $ / gains[ii] endfor ;; Record gain values used. wave_resp.sprsp.gain_used = gains ;; Adjust units strings. wave_resp.sprsp.spec_resp_units = 'DN cm^2 sr ph^-1 pix^-1' if q_vb then print, prognam+': Converting units... OK' endif ; === Finish ===================================== get_utc, utc, /stime hist_string = prognam+' '+progver+': ('+utc+' UTC) Generated {' $ + wave_resp.type+'} structure with name "' $ + wave_resp.name+'".' wave_resp.history[0] = hist_string if qoutfile then begin if q_vb then print, prognam+': Writing OUTFILE...' savegenx, file=outfile, wave_resp if q_vb then print, prognam+': Writing OUTFILE...OK' endif if q_vb then box_message, prognam+': ... Finished.' if qstop then stop return, wave_resp END ;======================================================================