CMS 3D CMS Logo

volumeHandle.cc
Go to the documentation of this file.
1 /*
2  * See header file for a description of this class.
3  *
4  * \author N. Amapane - INFN Torino (original developer)
5  */
6 
7 #include "volumeHandle.h"
13 
18 
19 #include "CLHEP/Units/GlobalSystemOfUnits.h"
20 
22 
23 #include <string>
24 #include <iterator>
25 #include <iomanip>
26 #include <iostream>
27 #include <boost/lexical_cast.hpp>
28 
29 using namespace SurfaceOrientation;
30 using namespace std;
31 
32 MagGeoBuilderFromDDD::volumeHandle::volumeHandle(const DDExpandedView &fv, bool expand2Pi, bool debugVal)
33  : magneticfield::BaseVolumeHandle(expand2Pi, debugVal) {
34  name = fv.logicalPart().name().name();
35  copyno = fv.copyno();
36  solid = fv.logicalPart().solid();
37  center_ = GlobalPoint(fv.translation().x() / cm, fv.translation().y() / cm, fv.translation().z() / cm);
38 
39  // ASSUMPTION: volume names ends with "_NUM" where NUM is the volume number
40  string volName = name;
41  volName.erase(0, volName.rfind('_') + 1);
42  volumeno = boost::lexical_cast<unsigned short>(volName);
43 
44  for (int i = 0; i < 6; ++i) {
45  isAssigned[i] = false;
46  }
47 
48  if (debug) {
49  cout.precision(7);
50  }
51 
52  referencePlane(fv);
53 
54  if (solid.shape() == DDSolidShape::ddbox) {
55  buildBox();
56  } else if (solid.shape() == DDSolidShape::ddtrap) {
57  buildTrap();
58  } else if (solid.shape() == DDSolidShape::ddcons) {
59  buildCons();
60  } else if (solid.shape() == DDSolidShape::ddtubs) {
61  buildTubs();
62  } else if (solid.shape() == DDSolidShape::ddpseudotrap) {
64  } else if (solid.shape() == DDSolidShape::ddtrunctubs) {
66  } else {
67  cout << "volumeHandle ctor: Unexpected solid: " << DDSolidShapesName::name(solid.shape()) << endl;
68  }
69 
70  // NOTE: Table name and master sector are no longer taken from xml!
71  // DDsvalues_type sv(fv.mergedSpecifics());
72 
73  // { // Extract the name of associated field file.
74  // std::vector<std::string> temp;
75  // std::string pname = "table";
76  // DDValue val(pname);
77  // DDsvalues_type sv(fv.mergedSpecifics());
78  // if (DDfetch(&sv,val)) {
79  // temp = val.strings();
80  // if (temp.size() != 1) {
81  // cout << "*** WARNING: volume has > 1 SpecPar " << pname << endl;
82  // }
83  // magFile = temp[0];
84 
85  // string find="[copyNo]";
86  // std::size_t j;
87  // for ( ; (j = magFile.find(find)) != string::npos ; ) {
88  // stringstream conv;
89  // conv << setfill('0') << setw(2) << copyno;
90  // string repl;
91  // conv >> repl;
92  // magFile.replace(j, find.length(), repl);
93  // }
94 
95  // } else {
96  // cout << "*** WARNING: volume does not have a SpecPar " << pname << endl;
97  // cout << " DDsvalues_type: " << fv.mergedSpecifics() << endl;
98  // }
99  // }
100 
101  // { // Extract the number of the master sector.
102  // std::vector<double> temp;
103  // const std::string pname = "masterSector";
104  // DDValue val(pname);
105  // if (DDfetch(&sv,val)) {
106  // temp = val.doubles();
107  // if (temp.size() != 1) {
108  // cout << "*** WARNING: volume has > 1 SpecPar " << pname << endl;
109  // }
110  // masterSector = int(temp[0]+.5);
111  // } else {
112  // if (MagGeoBuilderFromDDD::debug) {
113  // cout << "Volume does not have a SpecPar " << pname
114  // << " using: " << copyno << endl;
115  // cout << " DDsvalues_type: " << fv.mergedSpecifics() << endl;
116  // }
117  // masterSector = copyno;
118  // }
119  // }
120 
121  // Get material for this volume
122  if (fv.logicalPart().material().name().name() == "Iron")
123  isIronFlag = true;
124 
125  if (debug) {
126  cout << " RMin = " << theRMin << endl;
127  cout << " RMax = " << theRMax << endl;
128 
129  if (theRMin < 0 || theRN < theRMin || theRMax < theRN)
130  cout << "*** WARNING: wrong RMin/RN/RMax , shape: " << DDSolidShapesName::name(shape()) << endl;
131 
132  cout << "Summary: " << name << " " << copyno << " Shape= " << DDSolidShapesName::name(shape()) << " trasl "
133  << center() << " R " << center().perp() << " phi " << center().phi() << " magFile " << magFile
134  << " Material= " << fv.logicalPart().material().name() << " isIron= " << isIronFlag
135  << " masterSector= " << masterSector << std::endl;
136 
137  cout << " Orientation of surfaces:";
138  std::string sideName[3] = {"positiveSide", "negativeSide", "onSurface"};
139  for (int i = 0; i < 6; ++i) {
140  cout << " " << i << ":" << sideName[surfaces[i]->side(center_, 0.3)];
141  }
142  cout << endl;
143  }
144 }
145 
147  // The refPlane is the "main plane" for the solid. It corresponds to the
148  // x,y plane in the DDD local frame, and defines a frame where the local
149  // coordinates are the same as in DDD.
150  // In the geometry version 85l_030919, this plane is normal to the
151  // beam line for all volumes but pseudotraps, so that global R is along Y,
152  // global phi is along -X and global Z along Z:
153  //
154  // Global(for vol at pi/2) Local
155  // +R (+Y) +Y
156  // +phi(-X) -X
157  // +Z +Z
158  //
159  // For pseudotraps the refPlane is parallel to beam line and global R is
160  // along Z, global phi is along +-X and and global Z along Y:
161  //
162  // Global(for vol at pi/2) Local
163  // +R (+Y) +Z
164  // +phi(-X) +X
165  // +Z +Y
166  //
167  // Note that the frame is centered in the DDD volume center, which is
168  // inside the volume for DDD boxes and (pesudo)trapezoids, on the beam line
169  // for tubs, cons and trunctubs.
170 
171  // In geometry version 1103l, trapezoids have X and Z in the opposite direction
172  // than the above. Boxes are either oriented as described above or in some case
173  // have opposite direction for Y and X.
174 
175  // The global position
176  Surface::PositionType &posResult = center_;
177 
178  // The reference plane rotation
179  DD3Vector x, y, z;
180  fv.rotation().GetComponents(x, y, z);
181  if (debug) {
182  if (x.Cross(y).Dot(z) < 0.5) {
183  cout << "*** WARNING: Rotation is not RH " << endl;
184  }
185  }
186 
187  // The global rotation
188  Surface::RotationType rotResult(float(x.X()),
189  float(x.Y()),
190  float(x.Z()),
191  float(y.X()),
192  float(y.Y()),
193  float(y.Z()),
194  float(z.X()),
195  float(z.Y()),
196  float(z.Z()));
197 
198  refPlane = new GloballyPositioned<float>(posResult, rotResult);
199 
200  // Check correct orientation
201  if (debug) {
202  cout << "Refplane pos " << refPlane->position() << endl;
203 
204  // See comments above for the conventions for orientation.
205  LocalVector globalZdir(0., 0., 1.); // Local direction of the axis along global Z
207  globalZdir = LocalVector(0., 1., 0.);
208  }
209  if (refPlane->toGlobal(globalZdir).z() < 0.) {
210  globalZdir = -globalZdir;
211  }
212 
213  float chk = refPlane->toGlobal(globalZdir).dot(GlobalVector(0, 0, 1));
214  if (chk < .999)
215  cout << "*** WARNING RefPlane check failed!***" << chk << endl;
216  }
217 }
218 
219 std::vector<VolumeSide> MagGeoBuilderFromDDD::volumeHandle::sides() const {
220  std::vector<VolumeSide> result;
221  for (int i = 0; i < 6; ++i) {
222  // If this is just a master volume out of wich a 2pi volume
223  // should be built (e.g. central cylinder), skip the phi boundaries.
224  if (expand && (i == phiplus || i == phiminus))
225  continue;
226 
227  // FIXME: Skip null inner degenerate cylindrical surface
229  continue;
230 
231  ReferenceCountingPointer<Surface> s = const_cast<Surface *>(surfaces[i].get());
232  result.push_back(VolumeSide(s, GlobalFace(i), surfaces[i]->side(center_, 0.3)));
233  }
234  return result;
235 }
236 
238 
240 using namespace magneticfield;
241 
242 namespace {
243  // Old DD returns lengths in mm, but CMS code uses cm
244  template <class NumType>
245  inline constexpr NumType convertUnits(NumType millimeters) // Millimeters -> centimeters
246  {
247  return (geant_units::operators::convertMmToCm(millimeters));
248  }
249 } // namespace
250 
251 #include "buildBox.icc"
252 #include "buildTrap.icc"
253 #include "buildTubs.icc"
254 #include "buildCons.icc"
255 #include "buildPseudoTrap.icc"
256 #include "buildTruncTubs.icc"
const DDRotationMatrix & rotation() const
The absolute rotation of the current node.
MagGeoBuilderFromDDD::volumeHandle volumeHandle
const N & name() const
Definition: DDBase.h:59
T perp() const
Definition: PV3DBase.h:69
Surface::LocalVector LocalVector
volumeHandle(const DDExpandedView &fv, bool expand2Pi=false, bool debugVal=false)
Definition: volumeHandle.cc:32
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
const DDSolid & solid(void) const
Returns a reference object of the solid being the shape of this LogicalPart.
unsigned short volumeno
volume number
unsigned short copyno
copy number
static const char *const name(DDSolidShape s)
Definition: DDSolidShapes.h:32
GloballyPositioned< float > * refPlane
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DD3Vector
A DD Translation is currently implemented with Root Vector3D.
Definition: DDTranslation.h:6
Surface::GlobalPoint GlobalPoint
T z() const
Definition: PV3DBase.h:61
int masterSector
The sector for which an interpolator for this class of volumes should be built.
DDSolidShape shape(void) const
The type of the solid.
Definition: DDSolid.cc:119
void referencePlane(const DDExpandedView &fv)
const DDTranslation & translation() const
The absolute translation of the current node.
const GlobalPoint & center() const
Return the center of the volume.
GlobalPoint toGlobal(const LocalPoint &lp) const
int copyno() const
Copy number associated with the current node.
std::string name
Name of the volume.
constexpr NumType convertMmToCm(NumType millimeters)
Definition: GeantUnits.h:62
const DDLogicalPart & logicalPart() const
The logical-part of the current node in the expanded-view.
const PositionType & position() const
Provides an exploded view of the detector (tree-view)
const std::string & name() const
Returns the name.
Definition: DDName.cc:40
const DDMaterial & material(void) const
Returns a reference object of the material this LogicalPart is made of.
std::string magFile
Name of magnetic field table file.
#define constexpr
std::vector< VolumeSide > sides() const override
The surfaces and they orientation, as required to build a MagVolume.
DDSolidShape shape() const override
Shape of the solid.
Definition: volumeHandle.h:32
Global3DVector GlobalVector
Definition: GlobalVector.h:10