Jpp 19.3.0-rc.1
the software that should make you happy
Loading...
Searching...
No Matches
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"
16
17
18/**
19 * \author mdejong
20 */
21
22namespace JDETECTOR {}
23namespace JPP { using namespace JDETECTOR; }
24
25namespace 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.\ \".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) :
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:
637 };
638}
639
640#endif
Data structure for detector geometry and calibration.
Mathematical constants.
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Detector data structure.
Definition JDetector.hh:96
Logical location of module.
Definition JLocation.hh:40
Data structure for a composite optical module.
Definition JModule.hh:75
Auxiliary class for LCM logic parameters.
Auxiliary class for LCM logic parameters.
LCM_reverse_logic(const int __id, const int __lcm_id, const int __pmt_id)
Constructor.
Auxiliary class for OM cluster parameters.
OM(std::istream &in)
Constructor.
Auxiliary class for string parameters.
Monte Carlo detector (i.e. ".det" file).
JMonteCarloDetector(const bool useLogic)
Constructor.
void setUseLogic(const bool useLogic)
Set usage of logic.
static T find(T __begin, T __end, const int id)
Binary search method.
JMonteCarloDetector()
Default constructor.
friend std::istream & operator>>(std::istream &in, JMonteCarloDetector &detector)
Read detector from input.
JDetector & put(const int moduleID, const int pmtAddress, const JLocation &location, const JPMT &pmt)
Set PMT.
static bool compare(const JModule &first, const JModule &second)
Module comparator.
Data structure for PMT geometry, calibration and status.
Definition JPMT.hh:49
Data structure for angles in three dimensions.
Definition JAngle3D.hh:35
Axis object.
Definition JAxis3D.hh:41
Data structure for direction in three dimensions.
JDirection3D & transform(const JMatrix3D &T)
Transform.
Data structure for Euler angles in three dimensions.
Data structure for position in three dimensions.
void transform(const JRotation3D &R, const JVector3D &pos)
Transform position.
const JPosition3D & getPosition() const
Get position.
JVector3D & add(const JVector3D &vector)
Add vector.
Definition JVector3D.hh:142
JVector3D & div(const double factor)
Scale vector.
Definition JVector3D.hh:190
JVector3D & sub(const JVector3D &vector)
Subtract vector.
Definition JVector3D.hh:158
JVector3D & mul(const double factor)
Scale vector.
Definition JVector3D.hh:174
Auxiliary class for object identification.
Definition JObjectID.hh:25
int getID() const
Get identifier.
Definition JObjectID.hh:50
JComparator_t compare
Function object for comparisons.
Definition JRange.hh:565
std::string key
Definition JUTMGrid.hh:246
file Auxiliary data structures and methods for detector calibration.
Definition JAnchor.hh:12
static const int LED_BEACON_PMT_TYPE
PMT type of LED beacon.
const JObjectID & getUndefinedObjectID()
Get undefined object identifier.
Definition JObjectID.hh:149
static const double PI
Mathematical constants.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).