Jpp  17.0.0-rc.1
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JMonteCarloDetector.hh
Go to the documentation of this file.
1 #ifndef __JDETECTOR__JMONTECARLODETECTOR__
2 #define __JDETECTOR__JMONTECARLODETECTOR__
3 
4 #include <string>
5 #include <istream>
6 #include <vector>
7 #include <cmath>
8 #include <algorithm>
9 
10 #include "JMath/JConstants.hh"
11 #include "JLang/JObjectID.hh"
12 #include "JDetector/JDetector.hh"
15 #include "JGeometry3D/JAngle3D.hh"
16 
17 
18 /**
19  * \author mdejong
20  */
21 
22 namespace JDETECTOR {}
23 namespace JPP { using namespace JDETECTOR; }
24 
25 namespace JDETECTOR {
26 
27  using JMATH::PI;
28  using JLANG::JObjectID;
35 
36 
37  static const int LED_BEACON_PMT_TYPE = 2; //!< PMT type of LED beacon
38 
39 
40  /**
41  * Monte Carlo detector (i.e.\ so-called .det file).
42  */
44  public JDetector
45  {
46  private:
47  /**
48  * Auxiliary class for OM
49  */
50  class OM :
51  public JObjectID
52  {
53  public:
54  /**
55  * Constructor.
56  *
57  * \param in input stream
58  */
59  OM(std::istream& in)
60  {
61  in >> static_cast<JObjectID&>(*this) >> pmtType >> serialNumber >> address;
62  }
63 
64  int pmtType; //!< PMT type
65  int serialNumber; //!< PMT serial number
66  int address; //!< address
67  };
68 
69 
70  /**
71  * Auxiliary class for OM cluster parameters
72  */
73  class OM_cluster :
74  public JObjectID,
75  public std::vector<int>
76  {
77  public:
78  /**
79  * Constructor.
80  *
81  * \param in input stream
82  */
83  OM_cluster(std::istream& in)
84  {
85  int n;
86 
87  in >> static_cast<JObjectID&>(*this) >> string_id >> z >> n;
88 
89  this->resize(n);
90 
91  iterator p = this->begin();
92 
93  for ( ; n != 0; --n, ++p)
94  in >> *p;
95  }
96 
97 
98  int string_id; //!< string identifier
99  double z; //!< z position
100  };
101 
102 
103  /**
104  * Auxiliary class for OM cluster data
105  */
107  public JObjectID
108  {
109  public:
110  /**
111  * Constructor.
112  *
113  * \param in input stream
114  */
115  OM_cluster_data(std::istream& in)
116  {
117  in >> static_cast<JObjectID&>(*this) >> x >> y >> z >> theta >> phi >> psi;
118  }
119 
120 
121  double x; //!< x position
122  double y; //!< y position
123  double z; //!< z position
124  double theta; //!< Euler angle
125  double phi; //!< Euler angle
126  double psi; //!< Euler angle
127  };
128 
129  /**
130  * Auxiliary class for OM position
131  */
132  class OM_position :
133  public JObjectID
134  {
135  public:
136  /**
137  * Constructor.
138  *
139  * \param in input stream
140  */
141  OM_position(std::istream& in)
142  {
143  in >> static_cast<JObjectID&>(*this) >> x >> y >> z >> theta >> phi;
144  }
145 
146 
147  double x; //!< x position
148  double y; //!< y position
149  double z; //!< z position
150  double theta; //!< zenit angle of orientation
151  double phi; //!< azimuth angle of orientation
152  };
153 
154 
155  /**
156  * Auxiliary class for string parameters
157  */
158  class String :
159  public JObjectID
160  {
161  public:
162  /**
163  * Constructor.
164  *
165  * \param in input stream
166  */
167  String(std::istream& in)
168  {
169  in >> static_cast<JObjectID&>(*this) >> x >> y >> z >> tOffset >> twist >> twistRate;
170  }
171 
172 
173  double x; //!< x position
174  double y; //!< y position
175  double z; //!< z position
176  double tOffset; //!< time offset
177  double twist; //!< twist offset
178  double twistRate; //!< twist rate
179  };
180 
181 
182  /**
183  * Auxiliary class for LCM logic parameters
184  */
185  class LCM_logic :
186  public JObjectID,
187  public std::vector<int>
188  {
189  public:
190  /**
191  * Constructor.
192  *
193  * \param in input stream
194  */
195  LCM_logic(std::istream& in)
196  {
197  int n;
198 
199  in >> static_cast<JObjectID&>(*this) >> string_id >> lcm_id >> n;
200 
201  this->resize(n);
202 
203  iterator p = this->begin();
204 
205  for ( ; n != 0; --n, ++p)
206  in >> *p;
207  }
208 
209  int string_id; //!< string identifier
210  int lcm_id; //!< LCM identifier
211  };
212 
213 
214  /**
215  * Auxiliary class for LCM logic parameters
216  */
218  public JObjectID
219  {
220  public:
221  /**
222  * Default constructor.
223  */
225  JObjectID(),
226  lcm_id(-1),
227  pmt_id(-1)
228  {}
229 
230 
231  /**
232  * Constructor.
233  *
234  * \param __id identifier
235  * \param __lcm_id LCM identifier
236  * \param __pmt_id PMT identifier
237  */
239  const int __lcm_id,
240  const int __pmt_id) :
241  JObjectID(__id),
242  lcm_id (__lcm_id),
243  pmt_id (__pmt_id)
244  {}
245 
246 
247  int lcm_id; //!< LCM identifier
248  int pmt_id; //!< PMT identifier
249  };
250 
251 
252  public:
253  /**
254  * Default constructor.
255  */
257  JDetector(),
258  use_logic(false)
259  {}
260 
261 
262  /**
263  * Constructor.
264  *
265  * \param useLogic apply logic data in file
266  */
267  JMonteCarloDetector(const bool useLogic) :
268  JDetector(),
269  use_logic(useLogic)
270  {}
271 
272 
273 
274  /**
275  * Read detector from input.
276  *
277  * \param in input stream
278  * \param detector detector
279  * \return input stream
280  */
281  friend inline std::istream& operator>>(std::istream& in, JMonteCarloDetector& detector)
282  {
283  using namespace std;
284 
285  detector.clear();
286 
287 
288  vector<OM> OMaddress;
289  vector<OM_cluster> OMcluster;
290  vector<OM_position> OMposition;
291  vector<String> DetectorString;
292  vector<OM_cluster_data> OMclusterdata;
293  vector<LCM_logic> LCMlogic;
294 
295 
296  for (string key, buffer; in >> key; ) {
297 
298  if (key == "OM:")
299 
300  OMaddress.push_back(OM(in));
301 
302  else if (key == "OM_cluster:")
303 
304  OMcluster.push_back(OM_cluster(in));
305 
306  else if (key == "OM_position:")
307 
308  OMposition.push_back(OM_position(in));
309 
310  else if (key == "string:")
311 
312  DetectorString.push_back(String(in));
313 
314  else if (key == "OM_cluster_data:")
315 
316  OMclusterdata.push_back(OM_cluster_data(in));
317 
318  else if (key == "LCM_logic:")
319 
320  LCMlogic.push_back(LCM_logic(in));
321 
322  else
323 
324  getline(in, buffer);
325  }
326 
327 
328  // invert LCM_Logic data for fast lookup
329 
330  vector<LCM_reverse_logic> LCMreverselogic;
331 
332  for (vector<LCM_logic>::const_iterator i = LCMlogic.begin(); i != LCMlogic.end(); ++i) {
333 
334  const int lcm_id = i->getID();
335 
336  for (LCM_logic::const_iterator j = i->begin(); j != i->end(); ++j) {
337 
338  const int id = *j;
339  const int pmt_id = distance(i->begin(),j) + 1;
340 
341  LCMreverselogic.push_back(LCM_reverse_logic(id, lcm_id, pmt_id));
342  }
343  }
344 
345 
346  // sort data according to identifier
347 
348  sort(OMaddress .begin(), OMaddress .end());
349  sort(OMcluster .begin(), OMcluster .end());
350  sort(OMposition .begin(), OMposition .end());
351  sort(DetectorString .begin(), DetectorString .end());
352  sort(LCMreverselogic.begin(), LCMreverselogic.end());
353 
354 
355  vector<OM_cluster> ::const_iterator OMclusterIterator;
356  vector<String> ::const_iterator StringIterator;
357  vector<int> ::const_iterator addressIterator;
358  vector<OM> ::const_iterator OMIterator;
359  vector<OM_position> ::const_iterator OMpositionIterator;
360  vector<OM_cluster_data>::const_iterator OMclusterdataIterator;
361 
362 
363  for (OMclusterIterator = OMcluster.begin();
364  OMclusterIterator != OMcluster.end();
365  OMclusterIterator++) {
366 
367  StringIterator = find(DetectorString.begin(),
368  DetectorString.end(),
369  OMclusterIterator->string_id);
370 
371  if (StringIterator != DetectorString.end()) {
372 
373  const JLocation location(StringIterator->getID(), -1);
374 
375  for (addressIterator = OMclusterIterator->begin();
376  addressIterator != OMclusterIterator->end();
377  addressIterator++) {
378 
379  OMIterator = find(OMaddress.begin(),
380  OMaddress.end(),
381  *addressIterator);
382 
383  if (OMIterator != OMaddress.end()) {
384 
385  OMpositionIterator = find(OMposition.begin(),
386  OMposition.end(),
387  OMIterator->address);
388 
389  if (OMpositionIterator != OMposition.end()) {
390 
391  // rotate string
392 
393  double ct = cos(StringIterator->twist * PI / 180.0);
394  double st = sin(StringIterator->twist * PI / 180.0);
395 
396  double x = ct * OMpositionIterator->x - st * OMpositionIterator->y;
397  double y = st * OMpositionIterator->x + ct * OMpositionIterator->y;
398 
399  JPosition3D pos(StringIterator->x + x,
400  StringIterator->y + y,
401  StringIterator->z + OMpositionIterator->z + OMclusterIterator->z);
402 
403  JDirection3D dir(JAngle3D(OMpositionIterator->theta,
404  StringIterator->twist * PI / 180.0 + OMpositionIterator->phi));
405 
406  int lcm_id = OMclusterIterator->getID();
407  int pmt_id = OMIterator->address;
408 
409  if (detector.use_logic) {
410 
411  vector<LCM_reverse_logic>::const_iterator p = find(LCMreverselogic.begin(),
412  LCMreverselogic.end(),
413  OMIterator->getID());
414 
415  if (p != LCMreverselogic.end()) {
416  lcm_id = p->lcm_id;
417  pmt_id = p->pmt_id;
418  }
419  }
420 
421  detector.put(lcm_id, pmt_id - 1, location, JPMT(OMIterator->getID(), JAxis3D(pos, dir)));
422  }
423  }
424  }
425  }
426  }
427 
428 
429  // 'event' data
430 
431  for (OMclusterdataIterator = OMclusterdata.begin();
432  OMclusterdataIterator != OMclusterdata.end();
433  OMclusterdataIterator++) {
434 
435  const JPosition3D P(OMclusterdataIterator->x,
436  OMclusterdataIterator->y,
437  OMclusterdataIterator->z);
438 
439  const JEulerMatrix3D R(JEulerAngle3D(OMclusterdataIterator->theta,
440  OMclusterdataIterator->phi,
441  OMclusterdataIterator->psi));
442 
443  OMclusterIterator = find(OMcluster.begin(),
444  OMcluster.end(),
445  OMclusterdataIterator->getID());
446 
447  if (OMclusterIterator != OMcluster.end()) {
448 
449  const JLocation location(OMclusterIterator->string_id, -1);
450 
451  for (addressIterator = OMclusterIterator->begin();
452  addressIterator != OMclusterIterator->end();
453  addressIterator++) {
454 
455  OMIterator = find(OMaddress.begin(),
456  OMaddress.end(),
457  *addressIterator);
458 
459  if (OMIterator != OMaddress.end()) {
460 
461  OMpositionIterator = find(OMposition.begin(),
462  OMposition.end(),
463  OMIterator->address);
464 
465  if (OMpositionIterator != OMposition.end()) {
466 
467  JPosition3D pos(OMpositionIterator->x,
468  OMpositionIterator->y,
469  OMpositionIterator->z);
470 
471  JDirection3D dir(JAngle3D(OMpositionIterator->theta,
472  OMpositionIterator->phi));
473 
474  pos.transform(R);
475  dir.transform(R);
476 
477  pos += P;
478 
479  int lcm_id = OMclusterIterator->getID();
480  int pmt_id = OMIterator->address;
481 
482  if (detector.use_logic) {
483 
484  vector<LCM_reverse_logic>::const_iterator p = find(LCMreverselogic.begin(),
485  LCMreverselogic.end(),
486  OMIterator->getID());
487 
488  if (p != LCMreverselogic.end()) {
489  lcm_id = p->lcm_id;
490  pmt_id = p->pmt_id;
491  }
492  }
493 
494  detector.put(lcm_id, pmt_id - 1, location, JPMT(OMIterator->getID(), JAxis3D(pos, dir)));
495  }
496  }
497  }
498  }
499  }
500 
501  // set floor identifier
502 
503  sort(detector.begin(), detector.end(), JMonteCarloDetector::compare);
504 
505  int string = -1;
506  int floor = -1;
507 
508  for (JDetector::iterator module = detector.begin(); module != detector.end(); ++module) {
509 
510  if (module->getString() != string) {
511  string = module->getString();
512  floor = 0;
513  }
514 
515  module->setLocation(JLocation(string,++floor));
516  }
517 
518  return in;
519  }
520 
521 
522  /**
523  * Set usage of logic.
524  *
525  * \param useLogic apply logic data in file
526  */
527  void setUseLogic(const bool useLogic)
528  {
529  use_logic = useLogic;
530  }
531 
532 
533  protected:
534  /**
535  * Set PMT.
536  *
537  * \param moduleID module identifier
538  * \param pmtAddress PMT address
539  * \param location module location
540  * \param pmt JPMT
541  * \return this JDetector
542  */
543  JDetector& put(const int moduleID,
544  const int pmtAddress,
545  const JLocation& location,
546  const JPMT& pmt)
547  {
548  JDetector::iterator p = std::lower_bound(this->begin(), this->end(), moduleID);
549 
550  if (p == this->end() || p->getID() != moduleID) {
551 
552  JModule module(moduleID, location);
553 
554  module.resize(pmtAddress + 1);
555 
556  module[pmtAddress] = pmt;
557 
558  module.setPosition(pmt.getPosition());
559 
560  this->insert(p, module);
561 
562  } else {
563 
564  // average position
565 
566  int n = 0;
567 
568  for (JModule::const_iterator i = p->begin(); i != p->end(); ++i) {
569  if (i->getID() != getUndefinedObjectID().getID()) {
570  ++n;
571  }
572  }
573 
574  if (pmtAddress + 1 > (int) p->size()) {
575  p->resize(pmtAddress + 1);
576  }
577 
578  JPosition3D& P = static_cast<JPosition3D&>(*p);
579 
580  P.mul(n);
581 
582  if (p->at(pmtAddress).getID() != getUndefinedObjectID().getID())
583  P.sub(p->at(pmtAddress).getPosition());
584  else
585  ++n;
586 
587  P.add(pmt.getPosition());
588  P.div(n);
589 
590  p->at(pmtAddress) = pmt;
591  }
592 
593  return *this;
594  }
595 
596 
597  /**
598  * Binary search method.
599  *
600  * \param __begin begin of data
601  * \param __end end of data
602  * \param id target value
603  * \return pointer to corresponding element
604  */
605  template<class T>
606  static T find(T __begin, T __end, const int id)
607  {
608  T i = std::lower_bound(__begin, __end, id);
609 
610  if (i != __end && *i != id)
611  return __end;
612  else
613  return i;
614  }
615 
616 
617  /**
618  * Module comparator.\n
619  * The comparison is based on:
620  * -# string identifier;
621  * -# z-position.
622  *
623  * \param first first module
624  * \param second second module
625  * \return true if first module before second; else false
626  */
627  static bool compare(const JModule& first, const JModule& second)
628  {
629  if (first.getString() == second.getString())
630  return first.getZ() < second.getZ();
631  else
632  return first.getString() < second.getString();
633  }
634 
635  private:
636  bool use_logic;
637  };
638 }
639 
640 #endif
Data structure for angles in three dimensions.
Definition: JAngle3D.hh:33
Data structure for Euler angles in three dimensions.
String(std::istream &in)
Constructor.
JVector3D & mul(const double factor)
Scale vector.
Definition: JVector3D.hh:174
OM_cluster(std::istream &in)
Constructor.
Data structure for direction in three dimensions.
Definition: JDirection3D.hh:33
Data structure for a composite optical module.
Definition: JModule.hh:68
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
static const int LED_BEACON_PMT_TYPE
PMT type of LED beacon.
JMonteCarloDetector()
Default constructor.
Detector data structure.
Definition: JDetector.hh:89
static bool compare(const JModule &first, const JModule &second)
Module comparator.
LCM_logic(std::istream &in)
Constructor.
void setUseLogic(const bool useLogic)
Set usage of logic.
JDirection3D & transform(const JMatrix3D &T)
Transform.
Data structure for detector geometry and calibration.
void transform(const JRotation3D &R, const JVector3D &pos)
Transform position.
Definition: JPosition3D.hh:331
Axis object.
Definition: JAxis3D.hh:38
Monte Carlo detector (i.e. so-called .det file).
const int n
Definition: JPolint.hh:676
OM(std::istream &in)
Constructor.
double theta
zenit angle of orientation
JVector3D & sub(const JVector3D &vector)
Subtract vector.
Definition: JVector3D.hh:158
std::string key
Definition: JUTMGrid.hh:246
JDetector & put(const int moduleID, const int pmtAddress, const JLocation &location, const JPMT &pmt)
Set PMT.
Logical location of module.
Definition: JLocation.hh:37
Mathematical constants.
static T find(T __begin, T __end, const int id)
Binary search method.
do set_variable OUTPUT_DIRECTORY $WORKDIR T
int getID() const
Get identifier.
Definition: JObjectID.hh:50
JMonteCarloDetector(const bool useLogic)
Constructor.
Data structure for PMT geometry, calibration and status.
Definition: JPMT.hh:43
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition: JString.hh:478
Auxiliary class for string parameters.
static const double PI
Mathematical constants.
Auxiliary class for LCM logic parameters.
const JPosition3D & getPosition() const
Get position.
Definition: JPosition3D.hh:130
then usage $script[distance] fi case set_variable R
Definition: JDrawLED.sh:43
Auxiliary class for OM cluster data.
Auxiliary class for LCM logic parameters.
int getString() const
Get string number.
Definition: JLocation.hh:134
friend std::istream & operator>>(std::istream &in, JMonteCarloDetector &detector)
Read detector from input.
Auxiliary class for object identification.
Definition: JObjectID.hh:22
const JObjectID & getUndefinedObjectID()
Get undefined object identifier.
Definition: JObjectID.hh:149
Auxiliary class for OM cluster parameters.
int j
Definition: JPolint.hh:682
Data structure for position in three dimensions.
Definition: JPosition3D.hh:36
double phi
azimuth angle of orientation
LCM_reverse_logic(const int __id, const int __lcm_id, const int __pmt_id)
Constructor.
JVector3D & div(const double factor)
Scale vector.
Definition: JVector3D.hh:190
do set_variable DETECTOR_TXT $WORKDIR detector
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
Definition: JCanberra.sh:46
double getZ() const
Get z position.
Definition: JVector3D.hh:115
JVector3D & add(const JVector3D &vector)
Add vector.
Definition: JVector3D.hh:142
then $DIR JPlotNPE PDG P
Definition: JPlotNPE-PDG.sh:62
void setPosition(const JVector3D &pos)
Set position.
Definition: JPosition3D.hh:152