def sigma_mask(data,error= None,sigma=3,Verbose= False): if type(error) == type(None): error = np.zeros(len(data)) calcaverage = sigmacut.calcaverageclass() calcaverage.calcaverage_sigmacutloop(data,Nsigma=sigma ,median_firstiteration=True,saveused=True) if Verbose: print("mean:%f (uncertainty:%f)" % (calcaverage.mean,calcaverage.mean_err)) return calcaverage.clipped
def sigmacut_meandev(pixels, mask=None): sigmacut = calcaverageclass() pixels = np.ravel(pixels) initmask = np.isnan(pixels) if mask != None: initmask = np.logical_or(initmask, np.ravel(mask)) sigmacut.calcaverage_sigmacutloop(pixels, mask=initmask, Nsigma=3.0, verbose=0) return sigmacut.mean, sigmacut.stdev
def sigma_clipped_mean(pix): pix = np.ravel(pix) goodpts = ~np.isnan(pix) nanpts = np.isnan(pix) pixclass = sigmacut.calcaverageclass() pixclass.calcaverage_sigmacutloop(pix, Nsigma=3, saveused=True, mask=nanpts) finalmask = np.logical_or(nanpts, pixclass.clipped) pixclass.calcaverage_sigmacutloop(pix, Nsigma=0, mask=finalmask) return pixclass.mean, pixclass.stdev
def make_rdnoise(self): if self.verbose: print('Loading {}'.format(infile)) #Read in input fits file using astropy with fits.open(self.infile) as h: self.data = h[1].data self.hdr = h[1].header self.hdr0 = h[0].header #Keep only the first integration if len(self.data.shape) == 4: print('WARNING: Input data cube has 4 dimensions.') print('Extracting the first integration only and continuing.') self.data = self.data[0, :, :, :] elif len(self.data.shape) < 3: print 'ERROR: data cube has less than 3 dimensions!!! Quitting!' sys.exit(0) #Make sure the data are full frame Ngroups, ny, nx = self.data.shape if (ny, nx) != (2048, 2048): print("WARNING: input data from {} appear not to be full frame!". format(self.infile)) print("x,y dimensions are {}x{}".format(nx, ny)) sys.exit() if self.verbose: print('Number of groups: {}'.format(Ngroups)) #Set step sizes stepsizex = self.stepsizex stepsizey = self.stepsizey if stepsizex is None: stepsizex = self.boxsizex if stepsizey is None: stepsizey = self.boxsizey halfstepsizex = int(0.5 * stepsizex) halfstepsizey = int(0.5 * stepsizey) # get the xy limits. if (self.xmin is None): xmin = 0 else: xmin = self.xmin if (self.xmax is None): xmax = self.data.shape[2] else: xmax = self.xmax if (self.ymin is None): ymin = 0 else: ymin = self.ymin if (self.ymax is None): ymax = self.data.shape[1] else: ymax = self.ymax if self.verbose: print('xmin, xmax, ymin, ymax: {}, {}, {}, {}'.format( xmin, xmax, ymin, ymax)) sigmacut = calcaverageclass() #Create a series of CDS frames diffim = self.data[1:Ngroups, :, :] - self.data[0:Ngroups - 1, :, :] # define output matrices self.im_rdnoise = scipy.zeros((self.data.shape[1], self.data.shape[2]), dtype=float) self.im_rdnoise_err = scipy.zeros(self.im_rdnoise.shape, dtype=float) im_Nused = scipy.zeros(self.im_rdnoise.shape, dtype=int) im_Pskipped = scipy.zeros(self.im_rdnoise.shape, dtype=float) # load mask if self.bpm is not None: print('Loading mask file {}'.format(self.bpm)) with fits.open(self.bpm) as bpmhdu: self.bpmdata = bpmhdu[1].data if self.bpmdata.shape != (2048, 2048): print( "WARNING! Bad pixel mask shape is incorrect or was improperly read!" ) sys.exit() mask = scipy.where( scipy.logical_and(self.bpmdata, self.bpmval) > 0, True, False) # mask the overscan (THIS ASSUMES WE ARE WORKING ON FULL FRAME DATA) mask[0:4, :] = 1 mask[2044:2048, :] = 1 mask[:, 0:4] = 1 mask[:, 2044:2048] = 1 else: mask = scipy.zeros((self.data.shape[1], self.data.shape[2]), dtype=np.uint16) #load epoxy mask if needed detector = self.hdr0['DETECTOR'] if detector in [ 'NRCA1', 'NRCA3', 'NRCA4', 'NRCALONG', 'NRCB1', 'NRCB4' ]: epoxymask = self.load_epoxy_mask(detector) #invert the epoxy mask if requested if self.invert_epoxy: print( "Inverting the epoxy mask to work within the epoxy void region." ) epoxymask = epoxymask - 1 epoxymask[epoxymask == -1] = 1 #add the epoxy mask to the bpm mask = scipy.logical_or(mask, epoxymask) #create an inverted epoxy mask for later when filling in readnoise values #inv_epoxymask = epoxymask.astype(bool) #inv_epoxymask = np.invert(inv_epoxymask) x = xmin + halfstepsizex OneoverSQR2 = 1.0 / math.sqrt(2) xtransitions = [512, 2 * 512, 3 * 512] if self.gmin is None: gmin = 0 else: gmin = self.gmin if self.gmax is None: gmax = diffim.shape[0] else: gmax = self.gmax if gmax > diffim.shape[0]: gmax = diffim.shape[0] #lists of starting and stopping indexes for the filling later xfills = [] xfille = [] yfills = [] yfille = [] grange = range(gmin, gmax) while x < xmax: # define the x1,x2 of the box for stats x1 = x - int(0.5 * self.boxsizex) if x1 < 0: x1 = 0 if self.forcexylimits and (x1 < xmin): x1 = xmin x2 = int(x + max(1, 0.5 * self.boxsizex)) if x2 > self.data.shape[2]: x2 = self.data.shape[2] if self.forcexylimits and (x2 > xmax): x2 = xmax # make sure that the box contains only data from the same amp!!! for xtransition in xtransitions: if x >= xtransition and x1 < xtransition: x1 = xtransition if x < xtransition and x2 >= xtransition: x2 = xtransition #print('!!!x',x,0.5*self.boxsizex,x1,x2) y = ymin + halfstepsizey while y < ymax: # define the y1,y2 of the box for stats y1 = y - int(0.5 * self.boxsizey) if y1 < 0: y1 = 0 if self.forcexylimits and (y1 < ymin): y1 = ymin y2 = int(y + max(1, 0.5 * self.boxsizey)) if y2 > self.data.shape[2]: y2 = self.data.shape[1] if self.forcexylimits and (y2 > ymax): y2 = ymax if self.verbose: if (x % 64) == 0 and (y == 0): print('(x,y)=(%d,%d) box:%d:%d,%d:%d' % (x, y, x1, x2, y1, y2)) stdevs = [] Nused = [] Pskipped = [] for g in grange: sigmacut.calcaverage_sigmacutloop(diffim[g, y1:y2, x1:x2], mask=mask[y1:y2, x1:x2], Nsigma=3.0, verbose=0) if self.verbose: print('x:%d y:%d g:%d' % (x, y, g), sigmacut.__str__()) if sigmacut.converged and sigmacut.Nused > self.Npixmin and 100.0 * sigmacut.Nskipped / ( sigmacut.Nused + sigmacut.Nskipped) < self.Pclipmax: stdevs.append(sigmacut.stdev) Nused.append(sigmacut.Nused) Pskipped.append(100.0 * sigmacut.Nskipped / (sigmacut.Nused + sigmacut.Nskipped)) if len(stdevs) > 1: sigmacut.calcaverage_sigmacutloop(np.array(stdevs), Nsigma=3.0, verbose=0) if sigmacut.converged: self.im_rdnoise[y, x] = sigmacut.mean * OneoverSQR2 self.im_rdnoise_err[ y, x] = sigmacut.mean_err * OneoverSQR2 if self.verbose: print('x:%d y:%d average' % (x, y), sigmacut.__str__()) im_Nused[y, x] = scipy.median(Nused) im_Pskipped[y, x] = scipy.median(Pskipped) elif len(stdevs) == 1: self.im_rdnoise[y, x] = sigmacut.stdev * OneoverSQR2 self.im_rdnoise_err[y, x] = sigmacut.stdev_err * OneoverSQR2 im_Nused[y, x] = 1 im_Pskipped[y, x] = 0.0 if self.fill: xx1 = x - halfstepsizex for xtransition in xtransitions: if x - stepsizex < xtransition and x >= xtransition: xx1 = xtransition if x - stepsizex < 0: xx1 = 0 if xx1 < x1: xx1 = x1 if xx1 < 0: xx1 = 0 xx2 = x + max(1, halfstepsizex) for xtransition in xtransitions: if x + stepsizex >= xtransition and x < xtransition: xx2 = xtransition if x + stepsizex > self.data.shape[2]: xx2 = self.data.shape[2] if xx2 > x2: xx2 = x2 if xx2 > self.data.shape[2]: xx2 = self.data.shape[2] yy1 = y - halfstepsizey if y - stepsizey < 0: yy1 = 0 if yy1 < y1: yy1 = y1 if yy1 < 0: yy1 = 0 yy2 = y + max(1, halfstepsizey) if y + stepsizey > self.data.shape[1]: yy2 = self.data.shape[1] if yy2 > y2: yy2 = y2 if yy2 > self.data.shape[1]: yy2 = self.data.shape[1] #save the x and y coordinates for filling in missing data later xfills.append(xx1) xfille.append(xx2) yfills.append(yy1) yfille.append(yy2) if len(stdevs) > 0: self.im_rdnoise[yy1:yy2, xx1:xx2] = self.im_rdnoise[y, x] self.im_rdnoise_err[yy1:yy2, xx1:xx2] = self.im_rdnoise_err[y, x] im_Nused[yy1:yy2, xx1:xx2] = im_Nused[y, x] im_Pskipped[yy1:yy2, xx1:xx2] = im_Pskipped[y, x] y += stepsizey x += stepsizex #fill in the gaps in the map (i.e. the partial boxes that contain less than the minimum number #of pixels needed for calculating the readnoise for iter in range(self.fill_iterations): #print('BEGINNING FILL ITERATION {}'.format(iter)) self.im_rdnoise = self.fill_empty_regions(self.im_rdnoise, xfills, xfille, yfills, yfille) self.im_rdnoise_err = self.fill_empty_regions( self.im_rdnoise_err, xfills, xfille, yfills, yfille) #mask out the pixels in the low epoxy area if detector in [ 'NRCA1', 'NRCA3', 'NRCA4', 'NRCALONG', 'NRCB1', 'NRCB4' ]: self.im_rdnoise[epoxymask.astype(bool)] = 0. self.im_rdnoise_err[epoxymask.astype(bool)] = 0. #save output file outfilename = self.save_readnoise_file(self.im_rdnoise) #redcat team checks #subprocess.call(['fitsverify',outfilename]) return outfilename, self.im_rdnoise
#--------------------------------------------------------------------- #Next, quantify how well the quadrant-to-quadrant offsets were removed #by looking at the quad-to-quad offsets in the subtracted data with fits.open(origfile) as h: orig = h[1].data with fits.open(refeofile) as h: refeo = h[1].data ints, groups, yd, xd = orig.shape origmeans = np.zeros((ints, groups, 4)) origmeanerrs = np.zeros((ints, groups, 4)) refeomeans = np.zeros((ints, groups, 4)) refeomeanerrs = np.zeros((ints, groups, 4)) qstart = [0, 512, 1024, 1536, 2040] sig = sigmacut.calcaverageclass() for integration in xrange(ints): for group in xrange(groups): for quad in xrange(4): #use sigma-clipped mean sig.calcaverage_sigmacutloop(orig[integration, group, 4:2040, qstart[quad]:qstart[quad + 1]], Nsigma=3.0, verbose=0) origmeans[integration, group, quad] = sig.mean origmeanerrs[integration, group, quad] = sig.mean_err sig.calcaverage_sigmacutloop(refeo[integration, group, 4:2040, qstart[quad]:qstart[quad + 1]], Nsigma=3.0, verbose=0) refeomeans[integration, group, quad] = sig.mean
def run(self): #read in listfile files = [] with open(self.listfile) as f: for line in f: if len(line) > 2: files.append(line.strip()) #read in all of the individual readnoise maps numfiles = len(files) for i, file in enumerate(files): if self.verbose: print("Reading in " + file) map = ReadnoiseModel(file) mapdata = map.data if i == 0: all_maps = np.zeros( (len(files), mapdata.shape[0], mapdata.shape[1])) all_maps[i, :, :] = mapdata print("Individual readnoise maps read in") print("Beginning averaging") #now calculate the sigma-clipped mean readnoise for each pixel #could make this smarter by having it look for boxes....might be #tough in the case of epoxy voids that are irregularly shaped readnoise_map = np.zeros(mapdata.shape) readnoise_err = np.zeros(mapdata.shape) for y in xrange(mapdata.shape[0]): for x in xrange(mapdata.shape[1]): pixdata = all_maps[:, y, x] sigmacut = calcaverageclass() sigmacut.calcaverage_sigmacutloop(pixdata) readnoise_map[y, x] = sigmacut.mean readnoise_err[y, x] = sigmacut.stdev #convert to readnoise for a CDS pair readnoise_map = readnoise_map * np.sqrt(2) #find the gain reference file if needed if self.gainfile == None: self.gainfile = self.find_gainfile(files[0]) print("Using gain file: " + self.gainfile) #save the mean readnoise file in ADU, so we don't need to #repeat the steps above when the gain reference file changes mapadu = map mapadu.data = readnoise_map mapadu = self.header_prep(mapadu, files) #save the readnoise reference file if self.outfile == None: self.outfile = self.listfile + '_MEAN_READNOISE_MAP.fits' dot = self.outfile.rfind('.') adufile = self.outfile[0:dot] + '_ADU_FOR_CDS.fits' #if the specified output file exists, delete it. if os.path.isfile(adufile): os.remove(adufile) print("Saving mean CDS readnoise map in units of ADU as " + adufile) mapadu.save(adufile) print("Converting to electrons") #read in gain file, using SSB's GainModel gainmodel = GainModel(self.gainfile) gain = gainmodel.data #Now convert from ADU to electrons using the gain, and from single-frame to CDS #by multiplying by sqrt(2) readnoise_map = readnoise_map * gain #put the readnoise_map back into the previously-opened ReadnoiseModel instance map.data = readnoise_map #take care of all the details for the reference file header keywords #Since these files have already gone through mkimreadnoise_ssboutput.py, all that should #need to be updated is the HISTORY section, with the names of all the input files. print("Preparing header") map = self.header_prep(map, files) #save the readnoise reference file if self.outfile == None: self.outfile = self.listfile + '_MEAN_READNOISE_MAP_electrons_FOR_CDS.fits' #if the specified output file exists, delete it. if os.path.isfile(self.outfile): os.remove(self.outfile) print("Saving mean CDS readnoise image in electrons as " + self.outfile) map.save(self.outfile)
def mkimrdnoise(self,infile,outfilebasename,pattern='.fits',format='g%03d'): if self.verbose: print 'Loading ',infile #self.data, self.hdr = pyfits.getdata(infile, 0, header=True) #astropy.fits with fits.open(infile) as h: self.data = h[1].data self.hdr = h[1].header self.hdr0 = h[0].header #read in via RampModel #inramp = NRCRampModel() #indata = inramp.loadimage(infile) #self.data = indata.data #self.hdr = ??indata.header #self.hdr0 = ??indata.header if len(self.data.shape)==4: print('WARNING: Input data cube has 4 dimensions.') print('Extracting the first integration only and continuing.') self.data = self.data[0,:,:,:] elif len(self.data.shape) < 3: print 'ERROR: data cube has less than 3 dimensions!!! Quitting!' sys.exit(0) Ngroups = self.data.shape[0] if self.verbose: print 'Ngroups ',Ngroups #outfilebasename=re.sub('\.fits$','',outfilebasename) stepsizex = self.stepsizex stepsizey = self.stepsizey if stepsizex == None: stepsizex = self.boxsizex if stepsizey == None: stepsizey = self.boxsizey halfstepsizex = int(0.5*stepsizex) halfstepsizey = int(0.5*stepsizey) # get the xy limits. if (self.xmin==None): xmin=0 else: xmin=self.xmin if (self.xmax==None): xmax=self.data.shape[2] else: xmax=self.xmax if (self.ymin==None): ymin=0 else: ymin=self.ymin if (self.ymax==None): ymax=self.data.shape[1] else: ymax=self.ymax if self.verbose: print 'xmin, xmax, ymin, ymax:',xmin,xmax,ymin,ymax sigmacut = calcaverageclass() diffim = self.data[1:Ngroups,:,:]- self.data[0:Ngroups-1,:,:] # define output matrices im_rdnoise = scipy.zeros((self.data.shape[1],self.data.shape[2]), dtype=float) im_rdnoise_err = scipy.zeros(im_rdnoise.shape, dtype=float) im_Nused = scipy.zeros(im_rdnoise.shape, dtype=int) im_Pskipped = scipy.zeros(im_rdnoise.shape, dtype=float) # load mask if self.bpm != None: print 'loading ',self.bpm print('BPM read in via astropy for the moment, to avoid MaskModel bug!!!!!') #self.bpmdata = pyfits.getdata(self.bpm, 0).astype('int_') with fits.open(self.bpm) as bpmhdu: self.bpmdata = bpmhdu[1].data #bpminstance = MaskModel(self.bpm) #self.bpmdata = bpminstance.dq if self.bpmdata.shape != (2048,2048): print("WARNING! BPM shape is incorrect or was improperly read!") sys.exit() #print self.bpmdata mask = scipy.where(scipy.logical_and(self.bpmdata,self.bpmval)>0 ,True,False) # mask the overscan mask[0:4,:]=1 mask[2044:2048,:]=1 mask[:,0:4]=1 mask[:,2044:2048]=1 #print mask else: mask = scipy.zeros((self.data.shape[1],self.data.shape[2]),dtype=np.uint16) #load epoxy mask if needed detector = self.hdr0['DETECTOR'] if detector in ['NRCA1','NRCA3','NRCA4','NRCALONG','NRCB1','NRCB4']: epoxymask = self.load_epoxy_mask(detector) #invert the epoxy mask if requested if self.invert_epoxy: print("Inverting the epoxy mask to work within the epoxy void region.") epoxymask = epoxymask - 1 epoxymask[epoxymask == -1] = 1 #add the epoxy mask to the bpm mask = scipy.logical_or(mask,epoxymask) #create an inverted epoxy mask for later when filling in readnoise values inv_epoxymask = epoxymask.astype(bool) inv_epoxymask = np.invert(inv_epoxymask) x=xmin + halfstepsizex OneoverSQR2 = 1.0/math.sqrt(2) xtransitions = [512,2*512,3*512] if self.gmin==None: gmin=0 else: gmin=self.gmin if self.gmax==None: gmax=diffim.shape[0] else: gmax=self.gmax if gmax>diffim.shape[0]: gmax=diffim.shape[0] #lists of starting and stopping indexes for the filling later xfills = [] xfille = [] yfills = [] yfille = [] grange = xrange(gmin,gmax) while x<xmax: # define the x1,x2 of the box for stats x1 = x-int(0.5*self.boxsizex) if x1<0: x1=0 if self.forcexylimits and (x1<xmin): x1=xmin x2 = int(x+max(1,0.5*self.boxsizex)) if x2>self.data.shape[2]: x2=self.data.shape[2] if self.forcexylimits and (x2>xmax): x2=xmax # make sure that the box contains only data from the same amp!!! for xtransition in xtransitions: if x>=xtransition and x1<xtransition:x1=xtransition if x< xtransition and x2>=xtransition:x2=xtransition print '!!!x',x,0.5*self.boxsizex,x1,x2 y=ymin + halfstepsizey while y<ymax: # define the y1,y2 of the box for stats y1 = y-int(0.5*self.boxsizey) if y1<0: y1=0 if self.forcexylimits and (y1<ymin): y1=ymin y2 = int(y+max(1,0.5*self.boxsizey)) if y2>self.data.shape[2]: y2=self.data.shape[1] if self.forcexylimits and (y2>ymax): y2=ymax if (x % 64) == 0 and (y == 0): print '(x,y)=(%d,%d) box:%d:%d,%d:%d' % (x,y,x1,x2,y1,y2) stdevs = [] Nused = [] Pskipped = [] for g in grange: sigmacut.calcaverage_sigmacutloop(diffim[g,y1:y2,x1:x2],mask=mask[y1:y2,x1:x2],Nsigma=3.0,verbose=0) if self.verbose: print 'x:%d y:%d g:%d' % (x,y,g),sigmacut.__str__() if sigmacut.converged and sigmacut.Nused>self.Npixmin and 100.0*sigmacut.Nskipped/(sigmacut.Nused+sigmacut.Nskipped)<self.Pclipmax: stdevs.append(sigmacut.stdev) Nused.append(sigmacut.Nused) Pskipped.append(100.0*sigmacut.Nskipped/(sigmacut.Nused+sigmacut.Nskipped)) #if len(stdevs)>0: if len(stdevs)>1: sigmacut.calcaverage_sigmacutloop(np.array(stdevs),Nsigma=3.0,verbose=0) if sigmacut.converged: im_rdnoise[y,x]=sigmacut.mean*OneoverSQR2 im_rdnoise_err[y,x]=sigmacut.mean_err*OneoverSQR2 if self.verbose: print 'x:%d y:%d average' % (x,y),sigmacut.__str__() im_Nused[y,x]=scipy.median(Nused) im_Pskipped[y,x]=scipy.median(Pskipped) elif len(stdevs) == 1: im_rdnoise[y,x]=sigmacut.stdev*OneoverSQR2 im_rdnoise_err[y,x]=sigmacut.stdev_err*OneoverSQR2 im_Nused[y,x]=1 im_Pskipped[y,x]=0.0 if self.fill: xx1=x-halfstepsizex for xtransition in xtransitions: if x-stepsizex<xtransition and x>=xtransition:xx1=xtransition if x-stepsizex<0:xx1=0 if xx1<x1:xx1=x1 if xx1<0:xx1=0 xx2=x+max(1,halfstepsizex) for xtransition in xtransitions: if x+stepsizex>=xtransition and x<xtransition: xx2=xtransition if x+stepsizex>self.data.shape[2]: xx2=self.data.shape[2] if xx2>x2:xx2=x2 if xx2>self.data.shape[2]: xx2=self.data.shape[2] yy1=y-halfstepsizey if y-stepsizey<0:yy1=0 if yy1<y1:yy1=y1 if yy1<0:yy1=0 yy2=y+max(1,halfstepsizey) if y+stepsizey>self.data.shape[1]: yy2=self.data.shape[1] if yy2>y2:yy2=y2 if yy2>self.data.shape[1]: yy2=self.data.shape[1] #save the x and y coordinates for filling in missing data later xfills.append(xx1) xfille.append(xx2) yfills.append(yy1) yfille.append(yy2) if len(stdevs)>0: #submask = inv_epoxymask[yy1:yy2,xx1:xx2] im_rdnoise[yy1:yy2,xx1:xx2]=im_rdnoise[y,x]#*submask im_rdnoise_err[yy1:yy2,xx1:xx2]=im_rdnoise_err[y,x]#*submask im_Nused[yy1:yy2,xx1:xx2]=im_Nused[y,x] im_Pskipped[yy1:yy2,xx1:xx2]=im_Pskipped[y,x] ##### y+=stepsizey x+=stepsizex #fill in the gaps in the map (i.e. the partial boxes that contain less than the minimum number #of pixels needed for calculating the readnoise #save pre-filled image #h0=fits.PrimaryHDU(im_rdnoise) #hhlist = fits.HDUList([h0]) #tmpfile = 'before_filling_'+infile #if os.path.isfile(tmpfile): # os.rename(tmpfile,'outside_'+tmpfile) #hhlist.writeto(tmpfile) #goo = im_rdnoise > 0 #print(np.min(im_rdnoise[goo]),np.max(im_rdnoise[goo])) #print("BEFORE FILLING EDGES, FILE SAVED TO before_filling*fits") for iter in xrange(self.fill_iterations): print('BEGINNING FILL ITERATION {}'.format(iter)) im_rdnoise = self.fill_empty_regions(im_rdnoise,xfills,xfille,yfills,yfille) im_rdnoise_err = self.fill_empty_regions(im_rdnoise_err,xfills,xfille,yfills,yfille) #print("AFTER FILLING EDGES, FILE SAVED TO after_filling*fits") #h0=fits.PrimaryHDU(im_rdnoise) #hhlist = fits.HDUList([h0]) #tmpfile = 'after_filling_'+infile #if os.path.isfile(tmpfile): # os.rename(tmpfile,'outside_'+tmpfile) #hhlist.writeto(tmpfile) #goo = im_rdnoise > 0 #print(np.min(im_rdnoise[goo]),np.max(im_rdnoise[goo])) #now mask out the pixels in the epoxymask #print("why is this not being done????") #l0=fits.PrimaryHDU(epoxymask) #ll=fits.HDUList([l0]) #ll.writeto('test.fits',clobber=True) if detector in ['NRCA1','NRCA3','NRCA4','NRCALONG','NRCB1','NRCB4']: im_rdnoise[epoxymask.astype(bool)] = 0. im_rdnoise_err[epoxymask.astype(bool)] = 0. #l0=fits.PrimaryHDU(im_rdnoise) #ll=fits.HDUList([l0]) #ll.writeto('test2.fits',clobber=True) #stop #save output file outfilename = self.save_readnoise_file(im_rdnoise,infile,outfilebasename) #fits format checks check_ssb = fits.open(outfilename) print(check_ssb.info()) print(check_ssb['SCI'].data) print(check_ssb['SCI'].data[500,500]) print(im_rdnoise[500,500]) #redcat team checks subprocess.call(['fitsverify',outfilename])