G4Root Version 6.6
Loading...
Searching...
No Matches
TG4RootDetectorConstruction.cxx
Go to the documentation of this file.
1// @(#)root/g4root:$Id$
2// Author: Andrei Gheata 07/08/06
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
16
18#include "TG4RootNavMgr.h"
19#include "TG4RootNavigator.h"
20#include "TG4RootSolid.h"
21
22#include "G4FieldManager.hh"
23#include "G4GeometryManager.hh"
24#include "G4LogicalVolumeStore.hh"
25#include "G4Material.hh"
26#include "G4PVPlacement.hh"
27#include "G4PhysicalConstants.hh"
28#include "G4PhysicalVolumeStore.hh"
29#include "G4SolidStore.hh"
30#include "G4SystemOfUnits.hh"
31#include "G4UnitsTable.hh"
32
33#include "TGeoManager.h"
34#include "TGeoMatrix.h"
35
36#include "TList.h"
37
38// ClassImp(TG4RootDetectorConstruction)
39
40//______________________________________________________________________________
43 fIsConstructed(kFALSE),
44 fGeometry(0),
45 fTopPV(0),
46 fSDInit(0)
47{
49}
50
51//______________________________________________________________________________
54 fIsConstructed(kFALSE),
55 fGeometry(geom),
56 fTopPV(0),
57 fSDInit(0)
58{
60 if (!geom || !geom->IsClosed()) {
61 G4Exception("TG4RootDetectorConstruction::TG4RootDetectorConstruction",
62 "G4Root_F001", FatalException,
63 "Cannot create TG4RootDetectorConstruction without closed ROOT geometry "
64 "!");
65 }
66}
67
68//______________________________________________________________________________
70{
72// if (fGeometry) delete fGeometry;
73#ifdef G4GEOMETRY_VOXELDEBUG
74 G4cout << "Deleting Materials ... ";
75#endif
76 G4MaterialTable* mtab = (G4MaterialTable*)G4Material::GetMaterialTable();
77 std::vector<G4Material*>::iterator pos;
78 G4int icount = 0;
79 for (pos = mtab->begin(); pos != mtab->end(); pos++) {
80 if (*pos) {
81 delete *pos;
82 icount++;
83 }
84 }
85#ifdef G4GEOMETRY_VOXELDEBUG
86 G4cout << icount << " materials deleted !" << G4endl;
87 G4cout << "Deleting Elements ... ";
88#endif
89 G4ElementTable* eltab = (G4ElementTable*)G4Element::GetElementTable();
90 std::vector<G4Element*>::iterator pos1;
91 icount = 0;
92 for (pos1 = eltab->begin(); pos1 != eltab->end(); pos1++) {
93 if (*pos1) {
94 delete *pos1;
95 icount++;
96 }
97 }
98#ifdef G4GEOMETRY_VOXELDEBUG
99 G4cout << icount << " elements deleted !" << G4endl;
100 G4cout << "Deleting Rotations ... ";
101#endif
102 G4PhysicalVolumeStore* pvstore = G4PhysicalVolumeStore::GetInstance();
103 std::vector<G4VPhysicalVolume*>::iterator pos2;
104 icount = 0;
105 for (pos2 = pvstore->begin(); pos2 != pvstore->end(); pos2++) {
106 if (*pos2 && (*pos2)->GetRotation()) {
107 delete (*pos2)->GetRotation();
108 icount++;
109 }
110 }
111#ifdef G4GEOMETRY_VOXELDEBUG
112 G4cout << icount << " rotations deleted !" << G4endl;
113#endif
114 G4GeometryManager* mgr = G4GeometryManager::GetInstance();
115 mgr->OpenGeometry();
116 pvstore->Clean();
117 G4LogicalVolumeStore* lvstore = G4LogicalVolumeStore::GetInstance();
118 lvstore->Clean();
119 G4SolidStore* sstore = G4SolidStore::GetInstance();
120 sstore->Clean();
121 if (fSDInit) delete fSDInit;
122}
123
124//______________________________________________________________________________
127{
129 if (sdinit) {
130 if (fSDInit) delete fSDInit;
131 fSDInit = sdinit;
132 }
133 if (!fIsConstructed) {
134 Construct();
135 if (fSDInit) fSDInit->Initialize(this);
136 }
137}
138
139//______________________________________________________________________________
141{
143 if (!fGeometry || !fGeometry->IsClosed()) {
144 G4Exception("TG4RootDetectorConstruction::Construct", "G4Root_F001",
145 FatalException,
146 "Cannot create TG4RootDetectorConstruction without closed ROOT geometry "
147 "!");
148 }
149 if (fTopPV) return fTopPV;
150 // Convert reflections via TGeo reflection factory
151 fGeometry->ConvertReflections();
153 // CreateG4LogicalVolumes();
156 TG4RootNavigator* nav = navMgr->GetNavigator();
157 nav->SetDetectorConstruction(this);
158 nav->SetWorldVolume(fTopPV);
159 G4cout << "### INFO: TG4RootDetectorConstruction::Construct() finished"
160 << G4endl;
161 fIsConstructed = kTRUE;
162 return fTopPV;
163}
164
165//______________________________________________________________________________
167{
168 G4cout << "TG4RootDetectorConstruction::ConstructSDandField" << G4endl;
170 G4cout
171 << "### INFO: TG4RootDetectorConstruction::ConstructSDandField finished"
172 << G4endl;
173}
174
175//______________________________________________________________________________
177{
179 TIter next(fGeometry->GetListOfVolumes());
180 TGeoVolume* vol;
181 while ((vol = (TGeoVolume*)next())) {
183 }
184 G4cout << "===> GEANT4 logical volumes created and mapped to TGeo ones..."
185 << G4endl;
186}
187
188//______________________________________________________________________________
190{
192 TGeoNode* node = fGeometry->GetTopNode();
194 TGeoIterator next(fGeometry->GetTopVolume());
195 TGeoNode* mother;
196 while ((node = next())) {
197 mother = next.GetNode(next.GetLevel() - 1);
198 if (mother && node->GetMotherVolume() != mother->GetVolume())
199 node->SetMotherVolume(mother->GetVolume());
201 }
202
203 G4cout
204 << "===> GEANT4 physical volumes created and mapped to TGeo hierarchy..."
205 << G4endl;
206}
207
208//______________________________________________________________________________
210{
213 if (G4UnitDefinition::GetUnitsTable().size() == 0)
214 G4UnitDefinition::BuildUnitsTable();
215 // G4cout << "Units table: " << G4endl;
216 // G4UnitDefinition::PrintUnitsTable();
217 // CreateG4Elements();
218 TIter next(fGeometry->GetListOfMaterials());
219 TGeoMaterial* mat;
220 while ((mat = (TGeoMaterial*)next())) CreateG4Material(mat);
221 G4cout << "===> GEANT4 materials created and mapped to TGeo ones..."
222 << G4endl;
223}
224
225//______________________________________________________________________________
227{
229 TGeoElementTable* table = fGeometry->GetElementTable();
230 Int_t nelements = table->GetNelements();
231 TGeoElement* elem;
232 G4double a, z;
233 G4String name, symbol;
234 for (Int_t i = 0; i < nelements; i++) {
235 elem = table->GetElement(i);
236 a = G4double(elem->A()) * (g / mole);
237 z = G4double(elem->Z());
238 if ((z < 1) || (z > 101)) continue;
239 name = elem->GetTitle();
240 symbol = elem->GetName();
241 new G4Element(name, symbol, z, a);
242 }
243 G4cout << "===> GEANT4 elements created..." << G4endl;
244}
245
246//______________________________________________________________________________
248 TGeoVolume* vol)
249{
252 if (!vol) return NULL;
253 G4LogicalVolume* pVolume = GetG4Volume(vol);
254 if (pVolume) return pVolume;
255 G4String sname(vol->GetName());
256 G4VSolid* pSolid = CreateG4Solid(vol->GetShape());
257 if (!pSolid) {
258 G4ExceptionDescription description;
259 description << " " << "Cannot make solid from shape: "
260 << vol->GetShape()->GetName();
261 G4Exception("TG4RootDetectorConstruction::CreateG4LogicalVolume",
262 "G4Root_F002", FatalException, description);
263 }
264 G4Material* pMaterial = 0;
265 if (vol->IsAssembly()) {
266 pMaterial =
267 GetG4Material((TGeoMaterial*)fGeometry->GetListOfMaterials()->At(0));
268 }
269 else {
270 pMaterial = GetG4Material(vol->GetMedium()->GetMaterial());
271 }
272 if (!pMaterial) {
273 G4ExceptionDescription description;
274 description << " "
275 << "Cannot make material for volume: " << vol->GetName()
276 << G4endl;
277 G4Exception("TG4RootDetectorConstruction::CreateG4LogicalVolume",
278 "G4Root_F003", FatalException, description);
279 }
280 pVolume =
281 new G4LogicalVolume(pSolid, pMaterial, sname, NULL, NULL, NULL, false);
282 fG4VolumeMap.insert(G4VolumeVal_t(vol, pVolume));
283 fVolumeMap.insert(VolumeVal_t(pVolume, vol));
284 return pVolume;
285}
286
287//______________________________________________________________________________
289 TGeoNode* node)
290{
292 if (!node) return NULL;
293 node->cd();
294 G4VPhysicalVolume* pPhysicalVolume = GetG4VPhysicalVolume(node);
295 if (pPhysicalVolume) return pPhysicalVolume;
296 TGeoMatrix* mat = node->GetMatrix();
297 const Double_t* tr = mat->GetTranslation();
298 G4ThreeVector tlate(tr[0] * cm, tr[1] * cm, tr[2] * cm);
299 G4RotationMatrix* pRot = CreateG4Rotation(mat);
300 G4String pName(node->GetVolume()->GetName());
301 G4LogicalVolume* pCurrentLogical = CreateG4LogicalVolume(node->GetVolume());
302 if (!pCurrentLogical) {
303 G4ExceptionDescription description;
304 description << " " << "No G4 volume created for TGeo node "
305 << node->GetName() << G4endl;
306 G4Exception("TG4RootDetectorConstruction::CreateG4PhysicalVolume",
307 "G4Root_F004", FatalException, description);
308 }
309 G4LogicalVolume* pMotherLogical =
310 CreateG4LogicalVolume(node->GetMotherVolume());
311 if (!pMotherLogical && node != fGeometry->GetTopNode()) {
312 G4ExceptionDescription description;
313 description << " " << "No G4 mother volume crated for TGeo node "
314 << node->GetName();
315 G4Exception("TG4RootDetectorConstruction::CreateG4PhysicalVolume",
316 "G4Root_F005", FatalException, description);
317 }
318 G4bool pMany = false;
319 G4int pCopyNo = node->GetNumber();
320
321 pPhysicalVolume = new G4PVPlacement(
322 pRot, tlate, pCurrentLogical, pName, pMotherLogical, pMany, pCopyNo);
323 fG4PVolumeMap.insert(G4PVolumeVal_t(node, pPhysicalVolume));
324 fPVolumeMap.insert(PVolumeVal_t(pPhysicalVolume, node));
325 return pPhysicalVolume;
326}
327
328//______________________________________________________________________________
330 const TGeoMaterial* mat)
331{
334 G4Material* pMaterial = GetG4Material(mat);
335 if (pMaterial) return pMaterial;
336 G4State state = kStateUndefined;
337 G4double temp = mat->GetTemperature();
338 G4double pressure = mat->GetPressure();
339 switch (mat->GetState()) {
340 case TGeoMaterial::kMatStateUndefined:
341 state = kStateUndefined;
342 break;
343 case TGeoMaterial::kMatStateSolid:
344 state = kStateSolid;
345 break;
346 case TGeoMaterial::kMatStateLiquid:
347 state = kStateLiquid;
348 break;
349 case TGeoMaterial::kMatStateGas:
350 state = kStateGas;
351 break;
352 }
353 G4String elname, symbol;
354 TGeoElementTable* table = fGeometry->GetElementTable();
355 G4String name(mat->GetName());
356 G4double density = mat->GetDensity() * (g / cm3);
357 if (density < universe_mean_density || mat->GetZ() < 1.) {
358 density = universe_mean_density;
359 pMaterial = new G4Material(name, 1., 1.01 * g / mole, density, kStateGas,
360 STP_Temperature, 3.e-18 * pascal);
361 fG4MaterialMap.insert(G4MaterialVal_t(mat, pMaterial));
362 // G4cout << pMaterial << G4endl;
363 return pMaterial;
364 }
365
366 if (mat->IsMixture()) {
367 // Mixtures
368 const TGeoMixture* mixt = (const TGeoMixture*)mat;
369 G4int nComponents = mixt->GetNelements();
370 // G4cout << "Creating G4 mixture "<< name << G4endl;
371 pMaterial =
372 new G4Material(name, density, nComponents, state, temp, pressure);
373 for (Int_t i = 0; i < nComponents; i++) {
374 TGeoElement* elem = mixt->GetElement(i);
375 G4Element* pElement = nullptr;
376 if (elem->GetNisotopes() > 0) {
377 pElement = CreateG4Element(elem);
378 }
379 else {
380 TGeoElement* elemDb = table->GetElement(Int_t(mixt->GetZmixt()[i]));
381 if (!elemDb) {
382 G4ExceptionDescription description;
383 description << " "
384 << "Woops: no element corresponding to Z=" << elemDb->Z();
385 G4Exception("TG4RootDetectorConstruction::CreateG4Material",
386 "G4Root_F006", FatalException, description);
387 }
388 elname = elemDb->GetTitle();
389 symbol = elemDb->GetName();
390 pElement = new G4Element(elname, symbol, G4double(mixt->GetZmixt()[i]),
391 G4double(mixt->GetAmixt()[i]) * (g / mole));
392 }
393 pMaterial->AddElement(pElement, mixt->GetWmixt()[i]);
394 }
395 }
396 else {
397 // Materials with 1 element.
398 // G4cout << "Creating G4 material "<< name << G4endl;
399 if (mat->GetElement()
400 ->HasIsotopes()) { // user-defined material with isotopes
401 G4Element* pElement = CreateG4Element(mat->GetElement());
402 pMaterial = new G4Material(name, density, 1, state, temp, pressure);
403 pMaterial->AddElement(pElement, 1.);
404 }
405 else { // standard NIST element
406 pMaterial = new G4Material(name, G4double(mat->GetZ()),
407 mat->GetA() * g / mole, density, state, temp, pressure);
408 }
409 }
410
411 fG4MaterialMap.insert(G4MaterialVal_t(mat, pMaterial));
412 // G4cout << pMaterial << G4endl;
413 return pMaterial;
414}
415
416//______________________________________________________________________________
418{
419 G4Element* pElement =
420 G4Element::GetElement(elem->GetTitle(), /* G4bool warning = */ false);
421
422 // if such element is already created:
423 if (pElement != nullptr) {
424 return pElement;
425 }
426
427 // otherwise create a new one
428 if (elem->HasIsotopes() > 0) { // user-defined element with isotopes
429 G4int nIsotopes = elem->GetNisotopes();
430 for (G4int i = 0; i < nIsotopes; i++) {
431 TGeoIsotope* rIso = elem->GetIsotope(i);
432 if (i == 0) {
433 G4String elname = elem->GetTitle();
434 G4String symbol =
435 fGeometry->GetElementTable()->GetElement(rIso->GetZ())->GetName();
436 pElement = new G4Element(elname, symbol, nIsotopes);
437 }
438 G4Isotope* pIso = new G4Isotope(
439 rIso->GetName(), rIso->GetZ(), rIso->GetN(), rIso->GetA() * (g / mole));
440 pElement->AddIsotope(pIso, elem->GetRelativeAbundance(i));
441 }
442 G4cout << "Created element " << pElement->GetName()
443 << " with user-defined isotope composition" << G4endl;
444 G4cout << pElement << G4endl;
445 }
446 else { // standard NIST element
447 TGeoElementTable* table = fGeometry->GetElementTable();
448 TGeoElement* elemDb = table->GetElement(elem->Z());
449 if (!elemDb) {
450 G4ExceptionDescription description;
451 description << " "
452 << "Woops: no element corresponding to Z=" << elemDb->Z();
453 G4Exception("TG4RootDetectorConstruction::CreateG4Material",
454 "G4Root_F006", FatalException, description);
455 }
456 G4String elname = elemDb->GetTitle();
457 G4String symbol = elemDb->GetName();
458 pElement = new G4Element(
459 elname, symbol, G4double(elem->Z()), G4double(elem->A()) * (g / mole));
460 }
461 return pElement;
462}
463
464//______________________________________________________________________________
466 const TGeoMatrix* matrix)
467{
470 G4RotationMatrix* g4rot = 0;
471 if (matrix->IsRotation()) {
472 // matrix->Print();
473 const Double_t* marray = matrix->GetRotationMatrix();
474 Double_t invmat[9];
475 invmat[0] = marray[0];
476 invmat[1] = marray[3];
477 invmat[2] = marray[6];
478 invmat[3] = marray[1];
479 invmat[4] = marray[4];
480 invmat[5] = marray[7];
481 invmat[6] = marray[2];
482 invmat[7] = marray[5];
483 invmat[8] = marray[8];
484 CLHEP::HepRep3x3 mclhep(invmat);
485 g4rot = new G4RotationMatrix(mclhep);
486 // G4cout << *g4rot << G4endl;
487 }
488 return g4rot;
489}
490
491//______________________________________________________________________________
493{
496 return new TG4RootSolid(shape);
497 return NULL;
498}
499
500//______________________________________________________________________________
502 const TGeoMaterial* mat) const
503{
505 G4MaterialIt_t it = fG4MaterialMap.find(mat);
506 if (it != fG4MaterialMap.end()) return it->second;
507 return NULL;
508}
509
510//______________________________________________________________________________
512 const TGeoVolume* vol) const
513{
515 G4VolumeIt_t it = fG4VolumeMap.find(vol);
516 if (it != fG4VolumeMap.end()) return it->second;
517 return NULL;
518}
519
520//______________________________________________________________________________
522 const G4LogicalVolume* g4vol) const
523{
525 VolumeIt_t it = fVolumeMap.find(g4vol);
526 if (it != fVolumeMap.end()) return it->second;
527 return NULL;
528}
529
530//______________________________________________________________________________
532 const TGeoNode* node) const
533{
535 G4PVolumeIt_t it = fG4PVolumeMap.find(node);
536 if (it != fG4PVolumeMap.end()) return it->second;
537 return NULL;
538}
539
540//______________________________________________________________________________
542 const G4VPhysicalVolume* g4pvol) const
543{
545 PVolumeIt_t it = fPVolumeMap.find(g4pvol);
546 if (it != fPVolumeMap.end()) return it->second;
547 return NULL;
548}
Definition of the TG4RootDetectorConstruction and TVirtualUserPostDetConstruction classes.
Definition of the TG4RootNavMgr class.
Definition of the TG4RootNavigator class.
Definition of the TG4RootSolid class.
PVolumeMap_t::const_iterator PVolumeIt_t
the constant iterator for the map from G4VPhysicalVolume to TGeoNode
PVolumeMap_t fPVolumeMap
map of TGeo volumes
TVirtualUserPostDetConstruction * fSDInit
Sensitive detector hook.
G4VPhysicalVolume * GetG4VPhysicalVolume(const TGeoNode *node) const
G4VPhysicalVolume * CreateG4PhysicalVolume(TGeoNode *node)
G4PVolumeMap_t fG4PVolumeMap
map of G4 physical volumes
G4MaterialMap_t::const_iterator G4MaterialIt_t
the constant iterator for the map from TGeoMaterial to G4Material
G4RotationMatrix * CreateG4Rotation(const TGeoMatrix *matrix)
VolumeMap_t fVolumeMap
map of TGeo volumes
G4MaterialMap_t::value_type G4MaterialVal_t
the value type for the map from TGeoMaterial to G4Material
TGeoNode * GetNode(const G4VPhysicalVolume *g4vol) const
G4PVolumeMap_t::const_iterator G4PVolumeIt_t
the constant iterator for the map from TGeoNode to G4VPhysicalVolume
G4MaterialMap_t fG4MaterialMap
map of G4 materials
G4Material * CreateG4Material(const TGeoMaterial *mat)
void Initialize(TVirtualUserPostDetConstruction *sdinit=0)
G4VPhysicalVolume * fTopPV
World G4 physical volume.
PVolumeMap_t::value_type PVolumeVal_t
the value type for the map from G4VPhysicalVolume to TGeoNode
Bool_t fIsConstructed
flag Construct() called
VolumeMap_t::value_type VolumeVal_t
the value type for the map from G4LogicalVolume to TGeoVolume
virtual G4VPhysicalVolume * Construct()
G4LogicalVolume * GetG4Volume(const TGeoVolume *vol) const
G4VSolid * CreateG4Solid(TGeoShape *shape)
G4Material * GetG4Material(const TGeoMaterial *mat) const
G4VolumeMap_t fG4VolumeMap
map of G4 volumes
G4VolumeMap_t::const_iterator G4VolumeIt_t
the constant iterator for the map from TGeoVolume to G4LogicalVolume
TGeoVolume * GetVolume(const G4LogicalVolume *g4vol) const
G4PVolumeMap_t::value_type G4PVolumeVal_t
the value type for the map from TGeoNode to G4VPhysicalVolume
VolumeMap_t::const_iterator VolumeIt_t
the constant iterator for the map from G4LogicalVolume to TGeoVolume
G4Element * CreateG4Element(TGeoElement *elem)
G4VolumeMap_t::value_type G4VolumeVal_t
the value type for the map from TGeoVolume to G4LogicalVolume
G4LogicalVolume * CreateG4LogicalVolume(TGeoVolume *vol)
TGeoManager * fGeometry
TGeo geometry manager.
Manager class creating a G4Navigator based on a ROOT geometry.
TG4RootNavigator * GetNavigator() const
Return the G4 navigator working with TGeo.
static TG4RootNavMgr * GetInstance(TGeoManager *geom=0)
GEANT4 navigator using directly a TGeo geometry.
void SetDetectorConstruction(TG4RootDetectorConstruction *dc)
GEANT4 solid implemented by a ROOT shape.
Abstract class for defining links to G4 geometry.
virtual void Initialize(TG4RootDetectorConstruction *dc)=0
Initialize.