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