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"
49 ClassImp(AliDielectronCF)
51 AliDielectronCF::AliDielectronCF() :
52 TNamed("DielectronCF","DielectronCF"),
57 fVarBinLimitsLeg(0x0),
60 fStepForMCtruth(kFALSE),
61 fStepForNoCutsMCmotherPid(kFALSE),
62 fStepForAfterAllCuts(kTRUE),
63 fStepsForEachCut(kFALSE),
64 fStepsForCutsIncreasing(kFALSE),
65 fStepsForSignal(kTRUE),
66 fStepsForBackground(kFALSE),
74 // Default constructor
76 for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
81 for (Int_t i=0; i<kNmaxAddSteps; ++i){
82 fStepMasks[i]=0xFFFFFF;
86 //________________________________________________________________
87 AliDielectronCF::AliDielectronCF(const char* name, const char* title) :
93 fVarBinLimitsLeg(0x0),
96 fStepForMCtruth(kFALSE),
97 fStepForNoCutsMCmotherPid(kFALSE),
98 fStepForAfterAllCuts(kTRUE),
99 fStepsForEachCut(kFALSE),
100 fStepsForCutsIncreasing(kFALSE),
101 fStepsForSignal(kTRUE),
102 fStepsForBackground(kFALSE),
112 for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
117 for (Int_t i=0; i<kNmaxAddSteps; ++i){
118 fStepMasks[i]=0xFFFFFF;
122 //________________________________________________________________
123 AliDielectronCF::~AliDielectronCF()
128 if (fValues) delete [] fValues;
129 if (fVarBinLimits) delete fVarBinLimits;
130 if (fVarBinLimitsLeg) delete fVarBinLimitsLeg;
133 //________________________________________________________________
134 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, Int_t nbins,
135 Double_t min, Double_t max, Bool_t leg, Bool_t log)
138 // Add a variable to the CF configuration
139 // if leg is true it will add the variables of the leg
140 // if log is true log binning will be created
143 TVectorD *binLimits=0x0;
144 if (!log) binLimits=MakeLinBinning(nbins,min,max);
145 else binLimits=MakeLogBinning(nbins,min,max);
146 AddVariable(type,binLimits,leg);
149 //________________________________________________________________
150 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, const char* binLimitStr, Bool_t leg/*=kFALSE*/)
153 // Add a variable to the CF configuration
154 // specify arbitrary binning in a string.
155 // Bin limits need to be separated by a ","
157 TString limits(binLimitStr);
158 if (limits.IsNull()){
159 AliError(Form("Bin Limit string is empty, cannot add the variable '%s'",AliDielectronVarManager::GetValueName(type)));
163 TObjArray *arr=limits.Tokenize(",");
164 Int_t nLimits=arr->GetEntries();
166 AliError(Form("Need at leas 2 bin limits, cannot add the variable '%s'",AliDielectronVarManager::GetValueName(type)));
171 TVectorD *binLimits=new TVectorD(nLimits);
172 for (Int_t iLim=0; iLim<nLimits; ++iLim){
173 (*binLimits)[iLim]=(static_cast<TObjString*>(arr->At(iLim)))->GetString().Atof();
177 AddVariable(type,binLimits,leg);
180 //________________________________________________________________
181 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, TVectorD *binLimits, Bool_t leg/*=kFALSE*/)
184 // Add variable with the binning given in the TVectorD
188 fVarBinLimits=new TObjArray;
189 fVarBinLimits->SetOwner();
191 fVarBinLimits->Add(binLimits);
192 fVariables[fNVars] = (UInt_t)type;
195 if (!fVarBinLimitsLeg){
196 fVarBinLimitsLeg=new TObjArray;
197 fVarBinLimitsLeg->SetOwner();
199 fVarBinLimitsLeg->Add(binLimits);
200 fVariablesLeg[fNVarsLeg] = (UInt_t)type;
205 //________________________________________________________________
206 void AliDielectronCF::InitialiseContainer(const AliAnalysisFilter& filter)
209 // Initialise container based on the cuts in the analysis filter
212 fNCuts=filter.GetCuts()->GetEntries();
214 fHasMC=AliDielectronMC::Instance()->HasMC();
217 if (fStepsForSignal) ++fNAddSteps;
218 if (fStepsForBackground) ++fNAddSteps;
221 fStepForMCtruth=kFALSE;
222 fStepForNoCutsMCmotherPid=kFALSE;
223 fStepsForSignal=kFALSE;
224 fStepsForBackground=kFALSE;
228 if (fStepForMCtruth) ++fNSteps;
229 if (fStepForNoCutsMCmotherPid) ++fNSteps;
230 if (fStepForAfterAllCuts) fNSteps+=fNAddSteps;
232 if (fStepsForEachCut&&fNCuts>1) fNSteps+=(fNAddSteps*fNCuts); //one step for each cut + Signal (MC)
233 if (fStepsForCutsIncreasing&&fNCuts>2) fNSteps+=(fNAddSteps*(fNCuts-2)); //one step for the increasing cuts + Signal (MC)
234 // e.g. cut2&cut3, cut2&cut3&cut4
235 fNSteps+=(fNAddSteps*fNStepMasks); // cuts for the additional cut masks
236 // create the container
238 Int_t *nbins=new Int_t[fNVars+2*fNVarsLeg];
239 for (Int_t i=0;i<fNVars;++i) {
240 Int_t nBins=(static_cast<TVectorD*>(fVarBinLimits->At(i)))->GetNrows()-1;
243 for (Int_t i=0;i<fNVarsLeg;++i){
244 Int_t nBins=(static_cast<TVectorD*>(fVarBinLimitsLeg->At(i)))->GetNrows()-1;
245 nbins[i+fNVars]=nBins;
246 nbins[i+fNVars+fNVarsLeg]=nBins;
249 fCfContainer = new AliCFContainer(GetName(), GetTitle(), fNSteps, fNVars+2*fNVarsLeg, nbins);
252 // initialize the variables and their bin limits
253 for (Int_t iVar=0; iVar<fNVars; iVar++) {
254 UInt_t type=fVariables[iVar];
255 Double_t *binLim = (static_cast<TVectorD*>(fVarBinLimits->At(iVar)))->GetMatrixArray();
257 fCfContainer->SetBinLimits(iVar, binLim);
258 fCfContainer->SetVarTitle(iVar, AliDielectronVarManager::GetValueName(type));
261 // initialize the variables and their bin limits for the Legs
262 for (Int_t iVar=0; iVar<fNVarsLeg; iVar++) {
263 UInt_t type=fVariablesLeg[iVar];
264 Double_t *binLim=(static_cast<TVectorD*>(fVarBinLimitsLeg->At(iVar)))->GetMatrixArray();
267 fCfContainer->SetBinLimits(iVar+fNVars, binLim);
268 fCfContainer->SetVarTitle(iVar+fNVars, Form("Leg1_%s",AliDielectronVarManager::GetValueName(type)));
271 fCfContainer->SetBinLimits(iVar+fNVars+fNVarsLeg, binLim);
272 fCfContainer->SetVarTitle(iVar+fNVars+fNVarsLeg, Form("Leg2_%s",AliDielectronVarManager::GetValueName(type)));
275 // array for storing values
276 fValues = new Double_t[fNVars+2*fNVarsLeg];
278 //=================//
279 // Set step titles //
280 //=================//
284 if (fStepForMCtruth){
285 fCfContainer->SetStepTitle(step++,"MC truth");
288 //before cuts (MC truth)
289 if (fStepForNoCutsMCmotherPid){
290 fCfContainer->SetStepTitle(step++,"No cuts (Signal)");
294 //Steps for each of the cuts
295 if (fStepsForEachCut&&fNCuts>1){
296 for (Int_t iCut=0; iCut<fNCuts;++iCut) {
297 cutName=filter.GetCuts()->At(iCut)->GetName(); //TODO: User GetTitle???
299 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
303 fCfContainer->SetStepTitle(step++, (cutName+" (Signal)").Data()); //Step for the cut with MC truth
304 if (fStepsForBackground)
305 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
310 //Steps for increasing cut match
311 if (fStepsForCutsIncreasing&&fNCuts>2){
312 cutName=filter.GetCuts()->At(0)->GetName(); //TODO: User GetTitle???
313 for (Int_t iCut=1; iCut<fNCuts-1;++iCut) {
315 cutName+=filter.GetCuts()->At(iCut)->GetName();
317 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
321 fCfContainer->SetStepTitle(step++, (cutName+" (Signal)").Data()); //Step for the cut with MC truth
322 if (fStepsForBackground)
323 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
328 //Steps of user defined cut combinations
329 for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
331 UInt_t mask=fStepMasks[iComb];
332 for (Int_t iCut=0; iCut<fNCuts;++iCut) {
334 if (cutName.IsNull()){
335 cutName=filter.GetCuts()->At(iCut)->GetName();
338 cutName+=filter.GetCuts()->At(iCut)->GetName();
343 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
347 fCfContainer->SetStepTitle(step++, (cutName+" (Signal)").Data()); //Step for the cut with MC truth
348 if (fStepsForBackground)
349 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
354 if (fStepForAfterAllCuts){
355 cutName="No pair cuts";
356 if (filter.GetCuts()->At(0)){
357 cutName=filter.GetCuts()->At(0)->GetName(); //TODO: User GetTitle???
358 for (Int_t iCut=1; iCut<fNCuts;++iCut) {
360 cutName+=filter.GetCuts()->At(iCut)->GetName();
363 fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
366 fCfContainer->SetStepTitle(step++, (cutName+" (Signal)").Data()); //Step for the cut with MC truth
367 if (fStepsForBackground)
368 fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
373 AliError(Form("Something went wrong in the naming of the steps!!! (%d != %d)",step,fNSteps));
377 //________________________________________________________________
378 void AliDielectronCF::Fill(UInt_t mask, const AliDielectronPair *particle)
381 // Fill the containers
384 Bool_t isMCTruth=kFALSE;
385 if (fHasMC) isMCTruth=AliDielectronMC::Instance()->IsMotherPdg(particle,fPdgMother);
387 Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
388 AliDielectronVarManager::Fill(particle,valuesPair);
390 for (Int_t iVar=0; iVar<fNVars; ++iVar){
391 Int_t var=fVariables[iVar];
392 fValues[iVar]=valuesPair[var];
396 Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues];
397 AliDielectronVarManager::Fill(particle->GetFirstDaughter(),valuesLeg1);
398 Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues];
399 AliDielectronVarManager::Fill(particle->GetSecondDaughter(),valuesLeg2);
401 for (Int_t iVar=0; iVar<fNVarsLeg; ++iVar){
402 Int_t var=fVariablesLeg[iVar];
403 fValues[iVar+fNVars]=valuesLeg1[var];
404 fValues[iVar+fNVars+fNVarsLeg]=valuesLeg2[var];
408 UInt_t selectedMask=(1<<fNCuts)-1;
413 // step 0 would be full MC truth and is handled in FillMC
415 if (fStepForMCtruth) ++step;
418 if (fStepForNoCutsMCmotherPid){
419 if (isMCTruth) fCfContainer->Fill(fValues,step);
423 //Steps for each of the cuts
424 if (fStepsForEachCut&&fNCuts>1){
425 for (Int_t iCut=0; iCut<fNCuts;++iCut) {
426 if (mask&(1<<iCut)) {
427 fCfContainer->Fill(fValues,step);
431 if ( fStepsForSignal){
432 if (isMCTruth) fCfContainer->Fill(fValues,step);
435 if ( fStepsForBackground ){
436 if (!isMCTruth) fCfContainer->Fill(fValues,step);
446 //Steps for increasing cut match
447 if (fStepsForCutsIncreasing&&fNCuts>2){
448 for (Int_t iCut=1; iCut<fNCuts-1;++iCut) {
449 if (mask&(1<<((iCut+1)-1))) {
450 fCfContainer->Fill(fValues,step);
454 if ( fStepsForSignal){
455 if (isMCTruth) fCfContainer->Fill(fValues,step);
458 if ( fStepsForBackground ){
459 if (!isMCTruth) fCfContainer->Fill(fValues,step);
469 //Steps of user defined cut combinations
470 for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
471 UInt_t userMask=fStepMasks[iComb];
473 fCfContainer->Fill(fValues,step);
477 if ( fStepsForSignal){
478 if (isMCTruth) fCfContainer->Fill(fValues,step);
481 if ( fStepsForBackground ){
482 if (!isMCTruth) fCfContainer->Fill(fValues,step);
492 if (fStepForAfterAllCuts){
493 if (mask == selectedMask){
494 fCfContainer->Fill(fValues,step);
498 if ( fStepsForSignal){
499 if (isMCTruth) fCfContainer->Fill(fValues,step);
502 if ( fStepsForBackground ){
503 if (!isMCTruth) fCfContainer->Fill(fValues,step);
513 AliError("Something went wrong in the step filling!!!");
518 //________________________________________________________________
519 void AliDielectronCF::FillMC(const TObject *particle)
522 // fill MC part of the Container
524 if (!fStepForMCtruth) return;
526 Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
527 AliDielectronVarManager::Fill(particle,valuesPair);
529 AliVParticle *d1=0x0;
530 AliVParticle *d2=0x0;
531 AliDielectronMC::Instance()->GetDaughters(particle,d1,d2);
533 valuesPair[AliDielectronVarManager::kThetaHE]=AliDielectronPair::ThetaPhiCM(d1,d2,kTRUE,kTRUE);
534 valuesPair[AliDielectronVarManager::kPhiHE]=AliDielectronPair::ThetaPhiCM(d1,d2,kTRUE,kFALSE);
535 valuesPair[AliDielectronVarManager::kThetaCS]=AliDielectronPair::ThetaPhiCM(d1,d2,kFALSE,kTRUE);
536 valuesPair[AliDielectronVarManager::kPhiCS]=AliDielectronPair::ThetaPhiCM(d1,d2,kFALSE,kFALSE);
538 //TODO: temporary solution, set manually the pair type to 1: unlikesign SE
539 valuesPair[AliDielectronVarManager::kPairType]=1;
541 for (Int_t iVar=0; iVar<fNVars; ++iVar){
542 Int_t var=fVariables[iVar];
543 fValues[iVar]=valuesPair[var];
547 Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues];
548 Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues];
549 if (d1->Pt()>d2->Pt()){
550 AliDielectronVarManager::Fill(d1,valuesLeg1);
551 AliDielectronVarManager::Fill(d2,valuesLeg2);
553 AliDielectronVarManager::Fill(d2,valuesLeg1);
554 AliDielectronVarManager::Fill(d1,valuesLeg2);
557 for (Int_t iVar=0; iVar<fNVarsLeg; ++iVar){
558 Int_t var=fVariablesLeg[iVar];
559 fValues[iVar+fNVars]=valuesLeg1[var];
560 fValues[iVar+fNVars+fNVarsLeg]=valuesLeg2[var];
564 fCfContainer->Fill(fValues,0);
567 //_____________________________________________________________________________
568 TVectorD* AliDielectronCF::MakeLogBinning(Int_t nbinsX, Double_t xmin, Double_t xmax) const
571 // Make logarithmic binning
572 // the user has to delete the array afterwards!!!
576 if (xmin<1e-20 || xmax<1e-20){
577 AliError("For Log binning xmin and xmax must be > 1e-20. Using linear binning instead!");
578 return MakeLinBinning(nbinsX, xmin, xmax);
585 TVectorD *binLim=new TVectorD(nbinsX+1);
588 Double_t expMax=TMath::Log(last/first);
589 for (Int_t i=0; i<nbinsX+1; ++i){
590 (*binLim)[i]=first*TMath::Exp(expMax/nbinsX*(Double_t)i);
595 //_____________________________________________________________________________
596 TVectorD* AliDielectronCF::MakeLinBinning(Int_t nbinsX, Double_t xmin, Double_t xmax) const
599 // Make logarithmic binning
600 // the user has to delete the array afterwards!!!
607 TVectorD *binLim=new TVectorD(nbinsX+1);
610 Double_t binWidth=(last-first)/nbinsX;
611 for (Int_t i=0; i<nbinsX+1; ++i){
612 (*binLim)[i]=first+binWidth*(Double_t)i;