Jpp test-rotations-old
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 */
80
83
84
85 /**
86 * Auxiliary class for editing time offset.
87 */
88 struct JEditor :
89 public JParameter_t
90 {
91 /**
92 * Constructor.
93 *
94 * \param data data
95 * \param id identifier
96 */
97 JEditor(data_type& data, const int id) :
98 data(data),
99 id(id),
100 t0(0.0)
101 {}
102
103
104 /**
105 * Apply step.
106 *
107 * \param step step
108 */
109 virtual void apply(const double step) override
110 {
111 for (data_type::iterator evt = data.begin(); evt != data.end(); ++evt) {
112
113 map_type::iterator p = evt->data.find(id);
114
115 if (p != evt->data.end()) {
116 for (buffer_type::iterator hit = p->second.begin(); hit != p->second.end(); ++hit) {
117 static_cast<JHit&>(*hit) = JHit(hit->getT1() + step, hit->getToT());
118 }
119 }
120 }
121
122 this->t0 += step;
123 }
124
125 data_type& data; //!< data
126 int id; //!< identifier
127 double t0; //!< time offset [ns]
128 };
129
130
132 typedef JFIT::JRegressor <JFIT::JLine3Z, JFIT::JGandalf> JRegressor_t;
133
134
135 /**
136 * Thread pool for fits to data.
137 */
138 struct JPerth {
139 /**
140 * Constructor.
141 *
142 * \param storage storage for PDFs
143 * \param data data
144 * \param ns number of threads
145 */
147 const data_type& data,
148 const size_t ns) :
149 input(data),
150 stop(false)
151 {
152 using namespace std;
153 using namespace JPP;
154
155 Q.reset();
156
157 for (size_t i = 0; i < ns; ++i) {
158
159 thread worker([this, storage]() {
160
161 JRegressor_t regressor(storage);
162
163 regressor.parameters.resize(5);
164
165 regressor.parameters[0] = JLine3Z::pX();
166 regressor.parameters[1] = JLine3Z::pY();
167 regressor.parameters[2] = JLine3Z::pT();
168 regressor.parameters[3] = JLine3Z::pDX();
169 regressor.parameters[4] = JLine3Z::pDY();
170
171 buffer_type data;
172 JLine3Z value;
173
174 for ( ; ; ) {
175
176 {
177 unique_lock<mutex> lock(in);
178
179 cv.wait(lock, [this]() { return stop || this->input.hasNext(); });
180
181 if (stop && !this->input.hasNext()) {
182 return;
183 }
184
185 const event_type* evt = this->input.next();
186
187 // re-organise data
188
189 data.clear();
190
191 for (map_type::const_iterator p = evt->data.begin(); p != evt->data.end(); ++p) {
192 copy(p->second.begin(), p->second.end(), back_inserter(data));
193 }
194
195 value = evt->value;
196 }
197
198 const double chi2 = regressor(value, data.begin(), data.end());
199
200 {
201 unique_lock<mutex> lock(out);
202
203 Q.put(chi2);
204 }
205 }
206 });
207
208 workers.emplace_back(std::move(worker));
209 }
210 }
211
212
213 /**
214 * Destructor.
215 */
217 {
218 using namespace std;
219
220 {
221 unique_lock<mutex> lock(in);
222
223 stop = true;
224 }
225
226 cv.notify_all();
227
228 for (auto& worker : workers) {
229 worker.join();
230 }
231 }
232
234
235 private:
238 std::mutex in;
239 std::mutex out;
240 std::condition_variable cv;
241 bool stop;
242 };
243
244 /**
245 */
247
248
249 /**
250 * Auxiliary data structure for chi2 function object.
251 */
252 struct JPerth_t {
253 /**
254 * Get chi2.
255 *
256 * \param option option
257 * \return chi2/NDF
258 */
259 double operator()(const int option) const
260 {
262
263 return JPerth::Q.getMean();
264 }
265
268 const size_t ns;
269 };
270}
271
272
273/**
274 * \file
275 *
276 * Program to determine string or optical module time calibrations.
277 *
278 * \author mdejong
279 */
280int main(int argc, char **argv)
281{
282 using namespace std;
283 using namespace JPP;
284 using namespace KM3NETDAQ;
285
286 typedef JParallelFileScanner< JTypeList<JDAQEvent, JFIT::JEvt> > JParallelFileScanner_t;
287 typedef JParallelFileScanner_t::multi_pointer_type multi_pointer_type;
289 JACOUSTICS::JEvt>::typelist calibration_types;
290 typedef JMultipleFileScanner<calibration_types> JCalibration_t;
291
292 JMultipleFileScanner<> inputFile;
293 JLimit_t& numberOfEvents = inputFile.getLimit();
294 string detectorFile;
295 JCalibration_t calibrationFile;
296 double Tmax_s;
297 string pdfFile;
298 JMuonGandalfParameters_t parameters;
299 bool overwriteDetector;
300 set<int> strings; // string identifiers
301 set<int> modules; // module identifiers
302 int number_of_iterations = 1000;
303 int number_of_extra_steps = 0;
304 double epsilon = 1.0e-4;
305 double T_ns = 2.5; // step size
306 size_t threads; // number of threads
307 int debug;
308
309 const int DEFAULT_ID = -1;
310
311 try {
312
313 JProperties properties;
314
315 properties.insert(gmake_property(number_of_iterations));
316 properties.insert(gmake_property(number_of_extra_steps));
317 properties.insert(gmake_property(epsilon));
318 properties.insert(gmake_property(T_ns));
319
320 JParser<> zap("Program to determine string or optical module time calibrations.");
321
322 zap['f'] = make_field(inputFile);
323 zap['a'] = make_field(detectorFile);
324 zap['+'] = make_field(calibrationFile) = JPARSER::initialised();
325 zap['T'] = make_field(Tmax_s) = 100.0;
326 zap['n'] = make_field(numberOfEvents) = JLimit::max();
327 zap['P'] = make_field(pdfFile);
328 zap['@'] = make_field(parameters) = JPARSER::initialised();
329 zap['A'] = make_field(overwriteDetector, "overwrite detector file provided through '-a' with fitted time offsets.");
330 zap['S'] = make_field(strings, "string identifiers (" << DEFAULT_ID << " => all)") = JPARSER::initialised();
331 zap['M'] = make_field(modules, "module identifiers (" << DEFAULT_ID << " => all)") = JPARSER::initialised();
332 zap['%'] = make_field(properties, "fit parameters") = JPARSER::initialised();
333 zap['N'] = make_field(threads, "number of threads") = 1;
334 zap['d'] = make_field(debug) = 1;
335
336 zap(argc, argv);
337 }
338 catch(const exception& error) {
339 FATAL(error.what() << endl);
340 }
341
342
343 if (strings.empty() == modules.empty()) {
344 FATAL("Set either strings (option -S) or modules (option -M)." << endl);
345 }
346
348
349 try {
350 load(detectorFile, detector);
351 }
352 catch(const JException& error) {
353 FATAL(error);
354 }
355
356 unique_ptr<JDynamics> dynamics;
357
358 try {
359
360 dynamics.reset(new JDynamics(detector, Tmax_s));
361
362 dynamics->load(calibrationFile);
363 }
364 catch(const exception& error) {
365 if (!calibrationFile.empty()) {
366 FATAL(error.what());
367 }
368 }
369
370 const JModuleRouter router(dynamics ? dynamics->getDetector() : detector);
371
372 NOTICE("Reading PDFs... " << flush);
373
374 const JRegressorStorage_t storage(pdfFile, JTimeRange(parameters.TMin_ns, parameters.TMax_ns), parameters.TTS_ns);
375
376 NOTICE("OK" << endl);
377
378 JRegressor_t::debug = debug;
379 JRegressor_t::Vmax_npe = parameters.VMax_npe;
380 JRegressor_t::MAXIMUM_ITERATIONS = parameters.NMax;
381
382 // preprocess input data
383
384 const JBuildL0<JHitL0> buildL0;
385
386 data_type data;
387
388 counter_type skip = inputFile.getLowerLimit();
389 counter_type counter = inputFile.getLowerLimit();
390
391 for (JMultipleFileScanner<>::const_iterator i = inputFile.begin(); i != inputFile.end(); ++i) {
392
393 JSummaryFileRouter summary(*i);
394
395 for (JParallelFileScanner_t in(*i); (skip -= in.skip(skip)) == 0 && in.hasNext() && counter != numberOfEvents; ++counter) {
396
397 STATUS("event: " << setw(10) << counter << '\r'); DEBUG(endl);
398
399 multi_pointer_type ps = in.next();
400
401 const JDAQEvent* tev = ps;
402 const JFIT::JEvt* evt = ps;
403
404 summary.update(*tev);
405
406 if (dynamics) {
407 dynamics->update(*tev);
408 }
409
410 if (!evt->empty()) {
411
412 vector<JHitL0> dataL0;
413
414 buildL0(*tev, router, true, back_inserter(dataL0));
415
416 const JFIT::JFit& fit = (*evt)[0];
417
418 const JRotation3D R (getDirection(fit));
419 const JLine1Z tz(getPosition (fit).rotate(R), fit.getT());
420 JRange<double> Z_m;
421
422 if (fit.hasW(JSTART_LENGTH_METRES) &&
423 fit.getW(JSTART_LENGTH_METRES) > 0.0) {
424 Z_m = JZRange(parameters.ZMin_m, parameters.ZMax_m + fit.getW(JSTART_LENGTH_METRES));
425 }
426
427 const JFIT::JModel<JLine1Z> match(tz, parameters.roadWidth_m, JTimeRange(parameters.TMin_ns, parameters.TMax_ns), Z_m);
428
429 // hit selection based on start value
430
431 buffer_type buffer;
432
433 for (vector<JHitL0>::const_iterator i = dataL0.begin(); i != dataL0.end(); ++i) {
434
435 JHitW0 hit(*i, summary.getRate(i->getPMTIdentifier(), parameters.R_Hz));
436
437 hit.rotate(R);
438
439 if (match(hit)) {
440 buffer.push_back(hit);
441 }
442 }
443
444 // select first hit
445
446 sort(buffer.begin(), buffer.end(), JHitL0::compare);
447
448 buffer_type::const_iterator __end = unique(buffer.begin(), buffer.end(), equal_to<JDAQPMTIdentifier>());
449
450 // re-organise data
451
452 map_type map;
453
454 for (buffer_type::const_iterator hit = buffer.begin(); hit != __end; ++hit) {
455
456 const JModule& module = router.getModule(hit->getModuleID());
457
458 if (!strings.empty()) { map[module.getString()].push_back(*hit); }
459 if (!modules.empty()) { map[module.getID()] .push_back(*hit); }
460 }
461
462 data.push_back({map, tz});
463 }
464 }
465 }
466 STATUS(endl);
467
468
469 // fit
470
471 JGradient fit(number_of_iterations, number_of_extra_steps, epsilon, 3);
472
473 if (strings.count(DEFAULT_ID) != 0) { strings = getStringIDs(detector); }
474 if (modules.count(DEFAULT_ID) != 0) { modules = getModuleIDs(detector); }
475
476 for (int id : strings) { fit.push_back(JModifier_t(MAKE_STRING("string: " << FILL(4,'0') << id << FILL()), new JEditor(data, id), T_ns)); }
477 for (int id : modules) { fit.push_back(JModifier_t(MAKE_STRING("module: " << setw(8) << id), new JEditor(data, id), T_ns)); }
478
479 const JPerth_t perth = {storage, data, threads};
480
481 const double chi2 = fit(perth);
482
483 STATUS("result: " << FIXED(12,6) << chi2 << ' ' << setw(6) << fit.numberOfIterations << endl);
484
485 for (size_t i = 0; i != fit.size(); ++i) {
486 {
487 const JEditor* p = dynamic_cast<const JEditor*>(fit[i].get());
488
489 if (p != NULL) { STATUS(fit[i].name << ' ' << FIXED(9,3) << p->t0 << " [ns]" << endl); }
490 }
491 }
492
493
494 if (overwriteDetector) {
495
496 detector.comment.add(JMeta(argc, argv));
497
499
500 for (size_t i = 0; i != fit.size(); ++i) {
501
502 const JEditor* p = dynamic_cast<const JEditor*>(fit[i].get());
503
504 if (p != NULL) {
505 calibration[p->id] = p->t0;
506 }
507 }
508
509 const double t0 = getAverage(get_values(calibration), 0.0);
510
511 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
512
513 if (!module->empty()) {
514
515 map<int, double>::const_iterator p = (!strings.empty() ? calibration.find(module->getString()) :
516 !modules.empty() ? calibration.find(module->getID()) :
517 calibration.end());
518 if (p != calibration.end()) {
519 for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
520 module->getPMT(pmt).addT0(p->second - t0);
521 }
522 }
523 }
524 }
525
526 NOTICE("Store calibration data on file " << detectorFile << endl);
527
528 store(detectorFile, detector);
529 }
530}
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:280
#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:75
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.
bool hasW(const int i) const
Check availability of value.
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 double rate_Hz) 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_LENGTH_METRES
distance between projected positions on the track of optical modules for which the response does not ...
JDirection3D getDirection(const Vec &dir)
Get direction.
void copy(const Head &from, JHead &to)
Copy header from from to to.
Definition JHead.cc:163
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).
Model fits to data.
std::vector< JHitW0 > buffer_type
hits
Definition JPerth.cc:70
JLANG::JSTDObjectReader< const event_type > input_type
Definition JPerth.cc:82
std::vector< event_type > data_type
Definition JPerth.cc:81
JFIT::JRegressor< JFIT::JLine3Z, JFIT::JGandalf > JRegressor_t
Definition JPerth.cc:132
JFIT::JRegressorStorage< JFIT::JLine3Z, JFIT::JGandalf > JRegressorStorage_t
Definition JPerth.cc:131
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 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:90
data_type & data
data
Definition JPerth.cc:125
double t0
time offset [ns]
Definition JPerth.cc:127
JEditor(data_type &data, const int id)
Constructor.
Definition JPerth.cc:97
virtual void apply(const double step) override
Apply step.
Definition JPerth.cc:109
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:252
const JRegressorStorage_t & storage
Definition JPerth.cc:266
double operator()(const int option) const
Get chi2.
Definition JPerth.cc:259
const data_type & data
Definition JPerth.cc:267
Thread pool for fits to data.
Definition JPerth.cc:138
JPerth(const JRegressorStorage_t &storage, const data_type &data, const size_t ns)
Constructor.
Definition JPerth.cc:146
std::vector< std::thread > workers
Definition JPerth.cc:236
std::condition_variable cv
Definition JPerth.cc:240
static JMATH::JQuantile_t Q
Definition JPerth.cc:233
~JPerth()
Destructor.
Definition JPerth.cc:216
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