File indexing completed on 2026-03-28 08:35:16
0001 #pragma once
0002
0003 #include <map>
0004
0005 class G4LogicalVolume;
0006 class G4RadiatorMaterial;
0007 class G4OpticalSurface;
0008
0009 class CherenkovMirror;
0010 class CherenkovPhotonDetector;
0011
0012 #include "BitMask.h"
0013 #include "CherenkovDetector.h"
0014
0015 #define _STORE_ORPHAN_PHOTONS_ (0x00000001)
0016 #define _STORE_REFLECTION_POINTS_ (0x00000002)
0017 #define _STORE_REFRACTION_POINTS_ (0x00000003)
0018
0019 namespace IRT2 {
0020
0021 class CherenkovDetectorCollection: public BitMask {
0022 public:
0023 CherenkovDetectorCollection();
0024
0025 ~CherenkovDetectorCollection() {};
0026
0027 static CherenkovDetectorCollection *m_Instance;
0028 static CherenkovDetectorCollection *Instance() {
0029 return m_Instance ? m_Instance : new CherenkovDetectorCollection();
0030 };
0031
0032 CherenkovDetector *AddNewDetector(const char *name) {
0033 auto det = new CherenkovDetector(name);
0034 m_Detectors[det->GetName()] = det;
0035
0036 return det;
0037 };
0038
0039 CherenkovRadiator *FindOrAddRadiator(CherenkovDetector *det, const char *name, const G4LogicalVolume *volume,
0040 const G4RadiatorMaterial *material) {
0041 auto radiator = FindRadiator(volume);
0042
0043 if (!radiator) {
0044 radiator = new CherenkovRadiator(volume, material);
0045 det->AddRadiator(name, radiator);
0046
0047 m_RadiatorLookup[volume] = radiator;
0048 }
0049
0050 return radiator;
0051 };
0052 CherenkovRadiator *AddFlatRadiator(CherenkovDetector *det, const char *name, CherenkovDetector::ud where, unsigned path,
0053 const G4LogicalVolume *volume,
0054 const G4RadiatorMaterial *material, const FlatSurface *surface,
0055 double thickness) {
0056 auto radiator = FindOrAddRadiator(det, name, volume, material);
0057
0058
0059
0060 {
0061 auto boundary = surface->_Clone(0.0, TVector3(0,0,1));
0062 boundary->Shift(( thickness/2)*surface->GetNormal());
0063 det->AddOpticalBoundary(where, path, new OpticalBoundary(radiator, boundary, true));
0064 radiator->m_Borders[path].first = boundary;
0065
0066
0067
0068 if (where == CherenkovDetector::Downstream && !det->GetContainerVolume()->GetRearSide(path))
0069 det->GetContainerVolume()->m_Borders[path].second = boundary;
0070 }
0071 {
0072 auto boundary = surface->_Clone(0.0, TVector3(0,0,1));
0073 boundary->Shift((-thickness/2)*surface->GetNormal());
0074 det->AddOpticalBoundary(where, path, new OpticalBoundary(det->GetContainerVolume(), boundary, true));
0075 radiator->m_Borders[path].second = boundary;
0076
0077
0078
0079 if (where == CherenkovDetector::Upstream) det->GetContainerVolume()->m_Borders[path].first = boundary;
0080 }
0081
0082 return radiator;
0083 };
0084 void AddRadiatorLogicalVolume(CherenkovRadiator *radiator, const G4LogicalVolume *lv) {
0085 radiator->AddLogicalVolume(lv);
0086 m_RadiatorLookup[lv] = radiator;
0087 };
0088
0089
0090
0091 void AddPhotonDetector(CherenkovDetector *det, const G4LogicalVolume *lv,
0092 CherenkovPhotonDetector *pd) {
0093
0094 if (FindPhotonDetector(lv)) return;
0095
0096 det->AddPhotonDetector(pd);
0097
0098 m_PhotonDetectorLookup[lv] = pd;
0099 };
0100
0101
0102
0103 inline CherenkovRadiator *FindRadiator(const G4LogicalVolume *lv) {
0104 return (m_RadiatorLookup.find(lv) == m_RadiatorLookup.end() ? 0 : m_RadiatorLookup[lv]);
0105 };
0106 inline CherenkovMirror *FindMirror(const G4LogicalVolume *lv) {
0107 return (m_MirrorLookup.find(lv) == m_MirrorLookup.end() ? 0 : m_MirrorLookup[lv]);
0108 };
0109 inline void AddMirrorLookupEntry(const G4LogicalVolume *lv, CherenkovMirror *mirror) {
0110 m_MirrorLookup[lv] = mirror;
0111 };
0112 inline void AddPhotonDetectorLookupEntry(const G4LogicalVolume *lv, CherenkovPhotonDetector *pd) {
0113 m_PhotonDetectorLookup[lv] = pd;
0114 };
0115 inline CherenkovPhotonDetector *FindPhotonDetector(const G4LogicalVolume *lv) {
0116 return (m_PhotonDetectorLookup.find(lv) == m_PhotonDetectorLookup.end() ? 0 : m_PhotonDetectorLookup[lv]);
0117 };
0118
0119 CherenkovRadiator *SetContainerVolume(CherenkovDetector *det, const char *name, unsigned path,
0120 const G4LogicalVolume *lv,
0121 const G4RadiatorMaterial *material,
0122 ParametricSurface *surface) {
0123 auto radiator = FindOrAddRadiator(det, name, lv, material);
0124
0125 radiator->m_Borders[path].first = surface;
0126
0127 det->AddOpticalBoundary(CherenkovDetector::Upstream, path, new OpticalBoundary(FindRadiator(lv), surface, true));
0128
0129 det->SetContainerVolume(radiator);
0130
0131 return radiator;
0132 };
0133
0134
0135 CherenkovDetector *GetDetectorByRadiator(const CherenkovRadiator *radiator) {
0136 for(auto detector: m_Detectors)
0137 for(auto ptr: detector.second->Radiators())
0138 if (ptr.second == radiator)
0139 return detector.second;
0140
0141 return 0;
0142 };
0143 CherenkovDetector *GetDetector(const char *name) {
0144 if (m_Detectors.find(name) == m_Detectors.end()) return 0;
0145
0146 return m_Detectors[name];
0147 };
0148 const std::map<TString, CherenkovDetector*> &GetDetectors( void ) const {
0149 return m_Detectors;
0150 };
0151
0152
0153
0154 private:
0155 std::map<const G4LogicalVolume*, CherenkovRadiator*> m_RadiatorLookup;
0156 std::map<const G4LogicalVolume*, CherenkovMirror*> m_MirrorLookup;
0157 std::map<const G4LogicalVolume*, CherenkovPhotonDetector*> m_PhotonDetectorLookup;
0158
0159 std::map<TString, CherenkovDetector*> m_Detectors;
0160
0161
0162
0163 #ifndef DISABLE_ROOT_IO
0164 ClassDef(CherenkovDetectorCollection, 3);
0165 #endif
0166 };
0167
0168 }