Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
    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
Example #5
0
#---------------------------------------------------------------------
#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])