function iris_get_response,tt, response_file=response_file, $ pre_launch=pre_launch, version=version, full=full, angstrom=angstrom ; ;+ ; Name: iris_get_response ; ; Purpose: return IRIS effective area / response structure ; ; Input Paramters: ; time : time (or time vector) in anytim compatible format ; default: current time, which may not be what you want! ; time is ignored for versions 002 and 001 ; ; Output: ; function returns effective area structure for the given time(s) ; (or vector of structures if times is a vector) ; ; Keyword Parameters: ; response_file - optional user supplied ; - default is latest effective area file ; in $SSW_IRIS distribution ; version : version number of effective area file to be used ; - default: latest version ; /pre_launch : equivalent to version='002' ; Note: /pre_launch overrides version which overrides response_file ; /full : returns the full effective area structure including some ; cryptic coefficients ; /a : lambda units in Angstrom - default: nm ; ; Calling Sequence: ; IDL> iresp=iris_get_response(time) ; ; Notes: ; - Starting with effective area version 003, this routine calculates ; the time dependent effective area using coefficients. ; - The time dependent calibration comes from a combination of throughput ; trending and cross-calibration with SORCE/SOLSTICE ; - Version 003 is very preliminary, the time dependence may not be ; that accurate due to various simplifications and assumptions made ; - Output structure: ; IDL> help,iresp,/str ; DATE_OBS STRING '' ; LAMBDA FLOAT Array[3601] ; AREA_SG FLOAT Array[3601, 2] ; NAME_SG STRING Array[2] ; DN2PHOT_SG FLOAT Array[2] ; AREA_SJI FLOAT Array[3601, 4] ; NAME_SJI STRING Array[4] ; DN2PHOT_SJI FLOAT Array[4] ; COMMENT STRING '' ; VERSION STRING '003' ; VERSION_DATE STRING '20150331' ; ; /full returns additional tags, /pre_launch doesn't have dn2phot tags ; ; - Calls fit_iris_xput ; ; History: ; 13-Feb-2013 - J.P.Wuelser - effective area calibration ; S.L.Freeland - simple $SSW wrapper ala aia_get_response ; 31-Mar-2015 - J.P.Wuelser - time varying effective area ; 2-Mar-2016 - J.P.Wuelser - updated SJI effective area curve ; spline for NUV SG response (was linear) ; 20-Sep-2021 - G.Chintzoglou - updated response with final SOLSTICE obs ; taken on 23-Feb-2020 ; 06-Jan-2023 - G.Chintzoglou - updated NUV response by using ; A1 QS tabulated trending in the 2820-2830A ; range to account for recent drops ; in NUV throughput. This is a ; wavelength-independent ; correction. Zero-slope linear ; extrapolation is used for ; projected times beyond last ; tabulated value. ; 07-Feb-2023 - G.Chintzoglou - Dependency on SOLSTICE (beyond 23-Feb-2020) ; is now removed. ; Now two different sources are implemented. ; NUV SG and SJI response is ; calculated using TSIS data. ; FUV SG and SJI response is ; calculated using data from TIMED/SEE. ; 08-Apr-2023 - G.Chintzoglou - Updated response function with TIMED/SEE ; and TSIS data taken on 31-Mar-2023 ; 06-Nov-2023 - G.Chintzoglou - Due to significant uncertainties in the ; SOLSTICE & TIMED/SEE data, the ; FUV calibration for Si IV ; is updated for the entire IRIS ; mission, by removing ; the wavelength-dependent Aeff ; correction in the Si IV ; window. No other change in the calibration. ; ;- r=-1 prefix='sra' ; default is effective area respdir=get_logenv('$IRIS_RESPONSE') ; default is in $SSW_IRIS distribution ;respdir = './' if respdir eq '' then respdir=concat_dir('$SSW_IRIS','response') ; logic to get older version files if keyword_set(pre_launch) then version='002' if n_elements(version) eq 1 then case fix(version) of 1 : response_file = concat_dir(respdir,'iris_sra_20130211.geny') 2 : response_file = concat_dir(respdir,'iris_sra_20130715.geny') 3 : response_file = concat_dir(respdir,'iris_sra_c_20150331.geny') 4 : response_file = concat_dir(respdir,'iris_sra_c_20161022.geny') 5 : response_file = concat_dir(respdir,'iris_sra_c_20191101.geny') 6 : response_file = concat_dir(respdir,'iris_sra_c_20200223.geny') 7 : response_file = concat_dir(respdir,'iris_sra_c_20230223.geny') 8 : response_file = concat_dir(respdir,'iris_sra_c_20230331.geny') 9 : response_file = concat_dir(respdir,'iris_sra_c_20231106.geny') endcase ;stop if n_elements(response_file) eq 0 then begin response_file=file_search(respdir,'iris_' + prefix+'*') response_file=last_nelem(response_file) ; future versions? endif ;response_file = 'iris_sra_c_20230223.geny' ;response_file = 'iris_sra_c_20230331.geny' ;version = '008' ;stop if file_exist(response_file) then restgenx,file=response_file(0),r $ else begin box_message,'response file > ' + response_file(0) + ' not found...' return,r endelse version=r.version if fix(r.version) le 2 then begin if keyword_set(angstrom) then r.lambda=r.lambda*10. return,r endif ; time dependent effective area ; 1. output structure if n_elements(tt) eq 0 then get_utc,tt ntt = n_elements(tt) if keyword_set(full) then o1=r else begin $ o1 = {date_obs: '', $ lambda: r.lambda, $ area_sg: r.area_sg, $ name_sg: r.name_sg, $ dn2phot_sg: r.dn2phot_sg, $ area_sji: r.area_sji, $ name_sji: r.name_sji, $ dn2phot_sji: r.dn2phot_sji, $ comment: r.comment, $ version: r.version, $ version_date:r.version_date} endelse o1.area_sg = 0.0 o1.area_sji = 0.0 o = replicate(o1,ntt) o.date_obs = anytim(tt,/ccsds) ; 2. FUV SG effective areas ; Rough SG spectral ranges. Setting eff.area to 0 outside of these lamran = [[133.1,135.9],[138.8,140.8]] sz = size(r.coeffs_fuv) ; time dependent response for sz[3]=3 wavelengths rr = fltarr(ntt,sz[3]) for j=0,sz[3]-1 do rr[*,j]=fit_iris_xput(tt,r.c_f_time,r.coeffs_fuv[*,*,j]) ; interpolate onto lambda grid, separately for each of the two FUV CCDs for j=0,1 do begin $ w = where(r.lambda ge lamran[0,j] and r.lambda le lamran[1,j]) &$ for k=0L,ntt-1 do o[k].area_sg[w,0] $ =interpol(reform(rr[k,j:j+1]),r.c_f_lambda[j:j+1],r.lambda[w]) &$ endfor ;Version 009+ only: Remove wavelength dependence for the Si IV part of the FUV window. if float(version) ge 9 then begin lamran0 = [138.8,140.8] w0 = where(r.lambda ge lamran0[0] and r.lambda le lamran0[1]) ; lamran1 = 139.37+[-2,1]*0.01 ; w1 = where(r.lambda ge lamran1[0] and r.lambda le lamran1[1]) ; for k=0L,ntt-1 do o[k].area_sg[w0,0]=replicate(o[k].area_sg[w1[0],0], n_elements(w)) for k=0L,ntt-1 do o[k].area_sg[w0,0]=replicate(mean(o[k].area_sg[w0,0]), n_elements(w)) ;stop endif ; 3. NUV SG effective areas ; Rough SG spectral ranges. Setting eff.area to 0 outside of these lamran = [278.2,283.5] sz = size(r.coeffs_nuv) ; time dependent response for sz[3] wavelengths rr = fltarr(ntt,sz[3]) for j=0,sz[3]-1 do rr[*,j]=fit_iris_xput(tt,r.c_n_time,r.coeffs_nuv[*,*,j]) ;;;;;;; apply wavelength-independent factor to all wavelengths sz[3] if version eq '007' then begin ;determine if input time contains period of A1 QS 2820-2832A trend... ttai=anytim(strmid(tt, 0, 10),/tai) trendtai=anytim(strmid(r.trend_tim, 0 , 10),/tai) ;determine if time-range contains "switch" point... t1= (where(abs(ttai[*]-trendtai[0]) eq 0))[0] ;determine if time-range ;now determine end point of input time with respect to trend series. if t1[0] ne -1 then tt1 = (where(abs(ttai[-1]-trendtai[*]) eq 0))[-1] ;modify last two entries of r.trend to be flat so a zero-slope linear ;extrapolation can occur for after the last date of the tabulated ;values: r.trend[tt1-2]=r.trend[tt1-1] ;wavelength if t1[0] ne -1 then trendy = interpol(reform(r.trend[0:tt1-1]), anytim(r.trend_tim[0:tt1-1],/tai), ttai[t1:*]) ;apply trend now... all wavelengths points... ;stop if t1[0] ne -1 then for j=0,sz[3]-1 do rr[t1:*,j]=reform(rr[t1:*,j])*trendy[*] endif ;version 007 ;stop ; interpolate onto lambda grid w = where(r.lambda ge lamran[0] and r.lambda le lamran[1]) if fix(r.version) le 3 then begin for k=0L,ntt-1 do o[k].area_sg[w,1] $ =interpol(reform(rr[k,*]),r.c_n_lambda,r.lambda[w]) endif else begin for k=0L,ntt-1 do o[k].area_sg[w,1] $ =interpol(reform(rr[k,*]),r.c_n_lambda,r.lambda[w],/spline) endelse ; 4. SJI effective areas if fix(r.version) le 3 then begin sz = size(r.coeffs_sji) for j=0,sz[3]-1 do begin ; calculate pre-launch area from the individual elements pl_a = r.geom_area for k=0,n_elements(r.index_el_sji[*,j])-1 do $ pl_a=pl_a*r.elements[r.index_el_sji[k,j]].trans ; time dependent response rr = fit_iris_xput(tt,r.c_s_time[*,*,j],r.coeffs_sji[*,*,j]) ; time dependent profiles for k=0L,ntt-1 do o[k].area_sji[*,j]=pl_a*rr[k] endfor endif else begin for nuv=0,1 do begin ; calculate baseline SJI area curves asji = r.geom_area for k=0,n_elements(r.index_el_sji[*,nuv*2])-1 do $ asji=asji*r.elements[reform(r.index_el_sji[k,nuv*2:nuv*2+1])].trans ;stop ; apply time dependent profile shape adjustment to FUV SJI if ~nuv then begin ; FUV: apply FUV SG "slant", then normalize so that a weighted (2.4:1) ; sum at C II and Si IV gives constant response wei = [2.4,1.0] ; typical solar ratio CII : SiIV wav = r.c_f_lambda nwv = n_elements(wav) wav = [wav[0],(wav[nwv-2]*2.0+wav[nwv-1])/3.0] ; 2 wvlngts in nm ; calculate baseline SG area for scaling purposes asg = r.geom_area for k=0,n_elements(r.index_el_sg[*,nuv])-1 do $ asg=asg*r.elements[r.index_el_sg[k,nuv]].trans ; SG and SJI areas at wav asg2 = interpol(asg,r.lambda,wav) asj2 = fltarr(2,2) for j=0,1 do asj2[*,j]=interpol(asji[*,j],r.lambda,wav) ; calculate the normalized slant function scal, apply to asji for k=0L,ntt-1 do begin ; best-estimate slant, i.e., eff.area @ wav / baseline SG @ wav sca2 = interpol(o[k].area_sg[*,0],o[k].lambda,wav) / asg2 ; normalize slant so that total(wei*asj2*sca2)/total(wei*asj2)=1 for j=0,1 do begin sca2n = sca2 * total(wei*asj2[*,j])/total(wei*asj2[*,j]*sca2) scaln = interpol(sca2n,wav,r.lambda) > 0.0 o[k].area_sji[*,j] = asji[*,j]*scaln endfor endfor endif else begin ; NUV: essentially same calculation as r.version=3 for k=0L,ntt-1 do o[k].area_sji[*,2:3]=asji endelse endfor for j=0,3 do begin ; SJI specific time dependency rr = fit_iris_xput(tt,r.c_s_time[*,*,j],r.coeffs_sji[*,*,j]) for k=0L,ntt-1 do o[k].area_sji[*,j]=o[k].area_sji[*,j]*rr[k] ;;; Modify 2796 SJI based on 2832 SJI response to account for jumps if version eq '007' and ((j eq 2) or (j eq 3)) then begin ;2796 is j=2 for o.area_sji ;wavelength if t1[0] ne -1 then trendy = interpol(reform(r.trendsji[0:tt1-1]), anytim(r.trend_tim[0:tt1-1],/tai), ttai[t1:*]) ;apply trend now... all wavelength points... ;stop if t1[0] ne -1 then for k=t1,ntt-1 do o[k].area_sji[*,j]=reform(o[k].area_sji[*,j])*replicate(trendy[k-t1], n_elements(r.lambda)) endif ;j eq 1 i.e., 2796 endfor ;k loop endelse if keyword_set(angstrom) then o.lambda=o.lambda*10. ;stop return, o end