]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG3/dielectron/AliDielectronCF.cxx
dd9b03874d14fae19d095c2f487835cf3a849e42
[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 #include <TObjArray.h>
35 #include <TVectorD.h>
36 #include <TString.h>
37 #include <TObjString.h>
38
39 #include <AliCFContainer.h>
40 #include <AliAnalysisFilter.h>
41 #include <AliAnalysisCuts.h>
42 #include <AliVParticle.h>
43 #include <AliLog.h>
44
45 #include "AliDielectronCF.h"
46 #include "AliDielectronMC.h"
47 #include "AliDielectronPair.h"
48
49 ClassImp(AliDielectronCF)
50
51 AliDielectronCF::AliDielectronCF() :
52   TNamed("DielectronCF","DielectronCF"),
53   fNSteps(0),
54   fNVars(0),
55   fVarBinLimits(0x0),
56   fNVarsLeg(0),
57   fVarBinLimitsLeg(0x0),
58   fNCuts(0),
59   fValues(0x0),
60   fStepForMCtruth(kFALSE),
61   fStepForNoCutsMCmotherPid(kFALSE),
62   fStepForAfterAllCuts(kTRUE),
63   fStepsForEachCut(kFALSE),
64   fStepsForCutsIncreasing(kFALSE),
65   fStepsForSignal(kTRUE),
66   fStepsForBackground(kFALSE),
67   fNStepMasks(0),
68   fPdgMother(-1),
69   fCfContainer(0x0),
70   fHasMC(kFALSE),
71   fNAddSteps(0)
72 {
73   //
74   // Default constructor
75   //
76   for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
77     fVariables[i]=0;
78     fVariablesLeg[i]=0;
79   }
80
81   for (Int_t i=0; i<kNmaxAddSteps; ++i){
82     fStepMasks[i]=0xFFFFFF;
83   }
84 }
85
86 //________________________________________________________________
87 AliDielectronCF::AliDielectronCF(const char* name, const char* title) :
88   TNamed(name, title),
89   fNSteps(0),
90   fNVars(0),
91   fVarBinLimits(0x0),
92   fNVarsLeg(0),
93   fVarBinLimitsLeg(0x0),
94   fNCuts(0),
95   fValues(0x0),
96   fStepForMCtruth(kFALSE),
97   fStepForNoCutsMCmotherPid(kFALSE),
98   fStepForAfterAllCuts(kTRUE),
99   fStepsForEachCut(kFALSE),
100   fStepsForCutsIncreasing(kFALSE),
101   fStepsForSignal(kTRUE),
102   fStepsForBackground(kFALSE),
103   fNStepMasks(0),
104   fPdgMother(-1),
105   fCfContainer(0x0),
106   fHasMC(kFALSE),
107   fNAddSteps(0)
108 {
109   //
110   // Named constructor
111   //
112   for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
113     fVariables[i]=0;
114     fVariablesLeg[i]=0;
115   }
116   
117   for (Int_t i=0; i<kNmaxAddSteps; ++i){
118     fStepMasks[i]=0xFFFFFF;
119   }
120 }
121
122 //________________________________________________________________
123 AliDielectronCF::~AliDielectronCF()
124 {
125   //
126   // Destructor
127   //
128   if (fValues) delete [] fValues;
129   if (fVarBinLimits) delete fVarBinLimits;
130   if (fVarBinLimitsLeg) delete fVarBinLimitsLeg;
131 }
132
133 //________________________________________________________________
134 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, Int_t nbins,
135                                   Double_t min, Double_t max, Bool_t leg, Bool_t log)
136 {
137   //
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
141   //
142
143   TVectorD *binLimits=0x0;
144   if (!log) binLimits=MakeLinBinning(nbins,min,max);
145   else binLimits=MakeLogBinning(nbins,min,max);
146   AddVariable(type,binLimits,leg);
147 }
148
149 //________________________________________________________________
150 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, const char* binLimitStr, Bool_t leg/*=kFALSE*/)
151 {
152   //
153   // Add a variable to the CF configuration
154   // specify arbitrary binning in a string.
155   // Bin limits need to be separated by a ","
156   //
157   TString limits(binLimitStr);
158   if (limits.IsNull()){
159     AliError(Form("Bin Limit string is empty, cannot add the variable '%s'",AliDielectronVarManager::GetValueName(type)));
160     return;
161   }
162
163   TObjArray *arr=limits.Tokenize(",");
164   Int_t nLimits=arr->GetEntries();
165   if (nLimits<2){
166     AliError(Form("Need at leas 2 bin limits, cannot add the variable '%s'",AliDielectronVarManager::GetValueName(type)));
167     delete arr;
168     return;
169   }
170
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();
174   }
175
176   delete arr;
177   AddVariable(type,binLimits,leg);
178 }
179
180 //________________________________________________________________
181 void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, TVectorD *binLimits, Bool_t leg/*=kFALSE*/)
182 {
183   //
184   // Add variable with the binning given in the TVectorD
185   //
186   if (!leg){
187     if (!fVarBinLimits){
188       fVarBinLimits=new TObjArray;
189       fVarBinLimits->SetOwner();
190     }
191     fVarBinLimits->Add(binLimits);
192     fVariables[fNVars]  = (UInt_t)type;
193     ++fNVars;
194   } else {
195     if (!fVarBinLimitsLeg){
196       fVarBinLimitsLeg=new TObjArray;
197       fVarBinLimitsLeg->SetOwner();
198     }
199     fVarBinLimitsLeg->Add(binLimits);
200     fVariablesLeg[fNVarsLeg]  = (UInt_t)type;
201     ++fNVarsLeg;
202   }
203 }
204
205 //________________________________________________________________
206 void AliDielectronCF::InitialiseContainer(const AliAnalysisFilter& filter)
207 {
208   //
209   // Initialise container based on the cuts in the analysis filter
210   //
211
212   fNCuts=filter.GetCuts()->GetEntries();
213
214   fHasMC=AliDielectronMC::Instance()->HasMC();
215   fNAddSteps=1;
216   if (fHasMC){
217     if (fStepsForSignal) ++fNAddSteps;
218     if (fStepsForBackground) ++fNAddSteps;
219   } else {
220     //if 
221     fStepForMCtruth=kFALSE;
222     fStepForNoCutsMCmotherPid=kFALSE;
223     fStepsForSignal=kFALSE;
224     fStepsForBackground=kFALSE;
225   }
226     
227   fNSteps=0;
228   if (fStepForMCtruth) ++fNSteps;
229   if (fStepForNoCutsMCmotherPid) ++fNSteps;
230   if (fStepForAfterAllCuts) fNSteps+=fNAddSteps;
231
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
237   
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;
241     nbins[i]=nBins;
242   }
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;
247   }
248   
249   fCfContainer = new AliCFContainer(GetName(), GetTitle(), fNSteps, fNVars+2*fNVarsLeg, nbins);
250   delete [] nbins;
251   
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();
256
257     fCfContainer->SetBinLimits(iVar, binLim);
258     fCfContainer->SetVarTitle(iVar, AliDielectronVarManager::GetValueName(type));
259   }
260   
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();
265
266     //Leg1
267     fCfContainer->SetBinLimits(iVar+fNVars, binLim);
268     fCfContainer->SetVarTitle(iVar+fNVars, Form("Leg1_%s",AliDielectronVarManager::GetValueName(type)));
269     
270     //Leg2
271     fCfContainer->SetBinLimits(iVar+fNVars+fNVarsLeg, binLim);
272     fCfContainer->SetVarTitle(iVar+fNVars+fNVarsLeg, Form("Leg2_%s",AliDielectronVarManager::GetValueName(type)));
273   }
274
275   // array for storing values
276   fValues = new Double_t[fNVars+2*fNVarsLeg];
277   
278   //=================//
279   // Set step titles //
280   //=================//
281   Int_t step=0;
282
283   //Pure MC truth
284   if (fStepForMCtruth){
285     fCfContainer->SetStepTitle(step++,"MC truth");
286   }
287
288   //before cuts (MC truth)
289   if (fStepForNoCutsMCmotherPid){
290     fCfContainer->SetStepTitle(step++,"No cuts (Signal)");
291   }
292   
293   TString cutName;
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???
298       
299       fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
300       
301       if (fHasMC){
302         if (fStepsForSignal)
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
306       }
307     }
308   }
309
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) {
314       cutName+="&";
315       cutName+=filter.GetCuts()->At(iCut)->GetName();
316       
317       fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
318       
319       if (fHasMC){
320         if (fStepsForSignal)
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
324       }
325     }
326   }
327
328   //Steps of user defined cut combinations
329   for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
330     cutName="";
331     UInt_t mask=fStepMasks[iComb];
332     for (Int_t iCut=0; iCut<fNCuts;++iCut) {
333       if (mask&(1<<iCut)){
334         if (cutName.IsNull()){
335           cutName=filter.GetCuts()->At(iCut)->GetName();
336         }else{
337           cutName+="&";
338           cutName+=filter.GetCuts()->At(iCut)->GetName();
339         }
340       }
341     }
342     
343     fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
344     
345     if (fHasMC){
346       if (fStepsForSignal)
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
350     }
351   }
352
353   //After All cuts
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) {
359         cutName+="&";
360         cutName+=filter.GetCuts()->At(iCut)->GetName();
361       }
362     }
363     fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
364     if (fHasMC){
365       if (fStepsForSignal)
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
369     }
370   }
371
372   if (step!=fNSteps) {
373     AliError(Form("Something went wrong in the naming of the steps!!! (%d != %d)",step,fNSteps));
374   }
375 }
376
377 //________________________________________________________________
378 void AliDielectronCF::Fill(UInt_t mask, const AliDielectronPair *particle)
379 {
380   //
381   // Fill the containers
382   //
383
384   Bool_t isMCTruth=kFALSE;
385   if (fHasMC) isMCTruth=AliDielectronMC::Instance()->IsMotherPdg(particle,fPdgMother);
386
387   Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
388   AliDielectronVarManager::Fill(particle,valuesPair);
389
390   for (Int_t iVar=0; iVar<fNVars; ++iVar){
391     Int_t var=fVariables[iVar];
392     fValues[iVar]=valuesPair[var];
393   }
394
395   if (fNVarsLeg>0){
396     Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues];
397     AliDielectronVarManager::Fill(particle->GetFirstDaughter(),valuesLeg1);
398     Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues];
399     AliDielectronVarManager::Fill(particle->GetSecondDaughter(),valuesLeg2);
400
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];
405     }
406   }
407   
408   UInt_t selectedMask=(1<<fNCuts)-1;
409
410   //============//
411   // Fill steps //
412   //============//
413   // step 0 would be full MC truth and is handled in FillMC
414   Int_t step=0;
415   if (fStepForMCtruth) ++step;
416   
417   //No cuts (MC truth)
418   if (fStepForNoCutsMCmotherPid){
419     if (isMCTruth) fCfContainer->Fill(fValues,step);
420     ++step;
421   }
422   
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);
428         ++step;
429
430         if (fHasMC){
431           if ( fStepsForSignal){
432             if (isMCTruth) fCfContainer->Fill(fValues,step);
433             ++step;
434           }
435           if ( fStepsForBackground ){
436             if (!isMCTruth) fCfContainer->Fill(fValues,step);
437             ++step;
438           }
439         }
440       } else {
441         step+=fNAddSteps;
442       }
443     }
444   }
445
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);
451         ++step;
452         
453         if (fHasMC){
454           if ( fStepsForSignal){
455             if (isMCTruth) fCfContainer->Fill(fValues,step);
456             ++step;
457           }
458           if ( fStepsForBackground ){
459             if (!isMCTruth) fCfContainer->Fill(fValues,step);
460             ++step;
461           }
462         }
463       } else {
464         step+=fNAddSteps;
465       }
466     }
467   }
468
469   //Steps of user defined cut combinations
470   for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
471     UInt_t userMask=fStepMasks[iComb];
472     if (mask&userMask) {
473       fCfContainer->Fill(fValues,step);
474       ++step;
475       
476       if (fHasMC){
477         if ( fStepsForSignal){
478           if (isMCTruth) fCfContainer->Fill(fValues,step);
479           ++step;
480         }
481         if ( fStepsForBackground ){
482           if (!isMCTruth) fCfContainer->Fill(fValues,step);
483           ++step;
484         }
485       }
486     } else {
487       step+=fNAddSteps;
488     }
489   }
490   
491   //All cuts
492   if (fStepForAfterAllCuts){
493     if (mask == selectedMask){
494       fCfContainer->Fill(fValues,step);
495       ++step;
496       
497       if (fHasMC){
498         if ( fStepsForSignal){
499           if (isMCTruth) fCfContainer->Fill(fValues,step);
500           ++step;
501         }
502         if ( fStepsForBackground ){
503           if (!isMCTruth) fCfContainer->Fill(fValues,step);
504           ++step;
505         }
506       }
507     } else {
508       step+=fNAddSteps;
509     }
510   }
511   
512   if (step!=fNSteps) {
513     AliError("Something went wrong in the step filling!!!");
514   }
515   
516 }
517
518 //________________________________________________________________
519 void AliDielectronCF::FillMC(const TObject *particle)
520 {
521   //
522   // fill MC part of the Container
523   //
524   if (!fStepForMCtruth) return;
525   
526   Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
527   AliDielectronVarManager::Fill(particle,valuesPair);
528
529   AliVParticle *d1=0x0;
530   AliVParticle *d2=0x0;
531   AliDielectronMC::Instance()->GetDaughters(particle,d1,d2);
532   
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);
537   
538   //TODO: temporary solution, set manually the pair type to 1: unlikesign SE
539   valuesPair[AliDielectronVarManager::kPairType]=1;
540   
541   for (Int_t iVar=0; iVar<fNVars; ++iVar){
542     Int_t var=fVariables[iVar];
543     fValues[iVar]=valuesPair[var];
544   }
545   
546   if (fNVarsLeg>0){
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);
552     } else {
553       AliDielectronVarManager::Fill(d2,valuesLeg1);
554       AliDielectronVarManager::Fill(d1,valuesLeg2);
555     }
556     
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];
561     }
562   }
563   
564   fCfContainer->Fill(fValues,0);
565 }
566
567 //_____________________________________________________________________________
568 TVectorD* AliDielectronCF::MakeLogBinning(Int_t nbinsX, Double_t xmin, Double_t xmax) const
569 {
570   //
571   // Make logarithmic binning
572   // the user has to delete the array afterwards!!!
573   //
574   
575   //check limits
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);
579   }
580   if (xmax<xmin){
581     Double_t tmp=xmin;
582     xmin=xmax;
583     xmax=tmp;
584   }
585   TVectorD *binLim=new TVectorD(nbinsX+1);
586   Double_t first=xmin;
587   Double_t last=xmax;
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);
591   }
592   return binLim;
593 }
594
595 //_____________________________________________________________________________
596 TVectorD* AliDielectronCF::MakeLinBinning(Int_t nbinsX, Double_t xmin, Double_t xmax) const
597 {
598   //
599   // Make logarithmic binning
600   // the user has to delete the array afterwards!!!
601   //
602   if (xmax<xmin){
603     Double_t tmp=xmin;
604     xmin=xmax;
605     xmax=tmp;
606   }
607   TVectorD *binLim=new TVectorD(nbinsX+1);
608   Double_t first=xmin;
609   Double_t last=xmax;
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;
613   }
614   return binLim;
615 }
616