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 // $Id: TGeoFromDddService.cc,v 1.4 2010/08/24 07:12:00 yana Exp $
12 //
13 
14 // system include files
15 
16 // user include files
17 
19 
24 
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 
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 (0),
62  m_geoManager (0)
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 = 0;
101 }
102 
104 {
105  if (m_geoManager == 0)
106  {
107  if (m_eventSetup == 0)
108  edm::LogError("TGeoFromDddService") << "getGeoManager() -- EventSetup not present.\n";
109  else
110  {
112  if (m_geoManager == 0)
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 0;
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 == 0)
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 == 0)
182  {
183 
184  return 0;
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 0;
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 = (0 != nameToVolume_[info.first.name().fullname()]);
213  TGeoVolume *child = createVolume(info.first.name().fullname(),
214  info.first.solid(),
215  info.first.material());
216  if (0!=child && info.second != 0)
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 == 0 ) {
227  break;
228  }
229  }
230  if (0 == child || childAlreadyExists || level == int(parentStack.size()))
231  {
232  if (0!=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*
283 TGeoFromDddService::createShape(const std::string& iName,
284  const DDSolid& iSolid)
285 {
286  TGeoShape* rSolid= nameToShape_[iName];
287  if (rSolid == 0)
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[4]/deg);
321  break;
322  case ddtrap:
323  rSolid =new TGeoTrap(
324  iName.c_str(),
325  params[0]/cm, //dz
326  params[1]/deg, //theta
327  params[2]/deg, //phi
328  params[3]/cm, //dy1
329  params[4]/cm, //dx1
330  params[5]/cm, //dx2
331  params[6]/deg, //alpha1
332  params[7]/cm, //dy2
333  params[8]/cm, //dx3
334  params[9]/cm, //dx4
335  params[10]/deg);//alpha2
336  break;
337  case ddpolycone_rrz:
338  rSolid = new TGeoPcon(
339  iName.c_str(),
340  params[0]/deg,
341  params[1]/deg,
342  (params.size()-2)/3) ;
343  {
344  std::vector<double> temp(params.size()+1);
345  temp.reserve(params.size()+1);
346  temp[0]=params[0]/deg;
347  temp[1]=params[1]/deg;
348  temp[2]=(params.size()-2)/3;
349  std::copy(params.begin()+2,params.end(),temp.begin()+3);
350  for(std::vector<double>::iterator it=temp.begin()+3;
351  it != temp.end();
352  ++it) {
353  *it /=cm;
354  }
355  rSolid->SetDimensions(&(*(temp.begin())));
356  }
357  break;
358  case ddpolyhedra_rrz:
359  rSolid = new TGeoPgon(
360  iName.c_str(),
361  params[1]/deg,
362  params[2]/deg,
363  static_cast<int>(params[0]),
364  (params.size()-3)/3);
365  {
366  std::vector<double> temp(params.size()+1);
367  temp[0]=params[1]/deg;
368  temp[1]=params[2]/deg;
369  temp[2]=params[0];
370  temp[3]=(params.size()-3)/3;
371  std::copy(params.begin()+3,params.end(),temp.begin()+4);
372  for(std::vector<double>::iterator it=temp.begin()+4;
373  it != temp.end();
374  ++it) {
375  *it /=cm;
376  }
377  rSolid->SetDimensions(&(*(temp.begin())));
378  }
379  break;
380  case ddpseudotrap:
381  {
382  //implementation taken from SimG4Core/Geometry/src/DDG4SolidConverter.cc
383  static DDRotationMatrix s_rot(ROOT::Math::RotationX(90.*deg));
384  DDPseudoTrap pt(iSolid);
385  assert(pt.radius() < 0);
386  double x=0;
387  double r = fabs(pt.radius());
388  if( pt.atMinusZ()) {
389  x=pt.x1();
390  } else {
391  x=pt.x2();
392  }
393  double openingAngle = 2.0*asin(x/r);
394  double h=pt.y1()<pt.y2()? pt.y2() :pt.y1();
395  h+=h/20.;
396  double displacement=0;
397  double startPhi = 0;
398  double delta = sqrt((r+x)*(r-x));
399  if(pt.atMinusZ()) {
400  displacement=-pt.halfZ() - delta;
401  startPhi = 270.-openingAngle/deg/2.0;
402  }else {
403  displacement = pt.halfZ() + delta;
404  startPhi = 90. - openingAngle/deg/2.;
405  }
406  std::auto_ptr<TGeoShape> trap( new TGeoTrd2(pt.name().name().c_str(),
407  pt.x1()/cm,
408  pt.x2()/cm,
409  pt.y1()/cm,
410  pt.y2()/cm,
411  pt.halfZ()/cm) );
412  std::auto_ptr<TGeoShape> tubs( new TGeoTubeSeg(pt.name().name().c_str(),
413  0.,
414  r/cm,
415  h/cm,
416  startPhi,
417  openingAngle) );
418  TGeoSubtraction* sub = new TGeoSubtraction(trap.release(),
419  tubs.release(),
420  createPlacement(s_rot,
421  DDTranslation(0.,
422  0.,
423  displacement)));
424  rSolid = new TGeoCompositeShape(iName.c_str(),
425  sub);
426 
427 
428  break;
429  }
430  case ddsubtraction:
431  {
432  DDBooleanSolid boolSolid(iSolid);
433  if(!boolSolid) {
434  throw cms::Exception("GeomConvert") <<"conversion to DDBooleanSolid failed";
435  }
436 
437  std::auto_ptr<TGeoShape> left( createShape(boolSolid.solidA().name().fullname(),
438  boolSolid.solidA()) );
439  std::auto_ptr<TGeoShape> right( createShape(boolSolid.solidB().name().fullname(),
440  boolSolid.solidB()));
441  if( 0 != left.get() &&
442  0 != right.get() ) {
443  TGeoSubtraction* sub = new TGeoSubtraction(left.release(),right.release(),
444  gGeoIdentity,
445  createPlacement(
446  *(boolSolid.rotation().matrix()),
447  boolSolid.translation()));
448  rSolid = new TGeoCompositeShape(iName.c_str(),
449  sub);
450  }
451  break;
452  }
453  case ddunion:
454  {
455  DDBooleanSolid boolSolid(iSolid);
456  if(!boolSolid) {
457  throw cms::Exception("GeomConvert") <<"conversion to DDBooleanSolid failed";
458  }
459 
460  std::auto_ptr<TGeoShape> left( createShape(boolSolid.solidA().name().fullname(),
461  boolSolid.solidA()) );
462  std::auto_ptr<TGeoShape> right( createShape(boolSolid.solidB().name().fullname(),
463  boolSolid.solidB()));
464  //DEBUGGING
465  //break;
466  if( 0 != left.get() &&
467  0 != right.get() ) {
468  TGeoUnion* boolS = new TGeoUnion(left.release(),right.release(),
469  gGeoIdentity,
470  createPlacement(
471  *(boolSolid.rotation().matrix()),
472  boolSolid.translation()));
473  rSolid = new TGeoCompositeShape(iName.c_str(),
474  boolS);
475  }
476  break;
477  }
478  case ddintersection:
479  {
480  DDBooleanSolid boolSolid(iSolid);
481  if(!boolSolid) {
482  throw cms::Exception("GeomConvert") <<"conversion to DDBooleanSolid failed";
483  }
484 
485  std::auto_ptr<TGeoShape> left( createShape(boolSolid.solidA().name().fullname(),
486  boolSolid.solidA()) );
487  std::auto_ptr<TGeoShape> right( createShape(boolSolid.solidB().name().fullname(),
488  boolSolid.solidB()));
489  if( 0 != left.get() &&
490  0 != right.get() ) {
491  TGeoIntersection* boolS = new TGeoIntersection(left.release(),
492  right.release(),
493  gGeoIdentity,
494  createPlacement(
495  *(boolSolid.rotation().matrix()),
496  boolSolid.translation()));
497  rSolid = new TGeoCompositeShape(iName.c_str(),
498  boolS);
499  }
500  break;
501  }
502  default:
503  break;
504  }
505  nameToShape_[iName]=rSolid;
506  }
507  if (rSolid == 0)
508  {
509  std::cerr <<"COULD NOT MAKE "<<iName<<std::endl;
510  }
511  return rSolid;
512 }
513 
514 TGeoVolume*
515 TGeoFromDddService::createVolume(const std::string& iName,
516  const DDSolid& iSolid,
517  const DDMaterial& iMaterial)
518 {
519  TGeoVolume* v=nameToVolume_[iName];
520  if (v == 0)
521  {
522  TGeoShape* solid = createShape(iSolid.name().fullname(),
523  iSolid);
524  std::string mat_name = iMaterial.name().fullname();
525  TGeoMedium *geo_med = nameToMedium_[mat_name];
526  if (geo_med == 0)
527  {
528  TGeoMaterial *geo_mat = createMaterial(iMaterial);
529  geo_med = new TGeoMedium(mat_name.c_str(), 0, geo_mat);
530  nameToMedium_[mat_name] = geo_med;
531  }
532  if (solid)
533  {
534  v = new TGeoVolume(iName.c_str(),
535  solid,
536  geo_med);
537  }
538  nameToVolume_[iName] = v;
539  }
540  return v;
541 }
542 
543 TGeoMaterial*
545 {
546  std::string mat_name = iMaterial.name().fullname();
547  TGeoMaterial *mat = nameToMaterial_[mat_name];
548 
549  if (mat == 0)
550  {
551  if (iMaterial.noOfConstituents() > 0)
552  {
553  TGeoMixture *mix = new TGeoMixture(mat_name.c_str(),
554  iMaterial.noOfConstituents(),
555  iMaterial.density()*cm3/g);
556  for (int i = 0; i < iMaterial.noOfConstituents(); ++i)
557  {
558  mix->AddElement(createMaterial(iMaterial.constituent(i).first),
559  iMaterial.constituent(i).second);
560  }
561  mat = mix;
562  }
563  else
564  {
565  mat = new TGeoMaterial(mat_name.c_str(),
566  iMaterial.a()*mole/g, iMaterial.z(),
567  iMaterial.density()*cm3/g);
568  }
569  nameToMaterial_[mat_name] = mat;
570  }
571 
572  return mat;
573 }
574 
575 //
576 // const member functions
577 //
578 
579 //
580 // static member functions
581 //
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
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
DDRotation rotation(void) const
Definition: DDSolid.cc:535
graph< DDLogicalPart, DDPosData * >::value_type value_type
Definition: graphwalker.h:38
static const char * name(DDSolidShape s)
Definition: DDSolidShapes.h:21
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:46
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)
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
mathSSE::Vec4< T > v
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:33
double radius(void) const
radius of the cut-out (neg.) or rounding (pos.)
Definition: DDSolid.cc:238