Belle II Software  release-08-01-10
FieldManager.cc
1 /* Copyright 2008-2010, Technische Universitaet Muenchen,
2  Authors: Christian Hoeppner & Sebastian Neubert & Johannes Rauch
3 
4  This file is part of GENFIT.
5 
6  GENFIT is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published
8  by the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  GENFIT is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with GENFIT. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "FieldManager.h"
20 #include "IO.h"
21 
22 #include <math.h>
23 
24 namespace genfit {
25 
26 FieldManager* FieldManager::instance_ = nullptr;
27 AbsBField* FieldManager::field_ = nullptr;
28 
29 #ifdef CACHE
30 bool FieldManager::useCache_ = false;
31 unsigned int FieldManager::n_buckets_ = 8;
32 fieldCache* FieldManager::cache_ = nullptr;
33 #endif
34 
35 //#define DEBUG
36 
37 #ifdef CACHE
38 void FieldManager::getFieldVal(const double& posX, const double& posY, const double& posZ, double& Bx, double& By, double& Bz){
39  checkInitialized();
40 
41  if (useCache_) {
42 
43  // cache code copied from http://en.wikibooks.org/wiki/Optimizing_C%2B%2B/General_optimization_techniques/Memoization
44  static int last_read_i = 0;
45  static int last_written_i = 0;
46  int i = last_read_i;
47 
48  static const double epsilon = 0.001;
49 
50  #ifdef DEBUG
51  static int used = 0;
52  static int notUsed = 0;
53  #endif
54 
55  do {
56  if (fabs(cache_[i].posX - posX) < epsilon &&
57  fabs(cache_[i].posY - posY) < epsilon &&
58  fabs(cache_[i].posZ - posZ) < epsilon) {
59  Bx = cache_[i].Bx;
60  By = cache_[i].By;
61  Bz = cache_[i].Bz;
62  #ifdef DEBUG
63  ++used;
64  debugOut<<"used the cache! " << double(used)/(used + notUsed) << "\n";
65  #endif
66  return;
67  }
68  i = (i + 1) % n_buckets_;
69  } while (i != last_read_i);
70 
71  last_read_i = last_written_i = (last_written_i + 1) % n_buckets_;
72 
73  cache_[last_written_i].posX = posX;
74  cache_[last_written_i].posY = posY;
75  cache_[last_written_i].posZ = posZ;
76 
77  field_->get(posX, posY, posZ, cache_[last_written_i].Bx, cache_[last_written_i].By, cache_[last_written_i].Bz);
78 
79  Bx = cache_[last_written_i].Bx;
80  By = cache_[last_written_i].By;
81  Bz = cache_[last_written_i].Bz;
82  #ifdef DEBUG
83  ++notUsed;
84  debugOut<<"did NOT use the cache! \n";
85  #endif
86  return;
87 
88  }
89  else
90  return field_->get(posX, posY, posZ, Bx, By, Bz);
91 
92 }
93 
94 
95 void FieldManager::useCache(bool opt, unsigned int nBuckets) {
96  useCache_ = opt;
97  n_buckets_ = nBuckets;
98 
99  if (useCache_) {
100  cache_ = new fieldCache[n_buckets_];
101  for (size_t i = 0; i < n_buckets_; ++i) {
102  // Should be safe to initialize with values in Andromeda
103  cache_[i].posX = cache_[i].posY = cache_[i].posZ = 2.4e24 / sqrt(3);
104  cache_[i].Bx = cache_[i].By = cache_[i].Bz = 1e30;
105  }
106  }
107 }
108 #endif
109 
110 } /* End of namespace genfit */
virtual TVector3 get(const TVector3 &position) const =0
Get the magneticField [kGauss] at position.
void useCache(bool opt=true, unsigned int nBuckets=8)
Cache last lookup positions, and use stored field values if a lookup at (almost) the same position is...
TVector3 getFieldVal(const TVector3 &position)
This does NOT use the cache!
Definition: FieldManager.h:63
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Defines for I/O streams used for error and debug printing.
std::ostream debugOut
Default stream for debug output.