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