CMS 3D CMS Logo

TGeoFromDddService.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Geometry
4 // Class : TGeoFromDddService
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author:
10 // Created: Fri Jul 2 16:11:42 CEST 2010
11 //
12 
13 // system include files
14 
15 // user include files
16 
18 
23 
28 
30 
31 #include "TGeoManager.h"
32 #include "TGeoMatrix.h"
33 #include "TGeoCompositeShape.h"
34 #include "TGeoPcon.h"
35 #include "TGeoPgon.h"
36 #include "TGeoCone.h"
37 #include "TGeoBoolNode.h"
38 #include "TGeoTube.h"
39 #include "TGeoArb8.h"
40 #include "TGeoTrd2.h"
41 #include "TGeoXtru.h"
42 
43 #include "Math/GenVector/RotationX.h"
44 
45 #include "CLHEP/Units/GlobalSystemOfUnits.h"
46 
47 
48 //
49 // constants, enums and typedefs
50 //
51 
52 //
53 // static data member definitions
54 //
55 
56 //
57 // constructors and destructor
58 //
60  m_level (pset.getUntrackedParameter<int> ("level", 10)),
61  m_verbose (pset.getUntrackedParameter<bool>("verbose",false)),
62  m_eventSetup (nullptr),
63  m_geoManager (nullptr)
64 {
67 }
68 
70 {
71  if (m_geoManager)
72  {
73  delete m_geoManager;
74  }
75 }
76 
77 
78 //==============================================================================
79 // public member functions
80 //==============================================================================
81 
83 {
84  printf("TGeoFromDddService::postBeginRun\n");
85 
86  m_eventSetup = &es;
87 }
88 
90 {
91  printf("TGeoFromDddService::postEndRun\n");
92 
93  // Construction of geometry fails miserably on second attempt ...
94  /*
95  if (m_geoManager)
96  {
97  delete m_geoManager;
98  m_geoManager = 0;
99  }
100  */
101  m_eventSetup = nullptr;
102 }
103 
105 {
106  if (m_geoManager == nullptr)
107  {
108  if (m_eventSetup == nullptr)
109  edm::LogError("TGeoFromDddService") << "getGeoManager() -- EventSetup not present.\n";
110  else
111  {
113  if (m_geoManager == nullptr)
114  edm::LogError("TGeoFromDddService") << "getGeoManager() -- creation failed.\n";
115  }
116  }
117  gGeoManager = m_geoManager;
118  return m_geoManager;
119 }
120 
121 
122 //==============================================================================
123 // Local helpers
124 //==============================================================================
125 
126 namespace
127 {
128  TGeoCombiTrans* createPlacement(const DDRotationMatrix& iRot,
129  const DDTranslation& iTrans)
130  {
131  // std::cout << "in createPlacement" << std::endl;
132  double elements[9];
133  iRot.GetComponents(elements);
134  TGeoRotation r;
135  r.SetMatrix(elements);
136 
137  TGeoTranslation t(iTrans.x()/cm,
138  iTrans.y()/cm,
139  iTrans.z()/cm);
140 
141  return new TGeoCombiTrans(t,r);
142  }
143 }
144 
145 
146 //==============================================================================
147 // private member functions
148 //==============================================================================
149 
150 
151 TGeoManager*
153 {
154  using namespace edm;
155 
157  m_eventSetup->get<IdealGeometryRecord>().get(viewH);
158 
159  if ( ! viewH.isValid() )
160  {
161  return nullptr;
162  }
163 
164  TGeoManager *geo_mgr = new TGeoManager("cmsGeo","CMS Detector");
165  // NOTE: the default constructor does not create the identity matrix
166  if (gGeoIdentity == nullptr)
167  {
168  gGeoIdentity = new TGeoIdentity("Identity");
169  }
170 
171  std::cout << "about to initialize the DDCompactView walker" << std::endl;
172  auto walker = math::GraphWalker<DDLogicalPart, DDPosData*>( viewH->graph(), viewH->root());
173  auto info = walker.current();
174 
175  // The top most item is actually the volume holding both the
176  // geometry AND the magnetic field volumes!
177  walker.firstChild();
178 
179  TGeoVolume *top = createVolume(info.first.name().fullname(),
180  info.first.solid(),
181  info.first.material());
182  if (top == nullptr)
183  {
184 
185  return nullptr;
186  }
187 
188  geo_mgr->SetTopVolume(top);
189  // ROOT chokes unless colors are assigned
190  top->SetVisibility(kFALSE);
191  top->SetLineColor(kBlue);
192 
193  std::vector<TGeoVolume*> parentStack;
194  parentStack.push_back(top);
195 
196  if( ! walker.firstChild() ) {
197  return nullptr;
198  }
199 
200  do
201  {
202  auto info = walker.current();
203 
204  if (m_verbose)
205  {
206  for(unsigned int i=0; i<parentStack.size();++i) {
207  std::cout <<" ";
208  }
209  std::cout << info.first.name()<<" "<<info.second->copyno()<<" "
210  << DDSolidShapesName::name(info.first.solid().shape())<<std::endl;
211  }
212 
213  bool childAlreadyExists = (nullptr != nameToVolume_[info.first.name().fullname()]);
214  TGeoVolume *child = createVolume(info.first.name().fullname(),
215  info.first.solid(),
216  info.first.material());
217  if (nullptr!=child && info.second != nullptr)
218  {
219  parentStack.back()->AddNode(child,
220  info.second->copyno(),
221  createPlacement(info.second->rotation(),
222  info.second->translation()));
223  child->SetLineColor(kBlue);
224  }
225  else
226  {
227  if ( info.second == nullptr ) {
228  break;
229  }
230  }
231  if (nullptr == child || childAlreadyExists || level == int(parentStack.size()))
232  {
233  if (nullptr!=child)
234  {
235  child->SetLineColor(kRed);
236  }
237  //stop descending
238  if ( ! walker.nextSibling())
239  {
240  while (walker.parent())
241  {
242  parentStack.pop_back();
243  if (walker.nextSibling()) {
244  break;
245  }
246  }
247  }
248  }
249  else
250  {
251  if (walker.firstChild())
252  {
253  parentStack.push_back(child);
254  }
255  else
256  {
257  if ( ! walker.nextSibling())
258  {
259  while (walker.parent())
260  {
261  parentStack.pop_back();
262  if (walker.nextSibling()) {
263  break;
264  }
265  }
266  }
267  }
268  }
269  } while ( ! parentStack.empty());
270 
271  geo_mgr->CloseGeometry();
272 
273  geo_mgr->DefaultColors();
274 
275  nameToShape_.clear();
276  nameToVolume_.clear();
277  nameToMaterial_.clear();
278  nameToMedium_.clear();
279 
280  return geo_mgr;
281 }
282 
283 TGeoShape*
285  const DDSolid& iSolid)
286 {
287  TGeoShape* rSolid= nameToShape_[iName];
288  if (rSolid == nullptr)
289  {
290  const std::vector<double>& params = iSolid.parameters();
291  // std::cout <<" shape "<<iSolid<<std::endl;
292  switch(iSolid.shape())
293  {
294  case DDSolidShape::ddbox:
295  rSolid = new TGeoBBox(
296  iName.c_str(),
297  params[0]/cm,
298  params[1]/cm,
299  params[2]/cm);
300  break;
302  rSolid = new TGeoConeSeg(
303  iName.c_str(),
304  params[0]/cm,
305  params[1]/cm,
306  params[2]/cm,
307  params[3]/cm,
308  params[4]/cm,
309  params[5]/deg,
310  params[6]/deg+params[5]/deg
311  );
312  break;
314  //Order in params is zhalf,rIn,rOut,startPhi,deltaPhi
315  rSolid= new TGeoTubeSeg(
316  iName.c_str(),
317  params[1]/cm,
318  params[2]/cm,
319  params[0]/cm,
320  params[3]/deg,
321  params[3]/deg + params[4]/deg);
322  break;
324  //Order in params is zhalf,rIn,rOut,startPhi,deltaPhi
325  rSolid= new TGeoCtub(
326  iName.c_str(),
327  params[1]/cm,
328  params[2]/cm,
329  params[0]/cm,
330  params[3]/deg,
331  params[3]/deg + params[4]/deg,
332  params[5],params[6],params[7],
333  params[8],params[9],params[10]);
334  break;
336  rSolid =new TGeoTrap(
337  iName.c_str(),
338  params[0]/cm, //dz
339  params[1]/deg, //theta
340  params[2]/deg, //phi
341  params[3]/cm, //dy1
342  params[4]/cm, //dx1
343  params[5]/cm, //dx2
344  params[6]/deg, //alpha1
345  params[7]/cm, //dy2
346  params[8]/cm, //dx3
347  params[9]/cm, //dx4
348  params[10]/deg);//alpha2
349  break;
351  rSolid = new TGeoPcon(
352  iName.c_str(),
353  params[0]/deg,
354  params[1]/deg,
355  (params.size()-2)/3) ;
356  {
357  std::vector<double> temp(params.size()+1);
358  temp.reserve(params.size()+1);
359  temp[0]=params[0]/deg;
360  temp[1]=params[1]/deg;
361  temp[2]=(params.size()-2)/3;
362  std::copy(params.begin()+2,params.end(),temp.begin()+3);
363  for(std::vector<double>::iterator it=temp.begin()+3;
364  it != temp.end();
365  ++it) {
366  *it /=cm;
367  }
368  rSolid->SetDimensions(&(*(temp.begin())));
369  }
370  break;
372  rSolid = new TGeoPgon(
373  iName.c_str(),
374  params[1]/deg,
375  params[2]/deg,
376  static_cast<int>(params[0]),
377  (params.size()-3)/3);
378  {
379  std::vector<double> temp(params.size()+1);
380  temp[0]=params[1]/deg;
381  temp[1]=params[2]/deg;
382  temp[2]=params[0];
383  temp[3]=(params.size()-3)/3;
384  std::copy(params.begin()+3,params.end(),temp.begin()+4);
385  for(std::vector<double>::iterator it=temp.begin()+4;
386  it != temp.end();
387  ++it) {
388  *it /=cm;
389  }
390  rSolid->SetDimensions(&(*(temp.begin())));
391  }
392  break;
394  {
395  DDExtrudedPolygon extrPgon(iSolid);
396  std::vector<double> x = extrPgon.xVec();
397  std::transform(x.begin(), x.end(), x.begin(),[](double d) { return d/cm; });
398  std::vector<double> y = extrPgon.yVec();
399  std::transform(y.begin(), y.end(), y.begin(),[](double d) { return d/cm; });
400  std::vector<double> z = extrPgon.zVec();
401  std::vector<double> zx = extrPgon.zxVec();
402  std::vector<double> zy = extrPgon.zyVec();
403  std::vector<double> zscale = extrPgon.zscaleVec();
404 
405  TGeoXtru* mySolid = new TGeoXtru(z.size());
406  mySolid->DefinePolygon(x.size(), &(*x.begin()), &(*y.begin()));
407  for( size_t i = 0; i < params[0]; ++i )
408  {
409  mySolid->DefineSection( i, z[i]/cm, zx[i]/cm, zy[i]/cm, zscale[i]);
410  }
411 
412  rSolid = mySolid;
413  }
414  break;
416  {
417  //implementation taken from SimG4Core/Geometry/src/DDG4SolidConverter.cc
418  const static DDRotationMatrix s_rot(ROOT::Math::RotationX(90.*deg));
419  DDPseudoTrap pt(iSolid);
420  assert(pt.radius() < 0);
421  double x=0;
422  double r = fabs(pt.radius());
423  if( pt.atMinusZ()) {
424  x=pt.x1();
425  } else {
426  x=pt.x2();
427  }
428  double openingAngle = 2.0*asin(x/r);
429  double h=pt.y1()<pt.y2()? pt.y2() :pt.y1();
430  h+=h/20.;
431  double displacement=0;
432  double startPhi = 0;
433  double delta = sqrt((r+x)*(r-x));
434  if(pt.atMinusZ()) {
435  displacement=-pt.halfZ() - delta;
436  startPhi = 270.-openingAngle/deg/2.0;
437  }else {
438  displacement = pt.halfZ() + delta;
439  startPhi = 90. - openingAngle/deg/2.;
440  }
441  std::unique_ptr<TGeoShape> trap( new TGeoTrd2(pt.name().name().c_str(),
442  pt.x1()/cm,
443  pt.x2()/cm,
444  pt.y1()/cm,
445  pt.y2()/cm,
446  pt.halfZ()/cm) );
447  std::unique_ptr<TGeoShape> tubs( new TGeoTubeSeg(pt.name().name().c_str(),
448  0.,
449  r/cm,
450  h/cm,
451  startPhi,
452  openingAngle) );
453  TGeoSubtraction* sub = new TGeoSubtraction(trap.release(),
454  tubs.release(),
455  createPlacement(s_rot,
456  DDTranslation(0.,
457  0.,
458  displacement)));
459  rSolid = new TGeoCompositeShape(iName.c_str(),
460  sub);
461 
462 
463  break;
464  }
466  {
467  DDBooleanSolid boolSolid(iSolid);
468  if(!boolSolid) {
469  throw cms::Exception("GeomConvert") <<"conversion to DDBooleanSolid failed";
470  }
471 
472  std::unique_ptr<TGeoShape> left( createShape(boolSolid.solidA().name().fullname(),
473  boolSolid.solidA()) );
474  std::unique_ptr<TGeoShape> right( createShape(boolSolid.solidB().name().fullname(),
475  boolSolid.solidB()));
476  if( nullptr != left.get() &&
477  nullptr != right.get() ) {
478  TGeoSubtraction* sub = new TGeoSubtraction(left.release(),right.release(),
479  gGeoIdentity,
480  createPlacement(
481  boolSolid.rotation().matrix(),
482  boolSolid.translation()));
483  rSolid = new TGeoCompositeShape(iName.c_str(),
484  sub);
485  }
486  break;
487  }
489  {
490  DDBooleanSolid boolSolid(iSolid);
491  if(!boolSolid) {
492  throw cms::Exception("GeomConvert") <<"conversion to DDBooleanSolid failed";
493  }
494 
495  std::unique_ptr<TGeoShape> left( createShape(boolSolid.solidA().name().fullname(),
496  boolSolid.solidA()) );
497  std::unique_ptr<TGeoShape> right( createShape(boolSolid.solidB().name().fullname(),
498  boolSolid.solidB()));
499  //DEBUGGING
500  //break;
501  if( nullptr != left.get() &&
502  nullptr != right.get() ) {
503  TGeoUnion* boolS = new TGeoUnion(left.release(),right.release(),
504  gGeoIdentity,
505  createPlacement(
506  boolSolid.rotation().matrix(),
507  boolSolid.translation()));
508  rSolid = new TGeoCompositeShape(iName.c_str(),
509  boolS);
510  }
511  break;
512  }
514  {
515  DDBooleanSolid boolSolid(iSolid);
516  if(!boolSolid) {
517  throw cms::Exception("GeomConvert") <<"conversion to DDBooleanSolid failed";
518  }
519 
520  std::unique_ptr<TGeoShape> left( createShape(boolSolid.solidA().name().fullname(),
521  boolSolid.solidA()) );
522  std::unique_ptr<TGeoShape> right( createShape(boolSolid.solidB().name().fullname(),
523  boolSolid.solidB()));
524  if( nullptr != left.get() &&
525  nullptr != right.get() ) {
526  TGeoIntersection* boolS = new TGeoIntersection(left.release(),
527  right.release(),
528  gGeoIdentity,
529  createPlacement(
530  boolSolid.rotation().matrix(),
531  boolSolid.translation()));
532  rSolid = new TGeoCompositeShape(iName.c_str(),
533  boolS);
534  }
535  break;
536  }
537  default:
538  break;
539  }
540  nameToShape_[iName]=rSolid;
541  }
542  if (rSolid == nullptr)
543  {
544  std::cerr <<"COULD NOT MAKE "<<iName<<std::endl;
545  }
546  return rSolid;
547 }
548 
549 TGeoVolume*
551  const DDSolid& iSolid,
552  const DDMaterial& iMaterial)
553 {
554  TGeoVolume* v=nameToVolume_[iName];
555  if (v == nullptr)
556  {
557  TGeoShape* solid = createShape(iSolid.name().fullname(),
558  iSolid);
559  std::string mat_name = iMaterial.name().fullname();
560  TGeoMedium *geo_med = nameToMedium_[mat_name];
561  if (geo_med == nullptr)
562  {
563  TGeoMaterial *geo_mat = createMaterial(iMaterial);
564  geo_med = new TGeoMedium(mat_name.c_str(), 0, geo_mat);
565  nameToMedium_[mat_name] = geo_med;
566  }
567  if (solid)
568  {
569  v = new TGeoVolume(iName.c_str(),
570  solid,
571  geo_med);
572  }
573  nameToVolume_[iName] = v;
574  }
575  return v;
576 }
577 
578 TGeoMaterial*
580 {
581  std::string mat_name = iMaterial.name().fullname();
582  TGeoMaterial *mat = nameToMaterial_[mat_name];
583 
584  if (mat == nullptr)
585  {
586  if (iMaterial.noOfConstituents() > 0)
587  {
588  TGeoMixture *mix = new TGeoMixture(mat_name.c_str(),
589  iMaterial.noOfConstituents(),
590  iMaterial.density()*cm3/g);
591  for (int i = 0; i < iMaterial.noOfConstituents(); ++i)
592  {
593  mix->AddElement(createMaterial(iMaterial.constituent(i).first),
594  iMaterial.constituent(i).second);
595  }
596  mat = mix;
597  }
598  else
599  {
600  mat = new TGeoMaterial(mat_name.c_str(),
601  iMaterial.a()*mole/g, iMaterial.z(),
602  iMaterial.density()*cm3/g);
603  }
604  nameToMaterial_[mat_name] = mat;
605  }
606 
607  return mat;
608 }
609 
610 //
611 // const member functions
612 //
613 
614 //
615 // static member functions
616 //
void watchPostBeginRun(PostBeginRun::slot_type const &iSlot)
dbl * delta
Definition: mlp_gen.cc:36
std::map< std::string, TGeoMaterial * > nameToMaterial_
double a() const
returns the atomic mass
Definition: DDMaterial.cc:93
TGeoManager * m_geoManager
const std::vector< double > & parameters(void) const
Give the parameters of the solid.
Definition: DDSolid.cc:144
static const TGPicture * info(bool iBackgroundIsBlack)
const N & name() const
Definition: DDBase.h:74
double y2(void) const
half length along y on +z
Definition: DDSolid.cc:247
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
def copy(args, dbName)
const edm::EventSetup * m_eventSetup
DDMaterial is used to define and access material information.
Definition: DDMaterial.h:43
TGeoVolume * createVolume(const std::string &iName, const DDSolid &iSolid, const DDMaterial &iMaterial)
#define nullptr
ROOT::Math::Rotation3D DDRotationMatrix
A DDRotationMatrix is currently implemented with a ROOT Rotation3D.
std::vector< double > yVec(void) const
Definition: DDSolid.cc:480
std::vector< double > zyVec(void) const
Definition: DDSolid.cc:501
DDTranslation translation(void) const
Definition: DDSolid.cc:604
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
A DDSolid represents the shape of a part.
Definition: DDSolid.h:39
double y1(void) const
half length along y on -z
Definition: DDSolid.cc:244
std::map< std::string, TGeoVolume * > nameToVolume_
DDSolid solidB(void) const
Definition: DDSolid.cc:616
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDTranslation.h:7
std::vector< double > xVec(void) const
Definition: DDSolid.cc:473
double z() const
retruns the atomic number
Definition: DDMaterial.cc:99
static const char *const name(DDSolidShape s)
Definition: DDSolidShapes.h:23
DDRotation rotation(void) const
Definition: DDSolid.cc:598
bool atMinusZ(void) const
true, if cut-out or rounding is on the -z side
Definition: DDSolid.cc:253
double halfZ(void) const
half of the z-Axis
Definition: DDSolid.cc:235
T sqrt(T t)
Definition: SSEVec.h:18
const std::string fullname() const
Definition: DDName.h:43
FractionV::value_type constituent(int i) const
returns the i-th compound material and its fraction-mass
Definition: DDMaterial.cc:87
DDSolidShape shape(void) const
The type of the solid.
Definition: DDSolid.cc:138
std::map< std::string, TGeoMedium * > nameToMedium_
void postBeginRun(const edm::Run &, const edm::EventSetup &)
DDSolid solidA(void) const
Definition: DDSolid.cc:610
TGeoFromDddService(const edm::ParameterSet &, edm::ActivityRegistry &)
const Graph & graph() const
Provides read-only access to the data structure of the compact-view.
std::vector< double > zVec(void) const
Definition: DDSolid.cc:487
std::vector< double > zxVec(void) const
Definition: DDSolid.cc:494
double density() const
returns the density
Definition: DDMaterial.cc:104
TGeoMaterial * createMaterial(const DDMaterial &iMaterial)
int noOfConstituents() const
returns the number of compound materials or 0 for elementary materials
Definition: DDMaterial.cc:82
TGeoManager * createManager(int level)
std::map< std::string, TGeoShape * > nameToShape_
HLT enums.
T get() const
Definition: EventSetup.h:71
const DDLogicalPart & root() const
returns the DDLogicalPart representing the root of the geometrical hierarchy
void watchPostEndRun(PostEndRun::slot_type const &iSlot)
double x2(void) const
half length along x on +z
Definition: DDSolid.cc:241
bool isValid() const
Definition: ESHandle.h:44
std::vector< double > zscaleVec(void) const
Definition: DDSolid.cc:508
value_type current() const
Definition: GraphWalker.h:93
const std::string & name() const
Returns the name.
Definition: DDName.cc:53
TGeoManager * getGeoManager()
void postEndRun(const edm::Run &, const edm::EventSetup &)
TGeoShape * createShape(const std::string &iName, const DDSolid &iSolid)
double x1(void) const
half length along x on -z
Definition: DDSolid.cc:238
Definition: Run.h:45
DDRotationMatrix & matrix()
Definition: DDTransform.h:97
double radius(void) const
radius of the cut-out (neg.) or rounding (pos.)
Definition: DDSolid.cc:250