FUNCTION DIcal_xtalk, in, fitsHdr, FN=fn, FLAGS=flags ;;----------------------------------------------------------------------------- ;; PURPOSE: ;; Used in the DI Calibration Pipeline. ;; Removes the electrical crosstalk across quadrant boundaries ;; ;; CALLING SEQUENCE: ;; out = DIcal_xtalk, in, fitsHdr ;; ;; REQUIRED INPUTS: ;; in - The image to which this pipeline element is going to be applied ;; fitsHdr - The FITS header for the image ;; ;; OUTPUTS: ;; RETURN - the image after going through this calibration step ;; ;; OPTIONAL INPUT KEYWORDS: ;; FN - Filename of the gains to use. If this keyword is not set, ;; the database is queried. ;; FLAGS - Flags to identify bad sections of data ;; ;; EXAMPLE: ;; IDL> imgOut = DIcal_xtalk(imgIn, fitsHdr) ;; ;; PROCEDURES USED (i.e. called directly!): ;; SXPAR - Read FITS header ;; FXADDPAR - Modifies the FITS header ;; DI_SQLQuery - queries the database ;; getLocFN - Retrieves a local file ;; ;; MODIFICATION HISTORY: ;; 2004-11-15 M. Desnoyer Created ;; ;;----------------------------------------------------------------------------- ;; Do error handling ;CATCH, error error=0 IF error NE 0 THEN BEGIN CATCH, /CANCEL message, 'Remove crosstalk - ' + !ERROR_STATE.MSG, /NONAME ENDIF ;; Include @dical_flags out = double(in) ;; Get the instrument inst = strtrim(SXPAR(fitsHdr, 'INSTRUME', COUNT=c1),2) ;; Get the date the image was taken date = SXPAR(fitsHdr, 'OBSDATE', COUNT=c2) ;; Get the image mode mode = SXPAR(fitsHdr, 'IMGH030', COUNT=c3) ;; Make sure the FITS header contained everything IF (c1 EQ 0) OR (c2 EQ 0) OR (c3 EQ 0) THEN $ message, 'Invalid FITS Header', /NONAME ;; Get the filename of the gains IF NOT keyword_set(fn) THEN BEGIN serv = getSQLserver() db = 'di_calib' tbl = 'XTALK' sel = ['Filepath'] cond = 'Instrument = "'+inst+'" AND Date <= "'+date+$ '" AND Mode = '+strtrim(mode,2)+' order by Date desc, Version desc limit 1' webfn = di_sqlquery(serv, db, tbl, sel, cond, dim=dim) IF min(dim) EQ 0 THEN message, 'No valid crosstalk gains' fn1 = getLocFn(webFn, subdir='XTALK') ENDIF ELSE fn1 = fn ;; Get the gains gains = readFITS(fn1[0], calHdr, /SILENT) ;; Figure out where quadrants are, shifts and rotates dim = size(out, /dimensions); IF inst EQ 'HRIIR' THEN BEGIN qcnt = 2 ;; Find quadrant locations. The first row is the xy-coordinates ;; of the minimum corner. The second row is the coordinates of ;; the maximum corner. qloc = intarr(2,2,qcnt) qloc[*,*,0] = [[0 ,0 ],$ [dim[0]/2-1,dim[1]-1]] qloc[*,*,1] = [[dim[0]/2,0 ],$ [dim[0]-1,dim[1]-1]] rot = [[0,5],$ [5,0]] shft = intarr(2,2) ENDIF ELSE BEGIN ;;VIS qcnt = 4 ;; Find quadrant locations. The first row is the xy-coordinates ;; of the minimum corner. The second row is the coordinates of ;; the maximum corner. qloc = intarr(2,2,qcnt) qloc[*,*,0] = [[0 ,dim[1]/2], $ [dim[0]/2-1,dim[1]-1]] qloc[*,*,1] = [[dim[0]/2 ,dim[1]/2], $ [dim[0]-1 ,dim[1]-1]] qloc[*,*,2] = [[0 ,0 ], $ [dim[0]/2-1,dim[1]/2-1]] qloc[*,*,3] = [[dim[0]/2 ,0 ], $ [dim[0]-1 ,dim[1]/2-1]] rot = [[0,5,7,2],$ [5,0,2,7],$ [7,2,0,5],$ [2,7,5,0]] IF inst NE 'HRIIR' THEN $ shft = [[0 , 1, 1, 1],$ [-1, 0,-1,-1],$ [ 1, 1, 0, 1],$ [-1,-1,-1, 0]] $ ELSE shft = intarr(4,4) ENDELSE ;; Zero all the missing pixels IF n_elements(flags) GT 0 THEN BEGIN missLoc = where((flags AND FLAG_GAP) NE 0,missCnt) IF (missCnt GT 0) THEN out[missLoc] = 0 ENDIF ;; Generate the cross talk image ximg = dblarr(dim[0],dim[1]) FOR i=0,qcnt-1 DO BEGIN ;; Loop through quadrants to build curQuad = dblarr(dim[0]/2,dim[1]*2/qcnt) FOR j=0, qcnt-1 DO BEGIN ;; Loop through quadrants to add ghosts of ;; Extract the quadrant to make image of tmp = out[qloc[0,0,j]:qloc[0,1,j],qloc[1,0,j]:qloc[1,1,j]] ;; Scale the quadrant by the appropriate gain tmp = poly(tmp,gains[j,i,*]) ;; Rotate and shift the quadrant curQuad = curQuad + shift(rotate(tmp, rot[j,i]),shft[j,i]) ENDFOR ximg[qloc[0,0,i]:qloc[0,1,i],qloc[1,0,i]:qloc[1,1,i]] = curQuad ENDFOR ;; Subtract the crosstalk image out = out - ximg ;; Put back original data from missing pixels IF n_elements(flags) GT 0 THEN BEGIN IF (missCnt GT 0) THEN out[missLoc] = in[missLoc] ENDIF ;; Update the FITS header fxaddpar, fitsHdr, 'XTALK', 'T' fxaddpar, fitsHdr, 'XTALKFN', $ strupcase(strmid(fn1[0], strpos(fn1[0], path_sep(), /reverse_search)+1)) RETURN, out END