00001
00002
00003
00004
00005
00006
00007 #include "FitOverROI.hh"
00008 #include "FitTH1F.hh"
00009 #include "TNamed.h"
00010 #include "TString.h"
00011 #include "TCanvas.h"
00012 #include "EventData.hh"
00013 #include "TRint.h"
00014 #include "utilities.hh"
00015 #include "RootGraphix.hh"
00016 #include <sstream>
00017 #include <fstream>
00018 #include <map>
00019 #include <vector>
00020 #include <iostream>
00021 #include <iomanip>
00022 #include <cstdlib>
00023 #include "TTree.h"
00024 #include "TFile.h"
00025 #include "TF1.h"
00026
00027 #include "TMath.h"
00028 #include "TROOT.h"
00029 #include "TFitResult.h"
00030 #include "TSpectrum.h"
00031 #include "TPad.h"
00032 #include "TLine.h"
00033 #include "TAxis.h"
00034 #include "TList.h"
00035 #include "TCut.h"
00036 #include "TGraph.h"
00037 #include "TGraphErrors.h"
00038 #include <algorithm>
00039 #include <numeric>
00040 #include <string>
00041 #include "TMultiGraph.h"
00042 #include "TAttMarker.h"
00043 #include "TStyle.h"
00044 #include "TAttLine.h"
00045
00046
00047 using namespace std;
00048
00049 class tab{
00050 public:
00051 int n;
00052 char f;
00053 tab(int nspaces, char fill=' ') : n(nspaces),f(fill) {}
00054 };
00055
00056
00057 double base_start_time = -1;
00058 double base_end_time = -0.2;
00059 double sample_rate = 250.;
00060 double fit_min = 1.0;
00061 double fit_max = 6.0;
00062 bool background = true;
00063
00064 #define mLifetime 1.5;
00065 #define mShot_noise 0.5;
00066 #define mAmplitude 10000; //10 basic avg, 10000 sum, .001 energy
00067 #define mConst 0;
00068
00069 ostream& operator<<(ostream& out, tab t)
00070 { return out<<left<<setfill(t.f)<<setw(t.n); }
00071
00072
00073 Double_t ExpFunc(double* x, double* params) {
00074 double y = x[0];
00075 double lifetime = params[0];
00076
00077 double scale = params[2];
00078 double constant = params[3];
00079 double funct = TMath::Power(TMath::E(),-y/lifetime);
00080
00081
00082
00083
00084
00085
00086
00087 return scale*funct+constant;
00088 }
00089
00090
00091
00092 void DrawMany(map<int, TGraphErrors*>* avgwaveforms, RootGraphix* root, TCanvas* c) {
00093 c->Clear();
00094 int padn=1;
00095 DividePad(c, avgwaveforms->size());
00096 int color = 1;
00097 for( std::map<int,TGraphErrors*>::iterator it = avgwaveforms->begin();
00098 it != avgwaveforms->end(); it++) {
00099 c->cd(padn++);
00100 RootGraphix::Lock lock = root->AcquireLock();
00101 gPad->SetLogy();
00102 TGraphErrors* graph = (it->second);
00103 TAxis* xaxis = graph->GetXaxis();
00104 xaxis->SetRangeUser(-2, 10);
00105 TAxis* yaxis = graph->GetYaxis();
00106 yaxis->SetRangeUser(1., yaxis->GetXmax());
00107 graph->SetLineColor(color);
00108 graph->SetMarkerColor(color);
00109 graph->Draw("ALP");
00110
00111 }
00112 c->cd(0);
00113 c->Update();
00114
00115 }
00116
00117 void DrawSingle(TGraphErrors* graph, RootGraphix* root, TCanvas* c) {
00118 c->Clear();
00119 RootGraphix::Lock lock = root->AcquireLock();
00120 gPad->SetLogy();
00121 TAxis* xaxis = graph->GetXaxis();
00122 xaxis->SetRangeUser(-2, 10);
00123 xaxis->SetTitle("time [#mus]");
00124 graph->Draw("ALP");
00125 c->Update();
00126 }
00127
00128 void PlotResiduals(TGraphErrors* graph, RootGraphix* root, TCanvas* c) {
00129 c->Clear();
00130 RootGraphix::Lock lock = root->AcquireLock();
00131 TF1* func = graph->GetFunction("exp_func_f");
00132 double* x = graph->GetX();
00133 double* y = graph->GetY();
00134 int nsamps = graph->GetN();
00135 double resid_x[nsamps];
00136 double resid_y[nsamps];
00137
00138 for (int i=0; i<nsamps; i++) {
00139 resid_x[i] = x[i];
00140 if (x[i]<fit_min) {
00141 resid_y[i] = 0;
00142 }
00143 else {
00144 resid_y[i] = y[i]-func->Eval(x[i]);
00145 }
00146 }
00147 TGraph* residuals = new TGraph(nsamps, resid_x, resid_y);
00148 residuals->SetTitle(graph->GetTitle());
00149 TAxis* xaxis = residuals->GetXaxis();
00150 xaxis->SetRangeUser(func->GetXmin(), func->GetXmax());
00151 xaxis->SetTitle("time [#mus]");
00152 TAxis* yaxis = residuals->GetYaxis();
00153 yaxis->SetTitle("residuals [a.u.]");
00154 residuals->SetMarkerStyle(kFullDotMedium);
00155 residuals->Draw("AP");
00156 c->SetGridy(1);
00157 c->Update();
00158 }
00159
00160 int TimeToSample(double time, double sample_rate, int trigger_index, int split) {
00161 int samp = (int)(time*sample_rate+trigger_index);
00162 samp = (int)TMath::Floor((double) samp / (double) split );
00163 return samp;
00164 }
00165
00166
00167 void Baseline(double* baseline_mean, double* baseline_var, TGraphErrors* graph, int split) {
00168 double* y = graph->GetY();
00169 double* x = graph->GetX();
00170 double baseline = 0;
00171 double sumsq = 0;
00172 const int trigger_index = (int)TMath::Floor(sample_rate*TMath::Abs(x[0]));
00173 const int base_start_index = TimeToSample(base_start_time, sample_rate, trigger_index, split);
00174 const int base_end_index = TimeToSample(base_end_time, sample_rate, trigger_index, split);
00175 for (int i = base_start_index; i<base_end_index; i++) {
00176 baseline += y[i]/((double) base_end_index - (double) base_start_index);
00177 sumsq += y[i]*y[i]/((double) base_end_index - (double) base_start_index);
00178 }
00179 *baseline_var = sumsq - baseline*baseline;
00180 *baseline_mean = baseline;
00181
00182 }
00183
00184
00185
00186 void Loop(void (*func)(TGraphErrors* wave, int),
00187 map<int, map<int, TGraphErrors*> >* split_waves, int split) {
00188 for (map<int, map<int, TGraphErrors*> >::iterator it = split_waves->begin();
00189 it != split_waves->end(); it++) {
00190 for (map<int, TGraphErrors*>::iterator it2 = it->second.begin();
00191 it2 != it->second.end(); it2++) {
00192 TGraphErrors* wave = it2->second;
00193 (*func)(wave, split);
00194 }
00195 }
00196 }
00197
00198
00199 void AddBaselineErrors(TGraphErrors* wave, int nSplit) {
00200 double* ey = wave->GetEY();
00201 double baseline_mean = 0;
00202 double baseline_var = 0;
00203 Baseline(&baseline_mean, &baseline_var, wave, nSplit);
00204 for (int i=0; i<wave->GetN(); i++) {
00205 ey[i] = sqrt(baseline_var+ey[i]*ey[i]);
00206 }
00207 }
00208
00209 void loopAddBaselineErrors(map<int, map<int, TGraphErrors*> >* split_waves_by_ch, int nSplit) {
00210 Loop(AddBaselineErrors, split_waves_by_ch, nSplit);
00211 }
00212
00213
00214 void Subtract(TGraphErrors* wave, int nSplit) {
00215 double baseline_mean = 0;
00216 double baseline_var = 0;
00217 Baseline(&baseline_mean, &baseline_var, wave, nSplit);
00218 double* y = wave->GetY();
00219 for (int i=0; i<wave->GetN(); i++) {
00220 y[i] = y[i] - baseline_mean;
00221 }
00222 }
00223
00224 void loopSubtract(map<int, map<int, TGraphErrors*> >* split_waves_by_split, int nSplit) {
00225 Loop(Subtract, split_waves_by_split, nSplit);
00226 }
00227
00228
00229 void Fit(TGraphErrors* wave, int nSplit) {
00230
00231 int nparams = 4;
00232 double params[nparams];
00233 params[0] = mLifetime;
00234 params[1] = mShot_noise;
00235 params[2] = mAmplitude
00236 params[3] = mConst;
00237
00238 TF1* exp_func_f = new TF1("exp_func_f",ExpFunc,fit_min, fit_max, nparams);
00239
00240 exp_func_f->SetLineColor(kGreen);
00241 exp_func_f->SetParameters(params);
00242 exp_func_f->SetLineWidth(3);
00243 exp_func_f->SetParNames("lifetime","shot_noise","scale","constant");
00244 exp_func_f->FixParameter(1, 0);
00245 if (!background)
00246 exp_func_f->FixParameter(3, 0);
00247 TFitResultPtr fit_result = wave->Fit(exp_func_f,"MRE+");
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 }
00270
00271 void loopFit(map<int, map<int, TGraphErrors*> >* split_waves, int nSplit) {
00272 Loop(Fit, split_waves, nSplit);
00273 }
00274
00275
00276 void Split(map<int, TGraphErrors*>* avgwaveforms, map<int, map<int,TGraphErrors*> >* split_waves, int split) {
00277
00278
00279 for (std::map<int,TGraphErrors*>::iterator it = avgwaveforms->begin();
00280 it != avgwaveforms->end(); it++) {
00281 TGraphErrors* avggraph = (it->second);
00282 int splitN = (int)TMath::Floor((double) avggraph->GetN()/(double) split);
00283
00284 double* x = avggraph->GetX();
00285 double* y = avggraph->GetY();
00286 double* ey = avggraph->GetEY();
00287
00288 int ch = (it->first);
00289 std::map<int,TGraphErrors*> waves;
00290 int n = (it->first);
00291 char name[25];
00292 for (int i=0; i<split; i++) {
00293 TGraphErrors* graph = new TGraphErrors(splitN);
00294 waves.insert(std::make_pair(i, graph));
00295 sprintf(name,"ch%d split%d", n, i);
00296 waves[i]->SetName(name);
00297 waves[i]->SetTitle(name);
00298 }
00299
00300
00301 for (int j=0; j<avggraph->GetN(); j++) {
00302 if (j % split == 0 && j<(avggraph->GetN()-split+1)) {
00303 int jj = (int)TMath::Floor((double) j / (double) split);
00304 for (int i=0; i<split; i++) {
00305 waves[i]->SetPoint(jj, x[j+i], y[j+i]);
00306 waves[i]->SetPointError(jj, 0, ey[j+i]);
00307 }
00308 }
00309 }
00310
00311 split_waves->insert(std::make_pair(ch, waves));
00312 }
00313 }
00314
00315 void Reorganize(map<int, map<int, TGraphErrors*> >* split_waves_by_ch,
00316 map<int, map<int, TGraphErrors*> >* split_waves_by_split) {
00317 for (map<int, map<int, TGraphErrors*> >::iterator it = split_waves_by_ch->begin();
00318 it != split_waves_by_ch->end(); it++) {
00319 map<int, TGraphErrors*> ch = it->second;
00320 int ch_i = it->first;
00321 for (map<int, TGraphErrors*>::iterator it2 = ch.begin(); it2 != ch.end(); it2++) {
00322 TGraphErrors* wave = it2->second;
00323 int split_i = it2->first;
00324 if (!(split_waves_by_split->count(split_i)>0)) {
00325 map<int, TGraphErrors*> wave_i;
00326 split_waves_by_split->insert(make_pair(split_i, wave_i));
00327 }
00328 (split_waves_by_split->find(split_i))->second.insert(make_pair(ch_i, wave));
00329 }
00330 }
00331 }
00332
00333
00334
00335 void PrintResults(map<int, map<int, TGraphErrors*> >* split_waves_by_ch, int nSplit, int run) {
00336 int width = 80;
00337 cout<<"\n"<<tab(width,'*')<<""<<"\n"<<"Results for run"<<run<<" \n"<<tab(width,'*')<<""<<endl;
00338
00339 for (map<int, map<int, TGraphErrors*> >::iterator it = split_waves_by_ch->begin();
00340 it != split_waves_by_ch->end(); it++) {
00341 cout << "\nChannel " << it->first << "\n" << tab(width, '-') << "" << endl;
00342 cout<<tab(10)<<"split"<<tab(20)<<"lifetime"<<tab(20)<<"amplitude"<<tab(20)<<"background"<<tab(20)<<"chi2/ndf"<<endl;
00343 cout << tab(width,'-') << "" << endl;
00344 map<int, TGraphErrors*> waves = it->second;
00345 for (map<int, TGraphErrors*>::iterator it2 = waves.begin();
00346 it2 != waves.end(); it2++) {
00347 TGraphErrors* graph = it2->second;
00348 TF1* func = graph->GetFunction("exp_func_f");
00349 char lifetime[50];
00350 char amplitude[50];
00351 char offset[50];
00352 char chisq[50];
00353 sprintf(lifetime, "%#.5g +- %.4f", func->GetParameter(0), func->GetParError(0));
00354 sprintf(amplitude, "%#.5g +- %.4f", func->GetParameter(2), func->GetParError(2));
00355 sprintf(offset, "%#.5g +- %.4f", func->GetParameter(3), func->GetParError(3));
00356 sprintf(chisq, "%#.5g/%d", func->GetChisquare(), func->GetNDF());
00357 cout<<tab(10)<<it2->first<<tab(20)<<lifetime<<tab(20)<<amplitude<<tab(20)<<offset<<tab(20)<<chisq<<endl;
00358 }
00359
00360 }
00361 }
00362
00363 int ProcessRun(const char* fname) {
00364
00365
00366
00367
00368 RootGraphix root;
00369 root.Initialize();
00370 TFile *f = OpenFile(fname, "UPDATE");
00371 if (!f) {cout<<"File not opened!"<<endl;}
00372 TTree* Events = GetEventsTree(fname);
00373 if (!Events) {cout<<"!Events"<<endl; return -1;}
00374
00375 EventData* event = 0;
00376 Events->SetBranchAddress("event",&event);
00377 Events->GetEntry(0);
00378 cout<<"There are "<<Events->GetEntries()<<" entries in this tree."<<endl;
00379
00380 int nChans = event->channels.size();
00381 int run = event->run_id;
00382 printf("run %d\n", run);
00383
00384
00385 std::map<int, TGraphErrors*> avgwaveforms;
00386 for (int i=0; i<nChans; i++) {
00387 int chan = event->channels.at(i).channel_num;
00388 if (chan < 0) {
00389 continue;
00390 }
00391 if (chan == 6 || chan == 7) {
00392 continue;
00393 }
00394 TGraphErrors* avgch = (TGraphErrors*) GetAverageGraph(fname, chan);
00395 avgwaveforms.insert( std::make_pair(chan, avgch));
00396 }
00397
00398
00399 int nSplit = 8;
00400
00401 std::map<int, map<int, TGraphErrors*> > split_waves_by_ch;
00402 Split(&avgwaveforms, &split_waves_by_ch, nSplit);
00403
00404
00405
00406 map<int, map<int, TGraphErrors*> > split_waves_by_split;
00407 Reorganize(&split_waves_by_ch, &split_waves_by_split);
00408
00409
00410
00411
00412
00413 loopAddBaselineErrors(&split_waves_by_split, nSplit);
00414
00415
00416 loopSubtract(&split_waves_by_split, nSplit);
00417
00418
00419 loopFit(&split_waves_by_split, nSplit);
00420
00421
00422
00423 PrintResults(&split_waves_by_ch, nSplit, run);
00424
00425
00426
00427
00428
00429
00430 TCanvas* c = new TCanvas("c","fname");
00431 int chsplit = 4;
00432
00433 DrawMany(&split_waves_by_split[chsplit], &root, c);
00434 gStyle->SetOptFit();
00435
00436
00437 TCanvas* c3 = new TCanvas("c3", "ch_single");
00438 int plot_ch = 4;
00439 int plot_split = 5;
00440 TGraphErrors* ch_single = split_waves_by_ch[plot_ch][plot_split];
00441 DrawSingle(ch_single, &root, c3);
00442
00443
00444 TCanvas* c1 = new TCanvas("c1", "residuals");
00445 PlotResiduals(ch_single, &root, c1);
00446
00447
00448 char pause2;
00449 cout << endl << "Enter anything to quit." << endl;
00450 cin>>pause2;
00451
00452
00453
00454 return 0;
00455 }
00456
00457
00458 int main( int argc, char** argv)
00459 {
00460
00461
00462 std::stringstream rootfile, rawfile;
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 rootfile<<argv[1];
00481
00482
00483 return ProcessRun(rootfile.str().c_str());
00484 }
00485
00486