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() :
57 fUsedVars(new TBits(AliDielectronVarManager::kNMaxValues)),
63 fStepGenerated(kFALSE),
67 // Default Constructor
69 for (Int_t i=0; i<kMaxCuts; ++i){
74 fAxes.SetOwner(kTRUE);
75 fRefObj.SetOwner(kTRUE);
76 fArrPairType.SetOwner(kTRUE);
79 //______________________________________________
80 AliDielectronHF::AliDielectronHF(const char* name, const char* title) :
82 fUsedVars(new TBits(AliDielectronVarManager::kNMaxValues)),
88 fStepGenerated(kFALSE),
94 for (Int_t i=0; i<kMaxCuts; ++i){
99 fAxes.SetOwner(kTRUE);
100 fRefObj.SetOwner(kTRUE);
101 fArrPairType.SetOwner(kTRUE);
104 //______________________________________________
105 AliDielectronHF::~AliDielectronHF()
108 // Default Destructor
110 if(fUsedVars) delete fUsedVars;
113 fArrPairType.Delete();
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)
122 // Histogram creation 1D case with arbitraty binning X
123 // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
127 if(valTypeP==AliDielectronHistos::kNoProfile)
128 hist=new TH1F("","",binsX->GetNrows()-1,binsX->GetMatrixArray());
130 TString opt=""; Double_t pmin=0., pmax=0.;
131 if(!option.IsNull()) {
132 TObjArray *arr=option.Tokenize(";");
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();
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() );
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
150 for(Int_t i=0; i<4; i++) fUsedVars->SetBitNumber(valType[i],kTRUE);
151 fUsedVars->SetBitNumber(valTypeW,kTRUE);
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()));
157 fRefObj.AddLast(hist);
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)
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!!!
172 if(valTypeP==AliDielectronHistos::kNoProfile) {
174 binsX->GetNrows()-1,binsX->GetMatrixArray(),
175 binsY->GetNrows()-1,binsY->GetMatrixArray());
178 TString opt=""; Double_t pmin=0., pmax=0.;
179 if(!option.IsNull()) {
180 TObjArray *arr=option.Tokenize(";");
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();
187 hist=new TProfile2D("","",
188 binsX->GetNrows()-1,binsX->GetMatrixArray(),
189 binsY->GetNrows()-1,binsY->GetMatrixArray());
190 ((TProfile2D*)hist)->BuildOptions(pmin,pmax,opt.Data());
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
199 for(Int_t i=0; i<4; i++) fUsedVars->SetBitNumber(valType[i],kTRUE);
200 fUsedVars->SetBitNumber(valTypeW,kTRUE);
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()));
206 fRefObj.AddLast(hist);
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)
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!!!
221 if(valTypeP==AliDielectronHistos::kNoProfile) {
223 binsX->GetNrows()-1,binsX->GetMatrixArray(),
224 binsY->GetNrows()-1,binsY->GetMatrixArray(),
225 binsZ->GetNrows()-1,binsZ->GetMatrixArray());
228 TString opt=""; Double_t pmin=0., pmax=0.;
229 if(!option.IsNull()) {
230 TObjArray *arr=option.Tokenize(";");
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();
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());
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
250 for(Int_t i=0; i<4; i++) fUsedVars->SetBitNumber(valType[i],kTRUE);
251 fUsedVars->SetBitNumber(valTypeW,kTRUE);
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()));
257 fRefObj.AddLast(hist);
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)
268 // Add a variable to the mixing handler
271 // limit number of variables to kMaxCuts
272 if (fAxes.GetEntriesFast()>=kMaxCuts) return;
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;
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);
287 //________________________________________________________________
288 void AliDielectronHF::AddCutVariable(AliDielectronVarManager::ValueTypes type,
289 const char* binLimitStr, Bool_t leg, EBinType btype)
292 // Add a variable to the mixing handler with arbitrary binning
295 // limit number of variables to kMaxCuts
296 if (fAxes.GetEntriesFast()>=kMaxCuts) return;
298 TVectorD *binLimits=AliDielectronHelper::MakeArbitraryBinning(binLimitStr);
299 if (!binLimits) return;
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);
309 //________________________________________________________________
310 void AliDielectronHF::AddCutVariable(AliDielectronVarManager::ValueTypes type,
311 TVectorD * binLimits, Bool_t leg, EBinType btype)
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!!!
318 // limit number of variables to kMaxCuts
319 if (fAxes.GetEntriesFast()>=kMaxCuts) return;
321 if (!binLimits) return;
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);
331 //______________________________________________
332 void AliDielectronHF::Fill(Int_t label1, Int_t label2, Int_t nSignal)
335 // fill the pure MC part of the container starting from a pair of 2 particles (part1 and part2 are legs)
337 // fill only if we have asked for these steps
338 if(!fStepGenerated) return;
340 AliVParticle* part1 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label1);
341 AliVParticle* part2 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label2);
342 if(!part1 || !part2) return;
344 AliDielectronMC* dieMC = AliDielectronMC::Instance();
346 Int_t mLabel1 = dieMC->GetMothersLabel(label1); // should work for both ESD and AOD
347 Int_t mLabel2 = dieMC->GetMothersLabel(label2);
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;
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);
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);
366 // if pair types are filled, fill mc sources at the end
368 if(fPairType!=kMConly) istep=AliDielectron::kEv1PMRot+1;
370 // only OS at the moment
371 if(part1->Charge()*part2->Charge()<0) {
372 Fill(istep+nSignal+fSignalsMC->GetEntries(), valuesPair, valuesLeg1, valuesLeg2);
377 //______________________________________________
378 void AliDielectronHF::Fill(Int_t pairIndex, const AliDielectronPair *particle)
381 // fill histograms for event, pair and daughter cuts and pair types
384 // only OS pairs in case of MC
385 ////////////////////////////// if(fHasMC && pairIndex!=AliDielectron::kEv1PM) return;
387 // only selected pair types in case of data
388 if(!IsPairTypeSelected(pairIndex)) return;
390 // get event and pair variables
391 Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
392 AliDielectronVarManager::SetFillMap(fUsedVars);
393 AliDielectronVarManager::Fill(particle,valuesPair);
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);
403 // if pair types are filled, fill mc sources at the end
405 if(fPairType!=kMConly) istep=AliDielectron::kEv1PMRot+1;
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);
415 // all pair types w/o use of mc information
416 if(fPairType==kMConly) return;
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);
426 //______________________________________________
427 void AliDielectronHF::Fill(Int_t index, Double_t * const valuesPair, Double_t * const valuesLeg1, Double_t * const valuesLeg2)
430 // main fill function using index and values as input
433 TObjArray *histArr = static_cast<TObjArray*>(fArrPairType.At(index));
436 Int_t size = GetNumberOfBins();
437 // loop over all histograms
438 for(Int_t ihist=0; ihist<size; ihist++) {
441 Bool_t selected = kTRUE;
443 // loop over all cut variables
444 Int_t nvars = fAxes.GetEntriesFast();
445 for(Int_t ivar=0; ivar<nvars; ivar++) {
448 TVectorD *bins = static_cast<TVectorD*>(fAxes.At(ivar));
449 Int_t nbins = bins->GetNrows()-1;
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
465 if(fVarCutType[ivar]) {
466 if( (valuesLeg1[fVarCuts[ivar]] < lowEdge || valuesLeg1[fVarCuts[ivar]] >= upEdge) ||
467 (valuesLeg2[fVarCuts[ivar]] < lowEdge || valuesLeg2[fVarCuts[ivar]] >= upEdge) ) {
472 else { // pair and event variables
473 if( (valuesPair[fVarCuts[ivar]] < lowEdge || valuesPair[fVarCuts[ivar]] >= upEdge) ) {
480 } //end of var cut loop
482 // do not fill the histogram
483 if(!selected) continue;
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);
492 // AliDebug(10,Form("Fill var %d %s value %f in %s \n",fVar,AliDielectronVarManager::GetValueName(fVar),valuesPair[fVar],tmp->GetName()));
497 //______________________________________________
498 void AliDielectronHF::Init()
501 // initialise event buffers
505 fHasMC=AliDielectronMC::Instance()->HasMC();
507 if(fHasMC) steps=fSignalsMC->GetEntries();
508 if(fStepGenerated) steps*=2;
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);
515 Int_t size = GetNumberOfBins();
516 AliDebug(10,Form("Creating a histo array with size %d \n",size));
520 // fill object array with the array of bin cells
521 TObjArray *histArr = new TObjArray(0);
523 histArr->SetOwner(kTRUE);
524 histArr->Expand(size);
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);
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++) {
538 TVectorD *bins = static_cast<TVectorD*>(fAxes.At(ivar));
539 Int_t nbins = bins->GetNrows()-1;
542 // loop over all bin cells an set unique titles
543 for(Int_t ihist=0; ihist<size; ihist++) {
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
558 TObjArray *tmp= (TObjArray*) histArr->At(ihist);
559 TString title = tmp->GetName();
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
571 // copy array to the selected pair types/ MC sources
575 if(fPairType != kMConly) {
576 for(istep=0; istep<AliDielectron::kEv1PMRot+1; istep++) {
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();
584 fArrPairType[istep]=new TObjArray(0);
585 ((TObjArray*)fArrPairType[istep])->SetOwner();
586 ((TObjArray*)fArrPairType[istep])->SetName(AliDielectron::PairClassName(istep));
588 } //end: loop over pair types
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());
598 fArrPairType[istep+i+fSignalsMC->GetEntries()]=(TObjArray*)histArr->Clone(title.Data());
600 } // end: loop over sources
612 //______________________________________________
613 Int_t AliDielectronHF::GetNumberOfBins() const
616 // return the number of bins this histogram grid has
619 for (Int_t i=0; i<fAxes.GetEntriesFast(); ++i)
620 size*=((static_cast<TVectorD*>(fAxes.At(i)))->GetNrows()-1);
624 //______________________________________________
625 Bool_t AliDielectronHF::IsPairTypeSelected(Int_t itype)
628 // check whether a pair type was selected
629 // TODO: cross check or replace by mixinghandlers processsing
631 Bool_t selected = kFALSE;
634 if(fPairType==kAll) return kTRUE;
637 case AliDielectron::kEv1PP:
638 case AliDielectron::kEv1MM:
639 if(fPairType==kSeAll || fPairType==kSeMeAll || fPairType==kSeReAll ) selected = kTRUE;
641 case AliDielectron::kEv1PM:
642 if(fPairType!=kMeOnlyOS) selected = kTRUE;
644 case AliDielectron::kEv1PEv2P:
645 case AliDielectron::kEv1MEv2M:
646 if(fPairType==kMeAll || fPairType==kSeMeAll) selected = kTRUE;
648 case AliDielectron::kEv1PEv2M:
649 if(fPairType==kMeAll || fPairType==kSeMeAll) selected = kTRUE;
651 case AliDielectron::kEv1MEv2P:
652 if(fPairType==kMeAll || fPairType==kSeMeAll || fPairType==kMeOnlyOS || fPairType==kSeMeOnlyOS) selected = kTRUE;
654 case AliDielectron::kEv2PP:
655 case AliDielectron::kEv2PM:
656 case AliDielectron::kEv2MM:
659 case AliDielectron::kEv1PMRot:
660 if(fPairType==kSeReAll || fPairType==kSeReOnlyOS) selected = kTRUE;