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