function xrt_med_dark,index,ddates=ddates,nday=nday,nim=nim,darkff=darkff, $ dfile=dfile,stripdark=stripdark,quiet=quiet ;+ ;NAME: ; xrt_med_dark ;PURPOSE: ; Search full-frame dark images, make one full-frame medianed dark template, ; and then clip an appropriate region for a given FOV. ; ; If such a medianed dark already exists, program checks to see if better ; (closer in time to target data image) dark images exist and uses them ; to make a new medianed dark template. Otherwise it reuses the previous ; medianed dark template. ; ; In the special case of 1x1 images taken after the high-gain antenna ; failure, vertical strip (512x2048) darks are used when available ; and appropriate ; ; Program exits, setting dark=0., if it cannot derive a median dark ; given the restrictions of nim and nday ; ;CALLING: ; dark =xrt_med_dark(index [,ddates=ddates,darkff=darkff,nday=nday, $ ; dfile=dfile,stripdark=stripdark,quiet=quiet]) ; ;INPUT: ; index - index of (a single) image. ; ;OPTIONAL INPUTS: ; ddates=ddates - string array of dates/times of the dark files ; in an anytim() readable format corresponding to previous ; medianed dark below ; darkff=darkff - the previous radiation-free full-frame dark template ; generated by dark files with dates = ddates. ; nday=nday - define a half-period to search dark images. ; (default day=14; <7 is not advised) ; nim=nim - define number of dark images to median ; (default nim=5; odd numbers are best) ; quiet=quiet - run without printing [default - not quiet] ; ;OUTPUT: ; dark - a medianed dark image for the CCD FOV defined by index. ; ;OPTIONAL OUTPUTS: ; ddates - string array of dates/times of the dark files ; darkff - the radiation-free full-frame dark template ; generated for the FOV defined by index using dark ; filenames = dfile and dates = ddates ; dfiles - filename of dark images that were be used. ; stripdark - flag =1 if 1x1 binned "strip darks" ; (512x2048) were used. ; ; EXAMPLES: ; generate a single medianed dark (typically for use in dark subtraction ; or baseline calibration) corresponding to data described by index: ; ; dark =xrt_med_dark(index) ; ; generate a single medianed dark corresponding to data described by ; together with index, median over 7 darks but decrease the search range ; to 10 days, save the full-frame median dark, and dark files used: ; ; dark =xrt_med_dark(index,nday=10,nim=7,darkff=darkff,dfile=dfile ) ; ; when correcting multiple images close in time, it is advisable ; to output the full-frame median dark, and the file dates. Then ; on the subsequent calls of the program, it will check to see if ; it can reuse the last medianed dark (extracting it as needed from the ; full-frame median), which can save significant processing time ; ; dark =xrt_med_dark(index,ddates=ddates,darkff=darkff) ; ; ; If the user does NOT have a local XRT data archive, a new program ; can be used to set proper environment ; variables to permit copying over the network of the dark files ; needed for best dark correction, eg, ; ; IDL> xrt_search_network,/enable ; IDL> dark =xrt_med_dark(index,ddates=ddates,darkff=darkff) ; ; see for more details. ; ; ; NOTE: Output darks have nyquist ringing already removed. If the ; user wishes to recover a "raw" medianed dark (ringing still ; included), they can take the dark generated from xrt_med_dark ; and ; ; IDL> data_nonyq = no_nyquist(data,index) ; IDL> dark_raw = dark + (data - data_nonyq) ; ;HISTORY: ; progver = 'v2009.Jun.12' ; --- (SSaar) Version 1.0 written. Based in part on ; xrt_dark_img.pro by R. Kano progver = 'v2009.Jul.09' ; --- (SSaar) Fixed some minor bugs. progver = 'v2010.May.20' ; --- (SSaar) Fixed bug when files not found by ; xrt_cat; reduced error messages. progver = 'v2010.May.28' ; --- (SSaar) Permit use of 512x2048 "strip darks" ; for more recent 1x1 data. Added more ; explanatory notes. progver = 'v2010.Aug.19' ; --- (PGrigis,SSaar) Improved to allow web access of ; required darks if not available locally. ; Notes added explaining how to ; use web access of darks. progver = 'v2010.Dec.21' ; --- (SSaar) Improved ability to use "strip darks" ; progver = 'v2011.Jul.22 ; --- (SSaar) Further update to array position keywords progver = 'v2012-Apr-16' ;--- (SSaar (SAO)) Fixed problem arising when ; bad images are mislabeled as darks. progver = 'v2013-Feb-28' ;--- (SSaar (SAO)) added quiet mode ; bad images are mislabeled as darks. progver = 'v2013-Jun-25' ;--- (SSaar (SAO)) added check against pathological ; dark files with many hits or bad offsets. ; Added note about nyquist removal. progver = 'v2013-Aug-30' ;--- (McCauley (SAO)) fixed quiet flag. progver = 'v2013-Feb-04' ;--- (SSaar (SAO)) fixed bug in hit removal ; Reference: ; xrt_cat ; To use these, you may have to re-define XRT_DATA to the ; level0 hinode directory ; ; ;- ;t11=systime(1) if n_elements(nday) eq 0 then day=14 else day=nday if n_elements(nim) eq 0 then nim=5 q_qt=keyword_set(quiet) netsearch=0 ; set flag for network searching search_net=getenv('XRT_SEARCH_NETWORK') if search_net eq 'ENABLE' then netsearch=1 ; read nim full dark images around the 1st image. ind=index[0] dur=3600.*24*day st=anytim(anytim(ind.date_obs)-dur,/ECS) en=anytim(anytim(ind.date_obs)+dur,/ECS) bin=ind.chip_sum na=2048/bin flagdf = n_elements(darkff) gt 0 ; flag for existence of full-frame dark flag=1 ; all is well if flag=1 xrt_cat,st,en,dcat,ofil, $ ; look for full-frame darks search=['NAXIS1 = '+strtrim(na,2),'NAXIS2 = '+strtrim(na,2), $ 'EC_IMTYP = 1','CHIP_SUM = '+strtrim(bin,2)],quiet=q_qt case 1 of ; set up maximum sig_avg and limits on median dark (bin eq 1): begin sav_lim=0.3 sig_lim=1.3 end (bin eq 2): begin sav_lim=0.6 sig_lim=1.4 end (bin eq 4): begin sav_lim=2.2 sig_lim=1.8 end else: begin sav_lim=2.9 sig_lim=2.5 end endcase s_per_d = 24.*3600. t_ant = anytim('2008-01-09T00:00:00.0') ; time of hi-gain antenna problems flagstrip=0 ; set "strip dark" flag ncat=n_elements(ofil) if ncat le 4 then begin ; if not enough files found first time flag=0 if bin eq 1 and anytim(st) ge t_ant then begin ; if 1x1 & post-antenna fail xrt_cat,st,en,dcat,ofil, $ ; look for 512x2048 strip darks search=['NAXIS1 = 512','NAXIS2 = 2048', $ 'EC_IMTYP = 1','CHIP_SUM = 1'],quiet=q_qt ncat=n_elements(ofil) if ofil(0) ne '' then begin ; if you find them flagstrip=1 ; set "strip dark" flag flag=1 ; and regular "alls well" flag endif endif endif if flag ne 0 then begin if ncat lt nim then begin ; if not enough darks ( main core of dark ; points -reset these ->global median mdatc=median(datc) ; find global median if nk gt 0 then begin ; if there are counts > base level ilo=where(ik lt imx,nlo) ; find bad points with DNhist_max if nhi ne 0 then begin ; if there are some.... ihi=ik(ihi) xhimx=min(xh(ihi)) ihi2=where(datc ge xhimx,nhi2) if nhi2 ne 0 then datc(ihi2)=mdatc ; set them = current median endif endif if stdev(datc) gt 5*sig_lim or avg(datc) gt 3*sav_lim then begin iok=where(indgen(nd) ne j,nd0) ; test for, identify & darkc=darkc(*,*,iok) ; remove bad darks if nd0 lt 4 then begin ; if < 4 darks remain, use model flag=0. if q_qt eq 0 then $ print,'Too many flawed darks. Defaulting to model dark.' endif nd=nd0 endif else darkc(*,*,j)=datc + modj ; "cleaned" dark (ramp readded) j=j+1 endwhile ;stop ; *** HERE if flag ne 0 then begin darkff=median(darkc,dim=3) ; median the "cleaned" darks ddates=ddates1 ; set ddates to new one endif endif else begin ; if a read error if q_qt eq 0 then print,'Read error. Defaulting to model dark' flag=0. endelse endif else begin ; otherwise, if full-frame dark exists sd=size(darkff) ; check size; if Nx <> Ny... if sd(1) ne sd(2) then flagstrip=1 ; its really a strip dark! set flag endelse endif n1=na ; get Nx & Ny for rebinned full-frame dark n2=na ;stop if flag eq 1 then begin if flagstrip eq 1 then dark1=rebin(darkff,2048,2048) $ ; expand strip dark else dark1=darkff ; otherwise use input full-frame dark ; NOTE: rebin above is a fudge to use partial 1x1 ; darks to sub for full-frame when the latter ; are not present. Not optimal, but it works... dark1=rebin(dark1,n1,n2) ; rebin the median full-frame dark ; make a dark image for the observation from a full frame dark template sx=ind.siz_col/bin ; find FOV size rsiz-> siz x0=ind.pos_col/bin ; find FOV xmin rpos -> pos if x0 gt 2000 then x0=0 x1=x0+sx-1 ; find FOV xmax sy=ind.siz_row/bin ; rsiz-> siz y0=0 ; always begin with dark ramp bottom! y1=y0+sy-1 ; find FOV ymax dark=dark1[x0:x1,y0:y1] ; extract dark for FOV endif else dark=0. stripdark=flagstrip ;print,systime(1)-t11 return, dark end ; ; ;