Jpp 20.0.0-27-g39925593c-D
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,
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
1241
1242 for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
1243
1244 if (module->getFloor() != 0) {
1245
1246 const JModuleAddressMap memo = demo.get(module->getID());
1247
1248 for (vector< pair<JPMTPhysicalAddress, JPMTModifier> >::const_iterator i = alt.begin(); i != alt.end(); ++i) {
1249
1250 const JPMTIdentifier id(module->getID(), memo.getAddressTranslator(i->first).tdc);
1251
1252 if (debug >= debug_t) {
1253 print(cout, id, i->second);
1254 }
1255
1256 if (!i->second.apply(module->getPMT(id.getPMTAddress()))) {
1257 ERROR("No valid action: " << i->first << ' ' << i->second << endl);
1258 }
1259 }
1260
1261 const auto range = ring.equal_range(module->getID());
1262
1263 for (auto i = range.first; i != range.second; ++i) {
1264
1265 JPMTPhysicalAddress modifier = i->second;
1266
1267 modifier.ring = (char) toupper(modifier.ring);
1268
1269 if (modifier.ring != 'A') {
1270
1272
1273 for (size_t i = 0; i != module->size(); ++i) {
1274
1275 const JPMTPhysicalAddress& address = memo.getPMTPhysicalAddress(i);
1276
1277 if (address.ring == modifier.ring) {
1278 buffer[address] = (*module)[i];
1279 }
1280 }
1281
1282 for (size_t i = 0; i != module->size(); ++i) {
1283
1284 const JPMTPhysicalAddress& address = memo.getPMTPhysicalAddress(i);
1285
1286 if (address.ring == modifier.ring) {
1287
1288 int position = address.position + modifier.position;
1289
1290 while (position > 6) { position -= 6; }
1291 while (position < 1) { position += 6; }
1292
1293 const JPMTPhysicalAddress source(modifier.ring, position);
1294
1295 DEBUG("Module " << setw(10) << module->getID() << ' ' << address << " <= " << source << endl);
1296
1297 (*module)[i] = buffer[source];
1298 }
1299 }
1300 }
1301 }
1302 }
1303 }
1304 }
1305
1306
1307 switch (option) {
1308 case 1:
1309 sort(detector.begin(), detector.end(), make_comparator(&JModule::getID));
1310 break;
1311
1312 case 2:
1313 sort(detector.begin(), detector.end(), make_comparator(&JModule::getLocation));
1314 break;
1315
1316 default:
1317 break;
1318 };
1319
1320
1321 try {
1323 }
1324 catch(const JException& error) {
1325 FATAL(error);
1326 }
1327}
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.
Detector data structure.
Definition JDetector.hh:96
Router for direct addressing of location data in detector data structure.
Logical location of module.
Definition JLocation.hh:40
const JLocation & getLocation() const
Get location.
Definition JLocation.hh:70
Lookup table for PMT addresses in optical module.
Data structure for a composite optical module.
Definition JModule.hh:76
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.
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
Template definition of a multi-dimensional oscillation probability interpolation table.
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
JValue_t second
Definition JPair.hh:129
friend std::ostream & operator<<(std::ostream &out, const JPair< JKey_t, JValue_t > &pair)
Write pair to output.
Definition JPair.hh:81
Range of values.
Definition JRange.hh:42
static const std::string string_t
string
Definition JSydney.cc:90
std::ostream & operator<<(std::ostream &out, const morphology_type &object)
Write morphology to output stream.
std::istream & operator>>(std::istream &in, morphology_type &object)
Read morphology from input stream.
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::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:31
status_type getStatus(const JType< status_type > &type) const
Get status.
Definition JStatus.hh:60
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