AliPhysics  e59a9ba (e59a9ba)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliJetFlowTools.cxx
Go to the documentation of this file.
1 /************************************************************************
2  * Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
3  * *
4  * Author: The ALICE Off-line Project. *
5  * Contributors are mentioned in the code where appropriate. *
6  * *
7  * Permission to use, copy, modify and distribute this software and its *
8  * documentation strictly for non-commercial purposes is hereby granted *
9  * without fee, provided that the above copyright notice appears in all *
10  * copies and that both the copyright notice and this permission notice *
11  * appear in the supporting documentation. The authors make no claims *
12  * about the suitability of this software for any purpose. It is *
13  * provided "as is" without express or implied warranty. *
14  **************************************************************************/
15 
16 // Author: Redmer Alexander Bertens, Utrecht University, Utrecht, Netherlands
17 // (rbertens@cern.ch, rbertens@nikhef.nl, r.a.bertens@uu.nl)
18 //
19 // Tools class for Jet Flow Analysis, replaces 'extractJetFlow.C' macro
20 //
21 // The task uses input from two analysis tasks:
22 // - $ALICE_PHYSICS/PWGJE/EMCALJetTasks/UserTasks/AliAnalysisTaskJetV2.cxx
23 // used to retrieve jet spectra and delta pt distributions
24 // - $ALICE_PHYSICS/PWGJE/EMCALJetTasks/UserTasks/AliAnalysisTaskJetMatching.cxx
25 // used to construct the detector response function
26 // and unfolds jet spectra with respect to the event plane. The user can choose
27 // different alrogithms for unfolding which are available in (ali)root. RooUnfold
28 // libraries must be present on the system
29 // ( see http://hepunx.rl.ac.uk/~adye/software/unfold/RooUnfold.html ).
30 //
31 // The weak spot of this class is the function PrepareForUnfolding, which will read
32 // output from two output files and expects histograms with certain names and binning.
33 // Unfolding methods itself are general and should be able to handle any input, therefore one
34 // can forgo the PrepareForUnfolding method, and supply necessary input information via the
35 // SetRawInput() method
36 //
37 // to see an example of how to use this class, see $ALICE_PHYSICS/PWGCF/FLOW/macros/jetFlowTools.C
38 
39 // root includes
40 #include "TH1.h"
41 #include "TF2.h"
42 #include "TH2D.h"
43 #include "TGraph.h"
44 #include "TGraphErrors.h"
45 #include "TGraphAsymmErrors.h"
46 #include "TLine.h"
47 #include "TCanvas.h"
48 #include "TLegend.h"
49 #include "TArrayD.h"
50 #include "TList.h"
51 #include "TMinuit.h"
52 #include "TVirtualFitter.h"
53 #include "TLegend.h"
54 #include "TCanvas.h"
55 #include "TStyle.h"
56 #include "TLine.h"
57 #include "TVirtualFitter.h"
58 #include "TFitResultPtr.h"
59 #include "Minuit2/Minuit2Minimizer.h"
60 #include "Math/Functor.h"
61 // aliroot includes
62 #include "AliUnfolding.h"
63 #include "AliAnaChargedJetResponseMaker.h"
64 // class includes
65 #include "AliJetFlowTools.h"
66 // roo unfold includes (make sure you have these available on your system)
67 #include "RooUnfold.h"
68 #include "RooUnfoldResponse.h"
69 #include "RooUnfoldSvd.h"
70 #include "RooUnfoldBayes.h"
71 #include "TSVDUnfold.h"
72 
73 using namespace std;
74 //_____________________________________________________________________________
76  fListPrefix (-1),
77  fResponseMaker (new AliAnaChargedJetResponseMaker()),
78  fRMS (kTRUE),
79  fSymmRMS (0),
80  fConstantUE (kTRUE),
81  fRho0 (kFALSE),
82  fBootstrap (kFALSE),
83  fPower (new TF1("fPower","[0]*TMath::Power(x,-([1]))",0.,300.)),
84  fSaveFull (kTRUE),
85  fActiveString (""),
86  fActiveDir (0x0),
87  fInputList (0x0),
88  fRefreshInput (kTRUE),
89  fOutputFileName ("UnfoldedSpectra.root"),
90  fOutputFile (0x0),
91  fCentralityArray (0x0),
92  fMergeBinsArray (0x0),
93  fCentralityWeights (0x0),
94  fMergeWithList (0x0),
95  fMergeWithCen (-1),
96  fMergeWithWeight (1.),
97  fDetectorResponse (0x0),
98  fJetFindingEff (0x0),
99  fBetaIn (.1),
100  fBetaOut (.1),
101  fBayesianIterIn (4),
102  fBayesianIterOut (4),
103  fBayesianSmoothIn (0.),
104  fBayesianSmoothOut (0.),
105  fAvoidRoundingError (kFALSE),
106  fUnfoldingAlgorithm (kChi2),
107  fPrior (kPriorMeasured),
108  fPriorUser (0x0),
109  fBinsTrue (0x0),
110  fBinsRec (0x0),
111  fBinsTruePrior (0x0),
112  fBinsRecPrior (0x0),
113  fSVDRegIn (5),
114  fSVDRegOut (5),
115  fSVDToy (kTRUE),
116  fJetRadius (0.3),
117  fEventCount (-1),
118  fNormalizeSpectra (kFALSE),
119  fSmoothenPrior (kFALSE),
120  fFitMin (60.),
121  fFitMax (300.),
122  fFitStart (75.),
123  fSmoothenCounts (kTRUE),
124  fTestMode (kFALSE),
125  fRawInputProvided (kFALSE),
126  fEventPlaneRes (.63),
127  fUseDetectorResponse(kTRUE),
128  fUseDptResponse (kTRUE),
129  fTrainPower (kTRUE),
130  fDphiUnfolding (kTRUE),
131  fDphiDptUnfolding (kFALSE),
132  fExLJDpt (kTRUE),
133  fTitleFontSize (-999.),
134  fRMSSpectrumIn (0x0),
135  fRMSSpectrumOut (0x0),
136  fRMSRatio (0x0),
137  fRMSV2 (0x0),
138  fDeltaPtDeltaPhi (0x0),
139  fJetPtDeltaPhi (0x0),
140  fSpectrumIn (0x0),
141  fSpectrumOut (0x0),
142  fDptInDist (0x0),
143  fDptOutDist (0x0),
144  fDptIn (0x0),
145  fDptOut (0x0),
146  fFullResponseIn (0x0),
147  fFullResponseOut (0x0),
148  fPivot (55.),
149  fSubdueError (kTRUE),
150  fUnfoldedSpectrumIn (0x0),
151  fUnfoldedSpectrumOut(0x0) { // class constructor
152 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
153  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
154 #endif
155  fResponseMaker->SetRMMergeWeightFunction(new TF1("weightFunction", "x*TMath::Power(1.+(1./(8.*0.9))*x, -8.)", 0, 200));
156  for(Int_t i(0); i < fPower->GetNpar(); i++) fPower->SetParameter(i, 0.);
157 }
158 //_____________________________________________________________________________
159 void AliJetFlowTools::Make(TH1* customIn, TH1* customOut) {
160  // core function of the class
161 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
162  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
163 #endif
164  if(fDphiDptUnfolding) {
165  // to extract the yield as function of Dphi, Dpt - experimental
166  MakeAU();
167  return;
168  }
169  // 1) rebin the raw output of the jet task to the desired binnings
170  // 2) calls the unfolding routine
171  // 3) writes output to file
172  // can be repeated multiple times with different configurations
173 
174  // 1) manipulation of input histograms
175  // check if the input variables are present
176  if(fRefreshInput) {
177  if(!PrepareForUnfolding(customIn, customOut)) {
178  printf(" AliJetFlowTools::Make() Fatal error \n - couldn't prepare for unfolding ! \n");
179  return;
180  }
181  }
182  // 1a) resize the jet spectrum according to the binning scheme in fBinsTrue
183  // parts of the spectrum can end up in over or underflow bins
184 
185  // if bootstrap mode is kTRUE, resample the underlying distributions
186  // FIXME think about resampling the rebinned results or raw results, could lead to difference
187  // in smoothness of tail of spectrum (which is probably not used in any case, but still ... )
188 /*
189  if(fBootstrap) {
190  // resample but leave original spectra intact for the next unfolding round
191  fSpectrumIn = reinterpret_cast<TH1D*>(Bootstrap(fSpectrumIn, kFALSE));
192  fSpectrumOut = reinterpret_cast<TH1D*>(Bootstrap(fSpectrumOut, kFALSE));
193  }
194 */
195  TH1D* measuredJetSpectrumIn = RebinTH1D(fSpectrumIn, fBinsRec, TString("resized_in_"), kFALSE);
196  TH1D* measuredJetSpectrumOut = RebinTH1D(fSpectrumOut, fBinsRec, TString("resized_out_"), kFALSE);
197 
198  if(fBootstrap) {
199  measuredJetSpectrumIn = reinterpret_cast<TH1D*>(Bootstrap(measuredJetSpectrumIn, kFALSE));
200  measuredJetSpectrumOut = reinterpret_cast<TH1D*>(Bootstrap(measuredJetSpectrumOut, kFALSE));
201  }
202  // for now do it BEFORE as after gives an issue in Rebin function (counts are wrong)
203 
204 
205 
206  // 1b) resize the jet spectrum to 'true' bins. can serve as a prior and as a template for unfolding
207  // the template will be used as a prior for the chi2 unfolding
208  TH1D* measuredJetSpectrumTrueBinsIn = RebinTH1D(fSpectrumIn, fBinsTrue, TString("in"), kFALSE);
209  TH1D* measuredJetSpectrumTrueBinsOut = RebinTH1D(fSpectrumOut, fBinsTrue, TString("out"), kFALSE);
210  // get the full response matrix from the dpt and the detector response
212  // get the full response matrix. if test mode is chosen, the full response is replace by a unity matrix
213  // so that unfolding should return the initial spectrum
214  if(!fTestMode) {
218  } else if (fUseDptResponse && !fUseDetectorResponse) {
221  } else if (!fUseDptResponse && fUseDetectorResponse) {
225  printf(" > No response, exiting ! < \n" );
226  return;
227  }
228  } else {
231  }
232  // normalize each slide of the response to one
235  // resize to desired binning scheme
236  TH2D* resizedResponseIn = RebinTH2D(fFullResponseIn, fBinsTrue, fBinsRec, TString("in"));
237  TH2D* resizedResponseOut = RebinTH2D(fFullResponseOut, fBinsTrue, fBinsRec, TString("out"));
238  // get the kinematic efficiency
239  TH1D* kinematicEfficiencyIn = resizedResponseIn->ProjectionX();
240  kinematicEfficiencyIn->SetNameTitle("kin_eff_IN","kin_eff_IN");
241  TH1D* kinematicEfficiencyOut = resizedResponseOut->ProjectionX();
242  kinematicEfficiencyOut->SetNameTitle("kin_eff_OUT", "kin_eff_OUT");
243  // suppress the errors
244  for(Int_t i(0); i < kinematicEfficiencyOut->GetXaxis()->GetNbins(); i++) {
245  kinematicEfficiencyIn->SetBinError(1+i, 0.);
246  kinematicEfficiencyOut->SetBinError(1+i, 0.);
247  }
248  TH1D* jetFindingEfficiency(0x0);
249  if(fJetFindingEff) {
250  jetFindingEfficiency = ProtectHeap(fJetFindingEff);
251  jetFindingEfficiency->SetNameTitle(Form("%s_coarse", jetFindingEfficiency->GetName()), Form("%s_coarse", jetFindingEfficiency->GetName()));
252  jetFindingEfficiency = RebinTH1D(jetFindingEfficiency, fBinsTrue);
253  }
254  // 2, 3) call the actual unfolding. results and transient objects are stored in a dedicated TDirectoryFile
255  TH1D* unfoldedJetSpectrumIn(0x0);
256  TH1D* unfoldedJetSpectrumOut(0x0);
257  fActiveDir->cd(); // select active dir
258  TDirectoryFile* dirIn = new TDirectoryFile(Form("InPlane___%s", fActiveString.Data()), Form("InPlane___%s", fActiveString.Data()));
259  dirIn->cd(); // select inplane subdir
260  // do the inplane unfolding
261  unfoldedJetSpectrumIn = UnfoldWrapper(
262  measuredJetSpectrumIn,
263  resizedResponseIn,
264  kinematicEfficiencyIn,
265  measuredJetSpectrumTrueBinsIn,
266  TString("in"),
267  jetFindingEfficiency);
268  resizedResponseIn->SetNameTitle("ResponseMatrixIn", "response matrix in plane");
269  resizedResponseIn->SetXTitle("p_{T, jet}^{true} (GeV/#it{c})");
270  resizedResponseIn->SetYTitle("p_{T, jet}^{rec} (GeV/#it{c})");
271  resizedResponseIn = ProtectHeap(resizedResponseIn);
272  resizedResponseIn->Write();
273  kinematicEfficiencyIn->SetNameTitle("KinematicEfficiencyIn","Kinematic efficiency, in plane");
274  kinematicEfficiencyIn = ProtectHeap(kinematicEfficiencyIn);
275  kinematicEfficiencyIn->Write();
276  fDetectorResponse->SetNameTitle("DetectorResponse", "Detector response matrix");
278  fDetectorResponse->Write();
279  // optional histograms
280  if(fSaveFull) {
281  fSpectrumIn->SetNameTitle("[ORIG]JetSpectrum", "[INPUT] Jet spectrum, in plane");
282  fSpectrumIn->Write();
283  fDptInDist->SetNameTitle("[ORIG]DeltaPt", "#delta p_{T} distribution, in plane");
284  fDptInDist->Write();
285  fDptIn->SetNameTitle("[ORIG]DeltaPtMatrix","#delta p_{T} matrix, in plane");
286  fDptIn->Write();
287  fFullResponseIn->SetNameTitle("ResponseMatrix", "Response matrix, in plane");
288  fFullResponseIn->Write();
289  }
290  fActiveDir->cd();
291  if(fDphiUnfolding) {
292  TDirectoryFile* dirOut = new TDirectoryFile(Form("OutOfPlane___%s", fActiveString.Data()), Form("OutOfPlane___%s", fActiveString.Data()));
293  dirOut->cd();
294  // do the out of plane unfolding
295  unfoldedJetSpectrumOut = UnfoldWrapper(
296  measuredJetSpectrumOut,
297  resizedResponseOut,
298  kinematicEfficiencyOut,
299  measuredJetSpectrumTrueBinsOut,
300  TString("out"),
301  jetFindingEfficiency);
302  resizedResponseOut->SetNameTitle("ResponseMatrixOut", "response matrix in plane");
303  resizedResponseOut->SetXTitle("p_{T, jet}^{true} (GeV/#it{c})");
304  resizedResponseOut->SetYTitle("p_{T, jet}^{rec} (GeV/#it{c})");
305  resizedResponseOut = ProtectHeap(resizedResponseOut);
306  resizedResponseOut->Write();
307  kinematicEfficiencyOut->SetNameTitle("KinematicEfficiencyOut","Kinematic efficiency, Out plane");
308  kinematicEfficiencyOut = ProtectHeap(kinematicEfficiencyOut);
309  kinematicEfficiencyOut->Write();
310  fDetectorResponse->SetNameTitle("DetectorResponse", "Detector response matrix");
312  fDetectorResponse->Write();
313  if(jetFindingEfficiency) jetFindingEfficiency->Write();
314  // optional histograms
315  if(fSaveFull) {
316  fSpectrumOut->SetNameTitle("[ORIG]JetSpectrum", "[INPUT]Jet spectrum, Out plane");
317  fSpectrumOut->Write();
318  fDptOutDist->SetNameTitle("[ORIG]DeltaPt", "#delta p_{T} distribution, Out plane");
319  fDptOutDist->Write();
320  fDptOut->SetNameTitle("[ORIG]DeltaPtMatrix","#delta p_{T} matrix, Out plane");
321  fDptOut->Write();
322  fFullResponseOut->SetNameTitle("[ORIG]ResponseMatrix", "Response matrix, Out plane");
323  fFullResponseOut->Write();
324  }
325 
326  // write general output histograms to file
327  fActiveDir->cd();
328  if(unfoldedJetSpectrumIn && unfoldedJetSpectrumOut && unfoldedJetSpectrumIn && unfoldedJetSpectrumOut) {
329  TGraphErrors* ratio(GetRatio((TH1D*)unfoldedJetSpectrumIn->Clone("unfoldedLocal_in"), (TH1D*)unfoldedJetSpectrumOut->Clone("unfoldedLocal_out")));
330  if(ratio) {
331  ratio->SetNameTitle("RatioInOutPlane", "Ratio in plane, out of plane jet spectrum");
332  ratio->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
333  ratio->GetYaxis()->SetTitle("yield IN / yield OUT");
334  ratio = ProtectHeap(ratio);
335  ratio->Write();
336  // write histo values to RMS files if both routines converged
337  // input values are weighted by their uncertainty
338  for(Int_t i(0); i < ratio->GetXaxis()->GetNbins(); i++) {
339  if(unfoldedJetSpectrumIn->GetBinError(i+1) > 0) fRMSSpectrumIn->Fill(fRMSSpectrumIn->GetBinCenter(i+1), unfoldedJetSpectrumIn->GetBinContent(i+1), 1./TMath::Power(unfoldedJetSpectrumIn->GetBinError(i+1), 2.));
340  if(unfoldedJetSpectrumOut->GetBinError(i+1) > 0) fRMSSpectrumOut->Fill(fRMSSpectrumOut->GetBinCenter(i+1), unfoldedJetSpectrumOut->GetBinContent(i+1), 1./TMath::Power(unfoldedJetSpectrumOut->GetBinError(i+1), 2.));
341  if(unfoldedJetSpectrumOut->GetBinContent(i+1) > 0) fRMSRatio->Fill(fRMSSpectrumIn->GetBinCenter(i+1), unfoldedJetSpectrumIn->GetBinContent(i+1) / unfoldedJetSpectrumOut->GetBinContent(i+1));
342  }
343  }
344  TGraphErrors* v2(GetV2((TH1D*)unfoldedJetSpectrumIn->Clone("unfoldedLocal_inv2"), (TH1D*)unfoldedJetSpectrumOut->Clone("unfoldedLocal_outv2"), fEventPlaneRes));
345  if(v2) {
346  v2->SetNameTitle("v2", "v_{2} from different in, out of plane yield");
347  v2->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
348  v2->GetYaxis()->SetTitle("v_{2}");
349  v2 = ProtectHeap(v2);
350  v2->Write();
351  }
352  } else if (unfoldedJetSpectrumOut && unfoldedJetSpectrumIn) {
353  TGraphErrors* ratio(GetRatio((TH1D*)unfoldedJetSpectrumIn->Clone("unfoldedLocal_in"), (TH1D*)unfoldedJetSpectrumOut->Clone("unfoldedLocal_out"), TString(""), kTRUE, fBinsRec->At(fBinsRec->GetSize()-1)));
354  if(ratio) {
355  ratio->SetNameTitle("[NC]RatioInOutPlane", "[NC]Ratio in plane, out of plane jet spectrum");
356  ratio->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
357  ratio->GetYaxis()->SetTitle("yield IN / yield OUT");
358  ratio = ProtectHeap(ratio);
359  ratio->Write();
360  }
361  TGraphErrors* v2(GetV2((TH1D*)unfoldedJetSpectrumIn->Clone("unfoldedLocal_inv2"), (TH1D*)unfoldedJetSpectrumOut->Clone("unfoldedLocal_outv2"), fEventPlaneRes));
362  if(v2) {
363  v2->SetNameTitle("v2", "v_{2} from different in, out of plane yield");
364  v2->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
365  v2->GetYaxis()->SetTitle("v_{2}");
366  v2 = ProtectHeap(v2);
367  v2->Write();
368  }
369  }
370  } // end of if(fDphiUnfolding)
371  fDeltaPtDeltaPhi->Write();
372  unfoldedJetSpectrumIn->Sumw2();
373  fUnfoldedSpectrumIn = ProtectHeap(unfoldedJetSpectrumIn, kFALSE);
374  unfoldedJetSpectrumIn->Write();
375  unfoldedJetSpectrumOut->Sumw2();
376  fUnfoldedSpectrumOut = ProtectHeap(unfoldedJetSpectrumOut, kFALSE);
377  unfoldedJetSpectrumOut->Write();
378  fJetPtDeltaPhi->Write();
379  // save the current state of the unfolding object
380  SaveConfiguration(unfoldedJetSpectrumIn ? kTRUE : kFALSE, unfoldedJetSpectrumOut ? kTRUE : kFALSE);
381  TH1D* unfoldedJetSpectrumInForSub((TH1D*)unfoldedJetSpectrumIn->Clone("forSubIn"));
382  TH1D* unfoldedJetSpectrumOutForSub((TH1D*)unfoldedJetSpectrumOut->Clone("forSubOut"));
383  unfoldedJetSpectrumInForSub->Add(unfoldedJetSpectrumOutForSub, -1.);
384  unfoldedJetSpectrumInForSub= ProtectHeap(unfoldedJetSpectrumInForSub);
385  unfoldedJetSpectrumInForSub->Write();
386 
387 }
388 //_____________________________________________________________________________
390  const TH1D* measuredJetSpectrum, // truncated raw jets (same binning as pt rec of response)
391  const TH2D* resizedResponse, // response matrix
392  const TH1D* kinematicEfficiency, // kinematic efficiency
393  const TH1D* measuredJetSpectrumTrueBins, // unfolding template: same binning is pt gen of response
394  const TString suffix, // suffix (in or out of plane)
395  const TH1D* jetFindingEfficiency) // jet finding efficiency
396 {
397 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
398  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
399 #endif
400  // wrapper function to call specific unfolding routine
401  TH1D* (AliJetFlowTools::*myFunction)(const TH1D*, const TH2D*, const TH1D*, const TH1D*, const TString, const TH1D*);
402  // initialize functon pointer
407  else if(fUnfoldingAlgorithm == kFold) myFunction = &AliJetFlowTools::FoldSpectrum;
408  else if(fUnfoldingAlgorithm == kNone) {
409  TH1D* clone((TH1D*)measuredJetSpectrum->Clone("clone"));
410  clone->SetNameTitle(Form("MeasuredJetSpectrum%s", suffix.Data()), Form("measuredJetSpectrum %s", suffix.Data()));
411  return clone;//RebinTH1D(clone, fBinsTrue, clone->GetName(), kFALSE);
412  }
413  else return 0x0;
414  // do the actual unfolding with the selected function
415  return (this->*myFunction)( measuredJetSpectrum, resizedResponse, kinematicEfficiency, measuredJetSpectrumTrueBins, suffix, jetFindingEfficiency);
416 }
417 //_____________________________________________________________________________
419  const TH1D* measuredJetSpectrum, // truncated raw jets (same binning as pt rec of response)
420  const TH2D* resizedResponse, // response matrix
421  const TH1D* kinematicEfficiency, // kinematic efficiency
422  const TH1D* measuredJetSpectrumTrueBins, // unfolding template: same binning is pt gen of response
423  const TString suffix, // suffix (in or out of plane)
424  const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
425 {
426 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
427  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
428 #endif
429  // unfold the spectrum using chi2 minimization
430 
431  // step 0) setup the static members of AliUnfolding
432  ResetAliUnfolding(); // reset from previous iteration
433  // also deletes and re-creates the global TVirtualFitter
434  AliUnfolding::SetUnfoldingMethod(AliUnfolding::kChi2Minimization);
435  if(!strcmp("in", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaIn);
436  else if(!strcmp("out", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaOut);
437  if(!strcmp("prior_in", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaIn);
438  else if(!strcmp("prior_out", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaOut);
439  AliUnfolding::SetNbins(fBinsRec->GetSize()-1, fBinsTrue->GetSize()-1);
440 
441  // step 1) clone all input histograms. the histograms are cloned to make sure that the original histograms
442  // stay intact. a local copy of a histogram (which only exists in the scope of this function) is
443  // denoted by the suffix 'Local'
444 
445  // measuredJetSpectrumLocal holds the spectrum that needs to be unfolded
446  TH1D *measuredJetSpectrumLocal = (TH1D*)measuredJetSpectrum->Clone(Form("measuredJetSpectrumLocal_%s", suffix.Data()));
447  // unfolded local will be filled with the result of the unfolding
448  TH1D *unfoldedLocal(new TH1D(Form("unfoldedLocal_%s", suffix.Data()), Form("unfoldedLocal_%s", suffix.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
449 
450  // full response matrix and kinematic efficiency
451  TH2D* resizedResponseLocal = (TH2D*)resizedResponse->Clone(Form("resizedResponseLocal_%s", suffix.Data()));
452  TH1D* kinematicEfficiencyLocal = (TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiencyLocal_%s", suffix.Data()));
453 
454  // the initial guess for the unfolded pt spectrum, equal to the folded spectrum, but in 'true' bins
455  TH1D *priorLocal = (TH1D*)measuredJetSpectrumTrueBins->Clone(Form("priorLocal_%s", suffix.Data()));
456  // optionally, the prior can be smoothened by extrapolating the spectrum using a power law fit
457  if(fSmoothenPrior) priorLocal = SmoothenPrior(priorLocal, fPower, fFitMin, fFitMax, fFitStart, kTRUE, fSmoothenCounts);
458 
459  // step 2) start the unfolding
460  Int_t status(-1), i(0);
461  while(status < 0 && i < 100) {
462  // i > 0 means that the first iteration didn't converge. in that case, the result of the first
463  // iteration (stored in unfoldedLocal) is cloned and used as a starting point for the
464  if (i > 0) priorLocal = (TH1D*)unfoldedLocal->Clone(Form("priorLocal_%s_%i", suffix.Data(), i));
465  status = AliUnfolding::Unfold(
466  resizedResponseLocal, // response matrix
467  kinematicEfficiencyLocal, // efficiency applied on the unfolded spectrum (can be NULL)
468  measuredJetSpectrumLocal, // measured spectrum
469  priorLocal, // initial conditions (set NULL to use measured spectrum)
470  unfoldedLocal); // results
471  // status holds the minuit fit status (where 0 means convergence)
472  i++;
473  }
474  // get the status of TMinuit::mnhess(), fISW[1] == 3 means the hessian matrix was calculated succesfully
475  TH2D* hPearson(0x0);
476  if(status == 0 && gMinuit->fISW[1] == 3) {
477  // if the unfolding converged and the hessian matrix is reliable, plot the pearson coefficients
478  TVirtualFitter *fitter(TVirtualFitter::GetFitter());
479  if(gMinuit) gMinuit->Command("SET COV");
480  TMatrixD covarianceMatrix(fBinsTrue->GetSize()-1, fBinsTrue->GetSize()-1, fitter->GetCovarianceMatrix());
481  TMatrixD *pearson((TMatrixD*)CalculatePearsonCoefficients(&covarianceMatrix));
482  pearson->Print();
483  hPearson = new TH2D(*pearson);
484  hPearson->SetNameTitle(Form("PearsonCoefficients_%s", suffix.Data()), Form("Pearson coefficients, %s plane", suffix.Data()));
485  hPearson = ProtectHeap(hPearson);
486  hPearson->Write();
487  if(fMergeBinsArray) unfoldedLocal = MergeSpectrumBins(fMergeBinsArray, unfoldedLocal, hPearson);
488  } else status = -1;
489 
490  // step 3) refold the unfolded spectrum and save the ratio measured / refolded
491  TH1D *foldedLocal(fResponseMaker->MultiplyResponseGenerated(unfoldedLocal, resizedResponseLocal,kinematicEfficiencyLocal));
492  foldedLocal->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("Refolded jet spectrum, %s plane", suffix.Data()));
493  unfoldedLocal->SetNameTitle(Form("UnfoldedSpectrum_%s", suffix.Data()), Form("Unfolded jet spectrum, %s plane", suffix.Data()));
494  TGraphErrors* ratio(GetRatio(foldedLocal, measuredJetSpectrumLocal, TString(""), kTRUE, fBinsTrue->At(fBinsTrue->GetSize()-1)));
495  if(ratio) {
496  ratio->SetNameTitle("RatioRefoldedMeasured", Form("Ratio measured, re-folded %s ", suffix.Data()));
497  ratio->GetYaxis()->SetTitle("ratio measured / re-folded");
498  ratio = ProtectHeap(ratio);
499  ratio->Write();
500  }
501 
502  // step 4) write histograms to file. to ensure that these have unique identifiers on the heap,
503  // objects are cloned using 'ProtectHeap()'
504  measuredJetSpectrumLocal->SetNameTitle(Form("InputSpectrum_%s", suffix.Data()), Form("InputSpectrum_%s", suffix.Data()));
505  measuredJetSpectrumLocal = ProtectHeap(measuredJetSpectrumLocal);
506  measuredJetSpectrumLocal->Write();
507 
508  resizedResponseLocal = ProtectHeap(resizedResponseLocal);
509  resizedResponseLocal->Write();
510 
511  unfoldedLocal = ProtectHeap(unfoldedLocal);
512  if(jetFindingEfficiency) unfoldedLocal->Divide(jetFindingEfficiency);
513  unfoldedLocal->Write();
514 
515  foldedLocal = ProtectHeap(foldedLocal);
516  foldedLocal->Write();
517 
518  priorLocal = ProtectHeap(priorLocal);
519  priorLocal->Write();
520 
521  // step 5) save the fit status (penalty value, degrees of freedom, chi^2 value)
522  TH1F* fitStatus(new TH1F(Form("fitStatus_%s_%s", fActiveString.Data(), suffix.Data()), Form("fitStatus_%s_%s", fActiveString.Data(), suffix.Data()), 4, -0.5, 3.5));
523  fitStatus->SetBinContent(1, AliUnfolding::fChi2FromFit);
524  fitStatus->GetXaxis()->SetBinLabel(1, "fChi2FromFit");
525  fitStatus->SetBinContent(2, AliUnfolding::fPenaltyVal);
526  fitStatus->GetXaxis()->SetBinLabel(2, "fPenaltyVal");
527  fitStatus->SetBinContent(3, fBinsRec->GetSize()-fBinsTrue->GetSize());
528  fitStatus->GetXaxis()->SetBinLabel(3, "DOF");
529  fitStatus->SetBinContent(4, (!strcmp(suffix.Data(), "in")) ? fBetaIn : fBetaOut);
530  fitStatus->GetXaxis()->SetBinLabel(4, (!strcmp(suffix.Data(), "in")) ? "fBetaIn" : "fBetaOut");
531  fitStatus->Write();
532 
533  return unfoldedLocal;
534 }
535 //_____________________________________________________________________________
537  const TH1D* measuredJetSpectrum, // jet pt in pt rec bins
538  const TH2D* resizedResponse, // full response matrix, normalized in slides of pt true
539  const TH1D* kinematicEfficiency, // kinematic efficiency
540  const TH1D* measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
541  const TString suffix, // suffix (in, out)
542  const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
543 {
544 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
545  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
546 #endif
547  TH1D* priorLocal( GetPrior(
548  measuredJetSpectrum, // jet pt in pt rec bins
549  resizedResponse, // full response matrix, normalized in slides of pt true
550  kinematicEfficiency, // kinematic efficiency
551  measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
552  suffix, // suffix (in, out)
553  jetFindingEfficiency)); // jet finding efficiency (optional)
554  if(!priorLocal) {
555  printf(" > couldn't find prior ! < \n");
556  return 0x0;
557  } else printf(" 1) retrieved prior \n");
558 
559  // go back to the 'root' directory of this instance of the SVD unfolding routine
560  (!strcmp(suffix.Data(), "in")) ? fActiveDir->cd(Form("InPlane___%s", fActiveString.Data())) : fActiveDir->cd(Form("OutOfPlane___%s", fActiveString.Data()));
561 
562  // 2) setup all the necessary input for the unfolding routine. all input histograms are copied locally
563  // measured jets in pt rec binning
564  TH1D *measuredJetSpectrumLocal((TH1D*)measuredJetSpectrum->Clone(Form("jets_%s", suffix.Data())));
565  // local copie of the response matrix
566  TH2D *resizedResponseLocal((TH2D*)resizedResponse->Clone(Form("resizedResponseLocal_%s", suffix.Data())));
567  // local copy of response matrix, all true slides normalized to 1
568  // this response matrix will eventually be used in the re-folding routine
569  TH2D *resizedResponseLocalNorm((TH2D*)resizedResponse->Clone(Form("resizedResponseLocalNorm_%s", suffix.Data())));
570  resizedResponseLocalNorm = NormalizeTH2D(resizedResponseLocalNorm);
571  // kinematic efficiency
572  TH1D *kinematicEfficiencyLocal((TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiency_%s", suffix.Data())));
573  // place holder histos
574  TH1D *unfoldedLocalSVD(0x0);
575  TH1D *foldedLocalSVD(0x0);
576  cout << " 2) setup necessary input " << endl;
577  // 3) configure routine
578  RooUnfold::ErrorTreatment errorTreatment = (fSVDToy) ? RooUnfold::kCovToy : RooUnfold::kCovariance;
579  cout << " step 3) configured routine " << endl;
580 
581  // 4) get transpose matrices
582  // a) get the transpose of the full response matrix
583  TH2* responseMatrixLocalTransposePrior(fResponseMaker->GetTransposeResponsMatrix(resizedResponseLocal));
584  responseMatrixLocalTransposePrior->SetNameTitle(Form("prior_%s_%s", responseMatrixLocalTransposePrior->GetName(), suffix.Data()),Form("prior_%s_%s", responseMatrixLocalTransposePrior->GetName(), suffix.Data()));
585  // normalize it with the prior. this will ensure that high statistics bins will constrain the
586  // end result most strenuously than bins with limited number of counts
587  responseMatrixLocalTransposePrior = fResponseMaker->NormalizeResponsMatrixYaxisWithPrior(responseMatrixLocalTransposePrior, priorLocal);
588  cout << " 4) retrieved first transpose matrix " << endl;
589 
590  // 5) get response for SVD unfolding
591  RooUnfoldResponse responseSVD(0, 0, responseMatrixLocalTransposePrior, Form("respCombinedSVD_%s", suffix.Data()), Form("respCombinedSVD_%s", suffix.Data()));
592  cout << " 5) retrieved roo unfold response object " << endl;
593 
594  // 6) actualy unfolding loop
595  RooUnfoldSvd unfoldSVD(&responseSVD, measuredJetSpectrumLocal, (!strcmp(suffix.Data(), "in")) ? fSVDRegIn : fSVDRegOut);
596  unfoldedLocalSVD = (TH1D*)unfoldSVD.Hreco(errorTreatment);
597  // correct the spectrum for the kinematic efficiency
598  unfoldedLocalSVD->Divide(kinematicEfficiencyLocal);
599 
600  // get the pearson coefficients from the covariance matrix
601  TMatrixD covarianceMatrix = unfoldSVD.Ereco(errorTreatment);
602  TMatrixD *pearson = (TMatrixD*)CalculatePearsonCoefficients(&covarianceMatrix);
603  TH2D* hPearson(0x0);
604  if(pearson) {
605  hPearson = new TH2D(*pearson);
606  pearson->Print();
607  hPearson->SetNameTitle(Form("PearsonCoefficients_%s", suffix.Data()), Form("Pearson coefficients_%s", suffix.Data()));
608  hPearson = ProtectHeap(hPearson);
609  hPearson->Write();
610  if(fMergeBinsArray) unfoldedLocalSVD = MergeSpectrumBins(fMergeBinsArray, unfoldedLocalSVD, hPearson);
611  } else return 0x0; // return if unfolding didn't converge
612 
613  // plot singular values and d_i vector
614  TSVDUnfold* svdUnfold(unfoldSVD.Impl());
615  TH1* hSVal(svdUnfold->GetSV());
616  TH1D* hdi(svdUnfold->GetD());
617  hSVal->SetNameTitle("SingularValuesOfAC", "Singular values of AC^{-1}");
618  hSVal->SetXTitle("singular values");
619  hSVal->Write();
620  hdi->SetNameTitle("dVector", "d vector after orthogonal transformation");
621  hdi->SetXTitle("|d_{i}^{kreg}|");
622  hdi->Write();
623  cout << " plotted singular values and d_i vector " << endl;
624 
625  // 7) refold the unfolded spectrum
626  foldedLocalSVD = fResponseMaker->MultiplyResponseGenerated(unfoldedLocalSVD, resizedResponseLocalNorm, kinematicEfficiencyLocal);
627  TGraphErrors* ratio(GetRatio(measuredJetSpectrumLocal, foldedLocalSVD, "ratio measured / re-folded", kTRUE));
628  ratio->SetNameTitle(Form("RatioRefoldedMeasured_%s", fActiveString.Data()), Form("Ratio measured / re-folded %s", fActiveString.Data()));
629  ratio->GetXaxis()->SetTitle("p_{t}^{rec, rec} [GeV/ c]");
630  ratio->GetYaxis()->SetTitle("ratio measured / re-folded");
631  ratio->Write();
632  cout << " 7) refolded the unfolded spectrum " << endl;
633 
634  // write the measured, unfolded and re-folded spectra to the output directory
635  measuredJetSpectrumLocal->SetNameTitle(Form("InputSpectrum_%s", suffix.Data()), Form("input spectrum (measured) %s", suffix.Data()));
636  measuredJetSpectrumLocal = ProtectHeap(measuredJetSpectrumLocal);
637  measuredJetSpectrumLocal->SetXTitle("p_{t}^{rec} [GeV/c]");
638  measuredJetSpectrumLocal->Write(); // input spectrum
639  unfoldedLocalSVD->SetNameTitle(Form("UnfoldedSpectrum_%s",suffix.Data()), Form("unfolded spectrum %s", suffix.Data()));
640  unfoldedLocalSVD = ProtectHeap(unfoldedLocalSVD);
641  if(jetFindingEfficiency) unfoldedLocalSVD->Divide(jetFindingEfficiency);
642  unfoldedLocalSVD->Write(); // unfolded spectrum
643  foldedLocalSVD->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("refoldedSpectrum_%s", suffix.Data()));
644  foldedLocalSVD = ProtectHeap(foldedLocalSVD);
645  foldedLocalSVD->Write(); // re-folded spectrum
646 
647  // save more general bookkeeeping histograms to the output directory
648  responseMatrixLocalTransposePrior->SetNameTitle("TransposeResponseMatrix", "Transpose of response matrix, normalize with prior");
649  responseMatrixLocalTransposePrior->SetXTitle("p_{T, jet}^{true} [GeV/c]");
650  responseMatrixLocalTransposePrior->SetYTitle("p_{T, jet}^{rec} [GeV/c]");
651  responseMatrixLocalTransposePrior->Write();
652  priorLocal->SetNameTitle("PriorOriginal", "Prior, original");
653  priorLocal->SetXTitle("p_{t} [GeV/c]");
654  priorLocal = ProtectHeap(priorLocal);
655  priorLocal->Write();
656  resizedResponseLocalNorm = ProtectHeap(resizedResponseLocalNorm);
657  resizedResponseLocalNorm->Write();
658 
659  // save some info
660  TH1F* fitStatus(new TH1F(Form("fitStatus_%s_%s", fActiveString.Data(), suffix.Data()), Form("fitStatus_%s_%s", fActiveString.Data(), suffix.Data()), 1, -0.5, 0.5));
661  fitStatus->SetBinContent(1, (!strcmp(suffix.Data(), "in")) ? fSVDRegIn : fSVDRegOut);
662  fitStatus->GetXaxis()->SetBinLabel(1, (!strcmp(suffix.Data(), "in")) ? "fSVDRegIn" : "fSVDRegOut");
663  fitStatus->Write();
664 
665  return unfoldedLocalSVD;
666 }
667 //_____________________________________________________________________________
669  const TH1D* measuredJetSpectrum, // jet pt in pt rec bins
670  const TH2D* resizedResponse, // full response matrix, normalized in slides of pt true
671  const TH1D* kinematicEfficiency, // kinematic efficiency
672  const TH1D* measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
673  const TString suffix, // suffix (in, out)
674  const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
675 {
676 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
677  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
678 #endif
679  // unfold the spectrum using the bayesian unfolding impelmented in AliUnfolding
680  // FIXME careful, not tested yet ! (06122013) FIXME
681 
682  // step 0) setup the static members of AliUnfolding
683  ResetAliUnfolding(); // reset from previous iteration
684  // also deletes and re-creates the global TVirtualFitter
685  AliUnfolding::SetUnfoldingMethod(AliUnfolding::kBayesian);
686  if(!strcmp("in", suffix.Data())) AliUnfolding::SetBayesianParameters(fBayesianSmoothIn, fBayesianIterIn);
687  else if(!strcmp("out", suffix.Data())) AliUnfolding::SetBayesianParameters(fBayesianSmoothOut, fBayesianIterOut);
688  else if(!strcmp("prior_in", suffix.Data())) AliUnfolding::SetBayesianParameters(fBayesianSmoothIn, fBayesianIterIn);
689  else if(!strcmp("prior_out", suffix.Data())) AliUnfolding::SetBayesianParameters(fBayesianSmoothOut, fBayesianIterOut);
690  AliUnfolding::SetNbins(fBinsRec->GetSize()-1, fBinsTrue->GetSize()-1);
691 
692  // 1) get a prior for unfolding and clone all the input histograms
693  TH1D* priorLocal( GetPrior(
694  measuredJetSpectrum, // jet pt in pt rec bins
695  resizedResponse, // full response matrix, normalized in slides of pt true
696  kinematicEfficiency, // kinematic efficiency
697  measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
698  suffix, // suffix (in, out)
699  jetFindingEfficiency)); // jet finding efficiency (optional)
700  if(!priorLocal) {
701  printf(" > couldn't find prior ! < \n");
702  return 0x0;
703  } else printf(" 1) retrieved prior \n");
704  // switch back to root dir of this unfolding procedure
705  (!strcmp(suffix.Data(), "in")) ? fActiveDir->cd(Form("InPlane___%s", fActiveString.Data())) : fActiveDir->cd(Form("OutOfPlane___%s", fActiveString.Data()));
706 
707  // measuredJetSpectrumLocal holds the spectrum that needs to be unfolded
708  TH1D *measuredJetSpectrumLocal = (TH1D*)measuredJetSpectrum->Clone(Form("measuredJetSpectrumLocal_%s", suffix.Data()));
709  // unfolded local will be filled with the result of the unfolding
710  TH1D *unfoldedLocal(new TH1D(Form("unfoldedLocal_%s", suffix.Data()), Form("unfoldedLocal_%s", suffix.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
711 
712  // full response matrix and kinematic efficiency
713  TH2D* resizedResponseLocal = (TH2D*)resizedResponse->Clone(Form("resizedResponseLocal_%s", suffix.Data()));
714  TH1D* kinematicEfficiencyLocal = (TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiencyLocal_%s", suffix.Data()));
715 
716  // step 2) start the unfolding
717  Int_t status(-1), i(0);
718  while(status < 0 && i < 100) {
719  // i > 0 means that the first iteration didn't converge. in that case, the result of the first
720  // iteration (stored in unfoldedLocal) is cloned and used as a starting point for the
721  if (i > 0) priorLocal = (TH1D*)unfoldedLocal->Clone(Form("priorLocal_%s_%i", suffix.Data(), i));
722  status = AliUnfolding::Unfold(
723  resizedResponseLocal, // response matrix
724  kinematicEfficiencyLocal, // efficiency applied on the unfolded spectrum (can be NULL)
725  measuredJetSpectrumLocal, // measured spectrum
726  priorLocal, // initial conditions (set NULL to use measured spectrum)
727  unfoldedLocal); // results
728  // status holds the minuit fit status (where 0 means convergence)
729  i++;
730  }
731  // get the status of TMinuit::mnhess(), fISW[1] == 3 means the hessian matrix was calculated succesfully
732  TH2D* hPearson(0x0);
733  if(status == 0 && gMinuit->fISW[1] == 3) {
734  // if the unfolding converged and the hessian matrix is reliable, plot the pearson coefficients
735  TVirtualFitter *fitter(TVirtualFitter::GetFitter());
736  if(gMinuit) gMinuit->Command("SET COV");
737  TMatrixD covarianceMatrix(fBinsTrue->GetSize()-1, fBinsTrue->GetSize()-1, fitter->GetCovarianceMatrix());
738  TMatrixD *pearson((TMatrixD*)CalculatePearsonCoefficients(&covarianceMatrix));
739  pearson->Print();
740  hPearson= new TH2D(*pearson);
741  hPearson->SetNameTitle(Form("PearsonCoefficients_%s", suffix.Data()), Form("Pearson coefficients, %s plane", suffix.Data()));
742  hPearson = ProtectHeap(hPearson);
743  hPearson->Write();
744  } else status = -1;
745  if(fMergeBinsArray) unfoldedLocal = MergeSpectrumBins(fMergeBinsArray, unfoldedLocal, hPearson);
746 
747  // step 3) refold the unfolded spectrum and save the ratio measured / refolded
748  TH1D *foldedLocal(fResponseMaker->MultiplyResponseGenerated(unfoldedLocal, resizedResponseLocal,kinematicEfficiencyLocal));
749  foldedLocal->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("Refolded jet spectrum, %s plane", suffix.Data()));
750  unfoldedLocal->SetNameTitle(Form("UnfoldedSpectrum_%s", suffix.Data()), Form("Unfolded jet spectrum, %s plane", suffix.Data()));
751  TGraphErrors* ratio(GetRatio(foldedLocal, measuredJetSpectrumLocal, TString(""), kTRUE, fBinsTrue->At(fBinsTrue->GetSize()-1)));
752  if(ratio) {
753  ratio->SetNameTitle("RatioRefoldedMeasured", Form("Ratio measured, re-folded %s ", suffix.Data()));
754  ratio->GetYaxis()->SetTitle("ratio measured / re-folded");
755  ratio = ProtectHeap(ratio);
756  ratio->Write();
757  }
758 
759  // step 4) write histograms to file. to ensure that these have unique identifiers on the heap,
760  // objects are cloned using 'ProtectHeap()'
761  measuredJetSpectrumLocal->SetNameTitle(Form("InputSpectrum_%s", suffix.Data()), Form("InputSpectrum_%s", suffix.Data()));
762  measuredJetSpectrumLocal = ProtectHeap(measuredJetSpectrumLocal);
763  measuredJetSpectrumLocal->Write();
764 
765  resizedResponseLocal = ProtectHeap(resizedResponseLocal);
766  resizedResponseLocal->Write();
767 
768  unfoldedLocal = ProtectHeap(unfoldedLocal);
769  if(jetFindingEfficiency) unfoldedLocal->Divide(jetFindingEfficiency);
770  unfoldedLocal->Write();
771 
772  foldedLocal = ProtectHeap(foldedLocal);
773  foldedLocal->Write();
774 
775  priorLocal = ProtectHeap(priorLocal);
776  priorLocal->Write();
777 
778  // step 5) save the fit status (penalty value, degrees of freedom, chi^2 value)
779  TH1F* fitStatus(new TH1F(Form("fitStatus_%s_%s", fActiveString.Data(), suffix.Data()), Form("fitStatus_%s_%s", fActiveString.Data(), suffix.Data()), 4, -0.5, 3.5));
780  fitStatus->SetBinContent(1, AliUnfolding::fChi2FromFit);
781  fitStatus->GetXaxis()->SetBinLabel(1, "fChi2FromFit");
782  fitStatus->SetBinContent(2, AliUnfolding::fPenaltyVal);
783  fitStatus->GetXaxis()->SetBinLabel(2, "fPenaltyVal");
784  fitStatus->SetBinContent(3, fBinsRec->GetSize()-fBinsTrue->GetSize());
785  fitStatus->GetXaxis()->SetBinLabel(3, "DOF");
786  fitStatus->SetBinContent(4, (!strcmp(suffix.Data(), "in")) ? fBetaIn : fBetaOut);
787  fitStatus->GetXaxis()->SetBinLabel(4, (!strcmp(suffix.Data(), "in")) ? "fBetaIn" : "fBetaOut");
788  fitStatus->Write();
789 
790  return unfoldedLocal;
791 }
792 //_____________________________________________________________________________
794  const TH1D* measuredJetSpectrum, // jet pt in pt rec bins
795  const TH2D* resizedResponse, // full response matrix, normalized in slides of pt true
796  const TH1D* kinematicEfficiency, // kinematic efficiency
797  const TH1D* measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
798  const TString suffix, // suffix (in, out)
799  const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
800 {
801 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
802  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
803 #endif
804  // use bayesian unfolding from the RooUnfold package to unfold jet spectra
805 
806  // 1) get a prior for unfolding.
807  TH1D* priorLocal( GetPrior(
808  measuredJetSpectrum, // jet pt in pt rec bins
809  resizedResponse, // full response matrix, normalized in slides of pt true
810  kinematicEfficiency, // kinematic efficiency
811  measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
812  suffix, // suffix (in, out)
813  jetFindingEfficiency)); // jet finding efficiency (optional)
814  if(!priorLocal) {
815  printf(" > couldn't find prior ! < \n");
816  return 0x0;
817  } else printf(" 1) retrieved prior \n");
818  (!strcmp(suffix.Data(), "in")) ? fActiveDir->cd(Form("InPlane___%s", fActiveString.Data())) : fActiveDir->cd(Form("OutOfPlane___%s", fActiveString.Data()));
819 
820  // 2) setup all the necessary input for the unfolding routine. all input histograms are copied locally
821  // measured jets in pt rec binning
822  TH1D *measuredJetSpectrumLocal((TH1D*)measuredJetSpectrum->Clone(Form("jets_%s", suffix.Data())));
823  // local copie of the response matrix
824  TH2D *resizedResponseLocal((TH2D*)resizedResponse->Clone(Form("resizedResponseLocal_%s", suffix.Data())));
825  // local copy of response matrix, all true slides normalized to 1
826  // this response matrix will eventually be used in the re-folding routine
827  TH2D *resizedResponseLocalNorm((TH2D*)resizedResponse->Clone(Form("resizedResponseLocalNorm_%s", suffix.Data())));
828  resizedResponseLocalNorm = NormalizeTH2D(resizedResponseLocalNorm);
829  // kinematic efficiency
830  TH1D *kinematicEfficiencyLocal((TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiency_%s", suffix.Data())));
831  // place holder histos
832  TH1D *unfoldedLocalBayes(0x0);
833  TH1D *foldedLocalBayes(0x0);
834  cout << " 2) setup necessary input " << endl;
835  // 4) get transpose matrices
836  // a) get the transpose of the full response matrix
837  TH2* responseMatrixLocalTransposePrior(fResponseMaker->GetTransposeResponsMatrix(resizedResponseLocal));
838  responseMatrixLocalTransposePrior->SetNameTitle(Form("prior_%s_%s", responseMatrixLocalTransposePrior->GetName(), suffix.Data()),Form("prior_%s_%s", responseMatrixLocalTransposePrior->GetName(), suffix.Data()));
839  // normalize it with the prior. this will ensure that high statistics bins will constrain the
840  // end result most strenuously than bins with limited number of counts
841  responseMatrixLocalTransposePrior = fResponseMaker->NormalizeResponsMatrixYaxisWithPrior(responseMatrixLocalTransposePrior, priorLocal);
842  // 3) get response for Bayesian unfolding
843  RooUnfoldResponse responseBayes(0, 0, responseMatrixLocalTransposePrior, Form("respCombinedBayes_%s", suffix.Data()), Form("respCombinedBayes_%s", suffix.Data()));
844 
845  // 4) actualy unfolding loop
846  RooUnfoldBayes unfoldBayes(&responseBayes, measuredJetSpectrumLocal, (!strcmp("in", suffix.Data())) ? fBayesianIterIn : fBayesianIterOut);
847  RooUnfold::ErrorTreatment errorTreatment = (fSVDToy) ? RooUnfold::kCovToy : RooUnfold::kCovariance;
848  unfoldedLocalBayes = (TH1D*)unfoldBayes.Hreco(errorTreatment);
849  // correct the spectrum for the kinematic efficiency
850  unfoldedLocalBayes->Divide(kinematicEfficiencyLocal);
851  // get the pearson coefficients from the covariance matrix
852  TMatrixD covarianceMatrix = unfoldBayes.Ereco(errorTreatment);
853  TMatrixD *pearson = (TMatrixD*)CalculatePearsonCoefficients(&covarianceMatrix);
854  TH2D* hPearson(0x0);
855  if(pearson) {
856  hPearson = new TH2D(*pearson);
857  pearson->Print();
858  hPearson->SetNameTitle(Form("PearsonCoefficients_%s", suffix.Data()), Form("Pearson coefficients_%s", suffix.Data()));
859  hPearson = ProtectHeap(hPearson);
860  hPearson->Write();
861  if(fMergeBinsArray) unfoldedLocalBayes = MergeSpectrumBins(fMergeBinsArray, unfoldedLocalBayes, hPearson);
862  } else return 0x0; // return if unfolding didn't converge
863 
864  // 5) refold the unfolded spectrum
865  foldedLocalBayes = fResponseMaker->MultiplyResponseGenerated(unfoldedLocalBayes, resizedResponseLocalNorm, kinematicEfficiencyLocal);
866  TGraphErrors* ratio(GetRatio(measuredJetSpectrumLocal, foldedLocalBayes, "ratio measured / re-folded", kTRUE));
867  ratio->SetNameTitle(Form("RatioRefoldedMeasured_%s", fActiveString.Data()), Form("Ratio measured / re-folded %s", fActiveString.Data()));
868  ratio->GetXaxis()->SetTitle("p_{t}^{rec, rec} [GeV/ c]");
869  ratio->GetYaxis()->SetTitle("ratio measured / re-folded");
870  ratio->Write();
871  cout << " 7) refolded the unfolded spectrum " << endl;
872 
873  // write the measured, unfolded and re-folded spectra to the output directory
874  measuredJetSpectrumLocal->SetNameTitle(Form("InputSpectrum_%s", suffix.Data()), Form("input spectrum (measured) %s", suffix.Data()));
875  measuredJetSpectrumLocal = ProtectHeap(measuredJetSpectrumLocal);
876  measuredJetSpectrumLocal->SetXTitle("p_{t}^{rec} [GeV/c]");
877  measuredJetSpectrumLocal->Write(); // input spectrum
878  unfoldedLocalBayes->SetNameTitle(Form("UnfoldedSpectrum_%s",suffix.Data()), Form("unfolded spectrum %s", suffix.Data()));
879  unfoldedLocalBayes = ProtectHeap(unfoldedLocalBayes);
880  if(jetFindingEfficiency) unfoldedLocalBayes->Divide(jetFindingEfficiency);
881  unfoldedLocalBayes->Write(); // unfolded spectrum
882  foldedLocalBayes->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("refoldedSpectrum_%s", suffix.Data()));
883  foldedLocalBayes = ProtectHeap(foldedLocalBayes);
884  foldedLocalBayes->Write(); // re-folded spectrum
885 
886  // save more general bookkeeeping histograms to the output directory
887  responseMatrixLocalTransposePrior->SetNameTitle("TransposeResponseMatrix", "Transpose of response matrix, normalize with prior");
888  responseMatrixLocalTransposePrior->SetXTitle("p_{T, jet}^{true} [GeV/c]");
889  responseMatrixLocalTransposePrior->SetYTitle("p_{T, jet}^{rec} [GeV/c]");
890  responseMatrixLocalTransposePrior->Write();
891  priorLocal->SetNameTitle("PriorOriginal", "Prior, original");
892  priorLocal->SetXTitle("p_{t} [GeV/c]");
893  priorLocal = ProtectHeap(priorLocal);
894  priorLocal->Write();
895  resizedResponseLocalNorm = ProtectHeap(resizedResponseLocalNorm);
896  resizedResponseLocalNorm->Write();
897 
898  // save some info
899  TH1F* fitStatus(new TH1F(Form("fitStatus_%s_%s", fActiveString.Data(), suffix.Data()), Form("fitStatus_%s_%s", fActiveString.Data(), suffix.Data()), 1, -0.5, 0.5));
900  fitStatus->SetBinContent(1, (!strcmp(suffix.Data(), "in")) ? fBayesianIterIn : fBayesianIterOut);
901  fitStatus->GetXaxis()->SetBinLabel(1, (!strcmp(suffix.Data(), "in")) ? "fBayesianIterIn" : "fBayesianIterOut");
902  fitStatus->Write();
903 
904  return unfoldedLocalBayes;
905 }
906 //_____________________________________________________________________________
908  const TH1D* measuredJetSpectrum, // truncated raw jets (same binning as pt rec of response)
909  const TH2D* resizedResponse, // response matrix
910  const TH1D* kinematicEfficiency, // kinematic efficiency
911  const TH1D* measuredJetSpectrumTrueBins, // not used
912  const TString suffix, // suffix (in or out of plane)
913  const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
914 {
915 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
916  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
917 #endif
918  // simple function to fold the given spectrum with the in-plane and out-of-plane response
919 
920  if(!measuredJetSpectrumTrueBins) SquelchWarning();
921  // 0) for consistency with the other methods, keep the same nomenclature which admittedly is a bit confusing
922  // what is 'unfolded' here, is just a clone of the input spectrum, binned to the 'unfolded' binning
923  TH1D* unfoldedLocal((TH1D*)measuredJetSpectrum->Clone(Form("unfoldedLocal_%s", suffix.Data())));
924 
925  // 1) full response matrix and kinematic efficiency
926  TH2D* resizedResponseLocal = (TH2D*)resizedResponse->Clone(Form("resizedResponseLocal_%s", suffix.Data()));
927  TH1D* kinematicEfficiencyLocal = (TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiencyLocal_%s", suffix.Data()));
928 
929  // step 2) fold the 'unfolded' spectrum and save the ratio measured / refolded
930  TH1D *foldedLocal(fResponseMaker->MultiplyResponseGenerated(unfoldedLocal, resizedResponseLocal,kinematicEfficiencyLocal));
931  foldedLocal->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("Refolded jet spectrum, %s plane", suffix.Data()));
932  unfoldedLocal->SetNameTitle(Form("UnfoldedSpectrum_%s", suffix.Data()), Form("Unfolded jet spectrum, %s plane", suffix.Data()));
933 
934  // step 3) write histograms to file. to ensure that these have unique identifiers on the heap,
935  // objects are cloned using 'ProtectHeap()'
936  TH1D* measuredJetSpectrumLocal((TH1D*)(measuredJetSpectrum->Clone("tempObject")));
937  measuredJetSpectrumLocal->SetNameTitle(Form("InputSpectrum_%s", suffix.Data()), Form("InputSpectrum_%s", suffix.Data()));
938  measuredJetSpectrumLocal = ProtectHeap(measuredJetSpectrumLocal);
939  measuredJetSpectrumLocal->Write();
940 
941  resizedResponseLocal = ProtectHeap(resizedResponseLocal);
942  resizedResponseLocal->Write();
943 
944  unfoldedLocal = ProtectHeap(unfoldedLocal);
945  if(jetFindingEfficiency) unfoldedLocal->Divide(jetFindingEfficiency);
946  unfoldedLocal->Write();
947 
948  foldedLocal = ProtectHeap(foldedLocal);
949  foldedLocal->Write();
950 
951  // return the folded result
952  return foldedLocal;
953 }
954 //_____________________________________________________________________________
955 Bool_t AliJetFlowTools::PrepareForUnfolding(TH1* customIn, TH1* customOut)
956 {
957 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
958  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
959 #endif
960  // prepare for unfolding. check if all the necessary input data is available, if not, retrieve it
961  if(fRawInputProvided) return kTRUE;
962  if(!fInputList) {
963  printf(" AliJetFlowTools::PrepareForUnfolding() fInputList not found \n - Set a list using AliJetFlowTools::SetInputList() \n");
964  return kFALSE;
965  }
966  if(!fDetectorResponse) printf(" WARNING, no detector response supplied ! May be ok (depending on what you want to do) \n ");
967  // check if the pt bin for true and rec have been set
968  if(!fBinsTrue || !fBinsRec) {
969  printf(" AliJetFlowTools::PrepareForUnfolding() no true or rec bins set, aborting ! \n");
970  return kFALSE;
971  }
972  if(!fRMSSpectrumIn && fDphiUnfolding) { // initialie the profiles which will hold the RMS values. if binning changes in between unfolding
973  // procedures, these profiles will be nonsensical, user is responsible
974  fRMSSpectrumIn = new TProfile("fRMSSpectrumIn", "fRMSSpectrumIn", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
975  fRMSSpectrumOut = new TProfile("fRMSSpectrumOut", "fRMSSpectrumOut", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
976  fRMSRatio = new TProfile("fRMSRatio", "fRMSRatio", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
977  }
978  if(!fTrainPower) {
979  // clear minuit state to avoid constraining the fit with the results of the previous iteration
980  for(Int_t i(0); i < fPower->GetNpar(); i++) fPower->SetParameter(i, 0.);
981  }
982  // extract the spectra
983  TString spectrumName(Form("fHistJetPsi2Pt_%i", fCentralityArray->At(0)));
984  if(fRho0) spectrumName = Form("fHistJetPsi2PtRho0_%i", fCentralityArray->At(0));
985  if(!fInputList->FindObject(spectrumName.Data())) {
986  printf(" Couldn't find spectrum %s ! \n", spectrumName.Data());
987  return kFALSE;
988  }
989 
990  // get the first scaled spectrum
991  fJetPtDeltaPhi = (TH2D*)fInputList->FindObject(spectrumName.Data());
992  // clone the spectrum on the heap. this is necessary since scale or add change the
993  // contents of the original histogram
995  fJetPtDeltaPhi->Scale(fCentralityWeights->At(0));
996  printf("Extracted %s wight weight %.2f \n", spectrumName.Data(), fCentralityWeights->At(0));
997  // merge subsequent bins (if any)
998  for(Int_t i(1); i < fCentralityArray->GetSize(); i++) {
999  spectrumName = Form("fHistJetPsi2Pt_%i", fCentralityArray->At(i));
1000  printf( " Merging with %s with weight %.4f \n", spectrumName.Data(), fCentralityWeights->At(i));
1001  fJetPtDeltaPhi->Add(((TH2D*)fInputList->FindObject(spectrumName.Data())), fCentralityWeights->At(i));
1002  }
1003  // if a second list is passed, merge this with the existing one
1004  if(fMergeWithList) {
1005  spectrumName = Form("fHistJetPsi2Pt_%i", fMergeWithCen);
1006  printf( " Adding additional output %s \n", spectrumName.Data());
1007  fJetPtDeltaPhi->Add(((TH2D*)fMergeWithList->FindObject(spectrumName.Data())), fMergeWithWeight);
1008  }
1009 
1010  // in plane spectrum
1011  if(!fDphiUnfolding) {
1012  fSpectrumIn = fJetPtDeltaPhi->ProjectionY(Form("_py_in_%s", spectrumName.Data()), 1, 40, "e");
1013  fSpectrumOut = fJetPtDeltaPhi->ProjectionY(Form("_py_out_%s", spectrumName.Data()), 1, 40, "e");
1014  } else {
1015  fSpectrumIn = fJetPtDeltaPhi->ProjectionY(Form("_py_ina_%s", spectrumName.Data()), 1, 10, "e");
1016  fSpectrumIn->Add(fJetPtDeltaPhi->ProjectionY(Form("_py_inb_%s", spectrumName.Data()), 31, 40, "e"));
1018  // out of plane spectrum
1019  fSpectrumOut = fJetPtDeltaPhi->ProjectionY(Form("_py_out_%s", spectrumName.Data()), 11, 30, "e");
1021  }
1022  // if a custom input is passed, overwrite existing histograms
1023  if(customIn) fSpectrumIn = dynamic_cast<TH1D*>(customIn);
1024  if(customOut) fSpectrumOut = dynamic_cast<TH1D*>(customOut);
1025 
1026  // normalize spectra to event count if requested
1027  if(fNormalizeSpectra) {
1028  TH1* rho((TH1*)fInputList->FindObject(Form("fHistRho_%i", fCentralityArray->At(0))));
1029  rho->Scale(fCentralityWeights->At(0));
1030  for(Int_t i(1); i < fCentralityArray->GetSize(); i++) {
1031  rho->Add((TH1*)fInputList->FindObject(Form("fHistRho_%i", fCentralityArray->At(i))), fCentralityWeights->At(i));
1032  }
1033  if(!rho) return 0x0;
1034  Bool_t normalizeToFullSpectrum = (fEventCount < 0) ? kTRUE : kFALSE;
1035  if (normalizeToFullSpectrum) fEventCount = rho->GetEntries();
1036  if(fEventCount > 0) {
1037  fSpectrumIn->Sumw2(); // necessary for correct error propagation of scale
1038  fSpectrumOut->Sumw2();
1039  Double_t pt(0);
1040  Double_t error(0); // lots of issues with the errors here ...
1041  for(Int_t i(0); i < fSpectrumIn->GetXaxis()->GetNbins(); i++) {
1042  pt = fSpectrumIn->GetBinContent(1+i)/fEventCount; // normalized count
1043  error = 1./((double)(fEventCount*fEventCount))*fSpectrumIn->GetBinError(1+i)*fSpectrumIn->GetBinError(1+i);
1044  fSpectrumIn->SetBinContent(1+i, pt);
1045  if(pt <= 0 ) fSpectrumIn->SetBinError(1+i, 0.);
1046  if(error > 0) fSpectrumIn->SetBinError(1+i, error);
1047  else fSpectrumIn->SetBinError(1+i, TMath::Sqrt(pt));
1048  }
1049  for(Int_t i(0); i < fSpectrumOut->GetXaxis()->GetNbins(); i++) {
1050  pt = fSpectrumOut->GetBinContent(1+i)/fEventCount; // normalized count
1051  error = 1./((double)(fEventCount*fEventCount))*fSpectrumOut->GetBinError(1+i)*fSpectrumOut->GetBinError(1+i);
1052  fSpectrumOut->SetBinContent(1+i, pt);
1053  if( pt <= 0) fSpectrumOut->SetBinError(1+i, 0.);
1054  if(error > 0) fSpectrumOut->SetBinError(1+i, error);
1055  else fSpectrumOut->SetBinError(1+i, TMath::Sqrt(pt));
1056  }
1057  }
1058  if(normalizeToFullSpectrum) fEventCount = -1;
1059  }
1060  // extract the delta pt matrices
1061  TString deltaptName("");
1062  if(!fRho0) {
1063  deltaptName += (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJ_%i", fCentralityArray->At(0)) : Form("fHistDeltaPtDeltaPhi2_%i", fCentralityArray->At(0));
1064  } else {
1065  deltaptName += (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJRho0_%i", fCentralityArray->At(0)) : Form("fHistDeltaPtDeltaPhi2Rho0_%i", fCentralityArray->At(0));
1066  }
1067  fDeltaPtDeltaPhi = ((TH2D*)fInputList->FindObject(deltaptName.Data()));
1068  if(!fDeltaPtDeltaPhi) {
1069  printf(" Couldn't find delta pt matrix %s ! \n", deltaptName.Data());
1070  printf(" > may be ok, depending no what you want to do < \n");
1071  fRefreshInput = kTRUE;
1072  return kTRUE;
1073  }
1074 
1075  // clone the distribution on the heap and if requested merge with other centralities
1077  fDeltaPtDeltaPhi->Scale(fCentralityWeights->At(0));
1078  printf("Extracted %s with weight %.2f \n", deltaptName.Data(), fCentralityWeights->At(0));
1079  for(Int_t i(1); i < fCentralityArray->GetSize(); i++) {
1080  deltaptName = (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJ_%i", fCentralityArray->At(i)) : Form("fHistDeltaPtDeltaPhi2_%i", fCentralityArray->At(i));
1081  printf(" Merging with %s with weight %.4f \n", deltaptName.Data(), fCentralityWeights->At(i));
1082  fDeltaPtDeltaPhi->Add((TH2D*)fInputList->FindObject(deltaptName.Data()), fCentralityWeights->At(i));
1083  }
1084  // if a second list is passed, merge this with the existing one
1085  if(fMergeWithList) {
1086  deltaptName = (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJ_%i", fMergeWithCen) : Form("fHistDeltaPtDeltaPhi2_%i", fMergeWithCen);
1087  printf(" Adding additional data %s \n", deltaptName.Data());
1088  fDeltaPtDeltaPhi->Add((TH2D*)fMergeWithList->FindObject(deltaptName.Data()), fMergeWithWeight);
1089  }
1090 
1091  // in plane delta pt distribution
1092  if(!fDphiUnfolding) {
1093  fDptInDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_in_%s", deltaptName.Data()), 1, 40, "e");
1094  fDptOutDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_out_%s", deltaptName.Data()), 1, 40, "e");
1095  } else {
1096  fDptInDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_ina_%s", deltaptName.Data()), 1, 10, "e");
1097  fDptInDist->Add(fDeltaPtDeltaPhi->ProjectionY(Form("_py_inb_%s", deltaptName.Data()), 31, 40, "e"));
1098  // out of plane delta pt distribution
1099  fDptOutDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_out_%s", deltaptName.Data()), 11, 30, "e");
1102  // TODO get dpt response matrix from ConstructDPtResponseFromTH1D
1103  }
1104 
1105  // create a rec - true smeared response matrix
1106  TMatrixD* rfIn = new TMatrixD(-50, 249, -50, 249);
1107  for(Int_t j(-50); j < 250; j++) { // loop on pt true slices j
1108  Bool_t skip = kFALSE;
1109  for(Int_t k(-50); k < 250; k++) { // loop on pt gen slices k
1110  (*rfIn)(k, j) = (skip) ? 0. : fDptInDist->GetBinContent(fDptInDist->GetXaxis()->FindBin(k-j));
1111  if(fAvoidRoundingError && k > j && TMath::AreEqualAbs(fDptInDist->GetBinContent(fDptInDist->GetXaxis()->FindBin(k-j)), 0, 1e-8)) skip = kTRUE;
1112  }
1113  }
1114  TMatrixD* rfOut = new TMatrixD(-50, 249, -50, 249);
1115  for(Int_t j(-50); j < 250; j++) { // loop on pt true slices j
1116  Bool_t skip = kFALSE;
1117  for(Int_t k(-50); k < 250; k++) { // loop on pt gen slices k
1118  (*rfOut)(k, j) = (skip) ? 0. : fDptOutDist->GetBinContent(fDptOutDist->GetXaxis()->FindBin(k-j));
1119  if(fAvoidRoundingError && k > j && TMath::AreEqualAbs(fDptOutDist->GetBinContent(fDptOutDist->GetXaxis()->FindBin(k-j)), 0, 1e-8)) skip = kTRUE;
1120  }
1121  }
1122  fDptIn = new TH2D(*rfIn);
1123  fDptIn->SetNameTitle(Form("dpt_response_INPLANE_%i", fCentralityArray->At(0)), Form("dpt_response_INPLANE_%i", fCentralityArray->At(0)));
1124  fDptIn->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
1125  fDptIn->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
1127  fDptOut = new TH2D(*rfOut);
1128  fDptOut->SetNameTitle(Form("dpt_response_OUTOFPLANE_%i", fCentralityArray->At(0)), Form("dpt_response_OUTOFPLANE_%i", fCentralityArray->At(0)));
1129  fDptOut->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
1130  fDptOut->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
1132 
1133  fRefreshInput = kTRUE; // force cloning of the input
1134  return kTRUE;
1135 }
1136 //_____________________________________________________________________________
1137 Bool_t AliJetFlowTools::PrepareForUnfolding(Int_t low, Int_t up) {
1138  // prepare for unfoldingUA - more robust method to extract input spectra from file
1139  // will replace PrepareForUnfolding eventually (09012014)
1140 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1141  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1142 #endif
1143  if(!fInputList) {
1144  printf(" AliJetFlowTools::PrepareForUnfolding() fInputList not found \n - Set a list using AliJetFlowTools::SetInputList() \n");
1145  return kFALSE;
1146  }
1147  if(!fDetectorResponse) printf(" WARNING, no detector response supplied ! May be ok (depending on what you want to do) \n ");
1148  // check if the pt bin for true and rec have been set
1149  if(!fBinsTrue || !fBinsRec) {
1150  printf(" AliJetFlowTools::PrepareForUnfolding() no true or rec bins set, aborting ! \n");
1151  return kFALSE;
1152  }
1153  if(!fTrainPower) {
1154  // clear minuit state to avoid constraining the fit with the results of the previous iteration
1155  for(Int_t i(0); i < fPower->GetNpar(); i++) fPower->SetParameter(i, 0.);
1156  }
1157  // extract the spectra
1158  TString spectrumName(Form("fHistJetPsi2Pt_%i", fCentralityArray->At(0)));
1159  if(fRho0) spectrumName = Form("fHistJetPsi2PtRho0_%i", fCentralityArray->At(0));
1160  fJetPtDeltaPhi = ((TH2D*)fInputList->FindObject(spectrumName.Data()));
1161  if(!fJetPtDeltaPhi) {
1162  printf(" Couldn't find spectrum %s ! \n", spectrumName.Data());
1163  return kFALSE;
1164  }
1165  if(fCentralityArray) {
1166  for(Int_t i(1); i < fCentralityArray->GetSize(); i++) {
1167  spectrumName = Form("fHistJetPsi2Pt_%i", fCentralityArray->At(i));
1168  fJetPtDeltaPhi->Add(((TH2D*)fInputList->FindObject(spectrumName.Data())));
1169  }
1170  }
1171  fJetPtDeltaPhi = ProtectHeap(fJetPtDeltaPhi, kFALSE);
1172  // in plane spectrum
1173  fSpectrumIn = fJetPtDeltaPhi->ProjectionY(Form("_py_in_%s", spectrumName.Data()), low, up, "e");
1174  // extract the delta pt matrices
1175  TString deltaptName("");
1176  if(!fRho0) {
1177  deltaptName += (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJ_%i", fCentralityArray->At(0)) : Form("fHistDeltaPtDeltaPhi2_%i", fCentralityArray->At(0));
1178  } else {
1179  deltaptName += (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJRho0_%i", fCentralityArray->At(0)) : Form("fHistDeltaPtDeltaPhi2Rho0_%i", fCentralityArray->At(0));
1180  }
1181  fDeltaPtDeltaPhi = ((TH2D*)fInputList->FindObject(deltaptName.Data()));
1182  if(!fDeltaPtDeltaPhi) {
1183  printf(" Couldn't find delta pt matrix %s ! \n", deltaptName.Data());
1184  printf(" > may be ok, depending no what you want to do < \n");
1185  fRefreshInput = kTRUE;
1186  return kTRUE;
1187  }
1188  if(fCentralityArray) {
1189  for(Int_t i(1); i < fCentralityArray->GetSize(); i++) {
1190  deltaptName += (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJ_%i", fCentralityArray->At(i)) : Form("fHistDeltaPtDeltaPhi2_%i", fCentralityArray->At(i));
1191  fDeltaPtDeltaPhi->Add(((TH2D*)fInputList->FindObject(deltaptName.Data())));
1192  }
1193  }
1194 
1196  // in plane delta pt distribution
1197  fDptInDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_in_%s", deltaptName.Data()), low, up, "e");
1198  // create a rec - true smeared response matrix
1199  TMatrixD* rfIn = new TMatrixD(-50, 249, -50, 249);
1200  for(Int_t j(-50); j < 250; j++) { // loop on pt true slices j
1201  Bool_t skip = kFALSE;
1202  for(Int_t k(-50); k < 250; k++) { // loop on pt gen slices k
1203  (*rfIn)(k, j) = (skip) ? 0. : fDptInDist->GetBinContent(fDptInDist->GetXaxis()->FindBin(k-j));
1204  if(fAvoidRoundingError && k > j && TMath::AreEqualAbs(fDptInDist->GetBinContent(fDptInDist->GetXaxis()->FindBin(k-j)), 0, 1e-8)) skip = kTRUE;
1205  }
1206  }
1207  fDptIn = new TH2D(*rfIn);
1208  fDptIn->SetNameTitle(Form("dpt_response_INPLANE_%i", fCentralityArray->At(0)), Form("dpt_response_INPLANE_%i", fCentralityArray->At(0)));
1209  fDptIn->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
1210  fDptIn->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
1212 
1213  return kTRUE;
1214 }
1215 //_____________________________________________________________________________
1217  const TH1D* measuredJetSpectrum, // jet pt in pt rec bins
1218  const TH2D* resizedResponse, // full response matrix, normalized in slides of pt true
1219  const TH1D* kinematicEfficiency, // kinematic efficiency
1220  const TH1D* measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
1221  const TString suffix, // suffix (in, out)
1222  const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
1223 {
1224 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1225  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1226 #endif
1227  // 1) get a prior for unfolding.
1228  // this can be either an unfolded spectrum from e.g. chi2 unfolding or the measured spectrum
1229  TH1D* unfolded(0x0);
1230  TDirectoryFile* dirOut = new TDirectoryFile(Form("Prior_%s___%s", suffix.Data(), fActiveString.Data()), Form("Prior_%s___%s", suffix.Data(), fActiveString.Data()));
1231  dirOut->cd();
1232  switch (fPrior) { // select the prior for unfolding
1233  case kPriorTF1 : {
1234  if(!fPriorUser) {
1235  printf("> GetPrior:: FATAL ERROR! TF1 prior requested but prior has not been set ! < \n");
1236  return 0x0;
1237  }
1238  return fPriorUser;
1239  } break;
1240  case kPriorPythia : {
1241  if(!fPriorUser) {
1242  printf("> GetPrior:: FATAL ERROR! pythia prior requested but prior has not been set ! < \n");
1243  return 0x0;
1244  }
1245  // rebin the given prior to the true spectrum (creates a new histo)
1246  return RebinTH1D(fPriorUser, fBinsTrue, Form("kPriorPythia_%s", suffix.Data()), kFALSE);
1247  } break;
1248  case kPriorChi2 : {
1249  TArrayI* placeHolder(0x0);
1250  if(fMergeBinsArray) {
1251  placeHolder = fMergeBinsArray;
1252  fMergeBinsArray = 0x0;
1253  }
1254  if(fBinsTruePrior && fBinsRecPrior) { // if set, use different binning for the prior
1255  TArrayD* tempArrayTrue(fBinsTrue); // temporarily cache the original binning
1256  fBinsTrue = fBinsTruePrior; // switch binning schemes (will be used in UnfoldSpectrumChi2())
1257  TArrayD* tempArrayRec(fBinsRec);
1259  // for the prior, do not re-bin the output
1260  TH1D* measuredJetSpectrumChi2 = RebinTH1D((!strcmp("in", suffix.Data())) ? fSpectrumIn : fSpectrumOut, fBinsRec, TString("resized_chi2"), kFALSE);
1261  TH1D* measuredJetSpectrumTrueBinsChi2 = RebinTH1D((!strcmp("in", suffix.Data())) ? fSpectrumIn : fSpectrumOut, fBinsTruePrior, TString("out"), kFALSE);
1262  TH2D* resizedResponseChi2(RebinTH2D((!strcmp("in", suffix.Data())) ? fFullResponseIn : fFullResponseOut,fBinsTruePrior, fBinsRec, TString("chi2")));
1263  TH1D* kinematicEfficiencyChi2(resizedResponseChi2->ProjectionX());
1264  kinematicEfficiencyChi2->SetNameTitle("kin_eff_chi2","kin_eff_chi2");
1265  for(Int_t i(0); i < kinematicEfficiencyChi2->GetXaxis()->GetNbins(); i++) kinematicEfficiencyChi2->SetBinError(1+i, 0.);
1266  unfolded= UnfoldSpectrumChi2(
1267  measuredJetSpectrumChi2,
1268  resizedResponseChi2,
1269  kinematicEfficiencyChi2,
1270  measuredJetSpectrumTrueBinsChi2, // prior for chi2 unfolding (measured)
1271  TString(Form("prior_%s", suffix.Data())));
1272  if(!unfolded) {
1273  printf(" > GetPrior:: panic, couldn't get prior from Chi2 unfolding! \n");
1274  printf(" probably Chi2 unfolding did not converge < \n");
1275  if(placeHolder) fMergeBinsArray = placeHolder;
1276  return 0x0;
1277  }
1278  fBinsTrue = tempArrayTrue; // reset bins borders
1279  fBinsRec = tempArrayRec;
1280  // if the chi2 prior has a different binning, rebin to the true binning for the unfolding
1281  unfolded = RebinTH1D(unfolded, fBinsTrue, TString(Form("unfoldedChi2Prior_%s", suffix.Data()))); // rebin unfolded
1282  } else {
1283  unfolded = UnfoldSpectrumChi2(
1284  measuredJetSpectrum,
1285  resizedResponse,
1286  kinematicEfficiency,
1287  measuredJetSpectrumTrueBins, // prior for chi2 unfolding (measured)
1288  TString(Form("prior_%s", suffix.Data())));
1289  if(!unfolded) {
1290  printf(" > GetPrior:: panic, couldn't get prior from Chi2 unfolding! \n");
1291  printf(" probably Chi2 unfolding did not converge < \n");
1292  if(placeHolder) fMergeBinsArray = placeHolder;
1293  return 0x0;
1294  }
1295  if(placeHolder) fMergeBinsArray = placeHolder;
1296  }
1297  break;
1298 
1299  }
1300  case kPriorMeasured : {
1301  unfolded = (TH1D*)measuredJetSpectrumTrueBins->Clone(Form("kPriorMeasured_%s", suffix.Data())); // copy template to unfolded to use as prior
1302  }
1303  default : break;
1304  }
1305  // it can be important that the prior is smooth, this can be achieved by
1306  // extrapolating the spectrum with a fitted power law when bins are sparsely filed
1307  if(jetFindingEfficiency) unfolded->Divide(jetFindingEfficiency);
1308  TH1D *priorLocal((TH1D*)unfolded->Clone(Form("priorUnfolded_%s", suffix.Data())));
1309  if(fSmoothenPrior) priorLocal = SmoothenPrior(priorLocal, fPower, fFitMin, fFitMax, fFitStart, kTRUE, fSmoothenCounts);
1310  return priorLocal;
1311 }
1312 //_____________________________________________________________________________
1313 TH1D* AliJetFlowTools::ResizeXaxisTH1D(TH1D* histo, Int_t low, Int_t up, TString suffix) {
1314  // resize the x-axis of a th1d
1315 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1316  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1317 #endif
1318  if(!histo) {
1319  printf(" > ResizeXaxisTH!D:: fatal error, NULL pointer passed < \n");
1320  return NULL;
1321  }
1322  // see how many bins we need to copy
1323  TH1D* resized = new TH1D(Form("%s_resized_%s", histo->GetName(), suffix.Data()), Form("%s_resized_%s", histo->GetName(), suffix.Data()), up-low, (double)low, (double)up);
1324  // low is the bin number of the first new bin
1325  Int_t l = histo->GetXaxis()->FindBin(low);
1326  // set the values
1327  Double_t _x(0), _xx(0);
1328  for(Int_t i(0); i < up-low; i++) {
1329  _x = histo->GetBinContent(l+i);
1330  _xx=histo->GetBinError(l+i);
1331  resized->SetBinContent(i+1, _x);
1332  resized->SetBinError(i+1, _xx);
1333  }
1334  return resized;
1335 }
1336 //_____________________________________________________________________________
1337 TH2D* AliJetFlowTools::ResizeYaxisTH2D(TH2D* histo, TArrayD* x, TArrayD* y, TString suffix) {
1338  // resize the y-axis of a th2d
1339 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1340  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1341 #endif
1342  if(!histo) {
1343  printf(" > ResizeYaxisTH2D:: fatal error, NULL pointer passed < \n");
1344  return NULL;
1345  }
1346  // see how many bins we need to copy
1347  TH2D* resized = new TH2D(Form("%s_resized_%s", histo->GetName(), suffix.Data()), Form("%s_resized_%s", histo->GetName(), suffix.Data()), x->GetSize()-1, x->GetArray(), y->GetSize()-1, y->GetArray());
1348  // assume only the y-axis has changed
1349  // low is the bin number of the first new bin
1350  Int_t low = histo->GetYaxis()->FindBin(y->At(0));
1351  // set the values
1352  Double_t _x(0), _xx(0);
1353  for(Int_t i(0); i < x->GetSize(); i++) {
1354  for(Int_t j(0); j < y->GetSize(); j++) {
1355  _x = histo->GetBinContent(i, low+j);
1356  _xx=histo->GetBinError(i, low+1+j);
1357  resized->SetBinContent(i, j, _x);
1358  resized->SetBinError(i, j, _xx);
1359  }
1360  }
1361  return resized;
1362 }
1363 //_____________________________________________________________________________
1364 TH2D* AliJetFlowTools::NormalizeTH2D(TH2D* histo, Bool_t noError) {
1365  // general method to normalize all vertical slices of a th2 to unity
1366  // i.e. get a probability matrix
1367 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1368  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1369 #endif
1370  if(!histo) {
1371  printf(" > NormalizeTH2D:: NULL pointer passed, returning NULL < \n");
1372  return NULL;
1373  }
1374  Int_t binsX = histo->GetXaxis()->GetNbins();
1375  Int_t binsY = histo->GetYaxis()->GetNbins();
1376 
1377  // normalize all slices in x
1378  for(Int_t i(0); i < binsX; i++) { // for each vertical slice
1379  Double_t weight = 0;
1380  for(Int_t j(0); j < binsY; j++) { // loop over all the horizontal components
1381  weight+=histo->GetBinContent(i+1, j+1);
1382  } // now we know the total weight
1383  for(Int_t j(0); j < binsY; j++) {
1384  if (weight <= 0 ) continue;
1385  histo->SetBinContent(1+i, j+1, histo->GetBinContent(1+i, j+1)/weight);
1386  if(noError) histo->SetBinError( 1+i, j+1, 0.);
1387  else histo->SetBinError( 1+i, j+1, histo->GetBinError( 1+i, j+1)/weight);
1388  }
1389  }
1390  return histo;
1391 }
1392 //_____________________________________________________________________________
1393 TH1* AliJetFlowTools::Bootstrap(TH1* hist, Bool_t kill) {
1394 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1395  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1396 #endif
1397  // resample a TH1
1398  // the returned histogram is new, the original is deleted from the heap if kill is true
1399  if(!hist) {
1400  printf(" > Bootstrap:: fatal error,NULL pointer passed! \n");
1401  return 0x0;
1402  }
1403  else printf(" > Bootstrap:: resampling, may take some time \n");
1404  // clone input histo
1405  TH1* bootstrapped((TH1*)(hist->Clone(Form("%s_bootstrapped", hist->GetName()))));
1406  bootstrapped->Reset();
1407 
1408  /* OLD method - slightly underestimates fluctuations
1409  // reset the content
1410  bootstrapped->Reset();
1411  // resample the input histogram
1412  for(Int_t i(0); i < hist->GetEntries(); i++) bootstrapped->Fill(hist->GetRandom()); */
1413 
1414  // new method
1415  Double_t mean(0), sigma(0);
1416  Int_t sampledMean(0), entries(0);
1417 
1418  for(Int_t i(0); i < hist->GetXaxis()->GetNbins(); i++) {
1419  // for each bin, get the value
1420  mean = hist->GetBinContent(i+1);
1421  sigma = hist->GetBinError(i+1);
1422  // draw a new mean
1423  sampledMean = TMath::Nint(gRandom->Gaus(mean, sigma));
1424  printf(" sampled %i from original number %.2f \n", sampledMean, mean);
1425  // set the new bin content
1426  bootstrapped->SetBinContent(i+1, sampledMean);
1427  if(sampledMean > 0) bootstrapped->SetBinError(i+1, TMath::Sqrt(sampledMean));
1428  entries += sampledMean;
1429  }
1430  printf(" Done bootstrapping, setting number of entries to %i \n", entries);
1431  bootstrapped->SetEntries((double)entries);
1432 
1433 
1434  // if requested kill input histo
1435  if(kill) delete hist;
1436  // return resampled histogram
1437  return bootstrapped;
1438 }
1439 //_____________________________________________________________________________
1440 TH1D* AliJetFlowTools::RebinTH1D(TH1D* histo, TArrayD* bins, TString suffix, Bool_t kill) {
1441 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1442  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1443 #endif
1444  // return a TH1D with the supplied histogram rebinned to the supplied bins
1445  // the returned histogram is new, the original is deleted from the heap if kill is true
1446  if(!histo || !bins) {
1447  printf(" > RebinTH1D:: fatal error, NULL pointer passed < \n");
1448  return NULL;
1449  }
1450  // create the output histo
1451  TString name = histo->GetName();
1452  name+="_template";
1453  name+=suffix;
1454  TH1D* rebinned = 0x0;
1455  // check if the histogram is normalized. if so, fall back to ROOT style rebinning
1456  // if not, rebin manually
1457  if(histo->GetBinContent(1) > 1 ) {
1458  rebinned = new TH1D(name.Data(), name.Data(), bins->GetSize()-1, bins->GetArray());
1459  for(Int_t i(0); i < histo->GetXaxis()->GetNbins(); i++) {
1460  // loop over the bins of the old histo and fill the new one with its data
1461  rebinned->Fill(histo->GetBinCenter(i+1), histo->GetBinContent(i+1));
1462  }
1463  } else rebinned = reinterpret_cast<TH1D*>(histo->Rebin(bins->GetSize()-1, name.Data(), bins->GetArray()));
1464  if(kill) delete histo;
1465  return rebinned;
1466 }
1467 //_____________________________________________________________________________
1468 TH2D* AliJetFlowTools::RebinTH2D(TH2D* rebinMe, TArrayD* binsTrue, TArrayD* binsRec, TString suffix) {
1469 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1470  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1471 #endif
1472  // weighted rebinning of a th2d, implementation for function call to AliAnaChargedJetResponseMaker
1473  // not static as it is just a wrapper for the response maker object
1474  if(!fResponseMaker || !binsTrue || !binsRec) {
1475  printf(" > RebinTH2D:: function called with NULL arguments < \n");
1476  return 0x0;
1477  }
1478  TString name(Form("%s_%s", rebinMe->GetName(), suffix.Data()));
1479  return (TH2D*)fResponseMaker->MakeResponseMatrixRebin(rebinMe, (TH2*)(new TH2D(name.Data(), name.Data(), binsTrue->GetSize()-1, binsTrue->GetArray(), binsRec->GetSize()-1, binsRec->GetArray())), kTRUE);
1480 }
1481 //_____________________________________________________________________________
1482 TH2D* AliJetFlowTools::MatrixMultiplication(TH2D* a, TH2D* b, TString name)
1483 {
1484 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1485  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1486 #endif
1487  // multiply two matrices
1488  if (a->GetNbinsX() != b->GetNbinsY()) return 0x0;
1489  TH2D* c = (TH2D*)a->Clone("c");
1490  for (Int_t y1 = 1; y1 <= a->GetNbinsY(); y1++) {
1491  for (Int_t x2 = 1; x2 <= b->GetNbinsX(); x2++) {
1492  Double_t val = 0;
1493  for (Int_t x1 = 1; x1 <= a->GetNbinsX(); x1++) {
1494  Int_t y2 = x1;
1495  val += a->GetBinContent(x1, y1) * b->GetBinContent(x2, y2);
1496  }
1497  c->SetBinContent(x2, y1, val);
1498  c->SetBinError(x2, y1, 0.);
1499  }
1500  }
1501  if(strcmp(name.Data(), "")) c->SetNameTitle(name.Data(), name.Data());
1502  return c;
1503 }
1504 //_____________________________________________________________________________
1505 TH1D* AliJetFlowTools::NormalizeTH1D(TH1D* histo, Double_t scale)
1506 {
1507 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1508  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1509 #endif
1510  // normalize a th1d to a certain scale
1511  histo->Sumw2();
1512  Double_t integral = histo->Integral()*scale;
1513  if (integral > 0 && scale == 1.) histo->Scale(1./integral, "width");
1514  else if (scale != 1.) histo->Scale(1./scale, "width");
1515  else printf(" > Histogram integral < 0, cannot normalize \n");
1516  return histo;
1517 }
1518 //_____________________________________________________________________________
1519 TH1D* AliJetFlowTools::MergeSpectrumBins(TArrayI* bins, TH1D* spectrum, TH2D* corr)
1520 {
1521 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1522  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1523 #endif
1524  // merge a spectrum histogram taking into account the correlation terms
1525  if(!(bins&&spectrum)) {
1526  printf(" > NULL pointer passed as argument in MergeSpectrumBins ! < \n");
1527  return 0x0;
1528  }
1529  Double_t sum(0), error(0), pearson(0);
1530  // take the sum of the bin content
1531  sum += spectrum->GetBinContent(bins->At(0));
1532  sum += spectrum->GetBinContent(bins->At(1));
1533  // quadratically sum the errors
1534  error += TMath::Power(spectrum->GetBinError(bins->At(0)), 2);
1535  error += TMath::Power(spectrum->GetBinError(bins->At(1)), 2);
1536  // add the covariance term
1537  pearson = corr->GetBinContent(bins->At(0), bins->At(1));
1538  if(!corr) {
1539  printf(" > PANIC ! something is wrong with the covariance matrix, assuming full correlation ! < \n ");
1540  pearson = 1;
1541  }
1542  error += 2.*spectrum->GetBinError(bins->At(0))*spectrum->GetBinError(bins->At(1))*pearson;
1543  spectrum->SetBinContent(1, sum);
1544  if(error <= 0) return spectrum;
1545  spectrum->SetBinError(1, TMath::Sqrt(error));
1546  printf(" > sum is %.2f \t error is %.8f < \n", sum, error);
1547  printf(" > REPLACING BIN CONTENT OF FIRST BIN (%i) WITH MERGED BINS (%i) and (%i) < \n", 1, bins->At(0), bins->At(1));
1548  return spectrum;
1549 }
1550 //_____________________________________________________________________________
1551 TMatrixD* AliJetFlowTools::CalculatePearsonCoefficients(TMatrixD* covarianceMatrix)
1552 {
1553 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1554  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1555 #endif
1556  // Calculate pearson coefficients from covariance matrix
1557  TMatrixD *pearsonCoefficients((TMatrixD*)covarianceMatrix->Clone("pearsonCoefficients"));
1558  Int_t nrows(covarianceMatrix->GetNrows()), ncols(covarianceMatrix->GetNcols());
1559  Double_t pearson(0.);
1560  if(nrows==0 && ncols==0) return 0x0;
1561  for(Int_t row = 0; row < nrows; row++) {
1562  for(Int_t col = 0; col<ncols; col++) {
1563  if((*covarianceMatrix)(row,row)!=0. && (*covarianceMatrix)(col,col)!=0.) pearson = (*covarianceMatrix)(row,col)/TMath::Sqrt((*covarianceMatrix)(row,row)*(*covarianceMatrix)(col,col));
1564  (*pearsonCoefficients)(row,col) = pearson;
1565  }
1566  }
1567  return pearsonCoefficients;
1568 }
1569 //_____________________________________________________________________________
1570 TH1D* AliJetFlowTools::SmoothenPrior(TH1D* spectrum, TF1* function, Double_t min, Double_t max, Double_t start, Bool_t kill, Bool_t counts) {
1571 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1572  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1573 #endif
1574  // smoothen the spectrum using a user defined function
1575  // returns a clone of the original spectrum if fitting failed
1576  // if kill is kTRUE the input spectrum will be deleted from the heap
1577  // if 'count' is selected, bins are filled with integers (necessary if the
1578  // histogram is interpreted in a routine which accepts only counts)
1579  if(!spectrum || !function) return 0x0;
1580  if(start > max) printf(" > cannot extrapolate fit beyond fit range ! < " );
1581  TH1D* temp = (TH1D*)spectrum->Clone(Form("%s_smoothened", spectrum->GetName()));
1582  temp->Sumw2(); // if already called on the original, this will give off a warning but do nothing
1583  TFitResultPtr r = temp->Fit(function, "", "", min, max);
1584  if((int)r == 0) { // MINUIT status
1585  for(Int_t i(0); i < temp->GetNbinsX() + 1; i++) {
1586  if(temp->GetBinCenter(i) > start) { // from this pt value use extrapolation
1587  (counts) ? temp->SetBinContent(i, (int)(function->Integral(temp->GetXaxis()->GetBinLowEdge(i),temp->GetXaxis()->GetBinUpEdge(i))/temp->GetXaxis()->GetBinWidth(i))) : temp->SetBinContent(i, function->Integral(temp->GetXaxis()->GetBinLowEdge(i),temp->GetXaxis()->GetBinUpEdge(i))/temp->GetXaxis()->GetBinWidth(i));
1588  if(temp->GetBinContent(i) > 0) temp->SetBinError(i, TMath::Sqrt(temp->GetBinContent(i)));
1589  }
1590  }
1591  }
1592  if(kill) delete spectrum;
1593  return temp;
1594 }
1595 //_____________________________________________________________________________
1596 void AliJetFlowTools::Style(Bool_t legacy)
1597 {
1598 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1599  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1600 #endif
1601  // set global style for your current aliroot session
1602  if(!gStyle) return;
1603  // legacy style is pleasing to the eye, default is the formal ALICE style
1604  if(legacy) {
1605  gStyle->SetCanvasColor(-1);
1606  gStyle->SetPadColor(-1);
1607  gStyle->SetFrameFillColor(-1);
1608  gStyle->SetHistFillColor(-1);
1609  gStyle->SetTitleFillColor(-1);
1610  gStyle->SetFillColor(-1);
1611  gStyle->SetFillStyle(4000);
1612  gStyle->SetStatStyle(0);
1613  gStyle->SetTitleStyle(0);
1614  gStyle->SetCanvasBorderSize(0);
1615  gStyle->SetFrameBorderSize(0);
1616  gStyle->SetLegendBorderSize(0);
1617  gStyle->SetStatBorderSize(0);
1618  gStyle->SetTitleBorderSize(0);
1619  } else {
1620  gStyle->Reset("Plain");
1621  gStyle->SetOptTitle(0);
1622  gStyle->SetOptStat(0);
1623  gStyle->SetPalette(1);
1624  gStyle->SetCanvasColor(10);
1625  gStyle->SetCanvasBorderMode(0);
1626  gStyle->SetFrameLineWidth(1);
1627  gStyle->SetFrameFillColor(kWhite);
1628  gStyle->SetPadColor(10);
1629  gStyle->SetPadTickX(1);
1630  gStyle->SetPadTickY(1);
1631  gStyle->SetPadBottomMargin(0.17);
1632  gStyle->SetPadLeftMargin(0.15);
1633  gStyle->SetHistLineWidth(1);
1634  gStyle->SetHistLineColor(kRed);
1635  gStyle->SetFuncWidth(2);
1636  gStyle->SetFuncColor(kGreen);
1637  gStyle->SetLineWidth(2);
1638  gStyle->SetLabelSize(0.045,"xyz");
1639  gStyle->SetLabelOffset(0.01,"y");
1640  gStyle->SetLabelOffset(0.01,"x");
1641  gStyle->SetLabelColor(kBlack,"xyz");
1642  gStyle->SetTitleSize(0.05,"xyz");
1643  gStyle->SetTitleOffset(1.25,"y");
1644  gStyle->SetTitleOffset(1.2,"x");
1645  gStyle->SetTitleFillColor(kWhite);
1646  gStyle->SetTextSizePixels(26);
1647  gStyle->SetTextFont(42);
1648  gStyle->SetLegendBorderSize(0);
1649  gStyle->SetLegendFillColor(kWhite);
1650  gStyle->SetLegendFont(42);
1651  }
1652 }
1653 //_____________________________________________________________________________
1654 void AliJetFlowTools::Style(TCanvas* c, TString style)
1655 {
1656 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1657  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1658 #endif
1659  if(c) return;
1660  // set a default style for a canvas
1661  if(!strcmp(style.Data(), "PEARSON")) {
1662  printf(" > style PEARSON canvas < \n");
1663  gStyle->SetOptStat(0);
1664  c->SetGridx();
1665  c->SetGridy();
1666  c->SetTicks();
1667  return;
1668  } else if(!strcmp(style.Data(), "SPECTRUM")) {
1669  printf(" > style SPECTRUM canvas < \n");
1670  gStyle->SetOptStat(0);
1671  c->SetLogy();
1672  c->SetGridx();
1673  c->SetGridy();
1674  c->SetTicks();
1675  return;
1676  } else printf(" > Style called with unknown option %s \n returning < \n", style.Data());
1677 }
1678 //_____________________________________________________________________________
1679 void AliJetFlowTools::Style(TVirtualPad* c, TString style, Bool_t legacy)
1680 {
1681 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1682  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1683 #endif
1684  // set a default style for a canva
1685  if(!c) return;
1686  if(legacy) {
1687  c->SetLeftMargin(.25);
1688  c->SetBottomMargin(.25);
1689  }
1690  else Style();
1691  if(!strcmp(style.Data(), "PEARSON")) {
1692  printf(" > style PEARSON pad < \n");
1693  gStyle->SetOptStat(0);
1694  c->SetGridx();
1695  c->SetGridy();
1696  c->SetTicks();
1697  return;
1698  } else if(!strcmp(style.Data(), "SPECTRUM")) {
1699  printf(" > style SPECTRUM pad < \n");
1700  gStyle->SetOptStat(0);
1701  c->SetLogy();
1702  c->SetGridx();
1703  c->SetGridy();
1704  c->SetTicks();
1705  return;
1706  } else if (!strcmp(style.Data(), "GRID")) {
1707  printf(" > style GRID pad < \n");
1708  gStyle->SetOptStat(0);
1709  c->SetGridx();
1710  c->SetGridy();
1711  c->SetTicks();
1712  } else printf(" > Style called with unknown option %s \n returning < \n", style.Data());
1713 }
1714 //_____________________________________________________________________________
1715 void AliJetFlowTools::Style(TLegend* l)
1716 {
1717 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1718  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1719 #endif
1720  // set a default style for a legend
1721  if(!l) return;
1722  l->SetFillColor(0);
1723  l->SetBorderSize(0);
1724  if(gStyle) l->SetTextSize(gStyle->GetTextSize()*.08);
1725 }
1726 //_____________________________________________________________________________
1727 void AliJetFlowTools::Style(TH1* h, EColor col, histoType type, Bool_t legacy)
1728 {
1729 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1730  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1731 #endif
1732  // style a histo
1733  if(!h) return;
1734  h->GetYaxis()->SetNdivisions(505);
1735  h->SetLineColor(col);
1736  h->SetMarkerColor(col);
1737  h->SetLineWidth(2);
1738  h->SetMarkerSize(1.5);
1739  if(legacy) {
1740  h->SetTitle("");
1741  h->GetYaxis()->SetLabelSize(0.05);
1742  h->GetXaxis()->SetLabelSize(0.05);
1743  h->GetYaxis()->SetTitleOffset(1.5);
1744  h->GetXaxis()->SetTitleOffset(1.5);
1745  h->GetYaxis()->SetTitleSize(.05);
1746  h->GetXaxis()->SetTitleSize(.05);
1747  } else Style();
1748  switch (type) {
1749  case kInPlaneSpectrum : {
1750  h->SetTitle("IN PLANE");
1751  h->GetXaxis()->SetTitle("#it{p}_{T}^{ch, jet} (GeV/#it{c})");
1752  h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1753  } break;
1754  case kOutPlaneSpectrum : {
1755  h->SetTitle("OUT OF PLANE");
1756  h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1757  h->GetXaxis()->SetTitle("#it{p}_{T, jet}^{ch} (GeV/#it{c})");
1758  } break;
1759  case kUnfoldedSpectrum : {
1760  h->SetTitle("UNFOLDED");
1761  h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1762  h->GetXaxis()->SetTitle("#it{p}_{T, jet}^{ch} (GeV/#it{c})");
1763  } break;
1764  case kFoldedSpectrum : {
1765  h->SetTitle("FOLDED");
1766  h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1767  h->GetXaxis()->SetTitle("#it{p}_{T, jet}^{ch} (GeV/#it{c})");
1768  } break;
1769  case kMeasuredSpectrum : {
1770  h->SetTitle("MEASURED");
1771  h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1772  h->GetXaxis()->SetTitle("#it{p}_{T, jet}^{cht} (GeV/#it{c})");
1773  } break;
1774  case kBar : {
1775  h->SetFillColor(col);
1776  h->SetBarWidth(.6);
1777  h->GetXaxis()->SetTitle("#it{p}_{T, jet}^{ch} (GeV/#it{c})");
1778  h->SetBarOffset(0.2);
1779  }
1780  case kRatio : {
1781  h->SetMarkerStyle(8);
1782  h->SetMarkerSize(1.5);
1783  } break;
1784  case kDeltaPhi : {
1785  h->GetYaxis()->SetTitle("[counts]");
1786  h->GetXaxis()->SetTitle("#Delta #phi");
1787  }
1788  default : break;
1789  }
1790 }
1791 //_____________________________________________________________________________
1792 void AliJetFlowTools::Style(TGraph* h, EColor col, histoType type, Bool_t legacy)
1793 {
1794 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1795  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1796 #endif
1797  // style a tgraph
1798  if(!h) return;
1799  h->GetYaxis()->SetNdivisions(505);
1800  h->SetLineColor(col);
1801  h->SetMarkerColor(col);
1802  h->SetLineWidth(2);
1803  h->SetMarkerSize(1.5);
1804  h->SetTitle("");
1805  h->SetFillColor(kCyan);
1806  if(legacy) {
1807  h->GetYaxis()->SetLabelSize(0.05);
1808  h->GetXaxis()->SetLabelSize(0.05);
1809  h->GetYaxis()->SetTitleOffset(1.6);
1810  h->GetXaxis()->SetTitleOffset(1.6);
1811  h->GetYaxis()->SetTitleSize(.05);
1812  h->GetXaxis()->SetTitleSize(.05);
1813  } else Style();
1814  h->GetXaxis()->SetTitle("#it{p}_{T, jet}^{ch} (GeV/#it{c})");
1815  switch (type) {
1816  case kInPlaneSpectrum : {
1817  h->SetTitle("IN PLANE");
1818  h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1819  } break;
1820  case kOutPlaneSpectrum : {
1821  h->SetTitle("OUT OF PLANE");
1822  h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1823  } break;
1824  case kUnfoldedSpectrum : {
1825  h->SetTitle("UNFOLDED");
1826  h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1827  } break;
1828  case kFoldedSpectrum : {
1829  h->SetTitle("FOLDED");
1830  h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1831  } break;
1832  case kMeasuredSpectrum : {
1833  h->SetTitle("MEASURED");
1834  h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1835  } break;
1836  case kRatio : {
1837  h->GetYaxis()->SetTitle("(d#it{N}^{ch, jet}_{in plane}/(d#it{p}_{T}d#eta))/(d#it{N}^{ch,jet}_{out of plane}/(d#it{p}_{T}d#eta))");
1838  } break;
1839  case kV2 : {
1840  h->GetYaxis()->SetTitle("#it{v}_{2}^{ch, jet} {EP, |#Delta#eta|>0.9 } ");
1841  h->GetYaxis()->SetRangeUser(-.5, 1.);
1842  h->SetMarkerStyle(8);
1843  h->SetMarkerSize(1.5);
1844  } break;
1845  default : break;
1846  }
1847 }
1848 //_____________________________________________________________________________
1850  TH1D*& ratio, // pointer reference, output of this function
1851  TGraphErrors*& v2, // pointer reference, as output of this function
1852  TArrayI* in,
1853  TArrayI* out,
1854  TString inFile,
1855  TString outFile) const
1856 {
1857 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1858  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1859 #endif
1860  // pass clones of the nominal points and nominal v2 values
1861  if(fOutputFile && !fOutputFile->IsZombie()) fOutputFile->Close(); // if for some weird reason the unfolding output is still mutable
1862  TFile* readMe(new TFile(inFile.Data(), "READ")); // open unfolding output read-only
1863  if(readMe->IsZombie()) {
1864  printf(" > Fatal error, couldn't read %s for post processing ! < \n", inFile.Data());
1865  return;
1866  }
1867  printf("\n\n\n\t\t GetNominalValues \n > Recovered the following file structure : \n <");
1868  readMe->ls();
1869  TFile* output(new TFile(outFile.Data(), "RECREATE")); // create new output file
1870  if(output) SquelchWarning();
1871  // get some placeholders, have to be initialized but will be deleted
1872  ratio = new TH1D("nominal", "nominal", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
1873  TH1D* nominalIn(new TH1D("nominal in", "nominal in", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1874  TH1D* nominalOut(new TH1D("nominal out", "nominal out", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1875  Int_t iIn[] = {in->At(0), in->At(0)}; // first value is the nominal point
1876  Int_t iOut[] = {out->At(0), out->At(0)};
1877 
1878  // call the functions and set the relevant pointer references
1879  TH1D* dud(0x0);
1881  new TArrayI(2, iIn),
1882  new TArrayI(2, iOut),
1883  dud, dud, dud, dud, dud, dud,
1884  ratio, // pointer reference, output of this function
1885  nominalIn,
1886  nominalOut,
1887  1,
1888  fBinsTrue->At(0),
1889  fBinsTrue->At(fBinsTrue->GetSize()-1),
1890  readMe,
1891  "nominal_values");
1892  v2 = GetV2(nominalIn, nominalOut, fEventPlaneRes, "nominal v_{2}");
1893 
1894  // close the open files, reclaim ownership of histograms which are necessary outside of the file scope
1895  ratio->SetDirectory(0); // disassociate from current gDirectory
1896  readMe->Close();
1897 }
1898 //_____________________________________________________________________________
1900  TGraphAsymmErrors*& corrRatio, // correlated uncertainty pointer reference
1901  TGraphAsymmErrors*& corrV2, // correlated uncertainty pointer reference
1902  TArrayI* variationsIn, // variantions in plane
1903  TArrayI* variationsOut, // variantions out of plane
1904  Bool_t sym, // treat as symmmetric
1905  TArrayI* variations2ndIn, // second source of variations
1906  TArrayI* variations2ndOut, // second source of variations
1907  Bool_t sym2nd, // treat as symmetric
1908  TString type, // type of uncertaitny
1909  TString type2,
1910  Int_t columns, // divide the output canvasses in this many columns
1911  Float_t rangeLow, // lower pt range
1912  Float_t rangeUp, // upper pt range
1913  Float_t corr, // correlation strength
1914  TString in, // input file name (created by this unfolding class)
1915  TString out // output file name (which will hold results of the systematic test)
1916  ) const
1917 {
1918 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
1919  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
1920 #endif
1921  // do full systematics
1922  if(fOutputFile && !fOutputFile->IsZombie()) fOutputFile->Close(); // if for some weird reason the unfolding output is still mutable
1923  TFile* readMe(new TFile(in.Data(), "READ")); // open unfolding output read-only
1924  if(readMe->IsZombie()) {
1925  printf(" > Fatal error, couldn't read %s for post processing ! < \n", in.Data());
1926  return;
1927  }
1928  printf("\n\n\n\t\t GetCorrelatedUncertainty \n > Recovered the following file structure : \n <");
1929  readMe->ls();
1930  TFile* output(new TFile(out.Data(), "RECREATE")); // create new output file
1931 
1932  if(sym2nd) SquelchWarning();
1933 
1934  // create some null placeholder pointers
1935  TH1D* relativeErrorVariationInLow(0x0);
1936  TH1D* relativeErrorVariationInUp(0x0);
1937  TH1D* relativeErrorVariationOutLow(0x0);
1938  TH1D* relativeErrorVariationOutUp(0x0);
1939  TH1D* relativeError2ndVariationInLow(0x0);
1940  TH1D* relativeError2ndVariationInUp(0x0);
1941  TH1D* relativeError2ndVariationOutLow(0x0);
1942  TH1D* relativeError2ndVariationOutUp(0x0);
1943  TH1D* relativeStatisticalErrorIn(0x0);
1944  TH1D* relativeStatisticalErrorOut(0x0);
1945  // histo for the nominal ratio in / out
1946  TH1D* nominal(new TH1D("ratio in plane, out of plane", "ratio in plane, out of plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1947  TH1D* nominalIn(new TH1D("in plane jet yield", "in plane jet yield", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1948  TH1D* nominalOut(new TH1D("out of plane jet yield", "out of plane jet yield", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1949 
1950  // call the functions
1951  if(variationsIn && variationsOut) {
1953  variationsIn,
1954  variationsOut,
1955  relativeErrorVariationInUp, // pointer reference
1956  relativeErrorVariationInLow, // pointer reference
1957  relativeErrorVariationOutUp, // pointer reference
1958  relativeErrorVariationOutLow, // pointer reference
1959  relativeStatisticalErrorIn, // pointer reference
1960  relativeStatisticalErrorOut, // pointer reference
1961  nominal,
1962  nominalIn,
1963  nominalOut,
1964  columns,
1965  rangeLow,
1966  rangeUp,
1967  readMe,
1968  type,
1969  kFALSE,
1970  kTRUE);
1971  if(relativeErrorVariationInUp) {
1972  // canvas with the error from variation strength
1973  TCanvas* relativeErrorVariation(new TCanvas(Form("relativeError_%s", type.Data()), Form("relativeError_%s", type.Data())));
1974  relativeErrorVariation->Divide(2);
1975  relativeErrorVariation->cd(1);
1976  Style(gPad, "GRID");
1977  relativeErrorVariationInUp->DrawCopy("b");
1978  relativeErrorVariationInLow->DrawCopy("same b");
1979  Style(AddLegend(gPad));
1980  relativeErrorVariation->cd(2);
1981  Style(gPad, "GRID");
1982  relativeErrorVariationOutUp->DrawCopy("b");
1983  relativeErrorVariationOutLow->DrawCopy("same b");
1984  SavePadToPDF(relativeErrorVariation);
1985  Style(AddLegend(gPad));
1986  relativeErrorVariation->Write();
1987 
1988  // now smoothen the diced response error (as it is expected to be flat)
1989  // this is done by fitting a constant to the diced resonse error histo
1990  //
1991  TF1* lin = new TF1("lin", "[0]", rangeLow, rangeUp);
1992  relativeErrorVariationInUp->Fit(lin, "L", "", rangeLow, rangeUp);
1993  if(gMinuit->fISW[1] != 3) printf(" fit is NOT ok ! " );
1994  for(Int_t i(0); i < relativeErrorVariationInUp->GetNbinsX(); i++) {
1995  relativeErrorVariationInUp->SetBinContent(i+1, lin->GetParameter(0));
1996  }
1997  relativeErrorVariationInLow->Fit(lin, "L", "", rangeLow, rangeUp);
1998  printf(" > Fit over diced resonse, new value for all bins is %.4f < \n ", lin->GetParameter(0));
1999  for(Int_t i(0); i < relativeErrorVariationInUp->GetNbinsX(); i++) {
2000  relativeErrorVariationInLow->SetBinContent(i+1, 0);//lin->GetParameter(0));
2001  }
2002  relativeErrorVariationOutUp->Fit(lin, "L", "", rangeLow, rangeUp);
2003  printf(" > Fit over diced resonse, new value for all bins is %.4f < \n ", lin->GetParameter(0));
2004  for(Int_t i(0); i < relativeErrorVariationInUp->GetNbinsX(); i++) {
2005  relativeErrorVariationOutUp->SetBinContent(i+1, lin->GetParameter(0));
2006  }
2007  relativeErrorVariationOutLow->Fit(lin, "L", "", rangeLow, rangeUp);
2008  printf(" > Fit over diced resonse, new value for all bins is %.4f < \n ", lin->GetParameter(0));
2009  for(Int_t i(0); i < relativeErrorVariationInUp->GetNbinsX(); i++) {
2010  relativeErrorVariationOutLow->SetBinContent(i+1, 0);//lin->GetParameter(0));
2011  }
2012  }
2013  }
2014  // call the functions for a second set of systematic sources
2015  if(variations2ndIn && variations2ndOut) {
2017  variations2ndIn,
2018  variations2ndOut,
2019  relativeError2ndVariationInUp, // pointer reference
2020  relativeError2ndVariationInLow, // pointer reference
2021  relativeError2ndVariationOutUp, // pointer reference
2022  relativeError2ndVariationOutLow, // pointer reference
2023  relativeStatisticalErrorIn, // pointer reference
2024  relativeStatisticalErrorOut, // pointer reference
2025  nominal,
2026  nominalIn,
2027  nominalOut,
2028  columns,
2029  rangeLow,
2030  rangeUp,
2031  readMe,
2032  type2,
2033  kFALSE,
2034  kTRUE);
2035  if(relativeError2ndVariationInUp) {
2036  // canvas with the error from variation strength
2037  TCanvas* relativeError2ndVariation(new TCanvas(Form("relativeError2nd_%s", type2.Data()), Form("relativeError2nd_%s", type2.Data())));
2038  relativeError2ndVariation->Divide(2);
2039  relativeError2ndVariation->cd(1);
2040  Style(gPad, "GRID");
2041  relativeError2ndVariationInUp->DrawCopy("b");
2042  relativeError2ndVariationInLow->DrawCopy("same b");
2043  Style(AddLegend(gPad));
2044  relativeError2ndVariation->cd(2);
2045  Style(gPad, "GRID");
2046  relativeError2ndVariationOutUp->DrawCopy("b");
2047  relativeError2ndVariationOutLow->DrawCopy("same b");
2048  SavePadToPDF(relativeError2ndVariation);
2049  Style(AddLegend(gPad));
2050  relativeError2ndVariation->Write();
2051  }
2052 
2053  }
2054 
2055  // and the placeholder for the final systematic
2056  TH1D* relativeErrorInUp(new TH1D("max correlated uncertainty in plane", "max correlated uncertainty in plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2057  TH1D* relativeErrorOutUp(new TH1D("max correlated uncertainty out of plane", "max correlated uncertainty out of plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2058  TH1D* relativeErrorInLow(new TH1D("min correlated uncertainty in plane", "min correlated uncertainty in plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2059  TH1D* relativeErrorOutLow(new TH1D("min correlated uncertainty out of plane", "min correlated uncertainty out of plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2060  relativeErrorInUp->SetYTitle("relative uncertainty");
2061  relativeErrorOutUp->SetYTitle("relative uncertainty");
2062  relativeErrorInLow->SetYTitle("relative uncertainty");
2063  relativeErrorOutLow->SetYTitle("relative uncertainty");
2064 
2065  // merge the correlated errors (FIXME) trivial for one set
2066  Double_t aInUp(0.), bInUp(0.), cInUp(0.), dInUp(0.);
2067  Double_t aOutUp(0.), bOutUp(0.), cOutUp(0.), dOutUp(0.);
2068  Double_t aInLow(0.), bInLow(0.), cInLow(0.), dInLow(0.);
2069  Double_t aOutLow(0.), bOutLow(0.), cOutLow(0.), dOutLow(0.);
2070 
2071  for(Int_t b(0); b < fBinsTrue->GetSize()-1; b++) {
2072  // for the upper bound
2073  if(relativeErrorVariationInUp) aInUp = relativeErrorVariationInUp->GetBinContent(b+1);
2074  if(relativeErrorVariationOutUp) aOutUp = relativeErrorVariationOutUp->GetBinContent(b+1);
2075  if(relativeError2ndVariationInUp) bInUp = relativeError2ndVariationInUp->GetBinContent(b+1);
2076  if(relativeError2ndVariationOutUp) bInLow = relativeError2ndVariationOutUp->GetBinContent(b+1);
2077  dInUp = aInUp*aInUp + bInUp*bInUp + cInUp*cInUp;
2078  // for a symmetric first variation
2079  if(sym) dInUp += aInLow*aInLow;
2080  if(dInUp > 0) relativeErrorInUp->SetBinContent(b+1, TMath::Sqrt(dInUp));
2081  dOutUp = aOutUp*aOutUp + bOutUp*bOutUp + cOutUp*cOutUp;
2082  if(sym) dOutUp += aOutLow*aOutLow;
2083  if(dOutUp > 0) relativeErrorOutUp->SetBinContent(b+1, TMath::Sqrt(dOutUp));
2084  // for the lower bound
2085  if(relativeErrorVariationInLow) aInLow = relativeErrorVariationInLow->GetBinContent(b+1);
2086  if(relativeErrorVariationOutLow) aOutLow = relativeErrorVariationOutLow->GetBinContent(b+1);
2087  if(relativeError2ndVariationInLow) bInLow = relativeError2ndVariationInLow->GetBinContent(b+1);
2088  if(relativeError2ndVariationOutLow) bOutLow = relativeError2ndVariationOutLow->GetBinContent(b+1);
2089  dInLow = aInLow*aInLow + bInLow*bInLow + cInLow*cInLow;
2090  if(sym) dInLow += aInUp*aInUp;
2091  if(dInLow > 0) relativeErrorInLow->SetBinContent(b+1, -1*TMath::Sqrt(dInLow));
2092  dOutLow = aOutLow*aOutLow + bOutLow*bOutLow + cOutLow*cOutLow;
2093  if(sym) dOutLow += aOutUp*aOutUp;
2094  if(dOutLow > 0) relativeErrorOutLow->SetBinContent(b+1, -1.*TMath::Sqrt(dOutLow));
2095  }
2096  // project the estimated errors on the nominal ratio
2097  if(nominal) {
2098  Double_t* ax = new Double_t[fBinsTrue->GetSize()-1];
2099  Double_t* ay = new Double_t[fBinsTrue->GetSize()-1];
2100  Double_t* axh = new Double_t[fBinsTrue->GetSize()-1];
2101  Double_t* axl = new Double_t[fBinsTrue->GetSize()-1];
2102  Double_t* ayh = new Double_t[fBinsTrue->GetSize()-1];
2103  Double_t* ayl = new Double_t[fBinsTrue->GetSize()-1];
2104  Double_t lowErr(0.), upErr(0.);
2105  for(Int_t i(0); i < fBinsTrue->GetSize()-1; i++) {
2106  // add the in and out of plane errors in quadrature
2107  // propagation is tricky because we should consider two cases:
2108  // [1] the error is uncorrelated, and we propagate upper 1 with lower 2 and vice versa
2109  // [2] the error is correlated - in this case upper 1 should be propagated with upper 2
2110  // as the fluctuations are bound to always to of same sign
2111  if(corr <= 0) {
2112  lowErr = relativeErrorInLow->GetBinContent(i+1)*relativeErrorInLow->GetBinContent(i+1)+relativeErrorOutUp->GetBinContent(1+i)*relativeErrorOutUp->GetBinContent(i+1);
2113  upErr = relativeErrorInUp->GetBinContent(i+1)*relativeErrorInUp->GetBinContent(i+1)+relativeErrorOutLow->GetBinContent(i+1)*relativeErrorOutLow->GetBinContent(i+1);
2114  } else {
2115  lowErr = relativeErrorInLow->GetBinContent(i+1)*relativeErrorInLow->GetBinContent(i+1)+relativeErrorOutLow->GetBinContent(1+i)*relativeErrorOutLow->GetBinContent(i+1) -2.*corr*relativeErrorInLow->GetBinContent(i+1)*relativeErrorOutLow->GetBinContent(i+1);
2116  upErr = relativeErrorInUp->GetBinContent(i+1)*relativeErrorInUp->GetBinContent(i+1)+relativeErrorOutUp->GetBinContent(i+1)*relativeErrorOutUp->GetBinContent(i+1) - 2.*corr*relativeErrorInUp->GetBinContent(i+1)*relativeErrorOutUp->GetBinContent(i+1);
2117  }
2118  ayl[i] = TMath::Sqrt(TMath::Abs(lowErr))*nominal->GetBinContent(i+1);
2119  ayh[i] = TMath::Sqrt(TMath::Abs(upErr))*nominal->GetBinContent(i+1);
2120  // get the bin width (which is the 'error' on x
2121  Double_t binWidth(nominal->GetBinWidth(i+1));
2122  axl[i] = binWidth/2.;
2123  axh[i] = binWidth/2.;
2124  // now get the coordinate for the point
2125  ax[i] = nominal->GetBinCenter(i+1);
2126  ay[i] = nominal->GetBinContent(i+1);
2127  }
2128  // save the nominal ratio
2129  TGraphAsymmErrors* nominalError(new TGraphAsymmErrors(fBinsTrue->GetSize()-1, ax, ay, axl, axh, ayl, ayh));
2130  corrRatio = (TGraphAsymmErrors*)nominalError->Clone();
2131  nominalError->SetName("correlated uncertainty");
2132  TCanvas* nominalCanvas(new TCanvas("nominalCanvas", "nominalCanvas"));
2133  nominalCanvas->Divide(2);
2134  nominalCanvas->cd(1);
2135  Style(nominal, kBlack);
2136  Style(nominalError, kCyan, kRatio);
2137  nominalError->SetLineColor(kCyan);
2138  nominalError->SetMarkerColor(kCyan);
2139  nominalError->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2140  nominalError->GetYaxis()->SetRangeUser(.7, 2.2);
2141  nominalError->DrawClone("a2");
2142  nominal->DrawCopy("same E1");
2143  Style(AddLegend(gPad));
2144  Style(gPad, "GRID");
2145  Style(nominalCanvas);
2146  // save nominal v2 and systematic errors
2147  TGraphAsymmErrors* nominalV2Error(GetV2WithSystematicErrors(
2148  nominalIn,
2149  nominalOut,
2151  "v_{2} with shape uncertainty",
2152  relativeErrorInUp,
2153  relativeErrorInLow,
2154  relativeErrorOutUp,
2155  relativeErrorOutLow,
2156  corr));
2157  // pass the nominal values to the pointer references
2158  corrV2 = (TGraphAsymmErrors*)nominalV2Error->Clone();
2159  TGraphErrors* nominalV2(GetV2(nominalIn, nominalOut, fEventPlaneRes, "v_{2}"));
2160  nominalCanvas->cd(2);
2161  Style(nominalV2, kBlack);
2162  Style(nominalV2Error, kCyan, kV2);
2163  nominalV2Error->SetLineColor(kCyan);
2164  nominalV2Error->SetMarkerColor(kCyan);
2165  nominalV2Error->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2166  nominalV2Error->DrawClone("a2");
2167  nominalV2->DrawClone("same E1");
2168  Style(AddLegend(gPad));
2169  Style(gPad, "GRID");
2170  Style(nominalCanvas);
2171  SavePadToPDF(nominalCanvas);
2172  nominalCanvas->Write();
2173  }
2174 
2175  TCanvas* relativeError(new TCanvas("relativeCorrelatedError"," relativeCorrelatedError"));
2176  relativeError->Divide(2);
2177  relativeError->cd(1);
2178  Style(gPad, "GRID");
2179  relativeErrorInUp->GetYaxis()->SetRangeUser(-1.5, 3.);
2180  Style(relativeErrorInUp, kBlue, kBar);
2181  Style(relativeErrorInLow, kGreen, kBar);
2182  relativeErrorInUp->DrawCopy("b");
2183  relativeErrorInLow->DrawCopy("same b");
2184  Style(relativeStatisticalErrorIn, kRed);
2185  relativeStatisticalErrorIn->DrawCopy("same");
2186  Style(AddLegend(gPad));
2187  relativeError->cd(2);
2188  Style(gPad, "GRID");
2189  relativeErrorOutUp->GetYaxis()->SetRangeUser(-1.5, 3.);
2190  Style(relativeErrorOutUp, kBlue, kBar);
2191  Style(relativeErrorOutLow, kGreen, kBar);
2192  relativeErrorOutUp->DrawCopy("b");
2193  relativeErrorOutLow->DrawCopy("same b");
2194  Style(relativeStatisticalErrorOut, kRed);
2195  relativeStatisticalErrorOut->DrawCopy("same");
2196  Style(AddLegend(gPad));
2197 
2198  // write the buffered file to disk and close the file
2199  SavePadToPDF(relativeError);
2200  relativeError->Write();
2201  output->Write();
2202 }
2203 //_____________________________________________________________________________
2205  TGraphAsymmErrors*& shapeRatio, // pointer reference to final shape uncertainty of ratio
2206  TGraphAsymmErrors*& shapeV2, // pointer reference to final shape uncertainty of v2
2207  TArrayI* regularizationIn, // regularization strength systematics, in plane
2208  TArrayI* regularizationOut, // regularization strenght systematics, out of plane
2209  TArrayI* recBinIn, // rec bin ranges, in plane
2210  TArrayI* recBinOut, // rec bin ranges, out of plane
2211  TArrayI* methodIn, // method in
2212  TArrayI* methodOut, // method out
2213  Int_t columns, // divide the output canvasses in this many columns
2214  Float_t rangeLow, // lower pt range
2215  Float_t rangeUp, // upper pt range
2216  Float_t corr, // correlation strength
2217  TString in, // input file name (created by this unfolding class)
2218  TString out, // output file name (which will hold results of the systematic test)
2219  Bool_t regularizationOnV2 // get uncertainty on yields separately or v2 directly
2220  ) const
2221 {
2222 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
2223  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
2224 #endif
2225  // do full systematics
2226  if(fOutputFile && !fOutputFile->IsZombie()) fOutputFile->Close(); // if for some weird reason the unfolding output is still mutable
2227  TFile* readMe(new TFile(in.Data(), "READ")); // open unfolding output read-only
2228  if(readMe->IsZombie()) {
2229  printf(" > Fatal error, couldn't read %s for post processing ! < \n", in.Data());
2230  return;
2231  }
2232  printf("\n\n\n\t\t DOSYSTEMATICS \n > Recovered the following file structure : \n <");
2233  readMe->ls();
2234  TFile* output(new TFile(out.Data(), "RECREATE")); // create new output file
2235  // create some null placeholder pointers
2236  TH1D* relativeErrorRegularizationInLow(0x0);
2237  TH1D* relativeErrorRegularizationInUp(0x0);
2238  TH1D* relativeErrorRecBinInLow(0x0);
2239  TH1D* relativeErrorRecBinInUp(0x0);
2240  TH1D* relativeErrorMethodInLow(0x0);
2241  TH1D* relativeErrorMethodInUp(0x0);
2242  TH1D* relativeErrorRegularizationOutLow(0x0);
2243  TH1D* relativeErrorRegularizationOutUp(0x0);
2244  TH1D* relativeErrorRecBinOutLow(0x0);
2245  TH1D* relativeErrorRecBinOutUp(0x0);
2246  TH1D* relativeStatisticalErrorIn(0x0);
2247  TH1D* relativeStatisticalErrorOut(0x0);
2248  TH1D* relativeErrorMethodOutLow(0x0);
2249  TH1D* relativeErrorMethodOutUp(0x0);
2250  // histo for the nominal ratio in / out
2251  TH1D* nominal(new TH1D("ratio in plane, out of plane", "ratio in plane, out of plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2252  TH1D* nominalIn(new TH1D("in plane jet yield", "in plane jet yield", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2253  TH1D* nominalOut(new TH1D("out of plane jet yield", "out of plane jet yield", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2254 
2255  // call the functions
2256  if(regularizationIn && regularizationOut) {
2258  regularizationIn,
2259  regularizationOut,
2260  relativeErrorRegularizationInUp, // pointer reference
2261  relativeErrorRegularizationInLow, // pointer reference
2262  relativeErrorRegularizationOutUp, // pointer reference
2263  relativeErrorRegularizationOutLow, // pointer reference
2264  relativeStatisticalErrorIn, // pointer reference
2265  relativeStatisticalErrorOut, // pointer reference
2266  nominal,
2267  nominalIn,
2268  nominalOut,
2269  columns,
2270  rangeLow,
2271  rangeUp,
2272  readMe,
2273  "regularization",
2274  fRMS,
2275  !regularizationOnV2); // set to false means NO undertainty from ratio, but v2
2276  if(relativeErrorRegularizationInUp && !regularizationOnV2 ) {
2277  // canvas with the error from regularization strength
2278  TCanvas* relativeErrorRegularization(new TCanvas("relativeErrorRegularization", "relativeErrorRegularization"));
2279  relativeErrorRegularization->Divide(2);
2280  relativeErrorRegularization->cd(1);
2281  Style(gPad, "GRID");
2282  relativeErrorRegularizationInUp->DrawCopy("b");
2283  relativeErrorRegularizationInLow->DrawCopy("same b");
2284  Style(AddLegend(gPad));
2285  relativeErrorRegularization->cd(2);
2286  Style(gPad, "GRID");
2287  relativeErrorRegularizationOutUp->DrawCopy("b");
2288  relativeErrorRegularizationOutLow->DrawCopy("same b");
2289  SavePadToPDF(relativeErrorRegularization);
2290  Style(AddLegend(gPad));
2291  relativeErrorRegularization->Write();
2292  } else if(relativeErrorRegularizationInUp && regularizationOnV2 ) {
2293  // canvas with the error from regularization strength
2294  TCanvas* relativeErrorRegularization(new TCanvas("relativeErrorRegularization", "relativeErrorRegularization"));
2295  Style(gPad, "GRID");
2296  relativeErrorRegularization->cd(1);
2297  TH1F* relativeErrorRegularizationInUpErrors = (TH1F*)relativeErrorRegularizationInUp->Clone();
2298  for(Int_t i(1); i < relativeErrorRegularizationInUp->GetNbinsX() + 1; i++) {
2299  relativeErrorRegularizationInUpErrors->SetBinContent(i, relativeErrorRegularizationInUp->GetBinError(i));
2300  relativeErrorRegularizationInUpErrors->SetBinError(i, 0);
2301  }
2302  relativeErrorRegularizationInUpErrors->GetYaxis()->SetTitle("absolute error on v_{2} from unfolding");
2303  relativeErrorRegularizationInUpErrors->GetXaxis()->SetTitle("#it{p}_{T, jet}^{ch} (GeV/#it{c})");
2304  relativeErrorRegularizationInUpErrors->DrawCopy("b");
2305  Style(gPad, "GRID");
2306  relativeErrorRegularization->Write();
2307  }
2308  }
2309  if(recBinIn && recBinOut) {
2311  recBinIn,
2312  recBinOut,
2313  relativeErrorRecBinInUp, // pointer reference
2314  relativeErrorRecBinInLow, // pointer reference
2315  relativeErrorRecBinOutUp, // pointer reference
2316  relativeErrorRecBinOutLow, // pointer reference
2317  relativeStatisticalErrorIn,
2318  relativeStatisticalErrorOut,
2319  nominal,
2320  nominalIn,
2321  nominalOut,
2322  columns,
2323  rangeLow,
2324  rangeUp,
2325  readMe,
2326  "recBin",
2327  kFALSE,//fRMS, // was RMS< i think not ok ...
2328  kTRUE); // undertainty from ratio
2329  if(relativeErrorRecBinOutUp) {
2330  // canvas with the error from regularization strength
2331  TCanvas* relativeErrorRecBin(new TCanvas("relativeErrorRecBin"," relativeErrorRecBin"));
2332  relativeErrorRecBin->Divide(2);
2333  relativeErrorRecBin->cd(1);
2334  Style(gPad, "GRID");
2335  relativeErrorRecBinInUp->DrawCopy("b");
2336  relativeErrorRecBinInLow->DrawCopy("same b");
2337  Style(AddLegend(gPad));
2338  relativeErrorRecBin->cd(2);
2339  Style(gPad, "GRID");
2340  relativeErrorRecBinOutUp->DrawCopy("b");
2341  relativeErrorRecBinOutLow->DrawCopy("same b");
2342  SavePadToPDF(relativeErrorRecBin);
2343  Style(AddLegend(gPad));
2344  relativeErrorRecBin->Write();
2345  }
2346  }
2347  if(methodIn && methodOut) {
2349  methodIn,
2350  methodOut,
2351  relativeErrorMethodInUp, // pointer reference
2352  relativeErrorMethodInLow, // pointer reference
2353  relativeErrorMethodOutUp, // pointer reference
2354  relativeErrorMethodOutLow, // pointer reference
2355  relativeStatisticalErrorIn,
2356  relativeStatisticalErrorOut,
2357  nominal,
2358  nominalIn,
2359  nominalOut,
2360  columns,
2361  rangeLow,
2362  rangeUp,
2363  readMe,
2364  "method",
2365  kFALSE,
2366  kTRUE); // undertaitny from ratio
2367  if(relativeErrorMethodInUp) {
2368  TCanvas* relativeErrorMethod(new TCanvas("relativeErrorMethod", "relativeErrorMethod"));
2369  relativeErrorMethod->Divide(2);
2370  relativeErrorMethod->cd(1);
2371  Style(gPad, "GRID");
2372  relativeErrorMethodInUp->DrawCopy("b");
2373  relativeErrorMethodInLow->DrawCopy("same b");
2374  Style(AddLegend(gPad));
2375  relativeErrorMethod->cd(2);
2376  Style(gPad, "GRID");
2377  relativeErrorMethodOutUp->DrawCopy("b");
2378  relativeErrorMethodOutLow->DrawCopy("same b");
2379  SavePadToPDF(relativeErrorMethod);
2380  Style(AddLegend(gPad));
2381  relativeErrorMethod->Write();
2382  }
2383  }
2384 
2385  // and the placeholder for the final systematic
2386  TH1D* relativeErrorInUp(new TH1D("max shape uncertainty in plane", "max shape uncertainty in plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2387  TH1D* relativeErrorOutUp(new TH1D("max shape uncertainty out of plane", "max shape uncertainty out of plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2388  TH1D* relativeErrorInLow(new TH1D("min shape uncertainty in plane", "min shape uncertainty in plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2389  TH1D* relativeErrorOutLow(new TH1D("min shape uncertainty out of plane", "min shape uncertainty out of plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2390  relativeErrorInUp->SetYTitle("relative uncertainty");
2391  relativeErrorOutUp->SetYTitle("relative uncertainty");
2392  relativeErrorInLow->SetYTitle("relative uncertainty");
2393  relativeErrorOutLow->SetYTitle("relative uncertainty");
2394 
2395  // sum of squares for the total systematic error
2396  Double_t aInUp(0.), cInUp(0.), dInUp(0.), eInUp(0.);
2397  Double_t aOutUp(0.), cOutUp(0.), dOutUp(0.), eOutUp(0.);
2398  Double_t aInLow(0.), cInLow(0.), dInLow(0.), eInLow(0.);
2399  Double_t aOutLow(0.), cOutLow(0.), dOutLow(0.), eOutLow(0.);
2400 
2401  GetErrorFromFit(relativeErrorRecBinInUp, relativeErrorRecBinInLow, rangeLow, rangeUp, fPivot, fSubdueError, "measured, in-plane");
2402  GetErrorFromFit(relativeErrorRecBinOutUp, relativeErrorRecBinOutLow, rangeLow, rangeUp, fPivot, fSubdueError, "measured, out-of-plane");
2403  GetErrorFromFit(relativeErrorMethodInUp, relativeErrorMethodInLow, rangeLow, rangeUp, fPivot, fSubdueError, "background, in-plane");
2404  GetErrorFromFit(relativeErrorMethodOutUp, relativeErrorMethodOutLow, rangeLow, rangeUp, fPivot, fSubdueError, "background, out-of-plane");
2405 
2406  for(Int_t b(0); b < fBinsTrue->GetSize()-1; b++) {
2407  // for the upper bound only add regularization stuff if it is NOT done on v2 directly
2408  if(relativeErrorRegularizationInUp && !regularizationOnV2) aInUp = relativeErrorRegularizationInUp->GetBinContent(b+1);
2409  if(relativeErrorRegularizationOutUp && !regularizationOnV2) aOutUp = relativeErrorRegularizationOutUp->GetBinContent(b+1);
2410  if(relativeErrorRecBinInUp) cInUp = relativeErrorRecBinInUp->GetBinContent(b+1);
2411  if(relativeErrorRecBinOutUp) cOutUp = relativeErrorRecBinOutUp->GetBinContent(b+1);
2412  if(relativeErrorMethodInUp) dInUp = relativeErrorMethodInUp->GetBinContent(b+1);
2413  if(relativeErrorMethodOutUp) dOutUp = relativeErrorMethodOutUp->GetBinContent(b+1);
2414  // for the lower bound
2415  if(relativeErrorRegularizationInLow) aInLow = relativeErrorRegularizationInLow->GetBinContent(b+1);
2416  if(relativeErrorRegularizationOutLow) aOutLow = relativeErrorRegularizationOutLow->GetBinContent(b+1);
2417  if(relativeErrorRecBinInLow) cInLow = relativeErrorRecBinInLow->GetBinContent(b+1);
2418  if(relativeErrorRecBinOutLow) cOutLow = relativeErrorRecBinOutLow->GetBinContent(b+1);
2419  if(relativeErrorMethodInLow) dInLow = relativeErrorMethodInLow->GetBinContent(b+1);
2420  if(relativeErrorMethodOutLow) dOutLow = relativeErrorMethodOutLow->GetBinContent(b+1);
2421 
2422  if(fSymmRMS) { // since there is no a-priori assumption, we take these errors as symmetric
2423  RemoveSign(aInLow);
2424  RemoveSign(cInLow);
2425  RemoveSign(dInLow);
2426  RemoveSign(aOutLow);
2427  RemoveSign(cOutLow);
2428  RemoveSign(dOutLow);
2429  if(aInLow > aInUp) { aInUp = aInLow;
2430  } else {aInLow = aInUp;}
2431  if(aOutLow > aOutUp) { aOutUp = aOutLow;
2432  } else { aOutLow = aOutUp;}
2433  if(cInLow > cInUp) { cInUp = cInLow;
2434  } else {cInLow = cInUp; };
2435  if(cOutLow > cOutUp ) { cOutUp = cOutLow;
2436  } else { cOutLow = cOutUp; }
2437  // for confusio the logic changes here ...
2438  if(dInLow < dInUp) {dInLow = dInUp;
2439  } else { dInUp = dInLow;}
2440  if(dOutLow < dOutUp) { dOutLow = dOutUp;
2441  } else { dOutUp = dOutLow; }
2442  }
2443  // get the quadratic sums
2444  eInUp = aInUp*aInUp + cInUp*cInUp + dInUp*dInUp;
2445  if(eInUp > 0) relativeErrorInUp->SetBinContent(b+1, 1.*TMath::Sqrt(eInUp));
2446  eOutUp = aOutUp*aOutUp + cOutUp*cOutUp + dOutUp*dOutUp;
2447  if(eOutUp > 0) relativeErrorOutUp->SetBinContent(b+1, 1.*TMath::Sqrt(eOutUp));
2448 
2449  eInLow = aInLow*aInLow + cInLow*cInLow + dInLow*dInLow;
2450  if(eInLow > 0) relativeErrorInLow->SetBinContent(b+1, -1.*TMath::Sqrt(eInLow));
2451  eOutLow = aOutLow*aOutLow + cOutLow*cOutLow + dOutLow*dOutLow;
2452  if(eOutLow > 0) relativeErrorOutLow->SetBinContent(b+1, -1.*TMath::Sqrt(eOutLow));
2453 
2454  printf("%i) \teInUp %.4f \t eInLow %.4f \t eOutUp %4.f \t eOutLow %4.f \n", b, eInUp, eInLow, eOutUp, eOutLow);
2455  }
2456 
2457  // project the estimated errors on the nominal ratio
2458  if(nominal) {
2459  Double_t* ax = new Double_t[fBinsTrue->GetSize()-1];
2460  Double_t* ay = new Double_t[fBinsTrue->GetSize()-1];
2461  Double_t* axh = new Double_t[fBinsTrue->GetSize()-1];
2462  Double_t* axl = new Double_t[fBinsTrue->GetSize()-1];
2463  Double_t* ayh = new Double_t[fBinsTrue->GetSize()-1];
2464  Double_t* ayl = new Double_t[fBinsTrue->GetSize()-1];
2465  Double_t lowErr(0.), upErr(0.);
2466  for(Int_t i(0); i < fBinsTrue->GetSize()-1; i++) {
2467  // add the in and out of plane errors in quadrature
2468  // take special care here: to propagate the assymetric error, we need to correlate the
2469  // InLow with OutUp (minimum value of ratio) and InUp with OutLow (maximum value of ratio)
2470  lowErr = relativeErrorInLow->GetBinContent(i+1)*relativeErrorInLow->GetBinContent(i+1)+relativeErrorOutUp->GetBinContent(1+i)*relativeErrorOutUp->GetBinContent(i+1);
2471  upErr = relativeErrorInUp->GetBinContent(i+1)*relativeErrorInUp->GetBinContent(i+1)+relativeErrorOutLow->GetBinContent(i+1)*relativeErrorOutLow->GetBinContent(i+1);
2472  // set the errors
2473  ayl[i] = TMath::Sqrt(lowErr)*nominal->GetBinContent(i+1);
2474  ayh[i] = TMath::Sqrt(upErr)*nominal->GetBinContent(i+1);
2475  // get the bin width (which is the 'error' on x
2476  Double_t binWidth(nominal->GetBinWidth(i+1));
2477  axl[i] = binWidth/2.;
2478  axh[i] = binWidth/2.;
2479  // now get the coordinate for the point
2480  ax[i] = nominal->GetBinCenter(i+1);
2481  ay[i] = nominal->GetBinContent(i+1);
2482  }
2483 
2484  // save the nominal ratio
2485  TGraphAsymmErrors* nominalError(new TGraphAsymmErrors(fBinsTrue->GetSize()-1, ax, ay, axl, axh, ayl, ayh));
2486  shapeRatio = (TGraphAsymmErrors*)nominalError->Clone();
2487  nominalError->SetName("shape uncertainty");
2488  TCanvas* nominalCanvas(new TCanvas("nominalCanvas", "nominalCanvas"));
2489  nominalCanvas->Divide(2);
2490  nominalCanvas->cd(1);
2491  Style(nominal, kBlack);
2492  Style(nominalError, kCyan, kRatio);
2493  nominalError->SetLineColor(kCyan);
2494  nominalError->SetMarkerColor(kCyan);
2495  nominalError->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2496  nominalError->GetYaxis()->SetRangeUser(.7, 2.2);
2497  nominalError->DrawClone("a2");
2498  nominal->DrawCopy("same E1");
2499  Style(AddLegend(gPad));
2500  Style(gPad, "GRID");
2501  Style(nominalCanvas);
2502  // save nominal v2 and systematic errors
2503  TGraphAsymmErrors* nominalV2Error(GetV2WithSystematicErrors(
2504  nominalIn,
2505  nominalOut,
2507  "v_{2} with shape uncertainty",
2508  relativeErrorInUp,
2509  relativeErrorInLow,
2510  relativeErrorOutUp,
2511  relativeErrorOutLow,
2512  corr));
2513  shapeV2 = (TGraphAsymmErrors*)nominalV2Error->Clone();
2514  if(regularizationOnV2) shapeV2 = AddHistoErrorsToGraphErrors(shapeV2, relativeErrorRegularizationInUp);
2515  TGraphErrors* nominalV2(GetV2(nominalIn, nominalOut, fEventPlaneRes, "v_{2}"));
2516  // add in quadratufe (not very nice, rethink this because it may add additional weight to
2517  // the rms unfolded piece) the additional error
2518  nominalCanvas->cd(2);
2519  Style(nominalV2, kBlack);
2520  Style(nominalV2Error, kCyan, kV2);
2521  nominalV2Error->SetLineColor(kCyan);
2522  nominalV2Error->SetMarkerColor(kCyan);
2523  nominalV2Error->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2524  nominalV2Error->DrawClone("a2");
2525  nominalV2->DrawClone("same E1");
2526  Style(AddLegend(gPad));
2527  Style(gPad, "GRID");
2528  Style(nominalCanvas);
2529  SavePadToPDF(nominalCanvas);
2530  nominalCanvas->Write();
2531  }
2532  TCanvas* relativeError(new TCanvas("relativeError"," relativeError"));
2533  relativeError->Divide(2);
2534  relativeError->cd(1);
2535  Style(gPad, "GRID");
2536  relativeErrorInUp->GetYaxis()->SetRangeUser(-1.5, 3.);
2537  Style(relativeErrorInUp, kBlue, kBar);
2538  Style(relativeErrorInLow, kGreen, kBar);
2539  relativeErrorInUp->DrawCopy("b");
2540  relativeErrorInLow->DrawCopy("same b");
2541  Style(relativeStatisticalErrorIn, kRed);
2542  relativeStatisticalErrorIn->DrawCopy("same");
2543  Style(AddLegend(gPad));
2544  relativeError->cd(2);
2545  Style(gPad, "GRID");
2546  Style(relativeErrorOutUp, kBlue, kBar);
2547  Style(relativeErrorOutLow, kGreen, kBar);
2548  relativeErrorOutUp->DrawCopy("b");
2549  if(relativeErrorOutLow) relativeErrorOutLow->DrawCopy("same b");
2550  if(relativeStatisticalErrorOut) Style(relativeStatisticalErrorOut, kRed);
2551  if(relativeStatisticalErrorOut) relativeStatisticalErrorOut->DrawCopy("same");
2552  Style(AddLegend(gPad));
2553 
2554  // write the buffered file to disk
2555  SavePadToPDF(relativeError);
2556  relativeError->Write();
2557  output->Write();
2558 }
2559 //_____________________________________________________________________________
2561  TArrayI* variationsIn, // variantions in plane
2562  TArrayI* variationsOut, // variantions out of plane
2563  TH1D*& relativeErrorInUp, // pointer reference to minimum relative error histogram in plane
2564  TH1D*& relativeErrorInLow, // pointer reference to maximum relative error histogram in plane
2565  TH1D*& relativeErrorOutUp, // pointer reference to minimum relative error histogram out of plane
2566  TH1D*& relativeErrorOutLow, // pointer reference to maximum relative error histogram out of plane
2567  TH1D*& relativeStatisticalErrorIn, // relative systematic error on ratio
2568  TH1D*& relativeStatisticalErrorOut, // relative systematic error on ratio
2569  TH1D*& nominal, // clone of the nominal ratio in / out of plane
2570  TH1D*& nominalIn, // clone of the nominal in plane yield
2571  TH1D*& nominalOut, // clone of the nominal out of plane yield
2572  Int_t columns, // divide the output canvasses in this many columns
2573  Float_t rangeLow, // lower pt range
2574  Float_t rangeUp, // upper pt range
2575  TFile* readMe, // input file name (created by this unfolding class)
2576  TString source, // source of the variation
2577  Bool_t RMS, // return RMS of distribution of variations as error
2578  Bool_t onRatio // use ratio or v2 directly for assessing systematic uncertainty
2579  ) const
2580 {
2581 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
2582  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
2583 #endif
2584  // wrapper function to call specific systematics function using function pointers
2585  void (AliJetFlowTools::*myFunction)(TArrayI*, TArrayI*, TH1D*&, TH1D*&, TH1D*&, TH1D*&, TH1D*&, TH1D*&,
2586  TH1D*&, TH1D*&, TH1D*&, Int_t, Float_t, Float_t, TFile*, TString, Bool_t) const;
2587 
2588  printf(" >>> systematic wrapper called for %s <<< \n", source.Data());
2589 
2590  // assign function pointer
2592 
2593  // do the actual unfolding with the selected function
2594  return (this->*myFunction)(
2595  variationsIn,
2596  variationsOut,
2597  relativeErrorInUp,
2598  relativeErrorInLow,
2599  relativeErrorOutUp,
2600  relativeErrorOutLow,
2601  relativeStatisticalErrorIn,
2602  relativeStatisticalErrorOut,
2603  nominal,
2604  nominalIn,
2605  nominalOut,
2606  columns,
2607  rangeLow,
2608  rangeUp,
2609  readMe,
2610  source,
2611  RMS);
2612 }
2613 //_____________________________________________________________________________
2615  TArrayI* variationsIn, // variantions in plane
2616  TArrayI* variationsOut, // variantions out of plane
2617  TH1D*& relativeErrorInUp, // pointer reference to minimum relative error histogram in plane
2618  TH1D*& relativeErrorInLow, // pointer reference to maximum relative error histogram in plane
2619  TH1D*& relativeErrorOutUp, // pointer reference to minimum relative error histogram out of plane
2620  TH1D*& relativeErrorOutLow, // pointer reference to maximum relative error histogram out of plane
2621  TH1D*& relativeStatisticalErrorIn, // relative systematic error on ratio
2622  TH1D*& relativeStatisticalErrorOut, // relative systematic error on ratio
2623  TH1D*& nominal, // clone of the nominal ratio in / out of plane
2624  TH1D*& nominalIn, // clone of the nominal in plane yield
2625  TH1D*& nominalOut, // clone of the nominal out of plane yield
2626  Int_t columns, // divide the output canvasses in this many columns
2627  Float_t rangeLow, // lower pt range
2628  Float_t rangeUp, // upper pt range
2629  TFile* readMe, // input file name (created by this unfolding class)
2630  TString source, // source of the variation
2631  Bool_t RMS // return RMS of distribution of variations as error
2632  ) const
2633 {
2634 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
2635  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
2636 #endif
2637  // intermediate systematic check function. first index of supplied array is nominal value
2638  TList* listOfKeys((TList*)readMe->GetListOfKeys());
2639  if(!listOfKeys) {
2640  printf(" > Fatal error, couldn't retrieve list of keys. Input file might have been corrupted ! < \n");
2641  return;
2642  }
2643  // check input params
2644  if(variationsIn->GetSize() != variationsOut->GetSize()) {
2645  printf(" > DoSystematics: fatal error, input arrays have different sizes ! < \n ");
2646  return;
2647  }
2648  TDirectoryFile* defRootDirIn(dynamic_cast<TDirectoryFile*>(readMe->Get(listOfKeys->At(variationsIn->At(0))->GetName())));
2649  TDirectoryFile* defRootDirOut(dynamic_cast<TDirectoryFile*>(readMe->Get(listOfKeys->At(variationsOut->At(0))->GetName())));
2650  if(!(defRootDirIn && defRootDirOut)) {
2651  printf(" > DoSystematics: fatal error, couldn't retrieve nominal values ! < \n ");
2652  return;
2653  }
2654  TString defIn(defRootDirIn->GetName());
2655  TString defOut(defRootDirOut->GetName());
2656 
2657  // define lines to make the output prettier
2658  TLine* lineLow(new TLine(rangeLow, 0., rangeLow, 2.));
2659  TLine* lineUp(new TLine(rangeUp, 0., rangeUp, 2.));
2660  lineLow->SetLineColor(11);
2661  lineUp->SetLineColor(11);
2662  lineLow->SetLineWidth(3);
2663  lineUp->SetLineWidth(3);
2664 
2665  // define an output histogram with the maximum relative error from this systematic constribution
2666  // if the option RMS is set to false, sigma is not really a standard deviation but holds the maximum (or minimum) relative value that the data has
2667  // reached in this function call.
2668  // if the option RMS is set to true, sigma holds the RMS value (equal to sigma as the mean is zero for relative errors) of the distribution of variations
2669  // which should correspond to a 68% confidence level
2670  relativeErrorInUp = new TH1D(Form("relative error (up) from %s", source.Data()), Form("relative error (up) from %s", source.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2671  relativeErrorInLow = new TH1D(Form("relative error (low) from %s", source.Data()), Form("relative error (low) from %s", source.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2672  relativeErrorOutUp = new TH1D(Form("relative error (up) from %s", source.Data()), Form("relative error (up) from %s", source.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2673  relativeErrorOutLow = new TH1D(Form("relative error (low) from %s", source.Data()), Form("relative error (low) from %s", source.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2674  for(Int_t b(0); b < fBinsTrue->GetSize()-1; b++) {
2675  if(!RMS) {
2676  relativeErrorInUp->SetBinContent(b+1, 1.);
2677  relativeErrorInUp->SetBinError(b+1, 0.);
2678  relativeErrorOutUp->SetBinContent(b+1, 1.);
2679  relativeErrorOutUp->SetBinError(b+1, .0);
2680  relativeErrorInLow->SetBinContent(b+1, 1.);
2681  relativeErrorInLow->SetBinError(b+1, 0.);
2682  relativeErrorOutLow->SetBinContent(b+1, 1.);
2683  relativeErrorOutLow->SetBinError(b+1, .0);
2684  } else if(RMS) {
2685  relativeErrorInUp->SetBinContent(b+1, 0.);
2686  relativeErrorInUp->SetBinError(b+1, 0.);
2687  relativeErrorOutUp->SetBinContent(b+1, 0.);
2688  relativeErrorOutUp->SetBinError(b+1, 0.);
2689  relativeErrorInLow->SetBinContent(b+1, 0.);
2690  relativeErrorInLow->SetBinError(b+1, 0.);
2691  relativeErrorOutLow->SetBinContent(b+1, 0.);
2692  relativeErrorOutLow->SetBinError(b+1, 0.);
2693  }
2694  }
2695  Int_t relativeErrorInUpN[100] = {0};
2696  Int_t relativeErrorOutUpN[100] = {0};
2697  Int_t relativeErrorInLowN[100] = {0};
2698  Int_t relativeErrorOutLowN[100] = {0};
2699 
2700  // define an output histogram with the systematic error from this systematic constribution
2701  if(!relativeStatisticalErrorIn || !relativeStatisticalErrorOut) {
2702  relativeStatisticalErrorIn = new TH1D("relative statistical error, in plane", "relative statistical error, in plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2703  relativeStatisticalErrorOut = new TH1D("relative statistical error, out of plane", "relative statistital error, out of plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2704  }
2705 
2706  // prepare necessary canvasses
2707  TCanvas* canvasIn(new TCanvas(Form("SYST_%s_PearsonIn", source.Data()), Form("SYST_%s_PearsonIn", source.Data())));
2708  TCanvas* canvasOut(0x0);
2709  if(fDphiUnfolding) canvasOut = new TCanvas(Form("SYST_%s_PearsonOut", source.Data()), Form("SYST_%s_PearsonOut", source.Data()));
2710  TCanvas* canvasRatioMeasuredRefoldedIn(new TCanvas(Form("SYST_%s_RefoldedIn", source.Data()), Form("SYST_%s_RefoldedIn", source.Data())));
2711  TCanvas* canvasRatioMeasuredRefoldedOut(0x0);
2712  if(fDphiUnfolding) canvasRatioMeasuredRefoldedOut = new TCanvas(Form("SYST_%s_RefoldedOut", source.Data()), Form("SYST_%s_RefoldedOut", source.Data()));
2713  TCanvas* canvasSpectraIn(new TCanvas(Form("SYST_%s_SpectraIn", source.Data()), Form("SYST_%s_SpectraIn", source.Data())));
2714  TCanvas* canvasSpectraOut(0x0);
2715  if(fDphiUnfolding) canvasSpectraOut = new TCanvas(Form("SYST_%s_SpectraOut", source.Data()), Form("SYST_%s_SpectraOut", source.Data()));
2716  TCanvas* canvasRatio(0x0);
2717  if(fDphiUnfolding) canvasRatio = new TCanvas(Form("SYST_%s_Ratio", source.Data()), Form("SYST_%s_Ratio", source.Data()));
2718  TCanvas* canvasV2(0x0);
2719  if(fDphiUnfolding) canvasV2 = new TCanvas(Form("SYST_%s_V2", source.Data()), Form("SYST_%s_V2", source.Data()));
2720  TCanvas* canvasMISC(new TCanvas(Form("SYST_%s_MISC", source.Data()), Form("SYST_%s_MISC", source.Data())));
2721  TCanvas* canvasMasterIn(new TCanvas(Form("SYST_%s_defaultIn", source.Data()), Form("SYST_%s_defaultIn", source.Data())));
2722  TCanvas* canvasMasterOut(0x0);
2723  if(fDphiUnfolding) canvasMasterOut = new TCanvas(Form("SYST_%s_defaultOut", source.Data()), Form("SYST_%s_defaultOut", source.Data()));
2724  (fDphiUnfolding) ? canvasMISC->Divide(4, 2) : canvasMISC->Divide(4, 1);
2725 
2726  TCanvas* canvasProfiles(new TCanvas(Form("SYST_%s_canvasProfiles", source.Data()), Form("SYST_%s_canvasProfiles", source.Data())));
2727  canvasProfiles->Divide(2);
2728  TProfile* ratioProfile(new TProfile(Form("SYST_%s_ratioProfile", source.Data()), Form("SYST_%s_ratioProfile", source.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2729  TProfile* v2Profile(new TProfile(Form("SYST_%s_v2Profile", source.Data()), Form("SYST_%s_v2Profile", source.Data()),fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2730  // get an estimate of the number of outputs and find the default set
2731 
2732  Int_t rows = 1;
2733  columns = variationsIn->GetSize()-1;
2734  (TMath::Floor(variationsIn->GetSize()/(float)columns)+((variationsIn->GetSize()%columns)>0));
2735  canvasIn->Divide(columns, rows);
2736  if(canvasOut) canvasOut->Divide(columns, rows);
2737  canvasRatioMeasuredRefoldedIn->Divide(columns, rows);
2738  if(canvasRatioMeasuredRefoldedOut) canvasRatioMeasuredRefoldedOut->Divide(columns, rows);
2739  canvasSpectraIn->Divide(columns, rows);
2740  if(canvasSpectraOut) canvasSpectraOut->Divide(columns, rows);
2741  if(canvasRatio) canvasRatio->Divide(columns, rows);
2742  if(canvasV2) canvasV2->Divide(columns, rows);
2743  canvasMasterIn->Divide(columns, rows);
2744  if(canvasMasterOut) canvasMasterOut->Divide(columns, rows);
2745 
2746  // prepare a separate set of canvases to hold the nominal points
2747  TCanvas* canvasNominalIn(new TCanvas(Form("Nominal_%s_PearsonIn", source.Data()), Form("Nominal_%s_PearsonIn", source.Data())));
2748  TCanvas* canvasNominalOut(0x0);
2749  if(fDphiUnfolding) canvasNominalOut = new TCanvas(Form("Nominal_%s_PearsonOut", source.Data()), Form("Nominal_%s_PearsonOut", source.Data()));
2750  TCanvas* canvasNominalRatioMeasuredRefoldedIn(new TCanvas(Form("Nominal_%s_RefoldedIn", source.Data()), Form("Nominal_%s_RefoldedIn", source.Data())));
2751  TCanvas* canvasNominalRatioMeasuredRefoldedOut(0x0);
2752  if(fDphiUnfolding) canvasNominalRatioMeasuredRefoldedOut = new TCanvas(Form("Nominal_%s_RefoldedOut", source.Data()), Form("Nominal_%s_RefoldedOut", source.Data()));
2753  TCanvas* canvasNominalSpectraIn(new TCanvas(Form("Nominal_%s_SpectraIn", source.Data()), Form("Nominal_%s_SpectraIn", source.Data())));
2754  TCanvas* canvasNominalSpectraOut(0x0);
2755  if(fDphiUnfolding) canvasNominalSpectraOut = new TCanvas(Form("Nominal_%s_SpectraOut", source.Data()), Form("Nominal_%s_SpectraOut", source.Data()));
2756  TCanvas* canvasNominalRatio(0x0);
2757  if(fDphiUnfolding) canvasNominalRatio = new TCanvas(Form("Nominal_%s_Ratio", source.Data()), Form("Nominal_%s_Ratio", source.Data()));
2758  TCanvas* canvasNominalV2(0x0);
2759  if(fDphiUnfolding) canvasNominalV2 = new TCanvas(Form("Nominal_%s_V2", source.Data()), Form("Nominal_%s_V2", source.Data()));
2760  TCanvas* canvasNominalMISC(new TCanvas(Form("Nominal_%s_MISC", source.Data()), Form("Nominal_%s_MISC", source.Data())));
2761  TCanvas* canvasNominalMasterIn(new TCanvas(Form("Nominal_%s_defaultIn", source.Data()), Form("Nominal_%s_defaultIn", source.Data())));
2762  TCanvas* canvasNominalMasterOut(0x0);
2763  if(fDphiUnfolding) canvasNominalMasterOut = new TCanvas(Form("Nominal_%s_defaultOut", source.Data()), Form("Nominal_%s_defaultOut", source.Data()));
2764  (fDphiUnfolding) ? canvasNominalMISC->Divide(4, 2) : canvasNominalMISC->Divide(4, 1);
2765 
2766  canvasNominalSpectraIn->Divide(2);
2767  if(canvasNominalSpectraOut) canvasNominalSpectraOut->Divide(2);
2768 
2769  canvasNominalMasterIn->Divide(2);
2770  if(canvasNominalMasterOut) canvasNominalMasterOut->Divide(2);
2771 
2772  // extract the default output
2773  TH1D* defaultUnfoldedJetSpectrumIn(0x0);
2774  TH1D* defaultUnfoldedJetSpectrumOut(0x0);
2775  TDirectoryFile* defDirIn = (TDirectoryFile*)defRootDirIn->Get(Form("InPlane___%s", defIn.Data()));
2776  TDirectoryFile* defDirOut = (TDirectoryFile*)defRootDirOut->Get(Form("OutOfPlane___%s", defOut.Data()));
2777  if(defDirIn) defaultUnfoldedJetSpectrumIn = (TH1D*)defDirIn->Get(Form("UnfoldedSpectrum_in_%s", defIn.Data()));
2778  if(defDirOut) defaultUnfoldedJetSpectrumOut = (TH1D*)defDirOut->Get(Form("UnfoldedSpectrum_out_%s", defOut.Data()));
2779  printf(" > succesfully extracted default results < \n");
2780 
2781  // loop through the directories, only plot the graphs if the deconvolution converged
2782  TDirectoryFile* tempDirIn(0x0);
2783  TDirectoryFile* tempDirOut(0x0);
2784  TDirectoryFile* tempIn(0x0);
2785  TDirectoryFile* tempOut(0x0);
2786  TH1D* unfoldedSpectrumInForRatio(0x0);
2787  TH1D* unfoldedSpectrumOutForRatio(0x0);
2788  for(Int_t i(0), j(-1); i < variationsIn->GetSize(); i++) {
2789  tempDirIn = (dynamic_cast<TDirectoryFile*>(readMe->Get(listOfKeys->At(variationsIn->At(i))->GetName())));
2790  tempDirOut = (dynamic_cast<TDirectoryFile*>(readMe->Get(listOfKeys->At(variationsOut->At(i))->GetName())));
2791  if(!(tempDirIn && tempDirOut)) {
2792  printf(" > DoSystematics: couldn't get a set of variations < \n");
2793  continue;
2794  }
2795  TString dirNameIn(tempDirIn->GetName());
2796  TString dirNameOut(tempDirOut->GetName());
2797  // try to read the in- and out of plane subdirs
2798  tempIn = (TDirectoryFile*)tempDirIn->Get(Form("InPlane___%s", dirNameIn.Data()));
2799  tempOut = (TDirectoryFile*)tempDirOut->Get(Form("OutOfPlane___%s", dirNameOut.Data()));
2800  j++;
2801  if(tempIn) {
2802  // to see if the unfolding converged try to extract the pearson coefficients
2803  TH2D* pIn((TH2D*)tempIn->Get(Form("PearsonCoefficients_in_%s", dirNameIn.Data())));
2804  if(pIn) {
2805  printf(" - %s in plane converged \n", dirNameIn.Data());
2806  canvasIn->cd(j);
2807  if(i==0) canvasNominalIn->cd(j);
2808  Style(gPad, "PEARSON");
2809  pIn->DrawCopy("colz");
2810  TGraphErrors* rIn((TGraphErrors*)tempIn->Get(Form("RatioRefoldedMeasured_%s", dirNameIn.Data())));
2811  if(rIn) {
2812  Style(rIn);
2813  printf(" > found RatioRefoldedMeasured < \n");
2814  canvasRatioMeasuredRefoldedIn->cd(j);
2815  if(i==0) canvasNominalRatioMeasuredRefoldedIn->cd(j);
2816  Style(gPad, "GRID");
2817  rIn->SetFillColor(kRed);
2818  rIn->Draw("ap");
2819  }
2820  TH1D* dvector((TH1D*)tempIn->Get("dVector"));
2821  TH1D* avalue((TH1D*)tempIn->Get("SingularValuesOfAC"));
2822  TH2D* rm((TH2D*)tempIn->Get(Form("ResponseMatrixIn_%s", dirNameIn.Data())));
2823  TH1D* eff((TH1D*)tempIn->Get(Form("KinematicEfficiencyIn_%s", dirNameIn.Data())));
2824  if(dvector && avalue && rm && eff) {
2825  Style(dvector);
2826  Style(avalue);
2827  Style(rm);
2828  Style(eff);
2829  canvasMISC->cd(1);
2830  if(i==0) canvasNominalMISC->cd(1);
2831  Style(gPad, "SPECTRUM");
2832  dvector->DrawCopy();
2833  canvasMISC->cd(2);
2834  if(i==0) canvasNominalMISC->cd(2);
2835  Style(gPad, "SPECTRUM");
2836  avalue->DrawCopy();
2837  canvasMISC->cd(3);
2838  if(i==0) canvasNominalMISC->cd(3);
2839  Style(gPad, "PEARSON");
2840  rm->DrawCopy("colz");
2841  canvasMISC->cd(4);
2842  if(i==0) canvasNominalMISC->cd(4);
2843  Style(gPad, "GRID");
2844  eff->DrawCopy();
2845  } else if(rm && eff) {
2846  Style(rm);
2847  Style(eff);
2848  canvasMISC->cd(3);
2849  if(i==0) canvasNominalMISC->cd(3);
2850  Style(gPad, "PEARSON");
2851  rm->DrawCopy("colz");
2852  canvasMISC->cd(4);
2853  if(i==0) canvasNominalMISC->cd(4);
2854  Style(gPad, "GRID");
2855  eff->DrawCopy();
2856  }
2857  }
2858  TH1D* inputSpectrum((TH1D*)tempIn->Get(Form("InputSpectrum_in_%s", dirNameIn.Data())));
2859  TH1D* unfoldedSpectrum((TH1D*)tempIn->Get(Form("UnfoldedSpectrum_in_%s", dirNameIn.Data())));
2860  unfoldedSpectrumInForRatio = ProtectHeap(unfoldedSpectrum, kFALSE, TString("ForRatio"));
2861  TH1D* refoldedSpectrum((TH1D*)tempIn->Get(Form("RefoldedSpectrum_in_%s", dirNameIn.Data())));
2862  if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
2863  if(defaultUnfoldedJetSpectrumIn) {
2864  Style(defaultUnfoldedJetSpectrumIn, kBlue, kUnfoldedSpectrum);
2865  TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumIn->Clone(Form("defaultUnfoldedJetSpectrumIn_%s", dirNameIn.Data())));
2866  temp->Divide(unfoldedSpectrum);
2867  // get the absolute relative error
2868  for(Int_t b(0); b < fBinsTrue->GetSize()-1; b++) {
2869  if(!RMS) { // save the maximum deviation that a variation can cause
2870  // the variation is HIGHER than the nominal point, so the bar goes UP
2871  if( temp->GetBinContent(b+1) < 1 && temp->GetBinContent(b+1) < relativeErrorInUp->GetBinContent(b+1)) {
2872  relativeErrorInUp->SetBinContent(b+1, temp->GetBinContent(b+1));
2873  relativeErrorInUp->SetBinError(b+1, temp->GetBinError(b+1));
2874  }
2875  // the variation is LOWER than the nominal point, so the bar goes DOWN
2876  else if(temp->GetBinContent(b+1) > 1 && temp->GetBinContent(b+1) > relativeErrorInLow->GetBinContent(b+1)) {
2877  relativeErrorInLow->SetBinContent(b+1, temp->GetBinContent(b+1));
2878  relativeErrorInLow->SetBinError(b+1, temp->GetBinError(b+1));
2879  }
2880  } else if (RMS && !fSymmRMS) { // save info necessary for evaluating the RMS of a distribution of variations
2881  printf(" oops shouldnt be here \n " );
2882  if(temp->GetBinContent(b+1) < 1) {
2883  relativeErrorInUp->SetBinContent(b+1, relativeErrorInUp->GetBinContent(b+1)+TMath::Power(1.-temp->GetBinContent(b+1), 2));
2884  relativeErrorInUpN[b]++;
2885  }
2886  // the variation is LOWER than the nominal point, so the bar goes DOWN
2887  else if(temp->GetBinContent(b+1) > 1) {
2888  relativeErrorInLow->SetBinContent(b+1, relativeErrorInLow->GetBinContent(b+1)+TMath::Power(1.-temp->GetBinContent(b+1), 2));
2889  relativeErrorInLowN[b]++;
2890  }
2891  } else if (fSymmRMS) {
2892  // save symmetric sum of square to get a symmetric rms
2893  relativeErrorInUp->SetBinContent(b+1, relativeErrorInUp->GetBinContent(b+1)+TMath::Power(temp->GetBinContent(b+1)-1., 2));
2894  relativeErrorInUpN[b]++;
2895  }
2896  if(temp->GetBinError(b+1) > 0) relativeStatisticalErrorIn->SetBinContent(b+1, temp->GetBinError(b+1)/temp->GetBinContent(b+1));
2897  }
2898  temp->SetTitle(Form("[%s] / [%s]", defIn.Data(), dirNameIn.Data()));
2899  temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
2900  temp->GetYaxis()->SetTitle("ratio");
2901  canvasMasterIn->cd(j);
2902  temp->GetYaxis()->SetRangeUser(0., 2);
2903  Style(gPad, "GRID");
2904  temp->DrawCopy();
2905  canvasNominalMasterIn->cd(1);
2906  Style(gPad, "GRID");
2907  if(i > 0 ) {
2908  TH1D* tempSyst((TH1D*)temp->Clone(Form("%s_syst", temp->GetName())));
2909  tempSyst->SetTitle(Form("[%s] / [%s]", defIn.Data(), dirNameIn.Data()));
2910  Style(tempSyst, (EColor)(i+2));
2911  if(i==1) tempSyst->DrawCopy();
2912  else tempSyst->DrawCopy("same");
2913  }
2914  }
2915  TH1F* fitStatus((TH1F*)tempIn->Get(Form("fitStatus_%s_in", dirNameIn.Data())));
2916  canvasSpectraIn->cd(j);
2917  if(i==0) canvasNominalSpectraIn->cd(1);
2918  Style(gPad);
2919  Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
2920  unfoldedSpectrum->DrawCopy();
2921  Style(inputSpectrum, kGreen, kMeasuredSpectrum);
2922  inputSpectrum->DrawCopy("same");
2923  Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
2924  refoldedSpectrum->DrawCopy("same");
2925  TLegend* l(AddLegend(gPad));
2926  Style(l);
2927  if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
2928  Float_t chi(fitStatus->GetBinContent(1));
2929  Float_t pen(fitStatus->GetBinContent(2));
2930  Int_t dof((int)fitStatus->GetBinContent(3));
2931  Float_t beta(fitStatus->GetBinContent(4));
2932  l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
2933  } else if (fitStatus) { // only available in SVD fit
2934  Int_t reg((int)fitStatus->GetBinContent(1));
2935  l->AddEntry((TObject*)0, Form("REG %i", reg), "");
2936  }
2937  canvasNominalSpectraIn->cd(2);
2938  TH1D* tempSyst((TH1D*)unfoldedSpectrum->Clone(Form("%s_syst", unfoldedSpectrum->GetName())));
2939  tempSyst->SetTitle(Form("[%s]", dirNameIn.Data()));
2940  Style(tempSyst, (EColor)(i+2));
2941  Style(gPad, "SPECTRUM");
2942  if(i==0) tempSyst->DrawCopy();
2943  else tempSyst->DrawCopy("same");
2944  }
2945  }
2946  if(tempOut) {
2947  TH2D* pOut((TH2D*)tempOut->Get(Form("PearsonCoefficients_out_%s", dirNameOut.Data())));
2948  if(pOut) {
2949  printf(" - %s out of plane converged \n", dirNameOut.Data());
2950  canvasOut->cd(j);
2951  if(i==0) canvasNominalOut->cd(j);
2952  Style(gPad, "PEARSON");
2953  pOut->DrawCopy("colz");
2954  TGraphErrors* rOut((TGraphErrors*)tempOut->Get(Form("RatioRefoldedMeasured_%s", dirNameOut.Data())));
2955  if(rOut) {
2956  Style(rOut);
2957  printf(" > found RatioRefoldedMeasured < \n");
2958  canvasRatioMeasuredRefoldedOut->cd(j);
2959  if(i==0) canvasNominalRatioMeasuredRefoldedOut->cd(j);
2960  Style(gPad, "GRID");
2961  rOut->SetFillColor(kRed);
2962  rOut->Draw("ap");
2963  }
2964  TH1D* dvector((TH1D*)tempOut->Get("dVector"));
2965  TH1D* avalue((TH1D*)tempOut->Get("SingularValuesOfAC"));
2966  TH2D* rm((TH2D*)tempOut->Get(Form("ResponseMatrixOut_%s", dirNameOut.Data())));
2967  TH1D* eff((TH1D*)tempOut->Get(Form("KinematicEfficiencyOut_%s", dirNameOut.Data())));
2968  if(dvector && avalue && rm && eff) {
2969  Style(dvector);
2970  Style(avalue);
2971  Style(rm);
2972  Style(eff);
2973  canvasMISC->cd(5);
2974  if(i==0) canvasNominalMISC->cd(5);
2975  Style(gPad, "SPECTRUM");
2976  dvector->DrawCopy();
2977  canvasMISC->cd(6);
2978  if(i==0) canvasNominalMISC->cd(6);
2979  Style(gPad, "SPECTRUM");
2980  avalue->DrawCopy();
2981  canvasMISC->cd(7);
2982  if(i==0) canvasNominalMISC->cd(7);
2983  Style(gPad, "PEARSON");
2984  rm->DrawCopy("colz");
2985  canvasMISC->cd(8);
2986  if(i==0) canvasNominalMISC->cd(8);
2987  Style(gPad, "GRID");
2988  eff->DrawCopy();
2989  } else if(rm && eff) {
2990  Style(rm);
2991  Style(eff);
2992  canvasMISC->cd(7);
2993  if(i==0) canvasNominalMISC->cd(7);
2994  Style(gPad, "PEARSON");
2995  rm->DrawCopy("colz");
2996  canvasMISC->cd(8);
2997  if(i==0) canvasNominalMISC->cd(8);
2998  Style(gPad, "GRID");
2999  eff->DrawCopy();
3000  }
3001  }
3002  TH1D* inputSpectrum((TH1D*)tempOut->Get(Form("InputSpectrum_out_%s", dirNameOut.Data())));
3003  TH1D* unfoldedSpectrum((TH1D*)tempOut->Get(Form("UnfoldedSpectrum_out_%s", dirNameOut.Data())));
3004  unfoldedSpectrumOutForRatio = ProtectHeap(unfoldedSpectrum, kFALSE, TString("ForRatio"));
3005  TH1D* refoldedSpectrum((TH1D*)tempOut->Get(Form("RefoldedSpectrum_out_%s", dirNameOut.Data())));
3006  if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
3007  if(defaultUnfoldedJetSpectrumOut) {
3008  Style(defaultUnfoldedJetSpectrumOut, kBlue, kUnfoldedSpectrum);
3009  TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumOut->Clone(Form("defaultUnfoldedJetSpectrumOut_%s", dirNameOut.Data())));
3010  temp->Divide(unfoldedSpectrum);
3011  // get the absolute relative error
3012  for(Int_t b(0); b < fBinsTrue->GetSize()-1; b++) {
3013  if(!RMS) {
3014  // check if the error is larger than the current maximum
3015  if(temp->GetBinContent(b+1) < 1 && temp->GetBinContent(b+1) < relativeErrorOutUp->GetBinContent(b+1)) {
3016  relativeErrorOutUp->SetBinContent(b+1, temp->GetBinContent(b+1));
3017  relativeErrorOutUp->SetBinError(b+1, temp->GetBinError(b+1));
3018  }
3019  // check if the error is smaller than the current minimum
3020  else if(temp->GetBinContent(b+1) > 1 && temp->GetBinContent(b+1) > relativeErrorOutLow->GetBinContent(b+1)) {
3021  relativeErrorOutLow->SetBinContent(b+1, temp->GetBinContent(b+1));
3022  relativeErrorOutLow->SetBinError(b+1, temp->GetBinError(b+1));
3023  }
3024  } else if (RMS && !fSymmRMS) {
3025  printf(" OOps \n ");
3026  if(temp->GetBinContent(b+1) < 1) {
3027  relativeErrorOutUp->SetBinContent(b+1, relativeErrorOutUp->GetBinContent(b+1)+TMath::Power(1.-temp->GetBinContent(b+1), 2));
3028  relativeErrorOutUpN[b]++;
3029  }
3030  else if(temp->GetBinContent(b+1) > 1) {
3031  relativeErrorOutLow->SetBinContent(b+1, relativeErrorOutLow->GetBinContent(b+1)+TMath::Power(1.-temp->GetBinContent(b+1), 2));
3032  relativeErrorOutLowN[b]++;
3033  }
3034  } else if (fSymmRMS) {
3035  // save symmetric rms value
3036  relativeErrorOutUp->SetBinContent(b+1, relativeErrorOutUp->GetBinContent(b+1)+TMath::Power(temp->GetBinContent(b+1)-1., 2));
3037  relativeErrorOutUpN[b]++;
3038  }
3039  if(temp->GetBinError(b+1) > 0) relativeStatisticalErrorOut->SetBinContent(b+1, temp->GetBinError(b+1)/temp->GetBinContent(b+1));
3040  }
3041  temp->SetTitle(Form("[%s] / [%s]", defOut.Data(), dirNameOut.Data()));
3042  temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
3043  temp->GetYaxis()->SetTitle("ratio");
3044  canvasMasterOut->cd(j);
3045  temp->GetYaxis()->SetRangeUser(0., 2);
3046  Style(gPad, "GRID");
3047  temp->DrawCopy();
3048  canvasNominalMasterOut->cd(1);
3049  Style(gPad, "GRID");
3050  if(i > 0 ) {
3051  TH1D* tempSyst((TH1D*)temp->Clone(Form("%s_syst", temp->GetName())));
3052  tempSyst->SetTitle(Form("[%s] / [%s]", defOut.Data(), dirNameOut.Data()));
3053  Style(tempSyst, (EColor)(i+2));
3054  if(i==1) tempSyst->DrawCopy();
3055  else tempSyst->DrawCopy("same");
3056  }
3057  }
3058  TH1F* fitStatus((TH1F*)tempOut->Get(Form("fitStatus_%s_out", dirNameOut.Data())));
3059  canvasSpectraOut->cd(j);
3060  if(i==0) canvasNominalSpectraOut->cd(1);
3061  Style(gPad);
3062  Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
3063  unfoldedSpectrum->DrawCopy();
3064  Style(inputSpectrum, kGreen, kMeasuredSpectrum);
3065  inputSpectrum->DrawCopy("same");
3066  Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
3067  refoldedSpectrum->DrawCopy("same");
3068  TLegend* l(AddLegend(gPad));
3069  Style(l);
3070  if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
3071  Float_t chi(fitStatus->GetBinContent(1));
3072  Float_t pen(fitStatus->GetBinContent(2));
3073  Int_t dof((int)fitStatus->GetBinContent(3));
3074  Float_t beta(fitStatus->GetBinContent(4));
3075  l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
3076  } else if (fitStatus) { // only available in SVD fit
3077  Int_t reg((int)fitStatus->GetBinContent(1));
3078  l->AddEntry((TObject*)0, Form("REG %i", reg), "");
3079  }
3080  canvasNominalSpectraOut->cd(2);
3081  TH1D* tempSyst((TH1D*)unfoldedSpectrum->Clone(Form("%s_syst", unfoldedSpectrum->GetName())));
3082  tempSyst->SetTitle(Form("[%s]", dirNameOut.Data()));
3083  Style(tempSyst, (EColor)(i+2));
3084  Style(gPad, "SPECTRUM");
3085  if(i==0) tempSyst->DrawCopy();
3086  else tempSyst->DrawCopy("same");
3087  }
3088  }
3089  if(canvasRatio && canvasV2) {
3090  canvasRatio->cd(j);
3091  if(i==0) {
3092  canvasNominalRatio->cd(j);
3093  if(nominal && nominalIn && nominalOut) {
3094  // if a nominal ratio is requested, delete the placeholder and update the nominal point
3095  delete nominal;
3096  delete nominalIn;
3097  delete nominalOut;
3098  nominalIn = (TH1D*)unfoldedSpectrumInForRatio->Clone("in plane jet yield");
3099  nominalOut = (TH1D*)unfoldedSpectrumOutForRatio->Clone("out of plane jet yield");
3100  nominal = (TH1D*)unfoldedSpectrumInForRatio->Clone("ratio in plane out of plane");
3101  nominal->Divide(nominal, unfoldedSpectrumOutForRatio); // standard root divide for uncorrelated histos
3102  }
3103  }
3104  TGraphErrors* ratioYield(GetRatio(unfoldedSpectrumInForRatio, unfoldedSpectrumOutForRatio, TString(Form("ratio [in=%s, out=%s]", dirNameIn.Data(), dirNameOut.Data()))));
3105  Double_t _tempx(0), _tempy(0);
3106  if(ratioYield) {
3107  Style(ratioYield);
3108  for(Int_t b(0); b < fBinsTrue->GetSize(); b++) {
3109  ratioYield->GetPoint(b, _tempx, _tempy);
3110  ratioProfile->Fill(_tempx, _tempy);
3111  }
3112  ratioProfile->GetYaxis()->SetRangeUser(-0., 2.);
3113  ratioProfile->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
3114  ratioYield->GetYaxis()->SetRangeUser(-0., 2.);
3115  ratioYield->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
3116  ratioYield->SetFillColor(kRed);
3117  ratioYield->Draw("ap");
3118  }
3119  canvasV2->cd(j);
3120  if(i==0) canvasNominalV2->cd(j);
3121  TGraphErrors* ratioV2(GetV2(unfoldedSpectrumInForRatio,unfoldedSpectrumOutForRatio, fEventPlaneRes, TString(Form("v_{2} [in=%s, out=%s]", dirNameIn.Data(), dirNameOut.Data()))));
3122  if(ratioV2) {
3123  Style(ratioV2);
3124  for(Int_t b(0); b < fBinsTrue->GetSize(); b++) {
3125  ratioV2->GetPoint(b, _tempx, _tempy);
3126  v2Profile->Fill(_tempx, _tempy);
3127 
3128  }
3129  v2Profile->GetYaxis()->SetRangeUser(-0., 2.);
3130  v2Profile->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
3131  ratioV2->GetYaxis()->SetRangeUser(-.25, .75);
3132  ratioV2->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
3133  ratioV2->SetFillColor(kRed);
3134  ratioV2->Draw("ap");
3135  }
3136  }
3137  delete unfoldedSpectrumInForRatio;
3138  delete unfoldedSpectrumOutForRatio;
3139  }
3140  // save the canvasses
3141  canvasProfiles->cd(1);
3142  Style(ratioProfile);
3143  ratioProfile->DrawCopy();
3144  canvasProfiles->cd(2);
3145  Style(v2Profile);
3146  v2Profile->DrawCopy();
3147  SavePadToPDF(canvasProfiles);
3148  canvasProfiles->Write();
3149  SavePadToPDF(canvasIn);
3150  canvasIn->Write();
3151  if(canvasOut) {
3152  SavePadToPDF(canvasOut);
3153  canvasOut->Write();
3154  }
3155  SavePadToPDF(canvasRatioMeasuredRefoldedIn);
3156  canvasRatioMeasuredRefoldedIn->Write();
3157  if(canvasRatioMeasuredRefoldedOut) {
3158  SavePadToPDF(canvasRatioMeasuredRefoldedOut);
3159  canvasRatioMeasuredRefoldedOut->Write();
3160  }
3161  SavePadToPDF(canvasSpectraIn);
3162  canvasSpectraIn->Write();
3163  if(canvasSpectraOut) {
3164  SavePadToPDF(canvasSpectraOut);
3165  canvasSpectraOut->Write();
3166  SavePadToPDF(canvasRatio);
3167  canvasRatio->Write();
3168  SavePadToPDF(canvasV2);
3169  canvasV2->Write();
3170  }
3171  SavePadToPDF(canvasMasterIn);
3172  canvasMasterIn->Write();
3173  if(canvasMasterOut) {
3174  SavePadToPDF(canvasMasterOut);
3175  canvasMasterOut->Write();
3176  }
3177  SavePadToPDF(canvasMISC);
3178  canvasMISC->Write();
3179  // save the nomial canvasses
3180  SavePadToPDF(canvasNominalIn);
3181  canvasNominalIn->Write();
3182  if(canvasNominalOut) {
3183  SavePadToPDF(canvasNominalOut);
3184  canvasNominalOut->Write();
3185  }
3186  SavePadToPDF(canvasNominalRatioMeasuredRefoldedIn);
3187  canvasNominalRatioMeasuredRefoldedIn->Write();
3188  if(canvasNominalRatioMeasuredRefoldedOut) {
3189  SavePadToPDF(canvasNominalRatioMeasuredRefoldedOut);
3190  canvasNominalRatioMeasuredRefoldedOut->Write();
3191  }
3192  canvasNominalSpectraIn->cd(2);
3193  Style(AddLegend(gPad));
3194  SavePadToPDF(canvasNominalSpectraIn);
3195  canvasNominalSpectraIn->Write();
3196  if(canvasNominalSpectraOut) {
3197  canvasNominalSpectraOut->cd(2);
3198  Style(AddLegend(gPad));
3199  SavePadToPDF(canvasNominalSpectraOut);
3200  canvasNominalSpectraOut->Write();
3201  SavePadToPDF(canvasNominalRatio);
3202  canvasNominalRatio->Write();
3203  SavePadToPDF(canvasNominalV2);
3204  canvasNominalV2->Write();
3205  }
3206  canvasNominalMasterIn->cd(1);
3207  Style(AddLegend(gPad));
3208  lineUp->DrawClone("same");
3209  lineLow->DrawClone("same");
3210  SavePadToPDF(canvasNominalMasterIn);
3211  canvasNominalMasterIn->Write();
3212  if(canvasNominalMasterOut) {
3213  canvasNominalMasterOut->cd(1);
3214  Style(AddLegend(gPad));
3215  lineUp->DrawClone("same");
3216  lineLow->DrawClone("same");
3217  SavePadToPDF(canvasNominalMasterOut);
3218  canvasNominalMasterOut->Write();
3219  }
3220  SavePadToPDF(canvasNominalMISC);
3221  canvasNominalMISC->Write();
3222 
3223  // save the relative errors
3224  for(Int_t b(0); b < fBinsTrue->GetSize()-1; b++) {
3225  // to arrive at a min and max from here, combine in up and out low
3226  if(!RMS) {
3227  relativeErrorInUp->SetBinContent(b+1, -1.*(relativeErrorInUp->GetBinContent(b+1)-1));
3228 // relativeErrorInUp->SetBinError(b+1, 0.);
3229  relativeErrorOutUp->SetBinContent(b+1, -1.*(relativeErrorOutUp->GetBinContent(b+1)-1));
3230 // relativeErrorOutUp->SetBinError(b+1, .0);
3231  relativeErrorInLow->SetBinContent(b+1, -1.*(relativeErrorInLow->GetBinContent(b+1)-1));
3232 // relativeErrorInLow->SetBinError(b+1, 0.);
3233  relativeErrorOutLow->SetBinContent(b+1, -1.*(relativeErrorOutLow->GetBinContent(b+1)-1));
3234 // relativeErrorOutLow->SetBinError(b+1, .0);
3235  } else if (RMS) {
3236  // these guys are already stored as percentages, so no need to remove the offset of 1
3237  // RMS is defined as sqrt(sum(squared))/N
3238  // min is defined as negative, max is defined as positive
3239  if(!fSymmRMS) {
3240  if(relativeErrorInUpN[b] < 1) relativeErrorInUpN[b] = 1;
3241  if(relativeErrorInLowN[b] < 1) relativeErrorInLowN[b] = 1;
3242  if(relativeErrorOutUpN[b] < 1) relativeErrorOutUpN[b] = 1;
3243  if(relativeErrorOutLowN[b] < 1) relativeErrorOutLowN[b] = 1;
3244  relativeErrorInUp->SetBinContent(b+1, TMath::Sqrt(relativeErrorInUp->GetBinContent(b+1)/relativeErrorInUpN[b]));
3245 // relativeErrorInUp->SetBinError(b+1, 0.);
3246  relativeErrorOutUp->SetBinContent(b+1, TMath::Sqrt(relativeErrorOutUp->GetBinContent(b+1)/relativeErrorOutUpN[b]));
3247 // relativeErrorOutUp->SetBinError(b+1, .0);
3248  relativeErrorInLow->SetBinContent(b+1, -1.*TMath::Sqrt(relativeErrorInLow->GetBinContent(b+1)/relativeErrorInLowN[b]));
3249 // relativeErrorInLow->SetBinError(b+1, 0.);
3250  relativeErrorOutLow->SetBinContent(b+1, -1.*TMath::Sqrt(relativeErrorOutLow->GetBinContent(b+1)/relativeErrorOutLowN[b]));
3251 // relativeErrorOutLow->SetBinError(b+1, .0);
3252  } else if (fSymmRMS) {
3253  if(relativeErrorInUpN[b] < 1) relativeErrorInUpN[b] = 1;
3254  if(relativeErrorOutUpN[b] < 1) relativeErrorOutUpN[b] = 1;
3255  relativeErrorInUp->SetBinContent(b+1, TMath::Sqrt(relativeErrorInUp->GetBinContent(b+1)/relativeErrorInUpN[b]));
3256  relativeErrorOutUp->SetBinContent(b+1, TMath::Sqrt(relativeErrorOutUp->GetBinContent(b+1)/relativeErrorOutUpN[b]));
3257  }
3258  }
3259  }
3260  relativeErrorInUp->SetYTitle("relative uncertainty");
3261  relativeErrorOutUp->SetYTitle("relative uncertainty");
3262  relativeErrorInLow->SetYTitle("relative uncertainty");
3263  relativeErrorOutLow->SetYTitle("relative uncertainty");
3264  relativeErrorInUp->GetYaxis()->SetRangeUser(-1.5, 3.);
3265  relativeErrorInLow->GetYaxis()->SetRangeUser(-1.5, 3.);
3266  relativeErrorOutUp->GetYaxis()->SetRangeUser(-1.5, 3.);
3267  relativeErrorOutLow->GetYaxis()->SetRangeUser(-1.5, 3.);
3268 
3269  canvasNominalMasterIn->cd(2);
3270  Style(gPad, "GRID");
3271  Style(relativeErrorInUp, kBlue, kBar);
3272  Style(relativeErrorInLow, kGreen, kBar);
3273  relativeErrorInUp->DrawCopy("b");
3274  relativeErrorInLow->DrawCopy("same b");
3275  Style(AddLegend(gPad));
3276  SavePadToPDF(canvasNominalMasterIn);
3277  canvasNominalMasterIn->Write();
3278  canvasNominalMasterOut->cd(2);
3279  Style(gPad, "GRID");
3280  Style(relativeErrorOutUp, kBlue, kBar);
3281  Style(relativeErrorOutLow, kGreen, kBar);
3282  relativeErrorOutUp->DrawCopy("b");
3283  relativeErrorOutLow->DrawCopy("same b");
3284  Style(AddLegend(gPad));
3285  SavePadToPDF(canvasNominalMasterOut);
3286  canvasNominalMasterOut->Write();
3287 }
3288 //_____________________________________________________________________________
3290  TArrayI* variationsIn, // variantions in plane
3291  TArrayI* variationsOut, // variantions out of plane
3292  TH1D*& relativeErrorInUp, // will store systematic error on v2
3293  TH1D*& relativeErrorInLow, // remains NULL
3294  TH1D*& relativeErrorOutUp, // remains NULL
3295  TH1D*& relativeErrorOutLow, // remains NULL
3296  TH1D*& relativeStatisticalErrorIn, // remains NULL
3297  TH1D*& relativeStatisticalErrorOut, // remains NULL
3298  TH1D*& nominal, // nominal v2
3299  TH1D*& nominalIn, // remains NULL
3300  TH1D*& nominalOut, // remains NULL
3301  Int_t columns, // trivial
3302  Float_t rangeLow, // trivial
3303  Float_t rangeUp, // trivial
3304  TFile* readMe, // trivial
3305  TString source, // trivial
3306  Bool_t RMS // NOT trivial
3307  ) const
3308 {
3309 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
3310  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
3311 #endif
3312  // 0) intermediate systematic check function. first make sure a placeholder is ready
3313  if(relativeErrorInUp) delete relativeErrorInUp;
3314  relativeErrorInUp = new TH1D(Form("absolute_systematic_uncertainty_%s", source.Data()), Form("absolute_systematic_uncertainty_%s", source.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
3315 
3316  // 1) then loop over the variations
3317  for(Int_t i(0); i < variationsIn->GetSize(); i++) {
3318  printf(" variation %i of %i \n", i, variationsIn->GetSize());
3319  // the frist variation will be stored as nominal, others are looped over
3320  Int_t iIn[] = {variationsIn->At(i), variationsIn->At(i)};
3321  Int_t iOut[] = {variationsOut->At(i), variationsOut->At(i)};
3322 
3323  // call the functions and set the relevant pointer references
3324  TH1D* dud(0x0);
3325  DoIntermediateSystematics( // i guess this is the point where i retreive the variation
3326  new TArrayI(2, iIn), // except for i is one, that's the nominal measurement
3327  new TArrayI(2, iOut),
3328  dud, dud, dud, dud, dud, dud, dud,
3329  nominalIn,
3330  nominalOut,
3331  1,
3332  fBinsTrue->At(0),
3333  fBinsTrue->At(fBinsTrue->GetSize()-1),
3334  readMe,
3335  Form("error_on_v2_variation_%i", i));
3336 
3337  printf(" nominal in %i binsX \n", nominalIn->GetNbinsX());
3338  printf(" nominal out %i binsX \n", nominalOut->GetNbinsX());
3339 
3340  // 2) get a histo with the v2
3341  TH1D* v2(GetV2Histo(nominalIn, nominalOut, fEventPlaneRes, "nominal v_{2}"));
3342 
3343  printf(" v2 in %i binsX \n", v2->GetNbinsX());
3344  // 3) bounce if nominal measurement ...
3345  if(i==0) {
3346  nominal = v2;
3347  } else { // 4) calculate the uncertainty. for now only RMS style, easier and the first check
3348  for(Int_t k(0); k < nominal->GetNbinsX(); k++) {
3349  // 5) store the sum of squares of difference (so orig + square of new point) differentially
3350  relativeErrorInUp->SetBinContent(k+1, relativeErrorInUp->GetBinContent(k+1) + TMath::Power(v2->GetBinContent(k+1)-nominal->GetBinContent(k+1), 2));
3351  printf(" nominal bin %i is %.4f \n", k+1, nominal->GetBinContent(k+1));
3352  printf(" variati bin %i is %.4f \n", k+1, v2->GetBinContent(k+1));
3353  printf(" sum of squared difference is %.4f \n", relativeErrorInUp->GetBinContent(k+1));
3354  }
3355  delete v2;
3356  }
3357  }
3358  // 6) looped over all the variations, now divide by N and take the square for the RMS
3359  // to make life fun, the function that will add all uncertainties uses bin ERRORS, not content,
3360  // so we'll set the error here and set the relative error as bin content
3361  for(Int_t k(0); k < nominal->GetNbinsX(); k++) {
3362  relativeErrorInUp->SetBinError(k+1, TMath::Sqrt(relativeErrorInUp->GetBinContent(k+1)/((double)variationsIn->GetSize())));
3363  printf(" total absolute error in bin %i is %.4f \n", k+1, relativeErrorInUp->GetBinError(k+1));
3364  relativeErrorInUp->SetBinContent(k+1, relativeErrorInUp->GetBinError(k+1)/nominal->GetBinContent(k+1));
3365  }
3366  if(fConstantUE) {
3367  Int_t ctr(0);
3368  Double_t av(0), avct(0);
3369  for(Int_t k(3); k < 8; k++) {
3370  av+=relativeErrorInUp->GetBinError(k+1);
3371  avct+=relativeErrorInUp->GetBinContent(k+1);
3372  ctr++;
3373  }
3374  av/=((double)ctr);
3375  avct/=((double)ctr);
3376  for(Int_t k(8); k < nominal->GetNbinsX(); k++) {
3377  relativeErrorInUp->SetBinError(k+1, av);
3378  relativeErrorInUp->SetBinContent(k+1, avct);
3379  }
3380  }
3381 }
3382 //_____________________________________________________________________________
3383 void AliJetFlowTools::PostProcess(TString def, Int_t columns, Float_t rangeLow, Float_t rangeUp, TString in, TString out) const
3384 {
3385 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
3386  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
3387 #endif
3388  // go through the output file and perform post processing routines
3389  // can either be performed in one go with the unfolding, or at a later stage
3390  if(fOutputFile && !fOutputFile->IsZombie()) fOutputFile->Close();
3391  TFile readMe(in.Data(), "READ"); // open file read-only
3392  if(readMe.IsZombie()) {
3393  printf(" > Fatal error, couldn't read %s for post processing ! < \n", in.Data());
3394  return;
3395  }
3396  printf("\n\n\n\t\t POSTPROCESSING \n > Recovered the following file structure : \n <");
3397  readMe.ls();
3398  TList* listOfKeys((TList*)readMe.GetListOfKeys());
3399  if(!listOfKeys) {
3400  printf(" > Fatal error, couldn't retrieve list of keys. Input file might have been corrupted ! < \n");
3401  return;
3402  }
3403  // prepare necessary canvasses
3404  TCanvas* canvasIn(new TCanvas("PearsonIn", "PearsonIn"));
3405  TCanvas* canvasOut(0x0);
3406  if(fDphiUnfolding) canvasOut = new TCanvas("PearsonOut", "PearsonOut");
3407  TCanvas* canvasRatioMeasuredRefoldedIn(new TCanvas("RefoldedIn", "RefoldedIn"));
3408  TCanvas* canvasRatioMeasuredRefoldedOut(0x0);
3409  if(fDphiUnfolding) canvasRatioMeasuredRefoldedOut = new TCanvas("RefoldedOut", "RefoldedOut");
3410  TCanvas* canvasSpectraIn(new TCanvas("SpectraIn", "SpectraIn"));
3411  TCanvas* canvasSpectraOut(0x0);
3412  if(fDphiUnfolding) canvasSpectraOut = new TCanvas("SpectraOut", "SpectraOut");
3413  TCanvas* canvasRatio(0x0);
3414  if(fDphiUnfolding) canvasRatio = new TCanvas("Ratio", "Ratio");
3415  TCanvas* canvasV2(0x0);
3416  if(fDphiUnfolding) canvasV2 = new TCanvas("V2", "V2");
3417  TCanvas* canvasMISC(new TCanvas("MISC", "MISC"));
3418  TCanvas* canvasMasterIn(new TCanvas("defaultIn", "defaultIn"));
3419  TCanvas* canvasMasterOut(0x0);
3420  if(fDphiUnfolding) canvasMasterOut = new TCanvas("defaultOut", "defaultOut");
3421  (fDphiUnfolding) ? canvasMISC->Divide(4, 2) : canvasMISC->Divide(4, 1);
3422  TDirectoryFile* defDir(0x0);
3423  TCanvas* canvasProfiles(new TCanvas("canvasProfiles", "canvasProfiles"));
3424  canvasProfiles->Divide(2);
3425  TProfile* ratioProfile(new TProfile("ratioProfile", "ratioProfile", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
3426  TProfile* v2Profile(new TProfile("v2Profile", "v2Profile", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
3427  // get an estimate of the number of outputs and find the default set
3428  Int_t cacheMe(0);
3429  for(Int_t i(0); i < listOfKeys->GetSize(); i++) {
3430  if(dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()))) {
3431  if(!strcmp(listOfKeys->At(i)->GetName(), def.Data())) defDir = dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()));
3432  cacheMe++;
3433  }
3434  }
3435  Int_t rows(TMath::Floor(cacheMe/(float)columns)+((cacheMe%columns)>0));
3436  canvasIn->Divide(columns, rows);
3437  if(canvasOut) canvasOut->Divide(columns, rows);
3438  canvasRatioMeasuredRefoldedIn->Divide(columns, rows);
3439  if(canvasRatioMeasuredRefoldedOut) canvasRatioMeasuredRefoldedOut->Divide(columns, rows);
3440  canvasSpectraIn->Divide(columns, rows);
3441  if(canvasSpectraOut) canvasSpectraOut->Divide(columns, rows);
3442  if(canvasRatio) canvasRatio->Divide(columns, rows);
3443  if(canvasV2) canvasV2->Divide(columns, rows);
3444 
3445  canvasMasterIn->Divide(columns, rows);
3446  if(canvasMasterOut) canvasMasterOut->Divide(columns, rows);
3447  // extract the default output
3448  TH1D* defaultUnfoldedJetSpectrumIn(0x0);
3449  TH1D* defaultUnfoldedJetSpectrumOut(0x0);
3450  if(defDir) {
3451  TDirectoryFile* defDirIn = (TDirectoryFile*)defDir->Get(Form("InPlane___%s", def.Data()));
3452  TDirectoryFile* defDirOut = (TDirectoryFile*)defDir->Get(Form("OutOfPlane___%s", def.Data()));
3453  if(defDirIn) defaultUnfoldedJetSpectrumIn = (TH1D*)defDirIn->Get(Form("UnfoldedSpectrum_in_%s", def.Data()));
3454  if(defDirOut) defaultUnfoldedJetSpectrumOut = (TH1D*)defDirOut->Get(Form("UnfoldedSpectrum_out_%s", def.Data()));
3455  printf(" > succesfully extracted default results < \n");
3456  }
3457 
3458  // loop through the directories, only plot the graphs if the deconvolution converged
3459  TDirectoryFile* tempDir(0x0);
3460  TDirectoryFile* tempIn(0x0);
3461  TDirectoryFile* tempOut(0x0);
3462  for(Int_t i(0), j(0); i < listOfKeys->GetSize(); i++) {
3463  // read the directory by its name
3464  tempDir = dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()));
3465  if(!tempDir) continue;
3466  TString dirName(tempDir->GetName());
3467  // try to read the in- and out of plane subdirs
3468  tempIn = (TDirectoryFile*)tempDir->Get(Form("InPlane___%s", dirName.Data()));
3469  tempOut = (TDirectoryFile*)tempDir->Get(Form("OutOfPlane___%s", dirName.Data()));
3470  j++;
3471  if(!tempIn) { // attempt to get MakeAU output
3472  TString stringArray[] = {"a", "b", "c", "d", "e", "f", "g", "h"};
3473  TCanvas* tempPearson(new TCanvas(Form("pearson_%s", dirName.Data()), Form("pearson_%s", dirName.Data())));
3474  tempPearson->Divide(4,2);
3475  TCanvas* tempRatio(new TCanvas(Form("ratio_%s", dirName.Data()), Form("ratio_%s", dirName.Data())));
3476  tempRatio->Divide(4,2);
3477  TCanvas* tempResult(new TCanvas(Form("result_%s", dirName.Data()), Form("result_%s", dirName.Data())));
3478  tempResult->Divide(4,2);
3479  for(Int_t q(0); q < 8; q++) {
3480  tempIn = (TDirectoryFile*)tempDir->Get(Form("%s___%s", stringArray[q].Data(), dirName.Data()));
3481  if(tempIn) {
3482  // to see if the unfolding converged try to extract the pearson coefficients
3483  TH2D* pIn((TH2D*)tempIn->Get(Form("PearsonCoefficients_in_%s", dirName.Data())));
3484  if(pIn) {
3485  printf(" - %s in plane converged \n", dirName.Data());
3486  tempPearson->cd(1+q);
3487  Style(gPad, "PEARSON");
3488  pIn->DrawCopy("colz");
3489  TGraphErrors* rIn((TGraphErrors*)tempIn->Get(Form("RatioRefoldedMeasured_%s", dirName.Data())));
3490  if(rIn) {
3491  Style(rIn);
3492  printf(" > found RatioRefoldedMeasured < \n");
3493  tempRatio->cd(q+1);
3494  rIn->SetFillColor(kRed);
3495  rIn->Draw("ap");
3496  }
3497  TH1D* dvector((TH1D*)tempIn->Get("dVector"));
3498  TH1D* avalue((TH1D*)tempIn->Get("SingularValuesOfAC"));
3499  TH2D* rm((TH2D*)tempIn->Get(Form("ResponseMatrixIn_%s", dirName.Data())));
3500  TH1D* eff((TH1D*)tempIn->Get(Form("KinematicEfficiencyIn_%s", dirName.Data())));
3501  if(dvector && avalue && rm && eff) {
3502  Style(dvector);
3503  Style(avalue);
3504  Style(rm);
3505  Style(eff);
3506  canvasMISC->cd(1);
3507  Style(gPad, "SPECTRUM");
3508  dvector->DrawCopy();
3509  canvasMISC->cd(2);
3510  Style(gPad, "SPECTRUM");
3511  avalue->DrawCopy();
3512  canvasMISC->cd(3);
3513  Style(gPad, "PEARSON");
3514  rm->DrawCopy("colz");
3515  canvasMISC->cd(4);
3516  Style(gPad, "GRID");
3517  eff->DrawCopy();
3518  } else if(rm && eff) {
3519  Style(rm);
3520  Style(eff);
3521  canvasMISC->cd(3);
3522  Style(gPad, "PEARSON");
3523  rm->DrawCopy("colz");
3524  canvasMISC->cd(4);
3525  Style(gPad, "GRID");
3526  eff->DrawCopy();
3527  }
3528  }
3529  TH1D* inputSpectrum((TH1D*)tempIn->Get(Form("InputSpectrum_in_%s", dirName.Data())));
3530  TH1D* unfoldedSpectrum((TH1D*)tempIn->Get(Form("UnfoldedSpectrum_in_%s", dirName.Data())));
3531  TH1D* refoldedSpectrum((TH1D*)tempIn->Get(Form("RefoldedSpectrum_in_%s", dirName.Data())));
3532  if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
3533  if(defaultUnfoldedJetSpectrumIn) {
3534  Style(defaultUnfoldedJetSpectrumIn, kBlue, kUnfoldedSpectrum);
3535  TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumIn->Clone(Form("defaultUnfoldedJetSpectrumIn_%s", dirName.Data())));
3536  temp->Divide(unfoldedSpectrum);
3537  temp->SetTitle(Form("ratio default unfolded / %s", dirName.Data()));
3538  temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
3539  temp->GetYaxis()->SetTitle(Form("%s / %s", def.Data(), dirName.Data()));
3540  canvasMasterIn->cd(j);
3541  temp->GetYaxis()->SetRangeUser(0., 2);
3542  temp->DrawCopy();
3543  }
3544  TH1F* fitStatus((TH1F*)tempIn->Get(Form("fitStatus_%s_in", dirName.Data())));
3545  tempResult->cd(q+1);
3546  Style(gPad);
3547  Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
3548  unfoldedSpectrum->DrawCopy();
3549  Style(inputSpectrum, kGreen, kMeasuredSpectrum);
3550  inputSpectrum->DrawCopy("same");
3551  Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
3552  refoldedSpectrum->DrawCopy("same");
3553  TLegend* l(AddLegend(gPad));
3554  Style(l);
3555  if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
3556  Float_t chi(fitStatus->GetBinContent(1));
3557  Float_t pen(fitStatus->GetBinContent(2));
3558  Int_t dof((int)fitStatus->GetBinContent(3));
3559  Float_t beta(fitStatus->GetBinContent(4));
3560  l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
3561  } else if (fitStatus) { // only available in SVD fit
3562  Int_t reg((int)fitStatus->GetBinContent(1));
3563  l->AddEntry((TObject*)0, Form("REG %i", reg), "");
3564  }
3565  }
3566  }
3567  }
3568  }
3569  if(tempIn) {
3570  // to see if the unfolding converged try to extract the pearson coefficients
3571  TH2D* pIn((TH2D*)tempIn->Get(Form("PearsonCoefficients_in_%s", dirName.Data())));
3572  if(pIn) {
3573  printf(" - %s in plane converged \n", dirName.Data());
3574  canvasIn->cd(j);
3575  Style(gPad, "PEARSON");
3576  pIn->DrawCopy("colz");
3577  TGraphErrors* rIn((TGraphErrors*)tempIn->Get(Form("RatioRefoldedMeasured_%s", dirName.Data())));
3578  if(rIn) {
3579  Style(rIn);
3580  printf(" > found RatioRefoldedMeasured < \n");
3581  canvasRatioMeasuredRefoldedIn->cd(j);
3582  rIn->SetFillColor(kRed);
3583  rIn->Draw("ap");
3584  }
3585  TH1D* dvector((TH1D*)tempIn->Get("dVector"));
3586  TH1D* avalue((TH1D*)tempIn->Get("SingularValuesOfAC"));
3587  TH2D* rm((TH2D*)tempIn->Get(Form("ResponseMatrixIn_%s", dirName.Data())));
3588  TH1D* eff((TH1D*)tempIn->Get(Form("KinematicEfficiencyIn_%s", dirName.Data())));
3589  if(dvector && avalue && rm && eff) {
3590  Style(dvector);
3591  Style(avalue);
3592  Style(rm);
3593  Style(eff);
3594  canvasMISC->cd(1);
3595  Style(gPad, "SPECTRUM");
3596  dvector->DrawCopy();
3597  canvasMISC->cd(2);
3598  Style(gPad, "SPECTRUM");
3599  avalue->DrawCopy();
3600  canvasMISC->cd(3);
3601  Style(gPad, "PEARSON");
3602  rm->DrawCopy("colz");
3603  canvasMISC->cd(4);
3604  Style(gPad, "GRID");
3605  eff->DrawCopy();
3606  } else if(rm && eff) {
3607  Style(rm);
3608  Style(eff);
3609  canvasMISC->cd(3);
3610  Style(gPad, "PEARSON");
3611  rm->DrawCopy("colz");
3612  canvasMISC->cd(4);
3613  Style(gPad, "GRID");
3614  eff->DrawCopy();
3615  }
3616  }
3617  TH1D* inputSpectrum((TH1D*)tempIn->Get(Form("InputSpectrum_in_%s", dirName.Data())));
3618  TH1D* unfoldedSpectrum((TH1D*)tempIn->Get(Form("UnfoldedSpectrum_in_%s", dirName.Data())));
3619  TH1D* refoldedSpectrum((TH1D*)tempIn->Get(Form("RefoldedSpectrum_in_%s", dirName.Data())));
3620  if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
3621  if(defaultUnfoldedJetSpectrumIn) {
3622  Style(defaultUnfoldedJetSpectrumIn, kBlue, kUnfoldedSpectrum);
3623  TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumIn->Clone(Form("defaultUnfoldedJetSpectrumIn_%s", dirName.Data())));
3624  temp->Divide(unfoldedSpectrum);
3625  temp->SetTitle(Form("ratio default unfolded / %s", dirName.Data()));
3626  temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
3627  temp->GetYaxis()->SetTitle(Form("%s / %s", def.Data(), dirName.Data()));
3628  canvasMasterIn->cd(j);
3629  temp->GetYaxis()->SetRangeUser(0., 2);
3630  temp->DrawCopy();
3631  }
3632  TH1F* fitStatus((TH1F*)tempIn->Get(Form("fitStatus_%s_in", dirName.Data())));
3633  canvasSpectraIn->cd(j);
3634  Style(gPad);
3635  Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
3636  unfoldedSpectrum->DrawCopy();
3637  Style(inputSpectrum, kGreen, kMeasuredSpectrum);
3638  inputSpectrum->DrawCopy("same");
3639  Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
3640  refoldedSpectrum->DrawCopy("same");
3641  TLegend* l(AddLegend(gPad));
3642  Style(l);
3643  if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
3644  Float_t chi(fitStatus->GetBinContent(1));
3645  Float_t pen(fitStatus->GetBinContent(2));
3646  Int_t dof((int)fitStatus->GetBinContent(3));
3647  Float_t beta(fitStatus->GetBinContent(4));
3648  l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
3649  } else if (fitStatus) { // only available in SVD fit
3650  Int_t reg((int)fitStatus->GetBinContent(1));
3651  l->AddEntry((TObject*)0, Form("REG %i", reg), "");
3652  }
3653  }
3654  }
3655  if(tempOut) {
3656  TH2D* pOut((TH2D*)tempOut->Get(Form("PearsonCoefficients_out_%s", dirName.Data())));
3657  if(pOut) {
3658  printf(" - %s out of plane converged \n", dirName.Data());
3659  canvasOut->cd(j);
3660  Style(gPad, "PEARSON");
3661  pOut->DrawCopy("colz");
3662  TGraphErrors* rOut((TGraphErrors*)tempOut->Get(Form("RatioRefoldedMeasured_%s", dirName.Data())));
3663  if(rOut) {
3664  Style(rOut);
3665  printf(" > found RatioRefoldedMeasured < \n");
3666  canvasRatioMeasuredRefoldedOut->cd(j);
3667  rOut->SetFillColor(kRed);
3668  rOut->Draw("ap");
3669  }
3670  TH1D* dvector((TH1D*)tempOut->Get("dVector"));
3671  TH1D* avalue((TH1D*)tempOut->Get("SingularValuesOfAC"));
3672  TH2D* rm((TH2D*)tempOut->Get(Form("ResponseMatrixOut_%s", dirName.Data())));
3673  TH1D* eff((TH1D*)tempOut->Get(Form("KinematicEfficiencyOut_%s", dirName.Data())));
3674  if(dvector && avalue && rm && eff) {
3675  Style(dvector);
3676  Style(avalue);
3677  Style(rm);
3678  Style(eff);
3679  canvasMISC->cd(5);
3680  Style(gPad, "SPECTRUM");
3681  dvector->DrawCopy();
3682  canvasMISC->cd(6);
3683  Style(gPad, "SPECTRUM");
3684  avalue->DrawCopy();
3685  canvasMISC->cd(7);
3686  Style(gPad, "PEARSON");
3687  rm->DrawCopy("colz");
3688  canvasMISC->cd(8);
3689  Style(gPad, "GRID");
3690  eff->DrawCopy();
3691  } else if(rm && eff) {
3692  Style(rm);
3693  Style(eff);
3694  canvasMISC->cd(7);
3695  Style(gPad, "PEARSON");
3696  rm->DrawCopy("colz");
3697  canvasMISC->cd(8);
3698  Style(gPad, "GRID");
3699  eff->DrawCopy();
3700  }
3701  }
3702  TH1D* inputSpectrum((TH1D*)tempOut->Get(Form("InputSpectrum_out_%s", dirName.Data())));
3703  TH1D* unfoldedSpectrum((TH1D*)tempOut->Get(Form("UnfoldedSpectrum_out_%s", dirName.Data())));
3704  TH1D* refoldedSpectrum((TH1D*)tempOut->Get(Form("RefoldedSpectrum_out_%s", dirName.Data())));
3705  if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
3706  if(defaultUnfoldedJetSpectrumOut) {
3707  Style(defaultUnfoldedJetSpectrumOut, kBlue, kUnfoldedSpectrum);
3708  TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumOut->Clone(Form("defaultUnfoldedJetSpectrumOut_%s", dirName.Data())));
3709  temp->Divide(unfoldedSpectrum);
3710  temp->SetTitle(Form("ratio default unfolded / %s", dirName.Data()));
3711  temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
3712  temp->GetYaxis()->SetTitle(Form("%s / %s", def.Data(), dirName.Data()));
3713  canvasMasterOut->cd(j);
3714  temp->GetYaxis()->SetRangeUser(0., 2.);
3715  temp->DrawCopy();
3716  }
3717  TH1F* fitStatus((TH1F*)tempOut->Get(Form("fitStatus_%s_out", dirName.Data())));
3718  canvasSpectraOut->cd(j);
3719  Style(gPad);
3720  Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
3721  unfoldedSpectrum->DrawCopy();
3722  Style(inputSpectrum, kGreen, kMeasuredSpectrum);
3723  inputSpectrum->DrawCopy("same");
3724  Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
3725  refoldedSpectrum->DrawCopy("same");
3726  TLegend* l(AddLegend(gPad));
3727  Style(l);
3728  if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
3729  Float_t chi(fitStatus->GetBinContent(1));
3730  Float_t pen(fitStatus->GetBinContent(2));
3731  Int_t dof((int)fitStatus->GetBinContent(3));
3732  Float_t beta(fitStatus->GetBinContent(4));
3733  l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
3734  } else if (fitStatus) { // only available in SVD fit
3735  Int_t reg((int)fitStatus->GetBinContent(1));
3736  l->AddEntry((TObject*)0, Form("REG %i", reg), "");
3737  }
3738  }
3739  }
3740  if(canvasRatio && canvasV2) {
3741  canvasRatio->cd(j);
3742  TGraphErrors* ratioYield((TGraphErrors*)tempDir->Get(Form("RatioInOutPlane_%s", dirName.Data())));
3743  Double_t _tempx(0), _tempy(0);
3744  if(ratioYield) {
3745  Style(ratioYield);
3746  for(Int_t b(0); b < fBinsTrue->GetSize(); b++) {
3747  ratioYield->GetPoint(b, _tempx, _tempy);
3748  ratioProfile->Fill(_tempx, _tempy);
3749  }
3750  ratioProfile->GetYaxis()->SetRangeUser(-0., 2.);
3751  ratioProfile->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
3752  ratioYield->GetYaxis()->SetRangeUser(-0., 2.);
3753  ratioYield->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
3754  ratioYield->SetFillColor(kRed);
3755  ratioYield->Draw("ap");
3756  }
3757  canvasV2->cd(j);
3758  TGraphErrors* ratioV2((TGraphErrors*)tempDir->Get(Form("v2_%s", dirName.Data())));
3759  if(ratioV2) {
3760  Style(ratioV2);
3761  for(Int_t b(0); b < fBinsTrue->GetSize(); b++) {
3762  ratioV2->GetPoint(b, _tempx, _tempy);
3763  v2Profile->Fill(_tempx, _tempy);
3764 
3765  }
3766  v2Profile->GetYaxis()->SetRangeUser(-0., 2.);
3767  v2Profile->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
3768  ratioV2->GetYaxis()->SetRangeUser(-.25, .75);
3769  ratioV2->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
3770  ratioV2->SetFillColor(kRed);
3771  ratioV2->Draw("ap");
3772  }
3773  }
3774  }
3775  TFile output(out.Data(), "RECREATE");
3776  canvasProfiles->cd(1);
3777  Style(ratioProfile);
3778  ratioProfile->DrawCopy();
3779  canvasProfiles->cd(2);
3780  Style(v2Profile);
3781  v2Profile->DrawCopy();
3782  SavePadToPDF(canvasProfiles);
3783  canvasProfiles->Write();
3784  SavePadToPDF(canvasIn);
3785  canvasIn->Write();
3786  if(canvasOut) {
3787  SavePadToPDF(canvasOut);
3788  canvasOut->Write();
3789  }
3790  SavePadToPDF(canvasRatioMeasuredRefoldedIn);
3791  canvasRatioMeasuredRefoldedIn->Write();
3792  if(canvasRatioMeasuredRefoldedOut) {
3793  SavePadToPDF(canvasRatioMeasuredRefoldedOut);
3794  canvasRatioMeasuredRefoldedOut->Write();
3795  }
3796  SavePadToPDF(canvasSpectraIn);
3797  canvasSpectraIn->Write();
3798  if(canvasSpectraOut) {
3799  SavePadToPDF(canvasSpectraOut);
3800  canvasSpectraOut->Write();
3801  SavePadToPDF(canvasRatio);
3802  canvasRatio->Write();
3803  SavePadToPDF(canvasV2);
3804  canvasV2->Write();
3805  }
3806  SavePadToPDF(canvasMasterIn);
3807  canvasMasterIn->Write();
3808  if(canvasMasterOut) {
3809  SavePadToPDF(canvasMasterOut);
3810  canvasMasterOut->Write();
3811  }
3812  SavePadToPDF(canvasMISC);
3813  canvasMISC->Write();
3814  output.Write();
3815  output.Close();
3816 }
3817 //_____________________________________________________________________________
3818 void AliJetFlowTools::BootstrapSpectra(TString def, TString in, TString out) const
3819 {
3820 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
3821  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
3822 #endif
3823  // function to interpret results of bootstrapping routine
3824  // TString def should hold the true emperical distribution
3825  if(fOutputFile && !fOutputFile->IsZombie()) fOutputFile->Close();
3826  TFile readMe(in.Data(), "READ"); // open file read-only
3827  if(readMe.IsZombie()) {
3828  printf(" > Fatal error, couldn't read %s for post processing ! < \n", in.Data());
3829  return;
3830  }
3831  printf("\n\n\n\t\t BootstrapSpectra \n > Recovered the following file structure : \n <");
3832  readMe.ls();
3833  TList* listOfKeys((TList*)readMe.GetListOfKeys());
3834  if(!listOfKeys) {
3835  printf(" > Fatal error, couldn't retrieve list of keys. Input file might have been corrupted ! < \n");
3836  return;
3837  }
3838  // get an estimate of the number of outputs and find the default set
3839  TDirectoryFile* defDir(0x0);
3840  for(Int_t i(0); i < listOfKeys->GetSize(); i++) {
3841  if(dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()))) {
3842  if(!strcmp(listOfKeys->At(i)->GetName(), def.Data())) defDir = dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()));
3843  }
3844  }
3845 
3846  // extract the default output this is the 'emperical' distribution
3847  // w.r.t. which the other distributions will be evaluated
3848  TH1D* defaultUnfoldedJetSpectrumIn(0x0);
3849  TH1D* defaultUnfoldedJetSpectrumOut(0x0);
3850  TH1D* defaultInputSpectrumIn(0x0);
3851  TH1D* defaultInputSpectrumOut(0x0);
3852  TGraphErrors* v2Emperical(0x0);
3853  if(defDir) {
3854  TDirectoryFile* defDirIn = (TDirectoryFile*)defDir->Get(Form("InPlane___%s", def.Data()));
3855  TDirectoryFile* defDirOut = (TDirectoryFile*)defDir->Get(Form("OutOfPlane___%s", def.Data()));
3856  if(defDirIn) {
3857  defaultUnfoldedJetSpectrumIn = (TH1D*)defDirIn->Get(Form("UnfoldedSpectrum_in_%s", def.Data()));
3858  defaultInputSpectrumIn = (TH1D*)defDirIn->Get(Form("InputSpectrum_in_%s", def.Data()));
3859  }
3860  if(defDirOut) {
3861  defaultUnfoldedJetSpectrumOut = (TH1D*)defDirOut->Get(Form("UnfoldedSpectrum_out_%s", def.Data()));
3862  defaultInputSpectrumOut = (TH1D*)defDirOut->Get(Form("InputSpectrum_out_%s", def.Data()));
3863  }
3864  }
3865  if((!defaultUnfoldedJetSpectrumIn && defaultUnfoldedJetSpectrumOut)) {
3866  printf(" BootstrapSpectra: couldn't extract default spectra, aborting! \n");
3867  return;
3868  }
3869  else v2Emperical = GetV2(defaultUnfoldedJetSpectrumIn, defaultUnfoldedJetSpectrumOut, fEventPlaneRes);
3870 
3871  // now that we know for sure that the input is in place, reserve the bookkeeping histograms
3872  TH1F* delta0[fBinsTrue->GetSize()-1];
3873  for(Int_t i(0); i < fBinsTrue->GetSize()-1; i++) {
3874  delta0[i] = new TH1F(Form("delta%i_%.2f-%.2f_gev", i, fBinsTrue->At(i), fBinsTrue->At(i+1)), Form("#Delta_{0, %i} p_{T} %.2f-%.2f GeV/c", i, fBinsTrue->At(i), fBinsTrue->At(i+1)), 30, -1., 1.);//.15, .15);
3875  delta0[i]->Sumw2();
3876  }
3877  // and a canvas for illustration purposes only
3878  TCanvas* spectraIn(new TCanvas("spectraIn", "spectraIn"));
3879  TCanvas* spectraOut(new TCanvas("spectraOut", "spectraOut"));
3880  // common reference (in this case the generated v2)
3881  TF1* commonReference = new TF1("v2_strong_bkg_comb", "(x<=3)*.07+(x>3&&x<5)*(.07-(x-3)*.035)+(x>30&&x<40)*(x-30)*.005+(x>40)*.05", 0, 200);
3882 
3883  // loop through the directories, only plot the graphs if the deconvolution converged
3884  TDirectoryFile* tempDir(0x0);
3885  TDirectoryFile* tempIn(0x0);
3886  TDirectoryFile* tempOut(0x0);
3887  TH1D* unfoldedSpectrumIn(0x0);
3888  TH1D* unfoldedSpectrumOut(0x0);
3889  TH1D* measuredSpectrumIn(0x0);
3890  TH1D* measuredSpectrumOut(0x0);
3891  for(Int_t i(0), j(0); i < listOfKeys->GetSize(); i++) {
3892  // read the directory by its name
3893  tempDir = dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()));
3894  if(!tempDir) continue;
3895  TString dirName(tempDir->GetName());
3896  // read only bootstrapped outputs
3897  if(!dirName.Contains("bootstrap")) continue;
3898  // try to read the in- and out of plane subdirs
3899  tempIn = (TDirectoryFile*)tempDir->Get(Form("InPlane___%s", dirName.Data()));
3900  tempOut = (TDirectoryFile*)tempDir->Get(Form("OutOfPlane___%s", dirName.Data()));
3901  j++;
3902  // extract the unfolded spectra only if both in- and out-of-plane converted (i.e. pearson coefficients were saved)
3903  if(tempIn) {
3904  if(!(TH2D*)tempIn->Get(Form("PearsonCoefficients_in_%s", dirName.Data()))) continue;
3905  unfoldedSpectrumIn = (TH1D*)tempIn->Get(Form("UnfoldedSpectrum_in_%s", dirName.Data()));
3906  measuredSpectrumIn = (TH1D*)tempIn->Get(Form("InputSpectrum_in_%s", dirName.Data()));
3907  spectraIn->cd();
3908  (j==1) ? measuredSpectrumIn->DrawCopy() : measuredSpectrumIn->DrawCopy("same");
3909  }
3910  if(tempOut) {
3911  if(!(TH2D*)tempOut->Get(Form("PearsonCoefficients_out_%s", dirName.Data()))) continue;
3912  unfoldedSpectrumOut = (TH1D*)tempOut->Get(Form("UnfoldedSpectrum_out_%s", dirName.Data()));
3913  measuredSpectrumOut = (TH1D*)tempOut->Get(Form("InputSpectrum_out_%s", dirName.Data()));
3914  spectraOut->cd();
3915  (j==1) ? measuredSpectrumOut->DrawCopy() : measuredSpectrumOut->DrawCopy("same");
3916  }
3917  // get v2 with statistical uncertainties from the extracted spectra
3918  TGraphErrors* v2Bootstrapped(GetV2(unfoldedSpectrumIn, unfoldedSpectrumOut, fEventPlaneRes));
3919  // and loop over all bins to fill the bookkeeping histograms
3920  Double_t yBoot(0), yEmp(0), xDud(0);
3921  // optional: common reference (in this case the sampled v2 value)
3922  for(Int_t k(0); k < fBinsTrue->GetSize()-1; k++) {
3923  // read values point by point (passed by reference)
3924  v2Bootstrapped->GetPoint(k, xDud, yBoot);
3925  v2Emperical->GetPoint(k, xDud, yEmp);
3926  if(commonReference) {
3927  if(!commonReference->Eval(xDud)<1e-10) {
3928  yEmp/=commonReference->Eval(xDud);
3929  yBoot/=commonReference->Eval(xDud);
3930  } else { // if reference equals zero, take emperical distribution as reference
3931  yEmp/=yEmp; // 1
3932  yBoot/=yEmp;
3933  }
3934  }
3935  cout << " yEmp " << yEmp << " yBoot " << yBoot << endl;
3936  // save relative difference per pt bin
3937  if(TMath::Abs(yBoot)>1e-10) delta0[k]->Fill(yEmp - yBoot);
3938  }
3939  }
3940  // extracting final results now, as first estimate just a gaus fit to the distributions
3941  // (should be changed perhaps to proper rms eventually)
3942  // attach relevant data to current buffer in the same loop
3943  TFile output(out.Data(), "RECREATE");
3944  defaultInputSpectrumIn->SetLineColor(kRed);
3945  spectraIn->cd();
3946  defaultInputSpectrumIn->DrawCopy("same");
3947  defaultInputSpectrumOut->SetLineColor(kRed);
3948  spectraOut->cd();
3949  defaultInputSpectrumOut->DrawCopy("same");
3950  spectraIn->Write();
3951  spectraOut->Write();
3952 
3953  TH1F* delta0spread(new TH1F("delta0spread", "#sigma(#Delta_{0})", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
3954  TH1F* unfoldingError(new TH1F("unfoldingError", "error from unfolding algorithm", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
3955  TF1* gaus(new TF1("gaus", "gaus"/*[0]*exp(-0.5*((x-[1])/[2])**2)"*/, -1., 1.));
3956  Double_t xDud(0), yDud(0);
3957  for(Int_t i(0); i < fBinsTrue->GetSize()-1; i++) {
3958  delta0[i]->Fit(gaus);
3959  delta0[i]->GetYaxis()->SetTitle("counts");
3960  delta0[i]->GetXaxis()->SetTitle("(v_{2, jet}^{measured} - v_{2, jet}^{generated}) / input v_{2}");
3961  delta0spread->SetBinContent(i+1, gaus->GetParameter(1)); // mean of gaus
3962  delta0spread->SetBinError(i+1, gaus->GetParameter(2)); // sigma of gaus
3963  cout << " mean " << gaus->GetParameter(1) << endl;
3964  cout << " sigm " << gaus->GetParameter(2) << endl;
3965  delta0[i]->Write();
3966  v2Emperical->GetPoint(i, xDud, yDud);
3967  unfoldingError->SetBinContent(i+1, 1e-10/*gaus->GetParameter(1)*/);
3968  if(commonReference && !commonReference->Eval(xDud)<1e-10) unfoldingError->SetBinError(i+1, v2Emperical->GetErrorY(i)/(commonReference->Eval(xDud)));
3969  else if(yDud>10e-10) unfoldingError->SetBinError(i+1, v2Emperical->GetErrorY(i)/yDud);
3970  else unfoldingError->SetBinError(i+1, 0.);
3971  }
3972  delta0spread->GetXaxis()->SetTitle("p_{T}^{jet} (GeV/c)");
3973  delta0spread->GetYaxis()->SetTitle("(mean v_{2, jet}^{measured} - v_{2, jet}^{generated}) / input v_{2}");
3974  delta0spread->Write();
3975  unfoldingError->GetXaxis()->SetTitle("p_{T}^{jet} (GeV/c)");
3976  unfoldingError->GetYaxis()->SetTitle("(mean v_{2, jet}^{measured} - v_{2, jet}^{generated}) / input v_{2}");
3977  unfoldingError->Write();
3978  // write the buffer and close the file
3979  output.Write();
3980  output.Close();
3981 }
3982 //_____________________________________________________________________________
3984  TH2D* detectorResponse, // detector response matrix
3985  TH1D* jetPtIn, // in plane jet spectrum
3986  TH1D* jetPtOut, // out of plane jet spectrum
3987  TH1D* dptIn, // in plane delta pt distribution
3988  TH1D* dptOut, // out of plane delta pt distribution
3989  Int_t eventCount) {
3990 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
3991  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
3992 #endif
3993  // set input histograms manually
3994  fDetectorResponse = detectorResponse;
3995  fSpectrumIn = jetPtIn;
3996  fSpectrumOut = jetPtOut;
3997  fDptInDist = dptIn;
3998  fDptOutDist = dptOut;
3999  // check if all data is provided
4000  if(!fDetectorResponse) {
4001  printf(" fDetectorResponse not found \n ");
4002  return kFALSE;
4003  }
4004  // check if the pt bin for true and rec have been set
4005  if(!fBinsTrue || !fBinsRec) {
4006  printf(" No true or rec bins set, please set binning ! \n");
4007  return kFALSE;
4008  }
4009  if(!fRMSSpectrumIn) { // initialie the profiles which will hold the RMS values. if binning changes in between unfolding
4010  // procedures, these profiles will be nonsensical, user is responsible
4011  fRMSSpectrumIn = new TProfile("fRMSSpectrumIn", "fRMSSpectrumIn", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
4012  fRMSSpectrumOut = new TProfile("fRMSSpectrumOut", "fRMSSpectrumOut", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
4013  fRMSRatio = new TProfile("fRMSRatio", "fRMSRatio", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
4014  }
4015  // normalize spectra to event count if requested
4016  if(fNormalizeSpectra) {
4017  fEventCount = eventCount;
4018  if(fEventCount > 0) {
4019  fSpectrumIn->Sumw2(); // necessary for correct error propagation of scale
4020  fSpectrumOut->Sumw2();
4021  fSpectrumIn->Scale(1./((double)fEventCount));
4022  fSpectrumOut->Scale(1./((double)fEventCount));
4023  }
4024  }
4025  if(!fNormalizeSpectra && fEventCount > 0) {
4026  fSpectrumIn->Sumw2(); // necessary for correct error propagation of scale
4027  fSpectrumOut->Sumw2();
4028  fSpectrumIn->Scale(1./((double)fEventCount));
4029  fSpectrumOut->Scale(1./((double)fEventCount));
4030  }
4032  fDptIn->SetNameTitle(Form("dpt_response_INPLANE_%i", fCentralityArray->At(0)), Form("dpt_response_INPLANE_%i", fCentralityArray->At(0)));
4033  fDptIn->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
4034  fDptIn->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
4036  fDptOut->SetNameTitle(Form("dpt_response_OUTOFPLANE_%i", fCentralityArray->At(0)), Form("dpt_response_OUTOFPLANE_%i", fCentralityArray->At(0)));
4037  fDptOut->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
4038  fDptOut->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
4039 
4040 
4041  // set the flag to let other functions to read data from input file
4042  fRawInputProvided = kTRUE;
4043  return fRawInputProvided;
4044 }
4045 //_____________________________________________________________________________
4046 TGraphErrors* AliJetFlowTools::GetRatio(TH1 *h1, TH1* h2, TString name, Bool_t appendFit, Int_t xmax)
4047 {
4048 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4049  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4050 #endif
4051  // return ratio of h1 / h2
4052  // histograms can have different binning. errors are propagated as uncorrelated
4053  if(!(h1 && h2) ) {
4054  printf(" GetRatio called with NULL argument(s) \n ");
4055  return 0x0;
4056  }
4057  Int_t j(0);
4058  TGraphErrors *gr = new TGraphErrors();
4059  gr->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
4060  Double_t binCent(0.), ratio(0.), error2(0.), binWidth(0.);
4061  TH1* dud((TH1*)h1->Clone("dud"));
4062  dud->Sumw2();
4063  h1->Sumw2();
4064  h2->Sumw2();
4065  if(!dud->Divide(h1, h2)) {
4066  printf(" > ROOT failed to divide two histogams, dividing manually \n < ");
4067  for(Int_t i(1); i <= h1->GetNbinsX(); i++) {
4068  binCent = h1->GetXaxis()->GetBinCenter(i);
4069  if(xmax > 0. && binCent > xmax) continue;
4070  j = h2->FindBin(binCent);
4071  binWidth = h1->GetXaxis()->GetBinWidth(i);
4072  if(h2->GetBinContent(j) > 0.) {
4073  ratio = h1->GetBinContent(i)/h2->GetBinContent(j);
4074  Double_t A = h1->GetBinError(i)/h1->GetBinContent(i);
4075  Double_t B = h2->GetBinError(i)/h2->GetBinContent(i);
4076  error2 = ratio*ratio*A*A+ratio*ratio*B*B;
4077  if(error2 > 0 ) error2 = TMath::Sqrt(error2);
4078  gr->SetPoint(i-1, binCent, ratio);
4079  gr->SetPointError(i-1, 0.5*binWidth, error2);
4080  }
4081  }
4082  } else {
4083  printf( " > using ROOT to divide two histograms < \n");
4084  for(Int_t i(1); i <= h1->GetNbinsX(); i++) {
4085  binCent = dud->GetXaxis()->GetBinCenter(i);
4086  if(xmax > 0. && binCent > xmax) continue;
4087  binWidth = dud->GetXaxis()->GetBinWidth(i);
4088  gr->SetPoint(i-1,binCent,dud->GetBinContent(i));
4089  gr->SetPointError(i-1, 0.5*binWidth,dud->GetBinError(i));
4090  }
4091  }
4092 
4093  if(appendFit) {
4094  TF1* fit(new TF1("lin", "pol0", 10, 100));
4095  gr->Fit(fit);
4096  }
4097  if(strcmp(name, "")) gr->SetNameTitle(name.Data(), name.Data());
4098  if(dud) delete dud;
4099  return gr;
4100 }
4101 //_____________________________________________________________________________
4102 TGraphErrors* AliJetFlowTools::GetV2(TH1 *h1, TH1* h2, Double_t r, TString name)
4103 {
4104 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4105  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4106 #endif
4107  // get v2 from difference of in plane, out of plane yield
4108  // h1 must hold the in-plane yield, h2 holds the out of plane yield
4109  // r is the event plane resolution for the chosen centrality
4110  if(!(h1 && h2) ) {
4111  printf(" GetV2 called with NULL argument(s) \n ");
4112  return 0x0;
4113  }
4114  TGraphErrors *gr = new TGraphErrors();
4115  gr->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
4116  Float_t binCent(0.), ratio(0.), error2(0.), binWidth(0.);
4117  Double_t pre(TMath::Pi()/(4.*r)), in(0.), out(0.), ein(0.), eout(0.);
4118 
4119  for(Int_t i(1); i <= h1->GetNbinsX(); i++) {
4120  binCent = h1->GetXaxis()->GetBinCenter(i);
4121  binWidth = h1->GetXaxis()->GetBinWidth(i);
4122  if(h2->GetBinContent(i) > 0.) {
4123  in = h1->GetBinContent(i);
4124  ein = h1->GetBinError(i);
4125  out = h2->GetBinContent(i);
4126  eout = h2->GetBinError(i);
4127  ratio = pre*((in-out)/(in+out));
4128  error2 = (4.*out*out/(TMath::Power(in+out, 4)))*ein*ein+(4.*in*in/(TMath::Power(in+out, 4)))*eout*eout;
4129  error2 = error2*pre*pre;
4130  if(error2 > 0) error2 = TMath::Sqrt(error2);
4131  gr->SetPoint(i-1,binCent,ratio);
4132  gr->SetPointError(i-1,0.5*binWidth,error2);
4133  }
4134  }
4135  if(strcmp(name, "")) gr->SetNameTitle(name.Data(), name.Data());
4136  return gr;
4137 }
4138 //_____________________________________________________________________________
4139 TH1D* AliJetFlowTools::GetV2Histo(TH1 *h1, TH1* h2, Double_t r, TString name)
4140 {
4141 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4142  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4143 #endif
4144  // get v2 from difference of in plane, out of plane yield
4145  // h1 must hold the in-plane yield, h2 holds the out of plane yield
4146  // r is the event plane resolution for the chosen centrality
4147  if(!(h1 && h2) ) {
4148  printf(" GetV2 called with NULL argument(s) \n ");
4149  return 0x0;
4150  }
4151  TH1D* gr((TH1D*)h1->Clone(name.Data()));
4152  gr->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
4153  Float_t ratio(0.), error2(0.);
4154  Double_t pre(TMath::Pi()/(4.*r)), in(0.), out(0.), ein(0.), eout(0.);
4155 
4156  for(Int_t i(1); i <= h1->GetNbinsX(); i++) {
4157  if(h2->GetBinContent(i) > 0.) {
4158  in = h1->GetBinContent(i);
4159  ein = h1->GetBinError(i);
4160  out = h2->GetBinContent(i);
4161  eout = h2->GetBinError(i);
4162  ratio = pre*((in-out)/(in+out));
4163  error2 = (4.*out*out/(TMath::Power(in+out, 4)))*ein*ein+(4.*in*in/(TMath::Power(in+out, 4)))*eout*eout;
4164  error2 = error2*pre*pre;
4165  if(error2 > 0) error2 = TMath::Sqrt(error2);
4166  gr->SetBinContent(i,ratio);
4167  gr->SetBinError(i,error2);
4168  }
4169  }
4170  if(strcmp(name, "")) gr->SetNameTitle(name.Data(), name.Data());
4171  return gr;
4172 }
4173 //_____________________________________________________________________________
4175 {
4176 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4177  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4178 #endif
4179  // convert a tgrapherrors to a histogram
4180  if(!g) {
4181  printf(" > ConvertGraphToHistogram recevied a NULL pointer > \n");
4182  return 0x0;
4183  }
4184  // first get the frame which we'll use to build the histogram
4185  TH1F* hist(g->GetHistogram());
4186  Double_t xref(0), yref(0), yerr(0);
4187  // then copy the points and errors (remember graph starts at bin 0 and hist at 1)
4188  for(Int_t i(0); i < hist->GetNbinsX(); i++) {
4189  g->GetPoint(i, xref, yref);
4190  yerr = g->GetErrorY(i);
4191  hist->SetBinContent(i+1, yref);
4192  hist->SetBinError(i+1, yerr);
4193  }
4194  return hist;
4195 }
4196 //_____________________________________________________________________________
4197 TGraphAsymmErrors* AliJetFlowTools::AddHistoErrorsToGraphErrors(TGraphAsymmErrors* g, TH1D* h)
4198 {
4199 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4200  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4201 #endif
4202  // add the errors of a tgra histogram, assuming oncorrelated uncertainties
4203  // the points on the graph are returned !
4204  if(!(g&&h)) {
4205  printf(" > ConvertGraphToHistogram recevied a NULL pointer > \n");
4206  return 0x0;
4207  }
4208 
4209  printf("\n\n\n adding histo error to graph error \n\n\n\n");
4210 
4211 
4212  Double_t yerrL(0), yerrH(0), herr(0);
4213  // quadratic sum of the errors, assyming here symmetric ones
4214  for(Int_t i(0); i < h->GetNbinsX(); i++) {
4215  yerrH = g->GetErrorY(i);//high(i);
4216  yerrL = g->GetErrorY(i);//low(i);
4217  herr = h->GetBinError(i+1);
4218  cout << " graph error H " << yerrH << "\t histo error " << herr << endl;
4219  cout << " graph error L " << yerrL << "\t histo error " << herr << endl;
4220  yerrH = TMath::Sqrt(yerrH*yerrH+herr*herr);
4221  yerrL = TMath::Sqrt(yerrL*yerrL+herr*herr);
4222  g->SetPointError(i, g->GetErrorX(i), g->GetErrorX(i), yerrL, yerrH);
4223  }
4224  return g;
4225 }
4226 //_____________________________________________________________________________
4227 Double_t AliJetFlowTools::GetRMSOfTH1(TH1* h, Double_t a, Double_t b)
4228 {
4229 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4230  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4231 #endif
4232  // get rms between a and b for x-axis of histo
4233  if(!h || b < a ) return 0.;
4234 
4235  // a is a lower edge and b an upper edge
4236  Int_t binA(h->GetXaxis()->FindBin(a+.1));
4237  Int_t binB(h->GetXaxis()->FindBin(b+.1)); // on purpose
4238  Double_t RMS(0), mean(0), c(0);
4239 
4240  for(Int_t i(binA); i < binB; i++) {
4241  c++;
4242  mean += h->GetBinContent(i);
4243  }
4244  if( c > 0. ) {
4245  mean /= c;
4246  for(Int_t i(binA); i < binB; i++) RMS += (mean-h->GetBinContent(i))*(mean-h->GetBinContent(i));
4247  return TMath::Sqrt(RMS/c);
4248  }
4249  return 0.;
4250 }
4251 //_____________________________________________________________________________
4252 TF1* AliJetFlowTools::GetErrorFromFit(TH1* h1, TH1* h2, Double_t a, Double_t b,
4253  Float_t pivot, Bool_t subdueError, TString str, Bool_t setContent)
4254 {
4255 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4256  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4257 #endif
4258  // return an error from a fit
4259  TF1* lin = new TF1("lin", Form("(x<%i)*(pol1)+(x>%i)*[2]", (int)pivot, (int)pivot), a, b);
4260  // clone the input
4261  TF1* fit_pol0 = new TF1("fit_pol0", "pol0", pivot, b);
4262  TF1* fit_pol1 = new TF1("fit_pol1", "pol1", a, pivot);
4263 
4264  TH1* h((TH1*)h1->Clone(str.Data()));
4265  // reset the guy and fill it with the maxima
4266  h->Reset();
4267  Double_t _a(0), _b(0);
4268  for(Int_t i(1); i < h->GetNbinsX() + 1; i++) {
4269  _a = TMath::Abs(h1->GetBinContent(i));
4270  _b = TMath::Abs(h2->GetBinContent(i));
4271  if(_a > _b) {
4272  h->SetBinContent(i, _a);
4273  h->SetBinError(i, h1->GetBinError(i));
4274  } else {
4275  h->SetBinContent(i, _b);
4276  h->SetBinError(i, h2->GetBinError(i));
4277  }
4278  }
4279 
4280 
4281 
4282  // fit to full error. root doesn't like fitting a step-function, so fit these
4283  // two components separately ...
4284  h->Fit(fit_pol0, "", "", pivot, b);
4285  lin->SetParameter(2, (subdueError) ? 0. : fit_pol0->GetParameter(0));
4286 
4287  h->Fit(fit_pol1, "", "", a, pivot);
4288 
4289  //check if it makes sense
4290  if(fit_pol1->GetParameter(1) > 0) {
4291  fit_pol1 = new TF1("fit_pol2", "pol0", a, pivot);
4292  h->Fit(fit_pol1, "", "", a, pivot);
4293  lin->SetParameter(0, fit_pol1->GetParameter(0));
4294  lin->SetParameter(1, 0);
4295  } else {
4296  lin->SetParameter(0, fit_pol1->GetParameter(0));
4297  lin->SetParameter(1, fit_pol1->GetParameter(1));
4298  }
4299 
4300 
4301  // .. and then add them together
4302  h->GetListOfFunctions()->Add(lin);
4303 
4304  if(setContent) {
4305  // update the histos with the fit result
4306  for(Int_t i(1); i < h->GetNbinsX() + 1; i++) {
4307  // calculate the integral in a given bin
4308  Double_t dud(lin->Integral(h->GetXaxis()->GetBinLowEdge(i),h->GetXaxis()->GetBinUpEdge(i))/h->GetXaxis()->GetBinWidth(i));
4309  // if it's larger than 0, assign an 'up' error
4310  h1->SetBinContent(i, 0);
4311  h2->SetBinContent(i, 0);
4312  h1->SetBinError(i, 0);
4313  h2->SetBinError(i, 0);
4314  // dont' show errors outside of range of interest
4315  if(a > h->GetXaxis()->GetBinLowEdge(i) || b < h->GetXaxis()->GetBinUpEdge(i)) continue;
4316  // assign them correctly to up or low
4317  if(dud > 0) {
4318  h1->SetBinContent(i, dud);
4319  } else {
4320  h2->SetBinContent(i, dud);
4321  }
4322  }
4323  h->Write();
4324  }
4325  return lin;
4326 }
4327 //_____________________________________________________________________________
4329  TH1* h1, TH1* h2, Double_t r, TString name,
4330  TH1* relativeErrorInUp,
4331  TH1* relativeErrorInLow,
4332  TH1* relativeErrorOutUp,
4333  TH1* relativeErrorOutLow,
4334  Float_t rho) const
4335 {
4336 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4337  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4338 #endif
4339  // get v2 with asymmetric systematic error
4340  // note that this is ONLY the systematic error, no statistical error!
4341  // rho is the pearson correlation coefficient
4342  TGraphErrors* tempV2(GetV2(h1, h2, r, name));
4343  Double_t* ax = new Double_t[fBinsTrue->GetSize()-1];
4344  Double_t* ay = new Double_t[fBinsTrue->GetSize()-1];
4345  Double_t* axh = new Double_t[fBinsTrue->GetSize()-1];
4346  Double_t* axl = new Double_t[fBinsTrue->GetSize()-1];
4347  Double_t* ayh = new Double_t[fBinsTrue->GetSize()-1];
4348  Double_t* ayl = new Double_t[fBinsTrue->GetSize()-1];
4349  Double_t in(0.), out(0.), einUp(0.), einLow(0.), eoutUp(0.), eoutLow(0.), error2Up(0.), error2Low(0.);
4350  // loop through the bins and do error propagation
4351  for(Int_t i(0); i < fBinsTrue->GetSize()-1; i++) {
4352  // extract the absolute errors
4353  in = h1->GetBinContent(i+1);
4354  einUp = TMath::Abs(in*relativeErrorInUp->GetBinContent(i+1));
4355  einLow = TMath::Abs(in*relativeErrorInLow->GetBinContent(1+i));
4356  out = h2->GetBinContent(i+1);
4357  eoutUp = TMath::Abs(out*relativeErrorOutUp->GetBinContent(1+i));
4358  eoutLow = TMath::Abs(out*relativeErrorOutLow->GetBinContent(1+i));
4359  // get the error squared
4360  if(rho <= 0) {
4361  error2Up = TMath::Power(((r*4.)/(TMath::Pi())),-2.)*((4.*out*out/(TMath::Power(in+out, 4)))*einUp*einUp+(4.*in*in/(TMath::Power(in+out, 4)))*eoutLow*eoutLow);
4362  error2Low =TMath::Power(((r*4.)/(TMath::Pi())),-2.)*((4.*out*out/(TMath::Power(in+out, 4)))*einLow*einLow+(4.*in*in/(TMath::Power(in+out, 4)))*eoutUp*eoutUp);
4363  } else {
4364  error2Up = TMath::Power(((r*4.)/(TMath::Pi())),-2.)*((4.*out*out/(TMath::Power(in+out, 4)))*einUp*einUp+(4.*in*in/(TMath::Power(in+out, 4)))*eoutUp*eoutUp-((8.*out*in)/(TMath::Power(in+out, 4)))*rho*einUp*eoutUp);
4365  error2Low =TMath::Power(((r*4.)/(TMath::Pi())),-2.)*((4.*out*out/(TMath::Power(in+out, 4)))*einLow*einLow+(4.*in*in/(TMath::Power(in+out, 4)))*eoutLow*eoutLow-((8.*out*in)/(TMath::Power(in+out, 4)))*rho*einLow*eoutLow);
4366  }
4367  if(error2Up > 0) error2Up = TMath::Sqrt(error2Up);
4368  if(error2Low > 0) error2Low = TMath::Sqrt(error2Low);
4369  // set the errors
4370  ayh[i] = error2Up;
4371  ayl[i] = error2Low;
4372  // get the bin width (which is the 'error' on x)
4373  Double_t binWidth(h1->GetBinWidth(i+1));
4374  axl[i] = binWidth/2.;
4375  axh[i] = binWidth/2.;
4376  // now get the coordinate for the poin
4377  tempV2->GetPoint(i, ax[i], ay[i]);
4378  if(rho<=0) {
4379  cout << "[print] pt " << ax[i] << " errorLow" << gReductionFactor*ayl[i] << " errorUp " << gReductionFactor*ayh[i] << endl;
4380  cout << "[print] %" << ax[i] << " low " << (gReductionFactor*ayl[i])/ay[i] << " up " << (gReductionFactor*ayh[i])/ay[i] << endl;
4381  } else {
4382  cout << "[print] pt " << ax[i] << " errorLow" << ayl[i]*gReductionFactorCorr << " errorUp " << ayh[i]*gReductionFactorCorr << endl;
4383  cout << "[print] %" << ax[i] << " low " << (gReductionFactorCorr*ayl[i])/ay[i] << " up " << (gReductionFactorCorr*ayh[i])/ay[i] << endl;
4384  }
4385  }
4386  // save the nominal ratio
4387  TGraphAsymmErrors* nominalError(new TGraphAsymmErrors(fBinsTrue->GetSize()-1, ax, ay, axl, axh, ayl, ayh));
4388  nominalError->SetName("v_{2} with shape uncertainty");
4389  // do some memory management
4390  delete tempV2;
4391  delete[] ax;
4392  delete[] ay;
4393  delete[] axh;
4394  delete[] axl;
4395  delete[] ayh;
4396  delete[] ayl;
4397 
4398  return nominalError;
4399 }
4400 //_____________________________________________________________________________
4401 void AliJetFlowTools::WriteObject(TObject* object, TString suffix, Bool_t kill) {
4402 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4403  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4404 #endif
4405  // write object, if a unique identifier is given the object is cloned
4406  // and the clone is saved. setting kill to true will delete the original obect from the heap
4407  if(!object) {
4408  printf(" > WriteObject:: called with NULL arguments \n ");
4409  return;
4410  } else if(!strcmp("", suffix.Data())) object->Write();
4411  else {
4412  TObject* newObject(object->Clone(Form("%s_%s", object->GetName(), suffix.Data())));
4413  newObject->Write();
4414  }
4415  if(kill) delete object;
4416 }
4417 //_____________________________________________________________________________
4418 TH2D* AliJetFlowTools::ConstructDPtResponseFromTH1D(TH1D* dpt, Bool_t AvoidRoundingError) {
4419 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4420  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4421 #endif
4422  // construt a delta pt response matrix from supplied dpt distribution
4423  // binning is fine, set fBinsTrue and fBinsRec and call 'RebinTH2D' to
4424  // do a weighted rebinning to a (coarser) dpt distribution
4425  // be careful with the binning of the dpt response: it should be equal to that
4426  // of the response matrix, otherwise dpt and response matrices cannot be multiplied
4427  //
4428  // the response matrix will be square and have the same binning
4429  // (min, max and granularity) of the input histogram
4430  Int_t bins(dpt->GetXaxis()->GetNbins()); // number of bins, will also be no of rows, columns
4431  Double_t _bins[bins+1]; // prepare array with bin borders
4432  for(Int_t i(0); i < bins; i++) _bins[i] = dpt->GetBinLowEdge(i+1);
4433  _bins[bins] = dpt->GetBinLowEdge(bins)+dpt->GetBinWidth(bins+1); // get upper edge
4434  TH2D* res(new TH2D(Form("Response_from_%s", dpt->GetName()), Form("Response_from_%s", dpt->GetName()), bins, _bins, bins, _bins));
4435  for(Int_t j(0); j < bins+1; j++) { // loop on pt true slices j
4436  Bool_t skip = kFALSE;
4437  for(Int_t k(0); k < bins+1; k++) { // loop on pt gen slices k
4438  (skip) ? res->SetBinContent(j, k, 0.) : res->SetBinContent(j, k, dpt->GetBinContent(dpt->GetXaxis()->FindBin(k-j)));
4439  if(AvoidRoundingError && k > j && TMath::AreEqualAbs(dpt->GetBinContent(dpt->GetBinContent(k-j)), 0, 1e-8)) skip = kTRUE;
4440  }
4441  }
4442  return res;
4443 }
4444 //_____________________________________________________________________________
4445 TH2D* AliJetFlowTools::GetUnityResponse(TArrayD* binsTrue, TArrayD* binsRec, TString suffix) {
4446 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4447  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4448 #endif
4449  if(!binsTrue || !binsRec) {
4450  printf(" > GetUnityResponse:: function called with NULL arguments < \n");
4451  return 0x0;
4452  }
4453  TString name(Form("unityResponse_%s", suffix.Data()));
4454  TH2D* unity(new TH2D(name.Data(), name.Data(), binsTrue->GetSize()-1, binsTrue->GetArray(), binsRec->GetSize()-1, binsRec->GetArray()));
4455  for(Int_t i(0); i < binsTrue->GetSize(); i++) {
4456  for(Int_t j(0); j < binsRec->GetSize(); j++) {
4457  if(i==j) unity->SetBinContent(1+i, 1+j, 1.);
4458  }
4459  }
4460  return unity;
4461 }
4462 //_____________________________________________________________________________
4463 void AliJetFlowTools::SaveConfiguration(Bool_t convergedIn, Bool_t convergedOut) const {
4464 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4465  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4466 #endif
4467  // save configuration parameters to histogram
4468  TH1F* summary = new TH1F("UnfoldingConfiguration","UnfoldingConfiguration", 20, -.5, 19.5);
4469  summary->SetBinContent(1, fBetaIn);
4470  summary->GetXaxis()->SetBinLabel(1, "fBetaIn");
4471  summary->SetBinContent(2, fBetaOut);
4472  summary->GetXaxis()->SetBinLabel(2, "fBetaOut");
4473  summary->SetBinContent(3, fCentralityArray->At(0));
4474  summary->GetXaxis()->SetBinLabel(3, "fCentralityArray[0]");
4475  summary->SetBinContent(4, (int)convergedIn);
4476  summary->GetXaxis()->SetBinLabel(4, "convergedIn");
4477  summary->SetBinContent(5, (int)convergedOut);
4478  summary->GetXaxis()->SetBinLabel(5, "convergedOut");
4479  summary->SetBinContent(6, (int)fAvoidRoundingError);
4480  summary->GetXaxis()->SetBinLabel(6, "fAvoidRoundingError");
4481  summary->SetBinContent(7, (int)fUnfoldingAlgorithm);
4482  summary->GetXaxis()->SetBinLabel(7, "fUnfoldingAlgorithm");
4483  summary->SetBinContent(8, (int)fPrior);
4484  summary->GetXaxis()->SetBinLabel(8, "fPrior");
4485  summary->SetBinContent(9, fSVDRegIn);
4486  summary->GetXaxis()->SetBinLabel(9, "fSVDRegIn");
4487  summary->SetBinContent(10, fSVDRegOut);
4488  summary->GetXaxis()->SetBinLabel(10, "fSVDRegOut");
4489  summary->SetBinContent(11, (int)fSVDToy);
4490  summary->GetXaxis()->SetBinLabel(11, "fSVDToy");
4491  summary->SetBinContent(12, fJetRadius);
4492  summary->GetXaxis()->SetBinLabel(12, "fJetRadius");
4493  summary->SetBinContent(13, (int)fNormalizeSpectra);
4494  summary->GetXaxis()->SetBinLabel(13, "fNormalizeSpectra");
4495  summary->SetBinContent(14, (int)fSmoothenPrior);
4496  summary->GetXaxis()->SetBinLabel(14, "fSmoothenPrior");
4497  summary->SetBinContent(15, (int)fTestMode);
4498  summary->GetXaxis()->SetBinLabel(15, "fTestMode");
4499  summary->SetBinContent(16, (int)fUseDetectorResponse);
4500  summary->GetXaxis()->SetBinLabel(16, "fUseDetectorResponse");
4501  summary->SetBinContent(17, fBayesianIterIn);
4502  summary->GetXaxis()->SetBinLabel(17, "fBayesianIterIn");
4503  summary->SetBinContent(18, fBayesianIterOut);
4504  summary->GetXaxis()->SetBinLabel(18, "fBayesianIterOut");
4505  summary->SetBinContent(19, fBayesianSmoothIn);
4506  summary->GetXaxis()->SetBinLabel(19, "fBayesianSmoothIn");
4507  summary->SetBinContent(20, fBayesianSmoothOut);
4508  summary->GetXaxis()->SetBinLabel(20, "fBayesianSmoothOut");
4509 }
4510 //_____________________________________________________________________________
4512 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4513  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4514 #endif
4515  // ugly function: reset all unfolding parameters
4516  TVirtualFitter* fitter(TVirtualFitter::GetFitter());
4517  if(fitter) {
4518  printf(" > Found fitter, will delete it < \n");
4519  delete fitter;
4520  }
4521  if(gMinuit) {
4522  printf(" > Found gMinuit, will re-create it < \n");
4523  delete gMinuit;
4524  gMinuit = new TMinuit;
4525  }
4526  AliUnfolding::fgCorrelationMatrix = 0;
4527  AliUnfolding::fgCorrelationMatrixSquared = 0;
4528  AliUnfolding::fgCorrelationCovarianceMatrix = 0;
4529  AliUnfolding::fgCurrentESDVector = 0;
4530  AliUnfolding::fgEntropyAPriori = 0;
4531  AliUnfolding::fgEfficiency = 0;
4532  AliUnfolding::fgUnfoldedAxis = 0;
4533  AliUnfolding::fgMeasuredAxis = 0;
4534  AliUnfolding::fgFitFunction = 0;
4535  AliUnfolding::fgMaxInput = -1;
4536  AliUnfolding::fgMaxParams = -1;
4537  AliUnfolding::fgOverflowBinLimit = -1;
4538  AliUnfolding::fgRegularizationWeight = 10000;
4539  AliUnfolding::fgSkipBinsBegin = 0;
4540  AliUnfolding::fgMinuitStepSize = 0.1;
4541  AliUnfolding::fgMinuitPrecision = 1e-6;
4542  AliUnfolding::fgMinuitMaxIterations = 1000000;
4543  AliUnfolding::fgMinuitStrategy = 1.;
4544  AliUnfolding::fgMinimumInitialValue = kFALSE;
4545  AliUnfolding::fgMinimumInitialValueFix = -1;
4546  AliUnfolding::fgNormalizeInput = kFALSE;
4547  AliUnfolding::fgNotFoundEvents = 0;
4548  AliUnfolding::fgSkipBin0InChi2 = kFALSE;
4549  AliUnfolding::fgBayesianSmoothing = 1;
4550  AliUnfolding::fgBayesianIterations = 10;
4551  AliUnfolding::fgDebug = kFALSE;
4552  AliUnfolding::fgCallCount = 0;
4553  AliUnfolding::fgPowern = 5;
4554  AliUnfolding::fChi2FromFit = 0.;
4555  AliUnfolding::fPenaltyVal = 0.;
4556  AliUnfolding::fAvgResidual = 0.;
4557  AliUnfolding::fgPrintChi2Details = 0;
4558  AliUnfolding::fgCanvas = 0;
4559  AliUnfolding::fghUnfolded = 0;
4560  AliUnfolding::fghCorrelation = 0;
4561  AliUnfolding::fghEfficiency = 0;
4562  AliUnfolding::fghMeasured = 0;
4563  AliUnfolding::SetMinuitStepSize(1.);
4564  AliUnfolding::SetMinuitPrecision(1e-6);
4565  AliUnfolding::SetMinuitMaxIterations(100000);
4566  AliUnfolding::SetMinuitStrategy(2.);
4567  AliUnfolding::SetDebug(1);
4568 }
4569 //_____________________________________________________________________________
4570 TH1D* AliJetFlowTools::ProtectHeap(TH1D* protect, Bool_t kill, TString suffix) const {
4571 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4572  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4573 #endif
4574  // protect heap by adding unique qualifier to name
4575  if(!protect) return 0x0;
4576  TH1D* p = (TH1D*)protect->Clone();
4577  TString tempString(fActiveString);
4578  tempString+=suffix;
4579  p->SetName(Form("%s_%s", protect->GetName(), tempString.Data()));
4580  p->SetTitle(Form("%s_%s", protect->GetTitle(), tempString.Data()));
4581  if(kill) delete protect;
4582  return p;
4583 }
4584 //_____________________________________________________________________________
4585 TH2D* AliJetFlowTools::ProtectHeap(TH2D* protect, Bool_t kill, TString suffix) const {
4586 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4587  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4588 #endif
4589  // protect heap by adding unique qualifier to name
4590  if(!protect) return 0x0;
4591  TH2D* p = (TH2D*)protect->Clone();
4592  TString tempString(fActiveString);
4593  tempString+=suffix;
4594  p->SetName(Form("%s_%s", protect->GetName(), tempString.Data()));
4595  p->SetTitle(Form("%s_%s", protect->GetTitle(), tempString.Data()));
4596  if(kill) delete protect;
4597  return p;
4598 }
4599 //_____________________________________________________________________________
4600 TGraphErrors* AliJetFlowTools::ProtectHeap(TGraphErrors* protect, Bool_t kill, TString suffix) const {
4601 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4602  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4603 #endif
4604  // protect heap by adding unique qualifier to name
4605  if(!protect) return 0x0;
4606  TGraphErrors* p = (TGraphErrors*)protect->Clone();
4607  TString tempString(fActiveString);
4608  tempString+=suffix;
4609  p->SetName(Form("%s_%s", protect->GetName(), tempString.Data()));
4610  p->SetTitle(Form("%s_%s", protect->GetTitle(), tempString.Data()));
4611  if(kill) delete protect;
4612  return p;
4613 }
4614 //_____________________________________________________________________________
4616 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4617  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4618 #endif
4619  // === azimuthal unfolding ===
4620  //
4621  // unfolds the spectrum in delta phi bins, extracts the yield per bin, and does a fit
4622  // in transverse momentum and azimuthal correlation space to extract v2 params
4623  // settings are equal to the ones used for 'Make()'
4624  //
4625  // basic steps that are followed:
4626  // 1) rebin the raw output of the jet task to the desired binnings
4627  // 2) calls the unfolding routine
4628  // 3) writes output to file
4629  // can be repeated multiple times with different configurations
4630 
4631  Int_t low[] = {1, 6, 11, 16, 21, 26, 31, 36};
4632  Int_t up[] = {5, 10, 15, 20, 25, 30, 35, 40};
4633  TString stringArray[] = {"a", "b", "c", "d", "e", "f", "g", "h"};
4634  const Int_t ptBins(fBinsTrue->GetSize()-1);
4635  const Int_t dPhiBins(8);
4636  TH1D* dPtdPhi[fBinsTrue->GetSize()];
4637  for(Int_t i(0); i < ptBins; i++) dPtdPhi[i] = new TH1D(Form("dPtdPhi_%i", i), Form("dPtdPhi_%i", i), dPhiBins, 0, TMath::Pi());
4638 
4639  for(Int_t i(0); i < dPhiBins; i++) {
4640  // 1) manipulation of input histograms
4641  // check if the input variables are present
4642  if(!PrepareForUnfolding(low[i], up[i])) return;
4643  // 1a) resize the jet spectrum according to the binning scheme in fBinsTrue
4644  // parts of the spectrum can end up in over or underflow bins
4645  TH1D* measuredJetSpectrumIn = RebinTH1D(fSpectrumIn, fBinsRec, Form("resized_%s", stringArray[i].Data()), kFALSE);
4646 
4647  // 1b) resize the jet spectrum to 'true' bins. can serve as a prior and as a template for unfolding
4648  // the template will be used as a prior for the chi2 unfolding
4649  TH1D* measuredJetSpectrumTrueBinsIn = RebinTH1D(fSpectrumIn, fBinsTrue, stringArray[i], kFALSE);
4650 
4651  // get the full response matrix from the dpt and the detector response
4653  // get the full response matrix. if test mode is chosen, the full response is replace by a unity matrix
4654  // so that unfolding should return the initial spectrum
4659  // normalize each slide of the response to one
4661  // resize to desired binning scheme
4662  TH2D* resizedResponseIn = RebinTH2D(fFullResponseIn, fBinsTrue, fBinsRec, stringArray[i]);
4663  // get the kinematic efficiency
4664  TH1D* kinematicEfficiencyIn = resizedResponseIn->ProjectionX();
4665  kinematicEfficiencyIn->SetNameTitle(Form("kin_eff_%s", stringArray[i].Data()), Form("kin_eff_%s", stringArray[i].Data()));
4666  // suppress the errors
4667  for(Int_t j(0); j < kinematicEfficiencyIn->GetXaxis()->GetNbins(); j++) kinematicEfficiencyIn->SetBinError(1+j, 0.);
4668  TH1D* jetFindingEfficiency(0x0);
4669  if(fJetFindingEff) {
4670  jetFindingEfficiency = ProtectHeap(fJetFindingEff);
4671  jetFindingEfficiency->SetNameTitle(Form("%s_coarse", jetFindingEfficiency->GetName()), Form("%s_coarse", jetFindingEfficiency->GetName()));
4672  jetFindingEfficiency = RebinTH1D(jetFindingEfficiency, fBinsTrue);
4673  }
4674  // 2, 3) call the actual unfolding. results and transient objects are stored in a dedicated TDirectoryFile
4675  TH1D* unfoldedJetSpectrumIn(0x0);
4676  fActiveDir->cd(); // select active dir
4677  TDirectoryFile* dirIn = new TDirectoryFile(Form("%s___%s", stringArray[i].Data(), fActiveString.Data()), Form("%s___%s", stringArray[i].Data(), fActiveString.Data()));
4678  dirIn->cd(); // select inplane subdir
4679  // select the unfolding method
4680  unfoldedJetSpectrumIn = UnfoldWrapper(
4681  measuredJetSpectrumIn,
4682  resizedResponseIn,
4683  kinematicEfficiencyIn,
4684  measuredJetSpectrumTrueBinsIn,
4685  TString("dPtdPhiUnfolding"),
4686  jetFindingEfficiency);
4687  // arbitrarily save one of the full outputs (same for all dphi bins, avoid duplicates)
4688  if(i+1 == ptBins) {
4689  resizedResponseIn->SetNameTitle(Form("ResponseMatrix_%s", stringArray[i].Data()), Form("response matrix %s", stringArray[i].Data()));
4690  resizedResponseIn->SetXTitle("p_{T, jet}^{true} [GeV/c]");
4691  resizedResponseIn->SetYTitle("p_{T, jet}^{rec} [GeV/c]");
4692  resizedResponseIn = ProtectHeap(resizedResponseIn);
4693  resizedResponseIn->Write();
4694  kinematicEfficiencyIn->SetNameTitle(Form("KinematicEfficiency_%s", stringArray[i].Data()), Form("Kinematic efficiency, %s", stringArray[i].Data()));
4695  kinematicEfficiencyIn = ProtectHeap(kinematicEfficiencyIn);
4696  kinematicEfficiencyIn->Write();
4697  fDetectorResponse->SetNameTitle("DetectorResponse", "Detector response matrix");
4699  fDetectorResponse->Write();
4700  // optional histograms
4701  if(fSaveFull) {
4702  fSpectrumIn->SetNameTitle("[ORIG]JetSpectrum", Form("[INPUT] Jet spectrum, %s", stringArray[i].Data()));
4703  fSpectrumIn->Write();
4704  fDptInDist->SetNameTitle("[ORIG]DeltaPt", Form("#delta p_{T} distribution, %s", stringArray[i].Data()));
4705  fDptInDist->Write();
4706  fDptIn->SetNameTitle("[ORIG]DeltaPtMatrix", Form("#delta p_{T} matrix, %s", stringArray[i].Data()));
4707  fDptIn->Write();
4708  fFullResponseIn->SetNameTitle("ResponseMatrix", Form("Response matrix, %s", stringArray[i].Data()));
4709  fFullResponseIn->Write();
4710  }
4711  }
4712  fActiveDir->cd();
4713  fDeltaPtDeltaPhi->Write();
4714  fJetPtDeltaPhi->Write();
4715 
4716  TH1D* dud(ProtectHeap(unfoldedJetSpectrumIn, kTRUE, stringArray[i]));;
4717  Double_t integralError(0);
4718  // at this point in the code, the spectrum has been unfolded in a certain region of dPhi space
4719  // next step is splitting it in pt space as well to estimate the yield differentially in pt
4720  for(Int_t j(0); j < ptBins; j++) {
4721  // get the integrated
4722  Double_t integral(dud->IntegralAndError(j+1, j+2, integralError));
4723  dPtdPhi[j]->SetBinContent(i+1, integral);
4724  dPtdPhi[j]->SetBinError(i+1, integralError);
4725  }
4726  dud->Write();
4727  // save the current state of the unfolding object
4728  SaveConfiguration(unfoldedJetSpectrumIn ? kTRUE : kFALSE, kFALSE);
4729  }
4730  TF1* fourier = new TF1("fourier", "[0]*(1.+0.5*[1]*(TMath::Cos(2.*x)))", 0, TMath::Pi());
4731  TH1D* v2(new TH1D("v2FromFit", "v2FromFit", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
4732  for(Int_t i(0); i < ptBins; i++) {
4733  dPtdPhi[i]->Fit(fourier, "VI");
4734  Style(gPad, "PEARSON");
4735  Style(dPtdPhi[i], kBlue, kDeltaPhi);
4736  dPtdPhi[i]->DrawCopy();
4738  TString(Form("%.2f #LT p_{T} #LT %.2f", fBinsTrue->At(i), fBinsTrue->At(i+1))),
4739  kBlack,
4740  .38,
4741  .56,
4742  .62,
4743  .65
4744  );
4745  v2->SetBinContent(1+i, fourier->GetParameter(1));
4746  v2->SetBinError(1+i, fourier->GetParError(1));
4747  Style(gPad, "PEARSON");
4748  Style(v2, kBlack, kV2, kTRUE);
4749  v2->DrawCopy();
4750  dPtdPhi[i]->Write();
4751  }
4752 }
4753 //_____________________________________________________________________________
4754 void AliJetFlowTools::ReplaceBins(TArrayI* array, TGraphErrors* graph) {
4755  // replace bins
4756 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4757  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4758 #endif
4759  Double_t x(0), y(0);
4760  graph->GetPoint(0, x, y);
4761  graph->SetPoint(array->At(0)-1, fBinsTrue->At(array->At(0)), y);
4762  graph->SetPointError(array->At(0)-1, 10, graph->GetErrorY(0));
4763  graph->SetPoint(array->At(1)-1, -5, -5);
4764 }
4765 //_____________________________________________________________________________
4766 void AliJetFlowTools::ReplaceBins(TArrayI* array, TGraphAsymmErrors* graph) {
4767 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4768  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4769 #endif
4770  // replace bins
4771  Double_t x(0), y(0);
4772  graph->GetPoint(0, x, y);
4773  graph->SetPoint(array->At(0)-1, fBinsTrue->At(array->At(0)), y);
4774  Double_t yl = graph->GetErrorYlow(0);
4775  Double_t yh = graph->GetErrorYhigh(0);
4776  graph->SetPointError(array->At(0)-1, 10, 10, yl, yh);
4777  graph->SetPoint(array->At(1)-1, -5, -5);
4778 }
4779 //_____________________________________________________________________________
4781  TGraphErrors* n, // points with stat error
4782  TGraphAsymmErrors* shape, // points with shape error
4783  TGraphAsymmErrors* corr, // points with stat error
4784  Int_t low, // lower bin (tgraph starts at 0)
4785  Int_t up // upper bin
4786  )
4787 {
4788 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4789  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4790 #endif
4791  // main use of this function is filling the static buffers
4792  Double_t statE(0), shapeE(0), corrE(0), y(0), x(0);
4793 
4794  // print some stuff
4795  printf(" double v2[] = {\n");
4796  Int_t iterator(0);
4797  for(Int_t i(low); i < up+1; i++) {
4798  n->GetPoint(i, x, y);
4799  if(i==up) printf("%.4f}; \n\n", y);
4800  else printf("%.4f, \n", y);
4801  gV2->SetAt(y, iterator);
4802  iterator++;
4803  }
4804  iterator = 0;
4805  printf(" double stat[] = {\n");
4806  for(Int_t i(low); i < up+1; i++) {
4807  y = n->GetErrorYlow(i);
4808  if(i==up) printf("%.4f}; \n\n", y);
4809  else printf("%.4f, \n", y);
4810  gStat->SetAt(y, iterator);
4811  iterator++;
4812  }
4813  iterator = 0;
4814  printf(" double shape[] = {\n");
4815  for(Int_t i(low); i < up+1; i++) {
4816  y = shape->GetErrorYhigh(i);
4817  if (y < 0.0001) y = 0.0001; // avoid crash in fit routine
4818  y*=gReductionFactor;
4819  shape->SetPointEYhigh(i, y);
4820  y = shape->GetErrorYlow(i);
4821  if ( y < 0.0001) y = 0.0001;
4822  y*=gReductionFactor;
4823  shape->SetPointEYlow(i, y);
4824  if(i==up) printf("%.4f}; \n\n", y);
4825  else printf("%.4f, \n", y);
4826  gShape->SetAt(y, iterator);
4827  iterator++;
4828  }
4829  iterator = 0;
4830  printf(" double corr[] = {\n");
4831  for(Int_t i(low); i < up+1; i++) {
4832  y = gReductionFactorCorr*corr->GetErrorYhigh(i);
4833  corr->SetPointEYhigh(i, y);
4834  y = gReductionFactorCorr*corr->GetErrorYlow(i);
4835  corr->SetPointEYlow(i, y);
4836  if(i==up) printf("%.4f}; \n\n", y);
4837  else printf("%.4f, \n", y);
4838  gCorr->SetAt(y, iterator);
4839  iterator++;
4840  }
4841 
4842  // to plot the average error as function of number of events
4843  Float_t ctr(0);
4844  for(Int_t i(low); i < up+1; i++) {
4845  ctr = ctr + 1.;
4846  // set some flags to 0
4847  x = 0.;
4848  y = 0.;
4849  // get the nominal point
4850  n->GetPoint(i, x, y);
4851  statE += n->GetErrorY(i);
4852  shapeE += shape->GetErrorY(i);
4853  corrE += corr->GetErrorY(i);
4854  // combine the errors
4855  }
4856  printf(" ======================================\n");
4857  printf(" > between %i and %i GeV/c \n", low, up);
4858  cout << " AVERAGE_SHAPE " << shapeE/ctr << endl;
4859  cout << " AVERAGE_CORR " << corrE/ctr << endl;
4860  cout << " AVERAGE_STAT " << statE/ctr << endl;
4861 }
4862 //_____________________________________________________________________________
4864 {
4865 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4866  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4867 #endif
4868  // Choose method upon creation between:
4869  // kMigrad, kSimplex, kCombined,
4870  // kScan, kFumili
4871  ROOT::Minuit2::Minuit2Minimizer min ( ROOT::Minuit2::kMigrad );
4872  min.SetMaxFunctionCalls(1000000);
4873  min.SetMaxIterations(100000);
4874  min.SetTolerance(0.001);
4875 
4876  ROOT::Math::Functor f(&PhenixChi2nd,2);
4877  double step[] = {0.0000001, 0.0000001};
4878  double variable[] = {-1., -1.};
4879 
4880  min.SetFunction(f);
4881  // Set the free variables to be minimized!
4882  min.SetVariable(0,"epsilon_c",variable[0], step[0]);
4883  min.SetVariable(1,"epsilon_b",variable[1], step[1]);
4884 
4885 
4886  min.Minimize();
4887 }
4888 //_____________________________________________________________________________
4889 Double_t AliJetFlowTools::PhenixChi2nd(const Double_t *xx )
4890 {
4891 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4892  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4893 #endif
4894  // define arrays with results and errors here, see example at PhenixChi2()
4895 
4896  // return the function value at certain epsilon
4897  const Double_t epsc = xx[0];
4898  const Double_t epsb = xx[1];
4899  Double_t chi2(0);
4900  Int_t counts(gV2->GetSize() + gOffsetStop);
4901 
4902  if(gPwrtTo > -999) {
4903  // altered implemtation of eq 3 of arXiv:0801.1665v2
4904  // see analysis note and QM2014 poster for validation
4905  for(Int_t i(gOffsetStart); i < counts; i++) {
4906 
4907  // quadratic sum of statistical and uncorrelated systematic error
4908  Double_t e = gStat->At(i);
4909 
4910  // sum of v2 plus epsilon times correlated error minus hypothesis (gPwrtTo)
4911  // also the numerator of equation 3 of phenix paper
4912  Double_t numerator = TMath::Power(gV2->At(i)+epsc*gCorr->At(i)+epsb-gPwrtTo, 2);
4913 
4914  // modified denominator of equation 3 of phenix paper
4915  Double_t denominator = e*e;
4916 
4917  // add to the sum
4918  chi2 += numerator/denominator;
4919  }
4920  // add the square of epsilon to the total chi2 as penalty
4921 
4922  Double_t sumEpsb(0);
4923  for(Int_t j(gOffsetStart); j < counts; j++) sumEpsb += (epsb*epsb)/(gShape->At(j)*gShape->At(j));
4924  chi2 += epsc*epsc + sumEpsb/((float)counts);
4925  } else {
4926  // otherwise use the array
4927  for(Int_t i(gOffsetStart); i < counts; i++) {
4928 
4929  // quadratic sum of statistical and uncorrelated systematic error
4930  Double_t e = TMath::Sqrt(gStat->At(i)*gStat->At(i) + gPwrtToStatArray->At(i)*gPwrtToStatArray->At(i));
4931 
4932  // sum of v2 plus epsilon times correlated error minus hypothesis (gPwrtTo)
4933  // also the numerator of equation 3 of phenix paper
4934  Double_t numerator = TMath::Power(gV2->At(i)+epsc*gCorr->At(i)+epsb-gPwrtToArray->At(i), 2);
4935 
4936  // modified denominator of equation 3 of phenix paper
4937  Double_t denominator = e*e;
4938 
4939  // add to the sum
4940  chi2 += numerator/denominator;
4941  }
4942  // add the square of epsilon to the total chi2 as penalty
4943 
4944  Double_t sumEpsb(0);
4945  for(Int_t j(gOffsetStart); j < counts; j++) sumEpsb += (epsb*epsb)/(gShape->At(j)*gShape->At(j));
4946  chi2 += epsc*epsc + sumEpsb/((float)counts);
4947  }
4948  return chi2;
4949 }
4950 //_____________________________________________________________________________
4951 Double_t AliJetFlowTools::ConstructFunctionnd(Double_t *x, Double_t *par)
4952 {
4953 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4954  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4955 #endif
4956  // internal use only: evaluate the function at a given point
4957  if(par) SquelchWarning();
4959 }
4960 //_____________________________________________________________________________
4962 {
4963 #ifdef ALIJETFLOWTOOLS_DEBUG_FLAG
4964  printf("__FILE__ = %s \n __LINE __ %i , __FUNC__ %s \n ", __FILE__, __LINE__, __func__);
4965 #endif
4966  // return the fitting function, pass the p-value w.r.t. 0 by reference
4967  const Int_t DOF(7-2); // dof is n-2
4968  TF2 *f1 = new TF2("ndhist", AliJetFlowTools::ConstructFunctionnd, -100, 100, -100, 100, 0);
4969  printf(" > locating minima < \n");
4970  Double_t x(0), y(0);
4971  f1->GetMinimumXY(x, y);
4972  f1->GetXaxis()->SetTitle("#epsilon{c}");
4973  f1->GetXaxis()->SetTitle("#epsilon_{b}");
4974  f1->GetZaxis()->SetTitle("#chi^{2}");
4975 
4976  printf(" ===============================================================================\n");
4977  printf(" > minimal chi2 f(%.8f, %.8f) = %.8f (i should be ok ... ) \n", x, y, f1->Eval(x, y));
4978  cout << " so the probability of finding data at least as imcompatible with " << gPwrtTo << " as the actually" << endl;
4979  cout << " observed data is " << TMath::Prob(f1->Eval(x, y), DOF) << endl;
4980  cout << " minimization parameters: EPSILON_B " << y << endl;
4981  cout << " EPSILON_C " << x << endl;
4982  printf(" ===============================================================================\n");
4983 
4984  // pass the p-value by reference and return the function
4985  p = TMath::Prob(f1->Eval(x, y), DOF);
4986  return f1;
4987 }
4988 //_____________________________________________________________________________
TH1D * UnfoldSpectrumSVD(const TH1D *measuredJetSpectrum, const TH2D *resizedResponse, const TH1D *kinematicEfficiency, const TH1D *measuredJetSpectrumTrueBins, const TString suffix, const TH1D *jetFindingEfficiency=0x0)
return jsonbuilder str().c_str()
static TH1D * SmoothenPrior(TH1D *spectrum, TF1 *function, Double_t min, Double_t max, Double_t start, Bool_t kill=kTRUE, Bool_t counts=kTRUE)
static void WriteObject(TObject *object, TString suffix="", Bool_t kill=kTRUE)
static TH2D * ResizeYaxisTH2D(TH2D *histo, TArrayD *x, TArrayD *y, TString suffix="")
TH1D * UnfoldSpectrumBayesian(const TH1D *measuredJetSpectrum, const TH2D *resizedResponse, const TH1D *kinematicEfficiency, const TH1D *measuredJetSpectrumTrueBins, const TString suffix, const TH1D *jetFindingEfficiency=0x0)
Bool_t fUseDetectorResponse
static TH2D * NormalizeTH2D(TH2D *histo, Bool_t noError=kTRUE)
static Float_t gPwrtTo
TArrayD * fBinsRecPrior
static Int_t gOffsetStart
TDirectoryFile * fActiveDir
static Double_t ConstructFunctionnd(Double_t *x, Double_t *par)
TH1D * UnfoldSpectrumBayesianAli(const TH1D *measuredJetSpectrum, const TH2D *resizedResponse, const TH1D *kinematicEfficiency, const TH1D *measuredJetSpectrumTrueBins, const TString suffix, const TH1D *jetFindingEfficiency=0x0)
static TGraphAsymmErrors * AddHistoErrorsToGraphErrors(TGraphAsymmErrors *g, TH1D *h)
static Double_t PhenixChi2nd(const Double_t *xx)
AliAnaChargedJetResponseMaker * fResponseMaker
void GetNominalValues(TH1D *&ratio, TGraphErrors *&v2, TArrayI *in, TArrayI *out, TString inFile="UnfoldedSpectra.root", TString outFile="Nominal.root") const
Float_t fBayesianSmoothOut
static TArrayD * gStat
TProfile * fRMSSpectrumIn
static TH1D * MergeSpectrumBins(TArrayI *bins, TH1D *spectrum, TH2D *corr)
TArrayD * fBinsTruePrior
static TH1D * GetV2Histo(TH1 *h1=0x0, TH1 *h2=0x0, Double_t r=0., TString name="")
static Float_t gReductionFactor
static Float_t gReductionFactorCorr
void BootstrapSpectra(TString def, TString in="UnfoldedSpectra.root", TString out="BootstrapSpectra.root") const
void ReplaceBins(TArrayI *array, TGraphAsymmErrors *graph)
void DoIntermediateSystematicsOnV2(TArrayI *variationsIn, TArrayI *variationsOut, TH1D *&relativeErrorInUp, TH1D *&relativeErrorInLow, TH1D *&relativeErrorOutUp, TH1D *&relativeErrorOutLow, TH1D *&relativeSystematicIn, TH1D *&relativeSystematicOut, TH1D *&nominal, TH1D *&nominalIn, TH1D *&nominalOut, Int_t columns, Float_t rangeLow, Float_t rangeUp, TFile *readMe, TString source="", Bool_t RMS=kFALSE) const
TRandom * gRandom
static TH2D * MatrixMultiplication(TH2D *a, TH2D *b, TString name="CombinedResponse")
static TH2D * ConstructDPtResponseFromTH1D(TH1D *dpt, Bool_t AvoidRoundingError)
Float_t fMergeWithWeight
Double_t * sigma
Bool_t PrepareForUnfolding(TH1 *customIn=0x0, TH1 *customOut=0x0)
void PostProcess(TString def, Int_t columns=4, Float_t rangeLow=20, Float_t rangeUp=80, TString in="UnfoldedSpectra.root", TString out="ProcessedSpectra.root") const
static Int_t gOffsetStop
static TArrayD * gCorr
static void GetSignificance(TGraphErrors *n, TGraphAsymmErrors *shape, TGraphAsymmErrors *corr, Int_t low, Int_t up)
static void Style(Bool_t legacy=kFALSE)
void Make(TH1 *customIn=0x0, TH1 *customOut=0x0)
static void SavePadToPDF(TVirtualPad *pad)
void GetShapeUncertainty(TGraphAsymmErrors *&shapeRatio, TGraphAsymmErrors *&shapeV2, TArrayI *regularizationIn, TArrayI *regularizationOut, TArrayI *recBinIn=0x0, TArrayI *recBinOut=0x0, TArrayI *methodIn=0x0, TArrayI *methodOut=0x0, Int_t columns=4, Float_t rangeLow=20, Float_t rangeUp=80, Float_t corr=.0, TString in="UnfoldedSpectra.root", TString out="ShapeUncertainty.root", Bool_t regularizationOnV2=kTRUE) const
static TH1D * RebinTH1D(TH1D *histo, TArrayD *bins, TString suffix="", Bool_t kill=kTRUE)
static TH1F * ConvertGraphToHistogram(TGraphErrors *g)
void GetCorrelatedUncertainty(TGraphAsymmErrors *&corrRatio, TGraphAsymmErrors *&corrV2, TArrayI *variationsIn, TArrayI *variationsOut, Bool_t sym, TArrayI *variantions2ndIn, TArrayI *variantions2ndOut, Bool_t sym2nd, TString type="", TString type2="", Int_t columns=4, Float_t rangeLow=20, Float_t rangeUp=80, Float_t corr=.5, TString in="UnfoldedSpectra.root", TString out="CorrelatedUncertainty.root") const
unfoldingAlgorithm fUnfoldingAlgorithm
static TArrayD * gShape
static TGraphErrors * GetRatio(TH1 *h1=0x0, TH1 *h2=0x0, TString name="", Bool_t appendFit=kFALSE, Int_t xmax=-1)
Bool_t fAvoidRoundingError
TH1D * GetPrior(const TH1D *measuredJetSpectrum, const TH2D *resizedResponse, const TH1D *kinematicEfficiency, const TH1D *measuredJetSpectrumTrueBins, const TString suffix, const TH1D *jetFindingEfficiency)
static TF1 * GetErrorFromFit(TH1 *h1, TH1 *h2, Double_t a, Double_t b, Float_t pivot=50., Bool_t subdueError=kFALSE, TString str="", Bool_t setContent=kTRUE)
void DoIntermediateSystematics(TArrayI *variationsIn, TArrayI *variationsOut, TH1D *&relativeErrorInUp, TH1D *&relativeErrorInLow, TH1D *&relativeErrorOutUp, TH1D *&relativeErrorOutLow, TH1D *&relativeSystematicIn, TH1D *&relativeSystematicOut, TH1D *&nominal, TH1D *&nominalIn, TH1D *&nominalOut, Int_t columns, Float_t rangeLow, Float_t rangeUp, TFile *readMe, TString source="", Bool_t RMS=kFALSE) const
static TLegend * AddLegend(TVirtualPad *p, Bool_t style=kFALSE)
TH1D * UnfoldSpectrumChi2(const TH1D *measuredJetSpectrum, const TH2D *resizedResponse, const TH1D *kinematicEfficiency, const TH1D *measuredJetSpectrumTrueBins, const TString suffix, const TH1D *jetFindingEfficiency=0x0)
static TH1D * ResizeXaxisTH1D(TH1D *histo, Int_t low, Int_t up, TString suffix="")
TH1D * UnfoldWrapper(const TH1D *measuredJetSpectrum, const TH2D *resizedResponse, const TH1D *kinematicEfficiency, const TH1D *measuredJetSpectrumTrueBins, const TString suffix, const TH1D *jetFindingEfficiency=0x0)
static TGraphErrors * GetV2(TH1 *h1=0x0, TH1 *h2=0x0, Double_t r=0., TString name="")
Float_t fBayesianSmoothIn
TH1D * ProtectHeap(TH1D *protect, Bool_t kill=kTRUE, TString suffix="") const
Bool_t Data(TH1F *h, Double_t *rangefit, Bool_t writefit, Double_t &sgn, Double_t &errsgn, Double_t &bkg, Double_t &errbkg, Double_t &sgnf, Double_t &errsgnf, Double_t &sigmafit, Int_t &status)
TGraphAsymmErrors * GetV2WithSystematicErrors(TH1 *h1, TH1 *h2, Double_t r, TString name, TH1 *relativeErrorInUp, TH1 *relativeErrorInLow, TH1 *relativeErrorOutUp, TH1 *relativeErrorOutLow, Float_t rho=0.) const
static TArrayD * gPwrtToStatArray
TArrayI * fMergeBinsArray
static TH2D * GetUnityResponse(TArrayD *binsTrue, TArrayD *binsRec, TString suffix="")
static void RemoveSign(Double_t &d)
void SaveConfiguration(Bool_t convergedIn, Bool_t convergedOut) const
TH2D * RebinTH2D(TH2D *histo, TArrayD *binsTrue, TArrayD *binsRec, TString suffix="")
static TMatrixD * CalculatePearsonCoefficients(TMatrixD *covmat)
static TH1 * Bootstrap(TH1 *hist, Bool_t kill=kTRUE)
TArrayI * fCentralityArray
static TArrayD * gV2
static TF2 * ReturnFunctionnd(Double_t &p)
Double_t fEventPlaneRes
TProfile * fRMSSpectrumOut
Bool_t SetRawInput(TH2D *detectorResponse, TH1D *jetPtIn, TH1D *jetPtOut, TH1D *dptIn, TH1D *dptOut, Int_t eventCount=0)
TH1D * FoldSpectrum(const TH1D *measuredJetSpectrum, const TH2D *resizedResponse, const TH1D *kinematicEfficiency, const TH1D *measuredJetSpectrumTrueBins, const TString suffix, const TH1D *jetFindingEfficiency=0x0)
static void ResetAliUnfolding()
void SystematicsWrapper(TArrayI *variationsIn, TArrayI *variationsOut, TH1D *&relativeErrorInUp, TH1D *&relativeErrorInLow, TH1D *&relativeErrorOutUp, TH1D *&relativeErrorOutLow, TH1D *&relativeSystematicIn, TH1D *&relativeSystematicOut, TH1D *&nominal, TH1D *&nominalIn, TH1D *&nominalOut, Int_t columns, Float_t rangeLow, Float_t rangeUp, TFile *readMe, TString source="", Bool_t RMS=kFALSE, Bool_t onRatio=kTRUE) const
static TPaveText * AddText(TString text, EColor col, Double_t a=.2098, Double_t b=.5601, Double_t c=.613, Double_t d=.6211)
TProfile * fRMSRatio
static void SquelchWarning()
static void MinimizeChi2nd()
static TH1D * NormalizeTH1D(TH1D *histo, Double_t scale=1.)
TArrayD * fCentralityWeights
static TArrayD * gPwrtToArray
static Double_t GetRMSOfTH1(TH1 *h, Double_t a, Double_t b)