;+ ; NAME: ; smei_frm_track ; PURPOSE: ; Calculates frame baseline (pedestal, dark current, ; average intensity in squares and center group) using ; information from previously processed frames. ; CATEGORY: ; camera/idl/frm ; CALLING SEQUENCE: FUNCTION smei_frm_track, frm, count , $ nfill_control = nfill_control , $ nbad_control = nbad_control , $ ff = ff , $ hdr = hdr , $ img = img , $ reset = reset , $ status = status, $ silent = silent ; INPUTS: ; frm scalar; type: integer ; frame number to be processed ; count scalar; type: integer ; total # frames to be processed ; (used to dimension a several arrays maintained internally ; in common block, and used to clear the common block whe ; frm becomes equal to count (i.e. when all frames have been ; processed). ; OPTIONAL INPUT PARAMETERS: ; /silent suppress run-time information ; (passed to smei_frm_base) ; /reset re-initialize the current camera/mode combination ; nfill_control=nfill_control ; scalar; type: integer; default: (set in smei_frm_base) ; # good frames used to build reference base values ; (passed to smei_frm_base) ; ff=ff ; hdr=hdr ; img=img ; OUTPUTS: ; OPTIONAL OUTPUT PARAMETERS: ; hdr = hdr ; INCLUDE: @compile_opt.pro ; On error, return to caller ; EXTERNAL: ; smei_frm_hdr__define ; CALLS: ; InitVar, IsType, destroyvar, smei_frm_base, smei_frm_read, ArrayLocation ; COMMON BLOCKS: common smei_frm_track_save, ncount, cam_fulls, cam_start, cam_nail, frm_ok, cameras, modes, step ; PROCEDURE: ; MODIFICATION HISTORY: ; MAY-2003, Paul Hick (UCSD/CASS; pphick@ucsd.edu) ;- InitVar, silent, 0 InitVar, reset , /key loc = -1 IF frm EQ -1 THEN BEGIN ; Initialize base tracking smei_frm_base, /init, nfill_control=nfill_control, nbad_control=nbad_control, silent=silent ncount = count ; # frames to be processed cam_fulls = bytarr(3,3) cam_start = replicate(-1L,3,3) cam_nail = replicate(-1L,3,3) frm_ok = bytarr(count) ; Indicates that good base has been calculated cameras = replicate(-1,count) modes = replicate(-1,count) step = 1 frm += step ; Increment frame counter to zero ENDIF ELSE IF frm_ok[frm] THEN BEGIN ; Good base already calculated. Move to next frame. ;loc = frm ;status = '' frm += step ENDIF ELSE BEGIN ; Process frame ; smei_frm_read corrects for head room, if necessary, and corrects ; partially covered column for mode 1 and 2. IF IsType(ff, /defined) THEN BEGIN img = smei_frm_read(ff, hdr=hdr, /silent, error=error) IF error NE '' then destroyvar, img, hdr ENDIF CASE IsType(hdr, /defined) OF 0: BEGIN message, 'should not have happened. Abort !' ;frm += step END 1: BEGIN ; The return value of cam_full reflects the status of the current ; camera/mode combination. ; cam_full = 1: stable reference values for pedestal and dark current ; have been accumulated. ; cam_full = 0: stable reference values have not yet been accumulated, ; or the values have been cleared as a result of an ; explicit /reset or after failing to calculate valid ; pedestals and/or dark current for a large number of ; successive frames. ; Fills hdr.pedestal, hdr.dark_current, hdr.squares, hdr.centerpix smei_frm_base, hdr, img, reset=reset, cam_full=cam_full, $ cam_ok=cam_ok, frm=frm, step=step, status=status, $ silent=silent loc = frm camera = smei_property(hdr,/camera) mode = smei_property(hdr,/mode) info = TimeGet(smei_property(hdr,/time),/_ydoy,upto=TimeUnit(/sec)) info += ' ('+strcompress(frm, /rem)+')' info += ' cam'+strcompress(camera)+' mode'+strcompress(mode)+',' cameras[frm] = camera modes [frm] = mode p = ArrayLocation([camera-1,mode], dim=[3,3], /onedim) p = p[0] IF reset THEN BEGIN ; For control>1 a /reset always results in cam_full=0; for control=1 ; it might result in cam_full=0 too. ; An explicit /reset was issued. Set cam_start to avoid ; processing the preceeding images again, and clear cam_fulls. cam_start[p] = frm cam_fulls[p] = 0 ENDIF ELSE IF cam_start[p] EQ -1 THEN $ cam_start[p] = frm ; Initialize cam_start IF cam_nail[p] NE -1 THEN BEGIN IF frm EQ cam_nail[p] THEN BEGIN message, /info, info+' passing nail' ENDIF ELSE IF frm GT cam_nail[p] THEN BEGIN cam_nail [p] = -1 cam_start[p] = frm ENDIF ENDIF IF NOT cam_full OR cam_fulls[p] THEN BEGIN ; Either cam_full=0 (still accumulating) or cam_fulls[p]=1 ; (continuing a sequence of valid bases). ; If cam_full=1 then cam_fulls[p]=1 is the only way to reach ; this point; if also cam_ok=1 (valid base calculated) then advance ; cam_start[p] to frm. frm_ok[frm] = cam_full AND cam_ok IF frm_ok[frm] THEN cam_start[p] = frm ; If cam_full=1 then always cam_fulls[p]=1, so the next statement ; doesn't change the value of cam_fulls[p]. ; If cam_full=0 then cam_fulls[p] could be 0 or 1. ; If cam_full[p]=0 we are still accumulating base values from ; preceeding frames; in this case the next statement doesn't ; change the value of cam_fulls[p] either. If cam_fulls[p]=1, ; then a sequence of good base values was terminated in ; smei_frm_base because there were too many consecutive ; bad frames. frm += step ENDIF ELSE IF cam_nail[p] NE -1 THEN BEGIN frm += step ENDIF ELSE BEGIN ; cam_full=1 and cam_fulls[p]=0, i.e. finished accumulating base ; values from preceeding good frames. Start new sequence of valid ; bases by setting cam_fulls[p] message, /info, info+' restarted' ; Since we are going to look at earlier frames (back to at most ; cam_start[p]) remember the current frame number. We need this to ; prevent falling into an infinite loop. cam_nail[p] = frm ;frm = cam_start[p] ; Step back to frame cam_start[p] frm = (frm-nbad_control+1) > cam_start[p] ENDELSE cam_fulls[p] = cam_full END ENDCASE ENDELSE IF frm EQ ncount THEN BEGIN destroyvar, ncount, cam_fulls, cam_start, cam_nail, frm_ok, cameras, modes smei_frm_base, /clear ENDIF RETURN, loc & END