Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer << 3 // * DISCLAIMER * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th << 5 // * The following disclaimer summarizes all the specific disclaimers * 6 // * the Geant4 Collaboration. It is provided << 6 // * of contributors to this software. The specific disclaimers,which * 7 // * conditions of the Geant4 Software License << 7 // * govern, are listed with their locations in: * 8 // * LICENSE and available at http://cern.ch/ << 8 // * http://cern.ch/geant4/license * 9 // * include a list of copyright holders. << 10 // * 9 // * * 11 // * Neither the authors of this software syst 10 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 11 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 12 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 13 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file << 14 // * use. * 16 // * for the full disclaimer and the limitatio << 17 // * 15 // * * 18 // * This code implementation is the result << 16 // * This code implementation is the intellectual property of the * 19 // * technical work of the GEANT4 collaboratio << 17 // * GEANT4 collaboration. * 20 // * By using, copying, modifying or distri << 18 // * By copying, distributing or modifying the Program (or any work * 21 // * any work based on the software) you ag << 19 // * based on the Program) you indicate your acceptance of this * 22 // * use in resulting scientific publicati << 20 // * statement, and all its terms. * 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* 21 // ******************************************************************** 25 // 22 // 26 // G4VUserDetectorConstruction implementation << 27 // 23 // 28 // Original author: M.Asai, 1999 << 24 // $Id: G4VUserDetectorConstruction.cc,v 1.3 2001/07/11 10:08:34 gunter Exp $ 29 // ------------------------------------------- << 25 // GEANT4 tag $Name: geant4-08-00 $ >> 26 // 30 27 31 #include "G4VUserDetectorConstruction.hh" 28 #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" 29 #include "G4VPhysicalVolume.hh" 40 #include "G4VSensitiveDetector.hh" << 41 #include "G4VUserParallelWorld.hh" << 42 << 43 #include <cassert> << 44 #include <map> << 45 #include <sstream> << 46 << 47 // ------------------------------------------- << 48 void G4VUserDetectorConstruction::RegisterPara << 49 { << 50 auto pwItr = std::find(parallelWorld.cbegin( << 51 if (pwItr != parallelWorld.cend()) { << 52 G4String eM = "A parallel world <"; << 53 eM += aPW->GetName(); << 54 eM += "> is already registered to the user << 55 G4Exception("G4VUserDetectorConstruction:: << 56 FatalErrorInArgument, eM); << 57 } << 58 parallelWorld.push_back(aPW); << 59 } << 60 << 61 // ------------------------------------------- << 62 G4int G4VUserDetectorConstruction::ConstructPa << 63 { << 64 G4int nP = 0; << 65 for (const auto& pwItr : parallelWorld) { << 66 pwItr->Construct(); << 67 ++nP; << 68 } << 69 return nP; << 70 } << 71 << 72 // ------------------------------------------- << 73 void G4VUserDetectorConstruction::ConstructPar << 74 { << 75 for (const auto& pwItr : parallelWorld) { << 76 pwItr->ConstructSD(); << 77 } << 78 } << 79 << 80 // ------------------------------------------- << 81 G4int G4VUserDetectorConstruction::GetNumberOf << 82 { << 83 return (G4int)parallelWorld.size(); << 84 } << 85 << 86 // ------------------------------------------- << 87 G4VUserParallelWorld* G4VUserDetectorConstruct << 88 { << 89 if (i < 0 || i >= GetNumberOfParallelWorld() << 90 return parallelWorld[i]; << 91 } << 92 << 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 30 222 // The aSD has already been added by user to << 31 G4VUserDetectorConstruction::G4VUserDetectorConstruction() 223 // G4SDManager::GetSDMpointer()->AddNewDetec << 32 {;} 224 33 225 // New Logic: allow for "multiple" SDs being << 34 G4VUserDetectorConstruction::~G4VUserDetectorConstruction() 226 // To do that we use a special proxy SD call << 35 {;} 227 36 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 37