Exemple #1
0
def cdriver(method, data, guess, trim, radius, size,
                 mask=None, uncd=None, fitbg=1, maskstar=True,
                 expand=5.0, psf=None, psfctr=None):
  # Default mask: all good
  if mask is None:
    mask = np.ones(np.shape(data))
  # Default uncertainties: flat image
  if uncd is None:
    uncd = np.ones(np.shape(data))
  # Trim the image if requested
  if trim != 0:
    # Integer part of center
    cen = np.rint(guess)
    # Center in the trimed image
    loc = (trim, trim)
    # Do the trim:
    img, msk, err = ie.trimimage(data, cen, loc, mask=mask, uncd=uncd)
  else:
    cen = np.array([0,0])
    loc = np.rint(guess)
    img, msk, err = data, mask, uncd
  # If all data is bad:
  if not np.any(msk):
    raise Exception('Bad Frame Exception!')
  weights = 1.0/np.abs(err)
  # Get the center with one of the methods:
  if   method == 'fgc':
    foo, bar = g.fitgaussian(img, yxguess=loc, mask=msk, weights=weights,
                         fitbg=fitbg, maskg=maskstar)
    #print(foo, bar)
    y, x = foo[2:4]
    yerr, xerr = bar[2:4]

  # Make trimming correction and return
  return ((y, x) + cen - trim), (yerr, xerr)
Exemple #2
0
def centerdriver(method,
                 data,
                 guess,
                 trim,
                 radius,
                 size,
                 mask=None,
                 uncd=None,
                 fitbg=1,
                 maskstar=True,
                 expand=5.0,
                 psf=None,
                 psfctr=None):
    """
  Use the center method to find the center of a star in data, starting
  from position guess.
  
  Parameters:
  -----------
  method: string
          Name of the centering method to use.
  data:   2D ndarray
          Array containing the star image.
  guess:  2 elements 1D array
          y, x initial guess position of the target.
  trim:   integer
          Semi-length of the box around the target that will be trimmed.
  radius: float
          least asymmetry parameter. See err_fasym_c.
  size:   float
          least asymmetry parameter. See err_fasym_c.  
  mask:   2D ndarray
          A mask array of bad pixels. Same shape of data.
  uncd:   2D ndarray
          An array containing the uncertainty values of data. Same
          shape of data.
          
  Returns:
  --------
  A y,x tuple (scalars) with the coordinates of center of the target
  in data.
  
  Example:
  --------
  nica

  Modification History:
  ---------------------
  23-11-2010 patricio   Written by Patricio Cubillos
                        [email protected]
  """

    # Default mask: all good
    if mask is None:
        mask = np.ones(np.shape(data))

    # Default uncertainties: flat image
    if uncd is None:
        uncd = np.ones(np.shape(data))

    # Trim the image if requested
    if trim != 0:
        # Integer part of center
        cen = np.rint(guess)
        # Center in the trimed image
        loc = (trim, trim)
        # Do the trim:
        img, msk, err = ie.trimimage(data, cen, loc, mask=mask, uncd=uncd)
    else:
        cen = np.array([0, 0])
        loc = np.rint(guess)
        img, msk, err = data, mask, uncd

    # If all data is bad:
    if not np.any(msk):
        raise Exception('Bad Frame Exception!')

    weights = 1.0 / np.abs(err)
    extra = []

    # Get the center with one of the methods:
    if method == 'fgc':
        sy, sx, y, x = g.fitgaussian(img,
                                     yxguess=loc,
                                     mask=msk,
                                     weights=weights,
                                     fitbg=fitbg,
                                     maskg=maskstar)[0][0:4]
        extra = sy, sx  #Gaussian 1-sigma half-widths
    elif method == 'col':
        y, x = ctr.col(img)
    elif method == 'lag':
        [y, x], asym = la.actr(img,
                               loc,
                               asym_rad=radius,
                               asym_size=size,
                               method='gaus')
        #y, x = ctr.actr(img, loc, asym_rad=radius,
        #                asym_size=size, method='gaus')
    elif method == 'lac':
        [y, x], asym = la.actr(img,
                               loc,
                               asym_rad=radius,
                               asym_size=size,
                               method='col')
    elif method == 'bpf' or method == 'ipf':
        y, x, flux, sky = pf.spitzer_fit(img, msk, weights, psf, psfctr,
                                         expand, method)
        extra = flux, sky

    # Make trimming correction and return
    return ((y, x) + cen - trim), extra
Exemple #3
0
def centerdriver(method,
                 data,
                 guess,
                 trim,
                 radius,
                 size,
                 mask=None,
                 uncd=None,
                 fitbg=1,
                 maskstar=True,
                 expand=5.0,
                 psf=None,
                 psfctr=None,
                 noisepix=False,
                 npskyrad=(0, 0)):
    """
  Use the center method to find the center of a star in data, starting
  from position guess.
  
  Parameters:
  -----------
  method:   string
            Name of the centering method to use.
  data:     2D ndarray
            Array containing the star image.
  guess:    2 element 1D array
            y, x initial guess position of the target.
  trim:     integer
            Semi-length of the box around the target that will be trimmed.
  radius:   float
            Least-asymmetry parameter. See err_fasym_c.
  size:     float
            Least-asymmetry parameter. See err_fasym_c.  
  mask:     2D ndarray
            A mask array of bad pixels. Same shape as data.
  uncd:     2D ndarray
            An array containing the uncertainty values of data. Same
            shape as data.
  noisepix: bool
            Boolean flag to calculate and return noise pixels.
  npskyrad: 2 element iterable
            Radius of sky annuli used in noise pixel calculation
          
  Returns:
  --------
  A y,x tuple (scalars) with the coordinates of center of the target
  in data.
  
  Example:
  --------
  nica

  Modification History:
  ---------------------
  2010-11-23 patricio   Written by Patricio Cubillos
                        [email protected]
  2016-12-11 jh         Fixed None comparisons. Cleaned up docstring.
  2018-01-05 zacchaeus  updated for python3
                        [email protected]
  """

    # Default mask: all good
    if type(mask) == type(None):
        mask = np.ones(np.shape(data))

    # Default uncertainties: flat image
    if type(uncd) == type(None):
        uncd = np.ones(np.shape(data))

    # Trim the image if requested
    if trim != 0:
        # Integer part of center
        cen = np.rint(guess)
        # Center in the trimed image
        loc = (trim, trim)
        # Do the trim:
        img, msk, err = ie.trimimage(data,
                                     cen[0],
                                     cen[1],
                                     loc[0],
                                     loc[1],
                                     mask=mask,
                                     uncd=uncd)
    else:
        cen = np.array([0, 0])
        loc = np.rint(guess)
        img, msk, err = data, mask, uncd

    # If all data is bad:
    if not np.any(msk):
        raise Exception('Bad Frame Exception!')

    weights = 1.0 / np.abs(err)
    extra = []

    # Get the center with one of the methods:
    if method == 'fgc':
        par, err = g.fitgaussian(img,
                                 yxguess=loc,
                                 mask=msk,
                                 weights=weights,
                                 fitbg=fitbg,
                                 maskg=maskstar)
        y, x = par[2:4]
        #print('y: {:.3f}\tx: {:.3f}'.format(y, x))
        # array([yerr, xerr, ywidth, xwidth])
        extra = np.concatenate((err[2:4], par[0:2]))
    elif method == 'rfgc':
        par, err = g.rotfitgaussian(img,
                                    yxguess=loc,
                                    mask=msk,
                                    weights=weights,
                                    fitbg=fitbg,
                                    maskg=maskstar)
        y, x = par[2:4]
        #print('y: {:.3f}\tx: {:.3f}'.format(y, x))

        # array([yerr, xerr, ywidth, xwidth, rot])
        extra = np.concatenate((err[2:4], par[0:2], [par[5]]))
    elif method == 'col':
        y, x = cenlight.col(img, loc, npskyrad, mask=msk)


#    print(y, x)
    elif method == 'ccl':
        y, x = cenlight.ccl(img, trim, loc, npskyrad, mask=msk)
    elif method == 'lag':
        pos, asymarr = ctr.actr(img,
                                loc,
                                asym_rad=radius,
                                asym_size=size,
                                method='gaus')
        y = pos[0]
        x = pos[1]
    elif method == 'lac':
        pos, asymarr = ctr.actr(img,
                                loc,
                                asym_rad=radius,
                                asym_size=size,
                                method='col')
        y = pos[0]
        x = pos[1]
    elif method == 'bpf' or method == 'ipf':
        y, x, flux, sky = pf.spitzer_fit(img, msk, weights, psf, psfctr,
                                         expand, method)
        extra = flux, sky

    # Make trimming correction and return
    if noisepix == True:
        N = calcnoisepix(img, y, x, npskyrad, mask=msk)
        return ((y, x) + cen - trim), extra, N
    else:
        return ((y, x) + cen - trim), extra
Exemple #4
0
def photometry(event, pcf, photdir, mute, owd):

    tini = time.time()

    # Create photometry log
    logname = event.logname
    log = le.Logedit(photdir + "/" + logname, logname)
    log.writelog("\nStart " + photdir + " photometry: " + time.ctime())

    parentdir = os.getcwd() + "/"
    os.chdir(photdir)

    # Parse the attributes from the control file to the event:
    attrib = vars(pcf)
    keys = attrib.keys()
    for key in keys:
        setattr(event, key, attrib.get(key))

    maxnimpos, npos = event.maxnimpos, event.npos
    # allocating frame parameters:
    event.fp.aplev = np.zeros((npos, maxnimpos))
    event.fp.aperr = np.zeros((npos, maxnimpos))
    event.fp.nappix = np.zeros((npos, maxnimpos))
    event.fp.skylev = np.zeros((npos, maxnimpos))
    event.fp.skyerr = np.zeros((npos, maxnimpos))
    event.fp.nskypix = np.zeros((npos, maxnimpos))
    event.fp.nskyideal = np.zeros((npos, maxnimpos))
    event.fp.status = np.zeros((npos, maxnimpos))
    event.fp.good = np.zeros((npos, maxnimpos))

    # For interpolated aperture photometry, we need to "interpolate" the
    # mask, which requires float values. Thus, we convert the mask to
    # floats (this needs to be done before processes are spawned or memory
    # usage balloons).
    if event.mask.dtype != float:
        event.mask = event.mask.astype(float)

    # Aperture photometry:
    if event.phottype == "aper":  # not event.dooptimal or event.from_aper is None:

        # Multy Process set up:
        # Shared memory arrays allow only 1D Arrays :(
        aplev = Array("d", np.zeros(npos * maxnimpos))  # aperture flux
        aperr = Array("d", np.zeros(npos * maxnimpos))  # aperture error
        nappix = Array("d",
                       np.zeros(npos * maxnimpos))  # number of aperture pixels
        skylev = Array("d", np.zeros(npos * maxnimpos))  # sky level
        skyerr = Array("d", np.zeros(npos * maxnimpos))  # sky error
        nskypix = Array("d",
                        np.zeros(npos * maxnimpos))  # number of sky pixels
        nskyideal = Array("d", np.zeros(
            npos * maxnimpos))  # ideal number of sky pixels
        status = Array("d", np.zeros(npos * maxnimpos))  # apphot return status
        good = Array("d", np.zeros(npos * maxnimpos))  # good flag
        # Size of chunk of data each core will process:
        chunksize = maxnimpos // event.ncores + 1

        event.aparr = np.ones(npos * maxnimpos) * event.photap + event.offset

        print("Number of cores: " + str(event.ncores))
        # Start Muti Procecess:
        processes = []
        for nc in range(event.ncores):
            start = nc * chunksize  # Starting index to process
            end = (nc + 1) * chunksize  # Ending   index to process
            proc = Process(target=do_aphot,
                           args=(start, end, event, log, mute, aplev, aperr,
                                 nappix, skylev, skyerr, nskypix, nskyideal,
                                 status, good, 0))
            processes.append(proc)
            proc.start()

        # Make sure all processes finish their work:
        for nc in range(event.ncores):
            processes[nc].join()

        # Put the results in the event. I need to reshape them:
        event.fp.aplev = np.asarray(aplev).reshape(npos, maxnimpos)
        event.fp.aperr = np.asarray(aperr).reshape(npos, maxnimpos)
        event.fp.nappix = np.asarray(nappix).reshape(npos, maxnimpos)
        event.fp.skylev = np.asarray(skylev).reshape(npos, maxnimpos)
        event.fp.skyerr = np.asarray(skyerr).reshape(npos, maxnimpos)
        event.fp.nskypix = np.asarray(nskypix).reshape(npos, maxnimpos)
        event.fp.nskyideal = np.asarray(nskyideal).reshape(npos, maxnimpos)
        event.fp.status = np.asarray(status).reshape(npos, maxnimpos)
        event.fp.good = np.asarray(good).reshape(npos, maxnimpos)

        # raw photometry (no sky subtraction):
        event.fp.apraw = (event.fp.aplev + (event.fp.skylev * event.fp.nappix))

        # Print results into the log if it wasn't done before:
        for pos in range(npos):
            for i in range(event.nimpos[pos]):
                log.writelog(
                    '\nframe =%7d       ' % i + 'pos   =%5d       ' % pos +
                    'y =%7.3f       ' % event.fp.y[pos, i] +
                    'x =%7.3f' % event.fp.x[pos, i] + '\n' +
                    'aplev =%11.3f   ' % event.fp.aplev[pos, i] +
                    'aperr =%9.3f   ' % event.fp.aperr[pos, i] +
                    'nappix =%6.2f' % event.fp.nappix[pos, i] + '\n' +
                    'skylev=%11.3f   ' % event.fp.skylev[pos, i] +
                    'skyerr=%9.3f   ' % event.fp.skyerr[pos, i] +
                    'nskypix=%6.2f   ' % event.fp.nskypix[pos, i] +
                    'nskyideal=%6.2f' % event.fp.nskyideal[pos, i] + '\n' +
                    'status=%7d       ' % event.fp.status[pos, i] +
                    'good  =%5d' % event.fp.good[pos, i],
                    mute=True)

    elif event.phottype == "var":  # variable aperture radius

        # Multy Process set up:
        # Shared memory arrays allow only 1D Arrays :(
        aplev = Array("d", np.zeros(npos * maxnimpos))  # aperture flux
        aperr = Array("d", np.zeros(npos * maxnimpos))  # aperture error
        nappix = Array("d",
                       np.zeros(npos * maxnimpos))  # number of aperture pixels
        skylev = Array("d", np.zeros(npos * maxnimpos))  # sky level
        skyerr = Array("d", np.zeros(npos * maxnimpos))  # sky error
        nskypix = Array("d",
                        np.zeros(npos * maxnimpos))  # number of sky pixels
        nskyideal = Array("d", np.zeros(
            npos * maxnimpos))  # ideal number of sky pixels
        status = Array("d", np.zeros(npos * maxnimpos))  # apphot return status
        good = Array("d", np.zeros(npos * maxnimpos))  # good flag
        # Size of chunk of data each core will process:
        chunksize = maxnimpos // event.ncores + 1

        event.aparr = event.fp.noisepix[0]**.5 * event.photap + event.offset

        print("Number of cores: " + str(event.ncores))
        # Start Muti Procecess:
        processes = []
        for nc in range(event.ncores):
            start = nc * chunksize  # Starting index to process
            end = (nc + 1) * chunksize  # Ending   index to process
            proc = Process(target=do_aphot,
                           args=(start, end, event, log, mute, aplev, aperr,
                                 nappix, skylev, skyerr, nskypix, nskyideal,
                                 status, good, 0))
            processes.append(proc)
            proc.start()

        # Make sure all processes finish their work:
        for nc in range(event.ncores):
            processes[nc].join()

        # Put the results in the event. I need to reshape them:
        event.fp.aplev = np.asarray(aplev).reshape(npos, maxnimpos)
        event.fp.aperr = np.asarray(aperr).reshape(npos, maxnimpos)
        event.fp.nappix = np.asarray(nappix).reshape(npos, maxnimpos)
        event.fp.skylev = np.asarray(skylev).reshape(npos, maxnimpos)
        event.fp.skyerr = np.asarray(skyerr).reshape(npos, maxnimpos)
        event.fp.nskypix = np.asarray(nskypix).reshape(npos, maxnimpos)
        event.fp.nskyideal = np.asarray(nskyideal).reshape(npos, maxnimpos)
        event.fp.status = np.asarray(status).reshape(npos, maxnimpos)
        event.fp.good = np.asarray(good).reshape(npos, maxnimpos)

        # raw photometry (no sky subtraction):
        event.fp.apraw = (event.fp.aplev + (event.fp.skylev * event.fp.nappix))

        # Print results into the log if it wasn't done before:
        for pos in range(npos):
            for i in range(event.nimpos[pos]):
                log.writelog(
                    '\nframe =%7d       ' % i + 'pos   =%5d       ' % pos +
                    'y =%7.3f       ' % event.fp.y[pos, i] +
                    'x =%7.3f' % event.fp.x[pos, i] + '\n' +
                    'aplev =%11.3f   ' % event.fp.aplev[pos, i] +
                    'aperr =%9.3f   ' % event.fp.aperr[pos, i] +
                    'nappix =%6.2f' % event.fp.nappix[pos, i] + '\n' +
                    'skylev=%11.3f   ' % event.fp.skylev[pos, i] +
                    'skyerr=%9.3f   ' % event.fp.skyerr[pos, i] +
                    'nskypix=%6.2f   ' % event.fp.nskypix[pos, i] +
                    'nskyideal=%6.2f' % event.fp.nskyideal[pos, i] + '\n' +
                    'status=%7d       ' % event.fp.status[pos, i] +
                    'good  =%5d' % event.fp.good[pos, i],
                    mute=True)

    elif event.phottype == "ell":  # elliptical
        # Multy Process set up:
        # Shared memory arrays allow only 1D Arrays :(
        aplev = Array("d", np.zeros(npos * maxnimpos))  # aperture flux
        aperr = Array("d", np.zeros(npos * maxnimpos))  # aperture error
        nappix = Array("d",
                       np.zeros(npos * maxnimpos))  # number of aperture pixels
        skylev = Array("d", np.zeros(npos * maxnimpos))  # sky level
        skyerr = Array("d", np.zeros(npos * maxnimpos))  # sky error
        nskypix = Array("d",
                        np.zeros(npos * maxnimpos))  # number of sky pixels
        nskyideal = Array("d", np.zeros(
            npos * maxnimpos))  # ideal number of sky pixels
        status = Array("d", np.zeros(npos * maxnimpos))  # apphot return status
        good = Array("d", np.zeros(npos * maxnimpos))  # good flag
        # Size of chunk of data each core will process:
        chunksize = maxnimpos // event.ncores + 1

        print("Number of cores: " + str(event.ncores))
        # Start Muti Procecess:
        processes = []
        for nc in range(event.ncores):
            start = nc * chunksize  # Starting index to process
            end = (nc + 1) * chunksize  # Ending   index to process
            proc = Process(target=do_aphot,
                           args=(start, end, event, log, mute, aplev, aperr,
                                 nappix, skylev, skyerr, nskypix, nskyideal,
                                 status, good, 0))
            processes.append(proc)
            proc.start()

        # Make sure all processes finish their work:
        for nc in range(event.ncores):
            processes[nc].join()

        # Put the results in the event. I need to reshape them:
        event.fp.aplev = np.asarray(aplev).reshape(npos, maxnimpos)
        event.fp.aperr = np.asarray(aperr).reshape(npos, maxnimpos)
        event.fp.nappix = np.asarray(nappix).reshape(npos, maxnimpos)
        event.fp.skylev = np.asarray(skylev).reshape(npos, maxnimpos)
        event.fp.skyerr = np.asarray(skyerr).reshape(npos, maxnimpos)
        event.fp.nskypix = np.asarray(nskypix).reshape(npos, maxnimpos)
        event.fp.nskyideal = np.asarray(nskyideal).reshape(npos, maxnimpos)
        event.fp.status = np.asarray(status).reshape(npos, maxnimpos)
        event.fp.good = np.asarray(good).reshape(npos, maxnimpos)

        # raw photometry (no sky subtraction):
        event.fp.apraw = (event.fp.aplev + (event.fp.skylev * event.fp.nappix))

        # Print results into the log if it wasn't done before:
        for pos in range(npos):
            for i in range(event.nimpos[pos]):
                log.writelog(
                    '\nframe =%7d       ' % i + 'pos   =%5d       ' % pos +
                    'y =%7.3f       ' % event.fp.y[pos, i] +
                    'x =%7.3f' % event.fp.x[pos, i] + '\n' +
                    'aplev =%11.3f   ' % event.fp.aplev[pos, i] +
                    'aperr =%9.3f   ' % event.fp.aperr[pos, i] +
                    'nappix =%6.2f' % event.fp.nappix[pos, i] + '\n' +
                    'skylev=%11.3f   ' % event.fp.skylev[pos, i] +
                    'skyerr=%9.3f   ' % event.fp.skyerr[pos, i] +
                    'nskypix=%6.2f   ' % event.fp.nskypix[pos, i] +
                    'nskyideal=%6.2f' % event.fp.nskyideal[pos, i] + '\n' +
                    'status=%7d       ' % event.fp.status[pos, i] +
                    'good  =%5d' % event.fp.good[pos, i],
                    mute=True)

    elif event.phottype == "psffit":
        event.fp.aplev = event.fp.flux
        event.fp.skylev = event.fp.psfsky
        event.fp.good = np.zeros((event.npos, event.maxnimpos))
        for pos in range(event.npos):
            event.fp.good[pos, 0:event.nimpos[pos]] = 1

    elif event.phottype == "optimal":
        # utils for profile construction:
        pshape = np.array([2 * event.otrim + 1, 2 * event.otrim + 1])
        subpsf = np.zeros(np.asarray(pshape, int) * event.expand)
        x = np.indices(pshape)

        clock = t.Timer(np.sum(event.nimpos),
                        progress=np.array([0.05, 0.1, 0.25, 0.5, 0.75, 1.1]))

        for pos in range(npos):
            for i in range(event.nimpos[pos]):

                # Integer part of center of subimage:
                cen = np.rint([event.fp.y[pos, i], event.fp.x[pos, i]])
                # Center in the trimed image:
                loc = (event.otrim, event.otrim)
                # Do the trim:
                img, msk, err = ie.trimimage(event.data[i, :, :, pos],
                                             *cen,
                                             *loc,
                                             mask=event.mask[i, :, :, pos],
                                             uncd=event.uncd[i, :, :, pos])

                # Center of star in the subimage:
                ctr = (event.fp.y[pos, i] - cen[0] + event.otrim,
                       event.fp.x[pos, i] - cen[1] + event.otrim)

                # Make profile:
                # Index of the position in the supersampled PSF:
                pix = pf.pos2index(ctr, event.expand)
                profile, pctr = pf.make_psf_binning(event.psfim, pshape,
                                                    event.expand,
                                                    [pix[0], pix[1], 1.0, 0.0],
                                                    event.psfctr, subpsf)

                #subtract the sky level:
                img -= event.fp.psfsky[pos, i]
                # optimal photometry calculation:
                immean, uncert, good = op.optphot(img,
                                                  profile,
                                                  var=err**2.0,
                                                  mask=msk)

                event.fp.aplev[pos, i] = immean
                event.fp.aperr[pos, i] = uncert
                event.fp.skylev[pos, i] = event.fp.psfsky[pos, i]
                event.fp.good[pos, i] = good

                # Report progress:
                clock.check(np.sum(event.nimpos[0:pos]) + i,
                            name=event.centerdir)

    # START PREFLASH EDIT :::::::::::::::::::::::::::::::::::::

    # Do aperture on preflash data:
    if event.havepreflash:
        print("\nStart preflash photometry:")
        premaxnimpos = event.premaxnimpos
        preaplev = Array("d", np.zeros(npos * premaxnimpos))
        preaperr = Array("d", np.zeros(npos * premaxnimpos))
        prenappix = Array("d", np.zeros(npos * premaxnimpos))
        preskylev = Array("d", np.zeros(npos * premaxnimpos))
        preskyerr = Array("d", np.zeros(npos * premaxnimpos))
        preskynpix = Array("d", np.zeros(npos * premaxnimpos))
        preskyideal = Array("d", np.zeros(npos * premaxnimpos))
        prestatus = Array("d", np.zeros(npos * premaxnimpos))
        pregood = Array("d", np.zeros(npos * premaxnimpos))

        # Start Procecess:
        mute = False
        proc = Process(target=do_aphot,
                       args=(0, event.prenimpos[0], event, log, mute, preaplev,
                             preaperr, prenappix, preskylev, preskyerr,
                             preskynpix, preskyideal, prestatus, pregood, 1))
        proc.start()
        proc.join()

        # Put the results in the event. I need to reshape them:
        event.prefp.aplev = np.asarray(preaplev).reshape(npos, premaxnimpos)
        event.prefp.aperr = np.asarray(preaperr).reshape(npos, premaxnimpos)
        event.prefp.nappix = np.asarray(prenappix).reshape(npos, premaxnimpos)
        event.prefp.status = np.asarray(prestatus).reshape(npos, premaxnimpos)
        event.prefp.skylev = np.asarray(preskylev).reshape(npos, premaxnimpos)
        event.prefp.good = np.asarray(pregood).reshape(npos, premaxnimpos)

        # raw photometry (no sky subtraction):
        event.prefp.aplev = (event.prefp.aplev +
                             (event.prefp.skylev * event.prefp.nappix))
        # END PREFLASH EDIT :::::::::::::::::::::::::::::::::::::::

    if event.method in ["bpf"]:
        event.ispsf = False

    # PSF aperture correction:
    if event.ispsf and event.phottype == "aper":
        log.writelog('Calculating PSF aperture:')
        event.psfim = event.psfim.astype(np.float64)

        imerr = np.ones(np.shape(event.psfim))
        imask = np.ones(np.shape(event.psfim))
        skyfrac = 0.1

        event.aperfrac, ape, event.psfnappix, event.psfskylev, sle, \
             event.psfnskypix, event.psfnskyideal, event.psfstatus  \
                       = ap.apphot_c(event.psfim, imerr, imask,
                                     event.psfctr[0], event.psfctr[1],
                                     event.photap * event.psfexpand,
                                     event.skyin  * event.psfexpand,
                                     event.skyout * event.psfexpand,
                                     skyfrac, event.apscale, event.skymed)

        event.aperfrac += event.psfskylev * event.psfnappix

        event.fp.aplev /= event.aperfrac
        event.fp.aperr /= event.aperfrac

        log.writelog('Aperture contains %f of PSF.' % event.aperfrac)

    if event.ispsf and event.phottype == "var":
        log.writelog('Calculating PSF aperture:')
        event.psfim = event.psfim.astype(np.float64)

        imerr = np.ones(np.shape(event.psfim))
        imask = np.ones(np.shape(event.psfim))
        skyfrac = 0.1

        avgap = np.mean(event.aparr)

        event.aperfrac, ape, event.psfnappix, event.psfskylev, sle, \
             event.psfnskypix, event.psfnskyideal, event.psfstatus  \
                       = ap.apphot_c(event.psfim, imerr, imask,
                                     event.psfctr[0], event.psfctr[1],
                                     avgap        * event.psfexpand,
                                     event.skyin  * event.psfexpand,
                                     event.skyout * event.psfexpand,
                                     skyfrac, event.apscale, event.skymed)

        event.aperfrac += event.psfskylev * event.psfnappix

        event.fp.aplev /= event.aperfrac
        event.fp.aperr /= event.aperfrac

        log.writelog('Aperture contains %f of PSF.' % event.aperfrac)

    if event.ispsf and event.phottype == "ell":
        log.writelog('Calculating PSF aperture:')
        event.psfim = event.psfim.astype(np.float64)

        imerr = np.ones(np.shape(event.psfim))
        imask = np.ones(np.shape(event.psfim))
        skyfrac = 0.1

        avgxwid = np.mean(event.fp.xsig * event.photap)
        avgywid = np.mean(event.fp.ysig * event.photap)
        avgrot = np.mean(event.fp.rot)

        event.aperfrac, ape, event.psfnappix, event.psfskylev, sle, \
             event.psfnskypix, event.psfnskyideal, event.psfstatus  \
                       = ap.elphot_c(event.psfim, imerr, imask,
                                     event.psfctr[0], event.psfctr[1],
                                     avgxwid * event.psfexpand,
                                     avgywid * event.psfexpand,
                                     avgrot,
                                     event.skyin  * event.psfexpand,
                                     event.skyout * event.psfexpand,
                                     skyfrac, event.apscale, event.skymed)

        event.aperfrac += event.psfskylev * event.psfnappix

        event.fp.aplev /= event.aperfrac
        event.fp.aperr /= event.aperfrac

        log.writelog('Aperture contains %f of PSF.' % event.aperfrac)

    # Sadly we must do photometry for every aperture used
    # Possibly use a range and interpolate? Might be an option
    # for the future to speed this up.
    # This is commented out, as it seems to just remove the corrections
    # made by variable or elliptical photometry
    # if event.ispsf and (event.phottype == "var" or event.phottype == "ell"):
    #   log.writelog('Calculating PSF aperture. This may take some time.')
    #   event.psfim = event.psfim.astype(np.float64)

    #   imerr = np.ones(np.shape(event.psfim))
    #   imask = np.ones(np.shape(event.psfim))
    #   skyfrac = 0.1

    #   aperfrac     = Array("d", np.zeros(npos*maxnimpos))# psf flux
    #   aperfracerr  = Array("d", np.zeros(npos*maxnimpos))# psf flux error
    #   psfnappix    = Array("d", np.zeros(npos*maxnimpos))# psf aperture pix num
    #   psfsky       = Array("d", np.zeros(npos*maxnimpos))# psf sky level
    #   psfskyerr    = Array("d", np.zeros(npos*maxnimpos))# psf sky error
    #   psfnskypix   = Array("d", np.zeros(npos*maxnimpos))# psf sky pix num
    #   psfnskyideal = Array("d", np.zeros(npos*maxnimpos))# psf ideal sky pix num
    #   psfstatus    = Array("d", np.zeros(npos*maxnimpos))# psf return status
    #   psfgood      = Array("d", np.zeros(npos*maxnimpos))# psf good flag

    #   processes=[]
    #   for nc in range(event.ncores):
    #     start =  nc    * chunksize
    #     end   = (nc+1) * chunksize
    #     proc = Process(target=do_aphot_psf, args=(start, end, event, log, mute,
    #                                               aperfrac, aperfracerr,
    #                                               psfnappix,
    #                                               psfsky, psfskyerr,
    #                                               psfnskypix, psfnskyideal,
    #                                               psfstatus, psfgood))

    #     processes.append(proc)
    #     proc.start()

    #   for nc in range(event.ncores):
    #     processes[nc].join()

    #   # Reshape
    #   event.aperfrac     = np.asarray(aperfrac    ).reshape(npos,maxnimpos)
    #   event.aperfracerr  = np.asarray(aperfracerr ).reshape(npos,maxnimpos)
    #   event.psfnappix    = np.asarray(psfnappix   ).reshape(npos,maxnimpos)
    #   event.psfsky       = np.asarray(psfsky      ).reshape(npos,maxnimpos)
    #   event.psfskyerr    = np.asarray(psfskyerr   ).reshape(npos,maxnimpos)
    #   event.psfnskypix   = np.asarray(psfnskypix  ).reshape(npos,maxnimpos)
    #   event.psfnskyideal = np.asarray(psfnskyideal).reshape(npos,maxnimpos)
    #   event.psfstatus    = np.asarray(psfstatus   ).reshape(npos,maxnimpos)
    #   event.psfgood      = np.asarray(psfgood     ).reshape(npos,maxnimpos)

    #   event.aperfrac += event.psfsky * event.psfnappix

    #   event.fp.aplev /= event.aperfrac
    #   event.fp.aperr /= event.aperfrac

    #   log.writelog('Aperture contains average %f of PSF.'%np.mean(event.aperfrac))

    # save
    print("\nSaving ...")
    # denoised data:
    if event.denphot:
        killdata = 'dendata'
    else:
        killdata = 'data'
    me.saveevent(event,
                 event.eventname + "_pht",
                 delete=[killdata, 'uncd', 'mask'])

    # Print time elapsed and close log:
    cwd = os.getcwd() + "/"
    log.writelog("Output files (" + event.photdir + "):")
    log.writelog("Data:")
    log.writelog(" " + cwd + event.eventname + "_pht.dat")
    log.writelog("Log:")
    log.writelog(" " + cwd + logname)

    dt = t.hms_time(time.time() - tini)
    log.writeclose("\nEnd Photometry. Time (h:m:s):  %s " % dt + "  (" +
                   photdir + ")")
    print("--------------  ------------\n")

    os.chdir(owd)

    if event.runp5:
        os.system("python3 poet.py p5 %s/%s" %
                  (event.centerdir, event.photdir))
Exemple #5
0
def dooptphot(data,
              uncd,
              mask,
              fp,
              center,
              nimpos,
              rejlim=[1.45, 1, 0.005],
              itmax=20,
              trim=10,
              order=1,
              ftol=1e-8,
              resize=30,
              norm=1,
              log=None,
              psf=None):
    """
   Perform optimal photometry on a set of images.  

   Parameters
   ----------
   data:   4D array_like
           image array (im, x, y, pos)

   uncd:   4D array_like
           Array containing pixel uncertainties (same shape as data)

   mask: Array of same dimensions as data containing the bad
           pixel masks to be used in optimal photometry.  

   sratio: array_like
           Pixel scale ratios for each position in x and y. The
           array should have shape: (2, npos)

   psf:    Passed directly into CURVEFIT the psfdata image (handed
           through to CF_MIPS1_PSFCTR unmodified)

   rejlim: A 3-element array containing the cutoff values for chi
           square, sky-median(sky)(median taken per position), and
           sky error(above minimum sky error for that
           position). Images that produce values outside the
           cutoff range will be marked as such in IOSTATUS. The
           default values for these parameters are: 
           rejlim = [1.45, 1, 0.005]

   ftol:   Relative error desired in the sum of squares. Passed to
           scipy.optimize.leastsq.

   res:    passed into CURVEFIT

   trim:   Define half-width of sub-image

  
   Returns:
   -------
     Array containing a whole bunch of information. 

   OPTIONAL OUTPUTS:

   OSTATUS: An array that labels bad images (according to the
            criterion above- see REJLIM).An image that fails based on
            a high chi-square is labeled with a -1. A high or low sky
            level is labeled with a -10, and a high sky error is
            labeled with a -100.
  
   SIDE EFFECTS:
        This function defines pos, nx, maxnim, and nimpos if they arent
        already defined. 
  
    Examples
    --------
ofp = do.dooptphot(data, uncd, mask,  fp, center, nimpos,
              rejlim=[10.45, 10, 1.5], itmax=20, order=1,
              resize=30, norm=1)

pos = 0
plt.clf()
plt.plot(ofp.time[pos, 0:nimpos[pos]], fp.oskylev [pos, 0:nimpos[pos]], '+')
plt.plot(ofp.time[pos, 0:nimpos[pos]], fp.ophotlev[pos, 0:nimpos[pos]], '+')

   Revisions:
   ---------

   Written by Statia June 20, 2005

   2005-06-21 Statia   Added image rejection part.
   2005-07-14          Added sclpar keyword.
   2005-07-15          Distprf keyword.
   2008-03-07          Changed parinfo to fix xctr, yctr (to use values
                         from apphot).
   2008-06-03 Emily    Rewriting to use curvefit instead of mpfit,
                         as was done in mips1-3b-optphot.pro
   2008-06-05 Emily    (sloppy) MIPS correction for sky median rejection test
   2009-05-18 Kevin    Allowed curvefit to use subimages of data.
   2010-06-24 Patricio Converted to python.
  """

    tini = time.time()

    # pieces of apphot needed (from fp): x, y, aplev, skylev

    # Sizes
    maxnimpos, ny, nx, npos = np.shape(data)

    # initialize skyint and skyslope (used in calculating status and
    # returned if keywords set)
    skyint = np.zeros(npos)
    skyslope = np.zeros(npos)

    # Allocate space for the results
    fp.oxx = np.zeros((npos, maxnimpos))  # X position
    fp.oyy = np.zeros((npos, maxnimpos))  # Y position
    fp.oxerr = np.zeros((npos, maxnimpos))  # error in X position
    fp.oyerr = np.zeros((npos, maxnimpos))  # error in Y position
    fp.optlev = np.zeros((npos, maxnimpos))  # flux from curvefit
    fp.opterr = np.zeros((npos, maxnimpos))  # flux error curvefit
    fp.oskylev = np.zeros((npos, maxnimpos))  # sky level
    fp.oskyerr = np.zeros((npos, maxnimpos))  # sky error
    fp.ophotlev = np.zeros((npos, maxnimpos))  # flux from optphot
    fp.ophoterr = np.zeros((npos, maxnimpos))  # flux error from optphot
    fp.oniter = np.zeros((npos, maxnimpos))  # iteration number for curvefit
    fp.ofitstatus = np.zeros((npos, maxnimpos))  # status output from mpfiot
    fp.ocspdof = np.zeros((npos, maxnimpos))  # chi squared per dof
    # according to curvefit
    fp.ostatus = np.zeros((npos, maxnimpos))  # optphot return status
    # (formally reject)
    fp.ogood = np.zeros((npos, maxnimpos))  # good flag
    fp.orad = np.zeros((npos, maxnimpos))  # distance from nearest pix center

    # Get the PSF:
    if psf == None:
        psf = pb.psfbuild(data,
                          mask,
                          fp,
                          center,
                          nimpos,
                          resize=resize,
                          trim=trim)

    # Do photometry

    # The parameters to fit:
    # pars = [Y position, X position, aperture flux, sky flux level]
    pars = np.zeros(4)

    # Pixels of the centers
    yr, xr = center[0::2], center[1::2]  # integer values
    yoff = yr - trim
    xoff = xr - trim

    # Coordinates of the center of the psf in the subimage:
    psfyc, psfxc = fp.y[:, 0] - yoff, fp.x[:, 0] - xoff

    le.writelog('\nOptimal Photometry\n', log)
    # pos = 0
    # if True:
    for pos in np.arange(0, npos):
        for im in np.arange(0, nimpos[pos]):
            # calculate shifted, scaled PSF
            # should sky really be a free parameter at this point?

            # sub-image, sub-mask, sub-uncd
            subim, subma, subun = ie.trimimage(data[im, :, :,
                                                    pos], (yr[pos], xr[pos]),
                                               (trim, trim), mask[im, :, :,
                                                                  pos],
                                               uncd[im, :, :, pos])

            weights = 1.0 / subun**2.0
            # weights = 0.0 if uncd is huge, give points tiny value
            weights[np.where(weights == 0)] = np.mean(weights) / 100.0

            # The parameters to fit:
            pars[0] = fp.y[pos, im] - yoff[pos]  # Y position in the sub-image
            pars[1] = fp.x[pos, im] - xoff[pos]  # X position
            pars[2] = fp.aplev[pos, im]  # aperture flux
            pars[3] = fp.skylev[pos, im]  # sky flux level

            # center of the psf
            psfc = psfyc[pos], psfxc[pos]

            # Fit the PSF position, sky, and aperture flux level to the frame.
            fit, err, niter, csqpdof, stat = pf.psffit(subim,
                                                       weights,
                                                       psf[:, :, pos],
                                                       pars,
                                                       psfc,
                                                       order=order,
                                                       norm=norm)

            # Save the results of the fit
            fp.oyy[pos, im] = fit[0] + yoff[pos]
            fp.oyerr[pos, im] = err[0]
            fp.oxx[pos, im] = fit[1] + xoff[pos]
            fp.oxerr[pos, im] = err[1]
            fp.optlev[pos, im] = fit[2]
            fp.opterr[pos, im] = err[2]
            fp.oskylev[pos, im] = fit[3]
            fp.oskyerr[pos, im] = err[3]
            fp.oniter[pos, im] = niter
            fp.ocspdof[pos, im] = csqpdof
            fp.ofitstatus[pos, im] = stat

            subimpsf = pf.scalepsf(psf[:, :, pos], fit, np.shape(subim), psfc,
                                   order, norm)

            impsf = np.zeros((ny, nx))
            impsf = ie.pasteimage(impsf, (subimpsf - fp.oskylev[pos, im]) /
                                  fp.optlev[pos, im], (yr[pos], xr[pos]))

            # save yerror appropriately,
            # documentation for curvefit says yerror is "standard error between
            # yfit and y", what is this, really?

            fp.ophotlev[pos,im], fp.ophoterr[pos, im], profile, wght = \
                    op.optphot(data[im,:,:,pos] - fp.oskylev[pos,im],
                               impsf, var=uncd[im,:,:,pos]**2 + fp.oskyerr[pos,im]**2,
                               mask=mask[im,:,:,pos])

            le.writelog(
                '\n' + 'frame =%4d      ' % im + 'pos =%3d         ' % pos +
                'ocspdof =%11.3f  ' % fp.ocspdof[pos, im] +
                'niter   =%5d   ' % fp.oniter[pos, im] + '\n' +
                'y     =%8.3f  ' % fp.oyy[pos, im] +
                'yerr =%7.4f    ' % fp.oyerr[pos, im] +
                'flux    =%11.3f  ' % fp.ophotlev[pos, im] +
                'fluxerr =%9.3f  ' % fp.ophoterr[pos, im] + '\n' +
                'x     =%8.3f  ' % fp.oxx[pos, im] +
                'xerr =%7.4f    ' % fp.oxerr[pos, im] +
                'skylev  =%11.3f  ' % fp.oskylev[pos, im] +
                'skyerr  =%9.3f   ' % fp.oskyerr[pos, im], log)

        # Finding Bad Frames
        # Make rejection mask:
        #   0 = good;
        #   1 = chisq too high;
        #  10 = sky-median(sky) too high;
        # 100 = skyerror too high
        # It makes more sense if a bitmask, I don't know how to do that just now.

        # HIGH CHISQ
        loc = np.where(fp.ocspdof[pos, 0:nimpos[pos]] >= rejlim[0])
        if np.size(loc) != 0:
            fp.ostatus[pos, :][loc] -= 1
            le.writelog(
                str(np.size(loc)) + ' frames rejected for high chisq', log)

        # HIGH/LOW SKY RELATIVE TO SLOPE SUBTRACTED MEDIAN
        #FINDME: for MIPS, ignore first frames (code this more cleanly later)
        if (pos == 0) or (pos == 7):
            frames = np.where((np.arange(nimpos[pos]) % 6) != 0)
        else:
            frames = np.where((np.arange(nimpos[pos]) % 5) != 0)

        # Do a linear fit to the sky level as function of time.
        test = np.polyfit((fp.time[pos, 0:nimpos[pos]])[frames],
                          (fp.oskylev[pos, 0:nimpos[pos]])[frames], 1)

        skyint[pos] = test[1]
        skyslope[pos] = test[0]
        line = test[1] + test[0] * fp.time[pos, 0:nimpos[pos]]
        skydiff = np.abs(fp.oskylev[pos, 0:nimpos[pos]] - line)
        # print( skyint[pos], skyslope[pos] )
        # print( 'skylev', fp[ioskylev, 0:nimpos[pos]-1,pos]

        print('skydiff med: ' + str(np.median(skydiff)) + ', std: ' +
              str(np.std(skydiff)))
        loc = np.where(skydiff >= rejlim[1])
        if np.size(loc) != 0:
            fp.ostatus[pos, :][loc] -= 10
            le.writelog(
                str(np.size(loc)) + ' frames rejected for high/low sky level',
                log)

        # HIGH SKY ERROR
        y = fp.oskyerr[pos, 0:nimpos[pos]]
        loc = np.where(y >= rejlim[2] + np.amin(y))
        if np.size(loc) != 0:
            fp.ostatus[pos, :][loc] -= 100
            le.writelog(
                str(np.size(loc)) + ' frames rejected for sky error', log)

        print('rejection complete')

    fp.ogood[np.where(fp.ostatus == 0)] = 1

    # pixel R position
    fp.orad = np.sqrt((fp.oxx % 1.0 - 0.5)**2.0 + (fp.oyy % 1.0 - 0.5)**2.0)

    #le.writelog('optimal photometry time: %f minutes'%((time.time()-tini)/60), log)
    return fp, psf
Exemple #6
0
def psfbuild(data, mask, fp, center, nimpos, resize=30, trim=10):

  """

  The resampling uses scipy.ndimage.interpolation.zoom, the size of
  the result will have size = resize*size, the value of the corners
  coincide in both arrays.

  Work plan:

  + trim the images to a rectangular area around the star
  + bilinear interpolate images and masks
  + clip mask interpolation so that any mask value < 1 becomes 0
  + get centers from frameparameters (= from aperture photometry)
  + shift each image to align with center of first image
  + shift mask likewise
  + sum images
  + sum masks
  + multiply images by masks
  + psf = sum(image) / sum(mask)   (pixel-wise sum)
  + psf = psf - np.median(psf)    (to subtract sky)

import sys
sys.path.append('/home/patricio/ast/esp01/convert/lib/python')
import psfbuild as pb

import event      as ev
from loadevent import loadEvent
event = loadEvent('hd209bs51_ctr', load=['data','uncd','mask','event'])

psf = pb.psfbuild(event.data, event.mask, event.fp, event.srcest, 
                  event.nimpos, resize=20, trim=10)

fig = plt.figure(11)
plt.clf()
plt.imshow(psf[:,:,0], interpolation='nearest', origin='ll')
#plt.xlim(200,400)
#plt.ylim(200,400)
plt.colorbar()

  """

  tini = time.time()
  print('\nPSF Building:')

  mnpos, ny, nx, npos = np.shape(data)

  # Extract only a rectangular area around the star:
  subdata = np.zeros((mnpos, 2*trim+1, 2*trim+1, npos))
  submask = np.zeros((mnpos, 2*trim+1, 2*trim+1, npos))

  # Get shape of the sub-images
  sny, snx = np.shape(subdata[0,:,:,0])

  # Coordinates of the centers
  yc, xc = center[0::2], center[1::2]

  # Trim the image:
  for pos in np.arange(npos):
    for i in np.arange(mnpos):
      subdata[i,:,:,pos], submask[i,:,:,pos] = \
                   ie.trimimage( data[i,:,:,pos], (yc[pos],xc[pos]), 
                                 (trim, trim),    mask=mask[i,:,:,pos] )


  # Shape of resampled images:
  coory    = zoom(np.arange(sny)*1.0, resize, order=1)
  coorx    = zoom(np.arange(snx)*1.0, resize, order=1)
  rny, rnx = np.size(coory), np.size(coorx)


  # Get shifts according to centering:
  shifty = fp.y - fp.y[:,0:1]
  shiftx = fp.x - fp.x[:,0:1] 

  # Amount by which the images should be rolled to align them
  expandy = (rny-1.0)/(sny-1.0)
  expandx = (rnx-1.0)/(snx-1.0)
  rolly   = -np.round(shifty*expandy)
  rollx   = -np.round(shiftx*expandx)

  # Stupid python gets confused with -0 values!
  rolly[np.where(rolly==0)] = 0
  rollx[np.where(rollx==0)] = 0

  verbose = False
  if verbose:
    # Rounded shifts
    roundsy = -rolly/expandy
    roundsx = -rollx/expandx
    
    plt.figure(1,(10,5))
    plt.clf()
    plt.plot(shifty [3,:], 'r')
    plt.plot(roundsy[3,:], 'b')


    '''
    im  = 0
    pos = 0
    resize = 25
    z = zoom(subdata[i,:,:,pos], resize, order=1)
    z = zoom(subdata[i,:,:,pos], 501.0/sny, order=1)

    rny, rnx = (np.array([sny, snx]) - 1) * resize + 1

    print(np.shape(z))
    print(rny)

    q = zoom(z, 1./resize, order=1)

    resize=3
    z = zoom(x, 51./3,    order=1)
    q = zoom(z, 1./resize, order=1)
    q

    rny, rnx = (np.array([3, 3]) - 1) * (resize) + 1
    np.linspace(0, 3-1, rny)
    np.size(np.linspace(0, 3-1, rny))
    i2d.interp2d(x, expand=resize+1, order=0)

    coor = zoom(np.arange(sny)*1.0, resize, order=1)

    '''


  verbose = False
  if verbose:
    fig = plt.figure(5)
    plt.clf()
    plt.imshow(subdata[ 0,:,:,3], interpolation='nearest', origin='ll')
    plt.colorbar()

    fig = plt.figure(6)
    plt.clf()
    plt.imshow(subdata[36,:,:,3], interpolation='nearest', origin='ll') 
    plt.colorbar()

  nfig = 7

  # Allocate space for the resampled data
  rsdata = np.zeros((mnpos, rny, rnx, npos))
  rsmask = np.zeros((mnpos, rny, rnx, npos))

#  for i in np.arange(mnpos):
#    for pos in np.arange(npos):
  # Resample and align:
  for pos in np.arange(npos):
    for i in np.arange(nimpos[pos]):

      # Resample using linear interpolation:
      rsdata[i,:,:,pos] = zoom(subdata[i,:,:,pos], resize, order=1)
      rsmask[i,:,:,pos] = zoom(submask[i,:,:,pos], resize, order=1)
      rsmask[i,:,:,pos] = (rsmask[i,:,:,pos] == 1)

#       rsdata[i,:,:,pos] = i2d.interp2d(subdata[i,:,:,pos], expand=resize, 
#                                        y=y, x=x, yi=yi, xi=xi)
#       rsmask[i,:,:,pos] = i2d.interp2d(submask[i,:,:,pos], expand=resize, 
#                                        y=y, x=x, yi=yi, xi=xi)

#       fig = plt.figure(nfig)
#       nfig += 1
#       plt.clf()
#       plt.imshow(rsdata[i,:,:,pos], interpolation='nearest', origin='ll')
#       plt.xlim(250,350)
#       plt.ylim(250,350)
#       plt.colorbar()

      # Align the data using roll:
      rsdata[i,:,:,pos] = np.roll(np.roll(rsdata[i,:,:,pos], 
                                          int(rolly[pos,i]),axis=0), 
                                          int(rollx[pos,i]),axis=1)

      rsmask[i,:,:,pos] = np.roll(np.roll(rsmask[i,:,:,pos], 
                                          int(rolly[pos,i]),axis=0), 
                                          int(rollx[pos,i]),axis=1)
#      if i%15 == 0:  # progress
#        print(i)


  print('resizing time: %f seconds'%(time.time()-tini))

  verbose = False
  if verbose:
    fig = plt.figure(2)
    plt.clf()
    plt.imshow(rsmask[0,:,:,3], interpolation='nearest', origin='ll')
    plt.colorbar()

    fig = plt.figure(3)
    plt.clf()
    plt.imshow(rsmask[36,:,:,3], interpolation='nearest', origin='ll')
#    plt.xlim(250,350)
#    plt.ylim(250,350)
    plt.colorbar()

  verbose = False
  if verbose:
    fig = plt.figure(9)
    plt.clf()
    plt.imshow(rsdata[36,:,:,3], interpolation='nearest', origin='ll')
    #plt.xlim(250,350)
    #plt.ylim(250,350)
    plt.colorbar()


  # Multiply images by masks
  rsdata *= rsmask

  # Number of good values in each pixel
  ngood = np.sum(rsmask, axis=0)
  # Avoid dividing by 0
  loc = np.where(ngood == 0)
  ngood[loc] = 1.0

  # The PSF
  psf = np.sum(rsdata, axis=0) / ngood

  # Subtract the sky level:
  psf -= np.median(psf)

  # Fix bad pixels
  psf[loc] = 0.0

  # Normalize to sum(psf) = 1.0
  # psf /= np.sum(psf)

  # Plots:
  # plot(shifty[3,:])
  # resize  = 30


  return psf