CMS 3D CMS Logo

DD4hep_MagGeoBuilder.cc
Go to the documentation of this file.
1 /*
2  * See header file for a description of this class.
3  *
4  */
5 
6 #include "DD4hep_MagGeoBuilder.h"
7 #include "bLayer.h"
8 #include "eSector.h"
9 #include "FakeInterpolator.h"
10 
13 
15 
17 
19 
23 
26 
28 
32 
33 #include <iomanip>
34 #include <string>
35 #include <vector>
36 #include <sstream>
37 #include <algorithm>
38 #include <iterator>
39 #include <map>
40 #include <set>
41 #include <boost/algorithm/string/replace.hpp>
42 
43 using namespace std;
44 using namespace magneticfield;
45 using namespace edm;
46 using namespace angle_units::operators;
47 
48 MagGeoBuilder::MagGeoBuilder(string tableSet, int geometryVersion, bool debug)
49  : tableSet_(tableSet), geometryVersion_(geometryVersion), theGridFiles_(nullptr), debug_(debug) {
50  LogTrace("MagGeoBuilder") << "Constructing a MagGeoBuilder";
51 }
52 
54  for (auto i : bVolumes_) {
55  delete i;
56  }
57  for (auto i : eVolumes_) {
58  delete i;
59  }
60 }
61 
63  // The final countdown.
64  int ivolumes = volumes.size(); // number of volumes
65  int isurfaces = ivolumes * 6; // number of individual surfaces
66  int iassigned = 0; // How many have been assigned
67  int iunique = 0; // number of unique surfaces
68  int iref_ass = 0;
69  int iref_nass = 0;
70 
71  set<const void*> ptrs;
72 
73  for (auto i : volumes) {
74  DDSolidShape theShape = i->shape();
75  if (theShape == DDSolidShape::ddbox || theShape == DDSolidShape::ddcons || theShape == DDSolidShape::ddtrap ||
76  theShape == DDSolidShape::ddtubs) {
77  for (int side = 0; side < 6; ++side) {
78  int references = i->references(side);
79  if (i->isPlaneMatched(side)) {
80  ++iassigned;
81  bool firstOcc = (ptrs.insert(&(i->surface(side)))).second;
82  if (firstOcc)
83  iref_ass += references;
84  if (references < 2) {
85  LogTrace("MagGeoBuilder") << "*** Only 1 ref, vol: " << i->volumeno << " # " << i->copyno
86  << " side: " << side;
87  }
88  } else {
89  iref_nass += references;
90  if (references > 1) {
91  LogTrace("MagGeoBuilder") << "*** Ref_nass >1 ";
92  }
93  }
94  }
95  } // end if theShape
96  } // end for
97  iunique = ptrs.size();
98 
99  LogTrace("MagGeoBuilder") << " volumes " << ivolumes << newln << " surfaces " << isurfaces << newln
100  << " assigned " << iassigned << newln << " unique " << iunique << newln
101  << " iref_ass " << iref_ass << newln << " iref_nass " << iref_nass;
102 }
103 
105  cms::Volume top = det->worldVolume();
106  cms::DDFilteredView fv(det, top);
107  if (fv.next(0) == false) {
108  LogError("MagGeoBuilder") << "Filtered view is empty. Cannot build.";
109  return;
110  }
111 
112  // The actual field interpolators
113  map<string, MagProviderInterpol*> bInterpolators;
114  map<string, MagProviderInterpol*> eInterpolators;
115 
116  // Counter of different volumes
117  int bVolCount = 0;
118  int eVolCount = 0;
119 
120  const string magfStr{"MAGF"};
121  const string magfStr2{"cmsMagneticField:MAGF"};
122  if (fv.name() != magfStr && fv.name() != magfStr2) {
123  std::string topNodeName(fv.name());
124  LogTrace("MagGeoBuilder") << "Filtered view top node name is " << topNodeName << ".";
125 
126  //see if one of the children is MAGF
127  bool doSubDets = fv.next(0);
128 
129  bool go = true;
130  while (go && doSubDets) {
131  LogTrace("MagGeoBuilder") << "Next node name is " << fv.name() << ".";
132  if (fv.name() == magfStr)
133  break;
134  else
135  go = fv.next(0);
136  }
137  if (!go) {
138  throw cms::Exception("NoMAGF")
139  << " Neither the top node, nor any child node of the filtered view is \"MAGF\" but the top node is instead \""
140  << topNodeName << "\"";
141  }
142  }
143 
144  // Loop over MAGF volumes and create volumeHandles.
145  bool doSubDets = fv.next(0);
146  if (doSubDets == false) {
147  LogError("MagGeoBuilder") << "Filtered view has no node. Cannot build.";
148  return;
149  }
150  while (doSubDets) {
151  string name = fv.volume().volume().name();
152  LogTrace("MagGeoBuilder") << "Name: " << name;
153 
154  bool expand = false;
155  volumeHandle* v = new volumeHandle(fv, expand, debug_);
156 
157  if (theGridFiles_ != nullptr) {
158  int key = (v->volumeno) * 100 + v->copyno;
159  TableFileMap::const_iterator itable = theGridFiles_->find(key);
160  if (itable == theGridFiles_->end()) {
161  key = (v->volumeno) * 100;
162  itable = theGridFiles_->find(key);
163  }
164 
165  if (itable != theGridFiles_->end()) {
166  string magFile = (*itable).second.first;
167  stringstream conv;
168  string svol, ssec;
169  conv << setfill('0') << setw(3) << v->volumeno << " " << setw(2)
170  << v->copyno; // volume assumed to have 0s padding to 3 digits; sector assumed to have 0s padding to 2 digits
171  conv >> svol >> ssec;
172  boost::replace_all(magFile, "[v]", svol);
173  boost::replace_all(magFile, "[s]", ssec);
174  int masterSector = (*itable).second.second;
175  if (masterSector == 0)
176  masterSector = v->copyno;
177  v->magFile = magFile;
178  v->masterSector = masterSector;
179  } else {
180  edm::LogError("MagGeoBuilderbuild") << "ERROR: no table spec found for V " << v->volumeno << ":" << v->copyno;
181  }
182  }
183 
184  // Select volumes, build volume handles.
185  float Z = v->center().z();
186  float R = v->center().perp();
187  LogTrace("MagGeoBuilder") << " Vol R and Z values determine barrel or endcap. R = " << R << ", Z = " << Z;
188 
189  // v 85l: Barrel is everything up to |Z| = 661.0, excluding
190  // volume #7, centered at 6477.5
191  // v 1103l: same numbers work fine. #16 instead of #7, same coords;
192  // see comment below for V6,7
193  //ASSUMPTION: no misalignment is applied to mag volumes.
194  //FIXME: implement barrel/endcap flags as DDD SpecPars.
195  if ((fabs(Z) < 647. || (R > 350. && fabs(Z) < 662.)) &&
196  !(fabs(Z) > 480 && R < 172) // in 1103l we place V_6 and V_7 in the
197  // endcaps to preserve nice layer structure
198  // in the barrel. This does not hurt in v85l
199  // where there is a single V1
200  ) { // Barrel
201  LogTrace("MagGeoBuilder") << " (Barrel)";
202  bVolumes_.push_back(v);
203 
204  // Build the interpolator of the "master" volume (the one which is
205  // not replicated in phi)
206  // ASSUMPTION: copyno == sector.
207  if (v->copyno == v->masterSector) {
208  buildInterpolator(v, bInterpolators);
209  ++bVolCount;
210  }
211  } else { // Endcaps
212  LogTrace("MagGeoBuilder") << " (Endcaps)";
213  eVolumes_.push_back(v);
214  if (v->copyno == v->masterSector) {
215  buildInterpolator(v, eInterpolators);
216  ++eVolCount;
217  }
218  }
219  doSubDets = fv.next(0); // end of loop over MAGF
220  }
221 
222  LogTrace("MagGeoBuilder") << "Number of volumes (barrel): " << bVolumes_.size() << newln
223  << "Number of volumes (endcap): " << eVolumes_.size();
224  LogTrace("MagGeoBuilder") << "**********************************************************";
225 
226  // Now all volumeHandles are there, and parameters for each of the planes
227  // are calculated.
228 
229  //----------------------------------------------------------------------
230  // Print summary information
231 
232  if (debug_) {
233  LogTrace("MagGeoBuilder") << "-----------------------";
234  LogTrace("MagGeoBuilder") << "SUMMARY: Barrel ";
236 
237  LogTrace("MagGeoBuilder") << "SUMMARY: Endcaps ";
239  LogTrace("MagGeoBuilder") << "-----------------------";
240  }
241 
242  //----------------------------------------------------------------------
243  // Find barrel layers.
244 
245  if (bVolumes_.empty()) {
246  LogError("MagGeoBuilder") << "Error: Barrel volumes are missing. Terminating build.";
247  return;
248  }
249  vector<bLayer> layers; // the barrel layers
251 
252  // Find the layers (in R)
253  const float resolution = 1.; // cm
254  float rmin = bVolumes_.front()->RN() - resolution;
255  float rmax = bVolumes_.back()->RN() + resolution;
256  ClusterizingHistogram hisR(int((rmax - rmin) / resolution) + 1, rmin, rmax);
257 
258  LogTrace("MagGeoBuilder") << " R layers: " << rmin << " " << rmax;
259 
260  handles::const_iterator first = bVolumes_.begin();
261  handles::const_iterator last = bVolumes_.end();
262 
263  for (auto i : bVolumes_) {
264  hisR.fill(i->RN());
265  }
266  vector<float> rClust = hisR.clusterize(resolution);
267 
268  handles::const_iterator ringStart = first;
269  handles::const_iterator separ = first;
270 
271  for (unsigned int i = 0; i < rClust.size() - 1; ++i) {
272  if (debug_)
273  LogTrace("MagGeoBuilder") << " Layer at RN = " << rClust[i];
274  float rSepar = (rClust[i] + rClust[i + 1]) / 2.f;
275  while ((*separ)->RN() < rSepar)
276  ++separ;
277 
278  bLayer thislayer(ringStart, separ, debug_);
279  layers.push_back(thislayer);
280  ringStart = separ;
281  }
282  {
283  if (debug_)
284  LogTrace("MagGeoBuilder") << " Layer at RN = " << rClust.back();
285  bLayer thislayer(separ, last, debug_);
286  layers.push_back(thislayer);
287  }
288 
289  LogTrace("MagGeoBuilder") << "Barrel: Found " << rClust.size() << " clusters in R, " << layers.size() << " layers ";
290 
291  //----------------------------------------------------------------------
292  // Find endcap sectors
293  vector<eSector> sectors; // the endcap sectors
294 
295  // Find the number of sectors (should be 12 or 24 depending on the geometry model)
296  constexpr float phireso = 0.05; // rad
297  constexpr int twoPiOverPhiReso = static_cast<int>(2._pi / phireso) + 1;
298  ClusterizingHistogram hisPhi(twoPiOverPhiReso, -1._pi, 1._pi);
299 
300  for (auto i : eVolumes_) {
301  hisPhi.fill(i->minPhi());
302  }
303  vector<float> phiClust = hisPhi.clusterize(phireso);
304  int nESectors = phiClust.size();
305  if (nESectors <= 0) {
306  LogError("MagGeoBuilder") << "ERROR: Endcap sectors are missing. Terminating build.";
307  return;
308  }
309  if (debug_ && (nESectors % 12) != 0) {
310  LogTrace("MagGeoBuilder") << "ERROR: unexpected # of endcap sectors: " << nESectors;
311  }
312 
313  //Sort in phi
315 
316  // Handle the -pi/pi boundary: volumes crossing it could be half at the begin and half at end of the sorted list.
317  // So, check if any of the volumes that should belong to the first bin (at -phi) are at the end of the list:
318  float lastBinPhi = phiClust.back();
319  handles::reverse_iterator ri = eVolumes_.rbegin();
320  while ((*ri)->center().phi() > lastBinPhi) {
321  ++ri;
322  }
323  if (ri != eVolumes_.rbegin()) {
324  // ri points to the first element that is within the last bin.
325  // We need to move the following element (ie ri.base()) to the beginning of the list,
326  handles::iterator newbeg = ri.base();
327  rotate(eVolumes_.begin(), newbeg, eVolumes_.end());
328  }
329 
330  //Group volumes in sectors
331  int offset = eVolumes_.size() / nESectors;
332  for (int i = 0; i < nESectors; ++i) {
333  if (debug_) {
334  LogTrace("MagGeoBuilder") << " Sector at phi = " << (*(eVolumes_.begin() + ((i)*offset)))->center().phi();
335  // Additional x-check: sectors are expected to be made by volumes with the same copyno
336  int secCopyNo = -1;
337  for (handles::const_iterator iv = eVolumes_.begin() + ((i)*offset); iv != eVolumes_.begin() + ((i + 1) * offset);
338  ++iv) {
339  if (secCopyNo >= 0 && (*iv)->copyno != secCopyNo)
340  LogTrace("MagGeoBuilder") << "ERROR: volume copyno " << (*iv)->name << ":" << (*iv)->copyno
341  << " differs from others in same sectors with copyno = " << secCopyNo;
342  secCopyNo = (*iv)->copyno;
343  }
344  }
345 
346  sectors.push_back(eSector(eVolumes_.begin() + ((i)*offset), eVolumes_.begin() + ((i + 1) * offset), debug_));
347  }
348 
349  LogTrace("MagGeoBuilder") << "Endcap: Found " << sectors.size() << " sectors ";
350 
351  //----------------------------------------------------------------------
352  // Build MagVolumes and the MagGeometry hierarchy.
353 
354  //--- Barrel
355 
356  // Build MagVolumes and associate interpolators to them
357  buildMagVolumes(bVolumes_, bInterpolators);
358 
359  // Build MagBLayers
360  for (const auto& ilay : layers) {
361  mBLayers_.push_back(ilay.buildMagBLayer());
362  }
363  LogTrace("MagGeoBuilder") << "*** BARREL ********************************************" << newln
364  << "Number of different volumes = " << bVolCount << newln
365  << "Number of interpolators built = " << bInterpolators.size() << newln
366  << "Number of MagBLayers built = " << mBLayers_.size();
367  if (debug_) {
368  testInside(bVolumes_); // FIXME: all volumes should be checked in one go.
369  }
370  //--- Endcap
371  // Build MagVolumes and associate interpolators to them
372  buildMagVolumes(eVolumes_, eInterpolators);
373 
374  // Build the MagESectors
375  for (const auto& isec : sectors) {
376  mESectors_.push_back(isec.buildMagESector());
377  }
378  LogTrace("MagGeoBuilder") << "*** ENDCAP ********************************************" << newln
379  << "Number of different volumes = " << eVolCount << newln
380  << "Number of interpolators built = " << eInterpolators.size() << newln
381  << "Number of MagESector built = " << mESectors_.size();
382  if (debug_) {
383  testInside(eVolumes_); // FIXME: all volumes should be checked in one go.
384  }
385 }
386 
387 void MagGeoBuilder::buildMagVolumes(const handles& volumes, map<string, MagProviderInterpol*>& interpolators) {
388  // Build all MagVolumes setting the MagProviderInterpol
389  for (auto vol : volumes) {
390  const MagProviderInterpol* mp = nullptr;
391  if (interpolators.find(vol->magFile) != interpolators.end()) {
392  mp = interpolators[vol->magFile];
393  } else {
394  edm::LogError("MagGeoBuilder") << "No interpolator found for file " << vol->magFile << " vol: " << vol->volumeno
395  << "\n"
396  << interpolators.size();
397  }
398 
399  // Search for [volume,sector] in the list of scaling factors; sector = 0 handled as wildcard
400  // ASSUMPTION: copyno == sector.
401  int key = (vol->volumeno) * 100 + vol->copyno;
402  map<int, double>::const_iterator isf = theScalingFactors_.find(key);
403  if (isf == theScalingFactors_.end()) {
404  key = (vol->volumeno) * 100;
405  isf = theScalingFactors_.find(key);
406  }
407 
408  double sf = 1.;
409  if (isf != theScalingFactors_.end()) {
410  sf = (*isf).second;
411 
412  LogTrace("MagGeoBuilder") << "Applying scaling factor " << sf << " to " << vol->volumeno << "[" << vol->copyno
413  << "] (key:" << key << ")";
414  }
415 
416  const GloballyPositioned<float>* gpos = vol->placement();
417  vol->magVolume = new MagVolume6Faces(gpos->position(), gpos->rotation(), vol->sides(), mp, sf);
418 
419  if (vol->copyno == vol->masterSector) {
420  vol->magVolume->ownsFieldProvider(true);
421  }
422 
423  vol->magVolume->setIsIron(vol->isIron());
424 
425  // The name and sector of the volume are saved for debug purposes only. They may be removed at some point...
426  vol->magVolume->volumeNo = vol->volumeno;
427  vol->magVolume->copyno = vol->copyno;
428  }
429 }
430 
431 void MagGeoBuilder::buildInterpolator(const volumeHandle* vol, map<string, MagProviderInterpol*>& interpolators) {
432  // Phi of the master sector
433  double masterSectorPhi = (vol->masterSector - 1) * 1._pi / 6.;
434 
435  LogTrace("MagGeoBuilder") << "Building interpolator from " << vol->volumeno << " copyno " << vol->copyno << " at "
436  << vol->center() << " phi: " << static_cast<double>(vol->center().phi()) / 1._pi
437  << " pi, file: " << vol->magFile << " master: " << vol->masterSector;
438  if (debug_) {
439  double delta = std::abs(vol->center().phi() - masterSectorPhi);
440  if (delta > (1._pi / 9.)) {
441  LogTrace("MagGeoBuilder") << "***WARNING wrong sector? Vol delta from master sector is " << delta / 1._pi
442  << " pi";
443  }
444  }
445 
446  if (tableSet_ == "fake" || vol->magFile == "fake") {
447  interpolators[vol->magFile] = new magneticfield::FakeInterpolator();
448  return;
449  }
450 
451  string fullPath;
452 
453  try {
454  edm::FileInPath mydata("MagneticField/Interpolation/data/" + tableSet_ + "/" + vol->magFile);
455  fullPath = mydata.fullPath();
456  } catch (edm::Exception& exc) {
457  cerr << "MagGeoBuilder: exception in reading table; " << exc.what() << endl;
458  if (!debug_)
459  throw;
460  return;
461  }
462 
463  try {
464  if (vol->toExpand()) {
465  //FIXME: see discussion on mergeCylinders above.
466  // interpolators[vol->magFile] =
467  // MFGridFactory::build( fullPath, *(vol->placement()), vol->minPhi(), vol->maxPhi());
468  } else {
469  // If the table is in "local" coordinates, must create a reference
470  // frame that is appropriately rotated along the CMS Z axis.
471 
473 
474  if (vol->masterSector != 1) {
476 
477  GloballyPositioned<float>::RotationType rot(Vector(0, 0, 1), -masterSectorPhi);
478  Vector vpos(vol->placement()->position());
479 
481  vol->placement()->rotation() * rot);
482  }
483 
484  interpolators[vol->magFile] = MFGridFactory::build(fullPath, rf);
485  }
486  } catch (MagException& exc) {
487  LogTrace("MagGeoBuilder") << exc.what();
488  interpolators.erase(vol->magFile);
489  if (!debug_)
490  throw;
491  return;
492  }
493 
494  if (debug_) {
495  // Check that all grid points of the interpolator are inside the volume.
496  const MagVolume6Faces tempVolume(
497  vol->placement()->position(), vol->placement()->rotation(), vol->sides(), interpolators[vol->magFile]);
498 
499  const MFGrid* grid = dynamic_cast<const MFGrid*>(interpolators[vol->magFile]);
500  if (grid != nullptr) {
501  Dimensions sizes = grid->dimensions();
502  LogTrace("MagGeoBuilder") << "Grid has 3 dimensions "
503  << " number of nodes is " << sizes.w << " " << sizes.h << " " << sizes.d;
504 
505  const double tolerance = 0.03;
506 
507  size_t dumpCount = 0;
508  for (int j = 0; j < sizes.h; j++) {
509  for (int k = 0; k < sizes.d; k++) {
510  for (int i = 0; i < sizes.w; i++) {
511  MFGrid::LocalPoint lp = grid->nodePosition(i, j, k);
512  if (!tempVolume.inside(lp, tolerance)) {
513  if (++dumpCount < 2) {
514  MFGrid::GlobalPoint gp = tempVolume.toGlobal(lp);
515  LogTrace("MagGeoBuilder") << "GRID ERROR: " << i << " " << j << " " << k << " local: " << lp
516  << " global: " << gp << " R= " << gp.perp() << " phi=" << gp.phi();
517  }
518  }
519  }
520  }
521  }
522 
523  LogTrace("MagGeoBuilder") << "Volume:" << vol->volumeno
524  << " : Number of grid points outside the MagVolume: " << dumpCount << "/"
525  << sizes.w * sizes.h * sizes.d;
526  }
527  }
528 }
529 
531  // test inside() for all volumes.
532  LogTrace("MagGeoBuilder") << "--------------------------------------------------";
533  LogTrace("MagGeoBuilder") << " inside(center) test";
534  for (auto vol : volumes) {
535  for (auto i : volumes) {
536  if (i == vol)
537  continue;
538  //if (i->magVolume == 0) continue;
539  if (i->magVolume->inside(vol->center())) {
540  LogTrace("MagGeoBuilder") << "*** ERROR: center of V " << vol->volumeno << ":" << vol->copyno << " is inside V "
541  << i->volumeno << ":" << i->copyno;
542  }
543  }
544 
545  if (vol->magVolume->inside(vol->center())) {
546  LogTrace("MagGeoBuilder") << "V " << vol->volumeno << ":" << vol->copyno << " OK ";
547  } else {
548  LogTrace("MagGeoBuilder") << "*** ERROR: center of volume is not inside it, " << vol->volumeno << ":"
549  << vol->copyno;
550  }
551  }
552  LogTrace("MagGeoBuilder") << "--------------------------------------------------";
553 }
554 
555 vector<MagBLayer*> MagGeoBuilder::barrelLayers() const { return mBLayers_; }
556 
557 vector<MagESector*> MagGeoBuilder::endcapSectors() const { return mESectors_; }
558 
559 vector<MagVolume6Faces*> MagGeoBuilder::barrelVolumes() const {
560  vector<MagVolume6Faces*> v;
561  v.reserve(bVolumes_.size());
562  for (auto i : bVolumes_) {
563  v.push_back(i->magVolume);
564  }
565  return v;
566 }
567 
568 vector<MagVolume6Faces*> MagGeoBuilder::endcapVolumes() const {
569  vector<MagVolume6Faces*> v;
570  v.reserve(eVolumes_.size());
571  for (auto i : eVolumes_) {
572  v.push_back(i->magVolume);
573  }
574  return v;
575 }
576 
577 float MagGeoBuilder::maxR() const {
578  //FIXME: should get it from the actual geometry
579  return 900.;
580 }
581 
582 float MagGeoBuilder::maxZ() const {
583  //FIXME: should get it from the actual geometry
584  if (geometryVersion_ >= 160812)
585  return 2400.;
586  else if (geometryVersion_ >= 120812)
587  return 2000.;
588  else
589  return 1600.;
590 }
591 
592 void MagGeoBuilder::setScaling(const std::vector<int>& keys, const std::vector<double>& values) {
593  if (keys.size() != values.size()) {
594  throw cms::Exception("InvalidParameter")
595  << "Invalid field scaling parameters 'scalingVolumes' and 'scalingFactors' ";
596  }
597  for (unsigned int i = 0; i < keys.size(); ++i) {
599  }
600 }
601 
MagGeoBuilderFromDDD::volumeHandle volumeHandle
void buildInterpolator(const volumeHandle *vol, std::map< std::string, MagProviderInterpol *> &interpolators)
std::vector< MagBLayer * > barrelLayers() const
Get barrel layers.
int32_t *__restrict__ iv
std::string fullPath() const
Definition: FileInPath.cc:161
ROOT::Math::Plane3D::Vector Vector
Definition: EcalHitMaker.cc:29
const double tolerance
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
void summary(handles &volumes) const
GloballyPositioned< float >::LocalPoint LocalPoint
Definition: MFGrid.h:31
std::vector< MagESector * > mESectors_
Log< level::Error, false > LogError
const GlobalPoint & center() const
Return the center of the volume.
unsigned short volumeno
volume number
const char *const newln
#define LogTrace(id)
int w
Definition: MFGrid.h:16
unsigned short copyno
copy number
U second(std::pair< T, U > const &p)
std::string_view name() const
std::vector< MagBLayer * > mBLayers_
std::vector< float > clusterize(float resolution)
std::vector< BaseVolumeHandle * > handles
const char * what() const override
Definition: MagExceptions.cc:5
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int masterSector
The sector for which an interpolator for this class of volumes should be built.
double f[11][100]
static MFGrid * build(const std::string &name, const GloballyPositioned< float > &vol)
Build interpolator for a binary grid file.
bool next(int)
set current node to the next node in the filtered tree
Point3DBase< T, GlobalTag > PositionType
dd4hep::Volume Volume
void buildMagVolumes(const handles &volumes, std::map< std::string, MagProviderInterpol *> &interpolators)
const TableFileMap * theGridFiles_
void setGridFiles(const TableFileMap &gridFiles)
#define debug
Definition: HDRShower.cc:19
void precomputed_value_sort(RandomAccessIterator begin, RandomAccessIterator end, const Extractor &extr, const Compare &comp)
const PositionType & position() const
GloballyPositioned< float >::GlobalPoint GlobalPoint
Definition: MFGrid.h:29
dd4hep::Volume worldVolume() const
Handle to the world volume containing everything.
Definition: DDDetector.cc:62
DDSolidShape
Definition: DDSolidShapes.h:6
std::vector< MagESector * > endcapSectors() const
Get endcap layers.
Definition: MFGrid.h:27
int d
Definition: MFGrid.h:18
int h
Definition: MFGrid.h:17
EPOS::IO_EPOS conv
std::map< int, double > theScalingFactors_
std::vector< MagVolume6Faces * > barrelVolumes() const
HLT enums.
void build(const cms::DDDetector *det)
const PlacedVolume volume() const
The physical volume of the current node.
std::vector< VolumeSide > sides() const override
The surfaces and they orientation, as required to build a MagVolume.
void setScaling(const std::vector< int > &keys, const std::vector< double > &values)
const RotationType & rotation() const
char const * what() const noexcept override
Definition: Exception.cc:103
std::map< int, std::pair< std::string, int > > TableFileMap
const GloballyPositioned< float > * placement() const
Position and rotation.
def rotate(angle, cx=0, cy=0)
Definition: svgfig.py:705
std::vector< MagVolume6Faces * > endcapVolumes() const
std::string magFile
Name of magnetic field table file.
void testInside(handles &volumes)
void ownsFieldProvider(bool o)
Definition: MagVolume.h:47