Jpp  18.3.1
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 
18 #include "JDetector/JDetector.hh"
21 
22 #include "JDynamics/JDynamics.hh"
23 
24 #include "JSupport/JMeta.hh"
25 #include "JSupport/JSupport.hh"
29 
31 #include "JReconstruction/JEvt.hh"
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"
43 #include "JFit/JRegressorHelper.hh"
44 #include "JFit/JLine3ZRegressor.hh"
45 #include "JFit/JGradient.hh"
46 
48 
50 
51 #include "JTools/JRange.hh"
52 #include "JTools/JQuantile.hh"
53 
54 #include "Jeep/JProperties.hh"
55 #include "Jeep/JParser.hh"
56 #include "Jeep/JMessage.hh"
57 
58 
59 namespace JRECONSTRUCTION {
60 
62  using JFIT::JParameter_t;
63  using JFIT::JLine1Z;
64  using JFIT::JLine3Z;
66 
67  typedef std::vector<JHitW0> buffer_type; //!< hits
68  typedef std::map<int, buffer_type> map_type; //!< string -> hits
69 
70  /**
71  * Auxiliary data structure to store data and fit in memory.
72  */
73  struct event_type {
76  };
77 
80 
81 
82  /**
83  * Auxiliary class to edit time offset of data per string.
84  */
85  struct JStringEditor :
86  public JParameter_t
87  {
88  /**
89  * Constructor.
90  *
91  * \param data data
92  * \param id string identifier
93  */
94  JStringEditor(data_type& data, const int id) :
95  data(data),
96  id(id),
97  t0(0.0)
98  {}
99 
100 
101  /**
102  * Apply step.
103  *
104  * \param step step
105  */
106  virtual void apply(const double step) override
107  {
108  for (data_type::iterator evt = data.begin(); evt != data.end(); ++evt) {
109 
110  map_type::iterator p = evt->data.find(id);
111 
112  if (p != evt->data.end()) {
113  for (buffer_type::iterator hit = p->second.begin(); hit != p->second.end(); ++hit) {
114  static_cast<JTRIGGER::JHit&>(*hit) = JTRIGGER::JHit(hit->getT1() + step, hit->getToT());
115  }
116  }
117  }
118 
119  this->t0 += step;
120  }
121 
122  data_type& data; //!< data
123  int id; //!< string identifier
124  double t0; //!< time offset [ns]
125  };
126 
127 
130 
131 
132  /**
133  * Thread pool for fits to data.
134  */
135  struct JPerth {
136  /**
137  * Constructor.
138  *
139  * \param storage storage for PDFs
140  * \param data data
141  * \param ns number of threads
142  */
143  JPerth(const JRegressorStorage_t& storage,
144  const data_type& data,
145  const size_t ns) :
146  input(data),
147  stop(false)
148  {
149  using namespace std;
150  using namespace JPP;
151 
152  Q.reset();
153 
154  for (size_t i = 0; i < ns; ++i) {
155 
156  thread worker([this, storage]() {
157 
158  JRegressor_t regressor(storage);
159 
160  regressor.parameters.resize(5);
161 
162  regressor.parameters[0] = JLine3Z::pX();
163  regressor.parameters[1] = JLine3Z::pY();
164  regressor.parameters[2] = JLine3Z::pT();
165  regressor.parameters[3] = JLine3Z::pDX();
166  regressor.parameters[4] = JLine3Z::pDY();
167 
169  JLine3Z value;
170 
171  for ( ; ; ) {
172 
173  {
174  unique_lock<mutex> lock(in);
175 
176  cv.wait(lock, [this]() { return stop || this->input.hasNext(); });
177 
178  if (stop && !this->input.hasNext()) {
179  return;
180  }
181 
182  const event_type* evt = this->input.next();
183 
184  // re-organise data
185 
186  data.clear();
187 
188  for (map_type::const_iterator p = evt->data.begin(); p != evt->data.end(); ++p) {
189  copy(p->second.begin(), p->second.end(), back_inserter(data));
190  }
191 
192  value = evt->value;
193  }
194 
195  const double chi2 = regressor(value, data.begin(), data.end());
196 
197  {
198  unique_lock<mutex> lock(out);
199 
200  Q.put(chi2);
201  }
202  }
203  });
204 
205  workers.emplace_back(std::move(worker));
206  }
207  }
208 
209 
210  /**
211  * Destructor.
212  */
214  {
215  using namespace std;
216 
217  {
218  unique_lock<mutex> lock(in);
219 
220  stop = true;
221  }
222 
223  cv.notify_all();
224 
225  for (auto& worker : workers) {
226  worker.join();
227  }
228  }
229 
231 
232  private:
235  std::mutex in;
236  std::mutex out;
237  std::condition_variable cv;
238  bool stop;
239  };
240 
241  /**
242  */
244 
245 
246  /**
247  * Auxiliary data structure for chi2 function object.
248  */
249  struct JPerth_t {
250  /**
251  * Get chi2.
252  *
253  * \param option option
254  * \return chi2/NDF
255  */
256  double operator()(const int option) const
257  {
258  JPerth(storage, data, ns);
259 
260  return JPerth::Q.getMean();
261  }
262 
264  const data_type& data;
265  const size_t ns;
266  };
267 }
268 
269 
270 /**
271  * \file
272  *
273  * Program to determine inter-string time calibration.
274  *
275  * \author mdejong
276  */
277 int main(int argc, char **argv)
278 {
279  using namespace std;
280  using namespace JPP;
281  using namespace KM3NETDAQ;
282 
283  typedef JParallelFileScanner< JTypeList<JDAQEvent, JFIT::JEvt> > JParallelFileScanner_t;
284  typedef JParallelFileScanner_t::multi_pointer_type multi_pointer_type;
286  JACOUSTICS::JEvt>::typelist calibration_types;
287  typedef JMultipleFileScanner<calibration_types> JCalibration_t;
288 
289  JMultipleFileScanner<> inputFile;
290  JLimit_t& numberOfEvents = inputFile.getLimit();
291  string detectorFile;
292  JCalibration_t calibrationFile;
293  double Tmax_s;
294  string pdfFile;
296  bool overwriteDetector;
297  set<int> ids; // string identifiers
298  int number_of_iterations = 1000;
299  int number_of_extra_steps = 0;
300  double epsilon = 1.0e-4;
301  double T_ns = 2.5; // step size
302  size_t threads; // number of threads
303  int debug;
304 
305  try {
306 
307  JProperties properties;
308 
309  properties.insert(gmake_property(number_of_iterations));
310  properties.insert(gmake_property(number_of_extra_steps));
311  properties.insert(gmake_property(epsilon));
312  properties.insert(gmake_property(T_ns));
313 
314  JParser<> zap("Program to determine inter-string time calibration.");
315 
316  zap['f'] = make_field(inputFile);
317  zap['a'] = make_field(detectorFile);
318  zap['+'] = make_field(calibrationFile) = JPARSER::initialised();
319  zap['T'] = make_field(Tmax_s) = 100.0;
320  zap['n'] = make_field(numberOfEvents) = JLimit::max();
321  zap['P'] = make_field(pdfFile);
323  zap['A'] = make_field(overwriteDetector, "overwrite detector file provided through '-a' with fitted time offsets.");
324  zap['S'] = make_field(ids, "string identifiers (none = all)") = JPARSER::initialised();
325  zap['%'] = make_field(properties, "fit parameters") = JPARSER::initialised();
326  zap['N'] = make_field(threads, "number of threads") = 1;
327  zap['d'] = make_field(debug) = 1;
328 
329  zap(argc, argv);
330  }
331  catch(const exception& error) {
332  FATAL(error.what() << endl);
333  }
334 
335 
337 
338  try {
339  load(detectorFile, detector);
340  }
341  catch(const JException& error) {
342  FATAL(error);
343  }
344 
345  unique_ptr<JDynamics> dynamics;
346 
347  try {
348 
349  dynamics.reset(new JDynamics(detector, Tmax_s));
350 
351  dynamics->load(calibrationFile);
352  }
353  catch(const exception& error) {
354  if (!calibrationFile.empty()) {
355  FATAL(error.what());
356  }
357  }
358 
359  const JModuleRouter router(dynamics ? dynamics->getDetector() : detector);
360 
361  if (ids.empty()) {
362  ids = getStringIDs(detector);
363  }
364 
365  NOTICE("Reading PDFs... " << flush);
366 
367  const JRegressorStorage_t storage(pdfFile, parameters.TTS_ns);
368 
369  NOTICE("OK" << endl);
370 
372  JRegressor_t::T_ns.setRange(parameters.TMin_ns, parameters.TMax_ns);
373  JRegressor_t::Vmax_npe = parameters.VMax_npe;
374  JRegressor_t::MAXIMUM_ITERATIONS = parameters.NMax;
375 
376 
377  // preprocess input data
378 
379  const JBuildL0<JHitL0> buildL0;
380 
381  data_type data;
382 
383  counter_type skip = inputFile.getLowerLimit();
384  counter_type counter = inputFile.getLowerLimit();
385 
386  for (JMultipleFileScanner<>::const_iterator i = inputFile.begin(); i != inputFile.end(); ++i) {
387 
388  JSummaryFileRouter summary(*i, parameters.R_Hz);
389 
390  for (JParallelFileScanner_t in(*i); (skip -= in.skip(skip)) == 0 && in.hasNext() && counter != numberOfEvents; ++counter) {
391 
392  STATUS("event: " << setw(10) << counter << '\r'); DEBUG(endl);
393 
394  multi_pointer_type ps = in.next();
395 
396  const JDAQEvent* tev = ps;
397  const JFIT::JEvt* evt = ps;
398 
399  summary.update(*tev);
400 
401  if (dynamics) {
402  dynamics->update(*tev);
403  }
404 
405  if (!evt->empty()) {
406 
407  vector<JHitL0> dataL0;
408 
409  buildL0(*tev, router, true, back_inserter(dataL0));
410 
411  const JFIT::JFit& fit = (*evt)[0];
412 
413  const JRotation3D R (getDirection(fit));
414  const JLine1Z tz(getPosition (fit).rotate(R), fit.getT());
415  JRange<double> Z_m;
416 
417  if (fit.hasW(JSTART_LENGTH_METRES) &&
418  fit.getW(JSTART_LENGTH_METRES) > 0.0) {
419  Z_m = JZRange(parameters.ZMin_m, parameters.ZMax_m + fit.getW(JSTART_LENGTH_METRES));
420  }
421 
422  const JFIT::JModel<JLine1Z> match(tz, parameters.roadWidth_m, JRegressor_t::T_ns, Z_m);
423 
424  // hit selection based on start value
425 
426  buffer_type buffer;
427 
428  for (vector<JHitL0>::const_iterator i = dataL0.begin(); i != dataL0.end(); ++i) {
429 
430  JHitW0 hit(*i, summary.getRate(i->getPMTIdentifier()));
431 
432  hit.rotate(R);
433 
434  if (match(hit)) {
435  buffer.push_back(hit);
436  }
437  }
438 
439  // select first hit
440 
441  sort(buffer.begin(), buffer.end(), JHitL0::compare);
442 
443  buffer_type::const_iterator __end = unique(buffer.begin(), buffer.end(), equal_to<JDAQPMTIdentifier>());
444 
445  // re-organise data
446 
447  map_type map;
448 
449  for (buffer_type::const_iterator hit = buffer.begin(); hit != __end; ++hit) {
450 
451  const JModule& module = router.getModule(hit->getModuleID());
452 
453  map[module.getString()].push_back(*hit);
454  }
455 
456  data.push_back({map, tz});
457  }
458  }
459  }
460  STATUS(endl);
461 
462 
463  // fit
464 
465  JGradient fit(number_of_iterations, number_of_extra_steps, epsilon, 3);
466 
467  for (int id : ids) {
468  fit.push_back(JModifier_t(MAKE_STRING("string: " << FILL(4,'0') << id << FILL()), new JStringEditor(data, id), T_ns));
469  }
470 
471  const JPerth_t perth = {storage, data, threads};
472 
473  const double chi2 = fit(perth);
474 
475  STATUS("result: " << FIXED(12,6) << chi2 << ' ' << setw(6) << fit.numberOfIterations << endl);
476 
477  for (size_t i = 0; i != fit.size(); ++i) {
478 
479  const JStringEditor* p = dynamic_cast<const JStringEditor*>(fit[i].get());
480 
481  if (p != NULL) {
482  STATUS("string: " << FILL(4,'0') << p->id << FILL() << ' ' << FIXED(9,3) << p->t0 << " [ns]" << endl);
483  }
484  }
485 
486 
487  if (overwriteDetector) {
488 
489  detector.comment.add(JMeta(argc, argv));
490 
492 
493  double t0 = 0.0;
494 
495  for (size_t i = 0; i != fit.size(); ++i) {
496 
497  const JStringEditor* p = dynamic_cast<const JStringEditor*>(fit[i].get());
498 
499  if (p != NULL) {
500 
501  calibration[p->id] = p->t0;
502 
503  t0 += p->t0;
504  }
505  }
506 
507  t0 /= calibration.size();
508 
509  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
510 
511  if (!module->empty()) {
512 
513  map<int, double>::const_iterator p = calibration.find(module->getString());
514 
515  if (p != calibration.end()) {
516  for (int pmt = 0; pmt != NUMBER_OF_PMTS; ++pmt) {
517  module->getPMT(pmt).addT0(p->second - t0);
518  }
519  }
520  }
521  }
522 
523  NOTICE("Store calibration data on file " << detectorFile << endl);
524 
525  store(detectorFile, detector);
526  }
527 }
Auxiliary methods to evaluate Poisson probabilities and chi2.
Data regression method for JFIT::JLine3Z.
Template definition of a data regressor of given model.
Definition: JRegressor.hh:70
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:70
Utility class to parse command line options.
Definition: JParser.hh:1514
General exception.
Definition: JException.hh:24
~JPerth()
Destructor.
Definition: JPerth.cc:213
JPerth(const JRegressorStorage_t &storage, const data_type &data, const size_t ns)
Constructor.
Definition: JPerth.cc:143
int main(int argc, char *argv[])
Definition: Main.cc:15
ROOT TTree parameter settings of various packages.
Auxiliary data structure for chi2 function object.
Definition: JPerth.cc:249
std::vector< event_type > data_type
Definition: JPerth.cc:78
static JTOOLS::JQuantile Q
Definition: JPerth.cc:230
Data structure for a composite optical module.
Definition: JModule.hh:67
const JRegressorStorage_t & storage
Definition: JPerth.cc:263
void reset()
Reset.
Definition: JQuantile.hh:87
const data_type & data
Definition: JPerth.cc:264
std::map< int, buffer_type > map_type
string -&gt; hits
Definition: JPerth.cc:68
Template specialisation of L0 builder for JHitL0 data type.
Definition: JBuildL0.hh:102
#define gmake_property(A)
macros to convert (template) parameter to JPropertiesElement object
Auxiliary data structure for running average, standard deviation and quantiles.
Definition: JQuantile.hh:43
#define STATUS(A)
Definition: JMessage.hh:63
void update(const JDAQHeader &header)
Update router.
Detector data structure.
Definition: JDetector.hh:89
int id
string identifier
Definition: JPerth.cc:123
Router for direct addressing of module data in detector data structure.
Rotation matrix.
Definition: JRotation3D.hh:111
std::set< int > getStringIDs(const JDetector &detector)
Get list of strings identifiers.
std::vector< size_t > ns
double getRate() const
Get default rate.
Utility class to parse parameter values.
Definition: JProperties.hh:497
*fatal Wrong number of arguments esac JCookie sh typeset Z DETECTOR typeset Z SOURCE_RUN typeset Z TARGET_RUN set_variable PARAMETERS_FILE $WORKDIR parameters
Definition: diff-Tuna.sh:38
Hit data structure.
General purpose class for parallel reading of objects from a single file or multiple files...
Template specialisation of class JModel to match hit with muon trajectory along z-axis.
Definition: JFit/JModel.hh:34
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:83
Data structure for fit of straight line in positive z-direction.
Definition: JLine3Z.hh:36
static parameter_type pT()
Definition: JLine1Z.hh:182
Long64_t counter_type
Type definition for counter.
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:446
Template data structure for storage for PDF tables.
std::condition_variable cv
Definition: JPerth.cc:237
Data structure for detector geometry and calibration.
Auxiliary class to edit time offset of data per string.
Definition: JPerth.cc:85
double getMean() const
Get mean value.
Definition: JQuantile.hh:252
static struct JTRIGGER::JHitL0::compare compare
std::vector< JHitW0 > buffer_type
hits
Definition: JPerth.cc:67
Utility class to parse parameter values.
JFIT::JRegressor< JFIT::JLine3Z, JFIT::JGandalf > JRegressor_t
Definition: JPerth.cc:129
#define MAKE_STRING(A)
Make string.
Definition: JPrint.hh:127
Calibration.
Definition: JHead.hh:328
Auxiliary data structure to store data and fit in memory.
Definition: JPerth.cc:73
Basic data structure for L0 hit.
Data structure for track fit results with history and optional associated values. ...
Auxiliary class for defining the range of iterations of objects.
Definition: JLimit.hh:41
static parameter_type pDX()
Definition: JLine3Z.hh:319
JStringEditor(data_type &data, const int id)
Constructor.
Definition: JPerth.cc:94
virtual const pointer_type & next()=0
Get next element.
JAxis3D & rotate(const JRotation3D &R)
Rotate axis.
Definition: JAxis3D.hh:225
Detector file.
Definition: JHead.hh:226
bool hasW(const int i) const
Check availability of value.
Acoustic event fit.
Thread pool for fits to data.
Definition: JPerth.cc:135
Auxiliary class for recursive type list generation.
Definition: JTypeList.hh:351
double getT() const
Get time.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1989
Parallel scanning of objects from a single file or multiple files according a format that follows fro...
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file.
ROOT I/O of application specific meta data.
#define NOTICE(A)
Definition: JMessage.hh:64
JDirection3D getDirection(const JFit &fit)
Get direction.
void put(const double x, const double w=1.0)
Put value.
Definition: JQuantile.hh:133
virtual bool hasNext()=0
Check availability of next element.
Dynamic detector calibration.
File router for fast addressing of summary data.
Auxiliary data structure for fit parameter.
Definition: JGradient.hh:28
std::vector< std::thread > workers
Definition: JPerth.cc:233
static parameter_type pY()
Definition: JLine1Z.hh:181
General purpose messaging.
static parameter_type pDY()
Definition: JLine3Z.hh:320
Auxiliary data structure for sequence of same character.
Definition: JManip.hh:328
#define FATAL(A)
Definition: JMessage.hh:67
Scanning of objects from multiple files according a format that follows from the extension of each fi...
JLANG::JSTDObjectReader< const event_type > input_type
Definition: JPerth.cc:79
Direct access to module in detector data structure.
Auxiliary data structure for editable parameter.
Definition: JGradient.hh:47
static parameter_type pX()
Definition: JLine1Z.hh:180
Dynamic detector calibration.
Definition: JDynamics.hh:81
then JCookie sh JDataQuality D $DETECTOR_ID R
Definition: JDataQuality.sh:41
Auxiliary class for a hit with background rate value.
Definition: JHitW0.hh:21
int getString() const
Get string number.
Definition: JLocation.hh:134
virtual void apply(const double step) override
Apply step.
Definition: JPerth.cc:106
static const int JSTART_LENGTH_METRES
distance between first and last hits in metres from JStart.cc
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
data_type & data
data
Definition: JPerth.cc:122
Data structure for set of track fit results.
Auxiliary class to define a range between two values.
General purpose class for object reading from a list of file names.
Utility class to parse command line options.
JFIT::JRegressorStorage< JFIT::JLine3Z, JFIT::JGandalf > JRegressorStorage_t
Definition: JPerth.cc:128
double t0
time offset [ns]
Definition: JPerth.cc:124
then if[[!-f $DETECTOR]] then JDetector sh $DETECTOR fi cat $WORKDIR trigger_parameters txt<< EOFtrigger3DMuon.enabled=1;trigger3DMuon.numberOfHits=5;trigger3DMuon.gridAngle_deg=1;ctMin=0.0;TMaxLocal_ns=15.0;EOF set_variable TRIGGEREFFICIENCY_TRIGGERED_EVENTS_ONLY INPUT_FILES=() for((i=1;$i<=$NUMBER_OF_RUNS;++i));do JSirene.sh $DETECTOR $JPP_DATA/genhen.km3net_wpd_V2_0.evt.gz $WORKDIR/sirene_ ${i}.root JTriggerEfficiency.sh $DETECTOR $DETECTOR $WORKDIR/sirene_ ${i}.root $WORKDIR/trigger_efficiency_ ${i}.root $WORKDIR/trigger_parameters.txt $JPP_DATA/PMT_parameters.txt INPUT_FILES+=($WORKDIR/trigger_efficiency_ ${i}.root) done for ANGLE_DEG in $ANGLES_DEG[*];do set_variable SIGMA_NS 3.0 set_variable OUTLIERS 3 set_variable OUTPUT_FILE $WORKDIR/matrix\[${ANGLE_DEG}\deg\].root $JPP_DIR/examples/JReconstruction-f"$INPUT_FILES[*]"-o $OUTPUT_FILE-S ${SIGMA_NS}-A ${ANGLE_DEG}-O ${OUTLIERS}-d ${DEBUG}--!fiif[[$OPTION=="plot"]];then if((0));then for H1 in h0 h1;do JPlot1D-f"$WORKDIR/matrix["${^ANGLES_DEG}" deg].root:${H1}"-y"1 2e3"-Y-L TR-T""-\^"number of events [a.u.]"-> o chi2
Definition: JMatrixNZ.sh:106
Data structure for measured coincidence rates of all pairs of PMTs in optical module.
Definition: JFitK40.hh:99
Data structure for fit of straight line paralel to z-axis.
Definition: JLine1Z.hh:27
void copy(const Head &from, JHead &to)
Copy header from from to to.
Definition: JHead.cc:162
size_t numberOfIterations
Definition: JGradient.hh:273
JPosition3D getPosition(const JFit &fit)
Get position.
Orientation of module.
const JLimit & getLimit() const
Get limit.
Definition: JLimit.hh:84
do set_variable DETECTOR_TXT $WORKDIR detector
const char * map
Definition: elog.cc:87
static const int NUMBER_OF_PMTS
Total number of PMTs in module.
Definition: JDAQ.hh:26
const std::vector< double > & getW() const
Get associated values.
Conjugate gradient fit.
Definition: JGradient.hh:73
JTOOLS::JRange< double > JZRange
Definition: JFit/JModel.hh:21
const double epsilon
Definition: JQuadrature.cc:21
int debug
debug level
double operator()(const int option) const
Get chi2.
Definition: JPerth.cc:256
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62