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];