FUNCTION DI_fitDarkFunc, inst, dtctr, outFn, ERROR=error, START=start, $ ENDDT=enddt ;;----------------------------------------------------------------------------- ;; PURPOSE: ;; Uses all of the calibration dark frames between time START and ENDDT ;; that exist in the SDC SQL database. The darks must have the same ;; instrument and detector as the one asked for (TODO: What about ;; mode??). Takes these darks and does least squares fitting to the ;; following function for each pixel. ;; ;; For VIS: ;; ;;Dark(I,B) = A0*I + exp(A1 + A2/B) + A3 ;; ;;Dark(I,B) = A0*I*exp(A1*B) + A3 ;; Dark(I,B) = A0*I + exp(A1+A2*B) + A3 ;; ;; For IR: ;; TBD ;; ;; Where: ;; A[0..n-1] - Parameters of fitting model ;; I - Integration time (INTTIME) ;; B - Bench Temperature (IMGH051) ;; ;; Then, the parameters of the fittings are stored in outFn as an IDL ;; variable called "A", which is a [XSize,YSize,n] array with the ;; parameters for the pixels at (x,y) stored at A[x,y,*]. ;; ;; The function fitting is done using the routine MPFITFUN, which was ;; found at http://cow.physics.wisc.edu/~craigm/idl/ ;; ;; CALLING SEQUENCE: ;; flPtr = DI_fitDarkFunc(inst, dtctr[, outFn]) ;; ;; REQUIRED INPUTS: ;; inst - String specifying the instrument to look for (eg. 'HRI') ;; dtctr - Integer specifying the instrument detector (0=VIS, 1=IR) ;; ;; OUTPUTS: ;; RETURN - The filename of the file created. Blank sting if nothing ;; created ;; ERROR - 0 if everything worked, ;; 1 if there was an IO error, ;; 2 if the procedure call was invalid ;; 3 if there was an error calibrating the darks ;; 4 if fitting did not converge ;; 5 if no valid dark frames were found ;; ;; OPTIONAL INPUT KEYWORDS: ;; outFn - String specifying the filename to output the A cube to. If ;; not specified, then the output filename will be: ;; -.par ;; (eg. 030227-030401HRI1.par) ;; START - String (In YYYY-MM-DDTHH:MM format) specifying the starting ;; date of dark frames to use in the fitting. If not specified, ;; then all early dark frames will be used. ;; ENDDT - String (In YYYY-MM-DDTHH:MM format) specifying the ending date ;; of dark frames to use in the fitting. If not specified, then ;; all late dark frames will be used ;; ;; EXAMPLE: ;; IDL> fn = DI_fitDarkFunc( inst, dtctr, START=stDate, ENDDT=endDate) ;; ;; PROCEDURES USED (i.e. called directly!): ;; MPFITFUN - Performs least squares fitting for arbitrary models ;; DI_VISDarkFitModel - Contains the model evaluation needed by MPFITFUN ;; for VIS images ;; DI_IRDarkFitModel - Contains the model evaluation needed by MPFITFUN ;; for IR images ;; DI_sqlQuery - Query's a database for the images to use ;; getLocFn - Gets pointers to the images store locally ;; getSQLServer - Identifies the SQL server to use ;; readFITS - Loads a FITS image ;; DIcal_bitWeight - Calibrate the dark images ;; DIcal_linearDN - Calibrate the dark images ;; ;; MODIFICATION HISTORY: ;; 2004-06-07 M. Desnoyer Created ;; ;;----------------------------------------------------------------------------- fnCreated = '' ERROR = 0 ;; Get the info to connect to the SQL server serv = getSQLServer() db = 'di_testing' ;; Get the table name based on instrument and detector tblNm = inst IF dtctr EQ 0 THEN BEGIN tblNm = STRUPCASE(tblNm) + 'VIS' tempFld = 'CCDT' ENDIF ELSE IF dtctr EQ 1 THEN BEGIN tblNm = STRUPCASE(tblNm) + 'IR' tempFld = 'IRFPAT' ENDIF ELSE GOTO, callErr ;; Determine the condition on data to return ;; TODO: Detmine if mode should always be 1 cond = "(EXPERMNT like 'DRK%') AND (IMGH030 = 1) AND (INTTIME>=0)" IF keyword_set(start) THEN cond = cond + " AND (FNISODAT >= '"+start+"') " IF keyword_set(enddt) THEN cond = cond + " AND (FNISODAT <= '"+enddt+"') " cond = cond + 'order by FNISODAT' ;; Need: ;; Path - FNISODAT - INTTIME - Temperature ;; In addition, IR Needs: ;; TBD sel = ['FILEPATH','FNISODAT','INTTIME',tempFld] IF dtctr EQ 1 THEN sel = [sel] ;; Get the data from the SQL server ON_IOERROR, ioErr info = DI_sqlQuery(serv,db,tblNm,sel,cond,DIM=dim) IF min(dim) EQ 0 THEN GOTO, findErr fn = info[0,*] dates = info[1,*] drkParams = transpose(double(info[2:*,*])) ;; Get the local filenames for all the images fn=getLocFn(fn) IF error NE 0 THEN GOTO, ioErr ;; Figure out the size of the images tmp = readFITS(fn[0],/SILENT) IF size(tmp, /N_DIMENSIONS) EQ 0 THEN GOTO, ioErr drkDim = size(tmp, /DIMENSIONS) ;; Read in all of the images darks = intarr(drkDim[0],drkDim[1],dim[1],/NOZERO) FOR i=0, dim[1]-1 DO BEGIN tmp = readFITS(fn[i],hdr,/SILENT) IF size(tmp, /N_DIMENSIONS) EQ 0 THEN GOTO, ioErr ;; Correct each dark for uneven bit weighting and linearize ;IF DIcal_bitWeight(tmp,hdr,tmp) NE 0 THEN GOTO, calibErr IF dtctr EQ 1 THEN BEGIN ; IF DIcal_linearDN(tmp,hdr,tmp) NE 0 THEN GOTO, calibErr ENDIF ;; Store the corrected dark frame in the uber array darks[*,*,i] = tmp ENDFOR ;; Set up a control for VIS vs IR IF dtctr EQ 0 THEN BEGIN ;;VIS paramCnt = 4 parinfo = replicate({VALUE:0.D,LIMITED:[0,0],LIMITS:[0.D,0.D]} $ ,paramCnt) ;; Starting guesses for parameters ;; Integration time scaling - Bench temp scaling - ;; Bench Temp Exponential Scaling - Bias parinfo[*].value = [1.5d-5,-10.2,0.058,381] ;; Limits on parameters parinfo[0].limited[0] = 1 ;; Evaluation function funcName = 'DI_VISDarkFitModel' ENDIF ELSE BEGIN ;;IR paramCnt = 4 parinfo = replicate({VALUE:0.D,LIMITED:[0,0],LIMITS:[0.D,0.D]} $ ,paramCnt) ;; Starting guesses for parameters parinfo[*].value = [1e-5,16,-1000,500] ;; Limits on parameters ;; Evaluation function ;funcName = 'DI_IRDarkFitModel' funcName = 'DI_VISDarkFitModel' ENDELSE A = dblarr(drkDim[0],drkDim[1],paramCnt,/NOZERO) ;; Determine model parameters for each pixel FOR i=100,drkDim[0]-1 DO BEGIN FOR j=100, drkDim[1]-1 DO BEGIN Y = reform(darks[i,j,*],dim[1]) coefs = MPFITFUN(funcName,drkParams,Y,1.0, PARINFO=parinfo, $ AUTODERIVATIVE=0, BESTNORM=check, status=stat, $ MAXITER=500, yfit=test,/QUIET) IF stat EQ 5 THEN GOTO, convErr A[i,j,*] = coefs ENDFOR ENDFOR ;; Save the model parameters IF n_params() EQ 2 THEN BEGIN ;; Create default output filename stfn = dates[0] stfn = (strsplit(stfn,'T',/EXTRACT))[0] stfn = strsplit(stfn,'-',/EXTRACT) stfn = strmid(stfn[0],2)+stfn[1]+stfn[2] endfn = dates[dim[1]-1] endfn = (strsplit(endfn,'T',/EXTRACT))[0] endfn = strsplit(endfn,'-',/EXTRACT) endfn = strmid(endfn[0],2)+endfn[1]+endfn[2] outFn = stfn+'-'+endfn+strupcase(inst)+strtrim(string(dtctr),2)+'.par' ENDIF SAVE, A, FILENAME=outFn fnCreated = outFn GOTO, ret ioErr: ERROR = 1 GOTO, ret callErr: ERROR = 2 !ERROR_STATE.MSG = 'Invalid procedure call' GOTO, ret calibErr: ERROR = 3 !ERROR_STATE.MSG = 'Dark frames could not be calibrated' GOTO, ret convErr: ERROR = 4 !ERROR_STATE.MSG = 'The curve fitting did not converge for pixel:('+ $ strtrim(string(i),2)+','+ $ strtrim(string(j),2)+')' GOTO, ret findErr: ERROR = 5 !ERROR_STATE.MSG = 'Valid dark frames could not be found' GOTO, ret ;; Cleanup and return ret: files = FINDFILE('Temp/*.fit') IF SIZE(files, /N_DIMENSIONS) GT 0 THEN FILE_DELETE, files, /QUIET RETURN, fnCreated END