00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "G4Region.hh"
00035 #include "G4RegionStore.hh"
00036 #include "G4LogicalVolume.hh"
00037 #include "G4VPhysicalVolume.hh"
00038 #include "G4LogicalVolumeStore.hh"
00039 #include "G4VNestedParameterisation.hh"
00040 #include "G4VUserRegionInformation.hh"
00041 #include "G4Material.hh"
00042
00043
00044
00045
00046
00047
00048 G4Region::G4Region(const G4String& pName)
00049 : fName(pName), fRegionMod(true), fCut(0), fUserInfo(0), fUserLimits(0),
00050 fFieldManager(0), fFastSimulationManager(0), fWorldPhys(0),
00051 fRegionalSteppingAction(0),
00052 fInMassGeometry(false), fInParallelGeometry(false)
00053 {
00054 G4RegionStore* rStore = G4RegionStore::GetInstance();
00055 if (rStore->GetRegion(pName,false))
00056 {
00057 std::ostringstream message;
00058 message << "The region has NOT been registered !" << G4endl
00059 << " Region " << pName << " already existing in store !"
00060 << G4endl;
00061 G4Exception("G4Region::G4Region()", "GeomMgt1001",
00062 JustWarning, message);
00063 }
00064 else
00065 {
00066 rStore->Register(this);
00067 }
00068 }
00069
00070
00071
00072
00073
00074
00075 G4Region::G4Region( __void__& )
00076 : fName(""), fRegionMod(true), fCut(0), fUserInfo(0), fUserLimits(0),
00077 fFieldManager(0), fFastSimulationManager(0), fWorldPhys(0),
00078 fRegionalSteppingAction(0),
00079 fInMassGeometry(false), fInParallelGeometry(false)
00080 {
00081
00082
00083 G4RegionStore::GetInstance()->Register(this);
00084 }
00085
00086
00087
00088
00089
00090
00091 G4Region::~G4Region()
00092 {
00093 G4RegionStore::GetInstance()->DeRegister(this);
00094 if(fUserInfo) delete fUserInfo;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 void G4Region::ScanVolumeTree(G4LogicalVolume* lv, G4bool region)
00107 {
00108
00109
00110
00111 G4Region* currentRegion = 0;
00112 size_t noDaughters = lv->GetNoDaughters();
00113 G4Material* volMat = lv->GetMaterial();
00114 if(!volMat && fInMassGeometry)
00115 {
00116 std::ostringstream message;
00117 message << "Logical volume <" << lv->GetName() << ">" << G4endl
00118 << "does not have a valid material pointer." << G4endl
00119 << "A logical volume belonging to the (tracking) world volume "
00120 << "must have a valid material.";
00121 G4Exception("G4Region::ScanVolumeTree()", "GeomMgt0002",
00122 FatalException, message, "Check your geometry construction.");
00123 }
00124 if (region)
00125 {
00126 currentRegion = this;
00127 if (volMat)
00128 {
00129 AddMaterial(volMat);
00130 G4Material* baseMat = const_cast<G4Material*>(volMat->GetBaseMaterial());
00131 if (baseMat) { AddMaterial(baseMat); }
00132 }
00133 }
00134
00135
00136
00137
00138 lv->SetRegion(currentRegion);
00139
00140
00141
00142 if(noDaughters==0) return;
00143
00144 G4VPhysicalVolume* daughterPVol = lv->GetDaughter(0);
00145 if (daughterPVol->IsParameterised())
00146 {
00147
00148
00149
00150 G4VPVParameterisation* pParam = daughterPVol->GetParameterisation();
00151
00152 if (pParam->GetMaterialScanner())
00153 {
00154 size_t matNo = pParam->GetMaterialScanner()->GetNumberOfMaterials();
00155 for (register size_t mat=0; mat<matNo; mat++)
00156 {
00157 volMat = pParam->GetMaterialScanner()->GetMaterial(mat);
00158 if(!volMat && fInMassGeometry)
00159 {
00160 std::ostringstream message;
00161 message << "The parameterisation for the physical volume <"
00162 << daughterPVol->GetName() << ">" << G4endl
00163 << "does not return a valid material pointer." << G4endl
00164 << "A volume belonging to the (tracking) world volume must "
00165 << "have a valid material.";
00166 G4Exception("G4Region::ScanVolumeTree()", "GeomMgt0002",
00167 FatalException, message, "Check your parameterisation.");
00168 }
00169 if (volMat)
00170 {
00171 AddMaterial(volMat);
00172 G4Material* baseMat = const_cast<G4Material*>(volMat->GetBaseMaterial());
00173 if (baseMat) { AddMaterial(baseMat); }
00174 }
00175 }
00176 }
00177 else
00178 {
00179 size_t repNo = daughterPVol->GetMultiplicity();
00180 for (register size_t rep=0; rep<repNo; rep++)
00181 {
00182 volMat = pParam->ComputeMaterial(rep, daughterPVol);
00183 if(!volMat && fInMassGeometry)
00184 {
00185 std::ostringstream message;
00186 message << "The parameterisation for the physical volume <"
00187 << daughterPVol->GetName() << ">" << G4endl
00188 << "does not return a valid material pointer." << G4endl
00189 << "A volume belonging to the (tracking) world volume must "
00190 << "have a valid material.";
00191 G4Exception("G4Region::ScanVolumeTree()", "GeomMgt0002",
00192 FatalException, message, "Check your parameterisation.");
00193 }
00194 if(volMat)
00195 {
00196 AddMaterial(volMat);
00197 G4Material* baseMat = const_cast<G4Material*>(volMat->GetBaseMaterial());
00198 if (baseMat) { AddMaterial(baseMat); }
00199 }
00200 }
00201 }
00202 G4LogicalVolume* daughterLVol = daughterPVol->GetLogicalVolume();
00203 ScanVolumeTree(daughterLVol, region);
00204 }
00205 else
00206 {
00207 for (register size_t i=0; i<noDaughters; i++)
00208 {
00209 G4LogicalVolume* daughterLVol = lv->GetDaughter(i)->GetLogicalVolume();
00210 if (!daughterLVol->IsRootRegion())
00211 {
00212
00213
00214
00215 ScanVolumeTree(daughterLVol, region);
00216 }
00217 }
00218 }
00219 }
00220
00221
00222
00223
00224
00225
00226
00227 void G4Region::AddRootLogicalVolume(G4LogicalVolume* lv)
00228 {
00229
00230
00231 G4RootLVList::iterator pos;
00232 pos = std::find(fRootVolumes.begin(),fRootVolumes.end(),lv);
00233 if (pos == fRootVolumes.end())
00234 {
00235
00236
00237 fRootVolumes.push_back(lv);
00238 lv->SetRegionRootFlag(true);
00239 }
00240
00241
00242
00243 ScanVolumeTree(lv, true);
00244
00245
00246
00247 fRegionMod = true;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256 void G4Region::RemoveRootLogicalVolume(G4LogicalVolume* lv, G4bool scan)
00257 {
00258
00259
00260 G4RootLVList::iterator pos;
00261 pos = std::find(fRootVolumes.begin(),fRootVolumes.end(),lv);
00262 if (pos != fRootVolumes.end())
00263 {
00264 if (fRootVolumes.size() != 1)
00265 {
00266 lv->SetRegionRootFlag(false);
00267 }
00268 fRootVolumes.erase(pos);
00269 }
00270
00271 if (scan)
00272 {
00273 UpdateMaterialList();
00274 }
00275
00276
00277
00278 fRegionMod = true;
00279 }
00280
00281
00282
00283
00284
00285
00286 void G4Region::ClearMaterialList()
00287 {
00288 fMaterials.clear();
00289 }
00290
00291
00292
00293
00294
00295
00296
00297 void G4Region::UpdateMaterialList()
00298 {
00299
00300
00301 ClearMaterialList();
00302
00303
00304
00305
00306 G4RootLVList::iterator pLV;
00307 for (pLV=fRootVolumes.begin(); pLV!=fRootVolumes.end(); pLV++)
00308 {
00309 ScanVolumeTree(*pLV, true);
00310 }
00311 }
00312
00313
00314
00315
00316
00317
00318
00319 void G4Region::SetWorld(G4VPhysicalVolume* wp)
00320 {
00321 if(!wp)
00322 { fWorldPhys = 0; }
00323 else
00324 { if(BelongsTo(wp)) fWorldPhys = wp; }
00325
00326 return;
00327 }
00328
00329
00330
00331
00332
00333
00334
00335 G4bool G4Region::BelongsTo(G4VPhysicalVolume* thePhys) const
00336 {
00337 G4LogicalVolume* currLog = thePhys->GetLogicalVolume();
00338 if (currLog->GetRegion()==this) {return true;}
00339
00340 G4int nDaughters = currLog->GetNoDaughters();
00341 while (nDaughters--)
00342 {
00343 if (BelongsTo(currLog->GetDaughter(nDaughters))) {return true;}
00344 }
00345
00346 return false;
00347 }
00348
00349
00350
00351
00352
00353
00354
00355 void G4Region::ClearFastSimulationManager()
00356 {
00357 G4bool isUnique;
00358 G4Region* parent = GetParentRegion(isUnique);
00359 if(parent)
00360 {
00361 if (isUnique)
00362 {
00363 fFastSimulationManager = parent->GetFastSimulationManager();
00364 }
00365 else
00366 {
00367 std::ostringstream message;
00368 message << "Region <" << fName << "> belongs to more than"
00369 << " one parent region !" << G4endl
00370 << "A region cannot belong to more than one direct parent region,"
00371 << G4endl
00372 << "to have fast-simulation assigned.";
00373 G4Exception("G4Region::ClearFastSimulationManager()",
00374 "GeomMgt1002", JustWarning, message);
00375 fFastSimulationManager = 0;
00376 }
00377 }
00378 else
00379 {
00380 fFastSimulationManager = 0;
00381 }
00382 }
00383
00384
00385
00386
00387
00388
00389
00390 G4Region* G4Region::GetParentRegion(G4bool& unique) const
00391 {
00392 G4Region* parent = 0; unique = true;
00393 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
00394 G4LogicalVolumeStore::iterator lvItr;
00395
00396
00397
00398 for(lvItr=lvStore->begin(); lvItr!=lvStore->end(); lvItr++)
00399 {
00400 G4int nD = (*lvItr)->GetNoDaughters();
00401 G4Region* aR = (*lvItr)->GetRegion();
00402
00403
00404
00405 for(G4int iD=0; iD<nD; iD++)
00406 {
00407 if((*lvItr)->GetDaughter(iD)->GetLogicalVolume()->GetRegion()==this)
00408 {
00409 if(parent)
00410 {
00411 if(parent!=aR) { unique = false; }
00412 }
00413 else
00414
00415 {
00416 parent = aR;
00417 }
00418 }
00419 }
00420 }
00421 return parent;
00422 }