Ejemplo n.º 1
0
def prepare(struct,createvar=False, badpixelstruct=None, namps=2):

   #set up the file name
   infile=saltkey.getimagename(struct[0])

   #include information about which headers are science extensoisn
   #and check to make sure each array is a data array
   nextend=len(struct)-1
   nsciext=nextend
   for i in range(1,nextend+1):
       try:
           struct[i].header['XTENSION'] == 'IMAGE'
       except:
           msg='Extension %i in %s is not an image data'
           raise  SaltError(msg)
       saltkey.new('EXTNAME','SCI','Extension name',struct[i])
       saltkey.new('EXTVER',i,'Extension number',struct[i])

   #check the number of amplifiers
   #TODO:  This is current hardwired at a value of 2
   nccds = saltkey.get('NCCDS',struct[0])
   if (nextend%(nccds*namps) != 0):
        message = 'ERROR -- SALTPREPARE: Number of file extensions and '
        message += 'number of amplifiers are not consistent in ' + infile
        raise SaltError(message)

   #Add the inv. variance frame if requested--assumes no variance frame
   #and the science frames are in the first n frames
   if createvar:
       #create the inv. variance frames
       for i in range(1, nsciext+1):
           try:
               hdu=CreateVariance(struct[i], i, nextend+i)
           except Exception as e: 
               msg='Cannot create variance frame in extension %i of  %s because %s' % (nextend+i, infile, e)
               raise SaltError(msg) 
           struct[i].header.update('VAREXT',nextend+i, comment='Extension for Variance Frame')
           struct.append(hdu)
       nextend+=nsciext

       #create the badpixelframes
       for i in range(1, nsciext+1):
           try:
               hdu=createbadpixel(struct, badpixelstruct, i, nextend+i)
           except Exception as e: 
               msg='Could not create bad pixel extension in ext %i of %s because %s' % (nextend+i, infile, e)
               raise SaltError(msg) 
           struct[i].header.update('BPMEXT',nextend+i, comment='Extension for Bad Pixel Mask')
           struct.append(hdu)
       nextend+=nsciext


   #update the number of extensions
   saltkey.new('NSCIEXT',nsciext,'Number of science extensions', struct[0])
   saltkey.new('NEXTEND',nextend,'Number of data extensions', struct[0])


   return struct
Ejemplo n.º 2
0
def prepare(struct,createvar=False, badpixelstruct=None, namps=2):

   #set up the file name
   infile=saltkey.getimagename(struct[0])

   #include information about which headers are science extensoisn
   #and check to make sure each array is a data array
   nextend=len(struct)-1
   nsciext=nextend
   for i in range(1,nextend+1):
       try:
           struct[i].header['XTENSION'] == 'IMAGE'
       except:
           msg='Extension %i in %s is not an image data'
           raise  SaltError(msg)
       saltkey.new('EXTNAME','SCI','Extension name',struct[i])
       saltkey.new('EXTVER',i,'Extension number',struct[i])

   #check the number of amplifiers
   #TODO:  This is current hardwired at a value of 2
   nccds = saltkey.get('NCCDS',struct[0])
   if (nextend%(nccds*namps) != 0):
        message = 'ERROR -- SALTPREPARE: Number of file extensions and '
        message += 'number of amplifiers are not consistent in ' + infile
        raise SaltError(message)

   #Add the inv. variance frame if requested--assumes no variance frame
   #and the science frames are in the first n frames
   if createvar:
       #create the inv. variance frames
       for i in range(1, nsciext+1):
           try:
               hdu=CreateVariance(struct[i], i, nextend+i)
           except Exception, e: 
               msg='Cannot create variance frame in extension %i of  %s because %s' % (nextend+i, infile, e)
               raise SaltError(msg) 
           struct[i].header.update('VAREXT',nextend+i, comment='Extension for Variance Frame')
           struct.append(hdu)
       nextend+=nsciext

       #create the badpixelframes
       for i in range(1, nsciext+1):
           try:
               hdu=createbadpixel(struct, badpixelstruct, i, nextend+i)
           except Exception, e: 
               msg='Could not create bad pixel extension in ext %i of %s because %s' % (nextend+i, infile, e)
               raise SaltError(msg) 
           struct[i].header.update('BPMEXT',nextend+i, comment='Extension for Bad Pixel Mask')
           struct.append(hdu)
Ejemplo n.º 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)
Ejemplo n.º 4
0
def make_mosaic(struct, gap, xshift, yshift, rotation, interp_type='linear',
                boundary='constant', constant=0, geotran=True, fill=False,
                cleanup=True, log=None, verbose=False):
    """Given a SALT image struct, combine each of the individual amplifiers and
        apply the geometric CCD transformations to the image
    """

    # get the name of the file
    infile = saltkey.getimagename(struct[0], base=True)
    outpath = './'

    # identify instrument
    instrume, keyprep, keygain, keybias, keyxtalk, keyslot = \
        saltkey.instrumid(struct)

    # how many amplifiers?
    nsciext = saltkey.get('NSCIEXT', struct[0])
    nextend = saltkey.get('NEXTEND', struct[0])
    nccds = saltkey.get('NCCDS', struct[0])
    amplifiers = nccds * 2

    if nextend > nsciext:
        varframe = True
    else:
        varframe = False

    # CCD geometry coefficients
    if (instrume == 'RSS' or instrume == 'PFIS'):
        xsh = [0., xshift[0], 0., xshift[1]]
        ysh = [0., yshift[0], 0., yshift[1]]
        rot = [0., rotation[0], 0., rotation[1]]
    elif instrume == 'SALTICAM':
        xsh = [0., xshift[0], 0.]
        ysh = [0., yshift[0], 0.]
        rot = [0., rotation[0], 0]

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

    # CCD on-chip binning
    xbin, ybin = saltkey.ccdbin(struct[0])

    # create temporary primary extension
    outstruct = []
    outstruct.append(struct[0])
    # define temporary FITS file store tiled CCDs

    tilefile = saltio.tmpfile(outpath)
    tilefile += 'tile.fits'
    if varframe:
        tilehdu = [None] * (3 * int(nsciext / 2) + 1)
    else:
        tilehdu = [None] * int(nsciext / 2 + 1)
    tilehdu[0] = fits.PrimaryHDU()
    #tilehdu[0].header = struct[0].header

    if log:
        log.message('', with_stdout=verbose)

    # iterate over amplifiers, stich them to produce file of CCD images
    for i in range(int(nsciext / 2)):
        hdu = i * 2 + 1
        # amplifier = hdu%amplifiers
        # if (amplifier == 0): amplifier = amplifiers

        # read DATASEC keywords
        datasec1 = saltkey.get('DATASEC', struct[hdu])
        datasec2 = saltkey.get('DATASEC', struct[hdu + 1])
        xdsec1, ydsec1 = saltstring.secsplit(datasec1)
        xdsec2, ydsec2 = saltstring.secsplit(datasec2)

        # read images
        imdata1 = saltio.readimage(struct, hdu)
        imdata2 = saltio.readimage(struct, hdu + 1)

        # tile 2n amplifiers to yield n CCD images
        outdata = numpy.zeros((ydsec1[1] +
                               abs(ysh[i +
                                       1] /
                                   ybin), xdsec1[1] +
                               xdsec2[1] +
                               abs(xsh[i +
                                       1] /
                                   xbin)), numpy.float32)

        # set up the variance frame
        if varframe:
            vardata = outdata.copy()
            vdata1 = saltio.readimage(struct, struct[hdu].header['VAREXT'])
            vdata2 = saltio.readimage(struct, struct[hdu + 1].header['VAREXT'])

            bpmdata = outdata.copy()
            bdata1 = saltio.readimage(struct, struct[hdu].header['BPMEXT'])
            bdata2 = saltio.readimage(struct, struct[hdu + 1].header['BPMEXT'])

        x1 = xdsec1[0] - 1
        if x1 != 0:
            msg = 'The data in %s have not been trimmed prior to mosaicking.' \
                  % infile
            log.error(msg)
        if xsh[i + 1] < 0:
            x1 += abs(xsh[i + 1] / xbin)
        x2 = x1 + xdsec1[1]
        y1 = ydsec1[0] - 1
        if ysh[i + 1] < 0:
            y1 += abs(ysh[i + 1] / ybin)
        y2 = y1 + ydsec1[1]
        outdata[y1:y2, x1:x2] =\
            imdata1[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        if varframe:
            vardata[y1:y2, x1:x2] =\
                vdata1[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]
            bpmdata[y1:y2, x1:x2] =\
                bdata1[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        x1 = x2
        x2 = x1 + xdsec2[1]
        y1 = ydsec2[0] - 1
        if ysh[i + 1] < 0:
            y1 += abs(ysh[i + 1] / ybin)
        y2 = y1 + ydsec2[1]
        outdata[y1:y2, x1:x2] =\
            imdata2[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        if varframe:
            vardata[y1:y2, x1:x2] =\
                vdata2[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]
            bpmdata[y1:y2, x1:x2] =\
                bdata2[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        # size of new image
        naxis1 = str(xdsec1[1] + xdsec2[1])
        naxis2 = str(ydsec1[1])

        # add image and keywords to HDU list
        tilehdu[i + 1] = fits.ImageHDU(outdata)
        tilehdu[i + 1].header = struct[hdu].header
        #tilehdu[
        #    i + 1].header['DATASEC'] = '[1:' + naxis1 + ',1:' + naxis2 + ']'

        if varframe:
            vext = i + 1 + int(nsciext / 2.)
            tilehdu[vext] = fits.ImageHDU(vardata)
            #tilehdu[vext].header = struct[struct[hdu].header['VAREXT']].header
            #tilehdu[vext].header[
            #    'DATASEC'] = '[1:' + naxis1 + ',1:' + naxis2 + ']'

            bext = i + 1 + 2 * int(nsciext / 2.)
            tilehdu[bext] = fits.ImageHDU(bpmdata)
            #tilehdu[bext].header = struct[struct[hdu].header['BPMEXT']].header
            #tilehdu[bext].header[
            #    'DATASEC'] = '[1:' + naxis1 + ',1:' + naxis2 + ']'

        # image tile log message #1
        if log:
            message = os.path.basename(infile) + '[' + str(hdu) + ']['
            message += str(xdsec1[0]) + ':' + str(xdsec1[1]) + ','
            message += str(ydsec1[0]) + ':' + str(ydsec1[1]) + '] --> '
            message += os.path.basename(tilefile) + '[' + str(i + 1) + ']['
            message += str(xdsec1[0]) + ':' + str(xdsec1[1]) + ','
            message += str(ydsec1[0]) + ':' + str(ydsec1[1]) + ']'
            log.message(message, with_stdout=verbose, with_header=False)
            message = os.path.basename(infile) + '[' + str(hdu + 1) + ']['
            message += str(xdsec1[0]) + ':' + str(xdsec1[1]) + ','
            message += str(ydsec1[0]) + ':' + str(ydsec1[1]) + '] --> '
            message += os.path.basename(tilefile) + '[' + str(i + 1) + ']['
            message += str(xdsec1[1] + 1) + ':' + \
                str(xdsec1[1] + xdsec2[1]) + ','
            message += str(ydsec2[0]) + ':' + str(ydsec2[1]) + ']'
            log.message(message, with_stdout=verbose, with_header=False)

    # write temporary file of tiled CCDs
    hdulist = fits.HDUList(tilehdu)
    hdulist.writeto(tilefile)

    # iterate over CCDs, transform and rotate images
    yrot = [None] * 4
    xrot = [None] * 4

    tranfile = [' ']
    tranhdu = [0]
    if varframe:
        tranfile = [''] * (3 * int(nsciext / 2) + 1)
        tranhdu = [0] * (3 * int(nsciext / 2) + 1)
    else:
        tranfile = [''] * int(nsciext / 2 + 1)
        tranhdu = [0] * int(nsciext / 2 + 1)

    # this is hardwired for SALT where the second CCD is considered the
    # fiducial
    for hdu in range(1, int(nsciext / 2 + 1)):
        tranfile[hdu] = saltio.tmpfile(outpath)
        tranfile[hdu] += 'tran.fits'
        if varframe:
            tranfile[hdu + nccds] = saltio.tmpfile(outpath) + 'tran.fits'
            tranfile[hdu + 2 * nccds] = saltio.tmpfile(outpath) + 'tran.fits'

        ccd = hdu % nccds
        if (ccd == 0):
            ccd = nccds

        # correct rotation for CCD binning
        yrot[ccd] = rot[ccd] * ybin / xbin
        xrot[ccd] = rot[ccd] * xbin / ybin
        dxshift = xbin * int(float(int(gap) / xbin) + 0.5) - gap

        # transformation using geotran IRAF task
        # if (ccd == 1):
        if (ccd != 2):

            if geotran:
                message = '\nSALTMOSAIC -- geotran ' + tilefile + \
                    '[' + str(ccd) + '] ' + tranfile[hdu]
                message += ' \"\" \"\" xshift=' + \
                    str((xsh[ccd] + (2 - ccd) * dxshift) / xbin) + ' '
                message += 'yshift=' + \
                    str(ysh[ccd] / ybin) + ' xrotation=' + str(xrot[ccd]) + ' '
                message += 'yrotation=' + \
                    str(yrot[ccd]) + ' xmag=1 ymag=1 xmin=\'INDEF\''
                message += 'xmax=\'INDEF\' ymin=\'INDEF\' ymax=\'INDEF\' '
                message += 'ncols=\'INDEF\' '
                message += 'nlines=\'INDEF\' verbose=\'no\' '
                message += 'fluxconserve=\'yes\' nxblock=2048 '
                message += 'nyblock=2048 interpolant=\'' + \
                    interp_type + '\' boundary=\'constant\' constant=0'
                log.message(message, with_stdout=verbose)

                yd, xd = tilehdu[ccd].data.shape
                ncols = 'INDEF'  # ncols=xd+abs(xsh[ccd]/xbin)
                nlines = 'INDEF'  # nlines=yd+abs(ysh[ccd]/ybin)
                geo_xshift = xsh[ccd] + (2 - ccd) * dxshift / xbin
                geo_yshift = ysh[ccd] / ybin
                iraf.images.immatch.geotran(tilefile + "[" + str(ccd) + "]",
                                            tranfile[hdu],
                                            "",
                                            "",
                                            xshift=geo_xshift,
                                            yshift=geo_yshift,
                                            xrotation=xrot[ccd],
                                            yrotation=yrot[ccd],
                                            xmag=1, ymag=1, xmin='INDEF',
                                            xmax='INDEF', ymin='INDEF',
                                            ymax='INDEF', ncols=ncols,
                                            nlines=nlines, verbose='no',
                                            fluxconserve='yes', nxblock=2048,
                                            nyblock=2048, interpolant="linear",
                                            boundary="constant", constant=0)
                if varframe:
                    var_infile = tilefile + "[" + str(ccd + nccds) + "]"
                    iraf.images.immatch.geotran(var_infile,
                                                tranfile[hdu + nccds],
                                                "",
                                                "",
                                                xshift=geo_xshift,
                                                yshift=geo_yshift,
                                                xrotation=xrot[ccd],
                                                yrotation=yrot[ccd],
                                                xmag=1, ymag=1, xmin='INDEF',
                                                xmax='INDEF', ymin='INDEF',
                                                ymax='INDEF', ncols=ncols,
                                                nlines=nlines, verbose='no',
                                                fluxconserve='yes',
                                                nxblock=2048, nyblock=2048,
                                                interpolant="linear",
                                                boundary="constant",
                                                constant=0)
                    var2_infile = tilefile + "[" + str(ccd + 2 * nccds) + "]"
                    iraf.images.immatch.geotran(var2_infile,
                                                tranfile[hdu + 2 * nccds],
                                                "",
                                                "",
                                                xshift=geo_xshift,
                                                yshift=geo_yshift,
                                                xrotation=xrot[ccd],
                                                yrotation=yrot[ccd],
                                                xmag=1, ymag=1, xmin='INDEF',
                                                xmax='INDEF', ymin='INDEF',
                                                ymax='INDEF', ncols=ncols,
                                                nlines=nlines, verbose='no',
                                                fluxconserve='yes',
                                                nxblock=2048, nyblock=2048,
                                                interpolant="linear",
                                                boundary="constant",
                                                constant=0)

                # open the file and copy the data to tranhdu
                tstruct = fits.open(tranfile[hdu])
                tranhdu[hdu] = tstruct[0].data
                tstruct.close()
                if varframe:
                    tranhdu[
                        hdu +
                        nccds] = fits.open(
                        tranfile[
                            hdu +
                            nccds])[0].data
                    tranhdu[
                        hdu +
                        2 *
                        nccds] = fits.open(
                        tranfile[
                            hdu +
                            2 *
                            nccds])[0].data

            else:
                log.message(
                    "Transform CCD #%i using dx=%s, dy=%s, rot=%s" %
                    (ccd,
                     xsh[ccd] /
                        2.0,
                        ysh[ccd] /
                        2.0,
                        xrot[ccd]),
                    with_stdout=verbose,
                    with_header=False)
                tranhdu[hdu] = geometric_transform(
                    tilehdu[ccd].data,
                    tran_func,
                    prefilter=False,
                    order=1,
                    extra_arguments=(
                        xsh[ccd] / 2,
                        ysh[ccd] / 2,
                        1,
                        1,
                        xrot[ccd],
                        yrot[ccd]))
                tstruct = fits.PrimaryHDU(tranhdu[hdu])
                tstruct.writeto(tranfile[hdu])
                if varframe:
                    tranhdu[hdu + nccds] = geometric_transform(
                        tilehdu[hdu + 3].data,
                        tran_func,
                        prefilter=False,
                        order=1,
                        extra_arguments=(
                            xsh[ccd] / 2, ysh[ccd] / 2,
                            1, 1,
                            xrot[ccd], yrot[ccd]))
                    tranhdu[hdu + 2 * nccds] = geometric_transform(
                        tilehdu[hdu + 6].data,
                        tran_func,
                        prefilter=False,
                        order=1,
                        extra_arguments=(
                            xsh[ccd] / 2, ysh[ccd] / 2,
                            1, 1,
                            xrot[ccd], yrot[ccd]))

        else:
            log.message(
                "Transform CCD #%i using dx=%s, dy=%s, rot=%s" %
                (ccd, 0, 0, 0), with_stdout=verbose, with_header=False)
            tranhdu[hdu] = tilehdu[ccd].data
            if varframe:
                tranhdu[hdu + nccds] = tilehdu[ccd + nccds].data
                tranhdu[hdu + 2 * nccds] = tilehdu[ccd + 2 * nccds].data

    # open outfile
    if varframe:
        outlist = 4 * [None]
    else:
        outlist = 2 * [None]

    #outlist[0] = struct[0].copy()
    outlist[0] = fits.PrimaryHDU()
    outlist[0].header = struct[0].header

    naxis1 = int(gap / xbin * (nccds - 1))
    naxis2 = 0
    for i in range(1, nccds + 1):
        yw, xw = tranhdu[i].shape
        naxis1 += xw + int(abs(xsh[ccd] / xbin)) + 1
        naxis2 = max(naxis2, yw)
    outdata = numpy.zeros((naxis2, naxis1), numpy.float32)
    outdata.shape = naxis2, naxis1
    if varframe:
        vardata = outdata * 0
        bpmdata = outdata * 0 + 1

    # iterate over CCDs, stich them to produce a full image
    hdu = 0
    totxshift = 0
    for hdu in range(1, nccds + 1):

        # read DATASEC keywords
        ydsec, xdsec = tranhdu[hdu].shape

        # define size and shape of final image
        # tile CCDs to yield mosaiced image
        x1 = int((hdu - 1) * (xdsec + gap / xbin)) + int(totxshift)
        x2 = xdsec + x1
        y1 = int(0)
        y2 = int(ydsec)
        outdata[y1:y2, x1:x2] = tranhdu[hdu]
        totxshift += int(abs(xsh[hdu] / xbin)) + 1
        if varframe:
            vardata[y1:y2, x1:x2] = tranhdu[hdu + nccds]
            bpmdata[y1:y2, x1:x2] = tranhdu[hdu + 2 * nccds]

    # make sure to cover up all the gaps include bad areas
    if varframe:
        baddata = (outdata == 0)
        baddata = nd.maximum_filter(baddata, size=3)
        bpmdata[baddata] = 1
        

    # fill in the gaps if requested
    if fill:
        if varframe:
            outdata = fill_gaps(outdata, 0)
        else:
            outdata = fill_gaps(outdata, 0)

    # add to the file
    outlist[1] = fits.ImageHDU(outdata)
    if varframe:
        outlist[2] = fits.ImageHDU(vardata,name='VAR')
        outlist[3] = fits.ImageHDU(bpmdata,name='BPM')

    # create the image structure
    outstruct = fits.HDUList(outlist)

    # update the head informaation
    # housekeeping keywords
    saltkey.put('NEXTEND', 2, outstruct[0])
    saltkey.new('EXTNAME', 'SCI', 'Extension name', outstruct[1])
    saltkey.new('EXTVER', 1, 'Extension number', outstruct[1])
    if varframe:
        saltkey.new('VAREXT', 2, 'Variance frame extension', outstruct[1])
        saltkey.new('BPMEXT', 3, 'BPM Extension', outstruct[1])

    try:
        saltkey.copy(struct[1], outstruct[1], 'CCDSUM')
    except:
        pass

    # Add keywords associated with geometry
    saltkey.new('SGEOMGAP', gap, 'SALT Chip Gap', outstruct[0])
    c1str = '{:3.2f} {:3.2f} {:3.4f}'.format(xshift[0],
                                     yshift[0],
                                     rotation[0])
    saltkey.new('SGEOM1', c1str, 'SALT Chip 1 Transform', outstruct[0])
    c2str = '{:3.2f} {:3.2f} {:3.4f}'.format(xshift[1],
                                     yshift[1],
                                     rotation[1])
    saltkey.new('SGEOM2', c2str, 'SALT Chip 2 Transform', outstruct[0])

    # WCS keywords
    saltkey.new('CRPIX1', 0, 'WCS: X reference pixel', outstruct[1])
    saltkey.new('CRPIX2', 0, 'WCS: Y reference pixel', outstruct[1])
    saltkey.new(
        'CRVAL1',
        float(xbin),
        'WCS: X reference coordinate value',
        outstruct[1])
    saltkey.new(
        'CRVAL2',
        float(ybin),
        'WCS: Y reference coordinate value',
        outstruct[1])
    saltkey.new('CDELT1', float(xbin), 'WCS: X pixel size', outstruct[1])
    saltkey.new('CDELT2', float(ybin), 'WCS: Y pixel size', outstruct[1])
    saltkey.new('CTYPE1', 'pixel', 'X type', outstruct[1])
    saltkey.new('CTYPE2', 'pixel', 'Y type', outstruct[1])

    # cleanup temporary files
    if cleanup:
        for tfile in tranfile:
            if os.path.isfile(tfile):
                saltio.delete(tfile)
        if os.path.isfile(tilefile):
            status = saltio.delete(tilefile)

    # return the file
    return outstruct
Ejemplo n.º 5
0
def xtalk(struct,xcoeff,namps=2, log=None,verbose=False):
    """xtalk cross-talk corrects the amplifies.  It takes 

    """
    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 = namps * nccd

    #setup the log
    if log:
       message='%28s %23s' % ('HDU','Correction')
       message += '\n      ----------------------------------------------'
       log.message(message, with_header=False, with_stdout=verbose)

    #Loop over the image extensions and subtract one
    #set from the other--still hardwired at 2
    for i in range(1,nsciext, 2):
      if struct[i].name=='SCI' and struct[i+1].name=='SCI':
        #set up the first amplifier
        dat1=struct[i].data.copy()
        ext1=saltkey.get('EXTVER', struct[i])
        if xcoeff: 
           j=(ext1-1)%amplifiers
           xc1=float(xcoeff[j])
        else:
           xc1=1.0/saltkey.get('XTALK', struct[i])

        #set up the second amplifier
        dat2=struct[i+1].data.copy()
        ext2=saltkey.get('EXTVER', struct[i+1])
        if xcoeff: 
           j=(ext2-1)%amplifiers
           xc2=float(xcoeff[j])
        else:
           xc2=1.0/saltkey.get('XTALK', struct[i+1])

        #subtract one from the other
        struct[i].data=struct[i].data-xc2*dat2[:,::-1]
        struct[i+1].data=struct[i+1].data-xc1*dat1[:,::-1]

        #correct the variance frame
        if saltkey.found('VAREXT', struct[i]):
           vhdu1=saltkey.get('VAREXT', struct[i])
           vhdu2=saltkey.get('VAREXT', struct[i+1])
           try:
               struct[vhdu1].data+=xc2*struct[vhdu2].data
               struct[vhdu2].data+=xc1*struct[vhdu1].data
           except Exception, e:
               msg='Cannot update the variance frame in %s[%i] because %s' % (infile, vhdu1, e)
               raise SaltError(msg)


        #print the message
        if log:
           message = '%25s[%1d]  Amp%1d - Amp%1d * %8.6f' % \
                    (infile, i, ext1, ext2, xc2)
           log.message(message, with_header=False, with_stdout=verbose)
           message = '%25s[%1d]  Amp%1d - Amp%1d * %8.6f' % \
                    (infile, i+1, ext2, ext1, xc1)
           log.message(message, with_header=False, with_stdout=verbose)
Ejemplo n.º 6
0
def crclean(struct, crtype='fast', thresh=5, mbox=5, bbox=11, bthresh=3, flux_ratio=0.2, \
              gain=1, rdnoise=5, bfactor=2, fthresh=5, gbox=0, maxiter=1, update=True, log=None, verbose=True):
   """CRCLEAN cleans SALT-like data of cosmic rays.  The user has 
           three different choices for the type of cosmic ray cleaning being
           fast, median, and edge.  

           crytpe--type of cosmic ray cleaning. Either fast, median, or 
           thresh--threshold for detecting cosmic rays
           mbox--box for median cleaning
           bbox--background box for median measurement
           bthresh--threshold for iterating on background calculation
           flux_ratio--ratio of fluxes for 'fast' method
           gain--gain of images--set to None to read in from header
           rdnoise--read noise of images--set to None to read in from header
           bfactor--block replication factor for 'edge' method
           fthresh--threshold for excluding compact sources (edge only)
           gbox--Window size to grow sources.  gbox=0 for no growth of cosmic rays
           maxiter--maximum number of iterations

           return struct
   """
   #setup the image name
   infile=saltkey.getimagename(struct[0])

           
   #count the CR
   totcr=0

   #print out the header for the log
   if log:
       message = '%28s %11s' % ('HDU','COSMICRAYS')
       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)

   #cosmic ray clean each extension
   for i in range(len(struct)):
          
       #only clean the cosmic rays if it is a SCI extension or a single extension
       if struct[i].name=='SCI' or len(struct)==1:           
           #for the edge method, get the gain and rdnoise from the fits header
           #if they are not set
           if crtype=='edge':
               if gain==None: gain=saltkey.get('GAIN',struct[i])
               if rdnoise==None: rdnoise=saltkey.get('RDNOISE',struct[i])

           #get all the cosmic rays from an array
  
           crarr=cleancosmicrays(struct[i].data, crtype, thresh, mbox, bbox, bthresh, flux_ratio, \
                                gain, rdnoise, bfactor, fthresh, gbox, maxiter)
           #update the frame for the various values
           mask=(crarr>0)
           if update: struct[i].data[mask]=crarr[mask]

           #track the number of cosmic rays
           ncr=mask.sum()
           totcr += ncr
           
           #if verbose print out information
           if log:
               message='%25s[%1d]  %i' % (infile, i, ncr)
               log.message(message, with_header=False, with_stdout=verbose)

           #correct the BPM frame
           if saltkey.found('BPMEXT', struct[i]):
                b_i=saltkey.get('BPMEXT', struct[i])
                try:
                   struct[b_i].data[mask]=1
                except Exception, e:
                   msg='Cannot update the BPM frame in %s[%i] because %s' % (infile, b_i, e)
                   raise SaltError(msg)
Ejemplo n.º 7
0
def multicrclean(struct, crtype='fast', thresh=5, mbox=5, bbox=11, bthresh=3, flux_ratio=0.2, \
              gain=1, rdnoise=5, bfactor=2, fthresh=5, gbox=0, maxiter=1, update=True, log=None, verbose=True):
   """MULTICRCLEAN cleans SALT-like data of cosmic rays.  The user has 
      three different choices for the type of cosmic ray cleaning being
      fast, median, and edge.   The process is set up to use multithreading for 
      quick processing of the data.  

           crytpe--type of cosmic ray cleaning. Either fast, median, or 
           thresh--threshold for detecting cosmic rays
           mbox--box for median cleaning
           bbox--background box for median measurement
           bthresh--threshold for iterating on background calculation
           flux_ratio--ratio of fluxes for 'fast' method
           gain--gain of images--set to None to read in from header
           rdnoise--read noise of images--set to None to read in from header
           bfactor--block replication factor for 'edge' method
           fthresh--threshold for excluding compact sources (edge only)
           gbox--Window size to grow sources.  gbox=0 for no growth of cosmic rays
           maxiter--maximum number of iterations

           return struct
   """
   #setup the image name
   infile=saltkey.getimagename(struct[0])

           
   #count the CR
   totcr=0

   #print out the header for the log
   if log:
       message = '%28s %11s' % ('HDU','COSMICRAYS')
       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)

   
   task_list=[]
   nproc=0
   for hdu in struct:
       if hdu.name=='SCI':
           task_list.append((hdu.data, crtype, thresh, mbox, bbox, bthresh, flux_ratio, gain, rdnoise, bfactor , fthresh, gbox, maxiter))
           nproc+=1

   #set up the multi-thread
   p=mp.Pool()


   results=[p.apply_async(cleancosmicrays, i) for i in task_list]
   p.close()


   for i, hdu in enumerate(struct):
       if hdu.name=='SCI':
           #set up the cosmic ray array
           crarr=results[i-1].get()

           #update the frame for the various values
           mask=(crarr>0)
           if update: struct[i].data[mask]=crarr[mask]

           #track the number of cosmic rays
           ncr=mask.sum()
           totcr += ncr
           
           #if verbose print out information
           if log:
               message='%25s[%1d]  %i' % (infile, i, ncr)
               log.message(message, with_header=False, with_stdout=verbose)

           #correct the BPM frame
           if saltkey.found('BPMEXT', struct[i]):
                b_i=saltkey.get('BPMEXT', struct[i])
                try:
                   struct[b_i].data[mask]=1
                except Exception, e:
                   msg='Cannot update the BPM frame in %s[%i] because %s' % (infile, b_i, e)
                   raise SaltError(msg)
Ejemplo n.º 8
0
def make_mosaic(struct,
                gap,
                xshift,
                yshift,
                rotation,
                interp_type='linear',
                boundary='constant',
                constant=0,
                geotran=True,
                fill=False,
                cleanup=True,
                log=None,
                verbose=False):
    """Given a SALT image struct, combine each of the individual amplifiers and
        apply the geometric CCD transformations to the image
    """

    # get the name of the file
    infile = saltkey.getimagename(struct[0], base=True)
    outpath = './'

    # identify instrument
    instrume, keyprep, keygain, keybias, keyxtalk, keyslot = \
        saltkey.instrumid(struct)

    # how many amplifiers?
    nsciext = saltkey.get('NSCIEXT', struct[0])
    nextend = saltkey.get('NEXTEND', struct[0])
    nccds = saltkey.get('NCCDS', struct[0])
    amplifiers = nccds * 2

    if nextend > nsciext:
        varframe = True
    else:
        varframe = False

    # CCD geometry coefficients
    if (instrume == 'RSS' or instrume == 'PFIS'):
        xsh = [0., xshift[0], 0., xshift[1]]
        ysh = [0., yshift[0], 0., yshift[1]]
        rot = [0., rotation[0], 0., rotation[1]]
    elif instrume == 'SALTICAM':
        xsh = [0., xshift[0], 0.]
        ysh = [0., yshift[0], 0.]
        rot = [0., rotation[0], 0]

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

    # CCD on-chip binning
    xbin, ybin = saltkey.ccdbin(struct[0])

    # create temporary primary extension
    outstruct = []
    outstruct.append(struct[0])
    # define temporary FITS file store tiled CCDs

    tilefile = saltio.tmpfile(outpath)
    tilefile += 'tile.fits'
    if varframe:
        tilehdu = [None] * (3 * int(nsciext / 2) + 1)
    else:
        tilehdu = [None] * int(nsciext / 2 + 1)
    tilehdu[0] = fits.PrimaryHDU()
    #tilehdu[0].header = struct[0].header

    if log:
        log.message('', with_stdout=verbose)

    # iterate over amplifiers, stich them to produce file of CCD images
    for i in range(int(nsciext / 2)):
        hdu = i * 2 + 1
        # amplifier = hdu%amplifiers
        # if (amplifier == 0): amplifier = amplifiers

        # read DATASEC keywords
        datasec1 = saltkey.get('DATASEC', struct[hdu])
        datasec2 = saltkey.get('DATASEC', struct[hdu + 1])
        xdsec1, ydsec1 = saltstring.secsplit(datasec1)
        xdsec2, ydsec2 = saltstring.secsplit(datasec2)

        # read images
        imdata1 = saltio.readimage(struct, hdu)
        imdata2 = saltio.readimage(struct, hdu + 1)

        # tile 2n amplifiers to yield n CCD images
        outdata = numpy.zeros(
            (int(ydsec1[1] + abs(ysh[i + 1] / ybin)),
             int(xdsec1[1] + xdsec2[1] + abs(xsh[i + 1] / xbin))),
            numpy.float32)

        # set up the variance frame
        if varframe:
            vardata = outdata.copy()
            vdata1 = saltio.readimage(struct, struct[hdu].header['VAREXT'])
            vdata2 = saltio.readimage(struct, struct[hdu + 1].header['VAREXT'])

            bpmdata = outdata.copy()
            bdata1 = saltio.readimage(struct, struct[hdu].header['BPMEXT'])
            bdata2 = saltio.readimage(struct, struct[hdu + 1].header['BPMEXT'])

        x1 = xdsec1[0] - 1
        if x1 != 0:
            msg = 'The data in %s have not been trimmed prior to mosaicking.' \
                  % infile
            log.error(msg)
        if xsh[i + 1] < 0:
            x1 += int(abs(xsh[i + 1] / xbin))
        x2 = x1 + xdsec1[1]
        y1 = ydsec1[0] - 1
        if ysh[i + 1] < 0:
            y1 += int(abs(ysh[i + 1] / ybin))
        y2 = y1 + ydsec1[1]
        outdata[y1:y2, x1:x2] =\
            imdata1[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        if varframe:
            vardata[y1:y2, x1:x2] =\
                vdata1[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]
            bpmdata[y1:y2, x1:x2] =\
                bdata1[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        x1 = x2
        x2 = x1 + xdsec2[1]
        y1 = ydsec2[0] - 1
        if ysh[i + 1] < 0:
            y1 += abs(ysh[i + 1] / ybin)
        y2 = y1 + ydsec2[1]
        outdata[y1:y2, x1:x2] =\
            imdata2[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        if varframe:
            vardata[y1:y2, x1:x2] =\
                vdata2[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]
            bpmdata[y1:y2, x1:x2] =\
                bdata2[ydsec1[0] - 1:ydsec1[1], xdsec1[0] - 1:xdsec1[1]]

        # size of new image
        naxis1 = str(xdsec1[1] + xdsec2[1])
        naxis2 = str(ydsec1[1])

        # add image and keywords to HDU list
        tilehdu[i + 1] = fits.ImageHDU(outdata)
        tilehdu[i + 1].header = struct[hdu].header
        #tilehdu[
        #    i + 1].header['DATASEC'] = '[1:' + naxis1 + ',1:' + naxis2 + ']'

        if varframe:
            vext = i + 1 + int(nsciext / 2.)
            tilehdu[vext] = fits.ImageHDU(vardata)
            #tilehdu[vext].header = struct[struct[hdu].header['VAREXT']].header
            #tilehdu[vext].header[
            #    'DATASEC'] = '[1:' + naxis1 + ',1:' + naxis2 + ']'

            bext = i + 1 + 2 * int(nsciext / 2.)
            tilehdu[bext] = fits.ImageHDU(bpmdata)
            #tilehdu[bext].header = struct[struct[hdu].header['BPMEXT']].header
            #tilehdu[bext].header[
            #    'DATASEC'] = '[1:' + naxis1 + ',1:' + naxis2 + ']'

        # image tile log message #1
        if log:
            message = os.path.basename(infile) + '[' + str(hdu) + ']['
            message += str(xdsec1[0]) + ':' + str(xdsec1[1]) + ','
            message += str(ydsec1[0]) + ':' + str(ydsec1[1]) + '] --> '
            message += os.path.basename(tilefile) + '[' + str(i + 1) + ']['
            message += str(xdsec1[0]) + ':' + str(xdsec1[1]) + ','
            message += str(ydsec1[0]) + ':' + str(ydsec1[1]) + ']'
            log.message(message, with_stdout=verbose, with_header=False)
            message = os.path.basename(infile) + '[' + str(hdu + 1) + ']['
            message += str(xdsec1[0]) + ':' + str(xdsec1[1]) + ','
            message += str(ydsec1[0]) + ':' + str(ydsec1[1]) + '] --> '
            message += os.path.basename(tilefile) + '[' + str(i + 1) + ']['
            message += str(xdsec1[1] + 1) + ':' + \
                str(xdsec1[1] + xdsec2[1]) + ','
            message += str(ydsec2[0]) + ':' + str(ydsec2[1]) + ']'
            log.message(message, with_stdout=verbose, with_header=False)

    # write temporary file of tiled CCDs
    hdulist = fits.HDUList(tilehdu)
    hdulist.writeto(tilefile)

    # iterate over CCDs, transform and rotate images
    yrot = [None] * 4
    xrot = [None] * 4

    tranfile = [' ']
    tranhdu = [0]
    if varframe:
        tranfile = [''] * (3 * int(nsciext / 2) + 1)
        tranhdu = [0] * (3 * int(nsciext / 2) + 1)
    else:
        tranfile = [''] * int(nsciext / 2 + 1)
        tranhdu = [0] * int(nsciext / 2 + 1)

    # this is hardwired for SALT where the second CCD is considered the
    # fiducial
    for hdu in range(1, int(nsciext / 2 + 1)):
        tranfile[hdu] = saltio.tmpfile(outpath)
        tranfile[hdu] += 'tran.fits'
        if varframe:
            tranfile[hdu + nccds] = saltio.tmpfile(outpath) + 'tran.fits'
            tranfile[hdu + 2 * nccds] = saltio.tmpfile(outpath) + 'tran.fits'

        ccd = hdu % nccds
        if (ccd == 0):
            ccd = nccds

        # correct rotation for CCD binning
        yrot[ccd] = rot[ccd] * ybin / xbin
        xrot[ccd] = rot[ccd] * xbin / ybin
        dxshift = xbin * int(float(int(gap) / xbin) + 0.5) - gap

        # transformation using geotran IRAF task
        # if (ccd == 1):
        if (ccd != 2):

            if geotran:
                message = '\nSALTMOSAIC -- geotran ' + tilefile + \
                    '[' + str(ccd) + '] ' + tranfile[hdu]
                message += ' \"\" \"\" xshift=' + \
                    str((xsh[ccd] + (2 - ccd) * dxshift) / xbin) + ' '
                message += 'yshift=' + \
                    str(ysh[ccd] / ybin) + ' xrotation=' + str(xrot[ccd]) + ' '
                message += 'yrotation=' + \
                    str(yrot[ccd]) + ' xmag=1 ymag=1 xmin=\'INDEF\''
                message += 'xmax=\'INDEF\' ymin=\'INDEF\' ymax=\'INDEF\' '
                message += 'ncols=\'INDEF\' '
                message += 'nlines=\'INDEF\' verbose=\'no\' '
                message += 'fluxconserve=\'yes\' nxblock=2048 '
                message += 'nyblock=2048 interpolant=\'' + \
                    interp_type + '\' boundary=\'constant\' constant=0'
                log.message(message, with_stdout=verbose)

                yd, xd = tilehdu[ccd].data.shape
                ncols = 'INDEF'  # ncols=xd+abs(xsh[ccd]/xbin)
                nlines = 'INDEF'  # nlines=yd+abs(ysh[ccd]/ybin)
                geo_xshift = xsh[ccd] + (2 - ccd) * dxshift / xbin
                geo_yshift = ysh[ccd] / ybin
                iraf.images.immatch.geotran(tilefile + "[" + str(ccd) + "]",
                                            tranfile[hdu],
                                            "",
                                            "",
                                            xshift=geo_xshift,
                                            yshift=geo_yshift,
                                            xrotation=xrot[ccd],
                                            yrotation=yrot[ccd],
                                            xmag=1,
                                            ymag=1,
                                            xmin='INDEF',
                                            xmax='INDEF',
                                            ymin='INDEF',
                                            ymax='INDEF',
                                            ncols=ncols,
                                            nlines=nlines,
                                            verbose='no',
                                            fluxconserve='yes',
                                            nxblock=2048,
                                            nyblock=2048,
                                            interpolant="linear",
                                            boundary="constant",
                                            constant=0)
                if varframe:
                    var_infile = tilefile + "[" + str(ccd + nccds) + "]"
                    iraf.images.immatch.geotran(var_infile,
                                                tranfile[hdu + nccds],
                                                "",
                                                "",
                                                xshift=geo_xshift,
                                                yshift=geo_yshift,
                                                xrotation=xrot[ccd],
                                                yrotation=yrot[ccd],
                                                xmag=1,
                                                ymag=1,
                                                xmin='INDEF',
                                                xmax='INDEF',
                                                ymin='INDEF',
                                                ymax='INDEF',
                                                ncols=ncols,
                                                nlines=nlines,
                                                verbose='no',
                                                fluxconserve='yes',
                                                nxblock=2048,
                                                nyblock=2048,
                                                interpolant="linear",
                                                boundary="constant",
                                                constant=0)
                    var2_infile = tilefile + "[" + str(ccd + 2 * nccds) + "]"
                    iraf.images.immatch.geotran(var2_infile,
                                                tranfile[hdu + 2 * nccds],
                                                "",
                                                "",
                                                xshift=geo_xshift,
                                                yshift=geo_yshift,
                                                xrotation=xrot[ccd],
                                                yrotation=yrot[ccd],
                                                xmag=1,
                                                ymag=1,
                                                xmin='INDEF',
                                                xmax='INDEF',
                                                ymin='INDEF',
                                                ymax='INDEF',
                                                ncols=ncols,
                                                nlines=nlines,
                                                verbose='no',
                                                fluxconserve='yes',
                                                nxblock=2048,
                                                nyblock=2048,
                                                interpolant="linear",
                                                boundary="constant",
                                                constant=0)

                # open the file and copy the data to tranhdu
                tstruct = fits.open(tranfile[hdu])
                tranhdu[hdu] = tstruct[0].data
                tstruct.close()
                if varframe:
                    tranhdu[hdu + nccds] = fits.open(tranfile[hdu +
                                                              nccds])[0].data
                    tranhdu[hdu + 2 * nccds] = fits.open(
                        tranfile[hdu + 2 * nccds])[0].data

            else:
                log.message("Transform CCD #%i using dx=%s, dy=%s, rot=%s" %
                            (ccd, xsh[ccd] / 2.0, ysh[ccd] / 2.0, xrot[ccd]),
                            with_stdout=verbose,
                            with_header=False)
                tranhdu[hdu] = geometric_transform(
                    tilehdu[ccd].data,
                    tran_func,
                    prefilter=False,
                    order=1,
                    extra_arguments=(xsh[ccd] / 2, ysh[ccd] / 2, 1, 1,
                                     xrot[ccd], yrot[ccd]))
                tstruct = fits.PrimaryHDU(tranhdu[hdu])
                tstruct.writeto(tranfile[hdu])
                if varframe:
                    tranhdu[hdu + nccds] = geometric_transform(
                        tilehdu[hdu + 3].data,
                        tran_func,
                        prefilter=False,
                        order=1,
                        extra_arguments=(xsh[ccd] / 2, ysh[ccd] / 2, 1, 1,
                                         xrot[ccd], yrot[ccd]))
                    tranhdu[hdu + 2 * nccds] = geometric_transform(
                        tilehdu[hdu + 6].data,
                        tran_func,
                        prefilter=False,
                        order=1,
                        extra_arguments=(xsh[ccd] / 2, ysh[ccd] / 2, 1, 1,
                                         xrot[ccd], yrot[ccd]))

        else:
            log.message("Transform CCD #%i using dx=%s, dy=%s, rot=%s" %
                        (ccd, 0, 0, 0),
                        with_stdout=verbose,
                        with_header=False)
            tranhdu[hdu] = tilehdu[ccd].data
            if varframe:
                tranhdu[hdu + nccds] = tilehdu[ccd + nccds].data
                tranhdu[hdu + 2 * nccds] = tilehdu[ccd + 2 * nccds].data

    # open outfile
    if varframe:
        outlist = 4 * [None]
    else:
        outlist = 2 * [None]

    #outlist[0] = struct[0].copy()
    outlist[0] = fits.PrimaryHDU()
    outlist[0].header = struct[0].header

    naxis1 = int(gap / xbin * (nccds - 1))
    naxis2 = 0
    for i in range(1, nccds + 1):
        yw, xw = tranhdu[i].shape
        naxis1 += xw + int(abs(xsh[ccd] / xbin)) + 1
        naxis2 = max(naxis2, yw)
    outdata = numpy.zeros((naxis2, naxis1), numpy.float32)
    outdata.shape = naxis2, naxis1
    if varframe:
        vardata = outdata * 0
        bpmdata = outdata * 0 + 1

    # iterate over CCDs, stich them to produce a full image
    hdu = 0
    totxshift = 0
    for hdu in range(1, nccds + 1):

        # read DATASEC keywords
        ydsec, xdsec = tranhdu[hdu].shape

        # define size and shape of final image
        # tile CCDs to yield mosaiced image
        x1 = int((hdu - 1) * (xdsec + gap / xbin)) + int(totxshift)
        x2 = xdsec + x1
        y1 = int(0)
        y2 = int(ydsec)
        outdata[y1:y2, x1:x2] = tranhdu[hdu]
        totxshift += int(abs(xsh[hdu] / xbin)) + 1
        if varframe:
            vardata[y1:y2, x1:x2] = tranhdu[hdu + nccds]
            bpmdata[y1:y2, x1:x2] = tranhdu[hdu + 2 * nccds]

    # make sure to cover up all the gaps include bad areas
    if varframe:
        baddata = (outdata == 0)
        baddata = nd.maximum_filter(baddata, size=3)
        bpmdata[baddata] = 1

    # fill in the gaps if requested
    if fill:
        if varframe:
            outdata = fill_gaps(outdata, 0)
        else:
            outdata = fill_gaps(outdata, 0)

    # add to the file
    outlist[1] = fits.ImageHDU(outdata)
    if varframe:
        outlist[2] = fits.ImageHDU(vardata, name='VAR')
        outlist[3] = fits.ImageHDU(bpmdata, name='BPM')

    # create the image structure
    outstruct = fits.HDUList(outlist)

    # update the head informaation
    # housekeeping keywords
    saltkey.put('NEXTEND', 2, outstruct[0])
    saltkey.new('EXTNAME', 'SCI', 'Extension name', outstruct[1])
    saltkey.new('EXTVER', 1, 'Extension number', outstruct[1])
    if varframe:
        saltkey.new('VAREXT', 2, 'Variance frame extension', outstruct[1])
        saltkey.new('BPMEXT', 3, 'BPM Extension', outstruct[1])

    try:
        saltkey.copy(struct[1], outstruct[1], 'CCDSUM')
    except:
        pass

    # Add keywords associated with geometry
    saltkey.new('SGEOMGAP', gap, 'SALT Chip Gap', outstruct[0])
    c1str = '{:3.2f} {:3.2f} {:3.4f}'.format(xshift[0], yshift[0], rotation[0])
    saltkey.new('SGEOM1', c1str, 'SALT Chip 1 Transform', outstruct[0])
    c2str = '{:3.2f} {:3.2f} {:3.4f}'.format(xshift[1], yshift[1], rotation[1])
    saltkey.new('SGEOM2', c2str, 'SALT Chip 2 Transform', outstruct[0])

    # WCS keywords
    saltkey.new('CRPIX1', 0, 'WCS: X reference pixel', outstruct[1])
    saltkey.new('CRPIX2', 0, 'WCS: Y reference pixel', outstruct[1])
    saltkey.new('CRVAL1', float(xbin), 'WCS: X reference coordinate value',
                outstruct[1])
    saltkey.new('CRVAL2', float(ybin), 'WCS: Y reference coordinate value',
                outstruct[1])
    saltkey.new('CDELT1', float(xbin), 'WCS: X pixel size', outstruct[1])
    saltkey.new('CDELT2', float(ybin), 'WCS: Y pixel size', outstruct[1])
    saltkey.new('CTYPE1', 'pixel', 'X type', outstruct[1])
    saltkey.new('CTYPE2', 'pixel', 'Y type', outstruct[1])

    # cleanup temporary files
    if cleanup:
        for tfile in tranfile:
            if os.path.isfile(tfile):
                saltio.delete(tfile)
        if os.path.isfile(tilefile):
            status = saltio.delete(tilefile)

    # return the file
    return outstruct
Ejemplo n.º 9
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)
Ejemplo n.º 10
0
def xtalk(struct, xcoeff, namps=2, log=None, verbose=False):
    """xtalk cross-talk corrects the amplifies.  It takes 

    """
    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 = namps * nccd

    #setup the log
    if log:
        message = '%28s %23s' % ('HDU', 'Correction')
        message += '\n      ----------------------------------------------'
        log.message(message, with_header=False, with_stdout=verbose)

    #Loop over the image extensions and subtract one
    #set from the other--still hardwired at 2
    for i in range(1, nsciext, 2):
        if struct[i].name == 'SCI' and struct[i + 1].name == 'SCI':
            #set up the first amplifier
            dat1 = struct[i].data.copy()
            ext1 = saltkey.get('EXTVER', struct[i])
            if xcoeff:
                j = (ext1 - 1) % amplifiers
                xc1 = float(xcoeff[j])
            else:
                xc1 = 1.0 / saltkey.get('XTALK', struct[i])

            #set up the second amplifier
            dat2 = struct[i + 1].data.copy()
            ext2 = saltkey.get('EXTVER', struct[i + 1])
            if xcoeff:
                j = (ext2 - 1) % amplifiers
                xc2 = float(xcoeff[j])
            else:
                xc2 = 1.0 / saltkey.get('XTALK', struct[i + 1])

            #subtract one from the other
            struct[i].data = struct[i].data - xc2 * dat2[:, ::-1]
            struct[i + 1].data = struct[i + 1].data - xc1 * dat1[:, ::-1]

            #correct the variance frame
            if saltkey.found('VAREXT', struct[i]):
                vhdu1 = saltkey.get('VAREXT', struct[i])
                vhdu2 = saltkey.get('VAREXT', struct[i + 1])
                try:
                    struct[vhdu1].data += xc2 * struct[vhdu2].data
                    struct[vhdu2].data += xc1 * struct[vhdu1].data
                except Exception, e:
                    msg = 'Cannot update the variance frame in %s[%i] because %s' % (
                        infile, vhdu1, e)
                    raise SaltError(msg)

            #print the message
            if log:
                message = '%25s[%1d]  Amp%1d - Amp%1d * %8.6f' % \
                         (infile, i, ext1, ext2, xc2)
                log.message(message, with_header=False, with_stdout=verbose)
                message = '%25s[%1d]  Amp%1d - Amp%1d * %8.6f' % \
                         (infile, i+1, ext2, ext1, xc1)
                log.message(message, with_header=False, with_stdout=verbose)
Ejemplo n.º 11
0
def gain(struct,
         mult=True,
         usedb=False,
         dblist=None,
         ampccd=2,
         log=None,
         verbose=True):
    """gain processes a image hduList and gain corrects each amplifier.  It can
      either use gain settings in the header or those supplied in a config file
      which would be suppleid in the dblist (see helpfile for structure of the
      config file).  If variance frames exist, it will update those for changes 
      in the header value as well.   

      In the end, it will update the gain with a value of one signfing the data
      has been transformed into e- from ADU

      The program will look for the non-linear gain settings which are given by:
      e  = GAIN*(1 + GAIN1*E-6*ADU)*ADU

      mult--if true, multiple the gains
      usedb--use the values in the dblist, if false use the header values
      dblist--values for the gain and readnoise from the 
      ampccd--number of amplifiers per ccd

      dblist should have the following lists:  speed, rate, gain, noise, bias, amp
   """
    #get the infile name
    infile = saltkey.getimagename(struct[0])

    #how many science extensions
    nsciext = saltkey.get('NSCIEXT', struct[0])
    #how many data extensions
    nextend = saltkey.get('NSCIEXT', struct[0])

    # how many amplifiers?
    amplifiers = ampccd * saltkey.get('NCCDS', struct[0])

    #read the gain and rospeed for the image
    gainset = saltkey.get('GAINSET', struct[0])
    rospeed = saltkey.get('ROSPEED', struct[0])

    #loop through each amplifier and gain correct it
    if log:
        message = '%28s %6s %5s %3s %5s %5s' \
            % ('HDU','GAIN','SPEED','AMP','GAIN','NOISE')
        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)
    for i in range(nsciext):
        hdu = i + 1
        amp = i % amplifiers + 1
        #get the gain and rdnoise values for the array
        if usedb:
            gain, rdnoise = get_values(dblist, gainset, rospeed, amp)
            gain1 = 0
        else:
            gain = saltkey.get('GAIN', struct[hdu])
            rdnoise = saltkey.get('RDNOISE', struct[hdu])
            try:
                gain1 = saltkey.get('GAIN1', struct[hdu])
            except:
                gain1 = 0

        if mult:
            #correct the gain
            gainmult = 1
            try:
                data = struct[hdu].data
                struct[hdu].data = gain * data + gain1 * data**2
            except Exception, e:
                msg = 'Cannot gain correct %s[%i] because %s' % (infile, hdu,
                                                                 e)
                raise SaltError(msg)

            #correct the variance frame
            if saltkey.found('VAREXT', struct[hdu]):
                vhdu = saltkey.get('VAREXT', struct[hdu])
                try:
                    vdata = struct[vhdu].data
                    struct[vhdu].data = vdata * gain * (
                        1 + 2 * gain1 * 1e-6 * data)
                except Exception, e:
                    msg = 'Cannot update the variance frame in %s[%i] because %s' % (
                        infile, vhdu, e)
                    raise SaltError(msg)
Ejemplo n.º 12
0
def crclean(struct, crtype='fast', thresh=5, mbox=5, bbox=11, bthresh=3, flux_ratio=0.2, \
              gain=1, rdnoise=5, bfactor=2, fthresh=5, gbox=0, maxiter=1, update=True, log=None, verbose=True):
    """CRCLEAN cleans SALT-like data of cosmic rays.  The user has 
           three different choices for the type of cosmic ray cleaning being
           fast, median, and edge.  

           crytpe--type of cosmic ray cleaning. Either fast, median, or 
           thresh--threshold for detecting cosmic rays
           mbox--box for median cleaning
           bbox--background box for median measurement
           bthresh--threshold for iterating on background calculation
           flux_ratio--ratio of fluxes for 'fast' method
           gain--gain of images--set to None to read in from header
           rdnoise--read noise of images--set to None to read in from header
           bfactor--block replication factor for 'edge' method
           fthresh--threshold for excluding compact sources (edge only)
           gbox--Window size to grow sources.  gbox=0 for no growth of cosmic rays
           maxiter--maximum number of iterations

           return struct
   """
    #setup the image name
    infile = saltkey.getimagename(struct[0])

    #count the CR
    totcr = 0

    #print out the header for the log
    if log:
        message = '%28s %11s' % ('HDU', 'COSMICRAYS')
        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)

    #cosmic ray clean each extension
    for i in range(len(struct)):

        #only clean the cosmic rays if it is a SCI extension or a single extension
        if struct[i].name == 'SCI' or len(struct) == 1:
            #for the edge method, get the gain and rdnoise from the fits header
            #if they are not set
            if crtype == 'edge':
                if gain == None: gain = saltkey.get('GAIN', struct[i])
                if rdnoise == None: rdnoise = saltkey.get('RDNOISE', struct[i])

            #get all the cosmic rays from an array

            crarr=cleancosmicrays(struct[i].data, crtype, thresh, mbox, bbox, bthresh, flux_ratio, \
                                 gain, rdnoise, bfactor, fthresh, gbox, maxiter)
            #update the frame for the various values
            mask = (crarr > 0)
            if update: struct[i].data[mask] = crarr[mask]

            #track the number of cosmic rays
            ncr = mask.sum()
            totcr += ncr

            #if verbose print out information
            if log:
                message = '%25s[%1d]  %i' % (infile, i, ncr)
                log.message(message, with_header=False, with_stdout=verbose)

            #correct the BPM frame
            if saltkey.found('BPMEXT', struct[i]):
                b_i = saltkey.get('BPMEXT', struct[i])
                try:
                    struct[b_i].data[mask] = 1
                except Exception, e:
                    msg = 'Cannot update the BPM frame in %s[%i] because %s' % (
                        infile, b_i, e)
                    raise SaltError(msg)
Ejemplo n.º 13
0
def multicrclean(struct, crtype='fast', thresh=5, mbox=5, bbox=11, bthresh=3, flux_ratio=0.2, \
              gain=1, rdnoise=5, bfactor=2, fthresh=5, gbox=0, maxiter=1, update=True, log=None, verbose=True):
    """MULTICRCLEAN cleans SALT-like data of cosmic rays.  The user has 
      three different choices for the type of cosmic ray cleaning being
      fast, median, and edge.   The process is set up to use multithreading for 
      quick processing of the data.  

           crytpe--type of cosmic ray cleaning. Either fast, median, or 
           thresh--threshold for detecting cosmic rays
           mbox--box for median cleaning
           bbox--background box for median measurement
           bthresh--threshold for iterating on background calculation
           flux_ratio--ratio of fluxes for 'fast' method
           gain--gain of images--set to None to read in from header
           rdnoise--read noise of images--set to None to read in from header
           bfactor--block replication factor for 'edge' method
           fthresh--threshold for excluding compact sources (edge only)
           gbox--Window size to grow sources.  gbox=0 for no growth of cosmic rays
           maxiter--maximum number of iterations

           return struct
   """
    #setup the image name
    infile = saltkey.getimagename(struct[0])

    #count the CR
    totcr = 0

    #print out the header for the log
    if log:
        message = '%28s %11s' % ('HDU', 'COSMICRAYS')
        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)

    task_list = []
    nproc = 0
    for hdu in struct:
        if hdu.name == 'SCI':
            task_list.append(
                (hdu.data, crtype, thresh, mbox, bbox, bthresh, flux_ratio,
                 gain, rdnoise, bfactor, fthresh, gbox, maxiter))
            nproc += 1

    #set up the multi-thread
    p = mp.Pool()

    results = [p.apply_async(cleancosmicrays, i) for i in task_list]
    p.close()

    for i, hdu in enumerate(struct):
        if hdu.name == 'SCI':
            #set up the cosmic ray array
            crarr = results[i - 1].get()

            #update the frame for the various values
            mask = (crarr > 0)
            if update: struct[i].data[mask] = crarr[mask]

            #track the number of cosmic rays
            ncr = mask.sum()
            totcr += ncr

            #if verbose print out information
            if log:
                message = '%25s[%1d]  %i' % (infile, i, ncr)
                log.message(message, with_header=False, with_stdout=verbose)

            #correct the BPM frame
            if saltkey.found('BPMEXT', struct[i]):
                b_i = saltkey.get('BPMEXT', struct[i])
                try:
                    struct[b_i].data[mask] = 1
                except Exception, e:
                    msg = 'Cannot update the BPM frame in %s[%i] because %s' % (
                        infile, b_i, e)
                    raise SaltError(msg)
Ejemplo n.º 14
0
def gain(struct,mult=True,usedb=False, dblist=None, ampccd=2, log=None, verbose=True):
   """gain processes a image hduList and gain corrects each amplifier.  It can
      either use gain settings in the header or those supplied in a config file
      which would be suppleid in the dblist (see helpfile for structure of the
      config file).  If variance frames exist, it will update those for changes 
      in the header value as well.   

      In the end, it will update the gain with a value of one signfing the data
      has been transformed into e- from ADU

      The program will look for the non-linear gain settings which are given by:
      e  = GAIN*(1 + GAIN1*E-6*ADU)*ADU

      mult--if true, multiple the gains
      usedb--use the values in the dblist, if false use the header values
      dblist--values for the gain and readnoise from the 
      ampccd--number of amplifiers per ccd

      dblist should have the following lists:  speed, rate, gain, noise, bias, amp
   """
   #get the infile name
   infile=saltkey.getimagename(struct[0])

   #how many science extensions
   nsciext = saltkey.get('NSCIEXT',struct[0])
   #how many data extensions
   nextend = saltkey.get('NSCIEXT',struct[0])

   # how many amplifiers?
   amplifiers = ampccd*saltkey.get('NCCDS',struct[0])

   #read the gain and rospeed for the image
   gainset = saltkey.get('GAINSET',struct[0])
   rospeed = saltkey.get('ROSPEED',struct[0])

   #loop through each amplifier and gain correct it
   if log:
        message = '%28s %6s %5s %3s %5s %5s' \
            % ('HDU','GAIN','SPEED','AMP','GAIN','NOISE')
        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)
   for i in range(nsciext):
       hdu = i + 1
       amp = i%amplifiers+1
       #get the gain and rdnoise values for the array 
       if usedb:
           gain, rdnoise=get_values(dblist, gainset, rospeed, amp)
           gain1=0
       else:
           gain = saltkey.get('GAIN',struct[hdu])
           rdnoise = saltkey.get('RDNOISE',struct[hdu])
           try:
               gain1=saltkey.get('GAIN1',struct[hdu])
           except:
               gain1=0
 

       if mult:
           #correct the gain
           gainmult=1
           try:
               data=struct[hdu].data
               struct[hdu].data=gain*data+gain1*data**2
           except Exception as e:
               msg='Cannot gain correct %s[%i] because %s' % (infile, hdu, e)
               raise SaltError(msg)
               
           #correct the variance frame
           if saltkey.found('VAREXT', struct[hdu]):
               vhdu=saltkey.get('VAREXT', struct[hdu])
               try:
                   vdata=struct[vhdu].data
                   struct[vhdu].data=vdata*gain*(1+2*gain1*1e-6*data)
               except Exception as e:
                    msg='Cannot update the variance frame in %s[%i] because %s' % (infile, vhdu, e)
                    raise SaltError(msg)
       else:
           gainmult=gain
 
       #update the headers
       if usedb:
           saltkey.put('GAIN',gain,struct[hdu])
           saltkey.put('RDNOISE',rdnoise,struct[hdu])

       #add a keyword indicating what action was taken
       saltkey.new('GAINMULT',gainmult,'Gain multiplication', struct[hdu])

       #if logging is true, then print out the following information
       if log:
           message = '%25s[%1d] %6s %5s %2s %6.2f %5.2f' \
             % (infile,hdu,gainset,rospeed,amp, gain, rdnoise)
           log.message(message, with_header=False, with_stdout=verbose)

   #just to make it look pretty 
   if log:
       log.message('',  with_header=False, with_stdout=verbose)
          
   return struct