;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; DIcal_IrFarnhamFlatAsfCheck.pro ;;; ;;; Check for HRIIR Tony Farnham Master Flat with ASF profile ;;; - see ./Data/IR_Flats/tony_farnham_asf_flat/ ;;; ;;; INPUTS: ;;; FLAT - Flat field input, may be changed by this routine ;;; FITFNARG - Path to FITS file for which FLAT is PDU image data ;;; CALHDR - FITFN PDU Header function DIcal_IrFarnhamFlatAsfCheck, flatArg, fitFnArg, calHdr $ , dataFitHdr=dataFitHdr $ , debug=debugArg noDebug = keyword_set(debugArg) ? 0b : 1b fitFn = strtrim(fitFnArg[0],2) rtn = { success:0b } ;;; Assume this is not a Farnham HRIIR UBFF flat w/ASF profile ;;; Check if keyword PDUNAME exists is set correctly pduName = strtrim(sxpar( calHdr, 'PDUNAME', count=ct),2) if ct ne 1L then return, rtn flatName = pduName ;;; Assume PDUNAME is flat name ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Check for FITS header keyword PDUNAME version ;;; - Use STREGEX comparisons to convert to generic flatType ;;; - Use CASE flatType as there might be later versions and types of this kind of flat ;;; - The regex allows for suffixes after the month digits e.g. day digits flatType = 'UNKNOWN' ;;; Assume PDUNAME version will not be known ;;; pixORquad indicates if input argument flatArg applies to per-pixel ;;; or to per-quad linearization data, or both; assume BOTH by default ;;; Values are 'PIX' or 'QUAD' or 'BOTH' pixORquad = 'BOTH' pduNameBase = pduName ;;; may be needed later ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Simple type, master flat argument applies to both per-pix and per-quad yearMoRegex = '^IR_FARNHAM_MASTER_FLAT_V[2-9][0-9][0-9][0-9][0-1][0-9]' if stregex(pduName,yearMoRegex) eq 0 then begin ;;; If pduName matches regex ^IR_FARNHAM_MASTER_FLAT_Vyyyymm then ;;; flatArg (probably PDU data) is the master flat, the extension with ;;; EXTNAME = 'IR_FARNHAM_ASF_PROFILE_10240' is the 10240-byte ASF ;;; profile, and the extension with EXTNAME = 'DICAL_MAKE_IR_FLAT_Vxyz, ;;; where xyz is the same suffix as that after _V in pduName, is the ;;; code to convert the master flat into a flat specific for this image ;;; using the ASF profile. ;;; N.B. In the original version, V201009, the code has internal ;;; constants which are based on per-quadrant linearization ;;; coefficients. Later versions can work with either ;;; per-quadrant or per-pixel coefficients. The distinction is ;;; passed in as a fifth argument, flat_ver=0 for per-quad and ;;; flat_ver=1 for per_pixel. asfExtName = 'IR_FARNHAM_ASF_PROFILE_10240' vYearmo = strjoin( (strsplit( pduName, '_', /extract))[4:*], '_' ) idlProName = 'DICAL_MAKE_IR_FLAT_' + vYearmo + '.PRO' flatType = 'IR_FARNHAM_MASTER_FLAT_VYEARMMDD' endif ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; PQ type, master flat in argument applies to one or other ;;; For the PQ flats, the per-pixel and per-quadrant master flats are in ;;; separate extensions in the same file. One has _QUAD at the end of ;;; PDUNAME or EXTNAME, and the other has _PIX at the end of PDUNAME or ;;; EXTNAME. yearMoPQRegex = '^IR_FARNHAM_MASTER_FLAT_PQ_V[2-9][0-9][0-9][0-9][0-1][0-9][0-9]*_[PIXQUAD]*$' if stregex(pduName,yearMoPQRegex) eq 0 then begin toks = strsplit( pduName, '_', /extract) pduNameBase = strjoin( toks[0:n_elements(toks)-2],'_' ) ;;; drop _QUAD or _PIX vYearmo = toks[5] pixORquad = toks[6] ;;; = 'PIX' if PDU is per-pixel master flat, else 'QUAD' asfExtName = 'IR_FARNHAM_ASF_PROFILE_10240' idlProName = 'DICAL_MAKE_IR_FLAT_PQ_' + vYearmo + '.PRO' flatType = 'IR_FARNHAM_MASTER_FLAT_VYEARMMDD' endif CASE flatType of 'IR_FARNHAM_MASTER_FLAT_VYEARMMDD': $ begin ;;; - Copy flat argument to local variable, copy back later ubffFlat = flatArg ;;; After this point, any missing components will cause an exit in error opened=0b catcher=0L if noDebug then catch,catcher if catcher ne 0L then begin catch,/cancel msg=!error_state.msg if opened then FITS_CLOSE,fcb,/NO_ABORT message,msg,/NONAME return, 0b endif ;;; - Bench temperature and image mode from data file FITS header optbent = sxpar( dataFitHdr, 'SMOBENT', count=ct) if ct ne 1L or optbent le 0.0 then $ optbent = sxpar( dataFitHdr, 'OPTBENT', count=ct) if ct ne 1L or optbent le 0.0 then $ message,'Could not get bench temperature from FITS header' imgmode = sxpar( dataFitHdr, 'imgmode', count=ct) if ct ne 1L or imgmode lt 1 or imgmode gt 7 then $ message,'Could not get image mode from FITS header' ;;; - Open FITS file for multiple reads FITS_OPEN,fitFn,fcb,/NO_ABORT,MESSAGE=msg if msg ne '' then message,'FITS_OPEN failed on file '+fitFn+'; '+msg opened = 1b ;;; - Get ASF Transmission profile FLOAT[10240] from extension asfExtName FITS_READ,fcb,asfprof_os,asfHdr,EXTNAME=asfExtName,/NO_ABORT,MESSAGE=msg if msg ne '' then $ message,'FITS_READ failed on file '+fitFn+'('+asfExtName+'); '+msg IF n_elements(asfprof_os) NE 10240L THEN $ message, 'Invalid ASF profile (#elements='+strtrim(n_elements(asfprof_os),2)+'!=10240) in file '+fitFn $ , /NONAME ;;; - Compile routine from extension idlProName DIcal_IrProCheck, idlProName, fcb, /is_function, debug=debugArg ;;; Ensure flatArg, assumed from PDU from caller, matches linearization type flatcons = 'OK' ;;; Consistency check ;;; Retrieve the type of linearity correction: per-pixel or per-quadrant linType = sxpar( dataFitHdr, 'LIN_TYPE', count=ct) if ct eq 1 then begin ;;; If a linearization type keyword LIN_TYPE is per-pixel, then set ;;; flat_ver to 1; if LIN_TYPE is per-quadrant, set flat_ver to 0; ;;; otherwise ensure flat_ver does not exist case strupcase(linType) of 'PER-QUADRANT': flat_ver = 0 'PER-PIXEL': flat_ver = 1 else: ptr_free,ptr_new(flat_ver,/no_copy) ;;; delete variable flat_ver endcase ;;; linType endif else begin linType = 'PER-QUADRANT' ;;; assume per-quad if LIN_TYPE not in FITS header endelse ;;; convert per-pixel or per-quadrant to PIX or to QUAD, respectively ;;; start: PER-QUADRANT PER-PIXEL ;;; drop last 2 chars: PER-QUADRA PER-PIX ;;; drop first 4 chars: QUADRA PIX ;;; use first 4 chars: QUAD PIX linType34 = strmid( strmid(linType,0,strlen(linType)-2), 4, 4) ;;; Check that data linearity type matches that of the flat case pixORquad of 'BOTH': ;;; PDU matches both, do nothing else: $ begin if pixORquad ne linType34 then begin ;;; - Try to get correct master flat from extension ;;; pduNameBase + '_PIX' or + '_QUAD' flatName = pduNameBase + '_' + linType34 FITS_READ,fcb,tmpFlat,flatHdr,EXTNAME=flatName,/NO_ABORT,MESSAGE=msg if msg ne '' then $ message,'FITS_READ failed on file '+fitFn+'('+flatName+'); '+msg ubffFlat = temporary( tmpFlat ) ;;; save to local variable endif end endcase ;;; - Close calibration FITS file opened = 0b FITS_CLOSE,fcb,/NO_ABORT ;;; - drop .PRO suffix of idlProName, if present, to get funcname for cal_function lName = strlen(idlProName) sfx4 = strupcase(strmid(idlProName,(lName-4L)>0L)) funcName = strmid( idlProName, 0, lName-(sfx4 eq '.PRO' ? 4 : 0L)) ;;; - Set and pass flat_ver IFF version is not V201209 case vYearMo of 'V201009': $ begin if n_elements(flat_ver) eq 1 then begin if flat_ver ne 0 then begin flatcons = 'ERROR: NON-PER-QUADRANT LINEARIZATION' endif endif newFlat = call_function( funcName,ubffFlat,asfprof_os,optbent,imgmode) end else : $ begin newFlat = call_function( funcName,ubffFlat,asfprof_os,optbent,imgmode,flat_ver) end endcase flatArg = newFlat rtn = create_struct( rtn $ , 'FITS_KEYWORDS' $ , { FASFCORR: 'T' $ , FLATTYPE: flatType $ , FLATNAME: flatName $ , FLAT_PRO: idlProName $ , FLATCONS: flatcons $ , FLATTEMP: optbent $ } ) rtn.success = 1b end else: endcase return, rtn end