9 #include "boost/shared_array.hpp" 
   10 #include "boost/multi_index_container.hpp" 
   11 #include "boost/multi_index/sequenced_index.hpp" 
   12 #include "boost/multi_index/ordered_index.hpp" 
   13 #include "boost/multi_index/global_fun.hpp" 
   15 #include "gsl/gsl_linalg.h" 
   36 struct insertionOrderTag {};  
 
   37 typedef boost::multi_index_container<
 
   39         boost::multi_index::indexed_by<  
 
   40                 boost::multi_index::sequenced<boost::multi_index::tag<insertionOrderTag> >,
 
   41                 boost::multi_index::ordered_unique<  
 
   42                         boost::multi_index::tag<refIdTag>,
 
   43                         boost::multi_index::global_fun<ProxyPair const &, afwTable::RecordId, &getRefId> > > >
 
   44         MultiIndexedProxyPairList;
 
   55 inline double absDeltaAngle(
double ang1, 
double ang2) { 
return std::fmod(
std::fabs(ang1 - ang2), 
M_PI * 2); }
 
   64 struct CompareProxyFlux {
 
   66         double aFlux = 
a.record->get(
key);
 
   67         double bFlux = 
b.record->get(
key);
 
   92     if (startInd >= 
a.size()) {
 
   95     CompareProxyFlux cmp = {
key};
 
  106     for (
size_t i = 0; i < 
a.size(); i++) {
 
  108         double dpa = absDeltaAngle(
a[i].pa, p.
pa);
 
  109         if (dd < e && dpa < e_dpa) {
 
  118                                              ProxyPair const &q, 
double e, 
double dpa, 
double e_dpa = 0.02) {
 
  120     double dd_min = 1.E+10;
 
  123     for (
auto i = 
a.begin(); i != 
a.end(); ++i) {
 
  126         if (dd < e && absDeltaAngle(p.
pa, i->pa - dpa) < e_dpa && dd < dd_min && (i->first == q.
first)) {
 
  131         if (dd < e && absDeltaAngle(p.
pa, i->pa - dpa) < dpa_min) {
 
  141 void transform(
int order, boost::shared_array<double> 
const &
coeff, 
double x, 
double y, 
double *xn,
 
  143     int ncoeff = (order + 1) * (order + 2) / 2;
 
  147     for (
int i = 0; i <= order; i++) {
 
  148         for (
int k = 0; k <= i; k++) {
 
  158     int ncoeff = (order + 1) * (order + 2) / 2;
 
  163     for (
int i = 0; i <= order; i++) {
 
  164         for (
int k = 0; k <= i; k++) {
 
  173     for (
size_t k = 0; k < img.
size(); k++) {
 
  181     boost::shared_array<double> 
coeff(
new double[
ncoeff * 2]);
 
  183     for (
int loop = 0; loop < 1; loop++) {
 
  184         for (
int i = 0; i < 
ncoeff; i++) {
 
  185             for (
int j = 0; j < 
ncoeff; j++) {
 
  186                 a_data[i * 
ncoeff + j] = 0.0;
 
  187                 for (
size_t k = 0; k < img.
size(); k++) {
 
  190                                 pow(img[k].getX(), xorder[i]) * 
pow(img[k].getY(), yorder[i]) *
 
  191                                 pow(img[k].getX(), xorder[j]) * 
pow(img[k].getY(), yorder[j]);
 
  195             b_data[i] = c_data[i] = 0.0;
 
  196             for (
unsigned int k = 0; k < img.
size(); k++) {
 
  198                     b_data[i] += 
pow(img[k].getX(), xorder[i]) * 
pow(img[k].getY(), yorder[i]) *
 
  200                     c_data[i] += 
pow(img[k].getX(), xorder[i]) * 
pow(img[k].getY(), yorder[i]) *
 
  206         gsl_matrix_view 
a = gsl_matrix_view_array(a_data.get(), 
ncoeff, 
ncoeff);
 
  207         gsl_vector_view 
b = gsl_vector_view_array(b_data.get(), 
ncoeff);
 
  208         gsl_vector_view c = gsl_vector_view_array(c_data.get(), 
ncoeff);
 
  217         gsl_linalg_LU_decomp(&
a.matrix, p.get(), &s);
 
  218         gsl_linalg_LU_solve(&
a.matrix, p.get(), &
b.vector, 
x.get());
 
  219         gsl_linalg_LU_solve(&
a.matrix, p.get(), &c.vector, 
y.get());
 
  221         for (
int i = 0; i < 
ncoeff; i++) {
 
  226         double S, Sx, Sy, Sxx, Syy;
 
  227         S = Sx = Sy = Sxx = Syy = 0.0;
 
  228         for (
size_t k = 0; k < img.
size(); k++) {
 
  230                 double x0 = img[k].getX();
 
  231                 double y0 = img[k].getY();
 
  235                 Sx += (x1 - posRefCat[k].getX());
 
  236                 Sxx += (x1 - posRefCat[k].getX()) * (x1 - posRefCat[k].getX());
 
  237                 Sy += (y1 - posRefCat[k].getY());
 
  238                 Syy += (y1 - posRefCat[k].getY()) * (y1 - posRefCat[k].getY());
 
  241         double x_sig = 
std::sqrt((Sxx - Sx * Sx / S) / S);
 
  242         double y_sig = 
std::sqrt((Syy - Sy * Sy / S) / S);
 
  245         for (
size_t k = 0; k < img.
size(); k++) {
 
  246             double x0 = img[k].getX();
 
  247             double y0 = img[k].getY();
 
  250             if (
std::fabs(x1 - posRefCat[k].getX()) > 2. * x_sig ||
 
  251                 std::fabs(y1 - posRefCat[k].getY()) > 2. * y_sig) {
 
  273                                                                   double y, 
double matchingAllowancePix) {
 
  274     auto minDistSq = matchingAllowancePix * matchingAllowancePix;
 
  275     auto foundPtr = posRefCat.
end();
 
  276     for (
auto posRefPtr = posRefCat.
begin(); posRefPtr != posRefCat.
end(); ++posRefPtr) {
 
  277         auto const dx = posRefPtr->getX() - 
x;
 
  278         auto const dy = posRefPtr->getY() - 
y;
 
  279         auto const distSq = dx * dx + dy * dy;
 
  280         if (distSq < minDistSq) {
 
  281             foundPtr = posRefPtr;
 
  306 void addNearestMatch(MultiIndexedProxyPairList &proxyPairList, boost::shared_array<double> 
coeff,
 
  312     auto refObjDist = searchNearestPoint(posRefCat, x1, y1, matchingAllowancePix);
 
  313     if (refObjDist.first == posRefCat.
end()) {
 
  317     auto existingMatch = proxyPairList.get<refIdTag>().
find(refObjDist.first->record->getId());
 
  318     if (existingMatch == proxyPairList.get<refIdTag>().end()) {
 
  321         proxyPairList.get<refIdTag>().insert(proxyPair);
 
  329             if (existingMatch->distance <= refObjDist.second) {
 
  334                 proxyPairList.get<refIdTag>().
erase(existingMatch);
 
  336                 proxyPairList.get<refIdTag>().insert(proxyPair);
 
  352                                            ProxyVector const &sourceCat, 
double matchingAllowancePix,
 
  354     MultiIndexedProxyPairList proxyPairList;
 
  356     for (
auto sourcePtr = sourceCat.
begin(); sourcePtr != sourceCat.
end(); ++sourcePtr) {
 
  357         addNearestMatch(proxyPairList, 
coeff, posRefCat, *sourcePtr, matchingAllowancePix);
 
  360     if (proxyPairList.size() > 5) {
 
  361         for (
auto j = 0; j < 100; j++) {
 
  362             auto prevNumMatches = proxyPairList.size();
 
  365             srcMat.reserve(proxyPairList.size());
 
  366             catMat.reserve(proxyPairList.size());
 
  367             for (
auto matchPtr = proxyPairList.get<refIdTag>().begin();
 
  368                  matchPtr != proxyPairList.get<refIdTag>().end(); ++matchPtr) {
 
  369                 catMat.push_back(matchPtr->first);
 
  370                 srcMat.push_back(matchPtr->second);
 
  372             coeff = polyfit(order, srcMat, catMat);
 
  373             proxyPairList.clear();
 
  375             for (ProxyVector::const_iterator sourcePtr = sourceCat.
begin(); sourcePtr != sourceCat.
end();
 
  377                 addNearestMatch(proxyPairList, 
coeff, posRefCat, *sourcePtr, matchingAllowancePix);
 
  379             if (proxyPairList.size() == prevNumMatches) {
 
  385     matPair.reserve(proxyPairList.size());
 
  386     for (
auto proxyPairIter = proxyPairList.get<insertionOrderTag>().begin();
 
  387          proxyPairIter != proxyPairList.get<insertionOrderTag>().end(); ++proxyPairIter) {
 
  389                 proxyPairIter->first.record,
 
  390                 std::static_pointer_cast<afwTable::SourceRecord>(proxyPairIter->second.record),
 
  391                 proxyPairIter->distance));
 
  404     if (refFluxField.empty()) {
 
  407     if (sourceFluxField.empty()) {
 
  410     if (numBrightStars <= 0) {
 
  413     if (minMatchedPairs < 0) {
 
  416     if (matchingAllowancePix <= 0) {
 
  419     if (maxOffsetPix <= 0) {
 
  422     if (maxRotationDeg <= 0) {
 
  425     if (allowedNonperpDeg <= 0) {
 
  428     if (numPointsForShape <= 0) {
 
  431     if (maxDeterminant <= 0) {
 
  440     for (afwTable::SourceCatalog::const_iterator sourcePtr = sourceCat.begin(); sourcePtr != sourceCat.end();
 
  465     if (posRefCat.empty()) {
 
  468     if (sourceCat.empty()) {
 
  471     if (posRefBegInd < 0) {
 
  474     if (
static_cast<size_t>(posRefBegInd) >= posRefCat.size()) {
 
  482     for (
auto iter = sourceCat.begin(); 
iter != sourceCat.end(); ++
iter) {
 
  485     srcCenter /= sourceCat.size();
 
  488     for (
auto iter = posRefCat.begin(); 
iter != posRefCat.end(); ++
iter) {
 
  489         refCenter += 
iter->getCoord().getVector();
 
  491     refCenter /= posRefCat.size();
 
  501             selectPoint(sourceProxyCat, sourceCat.getSchema().find<
double>(control.
sourceFluxField).key,
 
  507             selectPoint(posRefProxyCat, posRefCat.getSchema().
find<
double>(control.
refFluxField).key,
 
  508                         sourceSubCat.
size() + 25, posRefBegInd);
 
  515     size_t const posRefCatSubSize = posRefSubCat.
size();
 
  516     for (
size_t i = 0; i < posRefCatSubSize - 1; i++) {
 
  517         for (
size_t j = i + 1; j < posRefCatSubSize; j++) {
 
  525     size_t const sourceSubCatSize = sourceSubCat.
size();
 
  526     for (
size_t i = 0; i < sourceSubCatSize - 1; i++) {
 
  527         for (
size_t j = i + 1; j < sourceSubCatSize; j++) {
 
  538     for (
size_t ii = 0; ii < sourcePairList.
size(); ii++) {
 
  550             for (
size_t l = 0; l < q.
size(); l++) {
 
  553                 double dpa = p.
pa - q[l].pa;
 
  566                 for (
size_t k = 0; k < sourceSubCat.
size(); k++) {
 
  567                     if (p.
first == sourceSubCat[k] || p.
second == sourceSubCat[k]) 
continue;
 
  573                     if (r != posRefPairList.
end()) {
 
  580                         if (srcMatPair.
size() == fullShapeSize) {
 
  586                 bool goodMatch = 
false;
 
  587                 if (srcMatPair.
size() == fullShapeSize) {
 
  589                     for (
size_t k = 1; k < catMatPair.
size(); k++) {
 
  590                         if (catMatPair[0].
first != catMatPair[k].
first) {
 
  597                 if (goodMatch && srcMatPair.
size() == fullShapeSize) {
 
  603                     for (
size_t k = 0; k < srcMatPair.
size(); k++) {
 
  608                     boost::shared_array<double> 
coeff = polyfit(1, srcMat, catMat);
 
  611                         for (
size_t k = 0; k < srcMat.
size(); k++) {
 
  612                             std::cout << 
"circle(" << srcMat[k].getX() << 
"," << srcMat[k].getY()
 
  614                             std::cout << 
"circle(" << catMat[k].getX() << 
"," << catMat[k].getY()
 
  616                             std::cout << 
"line(" << srcMat[0].getX() << 
"," << srcMat[0].getY() << 
"," 
  617                                       << srcMat[k].getX() << 
"," << srcMat[k].getY()
 
  618                                       << 
") # line=0 0 color=green" << 
std::endl;
 
  619                             std::cout << 
"line(" << catMat[0].getX() << 
"," << catMat[0].getY() << 
"," 
  620                                       << catMat[k].getX() << 
"," << catMat[k].getY()
 
  621                                       << 
") # line=0 0 color=red" << 
std::endl;
 
  638                         std::cout << 
"Angle between axes (deg; allowed 90 +/- ";
 
  651                         double x0, y0, x1, y1;
 
  655                         for (
size_t i = 0; i < sourceSubCat.
size(); i++) {
 
  656                             x0 = sourceSubCat[i].getX();
 
  657                             y0 = sourceSubCat[i].getY();
 
  661                             if (refObjDist.first != posRefSubCat.
end()) {
 
  666                                     std::cout << 
"Match: " << x0 << 
"," << y0 << 
" --> " << x1 << 
"," << y1
 
  667                                               << 
" <==> " << refObjDist.first->getX() << 
"," 
  668                                               << refObjDist.first->getY() << 
std::endl;
 
  679                         coeff = polyfit(1, srcMat, catMat);
 
  682                             for (
size_t i = 0; i < 6; ++i) {
 
  688                         matPair = FinalVerify(
coeff, posRefProxyCat, sourceProxyCat,
 
  691                             std::cout << 
"Number of matches: " << matPair.
size() << 
" vs " 
  698                             if (matPair.
size() > matPairSave.
size()) {
 
  699                                 matPairSave = matPair;
 
  707                             if (matPairCand.
size() == 3) {
 
  718     if (matPairCand.
size() == 0) {
 
  721         size_t nmatch = matPairCand[0].
size();
 
  723         for (
size_t i = 1; i < matPairCand.
size(); i++) {
 
  724             if (matPairCand[i].size() > nmatch) {
 
  725                 nmatch = matPairCand[i].
size();
 
  726                 matPairRet = matPairCand[i];