CMS 3D CMS Logo

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