source: trunk/source/geometry/management/src/G4Region.cc@ 1196

Last change on this file since 1196 was 1058, checked in by garnier, 17 years ago

file release beta

File size: 13.3 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id: G4Region.cc,v 1.26 2008/07/15 10:27:36 gcosmo Exp $
28// GEANT4 tag $Name: geant4-09-02-ref-02 $
29//
30//
31// class G4Region Implementation
32//
33// --------------------------------------------------------------------
34
35#include "G4Region.hh"
36#include "G4RegionStore.hh"
37#include "G4LogicalVolume.hh"
38#include "G4VPhysicalVolume.hh"
39#include "G4LogicalVolumeStore.hh"
40#include "G4VNestedParameterisation.hh"
41#include "G4VUserRegionInformation.hh"
42
43// *******************************************************************
44// Constructor:
45// - Adds self to region Store
46// *******************************************************************
47//
48G4Region::G4Region(const G4String& pName)
49 : fName(pName), fRegionMod(true), fCut(0), fUserInfo(0), fUserLimits(0),
50 fFastSimulationManager(0), fWorldPhys(0), fRegionalSteppingAction(0)
51{
52 G4RegionStore* rStore = G4RegionStore::GetInstance();
53 if (rStore->GetRegion(pName,false))
54 {
55 G4cerr << "WARNING - G4Region::G4Region()" << G4endl
56 << " Region " << pName << " already existing in store !"
57 << G4endl;
58 G4Exception("G4Region::G4Region()", "InvalidSetup", JustWarning,
59 "The region has NOT been registered !");
60 }
61 else
62 {
63 rStore->Register(this);
64 }
65}
66
67// ********************************************************************
68// Fake default constructor - sets only member data and allocates memory
69// for usage restricted to object persistency.
70// ********************************************************************
71//
72G4Region::G4Region( __void__& )
73 : fName(""), fRegionMod(true), fCut(0), fUserInfo(0), fUserLimits(0),
74 fFastSimulationManager(0), fWorldPhys(0), fRegionalSteppingAction(0)
75{
76 // Register to store
77 //
78 G4RegionStore::GetInstance()->Register(this);
79}
80
81// *******************************************************************
82// Destructor:
83// - Removes self from region Store
84// *******************************************************************
85//
86G4Region::~G4Region()
87{
88 G4RegionStore::GetInstance()->DeRegister(this);
89 if(fUserInfo) delete fUserInfo;
90}
91
92// *******************************************************************
93// ScanVolumeTree:
94// - Scans recursively the 'lv' logical volume tree, retrieves
95// and places all materials in the list.
96// - The boolean flag 'region' identifies if the volume tree must
97// have region reset (false) or if the current region must be
98// associated to the logical volume 'lv' and its tree (true).
99// *******************************************************************
100//
101void G4Region::ScanVolumeTree(G4LogicalVolume* lv, G4bool region)
102{
103 // If logical volume is going to become a region, add
104 // its material to the list if not already present
105 //
106 G4Region* currentRegion = 0;
107 size_t noDaughters = lv->GetNoDaughters();
108 G4Material* volMat = lv->GetMaterial();
109 if(!volMat)
110 {
111 G4String errmsg = "Logical volume <";
112 errmsg += lv->GetName();
113 errmsg += "> does not have a valid material pointer.\n";
114 errmsg += "A logical volume belonging to the (tracking) world volume ";
115 errmsg += "must have a valid material.\nCheck your geometry construction.";
116 G4Exception("G4Region::ScanVolumeTree()", "SetupError",
117 FatalException, errmsg);
118 }
119 if (region)
120 {
121 currentRegion = this;
122 AddMaterial(volMat);
123 }
124
125 // Set the LV region to be either the current region or NULL,
126 // according to the boolean selector
127 //
128 lv->SetRegion(currentRegion);
129
130 // Stop recursion here if no further daughters are involved
131 //
132 if(noDaughters==0) return;
133
134 G4VPhysicalVolume* daughterPVol = lv->GetDaughter(0);
135 if (daughterPVol->IsParameterised())
136 {
137 // Adopt special treatment in case of parameterised volumes,
138 // where parameterisation involves a new material scan
139 //
140 G4VPVParameterisation* pParam = daughterPVol->GetParameterisation();
141
142 if (pParam->GetMaterialScanner())
143 {
144 size_t matNo = pParam->GetMaterialScanner()->GetNumberOfMaterials();
145 for (register size_t mat=0; mat<matNo; mat++)
146 {
147 volMat = pParam->GetMaterialScanner()->GetMaterial(mat);
148 if(!volMat)
149 {
150 G4String errmsg = "The parameterisation for the physical volume <";
151 errmsg += daughterPVol->GetName();
152 errmsg += ">\n does not return a valid material pointer.\n";
153 errmsg += "A volume belonging to the (tracking) world volume must ";
154 errmsg += "have a valid material.\nCheck your parameterisation.";
155 G4Exception("G4Region::ScanVolumeTree()",
156 "SetupError", FatalException, errmsg);
157 }
158 AddMaterial(volMat);
159 }
160 }
161 else
162 {
163 size_t repNo = daughterPVol->GetMultiplicity();
164 for (register size_t rep=0; rep<repNo; rep++)
165 {
166 volMat = pParam->ComputeMaterial(rep, daughterPVol);
167 if(!volMat)
168 {
169 G4String errmsg = "The parameterisation for the physical volume <";
170 errmsg += daughterPVol->GetName();
171 errmsg += ">\n does not return a valid material pointer.\n";
172 errmsg += "A volume belonging to the (tracking) world volume must ";
173 errmsg += "have a valid material.\nCheck your parameterisation.";
174 G4Exception("G4Region::ScanVolumeTree()",
175 "SetupError", FatalException, errmsg);
176 }
177 AddMaterial(volMat);
178 }
179 }
180 G4LogicalVolume* daughterLVol = daughterPVol->GetLogicalVolume();
181 ScanVolumeTree(daughterLVol, region);
182 }
183 else
184 {
185 for (register size_t i=0; i<noDaughters; i++)
186 {
187 G4LogicalVolume* daughterLVol = lv->GetDaughter(i)->GetLogicalVolume();
188 if (!daughterLVol->IsRootRegion())
189 {
190 // Set daughter's LV to be a region and store materials in
191 // the materials list, if the LV is not already a root region
192 //
193 ScanVolumeTree(daughterLVol, region);
194 }
195 }
196 }
197}
198
199// *******************************************************************
200// AddRootLogicalVolume:
201// - Adds a root logical volume and sets its daughters flags as
202// regions. It also recomputes the materials list for the region.
203// *******************************************************************
204//
205void G4Region::AddRootLogicalVolume(G4LogicalVolume* lv)
206{
207 // Check the logical volume is not already in the list
208 //
209 G4RootLVList::iterator pos;
210 pos = std::find(fRootVolumes.begin(),fRootVolumes.end(),lv);
211 if (pos == fRootVolumes.end())
212 {
213 // Insert the root volume in the list and set it as root region
214 //
215 fRootVolumes.push_back(lv);
216 lv->SetRegionRootFlag(true);
217 }
218
219 // Scan recursively the tree of daugther volumes and set regions
220 //
221 ScanVolumeTree(lv, true);
222
223 // Set region as modified
224 //
225 fRegionMod = true;
226}
227
228// *******************************************************************
229// RemoveRootLogicalVolume:
230// - Removes a root logical volume and resets its daughters flags as
231// regions. It also recomputes the materials list for the region.
232// *******************************************************************
233//
234void G4Region::RemoveRootLogicalVolume(G4LogicalVolume* lv, G4bool scan)
235{
236 // Find and remove logical volume from the list
237 //
238 G4RootLVList::iterator pos;
239 pos = std::find(fRootVolumes.begin(),fRootVolumes.end(),lv);
240 if (pos != fRootVolumes.end())
241 {
242 if (fRootVolumes.size() != 1) // Avoid resetting flag for world since
243 { // volume may be already deleted !
244 lv->SetRegionRootFlag(false);
245 }
246 fRootVolumes.erase(pos);
247 }
248
249 if (scan) // Update the materials list
250 {
251 UpdateMaterialList();
252 }
253
254 // Set region as modified
255 //
256 fRegionMod = true;
257}
258
259// *******************************************************************
260// ClearMaterialList:
261// - Clears the material list.
262// *******************************************************************
263//
264void G4Region::ClearMaterialList()
265{
266 fMaterials.clear();
267}
268
269// *******************************************************************
270// UpdateMaterialList:
271// - computes material list looping through
272// each root logical volume in the region.
273// *******************************************************************
274//
275void G4Region::UpdateMaterialList()
276{
277 // Reset the materials list
278 //
279 ClearMaterialList();
280
281 // Loop over the root logical volumes and rebuild the list
282 // of materials from scratch
283 //
284 G4RootLVList::iterator pLV;
285 for (pLV=fRootVolumes.begin(); pLV!=fRootVolumes.end(); pLV++)
286 {
287 ScanVolumeTree(*pLV, true);
288 }
289}
290
291// *******************************************************************
292// SetWorld:
293// - Set the world physical volume if this region belongs to this
294// world. If the given pointer is null, reset the pointer.
295// *******************************************************************
296//
297void G4Region::SetWorld(G4VPhysicalVolume* wp)
298{
299 if(!wp)
300 { fWorldPhys = 0; }
301 else
302 { if(BelongsTo(wp)) fWorldPhys = wp; }
303
304 return;
305}
306
307// *******************************************************************
308// BelongsTo:
309// - Returns whether this region belongs to the given physical volume
310// (recursively scanned to the bottom of the hierarchy)
311// *******************************************************************
312//
313G4bool G4Region::BelongsTo(G4VPhysicalVolume* thePhys) const
314{
315 G4LogicalVolume* currLog = thePhys->GetLogicalVolume();
316 if (currLog->GetRegion()==this) {return true;}
317
318 G4int nDaughters = currLog->GetNoDaughters();
319 while (nDaughters--)
320 {
321 if (BelongsTo(currLog->GetDaughter(nDaughters))) {return true;}
322 }
323
324 return false;
325}
326
327// *******************************************************************
328// ClearFastSimulationManager:
329// - Set G4FastSimulationManager pointer to the one for the parent region
330// if it exists. Otherwise set to null.
331// *******************************************************************
332//
333void G4Region::ClearFastSimulationManager()
334{
335 G4bool isUnique;
336 G4Region* parent = GetParentRegion(isUnique);
337 if(parent)
338 {
339 if (isUnique)
340 {
341 fFastSimulationManager = parent->GetFastSimulationManager();
342 }
343 else
344 {
345 G4cout << "WARNING - G4Region::GetParentRegion()" << G4endl
346 << " Region <" << fName << "> belongs to more than"
347 << " one parent region !" << G4endl;
348 G4String message =
349 "A region (" + fName + ") cannot belong to more than one \n"
350 + "direct parent region, to have fast-simulation assigned.";
351 G4Exception("G4Region::ClearFastSimulationManager()",
352 "InvalidSetup", JustWarning, message);
353 fFastSimulationManager = 0;
354 }
355 }
356 else
357 {
358 fFastSimulationManager = 0;
359 }
360}
361
362// *******************************************************************
363// GetParentRegion:
364// - Returns a region that contains this region.
365// Otherwise null is returned.
366// *******************************************************************
367//
368G4Region* G4Region::GetParentRegion(G4bool& unique) const
369{
370 G4Region* parent = 0; unique = true;
371 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
372 G4LogicalVolumeStore::iterator lvItr;
373
374 // Loop over all logical volumes in the store
375 //
376 for(lvItr=lvStore->begin(); lvItr!=lvStore->end(); lvItr++)
377 {
378 G4int nD = (*lvItr)->GetNoDaughters();
379 G4Region* aR = (*lvItr)->GetRegion();
380
381 // Loop over all daughters of each logical volume
382 //
383 for(G4int iD=0; iD<nD; iD++)
384 {
385 if((*lvItr)->GetDaughter(iD)->GetLogicalVolume()->GetRegion()==this)
386 {
387 if(parent)
388 {
389 if(parent!=aR) { unique = false; }
390 }
391 else // Cache LV parent region which includes a daughter volume
392 // with the same associated region as the current one
393 {
394 parent = aR;
395 }
396 }
397 }
398 }
399 return parent;
400}
Note: See TracBrowser for help on using the repository browser.