]>
Commit | Line | Data |
---|---|---|
b68f7176 | 1 | // $Id$ |
2 | // Category: geometry | |
3 | // | |
e5967ab3 | 4 | // Author: I. Hrivnacova |
5 | // | |
6 | // Class TG4GeometryServices | |
7 | // ------------------------- | |
b68f7176 | 8 | // See the class description in the header file. |
9 | ||
10 | #include "TG4GeometryServices.h" | |
e5967ab3 | 11 | #include "TG4Limits.h" |
12 | #include "TG4IntMap.h" | |
13 | #include "TG4NameMap.h" | |
c4294cc7 | 14 | #include "TG4G3Units.h" |
e5967ab3 | 15 | #include "TG4G3ControlVector.h" |
16 | #include "TG4Globals.h" | |
b68f7176 | 17 | |
b68f7176 | 18 | #include <G4LogicalVolumeStore.hh> |
19 | #include <G4LogicalVolume.hh> | |
20 | #include <G4Material.hh> | |
e5967ab3 | 21 | #include <G4Element.hh> |
e4a64a3a | 22 | #include <G4UserLimits.hh> |
b68f7176 | 23 | #include <G3toG4.hh> |
e5967ab3 | 24 | #include <G3EleTable.hh> |
25 | #include <g4std/vector> | |
fd81f1f5 | 26 | #include <g4std/iomanip> |
e5967ab3 | 27 | |
28 | #include <math.h> | |
b68f7176 | 29 | |
30 | TG4GeometryServices* TG4GeometryServices::fgInstance = 0; | |
e5967ab3 | 31 | const G4double TG4GeometryServices::fgkAZTolerance = 0.001; |
32 | const G4double TG4GeometryServices::fgkDensityTolerance = 0.005; | |
b68f7176 | 33 | |
fed0483a | 34 | //_____________________________________________________________________________ |
e5967ab3 | 35 | TG4GeometryServices::TG4GeometryServices(TG4IntMap* mediumMap, |
b68f7176 | 36 | TG4NameMap* nameMap) |
5b6ecd36 | 37 | : TG4Verbose("geometryServices"), |
38 | fMediumMap(mediumMap), | |
364266ea | 39 | fNameMap(nameMap), |
40 | fWorld(0) | |
b68f7176 | 41 | { |
42 | // | |
43 | if (fgInstance) { | |
44 | TG4Globals::Exception( | |
45 | "TG4GeometryServices: attempt to create two instances of singleton."); | |
46 | } | |
47 | ||
b68f7176 | 48 | fgInstance = this; |
49 | } | |
50 | ||
fed0483a | 51 | //_____________________________________________________________________________ |
5b6ecd36 | 52 | TG4GeometryServices::TG4GeometryServices() |
53 | : TG4Verbose("geometryServices") { | |
b68f7176 | 54 | // |
55 | TG4Globals::Exception( | |
e5967ab3 | 56 | "TG4GeometryServices default constructor is protected."); |
b68f7176 | 57 | } |
58 | ||
59 | ||
fed0483a | 60 | //_____________________________________________________________________________ |
5b6ecd36 | 61 | TG4GeometryServices::TG4GeometryServices(const TG4GeometryServices& right) |
62 | : TG4Verbose("geometryServices") { | |
b68f7176 | 63 | // |
64 | TG4Globals::Exception( | |
65 | "Attempt to copy TG4GeometryServices singleton."); | |
66 | } | |
67 | ||
68 | ||
fed0483a | 69 | //_____________________________________________________________________________ |
b68f7176 | 70 | TG4GeometryServices::~TG4GeometryServices() { |
71 | // | |
72 | } | |
73 | ||
74 | //============================================================================= | |
75 | // | |
76 | // operators | |
77 | // | |
78 | //============================================================================= | |
79 | ||
fed0483a | 80 | //_____________________________________________________________________________ |
b68f7176 | 81 | TG4GeometryServices& |
82 | TG4GeometryServices::operator=(const TG4GeometryServices& right) | |
83 | { | |
84 | // check assignement to self | |
85 | if (this == &right) return *this; | |
86 | ||
87 | TG4Globals::Exception( | |
88 | "Attempt to assign TG4GeometryServices singleton."); | |
89 | ||
90 | return *this; | |
91 | } | |
92 | ||
e5967ab3 | 93 | //============================================================================= |
94 | // | |
95 | // private methods | |
96 | // | |
97 | //============================================================================= | |
98 | ||
99 | //_____________________________________________________________________________ | |
100 | G4bool TG4GeometryServices::IsG3Volume(const G4String& lvName) const | |
101 | { | |
102 | // Returns true if the logical volume of given volumeName | |
103 | // was not created by Gsposp method with a generic name | |
104 | // (name_copyNo). | |
105 | // --- | |
106 | ||
107 | if (lvName.contains(gSeparator)) | |
108 | return false; | |
109 | else | |
110 | return true; | |
111 | } | |
112 | ||
113 | //_____________________________________________________________________________ | |
114 | G4bool TG4GeometryServices::CompareElement(G4double a, G4double z, | |
115 | const G4Element* element) const | |
116 | { | |
117 | // Compares given parameters with those of a given element, | |
118 | // returns true if they are equal, false otherwise. | |
119 | // --- | |
120 | ||
121 | G4double ae = element->GetA()/TG4G3Units::AtomicWeight(); | |
122 | G4double ze = element->GetZ(); | |
123 | ||
124 | // g3tog4 can redefine A | |
7c00fc32 | 125 | G4double ax; |
126 | if (z<1) { | |
127 | // vacuum | |
128 | ax = 1.01*g/mole; | |
129 | } | |
130 | else | |
131 | ax = G3Ele.GetEle(z)->GetA()/TG4G3Units::AtomicWeight(); | |
e5967ab3 | 132 | |
133 | if (abs(ax - ae) < fgkAZTolerance && abs(z - ze) < fgkAZTolerance) | |
134 | return true; | |
135 | else | |
136 | return false; | |
137 | } | |
138 | ||
139 | //_____________________________________________________________________________ | |
140 | G4bool TG4GeometryServices::CompareMaterial(G4int nofElements, G4double density, | |
141 | const G4Material* material) const | |
142 | { | |
143 | // Compares given density with those of a given material, | |
144 | // returns true if they are equal, false otherwise. | |
145 | // --- | |
146 | ||
147 | G4double dm = material->GetDensity()/TG4G3Units::MassDensity(); | |
148 | G4int ne = material->GetNumberOfElements(); | |
149 | ||
150 | // density percentual difference | |
151 | G4double diff = abs(density - dm)/(density + dm)*2.; | |
152 | ||
153 | if (nofElements == ne && diff < fgkDensityTolerance) | |
154 | return true; | |
155 | else | |
156 | return false; | |
157 | } | |
158 | ||
159 | //_____________________________________________________________________________ | |
160 | G4double* TG4GeometryServices::ConvertAtomWeight(G4int nmat, | |
161 | G4double* a, G4double* wmat) const | |
162 | { | |
163 | // In case of proportions given in atom counts (nmat<0), | |
164 | // the wmat[i] are converted to weight fractions. | |
165 | // (From g3tog4 G4gsmixt.) | |
166 | // The new array has to be delete by client. | |
167 | // --- | |
168 | ||
169 | G4double* weight = new G4double[abs(nmat)]; | |
170 | ||
171 | if (nmat<0) { | |
172 | G4double aMol = 0.; | |
173 | G4int i; | |
174 | for (i=0; i<abs(nmat); i++) { | |
175 | // total molecular weight | |
176 | aMol += wmat[i]*a[i]; | |
177 | } | |
178 | if (aMol == 0.) { | |
179 | G4String text = "TG4GeometryServices::ConvertAtomWeight:\n"; | |
180 | text = text + " Total molecular weight = 0"; | |
181 | TG4Globals::Warning(text); | |
182 | } | |
183 | for (G4int i=0; i<abs(nmat); i++) { | |
184 | // weight fractions | |
185 | weight[i] = wmat[i]*a[i]/aMol; | |
186 | } | |
187 | } | |
188 | else | |
189 | for (G4int j=0; j<nmat; j++) weight[j] = wmat[j]; | |
190 | ||
191 | return weight; | |
192 | } | |
b68f7176 | 193 | |
194 | //============================================================================= | |
195 | // | |
196 | // public methods | |
197 | // | |
198 | //============================================================================= | |
199 | ||
fed0483a | 200 | //_____________________________________________________________________________ |
b68f7176 | 201 | G4double* TG4GeometryServices::CreateG4doubleArray(Float_t* array, |
202 | G4int size) const | |
203 | { | |
204 | // Converts Float_t* array to G4double*, | |
205 | // !! The new array has to be deleted by user. | |
206 | // --- | |
207 | ||
208 | G4double* doubleArray; | |
209 | if (size>0) { | |
210 | doubleArray = new G4double[size]; | |
211 | for (G4int i=0; i<size; i++) doubleArray[i] = array[i]; | |
212 | } | |
213 | else { | |
214 | doubleArray = 0; | |
215 | } | |
216 | return doubleArray; | |
217 | } | |
218 | ||
fed0483a | 219 | //_____________________________________________________________________________ |
b68f7176 | 220 | G4String TG4GeometryServices::CutName(const char* name) const |
221 | { | |
222 | // Removes spaces after the name if present. | |
223 | // --- | |
224 | ||
225 | G4String cutName = name; | |
226 | G4int i = cutName.length(); | |
227 | while (cutName(--i) == ' ') cutName = cutName(0,i); | |
228 | ||
229 | return cutName; | |
230 | } | |
231 | ||
fed0483a | 232 | //_____________________________________________________________________________ |
e5967ab3 | 233 | G4String TG4GeometryServices::CutMaterialName(const char* name) const |
234 | { | |
235 | // Removes the $ with precedent spaces at the name if present. | |
236 | // --- | |
237 | ||
238 | G4String cutName = name; | |
239 | cutName = cutName.substr(0,cutName.find('$')); | |
240 | ||
241 | return CutName(cutName); | |
242 | } | |
243 | ||
244 | //_____________________________________________________________________________ | |
245 | G4String TG4GeometryServices::G4ToG3VolumeName(const G4String& name) const | |
b68f7176 | 246 | { |
247 | // Cuts _copyNo extension added to logical volume name in case | |
248 | // the logical volume was created by Gsposp method. | |
249 | // --- | |
250 | ||
e5967ab3 | 251 | G4String cutName = name; |
252 | if (cutName.contains(gSeparator)) | |
253 | cutName = cutName(0,cutName.first(gSeparator)); | |
254 | ||
255 | return cutName; | |
b68f7176 | 256 | } |
257 | ||
fed0483a | 258 | //_____________________________________________________________________________ |
e5967ab3 | 259 | G4String TG4GeometryServices::GenerateLimitsName(G4int id, |
260 | const G4String& medName, | |
261 | const G4String& matName) const | |
e4a64a3a | 262 | { |
e5967ab3 | 263 | // Generate unique name for user limits composed from the tracking medium id, |
264 | // name and its material name. | |
265 | // | |
266 | G4String name = ""; | |
267 | TG4Globals::AppendNumberToString(name, id); | |
268 | name = name + "__med_" + medName + "__mat_" + matName; | |
e4a64a3a | 269 | |
e5967ab3 | 270 | return name; |
e4a64a3a | 271 | } |
b68f7176 | 272 | |
fed0483a | 273 | //_____________________________________________________________________________ |
b68f7176 | 274 | G4Material* TG4GeometryServices::MixMaterials(G4String name, G4double density, |
e5967ab3 | 275 | const TG4StringVector& matNames, |
276 | const TG4doubleVector& matWeights) | |
b68f7176 | 277 | { |
278 | // Creates a mixture of selected materials | |
279 | // --- | |
280 | ||
281 | // number of materials to be mixed | |
e5967ab3 | 282 | G4int nofMaterials = matNames.size(); |
283 | if (nofMaterials != matWeights.size()) { | |
b68f7176 | 284 | G4String text = "TG4GeometryServices::MixMaterials: "; |
285 | text = text + "different number of material names and weigths."; | |
286 | TG4Globals::Exception(text); | |
5b6ecd36 | 287 | } |
288 | ||
289 | if (VerboseLevel() > 1) { | |
290 | G4cout << "Nof of materials to be mixed: " << nofMaterials << G4endl; | |
291 | } | |
b68f7176 | 292 | |
293 | // fill vector of materials | |
e5967ab3 | 294 | G4std::vector<G4Material*> matVector; |
b68f7176 | 295 | G4int im; |
296 | for (im=0; im< nofMaterials; im++) { | |
297 | // material | |
e5967ab3 | 298 | G4Material* material = G4Material::GetMaterial(matNames[im]); |
299 | matVector.push_back(material); | |
b68f7176 | 300 | } |
301 | ||
302 | // create the mixed material | |
303 | G4Material* mixture = new G4Material(name, density, nofMaterials); | |
304 | for (im=0; im< nofMaterials; im++) { | |
305 | G4Material* material = matVector[im]; | |
e5967ab3 | 306 | G4double fraction = matWeights[im]; |
b68f7176 | 307 | mixture->AddMaterial(material, fraction); |
308 | } | |
309 | ||
310 | return mixture; | |
311 | } | |
312 | ||
e5967ab3 | 313 | //_____________________________________________________________________________ |
314 | void TG4GeometryServices::PrintNameMap() const | |
315 | { | |
316 | // Prints the map of volumes names to second names. | |
317 | // --- | |
318 | ||
319 | fNameMap->PrintAll(); | |
320 | } | |
321 | ||
322 | //_____________________________________________________________________________ | |
323 | void TG4GeometryServices::PrintLimits(const G4String& name) const | |
324 | { | |
325 | // Finds the limits with the specified name and prints them. | |
326 | // --- | |
327 | ||
328 | TG4Limits* limits = FindLimits(name, true); | |
329 | ||
330 | if (limits) limits->Print(); | |
331 | } | |
332 | ||
333 | //_____________________________________________________________________________ | |
334 | void TG4GeometryServices::PrintVolumeLimits(const G4String& volumeName) const | |
335 | { | |
336 | // Finds a logical volume with the specified name and prints | |
337 | // its limits. | |
338 | // --- | |
339 | ||
340 | G4LogicalVolume* lv = FindLogicalVolume(volumeName, false); | |
341 | ||
342 | if (lv) { | |
343 | TG4Limits* limits = GetLimits(lv->GetUserLimits()); | |
344 | G4cout << volumeName << " "; | |
345 | if (limits) | |
346 | limits->Print(); | |
347 | else | |
348 | G4cout << "has not the limits set." << G4endl; | |
349 | } | |
350 | } | |
351 | ||
352 | //_____________________________________________________________________________ | |
353 | void TG4GeometryServices::PrintStatistics(G4bool open, G4bool close) const | |
354 | { | |
355 | // Print G4 geometry statistics | |
356 | // --- | |
357 | ||
358 | ||
359 | if (open) TG4Globals::PrintStars(true); | |
360 | ||
361 | G4cout << " GEANT4 Geometry statistics: " << G4endl | |
fd81f1f5 | 362 | << " " << G4std::setw(5) << NofG4LogicalVolumes() |
e5967ab3 | 363 | << " logical volumes" << G4endl |
364 | << " " | |
fd81f1f5 | 365 | << G4std::setw(5) << NofG4PhysicalVolumes() |
e5967ab3 | 366 | << " physical volumes" << G4endl |
367 | << " " | |
fd81f1f5 | 368 | << G4std::setw(5) << G4Material::GetNumberOfMaterials() |
e5967ab3 | 369 | << " materials" << G4endl |
370 | << " " | |
fd81f1f5 | 371 | << G4std::setw(5) << TG4Limits::GetNofLimits() |
e5967ab3 | 372 | << " user limits" << G4endl; |
373 | ||
374 | if (close) TG4Globals::PrintStars(false); | |
375 | } | |
376 | ||
fd81f1f5 | 377 | //_____________________________________________________________________________ |
378 | void | |
379 | TG4GeometryServices::PrintLogicalVolumeStore() const | |
380 | { | |
381 | // Prints all logical volumes and their daughters. | |
382 | // --- | |
383 | ||
384 | G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance(); | |
385 | ||
386 | G4cout << "Logical volume store: " << G4endl; | |
387 | ||
388 | for (G4int i=0; i<lvStore->size(); i++) { | |
389 | ||
390 | G4LogicalVolume* lv = (*lvStore)[i]; | |
391 | ||
392 | G4cout << "Logical volume: " << G4endl; | |
393 | G4cout << " " << G4std::setw(5) << i | |
394 | << " " << lv | |
395 | << " " << lv->GetName() | |
396 | << " " << G4std::setw(5) << lv->GetNoDaughters() << " daughters" | |
397 | << " limits: " << lv->GetUserLimits() | |
398 | << G4endl; | |
399 | ||
400 | for (G4int j=0; j<lv->GetNoDaughters(); j++) { | |
401 | G4cout << " Daughter: " | |
402 | << G4std::setw(5) << j | |
403 | << " " << lv->GetDaughter(j) | |
404 | << " " << lv->GetDaughter(j)->GetName() | |
405 | << " of LV: " << lv->GetDaughter(j)->GetLogicalVolume() | |
406 | << " " << lv->GetDaughter(j)->GetLogicalVolume()->GetName() | |
407 | << " copy no: " << lv->GetDaughter(j)->GetCopyNo() | |
408 | << G4endl; | |
409 | ||
410 | } | |
411 | } | |
412 | } | |
413 | ||
fed0483a | 414 | //_____________________________________________________________________________ |
415 | Int_t TG4GeometryServices::NofG3Volumes() const | |
b68f7176 | 416 | { |
417 | // Returns the total number of logical volumes corresponding | |
418 | // to G3 volumes. ( | |
419 | // The logical volume that were created by Gsposp method | |
420 | // with a generic name (name_copyNo) are NOT included. | |
421 | // --- | |
422 | ||
e5967ab3 | 423 | G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance(); |
b68f7176 | 424 | |
425 | G4int counter = 0; | |
e5967ab3 | 426 | for (G4int i=0; i<lvStore->size(); i++) { |
427 | G4LogicalVolume* lv = (*lvStore)[i]; | |
b68f7176 | 428 | if (IsG3Volume(lv->GetName())) counter++; |
429 | } | |
430 | ||
431 | return counter; | |
432 | } | |
433 | ||
fed0483a | 434 | //_____________________________________________________________________________ |
b68f7176 | 435 | Int_t TG4GeometryServices::NofG4LogicalVolumes() const |
436 | { | |
437 | // Returns the total number of logical volumes in the geometry. | |
438 | // --- | |
439 | ||
e5967ab3 | 440 | G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance(); |
441 | return lvStore->size(); | |
b68f7176 | 442 | } |
443 | ||
fed0483a | 444 | //_____________________________________________________________________________ |
b68f7176 | 445 | Int_t TG4GeometryServices::NofG4PhysicalVolumes() const |
446 | { | |
447 | // Returns the total number of physical volumes in the geometry. | |
448 | // --- | |
449 | ||
e5967ab3 | 450 | G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance(); |
b68f7176 | 451 | |
452 | G4int counter = 0; | |
e5967ab3 | 453 | for (G4int i=0; i<lvStore->size(); i++) { |
454 | counter += ((*lvStore)[i])->GetNoDaughters(); | |
b68f7176 | 455 | } |
456 | ||
457 | return counter; | |
458 | } | |
459 | ||
e5967ab3 | 460 | |
461 | //______________________________________________________________________________ | |
462 | G4bool TG4GeometryServices::IsSpecialControls() const | |
b68f7176 | 463 | { |
e5967ab3 | 464 | // Returns true if a process control in some limits instance is set. |
b68f7176 | 465 | // --- |
466 | ||
e5967ab3 | 467 | G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance(); |
468 | ||
469 | for (G4int i=0; i<lvStore->size(); i++) { | |
470 | TG4Limits* limits = GetLimits((*lvStore)[i]->GetUserLimits()); | |
471 | if (limits && limits->IsControl()) return true; | |
472 | } | |
473 | ||
474 | return false; | |
b68f7176 | 475 | } |
476 | ||
e5967ab3 | 477 | //_____________________________________________________________________________ |
478 | TG4Limits* TG4GeometryServices::GetLimits(G4UserLimits* limits) const | |
479 | { | |
480 | // Checks and converts type of the given limits. | |
481 | // --- | |
482 | ||
483 | if (!limits) return 0; | |
484 | ||
485 | TG4Limits* tg4Limits = dynamic_cast<TG4Limits*> (limits); | |
486 | ||
487 | if (!tg4Limits) { | |
488 | G4Exception("TG4GeometryServices::GetLimits: Wrong limits type."); | |
489 | return 0; | |
490 | } | |
491 | else | |
492 | return tg4Limits; | |
493 | } | |
494 | ||
fed0483a | 495 | //_____________________________________________________________________________ |
b68f7176 | 496 | const G4String& TG4GeometryServices::GetMapSecond(const G4String& name) |
497 | { | |
498 | // Returns the second string associated with the name in | |
499 | // the name map. | |
500 | // --- | |
501 | ||
502 | return fNameMap->GetSecond(name); | |
503 | } | |
504 | ||
e5967ab3 | 505 | //_____________________________________________________________________________ |
506 | G4LogicalVolume* | |
507 | TG4GeometryServices::FindLogicalVolume(const G4String& name, G4bool silent) const | |
508 | { | |
509 | // Finds a logical volume with the specified name in G4LogicalVolumeStore. | |
510 | // --- | |
511 | ||
512 | G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance(); | |
513 | ||
514 | for (G4int i=0; i<lvStore->size(); i++) { | |
515 | G4LogicalVolume* lv = (*lvStore)[i]; | |
516 | if (lv->GetName() == name) return lv; | |
517 | } | |
518 | ||
519 | if (!silent) { | |
520 | G4String text = "TG4GeometryServices:: FindLogicalVolume:\n"; | |
521 | text = text + " Logical volume " + name + " does not exist."; | |
522 | TG4Globals::Warning(text); | |
523 | } | |
524 | return 0; | |
525 | } | |
526 | ||
fed0483a | 527 | //_____________________________________________________________________________ |
e5967ab3 | 528 | TG4Limits* |
529 | TG4GeometryServices::FindLimits(const G4String& name, G4bool silent) const | |
530 | { | |
531 | // Finds limits with the specified name. | |
532 | // --- | |
533 | ||
534 | G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance(); | |
535 | ||
536 | for (G4int i=0; i<lvStore->size(); i++) { | |
537 | G4LogicalVolume* lv = (*lvStore)[i]; | |
538 | TG4Limits* limits = GetLimits(lv->GetUserLimits()); | |
539 | if (limits && limits->GetName() == name) return limits; | |
540 | } | |
541 | ||
542 | if (!silent) { | |
543 | G4String text = "TG4GeometryServices:: FindLimits:\n"; | |
544 | text = text + " Logical volume " + name + " does not exist."; | |
545 | TG4Globals::Warning(text); | |
546 | } | |
547 | return 0; | |
548 | } | |
549 | ||
550 | //_____________________________________________________________________________ | |
551 | G4int TG4GeometryServices::GetMediumId(G4LogicalVolume* lv) const | |
b68f7176 | 552 | { |
553 | // Returns the second index for materials (having its origin in | |
554 | // G4 tracking media concept) | |
555 | // --- | |
556 | ||
e5967ab3 | 557 | return fMediumMap->GetSecond(lv->GetName()); |
b68f7176 | 558 | } |
559 | ||
fed0483a | 560 | //_____________________________________________________________________________ |
b68f7176 | 561 | G4double TG4GeometryServices::GetEffA(G4Material* material) const |
562 | { | |
563 | // Returns A or effective A=sum(pi*Ai) (if compound/mixture) | |
564 | // of given material. | |
565 | // --- | |
566 | ||
567 | G4double a = 0.; | |
568 | G4int nofElements = material->GetNumberOfElements(); | |
569 | if (nofElements > 1) { | |
570 | G4String text = "Effective A for material mixture ("; | |
571 | text = text + material->GetName(); | |
572 | text = text + ") is used."; | |
573 | //TG4Globals::Warning(text); | |
574 | ||
575 | for (G4int i=0; i<nofElements; i++) { | |
576 | G4double aOfElement = material->GetElement(i)->GetA(); | |
577 | G4double massFraction = material->GetFractionVector()[i]; | |
c4294cc7 | 578 | a += aOfElement*massFraction /(TG4G3Units::AtomicWeight()); |
b68f7176 | 579 | } |
580 | } | |
581 | else { | |
582 | a = material->GetA(); | |
c4294cc7 | 583 | a /= TG4G3Units::AtomicWeight(); |
b68f7176 | 584 | } |
585 | return a; | |
586 | } | |
587 | ||
fed0483a | 588 | //_____________________________________________________________________________ |
b68f7176 | 589 | G4double TG4GeometryServices::GetEffZ(G4Material* material) const |
590 | { | |
591 | // Returns Z or effective Z=sum(pi*Zi) (if compound/mixture) | |
592 | // of given material. | |
593 | // --- | |
594 | ||
595 | G4double z = 0.; | |
596 | G4int nofElements = material->GetNumberOfElements(); | |
597 | if (nofElements > 1) { | |
598 | G4String text = "Effective Z for material mixture ("; | |
599 | text = text + material->GetName(); | |
600 | text = text + ") is used."; | |
601 | //TG4Globals::Warning(text); | |
602 | ||
603 | for (G4int i=0; i<nofElements; i++) { | |
604 | G4double zOfElement = material->GetElement(i)->GetZ(); | |
605 | G4double massFraction = material->GetFractionVector()[i]; | |
606 | z += zOfElement*massFraction; | |
607 | } | |
608 | } | |
609 | else { | |
610 | z = material->GetZ(); | |
611 | } | |
612 | return z; | |
613 | } | |
e5967ab3 | 614 | |
615 | //_____________________________________________________________________________ | |
616 | G4Material* TG4GeometryServices::FindMaterial(G4double a, G4double z, | |
617 | G4double density) const | |
618 | { | |
619 | // Finds material in G4MaterialTable with specified parameters, | |
620 | // returns 0 if not found. | |
621 | // --- | |
622 | ||
623 | const G4MaterialTable* kpMatTable = G4Material::GetMaterialTable(); | |
624 | ||
625 | for (G4int i=0; i<G4Material::GetNumberOfMaterials(); i++) { | |
626 | ||
627 | G4Material* material = (*kpMatTable)[i]; | |
628 | ||
629 | if (CompareElement(a, z, material->GetElement(0)) && | |
630 | CompareMaterial(1, density, material)) | |
631 | ||
632 | return material; | |
633 | } | |
634 | ||
635 | return 0; | |
636 | } | |
637 | ||
638 | //_____________________________________________________________________________ | |
639 | G4Material* TG4GeometryServices::FindMaterial(G4double* a, G4double* z, | |
640 | G4double density, | |
641 | G4int nmat, G4double* wmat) const | |
642 | { | |
643 | // Finds material in G4MaterialTable with specified parameters, | |
644 | // returns 0 if not found. | |
645 | // --- | |
646 | ||
647 | G4double* weight = ConvertAtomWeight(nmat, a, wmat); | |
648 | ||
649 | // loop over materials | |
650 | G4Material* found = 0; | |
651 | for (G4int i=0; i<G4Material::GetNumberOfMaterials(); i++) { | |
652 | ||
653 | G4Material* material = (*G4Material::GetMaterialTable())[i]; | |
654 | G4int nm = material->GetNumberOfElements(); | |
655 | ||
656 | if (CompareMaterial(nm, density, material)) { | |
657 | ||
658 | // loop over elements | |
659 | G4bool equal = true; | |
660 | for (G4int ie=0; ie<nm; ie++) { | |
661 | ||
662 | G4double we = (material->GetFractionVector())[ie]; | |
663 | ||
664 | if (!CompareElement(a[ie], z[ie], material->GetElement(ie)) || | |
665 | abs(weight[ie] - we) > fgkAZTolerance) { | |
666 | ||
667 | equal = false; | |
668 | break; | |
669 | } | |
670 | } | |
671 | if (equal) { | |
672 | found = material; | |
673 | break; | |
674 | } | |
675 | } | |
676 | } | |
677 | ||
678 | delete [] weight; | |
679 | return found; | |
680 | } | |
681 |