Jpp  18.1.0
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JSydney.cc
Go to the documentation of this file.
1 #include <string>
2 #include <iostream>
3 #include <iomanip>
4 #include <vector>
5 #include <set>
6 #include <algorithm>
7 #include <limits>
8 #include <sys/stat.h>
9 
10 #include <type_traits>
11 #include <functional>
12 #include <future>
13 #include <mutex>
14 #include <thread>
15 #include <vector>
16 #include <queue>
17 
18 #include "TROOT.h"
19 #include "TFile.h"
20 
21 #include "JLang/JPredicate.hh"
22 #include "JLang/JComparator.hh"
23 #include "JLang/JComparison.hh"
25 
26 #include "JSystem/JStat.hh"
27 
28 #include "JDetector/JDetector.hh"
30 #include "JDetector/JTripod.hh"
32 #include "JDetector/JModule.hh"
33 #include "JDetector/JHydrophone.hh"
35 
36 #include "JFit/JGradient.hh"
37 
38 #include "JTools/JHashMap.hh"
39 #include "JTools/JRange.hh"
40 #include "JTools/JQuantile.hh"
41 
43 
45 #include "JAcoustics/JEmitter.hh"
47 #include "JAcoustics/JHit.hh"
50 #include "JAcoustics/JEvent.hh"
51 #include "JAcoustics/JSuperEvt.hh"
53 #include "JAcoustics/JSupport.hh"
57 
58 #include "Jeep/JTimer.hh"
59 #include "Jeep/JeepToolkit.hh"
60 #include "Jeep/JContainer.hh"
61 #include "Jeep/JParser.hh"
62 #include "Jeep/JMessage.hh"
63 
64 
65 namespace JACOUSTICS {
66 
68  using JEEP::JContainer;
69  using JFIT::JParameter_t;
70 
71  using namespace JDETECTOR;
72 
77 
78 
79  static const std::string initialise_t = "initialise"; //!< initialise
80  static const std::string fix_t = "fix"; //!< fix objects
81  static const std::string string_t = "string"; //!< string
82  static const std::string tripod_t = "tripod"; //!< tripod
83  static const std::string stage_t = "stage"; //!< fit stage
84 
85 
86  /**
87  * Auxiliary data structure for handling file names.
88  */
89  struct JFilenames {
90  std::string detector; //!< detector
91  std::string tripod; //!< tripod
92  std::string hydrophone; //!< hydrophone
93  std::string transmitter; //!< transmitter
94  };
95 
96 
97  /**
98  * Auxiliary data structure for setup of complete system.
99  */
100  struct JSetup {
101  JDetector detector; //!< detector
103  struct :
104  public hydrophones_container
105  {
106  /**
107  * Check if there is a hydrophone on given string.
108  *
109  * \param id string identifier
110  * \return true if hydrophone present; else false
111  */
112  bool hasString(const int id) const
113  {
114  using namespace std;
115 
116  return (find_if(this->begin(), this->end(), make_predicate(&JHydrophone::getString, id)) != this->end());
117  }
118  } hydrophones; //!< hydrophones
120  };
121 
122 
123  /**
124  * Main class for pre-calibration using acoustics data.
125  */
126  struct JSydney {
127 
128  static constexpr double RADIUS_M = 1.0; //!< maximal horizontal distance between T-bar and emitter/hydrophone
129 
130  /**
131  * List of identifiers.
132  */
133  struct ids_t :
134  public std::set<int>
135  {
136  /**
137  * Default constructor.
138  */
140  {}
141 
142 
143  /**
144  * Copy constructor.
145  *
146  * \param buffer list of identifiers
147  */
148  ids_t(const std::vector<int>& buffer) :
149  std::set<int>(buffer.begin(), buffer.end())
150  {}
151 
152 
153  /**
154  * Difference constructor.
155  * Make list of all elements in A that are not in B.
156  *
157  * \param A list of identifiers
158  * \param B list of identifiers
159  */
160  ids_t(const ids_t& A,
161  const ids_t& B)
162  {
163  std::set_difference(A.begin(), A.end(), B.begin(), B.end(), std::inserter(*this, this->begin()));
164  }
165 
166 
167  /**
168  * Fix.
169  * Keep list of elements that are not in B.
170  *
171  * \param B list of identifiers
172  */
173  void fix(const ids_t& B)
174  {
175  ids_t A;
176 
177  this->swap(A);
178 
179  std::set_difference(A.begin(), A.end(), B.begin(), B.end(), std::inserter(*this, this->begin()));
180  }
181 
182 
183  /**
184  * Read identifiers from input stream
185  *
186  * \param in input stream
187  * \param object identifiers
188  * \return input stream
189  */
190  friend inline std::istream& operator>>(std::istream& in, ids_t& object)
191  {
192  for (int id; in >> id; ) {
193  object.insert(id);
194  }
195 
196  if (!in.bad()) {
197  in.clear();
198  }
199 
200  return in;
201  }
202 
203 
204  /**
205  * Write identifiers to output stream
206  *
207  * \param out output stream
208  * \param object identifiers
209  * \return output stream
210  */
211  friend inline std::ostream& operator<<(std::ostream& out, const ids_t& object)
212  {
213  for (const int id : object) {
214  out << ' ' << id;
215  }
216 
217  return out;
218  }
219  };
220 
221 
222  /**
223  * Auxiliary data structure for group of lists of identifiers of to-be-fitted objects.
224  */
225  struct fits_t {
226  /**
227  * Default constructor.
228  */
230  {}
231 
232 
233  /**
234  * Initialise.
235  *
236  * \param setup setup
237  */
238  void initialise(const JSetup& setup)
239  {
240  using namespace JPP;
241 
242  strings = make_array(setup.detector .begin(), setup.detector .end(), &JModule ::getString);
243  tripods = make_array(setup.tripods .begin(), setup.tripods .end(), &JTripod ::getID);
244  hydrophones = make_array(setup.hydrophones .begin(), setup.hydrophones .end(), &JHydrophone ::getString);
245  transmitters = make_array(setup.transmitters.begin(), setup.transmitters.end(), &JTransmitter::getString);
246  }
247 
248  ids_t strings; //!< strings
249  ids_t tripods; //!< tripods
250  ids_t hydrophones; //!< hydrophones
251  ids_t transmitters; //!< transmitters
252  };
253 
254 
255  /**
256  * Auxiliary class to edit (z) position of module.
257  */
258  struct JModuleEditor :
259  public JParameter_t
260  {
261  /**
262  * Constructor.
263  *
264  * \param module module
265  */
267  module(module)
268  {}
269 
270 
271  /**
272  * Apply step.
273  *
274  * \param step step
275  */
276  virtual void apply(const double step) override
277  {
278  using namespace JPP;
279 
280  module.add(JVector3Z_t * step);
281  }
282 
283  private:
285  };
286 
287 
288  /**
289  * Auxiliary class to edit (x,y,z) position of string.
290  */
291  struct JStringEditor :
292  public JParameter_t
293  {
294  /**
295  * Constructor.
296  *
297  * The option <tt>true</tt> and <tt>false</tt> correspond to all modules and optical modules only, respectively.
298  *
299  * \param setup setup
300  * \param id string number
301  * \param direction direction
302  * \param option option
303  */
304  JStringEditor(JSetup& setup, const int id, const JVector3D& direction, const bool option) :
305  detector (setup.detector),
306  direction(direction)
307  {
308  for (size_t i = 0; i != detector.size(); ++i) {
309  if (detector[i].getString() == id && (detector[i].getFloor() != 0 || option)) {
310  index.push_back(i);
311  }
312  }
313  }
314 
315 
316  /**
317  * Apply step.
318  *
319  * \param step step
320  */
321  virtual void apply(const double step) override
322  {
323  for (const auto i : index) {
324  detector[i].add(direction * step);
325  }
326  }
327 
328  private:
332  };
333 
334 
335  /**
336  * Auxiliary class to edit length of Dyneema ropes.
337  */
338  struct JDyneemaEditor :
339  public JParameter_t
340  {
341  /**
342  * Constructor.
343  *
344  * \param setup setup
345  * \param id string number
346  * \param z0 reference position
347  */
348  JDyneemaEditor(JSetup& setup, const int id, const double z0 = 0.0) :
349  detector (setup.detector),
350  z0 (z0)
351  {
352  for (size_t i = 0; i != detector.size(); ++i) {
353  if (detector[i].getString() == id && detector[i].getFloor() != 0) {
354  index.push_back(i);
355  }
356  }
357  }
358 
359 
360  /**
361  * Apply step.
362  *
363  * \param step step
364  */
365  virtual void apply(const double step) override
366  {
367  for (const auto i : index) {
368 
369  JModule& module = detector[i];
370 
371  if (step > 0.0)
372  module.set(JVector3D(module.getX(), module.getY(), z0 + (module.getZ() - z0) * (1.0 + step)));
373  else if (step < 0.0)
374  module.set(JVector3D(module.getX(), module.getY(), z0 + (module.getZ() - z0) / (1.0 - step)));
375  }
376  }
377 
378  private:
380  double z0;
382  };
383 
384 
385  /**
386  * Auxiliary class to edit (x,y,z) position of tripod.
387  */
388  struct JTripodEditor :
389  public JParameter_t
390  {
391  /**
392  * Constructor.
393  *
394  * \param setup setup
395  * \param id tripod identifier
396  * \param direction direction
397  */
398  JTripodEditor(JSetup& setup, const int id, const JVector3D& direction) :
399  tripods (setup.tripods),
400  direction(direction)
401  {
402  using namespace std;
403  using namespace JPP;
404 
405  index = distance(tripods.begin(), find_if(tripods.begin(), tripods.end(), make_predicate(&JTripod::getID, id)));
406  }
407 
408 
409  /**
410  * Apply step.
411  *
412  * \param step step
413  */
414  virtual void apply(const double step) override
415  {
416  tripods[index].add(direction * step);
417  }
418 
419  private:
422  size_t index;
423  };
424 
425 
426  /**
427  * Auxiliary class to edit rotation of anchor.
428  */
429  struct JAnchorEditor :
430  public JParameter_t
431  {
432  /**
433  * Constructor.
434  *
435  * \param setup setup
436  * \param id string identifier
437  */
438  JAnchorEditor(JSetup& setup, const int id) :
439  hydrophones (setup.hydrophones),
440  transmitters(setup.transmitters)
441  {
442  using namespace std;
443  using namespace JPP;
444 
445  index[0] = distance(hydrophones .begin(), find_if(hydrophones .begin(), hydrophones .end(), make_predicate(&JHydrophone ::getString, id)));
446  index[1] = distance(transmitters.begin(), find_if(transmitters.begin(), transmitters.end(), make_predicate(&JTransmitter::getString, id)));
447  }
448 
449 
450  /**
451  * Apply step.
452  *
453  * \param step step
454  */
455  virtual void apply(const double step) override
456  {
457  using namespace JPP;
458 
459  const JRotation3Z R(step);
460 
461  if (index[0] != hydrophones .size()) { hydrophones [index[0]].rotate(R); }
462  if (index[1] != transmitters.size()) { transmitters[index[1]].rotate(R); }
463  }
464 
465  private:
468  size_t index[2];
469  };
470 
471 
472  /**
473  * Extended data structure for parameters of stage.
474  */
475  struct JParameters_t :
476  public JFitParameters
477  {
478  /**
479  * Default constuctor.
480  */
482  Nmax (std::numeric_limits<size_t>::max()),
483  Nextra (0),
484  epsilon(1.0e-4),
485  debug (3)
486  {}
487 
488 
489  /**
490  * Read parameters from input stream
491  *
492  * \param in input stream
493  * \param object parameters
494  * \return input stream
495  */
496  friend inline std::istream& operator>>(std::istream& in, JParameters_t& object)
497  {
498  object = JParameters_t();
499 
500  in >> object.option
501  >> object.mestimator
502  >> object.sigma_s
503  >> object.stdev
504  >> object.Nextra;
505 
506  if (in) {
507 
508  for (double value; in >> value; ) {
509  object.steps.push_back(value);
510  }
511 
512  if (!in.bad()) {
513  in.clear();
514  }
515  }
516 
517  return in;
518  }
519 
520 
521  /**
522  * Write parameters to output stream
523  *
524  * \param out output stream
525  * \param object parameters
526  * \return output stream
527  */
528  friend inline std::ostream& operator<<(std::ostream& out, const JParameters_t& object)
529  {
530  using namespace std;
531 
532  out << setw(2) << object.option << ' '
533  << setw(2) << object.mestimator << ' '
534  << SCIENTIFIC(9,3) << object.sigma_s << ' '
535  << SCIENTIFIC(9,3) << object.stdev << ' '
536  << setw(3) << object.Nextra;
537 
538  for (const double value : object.steps) {
539  out << ' ' << FIXED(9,5) << value;
540  }
541 
542  return out;
543  }
544 
545  size_t Nmax;
546  size_t Nextra;
547  double epsilon;
548  int debug;
550  };
551 
552 
553  /**
554  * Constructor.
555  *
556  * \param filenames file names
557  * \param V sound velocity
558  * \param jobs jobs
559  * \param debug debug
560  */
561  JSydney(const JFilenames& filenames,
562  const JSoundVelocity& V,
563  const size_t jobs,
564  const int debug) :
565  filenames(filenames),
566  V(V),
567  jobs(jobs),
568  debug(debug)
569  {
570  load(filenames.detector, setup.detector);
571 
572  setup.tripods.load(filenames.tripod.c_str());
573 
574  if (filenames.hydrophone != "") { setup.hydrophones .load(filenames.hydrophone .c_str()); }
575  if (filenames.transmitter != "") { setup.transmitters.load(filenames.transmitter.c_str()); }
576 
577  for (JDetector::const_iterator i = setup.detector.begin(); i != setup.detector.end(); ++i) {
578  receivers[i->getID()] = i->getLocation();
579  }
580 
581  // detach PMTs
582 
583  detector = setup.detector;
584 
585  for (JDetector::iterator module = setup.detector.begin(); module != setup.detector.end(); ++module) {
586  module->clear();
587  }
588 
589  router.reset(new JLocationRouter(setup.detector));
590 
591  fits.initialise(setup);
592 
593  this->V.set(setup.detector.getUTMZ()); // sound velocity at detector depth
594 
597 
599 
600  ROOT::EnableThreadSafety();
601  }
602 
603 
604  /**
605  * Fit procedure to determine the positions of tripods using strings that are fixed.
606  *
607  * \param parameters parameters
608  */
610  {
611  using namespace std;
612  using namespace JPP;
613 
614  this->parameters = parameters;
615 
616  JDetector buffer[2];
617 
618  for (JDetector::iterator module = setup.detector.begin(); module != setup.detector.end(); ++module) {
619 
620  if (fits.strings.count(module->getString()) != 0)
621  buffer[0].push_back(*module); // new strings
622  else
623  buffer[1].push_back(*module); // old strings
624  }
625 
626  setup.detector.swap(buffer[1]);
627 
628  JGradient fit(parameters.Nmax, parameters.Nextra, parameters.epsilon, parameters.debug);
629 
630  for (const int i : fits.tripods) {
631  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "tripod.x: " << RIGHT(4) << i), new JTripodEditor(setup, i, JVector3X_t), parameters.steps[0]));
632  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "tripod.y: " << RIGHT(4) << i), new JTripodEditor(setup, i, JVector3Y_t), parameters.steps[0]));
633  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "tripod.z: " << RIGHT(4) << i), new JTripodEditor(setup, i, JVector3Z_t), parameters.steps[0]));
634  }
635 
636  const double chi2 = fit(*this);
637 
638  copy(buffer[0].begin(), buffer[0].end(), back_inserter(setup.detector));
639 
640  STATUS("detector: " << FIXED(9,4) << chi2 << endl);
641  }
642 
643 
644  /**
645  * Fit procedure to determine the positions of the strings and tripods.
646  *
647  * \param parameters parameters
648  */
650  {
651  using namespace std;
652  using namespace JPP;
653 
654  this->parameters = parameters;
655 
656  JGradient fit(parameters.Nmax, parameters.Nextra, parameters.epsilon, parameters.debug);
657 
658  for (const int i : fits.strings) {
659  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "string.x: " << RIGHT(4) << i), new JStringEditor(setup, i, JVector3X_t, true), parameters.steps[0]));
660  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "string.y: " << RIGHT(4) << i), new JStringEditor(setup, i, JVector3Y_t, true), parameters.steps[0]));
661  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "string.z: " << RIGHT(4) << i), new JStringEditor(setup, i, JVector3Z_t, false), parameters.steps[0]));
662  }
663 
664  for (const int i : fits.tripods) {
665  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "tripod.x: " << RIGHT(4) << i), new JTripodEditor(setup, i, JVector3X_t), parameters.steps[1]));
666  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "tripod.y: " << RIGHT(4) << i), new JTripodEditor(setup, i, JVector3Y_t), parameters.steps[1]));
667  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "tripod.z: " << RIGHT(4) << i), new JTripodEditor(setup, i, JVector3Z_t), parameters.steps[1]));
668  }
669 
670  for (const int i : ids_t(fits.hydrophones, fits.transmitters)) {
671  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "anchor.R: " << RIGHT(4) << i), new JAnchorEditor(setup, i), parameters.steps[0] / RADIUS_M));
672  }
673 
674  for (const int i : fits.transmitters) {
675 
676  JModule& module = setup.detector.getModule(router->getAddress(JLocation(i,0)));
677 
678  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "anchor.R: " << RIGHT(4) << i), new JAnchorEditor(setup, i), parameters.steps[0] / RADIUS_M));
679  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "anchor.z: " << RIGHT(4) << i), new JModuleEditor(module), parameters.steps[0]));
680  }
681 
682  const double chi2 = fit(*this);
683 
684  STATUS("detector: " << FIXED(9,4) << chi2 << endl);
685  }
686 
687 
688  /**
689  * Fit procedure to determine the stretching and z-positions of individual strings.
690  *
691  * \param parameters parameters
692  */
694  {
695  using namespace std;
696  using namespace JPP;
697 
698  this->parameters = parameters;
699 
700  map<int, JDetector> buffer;
701 
702  double z0 = 0.0;
703 
704  for (JDetector::iterator module = setup.detector.begin(); module != setup.detector.end(); ++module) {
705 
706  buffer[module->getString()].push_back(*module);
707 
708  if (module->getZ() > z0) {
709  z0 = module->getZ();
710  }
711  }
712 
713  setup.detector.clear();
714 
715  for (const int i : fits.strings) {
716 
717  setup.detector.swap(buffer[i]);
718 
719  router.reset(new JLocationRouter(setup.detector));
720 
721  JGradient fit(parameters.Nmax, parameters.Nextra, parameters.epsilon, parameters.debug);
722 
723  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "string.M: " << RIGHT(4) << i), new JDyneemaEditor(setup, i, z0), parameters.steps[0]));
724  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "string.z: " << RIGHT(4) << i), new JStringEditor (setup, i, JVector3Z_t, false), parameters.steps[1]));
725 
726  const double chi2 = fit(*this);
727 
728  STATUS("string: " << setw(4) << i << ' ' << FIXED(9,4) << chi2 << endl);
729 
730  setup.detector.swap(buffer[i]);
731  }
732 
733  setup.detector.clear();
734 
735  for (const auto& detector : buffer) {
736  copy(detector.second.begin(), detector.second.end(), back_inserter(setup.detector));
737  }
738 
739  router.reset(new JLocationRouter(setup.detector));
740  }
741 
742 
743  /**
744  * Fit procedure to determine the z-positions of the modules.
745  *
746  * \param parameters parameters
747  */
749  {
750  using namespace std;
751  using namespace JPP;
752 
753  this->parameters = parameters;
754 
755  JGradient fit(parameters.Nmax, parameters.Nextra, parameters.epsilon, parameters.debug);
756 
757  for (JDetector::iterator module = setup.detector.begin(); module != setup.detector.end(); ++module) {
758  if (fits.strings.count(module->getString()) != 0 && module->getFloor() != 0) {
759  fit.push_back(JModifier_t(MAKE_STRING(LEFT(12) << "module.z: " << right << module->getLocation()), new JModuleEditor(*module), parameters.steps[0]));
760  }
761  }
762 
763  const double chi2 = fit(*this);
764 
765  STATUS("detector: " << FIXED(9,4) << chi2 << endl);
766  }
767 
768 
769  /**
770  * Get chi2.
771  *
772  * \param option option
773  * \return chi2/NDF
774  */
775  double operator()(const int option) const
776  {
777  using namespace std;
778  using namespace JPP;
779 
780  const JGeometry geometry(setup.detector, setup.hydrophones);
781 
782  JHashMap<int, JEmitter> emitters;
783 
784  for (tripods_container::const_iterator i = setup.tripods.begin(); i != setup.tripods.end(); ++i) {
785  {
786  emitters[i->getID()] = JEmitter(i->getID(), i->getUTMPosition() - setup.detector.getUTMPosition());
787  }
788  }
789 
790  for (transmitters_container::const_iterator i = setup.transmitters.begin(); i != setup.transmitters.end(); ++i) {
791  try {
792  emitters[i->getID()] = JEmitter(i->getID(), i->getPosition() + router->getModule(i->getLocation()).getPosition());
793  }
794  catch(const exception&) {} // if no module available, discard transmitter
795  }
796 
797  if (option == 0 || // step wise improvement of the chi2
798  option == 1) { // evaluation of the chi2 before the determination of the gradient of the chi2
799 
800  JSTDObjectWriter<JSuperEvt> out(this->odat); // storage of data for subsequent use
801 
802  this->odat.clear();
803 
804  JFremantle::output = (option == 1 ? &out : NULL);
805 
806  {
807  JFremantle fremantle(geometry, V, parameters, jobs);
808 
809  for (idat_type::const_iterator superevt = idat.begin(); superevt != idat.end(); ++superevt) {
810 
811  const JWeight getWeight(superevt->begin(), superevt->end());
812 
813  set<int> counter;
815 
816  for (ievt_type::const_iterator evt = superevt->begin(); evt != superevt->end(); ++evt) {
817 
818  const JEmitter& emitter = emitters [evt->getID()];
819  const double weight = getWeight(evt->getID());
820 
821  for (JEvent::const_iterator i = evt->begin(); i != evt->end(); ++i) {
822 
823  if (geometry.hasLocation(receivers[i->getID()])) {
824 
825  data.push_back(JHit(emitter,
826  distance(superevt->begin(), evt),
827  receivers[i->getID()],
828  i->getToA(),
829  parameters.sigma_s,
830  weight));
831 
832  counter.insert(evt->getID());
833  }
834  }
835  }
836 
837  if (counter.size() >= parameters.Nmin) {
838  fremantle.enqueue(data);
839  }
840  }
841  }
842 
843  return JFremantle::Q.getMean(numeric_limits<float>::max());
844 
845  } else if (option == 2) { // evaluation of the derivative of the chi2 to each fit parameter
846 
847  {
848  JPlatypus platypus(geometry, emitters, V, parameters, jobs);
849 
850  for (odat_type::const_iterator superevt = odat.begin(); superevt != odat.end(); ++superevt) {
851  platypus.enqueue(*superevt);
852  }
853  }
854 
855  return JPlatypus::Q.getMean(numeric_limits<float>::max());
856 
857  } else {
858 
859  return numeric_limits<float>::max();
860  }
861  }
862 
863 
864  /**
865  * Run.
866  *
867  * \param script steering script
868  */
869  void run(const std::string& script)
870  {
871  using namespace std;
872  using namespace JPP;
873 
874  ifstream in(script.c_str());
875 
876  while (in) {
877 
878  string key, value;
879 
880  if (in >> key) {
881 
882  if (key == initialise_t) { // set object identifiers
883 
884  fits.initialise(setup);
885 
886  } else if (key == fix_t) { // fix object identifiers
887 
888  getline(in, value);
889 
890  istringstream is(value);
891 
892  string type; // type of object
893  ids_t id; // identifiers
894 
895  if (is >> type >> id) {
896  if (type == string_t) {
897  fits.strings .fix(id);
898  fits.hydrophones .fix(id);
899  fits.transmitters.fix(id);
900  } else if (type == tripod_t) {
901  fits.tripods .fix(id);
902  } else {
903  THROW(JValueOutOfRange, "Invalid type <" << type << ">");
904  }
905  }
906 
907  } else if (key == stage_t) { // stage
908 
909  getline(in, value);
910 
911  istringstream is(value);
912 
913  string stage;
914  JParameters_t input;
915 
916  if (is >> stage >> input) {
917 
918  STATUS("stage " << setw(3) << stage << " {" << input << "}" << endl);
919 
920  JTimer timer;
921 
922  timer.start();
923 
924  ofstream out(MAKE_CSTRING("stage-" << stage << ".log"));
925 
926  {
927  JRedirectStream redirect(cout, out);
928 
929  switch (stage[stage.size() - 1]) {
930 
931  case '0':
932  stage_0(input);
933  break;
934 
935  case 'a':
936  case 'A':
937  stage_a(input);
938  break;
939 
940  case 'b':
941  case 'B':
942  stage_b(input);
943  break;
944 
945  case 'c':
946  case 'C':
947  stage_c(input);
948  break;
949 
950  default:
951  THROW(JValueOutOfRange, "Invalid stage <" << stage << ">");
952  break;
953  }
954  }
955 
956  out.close();
957 
958  store(stage);
959  store();
960 
961  timer.stop();
962 
963  STATUS("Elapsed time " << FIXED(12,3) << timer.usec_wall * 1.0e-6 << " s." << endl);
964  }
965 
966  } else {
967  THROW(JValueOutOfRange, "Invalid key <" << key << ">");
968  }
969  }
970  }
971 
972  in.close();
973  }
974 
975 
976  /**
977  * Store data in given directory.
978  *
979  * \param dir directory
980  */
981  void store(const std::string& dir = ".")
982  {
983  using namespace JPP;
984 
985  if (getFileStatus(dir.c_str()) || (mkdir(dir.c_str(), S_IRWXU | S_IRWXG) != -1)) {
986 
987  // attach PMTs
988 
989  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
990  module->set(router->getModule(module->getLocation()).getPosition());
991  }
992 
993  JDETECTOR::store(getFilename(dir, filenames.detector), detector);
994 
995  setup.tripods.store(getFilename(dir, filenames.tripod).c_str());
996 
997  if (filenames.hydrophone != "") { setup.hydrophones .store(getFilename(dir, filenames.hydrophone) .c_str()); }
998  if (filenames.transmitter != "") { setup.transmitters.store(getFilename(dir, filenames.transmitter).c_str()); }
999 
1000  } else {
1001 
1002  THROW(JValueOutOfRange, "Invalid directory <" << dir << ">");
1003  }
1004  }
1005 
1006 
1009  size_t jobs;
1010  int debug;
1013 
1015  std::unique_ptr<JLocationRouter> router;
1016 
1019 
1020  idat_type idat;
1021 
1022  private:
1024  mutable odat_type odat;
1025 
1026  JDetector detector; //!< PMTs
1028  };
1029 }
1030 
1031 
1032 /**
1033  * \file
1034  *
1035  * Application to perform acoustic pre-calibration.
1036  * \author mdejong
1037  */
1038 int main(int argc, char **argv)
1039 {
1040  using namespace std;
1041  using namespace JPP;
1042 
1043  JMultipleFileScanner<JEvent> inputFile;
1044  JLimit_t& numberOfEvents = inputFile.getLimit();
1045  JFilenames filenames; // file names
1046  JFitParameters parameters; // fit parameters
1047  string script; // script file
1048  JSoundVelocity V = getSoundVelocity; // default sound velocity
1049  disable_container disable; // disable tansmissions
1050  size_t jobs; // number of parallel jobs
1051  int debug;
1052 
1053  try {
1054 
1055  JParser<> zap("Application to perform acoustic pre-calibration.");
1056 
1057  zap['f'] = make_field(inputFile, "output of JAcousticEventBuilder[.sh]");
1058  zap['n'] = make_field(numberOfEvents) = JLimit::max();
1059  zap['a'] = make_field(filenames.detector);
1060  zap['@'] = make_field(parameters) = JPARSER::initialised();
1061  zap['s'] = make_field(script, "steering script");
1062  zap['V'] = make_field(V, "sound velocity") = JPARSER::initialised();
1063  zap['T'] = make_field(filenames.tripod, "tripod file");
1064  zap['Y'] = make_field(filenames.transmitter, "transmitter file") = JPARSER::initialised();
1065  zap['H'] = make_field(filenames.hydrophone, "hydrophone file") = JPARSER::initialised();
1066  zap['M'] = make_field(getMechanics, "mechanics data") = JPARSER::initialised();
1067  zap['!'] = make_field(disable, "disable transmission") = JPARSER::initialised();
1068  zap['N'] = make_field(jobs, "number of parallel jobs") = 1;
1069  zap['d'] = make_field(debug) = 1;
1070 
1071  zap(argc, argv);
1072  }
1073  catch(const exception &error) {
1074  FATAL(error.what() << endl);
1075  }
1076 
1077  if (jobs == 0) {
1078  FATAL("Invalid number of jobs " << jobs << endl);
1079  }
1080 
1081  JSydney sydney(filenames, V, jobs, debug);
1082 
1083  set<int> receivers;
1084  set<int> emitters;
1085 
1086  for (JDetector::const_iterator i = sydney.setup.detector .begin(); i != sydney.setup.detector .end(); ++i) {
1087  if (i->getFloor() != 0 || sydney.setup.hydrophones.hasString(i->getString())) {
1088  receivers.insert(i->getID());
1089  }
1090  }
1091 
1092  for (tripods_container::const_iterator i = sydney.setup.tripods .begin(); i != sydney.setup.tripods .end(); ++i) {
1093  {
1094  emitters.insert(i->getID());
1095  }
1096  }
1097 
1098  for (transmitters_container::const_iterator i = sydney.setup.transmitters.begin(); i != sydney.setup.transmitters.end(); ++i) {
1099  if (sydney.setup.detector.hasModule(i->getLocation())) {
1100  emitters.insert(i->getID());
1101  }
1102  }
1103 
1104  typedef vector<JEvent> buffer_type;
1105 
1106  buffer_type zbuf;
1107 
1108  while (inputFile.hasNext()) {
1109 
1110  const JEvent* evt = inputFile.next();
1111 
1112  if (emitters.count(evt->getID())) {
1113  zbuf.push_back(*evt);
1114  }
1115  }
1116 
1117  const JRange<double> unit(0.0, 1.0);
1118 
1119  sort(zbuf.begin(), zbuf.end()); // sort according first time-of-emission
1120 
1121  for (buffer_type::iterator p = zbuf.begin(), q; p != zbuf.end(); p = q) {
1122 
1123  for (q = p; ++q != zbuf.end() && q->begin()->getToE() <= p->rbegin()->getToE() + parameters.Tmax_s; ) {}
1124 
1125  JEvent::overlap(p, q, parameters.deadTime_s); // empty overlapping events
1126 
1127  JSydney::ievt_type buffer;
1128 
1129  for (buffer_type::iterator evt = p; evt != q; ++evt) {
1130 
1131  sort(evt->begin(), evt->end(), JKatoomba<>::compare);
1132 
1133  JEvent::iterator __end = unique(evt->begin(), evt->end(), make_comparator(&JTransmission::getID, JComparison::eq()));
1134 
1135  for (JEvent::iterator i = evt->begin(); i != __end; ) {
1136 
1137  if (disable.count(JTransmission_t(evt->getID(), i->getID())) == 0 &&
1138  disable.count(JTransmission_t(-1, i->getID())) == 0) {
1139 
1140  if (receivers.count(i->getID()) && i->getQ() >= parameters.Qmin * (unit(parameters.Qmin) ? i->getW() : 1.0)) {
1141  ++i; continue;
1142  }
1143  }
1144 
1145  iter_swap(i, --__end);
1146  }
1147 
1148  buffer.push_back(JEvent(evt->getOID(), buffer.size(), evt->getID(), evt->begin(), __end));
1149  }
1150 
1151  if (getNumberOfEmitters(buffer.begin(), buffer.end()) >= parameters.Nmin) {
1152  sydney.idat.push_back(buffer);
1153  }
1154  }
1155 
1156  sydney.run(script);
1157 }
void initialise(const JSetup &setup)
Initialise.
Definition: JSydney.cc:238
std::vector< ievt_type > idat_type
Definition: JSydney.cc:1018
ids_t(const std::vector< int > &buffer)
Copy constructor.
Definition: JSydney.cc:148
Auxiliary class to edit length of Dyneema ropes.
Definition: JSydney.cc:338
JDetector detector
PMTs.
Definition: JSydney.cc:1026
Utility class to parse command line options.
Definition: JParser.hh:1514
Acoustic hit.
JSydney(const JFilenames &filenames, const JSoundVelocity &V, const size_t jobs, const int debug)
Constructor.
Definition: JSydney.cc:561
std::vector< JHydrophone > & hydrophones
Definition: JSydney.cc:466
JDetector detector
detector
Definition: JSydney.cc:101
friend std::ostream & operator<<(std::ostream &out, const JParameters_t &object)
Write parameters to output stream.
Definition: JSydney.cc:528
JPredicate< JResult_t T::*, JComparison::eq > make_predicate(JResult_t T::*member, const JResult_t value)
Helper method to create predicate for data member.
Definition: JPredicate.hh:128
int main(int argc, char *argv[])
Definition: Main.cc:15
void stage_b(const JParameters_t &parameters)
Fit procedure to determine the stretching and z-positions of individual strings.
Definition: JSydney.cc:693
void stage_a(const JParameters_t &parameters)
Fit procedure to determine the positions of the strings and tripods.
Definition: JSydney.cc:649
$WORKDIR stage
friend std::istream & operator>>(std::istream &in, ids_t &object)
Read identifiers from input stream.
Definition: JSydney.cc:190
JComparator< JResult_t T::*, JComparison::lt > make_comparator(JResult_t T::*member)
Helper method to create comparator between values of data member.
double getWeight(T __begin, T __end)
Get total weight of data points.
Definition: JKatoomba_t.hh:59
static const std::string fix_t
fix objects
Definition: JSydney.cc:80
Sound velocity.
Data structure for a composite optical module.
Definition: JModule.hh:68
JContainer< std::vector< JTransmitter > > transmitters_container
Definition: JSydney.cc:74
double operator()(const int option) const
Get chi2.
Definition: JSydney.cc:775
static JDetectorMechanics getMechanics
Function object to get string mechanics.
Definition: JMechanics.hh:242
std::string detector
detector
Definition: JSydney.cc:90
bool hasModule(const JLocation &location) const
Check availability of module parameters.
Definition: JDetector.hh:294
virtual void apply(const double step) override
Apply step.
Definition: JSydney.cc:321
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
JVector3D getPosition(T __begin, T __end, const JPredicate< JTypename_t, JComparator_t > &predicate)
Get position from element in data which corresponds to given predicate.
General purpose class for hash map of unique keys.
Definition: JHashMap.hh:72
Auxiliary data structure to unify weights of acoustics data according to the number of pings per emit...
General purpose class for hash map of unique elements.
std::vector< JEvent > ievt_type
Definition: JSydney.cc:1017
#define STATUS(A)
Definition: JMessage.hh:63
ROOT TTree parameter settings.
Detector data structure.
Definition: JDetector.hh:89
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:712
virtual void apply(const double step) override
Apply step.
Definition: JSydney.cc:414
Auxiliary data structure for setup of complete system.
Definition: JSydney.cc:100
*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
#define MAKE_CSTRING(A)
Make C-string.
Definition: JPrint.hh:136
Acoustic event.
void run(const std::string &script)
Run.
Definition: JSydney.cc:869
then fatal Number of tripods
Definition: JFootprint.sh:45
tripods_container tripods
tripods
Definition: JSydney.cc:102
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:83
then usage $script< detector specific pre-calibration script >< option > nAuxiliary script to make scan of pre stretching of detector strings(see JEditDetector)." "\nPossible options
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:446
Auxiliary data structure for handling file names.
Definition: JSydney.cc:89
Extended data structure for parameters of stage.
Definition: JSydney.cc:475
transmitters_container transmitters
transmitters
Definition: JSydney.cc:119
V(JDAQEvent-JTriggerReprocessor)*1.0/(JDAQEvent+1.0e-10)
Acoustic emitter.
is
Definition: JDAQCHSM.chsm:167
ids_t(const ids_t &A, const ids_t &B)
Difference constructor.
Definition: JSydney.cc:160
Data structure for detector geometry and calibration.
void stop()
Stop timer.
Definition: JTimer.hh:113
double getMean() const
Get mean value.
Definition: JQuantile.hh:252
JMODEL::JString getString(const JFit &fit)
Get model parameters of string.
Acoustics hit.
static const JVector3D JVector3X_t(1, 0, 0)
unit x-vector
Data structure for hydrophone.
static const std::string stage_t
fit stage
Definition: JSydney.cc:83
size_t getNumberOfEmitters(T __begin, T __end)
Get number of emitters.
Auxiliary class to edit (x,y,z) position of string.
Definition: JSydney.cc:291
#define MAKE_STRING(A)
Make string.
Definition: JPrint.hh:127
Direct access to location in detector data structure.
static const std::string tripod_t
tripod
Definition: JSydney.cc:82
Rotation around Z-axis.
Definition: JRotation3D.hh:85
hydrophones
hydrophones
Acoustic super event fit toolkit.
Implementation of object output from STD container.
Acoustic fit parameters.
List of identifiers.
Definition: JSydney.cc:133
std::vector< double > steps
Definition: JSydney.cc:549
JFIT::JEvent JEvent
Definition: JHistory.hh:353
Auxiliary class for defining the range of iterations of objects.
Definition: JLimit.hh:41
static const JSoundVelocity getSoundVelocity(1541.0,-17.0e-3,-2000.0)
Function object for velocity of sound.
std::string hydrophone
hydrophone
Definition: JSydney.cc:92
void store(const std::string &dir=".")
Store data in given directory.
Definition: JSydney.cc:981
JParameters_t()
Default constuctor.
Definition: JSydney.cc:481
JModuleEditor(JModule &module)
Constructor.
Definition: JSydney.cc:266
Auxiliary class to edit (z) position of module.
Definition: JSydney.cc:258
Detector file.
Definition: JHead.hh:226
This class can be used to temporarily redirect one output (input) stream to another output (input) st...
JContainer< std::vector< JHydrophone > > hydrophones_container
Definition: JSydney.cc:75
void fix(const ids_t &B)
Fix.
Definition: JSydney.cc:173
Data structure for vector in three dimensions.
Definition: JVector3D.hh:34
Router for direct addressing of location data in detector data structure.
Data structure for transmitter.
JFilenames filenames
Definition: JSydney.cc:1007
Acoustic emitter.
Definition: JEmitter.hh:27
Logical location of module.
Definition: JLocation.hh:37
Acoustics toolkit.
JSoundVelocity V
Definition: JSydney.cc:1008
Auxiliary wrapper for I/O of container with optional comment (see JComment).
Definition: JContainer.hh:39
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1989
JContainer< std::set< JTransmission_t > > disable_container
Definition: JSydney.cc:76
ids_t()
Default constructor.
Definition: JSydney.cc:139
Acoustic event fit.
const array_type< JValue_t > & make_array(const JValue_t(&array)[N])
Method to create array of values.
Definition: JVectorize.hh:54
Auxiliary methods for handling file names, type names and environment.
int getID() const
Get identifier.
Definition: JObjectID.hh:50
ids_t transmitters
transmitters
Definition: JSydney.cc:251
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file.
Auxiliary class for CPU timing and usage.
Definition: JTimer.hh:32
then awk string
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition: JString.hh:478
static JTOOLS::JQuantile Q
chi2/NDF
Definition: JPlatypus_t.hh:171
Auxiliary data structure for fit parameter.
Definition: JGradient.hh:28
double getY() const
Get y position.
Definition: JVector3D.hh:104
Auxiliary class to edit rotation of anchor.
Definition: JSydney.cc:429
JContainer< std::vector< JTripod > > tripods_container
Definition: JSydney.cc:73
General purpose messaging.
virtual void apply(const double step) override
Apply step.
Definition: JSydney.cc:365
JDyneemaEditor(JSetup &setup, const int id, const double z0=0.0)
Constructor.
Definition: JSydney.cc:348
Implementation for depth dependend velocity of sound.
#define FATAL(A)
Definition: JMessage.hh:67
Scanning of objects from multiple files according a format that follows from the extension of each fi...
static JStat getFileStatus
Function object for file status.
Definition: JStat.hh:173
void enqueue(data_type &data)
Queue data.
Auxiliary data structure for editable parameter.
Definition: JGradient.hh:47
fits_t()
Default constructor.
Definition: JSydney.cc:229
virtual void apply(const double step) override
Apply step.
Definition: JSydney.cc:455
Thread pool for global fits.
Definition: JPlatypus_t.hh:34
then JCookie sh JDataQuality D $DETECTOR_ID R
Definition: JDataQuality.sh:41
static void overlap(T p, T q, const double Tmax_s)
Empty overlapping events.
int getString() const
Get string number.
Definition: JLocation.hh:134
std::vector< JTransmitter > & transmitters
Definition: JSydney.cc:467
friend std::ostream & operator<<(std::ostream &out, const ids_t &object)
Write identifiers to output stream.
Definition: JSydney.cc:211
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
detector()
Default constructor.
Definition: JHead.hh:231
void stage_c(const JParameters_t &parameters)
Fit procedure to determine the z-positions of the modules.
Definition: JSydney.cc:748
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.
Main class for pre-calibration using acoustics data.
Definition: JSydney.cc:126
static output_type * output
optional output
JFitParameters parameters
Definition: JSydney.cc:1027
Acoustic transmission identifier.
JTOOLS::JHashMap< int, JLocation > receivers
Definition: JSydney.cc:1014
Fit functions of acoustic model.
ids_t hydrophones
hydrophones
Definition: JSydney.cc:250
static const JVector3D JVector3Z_t(0, 0, 1)
unit z-vector
JAnchorEditor(JSetup &setup, const int id)
Constructor.
Definition: JSydney.cc:438
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
Thread pool for global fits.
Definition: JFremantle_t.hh:34
int getID() const
Get identifier.
static JTOOLS::JQuantile Q
chi2/NDF
double getX() const
Get x position.
Definition: JVector3D.hh:94
std::string tripod
tripod
Definition: JSydney.cc:91
void copy(const Head &from, JHead &to)
Copy header from from to to.
Definition: JHead.cc:162
bool hasLocation(const JLocation &location) const
Check if this detector has given location.
Definition: JGeometry.hh:561
Acoustic event.
std::string getFilename(const std::string &file_name)
Get file name part, i.e. part after last JEEP::PATHNAME_SEPARATOR if any.
Definition: JeepToolkit.hh:128
std::vector< size_t > index
Definition: JSydney.cc:381
JTripodEditor(JSetup &setup, const int id, const JVector3D &direction)
Constructor.
Definition: JSydney.cc:398
std::vector< size_t > index
Definition: JSydney.cc:331
JStringEditor(JSetup &setup, const int id, const JVector3D &direction, const bool option)
Constructor.
Definition: JSydney.cc:304
const JLimit & getLimit() const
Get limit.
Definition: JLimit.hh:84
static const std::string initialise_t
initialise
Definition: JSydney.cc:79
Exception for accessing a value in a collection that is outside of its range.
Definition: JException.hh:178
Auxiliary data structure for group of lists of identifiers of to-be-fitted objects.
Definition: JSydney.cc:225
virtual void apply(const double step) override
Apply step.
Definition: JSydney.cc:276
int getID() const
Get emitter identifier.
static const JVector3D JVector3Y_t(0, 1, 0)
unit y-vector
std::string transmitter
transmitter
Definition: JSydney.cc:93
Data structure for tripod.
std::vector< JSuperEvt > odat_type
Definition: JSydney.cc:1023
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
Definition: JCanberra.sh:46
Conjugate gradient fit.
Definition: JGradient.hh:73
source $JPP_DIR setenv csh $JPP_DIR &dev null eval JShellParser o a A
Acoustic transmission identifier.
JSoundVelocity & set(const double z0)
Set depth.
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:484
void enqueue(const JSuperEvt &evt)
Queue super event.
Definition: JPlatypus_t.hh:154
JModule & set(const JVector3D &pos)
Set position.
Definition: JModule.hh:408
friend std::istream & operator>>(std::istream &in, JParameters_t &object)
Read parameters from input stream.
Definition: JSydney.cc:496
script
Definition: JAcoustics.sh:2
double getZ() const
Get z position.
Definition: JVector3D.hh:115
std::unique_ptr< JLocationRouter > router
Definition: JSydney.cc:1015
const double epsilon
Definition: JQuadrature.cc:21
void stage_0(const JParameters_t &parameters)
Fit procedure to determine the positions of tripods using strings that are fixed. ...
Definition: JSydney.cc:609
Template definition of fit function of acoustic model.
Definition: JKatoomba_t.hh:75
Container I/O.
std::vector< JTripod > & tripods
Definition: JSydney.cc:420
int debug
debug level
unsigned long long usec_wall
Definition: JTimer.hh:224
void start()
Start timer.
Definition: JTimer.hh:89
Data structure for optical module.
File status.
static const std::string string_t
string
Definition: JSydney.cc:81
Auxiliary class to edit (x,y,z) position of tripod.
Definition: JSydney.cc:388