LSST Applications  21.0.0+04719a4bac,21.0.0-1-ga51b5d4+f5e6047307,21.0.0-11-g2b59f77+a9c1acf22d,21.0.0-11-ga42c5b2+86977b0b17,21.0.0-12-gf4ce030+76814010d2,21.0.0-13-g1721dae+760e7a6536,21.0.0-13-g3a573fe+768d78a30a,21.0.0-15-g5a7caf0+f21cbc5713,21.0.0-16-g0fb55c1+b60e2d390c,21.0.0-19-g4cded4ca+71a93a33c0,21.0.0-2-g103fe59+bb20972958,21.0.0-2-g45278ab+04719a4bac,21.0.0-2-g5242d73+3ad5d60fb1,21.0.0-2-g7f82c8f+8babb168e8,21.0.0-2-g8f08a60+06509c8b61,21.0.0-2-g8faa9b5+616205b9df,21.0.0-2-ga326454+8babb168e8,21.0.0-2-gde069b7+5e4aea9c2f,21.0.0-2-gecfae73+1d3a86e577,21.0.0-2-gfc62afb+3ad5d60fb1,21.0.0-25-g1d57be3cd+e73869a214,21.0.0-3-g357aad2+ed88757d29,21.0.0-3-g4a4ce7f+3ad5d60fb1,21.0.0-3-g4be5c26+3ad5d60fb1,21.0.0-3-g65f322c+e0b24896a3,21.0.0-3-g7d9da8d+616205b9df,21.0.0-3-ge02ed75+a9c1acf22d,21.0.0-4-g591bb35+a9c1acf22d,21.0.0-4-g65b4814+b60e2d390c,21.0.0-4-gccdca77+0de219a2bc,21.0.0-4-ge8a399c+6c55c39e83,21.0.0-5-gd00fb1e+05fce91b99,21.0.0-6-gc675373+3ad5d60fb1,21.0.0-64-g1122c245+4fb2b8f86e,21.0.0-7-g04766d7+cd19d05db2,21.0.0-7-gdf92d54+04719a4bac,21.0.0-8-g5674e7b+d1bd76f71f,master-gac4afde19b+a9c1acf22d,w.2021.13
LSST Data Management Base Package
Classes | Functions
lsst.meas.algorithms.loadReferenceObjects Namespace Reference

Classes

class  _FilterCatalog
 
class  ReferenceObjectLoaderBase
 
class  ReferenceObjectLoader
 
class  LoadReferenceObjectsConfig
 
class  LoadReferenceObjectsTask
 

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 catalog 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`
    Epoch to which to correct proper motion.

Definition at line 1442 of file loadReferenceObjects.py.

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

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

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

◆ getRefFluxField()

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

return the alias of "anyFilterMapsToThis", if present
else 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`, optional
    Name of camera filter. If not specified, ``defaultFilter`` needs to be
    set in the refcat loader config.

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

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

Definition at line 759 of file loadReferenceObjects.py.

759 def getRefFluxField(schema, filterName=None):
760  """Get the name of a flux field from a schema.
761 
762  return the alias of "anyFilterMapsToThis", if present
763  else if filterName is specified:
764  return "*filterName*_camFlux" if present
765  else return "*filterName*_flux" if present (camera filter name
766  matches reference filter name)
767  else throw RuntimeError
768  else:
769  return "camFlux", if present,
770  else throw RuntimeError
771 
772  Parameters
773  ----------
774  schema : `lsst.afw.table.Schema`
775  Reference catalog schema.
776  filterName : `str`, optional
777  Name of camera filter. If not specified, ``defaultFilter`` needs to be
778  set in the refcat loader config.
779 
780  Returns
781  -------
782  fluxFieldName : `str`
783  Name of flux field.
784 
785  Raises
786  ------
787  RuntimeError
788  If an appropriate field is not found.
789  """
790  if not isinstance(schema, afwTable.Schema):
791  raise RuntimeError("schema=%s is not a schema" % (schema,))
792  try:
793  return schema.getAliasMap().get("anyFilterMapsToThis")
794  except LookupError:
795  pass # try the filterMap next
796 
797  if filterName:
798  fluxFieldList = [filterName + "_camFlux", filterName + "_flux"]
799  else:
800  fluxFieldList = ["camFlux"]
801  for fluxField in fluxFieldList:
802  if fluxField in schema:
803  return fluxField
804 
805  raise RuntimeError("Could not find flux field(s) %s" % (", ".join(fluxFieldList)))
806 
807 
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 808 of file loadReferenceObjects.py.

808 def getRefFluxKeys(schema, filterName=None):
809  """Return keys for flux and flux error.
810 
811  Parameters
812  ----------
813  schema : `lsst.afw.table.Schema`
814  Reference catalog schema.
815  filterName : `str`
816  Name of camera filter.
817 
818  Returns
819  -------
820  keys : `tuple` of (`lsst.afw.table.Key`, `lsst.afw.table.Key`)
821  Two keys:
822 
823  - flux key
824  - flux error key, if present, else None
825 
826  Raises
827  ------
828  RuntimeError
829  If flux field not found.
830  """
831  fluxField = getRefFluxField(schema, filterName)
832  fluxErrField = fluxField + "Err"
833  fluxKey = schema[fluxField].asKey()
834  try:
835  fluxErrKey = schema[fluxErrField].asKey()
836  except Exception:
837  fluxErrKey = None
838  return (fluxKey, fluxErrKey)
839 
840 

◆ hasNanojanskyFluxUnits()

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

Definition at line 54 of file loadReferenceObjects.py.

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

◆ 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 43 of file loadReferenceObjects.py.

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

◆ 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 1381 of file loadReferenceObjects.py.

1381 def joinMatchListWithCatalogImpl(refObjLoader, matchCat, sourceCat):
1382  """Relink an unpersisted match list to sources and reference
1383  objects.
1384 
1385  A match list is persisted and unpersisted as a catalog of IDs
1386  produced by afw.table.packMatches(), with match metadata
1387  (as returned by the astrometry tasks) in the catalog's metadata
1388  attribute. This method converts such a match catalog into a match
1389  list, with links to source records and reference object records.
1390 
1391  Parameters
1392  ----------
1393  refObjLoader
1394  Reference object loader to use in getting reference objects
1395  matchCat : `lsst.afw.table.BaseCatalog`
1396  Unperisted packed match list.
1397  ``matchCat.table.getMetadata()`` must contain match metadata,
1398  as returned by the astrometry tasks.
1399  sourceCat : `lsst.afw.table.SourceCatalog`
1400  Source catalog. As a side effect, the catalog will be sorted
1401  by ID.
1402 
1403  Returns
1404  -------
1405  matchList : `lsst.afw.table.ReferenceMatchVector`
1406  Match list.
1407  """
1408  matchmeta = matchCat.table.getMetadata()
1409  version = matchmeta.getInt('SMATCHV')
1410  if version != 1:
1411  raise ValueError('SourceMatchVector version number is %i, not 1.' % version)
1412  filterName = matchmeta.getString('FILTER').strip()
1413  try:
1414  epoch = matchmeta.getDouble('EPOCH')
1415  except (LookupError, TypeError):
1416  epoch = None # Not present, or not correct type means it's not set
1417  if 'RADIUS' in matchmeta:
1418  # This is a circle style metadata, call loadSkyCircle
1419  ctrCoord = geom.SpherePoint(matchmeta.getDouble('RA'),
1420  matchmeta.getDouble('DEC'), geom.degrees)
1421  rad = matchmeta.getDouble('RADIUS')*geom.degrees
1422  refCat = refObjLoader.loadSkyCircle(ctrCoord, rad, filterName, epoch=epoch).refCat
1423  elif "INNER_UPPER_LEFT_RA" in matchmeta:
1424  # This is the sky box type (only triggers in the LoadReferenceObject class, not task)
1425  # Only the outer box is required to be loaded to get the maximum region, all filtering
1426  # will be done by the unpackMatches function, and no spatial filtering needs to be done
1427  # by the refObjLoader
1428  box = []
1429  for place in ("UPPER_LEFT", "UPPER_RIGHT", "LOWER_LEFT", "LOWER_RIGHT"):
1430  coord = geom.SpherePoint(matchmeta.getDouble(f"OUTER_{place}_RA"),
1431  matchmeta.getDouble(f"OUTER_{place}_DEC"),
1432  geom.degrees).getVector()
1433  box.append(coord)
1434  outerBox = sphgeom.ConvexPolygon(box)
1435  refCat = refObjLoader.loadRegion(outerBox, filterName=filterName, epoch=epoch).refCat
1436 
1437  refCat.sort()
1438  sourceCat.sort()
1439  return afwTable.unpackMatches(matchCat, refCat, sourceCat)
1440 
1441 
Point in an unspecified spherical coordinate system.
Definition: SpherePoint.h:57
bool strip
Definition: fits.cc:911
std::vector< Match< typename Cat1::Record, typename Cat2::Record > > unpackMatches(BaseCatalog const &matches, Cat1 const &cat1, Cat2 const &cat2)
Reconstruct a MatchVector from a BaseCatalog representation of the matches and a pair of catalogs.
Definition: Match.cc:455
def joinMatchListWithCatalogImpl(refObjLoader, matchCat, sourceCat)