def subbackground(image, sig, nbin, order, iter, type):
    """Calculate and subtract a global background from an image
    using a number of different methods.  This is assuming that
    slotmode data is being used.

    return data array
    """

    # return the same image if no background subtraction is required
    if type=='none': return image

    # calculate the image statistics
    if np.size(image)>0:
        mean, median, stddev=saltstat.iterstat(image,sig,iter)
    if stddev==0:
        raise SaltError('Standard deviation = 0')

    # Create a row median image. This will be useful for a number of purposes
    image_mrow=med_row_image(image)

    # Replace bright objects in the frame with the median value of that row
    mask=((image-mean) < sig*stddev)*(image-mean > -sig*stddev)
    image_sig=image*mask+(1-mask)*image_mrow

    if type == 'median-row':
        image_back=image*0.0+image_mrow

    # Median smooth the image
    if type == 'median':
        image_back=median_image(image_sig,nbin)

    # Make a fit to the surface
    if type=='surf':
        image_back=image.copy()

    if type=='both':
        image_surf=image.copy()
        for x in range(len(image[0])):
            y=np.arange(len(image))
            my=((image[:,x]-mean) < sig*stddev)*(image[:,x] -mean > -sig*stddev)
            cy=np.compress(my,y)
            cim=np.compress(my,image_med[:,x])
            coef=np.polyfit(cy,cim,order)
            image_surf[:,x]=np.polyval(coef,y)

    # subtract the fit
    image=image-image_back

    # return the image
    return image
Exemple #2
0
def cleancosmicrays(arr, crtype='fast', thresh=5, mbox=3, bbox=5, bthresh=5, flux_ratio=0.2, gain=1, \
                    rdnoise=5, b_factor=2, fthresh=3, gbin=0, max_iter=1):
    """Clean the cosmic rays from an input array using three different types of methods
   """
    niter = 0
    npix = 1
    onpix = 0

    #makesure the data array is in floating point
    try:
        arr = arr * 1.0
    except:
        message = 'Array cannot be convert to the correct data type'
        raise SaltError(message)

    #measure the mean values for the image--leaving this outside
    #because it doesn't need to be done on each iter loop
    if crtype == 'fast':
        mean, midpt, bsigma = saltstat.iterstat(arr, bthresh, max_iter)

    #set up the array
    crarr = arr * 0.0

    while niter < max_iter and npix > onpix:
        #apply the correct function to idenitfy cosmic rays
        if crtype == 'median':
            crarr += crmedian(arr, thresh, mbox, bbox)
        elif crtype == 'fast':
            crarr += crfast(arr, mean, bsigma, thresh, mbox, flux_ratio)
        elif crtype == 'edge':
            crarr += credge(arr, thresh, gain, rdnoise, b_factor, fthresh)
        else:
            message = 'CRTYPE %s is not a valid value' % crtype
            raise SaltError(message)

        #update the array
        mask = (crarr > 0)
        arr[mask] = crarr[mask]

        #count the number of cosmic rays identified
        onpix = npix
        npix = crarr.sum()
        niter += 1

    #grow the result
    if gbin > 0: crarr = crgrow(crarr, grad=gbin)

    return crarr
Exemple #3
0
def bias(struct,
         subover=True,
         trim=True,
         subbias=False,
         bstruct=None,
         median=False,
         function='polynomial',
         order=3,
         rej_lo=3,
         rej_hi=3,
         niter=10,
         plotover=False,
         log=None,
         verbose=True):
    """Bias subtracts the bias levels from a frame.  It will fit and subtract the overscan
      region, trim the images, and subtract a master bias if required.

      struct--image structure 
      subover--subtract the overscan region
      trim--trim the image
      subbias--subtract master bias
      bstruct--master bias image structure
      median--use the median instead of mean in image statistics
      function--form to fit to the overscan region
      order--order for the function
      rej_lo--sigma  of low points to reject in the fit
      rej_hi--sigma of high points to reject in the fit
      niter--number of iterations
      log--saltio log for recording information
      verbose--whether to print to stdout 
   """
    infile = saltkey.getimagename(struct[0])

    # how many extensions?
    nsciext = saltkey.get('NSCIEXT', struct[0])
    nextend = saltkey.get('NEXTEND', struct[0])
    nccd = saltkey.get('NCCDS', struct[0])

    # how many amplifiers?--this is hard wired
    amplifiers = 2 * nccd

    #log the process
    if subover and log:
        message = '%28s %7s %5s %4s %6s' % \
            ('HDU','Overscan','Order','RMS','Niter')
        log.message(
            '\n     --------------------------------------------------',
            with_header=False,
            with_stdout=verbose)
        log.message(message, with_header=False, with_stdout=verbose)
        log.message('     --------------------------------------------------',
                    with_header=False,
                    with_stdout=verbose)

    if (plotover):
        plt.figure(1)
        plt.axes([0.1, 0.1, 0.8, 0.8])
        plt.xlabel('CCD Column')
        plt.ylabel('Pixel Counts (e-)')
        plt.ion()

    #loop through the extensions and subtract the bias
    for i in range(1, nsciext + 1):
        if struct[i].name == 'SCI':

            #get the bias section
            biassec = saltkey.get('BIASSEC', struct[i])
            y1, y2, x1, x2 = saltio.getSection(biassec, iraf_format=True)
            #get the data section
            datasec = saltkey.get('DATASEC', struct[i])
            dy1, dy2, dx1, dx2 = saltio.getSection(datasec, iraf_format=True)

            #setup the overscan region
            if subover:
                yarr = np.arange(y1, y2, dtype=float)
                data = struct[i].data
                odata = struct[i].data[y1:y2, x1:x2]
                if median:
                    odata = np.median((struct[i].data[y1:y2, x1:x2]), axis=1)
                    olevel = np.median((struct[i].data[y1:y2, x1:x2]))
                    saltkey.new('OVERSCAN', '%f' % (olevel),
                                'Overscan median value', struct[i])
                else:
                    odata = np.mean((struct[i].data[y1:y2, x1:x2]), axis=1)
                    olevel = np.mean((struct[i].data[y1:y2, x1:x2]))
                    saltkey.new('OVERSCAN', '%f' % (olevel),
                                'Overscan mean value', struct[i])

                #fit the overscan region
                ifit=saltfit.interfit(yarr, odata, function=function, \
                                      order=order, thresh=rej_hi, niter=niter)
                try:
                    ifit.interfit()
                    coeffs = ifit.coef
                    ofit = ifit(yarr)
                    omean, omed, osigma = saltstat.iterstat((odata - ofit),
                                                            sig=3,
                                                            niter=5)
                except ValueError:
                    #catch the error if it is a zero array
                    ofit = np.array(yarr) * 0.0
                    osigma = 0.0
                except TypeError:
                    #catch the error if it is a zero array
                    ofit = np.array(yarr) * 0.0
                    osigma = 0.0

                #if it hasn't been already, convert image to
                #double format
                struct[i].data = 1.0 * struct[i].data
                try:
                    struct[i].header.remove('BZERO')
                    struct[i].header.remove('BSCALE')
                except:
                    pass

                #subtract the overscan region
                for j in range(len(struct[i].data[0])):
                    struct[i].data[y1:y2, j] -= ofit

                #report the information
                if log:
                    message = '%25s[%1d] %8.2f %3d %7.2f %3d' % \
                        (infile, i, olevel, order, osigma, niter)
                    log.message(message,
                                with_stdout=verbose,
                                with_header=False)

                #add the statistics to the image header
                saltkey.new('OVERRMS', '%f' % (osigma), 'Overscan RMS value',
                            struct[i])

                #update the variance frame
                if saltkey.found('VAREXT', struct[i]):
                    vhdu = saltkey.get('VAREXT', struct[i])
                    try:
                        vdata = struct[vhdu].data
                        #The bias level should not be included in the noise from the signal
                        for j in range(len(struct[i].data[0])):
                            vdata[y1:y2, j] -= ofit
                        #add a bit to make sure that the minimum error is the rednoise
                        rdnoise = saltkey.get('RDNOISE', struct[i])
                        vdata[vdata < rdnoise**2] = rdnoise**2
                        struct[vhdu].data = vdata + osigma**2

                    except Exception, e:
                        msg = 'Cannot update the variance frame in %s[%i] because %s' % (
                            infile, vhdu, e)
                        raise SaltError(msg)

                #plot the overscan region
                if plotover:
                    plt.plot(yarr, odata)
                    plt.plot(yarr, ofit)

            #trim the data and update the headers
            if trim:
                struct[i].data = struct[i].data[dy1:dy2, dx1:dx2]
                datasec = '[1:' + str(dx2 - dx1) + ',1:' + str(dy2 - dy1) + ']'
                saltkey.put('DATASEC', datasec, struct[i])

                #update the variance frame
                if saltkey.found('VAREXT', struct[i]):
                    vhdu = saltkey.get('VAREXT', struct[i])
                    struct[vhdu].data = struct[vhdu].data[dy1:dy2, dx1:dx2]
                    datasec = '[1:' + str(dx2 - dx1) + ',1:' + str(dy2 -
                                                                   dy1) + ']'
                    saltkey.put('DATASEC', datasec, struct[vhdu])
                #update the BPM frame
                if saltkey.found('BPMEXT', struct[i]):
                    bhdu = saltkey.get('BPMEXT', struct[i])
                    struct[bhdu].data = struct[bhdu].data[dy1:dy2, dx1:dx2]
                    datasec = '[1:' + str(dx2 - dx1) + ',1:' + str(dy2 -
                                                                   dy1) + ']'
                    saltkey.put('DATASEC', datasec, struct[bhdu])

            #subtract the master bias if necessary
            if subbias and bstruct:
                struct[i].data -= bstruct[i].data

                #update the variance frame
                if saltkey.found('VAREXT', struct[i]):
                    vhdu = saltkey.get('VAREXT', struct[i])
                    try:
                        vdata = struct[vhdu].data
                        struct[vhdu].data = vdata + bstruct[vhdu].data
                    except Exception, e:
                        msg = 'Cannot update the variance frame in %s[%i] because %s' % (
                            infile, vhdu, e)
                        raise SaltError(msg)
Exemple #4
0
def saltfpringfind(images,
                   method=None,
                   section=None,
                   thresh=5,
                   minsize=10,
                   niter=5,
                   conv=0.05,
                   displayimage=True,
                   clobber=False,
                   logfile='salt.log',
                   verbose=True):

    with logging(logfile, debug) as log:

        # Check the input images
        infiles = saltio.argunpack('Input', images)

        #check the method
        method = saltio.checkfornone(method)

        # read in the section
        section = saltio.checkfornone(section)
        if section is None:
            pass
        else:
            section = saltio.getSection(section)

        # open each raw image file
        for img in infiles:

            #open the fits file
            struct = saltio.openfits(img)
            data = struct[0].data

            #determine the background value for the image
            if section is None:
                #if section is none, just use all pixels greater than zero
                bdata = data[data > 0]
            else:
                y1, y2, x1, x2 = section
                bdata = data[y1:y2, x1:x2]
            bmean, bmedian, bstd = iterstat(bdata,
                                            sig=thresh,
                                            niter=niter,
                                            verbose=False)
            message="Image Background Statistics\n%30s %6s %8s %8s\n%30s %5.4f %5.4f %5.4f\n" %  \
                  ('Image', 'Mean', 'Median', 'Std',img, bmean, bmedian, bstd)
            log.message(message, with_stdout=verbose)

            mdata = data * (data - bmean > thresh * bstd)

            #prepare the first guess for the image
            ring_list = findrings(data,
                                  thresh=thresh,
                                  niter=niter,
                                  minsize=minsize)

            #if specified, find the center of the ring
            if method is not None:
                for i in range(len(ring_list)):
                    ring_list[i] = findcenter(data,
                                              ring_list[i],
                                              method,
                                              niter=niter,
                                              conv=conv)

        #if one peak: no rings.  If two peaks: one ring, if two peaks: four rings
            if len(ring_list) == 1:
                msg = "One ring dected in image"
            else:
                msg = "%i rings found in image" % len(ring_list)
            log.message(message, with_stdout=verbose)

            if displayimage:
                regfile = img.replace('.fits', '.reg')
                if clobber and os.path.isfile(regfile):
                    fout = saltio.delete(regfile)
                fout = open(regfile, 'w')
                fout.write("""# Region file format: DS9 version 4.1
# Filename:  %s
global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1
physical
""" % img)
                for ring in ring_list:
                    fout.write('circle(%f, %f, %f)\n' %
                               (ring.xc, ring.yc, ring.prad))
                    fout.write('circle(%f, %f, %f)\n' %
                               (ring.xc, ring.yc, ring.prad - 3 * ring.sigma))
                    fout.write('circle(%f, %f, %f)\n' %
                               (ring.xc, ring.yc, ring.prad + 3 * ring.sigma))

                fout.close()
                display(img, catname=regfile, rformat='reg')

            message = 'Ring Parameters\n%30s %6s %6s %6s\n' % ('Image', 'XC',
                                                               'YC', 'Radius')
            log.message(message, with_stdout=verbose)
            for ring in ring_list:
                msg = '%30s %6.2f %6.2f %6.2f\n' % (img, ring.xc, ring.yc,
                                                    ring.prad)
                log.message(msg, with_header=False, with_stdout=verbose)
def saltfpringfit(images,
                  outfile,
                  section=None,
                  bthresh=5,
                  niter=5,
                  displayimage=True,
                  clobber=True,
                  logfile='salt.log',
                  verbose=True):

    with logging(logfile, debug) as log:

        # Check the input images
        infiles = saltio.argunpack('Input', images)

        # read in the section
        if section is None:
            section = saltio.getSection(section)
            msg = 'This mode is not supported yet'
            raise SaltError(msg)
        else:
            section = saltio.getSection(section)
        print section

        # open each raw image file
        for img in infiles:

            #open the fits file
            struct = saltio.openfits(img)
            data = struct[0].data

            #only keep the bright pixels
            y1, y2, x1, x2 = section
            bmean, bmedian, bstd = iterstat(data[y1:y2, x1:x2],
                                            sig=bthresh,
                                            niter=niter,
                                            verbose=False)
            message="Image Background Statistics\n%30s %6s %8s %8s\n%30s %5.4f %5.4f %5.4f\n" %  \
                  ('Image', 'Mean', 'Median', 'Std',img, bmean, bmedian, bstd)
            log.message(message, with_stdout=verbose)

            mdata = data * (data - bmean > bthresh * bstd)

            #prepare the first guess for the image
            ring_list = findrings(data, thresh=5, niter=5, minsize=10)

            if displayimage:
                regfile = img.replace('.fits', '.reg')
                print regfile
                if clobber and os.path.isfile(regfile):
                    fout = saltio.delete(regfile)
                fout = open(regfile, 'w')
                fout.write("""# Region file format: DS9 version 4.1
# Filename:  %s
global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1
physical
""" % img)
                for ring in ring_list:
                    print ring
                    fout.write('circle(%f, %f, %f)\n' %
                               (ring.xc, ring.yc, ring.prad))
                    fout.write('circle(%f, %f, %f)\n' %
                               (ring.xc, ring.yc, ring.prad - 5 * ring.sigma))
                    fout.write('circle(%f, %f, %f)\n' %
                               (ring.xc, ring.yc, ring.prad + 5 * ring.sigma))

                fout.close()
                display(img, catname=regfile, rformat='reg')

        #write out the result for viewing
            struct[0].data = mdata
            saltio.writefits(struct, 'out.fits', clobber=True)

            message = 'Ring Parameters'
            log.message(message)