Jpp test-rotations-old-533-g2bdbdb559
the software that should make you happy
Loading...
Searching...
No Matches
JDetectorToolkit.hh
Go to the documentation of this file.
1#ifndef __JDETECTOR__JDETECTORTOOLKIT__
2#define __JDETECTOR__JDETECTORTOOLKIT__
3
4#include <limits>
5#include <istream>
6#include <ostream>
7#include <iostream>
8#include <fstream>
9#include <cmath>
10#include <vector>
11#include <set>
12#include <algorithm>
13#include <cstdlib>
14
26#include "JMath/JConstants.hh"
27#include "JMath/JMathToolkit.hh"
28#include "JTools/JRange.hh"
29#include "JIO/JFileStreamIO.hh"
30#include "Jeep/JeepToolkit.hh"
31#include "JLang/JException.hh"
32#include "JLang/gzstream.h"
33#include "JLang/JManip.hh"
34#include "JLang/Jpp.hh"
35
36
37/**
38 * \author mdejong
39 */
40
41namespace JDETECTOR {}
42namespace JPP { using namespace JDETECTOR; }
43
44/**
45 * Auxiliary classes and methods for detector calibration and simulation.
46 */
47namespace JDETECTOR {
48
54
55
56 /**
57 * File name extensions.
58 */
59 static const char* const GENDET_DETECTOR_FILE_FORMAT = "det"; //!< file format used by gendet
60 static const char* const BINARY_DETECTOR_FILE_FORMAT[] = { "dat", "datx" }; //!< JIO binary file format
61 static const char* const KM3NET_DETECTOR_FILE_FORMAT = "detx"; //!< %KM3NeT standard ASCII format
62 static const char* const ZIPPED_DETECTOR_FILE_FORMAT = "gz"; //!< zipped %KM3NeT standard ASCII format
63 static const char* const GDML_DETECTOR_FILE_FORMAT = "gdml"; //!< KM3Sim input format
64
65 static const char* const GDML_SCHEMA = getenv("GDML_SCHEMA_DIR"); //!< directory necessary for correct GDML header output
66 static const char* const CAN_MARGIN_M = getenv("CAN_MARGIN_M"); //!< extension of the detector size to comply with the can definition
67 static const char* const G4GDML_DEFAULT_SCHEMALOCATION = "http://service-spi.web.cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd";
68
69
70 /**
71 * Get maximal distance between modules in detector.
72 * The option can be used to include base modules, if any.
73 *
74 * \param detector detector
75 * \param option option
76 * \return maximal distance [m]
77 */
78 inline double getMaximalDistance(const JDetector& detector, const bool option = false)
79 {
80 using namespace JPP;
81
82 double dmax = 0.0;
83
84 for (JDetector::const_iterator i1 = detector.begin(); i1 != detector.end(); ++i1) {
85 for (JDetector::const_iterator i2 = detector.begin(); i2 != i1; ++i2) {
86
87 if (option || (i1->getFloor() != 0 && i2->getFloor() != 0)) {
88
89 const double ds = getDistance(i1->getPosition(), i2->getPosition());
90
91 if (ds > dmax) {
92 dmax = ds;
93 }
94 }
95 }
96 }
97
98 return dmax;
99 }
100
101
102 /**
103 * Get minimal distance between modules in detector.
104 *
105 * \param detector detector
106 * \return minimal distance [m]
107 */
109 {
110 using namespace std;
111 using namespace JPP;
112
113 double dmin = numeric_limits<double>::max();
114
115 for (JDetector::const_iterator i1 = detector.begin(); i1 != detector.end(); ++i1) {
116 for (JDetector::const_iterator i2 = detector.begin(); i2 != i1; ++i2) {
117
118 const double ds = getDistance(i1->getPosition(), i2->getPosition());
119
120 if (ds < dmin) {
121 dmin = ds;
122 }
123 }
124 }
125
126 return dmin;
127 }
128
129
130 /**
131 * Get maximal time between optical modules in detector following causality.
132 *
133 * \param detector detector
134 * \return maximal time [ns]
135 */
136 inline double getMaximalTime(const JDetector& detector)
137 {
138 using namespace JPP;
139
140 return getMaximalDistance(detector) * getIndexOfRefraction() * getInverseSpeedOfLight();
141 }
142
143
144 /**
145 * Get maximal time between optical modules in detector following causality.
146 * The road width corresponds to the maximal distance traveled by the light.
147 *
148 * \param detector detector
149 * \param roadWidth_m road width [m]
150 * \return maximal time [ns]
151 */
152 inline double getMaximalTime(const JDetector& detector, const double roadWidth_m)
153 {
154 using namespace JPP;
155
156 const double Dmax_m = getMaximalDistance(detector);
157
158 return (sqrt((Dmax_m + roadWidth_m*getSinThetaC()) *
159 (Dmax_m - roadWidth_m*getSinThetaC())) +
160 roadWidth_m * getSinThetaC() * getTanThetaC()) * getInverseSpeedOfLight();
161 }
162
163
164 /**
165 * Get de-calibrated time range.
166 *
167 * The de-calibrated time range is corrected for minimal and maximal time offset of PMTs in given module.
168 *
169 * \param timeRange time range [ns]
170 * \param module module
171 * \return time range [ns]
172 */
173 inline JTimeRange getTimeRange(const JTimeRange& timeRange, const JModule& module)
174 {
175 if (!module.empty()) {
176
178
179 for (JModule::const_iterator pmt = module.begin(); pmt != module.end(); ++pmt) {
180
181 const JCalibration& calibration = pmt->getCalibration();
182
183 time_range.include(putTime(timeRange.getLowerLimit(), calibration));
184 time_range.include(putTime(timeRange.getUpperLimit(), calibration));
185 }
186
187 return time_range;
188
189 } else {
190
191 return timeRange;
192 }
193 }
194
195
196 /**
197 * Get number of PMTs.
198 *
199 * \param module module
200 * \return number of PMTs
201 */
202 inline int getNumberOfPMTs(const JModule& module)
203 {
204 return module.size();
205 }
206
207
208 /**
209 * Get number of PMTs.
210 *
211 * \param detector detector
212 * \return number of PMTs
213 */
215 {
216 int number_of_pmts = 0;
217
218 for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
219 number_of_pmts += getNumberOfPMTs(*module);
220 }
221
222 return number_of_pmts;
223 }
224
225
226 /**
227 * Get list of strings identifiers.
228 *
229 * \param detector detector
230 * \return list of string identifiers
231 */
233 {
234 std::set<int> buffer;
235
236 for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
237 buffer.insert(module->getString());
238 }
239
240 return buffer;
241 }
242
243
244 /**
245 * Get list of modules identifiers.
246 *
247 * \param detector detector
248 * \param option option to include base modules
249 * \return list of module identifiers
250 */
251 inline std::set<int> getModuleIDs(const JDetector& detector, const bool option = false)
252 {
253 std::set<int> buffer;
254
255 for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
256 if (option || !module->empty()) {
257 buffer.insert(module->getID());
258 }
259 }
260
261 return buffer;
262 }
263
264
265 /**
266 * Get number of floors.
267 *
268 * \param detector detector
269 * \return number of floors
270 */
272 {
273 std::set<int> buffer;
274
275 for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
276 buffer.insert(module->getFloor());
277 }
278
279 return buffer.size();
280 }
281
282
283 /**
284 * Type definition for range of floors.
285 */
287
288
289 /**
290 * Get range of floors.
291 *
292 * \param detector detector
293 * \return range of floors
294 */
296 {
298
299 for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
300 buffer.include(module->getFloor());
301 }
302
303 return buffer;
304 }
305
306
307 /**
308 * Get number of modules.
309 *
310 * \param detector detector
311 * \param option option to include base modules
312 * \return number of modules
313 */
314 inline int getNumberOfModules(const JDetector& detector, const bool option = false)
315 {
316 std::set<int> buffer;
317
318 for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
319 if (option || !module->empty()) {
320 buffer.insert(module->getID());
321 }
322 }
323
324 return buffer.size();
325 }
326
327
328 /**
329 * Get rotation over X axis in Geant4 coordinate system
330 *
331 * \param dir direction
332 * \return X-rotation [deg]
333 */
334 inline double GetXrotationG4(const JVersor3D& dir)
335 {
336 using namespace JPP;
337
338 const double phi = atan2(dir.getDY(), dir.getDZ())*(180.0/PI);
339
340 if (phi < 0.0){
341 return phi + 360.0;
342 }
343 else{
344 return phi;
345 }
346 }
347
348
349 /**
350 * Get rotation over Y axis in Geant4 coordinate system
351 *
352 * \param dir direction
353 * \return Y-rotation [deg]
354 */
355 inline double GetYrotationG4(const JVersor3D& dir)
356 {
357 using namespace JPP;
358
359 return asin(-dir.getDX())*(180.0/PI);
360 }
361
362
363 inline void read_gdml(std::istream&, JDetector&)
364 {
365 THROW(JException, "Operation not defined.");
366 }
367
368
369 /**
370 * Writes KM3Sim GDML input file from detector
371 *
372 * \param out output stream
373 * \param detector detector
374 */
375 inline void write_gdml(std::ostream& out, const JDetector& detector)
376 {
377 using namespace std;
378 using namespace JPP;
379
380 const double DEFAULT_CAN_MARGIN_M = 350.0; // default can margin [m]
381 const double DEFAULT_WORLD_MARGIN_M = 50.0; // default world margin [m]
382
383 const JCylinder3D cylinder(detector.begin(), detector.end());
384
385 double can_margin;
386
387 if (CAN_MARGIN_M) {
388 can_margin = atof(CAN_MARGIN_M);
389 } else {
390 cerr << "CAN_MARGIN_M not defined! Setting standard CAN_MARGIN_M " << DEFAULT_CAN_MARGIN_M << " m." << endl;
391 can_margin = DEFAULT_CAN_MARGIN_M; //this is given in meters like all the dimensions in the GDML file (look at the unit field of every position and solid definition)
392 }
393
394 const double WorldCylinderHeight = 2*(cylinder.getZmax() - cylinder.getZmin() + can_margin + DEFAULT_WORLD_MARGIN_M);
395 const double WorldRadius = cylinder.getLength() + cylinder.getRadius() + can_margin + DEFAULT_WORLD_MARGIN_M;
396
397 const double Crust_Z_size = WorldCylinderHeight/2;
398 const double Crust_Z_position = -WorldCylinderHeight/4;
399
400 out << "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<gdml xmlns:gdml=\"http://cern.ch/2001/Schemas/GDML\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"";
401 if (!GDML_SCHEMA) {
402 cerr << "GDML_SCHEMA_DIR NOT DEFINED! Setting default path." << endl;
403 out << G4GDML_DEFAULT_SCHEMALOCATION << "\">\n\n\n";
404 } else {
405 out << GDML_SCHEMA << "gdml.xsd\">\n\n\n";
406 }
407 out << "<!-- Jpp version: "<< getGITVersion() << " -->\n";
408 out << "<define>\n";
409 out << "<rotation name=\"identity\"/>\n<position name=\"zero\"/>\n";
410
411 int PMTs_NO = 0;
412
413 for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
414
415 if(module->empty()) continue;
416
417 const JVector3D center = module->getCenter();
418
419 out << "<position name=\"PosString" << module->getString() << "_Dom" << module->getID() << "\" unit=\"m\" x=\"" << module->getX() << "\" y=\"" << module->getY() << "\" z=\"" << module->getZ() << "\"/>\n";
420
421 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
422
423 const JVector3D vec = static_cast<JVector3D>(*pmt).sub(center);
424 out << "<position name=\"CathodPosition" << pmt->getID() << "_" << module->getID() << "\" unit=\"m\" x=\"" << vec.getX() << "\" y=\"" << vec.getY() << "\" z=\"" << vec.getZ() << "\"/>\n";
425 out << "<rotation name=\"CathodRotation" << pmt->getID() << "_" << module->getID() << "\" unit=\"deg\" x=\"" << GetXrotationG4(*pmt) << "\" y=\"" << GetYrotationG4(*pmt) << "\" z=\"0.000000\"/>\n";
426 out << "<constant name=\"CathodID_" << PMTs_NO << "\" value=\"" << pmt->getID() << "\"/>\n";
427 PMTs_NO++;
428 }
429
430 }
431
432 out << "<position name=\"OMShift\" unit=\"m\" x=\"0\" y=\"0\" z=\"0.0392\"/>\n";
433 out << "\n\n\n";
434 out << "<!-- end of DU position definitions -->\n<position name=\"CrustPosition\" unit=\"m\" x=\"0\" y=\"0\" z=\"" << Crust_Z_position << "\"/>\n";
435
436 out << "</define>\n";
437 out << "<materials>\n";
438 out << "</materials>\n";
439 out << "<solids>\n";
440 out << " <box name=\"CrustBox\" lunit=\"m\" x=\"2200\" y=\"2200\" z=\"" << Crust_Z_size << "\"/>\n";
441 out << " <sphere name=\"OMSphere\" lunit=\"cm\" aunit=\"deg\" rmin=\"0.0\" rmax=\"21.6\" startphi=\"0.0\" deltaphi=\"360.0\" starttheta=\"0.0\" deltatheta=\"180.0\"/>\n";
442 out << " <tube name=\"CathodTube\" lunit=\"cm\" aunit=\"deg\" rmin=\"0.0\" rmax=\"4.7462\" z=\"0.5\" startphi=\"0.0\" deltaphi=\"360.0\"/>\n";
443 out << " <tube name=\"WorldTube\" lunit=\"m\" aunit=\"deg\" rmin=\"0.0\" rmax=\"" << WorldRadius << "\" z=\"" << WorldCylinderHeight << "\" startphi=\"0.0\" deltaphi=\"360.0\"/>\n";
444 out << "</solids>\n\n\n";
445
446 out << "<structure>\n";
447 out << " <volume name=\"CathodVolume\">\n";
448 out << " <materialref ref=\"Cathod\"/>\n";
449 out << " <solidref ref=\"CathodTube\"/>\n";
450 out << " </volume>\n";
451
452 out << "<!-- OMVolume(s) construction -->\n";
453
454 for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
455
456 if(module->empty()) continue;
457 out << " <volume name=\"OMVolume" << module->getID() << "\">\n";
458 out << " <materialref ref=\"Water\"/>\n";
459 out << " <solidref ref=\"OMSphere\"/>\n";
460
461 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
462 out << " <physvol>\n";
463 out << " <volumeref ref=\"CathodVolume\"/>\n";
464 out << " <positionref ref=\"CathodPosition" << pmt->getID() << "_" << module->getID() << "\"/>\n";
465 out << " <rotationref ref=\"CathodRotation" << pmt->getID() << "_" << module->getID() << "\"/>\n";
466 out << " </physvol>\n";
467 }
468
469 out << " </volume>\n";
470 }
471
472 out << "<!-- Crust Volume construction-->\n";
473 out << "<volume name=\"CrustVolume\">\n";
474 out << " <materialref ref=\"Crust\"/>\n";
475 out << " <solidref ref=\"CrustBox\"/>\n";
476 out << "</volume>\n";
477
478 out << "<!-- World Volume construction-->\n";
479 out << "<volume name=\"WorldVolume\">\n";
480 out << " <materialref ref=\"Water\"/>\n";
481 out << " <solidref ref=\"WorldTube\"/>\n";
482
483 out << " <physvol>\n";
484 out << " <volumeref ref=\"CrustVolume\"/>\n";
485 out << " <positionref ref=\"CrustPosition\"/>\n";
486 out << " <rotationref ref=\"identity\"/>\n";
487 out << " </physvol>\n";
488
489 for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
490 if(module->empty()) continue;
491 out << " <physvol>\n";
492 out << " <volumeref ref=\"OMVolume" << module->getID() << "\"/>\n";
493 out << " <positionref ref=\"PosString" << module->getString() << "_Dom" << module->getID() << "\"/>\n";
494 out << " <rotationref ref=\"identity\"/>\n";
495 out << " </physvol>\n";
496 }
497
498 out << "</volume>\n";
499
500 out << "</structure>\n";
501 out << "<setup name=\"Default\" version=\"1.0\">\n";
502 out << "<world ref=\"WorldVolume\"/>\n";
503 out << "</setup>\n";
504 out << "</gdml>\n";
505 }
506
507
508 /**
509 * Load detector from input file.
510 *
511 * Supported file formats:
512 * - ASCII file, extension JDETECTOR::GENDET_DETECTOR_FILE_FORMAT, gendet format;
513 * - binary file, extension JDETECTOR::BINARY_DETECTOR_FILE_FORMAT, Jpp internal format;
514 * - ASCII file, extension JDETECTOR::KM3NET_DETECTOR_FILE_FORMAT, %KM3NeT standard format;
515 * - gzipped file, extension JDETECTOR::ZIPPED_DETECTOR_FILE_FORMAT, %KM3NeT standard format;
516 *
517 * \param file_name file name
518 * \param detector detector
519 */
520 inline void load(const std::string& file_name, JDetector& detector)
521 {
522 using namespace std;
523 using namespace JPP;
524
525 if (getFilenameExtension(file_name) == GENDET_DETECTOR_FILE_FORMAT) {
526
527 JMonteCarloDetector buffer(true);
528
529 ifstream in(file_name.c_str());
530
531 if (!in) {
532 THROW(JFileOpenException, "File not opened for reading: " << file_name);
533 }
534
535 in >> buffer;
536
537 in.close();
538
539 detector.swap(buffer);
540
541 } else if (getFilenameExtension(file_name) == BINARY_DETECTOR_FILE_FORMAT[0] ||
542 getFilenameExtension(file_name) == BINARY_DETECTOR_FILE_FORMAT[1]) {
543
544 JFileStreamReader in(file_name.c_str());
545
546 if (!in) {
547 THROW(JFileOpenException, "File not opened for reading: " << file_name);
548 }
549
550 try {
551
552 detector.read(in);
553
554 } catch(const exception& error) {
555
556 // recovery procedure for old format of comments
557
559
560 in.clear();
561 in.rewind();
562
563 detector.read(in);
564
566 }
567
568 in.close();
569
570 } else if (getFilenameExtension(file_name) == KM3NET_DETECTOR_FILE_FORMAT) {
571
572 ifstream in(file_name.c_str());
573
574 if (!in) {
575 THROW(JFileOpenException, "File not opened for reading: " << file_name);
576 }
577
578 in >> detector;
579
580 in.close();
581
582 } else if (getFilenameExtension(file_name) == ZIPPED_DETECTOR_FILE_FORMAT) {
583
584 igzstream in(file_name.c_str());
585
586 if (!in) {
587 THROW(JFileOpenException, "File not opened for reading: " << file_name);
588 }
589
590 in >> detector;
591
592 in.close();
593
594 } else {
595
596 THROW(JProtocolException, "Protocol not defined: " << file_name);
597 }
598
599 if (!detector.hasVersion()) {
600 THROW(JValueOutOfRange, "Invalid version <" << detector.getVersion() << ">");
601 }
602 }
603
604
605 /**
606 * Store detector to output file.
607 *
608 * Supported file formats:
609 * - binary file, extension JDETECTOR::BINARY_DETECTOR_FILE_FORMAT, Jpp internal format;
610 * - ASCII file, extension JDETECTOR::KM3NET_DETECTOR_FILE_FORMAT, %KM3NeT standard format;
611 * - gzipped file, extension JDETECTOR::ZIPPED_DETECTOR_FILE_FORMAT, %KM3NeT standard format;
612 * - gdml file, extension JDETECTOR::GDML_DETECTOR_FILE_FORMAT, KM3Sim input format;
613 *
614 * \param file_name file name
615 * \param detector detector
616 */
617 inline void store(const std::string& file_name, const JDetector& detector)
618 {
619 using namespace std;
620 using namespace JPP;
621
622 if (getFilenameExtension(file_name) == BINARY_DETECTOR_FILE_FORMAT[1]) {
623
624 JFileStreamWriter out(file_name.c_str());
625
626 if (!out) {
627 THROW(JFileOpenException, "File not opened for writing: " << file_name);
628 }
629
630 detector.write(out);
631
632 out.close();
633
634 } else if (getFilenameExtension(file_name) == KM3NET_DETECTOR_FILE_FORMAT) {
635
636 std::ofstream out(file_name.c_str());
637
638 if (!out) {
639 THROW(JFileOpenException, "File not opened for writing: " << file_name);
640 }
641
642 out << detector;
643
644 out.close();
645
646 } else if (getFilenameExtension(file_name) == ZIPPED_DETECTOR_FILE_FORMAT) {
647
648 ogzstream out(file_name.c_str());
649
650 if (!out) {
651 THROW(JFileOpenException, "File not opened for writing: " << file_name);
652 }
653
654 out << detector;
655
656 out.close();
657
658 } else if (getFilenameExtension(file_name) == GDML_DETECTOR_FILE_FORMAT) {
659
660 std::ofstream out(file_name.c_str());
661
662 if (!out) {
663 THROW(JFileOpenException, "File not opened for writing: " << file_name);
664 }
665
666 write_gdml(out, detector);
667
668 out.close();
669
670 } else {
671
672 THROW(JProtocolException, "Protocol not defined: " << file_name);
673 }
674 }
675
676
677 /**
678 * Auxiliary class to get rotation matrix between two optical modules.
679 */
680 struct JRotation :
681 public JRotation3D
682 {
683
684 static const size_t NUMBER_OF_DIMENSIONS = 3; //!< Number of dimensions
685
686
687 /**
688 * Get rotation matrix to go from first to second module.
689 *
690 * \param first first module
691 * \param second second module
692 * \return rotation matrix
693 */
694 const JRotation3D& operator()(const JModule& first, const JModule& second)
695 {
696 this->setIdentity();
697
698 if (first.size() == second.size()) {
699
700 const size_t N = first.size();
701
702 if (N >= NUMBER_OF_DIMENSIONS) {
703
704 in .resize(N);
705 out.resize(N);
706
707 for (size_t i = 0; i != N; ++i) {
708 in [i] = first .getPMT(i).getDirection();
709 out[i] = second.getPMT(i).getDirection();
710 }
711
712 for (size_t i = 0; i != NUMBER_OF_DIMENSIONS; ++i) {
713 if (!orthonormalise(i)) {
714 THROW(JException, "Failure to orthonormalise direction " << i);
715 }
716 }
717
718 this->a00 = out[0].getX() * in[0].getX() + out[1].getX() * in[1].getX() + out[2].getX() * in[2].getX();
719 this->a01 = out[0].getX() * in[0].getY() + out[1].getX() * in[1].getY() + out[2].getX() * in[2].getY();
720 this->a02 = out[0].getX() * in[0].getZ() + out[1].getX() * in[1].getZ() + out[2].getX() * in[2].getZ();
721
722 this->a10 = out[0].getY() * in[0].getX() + out[1].getY() * in[1].getX() + out[2].getY() * in[2].getX();
723 this->a11 = out[0].getY() * in[0].getY() + out[1].getY() * in[1].getY() + out[2].getY() * in[2].getY();
724 this->a12 = out[0].getY() * in[0].getZ() + out[1].getY() * in[1].getZ() + out[2].getY() * in[2].getZ();
725
726 this->a20 = out[0].getZ() * in[0].getX() + out[1].getZ() * in[1].getX() + out[2].getZ() * in[2].getX();
727 this->a21 = out[0].getZ() * in[0].getY() + out[1].getZ() * in[1].getY() + out[2].getZ() * in[2].getY();
728 this->a22 = out[0].getZ() * in[0].getZ() + out[1].getZ() * in[1].getZ() + out[2].getZ() * in[2].getZ();
729
730 } else {
731
732 THROW(JException, "Module " << first.getID() << " size " << N << " < " << NUMBER_OF_DIMENSIONS);
733 }
734
735 } else {
736
737 THROW(JException, "Module " << first.getID() << " size " << first.size() << " != " << second.size());
738 }
739
740 return *this;
741 }
742
743 private:
744 /**
745 * Put normalised primary direction at specified index and orthoganilise following directions.\n
746 * This procedure follows Gram-Schmidt process.
747 *
748 * \param index index
749 * \param precision precision
750 * \return true if primary direction exists; else false
751 */
752 bool orthonormalise(const size_t index, const double precision = std::numeric_limits<double>::epsilon())
753 {
754 using namespace std;
755
756 size_t pos = index;
757
758 for (size_t i = index + 1; i != in.size(); ++i) {
759 if (in[i].getLengthSquared() > in[pos].getLengthSquared()) {
760 pos = i;
761 }
762 }
763
764 const double u = in[pos].getLength();
765
766 if (u > precision) {
767
768 in [pos] /= u;
769 out[pos] /= u;
770
771 if (pos != index) {
772 swap(in [pos], in [index]);
773 swap(out[pos], out[index]);
774 }
775
776 for (size_t i = index + 1; i != in.size(); ++i) {
777
778 const double dot = in[index].getDot(in[i]);
779
780 in [i] -= dot * in [index];
781 out[i] -= dot * out[index];
782 }
783
784 return true;
785
786 } else {
787
788 return false;
789 }
790 }
791
792
795 };
796
797
798 /**
799 * Function object to get rotation matrix to go from first to second module.
800 */
802
803
804 /**
805 * Get position to go from first to second module.
806 *
807 * \param first first module
808 * \param second second module
809 * \return position
810 */
811 inline JPosition3D getPosition(const JModule& first, const JModule& second)
812 {
813 return second.getPosition() - first.getPosition();
814 }
815
816
817 /**
818 * Get calibration to go from first to second calibration.
819 *
820 * \param first first calibration
821 * \param second second calibration
822 * \return calibration
823 */
824 inline JCalibration getCalibration(const JCalibration& first, const JCalibration& second)
825 {
826 return JCalibration(second.getT0() - first.getT0());
827 }
828}
829
830#endif
Data structure for detector geometry and calibration.
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Logical location of module.
I/O manipulators.
Binary methods for member methods.
Mathematical constants.
Physics constants.
Auxiliary class to define a range between two values.
Auxiliary methods for handling file names, type names and environment.
Jpp environment information.
Data structure for time calibration.
double getT0() const
Get time offset.
Detector data structure.
Definition JDetector.hh:96
static void setStartOfComment(const start_of_comment_type option)
Set option for short start of comment in binary I/O.
Definition JDetector.hh:589
Data structure for a composite optical module.
Definition JModule.hh:75
const JPMT & getPMT(const int index) const
Get PMT.
Definition JModule.hh:172
Monte Carlo detector (i.e. ".det" file).
double getRadius() const
Get radius.
Definition JCircle2D.hh:144
double getLength() const
Get length.
Definition JVector2D.hh:199
double getZmin() const
Get minimal z position.
double getZmax() const
Get maximal z position.
const JDirection3D & getDirection() const
Get direction.
Data structure for position in three dimensions.
const JPosition3D & getPosition() const
Get position.
Data structure for vector in three dimensions.
Definition JVector3D.hh:36
JVector3D & sub(const JVector3D &vector)
Subtract vector.
Definition JVector3D.hh:158
Data structure for normalised vector in three dimensions.
Definition JVersor3D.hh:28
double getDY() const
Get y direction.
Definition JVersor3D.hh:106
double getDX() const
Get x direction.
Definition JVersor3D.hh:95
double getDZ() const
Get z direction.
Definition JVersor3D.hh:117
Binary buffered file input.
virtual void clear() override
Clear status of reader.
Binary buffered file output.
void close()
Close file.
General exception.
Definition JException.hh:24
Exception for opening of file.
int getID() const
Get identifier.
Definition JObjectID.hh:50
Protocol exception.
Exception for accessing a value in a collection that is outside of its range.
JMatrix3D & setIdentity()
Set to identity matrix.
static JRange< double, std::less< double > > DEFAULT_RANGE()
Definition JRange.hh:555
range_type & include(argument_type x)
Include given value to range.
Definition JRange.hh:397
T getLowerLimit() const
Get lower limit.
Definition JRange.hh:202
T getUpperLimit() const
Get upper limit.
Definition JRange.hh:213
void close()
Definition gzstream.h:185
file Auxiliary data structures and methods for detector calibration.
Definition JAnchor.hh:12
int getNumberOfPMTs(const JModule &module)
Get number of PMTs.
static JRotation getRotation
Function object to get rotation matrix to go from first to second module.
int getNumberOfFloors(const JDetector &detector)
Get number of floors.
floor_range getRangeOfFloors(const JDetector &detector)
Get range of floors.
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
static const char *const GDML_DETECTOR_FILE_FORMAT
KM3Sim input format.
JCalibration getCalibration(const JCalibration &first, const JCalibration &second)
Get calibration to go from first to second calibration.
void write_gdml(std::ostream &out, const JDetector &detector)
Writes KM3Sim GDML input file from detector.
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file.
static const char *const ZIPPED_DETECTOR_FILE_FORMAT
zipped KM3NeT standard ASCII format
std::set< int > getStringIDs(const JDetector &detector)
Get list of strings identifiers.
static const char *const G4GDML_DEFAULT_SCHEMALOCATION
JPosition3D getPosition(const JModule &first, const JModule &second)
Get position to go from first to second module.
JTOOLS::JRange< int > floor_range
Type definition for range of floors.
double getMaximalTime(const JDetector &detector)
Get maximal time between optical modules in detector following causality.
static const char *const CAN_MARGIN_M
extension of the detector size to comply with the can definition
static const char *const KM3NET_DETECTOR_FILE_FORMAT
KM3NeT standard ASCII format
static const char *const GDML_SCHEMA
directory necessary for correct GDML header output
static const char *const GENDET_DETECTOR_FILE_FORMAT
File name extensions.
double GetYrotationG4(const JVersor3D &dir)
Get rotation over Y axis in Geant4 coordinate system.
int getNumberOfModules(const JDetector &detector, const bool option=false)
Get number of modules.
double getMinimalDistance(const JDetector &detector)
Get minimal distance between modules in detector.
double getMaximalDistance(const JDetector &detector, const bool option=false)
Get maximal distance between modules in detector.
double putTime(const T &t1, const JCalibration &cal)
Get de-calibrated time.
JTimeRange getTimeRange(const JTimeRange &timeRange, const JModule &module)
Get de-calibrated time range.
std::set< int > getModuleIDs(const JDetector &detector, const bool option=false)
Get list of modules identifiers.
double GetXrotationG4(const JVersor3D &dir)
Get rotation over X axis in Geant4 coordinate system.
void read_gdml(std::istream &, JDetector &)
static const char *const BINARY_DETECTOR_FILE_FORMAT[]
JIO binary file format.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Calibration.
Definition JHead.hh:330
Detector file.
Definition JHead.hh:227
Auxiliary class to get rotation matrix between two optical modules.
std::vector< JVector3D > out
const JRotation3D & operator()(const JModule &first, const JModule &second)
Get rotation matrix to go from first to second module.
std::vector< JVector3D > in
bool orthonormalise(const size_t index, const double precision=std::numeric_limits< double >::epsilon())
Put normalised primary direction at specified index and orthoganilise following directions.
static const size_t NUMBER_OF_DIMENSIONS
Number of dimensions.