CMS 3D CMS Logo

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