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
Namespaces | Classes | Typedefs | Functions
lsst::meas::astrom Namespace Reference

Namespaces

 anetAstrometry
 
 anetBasicAstrometry
 
 astrometry
 
 astrometryNetDataConfig
 
 catalogStarSelector
 
 detail
 
 fitTanSipWcs
 
 loadAstrometryNetObjects
 
 matchOptimisticB
 
 sip
 
 verifyWcs
 
 version
 

Classes

struct  RecordProxy
 
struct  ProxyPair
 
struct  MatchOptimisticBControl
 

Typedefs

typedef std::vector< RecordProxyProxyVector
 

Functions

ProxyVector makeProxies (afwTable::SourceCatalog const &sourceCat)
 
ProxyVector makeProxies (afwTable::SimpleCatalog const &posRefCat)
 
afwTable::ReferenceMatchVector matchOptimisticB (afwTable::SimpleCatalog const &posRefCat, afwTable::SourceCatalog const &sourceCat, MatchOptimisticBControl const &control, int posRefBegInd, bool verbose)
 

Typedef Documentation

Definition at line 50 of file matchOptimisticB.h.

Function Documentation

ProxyVector lsst::meas::astrom::makeProxies ( afwTable::SourceCatalog const &  sourceCat)

Definition at line 396 of file matchOptimisticB.cc.

396  {
397  ProxyVector r;
398  r.reserve(sourceCat.size());
399  for (afwTable::SourceCatalog::const_iterator sourcePtr = sourceCat.begin();
400  sourcePtr != sourceCat.end(); ++sourcePtr) {
401  r.push_back(RecordProxy(sourcePtr, sourcePtr->getCentroid()));
402  }
403  return r;
404  }
std::vector< RecordProxy > ProxyVector
Base::const_iterator const_iterator
Definition: SortedCatalog.h:49
ProxyVector lsst::meas::astrom::makeProxies ( afwTable::SimpleCatalog const &  posRefCat)

Definition at line 406 of file matchOptimisticB.cc.

406  {
407  auto centroidKey = posRefCat.getSchema().find<afwTable::Point<double>>("centroid").key;
408  auto hasCentroidKey = posRefCat.getSchema().find<afwTable::Flag>("hasCentroid").key;
409  ProxyVector r;
410  r.reserve(posRefCat.size());
411  for (afwTable::SimpleCatalog::const_iterator posRefPtr = posRefCat.begin();
412  posRefPtr != posRefCat.end(); ++posRefPtr) {
413  if (!posRefPtr->get(hasCentroidKey)) {
414  throw LSST_EXCEPT(pexExcept::InvalidParameterError, "unknown centroid");
415  }
416  r.push_back(RecordProxy(posRefPtr, posRefPtr->get(centroidKey)));
417  }
418  return r;
419  }
std::vector< RecordProxy > ProxyVector
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
Base::const_iterator const_iterator
Definition: SortedCatalog.h:49
Tag types used to declare specialized field types.
Definition: misc.h:35
lsst::afw::table::ReferenceMatchVector lsst::meas::astrom::matchOptimisticB ( lsst::afw::table::SimpleCatalog const &  posRefCat,
lsst::afw::table::SourceCatalog const &  sourceCat,
MatchOptimisticBControl const &  control,
int  posRefBegInd = 0,
bool  verbose = false 
)

Match sources to stars in a position reference catalog using optimistic pattern matching B

Optimistic Pattern Matching is described in V. Tabur 2007, PASA, 24, 189-198 "Fast Algorithms for Matching CCD Images to a Stellar Catalogue"

Parameters
[in]posRefCatcatalog of position reference stars fields that are used: coord centroid hasCentroid control.refFluxField flux for desired filter
[in]sourceCatcatalog of detected sources
[in]wcsestimated WCS
[in]controlcontrol object
[in]posRefBegIndindex of first start to use in posRefCat
[in]verbosetrue to print diagnostic information to std::cout

Definition at line 421 of file matchOptimisticB.cc.

427  {
428  control.validate();
429 
430  // Select brightest Nsub stars from list of objects
431  // Process both detected from image and external catalog
432  int Nsub = control.numBrightStars;
433  ProxyVector posRefProxyCat = makeProxies(posRefCat);
434  ProxyVector sourceProxyCat = makeProxies(sourceCat);
435  ProxyVector sourceSubCat = selectPoint(
436  sourceProxyCat,
437  sourceCat.getSchema().find<double>(control.sourceFluxField).key,
438  Nsub);
439  ProxyVector posRefSubCat = selectPoint(
440  posRefProxyCat,
441  posRefCat.getSchema().find<double>(control.refFluxField).key,
442  sourceSubCat.size()+25,
443  posRefBegInd);
444  if (verbose) {
445  std::cout << "Catalog sizes: " << sourceSubCat.size() << " " << posRefSubCat.size() << std::endl;
446  }
447 
448  // Construct a list of pairs of position reference stars sorted by increasing separation
449  std::vector<ProxyPair> posRefPairList;
450  size_t const posRefCatSubSize = posRefSubCat.size();
451  for (size_t i = 0; i < posRefCatSubSize-1; i++) {
452  for (size_t j = i+1; j < posRefCatSubSize; j++) {
453  posRefPairList.push_back(ProxyPair(posRefSubCat[i], posRefSubCat[j]));
454  }
455  }
456 
457  // Sort posRefPairList on distance
458  std::sort(posRefPairList.begin(), posRefPairList.end(), cmpPair);
459 
460  // Construct a list of pairs of sources sorted by increasing separation
461  std::vector<ProxyPair> sourcePairList;
462  size_t const sourceSubCatSize = sourceSubCat.size();
463  for (size_t i = 0; i < sourceSubCatSize-1; i++) {
464  for (size_t j = i+1; j < sourceSubCatSize; j++) {
465  sourcePairList.push_back(ProxyPair(sourceSubCat[i], sourceSubCat[j]));
466  }
467  }
468  std::sort(sourcePairList.begin(), sourcePairList.end(), cmpPair);
469 
471  afwTable::ReferenceMatchVector matPairSave;
472  std::vector<afwTable::ReferenceMatchVector> matPairCand;
473 
474  size_t const fullShapeSize = control.numPointsForShape - 1; // Max size of shape array
475  for (size_t ii = 0; ii < sourcePairList.size(); ii++) {
476  ProxyPair p = sourcePairList[ii];
477 
478  std::vector<ProxyPair> q = searchPair(posRefPairList, p,
479  control.matchingAllowancePix, control.maxRotationRad);
480 
481  // If candidate pairs are found
482  if (q.size() != 0) {
483 
484  std::vector<ProxyPair> srcMatPair;
485  std::vector<ProxyPair> catMatPair;
486 
487  // Go through candidate pairs
488  for (size_t l = 0; l < q.size(); l++) {
489 
490  double dpa = p.pa - q[l].pa;
491 
492  srcMatPair.clear();
493  catMatPair.clear();
494 
495  srcMatPair.push_back(p);
496  catMatPair.push_back(q[l]);
497 
498  if (verbose) {
499  std::cout << "p dist: " << p.distance << " pa: " << p.pa << std::endl;
500  std::cout << "q dist: " << q[l].distance << " pa: " << q[l].pa << std::endl;
501  }
502 
503  for (size_t k = 0; k < sourceSubCat.size(); k++) {
504  if (p.first == sourceSubCat[k] || p.second == sourceSubCat[k]) continue;
505 
506  ProxyPair pp(p.first, sourceSubCat[k]);
507 
508  std::vector<ProxyPair>::iterator r = searchPair3(posRefPairList, pp, q[l],
509  control.matchingAllowancePix, dpa, control.maxRotationRad);
510  if (r != posRefPairList.end()) {
511  srcMatPair.push_back(pp);
512  catMatPair.push_back(*r);
513  if (verbose) {
514  std::cout << " p dist: " << pp.distance << " pa: " << pp.pa << std::endl;
515  std::cout << " r dist: " << (*r).distance << " pa: " << (*r).pa << std::endl;
516  }
517  if (srcMatPair.size() == fullShapeSize) {
518  break;
519  }
520  }
521  }
522 
523  bool goodMatch = false;
524  if (srcMatPair.size() == fullShapeSize) {
525  goodMatch = true;
526  for (size_t k = 1; k < catMatPair.size(); k++) {
527  if (catMatPair[0].first != catMatPair[k].first) {
528  goodMatch = false;
529  }
530  }
531  }
532 
533  if (goodMatch && srcMatPair.size() == fullShapeSize) {
534 
535  ProxyVector srcMat;
536  ProxyVector catMat;
537 
538  srcMat.push_back(srcMatPair[0].first);
539  catMat.push_back(catMatPair[0].first);
540  for (size_t k = 0; k < srcMatPair.size(); k++) {
541  srcMat.push_back(srcMatPair[k].second);
542  catMat.push_back(catMatPair[k].second);
543  }
544 
545  boost::shared_array<double> coeff = polyfit(1, srcMat, catMat);
546 
547  if (verbose) {
548  for (size_t k = 0; k < srcMat.size(); k++) {
549  std::cout << "circle(" << srcMat[k].getX() << ","
550  << srcMat[k].getY() << ",10) # color=green" << std::endl;
551  std::cout << "circle(" << catMat[k].getX() << ","
552  << catMat[k].getY() << ",10) # color=red" << std::endl;
553  std::cout << "line(" << srcMat[0].getX() << "," << srcMat[0].getY() << ","
554  << srcMat[k].getX() << "," << srcMat[k].getY()
555  << ") # line=0 0 color=green" << std::endl;
556  std::cout << "line(" << catMat[0].getX() << "," << catMat[0].getY() << ","
557  << catMat[k].getX() << "," << catMat[k].getY()
558  << ") # line=0 0 color=red" << std::endl;
559  }
560  }
561 
562  double a = coeff[1];
563  double b = coeff[2];
564  double c = coeff[4];
565  double d = coeff[5];
566  double theta = std::acos((a*b+c*d)/(std::sqrt(a*a+c*c)*std::sqrt(b*b+d*d))) /
567  M_PI * 180.0;
568  if (verbose) {
569  std::cout << "Linear fit from match:" << std::endl;
570  std::cout << coeff[0] << " " << coeff[1] << " " << coeff[2] << std::endl;
571  std::cout << coeff[3] << " " << coeff[4] << " " << coeff[5] << std::endl;
572  std::cout << coeff[1] * coeff[5] - coeff[2] * coeff[4] - 1. << std::endl;
573  std::cout << theta << std::endl;
574  }
575  if (std::fabs(coeff[1] * coeff[5] - coeff[2] * coeff[4] - 1.) > control.maxDeterminant ||
576  std::fabs(theta - 90.) > control.angleDiffFrom90 ||
577  std::fabs(coeff[0]) > control.maxOffsetPix ||
578  std::fabs(coeff[3]) > control.maxOffsetPix) {
579  if (verbose) {
580  std::cout << "Bad; continuing" << std::endl;
581  }
582  continue;
583  } else {
584  double x0, y0, x1, y1;
585  int num = 0;
586  srcMat.clear();
587  catMat.clear();
588  for (size_t i = 0; i < sourceSubCat.size(); i++) {
589  x0 = sourceSubCat[i].getX();
590  y0 = sourceSubCat[i].getY();
591  transform(1, coeff, x0, y0, &x1, &y1);
592  auto p = searchNearestPoint(posRefSubCat, x1, y1,
593  control.matchingAllowancePix);
594  if (p != posRefSubCat.end()) {
595  num++;
596  srcMat.push_back(sourceSubCat[i]);
597  catMat.push_back(*p);
598  if (verbose) {
599  std::cout << "Match: " << x0 << "," << y0 << " --> "
600  << x1 << "," << y1 <<
601  " <==> " << p->getX() << "," << p->getY() << std::endl;
602  }
603  }
604  }
605  if (num <= control.numPointsForShape) {
606  // Can get matrix = 0,0,0,0; everything matches a single catalog object
607  if (verbose) {
608  std::cout << "Insufficient initial matches; continuing" << std::endl;
609  }
610  continue;
611  }
612  coeff = polyfit(1, srcMat, catMat);
613  if (verbose) {
614  std::cout << "Coefficients from initial matching:" << std::endl;
615  for (size_t i = 0; i < 6; ++i) {
616  std::cout << coeff[i] << " ";
617  }
618  std::cout << std::endl;
619  }
620 
621  matPair = FinalVerify(coeff, posRefProxyCat, sourceProxyCat,
622  control.matchingAllowancePix, verbose);
623  if (verbose) {
624  std::cout << "Number of matches: " << matPair.size() << " vs " <<
625  control.minMatchedPairs << std::endl;
626  }
627  if (matPair.size() <= control.minMatchedPairs) {
628  if (verbose) {
629  std::cout << "Insufficient final matches; continuing" << std::endl;
630  }
631  if (matPair.size() > matPairSave.size()) {
632  matPairSave = matPair;
633  }
634  continue;
635  } else {
636  if (verbose) {
637  std::cout << "Finish" << std::endl;
638  }
639  matPairCand.push_back(matPair);
640  if (matPairCand.size() == 3) {
641  goto END;
642  }
643  }
644  }
645  }
646  }
647  }
648  }
649 
650  END:
651  if (matPairCand.size() == 0) {
652  return matPairSave;
653  } else {
654  size_t nmatch = matPairCand[0].size();
655  afwTable::ReferenceMatchVector matPairRet = matPairCand[0];
656  for (size_t i = 1; i < matPairCand.size(); i++) {
657  if (matPairCand[i].size() > nmatch) {
658  nmatch = matPairCand[i].size();
659  matPairRet = matPairCand[i];
660  }
661  }
662  return matPairRet;
663  }
664  }
std::vector< ReferenceMatch > ReferenceMatchVector
Definition: fwd.h:97
int const x0
Definition: saturated.cc:45
std::vector< RecordProxy > ProxyVector
int d
Definition: KDTree.cc:89
ProxyVector makeProxies(afwTable::SourceCatalog const &sourceCat)
afw::table::Key< double > b
int const y0
Definition: saturated.cc:45