File indexing completed on 2025-12-10 10:18:05
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 CherenkovDetector *AddNewDetector(const char *name) {
0028 auto det = new CherenkovDetector(name);
0029 m_Detectors[det->GetName()] = det;
0030
0031 return det;
0032 };
0033
0034
0035
0036
0037 CherenkovRadiator *FindOrAddRadiator(CherenkovDetector *det, const char *name, const G4LogicalVolume *volume,
0038 const G4RadiatorMaterial *material) {
0039 auto radiator = FindRadiator(volume);
0040
0041 if (!radiator) {
0042 radiator = new CherenkovRadiator(volume, material);
0043 det->AddRadiator(name, radiator);
0044
0045 m_RadiatorLookup[volume] = radiator;
0046 }
0047
0048 return radiator;
0049 };
0050 CherenkovRadiator *AddFlatRadiator(CherenkovDetector *det, const char *name, CherenkovDetector::ud where, unsigned path,
0051 const G4LogicalVolume *volume,
0052 const G4RadiatorMaterial *material, const FlatSurface *surface,
0053 double thickness) {
0054 auto radiator = FindOrAddRadiator(det, name, volume, material);
0055
0056
0057
0058 {
0059 auto boundary = surface->_Clone(0.0, TVector3(0,0,1));
0060 boundary->Shift(( thickness/2)*surface->GetNormal());
0061 det->AddOpticalBoundary(where, path, new OpticalBoundary(radiator, boundary, true));
0062 radiator->m_Borders[path].first = boundary;
0063
0064
0065
0066 if (where == CherenkovDetector::Downstream && !det->GetContainerVolume()->GetRearSide(path))
0067 det->GetContainerVolume()->m_Borders[path].second = boundary;
0068 }
0069 {
0070 auto boundary = surface->_Clone(0.0, TVector3(0,0,1));
0071 boundary->Shift((-thickness/2)*surface->GetNormal());
0072 det->AddOpticalBoundary(where, path, new OpticalBoundary(det->GetContainerVolume(), boundary, true));
0073 radiator->m_Borders[path].second = boundary;
0074
0075
0076
0077 if (where == CherenkovDetector::Upstream) det->GetContainerVolume()->m_Borders[path].first = boundary;
0078 }
0079
0080 return radiator;
0081 };
0082 void AddRadiatorLogicalVolume(CherenkovRadiator *radiator, const G4LogicalVolume *lv) {
0083 radiator->AddLogicalVolume(lv);
0084 m_RadiatorLookup[lv] = radiator;
0085 };
0086
0087
0088
0089 void AddPhotonDetector(CherenkovDetector *det, const G4LogicalVolume *lv,
0090 CherenkovPhotonDetector *pd) {
0091
0092 if (FindPhotonDetector(lv)) return;
0093
0094 det->AddPhotonDetector(pd);
0095
0096 m_PhotonDetectorLookup[lv] = pd;
0097 };
0098
0099
0100
0101 inline CherenkovRadiator *FindRadiator(const G4LogicalVolume *lv) {
0102 return (m_RadiatorLookup.find(lv) == m_RadiatorLookup.end() ? 0 : m_RadiatorLookup[lv]);
0103 };
0104 inline CherenkovMirror *FindMirror(const G4LogicalVolume *lv) {
0105 return (m_MirrorLookup.find(lv) == m_MirrorLookup.end() ? 0 : m_MirrorLookup[lv]);
0106 };
0107 inline void AddMirrorLookupEntry(const G4LogicalVolume *lv, CherenkovMirror *mirror) {
0108 m_MirrorLookup[lv] = mirror;
0109 };
0110 inline void AddPhotonDetectorLookupEntry(const G4LogicalVolume *lv, CherenkovPhotonDetector *pd) {
0111 m_PhotonDetectorLookup[lv] = pd;
0112 };
0113 inline CherenkovPhotonDetector *FindPhotonDetector(const G4LogicalVolume *lv) {
0114 return (m_PhotonDetectorLookup.find(lv) == m_PhotonDetectorLookup.end() ? 0 : m_PhotonDetectorLookup[lv]);
0115 };
0116
0117 CherenkovRadiator *SetContainerVolume(CherenkovDetector *det, const char *name, unsigned path,
0118 const G4LogicalVolume *lv,
0119 const G4RadiatorMaterial *material,
0120 ParametricSurface *surface) {
0121 auto radiator = FindOrAddRadiator(det, name, lv, material);
0122
0123 radiator->m_Borders[path].first = surface;
0124
0125 det->AddOpticalBoundary(CherenkovDetector::Upstream, path, new OpticalBoundary(FindRadiator(lv), surface, true));
0126
0127 det->SetContainerVolume(radiator);
0128
0129 return radiator;
0130 };
0131
0132
0133 CherenkovDetector *GetDetectorByRadiator(const CherenkovRadiator *radiator) {
0134 for(auto detector: m_Detectors)
0135 for(auto ptr: detector.second->Radiators())
0136 if (ptr.second == radiator)
0137 return detector.second;
0138
0139 return 0;
0140 };
0141 CherenkovDetector *GetDetector(const char *name) {
0142 if (m_Detectors.find(name) == m_Detectors.end()) return 0;
0143
0144 return m_Detectors[name];
0145 };
0146 const std::map<TString, CherenkovDetector*> &GetDetectors( void ) const {
0147 return m_Detectors;
0148 };
0149
0150
0151
0152 private:
0153 std::map<const G4LogicalVolume*, CherenkovRadiator*> m_RadiatorLookup;
0154 std::map<const G4LogicalVolume*, CherenkovMirror*> m_MirrorLookup;
0155 std::map<const G4LogicalVolume*, CherenkovPhotonDetector*> m_PhotonDetectorLookup;
0156
0157 std::map<TString, CherenkovDetector*> m_Detectors;
0158
0159
0160
0161 #ifndef DISABLE_ROOT_IO
0162 ClassDef(CherenkovDetectorCollection, 3);
0163 #endif
0164 };
0165
0166 }