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/AliAnalysisTaskRhoVnModulation.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"
50 #include "TVirtualFitter.h"
56 #include "TVirtualFitter.h"
57 #include "TFitResultPtr.h"
59 #include "AliUnfolding.h"
60 #include "AliAnaChargedJetResponseMaker.h"
62 #include "AliJetFlowTools.h"
63 // roo unfold includes (make sure you have these available on your system)
64 #include "RooUnfold.h"
65 #include "RooUnfoldResponse.h"
66 #include "RooUnfoldSvd.h"
67 #include "RooUnfoldBayes.h"
68 #include "TSVDUnfold.h"
71 //_____________________________________________________________________________
72 AliJetFlowTools::AliJetFlowTools() :
73 fResponseMaker (new AliAnaChargedJetResponseMaker()),
74 fPower (new TF1("fPower","[0]*TMath::Power(x,-([1]))",0.,300.)),
79 fRefreshInput (kTRUE),
80 fOutputFileName ("UnfoldedSpectra.root"),
83 fDetectorResponse (0x0),
89 fBayesianSmoothIn (0.),
90 fBayesianSmoothOut (0.),
91 fAvoidRoundingError (kFALSE),
92 fUnfoldingAlgorithm (kChi2),
93 fPrior (kPriorMeasured),
103 fNormalizeSpectra (kFALSE),
104 fSmoothenPrior (kFALSE),
108 fSmoothenCounts (kTRUE),
110 fRawInputProvided (kFALSE),
111 fEventPlaneRes (.63),
112 fUseDetectorResponse(kTRUE),
113 fUseDptResponse (kTRUE),
115 fDphiUnfolding (kTRUE),
116 fDphiDptUnfolding (kFALSE),
118 fRMSSpectrumIn (0x0),
119 fRMSSpectrumOut (0x0),
122 fDeltaPtDeltaPhi (0x0),
123 fJetPtDeltaPhi (0x0),
130 fFullResponseIn (0x0),
131 fFullResponseOut (0x0) { // class constructor
132 // create response maker weight function (tuned to PYTHIA spectrum)
133 fResponseMaker->SetRMMergeWeightFunction(new TF1("weightFunction", "x*TMath::Power(1.+(1./(8.*0.9))*x, -8.)", 0, 200));
134 for(Int_t i(0); i < fPower->GetNpar(); i++) fPower->SetParameter(i, 0.);
136 //_____________________________________________________________________________
137 void AliJetFlowTools::Make() {
138 // core function of the class
139 if(fDphiDptUnfolding) {
140 // to extract the yield as function of Dphi, Dpt - experimental
144 // 1) rebin the raw output of the jet task to the desired binnings
145 // 2) calls the unfolding routine
146 // 3) writes output to file
147 // can be repeated multiple times with different configurations
149 // 1) manipulation of input histograms
150 // check if the input variables are present
152 if(!PrepareForUnfolding()) {
153 printf(" AliJetFlowTools::Make() Fatal error \n - couldn't prepare for unfolding ! \n");
157 // 1a) resize the jet spectrum according to the binning scheme in fBinsTrue
158 // parts of the spectrum can end up in over or underflow bins
160 Double_t binsTrue[] = {-50, -45, -40, -35, -30,-25, -20,-15, -10,-5, 0, 5, 10, 15, 20,25, 30,35, 40,45, 50, 55, 60,65, 70, 75,80,85, 90,95, 100};
161 TArrayD* temparray = new TArrayD(sizeof(binsTrue)/sizeof(binsTrue[0]), binsTrue);
162 TH1D* measuredJetSpectrumIn = RebinTH1D(fSpectrumIn, temparray, TString("resized_in_"), kFALSE);
163 TH1D* measuredJetSpectrumOut = RebinTH1D(fSpectrumOut, temparray, TString("resized_out_"), kFALSE);
165 TH1D* measuredJetSpectrumIn = RebinTH1D(fSpectrumIn, fBinsRec, TString("resized_in_"), kFALSE);
166 TH1D* measuredJetSpectrumOut = RebinTH1D(fSpectrumOut, fBinsRec, TString("resized_out_"), kFALSE);
168 // 1b) resize the jet spectrum to 'true' bins. can serve as a prior and as a template for unfolding
169 // the template will be used as a prior for the chi2 unfolding
170 TH1D* measuredJetSpectrumTrueBinsIn = RebinTH1D(fSpectrumIn, fBinsTrue, TString("in"), kFALSE);
171 TH1D* measuredJetSpectrumTrueBinsOut = RebinTH1D(fSpectrumOut, fBinsTrue, TString("out"), kFALSE);
172 // get the full response matrix from the dpt and the detector response
173 fDetectorResponse = NormalizeTH2D(fDetectorResponse);
174 // get the full response matrix. if test mode is chosen, the full response is replace by a unity matrix
175 // so that unfolding should return the initial spectrum
177 if(fUseDptResponse && fUseDetectorResponse) {
178 fFullResponseIn = MatrixMultiplication(fDptIn, fDetectorResponse);
179 fFullResponseOut = MatrixMultiplication(fDptOut, fDetectorResponse);
180 } else if (fUseDptResponse && !fUseDetectorResponse) {
181 fFullResponseIn = fDptIn;
182 fFullResponseOut = fDptOut;
183 } else if (!fUseDptResponse && fUseDetectorResponse) {
184 fFullResponseIn = fDetectorResponse;
185 fFullResponseOut = fDetectorResponse;
186 } else if (!fUseDptResponse && !fUseDetectorResponse && !fUnfoldingAlgorithm == AliJetFlowTools::kNone) {
187 printf(" > No response, exiting ! < \n" );
191 fFullResponseIn = GetUnityResponse(fBinsTrue, fBinsRec, TString("in"));
192 fFullResponseOut = GetUnityResponse(fBinsTrue, fBinsRec, TString("out"));
194 // normalize each slide of the response to one
195 NormalizeTH2D(fFullResponseIn);
196 NormalizeTH2D(fFullResponseOut);
197 // resize to desired binning scheme
198 TH2D* resizedResponseIn = RebinTH2D(fFullResponseIn, fBinsTrue, fBinsRec, TString("in"));
199 TH2D* resizedResponseOut = RebinTH2D(fFullResponseOut, fBinsTrue, fBinsRec, TString("out"));
200 // get the kinematic efficiency
201 TH1D* kinematicEfficiencyIn = resizedResponseIn->ProjectionX();
202 kinematicEfficiencyIn->SetNameTitle("kin_eff_IN","kin_eff_IN");
203 TH1D* kinematicEfficiencyOut = resizedResponseOut->ProjectionX();
204 kinematicEfficiencyOut->SetNameTitle("kin_eff_OUT", "kin_eff_OUT");
205 // suppress the errors
206 for(Int_t i(0); i < kinematicEfficiencyOut->GetXaxis()->GetNbins(); i++) {
207 kinematicEfficiencyIn->SetBinError(1+i, 0.);
208 kinematicEfficiencyOut->SetBinError(1+i, 0.);
210 TH1D* jetFindingEfficiency(0x0);
212 jetFindingEfficiency = ProtectHeap(fJetFindingEff);
213 jetFindingEfficiency->SetNameTitle(Form("%s_coarse", jetFindingEfficiency->GetName()), Form("%s_coarse", jetFindingEfficiency->GetName()));
214 jetFindingEfficiency = RebinTH1D(jetFindingEfficiency, fBinsTrue);
216 // 2, 3) call the actual unfolding. results and transient objects are stored in a dedicated TDirectoryFile
217 TH1D* unfoldedJetSpectrumIn(0x0);
218 TH1D* unfoldedJetSpectrumOut(0x0);
219 fActiveDir->cd(); // select active dir
220 TDirectoryFile* dirIn = new TDirectoryFile(Form("InPlane___%s", fActiveString.Data()), Form("InPlane___%s", fActiveString.Data()));
221 dirIn->cd(); // select inplane subdir
222 // do the inplane unfolding
223 unfoldedJetSpectrumIn = UnfoldWrapper(
224 measuredJetSpectrumIn,
226 kinematicEfficiencyIn,
227 measuredJetSpectrumTrueBinsIn,
229 jetFindingEfficiency);
230 resizedResponseIn->SetNameTitle("ResponseMatrixIn", "response matrix in plane");
231 resizedResponseIn->SetXTitle("p_{T, jet}^{true} [GeV/c]");
232 resizedResponseIn->SetYTitle("p_{T, jet}^{rec} [GeV/c]");
233 resizedResponseIn = ProtectHeap(resizedResponseIn);
234 resizedResponseIn->Write();
235 kinematicEfficiencyIn->SetNameTitle("KinematicEfficiencyIn","Kinematic efficiency, in plane");
236 kinematicEfficiencyIn = ProtectHeap(kinematicEfficiencyIn);
237 kinematicEfficiencyIn->Write();
238 fDetectorResponse->SetNameTitle("DetectorResponse", "Detector response matrix");
239 fDetectorResponse = ProtectHeap(fDetectorResponse, kFALSE);
240 fDetectorResponse->Write();
241 // optional histograms
243 fSpectrumIn->SetNameTitle("[ORIG]JetSpectrum", "[INPUT] Jet spectrum, in plane");
244 fSpectrumIn->Write();
245 fDptInDist->SetNameTitle("[ORIG]DeltaPt", "#delta p_{T} distribution, in plane");
247 fDptIn->SetNameTitle("[ORIG]DeltaPtMatrix","#delta p_{T} matrix, in plane");
249 fFullResponseIn->SetNameTitle("ResponseMatrix", "Response matrix, in plane");
250 fFullResponseIn->Write();
254 TDirectoryFile* dirOut = new TDirectoryFile(Form("OutOfPlane___%s", fActiveString.Data()), Form("OutOfPlane___%s", fActiveString.Data()));
256 // do the out of plane unfolding
257 unfoldedJetSpectrumOut = UnfoldWrapper(
258 measuredJetSpectrumOut,
260 kinematicEfficiencyOut,
261 measuredJetSpectrumTrueBinsOut,
263 jetFindingEfficiency);
264 resizedResponseOut->SetNameTitle("ResponseMatrixOut", "response matrix in plane");
265 resizedResponseOut->SetXTitle("p_{T, jet}^{true} [GeV/c]");
266 resizedResponseOut->SetYTitle("p_{T, jet}^{rec} [GeV/c]");
267 resizedResponseOut = ProtectHeap(resizedResponseOut);
268 resizedResponseOut->Write();
269 kinematicEfficiencyOut->SetNameTitle("KinematicEfficiencyOut","Kinematic efficiency, Out plane");
270 kinematicEfficiencyOut = ProtectHeap(kinematicEfficiencyOut);
271 kinematicEfficiencyOut->Write();
272 fDetectorResponse->SetNameTitle("DetectorResponse", "Detector response matrix");
273 fDetectorResponse = ProtectHeap(fDetectorResponse, kFALSE);
274 fDetectorResponse->Write();
275 if(jetFindingEfficiency) jetFindingEfficiency->Write();
276 // optional histograms
278 fSpectrumOut->SetNameTitle("[ORIG]JetSpectrum", "[INPUT]Jet spectrum, Out plane");
279 fSpectrumOut->Write();
280 fDptOutDist->SetNameTitle("[ORIG]DeltaPt", "#delta p_{T} distribution, Out plane");
281 fDptOutDist->Write();
282 fDptOut->SetNameTitle("[ORIG]DeltaPtMatrix","#delta p_{T} matrix, Out plane");
284 fFullResponseOut->SetNameTitle("[ORIG]ResponseMatrix", "Response matrix, Out plane");
285 fFullResponseOut->Write();
288 // write general output histograms to file
290 if(unfoldedJetSpectrumIn && unfoldedJetSpectrumOut && unfoldedJetSpectrumIn && unfoldedJetSpectrumOut) {
291 TGraphErrors* ratio(GetRatio((TH1D*)unfoldedJetSpectrumIn->Clone("unfoldedLocal_in"), (TH1D*)unfoldedJetSpectrumOut->Clone("unfoldedLocal_out")));
293 ratio->SetNameTitle("RatioInOutPlane", "Ratio in plane, out of plane jet spectrum");
294 ratio->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
295 ratio->GetYaxis()->SetTitle("yield IN / yield OUT");
296 ratio = ProtectHeap(ratio);
298 // write histo values to RMS files if both routines converged
299 // input values are weighted by their uncertainty
300 for(Int_t i(0); i < ratio->GetXaxis()->GetNbins(); i++) {
301 if(unfoldedJetSpectrumIn->GetBinError(i+1) > 0) fRMSSpectrumIn->Fill(fRMSSpectrumIn->GetBinCenter(i+1), unfoldedJetSpectrumIn->GetBinContent(i+1), 1./TMath::Power(unfoldedJetSpectrumIn->GetBinError(i+1), 2.));
302 if(unfoldedJetSpectrumOut->GetBinError(i+1) > 0) fRMSSpectrumOut->Fill(fRMSSpectrumOut->GetBinCenter(i+1), unfoldedJetSpectrumOut->GetBinContent(i+1), 1./TMath::Power(unfoldedJetSpectrumOut->GetBinError(i+1), 2.));
303 if(unfoldedJetSpectrumOut->GetBinContent(i+1) > 0) fRMSRatio->Fill(fRMSSpectrumIn->GetBinCenter(i+1), unfoldedJetSpectrumIn->GetBinContent(i+1) / unfoldedJetSpectrumOut->GetBinContent(i+1));
306 TGraphErrors* v2(GetV2((TH1D*)unfoldedJetSpectrumIn->Clone("unfoldedLocal_inv2"), (TH1D*)unfoldedJetSpectrumOut->Clone("unfoldedLocal_outv2")));
308 v2->SetNameTitle("v2", "v_{2} from different in, out of plane yield");
309 v2->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
310 v2->GetYaxis()->SetTitle("v_{2}");
311 v2 = ProtectHeap(v2);
314 } else if (unfoldedJetSpectrumOut && unfoldedJetSpectrumIn) {
315 TGraphErrors* ratio(GetRatio((TH1D*)unfoldedJetSpectrumIn->Clone("unfoldedLocal_in"), (TH1D*)unfoldedJetSpectrumOut->Clone("unfoldedLocal_out"), TString(""), kTRUE, fBinsRec->At(fBinsRec->GetSize()-1)));
317 ratio->SetNameTitle("[NC]RatioInOutPlane", "[NC]Ratio in plane, out of plane jet spectrum");
318 ratio->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
319 ratio->GetYaxis()->SetTitle("yield IN / yield OUT");
320 ratio = ProtectHeap(ratio);
323 TGraphErrors* v2(GetV2((TH1D*)unfoldedJetSpectrumIn->Clone("unfoldedLocal_inv2"), (TH1D*)unfoldedJetSpectrumOut->Clone("unfoldedLocal_outv2")));
325 v2->SetNameTitle("v2", "v_{2} from different in, out of plane yield");
326 v2->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
327 v2->GetYaxis()->SetTitle("v_{2}");
328 v2 = ProtectHeap(v2);
332 } // end of if(fDphiUnfolding)
333 fDeltaPtDeltaPhi->Write();
334 unfoldedJetSpectrumIn->Sumw2();
335 ProtectHeap(unfoldedJetSpectrumIn, kFALSE);
336 unfoldedJetSpectrumIn->Write();
337 unfoldedJetSpectrumOut->Sumw2();
338 ProtectHeap(unfoldedJetSpectrumOut, kFALSE);
339 unfoldedJetSpectrumOut->Write();
340 fJetPtDeltaPhi->Write();
341 // save the current state of the unfolding object
342 SaveConfiguration(unfoldedJetSpectrumIn ? kTRUE : kFALSE, unfoldedJetSpectrumOut ? kTRUE : kFALSE);
343 TH1D* unfoldedJetSpectrumInForSub((TH1D*)unfoldedJetSpectrumIn->Clone("forSubIn"));
344 TH1D* unfoldedJetSpectrumOutForSub((TH1D*)unfoldedJetSpectrumOut->Clone("forSubOut"));
345 unfoldedJetSpectrumInForSub->Add(unfoldedJetSpectrumOutForSub, -1.);
346 unfoldedJetSpectrumInForSub= ProtectHeap(unfoldedJetSpectrumInForSub);
347 unfoldedJetSpectrumInForSub->Write();
350 //_____________________________________________________________________________
351 TH1D* AliJetFlowTools::UnfoldWrapper(
352 const TH1D* measuredJetSpectrum, // truncated raw jets (same binning as pt rec of response)
353 const TH2D* resizedResponse, // response matrix
354 const TH1D* kinematicEfficiency, // kinematic efficiency
355 const TH1D* measuredJetSpectrumTrueBins, // unfolding template: same binning is pt gen of response
356 const TString suffix, // suffix (in or out of plane)
357 const TH1D* jetFindingEfficiency) // jet finding efficiency
359 // wrapper function to call specific unfolding routine
360 TH1D* (AliJetFlowTools::*myFunction)(const TH1D*, const TH2D*, const TH1D*, const TH1D*, const TString, const TH1D*);
361 // initialize functon pointer
362 if(fUnfoldingAlgorithm == kChi2) myFunction = &AliJetFlowTools::UnfoldSpectrumChi2;
363 else if(fUnfoldingAlgorithm == kBayesian) myFunction = &AliJetFlowTools::UnfoldSpectrumBayesian;
364 else if(fUnfoldingAlgorithm == kBayesianAli) myFunction = &AliJetFlowTools::UnfoldSpectrumBayesianAli;
365 else if(fUnfoldingAlgorithm == kSVD) myFunction = &AliJetFlowTools::UnfoldSpectrumSVD;
366 else if(fUnfoldingAlgorithm == kNone) {
367 TH1D* clone((TH1D*)measuredJetSpectrum->Clone("clone"));
368 clone->SetNameTitle(Form("MeasuredJetSpectrum%s", suffix.Data()), Form("measuredJetSpectrum %s", suffix.Data()));
372 // do the actual unfolding with the selected function
373 return (this->*myFunction)( measuredJetSpectrum, resizedResponse, kinematicEfficiency, measuredJetSpectrumTrueBins, suffix, jetFindingEfficiency);
375 //_____________________________________________________________________________
376 TH1D* AliJetFlowTools::UnfoldSpectrumChi2(
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 (optional)
384 // unfold the spectrum using chi2 minimization
386 // step 0) setup the static members of AliUnfolding
387 ResetAliUnfolding(); // reset from previous iteration
388 // also deletes and re-creates the global TVirtualFitter
389 AliUnfolding::SetUnfoldingMethod(AliUnfolding::kChi2Minimization);
390 if(!strcmp("in", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaIn);
391 else if(!strcmp("out", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaOut);
392 if(!strcmp("prior_in", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaIn);
393 else if(!strcmp("prior_out", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaOut);
394 AliUnfolding::SetNbins(fBinsRec->GetSize()-1, fBinsTrue->GetSize()-1);
396 // step 1) clone all input histograms. the histograms are cloned to make sure that the original histograms
397 // stay intact. a local copy of a histogram (which only exists in the scope of this function) is
398 // denoted by the suffix 'Local'
400 // measuredJetSpectrumLocal holds the spectrum that needs to be unfolded
401 TH1D *measuredJetSpectrumLocal = (TH1D*)measuredJetSpectrum->Clone(Form("measuredJetSpectrumLocal_%s", suffix.Data()));
402 // unfolded local will be filled with the result of the unfolding
403 TH1D *unfoldedLocal(new TH1D(Form("unfoldedLocal_%s", suffix.Data()), Form("unfoldedLocal_%s", suffix.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
405 // full response matrix and kinematic efficiency
406 TH2D* resizedResponseLocal = (TH2D*)resizedResponse->Clone(Form("resizedResponseLocal_%s", suffix.Data()));
407 TH1D* kinematicEfficiencyLocal = (TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiencyLocal_%s", suffix.Data()));
409 // the initial guess for the unfolded pt spectrum, equal to the folded spectrum, but in 'true' bins
410 TH1D *priorLocal = (TH1D*)measuredJetSpectrumTrueBins->Clone(Form("priorLocal_%s", suffix.Data()));
411 // optionally, the prior can be smoothened by extrapolating the spectrum using a power law fit
412 if(fSmoothenPrior) priorLocal = SmoothenPrior(priorLocal, fPower, fFitMin, fFitMax, fFitStart, kTRUE, fSmoothenCounts);
414 // step 2) start the unfolding
415 Int_t status(-1), i(0);
416 while(status < 0 && i < 100) {
417 // i > 0 means that the first iteration didn't converge. in that case, the result of the first
418 // iteration (stored in unfoldedLocal) is cloned and used as a starting point for the
419 if (i > 0) priorLocal = (TH1D*)unfoldedLocal->Clone(Form("priorLocal_%s_%i", suffix.Data(), i));
420 status = AliUnfolding::Unfold(
421 resizedResponseLocal, // response matrix
422 kinematicEfficiencyLocal, // efficiency applied on the unfolded spectrum (can be NULL)
423 measuredJetSpectrumLocal, // measured spectrum
424 priorLocal, // initial conditions (set NULL to use measured spectrum)
425 unfoldedLocal); // results
426 // status holds the minuit fit status (where 0 means convergence)
429 // get the status of TMinuit::mnhess(), fISW[1] == 3 means the hessian matrix was calculated succesfully
430 if(status == 0 && gMinuit->fISW[1] == 3) {
431 // if the unfolding converged and the hessian matrix is reliable, plot the pearson coefficients
432 TVirtualFitter *fitter(TVirtualFitter::GetFitter());
433 if(gMinuit) gMinuit->Command("SET COV");
434 TMatrixD covarianceMatrix(fBinsTrue->GetSize()-1, fBinsTrue->GetSize()-1, fitter->GetCovarianceMatrix());
435 TMatrixD *pearson((TMatrixD*)CalculatePearsonCoefficients(&covarianceMatrix));
437 TH2D *hPearson(new TH2D(*pearson));
438 hPearson->SetNameTitle(Form("PearsonCoefficients_%s", suffix.Data()), Form("Pearson coefficients, %s plane", suffix.Data()));
439 hPearson = ProtectHeap(hPearson);
443 // step 3) refold the unfolded spectrum and save the ratio measured / refolded
444 TH1D *foldedLocal(fResponseMaker->MultiplyResponseGenerated(unfoldedLocal, resizedResponseLocal,kinematicEfficiencyLocal));
445 foldedLocal->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("Refolded jet spectrum, %s plane", suffix.Data()));
446 unfoldedLocal->SetNameTitle(Form("UnfoldedSpectrum_%s", suffix.Data()), Form("Unfolded jet spectrum, %s plane", suffix.Data()));
447 TGraphErrors* ratio(GetRatio(foldedLocal, measuredJetSpectrumLocal, TString(""), kTRUE, fBinsTrue->At(fBinsTrue->GetSize()-1)));
449 ratio->SetNameTitle("RatioRefoldedMeasured", Form("Ratio measured, re-folded %s ", suffix.Data()));
450 ratio->GetYaxis()->SetTitle("ratio measured / re-folded");
451 ratio = ProtectHeap(ratio);
455 // step 4) write histograms to file. to ensure that these have unique identifiers on the heap,
456 // objects are cloned using 'ProtectHeap()'
457 measuredJetSpectrumLocal->SetNameTitle(Form("InputSpectrum_%s", suffix.Data()), Form("InputSpectrum_%s", suffix.Data()));
458 measuredJetSpectrumLocal = ProtectHeap(measuredJetSpectrumLocal);
459 measuredJetSpectrumLocal->Write();
461 resizedResponseLocal = ProtectHeap(resizedResponseLocal);
462 resizedResponseLocal->Write();
464 unfoldedLocal = ProtectHeap(unfoldedLocal);
465 if(jetFindingEfficiency) unfoldedLocal->Divide(jetFindingEfficiency);
466 unfoldedLocal->Write();
468 foldedLocal = ProtectHeap(foldedLocal);
469 foldedLocal->Write();
471 priorLocal = ProtectHeap(priorLocal);
474 // step 5) save the fit status (penalty value, degrees of freedom, chi^2 value)
475 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));
476 fitStatus->SetBinContent(1, AliUnfolding::fChi2FromFit);
477 fitStatus->GetXaxis()->SetBinLabel(1, "fChi2FromFit");
478 fitStatus->SetBinContent(2, AliUnfolding::fPenaltyVal);
479 fitStatus->GetXaxis()->SetBinLabel(2, "fPenaltyVal");
480 fitStatus->SetBinContent(3, fBinsRec->GetSize()-fBinsTrue->GetSize());
481 fitStatus->GetXaxis()->SetBinLabel(3, "DOF");
482 fitStatus->SetBinContent(4, (!strcmp(suffix.Data(), "in")) ? fBetaIn : fBetaOut);
483 fitStatus->GetXaxis()->SetBinLabel(4, (!strcmp(suffix.Data(), "in")) ? "fBetaIn" : "fBetaOut");
485 return unfoldedLocal;
487 //_____________________________________________________________________________
488 TH1D* AliJetFlowTools::UnfoldSpectrumSVD(
489 const TH1D* measuredJetSpectrum, // jet pt in pt rec bins
490 const TH2D* resizedResponse, // full response matrix, normalized in slides of pt true
491 const TH1D* kinematicEfficiency, // kinematic efficiency
492 const TH1D* measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
493 const TString suffix, // suffix (in, out)
494 const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
497 TH1D* priorLocal( GetPrior(
498 measuredJetSpectrum, // jet pt in pt rec bins
499 resizedResponse, // full response matrix, normalized in slides of pt true
500 kinematicEfficiency, // kinematic efficiency
501 measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
502 suffix, // suffix (in, out)
503 jetFindingEfficiency)); // jet finding efficiency (optional)
505 printf(" > couldn't find prior ! < \n");
507 } else printf(" 1) retrieved prior \n");
509 // go back to the 'root' directory of this instance of the SVD unfolding routine
510 (!strcmp(suffix.Data(), "in")) ? fActiveDir->cd(Form("InPlane___%s", fActiveString.Data())) : fActiveDir->cd(Form("OutOfPlane___%s", fActiveString.Data()));
512 // 2) setup all the necessary input for the unfolding routine. all input histograms are copied locally
513 // measured jets in pt rec binning
514 TH1D *measuredJetSpectrumLocal((TH1D*)measuredJetSpectrum->Clone(Form("jets_%s", suffix.Data())));
515 // local copie of the response matrix
516 TH2D *resizedResponseLocal((TH2D*)resizedResponse->Clone(Form("resizedResponseLocal_%s", suffix.Data())));
517 // local copy of response matrix, all true slides normalized to 1
518 // this response matrix will eventually be used in the re-folding routine
519 TH2D *resizedResponseLocalNorm((TH2D*)resizedResponse->Clone(Form("resizedResponseLocalNorm_%s", suffix.Data())));
520 resizedResponseLocalNorm = NormalizeTH2D(resizedResponseLocalNorm);
521 // kinematic efficiency
522 TH1D *kinematicEfficiencyLocal((TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiency_%s", suffix.Data())));
523 // place holder histos
524 TH1D *unfoldedLocalSVD(0x0);
525 TH1D *foldedLocalSVD(0x0);
526 cout << " 2) setup necessary input " << endl;
527 // 3) configure routine
528 RooUnfold::ErrorTreatment errorTreatment = (fSVDToy) ? RooUnfold::kCovToy : RooUnfold::kCovariance;
529 cout << " step 3) configured routine " << endl;
531 // 4) get transpose matrices
532 // a) get the transpose of the full response matrix
533 TH2* responseMatrixLocalTransposePrior(fResponseMaker->GetTransposeResponsMatrix(resizedResponseLocal));
534 responseMatrixLocalTransposePrior->SetNameTitle(Form("prior_%s_%s", responseMatrixLocalTransposePrior->GetName(), suffix.Data()),Form("prior_%s_%s", responseMatrixLocalTransposePrior->GetName(), suffix.Data()));
535 // normalize it with the prior. this will ensure that high statistics bins will constrain the
536 // end result most strenuously than bins with limited number of counts
537 responseMatrixLocalTransposePrior = fResponseMaker->NormalizeResponsMatrixYaxisWithPrior(responseMatrixLocalTransposePrior, priorLocal);
538 cout << " 4) retrieved first transpose matrix " << endl;
540 // 5) get response for SVD unfolding
541 RooUnfoldResponse responseSVD(0, 0, responseMatrixLocalTransposePrior, Form("respCombinedSVD_%s", suffix.Data()), Form("respCombinedSVD_%s", suffix.Data()));
542 cout << " 5) retrieved roo unfold response object " << endl;
544 // 6) actualy unfolding loop
545 RooUnfoldSvd unfoldSVD(&responseSVD, measuredJetSpectrumLocal, (!strcmp(suffix.Data(), "in")) ? fSVDRegIn : fSVDRegOut);
546 unfoldedLocalSVD = (TH1D*)unfoldSVD.Hreco(errorTreatment);
547 // correct the spectrum for the kinematic efficiency
548 unfoldedLocalSVD->Divide(kinematicEfficiencyLocal);
550 // get the pearson coefficients from the covariance matrix
551 TMatrixD covarianceMatrix = unfoldSVD.Ereco(errorTreatment);
552 TMatrixD *pearson = (TMatrixD*)CalculatePearsonCoefficients(&covarianceMatrix);
554 TH2D* hPearson(new TH2D(*pearson));
556 hPearson->SetNameTitle(Form("PearsonCoefficients_%s", suffix.Data()), Form("Pearson coefficients_%s", suffix.Data()));
557 hPearson = ProtectHeap(hPearson);
559 } else return 0x0; // return if unfolding didn't converge
561 // plot singular values and d_i vector
562 TSVDUnfold* svdUnfold(unfoldSVD.Impl());
563 TH1* hSVal(svdUnfold->GetSV());
564 TH1D* hdi(svdUnfold->GetD());
565 hSVal->SetNameTitle("SingularValuesOfAC", "Singular values of AC^{-1}");
566 hSVal->SetXTitle("singular values");
568 hdi->SetNameTitle("dVector", "d vector after orthogonal transformation");
569 hdi->SetXTitle("|d_{i}^{kreg}|");
571 cout << " plotted singular values and d_i vector " << endl;
573 // 7) refold the unfolded spectrum
574 foldedLocalSVD = fResponseMaker->MultiplyResponseGenerated(unfoldedLocalSVD, resizedResponseLocalNorm, kinematicEfficiencyLocal);
575 TGraphErrors* ratio(GetRatio(measuredJetSpectrumLocal, foldedLocalSVD, "ratio measured / re-folded", kTRUE));
576 ratio->SetNameTitle(Form("RatioRefoldedMeasured_%s", fActiveString.Data()), Form("Ratio measured / re-folded %s", fActiveString.Data()));
577 ratio->GetXaxis()->SetTitle("p_{t}^{rec, rec} [GeV/ c]");
578 ratio->GetYaxis()->SetTitle("ratio measured / re-folded");
580 cout << " 7) refolded the unfolded spectrum " << endl;
582 // write the measured, unfolded and re-folded spectra to the output directory
583 measuredJetSpectrumLocal->SetNameTitle(Form("InputSpectrum_%s", suffix.Data()), Form("input spectrum (measured) %s", suffix.Data()));
584 measuredJetSpectrumLocal = ProtectHeap(measuredJetSpectrumLocal);
585 measuredJetSpectrumLocal->SetXTitle("p_{t}^{rec} [GeV/c]");
586 measuredJetSpectrumLocal->Write(); // input spectrum
587 unfoldedLocalSVD->SetNameTitle(Form("UnfoldedSpectrum_%s",suffix.Data()), Form("unfolded spectrum %s", suffix.Data()));
588 unfoldedLocalSVD = ProtectHeap(unfoldedLocalSVD);
589 if(jetFindingEfficiency) unfoldedLocalSVD->Divide(jetFindingEfficiency);
590 unfoldedLocalSVD->Write(); // unfolded spectrum
591 foldedLocalSVD->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("refoldedSpectrum_%s", suffix.Data()));
592 foldedLocalSVD = ProtectHeap(foldedLocalSVD);
593 foldedLocalSVD->Write(); // re-folded spectrum
595 // save more general bookkeeeping histograms to the output directory
596 responseMatrixLocalTransposePrior->SetNameTitle("TransposeResponseMatrix", "Transpose of response matrix, normalize with prior");
597 responseMatrixLocalTransposePrior->SetXTitle("p_{T, jet}^{true} [GeV/c]");
598 responseMatrixLocalTransposePrior->SetYTitle("p_{T, jet}^{rec} [GeV/c]");
599 responseMatrixLocalTransposePrior->Write();
600 priorLocal->SetNameTitle("PriorOriginal", "Prior, original");
601 priorLocal->SetXTitle("p_{t} [GeV/c]");
602 priorLocal = ProtectHeap(priorLocal);
604 resizedResponseLocalNorm = ProtectHeap(resizedResponseLocalNorm);
605 resizedResponseLocalNorm->Write();
608 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));
609 fitStatus->SetBinContent(1, (!strcmp(suffix.Data(), "in")) ? fSVDRegIn : fSVDRegOut);
610 fitStatus->GetXaxis()->SetBinLabel(1, (!strcmp(suffix.Data(), "in")) ? "fSVDRegIn" : "fSVDRegOut");
613 return unfoldedLocalSVD;
615 //_____________________________________________________________________________
616 TH1D* AliJetFlowTools::UnfoldSpectrumBayesianAli(
617 const TH1D* measuredJetSpectrum, // jet pt in pt rec bins
618 const TH2D* resizedResponse, // full response matrix, normalized in slides of pt true
619 const TH1D* kinematicEfficiency, // kinematic efficiency
620 const TH1D* measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
621 const TString suffix, // suffix (in, out)
622 const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
624 // unfold the spectrum using the bayesian unfolding impelmented in AliUnfolding
625 // FIXME careful, not tested yet ! (06122013) FIXME
627 // step 0) setup the static members of AliUnfolding
628 ResetAliUnfolding(); // reset from previous iteration
629 // also deletes and re-creates the global TVirtualFitter
630 AliUnfolding::SetUnfoldingMethod(AliUnfolding::kBayesian);
631 if(!strcmp("in", suffix.Data())) AliUnfolding::SetBayesianParameters(fBayesianSmoothIn, fBayesianIterIn);
632 else if(!strcmp("out", suffix.Data())) AliUnfolding::SetBayesianParameters(fBayesianSmoothOut, fBayesianIterOut);
633 else if(!strcmp("prior_in", suffix.Data())) AliUnfolding::SetBayesianParameters(fBayesianSmoothIn, fBayesianIterIn);
634 else if(!strcmp("prior_out", suffix.Data())) AliUnfolding::SetBayesianParameters(fBayesianSmoothOut, fBayesianIterOut);
635 AliUnfolding::SetNbins(fBinsRec->GetSize()-1, fBinsTrue->GetSize()-1);
637 // 1) get a prior for unfolding and clone all the input histograms
638 TH1D* priorLocal( GetPrior(
639 measuredJetSpectrum, // jet pt in pt rec bins
640 resizedResponse, // full response matrix, normalized in slides of pt true
641 kinematicEfficiency, // kinematic efficiency
642 measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
643 suffix, // suffix (in, out)
644 jetFindingEfficiency)); // jet finding efficiency (optional)
646 printf(" > couldn't find prior ! < \n");
648 } else printf(" 1) retrieved prior \n");
649 // switch back to root dir of this unfolding procedure
650 (!strcmp(suffix.Data(), "in")) ? fActiveDir->cd(Form("InPlane___%s", fActiveString.Data())) : fActiveDir->cd(Form("OutOfPlane___%s", fActiveString.Data()));
652 // measuredJetSpectrumLocal holds the spectrum that needs to be unfolded
653 TH1D *measuredJetSpectrumLocal = (TH1D*)measuredJetSpectrum->Clone(Form("measuredJetSpectrumLocal_%s", suffix.Data()));
654 // unfolded local will be filled with the result of the unfolding
655 TH1D *unfoldedLocal(new TH1D(Form("unfoldedLocal_%s", suffix.Data()), Form("unfoldedLocal_%s", suffix.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
657 // full response matrix and kinematic efficiency
658 TH2D* resizedResponseLocal = (TH2D*)resizedResponse->Clone(Form("resizedResponseLocal_%s", suffix.Data()));
659 TH1D* kinematicEfficiencyLocal = (TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiencyLocal_%s", suffix.Data()));
661 // step 2) start the unfolding
662 Int_t status(-1), i(0);
663 while(status < 0 && i < 100) {
664 // i > 0 means that the first iteration didn't converge. in that case, the result of the first
665 // iteration (stored in unfoldedLocal) is cloned and used as a starting point for the
666 if (i > 0) priorLocal = (TH1D*)unfoldedLocal->Clone(Form("priorLocal_%s_%i", suffix.Data(), i));
667 status = AliUnfolding::Unfold(
668 resizedResponseLocal, // response matrix
669 kinematicEfficiencyLocal, // efficiency applied on the unfolded spectrum (can be NULL)
670 measuredJetSpectrumLocal, // measured spectrum
671 priorLocal, // initial conditions (set NULL to use measured spectrum)
672 unfoldedLocal); // results
673 // status holds the minuit fit status (where 0 means convergence)
676 // get the status of TMinuit::mnhess(), fISW[1] == 3 means the hessian matrix was calculated succesfully
677 if(status == 0 && gMinuit->fISW[1] == 3) {
678 // if the unfolding converged and the hessian matrix is reliable, plot the pearson coefficients
679 TVirtualFitter *fitter(TVirtualFitter::GetFitter());
680 if(gMinuit) gMinuit->Command("SET COV");
681 TMatrixD covarianceMatrix(fBinsTrue->GetSize()-1, fBinsTrue->GetSize()-1, fitter->GetCovarianceMatrix());
682 TMatrixD *pearson((TMatrixD*)CalculatePearsonCoefficients(&covarianceMatrix));
684 TH2D *hPearson(new TH2D(*pearson));
685 hPearson->SetNameTitle(Form("PearsonCoefficients_%s", suffix.Data()), Form("Pearson coefficients, %s plane", suffix.Data()));
686 hPearson = ProtectHeap(hPearson);
690 // step 3) refold the unfolded spectrum and save the ratio measured / refolded
691 TH1D *foldedLocal(fResponseMaker->MultiplyResponseGenerated(unfoldedLocal, resizedResponseLocal,kinematicEfficiencyLocal));
692 foldedLocal->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("Refolded jet spectrum, %s plane", suffix.Data()));
693 unfoldedLocal->SetNameTitle(Form("UnfoldedSpectrum_%s", suffix.Data()), Form("Unfolded jet spectrum, %s plane", suffix.Data()));
694 TGraphErrors* ratio(GetRatio(foldedLocal, measuredJetSpectrumLocal, TString(""), kTRUE, fBinsTrue->At(fBinsTrue->GetSize()-1)));
696 ratio->SetNameTitle("RatioRefoldedMeasured", Form("Ratio measured, re-folded %s ", suffix.Data()));
697 ratio->GetYaxis()->SetTitle("ratio measured / re-folded");
698 ratio = ProtectHeap(ratio);
702 // step 4) write histograms to file. to ensure that these have unique identifiers on the heap,
703 // objects are cloned using 'ProtectHeap()'
704 measuredJetSpectrumLocal->SetNameTitle(Form("InputSpectrum_%s", suffix.Data()), Form("InputSpectrum_%s", suffix.Data()));
705 measuredJetSpectrumLocal = ProtectHeap(measuredJetSpectrumLocal);
706 measuredJetSpectrumLocal->Write();
708 resizedResponseLocal = ProtectHeap(resizedResponseLocal);
709 resizedResponseLocal->Write();
711 unfoldedLocal = ProtectHeap(unfoldedLocal);
712 if(jetFindingEfficiency) unfoldedLocal->Divide(jetFindingEfficiency);
713 unfoldedLocal->Write();
715 foldedLocal = ProtectHeap(foldedLocal);
716 foldedLocal->Write();
718 priorLocal = ProtectHeap(priorLocal);
721 // step 5) save the fit status (penalty value, degrees of freedom, chi^2 value)
722 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));
723 fitStatus->SetBinContent(1, AliUnfolding::fChi2FromFit);
724 fitStatus->GetXaxis()->SetBinLabel(1, "fChi2FromFit");
725 fitStatus->SetBinContent(2, AliUnfolding::fPenaltyVal);
726 fitStatus->GetXaxis()->SetBinLabel(2, "fPenaltyVal");
727 fitStatus->SetBinContent(3, fBinsRec->GetSize()-fBinsTrue->GetSize());
728 fitStatus->GetXaxis()->SetBinLabel(3, "DOF");
729 fitStatus->SetBinContent(4, (!strcmp(suffix.Data(), "in")) ? fBetaIn : fBetaOut);
730 fitStatus->GetXaxis()->SetBinLabel(4, (!strcmp(suffix.Data(), "in")) ? "fBetaIn" : "fBetaOut");
732 return unfoldedLocal;
734 //_____________________________________________________________________________
735 TH1D* AliJetFlowTools::UnfoldSpectrumBayesian(
736 const TH1D* measuredJetSpectrum, // jet pt in pt rec bins
737 const TH2D* resizedResponse, // full response matrix, normalized in slides of pt true
738 const TH1D* kinematicEfficiency, // kinematic efficiency
739 const TH1D* measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
740 const TString suffix, // suffix (in, out)
741 const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
743 // use bayesian unfolding from the RooUnfold package to unfold jet spectra
745 // 1) get a prior for unfolding.
746 TH1D* priorLocal( GetPrior(
747 measuredJetSpectrum, // jet pt in pt rec bins
748 resizedResponse, // full response matrix, normalized in slides of pt true
749 kinematicEfficiency, // kinematic efficiency
750 measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
751 suffix, // suffix (in, out)
752 jetFindingEfficiency)); // jet finding efficiency (optional)
754 printf(" > couldn't find prior ! < \n");
756 } else printf(" 1) retrieved prior \n");
757 (!strcmp(suffix.Data(), "in")) ? fActiveDir->cd(Form("InPlane___%s", fActiveString.Data())) : fActiveDir->cd(Form("OutOfPlane___%s", fActiveString.Data()));
759 // 2) setup all the necessary input for the unfolding routine. all input histograms are copied locally
760 // measured jets in pt rec binning
761 TH1D *measuredJetSpectrumLocal((TH1D*)measuredJetSpectrum->Clone(Form("jets_%s", suffix.Data())));
762 // local copie of the response matrix
763 TH2D *resizedResponseLocal((TH2D*)resizedResponse->Clone(Form("resizedResponseLocal_%s", suffix.Data())));
764 // local copy of response matrix, all true slides normalized to 1
765 // this response matrix will eventually be used in the re-folding routine
766 TH2D *resizedResponseLocalNorm((TH2D*)resizedResponse->Clone(Form("resizedResponseLocalNorm_%s", suffix.Data())));
767 resizedResponseLocalNorm = NormalizeTH2D(resizedResponseLocalNorm);
768 // kinematic efficiency
769 TH1D *kinematicEfficiencyLocal((TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiency_%s", suffix.Data())));
770 // place holder histos
771 TH1D *unfoldedLocalBayes(0x0);
772 TH1D *foldedLocalBayes(0x0);
773 cout << " 2) setup necessary input " << endl;
774 // 4) get transpose matrices
775 // a) get the transpose of the full response matrix
776 TH2* responseMatrixLocalTransposePrior(fResponseMaker->GetTransposeResponsMatrix(resizedResponseLocal));
777 responseMatrixLocalTransposePrior->SetNameTitle(Form("prior_%s_%s", responseMatrixLocalTransposePrior->GetName(), suffix.Data()),Form("prior_%s_%s", responseMatrixLocalTransposePrior->GetName(), suffix.Data()));
778 // normalize it with the prior. this will ensure that high statistics bins will constrain the
779 // end result most strenuously than bins with limited number of counts
780 responseMatrixLocalTransposePrior = fResponseMaker->NormalizeResponsMatrixYaxisWithPrior(responseMatrixLocalTransposePrior, priorLocal);
781 // 3) get response for Bayesian unfolding
782 RooUnfoldResponse responseBayes(0, 0, responseMatrixLocalTransposePrior, Form("respCombinedBayes_%s", suffix.Data()), Form("respCombinedBayes_%s", suffix.Data()));
784 // 4) actualy unfolding loop
785 RooUnfoldBayes unfoldBayes(&responseBayes, measuredJetSpectrumLocal, (!strcmp("in", suffix.Data())) ? fBayesianIterIn : fBayesianIterOut);
786 RooUnfold::ErrorTreatment errorTreatment = (fSVDToy) ? RooUnfold::kCovToy : RooUnfold::kCovariance;
787 unfoldedLocalBayes = (TH1D*)unfoldBayes.Hreco(errorTreatment);
788 // correct the spectrum for the kinematic efficiency
789 unfoldedLocalBayes->Divide(kinematicEfficiencyLocal);
790 // get the pearson coefficients from the covariance matrix
791 TMatrixD covarianceMatrix = unfoldBayes.Ereco(errorTreatment);
792 TMatrixD *pearson = (TMatrixD*)CalculatePearsonCoefficients(&covarianceMatrix);
794 TH2D* hPearson(new TH2D(*pearson));
796 hPearson->SetNameTitle(Form("PearsonCoefficients_%s", suffix.Data()), Form("Pearson coefficients_%s", suffix.Data()));
797 hPearson = ProtectHeap(hPearson);
799 } else return 0x0; // return if unfolding didn't converge
801 // 5) refold the unfolded spectrum
802 foldedLocalBayes = fResponseMaker->MultiplyResponseGenerated(unfoldedLocalBayes, resizedResponseLocalNorm, kinematicEfficiencyLocal);
803 TGraphErrors* ratio(GetRatio(measuredJetSpectrumLocal, foldedLocalBayes, "ratio measured / re-folded", kTRUE));
804 ratio->SetNameTitle(Form("RatioRefoldedMeasured_%s", fActiveString.Data()), Form("Ratio measured / re-folded %s", fActiveString.Data()));
805 ratio->GetXaxis()->SetTitle("p_{t}^{rec, rec} [GeV/ c]");
806 ratio->GetYaxis()->SetTitle("ratio measured / re-folded");
808 cout << " 7) refolded the unfolded spectrum " << endl;
810 // write the measured, unfolded and re-folded spectra to the output directory
811 measuredJetSpectrumLocal->SetNameTitle(Form("InputSpectrum_%s", suffix.Data()), Form("input spectrum (measured) %s", suffix.Data()));
812 measuredJetSpectrumLocal = ProtectHeap(measuredJetSpectrumLocal);
813 measuredJetSpectrumLocal->SetXTitle("p_{t}^{rec} [GeV/c]");
814 measuredJetSpectrumLocal->Write(); // input spectrum
815 unfoldedLocalBayes->SetNameTitle(Form("UnfoldedSpectrum_%s",suffix.Data()), Form("unfolded spectrum %s", suffix.Data()));
816 unfoldedLocalBayes = ProtectHeap(unfoldedLocalBayes);
817 if(jetFindingEfficiency) unfoldedLocalBayes->Divide(jetFindingEfficiency);
818 unfoldedLocalBayes->Write(); // unfolded spectrum
819 foldedLocalBayes->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("refoldedSpectrum_%s", suffix.Data()));
820 foldedLocalBayes = ProtectHeap(foldedLocalBayes);
821 foldedLocalBayes->Write(); // re-folded spectrum
823 // save more general bookkeeeping histograms to the output directory
824 responseMatrixLocalTransposePrior->SetNameTitle("TransposeResponseMatrix", "Transpose of response matrix, normalize with prior");
825 responseMatrixLocalTransposePrior->SetXTitle("p_{T, jet}^{true} [GeV/c]");
826 responseMatrixLocalTransposePrior->SetYTitle("p_{T, jet}^{rec} [GeV/c]");
827 responseMatrixLocalTransposePrior->Write();
828 priorLocal->SetNameTitle("PriorOriginal", "Prior, original");
829 priorLocal->SetXTitle("p_{t} [GeV/c]");
830 priorLocal = ProtectHeap(priorLocal);
832 resizedResponseLocalNorm = ProtectHeap(resizedResponseLocalNorm);
833 resizedResponseLocalNorm->Write();
836 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));
837 fitStatus->SetBinContent(1, (!strcmp(suffix.Data(), "in")) ? fBayesianIterIn : fBayesianIterOut);
838 fitStatus->GetXaxis()->SetBinLabel(1, (!strcmp(suffix.Data(), "in")) ? "fBayesianIterIn" : "fBayesianIterOut");
841 return unfoldedLocalBayes;
843 //_____________________________________________________________________________
844 Bool_t AliJetFlowTools::PrepareForUnfolding()
846 // prepare for unfolding
847 if(fRawInputProvided) return kTRUE;
849 printf(" AliJetFlowTools::PrepareForUnfolding() fInputList not found \n - Set a list using AliJetFlowTools::SetInputList() \n");
852 if(!fDetectorResponse) printf(" WARNING, no detector response supplied ! May be ok (depending on what you want to do) \n ");
853 // check if the pt bin for true and rec have been set
854 if(!fBinsTrue || !fBinsRec) {
855 printf(" AliJetFlowTools::PrepareForUnfolding() no true or rec bins set, aborting ! \n");
858 if(!fRMSSpectrumIn && fDphiUnfolding) { // initialie the profiles which will hold the RMS values. if binning changes in between unfolding
859 // procedures, these profiles will be nonsensical, user is responsible
860 fRMSSpectrumIn = new TProfile("fRMSSpectrumIn", "fRMSSpectrumIn", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
861 fRMSSpectrumOut = new TProfile("fRMSSpectrumOut", "fRMSSpectrumOut", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
862 fRMSRatio = new TProfile("fRMSRatio", "fRMSRatio", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
865 // clear minuit state to avoid constraining the fit with the results of the previous iteration
866 for(Int_t i(0); i < fPower->GetNpar(); i++) fPower->SetParameter(i, 0.);
868 // extract the spectra
869 TString spectrumName(Form("fHistJetPsi2Pt_%i", fCentralityBin));
870 fJetPtDeltaPhi = ((TH2D*)fInputList->FindObject(spectrumName.Data()));
871 if(!fJetPtDeltaPhi) {
872 printf(" Couldn't find spectrum %s ! \n", spectrumName.Data());
875 fJetPtDeltaPhi = ProtectHeap(fJetPtDeltaPhi, kFALSE);
877 if(!fDphiUnfolding) {
878 fSpectrumIn = fJetPtDeltaPhi->ProjectionY(Form("_py_in_%s", spectrumName.Data()), 1, 40, "e");
879 fSpectrumOut = fJetPtDeltaPhi->ProjectionY(Form("_py_out_%s", spectrumName.Data()), 1, 40, "e");
881 fSpectrumIn = fJetPtDeltaPhi->ProjectionY(Form("_py_ina_%s", spectrumName.Data()), 1, 10, "e");
882 fSpectrumIn->Add(fJetPtDeltaPhi->ProjectionY(Form("_py_inb_%s", spectrumName.Data()), 31, 40, "e"));
883 fSpectrumIn = ProtectHeap(fSpectrumIn);
884 // out of plane spectrum
885 fSpectrumOut = fJetPtDeltaPhi->ProjectionY(Form("_py_out_%s", spectrumName.Data()), 11, 30, "e");
886 fSpectrumOut = ProtectHeap(fSpectrumOut);
888 // normalize spectra to event count if requested
889 if(fNormalizeSpectra) {
890 TH1* rho((TH1*)fInputList->FindObject(Form("fHistRho_%i", fCentralityBin)));
892 Bool_t normalizeToFullSpectrum = (fEventCount < 0) ? kTRUE : kFALSE;
893 if (normalizeToFullSpectrum) fEventCount = rho->GetEntries();
894 if(fEventCount > 0) {
895 fSpectrumIn->Sumw2(); // necessary for correct error propagation of scale
896 fSpectrumOut->Sumw2();
898 Double_t error(0); // lots of issues with the errors here ...
899 for(Int_t i(0); i < fSpectrumIn->GetXaxis()->GetNbins(); i++) {
900 pt = fSpectrumIn->GetBinContent(1+i)/fEventCount; // normalized count
901 error = 1./((double)(fEventCount*fEventCount))*fSpectrumIn->GetBinError(1+i)*fSpectrumIn->GetBinError(1+i);
902 fSpectrumIn->SetBinContent(1+i, pt);
903 if(pt <= 0 ) fSpectrumIn->SetBinError(1+i, 0.);
904 if(error > 0) fSpectrumIn->SetBinError(1+i, error);
905 else fSpectrumIn->SetBinError(1+i, TMath::Sqrt(pt));
907 for(Int_t i(0); i < fSpectrumOut->GetXaxis()->GetNbins(); i++) {
908 pt = fSpectrumOut->GetBinContent(1+i)/fEventCount; // normalized count
909 error = 1./((double)(fEventCount*fEventCount))*fSpectrumOut->GetBinError(1+i)*fSpectrumOut->GetBinError(1+i);
910 fSpectrumOut->SetBinContent(1+i, pt);
911 if( pt <= 0) fSpectrumOut->SetBinError(1+i, 0.);
912 if(error > 0) fSpectrumOut->SetBinError(1+i, error);
913 else fSpectrumOut->SetBinError(1+i, TMath::Sqrt(pt));
916 if(normalizeToFullSpectrum) fEventCount = -1;
918 // extract the delta pt matrices
919 TString deltaptName("");
920 deltaptName += (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJ_%i", fCentralityBin) : Form("fHistDeltaPtDeltaPhi2_%i", fCentralityBin);
921 fDeltaPtDeltaPhi = ((TH2D*)fInputList->FindObject(deltaptName.Data()));
922 if(!fDeltaPtDeltaPhi) {
923 printf(" Couldn't find delta pt matrix %s ! \n", deltaptName.Data());
924 printf(" > may be ok, depending no what you want to do < \n");
925 fRefreshInput = kTRUE;
928 fDeltaPtDeltaPhi = ProtectHeap(fDeltaPtDeltaPhi, kFALSE);
929 // in plane delta pt distribution
930 if(!fDphiUnfolding) {
931 fDptInDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_in_%s", deltaptName.Data()), 1, 40, "e");
932 fDptOutDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_out_%s", deltaptName.Data()), 1, 40, "e");
934 fDptInDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_ina_%s", deltaptName.Data()), 1, 10, "e");
935 fDptInDist->Add(fDeltaPtDeltaPhi->ProjectionY(Form("_py_inb_%s", deltaptName.Data()), 31, 40, "e"));
936 // out of plane delta pt distribution
937 fDptOutDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_out_%s", deltaptName.Data()), 11, 30, "e");
938 fDptInDist = ProtectHeap(fDptInDist);
939 fDptOutDist = ProtectHeap(fDptOutDist);
940 // TODO get dpt response matrix from ConstructDPtResponseFromTH1D
943 // create a rec - true smeared response matrix
944 TMatrixD* rfIn = new TMatrixD(-50, 249, -50, 249);
945 for(Int_t j(-50); j < 250; j++) { // loop on pt true slices j
946 Bool_t skip = kFALSE;
947 for(Int_t k(-50); k < 250; k++) { // loop on pt gen slices k
948 (*rfIn)(k, j) = (skip) ? 0. : fDptInDist->GetBinContent(fDptInDist->GetXaxis()->FindBin(k-j));
949 if(fAvoidRoundingError && k > j && TMath::AreEqualAbs(fDptInDist->GetBinContent(fDptInDist->GetXaxis()->FindBin(k-j)), 0, 1e-8)) skip = kTRUE;
952 TMatrixD* rfOut = new TMatrixD(-50, 249, -50, 249);
953 for(Int_t j(-50); j < 250; j++) { // loop on pt true slices j
954 Bool_t skip = kFALSE;
955 for(Int_t k(-50); k < 250; k++) { // loop on pt gen slices k
956 (*rfOut)(k, j) = (skip) ? 0. : fDptOutDist->GetBinContent(fDptOutDist->GetXaxis()->FindBin(k-j));
957 if(fAvoidRoundingError && k > j && TMath::AreEqualAbs(fDptOutDist->GetBinContent(fDptOutDist->GetXaxis()->FindBin(k-j)), 0, 1e-8)) skip = kTRUE;
960 fDptIn = new TH2D(*rfIn);
961 fDptIn->SetNameTitle(Form("dpt_response_INPLANE_%i", fCentralityBin), Form("dpt_response_INPLANE_%i", fCentralityBin));
962 fDptIn->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
963 fDptIn->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
964 fDptIn = ProtectHeap(fDptIn);
965 fDptOut = new TH2D(*rfOut);
966 fDptOut->SetNameTitle(Form("dpt_response_OUTOFPLANE_%i", fCentralityBin), Form("dpt_response_OUTOFPLANE_%i", fCentralityBin));
967 fDptOut->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
968 fDptOut->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
969 fDptOut = ProtectHeap(fDptOut);
971 fRefreshInput = kTRUE; // force cloning of the input
974 //_____________________________________________________________________________
975 Bool_t AliJetFlowTools::PrepareForUnfolding(Int_t low, Int_t up) {
976 // prepare for unfoldingUA - more robust method to extract input spectra from file
977 // will replace PrepareForUnfolding eventually (09012014)
979 printf(" AliJetFlowTools::PrepareForUnfolding() fInputList not found \n - Set a list using AliJetFlowTools::SetInputList() \n");
982 if(!fDetectorResponse) printf(" WARNING, no detector response supplied ! May be ok (depending on what you want to do) \n ");
983 // check if the pt bin for true and rec have been set
984 if(!fBinsTrue || !fBinsRec) {
985 printf(" AliJetFlowTools::PrepareForUnfolding() no true or rec bins set, aborting ! \n");
989 // clear minuit state to avoid constraining the fit with the results of the previous iteration
990 for(Int_t i(0); i < fPower->GetNpar(); i++) fPower->SetParameter(i, 0.);
992 // extract the spectra
993 TString spectrumName(Form("fHistJetPsi2Pt_%i", fCentralityBin));
994 fJetPtDeltaPhi = ((TH2D*)fInputList->FindObject(spectrumName.Data()));
995 if(!fJetPtDeltaPhi) {
996 printf(" Couldn't find spectrum %s ! \n", spectrumName.Data());
999 fJetPtDeltaPhi = ProtectHeap(fJetPtDeltaPhi, kFALSE);
1000 // in plane spectrum
1001 fSpectrumIn = fJetPtDeltaPhi->ProjectionY(Form("_py_in_%s", spectrumName.Data()), low, up, "e");
1002 // extract the delta pt matrices
1003 TString deltaptName("");
1004 deltaptName += (fExLJDpt) ? Form("fHistDeltaPtDeltaPhi2ExLJ_%i", fCentralityBin) : Form("fHistDeltaPtDeltaPhi2_%i", fCentralityBin);
1005 fDeltaPtDeltaPhi = ((TH2D*)fInputList->FindObject(deltaptName.Data()));
1006 if(!fDeltaPtDeltaPhi) {
1007 printf(" Couldn't find delta pt matrix %s ! \n", deltaptName.Data());
1008 printf(" > may be ok, depending no what you want to do < \n");
1009 fRefreshInput = kTRUE;
1012 fDeltaPtDeltaPhi = ProtectHeap(fDeltaPtDeltaPhi, kFALSE);
1013 // in plane delta pt distribution
1014 fDptInDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_in_%s", deltaptName.Data()), low, up, "e");
1015 // create a rec - true smeared response matrix
1016 TMatrixD* rfIn = new TMatrixD(-50, 249, -50, 249);
1017 for(Int_t j(-50); j < 250; j++) { // loop on pt true slices j
1018 Bool_t skip = kFALSE;
1019 for(Int_t k(-50); k < 250; k++) { // loop on pt gen slices k
1020 (*rfIn)(k, j) = (skip) ? 0. : fDptInDist->GetBinContent(fDptInDist->GetXaxis()->FindBin(k-j));
1021 if(fAvoidRoundingError && k > j && TMath::AreEqualAbs(fDptInDist->GetBinContent(fDptInDist->GetXaxis()->FindBin(k-j)), 0, 1e-8)) skip = kTRUE;
1024 fDptIn = new TH2D(*rfIn);
1025 fDptIn->SetNameTitle(Form("dpt_response_INPLANE_%i", fCentralityBin), Form("dpt_response_INPLANE_%i", fCentralityBin));
1026 fDptIn->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
1027 fDptIn->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
1028 fDptIn = ProtectHeap(fDptIn);
1032 //_____________________________________________________________________________
1033 TH1D* AliJetFlowTools::GetPrior(
1034 const TH1D* measuredJetSpectrum, // jet pt in pt rec bins
1035 const TH2D* resizedResponse, // full response matrix, normalized in slides of pt true
1036 const TH1D* kinematicEfficiency, // kinematic efficiency
1037 const TH1D* measuredJetSpectrumTrueBins, // jet pt in pt true bins, also the prior when measured is chosen as prior
1038 const TString suffix, // suffix (in, out)
1039 const TH1D* jetFindingEfficiency) // jet finding efficiency (optional)
1041 // 1) get a prior for unfolding.
1042 // this can be either an unfolded spectrum from e.g. chi2 unfolding or the measured spectrum
1043 TH1D* unfolded(0x0);
1044 TDirectoryFile* dirOut = new TDirectoryFile(Form("Prior_%s___%s", suffix.Data(), fActiveString.Data()), Form("Prior_%s___%s", suffix.Data(), fActiveString.Data()));
1046 switch (fPrior) { // select the prior for unfolding
1048 if(fBinsTruePrior && fBinsRecPrior) { // if set, use different binning for the prior
1049 TArrayD* tempArrayTrue(fBinsTrue); // temporarily cache the original binning
1050 fBinsTrue = fBinsTruePrior; // switch binning schemes (will be used in UnfoldSpectrumChi2())
1051 TArrayD* tempArrayRec(fBinsRec);
1052 fBinsRec = fBinsRecPrior;
1053 TH1D* measuredJetSpectrumChi2 = RebinTH1D((!strcmp("in", suffix.Data())) ? fSpectrumIn : fSpectrumOut, fBinsRec, TString("resized_chi2"), kFALSE);
1054 TH1D* measuredJetSpectrumTrueBinsChi2 = RebinTH1D((!strcmp("in", suffix.Data())) ? fSpectrumIn : fSpectrumOut, fBinsTruePrior, TString("out"), kFALSE);
1055 TH2D* resizedResponseChi2(RebinTH2D((!strcmp("in", suffix.Data())) ? fFullResponseIn : fFullResponseOut,fBinsTruePrior, fBinsRec, TString("chi2")));
1056 TH1D* kinematicEfficiencyChi2(resizedResponseChi2->ProjectionX());
1057 kinematicEfficiencyChi2->SetNameTitle("kin_eff_chi2","kin_eff_chi2");
1058 for(Int_t i(0); i < kinematicEfficiencyChi2->GetXaxis()->GetNbins(); i++) kinematicEfficiencyChi2->SetBinError(1+i, 0.);
1059 unfolded= UnfoldSpectrumChi2(
1060 measuredJetSpectrumChi2,
1061 resizedResponseChi2,
1062 kinematicEfficiencyChi2,
1063 measuredJetSpectrumTrueBinsChi2, // prior for chi2 unfolding (measured)
1064 TString(Form("prior_%s", suffix.Data())));
1066 printf(" > GetPrior:: panic, couldn't get prior from Chi2 unfolding! \n");
1067 printf(" probably Chi2 unfolding did not converge < \n");
1070 fBinsTrue = tempArrayTrue; // reset bins borders
1071 fBinsRec = tempArrayRec;
1072 // if the chi2 prior has a different binning, rebin to the true binning for the unfolding
1073 unfolded = RebinTH1D(unfolded, fBinsTrue, TString(Form("unfoldedChi2Prior_%s", suffix.Data()))); // rebin unfolded
1075 unfolded = UnfoldSpectrumChi2(
1076 measuredJetSpectrum,
1078 kinematicEfficiency,
1079 measuredJetSpectrumTrueBins, // prior for chi2 unfolding (measured)
1080 TString(Form("prior_%s", suffix.Data())));
1082 printf(" > GetPrior:: panic, couldn't get prior from Chi2 unfolding! \n");
1083 printf(" probably Chi2 unfolding did not converge < \n");
1089 case kPriorMeasured : {
1090 unfolded = (TH1D*)measuredJetSpectrumTrueBins->Clone(Form("kPriorMeasured_%s", suffix.Data())); // copy template to unfolded to use as prior
1094 // it can be important that the prior is smooth, this can be achieved by
1095 // extrapolating the spectrum with a fitted power law when bins are sparsely filed
1096 if(jetFindingEfficiency) unfolded->Divide(jetFindingEfficiency);
1097 TH1D *priorLocal((TH1D*)unfolded->Clone(Form("priorUnfolded_%s", suffix.Data())));
1098 if(fSmoothenPrior) priorLocal = SmoothenPrior(priorLocal, fPower, fFitMin, fFitMax, fFitStart, kTRUE, fSmoothenCounts);
1101 //_____________________________________________________________________________
1102 TH1D* AliJetFlowTools::ResizeXaxisTH1D(TH1D* histo, Int_t low, Int_t up, TString suffix) {
1103 // resize the x-axis of a th1d
1105 printf(" > ResizeXaxisTH!D:: fatal error, NULL pointer passed < \n");
1108 // see how many bins we need to copy
1109 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);
1110 // low is the bin number of the first new bin
1111 Int_t l = histo->GetXaxis()->FindBin(low);
1113 Double_t _x(0), _xx(0);
1114 for(Int_t i(0); i < up-low; i++) {
1115 _x = histo->GetBinContent(l+i);
1116 _xx=histo->GetBinError(l+i);
1117 resized->SetBinContent(i+1, _x);
1118 resized->SetBinError(i+1, _xx);
1122 //_____________________________________________________________________________
1123 TH2D* AliJetFlowTools::ResizeYaxisTH2D(TH2D* histo, TArrayD* x, TArrayD* y, TString suffix) {
1124 // resize the y-axis of a th2d
1126 printf(" > ResizeYaxisTH2D:: fatal error, NULL pointer passed < \n");
1129 // see how many bins we need to copy
1130 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());
1131 // assume only the y-axis has changed
1132 // low is the bin number of the first new bin
1133 Int_t low = histo->GetYaxis()->FindBin(y->At(0));
1135 Double_t _x(0), _xx(0);
1136 for(Int_t i(0); i < x->GetSize(); i++) {
1137 for(Int_t j(0); j < y->GetSize(); j++) {
1138 _x = histo->GetBinContent(i, low+j);
1139 _xx=histo->GetBinError(i, low+1+j);
1140 resized->SetBinContent(i, j, _x);
1141 resized->SetBinError(i, j, _xx);
1146 //_____________________________________________________________________________
1147 TH2D* AliJetFlowTools::NormalizeTH2D(TH2D* histo, Bool_t noError) {
1148 // general method to normalize all vertical slices of a th2 to unity
1149 // i.e. get a probability matrix
1151 printf(" > NormalizeTH2D:: fatal error, NULL pointer passed < \n");
1154 Int_t binsX = histo->GetXaxis()->GetNbins();
1155 Int_t binsY = histo->GetYaxis()->GetNbins();
1157 // normalize all slices in x
1158 for(Int_t i(0); i < binsX; i++) { // for each vertical slice
1159 Double_t weight = 0;
1160 for(Int_t j(0); j < binsY; j++) { // loop over all the horizontal components
1161 weight+=histo->GetBinContent(i+1, j+1);
1162 } // now we know the total weight
1163 for(Int_t j(0); j < binsY; j++) {
1164 if (weight <= 0 ) continue;
1165 histo->SetBinContent(1+i, j+1, histo->GetBinContent(1+i, j+1)/weight);
1166 if(noError) histo->SetBinError( 1+i, j+1, 0.);
1167 else histo->SetBinError( 1+i, j+1, histo->GetBinError( 1+i, j+1)/weight);
1172 //_____________________________________________________________________________
1173 TH1D* AliJetFlowTools::RebinTH1D(TH1D* histo, TArrayD* bins, TString suffix, Bool_t kill) {
1174 // return a TH1D with the supplied histogram rebinned to the supplied bins
1175 // the returned histogram is new, the original is deleted from the heap if kill is true
1176 if(!histo || !bins) {
1177 printf(" > RebinTH1D:: fatal error, NULL pointer passed < \n");
1180 // create the output histo
1181 TString name = histo->GetName();
1184 TH1D* rebinned = new TH1D(name.Data(), name.Data(), bins->GetSize()-1, bins->GetArray());
1185 for(Int_t i(0); i < histo->GetXaxis()->GetNbins(); i++) {
1186 // loop over the bins of the old histo and fill the new one with its data
1187 rebinned->Fill(histo->GetBinCenter(i+1), histo->GetBinContent(i+1));
1189 if(kill) delete histo;
1192 //_____________________________________________________________________________
1193 TH2D* AliJetFlowTools::RebinTH2D(TH2D* rebinMe, TArrayD* binsTrue, TArrayD* binsRec, TString suffix) {
1194 // weighted rebinning of a th2d, implementation for function call to AliAnaChargedJetResponseMaker
1195 if(!fResponseMaker || !binsTrue || !binsRec) {
1196 printf(" > RebinTH2D:: function called with NULL arguments < \n");
1199 TString name(Form("%s_%s", rebinMe->GetName(), suffix.Data()));
1200 return (TH2D*)fResponseMaker->MakeResponseMatrixRebin(rebinMe, (TH2*)(new TH2D(name.Data(), name.Data(), binsTrue->GetSize()-1, binsTrue->GetArray(), binsRec->GetSize()-1, binsRec->GetArray())), kTRUE);
1202 //_____________________________________________________________________________
1203 TH2D* AliJetFlowTools::MatrixMultiplication(TH2D* a, TH2D* b, TString name)
1205 // multiply two matrices
1206 if (a->GetNbinsX() != b->GetNbinsY()) return 0x0;
1207 TH2D* c = (TH2D*)a->Clone("c");
1208 for (Int_t y1 = 1; y1 <= a->GetNbinsY(); y1++) {
1209 for (Int_t x2 = 1; x2 <= b->GetNbinsX(); x2++) {
1211 for (Int_t x1 = 1; x1 <= a->GetNbinsX(); x1++) {
1213 val += a->GetBinContent(x1, y1) * b->GetBinContent(x2, y2);
1215 c->SetBinContent(x2, y1, val);
1216 c->SetBinError(x2, y1, 0.);
1219 if(strcmp(name.Data(), "")) c->SetNameTitle(name.Data(), name.Data());
1222 //_____________________________________________________________________________
1223 TH1D* AliJetFlowTools::NormalizeTH1D(TH1D* histo, Double_t scale)
1225 // normalize a th1d to a certain scale
1227 Double_t integral = histo->Integral()*scale;
1228 if (integral > 0 && scale == 1.) histo->Scale(1./integral, "width");
1229 else if (scale != 1.) histo->Scale(1./scale, "width");
1230 else printf(" > Histogram integral < 0, cannot normalize \n");
1233 //_____________________________________________________________________________
1234 TMatrixD* AliJetFlowTools::CalculatePearsonCoefficients(TMatrixD* covarianceMatrix)
1236 // Calculate pearson coefficients from covariance matrix
1237 TMatrixD *pearsonCoefficients((TMatrixD*)covarianceMatrix->Clone("pearsonCoefficients"));
1238 Int_t nrows(covarianceMatrix->GetNrows()), ncols(covarianceMatrix->GetNcols());
1239 Double_t pearson(0.);
1240 if(nrows==0 && ncols==0) return 0x0;
1241 for(Int_t row = 0; row < nrows; row++) {
1242 for(Int_t col = 0; col<ncols; col++) {
1243 if((*covarianceMatrix)(row,row)!=0. && (*covarianceMatrix)(col,col)!=0.) pearson = (*covarianceMatrix)(row,col)/TMath::Sqrt((*covarianceMatrix)(row,row)*(*covarianceMatrix)(col,col));
1244 (*pearsonCoefficients)(row,col) = pearson;
1247 return pearsonCoefficients;
1249 //_____________________________________________________________________________
1250 TH1D* AliJetFlowTools::SmoothenPrior(TH1D* spectrum, TF1* function, Double_t min, Double_t max, Double_t start, Bool_t kill, Bool_t counts) {
1251 // smoothen the spectrum using a user defined function
1252 // returns a clone of the original spectrum if fitting failed
1253 // if kill is kTRUE the input spectrum will be deleted from the heap
1254 // if 'count' is selected, bins are filled with integers (necessary if the
1255 // histogram is interpreted in a routine which accepts only counts)
1256 if(!spectrum || !function) return 0x0;
1257 if(start > max) printf(" > cannot extrapolate fit beyond fit range ! < " );
1258 TH1D* temp = (TH1D*)spectrum->Clone(Form("%s_smoothened", spectrum->GetName()));
1259 temp->Sumw2(); // if already called on the original, this will give off a warning but do nothing
1260 TFitResultPtr r = temp->Fit(function, "", "", min, max);
1261 if((int)r == 0) { // MINUIT status
1262 for(Int_t i(0); i < temp->GetNbinsX() + 1; i++) {
1263 if(temp->GetBinCenter(i) > start) { // from this pt value use extrapolation
1264 (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));
1265 if(temp->GetBinContent(i) > 0) temp->SetBinError(i, TMath::Sqrt(temp->GetBinContent(i)));
1269 if(kill) delete spectrum;
1272 //_____________________________________________________________________________
1273 void AliJetFlowTools::Style(TCanvas* c, TString style)
1275 // set a default style for a canvas
1276 if(!strcmp(style.Data(), "PEARSON")) {
1277 printf(" > style PEARSON canvas < \n");
1278 gStyle->SetOptStat(0);
1283 } else if(!strcmp(style.Data(), "SPECTRUM")) {
1284 printf(" > style SPECTRUM canvas < \n");
1285 gStyle->SetOptStat(0);
1291 } else printf(" > Style called with unknown option %s \n returning < \n", style.Data());
1293 //_____________________________________________________________________________
1294 void AliJetFlowTools::Style(TVirtualPad* c, TString style)
1296 // set a default style for a canvas
1297 if(!strcmp(style.Data(), "PEARSON")) {
1298 printf(" > style PEARSON pad < \n");
1299 gStyle->SetOptStat(0);
1304 } else if(!strcmp(style.Data(), "SPECTRUM")) {
1305 printf(" > style SPECTRUM pad < \n");
1306 gStyle->SetOptStat(0);
1312 } else printf(" > Style called with unknown option %s \n returning < \n", style.Data());
1314 //_____________________________________________________________________________
1315 void AliJetFlowTools::Style(TLegend* l)
1317 // set a default style for a legend
1318 l->SetTextSize(.06);
1321 //_____________________________________________________________________________
1322 void AliJetFlowTools::Style(TH1* h, EColor col, histoType type)
1325 h->SetLineColor(col);
1326 h->SetMarkerColor(col);
1327 h->SetLineWidth(2.);
1328 h->SetMarkerSize(2.);
1329 h->SetTitleSize(0.06);
1330 h->GetYaxis()->SetLabelSize(0.06);
1331 h->GetXaxis()->SetLabelSize(0.06);
1332 h->GetYaxis()->SetTitleSize(0.06);
1333 h->GetXaxis()->SetTitleSize(0.06);
1334 h->GetYaxis()->SetTitleOffset(1.);
1335 h->GetXaxis()->SetTitleOffset(.9);
1337 case kInPlaneSpectrum : {
1338 h->SetTitle("IN PLANE");
1339 h->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
1340 h->GetYaxis()->SetTitle("counts");
1342 case kOutPlaneSpectrum : {
1343 h->SetTitle("OUT OF PLANE");
1344 h->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
1345 h->GetYaxis()->SetTitle("counts");
1347 case kUnfoldedSpectrum : {
1348 h->SetTitle("UNFOLDED");
1349 h->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
1350 h->GetYaxis()->SetTitle("counts");
1352 case kFoldedSpectrum : {
1353 h->SetTitle("FOLDED");
1354 h->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
1355 h->GetYaxis()->SetTitle("counts");
1357 case kMeasuredSpectrum : {
1358 h->SetTitle("MEASURED");
1359 h->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
1360 h->GetYaxis()->SetTitle("counts");
1365 //_____________________________________________________________________________
1366 void AliJetFlowTools::Style(TGraph* h, EColor col, histoType type)
1369 h->SetLineColor(col);
1370 h->SetMarkerColor(col);
1371 h->SetLineWidth(2.);
1372 h->SetMarkerSize(2.);
1373 h->GetYaxis()->SetLabelSize(0.06);
1374 h->GetXaxis()->SetLabelSize(0.06);
1375 h->GetYaxis()->SetTitleSize(0.06);
1376 h->GetXaxis()->SetTitleSize(0.06);
1377 h->GetYaxis()->SetTitleOffset(1.);
1378 h->GetXaxis()->SetTitleOffset(.9);
1380 case kInPlaneSpectrum : {
1381 h->SetTitle("IN PLANE");
1382 h->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
1383 h->GetYaxis()->SetTitle("counts");
1385 case kOutPlaneSpectrum : {
1386 h->SetTitle("OUT OF PLANE");
1387 h->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
1388 h->GetYaxis()->SetTitle("counts");
1390 case kUnfoldedSpectrum : {
1391 h->SetTitle("UNFOLDED");
1392 h->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
1393 h->GetYaxis()->SetTitle("counts");
1395 case kFoldedSpectrum : {
1396 h->SetTitle("FOLDED");
1397 h->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
1398 h->GetYaxis()->SetTitle("counts");
1400 case kMeasuredSpectrum : {
1401 h->SetTitle("MEASURED");
1402 h->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
1403 h->GetYaxis()->SetTitle("counts");
1408 //_____________________________________________________________________________
1409 void AliJetFlowTools::DoSystematics(Int_t nominalIn, Int_t nominalOut, TArrayI* variationsIn, TArrayI* variationsOut, Int_t columns, Float_t rangeLow, Float_t rangeUp, TString in, TString out) const
1411 // do systematics. structure of this function is similar to that of PostProcess, however
1412 // in this case a nomial index can be supplied as well as an array of systematic checks
1414 // FIXME make separate canvas for nominal value
1416 if(fOutputFile && !fOutputFile->IsZombie()) fOutputFile->Close();
1417 TFile readMe(in.Data(), "READ"); // open file read-only
1418 if(readMe.IsZombie()) {
1419 printf(" > Fatal error, couldn't read %s for post processing ! < \n", in.Data());
1422 printf("\n\n\n\t\t DOSYSTEMATICS \n > Recovered the following file structure : \n <");
1424 TList* listOfKeys((TList*)readMe.GetListOfKeys());
1426 printf(" > Fatal error, couldn't retrieve list of keys. Input file might have been corrupted ! < \n");
1429 // check input params
1430 if(variationsIn->GetSize() != variationsOut->GetSize()) {
1431 printf(" > DoSystematics: fatal error, input arrays have different sizes ! < \n ");
1434 TDirectoryFile* defRootDirIn(dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(nominalIn)->GetName())));
1435 TDirectoryFile* defRootDirOut(dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(nominalOut)->GetName())));
1436 if(!(defRootDirIn && defRootDirOut)) {
1437 printf(" > DoSystematics: fatal error, couldn't retrieve nominal values ! < \n ");
1440 TString defIn(defRootDirIn->GetName());
1441 TString defOut(defRootDirOut->GetName());
1442 // prepare necessary canvasses
1443 TCanvas* canvasIn(new TCanvas("SYSTPearsonIn", "SYSTPearsonIn"));
1444 TCanvas* canvasOut(0x0);
1445 if(fDphiUnfolding) canvasOut = new TCanvas("SYSTPearsonOut", "SYSTPearsonOut");
1446 TCanvas* canvasRatioMeasuredRefoldedIn(new TCanvas("SYSTRefoldedIn", "SYSTRefoldedIn"));
1447 TCanvas* canvasRatioMeasuredRefoldedOut(0x0);
1448 if(fDphiUnfolding) canvasRatioMeasuredRefoldedOut = new TCanvas("SYSTRefoldedOut", "SYSTRefoldedOut");
1449 TCanvas* canvasSpectraIn(new TCanvas("SYSTSpectraIn", "SYSTSpectraIn"));
1450 TCanvas* canvasSpectraOut(0x0);
1451 if(fDphiUnfolding) canvasSpectraOut = new TCanvas("SYSTSpectraOut", "SYSTSpectraOut");
1452 TCanvas* canvasRatio(0x0);
1453 if(fDphiUnfolding) canvasRatio = new TCanvas("SYSTRatio", "SYSTRatio");
1454 TCanvas* canvasV2(0x0);
1455 if(fDphiUnfolding) canvasV2 = new TCanvas("SYSTV2", "SYSTV2");
1456 TCanvas* canvasMISC(new TCanvas("SYSTMISC", "SYSTMISC"));
1457 TCanvas* canvasMasterIn(new TCanvas("SYSTdefaultIn", "SYSTdefaultIn"));
1458 TCanvas* canvasMasterOut(0x0);
1459 if(fDphiUnfolding) canvasMasterOut = new TCanvas("SYSTdefaultOut", "SYSTdefaultOut");
1460 (fDphiUnfolding) ? canvasMISC->Divide(4, 2) : canvasMISC->Divide(4, 1);
1462 TCanvas* canvasProfiles(new TCanvas("SYSTcanvasProfiles", "SYSTcanvasProfiles"));
1463 canvasProfiles->Divide(2);
1464 TProfile* ratioProfile(new TProfile("SYSTratioProfile", "SYSTratioProfile", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1465 TProfile* v2Profile(new TProfile("SYSTv2Profile", "SYSTv2Profile", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1466 // get an estimate of the number of outputs and find the default set
1467 Int_t rows(TMath::Floor(variationsIn->GetSize()/(float)columns)+((variationsIn->GetSize()%columns)>0));
1468 canvasIn->Divide(columns, rows);
1469 if(canvasOut) canvasOut->Divide(columns, rows);
1470 canvasRatioMeasuredRefoldedIn->Divide(columns, rows);
1471 if(canvasRatioMeasuredRefoldedOut) canvasRatioMeasuredRefoldedOut->Divide(columns, rows);
1472 canvasSpectraIn->Divide(columns, rows);
1473 if(canvasSpectraOut) canvasSpectraOut->Divide(columns, rows);
1474 if(canvasRatio) canvasRatio->Divide(columns, rows);
1475 if(canvasV2) canvasV2->Divide(columns, rows);
1476 canvasMasterIn->Divide(columns, rows);
1477 if(canvasMasterOut) canvasMasterOut->Divide(columns, rows);
1479 // prepare a separate set of canvases to hold the nominal points
1480 TCanvas* canvasNominalIn(new TCanvas("NominalPearsonIn", "NominalPearsonIn"));
1481 TCanvas* canvasNominalOut(0x0);
1482 if(fDphiUnfolding) canvasNominalOut = new TCanvas("NominalPearsonOut", "NominalPearsonOut");
1483 TCanvas* canvasNominalRatioMeasuredRefoldedIn(new TCanvas("NominalRefoldedIn", "NominalRefoldedIn"));
1484 TCanvas* canvasNominalRatioMeasuredRefoldedOut(0x0);
1485 if(fDphiUnfolding) canvasNominalRatioMeasuredRefoldedOut = new TCanvas("NominalRefoldedOut", "NominalRefoldedOut");
1486 TCanvas* canvasNominalSpectraIn(new TCanvas("NominalSpectraIn", "NominalSpectraIn"));
1487 TCanvas* canvasNominalSpectraOut(0x0);
1488 if(fDphiUnfolding) canvasNominalSpectraOut = new TCanvas("NominalSpectraOut", "NominalSpectraOut");
1489 TCanvas* canvasNominalRatio(0x0);
1490 if(fDphiUnfolding) canvasNominalRatio = new TCanvas("NominalRatio", "NominalRatio");
1491 TCanvas* canvasNominalV2(0x0);
1492 if(fDphiUnfolding) canvasNominalV2 = new TCanvas("NominalV2", "NominalV2");
1493 TCanvas* canvasNominalMISC(new TCanvas("NominalMISC", "NominalMISC"));
1494 TCanvas* canvasNominalMasterIn(new TCanvas("NominaldefaultIn", "NominaldefaultIn"));
1495 TCanvas* canvasNominalMasterOut(0x0);
1496 if(fDphiUnfolding) canvasNominalMasterOut = new TCanvas("NominaldefaultOut", "NominaldefaultOut");
1497 (fDphiUnfolding) ? canvasNominalMISC->Divide(4, 2) : canvasNominalMISC->Divide(4, 1);
1499 columns = 1; rows = 1;
1500 canvasNominalIn->Divide(columns, rows);
1501 if(canvasNominalOut) canvasNominalOut->Divide(columns, rows);
1502 canvasNominalRatioMeasuredRefoldedIn->Divide(columns, rows);
1503 if(canvasNominalRatioMeasuredRefoldedOut) canvasNominalRatioMeasuredRefoldedOut->Divide(columns, rows);
1504 canvasNominalSpectraIn->Divide(columns, rows);
1505 if(canvasNominalSpectraOut) canvasNominalSpectraOut->Divide(columns, rows);
1506 if(canvasNominalRatio) canvasNominalRatio->Divide(columns, rows);
1507 if(canvasNominalV2) canvasNominalV2->Divide(columns, rows);
1509 canvasNominalMasterIn->Divide(columns, rows);
1510 if(canvasNominalMasterOut) canvasNominalMasterOut->Divide(columns, rows);
1512 // extract the default output
1513 TH1D* defaultUnfoldedJetSpectrumIn(0x0);
1514 TH1D* defaultUnfoldedJetSpectrumOut(0x0);
1515 TDirectoryFile* defDirIn = (TDirectoryFile*)defRootDirIn->Get(Form("InPlane___%s", defIn.Data()));
1516 TDirectoryFile* defDirOut = (TDirectoryFile*)defRootDirOut->Get(Form("OutOfPlane___%s", defOut.Data()));
1517 if(defDirIn) defaultUnfoldedJetSpectrumIn = (TH1D*)defDirIn->Get(Form("UnfoldedSpectrum_in_%s", defIn.Data()));
1518 if(defDirOut) defaultUnfoldedJetSpectrumOut = (TH1D*)defDirOut->Get(Form("UnfoldedSpectrum_out_%s", defOut.Data()));
1519 printf(" > succesfully extracted default results < \n");
1521 // loop through the directories, only plot the graphs if the deconvolution converged
1522 TDirectoryFile* tempDirIn(0x0);
1523 TDirectoryFile* tempDirOut(0x0);
1524 TDirectoryFile* tempIn(0x0);
1525 TDirectoryFile* tempOut(0x0);
1526 TH1D* unfoldedSpectrumInForRatio(0x0);
1527 TH1D* unfoldedSpectrumOutForRatio(0x0);
1528 for(Int_t i(0), j(-1); i < variationsIn->GetSize(); i++) {
1529 tempDirIn = (dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(variationsIn->At(i))->GetName())));
1530 tempDirOut = (dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(variationsOut->At(i))->GetName())));
1531 if(!(tempDirIn && tempDirOut)) {
1532 printf(" > DoSystematics: couldn't get a set of variations < \n");
1535 TString dirNameIn(tempDirIn->GetName());
1536 TString dirNameOut(tempDirOut->GetName());
1537 // try to read the in- and out of plane subdirs
1538 tempIn = (TDirectoryFile*)tempDirIn->Get(Form("InPlane___%s", dirNameIn.Data()));
1539 tempOut = (TDirectoryFile*)tempDirOut->Get(Form("OutOfPlane___%s", dirNameOut.Data()));
1542 // to see if the unfolding converged try to extract the pearson coefficients
1543 TH2D* pIn((TH2D*)tempIn->Get(Form("PearsonCoefficients_in_%s", dirNameIn.Data())));
1545 printf(" - %s in plane converged \n", dirNameIn.Data());
1547 if(i==0) canvasNominalIn->cd(j);
1548 Style(gPad, "PEARSON");
1549 pIn->DrawCopy("colz");
1550 TGraphErrors* rIn((TGraphErrors*)tempIn->Get(Form("RatioRefoldedMeasured_%s", dirNameIn.Data())));
1553 printf(" > found RatioRefoldedMeasured < \n");
1554 canvasRatioMeasuredRefoldedIn->cd(j);
1555 if(i==0) canvasNominalRatioMeasuredRefoldedIn->cd(j);
1556 rIn->SetFillColor(kRed);
1559 TH1D* dvector((TH1D*)tempIn->Get("dVector"));
1560 TH1D* avalue((TH1D*)tempIn->Get("SingularValuesOfAC"));
1561 TH2D* rm((TH2D*)tempIn->Get(Form("ResponseMatrixIn_%s", dirNameIn.Data())));
1562 TH1D* eff((TH1D*)tempIn->Get(Form("KinematicEfficiencyIn_%s", dirNameIn.Data())));
1563 if(dvector && avalue && rm && eff) {
1569 if(i==0) canvasNominalMISC->cd(1);
1570 Style(gPad, "SPECTRUM");
1571 dvector->DrawCopy();
1573 if(i==0) canvasNominalMISC->cd(2);
1574 Style(gPad, "SPECTRUM");
1577 if(i==0) canvasNominalMISC->cd(3);
1578 Style(gPad, "PEARSON");
1579 rm->DrawCopy("colz");
1581 if(i==0) canvasNominalMISC->cd(4);
1583 } else if(rm && eff) {
1587 if(i==0) canvasNominalMISC->cd(3);
1588 Style(gPad, "PEARSON");
1589 rm->DrawCopy("colz");
1591 if(i==0) canvasNominalMISC->cd(4);
1595 TH1D* inputSpectrum((TH1D*)tempIn->Get(Form("InputSpectrum_in_%s", dirNameIn.Data())));
1596 TH1D* unfoldedSpectrum((TH1D*)tempIn->Get(Form("UnfoldedSpectrum_in_%s", dirNameIn.Data())));
1597 unfoldedSpectrumInForRatio = ProtectHeap(unfoldedSpectrum, kFALSE, TString("ForRatio"));
1598 TH1D* refoldedSpectrum((TH1D*)tempIn->Get(Form("RefoldedSpectrum_in_%s", dirNameIn.Data())));
1599 if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
1600 if(defaultUnfoldedJetSpectrumIn) {
1601 Style(defaultUnfoldedJetSpectrumIn, kBlue, kUnfoldedSpectrum);
1602 TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumIn->Clone(Form("defaultUnfoldedJetSpectrumIn_%s", dirNameIn.Data())));
1603 temp->Divide(unfoldedSpectrum);
1604 temp->SetTitle(Form("[%s] / [%s]", defIn.Data(), dirNameIn.Data()));
1605 temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
1606 temp->GetYaxis()->SetTitle("ratio");
1607 canvasMasterIn->cd(j);
1608 if(i==0) canvasNominalMasterIn->cd(j);
1609 temp->GetYaxis()->SetRangeUser(0., 2);
1612 TH1F* fitStatus((TH1F*)tempIn->Get(Form("fitStatus_%s_in", dirNameIn.Data())));
1613 canvasSpectraIn->cd(j);
1614 if(i==0) canvasNominalSpectraIn->cd(j);
1616 Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
1617 unfoldedSpectrum->DrawCopy();
1618 Style(inputSpectrum, kGreen, kMeasuredSpectrum);
1619 inputSpectrum->DrawCopy("same");
1620 Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
1621 refoldedSpectrum->DrawCopy("same");
1622 TLegend* l(AddLegend(gPad));
1624 if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
1625 Float_t chi(fitStatus->GetBinContent(1));
1626 Float_t pen(fitStatus->GetBinContent(2));
1627 Int_t dof((int)fitStatus->GetBinContent(3));
1628 Float_t beta(fitStatus->GetBinContent(4));
1629 l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
1630 } else if (fitStatus) { // only available in SVD fit
1631 Int_t reg((int)fitStatus->GetBinContent(1));
1632 l->AddEntry((TObject*)0, Form("REG %i", reg), "");
1637 TH2D* pOut((TH2D*)tempOut->Get(Form("PearsonCoefficients_out_%s", dirNameOut.Data())));
1639 printf(" - %s out of plane converged \n", dirNameOut.Data());
1641 if(i==0) canvasNominalOut->cd(j);
1642 Style(gPad, "PEARSON");
1643 pOut->DrawCopy("colz");
1644 TGraphErrors* rOut((TGraphErrors*)tempOut->Get(Form("RatioRefoldedMeasured_%s", dirNameOut.Data())));
1647 printf(" > found RatioRefoldedMeasured < \n");
1648 canvasRatioMeasuredRefoldedOut->cd(j);
1649 if(i==0) canvasNominalRatioMeasuredRefoldedOut->cd(j);
1650 rOut->SetFillColor(kRed);
1653 TH1D* dvector((TH1D*)tempOut->Get("dVector"));
1654 TH1D* avalue((TH1D*)tempOut->Get("SingularValuesOfAC"));
1655 TH2D* rm((TH2D*)tempOut->Get(Form("ResponseMatrixOut_%s", dirNameOut.Data())));
1656 TH1D* eff((TH1D*)tempOut->Get(Form("KinematicEfficiencyOut_%s", dirNameOut.Data())));
1657 if(dvector && avalue && rm && eff) {
1663 if(i==0) canvasNominalMISC->cd(5);
1664 Style(gPad, "SPECTRUM");
1665 dvector->DrawCopy();
1667 if(i==0) canvasNominalMISC->cd(6);
1668 Style(gPad, "SPECTRUM");
1671 if(i==0) canvasNominalMISC->cd(7);
1672 Style(gPad, "PEARSON");
1673 rm->DrawCopy("colz");
1675 if(i==0) canvasNominalMISC->cd(8);
1677 } else if(rm && eff) {
1681 if(i==0) canvasNominalMISC->cd(7);
1682 Style(gPad, "PEARSON");
1683 rm->DrawCopy("colz");
1685 if(i==0) canvasNominalMISC->cd(8);
1689 TH1D* inputSpectrum((TH1D*)tempOut->Get(Form("InputSpectrum_out_%s", dirNameOut.Data())));
1690 TH1D* unfoldedSpectrum((TH1D*)tempOut->Get(Form("UnfoldedSpectrum_out_%s", dirNameOut.Data())));
1691 unfoldedSpectrumOutForRatio = ProtectHeap(unfoldedSpectrum, kFALSE, TString("ForRatio"));
1692 TH1D* refoldedSpectrum((TH1D*)tempOut->Get(Form("RefoldedSpectrum_out_%s", dirNameOut.Data())));
1693 if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
1694 if(defaultUnfoldedJetSpectrumOut) {
1695 Style(defaultUnfoldedJetSpectrumOut, kBlue, kUnfoldedSpectrum);
1696 TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumOut->Clone(Form("defaultUnfoldedJetSpectrumOut_%s", dirNameOut.Data())));
1697 temp->Divide(unfoldedSpectrum);
1698 temp->SetTitle(Form("ratio nominal [%s] / [%s]", defOut.Data(), dirNameOut.Data()));
1699 temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
1700 temp->GetYaxis()->SetTitle("ratio");
1701 canvasMasterOut->cd(j);
1702 if(i==0) canvasNominalMasterOut->cd(j);
1703 temp->GetYaxis()->SetRangeUser(0., 2.);
1706 TH1F* fitStatus((TH1F*)tempOut->Get(Form("fitStatus_%s_out", dirNameOut.Data())));
1707 canvasSpectraOut->cd(j);
1708 if(i==0) canvasNominalSpectraOut->cd(j);
1710 Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
1711 unfoldedSpectrum->DrawCopy();
1712 Style(inputSpectrum, kGreen, kMeasuredSpectrum);
1713 inputSpectrum->DrawCopy("same");
1714 Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
1715 refoldedSpectrum->DrawCopy("same");
1716 TLegend* l(AddLegend(gPad));
1718 if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
1719 Float_t chi(fitStatus->GetBinContent(1));
1720 Float_t pen(fitStatus->GetBinContent(2));
1721 Int_t dof((int)fitStatus->GetBinContent(3));
1722 Float_t beta(fitStatus->GetBinContent(4));
1723 l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
1724 } else if (fitStatus) { // only available in SVD fit
1725 Int_t reg((int)fitStatus->GetBinContent(1));
1726 l->AddEntry((TObject*)0, Form("REG %i", reg), "");
1730 if(canvasRatio && canvasV2) {
1732 if(i==0) canvasNominalRatio->cd(j);
1733 TGraphErrors* ratioYield(GetRatio(unfoldedSpectrumInForRatio, unfoldedSpectrumOutForRatio, TString(Form("ratio [in=%s, out=%s]", dirNameIn.Data(), dirNameOut.Data()))));
1734 Double_t _tempx(0), _tempy(0);
1737 for(Int_t b(0); b < fBinsTrue->GetSize(); b++) {
1738 ratioYield->GetPoint(b+1, _tempx, _tempy);
1739 ratioProfile->Fill(_tempx, _tempy);
1741 ratioProfile->GetYaxis()->SetRangeUser(-0., 2.);
1742 ratioProfile->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
1743 ratioYield->GetYaxis()->SetRangeUser(-0., 2.);
1744 ratioYield->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
1745 ratioYield->SetFillColor(kRed);
1746 ratioYield->Draw("ap");
1749 if(i==0) canvasNominalV2->cd(j);
1750 TGraphErrors* ratioV2(GetV2(unfoldedSpectrumInForRatio,unfoldedSpectrumOutForRatio, .7, TString(Form("v_{2} [in=%s, out=%s]", dirNameIn.Data(), dirNameOut.Data()))));
1753 for(Int_t b(0); b < fBinsTrue->GetSize(); b++) {
1754 ratioV2->GetPoint(b+1, _tempx, _tempy);
1755 v2Profile->Fill(_tempx, _tempy);
1758 v2Profile->GetYaxis()->SetRangeUser(-0., 2.);
1759 v2Profile->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
1760 ratioV2->GetYaxis()->SetRangeUser(-.25, .75);
1761 ratioV2->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
1762 ratioV2->SetFillColor(kRed);
1763 ratioV2->Draw("ap");
1766 delete unfoldedSpectrumInForRatio;
1767 delete unfoldedSpectrumOutForRatio;
1769 TFile output(out.Data(), "RECREATE");
1770 // save the canvasses
1771 canvasProfiles->cd(1);
1772 Style(ratioProfile);
1773 ratioProfile->DrawCopy();
1774 canvasProfiles->cd(2);
1776 v2Profile->DrawCopy();
1777 SavePadToPDF(canvasProfiles);
1778 canvasProfiles->Write();
1779 SavePadToPDF(canvasIn);
1782 SavePadToPDF(canvasOut);
1785 SavePadToPDF(canvasRatioMeasuredRefoldedIn);
1786 canvasRatioMeasuredRefoldedIn->Write();
1787 if(canvasRatioMeasuredRefoldedOut) {
1788 SavePadToPDF(canvasRatioMeasuredRefoldedOut);
1789 canvasRatioMeasuredRefoldedOut->Write();
1791 SavePadToPDF(canvasSpectraIn);
1792 canvasSpectraIn->Write();
1793 if(canvasSpectraOut) {
1794 SavePadToPDF(canvasSpectraOut);
1795 canvasSpectraOut->Write();
1796 SavePadToPDF(canvasRatio);
1797 canvasRatio->Write();
1798 SavePadToPDF(canvasV2);
1801 SavePadToPDF(canvasMasterIn);
1802 canvasMasterIn->Write();
1803 if(canvasMasterOut) {
1804 SavePadToPDF(canvasMasterOut);
1805 canvasMasterOut->Write();
1807 SavePadToPDF(canvasMISC);
1808 canvasMISC->Write();
1809 // save the nomial canvasses
1810 SavePadToPDF(canvasNominalIn);
1811 canvasNominalIn->Write();
1812 if(canvasNominalOut) {
1813 SavePadToPDF(canvasNominalOut);
1814 canvasNominalOut->Write();
1816 SavePadToPDF(canvasNominalRatioMeasuredRefoldedIn);
1817 canvasNominalRatioMeasuredRefoldedIn->Write();
1818 if(canvasNominalRatioMeasuredRefoldedOut) {
1819 SavePadToPDF(canvasNominalRatioMeasuredRefoldedOut);
1820 canvasNominalRatioMeasuredRefoldedOut->Write();
1822 SavePadToPDF(canvasNominalSpectraIn);
1823 canvasNominalSpectraIn->Write();
1824 if(canvasNominalSpectraOut) {
1825 SavePadToPDF(canvasNominalSpectraOut);
1826 canvasNominalSpectraOut->Write();
1827 SavePadToPDF(canvasNominalRatio);
1828 canvasNominalRatio->Write();
1829 SavePadToPDF(canvasNominalV2);
1830 canvasNominalV2->Write();
1832 SavePadToPDF(canvasNominalMasterIn);
1833 canvasNominalMasterIn->Write();
1834 if(canvasNominalMasterOut) {
1835 SavePadToPDF(canvasNominalMasterOut);
1836 canvasNominalMasterOut->Write();
1838 SavePadToPDF(canvasNominalMISC);
1839 canvasNominalMISC->Write();
1844 //_____________________________________________________________________________
1845 void AliJetFlowTools::PostProcess(TString def, Int_t columns, Float_t rangeLow, Float_t rangeUp, TString in, TString out) const
1847 // go through the output file and perform post processing routines
1848 // can either be performed in one go with the unfolding, or at a later stage
1849 if(fOutputFile && !fOutputFile->IsZombie()) fOutputFile->Close();
1850 TFile readMe(in.Data(), "READ"); // open file read-only
1851 if(readMe.IsZombie()) {
1852 printf(" > Fatal error, couldn't read %s for post processing ! < \n", in.Data());
1855 printf("\n\n\n\t\t POSTPROCESSING \n > Recovered the following file structure : \n <");
1857 TList* listOfKeys((TList*)readMe.GetListOfKeys());
1859 printf(" > Fatal error, couldn't retrieve list of keys. Input file might have been corrupted ! < \n");
1862 // prepare necessary canvasses
1863 TCanvas* canvasIn(new TCanvas("PearsonIn", "PearsonIn"));
1864 TCanvas* canvasOut(0x0);
1865 if(fDphiUnfolding) canvasOut = new TCanvas("PearsonOut", "PearsonOut");
1866 TCanvas* canvasRatioMeasuredRefoldedIn(new TCanvas("RefoldedIn", "RefoldedIn"));
1867 TCanvas* canvasRatioMeasuredRefoldedOut(0x0);
1868 if(fDphiUnfolding) canvasRatioMeasuredRefoldedOut = new TCanvas("RefoldedOut", "RefoldedOut");
1869 TCanvas* canvasSpectraIn(new TCanvas("SpectraIn", "SpectraIn"));
1870 TCanvas* canvasSpectraOut(0x0);
1871 if(fDphiUnfolding) canvasSpectraOut = new TCanvas("SpectraOut", "SpectraOut");
1872 TCanvas* canvasRatio(0x0);
1873 if(fDphiUnfolding) canvasRatio = new TCanvas("Ratio", "Ratio");
1874 TCanvas* canvasV2(0x0);
1875 if(fDphiUnfolding) canvasV2 = new TCanvas("V2", "V2");
1876 TCanvas* canvasMISC(new TCanvas("MISC", "MISC"));
1877 TCanvas* canvasMasterIn(new TCanvas("defaultIn", "defaultIn"));
1878 TCanvas* canvasMasterOut(0x0);
1879 if(fDphiUnfolding) canvasMasterOut = new TCanvas("defaultOut", "defaultOut");
1880 (fDphiUnfolding) ? canvasMISC->Divide(4, 2) : canvasMISC->Divide(4, 1);
1881 TDirectoryFile* defDir(0x0);
1882 TCanvas* canvasProfiles(new TCanvas("canvasProfiles", "canvasProfiles"));
1883 canvasProfiles->Divide(2);
1884 TProfile* ratioProfile(new TProfile("ratioProfile", "ratioProfile", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1885 TProfile* v2Profile(new TProfile("v2Profile", "v2Profile", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
1886 // get an estimate of the number of outputs and find the default set
1888 for(Int_t i(0); i < listOfKeys->GetSize(); i++) {
1889 if(dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()))) {
1890 if(!strcmp(listOfKeys->At(i)->GetName(), def.Data())) defDir = dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()));
1894 Int_t rows(TMath::Floor(cacheMe/(float)columns)+((cacheMe%columns)>0));
1895 canvasIn->Divide(columns, rows);
1896 if(canvasOut) canvasOut->Divide(columns, rows);
1897 canvasRatioMeasuredRefoldedIn->Divide(columns, rows);
1898 if(canvasRatioMeasuredRefoldedOut) canvasRatioMeasuredRefoldedOut->Divide(columns, rows);
1899 canvasSpectraIn->Divide(columns, rows);
1900 if(canvasSpectraOut) canvasSpectraOut->Divide(columns, rows);
1901 if(canvasRatio) canvasRatio->Divide(columns, rows);
1902 if(canvasV2) canvasV2->Divide(columns, rows);
1904 canvasMasterIn->Divide(columns, rows);
1905 if(canvasMasterOut) canvasMasterOut->Divide(columns, rows);
1906 // extract the default output
1907 TH1D* defaultUnfoldedJetSpectrumIn(0x0);
1908 TH1D* defaultUnfoldedJetSpectrumOut(0x0);
1910 TDirectoryFile* defDirIn = (TDirectoryFile*)defDir->Get(Form("InPlane___%s", def.Data()));
1911 TDirectoryFile* defDirOut = (TDirectoryFile*)defDir->Get(Form("OutOfPlane___%s", def.Data()));
1912 if(defDirIn) defaultUnfoldedJetSpectrumIn = (TH1D*)defDirIn->Get(Form("UnfoldedSpectrum_in_%s", def.Data()));
1913 if(defDirOut) defaultUnfoldedJetSpectrumOut = (TH1D*)defDirOut->Get(Form("UnfoldedSpectrum_out_%s", def.Data()));
1914 printf(" > succesfully extracted default results < \n");
1917 // loop through the directories, only plot the graphs if the deconvolution converged
1918 TDirectoryFile* tempDir(0x0);
1919 TDirectoryFile* tempIn(0x0);
1920 TDirectoryFile* tempOut(0x0);
1921 for(Int_t i(0), j(0); i < listOfKeys->GetSize(); i++) {
1922 // read the directory by its name
1923 tempDir = dynamic_cast<TDirectoryFile*>(readMe.Get(listOfKeys->At(i)->GetName()));
1924 if(!tempDir) continue;
1925 TString dirName(tempDir->GetName());
1926 // try to read the in- and out of plane subdirs
1927 tempIn = (TDirectoryFile*)tempDir->Get(Form("InPlane___%s", dirName.Data()));
1928 tempOut = (TDirectoryFile*)tempDir->Get(Form("OutOfPlane___%s", dirName.Data()));
1930 if(!tempIn) { // attempt to get MakeAU output
1931 TString stringArray[] = {"a", "b", "c", "d", "e", "f", "g", "h"};
1932 TCanvas* tempPearson(new TCanvas(Form("pearson_%s", dirName.Data()), Form("pearson_%s", dirName.Data())));
1933 tempPearson->Divide(4,2);
1934 TCanvas* tempRatio(new TCanvas(Form("ratio_%s", dirName.Data()), Form("ratio_%s", dirName.Data())));
1935 tempRatio->Divide(4,2);
1936 TCanvas* tempResult(new TCanvas(Form("result_%s", dirName.Data()), Form("result_%s", dirName.Data())));
1937 tempResult->Divide(4,2);
1938 for(Int_t q(0); q < 8; q++) {
1939 tempIn = (TDirectoryFile*)tempDir->Get(Form("%s___%s", stringArray[q].Data(), dirName.Data()));
1941 // to see if the unfolding converged try to extract the pearson coefficients
1942 TH2D* pIn((TH2D*)tempIn->Get(Form("PearsonCoefficients_in_%s", dirName.Data())));
1944 printf(" - %s in plane converged \n", dirName.Data());
1945 tempPearson->cd(1+q);
1946 Style(gPad, "PEARSON");
1947 pIn->DrawCopy("colz");
1948 TGraphErrors* rIn((TGraphErrors*)tempIn->Get(Form("RatioRefoldedMeasured_%s", dirName.Data())));
1951 printf(" > found RatioRefoldedMeasured < \n");
1953 rIn->SetFillColor(kRed);
1956 TH1D* dvector((TH1D*)tempIn->Get("dVector"));
1957 TH1D* avalue((TH1D*)tempIn->Get("SingularValuesOfAC"));
1958 TH2D* rm((TH2D*)tempIn->Get(Form("ResponseMatrixIn_%s", dirName.Data())));
1959 TH1D* eff((TH1D*)tempIn->Get(Form("KinematicEfficiencyIn_%s", dirName.Data())));
1960 if(dvector && avalue && rm && eff) {
1966 Style(gPad, "SPECTRUM");
1967 dvector->DrawCopy();
1969 Style(gPad, "SPECTRUM");
1972 Style(gPad, "PEARSON");
1973 rm->DrawCopy("colz");
1976 } else if(rm && eff) {
1980 Style(gPad, "PEARSON");
1981 rm->DrawCopy("colz");
1986 TH1D* inputSpectrum((TH1D*)tempIn->Get(Form("InputSpectrum_in_%s", dirName.Data())));
1987 TH1D* unfoldedSpectrum((TH1D*)tempIn->Get(Form("UnfoldedSpectrum_in_%s", dirName.Data())));
1988 TH1D* refoldedSpectrum((TH1D*)tempIn->Get(Form("RefoldedSpectrum_in_%s", dirName.Data())));
1989 if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
1990 if(defaultUnfoldedJetSpectrumIn) {
1991 Style(defaultUnfoldedJetSpectrumIn, kBlue, kUnfoldedSpectrum);
1992 TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumIn->Clone(Form("defaultUnfoldedJetSpectrumIn_%s", dirName.Data())));
1993 temp->Divide(unfoldedSpectrum);
1994 temp->SetTitle(Form("ratio default unfolded / %s", dirName.Data()));
1995 temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
1996 temp->GetYaxis()->SetTitle(Form("%s / %s", def.Data(), dirName.Data()));
1997 canvasMasterIn->cd(j);
1998 temp->GetYaxis()->SetRangeUser(0., 2);
2001 TH1F* fitStatus((TH1F*)tempIn->Get(Form("fitStatus_%s_in", dirName.Data())));
2002 tempResult->cd(q+1);
2004 Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
2005 unfoldedSpectrum->DrawCopy();
2006 Style(inputSpectrum, kGreen, kMeasuredSpectrum);
2007 inputSpectrum->DrawCopy("same");
2008 Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
2009 refoldedSpectrum->DrawCopy("same");
2010 TLegend* l(AddLegend(gPad));
2012 if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
2013 Float_t chi(fitStatus->GetBinContent(1));
2014 Float_t pen(fitStatus->GetBinContent(2));
2015 Int_t dof((int)fitStatus->GetBinContent(3));
2016 Float_t beta(fitStatus->GetBinContent(4));
2017 l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
2018 } else if (fitStatus) { // only available in SVD fit
2019 Int_t reg((int)fitStatus->GetBinContent(1));
2020 l->AddEntry((TObject*)0, Form("REG %i", reg), "");
2027 // to see if the unfolding converged try to extract the pearson coefficients
2028 TH2D* pIn((TH2D*)tempIn->Get(Form("PearsonCoefficients_in_%s", dirName.Data())));
2030 printf(" - %s in plane converged \n", dirName.Data());
2032 Style(gPad, "PEARSON");
2033 pIn->DrawCopy("colz");
2034 TGraphErrors* rIn((TGraphErrors*)tempIn->Get(Form("RatioRefoldedMeasured_%s", dirName.Data())));
2037 printf(" > found RatioRefoldedMeasured < \n");
2038 canvasRatioMeasuredRefoldedIn->cd(j);
2039 rIn->SetFillColor(kRed);
2042 TH1D* dvector((TH1D*)tempIn->Get("dVector"));
2043 TH1D* avalue((TH1D*)tempIn->Get("SingularValuesOfAC"));
2044 TH2D* rm((TH2D*)tempIn->Get(Form("ResponseMatrixIn_%s", dirName.Data())));
2045 TH1D* eff((TH1D*)tempIn->Get(Form("KinematicEfficiencyIn_%s", dirName.Data())));
2046 if(dvector && avalue && rm && eff) {
2052 Style(gPad, "SPECTRUM");
2053 dvector->DrawCopy();
2055 Style(gPad, "SPECTRUM");
2058 Style(gPad, "PEARSON");
2059 rm->DrawCopy("colz");
2062 } else if(rm && eff) {
2066 Style(gPad, "PEARSON");
2067 rm->DrawCopy("colz");
2072 TH1D* inputSpectrum((TH1D*)tempIn->Get(Form("InputSpectrum_in_%s", dirName.Data())));
2073 TH1D* unfoldedSpectrum((TH1D*)tempIn->Get(Form("UnfoldedSpectrum_in_%s", dirName.Data())));
2074 TH1D* refoldedSpectrum((TH1D*)tempIn->Get(Form("RefoldedSpectrum_in_%s", dirName.Data())));
2075 if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
2076 if(defaultUnfoldedJetSpectrumIn) {
2077 Style(defaultUnfoldedJetSpectrumIn, kBlue, kUnfoldedSpectrum);
2078 TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumIn->Clone(Form("defaultUnfoldedJetSpectrumIn_%s", dirName.Data())));
2079 temp->Divide(unfoldedSpectrum);
2080 temp->SetTitle(Form("ratio default unfolded / %s", dirName.Data()));
2081 temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
2082 temp->GetYaxis()->SetTitle(Form("%s / %s", def.Data(), dirName.Data()));
2083 canvasMasterIn->cd(j);
2084 temp->GetYaxis()->SetRangeUser(0., 2);
2087 TH1F* fitStatus((TH1F*)tempIn->Get(Form("fitStatus_%s_in", dirName.Data())));
2088 canvasSpectraIn->cd(j);
2090 Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
2091 unfoldedSpectrum->DrawCopy();
2092 Style(inputSpectrum, kGreen, kMeasuredSpectrum);
2093 inputSpectrum->DrawCopy("same");
2094 Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
2095 refoldedSpectrum->DrawCopy("same");
2096 TLegend* l(AddLegend(gPad));
2098 if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
2099 Float_t chi(fitStatus->GetBinContent(1));
2100 Float_t pen(fitStatus->GetBinContent(2));
2101 Int_t dof((int)fitStatus->GetBinContent(3));
2102 Float_t beta(fitStatus->GetBinContent(4));
2103 l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
2104 } else if (fitStatus) { // only available in SVD fit
2105 Int_t reg((int)fitStatus->GetBinContent(1));
2106 l->AddEntry((TObject*)0, Form("REG %i", reg), "");
2111 TH2D* pOut((TH2D*)tempOut->Get(Form("PearsonCoefficients_out_%s", dirName.Data())));
2113 printf(" - %s out of plane converged \n", dirName.Data());
2115 Style(gPad, "PEARSON");
2116 pOut->DrawCopy("colz");
2117 TGraphErrors* rOut((TGraphErrors*)tempOut->Get(Form("RatioRefoldedMeasured_%s", dirName.Data())));
2120 printf(" > found RatioRefoldedMeasured < \n");
2121 canvasRatioMeasuredRefoldedOut->cd(j);
2122 rOut->SetFillColor(kRed);
2125 TH1D* dvector((TH1D*)tempOut->Get("dVector"));
2126 TH1D* avalue((TH1D*)tempOut->Get("SingularValuesOfAC"));
2127 TH2D* rm((TH2D*)tempOut->Get(Form("ResponseMatrixOut_%s", dirName.Data())));
2128 TH1D* eff((TH1D*)tempOut->Get(Form("KinematicEfficiencyOut_%s", dirName.Data())));
2129 if(dvector && avalue && rm && eff) {
2135 Style(gPad, "SPECTRUM");
2136 dvector->DrawCopy();
2138 Style(gPad, "SPECTRUM");
2141 Style(gPad, "PEARSON");
2142 rm->DrawCopy("colz");
2145 } else if(rm && eff) {
2149 Style(gPad, "PEARSON");
2150 rm->DrawCopy("colz");
2155 TH1D* inputSpectrum((TH1D*)tempOut->Get(Form("InputSpectrum_out_%s", dirName.Data())));
2156 TH1D* unfoldedSpectrum((TH1D*)tempOut->Get(Form("UnfoldedSpectrum_out_%s", dirName.Data())));
2157 TH1D* refoldedSpectrum((TH1D*)tempOut->Get(Form("RefoldedSpectrum_out_%s", dirName.Data())));
2158 if(inputSpectrum && unfoldedSpectrum && refoldedSpectrum) {
2159 if(defaultUnfoldedJetSpectrumOut) {
2160 Style(defaultUnfoldedJetSpectrumOut, kBlue, kUnfoldedSpectrum);
2161 TH1D* temp((TH1D*)defaultUnfoldedJetSpectrumOut->Clone(Form("defaultUnfoldedJetSpectrumOut_%s", dirName.Data())));
2162 temp->Divide(unfoldedSpectrum);
2163 temp->SetTitle(Form("ratio default unfolded / %s", dirName.Data()));
2164 temp->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
2165 temp->GetYaxis()->SetTitle(Form("%s / %s", def.Data(), dirName.Data()));
2166 canvasMasterOut->cd(j);
2167 temp->GetYaxis()->SetRangeUser(0., 2.);
2170 TH1F* fitStatus((TH1F*)tempOut->Get(Form("fitStatus_%s_out", dirName.Data())));
2171 canvasSpectraOut->cd(j);
2173 Style(unfoldedSpectrum, kRed, kUnfoldedSpectrum);
2174 unfoldedSpectrum->DrawCopy();
2175 Style(inputSpectrum, kGreen, kMeasuredSpectrum);
2176 inputSpectrum->DrawCopy("same");
2177 Style(refoldedSpectrum, kBlue, kFoldedSpectrum);
2178 refoldedSpectrum->DrawCopy("same");
2179 TLegend* l(AddLegend(gPad));
2181 if(fitStatus && fitStatus->GetNbinsX() == 4) { // only available in chi2 fit
2182 Float_t chi(fitStatus->GetBinContent(1));
2183 Float_t pen(fitStatus->GetBinContent(2));
2184 Int_t dof((int)fitStatus->GetBinContent(3));
2185 Float_t beta(fitStatus->GetBinContent(4));
2186 l->AddEntry((TObject*)0, Form("#chi %.2f \tP %.2f \tDOF %i, #beta %.2f", chi, pen, dof, beta), "");
2187 } else if (fitStatus) { // only available in SVD fit
2188 Int_t reg((int)fitStatus->GetBinContent(1));
2189 l->AddEntry((TObject*)0, Form("REG %i", reg), "");
2193 if(canvasRatio && canvasV2) {
2195 TGraphErrors* ratioYield((TGraphErrors*)tempDir->Get(Form("RatioInOutPlane_%s", dirName.Data())));
2196 Double_t _tempx(0), _tempy(0);
2199 for(Int_t b(0); b < fBinsTrue->GetSize(); b++) {
2200 ratioYield->GetPoint(b+1, _tempx, _tempy);
2201 ratioProfile->Fill(_tempx, _tempy);
2203 ratioProfile->GetYaxis()->SetRangeUser(-0., 2.);
2204 ratioProfile->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2205 ratioYield->GetYaxis()->SetRangeUser(-0., 2.);
2206 ratioYield->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2207 ratioYield->SetFillColor(kRed);
2208 ratioYield->Draw("ap");
2211 TGraphErrors* ratioV2((TGraphErrors*)tempDir->Get(Form("v2_%s", dirName.Data())));
2214 for(Int_t b(0); b < fBinsTrue->GetSize(); b++) {
2215 ratioV2->GetPoint(b+1, _tempx, _tempy);
2216 v2Profile->Fill(_tempx, _tempy);
2219 v2Profile->GetYaxis()->SetRangeUser(-0., 2.);
2220 v2Profile->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2221 ratioV2->GetYaxis()->SetRangeUser(-.25, .75);
2222 ratioV2->GetXaxis()->SetRangeUser(rangeLow, rangeUp);
2223 ratioV2->SetFillColor(kRed);
2224 ratioV2->Draw("ap");
2228 TFile output(out.Data(), "RECREATE");
2229 canvasProfiles->cd(1);
2230 Style(ratioProfile);
2231 ratioProfile->DrawCopy();
2232 canvasProfiles->cd(2);
2234 v2Profile->DrawCopy();
2235 SavePadToPDF(canvasProfiles);
2236 canvasProfiles->Write();
2237 SavePadToPDF(canvasIn);
2240 SavePadToPDF(canvasOut);
2243 SavePadToPDF(canvasRatioMeasuredRefoldedIn);
2244 canvasRatioMeasuredRefoldedIn->Write();
2245 if(canvasRatioMeasuredRefoldedOut) {
2246 SavePadToPDF(canvasRatioMeasuredRefoldedOut);
2247 canvasRatioMeasuredRefoldedOut->Write();
2249 SavePadToPDF(canvasSpectraIn);
2250 canvasSpectraIn->Write();
2251 if(canvasSpectraOut) {
2252 SavePadToPDF(canvasSpectraOut);
2253 canvasSpectraOut->Write();
2254 SavePadToPDF(canvasRatio);
2255 canvasRatio->Write();
2256 SavePadToPDF(canvasV2);
2259 SavePadToPDF(canvasMasterIn);
2260 canvasMasterIn->Write();
2261 if(canvasMasterOut) {
2262 SavePadToPDF(canvasMasterOut);
2263 canvasMasterOut->Write();
2265 SavePadToPDF(canvasMISC);
2266 canvasMISC->Write();
2270 //_____________________________________________________________________________
2271 Bool_t AliJetFlowTools::SetRawInput (
2272 TH2D* detectorResponse, // detector response matrix
2273 TH1D* jetPtIn, // in plane jet spectrum
2274 TH1D* jetPtOut, // out of plane jet spectrum
2275 TH1D* dptIn, // in plane delta pt distribution
2276 TH1D* dptOut, // out of plane delta pt distribution
2278 // set input histograms manually
2279 fDetectorResponse = detectorResponse;
2280 fSpectrumIn = jetPtIn;
2281 fSpectrumOut = jetPtOut;
2283 fDptOutDist = dptOut;
2284 fRawInputProvided = kTRUE;
2285 // check if all data is provided
2286 if(!fDetectorResponse) {
2287 printf(" fDetectorResponse not found \n ");
2290 // check if the pt bin for true and rec have been set
2291 if(!fBinsTrue || !fBinsRec) {
2292 printf(" No true or rec bins set, please set binning ! \n");
2295 if(!fRMSSpectrumIn) { // initialie the profiles which will hold the RMS values. if binning changes in between unfolding
2296 // procedures, these profiles will be nonsensical, user is responsible
2297 fRMSSpectrumIn = new TProfile("fRMSSpectrumIn", "fRMSSpectrumIn", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2298 fRMSSpectrumOut = new TProfile("fRMSSpectrumOut", "fRMSSpectrumOut", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2299 fRMSRatio = new TProfile("fRMSRatio", "fRMSRatio", fBinsTrue->GetSize()-1, fBinsTrue->GetArray());
2301 // normalize spectra to event count if requested
2302 if(fNormalizeSpectra) {
2303 fEventCount = eventCount;
2304 if(fEventCount > 0) {
2305 fSpectrumIn->Sumw2(); // necessary for correct error propagation of scale
2306 fSpectrumOut->Sumw2();
2307 fSpectrumIn->Scale(1./((double)fEventCount));
2308 fSpectrumOut->Scale(1./((double)fEventCount));
2311 if(!fNormalizeSpectra && fEventCount > 0) {
2312 fSpectrumIn->Sumw2(); // necessary for correct error propagation of scale
2313 fSpectrumOut->Sumw2();
2314 fSpectrumIn->Scale(1./((double)fEventCount));
2315 fSpectrumOut->Scale(1./((double)fEventCount));
2317 fDptIn = ConstructDPtResponseFromTH1D(fDptInDist, fAvoidRoundingError);
2318 fDptIn->SetNameTitle(Form("dpt_response_INPLANE_%i", fCentralityBin), Form("dpt_response_INPLANE_%i", fCentralityBin));
2319 fDptIn->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
2320 fDptIn->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
2321 fDptOut = ConstructDPtResponseFromTH1D(fDptOutDist, fAvoidRoundingError);
2322 fDptOut->SetNameTitle(Form("dpt_response_OUTOFPLANE_%i", fCentralityBin), Form("dpt_response_OUTOFPLANE_%i", fCentralityBin));
2323 fDptOut->GetXaxis()->SetTitle("p_{T, jet}^{gen} [GeV/c]");
2324 fDptOut->GetYaxis()->SetTitle("p_{T, jet}^{rec} [GeV/c]");
2328 //_____________________________________________________________________________
2329 TGraphErrors* AliJetFlowTools::GetRatio(TH1 *h1, TH1* h2, TString name, Bool_t appendFit, Int_t xmax)
2331 // return ratio of h1 / h2
2332 // histograms can have different binning. errors are propagated as uncorrelated
2334 printf(" GetRatio called with NULL argument(s) \n ");
2338 TGraphErrors *gr = new TGraphErrors();
2339 gr->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
2340 Double_t binCent(0.), ratio(0.), error2(0.), binWidth(0.);
2341 TH1* dud((TH1*)h1->Clone("dud"));
2345 if(!dud->Divide(h1, h2)) {
2346 printf(" > ROOT failed to divide two histogams, dividing manually \n < ");
2347 for(Int_t i(1); i <= h1->GetNbinsX(); i++) {
2348 binCent = h1->GetXaxis()->GetBinCenter(i);
2349 if(xmax > 0. && binCent > xmax) continue;
2350 j = h2->FindBin(binCent);
2351 binWidth = h1->GetXaxis()->GetBinWidth(i);
2352 if(h2->GetBinContent(j) > 0.) {
2353 ratio = h1->GetBinContent(i)/h2->GetBinContent(j);
2354 /* original propagation of uncertainty changed 08012014
2355 Double_t A = 1./h2->GetBinContent(j)*h1->GetBinError(i);
2357 if(h2->GetBinError(j)>0.) {
2358 B = -1.*h1->GetBinContent(i)/(h2->GetBinContent(j)*h2->GetBinContent(j))*h2->GetBinError(j);
2360 } else error2 = A*A; */
2361 Double_t A = h1->GetBinError(i)/h1->GetBinContent(i);
2362 Double_t B = h2->GetBinError(i)/h2->GetBinContent(i);
2363 error2 = ratio*ratio*A*A+ratio*ratio*B*B;
2364 if(error2 > 0 ) error2 = TMath::Sqrt(error2);
2365 gr->SetPoint(gr->GetN(), binCent, ratio);
2366 gr->SetPointError(gr->GetN()-1, 0.5*binWidth, error2);
2370 printf( " > using ROOT to divide two histograms < \n");
2371 for(Int_t i(1); i <= h1->GetNbinsX(); i++) {
2372 binCent = dud->GetXaxis()->GetBinCenter(i);
2373 if(xmax > 0. && binCent > xmax) continue;
2374 binWidth = dud->GetXaxis()->GetBinWidth(i);
2375 gr->SetPoint(gr->GetN(),binCent,dud->GetBinContent(i));
2376 gr->SetPointError(gr->GetN()-1,0.5*binWidth,dud->GetBinError(i));
2381 TF1* fit(new TF1("lin", "pol0", 10, 100));
2384 if(strcmp(name, "")) gr->SetNameTitle(name.Data(), name.Data());
2388 //_____________________________________________________________________________
2389 TGraphErrors* AliJetFlowTools::GetV2(TH1 *h1, TH1* h2, Double_t r, TString name)
2391 // get v2 from difference of in plane, out of plane yield
2392 // h1 must hold the in-plane yield, h2 holds the out of plane yield
2393 // different binning is allowed but will mean that the error
2394 // propagation is unreliable
2395 // r is the event plane resolution for the chosen centrality
2397 printf(" GetV2 called with NULL argument(s) \n ");
2401 TGraphErrors *gr = new TGraphErrors();
2402 gr->GetXaxis()->SetTitle("p_{T, jet} [GeV/c]");
2403 Float_t binCent(0.), ratio(0.), error2(0.), binWidth(0.);
2404 Double_t pre(TMath::Pi()/(4.*r)), in(0.), out(0.), ein(0.), eout(0.);
2405 for(Int_t i(1); i <= h1->GetNbinsX(); i++) {
2406 binCent = h1->GetXaxis()->GetBinCenter(i);
2407 j = h2->FindBin(binCent);
2408 binWidth = h1->GetXaxis()->GetBinWidth(i);
2409 if(h2->GetBinContent(j) > 0.) {
2410 in = h1->GetBinContent(i);
2411 ein = h1->GetBinError(i);
2412 out = h2->GetBinContent(j);
2413 eout = h2->GetBinError(j);
2414 ratio = pre*((in-out)/(in+out));
2415 error2 =((r*4.)/(TMath::Pi()))*((4.*out*out/(TMath::Power(in+out, 4)))*ein*ein+(4.*in*in/(TMath::Power(in+out, 4)))*eout*eout);
2416 if(error2 > 0) error2 = TMath::Sqrt(error2);
2417 gr->SetPoint(gr->GetN(),binCent,ratio);
2418 gr->SetPointError(gr->GetN()-1,0.5*binWidth,error2);
2421 if(strcmp(name, "")) gr->SetNameTitle(name.Data(), name.Data());
2424 //_____________________________________________________________________________
2425 void AliJetFlowTools::WriteObject(TObject* object, TString suffix, Bool_t kill) {
2426 // write object, if a unique identifier is given the object is cloned
2427 // and the clone is saved. setting kill to true will delete the original obect from the heap
2429 printf(" > WriteObject:: called with NULL arguments \n ");
2431 } else if(!strcmp("", suffix.Data())) object->Write();
2433 TObject* newObject(object->Clone(Form("%s_%s", object->GetName(), suffix.Data())));
2436 if(kill) delete object;
2438 //_____________________________________________________________________________
2439 TH2D* AliJetFlowTools::ConstructDPtResponseFromTH1D(TH1D* dpt, Bool_t AvoidRoundingError) {
2440 // construt a delta pt response matrix from supplied dpt distribution
2441 // binning is fine, set fBinsTrue and fBinsRec and call 'RebinTH2D' to
2442 // do a weighted rebinning to a (coarser) dpt distribution
2443 // be careful with the binning of the dpt response: it should be equal to that
2444 // of the response matrix, otherwise dpt and response matrices cannot be multiplied
2446 // the response matrix will be square and have the same binning
2447 // (min, max and granularity) of the input histogram
2448 Int_t bins(dpt->GetXaxis()->GetNbins()); // number of bins, will also be no of rows, columns
2449 Double_t _bins[bins+1]; // prepare array with bin borders
2450 for(Int_t i(0); i < bins; i++) _bins[i] = dpt->GetBinLowEdge(i+1);
2451 _bins[bins] = dpt->GetBinLowEdge(bins)+dpt->GetBinWidth(bins+1); // get upper edge
2452 TH2D* res(new TH2D(Form("Response_from_%s", dpt->GetName()), Form("Response_from_%s", dpt->GetName()), bins, _bins, bins, _bins));
2453 for(Int_t j(0); j < bins+1; j++) { // loop on pt true slices j
2454 Bool_t skip = kFALSE;
2455 for(Int_t k(0); k < bins+1; k++) { // loop on pt gen slices k
2456 (skip) ? res->SetBinContent(j, k, 0.) : res->SetBinContent(j, k, dpt->GetBinContent(dpt->GetXaxis()->FindBin(k-j)));
2457 if(AvoidRoundingError && k > j && TMath::AreEqualAbs(dpt->GetBinContent(dpt->GetBinContent(k-j)), 0, 1e-8)) skip = kTRUE;
2462 //_____________________________________________________________________________
2463 TH2D* AliJetFlowTools::GetUnityResponse(TArrayD* binsTrue, TArrayD* binsRec, TString suffix) {
2464 if(!binsTrue || !binsRec) {
2465 printf(" > GetUnityResponse:: function called with NULL arguments < \n");
2468 TString name(Form("unityResponse_%s", suffix.Data()));
2469 TH2D* unity(new TH2D(name.Data(), name.Data(), binsTrue->GetSize()-1, binsTrue->GetArray(), binsRec->GetSize()-1, binsRec->GetArray()));
2470 for(Int_t i(0); i < binsTrue->GetSize(); i++) {
2471 for(Int_t j(0); j < binsRec->GetSize(); j++) {
2472 if(i==j) unity->SetBinContent(1+i, 1+j, 1.);
2477 //_____________________________________________________________________________
2478 void AliJetFlowTools::SaveConfiguration(Bool_t convergedIn, Bool_t convergedOut) const {
2479 // save configuration parameters to histogram
2480 TH1F* summary = new TH1F("UnfoldingConfiguration","UnfoldingConfiguration", 20, -.5, 19.5);
2481 summary->SetBinContent(1, fBetaIn);
2482 summary->GetXaxis()->SetBinLabel(1, "fBetaIn");
2483 summary->SetBinContent(2, fBetaOut);
2484 summary->GetXaxis()->SetBinLabel(2, "fBetaOut");
2485 summary->SetBinContent(3, fCentralityBin);
2486 summary->GetXaxis()->SetBinLabel(3, "fCentralityBin");
2487 summary->SetBinContent(4, (int)convergedIn);
2488 summary->GetXaxis()->SetBinLabel(4, "convergedIn");
2489 summary->SetBinContent(5, (int)convergedOut);
2490 summary->GetXaxis()->SetBinLabel(5, "convergedOut");
2491 summary->SetBinContent(6, (int)fAvoidRoundingError);
2492 summary->GetXaxis()->SetBinLabel(6, "fAvoidRoundingError");
2493 summary->SetBinContent(7, (int)fUnfoldingAlgorithm);
2494 summary->GetXaxis()->SetBinLabel(7, "fUnfoldingAlgorithm");
2495 summary->SetBinContent(8, (int)fPrior);
2496 summary->GetXaxis()->SetBinLabel(8, "fPrior");
2497 summary->SetBinContent(9, fSVDRegIn);
2498 summary->GetXaxis()->SetBinLabel(9, "fSVDRegIn");
2499 summary->SetBinContent(10, fSVDRegOut);
2500 summary->GetXaxis()->SetBinLabel(10, "fSVDRegOut");
2501 summary->SetBinContent(11, (int)fSVDToy);
2502 summary->GetXaxis()->SetBinLabel(11, "fSVDToy");
2503 summary->SetBinContent(12, fJetRadius);
2504 summary->GetXaxis()->SetBinLabel(12, "fJetRadius");
2505 summary->SetBinContent(13, (int)fNormalizeSpectra);
2506 summary->GetXaxis()->SetBinLabel(13, "fNormalizeSpectra");
2507 summary->SetBinContent(14, (int)fSmoothenPrior);
2508 summary->GetXaxis()->SetBinLabel(14, "fSmoothenPrior");
2509 summary->SetBinContent(15, (int)fTestMode);
2510 summary->GetXaxis()->SetBinLabel(15, "fTestMode");
2511 summary->SetBinContent(16, (int)fUseDetectorResponse);
2512 summary->GetXaxis()->SetBinLabel(16, "fUseDetectorResponse");
2513 summary->SetBinContent(17, fBayesianIterIn);
2514 summary->GetXaxis()->SetBinLabel(17, "fBayesianIterIn");
2515 summary->SetBinContent(18, fBayesianIterOut);
2516 summary->GetXaxis()->SetBinLabel(18, "fBayesianIterOut");
2517 summary->SetBinContent(19, fBayesianSmoothIn);
2518 summary->GetXaxis()->SetBinLabel(19, "fBayesianSmoothIn");
2519 summary->SetBinContent(20, fBayesianSmoothOut);
2520 summary->GetXaxis()->SetBinLabel(20, "fBayesianSmoothOut");
2522 //_____________________________________________________________________________
2523 void AliJetFlowTools::ResetAliUnfolding() {
2524 // ugly function: reset all unfolding parameters
2525 TVirtualFitter* fitter(TVirtualFitter::GetFitter());
2527 printf(" > Found fitter, will delete it < \n");
2531 printf(" > Found gMinuit, will re-create it < \n");
2533 gMinuit = new TMinuit;
2535 AliUnfolding::fgCorrelationMatrix = 0;
2536 AliUnfolding::fgCorrelationMatrixSquared = 0;
2537 AliUnfolding::fgCorrelationCovarianceMatrix = 0;
2538 AliUnfolding::fgCurrentESDVector = 0;
2539 AliUnfolding::fgEntropyAPriori = 0;
2540 AliUnfolding::fgEfficiency = 0;
2541 AliUnfolding::fgUnfoldedAxis = 0;
2542 AliUnfolding::fgMeasuredAxis = 0;
2543 AliUnfolding::fgFitFunction = 0;
2544 AliUnfolding::fgMaxInput = -1;
2545 AliUnfolding::fgMaxParams = -1;
2546 AliUnfolding::fgOverflowBinLimit = -1;
2547 AliUnfolding::fgRegularizationWeight = 10000;
2548 AliUnfolding::fgSkipBinsBegin = 0;
2549 AliUnfolding::fgMinuitStepSize = 0.1;
2550 AliUnfolding::fgMinuitPrecision = 1e-6;
2551 AliUnfolding::fgMinuitMaxIterations = 1000000;
2552 AliUnfolding::fgMinuitStrategy = 1.;
2553 AliUnfolding::fgMinimumInitialValue = kFALSE;
2554 AliUnfolding::fgMinimumInitialValueFix = -1;
2555 AliUnfolding::fgNormalizeInput = kFALSE;
2556 AliUnfolding::fgNotFoundEvents = 0;
2557 AliUnfolding::fgSkipBin0InChi2 = kFALSE;
2558 AliUnfolding::fgBayesianSmoothing = 1;
2559 AliUnfolding::fgBayesianIterations = 10;
2560 AliUnfolding::fgDebug = kFALSE;
2561 AliUnfolding::fgCallCount = 0;
2562 AliUnfolding::fgPowern = 5;
2563 AliUnfolding::fChi2FromFit = 0.;
2564 AliUnfolding::fPenaltyVal = 0.;
2565 AliUnfolding::fAvgResidual = 0.;
2566 AliUnfolding::fgPrintChi2Details = 0;
2567 AliUnfolding::fgCanvas = 0;
2568 AliUnfolding::fghUnfolded = 0;
2569 AliUnfolding::fghCorrelation = 0;
2570 AliUnfolding::fghEfficiency = 0;
2571 AliUnfolding::fghMeasured = 0;
2572 AliUnfolding::SetMinuitStepSize(1.);
2573 AliUnfolding::SetMinuitPrecision(1e-6);
2574 AliUnfolding::SetMinuitMaxIterations(100000);
2575 AliUnfolding::SetMinuitStrategy(2.);
2576 AliUnfolding::SetDebug(1);
2578 //_____________________________________________________________________________
2579 TH1D* AliJetFlowTools::ProtectHeap(TH1D* protect, Bool_t kill, TString suffix) const {
2580 // protect heap by adding unique qualifier to name
2581 if(!protect) return 0x0;
2582 TH1D* p = (TH1D*)protect->Clone();
2583 TString tempString(fActiveString);
2585 p->SetName(Form("%s_%s", protect->GetName(), tempString.Data()));
2586 p->SetTitle(Form("%s_%s", protect->GetTitle(), tempString.Data()));
2587 if(kill) delete protect;
2590 //_____________________________________________________________________________
2591 TH2D* AliJetFlowTools::ProtectHeap(TH2D* protect, Bool_t kill, TString suffix) const {
2592 // protect heap by adding unique qualifier to name
2593 if(!protect) return 0x0;
2594 TH2D* p = (TH2D*)protect->Clone();
2595 TString tempString(fActiveString);
2597 p->SetName(Form("%s_%s", protect->GetName(), tempString.Data()));
2598 p->SetTitle(Form("%s_%s", protect->GetTitle(), tempString.Data()));
2599 if(kill) delete protect;
2602 //_____________________________________________________________________________
2603 TGraphErrors* AliJetFlowTools::ProtectHeap(TGraphErrors* protect, Bool_t kill, TString suffix) const {
2604 // protect heap by adding unique qualifier to name
2605 if(!protect) return 0x0;
2606 TGraphErrors* p = (TGraphErrors*)protect->Clone();
2607 TString tempString(fActiveString);
2609 p->SetName(Form("%s_%s", protect->GetName(), tempString.Data()));
2610 p->SetTitle(Form("%s_%s", protect->GetTitle(), tempString.Data()));
2611 if(kill) delete protect;
2614 //_____________________________________________________________________________
2615 void AliJetFlowTools::MakeAU() {
2616 // === azimuthal unfolding ===
2618 // unfolds the spectrum in delta phi bins, extracts the yield per bin, and does a fit
2619 // in transverse momentum and azimuthal correlation space to extract v2 params
2620 // settings are equal to the ones used for 'Make()'
2622 // basic steps that are followed:
2623 // 1) rebin the raw output of the jet task to the desired binnings
2624 // 2) calls the unfolding routine
2625 // 3) writes output to file
2626 // can be repeated multiple times with different configurations
2628 Int_t low[] = {1, 6, 11, 16, 21, 26, 31, 36};
2629 Int_t up[] = {5, 10, 15, 20, 25, 30, 35, 40};
2630 TString stringArray[] = {"a", "b", "c", "d", "e", "f", "g", "h"};
2632 for(Int_t i(0); i < 6; i++) dPtdPhi[i] = new TH1D(Form("dPtdPhi_%i", i), Form("dPtdPhi_%i", i), 8, 0, TMath::Pi());
2634 for(Int_t i(0); i < 8; i++) {
2635 // 1) manipulation of input histograms
2636 // check if the input variables are present
2637 if(!PrepareForUnfolding(low[i], up[i])) return;
2638 // 1a) resize the jet spectrum according to the binning scheme in fBinsTrue
2639 // parts of the spectrum can end up in over or underflow bins
2640 TH1D* measuredJetSpectrumIn = RebinTH1D(fSpectrumIn, fBinsRec, Form("resized_%s", stringArray[i].Data()), kFALSE);
2642 // 1b) resize the jet spectrum to 'true' bins. can serve as a prior and as a template for unfolding
2643 // the template will be used as a prior for the chi2 unfolding
2644 TH1D* measuredJetSpectrumTrueBinsIn = RebinTH1D(fSpectrumIn, fBinsTrue, stringArray[i], kFALSE);
2646 // get the full response matrix from the dpt and the detector response
2647 fDetectorResponse = NormalizeTH2D(fDetectorResponse);
2648 // get the full response matrix. if test mode is chosen, the full response is replace by a unity matrix
2649 // so that unfolding should return the initial spectrum
2650 if(fUseDptResponse && fUseDetectorResponse) fFullResponseIn = MatrixMultiplication(fDptIn, fDetectorResponse);
2651 else if (fUseDptResponse && !fUseDetectorResponse) fFullResponseIn = fDptIn;
2652 else if (!fUseDptResponse && fUseDetectorResponse) fFullResponseIn = fDetectorResponse;
2653 else if (!fUseDptResponse && !fUseDetectorResponse && !fUnfoldingAlgorithm == AliJetFlowTools::kNone) return;
2654 // normalize each slide of the response to one
2655 NormalizeTH2D(fFullResponseIn);
2656 // resize to desired binning scheme
2657 TH2D* resizedResponseIn = RebinTH2D(fFullResponseIn, fBinsTrue, fBinsRec, stringArray[i]);
2658 // get the kinematic efficiency
2659 TH1D* kinematicEfficiencyIn = resizedResponseIn->ProjectionX();
2660 kinematicEfficiencyIn->SetNameTitle(Form("kin_eff_%s", stringArray[i].Data()), Form("kin_eff_%s", stringArray[i].Data()));
2661 // suppress the errors
2662 for(Int_t j(0); j < kinematicEfficiencyIn->GetXaxis()->GetNbins(); j++) kinematicEfficiencyIn->SetBinError(1+j, 0.);
2663 TH1D* jetFindingEfficiency(0x0);
2664 if(fJetFindingEff) {
2665 jetFindingEfficiency = ProtectHeap(fJetFindingEff);
2666 jetFindingEfficiency->SetNameTitle(Form("%s_coarse", jetFindingEfficiency->GetName()), Form("%s_coarse", jetFindingEfficiency->GetName()));
2667 jetFindingEfficiency = RebinTH1D(jetFindingEfficiency, fBinsTrue);
2669 // 2, 3) call the actual unfolding. results and transient objects are stored in a dedicated TDirectoryFile
2670 TH1D* unfoldedJetSpectrumIn(0x0);
2671 fActiveDir->cd(); // select active dir
2672 TDirectoryFile* dirIn = new TDirectoryFile(Form("%s___%s", stringArray[i].Data(), fActiveString.Data()), Form("%s___%s", stringArray[i].Data(), fActiveString.Data()));
2673 dirIn->cd(); // select inplane subdir
2674 // select the unfolding method
2675 unfoldedJetSpectrumIn = UnfoldWrapper(
2676 measuredJetSpectrumIn,
2678 kinematicEfficiencyIn,
2679 measuredJetSpectrumTrueBinsIn,
2680 TString("dPtdPhiUnfolding"),
2681 jetFindingEfficiency);
2683 resizedResponseIn->SetNameTitle(Form("ResponseMatrix_%s", stringArray[i].Data()), Form("response matrix %s", stringArray[i].Data()));
2684 resizedResponseIn->SetXTitle("p_{T, jet}^{true} [GeV/c]");
2685 resizedResponseIn->SetYTitle("p_{T, jet}^{rec} [GeV/c]");
2686 resizedResponseIn = ProtectHeap(resizedResponseIn);
2687 resizedResponseIn->Write();
2688 kinematicEfficiencyIn->SetNameTitle(Form("KinematicEfficiency_%s", stringArray[i].Data()), Form("Kinematic efficiency, %s", stringArray[i].Data()));
2689 kinematicEfficiencyIn = ProtectHeap(kinematicEfficiencyIn);
2690 kinematicEfficiencyIn->Write();
2691 fDetectorResponse->SetNameTitle("DetectorResponse", "Detector response matrix");
2692 fDetectorResponse = ProtectHeap(fDetectorResponse, kFALSE);
2693 fDetectorResponse->Write();
2694 // optional histograms
2696 fSpectrumIn->SetNameTitle("[ORIG]JetSpectrum", Form("[INPUT] Jet spectrum, %s", stringArray[i].Data()));
2697 fSpectrumIn->Write();
2698 fDptInDist->SetNameTitle("[ORIG]DeltaPt", Form("#delta p_{T} distribution, %s", stringArray[i].Data()));
2699 fDptInDist->Write();
2700 fDptIn->SetNameTitle("[ORIG]DeltaPtMatrix", Form("#delta p_{T} matrix, %s", stringArray[i].Data()));
2702 fFullResponseIn->SetNameTitle("ResponseMatrix", Form("Response matrix, %s", stringArray[i].Data()));
2703 fFullResponseIn->Write();
2707 fDeltaPtDeltaPhi->Write();
2708 fJetPtDeltaPhi->Write();
2710 TH1D* dud(ProtectHeap(unfoldedJetSpectrumIn, kTRUE, stringArray[i]));;
2711 Double_t integralError(0);
2712 for(Int_t j(0); j < 6; j++) {
2713 // get the integrated
2714 Double_t integral(dud->IntegralAndError(2*j+1, 2*j+3, integralError));
2715 dPtdPhi[j]->SetBinContent(i+1, integral);
2716 dPtdPhi[j]->SetBinError(i+1, integralError);
2719 // save the current state of the unfolding object
2720 SaveConfiguration(unfoldedJetSpectrumIn ? kTRUE : kFALSE, kFALSE);
2722 TF1* fourier = new TF1("fourier", "[0]*(1.+0.5*[1]*(TMath::Cos(2.*x)))", 0, TMath::Pi());
2723 TH1D* v2(new TH1D("v2FromFit", "v2FromFit", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()));
2724 for(Int_t i(0); i < 6; i++) {
2725 dPtdPhi[i]->Fit(fourier, "VI");
2726 v2->SetBinContent(1+i, fourier->GetParameter(1));
2727 v2->SetBinError(1+i, fourier->GetParError(1));
2728 dPtdPhi[i]->Write();
2732 //_____________________________________________________________________________