CMS 3D CMS Logo

MagGeometry.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 
12 
14 
17 
20 
21 #include <iostream>
22 
23 using namespace std;
24 using namespace edm;
25 
26 MagGeometry::MagGeometry(int geomVersion,
27  const std::vector<MagBLayer*>& tbl,
28  const std::vector<MagESector*>& tes,
29  const std::vector<MagVolume6Faces*>& tbv,
30  const std::vector<MagVolume6Faces*>& tev)
31  : MagGeometry(geomVersion,
32  reinterpret_cast<std::vector<MagBLayer const*> const&>(tbl),
33  reinterpret_cast<std::vector<MagESector const*> const&>(tes),
34  reinterpret_cast<std::vector<MagVolume6Faces const*> const&>(tbv),
35  reinterpret_cast<std::vector<MagVolume6Faces const*> const&>(tev)) {}
36 
37 MagGeometry::MagGeometry(int geomVersion,
38  const std::vector<MagBLayer const*>& tbl,
39  const std::vector<MagESector const*>& tes,
40  const std::vector<MagVolume6Faces const*>& tbv,
41  const std::vector<MagVolume6Faces const*>& tev)
43  theBLayers(tbl),
44  theESectors(tes),
45  theBVolumes(tbv),
46  theEVolumes(tev),
48  geometryVersion(geomVersion) {
49  vector<double> rBorders;
50 
51  for (vector<MagBLayer const*>::const_iterator ilay = theBLayers.begin(); ilay != theBLayers.end(); ++ilay) {
53  cout << " Barrel layer at " << (*ilay)->minR() << endl;
54  //FIXME assume layers are already sorted in minR
55  rBorders.push_back((*ilay)->minR());
56  }
57 
59 
60  if (verbose::debugOut) {
61  for (vector<MagESector const*>::const_iterator isec = theESectors.begin(); isec != theESectors.end(); ++isec) {
62  cout << " Endcap sector at " << (*isec)->minPhi() << endl;
63  }
64  }
65 
66  //FIXME assume sectors are already sorted in phi
67  //FIXME: PeriodicBinFinderInPhi gets *center* of first bin
68  int nEBins = theESectors.size();
69  if (nEBins > 0)
70  theEndcapBinFinder = new PeriodicBinFinderInPhi<float>(theESectors.front()->minPhi() + Geom::pi() / nEBins, nEBins);
71 }
72 
74  if (theBarrelBinFinder != nullptr)
75  delete theBarrelBinFinder;
76  if (theEndcapBinFinder != nullptr)
77  delete theEndcapBinFinder;
78 
79  for (vector<MagBLayer const*>::const_iterator ilay = theBLayers.begin(); ilay != theBLayers.end(); ++ilay) {
80  delete (*ilay);
81  }
82 
83  for (vector<MagESector const*>::const_iterator ilay = theESectors.begin(); ilay != theESectors.end(); ++ilay) {
84  delete (*ilay);
85  }
86 }
87 
88 // Return field vector at the specified global point
90  MagVolume const* v = nullptr;
91 
92  v = findVolume(gp);
93  if (v != nullptr) {
94  return v->fieldInTesla(gp);
95  }
96 
97  // Fall-back case: no volume found
98 
99  if (edm::isNotFinite(gp.mag())) {
100  LogWarning("InvalidInput") << "Input value invalid (not a number): " << gp << endl;
101 
102  } else {
103  LogWarning("MagneticField") << "MagGeometry::fieldInTesla: failed to find volume for " << gp << endl;
104  }
105  return GlobalVector();
106 }
107 
108 // Linear search implementation (just for testing)
110  MagVolume6Faces const* found = nullptr;
111 
112  int errCnt = 0;
113  if (inBarrel(gp)) { // Barrel
114  for (vector<MagVolume6Faces const*>::const_iterator v = theBVolumes.begin(); v != theBVolumes.end(); ++v) {
115  if ((*v) == nullptr) { //FIXME: remove this check
116  cout << endl << "***ERROR: MagGeometry::findVolume: MagVolume for barrel not set" << endl;
117  ++errCnt;
118  if (errCnt < 3)
119  continue;
120  else
121  break;
122  }
123  if ((*v)->inside(gp, tolerance)) {
124  found = (*v);
125  break;
126  }
127  }
128 
129  } else { // Endcaps
130  for (vector<MagVolume6Faces const*>::const_iterator v = theEVolumes.begin(); v != theEVolumes.end(); ++v) {
131  if ((*v) == nullptr) { //FIXME: remove this check
132  cout << endl << "***ERROR: MagGeometry::findVolume: MagVolume for endcap not set" << endl;
133  ++errCnt;
134  if (errCnt < 3)
135  continue;
136  else
137  break;
138  }
139  if ((*v)->inside(gp, tolerance)) {
140  found = (*v);
141  break;
142  }
143  }
144  }
145 
146  return found;
147 }
148 
149 // Use hierarchical structure for fast lookup.
151  // Check volume cache
152  auto lastVolumeCheck = lastVolume.load(std::memory_order_acquire);
153  if (lastVolumeCheck != nullptr && lastVolumeCheck->inside(gp)) {
154  return lastVolumeCheck;
155  }
156 
157  MagVolume const* result = nullptr;
158  if (inBarrel(gp)) { // Barrel
159  double R = gp.perp();
160  int bin = theBarrelBinFinder->binIndex(R);
161 
162  // Search up to 3 layers inwards. This may happen for very thin layers.
163  for (int bin1 = bin; bin1 >= max(0, bin - 3); --bin1) {
164  if (verbose::debugOut)
165  cout << "Trying layer at R " << theBLayers[bin1]->minR() << " " << R << endl;
166  result = theBLayers[bin1]->findVolume(gp, tolerance);
167  if (verbose::debugOut)
168  cout << "***In blayer " << bin1 - bin << " " << (result == nullptr ? " failed " : " OK ") << endl;
169  if (result != nullptr)
170  break;
171  }
172 
173  } else { // Endcaps
174  Geom::Phi<float> phi = gp.phi();
175  if (theEndcapBinFinder != nullptr && !theESectors.empty()) {
176  int bin = theEndcapBinFinder->binIndex(phi);
177  if (verbose::debugOut)
178  cout << "Trying endcap sector at phi " << theESectors[bin]->minPhi() << " " << phi << endl;
179  result = theESectors[bin]->findVolume(gp, tolerance);
180  if (verbose::debugOut)
181  cout << "***In guessed esector " << (result == nullptr ? " failed " : " OK ") << endl;
182  } else
183  edm::LogError("MagGeometry") << "Endcap empty";
184  }
185 
186  if (result == nullptr && tolerance < 0.0001) {
187  // If search fails, retry with a 300 micron tolerance.
188  // This is a hack for thin gaps on air-iron boundaries,
189  // which will not be present anymore once surfaces are matched.
190  if (verbose::debugOut)
191  cout << "Increasing the tolerance to 0.03" << endl;
192  result = findVolume(gp, 0.03);
193  }
194 
195  if (cacheLastVolume)
196  lastVolume.store(result, std::memory_order_release);
197 
198  return result;
199 }
200 
202  float Z = fabs(gp.z());
203  float R = gp.perp();
204 
205  // FIXME: Get these dimensions from the builder.
206  if (geometryVersion >= 120812) {
207  return (Z < 350. || (R > 172.4 && Z < 633.29) || (R > 308.735 && Z < 662.01));
208  } else if (geometryVersion >= 90812) { // FIXME no longer supported
209  return (Z < 350. || (R > 172.4 && Z < 633.89) || (R > 308.755 && Z < 662.01));
210  } else { // versions 71212, 90322
211  return (Z < 350. || (R > 172.4 && Z < 633.29) || (R > 308.755 && Z < 661.01));
212  }
213 }
Surface::GlobalVector GlobalVector
Definition: MagGeometry.h:25
T perp() const
Definition: PV3DBase.h:69
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
const double tolerance
std::atomic< MagVolume const * > lastVolume
Definition: MagGeometry.h:64
#define nullptr
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
int binIndex(T phi) const override
returns an index in the valid range for the bin that contains phi
~MagGeometry()
Destructor.
Definition: MagGeometry.cc:73
bool inBarrel(const GlobalPoint &gp) const
Definition: MagGeometry.cc:201
MagVolume const * findVolume(const GlobalPoint &gp, double tolerance=0.) const
Find a volume.
Definition: MagGeometry.cc:150
T mag() const
Definition: PV3DBase.h:64
std::vector< MagESector const * > theESectors
Definition: MagGeometry.h:67
PeriodicBinFinderInPhi< float > const * theEndcapBinFinder
Definition: MagGeometry.h:74
T z() const
Definition: PV3DBase.h:61
MagVolume const * findVolume1(const GlobalPoint &gp, double tolerance=0.) const
Definition: MagGeometry.cc:109
int binIndex(T R) const override
Definition: MagBinFinders.h:62
std::vector< MagBLayer const * > theBLayers
Definition: MagGeometry.h:66
std::vector< MagVolume6Faces const * > theBVolumes
Definition: MagGeometry.h:70
LocalVector fieldInTesla(const LocalPoint &lp) const
Definition: MagVolume.cc:11
HLT enums.
GlobalVector fieldInTesla(const GlobalPoint &gp) const
Return field vector at the specified global point.
Definition: MagGeometry.cc:89
MagGeometry(int geomVersion, const std::vector< MagBLayer * > &, const std::vector< MagESector * > &, const std::vector< MagVolume6Faces * > &, const std::vector< MagVolume6Faces * > &)
Constructor.
Definition: MagGeometry.cc:26
std::vector< MagVolume6Faces const * > theEVolumes
Definition: MagGeometry.h:71
static constexpr bool debugOut
Definition: MagVerbosity.h:17
constexpr double pi()
Definition: Pi.h:31
MagBinFinders::GeneralBinFinderInR< double > const * theBarrelBinFinder
Definition: MagGeometry.h:73
bool cacheLastVolume
Definition: MagGeometry.h:76
int geometryVersion
Definition: MagGeometry.h:77