Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-10 07:50:32

0001 #pragma once
0002 /**
0003 u4/U4SensorIdentifierDefault.h
0004 ================================
0005 
0006 This fulfils U4SensorIdentifier protocol, it is used
0007 to identify sensors in the geometry.  To override this
0008 implementation use G4CXOpticks::SetSensorIdentifier.
0009 
0010 
0011 **/
0012 
0013 #include <vector>
0014 #include <iostream>
0015 #include <map>
0016 
0017 #include "G4PVPlacement.hh"
0018 
0019 #include "sstr.h"
0020 #include "ssys.h"
0021 
0022 #include "U4SensorIdentifier.h"
0023 #include "U4Boundary.h"
0024 
0025 
0026 struct U4SensorIdentifierDefault : public U4SensorIdentifier
0027 {
0028     static std::vector<std::string>* GLOBAL_SENSOR_BOUNDARY_LIST ;
0029 
0030     void setLevel(int _level);
0031     int getGlobalIdentity(const G4VPhysicalVolume* pv, const G4VPhysicalVolume* ppv ) ;
0032     int getInstanceIdentity(const G4VPhysicalVolume* instance_outer_pv ) const ;
0033     static void FindSD_r( std::vector<const G4VPhysicalVolume*>& sdpv , const G4VPhysicalVolume* pv, int depth );
0034     static bool IsInterestingCopyNo( int copyno );
0035 
0036     int level = 0 ;
0037     std::vector<int> count_global_sensor_boundary ;
0038 
0039 };
0040 
0041 
0042 std::vector<std::string>*
0043 U4SensorIdentifierDefault::GLOBAL_SENSOR_BOUNDARY_LIST = ssys::getenv_vec<std::string>("U4SensorIdentifierDefault__GLOBAL_SENSOR_BOUNDARY_LIST", "", '\n' );
0044 
0045 
0046 inline void U4SensorIdentifierDefault::setLevel(int _level)
0047 {
0048     level = _level ;
0049 }
0050 
0051 /**
0052 U4SensorIdentifierDefault::getGlobalIdentity
0053 ---------------------------------------------
0054 
0055 Canonically invoked from U4Tree::identifySensitiveGlobals
0056 
0057 Currently a kludge using hardcoded pvn prefix.
0058 This is because sensors within the global remainder
0059 is only relevant to test geometries for JUNO.
0060 
0061 Would be better to construct a boundary name and match that
0062 against a list of sensor boundaries (see GBndLib__SENSOR_BOUNDARY_LIST)
0063 
0064 
0065 **/
0066 
0067 inline int U4SensorIdentifierDefault::getGlobalIdentity( const G4VPhysicalVolume* pv, const G4VPhysicalVolume* ppv )
0068 {
0069     U4Boundary boundary(pv,ppv);
0070 
0071     const char* bnd = boundary.bnd.c_str() ;
0072 
0073     int id = ssys::listed_count( &count_global_sensor_boundary, GLOBAL_SENSOR_BOUNDARY_LIST, bnd ) ;
0074 
0075     if(level > 0) std::cout
0076         << "U4SensorIdentifierDefault::getGlobalIdentity "
0077         << " level " << level
0078         << " id " << id
0079         << " bnd " << bnd
0080         << std::endl
0081         ;
0082 
0083 
0084     return id ;
0085 }
0086 
0087 
0088 /**
0089 U4SensorIdentifierDefault::getInstanceIdentity
0090 ---------------------------------------------------
0091 
0092 Canonically used from U4Tree::identifySensitiveInstances
0093 
0094 The argument *instance_outer_pv* is recursively traversed
0095 
0096 Returns -1 to signify "not-a-sensor" otherwise returns
0097 the copyno (aka "lpmtid") from the JUNO Geant4 PV of PMTs can be zero and
0098 is used for identification of sensors with (unfortunately)
0099 a non-contiguous set of values with some very large gaps.
0100 
0101 HMM: if were to switch to using the contiguous "lpmtidx"
0102 rather than the non-contiguous "lpmtid" this would likely
0103 be the place to do it.  HMM: but its too JUNO specific for here ?
0104 
0105 **/
0106 
0107 
0108 inline int U4SensorIdentifierDefault::getInstanceIdentity( const G4VPhysicalVolume* instance_outer_pv ) const
0109 {
0110     const char* pvn = instance_outer_pv ? instance_outer_pv->GetName().c_str() : "-" ;
0111     bool has_PMT_pvn = strstr(pvn, "PMT") != nullptr  ;
0112 
0113     const G4PVPlacement* pvp = dynamic_cast<const G4PVPlacement*>(instance_outer_pv) ;
0114     int copyno = pvp ? pvp->GetCopyNo() : -1 ;
0115 
0116     std::vector<const G4VPhysicalVolume*> sdpv ;
0117     FindSD_r(sdpv, instance_outer_pv, 0 );
0118 
0119     unsigned num_sd = sdpv.size() ;
0120     bool     is_sensor = num_sd > 0;
0121 
0122     int identifier = is_sensor ? copyno : -1  ;
0123 
0124     //bool is_interesting_copyno = IsInterestingCopyNo(copyno) ;
0125     //bool dump = is_sensor && is_interesting_copyno ;
0126     //bool dump = false ;
0127     //bool dump = true ;
0128     //bool dump = num_sd > 0 ;
0129 
0130     if(level > 0) std::cout
0131         << "U4SensorIdentifierDefault::getIdentity"
0132         << " level " << level
0133         << " copyno " << copyno
0134         << " num_sd " << num_sd
0135         << " is_sensor " << is_sensor
0136         << " pvn " << ( pvn ? pvn : "-" )
0137         << " has_PMT_pvn " << ( has_PMT_pvn ? "YES" : "NO " )
0138         << " identifier " << identifier
0139         << std::endl
0140         ;
0141 
0142 
0143     return identifier ;
0144 }
0145 
0146 /**
0147 U4SensorIdentifierDefault::FindSD_r
0148 -------------------------------------
0149 
0150 Recursive traverse collecting pv pointers for pv with associated SensitiveDetector.
0151 
0152 **/
0153 
0154 inline void U4SensorIdentifierDefault::FindSD_r(
0155     std::vector<const G4VPhysicalVolume*>& sdpv ,
0156     const G4VPhysicalVolume* pv,
0157     int depth )
0158 {
0159     const G4LogicalVolume* lv = pv->GetLogicalVolume() ;
0160     G4VSensitiveDetector* sd = lv->GetSensitiveDetector() ;
0161     if(sd) sdpv.push_back(pv);
0162     for (size_t i=0 ; i < size_t(lv->GetNoDaughters()) ; i++ ) FindSD_r( sdpv, lv->GetDaughter(i), depth+1 );
0163 }
0164 
0165 
0166 inline bool U4SensorIdentifierDefault::IsInterestingCopyNo( int copyno )
0167 {
0168     return
0169         copyno > -1 &&
0170            (
0171             (std::abs( copyno -      0 ) < 100) ||
0172             (std::abs( copyno -  17612 ) < 100) ||
0173             (std::abs( copyno -  30000 ) < 100) ||
0174             (std::abs( copyno -  32400 ) < 100) ||
0175             (std::abs( copyno - 300000 ) < 100) ||
0176             (std::abs( copyno - 325600 ) < 100)
0177            )
0178         ;
0179 }
0180 
0181