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"
530 if (posRefBegInd < 0) {
531 throw LSST_EXCEPT(pexExcept::InvalidParameterError,
"posRefBegInd < 0");
533 if (posRefBegInd >= posRefCat.size()) {
534 throw LSST_EXCEPT(pexExcept::InvalidParameterError,
"posRefBegInd too big");
539 if (
wcs.hasDistortion()) {
543 for (
auto iter = sourceCat.begin();
iter != sourceCat.end(); ++
iter) {
546 srcCenter /= sourceCat.size();
549 for (
auto iter = posRefCat.begin();
iter != posRefCat.end(); ++
iter) {
552 refCenter /= posRefCat.size();
554 tanWcs = boost::make_shared<afw::image::Wcs>(
567 sourceCat.getSchema().find<
double>(control.sourceFluxField).key,
568 control.numBrightStars);
574 posRefCat.getSchema().find<
double>(control.refFluxField).key,
575 sourceSubCat.size()+25,
578 std::cout <<
"Catalog sizes: " << sourceSubCat.size() <<
" " << posRefSubCat.size() << std::endl;
582 std::vector<ProxyPair> posRefPairList;
583 size_t const posRefCatSubSize = posRefSubCat.size();
584 for (
size_t i = 0; i < posRefCatSubSize-1; i++) {
585 for (
size_t j = i+1; j < posRefCatSubSize; j++) {
586 posRefPairList.push_back(
ProxyPair(posRefSubCat[i], posRefSubCat[j]));
589 std::sort(posRefPairList.begin(), posRefPairList.end(), cmpPair);
592 std::vector<ProxyPair> sourcePairList;
593 size_t const sourceSubCatSize = sourceSubCat.size();
594 for (
size_t i = 0; i < sourceSubCatSize-1; i++) {
595 for (
size_t j = i+1; j < sourceSubCatSize; j++) {
596 sourcePairList.push_back(
ProxyPair(sourceSubCat[i], sourceSubCat[j]));
599 std::sort(sourcePairList.begin(), sourcePairList.end(), cmpPair);
603 std::vector<afwTable::ReferenceMatchVector> matPairCand;
605 size_t const fullShapeSize = control.numPointsForShape - 1;
606 for (
size_t ii = 0; ii < sourcePairList.size(); ii++) {
609 std::vector<ProxyPair> q = searchPair(posRefPairList, p,
610 control.matchingAllowancePix, maxRotationRad);
615 std::vector<ProxyPair> srcMatPair;
616 std::vector<ProxyPair> catMatPair;
619 for (
size_t l = 0; l < q.size(); l++) {
622 double dpa = p.
pa - q[l].pa;
627 srcMatPair.push_back(p);
628 catMatPair.push_back(q[l]);
631 std::cout <<
"p dist: " << p.
distance <<
" pa: " << p.
pa << std::endl;
632 std::cout <<
"q dist: " << q[l].distance <<
" pa: " << q[l].pa << std::endl;
635 for (
size_t k = 0; k < sourceSubCat.size(); k++) {
636 if (p.
first == sourceSubCat[k] || p.
second == sourceSubCat[k])
continue;
640 std::vector<ProxyPair>::iterator r = searchPair3(posRefPairList, pp, q[l],
641 control.matchingAllowancePix, dpa, maxRotationRad);
642 if (r != posRefPairList.end()) {
643 srcMatPair.push_back(pp);
644 catMatPair.push_back(*r);
646 std::cout <<
" p dist: " << pp.distance <<
" pa: " << pp.pa << std::endl;
647 std::cout <<
" r dist: " << (*r).distance <<
" pa: " << (*r).pa << std::endl;
649 if (srcMatPair.size() == fullShapeSize) {
655 bool goodMatch =
false;
656 if (srcMatPair.size() == fullShapeSize) {
658 for (
size_t k = 1; k < catMatPair.size(); k++) {
659 if (catMatPair[0].first != catMatPair[k].first) {
666 if (goodMatch && srcMatPair.size() == fullShapeSize) {
671 srcMat.push_back(srcMatPair[0].first);
672 catMat.push_back(catMatPair[0].first);
673 for (
size_t k = 0; k < srcMatPair.size(); k++) {
674 srcMat.push_back(srcMatPair[k].second);
675 catMat.push_back(catMatPair[k].second);
678 boost::shared_array<double> coeff = polyfit(1, srcMat, catMat);
681 for (
size_t k = 0; k < srcMat.size(); k++) {
682 std::cout <<
"circle(" << srcMat[k].getX() <<
","
683 << srcMat[k].getY() <<
",10) # color=green" << std::endl;
684 std::cout <<
"circle(" << catMat[k].getX() <<
","
685 << catMat[k].getY() <<
",10) # color=red" << std::endl;
686 std::cout <<
"line(" << srcMat[0].getX() <<
"," << srcMat[0].getY() <<
","
687 << srcMat[k].getX() <<
"," << srcMat[k].getY()
688 <<
") # line=0 0 color=green" << std::endl;
689 std::cout <<
"line(" << catMat[0].getX() <<
"," << catMat[0].getY() <<
","
690 << catMat[k].getX() <<
"," << catMat[k].getY()
691 <<
") # line=0 0 color=red" << std::endl;
700 (std::sqrt(a*a+c*c)*std::sqrt(b*b+d*d))),
703 std::cout <<
"Linear fit from match:" << std::endl;
704 std::cout << coeff[0] <<
" " << coeff[1] <<
" " << coeff[2] << std::endl;
705 std::cout << coeff[3] <<
" " << coeff[4] <<
" " << coeff[5] << std::endl;
706 std::cout <<
"Determinant (max " << control.maxDeterminant <<
"): ";
707 std::cout << coeff[1] * coeff[5] - coeff[2] * coeff[4] - 1. << std::endl;
708 std::cout <<
"Angle between axes (deg; allowed 90 +/- ";
709 std::cout << control.allowedNonperpDeg <<
"): ";
710 std::cout << theta.asDegrees() << std::endl;
712 if (std::fabs(coeff[1] * coeff[5] - coeff[2] * coeff[4] - 1.)
713 > control.maxDeterminant ||
714 std::fabs(theta.asDegrees() - 90) > control.allowedNonperpDeg ||
715 std::fabs(coeff[0]) > control.maxOffsetPix ||
716 std::fabs(coeff[3]) > control.maxOffsetPix) {
718 std::cout <<
"Bad; continuing" << std::endl;
722 double x0,
y0, x1, y1;
726 for (
size_t i = 0; i < sourceSubCat.size(); i++) {
727 x0 = sourceSubCat[i].getX();
728 y0 = sourceSubCat[i].getY();
729 transform(1, coeff, x0, y0, &x1, &y1);
730 auto refObjDist = searchNearestPoint(posRefSubCat, x1, y1,
731 control.matchingAllowancePix);
732 if (refObjDist.first != posRefSubCat.end()) {
734 srcMat.push_back(sourceSubCat[i]);
735 catMat.push_back(*refObjDist.first);
737 std::cout <<
"Match: " << x0 <<
"," << y0 <<
" --> "
738 << x1 <<
"," << y1 <<
" <==> "
739 << refObjDist.first->getX() <<
"," << refObjDist.first->getY()
744 if (num <= control.numPointsForShape) {
747 std::cout <<
"Insufficient initial matches; continuing" << std::endl;
751 coeff = polyfit(1, srcMat, catMat);
753 std::cout <<
"Coefficients from initial matching:" << std::endl;
754 for (
size_t i = 0; i < 6; ++i) {
755 std::cout << coeff[i] <<
" ";
757 std::cout << std::endl;
760 matPair = FinalVerify(coeff, posRefProxyCat, sourceProxyCat,
761 control.matchingAllowancePix, verbose);
763 std::cout <<
"Number of matches: " << matPair.size() <<
" vs " <<
764 control.minMatchedPairs << std::endl;
766 if (matPair.size() <= control.minMatchedPairs) {
768 std::cout <<
"Insufficient final matches; continuing" << std::endl;
770 if (matPair.size() > matPairSave.size()) {
771 matPairSave = matPair;
776 std::cout <<
"Finish" << std::endl;
778 matPairCand.push_back(matPair);
779 if (matPairCand.size() == 3) {
790 if (matPairCand.size() == 0) {
793 size_t nmatch = matPairCand[0].size();
795 for (
size_t i = 1; i < matPairCand.size(); i++) {
796 if (matPairCand[i].size() > nmatch) {
797 nmatch = matPairCand[i].size();
798 matPairRet = matPairCand[i];
Extent< double, 3 > Extent3D
lsst::afw::geom::Point2D getPosition(lsst::afw::geom::AngleUnit unit=lsst::afw::geom::degrees) const
Return our contents in a Point2D object.
lsst::afw::geom::Angle Angle
Point< double, 2 > Point2D
std::vector< ReferenceMatch > ReferenceMatchVector
Point< double, 3 > Point3D
lsst::afw::coord::IcrsCoord IcrsCoord
AngleUnit const radians
constant with units of radians
if(width!=gim.getWidth()||height!=gim.getHeight()||x0!=gim.getX0()||y0!=gim.getY0())
lsst::afw::image::Wcs Wcs
double degToRad(long double angleInDegrees)
#define LSST_EXCEPT(type,...)
std::vector< RecordProxy > ProxyVector
afw::table::Key< double > b
Extent< double, 2 > Extent2D
ProxyVector makeProxies(lsst::afw::table::SourceCatalog const &sourceCat, afw::image::Wcs const &distortedWcs, afw::image::Wcs const &tanWcs)