Jpp 20.0.0-27-g39925593c-D
the software that should make you happy
Loading...
Searching...
No Matches
JPerth.cc
Go to the documentation of this file.
1#include <string>
2#include <iostream>
3#include <iomanip>
4#include <type_traits>
5#include <functional>
6#include <future>
7#include <mutex>
8#include <thread>
9#include <vector>
10#include <set>
11#include <memory>
12#include <algorithm>
13
16#include "JDAQ/JDAQEventIO.hh"
17
21
23
24#include "JSupport/JMeta.hh"
25#include "JSupport/JSupport.hh"
29
34
35#include "JTrigger/JHitL0.hh"
36#include "JTrigger/JBuildL0.hh"
37
38#include "JFit/JFitToolkit.hh"
39#include "JFit/JLine1Z.hh"
40#include "JFit/JLine3Z.hh"
41#include "JFit/JModel.hh"
42#include "JFit/JGandalf.hh"
44#include "JFit/JGradient.hh"
45
47#include "JLang/JVectorize.hh"
48
50
51#include "JMath/JMath.hh"
52#include "JMath/JQuantile_t.hh"
53
54#include "JTools/JRange.hh"
55
56#include "Jeep/JProperties.hh"
57#include "Jeep/JParser.hh"
58#include "Jeep/JMessage.hh"
59
60
61namespace JRECONSTRUCTION {
62
65 using JFIT::JLine1Z;
66 using JFIT::JLine3Z;
68 using JTRIGGER::JHit;
69
71 typedef std::map<int, buffer_type> map_type; //!< identifier -> hits
72
73 /**
74 * Auxiliary data structure to store data and fit in memory.
75 */
76 struct event_type {
79 bool status = true;
80 };
81
84
85
86 /**
87 * Auxiliary class for editing time offset.
88 */
89 struct JEditor :
90 public JParameter_t
91 {
92 /**
93 * Constructor.
94 *
95 * \param data data
96 * \param id identifier
97 */
98 JEditor(data_type& data, const int id) :
99 data(data),
100 id(id),
101 t0(0.0)
102 {}
103
104
105 /**
106 * Apply step.
107 *
108 * \param step step
109 */
110 virtual void apply(const double step) override
111 {
112 for (data_type::iterator evt = data.begin(); evt != data.end(); ++evt) {
113
114 map_type::iterator p = evt->data.find(id);
115
116 if ((evt->status = (p != evt->data.end()))) {
117 for (buffer_type::iterator hit = p->second.begin(); hit != p->second.end(); ++hit) {
118 static_cast<JHit&>(*hit) = JHit(hit->getT1() + step, hit->getToT());
119 }
120 }
121 }
122
123 this->t0 += step;
124 }
125
126 data_type& data; //!< data
127 int id; //!< identifier
128 double t0; //!< time offset [ns]
129 };
130
131
133 typedef JFIT::JRegressor <JFIT::JLine3Z, JFIT::JGandalf> JRegressor_t;
134
135
136 /**
137 * Thread pool for fits to data.
138 */
139 struct JPerth {
140 /**
141 * Constructor.
142 *
143 * \param storage storage for PDFs
144 * \param data data
145 * \param ns number of threads
146 * \param option option
147 */
149 const data_type& data,
150 const size_t ns,
151 const int option) :
152 input(data),
153 stop(false)
154 {
155 using namespace std;
156 using namespace JPP;
157
158 Q.reset();
159
160 for (size_t i = 0; i < ns; ++i) {
161
162 thread worker([this, storage, option]() {
163
164 JRegressor_t regressor(storage);
165
166 regressor.parameters.resize(5);
167
168 regressor.parameters[0] = JLine3Z::pX();
169 regressor.parameters[1] = JLine3Z::pY();
170 regressor.parameters[2] = JLine3Z::pT();
171 regressor.parameters[3] = JLine3Z::pDX();
172 regressor.parameters[4] = JLine3Z::pDY();
173
174 buffer_type data;
175 JLine3Z value;
176
177 for ( ; ; ) {
178
179 {
181
182 cv.wait(lock, [this]() { return stop || this->input.hasNext(); });
183
184 if (stop && !this->input.hasNext()) {
185 return;
186 }
187
188 const event_type* evt = this->input.next();
189
190 // re-organise data
191
192 data.clear();
193
194 // 2 => evaluation of the derivative of the chi2 to each fit parameter.
195
196 if (option != 2 || evt->status) {
197 for (map_type::const_iterator p = evt->data.begin(); p != evt->data.end(); ++p) {
198 copy(p->second.begin(), p->second.end(), back_inserter(data));
199 }
200 }
201
202 value = evt->value;
203 }
204
205 if (!data.empty()) {
206
207 const double chi2 = regressor(value, data.begin(), data.end());
208
209 {
211
212 Q.put(chi2);
213 }
214 }
215 }
216 });
217
218 workers.emplace_back(std::move(worker));
219 }
220 }
221
222
223 /**
224 * Destructor.
225 */
227 {
228 using namespace std;
229
230 {
232
233 stop = true;
234 }
235
236 cv.notify_all();
237
238 for (auto& worker : workers) {
239 worker.join();
240 }
241 }
242
244
245 private:
248 std::mutex in;
249 std::mutex out;
250 std::condition_variable cv;
251 bool stop;
252 };
253
254 /**
255 */
257
258
259 /**
260 * Auxiliary data structure for chi2 function object.
261 */
262 struct JPerth_t {
263 /**
264 * Get chi2.
265 *
266 * \param option option
267 * \return chi2/NDF
268 */
269 double operator()(const int option) const
270 {
271 JPerth(storage, data, ns, option);
272
273 return JPerth::Q.getMean(0.0);
274 }
275
278 const size_t ns;
279 };
280}
281
282
283/**
284 * \file
285 *
286 * Program to determine string or optical module time calibrations.
287 *
288 * \author mdejong
289 */
290int main(int argc, char **argv)
291{
292 using namespace std;
293 using namespace JPP;
294 using namespace KM3NETDAQ;
295
297 typedef JParallelFileScanner_t::multi_pointer_type multi_pointer_type;
300 typedef JMultipleFileScanner<calibration_types> JCalibration_t;
301
302 JMultipleFileScanner<> inputFile;
303 JLimit_t& numberOfEvents = inputFile.getLimit();
304 string detectorFile;
305 JCalibration_t calibrationFile;
306 double Tmax_s;
307 string pdfFile;
308 JMuonGandalfParameters_t parameters;
310 set<int> strings; // string identifiers
311 set<int> modules; // module identifiers
312 int number_of_iterations = 1000;
313 int number_of_extra_steps = 0;
314 double epsilon = 1.0e-4;
315 double T_ns = 2.5; // step size
316 size_t threads; // number of threads
317 int debug;
318
319 parameters.ZMin_m = -1.0e4; // set range hit selection
320 parameters.ZMax_m = +1.0e4;
321
322 const int DEFAULT_ID = -1;
323
324 try {
325
326 JProperties properties;
327
328 properties.insert(gmake_property(number_of_iterations));
329 properties.insert(gmake_property(number_of_extra_steps));
330 properties.insert(gmake_property(epsilon));
331 properties.insert(gmake_property(T_ns));
332
333 JParser<> zap("Program to determine string or optical module time calibrations.");
334
335 zap['f'] = make_field(inputFile);
338 zap['T'] = make_field(Tmax_s) = 100.0;
339 zap['n'] = make_field(numberOfEvents) = JLimit::max();
340 zap['F'] = make_field(pdfFile);
341 zap['@'] = make_field(parameters) = JPARSER::initialised();
342 zap['A'] = make_field(overwriteDetector, "overwrite detector file provided through '-a' with fitted time offsets.");
343 zap['S'] = make_field(strings, "string identifiers (" << DEFAULT_ID << " => all)") = JPARSER::initialised();
344 zap['M'] = make_field(modules, "module identifiers (" << DEFAULT_ID << " => all)") = JPARSER::initialised();
345 zap['%'] = make_field(properties, "fit parameters") = JPARSER::initialised();
346 zap['N'] = make_field(threads, "number of threads") = 1;
347 zap['d'] = make_field(debug) = 1;
348
349 zap(argc, argv);
350 }
351 catch(const exception& error) {
352 FATAL(error.what() << endl);
353 }
354
355
356 if (strings.empty() == modules.empty()) {
357 FATAL("Set either strings (option -S) or modules (option -M)." << endl);
358 }
359
361
362 try {
364 }
365 catch(const JException& error) {
366 FATAL(error);
367 }
368
370
371 try {
372
373 dynamics.reset(new JDynamics(detector, Tmax_s));
374
376 }
377 catch(const exception& error) {
378 if (!calibrationFile.empty()) {
379 FATAL(error.what());
380 }
381 }
382
383 const JModuleRouter router(dynamics ? dynamics->getDetector() : detector);
384
385 NOTICE("Reading PDFs... " << flush);
386
387 const JRegressorStorage_t storage(pdfFile, JTimeRange(parameters.TMin_ns, parameters.TMax_ns), parameters.TTS_ns);
388
389 NOTICE("OK" << endl);
390
391 JRegressor_t::debug = debug;
392 JRegressor_t::Vmax_npe = parameters.VMax_npe;
393 JRegressor_t::MAXIMUM_ITERATIONS = parameters.NMax;
394
395 // preprocess input data
396
397 NOTICE("Reading data" << endl);
398
400
401 data_type data;
402
403 counter_type skip = inputFile.getLowerLimit();
404 counter_type counter = inputFile.getLowerLimit();
405
406 for (JMultipleFileScanner<>::const_iterator i = inputFile.begin(); i != inputFile.end(); ++i) {
407
408 JSummaryFileRouter summary(*i);
409
410 for (JParallelFileScanner_t in(*i); (skip -= in.skip(skip)) == 0 && in.hasNext() && counter != numberOfEvents; ++counter) {
411
412 STATUS("event: " << setw(10) << counter << '\r'); DEBUG(endl);
413
414 multi_pointer_type ps = in.next();
415
416 const JDAQEvent* tev = ps;
417 JFIT::JEvt* evt = ps;
418
419 summary.update(*tev);
420
421 if (dynamics) {
422 dynamics->update(*tev);
423 }
424
425 JFIT::JEvt::iterator __end = partition(evt->begin(), evt->end(), JHistory::is_application(JMUONGANDALF));
426
427 if (evt->begin() != __end) {
428
429 sort(evt->begin(), __end, qualitySorter);
430
431 vector<JHitL0> dataL0;
432
433 buildL0(*tev, router, true, back_inserter(dataL0));
434
435 const JFIT::JFit& fit = (*evt)[0];
436
437 const JRotation3D R (getDirection(fit));
438 const JLine1Z tz(getPosition (fit).rotate(R), fit.getT());
440
441 if (fit.getW(JSTART_LENGTH_METRES, 0.0) > 0.0) {
442 Z_m = JZRange(fit.getW(JSTART_ZMIN_M) + parameters.ZMin_m,
443 fit.getW(JSTART_ZMAX_M) + parameters.ZMax_m);
444 }
445
446 const JFIT::JModel<JLine1Z> match(tz, parameters.roadWidth_m, JTimeRange(parameters.TMin_ns, parameters.TMax_ns), Z_m);
447
448 // hit selection based on start value
449
450 buffer_type buffer;
451
452 for (vector<JHitL0>::const_iterator i = dataL0.begin(); i != dataL0.end(); ++i) {
453
454 JHitW0 hit(*i, summary.getRate(i->getPMTIdentifier(), parameters.R_Hz));
455
456 hit.rotate(R);
457
458 if (match(hit)) {
459 buffer.push_back(hit);
460 }
461 }
462
463 // select first hit
464
465 sort(buffer.begin(), buffer.end(), JHitL0::compare);
466
467 buffer_type::const_iterator __end = unique(buffer.begin(), buffer.end(), equal_to<JDAQPMTIdentifier>());
468
469 // re-organise data
470
471 map_type map;
472
473 for (buffer_type::const_iterator hit = buffer.begin(); hit != __end; ++hit) {
474
475 const JModule& module = router.getModule(hit->getModuleID());
476
477 if (!strings.empty()) { map[module.getString()].push_back(*hit); }
478 if (!modules.empty()) { map[module.getID()] .push_back(*hit); }
479 }
480
481 data.push_back({map, tz, true});
482 }
483 }
484 }
485 STATUS(endl);
486 NOTICE("OK" << endl);
487
488
489 // fit
490
492
493 if (strings.count(DEFAULT_ID) != 0) { strings = getStringIDs(detector); }
494 if (modules.count(DEFAULT_ID) != 0) { modules = getModuleIDs(detector); }
495
496 for (int id : strings) { fit.push_back(JModifier_t(MAKE_STRING("string: " << FILL(4,'0') << id << FILL()), new JEditor(data, id), T_ns)); }
497 for (int id : modules) { fit.push_back(JModifier_t(MAKE_STRING("module: " << setw(8) << id), new JEditor(data, id), T_ns)); }
498
499 const JPerth_t perth = {storage, data, threads};
500
501 const double chi2 = fit(perth);
502
503 STATUS("result: " << FIXED(12,6) << chi2 << ' ' << setw(6) << fit.numberOfIterations << endl);
504
505 for (size_t i = 0; i != fit.size(); ++i) {
506 {
507 const JEditor* p = dynamic_cast<const JEditor*>(fit[i].get());
508
509 if (p != NULL) { STATUS(fit[i].name << ' ' << FIXED(9,3) << p->t0 << " [ns]" << endl); }
510 }
511 }
512
513
514 if (overwriteDetector) {
515
516 detector.comment.add(JMeta(argc, argv));
517
519
520 for (size_t i = 0; i != fit.size(); ++i) {
521
522 const JEditor* p = dynamic_cast<const JEditor*>(fit[i].get());
523
524 if (p != NULL) {
525 calibration[p->id] = p->t0;
526 }
527 }
528
529 const double t0 = getAverage(get_values(calibration), 0.0);
530
531 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
532
533 if (!module->empty()) {
534
535 map<int, double>::const_iterator p = (!strings.empty() ? calibration.find(module->getString()) :
536 !modules.empty() ? calibration.find(module->getID()) :
537 calibration.end());
538 if (p != calibration.end()) {
539 for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
540 module->getPMT(pmt).addT0(p->second - t0);
541 }
542 }
543 }
544 }
545
546 NOTICE("Store calibration data on file " << detectorFile << endl);
547
549 }
550}
Data structure for detector geometry and calibration.
Dynamic detector calibration.
Auxiliary methods to evaluate Poisson probabilities and chi2.
Basic data structure for L0 hit.
Data regression method for JFIT::JLine3Z.
Base class for data structures with artithmetic capabilities.
General purpose messaging.
#define DEBUG(A)
Message macros.
Definition JMessage.hh:62
#define STATUS(A)
Definition JMessage.hh:63
#define NOTICE(A)
Definition JMessage.hh:64
#define FATAL(A)
Definition JMessage.hh:67
int debug
debug level
Definition JSirene.cc:72
ROOT I/O of application specific meta data.
Direct access to module in detector data structure.
Scanning of objects from multiple files according a format that follows from the extension of each fi...
Parallel scanning of objects from a single file or multiple files according a format that follows fro...
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2142
int main(int argc, char **argv)
Definition JPerth.cc:290
#define MAKE_STRING(A)
Make string.
Definition JPrint.hh:63
Utility class to parse parameter values.
#define gmake_property(A)
macros to convert (template) parameter to JPropertiesElement object
Auxiliary class to define a range between two values.
ROOT TTree parameter settings of various packages.
Auxiliary methods to convert data members or return values of member methods of a set of objects to a...
Detector data structure.
Definition JDetector.hh:96
Router for direct addressing of module data in detector data structure.
Data structure for a composite optical module.
Definition JModule.hh:76
Utility class to parse parameter values.
Data structure for set of track fit results.
Data structure for track fit results with history and optional associated values.
const std::vector< double > & getW() const
Get associated values.
double getT() const
Get time.
Data structure for fit of straight line paralel to z-axis.
Definition JLine1Z.hh:29
static parameter_type pY()
Definition JLine1Z.hh:181
static parameter_type pX()
Definition JLine1Z.hh:180
static parameter_type pT()
Definition JLine1Z.hh:182
Data structure for fit of straight line in positive z-direction.
Definition JLine3Z.hh:40
static parameter_type pDY()
Definition JLine3Z.hh:320
static parameter_type pDX()
Definition JLine3Z.hh:319
General exception.
Definition JException.hh:24
virtual bool hasNext()=0
Check availability of next element.
virtual const pointer_type & next()=0
Get next element.
Template definition of a multi-dimensional oscillation probability interpolation table.
void load()
Load oscillation probability table.
Auxiliary class for a hit with background rate value.
Definition JHitW0.hh:23
File router for fast addressing of summary data.
void update(const JDAQHeader &header)
Update router.
double getRate(const JDAQPMTIdentifier &id) const
Get rate.
Hit data structure.
const char * map
Definition elog.cc:87
static const int JSTART_ZMAX_M
end position of track see JRECONSTRUCTION::JMuonStart
static const int JSTART_LENGTH_METRES
distance between projected positions on the track of optical modules for which the response does not ...
static const int JSTART_ZMIN_M
start position of track see JRECONSTRUCTION::JMuonStart
JDirection3D getDirection(const Vec &dir)
Get direction.
JPosition3D getPosition(const Vec &pos)
Get position.
JTOOLS::JRange< double > JTimeRange
Type definition for time range (unit [s]).
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file.
std::set< int > getStringIDs(const JDetector &detector)
Get list of strings identifiers.
std::set< int > getModuleIDs(const JDetector &detector, const bool option=false)
Get list of modules identifiers.
JTOOLS::JRange< double > JZRange
const array_type< JValue_t > & get_values(const std::map< JKey_t, JValue_t, JComparator_t, JAllocator_t > &data)
Method to create array of values of map.
std::iterator_traits< T >::value_type getAverage(T __begin, T __end)
Get average.
Definition JMath.hh:494
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
std::vector< JHitW0 > buffer_type
hits
Definition JPerth.cc:70
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.
JLANG::JSTDObjectReader< const event_type > input_type
Definition JPerth.cc:83
std::vector< event_type > data_type
Definition JPerth.cc:82
JFIT::JRegressor< JFIT::JLine3Z, JFIT::JGandalf > JRegressor_t
Definition JPerth.cc:133
JFIT::JRegressorStorage< JFIT::JLine3Z, JFIT::JGandalf > JRegressorStorage_t
Definition JPerth.cc:132
std::map< int, buffer_type > map_type
identifier -> hits
Definition JPerth.cc:71
KM3NeT DAQ data structures and auxiliaries.
Definition DataQueue.cc:39
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
Definition JDAQ.hh:26
Auxiliary data structure for sequence of same character.
Definition JManip.hh:330
Auxiliary data structure for floating point format specification.
Definition JManip.hh:448
Calibration.
Definition JHead.hh:330
Detector file.
Definition JHead.hh:227
Acoustic event fit.
Data structure for measured coincidence rates of all pairs of PMTs in optical module.
Definition JFitK40.hh:103
Orientation of module.
Dynamic detector calibration.
Definition JDynamics.hh:86
Conjugate gradient fit.
Definition JGradient.hh:75
size_t numberOfIterations
Definition JGradient.hh:273
Auxiliary class to test history.
Definition JHistory.hh:188
Auxiliary class to match data points with given model.
Auxiliary data structure for editable parameter.
Definition JGradient.hh:49
Auxiliary data structure for fit parameter.
Definition JGradient.hh:28
Template data structure for storage of internal data.
Template definition of a data regressor of given model.
Definition JRegressor.hh:70
Implementation of object iteration from STD container.
Auxiliary class for recursive type list generation.
Definition JTypeList.hh:351
Auxiliary data structure for average.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition JParser.hh:68
Auxiliary class for editing time offset.
Definition JPerth.cc:91
data_type & data
data
Definition JPerth.cc:126
double t0
time offset [ns]
Definition JPerth.cc:128
JEditor(data_type &data, const int id)
Constructor.
Definition JPerth.cc:98
virtual void apply(const double step) override
Apply step.
Definition JPerth.cc:110
double TMin_ns
minimal time w.r.t. Cherenkov hypothesis [ns]
double TMax_ns
maximal time w.r.t. Cherenkov hypothesis [ns]
double VMax_npe
maximum number of of photo-electrons
Auxiliary data structure for chi2 function object.
Definition JPerth.cc:262
const JRegressorStorage_t & storage
Definition JPerth.cc:276
double operator()(const int option) const
Get chi2.
Definition JPerth.cc:269
const data_type & data
Definition JPerth.cc:277
Thread pool for fits to data.
Definition JPerth.cc:139
std::vector< std::thread > workers
Definition JPerth.cc:246
std::condition_variable cv
Definition JPerth.cc:250
static JMATH::JQuantile_t Q
Definition JPerth.cc:243
~JPerth()
Destructor.
Definition JPerth.cc:226
JPerth(const JRegressorStorage_t &storage, const data_type &data, const size_t ns, const int option)
Constructor.
Definition JPerth.cc:148
Auxiliary data structure to store data and fit in memory.
Definition JPerth.cc:76
Auxiliary class for defining the range of iterations of objects.
Definition JLimit.hh:45
static counter_type max()
Get maximum counter value.
Definition JLimit.hh:128
Auxiliary class for ROOT I/O of application specific meta data.
Definition JMeta.hh:72
Auxiliary data structure for sorting of hits.
Definition JHitL0.hh:85