Jpp 19.3.0-rc.2
the software that should make you happy
Loading...
Searching...
No Matches
JModule.hh
Go to the documentation of this file.
1#ifndef __JDETECTOR__JMODULE__
2#define __JDETECTOR__JMODULE__
3
4#include <istream>
5#include <ostream>
6#include <vector>
7
10#include "JDetector/JPMT.hh"
12#include "Jeep/JStatus.hh"
13
18
19#include "JLang/JException.hh"
20#include "JMath/JMatrix3S.hh"
21#include "JMath/JMath.hh"
22
23#include "JIO/JSerialisable.hh"
24
25
26/**
27 * \file
28 *
29 * Data structure for optical module.
30 * \author mdejong
31 */
32namespace JDETECTOR {}
33namespace JPP { using namespace JDETECTOR; }
34
35namespace JDETECTOR {
36
44 using JEEP::JStatus;
46 using JIO::JReader;
47 using JIO::JWriter;
48
49
50 /**
51 * Data structure for a composite optical module.
52 *
53 * A module consists of a set of PMTs. A JPMT object is used for each PMT.\n
54 * The index of the PMT in the module corresponds to the readout channel (TDC).\n
55 * The quaternion data and time offset correspond to the calibration of the compass and piezo sensor inside the module, respectively.\n
56 * There are no PMTs and piezo sensor in the base module. The time offset then corresponds to the hydrophone.
57 * Note that the positions of the PMTs are absolute in space (i.e.\ not relative to the position of the module).
58 *
59 * The I/O of the position, quaternion data and time offset of the module depends on the detector version.\n
60 * The member method JModule::compile is used to set the position, quaternion data and time offset
61 * for detector versions for which these are not defined.\n
62 * In this, the position of the module is determined from the intersection point of the PMT axes.
63 *
64 * Note finally that the positions of the reference modules may not exactly be at the origin
65 * due to the finite accuracy of the PMT axes.\n
66 */
67 class JModule :
68 public JModuleIdentifier,
69 public JLocation,
70 public JPosition3D,
71 public JQuaternion3D,
72 public JCalibration,
73 public JStatus,
74 public std::vector<JPMT>
75 {
76 public:
77
78 using JStatus::has;
79 using JStatus::set;
80 using JStatus::reset;
81
82 /**
83 * Default constructor.
84 */
87 JLocation(),
91 JStatus(),
92 std::vector<JPMT>()
93 {}
94
95
96 /**
97 * Constructor.
98 *
99 * \param id identifier
100 * \param location location
101 */
102 JModule(const int id,
103 const JLocation& location) :
105 JLocation(location),
106 JPosition3D(),
108 JCalibration(),
109 JStatus(),
110 std::vector<JPMT>()
111 {}
112
113
114 /**
115 * Get detector version.
116 */
118 {
119 static JDetectorVersion version;
120
121 return version;
122 }
123
124
125 /**
126 * Set detector version.
127 *
128 * \param version version
129 */
130 static void setVersion(const JVersion& version)
131 {
132 getVersion() = JDetectorVersion(version);
133 }
134
135
136 /**
137 * Compare modules.
138 *
139 * The comparison only covers the orientations of the modules.
140 *
141 * \param first first module
142 * \param second second module
143 * \param precision precision
144 * \return true if two modules are equal; else false
145 */
146 static inline bool compare(const JModule& first,
147 const JModule& second,
148 const double precision = 1.0e-3)
149 {
150 if (first.size() == second.size()) {
151
152 for (size_t i = 0; i != first.size(); ++i) {
153 if (first[i].getDirection().getDot(second[i].getDirection()) < 1.0 - precision) {
154 return false;
155 }
156 }
157
158 return true;
159 }
160
161 return false;
162 }
163
164
165
166 /**
167 * Get PMT.
168 *
169 * \param index readout channel (TDC)
170 * \return PMT at given index
171 */
172 const JPMT& getPMT(const int index) const
173 {
174 return at(index);
175 }
176
177
178 /**
179 * Get PMT.
180 *
181 * \param index readout channel (TDC)
182 * \return PMT at given index
183 */
184 JPMT& getPMT(const int index)
185 {
186 return at(index);
187 }
188
189
190 /**
191 * Set PMT.
192 *
193 * \param index readout channel (TDC)
194 * \param pmt PMT
195 */
196 void setPMT(const int index, const JPMT& pmt)
197 {
198 if (index >= (int) size()) {
199 resize(index + 1);
200 }
201
202 (*this)[index] = pmt;
203 }
204
205
206 /**
207 * Get center of module based on crossing point of PMT axes.
208 *
209 * This method perform a fit of the crossing point of the PMT axes.\n
210 * A general purpose implementation of such a fit is available in JFIT::JEstimator<JPoint3D>.
211 *
212 * \return center
213 */
215 {
216 using namespace JPP;
217
218 if (this->size() > 1u) {
219
220 double x = 0;
221 double y = 0;
222 double z = 0;
223
224 JMatrix3S V;
225
226 for (const_iterator pmt = this->begin(); pmt != this->end(); ++pmt) {
227
228 const double xx = 1.0 - pmt->getDX() * pmt->getDX();
229 const double yy = 1.0 - pmt->getDY() * pmt->getDY();
230 const double zz = 1.0 - pmt->getDZ() * pmt->getDZ();
231
232 const double xy = -pmt->getDX() * pmt->getDY();
233 const double xz = -pmt->getDX() * pmt->getDZ();
234 const double yz = -pmt->getDY() * pmt->getDZ();
235
236 V.a00 += xx;
237 V.a01 += xy;
238 V.a02 += xz;
239
240 V.a11 += yy;
241 V.a12 += yz;
242
243 V.a22 += zz;
244
245 x += xx * pmt->getX() + xy * pmt->getY() + xz * pmt->getZ();
246 y += xy * pmt->getX() + yy * pmt->getY() + yz * pmt->getZ();
247 z += xz * pmt->getX() + yz * pmt->getY() + zz * pmt->getZ();
248 }
249
250 V.a10 = V.a01;
251 V.a20 = V.a02;
252 V.a21 = V.a12;
253
254 V.invert();
255
256 return JVector3D(V.a00 * x + V.a01 * y + V.a02 * z,
257 V.a10 * x + V.a11 * y + V.a12 * z,
258 V.a20 * x + V.a21 * y + V.a22 * z);
259
260 } else {
261 throw JValueOutOfRange("JModule::getCenter(): Not enough PMTs.");
262 }
263 }
264
265
266 /**
267 * Compile module data.
268 *
269 * For detector versions before JDetectorVersion::V4,
270 * the position,
271 * quaternion data and
272 * time offset of the module should be set.\n
273 * The position is set to the intersection point of the PMT axes (or their average position if this is not possible).\n
274 * The quaternion data are maintained.\n
275 * For an optical module (i.e.\ floor > 0),
276 * the time offset is set to the average time offset of the PMTs and
277 * for a base module (i.e.\ floor = 0),
278 * the time offset is set to zero.\n
279 * These time offsets should be corrected for delay in the piezo sensor and hydrophone, respectively.
280 */
281 void compile()
282 {
283 using namespace std;
284 using namespace JPP;
285
286 if (!this->empty()) {
287
288 JPosition3D& pos = this->getPosition();
289
290 try {
291 pos = this->getCenter();
292 }
293 catch(const exception&) {
294
295 pos = JPosition3D(0.0, 0.0, 0.0);
296
297 for (iterator i = this->begin(); i != this->end(); ++i) {
298 pos.add(i->getPosition());
299 }
300
301 pos.div(size());
302 }
303 }
304
305 this->setCalibration(getAverage(make_array(this->begin(), this->end(), &JModule::getT0), 0.0));
306 }
307
308
309 /**
310 * Rotate module.
311 *
312 * \param R rotation matrix
313 */
314 void rotate(const JRotation3D& R)
315 {
317
318 for (iterator i = this->begin(); i != this->end(); ++i) {
319 i->rotate(R);
320 }
321 }
322
323
324 /**
325 * Rotate back module.
326 *
327 * \param R rotation matrix
328 */
330 {
332
333 for (iterator i = this->begin(); i != this->end(); ++i) {
334 i->rotate_back(R);
335 }
336 }
337
338
339 /**
340 * Transformation of geometry (see method JGEOMETRY3D::JPosition3D::transform(const JRotation3D&, const JVector3D&)).
341 *
342 * \param R rotation matrix
343 * \param pos position of origin (after rotation)
344 */
345 void transform(const JRotation3D& R,
346 const JVector3D& pos)
347 {
349
350 for (iterator i = this->begin(); i != this->end(); ++i) {
351 i->transform(R, pos);
352 }
353 }
354
355
356 /**
357 * Transformation of geometry.
358 *
359 * \param T transformation
360 */
362 {
363 JPosition3D::transform(T.getRotation(), T.getPosition());
364
365 for (iterator i = this->begin(); i != this->end(); ++i) {
366 i->transform(T);
367 }
368 }
369
370
371 /**
372 * Rotate module.
373 *
374 * \param Q quaternion
375 */
376 void rotate(const JQuaternion3D& Q)
377 {
379
380 for (iterator i = this->begin(); i != this->end(); ++i) {
381 i->rotate(Q);
382 }
383 }
384
385
386 /**
387 * Rotate back module.
388 *
389 * \param Q quaternion
390 */
392 {
394
395 for (iterator i = this->begin(); i != this->end(); ++i) {
396 i->rotate_back(Q);
397 }
398 }
399
400
401 /**
402 * Set position.
403 *
404 * \param pos position
405 * \return this module
406 */
407 JModule& set(const JVector3D& pos)
408 {
409 return add(pos - this->getPosition());
410 }
411
412
413 /**
414 * Add position.
415 *
416 * \param pos position
417 * \return this module
418 */
419 JModule& add(const JVector3D& pos)
420 {
421 for (iterator i = begin(); i != end(); ++i) {
422 i->add(pos);
423 }
424
425 JPosition3D::add(pos);
426
427 return *this;
428 }
429
430
431 /**
432 * Subtract position.
433 *
434 * \param pos position
435 * \return this module
436 */
437 JModule& sub(const JVector3D& pos)
438 {
439 for (iterator i = begin(); i != end(); ++i) {
440 i->sub(pos);
441 }
442
443 JPosition3D::sub(pos);
444
445 return *this;
446 }
447
448
449 /**
450 * Set time offset.
451 *
452 * \param t0 time offset [ns]
453 * \return this module
454 */
455 JModule& set(const double t0)
456 {
457 for (iterator i = begin(); i != end(); ++i) {
458 i->setT0(t0);
459 }
460
461 return *this;
462 }
463
464
465 /**
466 * Add time offset.
467 *
468 * \param t0 time offset [ns]
469 * \return this module
470 */
471 JModule& add(const double t0)
472 {
473 for (iterator i = begin(); i != end(); ++i) {
474 i->addT0(t0);
475 }
476
477 return *this;
478 }
479
480
481 /**
482 * Subtract time offset.
483 *
484 * \param t0 time offset [ns]
485 * \return this module
486 */
487 JModule& sub(const double t0)
488 {
489 for (iterator i = begin(); i != end(); ++i) {
490 i->subT0(t0);
491 }
492
493 return *this;
494 }
495
496
497 /**
498 * Add position.
499 *
500 * \param pos position
501 * \return this module
502 */
504 {
505 return this->add(pos);
506 }
507
508
509 /**
510 * Subtract position.
511 *
512 * \param pos position
513 * \return this module
514 */
516 {
517 return this->sub(pos);
518 }
519
520
521 /**
522 * Read module from input.
523 *
524 * \param in input stream
525 * \param module module
526 * \return input stream
527 */
528 friend inline std::istream& operator>>(std::istream& in, JModule& module)
529 {
530 module = JModule();
531
532 in >> static_cast<JModuleIdentifier&>(module);
533 in >> static_cast<JLocation&> (module);
534
536 in >> static_cast<JPosition3D&> (module);
537 in >> static_cast<JQuaternion3D&>(module);
538 in >> static_cast<JCalibration&> (module);
539 }
540
542 in >> static_cast<JStatus&> (module);
543 }
544
545 unsigned int n;
546
547 in >> n;
548
549 for (JPMT pmt; n != 0 && in >> pmt; --n) {
550 module.push_back(pmt);
551 }
552
554 module.compile();
555 }
556
557 return in;
558 }
559
560
561 /**
562 * Write module to output.
563 *
564 * \param out output stream
565 * \param module module
566 * \return output stream
567 */
568 friend inline std::ostream& operator<<(std::ostream& out, const JModule& module)
569 {
570 using namespace std;
571
572 out << setw(10);
573 out << static_cast<const JModuleIdentifier&>(module);
574 out << ' ';
575 out << static_cast<const JLocation&> (module);
576
578 out << ' ';
579 out << static_cast<const JPosition3D&> (module);
580 out << ' ';
581 out << static_cast<const JQuaternion3D&>(module);
582 out << ' ';
583 out << static_cast<const JCalibration&> (module);
584 }
585
587 out << ' ';
588 out << static_cast<const JStatus&> (module);
589 }
590
591 out << ' ' << module.size() << endl;
592
593 for (const_iterator i = module.begin(); i != module.end(); ++i) {
594 out << ' ' << *i << endl;;
595 }
596
597 return out;
598 }
599
600
601 /**
602 * Read module from input.
603 *
604 * \param in reader
605 * \param module module
606 * \return rrreader
607 */
608 friend inline JReader& operator>>(JReader& in, JModule& module)
609 {
610 module = JModule();
611
612 in >> static_cast<JModuleIdentifier&>(module);
613 in >> static_cast<JLocation&> (module);
614
616 in >> static_cast<JPosition3D&> (module);
617 in >> static_cast<JQuaternion3D&>(module);
618 in >> static_cast<JCalibration&> (module);
619 }
620
622 in >> static_cast<JStatus&> (module);
623 }
624
625 int n;
626
627 in >> n;
628
629 module.resize(n);
630
631 for (JModule::iterator out = module.begin(); n != 0; --n, ++out) {
632 in >> *out;
633 }
634
636 module.compile();
637 }
638
639 return in;
640 }
641
642
643 /**
644 * Write module to output.
645 *
646 * \param out writer
647 * \param module module
648 * \return writer
649 */
650 friend inline JWriter& operator<<(JWriter& out, const JModule& module)
651 {
652 out << static_cast<const JModuleIdentifier&>(module);
653 out << static_cast<const JLocation&> (module);
654
656 out << static_cast<const JPosition3D&> (module);
657 out << static_cast<const JQuaternion3D&>(module);
658 out << static_cast<const JCalibration&> (module);
659 }
660
662 out << static_cast<const JStatus&> (module);
663 }
664
665 int n = module.size();
666
667 out << n;
668
669 for (const_iterator i = module.begin(); i != module.end(); ++i) {
670 out << *i;
671 }
672
673 return out;
674 }
675 };
676}
677
678#endif
Data structure for detector version.
Exceptions.
Logical location of module.
Base class for data structures with artithmetic capabilities.
Data structure for PMT geometry and calibration.
Data structure for time calibration.
double getT0() const
Get time offset.
void setCalibration(const JCalibration &cal)
Set calibration.
Logical location of module.
Definition JLocation.hh:40
Data structure for a composite optical module.
Definition JModule.hh:75
friend std::ostream & operator<<(std::ostream &out, const JModule &module)
Write module to output.
Definition JModule.hh:568
static JDetectorVersion & getVersion()
Get detector version.
Definition JModule.hh:117
JModule()
Default constructor.
Definition JModule.hh:85
void compile()
Compile module data.
Definition JModule.hh:281
JModule & operator-=(const JVector3D &pos)
Subtract position.
Definition JModule.hh:515
static void setVersion(const JVersion &version)
Set detector version.
Definition JModule.hh:130
void setPMT(const int index, const JPMT &pmt)
Set PMT.
Definition JModule.hh:196
JModule & set(const JVector3D &pos)
Set position.
Definition JModule.hh:407
JModule & set(const double t0)
Set time offset.
Definition JModule.hh:455
JModule & sub(const double t0)
Subtract time offset.
Definition JModule.hh:487
friend JWriter & operator<<(JWriter &out, const JModule &module)
Write module to output.
Definition JModule.hh:650
static bool compare(const JModule &first, const JModule &second, const double precision=1.0e-3)
Compare modules.
Definition JModule.hh:146
JModule & add(const double t0)
Add time offset.
Definition JModule.hh:471
friend JReader & operator>>(JReader &in, JModule &module)
Read module from input.
Definition JModule.hh:608
JVector3D getCenter() const
Get center of module based on crossing point of PMT axes.
Definition JModule.hh:214
JModule & add(const JVector3D &pos)
Add position.
Definition JModule.hh:419
void transform(const JRotation3D &R, const JVector3D &pos)
Transformation of geometry (see method JGEOMETRY3D::JPosition3D::transform(const JRotation3D&,...
Definition JModule.hh:345
void transform(const JTransformation3D &T)
Transformation of geometry.
Definition JModule.hh:361
JPMT & getPMT(const int index)
Get PMT.
Definition JModule.hh:184
void rotate(const JQuaternion3D &Q)
Rotate module.
Definition JModule.hh:376
JModule & operator+=(const JVector3D &pos)
Add position.
Definition JModule.hh:503
JModule(const int id, const JLocation &location)
Constructor.
Definition JModule.hh:102
void rotate(const JRotation3D &R)
Rotate module.
Definition JModule.hh:314
const JPMT & getPMT(const int index) const
Get PMT.
Definition JModule.hh:172
void rotate_back(const JRotation3D &R)
Rotate back module.
Definition JModule.hh:329
void rotate_back(const JQuaternion3D &Q)
Rotate back module.
Definition JModule.hh:391
JModule & sub(const JVector3D &pos)
Subtract position.
Definition JModule.hh:437
friend std::istream & operator>>(std::istream &in, JModule &module)
Read module from input.
Definition JModule.hh:528
Data structure for PMT geometry, calibration and status.
Definition JPMT.hh:49
Axis object.
Definition JAxis3D.hh:41
Data structure for position in three dimensions.
void transform(const JRotation3D &R, const JVector3D &pos)
Transform position.
JPosition3D & rotate(const JRotation3D &R)
Rotate.
double getDot(const JAngle3D &angle) const
Get dot product.
JPosition3D()
Default constructor.
const JPosition3D & getPosition() const
Get position.
JPosition3D & rotate_back(const JRotation3D &R)
Rotate back.
Data structure for unit quaternion in three dimensions.
Data structure for vector in three dimensions.
Definition JVector3D.hh:36
JVector3D & add(const JVector3D &vector)
Add vector.
Definition JVector3D.hh:142
JVector3D & div(const double factor)
Scale vector.
Definition JVector3D.hh:190
JVector3D()
Default constructor.
Definition JVector3D.hh:41
JVector3D & sub(const JVector3D &vector)
Subtract vector.
Definition JVector3D.hh:158
Data structure for normalised vector in three dimensions.
Definition JVersor3D.hh:28
Interface for binary input.
Interface for binary output.
Auxiliary class for object identification.
Definition JObjectID.hh:25
Exception for accessing a value in a collection that is outside of its range.
3 x 3 symmetric matrix
Definition JMatrix3S.hh:31
void invert()
Invert matrix.
Definition JMatrix3S.hh:80
file Auxiliary data structures and methods for detector calibration.
Definition JAnchor.hh:12
static const JGetDetectorVersion getDetectorVersion
Function object to map detector version to numerical value.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
@ V5
Version with module status field.
@ V4
Version with quaternion and time offset per module.
Auxiliary class for version identifier.
Auxiliary class for handling status.
Definition JStatus.hh:39
void set(const int bit)
Set PMT status.
Definition JStatus.hh:131
bool has(const int bit) const
Test PMT status.
Definition JStatus.hh:120
void reset(const int bit)
Reset PMT status.
Definition JStatus.hh:142