]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGDQ/dielectron/AliDielectronHF.cxx
filtering updates
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliDielectronHF.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 HF                                  //
18 //                                                                       //
19 //                                                                       //
20 /*
21 Detailed description
22
23
24 */
25 //                                                                       //
26 ///////////////////////////////////////////////////////////////////////////
27
28 #include <TVectorD.h>
29 #include <TH1.h>
30 #include <TH1F.h>
31 #include <TH2.h>
32 #include <TH3.h>
33 #include <TProfile.h>
34 #include <TProfile2D.h>
35 #include <TProfile3D.h>
36 #include <TAxis.h>
37 #include <TString.h>
38 #include <TObjString.h>
39 #include <TObjArray.h>
40
41 #include <AliVParticle.h>
42 #include <AliLog.h>
43
44 #include "AliDielectron.h"
45 #include "AliDielectronHelper.h"
46 #include "AliDielectronMC.h"
47 #include "AliDielectronPair.h"
48 #include "AliDielectronSignalMC.h"
49
50 #include "AliDielectronHistos.h"
51 #include "AliDielectronHF.h"
52
53 ClassImp(AliDielectronHF)
54
55 AliDielectronHF::AliDielectronHF() :
56   TNamed(),
57   fUsedVars(new TBits(AliDielectronVarManager::kNMaxValues)),
58   fArrPairType(),
59   fPairType(kSeOnlyOS),
60   fSignalsMC(0x0),
61   fAxes(kMaxCuts),
62   fHasMC(kFALSE),
63   fStepGenerated(kFALSE),
64   fRefObj(1)
65 {
66   //
67   // Default Constructor
68   //
69   for (Int_t i=0; i<kMaxCuts; ++i){
70     fVarCuts[i]=0;
71     fVarCutType[i]=0;
72     fBinType[i]=kStdBin;
73   }
74   fAxes.SetOwner(kTRUE);
75   fRefObj.SetOwner(kTRUE);
76   fArrPairType.SetOwner(kTRUE);
77 }
78
79 //______________________________________________
80 AliDielectronHF::AliDielectronHF(const char* name, const char* title) :
81   TNamed(name, title),
82   fUsedVars(new TBits(AliDielectronVarManager::kNMaxValues)),
83   fArrPairType(),
84   fPairType(kSeOnlyOS),
85   fSignalsMC(0x0),
86   fAxes(kMaxCuts),
87   fHasMC(kFALSE),
88   fStepGenerated(kFALSE),
89   fRefObj(1)
90 {
91   //
92   // Named Constructor
93   //
94   for (Int_t i=0; i<kMaxCuts; ++i){
95     fVarCuts[i]=0;
96     fVarCutType[i]=0;
97     fBinType[i]=kStdBin;
98   }
99   fAxes.SetOwner(kTRUE);
100   fRefObj.SetOwner(kTRUE);
101   fArrPairType.SetOwner(kTRUE);
102 }
103
104 //______________________________________________
105 AliDielectronHF::~AliDielectronHF()
106 {
107   //
108   // Default Destructor
109   //
110   if(fUsedVars) delete fUsedVars;
111   fAxes.Delete();
112   fRefObj.Delete();
113   fArrPairType.Delete();
114 }
115
116 //_____________________________________________________________________________
117 void AliDielectronHF::UserProfile(const char* histClass, UInt_t valTypeP,
118                                       const TVectorD * const binsX,
119                                       UInt_t valTypeX, TString option, UInt_t valTypeW)
120 {
121   //
122   // Histogram creation 1D case with arbitraty binning X
123   // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
124   //
125
126   TH1 *hist=0x0;
127   if(valTypeP==AliDielectronHistos::kNoProfile)
128     hist=new TH1F("","",binsX->GetNrows()-1,binsX->GetMatrixArray());
129   else {
130     TString opt=""; Double_t pmin=0., pmax=0.;
131     if(!option.IsNull()) {
132       TObjArray *arr=option.Tokenize(";");
133       arr->SetOwner();
134       opt=((TObjString*)arr->At(0))->GetString();
135       if(arr->GetEntriesFast()>1) pmin=(((TObjString*)arr->At(1))->GetString()).Atof();
136       if(arr->GetEntriesFast()>2) pmax=(((TObjString*)arr->At(2))->GetString()).Atof();
137       delete arr;
138     }
139     hist=new TProfile("","",binsX->GetNrows()-1,binsX->GetMatrixArray());
140     ((TProfile*)hist)->BuildOptions(pmin,pmax,opt.Data());
141     //      printf(" name %s PROFILE options: pmin %.1f pmax %.1f err %s \n",name,((TProfile*)hist)->GetYmin(),((TProfile*)hist)->GetYmax(),((TProfile*)hist)->GetErrorOption() );
142   }
143
144   // store variales in axes
145   UInt_t valType[4] = {0};
146   valType[0]=valTypeX;     valType[1]=valTypeP;
147   AliDielectronHistos::StoreVariables(hist, valType);
148   hist->SetUniqueID(valTypeW); // store weighting variable
149
150   for(Int_t i=0; i<4; i++)   fUsedVars->SetBitNumber(valType[i],kTRUE);
151   fUsedVars->SetBitNumber(valTypeW,kTRUE);
152
153   // adapt the name and title of the histogram in case they are empty
154   AliDielectronHistos::AdaptNameTitle(hist, histClass);
155   hist->SetName(Form("HF_%s",hist->GetName()));
156
157   fRefObj.AddLast(hist);
158   delete binsX;
159 }
160
161 //_____________________________________________________________________________
162 void AliDielectronHF::UserProfile(const char* histClass, UInt_t valTypeP,
163                                       const TVectorD * const binsX, const TVectorD * const binsY,
164                                       UInt_t valTypeX, UInt_t valTypeY, TString option, UInt_t valTypeW)
165 {
166   //
167   // Histogram creation 2D case with arbitraty binning X and Y
168   // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
169   //
170
171   TH1 *hist=0x0;
172   if(valTypeP==AliDielectronHistos::kNoProfile) {
173     hist=new TH2F("","",
174                   binsX->GetNrows()-1,binsX->GetMatrixArray(),
175                   binsY->GetNrows()-1,binsY->GetMatrixArray()); 
176   }
177   else  {
178     TString opt=""; Double_t pmin=0., pmax=0.;
179     if(!option.IsNull()) {
180       TObjArray *arr=option.Tokenize(";");
181       arr->SetOwner();
182       opt=((TObjString*)arr->At(0))->GetString();
183       if(arr->GetEntriesFast()>1) pmin=(((TObjString*)arr->At(1))->GetString()).Atof();
184       if(arr->GetEntriesFast()>2) pmax=(((TObjString*)arr->At(2))->GetString()).Atof();
185       delete arr;
186     }
187     hist=new TProfile2D("","",
188                         binsX->GetNrows()-1,binsX->GetMatrixArray(),
189                         binsY->GetNrows()-1,binsY->GetMatrixArray());
190     ((TProfile2D*)hist)->BuildOptions(pmin,pmax,opt.Data());
191   }
192
193   // store variales in axes
194   UInt_t valType[4] = {0};
195   valType[0]=valTypeX;     valType[1]=valTypeY; valType[2]=valTypeP;
196   AliDielectronHistos::StoreVariables(hist, valType);
197   hist->SetUniqueID(valTypeW); // store weighting variable
198
199   for(Int_t i=0; i<4; i++)   fUsedVars->SetBitNumber(valType[i],kTRUE);
200   fUsedVars->SetBitNumber(valTypeW,kTRUE);
201
202   // adapt the name and title of the histogram in case they are empty
203   AliDielectronHistos::AdaptNameTitle(hist, histClass);
204   hist->SetName(Form("HF_%s",hist->GetName()));
205
206   fRefObj.AddLast(hist);
207   delete binsX;
208   delete binsY;
209 }
210
211 //_____________________________________________________________________________
212 void AliDielectronHF::UserProfile(const char* histClass, UInt_t valTypeP,
213                                       const TVectorD * const binsX, const TVectorD * const binsY, const TVectorD * const binsZ,
214                                       UInt_t valTypeX, UInt_t valTypeY, UInt_t valTypeZ, TString option, UInt_t valTypeW)
215 {
216   //
217   // Histogram creation 3D case with arbitraty binning X, Y, Z
218   // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
219   //
220   TH1 *hist=0x0;
221   if(valTypeP==AliDielectronHistos::kNoProfile) {
222     hist=new TH3F("","",
223                   binsX->GetNrows()-1,binsX->GetMatrixArray(),
224                   binsY->GetNrows()-1,binsY->GetMatrixArray(),
225                   binsZ->GetNrows()-1,binsZ->GetMatrixArray());
226   }
227   else {
228     TString opt=""; Double_t pmin=0., pmax=0.;
229     if(!option.IsNull()) {
230       TObjArray *arr=option.Tokenize(";");
231       arr->SetOwner();
232       opt=((TObjString*)arr->At(0))->GetString();
233       if(arr->GetEntriesFast()>1) pmin=(((TObjString*)arr->At(1))->GetString()).Atof();
234       if(arr->GetEntriesFast()>2) pmax=(((TObjString*)arr->At(2))->GetString()).Atof();
235       delete arr;
236     }
237     hist=new TProfile3D("","",
238                         binsX->GetNrows()-1,binsX->GetMatrixArray(),
239                         binsY->GetNrows()-1,binsY->GetMatrixArray(),
240                         binsZ->GetNrows()-1,binsZ->GetMatrixArray());
241     ((TProfile3D*)hist)->BuildOptions(pmin,pmax,opt.Data());
242   }
243
244   // store variales in axes
245   UInt_t valType[4] = {0};
246   valType[0]=valTypeX;     valType[1]=valTypeY;     valType[2]=valTypeZ;     valType[3]=valTypeP;
247   AliDielectronHistos::StoreVariables(hist, valType);
248   hist->SetUniqueID(valTypeW); // store weighting variable
249
250   for(Int_t i=0; i<4; i++)   fUsedVars->SetBitNumber(valType[i],kTRUE);
251   fUsedVars->SetBitNumber(valTypeW,kTRUE);
252
253   // adapt the name and title of the histogram in case they are empty
254   AliDielectronHistos::AdaptNameTitle(hist, histClass);
255   hist->SetName(Form("HF_%s",hist->GetName()));
256
257   fRefObj.AddLast(hist);
258   delete binsX;
259   delete binsY;
260   delete binsZ;
261 }
262
263 //________________________________________________________________
264 void AliDielectronHF::AddCutVariable(AliDielectronVarManager::ValueTypes type,
265                                      Int_t nbins, Double_t min, Double_t max, Bool_t log, Bool_t leg, EBinType btype)
266 {
267   //
268   // Add a variable to the mixing handler
269   //
270
271   // limit number of variables to kMaxCuts
272   if (fAxes.GetEntriesFast()>=kMaxCuts) return;
273   
274   TVectorD *binLimits=0x0;
275   if (!log) binLimits=AliDielectronHelper::MakeLinBinning(nbins,min,max);
276   else binLimits=AliDielectronHelper::MakeLogBinning(nbins,min,max);
277   if (!binLimits) return;
278
279   Int_t size=fAxes.GetEntriesFast();
280   fVarCuts[size]=(UShort_t)type;
281   fVarCutType[size]=leg;
282   fAxes.Add(binLimits->Clone());
283   fBinType[size]=btype;
284   fUsedVars->SetBitNumber(type,kTRUE);
285 }
286
287 //________________________________________________________________
288 void AliDielectronHF::AddCutVariable(AliDielectronVarManager::ValueTypes type,
289                                              const char* binLimitStr, Bool_t leg, EBinType btype)
290 {
291   //
292   // Add a variable to the mixing handler with arbitrary binning
293   //
294
295   // limit number of variables to kMaxCuts
296   if (fAxes.GetEntriesFast()>=kMaxCuts) return;
297   
298   TVectorD *binLimits=AliDielectronHelper::MakeArbitraryBinning(binLimitStr);
299   if (!binLimits) return;
300   
301   Int_t size=fAxes.GetEntriesFast();
302   fVarCuts[size]=(UShort_t)type;
303   fVarCutType[size]=leg;
304   fAxes.Add(binLimits);
305   fBinType[size]=btype;
306   fUsedVars->SetBitNumber(type,kTRUE);
307 }
308
309 //________________________________________________________________
310 void AliDielectronHF::AddCutVariable(AliDielectronVarManager::ValueTypes type,
311                                              TVectorD * binLimits, Bool_t leg, EBinType btype)
312 {
313   //
314   // Add a variable to the mixing handler with a vector
315   // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
316   //
317
318   // limit number of variables to kMaxCuts
319   if (fAxes.GetEntriesFast()>=kMaxCuts) return;
320   
321   if (!binLimits) return;
322   
323   Int_t size=fAxes.GetEntriesFast();
324   fVarCuts[size]=(UShort_t)type;
325   fVarCutType[size]=leg;
326   fAxes.Add(binLimits);
327   fBinType[size]=btype;
328   fUsedVars->SetBitNumber(type,kTRUE);
329 }
330
331 //______________________________________________
332 void AliDielectronHF::Fill(Int_t label1, Int_t label2, Int_t nSignal) 
333 {
334   //
335   // fill the pure MC part of the container starting from a pair of 2 particles (part1 and part2 are legs)
336   //
337   // fill only if we have asked for these steps
338   if(!fStepGenerated) return;
339
340   AliVParticle* part1 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label1);
341   AliVParticle* part2 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label2);
342   if(!part1 || !part2) return;
343
344   AliDielectronMC* dieMC = AliDielectronMC::Instance();
345   
346   Int_t mLabel1 = dieMC->GetMothersLabel(label1);    // should work for both ESD and AOD
347   Int_t mLabel2 = dieMC->GetMothersLabel(label2);
348
349   // check the same mother option
350   AliDielectronSignalMC* sigMC = (AliDielectronSignalMC*)fSignalsMC->At(nSignal);
351   if(sigMC->GetMothersRelation()==AliDielectronSignalMC::kSame && mLabel1!=mLabel2) return;
352   if(sigMC->GetMothersRelation()==AliDielectronSignalMC::kDifferent && mLabel1==mLabel2) return;
353     
354   AliDielectronVarManager::SetFillMap(fUsedVars);
355   // fill the leg variables
356   Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues];
357   Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues];
358   AliDielectronVarManager::Fill(part1,valuesLeg1);
359   AliDielectronVarManager::Fill(part2,valuesLeg2);
360     
361   // fill the pair and event variables
362   Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
363   AliDielectronVarManager::Fill(dieMC->GetMCEvent(), valuesPair);
364   AliDielectronVarManager::FillVarMCParticle2(part1,part2,valuesPair);
365
366   // if pair types are filled, fill mc sources at the end
367   Int_t istep=0;
368   if(fPairType!=kMConly) istep=AliDielectron::kEv1PMRot+1;
369
370   // only OS at the moment
371   if(part1->Charge()*part2->Charge()<0) {
372     Fill(istep+nSignal+fSignalsMC->GetEntries(), valuesPair,  valuesLeg1, valuesLeg2);
373   }
374
375   return;
376 }
377 //______________________________________________
378 void AliDielectronHF::Fill(Int_t pairIndex, const AliDielectronPair *particle)
379 {
380   //
381   // fill histograms for event, pair and daughter cuts and pair types
382   //
383   
384   // only OS pairs in case of MC
385   //////////////////////////////  if(fHasMC && pairIndex!=AliDielectron::kEv1PM) return;
386
387   // only selected pair types in case of data
388   if(!IsPairTypeSelected(pairIndex)) return;
389
390   // get event and pair variables
391   Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
392   AliDielectronVarManager::SetFillMap(fUsedVars);
393   AliDielectronVarManager::Fill(particle,valuesPair);
394
395   // get leg variables (TODO: do not fill for the moment since leg cuts are not opened)
396   Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues]={0};
397   //AliDielectronVarManager::Fill(particle->GetFirstDaughter(),valuesLeg1);
398   Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues]={0};
399   //AliDielectronVarManager::Fill(particle->GetSecondDaughter(),valuesLeg2);
400
401   // fill
402
403   // if pair types are filled, fill mc sources at the end
404   Int_t istep = 0;
405   if(fPairType!=kMConly) istep=AliDielectron::kEv1PMRot+1;
406
407   // mc source steps (only OS SE pairs)
408   if(fHasMC && fSignalsMC && pairIndex==AliDielectron::kEv1PM) {
409     for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
410       if(AliDielectronMC::Instance()->IsMCTruth(particle, (AliDielectronSignalMC*)fSignalsMC->At(i)))
411         Fill(istep+i, valuesPair,  valuesLeg1, valuesLeg2);
412     }
413   }
414
415   // all pair types w/o use of mc information
416   if(fPairType==kMConly) return;
417
418   // remove comments
419   //// select correct step if we are looking at signals too
420   ////  if(fHasMC && fSignalsMC) pairIndex += ( fSignalsMC->GetEntries() * (fStepGenerated ? 2 : 1) );
421   Fill(pairIndex, valuesPair,  valuesLeg1, valuesLeg2); 
422
423   return;
424 }
425
426 //______________________________________________
427 void AliDielectronHF::Fill(Int_t index, Double_t * const valuesPair, Double_t * const valuesLeg1, Double_t * const valuesLeg2)
428 {
429   //
430   // main fill function using index and values as input
431   //
432
433   TObjArray *histArr = static_cast<TObjArray*>(fArrPairType.At(index));
434   if(!histArr) return;
435
436   Int_t size  = GetNumberOfBins();
437   // loop over all histograms
438   for(Int_t ihist=0; ihist<size; ihist++) {
439
440     Int_t sizeAdd   = 1;
441     Bool_t selected = kTRUE;
442     
443     // loop over all cut variables
444     Int_t nvars = fAxes.GetEntriesFast();
445     for(Int_t ivar=0; ivar<nvars; ivar++) {
446       
447       // get bin limits
448       TVectorD *bins = static_cast<TVectorD*>(fAxes.At(ivar));
449       Int_t nbins    = bins->GetNrows()-1;
450
451       // bin limits for current ivar bin
452       Int_t ibin   = (ihist/sizeAdd)%nbins;
453       Double_t lowEdge = (*bins)[ibin];
454       Double_t upEdge  = (*bins)[ibin+1];
455       switch(fBinType[ivar]) {
456       case kStdBin:     upEdge=(*bins)[ibin+1];     break;
457       case kBinToMax:   upEdge=(*bins)[nbins];      break;
458       case kBinFromMin: lowEdge=(*bins)[0];         break;
459       case kSymBin:     upEdge=(*bins)[nbins-ibin];
460         if(ibin>=((Double_t)(nbins+1))/2) upEdge=(*bins)[nbins]; // to avoid low>up
461         break;
462       }
463
464       // leg variable
465       if(fVarCutType[ivar]) {
466         if( (valuesLeg1[fVarCuts[ivar]] < lowEdge || valuesLeg1[fVarCuts[ivar]] >= upEdge) ||
467             (valuesLeg2[fVarCuts[ivar]] < lowEdge || valuesLeg2[fVarCuts[ivar]] >= upEdge) ) {
468           selected=kFALSE;
469           break;
470         }
471       }
472       else { // pair and event variables
473         if( (valuesPair[fVarCuts[ivar]] < lowEdge || valuesPair[fVarCuts[ivar]] >= upEdge) ) {
474           selected=kFALSE;
475           break;
476         }
477       }
478
479       sizeAdd*=nbins;
480     } //end of var cut loop
481
482     // do not fill the histogram
483     if(!selected) continue;
484
485     // fill the object with Pair and event values
486     TObjArray *tmp = (TObjArray*) histArr->At(ihist);
487     TString title = tmp->GetName();
488     AliDebug(10,title.Data());
489     for(Int_t i=0; i<tmp->GetEntriesFast(); i++) {
490       AliDielectronHistos::FillValues(tmp->At(i), valuesPair);
491     }
492     //    AliDebug(10,Form("Fill var %d %s value %f in %s \n",fVar,AliDielectronVarManager::GetValueName(fVar),valuesPair[fVar],tmp->GetName()));
493   } //end of hist loop
494
495 }
496
497 //______________________________________________
498 void AliDielectronHF::Init()
499 {
500   //
501   // initialise event buffers
502   //
503
504   // has MC signals
505   fHasMC=AliDielectronMC::Instance()->HasMC();
506   Int_t steps = 0;
507   if(fHasMC) steps=fSignalsMC->GetEntries();
508   if(fStepGenerated) steps*=2; 
509
510   // init pair type array
511   fArrPairType.SetName(Form("%s_HF",GetName()));
512   if(fHasMC && fPairType==kMConly) fArrPairType.Expand(steps);
513   else fArrPairType.Expand(AliDielectron::kEv1PMRot+1+steps);
514
515   Int_t size  = GetNumberOfBins();
516   AliDebug(10,Form("Creating a histo array with size %d \n",size));
517
518   Int_t sizeAdd  = 1; 
519
520   // fill object array with the array of bin cells
521   TObjArray *histArr = new TObjArray(0);
522   if(!histArr) return;
523   histArr->SetOwner(kTRUE);
524   histArr->Expand(size);
525
526   //  printf("fRefObj %p \n",fRefObj);
527   // array of histograms to each bin cell
528   for(Int_t ihist=0; ihist<size; ihist++) {
529     histArr->AddAt(fRefObj.Clone(""), ihist);
530     //histArr->AddAt(fRefObj.Clone(Form("h%04d",ihist)), ihist);
531   }
532
533   // loop over all cut variables and do the naming according to its bin cell
534   Int_t nvars = fAxes.GetEntriesFast();
535   for(Int_t ivar=0; ivar<nvars; ivar++) {
536     
537     // get bin limits
538     TVectorD *bins = static_cast<TVectorD*>(fAxes.At(ivar));
539     Int_t nbins    = bins->GetNrows()-1;
540
541
542     // loop over all bin cells an set unique titles
543     for(Int_t ihist=0; ihist<size; ihist++) {
544
545       // get the lower limit for current ivar bin
546       Int_t ibin   = (ihist/sizeAdd)%nbins; 
547       Double_t lowEdge = (*bins)[ibin];
548       Double_t upEdge  = (*bins)[ibin+1];
549       switch(fBinType[ivar]) {
550       case kStdBin:     upEdge=(*bins)[ibin+1];     break;
551       case kBinToMax:   upEdge=(*bins)[nbins];      break;
552       case kBinFromMin: lowEdge=(*bins)[0];         break;
553       case kSymBin:     upEdge=(*bins)[nbins-ibin];
554         if(ibin>=((Double_t)(nbins+1))/2) upEdge=(*bins)[nbins]; // to avoid low>up
555         break;
556       }
557
558       TObjArray *tmp= (TObjArray*) histArr->At(ihist);
559       TString title = tmp->GetName();
560       if(!ivar)             title ="";
561       if( ivar)             title+=":";
562       if(fVarCutType[ivar]) title+="Leg";
563       title+=AliDielectronVarManager::GetValueName(fVarCuts[ivar]);
564       title+=Form("#%.2f#%.2f",lowEdge,upEdge);
565       tmp->SetName(title.Data());
566       AliDebug(10,title.Data());
567     } // end: array of bin cell
568     sizeAdd*=nbins;
569   } //end: cut loop
570
571   // copy array to the selected pair types/ MC sources
572
573   // pair types
574   Int_t istep=0;
575   if(fPairType != kMConly) {
576     for(istep=0; istep<AliDielectron::kEv1PMRot+1; istep++) {
577
578       if(IsPairTypeSelected(istep)) {
579         // add a deep copy of the array
580         fArrPairType[istep]=(TObjArray*)histArr->Clone(AliDielectron::PairClassName(istep));
581         ((TObjArray*)fArrPairType[istep])->SetOwner();
582       }
583       else {
584         fArrPairType[istep]=new TObjArray(0);
585         ((TObjArray*)fArrPairType[istep])->SetOwner();
586         ((TObjArray*)fArrPairType[istep])->SetName(AliDielectron::PairClassName(istep));
587       }
588     } //end: loop over pair types
589   }
590
591   // mc sources
592   if(fHasMC) {
593     for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
594       TString title = Form("(Signal: %s)",fSignalsMC->At(i)->GetTitle());
595       fArrPairType[istep+i]=(TObjArray*)histArr->Clone(title.Data());
596       if(fStepGenerated)  {
597         title+=" MC truth";
598         fArrPairType[istep+i+fSignalsMC->GetEntries()]=(TObjArray*)histArr->Clone(title.Data());
599       }
600     } // end: loop over sources
601   }
602
603
604   // clean up
605   if(histArr) {
606     delete histArr;
607     histArr=0;
608   }
609
610 }
611
612 //______________________________________________
613 Int_t AliDielectronHF::GetNumberOfBins() const
614 {
615   //
616   // return the number of bins this histogram grid has
617   //
618   Int_t size=1;
619   for (Int_t i=0; i<fAxes.GetEntriesFast(); ++i)
620     size*=((static_cast<TVectorD*>(fAxes.At(i)))->GetNrows()-1);
621   return size;
622 }
623
624 //______________________________________________
625 Bool_t AliDielectronHF::IsPairTypeSelected(Int_t itype)
626 {
627   //
628   // check whether a pair type was selected
629   // TODO: cross check or replace by mixinghandlers processsing
630
631   Bool_t selected = kFALSE;
632
633   // fill all
634   if(fPairType==kAll) return kTRUE;
635
636   switch(itype) {
637   case AliDielectron::kEv1PP:
638   case AliDielectron::kEv1MM:
639     if(fPairType==kSeAll || fPairType==kSeMeAll || fPairType==kSeReAll )   selected = kTRUE;
640     break;
641   case AliDielectron::kEv1PM:
642     if(fPairType!=kMeOnlyOS)  selected = kTRUE;
643     break;
644   case AliDielectron::kEv1PEv2P:
645   case AliDielectron::kEv1MEv2M:
646     if(fPairType==kMeAll || fPairType==kSeMeAll)   selected = kTRUE;
647     break;
648   case AliDielectron::kEv1PEv2M:
649     if(fPairType==kMeAll || fPairType==kSeMeAll) selected = kTRUE;
650     break;
651   case AliDielectron::kEv1MEv2P:
652     if(fPairType==kMeAll || fPairType==kSeMeAll || fPairType==kMeOnlyOS || fPairType==kSeMeOnlyOS)   selected = kTRUE;
653     break;
654   case AliDielectron::kEv2PP:
655   case AliDielectron::kEv2PM:
656   case AliDielectron::kEv2MM:
657     selected = kFALSE;
658     break;
659   case AliDielectron::kEv1PMRot:
660     if(fPairType==kSeReAll || fPairType==kSeReOnlyOS)   selected = kTRUE;
661     break;
662   }
663
664   return selected;
665
666 }
667
668