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