LSSTApplications  18.1.0
LSSTDataManagementBasePackage
Classes | Functions
lsst.meas.algorithms.loadReferenceObjects Namespace Reference

Classes

class  _FilterCatalog
 
class  LoadReferenceObjectsConfig
 
class  LoadReferenceObjectsTask
 Abstract base class to load objects from reference catalogs. More...
 
class  ReferenceObjectLoader
 

Functions

def isOldFluxField (name, units)
 
def hasNanojanskyFluxUnits (schema)
 
def getFormatVersionFromRefCat (refCat)
 
def convertToNanojansky (catalog, log, doConvert=True)
 
def getRefFluxField (schema, filterName=None)
 
def getRefFluxKeys (schema, filterName=None)
 
def joinMatchListWithCatalogImpl (refObjLoader, matchCat, sourceCat)
 
def applyProperMotionsImpl (log, catalog, epoch)
 

Function Documentation

◆ applyProperMotionsImpl()

def lsst.meas.algorithms.loadReferenceObjects.applyProperMotionsImpl (   log,
  catalog,
  epoch 
)
Apply proper motion correction to a reference catalog.

Adjust position and position error in the ``catalog``
for proper motion to the specified ``epoch``,
modifying the catalong in place.

Parameters
----------
log : `lsst.log.log`
    log object to write to
catalog : `lsst.afw.table.SimpleCatalog`
    Catalog of positions, containing:

    - Coordinates, retrieved by the table's coordinate key.
    - ``coord_raErr`` : Error in Right Ascension (rad).
    - ``coord_decErr`` : Error in Declination (rad).
    - ``pm_ra`` : Proper motion in Right Ascension (rad/yr,
        East positive)
    - ``pm_raErr`` : Error in ``pm_ra`` (rad/yr), optional.
    - ``pm_dec`` : Proper motion in Declination (rad/yr,
        North positive)
    - ``pm_decErr`` : Error in ``pm_dec`` (rad/yr), optional.
    - ``epoch`` : Mean epoch of object (an astropy.time.Time)
epoch : `astropy.time.Time` (optional)
    Epoch to which to correct proper motion and parallax,
    or None to not apply such corrections.

Definition at line 1457 of file loadReferenceObjects.py.

1457 def applyProperMotionsImpl(log, catalog, epoch):
1458  """Apply proper motion correction to a reference catalog.
1459 
1460  Adjust position and position error in the ``catalog``
1461  for proper motion to the specified ``epoch``,
1462  modifying the catalong in place.
1463 
1464  Parameters
1465  ----------
1466  log : `lsst.log.log`
1467  log object to write to
1468  catalog : `lsst.afw.table.SimpleCatalog`
1469  Catalog of positions, containing:
1470 
1471  - Coordinates, retrieved by the table's coordinate key.
1472  - ``coord_raErr`` : Error in Right Ascension (rad).
1473  - ``coord_decErr`` : Error in Declination (rad).
1474  - ``pm_ra`` : Proper motion in Right Ascension (rad/yr,
1475  East positive)
1476  - ``pm_raErr`` : Error in ``pm_ra`` (rad/yr), optional.
1477  - ``pm_dec`` : Proper motion in Declination (rad/yr,
1478  North positive)
1479  - ``pm_decErr`` : Error in ``pm_dec`` (rad/yr), optional.
1480  - ``epoch`` : Mean epoch of object (an astropy.time.Time)
1481  epoch : `astropy.time.Time` (optional)
1482  Epoch to which to correct proper motion and parallax,
1483  or None to not apply such corrections.
1484  """
1485  if "epoch" not in catalog.schema or "pm_ra" not in catalog.schema or "pm_dec" not in catalog.schema:
1486  log.warn("Proper motion correction not available from catalog")
1487  return
1488  if not catalog.isContiguous():
1489  raise RuntimeError("Catalog must be contiguous")
1490  catEpoch = astropy.time.Time(catalog["epoch"], scale="tai", format="mjd")
1491  log.debug("Correcting reference catalog for proper motion to %r", epoch)
1492  # Use `epoch.tai` to make sure the time difference is in TAI
1493  timeDiffsYears = (epoch.tai - catEpoch).to(astropy.units.yr).value
1494  coordKey = catalog.table.getCoordKey()
1495  # Compute the offset of each object due to proper motion
1496  # as components of the arc of a great circle along RA and Dec
1497  pmRaRad = catalog["pm_ra"]
1498  pmDecRad = catalog["pm_dec"]
1499  offsetsRaRad = pmRaRad*timeDiffsYears
1500  offsetsDecRad = pmDecRad*timeDiffsYears
1501  # Compute the corresponding bearing and arc length of each offset
1502  # due to proper motion, and apply the offset
1503  # The factor of 1e6 for computing bearing is intended as
1504  # a reasonable scale for typical values of proper motion
1505  # in order to avoid large errors for small values of proper motion;
1506  # using the offsets is another option, but it can give
1507  # needlessly large errors for short duration
1508  offsetBearingsRad = numpy.arctan2(pmDecRad*1e6, pmRaRad*1e6)
1509  offsetAmountsRad = numpy.hypot(offsetsRaRad, offsetsDecRad)
1510  for record, bearingRad, amountRad in zip(catalog, offsetBearingsRad, offsetAmountsRad):
1511  record.set(coordKey,
1512  record.get(coordKey).offset(bearing=bearingRad*lsst.geom.radians,
1513  amount=amountRad*lsst.geom.radians))
1514  # Increase error in RA and Dec based on error in proper motion
1515  if "coord_raErr" in catalog.schema:
1516  catalog["coord_raErr"] = numpy.hypot(catalog["coord_raErr"],
1517  catalog["pm_raErr"]*timeDiffsYears)
1518  if "coord_decErr" in catalog.schema:
1519  catalog["coord_decErr"] = numpy.hypot(catalog["coord_decErr"],
1520  catalog["pm_decErr"]*timeDiffsYears)
1521 
table::Key< int > to

◆ convertToNanojansky()

def lsst.meas.algorithms.loadReferenceObjects.convertToNanojansky (   catalog,
  log,
  doConvert = True 
)
Convert fluxes in a catalog from jansky to nanojansky.

Parameters
----------
catalog : `lsst.afw.table.SimpleCatalog`
    The catalog to convert.
log : `lsst.log.Log`
    Log to send messages to.
doConvert : `bool`, optional
    Return a converted catalog, or just identify the fields that need to be converted?
    This supports the "write=False" mode of `bin/convert_to_nJy.py`.

Returns
-------
catalog : `lsst.afw.table.SimpleCatalog` or None
    The converted catalog, or None if ``doConvert`` is False.

Notes
-----
Support for old units in reference catalogs will be removed after the
release of late calendar year 2019.
Use `meas_algorithms/bin/convert_to_nJy.py` to update your reference catalog.

Definition at line 89 of file loadReferenceObjects.py.

89 def convertToNanojansky(catalog, log, doConvert=True):
90  """Convert fluxes in a catalog from jansky to nanojansky.
91 
92  Parameters
93  ----------
94  catalog : `lsst.afw.table.SimpleCatalog`
95  The catalog to convert.
96  log : `lsst.log.Log`
97  Log to send messages to.
98  doConvert : `bool`, optional
99  Return a converted catalog, or just identify the fields that need to be converted?
100  This supports the "write=False" mode of `bin/convert_to_nJy.py`.
101 
102  Returns
103  -------
104  catalog : `lsst.afw.table.SimpleCatalog` or None
105  The converted catalog, or None if ``doConvert`` is False.
106 
107  Notes
108  -----
109  Support for old units in reference catalogs will be removed after the
110  release of late calendar year 2019.
111  Use `meas_algorithms/bin/convert_to_nJy.py` to update your reference catalog.
112  """
113  # Do not share the AliasMap: for refcats, that gets created when the
114  # catalog is read from disk and should not be propagated.
115  mapper = lsst.afw.table.SchemaMapper(catalog.schema, shareAliasMap=False)
116  mapper.addMinimalSchema(lsst.afw.table.SimpleTable.makeMinimalSchema())
117  input_fields = []
118  output_fields = []
119  for field in catalog.schema:
120  oldName = field.field.getName()
121  oldUnits = field.field.getUnits()
122  if isOldFluxField(oldName, oldUnits):
123  units = 'nJy'
124  # remap Sigma flux fields to Err, so we can drop the alias
125  if oldName.endswith('_fluxSigma'):
126  name = oldName.replace('_fluxSigma', '_fluxErr')
127  else:
128  name = oldName
129  newField = lsst.afw.table.Field[field.dtype](name, field.field.getDoc(), units)
130  mapper.addMapping(field.getKey(), newField)
131  input_fields.append(field.field)
132  output_fields.append(newField)
133  else:
134  mapper.addMapping(field.getKey())
135 
136  fluxFieldsStr = '; '.join("(%s, '%s')" % (field.getName(), field.getUnits()) for field in input_fields)
137 
138  if doConvert:
139  newSchema = mapper.getOutputSchema()
140  output = lsst.afw.table.SimpleCatalog(newSchema)
141  output.extend(catalog, mapper=mapper)
142  for field in output_fields:
143  output[field.getName()] *= 1e9
144  log.info(f"Converted refcat flux fields to nJy (name, units): {fluxFieldsStr}")
145  return output
146  else:
147  log.info(f"Found old-style refcat flux fields (name, units): {fluxFieldsStr}")
148  return None
149 
150 
static Schema makeMinimalSchema()
Return a minimal schema for Simple tables and records.
Definition: Simple.h:140
A mapping between the keys of two Schemas, used to copy data between them.
Definition: SchemaMapper.h:21
def convertToNanojansky(catalog, log, doConvert=True)
Custom catalog class for record/table subclasses that are guaranteed to have an ID, and should generally be sorted by that ID.
Definition: fwd.h:63
A description of a field in a table.
Definition: Field.h:24

◆ getFormatVersionFromRefCat()

def lsst.meas.algorithms.loadReferenceObjects.getFormatVersionFromRefCat (   refCat)
"Return the format version stored in a reference catalog header.

Parameters
----------
refCat : `lsst.afw.table.SimpleCatalog`
    Reference catalog to inspect.

Returns
-------
version : `int` or `None`
    Format version integer, or `None` if the catalog has no metadata
    or the metadata does not include a "REFCAT_FORMAT_VERSION" key.

Definition at line 66 of file loadReferenceObjects.py.

66 def getFormatVersionFromRefCat(refCat):
67  """"Return the format version stored in a reference catalog header.
68 
69  Parameters
70  ----------
71  refCat : `lsst.afw.table.SimpleCatalog`
72  Reference catalog to inspect.
73 
74  Returns
75  -------
76  version : `int` or `None`
77  Format version integer, or `None` if the catalog has no metadata
78  or the metadata does not include a "REFCAT_FORMAT_VERSION" key.
79  """
80  md = refCat.getMetadata()
81  if md is None:
82  return None
83  try:
84  return md.getScalar("REFCAT_FORMAT_VERSION")
85  except KeyError:
86  return None
87 
88 

◆ getRefFluxField()

def lsst.meas.algorithms.loadReferenceObjects.getRefFluxField (   schema,
  filterName = None 
)
Get the name of a flux field from a schema.

if filterName is specified:
    return *filterName*_camFlux if present
    else return *filterName*_flux if present (camera filter name matches reference filter name)
    else throw RuntimeError
else:
    return camFlux, if present,
    else throw RuntimeError

Parameters
----------
schema : `lsst.afw.table.Schema`
    Reference catalog schema.
filterName : `str`
    Name of camera filter.

Returns
-------
fluxFieldName : `str`
    Name of flux field.

Raises
------
RuntimeError
    If an appropriate field is not found.

Definition at line 688 of file loadReferenceObjects.py.

688 def getRefFluxField(schema, filterName=None):
689  """Get the name of a flux field from a schema.
690 
691  if filterName is specified:
692  return *filterName*_camFlux if present
693  else return *filterName*_flux if present (camera filter name matches reference filter name)
694  else throw RuntimeError
695  else:
696  return camFlux, if present,
697  else throw RuntimeError
698 
699  Parameters
700  ----------
701  schema : `lsst.afw.table.Schema`
702  Reference catalog schema.
703  filterName : `str`
704  Name of camera filter.
705 
706  Returns
707  -------
708  fluxFieldName : `str`
709  Name of flux field.
710 
711  Raises
712  ------
713  RuntimeError
714  If an appropriate field is not found.
715  """
716  if not isinstance(schema, afwTable.Schema):
717  raise RuntimeError("schema=%s is not a schema" % (schema,))
718  if filterName:
719  fluxFieldList = [filterName + "_camFlux", filterName + "_flux"]
720  else:
721  fluxFieldList = ["camFlux"]
722  for fluxField in fluxFieldList:
723  if fluxField in schema:
724  return fluxField
725 
726  raise RuntimeError("Could not find flux field(s) %s" % (", ".join(fluxFieldList)))
727 
728 
Defines the fields and offsets for a table.
Definition: Schema.h:50

◆ getRefFluxKeys()

def lsst.meas.algorithms.loadReferenceObjects.getRefFluxKeys (   schema,
  filterName = None 
)
Return keys for flux and flux error.

Parameters
----------
schema : `lsst.afw.table.Schema`
    Reference catalog schema.
filterName : `str`
    Name of camera filter.

Returns
-------
keys : `tuple` of (`lsst.afw.table.Key`, `lsst.afw.table.Key`)
    Two keys:

    - flux key
    - flux error key, if present, else None

Raises
------
RuntimeError
    If flux field not found.

Definition at line 729 of file loadReferenceObjects.py.

729 def getRefFluxKeys(schema, filterName=None):
730  """Return keys for flux and flux error.
731 
732  Parameters
733  ----------
734  schema : `lsst.afw.table.Schema`
735  Reference catalog schema.
736  filterName : `str`
737  Name of camera filter.
738 
739  Returns
740  -------
741  keys : `tuple` of (`lsst.afw.table.Key`, `lsst.afw.table.Key`)
742  Two keys:
743 
744  - flux key
745  - flux error key, if present, else None
746 
747  Raises
748  ------
749  RuntimeError
750  If flux field not found.
751  """
752  fluxField = getRefFluxField(schema, filterName)
753  fluxErrField = fluxField + "Err"
754  fluxKey = schema[fluxField].asKey()
755  try:
756  fluxErrKey = schema[fluxErrField].asKey()
757  except Exception:
758  fluxErrKey = None
759  return (fluxKey, fluxErrKey)
760 
761 

◆ hasNanojanskyFluxUnits()

def lsst.meas.algorithms.loadReferenceObjects.hasNanojanskyFluxUnits (   schema)
Return True if the units of all flux and fluxErr are correct (nJy).

Definition at line 57 of file loadReferenceObjects.py.

57 def hasNanojanskyFluxUnits(schema):
58  """Return True if the units of all flux and fluxErr are correct (nJy).
59  """
60  for field in schema:
61  if isOldFluxField(field.field.getName(), field.field.getUnits()):
62  return False
63  return True
64 
65 

◆ isOldFluxField()

def lsst.meas.algorithms.loadReferenceObjects.isOldFluxField (   name,
  units 
)
Return True if this name/units combination corresponds to an
"old-style" reference catalog flux field.

Definition at line 46 of file loadReferenceObjects.py.

46 def isOldFluxField(name, units):
47  """Return True if this name/units combination corresponds to an
48  "old-style" reference catalog flux field.
49  """
50  unitsCheck = units != 'nJy' # (units == 'Jy' or units == '' or units == '?')
51  isFlux = name.endswith('_flux')
52  isFluxSigma = name.endswith('_fluxSigma')
53  isFluxErr = name.endswith('_fluxErr')
54  return (isFlux or isFluxSigma or isFluxErr) and unitsCheck
55 
56 

◆ joinMatchListWithCatalogImpl()

def lsst.meas.algorithms.loadReferenceObjects.joinMatchListWithCatalogImpl (   refObjLoader,
  matchCat,
  sourceCat 
)
Relink an unpersisted match list to sources and reference
objects.

A match list is persisted and unpersisted as a catalog of IDs
produced by afw.table.packMatches(), with match metadata
(as returned by the astrometry tasks) in the catalog's metadata
attribute. This method converts such a match catalog into a match
list, with links to source records and reference object records.

Parameters
----------
refObjLoader
    Reference object loader to use in getting reference objects
matchCat : `lsst.afw.table.BaseCatalog`
    Unperisted packed match list.
    ``matchCat.table.getMetadata()`` must contain match metadata,
    as returned by the astrometry tasks.
sourceCat : `lsst.afw.table.SourceCatalog`
    Source catalog. As a side effect, the catalog will be sorted
    by ID.

Returns
-------
matchList : `lsst.afw.table.ReferenceMatchVector`
    Match list.

Definition at line 1396 of file loadReferenceObjects.py.

1396 def joinMatchListWithCatalogImpl(refObjLoader, matchCat, sourceCat):
1397  """Relink an unpersisted match list to sources and reference
1398  objects.
1399 
1400  A match list is persisted and unpersisted as a catalog of IDs
1401  produced by afw.table.packMatches(), with match metadata
1402  (as returned by the astrometry tasks) in the catalog's metadata
1403  attribute. This method converts such a match catalog into a match
1404  list, with links to source records and reference object records.
1405 
1406  Parameters
1407  ----------
1408  refObjLoader
1409  Reference object loader to use in getting reference objects
1410  matchCat : `lsst.afw.table.BaseCatalog`
1411  Unperisted packed match list.
1412  ``matchCat.table.getMetadata()`` must contain match metadata,
1413  as returned by the astrometry tasks.
1414  sourceCat : `lsst.afw.table.SourceCatalog`
1415  Source catalog. As a side effect, the catalog will be sorted
1416  by ID.
1417 
1418  Returns
1419  -------
1420  matchList : `lsst.afw.table.ReferenceMatchVector`
1421  Match list.
1422  """
1423  matchmeta = matchCat.table.getMetadata()
1424  version = matchmeta.getInt('SMATCHV')
1425  if version != 1:
1426  raise ValueError('SourceMatchVector version number is %i, not 1.' % version)
1427  filterName = matchmeta.getString('FILTER').strip()
1428  try:
1429  epoch = matchmeta.getDouble('EPOCH')
1431  epoch = None # Not present, or not correct type means it's not set
1432  if 'RADIUS' in matchmeta:
1433  # This is a circle style metadata, call loadSkyCircle
1434  ctrCoord = lsst.geom.SpherePoint(matchmeta.getDouble('RA'),
1435  matchmeta.getDouble('DEC'), lsst.geom.degrees)
1436  rad = matchmeta.getDouble('RADIUS') * lsst.geom.degrees
1437  refCat = refObjLoader.loadSkyCircle(ctrCoord, rad, filterName, epoch=epoch).refCat
1438  elif "INNER_UPPER_LEFT_RA" in matchmeta:
1439  # This is the sky box type (only triggers in the LoadReferenceObject class, not task)
1440  # Only the outer box is required to be loaded to get the maximum region, all filtering
1441  # will be done by the unpackMatches function, and no spatial filtering needs to be done
1442  # by the refObjLoader
1443  box = []
1444  for place in ("UPPER_LEFT", "UPPER_RIGHT", "LOWER_LEFT", "LOWER_RIGHT"):
1445  coord = lsst.geom.SpherePoint(matchmeta.getDouble(f"OUTER_{place}_RA"),
1446  matchmeta.getDouble(f"OUTER_{place}_DEC"),
1447  lsst.geom.degrees).getVector()
1448  box.append(coord)
1449  outerBox = sphgeom.ConvexPolygon(box)
1450  refCat = refObjLoader.loadRegion(outerBox, filterName=filterName, epoch=epoch).refCat
1451 
1452  refCat.sort()
1453  sourceCat.sort()
1454  return afwTable.unpackMatches(matchCat, refCat, sourceCat)
1455 
1456 
Reports attempts to access elements using an invalid key.
Definition: Runtime.h:151
def joinMatchListWithCatalogImpl(refObjLoader, matchCat, sourceCat)
Point in an unspecified spherical coordinate system.
Definition: SpherePoint.h:57
template SourceMatchVector unpackMatches(BaseCatalog const &, SourceCatalog const &, SourceCatalog const &)
Reports errors from accepting an object of an unexpected or inappropriate type.
Definition: Runtime.h:167
bool strip
Definition: fits.cc:883