1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////////////
34 #include <TProfile2D.h>
35 #include <TProfile3D.h>
38 #include <TObjString.h>
39 #include <TObjArray.h>
41 #include <AliVParticle.h>
44 #include "AliDielectron.h"
45 #include "AliDielectronHelper.h"
46 #include "AliDielectronMC.h"
47 #include "AliDielectronPair.h"
48 #include "AliDielectronSignalMC.h"
50 #include "AliDielectronHistos.h"
51 #include "AliDielectronHF.h"
53 ClassImp(AliDielectronHF)
55 AliDielectronHF::AliDielectronHF() :
62 fStepGenerated(kFALSE),
66 // Default Constructor
68 for (Int_t i=0; i<kMaxCuts; ++i){
73 fAxes.SetOwner(kTRUE);
74 fRefObj.SetOwner(kTRUE);
75 fArrPairType.SetOwner(kTRUE);
78 //______________________________________________
79 AliDielectronHF::AliDielectronHF(const char* name, const char* title) :
86 fStepGenerated(kFALSE),
92 for (Int_t i=0; i<kMaxCuts; ++i){
97 fAxes.SetOwner(kTRUE);
98 fRefObj.SetOwner(kTRUE);
99 fArrPairType.SetOwner(kTRUE);
102 //______________________________________________
103 AliDielectronHF::~AliDielectronHF()
106 // Default Destructor
110 fArrPairType.Delete();
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)
119 // Histogram creation 1D case with arbitraty binning X
120 // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
124 if(valTypeP==AliDielectronHistos::kNoProfile)
125 hist=new TH1F("","",binsX->GetNrows()-1,binsX->GetMatrixArray());
127 TString opt=""; Double_t pmin=0., pmax=0.;
128 if(!option.IsNull()) {
129 TObjArray *arr=option.Tokenize(";");
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();
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() );
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
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()));
151 fRefObj.AddLast(hist);
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)
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!!!
166 if(valTypeP==AliDielectronHistos::kNoProfile) {
168 binsX->GetNrows()-1,binsX->GetMatrixArray(),
169 binsY->GetNrows()-1,binsY->GetMatrixArray());
172 TString opt=""; Double_t pmin=0., pmax=0.;
173 if(!option.IsNull()) {
174 TObjArray *arr=option.Tokenize(";");
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();
181 hist=new TProfile2D("","",
182 binsX->GetNrows()-1,binsX->GetMatrixArray(),
183 binsY->GetNrows()-1,binsY->GetMatrixArray());
184 ((TProfile2D*)hist)->BuildOptions(pmin,pmax,opt.Data());
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
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()));
197 fRefObj.AddLast(hist);
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)
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!!!
212 if(valTypeP==AliDielectronHistos::kNoProfile) {
214 binsX->GetNrows()-1,binsX->GetMatrixArray(),
215 binsY->GetNrows()-1,binsY->GetMatrixArray(),
216 binsZ->GetNrows()-1,binsZ->GetMatrixArray());
219 TString opt=""; Double_t pmin=0., pmax=0.;
220 if(!option.IsNull()) {
221 TObjArray *arr=option.Tokenize(";");
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();
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());
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
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()));
245 fRefObj.AddLast(hist);
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)
256 // Add a variable to the mixing handler
259 // limit number of variables to kMaxCuts
260 if (fAxes.GetEntriesFast()>=kMaxCuts) return;
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;
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;
274 //________________________________________________________________
275 void AliDielectronHF::AddCutVariable(AliDielectronVarManager::ValueTypes type,
276 const char* binLimitStr, Bool_t leg, EBinType btype)
279 // Add a variable to the mixing handler with arbitrary binning
282 // limit number of variables to kMaxCuts
283 if (fAxes.GetEntriesFast()>=kMaxCuts) return;
285 TVectorD *binLimits=AliDielectronHelper::MakeArbitraryBinning(binLimitStr);
286 if (!binLimits) return;
288 Int_t size=fAxes.GetEntriesFast();
289 fVarCuts[size]=(UShort_t)type;
290 fVarCutType[size]=leg;
291 fAxes.Add(binLimits);
292 fBinType[size]=btype;
295 //________________________________________________________________
296 void AliDielectronHF::AddCutVariable(AliDielectronVarManager::ValueTypes type,
297 TVectorD * binLimits, Bool_t leg, EBinType btype)
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!!!
304 // limit number of variables to kMaxCuts
305 if (fAxes.GetEntriesFast()>=kMaxCuts) return;
307 if (!binLimits) return;
309 Int_t size=fAxes.GetEntriesFast();
310 fVarCuts[size]=(UShort_t)type;
311 fVarCutType[size]=leg;
312 fAxes.Add(binLimits);
313 fBinType[size]=btype;
316 //______________________________________________
317 void AliDielectronHF::Fill(Int_t label1, Int_t label2, Int_t nSignal)
320 // fill the pure MC part of the container starting from a pair of 2 particles (part1 and part2 are legs)
322 // fill only if we have asked for these steps
323 if(!fStepGenerated) return;
325 AliVParticle* part1 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label1);
326 AliVParticle* part2 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label2);
327 if(!part1 || !part2) return;
329 AliDielectronMC* dieMC = AliDielectronMC::Instance();
331 Int_t mLabel1 = dieMC->GetMothersLabel(label1); // should work for both ESD and AOD
332 Int_t mLabel2 = dieMC->GetMothersLabel(label2);
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;
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);
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);
350 // if pair types are filled, fill mc sources at the end
352 if(fPairType!=kMConly) istep=AliDielectron::kEv1PMRot+1;
354 // only OS at the moment
355 if(part1->Charge()*part2->Charge()<0) {
356 Fill(istep+nSignal+fSignalsMC->GetEntries(), valuesPair, valuesLeg1, valuesLeg2);
361 //______________________________________________
362 void AliDielectronHF::Fill(Int_t pairIndex, const AliDielectronPair *particle)
365 // fill histograms for event, pair and daughter cuts and pair types
368 // only OS pairs in case of MC
369 ////////////////////////////// if(fHasMC && pairIndex!=AliDielectron::kEv1PM) return;
371 // only selected pair types in case of data
372 if(!IsPairTypeSelected(pairIndex)) return;
374 // get event and pair variables
375 Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
376 AliDielectronVarManager::Fill(particle,valuesPair);
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);
386 // if pair types are filled, fill mc sources at the end
388 if(fPairType!=kMConly) istep=AliDielectron::kEv1PMRot+1;
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);
398 // all pair types w/o use of mc information
399 if(fPairType==kMConly) return;
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);
409 //______________________________________________
410 void AliDielectronHF::Fill(Int_t index, Double_t * const valuesPair, Double_t * const valuesLeg1, Double_t * const valuesLeg2)
413 // main fill function using index and values as input
416 TObjArray *histArr = static_cast<TObjArray*>(fArrPairType.At(index));
419 Int_t size = GetNumberOfBins();
420 // loop over all histograms
421 for(Int_t ihist=0; ihist<size; ihist++) {
424 Bool_t selected = kTRUE;
426 // loop over all cut variables
427 Int_t nvars = fAxes.GetEntriesFast();
428 for(Int_t ivar=0; ivar<nvars; ivar++) {
431 TVectorD *bins = static_cast<TVectorD*>(fAxes.At(ivar));
432 Int_t nbins = bins->GetNrows()-1;
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
448 if(fVarCutType[ivar]) {
449 if( (valuesLeg1[fVarCuts[ivar]] < lowEdge || valuesLeg1[fVarCuts[ivar]] >= upEdge) ||
450 (valuesLeg2[fVarCuts[ivar]] < lowEdge || valuesLeg2[fVarCuts[ivar]] >= upEdge) ) {
455 else { // pair and event variables
456 if( (valuesPair[fVarCuts[ivar]] < lowEdge || valuesPair[fVarCuts[ivar]] >= upEdge) ) {
463 } //end of var cut loop
465 // do not fill the histogram
466 if(!selected) continue;
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);
475 // AliDebug(10,Form("Fill var %d %s value %f in %s \n",fVar,AliDielectronVarManager::GetValueName(fVar),valuesPair[fVar],tmp->GetName()));
480 //______________________________________________
481 void AliDielectronHF::Init()
484 // initialise event buffers
488 fHasMC=AliDielectronMC::Instance()->HasMC();
490 if(fHasMC) steps=fSignalsMC->GetEntries();
491 if(fStepGenerated) steps*=2;
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);
498 Int_t size = GetNumberOfBins();
499 AliDebug(10,Form("Creating a histo array with size %d \n",size));
503 // fill object array with the array of bin cells
504 TObjArray *histArr = new TObjArray(0);
506 histArr->SetOwner(kTRUE);
507 histArr->Expand(size);
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);
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++) {
521 TVectorD *bins = static_cast<TVectorD*>(fAxes.At(ivar));
522 Int_t nbins = bins->GetNrows()-1;
525 // loop over all bin cells an set unique titles
526 for(Int_t ihist=0; ihist<size; ihist++) {
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
541 TObjArray *tmp= (TObjArray*) histArr->At(ihist);
542 TString title = tmp->GetName();
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
554 // copy array to the selected pair types/ MC sources
558 if(fPairType != kMConly) {
559 for(istep=0; istep<AliDielectron::kEv1PMRot+1; istep++) {
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();
567 fArrPairType[istep]=new TObjArray(0);
568 ((TObjArray*)fArrPairType[istep])->SetOwner();
569 ((TObjArray*)fArrPairType[istep])->SetName(AliDielectron::PairClassName(istep));
571 } //end: loop over pair types
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());
581 fArrPairType[istep+i+fSignalsMC->GetEntries()]=(TObjArray*)histArr->Clone(title.Data());
583 } // end: loop over sources
595 //______________________________________________
596 Int_t AliDielectronHF::GetNumberOfBins() const
599 // return the number of bins this mixing handler has
602 for (Int_t i=0; i<fAxes.GetEntriesFast(); ++i)
603 size*=((static_cast<TVectorD*>(fAxes.At(i)))->GetNrows()-1);
607 //______________________________________________
608 Bool_t AliDielectronHF::IsPairTypeSelected(Int_t itype)
611 // check whether a pair type was selected
612 // TODO: cross check or replace by mixinghandlers processsing
614 Bool_t selected = kFALSE;
617 if(fPairType==kAll) return kTRUE;
620 case AliDielectron::kEv1PP:
621 case AliDielectron::kEv1MM:
622 if(fPairType==kSeAll || fPairType==kSeMeAll || fPairType==kSeReAll ) selected = kTRUE;
624 case AliDielectron::kEv1PM:
625 if(fPairType!=kMeOnlyOS) selected = kTRUE;
627 case AliDielectron::kEv1PEv2P:
628 case AliDielectron::kEv1MEv2M:
629 if(fPairType==kMeAll || fPairType==kSeMeAll) selected = kTRUE;
631 case AliDielectron::kEv1PEv2M:
632 if(fPairType==kMeAll || fPairType==kSeMeAll) selected = kTRUE;
634 case AliDielectron::kEv1MEv2P:
635 if(fPairType==kMeAll || fPairType==kSeMeAll || fPairType==kMeOnlyOS || fPairType==kSeMeOnlyOS) selected = kTRUE;
637 case AliDielectron::kEv2PP:
638 case AliDielectron::kEv2PM:
639 case AliDielectron::kEv2MM:
642 case AliDielectron::kEv1PMRot:
643 if(fPairType==kSeReAll || fPairType==kSeReOnlyOS) selected = kTRUE;