1 #include "AliAnalysisMuMuBinning.h"
4 // AliAnalysisMuMuBinning.h : a class to hold bins of various sizes
6 // The idea behind this class is to store it together with
7 // the histograms (corresponding to the bins)
8 // so we can then loop easily on all bins afterwards.
10 // author: L. Aphecetche (Subatech)
14 #include "Riostream.h"
17 #include "TObjArray.h"
18 #include "TObjString.h"
21 ClassImp(AliAnalysisMuMuBinning::Range)
22 ClassImp(AliAnalysisMuMuBinning)
24 //______________________________________________________________________________
25 AliAnalysisMuMuBinning::AliAnalysisMuMuBinning(const char* name, const char* title)
26 : TNamed(name,title), fBins(0x0)
31 //______________________________________________________________________________
32 AliAnalysisMuMuBinning::AliAnalysisMuMuBinning(const AliAnalysisMuMuBinning& rhs)
33 : TNamed(), fBins(0x0)
36 TObjArray* bins = rhs.CreateBinObjArray();
38 AliAnalysisMuMuBinning::Range* b;
40 while ( ( b = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
46 //______________________________________________________________________________
47 AliAnalysisMuMuBinning& AliAnalysisMuMuBinning::operator=(const AliAnalysisMuMuBinning& rhs)
49 // assignment operator
55 TObjArray* bins = rhs.CreateBinObjArray();
57 AliAnalysisMuMuBinning::Range* b;
59 while ( ( b = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
67 //______________________________________________________________________________
68 AliAnalysisMuMuBinning::~AliAnalysisMuMuBinning()
74 //______________________________________________________________________________
75 void AliAnalysisMuMuBinning::AddBin(const AliAnalysisMuMuBinning::Range& bin)
78 AddBin(bin.What().Data(),bin.Quantity().Data(),
79 bin.Xmin(),bin.Xmax(),
80 bin.Ymin(),bin.Ymax(),bin.Flavour());
83 //______________________________________________________________________________
84 void AliAnalysisMuMuBinning::AddBin(const char* what, const char* quantity,
85 Double_t xmin, Double_t xmax,
86 Double_t ymin, Double_t ymax,
90 /// Note that what and Quantity are not case sensitive.
94 fBins->SetOwnerKeyValue(kTRUE,kTRUE);
100 TString sQuantity(quantity);
103 TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(swhat.Data()));
108 fBins->Add(new TObjString(swhat),b);
111 Range* r = new Range(swhat.Data(),sQuantity.Data(),xmin,xmax,ymin,ymax,flavour);
113 if ( b->FindObject(r) )
115 AliDebug(1,Form("Trying to add an already existing bin : %s. Not doing it.",r->AsString().Data()));
122 TString bQuantity(Form("%s-%s",swhat.Data(),sQuantity.Data()));
124 TString name(GetName());
126 if ( !name.Contains(bQuantity) )
141 //______________________________________________________________________________
142 Double_t* AliAnalysisMuMuBinning::CreateBinArray() const
144 /// Create a (variable) bin array suitable for TH1 constructor
145 /// The returned array must be deleted by the user
146 /// (using delete[] )
148 TObjArray* binArray = CreateBinObjArray();
149 if (!binArray) return 0x0;
150 Double_t* bins = new Double_t[binArray->GetEntries()+1];
151 TIter next(binArray);
152 AliAnalysisMuMuBinning::Range* b;
154 while ( ( b = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
160 b = static_cast<AliAnalysisMuMuBinning::Range*>(binArray->At(binArray->GetEntries()-1));
168 //______________________________________________________________________________
169 TObjArray* AliAnalysisMuMuBinning::CreateBinObjArray() const
171 /// Get the list of all the bins
172 /// The returned array must be deleted by the user
174 TObjArray* a = new TObjArray;
177 TIter nextwhat(fBins);
180 while ( ( what = static_cast<TObjString*>(nextwhat()) ) )
182 TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(what->String().Data()));
186 while ( ( r = static_cast<Range*>(next()) ) )
192 if ( a->GetLast() < 0 )
200 //______________________________________________________________________________
201 TObjArray* AliAnalysisMuMuBinning::CreateBinObjArray(const char* what) const
203 /// Get the list of bins for a given what
204 /// The returned array must be deleted by the user
206 if (!fBins) return 0x0;
208 TObjArray* a = new TObjArray;
214 TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(swhat.Data()));
220 while ( ( r = static_cast<Range*>(next()) ) )
225 if ( a->GetLast() < 0 )
234 //______________________________________________________________________________
235 TObjArray* AliAnalysisMuMuBinning::CreateBinObjArray(const char* what, const char* quantity, const char* flavour) const
237 /// Get the list of bins for a given what and given Quantity
238 /// The returned array must be deleted by the user
239 /// Quantity can be a single Quantity or several Quantitys separated by comma
241 TObjArray* a = new TObjArray;
247 TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(swhat.Data()));
253 TString sQuantity(quantity);
256 TString sflavour(flavour);
258 TObjArray* Quantitys = sQuantity.Tokenize(",");
259 TObjString* oneQuantity;
260 TIter nextQuantity(Quantitys);
262 while ( ( r = static_cast<Range*>(next()) ) )
264 nextQuantity.Reset();
265 while ( ( oneQuantity = static_cast<TObjString*>(nextQuantity()) ) )
267 if ( r->Quantity() == oneQuantity->String() &&
268 ( ( sflavour.Length() > 0 && r->Flavour() == sflavour.Data() ) || sflavour.Length()==0 ) )
275 if ( a->GetLast() < 0 )
285 //______________________________________________________________________________
286 Double_t* AliAnalysisMuMuBinning::CreateBinArrayY() const
288 /// Create a TObjArray with 2 (variable) bin array with x and y binning, suitable for TH1
289 /// The returned array must be deleted by the user
290 /// (using delete[] )
292 TObjArray* binArray = CreateBinObjArray();
293 if (!binArray) return 0x0;
295 AliAnalysisMuMuBinning::Range* firstBin = static_cast<AliAnalysisMuMuBinning::Range*>(binArray->First());
297 Double_t* binsY = new Double_t[binArray->GetEntries()+1];
299 Double_t minY = firstBin->Ymin();
300 Double_t maxY = firstBin->Ymax();
304 std::cout << "No 2D binning" << std::endl;
310 TIter next(binArray);
311 AliAnalysisMuMuBinning::Range* b;
313 while ( ( b = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
315 if ( (i != 0) && (minY == b->Ymin()) ) break;
317 binsY[i] = b->Ymin();
321 b = static_cast<AliAnalysisMuMuBinning::Range*>(binArray->At(i-1));
323 binsY[i] = b->Ymax();
325 Double_t* bins = new Double_t[i + 1];
327 for (Int_t j = 0 ; j < (i+1) ; j++)
337 //______________________________________________________________________________
338 Int_t AliAnalysisMuMuBinning::GetNBinsX() const
340 /// Gets the number of x bins, suitable for TH1
343 TObjArray* binArray = CreateBinObjArray();
344 if (!binArray) return 0;
349 TIter next(binArray);
350 AliAnalysisMuMuBinning::Range* b;
352 while ( ( b = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
354 if ( (i != 0) && (binsX == b->Xmin()) ) continue;
364 //______________________________________________________________________________
365 Int_t AliAnalysisMuMuBinning::GetNBinsY() const
367 /// Gets the number of x bins, suitable for TH1
370 TObjArray* binArray = CreateBinObjArray();
371 if (!binArray) return 0x0;
375 AliAnalysisMuMuBinning::Range* firstBin = static_cast<AliAnalysisMuMuBinning::Range*>(binArray->First());
377 Double_t minY = firstBin->Ymin();
378 Double_t maxY = firstBin->Ymax();
382 std::cout << "No 2D binning" << std::endl;
387 TIter next(binArray);
388 AliAnalysisMuMuBinning::Range* b;
390 while ( ( b = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
392 if ( (i != 0) && (minY == b->Ymin()) ) break;
402 //______________________________________________________________________________
403 Double_t* AliAnalysisMuMuBinning::CreateBinArrayX() const
405 /// Create a TObjArray with 2 (variable) bin array with x and y binning , suitable for TH1
406 /// The returned array must be deleted by the user
407 /// (using delete[] )
409 TObjArray* binArray = CreateBinObjArray();
410 if (!binArray) return 0x0;
412 Double_t* binsX = new Double_t[binArray->GetEntries()+1];
415 TIter next(binArray);
416 AliAnalysisMuMuBinning::Range* b;
418 while ( ( b = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
420 if ( (i != 0) && (binsX[i-1] == b->Xmin()) ) continue;
422 binsX[i] = b->Xmin();
426 b = static_cast<AliAnalysisMuMuBinning::Range*>(binArray->At(binArray->GetEntries()-1));
428 binsX[i] = b->Xmax();
430 Double_t* bins = new Double_t[i + 1];
432 for (Int_t j = 0 ; j < (i+1) ; j++)
442 //______________________________________________________________________________
443 void AliAnalysisMuMuBinning::CreateMesh(const char* what,
444 const char* quantity1, const char* quantity2,
448 /// Create 2D bins from existing 1d ones of Quantity1 and Quantity2
449 TObjArray* a1 = CreateBinObjArray(what,quantity1,flavour);
452 AliError(Form("No bin for Quantity %s. Done nothing.",quantity1));
455 TObjArray* a2 = CreateBinObjArray(what,quantity2,flavour);
458 AliError(Form("No bin for Quantity %s. Done nothing.",quantity2));
462 TString meshQuantity(Form("%s VS %s - %s",quantity1,quantity2,flavour));
464 for ( Int_t i1 = 0; i1 <= a1->GetLast(); ++i1 )
466 Range* r1 = static_cast<Range*>(a1->At(i1));
468 for ( Int_t i2 = 0; i2 <= a2->GetLast(); ++i2 )
470 Range* r2 = static_cast<Range*>(a2->At(i2));
472 AddBin(what,meshQuantity,r2->Xmin(),r2->Xmax(),r1->Xmin(),r1->Xmax(),Form("%s VS %s",r1->Flavour().Data(),r2->Flavour().Data()));
481 TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(what));
484 TString sQuantity1(quantity1);
485 TString sQuantity2(quantity2);
487 sQuantity1.ToUpper();
488 sQuantity2.ToUpper();
490 while ( ( r = static_cast<Range*>(next())) )
492 if ( r->Quantity() == quantity1 ||
493 r->Quantity() == quantity2 )
501 //______________________________________________________________________________
502 TObjArray* AliAnalysisMuMuBinning::CreateWhatArray() const
504 /// Create a TObjString array with the names of the what we're holding results for
505 /// Returned array must be delete by user
507 TObjArray* whatArray(0x0);
509 TIter nextwhat(fBins);
512 while ( ( what = static_cast<TObjString*>(nextwhat()) ) )
516 whatArray = new TObjArray;
517 whatArray->SetOwner(kTRUE);
519 whatArray->Add(new TObjString(*what));
524 //______________________________________________________________________________
525 TObjArray* AliAnalysisMuMuBinning::CreateQuantityArray() const
527 /// Create a TObjString array with the names of the binning Quantitys
528 /// Returned array must be delete by user
530 TObjArray* QuantityArray(0x0);
532 TIter nextwhat(fBins);
535 while ( ( what = static_cast<TObjString*>(nextwhat()) ) )
537 TObjArray* whats = static_cast<TObjArray*>(fBins->GetValue(what->String()));
542 while ( ( r = static_cast<Range*>(next())) )
546 QuantityArray = new TObjArray;
547 QuantityArray->SetOwner(kTRUE);
549 if ( !QuantityArray->FindObject(r->Quantity()) )
551 QuantityArray->Add(new TObjString(r->Quantity()));
555 return QuantityArray;
558 //______________________________________________________________________________
559 Bool_t AliAnalysisMuMuBinning::IsEqual(const TObject* obj) const
561 /// Return kTRUE if obj is an AliAnalysisMuMuBinning object and is
564 if ( obj->IsA() == AliAnalysisMuMuBinning::Class() )
566 const AliAnalysisMuMuBinning* other = static_cast<const AliAnalysisMuMuBinning*>(obj);
568 TIter nextOther(other->fBins);
571 while ( ( str = static_cast<TObjString*>(nextOther()) ) )
573 TObject* o = fBins->GetValue(str->String());
574 if (!o) return kFALSE;
575 if (o->IsA() != TObjArray::Class()) return kFALSE;
577 TObjArray* thisArray = static_cast<TObjArray*>(o);
579 o = other->fBins->GetValue(str->String());
580 if (!o) return kFALSE;
581 if (o->IsA() != TObjArray::Class()) return kFALSE;
583 TObjArray* otherArray = static_cast<TObjArray*>(o);
585 Int_t n = thisArray->GetEntries();
587 if ( n != otherArray->GetEntries() ) return kFALSE;
589 for ( Int_t i = 0; i < n; ++i )
591 Range* thisRange = static_cast<Range*>(thisArray->At(i));
592 Range* otherRange = static_cast<Range*>(otherArray->At(i));
594 if ( !thisRange->IsEqual(otherRange) ) return kFALSE;
604 //______________________________________________________________________________
605 Long64_t AliAnalysisMuMuBinning::Merge(TCollection* list)
609 // Merge a list of AliAnalysisMuMuBinning objects with this
610 // Returns the number of merged objects (including this).
614 if (list->IsEmpty()) return 1;
620 while ( ( currObj = next() ) )
622 AliAnalysisMuMuBinning* binning = dynamic_cast<AliAnalysisMuMuBinning*>(currObj);
625 AliFatal(Form("object named \"%s\" is a %s instead of an AliAnalysisMuMuBinning!", currObj->GetName(), currObj->ClassName()));
629 if ( IsEqual(binning) )
631 // nothing to do if we have the same binning already ;-)
635 AliWarning("Implement me!");
636 std::cout << ">>>> this=" << std::endl;
638 std::cout << ">>>> other=" << std::endl;
647 //______________________________________________________________________________
648 AliAnalysisMuMuBinning*
649 AliAnalysisMuMuBinning::Project(const char* what, const char* quantity, const char* flavour) const
651 /// Create a sub-binning object with only the bins pertaining to (what,Quantity)
653 TObjArray* bins = CreateBinObjArray(what,quantity,flavour);
654 if (!bins) return 0x0;
655 AliAnalysisMuMuBinning* p = new AliAnalysisMuMuBinning;
657 AliAnalysisMuMuBinning::Range* bin;
658 TString sQuantity(quantity);
661 while ( ( bin = static_cast<AliAnalysisMuMuBinning::Range*>(next())) )
663 if (bin->Quantity()!=sQuantity || bin->Flavour()!=flavour)
665 AliDebug(1,Form("sQuantity=%s flavour=%s bin=%s => skip",sQuantity.Data(),flavour,bin->AsString().Data()));
669 p->AddBin(what,bin->Quantity(),bin->Xmin(),bin->Xmax(),bin->Ymin(),bin->Ymax(),bin->Flavour().Data());
678 //______________________________________________________________________________
679 void AliAnalysisMuMuBinning::Print(Option_t* /*opt*/) const
685 std::cout << "Empty object. No bin defined. " << std::endl;
689 TIter nextwhat(fBins);
692 while ( ( str = static_cast<TObjString*>(nextwhat()) ) )
694 std::cout << "what : " << str->String().Data() << std::endl;
695 TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(str->String()));
700 while ( ( r = static_cast<Range*>(next()) ) )
702 std::cout << Form("BIN %3d ",i++);
708 //______________________________________________________________________________
709 //______________________________________________________________________________
710 //______________________________________________________________________________
711 //______________________________________________________________________________
713 //______________________________________________________________________________
714 AliAnalysisMuMuBinning::Range::Range(const char* what, const char* quantity,
715 Double_t xmin, Double_t xmax,
716 Double_t ymin, Double_t ymax,
718 : TObject(), fWhat(what), fQuantity(quantity),
719 fXmin(xmin), fXmax(xmax), fYmin(ymin), fYmax(ymax),
727 //______________________________________________________________________________
728 TString AliAnalysisMuMuBinning::Range::AsString() const
730 /// Return a string representation of this range
732 if ( IsIntegrated()) return Quantity().Data();
736 if ( fFlavour.Length() > 0 )
738 s.Form("%s_%s_%05.2f_%05.2f",Quantity().Data(),Flavour().Data(),Xmin(),Xmax());
742 s.Form("%s_%05.2f_%05.2f",Quantity().Data(),Xmin(),Xmax());
747 s += TString::Format("_%06.2f_%06.2f",Ymin(),Ymax());
750 s.ReplaceAll(" ","");
751 s.ReplaceAll("+","");
752 s.ReplaceAll("-","m");
757 //______________________________________________________________________________
758 Int_t AliAnalysisMuMuBinning::Range::Compare(const TObject* obj) const
760 // Must return -1 if this is smaller
761 // than obj, 0 if objects are equal and 1 if this is larger than obj.
762 const Range* other = static_cast<const Range*>(obj);
764 int s = strcmp(What().Data(),other->What().Data());
768 s = strcmp(Quantity().Data(),other->Quantity().Data());
772 s = strcmp(Flavour().Data(),other->Flavour().Data());
776 // if ( IsIntegrated() && other->IsIntegrated() ) return 0;
778 if ( Xmin() < other->Xmin() )
782 else if ( Xmin() > other->Xmin() )
788 if ( Xmax() < other->Xmax() )
792 else if ( Xmax() > other->Xmax() )
797 if ( Ymin() < other->Ymin() )
801 else if ( Ymin() > other->Ymin() )
807 if ( Ymax() < other->Ymax() )
811 else if ( Ymax() > other->Ymax() )
821 //______________________________________________________________________________
822 Bool_t AliAnalysisMuMuBinning::Range::IsInRange(Double_t x, Double_t y) const
824 /// If Range is 1D, returns true if x is in range
825 /// If Range is 2D, returns true if (x,y) is in range
827 if ( IsIntegrated() )
835 return ( x >= Xmin() && x < Xmax() && y >= Ymin() && y < Ymax());
839 return ( x >= Xmin() && x < Xmax() );
844 //______________________________________________________________________________
845 Bool_t AliAnalysisMuMuBinning::Range::IsIntegrated() const
847 /// Whether we're a null object (aka integrated) or not
849 Xmin() >= TMath::Limits<Double_t>::Max() &&
850 Ymin() >= TMath::Limits<Double_t>::Max() &&
851 Xmax() >= TMath::Limits<Double_t>::Max() &&
852 Ymax() >= TMath::Limits<Double_t>::Max() ;
856 //______________________________________________________________________________
857 void AliAnalysisMuMuBinning::Range::Print(Option_t* /*opt*/) const
863 std::cout << Form("%s : %s : INTEGRATED",What().Data(),Quantity().Data()) << std::endl;
868 std::cout << Form("%s : %s : %5.2f : %5.2f",What().Data(),Quantity().Data(),Xmin(),Xmax());
872 std::cout << Form(" ; %5.2f : %5.2f",Ymin(),Ymax());
875 if (Flavour().Length()>0)
877 std::cout << " - " << Flavour().Data();
880 std::cout << "->" << AsString().Data() << std::endl;