/* Copyright 2008-2010, Technische Universitaet Muenchen, Authors: Christian Hoeppner & Sebastian Neubert & Johannes Rauch This file is part of GENFIT. GENFIT is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. GENFIT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with GENFIT. If not, see . */ #include "FieldManager.h" #include #include namespace genfit { FieldManager* FieldManager::instance_ = NULL; AbsBField* FieldManager::field_ = NULL; #ifdef CACHE bool FieldManager::useCache_ = false; unsigned int FieldManager::n_buckets_ = 8; fieldCache* FieldManager::cache_ = NULL; #endif //#define DEBUG #ifdef CACHE void FieldManager::getFieldVal(const double& posX, const double& posY, const double& posZ, double& Bx, double& By, double& Bz){ checkInitialized(); if (useCache_) { // cache code copied from http://en.wikibooks.org/wiki/Optimizing_C%2B%2B/General_optimization_techniques/Memoization static int last_read_i = 0; static int last_written_i = 0; int i = last_read_i; static const double epsilon = 0.001; #ifdef DEBUG static int used = 0; static int notUsed = 0; #endif do { if (fabs(cache_[i].posX - posX) < epsilon && fabs(cache_[i].posY - posY) < epsilon && fabs(cache_[i].posZ - posZ) < epsilon) { Bx = cache_[i].Bx; By = cache_[i].By; Bz = cache_[i].Bz; #ifdef DEBUG ++used; std::cout<<"used the cache! " << double(used)/(used + notUsed) << "\n"; #endif return; } i = (i + 1) % n_buckets_; } while (i != last_read_i); last_read_i = last_written_i = (last_written_i + 1) % n_buckets_; cache_[last_written_i].posX = posX; cache_[last_written_i].posY = posY; cache_[last_written_i].posZ = posZ; field_->get(posX, posY, posZ, cache_[last_written_i].Bx, cache_[last_written_i].By, cache_[last_written_i].Bz); Bx = cache_[last_written_i].Bx; By = cache_[last_written_i].By; Bz = cache_[last_written_i].Bz; #ifdef DEBUG ++notUsed; std::cout<<"did NOT use the cache! \n"; #endif return; } else return field_->get(posX, posY, posZ, Bx, By, Bz); } void FieldManager::useCache(bool opt, unsigned int nBuckets) { useCache_ = opt; n_buckets_ = nBuckets; if (useCache_) { cache_ = new fieldCache[n_buckets_]; for (size_t i = 0; i < n_buckets_; ++i) { // Should be safe to initialize with values in Andromeda cache_[i].posX = cache_[i].posY = cache_[i].posZ = 2.4e24 / sqrt(3); cache_[i].Bx = cache_[i].By = cache_[i].Bz = 1e30; } } } #endif } /* End of namespace genfit */