]>
Commit | Line | Data |
---|---|---|
dc1455ee | 1 | /************************************************************************* |
2 | * Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | // Author: Redmer Alexander Bertens, Utrecht University, Utrecht, Netherlands | |
17 | // (rbertens@cern.ch, rbertens@nikhef.nl, r.a.bertens@uu.nl) | |
18 | // | |
19 | // Tools class for Jet Flow Analysis, replaces 'extractJetFlow.C' macro | |
4292ca60 | 20 | // |
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 | |
ef12d5a5 | 28 | // libraries must be present on the system (see http://hepunx.rl.ac.uk/~adye/software/unfold/RooUnfold.html). |
29 | // A test mode is available in which the spectrum is unfolded with a generated unity response | |
30 | // matrix. | |
4292ca60 | 31 | // |
32 | // The weak spot of this class is the function PrepareForUnfolding, which will read | |
33 | // output from two output files and expects histograms with certain names and binning. | |
34 | // Unfolding methods itself are general and should be able to handle any input, therefore one | |
35 | // can forgo the PrepareForUnfolding method, and supply necessary input information via the | |
36 | // SetRawInput() method | |
37 | // | |
38 | // to see an example of how to use this class, see $ALICE_ROOT/PWGCF/FLOW/macros/jetFlowTools.C | |
dc1455ee | 39 | |
40 | // root includes | |
41 | #include "TF1.h" | |
42 | #include "TH1D.h" | |
43 | #include "TH2D.h" | |
4292ca60 | 44 | #include "TGraphErrors.h" |
dc1455ee | 45 | #include "TArrayD.h" |
46 | #include "TList.h" | |
47 | #include "TMinuit.h" | |
48 | #include "TVirtualFitter.h" | |
49 | #include "TLegend.h" | |
50 | #include "TCanvas.h" | |
51 | #include "TStyle.h" | |
dc1455ee | 52 | #include "TLine.h" |
ad04a83c | 53 | #include "TMath.h" |
4292ca60 | 54 | #include "TVirtualFitter.h" |
ef12d5a5 | 55 | #include "TFitResultPtr.h" |
4292ca60 | 56 | // aliroot includes |
dc1455ee | 57 | #include "AliUnfolding.h" |
58 | #include "AliAnaChargedJetResponseMaker.h" | |
4292ca60 | 59 | // class includes |
dc1455ee | 60 | #include "AliJetFlowTools.h" |
51e6bc5a | 61 | // roo unfold includes (make sure you have these available on your system) |
62 | #include "RooUnfold.h" | |
63 | #include "RooUnfoldResponse.h" | |
64 | #include "RooUnfoldSvd.h" | |
65 | #include "TSVDUnfold.h" | |
dc1455ee | 66 | |
67 | using namespace std; | |
dc1455ee | 68 | //_____________________________________________________________________________ |
69 | AliJetFlowTools::AliJetFlowTools() : | |
4292ca60 | 70 | fResponseMaker (new AliAnaChargedJetResponseMaker()), |
ef12d5a5 | 71 | fPower (new TF1("fPower","[0]*TMath::Power(x,-([1]))",0.,300.)), |
4292ca60 | 72 | fSaveFull (kFALSE), |
dc1455ee | 73 | fActiveString (""), |
ad04a83c | 74 | fActiveDir (0x0), |
dc1455ee | 75 | fInputList (0x0), |
4292ca60 | 76 | fRefreshInput (kTRUE), |
dc1455ee | 77 | fOutputFileName ("UnfoldedSpectra.root"), |
ad04a83c | 78 | fOutputFile (0x0), |
dc1455ee | 79 | fCentralityBin (0), |
dc1455ee | 80 | fDetectorResponse (0x0), |
4292ca60 | 81 | fBetaIn (.1), |
82 | fBetaOut (.1), | |
ef12d5a5 | 83 | fAvoidRoundingError (kFALSE), |
51e6bc5a | 84 | fUnfoldingAlgorithm (kChi2), |
85 | fPrior (kPriorMeasured), | |
dc1455ee | 86 | fBinsTrue (0x0), |
87 | fBinsRec (0x0), | |
ef12d5a5 | 88 | fBinsTruePrior (0x0), |
89 | fBinsRecPrior (0x0), | |
4292ca60 | 90 | fSVDRegIn (5), |
91 | fSVDRegOut (5), | |
51e6bc5a | 92 | fSVDToy (kTRUE), |
93 | fJetRadius (0.3), | |
20abfcc4 | 94 | fEventCount (-1), |
95 | fNormalizeSpectra (kTRUE), | |
4292ca60 | 96 | fSmoothenSpectrum (kTRUE), |
97 | fFitMin (60.), | |
98 | fFitMax (105.), | |
99 | fFitStart (75.), | |
ef12d5a5 | 100 | fTestMode (kFALSE), |
101 | fNoDphi (kFALSE), | |
4292ca60 | 102 | fRawInputProvided (kFALSE), |
ef12d5a5 | 103 | fEventPlaneRes (.63), |
104 | fUseDetectorResponse(kTRUE), | |
105 | fTrainPower (kTRUE), | |
4292ca60 | 106 | fRMSSpectrumIn (0x0), |
107 | fRMSSpectrumOut (0x0), | |
108 | fRMSRatio (0x0), | |
ef12d5a5 | 109 | fRMSV2 (0x0), |
ad04a83c | 110 | fDeltaPtDeltaPhi (0x0), |
111 | fJetPtDeltaPhi (0x0), | |
dc1455ee | 112 | fSpectrumIn (0x0), |
113 | fSpectrumOut (0x0), | |
114 | fDptInDist (0x0), | |
115 | fDptOutDist (0x0), | |
116 | fDptIn (0x0), | |
117 | fDptOut (0x0), | |
118 | fFullResponseIn (0x0), | |
119 | fFullResponseOut (0x0), | |
120 | fUnfoldedIn (0x0), | |
4292ca60 | 121 | fUnfoldedOut (0x0) { // class constructor |
122 | // create response maker weight function | |
123 | fResponseMaker->SetRMMergeWeightFunction(new TF1("weightFunction", "x*TMath::Power(1.+(1./(8.*0.9))*x, -8.)", 0 ,200)); | |
124 | } | |
dc1455ee | 125 | //_____________________________________________________________________________ |
126 | void AliJetFlowTools::Make() { | |
ad04a83c | 127 | // core function of the class |
4292ca60 | 128 | // 1) rebin the raw output of the jet task to the desired binnings |
ad04a83c | 129 | // 2) calls the unfolding routine |
130 | // 3) writes output to file | |
4292ca60 | 131 | // can be repeated multiple times with different configurations |
132 | ||
ad04a83c | 133 | // 1) manipulation of input histograms |
dc1455ee | 134 | // check if the input variables are present |
4292ca60 | 135 | if(fRefreshInput) { |
136 | if(!PrepareForUnfolding()) { | |
137 | printf(" AliJetFlowTools::Make() Fatal error \n - couldn't prepare for unfolding ! \n"); | |
138 | return; | |
139 | } | |
dc1455ee | 140 | } |
4292ca60 | 141 | // 1a) resize the jet spectrum according to the binning scheme in fBinsTrue |
142 | // parts of the spectrum can end up in over or underflow bins | |
143 | TH1D* resizedJetPtIn = GetUnfoldingTemplate(fSpectrumIn, fBinsRec, TString("resized_in_")); | |
144 | TH1D* resizedJetPtOut = GetUnfoldingTemplate(fSpectrumOut, fBinsRec, TString("resized_out_")); | |
145 | ||
146 | // 1b) get the unfolding template | |
147 | // the template will be used as a prior for the chi2 unfolding | |
148 | // it holds thie rec spectrum, but is rebinned to the gen binning scheme | |
dc1455ee | 149 | TH1D* unfoldingTemplateIn = GetUnfoldingTemplate(fSpectrumIn, fBinsTrue, TString("in")); |
150 | TH1D* unfoldingTemplateOut = GetUnfoldingTemplate(fSpectrumOut, fBinsTrue, TString("out")); | |
151 | ||
4292ca60 | 152 | // get the full response matrix from the dpt and the detector response |
dc1455ee | 153 | fDetectorResponse = NormalizeTH2D(fDetectorResponse); |
ef12d5a5 | 154 | // get the full response matrix. if test mode is chosen, the full response is replace by a unity matrix |
155 | // so that unfolding should return the initial spectrum | |
156 | if(!fTestMode) { | |
157 | fFullResponseIn = (fUseDetectorResponse) ? MatrixMultiplicationTH2D(fDptIn, fDetectorResponse) : fDptIn; | |
158 | fFullResponseOut = (fUseDetectorResponse) ? MatrixMultiplicationTH2D(fDptOut, fDetectorResponse) : fDptOut; | |
159 | } else { | |
160 | fFullResponseIn = GetUnityResponse(fBinsTrue, fBinsRec, TString("in")); | |
161 | fFullResponseOut = GetUnityResponse(fBinsTrue, fBinsRec, TString("out")); | |
162 | } | |
4292ca60 | 163 | // normalize each slide of the response to one |
dc1455ee | 164 | NormalizeTH2D(fFullResponseIn); |
165 | NormalizeTH2D(fFullResponseOut); | |
4292ca60 | 166 | // resize to desired binning scheme |
167 | TH2D* resizedResonseIn = RebinTH2D(fFullResponseIn, fBinsTrue, fBinsRec, TString("in")); | |
168 | TH2D* resizedResonseOut = RebinTH2D(fFullResponseOut, fBinsTrue, fBinsRec, TString("out")); | |
169 | // get the kinematic efficiency | |
dc1455ee | 170 | TH1D* kinematicEfficiencyIn = resizedResonseIn->ProjectionX(); |
4292ca60 | 171 | kinematicEfficiencyIn->SetNameTitle("kin_eff_IN","kin_eff_IN"); |
dc1455ee | 172 | TH1D* kinematicEfficiencyOut = resizedResonseOut->ProjectionX(); |
4292ca60 | 173 | kinematicEfficiencyOut->SetNameTitle("kin_eff_OUT", "kin_eff_OUT"); |
174 | // suppress the errors | |
51e6bc5a | 175 | for(Int_t i(0); i < kinematicEfficiencyOut->GetXaxis()->GetNbins(); i++) { |
176 | kinematicEfficiencyIn->SetBinError(1+i, 0.); | |
4292ca60 | 177 | kinematicEfficiencyOut->SetBinError(1+i, 0.); |
51e6bc5a | 178 | } |
ad04a83c | 179 | // 2, 3) call the actual unfolding. results and transient objects are stored in a dedicated TDirectoryFile |
180 | fActiveDir->cd(); // select active dir | |
181 | TDirectoryFile* dirIn = new TDirectoryFile(Form("InPlane___%s", fActiveString.Data()), Form("InPlane___%s", fActiveString.Data())); | |
182 | dirIn->cd(); // select inplane subdir | |
51e6bc5a | 183 | Bool_t convergedIn(kFALSE), convergedOut(kFALSE); |
184 | // select the unfolding method | |
185 | switch (fUnfoldingAlgorithm) { | |
186 | case kChi2 : { | |
187 | convergedIn = UnfoldSpectrumChi2( // do the inplane unfolding | |
188 | resizedJetPtIn, | |
189 | resizedResonseIn, | |
190 | kinematicEfficiencyIn, | |
191 | unfoldingTemplateIn, | |
192 | fUnfoldedIn, | |
193 | TString("in")); | |
20abfcc4 | 194 | printf(" > Spectrum (in plane) unfolded using kChi2 unfolding < \n"); |
51e6bc5a | 195 | } break; |
196 | case kSVD : { | |
197 | convergedIn = UnfoldSpectrumSVD( // do the inplane unfolding | |
198 | resizedJetPtIn, | |
199 | resizedResonseIn, | |
200 | kinematicEfficiencyIn, | |
201 | unfoldingTemplateIn, | |
4292ca60 | 202 | fUnfoldedIn, |
51e6bc5a | 203 | TString("in")); |
20abfcc4 | 204 | printf(" > Spectrum (in plane) unfolded using kSVD unfolding < \n"); |
51e6bc5a | 205 | } break; |
ef12d5a5 | 206 | case kNone : { // do nothing, just rebin and optionally smooothen the spectrum |
207 | resizedResonseIn->SetNameTitle("measuredSpectrumIn", "measured spectrum, in plane"); | |
208 | if(fSmoothenSpectrum) { // see if we want to smooothen the spectrum | |
209 | TH1D* resizedJetPtInJagged((TH1D*)resizedJetPtIn->Clone("cachedRawJetJaggedIn")); | |
210 | resizedJetPtInJagged->SetNameTitle("measured spectrum before smoothening in", "measured spectrum, before smoothening in"); | |
211 | resizedJetPtInJagged = ProtectHeap(resizedJetPtInJagged); | |
212 | resizedJetPtInJagged->Write(); // save the original | |
213 | resizedJetPtIn->Sumw2(); | |
214 | TFitResultPtr r = resizedJetPtIn->Fit(fPower, "QWILS", "", fFitMin, fFitMax); | |
215 | if((int)r == 0 ) { | |
216 | for(Int_t i(0); i < resizedJetPtIn->GetNbinsX() + 1; i++) { | |
217 | if(resizedJetPtIn->GetBinCenter(i) > fFitStart) { // from this pt value use extrapolation | |
218 | resizedJetPtIn->SetBinContent(i,fPower->Integral(resizedJetPtIn->GetXaxis()->GetBinLowEdge(i),resizedJetPtIn->GetXaxis()->GetBinUpEdge(i))/resizedJetPtIn->GetXaxis()->GetBinWidth(i)); | |
219 | } | |
220 | } | |
221 | } else printf(" > PANIC, SMOOTHENING FAILED < \n"); | |
222 | } | |
223 | fUnfoldedIn = ProtectHeap(resizedJetPtIn, kTRUE, TString("in")); | |
224 | convergedIn = kTRUE; | |
225 | } break; | |
226 | ||
51e6bc5a | 227 | default : { |
228 | printf(" > Selected unfolding method is not implemented yet ! \n"); | |
229 | return; | |
230 | } | |
231 | } | |
4292ca60 | 232 | resizedResonseIn->SetNameTitle("ResponseMatrixIn", "response matrix in plane"); |
233 | resizedResonseIn->SetXTitle("p_{T}^{true} [GeV/c]"); | |
234 | resizedResonseIn->SetYTitle("p_{T}^{rec} [GeV/c]"); | |
235 | resizedResonseIn = ProtectHeap(resizedResonseIn); | |
ad04a83c | 236 | resizedResonseIn->Write(); |
4292ca60 | 237 | kinematicEfficiencyIn->SetNameTitle("KinematicEfficiencyIn","Kinematic efficiency, in plane"); |
238 | kinematicEfficiencyIn = ProtectHeap(kinematicEfficiencyIn); | |
ad04a83c | 239 | kinematicEfficiencyIn->Write(); |
240 | fDetectorResponse->SetNameTitle("DetectorResponse", "Detector response matrix"); | |
4292ca60 | 241 | fDetectorResponse = ProtectHeap(fDetectorResponse, kFALSE); |
ad04a83c | 242 | fDetectorResponse->Write(); |
4292ca60 | 243 | // optional histograms |
244 | if(fSaveFull) { | |
245 | fSpectrumIn->SetNameTitle("[ORIG]JetSpectrum", "[INPUT] Jet spectrum, in plane"); | |
246 | fSpectrumIn->Write(); | |
247 | fDptInDist->SetNameTitle("[ORIG]DeltaPt", "#delta p_{T} distribution, in plane"); | |
248 | fDptInDist->Write(); | |
249 | fDptIn->SetNameTitle("[ORIG]DeltaPtMatrix","#delta p_{T} matrix, in plane"); | |
250 | fDptIn->Write(); | |
251 | fFullResponseIn->SetNameTitle("ResponseMatrix", "Response matrix, in plane"); | |
252 | fFullResponseIn->Write(); | |
253 | } | |
ad04a83c | 254 | fActiveDir->cd(); |
255 | TDirectoryFile* dirOut = new TDirectoryFile(Form("OutOfPlane___%s", fActiveString.Data()), Form("OutOfPlane___%s", fActiveString.Data())); | |
256 | dirOut->cd(); | |
51e6bc5a | 257 | switch (fUnfoldingAlgorithm) { |
258 | case kChi2 : { | |
259 | convergedOut = UnfoldSpectrumChi2( | |
260 | resizedJetPtOut, | |
261 | resizedResonseOut, | |
262 | kinematicEfficiencyOut, | |
263 | unfoldingTemplateOut, | |
264 | fUnfoldedOut, | |
265 | TString("out")); | |
20abfcc4 | 266 | printf(" > Spectrum (out of plane) unfolded using kChi2 < \n"); |
51e6bc5a | 267 | } break; |
268 | case kSVD : { | |
269 | convergedOut = UnfoldSpectrumSVD( | |
270 | resizedJetPtOut, | |
271 | resizedResonseOut, | |
272 | kinematicEfficiencyOut, | |
273 | unfoldingTemplateOut, | |
4292ca60 | 274 | fUnfoldedOut, |
51e6bc5a | 275 | TString("out")); |
20abfcc4 | 276 | printf(" > Spectrum (out of plane) unfolded using kSVD < \n"); |
51e6bc5a | 277 | } break; |
ef12d5a5 | 278 | case kNone : { // do nothing, just rebin and optionally smooothen the spectrum |
279 | resizedResonseOut->SetNameTitle("measuredSpectrumOut", "measured spectrum, out plane"); | |
280 | if(fSmoothenSpectrum) { // see if we want to smooothen the spectrum | |
281 | TH1D* resizedJetPtOutJagged((TH1D*)resizedJetPtOut->Clone("cachedRawJetJaggedOut")); | |
282 | resizedJetPtOutJagged->SetNameTitle("measured spectrum before smoothening Out", "measured spectrum, before smoothening Out"); | |
283 | resizedJetPtOutJagged = ProtectHeap(resizedJetPtOutJagged); | |
284 | resizedJetPtOutJagged->Write(); // save the original | |
285 | resizedJetPtOut->Sumw2(); | |
286 | TFitResultPtr r = resizedJetPtOut->Fit(fPower, "QWILS", "", fFitMin, fFitMax); | |
287 | if((int)r == 0) { | |
288 | for(Int_t i(0); i < resizedJetPtOut->GetNbinsX() + 1; i++) { | |
289 | if(resizedJetPtOut->GetBinCenter(i) > fFitStart) { // from this pt value use extrapolation | |
290 | resizedJetPtOut->SetBinContent(i,fPower->Integral(resizedJetPtOut->GetXaxis()->GetBinLowEdge(i),resizedJetPtOut->GetXaxis()->GetBinUpEdge(i))/resizedJetPtOut->GetXaxis()->GetBinWidth(i)); | |
291 | } | |
292 | } | |
293 | }else printf(" > PANIC, SMOOTHENING FAILED < \n"); | |
294 | ||
295 | } | |
296 | fUnfoldedOut = ProtectHeap(resizedJetPtOut, kTRUE, TString("out")); | |
297 | convergedOut = kTRUE; | |
298 | } break; | |
51e6bc5a | 299 | default : { |
300 | printf(" > Selected unfolding method is not implemented yet ! \n"); | |
301 | return; | |
302 | } | |
303 | } | |
4292ca60 | 304 | resizedResonseOut->SetNameTitle("ResponseMatrixOut", "response matrix in plane"); |
305 | resizedResonseOut->SetXTitle("p_{T}^{true} [GeV/c]"); | |
306 | resizedResonseOut->SetYTitle("p_{T}^{rec} [GeV/c]"); | |
307 | resizedResonseOut = ProtectHeap(resizedResonseOut); | |
ad04a83c | 308 | resizedResonseOut->Write(); |
4292ca60 | 309 | kinematicEfficiencyOut->SetNameTitle("KinematicEfficiencyOut","Kinematic efficiency, Out plane"); |
310 | kinematicEfficiencyOut = ProtectHeap(kinematicEfficiencyOut); | |
ad04a83c | 311 | kinematicEfficiencyOut->Write(); |
312 | fDetectorResponse->SetNameTitle("DetectorResponse", "Detector response matrix"); | |
4292ca60 | 313 | fDetectorResponse = ProtectHeap(fDetectorResponse, kFALSE); |
ad04a83c | 314 | fDetectorResponse->Write(); |
4292ca60 | 315 | // optional histograms |
316 | if(fSaveFull) { | |
ef12d5a5 | 317 | fSpectrumOut->SetNameTitle("[ORIG]JetSpectrum", "[INPUT]Jet spectrum, Out plane"); |
4292ca60 | 318 | fSpectrumOut->Write(); |
319 | fDptOutDist->SetNameTitle("[ORIG]DeltaPt", "#delta p_{T} distribution, Out plane"); | |
320 | fDptOutDist->Write(); | |
321 | fDptOut->SetNameTitle("[ORIG]DeltaPtMatrix","#delta p_{T} matrix, Out plane"); | |
322 | fDptOut->Write(); | |
323 | fFullResponseOut->SetNameTitle("[ORIG]ResponseMatrix", "Response matrix, Out plane"); | |
324 | fFullResponseOut->Write(); | |
325 | } | |
51e6bc5a | 326 | // write general output histograms to file |
ad04a83c | 327 | fActiveDir->cd(); |
4292ca60 | 328 | if(convergedIn && convergedOut && fUnfoldedIn && fUnfoldedOut) { |
ef12d5a5 | 329 | TGraphErrors* ratio(GetRatio((TH1D*)fUnfoldedIn->Clone("unfoldedLocal_in"), (TH1D*)fUnfoldedOut->Clone("unfoldedLocal_out"))); |
4292ca60 | 330 | if(ratio) { |
331 | ratio->SetNameTitle("RatioInOutPlane", "Ratio in plane, out of plane jet spectrum"); | |
332 | ratio->GetXaxis()->SetTitle("p_{T} [GeV/c]"); | |
333 | ratio->GetYaxis()->SetTitle("yield IN / yield OUT"); | |
ef12d5a5 | 334 | ratio = ProtectHeap(ratio); |
4292ca60 | 335 | ratio->Write(); |
336 | // write histo values to RMS files if both routines converged | |
337 | // input values are weighted by their uncertainty | |
338 | for(Int_t i(0); i < ratio->GetXaxis()->GetNbins(); i++) { | |
339 | if(fUnfoldedIn->GetBinError(i+1) > 0) fRMSSpectrumIn->Fill(fRMSSpectrumIn->GetBinCenter(i+1), fUnfoldedIn->GetBinContent(i+1), 1./TMath::Power(fUnfoldedIn->GetBinError(i+1), 2.)); | |
340 | if(fUnfoldedOut->GetBinError(i+1) > 0) fRMSSpectrumOut->Fill(fRMSSpectrumOut->GetBinCenter(i+1), fUnfoldedOut->GetBinContent(i+1), 1./TMath::Power(fUnfoldedOut->GetBinError(i+1), 2.)); | |
341 | if(fUnfoldedOut->GetBinContent(i+1) > 0) fRMSRatio->Fill(fRMSSpectrumIn->GetBinCenter(i+1), fUnfoldedIn->GetBinContent(i+1) / fUnfoldedOut->GetBinContent(i+1)); | |
ef12d5a5 | 342 | } |
343 | } | |
344 | TGraphErrors* v2(GetV2((TH1D*)fUnfoldedIn->Clone("unfoldedLocal_inv2"), (TH1D*)fUnfoldedOut->Clone("unfoldedLocal_outv2"))); | |
345 | if(v2) { | |
346 | v2->SetNameTitle("v2", "v_{2} from different in, out of plane yield"); | |
347 | v2->GetXaxis()->SetTitle("p_{T} [GeV/c]"); | |
348 | v2->GetYaxis()->SetTitle("v_{2}"); | |
349 | v2 = ProtectHeap(v2); | |
350 | v2->Write(); | |
351 | } | |
352 | } else if (fUnfoldedOut && fUnfoldedIn) { | |
353 | TGraphErrors* ratio(GetRatio((TH1D*)fUnfoldedIn->Clone("unfoldedLocal_in"), (TH1D*)fUnfoldedOut->Clone("unfoldedLocal_out"), TString(""), fBinsRec->At(fBinsRec->GetSize()-1))); | |
354 | if(ratio) { | |
355 | ratio->SetNameTitle("[NC]RatioInOutPlane", "[NC]Ratio in plane, out of plane jet spectrum"); | |
356 | ratio->GetXaxis()->SetTitle("p_{T} [GeV/c]"); | |
357 | ratio->GetYaxis()->SetTitle("yield IN / yield OUT"); | |
358 | ratio = ProtectHeap(ratio); | |
359 | ratio->Write(); | |
360 | } | |
361 | TGraphErrors* v2(GetV2((TH1D*)fUnfoldedIn->Clone("unfoldedLocal_inv2"), (TH1D*)fUnfoldedOut->Clone("unfoldedLocal_outv2"))); | |
362 | if(v2) { | |
363 | v2->SetNameTitle("v2", "v_{2} from different in, out of plane yield"); | |
364 | v2->GetXaxis()->SetTitle("p_{T} [GeV/c]"); | |
365 | v2->GetYaxis()->SetTitle("v_{2}"); | |
366 | v2 = ProtectHeap(v2); | |
367 | v2->Write(); | |
4292ca60 | 368 | } |
20abfcc4 | 369 | } |
ad04a83c | 370 | fDeltaPtDeltaPhi->Write(); |
371 | fJetPtDeltaPhi->Write(); | |
4292ca60 | 372 | SaveConfiguration(convergedIn, convergedOut); |
dc1455ee | 373 | } |
374 | //_____________________________________________________________________________ | |
51e6bc5a | 375 | Bool_t AliJetFlowTools::UnfoldSpectrumChi2( |
4292ca60 | 376 | TH1D* resizedJetPt, // truncated raw jets (same binning as pt rec of response) |
377 | TH2D* resizedResonse, // response matrix | |
378 | TH1D* kinematicEfficiency, // kinematic efficiency | |
379 | TH1D* unfoldingTemplate, // unfolding template: same binning is pt gen of response | |
380 | TH1D *&unfolded, // will point to the unfolded spectrum | |
381 | TString suffix) // suffix (in or out of plane) | |
dc1455ee | 382 | { |
51e6bc5a | 383 | // unfold the spectrum using chi2 minimization |
384 | ||
4292ca60 | 385 | // step 0) setup the static members of AliUnfolding |
386 | ResetAliUnfolding(); // reset from previous iteration | |
387 | // also deletes and re-creates the global TVirtualFitter | |
388 | AliUnfolding::SetUnfoldingMethod(AliUnfolding::kChi2Minimization); | |
389 | if(!strcmp("in", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaIn); | |
390 | else if(!strcmp("out", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaOut); | |
391 | if(!strcmp("prior_in", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaIn); | |
392 | else if(!strcmp("prior_out", suffix.Data())) AliUnfolding::SetChi2Regularization(AliUnfolding::kLogLog, fBetaOut); | |
393 | AliUnfolding::SetNbins(fBinsRec->GetSize()-1, fBinsTrue->GetSize()-1); | |
dc1455ee | 394 | |
4292ca60 | 395 | // step 1) clone all input histograms. |
396 | ||
397 | // resizedJetPtLocal holds the spectrum that needs to be unfolded | |
51e6bc5a | 398 | TH1D *resizedJetPtLocal = (TH1D*)resizedJetPt->Clone(Form("resizedJetPtLocal_%s", suffix.Data())); |
4292ca60 | 399 | if(fSmoothenSpectrum) { // see if we want to smooothen the spectrum |
400 | TH1D* resizedJetPtLocalJagged((TH1D*)resizedJetPtLocal->Clone(Form("cachedRawJetLocalJagged_%s", suffix.Data()))); | |
401 | resizedJetPtLocalJagged->SetNameTitle(Form("measured spectrum before smoothening %s", suffix.Data()), Form("measured spectrum, before smoothening %s", suffix.Data())); | |
402 | resizedJetPtLocalJagged = ProtectHeap(resizedJetPtLocalJagged); | |
403 | resizedJetPtLocalJagged->Write(); // save the original | |
404 | resizedJetPtLocal->Sumw2(); | |
ef12d5a5 | 405 | TFitResultPtr r = resizedJetPtLocal->Fit(fPower, "QWILS", "", fFitMin, fFitMax); |
406 | if((int)r == 0) { | |
407 | for(Int_t i(0); i < resizedJetPtLocal->GetNbinsX() + 1; i++) { | |
408 | if(resizedJetPtLocal->GetBinCenter(i) > fFitStart) { // from this pt value use extrapolation | |
409 | resizedJetPtLocal->SetBinContent(i,fPower->Integral(resizedJetPtLocal->GetXaxis()->GetBinLowEdge(i),resizedJetPtLocal->GetXaxis()->GetBinUpEdge(i))/resizedJetPtLocal->GetXaxis()->GetBinWidth(i)); | |
410 | } | |
4292ca60 | 411 | } |
ef12d5a5 | 412 | }else printf(" > PANIC, SMOOTHENING FAILED < \n"); |
413 | ||
4292ca60 | 414 | } |
415 | // unfolded local will be filled with the result of the unfolding | |
416 | TH1D *unfoldedLocal(new TH1D(Form("unfoldedLocal_%s", suffix.Data()), Form("unfoldedLocal_%s", suffix.Data()), fBinsTrue->GetSize()-1, fBinsTrue->GetArray())); | |
417 | ||
dc1455ee | 418 | // full response matrix and kinematic efficiency |
51e6bc5a | 419 | TH2D* resizedResponseLocal = (TH2D*)resizedResonse->Clone(Form("resizedResponseLocal_%s", suffix.Data())); |
420 | TH1D* kinematicEfficiencyLocal = (TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiencyLocal_%s", suffix.Data())); | |
4292ca60 | 421 | // the initial guess for the unfolded pt spectrum, equal to the folded spectrum, but in 'true' bins |
422 | TH1D *priorLocal = (TH1D*)unfoldingTemplate->Clone(Form("priorLocal_%s", suffix.Data())); | |
ef12d5a5 | 423 | if(fSmoothenSpectrum) { |
424 | TH1D* priorLocalJagged((TH1D*)priorLocal->Clone(Form("cachedRawJetLocalJagged_%s", suffix.Data()))); | |
425 | priorLocalJagged->SetNameTitle(Form("prior before smoothening %s", suffix.Data()), Form("prior before smoothening %s", suffix.Data())); | |
426 | priorLocalJagged = ProtectHeap(priorLocalJagged); | |
427 | priorLocalJagged->Write(); // save the original | |
428 | priorLocal->Sumw2(); | |
429 | TFitResultPtr r = priorLocal->Fit(fPower, "WQILS", "", fFitMin, fFitMax); | |
430 | if((int)r == 0) { | |
431 | for(Int_t i(0); i < priorLocal->GetNbinsX() + 1; i++) { | |
432 | if(priorLocal->GetBinCenter(i) > fFitStart) { // from this pt value use extrapolation | |
433 | priorLocal->SetBinContent(i,fPower->Integral(priorLocal->GetXaxis()->GetBinLowEdge(i),priorLocal->GetXaxis()->GetBinUpEdge(i))/priorLocal->GetXaxis()->GetBinWidth(i)); | |
434 | } | |
435 | } | |
436 | }else printf(" > PANIC, SMOOTHENING FAILED < \n"); | |
437 | ||
438 | } | |
4292ca60 | 439 | // step 2) start the unfolding |
51e6bc5a | 440 | Int_t status(-1), i(0); |
441 | while(status < 0 && i < 100) { | |
4292ca60 | 442 | // i > 0 means that the first iteration didn't converge. in that case, the result of the first |
443 | // iteration (stored in unfoldedLocal) is cloned and used as a starting point for the | |
444 | if (i > 0) priorLocal = (TH1D*)unfoldedLocal->Clone(Form("priorLocal_%s_%i", suffix.Data(), i)); | |
445 | status = AliUnfolding::Unfold( | |
446 | resizedResponseLocal, // response matrix | |
447 | kinematicEfficiencyLocal, // efficiency applied on the unfolded spectrum (can be NULL) | |
448 | resizedJetPtLocal, // measured spectrum | |
449 | priorLocal, // initial conditions (set NULL to use measured spectrum) | |
450 | unfoldedLocal); // results | |
451 | // status holds the minuit fit status (where 0 means convergence) | |
51e6bc5a | 452 | i++; |
453 | } | |
4292ca60 | 454 | // get the status of TMinuit::mnhess(), fISW[1] == 3 means the hessian matrix was calculated succesfully |
455 | if(status == 0 && gMinuit->fISW[1] == 3) { | |
456 | // if the unfolding converged and the hessian matrix is reliable, plot the pearson coefficients | |
ad04a83c | 457 | TVirtualFitter *fitter(TVirtualFitter::GetFitter()); |
4292ca60 | 458 | if(gMinuit) gMinuit->Command("SET COV"); |
459 | TMatrixD covarianceMatrix(fBinsTrue->GetSize()-1, fBinsTrue->GetSize()-1, fitter->GetCovarianceMatrix()); | |
460 | TMatrixD *pearson((TMatrixD*)CalculatePearsonCoefficients(&covarianceMatrix)); | |
461 | pearson->Print(); | |
ad04a83c | 462 | TH2D *hPearson(new TH2D(*pearson)); |
4292ca60 | 463 | hPearson->SetNameTitle(Form("PearsonCoefficients_%s", suffix.Data()), Form("Pearson coefficients, %s plane", suffix.Data())); |
464 | hPearson = ProtectHeap(hPearson); | |
ad04a83c | 465 | hPearson->Write(); |
4292ca60 | 466 | } else status = -1; |
467 | // step 3) refold the unfolded spectrum and save the ratio measured / refolded | |
468 | TH1D *foldedLocal(fResponseMaker->MultiplyResponseGenerated(unfoldedLocal, resizedResponseLocal,kinematicEfficiencyLocal)); | |
469 | foldedLocal->SetNameTitle(Form("RefoldedSpectrum_%s", suffix.Data()), Form("Refolded jet spectrum, %s plane", suffix.Data())); | |
470 | unfoldedLocal->SetNameTitle(Form("UnfoldedSpectrum_%s", suffix.Data()), Form("Unfolded jet spectrum, %s plane", suffix.Data())); | |
471 | TGraphErrors* ratio(GetRatio(foldedLocal, resizedJetPtLocal, kTRUE, fBinsTrue->At(0), fBinsTrue->At(fBinsTrue->GetSize()-1))); | |
472 | if(ratio) { | |
473 | ratio->SetNameTitle("RatioRefoldedMeasured", Form("Ratio refolded and measured spectrum %s plane", suffix.Data())); | |
474 | ratio = ProtectHeap(ratio); | |
475 | ratio->Write(); | |
476 | } | |
477 | resizedJetPtLocal = ProtectHeap(resizedJetPtLocal); | |
478 | resizedJetPtLocal->Write(); | |
479 | resizedResponseLocal = ProtectHeap(resizedResponseLocal); | |
480 | resizedResponseLocal->Write(); | |
481 | unfoldedLocal = ProtectHeap(unfoldedLocal); | |
51e6bc5a | 482 | unfoldedLocal->Write(); |
483 | unfolded = unfoldedLocal; | |
4292ca60 | 484 | foldedLocal = ProtectHeap(foldedLocal); |
485 | foldedLocal->Write(); | |
ef12d5a5 | 486 | priorLocal = ProtectHeap(priorLocal); |
487 | priorLocal->Write(); | |
4292ca60 | 488 | return (status == 0) ? kTRUE : kFALSE; |
dc1455ee | 489 | } |
490 | //_____________________________________________________________________________ | |
51e6bc5a | 491 | Bool_t AliJetFlowTools::UnfoldSpectrumSVD( |
4292ca60 | 492 | TH1D* resizedJetPt, // jet pt in pt rec bins |
493 | TH2D* resizedResonse, // full response matrix, normalized in slides of pt true | |
494 | TH1D* kinematicEfficiency, // kinematic efficiency | |
ef12d5a5 | 495 | TH1D* unfoldingTemplate, // jet pt in pt true bins, also the prior when measured is chosen as prior |
496 | TH1D *&unfolded, // will point to result. temporarily holds prior when chi2 is chosen as prior | |
4292ca60 | 497 | TString suffix) // suffix (in, out) |
51e6bc5a | 498 | { |
499 | // use SVD (singular value decomposition) method to unfold spectra | |
500 | ||
4292ca60 | 501 | // 1) get a prior for unfolding. |
502 | // this can be either an unfolded spectrum from e.g. chi2 unfolding or the measured spectrum | |
51e6bc5a | 503 | TDirectoryFile* dirOut = new TDirectoryFile(Form("Prior_%s___%s", suffix.Data(), fActiveString.Data()), Form("Prior_%s___%s", suffix.Data(), fActiveString.Data())); |
504 | dirOut->cd(); | |
20abfcc4 | 505 | switch (fPrior) { // select the prior for unfolding |
506 | case kPriorChi2 : { | |
ef12d5a5 | 507 | if(fBinsTruePrior && fBinsRecPrior) { // if set, use different binning for the prior |
508 | TArrayD* tempArrayTrue(fBinsTrue); // temporarily cache the original (SVD) binning | |
509 | fBinsTrue = fBinsTruePrior; // switch binning schemes (will be used in UnfoldSpectrumChi2()) | |
510 | TArrayD* tempArrayRec(fBinsRec); | |
511 | fBinsRec = fBinsRecPrior; | |
512 | TH1D* resizedJetPtChi2 = GetUnfoldingTemplate((!strcmp("in", suffix.Data())) ? fSpectrumIn : fSpectrumOut, fBinsRec, TString("resized_chi2")); | |
513 | TH1D* unfoldingTemplateChi2 = GetUnfoldingTemplate((!strcmp("in", suffix.Data())) ? fSpectrumIn : fSpectrumOut, fBinsTruePrior, TString("out")); | |
514 | TH2D* resizedResonseChi2(RebinTH2D((!strcmp("in", suffix.Data())) ? fFullResponseIn : fFullResponseOut,fBinsTruePrior, fBinsRec, TString("chi2"))); | |
515 | TH1D* kinematicEfficiencyChi2(resizedResonseChi2->ProjectionX()); | |
516 | kinematicEfficiencyChi2->SetNameTitle("kin_eff_chi2","kin_eff_chi2"); | |
517 | for(Int_t i(0); i < kinematicEfficiencyChi2->GetXaxis()->GetNbins(); i++) kinematicEfficiencyChi2->SetBinError(1+i, 0.); | |
518 | if(! UnfoldSpectrumChi2( | |
519 | resizedJetPtChi2, | |
520 | resizedResonseChi2, | |
521 | kinematicEfficiencyChi2, | |
522 | unfoldingTemplateChi2, // prior for chi2 unfolding (measured) | |
523 | unfolded, // will hold the result from chi2 (is prior for SVD) | |
524 | TString(Form("prior_%s", suffix.Data()))) ) { | |
525 | printf(" > UnfoldSVD:: panic, couldn't get prior from Chi2 unfolding! \n"); | |
526 | printf(" probably Chi2 unfolding did not converge < \n"); | |
527 | return kFALSE; | |
528 | } | |
529 | fBinsTrue = tempArrayTrue; // reset bins borders | |
530 | fBinsRec = tempArrayRec; | |
531 | unfolded = GetUnfoldingTemplate(unfolded, fBinsTrue, TString(Form("unfoldedChi2Prior_%s", suffix.Data()))); // rebin unfolded | |
532 | } else if(! UnfoldSpectrumChi2( | |
20abfcc4 | 533 | resizedJetPt, |
534 | resizedResonse, | |
535 | kinematicEfficiency, | |
ef12d5a5 | 536 | unfoldingTemplate, // prior for chi2 unfolding (measured) |
537 | unfolded, // will hold the result from chi2 (is prior for SVD) | |
4292ca60 | 538 | TString(Form("prior_%s", suffix.Data()))) ) { |
539 | printf(" > UnfoldSVD:: panic, couldn't get prior from Chi2 unfolding! \n"); | |
540 | printf(" probably Chi2 unfolding did not converge < \n"); | |
541 | return kFALSE; | |
542 | } | |
543 | if(!unfolded) { | |
544 | printf(" > UnfoldSVD:: panic, Chi2 unfolding converged but the prior is NULL ! < " ); | |
545 | return kFALSE; | |
546 | } | |
20abfcc4 | 547 | break; |
548 | } | |
4292ca60 | 549 | case kPriorMeasured : { |
ef12d5a5 | 550 | unfolded = (TH1D*)unfoldingTemplate->Clone(Form("kPriorMeasured_%s", suffix.Data())); // copy template to unfolded to use as prior |
551 | if(fSmoothenSpectrum) { // optionally smoothen the measured prior | |
552 | unfolded->Sumw2(); | |
553 | TFitResultPtr r = unfolded->Fit(fPower, "QWILS", "", fFitMin, fFitMax); | |
554 | if((int)r == 0) { | |
555 | for(Int_t i(1); i < unfolded->GetNbinsX() + 1; i++) { | |
556 | if(unfolded->GetBinCenter(i) > fFitStart) { // from this pt value use extrapolation | |
557 | unfolded->SetBinContent(i,fPower->Integral(unfolded->GetXaxis()->GetBinLowEdge(i),unfolded->GetXaxis()->GetBinUpEdge(i))/unfolded->GetXaxis()->GetBinWidth(i)); | |
558 | } | |
559 | } | |
560 | }else printf(" > PANIC, SMOOTHENING FAILED < \n"); | |
561 | } | |
562 | // unfoldingTemplate = ProtectHeap(unfolded, kFALSE, TString("template")); | |
4292ca60 | 563 | } |
20abfcc4 | 564 | default : break; |
565 | } | |
566 | // note: true and measured spectrum must have same binning for SVD unfolding | |
ef12d5a5 | 567 | // a sane starting point for regularization is nbins / 2 (but the user has to set this ! ) |
20abfcc4 | 568 | if(unfoldingTemplate->GetXaxis()->GetNbins() != resizedJetPt->GetXaxis()->GetNbins()) { |
4292ca60 | 569 | printf(" > UnfoldSpectrumSVD:: PANIC, true and measured spectrum must have same numer of bins ! < \n "); |
20abfcc4 | 570 | } |
571 | (!strcmp(suffix.Data(), "in")) ? fActiveDir->cd(Form("InPlane___%s", fActiveString.Data())) : fActiveDir->cd(Form("OutOfPlane___%s", fActiveString.Data())); | |
4292ca60 | 572 | cout << " 1) retrieved prior " << endl; |
20abfcc4 | 573 | |
4292ca60 | 574 | // 2) setup all the necessary input for the unfolding routine. all input histograms are copied locally |
575 | // prior | |
20abfcc4 | 576 | TH1D *unfoldedLocal((TH1D*)unfolded->Clone(Form("priorUnfolded_%s", suffix.Data()))); |
4292ca60 | 577 | // raw jets in pt rec binning |
51e6bc5a | 578 | TH1D *cachedRawJetLocal((TH1D*)resizedJetPt->Clone(Form("jets_%s", suffix.Data()))); |
ef12d5a5 | 579 | // raw jets in pt true binning |
51e6bc5a | 580 | TH1D *cachedRawJetLocalCoarse((TH1D*)unfoldingTemplate->Clone(Form("unfoldingTemplate_%s", suffix.Data()))); |
ef12d5a5 | 581 | // copy of raw jets in pt true binning |
51e6bc5a | 582 | TH1D *cachedRawJetLocalCoarseOrig((TH1D*)cachedRawJetLocalCoarse->Clone(Form("cachedRawJetLocalCoarseOrig_%s", suffix.Data()))); |
ef12d5a5 | 583 | // local copies response matrix |
51e6bc5a | 584 | TH2D *cachedResponseLocal((TH2D*)resizedResonse->Clone(Form("cachedResponseLocal_%s", suffix.Data()))); |
ef12d5a5 | 585 | // local copy of response matrix, all true slides normalized to 1 |
51e6bc5a | 586 | TH2D *cachedResponseLocalNorm((TH2D*)resizedResonse->Clone(Form("cachedResponseLocalNorm_%s", suffix.Data()))); |
ef12d5a5 | 587 | cachedResponseLocalNorm = NormalizeTH2D(cachedResponseLocalNorm); |
588 | // kinematic efficiency | |
51e6bc5a | 589 | TH1D *kinematicEfficiencyLocal((TH1D*)kinematicEfficiency->Clone(Form("kinematicEfficiency_%s", suffix.Data()))); |
ef12d5a5 | 590 | // place holder histos |
4292ca60 | 591 | TH1 *unfoldedLocalSVD(0x0); |
592 | TH1 *foldedLocalSVD(0x0); | |
593 | cout << " 2) setup necessary input " << endl; | |
51e6bc5a | 594 | // 3) configure routine |
595 | RooUnfold::ErrorTreatment errorTreatment = (fSVDToy) ? RooUnfold::kCovToy : RooUnfold::kCovariance; | |
20abfcc4 | 596 | // prior: use fit for where the histogram is sparsely filled |
ef12d5a5 | 597 | if(fSmoothenSpectrum) { // smoothen raw input jets in true and rec binning, and smoothen the prior |
4292ca60 | 598 | cachedRawJetLocalCoarse->Sumw2(); |
ef12d5a5 | 599 | TFitResultPtr r = cachedRawJetLocalCoarse->Fit(fPower, "QWILS", "", fFitMin, fFitMax); |
600 | if((int)r == 0) { | |
601 | for(Int_t i(1); i < cachedRawJetLocalCoarse->GetNbinsX() + 1; i++) { | |
602 | if(cachedRawJetLocalCoarse->GetBinCenter(i) > fFitStart) { | |
603 | cachedRawJetLocalCoarse->SetBinContent(i,fPower->Integral(cachedRawJetLocalCoarse->GetXaxis()->GetBinLowEdge(i),cachedRawJetLocalCoarse->GetXaxis()->GetBinUpEdge(i))/cachedRawJetLocalCoarse->GetXaxis()->GetBinWidth(i)); | |
604 | } | |
4292ca60 | 605 | } |
ef12d5a5 | 606 | } else printf(" > PANIC, SMOOTHENING FAILED < \n"); |
4292ca60 | 607 | TH1D* cachedRawJetLocalJagged((TH1D*)cachedRawJetLocal->Clone("cachedRawJetLocalJagged")); |
608 | cachedRawJetLocalJagged->SetNameTitle("measured spectrum before smoothening", "measured spectrum, before smoothening"); | |
609 | cachedRawJetLocalJagged->Write(); | |
610 | cachedRawJetLocal->Sumw2(); | |
ef12d5a5 | 611 | r = cachedRawJetLocal->Fit(fPower, "S", "", fFitMin, fFitMax); |
612 | if((int)r == 0) { | |
613 | for(Int_t i(0); i < cachedRawJetLocal->GetNbinsX() + 1; i++) { | |
614 | if(cachedRawJetLocal->GetBinCenter(i) > fFitStart) { // from this pt value use extrapolation | |
615 | cachedRawJetLocal->SetBinContent(i,fPower->Integral(cachedRawJetLocal->GetXaxis()->GetBinLowEdge(i),cachedRawJetLocal->GetXaxis()->GetBinUpEdge(i))/cachedRawJetLocal->GetXaxis()->GetBinWidth(i)); | |
616 | } | |
617 | } | |
618 | } | |
619 | r = unfoldedLocal->Fit(fPower, "S", "", fFitMin, fFitMax); | |
620 | if((int)r == 0) { | |
621 | for(Int_t i(0); i < unfoldedLocal->GetNbinsX() + 1; i++) { | |
622 | if(unfoldedLocal->GetBinCenter(i) > fFitStart) { // from this pt value use extrapolation | |
623 | unfoldedLocal->SetBinContent(i,fPower->Integral(unfoldedLocal->GetXaxis()->GetBinLowEdge(i),unfoldedLocal->GetXaxis()->GetBinUpEdge(i))/unfoldedLocal->GetXaxis()->GetBinWidth(i)); | |
624 | } | |
4292ca60 | 625 | } |
51e6bc5a | 626 | } |
4292ca60 | 627 | } |
628 | cout << " 3) configured routine " << endl; | |
629 | // 4) get transpose matrices | |
630 | // a) get the transpose matrix for the prior | |
631 | TH2* responseMatrixLocalTransposePrior(fResponseMaker->GetTransposeResponsMatrix(cachedResponseLocal)); | |
632 | responseMatrixLocalTransposePrior->SetNameTitle(Form("prior_%s_%s", responseMatrixLocalTransposePrior->GetName(), suffix.Data()),Form("prior_%s_%s", responseMatrixLocalTransposePrior->GetName(), suffix.Data())); | |
633 | // normalize it with the prior | |
ef12d5a5 | 634 | responseMatrixLocalTransposePrior = fResponseMaker->NormalizeResponsMatrixYaxisWithPrior(responseMatrixLocalTransposePrior, unfoldedLocal); |
4292ca60 | 635 | cout << " 4a) retrieved first transpose matrix " << endl; |
636 | // b) prior norm | |
637 | TH2* responseMatrixLocalTransposePriorNorm(fResponseMaker->GetTransposeResponsMatrix(cachedResponseLocalNorm)); | |
638 | responseMatrixLocalTransposePriorNorm->SetNameTitle(Form("prior_%s_%s", responseMatrixLocalTransposePriorNorm->GetName(), suffix.Data()),Form("prior_%s_%s", responseMatrixLocalTransposePriorNorm->GetName(), suffix.Data())); | |
639 | // normalize with the prior | |
640 | responseMatrixLocalTransposePriorNorm = fResponseMaker->NormalizeResponsMatrixYaxisWithPrior(responseMatrixLocalTransposePriorNorm, unfoldedLocal); | |
641 | cout << " 4b) retrieved second transpose matrix " << endl; | |
642 | ||
643 | // 5) get response for SVD unfolding | |
644 | RooUnfoldResponse responseSVD(0, 0, responseMatrixLocalTransposePrior, Form("respCombinedSVD_%s", suffix.Data()), Form("respCombinedSVD_%s", suffix.Data())); | |
51e6bc5a | 645 | |
4292ca60 | 646 | // change to inplane dir |
20abfcc4 | 647 | (!strcmp(suffix.Data(), "in")) ? fActiveDir->cd(Form("InPlane___%s", fActiveString.Data())) :fActiveDir->cd(Form("OutOfPlane___%s", fActiveString.Data())); |
4292ca60 | 648 | |
649 | cout << " 5) retrieved roo unfold response object " << endl; | |
650 | // 6) actualy unfolding loop | |
651 | RooUnfoldSvd unfoldSVD(&responseSVD, cachedRawJetLocal, (!strcmp(suffix.Data(), "in")) ? fSVDRegIn : fSVDRegOut); | |
20abfcc4 | 652 | unfoldedLocalSVD = (TH1D*)unfoldSVD.Hreco(errorTreatment); |
653 | TMatrixD covarianceMatrix = unfoldSVD.Ereco(errorTreatment); | |
654 | TMatrixD *pearson = (TMatrixD*)CalculatePearsonCoefficients(&covarianceMatrix); | |
ef12d5a5 | 655 | cout << " Pearson coeffs" << endl; |
4292ca60 | 656 | // create the unfolding qa plots |
657 | cout << " 6) unfolded spectrum " << endl; | |
658 | if(pearson) { | |
659 | TH2D* hPearson = new TH2D(*pearson); | |
660 | pearson->Print(); | |
661 | hPearson->SetNameTitle("PearsonCoefficients", "Pearson coefficients"); | |
662 | hPearson->Write(); | |
663 | } else return kFALSE; // return if unfolding didn't converge | |
664 | // correct for the efficiency | |
ef12d5a5 | 665 | unfoldedLocalSVD->Divide(kinematicEfficiencyLocal); |
4292ca60 | 666 | |
667 | // plot singular values and d_i vector | |
20abfcc4 | 668 | TSVDUnfold* svdUnfold(unfoldSVD.Impl()); |
51e6bc5a | 669 | TH1* hSVal(svdUnfold->GetSV()); |
670 | TH1D* hdi(svdUnfold->GetD()); | |
4292ca60 | 671 | hSVal->SetNameTitle("SingularValuesOfAC", "Singular values of AC^{-1}"); |
51e6bc5a | 672 | hSVal->SetXTitle("singular values"); |
673 | hSVal->Write(); | |
4292ca60 | 674 | hdi->SetNameTitle("dVector", "d vector after orthogonal transformation"); |
51e6bc5a | 675 | hdi->SetXTitle("|d_{i}^{kreg}|"); |
676 | hdi->Write(); | |
4292ca60 | 677 | cout << " plotted singular values and d_i vector " << endl; |
678 | ||
679 | // 7) refold the unfolded spectrum | |
680 | foldedLocalSVD = fResponseMaker->MultiplyResponseGenerated(unfoldedLocalSVD, cachedResponseLocalNorm,kinematicEfficiencyLocal); | |
681 | TGraphErrors* ratio(GetRatio(cachedRawJetLocal, foldedLocalSVD, "ratio measured / re-folded")); | |
682 | ratio->GetXaxis()->SetTitle("p_{t}^{rec, rec} [GeV/ c]"); | |
683 | ratio->GetYaxis()->SetTitle("ratio measured / re-folded"); | |
684 | ratio->Write(); | |
685 | cout << " 7) refolded the unfolded spectrum " << endl; | |
686 | ||
687 | // write to output | |
688 | cachedRawJetLocal->SetNameTitle("input spectrum","input spectrum (measured)"); | |
689 | cachedRawJetLocal->SetXTitle("p_{t}^{rec} [GeV/c]"); | |
690 | cachedRawJetLocal->Write(); // input spectrum | |
691 | unfoldedLocalSVD->SetNameTitle("unfolded spectrum","unfolded spectrum"); | |
692 | unfoldedLocalSVD->Write(); // unfolded spectrum | |
693 | foldedLocalSVD->SetNameTitle(Form("refoldedSpectrum_%s", suffix.Data()), Form("refoldedSpectrum_%s", suffix.Data())); | |
694 | foldedLocalSVD->Write(); // re-folded spectrum | |
695 | // switch back to active root directory | |
20abfcc4 | 696 | (!strcmp(suffix.Data(), "in")) ? fActiveDir->cd(Form("InPlane___%s", fActiveString.Data())) :fActiveDir->cd(Form("OutOfPlane___%s", fActiveString.Data())); |
4292ca60 | 697 | responseMatrixLocalTransposePrior->SetNameTitle("TransposeResponseMatrix", "Transpose of response matrix"); |
698 | responseMatrixLocalTransposePrior->SetXTitle("p_{T}^{true} [GeV/c]"); | |
699 | responseMatrixLocalTransposePrior->SetYTitle("p_{T}^{rec} [GeV/c]"); | |
700 | responseMatrixLocalTransposePrior->Write(); | |
701 | cachedRawJetLocal->SetNameTitle("PriorOriginal", "Prior, original"); | |
702 | cachedRawJetLocal->SetXTitle("p_{t} [GeV/c]"); | |
703 | cachedRawJetLocalCoarse->SetNameTitle("PriorSmoothened", "Prior, smoothened"); | |
704 | cachedRawJetLocalCoarse->SetXTitle("p_{t} [GeV/c]"); | |
705 | cachedRawJetLocalCoarse->Write(); | |
706 | cachedRawJetLocalCoarseOrig->SetNameTitle("Prior", "Prior"); | |
707 | cachedRawJetLocalCoarseOrig->SetXTitle("p_{t} [GeV/c]"); | |
708 | cachedRawJetLocalCoarseOrig->Write(); | |
709 | unfolded = (TH1D*)unfoldedLocalSVD; | |
ef12d5a5 | 710 | cachedResponseLocalNorm = ProtectHeap(cachedResponseLocalNorm); |
711 | cachedResponseLocalNorm->Write(); | |
20abfcc4 | 712 | return (unfoldedLocalSVD) ? kTRUE : kFALSE; |
51e6bc5a | 713 | } |
714 | //_____________________________________________________________________________ | |
dc1455ee | 715 | Bool_t AliJetFlowTools::PrepareForUnfolding() |
716 | { | |
717 | // prepare for unfolding | |
4292ca60 | 718 | if(fRawInputProvided) return kTRUE; |
dc1455ee | 719 | if(!fInputList) { |
720 | printf(" AliJetFlowTools::PrepareForUnfolding() fInputList not found \n - Set a list using AliJetFlowTools::SetInputList() \n"); | |
721 | return kFALSE; | |
722 | } | |
723 | if(!fDetectorResponse) { | |
724 | printf(" AliJetFlowTools::PrepareForUnfolding() fDetectorResponse not found \n - Set detector response using AliJetFlowTools::SetDetectorResponse() \n "); | |
725 | return kFALSE; | |
726 | } | |
4292ca60 | 727 | // check if the pt bin for true and rec have been set |
728 | if(!fBinsTrue || !fBinsRec) { | |
729 | printf(" AliJetFlowTools::PrepareForUnfolding() no true or rec bins set, aborting ! \n"); | |
730 | return kFALSE; | |
dc1455ee | 731 | } |
4292ca60 | 732 | if(!fRMSSpectrumIn) { // initialie the profiles which will hold the RMS values. if binning changes in between unfolding |
733 | // procedures, these profiles will be nonsensical, user is responsible | |
734 | fRMSSpectrumIn = new TProfile("fRMSSpectrumIn", "fRMSSpectrumIn", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()); | |
735 | fRMSSpectrumOut = new TProfile("fRMSSpectrumOut", "fRMSSpectrumOut", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()); | |
736 | fRMSRatio = new TProfile("fRMSRatio", "fRMSRatio", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()); | |
dc1455ee | 737 | } |
ef12d5a5 | 738 | if(!fTrainPower) { |
739 | for(Int_t i(0); i < fPower->GetNpar(); i++) fPower->SetParameter(i, 0.); | |
740 | } | |
dc1455ee | 741 | // extract the spectra |
742 | TString spectrumName(Form("fHistJetPsi2Pt_%i", fCentralityBin)); | |
ad04a83c | 743 | fJetPtDeltaPhi = ((TH2D*)fInputList->FindObject(spectrumName.Data())); |
744 | if(!fJetPtDeltaPhi) { | |
dc1455ee | 745 | printf(" Couldn't find spectrum %s ! \n", spectrumName.Data()); |
746 | return kFALSE; | |
747 | } | |
4292ca60 | 748 | fJetPtDeltaPhi = ProtectHeap(fJetPtDeltaPhi, kFALSE); |
dc1455ee | 749 | // in plane spectrum |
ef12d5a5 | 750 | if(fNoDphi) { |
751 | fSpectrumIn = fJetPtDeltaPhi->ProjectionY(Form("_py_in_%s", spectrumName.Data()), 1, 40); | |
752 | fSpectrumOut = fJetPtDeltaPhi->ProjectionY(Form("_py_out_%s", spectrumName.Data()), 1, 40); | |
753 | } else { | |
754 | fSpectrumIn = fJetPtDeltaPhi->ProjectionY(Form("_py_ina_%s", spectrumName.Data()), 1, 10); | |
755 | fSpectrumIn->Add(fJetPtDeltaPhi->ProjectionY(Form("_py_inb_%s", spectrumName.Data()), 31, 40)); | |
756 | fSpectrumIn = ProtectHeap(fSpectrumIn); | |
757 | // out of plane spectrum | |
758 | fSpectrumOut = fJetPtDeltaPhi->ProjectionY(Form("_py_out_%s", spectrumName.Data()), 11, 30); | |
759 | fSpectrumOut = ProtectHeap(fSpectrumOut); | |
760 | } | |
20abfcc4 | 761 | // normalize spectra to event count if requested |
762 | if(fNormalizeSpectra) { | |
763 | TH1* rho((TH1*)fInputList->FindObject(Form("fHistRho_%i", fCentralityBin))); | |
ef12d5a5 | 764 | if(!rho) return 0x0; |
765 | Bool_t normalizeToFullSpectrum = (fEventCount < 0) ? kTRUE : kFALSE; | |
766 | if (normalizeToFullSpectrum) fEventCount = rho->GetEntries(); | |
20abfcc4 | 767 | if(fEventCount > 0) { |
4292ca60 | 768 | fSpectrumIn->Sumw2(); // necessary for correct error propagation of scale |
769 | fSpectrumOut->Sumw2(); | |
ef12d5a5 | 770 | Double_t pt(0); |
771 | // Double_t error(0); // lots of issues with the errors here ... | |
772 | for(Int_t i(0); i < fSpectrumIn->GetXaxis()->GetNbins(); i++) { | |
4292ca60 | 773 | pt = fSpectrumIn->GetBinContent(1+i)/fEventCount; // normalized count |
ef12d5a5 | 774 | // error = 1./((double)(fEventCount*fEventCount))*fSpectrumIn->GetBinError(1+i)*fSpectrumIn->GetBinError(1+i); |
4292ca60 | 775 | fSpectrumIn->SetBinContent(1+i, pt); |
ef12d5a5 | 776 | if(pt <= 0 ) fSpectrumIn->SetBinError(1+i, 0.); |
777 | // if(error > 0) fSpectrumIn->SetBinError(1+i, TMath::Sqrt(error)); | |
778 | else fSpectrumIn->SetBinError(1+i, TMath::Sqrt(pt)); | |
4292ca60 | 779 | } |
ef12d5a5 | 780 | for(Int_t i(0); i < fSpectrumOut->GetXaxis()->GetNbins(); i++) { |
781 | pt = fSpectrumOut->GetBinContent(1+i)/fEventCount; // normalized count | |
782 | // error = 1./((double)(fEventCount*fEventCount))*fSpectrumOut->GetBinError(1+i)*fSpectrumOut->GetBinError(1+i); | |
783 | fSpectrumOut->SetBinContent(1+i, pt); | |
784 | if( pt <= 0) fSpectrumOut->SetBinError(1+i, 0.); | |
785 | // if(error > 0) fSpectrumOut->SetBinError(1+i, TMath::Sqrt(error)); | |
786 | else fSpectrumOut->SetBinError(1+i, TMath::Sqrt(pt)); | |
4292ca60 | 787 | } |
20abfcc4 | 788 | } |
ef12d5a5 | 789 | if(normalizeToFullSpectrum) fEventCount = -1; |
20abfcc4 | 790 | } |
dc1455ee | 791 | // extract the delta pt matrices |
792 | TString deltaptName(Form("fHistDeltaPtDeltaPhi2_%i", fCentralityBin)); | |
ad04a83c | 793 | fDeltaPtDeltaPhi = ((TH2D*)fInputList->FindObject(deltaptName.Data())); |
794 | if(!fDeltaPtDeltaPhi) { | |
dc1455ee | 795 | printf(" Couldn't find delta pt matrix %s ! \n", deltaptName.Data()); |
796 | } | |
4292ca60 | 797 | fDeltaPtDeltaPhi = ProtectHeap(fDeltaPtDeltaPhi, kFALSE); |
798 | // in plane delta pt distribution | |
ef12d5a5 | 799 | if(fNoDphi) { |
800 | fDptInDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_in_%s", deltaptName.Data()), 1, 40); | |
801 | fDptOutDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_out_%s", deltaptName.Data()), 1, 40); | |
802 | } else { | |
803 | fDptInDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_ina_%s", deltaptName.Data()), 1, 10); | |
804 | fDptInDist->Add(fDeltaPtDeltaPhi->ProjectionY(Form("_py_inb_%s", deltaptName.Data()), 31, 40)); | |
805 | // out of plane delta pt distribution | |
806 | fDptOutDist = fDeltaPtDeltaPhi->ProjectionY(Form("_py_out_%s", deltaptName.Data()), 11, 30); | |
807 | fDptInDist = ProtectHeap(fDptInDist); | |
808 | fDptOutDist = ProtectHeap(fDptOutDist); | |
809 | // TODO get dpt response matrix from ConstructDPtResponseFromTH1D | |
810 | } | |
4292ca60 | 811 | |
dc1455ee | 812 | // create a rec - true smeared response matrix |
813 | TMatrixD* rfIn = new TMatrixD(-50, 249, -50, 249); | |
814 | for(Int_t j(-50); j < 250; j++) { // loop on pt true slices j | |
ad04a83c | 815 | Bool_t skip = kFALSE; |
dc1455ee | 816 | for(Int_t k(-50); k < 250; k++) { // loop on pt gen slices k |
ad04a83c | 817 | (*rfIn)(k, j) = (skip) ? 0. : fDptInDist->GetBinContent(fDptInDist->GetXaxis()->FindBin(k-j)); |
818 | if(fAvoidRoundingError && k > j && TMath::AreEqualAbs(fDptInDist->GetBinContent(fDptInDist->GetXaxis()->FindBin(k-j)), 0, 1e-8)) skip = kTRUE; | |
dc1455ee | 819 | } |
820 | } | |
821 | TMatrixD* rfOut = new TMatrixD(-50, 249, -50, 249); | |
822 | for(Int_t j(-50); j < 250; j++) { // loop on pt true slices j | |
ad04a83c | 823 | Bool_t skip = kFALSE; |
dc1455ee | 824 | for(Int_t k(-50); k < 250; k++) { // loop on pt gen slices k |
ad04a83c | 825 | (*rfOut)(k, j) = (skip) ? 0. : fDptOutDist->GetBinContent(fDptOutDist->GetXaxis()->FindBin(k-j)); |
826 | if(fAvoidRoundingError && k > j && TMath::AreEqualAbs(fDptOutDist->GetBinContent(fDptOutDist->GetXaxis()->FindBin(k-j)), 0, 1e-8)) skip = kTRUE; | |
dc1455ee | 827 | } |
828 | } | |
829 | fDptIn = new TH2D(*rfIn); | |
830 | fDptIn->SetNameTitle(Form("dpt_response_INPLANE_%i", fCentralityBin), Form("dpt_response_INPLANE_%i", fCentralityBin)); | |
831 | fDptIn->GetXaxis()->SetTitle("p_{T}^{gen} [GeV/c]"); | |
832 | fDptIn->GetYaxis()->SetTitle("p_{T}^{rec} [GeV/c]"); | |
4292ca60 | 833 | fDptIn = ProtectHeap(fDptIn); |
dc1455ee | 834 | fDptOut = new TH2D(*rfOut); |
835 | fDptOut->SetNameTitle(Form("dpt_response_OUTOFPLANE_%i", fCentralityBin), Form("dpt_response_OUTOFPLANE_%i", fCentralityBin)); | |
836 | fDptOut->GetXaxis()->SetTitle("p_{T}^{gen} [GeV/c]"); | |
837 | fDptOut->GetYaxis()->SetTitle("p_{T}^{rec} [GeV/c]"); | |
4292ca60 | 838 | fDptOut = ProtectHeap(fDptOut); |
839 | ||
840 | fRefreshInput = kTRUE; // force cloning of the input | |
dc1455ee | 841 | return kTRUE; |
842 | } | |
843 | //_____________________________________________________________________________ | |
844 | TH1D* AliJetFlowTools::ResizeXaxisTH1D(TH1D* histo, Int_t low, Int_t up, TString suffix) { | |
845 | // resize the x-axis of a th1d | |
846 | if(!histo) { | |
847 | printf(" > ResizeXaxisTH!D:: fatal error, NULL pointer passed < \n"); | |
848 | return NULL; | |
849 | } | |
850 | // see how many bins we need to copy | |
851 | 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); | |
852 | // low is the bin number of the first new bin | |
853 | Int_t l = histo->GetXaxis()->FindBin(low); | |
854 | // set the values | |
855 | Double_t _x(0), _xx(0); | |
856 | for(Int_t i(0); i < up-low; i++) { | |
857 | _x = histo->GetBinContent(l+i); | |
858 | _xx=histo->GetBinError(l+i); | |
859 | resized->SetBinContent(i+1, _x); | |
860 | resized->SetBinError(i+1, _xx); | |
861 | } | |
862 | return resized; | |
863 | } | |
864 | //_____________________________________________________________________________ | |
865 | TH2D* AliJetFlowTools::ResizeYaxisTH2D(TH2D* histo, TArrayD* x, TArrayD* y, TString suffix) { | |
866 | // resize the y-axis of a th2d | |
867 | if(!histo) { | |
868 | printf(" > ResizeYaxisTH2D:: fatal error, NULL pointer passed < \n"); | |
869 | return NULL; | |
870 | } | |
871 | // see how many bins we need to copy | |
872 | 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()); | |
873 | // assume only the y-axis has changed | |
874 | // low is the bin number of the first new bin | |
875 | Int_t low = histo->GetYaxis()->FindBin(y->At(0)); | |
876 | // set the values | |
877 | Double_t _x(0), _xx(0); | |
878 | for(Int_t i(0); i < x->GetSize(); i++) { | |
879 | for(Int_t j(0); j < y->GetSize(); j++) { | |
880 | _x = histo->GetBinContent(i, low+j); | |
881 | _xx=histo->GetBinError(i, low+1+j); | |
882 | resized->SetBinContent(i, j, _x); | |
883 | resized->SetBinError(i, j, _xx); | |
884 | } | |
885 | } | |
886 | return resized; | |
887 | } | |
888 | //_____________________________________________________________________________ | |
889 | TH2D* AliJetFlowTools::NormalizeTH2D(TH2D* histo) { | |
890 | // general method to normalize all vertical slices of a th2 to unity | |
891 | // i.e. get a probability matrix | |
892 | if(!histo) { | |
893 | printf(" > NormalizeTH2D:: fatal error, NULL pointer passed < \n"); | |
894 | return NULL; | |
895 | } | |
896 | Int_t binsX = histo->GetXaxis()->GetNbins(); | |
897 | Int_t binsY = histo->GetYaxis()->GetNbins(); | |
898 | ||
899 | // normalize all slices in x | |
900 | for(Int_t i(0); i < binsX; i++) { // for each vertical slice | |
901 | Double_t weight = 0; | |
902 | for(Int_t j(0); j < binsY; j++) { // loop over all the horizontal components | |
903 | weight+=histo->GetBinContent(i+1, j+1); | |
904 | } // now we know the total weight | |
905 | for(Int_t j(0); j < binsY; j++) { | |
906 | if (weight <= 0 ) continue; | |
907 | histo->SetBinContent(1+i, j+1, histo->GetBinContent(1+i, j+1)/weight); | |
908 | histo->SetBinError( 1+i, j+1, histo->GetBinError( 1+i, j+1)/weight); | |
909 | } | |
910 | } | |
911 | return histo; | |
912 | } | |
913 | //_____________________________________________________________________________ | |
914 | TH1D* AliJetFlowTools::GetUnfoldingTemplate(TH1D* histo, TArrayD* bins, TString suffix) { | |
915 | // return a TH1D with the supplied histogram rebinned to the supplied bins | |
916 | // this histogram will be used as a startng point for the chi^2 minimization | |
4292ca60 | 917 | // the returned histogram is new |
dc1455ee | 918 | if(!histo || !bins) { |
919 | printf(" > RebinTH2D:: fatal error, NULL pointer passed < \n"); | |
920 | return NULL; | |
921 | } | |
922 | // create the output histo | |
923 | TString name = histo->GetName(); | |
924 | name+="_template"; | |
925 | name+=suffix; | |
926 | TH1D* rebinned = new TH1D(name.Data(), name.Data(), bins->GetSize()-1, bins->GetArray()); | |
927 | for(Int_t i(0); i < histo->GetXaxis()->GetNbins(); i++) { | |
4292ca60 | 928 | // loop over the bins of the old histo and fill the new one with its data |
929 | rebinned->Fill(histo->GetBinCenter(i+1), histo->GetBinContent(i+1)); | |
dc1455ee | 930 | } |
931 | return rebinned; | |
932 | } | |
933 | //_____________________________________________________________________________ | |
4292ca60 | 934 | TH2D* AliJetFlowTools::RebinTH2D(TH2D* rebinMe, TArrayD* binsTrue, TArrayD* binsRec, TString suffix) { |
935 | if(!fResponseMaker || !binsTrue || !binsRec) { | |
936 | printf(" > RebinTH2D:: function called with NULL arguments < \n"); | |
937 | return 0x0; | |
dc1455ee | 938 | } |
4292ca60 | 939 | TString name(Form("%s_%s", rebinMe->GetName(), suffix.Data())); |
940 | return (TH2D*)fResponseMaker->MakeResponseMatrixRebin(rebinMe, (TH2*)(new TH2D(name.Data(), name.Data(), binsTrue->GetSize()-1, binsTrue->GetArray(), binsRec->GetSize()-1, binsRec->GetArray())), kTRUE); | |
dc1455ee | 941 | } |
942 | //_____________________________________________________________________________ | |
943 | TH2D* AliJetFlowTools::MatrixMultiplicationTH2D(TH2D* A, TH2D* B, TString name) { | |
944 | // general matrix multiplication | |
945 | if(!A || !B) { | |
946 | printf(" > MatrixMultiplicationTH2D:: fatal error, NULL pointer passed < \n"); | |
947 | return NULL; | |
948 | } | |
949 | // step A -> see if the matrices are both square and of equal dimensions | |
950 | Int_t aX(A->GetXaxis()->GetNbins()); | |
951 | Int_t aY(A->GetYaxis()->GetNbins()); | |
952 | Int_t bX(B->GetXaxis()->GetNbins()); | |
953 | Int_t bY(B->GetYaxis()->GetNbins()); | |
954 | if(!(aX == aY && aX == bX && aX == bY)) { | |
955 | printf(" > MatrixMultiplicationTH2D:: Error, matrices with incompatible dimensions passed ! < \n"); | |
956 | printf(" - matrix A (%i, %i) \n", aX, aY); | |
957 | printf(" - matrix B (%i, %i) \n", bX, bY); | |
958 | return NULL; | |
959 | } | |
960 | ||
961 | // step B -> setup a new matrix template to store the results | |
962 | TH2D* C = (TH2D*)A->Clone(); | |
963 | C->SetNameTitle(name.Data(), name.Data()); | |
964 | C->GetXaxis()->SetTitle("p_{T}^{gen} [GeV/c]"); | |
965 | C->GetYaxis()->SetTitle("p_{T}^{rec} [GeV/c]"); | |
966 | ||
967 | // step C -> nested loop multiplication | |
968 | printf ( " >> parsing matrix data, may take some time (depending on matrix dimensions) << \n"); | |
969 | for(Int_t i(0); i < aX; i++) { // x coordinate of target matrix | |
970 | for(Int_t j(0); j < aY; j++) { // y coordinate of target matrix | |
971 | ||
51e6bc5a | 972 | // the coordinate of the target matrix (x, y) is the dot |
973 | // product of row x of matrix A with column y of matrix B | |
dc1455ee | 974 | // so in this nexted loop, we need to fill point i, j of the target matrix |
975 | // with the dot product of | |
976 | // matrix A) row i \cdotp matrix B) column j | |
977 | // looping through a row means that y remains constant | |
978 | // looping through a column means that x remains constant | |
979 | ||
980 | Double_t value(0); // placeholder for target value | |
981 | for(Int_t x(0); x < aX; x++) value += A->GetBinContent(x, i) * B->GetBinContent(j, x); | |
982 | C->SetBinContent(i, j); | |
983 | } | |
984 | } | |
985 | return C; | |
986 | } | |
987 | //_____________________________________________________________________________ | |
988 | TH1D* AliJetFlowTools::NormalizeTH1D(TH1D* histo, Double_t scale) { | |
989 | // normalize a th1d to a certain scale | |
4292ca60 | 990 | histo->Sumw2(); |
991 | Double_t integral = histo->Integral()*scale; | |
992 | if (integral > 0 && scale == 1.) histo->Scale(1./integral, "width"); | |
993 | else if (scale != 1.) histo->Scale(1./scale, "width"); | |
994 | else printf(" > Histogram integral < 0, cannot normalize \n"); | |
995 | return histo; | |
dc1455ee | 996 | } |
997 | //_____________________________________________________________________________ | |
51e6bc5a | 998 | TMatrixD* AliJetFlowTools::CalculatePearsonCoefficients(TMatrixD* covarianceMatrix) |
dc1455ee | 999 | { |
1000 | // Calculate pearson coefficients from covariance matrix | |
51e6bc5a | 1001 | TMatrixD *pearsonCoefficients((TMatrixD*)covarianceMatrix->Clone("pearsonCoefficients")); |
1002 | Int_t nrows(covarianceMatrix->GetNrows()), ncols(covarianceMatrix->GetNcols()); | |
ad04a83c | 1003 | Double_t pearson(0.); |
dc1455ee | 1004 | if(nrows==0 && ncols==0) return 0x0; |
ef12d5a5 | 1005 | for(Int_t row = 0; row < nrows; row++) { |
1006 | for(Int_t col = 0; col<ncols; col++) { | |
51e6bc5a | 1007 | if((*covarianceMatrix)(row,row)!=0. && (*covarianceMatrix)(col,col)!=0.) pearson = (*covarianceMatrix)(row,col)/TMath::Sqrt((*covarianceMatrix)(row,row)*(*covarianceMatrix)(col,col)); |
1008 | (*pearsonCoefficients)(row,col) = pearson; | |
dc1455ee | 1009 | } |
1010 | } | |
51e6bc5a | 1011 | return pearsonCoefficients; |
dc1455ee | 1012 | } |
1013 | //_____________________________________________________________________________ | |
4292ca60 | 1014 | Bool_t AliJetFlowTools::SetRawInput ( |
1015 | TH2D* detectorResponse, // detector response matrix | |
1016 | TH1D* jetPtIn, // in plane jet spectrum | |
1017 | TH1D* jetPtOut, // out of plane jet spectrum | |
1018 | TH1D* dptIn, // in plane delta pt distribution | |
1019 | TH1D* dptOut, // out of plane delta pt distribution | |
1020 | Int_t eventCount) { | |
1021 | // set input histograms manually | |
1022 | fDetectorResponse = detectorResponse; | |
1023 | fSpectrumIn = jetPtIn; | |
1024 | fSpectrumOut = jetPtOut; | |
1025 | fDptInDist = dptIn; | |
1026 | fDptOutDist = dptOut; | |
1027 | fRawInputProvided = kTRUE; | |
1028 | // check if all data is provided | |
1029 | if(!fDetectorResponse) { | |
1030 | printf(" fDetectorResponse not found \n "); | |
1031 | return kFALSE; | |
1032 | } | |
1033 | // check if the pt bin for true and rec have been set | |
1034 | if(!fBinsTrue || !fBinsRec) { | |
1035 | printf(" No true or rec bins set, please set binning ! \n"); | |
1036 | return kFALSE; | |
1037 | } | |
1038 | if(!fRMSSpectrumIn) { // initialie the profiles which will hold the RMS values. if binning changes in between unfolding | |
1039 | // procedures, these profiles will be nonsensical, user is responsible | |
1040 | fRMSSpectrumIn = new TProfile("fRMSSpectrumIn", "fRMSSpectrumIn", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()); | |
1041 | fRMSSpectrumOut = new TProfile("fRMSSpectrumOut", "fRMSSpectrumOut", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()); | |
1042 | fRMSRatio = new TProfile("fRMSRatio", "fRMSRatio", fBinsTrue->GetSize()-1, fBinsTrue->GetArray()); | |
1043 | } | |
1044 | // normalize spectra to event count if requested | |
1045 | if(fNormalizeSpectra) { | |
1046 | fEventCount = eventCount; | |
1047 | if(fEventCount > 0) { | |
1048 | fSpectrumIn->Sumw2(); // necessary for correct error propagation of scale | |
1049 | fSpectrumOut->Sumw2(); | |
1050 | fSpectrumIn->Scale(1./((double)fEventCount)); | |
1051 | fSpectrumOut->Scale(1./((double)fEventCount)); | |
1052 | } | |
1053 | } | |
1054 | if(!fNormalizeSpectra && fEventCount > 0) { | |
1055 | fSpectrumIn->Sumw2(); // necessary for correct error propagation of scale | |
1056 | fSpectrumOut->Sumw2(); | |
1057 | fSpectrumIn->Scale(1./((double)fEventCount)); | |
1058 | fSpectrumOut->Scale(1./((double)fEventCount)); | |
1059 | } | |
1060 | fDptIn = ConstructDPtResponseFromTH1D(fDptInDist, fAvoidRoundingError); | |
1061 | fDptIn->SetNameTitle(Form("dpt_response_INPLANE_%i", fCentralityBin), Form("dpt_response_INPLANE_%i", fCentralityBin)); | |
1062 | fDptIn->GetXaxis()->SetTitle("p_{T}^{gen} [GeV/c]"); | |
1063 | fDptIn->GetYaxis()->SetTitle("p_{T}^{rec} [GeV/c]"); | |
1064 | fDptOut = ConstructDPtResponseFromTH1D(fDptOutDist, fAvoidRoundingError); | |
1065 | fDptOut->SetNameTitle(Form("dpt_response_OUTOFPLANE_%i", fCentralityBin), Form("dpt_response_OUTOFPLANE_%i", fCentralityBin)); | |
1066 | fDptOut->GetXaxis()->SetTitle("p_{T}^{gen} [GeV/c]"); | |
1067 | fDptOut->GetYaxis()->SetTitle("p_{T}^{rec} [GeV/c]"); | |
1068 | ||
1069 | return kTRUE; | |
1070 | } | |
1071 | //_____________________________________________________________________________ | |
1072 | TGraphErrors* AliJetFlowTools::GetRatio(TH1 *h1, TH1* h2, TString name, Bool_t appendFit, Int_t xmax) | |
dc1455ee | 1073 | { |
ef12d5a5 | 1074 | // return ratio of h1 / h2 |
1075 | // histograms can have different binning. errors are propagated as uncorrelated | |
20abfcc4 | 1076 | if(!(h1 && h2) ) { |
1077 | printf(" GetRatio called with NULL argument(s) \n "); | |
1078 | return 0x0; | |
1079 | } | |
ad04a83c | 1080 | Int_t j(0); |
4292ca60 | 1081 | TGraphErrors *gr = new TGraphErrors(); |
ef12d5a5 | 1082 | Double_t binCent(0.), ratio(0.), error2(0.), binWidth(0.); |
4292ca60 | 1083 | for(Int_t i(1); i <= h1->GetNbinsX(); i++) { |
dc1455ee | 1084 | binCent = h1->GetXaxis()->GetBinCenter(i); |
4292ca60 | 1085 | if(xmax > 0. && binCent > xmax) continue; |
dc1455ee | 1086 | j = h2->FindBin(binCent); |
1087 | binWidth = h1->GetXaxis()->GetBinWidth(i); | |
ad04a83c | 1088 | if(h2->GetBinContent(j) > 0.) { |
dc1455ee | 1089 | ratio = h1->GetBinContent(i)/h2->GetBinContent(j); |
1090 | Double_t A = 1./h2->GetBinContent(j)*h1->GetBinError(i); | |
4292ca60 | 1091 | Double_t B = 0.; |
1092 | if(h2->GetBinError(j)>0.) { | |
1093 | B = -1.*h1->GetBinContent(i)/(h2->GetBinContent(j)*h2->GetBinContent(j))*h2->GetBinError(j); | |
1094 | error2 = A*A + B*B; | |
ef12d5a5 | 1095 | } else error2 = A*A; |
1096 | if(error2 > 0 ) error2 = TMath::Sqrt(error2); | |
dc1455ee | 1097 | gr->SetPoint(gr->GetN(),binCent,ratio); |
ef12d5a5 | 1098 | gr->SetPointError(gr->GetN()-1,0.5*binWidth,error2); |
dc1455ee | 1099 | } |
1100 | } | |
ad04a83c | 1101 | if(appendFit) { |
4292ca60 | 1102 | TF1* fit(new TF1("lin", "pol0", 10, 100)); |
ad04a83c | 1103 | gr->Fit(fit); |
1104 | } | |
4292ca60 | 1105 | if(strcmp(name, "")) gr->SetNameTitle(name.Data(), name.Data()); |
dc1455ee | 1106 | return gr; |
1107 | } | |
1108 | //_____________________________________________________________________________ | |
ef12d5a5 | 1109 | TGraphErrors* AliJetFlowTools::GetV2(TH1 *h1, TH1* h2, Double_t r, TString name) |
1110 | { | |
1111 | // get v2 from difference of in plane, out of plane yield | |
1112 | // h1 must hold the in-plane yield, h2 holds the out of plane yield | |
1113 | // different binning is allowed | |
1114 | // r is the event plane resolution for the chosen centrality | |
1115 | if(!(h1 && h2) ) { | |
1116 | printf(" GetV2 called with NULL argument(s) \n "); | |
1117 | return 0x0; | |
1118 | } | |
1119 | Int_t j(0); | |
1120 | TGraphErrors *gr = new TGraphErrors(); | |
1121 | Float_t binCent(0.), ratio(0.), error2(0.), binWidth(0.); | |
1122 | Double_t pre(TMath::Pi()/(4.*r)), in(0.), out(0.), ein(0.), eout(0.); | |
1123 | for(Int_t i(1); i <= h1->GetNbinsX(); i++) { | |
1124 | binCent = h1->GetXaxis()->GetBinCenter(i); | |
1125 | j = h2->FindBin(binCent); | |
1126 | binWidth = h1->GetXaxis()->GetBinWidth(i); | |
1127 | if(h2->GetBinContent(j) > 0.) { | |
1128 | in = h1->GetBinContent(i); | |
1129 | ein = h1->GetBinError(i); | |
1130 | out = h2->GetBinContent(j); | |
1131 | eout = h2->GetBinError(j); | |
1132 | ratio = pre*((in-out)/(in+out)); | |
1133 | error2 = (r*4.)/(TMath::Pi())*((out*out/(TMath::Power(in+out, 4)))*ein*ein+(in*in/(TMath::Power(in+out, 4)))*eout*eout); | |
1134 | if(error2 > 0) error2 = TMath::Sqrt(error2); | |
1135 | gr->SetPoint(gr->GetN(),binCent,ratio); | |
1136 | gr->SetPointError(gr->GetN()-1,0.5*binWidth,error2); | |
1137 | } | |
1138 | } | |
1139 | if(strcmp(name, "")) gr->SetNameTitle(name.Data(), name.Data()); | |
1140 | return gr; | |
1141 | } | |
1142 | //_____________________________________________________________________________ | |
4292ca60 | 1143 | void AliJetFlowTools::WriteObject(TObject* object) { |
1144 | // write object with unique identifier to active TDirectoryFile | |
1145 | if(!object) { | |
1146 | printf(" > WriteObject:: called with NULL arguments \n "); | |
1147 | return; | |
1148 | } else object->Write(); | |
1149 | // FIXME to be implememnted | |
1150 | } | |
1151 | //_____________________________________________________________________________ | |
1152 | TH2D* AliJetFlowTools::ConstructDPtResponseFromTH1D(TH1D* dpt, Bool_t AvoidRoundingError) { | |
1153 | // construt a delta pt response matrix from supplied dpt distribution | |
1154 | // binning is fine, set fBinsTrue and fBinsRec and call 'RebinTH2D' to | |
1155 | // do a weighted rebinning to a (coarser) dpt distribution | |
1156 | // be careful with the binning of the dpt response: it should be equal to that | |
1157 | // of the response matrix, otherwise dpt and response matrices cannot be multiplied | |
1158 | // | |
1159 | // the response matrix will be square and have the same binning | |
1160 | // (min, max and granularity) of the input histogram | |
1161 | Int_t bins(dpt->GetXaxis()->GetNbins()); // number of bins, will also be no of rows, columns | |
1162 | Double_t _bins[bins+1]; // prepare array with bin borders | |
1163 | for(Int_t i(0); i < bins; i++) _bins[i] = dpt->GetBinLowEdge(i+1); | |
1164 | _bins[bins] = dpt->GetBinLowEdge(bins)+dpt->GetBinWidth(bins+1); // get upper edge | |
1165 | TH2D* res(new TH2D(Form("Response_from_%s", dpt->GetName()), Form("Response_from_%s", dpt->GetName()), bins, _bins, bins, _bins)); | |
1166 | for(Int_t j(0); j < bins+1; j++) { // loop on pt true slices j | |
1167 | Bool_t skip = kFALSE; | |
1168 | for(Int_t k(0); k < bins+1; k++) { // loop on pt gen slices k | |
1169 | (skip) ? res->SetBinContent(j, k, 0.) : res->SetBinContent(j, k, dpt->GetBinContent(dpt->GetXaxis()->FindBin(k-j))); | |
1170 | if(AvoidRoundingError && k > j && TMath::AreEqualAbs(dpt->GetBinContent(dpt->GetBinContent(k-j)), 0, 1e-8)) skip = kTRUE; | |
1171 | } | |
1172 | } | |
1173 | return res; | |
1174 | } | |
ef12d5a5 | 1175 | //_____________________________________________________________________________ |
1176 | TH2D* AliJetFlowTools::GetUnityResponse(TArrayD* binsTrue, TArrayD* binsRec, TString suffix) { | |
1177 | if(!binsTrue || !binsRec) { | |
1178 | printf(" > GetUnityResponse:: function called with NULL arguments < \n"); | |
1179 | return 0x0; | |
1180 | } | |
1181 | TString name(Form("unityResponse_%s", suffix.Data())); | |
1182 | TH2D* unity(new TH2D(name.Data(), name.Data(), binsTrue->GetSize()-1, binsTrue->GetArray(), binsRec->GetSize()-1, binsRec->GetArray())); | |
1183 | for(Int_t i(0); i < binsTrue->GetSize(); i++) { | |
1184 | for(Int_t j(0); j < binsRec->GetSize(); j++) { | |
1185 | if(i==j) unity->SetBinContent(1+i, 1+j, 1.); | |
1186 | } | |
1187 | } | |
1188 | return unity; | |
1189 | } | |
4292ca60 | 1190 | //_____________________________________________________________________________ |
1191 | void AliJetFlowTools::SaveConfiguration(Bool_t convergedIn, Bool_t convergedOut) { | |
1192 | // save configuration parameters to histogram | |
ef12d5a5 | 1193 | TH1F* summary = new TH1F("UnfoldingConfiguration","UnfoldingConfiguration", 16, -.5, 16.5); |
1194 | summary->SetBinContent(1, fBetaIn); | |
1195 | summary->GetXaxis()->SetBinLabel(1, "fBetaIn"); | |
1196 | summary->SetBinContent(2, fBetaOut); | |
1197 | summary->GetXaxis()->SetBinLabel(2, "fBetaOut"); | |
1198 | summary->SetBinContent(3, fCentralityBin); | |
1199 | summary->GetXaxis()->SetBinLabel(3, "fCentralityBin"); | |
1200 | summary->SetBinContent(4, (int)convergedIn); | |
1201 | summary->GetXaxis()->SetBinLabel(4, "convergedIn"); | |
1202 | summary->SetBinContent(5, (int)convergedOut); | |
1203 | summary->GetXaxis()->SetBinLabel(5, "convergedOut"); | |
1204 | summary->SetBinContent(6, (int)fAvoidRoundingError); | |
1205 | summary->GetXaxis()->SetBinLabel(6, "fAvoidRoundingError"); | |
1206 | summary->SetBinContent(7, (int)fUnfoldingAlgorithm); | |
1207 | summary->GetXaxis()->SetBinLabel(7, "fUnfoldingAlgorithm"); | |
1208 | summary->SetBinContent(8, (int)fPrior); | |
1209 | summary->GetXaxis()->SetBinLabel(8, "fPrior"); | |
1210 | summary->SetBinContent(9, fSVDRegIn); | |
1211 | summary->GetXaxis()->SetBinLabel(9, "fSVDRegIn"); | |
1212 | summary->SetBinContent(10, fSVDRegOut); | |
1213 | summary->GetXaxis()->SetBinLabel(10, "fSVDRegOut"); | |
1214 | summary->SetBinContent(11, (int)fSVDToy); | |
1215 | summary->GetXaxis()->SetBinLabel(11, "fSVDToy"); | |
1216 | summary->SetBinContent(12, fJetRadius); | |
1217 | summary->GetXaxis()->SetBinLabel(12, "fJetRadius"); | |
1218 | summary->SetBinContent(13, (int)fNormalizeSpectra); | |
1219 | summary->GetXaxis()->SetBinLabel(13, "fNormalizeSpectra"); | |
1220 | summary->SetBinContent(14, (int)fSmoothenSpectrum); | |
1221 | summary->GetXaxis()->SetBinLabel(14, "fSmoothenSpectrum"); | |
1222 | summary->SetBinContent(15, (int)fTestMode); | |
1223 | summary->GetXaxis()->SetBinLabel(15, "fTestMode"); | |
1224 | summary->SetBinContent(16, (int)fUseDetectorResponse); | |
1225 | summary->GetXaxis()->SetBinLabel(16, "fUseDetectorResponse"); | |
1226 | summary->Write(); | |
4292ca60 | 1227 | } |
1228 | //_____________________________________________________________________________ | |
1229 | void AliJetFlowTools::ResetAliUnfolding() { | |
1230 | // ugly function: reset all unfolding parameters | |
1231 | TVirtualFitter* fitter(TVirtualFitter::GetFitter()); | |
1232 | if(fitter) { | |
1233 | printf(" > Found fitter, will delete it < \n"); | |
1234 | delete fitter; | |
1235 | } | |
ef12d5a5 | 1236 | // if(gMinuit) { |
1237 | // printf(" > Found gMinuit, will re-create it < \n"); | |
1238 | // delete gMinuit; | |
1239 | // gMinuit = new TMinuit; | |
1240 | // } | |
4292ca60 | 1241 | AliUnfolding::fgCorrelationMatrix = 0; |
1242 | AliUnfolding::fgCorrelationMatrixSquared = 0; | |
1243 | AliUnfolding::fgCorrelationCovarianceMatrix = 0; | |
1244 | AliUnfolding::fgCurrentESDVector = 0; | |
1245 | AliUnfolding::fgEntropyAPriori = 0; | |
1246 | AliUnfolding::fgEfficiency = 0; | |
1247 | AliUnfolding::fgUnfoldedAxis = 0; | |
1248 | AliUnfolding::fgMeasuredAxis = 0; | |
1249 | AliUnfolding::fgFitFunction = 0; | |
1250 | AliUnfolding::fgMaxInput = -1; | |
1251 | AliUnfolding::fgMaxParams = -1; | |
1252 | AliUnfolding::fgOverflowBinLimit = -1; | |
1253 | AliUnfolding::fgRegularizationWeight = 10000; | |
1254 | AliUnfolding::fgSkipBinsBegin = 0; | |
1255 | AliUnfolding::fgMinuitStepSize = 0.1; | |
1256 | AliUnfolding::fgMinuitPrecision = 1e-6; | |
1257 | AliUnfolding::fgMinuitMaxIterations = 1000000; | |
1258 | AliUnfolding::fgMinuitStrategy = 1.; | |
1259 | AliUnfolding::fgMinimumInitialValue = kFALSE; | |
1260 | AliUnfolding::fgMinimumInitialValueFix = -1; | |
1261 | AliUnfolding::fgNormalizeInput = kFALSE; | |
1262 | AliUnfolding::fgNotFoundEvents = 0; | |
1263 | AliUnfolding::fgSkipBin0InChi2 = kFALSE; | |
1264 | AliUnfolding::fgBayesianSmoothing = 1; | |
1265 | AliUnfolding::fgBayesianIterations = 10; | |
1266 | AliUnfolding::fgDebug = kFALSE; | |
1267 | AliUnfolding::fgCallCount = 0; | |
1268 | AliUnfolding::fgPowern = 5; | |
1269 | AliUnfolding::fChi2FromFit = 0.; | |
1270 | AliUnfolding::fPenaltyVal = 0.; | |
1271 | AliUnfolding::fAvgResidual = 0.; | |
1272 | AliUnfolding::fgPrintChi2Details = 0; | |
1273 | AliUnfolding::fgCanvas = 0; | |
1274 | AliUnfolding::fghUnfolded = 0; | |
1275 | AliUnfolding::fghCorrelation = 0; | |
1276 | AliUnfolding::fghEfficiency = 0; | |
1277 | AliUnfolding::fghMeasured = 0; | |
1278 | AliUnfolding::SetMinuitStepSize(1.); | |
1279 | AliUnfolding::SetMinuitPrecision(1e-6); | |
1280 | AliUnfolding::SetMinuitMaxIterations(100000); | |
1281 | AliUnfolding::SetMinuitStrategy(2.); | |
1282 | AliUnfolding::SetDebug(1); | |
1283 | } | |
1284 | //_____________________________________________________________________________ | |
ef12d5a5 | 1285 | TH1D* AliJetFlowTools::ProtectHeap(TH1D* protect, Bool_t kill, TString suffix) { |
4292ca60 | 1286 | // protect heap by adding unique qualifier to name |
1287 | if(!protect) return 0x0; | |
1288 | TH1D* p = (TH1D*)protect->Clone(); | |
ef12d5a5 | 1289 | TString tempString(fActiveString); |
1290 | tempString+=suffix; | |
1291 | p->SetName(Form("%s_%s", protect->GetName(), tempString.Data())); | |
1292 | p->SetTitle(Form("%s_%s", protect->GetTitle(), tempString.Data())); | |
4292ca60 | 1293 | if(kill) delete protect; |
1294 | return p; | |
1295 | } | |
1296 | //_____________________________________________________________________________ | |
ef12d5a5 | 1297 | TH2D* AliJetFlowTools::ProtectHeap(TH2D* protect, Bool_t kill, TString suffix) { |
4292ca60 | 1298 | // protect heap by adding unique qualifier to name |
1299 | if(!protect) return 0x0; | |
1300 | TH2D* p = (TH2D*)protect->Clone(); | |
ef12d5a5 | 1301 | TString tempString(fActiveString); |
1302 | tempString+=suffix; | |
1303 | p->SetName(Form("%s_%s", protect->GetName(), tempString.Data())); | |
1304 | p->SetTitle(Form("%s_%s", protect->GetTitle(), tempString.Data())); | |
4292ca60 | 1305 | if(kill) delete protect; |
1306 | return p; | |
1307 | } | |
1308 | //_____________________________________________________________________________ | |
ef12d5a5 | 1309 | TGraphErrors* AliJetFlowTools::ProtectHeap(TGraphErrors* protect, Bool_t kill, TString suffix) { |
4292ca60 | 1310 | // protect heap by adding unique qualifier to name |
1311 | if(!protect) return 0x0; | |
1312 | TGraphErrors* p = (TGraphErrors*)protect->Clone(); | |
ef12d5a5 | 1313 | TString tempString(fActiveString); |
1314 | tempString+=suffix; | |
1315 | p->SetName(Form("%s_%s", protect->GetName(), tempString.Data())); | |
1316 | p->SetTitle(Form("%s_%s", protect->GetTitle(), tempString.Data())); | |
4292ca60 | 1317 | if(kill) delete protect; |
1318 | return p; | |
1319 | } | |
1320 | //_____________________________________________________________________________ |