def _skymatch(imageList, paramDict, in_memory, clean, logfile): # '_skymatch' converts input imageList and other parameters to # data structures accepted by the "skymatch" package. # It also creates a temporary mask by combining 'static' mask, # DQ image, and user-supplied mask. The combined mask is then # passed to 'skymatch' to be used for excluding "bad" pixels. #header keyword that contains the sky that's been subtracted skyKW = "MDRIZSKY" nimg = len(imageList) if nimg == 0: ml.logentry("Skymatch needs at least one images to perform{0}" \ "sky matching. Nothing to be done.",os.linesep) return # create a list of input file names as provided by the user: user_fnames = [] loaded_fnames = [] filemaskinfos = nimg * [None] for img in imageList: user_fnames.append(img._original_file_name) loaded_fnames.append(img._filename) # parse sky mask catalog file (if any): catfile = paramDict['skymask_cat'] if catfile: #extname = imageList[0].scienceExt #assert(extname is not None and extname != '') catfile = catfile.strip() mfindx = parse_at_file(fname=catfile, default_ext=('SCI', '*'), default_mask_ext=0, clobber=False, fnamesOnly=True, doNotOpenDQ=True, match2Images=user_fnames, im_fmode='update', dq_fmode='readonly', msk_fmode='readonly', logfile=MultiFileLog(console=True), verbose=True) for p in mfindx: filemaskinfos[p[1]] = p[0] # step through the list of input images and create # combined (static + DQ + user supplied, if any) mask, and # create a list of FileExtMaskInfo objects to be passed # to 'skymatch' function. # # This needs to be done in several steps, mostly due to the fact that # the mask catalogs use "original" (e.g., GEIS, WAIVER FITS) file names # while ultimately we want to open the version converted to MEF. Second # reason is that we want to combine user supplied masks with DQ+static # masks provided by astrodrizzle. new_fi = [] sky_bits = interpret_bit_flags(paramDict['sky_bits']) for i in range(nimg): # extract extension information: extname = imageList[i].scienceExt extver = imageList[i].group if extver is None: extver = imageList[i].getExtensions() assert (extname is not None and extname != '') assert (extver) # create a new FileExtMaskInfo object fi = FileExtMaskInfo(default_ext=(extname, '*'), default_mask_ext=0, clobber=False, doNotOpenDQ=True, fnamesOnly=False, im_fmode='update', dq_fmode='readonly', msk_fmode='readonly') # set image file and extensions: fi.image = loaded_fnames[i] extlist = [(extname, ev) for ev in extver] fi.append_ext(extlist) # set user masks if any (this will open the files for a later use): fi0 = filemaskinfos[i] if fi0 is not None: nmask = len(fi0.mask_images) for m in range(nmask): mask = fi0.mask_images[m] ext = fi0.maskext[m] fi.append_mask(mask, ext) fi.finalize() # combine user masks with static masks: assert (len(extlist) == fi.count ) #TODO: <-- remove after thorough testing masklist = [] mextlist = [] for k in range(fi.count): if fi.mask_images[k].closed: umask = None else: umask = fi.mask_images[k].hdu[fi.maskext[k]].data (mask, mext) = _buildStaticDQUserMask(imageList[i], extlist[k], sky_bits, paramDict['use_static'], fi.mask_images[k], fi.maskext[k], in_memory) masklist.append(mask) mextlist.append(mext) # replace the original user-supplied masks with the # newly computed combined static+DQ+user masks: fi.clear_masks() for k in range(fi.count): if in_memory and mask is not None: # os.stat() on the "original_fname" of the mask will fail # since this is a "virtual" mask. Therefore we need to compute # mask_stat ourselves. We will simply use id(data) for this: mstat = os.stat_result((0, id(mask.hdu)) + 8 * (0, )) fi.append_mask(masklist[k], mextlist[k], mask_stat=mstat) else: fi.append_mask(masklist[k], mextlist[k]) if masklist[k]: masklist[k].release() fi.finalize() new_fi.append(fi) # Run skymatch algorithm: skymatch(new_fi, skymethod=paramDict['skymethod'], skystat=paramDict['skystat'], lower=paramDict['skylower'], upper=paramDict['skyupper'], nclip=paramDict['skyclip'], lsigma=paramDict['skylsigma'], usigma=paramDict['skyusigma'], binwidth=paramDict['skywidth'], skyuser_kwd=skyKW, units_kwd='BUNIT', readonly=not paramDict['skysub'], dq_bits=None, optimize='inmemory' if in_memory else 'balanced', clobber=True, clean=clean, verbose=True, flog=MultiFileLog(console=True, enableBold=False), _taskname4history='AstroDrizzle') # Populate 'subtractedSky' and 'computedSky' of input image objects: for i in range(nimg): assert (not new_fi[i].fnamesOnly and not new_fi[i].image.closed) image = imageList[i] skysubimage = new_fi[i].image.hdu numchips = image._numchips extname = image.scienceExt assert (os.path.samefile(image._filename, skysubimage.filename())) for extver in range(1, numchips + 1, 1): chip = image[extname, extver] if not chip.group_member: continue subtracted_sky = skysubimage[extname, extver].header.get(skyKW, 0.) chip.subtractedSky = subtracted_sky chip.computedSky = subtracted_sky # clean-up: for fi in new_fi: fi.release_all_images()
def _skymatch(imageList, paramDict, in_memory, clean, logfile): # '_skymatch' converts input imageList and other parameters to # data structures accepted by the "skymatch" package. # It also creates a temporary mask by combining 'static' mask, # DQ image, and user-supplied mask. The combined mask is then # passed to 'skymatch' to be used for excluding "bad" pixels. skyKW="MDRIZSKY" #header keyword that contains the sky that's been subtracted nimg = len(imageList) if nimg == 0: ml.logentry("Skymatch needs at least one images to perform{0}" \ "sky matching. Nothing to be done.",os.linesep) return # create a list of input file names as provided by the user: user_fnames = [] loaded_fnames = [] filemaskinfos = nimg * [ None ] for img in imageList: user_fnames.append(img._original_file_name) loaded_fnames.append(img._filename) # parse sky mask catalog file (if any): catfile = paramDict['skymask_cat'] if catfile: #extname = imageList[0].scienceExt #assert(extname is not None and extname != '') catfile = catfile.strip() mfindx = parse_at_file(fname = catfile, default_ext = ('SCI','*'), default_mask_ext = 0, clobber = False, fnamesOnly = True, doNotOpenDQ = True, match2Images = user_fnames, im_fmode = 'update', dq_fmode = 'readonly', msk_fmode = 'readonly', logfile = MultiFileLog(console=True), verbose = True) for p in mfindx: filemaskinfos[p[1]] = p[0] # step through the list of input images and create # combined (static + DQ + user supplied, if any) mask, and # create a list of FileExtMaskInfo objects to be passed # to 'skymatch' function. # # This needs to be done in several steps, mostly due to the fact that # the mask catalogs use "original" (e.g., GEIS, WAIVER FITS) file names # while ultimately we want to open the version converted to MEF. Second # reason is that we want to combine user supplied masks with DQ+static # masks provided by astrodrizzle. new_fi = [] sky_bits = bitmask.interpret_bits_value(paramDict['sky_bits']) for i in range(nimg): # extract extension information: extname = imageList[i].scienceExt extver = imageList[i].group if extver is None: extver = imageList[i].getExtensions() assert(extname is not None and extname != '') assert(extver) # create a new FileExtMaskInfo object fi = FileExtMaskInfo(default_ext=(extname,'*'), default_mask_ext=0, clobber=False, doNotOpenDQ=True, fnamesOnly=False, im_fmode='update', dq_fmode='readonly', msk_fmode='readonly') # set image file and extensions: fi.image = loaded_fnames[i] extlist = [ (extname,ev) for ev in extver ] fi.append_ext(extlist) # set user masks if any (this will open the files for a later use): fi0 = filemaskinfos[i] if fi0 is not None: nmask = len(fi0.mask_images) for m in range(nmask): mask = fi0.mask_images[m] ext = fi0.maskext[m] fi.append_mask(mask, ext) fi.finalize() # combine user masks with static masks: assert(len(extlist) == fi.count) #TODO: <-- remove after thorough testing masklist = [] mextlist = [] for k in range(fi.count): if fi.mask_images[k].closed: umask = None else: umask = fi.mask_images[k].hdu[fi.maskext[k]].data (mask, mext) = _buildStaticDQUserMask(imageList[i], extlist[k], sky_bits, paramDict['use_static'], fi.mask_images[k], fi.maskext[k], in_memory) masklist.append(mask) mextlist.append(mext) # replace the original user-supplied masks with the # newly computed combined static+DQ+user masks: fi.clear_masks() for k in range(fi.count): if in_memory and mask is not None: # os.stat() on the "original_fname" of the mask will fail # since this is a "virtual" mask. Therefore we need to compute # mask_stat ourselves. We will simply use id(data) for this: mstat = os.stat_result((0,id(mask.hdu)) + 8*(0,)) fi.append_mask(masklist[k], mextlist[k], mask_stat=mstat) else: fi.append_mask(masklist[k], mextlist[k]) if masklist[k]: masklist[k].release() fi.finalize() new_fi.append(fi) # Run skymatch algorithm: skymatch(new_fi, skymethod = paramDict['skymethod'], skystat = paramDict['skystat'], lower = paramDict['skylower'], upper = paramDict['skyupper'], nclip = paramDict['skyclip'], lsigma = paramDict['skylsigma'], usigma = paramDict['skyusigma'], binwidth = paramDict['skywidth'], skyuser_kwd = skyKW, units_kwd = 'BUNIT', readonly = not paramDict['skysub'], dq_bits = None, optimize = 'inmemory' if in_memory else 'balanced', clobber = True, clean = clean, verbose = True, flog = MultiFileLog(console = True, enableBold = False), _taskname4history = 'AstroDrizzle') # Populate 'subtractedSky' and 'computedSky' of input image objects: for i in range(nimg): assert(not new_fi[i].fnamesOnly and not new_fi[i].image.closed) image = imageList[i] skysubimage = new_fi[i].image.hdu numchips = image._numchips extname = image.scienceExt assert(os.path.samefile(image._filename, skysubimage.filename())) for extver in range(1,numchips+1,1): chip = image[extname,extver] if not chip.group_member: continue subtracted_sky = skysubimage[extname,extver].header[skyKW] chip.subtractedSky = subtracted_sky chip.computedSky = subtracted_sky # clean-up: for fi in new_fi: fi.release_all_images()