File indexing completed on 2025-01-18 10:01:24
0001
0002 #include <vector>
0003 #include <map>
0004
0005 #include <TRef.h>
0006 #include <TString.h>
0007
0008 #ifndef _CHERENKOV_DETECTOR_
0009 #define _CHERENKOV_DETECTOR_
0010
0011 #include "CherenkovPhotonDetector.h"
0012 class CherenkovMirrorGroup;
0013 class OpticalBoundary;
0014 class G4LogicalVolume;
0015
0016 class CherenkovDetector: public TObject {
0017 public:
0018 CherenkovDetector(const char *name = 0): m_Name(name ? name : ""),
0019 m_ReadoutCellMask(0x0) {};
0020 ~CherenkovDetector() {};
0021
0022 void AddOpticalBoundary(unsigned sector, OpticalBoundary *boundary) {
0023 _m_OpticalBoundaries[sector].push_back(boundary);
0024 };
0025
0026 void AddRadiator(const char *name, CherenkovRadiator *radiator) {
0027 _m_Radiators[name] = radiator;
0028 };
0029
0030
0031
0032 void AddPhotonDetector(CherenkovPhotonDetector *pd) {
0033 m_PhotonDetectors.push_back(pd);
0034 };
0035 void CreatePhotonDetectorInstance(unsigned sector, CherenkovPhotonDetector *pd,
0036 uint64_t icopy, ParametricSurface *surface) {
0037 auto irt = pd->AllocateIRT(sector, icopy);
0038
0039 if (_m_OpticalBoundaries.find(sector) != _m_OpticalBoundaries.end())
0040 for(auto boundary: _m_OpticalBoundaries[sector])
0041 irt->AddOpticalBoundary(boundary);
0042
0043 pd->AddItselfToOpticalBoundaries(irt, surface);
0044 };
0045
0046
0047
0048 std::map<TString, CherenkovRadiator*> &Radiators( void ) { return _m_Radiators; };
0049
0050
0051 std::map<unsigned, std::vector<OpticalBoundary*>> _m_OpticalBoundaries;
0052 std::vector<CherenkovPhotonDetector*> m_PhotonDetectors;
0053
0054
0055
0056 void SetContainerVolume(CherenkovRadiator *radiator) { m_ContainerVolume = radiator; };
0057 CherenkovRadiator *GetContainerVolume( void ) const {
0058 return dynamic_cast<CherenkovRadiator*>(m_ContainerVolume.GetObject()); };
0059 TRef m_ContainerVolume;
0060
0061 const char *GetName( void ) const { return m_Name.Data(); };
0062
0063 CherenkovRadiator *GetRadiator(const char *name) {
0064 if (_m_Radiators.find(name) == _m_Radiators.end()) return 0;
0065
0066 return _m_Radiators[name];
0067 };
0068
0069 void SetReadoutCellMask(uint64_t mask) { m_ReadoutCellMask = mask; };
0070 inline uint64_t GetReadoutCellMask( void ) const { return m_ReadoutCellMask; };
0071
0072
0073 unsigned GetSector(const TVector3 &pt) {
0074
0075 unsigned nSectors = _m_OpticalBoundaries.size();
0076
0077
0078 if (nSectors <= 1) return 0;
0079
0080
0081 double bin = 2*M_PI/nSectors, offset = -bin/2;
0082
0083 return (unsigned)floor((pt.Phi() + 4*M_PI - offset)/bin) % nSectors;
0084
0085 };
0086
0087
0088 CherenkovRadiator *GuessRadiator(const TVector3 &x0, const TVector3 &n0) {
0089
0090 if (_m_OpticalBoundaries.empty()) return 0;
0091
0092
0093 unsigned isec = GetSector(x0);
0094
0095
0096 for(auto rptr: _m_Radiators) {
0097 const auto radiator = rptr.second;
0098
0099
0100 auto s1 = radiator->GetFrontSide(isec);
0101 auto s2 = radiator->GetRearSide (isec);
0102
0103
0104 TVector3 from, to;
0105
0106 bool b1 = s1->GetCrossing(x0, -1*n0, &from, false);
0107 bool b2 = s2->GetCrossing(x0, n0, &to);
0108
0109 if (!b1 || !b2) continue;
0110
0111 if ((x0 - from).Dot(to - x0) > 0.0) return radiator;
0112 }
0113
0114
0115 return 0;
0116 };
0117
0118
0119 std::function<TVector3(long long int)> m_ReadoutIDToPosition;
0120
0121 private:
0122 TString m_Name;
0123
0124 uint64_t m_ReadoutCellMask;
0125
0126
0127
0128 std::map<TString, CherenkovRadiator*> _m_Radiators;
0129
0130
0131 #ifndef DISABLE_ROOT_IO
0132 ClassDef(CherenkovDetector, 5);
0133 #endif
0134 };
0135
0136 #endif