18 static double sq(
double x) {
return x * x; }
26 double det = vxx * vyy - vxy * vxy;
39 stream <<
" number of elements " << starMatchList.size() << std::endl;
40 copy(starMatchList.begin(), starMatchList.end(), std::ostream_iterator<StarMatch>(stream));
44 static std::unique_ptr<double[]> chi2_array(
const StarMatchList &starMatchList,
const Gtransfo >ransfo) {
45 unsigned s = starMatchList.size();
46 auto res = std::unique_ptr<double[]>(
new double[s]);
48 for (
auto const &it : starMatchList) res[count++] = it.computeChi2(gtransfo);
52 static unsigned chi2_cleanup(StarMatchList &starMatchList,
const double chi2Cut,
const Gtransfo >ransfo) {
53 unsigned erased = starMatchList.removeAmbiguities(gtransfo);
54 for (
auto smi = starMatchList.begin(); smi != starMatchList.end();) {
55 if (smi->chi2 > chi2Cut) {
56 smi = starMatchList.erase(smi);
78 _chi2 = _transfo->fit(*
this);
88 if (_chi2 <= 0)
return;
89 unsigned npair = int(size());
90 if (npair == 0)
break;
93 std::unique_ptr<double[]> chi2_array(
new double[npair]);
95 for (
auto &starMatch : *
this) chi2_array[count++] = starMatch.chi2 = starMatch.computeChi2(*_transfo);
97 std::sort(chi2_array.get(), chi2_array.get() + npair);
98 double median = (npair & 1) ? chi2_array[npair / 2]
99 : (chi2_array[npair / 2 - 1] + chi2_array[npair / 2]) * 0.5;
102 cut = sq(nSigmas) * median;
103 nremoved = chi2_cleanup(*
this, cut, *_transfo);
110 int deno = (2. * size() - _transfo->getNpar());
111 return (deno > 0) ? sqrt(_dist2 / deno) : -1;
115 for (
auto &smi : *
this) smi.setDistance(gtransfo);
119 if (!which)
return 0;
121 int initial_count = size();
130 return (initial_count - size());
135 setTransfo(std::make_shared<GtransfoLinShift>());
148 if (!_transfo)
return nullptr;
150 auto old_transfo = _transfo->clone();
151 double old_chi2 = _chi2;
156 auto inverted_transfo = _transfo->clone();
161 return inverted_transfo;
167 for (si = begin(); si != end() && count < nKeep; ++count, ++si)
173 for (
auto &starMatch : *
this) {
181 for (
auto const &starMatch : *
this) {
182 if (starMatch.computeDistance(identity) < mindist) n++;
188 const Gtransfo *posteriorTransfo)
const {
191 const Gtransfo &T1 = (priorTransfo) ? *priorTransfo :
id;
192 const Gtransfo &T2 = (posteriorTransfo) ? *posteriorTransfo :
id;
194 for (
auto const &starMatch : *
this) {
199 transformed.push_back(
StarMatch(p1, p2, starMatch.s1, starMatch.s2));
204 stream <<
" ================================================================" << std::endl
205 <<
" Transformation between lists of order " <<
getTransfoOrder() << std::endl
208 <<
" Number in the list = " << size() << std::endl
209 <<
" ================================================================" << std::endl;
214 for (
auto const &starMatch : starMatchList)
215 dist2 += gtransfo.
apply(starMatch.point1).computeDist2(starMatch.point2);
220 unsigned s = starMatchList.size();
221 std::unique_ptr<double[]> chi2s(chi2_array(starMatchList, gtransfo));
223 for (
unsigned k = 0; k < s; ++k) chi2 += chi2s[k];
implements the linear transformations (6 real coefficients).
double computeChi2(const Gtransfo >ransfo) const
returns the chi2 (using errors in the FatPoint's)
bool compareStar2(const StarMatch &one, const StarMatch &two)
A hanger for star associations.
double computeResidual() const
returns the average 1d Residual (last call to refineTransfo)
bool sameStar1(const StarMatch &one, const StarMatch &two)
void setDistance(const Gtransfo >ransfo)
Sets the distance (residual) field of all std::list elements. Mandatory before sorting on distances...
void setTransfoOrder(int order)
set transfo according to the given order.
std::unique_ptr< Gtransfo > inverseTransfo()
returns the inverse transfo (swap, fit(refineTransfo) , and swap).
int recoveredNumber(double mindist) const
count the number of elements for which distance is < mindist
std::ostream & operator<<(std::ostream &stream, const Gtransfo >ransfo)
allows 'stream << Transfo;' (by calling gtransfo.dump(stream)).
Polynomial transformation class.
A Point with uncertainties.
double getChi2() const
access to the chi2 of the last call to refineTransfo.
unsigned removeAmbiguities(const Gtransfo >ransfo, int which=3)
cleans up the std::list of pairs for pairs that share one of their stars, keeping the closest one...
double computeChi2(const StarMatchList &L, const Gtransfo >ransfo)
the actual chi2
virtual void transformPosAndErrors(const FatPoint &in, FatPoint &out) const
void applyTransfo(StarMatchList &transformed, const Gtransfo *priorTransfo, const Gtransfo *posteriorTransfo=nullptr) const
enables to get a transformed StarMatchList.
void setTransfo(const Gtransfo *gtransfo)
sets a transfo between the 2 std::lists and deletes the previous or default one. No fit...
A do-nothing transformation. It anyway has dummy routines to mimick a Gtransfo.
void refineTransfo(double nSigmas)
removes pairs beyond nSigmas in distance (where the sigma scale is set by the fit) and iterates until...
double computeDist2(const StarMatchList &S, const Gtransfo >ransfo)
sum of distance squared
a virtual (interface) class for geometric transformations.
int getTransfoOrder() const
returns the order of the used transfo
bool compareStar1(const StarMatch &one, const StarMatch &two)
void swap()
swaps elements 1 and 2 of each starmatch in std::list.
void dumpTransfo(std::ostream &stream=std::cout) const
print the matching transformation quality (transfo, chi2, residual)
void cutTail(int nKeep)
deletes the tail of the match std::list
virtual void apply(const double xIn, const double yIn, double &xOut, double &yOut) const =0
bool sameStar2(const StarMatch &one, const StarMatch &two)