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
00030
00031 fResPtr.NewQuery(vc,0);
00032 VldRange newrange = fResPtr.GetValidityRec()->GetVldRange();
00033
00034
00035 if( (newrange.GetTimeStart()!=fVldRange.GetTimeStart()) ||
00036 (newrange.GetTimeEnd()!=fVldRange.GetTimeEnd()) ||
00037 ( newrange.GetDetectorMask()!=fVldRange.GetDetectorMask()) ||
00038 ( newrange.GetSimMask()!=fVldRange.GetSimMask()) ) {
00039
00040
00041 fVldRange = newrange;
00042 Rebuild();
00043 }
00044 }
00045
00046 void RangeLookupTable::Print(Option_t* ) const
00047 {
00048
00049
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);
00064 std::cout << setprecision(6);
00065 }
00066
00067
00068 void RangeLookupTable::Rebuild()
00069 {
00070
00071
00072
00073 frange.clear();
00074 fmomentum.clear();
00075
00076
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
00099
00100
00101
00102
00103
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
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
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
00141
00142 int i = BinarySearch(frange,value,true);
00143
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 }