Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // G4VUserDetectorConstruction implementation << 27 // 26 // 28 // Original author: M.Asai, 1999 << 27 // $Id: G4VUserDetectorConstruction.cc,v 1.8 2007/05/03 17:59:18 asaim Exp $ 29 // ------------------------------------------- << 28 // GEANT4 tag $Name: geant4-09-01-patch-01 $ >> 29 // 30 30 31 #include "G4VUserDetectorConstruction.hh" 31 #include "G4VUserDetectorConstruction.hh" 32 << 33 #include "G4FieldManager.hh" << 34 #include "G4LogicalVolume.hh" << 35 #include "G4LogicalVolumeStore.hh" << 36 #include "G4MultiSensitiveDetector.hh" << 37 #include "G4RunManager.hh" << 38 #include "G4SDManager.hh" << 39 #include "G4VPhysicalVolume.hh" 32 #include "G4VPhysicalVolume.hh" 40 #include "G4VSensitiveDetector.hh" << 41 #include "G4VUserParallelWorld.hh" 33 #include "G4VUserParallelWorld.hh" 42 34 43 #include <cassert> << 35 G4VUserDetectorConstruction::G4VUserDetectorConstruction() 44 #include <map> << 36 {;} 45 #include <sstream> << 37 >> 38 G4VUserDetectorConstruction::~G4VUserDetectorConstruction() >> 39 {;} 46 40 47 // ------------------------------------------- << 48 void G4VUserDetectorConstruction::RegisterPara 41 void G4VUserDetectorConstruction::RegisterParallelWorld(G4VUserParallelWorld* aPW) 49 { 42 { 50 auto pwItr = std::find(parallelWorld.cbegin( << 43 std::vector<G4VUserParallelWorld*>::iterator pwItr; 51 if (pwItr != parallelWorld.cend()) { << 44 for(pwItr=parallelWorld.begin();pwItr!=parallelWorld.end();pwItr++) 52 G4String eM = "A parallel world <"; << 45 { 53 eM += aPW->GetName(); << 46 if((*pwItr)->GetName()==aPW->GetName()) 54 eM += "> is already registered to the user << 47 { 55 G4Exception("G4VUserDetectorConstruction:: << 48 G4String eM = "A parallel world <"; 56 FatalErrorInArgument, eM); << 49 eM += aPW->GetName(); >> 50 eM += "> is already registered to the user detector construction."; >> 51 G4Exception("G4VUserDetectorConstruction::RegisterParallelWorld", >> 52 "RunUDet000",FatalErrorInArgument,eM); >> 53 } 57 } 54 } 58 parallelWorld.push_back(aPW); 55 parallelWorld.push_back(aPW); 59 } 56 } 60 57 61 // ------------------------------------------- << 62 G4int G4VUserDetectorConstruction::ConstructPa 58 G4int G4VUserDetectorConstruction::ConstructParallelGeometries() 63 { 59 { 64 G4int nP = 0; 60 G4int nP = 0; 65 for (const auto& pwItr : parallelWorld) { << 61 std::vector<G4VUserParallelWorld*>::iterator pwItr; 66 pwItr->Construct(); << 62 for(pwItr=parallelWorld.begin();pwItr!=parallelWorld.end();pwItr++) 67 ++nP; << 63 { >> 64 (*pwItr)->Construct(); >> 65 nP++; 68 } 66 } 69 return nP; 67 return nP; 70 } 68 } 71 69 72 // ------------------------------------------- << 73 void G4VUserDetectorConstruction::ConstructPar << 74 { << 75 for (const auto& pwItr : parallelWorld) { << 76 pwItr->ConstructSD(); << 77 } << 78 } << 79 << 80 // ------------------------------------------- << 81 G4int G4VUserDetectorConstruction::GetNumberOf 70 G4int G4VUserDetectorConstruction::GetNumberOfParallelWorld() const 82 { << 71 { return parallelWorld.size(); } 83 return (G4int)parallelWorld.size(); << 84 } << 85 72 86 // ------------------------------------------- << 87 G4VUserParallelWorld* G4VUserDetectorConstruct 73 G4VUserParallelWorld* G4VUserDetectorConstruction::GetParallelWorld(G4int i) const 88 { 74 { 89 if (i < 0 || i >= GetNumberOfParallelWorld() << 75 if(i<0||i>=GetNumberOfParallelWorld()) return 0; 90 return parallelWorld[i]; 76 return parallelWorld[i]; 91 } 77 } 92 78 93 // ------------------------------------------- << 94 void G4VUserDetectorConstruction::ConstructSDa << 95 << 96 // ------------------------------------------- << 97 void G4VUserDetectorConstruction::CloneF() << 98 { << 99 using FMtoFMmap = std::map<G4FieldManager*, << 100 using FMpair = std::pair<G4FieldManager*, G4 << 101 << 102 FMtoFMmap masterToWorker; << 103 G4LogicalVolumeStore* const logVolStore = G4 << 104 for (const auto& g4LogicalVolume : *logVolSt << 105 // Use shadow of master to get instance of << 106 G4FieldManager* masterFM = nullptr; // g4 << 107 G4FieldManager* clonedFM = nullptr; << 108 if (masterFM != nullptr) { << 109 auto fmFound = masterToWorker.find(maste << 110 if (fmFound == masterToWorker.cend()) { << 111 // First time we see this SD, let's cl << 112 try { << 113 auto insertedEl = masterToWorker.ins << 114 clonedFM = (insertedEl.first)->secon << 115 } << 116 catch (...) { << 117 G4ExceptionDescription msg; << 118 msg << "Cloning of G4FieldManager fa << 119 << " But derived class does not << 120 "continue."; << 121 G4Exception("G4VUserDetectorConstruc << 122 } << 123 } << 124 else { << 125 // We have already seen this SD attach << 126 // let's re-use previous clone << 127 clonedFM = (*fmFound).second; << 128 } << 129 } // masterFM != 0 << 130 // Note that we do not push FM to daughter << 131 // we area looping on all logical volumes << 132 // the map master<->cloned the final effec << 133 // correct Boolean flag: log-volumes that << 134 // FM they will have cloned ones << 135 g4LogicalVolume->SetFieldManager(clonedFM, << 136 } << 137 } << 138 << 139 // ------------------------------------------- << 140 void G4VUserDetectorConstruction::CloneSD() << 141 { << 142 // Loop on ALL logial volumes to search for << 143 G4LogicalVolumeStore* const logVolStore = G4 << 144 << 145 using SDtoSDmap = std::map<G4VSensitiveDetec << 146 using SDpair = std::pair<G4VSensitiveDetecto << 147 SDtoSDmap masterToWorker; << 148 << 149 for (const auto& g4LogicalVolume : *logVolSt << 150 // Use shadow of master to get the instanc << 151 G4VSensitiveDetector* masterSD = nullptr; << 152 G4VSensitiveDetector* clonedSD = nullptr; << 153 if (masterSD != nullptr) { << 154 auto sdFound = masterToWorker.find(maste << 155 if (sdFound == masterToWorker.cend()) { << 156 // First time we see this SD, let's cl << 157 try { << 158 auto insertedEl = masterToWorker.ins << 159 clonedSD = (insertedEl.first)->secon << 160 } << 161 catch (...) { << 162 G4ExceptionDescription msg; << 163 msg << "Cloning of G4VSensitiveDetec << 164 #ifndef WIN32 << 165 << " (full path name: " << maste << 166 #endif << 167 << " But derived class does not << 168 "continue."; << 169 G4Exception("G4VUserDetectorConstruc << 170 } << 171 } << 172 else { << 173 // We have already seen this SD attach << 174 // let's re-use previous clone << 175 clonedSD = (*sdFound).second; << 176 } << 177 } // masterSD!=0 << 178 g4LogicalVolume->SetSensitiveDetector(clon << 179 } << 180 } << 181 << 182 // ------------------------------------------- << 183 void G4VUserDetectorConstruction::SetSensitive << 184 << 185 { << 186 G4bool found = false; << 187 G4LogicalVolumeStore* store = G4LogicalVolum << 188 auto volmap = store->GetMap(); << 189 auto pos = volmap.find(logVolName); << 190 if (pos != volmap.cend()) { << 191 if ((pos->second.size() > 1) && !multi) { << 192 G4String eM = "More than one logical vol << 193 eM += pos->first; << 194 eM += "> are found and thus the sensitiv << 195 eM += aSD->GetName(); << 196 eM += "> cannot be uniquely assigned."; << 197 G4Exception("G4VUserDetectorConstruction << 198 FatalErrorInArgument, eM); << 199 } << 200 found = true; << 201 for (auto& i : pos->second) { << 202 SetSensitiveDetector(i, aSD); << 203 } << 204 } << 205 if (!found) { << 206 G4String eM2 = "No logical volume of name << 207 eM2 += logVolName; << 208 eM2 += "> is found. The specified sensitiv << 209 eM2 += aSD->GetName(); << 210 eM2 += "> couldn't be assigned to any volu << 211 G4Exception("G4VUserDetectorConstruction:: << 212 FatalErrorInArgument, eM2); << 213 } << 214 } << 215 << 216 // ------------------------------------------- << 217 void G4VUserDetectorConstruction::SetSensitive << 218 << 219 { << 220 assert(logVol != nullptr && aSD != nullptr); << 221 << 222 // The aSD has already been added by user to << 223 // G4SDManager::GetSDMpointer()->AddNewDetec << 224 << 225 // New Logic: allow for "multiple" SDs being << 226 // To do that we use a special proxy SD call << 227 << 228 // Get existing SD if already set and check << 229 G4VSensitiveDetector* originalSD = logVol->G << 230 if (originalSD == aSD) { << 231 G4ExceptionDescription msg; << 232 msg << "Attempting to add multiple times t << 233 msg << originalSD->GetName() << "\") is no << 234 G4Exception("G4VUserDetectorConstruction:: << 235 return; << 236 } << 237 if (originalSD == nullptr) { << 238 logVol->SetSensitiveDetector(aSD); << 239 } << 240 else { << 241 auto msd = dynamic_cast<G4MultiSensitiveDe << 242 if (msd != nullptr) { << 243 msd->AddSD(aSD); << 244 } << 245 else { << 246 std::ostringstream mn; << 247 mn << "/MultiSD_" << logVol->GetName() < << 248 const G4String msdname = mn.str(); << 249 msd = new G4MultiSensitiveDetector(msdna << 250 // We need to register the proxy to have << 251 G4SDManager::GetSDMpointer()->AddNewDete << 252 msd->AddSD(originalSD); << 253 msd->AddSD(aSD); << 254 logVol->SetSensitiveDetector(msd); << 255 } << 256 } << 257 } << 258 79