Add a draw class for the CORRFW (produces a warning, will be fixed
[u/mrichter/AliRoot.git] / PWG3 / dielectron / AliDielectronCF.cxx
1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
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 **************************************************************************/
15
16 ///////////////////////////////////////////////////////////////////////////
17 //       Dielectron Correction framework manager                         //
18 //                                                                       //
19 /*
20
21
22
23
24
25
26
27
28
29 */
30 //                                                                       //
31 ///////////////////////////////////////////////////////////////////////////
32
33 #include <TList.h>
34
35 #include <AliCFContainer.h>
36 #include <AliAnalysisFilter.h>
37 #include <AliAnalysisCuts.h>
38 #include <AliVParticle.h>
39 #include <AliLog.h>
40
41 #include "AliDielectronCF.h"
42 #include "AliDielectronMC.h"
43 #include "AliDielectronPair.h"
44
45 ClassImp(AliDielectronCF)
46
47 AliDielectronCF::AliDielectronCF() :
48   TNamed("DielectronCF","DielectronCF"),
49   fNSteps(0),
50   fNVars(0),
51   fNVarsLeg(0),
52   fNCuts(0),
53   fValues(0x0),
54   fStepForMCtruth(kFALSE),
55   fStepForNoCutsMCmotherPid(kFALSE),
56   fStepForAfterAllCuts(kTRUE),
57   fStepsForEachCut(kFALSE),
58   fStepsForCutsIncreasing(kFALSE),
59   fNStepMasks(0),
60   fPdgMother(-1),
61   fCfContainer(0x0)
62 {
63   //
64   // Default constructor
65   //
66   for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
67     fVariables[i]=0;
68   }
69
70   for (Int_t i=0; i<kNmaxAddSteps; ++i){
71     fNBins[i]=0;
72     fVarLoLimit[i]=0.;
73     fVarUpLimit[i]=0.;
74     fNBinsLeg[i]=0;
75     fVarLoLimitLeg[i]=0.;
76     fVarUpLimitLeg[i]=0.;
77     fStepMasks[i]=0xFFFFFF;
78   }
79 }
80
81 //________________________________________________________________
82 AliDielectronCF::AliDielectronCF(const char* name, const char* title) :
83   TNamed(name, title),
84   fNSteps(0),
85   fNVars(0),
86   fNVarsLeg(0),
87   fNCuts(0),
88   fValues(0x0),
89   fStepForMCtruth(kFALSE),
90   fStepForNoCutsMCmotherPid(kFALSE),
91   fStepForAfterAllCuts(kTRUE),
92   fStepsForEachCut(kFALSE),
93   fStepsForCutsIncreasing(kFALSE),
94   fNStepMasks(0),
95   fPdgMother(-1),
96   fCfContainer(0x0)
97 {
98   //
99   // Named constructor
100   //
101   for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
102     fVariables[i]=0;
103   }
104   
105   for (Int_t i=0; i<kNmaxAddSteps; ++i){
106     fNBins[i]=0;
107     fVarLoLimit[i]=0.;
108     fVarUpLimit[i]=0.;
109     fNBinsLeg[i]=0;
110     fVarLoLimitLeg[i]=0.;
111     fVarUpLimitLeg[i]=0.;
112     fStepMasks[i]=0xFFFFFF;
113   }
114 }
115
116 //________________________________________________________________
117 AliDielectronCF::~AliDielectronCF()
118 {
119   //
120   // Destructor
121   //
122   if (fValues) delete [] fValues;
123 }
124
125 //________________________________________________________________
126 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, Int_t nbins, Double_t min, Double_t max, Bool_t leg)
127 {
128   //
129   // Add a variable to the CF configuration
130   //
131
132   if (!leg){
133     fVariables[fNVars]  = (UInt_t)type;
134     fVarLoLimit[fNVars] = min;
135     fVarUpLimit[fNVars] = max;
136     fNBins[fNVars]      = nbins;
137     ++fNVars;
138   } else {
139     fVariablesLeg[fNVarsLeg]  = (UInt_t)type;
140     fVarLoLimitLeg[fNVarsLeg] = min;
141     fVarUpLimitLeg[fNVarsLeg] = max;
142     fNBinsLeg[fNVarsLeg]      = nbins;
143     ++fNVarsLeg;
144   }
145 }
146
147 //________________________________________________________________
148 void AliDielectronCF::InitialiseContainer(const AliAnalysisFilter& filter)
149 {
150   //
151   // Initialise container based on the cuts in the analysis filter
152   //
153
154   fNCuts=filter.GetCuts()->GetEntries();
155
156   fNSteps=0;
157   if (fStepForMCtruth) ++fNSteps;
158   if (fStepForNoCutsMCmotherPid) ++fNSteps;
159   if (fStepForAfterAllCuts) fNSteps+=2;
160   
161   if (fStepsForEachCut&&fNCuts>1)        fNSteps+=(2*fNCuts);     //one step for each cut + MC truth
162   if (fStepsForCutsIncreasing&&fNCuts>2) fNSteps+=(2*(fNCuts-2)); //one step for the increasing cuts + MC truth
163                                                       // e.g. cut2&cut3, cut2&cut3&cut4
164   fNSteps+=(2*fNStepMasks);                            // cuts for the additional cut masks
165   // create the container
166   Int_t *nbins=new Int_t[fNVars+2*fNVarsLeg];
167   for (Int_t i=0;i<fNVars;++i)    nbins[i]=fNBins[i];
168   for (Int_t i=0;i<fNVarsLeg;++i) nbins[i+fNVars]=fNBinsLeg[i];
169   for (Int_t i=0;i<fNVarsLeg;++i) nbins[i+fNVars+fNVarsLeg]=fNBinsLeg[i];
170   
171   fCfContainer = new AliCFContainer(GetName(), GetTitle(), fNSteps, fNVars+2*fNVarsLeg, nbins);
172   delete [] nbins;
173   
174   // initialize the variables and their bin limits
175   for (Int_t iVar=0; iVar<fNVars; iVar++) {
176     UInt_t type=fVariables[iVar];
177     Int_t    nBins = fNBins[iVar];
178     Double_t loLim = fVarLoLimit[iVar];
179     Double_t upLim = fVarUpLimit[iVar];
180     Double_t *binLim = new Double_t[nBins+1];
181     
182     // set the bin limits
183     for(Int_t iBin=0; iBin<=nBins; iBin++) binLim[iBin] = loLim + (upLim-loLim) / nBins*(Double_t)iBin;
184     
185     fCfContainer->SetBinLimits(iVar, binLim);
186     fCfContainer->SetVarTitle(iVar, AliDielectronVarManager::GetValueName(type));
187     delete [] binLim;
188   }
189   
190   // initialize the variables and their bin limits for the Legs
191   for (Int_t iVar=0; iVar<fNVarsLeg; iVar++) {
192     UInt_t type=fVariablesLeg[iVar];
193     Int_t    nBins = fNBinsLeg[iVar];
194     Double_t loLim = fVarLoLimitLeg[iVar];
195     Double_t upLim = fVarUpLimitLeg[iVar];
196     Double_t *binLim = new Double_t[nBins+1];
197     
198     // set the bin limits
199     for(Int_t iBin=0; iBin<=nBins; iBin++) binLim[iBin] = loLim + (upLim-loLim) / nBins*(Double_t)iBin;
200
201     //Leg1
202     fCfContainer->SetBinLimits(iVar+fNVars, binLim);
203     fCfContainer->SetVarTitle(iVar+fNVars, Form("Leg1_%s",AliDielectronVarManager::GetValueName(type)));
204     
205     //Leg2
206     fCfContainer->SetBinLimits(iVar+fNVars+fNVarsLeg, binLim);
207     fCfContainer->SetVarTitle(iVar+fNVars+fNVarsLeg, Form("Leg2_%s",AliDielectronVarManager::GetValueName(type)));
208     
209     delete [] binLim;
210   }
211
212   // array for storing values
213   fValues = new Double_t[fNVars+2*fNVarsLeg];
214   
215   //=================//
216   // Set step titles //
217   //=================//
218   Int_t step=0;
219
220   //Pure MC truth
221   if (fStepForMCtruth){
222       fCfContainer->SetStepTitle(step++,"MC truth");
223   }
224
225   //before cuts (MC truth)
226   if (fStepForNoCutsMCmotherPid){
227     fCfContainer->SetStepTitle(step++,"No cuts (MC mother)");
228   }
229   
230   //After All cuts
231   TString cutName;
232   if (fStepForAfterAllCuts){
233     cutName="All Cuts"; //TODO: User GetTitle???
234     fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
235     cutName+=" (MC truth)";
236     fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut with MC truth
237   }
238
239   //Steps for each of the cuts
240   if (fStepsForEachCut&&fNCuts>1){
241     for (Int_t iCut=0; iCut<fNCuts;++iCut) {
242       cutName=filter.GetCuts()->At(iCut)->GetName(); //TODO: User GetTitle???
243       fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
244       cutName+=" (MC mother)";
245       fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut with MC truth
246     }
247   }
248
249   //Steps for increasing cut match
250   if (fStepsForCutsIncreasing&&fNCuts>2){
251     cutName=filter.GetCuts()->At(0)->GetName(); //TODO: User GetTitle???
252     for (Int_t iCut=1; iCut<fNCuts-1;++iCut) {
253       cutName+="&";
254       cutName+=filter.GetCuts()->At(iCut)->GetName();
255       fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
256       cutName+=" (MC mother)";
257       fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut with MC truth
258     }
259   }
260
261   //Steps of user defined cut combinations
262   for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
263     cutName="";
264     UInt_t mask=fStepMasks[iComb];
265     for (Int_t iCut=0; iCut<fNCuts;++iCut) {
266       if (mask&(1<<iCut)){
267         if (cutName.IsNull()){
268           cutName=filter.GetCuts()->At(iCut)->GetName();
269         }else{
270           cutName+="&";
271           cutName+=filter.GetCuts()->At(iCut)->GetName();
272         }
273       }
274     }
275     fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
276     cutName+=" (MC mother)";
277     fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut with MC truth
278   }
279
280   if (step!=fNSteps) {
281     AliError("Something went wrong in the naming of the steps!!!");
282   }
283 }
284
285 //________________________________________________________________
286 void AliDielectronCF::Fill(UInt_t mask, const AliDielectronPair *particle)
287 {
288   //
289   // Fill the containers
290   //
291
292   Bool_t isMCTruth=kFALSE;
293   if (fPdgMother>=0) isMCTruth=AliDielectronMC::Instance()->IsMotherPdg(particle,fPdgMother);
294
295   Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
296   AliDielectronVarManager::Fill(particle,valuesPair);
297
298   for (Int_t iVar=0; iVar<fNVars; ++iVar){
299     Int_t var=fVariables[iVar];
300     fValues[iVar]=valuesPair[var];
301   }
302
303   if (fNVarsLeg>0){
304     Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues];
305     AliDielectronVarManager::Fill(particle->GetFirstDaughter(),valuesLeg1);
306     Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues];
307     AliDielectronVarManager::Fill(particle->GetSecondDaughter(),valuesLeg2);
308
309     for (Int_t iVar=0; iVar<fNVarsLeg; ++iVar){
310       Int_t var=fVariablesLeg[iVar];
311       fValues[iVar+fNVars]=valuesLeg1[var];
312       fValues[iVar+fNVars+fNVarsLeg]=valuesLeg2[var];
313     }
314   }
315   
316   UInt_t selectedMask=(1<<fNCuts)-1;
317
318   //============//
319   // Fill steps //
320   //============//
321   // step 0 would be full MC truth and is handled in FillMC
322   Int_t step=0;
323   if (fStepForMCtruth) ++step;
324
325   //No cuts (MC truth)
326   if (fStepForNoCutsMCmotherPid){
327     if (isMCTruth) fCfContainer->Fill(fValues,step);
328     ++step;
329   }
330   
331   //All cuts
332   if (fStepForAfterAllCuts){
333     if (mask == selectedMask){
334       fCfContainer->Fill(fValues,step);
335       ++step;
336       if (isMCTruth) fCfContainer->Fill(fValues,step);
337       ++step;
338     } else {
339       step+=2;
340     }
341   }
342   
343   //Steps for each of the cuts
344   if (fStepsForEachCut&&fNCuts>1){
345     for (Int_t iCut=0; iCut<fNCuts;++iCut) {
346       if (mask&(1<<iCut)) {
347         fCfContainer->Fill(fValues,step);
348         ++step;
349         if (isMCTruth) fCfContainer->Fill(fValues,step);
350         ++step;
351       } else {
352         step+=2;
353       }
354     }
355   }
356
357   //Steps for increasing cut match
358   if (fStepsForCutsIncreasing&&fNCuts>2){
359     for (Int_t iCut=1; iCut<fNCuts-1;++iCut) {
360       if (mask&(1<<((iCut+1)-1))) {
361         fCfContainer->Fill(fValues,step);
362         ++step;
363         if (isMCTruth) fCfContainer->Fill(fValues,step);
364         ++step;
365       } else {
366         step+=2;
367       }
368     }
369   }
370
371   //Steps of user defined cut combinations
372   for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
373     UInt_t userMask=fStepMasks[iComb];
374     if (mask&userMask) {
375       fCfContainer->Fill(fValues,step);
376       ++step;
377       if (isMCTruth) fCfContainer->Fill(fValues,step);
378       ++step;
379     } else {
380       step+=2;
381     }
382   }
383   
384 }
385
386 //________________________________________________________________
387 void AliDielectronCF::FillMC(const TObject *particle)
388 {
389   //
390   // fill MC part of the Container
391   //
392   if (!fStepForMCtruth) return;
393   
394   Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
395   AliDielectronVarManager::Fill(particle,valuesPair);
396   
397   //TODO: temporary solution, set manually the pair type to 1: mixed e+-
398   valuesPair[AliDielectronVarManager::kPairType]=1;
399   
400   for (Int_t iVar=0; iVar<fNVars; ++iVar){
401     Int_t var=fVariables[iVar];
402     fValues[iVar]=valuesPair[var];
403   }
404   
405   if (fNVarsLeg>0){
406     AliVParticle *d1=0x0;
407     AliVParticle *d2=0x0;
408     AliDielectronMC::Instance()->GetDaughters(particle,d1,d2);
409     Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues];
410     AliDielectronVarManager::Fill(d1,valuesLeg1);
411     Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues];
412     AliDielectronVarManager::Fill(d2,valuesLeg2);
413     
414     for (Int_t iVar=0; iVar<fNVarsLeg; ++iVar){
415       Int_t var=fVariablesLeg[iVar];
416       fValues[iVar+fNVars]=valuesLeg1[var];
417       fValues[iVar+fNVars+fNVarsLeg]=valuesLeg2[var];
418     }
419   }
420   
421   fCfContainer->Fill(fValues,0);
422 }
423