]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGDQ/dielectron/AliDielectronCF.cxx
Add Mahmut's pp task
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliDielectronCF.cxx
1
2 /*************************************************************************
3 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 *                                                                        *
5 * Author: The ALICE Off-line Project.                                    *
6 * Contributors are mentioned in the code where appropriate.              *
7 *                                                                        *
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 **************************************************************************/
16
17 ///////////////////////////////////////////////////////////////////////////
18 //       Dielectron Correction framework manager                         //
19 //                                                                       //
20 /*
21
22
23
24
25
26
27
28
29
30 */
31 //                                                                       //
32 ///////////////////////////////////////////////////////////////////////////
33
34 #include <TList.h>
35 #include <TObjArray.h>
36 #include <TVectorD.h>
37 #include <TString.h>
38 #include <TObjString.h>
39
40 #include <AliCFContainer.h>
41 #include <AliAnalysisFilter.h>
42 #include <AliAnalysisCuts.h>
43 #include <AliVParticle.h>
44 #include <AliLog.h>
45
46 #include "AliDielectronCF.h"
47 #include "AliDielectronMC.h"
48 #include "AliDielectronPair.h"
49 #include "AliDielectronSignalMC.h"
50
51 ClassImp(AliDielectronCF)
52
53 AliDielectronCF::AliDielectronCF() :
54   TNamed("DielectronCF","DielectronCF"),
55   fNSteps(0),
56   fNVars(0),
57   fVarBinLimits(0x0),
58   fNVarsLeg(0),
59   fVarBinLimitsLeg(0x0),
60   fNCuts(0),
61   fValues(0x0),
62   fIsMCTruth(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),
72   fNStepMasks(0),
73   fPdgMother(-1),
74   fSignalsMC(0x0),
75   fCfContainer(0x0),
76   fHasMC(kFALSE),
77   fNAddSteps(0)
78 {
79   //
80   // Default constructor
81   //
82   for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
83     fVariables[i]=0;
84     fVariablesLeg[i]=0;
85   }
86
87   for (Int_t i=0; i<kNmaxAddSteps; ++i){
88     fStepMasks[i]=0xFFFFFF;
89   }
90 }
91
92 //________________________________________________________________
93 AliDielectronCF::AliDielectronCF(const char* name, const char* title) :
94   TNamed(name, title),
95   fNSteps(0),
96   fNVars(0),
97   fVarBinLimits(0x0),
98   fNVarsLeg(0),
99   fVarBinLimitsLeg(0x0),
100   fNCuts(0),
101   fValues(0x0),
102   fIsMCTruth(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),
112   fNStepMasks(0),
113   fPdgMother(-1),
114   fSignalsMC(0x0),
115   fCfContainer(0x0),
116   fHasMC(kFALSE),
117   fNAddSteps(0)
118 {
119   //
120   // Named constructor
121   //
122   for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
123     fVariables[i]=0;
124     fVariablesLeg[i]=0;
125   }
126   
127   for (Int_t i=0; i<kNmaxAddSteps; ++i){
128     fStepMasks[i]=0xFFFFFF;
129   }
130 }
131
132 //________________________________________________________________
133 AliDielectronCF::~AliDielectronCF()
134 {
135   //
136   // Destructor
137   //
138   if (fValues) delete [] fValues;
139   if (fIsMCTruth) delete [] fIsMCTruth;
140   if (fVarBinLimits) delete fVarBinLimits;
141   if (fVarBinLimitsLeg) delete fVarBinLimitsLeg;
142 }
143
144 //________________________________________________________________
145 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, Int_t nbins,
146                                   Double_t min, Double_t max, Bool_t leg, Bool_t log)
147 {
148   //
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
152   //
153
154   TVectorD *binLimits=0x0;
155   if (!log) binLimits=MakeLinBinning(nbins,min,max);
156   else binLimits=MakeLogBinning(nbins,min,max);
157   AddVariable(type,binLimits,leg);
158 }
159
160 //________________________________________________________________
161 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, const char* binLimitStr, Bool_t leg/*=kFALSE*/)
162 {
163   //
164   // Add a variable to the CF configuration
165   // specify arbitrary binning in a string.
166   // Bin limits need to be separated by a ","
167   //
168   TString limits(binLimitStr);
169   if (limits.IsNull()){
170     AliError(Form("Bin Limit string is empty, cannot add the variable '%s'",AliDielectronVarManager::GetValueName(type)));
171     return;
172   }
173
174   TObjArray *arr=limits.Tokenize(",");
175   Int_t nLimits=arr->GetEntries();
176   if (nLimits<2){
177     AliError(Form("Need at leas 2 bin limits, cannot add the variable '%s'",AliDielectronVarManager::GetValueName(type)));
178     delete arr;
179     return;
180   }
181
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();
185   }
186
187   delete arr;
188   AddVariable(type,binLimits,leg);
189 }
190
191 //________________________________________________________________
192 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, TVectorD *binLimits, Bool_t leg/*=kFALSE*/)
193 {
194   //
195   // Add variable with the binning given in the TVectorD
196   //
197   if (!leg){
198     if (!fVarBinLimits){
199       fVarBinLimits=new TObjArray;
200       fVarBinLimits->SetOwner();
201     }
202     fVarBinLimits->Add(binLimits);
203     fVariables[fNVars]  = (UInt_t)type;
204     ++fNVars;
205   } else {
206     if (!fVarBinLimitsLeg){
207       fVarBinLimitsLeg=new TObjArray;
208       fVarBinLimitsLeg->SetOwner();
209     }
210     fVarBinLimitsLeg->Add(binLimits);
211     fVariablesLeg[fNVarsLeg]  = (UInt_t)type;
212     ++fNVarsLeg;
213   }
214 }
215
216 //________________________________________________________________
217 void AliDielectronCF::InitialiseContainer(const AliAnalysisFilter& filter)
218 {
219   //
220   // Initialise container based on the cuts in the analysis filter
221   //
222
223   fNCuts=filter.GetCuts()->GetEntries();
224
225   fHasMC=AliDielectronMC::Instance()->HasMC();
226   fNAddSteps=1;
227   if (fHasMC){
228     if (fStepsForSignal && fSignalsMC) fNAddSteps+=fSignalsMC->GetEntries();
229     if (fStepsForBackground) ++fNAddSteps;
230     if (fStepsForMCtruthOnly) --fNAddSteps; // No Step for Pair information
231   } else {
232     //if 
233     fStepForMCtruth=kFALSE;
234     fStepForNoCutsMCmotherPid=kFALSE;
235     fStepsForSignal=kFALSE;
236     fStepsForBackground=kFALSE;
237   }
238   // consitency checks to not duplicate steps
239   if (fStepsForCutsIncreasing)     fStepForAfterAllCuts=kFALSE;
240   if (fStepsForEachCut&&fNCuts==1) fStepForAfterAllCuts=kFALSE;
241   
242   fNSteps=0;
243   if (fStepForMCtruth && fSignalsMC)           fNSteps+=fSignalsMC->GetEntries();
244   if (fStepForNoCutsMCmotherPid && fSignalsMC) fNSteps+=fSignalsMC->GetEntries();
245   if (fStepForAfterAllCuts)                    fNSteps+=fNAddSteps;
246   
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, ...
250   
251   fNSteps+=(fNAddSteps*fNStepMasks);                              // cuts for the additional cut masks
252
253   if (fStepForPreFilter) fNSteps+=fNAddSteps; //Add at the end for Prefilter (maxcutmask+1)
254   
255   // create the container
256   
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;
260     nbins[i]=nBins;
261   }
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;
266   }
267   
268   fCfContainer = new AliCFContainer(GetName(), GetTitle(), fNSteps, fNVars+2*fNVarsLeg, nbins);
269   delete [] nbins;
270   
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();
275
276     fCfContainer->SetBinLimits(iVar, binLim);
277     fCfContainer->SetVarTitle(iVar, AliDielectronVarManager::GetValueName(type));
278   }
279   
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();
284
285     //Leg1
286     fCfContainer->SetBinLimits(iVar+fNVars, binLim);
287     fCfContainer->SetVarTitle(iVar+fNVars, Form("Leg1_%s",AliDielectronVarManager::GetValueName(type)));
288     
289     //Leg2
290     fCfContainer->SetBinLimits(iVar+fNVars+fNVarsLeg, binLim);
291     fCfContainer->SetVarTitle(iVar+fNVars+fNVarsLeg, Form("Leg2_%s",AliDielectronVarManager::GetValueName(type)));
292   }
293
294   // array for storing values
295   fValues = new Double_t[fNVars+2*fNVarsLeg];
296
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   //=================//
302   Int_t step=0;
303
304   //Pure MC truth
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()));
308   }
309
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()));
314   }
315   
316   TString cutName;
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
323       }
324       if (fHasMC){
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
328           } 
329         }
330         if (fStepsForBackground)
331           fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
332       }
333     }
334   }
335
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
344       }
345       if (fHasMC){
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
349           }
350           if (fStepsForBackground)
351             fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
352       }
353     }
354   }
355
356   //Steps of user defined cut combinations
357   for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
358     cutName="";
359     UInt_t mask=fStepMasks[iComb];
360     for (Int_t iCut=0; iCut<fNCuts;++iCut) {
361       if (mask&(1<<iCut)){
362         if (cutName.IsNull()){
363           cutName=filter.GetCuts()->At(iCut)->GetName();
364         }else{
365           cutName+="&";
366           cutName+=filter.GetCuts()->At(iCut)->GetName();
367         }
368       }
369     }
370     
371     fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
372     
373     if (fHasMC){
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
377         }
378       if (fStepsForBackground)
379         fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
380     }
381   }
382
383   //After All cuts
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) {
389         cutName+="&";
390         cutName+=filter.GetCuts()->At(iCut)->GetName();
391       }
392     }
393     if (!fStepsForMCtruthOnly) {
394       fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
395     }
396     if (fHasMC){
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
400         }
401         if (fStepsForBackground)
402           fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
403     }
404   }
405
406   //Additional Step for result after PreFilter
407   if (fStepForPreFilter){
408     cutName="PreFilter";
409     fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
410     if (fHasMC){
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
414         }
415         if (fStepsForBackground)
416           fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
417     }
418   }
419
420
421
422   if (step!=fNSteps) {
423     AliError(Form("Something went wrong in the naming of the steps!!! (%d != %d)",step,fNSteps));
424   }
425 }
426
427 //________________________________________________________________
428 void AliDielectronCF::Fill(UInt_t mask, const AliDielectronPair *particle)
429 {
430   //
431   // Fill the containers
432   //
433
434   // Check the MC truths
435   if(fIsMCTruth) {
436     for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) fIsMCTruth[i]=kFALSE;
437   }
438
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);
442   
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]);
448     }
449     // background is considered that pair which does not fulfill any of the signals
450     isBackground = !isBackground;
451   }
452   
453   Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
454   AliDielectronVarManager::Fill(particle,valuesPair);
455
456   for (Int_t iVar=0; iVar<fNVars; ++iVar){
457     Int_t var=fVariables[iVar];
458     fValues[iVar]=valuesPair[var];
459   }
460
461   if (fNVarsLeg>0){
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);
466
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];
471     }
472   }
473   
474   UInt_t selectedMask=(1<<fNCuts)-1;
475
476   //============//
477   // Fill steps //
478   //============//
479   // Pure MC steps are handled in FillMC
480   Int_t step=0;
481   if (fStepForMCtruth && fIsMCTruth) step+=fSignalsMC->GetEntries();
482   
483   //No cuts (MC truth)
484   if (fStepForNoCutsMCmotherPid && fIsMCTruth){
485     for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
486       if(fIsMCTruth[i]) {
487         fCfContainer->Fill(fValues,step);
488       }
489       ++step;
490     }
491   }
492   
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);
500           ++step;
501         }
502         if (fHasMC){
503           if ( fStepsForSignal && fIsMCTruth){
504             for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
505               if(fIsMCTruth[i]) {
506                 fCfContainer->Fill(fValues,step);
507               }
508               ++step;
509             }
510           }
511           if ( fStepsForBackground ){
512             if (isBackground) fCfContainer->Fill(fValues,step);
513             ++step;
514           }
515         }
516       } else {
517         step+=fNAddSteps;
518       }
519     }
520   }
521   
522
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);
530           ++step;
531         }
532
533         if (fHasMC){
534           if ( fStepsForSignal && fIsMCTruth){
535             for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
536               if(fIsMCTruth[i]) {
537                 fCfContainer->Fill(fValues,step);
538               }
539               ++step;
540             }
541           }
542           if ( fStepsForBackground ){
543             if (isBackground) fCfContainer->Fill(fValues,step);
544             ++step;
545           }
546         }
547       } else {
548         step+=fNAddSteps;
549       }
550     }
551   }
552
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);
559         ++step;
560       }
561       if (fHasMC){
562         if ( fStepsForSignal && fIsMCTruth){
563           for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
564             if(fIsMCTruth[i]) {
565               fCfContainer->Fill(fValues,step);
566             }
567             ++step;
568           }
569         }
570         if ( fStepsForBackground ){
571           if (isBackground) fCfContainer->Fill(fValues,step);
572           ++step;
573         }
574       }
575     } else {
576       step+=fNAddSteps;
577     }
578   }
579   
580   //All cuts
581   if (fStepForAfterAllCuts){
582     if (mask == selectedMask){
583       if(!fStepsForMCtruthOnly) {
584         fCfContainer->Fill(fValues,step);
585         ++step;
586       }
587
588       if (fHasMC){
589         if ( fStepsForSignal && fIsMCTruth){
590           for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
591             if(fIsMCTruth[i]) {
592               fCfContainer->Fill(fValues,step);
593             }
594             ++step;
595           }
596         }
597         if ( fStepsForBackground ){
598           if (isBackground) fCfContainer->Fill(fValues,step);
599           ++step;
600         }
601       }
602     } else {
603       step+=fNAddSteps;
604     }
605   }
606
607   //prefilter
608   if (fStepForPreFilter) {
609     if (mask&(1<<fNCuts)) {
610       if(!fStepsForMCtruthOnly) {
611         fCfContainer->Fill(fValues,step);
612         ++step;
613       }
614       if (fHasMC){
615         if ( fStepsForSignal && fIsMCTruth){
616           for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
617             if(fIsMCTruth[i]) {
618               fCfContainer->Fill(fValues,step);
619             }
620             ++step;
621           }
622         }
623         if ( fStepsForBackground ){
624           if (isBackground) fCfContainer->Fill(fValues,step);
625           ++step;
626         }
627       }
628     }
629     else {
630       step+=fNAddSteps;
631     }
632   }
633   
634   if (step!=fNSteps) {
635     AliError("Something went wrong in the step filling!!!");
636   }
637 }
638
639 //________________________________________________________________
640 void AliDielectronCF::FillMC(const TObject *particle)
641 {
642   //
643   // fill MC part of the Container
644   //
645   if (!fStepForMCtruth) return;
646   
647   Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
648   AliDielectronVarManager::Fill(particle,valuesPair);
649
650   AliVParticle *d1=0x0;
651   AliVParticle *d2=0x0;
652   AliDielectronMC::Instance()->GetDaughters(particle,d1,d2);
653   
654   //TODO: temporary solution, set manually the pair type to 1: unlikesign SE
655   valuesPair[AliDielectronVarManager::kPairType]=1;
656   
657   for (Int_t iVar=0; iVar<fNVars; ++iVar){
658     Int_t var=fVariables[iVar];
659     fValues[iVar]=valuesPair[var];
660   }
661   
662   if (fNVarsLeg>0){
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);
668     } else {
669       AliDielectronVarManager::Fill(d2,valuesLeg1);
670       AliDielectronVarManager::Fill(d1,valuesLeg2);
671     }
672     
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];
677     }
678   }
679   
680   fCfContainer->Fill(fValues,0);
681 }
682
683
684 //________________________________________________________________
685 void AliDielectronCF::FillMC(Int_t label1, Int_t label2, Int_t nSignal) {
686   //
687   // fill the pure MC part of the container starting from a pair of 2 particles (part1 and part2 are legs)
688   //
689   if (!fStepForMCtruth) return;
690
691   AliVParticle* part1 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label1);
692   AliVParticle* part2 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label2);
693
694   AliDielectronMC* dieMC = AliDielectronMC::Instance();
695
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;
702     
703   // fill the leg variables
704   if (fNVarsLeg>0){
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);
710     } else {
711       AliDielectronVarManager::Fill(part2,valuesLeg1);
712       AliDielectronVarManager::Fill(part1,valuesLeg2);
713     }
714     
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];
719     }
720   }
721
722   Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
723   AliDielectronVarManager::Fill(dieMC->GetMCEvent(), valuesPair);
724   AliDielectronVarManager::FillVarMCParticle2(part1,part2,valuesPair);
725
726   if(part1->Charge()*part2->Charge()<0)
727     valuesPair[AliDielectronVarManager::kPairType]=1;
728   else if(part1->Charge()>0)
729     valuesPair[AliDielectronVarManager::kPairType]=0;
730   else
731     valuesPair[AliDielectronVarManager::kPairType]=2; // if one of the two particles is neutral, the pair will go here
732
733   for(Int_t iVar=0; iVar<fNVars; ++iVar){
734     Int_t var=fVariables[iVar];
735     fValues[iVar]=valuesPair[var];
736   }
737
738   fCfContainer->Fill(fValues,nSignal);
739 }
740
741
742 //_____________________________________________________________________________
743 TVectorD* AliDielectronCF::MakeLogBinning(Int_t nbinsX, Double_t xmin, Double_t xmax) const
744 {
745   //
746   // Make logarithmic binning
747   // the user has to delete the array afterwards!!!
748   //
749   
750   //check limits
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);
754   }
755   if (xmax<xmin){
756     Double_t tmp=xmin;
757     xmin=xmax;
758     xmax=tmp;
759   }
760   TVectorD *binLim=new TVectorD(nbinsX+1);
761   Double_t first=xmin;
762   Double_t last=xmax;
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);
766   }
767   return binLim;
768 }
769
770 //_____________________________________________________________________________
771 TVectorD* AliDielectronCF::MakeLinBinning(Int_t nbinsX, Double_t xmin, Double_t xmax) const
772 {
773   //
774   // Make logarithmic binning
775   // the user has to delete the array afterwards!!!
776   //
777   if (xmax<xmin){
778     Double_t tmp=xmin;
779     xmin=xmax;
780     xmax=tmp;
781   }
782   TVectorD *binLim=new TVectorD(nbinsX+1);
783   Double_t first=xmin;
784   Double_t last=xmax;
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;
788   }
789   return binLim;
790 }
791