Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Geo2G4SolidFactory.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "Geo2G4SolidFactory.h"
6 #include "LArWheelSolid.h"
7 #include "LArWheelSliceSolid.h"
8 #include "LArWheelSolidDDProxy.h"
9 
10 
11 #include "GeoModelKernel/GeoShape.h"
12 #include "GeoModelKernel/GeoBox.h"
13 #include "GeoModelKernel/GeoTube.h"
14 #include "GeoModelKernel/GeoTubs.h"
15 #include "GeoModelKernel/GeoTrd.h"
16 #include "GeoModelKernel/GeoPcon.h"
17 #include "GeoModelKernel/GeoPgon.h"
18 #include "GeoModelKernel/GeoPara.h"
19 #include "GeoModelKernel/GeoTrap.h"
20 #include "GeoModelKernel/GeoCons.h"
21 #include "GeoModelKernel/GeoSimplePolygonBrep.h"
22 #include "GeoModelKernel/GeoTessellatedSolid.h"
23 #include "GeoModelKernel/GeoEllipticalTube.h"
24 #include "GeoModelKernel/GeoTorus.h"
25 #include "GeoModelKernel/GeoGenericTrap.h"
26 #include "GeoModelKernel/GeoShapeShift.h"
27 #include "GeoModelKernel/GeoShapeUnion.h"
28 #include "GeoModelKernel/GeoShapeIntersection.h"
29 #include "GeoModelKernel/GeoUnidentifiedShape.h"
30 #include "GeoModelKernel/GeoShapeSubtraction.h"
31 
32 
33 #include "GaudiKernel/ISvcLocator.h"
34 #include "GaudiKernel/Bootstrap.h"
40 
41 
44 
45 
46 
47 #include "G4VSolid.hh"
48 #include "G4Box.hh"
49 #include "G4Tubs.hh"
50 #include "G4Trd.hh"
51 #include "G4Polycone.hh"
52 #include "G4Cons.hh"
53 #include "G4Polyhedra.hh"
54 #include "G4Trap.hh"
55 #include "G4Para.hh"
56 #include "G4UnionSolid.hh"
57 #include "G4DisplacedSolid.hh"
58 #include "G4IntersectionSolid.hh"
59 #include "G4SubtractionSolid.hh"
60 #include "G4ExtrudedSolid.hh"
61 #include "G4TessellatedSolid.hh"
62 #include "G4EllipticalTube.hh"
63 #include "G4Torus.hh"
64 #include "G4TriangularFacet.hh"
65 #include "G4QuadrangularFacet.hh"
66 #include "G4GenericTrap.hh"
67 
68 #include <iostream>
69 #include <map>
70 #include <cmath>
71 #include <utility>
72 
74 
75 typedef std::map<const GeoShape*, G4VSolid*, std::less<const GeoShape*> > shapesMap;
76 typedef std::map<std::string, G4VSolid*,std::less<std::string> > customSolidMap;
77 
79 /* entries w/o explicit Pos/Neg kept for backward compatibility */
80  { "LAr::EMEC::InnerWheel::Absorber", {InnerAbsorberWheel, 1} },
81  { "LAr::EMEC::InnerWheel::Electrode", {InnerElectrodWheel, 1} },
82  { "LAr::EMEC::InnerWheel::Glue", {InnerGlueWheel, 1} },
83  { "LAr::EMEC::InnerWheel::Lead", {InnerLeadWheel, 1} },
84 
85  { "LAr::EMEC::OuterWheel::Absorber", {OuterAbsorberWheel, 1} },
86  { "LAr::EMEC::OuterWheel::Electrode", {OuterElectrodWheel, 1} },
87  { "LAr::EMEC::OuterWheel::Glue", {OuterGlueWheel, 1} },
88  { "LAr::EMEC::OuterWheel::Lead", {OuterLeadWheel, 1} },
89 
90  { "LAr::EMEC::Pos::InnerWheel::Absorber", {InnerAbsorberWheel, 1} },
91  { "LAr::EMEC::Pos::InnerWheel::Electrode", {InnerElectrodWheel, 1} },
92  { "LAr::EMEC::Pos::InnerWheel::Glue", {InnerGlueWheel, 1} },
93  { "LAr::EMEC::Pos::InnerWheel::Lead", {InnerLeadWheel, 1} },
94 
95  { "LAr::EMEC::Pos::OuterWheel::Absorber", {OuterAbsorberWheel, 1} },
96  { "LAr::EMEC::Pos::OuterWheel::Electrode", {OuterElectrodWheel, 1} },
97  { "LAr::EMEC::Pos::OuterWheel::Glue", {OuterGlueWheel, 1} },
98  { "LAr::EMEC::Pos::OuterWheel::Lead", {OuterLeadWheel, 1} },
99 
100  { "LAr::EMEC::Neg::InnerWheel::Absorber", {InnerAbsorberWheel, -1} },
101  { "LAr::EMEC::Neg::InnerWheel::Electrode", {InnerElectrodWheel, -1} },
102  { "LAr::EMEC::Neg::InnerWheel::Glue", {InnerGlueWheel, -1} },
103  { "LAr::EMEC::Neg::InnerWheel::Lead", {InnerLeadWheel, -1} },
104 
105  { "LAr::EMEC::Neg::OuterWheel::Absorber", {OuterAbsorberWheel, -1} },
106  { "LAr::EMEC::Neg::OuterWheel::Electrode", {OuterElectrodWheel, -1} },
107  { "LAr::EMEC::Neg::OuterWheel::Glue", {OuterGlueWheel, -1} },
108  { "LAr::EMEC::Neg::OuterWheel::Lead", {OuterLeadWheel, -1} },
109 
110  { "LAr::EMEC::InnerModule::Absorber", {InnerAbsorberModule, 1} },
111  { "LAr::EMEC::InnerModule::Electrode", {InnerElectrodModule, 1} },
112  { "LAr::EMEC::OuterModule::Absorber", {OuterAbsorberModule, 1} },
113  { "LAr::EMEC::OuterModule::Electrode", {OuterElectrodModule, 1} },
114 
115  { "LAr::EMEC::Pos::InnerCone::Absorber", {InnerAbsorberCone, 1} },
116  { "LAr::EMEC::Pos::InnerCone::Electrode", {InnerElectrodCone, 1} },
117  { "LAr::EMEC::Pos::InnerCone::Glue", {InnerGlueCone, 1} },
118  { "LAr::EMEC::Pos::InnerCone::Lead", {InnerLeadCone, 1} },
119 
120  { "LAr::EMEC::Neg::InnerCone::Absorber", {InnerAbsorberCone, -1} },
121  { "LAr::EMEC::Neg::InnerCone::Electrode", {InnerElectrodCone, -1} },
122  { "LAr::EMEC::Neg::InnerCone::Glue", {InnerGlueCone, -1} },
123  { "LAr::EMEC::Neg::InnerCone::Lead", {InnerLeadCone, -1} },
124 
125  { "LAr::EMEC::Pos::OuterFrontCone::Absorber", {OuterAbsorberFrontCone, 1} },
126  { "LAr::EMEC::Pos::OuterFrontCone::Electrode", {OuterElectrodFrontCone, 1} },
127  { "LAr::EMEC::Pos::OuterFrontCone::Glue", {OuterGlueFrontCone, 1} },
128  { "LAr::EMEC::Pos::OuterFrontCone::Lead", {OuterLeadFrontCone, 1} },
129 
130  { "LAr::EMEC::Neg::OuterFrontCone::Absorber", {OuterAbsorberFrontCone, -1} },
131  { "LAr::EMEC::Neg::OuterFrontCone::Electrode", {OuterElectrodFrontCone, -1} },
132  { "LAr::EMEC::Neg::OuterFrontCone::Glue", {OuterGlueFrontCone, -1} },
133  { "LAr::EMEC::Neg::OuterFrontCone::Lead", {OuterLeadFrontCone, -1} },
134 
135  { "LAr::EMEC::Pos::OuterBackCone::Absorber", {OuterAbsorberBackCone, 1} },
136  { "LAr::EMEC::Pos::OuterBackCone::Electrode", {OuterElectrodBackCone, 1} },
137  { "LAr::EMEC::Pos::OuterBackCone::Glue", {OuterGlueBackCone, 1} },
138  { "LAr::EMEC::Pos::OuterBackCone::Lead", {OuterLeadBackCone, 1} },
139 
140  { "LAr::EMEC::Neg::OuterBackCone::Absorber", {OuterAbsorberBackCone, -1} },
141  { "LAr::EMEC::Neg::OuterBackCone::Electrode", {OuterElectrodBackCone, -1} },
142  { "LAr::EMEC::Neg::OuterBackCone::Glue", {OuterGlueBackCone, -1} },
143  { "LAr::EMEC::Neg::OuterBackCone::Lead", {OuterLeadBackCone, -1} },
144 };
145 
147  AthMessaging("Geo2G4SolidFactory"),
148  m_detStore( "StoreGateSvc/DetectorStore", "Geo2G4SolidFactory" )
149 {
150 }
151 
152 G4VSolid *Geo2G4SolidFactory::Build ATLAS_NOT_THREAD_SAFE (const GeoShape* geoShape, const std::string & name)
153 {
154  G4VSolid* theSolid(nullptr);
155 
156  static customSolidMap customSolids;
157  static shapesMap sharedShapes;
158  if(sharedShapes.find(geoShape)!=sharedShapes.end())
159  return sharedShapes[geoShape];
160 
161  // ------- Variables for boolean operations
162  G4VSolid* solidA(nullptr);
163  G4VSolid* solidB(nullptr);
164  auto n = name;
165 
166  //
167  // The Box
168  //
169  if(geoShape->typeID() == GeoBox::getClassTypeID() )
170  {
171  const GeoBox* theBox = dynamic_cast<const GeoBox*> (geoShape);
172  if (nullptr==theBox) throw std::runtime_error("TypeID did not match cast for box");
173  if (n.empty()) n="G4Box";
174  if (theBox->getXHalfLength()<=0.){ ATH_MSG_WARNING("Box " << n << " has an x side of " << theBox->getXHalfLength() <<" - using std::abs.");}
175  if (theBox->getYHalfLength()<=0.){ ATH_MSG_WARNING("Box " << n << " has an y side of " << theBox->getYHalfLength() <<" - using std::abs.");}
176  if (theBox->getZHalfLength()<=0.){ ATH_MSG_WARNING("Box " << n << " has an z side of " << theBox->getZHalfLength() <<" - using std::abs.");}
177  theSolid = new G4Box(n,
178  std::abs(theBox->getXHalfLength()),
179  std::abs(theBox->getYHalfLength()),
180  std::abs(theBox->getZHalfLength()));
181  }
182  //
183  // The Tube
184  //
185  else if(geoShape->typeID() == GeoTube::getClassTypeID() )
186  {
187  const GeoTube* theTube = dynamic_cast<const GeoTube*> (geoShape);
188  if (nullptr==theTube) throw std::runtime_error("TypeID did not match cast for tube");
189  if (n.empty()) n="G4Tube";
190  if (theTube->getRMax()<=0.){ ATH_MSG_WARNING("Tube " << n << " has a max radius of " << theTube->getRMax() <<" - using std::abs.");}
191  if (theTube->getZHalfLength()<=0.){ ATH_MSG_WARNING("Tube " << n << " has a z half length of " << theTube->getZHalfLength() << " - using std::abs.");}
192  if (theTube->getRMax()<theTube->getRMin()){ ATH_MSG_WARNING("Tube " << n << " has a max radius of " << theTube->getRMax() << " and a min radius of " << theTube->getRMin());}
193  theSolid = new G4Tubs(n,
194  theTube->getRMin(),
195  std::abs(theTube->getRMax()),
196  std::abs(theTube->getZHalfLength()),
197  0.,360*CLHEP::deg);
198  }
199  //
200  // The Tubs
201  //
202  else if(geoShape->typeID() == GeoTubs::getClassTypeID() )
203  {
204  const GeoTubs* theTubs = dynamic_cast<const GeoTubs*> (geoShape);
205  if (nullptr==theTubs) throw std::runtime_error("TypeID did not match cast for tubs");
206  if (n.empty()) n="G4Tubs";
207  if (theTubs->getRMin()<0.){ ATH_MSG_WARNING("Tubs " << n << " has a min radius of " << theTubs->getRMax());}
208  if (theTubs->getRMax()<=0.){ ATH_MSG_WARNING("Tubs " << n << " has a max radius of " << theTubs->getRMax() <<" - using std::abs.");}
209  if (theTubs->getZHalfLength()<=0.){ ATH_MSG_WARNING("Tubs " << n << " has a half length of " << theTubs->getZHalfLength() <<" - using std::abs.");}
210  if (theTubs->getRMax()<theTubs->getRMin()){ ATH_MSG_WARNING("Tubs " << n << " has a max radius of " << theTubs->getRMax() << " and a min radius of " << theTubs->getRMin());}
211  if (theTubs->getDPhi()<=0.){ ATH_MSG_WARNING("Tubs " << n << " has a dPhi of " << theTubs->getDPhi());}
212  theSolid = new G4Tubs(n,
213  theTubs->getRMin(),
214  std::abs(theTubs->getRMax()),
215  std::abs(theTubs->getZHalfLength()),
216  theTubs->getSPhi(),
217  theTubs->getDPhi());
218  }
219  //
220  // The Trd
221  //
222  else if(geoShape->typeID() == GeoTrd::getClassTypeID() )
223  {
224  const GeoTrd* theTrd = dynamic_cast<const GeoTrd*> (geoShape);
225  if (nullptr==theTrd) throw std::runtime_error("TypeID did not match cast for trd");
226  if (n.empty()) n="G4Trd";
227  if (theTrd->getXHalfLength1()<0.){ ATH_MSG_WARNING("Trd " << n << " has a x half length 1 of " << theTrd->getXHalfLength1() << " - using std::abs.");}
228  if (theTrd->getXHalfLength2()<0.){ ATH_MSG_WARNING("Trd " << n << " has a x half length 2 of " << theTrd->getXHalfLength2() << " - using std::abs.");}
229  if (theTrd->getYHalfLength1()<0.){ ATH_MSG_WARNING("Trd " << n << " has a y half length 1 of " << theTrd->getYHalfLength1() << " - using std::abs.");}
230  if (theTrd->getYHalfLength2()<0.){ ATH_MSG_WARNING("Trd " << n << " has a y half length 2 of " << theTrd->getYHalfLength2() << " - using std::abs.");}
231  if (theTrd->getZHalfLength()<=0.){ ATH_MSG_WARNING("Trd " << n << " has a z half length of " << theTrd->getZHalfLength() << " - using std::abs.");}
232  if (theTrd->getXHalfLength1()<=0. && theTrd->getXHalfLength2()<=0.){ ATH_MSG_WARNING("Trd " << n << " has an x half length 1 of " << theTrd->getXHalfLength1()
233  << " and an x half length 2 of " << theTrd->getXHalfLength2() << " - using std::abs.");}
234  if (theTrd->getYHalfLength1()<=0. && theTrd->getYHalfLength2()<=0.){ ATH_MSG_WARNING("Trd " << n << " has a y half length 1 of " << theTrd->getYHalfLength1()
235  << " and a y half length 2 of " << theTrd->getYHalfLength2() << " - using std::abs.");}
236  theSolid = new G4Trd(n,
237  std::abs(theTrd->getXHalfLength1()),
238  std::abs(theTrd->getXHalfLength2()),
239  std::abs(theTrd->getYHalfLength1()),
240  std::abs(theTrd->getYHalfLength2()),
241  std::abs(theTrd->getZHalfLength()));
242  }
243  //
244  // GeoPcon
245  //
246  else if(geoShape->typeID() == GeoPcon::getClassTypeID())
247  {
248  const GeoPcon* thePcon = dynamic_cast<const GeoPcon*>(geoShape);
249  if (nullptr==thePcon) throw std::runtime_error("TypeID did not match cast for pcon");
250  theSolid = new G4Polycone(n.empty()?"G4Polycone":std::move(n),
251  thePcon->getSPhi(),
252  thePcon->getDPhi(),
253  thePcon->getNPlanes(),
254  thePcon->getZPlaneBuff(),
255  thePcon->getRMinBuff(),
256  thePcon->getRMaxBuff());
257  }
258  //
259  // GeoCons
260  //
261  else if(geoShape->typeID() == GeoCons::getClassTypeID())
262  {
263  const GeoCons* theCons = dynamic_cast<const GeoCons*>(geoShape);
264  if (nullptr==theCons) throw std::runtime_error("TypeID did not match cast for cons");
265  if (n.empty()) n="G4Cons";
266  if (theCons->getRMax1()<0.){ ATH_MSG_WARNING("Cons " << n << " has a max radius 1 of " << theCons->getRMax1() << " - will use std::abs.");}
267  if (theCons->getRMax2()<0.){ ATH_MSG_WARNING("Cons " << n << " has a max radius 2 of " << theCons->getRMax2() << " - will use std::abs.");}
268  if (theCons->getRMin1()<0.){ ATH_MSG_WARNING("Cons " << n << " has a min radius 1 of " << theCons->getRMin1());}
269  if (theCons->getRMin2()<0.){ ATH_MSG_WARNING("Cons " << n << " has a min radius 2 of " << theCons->getRMin2());}
270  if (theCons->getDZ()<=0){ ATH_MSG_WARNING("Cons " << n << " has a DZ of " << theCons->getDZ() << " - will use std::abs.");}
271  if (theCons->getRMax1()<=0. && theCons->getRMax2()<=0.){ ATH_MSG_WARNING("Cons " << n << " has a max radius 1 of " << theCons->getRMax1()
272  << " and a max radius 2 of " << theCons->getRMax2() << " - will use std::abs.");}
273  theSolid = new G4Cons(n,
274  theCons->getRMin1(),
275  std::abs(theCons->getRMax1()),
276  theCons->getRMin2(),
277  std::abs(theCons->getRMax2()),
278  std::abs(theCons->getDZ()),
279  theCons->getSPhi(),
280  theCons->getDPhi());
281  }
282  //
283  // GeoPara
284  //
285  else if(geoShape->typeID() == GeoPara::getClassTypeID())
286  {
287  const GeoPara* thePara = dynamic_cast<const GeoPara*>(geoShape);
288  if (nullptr==thePara) throw std::runtime_error("TypeID did not match cast for para");
289  if (n.empty()) n="G4Para";
290  if (thePara->getXHalfLength()<=0.){ ATH_MSG_WARNING("Para " << n << " has an x side of " << thePara->getXHalfLength() <<" - using std::abs.");}
291  if (thePara->getYHalfLength()<=0.){ ATH_MSG_WARNING("Para " << n << " has an y side of " << thePara->getYHalfLength() <<" - using std::abs.");}
292  if (thePara->getZHalfLength()<=0.){ ATH_MSG_WARNING("Para " << n << " has an z side of " << thePara->getZHalfLength() <<" - using std::abs.");}
293  theSolid = new G4Para(n,
294  std::abs(thePara->getXHalfLength()),
295  std::abs(thePara->getYHalfLength()),
296  std::abs(thePara->getZHalfLength()),
297  thePara->getAlpha(),
298  thePara->getTheta(),
299  thePara->getPhi());
300  }
301  //
302  // GeoPgon
303  //
304  else if(geoShape->typeID() == GeoPgon::getClassTypeID())
305  {
306  const GeoPgon* thePgon = dynamic_cast<const GeoPgon*>(geoShape);
307  if (nullptr==thePgon) throw std::runtime_error("TypeID did not match cast for pgon");
308 
309  // NB G4Polyhedra copies the contents of these arrays rather than taking ownership.
310  unsigned nPlanes = thePgon->getNPlanes();
311  auto rInner = std::make_unique<double[]>(nPlanes);
312  auto rOuter = std::make_unique<double[]>(nPlanes);
313  double alpha = thePgon->getDPhi()/(2*thePgon->getNSides()); // 1/2 openning angle
314  for (unsigned int index=0; index<static_cast<unsigned int>(nPlanes); index++) {
315  rInner[index] = thePgon->getRMinPlane(index)*cos(alpha);
316  rOuter[index] = thePgon->getRMaxPlane(index)*cos(alpha);
317  }
318 
319  theSolid = new G4Polyhedra(n.empty()?"G4Polyhedra":std::move(n),
320  thePgon->getSPhi(),
321  thePgon->getDPhi(),
322  thePgon->getNSides(),
323  nPlanes,
324  thePgon->getZPlaneBuff(),
325  rInner.get(),
326  rOuter.get());
327  }
328  //
329  // GeoTrap
330  //
331  else if(geoShape->typeID() == GeoTrap::getClassTypeID())
332  {
333  const GeoTrap* theTrap = dynamic_cast<const GeoTrap*>(geoShape);
334  if (nullptr==theTrap) throw std::runtime_error("TypeID did not match cast for trap");
335  if (n.empty()) n="G4Trap";
336  if (theTrap->getZHalfLength()<=0.){ ATH_MSG_WARNING("Trap " << n << " has an z side of " << theTrap->getZHalfLength() <<" - using std::abs.");}
337  theSolid = new G4Trap(n,
338  std::abs(theTrap->getZHalfLength()),
339  theTrap->getTheta(),
340  theTrap->getPhi(),
341  theTrap->getDydzn(),
342  theTrap->getDxdyndzn(),
343  theTrap->getDxdypdzn(),
344  theTrap->getAngleydzn(),
345  theTrap->getDydzp(),
346  theTrap->getDxdyndzp(),
347  theTrap->getDxdypdzp(),
348  theTrap->getAngleydzp());
349  }
350  //
351  // Simple Polygon Brep
352  //
353  else if(geoShape->typeID() == GeoSimplePolygonBrep::getClassTypeID())
354  {
355  const GeoSimplePolygonBrep* theBrep = dynamic_cast<const GeoSimplePolygonBrep*>(geoShape);
356  if (nullptr==theBrep) throw std::runtime_error("TypeID did not match cast for brep");
357  if (n.empty()) n="G4ExtrudedSolid";
358  double dz = theBrep->getDZ();
359  int nVertices = theBrep->getNVertices();
360 
361  G4TwoVector off(0,0);
362  std::vector<G4TwoVector> polygon;
363 
364  polygon.reserve(nVertices);
365 for(int i=0; i<nVertices; i++)
366  polygon.push_back(G4TwoVector(theBrep->getXVertex(nVertices-1-i),theBrep->getYVertex(nVertices-1-i)));
367 
368  theSolid = new G4ExtrudedSolid(n,polygon,dz,off,1,off,1);
369  }
370  //
371  // Tessellated Solid
372  //
373  else if(geoShape->typeID() == GeoTessellatedSolid::getClassTypeID())
374  {
375  const GeoTessellatedSolid* theTessellated = dynamic_cast<const GeoTessellatedSolid*>(geoShape);
376  if (nullptr==theTessellated) throw std::runtime_error("TypeID did not match cast for tessellated solid");
377  if(n.empty()) n="G4TessellatedSolid";
378 
379  G4TessellatedSolid* g4Tessellated = new G4TessellatedSolid(n);
380  for(size_t i=0; i<theTessellated->getNumberOfFacets(); ++i) {
381  GeoFacet* geoFacet = theTessellated->getFacet(i);
382  G4FacetVertexType vertexType = (geoFacet->getVertexType()==GeoFacet::ABSOLUTE? ABSOLUTE : RELATIVE);
383  G4VFacet* g4Facet(nullptr);
384  if(geoFacet->getNumberOfVertices()==3)
385  g4Facet = new G4TriangularFacet(Amg::EigenToHep3Vector(geoFacet->getVertex(0)),
386  Amg::EigenToHep3Vector(geoFacet->getVertex(1)),
387  Amg::EigenToHep3Vector(geoFacet->getVertex(2)),
388  vertexType);
389  else
390  g4Facet = new G4QuadrangularFacet(Amg::EigenToHep3Vector(geoFacet->getVertex(0)),
391  Amg::EigenToHep3Vector(geoFacet->getVertex(1)),
392  Amg::EigenToHep3Vector(geoFacet->getVertex(2)),
393  Amg::EigenToHep3Vector(geoFacet->getVertex(3)),
394  vertexType);
395 
396  g4Tessellated->AddFacet(g4Facet);
397  }
398  g4Tessellated->SetSolidClosed(true);
399  theSolid = g4Tessellated;
400  }
401  //
402  // Elliptical Tube
403  //
404  else if(geoShape->typeID() == GeoEllipticalTube::getClassTypeID())
405  {
406  const GeoEllipticalTube* theEltube = dynamic_cast<const GeoEllipticalTube*>(geoShape);
407  if (nullptr==theEltube) throw std::runtime_error("TypeID did not match cast for elliptical tube");
408  if (n.empty()) n="G4EllipticalTube";
409 
410  if (theEltube->getXHalfLength()<=0.){ ATH_MSG_WARNING("Eltube " << n << " has an x side of " << theEltube->getXHalfLength() <<" - using std::abs.");}
411  if (theEltube->getYHalfLength()<=0.){ ATH_MSG_WARNING("Eltube " << n << " has an y side of " << theEltube->getYHalfLength() <<" - using std::abs.");}
412  if (theEltube->getZHalfLength()<=0.){ ATH_MSG_WARNING("Eltube " << n << " has an z side of " << theEltube->getZHalfLength() <<" - using std::abs.");}
413  G4EllipticalTube* g4Eltube = new G4EllipticalTube(n
414  ,std::abs(theEltube->getXHalfLength())
415  ,std::abs(theEltube->getYHalfLength())
416  ,std::abs(theEltube->getZHalfLength()));
417  theSolid = g4Eltube;
418  }
419  //
420  // Torus
421  //
422  else if(geoShape->typeID() == GeoTorus::getClassTypeID() ) {
423  const GeoTorus* theTorus = dynamic_cast<const GeoTorus*> (geoShape);
424  if (nullptr==theTorus) throw std::runtime_error("TypeID did not match cast for torus");
425  if (n.empty()) n="G4Torus";
426 
427  theSolid = new G4Torus(n,
428  theTorus->getRMin(),
429  theTorus->getRMax(),
430  theTorus->getRTor(),
431  theTorus->getSPhi(),
432  theTorus->getDPhi());
433  }
434  //
435  // Generic Trap
436  //
437  else if(geoShape->typeID() == GeoGenericTrap::getClassTypeID()) {
438  const GeoGenericTrap* theGenTrap = dynamic_cast<const GeoGenericTrap*>(geoShape);
439  if (nullptr==theGenTrap) throw std::runtime_error("TypeID did not match cast for generic trap");
440  if (n.empty()) n="G4GenericTrap";
441  if (theGenTrap->getZHalfLength()<=0.){ ATH_MSG_WARNING("GenTrap " << n << " has an z side of " << theGenTrap->getZHalfLength() <<" - using std::abs.");}
442 
443  // Translate vector of vertices from Eigen to CLHEP
444  std::vector<CLHEP::Hep2Vector> clhepVertices;
445  clhepVertices.reserve(theGenTrap->getVertices().size());
446  for(const GeoTrf::Vector2D& geoVertex : theGenTrap->getVertices()) {
447  clhepVertices.push_back(CLHEP::Hep2Vector(geoVertex.x(),geoVertex.y()));
448  }
449 
450  G4GenericTrap* g4GenTrap = new G4GenericTrap(n
451  ,std::abs(theGenTrap->getZHalfLength())
452  ,clhepVertices);
453  theSolid = g4GenTrap;
454  }
455  //
456  // Boolean volumes
457  // We make use of G4DisplacedSolid which is not documented in the manual but makes the implementation
458  // a lot simpler.
459  //
460  // GeoShapeShift
461  //
462  else if (geoShape->typeID() == GeoShapeShift::getClassTypeID() )
463  {
464  const GeoShapeShift* theShapeShift = dynamic_cast<const GeoShapeShift*> (geoShape);
465  if (nullptr==theShapeShift) throw std::runtime_error("TypeID did not match cast for shape shift");
466  if (n.empty()) n="DisplacedSolid";
467  G4VSolid * undisplacedSolid = Build(theShapeShift->getOp());
468  theSolid = new G4DisplacedSolid(n, undisplacedSolid, Amg::EigenTransformToCLHEP(theShapeShift->getX()));
469  }
470  //
471  // GeoShapeUnion
472  //
473  else if (geoShape->typeID() == GeoShapeUnion::getClassTypeID() )
474  {
475  const GeoShapeUnion* theUnion = dynamic_cast<const GeoShapeUnion*> (geoShape);
476  if (nullptr==theUnion) throw std::runtime_error("TypeID did not match cast for union");
477  if (n.empty()) n="Union";
478  solidA = Build(theUnion->getOpA());
479  solidB = Build(theUnion->getOpB());
480  theSolid = new G4UnionSolid(n, solidA, solidB);
481  }
482  //
483  // GeoShapeIntersection
484  //
485  else if (geoShape->typeID() == GeoShapeIntersection::getClassTypeID() )
486  {
487  const GeoShapeIntersection* theIntersection = dynamic_cast<const GeoShapeIntersection*>(geoShape);
488  if (nullptr==theIntersection) throw std::runtime_error("TypeID did not match cast for intersection");
489  if (n.empty()) n="Intersection";
490  solidA = Build(theIntersection->getOpA());
491  solidB = Build(theIntersection->getOpB());
492  theSolid = new G4IntersectionSolid(n, solidA, solidB);
493  }
494  //
495  // GeoShapeSubtraction
496  //
497  else if (geoShape->typeID() == GeoShapeSubtraction::getClassTypeID() )
498  {
499  const GeoShapeSubtraction* theSubtraction = dynamic_cast<const GeoShapeSubtraction*>(geoShape);
500  if (nullptr==theSubtraction) throw std::runtime_error("TypeID did not match cast for subtraction");
501  if (n.empty()) n="Subtraction";
502  solidA = Build(theSubtraction->getOpA());
503  solidB = Build(theSubtraction->getOpB());
504  theSolid = new G4SubtractionSolid(n, solidA, solidB);
505  }
506  //
507  // Custom Shapes (presently LAr shapes only)
508  //
509  else if(geoShape->typeID() == GeoUnidentifiedShape::getClassTypeID())
510  {
511  const GeoUnidentifiedShape* customShape = dynamic_cast<const GeoUnidentifiedShape*> (geoShape);
512  if (nullptr==customShape) throw std::runtime_error("TypeID did not match cast for custom shape");
513  if (customShape->name()=="LArCustomShape") {
514 
515 
516 
517  ISvcLocator* svcLocator = Gaudi::svcLocator();
518  // Access the GeoModelSvc:
519  SmartIF<IGeoModelSvc> geoModel{svcLocator->service ("GeoModelSvc")};
520  if ( !geoModel ) {
521  G4Exception(
522  "Geo2G4SolidFactory", "AccessGeoModel", FatalException,
523  "Build cannot access GeoModelSvc");
524  }
525  SmartIF<IGeoDbTagSvc> geoDbTagSvc{svcLocator->service ("GeoDbTagSvc")};
526  if ( !geoDbTagSvc ) {
527  G4Exception(
528  "Geo2G4SolidFactory", "AccessDbTagSvc", FatalException,
529  "Build cannot access DbTagSvc");
530  }
531  // Access the geometry database:
532  SmartIF<IRDBAccessSvc> pAccessSvc{svcLocator->service(geoDbTagSvc->getParamSvcName())};
533  if ( !pAccessSvc ) {
534  G4Exception(
535  "Geo2G4SolidFactory", "AccessAccessSvc", FatalException,
536  "Build cannot access AccessSvc");
537  }
538  DecodeVersionKey larVersionKey(geoModel, "LAr");
539  EMECData emecData=toEMECData(pAccessSvc,larVersionKey);
540 
541 
542 
543  std::string customName = customShape->asciiData();
544  customSolidMap::const_iterator it = customSolids.find(customName);
545  if(it!=customSolids.end())
546  theSolid = it->second;
547  else
548  {
549  theSolid = nullptr;
550  if(customName.find("Slice") != std::string::npos){
551  theSolid = createLArWheelSliceSolid(customShape,emecData);
552  } else {
553  theSolid = createLArWheelSolid(customName, s_lwsTypes.at(customName) ,emecData); // map.at throws std::out_of_range exception on unknown shape name
554  }
555  if ( nullptr == theSolid ) {
556  std::string error = std::string("Can't create LArWheelSolid for name ") + customName + " in Geo2G4SolidFactory::Build";
557  throw std::runtime_error(error);
558  }
559 
560  if(theSolid != nullptr) customSolids[customName] = theSolid;
561  }
562  }
563  }
564  //
565  // Catch All
566  //
567  else
568  {
569  ATH_MSG_FATAL("Sorry this solid is not yet implemented... ");
570  ATH_MSG_FATAL(geoShape->type());
571  ATH_MSG_FATAL("You will have a core dump...");
572  return nullptr;
573  }
574 
575  sharedShapes[geoShape] = theSolid;
576  return theSolid;
577 }
578 
579 G4VSolid* Geo2G4SolidFactory::createLArWheelSolid ATLAS_NOT_THREAD_SAFE (const std::string& name, const LArWheelSolidDef_t & lwsdef, const EMECData & emecData) const { // LArWheelSolid_t wheelType, int zside
580  LArWheelSolid_t wheelType = lwsdef.first;
581  int zside = lwsdef.second;
582 
583  LArWheelSolid * theLWS = new LArWheelSolid(name, wheelType, zside,nullptr, &emecData);
584 
585  LArWheelSolidDDProxy * theLWS_p = new LArWheelSolidDDProxy(theLWS);
586  // ownership is passed to detStore
587  if ( m_detStore->record(theLWS_p, name).isFailure() ) {
588  ATH_MSG_WARNING("Can't store proxy for LArWheelSolid to the DetectorStore");
589  delete theLWS_p;
590  }
591  return theLWS;
592 }
593 
594 G4VSolid* Geo2G4SolidFactory::createLArWheelSliceSolid ATLAS_NOT_THREAD_SAFE (const GeoUnidentifiedShape* customShape, const EMECData & emecData) const
595 {
596  LArWheelSliceSolid *theLWS = new LArWheelSliceSolid(customShape->asciiData(),&emecData);
597 
598  LArWheelSolidDDProxy *theLWS_p = new LArWheelSolidDDProxy(theLWS);
599  // ownership is passed to detStore
600  if(m_detStore->record(theLWS_p, theLWS->GetName()).isFailure()){
601  ATH_MSG_WARNING("Can't store proxy for LArWheelSolid to the DetectorStore");
602  delete theLWS_p;
603  }
604  return theLWS;
605 }
Geo2G4SolidFactory::s_lwsTypes
static const LArWheelSolid_typemap s_lwsTypes
Definition: Geo2G4SolidFactory.h:36
InnerElectrodCone
@ InnerElectrodCone
Definition: LArWheelSolid_type.h:26
InnerGlueWheel
@ InnerGlueWheel
Definition: LArWheelSolid_type.h:21
ATLAS_NOT_THREAD_SAFE
G4VSolid *Geo2G4SolidFactory::Build ATLAS_NOT_THREAD_SAFE(const GeoShape *geoShape, const std::string &name)
Definition: Geo2G4SolidFactory.cxx:152
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
add-xsec-uncert-quadrature-N.alpha
alpha
Definition: add-xsec-uncert-quadrature-N.py:110
OuterLeadFrontCone
@ OuterLeadFrontCone
Definition: LArWheelSolid_type.h:32
NSWL1::nVertices
int nVertices(const Polygon &p)
Definition: GeoUtils.cxx:35
Geo2G4SolidFactory::LArWheelSolid_typemap
std::map< std::string, LArWheelSolidDef_t > LArWheelSolid_typemap
Definition: Geo2G4SolidFactory.h:27
OuterAbsorberBackCone
@ OuterAbsorberBackCone
Definition: LArWheelSolid_type.h:33
LArWheelSliceSolid.h
EMECData.h
OuterLeadBackCone
@ OuterLeadBackCone
Definition: LArWheelSolid_type.h:36
OuterGlueWheel
@ OuterGlueWheel
Definition: LArWheelSolid_type.h:22
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
index
Definition: index.py:1
EMECData
Definition: EMECData.h:131
skel.it
it
Definition: skel.GENtoEVGEN.py:407
LArWheelSolid_t
LArWheelSolid_t
Definition: LArWheelSolid_type.h:12
deg
#define deg
Definition: SbPolyhedron.cxx:17
Amg::EigenToHep3Vector
CLHEP::Hep3Vector EigenToHep3Vector(const Amg::Vector3D &eigenvector)
Converts an Eigen-based Amg::Vector3D into a CLHEP-based CLHEP::Hep3Vector.
Definition: CLHEPtoEigenConverter.h:147
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
InnerElectrodModule
@ InnerElectrodModule
Definition: LArWheelSolid_type.h:19
Geo2G4SolidFactory::Geo2G4SolidFactory
Geo2G4SolidFactory()
Definition: Geo2G4SolidFactory.cxx:146
InnerElectrodWheel
@ InnerElectrodWheel
Definition: LArWheelSolid_type.h:15
InnerGlueCone
@ InnerGlueCone
Definition: LArWheelSolid_type.h:27
OuterElectrodModule
@ OuterElectrodModule
Definition: LArWheelSolid_type.h:20
OuterGlueFrontCone
@ OuterGlueFrontCone
Definition: LArWheelSolid_type.h:31
OuterAbsorberModule
@ OuterAbsorberModule
Definition: LArWheelSolid_type.h:18
LArWheelSolid.h
InnerLeadWheel
@ InnerLeadWheel
Definition: LArWheelSolid_type.h:23
OuterElectrodFrontCone
@ OuterElectrodFrontCone
Definition: LArWheelSolid_type.h:30
IRDBAccessSvc.h
Definition of the abstract IRDBAccessSvc interface.
lumiFormat.i
int i
Definition: lumiFormat.py:85
beamspotman.n
n
Definition: beamspotman.py:731
DecodeVersionKey
This is a helper class to query the version tags from GeoModelSvc and determine the appropriate tag a...
Definition: DecodeVersionKey.h:18
InnerAbsorberWheel
@ InnerAbsorberWheel
Definition: LArWheelSolid_type.h:13
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
shapesMap
std::map< const GeoShape *, G4VSolid *, std::less< const GeoShape * > > shapesMap
Definition: Geo2G4SolidFactory.cxx:75
OuterLeadWheel
@ OuterLeadWheel
Definition: LArWheelSolid_type.h:24
OuterElectrodBackCone
@ OuterElectrodBackCone
Definition: LArWheelSolid_type.h:34
OuterGlueBackCone
@ OuterGlueBackCone
Definition: LArWheelSolid_type.h:35
LArWheelSolidDDProxy
Definition: LArWheelSolidDDProxy.h:17
InnerLeadCone
@ InnerLeadCone
Definition: LArWheelSolid_type.h:28
InnerAbsorberModule
@ InnerAbsorberModule
Definition: LArWheelSolid_type.h:17
CLHEPtoEigenConverter.h
Geo2G4SolidFactory.h
OuterElectrodWheel
@ OuterElectrodWheel
Definition: LArWheelSolid_type.h:16
LArWheelSolid
Definition: LArWheelSolid.h:94
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
toEMECData.h
xAOD::vertexType
vertexType
Definition: Vertex_v1.cxx:166
DecodeVersionKey.h
OuterAbsorberFrontCone
@ OuterAbsorberFrontCone
Definition: LArWheelSolid_type.h:29
DeMoScan.index
string index
Definition: DeMoScan.py:364
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
toEMECData
EMECData toEMECData(IRDBAccessSvc *rdbAccess, const DecodeVersionKey &larVersionKey)
Definition: toEMECData.h:14
Amg::EigenTransformToCLHEP
HepGeom::Transform3D EigenTransformToCLHEP(const Amg::Transform3D &eigenTransf)
Converts an Eigen-based Amg::Transform3D into a CLHEP-based HepGeom::Transform3D.
Definition: CLHEPtoEigenConverter.h:120
LArWheelSolidDDProxy.h
InnerAbsorberCone
@ InnerAbsorberCone
Definition: LArWheelSolid_type.h:25
LArWheelSliceSolid
Definition: LArWheelSliceSolid.h:46
IRDBRecordset.h
Definition of the abstract IRDBRecordset interface.
IGeoModelSvc.h
error
Definition: IImpactPoint3dEstimator.h:70
OuterAbsorberWheel
@ OuterAbsorberWheel
Definition: LArWheelSolid_type.h:14
customSolidMap
std::map< std::string, G4VSolid *, std::less< std::string > > customSolidMap
Definition: Geo2G4SolidFactory.cxx:76