CMS 3D CMS Logo

List of all members | Public Member Functions | Private Member Functions | Private Attributes
magneticfield::MagGeoBuilder Class Reference

#include <DD4hep_MagGeoBuilder.h>

Public Member Functions

std::vector< MagBLayer * > barrelLayers () const
 Get barrel layers. More...
 
std::vector< MagVolume6Faces * > barrelVolumes () const
 
void build (const cms::DDDetector *det)
 
std::vector< MagESector * > endcapSectors () const
 Get endcap layers. More...
 
std::vector< MagVolume6Faces * > endcapVolumes () const
 
 MagGeoBuilder (std::string tableSet, int geometryVersion, bool debug=false)
 
float maxR () const
 
float maxZ () const
 
void setGridFiles (const TableFileMap &gridFiles)
 
void setScaling (const std::vector< int > &keys, const std::vector< double > &values)
 
 ~MagGeoBuilder ()
 

Private Member Functions

void buildInterpolator (const volumeHandle *vol, std::map< std::string, MagProviderInterpol *> &interpolators)
 
void buildMagVolumes (const handles &volumes, std::map< std::string, MagProviderInterpol *> &interpolators)
 
void summary (handles &volumes) const
 
void testInside (handles &volumes)
 

Private Attributes

handles bVolumes_
 
const bool debug_
 
handles eVolumes_
 
int geometryVersion_
 
std::vector< MagBLayer * > mBLayers_
 
std::vector< MagESector * > mESectors_
 
std::string tableSet_
 
const TableFileMaptheGridFiles_
 
std::map< int, double > theScalingFactors_
 

Detailed Description

Definition at line 35 of file DD4hep_MagGeoBuilder.h.

Constructor & Destructor Documentation

◆ MagGeoBuilder()

MagGeoBuilder::MagGeoBuilder ( std::string  tableSet,
int  geometryVersion,
bool  debug = false 
)

Definition at line 48 of file DD4hep_MagGeoBuilder.cc.

References LogTrace.

50  LogTrace("MagGeoBuilder") << "Constructing a MagGeoBuilder";
51 }
#define LogTrace(id)
const TableFileMap * theGridFiles_
#define debug
Definition: HDRShower.cc:19

◆ ~MagGeoBuilder()

MagGeoBuilder::~MagGeoBuilder ( )

Definition at line 53 of file DD4hep_MagGeoBuilder.cc.

References bVolumes_, eVolumes_, and mps_fire::i.

53  {
54  for (auto i : bVolumes_) {
55  delete i;
56  }
57  for (auto i : eVolumes_) {
58  delete i;
59  }
60 }

Member Function Documentation

◆ barrelLayers()

vector< MagBLayer * > MagGeoBuilder::barrelLayers ( ) const

◆ barrelVolumes()

vector< MagVolume6Faces * > MagGeoBuilder::barrelVolumes ( ) const

Definition at line 559 of file DD4hep_MagGeoBuilder.cc.

References bVolumes_, mps_fire::i, and findQualityFiles::v.

Referenced by magneticfield::DD4hep_VolumeBasedMagneticFieldESProducer::produce(), and magneticfield::DD4hep_VolumeBasedMagneticFieldESProducerFromDB::produce().

559  {
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 }

◆ build()

void MagGeoBuilder::build ( const cms::DDDetector det)

Definition at line 104 of file DD4hep_MagGeoBuilder.cc.

References buildInterpolator(), buildMagVolumes(), bVolumes_, ClusterizingHistogram::clusterize(), conv, debug_, eVolumes_, Exception, f, ClusterizingHistogram::fill(), first, mps_fire::i, gpuVertexFinder::iv, crabWrapper::key, dqmdumpme::last, hgcalTopologyTester_cfi::layers, LogTrace, mBLayers_, mESectors_, Skims_PA_cff::name, cms::DDFilteredView::name(), magneticfield::newln, cms::DDFilteredView::next(), hltrates_dqm_sourceclient-live_cfg::offset, precomputed_value_sort(), dttmaxenums::R, L1TObjectsTimingClient_cff::resolution, svgfig::rotate(), volumeBasedMagneticField_160812_cfi::sectors, AlCaHLTBitMon_QueryRunRegistry::string, summary(), testInside(), theGridFiles_, findQualityFiles::v, cms::DDFilteredView::volume(), cms::DDDetector::worldVolume(), and BeamSpotPI::Z.

Referenced by magneticfield::DD4hep_VolumeBasedMagneticFieldESProducer::produce(), and magneticfield::DD4hep_VolumeBasedMagneticFieldESProducerFromDB::produce().

104  {
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 }
MagGeoBuilderFromDDD::volumeHandle volumeHandle
void buildInterpolator(const volumeHandle *vol, std::map< std::string, MagProviderInterpol *> &interpolators)
int32_t *__restrict__ iv
void summary(handles &volumes) const
std::vector< MagESector * > mESectors_
Log< level::Error, false > LogError
const char *const newln
#define LogTrace(id)
std::vector< MagBLayer * > mBLayers_
double f[11][100]
dd4hep::Volume Volume
void buildMagVolumes(const handles &volumes, std::map< std::string, MagProviderInterpol *> &interpolators)
const TableFileMap * theGridFiles_
void precomputed_value_sort(RandomAccessIterator begin, RandomAccessIterator end, const Extractor &extr, const Compare &comp)
dd4hep::Volume worldVolume() const
Handle to the world volume containing everything.
Definition: DDDetector.cc:62
EPOS::IO_EPOS conv
def rotate(angle, cx=0, cy=0)
Definition: svgfig.py:705
void testInside(handles &volumes)

◆ buildInterpolator()

void MagGeoBuilder::buildInterpolator ( const volumeHandle vol,
std::map< std::string, MagProviderInterpol *> &  interpolators 
)
private

Definition at line 431 of file DD4hep_MagGeoBuilder.cc.

References funct::abs(), MFGridFactory::build(), magneticfield::BaseVolumeHandle::center(), EcnaPython_AdcPeg12_S1_10_R170298_1_0_150_Dee0::cerr, magneticfield::BaseVolumeHandle::copyno, Dimensions::d, debug_, dumpMFGeometry_cfg::delta, contentValuesFiles::fullPath, edm::FileInPath::fullPath(), runTauDisplay::gp, getRunAppsInfo::grid, Dimensions::h, mps_fire::i, if(), dqmiolumiharvest::j, dqmdumpme::k, LogTrace, magneticfield::BaseVolumeHandle::magFile, magneticfield::BaseVolumeHandle::masterSector, PV3DBase< T, PVType, FrameType >::phi(), magneticfield::BaseVolumeHandle::placement(), GloballyPositioned< T >::position(), hcal_runs::rf, makeMuonMisalignmentScenario::rot, GloballyPositioned< T >::rotation(), magneticfield::volumeHandle::sides(), tableSet_, magneticfield::BaseVolumeHandle::toExpand(), tolerance, magneticfield::BaseVolumeHandle::volumeno, Dimensions::w, MagException::what(), and cms::Exception::what().

Referenced by build().

431  {
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 }
ROOT::Math::Plane3D::Vector Vector
Definition: EcalHitMaker.cc:29
const double tolerance
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
GloballyPositioned< float >::LocalPoint LocalPoint
Definition: MFGrid.h:31
const GlobalPoint & center() const
Return the center of the volume.
unsigned short volumeno
volume number
#define LogTrace(id)
int w
Definition: MFGrid.h:16
unsigned short copyno
copy number
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.
static MFGrid * build(const std::string &name, const GloballyPositioned< float > &vol)
Build interpolator for a binary grid file.
Point3DBase< T, GlobalTag > PositionType
const PositionType & position() const
GloballyPositioned< float >::GlobalPoint GlobalPoint
Definition: MFGrid.h:29
Definition: MFGrid.h:27
int d
Definition: MFGrid.h:18
int h
Definition: MFGrid.h:17
std::vector< VolumeSide > sides() const override
The surfaces and they orientation, as required to build a MagVolume.
const RotationType & rotation() const
char const * what() const noexcept override
Definition: Exception.cc:103
const GloballyPositioned< float > * placement() const
Position and rotation.
std::string magFile
Name of magnetic field table file.

◆ buildMagVolumes()

void MagGeoBuilder::buildMagVolumes ( const handles volumes,
std::map< std::string, MagProviderInterpol *> &  interpolators 
)
private

Definition at line 387 of file DD4hep_MagGeoBuilder.cc.

References crabWrapper::key, LogTrace, MagVolume::ownsFieldProvider(), GloballyPositioned< T >::position(), GloballyPositioned< T >::rotation(), theScalingFactors_, and volumeBasedMagneticField_160812_cfi::volumes.

Referenced by build().

387  {
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 }
Log< level::Error, false > LogError
#define LogTrace(id)
const PositionType & position() const
std::map< int, double > theScalingFactors_
const RotationType & rotation() const
void ownsFieldProvider(bool o)
Definition: MagVolume.h:47

◆ endcapSectors()

vector< MagESector * > MagGeoBuilder::endcapSectors ( ) const

◆ endcapVolumes()

vector< MagVolume6Faces * > MagGeoBuilder::endcapVolumes ( ) const

Definition at line 568 of file DD4hep_MagGeoBuilder.cc.

References eVolumes_, mps_fire::i, and findQualityFiles::v.

Referenced by magneticfield::DD4hep_VolumeBasedMagneticFieldESProducer::produce(), and magneticfield::DD4hep_VolumeBasedMagneticFieldESProducerFromDB::produce().

568  {
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 }

◆ maxR()

float MagGeoBuilder::maxR ( ) const

Definition at line 577 of file DD4hep_MagGeoBuilder.cc.

Referenced by magneticfield::DD4hep_VolumeBasedMagneticFieldESProducer::produce(), and magneticfield::DD4hep_VolumeBasedMagneticFieldESProducerFromDB::produce().

577  {
578  //FIXME: should get it from the actual geometry
579  return 900.;
580 }

◆ maxZ()

float MagGeoBuilder::maxZ ( ) const

Definition at line 582 of file DD4hep_MagGeoBuilder.cc.

References geometryVersion_.

Referenced by magneticfield::DD4hep_VolumeBasedMagneticFieldESProducer::produce(), and magneticfield::DD4hep_VolumeBasedMagneticFieldESProducerFromDB::produce().

582  {
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 }

◆ setGridFiles()

void MagGeoBuilder::setGridFiles ( const TableFileMap gridFiles)

◆ setScaling()

void MagGeoBuilder::setScaling ( const std::vector< int > &  keys,
const std::vector< double > &  values 
)

Set scaling factors for individual volumes. "keys" is a vector of 100*volume number + sector (sector 0 = all sectors) "values" are the corresponding scaling factors

Definition at line 592 of file DD4hep_MagGeoBuilder.cc.

References Exception, mps_fire::i, relativeConstraints::keys, theScalingFactors_, and contentValuesCheck::values.

Referenced by magneticfield::DD4hep_VolumeBasedMagneticFieldESProducer::produce(), and magneticfield::DD4hep_VolumeBasedMagneticFieldESProducerFromDB::produce().

592  {
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 }
std::map< int, double > theScalingFactors_

◆ summary()

void MagGeoBuilder::summary ( handles volumes) const
private

Definition at line 62 of file DD4hep_MagGeoBuilder.cc.

References ddbox, ddcons, ddtrap, ddtubs, mps_fire::i, LogTrace, magneticfield::newln, edm::second(), and volumeBasedMagneticField_160812_cfi::volumes.

Referenced by build().

62  {
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 }
const char *const newln
#define LogTrace(id)
U second(std::pair< T, U > const &p)
DDSolidShape
Definition: DDSolidShapes.h:6

◆ testInside()

void MagGeoBuilder::testInside ( handles volumes)
private

Definition at line 530 of file DD4hep_MagGeoBuilder.cc.

References mps_fire::i, LogTrace, and volumeBasedMagneticField_160812_cfi::volumes.

Referenced by build().

530  {
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 }
#define LogTrace(id)

Member Data Documentation

◆ bVolumes_

handles magneticfield::MagGeoBuilder::bVolumes_
private

Definition at line 77 of file DD4hep_MagGeoBuilder.h.

Referenced by barrelVolumes(), build(), and ~MagGeoBuilder().

◆ debug_

const bool magneticfield::MagGeoBuilder::debug_
private

Definition at line 89 of file DD4hep_MagGeoBuilder.h.

Referenced by build(), and buildInterpolator().

◆ eVolumes_

handles magneticfield::MagGeoBuilder::eVolumes_
private

Definition at line 78 of file DD4hep_MagGeoBuilder.h.

Referenced by build(), endcapVolumes(), and ~MagGeoBuilder().

◆ geometryVersion_

int magneticfield::MagGeoBuilder::geometryVersion_
private

Definition at line 84 of file DD4hep_MagGeoBuilder.h.

Referenced by maxZ().

◆ mBLayers_

std::vector<MagBLayer*> magneticfield::MagGeoBuilder::mBLayers_
private

Definition at line 80 of file DD4hep_MagGeoBuilder.h.

Referenced by barrelLayers(), and build().

◆ mESectors_

std::vector<MagESector*> magneticfield::MagGeoBuilder::mESectors_
private

Definition at line 81 of file DD4hep_MagGeoBuilder.h.

Referenced by build(), and endcapSectors().

◆ tableSet_

std::string magneticfield::MagGeoBuilder::tableSet_
private

Definition at line 83 of file DD4hep_MagGeoBuilder.h.

Referenced by buildInterpolator().

◆ theGridFiles_

const TableFileMap* magneticfield::MagGeoBuilder::theGridFiles_
private

Definition at line 87 of file DD4hep_MagGeoBuilder.h.

Referenced by build(), and setGridFiles().

◆ theScalingFactors_

std::map<int, double> magneticfield::MagGeoBuilder::theScalingFactors_
private

Definition at line 86 of file DD4hep_MagGeoBuilder.h.

Referenced by buildMagVolumes(), and setScaling().