CbmRoot
Loading...
Searching...
No Matches
PairAnalysisSpectrum.cxx
Go to the documentation of this file.
1/* Copyright (C) 2016-2021 Justus-Liebig-Universitaet Giessen, Giessen
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Julian Book [committer] */
4
6// PairAnalysisSpectrum //
7// //
8// //
9/*
10
11 post-processing class to extract signals, efficiency, apply corrections,
12 calculate systematics and describe the spectra by some functions/models.
13
14 Example:
15
16 PairAnalysisSpectrum *spectrum = new PairAnalysisSpectrum("legend header","systematics");
17
18 spectrum->SetParticleOfInterest(pdgcode);
19 spectrum->SetVariable("Pt",PairAnalysisHelper::MakeLinBinning(20,0.,2.) );
20
21 spectrum->SetSystMethod( PairAnalysisSpectrum::kSystMax );
22
23 // add input spectra coming from PairAnalysisHistos
24 spectrum->AddInput( histos->DrawSame("pM_Pt","nomc goff"), // raw invariant mass spectrum
25 "like-sign", // unique string
26 histos->DrawSame("pPt","onlymc goff sel","phi") // optional: MC spectra for efficiency
27 );
28 spectrum->AddExtractor( sig ); // signal extraction (see PairAnalysisSignalExt)
29
30 .... add more input as much as you want
31
32
33 // process all inputs
34 spectrum->Process();
35
36
37 // draw spectra using TTree::Draw command + some extra arguments (see Draw)
38 // see Extraction for content
39 spectrum->Draw("s/eff:var","","leg logY syst P");
40
41 // fit the spectrum by some predefined function (see PairAnalysisFunction)
42 spectrum->SetFitRange(0.,2.);
43 spectrum->SetDefault( PairAnalysisFunction::kBoltzmann );
44 spectrum->SetFitOption("RN0");
45 spectrum->Fit("leg L");
46
47 */
48// //
50
51//#include <TObject.h>
53
54#include <TCanvas.h>
55#include <TDatabasePDG.h>
56#include <TEventList.h>
57#include <TF1.h>
58#include <TFile.h>
59#include <TFormula.h>
60#include <TGraphErrors.h>
61#include <TH1.h>
62#include <TList.h>
63#include <TObjString.h>
64#include <TPad.h>
65#include <TPaveText.h>
66#include <TProfile.h>
67#include <TProfile2D.h>
68#include <TROOT.h>
69#include <TTree.h>
70#include <TVectorT.h>
71
72#include "PairAnalysisHF.h"
73#include "PairAnalysisHistos.h"
75#include "PairAnalysisStyler.h"
77
78ClassImp(PairAnalysisSpectrum)
79
80 //______________________________________________
81 PairAnalysisSpectrum::PairAnalysisSpectrum()
82 : PairAnalysisSpectrum("spectrum", "title")
83{
87}
88
89//______________________________________________
90PairAnalysisSpectrum::PairAnalysisSpectrum(const char* name, const char* title)
91 : PairAnalysisFunction(name, title)
92 , fRawInput(0)
93 , fMCInput(0)
94 , fMCTruth(0)
95 , fExtractor(0)
96{
100 fTree = new TTree("PAPa", "PAPa-Spectrum");
101 fExt = new Extraction;
102 for (Int_t i = 0; i < 100; i++)
103 fInputKeys[i] = "";
104}
105
106//______________________________________________
107PairAnalysisSpectrum::~PairAnalysisSpectrum()
108{
112 if (fResults) delete fResults;
113 if (fExtractions) delete fExtractions;
114}
115
116//______________________________________________
117void PairAnalysisSpectrum::AddInput(TObjArray* raw, TString identifier, TObjArray* mc, TObjArray* truth)
118{
123 fRawInput.Add(raw);
124 if (mc) fMCInput.Add(mc);
125 if (truth) fMCTruth.Add(truth);
126 fInputKeys[fIdx] = identifier;
127 fIdx++;
128}
129
130//______________________________________________
131void PairAnalysisSpectrum::Init()
132{
136 fTree->Branch("Extraction", &fExt);
137 // fTree ->Branch("hSignal","TH1",&fHistSignal,32000,0);
138}
139
140//______________________________________________
141void PairAnalysisSpectrum::Process()
142{
146 Init();
147
148 Int_t i = -1;
149
150 TIter nextRaw(&fRawInput); // raw content
151 TObject* obj = NULL;
152 PairAnalysisHF* hf = NULL;
153 PairAnalysisHistos* h = NULL;
154
155 TObject* objMC = NULL;
156 PairAnalysisHF* hfMC = NULL;
157 PairAnalysisHistos* hMC = NULL;
158
159 TObject* objMCtruth = NULL;
160
162 while ((obj = nextRaw())) {
163 i++;
164 TObject::Info("Process", "Check Extraction for %s", fInputKeys[i].Data());
165 TObject::Info("Process", "------------------------------------------------------------"
166 "-----------");
167 TObject::Info("Process", "Input type: %s \n", obj->ClassName());
168
169 if (fVarBinning) {
170 TObject::Info("Process", "Binning provided for %s from %.3f to %.3f", fVar.Data(), fVarBinning->Min(),
171 fVarBinning->Max());
172 // fVarBinning->Print();
173 }
174
175 TObjArray* histArr = dynamic_cast<TObjArray*>(obj);
176 if (!(histArr)) {
177 if (!(h = dynamic_cast<PairAnalysisHistos*>(obj))) {
178 if (!(hf = dynamic_cast<PairAnalysisHF*>(obj))) {
179 TObject::Error("Process", "No input format found");
180 continue;
181 }
182 }
183 }
184
185 // get extractor
186 PairAnalysisSignalExt* sig = dynamic_cast<PairAnalysisSignalExt*>(fExtractor.At(i));
187 if (!sig) continue;
188
189
191 objMC = fMCInput.At(i);
192 TObjArray* histArrMC = NULL;
193 if (objMC) {
194 TObject::Info("Process", "Input MC type: %s \n", objMC->ClassName());
195 histArrMC = dynamic_cast<TObjArray*>(objMC);
196 if (!(histArrMC)) {
197 if (!(hMC = dynamic_cast<PairAnalysisHistos*>(objMC))) {
198 if (!(hfMC = dynamic_cast<PairAnalysisHF*>(objMC))) {
199 TObject::Error("Process", "No MC input format found");
200 //continue;
201 }
202 }
203 }
204 }
205
207 objMCtruth = fMCTruth.At(i);
208 TObjArray* histArrMCt = NULL;
209 if (objMCtruth) {
210 TObject::Info("Process", "Input MC truth type: %s \n", objMCtruth->ClassName());
211 histArrMCt = dynamic_cast<TObjArray*>(objMCtruth);
212 }
213
214
216 if (!fVarBinning) {
217
218 // get raw input histograms
219 if (!histArr && h) histArr = h->DrawSame("pM-wghtWeight",
220 "nomc goff"); //NOTE w/o "can" it crashes
221 // if(!histArr && h) histArr = h->DrawSame("pM","can nomc goff"); //NOTE w/o "can" it crashes
222 // histArr->Print();
223 // get mc input histograms TODO: think about integration
224 if (!histArrMC && hMC) histArrMC = hMC->DrawSame("pM", "onlymc eff goff"); //NOTE w/o "can" it crashes
225
226
227 // process raw signal extraction
228 sig->Process(histArr);
229 if (gErrorIgnoreLevel < kWarning) sig->Print("");
230
231 // validate signal extraction
232 if (sig->GetSignal() < 0.) continue;
233
234 // fill the tree
235 fExt->setup = fInputKeys[i];
236 fExt->setupId = i;
237 fExt->poi = sig->GetParticleOfInterest();
238 fExt->var = 1.; //integrated
239 fExt->varE = 0.;
240 fExt->s = sig->GetSignal();
241 fExt->sE = sig->GetSignalError();
242 fExt->b = sig->GetBackground();
243 fExt->bE = sig->GetBackgroundError();
244 fExt->sb = sig->GetSB();
245 fExt->sbE = sig->GetSBError();
246 fExt->sgn = sig->GetSignificance();
247 fExt->sgnE = sig->GetSignificanceError();
248 fExt->HistSignal = NULL; //dynamic_cast<TH1F*>(sig->GetSignalHistogram());
249 fExt->eff = 1.; //TODO: calculate this
250 fExt->effE = 0.; //TODO: calculate this
251 fExt->signal = sig; //NULL;
252 fExt->sref = 1.; //TODO: calculate this
253 fExt->srefE = 0.; //TODO: calculate this
254
255 fTree->Fill();
256 }
257 else {
258
260 if (h && !h->SetCutClass(fInputKeys[i].Data())) continue;
261
262 if (!histArr && h) histArr = h->DrawSame(Form("pM_%s", fVar.Data()), "nomc goff");
263 TH2* histPM = (TH2*) sig->FindObject(histArr, PairAnalysis::EPairType::kSEPM);
264 if (!histPM) return;
265
266 TObjArray tmpArr;
267 tmpArr.SetOwner(kFALSE);
268
270 TH1* histMC = NULL;
271 if (!histArrMC && hMC) {
272 histArrMC = hMC->DrawSame(Form("p%s", fVar.Data()), "goff sel",
273 "phi"); // TODO: add search using fPOIpdg
274 }
275 if (histArrMC) {
276 TH1* tmpMCnom = (TH1*) histArrMC->At(0);
277 if (histArrMC->GetEntriesFast() < 2) return;
278 TH1* tmpMCden = (TH1*) histArrMC->At(1);
280 histMC = tmpMCnom->Rebin(fVarBinning->GetNrows() - 1, "effMC", fVarBinning->GetMatrixArray());
281 TH1* histMCden = tmpMCden->Rebin(fVarBinning->GetNrows() - 1, "effMCden", fVarBinning->GetMatrixArray());
282 histMC->Divide(histMCden);
283 delete histMCden;
284 }
286 if (histMC) TObject::Info("Process", "MC histogram found and rebinned");
287
289 TH1* histMCtruth = NULL;
290 if (histArrMCt) {
291 TH1* tmpMCtrue = (TH1*) histArrMCt->At(0);
292 if (!tmpMCtrue) return;
294 histMCtruth = tmpMCtrue->Rebin(fVarBinning->GetNrows() - 1, "sMCtrue", fVarBinning->GetMatrixArray());
295 }
297 if (histMCtruth) TObject::Info("Process", "MCtruth reference histogram found and rebinned");
298
299 // loop over all bins
300 for (Int_t bin = 0; bin < fVarBinning->GetNrows() - 1; bin++) {
301 tmpArr.Clear();
302
303 // var bin limits
304 Double_t xLo = fVarBinning->GetMatrixArray()[bin];
305 Double_t xHi = fVarBinning->GetMatrixArray()[bin + 1] - 0.000001;
306 // axis limits
307 Int_t binLo = histPM->GetYaxis()->FindBin(xLo);
308 Int_t binHi = histPM->GetYaxis()->FindBin(xHi);
309 // found bin limits
310 Double_t fndLo = histPM->GetYaxis()->GetBinLowEdge(binLo);
311 Double_t fndHi = histPM->GetYaxis()->GetBinLowEdge(binHi + 1);
312 //printf("binning requested, found of %s: %.3f-%.3f, %.3f-%.3f \n", fVar.Data(), xLo,xHi, fndLo,fndHi );
313 TObject::Info("Process", "Bin %d: %.3f < %s < %.3f", bin, fndLo, fVar.Data(), fndHi);
314
315 // fill array for signal extraction
316 for (Int_t ih = 0; ih < histArr->GetEntriesFast(); ih++) {
317 TH2* hist = (TH2*) histArr->UncheckedAt(ih);
318 tmpArr.Add(hist->ProjectionX(hist->GetTitle(), binLo, binHi, "e"));
319 }
320 // tmpArr.Print();
321
322 // process
323 sig->Process(&tmpArr);
324 if (gErrorIgnoreLevel < kWarning) sig->Print("");
325
326 // validate signal extraction
327 if (sig->GetSignal() < 0.) continue;
328 if (TMath::IsNaN(sig->GetSignalError())) continue;
329
330 // fill the tree
331 fExt->setup = fInputKeys[i];
332 fExt->setupId = i;
333 fExt->poi = sig->GetParticleOfInterest();
334 fExt->var = (fndHi - fndLo) / 2 + fndLo; // center of the found bin
335 fExt->varE = (fndHi - fndLo) / 2; // found bin width
336 fExt->s = sig->GetSignal();
337 fExt->sE = sig->GetSignalError();
338 fExt->b = sig->GetBackground();
339 fExt->bE = sig->GetBackgroundError();
340 fExt->sb = sig->GetSB();
341 fExt->sbE = sig->GetSBError();
342 fExt->sgn = sig->GetSignificance();
343 fExt->sgnE = sig->GetSignificanceError();
344 fExt->HistSignal = NULL; //dynamic_cast<TH1F*>(sig->GetSignalHistogram());
345 fExt->eff = (histMC ? histMC->GetBinContent(bin + 1) : 1.);
346 fExt->effE = (histMC ? histMC->GetBinError(bin + 1) : 0.);
347 fExt->signal = sig;
348 fExt->sref = (histMCtruth ? histMCtruth->GetBinContent(bin + 1) : 0.);
349 fExt->srefE = (histMCtruth ? histMCtruth->GetBinError(bin + 1) : 0.);
350
351 fTree->Fill();
352
353 // set variable
354 // hf->AddCutVariable( (EValueTypes)
355 // PairAnalysisVarManager::GetValueType(fVar.Data()),
356 // fVarBinning->GetMatrixArray()[bin],
357 // fVarBinning->GetMatrixArray()[bin+1]
358 // );
359
360 // get histogram array
361 //...
362
363 } //end binning
364
366 if (histMC) delete histMC;
367 if (histMCtruth) delete histMCtruth;
368
369 } // end 2D
370
371 } // end raw content
372
373 // fTree->Print();
374}
375
376//______________________________________________
377void PairAnalysisSpectrum::DrawSpectrum(const char* varexp, const char* selection, Option_t* option)
378{
379 //
380 // TTree draw alias
381 //
394
395 TString optString(option);
396 optString.ToLower();
397 printf("Plot spectrum: '%s' \t selection: '%s' \t options: '%s' \n", varexp, selection, optString.Data());
398 Bool_t optLegFull = optString.Contains("legf");
399 optString.ReplaceAll("legf", "");
400 Bool_t optLeg = optString.Contains("leg");
401 optString.ReplaceAll("leg", "");
402 Bool_t optSyst = optString.Contains("syst");
403 optString.ReplaceAll("syst", "");
404 Bool_t optPrint = optString.Contains("print");
405 optString.ReplaceAll("print", "");
406 Bool_t optSamePad = optString.Contains("samepad");
407 optString.ReplaceAll("samepad", "");
408
410 Long64_t n = 1;
411
414
416 TString ckey(varexp);
417 Int_t ndim = ckey.CountChar(':') + 1;
418
420 TObjArray* carr = ckey.Tokenize(":");
421 carr->SetOwner();
422 // delete carr;
423
425 TObjArray* oarr = ckey.Tokenize("+-*/:");
426 oarr->SetOwner();
427 TString fkey = ((TObjString*) oarr->At(0))->GetString();
428 delete oarr;
429
431 ckey.ReplaceAll("/", "#");
432 TCanvas* c = NULL;
433 if (optSamePad) c = gPad->GetCanvas();
434 else
435 c = (TCanvas*) gROOT->FindObject(ckey.Data());
436 if (!c) {
437 TObject::Info("Draw", "create new canvas: '%s'", ckey.Data());
438 c = new TCanvas(ckey.Data(), ckey.Data());
439 }
440 c->cd();
441
443 TObject* obj;
444 Int_t nobj = 0;
445 TList* prim = gPad->GetListOfPrimitives();
447 for (Int_t io = 0; io < prim->GetSize(); io++) {
448 obj = prim->At(io);
449 if (obj->InheritsFrom(TGraph::Class()) && obj != prim->At(io + 1)) nobj++;
450 }
451
452 TLegend* leg = 0;
453 if ((optLeg && !nobj)) {
454 // if ( (optLeg && optTask && !nobj) || (optLeg && !optTask && !optDet) ) {
455 leg = new TLegend(0. + gPad->GetLeftMargin() + gStyle->GetTickLength("Y"),
456 0. + gPad->GetBottomMargin() + gStyle->GetTickLength("X"),
457 1. - gPad->GetRightMargin() + gStyle->GetTickLength("Y"),
458 1. - gPad->GetTopMargin() + gStyle->GetTickLength("X"), GetName(), "nbNDC");
459 }
460 else if (optLeg && nobj) {
461 leg = (TLegend*) prim->FindObject("TPave");
462 }
463
464 Info("Draw", "Basics: nobj: %d \t leg: %p", nobj, leg);
465
466 // logaritmic style
467 if (optString.Contains("logx")) gPad->SetLogx();
468 if (optString.Contains("logy")) gPad->SetLogy();
469 if (optString.Contains("logz")) gPad->SetLogz();
470 optString.ReplaceAll("logx", "");
471 optString.ReplaceAll("logy", "");
472 optString.ReplaceAll("logz", "");
473
474 if (ndim < 3 && !ckey.Contains("signal->")) { // build own histogram with labels
475
476 // printf("try to get errors for %d dimensional input \n",ndim);
477 TString varkey(varexp);
478
479 // get event list
480 n = fTree->Draw(">>elist", selection);
481 if (!n) {
482 delete carr;
483 return;
484 }
485 TEventList* elist = gDirectory->Get<TEventList>("elist");
486 if (elist) {
487 elist->SetReapplyCut(kTRUE); // important!
488 // elist->Print("all");
489 fTree->SetEventList(elist);
490 }
491
492 TH1D* hist = 0x0;
493 // set up a proper histogram with labels
494 if (varkey.Contains("setup")) {
495
496 hist = new TH1D(); // activate buffer
497 hist->SetNameTitle(varexp, selection);
498
499 //read strings for all entries
500 for (Long64_t i = 0; i < n; i++) {
501 fTree->GetEntry(i);
502 hist->Fill((fExt->setup).Data(), 1.);
503 // printf(" read from tree: %s \n",(fExt->setup).Data());
504 }
505
506 hist->Draw("AXIS");
507 hist->GetXaxis()->SetRange(1, n);
508 }
509
510 // get errors from tree
511 TString errkey = ((TObjString*) carr->At(0))->GetString();
512 errkey.ReplaceAll(fkey, fkey + "E");
513 // if(ndim>1) varkey.ReplaceAll(fkey+":",fkey+":"+fkey+"E:");
514 // else varkey.ReplaceAll(fkey,fkey+":"+fkey+"E");
515 // if(ndim>1) varkey.ReplaceAll(fkey+":",fkey+":"+fkey+"E:");
516 // else
517 if (!fkey.Contains("E")) {
518 varkey.Append(errkey.Prepend(":"));
519 Info("Draw", " Appended '%s' by '%s' for error caluclation", varkey.Data(), errkey.Data());
520 }
521
523 //printf("execute collect/draw command for %s \n",varkey.Data());
524 fTree->Draw(varkey, selection, "goff");
525
527 Double_t* xval = new Double_t[fTree->GetSelectedRows()];
528 for (Int_t ix = 0; ix < fTree->GetSelectedRows(); ix++)
529 xval[ix] = 1.;
530
532 TGraphErrors* gr = 0x0;
533 if (ndim > 1) gr = new TGraphErrors(fTree->GetSelectedRows(), fTree->GetV2(), fTree->GetV1(), 0, fTree->GetV3());
534 else
535 gr = new TGraphErrors(fTree->GetSelectedRows(), fTree->GetV1(), xval, fTree->GetV2(), 0);
536 delete[] xval;
537
538 if (!gr) {
539 delete carr;
540 return;
541 }
542
545 TString sel(selection);
546 sel.ReplaceAll("setup.Contains", "");
547 sel.ReplaceAll("(\"", "*");
548 sel.ReplaceAll("\")", "*");
549 sel.ReplaceAll("setup==", "");
550 sel.ReplaceAll("\"", "");
551 gr->SetName(Form("%s", sel.Data()));
552 if (sel.Contains("setupId==") && sel.Length() < 11) {
553 sel.ReplaceAll("setupId==", "");
554 Int_t iId = sel.Atoi();
555 gr->SetName(Form("%s", fInputKeys[iId].Data()));
556 }
557 if (optSyst) gr->SetName(GetTitle());
558 if (fkey.Contains("ref")) gr->SetName("MC-truth");
559
560 // sort x-values
561 gr->Sort();
562 TGraphErrors* grE = NULL; // statistical
563 TGraphErrors* grS = NULL; // systematic
564 TGraphErrors* grC = NULL; // stat + syst
565 if (optSyst && fVarBinning) { //TODO: implement systematic calculation w/o binning
566 grE = new TGraphErrors(); // statistical graph
567 grS = new TGraphErrors(); // systematics graph
568 grC = new TGraphErrors(); // systematics graph
569 Double_t* gx = gr->GetX();
570 Double_t* gy = gr->GetY();
571 Double_t* gye = gr->GetEY();
572
573 // loop over all variable bins
574 Int_t first = 0; //TMath::BinarySearch(gr->GetN(),gx,xLo); //first bin
575 Int_t ibin = 0;
576 while (first < gr->GetN()) {
577 // for(ibin=0; ibin<fVarBinning->GetNrows()-1; ibin++) {
578
579 Int_t nsys = 0; // counter #systematics
580 Double_t ysys = 0.; // y-vlaue of systematic = mean value
581 Double_t esys = 0.; // uncertainty depends on method
582 // calculate mean
583 Double_t xvar = gx[first];
584 for (Int_t i = first; i < gr->GetN(); i++) {
585 // printf("gx[i]:%f xvar:%f xLo:%f\n",gx[i],xvar,xLo);
586 // if(TMath::Abs(gx[i]-xvar)>1.e-8) break;
587 if ((gx[i] - xvar) > 1.e-8) break;
588 // printf("graph entry %d, found index first: %d with value %.3f \t y: %.3f+-%.3f \n",
589 // i,first,xvar,gy[i],gye[i]);
590 nsys++;
591 ysys += gy[i];
592 }
593 ysys /= (nsys ? nsys : 1); // protect for zero division
594 // printf("bin %d, found index first: %d, %.3f \t y:%3.f \t nsys:%d\n",ibin,first,xvar,ysys,nsys);
595
596 // y-syst. uncertainty
597 // printf("syst %f , <y> %f\n",esys,ysys);
598 for (Int_t i = 0; i < nsys; i++) {
599 Int_t j = first + i;
600 // if(gx[j]!=xLo) break; // check should not be needed
601 Double_t uce = 0.;
602 switch (fSystMthd) {
603 case ESystMethod::kBarlow:
604 // I. calc uncorr. stat. error from sub/superset w.r.t. first measurement
605 uce = TMath::Sqrt(TMath::Abs(gye[j] * gye[j] - gye[first] * gye[first]));
606 // II. calc max. deviation w.r.t. mean y-value incl. 1sigma* 0.9 of I.
607 // NOTE: 0.9 can be change to a max value of 1->1sigma, 0.9 is more consevative
608 esys = TMath::Max(esys, TMath::Abs(ysys - gy[j]) - 0.9 * uce);
609 break;
610 case ESystMethod::kSystMax: esys = TMath::Max(esys, TMath::Abs(ysys - gy[j])); break;
611 case ESystMethod::kSystRMS: esys += gy[j] * gy[j]; break;
612 }
613 // printf("bin error %f \t syst %f from abs %f \n",gye[j],esys, TMath::Abs( gy[j] ));
614 }
615
616 // normalisation
617 switch (fSystMthd) {
618 case ESystMethod::kBarlow: /* nothing to be done */ break;
619 case ESystMethod::kSystMax: /* nothing to be done */ break;
620 case ESystMethod::kSystRMS: esys = TMath::Sqrt(TMath::Abs(esys / (nsys ? nsys : 1) - ysys * ysys)); break;
621 }
622
623 // fill statistical and systematic graph values and errors
624 grE->SetPoint(ibin, xvar, ysys); // mean
625 grE->SetPointError(ibin, 0.0, gye[first]); // stat.uncert. of first set
626
627 Double_t boxW = (fVarBinning->Max() - fVarBinning->Min()) / (fVarBinning->GetNrows() - 1);
628 grS->SetPoint(ibin, xvar, ysys); // mean
629 grS->SetPointError(ibin, boxW * 0.35, esys); // systematic value
630
631 // calculate err = sqrt(stat.**2 + syst**2)
632 grC->SetPoint(ibin, xvar, ysys); // mean
633 grC->SetPointError(ibin, boxW * 0.35, TMath::Sqrt(esys * esys + gye[first] * gye[first]));
634
635 // increase index counter
636 first += nsys;
637 ibin++;
638 } //next bin
639 // grS->Print();
640 }
641 else {
642 grC = new TGraphErrors(*gr);
643 }
644
645 if (optPrint) grC->Print();
646
647 Info("Draw", " Draw object with options: '%s'", optString.Data());
648 if (!PairAnalysisStyler::GetFirstHistogram()) gr->Draw((optString + "A").Data());
649 else {
650 gr->Draw((optString + "same").Data());
651
652 // set axis maximum
653 Double_t* valE = grC->GetEY();
654 Double_t* val = grC->GetY();
655 Int_t npnts = grC->GetN();
656 Int_t idx[1000];
657 TMath::Sort(npnts, val, idx, kTRUE); // kFALSE=increasing numbers
658
659 Double_t errmin = (TMath::IsNaN(valE[idx[npnts - 1]]) ? 0. : valE[idx[npnts - 1]]);
660 Double_t min = (val[idx[npnts - 1]] - errmin) * 0.9;
661 Double_t tmpmin = PairAnalysisStyler::GetFirstHistogram()->GetMinimum();
662 PairAnalysisStyler::GetFirstHistogram()->SetMinimum((tmpmin < min ? tmpmin : min));
663 Double_t errmax = (TMath::IsNaN(valE[idx[0]]) ? 0. : valE[idx[0]]);
664 Double_t max = (val[idx[0]] + errmax) * 1.1;
665 Double_t tmpmax = PairAnalysisStyler::GetFirstHistogram()->GetMaximum();
666 PairAnalysisStyler::GetFirstHistogram()->SetMaximum((tmpmax > max ? tmpmax : max));
667 }
668
669 // draw systemtaic graph ontop
670 if (grS) {
671 PairAnalysisStyler::Style(grE, nobj);
672 grE->Draw((optString + "A").Data());
673 PairAnalysisStyler::Style(grS, nobj);
674 grS->SetFillColor(grS->GetLineColor());
675 grS->SetFillStyle(kFEmpty);
676 grS->Draw("2same");
677 }
678
679 // legend
680 TString legOpt = optString + "L";
681 legOpt.ReplaceAll("hist", "");
682 legOpt.ReplaceAll("scat", "");
683 if (legOpt.Contains("col")) legOpt = "";
684 legOpt.ReplaceAll("z", "");
685 legOpt.ReplaceAll("e", "");
686
687 TString legkey = gr->GetName();
688 if (leg) leg->AddEntry(gr, gr->GetName(), legOpt.Data());
689
690 fSignal = grC;
691 PairAnalysisStyler::Style(fSignal, nobj);
692 }
693 else {
694 // execute tree draw command
695 fTree->Draw(varexp, selection, optString.Data());
696 fprintf(stderr, "use plain TTree::Draw command \n");
697 return;
698 }
699
700
702 // printf("modify axis titles \n");
703 if (!optSamePad) {
704 UInt_t varx = PairAnalysisVarManager::GetValueType(fVar.Data());
705 TString var(varexp);
706 TObjArray* arr = var.Tokenize(":");
707 arr->SetOwner();
708 TString xt = "";
709 TString yt = "Entries";
710 xt = ((TObjString*) arr->At(0))->GetString();
711 if (xt.EqualTo("sb")) xt = PairAnalysisSignalExt::GetValueName(3);
712 else if (xt.EqualTo("s"))
714 else if (xt.EqualTo("b"))
716 else if (xt.EqualTo("sgn"))
718 else if (xt.EqualTo("var"))
720 else if (xt.Contains("var")) {
721 xt.ReplaceAll("varE", Form("#Delta%s", PairAnalysisVarManager::GetValueLabel(varx)));
722 xt.ReplaceAll("var", PairAnalysisVarManager::GetValueLabel(varx));
723 }
724
725 if (arr->GetEntriesFast() < 2) {
726 PairAnalysisStyler::GetFirstHistogram()->SetXTitle(xt.Data());
727 PairAnalysisStyler::GetFirstHistogram()->SetYTitle(yt.Data());
728 }
729 else {
730 PairAnalysisStyler::GetFirstHistogram()->SetYTitle(xt.Data());
731 xt = ((TObjString*) arr->At(1))->GetString();
732 if (xt.EqualTo("sb")) xt = PairAnalysisSignalExt::GetValueName(3);
733 else if (xt.EqualTo("s"))
735 else if (xt.EqualTo("b"))
737 else if (xt.EqualTo("sgn"))
739 else if (xt.EqualTo("var"))
741 else if (xt.Contains("var")) {
742 xt.ReplaceAll("varE", Form("#Delta%s", PairAnalysisVarManager::GetValueLabel(varx)));
743 xt.ReplaceAll("var", PairAnalysisVarManager::GetValueLabel(varx));
744 }
745 PairAnalysisStyler::GetFirstHistogram()->SetXTitle(xt.Data());
746 }
747
749 if (arr) delete arr;
750 }
751
753 if (carr) delete carr;
754
756 if (fVarBinning) PairAnalysisStyler::GetFirstHistogram()->SetAxisRange(fVarBinning->Min(), fVarBinning->Max(), "X");
757 // PairAnalysisStyler::GetFirstHistogram()->GetXaxis()->SetNdivisions(, 0, 0, kFALSE);
758
759
760 // legend
761 if (leg) {
762 PairAnalysisStyler::SetLegendAttributes(leg, optLegFull); // coordinates, margins, fillstyle, fontsize
763 if (!nobj) leg->Draw(); // only draw the legend once
765 }
766
768 fTree->SetEventList(0);
769}
770
771//______________________________________________
772void PairAnalysisSpectrum::Write()
773{
777
779 TFile* oldFile = gFile;
780 TDirectory* oldDir = gDirectory;
781
782 TFile* fout = new TFile("test.root", "RECREATE");
783 fout->cd();
784 // fTree->Print();
785 fTree->Write();
786 fout->Close();
787
789 gFile = oldFile;
790 gDirectory = oldDir;
791}
792
793//______________________________________________
794void PairAnalysisSpectrum::Fit(TString drawoption)
795{
803
804 drawoption.ToLower();
805 Bool_t optLeg = drawoption.Contains("leg");
806 drawoption.ReplaceAll("leg", "");
807
808 // fSignal->Print();
809
810 Info("Fit", "Spectrum fit method: %s", fFuncSigBack->GetName());
811 Int_t fitResult = fSignal->Fit(fFuncSigBack, (fFitOpt + "EX0").Data());
812
813 // warning in case of fit issues
814 if (fitResult != 0) {
815 Error("Fit", "fit has error/issue (%d)", fitResult);
816 return;
817 }
818
819 PairAnalysisStyler::Style(fFuncSigBack, static_cast<Int_t>(PairAnalysisStyler::Eidx::kFit));
820 fFuncSigBack->SetLineColor(fSignal->GetLineColor());
821 // fFuncSigBack->SetLineStyle(kDashed);
822
823 // PairAnalysisStyler::Style(fit, PairAnalysisStyler::kFit);
824 TF1* fit = fFuncSigBack->DrawCopy((drawoption + "same").Data());
825
827 fDof = fFuncSigBack->GetNDF();
828 if (fDof) fChi2Dof = fFuncSigBack->GetChisquare() / fFuncSigBack->GetNDF();
829
831 if (optLeg) {
832 TList* prim = gPad->GetListOfPrimitives();
833 TLegend* leg = (TLegend*) prim->FindObject("TPave");
834 TString legkey = fFuncSigBack->GetName();
836 if (leg) {
837 leg->AddEntry(fit, fFuncSigBack->GetName(), drawoption.Data());
840 }
841 }
842}
Char_t * gr
bool first
ClassImp(PairAnalysisSpectrum) PairAnalysisSpectrum
Data class with information on a STS local track.
Int_t GetParticleOfInterest() const
void Print(Option_t *option="") const
static const char * GetValueName(Int_t i)
void Process(TObjArray *const arrhist)
Double_t GetSignificanceError() const
TObject * FindObject(TObjArray *arrhist, PairAnalysis::EPairType type) const
Double_t GetBackgroundError() const
static const char * GetValueUnit(Int_t i)
static UInt_t GetValueType(const char *valname)
static const char * GetValueLabel(Int_t i)
void Style(TObject *obj, Int_t idx=0)
void SetLegendAttributes(TLegend *leg, Bool_t fill=kFALSE)