LightYieldCorrection.cc

00001 #include "LightYieldCorrection.hh"
00002 #include "utilities.hh"
00003 
00004 #include "EventData.hh"
00005 #include "EventHandler.hh"
00006 
00007 #include "TROOT.h"
00008 #include "TGraph.h"
00009 #include "TH1.h"
00010 #include "TCanvas.h"
00011 #include "TGraphErrors.h"
00012 #include "TCut.h"
00013 #include "TCanvas.h"
00014 #include "TF1.h"
00015 #include "TRandom3.h"
00016 #include "TTree.h"
00017 #include "TAxis.h"
00018 #include "TStyle.h"
00019 #include "TNtuple.h"
00020 #include "TFile.h"
00021 
00022 
00023 #include <iostream>
00024 #include <numeric>
00025 #include <sstream>
00026 
00027 TGraph* MakeFakePulse(TGraph* singlepe, int nphotons, TGraph* output,
00028                       double spe_resolution, double t0, 
00029                       double fprompt, double tslow, 
00030                       double tfast, double jitter, bool use_binomial)
00031 {
00032   //subtract the baseline off of the reference pulse
00033   //GetBaseline(singlepe, 100, true);
00034   
00035   //make a new TGraph if output==0
00036   if(!output){
00037     const int npts = 250*9; // -1 to 8 microseconds, 250 samps/microsec
00038     output = new TGraph(npts, singlepe->GetX(), singlepe->GetY());
00039   }
00040   //first determine when each photon ought to arrive
00041   std::vector<double> initial_times;
00042   std::vector<double> amplitudes;
00043   TRandom3 randgen(0);
00044   //choose how many are in the prompt part from binomial statistics
00045   int nfast = (int)(nphotons * fprompt);
00046   if(use_binomial)
00047     nfast = randgen.Binomial(nphotons, fprompt);
00048   int nslow = nphotons - nfast;
00049   //the arrival time is from an exponential disttribution 
00050   //then convolve with a gaussian jitter
00051   for(int i=0; i < nfast; i++)
00052     initial_times.push_back((randgen.Exp(tfast)+t0) * randgen.Gaus(1,jitter));
00053   for(int i=0; i < nslow; i++)
00054     initial_times.push_back((randgen.Exp(tslow)+t0) * randgen.Gaus(1,jitter));
00055   
00056   //the amplitude is smeared by the resolution
00057   for(int i=0; i < nphotons; i++)
00058     amplitudes.push_back(randgen.Gaus(1,spe_resolution));
00059   
00060   //fill the pulse with our generated photons
00061   double* t = output->GetX();
00062   double t_first = t[0];
00063   double dt = t[1]-t[0];
00064   double* y = output->GetY();
00065   double* yinput = singlepe->GetY();
00066   double tmin = singlepe->GetX()[0];
00067   for(int samp=0; samp < output->GetN(); samp++){
00068     y[samp] = 0;
00069     for(size_t pulse = 0; pulse < initial_times.size(); pulse++){
00070       double eval_time = t[samp] - initial_times[pulse];
00071       if( eval_time < tmin ) continue;
00072       //instead of using Eval, get an exact sample index
00073       y[samp] += yinput[(size_t)((eval_time-t_first)/dt)] * amplitudes[pulse];
00074       //y[samp] += singlepe->Eval(eval_time) * amplitudes[pulse];
00075     }
00076   }
00077   return output;
00078 }
00079     
00080 TGraph* GetNormalizedSPETemplate(int channel)
00081 {
00082   TGraph* singlepe = GetAverageGraph("/data/test_processing/Run000281.root",
00083                                      channel);
00084   //subtract the baseline
00085   GetBaseline(singlepe, 100, true);
00086   //integrate the singlepe over the laser window
00087   //find the laser window from the events tree
00088   TTree* LaserEventsTree = GetEventsTree("/data/test_processing/Run000281.root");
00089   EventData* ev = 0;
00090   LaserEventsTree->SetBranchAddress("EventData", &ev);
00091   LaserEventsTree->GetEntry(0);
00092   int start = ev->GetChannelByID(channel)->regions[0].start_index;
00093   int end = ev->GetChannelByID(channel)->regions[0].end_index;
00094   double* y = singlepe->GetY();
00095   double integral = std::accumulate(y+start, y+end, 0.);
00096   //normalize the template to unit integral
00097   for(int i=0; i < singlepe->GetN(); i++){
00098     y[i] /= integral;
00099   }
00100   return singlepe;
00101 
00102 }
00103 
00104 void TestCorrectionWithNphotons(int channel, int ntrials, int npoints,
00105                                 int min_photons, int photons_step)
00106 {
00107   //define the start and end indices for integration (-0.05 to 7 microseconds)
00108   const int start_index = 238;
00109   const int end_index = 2001;
00110   const int fprompt_start_index = 238;
00111   const int fprompt_end_index = 275;
00112   //first load the singlepe template
00113   TGraph* singlepe = GetNormalizedSPETemplate(channel);
00114   TGraph* output = 0;
00115   //create the output ntuple
00116   std::stringstream fname;
00117   fname<<"analysis/LightYieldCorrection_"<<time(0)<<".root";
00118   std::cout<<"Saving output to file "<<fname.str()<<std::endl;
00119   TFile f(fname.str().c_str(),"RECREATE");
00120   TNtuple tree("yield","Integral vs NPE","npe:integral:fprompt_measured");
00121   for(int point = 0; point < npoints; point++){
00122     int nphotons = min_photons + point * photons_step;
00123     for(int trial = 0; trial < ntrials; trial++){
00124       if(trial%100 == 0){
00125         std::cout<<"Simulating "<<nphotons<<" photons,  trial "
00126                  <<trial<<std::endl;
00127       }
00128       output = MakeFakePulse(singlepe, nphotons, output, 0., -0.18,
00129                              0.25, 1.4,0.007,0.,false);
00130       double* y = output->GetY();
00131       //integrate the fake pulse 
00132       double integral = std::accumulate(y+start_index, y+end_index, 0.);
00133       double fprompt_measured = 
00134         std::accumulate(y+fprompt_start_index, y+fprompt_end_index, 0.) /
00135         integral;
00136       tree.Fill(nphotons, integral, fprompt_measured);
00137     }
00138     //save after every batch
00139     tree.Write("",TObject::kWriteDelete);
00140   }
00141 
00142   f.Close();
00143 }
00144 
00145 void TestCorrectionWithTimeParams(int channel, int ntrials,
00146                                   double t0center, double t0width,
00147                                   double fpromptcenter, double fpromptwidth,
00148                                   double tslowcenter, double tslowwidth)
00149 {
00150   //define the start and end indices for integration (-0.05 to 7 microseconds)
00151   const int start_index = 238;
00152   const int end_index = 2001;
00153   const int fprompt_start_index = 238;
00154   const int fprompt_end_index = 275;
00155   //define the fixed parameters
00156   const int nphotons = 300;
00157   const double spe_resolution = 0.;
00158   
00159   //first load the singlepe template
00160   TGraph* singlepe = GetNormalizedSPETemplate(channel);
00161   TGraph* output = 0;
00162   //create the output ntuple
00163   std::stringstream fname;
00164   fname<<"analysis/LightYieldCorrection_"<<time(0)<<".root";
00165   std::cout<<"Saving output to file "<<fname.str()<<std::endl;
00166   TFile f(fname.str().c_str(),"RECREATE");
00167   TNtuple tree("yield","Integral vs time params",
00168                "npe:integral:fprompt_measured:t0:fprompt:tslow");
00169   TRandom3 myrand(0);
00170   for(int i=0; i < ntrials; i++){
00171     //choose all the appropriate values from random gaussians
00172     double t0 = myrand.Gaus(t0center, t0width);
00173     double fprompt = myrand.Gaus(fpromptcenter,fpromptwidth);
00174     double tslow = myrand.Gaus(tslowcenter, tslowwidth);
00175     if(i%100 == 0)
00176       std::cout<<"Simulating trial "<<i<<std::endl;
00177     output = MakeFakePulse(singlepe, nphotons, output, spe_resolution,
00178                            t0, fprompt, tslow);
00179     double* y = output->GetY();
00180     double integral = std::accumulate(y+start_index, y+end_index, 0.);
00181     double fprompt_measured = 
00182         std::accumulate(y+fprompt_start_index, y+fprompt_end_index, 0.) /
00183         integral;
00184     tree.Fill(nphotons, integral, fprompt_measured, t0, fprompt, tslow);
00185     //save the tree intermittently
00186     if(i%100 == 0)
00187       tree.Write("",TObject::kWriteDelete);
00188   }
00189   //save the tree
00190   tree.Write("",TObject::kWriteDelete);
00191 }
00192 
00193 TGraphErrors* PlotYieldvsNPE(const char* file, int npoints, int min_photons,
00194                              int photons_step, const char* treename)
00195 {
00196   TFile fin(file);
00197   if(!fin.IsOpen())
00198     return 0;
00199   TTree* tree = (TTree*)(fin.Get(treename));
00200   if(!tree)
00201     return 0;
00202   
00203   TH1* hist = 0;
00204   double x[npoints];
00205   double y[npoints];
00206   double ye[npoints];
00207   for(int i=0; i < npoints; i++){
00208     int nphotons = min_photons + i * photons_step;
00209     x[i] = nphotons;
00210     char photoncut[100];
00211     sprintf(photoncut, "npe == %d", nphotons);
00212     tree->Draw("npe/integral",photoncut);
00213     hist = (TH1*)(gROOT->FindObject("htemp"));
00214     if(hist){
00215       y[i] = hist->GetMean();
00216       ye[i] = hist->GetRMS();
00217     }
00218   }
00219   TGraphErrors* g = new TGraphErrors(npoints, x, y, 0, ye);
00220   g->SetTitle("Light Yield Correction vs NPE Generated");
00221   g->GetXaxis()->SetTitle("NPE Generated");
00222   g->GetYaxis()->SetTitle("Light Yield Correction Factor");
00223   g->Draw("alpe");
00224   g->Fit("pol1");
00225   
00226   return g;
00227 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on 20 Jun 2014 for daqman by  doxygen 1.6.1