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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////
19 // Dielectron Correction framework manager //
33 ///////////////////////////////////////////////////////////////////////////
36 #include <TObjArray.h>
39 #include <TObjString.h>
41 #include <AliCFContainer.h>
42 #include <AliAnalysisFilter.h>
43 #include <AliAnalysisCuts.h>
44 #include <AliVParticle.h>
47 #include "AliDielectronCF.h"
48 #include "AliDielectronMC.h"
49 #include "AliDielectronPair.h"
51 ClassImp(AliDielectronCF)
53 AliDielectronCF::AliDielectronCF() :
54 TNamed("DielectronCF","DielectronCF"),
59 fVarBinLimitsLeg(0x0),
62 fStepForMCtruth(kFALSE),
63 fStepForNoCutsMCmotherPid(kFALSE),
64 fStepForAfterAllCuts(kTRUE),
65 fStepForPreFilter(kFALSE),
66 fStepsForEachCut(kFALSE),
67 fStepsForCutsIncreasing(kFALSE),
68 fStepsForSignal(kTRUE),
69 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),
116 for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
121 for (Int_t i=0; i<kNmaxAddSteps; ++i){
122 fStepMasks[i]=0xFFFFFF;
126 //________________________________________________________________
127 AliDielectronCF::~AliDielectronCF()
132 if (fValues) delete [] fValues;
133 if (fVarBinLimits) delete fVarBinLimits;
134 if (fVarBinLimitsLeg) delete fVarBinLimitsLeg;
137 //________________________________________________________________
138 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, Int_t nbins,
139 Double_t min, Double_t max, Bool_t leg, Bool_t log)
142 // Add a variable to the CF configuration
143 // if leg is true it will add the variables of the leg
144 // if log is true log binning will be created
147 TVectorD *binLimits=0x0;
148 if (!log) binLimits=MakeLinBinning(nbins,min,max);
149 else binLimits=MakeLogBinning(nbins,min,max);
150 AddVariable(type,binLimits,leg);
153 //________________________________________________________________
154 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, const char* binLimitStr, Bool_t leg/*=kFALSE*/)
157 // Add a variable to the CF configuration
158 // specify arbitrary binning in a string.
159 // Bin limits need to be separated by a ","
161 TString limits(binLimitStr);
162 if (limits.IsNull()){
163 AliError(Form("Bin Limit string is empty, cannot add the variable '%s'",AliDielectronVarManager::GetValueName(type)));
167 TObjArray *arr=limits.Tokenize(",");
168 Int_t nLimits=arr->GetEntries();
170 AliError(Form("Need at leas 2 bin limits, cannot add the variable '%s'",AliDielectronVarManager::GetValueName(type)));
175 TVectorD *binLimits=new TVectorD(nLimits);
176 for (Int_t iLim=0; iLim<nLimits; ++iLim){
177 (*binLimits)[iLim]=(static_cast<TObjString*>(arr->At(iLim)))->GetString().Atof();
181 AddVariable(type,binLimits,leg);
184 //________________________________________________________________
185 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, TVectorD *binLimits, Bool_t leg/*=kFALSE*/)
188 // Add variable with the binning given in the TVectorD
192 fVarBinLimits=new TObjArray;
193 fVarBinLimits->SetOwner();
195 fVarBinLimits->Add(binLimits);
196 fVariables[fNVars] = (UInt_t)type;
199 if (!fVarBinLimitsLeg){
200 fVarBinLimitsLeg=new TObjArray;
201 fVarBinLimitsLeg->SetOwner();
203 fVarBinLimitsLeg->Add(binLimits);
204 fVariablesLeg[fNVarsLeg] = (UInt_t)type;
209 //________________________________________________________________
210 void AliDielectronCF::InitialiseContainer(const AliAnalysisFilter& filter)
213 // Initialise container based on the cuts in the analysis filter
216 fNCuts=filter.GetCuts()->GetEntries();
218 fHasMC=AliDielectronMC::Instance()->HasMC();
221 if (fStepsForSignal) ++fNAddSteps;
222 if (fStepsForBackground) ++fNAddSteps;
225 fStepForMCtruth=kFALSE;
226 fStepForNoCutsMCmotherPid=kFALSE;
227 fStepsForSignal=kFALSE;
228 fStepsForBackground=kFALSE;
232 if (fStepForMCtruth) ++fNSteps;
233 if (fStepForNoCutsMCmotherPid) ++fNSteps;
234 if (fStepForAfterAllCuts) fNSteps+=fNAddSteps;
236 if (fStepsForEachCut&&fNCuts>1) fNSteps+=(fNAddSteps*fNCuts); //one step for each cut + Signal (MC)
237 if (fStepsForCutsIncreasing&&fNCuts>2) fNSteps+=(fNAddSteps*(fNCuts-2)); //one step for the increasing cuts + Signal (MC)
238 // e.g. cut2&cut3, cut2&cut3&cut4
239 fNSteps+=(fNAddSteps*fNStepMasks); // cuts for the additional cut masks
241 if (fStepForPreFilter) fNSteps+=fNAddSteps; //Add at the end for Prefilter (maxcutmask+1)
243 // create the container
245 Int_t *nbins=new Int_t[fNVars+2*fNVarsLeg];
246 for (Int_t i=0;i<fNVars;++i) {
247 Int_t nBins=(static_cast<TVectorD*>(fVarBinLimits->At(i)))->GetNrows()-1;
250 for (Int_t i=0;i<fNVarsLeg;++i){
251 Int_t nBins=(static_cast<TVectorD*>(fVarBinLimitsLeg->At(i)))->GetNrows()-1;
252 nbins[i+fNVars]=nBins;
253 nbins[i+fNVars+fNVarsLeg]=nBins;
256 fCfContainer = new AliCFContainer(GetName(), GetTitle(), fNSteps, fNVars+2*fNVarsLeg, nbins);
259 // initialize the variables and their bin limits
260 for (Int_t iVar=0; iVar<fNVars; iVar++) {
261 UInt_t type=fVariables[iVar];
262 Double_t *binLim = (static_cast<TVectorD*>(fVarBinLimits->At(iVar)))->GetMatrixArray();
264 fCfContainer->SetBinLimits(iVar, binLim);
265 fCfContainer->SetVarTitle(iVar, AliDielectronVarManager::GetValueName(type));
268 // initialize the variables and their bin limits for the Legs
269 for (Int_t iVar=0; iVar<fNVarsLeg; iVar++) {
270 UInt_t type=fVariablesLeg[iVar];
271 Double_t *binLim=(static_cast<TVectorD*>(fVarBinLimitsLeg->At(iVar)))->GetMatrixArray();
274 fCfContainer->SetBinLimits(iVar+fNVars, binLim);
275 fCfContainer->SetVarTitle(iVar+fNVars, Form("Leg1_%s",AliDielectronVarManager::GetValueName(type)));
278 fCfContainer->SetBinLimits(iVar+fNVars+fNVarsLeg, binLim);
279 fCfContainer->SetVarTitle(iVar+fNVars+fNVarsLeg, Form("Leg2_%s",AliDielectronVarManager::GetValueName(type)));
282 // array for storing values
283 fValues = new Double_t[fNVars+2*fNVarsLeg];
285 //=================//
286 // Set step titles //
287 //=================//
291 if (fStepForMCtruth){
292 fCfContainer->SetStepTitle(step++,"MC truth");
295 //before cuts (MC truth)
296 if (fStepForNoCutsMCmotherPid){
297 fCfContainer->SetStepTitle(step++,"No cuts (Signal)");
301 //Steps for each of the cuts
302 if (fStepsForEachCut&&fNCuts>1){
303 for (Int_t iCut=0; iCut<fNCuts;++iCut) {
304 cutName=filter.GetCuts()->At(iCut)->GetName(); //TODO: User GetTitle???
306 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
310 fCfContainer->SetStepTitle(step++, (cutName+" (Signal)").Data()); //Step for the cut with MC truth
311 if (fStepsForBackground)
312 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
317 //Steps for increasing cut match
318 if (fStepsForCutsIncreasing&&fNCuts>2){
319 cutName=filter.GetCuts()->At(0)->GetName(); //TODO: User GetTitle???
320 for (Int_t iCut=1; iCut<fNCuts-1;++iCut) {
322 cutName+=filter.GetCuts()->At(iCut)->GetName();
324 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
328 fCfContainer->SetStepTitle(step++, (cutName+" (Signal)").Data()); //Step for the cut with MC truth
329 if (fStepsForBackground)
330 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
335 //Steps of user defined cut combinations
336 for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
338 UInt_t mask=fStepMasks[iComb];
339 for (Int_t iCut=0; iCut<fNCuts;++iCut) {
341 if (cutName.IsNull()){
342 cutName=filter.GetCuts()->At(iCut)->GetName();
345 cutName+=filter.GetCuts()->At(iCut)->GetName();
350 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
354 fCfContainer->SetStepTitle(step++, (cutName+" (Signal)").Data()); //Step for the cut with MC truth
355 if (fStepsForBackground)
356 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
361 if (fStepForAfterAllCuts){
362 cutName="No pair cuts";
363 if (filter.GetCuts()->At(0)){
364 cutName=filter.GetCuts()->At(0)->GetName(); //TODO: User GetTitle???
365 for (Int_t iCut=1; iCut<fNCuts;++iCut) {
367 cutName+=filter.GetCuts()->At(iCut)->GetName();
370 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
373 fCfContainer->SetStepTitle(step++, (cutName+" (Signal)").Data()); //Step for the cut with MC truth
374 if (fStepsForBackground)
375 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
379 //Additional Step for result after PreFilter
380 if (fStepForPreFilter){
382 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
385 fCfContainer->SetStepTitle(step++, (cutName+" (Signal)").Data()); //Step for the cut with MC truth
386 if (fStepsForBackground)
387 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
394 AliError(Form("Something went wrong in the naming of the steps!!! (%d != %d)",step,fNSteps));
398 //________________________________________________________________
399 void AliDielectronCF::Fill(UInt_t mask, const AliDielectronPair *particle)
402 // Fill the containers
405 Bool_t isMCTruth=kFALSE;
406 if (fHasMC) isMCTruth=AliDielectronMC::Instance()->IsMotherPdg(particle,fPdgMother);
408 Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
409 AliDielectronVarManager::Fill(particle,valuesPair);
411 for (Int_t iVar=0; iVar<fNVars; ++iVar){
412 Int_t var=fVariables[iVar];
413 fValues[iVar]=valuesPair[var];
417 Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues];
418 AliDielectronVarManager::Fill(particle->GetFirstDaughter(),valuesLeg1);
419 Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues];
420 AliDielectronVarManager::Fill(particle->GetSecondDaughter(),valuesLeg2);
422 for (Int_t iVar=0; iVar<fNVarsLeg; ++iVar){
423 Int_t var=fVariablesLeg[iVar];
424 fValues[iVar+fNVars]=valuesLeg1[var];
425 fValues[iVar+fNVars+fNVarsLeg]=valuesLeg2[var];
429 UInt_t selectedMask=(1<<fNCuts)-1;
434 // step 0 would be full MC truth and is handled in FillMC
436 if (fStepForMCtruth) ++step;
439 if (fStepForNoCutsMCmotherPid){
440 if (isMCTruth) fCfContainer->Fill(fValues,step);
444 //Steps for each of the cuts
445 if (fStepsForEachCut&&fNCuts>1){
446 for (Int_t iCut=0; iCut<fNCuts;++iCut) {
447 if (mask&(1<<iCut)) {
448 fCfContainer->Fill(fValues,step);
452 if ( fStepsForSignal){
453 if (isMCTruth) fCfContainer->Fill(fValues,step);
456 if ( fStepsForBackground ){
457 if (!isMCTruth) fCfContainer->Fill(fValues,step);
468 //Steps for increasing cut match
469 if (fStepsForCutsIncreasing&&fNCuts>2){
470 for (Int_t iCut=1; iCut<fNCuts-1;++iCut) {
471 if (mask&(1<<((iCut+1)-1))) {
472 fCfContainer->Fill(fValues,step);
476 if ( fStepsForSignal){
477 if (isMCTruth) fCfContainer->Fill(fValues,step);
480 if ( fStepsForBackground ){
481 if (!isMCTruth) fCfContainer->Fill(fValues,step);
491 //Steps of user defined cut combinations
492 for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
493 UInt_t userMask=fStepMasks[iComb];
495 fCfContainer->Fill(fValues,step);
499 if ( fStepsForSignal){
500 if (isMCTruth) fCfContainer->Fill(fValues,step);
503 if ( fStepsForBackground ){
504 if (!isMCTruth) fCfContainer->Fill(fValues,step);
514 if (fStepForAfterAllCuts){
515 if (mask == selectedMask){
516 fCfContainer->Fill(fValues,step);
520 if ( fStepsForSignal){
521 if (isMCTruth) fCfContainer->Fill(fValues,step);
524 if ( fStepsForBackground ){
525 if (!isMCTruth) fCfContainer->Fill(fValues,step);
533 if (fStepForPreFilter) {
534 if (mask&(1<<fNCuts)) {
535 fCfContainer->Fill(fValues,step);
539 if ( fStepsForSignal){
540 if (isMCTruth) fCfContainer->Fill(fValues,step);
543 if ( fStepsForBackground ){
544 if (!isMCTruth) fCfContainer->Fill(fValues,step);
554 AliError("Something went wrong in the step filling!!!");
559 //________________________________________________________________
560 void AliDielectronCF::FillMC(const TObject *particle)
563 // fill MC part of the Container
565 if (!fStepForMCtruth) return;
567 Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
568 AliDielectronVarManager::Fill(particle,valuesPair);
570 AliVParticle *d1=0x0;
571 AliVParticle *d2=0x0;
572 AliDielectronMC::Instance()->GetDaughters(particle,d1,d2);
574 valuesPair[AliDielectronVarManager::kThetaHE]=AliDielectronPair::ThetaPhiCM(d1,d2,kTRUE,kTRUE);
575 valuesPair[AliDielectronVarManager::kPhiHE]=AliDielectronPair::ThetaPhiCM(d1,d2,kTRUE,kFALSE);
576 valuesPair[AliDielectronVarManager::kThetaCS]=AliDielectronPair::ThetaPhiCM(d1,d2,kFALSE,kTRUE);
577 valuesPair[AliDielectronVarManager::kPhiCS]=AliDielectronPair::ThetaPhiCM(d1,d2,kFALSE,kFALSE);
579 //TODO: temporary solution, set manually the pair type to 1: unlikesign SE
580 valuesPair[AliDielectronVarManager::kPairType]=1;
582 for (Int_t iVar=0; iVar<fNVars; ++iVar){
583 Int_t var=fVariables[iVar];
584 fValues[iVar]=valuesPair[var];
588 Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues];
589 Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues];
590 if (d1->Pt()>d2->Pt()){
591 AliDielectronVarManager::Fill(d1,valuesLeg1);
592 AliDielectronVarManager::Fill(d2,valuesLeg2);
594 AliDielectronVarManager::Fill(d2,valuesLeg1);
595 AliDielectronVarManager::Fill(d1,valuesLeg2);
598 for (Int_t iVar=0; iVar<fNVarsLeg; ++iVar){
599 Int_t var=fVariablesLeg[iVar];
600 fValues[iVar+fNVars]=valuesLeg1[var];
601 fValues[iVar+fNVars+fNVarsLeg]=valuesLeg2[var];
605 fCfContainer->Fill(fValues,0);
608 //_____________________________________________________________________________
609 TVectorD* AliDielectronCF::MakeLogBinning(Int_t nbinsX, Double_t xmin, Double_t xmax) const
612 // Make logarithmic binning
613 // the user has to delete the array afterwards!!!
617 if (xmin<1e-20 || xmax<1e-20){
618 AliError("For Log binning xmin and xmax must be > 1e-20. Using linear binning instead!");
619 return MakeLinBinning(nbinsX, xmin, xmax);
626 TVectorD *binLim=new TVectorD(nbinsX+1);
629 Double_t expMax=TMath::Log(last/first);
630 for (Int_t i=0; i<nbinsX+1; ++i){
631 (*binLim)[i]=first*TMath::Exp(expMax/nbinsX*(Double_t)i);
636 //_____________________________________________________________________________
637 TVectorD* AliDielectronCF::MakeLinBinning(Int_t nbinsX, Double_t xmin, Double_t xmax) const
640 // Make logarithmic binning
641 // the user has to delete the array afterwards!!!
648 TVectorD *binLim=new TVectorD(nbinsX+1);
651 Double_t binWidth=(last-first)/nbinsX;
652 for (Int_t i=0; i<nbinsX+1; ++i){
653 (*binLim)[i]=first+binWidth*(Double_t)i;