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