Jpp  master_rocky-37-gf0c5bc59d
the software that should make you happy
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 
9 #include "JDetector/JLocation.hh"
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  */
32 namespace JDETECTOR {}
33 namespace JPP { using namespace JDETECTOR; }
34 
35 namespace 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  */
85  JModule() :
87  JLocation(),
88  JPosition3D(),
89  JQuaternion3D(),
90  JCalibration(),
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) :
104  JModuleIdentifier(id),
105  JLocation(location),
106  JPosition3D(),
107  JQuaternion3D(),
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  */
329  void rotate_back(const JRotation3D& R)
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  {
348  JPosition3D::transform(R, pos);
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  {
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  */
391  void rotate_back(const JQuaternion3D& Q)
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 subT0(const double t0)
Subtract time offset.
void setCalibration(const JCalibration &cal)
Set calibration.
void setT0(const double t0)
Set time offset.
void addT0(const double t0)
Add time offset.
Logical location of module.
Definition: JLocation.hh:40
Data structure for a composite optical module.
Definition: JModule.hh:75
JModule()
Default constructor.
Definition: JModule.hh:85
void compile()
Compile module data.
Definition: JModule.hh:281
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
friend std::istream & operator>>(std::istream &in, JModule &module)
Read module from input.
Definition: JModule.hh:528
static bool compare(const JModule &first, const JModule &second, const double precision=1.0e-3)
Compare modules.
Definition: JModule.hh:146
JModule & add(const JVector3D &pos)
Add position.
Definition: JModule.hh:419
JModule & sub(const double t0)
Subtract time offset.
Definition: JModule.hh:487
JVector3D getCenter() const
Get center of module based on crossing point of PMT axes.
Definition: JModule.hh:214
static JDetectorVersion & getVersion()
Get detector version.
Definition: JModule.hh:117
friend JWriter & operator<<(JWriter &out, const JModule &module)
Write module to output.
Definition: JModule.hh:650
void transform(const JRotation3D &R, const JVector3D &pos)
Transformation of geometry (see method JGEOMETRY3D::JPosition3D::transform(const JRotation3D&,...
Definition: JModule.hh:345
JModule & operator-=(const JVector3D &pos)
Subtract position.
Definition: JModule.hh:515
void transform(const JTransformation3D &T)
Transformation of geometry.
Definition: JModule.hh:361
JModule & sub(const JVector3D &pos)
Subtract position.
Definition: JModule.hh:437
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
friend std::ostream & operator<<(std::ostream &out, const JModule &module)
Write module to output.
Definition: JModule.hh:568
void rotate(const JQuaternion3D &Q)
Rotate module.
Definition: JModule.hh:376
const JPMT & getPMT(const int index) const
Get PMT.
Definition: JModule.hh:172
JModule(const int id, const JLocation &location)
Constructor.
Definition: JModule.hh:102
JModule & set(const JVector3D &pos)
Set position.
Definition: JModule.hh:407
JModule & operator+=(const JVector3D &pos)
Add position.
Definition: JModule.hh:503
void rotate(const JRotation3D &R)
Rotate module.
Definition: JModule.hh:314
JModule & set(const double t0)
Set time offset.
Definition: JModule.hh:455
void rotate_back(const JRotation3D &R)
Rotate back module.
Definition: JModule.hh:329
JPMT & getPMT(const int index)
Get PMT.
Definition: JModule.hh:184
void rotate_back(const JQuaternion3D &Q)
Rotate back module.
Definition: JModule.hh:391
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.
Definition: JPosition3D.hh:38
JPosition3D & rotate(const JRotation3D &R)
Rotate.
Definition: JPosition3D.hh:186
const JPosition3D & getPosition() const
Get position.
Definition: JPosition3D.hh:130
double getDot(const JVector3D &vector) const
Get dot product.
Definition: JVector3D.hh:282
JPosition3D()
Default constructor.
Definition: JPosition3D.hh:48
JPosition3D & rotate_back(const JRotation3D &R)
Rotate back.
Definition: JPosition3D.hh:200
JVector3D & transform(const JMatrix3D &T)
Transform.
Definition: JVector3D.hh:206
Data structure for unit quaternion in three dimensions.
Rotation matrix.
Definition: JRotation3D.hh:114
const JRotation3D & getRotation() const
Get rotation.
Definition: JRotation3D.hh:272
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.
Definition: JException.hh:180
3 x 3 symmetric matrix
Definition: JMatrix3S.hh:31
void invert()
Invert matrix.
Definition: JMatrix3S.hh:80
JDirection3D getDirection(const Vec &dir)
Get direction.
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.
const array_type< JValue_t > & make_array(const JValue_t(&array)[N])
Method to create array of values.
Definition: JVectorize.hh:54
std::iterator_traits< T >::value_type getAverage(T __begin, T __end)
Get average.
Definition: JMath.hh:494
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
const int n
Definition: JPolint.hh:786
Definition: JSTDTypes.hh:14
@ 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