1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////
17 // Dielectron Correction framework manager //
31 ///////////////////////////////////////////////////////////////////////////
34 #include <TObjArray.h>
37 #include <TObjString.h>
39 #include <AliCFContainer.h>
40 #include <AliAnalysisFilter.h>
41 #include <AliAnalysisCuts.h>
42 #include <AliVParticle.h>
45 #include "AliDielectronCF.h"
46 #include "AliDielectronMC.h"
47 #include "AliDielectronPair.h"
48 #include "AliDielectronSignalMC.h"
50 ClassImp(AliDielectronCF)
52 AliDielectronCF::AliDielectronCF() :
53 TNamed("DielectronCF","DielectronCF"),
58 fVarBinLimitsLeg(0x0),
61 fStepForMCtruth(kFALSE),
62 fStepForNoCutsMCmotherPid(kFALSE),
63 fStepForAfterAllCuts(kTRUE),
64 fStepForPreFilter(kFALSE),
65 fStepsForEachCut(kFALSE),
66 fStepsForCutsIncreasing(kFALSE),
67 fStepsForSignal(kTRUE),
68 fStepsForBackground(kFALSE),
77 // Default constructor
79 for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
84 for (Int_t i=0; i<kNmaxAddSteps; ++i){
85 fStepMasks[i]=0xFFFFFF;
89 //________________________________________________________________
90 AliDielectronCF::AliDielectronCF(const char* name, const char* title) :
96 fVarBinLimitsLeg(0x0),
99 fStepForMCtruth(kFALSE),
100 fStepForNoCutsMCmotherPid(kFALSE),
101 fStepForAfterAllCuts(kTRUE),
102 fStepForPreFilter(kFALSE),
103 fStepsForEachCut(kFALSE),
104 fStepsForCutsIncreasing(kFALSE),
105 fStepsForSignal(kTRUE),
106 fStepsForBackground(kFALSE),
117 for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
122 for (Int_t i=0; i<kNmaxAddSteps; ++i){
123 fStepMasks[i]=0xFFFFFF;
127 //________________________________________________________________
128 AliDielectronCF::~AliDielectronCF()
133 if (fValues) delete [] fValues;
134 if (fVarBinLimits) delete fVarBinLimits;
135 if (fVarBinLimitsLeg) delete fVarBinLimitsLeg;
138 //________________________________________________________________
139 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, Int_t nbins,
140 Double_t min, Double_t max, Bool_t leg, Bool_t log)
143 // Add a variable to the CF configuration
144 // if leg is true it will add the variables of the leg
145 // if log is true log binning will be created
148 TVectorD *binLimits=0x0;
149 if (!log) binLimits=MakeLinBinning(nbins,min,max);
150 else binLimits=MakeLogBinning(nbins,min,max);
151 AddVariable(type,binLimits,leg);
154 //________________________________________________________________
155 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, const char* binLimitStr, Bool_t leg/*=kFALSE*/)
158 // Add a variable to the CF configuration
159 // specify arbitrary binning in a string.
160 // Bin limits need to be separated by a ","
162 TString limits(binLimitStr);
163 if (limits.IsNull()){
164 AliError(Form("Bin Limit string is empty, cannot add the variable '%s'",AliDielectronVarManager::GetValueName(type)));
168 TObjArray *arr=limits.Tokenize(",");
169 Int_t nLimits=arr->GetEntries();
171 AliError(Form("Need at leas 2 bin limits, cannot add the variable '%s'",AliDielectronVarManager::GetValueName(type)));
176 TVectorD *binLimits=new TVectorD(nLimits);
177 for (Int_t iLim=0; iLim<nLimits; ++iLim){
178 (*binLimits)[iLim]=(static_cast<TObjString*>(arr->At(iLim)))->GetString().Atof();
182 AddVariable(type,binLimits,leg);
185 //________________________________________________________________
186 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, TVectorD *binLimits, Bool_t leg/*=kFALSE*/)
189 // Add variable with the binning given in the TVectorD
193 fVarBinLimits=new TObjArray;
194 fVarBinLimits->SetOwner();
196 fVarBinLimits->Add(binLimits);
197 fVariables[fNVars] = (UInt_t)type;
200 if (!fVarBinLimitsLeg){
201 fVarBinLimitsLeg=new TObjArray;
202 fVarBinLimitsLeg->SetOwner();
204 fVarBinLimitsLeg->Add(binLimits);
205 fVariablesLeg[fNVarsLeg] = (UInt_t)type;
210 //________________________________________________________________
211 void AliDielectronCF::InitialiseContainer(const AliAnalysisFilter& filter)
214 // Initialise container based on the cuts in the analysis filter
217 fNCuts=filter.GetCuts()->GetEntries();
219 fHasMC=AliDielectronMC::Instance()->HasMC();
222 if (fStepsForSignal && fSignalsMC) fNAddSteps+=fSignalsMC->GetEntries();
223 if (fStepsForBackground) ++fNAddSteps;
226 fStepForMCtruth=kFALSE;
227 fStepForNoCutsMCmotherPid=kFALSE;
228 fStepsForSignal=kFALSE;
229 fStepsForBackground=kFALSE;
233 if (fStepForMCtruth && fSignalsMC) fNSteps+=fSignalsMC->GetEntries();
234 if (fStepForNoCutsMCmotherPid && fSignalsMC) fNSteps+=fSignalsMC->GetEntries();
235 if (fStepForAfterAllCuts) fNSteps+=fNAddSteps;
237 if (fStepsForEachCut&&fNCuts>1) fNSteps+=(fNAddSteps*fNCuts); //one step for each cut + Signal (MC)
238 if (fStepsForCutsIncreasing&&fNCuts>2) fNSteps+=(fNAddSteps*(fNCuts-2)); //one step for the increasing cuts + Signal (MC)
239 // e.g. cut2&cut3, cut2&cut3&cut4
240 fNSteps+=(fNAddSteps*fNStepMasks); // cuts for the additional cut masks
242 if (fStepForPreFilter) fNSteps+=fNAddSteps; //Add at the end for Prefilter (maxcutmask+1)
244 // create the container
246 Int_t *nbins=new Int_t[fNVars+2*fNVarsLeg];
247 for (Int_t i=0;i<fNVars;++i) {
248 Int_t nBins=(static_cast<TVectorD*>(fVarBinLimits->At(i)))->GetNrows()-1;
251 for (Int_t i=0;i<fNVarsLeg;++i){
252 Int_t nBins=(static_cast<TVectorD*>(fVarBinLimitsLeg->At(i)))->GetNrows()-1;
253 nbins[i+fNVars]=nBins;
254 nbins[i+fNVars+fNVarsLeg]=nBins;
257 fCfContainer = new AliCFContainer(GetName(), GetTitle(), fNSteps, fNVars+2*fNVarsLeg, nbins);
260 // initialize the variables and their bin limits
261 for (Int_t iVar=0; iVar<fNVars; iVar++) {
262 UInt_t type=fVariables[iVar];
263 Double_t *binLim = (static_cast<TVectorD*>(fVarBinLimits->At(iVar)))->GetMatrixArray();
265 fCfContainer->SetBinLimits(iVar, binLim);
266 fCfContainer->SetVarTitle(iVar, AliDielectronVarManager::GetValueName(type));
269 // initialize the variables and their bin limits for the Legs
270 for (Int_t iVar=0; iVar<fNVarsLeg; iVar++) {
271 UInt_t type=fVariablesLeg[iVar];
272 Double_t *binLim=(static_cast<TVectorD*>(fVarBinLimitsLeg->At(iVar)))->GetMatrixArray();
275 fCfContainer->SetBinLimits(iVar+fNVars, binLim);
276 fCfContainer->SetVarTitle(iVar+fNVars, Form("Leg1_%s",AliDielectronVarManager::GetValueName(type)));
279 fCfContainer->SetBinLimits(iVar+fNVars+fNVarsLeg, binLim);
280 fCfContainer->SetVarTitle(iVar+fNVars+fNVarsLeg, Form("Leg2_%s",AliDielectronVarManager::GetValueName(type)));
283 // array for storing values
284 fValues = new Double_t[fNVars+2*fNVarsLeg];
286 //=================//
287 // Set step titles //
288 //=================//
292 if(fStepForMCtruth && fSignalsMC) {
293 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++)
294 fCfContainer->SetStepTitle(step++, Form("MC truth (Signal: %s)", fSignalsMC->At(i)->GetTitle()));
297 //before cuts (MC truth)
298 if (fStepForNoCutsMCmotherPid && fSignalsMC){
299 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++)
300 fCfContainer->SetStepTitle(step++,Form("No cuts (Signal: %s)",fSignalsMC->At(i)->GetTitle()));
304 //Steps for each of the cuts
305 if (fStepsForEachCut&&fNCuts>1){
306 for (Int_t iCut=0; iCut<fNCuts;++iCut) {
307 cutName=filter.GetCuts()->At(iCut)->GetName(); //TODO: User GetTitle???
309 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
312 if (fStepsForSignal && fSignalsMC) {
313 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
314 fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
317 if (fStepsForBackground)
318 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
323 //Steps for increasing cut match
324 if (fStepsForCutsIncreasing&&fNCuts>2){
325 cutName=filter.GetCuts()->At(0)->GetName(); //TODO: User GetTitle???
326 for (Int_t iCut=1; iCut<fNCuts-1;++iCut) {
328 cutName+=filter.GetCuts()->At(iCut)->GetName();
330 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
333 if (fStepsForSignal && fSignalsMC)
334 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
335 fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
337 if (fStepsForBackground)
338 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
343 //Steps of user defined cut combinations
344 for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
346 UInt_t mask=fStepMasks[iComb];
347 for (Int_t iCut=0; iCut<fNCuts;++iCut) {
349 if (cutName.IsNull()){
350 cutName=filter.GetCuts()->At(iCut)->GetName();
353 cutName+=filter.GetCuts()->At(iCut)->GetName();
358 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
361 if (fStepsForSignal && fSignalsMC)
362 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
363 fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
365 if (fStepsForBackground)
366 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
371 if (fStepForAfterAllCuts){
372 cutName="No pair cuts";
373 if (filter.GetCuts()->At(0)){
374 cutName=filter.GetCuts()->At(0)->GetName(); //TODO: User GetTitle???
375 for (Int_t iCut=1; iCut<fNCuts;++iCut) {
377 cutName+=filter.GetCuts()->At(iCut)->GetName();
380 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
382 if (fStepsForSignal && fSignalsMC)
383 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
384 fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
386 if (fStepsForBackground)
387 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
391 //Additional Step for result after PreFilter
392 if (fStepForPreFilter){
394 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
396 if (fStepsForSignal && fSignalsMC)
397 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
398 fCfContainer->SetStepTitle(step++, Form("%s (Signal %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
400 if (fStepsForBackground)
401 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
408 AliError(Form("Something went wrong in the naming of the steps!!! (%d != %d)",step,fNSteps));
412 //________________________________________________________________
413 void AliDielectronCF::Fill(UInt_t mask, const AliDielectronPair *particle)
416 // Fill the containers
419 // Check the MC truths
420 Bool_t* isMCTruth=0x0;
421 if(fHasMC && fSignalsMC && fSignalsMC->GetEntries()>0) {
422 isMCTruth=new Bool_t[fSignalsMC->GetEntries()];
423 for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) isMCTruth[i]=kFALSE;
426 Bool_t isBackground = kFALSE;
427 if(fHasMC && isMCTruth) {
428 for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
429 isMCTruth[i] = AliDielectronMC::Instance()->IsMCTruth(particle, (AliDielectronSignalMC*)fSignalsMC->At(i));
430 isBackground = (isBackground || isMCTruth[i]);
432 // background is considered that pair which does not fulfill any of the signals
433 isBackground = !isBackground;
436 Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
437 AliDielectronVarManager::Fill(particle,valuesPair);
439 for (Int_t iVar=0; iVar<fNVars; ++iVar){
440 Int_t var=fVariables[iVar];
441 fValues[iVar]=valuesPair[var];
445 Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues];
446 AliDielectronVarManager::Fill(particle->GetFirstDaughter(),valuesLeg1);
447 Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues];
448 AliDielectronVarManager::Fill(particle->GetSecondDaughter(),valuesLeg2);
450 for (Int_t iVar=0; iVar<fNVarsLeg; ++iVar){
451 Int_t var=fVariablesLeg[iVar];
452 fValues[iVar+fNVars]=valuesLeg1[var];
453 fValues[iVar+fNVars+fNVarsLeg]=valuesLeg2[var];
457 UInt_t selectedMask=(1<<fNCuts)-1;
462 // Pure MC steps are handled in FillMC
464 if (fStepForMCtruth && isMCTruth) step+=fSignalsMC->GetEntries();
467 if (fStepForNoCutsMCmotherPid && isMCTruth){
468 for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
470 fCfContainer->Fill(fValues,step);
476 //Steps for each of the cuts
477 if (fStepsForEachCut&&fNCuts>1){
478 for (Int_t iCut=0; iCut<fNCuts;++iCut) {
479 if (mask&(1<<iCut)) {
480 fCfContainer->Fill(fValues,step);
484 if ( fStepsForSignal && isMCTruth){
485 for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
487 fCfContainer->Fill(fValues,step);
492 if ( fStepsForBackground ){
493 if (isBackground) fCfContainer->Fill(fValues,step);
504 //Steps for increasing cut match
505 if (fStepsForCutsIncreasing&&fNCuts>2){
506 for (Int_t iCut=1; iCut<fNCuts-1;++iCut) {
507 if (mask&(1<<((iCut+1)-1))) {
508 fCfContainer->Fill(fValues,step);
512 if ( fStepsForSignal && isMCTruth){
513 for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
515 fCfContainer->Fill(fValues,step);
520 if ( fStepsForBackground ){
521 if (isBackground) fCfContainer->Fill(fValues,step);
531 //Steps of user defined cut combinations
532 for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
533 UInt_t userMask=fStepMasks[iComb];
535 fCfContainer->Fill(fValues,step);
539 if ( fStepsForSignal && isMCTruth){
540 for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
542 fCfContainer->Fill(fValues,step);
547 if ( fStepsForBackground ){
548 if (isBackground) fCfContainer->Fill(fValues,step);
558 if (fStepForAfterAllCuts){
559 if (mask == selectedMask){
560 fCfContainer->Fill(fValues,step);
564 if ( fStepsForSignal && isMCTruth){
565 for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
567 fCfContainer->Fill(fValues,step);
572 if ( fStepsForBackground ){
573 if (isBackground) fCfContainer->Fill(fValues,step);
581 if (fStepForPreFilter) {
582 if (mask&(1<<fNCuts)) {
583 fCfContainer->Fill(fValues,step);
587 if ( fStepsForSignal && isMCTruth){
588 for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
590 fCfContainer->Fill(fValues,step);
595 if ( fStepsForBackground ){
596 if (isBackground) fCfContainer->Fill(fValues,step);
606 AliError("Something went wrong in the step filling!!!");
608 if(isMCTruth) delete [] isMCTruth;
611 //________________________________________________________________
612 void AliDielectronCF::FillMC(const TObject *particle)
615 // fill MC part of the Container
617 if (!fStepForMCtruth) return;
619 Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
620 AliDielectronVarManager::Fill(particle,valuesPair);
622 AliVParticle *d1=0x0;
623 AliVParticle *d2=0x0;
624 AliDielectronMC::Instance()->GetDaughters(particle,d1,d2);
626 valuesPair[AliDielectronVarManager::kThetaHE]=AliDielectronPair::ThetaPhiCM(d1,d2,kTRUE,kTRUE);
627 valuesPair[AliDielectronVarManager::kPhiHE]=AliDielectronPair::ThetaPhiCM(d1,d2,kTRUE,kFALSE);
628 valuesPair[AliDielectronVarManager::kThetaCS]=AliDielectronPair::ThetaPhiCM(d1,d2,kFALSE,kTRUE);
629 valuesPair[AliDielectronVarManager::kPhiCS]=AliDielectronPair::ThetaPhiCM(d1,d2,kFALSE,kFALSE);
631 //TODO: temporary solution, set manually the pair type to 1: unlikesign SE
632 valuesPair[AliDielectronVarManager::kPairType]=1;
634 for (Int_t iVar=0; iVar<fNVars; ++iVar){
635 Int_t var=fVariables[iVar];
636 fValues[iVar]=valuesPair[var];
640 Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues];
641 Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues];
642 if (d1->Pt()>d2->Pt()){
643 AliDielectronVarManager::Fill(d1,valuesLeg1);
644 AliDielectronVarManager::Fill(d2,valuesLeg2);
646 AliDielectronVarManager::Fill(d2,valuesLeg1);
647 AliDielectronVarManager::Fill(d1,valuesLeg2);
650 for (Int_t iVar=0; iVar<fNVarsLeg; ++iVar){
651 Int_t var=fVariablesLeg[iVar];
652 fValues[iVar+fNVars]=valuesLeg1[var];
653 fValues[iVar+fNVars+fNVarsLeg]=valuesLeg2[var];
657 fCfContainer->Fill(fValues,0);
661 //________________________________________________________________
662 void AliDielectronCF::FillMC(Int_t label1, Int_t label2, Int_t nSignal) {
664 // fill the pure MC part of the container starting from a pair of 2 particles (part1 and part2 are legs)
666 if (!fStepForMCtruth) return;
668 AliVParticle* part1 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label1);
669 AliVParticle* part2 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label2);
671 AliDielectronMC* dieMC = AliDielectronMC::Instance();
673 Int_t mLabel1 = dieMC->GetMothersLabel(label1); // should work for both ESD and AOD
674 Int_t mLabel2 = dieMC->GetMothersLabel(label2);
675 // check the same mother option
676 AliDielectronSignalMC* sigMC = (AliDielectronSignalMC*)fSignalsMC->At(nSignal);
677 if(sigMC->GetMothersRelation()==AliDielectronSignalMC::kSame && mLabel1!=mLabel2) return;
678 if(sigMC->GetMothersRelation()==AliDielectronSignalMC::kDifferent && mLabel1==mLabel2) return;
680 // fill the leg variables
682 Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues];
683 Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues];
684 if (part1->Pt()>part2->Pt()){
685 AliDielectronVarManager::Fill(part1,valuesLeg1);
686 AliDielectronVarManager::Fill(part2,valuesLeg2);
688 AliDielectronVarManager::Fill(part2,valuesLeg1);
689 AliDielectronVarManager::Fill(part1,valuesLeg2);
692 for (Int_t iVar=0; iVar<fNVarsLeg; ++iVar){
693 Int_t var=fVariablesLeg[iVar];
694 fValues[iVar+fNVars]=valuesLeg1[var];
695 fValues[iVar+fNVars+fNVarsLeg]=valuesLeg2[var];
699 Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
700 AliDielectronVarManager::FillVarMCParticle2(part1,part2,valuesPair);
702 valuesPair[AliDielectronVarManager::kThetaHE]=AliDielectronPair::ThetaPhiCM(part1,part2,kTRUE,kTRUE);
703 valuesPair[AliDielectronVarManager::kPhiHE]=AliDielectronPair::ThetaPhiCM(part1,part2,kTRUE,kFALSE);
704 valuesPair[AliDielectronVarManager::kThetaCS]=AliDielectronPair::ThetaPhiCM(part1,part2,kFALSE,kTRUE);
705 valuesPair[AliDielectronVarManager::kPhiCS]=AliDielectronPair::ThetaPhiCM(part1,part2,kFALSE,kFALSE);
707 if(part1->Charge()*part2->Charge()<0)
708 valuesPair[AliDielectronVarManager::kPairType]=1;
709 else if(part1->Charge()>0)
710 valuesPair[AliDielectronVarManager::kPairType]=0;
712 valuesPair[AliDielectronVarManager::kPairType]=2;
714 for(Int_t iVar=0; iVar<fNVars; ++iVar){
715 Int_t var=fVariables[iVar];
716 fValues[iVar]=valuesPair[var];
719 fCfContainer->Fill(fValues,nSignal);
723 //_____________________________________________________________________________
724 TVectorD* AliDielectronCF::MakeLogBinning(Int_t nbinsX, Double_t xmin, Double_t xmax) const
727 // Make logarithmic binning
728 // the user has to delete the array afterwards!!!
732 if (xmin<1e-20 || xmax<1e-20){
733 AliError("For Log binning xmin and xmax must be > 1e-20. Using linear binning instead!");
734 return MakeLinBinning(nbinsX, xmin, xmax);
741 TVectorD *binLim=new TVectorD(nbinsX+1);
744 Double_t expMax=TMath::Log(last/first);
745 for (Int_t i=0; i<nbinsX+1; ++i){
746 (*binLim)[i]=first*TMath::Exp(expMax/nbinsX*(Double_t)i);
751 //_____________________________________________________________________________
752 TVectorD* AliDielectronCF::MakeLinBinning(Int_t nbinsX, Double_t xmin, Double_t xmax) const
755 // Make logarithmic binning
756 // the user has to delete the array afterwards!!!
763 TVectorD *binLim=new TVectorD(nbinsX+1);
766 Double_t binWidth=(last-first)/nbinsX;
767 for (Int_t i=0; i<nbinsX+1; ++i){
768 (*binLim)[i]=first+binWidth*(Double_t)i;