Jpp 20.0.0-rc.8
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 {
180 unique_lock<mutex> lock(in);
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 {
210 unique_lock<mutex> lock(out);
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 {
231 unique_lock<mutex> lock(in);
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
296 typedef JParallelFileScanner< JTypeList<JDAQEvent, JFIT::JEvt> > JParallelFileScanner_t;
297 typedef JParallelFileScanner_t::multi_pointer_type multi_pointer_type;
299 JACOUSTICS::JEvt>::typelist calibration_types;
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;
309 bool overwriteDetector;
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);
336 zap['a'] = make_field(detectorFile);
337 zap['+'] = make_field(calibrationFile) = JPARSER::initialised();
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 {
363 load(detectorFile, detector);
364 }
365 catch(const JException& error) {
366 FATAL(error);
367 }
368
369 unique_ptr<JDynamics> dynamics;
370
371 try {
372
373 dynamics.reset(new JDynamics(detector, Tmax_s));
374
375 dynamics->load(calibrationFile);
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
399 const JBuildL0<JHitL0> buildL0;
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());
439 JRange<double> Z_m;
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
491 JGradient fit(number_of_iterations, number_of_extra_steps, epsilon, 3);
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
548 store(detectorFile, detector);
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
int getString() const
Get string number.
Definition JLocation.hh:135
Router for direct addressing of module data in detector data structure.
const JModule & getModule(const JObjectID &id) const
Get module parameters.
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
JAxis3D & rotate(const JRotation3D &R)
Rotate axis.
Definition JAxis3D.hh:225
General exception.
Definition JException.hh:24
int getID() const
Get identifier.
Definition JObjectID.hh:50
Utility class to parse command line options.
Definition JParser.hh:1698
Auxiliary class for a hit with background rate value.
Definition JHitW0.hh:23
General purpose class for object reading from a list of file names.
General purpose class for parallel reading of objects from a single file or multiple files.
File router for fast addressing of summary data.
void update(const JDAQHeader &header)
Update router.
double getRate(const JDAQPMTIdentifier &id) const
Get rate.
Range of values.
Definition JRange.hh:42
Template L0 hit builder.
Definition JBuildL0.hh:38
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
Long64_t counter_type
Type definition for counter.
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
virtual const pointer_type & next() override
Get next element.
virtual bool hasNext() override
Check availability of next element.
Implementation of object iteration from STD container.
Auxiliary class for recursive type list generation.
Definition JTypeList.hh:351
Auxiliary data structure for average.
void put(const double x)
Put value.
void reset()
Reset.
double getMean() const
Get mean value.
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