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

PhotonLookupTable.cxx

Go to the documentation of this file.
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   // Switches to a new validity context.
00029   // 
00030   fResPtr.NewQuery(vc,0);
00031   VldRange newrange = fResPtr.GetValidityRec()->GetVldRange();
00032 
00033   // See if the table has somehow changed.
00034   if( (newrange.GetTimeStart()!=fVldRange.GetTimeStart()) ||
00035       (newrange.GetTimeEnd()!=fVldRange.GetTimeEnd()) ||
00036       ( newrange.GetDetectorMask()!=fVldRange.GetDetectorMask()) ||
00037       ( newrange.GetSimMask()!=fVldRange.GetSimMask()) )  {
00038 
00039     // Table changed. Rebuild the data.
00040     fVldRange = newrange;
00041     Rebuild(); 
00042   }
00043 }
00044 
00045 void PhotonLookupTable::Rebuild()
00046 {
00047   //
00048   // Rebuilds arrays if the DB result changes.
00049   //
00050   fx.clear();
00051   fy.clear();
00052   fint.clear();
00053 
00054   // Use a map to sort the data as it comes in.
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   // Find the nearest entry below value.
00079 
00080   // Binary search. Lifted mercilessly from TMath.cxx
00081   // fx is supposed  to be sorted prior to this call.
00082   // If match is found, function returns position of element.
00083   // If no match found, function gives nearest element smaller than value.
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   // Make the guess.
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     // Ensure the guess paramater isn't silly.
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   // Find the y corresponding to x. Interpolate.
00121   //
00122   int i = BinarySearch(fx,value,true);
00123   //cout << "Binary search: " << i << "\t" << fx[i] << endl;
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   // Pick a random x from the integral of y
00132   // using random number r.
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]); // is 0 to 1
00138   //double yy1 = fy[i]*fy[i];
00139   //double yy2 = fy[i+1]*fy[i+1];
00140   //double dy = fy[i+1]-fy[i];
00141   double fraction;
00142   //if(dy!=0) 
00143   //fraction = (-fy[i] + sqrt(yy1+(yy2-yy1)*r2))/(fy[i+1]-fy[i]);
00144     //else
00145   fraction = r2;
00146   double val = fx[i] + (fx[i+1]-fx[i])*fraction;
00147   
00148   //cout << "Pick: " 
00149   //    << fx[i] << "\t" 
00150   //   << (fraction) << "\t" 
00151   //   << fx[i+1]-fx[i] << "\t" 
00152   //   << val << endl;
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   // Draw a TGraph of the table.
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   // Print out the table.
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 }

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