Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-06-01 07:07:32

0001 
0002 #include <map>
0003 
0004 #ifndef _CHERENKOV_DETECTOR_COLLECTION_
0005 #define _CHERENKOV_DETECTOR_COLLECTION_
0006 
0007 class G4LogicalVolume;
0008 class G4RadiatorMaterial;
0009 class G4OpticalSurface;
0010 
0011 class CherenkovMirror;
0012 class CherenkovPhotonDetector;
0013 
0014 #include "BitMask.h"
0015 #include "CherenkovDetector.h"
0016 
0017 #define _STORE_ORPHAN_PHOTONS_    (0x00000001)
0018 #define _STORE_REFLECTION_POINTS_ (0x00000002)
0019 #define _STORE_REFRACTION_POINTS_ (0x00000003)
0020 
0021 class CherenkovDetectorCollection: public BitMask {
0022  public:
0023   CherenkovDetectorCollection() {};
0024   // FIXME: populate the dtor, for completeness;
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   CherenkovRadiator *FindOrAddRadiator(CherenkovDetector *det, const char *name, const G4LogicalVolume *volume, 
0035                  const G4RadiatorMaterial *material) {
0036     auto radiator = FindRadiator(volume);
0037     // FIXME: check consistency;
0038     if (!radiator) {
0039       radiator = new CherenkovRadiator(volume, material);
0040       det->AddRadiator(name, radiator);
0041 
0042       m_RadiatorLookup[volume] = radiator;
0043     } //if
0044 
0045     return radiator;
0046   };
0047   CherenkovRadiator *AddFlatRadiator(CherenkovDetector *det, const char *name, unsigned path, 
0048                      const G4LogicalVolume *volume, 
0049                      const G4RadiatorMaterial *material, const FlatSurface *surface, 
0050                      double thickness) {
0051     auto radiator = FindOrAddRadiator(det, name, volume, material);
0052 
0053     // Make a pair of local copies; they are stored in their respective class instances, 
0054     // therefore need two separate ones;
0055     {
0056       auto boundary = surface->_Clone(0.0, TVector3(0,0,1));
0057       boundary->Shift(( thickness/2)*surface->GetNormal());
0058       det->AddOpticalBoundary(path, new OpticalBoundary(radiator,                  boundary, true));
0059       radiator->m_Borders[path].first = boundary;
0060     }
0061     {
0062       auto boundary = surface->_Clone(0.0, TVector3(0,0,1));
0063       boundary->Shift((-thickness/2)*surface->GetNormal());
0064       det->AddOpticalBoundary(path, new OpticalBoundary(det->GetContainerVolume(), boundary, true));
0065 
0066       radiator->m_Borders[path].second = boundary;
0067       // This will most likely be a temporary assignment;
0068       det->GetContainerVolume()->m_Borders[path].first = boundary;
0069     }    
0070 
0071     return radiator;
0072   };
0073   void AddPhotonDetector(CherenkovDetector *det, const G4LogicalVolume *lv, 
0074              CherenkovPhotonDetector *pd) {
0075     // FIXME: a consistency check!;
0076     if (FindPhotonDetector(lv)) return;
0077 
0078     det->AddPhotonDetector(pd);
0079 
0080     m_PhotonDetectorLookup[lv] = pd;
0081   };
0082 
0083   //inline unsigned GetDetectorCount( void ) const { return m_Detectors.size(); };
0084 
0085   inline CherenkovRadiator *FindRadiator(const G4LogicalVolume *lv) {
0086     return (m_RadiatorLookup.find(lv) == m_RadiatorLookup.end() ? 0 : m_RadiatorLookup[lv]);
0087   };
0088   inline CherenkovMirror *FindMirror(const G4LogicalVolume *lv) {
0089     return (m_MirrorLookup.find(lv) == m_MirrorLookup.end() ? 0 : m_MirrorLookup[lv]);
0090   };
0091   inline void AddMirrorLookupEntry(const G4LogicalVolume *lv, CherenkovMirror *mirror) {
0092     m_MirrorLookup[lv] = mirror;
0093   };
0094   inline void AddPhotonDetectorLookupEntry(const G4LogicalVolume *lv, CherenkovPhotonDetector *pd) {
0095     m_PhotonDetectorLookup[lv] = pd;
0096   };
0097   inline CherenkovPhotonDetector *FindPhotonDetector(const G4LogicalVolume *lv) {
0098     return (m_PhotonDetectorLookup.find(lv) == m_PhotonDetectorLookup.end() ? 0 : m_PhotonDetectorLookup[lv]);
0099   };
0100 
0101   CherenkovRadiator *SetContainerVolume(CherenkovDetector *det, const char *name, unsigned path, 
0102                     const G4LogicalVolume *lv, 
0103                     const G4RadiatorMaterial *material, 
0104                     /*const*/ ParametricSurface *surface) { 
0105     auto radiator = FindOrAddRadiator(det, name, lv, material);
0106     // This is most likely a temporary assignment;
0107     radiator->m_Borders[path].first = surface;
0108 
0109     det->AddOpticalBoundary(path, new OpticalBoundary(FindRadiator(lv), surface, true));
0110     //det->SetContainerVolume(lv);
0111     det->SetContainerVolume(radiator);
0112 
0113     return radiator;
0114   };
0115 
0116   // FIXME: do it more efficient later;
0117   CherenkovDetector *GetDetectorByRadiator(const CherenkovRadiator *radiator) {
0118     for(auto detector: _m_Detectors)
0119       for(auto ptr: detector.second->Radiators())
0120     if (ptr.second == radiator)
0121       return detector.second;
0122       
0123     return 0;
0124   };
0125   CherenkovDetector *GetDetector(const char *name) {
0126     if (_m_Detectors.find(name) == _m_Detectors.end()) return 0;
0127 
0128     return _m_Detectors[name];
0129   };
0130   const std::map<TString, CherenkovDetector*> &GetDetectors( void ) const {
0131     return _m_Detectors;
0132   }; 
0133 
0134   // The lookup tables are global of course since the same particle can hit radiators
0135   // in more than one detector;
0136  private:
0137   std::map<const G4LogicalVolume*, CherenkovRadiator*>       m_RadiatorLookup;         //!
0138   std::map<const G4LogicalVolume*, CherenkovMirror*>         m_MirrorLookup;           //!
0139   std::map<const G4LogicalVolume*, CherenkovPhotonDetector*> m_PhotonDetectorLookup;   //!
0140 
0141   std::map<TString, CherenkovDetector*> _m_Detectors;
0142   
0143 #ifndef DISABLE_ROOT_IO
0144   ClassDef(CherenkovDetectorCollection, 2);
0145 #endif
0146 };
0147 
0148 #endif