2 /*************************************************************************
3 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
5 * Author: The ALICE Off-line Project. *
6 * Contributors are mentioned in the code where appropriate. *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
17 ///////////////////////////////////////////////////////////////////////////
18 // Dielectron Correction framework manager //
32 ///////////////////////////////////////////////////////////////////////////
35 #include <TObjArray.h>
38 #include <TObjString.h>
40 #include <AliCFContainer.h>
41 #include <AliAnalysisFilter.h>
42 #include <AliAnalysisCuts.h>
43 #include <AliVParticle.h>
46 #include "AliDielectronCF.h"
47 #include "AliDielectronMC.h"
48 #include "AliDielectronPair.h"
49 #include "AliDielectronSignalMC.h"
51 ClassImp(AliDielectronCF)
53 AliDielectronCF::AliDielectronCF() :
54 TNamed("DielectronCF","DielectronCF"),
59 fVarBinLimitsLeg(0x0),
63 fStepForMCtruth(kFALSE),
64 fStepForNoCutsMCmotherPid(kFALSE),
65 fStepForAfterAllCuts(kTRUE),
66 fStepForPreFilter(kFALSE),
67 fStepsForEachCut(kFALSE),
68 fStepsForCutsIncreasing(kFALSE),
69 fStepsForSignal(kTRUE),
70 fStepsForBackground(kFALSE),
71 fStepsForMCtruthOnly(kFALSE),
80 // Default constructor
82 for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
87 for (Int_t i=0; i<kNmaxAddSteps; ++i){
88 fStepMasks[i]=0xFFFFFF;
92 //________________________________________________________________
93 AliDielectronCF::AliDielectronCF(const char* name, const char* title) :
99 fVarBinLimitsLeg(0x0),
103 fStepForMCtruth(kFALSE),
104 fStepForNoCutsMCmotherPid(kFALSE),
105 fStepForAfterAllCuts(kTRUE),
106 fStepForPreFilter(kFALSE),
107 fStepsForEachCut(kFALSE),
108 fStepsForCutsIncreasing(kFALSE),
109 fStepsForSignal(kTRUE),
110 fStepsForBackground(kFALSE),
111 fStepsForMCtruthOnly(kFALSE),
122 for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
127 for (Int_t i=0; i<kNmaxAddSteps; ++i){
128 fStepMasks[i]=0xFFFFFF;
132 //________________________________________________________________
133 AliDielectronCF::~AliDielectronCF()
138 if (fValues) delete [] fValues;
139 if (fIsMCTruth) delete [] fIsMCTruth;
140 if (fVarBinLimits) delete fVarBinLimits;
141 if (fVarBinLimitsLeg) delete fVarBinLimitsLeg;
144 //________________________________________________________________
145 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, Int_t nbins,
146 Double_t min, Double_t max, Bool_t leg, Bool_t log)
149 // Add a variable to the CF configuration
150 // if leg is true it will add the variables of the leg
151 // if log is true log binning will be created
154 TVectorD *binLimits=0x0;
155 if (!log) binLimits=MakeLinBinning(nbins,min,max);
156 else binLimits=MakeLogBinning(nbins,min,max);
157 AddVariable(type,binLimits,leg);
160 //________________________________________________________________
161 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, const char* binLimitStr, Bool_t leg/*=kFALSE*/)
164 // Add a variable to the CF configuration
165 // specify arbitrary binning in a string.
166 // Bin limits need to be separated by a ","
168 TString limits(binLimitStr);
169 if (limits.IsNull()){
170 AliError(Form("Bin Limit string is empty, cannot add the variable '%s'",AliDielectronVarManager::GetValueName(type)));
174 TObjArray *arr=limits.Tokenize(",");
175 Int_t nLimits=arr->GetEntries();
177 AliError(Form("Need at leas 2 bin limits, cannot add the variable '%s'",AliDielectronVarManager::GetValueName(type)));
182 TVectorD *binLimits=new TVectorD(nLimits);
183 for (Int_t iLim=0; iLim<nLimits; ++iLim){
184 (*binLimits)[iLim]=(static_cast<TObjString*>(arr->At(iLim)))->GetString().Atof();
188 AddVariable(type,binLimits,leg);
191 //________________________________________________________________
192 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, TVectorD *binLimits, Bool_t leg/*=kFALSE*/)
195 // Add variable with the binning given in the TVectorD
199 fVarBinLimits=new TObjArray;
200 fVarBinLimits->SetOwner();
202 fVarBinLimits->Add(binLimits);
203 fVariables[fNVars] = (UInt_t)type;
206 if (!fVarBinLimitsLeg){
207 fVarBinLimitsLeg=new TObjArray;
208 fVarBinLimitsLeg->SetOwner();
210 fVarBinLimitsLeg->Add(binLimits);
211 fVariablesLeg[fNVarsLeg] = (UInt_t)type;
216 //________________________________________________________________
217 void AliDielectronCF::InitialiseContainer(const AliAnalysisFilter& filter)
220 // Initialise container based on the cuts in the analysis filter
223 fNCuts=filter.GetCuts()->GetEntries();
225 fHasMC=AliDielectronMC::Instance()->HasMC();
228 if (fStepsForSignal && fSignalsMC) fNAddSteps+=fSignalsMC->GetEntries();
229 if (fStepsForBackground) ++fNAddSteps;
230 if (fStepsForMCtruthOnly) --fNAddSteps; // No Step for Pair information
233 fStepForMCtruth=kFALSE;
234 fStepForNoCutsMCmotherPid=kFALSE;
235 fStepsForSignal=kFALSE;
236 fStepsForBackground=kFALSE;
238 // consitency checks to not duplicate steps
239 if (fStepsForCutsIncreasing) fStepForAfterAllCuts=kFALSE;
240 if (fStepsForEachCut&&fNCuts==1) fStepForAfterAllCuts=kFALSE;
243 if (fStepForMCtruth && fSignalsMC) fNSteps+=fSignalsMC->GetEntries();
244 if (fStepForNoCutsMCmotherPid && fSignalsMC) fNSteps+=fSignalsMC->GetEntries();
245 if (fStepForAfterAllCuts) fNSteps+=fNAddSteps;
247 if (fStepsForEachCut) fNSteps+=(fNAddSteps*fNCuts); //one step for each cut + Signal (MC)
248 if (fStepsForCutsIncreasing) fNSteps+=(fNAddSteps*fNCuts); //one step for the increasing cuts + Signal (MC)
249 // e.g. cut1, cut1&cut2, cut1&cut2&cut3, ...
251 fNSteps+=(fNAddSteps*fNStepMasks); // cuts for the additional cut masks
253 if (fStepForPreFilter) fNSteps+=fNAddSteps; //Add at the end for Prefilter (maxcutmask+1)
255 // create the container
257 Int_t *nbins=new Int_t[fNVars+2*fNVarsLeg];
258 for (Int_t i=0;i<fNVars;++i) {
259 Int_t nBins=(static_cast<TVectorD*>(fVarBinLimits->At(i)))->GetNrows()-1;
262 for (Int_t i=0;i<fNVarsLeg;++i){
263 Int_t nBins=(static_cast<TVectorD*>(fVarBinLimitsLeg->At(i)))->GetNrows()-1;
264 nbins[i+fNVars]=nBins;
265 nbins[i+fNVars+fNVarsLeg]=nBins;
268 fCfContainer = new AliCFContainer(GetName(), GetTitle(), fNSteps, fNVars+2*fNVarsLeg, nbins);
271 // initialize the variables and their bin limits
272 for (Int_t iVar=0; iVar<fNVars; iVar++) {
273 UInt_t type=fVariables[iVar];
274 Double_t *binLim = (static_cast<TVectorD*>(fVarBinLimits->At(iVar)))->GetMatrixArray();
276 fCfContainer->SetBinLimits(iVar, binLim);
277 fCfContainer->SetVarTitle(iVar, AliDielectronVarManager::GetValueName(type));
280 // initialize the variables and their bin limits for the Legs
281 for (Int_t iVar=0; iVar<fNVarsLeg; iVar++) {
282 UInt_t type=fVariablesLeg[iVar];
283 Double_t *binLim=(static_cast<TVectorD*>(fVarBinLimitsLeg->At(iVar)))->GetMatrixArray();
286 fCfContainer->SetBinLimits(iVar+fNVars, binLim);
287 fCfContainer->SetVarTitle(iVar+fNVars, Form("Leg1_%s",AliDielectronVarManager::GetValueName(type)));
290 fCfContainer->SetBinLimits(iVar+fNVars+fNVarsLeg, binLim);
291 fCfContainer->SetVarTitle(iVar+fNVars+fNVarsLeg, Form("Leg2_%s",AliDielectronVarManager::GetValueName(type)));
294 // array for storing values
295 fValues = new Double_t[fNVars+2*fNVarsLeg];
297 // array for storing MC info
298 if (fHasMC && fSignalsMC && fSignalsMC->GetEntries()>0) fIsMCTruth=new Bool_t[fSignalsMC->GetEntries()];
299 //=================//
300 // Set step titles //
301 //=================//
305 if(fStepForMCtruth && fSignalsMC) {
306 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++)
307 fCfContainer->SetStepTitle(step++, Form("MC truth (Signal: %s)", fSignalsMC->At(i)->GetTitle()));
310 //before cuts (MC truth)
311 if (fStepForNoCutsMCmotherPid && fSignalsMC){
312 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++)
313 fCfContainer->SetStepTitle(step++,Form("No cuts (Signal: %s)",fSignalsMC->At(i)->GetTitle()));
317 //Steps for each of the cuts
318 if (fStepsForEachCut){
319 for (Int_t iCut=0; iCut<fNCuts;++iCut) {
320 cutName=filter.GetCuts()->At(iCut)->GetName(); //TODO: User GetTitle???
321 if (!fStepsForMCtruthOnly) {
322 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
325 if (fStepsForSignal && fSignalsMC) {
326 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
327 fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
330 if (fStepsForBackground)
331 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
336 //Steps for increasing cut match
337 if (fStepsForCutsIncreasing){
338 cutName=""; //TODO: User GetTitle???
339 for (Int_t iCut=0; iCut<fNCuts;++iCut) {
340 if (!cutName.IsNull()) cutName+="&";
341 cutName+=filter.GetCuts()->At(iCut)->GetName();
342 if (!fStepsForMCtruthOnly) {
343 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
346 if (fStepsForSignal && fSignalsMC)
347 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
348 fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
350 if (fStepsForBackground)
351 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
356 //Steps of user defined cut combinations
357 for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
359 UInt_t mask=fStepMasks[iComb];
360 for (Int_t iCut=0; iCut<fNCuts;++iCut) {
362 if (cutName.IsNull()){
363 cutName=filter.GetCuts()->At(iCut)->GetName();
366 cutName+=filter.GetCuts()->At(iCut)->GetName();
371 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
374 if (fStepsForSignal && fSignalsMC)
375 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
376 fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
378 if (fStepsForBackground)
379 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
384 if (fStepForAfterAllCuts){
385 cutName="No pair cuts";
386 if (filter.GetCuts()->At(0)){
387 cutName=filter.GetCuts()->At(0)->GetName(); //TODO: User GetTitle???
388 for (Int_t iCut=1; iCut<fNCuts;++iCut) {
390 cutName+=filter.GetCuts()->At(iCut)->GetName();
393 if (!fStepsForMCtruthOnly) {
394 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
397 if (fStepsForSignal && fSignalsMC)
398 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
399 fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
401 if (fStepsForBackground)
402 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
406 //Additional Step for result after PreFilter
407 if (fStepForPreFilter){
409 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
411 if (fStepsForSignal && fSignalsMC)
412 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
413 fCfContainer->SetStepTitle(step++, Form("%s (Signal %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
415 if (fStepsForBackground)
416 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
423 AliError(Form("Something went wrong in the naming of the steps!!! (%d != %d)",step,fNSteps));
427 //________________________________________________________________
428 void AliDielectronCF::Fill(UInt_t mask, const AliDielectronPair *particle)
431 // Fill the containers
434 // Check the MC truths
436 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) fIsMCTruth[i]=kFALSE;
439 //TODO: for the moment don't fill truth information for mixed event paris. No valid MC info is available
440 // in the mixing handler
441 Bool_t isMixedPair=(particle->GetType()>2&&particle->GetType()<10);
443 Bool_t isBackground = kFALSE;
444 if(fIsMCTruth && !isMixedPair) {
445 for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
446 fIsMCTruth[i] = AliDielectronMC::Instance()->IsMCTruth(particle, (AliDielectronSignalMC*)fSignalsMC->At(i));
447 isBackground = (isBackground || fIsMCTruth[i]);
449 // background is considered that pair which does not fulfill any of the signals
450 isBackground = !isBackground;
453 Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
454 AliDielectronVarManager::Fill(particle,valuesPair);
456 for (Int_t iVar=0; iVar<fNVars; ++iVar){
457 Int_t var=fVariables[iVar];
458 fValues[iVar]=valuesPair[var];
462 Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues]={0};
463 AliDielectronVarManager::Fill(particle->GetFirstDaughter(),valuesLeg1);
464 Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues]={0};
465 AliDielectronVarManager::Fill(particle->GetSecondDaughter(),valuesLeg2);
467 for (Int_t iVar=0; iVar<fNVarsLeg; ++iVar){
468 Int_t var=fVariablesLeg[iVar];
469 fValues[iVar+fNVars]=valuesLeg1[var];
470 fValues[iVar+fNVars+fNVarsLeg]=valuesLeg2[var];
474 UInt_t selectedMask=(1<<fNCuts)-1;
479 // Pure MC steps are handled in FillMC
481 if (fStepForMCtruth && fIsMCTruth) step+=fSignalsMC->GetEntries();
484 if (fStepForNoCutsMCmotherPid && fIsMCTruth){
485 for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
487 fCfContainer->Fill(fValues,step);
493 //Steps for each of the cuts
494 if (fStepsForEachCut){
495 for (Int_t iCut=0; iCut<fNCuts;++iCut) {
496 UInt_t cutMask=1<<iCut;
497 if ((mask&cutMask)==cutMask) {
498 if(!fStepsForMCtruthOnly) {
499 fCfContainer->Fill(fValues,step);
503 if ( fStepsForSignal && fIsMCTruth){
504 for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
506 fCfContainer->Fill(fValues,step);
511 if ( fStepsForBackground ){
512 if (isBackground) fCfContainer->Fill(fValues,step);
523 //Steps for increasing cut match
524 if (fStepsForCutsIncreasing&&fNCuts>2){
525 for (Int_t iCut=0; iCut<fNCuts;++iCut) {
526 UInt_t cutMask=(1<<(iCut+1))-1;
527 if ((mask&cutMask)==cutMask) {
528 if(!fStepsForMCtruthOnly) {
529 fCfContainer->Fill(fValues,step);
534 if ( fStepsForSignal && fIsMCTruth){
535 for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
537 fCfContainer->Fill(fValues,step);
542 if ( fStepsForBackground ){
543 if (isBackground) fCfContainer->Fill(fValues,step);
553 //Steps of user defined cut combinations
554 for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
555 UInt_t userMask=fStepMasks[iComb];
556 if ((mask&userMask)==userMask) {
557 if(!fStepsForMCtruthOnly) {
558 fCfContainer->Fill(fValues,step);
562 if ( fStepsForSignal && fIsMCTruth){
563 for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
565 fCfContainer->Fill(fValues,step);
570 if ( fStepsForBackground ){
571 if (isBackground) fCfContainer->Fill(fValues,step);
581 if (fStepForAfterAllCuts){
582 if (mask == selectedMask){
583 if(!fStepsForMCtruthOnly) {
584 fCfContainer->Fill(fValues,step);
589 if ( fStepsForSignal && fIsMCTruth){
590 for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
592 fCfContainer->Fill(fValues,step);
597 if ( fStepsForBackground ){
598 if (isBackground) fCfContainer->Fill(fValues,step);
608 if (fStepForPreFilter) {
609 if (mask&(1<<fNCuts)) {
610 if(!fStepsForMCtruthOnly) {
611 fCfContainer->Fill(fValues,step);
615 if ( fStepsForSignal && fIsMCTruth){
616 for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
618 fCfContainer->Fill(fValues,step);
623 if ( fStepsForBackground ){
624 if (isBackground) fCfContainer->Fill(fValues,step);
635 AliError("Something went wrong in the step filling!!!");
639 //________________________________________________________________
640 void AliDielectronCF::FillMC(const TObject *particle)
643 // fill MC part of the Container
645 if (!fStepForMCtruth) return;
647 Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
648 AliDielectronVarManager::Fill(particle,valuesPair);
650 AliVParticle *d1=0x0;
651 AliVParticle *d2=0x0;
652 AliDielectronMC::Instance()->GetDaughters(particle,d1,d2);
654 //TODO: temporary solution, set manually the pair type to 1: unlikesign SE
655 valuesPair[AliDielectronVarManager::kPairType]=1;
657 for (Int_t iVar=0; iVar<fNVars; ++iVar){
658 Int_t var=fVariables[iVar];
659 fValues[iVar]=valuesPair[var];
663 Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues];
664 Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues];
665 if (d1->Pt()>d2->Pt()){
666 AliDielectronVarManager::Fill(d1,valuesLeg1);
667 AliDielectronVarManager::Fill(d2,valuesLeg2);
669 AliDielectronVarManager::Fill(d2,valuesLeg1);
670 AliDielectronVarManager::Fill(d1,valuesLeg2);
673 for (Int_t iVar=0; iVar<fNVarsLeg; ++iVar){
674 Int_t var=fVariablesLeg[iVar];
675 fValues[iVar+fNVars]=valuesLeg1[var];
676 fValues[iVar+fNVars+fNVarsLeg]=valuesLeg2[var];
680 fCfContainer->Fill(fValues,0);
684 //________________________________________________________________
685 void AliDielectronCF::FillMC(Int_t label1, Int_t label2, Int_t nSignal) {
687 // fill the pure MC part of the container starting from a pair of 2 particles (part1 and part2 are legs)
689 if (!fStepForMCtruth) return;
691 AliVParticle* part1 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label1);
692 AliVParticle* part2 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label2);
694 AliDielectronMC* dieMC = AliDielectronMC::Instance();
696 Int_t mLabel1 = dieMC->GetMothersLabel(label1); // should work for both ESD and AOD
697 Int_t mLabel2 = dieMC->GetMothersLabel(label2);
698 // check the same mother option
699 AliDielectronSignalMC* sigMC = (AliDielectronSignalMC*)fSignalsMC->At(nSignal);
700 if(sigMC->GetMothersRelation()==AliDielectronSignalMC::kSame && mLabel1!=mLabel2) return;
701 if(sigMC->GetMothersRelation()==AliDielectronSignalMC::kDifferent && mLabel1==mLabel2) return;
703 // fill the leg variables
705 Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues];
706 Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues];
707 if (part1->Pt()>part2->Pt()){
708 AliDielectronVarManager::Fill(part1,valuesLeg1);
709 AliDielectronVarManager::Fill(part2,valuesLeg2);
711 AliDielectronVarManager::Fill(part2,valuesLeg1);
712 AliDielectronVarManager::Fill(part1,valuesLeg2);
715 for (Int_t iVar=0; iVar<fNVarsLeg; ++iVar){
716 Int_t var=fVariablesLeg[iVar];
717 fValues[iVar+fNVars]=valuesLeg1[var];
718 fValues[iVar+fNVars+fNVarsLeg]=valuesLeg2[var];
722 Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
723 AliDielectronVarManager::Fill(dieMC->GetMCEvent(), valuesPair);
724 AliDielectronVarManager::FillVarMCParticle2(part1,part2,valuesPair);
726 if(part1->Charge()*part2->Charge()<0)
727 valuesPair[AliDielectronVarManager::kPairType]=1;
728 else if(part1->Charge()>0)
729 valuesPair[AliDielectronVarManager::kPairType]=0;
731 valuesPair[AliDielectronVarManager::kPairType]=2; // if one of the two particles is neutral, the pair will go here
733 for(Int_t iVar=0; iVar<fNVars; ++iVar){
734 Int_t var=fVariables[iVar];
735 fValues[iVar]=valuesPair[var];
738 fCfContainer->Fill(fValues,nSignal);
742 //_____________________________________________________________________________
743 TVectorD* AliDielectronCF::MakeLogBinning(Int_t nbinsX, Double_t xmin, Double_t xmax) const
746 // Make logarithmic binning
747 // the user has to delete the array afterwards!!!
751 if (xmin<1e-20 || xmax<1e-20){
752 AliError("For Log binning xmin and xmax must be > 1e-20. Using linear binning instead!");
753 return MakeLinBinning(nbinsX, xmin, xmax);
760 TVectorD *binLim=new TVectorD(nbinsX+1);
763 Double_t expMax=TMath::Log(last/first);
764 for (Int_t i=0; i<nbinsX+1; ++i){
765 (*binLim)[i]=first*TMath::Exp(expMax/nbinsX*(Double_t)i);
770 //_____________________________________________________________________________
771 TVectorD* AliDielectronCF::MakeLinBinning(Int_t nbinsX, Double_t xmin, Double_t xmax) const
774 // Make logarithmic binning
775 // the user has to delete the array afterwards!!!
782 TVectorD *binLim=new TVectorD(nbinsX+1);
785 Double_t binWidth=(last-first)/nbinsX;
786 for (Int_t i=0; i<nbinsX+1; ++i){
787 (*binLim)[i]=first+binWidth*(Double_t)i;