Jpp 21.0.0-rc.1
the software that should make you happy
Loading...
Searching...
No Matches
JMuonPrefit.hh
Go to the documentation of this file.
1#ifndef __JRECONSTRUCTION__JMUONPREFIT__
2#define __JRECONSTRUCTION__JMUONPREFIT__
3
4#include <iostream>
5#include <iomanip>
6#include <vector>
7#include <algorithm>
8
12
13#include "JTrigger/JHitR1.hh"
14#include "JTrigger/JBuildL0.hh"
15#include "JTrigger/JBuildL2.hh"
17#include "JTrigger/JMatch1D.hh"
18#include "JTrigger/JMatch3B.hh"
19
20#include "JFit/JLine1Z.hh"
22#include "JFit/JMatrixNZ.hh"
23#include "JFit/JVectorNZ.hh"
24#include "JFit/JFitToolkit.hh"
25
29
30#include "JMath/JConstants.hh"
32
33#include "JLang/JPredicate.hh"
34
37
39
42
43#include "Jeep/JMessage.hh"
44
45
46/**
47 * \author mdejong, gmaggi, azegarelli
48 */
49
50namespace JRECONSTRUCTION {}
51namespace JPP { using namespace JRECONSTRUCTION; }
52
53namespace JRECONSTRUCTION {
54
57 using JFIT::JLine1Z;
58 using JFIT::JEstimator;
59 using JFIT::JMatrixNZ;
60 using JFIT::JVectorNZ;
65
66
67 /**
68 * Wrapper class to make pre-fit of muon trajectory.
69 *
70 * The JMuonPrefit fit is used to generate start values for subsequent fits (usually JMuonSimplex and JMuonGandalf).\n
71 * To this end, a scan of directions is made and the time and transverse positions of the track are fitted for each direction (JFIT::JEstimator<JLine1Z>).\n
72 * The directions are spaced by the parameters JMuonPrefitParameters_t::gridAngle_deg.\n
73 * This angle corresponds to the envisaged angular accuracy of the result.\n
74 * The probability that one of the results is less than this angle away from the correct value,
75 * multiple start values should be considered (JMuonPrefitParameters_t::numberOfPrefits).\n
76 * Note that the CPU time scales with the inverse of the square of this angle.\n
77 * The chi-squared is based on the time residuals.\n
78 */
79 struct JMuonPrefit :
81 public JEstimator<JLine1Z>
82 {
86
87 using JEstimator_t::operator();
88
89 /**
90 * Input data type.
91 */
92 struct input_type :
93 public JDAQEventHeader
94 {
95 /**
96 * Default constructor.
97 */
99 {}
100
101
102 /**
103 * Constructor.
104 *
105 * \param header header
106 * \param coverage coverage
107 */
109 const coverage_type& coverage) :
110 JDAQEventHeader(header),
112 {}
113
117 };
118
119
120 /**
121 * Constructor
122 *
123 * \param parameters parameters
124 * \param debug debug
125 */
127 const int debug = 0) :
128 JMuonPrefitParameters_t(parameters),
129 omega (parameters.gridAngle_deg * JMATH::PI/180.0),
130 debug (debug)
131 {}
132
133
134 /**
135 * Constructor
136 *
137 * \param parameters parameters
138 * \param omega directions
139 * \param debug debug
140 */
142 const JOmega3D& omega,
143 const int debug = 0) :
144 JMuonPrefitParameters_t(parameters),
145 omega (omega),
146 debug (debug)
147 {}
148
149
150 /**
151 * Get input data.
152 *
153 * \param router module router
154 * \param event event
155 * \param coverage coverage
156 * \return input data
157 */
159 const JDAQEvent& event,
160 const coverage_type& coverage) const
161
162 {
163 using namespace std;
164 using namespace JTRIGGER;
165 using namespace KM3NETDAQ;
166
167 const JBuildL0<hit_type> buildL0;
169
170 input_type input(event.getDAQEventHeader(), coverage);
171
172 buffer_type& dataL0 = input.dataL0;
173 buffer_type& dataL1 = input.dataL1;
174
175 buildL2(event, router, !useL0, back_inserter(dataL1));
176
177 // 3D cluster of unique optical modules
178
180
181 sort(dataL1.begin(), dataL1.end(), hit_type::compare);
182
183 buffer_type::iterator __end = dataL1.end();
184
185 __end = unique(dataL1.begin(), __end, equal_to<JDAQModuleIdentifier>());
186
187 __end = clusterizeWeight(dataL1.begin(), __end, match3B);
188
189 dataL1.erase(__end, dataL1.end());
190
191
192 if (useL0) {
193
194 buildL0(event, router, true, back_inserter(dataL0));
195
196 __end = dataL0.end();
197
198 for (buffer_type::iterator i = dataL0.begin(); i != __end; ) {
199
200 if (match3B.count(*i, dataL1.begin(), dataL1.end()) != 0)
201 ++i;
202 else
203 swap(*i, *--__end);
204 }
205
206 dataL0.erase(__end, dataL0.end());
207 }
208
209 return input;
210 }
211
212
213 /**
214 * Fit function.
215 *
216 * \param input input data
217 * \return fit results
218 */
220 {
221 using namespace std;
222 using namespace JPP;
223
224 const double HIT_OFF = 1.0e3 * sigma_ns * sigma_ns; // [ns^2]
225
227
228 const buffer_type& dataL0 = input.dataL0;
229 const buffer_type& dataL1 = input.dataL1;
230
231 data.reserve(dataL0.size() +
232 dataL1.size());
233
234 JEvent event(JMUONPREFIT);
235
236 JEvt out;
237
238 for (JOmega3D_t::const_iterator dir = omega.begin(); dir != omega.end(); ++dir) {
239
240 const JRotation3D R(*dir);
241
242
243 buffer_type::iterator __end = copy(dataL1.begin(), dataL1.end(), data.begin());
244
245 for (buffer_type::iterator i = data.begin(); i != __end; ++i) {
246 i->rotate(R);
247 }
248
249
250 // reduce data
251
252 if (distance(data.begin(), __end) > NMaxHits) {
253
254 buffer_type::iterator __p = data.begin();
255
256 advance(__p, NMaxHits);
257
258 partial_sort(data.begin(), __p, __end, cmz);
259
260 __end = __p;
261 }
262
263
264 // 1D cluster
265
266 __end = clusterizeWeight(data.begin(), __end, match1D);
267
268 if (useL0 &&
269 distance(data.begin(), __end) < useL0 &&
270 distance(data.begin(), __end) < NMaxHits) {
271
272 buffer_type::iterator p = __end; // begin L0 data
273 buffer_type::iterator q = copy(dataL0.begin(), dataL0.end(), p); // end L0 data
274
275 for (buffer_type::iterator i = p; i != q; ++i) {
276
277 if (find_if(data.begin(), __end, make_predicate(&hit_type::getModuleID, i->getModuleID())) == __end) {
278
279 i->rotate(R);
280
281 if (match1D.count(*i, data.begin(), __end) != 0) {
282 *p = *i;
283 ++p;
284 }
285 }
286 }
287
288 __end = clusterize(__end, p, match1D);
289 }
290
291
292 if (distance(data.begin(), __end) <= NUMBER_OF_PARAMETERS) {
293 continue;
294 }
295
296
297 // 1D fit
298
299 JLine1Z tz;
300 double chi2 = numeric_limits<double>::max();
301 int NDF = distance(data.begin(), __end) - NUMBER_OF_PARAMETERS;
302 int N = getCount(data.begin(), __end);
303
304 try {
305
306 sort(data.begin(), __end, hit_type::compare);
307
308 (*this)(data.begin(), __end);
309
310 V.set(*this, data.begin(), __end, gridAngle_deg, sigma_ns);
311 Y.set(*this, data.begin(), __end);
312
313 V.invert();
314
315 tz = *this;
316 chi2 = getChi2(Y, V);
317 }
318 catch(const exception& error) {
319 continue;
320 }
321
322
323 // outlier removal
324
325 if (distance(data.begin(), __end) <= factoryLimit) {
326
327 int number_of_outliers = numberOfOutliers;
328
329 if (number_of_outliers > NDF - 1) {
330 number_of_outliers = NDF - 1;
331 }
332
333 double ymin = chi2 - STANDARD_DEVIATIONS * STANDARD_DEVIATIONS;
334
335 for (int n = 1; n <= number_of_outliers; ++n, ymin -= STANDARD_DEVIATIONS * STANDARD_DEVIATIONS) {
336
337 sort(data.begin(), __end, hit_type::compare);
338
339 buffer_type::iterator __end1 = prev(__end, n);
340
341 do {
342
343 try {
344
345 (*this)(data.begin(), __end1);
346
347 V.set(*this, data.begin(), __end1, gridAngle_deg, sigma_ns);
348 Y.set(*this, data.begin(), __end1);
349
350 V.invert();
351
352 double y = getChi2(Y, V);
353
355
356 WARNING(endl << "JMuonPrefit: invalid chi2 " << y << endl);
357
358 } else {
359
360 if (y < 0.0) {
361 y = 0.0;
362 }
363
364 if (y < ymin) {
365 ymin = y;
366 tz = *this;
367 chi2 = ymin;
368 NDF = distance(data.begin(), __end1) - NUMBER_OF_PARAMETERS;
369 N = getCount(data.begin(), __end1);
370 }
371 }
372 }
373 catch(const exception& error) {}
374
375 } while (next_permutation(data.begin(), __end1, __end, hit_type::compare));
376 }
377
378 } else {
379
380 const int number_of_outliers = NDF - 1;
381
382 for (int n = 1; n <= number_of_outliers; ++n) {
383
384 double ymax = 0.0;
385 int k = -1;
386
387 for (size_t i = 0; i != Y.size(); ++i) {
388
389 double y = getChi2(Y, V, i);
390
391 if (y > ymax) {
392 ymax = y;
393 k = i;
394 }
395 }
396
398 break;
399 }
400
401 try {
402
403 V.update(k, +HIT_OFF);
404
405 this->update(data.begin(), __end, V);
406
407 Y.set(*this, data.begin(), __end);
408
409 tz = *this;
410 chi2 = getChi2(Y, V);
411 NDF -= 1;
412 N -= getCount(data[k]);
413 }
414 catch(const exception& error) {
415 break;
416 }
417 }
418 }
419
420 tz.rotate_back(R);
421
422 out.push_back(getFit(event(), tz, *dir, getQuality(chi2, N, NDF), NDF));
423
424 // set additional values
425
426 out.rbegin()->setW(JPP_COVERAGE_ORIENTATION, input.coverage.orientation);
427 out.rbegin()->setW(JPP_COVERAGE_POSITION, input.coverage.position);
428 }
429
430
431 if (numberOfPrefits > 0) {
432
433 JEvt::iterator __end = out.end();
434
435 if (Qwatershed > 0) { // sort distinct maxima
436
437 __end = out.begin(); // output
438
439 for (JEvt::iterator p1 = out.begin(); p1 != out.end() && (size_t) distance(out.begin(), __end) < numberOfPrefits; ) {
440
441 JEvt::iterator p2 = p1; // p2 -> best-of-the-rest
442
443 for (JEvt::iterator i = p1; i != out.end(); ++i) {
444 if (qualitySorter(*i, *p2)) {
445 p2 = i;
446 }
447 }
448
449 swap(*p2, *p1); // put best-of-the-rest at head
450
451 p2 = p1++; // p2 = head; p1 = next to head
452
453 const JPointing pointing(*p2); // reference direction
454
455 sort(p1, out.end(), pointing); // sort according space angle with respect to reference direction
456
457 for (double Q = p2->getQ();
458 p1 != out.end() && (p1->getQ() >= p2->getQ() - Qwatershed || // bottom
459 p1->getQ() <= Q); // descend
460 ++p1) {
461 Q = p1->getQ();
462 }
463
464 swap(*(__end++), *p2); // output head
465 }
466
467 } else {
468
469 advance(__end = out.begin(), min(numberOfPrefits, out.size()));
470
471 partial_sort(out.begin(), __end, out.end(), qualitySorter);
472 }
473
474 if (numberOfPostfits > 0) {
475
476 __end = gridify(__end, out.end(), numberOfPostfits);
477 }
478
479 out.erase(__end, out.end());
480
481 } else {
482
483 sort(out.begin(), out.end(), qualitySorter);
484 }
485
486 return out;
487 }
488
489
490 /**
491 * Auxiliary data structure for sorting of hits.
492 */
493 static const struct cmz {
494 /**
495 * Sort hits according times corrected for position along z-axis.
496 *
497 * \param first first hit
498 * \param second second hit
499 * \return true if first hit earlier than second hit; else false
500 */
501 template<class T>
502 inline bool operator()(const T& first, const T& second) const
503 {
504 using namespace JPP;
505
506 return (first .getT() * getSpeedOfLight() - first .getZ() <
507 second.getT() * getSpeedOfLight() - second.getZ());
508 }
510
511
513 int debug;
514
515 static constexpr double STANDARD_DEVIATIONS = 3.0; //!< number of standard deviations for outlier removal [unit]
516
517 private:
521 };
522}
523
524#endif
Algorithms for hit clustering and sorting.
Coverage of dynamical detector calibration.
TPaveText * p1
Auxiliary methods to evaluate Poisson probabilities and chi2.
Reduced data structure for L1 hit.
Linear fit of JFIT::JLine1Z.
Match operator for Cherenkov light from muon with given direction.
Match operator for Cherenkov light from muon in any direction.
Mathematical constants.
General purpose messaging.
#define WARNING(A)
Definition JMessage.hh:65
Direct access to module in detector data structure.
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Router for direct addressing of module data in detector data structure.
Template definition of linear fit.
Definition JEstimator.hh:25
Data structure for set of track fit results.
Data structure for fit of straight line paralel to z-axis.
Definition JLine1Z.hh:29
Determination of the co-variance matrix of hits for a track along z-axis (JFIT::JLine1Z).
Definition JMatrixNZ.hh:30
void set(const JVector3D &pos, T __begin, T __end, const double alpha, const double sigma)
Set co-variance matrix.
Definition JMatrixNZ.hh:85
Determination of the time residual vector of hits for a track along z-axis (JFIT::JLine1Z).
Definition JVectorNZ.hh:23
void set(const JLine1Z &track, T __begin, T __end)
Set time residual vector.
Definition JVectorNZ.hh:68
Direction set covering (part of) solid angle.
Definition JOmega3D.hh:68
JPosition3D & rotate_back(const JRotation3D &R)
Rotate back.
Auxiliary class to compare fit results with respect to a reference direction (e.g....
Template L0 hit builder.
Definition JBuildL0.hh:38
Template L2 builder.
Definition JBuildL2.hh:49
Reduced data structure for L1 hit.
Definition JHitR1.hh:38
1D match criterion.
Definition JMatch1D.hh:33
3D match criterion with road width.
Definition JMatch3B.hh:36
const JDAQEventHeader & getDAQEventHeader() const
Get DAQ event header.
int getModuleID() const
Get module identifier.
static const int JPP_COVERAGE_POSITION
coverage of dynamic position calibration of this event
static const int JPP_COVERAGE_ORIENTATION
coverage of dynamic orientation calibration of this event
double getChi2(const double P)
Get chi2 corresponding to given probability.
size_t getCount(const array_type< T > &buffer, const JCompare_t &compare)
Count number of unique values.
const double getSpeedOfLight()
Get speed of light.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
double getQuality(const double chi2, const int N, const int NDF)
Get quality of fit.
void copy(const JFIT::JEvt::const_iterator __begin, const JFIT::JEvt::const_iterator __end, Evt &out)
Copy tracks.
bool qualitySorter(const JFit &first, const JFit &second)
Comparison of fit results.
JFit getFit(const JHistory &history, const JTrack3D &track, const double Q, const int NDF, const double energy=0.0, const int status=SINGLE_STAGE)
Get fit.
JEvt::iterator gridify(JEvt::iterator __begin, JEvt::iterator __end, const int N)
Gridify set of fits.
counter_type advance(counter_type &counter, const counter_type value, const counter_type limit=std::numeric_limits< counter_type >::max())
Advance counter.
const int n
Definition JPolint.hh:791
bool next_permutation(T __begin, T __last, T __end, JComparator_t compare, std::bidirectional_iterator_tag)
Implementation of method next_permutation for bidirectional iterators.
Auxiliary classes and methods for triggering.
JHitIterator_t clusterize(JHitIterator_t __begin, JHitIterator_t __end, const JMatch_t &match, const int Nmin=1)
Partition data according given binary match operator.
Definition JAlgorithm.hh:38
JHitIterator_t clusterizeWeight(JHitIterator_t __begin, JHitIterator_t __end, const JMatch_t &match)
Partition data according given binary match operator.
KM3NeT DAQ data structures and auxiliaries.
Definition DataQueue.cc:39
Data structure for coverage of detector by dynamical calibrations.
Definition JCoverage.hh:19
double position
coverage of detector by available position calibration [0,1]
Definition JCoverage.hh:42
double orientation
coverage of detector by available orientation calibration [0,1]
Definition JCoverage.hh:41
Auxiliary class for historical event.
Definition JHistory.hh:40
void update(const size_t k, const double value)
Update inverted matrix at given diagonal element.
Definition JMatrixNS.hh:446
void invert()
Invert matrix according LDU decomposition.
Definition JMatrixNS.hh:75
double ctMin
minimal cosine space angle between PMT axes
int factoryLimit
factory limit for combinatorics
double TMaxLocal_ns
time window for local coincidences [ns]
double gridAngle_deg
grid angle for directions [deg]
Auxiliary data structure for sorting of hits.
bool operator()(const T &first, const T &second) const
Sort hits according times corrected for position along z-axis.
input_type(const JDAQEventHeader &header, const coverage_type &coverage)
Constructor.
Wrapper class to make pre-fit of muon trajectory.
static constexpr double STANDARD_DEVIATIONS
number of standard deviations for outlier removal [unit]
static const struct JRECONSTRUCTION::JMuonPrefit::cmz cmz
input_type getInput(const JModuleRouter &router, const JDAQEvent &event, const coverage_type &coverage) const
Get input data.
JMuonPrefit(const JMuonPrefitParameters_t &parameters, const int debug=0)
Constructor.
JEstimator< JLine1Z > JEstimator_t
JEvt operator()(const input_type &input)
Fit function.
std::vector< hit_type > buffer_type
JMuonPrefit(const JMuonPrefitParameters_t &parameters, const JOmega3D &omega, const int debug=0)
Constructor.
Auxiliary data structure for sorting of hits.
Definition JHitR1.hh:206
Data structure for L2 parameters.