def test_pixel_coords(self):
        """
        Test that pixelCoordsFromRaDecLSST with non-zero proper motion etc.
        agrees with pixelCoordsFromPupilCoords when pupilCoords are
        calculated with the same proper motion, etc.
        """
        (obs, ra_list, dec_list, pm_ra_list, pm_dec_list, parallax_list,
         v_rad_list) = self.set_data(26)

        for is_none in ('pm_ra', 'pm_dec', 'parallax', 'v_rad'):
            pm_ra = pm_ra_list
            pm_dec = pm_dec_list
            parallax = parallax_list
            v_rad = v_rad_list

            if is_none == 'pm_ra':
                pm_ra = None
            elif is_none == 'pm_dec':
                pm_dec = None
            elif is_none == 'parallax':
                parallax = None
            elif is_none == 'v_rad':
                v_rad = None

            xp, yp = pupilCoordsFromRaDec(ra_list,
                                          dec_list,
                                          pm_ra=pm_ra,
                                          pm_dec=pm_dec,
                                          parallax=parallax,
                                          v_rad=v_rad,
                                          obs_metadata=obs)

            xpx_control, ypx_control = pixelCoordsFromPupilCoords(
                xp, yp, camera=self.camera)

            xpx_test, ypx_test = pixelCoordsFromRaDecLSST(ra_list,
                                                          dec_list,
                                                          pm_ra=pm_ra,
                                                          pm_dec=pm_dec,
                                                          parallax=parallax,
                                                          v_rad=v_rad,
                                                          obs_metadata=obs)

            xpx_radians, ypx_radians = _pixelCoordsFromRaDecLSST(
                np.radians(ra_list),
                np.radians(dec_list),
                pm_ra=radiansFromArcsec(pm_ra),
                pm_dec=radiansFromArcsec(pm_dec),
                parallax=radiansFromArcsec(parallax),
                v_rad=v_rad,
                obs_metadata=obs)

            np.testing.assert_array_equal(xpx_control, xpx_test)
            np.testing.assert_array_equal(ypx_control, ypx_test)
            np.testing.assert_array_equal(xpx_control, xpx_radians)
            np.testing.assert_array_equal(ypx_control, ypx_radians)
            self.assertLess(len(np.where(np.isnan(xpx_control))[0]),
                            len(xpx_test) / 4)
            self.assertLess(len(np.where(np.isnan(ypx_control))[0]),
                            len(ypx_test) / 4)
Пример #2
0
def chipNameFromRaDec(ra, dec, pm_ra=None, pm_dec=None, parallax=None, v_rad=None,
                      obs_metadata=None, camera=None,
                      epoch=2000.0, allow_multiple_chips=False):
    """
    Return the names of detectors that see the object specified by
    (RA, Dec) in degrees.

    @param [in] ra in degrees (a numpy array or a float).
    In the International Celestial Reference System.

    @param [in] dec in degrees (a numpy array or a float).
    In the International Celestial Reference System.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in arcsec
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).

    @param [in] obs_metadata is an ObservationMetaData characterizing the telescope pointing

    @param [in] epoch is the epoch in Julian years of the equinox against which RA and Dec are
    measured.  Default is 2000.

    @param [in] camera is an afw.cameraGeom camera instance characterizing the camera

    @param [in] allow_multiple_chips is a boolean (default False) indicating whether or not
    this method will allow objects to be visible on more than one chip.  If it is 'False'
    and an object appears on more than one chip, an exception will be raised.  If it is 'True'
    and an object falls on more than one chip, it will still only return the first chip in the
    list of chips returned. THIS BEHAVIOR SHOULD BE FIXED IN A FUTURE TICKET.

    @param [out] a numpy array of chip names
    """
    if pm_ra is not None:
        pm_ra_out = radiansFromArcsec(pm_ra)
    else:
        pm_ra_out = None

    if pm_dec is not None:
        pm_dec_out = radiansFromArcsec(pm_dec)
    else:
        pm_dec_out = None

    if parallax is not None:
        parallax_out = radiansFromArcsec(parallax)
    else:
        parallax_out = None

    return _chipNameFromRaDec(np.radians(ra), np.radians(dec),
                              pm_ra=pm_ra_out, pm_dec=pm_dec_out,
                              parallax=parallax_out, v_rad=v_rad,
                              obs_metadata=obs_metadata, epoch=epoch,
                              camera=camera, allow_multiple_chips=allow_multiple_chips)
def chipNameFromRaDecLSST(ra, dec, pm_ra=None, pm_dec=None, parallax=None, v_rad=None,
                          obs_metadata=None, epoch=2000.0, allow_multiple_chips=False):
    """
    Return the names of detectors on the LSST camera that see the object specified by
    (RA, Dec) in degrees.

    @param [in] ra in degrees (a numpy array or a float).
    In the International Celestial Reference System.

    @param [in] dec in degrees (a numpy array or a float).
    In the International Celestial Reference System.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in arcsec
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).

    @param [in] obs_metadata is an ObservationMetaData characterizing the telescope pointing

    @param [in] epoch is the epoch in Julian years of the equinox against which RA and Dec are
    measured.  Default is 2000.

    @param [in] allow_multiple_chips is a boolean (default False) indicating whether or not
    this method will allow objects to be visible on more than one chip.  If it is 'False'
    and an object appears on more than one chip, only the first chip will appear in the list of
    chipNames but NO WARNING WILL BE EMITTED.  If it is 'True' and an object falls on more than one
    chip, a list of chipNames will appear for that object.

    @param [out] the name(s) of the chips on which ra, dec fall (will be a numpy
    array if more than one)
    """
    if pm_ra is not None:
        pm_ra_out = radiansFromArcsec(pm_ra)
    else:
        pm_ra_out = None

    if pm_dec is not None:
        pm_dec_out = radiansFromArcsec(pm_dec)
    else:
        pm_dec_out = None

    if parallax is not None:
        parallax_out = radiansFromArcsec(parallax)
    else:
        parallax_out = None

    return _chipNameFromRaDecLSST(np.radians(ra), np.radians(dec),
                                  pm_ra=pm_ra_out, pm_dec=pm_dec_out,
                                  parallax=parallax_out, v_rad=v_rad,
                                  obs_metadata=obs_metadata, epoch=epoch,
                                  allow_multiple_chips=allow_multiple_chips)
Пример #4
0
def focalPlaneCoordsFromRaDec(ra, dec, pm_ra=None, pm_dec=None, parallax=None, v_rad=None,
                              obs_metadata=None, epoch=2000.0, camera=None):
    """
    Get the focal plane coordinates for all objects in the catalog.

    @param [in] ra is in degrees in the International Celestial Reference System.
    Can be either a float or a numpy array.

    @param [in] dec is in degrees in the International Celestial Reference System.
    Can be either a float or a numpy array.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in arcsec
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).

    @param [in] obs_metadata is an ObservationMetaData object describing the telescope
    pointing (only if specifying RA and Dec rather than pupil coordinates)

    @param [in] epoch is the julian epoch of the mean equinox used for coordinate transformations
    (in years; only if specifying RA and Dec rather than pupil coordinates; default is 2000)

    @param [in] camera is an afw.cameraGeom camera object

    @param [out] a 2-D numpy array in which the first row is the x
    focal plane coordinate and the second row is the y focal plane
    coordinate (both in millimeters)
    """

    if pm_ra is not None:
        pm_ra_out = radiansFromArcsec(pm_ra)
    else:
        pm_ra_out = None

    if pm_dec is not None:
        pm_dec_out = radiansFromArcsec(pm_dec)
    else:
        pm_dec_out = None

    if parallax is not None:
        parallax_out = radiansFromArcsec(parallax)
    else:
        parallax_out = None

    return _focalPlaneCoordsFromRaDec(np.radians(ra), np.radians(dec),
                                      pm_ra=pm_ra_out, pm_dec=pm_dec_out,
                                      parallax=parallax_out, v_rad=v_rad,
                                      obs_metadata=obs_metadata, epoch=epoch,
                                      camera=camera)
def observedFromICRS(ra, dec, pm_ra=None, pm_dec=None, parallax=None, v_rad=None,
                     obs_metadata=None, epoch=None, includeRefraction=True):
    """
    Convert mean position (RA, Dec) in the International Celestial Reference Frame
    to observed (RA, Dec).

    included are precession-nutation, aberration, proper motion, parallax, refraction,
    radial velocity, diurnal aberration.

    This method works in degrees.

    @param [in] ra is the unrefracted RA in degrees (ICRS).  Must be a numpy array.

    @param [in] dec is the unrefracted Dec in degrees (ICRS).  Must be a numpy array.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (arcsec/yr)

    @param [in] pm_dec is proper motion in dec (arcsec/yr)

    @param [in] parallax is parallax in arcsec

    @param [in] v_rad is radial velocity (km/s)

    @param [in] obs_metadata is an ObservationMetaData object describing the
    telescope pointing.

    @param [in] epoch is the julian epoch (in years) against which the mean
    equinoxes are measured.

    @param [in] includeRefraction toggles whether or not to correct for refraction

    @param [out] a 2-D numpy array in which the first row is the observed
    RA and the second row is the observed Dec (both in degrees)
    """

    if pm_ra is not None:
        pm_ra_in = radiansFromArcsec(pm_ra)
    else:
        pm_ra_in = None

    if pm_dec is not None:
        pm_dec_in = radiansFromArcsec(pm_dec)
    else:
        pm_dec_in = None

    if parallax is not None:
        parallax_in = radiansFromArcsec(parallax)
    else:
        parallax_in = None

    output = _observedFromICRS(numpy.radians(ra), numpy.radians(dec),
                               pm_ra=pm_ra_in, pm_dec=pm_dec_in, parallax=parallax_in,
                               v_rad=v_rad, obs_metadata=obs_metadata, epoch=epoch,
                               includeRefraction=includeRefraction)

    return numpy.degrees(output)
    def test_chip_name(self):
        """
        Test that chipNameFromRaDecLSST with non-zero proper motion etc.
        agrees with chipNameFromPupilCoords when pupilCoords are
        calculated with the same proper motion, etc.
        """
        (obs, ra_list, dec_list, pm_ra_list, pm_dec_list, parallax_list,
         v_rad_list) = self.set_data(11)

        for is_none in ('pm_ra', 'pm_dec', 'parallax', 'v_rad'):
            pm_ra = pm_ra_list
            pm_dec = pm_dec_list
            parallax = parallax_list
            v_rad = v_rad_list

            if is_none == 'pm_ra':
                pm_ra = None
            elif is_none == 'pm_dec':
                pm_dec = None
            elif is_none == 'parallax':
                parallax = None
            elif is_none == 'v_rad':
                v_rad = None

            xp, yp = pupilCoordsFromRaDec(ra_list,
                                          dec_list,
                                          pm_ra=pm_ra,
                                          pm_dec=pm_dec,
                                          parallax=parallax,
                                          v_rad=v_rad,
                                          obs_metadata=obs)

            name_control = chipNameFromPupilCoords(xp, yp, camera=self.camera)

            name_test = chipNameFromRaDecLSST(ra_list,
                                              dec_list,
                                              pm_ra=pm_ra,
                                              pm_dec=pm_dec,
                                              parallax=parallax,
                                              v_rad=v_rad,
                                              obs_metadata=obs)

            name_radians = _chipNameFromRaDecLSST(
                np.radians(ra_list),
                np.radians(dec_list),
                pm_ra=radiansFromArcsec(pm_ra),
                pm_dec=radiansFromArcsec(pm_dec),
                parallax=radiansFromArcsec(parallax),
                v_rad=v_rad,
                obs_metadata=obs)

            np.testing.assert_array_equal(name_control, name_test)
            np.testing.assert_array_equal(name_control, name_radians)
            self.assertGreater(len(np.unique(name_control.astype(str))), 4)
            self.assertLess(len(np.where(np.equal(name_control, None))[0]),
                            len(name_control) / 4)
 def setUp(self):
     self.nStars = 10
     np.random.seed(8273)
     self.raList = np.random.random_sample(self.nStars)*2.0*np.pi
     self.decList = (np.random.random_sample(self.nStars)-0.5)*np.pi
     self.mjdList = np.random.random_sample(10)*5000.0 + 52000.0
     self.pm_raList = utils.radiansFromArcsec(np.random.random_sample(self.nStars)*10.0 - 5.0)
     self.pm_decList = utils.radiansFromArcsec(np.random.random_sample(self.nStars)*10.0 - 5.0)
     self.pxList = utils.radiansFromArcsec(np.random.random_sample(self.nStars)*2.0)
     self.v_radList = np.random.random_sample(self.nStars)*500.0 - 250.0
Пример #8
0
def applyProperMotion(ra,
                      dec,
                      pm_ra,
                      pm_dec,
                      parallax,
                      v_rad,
                      epoch=2000.0,
                      mjd=None):
    """Applies proper motion between two epochs.

    units:  ra (degrees), dec (degrees), pm_ra (arcsec/year), pm_dec
    (arcsec/year), parallax (arcsec), v_rad (km/sec, positive if receding),
    epoch (Julian years)

    Returns corrected ra and dec (in radians)

    The function palpy.pm does not work properly if the parallax is below
    0.00045 arcseconds

    @param [in] ra in degrees.  Can be a number or a numpy array (not a list).

    @param [in] dec in degrees.  Can be a number or a numpy array (not a list).

    @param [in] pm_ra is ra proper motion multiplied by cos(Dec) in arcsec/year.
    Can be a number or a numpy array (not a list).

    @param [in] pm_dec is dec proper motion in arcsec/year.
    Can be a number or a numpy array (not a list).

    @param [in] parallax in arcsec. Can be a number or a numpy array (not a list).

    @param [in] v_rad is radial velocity in km/sec (positive if the object is receding).
    Can be a number or a numpy array (not a list).

    @param [in] epoch is epoch in Julian years (default: 2000.0)

    @param [in] mjd is an instantiation of the ModifiedJulianDate class
    representing the date of the observation

    @param [out] a 2-D numpy array in which the first row is the RA corrected
    for proper motion and the second row is the Dec corrected for proper motion
    (both in degrees)
    """

    output = _applyProperMotion(np.radians(ra),
                                np.radians(dec),
                                radiansFromArcsec(pm_ra),
                                radiansFromArcsec(pm_dec),
                                radiansFromArcsec(parallax),
                                v_rad,
                                epoch=epoch,
                                mjd=mjd)

    return np.degrees(output)
def appGeoFromICRS(ra, dec, pm_ra=None, pm_dec=None, parallax=None,
                   v_rad=None, epoch=2000.0, mjd = None):
    """
    Convert the mean position (RA, Dec) in the International Celestial Reference
    System (ICRS) to the mean apparent geocentric position

    units:  ra (degrees), dec (degrees), pm_ra (arcsec/year), pm_dec
    (arcsec/year), parallax (arcsec), v_rad (km/sec; positive if receding),
    epoch (Julian years)

    @param [in] ra in degrees (ICRS).  Must be a numpy array.

    @param [in] dec in degrees (ICRS).  Must be a numpy array.

    @param [in] pm_ra is ra proper motion multiplied by cos(Dec) in arcsec/year

    @param [in] pm_dec is dec proper motion in arcsec/year

    @param [in] parallax in arcsec

    @param [in] v_rad is radial velocity in km/sec (positive if the object is receding)

    @param [in] epoch is the julian epoch (in years) of the equinox against which to
    measure RA (default: 2000.0)

    @param [in] mjd is an instantiation of the ModifiedJulianDate class
    representing the date of the observation

    @param [out] a 2-D numpy array in which the first row is the apparent
    geocentric RA and the second row is the apparent geocentric Dec (both in degrees)
    """

    if pm_ra is not None:
        pm_ra_in = radiansFromArcsec(pm_ra)
    else:
        pm_ra_in = None

    if pm_dec is not None:
        pm_dec_in = radiansFromArcsec(pm_dec)
    else:
        pm_dec_in = None

    if parallax is not None:
        px_in = radiansFromArcsec(parallax)
    else:
        px_in = None

    output = _appGeoFromICRS(numpy.radians(ra), numpy.radians(dec),
                             pm_ra=pm_ra_in, pm_dec=pm_dec_in,
                             parallax=px_in, v_rad=v_rad, epoch=epoch, mjd=mjd)


    return numpy.degrees(output)
Пример #10
0
    def test_pixel_coords(self):
        """
        Test that pixelCoordsFromRaDecLSST with non-zero proper motion etc.
        agrees with pixelCoordsFromPupilCoords when pupilCoords are
        calculated with the same proper motion, etc.
        """
        (obs, ra_list, dec_list,
         pm_ra_list, pm_dec_list,
         parallax_list, v_rad_list) = self.set_data(26)

        for is_none in ('pm_ra', 'pm_dec', 'parallax', 'v_rad'):
            pm_ra = pm_ra_list
            pm_dec = pm_dec_list
            parallax = parallax_list
            v_rad = v_rad_list

            if is_none == 'pm_ra':
                pm_ra = None
            elif is_none == 'pm_dec':
                pm_dec = None
            elif is_none == 'parallax':
                parallax = None
            elif is_none == 'v_rad':
                v_rad = None

            xp, yp = pupilCoordsFromRaDec(ra_list, dec_list,
                                          pm_ra=pm_ra, pm_dec=pm_dec,
                                          parallax=parallax, v_rad=v_rad,
                                          obs_metadata=obs)

            xpx_control, ypx_control = pixelCoordsFromPupilCoords(xp, yp, camera=self.camera,
                                                                  includeDistortion=False)

            xpx_test, ypx_test = pixelCoordsFromRaDecLSST(ra_list, dec_list,
                                                          pm_ra=pm_ra, pm_dec=pm_dec,
                                                          parallax=parallax, v_rad=v_rad,
                                                          obs_metadata=obs,
                                                          includeDistortion=False)

            xpx_radians, ypx_radians = _pixelCoordsFromRaDecLSST(np.radians(ra_list), np.radians(dec_list),
                                                                 pm_ra=radiansFromArcsec(pm_ra),
                                                                 pm_dec=radiansFromArcsec(pm_dec),
                                                                 parallax=radiansFromArcsec(parallax),
                                                                 v_rad=v_rad, obs_metadata=obs,
                                                                 includeDistortion=False)

            np.testing.assert_array_equal(xpx_control, xpx_test)
            np.testing.assert_array_equal(ypx_control, ypx_test)
            np.testing.assert_array_equal(xpx_control, xpx_radians)
            np.testing.assert_array_equal(ypx_control, ypx_radians)
            self.assertLess(len(np.where(np.isnan(xpx_control))[0]), len(xpx_test)/4)
            self.assertLess(len(np.where(np.isnan(ypx_control))[0]), len(ypx_test)/4)
Пример #11
0
 def setUp(self):
     self.nStars = 10
     self.rng = np.random.RandomState(8273)
     self.raList = self.rng.random_sample(self.nStars) * 2.0 * np.pi
     self.decList = (self.rng.random_sample(self.nStars) - 0.5) * np.pi
     self.mjdList = self.rng.random_sample(10) * 5000.0 + 52000.0
     self.pm_raList = utils.radiansFromArcsec(
         self.rng.random_sample(self.nStars) * 10.0 - 5.0)
     self.pm_decList = utils.radiansFromArcsec(
         self.rng.random_sample(self.nStars) * 10.0 - 5.0)
     self.pxList = utils.radiansFromArcsec(
         self.rng.random_sample(self.nStars) * 2.0)
     self.v_radList = self.rng.random_sample(self.nStars) * 500.0 - 250.0
Пример #12
0
def create_text_catalog(obs, file_name, raDisplacement, decDisplacement, \
                        hlr=None, mag_norm=None, pa=None):
    """
    Create a text file containing objects that can be read in by a fileDBObject class.

    @param [in] obs is an ObservationMetaData specifying the pointing on which the catalog
    will be centered

    @param [in] file_name is the name of the file to be created.  If a file already exists with that
    name, throw an error.

    @param [in] raDisplacement is a numpy array listing the RA displacements of objects from the
    pointing's center in arcseconds

    @param [in] decDisplacement is a numpy array listing the Dec displacements of objects from the
    pointings' center in arcseconds

    @param [in] hlr is an optional list of half light radii in arcseconds

    @param [in] mag_norm is an optional list of the objects' magnitude normalizations

    @param [in] pa is an optional list of the objects' position angles in degrees
    """

    if os.path.exists(file_name):
        os.unlink(file_name)

    raDisplacementList = radiansFromArcsec(raDisplacement)
    decDisplacementList = radiansFromArcsec(decDisplacement)

    if hlr is None:
        hlr = [2.0] * len(raDisplacement)

    if mag_norm is None:
        mag_norm = [20.0] * len(raDisplacement)

    if pa is None:
        pa = [0.0] * len(raDisplacement)

    with open(file_name, 'w') as outFile:
        outFile.write('# test_id ra dec hlr mag_norm pa\n')

        for ix, (dx, dy, halfLight, magNorm, pp) in \
        enumerate(zip(raDisplacementList, decDisplacementList, hlr, mag_norm, pa)):

            rr = numpy.degrees(obs._pointingRA + dx)
            dd = numpy.degrees(obs._pointingDec + dy)

            outFile.write('%d %.9f %.9f %.9f %.9f %.9f\n' %
                          (ix, rr, dd, halfLight, magNorm, pp))
def create_text_catalog(obs, file_name, raDisplacement, decDisplacement, \
                        hlr=None, mag_norm=None, pa=None):
    """
    Create a text file containing objects that can be read in by a fileDBObject class.

    @param [in] obs is an ObservationMetaData specifying the pointing on which the catalog
    will be centered

    @param [in] file_name is the name of the file to be created.  If a file already exists with that
    name, throw an error.

    @param [in] raDisplacement is a numpy array listing the RA displacements of objects from the
    pointing's center in arcseconds

    @param [in] decDisplacement is a numpy array listing the Dec displacements of objects from the
    pointings' center in arcseconds

    @param [in] hlr is an optional list of half light radii in arcseconds

    @param [in] mag_norm is an optional list of the objects' magnitude normalizations

    @param [in] pa is an optional list of the objects' position angles in degrees
    """

    if os.path.exists(file_name):
        os.unlink(file_name)

    raDisplacementList = radiansFromArcsec(raDisplacement)
    decDisplacementList = radiansFromArcsec(decDisplacement)

    if hlr is None:
        hlr = [2.0]*len(raDisplacement)

    if mag_norm is None:
        mag_norm = [21.0]*len(raDisplacement)

    if pa is None:
        pa = [0.0]*len(raDisplacement)


    with open(file_name,'w') as outFile:
        outFile.write('# test_id ra dec hlr mag_norm pa\n')

        for ix, (dx, dy, halfLight, magNorm, pp) in \
        enumerate(zip(raDisplacementList, decDisplacementList, hlr, mag_norm, pa)):

            rr = numpy.degrees(obs._unrefractedRA+dx)
            dd = numpy.degrees(obs._unrefractedDec+dy)

            outFile.write('%d %.9f %.9f %.9f %.9f %.9f\n' % (ix, rr, dd, halfLight, magNorm, pp))
Пример #14
0
class hlrCat(GalSimGalaxies):
    camera = ReturnCamera(
        os.path.join(getPackageDir('sims_GalSimInterface'), 'tests',
                     'cameraData'))
    bandpassNames = ['u']
    default_columns = [('sedFilename', 'sed_flat.txt', (str, 12)),
                       ('magNorm', 21.0, float), ('galacticAv', 0.1, float),
                       ('galacticRv', 3.1, float),
                       ('galSimType', 'sersic', (str, 11)),
                       ('internalAv', 0.1, float), ('internalRv', 3.1, float),
                       ('redshift', 0.0, float),
                       ('majorAxis', radiansFromArcsec(1.0), float),
                       ('minorAxis', radiansFromArcsec(1.0), float),
                       ('sindex', 4.0, float)]
Пример #15
0
    def test_chip_name(self):
        """
        Test that chipNameFromRaDecLSST with non-zero proper motion etc.
        agrees with chipNameFromPupilCoords when pupilCoords are
        calculated with the same proper motion, etc.
        """
        (obs, ra_list, dec_list,
         pm_ra_list, pm_dec_list,
         parallax_list, v_rad_list) = self.set_data(11)

        for is_none in ('pm_ra', 'pm_dec', 'parallax', 'v_rad'):
            pm_ra = pm_ra_list
            pm_dec = pm_dec_list
            parallax = parallax_list
            v_rad = v_rad_list

            if is_none == 'pm_ra':
                pm_ra = None
            elif is_none == 'pm_dec':
                pm_dec = None
            elif is_none == 'parallax':
                parallax = None
            elif is_none == 'v_rad':
                v_rad = None

            xp, yp = pupilCoordsFromRaDec(ra_list, dec_list,
                                          pm_ra=pm_ra, pm_dec=pm_dec,
                                          parallax=parallax, v_rad=v_rad,
                                          obs_metadata=obs)

            name_control = chipNameFromPupilCoords(xp, yp, camera=self.camera)

            name_test = chipNameFromRaDecLSST(ra_list, dec_list,
                                              pm_ra=pm_ra, pm_dec=pm_dec,
                                              parallax=parallax, v_rad=v_rad,
                                              obs_metadata=obs)

            name_radians = _chipNameFromRaDecLSST(np.radians(ra_list), np.radians(dec_list),
                                                  pm_ra=radiansFromArcsec(pm_ra),
                                                  pm_dec=radiansFromArcsec(pm_dec),
                                                  parallax=radiansFromArcsec(parallax), v_rad=v_rad,
                                                  obs_metadata=obs)

            np.testing.assert_array_equal(name_control, name_test)
            np.testing.assert_array_equal(name_control, name_radians)
            self.assertGreater(len(np.unique(name_control.astype(str))), 4)
            self.assertLess(len(np.where(np.equal(name_control, None))[0]), len(name_control)/4)
    def _doesObjectImpingeOnDetector(self,
                                     xPupil=None,
                                     yPupil=None,
                                     detector=None,
                                     imgScale=None,
                                     nonZeroPixels=None):
        """
        Compare an astronomical object to a detector and determine whether or not that object will cast any
        light on that detector (in case the object is near the edge of a detector and will cast some
        incidental light onto it).

        This method is called by the method findAllDetectors.  findAllDetectors will generate a test image
        of an astronomical object.  It will find all of the pixels in that test image with flux above
        a certain threshold and pass that list of pixels into this method along with data characterizing
        the detector in question.  This method compares the pupil coordinates of those pixels with the pupil
        coordinate domain of the detector. If some of those pixels fall inside the detector, then this method
        returns True (signifying that the astronomical object does cast light on the detector).  If not, this
        method returns False.

        @param [in] xPupil the x pupil coordinate of the image's origin in arcseconds

        @param [in] yPupil the y pupil coordinate of the image's origin in arcseconds

        @param [in] detector an instantiation of GalSimDetector.  This is the detector against
        which we will compare the object.

        @param [in] nonZeroPixels is a numpy array of non-zero pixels from the test image referenced
        above.  nonZeroPixels[0] is their x coordinate (in pixel value).  nonZeroPixels[1] is
        ther y coordinate.

        @param [in] imgScale is the platescale of the test image in arcseconds per pixel
        """

        if detector is None:
            return False

        xPupilList = radiansFromArcsec(
            np.array([xPupil + ix * imgScale for ix in nonZeroPixels[0]]))
        yPupilList = radiansFromArcsec(
            np.array([yPupil + iy * imgScale for iy in nonZeroPixels[1]]))

        answer = detector.containsPupilCoordinates(xPupilList, yPupilList)

        if True in answer:
            return True
        else:
            return False
def applyProperMotion(ra, dec, pm_ra, pm_dec, parallax, v_rad, \
                      epoch=2000.0, mjd=None):
    """Applies proper motion between two epochs.

    units:  ra (degrees), dec (degrees), pm_ra (arcsec/year), pm_dec
    (arcsec/year), parallax (arcsec), v_rad (km/sec, positive if receding),
    epoch (Julian years)

    Returns corrected ra and dec (in radians)

    The function palpy.pm does not work properly if the parallax is below
    0.00045 arcseconds

    @param [in] ra in degrees.  Can be a float or a numpy array (not a list).

    @param [in] dec in degrees.  Can be a float or a numpy array (not a list).

    @param [in] pm_ra is ra proper motion multiplied by cos(Dec) in arcsec/year.
    Can be a float or a numpy array (not a list).

    @param [in] pm_dec is dec proper motion in arcsec/year.
    Can be a float or a numpy array (not a list).

    @param [in] parallax in arcsec. Can be a float or a numpy array (not a list).

    @param [in] v_rad is radial velocity in km/sec (positive if the object is receding).
    Can be a float or a numpy array (not a list).

    @param [in] epoch is epoch in Julian years (default: 2000.0)

    @param [in] mjd is an instantiation of the ModifiedJulianDate class
    representing the date of the observation

    @param [out] a 2-D numpy array in which the first row is the RA corrected
    for proper motion and the second row is the Dec corrected for proper motion
    (both in degrees)
    """

    output = _applyProperMotion(numpy.radians(ra), numpy.radians(dec),
                                radiansFromArcsec(pm_ra),
                                radiansFromArcsec(pm_dec),
                                radiansFromArcsec(parallax),
                                v_rad, epoch=epoch, mjd=mjd)

    return numpy.degrees(output)
class hlrCat(GalSimGalaxies):
    bandpassNames = ['u']
    default_columns = [
        ('sedFilename', 'sed_flat.txt', (str, 12)),
        ('magNorm', 21.0, float),
        ('galacticAv', 0.1, float),
        ('galacticRv', 3.1, float),
        ('galSimType', 'sersic', (str, 11)),
        ('internalAv', 0.1, float),
        ('internalRv', 3.1, float),
        ('redshift', 0.0, float),
        ('majorAxis', radiansFromArcsec(1.0), float),
        ('minorAxis', radiansFromArcsec(1.0), float),
        ('sindex', 4.0, float),
        ('shear1', 0.0, float),
        ('shear2', 0.0, float),
        ('kappa', 0.0, float),
    ]
class hlrCatRandomWalk(GalSimRandomWalk):
    bandpassNames = ['u']
    default_columns = [
        ('sedFilename', 'sed_flat.txt', (str, 12)),
        ('magNorm', 21.0, float),
        ('galacticAv', 0.1, float),
        ('galacticRv', 3.1, float),
        ('galSimType', 'RandomWalk', (str, 10)),
        ('internalAv', 0.1, float),
        ('internalRv', 3.1, float),
        ('redshift', 0.0, float),
        ('majorAxis', radiansFromArcsec(1.0), float),
        ('minorAxis', radiansFromArcsec(1.0), float),
        ('npoints', 10000, int),
        ('sindex', 0.0, float),
        ('gamma1', 0.0, float),
        ('gamma2', 0.0, float),
        ('kappa', 0.0, float),
    ]
    def _doesObjectImpingeOnDetector(self, xPupil=None, yPupil=None, detector=None,
                                     imgScale=None, nonZeroPixels=None):
        """
        Compare an astronomical object to a detector and determine whether or not that object will cast any
        light on that detector (in case the object is near the edge of a detector and will cast some
        incidental light onto it).

        This method is called by the method findAllDetectors.  findAllDetectors will generate a test image
        of an astronomical object.  It will find all of the pixels in that test image with flux above
        a certain threshold and pass that list of pixels into this method along with data characterizing
        the detector in question.  This method compares the pupil coordinates of those pixels with the pupil
        coordinate domain of the detector. If some of those pixels fall inside the detector, then this method
        returns True (signifying that the astronomical object does cast light on the detector).  If not, this
        method returns False.

        @param [in] xPupil the x pupil coordinate of the image's origin in arcseconds

        @param [in] yPupil the y pupil coordinate of the image's origin in arcseconds

        @param [in] detector an instantiation of GalSimDetector.  This is the detector against
        which we will compare the object.

        @param [in] nonZeroPixels is a numpy array of non-zero pixels from the test image referenced
        above.  nonZeroPixels[0] is their x coordinate (in pixel value).  nonZeroPixels[1] is
        ther y coordinate.

        @param [in] imgScale is the platescale of the test image in arcseconds per pixel
        """

        if detector is None:
            return False

        xPupilList = radiansFromArcsec(numpy.array([xPupil + ix*imgScale for ix in nonZeroPixels[0]]))
        yPupilList = radiansFromArcsec(numpy.array([yPupil + iy*imgScale for iy in nonZeroPixels[1]]))

        answer = detector.containsPupilCoordinates(xPupilList, yPupilList)

        if True in answer:
            return True
        else:
            return False
Пример #21
0
def xyz_from_lon_lat_px(lon, lat, px):
    """
    Parameters
    ----------
    lon is galactic longitude in degrees

    lat is galactic latitude in degrees

    px in parallax in arcseconds

    Returns
    -------
    A numpy array containing the vector from Sgr A* to the
    input star.  Distances in parsecs.
    """

    _d_center = 8.33e3  # distance from the Sun to Sgr A* from
    # Gillessen et al 2009 (ApJ 692, 1075) eqn 11

    _lon_center = 359.9442
    _lat_center = -0.0462  # galactic latitude and longitude of Sgr A* from
    # http://simbad.u-strasbg.fr/simbad/sim-basic?Ident=Sagittarius+A&submit=SIMBAD+search

    _au_to_parsec = 1.0 / 206265.0

    if not hasattr(xyz_from_lon_lat_px, '_xyz_center'):
        lon_rad = np.radians(_lon_center)
        lat_rad = np.radians(_lat_center)
        xx = np.cos(lon_rad) * np.cos(lat_rad)
        yy = np.sin(lon_rad) * np.cos(lat_rad)
        zz = np.sin(lat_rad)

        xyz_from_lon_lat_px._xyz_center = np.array(
            [_d_center * xx, _d_center * yy, _d_center * zz])

    lon_rad = np.radians(lon)
    lat_rad = np.radians(lat)
    dd = _au_to_parsec / radiansFromArcsec(px)

    xx = dd * np.cos(lon_rad) * np.cos(lat_rad)
    yy = dd * np.sin(lon_rad) * np.cos(lat_rad)
    zz = dd * np.sin(lat_rad)

    return np.array([
        xx - xyz_from_lon_lat_px._xyz_center[0],
        yy - xyz_from_lon_lat_px._xyz_center[1],
        zz - xyz_from_lon_lat_px._xyz_center[2]
    ])
Пример #22
0
    def testUnitConversion(self):
        """
        Test that arcsecFromRadians, arcsecFromDegrees,
        radiansFromArcsec, and degreesFromArcsec are all
        self-consistent
        """

        radList = self.rng.random_sample(100) * 2.0 * np.pi
        degList = np.degrees(radList)

        arcsecRadList = utils.arcsecFromRadians(radList)
        arcsecDegList = utils.arcsecFromDegrees(degList)

        np.testing.assert_array_equal(arcsecRadList, arcsecDegList)

        arcsecList = self.rng.random_sample(100) * 1.0
        radList = utils.radiansFromArcsec(arcsecList)
        degList = utils.degreesFromArcsec(arcsecList)
        np.testing.assert_array_equal(np.radians(degList), radList)
    def testUnitConversion(self):
        """
        Test that arcsecFromRadians, arcsecFromDegrees,
        radiansFromArcsec, and degreesFromArcsec are all
        self-consistent
        """

        radList = np.random.random_sample(100)*2.0*np.pi
        degList = np.degrees(radList)

        arcsecRadList = utils.arcsecFromRadians(radList)
        arcsecDegList = utils.arcsecFromDegrees(degList)

        np.testing.assert_array_equal(arcsecRadList, arcsecDegList)

        arcsecList = np.random.random_sample(100)*1.0
        radList = utils.radiansFromArcsec(arcsecList)
        degList = utils.degreesFromArcsec(arcsecList)
        np.testing.assert_array_equal(np.radians(degList), radList)
    def setUpClass(cls):
        cls.dataDir = os.path.join(getPackageDir('sims_GalSimInterface'),
                                   'tests', 'scratchSpace')
        cls.n_objects = 5
        rng = np.random.RandomState(45)
        pointingRA = 45.2
        pointingDec = -31.6

        cls.obs = ObservationMetaData(pointingRA=pointingRA, pointingDec=pointingDec,
                                      rotSkyPos=1.2, bandpassName='r', mjd=57341.5,
                                      boundLength=0.1, boundType='circle')

        cls.dtype = np.dtype([('id', int),
                              ('raJ2000', np.float),
                              ('decJ2000', np.float),
                              ('ra_deg', np.float),
                              ('dec_deg', np.float),
                              ('sedFilename', (str, 300)),
                              ('magNorm', np.float),
                              ('redshift', np.float),
                              ('majorAxis', np.float),
                              ('minorAxis', np.float),
                              ('positionAngle', np.float),
                              ('halfLightRadius', np.float),
                              ('sindex', np.float),
                              ('internalAv', np.float),
                              ('internalRv', np.float),
                              ('galacticAv', np.float),
                              ('galacticRv', np.float),
                              ('properMotionRa', np.float),
                              ('properMotionDec', np.float),
                              ('radialVelocity', np.float),
                              ('parallax', np.float)])

        # generate some galaxy bulge data
        redshift = rng.random_sample(cls.n_objects)*1.5
        rr = rng.random_sample(cls.n_objects)*0.05
        theta = rng.random_sample(cls.n_objects)*2.0*np.pi
        ra = np.radians(pointingRA + rr*np.cos(theta))
        dec = np.radians(pointingDec + rr*np.sin(theta))
        magNorm = rng.random_sample(cls.n_objects)*7.0 + 18.0
        sindex = rng.random_sample(cls.n_objects)*4.0+1.0
        hlr = radiansFromArcsec(rng.random_sample(cls.n_objects)*10.0 + 1.0)
        positionAngle = rng.random_sample(cls.n_objects)*np.pi
        internalAv = rng.random_sample(cls.n_objects)*0.5+0.1
        internalRv = rng.random_sample(cls.n_objects)*0.5+2.7
        majorAxis = radiansFromArcsec(rng.random_sample(cls.n_objects)*2.0 + 0.5)
        minorAxis = radiansFromArcsec(rng.random_sample(cls.n_objects)*2.0 + 0.5)
        galacticAv = rng.random_sample(cls.n_objects)*0.5+0.1
        galacticRv = rng.random_sample(cls.n_objects)*0.5+2.7
        properMotionRa = np.zeros(cls.n_objects)
        properMotionDec = np.zeros(cls.n_objects)
        radialVelocity = np.zeros(cls.n_objects)
        parallax = np.zeros(cls.n_objects)
        cls.bulge_name = os.path.join(cls.dataDir, 'galSimPhoSim_test_bulge.dat')
        with open(cls.bulge_name, 'w') as output_file:
            output_file.write('# header\n')
            for ix in range(cls.n_objects):
                output_file.write('%d %f %f %f %f Const.79E06.002Z.spec %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n' %
                                  (ix, ra[ix], dec[ix], np.degrees(ra[ix]), np.degrees(dec[ix]),
                                   magNorm[ix], redshift[ix],
                                   max(majorAxis[ix], minorAxis[ix]), min(majorAxis[ix], minorAxis[ix]),
                                   positionAngle[ix], hlr[ix], sindex[ix], internalAv[ix], internalRv[ix],
                                   galacticAv[ix], galacticRv[ix],
                                   properMotionRa[ix], properMotionDec[ix], radialVelocity[ix], parallax[ix]))

        # generate some galaxy disk data
        redshift = rng.random_sample(cls.n_objects)*1.5
        rr = rng.random_sample(cls.n_objects)*0.05
        theta = rng.random_sample(cls.n_objects)*2.0*np.pi
        ra = np.radians(pointingRA + rr*np.cos(theta))
        dec = np.radians(pointingDec + rr*np.sin(theta))
        magNorm = rng.random_sample(cls.n_objects)*7.0 + 18.0
        sindex = rng.random_sample(cls.n_objects)*4.0+1.0
        hlr = radiansFromArcsec(rng.random_sample(cls.n_objects)*10.0 + 1.0)
        positionAngle = rng.random_sample(cls.n_objects)*np.pi
        internalAv = rng.random_sample(cls.n_objects)*0.5+0.1
        internalRv = rng.random_sample(cls.n_objects)*0.5+2.7
        majorAxis = radiansFromArcsec(rng.random_sample(cls.n_objects)*2.0 + 0.5)
        minorAxis = radiansFromArcsec(rng.random_sample(cls.n_objects)*2.0 + 0.5)
        galacticAv = rng.random_sample(cls.n_objects)*0.5+0.1
        galacticRv = rng.random_sample(cls.n_objects)*0.5+2.7
        properMotionRa = np.zeros(cls.n_objects)
        properMotionDec = np.zeros(cls.n_objects)
        radialVelocity = np.zeros(cls.n_objects)
        parallax = np.zeros(cls.n_objects)
        cls.disk_name = os.path.join(cls.dataDir, 'galSimPhoSim_test_disk.dat')
        with open(cls.disk_name, 'w') as output_file:
            output_file.write('# header\n')
            for ix in range(cls.n_objects):
                output_file.write('%d %f %f %f %f Inst.79E06.02Z.spec %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n' %
                                  (ix, ra[ix], dec[ix], np.degrees(ra[ix]), np.degrees(dec[ix]),
                                   magNorm[ix], redshift[ix],
                                   max(majorAxis[ix], minorAxis[ix]), min(majorAxis[ix], minorAxis[ix]),
                                   positionAngle[ix], hlr[ix], sindex[ix], internalAv[ix], internalRv[ix],
                                   galacticAv[ix], galacticRv[ix],
                                   properMotionRa[ix], properMotionDec[ix], radialVelocity[ix], parallax[ix]))

        # generate some agn data
        redshift = rng.random_sample(cls.n_objects)*1.5
        rr = rng.random_sample(cls.n_objects)*0.05
        theta = rng.random_sample(cls.n_objects)*2.0*np.pi
        ra = np.radians(pointingRA + rr*np.cos(theta))
        dec = np.radians(pointingDec + rr*np.sin(theta))
        magNorm = rng.random_sample(cls.n_objects)*7.0 + 18.0
        sindex = np.zeros(cls.n_objects)
        hlr = np.zeros(cls.n_objects)
        positionAngle = np.zeros(cls.n_objects)
        internalAv = np.zeros(cls.n_objects)
        internalRv = np.zeros(cls.n_objects)
        majorAxis = np.zeros(cls.n_objects)
        minorAxis = np.zeros(cls.n_objects)
        galacticAv = rng.random_sample(cls.n_objects)*0.5+0.1
        galacticRv = rng.random_sample(cls.n_objects)*0.5+2.7
        properMotionRa = np.zeros(cls.n_objects)
        properMotionDec = np.zeros(cls.n_objects)
        radialVelocity = np.zeros(cls.n_objects)
        parallax = np.zeros(cls.n_objects)
        cls.agn_name = os.path.join(cls.dataDir, 'galSimPhoSim_test_agn.dat')
        with open(cls.agn_name, 'w') as output_file:
            output_file.write('# header\n')
            for ix in range(cls.n_objects):
                output_file.write('%d %f %f %f %f agn.spec %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n' %
                                  (ix, ra[ix], dec[ix], np.degrees(ra[ix]), np.degrees(dec[ix]),
                                   magNorm[ix], redshift[ix],
                                   max(majorAxis[ix], minorAxis[ix]), min(majorAxis[ix], minorAxis[ix]),
                                   positionAngle[ix], hlr[ix], sindex[ix], internalAv[ix], internalRv[ix],
                                   galacticAv[ix], galacticRv[ix],
                                   properMotionRa[ix], properMotionDec[ix], radialVelocity[ix], parallax[ix]))

        # generate some star data
        redshift = rng.random_sample(cls.n_objects)*1.5
        rr = rng.random_sample(cls.n_objects)*0.05
        theta = rng.random_sample(cls.n_objects)*2.0*np.pi
        ra = np.radians(pointingRA + rr*np.cos(theta))
        dec = np.radians(pointingDec + rr*np.sin(theta))
        magNorm = rng.random_sample(cls.n_objects)*7.0 + 18.0
        sindex = np.zeros(cls.n_objects)
        hlr = np.zeros(cls.n_objects)
        positionAngle = np.zeros(cls.n_objects)
        internalAv = np.zeros(cls.n_objects)
        internalRv = np.zeros(cls.n_objects)
        majorAxis = np.zeros(cls.n_objects)
        minorAxis = np.zeros(cls.n_objects)
        galacticAv = rng.random_sample(cls.n_objects)*0.5+0.1
        galacticRv = rng.random_sample(cls.n_objects)*0.5+2.7
        properMotionRa = radiansFromArcsec(rng.random_sample(cls.n_objects)*0.0002)
        properMotionDec = radiansFromArcsec(rng.random_sample(cls.n_objects)*0.0002)
        radialVelocity = rng.random_sample(cls.n_objects)*200.0
        parallax = radiansFromArcsec(rng.random_sample(cls.n_objects)*0.0002)
        cls.star_name = os.path.join(cls.dataDir, 'galSimPhoSim_test_star.dat')
        with open(cls.star_name, 'w') as output_file:
            output_file.write('# header\n')
            for ix in range(cls.n_objects):
                output_file.write('%d %f %f %f %f km30_5000.fits_g10_5040 %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n' %
                                  (ix, ra[ix], dec[ix], np.degrees(ra[ix]), np.degrees(dec[ix]),
                                   magNorm[ix], redshift[ix],
                                   max(majorAxis[ix], minorAxis[ix]), min(majorAxis[ix], minorAxis[ix]),
                                   positionAngle[ix], hlr[ix], sindex[ix], internalAv[ix], internalRv[ix],
                                   galacticAv[ix], galacticRv[ix],
                                   properMotionRa[ix], properMotionDec[ix], radialVelocity[ix], parallax[ix]))
Пример #25
0
    def test_with_proper_motion(self):
        """
        Test that calculating pupil coordinates in the presence of proper motion, parallax,
        and radial velocity is equivalent to
        observedFromICRS -> icrsFromObserved -> pupilCoordsFromRaDec
        (mostly to make surethat pupilCoordsFromRaDec is correctly calling observedFromICRS
        with non-zero proper motion, etc.)
        """
        rng = np.random.RandomState(38442)
        is_valid = False
        while not is_valid:
            mjd_tai = 59580.0 + 10000.0*rng.random_sample()
            obs = ObservationMetaData(mjd=mjd_tai)
            ra, dec = raDecFromAltAz(78.0, 112.0, obs)
            dd = distanceToSun(ra, dec, obs.mjd)
            if dd > 45.0:
                is_valid = True

        n_obj = 1000
        rr = rng.random_sample(n_obj)*2.0
        theta = rng.random_sample(n_obj)*2.0*np.pi
        ra_list = ra + rr*np.cos(theta)
        dec_list = dec + rr*np.sin(theta)
        obs = ObservationMetaData(pointingRA=ra, pointingDec=dec, mjd=mjd_tai, rotSkyPos=19.0)

        pm_ra_list = rng.random_sample(n_obj)*100.0 - 50.0
        pm_dec_list = rng.random_sample(n_obj)*100.0 - 50.0
        px_list = rng.random_sample(n_obj) + 0.05
        v_rad_list = rng.random_sample(n_obj)*600.0 - 300.0

        for includeRefraction in (True, False):

            ra_obs, dec_obs = observedFromICRS(ra_list, dec_list,
                                               pm_ra=pm_ra_list, pm_dec=pm_dec_list,
                                               parallax=px_list, v_rad=v_rad_list,
                                               obs_metadata=obs, epoch=2000.0,
                                               includeRefraction=includeRefraction)

            ra_icrs, dec_icrs = icrsFromObserved(ra_obs, dec_obs, obs_metadata=obs,
                                                 epoch=2000.0, includeRefraction=includeRefraction)

            xp_control, yp_control = pupilCoordsFromRaDec(ra_icrs, dec_icrs, obs_metadata=obs,
                                                          epoch=2000.0, includeRefraction=includeRefraction)

            xp_test, yp_test = pupilCoordsFromRaDec(ra_list, dec_list,
                                                    pm_ra=pm_ra_list, pm_dec=pm_dec_list,
                                                    parallax=px_list, v_rad=v_rad_list,
                                                    obs_metadata=obs, epoch=2000.0,
                                                    includeRefraction=includeRefraction)

            distance = arcsecFromRadians(np.sqrt(np.power(xp_test-xp_control, 2) +
                                                 np.power(yp_test-yp_control, 2)))
            self.assertLess(distance.max(), 0.006)

            # now test it in radians
            xp_rad, yp_rad = _pupilCoordsFromRaDec(np.radians(ra_list), np.radians(dec_list),
                                                   pm_ra=radiansFromArcsec(pm_ra_list),
                                                   pm_dec=radiansFromArcsec(pm_dec_list),
                                                   parallax=radiansFromArcsec(px_list),
                                                   v_rad=v_rad_list,
                                                   obs_metadata=obs, epoch=2000.0,
                                                   includeRefraction=includeRefraction)

            np.testing.assert_array_equal(xp_rad, xp_test)
            np.testing.assert_array_equal(yp_rad, yp_test)

            # now test it with proper motion = 0
            ra_obs, dec_obs = observedFromICRS(ra_list, dec_list,
                                               parallax=px_list, v_rad=v_rad_list,
                                               obs_metadata=obs, epoch=2000.0,
                                               includeRefraction=includeRefraction)

            ra_icrs, dec_icrs = icrsFromObserved(ra_obs, dec_obs, obs_metadata=obs,
                                                 epoch=2000.0, includeRefraction=includeRefraction)

            xp_control, yp_control = pupilCoordsFromRaDec(ra_icrs, dec_icrs, obs_metadata=obs,
                                                          epoch=2000.0, includeRefraction=includeRefraction)

            xp_test, yp_test = pupilCoordsFromRaDec(ra_list, dec_list,
                                                    parallax=px_list, v_rad=v_rad_list,
                                                    obs_metadata=obs, epoch=2000.0,
                                                    includeRefraction=includeRefraction)

            distance = arcsecFromRadians(np.sqrt(np.power(xp_test-xp_control, 2) +
                                                 np.power(yp_test-yp_control, 2)))
            self.assertLess(distance.max(), 1.0e-6)
Пример #26
0
def pupilCoordsFromRaDec(ra_in, dec_in,
                         pm_ra=None, pm_dec=None, parallax=None,
                         v_rad=None, includeRefraction=True,
                         obs_metadata=None, epoch=2000.0):
    """
    Take an input RA and dec from the sky and convert it to coordinates
    on the focal plane.

    This uses PAL's gnomonic projection routine which assumes that the focal
    plane is perfectly flat.  The output is in Cartesian coordinates, assuming
    that the Celestial Sphere is a unit sphere.

    The RA, Dec accepted by this method are in the International Celestial
    Reference System.  Before applying the gnomonic projection, this method
    transforms those RA, Dec into observed geocentric coordinates, applying
    the effects of precession, nutation, aberration, parallax and refraction.
    This is done, because the gnomonic projection ought to be applied to what
    observers actually see, rather than the idealized, above-the-atmosphere
    coordinates represented by the ICRS.

    @param [in] ra_in is in degrees (ICRS).  Can be either a numpy array or a number.

    @param [in] dec_in is in degrees (ICRS).  Can be either a numpy array or a number.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in arcsec
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).

    @param [in] includeRefraction is a boolean controlling the application of refraction.

    @param [in] obs_metadata is an ObservationMetaData instantiation characterizing the
    telescope location and pointing.

    @param [in] epoch is the epoch of mean ra and dec in julian years (default=2000.0)

    @param [out] returns a numpy array whose first row is the x coordinate on the pupil in
    radians and whose second row is the y coordinate in radians
    """

    if pm_ra is not None:
        pm_ra_in = radiansFromArcsec(pm_ra)
    else:
        pm_ra_in = None

    if pm_dec is not None:
        pm_dec_in = radiansFromArcsec(pm_dec)
    else:
        pm_dec_in = None

    if parallax is not None:
        parallax_in = radiansFromArcsec(parallax)
    else:
        parallax_in = None

    return _pupilCoordsFromRaDec(np.radians(ra_in), np.radians(dec_in),
                                 pm_ra=pm_ra_in, pm_dec=pm_dec_in,
                                 parallax=parallax_in, v_rad=v_rad,
                                 includeRefraction=includeRefraction,
                                 obs_metadata=obs_metadata, epoch=epoch)
    def test_applyProperMotion(self):
        """
        Compare the output of _applyProperMotion to control outputs
        generated by recreating the 'space motion' section of code
        from palMapqk.c in palpy/cextern/pal
        """
        VF=0.21094502
        pal_das2r=4.8481368110953599358991410235794797595635330237270e-6;

        numpy.random.seed(18)
        nSamples = 1000

        mjdList = numpy.random.random_sample(20)*20000.0 + 45000.0

        for mjd in mjdList:

            raList_icrs = numpy.random.random_sample(nSamples)*2.0*numpy.pi
            decList_icrs = (numpy.random.random_sample(nSamples)-0.5)*numpy.pi

            # stars' original position in Cartesian space
            x_list_icrs = numpy.cos(decList_icrs)*numpy.cos(raList_icrs)
            y_list_icrs = numpy.cos(decList_icrs)*numpy.sin(raList_icrs)
            z_list_icrs = numpy.sin(decList_icrs)


            pm_ra = (numpy.random.random_sample(nSamples)-0.5)*radiansFromArcsec(1.0)
            pm_dec = (numpy.random.random_sample(nSamples)-0.5)*radiansFromArcsec(1.0)
            px = numpy.random.random_sample(nSamples)*radiansFromArcsec(1.0)
            v_rad = numpy.random.random_sample(nSamples)*200.0


            ra_list_pm, dec_list_pm = _applyProperMotion(raList_icrs, decList_icrs,
                                                         pm_ra*numpy.cos(decList_icrs),
                                                         pm_dec, px, v_rad, mjd=ModifiedJulianDate(TAI=mjd))

            # stars' Cartesian position after proper motion is applied
            x_list_pm = numpy.cos(dec_list_pm)*numpy.cos(ra_list_pm)
            y_list_pm = numpy.cos(dec_list_pm)*numpy.sin(ra_list_pm)
            z_list_pm = numpy.sin(dec_list_pm)

            ###############################################################
            # The code below is copied from palMapqk.c in palpy/cextern/pal
            params = pal.mappa(2000.0, mjd)
            pmt = params[0]
            eb = numpy.array([params[1], params[2], params[3]])

            pxr = px*pal_das2r

            w = VF*v_rad*pxr

            motion_per_year = numpy.array([-1.0*pm_ra*y_list_icrs - pm_dec*numpy.cos(raList_icrs)*numpy.sin(decList_icrs) + w*x_list_icrs,
                                     pm_ra*x_list_icrs - pm_dec*numpy.sin(raList_icrs)*numpy.sin(decList_icrs) + w*y_list_icrs,
                                     pm_dec*numpy.cos(decList_icrs) + w*z_list_icrs])


            xyz_control = numpy.array([
                                      x_list_icrs + pmt*motion_per_year[0] - pxr*eb[0],
                                      y_list_icrs + pmt*motion_per_year[1] - pxr*eb[1],
                                      z_list_icrs + pmt*motion_per_year[2] - pxr*eb[2]
                                      ])

            xyz_norm = numpy.sqrt(numpy.power(xyz_control[0],2) + numpy.power(xyz_control[1],2) + numpy.power(xyz_control[2],2))

            # stars' Cartesian position after applying the control proper motion method
            xyz_control[0] = xyz_control[0]/xyz_norm
            xyz_control[1] = xyz_control[1]/xyz_norm
            xyz_control[2] = xyz_control[2]/xyz_norm

            # this is the Cartesian distance between the stars' positions as found by _applyProperMotion
            # and the distance as found by the control proper motion code above
            distance = numpy.sqrt(numpy.power(x_list_pm-xyz_control[0],2) + numpy.power(y_list_pm-xyz_control[1],2) +
                                  numpy.power(z_list_pm-xyz_control[2],2))

            # this is the Cartesian distance between the stars' original positions on the celestial sphere
            # and their positions after the control proper motion was applied
            correction = numpy.sqrt(numpy.power(xyz_control[0]-x_list_icrs,2) + numpy.power(xyz_control[1]-y_list_icrs,2) +
                                    numpy.power(xyz_control[2]-z_list_icrs,2))

            dex = numpy.argmax(distance)
            msg = 'pm %e %e vr %e px %e; time %e; err %e arcsec; corr %e' % \
            (arcsecFromRadians(pm_ra[dex]), arcsecFromRadians(pm_dec[dex]),
             v_rad[dex], arcsecFromRadians(px[dex]), pmt, arcsecFromRadians(distance[dex]),
             arcsecFromRadians(correction[dex]))

            self.assertLess((distance/correction).max(), 0.01, msg=msg)
Пример #28
0
def sources_from_file(file_name, obs_md, phot_params, numRows=None):
    """
    Read in an InstanceCatalog and extract all of the astrophysical
    sources from it

    Parameters
    ----------
    file_name: str
        The name of the InstanceCatalog

    obs_md: ObservationMetaData
        The ObservationMetaData characterizing the pointing

    phot_params: PhotometricParameters
        The PhotometricParameters characterizing this telescope

    numRows: int (optional)
        The number of rows of the InstanceCatalog to read in (including the
        header)

    Returns
    -------
    gs_obj_arr: numpy array
        Contains the GalSimCelestialObjects for all of the
        astrophysical sources in this InstanceCatalog

    out_obj_dict: dict
        Keyed on the names of the detectors in the LSST camera.
        The values are numpy arrays of GalSimCelestialObjects
        that should be simulated for that detector, including
        objects that are near the edge of the chip or
        just bright (in which case, they might still illuminate
        the detector).
    """

    camera = get_obs_lsstSim_camera()

    num_objects = 0
    ct_rows = 0
    with fopen(file_name, mode='rt') as input_file:
        for line in input_file:
            ct_rows += 1
            params = line.strip().split()
            if params[0] == 'object':
                num_objects += 1
            if numRows is not None and ct_rows >= numRows:
                break

    # RA, Dec in the coordinate system expected by PhoSim
    ra_phosim = np.zeros(num_objects, dtype=float)
    dec_phosim = np.zeros(num_objects, dtype=float)

    sed_name = [None] * num_objects
    mag_norm = 55.0 * np.ones(num_objects, dtype=float)
    gamma1 = np.zeros(num_objects, dtype=float)
    gamma2 = np.zeros(num_objects, dtype=float)
    kappa = np.zeros(num_objects, dtype=float)

    internal_av = np.zeros(num_objects, dtype=float)
    internal_rv = np.zeros(num_objects, dtype=float)
    galactic_av = np.zeros(num_objects, dtype=float)
    galactic_rv = np.zeros(num_objects, dtype=float)
    semi_major_arcsec = np.zeros(num_objects, dtype=float)
    semi_minor_arcsec = np.zeros(num_objects, dtype=float)
    position_angle_degrees = np.zeros(num_objects, dtype=float)
    sersic_index = np.zeros(num_objects, dtype=float)
    npoints = np.zeros(num_objects, dtype=int)
    redshift = np.zeros(num_objects, dtype=float)

    unique_id = np.zeros(num_objects, dtype=int)
    object_type = np.zeros(num_objects, dtype=int)

    i_obj = -1
    with fopen(file_name, mode='rt') as input_file:
        for line in input_file:
            params = line.strip().split()
            if params[0] != 'object':
                continue
            i_obj += 1
            if numRows is not None and i_obj >= num_objects:
                break
            unique_id[i_obj] = int(params[1])
            ra_phosim[i_obj] = float(params[2])
            dec_phosim[i_obj] = float(params[3])
            mag_norm[i_obj] = float(params[4])
            sed_name[i_obj] = params[5]
            redshift[i_obj] = float(params[6])
            gamma1[i_obj] = float(params[7])
            gamma2[i_obj] = float(params[8])
            kappa[i_obj] = float(params[9])
            if params[12].lower() == 'point':
                object_type[i_obj] = _POINT_SOURCE
                i_gal_dust_model = 14
                if params[13].lower() != 'none':
                    i_gal_dust_model = 16
                    internal_av[i_obj] = float(params[14])
                    internal_rv[i_obj] = float(params[15])
                if params[i_gal_dust_model].lower() != 'none':
                    galactic_av[i_obj] = float(params[i_gal_dust_model + 1])
                    galactic_rv[i_obj] = float(params[i_gal_dust_model + 2])
            elif params[12].lower() == 'sersic2d':
                object_type[i_obj] = _SERSIC_2D
                semi_major_arcsec[i_obj] = float(params[13])
                semi_minor_arcsec[i_obj] = float(params[14])
                position_angle_degrees[i_obj] = float(params[15])
                sersic_index[i_obj] = float(params[16])
                i_gal_dust_model = 18
                if params[17].lower() != 'none':
                    i_gal_dust_model = 20
                    internal_av[i_obj] = float(params[18])
                    internal_rv[i_obj] = float(params[19])
                if params[i_gal_dust_model].lower() != 'none':
                    galactic_av[i_obj] = float(params[i_gal_dust_model + 1])
                    galactic_rv[i_obj] = float(params[i_gal_dust_model + 2])
            elif params[12].lower() == 'knots':
                object_type[i_obj] = _RANDOM_WALK
                semi_major_arcsec[i_obj] = float(params[13])
                semi_minor_arcsec[i_obj] = float(params[14])
                position_angle_degrees[i_obj] = float(params[15])
                npoints[i_obj] = int(params[16])
                i_gal_dust_model = 18
                if params[17].lower() != 'none':
                    i_gal_dust_model = 20
                    internal_av[i_obj] = float(params[18])
                    internal_rv[i_obj] = float(params[19])
                if params[i_gal_dust_model].lower() != 'none':
                    galactic_av[i_obj] = float(params[i_gal_dust_model + 1])
                    galactic_rv[i_obj] = float(params[i_gal_dust_model + 2])
            else:
                raise RuntimeError("Do not know how to handle "
                                   "object type: %s" % params[12])

    ra_appGeo, dec_appGeo = PhoSimAstrometryBase._appGeoFromPhoSim(
        np.radians(ra_phosim), np.radians(dec_phosim), obs_md)

    (ra_obs_rad, dec_obs_rad) = _observedFromAppGeo(ra_appGeo,
                                                    dec_appGeo,
                                                    obs_metadata=obs_md,
                                                    includeRefraction=True)

    semi_major_radians = radiansFromArcsec(semi_major_arcsec)
    semi_minor_radians = radiansFromArcsec(semi_minor_arcsec)
    position_angle_radians = np.radians(position_angle_degrees)

    x_pupil, y_pupil = _pupilCoordsFromObserved(ra_obs_rad, dec_obs_rad,
                                                obs_md)

    bp_dict = BandpassDict.loadTotalBandpassesFromFiles()

    sed_dir = lsstUtils.getPackageDir('sims_sed_library')

    object_is_valid = np.array([True] * num_objects)

    invalid_objects = np.where(
        np.logical_or(
            np.logical_or(
                mag_norm > 50.0,
                np.logical_and(galactic_av == 0.0, galactic_rv == 0.0)),
            np.logical_or(
                np.logical_and(object_type == _SERSIC_2D,
                               semi_major_arcsec < semi_minor_arcsec),
                np.logical_and(object_type == _RANDOM_WALK, npoints <= 0))))

    object_is_valid[invalid_objects] = False

    if len(invalid_objects[0]) > 0:
        message = "\nOmitted %d suspicious objects from " % len(
            invalid_objects[0])
        message += "the instance catalog:\n"
        n_bad_mag_norm = len(np.where(mag_norm > 50.0)[0])
        message += "    %d had mag_norm > 50.0\n" % n_bad_mag_norm
        n_bad_av = len(
            np.where(np.logical_and(galactic_av == 0.0,
                                    galactic_rv == 0.0))[0])
        message += "    %d had galactic_Av == galactic_Rv == 0\n" % n_bad_av
        n_bad_axes = len(
            np.where(
                np.logical_and(object_type == _SERSIC_2D,
                               semi_major_arcsec < semi_minor_arcsec))[0])
        message += "    %d had semi_major_axis < semi_minor_axis\n" % n_bad_axes
        n_bad_knots = len(
            np.where(np.logical_and(object_type == _RANDOM_WALK,
                                    npoints <= 0))[0])
        message += "    %d had n_points <= 0 \n" % n_bad_knots
        warnings.warn(message)

    wav_int = None
    wav_gal = None

    gs_object_arr = []
    for i_obj in range(num_objects):
        if not object_is_valid[i_obj]:
            continue

        if object_type[i_obj] == _POINT_SOURCE:
            gs_type = 'pointSource'
        elif object_type[i_obj] == _SERSIC_2D:
            gs_type = 'sersic'
        elif object_type[i_obj] == _RANDOM_WALK:
            gs_type = 'RandomWalk'

        # load the SED
        sed_obj = Sed()
        sed_obj.readSED_flambda(os.path.join(sed_dir, sed_name[i_obj]))
        fnorm = getImsimFluxNorm(sed_obj, mag_norm[i_obj])
        sed_obj.multiplyFluxNorm(fnorm)
        if internal_av[i_obj] != 0.0:
            if wav_int is None or not np.array_equal(sed_obj.wavelen, wav_int):
                a_int, b_int = sed_obj.setupCCMab()
                wav_int = copy.deepcopy(sed_obj.wavelen)

            sed_obj.addCCMDust(a_int,
                               b_int,
                               A_v=internal_av[i_obj],
                               R_v=internal_rv[i_obj])

        if redshift[i_obj] != 0.0:
            sed_obj.redshiftSED(redshift[i_obj], dimming=True)

        sed_obj.resampleSED(wavelen_match=bp_dict.wavelenMatch)

        if galactic_av[i_obj] != 0.0:
            if wav_gal is None or not np.array_equal(sed_obj.wavelen, wav_gal):
                a_g, b_g = sed_obj.setupCCMab()
                wav_gal = copy.deepcopy(sed_obj.wavelen)

            sed_obj.addCCMDust(a_g,
                               b_g,
                               A_v=galactic_av[i_obj],
                               R_v=galactic_rv[i_obj])

        gs_object = GalSimCelestialObject(gs_type,
                                          x_pupil[i_obj],
                                          y_pupil[i_obj],
                                          semi_major_radians[i_obj],
                                          semi_minor_radians[i_obj],
                                          semi_major_radians[i_obj],
                                          position_angle_radians[i_obj],
                                          sersic_index[i_obj],
                                          sed_obj,
                                          bp_dict,
                                          phot_params,
                                          npoints[i_obj],
                                          gamma1=gamma1[i_obj],
                                          gamma2=gamma2[i_obj],
                                          kappa=kappa[i_obj],
                                          uniqueId=unique_id[i_obj])

        gs_object_arr.append(gs_object)

    gs_object_arr = np.array(gs_object_arr)

    # how close to the edge of the detector a source has
    # to be before we will just simulate it anyway
    pix_tol = 50.0

    # any source brighter than this will be considered
    # so bright that it should be simulated for all
    # detectors, just in case light scatters onto them.
    max_mag = 16.0

    # down-select mag_norm, x_pupil, and y_pupil
    # to only contain those objects that were
    # deemed to be valid above
    valid = np.where(object_is_valid)
    mag_norm = mag_norm[valid]
    x_pupil = x_pupil[valid]
    y_pupil = y_pupil[valid]

    assert len(mag_norm) == len(gs_object_arr)
    assert len(x_pupil) == len(gs_object_arr)
    assert len(y_pupil) == len(gs_object_arr)

    out_obj_dict = {}
    for det in lsst_camera():
        chip_name = det.getName()
        pixel_corners = getCornerPixels(chip_name, lsst_camera())
        x_min = pixel_corners[0][0]
        x_max = pixel_corners[2][0]
        y_min = pixel_corners[0][1]
        y_max = pixel_corners[3][1]
        xpix, ypix = pixelCoordsFromPupilCoords(x_pupil,
                                                y_pupil,
                                                chipName=chip_name,
                                                camera=lsst_camera())

        on_chip = np.where(
            np.logical_or(
                mag_norm < max_mag,
                np.logical_and(
                    xpix > x_min - pix_tol,
                    np.logical_and(
                        xpix < x_max + pix_tol,
                        np.logical_and(ypix > y_min - pix_tol,
                                       ypix < y_max + pix_tol)))))

        out_obj_dict[chip_name] = gs_object_arr[on_chip]

    return gs_object_arr, out_obj_dict
Пример #29
0
def extract_objects(df, header):
    """
    Extract the object information needed by the sims code
    and pack into a new dataframe.

    Parameters
    ----------
    df : pandas.DataFrame
        DataFrame containing the instance catalog object data.

    header : dictionary
        dictionary containing the PhoSim header cards as output
        by extract_commands()
        (necessary for correctly applying proper motion to stars)

    Returns
    -------
    pandas.DataFrame
        A DataFrame with the columns expected by the sims code.
    """
    # Check for unhandled source types and emit warning if any are present.
    valid_types = dict(point='pointSource',
                       sersic2d='sersic')
    invalid_types = set(df['SOURCE_TYPE']) - set(valid_types)
    if invalid_types:
        warnings.warn("Instance catalog contains unhandled source types:\n%s\nSkipping these."
                      % '\n'.join(invalid_types))

    columns = ('uniqueId', 'galSimType',
               'magNorm', 'sedFilepath', 'redshift',
               'raJ2000', 'decJ2000',
               'halfLightRadius',
               'minorAxis',
               'majorAxis',
               'positionAngle', 'sindex',
               'properMotionRa', 'properMotionDec',
               'parallax', 'radialVelocity')

    # Process point sources and galaxies separately.
    source_type = 'point'
    stars = df.query("SOURCE_TYPE=='%s'" % source_type)
    phosim_stars = pd.DataFrame(np.zeros((len(stars), len(columns))),
                                index=stars.index,
                                columns=columns)
    phosim_stars['uniqueId'] = pd.to_numeric(stars['VALUE']).tolist()
    phosim_stars['galSimType'] = valid_types[source_type]
    phosim_stars['magNorm'] = pd.to_numeric(stars['MAG_NORM']).tolist()
    phosim_stars['sedFilepath'] = stars['SED_NAME'].tolist()
    phosim_stars['redshift'] = pd.to_numeric(stars['REDSHIFT']).tolist()
    phosim_stars['raJ2000'] = pd.to_numeric(stars['RA']).tolist()
    phosim_stars['decJ2000'] = pd.to_numeric(stars['DEC']).tolist()
    phosim_stars['properMotionRa'] = pd.to_numeric(stars['PAR5']).tolist()
    phosim_stars['properMotionDec'] = pd.to_numeric(stars['PAR6']).tolist()
    phosim_stars['parallax'] = pd.to_numeric(stars['PAR7']).tolist()
    phosim_stars['radialVelocity'] = pd.to_numeric(stars['PAR8']).tolist()
    if len(phosim_stars) > 0:
        phosim_stars = extract_extinction(stars, phosim_stars, 1)

        mjd = ModifiedJulianDate(TAI=header['mjd'])
        raICRS, decICRS = applyProperMotion(phosim_stars.raJ2000.values,
                                            phosim_stars.decJ2000.values,
                                            phosim_stars.properMotionRa.values,
                                            phosim_stars.properMotionDec.values,
                                            phosim_stars.parallax.values,
                                            phosim_stars.radialVelocity.values,
                                            mjd=mjd)

        phosim_stars = phosim_stars.assign(raICRS=raICRS, decICRS=decICRS)

    source_type = 'sersic2d'
    galaxies = df.query("SOURCE_TYPE == '%s'" % source_type)
    phosim_galaxies = pd.DataFrame(np.zeros((len(galaxies), len(columns))),
                                   index=galaxies.index,
                                   columns=columns)
    phosim_galaxies['uniqueId'] = pd.to_numeric(galaxies['VALUE']).tolist()
    phosim_galaxies['galSimType'] = valid_types[source_type]
    phosim_galaxies['magNorm'] = pd.to_numeric(galaxies['MAG_NORM']).tolist()
    phosim_galaxies['sedFilepath'] = galaxies['SED_NAME'].tolist()
    phosim_galaxies['redshift'] = pd.to_numeric(galaxies['REDSHIFT']).tolist()
    phosim_galaxies['raJ2000'] = pd.to_numeric(galaxies['RA']).tolist()
    phosim_galaxies['decJ2000'] = pd.to_numeric(galaxies['DEC']).tolist()
    phosim_galaxies['majorAxis'] = \
        radiansFromArcsec(pd.to_numeric(galaxies['PAR1'])).tolist()
    phosim_galaxies['minorAxis'] = \
        radiansFromArcsec(pd.to_numeric(galaxies['PAR2'])).tolist()
    phosim_galaxies['halfLightRadius'] = phosim_galaxies['majorAxis']
    phosim_galaxies['positionAngle'] = \
        (np.pi/180.*pd.to_numeric(galaxies['PAR3'])).tolist()
    phosim_galaxies['sindex'] = pd.to_numeric(galaxies['PAR4']).tolist()
    n_gal = len(phosim_galaxies.raJ2000.values)
    phosim_galaxies = phosim_galaxies.assign(raICRS=phosim_galaxies.raJ2000,
                                             decICRS=phosim_galaxies.decJ2000,
                                             properMotionRa=np.zeros(n_gal),
                                             properMotionDec=np.zeros(n_gal),
                                             parallax=np.zeros(n_gal),
                                             radialVelocity=np.zeros(n_gal))

    if len(phosim_galaxies) > 0:
        phosim_galaxies = extract_extinction(galaxies, phosim_galaxies, 5)

    return pd.concat((phosim_stars, phosim_galaxies), ignore_index=True)
Пример #30
0
def pixelCoordsFromRaDec(ra, dec, pm_ra=None, pm_dec=None, parallax=None, v_rad=None,
                         obs_metadata=None,
                         chipName=None, camera=None,
                         epoch=2000.0, includeDistortion=True):
    """
    Get the pixel positions (or nan if not on a chip) for objects based
    on their RA, and Dec (in degrees)

    @param [in] ra is in degrees in the International Celestial Reference System.
    Can be either a float or a numpy array.

    @param [in] dec is in degrees in the International Celestial Reference System.
    Can be either a float or a numpy array.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in arcsec
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).


    @param [in] obs_metadata is an ObservationMetaData characterizing the telescope
    pointing.

    @param [in] epoch is the epoch in Julian years of the equinox against which
    RA is measured.  Default is 2000.

    @param [in] chipName designates the names of the chips on which the pixel
    coordinates will be reckoned.  Can be either single value, an array, or None.
    If an array, there must be as many chipNames as there are (RA, Dec) pairs.
    If a single value, all of the pixel coordinates will be reckoned on the same
    chip.  If None, this method will calculate which chip each(RA, Dec) pair actually
    falls on, and return pixel coordinates for each (RA, Dec) pair on the appropriate
    chip.  Default is None.

    @param [in] camera is an afwCameraGeom object specifying the attributes of the camera.
    This is an optional argument to be passed to chipName.

    @param [in] includeDistortion is a boolean.  If True (default), then this method will
    return the true pixel coordinates with optical distortion included.  If False, this
    method will return TAN_PIXEL coordinates, which are the pixel coordinates with
    estimated optical distortion removed.  See the documentation in afw.cameraGeom for more
    details.

    @param [out] a 2-D numpy array in which the first row is the x pixel coordinate
    and the second row is the y pixel coordinate
    """

    if pm_ra is not None:
        pm_ra_out = radiansFromArcsec(pm_ra)
    else:
        pm_ra_out = None

    if pm_dec is not None:
        pm_dec_out = radiansFromArcsec(pm_dec)
    else:
        pm_dec_out = None

    if parallax is not None:
        parallax_out = radiansFromArcsec(parallax)
    else:
        parallax_out = None

    return _pixelCoordsFromRaDec(np.radians(ra), np.radians(dec),
                                 pm_ra=pm_ra_out, pm_dec=pm_dec_out,
                                 parallax=parallax_out, v_rad=v_rad,
                                 chipName=chipName, camera=camera,
                                 includeDistortion=includeDistortion,
                                 obs_metadata=obs_metadata, epoch=epoch)
Пример #31
0
    def test_flare_magnitudes_mixed_with_none(self):
        """
        Test that we get the expected magnitudes out
        """
        db = MLT_test_DB(database=self.db_name, driver='sqlite')

        # load the quiescent SEDs of the objects in our catalog
        sed_list = SedList(['lte028-5.0+0.5a+0.0.BT-Settl.spec.gz']*4,
                           [17.1, 17.2, 17.3, 17.4],
                           galacticAvList = [2.432, 1.876, 2.654, 2.364],
                           fileDir=getPackageDir('sims_sed_library'),
                           specMap=defaultSpecMap)

        bp_dict = BandpassDict.loadTotalBandpassesFromFiles()

        # calculate the quiescent fluxes of the objects in our catalog
        baseline_fluxes = bp_dict.fluxListForSedList(sed_list)

        bb_wavelen = np.arange(100.0, 1600.0, 0.1)
        bb = models.BlackBody(temperature=9000.0 * u.K, scale=1.0 * u.erg / (u.cm ** 2 * u.AA * u.s * u.sr))
        bb_flambda = bb(bb_wavelen * u.nm).to_value()

        # this data is taken from the setUpClass() classmethod above
        t0_list = [456.2, 41006.2, 117.2, 10456.2]
        av_list = [2.432, 1.876, 2.654, 2.364]
        parallax_list = np.array([0.25, 0.15, 0.3, 0.22])
        distance_list = 1.0/(206265.0*radiansFromArcsec(0.001*parallax_list))
        distance_list *= 3.0857e18  # convert to cm

        dtype = np.dtype([('id', int), ('u', float), ('g', float)])

        photParams = PhotometricParameters()

        ss = Sed()

        quiet_cat_name = os.path.join(self.scratch_dir, 'mlt_mixed_with_none_quiet_cat.txt')
        flare_cat_name = os.path.join(self.scratch_dir, 'mlt_mixed_with_none_flaring_cat.txt')

        # loop over several MJDs and verify that, to within a
        # milli-mag, our flaring model gives us the magnitudes
        # expected, given the light curves specified in
        # setUpClass()
        for mjd in (59580.0, 60000.0, 70000.0, 80000.0):

            obs = ObservationMetaData(mjd=mjd)

            quiet_cat = QuiescentCatalog(db, obs_metadata=obs)
            quiet_cat.write_catalog(quiet_cat_name)

            flare_cat = FlaringCatalog(db, obs_metadata=obs)
            flare_cat._mlt_lc_file = self.mlt_lc_name
            flare_cat.write_catalog(flare_cat_name)

            quiescent_data = np.genfromtxt(quiet_cat_name, dtype=dtype, delimiter=',')
            flaring_data = np.genfromtxt(flare_cat_name, dtype=dtype, delimiter=',')
            self.assertGreater(len(flaring_data), 3)

            for ix in range(len(flaring_data)):
                obj_id = flaring_data['id'][ix]
                self.assertEqual(obj_id, ix)

                # the models below are as specified in the
                # setUpClass() method
                if obj_id == 0 or obj_id == 1:
                    amp = 1.0e42
                    dt = 3652.5
                    t_min = flare_cat._survey_start - t0_list[obj_id]

                    tt = mjd - t_min
                    while tt > dt:
                        tt -= dt

                    u_flux = amp*(1.0+np.power(np.sin(tt/100.0), 2))
                    g_flux = amp*(1.0+np.power(np.cos(tt/100.0), 2))
                elif obj_id==2:
                    amp = 2.0e41
                    dt = 365.25
                    t_min = flare_cat._survey_start - t0_list[obj_id]

                    tt = mjd - t_min
                    while tt > dt:
                        tt -= dt
                    u_flux = amp*(1.0+np.power(np.sin(tt/50.0), 2))
                    g_flux = amp*(1.0+np.power(np.cos(tt/50.0), 2))
                else:
                    u_flux = 0.0
                    g_flux = 0.0

                # calculate the multiplicative effect of dust on a 9000K
                # black body
                bb_sed = Sed(wavelen=bb_wavelen, flambda=bb_flambda)
                u_bb_flux = bb_sed.calcFlux(bp_dict['u'])
                g_bb_flux = bb_sed.calcFlux(bp_dict['g'])
                a_x, b_x = bb_sed.setupCCM_ab()
                bb_sed.addDust(a_x, b_x, A_v=av_list[obj_id])
                u_bb_dusty_flux = bb_sed.calcFlux(bp_dict['u'])
                g_bb_dusty_flux = bb_sed.calcFlux(bp_dict['g'])

                dust_u = u_bb_dusty_flux/u_bb_flux
                dust_g = g_bb_dusty_flux/g_bb_flux

                area = 4.0*np.pi*np.power(distance_list[obj_id], 2)
                tot_u_flux = baseline_fluxes[obj_id][0] + u_flux*dust_u/area
                tot_g_flux = baseline_fluxes[obj_id][1] + g_flux*dust_g/area

                msg = ('failed on object %d; mjd %.2f\n u_quiet %e u_flare %e\n g_quiet %e g_flare %e' %
                       (obj_id, mjd, quiescent_data['u'][obj_id], flaring_data['u'][obj_id],
                        quiescent_data['g'][obj_id], flaring_data['g'][obj_id]))

                self.assertEqual(quiescent_data['id'][obj_id], flaring_data['id'][obj_id], msg=msg)
                self.assertAlmostEqual(ss.magFromFlux(baseline_fluxes[obj_id][0]),
                                       quiescent_data['u'][obj_id], 3, msg=msg)
                self.assertAlmostEqual(ss.magFromFlux(baseline_fluxes[obj_id][1]),
                                       quiescent_data['g'][obj_id], 3, msg=msg)
                self.assertAlmostEqual(ss.magFromFlux(tot_u_flux), flaring_data['u'][obj_id],
                                       3, msg=msg)
                self.assertAlmostEqual(ss.magFromFlux(tot_g_flux), flaring_data['g'][obj_id],
                                       3, msg=msg)
                if obj_id != 3:
                    self.assertGreater(np.abs(flaring_data['g'][obj_id]-quiescent_data['g'][obj_id]),
                                       0.001, msg=msg)
                    self.assertGreater(np.abs(flaring_data['u'][obj_id]-quiescent_data['u'][obj_id]),
                                       0.001, msg=msg)
                else:
                    self.assertEqual(flaring_data['g'][obj_id]-quiescent_data['g'][obj_id], 0.0, msg=msg)
                    self.assertEqual(flaring_data['u'][obj_id]-quiescent_data['u'][obj_id], 0.0, msg=msg)

        if os.path.exists(quiet_cat_name):
            os.unlink(quiet_cat_name)
        if os.path.exists(flare_cat_name):
            os.unlink(flare_cat_name)
Пример #32
0
    def sprinkle(self):
        # Define a list that we can write out to a text file
        lenslines = []
        # For each galaxy in the catsim catalog
        updated_catalog = self.catalog.copy()
        print("Running sprinkler. Catalog Length: ", len(self.catalog))
        for rowNum, row in enumerate(self.catalog):
            if rowNum == 100 or rowNum % 100000==0:
                print("Gone through ", rowNum, " lines of catalog.")
            if not np.isnan(row['galaxyAgn_magNorm']):
                candidates = self.find_lens_candidates(row['galaxyAgn_redshift'],
                                                       row['galaxyAgn_magNorm'])
                varString = json.loads(row['galaxyAgn_varParamStr'])
                varString['pars']['t0_mjd'] = 59300.0
                row['galaxyAgn_varParamStr'] = json.dumps(varString)
                np.random.seed(row['galtileid'] % (2^32 -1))
                pick_value = np.random.uniform()
            # If there aren't any lensed sources at this redshift from OM10 move on the next object
                if ((len(candidates) > 0) and (pick_value <= self.density_param)):
                    # Randomly choose one the lens systems
                    # (can decide with or without replacement)
                    # Sort first to make sure the same choice is made every time
                    candidates = candidates[np.argsort(candidates['twinklesId'])]
                    newlens = np.random.choice(candidates)

                    # Append the lens galaxy
                    # For each image, append the lens images
                    for i in range(newlens['NIMG']):
                        lensrow = row.copy()
                        # XIMG and YIMG are in arcseconds
                        # raPhSim and decPhoSim are in radians
                        #Shift all parts of the lensed object, not just its agn part
                        for lensPart in ['galaxyBulge', 'galaxyDisk', 'galaxyAgn']:
                            lens_ra = lensrow[str(lensPart+'_raJ2000')]
                            lens_dec = lensrow[str(lensPart+'_decJ2000')]
                            delta_ra = np.radians(newlens['XIMG'][i] / 3600.0) / np.cos(lens_dec)
                            delta_dec = np.radians(newlens['YIMG'][i] / 3600.0)
                            lensrow[str(lensPart + '_raJ2000')] = lens_ra + delta_ra
                            lensrow[str(lensPart + '_decJ2000')] = lens_dec + delta_dec
                        mag_adjust = 2.5*np.log10(np.abs(newlens['MAG'][i]))
                        lensrow['galaxyAgn_magNorm'] -= mag_adjust
                        varString = json.loads(lensrow['galaxyAgn_varParamStr'])
                        varString['pars']['t0Delay'] = newlens['DELAY'][i]
                        varString['varMethodName'] = 'applyAgnTimeDelay'
                        lensrow['galaxyAgn_varParamStr'] = json.dumps(varString)
                        lensrow['galaxyDisk_majorAxis'] = 0.0
                        lensrow['galaxyDisk_minorAxis'] = 0.0
                        lensrow['galaxyDisk_positionAngle'] = 0.0
                        lensrow['galaxyDisk_internalAv'] = 0.0
                        lensrow['galaxyDisk_magNorm'] = np.nan
                        lensrow['galaxyDisk_sedFilename'] = None
                        lensrow['galaxyBulge_majorAxis'] = 0.0
                        lensrow['galaxyBulge_minorAxis'] = 0.0
                        lensrow['galaxyBulge_positionAngle'] = 0.0
                        lensrow['galaxyBulge_internalAv'] = 0.0
                        lensrow['galaxyBulge_magNorm'] = np.nan
                        lensrow['galaxyBulge_sedFilename'] = None
                        lensrow['galaxyBulge_redshift'] = newlens['ZSRC']
                        lensrow['galaxyDisk_redshift'] = newlens['ZSRC']
                        lensrow['galaxyAgn_redshift'] = newlens['ZSRC']
                        #To get back twinklesID in lens catalog from phosim catalog id number
                        #just use np.right_shift(phosimID-28, 10). Take the floor of the last
                        #3 numbers to get twinklesID in the twinkles lens catalog and the remainder is
                        #the image number minus 1.
                        lensrow['galtileid'] = (lensrow['galtileid']*10000 +
                                                newlens['twinklesId']*4 + i)

                        updated_catalog = np.append(updated_catalog, lensrow)

                    #Now manipulate original entry to be the lens galaxy with desired properties
                    #Start by deleting Disk and AGN properties
                    if not np.isnan(row['galaxyDisk_magNorm']):
                        row['galaxyDisk_majorAxis'] = 0.0
                        row['galaxyDisk_minorAxis'] = 0.0
                        row['galaxyDisk_positionAngle'] = 0.0
                        row['galaxyDisk_internalAv'] = 0.0
                        row['galaxyDisk_magNorm'] = np.nan
                        row['galaxyDisk_sedFilename'] = None
                    row['galaxyAgn_magNorm'] = np.nan
                    row['galaxyAgn_sedFilename'] = None
                    #Now insert desired Bulge properties
                    row['galaxyBulge_sedFilename'] = newlens['lens_sed']
                    row['galaxyBulge_redshift'] = newlens['ZLENS']
                    row['galaxyDisk_redshift'] = newlens['ZLENS']
                    row['galaxyAgn_redshift'] = newlens['ZLENS']
                    row['galaxyBulge_magNorm'] = matchBase().calcMagNorm([newlens['APMAG_I']], self.LRG, self.bandpassDict) #Changed from i band to imsimband
                    row['galaxyBulge_majorAxis'] = radiansFromArcsec(newlens['REFF'] / np.sqrt(1 - newlens['ELLIP']))
                    row['galaxyBulge_minorAxis'] = radiansFromArcsec(newlens['REFF'] * np.sqrt(1 - newlens['ELLIP']))
                    #Convert orientation angle to west of north from east of north by *-1.0 and convert to radians
                    row['galaxyBulge_positionAngle'] = newlens['PHIE']*(-1.0)*np.pi/180.0
                    #Replace original entry with new entry
                    updated_catalog[rowNum] = row

        return updated_catalog
Пример #33
0
                  host='fatboy.phys.washington.edu',
                  port=1433,
                  driver='mssql+pymssql')

    results_iter = db.get_arbitrary_chunk_iterator(query,
                                                   dtype=dtype,
                                                   chunk_size=100000)

    dummy_sed = Sed()
    _au_to_parsec = 1.0 / 206265.0
    _cm_per_parsec = 3.08576e18

    ct_bad = 0
    ct_total = 0
    for i_chunk, chunk in enumerate(results_iter):
        parallax = radiansFromArcsec(0.001 * chunk['parallax'])
        dd = _au_to_parsec / parallax
        sphere_area = 4.0 * np.pi * np.power(dd * _cm_per_parsec, 2)

        flux_factor = 1.0 / sphere_area

        dust_factor = {}
        for mag_name in mag_name_list:
            dust_factor[mag_name] = np.interp(chunk['ebv'], dust_grid['ebv'],
                                              dust_grid[mag_name])

        lc_int_dex = np.ones(len(chunk), dtype=int)
        dmag_max = np.zeros(len(chunk), dtype=float)
        mag_min = np.zeros(len(chunk), dtype=float)
        for i_star, star in enumerate(chunk):
            var_dict = json.loads(star['varParamStr'])
lc_curve_time = {}
t_max_dex_dict = {}
with np.load(fname) as lc_file:
    for name in lc_file.keys():
        if 'time' in name:
            lc_curve_time[name] = lc_file[name]
        else:
            dex = np.argmax(lc_file[name])
            t_max_dex_dict[name] = dex

lc_name_list = [
    'early_active', 'early_inactive', 'mid_active', 'mid_inactive',
    'late_active'
]

milliarcsec = radiansFromArcsec(0.001)
ebv_grid = np.arange(0.01, 7.01, 0.01)
parallax_grid = np.arange(0.01 * milliarcsec, 50.0 * milliarcsec, milliarcsec)

n_steps = len(parallax_grid)

out_cache = {}
out_cache['parallax_grid(mas)'] = parallax_grid / milliarcsec

for lc_name_root in lc_name_list:
    for lc_dex in range(4):
        lc_name = lc_name_root + '_%d' % lc_dex
        print(lc_name)
        t_max_dex = t_max_dex_dict[lc_name + '_u']

        for bp in 'grizy':
Пример #35
0
    def test_different_cameras(self):
        rng = np.random.RandomState(6512)

        pointing_ra = 15.0
        pointing_dec = 13.0

        n_obj = 100
        ra_list = pointing_ra + 2.0*rng.random_sample(n_obj)
        dec_list = pointing_dec + 2.0*rng.random_sample(n_obj)
        px_list = radiansFromArcsec(0.005)*rng.random_sample(n_obj)
        px_list += radiansFromArcsec(0.001)
        mura_list = radiansFromArcsec(0.005)*rng.random_sample(n_obj)
        mudec_list = radiansFromArcsec(0.005)*rng.random_sample(n_obj)
        vrad_list = 100.0*rng.random_sample(n_obj)

        with lsst.utils.tests.getTempFilePath('.txt') as db_text_file:
            with open(db_text_file, 'w') as out_file:
                for ix, (rdeg, ddeg, rrad, drad, px, mura, mudec, vrad) in \
                    enumerate(zip(ra_list, dec_list,
                              np.radians(ra_list), np.radians(dec_list),
                              px_list, mura_list, mudec_list, vrad_list)):

                    out_file.write('%d %e %e %e %e %e %e %e %e\n' % (ix, rdeg, ddeg,
                                                                     rrad, drad,
                                                                     px,
                                                                     mura, mudec,
                                                                     vrad))

            dtype = np.dtype([('id', int), ('raDeg', float), ('decDeg', float),
                             ('raJ2000', float), ('decJ2000', float),
                             ('parallax', float),
                             ('properMotionRa', float), ('properMotionDec', float),
                             ('radialVelocity', float)])

            db = fileDBObject(db_text_file, dtype=dtype, idColKey='id')
            db.raColName = 'raDeg'
            db.decColName = 'decDeg'


        class CameraCoordsCatalog(AstrometryStars, CameraCoords,
                                  InstanceCatalog):
            camera = LsstSimMapper().camera
            column_outputs = ['id', 'chipName']


        class CameraCoordsLSSTCatalog(AstrometryStars, CameraCoordsLSST,
                                      InstanceCatalog):
            column_outputs = ['id', 'chipName']

        obs = ObservationMetaData(pointingRA=pointing_ra,
                                  pointingDec=pointing_dec,
                                  boundLength=1.75,
                                  boundType='circle',
                                  rotSkyPos=23.0,
                                  mjd=59580.0)

        control_cat = CameraCoordsCatalog(db, obs_metadata=obs)
        test_cat = CameraCoordsLSSTCatalog(db, obs_metadata=obs)

        control_line_list = []
        none_chips = 0
        for line in control_cat.iter_catalog():
            if line[1] is None:
                none_chips += 1
            control_line_list.append(line)
        self.assertGreater(len(control_line_list), 0)
        self.assertLess(none_chips, len(control_line_list)/2)

        line_ct = 0
        for line in test_cat.iter_catalog():
            line_ct += 1
            self.assertIn(line, control_line_list)
        self.assertEqual(line_ct, len(control_line_list))
Пример #36
0
def pupilCoordsFromRaDec(ra_in,
                         dec_in,
                         pm_ra=None,
                         pm_dec=None,
                         parallax=None,
                         v_rad=None,
                         includeRefraction=True,
                         obs_metadata=None,
                         epoch=2000.0):
    """
    Take an input RA and dec from the sky and convert it to coordinates
    on the focal plane.

    This uses PAL's gnomonic projection routine which assumes that the focal
    plane is perfectly flat.  The output is in Cartesian coordinates, assuming
    that the Celestial Sphere is a unit sphere.

    The RA, Dec accepted by this method are in the International Celestial
    Reference System.  Before applying the gnomonic projection, this method
    transforms those RA, Dec into observed geocentric coordinates, applying
    the effects of precession, nutation, aberration, parallax and refraction.
    This is done, because the gnomonic projection ought to be applied to what
    observers actually see, rather than the idealized, above-the-atmosphere
    coordinates represented by the ICRS.

    @param [in] ra_in is in degrees (ICRS).  Can be either a numpy array or a number.

    @param [in] dec_in is in degrees (ICRS).  Can be either a numpy array or a number.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in arcsec
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).

    @param [in] includeRefraction is a boolean controlling the application of refraction.

    @param [in] obs_metadata is an ObservationMetaData instantiation characterizing the
    telescope location and pointing.

    @param [in] epoch is the epoch of mean ra and dec in julian years (default=2000.0)

    @param [out] returns a numpy array whose first row is the x coordinate on the pupil in
    radians and whose second row is the y coordinate in radians
    """

    if pm_ra is not None:
        pm_ra_in = radiansFromArcsec(pm_ra)
    else:
        pm_ra_in = None

    if pm_dec is not None:
        pm_dec_in = radiansFromArcsec(pm_dec)
    else:
        pm_dec_in = None

    if parallax is not None:
        parallax_in = radiansFromArcsec(parallax)
    else:
        parallax_in = None

    return _pupilCoordsFromRaDec(np.radians(ra_in),
                                 np.radians(dec_in),
                                 pm_ra=pm_ra_in,
                                 pm_dec=pm_dec_in,
                                 parallax=parallax_in,
                                 v_rad=v_rad,
                                 includeRefraction=includeRefraction,
                                 obs_metadata=obs_metadata,
                                 epoch=epoch)
Пример #37
0
    def test_flare_magnitudes_mixed_with_dummy(self):
        """
        Test that we get the expected magnitudes out
        """
        db = MLT_test_DB(database=self.db_name, driver='sqlite')

        # load the quiescent SEDs of the objects in our catalog
        sed_list = SedList(['lte028-5.0+0.5a+0.0.BT-Settl.spec.gz']*4,
                           [17.1, 17.2, 17.3, 17.4],
                           galacticAvList = [2.432, 1.876, 2.654, 2.364],
                           fileDir=getPackageDir('sims_sed_library'),
                           specMap=defaultSpecMap)

        bp_dict = BandpassDict.loadTotalBandpassesFromFiles()

        # calculate the quiescent fluxes of the objects in our catalog
        baseline_fluxes = bp_dict.fluxListForSedList(sed_list)

        bb_wavelen = np.arange(100.0, 1600.0, 0.1)
        bb_flambda = blackbody_lambda(bb_wavelen*10.0, 9000.0)

        # this data is taken from the setUpClass() classmethod above
        t0_list = [456.2, 41006.2, 117.2, 10456.2]
        av_list = [2.432, 1.876, 2.654, 2.364]
        parallax_list = np.array([0.25, 0.15, 0.3, 0.22])
        distance_list = 1.0/(206265.0*radiansFromArcsec(0.001*parallax_list))
        distance_list *= 3.0857e18  # convert to cm

        dtype = np.dtype([('id', int), ('u', float), ('g', float)])

        photParams = PhotometricParameters()

        ss = Sed()

        quiet_cat_name = os.path.join(self.scratch_dir, 'mlt_mixed_with_dummy_quiet_cat.txt')
        flare_cat_name = os.path.join(self.scratch_dir, 'mlt_mixed_with_dummy_flaring_cat.txt')

        # loop over several MJDs and verify that, to within a
        # milli-mag, our flaring model gives us the magnitudes
        # expected, given the light curves specified in
        # setUpClass()
        for mjd in (59580.0, 60000.0, 70000.0, 80000.0):

            obs = ObservationMetaData(mjd=mjd)

            quiet_cat = QuiescentCatalog(db, obs_metadata=obs)
            quiet_cat.write_catalog(quiet_cat_name)

            flare_cat = FlaringCatalogDummy(db, obs_metadata=obs)
            flare_cat.scratch_dir = self.scratch_dir
            flare_cat._mlt_lc_file = self.mlt_lc_name
            flare_cat.write_catalog(flare_cat_name)

            quiescent_data = np.genfromtxt(quiet_cat_name, dtype=dtype, delimiter=',')
            flaring_data = np.genfromtxt(flare_cat_name, dtype=dtype, delimiter=',')

            self.assertGreater(len(quiescent_data), 2)
            self.assertEqual(len(quiescent_data), len(flaring_data))
            self.assertIn(3, flaring_data['id'])

            for ix in range(len(flaring_data)):
                obj_id = flaring_data['id'][ix]
                self.assertEqual(obj_id, ix)


                msg = ('failed on object %d; mjd %.2f\n u_quiet %e u_flare %e\n g_quiet %e g_flare %e' %
                       (obj_id, mjd, quiescent_data['u'][obj_id], flaring_data['u'][obj_id],
                        quiescent_data['g'][obj_id], flaring_data['g'][obj_id]))

                self.assertEqual(quiescent_data['id'][obj_id], flaring_data['id'][obj_id], msg=msg)
                self.assertAlmostEqual(ss.magFromFlux(baseline_fluxes[obj_id][0]),
                                       quiescent_data['u'][obj_id], 3, msg=msg)
                self.assertAlmostEqual(ss.magFromFlux(baseline_fluxes[obj_id][1]),
                                       quiescent_data['g'][obj_id], 3, msg=msg)
                if obj_id != 3:

                    # the models below are as specified in the
                    # setUpClass() method
                    if obj_id == 0 or obj_id == 1:
                        amp = 1.0e42
                        dt = 3652.5
                        t_min = flare_cat._survey_start - t0_list[obj_id]

                        tt = mjd - t_min
                        while tt > dt:
                            tt -= dt

                        u_flux = amp*(1.0+np.power(np.sin(tt/100.0), 2))
                        g_flux = amp*(1.0+np.power(np.cos(tt/100.0), 2))
                    elif obj_id==2:
                        amp = 2.0e41
                        dt = 365.25
                        t_min = flare_cat._survey_start - t0_list[obj_id]

                        tt = mjd - t_min
                        while tt > dt:
                            tt -= dt
                        u_flux = amp*(1.0+np.power(np.sin(tt/50.0), 2))
                        g_flux = amp*(1.0+np.power(np.cos(tt/50.0), 2))

                    # calculate the multiplicative effect of dust on a 9000K
                    # black body
                    bb_sed = Sed(wavelen=bb_wavelen, flambda=bb_flambda)
                    u_bb_flux = bb_sed.calcFlux(bp_dict['u'])
                    g_bb_flux = bb_sed.calcFlux(bp_dict['g'])
                    a_x, b_x = bb_sed.setupCCM_ab()
                    bb_sed.addDust(a_x, b_x, A_v=av_list[obj_id])
                    u_bb_dusty_flux = bb_sed.calcFlux(bp_dict['u'])
                    g_bb_dusty_flux = bb_sed.calcFlux(bp_dict['g'])

                    dust_u = u_bb_dusty_flux/u_bb_flux
                    dust_g = g_bb_dusty_flux/g_bb_flux

                    area = 4.0*np.pi*np.power(distance_list[obj_id], 2)
                    tot_u_flux = baseline_fluxes[obj_id][0] + u_flux*dust_u/area
                    tot_g_flux = baseline_fluxes[obj_id][1] + g_flux*dust_g/area

                    self.assertAlmostEqual(ss.magFromFlux(tot_u_flux), flaring_data['u'][obj_id],
                                           3, msg=msg)
                    self.assertAlmostEqual(ss.magFromFlux(tot_g_flux), flaring_data['g'][obj_id],
                                           3, msg=msg)

                    self.assertGreater(np.abs(flaring_data['g'][obj_id]-quiescent_data['g'][obj_id]),
                                       0.001, msg=msg)
                    self.assertGreater(np.abs(flaring_data['u'][obj_id]-quiescent_data['u'][obj_id]),
                                       0.001, msg=msg)
                else:
                    self.assertAlmostEqual(flaring_data['g'][obj_id],
                                           quiescent_data['g'][obj_id]+3*(mjd-59580.0)/10000.0,
                                           3, msg=msg)
                    self.assertAlmostEqual(flaring_data['u'][obj_id],
                                           quiescent_data['u'][obj_id]+2*(mjd-59580.0)/10000.0,
                                           3, msg=msg)

        if os.path.exists(quiet_cat_name):
            os.unlink(quiet_cat_name)
        if os.path.exists(flare_cat_name):
            os.unlink(flare_cat_name)
Пример #38
0
def chipNameFromRaDec(ra,
                      dec,
                      pm_ra=None,
                      pm_dec=None,
                      parallax=None,
                      v_rad=None,
                      obs_metadata=None,
                      camera=None,
                      epoch=2000.0,
                      allow_multiple_chips=False):
    """
    Return the names of detectors that see the object specified by
    (RA, Dec) in degrees.

    @param [in] ra in degrees (a numpy array or a float).
    In the International Celestial Reference System.

    @param [in] dec in degrees (a numpy array or a float).
    In the International Celestial Reference System.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in arcsec
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).

    @param [in] obs_metadata is an ObservationMetaData characterizing the telescope pointing

    @param [in] epoch is the epoch in Julian years of the equinox against which RA and Dec are
    measured.  Default is 2000.

    @param [in] camera is an afw.cameraGeom camera instance characterizing the camera

    @param [in] allow_multiple_chips is a boolean (default False) indicating whether or not
    this method will allow objects to be visible on more than one chip.  If it is 'False'
    and an object appears on more than one chip, an exception will be raised.  If it is 'True'
    and an object falls on more than one chip, it will still only return the first chip in the
    list of chips returned. THIS BEHAVIOR SHOULD BE FIXED IN A FUTURE TICKET.

    @param [out] a numpy array of chip names
    """
    if pm_ra is not None:
        pm_ra_out = radiansFromArcsec(pm_ra)
    else:
        pm_ra_out = None

    if pm_dec is not None:
        pm_dec_out = radiansFromArcsec(pm_dec)
    else:
        pm_dec_out = None

    if parallax is not None:
        parallax_out = radiansFromArcsec(parallax)
    else:
        parallax_out = None

    return _chipNameFromRaDec(np.radians(ra),
                              np.radians(dec),
                              pm_ra=pm_ra_out,
                              pm_dec=pm_dec_out,
                              parallax=parallax_out,
                              v_rad=v_rad,
                              obs_metadata=obs_metadata,
                              epoch=epoch,
                              camera=camera,
                              allow_multiple_chips=allow_multiple_chips)
Пример #39
0
    def sprinkle(self):
        # Define a list that we can write out to a text file
        lenslines = []
        # For each galaxy in the catsim catalog
        updated_catalog = self.catalog.copy()
        # print("Running sprinkler. Catalog Length: ", len(self.catalog))
        for rowNum, row in enumerate(self.catalog):
            # if rowNum == 100 or rowNum % 100000==0:
            #     print("Gone through ", rowNum, " lines of catalog.")
            if not np.isnan(row[self.defs_dict['galaxyAgn_magNorm']]):
                candidates = self.find_lens_candidates(
                    row[self.defs_dict['galaxyAgn_redshift']],
                    row[self.defs_dict['galaxyAgn_magNorm']])
                #varString = json.loads(row[self.defs_dict['galaxyAgn_varParamStr']])
                # varString[self.defs_dict['pars']]['t0_mjd'] = 59300.0
                #row[self.defs_dict['galaxyAgn_varParamStr']] = json.dumps(varString)
                np.random.seed(row[self.defs_dict['galtileid']] % (2 ^ 32 - 1))
                pick_value = np.random.uniform()
                # If there aren't any lensed sources at this redshift from OM10 move on the next object
                if (((len(candidates) > 0) and
                     (pick_value <= self.density_param) and
                     (self.cached_sprinkling is False)) |
                    ((self.cached_sprinkling is True) and
                     (row[self.defs_dict['galtileid']]
                      in self.agn_cache['galtileid'].values))):
                    # Randomly choose one the lens systems
                    # (can decide with or without replacement)
                    # Sort first to make sure the same choice is made every time
                    if self.cached_sprinkling is True:
                        twinkles_sys_cache = self.agn_cache.query(
                            'galtileid == %i' %
                            row[self.defs_dict['galtileid']]
                        )['twinkles_system'].values[0]
                        newlens = self.lenscat[np.where(
                            self.lenscat['twinklesId'] == twinkles_sys_cache)
                                               [0]][0]
                    else:
                        candidates = candidates[np.argsort(
                            candidates['twinklesId'])]
                        newlens = np.random.choice(candidates)
                    # Append the lens galaxy
                    # For each image, append the lens images
                    for i in range(newlens['NIMG']):
                        lensrow = row.copy()
                        # XIMG and YIMG are in arcseconds
                        # raPhSim and decPhoSim are in radians
                        #Shift all parts of the lensed object, not just its agn part
                        for lensPart in [
                                'galaxyBulge', 'galaxyDisk', 'galaxyAgn'
                        ]:
                            lens_ra = lensrow[self.defs_dict[str(lensPart +
                                                                 '_raJ2000')]]
                            lens_dec = lensrow[self.defs_dict[str(
                                lensPart + '_decJ2000')]]
                            delta_ra = np.radians(
                                newlens['XIMG'][i] / 3600.0) / np.cos(lens_dec)
                            delta_dec = np.radians(newlens['YIMG'][i] / 3600.0)
                            lensrow[self.defs_dict[str(
                                lensPart + '_raJ2000')]] = lens_ra + delta_ra
                            lensrow[self.defs_dict[
                                str(lensPart +
                                    '_decJ2000')]] = lens_dec + delta_dec
                        mag_adjust = 2.5 * np.log10(np.abs(newlens['MAG'][i]))
                        lensrow[
                            self.defs_dict['galaxyAgn_magNorm']] -= mag_adjust
                        varString = json.loads(
                            lensrow[self.defs_dict['galaxyAgn_varParamStr']])
                        varString[self.defs_dict['pars']]['t0Delay'] = newlens[
                            'DELAY'][i]
                        varString[self.defs_dict[
                            'varMethodName']] = 'applyAgnTimeDelay'
                        lensrow[self.defs_dict[
                            'galaxyAgn_varParamStr']] = json.dumps(varString)
                        lensrow[self.defs_dict['galaxyDisk_majorAxis']] = 0.0
                        lensrow[self.defs_dict['galaxyDisk_minorAxis']] = 0.0
                        lensrow[
                            self.defs_dict['galaxyDisk_positionAngle']] = 0.0
                        lensrow[self.defs_dict['galaxyDisk_internalAv']] = 0.0
                        lensrow[self.defs_dict[
                            'galaxyDisk_magNorm']] = 999.  #np.nan To be fixed post run1.1
                        lensrow[
                            self.defs_dict['galaxyDisk_sedFilename']] = None
                        lensrow[self.defs_dict['galaxyBulge_majorAxis']] = 0.0
                        lensrow[self.defs_dict['galaxyBulge_minorAxis']] = 0.0
                        lensrow[
                            self.defs_dict['galaxyBulge_positionAngle']] = 0.0
                        lensrow[self.defs_dict['galaxyBulge_internalAv']] = 0.0
                        lensrow[self.defs_dict[
                            'galaxyBulge_magNorm']] = 999.  #np.nan To be fixed post run1.1
                        lensrow[
                            self.defs_dict['galaxyBulge_sedFilename']] = None
                        lensrow[self.defs_dict[
                            'galaxyBulge_redshift']] = newlens['ZSRC']
                        lensrow[self.defs_dict[
                            'galaxyDisk_redshift']] = newlens['ZSRC']
                        lensrow[self.defs_dict[
                            'galaxyAgn_redshift']] = newlens['ZSRC']
                        #To get back twinklesID in lens catalog from phosim catalog id number
                        #just use np.right_shift(phosimID-28, 10). Take the floor of the last
                        #3 numbers to get twinklesID in the twinkles lens catalog and the remainder is
                        #the image number minus 1.
                        lensrow[self.defs_dict['galtileid']] = (
                            lensrow[self.defs_dict['galtileid']] * 10000 +
                            newlens['twinklesId'] * 4 + i)

                        updated_catalog = np.append(updated_catalog, lensrow)

                    #Now manipulate original entry to be the lens galaxy with desired properties
                    #Start by deleting Disk and AGN properties
                    if not np.isnan(row[self.defs_dict['galaxyDisk_magNorm']]):
                        row[self.defs_dict['galaxyDisk_majorAxis']] = 0.0
                        row[self.defs_dict['galaxyDisk_minorAxis']] = 0.0
                        row[self.defs_dict['galaxyDisk_positionAngle']] = 0.0
                        row[self.defs_dict['galaxyDisk_internalAv']] = 0.0
                        row[self.defs_dict[
                            'galaxyDisk_magNorm']] = 999.  #np.nan To be fixed post run1.1
                        row[self.defs_dict['galaxyDisk_sedFilename']] = None
                    row[self.defs_dict[
                        'galaxyAgn_magNorm']] = None  #np.nan To be fixed post run1.1
                    row[self.defs_dict[
                        'galaxyDisk_magNorm']] = 999.  # To be fixed in run1.1
                    row[self.defs_dict['galaxyAgn_sedFilename']] = None
                    #Now insert desired Bulge properties
                    row[self.defs_dict['galaxyBulge_sedFilename']] = newlens[
                        'lens_sed']
                    row[self.
                        defs_dict['galaxyBulge_redshift']] = newlens['ZLENS']
                    row[self.
                        defs_dict['galaxyDisk_redshift']] = newlens['ZLENS']
                    row[self.
                        defs_dict['galaxyAgn_redshift']] = newlens['ZLENS']
                    row_lens_sed = Sed()
                    row_lens_sed.readSED_flambda(
                        str(self.galDir + newlens['lens_sed']))
                    row_lens_sed.redshiftSED(newlens['ZLENS'], dimming=True)
                    row[self.defs_dict['galaxyBulge_magNorm']] = matchBase(
                    ).calcMagNorm(
                        [newlens['APMAG_I']], row_lens_sed,
                        self.bandpassDict)  #Changed from i band to imsimband
                    row[self.defs_dict[
                        'galaxyBulge_majorAxis']] = radiansFromArcsec(
                            newlens['REFF'] / np.sqrt(1 - newlens['ELLIP']))
                    row[self.defs_dict[
                        'galaxyBulge_minorAxis']] = radiansFromArcsec(
                            newlens['REFF'] * np.sqrt(1 - newlens['ELLIP']))
                    #Convert orientation angle to west of north from east of north by *-1.0 and convert to radians
                    row[self.defs_dict['galaxyBulge_positionAngle']] = newlens[
                        'PHIE'] * (-1.0) * np.pi / 180.0
                    #Replace original entry with new entry
                    updated_catalog[rowNum] = row
            else:
                if self.cached_sprinkling is True:
                    if row[self.defs_dict['galtileid']] in self.sne_cache[
                            'galtileid'].values:
                        use_system = self.sne_cache.query(
                            'galtileid == %i' %
                            row[self.defs_dict['galtileid']]
                        )['twinkles_system'].values
                        use_df = self.sne_catalog.query(
                            'twinkles_sysno == %i' % use_system)
                        self.used_systems.append(use_system)
                    else:
                        continue
                else:
                    lens_sne_candidates = self.find_sne_lens_candidates(
                        row[self.defs_dict['galaxyDisk_redshift']])
                    candidate_sysno = np.unique(
                        lens_sne_candidates['twinkles_sysno'])
                    num_candidates = len(candidate_sysno)
                    if num_candidates == 0:
                        continue
                    used_already = np.array([
                        sys_num in self.used_systems
                        for sys_num in candidate_sysno
                    ])
                    unused_sysno = candidate_sysno[~used_already]
                    if len(unused_sysno) == 0:
                        continue
                    np.random.seed(row[self.defs_dict['galtileid']] %
                                   (2 ^ 32 - 1))
                    use_system = np.random.choice(unused_sysno)
                    use_df = self.sne_catalog.query('twinkles_sysno == %i' %
                                                    use_system)

                for i in range(len(use_df)):
                    lensrow = row.copy()
                    for lensPart in ['galaxyBulge', 'galaxyDisk', 'galaxyAgn']:
                        lens_ra = lensrow[self.defs_dict[str(lensPart +
                                                             '_raJ2000')]]
                        lens_dec = lensrow[self.defs_dict[str(lensPart +
                                                              '_decJ2000')]]
                        delta_ra = np.radians(
                            use_df['x'].iloc[i] / 3600.0) / np.cos(lens_dec)
                        delta_dec = np.radians(use_df['y'].iloc[i] / 3600.0)
                        lensrow[self.defs_dict[str(
                            lensPart + '_raJ2000')]] = lens_ra + delta_ra
                        lensrow[self.defs_dict[str(
                            lensPart + '_decJ2000')]] = lens_dec + delta_dec
                    # varString = json.loads(lensrow[self.defs_dict['galaxyAgn_varParamStr']])
                    varString = 'None'
                    lensrow[
                        self.defs_dict['galaxyAgn_varParamStr']] = varString
                    lensrow[self.defs_dict['galaxyDisk_majorAxis']] = 0.0
                    lensrow[self.defs_dict['galaxyDisk_minorAxis']] = 0.0
                    lensrow[self.defs_dict['galaxyDisk_positionAngle']] = 0.0
                    lensrow[self.defs_dict['galaxyDisk_internalAv']] = 0.0
                    lensrow[self.defs_dict[
                        'galaxyDisk_magNorm']] = 999.  #np.nan To be fixed post run1.1
                    lensrow[self.defs_dict['galaxyDisk_sedFilename']] = None
                    lensrow[self.defs_dict['galaxyBulge_majorAxis']] = 0.0
                    lensrow[self.defs_dict['galaxyBulge_minorAxis']] = 0.0
                    lensrow[self.defs_dict['galaxyBulge_positionAngle']] = 0.0
                    lensrow[self.defs_dict['galaxyBulge_internalAv']] = 0.0
                    lensrow[self.defs_dict[
                        'galaxyBulge_magNorm']] = 999.  #np.nan To be fixed post run1.1
                    lensrow[self.defs_dict['galaxyBulge_sedFilename']] = None
                    z_s = use_df['zs'].iloc[i]
                    lensrow[self.defs_dict['galaxyBulge_redshift']] = z_s
                    lensrow[self.defs_dict['galaxyDisk_redshift']] = z_s
                    lensrow[self.defs_dict['galaxyAgn_redshift']] = z_s
                    #To get back twinklesID in lens catalog from phosim catalog id number
                    #just use np.right_shift(phosimID-28, 10). Take the floor of the last
                    #3 numbers to get twinklesID in the twinkles lens catalog and the remainder is
                    #the image number minus 1.
                    lensrow[self.defs_dict['galtileid']] = (
                        lensrow[self.defs_dict['galtileid']] * 10000 +
                        use_system * 4 + i)

                    add_to_cat, sn_magnorm, sn_fname = self.create_sn_sed(
                        use_df.iloc[i],
                        lensrow[self.defs_dict['galaxyAgn_raJ2000']],
                        lensrow[self.defs_dict['galaxyAgn_decJ2000']],
                        self.visit_mjd)
                    lensrow[self.defs_dict['galaxyAgn_sedFilename']] = sn_fname
                    lensrow[self.defs_dict[
                        'galaxyAgn_magNorm']] = sn_magnorm  #This will need to be adjusted to proper band
                    mag_adjust = 2.5 * np.log10(np.abs(use_df['mu'].iloc[i]))
                    lensrow[self.defs_dict['galaxyAgn_magNorm']] -= mag_adjust

                    if add_to_cat is True:
                        updated_catalog = np.append(updated_catalog, lensrow)
                    else:
                        continue
                    #Now manipulate original entry to be the lens galaxy with desired properties
                    #Start by deleting Disk and AGN properties
                if not np.isnan(row[self.defs_dict['galaxyDisk_magNorm']]):
                    row[self.defs_dict['galaxyDisk_majorAxis']] = 0.0
                    row[self.defs_dict['galaxyDisk_minorAxis']] = 0.0
                    row[self.defs_dict['galaxyDisk_positionAngle']] = 0.0
                    row[self.defs_dict['galaxyDisk_internalAv']] = 0.0
                    row[self.defs_dict[
                        'galaxyDisk_magNorm']] = 999.  #np.nan To be fixed post run1.1
                    row[self.defs_dict['galaxyDisk_sedFilename']] = None
                row[self.defs_dict[
                    'galaxyAgn_magNorm']] = None  #np.nan To be fixed post run1.1
                row[self.defs_dict[
                    'galaxyDisk_magNorm']] = 999.  #To be fixed post run1.1
                row[self.defs_dict['galaxyAgn_sedFilename']] = None
                #Now insert desired Bulge properties
                row[self.defs_dict['galaxyBulge_sedFilename']] = use_df[
                    'lens_sed'].iloc[0]
                row[self.
                    defs_dict['galaxyBulge_redshift']] = use_df['zl'].iloc[0]
                row[self.
                    defs_dict['galaxyDisk_redshift']] = use_df['zl'].iloc[0]
                row[self.
                    defs_dict['galaxyAgn_redshift']] = use_df['zl'].iloc[0]
                row[self.defs_dict['galaxyBulge_magNorm']] = use_df[
                    'bulge_magnorm'].iloc[0]
                # row[self.defs_dict['galaxyBulge_magNorm']] = matchBase().calcMagNorm([newlens['APMAG_I']], self.LRG, self.bandpassDict) #Changed from i band to imsimband
                row[self.
                    defs_dict['galaxyBulge_majorAxis']] = radiansFromArcsec(
                        use_df['r_eff'].iloc[0] /
                        np.sqrt(1 - use_df['e'].iloc[0]))
                row[self.
                    defs_dict['galaxyBulge_minorAxis']] = radiansFromArcsec(
                        use_df['r_eff'].iloc[0] *
                        np.sqrt(1 - use_df['e'].iloc[0]))
                #Convert orientation angle to west of north from east of north by *-1.0 and convert to radians
                row[self.defs_dict['galaxyBulge_positionAngle']] = use_df[
                    'theta_e'].iloc[0] * (-1.0) * np.pi / 180.0
                #Replace original entry with new entry
                updated_catalog[rowNum] = row

        return updated_catalog
Пример #40
0
    def test_with_proper_motion(self):
        """
        Test that calculating pupil coordinates in the presence of proper motion, parallax,
        and radial velocity is equivalent to
        observedFromICRS -> icrsFromObserved -> pupilCoordsFromRaDec
        (mostly to make surethat pupilCoordsFromRaDec is correctly calling observedFromICRS
        with non-zero proper motion, etc.)
        """
        rng = np.random.RandomState(38442)
        is_valid = False
        while not is_valid:
            mjd_tai = 59580.0 + 10000.0 * rng.random_sample()
            obs = ObservationMetaData(mjd=mjd_tai)
            ra, dec = raDecFromAltAz(78.0, 112.0, obs)
            dd = distanceToSun(ra, dec, obs.mjd)
            if dd > 45.0:
                is_valid = True

        n_obj = 1000
        rr = rng.random_sample(n_obj) * 2.0
        theta = rng.random_sample(n_obj) * 2.0 * np.pi
        ra_list = ra + rr * np.cos(theta)
        dec_list = dec + rr * np.sin(theta)
        obs = ObservationMetaData(pointingRA=ra,
                                  pointingDec=dec,
                                  mjd=mjd_tai,
                                  rotSkyPos=19.0)

        pm_ra_list = rng.random_sample(n_obj) * 100.0 - 50.0
        pm_dec_list = rng.random_sample(n_obj) * 100.0 - 50.0
        px_list = rng.random_sample(n_obj) + 0.05
        v_rad_list = rng.random_sample(n_obj) * 600.0 - 300.0

        for includeRefraction in (True, False):

            ra_obs, dec_obs = observedFromICRS(
                ra_list,
                dec_list,
                pm_ra=pm_ra_list,
                pm_dec=pm_dec_list,
                parallax=px_list,
                v_rad=v_rad_list,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            ra_icrs, dec_icrs = icrsFromObserved(
                ra_obs,
                dec_obs,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            xp_control, yp_control = pupilCoordsFromRaDec(
                ra_icrs,
                dec_icrs,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            xp_test, yp_test = pupilCoordsFromRaDec(
                ra_list,
                dec_list,
                pm_ra=pm_ra_list,
                pm_dec=pm_dec_list,
                parallax=px_list,
                v_rad=v_rad_list,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            distance = arcsecFromRadians(
                np.sqrt(
                    np.power(xp_test - xp_control, 2) +
                    np.power(yp_test - yp_control, 2)))
            self.assertLess(distance.max(), 0.006)

            # now test it in radians
            xp_rad, yp_rad = _pupilCoordsFromRaDec(
                np.radians(ra_list),
                np.radians(dec_list),
                pm_ra=radiansFromArcsec(pm_ra_list),
                pm_dec=radiansFromArcsec(pm_dec_list),
                parallax=radiansFromArcsec(px_list),
                v_rad=v_rad_list,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            np.testing.assert_array_equal(xp_rad, xp_test)
            np.testing.assert_array_equal(yp_rad, yp_test)

            # now test it with proper motion = 0
            ra_obs, dec_obs = observedFromICRS(
                ra_list,
                dec_list,
                parallax=px_list,
                v_rad=v_rad_list,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            ra_icrs, dec_icrs = icrsFromObserved(
                ra_obs,
                dec_obs,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            xp_control, yp_control = pupilCoordsFromRaDec(
                ra_icrs,
                dec_icrs,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            xp_test, yp_test = pupilCoordsFromRaDec(
                ra_list,
                dec_list,
                parallax=px_list,
                v_rad=v_rad_list,
                obs_metadata=obs,
                epoch=2000.0,
                includeRefraction=includeRefraction)

            distance = arcsecFromRadians(
                np.sqrt(
                    np.power(xp_test - xp_control, 2) +
                    np.power(yp_test - yp_control, 2)))
            self.assertLess(distance.max(), 1.0e-6)
Пример #41
0
def focalPlaneCoordsFromRaDec(ra,
                              dec,
                              pm_ra=None,
                              pm_dec=None,
                              parallax=None,
                              v_rad=None,
                              obs_metadata=None,
                              epoch=2000.0,
                              camera=None):
    """
    Get the focal plane coordinates for all objects in the catalog.

    @param [in] ra is in degrees in the International Celestial Reference System.
    Can be either a float or a numpy array.

    @param [in] dec is in degrees in the International Celestial Reference System.
    Can be either a float or a numpy array.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in arcsec
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).

    @param [in] obs_metadata is an ObservationMetaData object describing the telescope
    pointing (only if specifying RA and Dec rather than pupil coordinates)

    @param [in] epoch is the julian epoch of the mean equinox used for coordinate transformations
    (in years; only if specifying RA and Dec rather than pupil coordinates; default is 2000)

    @param [in] camera is an afw.cameraGeom camera object

    @param [out] a 2-D numpy array in which the first row is the x
    focal plane coordinate and the second row is the y focal plane
    coordinate (both in millimeters)
    """

    if pm_ra is not None:
        pm_ra_out = radiansFromArcsec(pm_ra)
    else:
        pm_ra_out = None

    if pm_dec is not None:
        pm_dec_out = radiansFromArcsec(pm_dec)
    else:
        pm_dec_out = None

    if parallax is not None:
        parallax_out = radiansFromArcsec(parallax)
    else:
        parallax_out = None

    return _focalPlaneCoordsFromRaDec(np.radians(ra),
                                      np.radians(dec),
                                      pm_ra=pm_ra_out,
                                      pm_dec=pm_dec_out,
                                      parallax=parallax_out,
                                      v_rad=v_rad,
                                      obs_metadata=obs_metadata,
                                      epoch=epoch,
                                      camera=camera)
Пример #42
0
def appGeoFromICRS(ra,
                   dec,
                   pm_ra=None,
                   pm_dec=None,
                   parallax=None,
                   v_rad=None,
                   epoch=2000.0,
                   mjd=None):
    """
    Convert the mean position (RA, Dec) in the International Celestial Reference
    System (ICRS) to the mean apparent geocentric position

    units:  ra (degrees), dec (degrees), pm_ra (arcsec/year), pm_dec
    (arcsec/year), parallax (arcsec), v_rad (km/sec; positive if receding),
    epoch (Julian years)

    @param [in] ra in degrees (ICRS).  Can be a numpy array or a number.

    @param [in] dec in degrees (ICRS).  Can be a numpy array or a number.

    @param [in] pm_ra is ra proper motion multiplied by cos(Dec) in arcsec/year

    @param [in] pm_dec is dec proper motion in arcsec/year

    @param [in] parallax in arcsec

    @param [in] v_rad is radial velocity in km/sec (positive if the object is receding)

    @param [in] epoch is the julian epoch (in years) of the equinox against which to
    measure RA (default: 2000.0)

    @param [in] mjd is an instantiation of the ModifiedJulianDate class
    representing the date of the observation

    @param [out] a 2-D numpy array in which the first row is the apparent
    geocentric RA and the second row is the apparent geocentric Dec (both in degrees)
    """

    if pm_ra is not None:
        pm_ra_in = radiansFromArcsec(pm_ra)
    else:
        pm_ra_in = None

    if pm_dec is not None:
        pm_dec_in = radiansFromArcsec(pm_dec)
    else:
        pm_dec_in = None

    if parallax is not None:
        px_in = radiansFromArcsec(parallax)
    else:
        px_in = None

    output = _appGeoFromICRS(np.radians(ra),
                             np.radians(dec),
                             pm_ra=pm_ra_in,
                             pm_dec=pm_dec_in,
                             parallax=px_in,
                             v_rad=v_rad,
                             epoch=epoch,
                             mjd=mjd)

    return np.degrees(output)
    def setUpClass(cls):
        cls.camera = camTestUtils.CameraWrapper().camera
        cls.dataDir = tempfile.mkdtemp(dir=ROOT, prefix='GalSimPhoSimTest-')
        cls.n_objects = 5
        rng = np.random.RandomState(45)
        pointingRA = 45.2
        pointingDec = -31.6

        cls.obs = ObservationMetaData(pointingRA=pointingRA,
                                      pointingDec=pointingDec,
                                      rotSkyPos=1.2,
                                      bandpassName='r',
                                      mjd=57341.5,
                                      boundLength=0.1,
                                      boundType='circle')

        cls.dtype = np.dtype([
            ('id', int), ('raJ2000', np.float), ('decJ2000', np.float),
            ('ra_deg', np.float), ('dec_deg', np.float),
            ('sedFilename', (str, 300)), ('magNorm', np.float),
            ('redshift', np.float), ('majorAxis', np.float),
            ('minorAxis', np.float), ('positionAngle', np.float),
            ('halfLightRadius', np.float), ('sindex', np.float),
            ('internalAv', np.float), ('internalRv', np.float),
            ('galacticAv', np.float), ('galacticRv', np.float),
            ('properMotionRa', np.float), ('properMotionDec', np.float),
            ('radialVelocity', np.float), ('parallax', np.float)
        ])

        # generate some galaxy bulge data
        redshift = rng.random_sample(cls.n_objects) * 1.5
        rr = rng.random_sample(cls.n_objects) * 0.05
        theta = rng.random_sample(cls.n_objects) * 2.0 * np.pi
        ra = np.radians(pointingRA + rr * np.cos(theta))
        dec = np.radians(pointingDec + rr * np.sin(theta))
        magNorm = rng.random_sample(cls.n_objects) * 7.0 + 18.0
        sindex = rng.random_sample(cls.n_objects) * 4.0 + 1.0
        hlr = radiansFromArcsec(rng.random_sample(cls.n_objects) * 10.0 + 1.0)
        positionAngle = rng.random_sample(cls.n_objects) * np.pi
        internalAv = rng.random_sample(cls.n_objects) * 0.5 + 0.1
        internalRv = rng.random_sample(cls.n_objects) * 0.5 + 2.7
        majorAxis = radiansFromArcsec(
            rng.random_sample(cls.n_objects) * 2.0 + 0.5)
        minorAxis = radiansFromArcsec(
            rng.random_sample(cls.n_objects) * 2.0 + 0.5)
        galacticAv = rng.random_sample(cls.n_objects) * 0.5 + 0.1
        galacticRv = rng.random_sample(cls.n_objects) * 0.5 + 2.7
        properMotionRa = np.zeros(cls.n_objects)
        properMotionDec = np.zeros(cls.n_objects)
        radialVelocity = np.zeros(cls.n_objects)
        parallax = np.zeros(cls.n_objects)
        cls.bulge_name = os.path.join(cls.dataDir,
                                      'galSimPhoSim_test_bulge.dat')
        with open(cls.bulge_name, 'w') as output_file:
            output_file.write('# header\n')
            for ix in range(cls.n_objects):
                output_file.write(
                    '%d %f %f %f %f Const.79E06.002Z.spec %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n'
                    % (ix, ra[ix], dec[ix], np.degrees(ra[ix]),
                       np.degrees(dec[ix]), magNorm[ix], redshift[ix],
                       max(majorAxis[ix], minorAxis[ix]),
                       min(majorAxis[ix], minorAxis[ix]), positionAngle[ix],
                       hlr[ix], sindex[ix], internalAv[ix], internalRv[ix],
                       galacticAv[ix], galacticRv[ix], properMotionRa[ix],
                       properMotionDec[ix], radialVelocity[ix], parallax[ix]))

        # generate some galaxy disk data
        redshift = rng.random_sample(cls.n_objects) * 1.5
        rr = rng.random_sample(cls.n_objects) * 0.05
        theta = rng.random_sample(cls.n_objects) * 2.0 * np.pi
        ra = np.radians(pointingRA + rr * np.cos(theta))
        dec = np.radians(pointingDec + rr * np.sin(theta))
        magNorm = rng.random_sample(cls.n_objects) * 7.0 + 18.0
        sindex = rng.random_sample(cls.n_objects) * 4.0 + 1.0
        hlr = radiansFromArcsec(rng.random_sample(cls.n_objects) * 10.0 + 1.0)
        positionAngle = rng.random_sample(cls.n_objects) * np.pi
        internalAv = rng.random_sample(cls.n_objects) * 0.5 + 0.1
        internalRv = rng.random_sample(cls.n_objects) * 0.5 + 2.7
        majorAxis = radiansFromArcsec(
            rng.random_sample(cls.n_objects) * 2.0 + 0.5)
        minorAxis = radiansFromArcsec(
            rng.random_sample(cls.n_objects) * 2.0 + 0.5)
        galacticAv = rng.random_sample(cls.n_objects) * 0.5 + 0.1
        galacticRv = rng.random_sample(cls.n_objects) * 0.5 + 2.7
        properMotionRa = np.zeros(cls.n_objects)
        properMotionDec = np.zeros(cls.n_objects)
        radialVelocity = np.zeros(cls.n_objects)
        parallax = np.zeros(cls.n_objects)
        cls.disk_name = os.path.join(cls.dataDir, 'galSimPhoSim_test_disk.dat')
        with open(cls.disk_name, 'w') as output_file:
            output_file.write('# header\n')
            for ix in range(cls.n_objects):
                output_file.write(
                    '%d %f %f %f %f Inst.79E06.02Z.spec %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n'
                    % (ix, ra[ix], dec[ix], np.degrees(ra[ix]),
                       np.degrees(dec[ix]), magNorm[ix], redshift[ix],
                       max(majorAxis[ix], minorAxis[ix]),
                       min(majorAxis[ix], minorAxis[ix]), positionAngle[ix],
                       hlr[ix], sindex[ix], internalAv[ix], internalRv[ix],
                       galacticAv[ix], galacticRv[ix], properMotionRa[ix],
                       properMotionDec[ix], radialVelocity[ix], parallax[ix]))

        # generate some agn data
        redshift = rng.random_sample(cls.n_objects) * 1.5
        rr = rng.random_sample(cls.n_objects) * 0.05
        theta = rng.random_sample(cls.n_objects) * 2.0 * np.pi
        ra = np.radians(pointingRA + rr * np.cos(theta))
        dec = np.radians(pointingDec + rr * np.sin(theta))
        magNorm = rng.random_sample(cls.n_objects) * 7.0 + 18.0
        sindex = np.zeros(cls.n_objects)
        hlr = np.zeros(cls.n_objects)
        positionAngle = np.zeros(cls.n_objects)
        internalAv = np.zeros(cls.n_objects)
        internalRv = np.zeros(cls.n_objects)
        majorAxis = np.zeros(cls.n_objects)
        minorAxis = np.zeros(cls.n_objects)
        galacticAv = rng.random_sample(cls.n_objects) * 0.5 + 0.1
        galacticRv = rng.random_sample(cls.n_objects) * 0.5 + 2.7
        properMotionRa = np.zeros(cls.n_objects)
        properMotionDec = np.zeros(cls.n_objects)
        radialVelocity = np.zeros(cls.n_objects)
        parallax = np.zeros(cls.n_objects)
        cls.agn_name = os.path.join(cls.dataDir, 'galSimPhoSim_test_agn.dat')
        with open(cls.agn_name, 'w') as output_file:
            output_file.write('# header\n')
            for ix in range(cls.n_objects):
                output_file.write(
                    '%d %f %f %f %f agn.spec %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n'
                    % (ix, ra[ix], dec[ix], np.degrees(ra[ix]),
                       np.degrees(dec[ix]), magNorm[ix], redshift[ix],
                       max(majorAxis[ix], minorAxis[ix]),
                       min(majorAxis[ix], minorAxis[ix]), positionAngle[ix],
                       hlr[ix], sindex[ix], internalAv[ix], internalRv[ix],
                       galacticAv[ix], galacticRv[ix], properMotionRa[ix],
                       properMotionDec[ix], radialVelocity[ix], parallax[ix]))

        # generate some star data
        redshift = rng.random_sample(cls.n_objects) * 1.5
        rr = rng.random_sample(cls.n_objects) * 0.05
        theta = rng.random_sample(cls.n_objects) * 2.0 * np.pi
        ra = np.radians(pointingRA + rr * np.cos(theta))
        dec = np.radians(pointingDec + rr * np.sin(theta))
        magNorm = rng.random_sample(cls.n_objects) * 7.0 + 18.0
        sindex = np.zeros(cls.n_objects)
        hlr = np.zeros(cls.n_objects)
        positionAngle = np.zeros(cls.n_objects)
        internalAv = np.zeros(cls.n_objects)
        internalRv = np.zeros(cls.n_objects)
        majorAxis = np.zeros(cls.n_objects)
        minorAxis = np.zeros(cls.n_objects)
        galacticAv = rng.random_sample(cls.n_objects) * 0.5 + 0.1
        galacticRv = rng.random_sample(cls.n_objects) * 0.5 + 2.7
        properMotionRa = radiansFromArcsec(
            rng.random_sample(cls.n_objects) * 0.0002)
        properMotionDec = radiansFromArcsec(
            rng.random_sample(cls.n_objects) * 0.0002)
        radialVelocity = rng.random_sample(cls.n_objects) * 200.0
        parallax = radiansFromArcsec(rng.random_sample(cls.n_objects) * 0.0002)
        cls.star_name = os.path.join(cls.dataDir, 'galSimPhoSim_test_star.dat')
        with open(cls.star_name, 'w') as output_file:
            output_file.write('# header\n')
            for ix in range(cls.n_objects):
                output_file.write(
                    '%d %f %f %f %f km30_5000.fits_g10_5040 %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n'
                    % (ix, ra[ix], dec[ix], np.degrees(ra[ix]),
                       np.degrees(dec[ix]), magNorm[ix], redshift[ix],
                       max(majorAxis[ix], minorAxis[ix]),
                       min(majorAxis[ix], minorAxis[ix]), positionAngle[ix],
                       hlr[ix], sindex[ix], internalAv[ix], internalRv[ix],
                       galacticAv[ix], galacticRv[ix], properMotionRa[ix],
                       properMotionDec[ix], radialVelocity[ix], parallax[ix]))
Пример #44
0
def observedFromICRS(ra,
                     dec,
                     pm_ra=None,
                     pm_dec=None,
                     parallax=None,
                     v_rad=None,
                     obs_metadata=None,
                     epoch=None,
                     includeRefraction=True):
    """
    Convert mean position (RA, Dec) in the International Celestial Reference Frame
    to observed (RA, Dec).

    included are precession-nutation, aberration, proper motion, parallax, refraction,
    radial velocity, diurnal aberration.

    This method works in degrees.

    @param [in] ra is the unrefracted RA in degrees (ICRS).  Can be a numpy array or a number.

    @param [in] dec is the unrefracted Dec in degrees (ICRS).  Can be a numpy array or a number.

    @param [in] pm_ra is proper motion in RA multiplied by cos(Dec) (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] pm_dec is proper motion in dec (arcsec/yr)
    Can be a numpy array or a number or None (default=None).

    @param [in] parallax is parallax in arcsec
    Can be a numpy array or a number or None (default=None).

    @param [in] v_rad is radial velocity (km/s)
    Can be a numpy array or a number or None (default=None).

    @param [in] obs_metadata is an ObservationMetaData object describing the
    telescope pointing.

    @param [in] epoch is the julian epoch (in years) against which the mean
    equinoxes are measured.

    @param [in] includeRefraction toggles whether or not to correct for refraction

    @param [out] a 2-D numpy array in which the first row is the observed
    RA and the second row is the observed Dec (both in degrees)
    """

    if pm_ra is not None:
        pm_ra_in = radiansFromArcsec(pm_ra)
    else:
        pm_ra_in = None

    if pm_dec is not None:
        pm_dec_in = radiansFromArcsec(pm_dec)
    else:
        pm_dec_in = None

    if parallax is not None:
        parallax_in = radiansFromArcsec(parallax)
    else:
        parallax_in = None

    output = _observedFromICRS(np.radians(ra),
                               np.radians(dec),
                               pm_ra=pm_ra_in,
                               pm_dec=pm_dec_in,
                               parallax=parallax_in,
                               v_rad=v_rad,
                               obs_metadata=obs_metadata,
                               epoch=epoch,
                               includeRefraction=includeRefraction)

    return np.degrees(output)
    def test_appGeoFromICRS(self):
        """
        Test conversion between ICRS RA, Dec and apparent geocentric ICRS.

        Apparent, geocentric RA, Dec of objects will be taken from this website

        http://aa.usno.navy.mil/data/docs/geocentric.php

        dates converted to JD using this website

        http://aa.usno.navy.mil/data/docs/geocentric.php

        """

        hours = numpy.radians(360.0/24.0)
        minutes = hours/60.0
        seconds = minutes/60.0

        # test on Arcturus
        # data taken from
        # http://aa.usno.navy.mil/data/docs/geocentric.php
        ra_icrs = 14.0*hours + 15.0*minutes + 39.67207*seconds
        dec_icrs = numpy.radians(19.0 + 10.0/60.0 + 56.673/3600.0)
        pm_ra = radiansFromArcsec(-1.0939)
        pm_dec = radiansFromArcsec(-2.00006)
        v_rad = -5.19
        px = radiansFromArcsec(0.08883)

        mjd_list = []
        ra_app_list = []
        dec_app_list = []

        #jd (UT)
        jd = 2457000.375000
        mjd = jd-2400000.5

        mjd_list.append(mjd)
        ra_app_list.append(14.0*hours + 16.0*minutes + 19.59*seconds)
        dec_app_list.append(numpy.radians(19.0 + 6.0/60.0 + 19.56/3600.0))

        jd = 2457187.208333
        mjd = jd-2400000.5
        mjd_list.append(mjd)
        ra_app_list.append(14.0*hours + 16.0*minutes + 22.807*seconds)
        dec_app_list.append(numpy.radians(19.0+6.0/60.0+18.12/3600.0))

        jd = 2457472.625000
        mjd = jd-2400000.5
        mjd_list.append(mjd)
        ra_app_list.append(14.0*hours + 16.0*minutes + 24.946*seconds)
        dec_app_list.append(numpy.radians(19.0 + 5.0/60.0 + 49.65/3600.0))

        for mjd, ra_app, dec_app in zip(mjd_list, ra_app_list, dec_app_list):
            obs = ObservationMetaData(mjd=mjd)

            ra_test, dec_test = _appGeoFromICRS(numpy.array([ra_icrs]), numpy.array([dec_icrs]),
                                                mjd=obs.mjd,
                                                pm_ra=numpy.array([pm_ra]),
                                                pm_dec=numpy.array([pm_dec]),
                                                v_rad=numpy.array([v_rad]),
                                                parallax=numpy.array([px]),
                                                epoch=2000.0)

            distance = arcsecFromRadians(haversine(ra_app, dec_app, ra_test[0], dec_test[0]))
            self.assertLess(distance, 0.1)


        # test on Sirius
        # data taken from
        # http://simbad.u-strasbg.fr/simbad/sim-id?Ident=Sirius
        ra_icrs = 6.0*hours + 45.0*minutes + 8.91728*seconds
        dec_icrs = numpy.radians(-16.0 - 42.0/60.0 -58.0171/3600.0)
        pm_ra = radiansFromArcsec(-0.54601)
        pm_dec = radiansFromArcsec(-1.22307)
        px = radiansFromArcsec(0.37921)
        v_rad = -5.5

        mjd_list = []
        ra_app_list = []
        dec_app_list = []

        jd = 2457247.000000
        mjd_list.append(jd-2400000.5)
        ra_app_list.append(6.0*hours + 45.0*minutes + 49.276*seconds)
        dec_app_list.append(numpy.radians(-16.0 - 44.0/60.0 - 18.69/3600.0))

        jd = 2456983.958333
        mjd_list.append(jd-2400000.5)
        ra_app_list.append(6.0*hours + 45.0*minutes + 49.635*seconds)
        dec_app_list.append(numpy.radians(-16.0 - 44.0/60.0 - 17.04/3600.0))

        jd = 2457523.958333
        mjd_list.append(jd-2400000.5)
        ra_app_list.append(6.0*hours + 45.0*minutes + 50.99*seconds)
        dec_app_list.append(numpy.radians(-16.0 - 44.0/60.0 - 39.76/3600.0))

        for mjd, ra_app, dec_app in zip(mjd_list, ra_app_list, dec_app_list):
            obs = ObservationMetaData(mjd=mjd)

            ra_test, dec_test = _appGeoFromICRS(numpy.array([ra_icrs]), numpy.array([dec_icrs]),
                                                mjd=obs.mjd,
                                                pm_ra=numpy.array([pm_ra]),
                                                pm_dec=numpy.array([pm_dec]),
                                                v_rad=numpy.array([v_rad]),
                                                parallax=numpy.array([px]),
                                                epoch=2000.0)

            distance = arcsecFromRadians(haversine(ra_app, dec_app, ra_test[0], dec_test[0]))
            self.assertLess(distance, 0.1)
    def testPlacement(self):
        """
        Test that GalSimInterpreter puts objects on the right detectors.

        Do so by creating a catalog of 10 closely-packed stars.  Draw test FITS
        images of them using the GalSim Catalog infrastructure.  Draw control FITS
        images of the detectors in the camera, paranoidly including every star
        in every control image (GalSim contains code such that it will not
        actually add flux to an image in cases where we try to include a
        star that does not actually fall on a detector).  Compare that

        a) the fluxes of the test and control images agree within some tolerance

        b) the fluxes of control images that have no corresponding test image
        (i.e. detectors on which no star actually fell) are effectively zero
        """

        #generate the database
        numpy.random.seed(32)
        catSize = 10
        dbName = 'galSimPlacementTestDB.db'
        driver = 'sqlite'
        if os.path.exists(dbName):
            os.unlink(dbName)

        displacedRA = (-40.0 + numpy.random.sample(catSize)*(120.0))/3600.0
        displacedDec = (-20.0 + numpy.random.sample(catSize)*(80.0))/3600.0
        obs_metadata = makePhoSimTestDB(filename=dbName, displacedRA=displacedRA, displacedDec=displacedDec,
                                        bandpass=self.bandpassNameList,
                                        m5=self.m5, seeing=self.seeing)

        catName = 'testPlacementCat.sav'
        stars = testStarsDBObj(driver=driver, database=dbName)

        #create the catalog
        cat = testStarCatalog(stars, obs_metadata = obs_metadata)
        results = cat.iter_catalog()
        firstLine = True

        #iterate over the catalog, giving every star a chance to
        #illumine every detector
        controlImages = {}
        for i, line in enumerate(results):
            galSimType = line[0]
            xPupil = line[5]
            yPupil = line[6]


            majorAxis = line[8]
            minorAxis = line[9]
            sindex = line[10]
            halfLightRadius = line[11]
            positionAngle = line[12]
            if firstLine:
                sedList = cat._calculateGalSimSeds()
                for detector in cat.galSimInterpreter.detectors:
                    for bandpass in cat.galSimInterpreter.bandpasses:
                        controlImages['placementControl_' + \
                                      cat.galSimInterpreter._getFileName(detector=detector, bandpassName=bandpass)] = \
                                      cat.galSimInterpreter.blankImage(detector=detector)
                firstLine = False

            spectrum = galsim.SED(spec=lambda ll: numpy.interp(ll, sedList[i].wavelen, sedList[i].flambda), flux_type='flambda')
            for bp in cat.galSimInterpreter.bandpasses:
                bandpass = cat.galSimInterpreter.bandpasses[bp]
                for detector in cat.galSimInterpreter.detectors:
                    centeredObj = cat.galSimInterpreter.PSF.applyPSF(xPupil=xPupil, yPupil=yPupil, bandpass=bandpass)

                    xPix, yPix = pixelCoordsFromPupilCoords(numpy.array([radiansFromArcsec(xPupil)]),
                                                            numpy.array([radiansFromArcsec(yPupil)]),
                                                            chipNames = [detector.name],
                                                            camera = detector.afwCamera)

                    dx = xPix[0] - detector.xCenterPix
                    dy = yPix[0] - detector.yCenterPix
                    obj = centeredObj*spectrum
                    localImage = cat.galSimInterpreter.blankImage(detector=detector)
                    localImage = obj.drawImage(bandpass=bandpass, wcs=detector.wcs, method='phot',
                                               gain=detector.photParams.gain, image=localImage,
                                               offset=galsim.PositionD(dx, dy))

                    controlImages['placementControl_' + \
                                  cat.galSimInterpreter._getFileName(detector=detector, bandpassName=bp)] += \
                                  localImage

        for name in controlImages:
            controlImages[name].write(file_name=name)

        #write the test images using the catalog infrastructure
        testNames = cat.write_images(nameRoot='placementTest')

        #make sure that every test image has a corresponding control image
        for testName in testNames:
            controlName = testName.replace('Test', 'Control')
            msg = '%s has no counterpart ' % testName
            self.assertTrue(controlName in controlImages, msg=msg)

        #make sure that the test and control images agree to some tolerance
        ignored = 0
        zeroFlux = 0
        for controlName in controlImages:
            controlImage = afwImage.ImageF(controlName)
            controlFlux = controlImage.getArray().sum()

            testName = controlName.replace('Control', 'Test')
            if testName in testNames:
                testImage = afwImage.ImageF(testName)
                testFlux = testImage.getArray().sum()
                msg = '%s: controlFlux = %e, testFlux = %e' % (controlName, controlFlux, testFlux)
                if controlFlux>1000.0:
                    #the randomness of photon shooting means that faint images won't agree
                    self.assertTrue(numpy.abs(controlFlux/testFlux - 1.0)<0.1, msg=msg)
                else:
                    ignored += 1
            else:
                #make sure that controlImages that have no corresponding test image really do
                #have zero flux (because no star fell on them)
                zeroFlux += 1
                msg = '%s has flux %e but was not written by catalog' % (controlName, controlFlux)
                self.assertTrue(controlFlux<1.0, msg=msg)

        self.assertTrue(ignored<len(testNames)/2)
        self.assertTrue(zeroFlux>0)

        for testName in testNames:
            if os.path.exists(testName):
                os.unlink(testName)

        for controlName in controlImages:
            if os.path.exists(controlName):
                os.unlink(controlName)

        if os.path.exists(dbName):
            os.unlink(dbName)
Пример #47
0
    def testPlacement(self):
        """
        Test that GalSimInterpreter puts objects on the right detectors.

        Do so by creating a catalog of 3 closely-packed stars.  Draw test FITS
        images of them using the GalSim Catalog infrastructure.  Draw control FITS
        images of the detectors in the camera, paranoidly including every star
        in every control image (GalSim contains code such that it will not
        actually add flux to an image in cases where we try to include a
        star that does not actually fall on a detector).  Compare that

        a) the fluxes of the test and control images agree within some tolerance

        b) the fluxes of control images that have no corresponding test image
        (i.e. detectors on which no star actually fell) are effectively zero
        """

        # generate the database
        np_rng = np.random.RandomState(32)
        gs_rng = galsim.UniformDeviate(112)
        catSize = 3
        dbName = 'galSimPlacementTestDB.db'
        driver = 'sqlite'
        if os.path.exists(dbName):
            os.unlink(dbName)

        deltaRA = (-40.0 + np_rng.random_sample(catSize) * (120.0)) / 3600.0
        deltaDec = (-20.0 + np_rng.random_sample(catSize) * (80.0)) / 3600.0
        obs_metadata = makePhoSimTestDB(filename=dbName,
                                        deltaRA=deltaRA,
                                        deltaDec=deltaDec,
                                        bandpass=self.bandpassNameList,
                                        m5=self.m5,
                                        seeing=self.seeing)

        stars = testStarsDBObj(driver=driver, database=dbName)

        # create the catalog
        cat = testStarCatalog(stars, obs_metadata=obs_metadata)
        results = cat.iter_catalog()
        firstLine = True

        # iterate over the catalog, giving every star a chance to
        # illumine every detector
        controlImages = {}
        for i, line in enumerate(results):
            xPupil = line[5]
            yPupil = line[6]

            if firstLine:
                sedList = list(cat._calculateGalSimSeds())
                for detector in cat.galSimInterpreter.detectors:
                    for bandpass in cat.galSimInterpreter.bandpassDict:
                        controlImages['placementControl_' +
                                      cat.galSimInterpreter._getFileName(detector=detector,
                                                                         bandpassName=bandpass)] = \
                            cat.galSimInterpreter.blankImage(detector=detector)

                firstLine = False

            for bp in cat.galSimInterpreter.bandpassDict:
                bandpass = cat.galSimInterpreter.bandpassDict[bp]
                adu = sedList[i].calcADU(bandpass, cat.photParams)
                for detector in cat.galSimInterpreter.detectors:
                    centeredObj = cat.galSimInterpreter.PSF.applyPSF(
                        xPupil=xPupil, yPupil=yPupil)

                    xPix, yPix = pixelCoordsFromPupilCoords(
                        radiansFromArcsec(xPupil),
                        radiansFromArcsec(yPupil),
                        chipName=detector.name,
                        camera=detector.afwCamera)

                    dx = xPix - detector.xCenterPix
                    dy = yPix - detector.yCenterPix
                    obj = centeredObj.withFlux(adu * detector.photParams.gain)
                    localImage = cat.galSimInterpreter.blankImage(
                        detector=detector)
                    localImage = obj.drawImage(wcs=detector.wcs,
                                               method='phot',
                                               gain=detector.photParams.gain,
                                               image=localImage,
                                               offset=galsim.PositionD(dx, dy),
                                               rng=gs_rng)

                    controlImages[
                        'placementControl_' +
                        cat.galSimInterpreter._getFileName(
                            detector=detector, bandpassName=bp)] += localImage

        self.assertGreater(len(controlImages), 0)

        for name in controlImages:
            controlImages[name].write(file_name=name)

        # write the test images using the catalog infrastructure
        testNames = cat.write_images(nameRoot='placementTest')

        # make sure that every test image has a corresponding control image
        for testName in testNames:
            controlName = testName.replace('Test', 'Control')
            msg = '%s has no counterpart ' % testName
            self.assertIn(controlName, controlImages, msg=msg)

        # make sure that the test and control images agree to some tolerance
        ignored = 0
        zeroFlux = 0
        valid = 0
        for controlName in controlImages:
            controlImage = afwImage.ImageF(controlName)
            controlFlux = controlImage.getArray().sum()

            testName = controlName.replace('Control', 'Test')
            if testName in testNames:
                testImage = afwImage.ImageF(testName)
                testFlux = testImage.getArray().sum()
                if controlFlux > 1000.0:
                    countSigma = np.sqrt(controlFlux / cat.photParams.gain)
                    msg = '%s: controlFlux = %e, testFlux = %e, sigma %e' \
                          % (controlName, controlFlux, testFlux, countSigma)

                    # the randomness of photon shooting means that faint images won't agree
                    self.assertLess(np.abs(controlFlux - testFlux),
                                    4.0 * countSigma,
                                    msg=msg)
                    valid += 1
                else:
                    ignored += 1
            else:
                # make sure that controlImages that have no corresponding test image really do
                # have zero flux (because no star fell on them)
                zeroFlux += 1
                msg = '%s has flux %e but was not written by catalog' % (
                    controlName, controlFlux)
                self.assertLess(controlFlux, 1.0, msg=msg)

        self.assertGreater(valid, 0)
        self.assertLess(ignored, len(testNames) / 2)
        self.assertGreater(zeroFlux, 0)

        for testName in testNames:
            if os.path.exists(testName):
                os.unlink(testName)

        for controlName in controlImages:
            if os.path.exists(controlName):
                os.unlink(controlName)

        if os.path.exists(dbName):
            os.unlink(dbName)
Пример #48
0
    def _make_gs_object(self, object_line, x_pupil, y_pupil):
        params = object_line.strip().split()
        unique_id = params[1]
        ra_phosim = float(params[2])
        dec_phosim = float(params[3])
        mag_norm = float(params[4])
        sed_name = params[5]
        redshift = float(params[6])
        gamma1 = float(params[7])
        gamma2 = self.gamma2_sign * float(params[8])
        kappa = float(params[9])
        internal_av = 0
        internal_rv = 0
        galactic_av = 0
        galactic_rv = 0
        fits_file = None
        pixel_scale = 0
        rotation_angle = 0
        npoints = 0
        semi_major_arcsec = 0
        semi_minor_arcsec = 0
        position_angle_degrees = 0
        sersic_index = 0
        if params[12].lower() == 'point':
            gs_type = 'pointSource'
            i_gal_dust_model = 14
            if params[13].lower() != 'none':
                i_gal_dust_model = 16
                internal_av = float(params[14])
                internal_rv = float(params[15])
            if params[i_gal_dust_model].lower() != 'none':
                galactic_av = float(params[i_gal_dust_model + 1])
                galactic_rv = float(params[i_gal_dust_model + 2])
        elif params[12].lower() == 'sersic2d':
            gs_type = 'sersic'
            semi_major_arcsec = float(params[13])
            semi_minor_arcsec = float(params[14])
            position_angle_degrees = float(params[15])
            sersic_index = float(params[16])
            i_gal_dust_model = 18
            if params[17].lower() != 'none':
                i_gal_dust_model = 20
                internal_av = float(params[18])
                internal_rv = float(params[19])
            if params[i_gal_dust_model].lower() != 'none':
                galactic_av = float(params[i_gal_dust_model + 1])
                galactic_rv = float(params[i_gal_dust_model + 2])
        elif params[12].lower() == 'knots':
            gs_type = 'RandomWalk'
            semi_major_arcsec = float(params[13])
            semi_minor_arcsec = float(params[14])
            position_angle_degrees = float(params[15])
            npoints = int(params[16])
            i_gal_dust_model = 18
            if params[17].lower() != 'none':
                i_gal_dust_model = 20
                internal_av = float(params[18])
                internal_rv = float(params[19])
            if params[i_gal_dust_model].lower() != 'none':
                galactic_av = float(params[i_gal_dust_model + 1])
                galactic_rv = float(params[i_gal_dust_model + 2])
        elif (params[12].endswith('.fits') or params[12].endswith('.fits.gz')):
            gs_type = 'FitsImage'
            fits_file = find_file_path(params[12], get_image_dirs())
            pixel_scale = float(params[13])
            rotation_angle = float(params[14])
            i_gal_dust_model = 16
            if params[15].lower() != 'none':
                i_gal_dust_model = 18
                internal_av = float(params[16])
                internal_rv = float(params[17])
            if params[i_gal_dust_model].lower() != 'none':
                galactic_av = float(params[i_gal_dust_model + 1])
                galactic_rv = float(params[i_gal_dust_model + 2])
        else:
            raise RuntimeError("Do not know how to handle "
                               "object type: %s" % params[12])

        object_is_valid = (mag_norm < 50.0
                           and (galactic_av != 0 or galactic_rv != 0)
                           and not (gs_type == 'sersic'
                                    and semi_major_arcsec < semi_minor_arcsec)
                           and not (gs_type == 'RandomWalk' and npoints <= 0))
        if not object_is_valid:
            return None
        sed_obj = SedWrapper(find_file_path(sed_name, self.sed_dirs), mag_norm,
                             redshift, internal_av, internal_rv, galactic_av,
                             galactic_rv, self.bp_dict)
        position_angle_radians = np.radians(360 - position_angle_degrees)
        gs_object = GalSimCelestialObject(gs_type,
                                          x_pupil,
                                          y_pupil,
                                          radiansFromArcsec(semi_major_arcsec),
                                          radiansFromArcsec(semi_minor_arcsec),
                                          radiansFromArcsec(semi_major_arcsec),
                                          position_angle_radians,
                                          sersic_index,
                                          sed_obj,
                                          self.bp_dict,
                                          self.phot_params,
                                          npoints,
                                          fits_file,
                                          pixel_scale,
                                          rotation_angle,
                                          gamma1=gamma1,
                                          gamma2=gamma2,
                                          kappa=kappa,
                                          uniqueId=unique_id)
        return gs_object
Пример #49
0
    def test_different_cameras(self):
        rng = np.random.RandomState(6512)

        pointing_ra = 15.0
        pointing_dec = 13.0

        n_obj = 100
        ra_list = pointing_ra + 2.0 * rng.random_sample(n_obj)
        dec_list = pointing_dec + 2.0 * rng.random_sample(n_obj)
        px_list = radiansFromArcsec(0.005) * rng.random_sample(n_obj)
        px_list += radiansFromArcsec(0.001)
        mura_list = radiansFromArcsec(0.005) * rng.random_sample(n_obj)
        mudec_list = radiansFromArcsec(0.005) * rng.random_sample(n_obj)
        vrad_list = 100.0 * rng.random_sample(n_obj)

        with lsst.utils.tests.getTempFilePath('.txt') as db_text_file:
            with open(db_text_file, 'w') as out_file:
                for ix, (rdeg, ddeg, rrad, drad, px, mura, mudec, vrad) in \
                    enumerate(zip(ra_list, dec_list,
                              np.radians(ra_list), np.radians(dec_list),
                              px_list, mura_list, mudec_list, vrad_list)):

                    out_file.write(
                        '%d %e %e %e %e %e %e %e %e\n' %
                        (ix, rdeg, ddeg, rrad, drad, px, mura, mudec, vrad))

            dtype = np.dtype([('id', int), ('raDeg', float), ('decDeg', float),
                              ('raJ2000', float), ('decJ2000', float),
                              ('parallax', float), ('properMotionRa', float),
                              ('properMotionDec', float),
                              ('radialVelocity', float)])

            db = fileDBObject(db_text_file, dtype=dtype, idColKey='id')
            db.raColName = 'raDeg'
            db.decColName = 'decDeg'

        class CameraCoordsCatalog(AstrometryStars, CameraCoords,
                                  InstanceCatalog):
            camera = LsstSimMapper().camera
            column_outputs = ['id', 'chipName']

        class CameraCoordsLSSTCatalog(AstrometryStars, CameraCoordsLSST,
                                      InstanceCatalog):
            column_outputs = ['id', 'chipName']

        obs = ObservationMetaData(pointingRA=pointing_ra,
                                  pointingDec=pointing_dec,
                                  boundLength=1.75,
                                  boundType='circle',
                                  rotSkyPos=23.0,
                                  mjd=59580.0)

        control_cat = CameraCoordsCatalog(db, obs_metadata=obs)
        test_cat = CameraCoordsLSSTCatalog(db, obs_metadata=obs)

        control_line_list = []
        none_chips = 0
        for line in control_cat.iter_catalog():
            if line[1] is None:
                none_chips += 1
            control_line_list.append(line)
        self.assertGreater(len(control_line_list), 0)
        self.assertLess(none_chips, len(control_line_list) / 2)

        line_ct = 0
        for line in test_cat.iter_catalog():
            line_ct += 1
            self.assertIn(line, control_line_list)
        self.assertEqual(line_ct, len(control_line_list))
Пример #50
0
frac = find_fraction_flare_active(prob_vec, np.abs(xyz[2]))
draws = rng.random_sample(len(frac))
activity_level = ['active' if dd<ff else 'inactive'
                  for ff, dd in zip(frac, draws)]

type_dict = {}
for ii in range(3):
    type_dict['M%d' % ii] = 'early'
for ii in range(3,6):
    type_dict['M%d' % ii] = 'mid'
for ii in range(6,9):
    type_dict['M%d' % ii] = 'late'

from lsst.sims.utils import radiansFromArcsec
dd = _au_to_parsec/radiansFromArcsec(data['parallax']*0.001)
from lsst.sims.photUtils import PhotometricParameters

params = PhotometricParameters()

# divide the effective area of the LSST mirror by the sphere
# through which the flare is radiating (3.08576e18 is a parsec
# in cm)
flux_factor = params.effarea/(4.0*np.pi*np.power(dd*3.08576e18, 2))

types_simulated = []
du = []
dg = []
dr = []
di = []
dz = []
Пример #51
0
    def pixelCoordsFromRaDec(self,
                             ra,
                             dec,
                             pm_ra=None,
                             pm_dec=None,
                             parallax=None,
                             v_rad=None,
                             obs_metadata=None,
                             chipName=None,
                             epoch=2000.0,
                             includeDistortion=True):
        """
        Get the pixel positions (or nan if not on a chip) for objects based
        on their RA, and Dec (in degrees)

        Parameters
        ----------
        ra is in degrees in the International Celestial Reference System.
        Can be either a float or a numpy array.

        dec is in degrees in the International Celestial Reference System.
        Can be either a float or a numpy array.

        pm_ra is proper motion in RA multiplied by cos(Dec) (arcsec/yr)
        Can be a numpy array or a number or None (default=None).

        pm_dec is proper motion in dec (arcsec/yr)
        Can be a numpy array or a number or None (default=None).

        parallax is parallax in arcsec
        Can be a numpy array or a number or None (default=None).

        v_rad is radial velocity (km/s)
        Can be a numpy array or a number or None (default=None).

        obs_metadata is an ObservationMetaData characterizing the telescope
        pointing.

        epoch is the epoch in Julian years of the equinox against which
        RA is measured.  Default is 2000.

        chipName designates the names of the chips on which the pixel
        coordinates will be reckoned.  Can be either single value, an array, or None.
        If an array, there must be as many chipNames as there are (RA, Dec) pairs.
        If a single value, all of the pixel coordinates will be reckoned on the same
        chip.  If None, this method will calculate which chip each(RA, Dec) pair actually
        falls on, and return pixel coordinates for each (RA, Dec) pair on the appropriate
        chip.  Default is None.

        includeDistortion is a boolean.  If True (default), then this method will
        return the true pixel coordinates with optical distortion included.  If False, this
        method will return TAN_PIXEL coordinates, which are the pixel coordinates with
        estimated optical distortion removed.  See the documentation in afw.cameraGeom for more
        details.

        Returns
        -------
        a 2-D numpy array in which the first row is the x pixel coordinate
        and the second row is the y pixel coordinate.  These pixel coordinates
        are defined in the Camera team system, rather than the DM system.
        """

        if pm_ra is not None:
            pm_ra_out = simsUtils.radiansFromArcsec(pm_ra)
        else:
            pm_ra_out = None

        if pm_dec is not None:
            pm_dec_out = simsUtils.radiansFromArcsec(pm_dec)
        else:
            pm_dec_out = None

        if parallax is not None:
            parallax_out = simsUtils.radiansFromArcsec(parallax)
        else:
            parallax_out = None

        return self._pixelCoordsFromRaDec(np.radians(ra),
                                          np.radians(dec),
                                          pm_ra=pm_ra_out,
                                          pm_dec=pm_dec_out,
                                          parallax=parallax_out,
                                          v_rad=v_rad,
                                          chipName=chipName,
                                          obs_metadata=obs_metadata,
                                          epoch=2000.0,
                                          includeDistortion=includeDistortion)
    def testPlacement(self):
        """
        Test that GalSimInterpreter puts objects on the right detectors.

        Do so by creating a catalog of 3 closely-packed stars.  Draw test FITS
        images of them using the GalSim Catalog infrastructure.  Draw control FITS
        images of the detectors in the camera, paranoidly including every star
        in every control image (GalSim contains code such that it will not
        actually add flux to an image in cases where we try to include a
        star that does not actually fall on a detector).  Compare that

        a) the fluxes of the test and control images agree within some tolerance

        b) the fluxes of control images that have no corresponding test image
        (i.e. detectors on which no star actually fell) are effectively zero
        """

        # generate the database
        np_rng = np.random.RandomState(32)
        gs_rng = galsim.UniformDeviate(112)
        catSize = 3
        dbName = "galSimPlacementTestDB.db"
        driver = "sqlite"
        if os.path.exists(dbName):
            os.unlink(dbName)

        deltaRA = (-40.0 + np_rng.random_sample(catSize) * (120.0)) / 3600.0
        deltaDec = (-20.0 + np_rng.random_sample(catSize) * (80.0)) / 3600.0
        obs_metadata = makePhoSimTestDB(
            filename=dbName,
            deltaRA=deltaRA,
            deltaDec=deltaDec,
            bandpass=self.bandpassNameList,
            m5=self.m5,
            seeing=self.seeing,
        )

        stars = testStarsDBObj(driver=driver, database=dbName)

        # create the catalog
        cat = testStarCatalog(stars, obs_metadata=obs_metadata)
        results = cat.iter_catalog()
        firstLine = True

        # iterate over the catalog, giving every star a chance to
        # illumine every detector
        controlImages = {}
        for i, line in enumerate(results):
            xPupil = line[5]
            yPupil = line[6]

            if firstLine:
                sedList = list(cat._calculateGalSimSeds())
                for detector in cat.galSimInterpreter.detectors:
                    for bandpass in cat.galSimInterpreter.bandpassDict:
                        controlImages[
                            "placementControl_"
                            + cat.galSimInterpreter._getFileName(detector=detector, bandpassName=bandpass)
                        ] = cat.galSimInterpreter.blankImage(detector=detector)

                firstLine = False

            for bp in cat.galSimInterpreter.bandpassDict:
                bandpass = cat.galSimInterpreter.bandpassDict[bp]
                adu = sedList[i].calcADU(bandpass, cat.photParams)
                for detector in cat.galSimInterpreter.detectors:
                    centeredObj = cat.galSimInterpreter.PSF.applyPSF(xPupil=xPupil, yPupil=yPupil)

                    xPix, yPix = pixelCoordsFromPupilCoords(
                        radiansFromArcsec(xPupil),
                        radiansFromArcsec(yPupil),
                        chipName=detector.name,
                        camera=detector.afwCamera,
                    )

                    dx = xPix - detector.xCenterPix
                    dy = yPix - detector.yCenterPix
                    obj = centeredObj.withFlux(adu * detector.photParams.gain)
                    localImage = cat.galSimInterpreter.blankImage(detector=detector)
                    localImage = obj.drawImage(
                        wcs=detector.wcs,
                        method="phot",
                        gain=detector.photParams.gain,
                        image=localImage,
                        offset=galsim.PositionD(dx, dy),
                        rng=gs_rng,
                    )

                    controlImages[
                        "placementControl_" + cat.galSimInterpreter._getFileName(detector=detector, bandpassName=bp)
                    ] += localImage

        self.assertGreater(len(controlImages), 0)

        for name in controlImages:
            controlImages[name].write(file_name=name)

        # write the test images using the catalog infrastructure
        testNames = cat.write_images(nameRoot="placementTest")

        # make sure that every test image has a corresponding control image
        for testName in testNames:
            controlName = testName.replace("Test", "Control")
            msg = "%s has no counterpart " % testName
            self.assertIn(controlName, controlImages, msg=msg)

        # make sure that the test and control images agree to some tolerance
        ignored = 0
        zeroFlux = 0
        valid = 0
        for controlName in controlImages:
            controlImage = afwImage.ImageF(controlName)
            controlFlux = controlImage.getArray().sum()

            testName = controlName.replace("Control", "Test")
            if testName in testNames:
                testImage = afwImage.ImageF(testName)
                testFlux = testImage.getArray().sum()
                if controlFlux > 1000.0:
                    countSigma = np.sqrt(controlFlux / cat.photParams.gain)
                    msg = "%s: controlFlux = %e, testFlux = %e, sigma %e" % (
                        controlName,
                        controlFlux,
                        testFlux,
                        countSigma,
                    )

                    # the randomness of photon shooting means that faint images won't agree
                    self.assertLess(np.abs(controlFlux - testFlux), 4.0 * countSigma, msg=msg)
                    valid += 1
                else:
                    ignored += 1
            else:
                # make sure that controlImages that have no corresponding test image really do
                # have zero flux (because no star fell on them)
                zeroFlux += 1
                msg = "%s has flux %e but was not written by catalog" % (controlName, controlFlux)
                self.assertLess(controlFlux, 1.0, msg=msg)

        self.assertGreater(valid, 0)
        self.assertLess(ignored, len(testNames) / 2)
        self.assertGreater(zeroFlux, 0)

        for testName in testNames:
            if os.path.exists(testName):
                os.unlink(testName)

        for controlName in controlImages:
            if os.path.exists(controlName):
                os.unlink(controlName)

        if os.path.exists(dbName):
            os.unlink(dbName)