CMS 3D CMS Logo

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