Пример #1
0
    def test_readwrite_tractor(self):
        tractorfile = io.list_tractorfiles(self.datadir)[0]
        sweepfile = io.list_sweepfiles(self.datadir)[0]
        data = io.read_tractor(sweepfile)
        self.assertEqual(len(data), 6)  #- test data has 6 objects per file
        data = io.read_tractor(tractorfile)
        self.assertEqual(len(data), 6)  #- test data has 6 objects per file
        data, hdr = io.read_tractor(tractorfile, header=True)
        self.assertEqual(len(data), 6)  #- test data has 6 objects per file

        #ADM check PHOTSYS got added in writing targets
        io.write_targets(self.testfile, data, indir=self.datadir)
        #ADM use fits read wrapper in io to correctly handle whitespace
        d2, h2 = io.whitespace_fits_read(self.testfile, header=True)
        self.assertEqual(
            list(data.dtype.names) + ["PHOTSYS"], list(d2.dtype.names))

        #ADM check PHOTSYS and HPXPIXEL got added writing targets with NSIDE request
        io.write_targets(self.testfile, data, nside=64, indir=self.datadir)
        #ADM use fits read wrapper in io to correctly handle whitespace
        d2, h2 = io.whitespace_fits_read(self.testfile, header=True)
        self.assertEqual(
            list(data.dtype.names) + ["HPXPIXEL", "PHOTSYS"],
            list(d2.dtype.names))

        for column in data.dtype.names:
            self.assertTrue(np.all(data[column] == d2[column]))
Пример #2
0
    def test_fix_dr1(self):
        '''test the DR1 TYPE dype fix (make everything S4)'''
        #- First, break it
        files = io.list_sweepfiles(self.datadir)
        objects = io.read_tractor(files[0])
        dt = objects.dtype.descr
        for i in range(len(dt)):
            if dt[i][0] == 'TYPE':
                dt[i] = ('TYPE', 'S10')
                break
        badobjects = objects.astype(np.dtype(dt))

        newobjects = io.fix_tractor_dr1_dtype(badobjects)
        self.assertEqual(newobjects['TYPE'].dtype, np.dtype('S4'))
Пример #3
0
def collect_bright_stars(
        bands,
        maglim,
        numproc=4,
        rootdirname='/global/project/projectdirs/cosmo/data/legacysurvey/dr3.1/sweep/3.1',
        outfilename=None):
    """Extract a structure from the sweeps containing only bright stars in a given band to a given magnitude limit

    Parameters
    ----------
    bands : :class:`str`
        A magnitude band from the sweeps, e.g., "G", "R", "Z".
        Can pass multiple bands as string, e.g. "GRZ", in which case maglim has to be a
        list of the same length as the string
    maglim : :class:`float`
        The upper limit in that magnitude band for which to assemble a list of bright stars.
        Can pass a list of magnitude limits, in which case bands has to be a string of the
        same length (e.g., "GRZ" for [12.3,12.7,12.6]
    numproc : :class:`int`, optional
        Number of processes over which to parallelize
    rootdirname : :class:`str`, optional, defaults to dr3
        Root directory containing either sweeps or tractor files...e.g. for dr3 this might be
        /global/project/projectdirs/cosmo/data/legacysurvey/dr3/sweeps/dr3.1
    outfilename : :class:`str`, optional, defaults to not writing anything to file
        (FITS) File name to which to write the output structure of bright stars

    Returns
    -------
    :class:`recarray`
        The structure of bright stars from the sweeps limited in the passed band(s) to the
        passed maglim(s).
    """
    #ADM set up default logger
    from lvmutil.log import get_logger
    log = get_logger()

    #ADM use io.py to retrieve list of sweeps or tractor files
    infiles = io.list_sweepfiles(rootdirname)
    if len(infiles) == 0:
        infiles = io.list_tractorfiles(rootdirname)
    if len(infiles) == 0:
        raise IOError(
            'No sweep or tractor files found in {}'.format(rootdirname))

    #ADM force the input maglim to be a list (in case a single value was passed)
    if type(maglim) == type(16) or type(maglim) == type(16.):
        maglim = [maglim]

    #ADM set bands to uppercase if passed as lower case
    bands = bands.upper()
    #ADM the band names as a flux array instead of a string
    bandnames = np.array(["FLUX_" + band for band in bands])

    if len(bandnames) != len(maglim):
        raise IOError(
            'bands has to be the same length as maglim and {} does not equal {}'
            .format(len(bands), len(maglim)))

    #ADM change input magnitude(s) to a flux to test against
    fluxlim = 10.**((22.5 - np.array(maglim)) / 2.5)

    #ADM parallel formalism from this step forward is stolen from cuts.select_targets

    #ADM function to grab the bright stars from a given file
    def _get_bright_stars(filename):
        '''Retrieves bright stars from a sweeps/Tractor file'''
        objs = io.read_tractor(filename)
        #ADM write the fluxes as an array instead of as named columns
        fluxes = objs[bandnames].view(
            objs[bandnames].dtype[0]).reshape(objs[bandnames].shape + (-1, ))
        #ADM Retain rows for which ANY band is brighter than maglim
        w = np.where(np.any(fluxes > fluxlim, axis=1))
        if len(w[0]) > 0:
            return objs[w]

    #ADM counter for how many files have been processed
    #ADM critical to use np.ones because a numpy scalar allows in place modifications
    # c.f https://www.python.org/dev/peps/pep-3104/
    totfiles = np.ones((), dtype='i8') * len(infiles)
    nfiles = np.ones((), dtype='i8')
    t0 = time()
    log.info('Collecting bright stars from sweeps...')

    def _update_status(result):
        '''wrapper function for the critical reduction operation,
        that occurs on the main parallel process'''
        if nfiles % 25 == 0:
            elapsed = time() - t0
            rate = nfiles / elapsed
            log.info(
                '{}/{} files; {:.1f} files/sec; {:.1f} total mins elapsed'.
                format(nfiles, totfiles, rate, elapsed / 60.))
        nfiles[...] += 1  #this is an in-place modification
        return result

    #ADM did we ask to parallelize, or not?
    if numproc > 1:
        pool = sharedmem.MapReduce(np=numproc)
        with pool:
            starstruc = pool.map(_get_bright_stars,
                                 infiles,
                                 reduce=_update_status)
    else:
        starstruc = []
        for file in infiles:
            starstruc.append(_update_status(_get_bright_stars(file)))

    #ADM note that if there were no bright stars in a file then
    #ADM the _get_bright_stars function will have returned NoneTypes
    #ADM so we need to filter those out
    starstruc = [x for x in starstruc if x is not None]
    if len(starstruc) == 0:
        raise IOError(
            'There are no stars brighter than {} in {} in files in {} with which to make a mask'
            .format(str(maglim), bands, rootdirname))
    #ADM concatenate all of the output recarrays
    starstruc = np.hstack(starstruc)

    #ADM if the name of a file for output is passed, then write to it
    if outfilename is not None:
        fitsio.write(outfilename, starstruc, clobber=True)

    return starstruc
Пример #4
0
 def test_list_sweepfiles(self):
     files = io.list_sweepfiles(self.datadir)
     self.assertEqual(len(files), 3)
     for x in files:
         self.assertTrue(os.path.basename(x).startswith('sweep'))
         self.assertTrue(os.path.basename(x).endswith('.fits'))
Пример #5
0
 def setUpClass(cls):
     cls.datadir = resource_filename('lvmtarget.test', 't')
     cls.tractorfiles = sorted(io.list_tractorfiles(cls.datadir))
     cls.sweepfiles = sorted(io.list_sweepfiles(cls.datadir))