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[4]/deg);
320  break;
321  case ddtrap:
322  rSolid =new TGeoTrap(
323  iName.c_str(),
324  params[0]/cm, //dz
325  params[1]/deg, //theta
326  params[2]/deg, //phi
327  params[3]/cm, //dy1
328  params[4]/cm, //dx1
329  params[5]/cm, //dx2
330  params[6]/deg, //alpha1
331  params[7]/cm, //dy2
332  params[8]/cm, //dx3
333  params[9]/cm, //dx4
334  params[10]/deg);//alpha2
335  break;
336  case ddpolycone_rrz:
337  rSolid = new TGeoPcon(
338  iName.c_str(),
339  params[0]/deg,
340  params[1]/deg,
341  (params.size()-2)/3) ;
342  {
343  std::vector<double> temp(params.size()+1);
344  temp.reserve(params.size()+1);
345  temp[0]=params[0]/deg;
346  temp[1]=params[1]/deg;
347  temp[2]=(params.size()-2)/3;
348  std::copy(params.begin()+2,params.end(),temp.begin()+3);
349  for(std::vector<double>::iterator it=temp.begin()+3;
350  it != temp.end();
351  ++it) {
352  *it /=cm;
353  }
354  rSolid->SetDimensions(&(*(temp.begin())));
355  }
356  break;
357  case ddpolyhedra_rrz:
358  rSolid = new TGeoPgon(
359  iName.c_str(),
360  params[1]/deg,
361  params[2]/deg,
362  static_cast<int>(params[0]),
363  (params.size()-3)/3);
364  {
365  std::vector<double> temp(params.size()+1);
366  temp[0]=params[1]/deg;
367  temp[1]=params[2]/deg;
368  temp[2]=params[0];
369  temp[3]=(params.size()-3)/3;
370  std::copy(params.begin()+3,params.end(),temp.begin()+4);
371  for(std::vector<double>::iterator it=temp.begin()+4;
372  it != temp.end();
373  ++it) {
374  *it /=cm;
375  }
376  rSolid->SetDimensions(&(*(temp.begin())));
377  }
378  break;
379  case ddpseudotrap:
380  {
381  //implementation taken from SimG4Core/Geometry/src/DDG4SolidConverter.cc
382  const static DDRotationMatrix s_rot(ROOT::Math::RotationX(90.*deg));
383  DDPseudoTrap pt(iSolid);
384  assert(pt.radius() < 0);
385  double x=0;
386  double r = fabs(pt.radius());
387  if( pt.atMinusZ()) {
388  x=pt.x1();
389  } else {
390  x=pt.x2();
391  }
392  double openingAngle = 2.0*asin(x/r);
393  double h=pt.y1()<pt.y2()? pt.y2() :pt.y1();
394  h+=h/20.;
395  double displacement=0;
396  double startPhi = 0;
397  double delta = sqrt((r+x)*(r-x));
398  if(pt.atMinusZ()) {
399  displacement=-pt.halfZ() - delta;
400  startPhi = 270.-openingAngle/deg/2.0;
401  }else {
402  displacement = pt.halfZ() + delta;
403  startPhi = 90. - openingAngle/deg/2.;
404  }
405  std::auto_ptr<TGeoShape> trap( new TGeoTrd2(pt.name().name().c_str(),
406  pt.x1()/cm,
407  pt.x2()/cm,
408  pt.y1()/cm,
409  pt.y2()/cm,
410  pt.halfZ()/cm) );
411  std::auto_ptr<TGeoShape> tubs( new TGeoTubeSeg(pt.name().name().c_str(),
412  0.,
413  r/cm,
414  h/cm,
415  startPhi,
416  openingAngle) );
417  TGeoSubtraction* sub = new TGeoSubtraction(trap.release(),
418  tubs.release(),
419  createPlacement(s_rot,
420  DDTranslation(0.,
421  0.,
422  displacement)));
423  rSolid = new TGeoCompositeShape(iName.c_str(),
424  sub);
425 
426 
427  break;
428  }
429  case ddsubtraction:
430  {
431  DDBooleanSolid boolSolid(iSolid);
432  if(!boolSolid) {
433  throw cms::Exception("GeomConvert") <<"conversion to DDBooleanSolid failed";
434  }
435 
436  std::auto_ptr<TGeoShape> left( createShape(boolSolid.solidA().name().fullname(),
437  boolSolid.solidA()) );
438  std::auto_ptr<TGeoShape> right( createShape(boolSolid.solidB().name().fullname(),
439  boolSolid.solidB()));
440  if( 0 != left.get() &&
441  0 != right.get() ) {
442  TGeoSubtraction* sub = new TGeoSubtraction(left.release(),right.release(),
443  gGeoIdentity,
444  createPlacement(
445  *(boolSolid.rotation().matrix()),
446  boolSolid.translation()));
447  rSolid = new TGeoCompositeShape(iName.c_str(),
448  sub);
449  }
450  break;
451  }
452  case ddunion:
453  {
454  DDBooleanSolid boolSolid(iSolid);
455  if(!boolSolid) {
456  throw cms::Exception("GeomConvert") <<"conversion to DDBooleanSolid failed";
457  }
458 
459  std::auto_ptr<TGeoShape> left( createShape(boolSolid.solidA().name().fullname(),
460  boolSolid.solidA()) );
461  std::auto_ptr<TGeoShape> right( createShape(boolSolid.solidB().name().fullname(),
462  boolSolid.solidB()));
463  //DEBUGGING
464  //break;
465  if( 0 != left.get() &&
466  0 != right.get() ) {
467  TGeoUnion* boolS = new TGeoUnion(left.release(),right.release(),
468  gGeoIdentity,
469  createPlacement(
470  *(boolSolid.rotation().matrix()),
471  boolSolid.translation()));
472  rSolid = new TGeoCompositeShape(iName.c_str(),
473  boolS);
474  }
475  break;
476  }
477  case ddintersection:
478  {
479  DDBooleanSolid boolSolid(iSolid);
480  if(!boolSolid) {
481  throw cms::Exception("GeomConvert") <<"conversion to DDBooleanSolid failed";
482  }
483 
484  std::auto_ptr<TGeoShape> left( createShape(boolSolid.solidA().name().fullname(),
485  boolSolid.solidA()) );
486  std::auto_ptr<TGeoShape> right( createShape(boolSolid.solidB().name().fullname(),
487  boolSolid.solidB()));
488  if( 0 != left.get() &&
489  0 != right.get() ) {
490  TGeoIntersection* boolS = new TGeoIntersection(left.release(),
491  right.release(),
492  gGeoIdentity,
493  createPlacement(
494  *(boolSolid.rotation().matrix()),
495  boolSolid.translation()));
496  rSolid = new TGeoCompositeShape(iName.c_str(),
497  boolS);
498  }
499  break;
500  }
501  default:
502  break;
503  }
504  nameToShape_[iName]=rSolid;
505  }
506  if (rSolid == 0)
507  {
508  std::cerr <<"COULD NOT MAKE "<<iName<<std::endl;
509  }
510  return rSolid;
511 }
512 
513 TGeoVolume*
515  const DDSolid& iSolid,
516  const DDMaterial& iMaterial)
517 {
518  TGeoVolume* v=nameToVolume_[iName];
519  if (v == 0)
520  {
521  TGeoShape* solid = createShape(iSolid.name().fullname(),
522  iSolid);
523  std::string mat_name = iMaterial.name().fullname();
524  TGeoMedium *geo_med = nameToMedium_[mat_name];
525  if (geo_med == 0)
526  {
527  TGeoMaterial *geo_mat = createMaterial(iMaterial);
528  geo_med = new TGeoMedium(mat_name.c_str(), 0, geo_mat);
529  nameToMedium_[mat_name] = geo_med;
530  }
531  if (solid)
532  {
533  v = new TGeoVolume(iName.c_str(),
534  solid,
535  geo_med);
536  }
537  nameToVolume_[iName] = v;
538  }
539  return v;
540 }
541 
542 TGeoMaterial*
544 {
545  std::string mat_name = iMaterial.name().fullname();
546  TGeoMaterial *mat = nameToMaterial_[mat_name];
547 
548  if (mat == 0)
549  {
550  if (iMaterial.noOfConstituents() > 0)
551  {
552  TGeoMixture *mix = new TGeoMixture(mat_name.c_str(),
553  iMaterial.noOfConstituents(),
554  iMaterial.density()*cm3/g);
555  for (int i = 0; i < iMaterial.noOfConstituents(); ++i)
556  {
557  mix->AddElement(createMaterial(iMaterial.constituent(i).first),
558  iMaterial.constituent(i).second);
559  }
560  mat = mix;
561  }
562  else
563  {
564  mat = new TGeoMaterial(mat_name.c_str(),
565  iMaterial.a()*mole/g, iMaterial.z(),
566  iMaterial.density()*cm3/g);
567  }
568  nameToMaterial_[mat_name] = mat;
569  }
570 
571  return mat;
572 }
573 
574 //
575 // const member functions
576 //
577 
578 //
579 // static member functions
580 //
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:150
static const TGPicture * info(bool iBackgroundIsBlack)
const N & name() const
Definition: DDBase.h:82
double y2(void) const
half length along y on +z
Definition: DDSolid.cc:236
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)
list elements
Definition: asciidump.py:414
DDTranslation translation(void) const
Definition: DDSolid.cc:540
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:35
double y1(void) const
half length along y on -z
Definition: DDSolid.cc:234
std::map< std::string, TGeoVolume * > nameToVolume_
DDSolid solidB(void) const
Definition: DDSolid.cc:550
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDTranslation.h:7
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:535
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:240
double halfZ(void) const
half of the z-Axis
Definition: DDSolid.cc:228
T sqrt(T t)
Definition: SSEVec.h:48
const std::string fullname() const
Definition: DDName.h:56
FractionV::value_type constituent(int i) const
returns the i-th compound material and its fraction-mass
Definition: DDMaterial.cc:89
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:545
TGeoFromDddService(const edm::ParameterSet &, edm::ActivityRegistry &)
double density() const
returns the density
Definition: DDMaterial.cc:109
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
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:83
TGeoManager * createManager(int level)
std::map< std::string, TGeoShape * > nameToShape_
tuple cout
Definition: gather_cfg.py:121
tuple level
Definition: testEve_cfg.py:34
void watchPostEndRun(PostEndRun::slot_type const &iSlot)
volatile std::atomic< bool > shutdown_flag false
Definition: DDAxes.h:10
DDRotationMatrix * matrix()
Definition: DDTransform.h:94
double x2(void) const
half length along x on +z
Definition: DDSolid.cc:232
ROOT::Math::Rotation3D DDRotationMatrix
A DDRotationMatrix is currently implemented with a ROOT Rotation3D.
const std::string & name() const
Returns the name.
Definition: DDName.cc:87
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:230
Definition: Run.h:41
double radius(void) const
radius of the cut-out (neg.) or rounding (pos.)
Definition: DDSolid.cc:238