00001 #include "TH1.h"
00002 #include "TF1.h"
00003 #include "TMath.h"
00004 #include "TSpectrum.h"
00005 #include "TTree.h"
00006 #include "TROOT.h"
00007 #include "TCanvas.h"
00008 #include "TFile.h"
00009 #include "TCut.h"
00010 #include <algorithm>
00011 #include <string>
00012 #include <iomanip>
00013 #include <iostream>
00014
00015
00016 #define NPEAKS 10
00017
00018 enum PARAMETERS {CONSTANT, LAMBDA, MEAN, SIGMA, AMP1, L1 , NPAR, AMP2, L2 };
00019
00020
00021 const char* names[] = {"CONSTANT","LAMBDA", "SPE_MEAN", "SPE_SIGMA", "AMP1", "L1", "AMP2","L2","NPAR"};
00022
00023
00024 Double_t background_func(Double_t* x, Double_t* params)
00025 {
00026 return exp(params[AMP1] + x[0]*params[L1]);
00027
00028 }
00029
00030 Double_t signal_func(Double_t* x, Double_t* params)
00031 {
00032 double signal = 0;
00033
00034 for(int i=1; i<=NPEAKS; i++){
00035 signal += params[CONSTANT] * TMath::Poisson(i,params[LAMBDA])
00036 * TMath::Gaus(x[0], i*params[MEAN], sqrt(i)*params[SIGMA], true);
00037 }
00038
00039 return signal;
00040 }
00041
00042 Double_t SPEFunc(Double_t* x, Double_t* params)
00043 {
00044 return signal_func(x, params) + background_func(x,params);
00045 }
00046
00047 TCut get_time_cut(TTree* tree, TCut chan_cut = "")
00048 {
00049 tree->Draw("channels.pulses.start_index >> h_start_index",chan_cut);
00050 TH1F* h_start_index = (TH1F*)(gROOT->FindObject("h_start_index"));
00051 int centerbin = h_start_index->GetMaximumBin();
00052 int lowbin = centerbin, highbin = centerbin;
00053 while( h_start_index->GetBinContent(lowbin-1) <
00054 h_start_index->GetBinContent(lowbin) ) lowbin--;
00055 while( h_start_index->GetBinContent(highbin+1) <
00056 h_start_index->GetBinContent(highbin) ) highbin++;
00057
00058 char cutstr[100];
00059 sprintf(cutstr, "channels.pulses.start_index > %.1f && channels.pulses.start_index < %.1f", h_start_index->GetBinLowEdge(lowbin),
00060 h_start_index->GetBinLowEdge(highbin+1) );
00061 return TCut(cutstr);
00062 }
00063
00064
00065 int FitSPE(TH1* spe, int ntriggers)
00066 {
00067 double fitmin, fitmax;
00068 double params[NPAR];
00069
00070 params[MEAN] = spe->GetMean();
00071 params[SIGMA] = spe->GetRMS();
00072 int bin = spe->FindBin(params[MEAN]);
00073 if(spe->GetMaximumBin() == 1){
00074 spe->Fit("gaus","Q0","",spe->GetBinCenter(bin),
00075 spe->GetBinCenter(bin+20));
00076 }
00077 else{
00078 spe->Fit("gaus","Q0","",spe->GetBinCenter(bin-10),
00079 spe->GetBinCenter(bin+10));
00080 }
00081 TF1* gaus = spe->GetFunction("gaus");
00082 if(gaus->GetParameter(1) > 0)
00083 params[MEAN] = gaus->GetParameter(1);
00084 if(gaus->GetParameter(2) > 0 && gaus->GetParameter(2) < params[SIGMA])
00085 params[SIGMA] = gaus->GetParameter(2);
00086
00087 params[LAMBDA] = 0.5;
00088
00089 bin = spe->GetNbinsX();
00090 while(spe->GetBinContent(--bin) < 2) {}
00091 fitmax = spe->GetBinCenter(bin);
00092
00093 spe->Fit("expo","Q0","",spe->GetBinCenter(bin), spe->GetBinCenter(bin-10));
00094
00095
00096
00097 bin = spe->FindBin(params[MEAN]) - 5;
00098 double compval = spe->GetBinContent(bin--);
00099 while(spe->GetBinContent(bin) < compval && spe->GetBinContent(bin) != 0){
00100 compval = spe->GetBinContent(bin--);
00101 }
00102 if(spe->GetBinContent(bin) == 0){
00103 fitmin = spe->GetBinCenter(bin+1);
00104 }
00105 else{
00106 ++bin;
00107
00108 int minbin = bin;
00109 compval = spe->GetBinContent(bin--);
00110 while(spe->GetBinContent(bin) > compval && bin > 0 ){
00111 compval = spe->GetBinContent(bin--);
00112 }
00113 ++bin;
00114 spe->Fit("expo","Q0","",spe->GetBinCenter(bin), spe->GetBinCenter(minbin));
00115 params[AMP1] = spe->GetFunction("expo")->GetParameter(0);
00116 params[L1] = spe->GetFunction("expo")->GetParameter(1);
00117 fitmin = spe->GetBinCenter(bin+1);
00118 }
00119
00120
00121
00122 params[CONSTANT] = ntriggers * spe->GetBinWidth(1);
00123 fitmin = spe->GetBinCenter(4);
00124
00125 TF1* spefunc = new TF1("spefunc", SPEFunc, fitmin, fitmax, NPAR);
00126
00127
00128 spefunc->SetParameters(params);
00129 for(int i=0; i<NPAR; i++)
00130 spefunc->SetParName(i, names[i]);
00131 spefunc->SetParLimits(CONSTANT, 0 , params[CONSTANT]*100.);
00132 spefunc->SetParLimits(LAMBDA, 0, 2);
00133 spefunc->SetParLimits(MEAN, std::max(params[MEAN]-params[SIGMA],0.),
00134 params[MEAN]+params[SIGMA]);
00135 spefunc->SetParLimits(SIGMA, 0, spe->GetRMS());
00136
00137 spefunc->SetParLimits(L1, -30, 0);
00138 spefunc->SetParLimits(AMP1, -30, 30);
00139 spefunc->SetParLimits(L2, -30, 0);
00140 spefunc->SetParLimits(AMP2, -30, 30);
00141
00142
00143
00144
00145 spefunc->SetLineStyle(1);
00146 spefunc->SetLineColor(kBlue);
00147 int result = spe->Fit(spefunc,"MRNI");
00148 spefunc->DrawCopy("same");
00149 std::cout<<"Fit results: \n"<<
00150 "\t Chi2/NDF = "<<spefunc->GetChisquare()<<"/"<<spefunc->GetNDF()
00151 <<"\n\t Prob = "<<spefunc->GetProb()<<std::endl;
00152 for(int i=0; i<NPAR; i++)
00153 params[i] = spefunc->GetParameter(i);
00154 TF1* background = new TF1("background",background_func,fitmin,fitmax,NPAR);
00155 background->SetLineColor(kRed);
00156 background->SetParameters(spefunc->GetParameters());
00157 background->DrawCopy("same");
00158
00159 TF1* signal = new TF1("signal",signal_func,fitmin,fitmax,NPAR);
00160 signal->SetLineColor(kGreen);
00161 signal->SetParameters(spefunc->GetParameters());
00162 signal->DrawCopy("same");
00163
00164 TF1* apeak = new TF1("apeak","[0]*TMath::Gaus(x,[1],[2],1)",fitmin, fitmax);
00165 apeak->SetLineColor(kMagenta);
00166 apeak->SetLineStyle(2);
00167 for(int i=1; i<=NPEAKS; i++){
00168 apeak->SetParameters(params[CONSTANT]*TMath::Poisson(i,params[LAMBDA]),
00169 i*params[MEAN], sqrt(i)*params[SIGMA]);
00170 apeak->DrawCopy("same");
00171 }
00172 cout<<"Entries in Events tree: "<<ntriggers<<"; Poisson trials: "
00173 <<params[CONSTANT] / spe->GetBinWidth(1)<<std::endl;
00174
00175 return result;
00176 }
00177
00178 int ProcessSPEFile(const char* fname, Long_t roi = -1, int channel = -1)
00179 {
00180 TCanvas* c = new TCanvas;
00181 c->SetLogy();
00182 c->SetTitle(fname);
00183 static bool loaded = false;
00184 if(!loaded){
00185 gROOT->ProcessLine(".L lib/libDict.so");
00186 loaded = true;
00187 }
00188
00189 TFile* fin = new TFile(fname);
00190 if(!fin->IsOpen()){
00191 std::cerr<<"Unable to open file "<<fname<<std::endl;
00192 return 1;
00193 }
00194
00195 TTree* Events = (TTree*)(fin->Get("Events"));
00196 if(!Events){
00197 std::cerr<<"Unable to load Events tree from file "<<fname<<std::endl;
00198 return 2;
00199 }
00200 TString data_source;
00201 if(roi == -1) data_source = "channels.pulses.integral";
00202 else data_source = TString("-channels.regions[") + roi
00203 + TString("].integral");
00204 Events->Draw(data_source+" >> htemp",data_source+" > 0");
00205
00206 TH1* htemp = (TH1*)(gROOT->FindObject("htemp"));
00207 double emax = htemp->GetMean()*5;
00208
00209 TCut min_en = (data_source+" > 0").Data();
00210 char chstring[100];
00211 sprintf(chstring,data_source+" < %.0f",emax);
00212 TCut max_en = chstring;
00213 sprintf(chstring,"channels.channel_id == %d",channel);
00214 TCut chan_cut = (channel == -1 ? "" : chstring);
00215
00216 TCut time_cut = (roi == -1 ? get_time_cut(Events, chan_cut) : "" );
00217
00218 TCut total_cut = min_en && max_en && time_cut && chan_cut;
00219
00220 Events->Draw(data_source+" >> hspec",total_cut,"e");
00221 TH1* hspec = (TH1*)(gROOT->FindObject("hspec"));
00222
00223
00224 int val = FitSPE(hspec, Events->GetEntries());
00225
00226 return val;
00227 }
00228