Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

RangeLookupTable.cxx

Go to the documentation of this file.
00001 #include "RangeLookupTable.h"
00002 #include <TGraph.h>
00003 #include <TH1F.h>
00004 #include <TRandom.h>
00005 #include <iostream>
00006 #include <iomanip>
00007 
00008 using namespace std;
00009 
00010 ClassImp(RangeLookupTable)
00011 
00012 VldContext RangeLookupTable::fgDefaultContext(Detector::kNear,
00013                                               SimFlag::kData,
00014                                               VldTimeStamp());
00015 
00016 RangeLookupTable::RangeLookupTable(const char* tablename, 
00017                                      const VldContext& vc)
00018   : fTableName(tablename),
00019     fResPtr(string(tablename), vc),
00020     fGraph(0)
00021 {
00022   Rebuild();
00023   fVldRange =  fResPtr.GetValidityRec()->GetVldRange();
00024 }
00025 
00026 void RangeLookupTable::Reset(const VldContext& vc)
00027 {
00028   //
00029   // Switches to a new validity context.
00030   // 
00031   fResPtr.NewQuery(vc,0);
00032   VldRange newrange = fResPtr.GetValidityRec()->GetVldRange();
00033 
00034   // See if the table has somehow changed.
00035   if( (newrange.GetTimeStart()!=fVldRange.GetTimeStart()) ||
00036       (newrange.GetTimeEnd()!=fVldRange.GetTimeEnd()) ||
00037       ( newrange.GetDetectorMask()!=fVldRange.GetDetectorMask()) ||
00038       ( newrange.GetSimMask()!=fVldRange.GetSimMask()) )  {
00039 
00040     // Table changed. Rebuild the data.
00041     fVldRange = newrange;
00042     Rebuild(); 
00043   }
00044 }
00045 
00046 void RangeLookupTable::Print(Option_t* /* option */) const
00047 {
00048   //
00049   // Print the values
00050   //
00051   std::cout << "RangeLookupTable " << fTableName 
00052             << " has " << fN << " points." << std::endl;
00053   std::cout << "  indx      Range in Fe     Mu Momentum        Integral"
00054             << std::endl;
00055   std::cout << "            (g/cm^2)        (GeV/c)" 
00056             << std::endl;
00057   for (UInt_t i=0; i < fN ; ++i) {
00058     std::cout << " [ " << std::setw(3) << i << "] "
00059               << setw(15) << setprecision(7) << frange[i] << " " 
00060               << setw(15) << setprecision(7) << fmomentum[i] << " " 
00061               << std::endl;
00062   }
00063   std::cout << resetiosflags(ios::floatfield); // reset to "%g" format
00064   std::cout << setprecision(6);
00065 }
00066 
00067 
00068 void RangeLookupTable::Rebuild()
00069 {
00070   //
00071   // Rebuilds arrays if the DB result changes.
00072   //
00073   frange.clear();
00074   fmomentum.clear();
00075  
00076   // Use a map to sort the data as it comes in.
00077   std::map<double,double> sortMap;
00078   std::map<double,double>::iterator sortMapItr;
00079 
00080   for(UInt_t i=0; i<fResPtr.GetNumRows(); i++) {
00081     sortMap[ fResPtr.GetRow(i)->GetRange() ] =  fResPtr.GetRow(i)->GetMomentum();
00082   }
00083 
00084    for( sortMapItr = sortMap.begin(); sortMapItr != sortMap.end(); sortMapItr++) 
00085 {
00086     frange.push_back(sortMapItr->first);
00087     fmomentum.push_back(sortMapItr->second);
00088   }
00089   fN = frange.size();
00090 
00091 }
00092 
00094 Int_t RangeLookupTable::BinarySearch( std::vector<Double_t> &array,
00095                                        Double_t value, 
00096                                        Bool_t doGuess )
00097 {
00098   // Find the nearest entry below value.
00099 
00100   // Binary search. Lifted mercilessly from TMath.cxx
00101   // fx is supposed  to be sorted prior to this call.
00102   // If match is found, function returns position of element.
00103   // If no match found, function gives nearest element smaller than value.
00104 
00105   Int_t nabove, nbelow, middle;
00106   UInt_t n = array.size();
00107   if(value<=array[0]) return 0;
00108   if(value>=array[n-2]) return n-2;
00109   nabove = n+1;
00110   nbelow = 0;
00111   
00112   // Make the guess.
00113   if(doGuess) {
00114     Double_t guess = (value-array[0])/(array[n-1]-array[0]);
00115     if(guess<0.5) middle = (Int_t)(guess*n) +2;
00116     else          middle = (Int_t)(guess*n) -2;
00117 
00118     // Ensure the guess paramater isn't silly.
00119     if(middle>(Int_t)(n-1)) middle = n-1; 
00120     if(middle<1) middle = 1;
00121       
00122   } else {
00123     middle = (nabove-nbelow)/2;
00124   }
00125   
00126   while(nabove-nbelow > 1) {
00127     if (value == array[middle-1]) return middle-1;
00128     if (value  < array[middle-1]) nabove = middle;
00129     else                          nbelow = middle;
00130     middle = (nabove+nbelow)/2;
00131   }
00132   return nbelow-1;
00133 }
00134 
00135 
00137 Double_t RangeLookupTable::Interpolate( Double_t value )
00138 {
00139   //
00140   // Find the y corresponding to x. Interpolate.
00141   //
00142   int i = BinarySearch(frange,value,true);
00143   //cout << "Binary search: " << i << "\t" << frange[i] << endl;
00144   return (value-frange[i])/(frange[i+1]-frange[i])*(fmomentum[i+1]-fmomentum[i]) + fmomentum[i];
00145 }
00146 
00148 Double_t RangeLookupTable::GetMaximum()
00149 {
00150   double max = -1e20;
00151   for(UInt_t i=0;i<fN;i++) {
00152     if(fmomentum[i]>max) max = fmomentum[i];
00153   }
00154   return max;
00155 }

Generated on Thu Nov 1 11:52:38 2007 for loon by  doxygen 1.3.9.1