Jpp 21.0.0-rc.3
the software that should make you happy
Loading...
Searching...
No Matches
JDetectorSupportkit.hh
Go to the documentation of this file.
1#ifndef __JDETECTOR__JDETECTORSUPPORTKIT__
2#define __JDETECTOR__JDETECTORSUPPORTKIT__
3
4#include "JLang/JTypeList.hh"
5#include "JLang/JNullType.hh"
6#include "JLang/JType.hh"
7#include "JLang/JException.hh"
8
9#include "JMath/JConstants.hh"
10
11#include "JDetector/JModule.hh"
15
16
17/**
18 * \file
19 *
20 * Detector support kit.
21 * \author mdejong
22 */
23namespace JDETECTOR {}
24namespace JPP { using namespace JDETECTOR; }
25
26namespace JDETECTOR {
27
28 using JLANG::JTypeList;
29 using JLANG::JTYPELIST;
30 using JLANG::JNullType;
31 using JLANG::JType;
34
35
36 static const double ORCA_TBARZ_M = 0.91; //!< ORCA T-bar position relative to seabed [m]
37 static const double ARCA_TBARZ_M = 0.95; //!< ORCA T-bar position relative to seabed [m]
38
39
40 /**
41 * Type definitions for different detectors.
42 */
43 struct JPPM_DU_t {}; //!< PPM_DU
44 struct JKM3NeT_t {}; //!< %KM3NeT default detector
45 struct JMonteCarlo_t {}; //!< Monte Carlo
46 struct JAntares_t {}; //!< %Antares
47 struct JObsolete_t {}; //!< obsolete detector
48 struct JKM3NeTFit_t {}; //!< %KM3NeT with cable swaps, etc. (see e.g. JPMTSwapDB.cc)
49
50
51 /**
52 * Type list of %KM3NeT detector types (specific detectors first).
53 */
55
56
57 /**
58 * Check validity of detector identifier.
59 *
60 * \param type detector type
61 * \param id detector identifier
62 * \return true if valid match; else false
63 */
64 inline bool hasDetector(JType<JPPM_DU_t> type, const int id) { return id == 1; }
65 inline bool hasDetector(JType<JKM3NeTFit_t> type, const int id) { return id >= 2 && id <= 2000000000; }
66 inline bool hasDetector(JType<JKM3NeT_t> type, const int id) { return id >= 2 && id <= 2000000000; }
67 inline bool hasDetector(JType<JMonteCarlo_t> type, const int id) { return id >= -2000000000 && id <= -2; }
68
69
70 /**
71 * Auxiliary interface for building detector.
72 */
75 {
76 /**
77 * Get module.
78 *
79 * The configuration of module is according internal module address map.
80 *
81 * \param id module identifier
82 * \param location module location
83 * \return module
84 */
85 const JModule& getModule(const int id = -1, const JLocation& location = JLocation()) const
86 {
87 module.setID(id);
88 module.setLocation(location);
89
90 const JModuleAddressMap& memo = this->get(id);
91
92 module.resize(memo.size());
93
94 if (memo.has( 0)) { module[memo[ 0].tdc] = JPMT( 1, JAxis3D(JVector3D(+0.000, +0.000, -0.200), JVersor3D(+0.000, +0.000, -1.000))); }
95
96 if (memo.has( 1)) { module[memo[ 1].tdc] = JPMT( 2, JAxis3D(JVector3D(+0.000, +0.105, -0.170), JVersor3D(+0.000, +0.527, -0.850))); }
97 if (memo.has( 2)) { module[memo[ 2].tdc] = JPMT( 3, JAxis3D(JVector3D(+0.091, +0.053, -0.170), JVersor3D(+0.456, +0.263, -0.850))); }
98 if (memo.has( 3)) { module[memo[ 3].tdc] = JPMT( 4, JAxis3D(JVector3D(+0.091, -0.053, -0.170), JVersor3D(+0.456, -0.263, -0.850))); }
99 if (memo.has( 4)) { module[memo[ 4].tdc] = JPMT( 5, JAxis3D(JVector3D(+0.000, -0.105, -0.170), JVersor3D(+0.000, -0.527, -0.850))); }
100 if (memo.has( 5)) { module[memo[ 5].tdc] = JPMT( 6, JAxis3D(JVector3D(-0.091, -0.053, -0.170), JVersor3D(-0.456, -0.263, -0.850))); }
101 if (memo.has( 6)) { module[memo[ 6].tdc] = JPMT( 7, JAxis3D(JVector3D(-0.091, +0.053, -0.170), JVersor3D(-0.456, +0.263, -0.850))); }
102
103 if (memo.has( 7)) { module[memo[ 7].tdc] = JPMT( 8, JAxis3D(JVector3D(+0.083, +0.144, -0.111), JVersor3D(+0.416, +0.720, -0.555))); }
104 if (memo.has( 8)) { module[memo[ 8].tdc] = JPMT( 9, JAxis3D(JVector3D(+0.166, +0.000, -0.111), JVersor3D(+0.832, +0.000, -0.555))); }
105 if (memo.has( 9)) { module[memo[ 9].tdc] = JPMT(10, JAxis3D(JVector3D(+0.083, -0.144, -0.111), JVersor3D(+0.416, -0.720, -0.555))); }
106 if (memo.has(10)) { module[memo[10].tdc] = JPMT(11, JAxis3D(JVector3D(-0.083, -0.144, -0.111), JVersor3D(-0.416, -0.720, -0.555))); }
107 if (memo.has(11)) { module[memo[11].tdc] = JPMT(12, JAxis3D(JVector3D(-0.166, +0.000, -0.111), JVersor3D(-0.832, +0.000, -0.555))); }
108 if (memo.has(12)) { module[memo[12].tdc] = JPMT(13, JAxis3D(JVector3D(-0.083, +0.144, -0.111), JVersor3D(-0.416, +0.720, -0.555))); }
109
110 if (memo.has(13)) { module[memo[13].tdc] = JPMT(14, JAxis3D(JVector3D(+0.000, +0.191, -0.059), JVersor3D(+0.000, +0.955, -0.295))); }
111 if (memo.has(14)) { module[memo[14].tdc] = JPMT(15, JAxis3D(JVector3D(+0.165, +0.096, -0.059), JVersor3D(+0.827, +0.478, -0.295))); }
112 if (memo.has(15)) { module[memo[15].tdc] = JPMT(16, JAxis3D(JVector3D(+0.165, -0.096, -0.059), JVersor3D(+0.827, -0.478, -0.295))); }
113 if (memo.has(16)) { module[memo[16].tdc] = JPMT(17, JAxis3D(JVector3D(+0.000, -0.191, -0.059), JVersor3D(+0.000, -0.955, -0.295))); }
114 if (memo.has(17)) { module[memo[17].tdc] = JPMT(18, JAxis3D(JVector3D(-0.165, -0.096, -0.059), JVersor3D(-0.827, -0.478, -0.295))); }
115 if (memo.has(18)) { module[memo[18].tdc] = JPMT(19, JAxis3D(JVector3D(-0.165, +0.096, -0.059), JVersor3D(-0.827, +0.478, -0.295))); }
116
117 if (memo.has(19)) { module[memo[19].tdc] = JPMT(20, JAxis3D(JVector3D(+0.096, +0.165, +0.059), JVersor3D(+0.478, +0.827, +0.295))); }
118 if (memo.has(20)) { module[memo[20].tdc] = JPMT(21, JAxis3D(JVector3D(+0.191, +0.000, +0.059), JVersor3D(+0.955, +0.000, +0.295))); }
119 if (memo.has(21)) { module[memo[21].tdc] = JPMT(22, JAxis3D(JVector3D(+0.096, -0.165, +0.059), JVersor3D(+0.478, -0.827, +0.295))); }
120 if (memo.has(22)) { module[memo[22].tdc] = JPMT(23, JAxis3D(JVector3D(-0.096, -0.165, +0.059), JVersor3D(-0.478, -0.827, +0.295))); }
121 if (memo.has(23)) { module[memo[23].tdc] = JPMT(24, JAxis3D(JVector3D(-0.191, +0.000, +0.059), JVersor3D(-0.955, +0.000, +0.295))); }
122 if (memo.has(24)) { module[memo[24].tdc] = JPMT(25, JAxis3D(JVector3D(-0.096, +0.165, +0.059), JVersor3D(-0.478, +0.827, +0.295))); }
123
124 if (memo.has(25)) { module[memo[25].tdc] = JPMT(26, JAxis3D(JVector3D(+0.000, +0.166, +0.111), JVersor3D(+0.000, +0.832, +0.555))); }
125 if (memo.has(26)) { module[memo[26].tdc] = JPMT(27, JAxis3D(JVector3D(+0.144, +0.083, +0.111), JVersor3D(+0.720, +0.416, +0.555))); }
126 if (memo.has(27)) { module[memo[27].tdc] = JPMT(28, JAxis3D(JVector3D(+0.144, -0.083, +0.111), JVersor3D(+0.720, -0.416, +0.555))); }
127 if (memo.has(28)) { module[memo[28].tdc] = JPMT(29, JAxis3D(JVector3D(+0.000, -0.166, +0.111), JVersor3D(+0.000, -0.832, +0.555))); }
128 if (memo.has(29)) { module[memo[29].tdc] = JPMT(30, JAxis3D(JVector3D(-0.144, -0.083, +0.111), JVersor3D(-0.720, -0.416, +0.555))); }
129 if (memo.has(30)) { module[memo[30].tdc] = JPMT(31, JAxis3D(JVector3D(-0.144, +0.083, +0.111), JVersor3D(-0.720, +0.416, +0.555))); }
130
131 configure();
132
133 module.compile();
134 module.set(JVector3D(0.0, 0.0, 0.0));
135
136 return module;
137 }
138
139 protected:
140 /**
141 * Configure module.
142 */
143 virtual void configure() const
144 {}
145
147 };
148
149
150 /**
151 * Template lookup table for detector builder.
152 *
153 * The template argument refers to a specific detector.\n
154 * This class should be specialised for each detector by providing an implementation of method getDefaultModuleAddressMap.\n
155 * In the constructor of the specialised class, the PMT cable swaps should be defined.\n
156 * Other features can be implemented in virtual method configure.
157 */
158 template<class JDetector_t>
160
161
162 /**
163 * Template specialisation of JDetectorBuilder for obsolete detector.
164 */
165 template<>
167 public JDetectorBuilder
168 {
169 public:
170 /**
171 * Default constructor.
172 */
175
176
177 /**
178 * Get default module address map.
179 *
180 * \return module address map
181 */
182 virtual const JModuleAddressMap& getDefaultModuleAddressMap() const override
183 {
184 static JModuleAddressMap memo;
185
186 if (memo.empty()) {
187
189
196
203
210
217
224
225 memo.configure();
226 }
227
228 return memo;
229 }
230 };
231
232
233 /**
234 * Template specialisation of JDetectorBuilder for PPM_DU detector.
235 */
236 template<>
238 public JDetectorBuilder
239 {
240 public:
241 /**
242 * Default constructor.
243 */
245 {
246 get(103).swap(24,30);
247 }
248
249
250 /**
251 * Get default module address map.
252 *
253 * \return module address map
254 */
255 virtual const JModuleAddressMap& getDefaultModuleAddressMap() const override
256 {
257 static JModuleAddressMap memo;
258
259 if (memo.empty()) {
260
262
269
276
283
290
297
298 memo.configure();
299 }
300
301 return memo;
302 }
303 };
304
305
306 /**
307 * Template specialisation of JDetectorBuilder for %KM3NeT detector.
308 */
309 template<>
311 public JDetectorBuilder
312 {
313 public:
314 /**
315 * Default constructor.
316 */
319
320
321 /**
322 * Get default module address map.
323 *
324 * \return module address map
325 */
326 virtual const JModuleAddressMap& getDefaultModuleAddressMap() const override
327 {
328 static JModuleAddressMap memo;
329
330 if (memo.empty()) {
331
333
340
347
354
361
368
369 memo.configure();
370 }
371
372 return memo;
373 }
374 };
375
376
377 /**
378 * Template specialisation of JDetectorBuilder for Monte Carlo detector.
379 */
380 template<>
382 public JDetectorBuilder
383 {
384 public:
385 /**
386 * Default constructor.
387 */
390
391
392 /**
393 * Get default module address map.
394 *
395 * \return module address map
396 */
397 virtual const JModuleAddressMap& getDefaultModuleAddressMap() const override
398 {
399 static JModuleAddressMap memo;
400
401 if (memo.empty()) {
402
404
411
418
425
432
439
440 memo.configure();
441 }
442
443 return memo;
444 }
445 };
446
447
448 /**
449 * Template specialisation of JDetectorBuilder for %KM3NeT detector with all known features.
450 */
451 template<>
453 public JDetectorBuilder_t<JKM3NeT_t>
454 {
455 public:
456 /**
457 * Default constructor.
458 */
460 {
461 // NCR A02904908
462
463 get(817802210).rotateL('B');
464
465 // https://elog.km3net.de/Analysis/721
466 // https://elog.km3net.de/Analysis/723
467
468 get(817351722).swapTDC(15, 17);
469 get(808972598).swapTDC(27, 28);
470 get(817315169).swapTDC(14, 18);
471 get(806481218).swapTDC( 9, 11);
472
473 get(817295048).rotateR('B');
474
475 // NCR A03733363
476
477 get(817565802).swapTDC( 3, 4);
478
479 // NCR A02922408
480
481 //get(817801283).swapTDC(22, 24);
482 //get(817801283).swapTDC(24, 26);
483
484 // https://git.km3net.de/working_groups/calibration/-/issues/154
485
486 get(805631219).swapTDC(23, 25);
487 get(805631219).swapTDC(24, 30);
488 get(810310870).swapTDC(12, 15);
489
490 get(805536976).rotateR('D');
491
492 // https://git.km3net.de/working_groups/calibration/-/issues/118
493
494 get(809069506).rotateL('D');
495
496 // https://git.km3net.de/working_groups/calibration/-/issues/162
497
498 get(817333258).swapTDC(6, 10);
499
500 // https://git.km3net.de/working_groups/calibration/-/issues/188
501
502 get(809099354).swapTDC( 9, 10);
503 get(809099354).swapTDC( 6, 8);
504 get(809099354).swapTDC( 3, 4);
505 get(809099354).swapTDC( 0, 2);
506 get(809099354).swapTDC( 1, 5);
507 get(809099354).swapTDC( 7, 11);
508
509 // https://git.km3net.de/working_groups/calibration/-/issues/193
510
511 get(809238362).swapTDC( 9, 11);
512
513 // https://git.km3net.de/working_groups/calibration/-/work_items/243
514
515 get(809094315).swapTDC(13,21);
516
517 // https://git.km3net.de/working_groups/calibration/-/work_items/252
518
519 get(810334835).rotateL('D');
520 }
521
522 protected:
523 /**
524 * Configure module.
525 */
526 virtual void configure() const override
527 {
528 using namespace JPP;
529
530 // https://elog.km3net.de/Analysis/723
531
532 if (module.getID() == 817802210) {
533 rotateLower(-60.0);
534 }
535
536 // https://git.km3net.de/auxiliary_data/calibration/-/issues/10
537
538 if (module.getID() == 817603901) {
539 rotateLower(+60.0);
540 }
541
542 // https://git.km3net.de/working_groups/calibration/-/issues/153
543
544 if (module.getID() == 810403184) {
545 rotateLower(-30.0);
546 }
547
548 // https://git.km3net.de/working_groups/calibration/-/issues/154
549
550 if (module.getID() == 805536812) {
551 rotateLower(+60.0);
552 }
553
554 // https://git.km3net.de/working_groups/calibration/-/issues/118
555
556 if (module.getID() == 809069506) {
557 rotateLower(-60.0);
558 }
559
560 // https://git.km3net.de/working_groups/calibration/-/work_items/252
561
562 if (module.getID() == 810334835) {
563 rotateLower(-60.0);
564 }
565 }
566
567
568 /**
569 * Rotate lower hemisphere clock-wise around z-axis.
570 *
571 * \param phi angle [deg]
572 */
573 void rotateLower(const double phi) const
574 {
575 using namespace JPP;
576
577 const JRotation3Z R(phi * PI / 180.0);
578
579 for (JModule::iterator pmt = module.begin(); pmt != module.end(); ++pmt) {
580 if (pmt->getDZ() < 0.0) {
581 pmt->rotate(R);
582 }
583 }
584 }
585 };
586
587
588 /**
589 * Get detector builder.
590 *
591 * \return detector builder
592 */
593 template<class JDetector_t>
595 {
597
598 return demo;
599 }
600
601
602 /**
603 * Get detector address map.
604 *
605 * \return detector address map
606 */
607 template<class JDetector_t>
612
613
614 /**
615 * Get module address map.
616 *
617 * \param id module identifier
618 * \return module address map
619 */
620 template<class JDetector_t>
625
626
627 /**
628 * Get PMT address translator for given module identifier and TDC channel.
629 *
630 * \param id module identifier
631 * \param tdc TDC
632 * \return PMT address translator
633 */
634 template<class JDetector_t>
635 inline const JPMTAddressTranslator& getPMTAddressTranslator(int id, int tdc)
636 {
638 }
639
640
641 /**
642 * Get PMT logical index for given module identifier and TDC channel.
643 *
644 * \param id module identifier
645 * \param tdc TDC
646 * \return PMT logical index
647 */
648 template<class JDetector_t>
649 inline int getPMTLogicalIndex(int id, int tdc)
650 {
652 }
653
654
655 /**
656 * Auxiliary class to extract detector address map from detector identifier.
657 */
658 template<class T>
660
661
662 template<class JHead_t, class JTail_t>
663 struct JDetectorHelper_t< JTypeList<JHead_t, JTail_t> >
664 {
665 /**
666 * Get detector address map.
667 *
668 * \param id detector identifier
669 * \return detector builder
670 */
671 static JDetectorBuilder& get(const int id)
672 {
673 if (hasDetector(JType<JHead_t>(), id))
675 else
677 }
678
679
680 /**
681 * Has detector address map.
682 *
683 * \param id detector identifier
684 * \return true if detector address map available; else false
685 */
686 static bool has(const int id)
687 {
689 }
690 };
691
692
693 template<class JHead_t>
695 {
696 /**
697 * Get detector address map.
698 *
699 * \param id detector identifier
700 * \return detector builder
701 */
702 static JDetectorBuilder& get(const int id)
703 {
704 if (hasDetector(JType<JHead_t>(), id))
706 else
707 THROW(JIndexOutOfRange, "getDetectorAddressMap<..>(" << id << ")" );
708 }
709
710
711 /**
712 * Has detector address map.
713 *
714 * \param id detector identifier
715 * \return true if detector address map available; else false
716 */
717 static bool has(const int id)
718 {
719 return hasDetector(JType<JHead_t>(), id);
720 }
721 };
722
723
724 /**
725 * Get detector builder.
726 *
727 * \param id detector identifier
728 * \return detector builder
729 */
731 {
733 }
734
735
736 /**
737 * Get detector address map.
738 *
739 * \param id detector identifier
740 * \return detector address map
741 */
746
747
748 /**
749 * Check if detector builder is available.
750 *
751 * \param id detector identifier
752 * \return true if detector builder available; else false
753 */
754 inline bool hasDetectorBuilder(const int id)
755 {
757 }
758
759
760 /**
761 * Check if detector address map is available.
762 *
763 * \param id detector identifier
764 * \return true if detector address map available; else false
765 */
766 inline bool hasDetectorAddressMap(const int id)
767 {
769 }
770
771
772 /**
773 * Get module according given detector type.
774 *
775 * \param type detector type
776 * \param id module identifier
777 * \param location module location
778 * \return module
779 */
780 template<class JDetector_t>
781 inline const JModule& getModule(const JType<JDetector_t> type,
782 const int id,
783 const JLocation& location = JLocation())
784 {
785 return getDetectorBuilder<JDetector_t>().getModule(id, location);
786 }
787
788
789 /**
790 * Get module according Antares detector type.
791 *
792 * \param type Antares detector type
793 * \param id module identifier
794 * \param location module location
795 * \return module
796 */
797 inline const JModule& getModule(const JType<JAntares_t> type,
798 const int id,
799 const JLocation& location = JLocation())
800 {
801 using namespace JPP;
802
803 static JModule module;
804
805 module.setID(id);
806
807 module.setLocation(location);
808
809 if (module.empty()) {
810
811 module.resize(3);
812
813 const double R = 0.5; // [m]
814
815 const double st = sin(0.75*PI);
816 const double ct = cos(0.75*PI);
817
818 for (int i = 0; i != 3; ++i) {
819
820 const double phi = (2.0*PI*i) / 3.0;
821 const double cp = cos(phi);
822 const double sp = sin(phi);
823
824 module[i] = JPMT(i, JAxis3D(JVector3D(R*st*cp, R*st*sp, R*ct), JVersor3D(st*cp, st*sp, ct)));
825 }
826 }
827
828 return module;
829 }
830
831
832 /**
833 * Get module according detector template.
834 *
835 * \param id module identifier
836 * \param location module location
837 * \return module
838 */
839 template<class JDetector_t>
840 inline const JModule& getModule(const int id,
841 const JLocation& location = JLocation())
842 {
843 return getModule(JType<JDetector_t>(), id, location);
844 }
845}
846
847#endif
848
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Mathematical constants.
Module support kit.
Data structure for optical module.
Lookup table for PMT addresses in detector.
const JModuleAddressMap & get(const int id) const
Get module address map.
virtual void configure() const override
Configure module.
void rotateLower(const double phi) const
Rotate lower hemisphere clock-wise around z-axis.
virtual const JModuleAddressMap & getDefaultModuleAddressMap() const override
Get default module address map.
virtual const JModuleAddressMap & getDefaultModuleAddressMap() const override
Get default module address map.
virtual const JModuleAddressMap & getDefaultModuleAddressMap() const override
Get default module address map.
virtual const JModuleAddressMap & getDefaultModuleAddressMap() const override
Get default module address map.
Template lookup table for detector builder.
Logical location of module.
Definition JLocation.hh:40
Lookup table for PMT addresses in optical module.
const JPMTAddressTranslator & getAddressTranslator(const int tdc) const
Get PMT address translator.
void configure()
Configure internal router.
int getIndex(const int tdc) const
Get PMT logical index for given TDC channel.
bool has(const int index) const
Test whether index is available.
Data structure for a composite optical module.
Definition JModule.hh:76
Data structure for PMT physical address.
Data structure for PMT readout address.
Rotation around Z-axis.
General exception.
Definition JException.hh:25
Exception for accessing an index in a collection that is outside of its range.
Definition JException.hh:92
file Auxiliary data structures and methods for detector calibration.
Definition JAnchor.hh:12
const JModule & getModule(const JType< JDetector_t > type, const int id, const JLocation &location=JLocation())
Get module according given detector type.
JDetectorBuilder & getDetectorBuilder()
Get detector builder.
static const double ORCA_TBARZ_M
ORCA T-bar position relative to seabed [m].
bool hasDetectorBuilder(const int id)
Check if detector builder is available.
const JPMTAddressTranslator & getPMTAddressTranslator(int id, int tdc)
Get PMT address translator for given module identifier and TDC channel.
static const double ARCA_TBARZ_M
ORCA T-bar position relative to seabed [m].
int getPMTLogicalIndex(int id, int tdc)
Get PMT logical index for given module identifier and TDC channel.
JDetectorAddressMap & getDetectorAddressMap()
Get detector address map.
JTYPELIST< JPPM_DU_t, JKM3NeTFit_t, JKM3NeT_t, JMonteCarlo_t >::typelist JDetectorTypes_t
Type list of KM3NeT detector types (specific detectors first).
bool hasDetectorAddressMap(const int id)
Check if detector address map is available.
JModuleAddressMap & getModuleAddressMap(int id)
Get module address map.
bool hasDetector(JType< JPPM_DU_t > type, const int id)
Check validity of detector identifier.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary interface for building detector.
virtual void configure() const
Configure module.
const JModule & getModule(const int id=-1, const JLocation &location=JLocation()) const
Get module.
static JDetectorBuilder & get(const int id)
Get detector address map.
static bool has(const int id)
Has detector address map.
static bool has(const int id)
Has detector address map.
static JDetectorBuilder & get(const int id)
Get detector address map.
Auxiliary class to extract detector address map from detector identifier.
KM3NeT with cable swaps, etc. (see e.g. JPMTSwapDB.cc)
KM3NeT default detector
Data structure to translate PMT physical to readout address.
Type definitions for different detectors.PPM_DU.
Auxiliary class for no type definition.
Definition JNullType.hh:19
Auxiliary class for recursive type list generation.
Definition JTypeList.hh:351
Type list.
Definition JTypeList.hh:23
Auxiliary class for a type holder.
Definition JType.hh:19