Jpp  master_rocky-37-gf0c5bc59d
the software that should make you happy
JEditDetector.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <sstream>
3 #include <string>
4 #include <vector>
5 #include <map>
6 #include <algorithm>
7 #include <cctype>
8 
9 #include "TRandom3.h"
10 
11 #include "JDetector/JDetector.hh"
18 #include "JDetector/JPMTStatus.hh"
22 #include "JGeometry3D/JVector3D.hh"
23 #include "JMath/JConstants.hh"
24 #include "JMath/JMath.hh"
25 #include "JTools/JRange.hh"
26 #include "JLang/JException.hh"
27 #include "JLang/JToken.hh"
28 #include "JLang/JComparator.hh"
29 #include "JLang/JComparison.hh"
30 #include "JSupport/JMeta.hh"
31 
32 #include "Jeep/JeepToolkit.hh"
33 #include "Jeep/JPrint.hh"
34 #include "Jeep/JParser.hh"
35 #include "Jeep/JMessage.hh"
36 
37 
38 namespace {
39 
40  using namespace JPP;
41 
42  /**
43  * Wild card for string identifier, module identifier or PMT address.
44  */
45  static const int WILDCARD = -1;
46 
47  static const std::string reset_t = "reset"; //!< Reset time offset, position and PMT status bit
48  static const std::string set_t = "set"; //!< Set time offset, position or PMT status bit
49  static const std::string setx_t = "setx"; //!< Set x-position
50  static const std::string sety_t = "sety"; //!< Set y-position
51  static const std::string setz_t = "setz"; //!< Set z-position
52  static const std::string addx_t = "addx"; //!< Add x-position
53  static const std::string addy_t = "addy"; //!< Add y-position
54  static const std::string addz_t = "addz"; //!< Add z-position
55  static const std::string subx_t = "subx"; //!< Subtract x-position
56  static const std::string suby_t = "suby"; //!< Subtract y-position
57  static const std::string subz_t = "subz"; //!< Subtract z-position
58  static const std::string add_t = "add"; //!< Add time offset or position
59  static const std::string sub_t = "sub"; //!< Subtract time offset or position
60  static const std::string rot_t = "rot"; //!< Rotate around z-axis by value [rad]
61  static const std::string lower_t = "lower"; //!< Rotate lower hemisphere around z-axis by value [rad]
62  static const std::string upper_t = "upper"; //!< Rotate upper hemisphere around z-axis by value [rad]
63  static const std::string mul_t = "mul"; //!< Multiply z-position by (1 + value)
64  static const std::string div_t = "div"; //!< Divide z-position by (1 + value)
65  static const std::string tilt_t = "tilt"; //!< Tilt string
66  static const std::string swap_t = "swap"; //!< Swap PMTs
67 
68  static const std::string assign_t = "assign"; //!< Assign module identifier
69  static const std::string locate_t = "locate"; //!< Locate module identifier
70  static const std::string string_t = "string"; //!< Assign string number
71 
72  static const std::string rand_t = "rand"; //!< Random value(s)
73  static const std::string randset_t = rand_t + set_t; //!< Set time offset or position
74  static const std::string randadd_t = rand_t + add_t; //!< Add time offset or position
75  static const std::string randsub_t = rand_t + sub_t; //!< Subtract time offset or position
76  static const std::string randrot_t = rand_t + rot_t; //!< Rotate around z-axis by value [rad]
77  static const std::string randmul_t = rand_t + mul_t; //!< Multiply z-position by (1 + value)
78  static const std::string randdiv_t = rand_t + div_t; //!< Divide z-position by (1 + value)
79  static const std::string randtilt_t = rand_t + tilt_t; //!< Tilt string
80 
81  static const std::string RESET_t = "RESET"; //!< Reset time offset of piezo/hydrophone and quaternion calibration of compass
82  static const std::string SET_t = "SET"; //!< Set time offset of piezo/hydrophone or quaternion calibration of compass
83  static const std::string ADD_t = "ADD"; //!< Add time offset of piezo/hydrophone or quaternion calibration of compass
84  static const std::string SUB_t = "SUB"; //!< Subtract time offset of piezo/hydrophone or quaternion calibration of compass
85  static const std::string ROT_t = "ROT"; //!< Rotate quaternion calibration of compass around z-axis by value [rad]
86 
87 
88  /**
89  * Apply action to given module.
90  *
91  * \param module module (I/O)
92  * \param action action
93  * \return true if valid action; else false
94  */
95  inline bool apply(JModule& module, const std::string& action)
96  {
97  if (action == reset_t) {
98 
99  // position does not depend on module but may not exactly be at origin
100 
101  module.setCalibration(JCalibration());
102  module.setStatus(JStatus());
103  module.setQuaternion(JQuaternion3D());
104  module.set(getModule<JKM3NeT_t>(1).getPosition());
105 
106  for (JModule::iterator pmt = module.begin(); pmt != module.end(); ++pmt) {
108  pmt->setStatus(JStatus());
109  }
110 
111  } else if (action == RESET_t) {
112 
113  module.setCalibration(JCalibration());
114  module.setQuaternion(JQuaternion3D());
115  module.setCalibration(getAverage(make_array(module.begin(), module.end(), &JPMT::getT0), 0.0));
116 
117  } else {
118 
119  return false;
120  }
121 
122  return true;
123  }
124 
125 
126  /**
127  * Apply action to given module.
128  *
129  * \param module module (I/O)
130  * \param action action
131  * \param value value
132  * \return true if valid action; else false
133  */
134  inline bool apply(JModule& module, const std::string& action, const double value)
135  {
136  if (action == set_t) { // actions with fixed values
137 
138  module.set(value);
139 
140  } else if (action == setx_t) {
141 
142  module.set(JVector3D(value, module.getY(), module.getZ()));
143 
144  } else if (action == addx_t) {
145 
146  module.add(JVector3D(value, 0.0, 0.0));
147 
148  } else if (action == subx_t) {
149 
150  module.sub(JVector3D(value, 0.0, 0.0));
151 
152  } else if (action == sety_t) {
153 
154  module.set(JVector3D(module.getX(), value, module.getZ()));
155 
156  } else if (action == addy_t) {
157 
158  module.add(JVector3D(0.0, value, 0.0));
159 
160  } else if (action == suby_t) {
161 
162  module.sub(JVector3D(0.0, value, 0.0));
163 
164  } else if (action == setz_t) {
165 
166  module.set(JVector3D(module.getX(), module.getY(), value));
167 
168  } else if (action == addz_t) {
169 
170  module.add(JVector3D(0.0, 0.0, value));
171 
172  } else if (action == subz_t) {
173 
174  module.sub(JVector3D(0.0, 0.0, value));
175 
176  } else if (action == add_t) {
177 
178  module.add(value);
179 
180  } else if (action == sub_t) {
181 
182  module.sub(value);
183 
184  } else if (action == rot_t) {
185 
186  const JVector3D center = module.getPosition();
187 
188  module.sub(center);
189 
190  module.rotate(JRotation3Z(value));
191 
192  module.add(center);
193 
194  } else if (action == lower_t ||
195  action == upper_t) {
196 
197  const JVector3D center = module.getPosition();
198 
199  module.sub(center);
200 
201  const JRotation3Z R(value);
202 
203  for (JModule::iterator pmt = module.begin(); pmt != module.end(); ++pmt) {
204  if ((action == upper_t && pmt->getDZ() > 0.0) ||
205  (action == lower_t && pmt->getDZ() < 0.0)) {
206  pmt->rotate(R);
207  }
208  }
209 
210  module.add(center);
211 
212  } else if (action == mul_t) {
213 
214  JVector3D center;
215 
216  if (value > 0.0)
217  center = JVector3D(module.getPosition().getX(),
218  module.getPosition().getY(),
219  module.getPosition().getZ() * (1.0 + value));
220  else
221  center = JVector3D(module.getPosition().getX(),
222  module.getPosition().getY(),
223  module.getPosition().getZ() / (1.0 - value));
224 
225  module.set(center);
226 
227  } else if (action == div_t) {
228 
229  JVector3D center;
230 
231  if (value > 0.0)
232  center = JVector3D(module.getPosition().getX(),
233  module.getPosition().getY(),
234  module.getPosition().getZ() / (1.0 + value));
235  else
236  center = JVector3D(module.getPosition().getX(),
237  module.getPosition().getY(),
238  module.getPosition().getZ() * (1.0 - value));
239 
240  module.set(center);
241 
242  } else if (action == SET_t) {
243 
244  module.getCalibration().setT0(value);
245 
246  } else if (action == ADD_t) {
247 
248  module.getCalibration().addT0(value);
249 
250  } else if (action == SUB_t) {
251 
252  module.getCalibration().subT0(value);
253 
254  } else if (action == ROT_t) {
255 
256  module.setQuaternion(JQuaternion3Z(value) * module.getQuaternion());
257 
258  } else if (action == randadd_t) { // actions with random values
259 
260  module.add(gRandom->Gaus(0.0, value));
261 
262  } else if (action == randsub_t) {
263 
264  module.sub(gRandom->Gaus(0.0, value));
265 
266  } else if (action == randrot_t){
267 
268  const JVector3D center = module.getPosition();
269 
270  module.sub(center);
271 
272  module.rotate(JRotation3Z(gRandom->Gaus(0.0, value)));
273 
274  module.add(center);
275 
276  } else if (action == randmul_t) {
277 
278  const JVector3D center(module.getPosition().getX(),
279  module.getPosition().getY(),
280  module.getPosition().getZ() * gRandom->Gaus(1.0, value));
281 
282  module.set(center);
283 
284  } else if (action == randdiv_t) {
285 
286  const JVector3D center(module.getPosition().getX(),
287  module.getPosition().getY(),
288  module.getPosition().getZ() / gRandom->Gaus(1.0, value));
289 
290  module.set(center);
291 
292  } else if (action == assign_t) { // action with assigments
293 
294  module.setID((int) value);
295 
296  } else if (action == string_t) {
297 
298  module.setLocation(JLocation((int) value, module.getFloor()));
299 
300  } else { //
301 
302  return false;
303  }
304 
305  return true;
306  }
307 
308 
309  /**
310  * Apply action to given module.
311  *
312  * \param module module (I/O)
313  * \param action action
314  * \param first first value
315  * \param second second value
316  * \return true if valid action; else false
317  */
318  inline bool apply(JModule& module, const std::string& action, const double first, const double second)
319  {
320  if (action == tilt_t) { // actions with fixed values
321 
322  const double Tx = first;
323  const double Ty = second;
324  const double Tz = sqrt(1.0 - Tx*Tx - Ty*Ty);
325 
326  const double x = Tx * module.getZ() + module.getX();
327  const double y = Ty * module.getZ() + module.getY();
328  const double z = Tz * module.getZ();
329 
330  module.set(JPosition3D(x,y,z));
331 
332  } else if (action == locate_t) {
333 
334  module.setLocation(JLocation((int) first, (int) second));
335 
336  } else if (action == swap_t) {
337 
338  std::swap(module[(int) first], module[(int) second]);
339 
340  } else { //
341 
342  return false;
343  }
344 
345  return true;
346  }
347 
348 
349  /**
350  * Apply action to given module.
351  *
352  * \param module module (I/O)
353  * \param action action
354  * \param pos pos
355  * \return true if valid action; else false
356  */
357  inline bool apply(JModule& module, const std::string& action, const JVector3D& pos)
358  {
359  const JVector3D randpos(gRandom->Gaus(0.0, pos.getX()),
360  gRandom->Gaus(0.0, pos.getY()),
361  gRandom->Gaus(0.0, pos.getZ()));
362 
363  if (action == set_t) // actions with fixed values
364  module.set(pos);
365  else if (action == add_t)
366  module.add(pos);
367  else if (action == sub_t)
368  module.sub(pos);
369  else if (action == randset_t) // actions with random values
370  module.set(randpos);
371  else if (action == randadd_t)
372  module.add(randpos);
373  else if (action == randsub_t)
374  module.sub(randpos);
375  else
376  return false;
377 
378  return true;
379  }
380 
381 
382  /**
383  * Apply action to given module.
384  *
385  * \param module module (I/O)
386  * \param action action
387  * \param Q quaternion
388  * \return true if valid action; else false
389  */
390  inline bool apply(JModule& module, const std::string& action, const JQuaternion3D& Q)
391  {
392  if (action == SET_t)
393  module.setQuaternion(Q);
394  else if (action == ADD_t)
395  module.setQuaternion(Q * module.getQuaternion());
396  else if (action == SUB_t)
397  module.setQuaternion(Q.getConjugate() * module.getQuaternion());
398  else
399  return false;
400 
401  module.getQuaternion().normalise();
402 
403  return true;
404  }
405 
406 
407  /**
408  * Apply action to given module.
409  *
410  * \param module module (I/O)
411  * \param action action
412  * \param value value
413  * \return true if valid action; else false
414  */
415  inline bool apply(JModule& module, const std::string& action, const std::string& value)
416  {
417  try {
418 
419  if (action == set_t)
420  module.getStatus().set (getModuleStatusBit(value));
421  else if (action == reset_t)
422  module.getStatus().reset(getModuleStatusBit(value));
423  else
424  return false;
425 
426  return true;
427  }
428  catch(const std::exception&) {
429  return false;
430  }
431  }
432 
433 
434  /**
435  * Apply action to given PMT.
436  *
437  * \param pmt PMT (I/O)
438  * \param action action
439  * \param value value
440  * \return true if valid action; else false
441  */
442  inline bool apply(JPMT& pmt, const std::string& action, const std::string& value)
443  {
444  try {
445 
446  if (action == set_t)
447  pmt.getStatus().set (getPMTStatusBit(value));
448  else if (action == reset_t)
449  pmt.getStatus().reset(getPMTStatusBit(value));
450  else
451  return false;
452 
453  return true;
454  }
455  catch(const std::exception&) {
456  return false;
457  }
458  }
459 
460 
461  /**
462  * Auxiliary class for module modifications.
463  */
464  struct JModifier {
465  /**
466  * Default constructor.
467  */
468  JModifier()
469  {}
470 
471 
472  /**
473  * Check validity.
474  *
475  * \return true if valid modifier; else false
476  */
477  bool is_valid() const
478  {
479  return (action != "" && !data.empty());
480  }
481 
482 
483  /**
484  * Apply action to given module depending on number of values.
485  *
486  * \param module module
487  * \return true if valid action; else false
488  */
489  bool apply(JModule& module) const
490  {
491  switch (data.size()) {
492 
493  case 0:
494  return ::apply(module, action);
495 
496  case 1:
497  return ::apply(module, action, data[0]);
498 
499  case 2:
500  return ::apply(module, action, data[0], data[1]);
501 
502  case 3:
503  return ::apply(module, action, JVector3D(data[0], data[1], data[2]));
504 
505  case 4:
506  return ::apply(module, action, JQuaternion3D(data[0], data[1], data[2], data[3]));
507 
508  default:
509  return false;
510  }
511  }
512 
513 
514  /**
515  * Read modifier from input.
516  *
517  * \param in input stream
518  * \param modifier modifier
519  * \return input stream
520  */
521  friend inline std::istream& operator>>(std::istream& in, JModifier& modifier)
522  {
523  if (in >> modifier.action) {
524 
525  modifier.data.clear();
526 
527  for (double x; in >> x; ) {
528  modifier.data.push_back(x);
529  }
530 
531  in.clear(std::ios_base::eofbit);
532  }
533 
534  return in;
535  }
536 
537 
538  /**
539  * Write modifier to output.
540  *
541  * \param out output stream
542  * \param modifier modifier
543  * \return output stream
544  */
545  friend inline std::ostream& operator<<(std::ostream& out, const JModifier& modifier)
546  {
547  out << modifier.action;
548 
549  for (std::vector<double>::const_iterator i = modifier.data.begin(); i != modifier.data.end(); ++i) {
550  out << ' ' << *i;
551  }
552 
553  return out;
554  }
555 
556 
557  std::string action;
559  };
560 
561 
562  /**
563  * Get modifier for given string.
564  *
565  * For actions <tt>ranXXX</tt>, the corresponding action <tt>XXX</tt> is made the same for all modules in the given string.\n
566  * For all other options, the input action is maintained.
567  *
568  * \param id string number
569  * \param modifier modifier
570  * \return modifier
571  */
572  inline const JModifier& getModifier(const int id, const JModifier& modifier)
573  {
574  using namespace std;
575 
577 
578  const string::size_type pos = modifier.action.find(rand_t);
579 
580  if (pos != string::npos) {
581 
582  JModifier& result = buffer[id][modifier.action][modifier.data.size()];
583 
584  if (!result.is_valid()) {
585 
586  result.action = modifier.action.substr(pos + rand_t.length());
587 
588  for (size_t i = 0; i != modifier.data.size(); ++i) {
589  result.data.push_back(gRandom->Gaus(0.0, modifier.data[i]));
590  }
591  }
592 
593  return result;
594 
595  } else {
596 
597  return modifier;
598  }
599  }
600 
601 
602  /**
603  * Auxiliary class for module status modifications.
604  */
605  struct JModuleModifier {
606  /**
607  * Default constructor.
608  */
609  JModuleModifier()
610  {}
611 
612 
613  /**
614  * Apply action to given module.
615  *
616  * \param module module
617  * \return true if valid action; else false
618  */
619  bool apply(JModule& module) const
620  {
621  return ::apply(module, action, value);
622  }
623 
624 
625  /**
626  * Read module modifier from input.
627  *
628  * \param in input stream
629  * \param modifier modifier
630  * \return input stream
631  */
632  friend inline std::istream& operator>>(std::istream& in, JModuleModifier& modifier)
633  {
634  return in >> modifier.action >> modifier.value;
635  }
636 
637 
638  /**
639  * Write module modifier to output.
640  *
641  * \param out output stream
642  * \param modifier modifier
643  * \return output stream
644  */
645  friend inline std::ostream& operator<<(std::ostream& out, const JModuleModifier& modifier)
646  {
647  out << modifier.action;
648  out << ' ';
649  out << modifier.value;
650 
651  return out;
652  }
653 
654 
655  std::string action;
656  std::string value;
657  };
658 
659 
660  /**
661  * Auxiliary class for PMT status modifications.
662  */
663  struct JPMTModifier {
664  /**
665  * Default constructor.
666  */
667  JPMTModifier()
668  {}
669 
670 
671  /**
672  * Apply action to given PMT.
673  *
674  * \param pmt PMT
675  * \return true if valid action; else false
676  */
677  bool apply(JPMT& pmt) const
678  {
679  return ::apply(pmt, action, value);
680  }
681 
682 
683  /**
684  * Read PMT modifier from input.
685  *
686  * \param in input stream
687  * \param modifier modifier
688  * \return input stream
689  */
690  friend inline std::istream& operator>>(std::istream& in, JPMTModifier& modifier)
691  {
692  return in >> modifier.action >> modifier.value;
693  }
694 
695 
696  /**
697  * Write PMT modifier to output.
698  *
699  * \param out output stream
700  * \param modifier modifier
701  * \return output stream
702  */
703  friend inline std::ostream& operator<<(std::ostream& out, const JPMTModifier& modifier)
704  {
705  out << modifier.action;
706  out << ' ';
707  out << modifier.value;
708 
709  return out;
710  }
711 
712 
713  std::string action;
714  std::string value;
715  };
716 
717 
718  /**
719  * Range of string numbers.
720  *
721  * The input format could be a single number or two numbers separated by JRange_t::SEPARATOR.
722  */
723  struct JRange_t :
724  public JRange<int>
725  {
726  /**
727  * Separator between two identifier values.
728  */
729  static const char SEPARATOR = '-';
730 
731  /**
732  * Default constructor.
733  */
734  JRange_t() :
735  JRange(-1, -1)
736  {}
737 
738 
739  /**
740  * Read range from input.
741  *
742  * \param in input stream
743  * \param range range
744  * \return input stream
745  */
746  friend inline std::istream& operator>>(std::istream& in, JRange_t& range)
747  {
748  if (in >> range.first) {
749 
750  range.second = range.first;
751 
752  if (in.peek() == (int) JRange_t::SEPARATOR) {
753 
754  in.get();
755 
756  in >> range.second;
757 
758  } else {
759 
760  in.clear();
761  }
762  }
763 
764  return in;
765  }
766 
767 
768  /**
769  * Write range to output.
770  *
771  * \param out output stream
772  * \param range range
773  * \return output stream
774  */
775  friend inline std::ostream& operator<<(std::ostream& out, const JRange_t& range)
776  {
777  return out << range.first << JRange_t::SEPARATOR << range.second;
778  }
779  };
780 
781 
782  /**
783  * Print module modification.
784  *
785  * \param out output stream
786  * \param module module
787  * \param modifier modifier
788  */
789  inline void print(std::ostream& out, const JModule& module, const JModifier& modifier)
790  {
791  using namespace std;
792  using namespace JPP;
793 
794  out << "Modifier" << ' '
795  << getLabel(module.getLocation()) << ' '
796  << setw(10) << module.getID() << ' '
797  << "action " << modifier << endl;
798  }
799 
800 
801  /**
802  * Print module modification.
803  *
804  * \param out output stream
805  * \param id module identifier
806  * \param modifier modifier
807  */
808  inline void print(std::ostream& out, const JModuleIdentifier& id, const JModuleModifier& modifier)
809  {
810  using namespace std;
811  using namespace JPP;
812 
813  out << "module modifier" << ' '
814  << "(" << setw(10) << id.getID() << ")" << ' '
815  << "action" << ' ' << modifier.action << ' '
816  << "value" << ' ' << modifier.value << endl;
817  }
818 
819 
820  /**
821  * Print PMT modification.
822  *
823  * \param out output stream
824  * \param pmt PMT identifier
825  * \param modifier modifier
826  */
827  inline void print(std::ostream& out, const JPMTIdentifier& pmt, const JPMTModifier& modifier)
828  {
829  using namespace std;
830  using namespace JPP;
831 
832  out << "PMT modifier" << ' '
833  << "(" << setw(10) << pmt.getID() << "," << setw(2) << pmt.getPMTAddress() << ")" << ' '
834  << "action" << ' ' << modifier.action << ' '
835  << "value" << ' ' << modifier.value << endl;
836  }
837 }
838 
839 
840 /**
841  * \file
842  *
843  * Auxiliary program to modify detector calibration.
844  *
845  * Syntax:
846  * <pre>
847  * -M "<module identifier> (set|add|sub|randset|randadd|randsub) x0 [x1 x2]"
848  * -(S|s) "<string number> (set|add|sub|randset|randadd|randsub) x0 [x1 x2]"
849  * -M "<module identifier> (setx|addx|subx|sety|addy|suby|setz|addz|subz) value"
850  * -(S|s) "<string number> (setx|addx|subx|sety|addy|suby|setz|addz|subz) value"
851  * -M "<module identifier> (rot|randrot|lower|upper) phi"
852  * -(S|s) "<string number> (rot|randrot) phi"
853  * -M "<module identifier> (mul|randmul) factor"
854  * -(S|s) "<string number> (mul|randmul) factor"
855  * -M "<module identifier> (div|randdiv) factor"
856  * -(S|s) "<string number> (div|randdiv) factor"
857  * -M "<module identifier> (reset)"
858  * -(S|s) "<string number> (reset)"
859  * -M "<module identifier> (assign) identifier"
860  * -M "<module identifier> (locate) <string> <floor>"
861  * -M "<module identifier> (swap) <PMT> <PMT>"
862  * -M "<module identifier> (SET|ADD|SUB|) x0 [x1 x2 x3]"
863  * -(S|s) "<string number> (SET|ADD|SUB|) x0 [x1 x2 x3]"
864  * -M "<module identifier> (ROT) phi"
865  * -(S|s) "<string number> (ROT) phi"
866  * -(S|s) "<string number> (tilt|randtilt) Tx Ty"
867  * -R "<module identifier> <PMT physical address>"
868  * -W "<module identifier> (set|reset) (MODULE_DISABLE|COMPASS_DISABLE|HYDROPHONE_DISABLE|PIEZO_DISABLE|MODULE_OUT_OF_SYNC)"
869  * -P "<PMT identifier> (set|reset) (PMT_DISABLE|HIGH_RATE_VETO_DISABLE|FIFO_FULL_DISABLE|UDP_COUNTER_DISABLE|UDP_TRAILER_DISABLE|OUT_OF_SYNC)"
870  * -p "<PMT physical address> (set|reset) (PMT_DISABLE|HIGH_RATE_VETO_DISABLE|FIFO_FULL_DISABLE|UDP_COUNTER_DISABLE|UDP_TRAILER_DISABLE|OUT_OF_SYNC)"
871  * -k "<string number>[-<string number>]"
872  * -r "<string number>[-<string number>]"
873  * -m "<module identifier>"
874  * -D "<string number> <floor>"
875  * -\@ "<key>=<value>[;<key>=<value>"
876  * </pre>
877  * Options <tt>-M</tt> and <tt>-S</tt> refer to a module and a string, respectively.\n
878  * The values provided for a string modification coherently apply to the modules of the specified string number.\n
879  * The option <tt>-s</tt> is equivalent to option <tt>-S</tt> except that
880  * the action applies only to the optical modules in the string and not the base module.
881  *
882  * The options <tt>randxxx</tt> correspond to a randomisation of the specified option.
883  *
884  * If the module identifier or string number is -1,
885  * the action is applied to all modules or strings in the detector, respectively.
886  *
887  * For options <tt>[rand]set</tt>, <tt>[rand]add</tt> and <tt>[rand]sub</tt>,
888  * the number of values apply to position or time calibration in the following way:
889  * -# time calibration <tt>(t = x0)</tt>
890  * -# invalid
891  * -# position calibration <tt>(x = x0, y = x1, z = x2)</tt>
892  *
893  * For options <tt>(set|add|sub)(x|y|z)</tt>, the value corresponds to last character of the the quoted action.
894  *
895  * For options <tt>[rand]rot</tt>,
896  * the angle <tt>phi</tt> refers to an anti-clockwise rotation around the z-axis.\n
897  * The options <tt>upper</tt> and <tt>lower</tt> refer to a rotation of the PMTs in the upper and lower hemisphere of the module, respectively.\n
898  * The rotation angle is defined in radians.
899  *
900  * For options <tt>[rand]mul</tt> and <tt>[rand]div</tt>,
901  * the multiplication/division <tt>factor</tt> (a.k.a.\ "stretching") applies to the z-coordinates of the modules.\n
902  * The factor is defined as a fraction; the actual multiplication/division factor is <tt>(1 + factor)</tt>.
903  *
904  * For options <tt>SET</tt>, <tt>ADD</tt> and <tt>SUB</tt>,
905  * the number of values apply to time or quaternion calibration of the module in the following way:
906  * -# time calibration of piezo sensor or hydrophone <tt>(t = x0)</tt>
907  * -# invalid
908  * -# invalid
909  * -# quaternion calibration of compass <tt>(qa = x0, qb = x1, qc = x2, qd = x3)</tt>
910  *
911  * For options <tt>ROT</tt>,
912  * the angle <tt>phi</tt> refers to an anti-clockwise rotation around the z-axis of the quaternion calibration of the compass.\n
913  * The rotation angle is defined in radians.
914  *
915  * Note that to correct the time calibration for the delay time of the piezo sensor and hydrophone,
916  * application JDetectorDB.cc can be used (option <tt>-WW</tt>).
917  *
918  * The units of all positions and time values are <tt>m</tt> and <tt>ns</tt>, respectively.
919  *
920  * Note that for string modifiers with option <tt>randxxx</tt>,
921  * the action is coherently applied to the modules in the specified string.\n
922  * Only one type of action (defined by <tt>xxx</tt> and the number of values) is then allowed per string.
923  *
924  * The option <tt>-R</tt> can be used to rotate the positions of PMTs within a given ring.\n
925  * In this, the position of the physical address of the PMT corresponds to the number of steps of the rotation.
926  *
927  * The option <tt>-W</tt> can be used to modify the status of a module.
928  * The options <tt>-P</tt> and <tt>-p</tt> can be used to modify the status of PMTs.
929  *
930  * Option <tt>-\@</tt> refers to the header information.\n
931  * The list of possible keys can be obtained using JPrintDetector.cc with option <tt>-O header</tt>.
932  *
933  * Multiple options <tt>-M</tt>, <tt>-S</tt>, <tt>-s</tt> or <tt>-\@</tt> will be processed in order of appearance.
934  *
935  * Options <tt>-k</tt> and <tt>-r</tt> can be used to keep and remove (a range of) string numbers, respectively.
936  *
937  * The options <tt>-m</tt> and <tt>-D</tt> can be used to maintain a specific module (and remove all others) and
938  * to delete a floor from a string, respectively.
939  *
940  * Note finally that if the output file name is the same as the input file name,
941  * the original file will be overwritten.
942  *
943  * \author mdejong
944  */
945 int main(int argc, char **argv)
946 {
947  using namespace std;
948  using namespace JPP;
949 
950  typedef JToken<';'> JToken_t;
951 
952  string inputFile;
953  string outputFile;
954  vector<JToken_t> hdr;
958  vector< pair<int,
959  JModuleModifier> > wip;
961  JPMTModifier> > pmt;
963  JPMTModifier> > alt;
964  multimap<int,
965  JPMTPhysicalAddress> ring;
966  vector<JRange_t> keep;
967  vector<JRange_t> rm;
968  vector<int> id;
969  multimap<int, int> del;
970  int option;
971  bool squash;
972  int debug;
973 
974  try {
975 
976  JParser<> zap("Auxiliary program to modify detector.");
977 
978  zap['a'] = make_field(inputFile);
979  zap['o'] = make_field(outputFile);
980  zap['@'] = make_field(hdr, "header modification") = JPARSER::initialised();
981  zap['M'] = make_field(mod, "module modification") = JPARSER::initialised();
982  zap['S'] = make_field(str, "string modification (optical modules and base modules)") = JPARSER::initialised();
983  zap['s'] = make_field(dos, "string modification (optical modules only)") = JPARSER::initialised();
984  zap['W'] = make_field(wip, "module status modification") = JPARSER::initialised();
985  zap['P'] = make_field(pmt, "PMT status modification by PMT logical address") = JPARSER::initialised();
986  zap['p'] = make_field(alt, "PMT status modification by PMT physical address") = JPARSER::initialised();
987  zap['R'] = make_field(ring, "rotate positions of PMTs in ring") = JPARSER::initialised();
988  zap['k'] = make_field(keep, "keep string[s]") = JPARSER::initialised();
989  zap['r'] = make_field(rm, "remove string[s]") = JPARSER::initialised();
990  zap['m'] = make_field(id, "maintain module by identifier") = JPARSER::initialised();
991  zap['D'] = make_field(del, "remove module by location") = JPARSER::initialised();
992  zap['O'] = make_field(option, "sort modules: "\
993  "0 -> no sort; 1 -> module identifier; 2 -> module location") = 0, 1, 2;
994  zap['q'] = make_field(squash, "squash meta data");
995  zap['d'] = make_field(debug, "debug level") = 2;
996 
997  zap(argc, argv);
998  }
999  catch(const exception &error) {
1000  FATAL(error.what() << endl);
1001  }
1002 
1003  gRandom->SetSeed(0);
1004 
1005  const int ns = ((keep.empty() ? 0 : 1) +
1006  (rm .empty() ? 0 : 1) +
1007  (id .empty() ? 0 : 1) +
1008  (del .empty() ? 0 : 1));
1009 
1010  if (ns > 1) {
1011  FATAL("Use either option -k, -r, -m or -D." << endl);
1012  }
1013 
1015 
1016  try {
1017  load(inputFile, detector);
1018  }
1019  catch(const JException& error) {
1020  FATAL(error);
1021  }
1022 
1023  if (squash) {
1024  detector.comment.clear();
1025  }
1026 
1027  detector.comment.add(JMeta(argc,argv));
1028 
1029  if (detector.setToLatestVersion()) {
1030  NOTICE("Set detector version to " << detector.getVersion() << endl);
1031  }
1032 
1033 
1034  if (!hdr.empty()) {
1035 
1036  int id = -1;
1037 
1038  JProperties helper = detector.getProperties();
1039 
1040  helper["id"] = id;
1041 
1042  for (vector<JToken_t>::const_iterator i = hdr.begin(); i != hdr.end(); ++i) {
1043 
1044  istringstream is(*i);
1045 
1046  is >> helper;
1047  }
1048 
1049  if (id != -1) {
1050  detector.setID(id);
1051  }
1052  }
1053 
1054 
1055  if (ns != 0) {
1056 
1057  for (JDetector::iterator module = detector.begin(); module != detector.end(); ) {
1058 
1059  bool __rm__ = !keep.empty() && rm.empty();
1060 
1061  for (vector<JRange_t>::const_iterator i = keep.begin(); i != keep.end(); ++i) {
1062  if (module->getString() >= i->first && module->getString() <= i->second) {
1063  __rm__ = false;
1064  }
1065  }
1066 
1067  for (vector<JRange_t>::const_iterator i = rm.begin(); i != rm.end(); ++i) {
1068  if (module->getString() >= i->first && module->getString() <= i->second) {
1069  __rm__ = true;
1070  }
1071  }
1072 
1073  if (!id.empty()) {
1074  __rm__ = find(id.begin(), id.end(), module->getID()) == id.end();
1075  }
1076 
1077  const auto range = del.equal_range(module->getString());
1078 
1079  for (auto i = range.first; i != range.second; ++i) {
1080  if (i->second == module->getFloor()) {
1081  __rm__ = true;
1082  }
1083  }
1084 
1085  if (__rm__)
1086  module = detector.erase(module);
1087  else
1088  ++module;
1089  }
1090  }
1091 
1092 
1093  for (vector< pair<int, JModifier> >::const_iterator i = mod.begin(); i != mod.end(); ++i) {
1094 
1095  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1096 
1097  if (module->getID() == i->first || i->first == WILDCARD ){
1098 
1099  if (debug >= debug_t) {
1100  print(cout, *module, i->second);
1101  }
1102 
1103  if (!i->second.apply(*module)) {
1104  ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1105  }
1106  }
1107  }
1108  }
1109 
1110 
1111  for (vector< pair<int, JModifier> >::const_iterator i = str.begin(); i != str.end(); ++i) {
1112 
1113  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1114 
1115  if (module->getString() == i->first || i->first == WILDCARD) {
1116 
1117  const JModifier modifier = getModifier(module->getString(), i->second);
1118 
1119  if (debug >= debug_t) {
1120  print(cout, *module, i->second);
1121  }
1122 
1123  if (!modifier.apply(*module)) {
1124  ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1125  }
1126  }
1127  }
1128  }
1129 
1130 
1131  for (vector< pair<int, JModifier> >::const_iterator i = dos.begin(); i != dos.end(); ++i) {
1132 
1133  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1134 
1135  if (module->getFloor() != 0) {
1136 
1137  if (module->getString() == i->first || i->first == WILDCARD) {
1138 
1139  const JModifier modifier = getModifier(module->getString(), i->second);
1140 
1141  if (debug >= debug_t) {
1142  print(cout, *module, i->second);
1143  }
1144 
1145  if (!modifier.apply(*module)) {
1146  ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1147  }
1148  }
1149  }
1150  }
1151  }
1152 
1153 
1154  for (vector< pair<int, JModuleModifier> >::const_iterator i = wip.begin(); i != wip.end(); ++i) {
1155 
1156  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1157 
1158  if (module->getID() == i->first || i->first == WILDCARD ){
1159 
1160  if (debug >= debug_t) {
1161  print(cout, *module, i->second);
1162  }
1163 
1164  if (!i->second.apply(*module)) {
1165  ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1166  }
1167  }
1168  }
1169  }
1170 
1171 
1172  for (vector< pair<JPMTIdentifier, JPMTModifier> >::const_iterator i = pmt.begin(); i != pmt.end(); ++i) {
1173 
1174  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1175 
1176  if (module->getID() == i->first.getModuleID() || i->first.getModuleID() == WILDCARD) {
1177 
1178  if (debug >= debug_t) {
1179  print(cout, i->first, i->second);
1180  }
1181 
1182  if (i->first.getPMTAddress() == WILDCARD) {
1183 
1184  for (int pmt = 0; pmt != getNumberOfPMTs(*module); ++pmt) {
1185  if (!i->second.apply(module->getPMT(pmt))) {
1186  ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1187  }
1188  }
1189 
1190  } else if (i->first.getPMTAddress() >= 0 &&
1191  i->first.getPMTAddress() < getNumberOfPMTs(*module) &&
1192  !i->second.apply(module->getPMT(i->first.getPMTAddress()))) {
1193  ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1194  }
1195  }
1196  }
1197  }
1198 
1199 
1200  if (!alt.empty() || !ring.empty()) {
1201 
1202  if (!hasDetectorAddressMap(detector.getID())) {
1203  FATAL("Invalid detector identifier " << detector.getID() << endl);
1204  }
1205 
1206  const JDetectorAddressMap& demo = getDetectorAddressMap(detector.getID());
1207 
1208  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1209 
1210  const JModuleAddressMap memo = demo.get(module->getID());
1211 
1212  for (vector< pair<JPMTPhysicalAddress, JPMTModifier> >::const_iterator i = alt.begin(); i != alt.end(); ++i) {
1213 
1214  const JPMTIdentifier id(module->getID(), memo.getAddressTranslator(i->first).tdc);
1215 
1216  if (debug >= debug_t) {
1217  print(cout, id, i->second);
1218  }
1219 
1220  if (!i->second.apply(module->getPMT(id.getPMTAddress()))) {
1221  ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1222  }
1223  }
1224 
1225  const auto range = ring.equal_range(module->getID());
1226 
1227  for (auto i = range.first; i != range.second; ++i) {
1228 
1229  JPMTPhysicalAddress modifier = i->second;
1230 
1231  modifier.ring = (char) toupper(modifier.ring);
1232 
1233  if (modifier.ring != 'A') {
1234 
1236 
1237  for (size_t i = 0; i != module->size(); ++i) {
1238 
1239  const JPMTPhysicalAddress& address = memo.getPMTPhysicalAddress(i);
1240 
1241  if (address.ring == modifier.ring) {
1242  buffer[address] = (*module)[i];
1243  }
1244  }
1245 
1246  for (size_t i = 0; i != module->size(); ++i) {
1247 
1248  const JPMTPhysicalAddress& address = memo.getPMTPhysicalAddress(i);
1249 
1250  if (address.ring == modifier.ring) {
1251 
1252  int position = address.position + modifier.position;
1253 
1254  while (position > 6) { position -= 6; }
1255  while (position < 1) { position += 6; }
1256 
1257  const JPMTPhysicalAddress source(modifier.ring, position);
1258 
1259  DEBUG("Module " << setw(10) << module->getID() << ' ' << address << " <= " << source << endl);
1260 
1261  (*module)[i] = buffer[source];
1262  }
1263  }
1264  }
1265  }
1266  }
1267  }
1268 
1269 
1270  switch (option) {
1271  case 1:
1272  sort(detector.begin(), detector.end(), make_comparator(&JModule::getID));
1273  break;
1274 
1275  case 2:
1276  sort(detector.begin(), detector.end(), make_comparator(&JModule::getLocation));
1277  break;
1278 
1279  default:
1280  break;
1281  };
1282 
1283 
1284  try {
1286  }
1287  catch(const JException& error) {
1288  FATAL(error);
1289  }
1290 }
string outputFile
Detector support kit.
Data structure for detector geometry and calibration.
int main(int argc, char **argv)
Exceptions.
std::istream & operator>>(std::istream &in, JAANET::JHead &header)
Read header from input.
Definition: JHead.hh:1832
Mathematical constants.
Base class for data structures with artithmetic capabilities.
General purpose messaging.
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62
#define ERROR(A)
Definition: JMessage.hh:66
#define NOTICE(A)
Definition: JMessage.hh:64
#define FATAL(A)
Definition: JMessage.hh:67
int debug
debug level
Definition: JSirene.cc:69
ROOT I/O of application specific meta data.
Direct access to module in detector data structure.
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:2142
I/O formatting auxiliaries.
Auxiliary class to define a range between two values.
Auxiliary methods for handling file names, type names and environment.
Data structure for time calibration.
double getT0() const
Get time offset.
const JCalibration & getCalibration() const
Get calibration.
void subT0(const double t0)
Subtract time offset.
void setCalibration(const JCalibration &cal)
Set calibration.
void setT0(const double t0)
Set time offset.
void addT0(const double t0)
Add time offset.
Lookup table for PMT addresses in detector.
const JModuleAddressMap & get(const int id) const
Get module address map.
Detector data structure.
Definition: JDetector.hh:96
Logical location of module.
Definition: JLocation.hh:40
int getFloor() const
Get floor number.
Definition: JLocation.hh:146
int getString() const
Get string number.
Definition: JLocation.hh:135
const JLocation & getLocation() const
Get location.
Definition: JLocation.hh:70
void setLocation(const JLocation &location)
Set location.
Definition: JLocation.hh:92
Lookup table for PMT addresses in optical module.
const JPMTAddressTranslator & getAddressTranslator(const int tdc) const
Get PMT address translator.
const JPMTPhysicalAddress & getPMTPhysicalAddress(const int tdc) const
Get PMT physical address.
Data structure for a composite optical module.
Definition: JModule.hh:75
JModule & add(const JVector3D &pos)
Add position.
Definition: JModule.hh:419
JModule & sub(const JVector3D &pos)
Subtract position.
Definition: JModule.hh:437
const JPMT & getPMT(const int index) const
Get PMT.
Definition: JModule.hh:172
JModule & set(const JVector3D &pos)
Set position.
Definition: JModule.hh:407
void rotate(const JRotation3D &R)
Rotate module.
Definition: JModule.hh:314
int getPMTAddress() const
Get PMT address (= TDC).
Data structure for PMT physical address.
char ring
ring number ['A','F']
int position
position within ring [1,6]
Data structure for PMT geometry, calibration and status.
Definition: JPMT.hh:49
Utility class to parse parameter values.
Definition: JProperties.hh:501
Data structure for position in three dimensions.
Definition: JPosition3D.hh:38
const JPosition3D & getPosition() const
Get position.
Definition: JPosition3D.hh:130
Data structure for unit quaternion in three dimensions.
const JQuaternion3D & getQuaternion() const
Get quaternion.
void setQuaternion(const JQuaternion3D &quaternion)
Set quaternion.
JQuaternion3D getConjugate() const
Get conjugate of this quaternion.
JQuaternion3D & normalise()
Normalise quaternion.
Rotation around Z-axis.
Definition: JRotation3D.hh:87
Data structure for vector in three dimensions.
Definition: JVector3D.hh:36
double getY() const
Get y position.
Definition: JVector3D.hh:104
double getZ() const
Get z position.
Definition: JVector3D.hh:115
double getX() const
Get x position.
Definition: JVector3D.hh:94
General exception.
Definition: JException.hh:24
Auxiliary class for object identification.
Definition: JObjectID.hh:25
void setID(const int id)
Set identifier.
Definition: JObjectID.hh:72
int getID() const
Get identifier.
Definition: JObjectID.hh:50
Wrapper class around string.
Definition: JToken.hh:26
Utility class to parse command line options.
Definition: JParser.hh:1698
friend std::istream & operator>>(std::istream &in, JPair< JKey_t, JValue_t > &pair)
Read pair from input.
Definition: JPair.hh:65
JKey_t first
Definition: JPair.hh:128
friend std::ostream & operator<<(std::ostream &out, const JPair< JKey_t, JValue_t > &pair)
Write pair to output.
Definition: JPair.hh:81
JValue_t second
Definition: JPair.hh:129
Range of values.
Definition: JRange.hh:42
std::ostream & operator<<(std::ostream &stream, const CLBCommonHeader &header)
JPosition3D getPosition(const Vec &pos)
Get position.
static const std::string string_t
string
Definition: JSydney.cc:89
std::ostream & print(std::ostream &out, const JTestSummary &summary, const char delimiter=' ', const bool useColors=true)
Print test summary.
std::string getLabel(const JLocation &location)
Get module label for monitoring and other applications.
Definition: JLocation.hh:247
int getNumberOfPMTs(const JModule &module)
Get number of PMTs.
static const JGetPMTStatusBit getPMTStatusBit
Function object to map key to PMT status bit.
Definition: JPMTStatus.hh:65
static const JGetModuleStatusBit getModuleStatusBit
Function object to map key to module status bit.
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.
bool hasDetectorAddressMap(const int id)
Check if detector address map is available.
JDetectorAddressMap & getDetectorAddressMap()
Get detector address map.
@ debug_t
debug
Definition: JMessage.hh:29
JComparator< JResult_t T::*, JComparison::lt > make_comparator(JResult_t T::*member)
Helper method to create comparator between values of data member.
const array_type< JValue_t > & make_array(const JValue_t(&array)[N])
Method to create array of values.
Definition: JVectorize.hh:54
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< size_t > ns
bool is_valid(const json &js)
Check validity of JSon data.
static const char WILDCARD
Definition: JDAQTags.hh:56
Definition: JSTDTypes.hh:14
Type definition of range.
Definition: JHead.hh:43
JRange_t()
Default constructor.
Definition: JHead.hh:47
Detector file.
Definition: JHead.hh:227
Auxiliary class for handling status.
Definition: JStatus.hh:39
int getStatus() const
Get status.
Definition: JStatus.hh:63
void setStatus(const JStatus &status)
Set status.
Definition: JStatus.hh:97
This class represents a rotation around the z-axis.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:68
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:72