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"
432 int Nsub = control.numBrightStars;
437 sourceCat.getSchema().find<
double>(control.sourceFluxField).key,
441 posRefCat.getSchema().find<
double>(control.refFluxField).key,
442 sourceSubCat.size()+25,
445 std::cout <<
"Catalog sizes: " << sourceSubCat.size() <<
" " << posRefSubCat.size() << std::endl;
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]));
458 std::sort(posRefPairList.begin(), posRefPairList.end(), cmpPair);
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]));
468 std::sort(sourcePairList.begin(), sourcePairList.end(), cmpPair);
472 std::vector<afwTable::ReferenceMatchVector> matPairCand;
474 size_t const fullShapeSize = control.numPointsForShape - 1;
475 for (
size_t ii = 0; ii < sourcePairList.size(); ii++) {
478 std::vector<ProxyPair> q = searchPair(posRefPairList, p,
479 control.matchingAllowancePix, control.maxRotationRad);
484 std::vector<ProxyPair> srcMatPair;
485 std::vector<ProxyPair> catMatPair;
488 for (
size_t l = 0; l < q.size(); l++) {
490 double dpa = p.
pa - q[l].pa;
495 srcMatPair.push_back(p);
496 catMatPair.push_back(q[l]);
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;
503 for (
size_t k = 0;
k < sourceSubCat.size();
k++) {
504 if (p.
first == sourceSubCat[
k] || p.
second == sourceSubCat[
k])
continue;
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);
514 std::cout <<
" p dist: " << pp.distance <<
" pa: " << pp.pa << std::endl;
515 std::cout <<
" r dist: " << (*r).distance <<
" pa: " << (*r).pa << std::endl;
517 if (srcMatPair.size() == fullShapeSize) {
523 bool goodMatch =
false;
524 if (srcMatPair.size() == fullShapeSize) {
526 for (
size_t k = 1; k < catMatPair.size(); k++) {
527 if (catMatPair[0].first != catMatPair[k].first) {
533 if (goodMatch && srcMatPair.size() == fullShapeSize) {
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);
545 boost::shared_array<double> coeff = polyfit(1, srcMat, catMat);
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;
566 double theta = std::acos((a*b+c*d)/(std::sqrt(a*a+c*c)*std::sqrt(b*b+d*d))) /
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;
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) {
580 std::cout <<
"Bad; continuing" << std::endl;
584 double x0,
y0, x1, y1;
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()) {
596 srcMat.push_back(sourceSubCat[i]);
597 catMat.push_back(*p);
599 std::cout <<
"Match: " << x0 <<
"," << y0 <<
" --> "
600 << x1 <<
"," << y1 <<
601 " <==> " << p->getX() <<
"," << p->getY() << std::endl;
605 if (num <= control.numPointsForShape) {
608 std::cout <<
"Insufficient initial matches; continuing" << std::endl;
612 coeff = polyfit(1, srcMat, catMat);
614 std::cout <<
"Coefficients from initial matching:" << std::endl;
615 for (
size_t i = 0; i < 6; ++i) {
616 std::cout << coeff[i] <<
" ";
618 std::cout << std::endl;
621 matPair = FinalVerify(coeff, posRefProxyCat, sourceProxyCat,
622 control.matchingAllowancePix, verbose);
624 std::cout <<
"Number of matches: " << matPair.size() <<
" vs " <<
625 control.minMatchedPairs << std::endl;
627 if (matPair.size() <= control.minMatchedPairs) {
629 std::cout <<
"Insufficient final matches; continuing" << std::endl;
631 if (matPair.size() > matPairSave.size()) {
632 matPairSave = matPair;
637 std::cout <<
"Finish" << std::endl;
639 matPairCand.push_back(matPair);
640 if (matPairCand.size() == 3) {
651 if (matPairCand.size() == 0) {
654 size_t nmatch = matPairCand[0].size();
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];
std::vector< ReferenceMatch > ReferenceMatchVector
std::vector< RecordProxy > ProxyVector
ProxyVector makeProxies(afwTable::SourceCatalog const &sourceCat)
afw::table::Key< double > b