]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TGeant4/TG4GeometryServices.cxx
Corrected bug in constructor (fIshunt has to be =1)
[u/mrichter/AliRoot.git] / TGeant4 / TG4GeometryServices.cxx
1 // $Id$
2 // Category: geometry
3 //
4 // See the class description in the header file.
5
6 #include "TG4GeometryServices.h"
7 #include "TG4VSensitiveDetector.h"
8 #include "TG4Globals.h"
9 #include "TG4G3Units.h"
10
11 #include <G4VSensitiveDetector.hh>
12 #include <G4LogicalVolumeStore.hh>
13 #include <G4LogicalVolume.hh>
14 #include <G4Material.hh>
15 #include <G4UserLimits.hh>
16 #include <G3toG4.hh> 
17
18 TG4GeometryServices* TG4GeometryServices::fgInstance = 0;
19
20 TG4GeometryServices::TG4GeometryServices(TG4intVector* mediumIdVector, 
21                                          TG4NameMap* nameMap) 
22 {
23 //
24   if (fgInstance) {
25     TG4Globals::Exception(
26       "TG4GeometryServices: attempt to create two instances of singleton.");
27   }
28
29   fMediumIdVector = mediumIdVector;
30   fNameMap = nameMap;
31
32   fgInstance = this;
33 }
34
35 TG4GeometryServices::TG4GeometryServices() {
36 // 
37   TG4Globals::Exception(
38     "Attempt to copy TG4GeometryServices singleton.");
39 }
40
41
42 TG4GeometryServices::TG4GeometryServices(const TG4GeometryServices& right) {
43 // 
44   TG4Globals::Exception(
45     "Attempt to copy TG4GeometryServices singleton.");
46 }
47
48
49 TG4GeometryServices::~TG4GeometryServices() {
50 //
51 }
52
53 //=============================================================================
54 //
55 // operators
56 //
57 //=============================================================================
58
59 TG4GeometryServices& 
60 TG4GeometryServices::operator=(const TG4GeometryServices& right)
61 {
62   // check assignement to self
63   if (this == &right) return *this;
64
65   TG4Globals::Exception(
66     "Attempt to assign TG4GeometryServices singleton.");
67     
68   return *this;  
69 }    
70           
71
72 //=============================================================================
73 //
74 // public methods
75 //
76 //=============================================================================
77
78
79 G4double* TG4GeometryServices::CreateG4doubleArray(Float_t* array, 
80                G4int size) const
81 {
82 // Converts Float_t* array to G4double*,
83 // !! The new array has to be deleted by user.
84 // ---
85
86   G4double* doubleArray;
87   if (size>0) {
88     doubleArray = new G4double[size]; 
89     for (G4int i=0; i<size; i++) doubleArray[i] = array[i];
90   }
91   else {
92     doubleArray = 0; 
93   }  
94   return doubleArray;
95 }
96
97
98 G4String TG4GeometryServices::CutName(const char* name) const
99 {
100 // Removes spaces after the name if present.
101 // ---
102
103   G4String cutName = name;
104   G4int i = cutName.length();
105   while (cutName(--i) == ' ') cutName = cutName(0,i);
106
107   return cutName;
108 }  
109
110 void TG4GeometryServices::G4ToG3VolumeName(G4String& name) const
111 {
112 // Cuts _copyNo extension added to logical volume name in case 
113 // the logical volume was created by Gsposp method.
114 // ---
115
116   if (name.contains(gSeparator)) 
117   name = name(0,name.first(gSeparator));
118 }
119
120 G4int TG4GeometryServices::SetUserLimits(G4UserLimits* userLimits, 
121                                          G4LogicalVolume* lv)
122 {
123 // Sets user limits to all logical volumes corresponding to 
124 // the same G3 volume as the volume with specified name.
125 // Returns the number of updated logical volumes.
126 // ---  
127
128   G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
129
130   G4String volName = lv->GetName();
131   G4ToG3VolumeName(volName);
132
133   G4int counter = 0;
134   for (G4int i=0; i<pLVStore->entries(); i++) {
135     G4LogicalVolume* lv = (*pLVStore)[i];
136     G4String name = lv->GetName();
137     G4ToG3VolumeName(name);
138     if (name == volName) {
139       lv->SetUserLimits(userLimits);
140       counter++;
141     }  
142   }
143   
144   return counter;
145 }
146
147 G4Material* TG4GeometryServices::MixMaterials(G4String name, G4double density, 
148         TG4StringVector* matNames, TG4doubleVector* matWeights)
149 {
150 // Creates a mixture of selected materials
151 // ---
152
153   // number of materials to be mixed  
154   G4int nofMaterials = matNames->entries();
155   if (nofMaterials != matWeights->entries()) {
156     G4String text = "TG4GeometryServices::MixMaterials: ";
157     text = text +  "different number of material names and weigths.";
158     TG4Globals::Exception(text);
159   }    
160   // add verbose
161   // G4cout << "Nof of materials to be mixed: " << nofMaterials << G4endl;
162
163   // fill vector of materials
164   TG4MaterialVector matVector;  
165   G4int im;
166   for (im=0; im< nofMaterials; im++) {
167     // material
168     G4Material* material = G4Material::GetMaterial((*matNames)[im]);
169     matVector.insert(material);
170   } 
171
172   // create the mixed material
173   G4Material* mixture = new G4Material(name, density, nofMaterials);
174   for (im=0; im< nofMaterials; im++) {
175     G4Material* material = matVector[im];
176     G4double fraction = (*matWeights)[im];
177     mixture->AddMaterial(material, fraction);
178   }
179
180   return mixture;
181 }  
182
183
184  Int_t TG4GeometryServices::NofG3Volumes() const
185 {
186 // Returns the total number of logical volumes corresponding
187 // to G3 volumes. (
188 // The logical volume that were created by Gsposp method 
189 // with a generic name (name_copyNo) are NOT included.
190 // ---
191
192   G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
193
194   G4int counter = 0;  
195   for (G4int i=0; i<pLVStore->entries(); i++) {
196     G4LogicalVolume* lv = (*pLVStore)[i];
197     if (IsG3Volume(lv->GetName())) counter++;
198   }
199   
200   return counter;  
201 }
202
203
204 Int_t TG4GeometryServices::NofG4LogicalVolumes() const
205 {
206 // Returns the total number of logical volumes in the geometry.
207 // ---
208
209   G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
210   return pLVStore->entries();
211 }
212
213
214 Int_t TG4GeometryServices::NofG4PhysicalVolumes() const
215 {
216 // Returns the total number of physical volumes in the geometry.
217 // ---
218
219   G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
220
221   G4int counter = 0;
222   for (G4int i=0; i<pLVStore->entries(); i++) {
223     counter += ((*pLVStore)[i])->GetNoDaughters();
224   }
225   
226   return counter;  
227 }
228
229
230 Int_t TG4GeometryServices::NofSensitiveDetectors() const
231 {
232 // Returns the total number of sensitive detectors.
233 // ---
234
235   return TG4VSensitiveDetector::GetTotalNofSensitiveDetectors();
236 }
237
238  
239 G4int TG4GeometryServices::GetVolumeID(const G4String& volName) const
240
241 // Returns the sensitive detector identifier.
242 // !! Gives exception in case logical volume is not associated with 
243 // a sensitive detector.
244 // ---
245
246   G4String g4VolName = CutName(volName);
247   G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
248   
249   for (G4int i=0; i<pLVStore->entries(); i++) {
250     G4LogicalVolume* lv = pLVStore->at(i);
251     G4VSensitiveDetector* sd = lv->GetSensitiveDetector();
252   
253     if ((sd) && (sd->GetName()==g4VolName)) {
254       TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
255       if (tsd)
256         return tsd->GetID();
257       else {
258         TG4Globals::Exception(
259           "TG4GeometryServices::GetVolumeID: Unknown sensitive detector type");
260         return 0;
261       }
262     }   
263   }
264
265   G4String text = "TG4GeometryServices::VolId: Sensitive detector ";
266   text = text + g4VolName;
267   text = text + " is not defined.\n"; 
268   TG4Globals::Warning(text);
269   return 0;
270 }
271
272
273 G4int TG4GeometryServices::GetVolumeID(G4LogicalVolume* logicalVolume) const 
274 {
275 // Returns the sensitive detector ID of the specified
276 // logical volume.
277 // ---
278  
279   // sensitive detector ID
280   G4VSensitiveDetector* sd
281     = logicalVolume->GetSensitiveDetector();
282   if (sd) {
283     TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
284     if (tsd)
285       return tsd->GetID();
286     else {
287       TG4Globals::Exception(
288         "TG4GeometryServices::GetVolumeID: Unknown sensitive detector type");
289       return 0;
290     }           
291   }  
292   else {
293     G4String text = "TG4GeometryServices::GetVolumeID: \n";
294     text = text + "    Volume " + logicalVolume->GetName();
295     text = text + " has not a sensitive detector.";
296     //TG4Globals::Exception(text);
297     TG4Globals::Warning(text);
298     return 0;
299   }             
300
301
302
303 G4String TG4GeometryServices::GetVolumeName(G4int volumeId) const
304 {
305 // Returns the name of the sensitive detector with the given identifier.
306 // Gives a warning in case logical volume is not associated with 
307 // a sensitive detector.
308 // ---
309
310   G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
311   
312   for (G4int i=0; i<pLVStore->entries(); i++) {
313     G4LogicalVolume* lv = pLVStore->at(i);
314     G4VSensitiveDetector* sd = lv->GetSensitiveDetector();
315     
316     if (sd) {
317       G4int sdID;
318       TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
319       if (tsd)
320         sdID = tsd->GetID();
321       else {
322         TG4Globals::Exception(
323           "TG4GeometryServices::VolId: Unknown sensitive detector type");
324         return "";
325       }
326       if (sdID == volumeId) return sd->GetName();
327     }  
328   }
329
330   G4String text = "TG4GeometryServices::VolName:\n";
331   text = text + "    Sensitive detector with given id is not defined. \n";
332   TG4Globals::Warning(text);
333   return "";                     
334 }
335
336
337 G4LogicalVolume* TG4GeometryServices::GetLogicalVolume(G4int volumeId) const 
338 {
339 // Finds the first logical volume with specified volumeId 
340 // (sensitive detector ID) in G4LogicalVolumeStore.
341 // ---
342
343   G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
344   
345   for (G4int i=0; i<pLVStore->entries(); i++) {
346     G4LogicalVolume* lv = pLVStore->at(i);
347     if (GetVolumeID(lv) == volumeId) return lv;
348   }
349   
350   G4String text = "TG4GeometryServices::GetLogicalVolume: \n";
351   text = text + "    Logical volume with given ID does not exist.";
352   return 0;                      
353 }  
354
355
356 G4bool TG4GeometryServices::IsG3Volume(const G4String& lvName) const
357 {
358 // Returns true if the logical volume of given volumeName
359 // was not created by Gsposp method with a generic name 
360 // (name_copyNo).
361 // ---
362
363   if (lvName.contains(gSeparator))
364     return false;  
365   else
366     return true;   
367 }
368
369
370 const G4String& TG4GeometryServices::GetMapSecond(const G4String& name)
371
372 // Returns the second string associated with the name in
373 // the name map.
374 // ---
375
376   return fNameMap->GetSecond(name); 
377 }
378
379
380 G4int TG4GeometryServices::GetMediumId(G4Material* material) const
381 {
382 // Returns the second index for materials (having its origin in
383 // G4 tracking media concept)
384 // ---
385
386   return (*fMediumIdVector)[material->GetIndex()];
387 }  
388
389
390 Int_t TG4GeometryServices::GetMediumId(G4int volumeId)  const
391 {
392 // Return the material number for a given volume id
393 // ---
394
395   G4LogicalVolume* logicalVolume = GetLogicalVolume(volumeId);
396     
397   G4Material* material = logicalVolume->GetMaterial();  
398
399   return GetMediumId(material);                  
400 }
401  
402
403 G4double TG4GeometryServices::GetEffA(G4Material* material) const
404 {
405 // Returns A or effective A=sum(pi*Ai) (if compound/mixture)
406 // of given material.
407 // ---
408
409   G4double a = 0.;
410   G4int nofElements = material->GetNumberOfElements();
411   if (nofElements > 1) {
412     G4String text = "Effective A for material mixture (";
413     text = text + material->GetName();
414     text = text + ") is used.";
415     //TG4Globals::Warning(text);
416
417     for (G4int i=0; i<nofElements; i++) {
418       G4double aOfElement = material->GetElement(i)->GetA();
419       G4double massFraction = material->GetFractionVector()[i];      
420       a += aOfElement*massFraction /(TG4G3Units::AtomicWeight());
421     }
422   }
423   else { 
424     a = material->GetA();
425     a /= TG4G3Units::AtomicWeight();
426   }
427   return a;
428 }
429
430
431 G4double TG4GeometryServices::GetEffZ(G4Material* material) const
432 {
433 // Returns Z or effective Z=sum(pi*Zi) (if compound/mixture)
434 // of given material.
435 // ---
436
437   G4double z = 0.;
438   G4int nofElements = material->GetNumberOfElements();
439   if (nofElements > 1) {
440     G4String text = "Effective Z for material mixture (";
441     text = text + material->GetName();
442     text = text + ") is used.";
443     //TG4Globals::Warning(text);
444
445     for (G4int i=0; i<nofElements; i++) {
446       G4double zOfElement = material->GetElement(i)->GetZ();
447       G4double massFraction = material->GetFractionVector()[i];
448       z += zOfElement*massFraction;
449     }
450   }
451   else { 
452     z = material->GetZ(); 
453   }  
454   return z;
455 }