Пример #1
0
def make_refcat(ra, dec):
    """
    Make a reference catalog for forced photometry

    Parameters:
    -----------
    ra : sequence or array
        Right Ascension in decimal degrees
    dec : sequence or array
        Declination in decimal degrees

    Returns:
    --------
    src_cat : lsst.afw.table.tableLib.SourceCatalog
        Source catalog for the forced photometry task
    """
    schema = out_butler.get('src_schema', immediate=True).schema
    mapper = afwTable.SchemaMapper(schema)
    mapper.addMinimalSchema(schema)
    newSchema = mapper.getOutputSchema()
    src_cat = afwTable.SourceCatalog(newSchema)
    for row in zip(ra, dec):
        record = src_cat.addNew()
        record.set('coord_ra', Angle(row[0] * degrees))
        record.set('coord_dec', Angle(row[1] * degrees))
    return (src_cat)
Пример #2
0
def create_source_catalog_from_text_and_butler(repo_dir, info, dataset='src'):
    butler = dafPersistence.Butler(repo_dir)
    schema = butler.get(dataset + "_schema", immediate=True).schema
    mapper = SchemaMapper(schema)
    mapper.addMinimalSchema(schema)
    newSchema = mapper.getOutputSchema()

    src_cat = SourceCatalog(newSchema)
    for row in info:
        record = src_cat.addNew()
        record.set('coord_ra', Angle(row['RA']*degrees))
        record.set('coord_dec', Angle(row['Dec']*degrees))

    print(src_cat['coord_ra'], src_cat['coord_dec'])
    return(src_cat)
Пример #3
0
    def _horizonRotAngle(self):
        """!Compute rotation angle of camera with respect to horizontal
        coordinates from self.visitInfo.

        @returns horizon rotation angle.
        """
        observatory = self.visitInfo.getObservatory()
        lat = observatory.getLatitude()
        lon = observatory.getLongitude()
        radec = self.visitInfo.getBoresightRaDec()
        ra = radec.getRa()
        dec = radec.getDec()
        era = self.visitInfo.getEra()
        ha = (era + lon - ra).wrap()
        alt = self.visitInfo.getBoresightAzAlt().getLatitude()

        # parallactic angle
        sinParAng = (np.cos(lat.asRadians()) * np.sin(ha.asRadians()) /
                     np.cos(alt.asRadians()))
        cosParAng = np.sqrt(1 - sinParAng * sinParAng)
        if dec > lat:
            cosParAng = -cosParAng
        parAng = Angle(np.arctan2(sinParAng, cosParAng))

        bra = self.visitInfo.getBoresightRotAngle()
        return (bra - parAng).wrap()
Пример #4
0
 def testZenithZero(self):
     """There should be no refraction exactly at zenith."""
     elevation = Angle(np.pi / 2.)
     wl = 505.  # in nm
     refractZen = refraction(wl,
                             elevation,
                             self.observatory,
                             weather=self.weather)
     self.assertAlmostEqual(refractZen.asDegrees(), 0.)
Пример #5
0
 def testRefractWeatherNan(self):
     """Test the values of refraction when no weather is supplied."""
     elevation = Angle(np.random.random() * np.pi / 2.)
     elevation = Angle(np.pi / 6.)  # Airmass 2.0
     wls = [370., 480., 620., 860., 960., 1025.]  # in nm
     refVals = [
         76.7339313496466,
         75.36869048516252,
         74.60378630142982,
         74.06932963258161,
         73.95668242959853,
         73.9006681751504,
     ]
     for wl, refVal in zip(wls, refVals):
         refract = refraction(wl, elevation, self.observatory)
         self.assertFloatsAlmostEqual(refract.asArcseconds(),
                                      refVal,
                                      rtol=1e-3)
Пример #6
0
 def testNoDifferential(self):
     """There should be no differential refraction if the wavelength is the same as the reference."""
     wl = 470.  # in nm
     wl_ref = wl
     elevation = Angle(np.random.random() * np.pi / 2.)
     diffRefraction = differentialRefraction(wl,
                                             wl_ref,
                                             elevation,
                                             self.observatory,
                                             weather=self.weather)
     self.assertFloatsAlmostEqual(diffRefraction.asDegrees(), 0.)
Пример #7
0
def refraction(wavelength, elevation, observatory, weather=None):
    """Calculate overall refraction under atmospheric and observing conditions.

    The calculation is taken from Stone 1996
    "An Accurate Method for Computing Atmospheric Refraction"
    Parameters
    ----------
    wavelength : `float`
        wavelength is in nm (valid for 230.2 < wavelength < 2058.6)
    elevation : `lsst.afw.geom.Angle`
        Elevation of the observation, as an Angle.
    observatory : `lsst.afw.coord.Observatory`
        Class containing the longitude, latitude,
        and altitude of the observatory.
    weather : `lsst.afw.coord.Weather`, optional
        Class containing the measured temperature, pressure, and humidity
        at the observatory during an observation
        If omitted, typical conditions for the observatory's elevation will be calculated.

    Returns
    -------
    `lsst.afw.geom.Angle`
        The angular refraction for light of the given wavelength,
        under the given observing conditions.
    """
    if wavelength < 230.2:
        raise ValueError(
            "Refraction calculation is valid for wavelengths between 230.2 and 2058.6 nm."
        )
    if wavelength > 2058.6:
        raise ValueError(
            "Refraction calculation is valid for wavelengths between 230.2 and 2058.6 nm."
        )
    latitude = observatory.getLatitude()
    altitude = observatory.getElevation()
    if weather is None:
        weather = defaultWeather(altitude * units.meter)
    reducedN = deltaN(wavelength, weather) / deltaRefractScale
    temperature = extractTemperature(weather, useKelvin=True)
    atmosScaleheightRatio = 4.5908E-6 * temperature / units.Kelvin

    # Account for oblate Earth
    # This replicates equation 10 of Stone 1996
    relativeGravity = (1. + 0.005302 * np.sin(latitude.asRadians())**2. -
                       0.00000583 * np.sin(2. * latitude.asRadians())**2. -
                       0.000000315 * altitude)

    # Calculate the tangent of the zenith angle.
    tanZ = np.tan(np.pi / 2. - elevation.asRadians())
    atmosTerm1 = reducedN * relativeGravity * (1. - atmosScaleheightRatio)
    atmosTerm2 = reducedN * relativeGravity * (atmosScaleheightRatio -
                                               reducedN / 2.)
    result = Angle(atmosTerm1 * tanZ + atmosTerm2 * tanZ**3.)
    return result
Пример #8
0
 def testParallacticAngleSouthMeridian(self):
     """An observation on the Meridian that is South of zenith has a parallactic angle of zero."""
     meridianBoresightRA = self.data1.era + self.data1.observatory.getLongitude(
     )
     southBoresightDec = self.data1.observatory.getLatitude(
     ) - 10. * degrees
     visitInfo = afwImage.VisitInfo(
         era=self.data1.era,
         boresightRaDec=SpherePoint(meridianBoresightRA, southBoresightDec),
         observatory=self.data1.observatory,
     )
     self.assertAnglesAlmostEqual(visitInfo.getBoresightParAngle(),
                                  Angle(0.))
Пример #9
0
    def create_source_catalog_from_external_catalog(self,
                                                    dataRef,
                                                    coord_file,
                                                    dataset='src',
                                                    debug=False):
        butler = dataRef.getButler()
        schema = butler.get(dataset + "_schema", immediate=True).schema
        mapper = afwTable.SchemaMapper(schema)
        mapper.addMinimalSchema(schema)
        newSchema = mapper.getOutputSchema()

        info = load_external_catalog_info(coord_file)

        src_cat = afwTable.SourceCatalog(newSchema)
        for row in info:
            record = src_cat.addNew()
            record.set('coord_ra', Angle(row['RA'] * degrees))
            record.set('coord_dec', Angle(row['Dec'] * degrees))

        if debug:
            print(src_cat['coord_ra'], src_cat['coord_dec'])
        return (src_cat)
Пример #10
0
 def testWavelengthRangeError(self):
     """Refraction should raise an error if the wavelength is out of range."""
     elevation = Angle(np.random.random() * np.pi / 2.)
     wl_low = 230.
     wl_high = 2059.
     self.assertRaises(ValueError,
                       refraction,
                       wl_low,
                       elevation,
                       self.observatory,
                       weather=self.weather)
     self.assertRaises(ValueError,
                       refraction,
                       wl_high,
                       elevation,
                       self.observatory,
                       weather=self.weather)
Пример #11
0
 def testRefractHighAirmass(self):
     """Compare the refraction calculation to precomputed values."""
     elevation = Angle(np.pi / 6.)  # Airmass 2.0
     wls = [370., 480., 620., 860., 960., 1025.]  # in nm
     refVals = [
         73.04868430514726,
         71.74884360909664,
         71.02058121935002,
         70.51172189207065,
         70.40446894800584,
         70.35113687114644,
     ]
     for wl, refVal in zip(wls, refVals):
         refract = refraction(wl,
                              elevation,
                              self.observatory,
                              weather=self.weather)
         self.assertFloatsAlmostEqual(refract.asArcseconds(),
                                      refVal,
                                      rtol=1e-3)
Пример #12
0
 def setUp(self):
     """Define parameters used by every test."""
     filter_name = 'g'
     n_step = 3
     pixel_scale = Angle(afwGeom.arcsecToRad(0.25))
     size = 20
     self.latitude = lsst_observatory.getLatitude()
     # NOTE that this array is randomly generated
     random_seed = 3
     rand_gen = np.random
     rand_gen.seed(random_seed)
     self.array = np.float32(rand_gen.random(size=(size, size)))
     self.dcrTemplate = BasicGenerateTemplate(size=size, filter_name=filter_name,
                                              n_step=n_step, pixel_scale=pixel_scale)
     self.dcrTemplate.create_skyMap(doWrite=False)
     self.dec = self.dcrTemplate.wcs.getSkyOrigin().getLatitude()
     self.ra = self.dcrTemplate.wcs.getSkyOrigin().getLongitude()
     self.azimuth = Angle(np.radians(140.0))
     self.elevation = Angle(np.radians(50.0))
     ha_term1 = np.sin(self.elevation.asRadians())
     ha_term2 = np.sin(self.dec.asRadians())*np.sin(self.latitude.asRadians())
     ha_term3 = np.cos(self.dec.asRadians())*np.cos(self.latitude.asRadians())
     self.hour_angle = Angle(np.arccos((ha_term1 - ha_term2) / ha_term3))
     p_angle = parallactic_angle(self.hour_angle, self.dec, self.latitude)
     self.rotation_angle = Angle(p_angle)
     self.dcrTemplate.weights = np.zeros_like(self.array)
     nonzero_inds = self.array > 0
     self.dcrTemplate.weights[nonzero_inds] = 1./np.abs(self.array[nonzero_inds])
     self.dcr_gen = self.dcrTemplate._dcr_generator(self.dcrTemplate.bandpass,
                                                    pixel_scale=self.dcrTemplate.pixel_scale,
                                                    elevation=self.elevation,
                                                    rotation_angle=self.rotation_angle,
                                                    use_midpoint=False)
     self.exposure = self.dcrTemplate.create_exposure(self.array, self.elevation, self.azimuth,
                                                      variance=None, boresightRotAngle=self.rotation_angle,
                                                      dec=self.dec, ra=self.ra)
Пример #13
0
class DcrCoaddTestBase(object):
    """Base class many unit tests can inherit from to simplify setup.

    Attributes
    ----------
    array : np.ndarray
        Random array of input data values.
    azimuth : lsst.afw.geom Angle
        Azimuth angle of the observation
    dcr_gen : GenerateTemplate.dcr_generator
        Generator of Differential Chromatic Refraction (DCR) values per sub-band.
    dcrTemplate : `GenerateTemplate`
        Basic instance of the `GenerateTemplate` class for testing.
    elevation : lsst.afw.geom Angle
        Elevation angle of the observation
    exposure : lsst.afw.image.ExposureD object
        The exposure containing the data from `array` and associated metadata.
    rotation_angle : lsst.afw.geom Angle, optional
            The rotation angle of the field around the boresight.
    """

    def setUp(self):
        """Define parameters used by every test."""
        filter_name = 'g'
        n_step = 3
        pixel_scale = Angle(afwGeom.arcsecToRad(0.25))
        size = 20
        self.latitude = lsst_observatory.getLatitude()
        # NOTE that this array is randomly generated
        random_seed = 3
        rand_gen = np.random
        rand_gen.seed(random_seed)
        self.array = np.float32(rand_gen.random(size=(size, size)))
        self.dcrTemplate = BasicGenerateTemplate(size=size, filter_name=filter_name,
                                                 n_step=n_step, pixel_scale=pixel_scale)
        self.dcrTemplate.create_skyMap(doWrite=False)
        self.dec = self.dcrTemplate.wcs.getSkyOrigin().getLatitude()
        self.ra = self.dcrTemplate.wcs.getSkyOrigin().getLongitude()
        self.azimuth = Angle(np.radians(140.0))
        self.elevation = Angle(np.radians(50.0))
        ha_term1 = np.sin(self.elevation.asRadians())
        ha_term2 = np.sin(self.dec.asRadians())*np.sin(self.latitude.asRadians())
        ha_term3 = np.cos(self.dec.asRadians())*np.cos(self.latitude.asRadians())
        self.hour_angle = Angle(np.arccos((ha_term1 - ha_term2) / ha_term3))
        p_angle = parallactic_angle(self.hour_angle, self.dec, self.latitude)
        self.rotation_angle = Angle(p_angle)
        self.dcrTemplate.weights = np.zeros_like(self.array)
        nonzero_inds = self.array > 0
        self.dcrTemplate.weights[nonzero_inds] = 1./np.abs(self.array[nonzero_inds])
        self.dcr_gen = self.dcrTemplate._dcr_generator(self.dcrTemplate.bandpass,
                                                       pixel_scale=self.dcrTemplate.pixel_scale,
                                                       elevation=self.elevation,
                                                       rotation_angle=self.rotation_angle,
                                                       use_midpoint=False)
        self.exposure = self.dcrTemplate.create_exposure(self.array, self.elevation, self.azimuth,
                                                         variance=None, boresightRotAngle=self.rotation_angle,
                                                         dec=self.dec, ra=self.ra)

    def tearDown(self):
        """Free memory."""
        del self.dcrTemplate
        del self.exposure
        del self.dcr_gen
Пример #14
0
# the GNU General Public License along with this program.  If not,
# see <http://www.lsstcorp.org/LegalNotices/>.
#
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from lsst.daf.base import DateTime
from lsst.afw.coord import Coord, IcrsCoord, Observatory, Weather
from lsst.afw.geom import Angle
from .imageLib import VisitInfo, RotType_UNKNOWN

__all__ = ["makeVisitInfo"]

nanFloat = float("nan")
nanAngle = Angle(nanFloat)


def makeVisitInfo(
    exposureId=0,
    exposureTime=nanFloat,
    darkTime=nanFloat,
    date=DateTime(),
    ut1=nanFloat,
    era=nanAngle,
    boresightRaDec=IcrsCoord(nanAngle, nanAngle),
    boresightAzAlt=Coord(nanAngle, nanAngle),
    boresightAirmass=nanFloat,
    boresightRotAngle=nanAngle,
    rotType=RotType_UNKNOWN,
    observatory=Observatory(nanAngle, nanAngle, nanFloat),
 def setUp(self):
     """Create a catalog to run through the ingestion process."""
     # First, connect to the database.
     self.host = os.environ.get("TEST_MYSQL_HOST",
                                "lsst-db.ncsa.illinois.edu")
     self.db = os.environ.get("TEST_MYSQL_DB", "test")
     self.port = int(os.environ.get("TEST_MYSQL_PORT", "3306"))
     self.conn = None
     try:
         self.conn = IngestCatalogTask.connect(
             host=self.host, port=self.port, db=self.db)
     except:
         pass
     # Create a schema containing one of every kind of afw field
     schema = afw_table.Schema()
     keys = (
         # Scalar fields
         schema.addField("scalar.u", type="U"),
         schema.addField("scalar.i", type="I"),
         schema.addField("scalar.l", type="L"),
         schema.addField("scalar.f", type="F"),
         schema.addField("scalar.d", type="D"),
         schema.addField("scalar.flag", type="Flag"),
         schema.addField("scalar.angle", type="Angle"),
         # Fixed-length array types
         schema.addField("fix.string", type="String", size=4),
         schema.addField("fix.array.u", type="ArrayU", size=2),
         schema.addField("fix.array.i", type="ArrayI", size=2),
         schema.addField("fix.array.f", type="ArrayF", size=2),
         schema.addField("fix.array.d", type="ArrayD", size=2),
         # Variable-length array types
         schema.addField("var.array.u", type="ArrayU", size=0),
         schema.addField("var.array.i", type="ArrayI", size=0),
         schema.addField("var.array.f", type="ArrayF", size=0),
         schema.addField("var.array.d", type="ArrayD", size=0),
     )
     # Setup schema aliases
     aliases = dict(
         S="scalar",
         F="fix",
         af="fix.array",
         V="var",
         av="var.array",
         vla="av",
     )
     for source, target in aliases.iteritems():
         schema.getAliasMap().set(source, target)
     # Create two rows of fake data...
     self.rows = (
         (
             0, -2147483648, -9223372036854775808, 1.0, math.pi,
             False, Angle(1.0),
             "ab ",
             np.array([0, 65535], dtype=np.uint16),
             np.array([-2147483648, 2147483647], dtype=np.int32),
             np.array([1.0, 2.0], dtype=np.float32),
             np.array([math.pi, math.e], dtype=np.float64),
             np.array(range(0), dtype=np.uint16),
             np.array(range(1), dtype=np.int32),
             np.array(range(3), dtype=np.float32),
             np.array(range(4), dtype=np.float64),
         ),
         (
             65535, 2147483647, 9223372036854775807, 2.0, math.e,
             True, Angle(2.0), "",
             np.array(range(2), dtype=np.uint16),
             np.array(range(2), dtype=np.int32),
             np.array(range(2), dtype=np.float32),
             np.array(range(2), dtype=np.float64),
             np.array([], dtype=np.uint16),
             np.array([], dtype=np.int32),
             np.array([], dtype=np.float32),
             np.array([], dtype=np.float64),
         )
     )
     # and a corresponding catalog
     self.catalog = afw_table.BaseCatalog(schema)
     for row in self.rows:
         record = self.catalog.addNew()
         for i, k in enumerate(keys):
             record.set(k, row[i])
     # Finally, choose table/view names that are unique with very high
     # probability.
     suffix = uuid.uuid4().hex
     self.table_name = "catalog_" + suffix
     self.view_name = "view_" + suffix