def cubezap(self, cube=None, skycube=None, mask=None, out=None, cfwidthSP=20, skymask=None, nevals=[], sky=True): if sky == False: zlevel = 'none' cftype = 'median' else: zlevel = 'median' cftype = 'weight' if nevals != []: optimizeType = 'none' else: optimizeType = 'normal' if os.path.isfile('ZAP_SVD.fits'): os.remove('ZAP_SVD.fits') if not out: out = '%s_zap%s' % (self.base, self.ext) if os.path.isfile(out): os.remove(out) if not cube: inc = self.base + self.ext if not mask: mask = self.mask if not skymask: skymask = self.skymask if skycube: svdfn = '%s_svd%s' % (self.base, self.ext) if os.path.isfile(svdfn): os.remove(svdfn) zap.SVDoutput(skycube, svdoutputfits=svdfn, mask=skymask, zlevel=zlevel, cftype=cftype) zap.process( inc, outcubefits=out, extSVD=svdfn, # mask=mask, cfwidthSP=cfwidthSP, nevals=nevals, optimizeType=optimizeType) else: zap.process(inc, outcubefits=out, mask=mask, nevals=nevals, cfwidthSP=cfwidthSP, zlevel=zlevel, optimizeType=optimizeType, cftype=cftype) self.output = out
def internalskysub(listob, skymask, deepwhite=None): """ Perform sky-subtraction using pixels within the cube listob -> OBs to loop on skymask -> if defined to a ds9 region file (iamge coordinate), compute sky in these regions (excluding sources) Otherwise mask sources and use all the pixels in the field. """ import os import glob from astropy.io import fits import numpy as np import zap import matplotlib.pyplot as plt import sep #grab top dir topdir = os.getcwd() #now loop over each folder and make the final illcorrected cubes for ob in listob: #change dir os.chdir(ob + '/Proc/Line/') print('Processing {} for sky subtraction correction'.format(ob)) #Search how many exposures are there scils = glob.glob("../Basic/OBJECT_RED_0*.fits*") nsci = len(scils) #loop on exposures and reduce frame with zeroth order sky subtraction + ZAP for exp in range(nsci): #do pass on IFUs print('Interal sky subtraction of exposure {}'.format(exp + 1)) #define names oldcube = "DATACUBE_FINAL_LINEWCS_EXP{0:d}_ILLCORR_stack.fits".format( exp + 1) oldimage = "IMAGE_FOV_LINEWCS_EXP{0:d}_ILLCORR_stack.fits".format( exp + 1) newcube = "DATACUBE_FINAL_LINEWCS_EXP{0:d}_lineskysub.fits".format( exp + 1) newimage = "IMAGE_FOV_LINEWCS_EXP{0:d}_lineskysub.fits".format( exp + 1) ifumask_iname = "IMAGE_IFUMASK_LINEWCS_EXP{0:d}.fits".format(exp + 1) source_mask = "IMAGE_SOURCEMASK_LINEWCS_EXP{0:d}.fits".format(exp + 1) zapcube = "DATACUBE_FINAL_LINEWCS_EXP{0:d}_zapsky.fits".format( exp + 1) zapimage = "IMAGE_FOV_LINEWCS_EXP{0:d}_zapsky.fits".format(exp + 1) zapsvdout = "ZAPSVDOUT_EXP{0:d}.fits".format(exp + 1) if not os.path.isfile(zapcube): #open the cube cube = fits.open(oldcube) #open mask ifu ifumask = fits.open(ifumask_iname) #if white image provided load it if (deepwhite): print("Use source mask image {}".format(deepwhite)) whsrc = fits.open(topdir + '/' + deepwhite) whitesource = whsrc[0].data.byteswap().newbyteorder() else: #create from cube print("Create source mask image from cube") whitesource = np.nanmedian(cube[1].data, axis=0) #now create a source mask print('Create a source mask') header = cube[1].header bkg = sep.Background(whitesource) bkg_subtraced_data = whitesource - bkg.back() thresh = 3. * bkg.globalrms minarea = 20. clean = True segmap = np.zeros((header["NAXIS2"], header["NAXIS1"])) #extract objects objects, segmap = sep.extract(bkg_subtraced_data, thresh, segmentation_map=True, minarea=minarea, clean=clean) #plt.imshow(segmap,origin='low') #plt.show() #plt.imshow(whitesource,origin='low') #plt.show() #define geometry nwave = cube[1].header["NAXIS3"] nx = cube[1].header["NAXIS1"] ny = cube[1].header["NAXIS2"] #make sure pixels are sky sub once and only once countsub = np.copy(ifumask[1].data) * 0. #if mask is set do a corse median sky subtraction if (skymask): print('Constructing sky mask') #for zap, sky region should be 0, and sources >1 skybox = np.zeros((ny, nx)) + 1 #construct the sky region mask from mypython.fits import pyregmask as pmk mysky = pmk.PyMask(nx, ny, "../../../" + skymask, header=cube[1].header) for ii in range(mysky.nreg): mysky.fillmask(ii) usepix = np.where(mysky.mask > 0) skybox[usepix] = 0 #plt.imshow(skybox,origin='low') #plt.show() #plt.imshow(segmap,origin='low') #plt.show() #plt.imshow(ifumask[1].data,origin='low') #plt.show() #exit() #now do median sky subtraction #loop over wavelength for ww in range(nwave): #extract sky slice skyimg = cube[1].data[ww, :, :] #grab pixels with no source and in mask region #avoid edges not flagged by IFU mask pixels = np.where((skybox < 1) & (segmap < 1) & (ifumask[1].data > 0)) #compute sky in good regions medsky = np.nanmedian(skyimg[pixels]) #subtract from all pixels cube[1].data[ww, :, :] = skyimg - medsky else: #otherwise do coarse sky IFU by IFU #loop over ifu for iff in range(24): thisifu = (iff + 1) * 100. nextifu = (iff + 2) * 100. + 1 #grab pixels in ifu without sources pixels=np.where((ifumask[1].data >= thisifu) & \ (ifumask[1].data < nextifu)\ & (segmap < 1) ) pixels_ifu=np.where((ifumask[1].data >= thisifu) \ & (ifumask[1].data < nextifu)\ & (countsub < 1)) #update used pixels countsub[pixels_ifu] = 1 #loop over wavelength for ww in range(nwave): skyimg = cube[1].data[ww, :, :] #compute sky in good regions medsky = np.nanmedian(skyimg[pixels]) #subtract from all IFU pixels skyimg[pixels_ifu] = skyimg[pixels_ifu] - medsky cube[1].data[ww, :, :] = skyimg #write final cube cube.writeto(newcube, clobber=True) #create white image print('Creating final white image') white_new = np.zeros((ny, nx)) for xx in range(nx): for yy in range(ny): white_new[yy, xx] = np.nansum(cube[1].data[:, yy, xx]) / nwave #save projected image hdu1 = fits.PrimaryHDU([]) hdu2 = fits.ImageHDU(white_new) hdu2.header = cube[1].header hdulist = fits.HDUList([hdu1, hdu2]) hdulist.writeto(newimage, clobber=True) #save segmap #make it redundant to be sure ZAP read right extension hdu1 = fits.PrimaryHDU(segmap) #hdu1.header=header hdu2 = fits.ImageHDU(segmap) #hdu2.header=header hdulist = fits.HDUList([hdu1, hdu2]) hdulist.writeto(source_mask, clobber=True) print('Running ZAP on exposure {}'.format(exp + 1)) #deal with masks if (skymask): #combine sky mask with source mask #make it redundant to be sure ZAP read right extension tmpzapmask = segmap + skybox hdu1 = fits.PrimaryHDU(tmpzapmask) #hdu1.header=header hdu2 = fits.ImageHDU(tmpzapmask) #hdu2.header=header hdulist = fits.HDUList([hdu1, hdu2]) hdulist.writeto("ZAP_" + source_mask, clobber=True) zapmask = "ZAP_" + source_mask else: zapmask = source_mask #clean old if exists try: os.remove(zapsvdout) except: pass #run new - handle change in keywords from v1 to v2 try: zap.process(newcube, outcubefits=zapcube, clean=True, svdoutputfits=zapsvdout, mask=zapmask) except: zap.process(newcube, outcubefits=zapcube, clean=True, mask=zapmask) #create white image from zap cube cube = fits.open(zapcube) print('Creating final white image from ZAP') white_new = np.zeros((ny, nx)) for xx in range(nx): for yy in range(ny): white_new[yy, xx] = np.nansum(cube[1].data[:, yy, xx]) / nwave #save projected image hdu1 = fits.PrimaryHDU([]) hdu2 = fits.ImageHDU(white_new) hdu2.header = cube[1].header hdulist = fits.HDUList([hdu1, hdu2]) hdulist.writeto(zapimage, clobber=True) else: print("ZAP cube exist alread for exposure {}... skip!".format( exp + 1)) #back to top for next OB os.chdir(topdir)
def internalskysub(listob, skymask, deepwhite=None): """ Perform sky-subtraction using pixels within the cube listob -> OBs to loop on skymask -> if defined to a ds9 region file (iamge coordinate), compute sky in these regions (excluding sources) Otherwise mask sources and use all the pixels in the field. """ import os import glob from astropy.io import fits import numpy as np import zap import matplotlib.pyplot as plt import sep # grab top dir topdir = os.getcwd() # now loop over each folder and make the final illcorrected cubes for ob in listob: # change dir os.chdir(ob + "/Proc/") print("Processing {} for sky subtraction correction".format(ob)) # Search how many exposures are there scils = glob.glob("OBJECT_RED_0*.fits*") nsci = len(scils) # loop on exposures and reduce frame with zeroth order sky subtraction + ZAP for exp in range(nsci): # do pass on IFUs print("Interal sky subtraction of exposure {}".format(exp + 1)) # define names oldcube = "DATACUBE_FINAL_LINEWCS_EXP{0:d}_ILLCORR_stack.fits".format(exp + 1) oldimage = "IMAGE_FOV_LINEWCS_EXP{0:d}_ILLCORR_stack.fits".format(exp + 1) newcube = "DATACUBE_FINAL_LINEWCS_EXP{0:d}_lineskysub.fits".format(exp + 1) newimage = "IMAGE_FOV_LINEWCS_EXP{0:d}_lineskysub.fits".format(exp + 1) ifumask_iname = "IMAGE_IFUMASK_LINEWCS_EXP{0:d}.fits".format(exp + 1) source_mask = "IMAGE_SOURCEMASK_LINEWCS_EXP{0:d}.fits".format(exp + 1) zapcube = "DATACUBE_FINAL_LINEWCS_EXP{0:d}_zapsky.fits".format(exp + 1) zapimage = "IMAGE_FOV_LINEWCS_EXP{0:d}_zapsky.fits".format(exp + 1) zapsvdout = "ZAPSVDOUT_EXP{0:d}.fits".format(exp + 1) if not os.path.isfile(zapcube): # open the cube cube = fits.open(oldcube) # open mask ifu ifumask = fits.open(ifumask_iname) # if white image provided load it if deepwhite: print("Use source mask image {}".format(deepwhite)) whsrc = fits.open(topdir + "/" + deepwhite) whitesource = whsrc[0].data.byteswap().newbyteorder() else: # create from cube print("Create source mask image from cube") whitesource = np.nanmedian(cube[1].data, axis=0) # now create a source mask print("Create a source mask") header = cube[1].header bkg = sep.Background(whitesource) bkg_subtraced_data = whitesource - bkg.back() thresh = 3.0 * bkg.globalrms minarea = 20.0 clean = True segmap = np.zeros((header["NAXIS2"], header["NAXIS1"])) # extract objects objects, segmap = sep.extract( bkg_subtraced_data, thresh, segmentation_map=True, minarea=minarea, clean=clean ) # plt.imshow(segmap,origin='low') # plt.show() # plt.imshow(whitesource,origin='low') # plt.show() # define geometry nwave = cube[1].header["NAXIS3"] nx = cube[1].header["NAXIS1"] ny = cube[1].header["NAXIS2"] # make sure pixels are sky sub once and only once countsub = np.copy(ifumask[1].data) * 0.0 # if mask is set do a corse median sky subtraction if skymask: print("Constructing sky mask") # for zap, sky region should be 0, and sources >1 skybox = np.zeros((ny, nx)) + 1 # construct the sky region mask from mypython.fits import pyregmask as pmk mysky = pmk.PyMask(nx, ny, "../../" + skymask, header=cube[1].header) for ii in range(mysky.nreg): mysky.fillmask(ii) usepix = np.where(mysky.mask > 0) skybox[usepix] = 0 # plt.imshow(skybox,origin='low') # plt.show() # plt.imshow(segmap,origin='low') # plt.show() # plt.imshow(ifumask[1].data,origin='low') # plt.show() # exit() # now do median sky subtraction # loop over wavelength for ww in range(nwave): # extract sky slice skyimg = cube[1].data[ww, :, :] # grab pixels with no source and in mask region # avoid edges not flagged by IFU mask pixels = np.where((skybox < 1) & (segmap < 1) & (ifumask[1].data > 0)) # compute sky in good regions medsky = np.nanmedian(skyimg[pixels]) # subtract from all pixels cube[1].data[ww, :, :] = skyimg - medsky else: # otherwise do coarse sky IFU by IFU # loop over ifu for iff in range(24): thisifu = (iff + 1) * 100.0 nextifu = (iff + 2) * 100.0 + 1 # grab pixels in ifu without sources pixels = np.where((ifumask[1].data >= thisifu) & (ifumask[1].data < nextifu) & (segmap < 1)) pixels_ifu = np.where( (ifumask[1].data >= thisifu) & (ifumask[1].data < nextifu) & (countsub < 1) ) # update used pixels countsub[pixels_ifu] = 1 # loop over wavelength for ww in range(nwave): skyimg = cube[1].data[ww, :, :] # compute sky in good regions medsky = np.nanmedian(skyimg[pixels]) # subtract from all IFU pixels skyimg[pixels_ifu] = skyimg[pixels_ifu] - medsky cube[1].data[ww, :, :] = skyimg # write final cube cube.writeto(newcube, clobber=True) # create white image print("Creating final white image") white_new = np.zeros((ny, nx)) for xx in range(nx): for yy in range(ny): white_new[yy, xx] = np.nansum(cube[1].data[:, yy, xx]) / nwave # save projected image hdu1 = fits.PrimaryHDU([]) hdu2 = fits.ImageHDU(white_new) hdu2.header = cube[1].header hdulist = fits.HDUList([hdu1, hdu2]) hdulist.writeto(newimage, clobber=True) # save segmap # make it redundant to be sure ZAP read right extension hdu1 = fits.PrimaryHDU(segmap) # hdu1.header=header hdu2 = fits.ImageHDU(segmap) # hdu2.header=header hdulist = fits.HDUList([hdu1, hdu2]) hdulist.writeto(source_mask, clobber=True) print("Running ZAP on exposure {}".format(exp + 1)) # deal with masks if skymask: # combine sky mask with source mask # make it redundant to be sure ZAP read right extension tmpzapmask = segmap + skybox hdu1 = fits.PrimaryHDU(tmpzapmask) # hdu1.header=header hdu2 = fits.ImageHDU(tmpzapmask) # hdu2.header=header hdulist = fits.HDUList([hdu1, hdu2]) hdulist.writeto("ZAP_" + source_mask, clobber=True) zapmask = "ZAP_" + source_mask else: zapmask = source_mask # clean old if exists try: os.remove(zapsvdout) except: pass # run new zap.process(newcube, outcubefits=zapcube, clean=True, svdoutputfits=zapsvdout, mask=zapmask) # create white image from zap cube cube = fits.open(zapcube) print("Creating final white image from ZAP") white_new = np.zeros((ny, nx)) for xx in range(nx): for yy in range(ny): white_new[yy, xx] = np.nansum(cube[1].data[:, yy, xx]) / nwave # save projected image hdu1 = fits.PrimaryHDU([]) hdu2 = fits.ImageHDU(white_new) hdu2.header = cube[1].header hdulist = fits.HDUList([hdu1, hdu2]) hdulist.writeto(zapimage, clobber=True) else: print("ZAP cube exist alread for exposure {}... skip!".format(exp + 1)) # back to top for next OB os.chdir(topdir)
def zapskysub(listob, extmask=None, extmaskonly=False): """ Loop over each OB and performs zap sky subtraction listob -> OBs to process """ import os import glob import subprocess import shutil from astropy.io import fits import muse_utils as mut import numpy as np import sep import zap from mypython.fits import pyregmask as pmk #grab top dir topdir = os.getcwd() #now loop over each folder and make the final sky-subtracted cubes for ob in listob: #change dir os.chdir(ob + '/Proc/MPDAF') #use source mask already available (should we assume it is always available?) srcmask = 'selfcalib_mask.fits' if (extmask): extfitsmask = 'ext_mask.fits' srchdu = fits.open(srcmask) srcmsk = srchdu[0].data extmsk = np.zeros_like(srcmsk) nx = srchdu[0].header['NAXIS1'] ny = srchdu[0].header['NAXIS2'] #construct the sky region mask mysky = pmk.PyMask(nx, ny, "../../../" + extmask, header=srchdu[0].header) for ii in range(mysky.nreg): mysky.fillmask(ii) extmsk = extmsk + mysky.mask outhdu = fits.PrimaryHDU(extmsk) outhdu.writeto(extfitsmask, overwrite=True) srchdu.close() if (extmask and extmaskonly): namecombmask = 'extsrc_mask.fits' finalmsk = extmsk + srcmsk finalmsk[finalmsk > 0] = 1 outhdu = fits.PrimaryHDU(finalmsk) outhdu.writeto(namecombmask, overwrite=True) finalmask = namecombmask elif (extmask and not extmaskonly): finalmask = extfitsmask else: finalmask = srcmask #now loop over exposures and apply self calibration scils = glob.glob("../Basic/OBJECT_RED_0*.fits*") nsci = len(scils) print("Processing {} with ZAP".format(ob)) #loop on exposures and apply self calibration for exp in range(nsci): #these are the self-calibrated data cubeselfcal = "DATACUBE_RESAMPLED_EXP{0:d}_fix.fits".format(exp + 1) imageselfcal = "IMAGE_RESAMPLED_EXP{0:d}_fix.fits".format(exp + 1) #these are the sky subtracted products cubezap = "DATACUBE_RESAMPLED_EXP{0:d}_zap.fits".format(exp + 1) imagezap = "IMAGE_RESAMPLED_EXP{0:d}_zap.fits".format(exp + 1) if not os.path.isfile(cubezap): print('Reconstruct cube {} with ZAP'.format(cubezap)) #check if first 50 slices are all nan (typically from mixing E and N modes) currcube = fits.open(cubeselfcal) slice50 = currcube[1].data[0:50, :, :] goodpix = np.count_nonzero(np.isfinite(slice50)) if (goodpix < 1): #scan layers to find first with value endslice = 1 while (goodpix < 1): slice50 = currcube[1].data[0:endslice, :, :] goodpix = np.count_nonzero(np.isfinite(slice50)) endslice = endslice + 1 #find start index for good data endslice = endslice - 2 #write tmp trimmed cube hdu1 = fits.PrimaryHDU([], header=currcube[0].header) hdu2 = fits.ImageHDU(currcube[1].data[endslice:, :, :], header=currcube[1].header) hdu3 = fits.ImageHDU(currcube[2].data[endslice:, :, :], header=currcube[2].header) #update wave solution hdu2.header['CRVAL3'] = currcube[1].header[ 'CRVAL3'] + endslice * currcube[1].header['CD3_3'] hdu3.header['CRVAL3'] = currcube[2].header[ 'CRVAL3'] + endslice * currcube[2].header['CD3_3'] #write to new file hdul = fits.HDUList([hdu1, hdu2, hdu3]) hdul.writeto('trimmed_' + cubeselfcal, overwrite=True) currcube.close() #now run zap zap.process('trimmed_' + cubeselfcal, outcubefits='trimmed_' + cubezap, clean=True, mask=finalmask) #make copy of original cube shutil.copy(cubeselfcal, cubezap) #now update longcube = fits.open(cubezap, mode='update') shortcube = fits.open('trimmed_' + cubezap) longcube[1].data[endslice:, :, :] = shortcube[1].data longcube[2].data[endslice:, :, :] = shortcube[2].data longcube.flush() longcube.close() shortcube.close() else: #proceed with current data currcube.close() zap.process(cubeselfcal, outcubefits=cubezap, clean=True, mask=finalmask) #create white image from zap cube cube = fits.open(cubezap) #define geometry nwave = cube[1].header["NAXIS3"] nx = cube[1].header["NAXIS1"] ny = cube[1].header["NAXIS2"] print('Creating final white image from ZAP') white_new = np.zeros((ny, nx)) for xx in range(nx): for yy in range(ny): white_new[yy, xx] = np.nansum(cube[1].data[:, yy, xx]) / nwave #save projected image hdu1 = fits.PrimaryHDU([]) hdu2 = fits.ImageHDU(white_new) hdu2.header = cube[1].header hdulist = fits.HDUList([hdu1, hdu2]) hdulist.writeto(imagezap, overwrite=True) else: print('Cube {} already exists! Skip...'.format(cubezap)) #back to top os.chdir(topdir)
def zapskysub(listob): """ Loop over each OB and performs zap sky subtraction listob -> OBs to process """ import os import glob import subprocess import shutil from astropy.io import fits import muse_utils as mut import numpy as np import sep import zap #grab top dir topdir = os.getcwd() #now loop over each folder and make the final sky-subtracted cubes for ob in listob: #change dir os.chdir(ob + '/Proc/MPDAF') #use source mask already available srcmask = 'selfcalib_mask.fits' #now loop over exposures and apply self calibration scils = glob.glob("../Basic/OBJECT_RED_0*.fits*") nsci = len(scils) print("Processing {} with ZAP".format(ob)) #loop on exposures and apply self calibration for exp in range(nsci): #these are the self-calibrated data cubeselfcal = "DATACUBE_RESAMPLED_EXP{0:d}_fix.fits".format(exp + 1) imageselfcal = "IMAGE_RESAMPLED_EXP{0:d}_fix.fits".format(exp + 1) #these are the sky subtracted products cubezap = "DATACUBE_RESAMPLED_EXP{0:d}_zap.fits".format(exp + 1) imagezap = "IMAGE_RESAMPLED_EXP{0:d}_zap.fits".format(exp + 1) if not os.path.isfile(cubezap): print('Reconstruct cube {} with ZAP'.format(cubezap)) zap.process(cubeselfcal, outcubefits=cubezap, clean=True, mask=srcmask) #create white image from zap cube cube = fits.open(cubezap) #define geometry nwave = cube[1].header["NAXIS3"] nx = cube[1].header["NAXIS1"] ny = cube[1].header["NAXIS2"] print('Creating final white image from ZAP') white_new = np.zeros((ny, nx)) for xx in range(nx): for yy in range(ny): white_new[yy, xx] = np.nansum(cube[1].data[:, yy, xx]) / nwave #save projected image hdu1 = fits.PrimaryHDU([]) hdu2 = fits.ImageHDU(white_new) hdu2.header = cube[1].header hdulist = fits.HDUList([hdu1, hdu2]) hdulist.writeto(imagezap, overwrite=True) else: print('Cube {} already exists! Skip...'.format(cubezap)) #back to top os.chdir(topdir)
def zapskysub(listob, extmask=None, extmaskonly=False): """ Loop over each OB and performs zap sky subtraction listob -> OBs to process """ import os import glob import subprocess import shutil from astropy.io import fits import muse_utils as mut import numpy as np import sep import zap from mypython.fits import pyregmask as pmk #grab top dir topdir = os.getcwd() #now loop over each folder and make the final sky-subtracted cubes for ob in listob: #change dir os.chdir(ob + '/Proc/MPDAF') #use source mask already available (should we assume it is always available?) srcmask = 'selfcalib_mask.fits' if (extmask): extfitsmask = 'ext_mask.fits' srchdu = fits.open(srcmask) srcmsk = srchdu[0].data extmsk = np.zeros_like(srcmsk) nx = srchdu[0].header['NAXIS1'] ny = srchdu[0].header['NAXIS2'] #construct the sky region mask mysky = pmk.PyMask(nx, ny, "../../../" + extmask, header=srchdu[0].header) for ii in range(mysky.nreg): mysky.fillmask(ii) extmsk = extmsk + mysky.mask outhdu = fits.PrimaryHDU(extmsk) outhdu.writeto(extfitsmask, overwrite=True) srchdu.close() if (extmask and extmaskonly): namecombmask = 'extsrc_mask.fits' finalmsk = extmsk + srcmsk finalmsk[finalmsk > 0] = 1 outhdu = fits.PrimaryHDU(finalmsk) outhdu.writeto(namecombmask, overwrite=True) finalmask = namecombmask elif (extmask and not extmaskonly): finalmask = extfitsmask else: finalmask = srcmask #now loop over exposures and apply self calibration scils = glob.glob("../Basic/OBJECT_RED_0*.fits*") nsci = len(scils) print("Processing {} with ZAP".format(ob)) #loop on exposures and apply self calibration for exp in range(nsci): #these are the self-calibrated data cubeselfcal = "DATACUBE_RESAMPLED_EXP{0:d}_fix.fits".format(exp + 1) imageselfcal = "IMAGE_RESAMPLED_EXP{0:d}_fix.fits".format(exp + 1) #these are the sky subtracted products cubezap = "DATACUBE_RESAMPLED_EXP{0:d}_zap.fits".format(exp + 1) imagezap = "IMAGE_RESAMPLED_EXP{0:d}_zap.fits".format(exp + 1) if not os.path.isfile(cubezap): print('Reconstruct cube {} with ZAP'.format(cubezap)) zap.process(cubeselfcal, outcubefits=cubezap, clean=True, mask=finalmask) #create white image from zap cube cube = fits.open(cubezap) #define geometry nwave = cube[1].header["NAXIS3"] nx = cube[1].header["NAXIS1"] ny = cube[1].header["NAXIS2"] print('Creating final white image from ZAP') white_new = np.zeros((ny, nx)) for xx in range(nx): for yy in range(ny): white_new[yy, xx] = np.nansum(cube[1].data[:, yy, xx]) / nwave #save projected image hdu1 = fits.PrimaryHDU([]) hdu2 = fits.ImageHDU(white_new) hdu2.header = cube[1].header hdulist = fits.HDUList([hdu1, hdu2]) hdulist.writeto(imagezap, overwrite=True) else: print('Cube {} already exists! Skip...'.format(cubezap)) #back to top os.chdir(topdir)