CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
volumeHandle.cc
Go to the documentation of this file.
1 // #include "Utilities/Configuration/interface/Architecture.h"
2 
3 /*
4  * See header file for a description of this class.
5  *
6  * $Date: 2010/10/13 15:21:58 $
7  * $Revision: 1.14 $
8  * \author N. Amapane - INFN Torino
9  */
10 
17 
22 
23 #include "CLHEP/Units/GlobalSystemOfUnits.h"
24 
26 
27 #include <string>
28 #include <iterator>
29 #include <iomanip>
30 #include <iostream>
31 
32 using namespace SurfaceOrientation;
33 using namespace std;
34 
35 
37  delete refPlane;
38 }
39 
41  : name(fv.logicalPart().name().name()),
42  copyno(fv.copyno()),
43  magVolume(0),
44  masterSector(1),
45  theRN(0.),
46  theRMin(0.),
47  theRMax(0.),
48  refPlane(0),
49  solid(fv.logicalPart().solid()),
50  center_(GlobalPoint(fv.translation().x()/cm,
51  fv.translation().y()/cm,
52  fv.translation().z()/cm)),
53  expand(expand2Pi),
54  isIronFlag(false)
55 {
56  for (int i=0; i<6; ++i) {
57  isAssigned[i] = false;
58  }
59 
60 
62  cout.precision(7);
63  }
64 
65 
66  referencePlane(fv);
67 
68  if (solid.shape() == ddbox) {
69  buildBox(fv);
70  } else if (solid.shape() == ddtrap) {
71  buildTrap(fv);
72  } else if (solid.shape() == ddcons) {
73  buildCons(fv);
74  } else if (solid.shape() == ddtubs) {
75  buildTubs(fv);
76  } else if (solid.shape() == ddpseudotrap) {
77  buildPseudoTrap(fv);
78  } else if (solid.shape() == ddtrunctubs) {
79  buildTruncTubs(fv);
80  } else {
81  cout << "volumeHandle ctor: Unexpected solid: " << (int) solid.shape() << endl;
82  }
83 
84 
86 
87  { // Extract the name of associated field file.
88  std::vector<std::string> temp;
89  std::string pname = "table";
90  DDValue val(pname);
92  if (DDfetch(&sv,val)) {
93  temp = val.strings();
94  if (temp.size() != 1) {
95  cout << "*** WARNING: volume has > 1 SpecPar " << pname << endl;
96  }
97  magFile = temp[0];
98 
99  string find="[copyNo]";
100  std::size_t j;
101  for ( ; (j = magFile.find(find)) != string::npos ; ) {
102  stringstream conv;
103  conv << setfill('0') << setw(2) << copyno;
104  string repl;
105  conv >> repl;
106  magFile.replace(j, find.length(), repl);
107  }
108 
109  } else {
110  cout << "*** WARNING: volume does not have a SpecPar " << pname << endl;
111  cout << " DDsvalues_type: " << fv.mergedSpecifics() << endl;
112  }
113  }
114 
115  { // Extract the number of the master sector.
116  std::vector<double> temp;
117  const std::string pname = "masterSector";
118  DDValue val(pname);
119  if (DDfetch(&sv,val)) {
120  temp = val.doubles();
121  if (temp.size() != 1) {
122  cout << "*** WARNING: volume has > 1 SpecPar " << pname << endl;
123  }
124  masterSector = int(temp[0]+.5);
125  } else {
127  cout << "Volume does not have a SpecPar " << pname
128  << " using: " << copyno << endl;
129  cout << " DDsvalues_type: " << fv.mergedSpecifics() << endl;
130  }
132  }
133  }
134 
135  // Get material for this volume
136  if (fv.logicalPart().material().name().name() == "Iron") isIronFlag=true;
137 
138 
140  cout << " RMin = " << theRMin <<endl;
141  cout << " RMax = " << theRMax <<endl;
142 
143  if (theRMin < 0 || theRN < theRMin || theRMax < theRN)
144  cout << "*** WARNING: wrong RMin/RN/RMax , shape: " << (int) shape() << endl;
145 
146  cout << "Summary: " << name << " " << copyno
147  << " Shape= " << (int) shape()
148  << " trasl " << center()
149  << " R " << center().perp()
150  << " phi " << center().phi()
151  << " magFile " << magFile
152  << " Material= " << fv.logicalPart().material().name()
153  << " isIron= " << isIronFlag
154  << " masterSector= " << masterSector << std::endl;
155 
156  cout << " Orientation of surfaces:";
157  std::string sideName[3] = {"positiveSide", "negativeSide", "onSurface"};
158  for (int i=0; i<6; ++i) {
159  cout << " " << i << ":" << sideName[surfaces[i]->side(center_,0.3)];
160  }
161  cout << endl;
162  }
163 }
164 
165 
167  return center_;
168 }
169 
171  // The refPlane is the "main plane" for the solid. It corresponds to the
172  // x,y plane in the DDD local frame, and defines a frame where the local
173  // coordinates are the same as in DDD.
174  // In the geometry version 85l_030919, this plane is normal to the
175  // beam line for all volumes but pseudotraps, so that global R is along Y,
176  // global phi is along -X and global Z along Z:
177  //
178  // Global(for vol at pi/2) Local
179  // +R (+Y) +Y
180  // +phi(-X) -X
181  // +Z +Z
182  //
183  // For pseudotraps the refPlane is parallel to beam line and global R is
184  // along Z, global phi is along +-X and and global Z along Y:
185  //
186  // Global(for vol at pi/2) Local
187  // +R (+Y) +Z
188  // +phi(-X) +X
189  // +Z +Y
190  //
191  // Note that the frame is centered in the DDD volume center, which is
192  // inside the volume for DDD boxes and (pesudo)trapezoids, on the beam line
193  // for tubs, cons and trunctubs.
194 
195  // In geometry version 1103l, trapezoids have X and Z in the opposite direction
196  // than the above. Boxes are either oriented as described above or in some case
197  // have opposite direction for Y and X.
198 
199  // The global position
200  Surface::PositionType & posResult = center_;
201 
202  // The reference plane rotation
203  DD3Vector x, y, z;
204  fv.rotation().GetComponents(x,y,z);
206  if (x.Cross(y).Dot(z) < 0.5) {
207  cout << "*** WARNING: Rotation is not RH "<< endl;
208  }
209  }
210 
211  // The global rotation
213  rotResult(float(x.X()),float(x.Y()),float(x.Z()),
214  float(y.X()),float(y.Y()),float(y.Z()),
215  float(z.X()),float(z.Y()),float(z.Z()));
216 
217  refPlane = new GloballyPositioned<float>(posResult, rotResult);
218 
219  // Check correct orientation
221 
222  cout << "Refplane pos " << refPlane->position() << endl;
223 
224  // See comments above for the conventions for orientation.
225  LocalVector globalZdir(0.,0.,1.); // Local direction of the axis along global Z
226  if (solid.shape() == ddpseudotrap) {
227  globalZdir = LocalVector(0.,1.,0.);
228  }
229  if (refPlane->toGlobal(globalZdir).z()<0.) {
230  globalZdir=-globalZdir;
231  }
232 
233  float chk = refPlane->toGlobal(globalZdir).dot(GlobalVector(0,0,1));
234  if (chk < .999) cout << "*** WARNING RefPlane check failed!***"
235  << chk << endl;
236  }
237 }
238 
239 
240 
242  double deltaPhi,
243  double zhalf,
244  double rCentr) {
245  // This is 100% equal for cons and tubs!!!
246 
247  GlobalVector planeXAxis = refPlane->toGlobal(LocalVector( 1, 0, 0));
248  GlobalVector planeYAxis = refPlane->toGlobal(LocalVector( 0, 1, 0));
249  GlobalVector planeZAxis = refPlane->toGlobal(LocalVector( 0, 0, 1));
250 
251  // Local Y axis of the faces at +-phi.
252  GlobalVector y_phiplus = refPlane->toGlobal(LocalVector(cos(startPhi+deltaPhi),
253  sin(startPhi+deltaPhi),0.));
254  GlobalVector y_phiminus = refPlane->toGlobal(LocalVector(cos(startPhi),
255  sin(startPhi),0.));
256 
257  Surface::RotationType rot_Z(planeXAxis,planeYAxis);
258  Surface::RotationType rot_phiplus(planeZAxis, y_phiplus);
259  Surface::RotationType rot_phiminus(planeZAxis, y_phiminus);
260 
261  GlobalPoint pos_zplus(center_.x(),center_.y(),center_.z()+zhalf);
262  GlobalPoint pos_zminus(center_.x(),center_.y(),center_.z()-zhalf);
263  // BEWARE: in this case, the origin for phiplus,phiminus surfaces is
264  // at radius R and not on a plane passing by center_ orthogonal to the radius.
265  GlobalPoint pos_phiplus(refPlane->toGlobal(LocalPoint(rCentr*cos(startPhi+deltaPhi),rCentr*sin(startPhi+deltaPhi),0.)));
266  GlobalPoint pos_phiminus(refPlane->toGlobal(LocalPoint(rCentr*cos(startPhi),
267  rCentr*sin(startPhi),
268  0.)));
269  surfaces[zplus] = new Plane(pos_zplus, rot_Z);
270  surfaces[zminus] = new Plane(pos_zminus, rot_Z);
271  surfaces[phiplus] = new Plane(pos_phiplus, rot_phiplus);
272  surfaces[phiminus] = new Plane(pos_phiminus, rot_phiminus);
273 
275  cout << "Actual Center at: " << center_ << " R " << center_.perp()
276  << " phi " << center_.phi() << endl;
277  cout << "RN " << theRN << endl;
278 
279  cout << "pos_zplus " << pos_zplus << " "
280  << pos_zplus.perp() << " " << pos_zplus.phi() << endl
281  << "pos_zminus " << pos_zminus << " "
282  << pos_zminus.perp() << " " << pos_zminus.phi() << endl
283  << "pos_phiplus " << pos_phiplus << " "
284  << pos_phiplus.perp() << " " << pos_phiplus.phi() <<endl
285  << "pos_phiminus " << pos_phiminus << " "
286  << pos_phiminus.perp() << " " << pos_phiminus.phi() <<endl;
287 
288  cout << "y_phiplus " << y_phiplus << endl;
289  cout << "y_phiminus " << y_phiminus << endl;
290 
291  cout << "rot_Z " << surfaces[zplus]->toGlobal(LocalVector(0.,0.,1.)) << endl
292  << "rot_phi+ " << surfaces[phiplus]->toGlobal(LocalVector(0.,0.,1.))
293  << " phi " << surfaces[phiplus]->toGlobal(LocalVector(0.,0.,1.)).phi()
294  << endl
295  << "rot_phi- " << surfaces[phiminus]->toGlobal(LocalVector(0.,0.,1.))
296  << " phi " << surfaces[phiminus]->toGlobal(LocalVector(0.,0.,1.)).phi()
297  << endl;
298  }
299 
300 // // Check ordering.
302  if (pos_zplus.z() < pos_zminus.z()) {
303  cout << "*** WARNING: pos_zplus < pos_zminus " << endl;
304  }
305  if (Geom::Phi<float>(pos_phiplus.phi()-pos_phiminus.phi()) < 0. ) {
306  cout << "*** WARNING: pos_phiplus < pos_phiminus " << endl;
307  }
308  }
309 }
310 
311 
312 
313 bool MagGeoBuilderFromDDD::volumeHandle::sameSurface(const Surface & s1, Sides which_side, float tolerance)
314 {
315  //Check for null comparison
316  if (&s1==(surfaces[which_side]).get()){
317  if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: OK (same ptr)" << endl;
318  return true;
319  }
320 
321  const float maxtilt = 0.999;
322 
323  const Surface & s2 = *(surfaces[which_side]);
324  // Try with a plane.
325  const Plane * p1 = dynamic_cast<const Plane*>(&s1);
326  if (p1!=0) {
327  const Plane * p2 = dynamic_cast<const Plane*>(&s2);
328  if (p2==0) {
329  if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: different types" << endl;
330  return false;
331  }
332 
333  if ( (fabs(p1->normalVector().dot(p2->normalVector())) > maxtilt)
334  && (fabs((p1->toLocal(p2->position())).z()) < tolerance) ) {
335  if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: OK "
336  << fabs(p1->normalVector().dot(p2->normalVector()))
337  << " " << fabs((p1->toLocal(p2->position())).z()) << endl;
338  return true;
339  } else{
340  if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: not the same: "
341  << p1->normalVector() << p1->position() << endl
342  << " "
343  << p2->normalVector() << p2->position() << endl
344  << fabs(p1->normalVector().dot(p2->normalVector()))
345  << " " << (p1->toLocal(p2->position())).z()<< endl;
346  return false;
347  }
348  }
349 
350  // Try with a cylinder.
351  const Cylinder * cy1 = dynamic_cast<const Cylinder*>(&s1);
352  if (cy1!=0) {
353  const Cylinder * cy2 = dynamic_cast<const Cylinder*>(&s2);
354  if (cy2==0) {
355  if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: different types" << endl;
356  return false;
357  }
358  // Assume axis is the same!
359  if (fabs(cy1->radius() - cy2->radius()) < tolerance) {
360  return true;
361  } else {
362  return false;
363  }
364  }
365 
366  // Try with a cone.
367  const Cone * co1 = dynamic_cast<const Cone*>(&s1);
368  if (co1!=0) {
369  const Cone * co2 = dynamic_cast<const Cone*>(&s2);
370  if (co2==0) {
371  if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: different types" << endl;
372  return false;
373  }
374  // FIXME
375  if (fabs(co1->openingAngle()-co2->openingAngle()) < maxtilt
376  && (co1->vertex()-co2->vertex()).mag() < tolerance) {
377  return true;
378  } else {
379  return false;
380  }
381  }
382 
383  if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: unknown surfaces..." << endl;
384  return false;
385 }
386 
387 
388 
390 {
391  //Check for null assignment
392  if (&s1==(surfaces[which_side]).get()){
393  isAssigned[which_side] = true;
394  return true;
395  }
396 
397  if (!sameSurface(s1,which_side)){
398  cout << "***ERROR: setSurface: trying to assign a surface that does not match destination surface. Skipping." << endl;
399  const Surface & s2 = *(surfaces[which_side]);
400  //FIXME: Just planes for the time being!!!
401  const Plane * p1 = dynamic_cast<const Plane*>(&s1);
402  const Plane * p2 = dynamic_cast<const Plane*>(&s2);
403  if (p1!=0 && p2 !=0)
404  cout << p1->normalVector() << p1->position() << endl
405  << p2->normalVector() << p2->position() << endl;
406  return false;
407  }
408 
409 
410  if (isAssigned[which_side]) {
411  if (&s1!=(surfaces[which_side]).get()){
412  cout << "*** WARNING volumeHandle::setSurface: trying to reassign a surface to a different surface instance" << endl;
413  return false;
414  }
415  } else {
416  surfaces[which_side] = &s1;
417  isAssigned[which_side] = true;
418  if (MagGeoBuilderFromDDD::debug) cout << " Volume " << name << " # " << copyno << " Assigned: " << (int) which_side << endl;
419  return true;
420  }
421 
422  return false; // let the compiler be happy
423 }
424 
425 
426 
427 const Surface &
429  return *(surfaces[which_side]);
430 }
431 
432 
433 
434 const Surface &
436  assert(which_side >=0 && which_side <6);
437  return *(surfaces[which_side]);
438 }
439 
440 
441 std::vector<VolumeSide>
443  std::vector<VolumeSide> result;
444  for (int i=0; i<6; ++i){
445  // If this is just a master volume out of wich a 2pi volume
446  // should be built (e.g. central cylinder), skip the phi boundaries.
447  if (expand && (i==phiplus || i==phiminus)) continue;
448 
449  // FIXME: Skip null inner degenerate cylindrical surface
450  if (solid.shape() == ddtubs && i == SurfaceOrientation::inner && theRMin < 0.001) continue;
451 
452  ReferenceCountingPointer<Surface> s = const_cast<Surface*> (surfaces[i].get());
453  result.push_back(VolumeSide(s, GlobalFace(i),
454  surfaces[i]->side(center_,0.3)));
455  }
456  return result;
457 }
458 
459 void MagGeoBuilderFromDDD::volumeHandle::printUniqueNames(handles::const_iterator begin, handles::const_iterator end ) {
460  std::vector<std::string> names;
461  for (handles::const_iterator i = begin;
462  i != end; ++i){
463  names.push_back((*i)->name);
464  }
465 
466  sort(names.begin(),names.end());
467  std::vector<std::string>::iterator i = unique(names.begin(),names.end());
468  int nvols = int(i - names.begin());
469  cout << nvols << " ";
470  copy(names.begin(), i, ostream_iterator<std::string>(cout, " "));
471 
472  cout << endl;
473 }
474 
475 
476 #include "MagneticField/GeomBuilder/src/buildBox.icc"
477 #include "MagneticField/GeomBuilder/src/buildTrap.icc"
478 #include "MagneticField/GeomBuilder/src/buildTubs.icc"
479 #include "MagneticField/GeomBuilder/src/buildCons.icc"
480 #include "MagneticField/GeomBuilder/src/buildPseudoTrap.icc"
481 #include "MagneticField/GeomBuilder/src/buildTruncTubs.icc"
int i
Definition: DBlmapReader.cc:9
void buildBox(const DDExpandedView &fv)
const DDRotationMatrix & rotation() const
The absolute rotation of the current node.
Definition: Cone.h:20
const std::vector< double > & doubles() const
a reference to the double-valued values stored in the given instance of DDValue
Definition: DDValue.cc:134
Local3DVector LocalVector
Definition: LocalVector.h:12
DDsvalues_type mergedSpecifics() const
void buildPhiZSurf(double startPhi, double deltaPhi, double zhalf, double rCentr)
const N & name() const
Definition: DDBase.h:82
T perp() const
Definition: PV3DBase.h:71
static HepMC::IO_HEPEVT conv
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
void buildTubs(const DDExpandedView &fv)
GlobalVector normalVector() const
Definition: Plane.h:47
std::vector< VolumeSide > sides() const
The surfaces and they orientation, as required to build a MagVolume.
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Geom::Phi< T > phi() const
Definition: PV3DBase.h:68
void buildPseudoTrap(const DDExpandedView &fv)
const GlobalPoint & center() const
Return the center of the volume.
PreciseFloatType< T, U >::Type dot(const Vector3DBase< U, FrameTag > &v) const
Definition: Vector3DBase.h:107
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
static void printUniqueNames(handles::const_iterator begin, handles::const_iterator end)
Just for debugging...
std::string name
Name of the volume.
Definition: volumeHandle.h:58
DDSolidShape shape() const
Shape of the solid.
Definition: volumeHandle.h:97
bool DDfetch(const DDsvalues_type *, DDValue &)
helper for retrieving DDValues from DDsvalues_type *.
Definition: DDsvalues.cc:102
Definition: Plane.h:17
double double double z
tuple s2
Definition: indexGen.py:106
GlobalPoint vertex() const
Global position of the cone vertex.
Definition: Cone.h:50
Scalar radius() const
Radius of the cylinder.
Definition: Cylinder.h:55
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DD3Vector
A DD Translation is currently implemented with Root Vector3D.
Definition: DDTranslation.h:6
LocalPoint toLocal(const GlobalPoint &gp) const
T z() const
Definition: PV3DBase.h:63
tuple result
Definition: query.py:137
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
std::vector< std::pair< unsigned int, DDValue > > DDsvalues_type
std::maps an index to a DDValue. The index corresponds to the index assigned to the name of the std::...
Definition: DDsvalues.h:19
int j
Definition: DBlmapReader.cc:9
std::string magFile
Name of magnetic field table file.
Definition: volumeHandle.h:60
DDSolidShape shape(void) const
The type of the solid.
Definition: DDSolid.cc:144
void buildCons(const DDExpandedView &fv)
#define end
Definition: vmac.h:38
void referencePlane(const DDExpandedView &fv)
double p2[4]
Definition: TauolaWrapper.h:90
volumeHandle(const DDExpandedView &fv, bool expand2Pi=false)
Definition: volumeHandle.cc:40
const std::vector< std::string > & strings() const
a reference to the std::string-valued values stored in the given instance of DDValue ...
Definition: DDValue.h:71
const Surface & surface(int which_side) const
Get the current surface on specified side.
#define begin
Definition: vmac.h:31
double p1[4]
Definition: TauolaWrapper.h:89
void buildTrap(const DDExpandedView &fv)
int masterSector
The sector for which an interpolator for this class of volumes should be built.
Definition: volumeHandle.h:111
tuple cout
Definition: gather_cfg.py:121
const DDLogicalPart & logicalPart() const
The logical-part of the current node in the expanded-view.
Definition: DDAxes.h:10
const PositionType & position() const
Provides an exploded view of the detector (tree-view)
static const HistoName names[]
bool setSurface(const Surface &s1, Sides which_side)
Assign a shared surface perorming sanity checks.
bool sameSurface(const Surface &s1, Sides which_side, float tolerance=0.01)
Find out if two surfaces are the same physical surface.
const std::string & name() const
Returns the name.
Definition: DDName.cc:87
const DDMaterial & material(void) const
Returns a reference object of the material this LogicalPart is made of.
Global3DVector GlobalVector
Definition: GlobalVector.h:10
Geom::Theta< float > openingAngle() const
Angle of the cone.
Definition: Cone.h:53
void buildTruncTubs(const DDExpandedView &fv)