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