spefit.cc

00001 /* 
00002 Fit SPE spectra on individual channels and upload results to scenedb
00003 @author Charles Cao
00004 */
00005 
00006 
00007 //include all header files as in laserrun except ones know won't need
00008 #include "TNamed.h"
00009 #include "TString.h"
00010 #include "TCanvas.h"
00011 #include "EventData.hh"
00012 #include "TRint.h"
00013 #include "utilities.hh"
00014 #include "RootGraphix.hh"
00015 #include "CommandSwitchFunctions.hh"
00016 #include "ChanFitSettings.hh"
00017 #include <sstream>
00018 #include <fstream>
00019 #include <map>
00020 #include <vector>
00021 #include <iostream>
00022 #include <iomanip>
00023 #include <cstdlib>
00024 #include "TTree.h"
00025 #include "TFile.h"
00026 #include "TF1.h"
00027 #include "TH1F.h"
00028 
00029 using namespace std;
00030 
00031 
00032 const int mNCHANS = 2; // No. of pmt channels
00033 const double max_spe_length = 0.12; // spe length cut
00034 
00035 void PrintResults(std::map<int, TH1F*>* spectra){
00036   cout<<"Fit results are:"<<endl;
00037   cout<<"Ch\t"
00038       <<"mean\t"
00039       <<"mean_er\t"
00040       <<"sigma\t"
00041       <<"Chi2\t"
00042       <<"NDF\t"
00043       <<"Height1\t"
00044       <<"Height2\t"
00045       <<"Height3\t"
00046       <<"Height4"<<endl;
00047   map<int, TH1F*>::iterator it = spectra->begin();
00048   for(; it != spectra->end(); it++){
00049     TH1F* hist = it->second;
00050     TF1* spefunc = hist->GetFunction("spef");
00051     if(spefunc){
00052       int Channel = it->first;
00053       double Pdfmean = spefunc->GetParameter(0);
00054       double Pdfmean_err = spefunc->GetParError(0);
00055       double Pdfsigma = spefunc->GetParameter(1);
00056       double Chi2 = spefunc->GetChisquare();
00057       int Ndf = spefunc->GetNDF();
00058       double Height1 = spefunc->GetParameter(2);
00059       double Height2 = spefunc->GetParameter(3);
00060       double Height3 = spefunc->GetParameter(4);
00061       double Height4 = spefunc->GetParameter(5);
00062       cout<<Channel<<"\t"
00063           <<setprecision(4)<<Pdfmean<<"\t"
00064           <<setprecision(2)<<Pdfmean_err<<"\t"
00065           <<setprecision(3)<<Pdfsigma<<"\t"
00066           <<setprecision(4)<<Chi2<<"\t"
00067           <<Ndf<<"\t"
00068           <<setprecision(2)<<Height1<<"\t"
00069           <<setprecision(2)<<Height2<<"\t"
00070           <<setprecision(2)<<Height3<<"\t"
00071           <<setprecision(2)<<Height4<<endl;
00072     }
00073   }
00074   cout<<endl;
00075 }
00076 
00077 void DrawSpectra(map<int, TH1F*>* spectra, TCanvas* c){
00078   c->Clear();
00079   DividePad(c,spectra->size());
00080   int padn=1;
00081   for( std::map<int,TH1F*>::iterator it = spectra->begin(); it != spectra->end(); it++){
00082     c->cd(padn++);
00083     gPad->SetLogy();
00084     TH1* hist = (it->second);
00085     hist->Draw();
00086   }
00087   c->cd(0);    
00088   //c->Draw();
00089   c->Update();
00090 }
00091 
00092 void FitSPE(TH1F* spe, ChanFitSettings& CFS){
00093   float height1_start_value = spe->GetMaximum();
00094   float mean_start_value = spe->GetMaximumBin()+spe->GetXaxis()->GetXmin();
00095   //cout<< height1_start_value << ",, "<<mean_start_value<<endl;
00096   // Define spe fit function, sum of gaussians from 1 p.e. up to 4 p.e.
00097   TF1 *spef = new TF1("spef", "[2]*exp(-(x-[0])^2/(2*[1]^2))+[3]*exp(-(x-[0]*2)^2/(2*(2*[1]^2)))+[4]*exp(-(x-[0]*3)^2/(2*(3*[1]^2)))+[5]*exp(-(x-[0]*4)^2/(2*(4*[1]^2)))", mean_start_value, CFS.range_max);
00098   
00099   // Fit once with user specified range
00100   //spef->SetParameters(CFS.mean_start_value, CFS.sigma_start_value, CFS.constant_start_value, 0.1*CFS.constant_start_value, 0.01*CFS.constant_start_value, 0.001*CFS.constant_start_value);
00101   spef->SetParameters(mean_start_value, CFS.sigma_start_value, height1_start_value, 0.1*height1_start_value, 0.01*height1_start_value, 0.001*height1_start_value);
00102   spef->SetParNames("spe_mean","spe_sigma","height1","height2","height3","height4");
00103   spef->SetParLimits(1, 0, 20);
00104   spe->Fit("spef","MRE");
00105   
00106   double mean = spef->GetParameter(0);
00107   double sigma = spef->GetParameter(1);
00108   double height1 = spef->GetParameter(2);
00109   double height2 = spef->GetParameter(3);
00110   double height3 = spef->GetParameter(4);
00111   double height4 = spef->GetParameter(5);
00112 
00113   // Modify fit range and start values, and fit again
00114   double fitmin = mean - sigma;
00115   if (fitmin<CFS.pedrange_max) fitmin = CFS.pedrange_max; 
00116   spef->SetRange(fitmin, 4.0*mean);
00117   spef->SetParameters(mean,sigma,height1,height2,height3,height4);
00118   spef->SetLineColor(kRed);
00119   spe->Fit("spef","MRE");
00120   return;
00121 }
00122 
00123 void UpdateDatabase(map<int,TH1F*>* spectra, TTree* Events){
00124   //dummy function
00125   return;
00126 }
00127 
00128 void QueryUser(map<int, TH1F*>* spectra, RootGraphix* root, TTree* Events, TCanvas* c){
00129   bool showresults=true;
00130   string response = "";
00131   while(response != "q"){
00132     if(showresults){
00133       RootGraphix::Lock lock = root->AcquireLock();
00134       DrawSpectra(spectra, c);
00135       PrintResults(spectra);
00136     }
00137     showresults=false;
00138     cout<<"Enter \n q) to quit, \n"
00139         <<" r) to reprint the results, \n"
00140         <<endl;
00141     cin >> response;
00142     if(response == "q"){
00143       cout<<"Aborting without saving results."<<endl;
00144       break;
00145     }
00146     if(response == "r"){
00147       showresults=true;
00148     }
00149     
00150   }
00151   if(c) delete c;
00152 }
00153 
00154 int ProcessRun(const char* fname){
00155   //open the root file
00156   RootGraphix root;
00157   root.Initialize();
00158   TTree* Events = GetEventsTree(fname);
00159   if (!Events) {
00160     cout<<"!Events"<<endl; 
00161     return -1;
00162   }
00163   EventData* event = 0;
00164   Events->SetBranchAddress("event",&event);
00165   Events->GetEntry(0);  
00166   // Print run id, no. of channels and no. of events
00167   int run = event->run_id;
00168   if(run < 0){
00169     std::cerr<<"Unable to read runid from rootfile! Aborting."<<std::endl;
00170     return -1;
00171   }
00172   int nChans = event->channels.size();
00173   cout<<"Processing Run "<<run<<" with "<<nChans<<" channels."<<endl;
00174   cout<<"There are "<<Events->GetEntries()<<" events in this run."<<endl;
00175 
00176   // Load fit parameters
00177   ParameterList* ChanSettingsHandler = new ParameterList("ChannelsSettings","Stores channels of fit settings");
00178   ChanFitSettings ChannelsSettings[mNCHANS];
00179   for(int j=0; j< mNCHANS; j++){
00180     stringstream name;
00181     stringstream help;
00182     name<<"chan"<<j;
00183     help<<"Fit settings for channel "<<j;
00184     ChanSettingsHandler->RegisterParameter(name.str(),ChannelsSettings[j], help.str());
00185   }
00186   ifstream CFSConfig("cfg/speCFS.cfg");
00187   ChanSettingsHandler->ReadFrom(CFSConfig);
00188   CFSConfig.close();
00189 
00190   const int nbins=240;
00191   const double start=-40, end=200; 
00192   std::map<int,TH1F*> spectra;
00193   
00194   // Populate histograms
00195   for(int i=0; i < Events->GetEntries(); i++){
00196     if(i%5000 == 0) cout<<"Processing Entry "<<i<<endl;
00197     Events->GetEntry(i);
00198     // Loop over all pmt channels
00199     for(int j=0; j < mNCHANS; j++){
00200       ChannelData* channel = &(event->channels.at(j));
00201       if(channel->channel_id < 0){
00202         cout<<"channel->channel_id < 0"<<endl;
00203         continue;
00204       }
00205       if(!channel->baseline.found_baseline){
00206         continue;
00207       }
00208       std::map<int,TH1F*>::iterator mapit = spectra.find(channel->channel_id);
00209       TH1F* histo=0;
00210       if(mapit == spectra.end()){
00211         TString name = "channel";
00212         name += channel->channel_id;
00213         cout<<"Creating new histogram with name "<<name<<endl;
00214         histo = new TH1F(name,name,nbins,start,end);
00215         spectra.insert(std::make_pair(channel->channel_id, histo));
00216       }
00217       else{
00218         histo = (mapit->second);
00219       }
00220       //fill the histogram
00221       if(!histo){
00222         cerr<<"Null pointer passed!\n";
00223         return -2;
00224       }
00225       for(size_t n=0; n<channel->single_pe.size(); n++){
00226         //Cuts
00227         if (channel->single_pe[n].length>max_spe_length) continue;
00228         // passing all cuts
00229         histo->Fill(channel->single_pe[n].integral);
00230       }
00231     }
00232   }
00233   cout<<endl<<"About to fit"<<endl;
00234   //Draw all the histograms
00235   root.AcquireLock();
00236   TCanvas* c = new TCanvas("c",fname);
00237   c->SetWindowSize(2*c->GetWw(),c->GetWh());
00238   for(std::map<int,TH1F*>::iterator it = spectra.begin(); it != spectra.end(); it++){
00239     TH1F* hist = (it->second);
00240     cout<<endl<<"About to fit channel: "<<it->first<<endl<<endl;
00241     FitSPE(hist, ChannelsSettings[it->first]);
00242     cout<<endl<<"Done fitting channel: "<<it->first<<endl<<endl;
00243   } 
00244   QueryUser(&spectra, &root, Events, c);
00245   return 0;
00246 }
00247 
00248 
00249 int main( int argc, char** argv){
00250   if (argc != 2){
00251     cout<<"Usage: specfit <genroot-output-filename>"<<endl;
00252     return -1;
00253   } 
00254   //generate the run filename; make sure root file is there manually!
00255   std::stringstream rootfile;
00256   rootfile<<argv[1]; //to enter location explicitly at command line
00257   return ProcessRun(rootfile.str().c_str());
00258 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on 20 Jun 2014 for daqman by  doxygen 1.6.1