DD4hep - The AIDA detector description toolkit for high energy physics experiments
DD4hep  Rev:Unversioneddirectory
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Geant4Converter.cpp
Go to the documentation of this file.
1 // $Id$
2 //==========================================================================
3 // AIDA Detector description implementation for LCD
4 //--------------------------------------------------------------------------
5 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
6 // All rights reserved.
7 //
8 // For the licensing terms see $DD4hepINSTALL/LICENSE.
9 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
10 //
11 // Author : M.Frank
12 //
13 //==========================================================================
14 
15 // Framework include files
16 #include "DD4hep/LCDD.h"
17 #include "DD4hep/Plugins.h"
18 #include "DD4hep/Volumes.h"
19 #include "DD4hep/Printout.h"
20 #include "DD4hep/DD4hepUnits.h"
23 
24 #include "DDG4/Geant4Field.h"
25 #include "DDG4/Geant4Converter.h"
27 
28 // ROOT includes
29 #include "TROOT.h"
30 #include "TColor.h"
31 #include "TGeoNode.h"
32 #include "TGeoShape.h"
33 #include "TGeoCone.h"
34 #include "TGeoHype.h"
35 #include "TGeoPcon.h"
36 #include "TGeoEltu.h"
37 #include "TGeoPgon.h"
38 #include "TGeoSphere.h"
39 #include "TGeoTorus.h"
40 #include "TGeoTrd1.h"
41 #include "TGeoTrd2.h"
42 #include "TGeoTube.h"
43 #include "TGeoArb8.h"
44 #include "TGeoMatrix.h"
45 #include "TGeoBoolNode.h"
46 #include "TGeoParaboloid.h"
47 #include "TGeoCompositeShape.h"
48 #include "TGeoShapeAssembly.h"
49 #include "TGeoScaledShape.h"
50 #include "TGeoManager.h"
51 #include "TClass.h"
52 #include "TMath.h"
53 
54 // Geant4 include files
55 #include "G4VisAttributes.hh"
56 #include "G4ProductionCuts.hh"
57 #include "G4VUserRegionInformation.hh"
58 
59 #include "G4Element.hh"
60 #include "G4Box.hh"
61 #include "G4Trd.hh"
62 #include "G4Tubs.hh"
63 #include "G4Trap.hh"
64 #include "G4Cons.hh"
65 #include "G4Hype.hh"
66 #include "G4Torus.hh"
67 #include "G4Sphere.hh"
68 #include "G4Polycone.hh"
69 #include "G4Polyhedra.hh"
70 #include "G4UnionSolid.hh"
71 #include "G4Paraboloid.hh"
72 #include "G4Ellipsoid.hh"
73 #include "G4EllipticalTube.hh"
74 #include "G4SubtractionSolid.hh"
75 #include "G4IntersectionSolid.hh"
76 #include "G4Region.hh"
77 #include "G4UserLimits.hh"
78 #include "G4LogicalVolume.hh"
79 #include "G4Material.hh"
80 #include "G4Element.hh"
81 #include "G4Isotope.hh"
82 #include "G4Transform3D.hh"
83 #include "G4ThreeVector.hh"
84 #include "G4PVPlacement.hh"
85 #include "G4ElectroMagneticField.hh"
86 #include "G4FieldManager.hh"
87 #include "G4ReflectionFactory.hh"
88 #include "CLHEP/Units/SystemOfUnits.h"
89 
90 // C/C++ include files
91 #include <iostream>
92 #include <iomanip>
93 #include <sstream>
94 
95 using namespace DD4hep::Simulation;
96 //using namespace DD4hep::Simulation::Geant4GeometryMaps;
97 using namespace DD4hep::Geometry;
98 using namespace DD4hep;
99 using namespace std;
100 
102 #include "DD4hep/DetectorTools.h"
103 #include "G4RotationMatrix.hh"
104 #include "G4AffineTransform.hh"
105 #include "G4LogicalVolume.hh"
106 #include "G4VPhysicalVolume.hh"
107 #include "G4ReflectionFactory.hh"
108 
110  const TGeoNode* parent,
111  Chain chain,
112  Geant4AssemblyVolume* pAssembly,
113  G4LogicalVolume* pMotherLV,
114  G4Transform3D& transformation,
115  G4int copyNumBase,
116  G4bool surfCheck )
117 {
118  TGeoVolume* vol = parent->GetVolume();
119  static int level=0;
120  ++level;
121 
122 
123  unsigned int numberOfDaughters;
124 
125  if( copyNumBase == 0 )
126  {
127  numberOfDaughters = pMotherLV->GetNoDaughters();
128  }
129  else
130  {
131  numberOfDaughters = copyNumBase;
132  }
133 
134  // We start from the first available index
135  //
136  numberOfDaughters++;
137 
138  ImprintsCountPlus();
139 
140  std::vector<G4AssemblyTriplet> triplets = pAssembly->fTriplets;
141  //cout << " Assembly:" << DetectorTools::placementPath(chain) << endl;
142 
143  for( unsigned int i = 0; i < triplets.size(); i++ ) {
144  const TGeoNode* node = pAssembly->m_entries[i];
145  Chain new_chain = chain;
146  new_chain.push_back(node);
147  //cout << " Assembly: Entry: " << DetectorTools::placementPath(new_chain) << endl;
148 
149  G4Transform3D Ta( *(triplets[i].GetRotation()),
150  triplets[i].GetTranslation() );
151  if ( triplets[i].IsReflection() ) { Ta = Ta * G4ReflectZ3D(); }
152 
153  G4Transform3D Tfinal = transformation * Ta;
154 
155  if ( triplets[i].GetVolume() )
156  {
157  // Generate the unique name for the next PV instance
158  // The name has format:
159  //
160  // av_WWW_impr_XXX_YYY_ZZZ
161  // where the fields mean:
162  // WWW - assembly volume instance number
163  // XXX - assembly volume imprint number
164  // YYY - the name of a log. volume we want to make a placement of
165  // ZZZ - the log. volume index inside the assembly volume
166  //
167  std::stringstream pvName;
168  pvName << "av_"
169  << GetAssemblyID()
170  << "_impr_"
171  << GetImprintsCount()
172  << "_"
173  << triplets[i].GetVolume()->GetName().c_str()
174  << "_pv_"
175  << i
176  << std::ends;
177 
178  // Generate a new physical volume instance inside a mother
179  // (as we allow 3D transformation use G4ReflectionFactory to
180  // take into account eventual reflection)
181  //
182  G4PhysicalVolumesPair pvPlaced
183  = G4ReflectionFactory::Instance()->Place( Tfinal,
184  pvName.str().c_str(),
185  triplets[i].GetVolume(),
186  pMotherLV,
187  false,
188  numberOfDaughters + i,
189  surfCheck );
190 
191  // Register the physical volume created by us so we can delete it later
192  //
193  fPVStore.push_back( pvPlaced.first );
194  info.g4VolumeImprints[vol].push_back(make_pair(new_chain,pvPlaced.first));
195 #if 0
196  cout << " Assembly:Parent:" << parent->GetName() << " " << node->GetName()
197  << " " << (void*)node << " G4:" << pvName.str() << " Daughter:"
198  << DetectorTools::placementPath(new_chain) << endl;
199  cout << endl;
200 #endif
201 
202  if ( pvPlaced.second ) {
203  G4Exception("G4AssemblyVolume::MakeImprint(..)", "GeomVol0003", FatalException,
204  "Fancy construct popping new mother from the stack!");
205  //fPVStore.push_back( pvPlaced.second );
206  }
207  }
208  else if ( triplets[i].GetAssembly() ) {
209  // Place volumes in this assembly with composed transformation
210  imprint(info, parent, new_chain, (Geant4AssemblyVolume*)triplets[i].GetAssembly(), pMotherLV, Tfinal, i*100+copyNumBase, surfCheck );
211  }
212  else {
213  --level;
214  G4Exception("G4AssemblyVolume::MakeImprint(..)",
215  "GeomVol0003", FatalException,
216  "Triplet has no volume and no assembly");
217  }
218  }
219  //cout << "Imprinted assembly level:" << level << " in mother:" << pMotherLV->GetName() << endl;
220  --level;
221 }
222 
223 namespace {
224  static string indent = "";
225  static Double_t s_identity_rot[] = { 1., 0., 0., 0., 1., 0., 0., 0., 1. };
226  struct MyTransform3D : public G4Transform3D {
227  MyTransform3D(double XX, double XY, double XZ, double DX, double YX, double YY, double YZ, double DY, double ZX, double ZY,
228  double ZZ, double DZ)
229  : G4Transform3D(XX, XY, XZ, DX, YX, YY, YZ, DY, ZX, ZY, ZZ, DZ) {
230  }
231  MyTransform3D(const double* t, const double* r = s_identity_rot)
232  : G4Transform3D(r[0],r[1],r[2],t[0]*CM_2_MM,r[3],r[4],r[5],t[1]*CM_2_MM,r[6],r[7],r[8],t[2]*CM_2_MM) {
233  }
234  };
235 
236 #if 0 // warning: unused function 'handleName' [-Wunused-function]
237  void handleName(const TGeoNode* n) {
238  TGeoVolume* v = n->GetVolume();
239  TGeoMedium* m = v->GetMedium();
240  TGeoShape* s = v->GetShape();
241  string nam;
242  printout(DEBUG, "G4", "TGeoNode:'%s' Vol:'%s' Shape:'%s' Medium:'%s'", n->GetName(), v->GetName(), s->GetName(),
243  m->GetName());
244  }
245 #endif
246 
247  class G4UserRegionInformation : public G4VUserRegionInformation {
248  public:
249  Region region;
250  double threshold;
251  bool storeSecondaries;
252  G4UserRegionInformation()
253  : threshold(0.0), storeSecondaries(false) {
254  }
255  virtual ~G4UserRegionInformation() {
256  }
257  virtual void Print() const {
258  if (region.isValid())
259  printout(DEBUG, "Region", "Name:%s", region.name());
260  }
261  };
262 }
263 
266  : Geant4Mapping(lcdd_ref), m_checkOverlaps(true) {
267  this->Geant4Mapping::init();
268  m_propagateRegions = true;
270 }
271 
274  : Geant4Mapping(lcdd_ref), m_checkOverlaps(true) {
275  this->Geant4Mapping::init();
276  m_propagateRegions = true;
277  m_outputLevel = level;
278 }
279 
282 }
283 
285 void* Geant4Converter::handleElement(const string& name, const Atom element) const {
286  G4Element* g4e = data().g4Elements[element];
287  if (!g4e) {
288  g4e = G4Element::GetElement(name, false);
289  if (!g4e) {
290  if (element->GetNisotopes() > 1) {
291  g4e = new G4Element(name, element->GetTitle(), element->GetNisotopes());
292  for (int i = 0, n = element->GetNisotopes(); i < n; ++i) {
293  TGeoIsotope* iso = element->GetIsotope(i);
294  G4Isotope* g4iso = G4Isotope::GetIsotope(iso->GetName(), false);
295  if (!g4iso) {
296  g4iso = new G4Isotope(iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA());
297  }
298  g4e->AddIsotope(g4iso, element->GetRelativeAbundance(i));
299  }
300  }
301  else {
302  g4e = new G4Element(element->GetTitle(), name, element->Z(), element->A() * (CLHEP::g / CLHEP::mole));
303  }
304  stringstream str;
305  str << (*g4e);
306  printout(m_outputLevel, "Geant4Converter", "++ Created G4 %s", str.str().c_str());
307  }
308  data().g4Elements[element] = g4e;
309  }
310  return g4e;
311 }
312 
314 void* Geant4Converter::handleMaterial(const string& name, Material medium) const {
315  G4Material* mat = data().g4Materials[medium];
316  if (!mat) {
317  mat = G4Material::GetMaterial(name, false);
318  if (!mat) {
319  TGeoMaterial* material = medium->GetMaterial();
320  G4State state = kStateUndefined;
321  double density = material->GetDensity() * (CLHEP::gram / CLHEP::cm3);
322  if (density < 1e-25)
323  density = 1e-25;
324  switch (material->GetState()) {
325  case TGeoMaterial::kMatStateSolid:
326  state = kStateSolid;
327  break;
328  case TGeoMaterial::kMatStateLiquid:
329  state = kStateLiquid;
330  break;
331  case TGeoMaterial::kMatStateGas:
332  state = kStateGas;
333  break;
334  default:
335  case TGeoMaterial::kMatStateUndefined:
336  state = kStateUndefined;
337  break;
338  }
339  if (material->IsMixture()) {
340  double A_total = 0.0;
341  double W_total = 0.0;
342  TGeoMixture* mix = (TGeoMixture*) material;
343  int nElements = mix->GetNelements();
344  mat = new G4Material(name, density, nElements, state,
345  material->GetTemperature(), material->GetPressure());
346  for (int i = 0; i < nElements; ++i) {
347  A_total += (mix->GetAmixt())[i];
348  W_total += (mix->GetWmixt())[i];
349  }
350  for (int i = 0; i < nElements; ++i) {
351  TGeoElement* e = mix->GetElement(i);
352  G4Element* g4e = (G4Element*) handleElement(e->GetName(), Atom(e));
353  if (!g4e) {
354  printout(ERROR, "Material",
355  "Missing component %s for material %s. A=%f W=%f",
356  e->GetName(), mix->GetName(), A_total, W_total);
357  }
358  //mat->AddElement(g4e, (mix->GetAmixt())[i] / A_total);
359  mat->AddElement(g4e, (mix->GetWmixt())[i] / W_total);
360  }
361  }
362  else {
363  double z = material->GetZ(), a = material->GetA();
364  if ( z < 1.0000001 ) z = 1.0;
365  if ( a < 0.5000001 ) a = 1.0;
366  mat = new G4Material(name, z, a, density, state,
367  material->GetTemperature(), material->GetPressure());
368  }
369  stringstream str;
370  str << (*mat);
371  printout(m_outputLevel, "Geant4Converter", "++ Created G4 %s", str.str().c_str());
372  }
373  data().g4Materials[medium] = mat;
374  }
375  return mat;
376 }
377 
379 void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) const {
380  G4VSolid* solid = 0;
381  if (shape) {
382  if (0 != (solid = data().g4Solids[shape])) {
383  return solid;
384  }
385  else if (shape->IsA() == TGeoShapeAssembly::Class()) {
386  // Assemblies have no corresponding 'shape' in Geant4. Ignore the shape translation.
387  // It does not harm, since this 'shape' is never accessed afterwards.
388  data().g4Solids[shape] = solid;
389  return solid;
390  }
391  else if (shape->IsA() == TGeoBBox::Class()) {
392  const TGeoBBox* s = (const TGeoBBox*) shape;
393  solid = new G4Box(name, s->GetDX() * CM_2_MM, s->GetDY() * CM_2_MM, s->GetDZ() * CM_2_MM);
394  }
395  else if (shape->IsA() == TGeoTube::Class()) {
396  const TGeoTube* s = (const TGeoTube*) shape;
397  solid = new G4Tubs(name, s->GetRmin() * CM_2_MM, s->GetRmax() * CM_2_MM, s->GetDz() * CM_2_MM, 0, 2. * M_PI);
398  }
399  else if (shape->IsA() == TGeoTubeSeg::Class()) {
400  const TGeoTubeSeg* s = (const TGeoTubeSeg*) shape;
401  solid = new G4Tubs(name, s->GetRmin() * CM_2_MM, s->GetRmax() * CM_2_MM, s->GetDz() * CM_2_MM,
402  s->GetPhi1() * DEGREE_2_RAD, (s->GetPhi2()-s->GetPhi1()) * DEGREE_2_RAD);
403  }
404  else if (shape->IsA() == TGeoEltu::Class()) {
405  const TGeoEltu* s = (const TGeoEltu*) shape;
406  solid = new G4EllipticalTube(name,s->GetA() * CM_2_MM, s->GetB() * CM_2_MM, s->GetDz() * CM_2_MM);
407  }
408  else if (shape->IsA() == TGeoTrd1::Class()) {
409  const TGeoTrd1* s = (const TGeoTrd1*) shape;
410  solid = new G4Trd(name, s->GetDx1() * CM_2_MM, s->GetDx2() * CM_2_MM, s->GetDy() * CM_2_MM, s->GetDy() * CM_2_MM,
411  s->GetDz() * CM_2_MM);
412  }
413  else if (shape->IsA() == TGeoTrd2::Class()) {
414  const TGeoTrd2* s = (const TGeoTrd2*) shape;
415  solid = new G4Trd(name, s->GetDx1() * CM_2_MM, s->GetDx2() * CM_2_MM, s->GetDy1() * CM_2_MM, s->GetDy2() * CM_2_MM,
416  s->GetDz() * CM_2_MM);
417  }
418  else if (shape->IsA() == TGeoHype::Class()) {
419  const TGeoHype* s = (const TGeoHype*) shape;
420  solid = new G4Hype(name, s->GetRmin() * CM_2_MM, s->GetRmax() * CM_2_MM,
421  s->GetStIn() * DEGREE_2_RAD, s->GetStOut() * DEGREE_2_RAD,
422  s->GetDz() * CM_2_MM);
423  }
424  else if (shape->IsA() == TGeoPgon::Class()) {
425  const TGeoPgon* s = (const TGeoPgon*) shape;
426  double phi_start = s->GetPhi1() * DEGREE_2_RAD;
427  double phi_total = (s->GetDphi() + s->GetPhi1()) * DEGREE_2_RAD;
428  vector<double> rmin, rmax, z;
429  for (Int_t i = 0; i < s->GetNz(); ++i) {
430  rmin.push_back(s->GetRmin(i) * CM_2_MM);
431  rmax.push_back(s->GetRmax(i) * CM_2_MM);
432  z.push_back(s->GetZ(i) * CM_2_MM);
433  }
434  solid = new G4Polyhedra(name, phi_start, phi_total, s->GetNedges(), s->GetNz(), &z[0], &rmin[0], &rmax[0]);
435  }
436  else if (shape->IsA() == TGeoPcon::Class()) {
437  const TGeoPcon* s = (const TGeoPcon*) shape;
438  double phi_start = s->GetPhi1() * DEGREE_2_RAD;
439  double phi_total = (s->GetDphi() + s->GetPhi1()) * DEGREE_2_RAD;
440  vector<double> rmin, rmax, z;
441  for (Int_t i = 0; i < s->GetNz(); ++i) {
442  rmin.push_back(s->GetRmin(i) * CM_2_MM);
443  rmax.push_back(s->GetRmax(i) * CM_2_MM);
444  z.push_back(s->GetZ(i) * CM_2_MM);
445  }
446  solid = new G4Polycone(name, phi_start, phi_total, s->GetNz(), &z[0], &rmin[0], &rmax[0]);
447  }
448  else if (shape->IsA() == TGeoCone::Class()) {
449  const TGeoCone* s = (const TGeoCone*) shape;
450  solid = new G4Cons(name, s->GetRmin1() * CM_2_MM, s->GetRmax1() * CM_2_MM, s->GetRmin2() * CM_2_MM,
451  s->GetRmax2() * CM_2_MM, s->GetDz() * CM_2_MM, 0.0, 2.*M_PI);
452  }
453  else if (shape->IsA() == TGeoConeSeg::Class()) {
454  const TGeoConeSeg* s = (const TGeoConeSeg*) shape;
455  solid = new G4Cons(name, s->GetRmin1() * CM_2_MM, s->GetRmax1() * CM_2_MM, s->GetRmin2() * CM_2_MM,
456  s->GetRmax2() * CM_2_MM, s->GetDz() * CM_2_MM, s->GetPhi1() * DEGREE_2_RAD, (s->GetPhi2()-s->GetPhi1()) * DEGREE_2_RAD);
457  }
458  else if (shape->IsA() == TGeoParaboloid::Class()) {
459  const TGeoParaboloid* s = (const TGeoParaboloid*) shape;
460  solid = new G4Paraboloid(name, s->GetDz() * CM_2_MM, s->GetRlo() * CM_2_MM, s->GetRhi() * CM_2_MM);
461  }
462 #if 0 /* Not existent */
463  else if (shape->IsA() == TGeoEllisoid::Class()) {
464  const TGeoParaboloid* s = (const TGeoParaboloid*) shape;
465  solid = new G4Paraboloid(name, s->GetDz() * CM_2_MM, s->GetRlo() * CM_2_MM, s->GetRhi() * CM_2_MM);
466  }
467 #endif
468  else if (shape->IsA() == TGeoSphere::Class()) {
469  const TGeoSphere* s = (const TGeoSphere*) shape;
470  solid = new G4Sphere(name, s->GetRmin() * CM_2_MM, s->GetRmax() * CM_2_MM, s->GetPhi1() * DEGREE_2_RAD,
471  s->GetPhi2() * DEGREE_2_RAD, s->GetTheta1() * DEGREE_2_RAD, s->GetTheta2() * DEGREE_2_RAD);
472  }
473  else if (shape->IsA() == TGeoTorus::Class()) {
474  const TGeoTorus* s = (const TGeoTorus*) shape;
475  solid = new G4Torus(name, s->GetRmin() * CM_2_MM, s->GetRmax() * CM_2_MM, s->GetR() * CM_2_MM,
476  s->GetPhi1() * DEGREE_2_RAD, s->GetDphi() * DEGREE_2_RAD);
477  }
478  else if (shape->IsA() == TGeoTrap::Class()) {
479  const TGeoTrap* s = (const TGeoTrap*) shape;
480  solid = new G4Trap(name, s->GetDz() * CM_2_MM, s->GetTheta(), s->GetPhi(),
481  s->GetH1() * CM_2_MM, s->GetBl1() * CM_2_MM, s->GetTl1() * CM_2_MM, s->GetAlpha1() * DEGREE_2_RAD,
482  s->GetH2() * CM_2_MM, s->GetBl2() * CM_2_MM, s->GetTl2() * CM_2_MM, s->GetAlpha2() * DEGREE_2_RAD);
483  }
484  else if (shape->IsA() == TGeoCompositeShape::Class()) {
485  const TGeoCompositeShape* s = (const TGeoCompositeShape*) shape;
486  const TGeoBoolNode* boolean = s->GetBoolNode();
487  TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator();
488  TGeoMatrix* m = boolean->GetRightMatrix();
489  G4VSolid* left = (G4VSolid*) handleSolid(name + "_left", boolean->GetLeftShape());
490  G4VSolid* right = (G4VSolid*) handleSolid(name + "_right", boolean->GetRightShape());
491 
492  if (!left) {
493  throw runtime_error("G4Converter: No left Geant4 Solid present for composite shape:" + name);
494  }
495  if (!right) {
496  throw runtime_error("G4Converter: No right Geant4 Solid present for composite shape:" + name);
497  }
498 
499  //specific case!
500  //Ellipsoid tag preparing
501  //if left == TGeoScaledShape AND right == TGeoBBox
502  // AND if TGeoScaledShape->GetShape == TGeoSphere
503  TGeoShape* ls = boolean->GetLeftShape();
504  TGeoShape* rs = boolean->GetRightShape();
505  if (strcmp(ls->ClassName(), "TGeoScaledShape") == 0 &&
506  strcmp(rs->ClassName(), "TGeoBBox") == 0) {
507  if (strcmp(((TGeoScaledShape *)ls)->GetShape()->ClassName(), "TGeoSphere") == 0) {
508  if (oper == TGeoBoolNode::kGeoIntersection) {
509  TGeoScaledShape* lls = (TGeoScaledShape *)ls;
510  TGeoBBox* rrs = (TGeoBBox*)rs;
511  double sx = lls->GetScale()->GetScale()[0];
512  double sy = lls->GetScale()->GetScale()[1];
513  double radius = ((TGeoSphere *)lls->GetShape())->GetRmax();
514  double dz = rrs->GetDZ();
515  double zorig = rrs->GetOrigin()[2];
516  double zcut2 = dz + zorig;
517  double zcut1 = 2 * zorig - zcut2;
518  solid = new G4Ellipsoid(name,
519  sx * radius * CM_2_MM,
520  sy * radius * CM_2_MM,
521  radius * CM_2_MM,
522  zcut1 * CM_2_MM,
523  zcut2 * CM_2_MM);
524  data().g4Solids[shape] = solid;
525  return solid;
526  }
527  }
528  }
529 
530  if (m->IsRotation()) {
531  MyTransform3D transform(m->GetTranslation(),m->GetRotationMatrix());
532  if (oper == TGeoBoolNode::kGeoSubtraction)
533  solid = new G4SubtractionSolid(name, left, right, transform);
534  else if (oper == TGeoBoolNode::kGeoUnion)
535  solid = new G4UnionSolid(name, left, right, transform);
536  else if (oper == TGeoBoolNode::kGeoIntersection)
537  solid = new G4IntersectionSolid(name, left, right, transform);
538  }
539  else {
540  const Double_t *t = m->GetTranslation();
541  G4ThreeVector transform(t[0] * CM_2_MM, t[1] * CM_2_MM, t[2] * CM_2_MM);
542  if (oper == TGeoBoolNode::kGeoSubtraction)
543  solid = new G4SubtractionSolid(name, left, right, 0, transform);
544  else if (oper == TGeoBoolNode::kGeoUnion)
545  solid = new G4UnionSolid(name, left, right, 0, transform);
546  else if (oper == TGeoBoolNode::kGeoIntersection)
547  solid = new G4IntersectionSolid(name, left, right, 0, transform);
548  }
549  }
550 
551  if (!solid) {
552  string err = "Failed to handle unknown solid shape:" + name + " of type " + string(shape->IsA()->GetName());
553  throw runtime_error(err);
554  }
555  data().g4Solids[shape] = solid;
556  }
557  return solid;
558 }
559 
561 void* Geant4Converter::handleVolume(const string& name, const TGeoVolume* volume) const {
562  Geant4GeometryInfo& info = data();
563  Geant4GeometryMaps::VolumeMap::const_iterator volIt = info.g4Volumes.find(volume);
564  if (volIt == info.g4Volumes.end() ) {
565  const TGeoVolume* v = volume;
566  Volume _v = Ref_t(v);
567  string n = v->GetName();
568  TGeoMedium* m = v->GetMedium();
569  TGeoShape* s = v->GetShape();
570  G4VSolid* solid = (G4VSolid*) handleSolid(s->GetName(), s);
571  G4Material* medium = 0;
572  bool assembly = s->IsA() == TGeoShapeAssembly::Class() || v->IsA() == TGeoVolumeAssembly::Class();
573 
574  LimitSet lim = _v.limitSet();
575  G4UserLimits* user_limits = 0;
576  if (lim.isValid()) {
577  user_limits = info.g4Limits[lim];
578  if (!user_limits) {
579  throw runtime_error("G4Cnv::volume[" + name + "]: + FATAL Failed to "
580  "access Geant4 user limits.");
581  }
582  }
583  VisAttr vis = _v.visAttributes();
584  G4VisAttributes* vis_attr = 0;
585  if (vis.isValid()) {
586  vis_attr = (G4VisAttributes*)handleVis(vis.name(), vis);
587  }
588  Region reg = _v.region();
589  G4Region* region = 0;
590  if (reg.isValid()) {
591  region = info.g4Regions[reg];
592  if (!region) {
593  throw runtime_error("G4Cnv::volume[" + name + "]: + FATAL Failed to "
594  "access Geant4 region.");
595  }
596  }
597  PrintLevel lvl = m_outputLevel; //string(det.name())=="SiTrackerBarrel" ? WARNING : m_outputLevel;
598  printout(lvl, "Geant4Converter", "++ Convert Volume %-32s: %p %s/%s assembly:%s",
599  n.c_str(), v, s->IsA()->GetName(), v->IsA()->GetName(), yes_no(assembly));
600 
601  if (assembly) {
602  //info.g4AssemblyVolumes[v] = new Geant4AssemblyVolume();
603  return 0;
604  }
605  medium = (G4Material*) handleMaterial(m->GetName(), Material(m));
606  if (!solid) {
607  throw runtime_error("G4Converter: No Geant4 Solid present for volume:" + n);
608  }
609  if (!medium) {
610  throw runtime_error("G4Converter: No Geant4 material present for volume:" + n);
611  }
612  if (user_limits) {
613  printout(m_outputLevel, "Geant4Converter", "++ Volume + Apply LIMITS settings:%-24s to volume %s.",
614  lim.name(), _v.name());
615  }
616  G4LogicalVolume* vol = new G4LogicalVolume(solid, medium, n, 0, 0, user_limits);
617  if (region) {
618  printout(m_outputLevel, "Geant4Converter", "++ Volume + Apply REGION settings: %s to volume %s.",
619  reg.name(), _v.name());
620  vol->SetRegion(region);
621  region->AddRootLogicalVolume(vol);
622  }
623  if (vis_attr) {
624  vol->SetVisAttributes(vis_attr);
625  }
626  info.g4Volumes[v] = vol;
627  printout(m_outputLevel, "Geant4Converter", "++ Volume + %s converted: %p ---> G4: %p", n.c_str(), v, vol);
628  }
629  return 0;
630 }
631 
633 void* Geant4Converter::collectVolume(const string& /* name */, const TGeoVolume* volume) const {
634  Geant4GeometryInfo& info = data();
635  const TGeoVolume* v = volume;
636  Volume _v = Ref_t(v);
637  Region reg = _v.region();
638  LimitSet lim = _v.limitSet();
640 
641  if (lim.isValid())
642  info.limits[lim].insert(v);
643  if (reg.isValid())
644  info.regions[reg].insert(v);
645  if (det.isValid())
646  info.sensitives[det].insert(v);
647  return (void*) v;
648 }
649 
651 void* Geant4Converter::handleAssembly(const std::string& name, const TGeoNode* node) const {
652  TGeoVolume* mot_vol = node->GetVolume();
653  if ( mot_vol->IsA() != TGeoVolumeAssembly::Class() ) {
654  return 0;
655  }
656  Geant4GeometryInfo& info = data();
657  Geant4AssemblyVolume* g4 = info.g4AssemblyVolumes[node];
658 
659  if ( !g4 ) {
660  g4 = new Geant4AssemblyVolume();
661  for(Int_t i=0; i < mot_vol->GetNdaughters(); ++i) {
662  TGeoNode* d = mot_vol->GetNode(i);
663  TGeoVolume* dau_vol = d->GetVolume();
664  TGeoMatrix* tr = d->GetMatrix();
665  MyTransform3D transform(tr->GetTranslation(),tr->IsRotation() ? tr->GetRotationMatrix() : s_identity_rot);
666  if ( dau_vol->IsA() == TGeoVolumeAssembly::Class() ) {
667  Geant4GeometryMaps::AssemblyMap::iterator assIt = info.g4AssemblyVolumes.find(d);
668  if ( assIt == info.g4AssemblyVolumes.end() ) {
669  printout(FATAL, "Geant4Converter", "+++ Invalid child assembly at %s : %d parent: %s child:%s",
670  __FILE__, __LINE__, name.c_str(), d->GetName());
671  }
672  g4->placeAssembly(d,(*assIt).second,transform);
673  printout(m_outputLevel, "Geant4Converter", "+++ Assembly: AddPlacedAssembly : dau:%s "
674  "to mother %s Tr:x=%8.3f y=%8.3f z=%8.3f",
675  dau_vol->GetName(), mot_vol->GetName(),
676  transform.dx(), transform.dy(), transform.dz());
677  }
678  else {
679  Geant4GeometryMaps::VolumeMap::iterator volIt = info.g4Volumes.find(dau_vol);
680  if ( volIt == info.g4Volumes.end() ) {
681  printout(FATAL, "Geant4Converter", "+++ Invalid child volume at %s : %d parent: %s child:%s",
682  __FILE__, __LINE__, name.c_str(), d->GetName());
683  }
684  g4->placeVolume(d,(*volIt).second, transform);
685  printout(m_outputLevel, "Geant4Converter", "+++ Assembly: AddPlacedVolume : dau:%s "
686  "to mother %s Tr:x=%8.3f y=%8.3f z=%8.3f",
687  dau_vol->GetName(), mot_vol->GetName(),
688  transform.dx(), transform.dy(), transform.dz());
689  }
690  }
691  info.g4AssemblyVolumes[node] = g4;
692  }
693  return g4;
694 }
695 
697 void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node) const {
698  Geant4GeometryInfo& info = data();
699  Geant4GeometryMaps::PlacementMap::const_iterator g4it = info.g4Placements.find(node);
700  G4VPhysicalVolume* g4 = (g4it == info.g4Placements.end()) ? 0 : (*g4it).second;
701  if (!g4) {
702  TGeoVolume* mot_vol = node->GetMotherVolume();
703  TGeoVolume* vol = node->GetVolume();
704  TGeoMatrix* tr = node->GetMatrix();
705  if (!tr) {
706  printout(FATAL, "Geant4Converter", "++ Attempt to handle placement without transformation:%p %s of type %s vol:%p", node,
707  node->GetName(), node->IsA()->GetName(), vol);
708  }
709  else if (0 == vol) {
710  printout(FATAL, "Geant4Converter", "++ Unknown G4 volume:%p %s of type %s ptr:%p", node, node->GetName(),
711  node->IsA()->GetName(), vol);
712  }
713  else {
714  int copy = node->GetNumber();
715  bool node_is_assembly = vol->IsA() == TGeoVolumeAssembly::Class();
716  bool mother_is_assembly = mot_vol ? mot_vol->IsA() == TGeoVolumeAssembly::Class() : false;
717  MyTransform3D transform(tr->GetTranslation(),tr->IsRotation() ? tr->GetRotationMatrix() : s_identity_rot);
718  Geant4GeometryMaps::VolumeMap::const_iterator volIt = info.g4Volumes.find(mot_vol);
719 
720  if ( mother_is_assembly ) {
721  //
722  // Mother is an assembly:
723  // Nothing to do here, because:
724  // -- placed volumes were already added before in "handleAssembly"
725  // -- imprint cannot be made, because this requires a logical volume as a mother
726  //
727  printout(m_outputLevel, "Geant4Converter", "+++ Assembly: **** : dau:%s "
728  "to mother %s Tr:x=%8.3f y=%8.3f z=%8.3f",
729  vol->GetName(), mot_vol->GetName(),
730  transform.dx(), transform.dy(), transform.dz());
731  return 0;
732  }
733  else if ( node_is_assembly ) {
734  //
735  // Node is an assembly:
736  // Imprint the assembly. The mother MUST already be transformed.
737  //
738  printout(m_outputLevel, "Geant4Converter", "+++ Assembly: makeImprint: dau:%s in mother %s "
739  "Tr:x=%8.3f y=%8.3f z=%8.3f",
740  node->GetName(), mot_vol->GetName(),
741  transform.dx(), transform.dy(), transform.dz());
744  chain.push_back(node);
745  ass->imprint(info,node,chain,ass,(*volIt).second, transform, copy, m_checkOverlaps);
746  return 0;
747  }
748  else if ( node != gGeoManager->GetTopNode() && volIt == info.g4Volumes.end() ) {
749  throw logic_error("Geant4Converter: Invalid mother volume found!");
750  }
751  G4LogicalVolume* g4vol = info.g4Volumes[vol];
752  G4LogicalVolume* g4mot = info.g4Volumes[mot_vol];
753  g4 = new G4PVPlacement(transform, // no rotation
754  g4vol, // its logical volume
755  name, // its name
756  g4mot, // its mother (logical) volume
757  false, // no boolean operations
758  copy, // its copy number
760  }
761  info.g4Placements[node] = g4;
762  }
763  else {
764  printout(ERROR, "Geant4Converter", "++ Attempt to DOUBLE-place physical volume: %s No:%d", name.c_str(), node->GetNumber());
765  }
766  return g4;
767 }
768 
770 void* Geant4Converter::handleRegion(Region region, const set<const TGeoVolume*>& /* volumes */) const {
771  G4Region* g4 = data().g4Regions[region];
772  if (!g4) {
773  Region r = Ref_t(region);
774  g4 = new G4Region(r.name());
775  // set production cut
776  G4ProductionCuts* cuts = new G4ProductionCuts();
777  cuts->SetProductionCut(r.cut()*CLHEP::mm/dd4hep::mm);
778  g4->SetProductionCuts(cuts);
779 
780  // create region info with storeSecondaries flag
781  G4UserRegionInformation* info = new G4UserRegionInformation();
782  info->region = r;
783  info->threshold = r.threshold()*CLHEP::MeV/dd4hep::MeV;
784  info->storeSecondaries = r.storeSecondaries();
785  g4->SetUserInformation(info);
786 
787  printout(m_outputLevel, "Geant4Converter", "++ Converted region settings of:%s.", r.name());
788  vector < string > &limits = r.limits();
789  for (vector<string>::const_iterator i = limits.begin(); i != limits.end(); ++i) {
790  const string& nam = *i;
791  LimitSet ls = m_lcdd.limitSet(nam);
792  if (ls.isValid()) {
793  bool found = false;
795  for (Geant4GeometryMaps::LimitMap::const_iterator j = lm.begin(); j != lm.end(); ++j) {
796  if (nam == (*j).first->GetName()) {
797  g4->SetUserLimits((*j).second);
798  found = true;
799  break;
800  }
801  }
802  if (found)
803  continue;
804  }
805  throw runtime_error("G4Region: Failed to resolve user limitset:" + *i);
806  }
807  data().g4Regions[region] = g4;
808  }
809  return g4;
810 }
811 
813 void* Geant4Converter::handleLimitSet(LimitSet limitset, const set<const TGeoVolume*>& /* volumes */) const {
814  G4UserLimits* g4 = data().g4Limits[limitset];
815  if (!g4) {
816  LimitSet ls = Ref_t(limitset);
817  g4 = new G4UserLimits(limitset->GetName());
818  const set<Limit>& limits = ls.limits();
819  for (LimitSet::Object::const_iterator i = limits.begin(); i != limits.end(); ++i) {
820  const Limit& l = *i;
821  if (l.name == "step_length_max")
822  g4->SetMaxAllowedStep(l.value*CLHEP::mm/dd4hep::mm);
823  else if (l.name == "track_length_max")
824  g4->SetMaxAllowedStep(l.value*CLHEP::mm/dd4hep::mm);
825  else if (l.name == "time_max")
826  g4->SetUserMaxTime(l.value*CLHEP::ns/dd4hep::ns);
827  else if (l.name == "ekin_min")
828  g4->SetUserMinEkine(l.value*CLHEP::MeV/dd4hep::MeV);
829  else if (l.name == "range_min")
830  g4->SetUserMinRange(l.value);
831  else
832  throw runtime_error("Unknown Geant4 user limit: " + l.toString());
833  }
834  data().g4Limits[limitset] = g4;
835  }
836  return g4;
837 }
838 
840 void* Geant4Converter::handleVis(const string& /* name */, VisAttr attr) const {
841  Geant4GeometryInfo& info = data();
842  G4VisAttributes* g4 = info.g4Vis[attr];
843  if (!g4) {
844  float r = 0, g = 0, b = 0;
845  int style = attr.lineStyle();
846  attr.rgb(r, g, b);
847  g4 = new G4VisAttributes(attr.visible(), G4Colour(r, g, b, attr.alpha()));
848  //g4->SetLineWidth(attr->GetLineWidth());
849  g4->SetDaughtersInvisible(!attr.showDaughters());
850  if (style == VisAttr::SOLID) {
851  g4->SetLineStyle(G4VisAttributes::unbroken);
852  g4->SetForceWireframe(false);
853  g4->SetForceSolid(true);
854  }
855  else if (style == VisAttr::WIREFRAME || style == VisAttr::DASHED) {
856  g4->SetLineStyle(G4VisAttributes::dashed);
857  g4->SetForceSolid(false);
858  g4->SetForceWireframe(true);
859  }
860  info.g4Vis[attr] = g4;
861  }
862  return g4;
863 }
864 
867  map < string, string > processors;
868  static int s_idd = 9999999;
869  string id;
870  for (LCDD::Properties::const_iterator i = prp.begin(); i != prp.end(); ++i) {
871  const string& nam = (*i).first;
872  const LCDD::PropertyValues& vals = (*i).second;
873  if (nam.substr(0, 6) == "geant4") {
874  LCDD::PropertyValues::const_iterator id_it = vals.find("id");
875  if (id_it != vals.end()) {
876  id = (*id_it).second;
877  }
878  else {
879  char txt[32];
880  ::snprintf(txt, sizeof(txt), "%d", ++s_idd);
881  id = txt;
882  }
883  processors.insert(make_pair(id, nam));
884  }
885  }
886  for (map<string, string>::const_iterator i = processors.begin(); i != processors.end(); ++i) {
887  const Geometry::GeoHandler* hdlr = this;
888  string nam = (*i).second;
889  const LCDD::PropertyValues& vals = prp[nam];
890  string type = vals.find("type")->second;
891  string tag = type + "_Geant4_action";
892  long result = PluginService::Create<long>(tag, &m_lcdd, hdlr, &vals);
893  if (0 == result) {
894  throw runtime_error("Failed to locate plugin to interprete files of type"
895  " \"" + tag + "\" - no factory:" + type);
896  }
897  result = *(long*) result;
898  if (result != 1) {
899  throw runtime_error("Failed to invoke the plugin " + tag + " of type " + type);
900  }
901  printout(m_outputLevel, "Geant4Converter", "+++++ Executed Successfully Geant4 setup module *%s*.", type.c_str());
902  }
903 }
904 
906 void Geant4Converter::printSensitive(SensitiveDetector sens_det, const set<const TGeoVolume*>& /* volumes */) const {
907  Geant4GeometryInfo& info = data();
908  ConstVolumeSet& volset = info.sensitives[sens_det];
909  SensitiveDetector sd = Ref_t(sens_det);
910  stringstream str;
911 
912  printout(INFO, "Geant4Converter", "++ SensitiveDetector: %-18s %-20s Hits:%-16s", sd.name(), ("[" + sd.type() + "]").c_str(),
913  sd.hitsCollection().c_str());
914  str << " | " << "Cutoff:" << setw(6) << left << sd.energyCutoff() << setw(5) << right << volset.size()
915  << " volumes ";
916  if (sd.region().isValid())
917  str << " Region:" << setw(12) << left << sd.region().name();
918  if (sd.limits().isValid())
919  str << " Limits:" << setw(12) << left << sd.limits().name();
920  str << ".";
921  printout(INFO, "Geant4Converter", str.str().c_str());
922 
923  for (ConstVolumeSet::iterator i = volset.begin(); i != volset.end(); ++i) {
924  map<Volume, G4LogicalVolume*>::iterator v = info.g4Volumes.find(*i);
925  G4LogicalVolume* vol = (*v).second;
926  str.str("");
927  str << " | " << "Volume:" << setw(24) << left << vol->GetName() << " "
928  << vol->GetNoDaughters() << " daughters.";
929  printout(INFO, "Geant4Converter", str.str().c_str());
930  }
931 }
932 
933 string printSolid(G4VSolid* sol) {
934  stringstream str;
935  if (typeid(*sol) == typeid(G4Box)) {
936  const G4Box* b = (G4Box*) sol;
937  str << "++ Box: x=" << b->GetXHalfLength() << " y=" << b->GetYHalfLength() << " z=" << b->GetZHalfLength();
938  }
939  else if (typeid(*sol) == typeid(G4Tubs)) {
940  const G4Tubs* t = (const G4Tubs*) sol;
941  str << " Tubs: Ri=" << t->GetInnerRadius() << " Ra=" << t->GetOuterRadius() << " z/2=" << t->GetZHalfLength() << " Phi="
942  << t->GetStartPhiAngle() << "..." << t->GetDeltaPhiAngle();
943  }
944  return str.str();
945 }
946 
948 void* Geant4Converter::printPlacement(const string& name, const TGeoNode* node) const {
949  Geant4GeometryInfo& info = data();
950  G4VPhysicalVolume* g4 = info.g4Placements[node];
951  G4LogicalVolume* vol = info.g4Volumes[node->GetVolume()];
952  G4LogicalVolume* mot = info.g4Volumes[node->GetMotherVolume()];
953  G4VSolid* sol = vol->GetSolid();
954  G4ThreeVector tr = g4->GetObjectTranslation();
955 
956  G4VSensitiveDetector* sd = vol->GetSensitiveDetector();
957  if (!sd) {
958  return g4;
959  }
960  stringstream str;
961  str << "G4Cnv::placement: + " << name << " No:" << node->GetNumber() << " Vol:" << vol->GetName() << " Solid:"
962  << sol->GetName();
963  printout(m_outputLevel, "G4Placement", str.str().c_str());
964  str.str("");
965  str << " |" << " Loc: x=" << tr.x() << " y=" << tr.y() << " z=" << tr.z();
966  printout(m_outputLevel, "G4Placement", str.str().c_str());
967  printout(m_outputLevel, "G4Placement", printSolid(sol).c_str());
968  str.str("");
969  str << " |" << " Ndau:" << vol->GetNoDaughters() << " physvols." << " Mat:" << vol->GetMaterial()->GetName()
970  << " Mother:" << (char*) (mot ? mot->GetName().c_str() : "---");
971  printout(m_outputLevel, "G4Placement", str.str().c_str());
972  str.str("");
973  str << " |" << " SD:" << sd->GetName();
974  printout(m_outputLevel, "G4Placement", str.str().c_str());
975  return g4;
976 }
977 
978 template <typename O, typename C, typename F> void handleRefs(const O* o, const C& c, F pmf) {
979  for (typename C::const_iterator i = c.begin(); i != c.end(); ++i) {
980  //(o->*pmf)((*i)->GetName(), *i);
981  (o->*pmf)("", *i);
982  }
983 }
984 template <typename O, typename C, typename F> void handle(const O* o, const C& c, F pmf) {
985  for (typename C::const_iterator i = c.begin(); i != c.end(); ++i) {
986  (o->*pmf)((*i)->GetName(), *i);
987  }
988 }
989 
990 template <typename O, typename C, typename F> void handleMap(const O* o, const C& c, F pmf) {
991  for (typename C::const_iterator i = c.begin(); i != c.end(); ++i)
992  (o->*pmf)((*i).first, (*i).second);
993 }
994 
995 template <typename O, typename C, typename F> void handleRMap(const O* o, const C& c, F pmf) {
996  for (typename C::const_reverse_iterator i = c.rbegin(); i != c.rend(); ++i) {
997  //cout << "Handle RMAP [ " << (*i).first << " ]" << endl;
998  handle(o, (*i).second, pmf);
999  }
1000 }
1001 
1004  Geant4GeometryInfo& geo = this->init();
1005  m_data->clear();
1006  collect(top, geo);
1007  m_checkOverlaps = false;
1008  // We do not have to handle defines etc.
1009  // All positions and the like are not really named.
1010  // Hence, start creating the G4 objects for materials, solids and log volumes.
1011  Material mat = m_lcdd.material("Argon");
1012  handleMaterial(mat.name(), mat);
1013  mat = m_lcdd.material("Silicon");
1014  handleMaterial(mat.name(), mat);
1015 
1016  //m_outputLevel = WARNING;
1017  //setPrintLevel(VERBOSE);
1018 
1021  printout(m_outputLevel, "Geant4Converter", "++ Handled %ld solids.", geo.solids.size());
1023  printout(m_outputLevel, "Geant4Converter", "++ Handled %ld visualization attributes.", geo.vis.size());
1025  printout(m_outputLevel, "Geant4Converter", "++ Handled %ld limit sets.", geo.limits.size());
1027  printout(m_outputLevel, "Geant4Converter", "++ Handled %ld regions.", geo.regions.size());
1029  printout(m_outputLevel, "Geant4Converter", "++ Handled %ld volumes.", geo.volumes.size());
1031  // Now place all this stuff appropriately
1033  //==================== Fields
1035 
1036  //handleMap(this, geo.sensitives, &Geant4Converter::printSensitive);
1037  //handleRMap(this, *m_data, &Geant4Converter::printPlacement);
1038 
1039  geo.setWorld(top.placement().ptr());
1040  geo.valid = true;
1041  printout(INFO, "Geant4Converter", "+++ Successfully converted geometry to Geant4.");
1042  return *this;
1043 }
Geant4GeometryMaps::LimitMap g4Limits
Handle class to hold the information of a sensitive detector.
Definition: Detector.h:47
std::string toString() const
Conversion to a string representation.
Definition: Objects.cpp:414
void setWorld(const TGeoNode *node)
Set the world volume.
Hack! Wrapper around G4AssemblyVolume to access protected members.
Ref_t sensitiveDetector() const
Access to the handle to the sensitive detector.
Definition: Volumes.cpp:743
Class of the ROOT toolkit. See http://root.cern.ch/root/htmldoc/ClassIndex.html.
Definition: ROOTClasses.h:14
void handleRefs(const O *o, const C &c, F pmf)
static const double MeV
Definition: DD4hepUnits.h:146
const char * name() const
Access the object name (or "" if not supported by the object)
Definition: Handle.inl:36
Handle class describing a material.
Definition: Objects.h:300
bool storeSecondaries() const
Access secondaries flag.
Definition: Objects.cpp:480
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:124
Handle class describing an element in the periodic table.
Definition: Objects.h:267
#define M_PI
Definition: Handle.h:39
const std::string & hitsCollection() const
Access the hits collection name.
Definition: Detector.cpp:473
LimitSet limitSet() const
Access to the limit set.
Definition: Volumes.cpp:731
const std::set< DD4hep::Geometry::Limit > & limits() const
Accessor to limits container.
Definition: Objects.cpp:434
Class of the Geant4 toolkit. See http://www-geant4.kek.jp/Reference.
Definition: Geant4Classes.h:48
Geant4GeometryMaps::AssemblyMap g4AssemblyVolumes
double cut() const
Access cut value.
Definition: Objects.cpp:470
virtual void * handleAssembly(const std::string &name, const TGeoNode *node) const
Dump volume placement in GDML format to output stream.
const char * yes_no(bool value)
Helper function to print booleans in format YES/NO.
Definition: Printout.h:295
LimitSet limits() const
Access to the limit set of the sensitive detector (not mandatory).
Definition: Detector.cpp:519
Geant4GeometryInfo & init()
Create and attach new data block. Delete old data block if present.
string printSolid(G4VSolid *sol)
#define mix(a, b, c)
virtual ~Geant4Converter()
Standard destructor.
void copy(Alignment from, Alignment to)
Copy alignment object from source object.
TGeoShape * s
Definition: Volumes.cpp:294
return e
Definition: Volumes.cpp:297
VisAttr visAttributes() const
Access the visualisation attributes.
Definition: Volumes.cpp:679
virtual void * handleLimitSet(LimitSet limitset, const std::set< const TGeoVolume * > &volumes) const
Convert the geometry type LimitSet into the corresponding Geant4 object(s).
PrintLevel printLevel()
Access the current printer level.
Definition: Printout.cpp:323
virtual void * handleElement(const std::string &name, Atom element) const
Convert the geometry type element into the corresponding Geant4 object(s).
PrintLevel
Definition: Printout.h:47
virtual void * handleVolume(const std::string &name, const TGeoVolume *volume) const
Convert the geometry type logical volume into the corresponding Geant4 object(s). ...
T * ptr() const
Access to the held object.
Definition: Handle.h:149
Geant4GeometryMaps::RegionVolumes regions
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:237
void handleRMap(const O *o, const C &c, F pmf)
std::vector< const TGeoNode * > m_entries
bool rgb(float &red, float &green, float &blue) const
Get RGB values of the color (if valid)
Definition: Objects.cpp:333
virtual LimitSet limitSet(const std::string &name) const =0
Retrieve a limitset by it's name from the detector description.
GeoHandler & collect(DetElement top)
Collect geometry information from traversal.
Definition: GeoHandler.cpp:80
std::vector< std::string > & limits() const
Access references to user limits.
Definition: Objects.cpp:465
std::string placementPath(DetElement element)
Assemble the placement path from a given detector element to the world volume.
The base class for all DD4hep geometry crawlers.
Definition: GeoHandler.h:102
bool visible() const
Get visibility flag.
Definition: Objects.cpp:277
virtual void * handleRegion(Region region, const std::set< const TGeoVolume * > &volumes) const
Convert the geometry type region into the corresponding Geant4 object(s).
long placeAssembly(const TGeoNode *n, Geant4AssemblyVolume *pPlacedVolume, G4Transform3D &transformation)
virtual void * handleMaterial(const std::string &name, Material medium) const
Convert the geometry type material into the corresponding Geant4 object(s).
double threshold() const
Access production threshold.
Definition: Objects.cpp:475
static const double cm3
Definition: DD4hepUnits.h:75
Geant4GeometryMaps::VolumeMap g4Volumes
Geant4GeometryMaps::MaterialMap g4Materials
virtual void * handleVis(const std::string &name, VisAttr vis) const
Convert the geometry visualisation attributes to the corresponding Geant4 object(s).
long placeVolume(const TGeoNode *n, G4LogicalVolume *pPlacedVolume, G4Transform3D &transformation)
Geant4GeometryMaps::VolumeImprintMap g4VolumeImprints
std::string name
Definition: Objects.h:447
std::set< const TGeoVolume * > ConstVolumeSet
Definition: GeoHandler.h:54
int lineStyle() const
Get line style.
Definition: Objects.cpp:287
std::vector< const TGeoNode * > Chain
static const double gram
Definition: DD4hepUnits.h:157
static const double mole
Definition: DD4hepUnits.h:238
virtual void printSensitive(SensitiveDetector sens_det, const std::set< const TGeoVolume * > &volumes) const
Print the geometry type SensitiveDetector.
PlacedVolume placement() const
Access to the physical volume of this detector element.
Definition: Detector.cpp:279
static const double g
Definition: DD4hepUnits.h:162
Region region() const
Access to the handle to the region structure.
Definition: Volumes.cpp:712
Geant4Converter(LCDD &lcdd)
Initializing Constructor.
Geant4GeometryMaps::LimitVolumes limits
virtual void * printPlacement(const std::string &name, const TGeoNode *node) const
Print Geant4 placement.
Handle< NamedObject > Ref_t
Default Ref_t definition describing named objects.
Definition: Handle.h:176
Geant4GeometryMaps::SensitiveVolumes sensitives
Geant4Converter & create(DetElement top)
Create geometry conversion.
Geant4GeometryMaps::RegionMap g4Regions
Small object describing a limit structure acting on a particle type.
Definition: Objects.h:444
std::map< std::string, PropertyValues > Properties
Definition: LCDD.h:89
#define DEGREE_2_RAD
Definition: Handle.h:29
virtual void * collectVolume(const std::string &name, const TGeoVolume *volume) const
Dump logical volume in GDML format to output stream.
virtual Properties & properties() const =0
Access to properties map.
Handle class describing visualization attributes.
Definition: Objects.h:341
Handle class describing a detector element.
Definition: Detector.h:172
void handleProperties(LCDD::Properties &prp) const
Handle the geant 4 specific properties.
#define CM_2_MM
Definition: Handle.h:32
Geant4GeometryMaps::ElementMap g4Elements
Geant4GeometryMaps::PlacementMap g4Placements
void handleMap(const O *o, const C &c, F pmf)
Geometry converter from DD4hep to Geant 4.
View * v
Definition: MultiView.cpp:30
Handle class describing a set of limits as they are used for simulation.
Definition: Objects.h:475
Handle class describing a region as used in simulation.
Definition: Objects.h:516
void imprint(Geant4GeometryInfo &info, const TGeoNode *n, Chain chain, Geant4AssemblyVolume *pAssembly, G4LogicalVolume *pMotherLV, G4Transform3D &transformation, G4int copyNumBase, G4bool surfCheck)
The main interface to the DD4hep detector description package.
Definition: LCDD.h:82
Concreate class holding the relation information between geant4 objects and dd4hep objects...
Geometry mapping from DD4hep to Geant 4.
Definition: Geant4Mapping.h:36
virtual void * handlePlacement(const std::string &name, const TGeoNode *node) const
Convert the geometry type volume placement into the corresponding Geant4 object(s).
virtual Material material(const std::string &name) const =0
Retrieve a matrial by it's name from the detector description.
float alpha() const
Get alpha value.
Definition: Objects.cpp:307
void handle(const O *o, const C &c, F pmf)
Geant4GeometryMaps::SolidMap g4Solids
static const double mm
Definition: DD4hepUnits.h:69
int printout(PrintLevel severity, const char *src, const char *fmt,...)
Calls the display action with a given severity level.
Definition: Printout.cpp:111
std::string type() const
Access the type of the sensitive detector.
Definition: Detector.cpp:440
std::map< LimitSet, G4UserLimits * > LimitMap
Region region() const
Access to the region setting of the sensitive detector (not mandatory)
Definition: Detector.cpp:508
Geant4GeometryInfo & data() const
Access to the data pointer.
Definition: Geant4Mapping.h:72
static const double ns
Definition: DD4hepUnits.h:122
TGeoShape TGeoMedium * m
Definition: Volumes.cpp:294
std::map< std::string, std::string > PropertyValues
Definition: LCDD.h:88
bool showDaughters() const
Get Flag to show/hide daughter elements.
Definition: Objects.cpp:267
virtual void * handleSolid(const std::string &name, const TGeoShape *volume) const
Convert the geometry type solid into the corresponding Geant4 object(s).
double energyCutoff() const
Access energy cut off.
Definition: Detector.cpp:462