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