LSSTApplications  1.1.2+25,10.0+13,10.0+132,10.0+133,10.0+224,10.0+41,10.0+8,10.0-1-g0f53050+14,10.0-1-g4b7b172+19,10.0-1-g61a5bae+98,10.0-1-g7408a83+3,10.0-1-gc1e0f5a+19,10.0-1-gdb4482e+14,10.0-11-g3947115+2,10.0-12-g8719d8b+2,10.0-15-ga3f480f+1,10.0-2-g4f67435,10.0-2-gcb4bc6c+26,10.0-28-gf7f57a9+1,10.0-3-g1bbe32c+14,10.0-3-g5b46d21,10.0-4-g027f45f+5,10.0-4-g86f66b5+2,10.0-4-gc4fccf3+24,10.0-40-g4349866+2,10.0-5-g766159b,10.0-5-gca2295e+25,10.0-6-g462a451+1
LSSTDataManagementBasePackage
clustering.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2012 LSST Corporation.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <http://www.lsstcorp.org/LegalNotices/>.
23  */
24 
30 
31 #include "lsst/utils/ieee.h"
32 #include "lsst/pex/logging/Log.h"
37 
38 using lsst::pex::exceptions::InvalidParameterError;
39 using lsst::pex::exceptions::NotFoundError;
40 
42 
44 
48 
51 
54 using lsst::afw::table::Flag;
64 
66 
68 
69 
70 namespace lsst { namespace ap { namespace cluster {
71 
72 // -- Schema / table/ catalog setup --------
73 
74 namespace {
75 
76  // Unary predicate that always returns true.
77  struct True {
78  template <typename T> bool operator()(T dummy) const {
79  return true;
80  }
81  };
82 
83  void addFlux(Schema & schema,
84  Schema const & proto,
85  std::string const & filter,
86  std::string const & name,
87  std::string const & unit)
88  {
89  std::string doc = "inverse variance weighted mean of " + filter +
90  "-filter source " + name + " (" +
91  proto.find<Flux::MeasTag>(name).field.getDoc() + ")";
92  addFluxFields(schema, filter, name, doc, unit);
93  }
94 
95  void addShape(Schema & schema,
96  Schema const & proto,
97  std::string const & filter,
98  std::string const & name)
99  {
100  std::string doc = "inverse variance weighted mean of " + filter +
101  "-filter source " + name + " (" +
102  proto.find<Shape::MeasTag>(name).field.getDoc() + ")";
103  addShapeFields(schema, filter, name, doc);
104  }
105 
106  bool hasFluxField(Schema const & schema, std::string const & name) {
107  try {
108  schema.find<Flux::MeasTag>(name);
109  } catch (NotFoundError &) {
110  return false;
111  }
112  return true;
113  }
114 
115  bool hasShapeField(Schema const & schema, std::string const & name) {
116  try {
117  schema.find<Shape::MeasTag>(name);
118  } catch (NotFoundError &) {
119  return false;
120  }
121  return true;
122  }
123 
124  struct FilterNameCmp {
125  bool operator()(std::string const &, std::string const &) const;
126  };
127 
128  bool FilterNameCmp::operator()(std::string const & a, std::string const & b) const {
129  return Filter(a, false).getId() < Filter(b, false).getId();
130  }
131 
132 } // namespace <anonymous>
133 
134 
135 std::pair<boost::shared_ptr<SourceTable>, SchemaMapper> const makeOutputSourceTable(
136  SourceTable const & prototype,
137  SourceProcessingControl const & control)
138 {
139  if (!prototype.getCoordKey().isValid() ||
140  !prototype.getCentroidKey().isValid()) {
141  throw LSST_EXCEPT(InvalidParameterError, "Prototypical "
142  "SourceCatalog must have valid Coord and Centroid fields");
143  }
144  SchemaMapper mapper(prototype.getSchema());
145  // add all fields in the input schema to the output schema.
146  mapper.addMappingsWhere(True());
147  // add coordinate error
148  mapper.addOutputField(Field<Covariance<lsst::afw::table::Point<float> > >(
149  "coord.err",
150  "covariance matrix for source sky-coordinates",
151  "rad^2"));
152  if (!control.exposurePrefix.empty()) {
153  // add exposure related fields
154  mapper.addOutputField(Field<int64_t>(
155  control.exposurePrefix + ".id",
156  "ID of exposure source was measured on"));
157  if (!control.multiBand) {
158  mapper.addOutputField(Field<int>(
159  control.exposurePrefix + ".filter.id",
160  "ID of filter for exposure"));
161  }
162  if (!control.coadd) {
163  mapper.addOutputField(Field<float>(
164  control.exposurePrefix + ".time",
165  "exposure time",
166  "s"));
167  mapper.addOutputField(Field<double>(
168  control.exposurePrefix + ".time.mid",
169  "middle of exposure time",
170  "mjd"));
171  }
172  }
173  if (!control.clusterPrefix.empty()) {
174  // add cluster related fields
175  mapper.addOutputField(Field<int64_t>(
176  control.clusterPrefix + ".id",
177  "ID of cluster containing source; 0 if source is not assigned to any cluster."));
178  mapper.addOutputField(Field<lsst::afw::table::Coord>(
179  control.clusterPrefix + ".coord",
180  "ICRS sky-coordinates of cluster containing source",
181  "rad"));
182  }
183  boost::shared_ptr<SourceTable> table =
184  SourceTable::make(mapper.getOutputSchema(), boost::shared_ptr<IdFactory>());
185  // copy slot mappings from prototype
186  table->definePsfFlux(prototype.getPsfFluxDefinition());
187  table->defineModelFlux(prototype.getModelFluxDefinition());
188  table->defineApFlux(prototype.getApFluxDefinition());
189  table->defineInstFlux(prototype.getInstFluxDefinition());
190  table->defineCentroid(prototype.getCentroidDefinition());
191  table->defineShape(prototype.getShapeDefinition());
192 
193  return std::make_pair(table, mapper);
194 }
195 
196 
197 boost::shared_ptr<SourceClusterTable> const makeSourceClusterTable(
198  SourceTable const & prototype,
199  boost::shared_ptr<IdFactory> const & idFactory,
200  SourceProcessingControl const & control)
201 {
202  typedef std::vector<std::string>::const_iterator Iter;
203 
205  schema.setVersion(0);
206  // Add basic fields
208  "coord.err",
209  "sample covariance matrix for coord field (unweighted mean sky-coordinates)",
210  "rad^2");
211  schema.addField<int>(
212  "obs.count",
213  "number of sources in cluster");
214  schema.addField<Flag>(
215  "flag.noise",
216  "set if cluster was created from a single noise source");
217  if (prototype.getCentroidKey().isValid() &&
218  prototype.getCentroidErrKey().isValid()) {
220  "coord.weightedmean",
221  "inverse variance weighted mean sky-coordinates (ICRS)",
222  "rad");
224  "coord.weightedmean.err",
225  "covariance matrix for coord.weightedmean field",
226  "rad^2");
227  schema.addField<int>(
228  "coord.weightedmean.count",
229  "number of samples used to compute coord.weightedmean");
230  }
231  if (!control.exposurePrefix.empty()) {
232  schema.addField<double>(
233  "obs.time.min",
234  "earliest observation time of sources in cluster (TAI)",
235  "mjd");
236  schema.addField<double>(
237  "obs.time.mean",
238  "mean observation time of sources in cluster (TAI)",
239  "mjd");
240  schema.addField<double>(
241  "obs.time.max",
242  "latest observation time of sources in cluster (TAI)",
243  "mjd");
244  }
245  std::vector<std::string> filters = Filter::getNames();
246  // Sort filter names by ID so that fields are added in a consistent order
247  std::sort(filters.begin(), filters.end(), FilterNameCmp());
248  // Add filter specific fields
249  for (Iter filt = filters.begin(), eFilt = filters.end(); filt != eFilt; ++filt) {
250  schema.addField<int>(
251  *filt + ".obs.count",
252  "number of " + *filt + "-filter sources in cluster");
253  if (!control.exposurePrefix.empty()) {
254  schema.addField<double>(
255  *filt + ".obs.time.min",
256  "earliest observation time of " + *filt + "-filter sources in cluster (TAI)",
257  "mjd");
258  schema.addField<double>(
259  *filt + ".obs.time.max",
260  "latest observation time of " + *filt + "-filter sources in cluster (TAI)",
261  "mjd");
262  }
263  for (Iter flux = control.fluxFields.begin(), eFlux = control.fluxFields.end();
264  flux != eFlux; ++flux) {
265  if (hasFluxField(prototype.getSchema(), *flux)) {
266  addFlux(schema, prototype.getSchema(), *filt, *flux, control.fluxUnit);
267  }
268  }
269  for (Iter shape = control.shapeFields.begin(), eShape = control.shapeFields.end();
270  shape != eShape; ++shape) {
271  if (hasShapeField(prototype.getSchema(), *shape)) {
272  addShape(schema, prototype.getSchema(), *filt, *shape);
273  }
274  }
275  }
276 
277  // Create table
278  boost::shared_ptr<SourceClusterTable> table =
279  SourceClusterTable::make(schema, idFactory);
280 
281  // setup slot mappings
282  table->defineCoordErr("coord.err");
283  table->defineNumSources("obs.count");
284  if (prototype.getCentroidKey().isValid() &&
285  prototype.getCentroidErrKey().isValid()) {
286  table->defineWeightedMeanCoord("coord.weightedmean");
287  table->defineWeightedMeanCoordErr("coord.weightedmean.err");
288  table->defineWeightedMeanCoordCount("coord.weightedmean.count");
289  }
290  if (!control.exposurePrefix.empty()) {
291  table->defineTimeMin("obs.time.min");
292  table->defineTimeMean("obs.time.mean");
293  table->defineTimeMax("obs.time.max");
294  }
295  for (Iter filt = filters.begin(), eFilt = filters.end();
296  filt != eFilt; ++filt) {
297  table->defineNumSources(*filt, "obs.count");
298  if (!control.exposurePrefix.empty()) {
299  table->defineTimeMin(*filt, "obs.time.min");
300  table->defineTimeMax(*filt, "obs.time.max");
301  }
302  Iter flux = control.fluxFields.begin(), eFlux = control.fluxFields.end();
303  if (prototype.getPsfFluxKey().isValid() &&
304  prototype.getPsfFluxErrKey().isValid()) {
305  std::string def = prototype.getPsfFluxDefinition();
306  if (std::find(flux, eFlux, def) != eFlux) {
307  table->definePsfFlux(*filt, def);
308  }
309  }
310  if (prototype.getModelFluxKey().isValid() &&
311  prototype.getModelFluxErrKey().isValid()) {
312  std::string def = prototype.getModelFluxDefinition();
313  if (std::find(flux, eFlux, def) != eFlux) {
314  table->defineModelFlux(*filt, def);
315  }
316  }
317  if (prototype.getApFluxKey().isValid() &&
318  prototype.getApFluxErrKey().isValid()) {
319  std::string def = prototype.getApFluxDefinition();
320  if (std::find(flux, eFlux, def) != eFlux) {
321  table->defineApFlux(*filt, def);
322  }
323  }
324  if (prototype.getInstFluxKey().isValid() &&
325  prototype.getInstFluxErrKey().isValid()) {
326  std::string def = prototype.getInstFluxDefinition();
327  if (std::find(flux, eFlux, def) != eFlux) {
328  table->defineInstFlux(*filt, def);
329  }
330  }
331  if (prototype.getShapeKey().isValid() &&
332  prototype.getShapeErrKey().isValid()) {
333  std::string def = prototype.getShapeDefinition();
334  Iter shape = control.shapeFields.begin(), eShape = control.shapeFields.end();
335  if (std::find(shape, eShape, def) != eShape) {
336  table->defineShape(*filt, def);
337  }
338  }
339  }
340  return table;
341 }
342 
343 
344 // -- Source processing --------
345 
346 namespace {
347 
348  // Return true if the slot mappings for the two catalogs are identical
349  bool compareSlots(SourceTable const & a, SourceTable const & b) {
350  return (
351  a.getPsfFluxKey() == b.getPsfFluxKey() &&
352  a.getPsfFluxErrKey() == b.getPsfFluxErrKey() &&
354  a.getModelFluxKey() == b.getModelFluxKey() &&
357  a.getApFluxKey() == b.getApFluxKey() &&
358  a.getApFluxErrKey() == b.getApFluxErrKey() &&
359  a.getApFluxFlagKey() == b.getApFluxFlagKey() &&
360  a.getInstFluxKey() == b.getInstFluxKey() &&
363  a.getCentroidKey() == b.getCentroidKey() &&
366  a.getShapeKey() == b.getShapeKey() &&
367  a.getShapeErrKey() == b.getShapeErrKey() &&
369  );
370  }
371 
372 } // namespace <anonymous>
373 
374 
376  SourceCatalog const & expSources,
377  ExposureInfo const & expInfo,
378  lsst::ap::utils::PT1SkyTile const * skyTile,
379  SourceProcessingControl const & control,
380  SchemaMapper const & mapper,
381  SourceCatalog & sources,
382  SourceCatalog & badSources,
383  SourceCatalog & invalidSources)
384 {
385  typedef std::vector<std::string>::const_iterator StringIter;
386  typedef std::vector<Key<Flag> >::const_iterator FlagKeyIter;
387  typedef SourceCatalog::const_iterator SourceIter;
388 
389  Log log(Log::getDefaultLog(), "lsst.ap.cluster");
390  log.format(Log::INFO, "Processing sources from exposure %lld",
391  static_cast<long long>(expInfo.getId()));
392 
393  // Validate that schemas and slots match as expected
394  if (sources.getSchema() != badSources.getSchema() ||
395  sources.getSchema() != invalidSources.getSchema()) {
396  throw LSST_EXCEPT(InvalidParameterError, "output "
397  "SourceCatalog schema mismatch");
398  }
399  if (!sources.getSchema().contains(expSources.getSchema())) {
400  throw LSST_EXCEPT(InvalidParameterError, "output SourceCatalog "
401  "schema does not contain input SourceCatalog schema");
402  }
403  if (mapper.getInputSchema() != expSources.getSchema()) {
404  throw LSST_EXCEPT(InvalidParameterError, "SchemaMapper and "
405  "input source catalog disagree on input schema.");
406  }
407  if (mapper.getOutputSchema() != sources.getSchema()) {
408  throw LSST_EXCEPT(InvalidParameterError, "SchemaMapper and "
409  "output source catalogs disagree on output schema.");
410  }
411  if (!compareSlots(*expSources.getTable(), *sources.getTable()) ||
412  !compareSlots(*sources.getTable(), *badSources.getTable()) ||
413  !compareSlots(*badSources.getTable(), *invalidSources.getTable())) {
414  throw LSST_EXCEPT(InvalidParameterError, "slot mappings "
415  "for input and output SourceCatalogs differ");
416  }
417 
418  // Construct bad source flag key vector
419  std::vector<Key<Flag> > badKeys;
420  for (StringIter i = control.badFlagFields.begin(),
421  e = control.badFlagFields.end(); i != e; ++i) {
422  badKeys.push_back(expSources.getSchema().find<Flag>(*i).key);
423  }
424  // Extract exposure X/Y bounds relative to parent exposure (if there is one).
425  // This is because centroids of coadd-sources are in the pixel coordinate system
426  // of the tract exposure containing the patch they were measured on, NOT in
427  // the pixel coordinate system of the patch.
428  double const xMin = indexToPosition(expInfo.getX0()) - 0.5;
429  double const yMin = indexToPosition(expInfo.getY0()) - 0.5;
430  double const xMax = indexToPosition(expInfo.getX0() + expInfo.getWidth() - 1) + 0.5;
431  double const yMax = indexToPosition(expInfo.getY0() + expInfo.getHeight() - 1) + 0.5;
432 
433  // Set up keys to additional fields
434  Key<int64_t> expIdKey;
435  Key<int> expFilterIdKey;
436  Key<float> expTimeKey;
437  Key<double> expTimeMidKey;
439  sources.getTable()->getCentroidErrKey();
441  Key<lsst::afw::coord::Coord> clusterCoordKey;
442  try {
443  coordErrKey = sources.getSchema()["coord.err"];
444  } catch (NotFoundError &) {
445  // no easy way to ask whether a field exists by name?
446  }
447  if (!control.exposurePrefix.empty()) {
448  Schema schema = mapper.getOutputSchema();
449  expIdKey = schema[control.exposurePrefix + ".id"];
450  if (!control.multiBand) {
451  expFilterIdKey = schema[control.exposurePrefix + ".filter.id"];
452  }
453  if (!control.coadd) {
454  expTimeKey = schema[control.exposurePrefix + ".time"];
455  expTimeMidKey = schema[control.exposurePrefix + ".time.mid"];
456  }
457  }
458  if (!control.clusterPrefix.empty()) {
459  Schema schema = mapper.getOutputSchema();
460  clusterCoordKey = schema[control.clusterPrefix + ".coord"];
461  }
462  size_t ngood = 0, nbad = 0, ninvalid = 0, noutside = 0;
463  // Loop over input sources
464  for (SourceIter s = expSources.begin(), es = expSources.end(); s != es; ++s) {
465  // Check source validity
466  bool invalid = false;
467  double x = s->getX();
468  double y = s->getY();
469  if (lsst::utils::isnan(x) || lsst::utils::isnan(y)) {
470  log.format(Log::WARN, "Centroid of source %lld contains NaNs",
471  static_cast<long long>(s->getId()));
472  invalid = true;
473  } else if (x < xMin || x > xMax || y < yMin || y > yMax) {
474  log.format(Log::WARN, "Centroid of source %lld does not lie on exposure",
475  static_cast<long long>(s->getId()));
476  invalid = true;
477  } else if (lsst::utils::isnan(s->getRa().asRadians()) ||
478  lsst::utils::isnan(s->getDec().asRadians())) {
479  log.format(Log::WARN, "Sky-coord of source %lld contains NaNs",
480  static_cast<long long>(s->getId()));
481  invalid = true;
482  }
483  if (!invalid && skyTile && !skyTile->contains(s->getCoord())) {
484  // skip sources outside the sky-tilea
485  noutside += 1;
486  continue;
487  }
488  bool bad = false;
489  // Check whether source is flagged as bad
490  for (FlagKeyIter f = badKeys.begin(), ef = badKeys.end(); f != ef; ++f) {
491  if (s->get(*f)) {
492  bad = true;
493  break;
494  }
495  }
496  // Copy input source to appropriate output catalog
497  boost::shared_ptr<SourceRecord> os;
498  if (invalid) {
499  ninvalid += 1;
500  os = invalidSources.addNew();
501  } else if (bad) {
502  nbad += 1;
503  os = badSources.addNew();
504  } else {
505  ngood += 1;
506  os = sources.addNew();
507  }
508  os->assign(*s, mapper);
509  // Add exposure parameters
510  if (expIdKey.isValid()) {
511  os->set(expIdKey, expInfo.getId());
512  }
513  if (expFilterIdKey.isValid()) {
514  os->set(expFilterIdKey, expInfo.getFilter().getId());
515  }
516  if (expTimeKey.isValid()) {
517  os->set(expTimeKey, expInfo.getExposureTime());
518  }
519  if (expTimeMidKey.isValid()) {
520  os->set(expTimeMidKey, expInfo.getEpoch());
521  }
522  // Source cluster coords default to source coordinates
523  if (clusterCoordKey.isValid()) {
524  os->set(clusterCoordKey, s->getCoord());
525  }
526  // Compute sky-coordinate errors
527  if (!invalid && coordErrKey.isValid() && centroidErrKey.isValid()) {
528  Eigen::Matrix2d cov = s->getCentroidErr().cast<double>();
529  bool computeErr = true;
530  if (lsst::utils::isnan(cov(0,0)) || lsst::utils::isnan(cov(1,1))) {
531  computeErr = false;
532  } else if (cov(0,1) != cov(1,0)) {
533  // FIXME: for now, no measurement algorithms actually
534  // compute full covariance matrixes, and the
535  // off diagonal matrix elements are always NaN.
536  // Longer term, we will need some algorithm metadata
537  // to decide whether an off-diagonal NaN means a
538  // sample should be ignored because a computation failed,
539  // or whether it should be zeroed because the algorithm
540  // never computes it.
541  if (lsst::utils::isnan(cov(0,1)) && lsst::utils::isnan(cov(1,0))) {
542  cov(0,1) = 0.0; cov(1,0) = 0.0;
543  } else {
544  computeErr = false;
545  }
546  }
547  if (computeErr) {
548  Eigen::Matrix2d m = expInfo.getWcs()->linearizePixelToSky(
549  s->getCentroid(), radians).getLinear().getMatrix();
550  os->set(coordErrKey, (m * cov * m.transpose()).cast<float>());
551  }
552  }
553  }
554  log.format(Log::INFO, "processed %lld sources (invalid: %lld, "
555  "outside sky-tile: %lld, bad: %lld, good: %lld)",
556  static_cast<long long>(expSources.size()),
557  static_cast<long long>(ninvalid),
558  static_cast<long long>(noutside),
559  static_cast<long long>(nbad),
560  static_cast<long long>(ngood));
561 }
562 
563 
564 // -- Spatial clustering --------
565 
566 namespace {
567 
568  typedef detail::Point<3, boost::shared_ptr<SourceRecord> > OpticsPoint;
569  typedef detail::Optics<3, SourceRecord> Optics;
570 
572  unsigned int const MAX_SOURCES =
573  static_cast<unsigned int>(std::numeric_limits<int>::max());
574 
575 } // namespace <anonymous>
576 
577 
578 std::vector<SourceCatalog> const cluster(
579  SourceCatalog const & sources,
580  ClusteringControl const & control)
581 {
582  typedef SourceCatalog::const_iterator Iter;
583 
584  if (sources.size() > MAX_SOURCES) {
585  throw LSST_EXCEPT(InvalidParameterError, "too many sources to cluster");
586  }
587  control.validate();
588  boost::scoped_array<OpticsPoint> entries(new OpticsPoint[sources.size()]);
589  std::vector<SourceCatalog> clusters;
590  int i = 0;
591  for (Iter s = sources.begin(), e = sources.end(); s != e; ++s, ++i) {
592  entries[i].coords = s->getCoord().getVector().asEigen();
593  entries[i].data = s;
594  }
595  if (i > 0) {
596  // Convert epsilon and leafExtentThreshold to radians, and account
597  // for the fact that our metric is the squared euclidian distance,
598  // not angular separation.
599  double eps = std::sin(0.5 * control.getEpsilon().asRadians());
600  eps = 4.0 * eps * eps;
601  double let = control.getLeafExtentThreshold().asRadians();
602  if (let > 0.0) {
603  let = std::sin(0.5 * let);
604  let = 4.0 * let * let;
605  }
606  Optics optics(entries.get(), i, control.minNeighbors, eps, let, control.pointsPerLeaf);
607  optics.run(sources.getTable(), clusters, detail::SquaredEuclidianDistanceOverSphere());
608  }
609  return clusters;
610 }
611 
612 
613 // -- Cluster attributes --------
614 
616  SourceCatalog & sources,
617  SourceClusterRecord const & record,
618  SourceProcessingControl const & control)
619 {
620  typedef SourceCatalog::iterator Iter;
621 
622  if (control.clusterPrefix.empty()) {
623  return;
624  }
625  Key<int64_t> idKey;
627  try {
628  idKey = sources.getSchema().find<int64_t>(control.clusterPrefix + ".id").key;
629  coordKey = sources.getSchema().find<lsst::afw::coord::Coord>(
630  control.clusterPrefix + ".coord").key;
631  } catch (NotFoundError &) {
632  // could not find fields with the expected name
633  return;
634  }
635  int64_t const id = record.getId();
636  IcrsCoord const coord = record.getCoord();
637  for (Iter i = sources.begin(), e = sources.end(); i != e; ++i) {
638  i->set(idKey, id);
639  i->set(coordKey, coord);
640  }
641 }
642 
643 
644 }}} // namespace lsst::ap::cluster
645 
int y
Defines the fields and offsets for a table.
Definition: Schema.h:46
Key< Flag > getModelFluxFlagKey() const
Return the key used for the ModelFlux slot failure flag.
Definition: Source.h:392
bool isValid() const
Return True if all the constituent Keys are valid.
Definition: aggregates.h:262
std::vector< std::string > shapeFields
&quot;A list of shape field names which should be carried over from input\n&quot; &quot;source tables to output s...
int getHeight() const
Get exposure width and/or height.
Definition: ExposureInfo.h:104
Image utility functions.
boost::shared_ptr< SourceClusterTable > const makeSourceClusterTable(SourceTable const &prototype, boost::shared_ptr< IdFactory > const &idFactory, SourceProcessingControl const &control)
Definition: clustering.cc:197
double indexToPosition(double ind)
Convert image index to image position.
Definition: ImageUtils.h:54
AngleUnit const radians
constant with units of radians
Definition: Angle.h:91
CentroidSlotDefinition::MeasKey getCentroidKey() const
Return the key used for the Centroid slot measurement value.
Definition: Source.h:566
Schema const getOutputSchema() const
Return the output schema (copy-on-write).
Definition: SchemaMapper.h:26
ShapeSlotDefinition::ErrKey getShapeErrKey() const
Return the key used for the Shape slot uncertainty.
Definition: Source.h:639
static Schema makeMinimalSchema()
Return a minimal schema for Simple tables and records.
Definition: Simple.h:120
A mapping between the keys of two Schemas, used to copy data between them.
Definition: SchemaMapper.h:19
std::vector< SourceCatalog > const cluster(SourceCatalog const &sources, ClusteringControl const &control)
Definition: clustering.cc:578
Key< Flag > getApFluxFlagKey() const
Return the key used for the ApFlux slot failure flag.
Definition: Source.h:456
Record class that contains measurement averages on clusters of single exposure sources.
Definition: SourceCluster.h:98
bool isValid() const
Return true if the key was initialized to valid offset.
Definition: Key.h:83
Key< Flag > getInstFluxFlagKey() const
Return the key used for the InstFlux slot failure flag.
Definition: Source.h:520
FluxSlotDefinition::MeasKey getApFluxKey() const
Return the key used for the ApFlux slot measurement value.
Definition: Source.h:438
Implementation of the Optics class.
int getY0() const
Get pixel coordinates of sub-image pixel (0,0) in the parent exposure.
Definition: ExposureInfo.h:111
RecordId getId() const
Convenience accessors for the keys in the minimal reference schema.
Definition: Simple.h:203
FluxSlotDefinition::MeasKey getPsfFluxKey() const
Return the key used for the PsfFlux slot measurement value.
Definition: Source.h:310
double getExposureTime() const
Return the exposure time, s. NaN for coadds.
Definition: ExposureInfo.h:85
lsst::afw::coord::IcrsCoord IcrsCoord
Definition: misc.h:41
int isnan(T t)
Definition: ieee.h:110
a place to record messages and descriptions of the state of processing.
Definition: Log.h:154
lsst::afw::geom::Angle const getLeafExtentThreshold() const
FluxSlotDefinition::ErrKey getModelFluxErrKey() const
Return the key used for the ModelFlux slot uncertainty.
Definition: Source.h:383
std::string clusterPrefix
&quot;Prefix for cluster related fields in the output source schema.\n&quot; &quot;May be empty.\n&quot; ; ...
Functions for clustering sources.
std::string getPsfFluxDefinition() const
Return the name of the field used for the PsfFlux slot.
Definition: Source.h:292
int pointsPerLeaf
&quot;A performance tuning parameter for the k-d tree used internally by\n&quot; &quot;the OPTICS implementation...
double asRadians() const
Definition: Angle.h:122
IcrsCoord getCoord() const
Convenience accessors for the keys in the minimal reference schema.
Definition: Simple.h:206
afw::geom::ellipses::Quadrupole Shape
Definition: constants.h:58
std::string getShapeDefinition() const
Return the name of the field used for the Shape slot.
Definition: Source.h:612
def log
Definition: log.py:85
int getId() const
Definition: Filter.h:136
double getEpoch() const
Return the exposure mid-point, MJD TAI. NaN for coadds.
Definition: ExposureInfo.h:82
double max
Definition: attributes.cc:218
Metrics (distance functions) over K-dimensional spaces.
std::string getInstFluxDefinition() const
Return the name of the field used for the InstFlux slot.
Definition: Source.h:484
tbl::Schema schema
Definition: CoaddPsf.cc:324
An affine coordinate transformation consisting of a linear transformation and an offset.
bool isValid() const
Return True if all the constituent sigma Keys are valid.
int minNeighbors
&quot;The minimum cardinality of the epsilonArcsec-neighborhood of a source\n&quot; &quot;S for S to be considered a...
A description of a field in a table.
Definition: Field.h:22
static boost::shared_ptr< SourceClusterTable > make(lsst::afw::table::Schema const &schema, boost::shared_ptr< lsst::afw::table::IdFactory > const &idFactory)
Construct a new table.
void format(int importance, const char *fmt,...)
lsst::afw::geom::Angle const getEpsilon() const
SchemaItem< T > find(std::string const &name) const
Find a SchemaItem in the Schema by name.
Key< Flag > getPsfFluxFlagKey() const
Return the key used for the PsfFlux slot failure flag.
Definition: Source.h:328
Parameters for the clustering algorithm and its internals.
Holds an integer identifier for an LSST filter.
Definition: Filter.h:107
A polymorphic functor base class for generating record IDs for a table.
Definition: IdFactory.h:19
void setVersion(int version)
Set the table&#39;s version.
Definition: Schema.h:325
Key< Flag > getShapeFlagKey() const
Return the key used for the Shape slot failure flag.
Definition: Source.h:648
void addMappingsWhere(Predicate predicate, bool doReplace=true)
Add mappings for all fields that match criteria defined by a predicate.
Definition: SchemaMapper.h:225
lsst::afw::image::Filter const & getFilter() const
Return the filter of the exposure. UNKNOWN for multi-band.
Definition: ExposureInfo.h:79
int x
Table class that contains measurements made on a single exposure.
Definition: Source.h:194
FluxSlotDefinition::MeasKey getModelFluxKey() const
Return the key used for the ModelFlux slot measurement value.
Definition: Source.h:374
int INFO
Definition: log.py:37
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
Key< T > addField(Field< T > const &field, bool doReplace=false)
Add a new field to the Schema, and return the associated Key.
bool coadd
&quot;If true, sources have been detected/measured on coadd exposures,\n&quot; &quot;and have no associated time-sta...
std::vector< std::string > badFlagFields
&quot;A list of flag field names. If an input source has any of the\n&quot; &quot;corresponding flag bits set...
std::string getCentroidDefinition() const
Return the name of the field used for the Centroid slot.
Definition: Source.h:548
Schema getSchema() const
Return the table&#39;s schema.
Definition: BaseTable.h:129
A class used as a handle to a particular field in a table.
Definition: fwd.h:44
lsst::afw::geom::Angle Angle
Definition: misc.h:42
std::vector< std::string > fluxFields
&quot;A list of flux field names which should be carried over from input\n&quot; &quot;source tables to output so...
FluxSlotDefinition::ErrKey getPsfFluxErrKey() const
Return the key used for the PsfFlux slot uncertainty.
Definition: Source.h:319
FluxSlotDefinition::ErrKey getInstFluxErrKey() const
Return the key used for the InstFlux slot uncertainty.
Definition: Source.h:511
int getWidth() const
Get exposure width and/or height.
Definition: ExposureInfo.h:103
static Key< Coord > getCoordKey()
Key for the celestial coordinates.
Definition: Simple.h:154
afw::table::Key< double > b
bool contains(lsst::afw::coord::Coord const &coord) const
Return true if the given coordinates lie inside the sky tile.
Definition: PT1SkyTile.cc:80
bool multiBand
&quot;If true, sources have been detected/measured on multi-band\n&quot; &quot;exposures (e.g. chi-squared coadds) a...
Key< Flag > getCentroidFlagKey() const
Return the key used for the Centroid slot failure flag.
Definition: Source.h:584
Record class that contains measurements made on a single exposure.
Definition: Source.h:81
int64_t getId() const
Return the unique integer identifier for the exposure.
Definition: ExposureInfo.h:75
std::string fluxUnit
&quot;Unit of calibrated flux.\n&quot; ;
int getX0() const
Get pixel coordinates of sub-image pixel (0,0) in the parent exposure.
Definition: ExposureInfo.h:110
void setClusterFields(SourceCatalog &sources, SourceClusterRecord const &record, SourceProcessingControl const &control)
Definition: clustering.cc:615
int WARN
Definition: log.py:38
FluxSlotDefinition::ErrKey getApFluxErrKey() const
Return the key used for the ApFlux slot uncertainty.
Definition: Source.h:447
ShapeSlotDefinition::MeasKey getShapeKey() const
Return the key used for the Shape slot measurement value.
Definition: Source.h:630
Schema const getInputSchema() const
Return the input schema (copy-on-write).
Definition: SchemaMapper.h:23
void processSources(SourceCatalog const &expSources, ExposureInfo const &expInfo, lsst::ap::utils::PT1SkyTile const *skyTile, SourceProcessingControl const &control, SchemaMapper const &mapper, SourceCatalog &sources, SourceCatalog &badSources, SourceCatalog &invalidSources)
Definition: clustering.cc:375
Tag types used to declare specialized field types.
Definition: misc.h:35
std::pair< boost::shared_ptr< SourceTable >, SchemaMapper > const makeOutputSourceTable(SourceTable const &prototype, SourceProcessingControl const &control)
Definition: clustering.cc:135
A class to handle Icrs coordinates (inherits from Coord)
Definition: Coord.h:155
bool isValid() const
Return True if both the x and y Keys are valid.
Definition: aggregates.h:105
CentroidSlotDefinition::ErrKey getCentroidErrKey() const
Return the key used for the Centroid slot uncertainty.
Definition: Source.h:575
FluxSlotDefinition::MeasKey getInstFluxKey() const
Return the key used for the InstFlux slot measurement value.
Definition: Source.h:502
lsst::afw::image::Wcs::ConstPtr getWcs() const
Return the exposure WCS.
Definition: ExposureInfo.h:137
std::string exposurePrefix
&quot;Prefix for exposure related fields in the output source schema.\n&quot; &quot;May be empty.\n&quot; ;
std::string getApFluxDefinition() const
Return the name of the field used for the ApFlux slot.
Definition: Source.h:420
KeyTuple< lsst::afw::table::Shape > addShapeFields(lsst::afw::table::Schema &schema, std::string const &filter, std::string const &name, std::string const &doc)
Convenience function to setup fields for shapes.
SortedCatalogT< SourceRecord > SourceCatalog
Definition: fwd.h:75
KeyTuple< lsst::afw::table::Flux > addFluxFields(lsst::afw::table::Schema &schema, std::string const &filter, std::string const &name, std::string const &doc, std::string const &unit)
Convenience function to setup fields for fluxes.
std::string getModelFluxDefinition() const
Return the name of the field used for the ModelFlux slot.
Definition: Source.h:356