1 /*************************************************************************
2 * Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 // Author: Redmer Alexander Bertens, Utrecht University, Utrecht, Netherlands
17 // (rbertens@cern.ch, rbertens@nikhef.nl, r.a.bertens@uu.nl)
19 // Tools class for Jet Flow Analysis, replaces 'extractJetFlow.C' macro
21 // The task uses input from two analysis tasks:
22 // - $ALICE_ROOT/PWGJE/EMCALJetTasks/UserTasks/AliAnalysisTaskJetV2.cxx
23 // used to retrieve jet spectra and delta pt distributions
24 // - $ALICE_ROOT/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 ).
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
37 // to see an example of how to use this class, see $ALICE_ROOT/PWGCF/FLOW/macros/jetFlowTools.C
44 #include "TGraphErrors.h"
45 #include "TGraphAsymmErrors.h"
52 #include "TVirtualFitter.h"
58 #include "TVirtualFitter.h"
59 #include "TFitResultPtr.h"
60 #include "Minuit2/Minuit2Minimizer.h"
61 #include "Math/Functor.h"
63 #include "AliUnfolding.h"
64 #include "AliAnaChargedJetResponseMaker.h"
66 #include "AliJetFlowTools.h"
67 // roo unfold includes (make sure you have these available on your system)
68 #include "RooUnfold.h"
69 #include "RooUnfoldResponse.h"
70 #include "RooUnfoldSvd.h"
71 #include "RooUnfoldBayes.h"
72 #include "TSVDUnfold.h"
75 //_____________________________________________________________________________
76 AliJetFlowTools::AliJetFlowTools() :
77 fResponseMaker (new AliAnaChargedJetResponseMaker()),
82 fPower (new TF1("fPower","[0]*TMath::Power(x,-([1]))",0.,300.)),
87 fRefreshInput (kTRUE),
88 fOutputFileName ("UnfoldedSpectra.root"),
90 fCentralityArray (0x0),
91 fMergeBinsArray (0x0),
92 fCentralityWeights (0x0),
93 fDetectorResponse (0x0),
99 fBayesianSmoothIn (0.),
100 fBayesianSmoothOut (0.),
101 fAvoidRoundingError (kFALSE),
102 fUnfoldingAlgorithm (kChi2),
103 fPrior (kPriorMeasured),
107 fBinsTruePrior (0x0),
114 fNormalizeSpectra (kFALSE),
115 fSmoothenPrior (kFALSE),
119 fSmoothenCounts (kTRUE),
121 fRawInputProvided (kFALSE),
122 fEventPlaneRes (.63),
123 fUseDetectorResponse(kTRUE),
124 fUseDptResponse (kTRUE),
126 fDphiUnfolding (kTRUE),
127 fDphiDptUnfolding (kFALSE),
129 fTitleFontSize (-999.),
130 fRMSSpectrumIn (0x0),
131 fRMSSpectrumOut (0x0),
134 fDeltaPtDeltaPhi (0x0),
135 fJetPtDeltaPhi (0x0),
142 fFullResponseIn (0x0),
143 fFullResponseOut (0x0) { // class constructor
144 // create response maker weight function (tuned to PYTHIA spectrum)
145 fResponseMaker->SetRMMergeWeightFunction(new TF1("weightFunction", "x*TMath::Power(1.+(1./(8.*0.9))*x, -8.)", 0, 200));
146 for(Int_t i(0); i < fPower->GetNpar(); i++) fPower->SetParameter(i, 0.);
148 //_____________________________________________________________________________
149 void AliJetFlowTools::Make(TH1* customIn, TH1* customOut) {
150 // core function of the class
151 if(fDphiDptUnfolding) {
152 // to extract the yield as function of Dphi, Dpt - experimental
156 // 1) rebin the raw output of the jet task to the desired binnings
157 // 2) calls the unfolding routine
158 // 3) writes output to file
159 // can be repeated multiple times with different configurations
161 // 1) manipulation of input histograms
162 // check if the input variables are present
164 if(!PrepareForUnfolding(customIn, customOut)) {
165 printf(" AliJetFlowTools::Make() Fatal error \n - couldn't prepare for unfolding ! \n");
169 // 1a) resize the jet spectrum according to the binning scheme in fBinsTrue
170 // parts of the spectrum can end up in over or underflow bins
172 // if bootstrap mode is kTRUE, resample the underlying distributions
173 // FIXME think about resampling the rebinned results or raw results, could lead to difference
174 // in smoothness of tail of spectrum (which is probably not used in any case, but still ... )
177 // resample but leave original spectra intact for the next unfolding round
178 fSpectrumIn = reinterpret_cast<TH1D*>(Bootstrap(fSpectrumIn, kFALSE));
179 fSpectrumOut = reinterpret_cast<TH1D*>(Bootstrap(fSpectrumOut, kFALSE));
182 TH1D* measuredJetSpectrumIn = RebinTH1D(fSpectrumIn, fBinsRec, TString("resized_in_"), kFALSE);
183 TH1D* measuredJetSpectrumOut = RebinTH1D(fSpectrumOut, fBinsRec, TString("resized_out_"), kFALSE);
186 measuredJetSpectrumIn = reinterpret_cast<TH1D*>(Bootstrap(measuredJetSpectrumIn, kFALSE));
187 measuredJetSpectrumOut = reinterpret_cast<TH1D*>(Bootstrap(measuredJetSpectrumOut, kFALSE));
189 // for now do it BEFORE as after gives an issue in Rebin function (counts are wrong)
193 // 1b) resize the jet spectrum to 'true' bins. can serve as a prior and as a template for unfolding
194 // the template will be used as a prior for the chi2 unfolding
195 TH1D* measuredJetSpectrumTrueBinsIn = RebinTH1D(fSpectrumIn, fBinsTrue, TString("in"), kFALSE);
196 TH1D* measuredJetSpectrumTrueBinsOut = RebinTH1D(fSpectrumOut, fBinsTrue, TString("out"), kFALSE);
197 // get the full response matrix from the dpt and the detector response
198 fDetectorResponse = NormalizeTH2D(fDetectorResponse);
199 // get the full response matrix. if test mode is chosen, the full response is replace by a unity matrix
200 // so that unfolding should return the initial spectrum
202 if(fUseDptResponse && fUseDetectorResponse) {
203 fFullResponseIn = MatrixMultiplication(fDptIn, fDetectorResponse);
204 fFullResponseOut = MatrixMultiplication(fDptOut, fDetectorResponse);
205 } else if (fUseDptResponse && !fUseDetectorResponse) {
206 fFullResponseIn = fDptIn;
207 fFullResponseOut = fDptOut;
208 } else if (!fUseDptResponse && fUseDetectorResponse) {
209 fFullResponseIn = fDetectorResponse;
210 fFullResponseOut = fDetectorResponse;
211 } else if (!fUseDptResponse && !fUseDetectorResponse && !fUnfoldingAlgorithm == AliJetFlowTools::kNone) {
212 printf(" > No response, exiting ! < \n" );
216 fFullResponseIn = GetUnityResponse(fBinsTrue, fBinsRec, TString("in"));
217 fFullResponseOut = GetUnityResponse(fBinsTrue, fBinsRec, TString("out"));
219 // normalize each slide of the response to one
220 NormalizeTH2D(fFullResponseIn);
221 NormalizeTH2D(fFullResponseOut);
222 // resize to desired binning scheme
223 TH2D* resizedResponseIn = RebinTH2D(fFullResponseIn, fBinsTrue, fBinsRec, TString("in"));
224 TH2D* resizedResponseOut = RebinTH2D(fFullResponseOut, fBinsTrue, fBinsRec, TString("out"));
225 // get the kinematic efficiency
226 TH1D* kinematicEfficiencyIn = resizedResponseIn->ProjectionX();
227 kinematicEfficiencyIn->SetNameTitle("kin_eff_IN","kin_eff_IN");
228 TH1D* kinematicEfficiencyOut = resizedResponseOut->ProjectionX();
229 kinematicEfficiencyOut->SetNameTitle("kin_eff_OUT", "kin_eff_OUT");
230 // suppress the errors
231 for(Int_t i(0); i < kinematicEfficiencyOut->GetXaxis()->GetNbins(); i++) {
232 kinematicEfficiencyIn->SetBinError(1+i, 0.);
233 kinematicEfficiencyOut->SetBinError(1+i, 0.);
235 TH1D* jetFindingEfficiency(0x0);
237 jetFindingEfficiency = ProtectHeap(fJetFindingEff);
238 jetFindingEfficiency->SetNameTitle(Form("%s_coarse", jetFindingEfficiency->GetName()), Form("%s_coarse", jetFindingEfficiency->GetName()));
239 jetFindingEfficiency = RebinTH1D(jetFindingEfficiency, fBinsTrue);
241 // 2, 3) call the actual unfolding. results and transient objects are stored in a dedicated TDirectoryFile
242 TH1D* unfoldedJetSpectrumIn(0x0);
243 TH1D* unfoldedJetSpectrumOut(0x0);
244 fActiveDir->cd(); // select active dir
245 TDirectoryFile* dirIn = new TDirectoryFile(Form("InPlane___%s", fActiveString.Data()), Form("InPlane___%s", fActiveString.Data()));
246 dirIn->cd(); // select inplane subdir
247 // do the inplane unfolding
248 unfoldedJetSpectrumIn = UnfoldWrapper(
249 measuredJetSpectrumIn,
251 kinematicEfficiencyIn,
252 measuredJetSpectrumTrueBinsIn,
254 jetFindingEfficiency);
255 resizedResponseIn->SetNameTitle("ResponseMatrixIn", "response matrix in plane");
256 resizedResponseIn->SetXTitle("p_{T, jet}^{true} (GeV/#it{c})");
257 resizedResponseIn->SetYTitle("p_{T, jet}^{rec} (GeV/#it{c})");
258 resizedResponseIn = ProtectHeap(resizedResponseIn);
259 resizedResponseIn->Write();
260 kinematicEfficiencyIn->SetNameTitle("KinematicEfficiencyIn","Kinematic efficiency, in plane");
261 kinematicEfficiencyIn = ProtectHeap(kinematicEfficiencyIn);
262 kinematicEfficiencyIn->Write();
263 fDetectorResponse->SetNameTitle("DetectorResponse", "Detector response matrix");
264 fDetectorResponse = ProtectHeap(fDetectorResponse, kFALSE);
265 fDetectorResponse->Write();
266 // optional histograms
268 fSpectrumIn->SetNameTitle("[ORIG]JetSpectrum", "[INPUT] Jet spectrum, in plane");
269 fSpectrumIn->Write();
270 fDptInDist->SetNameTitle("[ORIG]DeltaPt", "#delta p_{T} distribution, in plane");
272 fDptIn->SetNameTitle("[ORIG]DeltaPtMatrix","#delta p_{T} matrix, in plane");
274 fFullResponseIn->SetNameTitle("ResponseMatrix", "Response matrix, in plane");
275 fFullResponseIn->Write();
279 TDirectoryFile* dirOut = new TDirectoryFile(Form("OutOfPlane___%s", fActiveString.Data()), Form("OutOfPlane___%s", fActiveString.Data()));
281 // do the out of plane unfolding
282 unfoldedJetSpectrumOut = UnfoldWrapper(
283 measuredJetSpectrumOut,
285 kinematicEfficiencyOut,
286 measuredJetSpectrumTrueBinsOut,
288 jetFindingEfficiency);
289 resizedResponseOut->SetNameTitle("ResponseMatrixOut", "response matrix in plane");
290 resizedResponseOut->SetXTitle("p_{T, jet}^{true} (GeV/#it{c})");
291 resizedResponseOut->SetYTitle("p_{T, jet}^{rec} (GeV/#it{c})");
292 resizedResponseOut = ProtectHeap(resizedResponseOut);
293 resizedResponseOut->Write();
294 kinematicEfficiencyOut->SetNameTitle("KinematicEfficiencyOut","Kinematic efficiency, Out plane");
295 kinematicEfficiencyOut = ProtectHeap(kinematicEfficiencyOut);
296 kinematicEfficiencyOut->Write();
297 fDetectorResponse->SetNameTitle("DetectorResponse", "Detector response matrix");
298 fDetectorResponse = ProtectHeap(fDetectorResponse, kFALSE);
299 fDetectorResponse->Write();
300 if(jetFindingEfficiency) jetFindingEfficiency->Write();
301 // optional histograms
303 fSpectrumOut->SetNameTitle("[ORIG]JetSpectrum", "[INPUT]Jet spectrum, Out plane");
304 fSpectrumOut->Write();
305 fDptOutDist->SetNameTitle("[ORIG]DeltaPt", "#delta p_{T} distribution, Out plane");
306 fDptOutDist->Write();
307 fDptOut->SetNameTitle("[ORIG]DeltaPtMatrix","#delta p_{T} matrix, Out plane");
309 fFullResponseOut->SetNameTitle("[ORIG]ResponseMatrix", "Response matrix, Out plane");
310 fFullResponseOut->Write();
313 // write general output histograms to file
315 if(unfoldedJetSpectrumIn && unfoldedJetSpectrumOut && unfoldedJetSpectrumIn && unfoldedJetSpectrumOut) {
316 TGraphErrors* ratio(GetRatio((TH1D*)unfoldedJetSpectrumIn->Clone("unfoldedLocal_in"), (TH1D*)unfoldedJetSpectrumOut->Clone("unfoldedLocal_out")));
318 ratio->SetNameTitle("RatioInOutPlane", "Ratio in plane, out of plane jet spectrum");
319 ratio->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
320 ratio->GetYaxis()->SetTitle("yield IN / yield OUT");
321 ratio = ProtectHeap(ratio);
323 // write histo values to RMS files if both routines converged
324 // input values are weighted by their uncertainty
325 for(Int_t i(0); i < ratio->GetXaxis()->GetNbins(); i++) {
326 if(unfoldedJetSpectrumIn->GetBinError(i+1) > 0) fRMSSpectrumIn->Fill(fRMSSpectrumIn->GetBinCenter(i+1), unfoldedJetSpectrumIn->GetBinContent(i+1), 1./TMath::Power(unfoldedJetSpectrumIn->GetBinError(i+1), 2.));
327 if(unfoldedJetSpectrumOut->GetBinError(i+1) > 0) fRMSSpectrumOut->Fill(fRMSSpectrumOut->GetBinCenter(i+1), unfoldedJetSpectrumOut->GetBinContent(i+1), 1./TMath::Power(unfoldedJetSpectrumOut->GetBinError(i+1), 2.));
328 if(unfoldedJetSpectrumOut->GetBinContent(i+1) > 0) fRMSRatio->Fill(fRMSSpectrumIn->GetBinCenter(i+1), unfoldedJetSpectrumIn->GetBinContent(i+1) / unfoldedJetSpectrumOut->GetBinContent(i+1));
331 TGraphErrors* v2(GetV2((TH1D*)unfoldedJetSpectrumIn->Clone("unfoldedLocal_inv2"), (TH1D*)unfoldedJetSpectrumOut->Clone("unfoldedLocal_outv2"), fEventPlaneRes));
333 v2->SetNameTitle("v2", "v_{2} from different in, out of plane yield");
334 v2->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
335 v2->GetYaxis()->SetTitle("v_{2}");
336 v2 = ProtectHeap(v2);
339 } else if (unfoldedJetSpectrumOut && unfoldedJetSpectrumIn) {
340 TGraphErrors* ratio(GetRatio((TH1D*)unfoldedJetSpectrumIn->Clone("unfoldedLocal_in"), (TH1D*)unfoldedJetSpectrumOut->Clone("unfoldedLocal_out"), TString(""), kTRUE, fBinsRec->At(fBinsRec->GetSize()-1)));
342 ratio->SetNameTitle("[NC]RatioInOutPlane", "[NC]Ratio in plane, out of plane jet spectrum");
343 ratio->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
344 ratio->GetYaxis()->SetTitle("yield IN / yield OUT");
345 ratio = ProtectHeap(ratio);
348 TGraphErrors* v2(GetV2((TH1D*)unfoldedJetSpectrumIn->Clone("unfoldedLocal_inv2"), (TH1D*)unfoldedJetSpectrumOut->Clone("unfoldedLocal_outv2"), fEventPlaneRes));
350 v2->SetNameTitle("v2", "v_{2} from different in, out of plane yield");
351 v2->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
352 v2->GetYaxis()->SetTitle("v_{2}");
353 v2 = ProtectHeap(v2);
357 } // end of if(fDphiUnfolding)
358 fDeltaPtDeltaPhi->Write();
359 unfoldedJetSpectrumIn->Sumw2();
360 ProtectHeap(unfoldedJetSpectrumIn, kFALSE);
361 unfoldedJetSpectrumIn->Write();
362 unfoldedJetSpectrumOut->Sumw2();
363 ProtectHeap(unfoldedJetSpectrumOut, kFALSE);
364 unfoldedJetSpectrumOut->Write();
365 fJetPtDeltaPhi->Write();
366 // save the current state of the unfolding object
367 SaveConfiguration(unfoldedJetSpectrumIn ? kTRUE : kFALSE, unfoldedJetSpectrumOut ? kTRUE : kFALSE);
368 TH1D* unfoldedJetSpectrumInForSub((TH1D*)unfoldedJetSpectrumIn->Clone("forSubIn"));
369 TH1D* unfoldedJetSpectrumOutForSub((TH1D*)unfoldedJetSpectrumOut->Clone("forSubOut"));
370 unfoldedJetSpectrumInForSub->Add(unfoldedJetSpectrumOutForSub, -1.);
371 unfoldedJetSpectrumInForSub= ProtectHeap(unfoldedJetSpectrumInForSub);
372 unfoldedJetSpectrumInForSub->Write();
375 //_____________________________________________________________________________
376 TH1D* AliJetFlowTools::UnfoldWrapper(
377 const TH1D* measuredJetSpectrum, // truncated raw jets (same binning as pt rec of response)
378 const TH2D* resizedResponse, // response matrix
379 const TH1D* kinematicEfficiency, // kinematic efficiency
380 const TH1D* measuredJetSpectrumTrueBins, // unfolding template: same binning is pt gen of response
381 const TString suffix, // suffix (in or out of plane)
382 const TH1D* jetFindingEfficiency) // jet finding efficiency
384 // wrapper function to call specific unfolding routine
385 TH1D* (AliJetFlowTools::*myFunction)(const TH1D*, const TH2D*, const TH1D*, const TH1D*, const TString, const TH1D*);
386 // initialize functon pointer
387 if(fUnfoldingAlgorithm == kChi2) myFunction = &AliJetFlowTools::UnfoldSpectrumChi2;
388 else if(fUnfoldingAlgorithm == kBayesian) myFunction = &AliJetFlowTools::UnfoldSpectrumBayesian;
389 else if(fUnfoldingAlgorithm == kBayesianAli) myFunction = &AliJetFlowTools::UnfoldSpectrumBayesianAli;
390 else if(fUnfoldingAlgorithm == kSVD) myFunction = &AliJetFlowTools::UnfoldSpectrumSVD;
391 else if(fUnfoldingAlgorithm == kFold) myFunction = &AliJetFlowTools::FoldSpectrum;
392 else if(fUnfoldingAlgorithm == kNone) {
393 TH1D* clone((TH1D*)measuredJetSpectrum->Clone("clone"));
394 clone->SetNameTitle(Form("MeasuredJetSpectrum%s", suffix.Data()), Form("measuredJetSpectrum %s", suffix.Data()));
395 return clone;//RebinTH1D(clone, fBinsTrue, clone->GetName(), kFALSE);
398 // do the actual unfolding with the selected function
399 return (this->*myFunction)( measuredJetSpectrum, resizedResponse, kinematicEfficiency, measuredJetSpectrumTrueBins, suffix, jetFindingEfficiency);
401 //_____________________________________________________________________________
402 TH1D* AliJetFlowTools::UnfoldSpectrumChi2(
403 const TH1D* measuredJetSpectrum, // truncated raw jets (same binning as pt rec of response)
404 const TH2D* resizedResponse, // response matrix
405 const TH1D* kinematicEfficiency, // kinematic efficiency
406 const TH1D* measuredJetSpectrumTrueBins, // unfolding template: same binning is pt gen of response
407 const TString suffix, // suffix (in or out of plane)
408 const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
410 // unfold the spectrum using chi2 minimization
412 // step 0) setup the static members of AliUnfolding
413 ResetAliUnfolding(); // reset from previous iteration
414 // also deletes and re-creates the global TVirtualFitter
415 AliUnfolding::SetUnfoldingMethod(AliUnfolding::kChi2Minimization);
416 if(!strcmp("in", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaIn);
417 else if(!strcmp("out", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaOut);
418 if(!strcmp("prior_in", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaIn);
419 else if(!strcmp("prior_out", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaOut);
420 AliUnfolding::SetNbins(fBinsRec->GetSize()-1, fBinsTrue->GetSize()-1);
422 // step 1) clone all input histograms. the histograms are cloned to make sure that the original histograms
423 // stay intact. a local copy of a histogram (which only exists in the scope of this function) is
424 // denoted by the suffix 'Local'
426 // measuredJetSpectrumLocal holds the spectrum that needs to be unfolded
427 TH1D *measuredJetSpectrumLocal = (TH1D*)measuredJetSpectrum->Clone(Form("measuredJetSpectrumLocal_%s", suffix.Data()));
428 // unfolded local will be filled with the result of the unfolding
429 TH1D *unfoldedLocal(new TH1D(Form("unfoldedLocal_%s", suffix.Data()), Form("unfoldedLocal_%s", suffix.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
431 // full response matrix and kinematic efficiency
432 TH2D* resizedResponseLocal = (TH2D*)resizedResponse->Clone(Form("resizedResponseLocal_%s", suffix.Data()));
433 TH1D* kinematicEfficiencyLocal = (TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiencyLocal_%s", suffix.Data()));
435 // the initial guess for the unfolded pt spectrum, equal to the folded spectrum, but in 'true' bins
436 TH1D *priorLocal = (TH1D*)measuredJetSpectrumTrueBins->Clone(Form("priorLocal_%s", suffix.Data()));
437 // optionally, the prior can be smoothened by extrapolating the spectrum using a power law fit
438 if(fSmoothenPrior) priorLocal = SmoothenPrior(priorLocal, fPower, fFitMin, fFitMax, fFitStart, kTRUE, fSmoothenCounts);
440 // step 2) start the unfolding
441 Int_t status(-1), i(0);
442 while(status < 0 && i < 100) {
443 // i > 0 means that the first iteration didn't converge. in that case, the result of the first
444 // iteration (stored in unfoldedLocal) is cloned and used as a starting point for the
445 if (i > 0) priorLocal = (TH1D*)unfoldedLocal->Clone(Form("priorLocal_%s_%i", suffix.Data(), i));
446 status = AliUnfolding::Unfold(
447 resizedResponseLocal, // response matrix
448 kinematicEfficiencyLocal, // efficiency applied on the unfolded spectrum (can be NULL)
449 measuredJetSpectrumLocal, // measured spectrum
450 priorLocal, // initial conditions (set NULL to use measured spectrum)
451 unfoldedLocal); // results
452 // status holds the minuit fit status (where 0 means convergence)
455 // get the status of TMinuit::mnhess(), fISW[1] == 3 means the hessian matrix was calculated succesfully
457 if(status == 0 && gMinuit->fISW[1] == 3) {
458 // if the unfolding converged and the hessian matrix is reliable, plot the pearson coefficients
459 TVirtualFitter *fitter(TVirtualFitter::GetFitter());
460 if(gMinuit) gMinuit->Command("SET COV");
461 TMatrixD covarianceMatrix(fBinsTrue->GetSize()-1, fBinsTrue->GetSize()-1, fitter->GetCovarianceMatrix());
462 TMatrixD *pearson((TMatrixD*)CalculatePearsonCoefficients(&covarianceMatrix));
464 hPearson = new TH2D(*pearson);
465 hPearson->SetNameTitle(Form("PearsonCoefficients_%s", suffix.Data()), Form("Pearson coefficients, %s plane", suffix.Data()));
466 hPearson = ProtectHeap(hPearson);
468 if(fMergeBinsArray) unfoldedLocal = MergeSpectrumBins(fMergeBinsArray, unfoldedLocal, hPearson);
471 // step 3) refold the unfolded spectrum and save the ratio measured / refolded
472 TH1D *foldedLocal(fResponseMaker->MultiplyResponseGenerated(unfoldedLocal, resizedResponseLocal,kinematicEfficiencyLocal));
473 foldedLocal->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("Refolded jet spectrum, %s plane", suffix.Data()));
474 unfoldedLocal->SetNameTitle(Form("UnfoldedSpectrum_%s", suffix.Data()), Form("Unfolded jet spectrum, %s plane", suffix.Data()));
475 TGraphErrors* ratio(GetRatio(foldedLocal, measuredJetSpectrumLocal, TString(""), kTRUE, fBinsTrue->At(fBinsTrue->GetSize()-1)));
477 ratio->SetNameTitle("RatioRefoldedMeasured", Form("Ratio measured, re-folded %s ", suffix.Data()));
478 ratio->GetYaxis()->SetTitle("ratio measured / re-folded");
479 ratio = ProtectHeap(ratio);
483 // step 4) write histograms to file. to ensure that these have unique identifiers on the heap,
484 // objects are cloned using 'ProtectHeap()'
485 measuredJetSpectrumLocal->SetNameTitle(Form("InputSpectrum_%s", suffix.Data()), Form("InputSpectrum_%s", suffix.Data()));
486 measuredJetSpectrumLocal = ProtectHeap(measuredJetSpectrumLocal);
487 measuredJetSpectrumLocal->Write();
489 resizedResponseLocal = ProtectHeap(resizedResponseLocal);
490 resizedResponseLocal->Write();
492 unfoldedLocal = ProtectHeap(unfoldedLocal);
493 if(jetFindingEfficiency) unfoldedLocal->Divide(jetFindingEfficiency);
494 unfoldedLocal->Write();
496 foldedLocal = ProtectHeap(foldedLocal);
497 foldedLocal->Write();
499 priorLocal = ProtectHeap(priorLocal);
502 // step 5) save the fit status (penalty value, degrees of freedom, chi^2 value)
503 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));
504 fitStatus->SetBinContent(1, AliUnfolding::fChi2FromFit);
505 fitStatus->GetXaxis()->SetBinLabel(1, "fChi2FromFit");
506 fitStatus->SetBinContent(2, AliUnfolding::fPenaltyVal);
507 fitStatus->GetXaxis()->SetBinLabel(2, "fPenaltyVal");
508 fitStatus->SetBinContent(3, fBinsRec->GetSize()-fBinsTrue->GetSize());
509 fitStatus->GetXaxis()->SetBinLabel(3, "DOF");
510 fitStatus->SetBinContent(4, (!strcmp(suffix.Data(), "in")) ? fBetaIn : fBetaOut);
511 fitStatus->GetXaxis()->SetBinLabel(4, (!strcmp(suffix.Data(), "in")) ? "fBetaIn" : "fBetaOut");
514 return unfoldedLocal;
516 //_____________________________________________________________________________
517 TH1D* AliJetFlowTools::UnfoldSpectrumSVD(
518 const TH1D* measuredJetSpectrum, // jet pt in pt rec bins
519 const TH2D* resizedResponse, // full response matrix, normalized in slides of pt true
520 const TH1D* kinematicEfficiency, // kinematic efficiency
521 const TH1D* measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
522 const TString suffix, // suffix (in, out)
523 const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
526 TH1D* priorLocal( GetPrior(
527 measuredJetSpectrum, // jet pt in pt rec bins
528 resizedResponse, // full response matrix, normalized in slides of pt true
529 kinematicEfficiency, // kinematic efficiency
530 measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
531 suffix, // suffix (in, out)
532 jetFindingEfficiency)); // jet finding efficiency (optional)
534 printf(" > couldn't find prior ! < \n");
536 } else printf(" 1) retrieved prior \n");
538 // go back to the 'root' directory of this instance of the SVD unfolding routine
539 (!strcmp(suffix.Data(), "in")) ? fActiveDir->cd(Form("InPlane___%s", fActiveString.Data())) : fActiveDir->cd(Form("OutOfPlane___%s", fActiveString.Data()));
541 // 2) setup all the necessary input for the unfolding routine. all input histograms are copied locally
542 // measured jets in pt rec binning
543 TH1D *measuredJetSpectrumLocal((TH1D*)measuredJetSpectrum->Clone(Form("jets_%s", suffix.Data())));
544 // local copie of the response matrix
545 TH2D *resizedResponseLocal((TH2D*)resizedResponse->Clone(Form("resizedResponseLocal_%s", suffix.Data())));
546 // local copy of response matrix, all true slides normalized to 1
547 // this response matrix will eventually be used in the re-folding routine
548 TH2D *resizedResponseLocalNorm((TH2D*)resizedResponse->Clone(Form("resizedResponseLocalNorm_%s", suffix.Data())));
549 resizedResponseLocalNorm = NormalizeTH2D(resizedResponseLocalNorm);
550 // kinematic efficiency
551 TH1D *kinematicEfficiencyLocal((TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiency_%s", suffix.Data())));
552 // place holder histos
553 TH1D *unfoldedLocalSVD(0x0);
554 TH1D *foldedLocalSVD(0x0);
555 cout << " 2) setup necessary input " << endl;
556 // 3) configure routine
557 RooUnfold::ErrorTreatment errorTreatment = (fSVDToy) ? RooUnfold::kCovToy : RooUnfold::kCovariance;
558 cout << " step 3) configured routine " << endl;
560 // 4) get transpose matrices
561 // a) get the transpose of the full response matrix
562 TH2* responseMatrixLocalTransposePrior(fResponseMaker->GetTransposeResponsMatrix(resizedResponseLocal));
563 responseMatrixLocalTransposePrior->SetNameTitle(Form("prior_%s_%s", responseMatrixLocalTransposePrior->GetName(), suffix.Data()),Form("prior_%s_%s", responseMatrixLocalTransposePrior->GetName(), suffix.Data()));
564 // normalize it with the prior. this will ensure that high statistics bins will constrain the
565 // end result most strenuously than bins with limited number of counts
566 responseMatrixLocalTransposePrior = fResponseMaker->NormalizeResponsMatrixYaxisWithPrior(responseMatrixLocalTransposePrior, priorLocal);
567 cout << " 4) retrieved first transpose matrix " << endl;
569 // 5) get response for SVD unfolding
570 RooUnfoldResponse responseSVD(0, 0, responseMatrixLocalTransposePrior, Form("respCombinedSVD_%s", suffix.Data()), Form("respCombinedSVD_%s", suffix.Data()));
571 cout << " 5) retrieved roo unfold response object " << endl;
573 // 6) actualy unfolding loop
574 RooUnfoldSvd unfoldSVD(&responseSVD, measuredJetSpectrumLocal, (!strcmp(suffix.Data(), "in")) ? fSVDRegIn : fSVDRegOut);
575 unfoldedLocalSVD = (TH1D*)unfoldSVD.Hreco(errorTreatment);
576 // correct the spectrum for the kinematic efficiency
577 unfoldedLocalSVD->Divide(kinematicEfficiencyLocal);
579 // get the pearson coefficients from the covariance matrix
580 TMatrixD covarianceMatrix = unfoldSVD.Ereco(errorTreatment);
581 TMatrixD *pearson = (TMatrixD*)CalculatePearsonCoefficients(&covarianceMatrix);
584 hPearson = new TH2D(*pearson);
586 hPearson->SetNameTitle(Form("PearsonCoefficients_%s", suffix.Data()), Form("Pearson coefficients_%s", suffix.Data()));
587 hPearson = ProtectHeap(hPearson);
589 if(fMergeBinsArray) unfoldedLocalSVD = MergeSpectrumBins(fMergeBinsArray, unfoldedLocalSVD, hPearson);
590 } else return 0x0; // return if unfolding didn't converge
592 // plot singular values and d_i vector
593 TSVDUnfold* svdUnfold(unfoldSVD.Impl());
594 TH1* hSVal(svdUnfold->GetSV());
595 TH1D* hdi(svdUnfold->GetD());
596 hSVal->SetNameTitle("SingularValuesOfAC", "Singular values of AC^{-1}");
597 hSVal->SetXTitle("singular values");
599 hdi->SetNameTitle("dVector", "d vector after orthogonal transformation");
600 hdi->SetXTitle("|d_{i}^{kreg}|");
602 cout << " plotted singular values and d_i vector " << endl;
604 // 7) refold the unfolded spectrum
605 foldedLocalSVD = fResponseMaker->MultiplyResponseGenerated(unfoldedLocalSVD, resizedResponseLocalNorm, kinematicEfficiencyLocal);
606 TGraphErrors* ratio(GetRatio(measuredJetSpectrumLocal, foldedLocalSVD, "ratio measured / re-folded", kTRUE));
607 ratio->SetNameTitle(Form("RatioRefoldedMeasured_%s", fActiveString.Data()), Form("Ratio measured / re-folded %s", fActiveString.Data()));
608 ratio->GetXaxis()->SetTitle("p_{t}^{rec, rec} [GeV/ c]");
609 ratio->GetYaxis()->SetTitle("ratio measured / re-folded");
611 cout << " 7) refolded the unfolded spectrum " << endl;
613 // write the measured, unfolded and re-folded spectra to the output directory
614 measuredJetSpectrumLocal->SetNameTitle(Form("InputSpectrum_%s", suffix.Data()), Form("input spectrum (measured) %s", suffix.Data()));
615 measuredJetSpectrumLocal = ProtectHeap(measuredJetSpectrumLocal);
616 measuredJetSpectrumLocal->SetXTitle("p_{t}^{rec} [GeV/c]");
617 measuredJetSpectrumLocal->Write(); // input spectrum
618 unfoldedLocalSVD->SetNameTitle(Form("UnfoldedSpectrum_%s",suffix.Data()), Form("unfolded spectrum %s", suffix.Data()));
619 unfoldedLocalSVD = ProtectHeap(unfoldedLocalSVD);
620 if(jetFindingEfficiency) unfoldedLocalSVD->Divide(jetFindingEfficiency);
621 unfoldedLocalSVD->Write(); // unfolded spectrum
622 foldedLocalSVD->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("refoldedSpectrum_%s", suffix.Data()));
623 foldedLocalSVD = ProtectHeap(foldedLocalSVD);
624 foldedLocalSVD->Write(); // re-folded spectrum
626 // save more general bookkeeeping histograms to the output directory
627 responseMatrixLocalTransposePrior->SetNameTitle("TransposeResponseMatrix", "Transpose of response matrix, normalize with prior");
628 responseMatrixLocalTransposePrior->SetXTitle("p_{T, jet}^{true} [GeV/c]");
629 responseMatrixLocalTransposePrior->SetYTitle("p_{T, jet}^{rec} [GeV/c]");
630 responseMatrixLocalTransposePrior->Write();
631 priorLocal->SetNameTitle("PriorOriginal", "Prior, original");
632 priorLocal->SetXTitle("p_{t} [GeV/c]");
633 priorLocal = ProtectHeap(priorLocal);
635 resizedResponseLocalNorm = ProtectHeap(resizedResponseLocalNorm);
636 resizedResponseLocalNorm->Write();
639 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));
640 fitStatus->SetBinContent(1, (!strcmp(suffix.Data(), "in")) ? fSVDRegIn : fSVDRegOut);
641 fitStatus->GetXaxis()->SetBinLabel(1, (!strcmp(suffix.Data(), "in")) ? "fSVDRegIn" : "fSVDRegOut");
644 return unfoldedLocalSVD;
646 //_____________________________________________________________________________
647 TH1D* AliJetFlowTools::UnfoldSpectrumBayesianAli(
648 const TH1D* measuredJetSpectrum, // jet pt in pt rec bins
649 const TH2D* resizedResponse, // full response matrix, normalized in slides of pt true
650 const TH1D* kinematicEfficiency, // kinematic efficiency
651 const TH1D* measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
652 const TString suffix, // suffix (in, out)
653 const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
655 // unfold the spectrum using the bayesian unfolding impelmented in AliUnfolding
656 // FIXME careful, not tested yet ! (06122013) FIXME
658 // step 0) setup the static members of AliUnfolding
659 ResetAliUnfolding(); // reset from previous iteration
660 // also deletes and re-creates the global TVirtualFitter
661 AliUnfolding::SetUnfoldingMethod(AliUnfolding::kBayesian);
662 if(!strcmp("in", suffix.Data())) AliUnfolding::SetBayesianParameters(fBayesianSmoothIn, fBayesianIterIn);
663 else if(!strcmp("out", suffix.Data())) AliUnfolding::SetBayesianParameters(fBayesianSmoothOut, fBayesianIterOut);
664 else if(!strcmp("prior_in", suffix.Data())) AliUnfolding::SetBayesianParameters(fBayesianSmoothIn, fBayesianIterIn);
665 else if(!strcmp("prior_out", suffix.Data())) AliUnfolding::SetBayesianParameters(fBayesianSmoothOut, fBayesianIterOut);
666 AliUnfolding::SetNbins(fBinsRec->GetSize()-1, fBinsTrue->GetSize()-1);
668 // 1) get a prior for unfolding and clone all the input histograms
669 TH1D* priorLocal( GetPrior(
670 measuredJetSpectrum, // jet pt in pt rec bins
671 resizedResponse, // full response matrix, normalized in slides of pt true
672 kinematicEfficiency, // kinematic efficiency
673 measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
674 suffix, // suffix (in, out)
675 jetFindingEfficiency)); // jet finding efficiency (optional)
677 printf(" > couldn't find prior ! < \n");
679 } else printf(" 1) retrieved prior \n");
680 // switch back to root dir of this unfolding procedure
681 (!strcmp(suffix.Data(), "in")) ? fActiveDir->cd(Form("InPlane___%s", fActiveString.Data())) : fActiveDir->cd(Form("OutOfPlane___%s", fActiveString.Data()));
683 // measuredJetSpectrumLocal holds the spectrum that needs to be unfolded
684 TH1D *measuredJetSpectrumLocal = (TH1D*)measuredJetSpectrum->Clone(Form("measuredJetSpectrumLocal_%s", suffix.Data()));
685 // unfolded local will be filled with the result of the unfolding
686 TH1D *unfoldedLocal(new TH1D(Form("unfoldedLocal_%s", suffix.Data()), Form("unfoldedLocal_%s", suffix.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
688 // full response matrix and kinematic efficiency
689 TH2D* resizedResponseLocal = (TH2D*)resizedResponse->Clone(Form("resizedResponseLocal_%s", suffix.Data()));
690 TH1D* kinematicEfficiencyLocal = (TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiencyLocal_%s", suffix.Data()));
692 // step 2) start the unfolding
693 Int_t status(-1), i(0);
694 while(status < 0 && i < 100) {
695 // i > 0 means that the first iteration didn't converge. in that case, the result of the first
696 // iteration (stored in unfoldedLocal) is cloned and used as a starting point for the
697 if (i > 0) priorLocal = (TH1D*)unfoldedLocal->Clone(Form("priorLocal_%s_%i", suffix.Data(), i));
698 status = AliUnfolding::Unfold(
699 resizedResponseLocal, // response matrix
700 kinematicEfficiencyLocal, // efficiency applied on the unfolded spectrum (can be NULL)
701 measuredJetSpectrumLocal, // measured spectrum
702 priorLocal, // initial conditions (set NULL to use measured spectrum)
703 unfoldedLocal); // results
704 // status holds the minuit fit status (where 0 means convergence)
707 // get the status of TMinuit::mnhess(), fISW[1] == 3 means the hessian matrix was calculated succesfully
709 if(status == 0 && gMinuit->fISW[1] == 3) {
710 // if the unfolding converged and the hessian matrix is reliable, plot the pearson coefficients
711 TVirtualFitter *fitter(TVirtualFitter::GetFitter());
712 if(gMinuit) gMinuit->Command("SET COV");
713 TMatrixD covarianceMatrix(fBinsTrue->GetSize()-1, fBinsTrue->GetSize()-1, fitter->GetCovarianceMatrix());
714 TMatrixD *pearson((TMatrixD*)CalculatePearsonCoefficients(&covarianceMatrix));
716 hPearson= new TH2D(*pearson);
717 hPearson->SetNameTitle(Form("PearsonCoefficients_%s", suffix.Data()), Form("Pearson coefficients, %s plane", suffix.Data()));
718 hPearson = ProtectHeap(hPearson);
721 if(fMergeBinsArray) unfoldedLocal = MergeSpectrumBins(fMergeBinsArray, unfoldedLocal, hPearson);
723 // step 3) refold the unfolded spectrum and save the ratio measured / refolded
724 TH1D *foldedLocal(fResponseMaker->MultiplyResponseGenerated(unfoldedLocal, resizedResponseLocal,kinematicEfficiencyLocal));
725 foldedLocal->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("Refolded jet spectrum, %s plane", suffix.Data()));
726 unfoldedLocal->SetNameTitle(Form("UnfoldedSpectrum_%s", suffix.Data()), Form("Unfolded jet spectrum, %s plane", suffix.Data()));
727 TGraphErrors* ratio(GetRatio(foldedLocal, measuredJetSpectrumLocal, TString(""), kTRUE, fBinsTrue->At(fBinsTrue->GetSize()-1)));
729 ratio->SetNameTitle("RatioRefoldedMeasured", Form("Ratio measured, re-folded %s ", suffix.Data()));
730 ratio->GetYaxis()->SetTitle("ratio measured / re-folded");
731 ratio = ProtectHeap(ratio);
735 // step 4) write histograms to file. to ensure that these have unique identifiers on the heap,
736 // objects are cloned using 'ProtectHeap()'
737 measuredJetSpectrumLocal->SetNameTitle(Form("InputSpectrum_%s", suffix.Data()), Form("InputSpectrum_%s", suffix.Data()));
738 measuredJetSpectrumLocal = ProtectHeap(measuredJetSpectrumLocal);
739 measuredJetSpectrumLocal->Write();
741 resizedResponseLocal = ProtectHeap(resizedResponseLocal);
742 resizedResponseLocal->Write();
744 unfoldedLocal = ProtectHeap(unfoldedLocal);
745 if(jetFindingEfficiency) unfoldedLocal->Divide(jetFindingEfficiency);
746 unfoldedLocal->Write();
748 foldedLocal = ProtectHeap(foldedLocal);
749 foldedLocal->Write();
751 priorLocal = ProtectHeap(priorLocal);
754 // step 5) save the fit status (penalty value, degrees of freedom, chi^2 value)
755 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));
756 fitStatus->SetBinContent(1, AliUnfolding::fChi2FromFit);
757 fitStatus->GetXaxis()->SetBinLabel(1, "fChi2FromFit");
758 fitStatus->SetBinContent(2, AliUnfolding::fPenaltyVal);
759 fitStatus->GetXaxis()->SetBinLabel(2, "fPenaltyVal");
760 fitStatus->SetBinContent(3, fBinsRec->GetSize()-fBinsTrue->GetSize());
761 fitStatus->GetXaxis()->SetBinLabel(3, "DOF");
762 fitStatus->SetBinContent(4, (!strcmp(suffix.Data(), "in")) ? fBetaIn : fBetaOut);
763 fitStatus->GetXaxis()->SetBinLabel(4, (!strcmp(suffix.Data(), "in")) ? "fBetaIn" : "fBetaOut");
766 return unfoldedLocal;
768 //_____________________________________________________________________________
769 TH1D* AliJetFlowTools::UnfoldSpectrumBayesian(
770 const TH1D* measuredJetSpectrum, // jet pt in pt rec bins
771 const TH2D* resizedResponse, // full response matrix, normalized in slides of pt true
772 const TH1D* kinematicEfficiency, // kinematic efficiency
773 const TH1D* measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
774 const TString suffix, // suffix (in, out)
775 const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
777 // use bayesian unfolding from the RooUnfold package to unfold jet spectra
779 // 1) get a prior for unfolding.
780 TH1D* priorLocal( GetPrior(
781 measuredJetSpectrum, // jet pt in pt rec bins
782 resizedResponse, // full response matrix, normalized in slides of pt true
783 kinematicEfficiency, // kinematic efficiency
784 measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
785 suffix, // suffix (in, out)
786 jetFindingEfficiency)); // jet finding efficiency (optional)
788 printf(" > couldn't find prior ! < \n");
790 } else printf(" 1) retrieved prior \n");
791 (!strcmp(suffix.Data(), "in")) ? fActiveDir->cd(Form("InPlane___%s", fActiveString.Data())) : fActiveDir->cd(Form("OutOfPlane___%s", fActiveString.Data()));
793 // 2) setup all the necessary input for the unfolding routine. all input histograms are copied locally
794 // measured jets in pt rec binning
795 TH1D *measuredJetSpectrumLocal((TH1D*)measuredJetSpectrum->Clone(Form("jets_%s", suffix.Data())));
796 // local copie of the response matrix
797 TH2D *resizedResponseLocal((TH2D*)resizedResponse->Clone(Form("resizedResponseLocal_%s", suffix.Data())));
798 // local copy of response matrix, all true slides normalized to 1
799 // this response matrix will eventually be used in the re-folding routine
800 TH2D *resizedResponseLocalNorm((TH2D*)resizedResponse->Clone(Form("resizedResponseLocalNorm_%s", suffix.Data())));
801 resizedResponseLocalNorm = NormalizeTH2D(resizedResponseLocalNorm);
802 // kinematic efficiency
803 TH1D *kinematicEfficiencyLocal((TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiency_%s", suffix.Data())));
804 // place holder histos
805 TH1D *unfoldedLocalBayes(0x0);
806 TH1D *foldedLocalBayes(0x0);
807 cout << " 2) setup necessary input " << endl;
808 // 4) get transpose matrices
809 // a) get the transpose of the full response matrix
810 TH2* responseMatrixLocalTransposePrior(fResponseMaker->GetTransposeResponsMatrix(resizedResponseLocal));
811 responseMatrixLocalTransposePrior->SetNameTitle(Form("prior_%s_%s", responseMatrixLocalTransposePrior->GetName(), suffix.Data()),Form("prior_%s_%s", responseMatrixLocalTransposePrior->GetName(), suffix.Data()));
812 // normalize it with the prior. this will ensure that high statistics bins will constrain the
813 // end result most strenuously than bins with limited number of counts
814 responseMatrixLocalTransposePrior = fResponseMaker->NormalizeResponsMatrixYaxisWithPrior(responseMatrixLocalTransposePrior, priorLocal);
815 // 3) get response for Bayesian unfolding
816 RooUnfoldResponse responseBayes(0, 0, responseMatrixLocalTransposePrior, Form("respCombinedBayes_%s", suffix.Data()), Form("respCombinedBayes_%s", suffix.Data()));
818 // 4) actualy unfolding loop
819 RooUnfoldBayes unfoldBayes(&responseBayes, measuredJetSpectrumLocal, (!strcmp("in", suffix.Data())) ? fBayesianIterIn : fBayesianIterOut);
820 RooUnfold::ErrorTreatment errorTreatment = (fSVDToy) ? RooUnfold::kCovToy : RooUnfold::kCovariance;
821 unfoldedLocalBayes = (TH1D*)unfoldBayes.Hreco(errorTreatment);
822 // correct the spectrum for the kinematic efficiency
823 unfoldedLocalBayes->Divide(kinematicEfficiencyLocal);
824 // get the pearson coefficients from the covariance matrix
825 TMatrixD covarianceMatrix = unfoldBayes.Ereco(errorTreatment);
826 TMatrixD *pearson = (TMatrixD*)CalculatePearsonCoefficients(&covarianceMatrix);
829 hPearson = new TH2D(*pearson);
831 hPearson->SetNameTitle(Form("PearsonCoefficients_%s", suffix.Data()), Form("Pearson coefficients_%s", suffix.Data()));
832 hPearson = ProtectHeap(hPearson);
834 if(fMergeBinsArray) unfoldedLocalBayes = MergeSpectrumBins(fMergeBinsArray, unfoldedLocalBayes, hPearson);
835 } else return 0x0; // return if unfolding didn't converge
837 // 5) refold the unfolded spectrum
838 foldedLocalBayes = fResponseMaker->MultiplyResponseGenerated(unfoldedLocalBayes, resizedResponseLocalNorm, kinematicEfficiencyLocal);
839 TGraphErrors* ratio(GetRatio(measuredJetSpectrumLocal, foldedLocalBayes, "ratio measured / re-folded", kTRUE));
840 ratio->SetNameTitle(Form("RatioRefoldedMeasured_%s", fActiveString.Data()), Form("Ratio measured / re-folded %s", fActiveString.Data()));
841 ratio->GetXaxis()->SetTitle("p_{t}^{rec, rec} [GeV/ c]");
842 ratio->GetYaxis()->SetTitle("ratio measured / re-folded");
844 cout << " 7) refolded the unfolded spectrum " << endl;
846 // write the measured, unfolded and re-folded spectra to the output directory
847 measuredJetSpectrumLocal->SetNameTitle(Form("InputSpectrum_%s", suffix.Data()), Form("input spectrum (measured) %s", suffix.Data()));
848 measuredJetSpectrumLocal = ProtectHeap(measuredJetSpectrumLocal);
849 measuredJetSpectrumLocal->SetXTitle("p_{t}^{rec} [GeV/c]");
850 measuredJetSpectrumLocal->Write(); // input spectrum
851 unfoldedLocalBayes->SetNameTitle(Form("UnfoldedSpectrum_%s",suffix.Data()), Form("unfolded spectrum %s", suffix.Data()));
852 unfoldedLocalBayes = ProtectHeap(unfoldedLocalBayes);
853 if(jetFindingEfficiency) unfoldedLocalBayes->Divide(jetFindingEfficiency);
854 unfoldedLocalBayes->Write(); // unfolded spectrum
855 foldedLocalBayes->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("refoldedSpectrum_%s", suffix.Data()));
856 foldedLocalBayes = ProtectHeap(foldedLocalBayes);
857 foldedLocalBayes->Write(); // re-folded spectrum
859 // save more general bookkeeeping histograms to the output directory
860 responseMatrixLocalTransposePrior->SetNameTitle("TransposeResponseMatrix", "Transpose of response matrix, normalize with prior");
861 responseMatrixLocalTransposePrior->SetXTitle("p_{T, jet}^{true} [GeV/c]");
862 responseMatrixLocalTransposePrior->SetYTitle("p_{T, jet}^{rec} [GeV/c]");
863 responseMatrixLocalTransposePrior->Write();
864 priorLocal->SetNameTitle("PriorOriginal", "Prior, original");
865 priorLocal->SetXTitle("p_{t} [GeV/c]");
866 priorLocal = ProtectHeap(priorLocal);
868 resizedResponseLocalNorm = ProtectHeap(resizedResponseLocalNorm);
869 resizedResponseLocalNorm->Write();
872 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));
873 fitStatus->SetBinContent(1, (!strcmp(suffix.Data(), "in")) ? fBayesianIterIn : fBayesianIterOut);
874 fitStatus->GetXaxis()->SetBinLabel(1, (!strcmp(suffix.Data(), "in")) ? "fBayesianIterIn" : "fBayesianIterOut");
877 return unfoldedLocalBayes;
879 //_____________________________________________________________________________
880 TH1D* AliJetFlowTools::FoldSpectrum(
881 const TH1D* measuredJetSpectrum, // truncated raw jets (same binning as pt rec of response)
882 const TH2D* resizedResponse, // response matrix
883 const TH1D* kinematicEfficiency, // kinematic efficiency
884 const TH1D* measuredJetSpectrumTrueBins, // unfolding template: same binning is pt gen of response
885 const TString suffix, // suffix (in or out of plane)
886 const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
888 // simple function to fold the given spectrum with the in-plane and out-of-plane response
890 // 0) for consistency with the other methods, keep the same nomenclature which admittedly is a bit confusing
891 // what is 'unfolded' here, is just a clone of the input spectrum, binned to the 'unfolded' binning
892 TH1D* unfoldedLocal((TH1D*)measuredJetSpectrum->Clone(Form("unfoldedLocal_%s", suffix.Data())));
894 // 1) full response matrix and kinematic efficiency
895 TH2D* resizedResponseLocal = (TH2D*)resizedResponse->Clone(Form("resizedResponseLocal_%s", suffix.Data()));
896 TH1D* kinematicEfficiencyLocal = (TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiencyLocal_%s", suffix.Data()));
898 // step 2) fold the 'unfolded' spectrum and save the ratio measured / refolded
899 TH1D *foldedLocal(fResponseMaker->MultiplyResponseGenerated(unfoldedLocal, resizedResponseLocal,kinematicEfficiencyLocal));
900 foldedLocal->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("Refolded jet spectrum, %s plane", suffix.Data()));
901 unfoldedLocal->SetNameTitle(Form("UnfoldedSpectrum_%s", suffix.Data()), Form("Unfolded jet spectrum, %s plane", suffix.Data()));
903 // step 3) write histograms to file. to ensure that these have unique identifiers on the heap,
904 // objects are cloned using 'ProtectHeap()'
905 TH1D* measuredJetSpectrumLocal((TH1D*)(measuredJetSpectrum->Clone("tempObject")));
906 measuredJetSpectrumLocal->SetNameTitle(Form("InputSpectrum_%s", suffix.Data()), Form("InputSpectrum_%s", suffix.Data()));
907 measuredJetSpectrumLocal = ProtectHeap(measuredJetSpectrumLocal);
908 measuredJetSpectrumLocal->Write();
910 resizedResponseLocal = ProtectHeap(resizedResponseLocal);
911 resizedResponseLocal->Write();
913 unfoldedLocal = ProtectHeap(unfoldedLocal);
914 if(jetFindingEfficiency) unfoldedLocal->Divide(jetFindingEfficiency);
915 unfoldedLocal->Write();
917 foldedLocal = ProtectHeap(foldedLocal);
918 foldedLocal->Write();
920 // return the folded result
923 //_____________________________________________________________________________
924 Bool_t AliJetFlowTools::PrepareForUnfolding(TH1* customIn, TH1* customOut)
926 // prepare for unfolding. check if all the necessary input data is available, if not, retrieve it
927 if(fRawInputProvided) return kTRUE;
929 printf(" AliJetFlowTools::PrepareForUnfolding() fInputList not found \n - Set a list using AliJetFlowTools::SetInputList() \n");
932 if(!fDetectorResponse) printf(" WARNING, no detector response supplied ! May be ok (depending on what you want to do) \n ");
933 // check if the pt bin for true and rec have been set
934 if(!fBinsTrue || !fBinsRec) {
935 printf(" AliJetFlowTools::PrepareForUnfolding() no true or rec bins set, aborting ! \n");
938 if(!fRMSSpectrumIn && fDphiUnfolding) { // initialie the profiles which will hold the RMS values. if binning changes in between unfolding
939 // procedures, these profiles will be nonsensical, user is responsible
940 fRMSSpectrumIn = new TProfile("fRMSSpectrumIn", "fRMSSpectrumIn", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
941 fRMSSpectrumOut = new TProfile("fRMSSpectrumOut", "fRMSSpectrumOut", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
942 fRMSRatio = new TProfile("fRMSRatio", "fRMSRatio", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
945 // clear minuit state to avoid constraining the fit with the results of the previous iteration
946 for(Int_t i(0); i < fPower->GetNpar(); i++) fPower->SetParameter(i, 0.);
948 // extract the spectra
949 TString spectrumName(Form("fHistJetPsi2Pt_%i", fCentralityArray->At(0)));
950 if(fRho0) spectrumName = Form("fHistJetPsi2PtRho0_%i", fCentralityArray->At(0));
951 if(!fInputList->FindObject(spectrumName.Data())) {
952 printf(" Couldn't find spectrum %s ! \n", spectrumName.Data());
956 // get the first scaled spectrum
957 fJetPtDeltaPhi = (TH2D*)fInputList->FindObject(spectrumName.Data());
958 // clone the spectrum on the heap. this is necessary since scale or add change the
959 // contents of the original histogram
960 fJetPtDeltaPhi = ProtectHeap(fJetPtDeltaPhi, kFALSE);
961 fJetPtDeltaPhi->Scale(fCentralityWeights->At(0));
962 printf("Extracted %s wight weight %.2f \n", spectrumName.Data(), fCentralityWeights->At(0));
963 // merge subsequent bins (if any)
964 for(Int_t i(1); i < fCentralityArray->GetSize(); i++) {
965 spectrumName = Form("fHistJetPsi2Pt_%i", fCentralityArray->At(i));
966 printf( " Merging with %s with weight %.4f \n", spectrumName.Data(), fCentralityWeights->At(i));
967 fJetPtDeltaPhi->Add(((TH2D*)fInputList->FindObject(spectrumName.Data())), fCentralityWeights->At(i));
971 if(!fDphiUnfolding) {
972 fSpectrumIn = fJetPtDeltaPhi->ProjectionY(Form("_py_in_%s", spectrumName.Data()), 1, 40, "e");
973 fSpectrumOut = fJetPtDeltaPhi->ProjectionY(Form("_py_out_%s", spectrumName.Data()), 1, 40, "e");
975 fSpectrumIn = fJetPtDeltaPhi->ProjectionY(Form("_py_ina_%s", spectrumName.Data()), 1, 10, "e");
976 fSpectrumIn->Add(fJetPtDeltaPhi->ProjectionY(Form("_py_inb_%s", spectrumName.Data()), 31, 40, "e"));
977 fSpectrumIn = ProtectHeap(fSpectrumIn);
978 // out of plane spectrum
979 fSpectrumOut = fJetPtDeltaPhi->ProjectionY(Form("_py_out_%s", spectrumName.Data()), 11, 30, "e");
980 fSpectrumOut = ProtectHeap(fSpectrumOut);
982 // if a custom input is passed, overwrite existing histograms
983 if(customIn) fSpectrumIn = dynamic_cast<TH1D*>(customIn);
984 if(customOut) fSpectrumOut = dynamic_cast<TH1D*>(customOut);
986 // normalize spectra to event count if requested
987 if(fNormalizeSpectra) {
988 TH1* rho((TH1*)fInputList->FindObject(Form("fHistRho_%i", fCentralityArray->At(0))));
989 rho->Scale(fCentralityWeights->At(0));
990 for(Int_t i(1); i < fCentralityArray->GetSize(); i++) {
991 rho->Add((TH1*)fInputList->FindObject(Form("fHistRho_%i", fCentralityArray->At(i))), fCentralityWeights->At(i));
994 Bool_t normalizeToFullSpectrum = (fEventCount < 0) ? kTRUE : kFALSE;
995 if (normalizeToFullSpectrum) fEventCount = rho->GetEntries();
996 if(fEventCount > 0) {
997 fSpectrumIn->Sumw2(); // necessary for correct error propagation of scale
998 fSpectrumOut->Sumw2();
1000 Double_t error(0); // lots of issues with the errors here ...
1001 for(Int_t i(0); i < fSpectrumIn->GetXaxis()->GetNbins(); i++) {
1002 pt = fSpectrumIn->GetBinContent(1+i)/fEventCount; // normalized count
1003 error = 1./((double)(fEventCount*fEventCount))*fSpectrumIn->GetBinError(1+i)*fSpectrumIn->GetBinError(1+i);
1004 fSpectrumIn->SetBinContent(1+i, pt);
1005 if(pt <= 0 ) fSpectrumIn->SetBinError(1+i, 0.);
1006 if(error > 0) fSpectrumIn->SetBinError(1+i, error);
1007 else fSpectrumIn->SetBinError(1+i, TMath::Sqrt(pt));
1009 for(Int_t i(0); i < fSpectrumOut->GetXaxis()->GetNbins(); i++) {
1010 pt = fSpectrumOut->GetBinContent(1+i)/fEventCount; // normalized count
1011 error = 1./((double)(fEventCount*fEventCount))*fSpectrumOut->GetBinError(1+i)*fSpectrumOut->GetBinError(1+i);
1012 fSpectrumOut->SetBinContent(1+i, pt);
1013 if( pt <= 0) fSpectrumOut->SetBinError(1+i, 0.);
1014 if(error > 0) fSpectrumOut->SetBinError(1+i, error);
1015 else fSpectrumOut->SetBinError(1+i, TMath::Sqrt(pt));
1018 if(normalizeToFullSpectrum) fEventCount = -1;
1020 // extract the delta pt matrices
1021 TString deltaptName("");
1023 deltaptName += (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJ_%i", fCentralityArray->At(0)) : Form("fHistDeltaPtDeltaPhi2_%i", fCentralityArray->At(0));
1025 deltaptName += (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJRho0_%i", fCentralityArray->At(0)) : Form("fHistDeltaPtDeltaPhi2Rho0_%i", fCentralityArray->At(0));
1027 fDeltaPtDeltaPhi = ((TH2D*)fInputList->FindObject(deltaptName.Data()));
1028 if(!fDeltaPtDeltaPhi) {
1029 printf(" Couldn't find delta pt matrix %s ! \n", deltaptName.Data());
1030 printf(" > may be ok, depending no what you want to do < \n");
1031 fRefreshInput = kTRUE;
1035 // clone the distribution on the heap and if requested merge with other centralities
1036 fDeltaPtDeltaPhi = ProtectHeap(fDeltaPtDeltaPhi, kFALSE);
1037 fDeltaPtDeltaPhi->Scale(fCentralityWeights->At(0));
1038 printf("Extracted %s with weight %.2f \n", deltaptName.Data(), fCentralityWeights->At(0));
1039 for(Int_t i(1); i < fCentralityArray->GetSize(); i++) {
1040 deltaptName = (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJ_%i", fCentralityArray->At(i)) : Form("fHistDeltaPtDeltaPhi2_%i", fCentralityArray->At(i));
1041 printf(" Merging with %s with weight %.4f \n", deltaptName.Data(), fCentralityWeights->At(i));
1042 fDeltaPtDeltaPhi->Add((TH2D*)fInputList->FindObject(deltaptName.Data()), fCentralityWeights->At(i));
1045 // in plane delta pt distribution
1046 if(!fDphiUnfolding) {
1047 fDptInDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_in_%s", deltaptName.Data()), 1, 40, "e");
1048 fDptOutDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_out_%s", deltaptName.Data()), 1, 40, "e");
1050 fDptInDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_ina_%s", deltaptName.Data()), 1, 10, "e");
1051 fDptInDist->Add(fDeltaPtDeltaPhi->ProjectionY(Form("_py_inb_%s", deltaptName.Data()), 31, 40, "e"));
1052 // out of plane delta pt distribution
1053 fDptOutDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_out_%s", deltaptName.Data()), 11, 30, "e");
1054 fDptInDist = ProtectHeap(fDptInDist);
1055 fDptOutDist = ProtectHeap(fDptOutDist);
1056 // TODO get dpt response matrix from ConstructDPtResponseFromTH1D
1059 // create a rec - true smeared response matrix
1060 TMatrixD* rfIn = new TMatrixD(-50, 249, -50, 249);
1061 for(Int_t j(-50); j < 250; j++) { // loop on pt true slices j
1062 Bool_t skip = kFALSE;
1063 for(Int_t k(-50); k < 250; k++) { // loop on pt gen slices k
1064 (*rfIn)(k, j) = (skip) ? 0. : fDptInDist->GetBinContent(fDptInDist->GetXaxis()->FindBin(k-j));
1065 if(fAvoidRoundingError && k > j && TMath::AreEqualAbs(fDptInDist->GetBinContent(fDptInDist->GetXaxis()->FindBin(k-j)), 0, 1e-8)) skip = kTRUE;
1068 TMatrixD* rfOut = new TMatrixD(-50, 249, -50, 249);
1069 for(Int_t j(-50); j < 250; j++) { // loop on pt true slices j
1070 Bool_t skip = kFALSE;
1071 for(Int_t k(-50); k < 250; k++) { // loop on pt gen slices k
1072 (*rfOut)(k, j) = (skip) ? 0. : fDptOutDist->GetBinContent(fDptOutDist->GetXaxis()->FindBin(k-j));
1073 if(fAvoidRoundingError && k > j && TMath::AreEqualAbs(fDptOutDist->GetBinContent(fDptOutDist->GetXaxis()->FindBin(k-j)), 0, 1e-8)) skip = kTRUE;
1076 fDptIn = new TH2D(*rfIn);
1077 fDptIn->SetNameTitle(Form("dpt_response_INPLANE_%i", fCentralityArray->At(0)), Form("dpt_response_INPLANE_%i", fCentralityArray->At(0)));
1078 fDptIn->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
1079 fDptIn->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
1080 fDptIn = ProtectHeap(fDptIn);
1081 fDptOut = new TH2D(*rfOut);
1082 fDptOut->SetNameTitle(Form("dpt_response_OUTOFPLANE_%i", fCentralityArray->At(0)), Form("dpt_response_OUTOFPLANE_%i", fCentralityArray->At(0)));
1083 fDptOut->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
1084 fDptOut->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
1085 fDptOut = ProtectHeap(fDptOut);
1087 fRefreshInput = kTRUE; // force cloning of the input
1090 //_____________________________________________________________________________
1091 Bool_t AliJetFlowTools::PrepareForUnfolding(Int_t low, Int_t up) {
1092 // prepare for unfoldingUA - more robust method to extract input spectra from file
1093 // will replace PrepareForUnfolding eventually (09012014)
1095 printf(" AliJetFlowTools::PrepareForUnfolding() fInputList not found \n - Set a list using AliJetFlowTools::SetInputList() \n");
1098 if(!fDetectorResponse) printf(" WARNING, no detector response supplied ! May be ok (depending on what you want to do) \n ");
1099 // check if the pt bin for true and rec have been set
1100 if(!fBinsTrue || !fBinsRec) {
1101 printf(" AliJetFlowTools::PrepareForUnfolding() no true or rec bins set, aborting ! \n");
1105 // clear minuit state to avoid constraining the fit with the results of the previous iteration
1106 for(Int_t i(0); i < fPower->GetNpar(); i++) fPower->SetParameter(i, 0.);
1108 // extract the spectra
1109 TString spectrumName(Form("fHistJetPsi2Pt_%i", fCentralityArray->At(0)));
1110 if(fRho0) spectrumName = Form("fHistJetPsi2PtRho0_%i", fCentralityArray->At(0));
1111 fJetPtDeltaPhi = ((TH2D*)fInputList->FindObject(spectrumName.Data()));
1112 if(!fJetPtDeltaPhi) {
1113 printf(" Couldn't find spectrum %s ! \n", spectrumName.Data());
1116 if(fCentralityArray) {
1117 for(Int_t i(1); i < fCentralityArray->GetSize(); i++) {
1118 spectrumName = Form("fHistJetPsi2Pt_%i", fCentralityArray->At(i));
1119 fJetPtDeltaPhi->Add(((TH2D*)fInputList->FindObject(spectrumName.Data())));
1122 fJetPtDeltaPhi = ProtectHeap(fJetPtDeltaPhi, kFALSE);
1123 // in plane spectrum
1124 fSpectrumIn = fJetPtDeltaPhi->ProjectionY(Form("_py_in_%s", spectrumName.Data()), low, up, "e");
1125 // extract the delta pt matrices
1126 TString deltaptName("");
1128 deltaptName += (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJ_%i", fCentralityArray->At(0)) : Form("fHistDeltaPtDeltaPhi2_%i", fCentralityArray->At(0));
1130 deltaptName += (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJRho0_%i", fCentralityArray->At(0)) : Form("fHistDeltaPtDeltaPhi2Rho0_%i", fCentralityArray->At(0));
1132 fDeltaPtDeltaPhi = ((TH2D*)fInputList->FindObject(deltaptName.Data()));
1133 if(!fDeltaPtDeltaPhi) {
1134 printf(" Couldn't find delta pt matrix %s ! \n", deltaptName.Data());
1135 printf(" > may be ok, depending no what you want to do < \n");
1136 fRefreshInput = kTRUE;
1139 if(fCentralityArray) {
1140 for(Int_t i(1); i < fCentralityArray->GetSize(); i++) {
1141 deltaptName += (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJ_%i", fCentralityArray->At(i)) : Form("fHistDeltaPtDeltaPhi2_%i", fCentralityArray->At(i));
1142 fDeltaPtDeltaPhi->Add(((TH2D*)fInputList->FindObject(deltaptName.Data())));
1146 fDeltaPtDeltaPhi = ProtectHeap(fDeltaPtDeltaPhi, kFALSE);
1147 // in plane delta pt distribution
1148 fDptInDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_in_%s", deltaptName.Data()), low, up, "e");
1149 // create a rec - true smeared response matrix
1150 TMatrixD* rfIn = new TMatrixD(-50, 249, -50, 249);
1151 for(Int_t j(-50); j < 250; j++) { // loop on pt true slices j
1152 Bool_t skip = kFALSE;
1153 for(Int_t k(-50); k < 250; k++) { // loop on pt gen slices k
1154 (*rfIn)(k, j) = (skip) ? 0. : fDptInDist->GetBinContent(fDptInDist->GetXaxis()->FindBin(k-j));
1155 if(fAvoidRoundingError && k > j && TMath::AreEqualAbs(fDptInDist->GetBinContent(fDptInDist->GetXaxis()->FindBin(k-j)), 0, 1e-8)) skip = kTRUE;
1158 fDptIn = new TH2D(*rfIn);
1159 fDptIn->SetNameTitle(Form("dpt_response_INPLANE_%i", fCentralityArray->At(0)), Form("dpt_response_INPLANE_%i", fCentralityArray->At(0)));
1160 fDptIn->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
1161 fDptIn->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
1162 fDptIn = ProtectHeap(fDptIn);
1166 //_____________________________________________________________________________
1167 TH1D* AliJetFlowTools::GetPrior(
1168 const TH1D* measuredJetSpectrum, // jet pt in pt rec bins
1169 const TH2D* resizedResponse, // full response matrix, normalized in slides of pt true
1170 const TH1D* kinematicEfficiency, // kinematic efficiency
1171 const TH1D* measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
1172 const TString suffix, // suffix (in, out)
1173 const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
1175 // 1) get a prior for unfolding.
1176 // this can be either an unfolded spectrum from e.g. chi2 unfolding or the measured spectrum
1177 TH1D* unfolded(0x0);
1178 TDirectoryFile* dirOut = new TDirectoryFile(Form("Prior_%s___%s", suffix.Data(), fActiveString.Data()), Form("Prior_%s___%s", suffix.Data(), fActiveString.Data()));
1180 switch (fPrior) { // select the prior for unfolding
1183 printf("> GetPrior:: FATAL ERROR! TF1 prior requested but prior has not been set ! < \n");
1188 case kPriorPythia : {
1190 printf("> GetPrior:: FATAL ERROR! pythia prior requested but prior has not been set ! < \n");
1193 // rebin the given prior to the true spectrum (creates a new histo)
1194 return RebinTH1D(fPriorUser, fBinsTrue, Form("kPriorPythia_%s", suffix.Data()), kFALSE);
1197 TArrayI* placeHolder(0x0);
1198 if(fMergeBinsArray) {
1199 placeHolder = fMergeBinsArray;
1200 fMergeBinsArray = 0x0;
1202 if(fBinsTruePrior && fBinsRecPrior) { // if set, use different binning for the prior
1203 TArrayD* tempArrayTrue(fBinsTrue); // temporarily cache the original binning
1204 fBinsTrue = fBinsTruePrior; // switch binning schemes (will be used in UnfoldSpectrumChi2())
1205 TArrayD* tempArrayRec(fBinsRec);
1206 fBinsRec = fBinsRecPrior;
1207 // for the prior, do not re-bin the output
1208 TH1D* measuredJetSpectrumChi2 = RebinTH1D((!strcmp("in", suffix.Data())) ? fSpectrumIn : fSpectrumOut, fBinsRec, TString("resized_chi2"), kFALSE);
1209 TH1D* measuredJetSpectrumTrueBinsChi2 = RebinTH1D((!strcmp("in", suffix.Data())) ? fSpectrumIn : fSpectrumOut, fBinsTruePrior, TString("out"), kFALSE);
1210 TH2D* resizedResponseChi2(RebinTH2D((!strcmp("in", suffix.Data())) ? fFullResponseIn : fFullResponseOut,fBinsTruePrior, fBinsRec, TString("chi2")));
1211 TH1D* kinematicEfficiencyChi2(resizedResponseChi2->ProjectionX());
1212 kinematicEfficiencyChi2->SetNameTitle("kin_eff_chi2","kin_eff_chi2");
1213 for(Int_t i(0); i < kinematicEfficiencyChi2->GetXaxis()->GetNbins(); i++) kinematicEfficiencyChi2->SetBinError(1+i, 0.);
1214 unfolded= UnfoldSpectrumChi2(
1215 measuredJetSpectrumChi2,
1216 resizedResponseChi2,
1217 kinematicEfficiencyChi2,
1218 measuredJetSpectrumTrueBinsChi2, // prior for chi2 unfolding (measured)
1219 TString(Form("prior_%s", suffix.Data())));
1221 printf(" > GetPrior:: panic, couldn't get prior from Chi2 unfolding! \n");
1222 printf(" probably Chi2 unfolding did not converge < \n");
1223 if(placeHolder) fMergeBinsArray = placeHolder;
1226 fBinsTrue = tempArrayTrue; // reset bins borders
1227 fBinsRec = tempArrayRec;
1228 // if the chi2 prior has a different binning, rebin to the true binning for the unfolding
1229 unfolded = RebinTH1D(unfolded, fBinsTrue, TString(Form("unfoldedChi2Prior_%s", suffix.Data()))); // rebin unfolded
1231 unfolded = UnfoldSpectrumChi2(
1232 measuredJetSpectrum,
1234 kinematicEfficiency,
1235 measuredJetSpectrumTrueBins, // prior for chi2 unfolding (measured)
1236 TString(Form("prior_%s", suffix.Data())));
1238 printf(" > GetPrior:: panic, couldn't get prior from Chi2 unfolding! \n");
1239 printf(" probably Chi2 unfolding did not converge < \n");
1240 if(placeHolder) fMergeBinsArray = placeHolder;
1243 if(placeHolder) fMergeBinsArray = placeHolder;
1248 case kPriorMeasured : {
1249 unfolded = (TH1D*)measuredJetSpectrumTrueBins->Clone(Form("kPriorMeasured_%s", suffix.Data())); // copy template to unfolded to use as prior
1253 // it can be important that the prior is smooth, this can be achieved by
1254 // extrapolating the spectrum with a fitted power law when bins are sparsely filed
1255 if(jetFindingEfficiency) unfolded->Divide(jetFindingEfficiency);
1256 TH1D *priorLocal((TH1D*)unfolded->Clone(Form("priorUnfolded_%s", suffix.Data())));
1257 if(fSmoothenPrior) priorLocal = SmoothenPrior(priorLocal, fPower, fFitMin, fFitMax, fFitStart, kTRUE, fSmoothenCounts);
1260 //_____________________________________________________________________________
1261 TH1D* AliJetFlowTools::ResizeXaxisTH1D(TH1D* histo, Int_t low, Int_t up, TString suffix) {
1262 // resize the x-axis of a th1d
1264 printf(" > ResizeXaxisTH!D:: fatal error, NULL pointer passed < \n");
1267 // see how many bins we need to copy
1268 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);
1269 // low is the bin number of the first new bin
1270 Int_t l = histo->GetXaxis()->FindBin(low);
1272 Double_t _x(0), _xx(0);
1273 for(Int_t i(0); i < up-low; i++) {
1274 _x = histo->GetBinContent(l+i);
1275 _xx=histo->GetBinError(l+i);
1276 resized->SetBinContent(i+1, _x);
1277 resized->SetBinError(i+1, _xx);
1281 //_____________________________________________________________________________
1282 TH2D* AliJetFlowTools::ResizeYaxisTH2D(TH2D* histo, TArrayD* x, TArrayD* y, TString suffix) {
1283 // resize the y-axis of a th2d
1285 printf(" > ResizeYaxisTH2D:: fatal error, NULL pointer passed < \n");
1288 // see how many bins we need to copy
1289 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());
1290 // assume only the y-axis has changed
1291 // low is the bin number of the first new bin
1292 Int_t low = histo->GetYaxis()->FindBin(y->At(0));
1294 Double_t _x(0), _xx(0);
1295 for(Int_t i(0); i < x->GetSize(); i++) {
1296 for(Int_t j(0); j < y->GetSize(); j++) {
1297 _x = histo->GetBinContent(i, low+j);
1298 _xx=histo->GetBinError(i, low+1+j);
1299 resized->SetBinContent(i, j, _x);
1300 resized->SetBinError(i, j, _xx);
1305 //_____________________________________________________________________________
1306 TH2D* AliJetFlowTools::NormalizeTH2D(TH2D* histo, Bool_t noError) {
1307 // general method to normalize all vertical slices of a th2 to unity
1308 // i.e. get a probability matrix
1310 printf(" > NormalizeTH2D:: NULL pointer passed, returning NULL < \n");
1313 Int_t binsX = histo->GetXaxis()->GetNbins();
1314 Int_t binsY = histo->GetYaxis()->GetNbins();
1316 // normalize all slices in x
1317 for(Int_t i(0); i < binsX; i++) { // for each vertical slice
1318 Double_t weight = 0;
1319 for(Int_t j(0); j < binsY; j++) { // loop over all the horizontal components
1320 weight+=histo->GetBinContent(i+1, j+1);
1321 } // now we know the total weight
1322 for(Int_t j(0); j < binsY; j++) {
1323 if (weight <= 0 ) continue;
1324 histo->SetBinContent(1+i, j+1, histo->GetBinContent(1+i, j+1)/weight);
1325 if(noError) histo->SetBinError( 1+i, j+1, 0.);
1326 else histo->SetBinError( 1+i, j+1, histo->GetBinError( 1+i, j+1)/weight);
1331 //_____________________________________________________________________________
1332 TH1* AliJetFlowTools::Bootstrap(TH1* hist, Bool_t kill) {
1334 // the returned histogram is new, the original is deleted from the heap if kill is true
1336 printf(" > Bootstrap:: fatal error,NULL pointer passed! \n");
1339 else printf(" > Bootstrap:: resampling, may take some time \n");
1340 // clone input histo
1341 TH1* bootstrapped((TH1*)(hist->Clone(Form("%s_bootstrapped", hist->GetName()))));
1342 bootstrapped->Reset();
1344 /* OLD method - slightly underestimates fluctuations
1345 // reset the content
1346 bootstrapped->Reset();
1347 // resample the input histogram
1348 for(Int_t i(0); i < hist->GetEntries(); i++) bootstrapped->Fill(hist->GetRandom()); */
1351 Double_t mean(0), sigma(0);
1352 Int_t sampledMean(0), entries(0);
1354 for(Int_t i(0); i < hist->GetXaxis()->GetNbins(); i++) {
1355 // for each bin, get the value
1356 mean = hist->GetBinContent(i+1);
1357 sigma = hist->GetBinError(i+1);
1359 sampledMean = TMath::Nint(gRandom->Gaus(mean, sigma));
1360 printf(" sampled %i from original number %.2f \n", sampledMean, mean);
1361 // set the new bin content
1362 bootstrapped->SetBinContent(i+1, sampledMean);
1363 if(sampledMean > 0) bootstrapped->SetBinError(i+1, TMath::Sqrt(sampledMean));
1364 entries += sampledMean;
1366 printf(" Done bootstrapping, setting number of entries to %i \n", entries);
1367 bootstrapped->SetEntries((double)entries);
1370 // if requested kill input histo
1371 if(kill) delete hist;
1372 // return resampled histogram
1373 return bootstrapped;
1375 //_____________________________________________________________________________
1376 TH1D* AliJetFlowTools::RebinTH1D(TH1D* histo, TArrayD* bins, TString suffix, Bool_t kill) {
1377 // return a TH1D with the supplied histogram rebinned to the supplied bins
1378 // the returned histogram is new, the original is deleted from the heap if kill is true
1379 if(!histo || !bins) {
1380 printf(" > RebinTH1D:: fatal error, NULL pointer passed < \n");
1383 // create the output histo
1384 TString name = histo->GetName();
1387 TH1D* rebinned = 0x0;
1388 // check if the histogram is normalized. if so, fall back to ROOT style rebinning
1389 // if not, rebin manually
1390 if(histo->GetBinContent(1) > 1 ) {
1391 rebinned = new TH1D(name.Data(), name.Data(), bins->GetSize()-1, bins->GetArray());
1392 for(Int_t i(0); i < histo->GetXaxis()->GetNbins(); i++) {
1393 // loop over the bins of the old histo and fill the new one with its data
1394 rebinned->Fill(histo->GetBinCenter(i+1), histo->GetBinContent(i+1));
1396 } else rebinned = reinterpret_cast<TH1D*>(histo->Rebin(bins->GetSize()-1, name.Data(), bins->GetArray()));
1397 if(kill) delete histo;
1400 //_____________________________________________________________________________
1401 TH2D* AliJetFlowTools::RebinTH2D(TH2D* rebinMe, TArrayD* binsTrue, TArrayD* binsRec, TString suffix) {
1402 // weighted rebinning of a th2d, implementation for function call to AliAnaChargedJetResponseMaker
1403 // not static as it is just a wrapper for the response maker object
1404 if(!fResponseMaker || !binsTrue || !binsRec) {
1405 printf(" > RebinTH2D:: function called with NULL arguments < \n");
1408 TString name(Form("%s_%s", rebinMe->GetName(), suffix.Data()));
1409 return (TH2D*)fResponseMaker->MakeResponseMatrixRebin(rebinMe, (TH2*)(new TH2D(name.Data(), name.Data(), binsTrue->GetSize()-1, binsTrue->GetArray(), binsRec->GetSize()-1, binsRec->GetArray())), kTRUE);
1411 //_____________________________________________________________________________
1412 TH2D* AliJetFlowTools::MatrixMultiplication(TH2D* a, TH2D* b, TString name)
1414 // multiply two matrices
1415 if (a->GetNbinsX() != b->GetNbinsY()) return 0x0;
1416 TH2D* c = (TH2D*)a->Clone("c");
1417 for (Int_t y1 = 1; y1 <= a->GetNbinsY(); y1++) {
1418 for (Int_t x2 = 1; x2 <= b->GetNbinsX(); x2++) {
1420 for (Int_t x1 = 1; x1 <= a->GetNbinsX(); x1++) {
1422 val += a->GetBinContent(x1, y1) * b->GetBinContent(x2, y2);
1424 c->SetBinContent(x2, y1, val);
1425 c->SetBinError(x2, y1, 0.);
1428 if(strcmp(name.Data(), "")) c->SetNameTitle(name.Data(), name.Data());
1431 //_____________________________________________________________________________
1432 TH1D* AliJetFlowTools::NormalizeTH1D(TH1D* histo, Double_t scale)
1434 // normalize a th1d to a certain scale
1436 Double_t integral = histo->Integral()*scale;
1437 if (integral > 0 && scale == 1.) histo->Scale(1./integral, "width");
1438 else if (scale != 1.) histo->Scale(1./scale, "width");
1439 else printf(" > Histogram integral < 0, cannot normalize \n");
1442 //_____________________________________________________________________________
1443 TH1D* AliJetFlowTools::MergeSpectrumBins(TArrayI* bins, TH1D* spectrum, TH2D* corr)
1445 // merge a spectrum histogram taking into account the correlation terms
1446 if(!(bins&&spectrum)) {
1447 printf(" > NULL pointer passed as argument in MergeSpectrumBins ! < \n");
1450 Double_t sum(0), error(0), pearson(0);
1451 // take the sum of the bin content
1452 sum += spectrum->GetBinContent(bins->At(0));
1453 sum += spectrum->GetBinContent(bins->At(1));
1454 // quadratically sum the errors
1455 error += TMath::Power(spectrum->GetBinError(bins->At(0)), 2);
1456 error += TMath::Power(spectrum->GetBinError(bins->At(1)), 2);
1457 // add the covariance term
1458 pearson = corr->GetBinContent(bins->At(0), bins->At(1));
1460 printf(" > PANIC ! something is wrong with the covariance matrix, assuming full correlation ! < \n ");
1463 error += 2.*spectrum->GetBinError(bins->At(0))*spectrum->GetBinError(bins->At(1))*pearson;
1464 spectrum->SetBinContent(1, sum);
1465 if(error <= 0) return spectrum;
1466 spectrum->SetBinError(1, TMath::Sqrt(error));
1467 printf(" > sum is %.2f \t error is %.8f < \n", sum, error);
1468 printf(" > REPLACING BIN CONTENT OF FIRST BIN (%i) WITH MERGED BINS (%i) and (%i) < \n", 1, bins->At(0), bins->At(1));
1471 //_____________________________________________________________________________
1472 TMatrixD* AliJetFlowTools::CalculatePearsonCoefficients(TMatrixD* covarianceMatrix)
1474 // Calculate pearson coefficients from covariance matrix
1475 TMatrixD *pearsonCoefficients((TMatrixD*)covarianceMatrix->Clone("pearsonCoefficients"));
1476 Int_t nrows(covarianceMatrix->GetNrows()), ncols(covarianceMatrix->GetNcols());
1477 Double_t pearson(0.);
1478 if(nrows==0 && ncols==0) return 0x0;
1479 for(Int_t row = 0; row < nrows; row++) {
1480 for(Int_t col = 0; col<ncols; col++) {
1481 if((*covarianceMatrix)(row,row)!=0. && (*covarianceMatrix)(col,col)!=0.) pearson = (*covarianceMatrix)(row,col)/TMath::Sqrt((*covarianceMatrix)(row,row)*(*covarianceMatrix)(col,col));
1482 (*pearsonCoefficients)(row,col) = pearson;
1485 return pearsonCoefficients;
1487 //_____________________________________________________________________________
1488 TH1D* AliJetFlowTools::SmoothenPrior(TH1D* spectrum, TF1* function, Double_t min, Double_t max, Double_t start, Bool_t kill, Bool_t counts) {
1489 // smoothen the spectrum using a user defined function
1490 // returns a clone of the original spectrum if fitting failed
1491 // if kill is kTRUE the input spectrum will be deleted from the heap
1492 // if 'count' is selected, bins are filled with integers (necessary if the
1493 // histogram is interpreted in a routine which accepts only counts)
1494 if(!spectrum || !function) return 0x0;
1495 if(start > max) printf(" > cannot extrapolate fit beyond fit range ! < " );
1496 TH1D* temp = (TH1D*)spectrum->Clone(Form("%s_smoothened", spectrum->GetName()));
1497 temp->Sumw2(); // if already called on the original, this will give off a warning but do nothing
1498 TFitResultPtr r = temp->Fit(function, "", "", min, max);
1499 if((int)r == 0) { // MINUIT status
1500 for(Int_t i(0); i < temp->GetNbinsX() + 1; i++) {
1501 if(temp->GetBinCenter(i) > start) { // from this pt value use extrapolation
1502 (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));
1503 if(temp->GetBinContent(i) > 0) temp->SetBinError(i, TMath::Sqrt(temp->GetBinContent(i)));
1507 if(kill) delete spectrum;
1510 //_____________________________________________________________________________
1511 void AliJetFlowTools::Style(Bool_t legacy)
1513 // set global style for your current aliroot session
1515 // legacy style is pleasing to the eye, default is the formal ALICE style
1517 gStyle->SetCanvasColor(-1);
1518 gStyle->SetPadColor(-1);
1519 gStyle->SetFrameFillColor(-1);
1520 gStyle->SetHistFillColor(-1);
1521 gStyle->SetTitleFillColor(-1);
1522 gStyle->SetFillColor(-1);
1523 gStyle->SetFillStyle(4000);
1524 gStyle->SetStatStyle(0);
1525 gStyle->SetTitleStyle(0);
1526 gStyle->SetCanvasBorderSize(0);
1527 gStyle->SetFrameBorderSize(0);
1528 gStyle->SetLegendBorderSize(0);
1529 gStyle->SetStatBorderSize(0);
1530 gStyle->SetTitleBorderSize(0);
1532 gStyle->Reset("Plain");
1533 gStyle->SetOptTitle(0);
1534 gStyle->SetOptStat(0);
1535 gStyle->SetPalette(1);
1536 gStyle->SetCanvasColor(10);
1537 gStyle->SetCanvasBorderMode(0);
1538 gStyle->SetFrameLineWidth(1);
1539 gStyle->SetFrameFillColor(kWhite);
1540 gStyle->SetPadColor(10);
1541 gStyle->SetPadTickX(1);
1542 gStyle->SetPadTickY(1);
1543 gStyle->SetPadBottomMargin(0.15);
1544 gStyle->SetPadLeftMargin(0.15);
1545 gStyle->SetHistLineWidth(1);
1546 gStyle->SetHistLineColor(kRed);
1547 gStyle->SetFuncWidth(2);
1548 gStyle->SetFuncColor(kGreen);
1549 gStyle->SetLineWidth(2);
1550 gStyle->SetLabelSize(0.045,"xyz");
1551 gStyle->SetLabelOffset(0.01,"y");
1552 gStyle->SetLabelOffset(0.01,"x");
1553 gStyle->SetLabelColor(kBlack,"xyz");
1554 gStyle->SetTitleSize(0.05,"xyz");
1555 gStyle->SetTitleOffset(1.25,"y");
1556 gStyle->SetTitleOffset(1.2,"x");
1557 gStyle->SetTitleFillColor(kWhite);
1558 gStyle->SetTextSizePixels(26);
1559 gStyle->SetTextFont(42);
1560 gStyle->SetLegendBorderSize(0);
1561 gStyle->SetLegendFillColor(kWhite);
1562 gStyle->SetLegendFont(42);
1565 //_____________________________________________________________________________
1566 void AliJetFlowTools::Style(TCanvas* c, TString style)
1568 // set a default style for a canvas
1569 if(!strcmp(style.Data(), "PEARSON")) {
1570 printf(" > style PEARSON canvas < \n");
1571 gStyle->SetOptStat(0);
1576 } else if(!strcmp(style.Data(), "SPECTRUM")) {
1577 printf(" > style SPECTRUM canvas < \n");
1578 gStyle->SetOptStat(0);
1584 } else printf(" > Style called with unknown option %s \n returning < \n", style.Data());
1586 //_____________________________________________________________________________
1587 void AliJetFlowTools::Style(TVirtualPad* c, TString style, Bool_t legacy)
1589 // set a default style for a canva
1592 c->SetLeftMargin(.25);
1593 c->SetBottomMargin(.25);
1596 if(!strcmp(style.Data(), "PEARSON")) {
1597 printf(" > style PEARSON pad < \n");
1598 gStyle->SetOptStat(0);
1603 } else if(!strcmp(style.Data(), "SPECTRUM")) {
1604 printf(" > style SPECTRUM pad < \n");
1605 gStyle->SetOptStat(0);
1611 } else if (!strcmp(style.Data(), "GRID")) {
1612 printf(" > style GRID pad < \n");
1613 gStyle->SetOptStat(0);
1617 } else printf(" > Style called with unknown option %s \n returning < \n", style.Data());
1619 //_____________________________________________________________________________
1620 void AliJetFlowTools::Style(TLegend* l)
1622 // set a default style for a legend
1624 l->SetBorderSize(0);
1625 if(gStyle) l->SetTextSize(gStyle->GetTextSize()*.08);
1627 //_____________________________________________________________________________
1628 void AliJetFlowTools::Style(TH1* h, EColor col, histoType type, Bool_t legacy)
1631 h->GetYaxis()->SetNdivisions(505);
1632 h->SetLineColor(col);
1633 h->SetMarkerColor(col);
1635 h->SetMarkerSize(1);
1638 h->GetYaxis()->SetLabelSize(0.05);
1639 h->GetXaxis()->SetLabelSize(0.05);
1640 h->GetYaxis()->SetTitleOffset(1.5);
1641 h->GetXaxis()->SetTitleOffset(1.5);
1642 h->GetYaxis()->SetTitleSize(.05);
1643 h->GetXaxis()->SetTitleSize(.05);
1646 case kInPlaneSpectrum : {
1647 h->SetTitle("IN PLANE");
1648 h->GetXaxis()->SetTitle("#it{p}_{T}^{ch, jet} (GeV/#it{c})");
1649 h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1651 case kOutPlaneSpectrum : {
1652 h->SetTitle("OUT OF PLANE");
1653 h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1654 h->GetXaxis()->SetTitle("#it{p}_{T, jet}^{ch} (GeV/#it{c})");
1656 case kUnfoldedSpectrum : {
1657 h->SetTitle("UNFOLDED");
1658 h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1659 h->GetXaxis()->SetTitle("#it{p}_{T, jet}^{ch} (GeV/#it{c})");
1661 case kFoldedSpectrum : {
1662 h->SetTitle("FOLDED");
1663 h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1664 h->GetXaxis()->SetTitle("#it{p}_{T, jet}^{ch} (GeV/#it{c})");
1666 case kMeasuredSpectrum : {
1667 h->SetTitle("MEASURED");
1668 h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1669 h->GetXaxis()->SetTitle("#it{p}_{T, jet}^{cht} (GeV/#it{c})");
1672 h->SetFillColor(col);
1674 h->GetXaxis()->SetTitle("#it{p}_{T, jet}^{ch} (GeV/#it{c})");
1675 h->SetBarOffset(0.2);
1678 h->SetMarkerStyle(8);
1679 h->SetMarkerSize(1);
1682 h->GetYaxis()->SetTitle("[counts]");
1683 h->GetXaxis()->SetTitle("#Delta #phi");
1688 //_____________________________________________________________________________
1689 void AliJetFlowTools::Style(TGraph* h, EColor col, histoType type, Bool_t legacy)
1692 h->GetYaxis()->SetNdivisions(505);
1693 h->SetLineColor(col);
1694 h->SetMarkerColor(col);
1696 h->SetMarkerSize(1);
1698 h->SetFillColor(kCyan);
1700 h->GetYaxis()->SetLabelSize(0.05);
1701 h->GetXaxis()->SetLabelSize(0.05);
1702 h->GetYaxis()->SetTitleOffset(1.6);
1703 h->GetXaxis()->SetTitleOffset(1.6);
1704 h->GetYaxis()->SetTitleSize(.05);
1705 h->GetXaxis()->SetTitleSize(.05);
1707 h->GetXaxis()->SetTitle("#it{p}_{T, jet}^{ch} (GeV/#it{c})");
1709 case kInPlaneSpectrum : {
1710 h->SetTitle("IN PLANE");
1711 h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1713 case kOutPlaneSpectrum : {
1714 h->SetTitle("OUT OF PLANE");
1715 h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1717 case kUnfoldedSpectrum : {
1718 h->SetTitle("UNFOLDED");
1719 h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1721 case kFoldedSpectrum : {
1722 h->SetTitle("FOLDED");
1723 h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1725 case kMeasuredSpectrum : {
1726 h->SetTitle("MEASURED");
1727 h->GetYaxis()->SetTitle("#frac{d#it{N}}{d#it{p}_{T}}");
1730 // h->GetYaxis()->SetTitle("#frac{d#it{N_{in plane}^{jet}}}{d#it{p}_{T}} / #frac{d#it{N_{out of plane}^{jet}}}{d#it{p}_{T}}");
1731 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))");
1734 // h->GetYaxis()->SetTitle("#it{v}_{2} = #frac{1}{#it{R}} #frac{#pi}{4} #frac{#it{N_{in plane}} - #it{N_{out of plane}}}{#it{N_{in plane}} + #it{N_{out of plane}}}");
1735 h->GetYaxis()->SetTitle("#it{v}_{2}^{ch, jet} \{EP, |#Delta#eta|>0.9 \} ");
1736 h->GetYaxis()->SetRangeUser(-.5, 1.);
1737 h->SetMarkerStyle(8);
1738 h->SetMarkerSize(1);
1743 //_____________________________________________________________________________
1744 void AliJetFlowTools::GetNominalValues(
1745 TH1D*& ratio, // pointer reference, output of this function
1746 TGraphErrors*& v2, // pointer reference, as output of this function
1750 TString outFile) const
1752 // pass clones of the nominal points and nominal v2 values
1753 if(fOutputFile && !fOutputFile->IsZombie()) fOutputFile->Close(); // if for some weird reason the unfolding output is still mutable
1754 TFile* readMe(new TFile(inFile.Data(), "READ")); // open unfolding output read-only
1755 if(readMe->IsZombie()) {
1756 printf(" > Fatal error, couldn't read %s for post processing ! < \n", inFile.Data());
1759 printf("\n\n\n\t\t GetNominalValues \n > Recovered the following file structure : \n <");
1761 TFile* output(new TFile(outFile.Data(), "RECREATE")); // create new output file
1762 // get some placeholders, have to be initialized but will be deleted
1763 ratio = new TH1D("nominal", "nominal", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
1764 TH1D* nominalIn(new TH1D("nominal in", "nominal in", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1765 TH1D* nominalOut(new TH1D("nominal out", "nominal out", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1766 Int_t iIn[] = {in->At(0), in->At(0)}; // first value is the nominal point
1767 Int_t iOut[] = {out->At(0), out->At(0)};
1769 // call the functions and set the relevant pointer references
1771 DoIntermediateSystematics(
1772 new TArrayI(2, iIn),
1773 new TArrayI(2, iOut),
1774 dud, dud, dud, dud, dud, dud,
1775 ratio, // pointer reference, output of this function
1780 fBinsTrue->At(fBinsTrue->GetSize()-1),
1783 v2 = GetV2(nominalIn, nominalOut, fEventPlaneRes, "nominal v_{2}");
1785 // close the open files, reclaim ownership of histograms which are necessary outside of the file scope
1786 ratio->SetDirectory(0); // disassociate from current gDirectory
1789 //_____________________________________________________________________________
1790 void AliJetFlowTools::GetCorrelatedUncertainty(
1791 TGraphAsymmErrors*& corrRatio, // correlated uncertainty pointer reference
1792 TGraphAsymmErrors*& corrV2, // correlated uncertainty pointer reference
1793 TArrayI* variationsIn, // variantions in plane
1794 TArrayI* variationsOut, // variantions out of plane
1795 Bool_t sym, // treat as symmmetric
1796 TArrayI* variations2ndIn, // second source of variations
1797 TArrayI* variations2ndOut, // second source of variations
1798 Bool_t sym2nd, // treat as symmetric
1799 TString type, // type of uncertaitny
1801 Int_t columns, // divide the output canvasses in this many columns
1802 Float_t rangeLow, // lower pt range
1803 Float_t rangeUp, // upper pt range
1804 Float_t corr, // correlation strength
1805 TString in, // input file name (created by this unfolding class)
1806 TString out // output file name (which will hold results of the systematic test)
1809 // do full systematics
1810 if(fOutputFile && !fOutputFile->IsZombie()) fOutputFile->Close(); // if for some weird reason the unfolding output is still mutable
1811 TFile* readMe(new TFile(in.Data(), "READ")); // open unfolding output read-only
1812 if(readMe->IsZombie()) {
1813 printf(" > Fatal error, couldn't read %s for post processing ! < \n", in.Data());
1816 printf("\n\n\n\t\t GetCorrelatedUncertainty \n > Recovered the following file structure : \n <");
1818 TFile* output(new TFile(out.Data(), "RECREATE")); // create new output file
1820 // create some null placeholder pointers
1821 TH1D* relativeErrorVariationInLow(0x0);
1822 TH1D* relativeErrorVariationInUp(0x0);
1823 TH1D* relativeErrorVariationOutLow(0x0);
1824 TH1D* relativeErrorVariationOutUp(0x0);
1825 TH1D* relativeError2ndVariationInLow(0x0);
1826 TH1D* relativeError2ndVariationInUp(0x0);
1827 TH1D* relativeError2ndVariationOutLow(0x0);
1828 TH1D* relativeError2ndVariationOutUp(0x0);
1829 TH1D* relativeStatisticalErrorIn(0x0);
1830 TH1D* relativeStatisticalErrorOut(0x0);
1831 // histo for the nominal ratio in / out
1832 TH1D* nominal(new TH1D("ratio in plane, out of plane", "ratio in plane, out of plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1833 TH1D* nominalIn(new TH1D("in plane jet yield", "in plane jet yield", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1834 TH1D* nominalOut(new TH1D("out of plane jet yield", "out of plane jet yield", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1836 // call the functions
1837 if(variationsIn && variationsOut) {
1838 DoIntermediateSystematics(
1841 relativeErrorVariationInUp, // pointer reference
1842 relativeErrorVariationInLow, // pointer reference
1843 relativeErrorVariationOutUp, // pointer reference
1844 relativeErrorVariationOutLow, // pointer reference
1845 relativeStatisticalErrorIn, // pointer reference
1846 relativeStatisticalErrorOut, // pointer reference
1855 if(relativeErrorVariationInUp) {
1856 // canvas with the error from variation strength
1857 TCanvas* relativeErrorVariation(new TCanvas(Form("relativeError_%s", type.Data()), Form("relativeError_%s", type.Data())));
1858 relativeErrorVariation->Divide(2);
1859 relativeErrorVariation->cd(1);
1860 Style(gPad, "GRID");
1861 relativeErrorVariationInUp->DrawCopy("b");
1862 relativeErrorVariationInLow->DrawCopy("same b");
1863 Style(AddLegend(gPad));
1864 relativeErrorVariation->cd(2);
1865 Style(gPad, "GRID");
1866 relativeErrorVariationOutUp->DrawCopy("b");
1867 relativeErrorVariationOutLow->DrawCopy("same b");
1868 SavePadToPDF(relativeErrorVariation);
1869 Style(AddLegend(gPad));
1870 relativeErrorVariation->Write();
1872 // now smoothen the diced response error (as it is expected to be flat)
1873 // this is done by fitting a constant to the diced resonse error histo
1875 TF1* lin = new TF1("lin", "[0]", rangeLow, rangeUp);
1876 relativeErrorVariationInUp->Fit(lin, "L", "", rangeLow, rangeUp);
1877 if(!gMinuit->fISW[1] == 3) printf(" fit is NOT ok ! " );
1878 for(Int_t i(0); i < relativeErrorVariationInUp->GetNbinsX(); i++) {
1879 relativeErrorVariationInUp->SetBinContent(i+1, lin->GetParameter(0));
1881 relativeErrorVariationInLow->Fit(lin, "L", "", rangeLow, rangeUp);
1882 printf(" > Fit over diced resonse, new value for all bins is %.4f < \n ", lin->GetParameter(0));
1883 for(Int_t i(0); i < relativeErrorVariationInUp->GetNbinsX(); i++) {
1884 relativeErrorVariationInLow->SetBinContent(i+1, 0);//lin->GetParameter(0));
1886 relativeErrorVariationOutUp->Fit(lin, "L", "", rangeLow, rangeUp);
1887 printf(" > Fit over diced resonse, new value for all bins is %.4f < \n ", lin->GetParameter(0));
1888 for(Int_t i(0); i < relativeErrorVariationInUp->GetNbinsX(); i++) {
1889 relativeErrorVariationOutUp->SetBinContent(i+1, lin->GetParameter(0));
1891 relativeErrorVariationOutLow->Fit(lin, "L", "", rangeLow, rangeUp);
1892 printf(" > Fit over diced resonse, new value for all bins is %.4f < \n ", lin->GetParameter(0));
1893 for(Int_t i(0); i < relativeErrorVariationInUp->GetNbinsX(); i++) {
1894 relativeErrorVariationOutLow->SetBinContent(i+1, 0);//lin->GetParameter(0));
1898 // call the functions for a second set of systematic sources
1899 if(variations2ndIn && variations2ndOut) {
1900 DoIntermediateSystematics(
1903 relativeError2ndVariationInUp, // pointer reference
1904 relativeError2ndVariationInLow, // pointer reference
1905 relativeError2ndVariationOutUp, // pointer reference
1906 relativeError2ndVariationOutLow, // pointer reference
1907 relativeStatisticalErrorIn, // pointer reference
1908 relativeStatisticalErrorOut, // pointer reference
1917 if(relativeError2ndVariationInUp) {
1918 // canvas with the error from variation strength
1919 TCanvas* relativeError2ndVariation(new TCanvas(Form("relativeError2nd_%s", type2.Data()), Form("relativeError2nd_%s", type2.Data())));
1920 relativeError2ndVariation->Divide(2);
1921 relativeError2ndVariation->cd(1);
1922 Style(gPad, "GRID");
1923 relativeError2ndVariationInUp->DrawCopy("b");
1924 relativeError2ndVariationInLow->DrawCopy("same b");
1925 Style(AddLegend(gPad));
1926 relativeError2ndVariation->cd(2);
1927 Style(gPad, "GRID");
1928 relativeError2ndVariationOutUp->DrawCopy("b");
1929 relativeError2ndVariationOutLow->DrawCopy("same b");
1930 SavePadToPDF(relativeError2ndVariation);
1931 Style(AddLegend(gPad));
1932 relativeError2ndVariation->Write();
1937 // and the placeholder for the final systematic
1938 TH1D* relativeErrorInUp(new TH1D("max correlated uncertainty in plane", "max correlated uncertainty in plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1939 TH1D* relativeErrorOutUp(new TH1D("max correlated uncertainty out of plane", "max correlated uncertainty out of plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1940 TH1D* relativeErrorInLow(new TH1D("min correlated uncertainty in plane", "min correlated uncertainty in plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1941 TH1D* relativeErrorOutLow(new TH1D("min correlated uncertainty out of plane", "min correlated uncertainty out of plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1942 relativeErrorInUp->SetYTitle("relative uncertainty");
1943 relativeErrorOutUp->SetYTitle("relative uncertainty");
1944 relativeErrorInLow->SetYTitle("relative uncertainty");
1945 relativeErrorOutLow->SetYTitle("relative uncertainty");
1947 // merge the correlated errors (FIXME) trivial for one set
1948 Double_t aInUp(0.), bInUp(0.), cInUp(0.), dInUp(0.);
1949 Double_t aOutUp(0.), bOutUp(0.), cOutUp(0.), dOutUp(0.);
1950 Double_t aInLow(0.), bInLow(0.), cInLow(0.), dInLow(0.);
1951 Double_t aOutLow(0.), bOutLow(0.), cOutLow(0.), dOutLow(0.);
1953 for(Int_t b(0); b < fBinsTrue->GetSize()-1; b++) {
1954 // for the upper bound
1955 if(relativeErrorVariationInUp) aInUp = relativeErrorVariationInUp->GetBinContent(b+1);
1956 if(relativeErrorVariationOutUp) aOutUp = relativeErrorVariationOutUp->GetBinContent(b+1);
1957 if(relativeError2ndVariationInUp) bInUp = relativeError2ndVariationInUp->GetBinContent(b+1);
1958 if(relativeError2ndVariationOutUp) bInLow = relativeError2ndVariationOutUp->GetBinContent(b+1);
1959 dInUp = aInUp*aInUp + bInUp*bInUp + cInUp*cInUp;
1960 // for a symmetric first variation
1961 if(sym) dInUp += aInLow*aInLow;
1962 if(dInUp > 0) relativeErrorInUp->SetBinContent(b+1, TMath::Sqrt(dInUp));
1963 dOutUp = aOutUp*aOutUp + bOutUp*bOutUp + cOutUp*cOutUp;
1964 if(sym) dOutUp += aOutLow*aOutLow;
1965 if(dOutUp > 0) relativeErrorOutUp->SetBinContent(b+1, TMath::Sqrt(dOutUp));
1966 // for the lower bound
1967 if(relativeErrorVariationInLow) aInLow = relativeErrorVariationInLow->GetBinContent(b+1);
1968 if(relativeErrorVariationOutLow) aOutLow = relativeErrorVariationOutLow->GetBinContent(b+1);
1969 if(relativeError2ndVariationInLow) bInLow = relativeError2ndVariationInLow->GetBinContent(b+1);
1970 if(relativeError2ndVariationOutLow) bOutLow = relativeError2ndVariationOutLow->GetBinContent(b+1);
1971 dInLow = aInLow*aInLow + bInLow*bInLow + cInLow*cInLow;
1972 if(sym) dInLow += aInUp*aInUp;
1973 if(dInLow > 0) relativeErrorInLow->SetBinContent(b+1, -1*TMath::Sqrt(dInLow));
1974 dOutLow = aOutLow*aOutLow + bOutLow*bOutLow + cOutLow*cOutLow;
1975 if(sym) dOutLow += aOutUp*aOutUp;
1976 if(dOutLow > 0) relativeErrorOutLow->SetBinContent(b+1, -1.*TMath::Sqrt(dOutLow));
1978 // project the estimated errors on the nominal ratio
1980 Double_t* ax = new Double_t[fBinsTrue->GetSize()-1];
1981 Double_t* ay = new Double_t[fBinsTrue->GetSize()-1];
1982 Double_t* axh = new Double_t[fBinsTrue->GetSize()-1];
1983 Double_t* axl = new Double_t[fBinsTrue->GetSize()-1];
1984 Double_t* ayh = new Double_t[fBinsTrue->GetSize()-1];
1985 Double_t* ayl = new Double_t[fBinsTrue->GetSize()-1];
1986 Double_t lowErr(0.), upErr(0.);
1987 for(Int_t i(0); i < fBinsTrue->GetSize()-1; i++) {
1988 // add the in and out of plane errors in quadrature
1989 // propagation is tricky because we should consider two cases:
1990 // [1] the error is uncorrelated, and we propagate upper 1 with lower 2 and vice versa
1991 // [2] the error is correlated - in this case upper 1 should be propagated with upper 2
1992 // as the fluctuations are bound to always to of same sign
1994 lowErr = relativeErrorInLow->GetBinContent(i+1)*relativeErrorInLow->GetBinContent(i+1)+relativeErrorOutUp->GetBinContent(1+i)*relativeErrorOutUp->GetBinContent(i+1);
1995 upErr = relativeErrorInUp->GetBinContent(i+1)*relativeErrorInUp->GetBinContent(i+1)+relativeErrorOutLow->GetBinContent(i+1)*relativeErrorOutLow->GetBinContent(i+1);
1997 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);
1998 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);
2000 ayl[i] = TMath::Sqrt(TMath::Abs(lowErr))*nominal->GetBinContent(i+1);
2001 ayh[i] = TMath::Sqrt(TMath::Abs(upErr))*nominal->GetBinContent(i+1);
2002 // get the bin width (which is the 'error' on x
2003 Double_t binWidth(nominal->GetBinWidth(i+1));
2004 axl[i] = binWidth/2.;
2005 axh[i] = binWidth/2.;
2006 // now get the coordinate for the point
2007 ax[i] = nominal->GetBinCenter(i+1);
2008 ay[i] = nominal->GetBinContent(i+1);
2010 // save the nominal ratio
2011 TGraphAsymmErrors* nominalError(new TGraphAsymmErrors(fBinsTrue->GetSize()-1, ax, ay, axl, axh, ayl, ayh));
2012 corrRatio = (TGraphAsymmErrors*)nominalError->Clone();
2013 nominalError->SetName("correlated uncertainty");
2014 TCanvas* nominalCanvas(new TCanvas("nominalCanvas", "nominalCanvas"));
2015 nominalCanvas->Divide(2);
2016 nominalCanvas->cd(1);
2017 Style(nominal, kBlack);
2018 Style(nominalError, kCyan, kRatio);
2019 nominalError->SetLineColor(kCyan);
2020 nominalError->SetMarkerColor(kCyan);
2021 nominalError->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2022 nominalError->GetYaxis()->SetRangeUser(.7, 2.2);
2023 nominalError->DrawClone("a2");
2024 nominal->DrawCopy("same E1");
2025 Style(AddLegend(gPad));
2026 Style(gPad, "GRID");
2027 Style(nominalCanvas);
2028 // save nominal v2 and systematic errors
2029 TGraphAsymmErrors* nominalV2Error(GetV2WithSystematicErrors(
2033 "v_{2} with shape uncertainty",
2037 relativeErrorOutLow,
2039 // pass the nominal values to the pointer references
2040 corrV2 = (TGraphAsymmErrors*)nominalV2Error->Clone();
2041 TGraphErrors* nominalV2(GetV2(nominalIn, nominalOut, fEventPlaneRes, "v_{2}"));
2042 nominalCanvas->cd(2);
2043 Style(nominalV2, kBlack);
2044 Style(nominalV2Error, kCyan, kV2);
2045 nominalV2Error->SetLineColor(kCyan);
2046 nominalV2Error->SetMarkerColor(kCyan);
2047 nominalV2Error->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2048 nominalV2Error->DrawClone("a2");
2049 nominalV2->DrawClone("same E1");
2050 Style(AddLegend(gPad));
2051 Style(gPad, "GRID");
2052 Style(nominalCanvas);
2053 SavePadToPDF(nominalCanvas);
2054 nominalCanvas->Write();
2057 TCanvas* relativeError(new TCanvas("relativeCorrelatedError"," relativeCorrelatedError"));
2058 relativeError->Divide(2);
2059 relativeError->cd(1);
2060 Style(gPad, "GRID");
2061 relativeErrorInUp->GetYaxis()->SetRangeUser(-1.5, 3.);
2062 Style(relativeErrorInUp, kBlue, kBar);
2063 Style(relativeErrorInLow, kGreen, kBar);
2064 relativeErrorInUp->DrawCopy("b");
2065 relativeErrorInLow->DrawCopy("same b");
2066 Style(relativeStatisticalErrorIn, kRed);
2067 relativeStatisticalErrorIn->DrawCopy("same");
2068 Style(AddLegend(gPad));
2069 relativeError->cd(2);
2070 Style(gPad, "GRID");
2071 relativeErrorOutUp->GetYaxis()->SetRangeUser(-1.5, 3.);
2072 Style(relativeErrorOutUp, kBlue, kBar);
2073 Style(relativeErrorOutLow, kGreen, kBar);
2074 relativeErrorOutUp->DrawCopy("b");
2075 relativeErrorOutLow->DrawCopy("same b");
2076 Style(relativeStatisticalErrorOut, kRed);
2077 relativeStatisticalErrorOut->DrawCopy("same");
2078 Style(AddLegend(gPad));
2080 // write the buffered file to disk and close the file
2081 SavePadToPDF(relativeError);
2082 relativeError->Write();
2086 //_____________________________________________________________________________
2087 void AliJetFlowTools::GetShapeUncertainty(
2088 TGraphAsymmErrors*& shapeRatio, // pointer reference to final shape uncertainty of ratio
2089 TGraphAsymmErrors*& shapeV2, // pointer reference to final shape uncertainty of v2
2090 TArrayI* regularizationIn, // regularization strength systematics, in plane
2091 TArrayI* regularizationOut, // regularization strenght systematics, out of plane
2092 TArrayI* trueBinIn, // true bin ranges, in plane
2093 TArrayI* trueBinOut, // true bin ranges, out of plane
2094 TArrayI* recBinIn, // rec bin ranges, in plane
2095 TArrayI* recBinOut, // rec bin ranges, out of plane
2096 TArrayI* methodIn, // method in
2097 TArrayI* methodOut, // method out
2098 Int_t columns, // divide the output canvasses in this many columns
2099 Float_t rangeLow, // lower pt range
2100 Float_t rangeUp, // upper pt range
2101 Float_t corr, // correlation strength
2102 TString in, // input file name (created by this unfolding class)
2103 TString out // output file name (which will hold results of the systematic test)
2106 // do full systematics
2107 if(fOutputFile && !fOutputFile->IsZombie()) fOutputFile->Close(); // if for some weird reason the unfolding output is still mutable
2108 TFile* readMe(new TFile(in.Data(), "READ")); // open unfolding output read-only
2109 if(readMe->IsZombie()) {
2110 printf(" > Fatal error, couldn't read %s for post processing ! < \n", in.Data());
2113 printf("\n\n\n\t\t DOSYSTEMATICS \n > Recovered the following file structure : \n <");
2115 TFile* output(new TFile(out.Data(), "RECREATE")); // create new output file
2117 // create some null placeholder pointers
2118 TH1D* relativeErrorRegularizationInLow(0x0);
2119 TH1D* relativeErrorRegularizationInUp(0x0);
2120 TH1D* relativeErrorTrueBinInLow(0x0);
2121 TH1D* relativeErrorTrueBinInUp(0x0);
2122 TH1D* relativeErrorRecBinInLow(0x0);
2123 TH1D* relativeErrorRecBinInUp(0x0);
2124 TH1D* relativeErrorMethodInLow(0x0);
2125 TH1D* relativeErrorMethodInUp(0x0);
2126 TH1D* relativeErrorRegularizationOutLow(0x0);
2127 TH1D* relativeErrorRegularizationOutUp(0x0);
2128 TH1D* relativeErrorTrueBinOutLow(0x0);
2129 TH1D* relativeErrorTrueBinOutUp(0x0);
2130 TH1D* relativeErrorRecBinOutLow(0x0);
2131 TH1D* relativeErrorRecBinOutUp(0x0);
2132 TH1D* relativeStatisticalErrorIn(0x0);
2133 TH1D* relativeStatisticalErrorOut(0x0);
2134 TH1D* relativeErrorMethodOutLow(0x0);
2135 TH1D* relativeErrorMethodOutUp(0x0);
2136 // histo for the nominal ratio in / out
2137 TH1D* nominal(new TH1D("ratio in plane, out of plane", "ratio in plane, out of plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2138 TH1D* nominalIn(new TH1D("in plane jet yield", "in plane jet yield", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2139 TH1D* nominalOut(new TH1D("out of plane jet yield", "out of plane jet yield", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2141 // call the functions
2142 if(regularizationIn && regularizationOut) {
2143 DoIntermediateSystematics(
2146 relativeErrorRegularizationInUp, // pointer reference
2147 relativeErrorRegularizationInLow, // pointer reference
2148 relativeErrorRegularizationOutUp, // pointer reference
2149 relativeErrorRegularizationOutLow, // pointer reference
2150 relativeStatisticalErrorIn, // pointer reference
2151 relativeStatisticalErrorOut, // pointer reference
2161 if(relativeErrorRegularizationInUp) {
2162 // canvas with the error from regularization strength
2163 TCanvas* relativeErrorRegularization(new TCanvas("relativeErrorRegularization", "relativeErrorRegularization"));
2164 relativeErrorRegularization->Divide(2);
2165 relativeErrorRegularization->cd(1);
2166 Style(gPad, "GRID");
2167 relativeErrorRegularizationInUp->DrawCopy("b");
2168 relativeErrorRegularizationInLow->DrawCopy("same b");
2169 Style(AddLegend(gPad));
2170 relativeErrorRegularization->cd(2);
2171 Style(gPad, "GRID");
2172 relativeErrorRegularizationOutUp->DrawCopy("b");
2173 relativeErrorRegularizationOutLow->DrawCopy("same b");
2174 SavePadToPDF(relativeErrorRegularization);
2175 Style(AddLegend(gPad));
2176 relativeErrorRegularization->Write();
2179 if(trueBinIn && trueBinOut) {
2180 DoIntermediateSystematics(
2183 relativeErrorTrueBinInUp, // pointer reference
2184 relativeErrorTrueBinInLow, // pointer reference
2185 relativeErrorTrueBinOutUp, // pointer reference
2186 relativeErrorTrueBinOutLow, // pointer reference
2187 relativeStatisticalErrorIn,
2188 relativeStatisticalErrorOut,
2197 if(relativeErrorTrueBinInUp) {
2198 TCanvas* relativeErrorTrueBin(new TCanvas("relativeErrorTrueBin", "relativeErrorTrueBin"));
2199 relativeErrorTrueBin->Divide(2);
2200 relativeErrorTrueBin->cd(1);
2201 Style(gPad, "GRID");
2202 relativeErrorTrueBinInUp->DrawCopy("b");
2203 relativeErrorTrueBinInLow->DrawCopy("same b");
2204 Style(AddLegend(gPad));
2205 relativeErrorTrueBin->cd(2);
2206 Style(gPad, "GRID");
2207 relativeErrorTrueBinOutUp->DrawCopy("b");
2208 relativeErrorTrueBinOutLow->DrawCopy("same b");
2209 SavePadToPDF(relativeErrorTrueBin);
2210 Style(AddLegend(gPad));
2211 relativeErrorTrueBin->Write();
2214 if(recBinIn && recBinOut) {
2215 DoIntermediateSystematics(
2218 relativeErrorRecBinInUp, // pointer reference
2219 relativeErrorRecBinInLow, // pointer reference
2220 relativeErrorRecBinOutUp, // pointer reference
2221 relativeErrorRecBinOutLow, // pointer reference
2222 relativeStatisticalErrorIn,
2223 relativeStatisticalErrorOut,
2233 if(relativeErrorRecBinOutUp) {
2234 // canvas with the error from regularization strength
2235 TCanvas* relativeErrorRecBin(new TCanvas("relativeErrorRecBin"," relativeErrorRecBin"));
2236 relativeErrorRecBin->Divide(2);
2237 relativeErrorRecBin->cd(1);
2238 Style(gPad, "GRID");
2239 relativeErrorRecBinInUp->DrawCopy("b");
2240 relativeErrorRecBinInLow->DrawCopy("same b");
2241 Style(AddLegend(gPad));
2242 relativeErrorRecBin->cd(2);
2243 Style(gPad, "GRID");
2244 relativeErrorRecBinOutUp->DrawCopy("b");
2245 relativeErrorRecBinOutLow->DrawCopy("same b");
2246 SavePadToPDF(relativeErrorRecBin);
2247 Style(AddLegend(gPad));
2248 relativeErrorRecBin->Write();
2251 if(methodIn && methodOut) {
2252 DoIntermediateSystematics(
2255 relativeErrorMethodInUp, // pointer reference
2256 relativeErrorMethodInLow, // pointer reference
2257 relativeErrorMethodOutUp, // pointer reference
2258 relativeErrorMethodOutLow, // pointer reference
2259 relativeStatisticalErrorIn,
2260 relativeStatisticalErrorOut,
2270 if(relativeErrorMethodInUp) {
2271 TCanvas* relativeErrorMethod(new TCanvas("relativeErrorMethod", "relativeErrorMethod"));
2272 relativeErrorMethod->Divide(2);
2273 relativeErrorMethod->cd(1);
2274 Style(gPad, "GRID");
2275 relativeErrorMethodInUp->DrawCopy("b");
2276 relativeErrorMethodInLow->DrawCopy("same b");
2277 Style(AddLegend(gPad));
2278 relativeErrorMethod->cd(2);
2279 Style(gPad, "GRID");
2280 relativeErrorMethodOutUp->DrawCopy("b");
2281 relativeErrorMethodOutLow->DrawCopy("same b");
2282 SavePadToPDF(relativeErrorMethod);
2283 Style(AddLegend(gPad));
2284 relativeErrorMethod->Write();
2288 // and the placeholder for the final systematic
2289 TH1D* relativeErrorInUp(new TH1D("max shape uncertainty in plane", "max shape uncertainty in plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2290 TH1D* relativeErrorOutUp(new TH1D("max shape uncertainty out of plane", "max shape uncertainty out of plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2291 TH1D* relativeErrorInLow(new TH1D("min shape uncertainty in plane", "min shape uncertainty in plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2292 TH1D* relativeErrorOutLow(new TH1D("min shape uncertainty out of plane", "min shape uncertainty out of plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2293 relativeErrorInUp->SetYTitle("relative uncertainty");
2294 relativeErrorOutUp->SetYTitle("relative uncertainty");
2295 relativeErrorInLow->SetYTitle("relative uncertainty");
2296 relativeErrorOutLow->SetYTitle("relative uncertainty");
2298 // sum of squares for the total systematic error
2299 Double_t aInUp(0.), bInUp(0.), cInUp(0.), dInUp(0.), eInUp(0.);
2300 Double_t aOutUp(0.), bOutUp(0.), cOutUp(0.), dOutUp(0.), eOutUp(0.);
2301 Double_t aInLow(0.), bInLow(0.), cInLow(0.), dInLow(0.), eInLow(0.);
2302 Double_t aOutLow(0.), bOutLow(0.), cOutLow(0.), dOutLow(0.), eOutLow(0.);
2304 for(Int_t b(0); b < fBinsTrue->GetSize()-1; b++) {
2305 // for the upper bound
2306 if(relativeErrorRegularizationInUp) aInUp = relativeErrorRegularizationInUp->GetBinContent(b+1);
2307 if(relativeErrorRegularizationOutUp) aOutUp = relativeErrorRegularizationOutUp->GetBinContent(b+1);
2308 if(relativeErrorTrueBinInUp) bInUp = relativeErrorTrueBinInUp->GetBinContent(b+1);
2309 if(relativeErrorTrueBinOutUp) bOutUp = relativeErrorTrueBinOutUp->GetBinContent(b+1);
2310 if(relativeErrorRecBinInUp) cInUp = relativeErrorRecBinInUp->GetBinContent(b+1);
2311 if(relativeErrorRecBinOutUp) cOutUp = relativeErrorRecBinOutUp->GetBinContent(b+1);
2312 if(relativeErrorMethodInUp) dInUp = relativeErrorMethodInUp->GetBinContent(b+1);
2313 if(relativeErrorMethodOutUp) dOutUp = relativeErrorMethodOutUp->GetBinContent(b+1);
2314 eInUp = aInUp*aInUp + bInUp*bInUp + cInUp*cInUp + dInUp*dInUp;
2315 if(eInUp > 0) relativeErrorInUp->SetBinContent(b+1, 1.*TMath::Sqrt(eInUp));
2316 eOutUp = aOutUp*aOutUp + bOutUp*bOutUp + cOutUp*cOutUp + dOutUp*dOutUp;
2317 if(eOutUp > 0) relativeErrorOutUp->SetBinContent(b+1, 1.*TMath::Sqrt(eOutUp));
2318 // for the lower bound
2319 if(relativeErrorRegularizationInLow) aInLow = relativeErrorRegularizationInLow->GetBinContent(b+1);
2320 if(relativeErrorRegularizationOutLow) aOutLow = relativeErrorRegularizationOutLow->GetBinContent(b+1);
2321 if(relativeErrorTrueBinInLow) bInLow = relativeErrorTrueBinInLow->GetBinContent(b+1);
2322 if(relativeErrorTrueBinOutLow) bOutLow = relativeErrorTrueBinOutLow->GetBinContent(b+1);
2323 if(relativeErrorRecBinInLow) cInLow = relativeErrorRecBinInLow->GetBinContent(b+1);
2324 if(relativeErrorRecBinOutLow) cOutLow = relativeErrorRecBinOutLow->GetBinContent(b+1);
2325 if(relativeErrorMethodInLow) dInLow = relativeErrorMethodInLow->GetBinContent(b+1);
2326 if(relativeErrorMethodOutLow) dOutLow = relativeErrorMethodOutLow->GetBinContent(b+1);
2327 if(fSymmRMS) { // take first category as symmetric
2331 cOutLow = cOutUp; // other sources
2332 if(dInLow < dInUp) dInLow = dInUp;
2333 if(dOutLow < dOutUp) dOutLow = dOutUp;
2336 eInLow = aInLow*aInLow + bInLow*bInLow + cInLow*cInLow + dInLow*dInLow;
2337 if(eInLow > 0) relativeErrorInLow->SetBinContent(b+1, -1.*TMath::Sqrt(eInLow));
2338 eOutLow = aOutLow*aOutLow + bOutLow*bOutLow + cOutLow*cOutLow + dOutLow*dOutLow;
2339 if(eOutLow > 0) relativeErrorOutLow->SetBinContent(b+1, -1.*TMath::Sqrt(eOutLow));
2341 // project the estimated errors on the nominal ratio
2343 Double_t* ax = new Double_t[fBinsTrue->GetSize()-1];
2344 Double_t* ay = new Double_t[fBinsTrue->GetSize()-1];
2345 Double_t* axh = new Double_t[fBinsTrue->GetSize()-1];
2346 Double_t* axl = new Double_t[fBinsTrue->GetSize()-1];
2347 Double_t* ayh = new Double_t[fBinsTrue->GetSize()-1];
2348 Double_t* ayl = new Double_t[fBinsTrue->GetSize()-1];
2349 Double_t lowErr(0.), upErr(0.);
2350 for(Int_t i(0); i < fBinsTrue->GetSize()-1; i++) {
2351 // add the in and out of plane errors in quadrature
2352 // take special care here: to propagate the assymetric error, we need to correlate the
2353 // InLow with OutUp (minimum value of ratio) and InUp with OutLow (maximum value of ratio)
2354 lowErr = relativeErrorInLow->GetBinContent(i+1)*relativeErrorInLow->GetBinContent(i+1)+relativeErrorOutUp->GetBinContent(1+i)*relativeErrorOutUp->GetBinContent(i+1);
2355 upErr = relativeErrorInUp->GetBinContent(i+1)*relativeErrorInUp->GetBinContent(i+1)+relativeErrorOutLow->GetBinContent(i+1)*relativeErrorOutLow->GetBinContent(i+1);
2357 ayl[i] = TMath::Sqrt(lowErr)*nominal->GetBinContent(i+1);
2358 ayh[i] = TMath::Sqrt(upErr)*nominal->GetBinContent(i+1);
2359 // get the bin width (which is the 'error' on x
2360 Double_t binWidth(nominal->GetBinWidth(i+1));
2361 axl[i] = binWidth/2.;
2362 axh[i] = binWidth/2.;
2363 // now get the coordinate for the point
2364 ax[i] = nominal->GetBinCenter(i+1);
2365 ay[i] = nominal->GetBinContent(i+1);
2367 // save the nominal ratio
2368 TGraphAsymmErrors* nominalError(new TGraphAsymmErrors(fBinsTrue->GetSize()-1, ax, ay, axl, axh, ayl, ayh));
2369 shapeRatio = (TGraphAsymmErrors*)nominalError->Clone();
2370 nominalError->SetName("shape uncertainty");
2371 TCanvas* nominalCanvas(new TCanvas("nominalCanvas", "nominalCanvas"));
2372 nominalCanvas->Divide(2);
2373 nominalCanvas->cd(1);
2374 Style(nominal, kBlack);
2375 Style(nominalError, kCyan, kRatio);
2376 nominalError->SetLineColor(kCyan);
2377 nominalError->SetMarkerColor(kCyan);
2378 nominalError->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2379 nominalError->GetYaxis()->SetRangeUser(.7, 2.2);
2380 nominalError->DrawClone("a2");
2381 nominal->DrawCopy("same E1");
2382 Style(AddLegend(gPad));
2383 Style(gPad, "GRID");
2384 Style(nominalCanvas);
2385 // save nominal v2 and systematic errors
2386 TGraphAsymmErrors* nominalV2Error(GetV2WithSystematicErrors(
2390 "v_{2} with shape uncertainty",
2394 relativeErrorOutLow,
2396 shapeV2 = (TGraphAsymmErrors*)nominalV2Error->Clone();
2397 TGraphErrors* nominalV2(GetV2(nominalIn, nominalOut, fEventPlaneRes, "v_{2}"));
2398 nominalCanvas->cd(2);
2399 Style(nominalV2, kBlack);
2400 Style(nominalV2Error, kCyan, kV2);
2401 nominalV2Error->SetLineColor(kCyan);
2402 nominalV2Error->SetMarkerColor(kCyan);
2403 nominalV2Error->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2404 nominalV2Error->DrawClone("a2");
2405 nominalV2->DrawClone("same E1");
2406 Style(AddLegend(gPad));
2407 Style(gPad, "GRID");
2408 Style(nominalCanvas);
2409 SavePadToPDF(nominalCanvas);
2410 nominalCanvas->Write();
2413 TCanvas* relativeError(new TCanvas("relativeError"," relativeError"));
2414 relativeError->Divide(2);
2415 relativeError->cd(1);
2416 Style(gPad, "GRID");
2417 relativeErrorInUp->GetYaxis()->SetRangeUser(-1.5, 3.);
2418 Style(relativeErrorInUp, kBlue, kBar);
2419 Style(relativeErrorInLow, kGreen, kBar);
2420 relativeErrorInUp->DrawCopy("b");
2421 relativeErrorInLow->DrawCopy("same b");
2422 Style(relativeStatisticalErrorIn, kRed);
2423 relativeStatisticalErrorIn->DrawCopy("same");
2424 Style(AddLegend(gPad));
2425 relativeError->cd(2);
2426 Style(gPad, "GRID");
2427 relativeErrorOutUp->GetYaxis()->SetRangeUser(-1.5, 3.);
2428 Style(relativeErrorOutUp, kBlue, kBar);
2429 Style(relativeErrorOutLow, kGreen, kBar);
2430 relativeErrorOutUp->DrawCopy("b");
2431 relativeErrorOutLow->DrawCopy("same b");
2432 Style(relativeStatisticalErrorOut, kRed);
2433 relativeStatisticalErrorOut->DrawCopy("same");
2434 Style(AddLegend(gPad));
2436 // write the buffered file to disk and close the file
2437 SavePadToPDF(relativeError);
2438 relativeError->Write();
2442 //_____________________________________________________________________________
2443 void AliJetFlowTools::DoIntermediateSystematics(
2444 TArrayI* variationsIn, // variantions in plane
2445 TArrayI* variationsOut, // variantions out of plane
2446 TH1D*& relativeErrorInUp, // pointer reference to minimum relative error histogram in plane
2447 TH1D*& relativeErrorInLow, // pointer reference to maximum relative error histogram in plane
2448 TH1D*& relativeErrorOutUp, // pointer reference to minimum relative error histogram out of plane
2449 TH1D*& relativeErrorOutLow, // pointer reference to maximum relative error histogram out of plane
2450 TH1D*& relativeStatisticalErrorIn, // relative systematic error on ratio
2451 TH1D*& relativeStatisticalErrorOut, // relative systematic error on ratio
2452 TH1D*& nominal, // clone of the nominal ratio in / out of plane
2453 TH1D*& nominalIn, // clone of the nominal in plane yield
2454 TH1D*& nominalOut, // clone of the nominal out of plane yield
2455 Int_t columns, // divide the output canvasses in this many columns
2456 Float_t rangeLow, // lower pt range
2457 Float_t rangeUp, // upper pt range
2458 TFile* readMe, // input file name (created by this unfolding class)
2459 TString source, // source of the variation
2460 Bool_t RMS // return RMS of distribution of variations as error
2463 // intermediate systematic check function. first index of supplied array is nominal value
2464 TList* listOfKeys((TList*)readMe->GetListOfKeys());
2466 printf(" > Fatal error, couldn't retrieve list of keys. Input file might have been corrupted ! < \n");
2469 // check input params
2470 if(variationsIn->GetSize() != variationsOut->GetSize()) {
2471 printf(" > DoSystematics: fatal error, input arrays have different sizes ! < \n ");
2474 TDirectoryFile* defRootDirIn(dynamic_cast<TDirectoryFile*>(readMe->Get(listOfKeys->At(variationsIn->At(0))->GetName())));
2475 TDirectoryFile* defRootDirOut(dynamic_cast<TDirectoryFile*>(readMe->Get(listOfKeys->At(variationsOut->At(0))->GetName())));
2476 if(!(defRootDirIn && defRootDirOut)) {
2477 printf(" > DoSystematics: fatal error, couldn't retrieve nominal values ! < \n ");
2480 TString defIn(defRootDirIn->GetName());
2481 TString defOut(defRootDirOut->GetName());
2483 // define lines to make the output prettier
2484 TLine* lineLow(new TLine(rangeLow, 0., rangeLow, 2.));
2485 TLine* lineUp(new TLine(rangeUp, 0., rangeUp, 2.));
2486 lineLow->SetLineColor(11);
2487 lineUp->SetLineColor(11);
2488 lineLow->SetLineWidth(3);
2489 lineUp->SetLineWidth(3);
2491 // define an output histogram with the maximum relative error from this systematic constribution
2492 // 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
2493 // reached in this function call.
2494 // 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
2495 // which should correspond to a 68% confidence level
2496 relativeErrorInUp = new TH1D(Form("relative error (up) from %s", source.Data()), Form("relative error (up) from %s", source.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2497 relativeErrorInLow = new TH1D(Form("relative error (low) from %s", source.Data()), Form("relative error (low) from %s", source.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2498 relativeErrorOutUp = new TH1D(Form("relative error (up) from %s", source.Data()), Form("relative error (up) from %s", source.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2499 relativeErrorOutLow = new TH1D(Form("relative error (low) from %s", source.Data()), Form("relative error (low) from %s", source.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2500 for(Int_t b(0); b < fBinsTrue->GetSize()-1; b++) {
2502 relativeErrorInUp->SetBinContent(b+1, 1.);
2503 relativeErrorInUp->SetBinError(b+1, 0.);
2504 relativeErrorOutUp->SetBinContent(b+1, 1.);
2505 relativeErrorOutUp->SetBinError(b+1, .0);
2506 relativeErrorInLow->SetBinContent(b+1, 1.);
2507 relativeErrorInLow->SetBinError(b+1, 0.);
2508 relativeErrorOutLow->SetBinContent(b+1, 1.);
2509 relativeErrorOutLow->SetBinError(b+1, .0);
2511 relativeErrorInUp->SetBinContent(b+1, 0.);
2512 relativeErrorInUp->SetBinError(b+1, 0.);
2513 relativeErrorOutUp->SetBinContent(b+1, 0.);
2514 relativeErrorOutUp->SetBinError(b+1, 0.);
2515 relativeErrorInLow->SetBinContent(b+1, 0.);
2516 relativeErrorInLow->SetBinError(b+1, 0.);
2517 relativeErrorOutLow->SetBinContent(b+1, 0.);
2518 relativeErrorOutLow->SetBinError(b+1, 0.);
2521 Int_t relativeErrorInUpN[100] = {0};
2522 Int_t relativeErrorOutUpN[100] = {0};
2523 Int_t relativeErrorInLowN[100] = {0};
2524 Int_t relativeErrorOutLowN[100] = {0};
2526 // define an output histogram with the systematic error from this systematic constribution
2527 if(!relativeStatisticalErrorIn && !relativeStatisticalErrorOut) {
2528 relativeStatisticalErrorIn = new TH1D("relative statistical error, in plane", "relative statistical error, in plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2529 relativeStatisticalErrorOut = new TH1D("relative statistical error, out of plane", "relative statistital error, out of plane", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2532 // prepare necessary canvasses
2533 TCanvas* canvasIn(new TCanvas(Form("SYST_%s_PearsonIn", source.Data()), Form("SYST_%s_PearsonIn", source.Data())));
2534 TCanvas* canvasOut(0x0);
2535 if(fDphiUnfolding) canvasOut = new TCanvas(Form("SYST_%s_PearsonOut", source.Data()), Form("SYST_%s_PearsonOut", source.Data()));
2536 TCanvas* canvasRatioMeasuredRefoldedIn(new TCanvas(Form("SYST_%s_RefoldedIn", source.Data()), Form("SYST_%s_RefoldedIn", source.Data())));
2537 TCanvas* canvasRatioMeasuredRefoldedOut(0x0);
2538 if(fDphiUnfolding) canvasRatioMeasuredRefoldedOut = new TCanvas(Form("SYST_%s_RefoldedOut", source.Data()), Form("SYST_%s_RefoldedOut", source.Data()));
2539 TCanvas* canvasSpectraIn(new TCanvas(Form("SYST_%s_SpectraIn", source.Data()), Form("SYST_%s_SpectraIn", source.Data())));
2540 TCanvas* canvasSpectraOut(0x0);
2541 if(fDphiUnfolding) canvasSpectraOut = new TCanvas(Form("SYST_%s_SpectraOut", source.Data()), Form("SYST_%s_SpectraOut", source.Data()));
2542 TCanvas* canvasRatio(0x0);
2543 if(fDphiUnfolding) canvasRatio = new TCanvas(Form("SYST_%s_Ratio", source.Data()), Form("SYST_%s_Ratio", source.Data()));
2544 TCanvas* canvasV2(0x0);
2545 if(fDphiUnfolding) canvasV2 = new TCanvas(Form("SYST_%s_V2", source.Data()), Form("SYST_%s_V2", source.Data()));
2546 TCanvas* canvasMISC(new TCanvas(Form("SYST_%s_MISC", source.Data()), Form("SYST_%s_MISC", source.Data())));
2547 TCanvas* canvasMasterIn(new TCanvas(Form("SYST_%s_defaultIn", source.Data()), Form("SYST_%s_defaultIn", source.Data())));
2548 TCanvas* canvasMasterOut(0x0);
2549 if(fDphiUnfolding) canvasMasterOut = new TCanvas(Form("SYST_%s_defaultOut", source.Data()), Form("SYST_%s_defaultOut", source.Data()));
2550 (fDphiUnfolding) ? canvasMISC->Divide(4, 2) : canvasMISC->Divide(4, 1);
2552 TCanvas* canvasProfiles(new TCanvas(Form("SYST_%s_canvasProfiles", source.Data()), Form("SYST_%s_canvasProfiles", source.Data())));
2553 canvasProfiles->Divide(2);
2554 TProfile* ratioProfile(new TProfile(Form("SYST_%s_ratioProfile", source.Data()), Form("SYST_%s_ratioProfile", source.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2555 TProfile* v2Profile(new TProfile(Form("SYST_%s_v2Profile", source.Data()), Form("SYST_%s_v2Profile", source.Data()),fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2556 // get an estimate of the number of outputs and find the default set
2559 columns = variationsIn->GetSize()-1;
2560 (TMath::Floor(variationsIn->GetSize()/(float)columns)+((variationsIn->GetSize()%columns)>0));
2561 canvasIn->Divide(columns, rows);
2562 if(canvasOut) canvasOut->Divide(columns, rows);
2563 canvasRatioMeasuredRefoldedIn->Divide(columns, rows);
2564 if(canvasRatioMeasuredRefoldedOut) canvasRatioMeasuredRefoldedOut->Divide(columns, rows);
2565 canvasSpectraIn->Divide(columns, rows);
2566 if(canvasSpectraOut) canvasSpectraOut->Divide(columns, rows);
2567 if(canvasRatio) canvasRatio->Divide(columns, rows);
2568 if(canvasV2) canvasV2->Divide(columns, rows);
2569 canvasMasterIn->Divide(columns, rows);
2570 if(canvasMasterOut) canvasMasterOut->Divide(columns, rows);
2572 // prepare a separate set of canvases to hold the nominal points
2573 TCanvas* canvasNominalIn(new TCanvas(Form("Nominal_%s_PearsonIn", source.Data()), Form("Nominal_%s_PearsonIn", source.Data())));
2574 TCanvas* canvasNominalOut(0x0);
2575 if(fDphiUnfolding) canvasNominalOut = new TCanvas(Form("Nominal_%s_PearsonOut", source.Data()), Form("Nominal_%s_PearsonOut", source.Data()));
2576 TCanvas* canvasNominalRatioMeasuredRefoldedIn(new TCanvas(Form("Nominal_%s_RefoldedIn", source.Data()), Form("Nominal_%s_RefoldedIn", source.Data())));
2577 TCanvas* canvasNominalRatioMeasuredRefoldedOut(0x0);
2578 if(fDphiUnfolding) canvasNominalRatioMeasuredRefoldedOut = new TCanvas(Form("Nominal_%s_RefoldedOut", source.Data()), Form("Nominal_%s_RefoldedOut", source.Data()));
2579 TCanvas* canvasNominalSpectraIn(new TCanvas(Form("Nominal_%s_SpectraIn", source.Data()), Form("Nominal_%s_SpectraIn", source.Data())));
2580 TCanvas* canvasNominalSpectraOut(0x0);
2581 if(fDphiUnfolding) canvasNominalSpectraOut = new TCanvas(Form("Nominal_%s_SpectraOut", source.Data()), Form("Nominal_%s_SpectraOut", source.Data()));
2582 TCanvas* canvasNominalRatio(0x0);
2583 if(fDphiUnfolding) canvasNominalRatio = new TCanvas(Form("Nominal_%s_Ratio", source.Data()), Form("Nominal_%s_Ratio", source.Data()));
2584 TCanvas* canvasNominalV2(0x0);
2585 if(fDphiUnfolding) canvasNominalV2 = new TCanvas(Form("Nominal_%s_V2", source.Data()), Form("Nominal_%s_V2", source.Data()));
2586 TCanvas* canvasNominalMISC(new TCanvas(Form("Nominal_%s_MISC", source.Data()), Form("Nominal_%s_MISC", source.Data())));
2587 TCanvas* canvasNominalMasterIn(new TCanvas(Form("Nominal_%s_defaultIn", source.Data()), Form("Nominal_%s_defaultIn", source.Data())));
2588 TCanvas* canvasNominalMasterOut(0x0);
2589 if(fDphiUnfolding) canvasNominalMasterOut = new TCanvas(Form("Nominal_%s_defaultOut", source.Data()), Form("Nominal_%s_defaultOut", source.Data()));
2590 (fDphiUnfolding) ? canvasNominalMISC->Divide(4, 2) : canvasNominalMISC->Divide(4, 1);
2592 canvasNominalSpectraIn->Divide(2);
2593 if(canvasNominalSpectraOut) canvasNominalSpectraOut->Divide(2);
2595 canvasNominalMasterIn->Divide(2);
2596 if(canvasNominalMasterOut) canvasNominalMasterOut->Divide(2);
2598 // extract the default output
2599 TH1D* defaultUnfoldedJetSpectrumIn(0x0);
2600 TH1D* defaultUnfoldedJetSpectrumOut(0x0);
2601 TDirectoryFile* defDirIn = (TDirectoryFile*)defRootDirIn->Get(Form("InPlane___%s", defIn.Data()));
2602 TDirectoryFile* defDirOut = (TDirectoryFile*)defRootDirOut->Get(Form("OutOfPlane___%s", defOut.Data()));
2603 if(defDirIn) defaultUnfoldedJetSpectrumIn = (TH1D*)defDirIn->Get(Form("UnfoldedSpectrum_in_%s", defIn.Data()));
2604 if(defDirOut) defaultUnfoldedJetSpectrumOut = (TH1D*)defDirOut->Get(Form("UnfoldedSpectrum_out_%s", defOut.Data()));
2605 printf(" > succesfully extracted default results < \n");
2607 // loop through the directories, only plot the graphs if the deconvolution converged
2608 TDirectoryFile* tempDirIn(0x0);
2609 TDirectoryFile* tempDirOut(0x0);
2610 TDirectoryFile* tempIn(0x0);
2611 TDirectoryFile* tempOut(0x0);
2612 TH1D* unfoldedSpectrumInForRatio(0x0);
2613 TH1D* unfoldedSpectrumOutForRatio(0x0);
2614 for(Int_t i(0), j(-1); i < variationsIn->GetSize(); i++) {
2615 tempDirIn = (dynamic_cast<TDirectoryFile*>(readMe->Get(listOfKeys->At(variationsIn->At(i))->GetName())));
2616 tempDirOut = (dynamic_cast<TDirectoryFile*>(readMe->Get(listOfKeys->At(variationsOut->At(i))->GetName())));
2617 if(!(tempDirIn && tempDirOut)) {
2618 printf(" > DoSystematics: couldn't get a set of variations < \n");
2621 TString dirNameIn(tempDirIn->GetName());
2622 TString dirNameOut(tempDirOut->GetName());
2623 // try to read the in- and out of plane subdirs
2624 tempIn = (TDirectoryFile*)tempDirIn->Get(Form("InPlane___%s", dirNameIn.Data()));
2625 tempOut = (TDirectoryFile*)tempDirOut->Get(Form("OutOfPlane___%s", dirNameOut.Data()));
2628 // to see if the unfolding converged try to extract the pearson coefficients
2629 TH2D* pIn((TH2D*)tempIn->Get(Form("PearsonCoefficients_in_%s", dirNameIn.Data())));
2631 printf(" - %s in plane converged \n", dirNameIn.Data());
2633 if(i==0) canvasNominalIn->cd(j);
2634 Style(gPad, "PEARSON");
2635 pIn->DrawCopy("colz");
2636 TGraphErrors* rIn((TGraphErrors*)tempIn->Get(Form("RatioRefoldedMeasured_%s", dirNameIn.Data())));
2639 printf(" > found RatioRefoldedMeasured < \n");
2640 canvasRatioMeasuredRefoldedIn->cd(j);
2641 if(i==0) canvasNominalRatioMeasuredRefoldedIn->cd(j);
2642 Style(gPad, "GRID");
2643 rIn->SetFillColor(kRed);
2646 TH1D* dvector((TH1D*)tempIn->Get("dVector"));
2647 TH1D* avalue((TH1D*)tempIn->Get("SingularValuesOfAC"));
2648 TH2D* rm((TH2D*)tempIn->Get(Form("ResponseMatrixIn_%s", dirNameIn.Data())));
2649 TH1D* eff((TH1D*)tempIn->Get(Form("KinematicEfficiencyIn_%s", dirNameIn.Data())));
2650 if(dvector && avalue && rm && eff) {
2656 if(i==0) canvasNominalMISC->cd(1);
2657 Style(gPad, "SPECTRUM");
2658 dvector->DrawCopy();
2660 if(i==0) canvasNominalMISC->cd(2);
2661 Style(gPad, "SPECTRUM");
2664 if(i==0) canvasNominalMISC->cd(3);
2665 Style(gPad, "PEARSON");
2666 rm->DrawCopy("colz");
2668 if(i==0) canvasNominalMISC->cd(4);
2669 Style(gPad, "GRID");
2671 } else if(rm && eff) {
2675 if(i==0) canvasNominalMISC->cd(3);
2676 Style(gPad, "PEARSON");
2677 rm->DrawCopy("colz");
2679 if(i==0) canvasNominalMISC->cd(4);
2680 Style(gPad, "GRID");
2684 TH1D* inputSpectrum((TH1D*)tempIn->Get(Form("InputSpectrum_in_%s", dirNameIn.Data())));
2685 TH1D* unfoldedSpectrum((TH1D*)tempIn->Get(Form("UnfoldedSpectrum_in_%s", dirNameIn.Data())));
2686 unfoldedSpectrumInForRatio = ProtectHeap(unfoldedSpectrum, kFALSE, TString("ForRatio"));
2687 TH1D* refoldedSpectrum((TH1D*)tempIn->Get(Form("RefoldedSpectrum_in_%s", dirNameIn.Data())));
2688 if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
2689 if(defaultUnfoldedJetSpectrumIn) {
2690 Style(defaultUnfoldedJetSpectrumIn, kBlue, kUnfoldedSpectrum);
2691 TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumIn->Clone(Form("defaultUnfoldedJetSpectrumIn_%s", dirNameIn.Data())));
2692 temp->Divide(unfoldedSpectrum);
2693 // get the absolute relative error
2694 for(Int_t b(0); b < fBinsTrue->GetSize()-1; b++) {
2695 if(!RMS) { // save the maximum deviation that a variation can cause
2696 // the variation is HIGHER than the nominal point, so the bar goes UP
2697 if( temp->GetBinContent(b+1) < 1 && temp->GetBinContent(b+1) < relativeErrorInUp->GetBinContent(b+1)) {
2698 relativeErrorInUp->SetBinContent(b+1, temp->GetBinContent(b+1));
2699 relativeErrorInUp->SetBinError(b+1, 0.);
2701 // the variation is LOWER than the nominal point, so the bar goes DOWN
2702 else if(temp->GetBinContent(b+1) > 1 && temp->GetBinContent(b+1) > relativeErrorInLow->GetBinContent(b+1)) {
2703 relativeErrorInLow->SetBinContent(b+1, temp->GetBinContent(b+1));
2704 relativeErrorInLow->SetBinError(b+1, 0.);
2706 } else if (RMS && !fSymmRMS) { // save info necessary for evaluating the RMS of a distribution of variations
2707 printf(" oops shouldnt be here \n " );
2708 if(temp->GetBinContent(b+1) < 1) {
2709 relativeErrorInUp->SetBinContent(b+1, relativeErrorInUp->GetBinContent(b+1)+TMath::Power(1.-temp->GetBinContent(b+1), 2));
2710 relativeErrorInUpN[b]++;
2712 // the variation is LOWER than the nominal point, so the bar goes DOWN
2713 else if(temp->GetBinContent(b+1) > 1) {
2714 relativeErrorInLow->SetBinContent(b+1, relativeErrorInLow->GetBinContent(b+1)+TMath::Power(1.-temp->GetBinContent(b+1), 2));
2715 relativeErrorInLowN[b]++;
2717 } else if (fSymmRMS) {
2718 // save symmetric sum of square to get a symmetric rms
2719 relativeErrorInUp->SetBinContent(b+1, relativeErrorInUp->GetBinContent(b+1)+TMath::Power(temp->GetBinContent(b+1)-1., 2));
2720 relativeErrorInUpN[b]++;
2722 if(temp->GetBinError(b+1) > 0) relativeStatisticalErrorIn->SetBinContent(b+1, temp->GetBinError(b+1)/temp->GetBinContent(b+1));
2724 temp->SetTitle(Form("[%s] / [%s]", defIn.Data(), dirNameIn.Data()));
2725 temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
2726 temp->GetYaxis()->SetTitle("ratio");
2727 canvasMasterIn->cd(j);
2728 temp->GetYaxis()->SetRangeUser(0., 2);
2729 Style(gPad, "GRID");
2731 canvasNominalMasterIn->cd(1);
2732 Style(gPad, "GRID");
2734 TH1D* tempSyst((TH1D*)temp->Clone(Form("%s_syst", temp->GetName())));
2735 tempSyst->SetTitle(Form("[%s] / [%s]", defIn.Data(), dirNameIn.Data()));
2736 Style(tempSyst, (EColor)(i+2));
2737 if(i==1) tempSyst->DrawCopy();
2738 else tempSyst->DrawCopy("same");
2741 TH1F* fitStatus((TH1F*)tempIn->Get(Form("fitStatus_%s_in", dirNameIn.Data())));
2742 canvasSpectraIn->cd(j);
2743 if(i==0) canvasNominalSpectraIn->cd(1);
2745 Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
2746 unfoldedSpectrum->DrawCopy();
2747 Style(inputSpectrum, kGreen, kMeasuredSpectrum);
2748 inputSpectrum->DrawCopy("same");
2749 Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
2750 refoldedSpectrum->DrawCopy("same");
2751 TLegend* l(AddLegend(gPad));
2753 if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
2754 Float_t chi(fitStatus->GetBinContent(1));
2755 Float_t pen(fitStatus->GetBinContent(2));
2756 Int_t dof((int)fitStatus->GetBinContent(3));
2757 Float_t beta(fitStatus->GetBinContent(4));
2758 l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
2759 } else if (fitStatus) { // only available in SVD fit
2760 Int_t reg((int)fitStatus->GetBinContent(1));
2761 l->AddEntry((TObject*)0, Form("REG %i", reg), "");
2763 canvasNominalSpectraIn->cd(2);
2764 TH1D* tempSyst((TH1D*)unfoldedSpectrum->Clone(Form("%s_syst", unfoldedSpectrum->GetName())));
2765 tempSyst->SetTitle(Form("[%s]", dirNameIn.Data()));
2766 Style(tempSyst, (EColor)(i+2));
2767 Style(gPad, "SPECTRUM");
2768 if(i==0) tempSyst->DrawCopy();
2769 else tempSyst->DrawCopy("same");
2773 TH2D* pOut((TH2D*)tempOut->Get(Form("PearsonCoefficients_out_%s", dirNameOut.Data())));
2775 printf(" - %s out of plane converged \n", dirNameOut.Data());
2777 if(i==0) canvasNominalOut->cd(j);
2778 Style(gPad, "PEARSON");
2779 pOut->DrawCopy("colz");
2780 TGraphErrors* rOut((TGraphErrors*)tempOut->Get(Form("RatioRefoldedMeasured_%s", dirNameOut.Data())));
2783 printf(" > found RatioRefoldedMeasured < \n");
2784 canvasRatioMeasuredRefoldedOut->cd(j);
2785 if(i==0) canvasNominalRatioMeasuredRefoldedOut->cd(j);
2786 Style(gPad, "GRID");
2787 rOut->SetFillColor(kRed);
2790 TH1D* dvector((TH1D*)tempOut->Get("dVector"));
2791 TH1D* avalue((TH1D*)tempOut->Get("SingularValuesOfAC"));
2792 TH2D* rm((TH2D*)tempOut->Get(Form("ResponseMatrixOut_%s", dirNameOut.Data())));
2793 TH1D* eff((TH1D*)tempOut->Get(Form("KinematicEfficiencyOut_%s", dirNameOut.Data())));
2794 if(dvector && avalue && rm && eff) {
2800 if(i==0) canvasNominalMISC->cd(5);
2801 Style(gPad, "SPECTRUM");
2802 dvector->DrawCopy();
2804 if(i==0) canvasNominalMISC->cd(6);
2805 Style(gPad, "SPECTRUM");
2808 if(i==0) canvasNominalMISC->cd(7);
2809 Style(gPad, "PEARSON");
2810 rm->DrawCopy("colz");
2812 if(i==0) canvasNominalMISC->cd(8);
2813 Style(gPad, "GRID");
2815 } else if(rm && eff) {
2819 if(i==0) canvasNominalMISC->cd(7);
2820 Style(gPad, "PEARSON");
2821 rm->DrawCopy("colz");
2823 if(i==0) canvasNominalMISC->cd(8);
2824 Style(gPad, "GRID");
2828 TH1D* inputSpectrum((TH1D*)tempOut->Get(Form("InputSpectrum_out_%s", dirNameOut.Data())));
2829 TH1D* unfoldedSpectrum((TH1D*)tempOut->Get(Form("UnfoldedSpectrum_out_%s", dirNameOut.Data())));
2830 unfoldedSpectrumOutForRatio = ProtectHeap(unfoldedSpectrum, kFALSE, TString("ForRatio"));
2831 TH1D* refoldedSpectrum((TH1D*)tempOut->Get(Form("RefoldedSpectrum_out_%s", dirNameOut.Data())));
2832 if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
2833 if(defaultUnfoldedJetSpectrumOut) {
2834 Style(defaultUnfoldedJetSpectrumOut, kBlue, kUnfoldedSpectrum);
2835 TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumOut->Clone(Form("defaultUnfoldedJetSpectrumOut_%s", dirNameOut.Data())));
2836 temp->Divide(unfoldedSpectrum);
2837 // get the absolute relative error
2838 for(Int_t b(0); b < fBinsTrue->GetSize()-1; b++) {
2840 // check if the error is larger than the current maximum
2841 if(temp->GetBinContent(b+1) < 1 && temp->GetBinContent(b+1) < relativeErrorOutUp->GetBinContent(b+1)) {
2842 relativeErrorOutUp->SetBinContent(b+1, temp->GetBinContent(b+1));
2843 relativeErrorOutUp->SetBinError(b+1, 0.);
2845 // check if the error is smaller than the current minimum
2846 else if(temp->GetBinContent(b+1) > 1 && temp->GetBinContent(b+1) > relativeErrorOutLow->GetBinContent(b+1)) {
2847 relativeErrorOutLow->SetBinContent(b+1, temp->GetBinContent(b+1));
2848 relativeErrorOutLow->SetBinError(b+1, 0.);
2850 } else if (RMS && !fSymmRMS) {
2851 printf(" OOps \n ");
2852 if(temp->GetBinContent(b+1) < 1) {
2853 relativeErrorOutUp->SetBinContent(b+1, relativeErrorOutUp->GetBinContent(b+1)+TMath::Power(1.-temp->GetBinContent(b+1), 2));
2854 relativeErrorOutUpN[b]++;
2856 else if(temp->GetBinContent(b+1) > 1) {
2857 relativeErrorOutLow->SetBinContent(b+1, relativeErrorOutLow->GetBinContent(b+1)+TMath::Power(1.-temp->GetBinContent(b+1), 2));
2858 relativeErrorOutLowN[b]++;
2860 } else if (fSymmRMS) {
2861 // save symmetric rms value
2862 relativeErrorOutUp->SetBinContent(b+1, relativeErrorOutUp->GetBinContent(b+1)+TMath::Power(temp->GetBinContent(b+1)-1., 2));
2863 relativeErrorOutUpN[b]++;
2865 if(temp->GetBinError(b+1) > 0) relativeStatisticalErrorOut->SetBinContent(b+1, temp->GetBinError(b+1)/temp->GetBinContent(b+1));
2867 temp->SetTitle(Form("[%s] / [%s]", defOut.Data(), dirNameOut.Data()));
2868 temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
2869 temp->GetYaxis()->SetTitle("ratio");
2870 canvasMasterOut->cd(j);
2871 temp->GetYaxis()->SetRangeUser(0., 2);
2872 Style(gPad, "GRID");
2874 canvasNominalMasterOut->cd(1);
2875 Style(gPad, "GRID");
2877 TH1D* tempSyst((TH1D*)temp->Clone(Form("%s_syst", temp->GetName())));
2878 tempSyst->SetTitle(Form("[%s] / [%s]", defOut.Data(), dirNameOut.Data()));
2879 Style(tempSyst, (EColor)(i+2));
2880 if(i==1) tempSyst->DrawCopy();
2881 else tempSyst->DrawCopy("same");
2884 TH1F* fitStatus((TH1F*)tempOut->Get(Form("fitStatus_%s_out", dirNameOut.Data())));
2885 canvasSpectraOut->cd(j);
2886 if(i==0) canvasNominalSpectraOut->cd(1);
2888 Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
2889 unfoldedSpectrum->DrawCopy();
2890 Style(inputSpectrum, kGreen, kMeasuredSpectrum);
2891 inputSpectrum->DrawCopy("same");
2892 Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
2893 refoldedSpectrum->DrawCopy("same");
2894 TLegend* l(AddLegend(gPad));
2896 if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
2897 Float_t chi(fitStatus->GetBinContent(1));
2898 Float_t pen(fitStatus->GetBinContent(2));
2899 Int_t dof((int)fitStatus->GetBinContent(3));
2900 Float_t beta(fitStatus->GetBinContent(4));
2901 l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
2902 } else if (fitStatus) { // only available in SVD fit
2903 Int_t reg((int)fitStatus->GetBinContent(1));
2904 l->AddEntry((TObject*)0, Form("REG %i", reg), "");
2906 canvasNominalSpectraOut->cd(2);
2907 TH1D* tempSyst((TH1D*)unfoldedSpectrum->Clone(Form("%s_syst", unfoldedSpectrum->GetName())));
2908 tempSyst->SetTitle(Form("[%s]", dirNameOut.Data()));
2909 Style(tempSyst, (EColor)(i+2));
2910 Style(gPad, "SPECTRUM");
2911 if(i==0) tempSyst->DrawCopy();
2912 else tempSyst->DrawCopy("same");
2915 if(canvasRatio && canvasV2) {
2918 canvasNominalRatio->cd(j);
2919 if(nominal && nominalIn && nominalOut) {
2920 // if a nominal ratio is requested, delete the placeholder and update the nominal point
2924 nominalIn = (TH1D*)unfoldedSpectrumInForRatio->Clone("in plane jet yield");
2925 nominalOut = (TH1D*)unfoldedSpectrumOutForRatio->Clone("out of plane jet yield");
2926 nominal = (TH1D*)unfoldedSpectrumInForRatio->Clone("ratio in plane out of plane");
2927 nominal->Divide(nominal, unfoldedSpectrumOutForRatio); // standard root divide for uncorrelated histos
2930 TGraphErrors* ratioYield(GetRatio(unfoldedSpectrumInForRatio, unfoldedSpectrumOutForRatio, TString(Form("ratio [in=%s, out=%s]", dirNameIn.Data(), dirNameOut.Data()))));
2931 Double_t _tempx(0), _tempy(0);
2934 for(Int_t b(0); b < fBinsTrue->GetSize(); b++) {
2935 ratioYield->GetPoint(b, _tempx, _tempy);
2936 ratioProfile->Fill(_tempx, _tempy);
2938 ratioProfile->GetYaxis()->SetRangeUser(-0., 2.);
2939 ratioProfile->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2940 ratioYield->GetYaxis()->SetRangeUser(-0., 2.);
2941 ratioYield->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2942 ratioYield->SetFillColor(kRed);
2943 ratioYield->Draw("ap");
2946 if(i==0) canvasNominalV2->cd(j);
2947 TGraphErrors* ratioV2(GetV2(unfoldedSpectrumInForRatio,unfoldedSpectrumOutForRatio, fEventPlaneRes, TString(Form("v_{2} [in=%s, out=%s]", dirNameIn.Data(), dirNameOut.Data()))));
2950 for(Int_t b(0); b < fBinsTrue->GetSize(); b++) {
2951 ratioV2->GetPoint(b, _tempx, _tempy);
2952 v2Profile->Fill(_tempx, _tempy);
2955 v2Profile->GetYaxis()->SetRangeUser(-0., 2.);
2956 v2Profile->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2957 ratioV2->GetYaxis()->SetRangeUser(-.25, .75);
2958 ratioV2->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2959 ratioV2->SetFillColor(kRed);
2960 ratioV2->Draw("ap");
2963 delete unfoldedSpectrumInForRatio;
2964 delete unfoldedSpectrumOutForRatio;
2966 // save the canvasses
2967 canvasProfiles->cd(1);
2968 Style(ratioProfile);
2969 ratioProfile->DrawCopy();
2970 canvasProfiles->cd(2);
2972 v2Profile->DrawCopy();
2973 SavePadToPDF(canvasProfiles);
2974 canvasProfiles->Write();
2975 SavePadToPDF(canvasIn);
2978 SavePadToPDF(canvasOut);
2981 SavePadToPDF(canvasRatioMeasuredRefoldedIn);
2982 canvasRatioMeasuredRefoldedIn->Write();
2983 if(canvasRatioMeasuredRefoldedOut) {
2984 SavePadToPDF(canvasRatioMeasuredRefoldedOut);
2985 canvasRatioMeasuredRefoldedOut->Write();
2987 SavePadToPDF(canvasSpectraIn);
2988 canvasSpectraIn->Write();
2989 if(canvasSpectraOut) {
2990 SavePadToPDF(canvasSpectraOut);
2991 canvasSpectraOut->Write();
2992 SavePadToPDF(canvasRatio);
2993 canvasRatio->Write();
2994 SavePadToPDF(canvasV2);
2997 SavePadToPDF(canvasMasterIn);
2998 canvasMasterIn->Write();
2999 if(canvasMasterOut) {
3000 SavePadToPDF(canvasMasterOut);
3001 canvasMasterOut->Write();
3003 SavePadToPDF(canvasMISC);
3004 canvasMISC->Write();
3005 // save the nomial canvasses
3006 SavePadToPDF(canvasNominalIn);
3007 canvasNominalIn->Write();
3008 if(canvasNominalOut) {
3009 SavePadToPDF(canvasNominalOut);
3010 canvasNominalOut->Write();
3012 SavePadToPDF(canvasNominalRatioMeasuredRefoldedIn);
3013 canvasNominalRatioMeasuredRefoldedIn->Write();
3014 if(canvasNominalRatioMeasuredRefoldedOut) {
3015 SavePadToPDF(canvasNominalRatioMeasuredRefoldedOut);
3016 canvasNominalRatioMeasuredRefoldedOut->Write();
3018 canvasNominalSpectraIn->cd(2);
3019 Style(AddLegend(gPad));
3020 SavePadToPDF(canvasNominalSpectraIn);
3021 canvasNominalSpectraIn->Write();
3022 if(canvasNominalSpectraOut) {
3023 canvasNominalSpectraOut->cd(2);
3024 Style(AddLegend(gPad));
3025 SavePadToPDF(canvasNominalSpectraOut);
3026 canvasNominalSpectraOut->Write();
3027 SavePadToPDF(canvasNominalRatio);
3028 canvasNominalRatio->Write();
3029 SavePadToPDF(canvasNominalV2);
3030 canvasNominalV2->Write();
3032 canvasNominalMasterIn->cd(1);
3033 Style(AddLegend(gPad));
3034 lineUp->DrawClone("same");
3035 lineLow->DrawClone("same");
3036 SavePadToPDF(canvasNominalMasterIn);
3037 canvasNominalMasterIn->Write();
3038 if(canvasNominalMasterOut) {
3039 canvasNominalMasterOut->cd(1);
3040 Style(AddLegend(gPad));
3041 lineUp->DrawClone("same");
3042 lineLow->DrawClone("same");
3043 SavePadToPDF(canvasNominalMasterOut);
3044 canvasNominalMasterOut->Write();
3046 SavePadToPDF(canvasNominalMISC);
3047 canvasNominalMISC->Write();
3049 // save the relative errors
3050 for(Int_t b(0); b < fBinsTrue->GetSize()-1; b++) {
3051 // to arrive at a min and max from here, combine in up and out low
3053 relativeErrorInUp->SetBinContent(b+1, -1.*(relativeErrorInUp->GetBinContent(b+1)-1));
3054 relativeErrorInUp->SetBinError(b+1, 0.);
3055 relativeErrorOutUp->SetBinContent(b+1, -1.*(relativeErrorOutUp->GetBinContent(b+1)-1));
3056 relativeErrorOutUp->SetBinError(b+1, .0);
3057 relativeErrorInLow->SetBinContent(b+1, -1.*(relativeErrorInLow->GetBinContent(b+1)-1));
3058 relativeErrorInLow->SetBinError(b+1, 0.);
3059 relativeErrorOutLow->SetBinContent(b+1, -1.*(relativeErrorOutLow->GetBinContent(b+1)-1));
3060 relativeErrorOutLow->SetBinError(b+1, .0);
3062 // these guys are already stored as percentages, so no need to remove the offset of 1
3063 // RMS is defined as sqrt(sum(squared))/N
3064 // min is defined as negative, max is defined as positive
3066 if(relativeErrorInUpN[b] < 1) relativeErrorInUpN[b] = 1;
3067 if(relativeErrorInLowN[b] < 1) relativeErrorInLowN[b] = 1;
3068 if(relativeErrorOutUpN[b] < 1) relativeErrorOutUpN[b] = 1;
3069 if(relativeErrorOutLowN[b] < 1) relativeErrorOutLowN[b] = 1;
3070 relativeErrorInUp->SetBinContent(b+1, TMath::Sqrt(relativeErrorInUp->GetBinContent(b+1)/relativeErrorInUpN[b]));
3071 relativeErrorInUp->SetBinError(b+1, 0.);
3072 relativeErrorOutUp->SetBinContent(b+1, TMath::Sqrt(relativeErrorOutUp->GetBinContent(b+1)/relativeErrorOutUpN[b]));
3073 relativeErrorOutUp->SetBinError(b+1, .0);
3074 relativeErrorInLow->SetBinContent(b+1, -1.*TMath::Sqrt(relativeErrorInLow->GetBinContent(b+1)/relativeErrorInLowN[b]));
3075 relativeErrorInLow->SetBinError(b+1, 0.);
3076 relativeErrorOutLow->SetBinContent(b+1, -1.*TMath::Sqrt(relativeErrorOutLow->GetBinContent(b+1)/relativeErrorOutLowN[b]));
3077 relativeErrorOutLow->SetBinError(b+1, .0);
3078 } else if (fSymmRMS) {
3079 if(relativeErrorInUpN[b] < 1) relativeErrorInUpN[b] = 1;
3080 if(relativeErrorOutUpN[b] < 1) relativeErrorOutUpN[b] = 1;
3081 relativeErrorInUp->SetBinContent(b+1, TMath::Sqrt(relativeErrorInUp->GetBinContent(b+1)/relativeErrorInUpN[b]));
3082 relativeErrorOutUp->SetBinContent(b+1, TMath::Sqrt(relativeErrorOutUp->GetBinContent(b+1)/relativeErrorOutUpN[b]));
3086 relativeErrorInUp->SetYTitle("relative uncertainty");
3087 relativeErrorOutUp->SetYTitle("relative uncertainty");
3088 relativeErrorInLow->SetYTitle("relative uncertainty");
3089 relativeErrorOutLow->SetYTitle("relative uncertainty");
3090 relativeErrorInUp->GetYaxis()->SetRangeUser(-1.5, 3.);
3091 relativeErrorInLow->GetYaxis()->SetRangeUser(-1.5, 3.);
3092 relativeErrorOutUp->GetYaxis()->SetRangeUser(-1.5, 3.);
3093 relativeErrorOutLow->GetYaxis()->SetRangeUser(-1.5, 3.);
3095 canvasNominalMasterIn->cd(2);
3096 Style(gPad, "GRID");
3097 Style(relativeErrorInUp, kBlue, kBar);
3098 Style(relativeErrorInLow, kGreen, kBar);
3099 relativeErrorInUp->DrawCopy("b");
3100 relativeErrorInLow->DrawCopy("same b");
3101 Style(AddLegend(gPad));
3102 SavePadToPDF(canvasNominalMasterIn);
3103 canvasNominalMasterIn->Write();
3104 canvasNominalMasterOut->cd(2);
3105 Style(gPad, "GRID");
3106 Style(relativeErrorOutUp, kBlue, kBar);
3107 Style(relativeErrorOutLow, kGreen, kBar);
3108 relativeErrorOutUp->DrawCopy("b");
3109 relativeErrorOutLow->DrawCopy("same b");
3110 Style(AddLegend(gPad));
3111 SavePadToPDF(canvasNominalMasterOut);
3112 canvasNominalMasterOut->Write();
3114 //_____________________________________________________________________________
3115 void AliJetFlowTools::PostProcess(TString def, Int_t columns, Float_t rangeLow, Float_t rangeUp, TString in, TString out) const
3117 // go through the output file and perform post processing routines
3118 // can either be performed in one go with the unfolding, or at a later stage
3119 if(fOutputFile && !fOutputFile->IsZombie()) fOutputFile->Close();
3120 TFile readMe(in.Data(), "READ"); // open file read-only
3121 if(readMe.IsZombie()) {
3122 printf(" > Fatal error, couldn't read %s for post processing ! < \n", in.Data());
3125 printf("\n\n\n\t\t POSTPROCESSING \n > Recovered the following file structure : \n <");
3127 TList* listOfKeys((TList*)readMe.GetListOfKeys());
3129 printf(" > Fatal error, couldn't retrieve list of keys. Input file might have been corrupted ! < \n");
3132 // prepare necessary canvasses
3133 TCanvas* canvasIn(new TCanvas("PearsonIn", "PearsonIn"));
3134 TCanvas* canvasOut(0x0);
3135 if(fDphiUnfolding) canvasOut = new TCanvas("PearsonOut", "PearsonOut");
3136 TCanvas* canvasRatioMeasuredRefoldedIn(new TCanvas("RefoldedIn", "RefoldedIn"));
3137 TCanvas* canvasRatioMeasuredRefoldedOut(0x0);
3138 if(fDphiUnfolding) canvasRatioMeasuredRefoldedOut = new TCanvas("RefoldedOut", "RefoldedOut");
3139 TCanvas* canvasSpectraIn(new TCanvas("SpectraIn", "SpectraIn"));
3140 TCanvas* canvasSpectraOut(0x0);
3141 if(fDphiUnfolding) canvasSpectraOut = new TCanvas("SpectraOut", "SpectraOut");
3142 TCanvas* canvasRatio(0x0);
3143 if(fDphiUnfolding) canvasRatio = new TCanvas("Ratio", "Ratio");
3144 TCanvas* canvasV2(0x0);
3145 if(fDphiUnfolding) canvasV2 = new TCanvas("V2", "V2");
3146 TCanvas* canvasMISC(new TCanvas("MISC", "MISC"));
3147 TCanvas* canvasMasterIn(new TCanvas("defaultIn", "defaultIn"));
3148 TCanvas* canvasMasterOut(0x0);
3149 if(fDphiUnfolding) canvasMasterOut = new TCanvas("defaultOut", "defaultOut");
3150 (fDphiUnfolding) ? canvasMISC->Divide(4, 2) : canvasMISC->Divide(4, 1);
3151 TDirectoryFile* defDir(0x0);
3152 TCanvas* canvasProfiles(new TCanvas("canvasProfiles", "canvasProfiles"));
3153 canvasProfiles->Divide(2);
3154 TProfile* ratioProfile(new TProfile("ratioProfile", "ratioProfile", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
3155 TProfile* v2Profile(new TProfile("v2Profile", "v2Profile", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
3156 // get an estimate of the number of outputs and find the default set
3158 for(Int_t i(0); i < listOfKeys->GetSize(); i++) {
3159 if(dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()))) {
3160 if(!strcmp(listOfKeys->At(i)->GetName(), def.Data())) defDir = dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()));
3164 Int_t rows(TMath::Floor(cacheMe/(float)columns)+((cacheMe%columns)>0));
3165 canvasIn->Divide(columns, rows);
3166 if(canvasOut) canvasOut->Divide(columns, rows);
3167 canvasRatioMeasuredRefoldedIn->Divide(columns, rows);
3168 if(canvasRatioMeasuredRefoldedOut) canvasRatioMeasuredRefoldedOut->Divide(columns, rows);
3169 canvasSpectraIn->Divide(columns, rows);
3170 if(canvasSpectraOut) canvasSpectraOut->Divide(columns, rows);
3171 if(canvasRatio) canvasRatio->Divide(columns, rows);
3172 if(canvasV2) canvasV2->Divide(columns, rows);
3174 canvasMasterIn->Divide(columns, rows);
3175 if(canvasMasterOut) canvasMasterOut->Divide(columns, rows);
3176 // extract the default output
3177 TH1D* defaultUnfoldedJetSpectrumIn(0x0);
3178 TH1D* defaultUnfoldedJetSpectrumOut(0x0);
3180 TDirectoryFile* defDirIn = (TDirectoryFile*)defDir->Get(Form("InPlane___%s", def.Data()));
3181 TDirectoryFile* defDirOut = (TDirectoryFile*)defDir->Get(Form("OutOfPlane___%s", def.Data()));
3182 if(defDirIn) defaultUnfoldedJetSpectrumIn = (TH1D*)defDirIn->Get(Form("UnfoldedSpectrum_in_%s", def.Data()));
3183 if(defDirOut) defaultUnfoldedJetSpectrumOut = (TH1D*)defDirOut->Get(Form("UnfoldedSpectrum_out_%s", def.Data()));
3184 printf(" > succesfully extracted default results < \n");
3187 // loop through the directories, only plot the graphs if the deconvolution converged
3188 TDirectoryFile* tempDir(0x0);
3189 TDirectoryFile* tempIn(0x0);
3190 TDirectoryFile* tempOut(0x0);
3191 for(Int_t i(0), j(0); i < listOfKeys->GetSize(); i++) {
3192 // read the directory by its name
3193 tempDir = dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()));
3194 if(!tempDir) continue;
3195 TString dirName(tempDir->GetName());
3196 // try to read the in- and out of plane subdirs
3197 tempIn = (TDirectoryFile*)tempDir->Get(Form("InPlane___%s", dirName.Data()));
3198 tempOut = (TDirectoryFile*)tempDir->Get(Form("OutOfPlane___%s", dirName.Data()));
3200 if(!tempIn) { // attempt to get MakeAU output
3201 TString stringArray[] = {"a", "b", "c", "d", "e", "f", "g", "h"};
3202 TCanvas* tempPearson(new TCanvas(Form("pearson_%s", dirName.Data()), Form("pearson_%s", dirName.Data())));
3203 tempPearson->Divide(4,2);
3204 TCanvas* tempRatio(new TCanvas(Form("ratio_%s", dirName.Data()), Form("ratio_%s", dirName.Data())));
3205 tempRatio->Divide(4,2);
3206 TCanvas* tempResult(new TCanvas(Form("result_%s", dirName.Data()), Form("result_%s", dirName.Data())));
3207 tempResult->Divide(4,2);
3208 for(Int_t q(0); q < 8; q++) {
3209 tempIn = (TDirectoryFile*)tempDir->Get(Form("%s___%s", stringArray[q].Data(), dirName.Data()));
3211 // to see if the unfolding converged try to extract the pearson coefficients
3212 TH2D* pIn((TH2D*)tempIn->Get(Form("PearsonCoefficients_in_%s", dirName.Data())));
3214 printf(" - %s in plane converged \n", dirName.Data());
3215 tempPearson->cd(1+q);
3216 Style(gPad, "PEARSON");
3217 pIn->DrawCopy("colz");
3218 TGraphErrors* rIn((TGraphErrors*)tempIn->Get(Form("RatioRefoldedMeasured_%s", dirName.Data())));
3221 printf(" > found RatioRefoldedMeasured < \n");
3223 rIn->SetFillColor(kRed);
3226 TH1D* dvector((TH1D*)tempIn->Get("dVector"));
3227 TH1D* avalue((TH1D*)tempIn->Get("SingularValuesOfAC"));
3228 TH2D* rm((TH2D*)tempIn->Get(Form("ResponseMatrixIn_%s", dirName.Data())));
3229 TH1D* eff((TH1D*)tempIn->Get(Form("KinematicEfficiencyIn_%s", dirName.Data())));
3230 if(dvector && avalue && rm && eff) {
3236 Style(gPad, "SPECTRUM");
3237 dvector->DrawCopy();
3239 Style(gPad, "SPECTRUM");
3242 Style(gPad, "PEARSON");
3243 rm->DrawCopy("colz");
3245 Style(gPad, "GRID");
3247 } else if(rm && eff) {
3251 Style(gPad, "PEARSON");
3252 rm->DrawCopy("colz");
3254 Style(gPad, "GRID");
3258 TH1D* inputSpectrum((TH1D*)tempIn->Get(Form("InputSpectrum_in_%s", dirName.Data())));
3259 TH1D* unfoldedSpectrum((TH1D*)tempIn->Get(Form("UnfoldedSpectrum_in_%s", dirName.Data())));
3260 TH1D* refoldedSpectrum((TH1D*)tempIn->Get(Form("RefoldedSpectrum_in_%s", dirName.Data())));
3261 if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
3262 if(defaultUnfoldedJetSpectrumIn) {
3263 Style(defaultUnfoldedJetSpectrumIn, kBlue, kUnfoldedSpectrum);
3264 TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumIn->Clone(Form("defaultUnfoldedJetSpectrumIn_%s", dirName.Data())));
3265 temp->Divide(unfoldedSpectrum);
3266 temp->SetTitle(Form("ratio default unfolded / %s", dirName.Data()));
3267 temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
3268 temp->GetYaxis()->SetTitle(Form("%s / %s", def.Data(), dirName.Data()));
3269 canvasMasterIn->cd(j);
3270 temp->GetYaxis()->SetRangeUser(0., 2);
3273 TH1F* fitStatus((TH1F*)tempIn->Get(Form("fitStatus_%s_in", dirName.Data())));
3274 tempResult->cd(q+1);
3276 Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
3277 unfoldedSpectrum->DrawCopy();
3278 Style(inputSpectrum, kGreen, kMeasuredSpectrum);
3279 inputSpectrum->DrawCopy("same");
3280 Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
3281 refoldedSpectrum->DrawCopy("same");
3282 TLegend* l(AddLegend(gPad));
3284 if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
3285 Float_t chi(fitStatus->GetBinContent(1));
3286 Float_t pen(fitStatus->GetBinContent(2));
3287 Int_t dof((int)fitStatus->GetBinContent(3));
3288 Float_t beta(fitStatus->GetBinContent(4));
3289 l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
3290 } else if (fitStatus) { // only available in SVD fit
3291 Int_t reg((int)fitStatus->GetBinContent(1));
3292 l->AddEntry((TObject*)0, Form("REG %i", reg), "");
3299 // to see if the unfolding converged try to extract the pearson coefficients
3300 TH2D* pIn((TH2D*)tempIn->Get(Form("PearsonCoefficients_in_%s", dirName.Data())));
3302 printf(" - %s in plane converged \n", dirName.Data());
3304 Style(gPad, "PEARSON");
3305 pIn->DrawCopy("colz");
3306 TGraphErrors* rIn((TGraphErrors*)tempIn->Get(Form("RatioRefoldedMeasured_%s", dirName.Data())));
3309 printf(" > found RatioRefoldedMeasured < \n");
3310 canvasRatioMeasuredRefoldedIn->cd(j);
3311 rIn->SetFillColor(kRed);
3314 TH1D* dvector((TH1D*)tempIn->Get("dVector"));
3315 TH1D* avalue((TH1D*)tempIn->Get("SingularValuesOfAC"));
3316 TH2D* rm((TH2D*)tempIn->Get(Form("ResponseMatrixIn_%s", dirName.Data())));
3317 TH1D* eff((TH1D*)tempIn->Get(Form("KinematicEfficiencyIn_%s", dirName.Data())));
3318 if(dvector && avalue && rm && eff) {
3324 Style(gPad, "SPECTRUM");
3325 dvector->DrawCopy();
3327 Style(gPad, "SPECTRUM");
3330 Style(gPad, "PEARSON");
3331 rm->DrawCopy("colz");
3333 Style(gPad, "GRID");
3335 } else if(rm && eff) {
3339 Style(gPad, "PEARSON");
3340 rm->DrawCopy("colz");
3342 Style(gPad, "GRID");
3346 TH1D* inputSpectrum((TH1D*)tempIn->Get(Form("InputSpectrum_in_%s", dirName.Data())));
3347 TH1D* unfoldedSpectrum((TH1D*)tempIn->Get(Form("UnfoldedSpectrum_in_%s", dirName.Data())));
3348 TH1D* refoldedSpectrum((TH1D*)tempIn->Get(Form("RefoldedSpectrum_in_%s", dirName.Data())));
3349 if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
3350 if(defaultUnfoldedJetSpectrumIn) {
3351 Style(defaultUnfoldedJetSpectrumIn, kBlue, kUnfoldedSpectrum);
3352 TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumIn->Clone(Form("defaultUnfoldedJetSpectrumIn_%s", dirName.Data())));
3353 temp->Divide(unfoldedSpectrum);
3354 temp->SetTitle(Form("ratio default unfolded / %s", dirName.Data()));
3355 temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
3356 temp->GetYaxis()->SetTitle(Form("%s / %s", def.Data(), dirName.Data()));
3357 canvasMasterIn->cd(j);
3358 temp->GetYaxis()->SetRangeUser(0., 2);
3361 TH1F* fitStatus((TH1F*)tempIn->Get(Form("fitStatus_%s_in", dirName.Data())));
3362 canvasSpectraIn->cd(j);
3364 Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
3365 unfoldedSpectrum->DrawCopy();
3366 Style(inputSpectrum, kGreen, kMeasuredSpectrum);
3367 inputSpectrum->DrawCopy("same");
3368 Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
3369 refoldedSpectrum->DrawCopy("same");
3370 TLegend* l(AddLegend(gPad));
3372 if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
3373 Float_t chi(fitStatus->GetBinContent(1));
3374 Float_t pen(fitStatus->GetBinContent(2));
3375 Int_t dof((int)fitStatus->GetBinContent(3));
3376 Float_t beta(fitStatus->GetBinContent(4));
3377 l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
3378 } else if (fitStatus) { // only available in SVD fit
3379 Int_t reg((int)fitStatus->GetBinContent(1));
3380 l->AddEntry((TObject*)0, Form("REG %i", reg), "");
3385 TH2D* pOut((TH2D*)tempOut->Get(Form("PearsonCoefficients_out_%s", dirName.Data())));
3387 printf(" - %s out of plane converged \n", dirName.Data());
3389 Style(gPad, "PEARSON");
3390 pOut->DrawCopy("colz");
3391 TGraphErrors* rOut((TGraphErrors*)tempOut->Get(Form("RatioRefoldedMeasured_%s", dirName.Data())));
3394 printf(" > found RatioRefoldedMeasured < \n");
3395 canvasRatioMeasuredRefoldedOut->cd(j);
3396 rOut->SetFillColor(kRed);
3399 TH1D* dvector((TH1D*)tempOut->Get("dVector"));
3400 TH1D* avalue((TH1D*)tempOut->Get("SingularValuesOfAC"));
3401 TH2D* rm((TH2D*)tempOut->Get(Form("ResponseMatrixOut_%s", dirName.Data())));
3402 TH1D* eff((TH1D*)tempOut->Get(Form("KinematicEfficiencyOut_%s", dirName.Data())));
3403 if(dvector && avalue && rm && eff) {
3409 Style(gPad, "SPECTRUM");
3410 dvector->DrawCopy();
3412 Style(gPad, "SPECTRUM");
3415 Style(gPad, "PEARSON");
3416 rm->DrawCopy("colz");
3418 Style(gPad, "GRID");
3420 } else if(rm && eff) {
3424 Style(gPad, "PEARSON");
3425 rm->DrawCopy("colz");
3427 Style(gPad, "GRID");
3431 TH1D* inputSpectrum((TH1D*)tempOut->Get(Form("InputSpectrum_out_%s", dirName.Data())));
3432 TH1D* unfoldedSpectrum((TH1D*)tempOut->Get(Form("UnfoldedSpectrum_out_%s", dirName.Data())));
3433 TH1D* refoldedSpectrum((TH1D*)tempOut->Get(Form("RefoldedSpectrum_out_%s", dirName.Data())));
3434 if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
3435 if(defaultUnfoldedJetSpectrumOut) {
3436 Style(defaultUnfoldedJetSpectrumOut, kBlue, kUnfoldedSpectrum);
3437 TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumOut->Clone(Form("defaultUnfoldedJetSpectrumOut_%s", dirName.Data())));
3438 temp->Divide(unfoldedSpectrum);
3439 temp->SetTitle(Form("ratio default unfolded / %s", dirName.Data()));
3440 temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
3441 temp->GetYaxis()->SetTitle(Form("%s / %s", def.Data(), dirName.Data()));
3442 canvasMasterOut->cd(j);
3443 temp->GetYaxis()->SetRangeUser(0., 2.);
3446 TH1F* fitStatus((TH1F*)tempOut->Get(Form("fitStatus_%s_out", dirName.Data())));
3447 canvasSpectraOut->cd(j);
3449 Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
3450 unfoldedSpectrum->DrawCopy();
3451 Style(inputSpectrum, kGreen, kMeasuredSpectrum);
3452 inputSpectrum->DrawCopy("same");
3453 Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
3454 refoldedSpectrum->DrawCopy("same");
3455 TLegend* l(AddLegend(gPad));
3457 if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
3458 Float_t chi(fitStatus->GetBinContent(1));
3459 Float_t pen(fitStatus->GetBinContent(2));
3460 Int_t dof((int)fitStatus->GetBinContent(3));
3461 Float_t beta(fitStatus->GetBinContent(4));
3462 l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
3463 } else if (fitStatus) { // only available in SVD fit
3464 Int_t reg((int)fitStatus->GetBinContent(1));
3465 l->AddEntry((TObject*)0, Form("REG %i", reg), "");
3469 if(canvasRatio && canvasV2) {
3471 TGraphErrors* ratioYield((TGraphErrors*)tempDir->Get(Form("RatioInOutPlane_%s", dirName.Data())));
3472 Double_t _tempx(0), _tempy(0);
3475 for(Int_t b(0); b < fBinsTrue->GetSize(); b++) {
3476 ratioYield->GetPoint(b, _tempx, _tempy);
3477 ratioProfile->Fill(_tempx, _tempy);
3479 ratioProfile->GetYaxis()->SetRangeUser(-0., 2.);
3480 ratioProfile->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
3481 ratioYield->GetYaxis()->SetRangeUser(-0., 2.);
3482 ratioYield->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
3483 ratioYield->SetFillColor(kRed);
3484 ratioYield->Draw("ap");
3487 TGraphErrors* ratioV2((TGraphErrors*)tempDir->Get(Form("v2_%s", dirName.Data())));
3490 for(Int_t b(0); b < fBinsTrue->GetSize(); b++) {
3491 ratioV2->GetPoint(b, _tempx, _tempy);
3492 v2Profile->Fill(_tempx, _tempy);
3495 v2Profile->GetYaxis()->SetRangeUser(-0., 2.);
3496 v2Profile->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
3497 ratioV2->GetYaxis()->SetRangeUser(-.25, .75);
3498 ratioV2->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
3499 ratioV2->SetFillColor(kRed);
3500 ratioV2->Draw("ap");
3504 TFile output(out.Data(), "RECREATE");
3505 canvasProfiles->cd(1);
3506 Style(ratioProfile);
3507 ratioProfile->DrawCopy();
3508 canvasProfiles->cd(2);
3510 v2Profile->DrawCopy();
3511 SavePadToPDF(canvasProfiles);
3512 canvasProfiles->Write();
3513 SavePadToPDF(canvasIn);
3516 SavePadToPDF(canvasOut);
3519 SavePadToPDF(canvasRatioMeasuredRefoldedIn);
3520 canvasRatioMeasuredRefoldedIn->Write();
3521 if(canvasRatioMeasuredRefoldedOut) {
3522 SavePadToPDF(canvasRatioMeasuredRefoldedOut);
3523 canvasRatioMeasuredRefoldedOut->Write();
3525 SavePadToPDF(canvasSpectraIn);
3526 canvasSpectraIn->Write();
3527 if(canvasSpectraOut) {
3528 SavePadToPDF(canvasSpectraOut);
3529 canvasSpectraOut->Write();
3530 SavePadToPDF(canvasRatio);
3531 canvasRatio->Write();
3532 SavePadToPDF(canvasV2);
3535 SavePadToPDF(canvasMasterIn);
3536 canvasMasterIn->Write();
3537 if(canvasMasterOut) {
3538 SavePadToPDF(canvasMasterOut);
3539 canvasMasterOut->Write();
3541 SavePadToPDF(canvasMISC);
3542 canvasMISC->Write();
3546 //_____________________________________________________________________________
3547 void AliJetFlowTools::BootstrapSpectra(TString def, TString in, TString out) const
3549 // function to interpret results of bootstrapping routine
3550 // TString def should hold the true emperical distribution
3551 if(fOutputFile && !fOutputFile->IsZombie()) fOutputFile->Close();
3552 TFile readMe(in.Data(), "READ"); // open file read-only
3553 if(readMe.IsZombie()) {
3554 printf(" > Fatal error, couldn't read %s for post processing ! < \n", in.Data());
3557 printf("\n\n\n\t\t BootstrapSpectra \n > Recovered the following file structure : \n <");
3559 TList* listOfKeys((TList*)readMe.GetListOfKeys());
3561 printf(" > Fatal error, couldn't retrieve list of keys. Input file might have been corrupted ! < \n");
3564 // get an estimate of the number of outputs and find the default set
3565 TDirectoryFile* defDir(0x0);
3566 for(Int_t i(0); i < listOfKeys->GetSize(); i++) {
3567 if(dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()))) {
3568 if(!strcmp(listOfKeys->At(i)->GetName(), def.Data())) defDir = dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()));
3572 // extract the default output this is the 'emperical' distribution
3573 // w.r.t. which the other distributions will be evaluated
3574 TH1D* defaultUnfoldedJetSpectrumIn(0x0);
3575 TH1D* defaultUnfoldedJetSpectrumOut(0x0);
3576 TH1D* defaultInputSpectrumIn(0x0);
3577 TH1D* defaultInputSpectrumOut(0x0);
3578 TGraphErrors* v2Emperical(0x0);
3580 TDirectoryFile* defDirIn = (TDirectoryFile*)defDir->Get(Form("InPlane___%s", def.Data()));
3581 TDirectoryFile* defDirOut = (TDirectoryFile*)defDir->Get(Form("OutOfPlane___%s", def.Data()));
3583 defaultUnfoldedJetSpectrumIn = (TH1D*)defDirIn->Get(Form("UnfoldedSpectrum_in_%s", def.Data()));
3584 defaultInputSpectrumIn = (TH1D*)defDirIn->Get(Form("InputSpectrum_in_%s", def.Data()));
3587 defaultUnfoldedJetSpectrumOut = (TH1D*)defDirOut->Get(Form("UnfoldedSpectrum_out_%s", def.Data()));
3588 defaultInputSpectrumOut = (TH1D*)defDirOut->Get(Form("InputSpectrum_out_%s", def.Data()));
3591 if((!defaultUnfoldedJetSpectrumIn && defaultUnfoldedJetSpectrumOut)) {
3592 printf(" BootstrapSpectra: couldn't extract default spectra, aborting! \n");
3595 else v2Emperical = GetV2(defaultUnfoldedJetSpectrumIn, defaultUnfoldedJetSpectrumOut, fEventPlaneRes);
3597 // now that we know for sure that the input is in place, reserve the bookkeeping histograms
3598 TH1F* delta0[fBinsTrue->GetSize()-1];
3599 for(Int_t i(0); i < fBinsTrue->GetSize()-1; i++) {
3600 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);
3603 // and a canvas for illustration purposes only
3604 TCanvas* spectraIn(new TCanvas("spectraIn", "spectraIn"));
3605 TCanvas* spectraOut(new TCanvas("spectraOut", "spectraOut"));
3606 // common reference (in this case the generated v2)
3607 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);
3609 // loop through the directories, only plot the graphs if the deconvolution converged
3610 TDirectoryFile* tempDir(0x0);
3611 TDirectoryFile* tempIn(0x0);
3612 TDirectoryFile* tempOut(0x0);
3613 TH1D* unfoldedSpectrumIn(0x0);
3614 TH1D* unfoldedSpectrumOut(0x0);
3615 TH1D* measuredSpectrumIn(0x0);
3616 TH1D* measuredSpectrumOut(0x0);
3617 for(Int_t i(0), j(0); i < listOfKeys->GetSize(); i++) {
3618 // read the directory by its name
3619 tempDir = dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()));
3620 if(!tempDir) continue;
3621 TString dirName(tempDir->GetName());
3622 // read only bootstrapped outputs
3623 if(!dirName.Contains("bootstrap")) continue;
3624 // try to read the in- and out of plane subdirs
3625 tempIn = (TDirectoryFile*)tempDir->Get(Form("InPlane___%s", dirName.Data()));
3626 tempOut = (TDirectoryFile*)tempDir->Get(Form("OutOfPlane___%s", dirName.Data()));
3628 // extract the unfolded spectra only if both in- and out-of-plane converted (i.e. pearson coefficients were saved)
3630 if(!(TH2D*)tempIn->Get(Form("PearsonCoefficients_in_%s", dirName.Data()))) continue;
3631 unfoldedSpectrumIn = (TH1D*)tempIn->Get(Form("UnfoldedSpectrum_in_%s", dirName.Data()));
3632 measuredSpectrumIn = (TH1D*)tempIn->Get(Form("InputSpectrum_in_%s", dirName.Data()));
3634 (j==1) ? measuredSpectrumIn->DrawCopy() : measuredSpectrumIn->DrawCopy("same");
3637 if(!(TH2D*)tempOut->Get(Form("PearsonCoefficients_out_%s", dirName.Data()))) continue;
3638 unfoldedSpectrumOut = (TH1D*)tempOut->Get(Form("UnfoldedSpectrum_out_%s", dirName.Data()));
3639 measuredSpectrumOut = (TH1D*)tempOut->Get(Form("InputSpectrum_out_%s", dirName.Data()));
3641 (j==1) ? measuredSpectrumOut->DrawCopy() : measuredSpectrumOut->DrawCopy("same");
3643 // get v2 with statistical uncertainties from the extracted spectra
3644 TGraphErrors* v2Bootstrapped(GetV2(unfoldedSpectrumIn, unfoldedSpectrumOut, fEventPlaneRes));
3645 // and loop over all bins to fill the bookkeeping histograms
3646 Double_t yBoot(0), yEmp(0), xDud(0);
3647 // optional: common reference (in this case the sampled v2 value)
3648 for(Int_t k(0); k < fBinsTrue->GetSize()-1; k++) {
3649 // read values point by point (passed by reference)
3650 v2Bootstrapped->GetPoint(k, xDud, yBoot);
3651 v2Emperical->GetPoint(k, xDud, yEmp);
3652 if(commonReference) {
3653 if(!commonReference->Eval(xDud)<1e-10) {
3654 yEmp/=commonReference->Eval(xDud);
3655 yBoot/=commonReference->Eval(xDud);
3656 } else { // if reference equals zero, take emperical distribution as reference
3661 cout << " yEmp " << yEmp << " yBoot " << yBoot << endl;
3662 // save relative difference per pt bin
3663 if(TMath::Abs(yBoot)>1e-10) delta0[k]->Fill(yEmp - yBoot);
3666 // extracting final results now, as first estimate just a gaus fit to the distributions
3667 // (should be changed perhaps to proper rms eventually)
3668 // attach relevant data to current buffer in the same loop
3669 TFile output(out.Data(), "RECREATE");
3670 defaultInputSpectrumIn->SetLineColor(kRed);
3672 defaultInputSpectrumIn->DrawCopy("same");
3673 defaultInputSpectrumOut->SetLineColor(kRed);
3675 defaultInputSpectrumOut->DrawCopy("same");
3677 spectraOut->Write();
3679 TH1F* delta0spread(new TH1F("delta0spread", "#sigma(#Delta_{0})", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
3680 TH1F* unfoldingError(new TH1F("unfoldingError", "error from unfolding algorithm", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
3681 TF1* gaus(new TF1("gaus", "gaus"/*[0]*exp(-0.5*((x-[1])/[2])**2)"*/, -1., 1.));
3682 Double_t xDud(0), yDud(0);
3683 for(Int_t i(0); i < fBinsTrue->GetSize()-1; i++) {
3684 delta0[i]->Fit(gaus);
3685 delta0[i]->GetYaxis()->SetTitle("counts");
3686 delta0[i]->GetXaxis()->SetTitle("(v_{2, jet}^{measured} - v_{2, jet}^{generated}) / input v_{2}");
3687 delta0spread->SetBinContent(i+1, gaus->GetParameter(1)); // mean of gaus
3688 delta0spread->SetBinError(i+1, gaus->GetParameter(2)); // sigma of gaus
3689 cout << " mean " << gaus->GetParameter(1) << endl;
3690 cout << " sigm " << gaus->GetParameter(2) << endl;
3692 v2Emperical->GetPoint(i, xDud, yDud);
3693 unfoldingError->SetBinContent(i+1, 1e-10/*gaus->GetParameter(1)*/);
3694 if(commonReference && !commonReference->Eval(xDud)<1e-10) unfoldingError->SetBinError(i+1, v2Emperical->GetErrorY(i)/(commonReference->Eval(xDud)));
3695 else if(yDud>10e-10) unfoldingError->SetBinError(i+1, v2Emperical->GetErrorY(i)/yDud);
3696 else unfoldingError->SetBinError(i+1, 0.);
3698 delta0spread->GetXaxis()->SetTitle("p_{T}^{jet} (GeV/c)");
3699 delta0spread->GetYaxis()->SetTitle("(mean v_{2, jet}^{measured} - v_{2, jet}^{generated}) / input v_{2}");
3700 delta0spread->Write();
3701 unfoldingError->GetXaxis()->SetTitle("p_{T}^{jet} (GeV/c)");
3702 unfoldingError->GetYaxis()->SetTitle("(mean v_{2, jet}^{measured} - v_{2, jet}^{generated}) / input v_{2}");
3703 unfoldingError->Write();
3704 // write the buffer and close the file
3708 //_____________________________________________________________________________
3709 Bool_t AliJetFlowTools::SetRawInput (
3710 TH2D* detectorResponse, // detector response matrix
3711 TH1D* jetPtIn, // in plane jet spectrum
3712 TH1D* jetPtOut, // out of plane jet spectrum
3713 TH1D* dptIn, // in plane delta pt distribution
3714 TH1D* dptOut, // out of plane delta pt distribution
3716 // set input histograms manually
3717 fDetectorResponse = detectorResponse;
3718 fSpectrumIn = jetPtIn;
3719 fSpectrumOut = jetPtOut;
3721 fDptOutDist = dptOut;
3722 // check if all data is provided
3723 if(!fDetectorResponse) {
3724 printf(" fDetectorResponse not found \n ");
3727 // check if the pt bin for true and rec have been set
3728 if(!fBinsTrue || !fBinsRec) {
3729 printf(" No true or rec bins set, please set binning ! \n");
3732 if(!fRMSSpectrumIn) { // initialie the profiles which will hold the RMS values. if binning changes in between unfolding
3733 // procedures, these profiles will be nonsensical, user is responsible
3734 fRMSSpectrumIn = new TProfile("fRMSSpectrumIn", "fRMSSpectrumIn", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
3735 fRMSSpectrumOut = new TProfile("fRMSSpectrumOut", "fRMSSpectrumOut", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
3736 fRMSRatio = new TProfile("fRMSRatio", "fRMSRatio", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
3738 // normalize spectra to event count if requested
3739 if(fNormalizeSpectra) {
3740 fEventCount = eventCount;
3741 if(fEventCount > 0) {
3742 fSpectrumIn->Sumw2(); // necessary for correct error propagation of scale
3743 fSpectrumOut->Sumw2();
3744 fSpectrumIn->Scale(1./((double)fEventCount));
3745 fSpectrumOut->Scale(1./((double)fEventCount));
3748 if(!fNormalizeSpectra && fEventCount > 0) {
3749 fSpectrumIn->Sumw2(); // necessary for correct error propagation of scale
3750 fSpectrumOut->Sumw2();
3751 fSpectrumIn->Scale(1./((double)fEventCount));
3752 fSpectrumOut->Scale(1./((double)fEventCount));
3754 fDptIn = ConstructDPtResponseFromTH1D(fDptInDist, fAvoidRoundingError);
3755 fDptIn->SetNameTitle(Form("dpt_response_INPLANE_%i", fCentralityArray->At(0)), Form("dpt_response_INPLANE_%i", fCentralityArray->At(0)));
3756 fDptIn->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
3757 fDptIn->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
3758 fDptOut = ConstructDPtResponseFromTH1D(fDptOutDist, fAvoidRoundingError);
3759 fDptOut->SetNameTitle(Form("dpt_response_OUTOFPLANE_%i", fCentralityArray->At(0)), Form("dpt_response_OUTOFPLANE_%i", fCentralityArray->At(0)));
3760 fDptOut->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
3761 fDptOut->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
3764 // set the flag to let other functions to read data from input file
3765 fRawInputProvided = kTRUE;
3766 return fRawInputProvided;
3768 //_____________________________________________________________________________
3769 TGraphErrors* AliJetFlowTools::GetRatio(TH1 *h1, TH1* h2, TString name, Bool_t appendFit, Int_t xmax)
3771 // return ratio of h1 / h2
3772 // histograms can have different binning. errors are propagated as uncorrelated
3774 printf(" GetRatio called with NULL argument(s) \n ");
3778 TGraphErrors *gr = new TGraphErrors();
3779 gr->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
3780 Double_t binCent(0.), ratio(0.), error2(0.), binWidth(0.);
3781 TH1* dud((TH1*)h1->Clone("dud"));
3785 if(!dud->Divide(h1, h2)) {
3786 printf(" > ROOT failed to divide two histogams, dividing manually \n < ");
3787 for(Int_t i(1); i <= h1->GetNbinsX(); i++) {
3788 binCent = h1->GetXaxis()->GetBinCenter(i);
3789 if(xmax > 0. && binCent > xmax) continue;
3790 j = h2->FindBin(binCent);
3791 binWidth = h1->GetXaxis()->GetBinWidth(i);
3792 if(h2->GetBinContent(j) > 0.) {
3793 ratio = h1->GetBinContent(i)/h2->GetBinContent(j);
3794 Double_t A = h1->GetBinError(i)/h1->GetBinContent(i);
3795 Double_t B = h2->GetBinError(i)/h2->GetBinContent(i);
3796 error2 = ratio*ratio*A*A+ratio*ratio*B*B;
3797 if(error2 > 0 ) error2 = TMath::Sqrt(error2);
3798 gr->SetPoint(i-1, binCent, ratio);
3799 gr->SetPointError(i-1, 0.5*binWidth, error2);
3803 printf( " > using ROOT to divide two histograms < \n");
3804 for(Int_t i(1); i <= h1->GetNbinsX(); i++) {
3805 binCent = dud->GetXaxis()->GetBinCenter(i);
3806 if(xmax > 0. && binCent > xmax) continue;
3807 binWidth = dud->GetXaxis()->GetBinWidth(i);
3808 gr->SetPoint(i-1,binCent,dud->GetBinContent(i));
3809 gr->SetPointError(i-1, 0.5*binWidth,dud->GetBinError(i));
3814 TF1* fit(new TF1("lin", "pol0", 10, 100));
3817 if(strcmp(name, "")) gr->SetNameTitle(name.Data(), name.Data());
3821 //_____________________________________________________________________________
3822 TGraphErrors* AliJetFlowTools::GetV2(TH1 *h1, TH1* h2, Double_t r, TString name)
3824 // get v2 from difference of in plane, out of plane yield
3825 // h1 must hold the in-plane yield, h2 holds the out of plane yield
3826 // r is the event plane resolution for the chosen centrality
3828 printf(" GetV2 called with NULL argument(s) \n ");
3831 TGraphErrors *gr = new TGraphErrors();
3832 gr->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
3833 Float_t binCent(0.), ratio(0.), error2(0.), binWidth(0.);
3834 Double_t pre(TMath::Pi()/(4.*r)), in(0.), out(0.), ein(0.), eout(0.);
3836 for(Int_t i(1); i <= h1->GetNbinsX(); i++) {
3837 binCent = h1->GetXaxis()->GetBinCenter(i);
3838 binWidth = h1->GetXaxis()->GetBinWidth(i);
3839 if(h2->GetBinContent(i) > 0.) {
3840 in = h1->GetBinContent(i);
3841 ein = h1->GetBinError(i);
3842 out = h2->GetBinContent(i);
3843 eout = h2->GetBinError(i);
3844 ratio = pre*((in-out)/(in+out));
3845 error2 = (4.*out*out/(TMath::Power(in+out, 4)))*ein*ein+(4.*in*in/(TMath::Power(in+out, 4)))*eout*eout;
3846 error2 = error2*pre*pre;
3847 if(error2 > 0) error2 = TMath::Sqrt(error2);
3848 gr->SetPoint(i-1,binCent,ratio);
3849 gr->SetPointError(i-1,0.5*binWidth,error2);
3852 if(strcmp(name, "")) gr->SetNameTitle(name.Data(), name.Data());
3855 //_____________________________________________________________________________
3856 TGraphAsymmErrors* AliJetFlowTools::GetV2WithSystematicErrors(
3857 TH1* h1, TH1* h2, Double_t r, TString name,
3858 TH1* relativeErrorInUp,
3859 TH1* relativeErrorInLow,
3860 TH1* relativeErrorOutUp,
3861 TH1* relativeErrorOutLow,
3864 // get v2 with asymmetric systematic error
3865 // note that this is ONLY the systematic error, no statistical error!
3866 // rho is the pearson correlation coefficient
3867 TGraphErrors* tempV2(GetV2(h1, h2, r, name));
3868 Double_t* ax = new Double_t[fBinsTrue->GetSize()-1];
3869 Double_t* ay = new Double_t[fBinsTrue->GetSize()-1];
3870 Double_t* axh = new Double_t[fBinsTrue->GetSize()-1];
3871 Double_t* axl = new Double_t[fBinsTrue->GetSize()-1];
3872 Double_t* ayh = new Double_t[fBinsTrue->GetSize()-1];
3873 Double_t* ayl = new Double_t[fBinsTrue->GetSize()-1];
3874 Double_t in(0.), out(0.), einUp(0.), einLow(0.), eoutUp(0.), eoutLow(0.), error2Up(0.), error2Low(0.);
3875 // loop through the bins and do error propagation
3876 for(Int_t i(0); i < fBinsTrue->GetSize()-1; i++) {
3877 // extract the absolute errors
3878 in = h1->GetBinContent(i+1);
3879 einUp = TMath::Abs(in*relativeErrorInUp->GetBinContent(i+1));
3880 einLow = TMath::Abs(in*relativeErrorInLow->GetBinContent(1+i));
3881 out = h2->GetBinContent(i+1);
3882 eoutUp = TMath::Abs(out*relativeErrorOutUp->GetBinContent(1+i));
3883 eoutLow = TMath::Abs(out*relativeErrorOutLow->GetBinContent(1+i));
3884 // get the error squared
3886 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);
3887 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);
3889 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);
3890 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);
3892 if(error2Up > 0) error2Up = TMath::Sqrt(error2Up);
3893 if(error2Low > 0) error2Low = TMath::Sqrt(error2Low);
3897 // get the bin width (which is the 'error' on x)
3898 Double_t binWidth(h1->GetBinWidth(i+1));
3899 axl[i] = binWidth/2.;
3900 axh[i] = binWidth/2.;
3901 // now get the coordinate for the poin
3902 tempV2->GetPoint(i, ax[i], ay[i]);
3904 // save the nominal ratio
3905 TGraphAsymmErrors* nominalError(new TGraphAsymmErrors(fBinsTrue->GetSize()-1, ax, ay, axl, axh, ayl, ayh));
3906 nominalError->SetName("v_{2} with shape uncertainty");
3907 // do some memory management
3916 return nominalError;
3918 //_____________________________________________________________________________
3919 void AliJetFlowTools::WriteObject(TObject* object, TString suffix, Bool_t kill) {
3920 // write object, if a unique identifier is given the object is cloned
3921 // and the clone is saved. setting kill to true will delete the original obect from the heap
3923 printf(" > WriteObject:: called with NULL arguments \n ");
3925 } else if(!strcmp("", suffix.Data())) object->Write();
3927 TObject* newObject(object->Clone(Form("%s_%s", object->GetName(), suffix.Data())));
3930 if(kill) delete object;
3932 //_____________________________________________________________________________
3933 TH2D* AliJetFlowTools::ConstructDPtResponseFromTH1D(TH1D* dpt, Bool_t AvoidRoundingError) {
3934 // construt a delta pt response matrix from supplied dpt distribution
3935 // binning is fine, set fBinsTrue and fBinsRec and call 'RebinTH2D' to
3936 // do a weighted rebinning to a (coarser) dpt distribution
3937 // be careful with the binning of the dpt response: it should be equal to that
3938 // of the response matrix, otherwise dpt and response matrices cannot be multiplied
3940 // the response matrix will be square and have the same binning
3941 // (min, max and granularity) of the input histogram
3942 Int_t bins(dpt->GetXaxis()->GetNbins()); // number of bins, will also be no of rows, columns
3943 Double_t _bins[bins+1]; // prepare array with bin borders
3944 for(Int_t i(0); i < bins; i++) _bins[i] = dpt->GetBinLowEdge(i+1);
3945 _bins[bins] = dpt->GetBinLowEdge(bins)+dpt->GetBinWidth(bins+1); // get upper edge
3946 TH2D* res(new TH2D(Form("Response_from_%s", dpt->GetName()), Form("Response_from_%s", dpt->GetName()), bins, _bins, bins, _bins));
3947 for(Int_t j(0); j < bins+1; j++) { // loop on pt true slices j
3948 Bool_t skip = kFALSE;
3949 for(Int_t k(0); k < bins+1; k++) { // loop on pt gen slices k
3950 (skip) ? res->SetBinContent(j, k, 0.) : res->SetBinContent(j, k, dpt->GetBinContent(dpt->GetXaxis()->FindBin(k-j)));
3951 if(AvoidRoundingError && k > j && TMath::AreEqualAbs(dpt->GetBinContent(dpt->GetBinContent(k-j)), 0, 1e-8)) skip = kTRUE;
3956 //_____________________________________________________________________________
3957 TH2D* AliJetFlowTools::GetUnityResponse(TArrayD* binsTrue, TArrayD* binsRec, TString suffix) {
3958 if(!binsTrue || !binsRec) {
3959 printf(" > GetUnityResponse:: function called with NULL arguments < \n");
3962 TString name(Form("unityResponse_%s", suffix.Data()));
3963 TH2D* unity(new TH2D(name.Data(), name.Data(), binsTrue->GetSize()-1, binsTrue->GetArray(), binsRec->GetSize()-1, binsRec->GetArray()));
3964 for(Int_t i(0); i < binsTrue->GetSize(); i++) {
3965 for(Int_t j(0); j < binsRec->GetSize(); j++) {
3966 if(i==j) unity->SetBinContent(1+i, 1+j, 1.);
3971 //_____________________________________________________________________________
3972 void AliJetFlowTools::SaveConfiguration(Bool_t convergedIn, Bool_t convergedOut) const {
3973 // save configuration parameters to histogram
3974 TH1F* summary = new TH1F("UnfoldingConfiguration","UnfoldingConfiguration", 20, -.5, 19.5);
3975 summary->SetBinContent(1, fBetaIn);
3976 summary->GetXaxis()->SetBinLabel(1, "fBetaIn");
3977 summary->SetBinContent(2, fBetaOut);
3978 summary->GetXaxis()->SetBinLabel(2, "fBetaOut");
3979 summary->SetBinContent(3, fCentralityArray->At(0));
3980 summary->GetXaxis()->SetBinLabel(3, "fCentralityArray[0]");
3981 summary->SetBinContent(4, (int)convergedIn);
3982 summary->GetXaxis()->SetBinLabel(4, "convergedIn");
3983 summary->SetBinContent(5, (int)convergedOut);
3984 summary->GetXaxis()->SetBinLabel(5, "convergedOut");
3985 summary->SetBinContent(6, (int)fAvoidRoundingError);
3986 summary->GetXaxis()->SetBinLabel(6, "fAvoidRoundingError");
3987 summary->SetBinContent(7, (int)fUnfoldingAlgorithm);
3988 summary->GetXaxis()->SetBinLabel(7, "fUnfoldingAlgorithm");
3989 summary->SetBinContent(8, (int)fPrior);
3990 summary->GetXaxis()->SetBinLabel(8, "fPrior");
3991 summary->SetBinContent(9, fSVDRegIn);
3992 summary->GetXaxis()->SetBinLabel(9, "fSVDRegIn");
3993 summary->SetBinContent(10, fSVDRegOut);
3994 summary->GetXaxis()->SetBinLabel(10, "fSVDRegOut");
3995 summary->SetBinContent(11, (int)fSVDToy);
3996 summary->GetXaxis()->SetBinLabel(11, "fSVDToy");
3997 summary->SetBinContent(12, fJetRadius);
3998 summary->GetXaxis()->SetBinLabel(12, "fJetRadius");
3999 summary->SetBinContent(13, (int)fNormalizeSpectra);
4000 summary->GetXaxis()->SetBinLabel(13, "fNormalizeSpectra");
4001 summary->SetBinContent(14, (int)fSmoothenPrior);
4002 summary->GetXaxis()->SetBinLabel(14, "fSmoothenPrior");
4003 summary->SetBinContent(15, (int)fTestMode);
4004 summary->GetXaxis()->SetBinLabel(15, "fTestMode");
4005 summary->SetBinContent(16, (int)fUseDetectorResponse);
4006 summary->GetXaxis()->SetBinLabel(16, "fUseDetectorResponse");
4007 summary->SetBinContent(17, fBayesianIterIn);
4008 summary->GetXaxis()->SetBinLabel(17, "fBayesianIterIn");
4009 summary->SetBinContent(18, fBayesianIterOut);
4010 summary->GetXaxis()->SetBinLabel(18, "fBayesianIterOut");
4011 summary->SetBinContent(19, fBayesianSmoothIn);
4012 summary->GetXaxis()->SetBinLabel(19, "fBayesianSmoothIn");
4013 summary->SetBinContent(20, fBayesianSmoothOut);
4014 summary->GetXaxis()->SetBinLabel(20, "fBayesianSmoothOut");
4016 //_____________________________________________________________________________
4017 void AliJetFlowTools::ResetAliUnfolding() {
4018 // ugly function: reset all unfolding parameters
4019 TVirtualFitter* fitter(TVirtualFitter::GetFitter());
4021 printf(" > Found fitter, will delete it < \n");
4025 printf(" > Found gMinuit, will re-create it < \n");
4027 gMinuit = new TMinuit;
4029 AliUnfolding::fgCorrelationMatrix = 0;
4030 AliUnfolding::fgCorrelationMatrixSquared = 0;
4031 AliUnfolding::fgCorrelationCovarianceMatrix = 0;
4032 AliUnfolding::fgCurrentESDVector = 0;
4033 AliUnfolding::fgEntropyAPriori = 0;
4034 AliUnfolding::fgEfficiency = 0;
4035 AliUnfolding::fgUnfoldedAxis = 0;
4036 AliUnfolding::fgMeasuredAxis = 0;
4037 AliUnfolding::fgFitFunction = 0;
4038 AliUnfolding::fgMaxInput = -1;
4039 AliUnfolding::fgMaxParams = -1;
4040 AliUnfolding::fgOverflowBinLimit = -1;
4041 AliUnfolding::fgRegularizationWeight = 10000;
4042 AliUnfolding::fgSkipBinsBegin = 0;
4043 AliUnfolding::fgMinuitStepSize = 0.1;
4044 AliUnfolding::fgMinuitPrecision = 1e-6;
4045 AliUnfolding::fgMinuitMaxIterations = 1000000;
4046 AliUnfolding::fgMinuitStrategy = 1.;
4047 AliUnfolding::fgMinimumInitialValue = kFALSE;
4048 AliUnfolding::fgMinimumInitialValueFix = -1;
4049 AliUnfolding::fgNormalizeInput = kFALSE;
4050 AliUnfolding::fgNotFoundEvents = 0;
4051 AliUnfolding::fgSkipBin0InChi2 = kFALSE;
4052 AliUnfolding::fgBayesianSmoothing = 1;
4053 AliUnfolding::fgBayesianIterations = 10;
4054 AliUnfolding::fgDebug = kFALSE;
4055 AliUnfolding::fgCallCount = 0;
4056 AliUnfolding::fgPowern = 5;
4057 AliUnfolding::fChi2FromFit = 0.;
4058 AliUnfolding::fPenaltyVal = 0.;
4059 AliUnfolding::fAvgResidual = 0.;
4060 AliUnfolding::fgPrintChi2Details = 0;
4061 AliUnfolding::fgCanvas = 0;
4062 AliUnfolding::fghUnfolded = 0;
4063 AliUnfolding::fghCorrelation = 0;
4064 AliUnfolding::fghEfficiency = 0;
4065 AliUnfolding::fghMeasured = 0;
4066 AliUnfolding::SetMinuitStepSize(1.);
4067 AliUnfolding::SetMinuitPrecision(1e-6);
4068 AliUnfolding::SetMinuitMaxIterations(100000);
4069 AliUnfolding::SetMinuitStrategy(2.);
4070 AliUnfolding::SetDebug(1);
4072 //_____________________________________________________________________________
4073 TH1D* AliJetFlowTools::ProtectHeap(TH1D* protect, Bool_t kill, TString suffix) const {
4074 // protect heap by adding unique qualifier to name
4075 if(!protect) return 0x0;
4076 TH1D* p = (TH1D*)protect->Clone();
4077 TString tempString(fActiveString);
4079 p->SetName(Form("%s_%s", protect->GetName(), tempString.Data()));
4080 p->SetTitle(Form("%s_%s", protect->GetTitle(), tempString.Data()));
4081 if(kill) delete protect;
4084 //_____________________________________________________________________________
4085 TH2D* AliJetFlowTools::ProtectHeap(TH2D* protect, Bool_t kill, TString suffix) const {
4086 // protect heap by adding unique qualifier to name
4087 if(!protect) return 0x0;
4088 TH2D* p = (TH2D*)protect->Clone();
4089 TString tempString(fActiveString);
4091 p->SetName(Form("%s_%s", protect->GetName(), tempString.Data()));
4092 p->SetTitle(Form("%s_%s", protect->GetTitle(), tempString.Data()));
4093 if(kill) delete protect;
4096 //_____________________________________________________________________________
4097 TGraphErrors* AliJetFlowTools::ProtectHeap(TGraphErrors* protect, Bool_t kill, TString suffix) const {
4098 // protect heap by adding unique qualifier to name
4099 if(!protect) return 0x0;
4100 TGraphErrors* p = (TGraphErrors*)protect->Clone();
4101 TString tempString(fActiveString);
4103 p->SetName(Form("%s_%s", protect->GetName(), tempString.Data()));
4104 p->SetTitle(Form("%s_%s", protect->GetTitle(), tempString.Data()));
4105 if(kill) delete protect;
4108 //_____________________________________________________________________________
4109 void AliJetFlowTools::MakeAU() {
4110 // === azimuthal unfolding ===
4112 // unfolds the spectrum in delta phi bins, extracts the yield per bin, and does a fit
4113 // in transverse momentum and azimuthal correlation space to extract v2 params
4114 // settings are equal to the ones used for 'Make()'
4116 // basic steps that are followed:
4117 // 1) rebin the raw output of the jet task to the desired binnings
4118 // 2) calls the unfolding routine
4119 // 3) writes output to file
4120 // can be repeated multiple times with different configurations
4122 Int_t low[] = {1, 6, 11, 16, 21, 26, 31, 36};
4123 Int_t up[] = {5, 10, 15, 20, 25, 30, 35, 40};
4124 TString stringArray[] = {"a", "b", "c", "d", "e", "f", "g", "h"};
4125 const Int_t ptBins(fBinsTrue->GetSize()-1);
4126 const Int_t dPhiBins(8);
4127 TH1D* dPtdPhi[fBinsTrue->GetSize()];
4128 for(Int_t i(0); i < ptBins; i++) dPtdPhi[i] = new TH1D(Form("dPtdPhi_%i", i), Form("dPtdPhi_%i", i), dPhiBins, 0, TMath::Pi());
4130 // for the output initialize a canvas
4131 TCanvas* v2Fits(new TCanvas("v2 fits", "v2 fits"));
4132 v2Fits->Divide(4, TMath::Floor((1+ptBins)/(float)4)+(((1+ptBins)%4)>0));
4134 for(Int_t i(0); i < dPhiBins; i++) {
4135 // 1) manipulation of input histograms
4136 // check if the input variables are present
4137 if(!PrepareForUnfolding(low[i], up[i])) return;
4138 // 1a) resize the jet spectrum according to the binning scheme in fBinsTrue
4139 // parts of the spectrum can end up in over or underflow bins
4140 TH1D* measuredJetSpectrumIn = RebinTH1D(fSpectrumIn, fBinsRec, Form("resized_%s", stringArray[i].Data()), kFALSE);
4142 // 1b) resize the jet spectrum to 'true' bins. can serve as a prior and as a template for unfolding
4143 // the template will be used as a prior for the chi2 unfolding
4144 TH1D* measuredJetSpectrumTrueBinsIn = RebinTH1D(fSpectrumIn, fBinsTrue, stringArray[i], kFALSE);
4146 // get the full response matrix from the dpt and the detector response
4147 fDetectorResponse = NormalizeTH2D(fDetectorResponse);
4148 // get the full response matrix. if test mode is chosen, the full response is replace by a unity matrix
4149 // so that unfolding should return the initial spectrum
4150 if(fUseDptResponse && fUseDetectorResponse) fFullResponseIn = MatrixMultiplication(fDptIn, fDetectorResponse);
4151 else if (fUseDptResponse && !fUseDetectorResponse) fFullResponseIn = fDptIn;
4152 else if (!fUseDptResponse && fUseDetectorResponse) fFullResponseIn = fDetectorResponse;
4153 else if (!fUseDptResponse && !fUseDetectorResponse && !fUnfoldingAlgorithm == AliJetFlowTools::kNone) return;
4154 // normalize each slide of the response to one
4155 NormalizeTH2D(fFullResponseIn);
4156 // resize to desired binning scheme
4157 TH2D* resizedResponseIn = RebinTH2D(fFullResponseIn, fBinsTrue, fBinsRec, stringArray[i]);
4158 // get the kinematic efficiency
4159 TH1D* kinematicEfficiencyIn = resizedResponseIn->ProjectionX();
4160 kinematicEfficiencyIn->SetNameTitle(Form("kin_eff_%s", stringArray[i].Data()), Form("kin_eff_%s", stringArray[i].Data()));
4161 // suppress the errors
4162 for(Int_t j(0); j < kinematicEfficiencyIn->GetXaxis()->GetNbins(); j++) kinematicEfficiencyIn->SetBinError(1+j, 0.);
4163 TH1D* jetFindingEfficiency(0x0);
4164 if(fJetFindingEff) {
4165 jetFindingEfficiency = ProtectHeap(fJetFindingEff);
4166 jetFindingEfficiency->SetNameTitle(Form("%s_coarse", jetFindingEfficiency->GetName()), Form("%s_coarse", jetFindingEfficiency->GetName()));
4167 jetFindingEfficiency = RebinTH1D(jetFindingEfficiency, fBinsTrue);
4169 // 2, 3) call the actual unfolding. results and transient objects are stored in a dedicated TDirectoryFile
4170 TH1D* unfoldedJetSpectrumIn(0x0);
4171 fActiveDir->cd(); // select active dir
4172 TDirectoryFile* dirIn = new TDirectoryFile(Form("%s___%s", stringArray[i].Data(), fActiveString.Data()), Form("%s___%s", stringArray[i].Data(), fActiveString.Data()));
4173 dirIn->cd(); // select inplane subdir
4174 // select the unfolding method
4175 unfoldedJetSpectrumIn = UnfoldWrapper(
4176 measuredJetSpectrumIn,
4178 kinematicEfficiencyIn,
4179 measuredJetSpectrumTrueBinsIn,
4180 TString("dPtdPhiUnfolding"),
4181 jetFindingEfficiency);
4182 // arbitrarily save one of the full outputs (same for all dphi bins, avoid duplicates)
4184 resizedResponseIn->SetNameTitle(Form("ResponseMatrix_%s", stringArray[i].Data()), Form("response matrix %s", stringArray[i].Data()));
4185 resizedResponseIn->SetXTitle("p_{T, jet}^{true} [GeV/c]");
4186 resizedResponseIn->SetYTitle("p_{T, jet}^{rec} [GeV/c]");
4187 resizedResponseIn = ProtectHeap(resizedResponseIn);
4188 resizedResponseIn->Write();
4189 kinematicEfficiencyIn->SetNameTitle(Form("KinematicEfficiency_%s", stringArray[i].Data()), Form("Kinematic efficiency, %s", stringArray[i].Data()));
4190 kinematicEfficiencyIn = ProtectHeap(kinematicEfficiencyIn);
4191 kinematicEfficiencyIn->Write();
4192 fDetectorResponse->SetNameTitle("DetectorResponse", "Detector response matrix");
4193 fDetectorResponse = ProtectHeap(fDetectorResponse, kFALSE);
4194 fDetectorResponse->Write();
4195 // optional histograms
4197 fSpectrumIn->SetNameTitle("[ORIG]JetSpectrum", Form("[INPUT] Jet spectrum, %s", stringArray[i].Data()));
4198 fSpectrumIn->Write();
4199 fDptInDist->SetNameTitle("[ORIG]DeltaPt", Form("#delta p_{T} distribution, %s", stringArray[i].Data()));
4200 fDptInDist->Write();
4201 fDptIn->SetNameTitle("[ORIG]DeltaPtMatrix", Form("#delta p_{T} matrix, %s", stringArray[i].Data()));
4203 fFullResponseIn->SetNameTitle("ResponseMatrix", Form("Response matrix, %s", stringArray[i].Data()));
4204 fFullResponseIn->Write();
4208 fDeltaPtDeltaPhi->Write();
4209 fJetPtDeltaPhi->Write();
4211 TH1D* dud(ProtectHeap(unfoldedJetSpectrumIn, kTRUE, stringArray[i]));;
4212 Double_t integralError(0);
4213 // at this point in the code, the spectrum has been unfolded in a certain region of dPhi space
4214 // next step is splitting it in pt space as well to estimate the yield differentially in pt
4215 for(Int_t j(0); j < ptBins; j++) {
4216 // get the integrated
4217 Double_t integral(dud->IntegralAndError(j+1, j+2, integralError));
4218 dPtdPhi[j]->SetBinContent(i+1, integral);
4219 dPtdPhi[j]->SetBinError(i+1, integralError);
4222 // save the current state of the unfolding object
4223 SaveConfiguration(unfoldedJetSpectrumIn ? kTRUE : kFALSE, kFALSE);
4225 TF1* fourier = new TF1("fourier", "[0]*(1.+0.5*[1]*(TMath::Cos(2.*x)))", 0, TMath::Pi());
4226 TH1D* v2(new TH1D("v2FromFit", "v2FromFit", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
4227 for(Int_t i(0); i < ptBins; i++) {
4229 dPtdPhi[i]->Fit(fourier, "VI");
4230 Style(gPad, "PEARSON");
4231 Style(dPtdPhi[i], kBlue, kDeltaPhi);
4232 dPtdPhi[i]->DrawCopy();
4233 AliJetFlowTools::AddText(
4234 TString(Form("%.2f #LT p_{T} #LT %.2f", fBinsTrue->At(i), fBinsTrue->At(i+1))),
4241 v2->SetBinContent(1+i, fourier->GetParameter(1));
4242 v2->SetBinError(1+i, fourier->GetParError(1));
4244 v2Fits->cd(1+ptBins);
4245 Style(gPad, "PEARSON");
4246 Style(v2, kBlack, kV2, kTRUE);
4250 //_____________________________________________________________________________
4251 void AliJetFlowTools::ReplaceBins(TArrayI* array, TGraphErrors* graph) {
4253 Double_t x(0), y(0);
4254 graph->GetPoint(0, x, y);
4255 graph->SetPoint(array->At(0)-1, fBinsTrue->At(array->At(0)), y);
4256 graph->SetPointError(array->At(0)-1, 10, graph->GetErrorY(0));
4257 graph->SetPoint(array->At(1)-1, -5, -5);
4259 //_____________________________________________________________________________
4260 void AliJetFlowTools::ReplaceBins(TArrayI* array, TGraphAsymmErrors* graph) {
4262 Double_t x(0), y(0);
4263 graph->GetPoint(0, x, y);
4264 graph->SetPoint(array->At(0)-1, fBinsTrue->At(array->At(0)), y);
4265 Double_t yl = graph->GetErrorYlow(0);
4266 Double_t yh = graph->GetErrorYhigh(0);
4267 graph->SetPointError(array->At(0)-1, 10, 10, yl, yh);
4268 graph->SetPoint(array->At(1)-1, -5, -5);
4270 //_____________________________________________________________________________
4271 void AliJetFlowTools::GetSignificance(
4272 TGraphErrors* n, // points with stat error
4273 TGraphAsymmErrors* shape, // points with shape error
4274 TGraphAsymmErrors* corr, // points with stat error
4275 Int_t low, // lower bin (tgraph starts at 0)
4276 Int_t up // upper bin
4279 // main use of this function is filling the static buffers
4280 Double_t statE(0), shapeE(0), corrE(0), y(0), x(0), chi2(0);
4283 printf(" double v2[] = {\n");
4285 for(Int_t i(low); i < up+1; i++) {
4286 n->GetPoint(i, x, y);
4287 if(i==up) printf("%.4f}; \n\n", y);
4288 else printf("%.4f, \n", y);
4289 gV2->SetAt(y, iterator);
4293 printf(" double stat[] = {\n");
4294 for(Int_t i(low); i < up+1; i++) {
4295 y = n->GetErrorYlow(i);
4296 if(i==up) printf("%.4f}; \n\n", y);
4297 else printf("%.4f, \n", y);
4298 gStat->SetAt(y, iterator);
4302 printf(" double shape[] = {\n");
4303 for(Int_t i(low); i < up+1; i++) {
4304 y = shape->GetErrorYhigh(i);
4305 y*=gReductionFactor;
4306 shape->SetPointEYhigh(i, y);
4307 y = shape->GetErrorYlow(i);
4308 y*=gReductionFactor;
4309 shape->SetPointEYlow(i, y);
4310 if(i==up) printf("%.4f}; \n\n", y);
4311 else printf("%.4f, \n", y);
4312 gShape->SetAt(y, iterator);
4316 printf(" double corr[] = {\n");
4317 for(Int_t i(low); i < up+1; i++) {
4318 y = corr->GetErrorYlow(i);
4319 if(i==up) printf("%.4f}; \n\n", y);
4320 else printf("%.4f, \n", y);
4321 gCorr->SetAt(y, iterator);
4325 // to plot the average error as function of number of events
4327 for(Int_t i(low); i < up+1; i++) {
4329 // set some flags to 0
4332 // get the nominal point
4333 n->GetPoint(i, x, y);
4334 statE += n->GetErrorY(i);
4335 shapeE += shape->GetErrorY(i);
4336 corrE += corr->GetErrorY(i);
4337 // combine the errors
4339 printf(" ======================================\n");
4340 printf(" > between %i and %i GeV/c \n", low, up);
4341 cout << " AVERAGE_SHAPE " << shapeE/ctr << endl;
4342 cout << " AVERAGE_CORR " << corrE/ctr << endl;
4343 cout << " AVERAGE_STAT " << statE/ctr << endl;
4345 //_____________________________________________________________________________
4346 void AliJetFlowTools::MinimizeChi2nd()
4348 // Choose method upon creation between:
4349 // kMigrad, kSimplex, kCombined,
4351 ROOT::Minuit2::Minuit2Minimizer min ( ROOT::Minuit2::kMigrad );
4352 min.SetMaxFunctionCalls(1000000);
4353 min.SetMaxIterations(100000);
4354 min.SetTolerance(0.001);
4356 ROOT::Math::Functor f(&PhenixChi2nd,2);
4357 double step[] = {0.0000001, 0.0000001};
4358 double variable[] = {-1., -1.};
4361 // Set the free variables to be minimized!
4362 min.SetVariable(0,"epsilon_c",variable[0], step[0]);
4363 min.SetVariable(1,"epsilon_b",variable[1], step[1]);
4368 //_____________________________________________________________________________
4369 Double_t AliJetFlowTools::PhenixChi2nd(const Double_t *xx )
4371 // define arrays with results and errors here, see example at PhenixChi2()
4373 // return the function value at certain epsilon
4374 const Double_t epsc = xx[0];
4375 const Double_t epsb = xx[1];
4377 Int_t counts(gV2->GetSize() + gOffsetStop);
4379 // altered implemtation of eq 3 of arXiv:0801.1665v2
4380 // see analysis note and QM2014 poster for validation
4381 for(Int_t i(gOffsetStart); i < counts; i++) {
4383 // quadratic sum of statistical and uncorrelated systematic error
4384 Double_t e = gStat->At(i);;
4386 // sum of v2 plus epsilon times correlated error minus hypothesis (0)
4387 // also the numerator of equation 3 of phenix paper
4388 Double_t numerator = TMath::Power(gV2->At(i)+epsc*gCorr->At(i)+epsb, 2);
4390 // modified denominator of equation 3 of phenix paper
4391 Double_t denominator = e*e;
4394 chi2 += numerator/denominator;
4396 // add the square of epsilon to the total chi2 as penalty
4398 Double_t sumEpsb(0);
4399 for(Int_t j(gOffsetStart); j < counts; j++) sumEpsb += (epsb*epsb)/(gShape->At(j)*gShape->At(j));
4400 chi2 += epsc*epsc + sumEpsb/((float)counts);
4404 //_____________________________________________________________________________
4405 Double_t AliJetFlowTools::ConstructFunctionnd(Double_t *x, Double_t *par)
4407 // internal use only: evaluate the function at a given point
4408 return AliJetFlowTools::PhenixChi2nd(x);
4410 //_____________________________________________________________________________
4411 TF2* AliJetFlowTools::ReturnFunctionnd(Double_t &p)
4413 // return the fitting function, pass the p-value w.r.t. 0 by reference
4415 TF2 *f1 = new TF2("ndhist",AliJetFlowTools::ConstructFunctionnd, -100, 100, -100, 100, 0);
4416 printf(" > locating minima < \n");
4417 Double_t x(0), y(0);
4418 f1->GetMinimumXY(x, y);
4419 f1->GetXaxis()->SetTitle("#epsilon{b}");
4420 f1->GetXaxis()->SetTitle("#epsilon_{c}");
4421 f1->GetZaxis()->SetTitle("#chi^{2}");
4423 printf(" ===============================================================================\n");
4424 printf(" > minimal chi2 f(%.8f, %.8f) = %.8f (i should be ok ... ) \n", x, y, f1->Eval(x, y));
4425 cout << " so the probability of finding data at least as imcompatible with 0 as the actually" << endl;
4426 cout << " observed data is " << TMath::Prob(f1->Eval(x, y), DOF) << endl;
4427 printf(" ===============================================================================\n");
4429 // pass the p-value by reference and return the function
4430 p = TMath::Prob(f1->Eval(x, y), DOF);
4433 //_____________________________________________________________________________