00001 #include "PhotonLookupTable.h"
00002 #include <TGraph.h>
00003 #include <TH1F.h>
00004 #include <TRandom.h>
00005 #include <iostream>
00006
00007 using namespace std;
00008
00009 ClassImp(PhotonLookupTable)
00010
00011 VldContext PhotonLookupTable::fgDefaultContext(Detector::kNear,
00012 SimFlag::kData,
00013 VldTimeStamp() );
00014
00015 PhotonLookupTable::PhotonLookupTable(const char* tablename,
00016 const VldContext& vc)
00017 : fTableName(tablename),
00018 fResPtr(string(tablename), vc),
00019 fGraph(0)
00020 {
00021 Rebuild();
00022 fVldRange = fResPtr.GetValidityRec()->GetVldRange();
00023 }
00024
00025 void PhotonLookupTable::Reset(const VldContext& vc)
00026 {
00027
00028
00029
00030 fResPtr.NewQuery(vc,0);
00031 VldRange newrange = fResPtr.GetValidityRec()->GetVldRange();
00032
00033
00034 if( (newrange.GetTimeStart()!=fVldRange.GetTimeStart()) ||
00035 (newrange.GetTimeEnd()!=fVldRange.GetTimeEnd()) ||
00036 ( newrange.GetDetectorMask()!=fVldRange.GetDetectorMask()) ||
00037 ( newrange.GetSimMask()!=fVldRange.GetSimMask()) ) {
00038
00039
00040 fVldRange = newrange;
00041 Rebuild();
00042 }
00043 }
00044
00045 void PhotonLookupTable::Rebuild()
00046 {
00047
00048
00049
00050 fx.clear();
00051 fy.clear();
00052 fint.clear();
00053
00054
00055 std::map<double,double> sortMap;
00056 std::map<double,double>::iterator sortMapItr;
00057
00058 for(UInt_t i=0; i<fResPtr.GetNumRows(); i++) {
00059 sortMap[ fResPtr.GetRow(i)->GetX() ] = fResPtr.GetRow(i)->GetY();
00060 }
00061
00062 double integral = 0;
00063 for( sortMapItr = sortMap.begin(); sortMapItr != sortMap.end(); sortMapItr++) {
00064 fx.push_back(sortMapItr->first);
00065 fy.push_back(sortMapItr->second);
00066 integral += sortMapItr->second;
00067 fint.push_back(integral);
00068 }
00069 fN = fx.size();
00070
00071 }
00072
00074 Int_t PhotonLookupTable::BinarySearch( std::vector<Double_t> &array,
00075 Double_t value,
00076 Bool_t doGuess )
00077 {
00078
00079
00080
00081
00082
00083
00084
00085 Int_t nabove, nbelow, middle;
00086 UInt_t n = array.size();
00087 if(value<=array[0]) return 0;
00088 if(value>=array[n-2]) return n-2;
00089 nabove = n+1;
00090 nbelow = 0;
00091
00092
00093 if(doGuess) {
00094 Double_t guess = (value-array[0])/(array[n-1]-array[0]);
00095 if(guess<0.5) middle = (Int_t)(guess*n) +2;
00096 else middle = (Int_t)(guess*n) -2;
00097
00098
00099 if(middle>(Int_t)(n-1)) middle = n-1;
00100 if(middle<1) middle = 1;
00101
00102 } else {
00103 middle = (nabove-nbelow)/2;
00104 }
00105
00106 while(nabove-nbelow > 1) {
00107 if (value == array[middle-1]) return middle-1;
00108 if (value < array[middle-1]) nabove = middle;
00109 else nbelow = middle;
00110 middle = (nabove+nbelow)/2;
00111 }
00112 return nbelow-1;
00113 }
00114
00115
00117 Double_t PhotonLookupTable::Interpolate( Double_t value )
00118 {
00119
00120
00121
00122 int i = BinarySearch(fx,value,true);
00123
00124 return (value-fx[i])/(fx[i+1]-fx[i])*(fy[i+1]-fy[i]) + fy[i];
00125 }
00126
00128 Double_t PhotonLookupTable::Pick(Double_t r)
00129 {
00130
00131
00132
00133
00134 double pick = r* fint[fN-1];
00135 int i = BinarySearch(fint,pick);
00136
00137 double r2 = (pick-fint[i])/(fint[i+1]-fint[i]);
00138
00139
00140
00141 double fraction;
00142
00143
00144
00145 fraction = r2;
00146 double val = fx[i] + (fx[i+1]-fx[i])*fraction;
00147
00148
00149
00150
00151
00152
00153
00154 return val;
00155 }
00156
00158 Double_t PhotonLookupTable::GetMaximum()
00159 {
00160 double max = -1e20;
00161 for(UInt_t i=0;i<fN;i++) {
00162 if(fy[i]>max) max = fy[i];
00163 }
00164 return max;
00165 }
00166
00168 TGraph* PhotonLookupTable::GetGraph()
00169 {
00170
00171
00172
00173 if(!fGraph) {
00174 double* x = new double[fN];
00175 double* y = new double[fN];
00176
00177 for(UInt_t i=0;i<fN;i++) {
00178 x[i] = fx[i];
00179 y[i] = fy[i];
00180 }
00181
00182 fGraph = new TGraph(fN,x,y);
00183
00184 delete [] x;
00185 delete [] y;
00186 }
00187
00188 return fGraph;
00189 }
00190
00192 void PhotonLookupTable::Draw(Option_t* option)
00193 {
00194 GetGraph()->Draw(option);
00195 }
00196
00198 TH1* PhotonLookupTable::MakeRandomHisto(Int_t n)
00199 {
00200 TH1* h = new TH1F("tempTableHisto","tempTableHisto",fN*10,fx[0],fx[fN-1]);
00201 TRandom rand;
00202 for(int i=0; i<n; i++) {
00203 h->Fill(Pick(rand.Rndm()));
00204 }
00205 h->Draw();
00206 return h;
00207 }
00208
00209
00210 void PhotonLookupTable::Print(Option_t*) const
00211 {
00212
00213
00214
00215 cout << fTableName << endl;
00216 for(UInt_t i=0; i<fN; i++) {
00217 cout << "\t" << fx[i] << "\t" << fy[i] << endl;
00218 }
00219 }