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