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 void AliAnalysisMuMuBinning::CreateMesh(const char* what,
287 const char* quantity1, const char* quantity2,
291 /// Create 2D bins from existing 1d ones of Quantity1 and Quantity2
292 TObjArray* a1 = CreateBinObjArray(what,quantity1,flavour);
295 AliError(Form("No bin for Quantity %s. Done nothing.",quantity1));
298 TObjArray* a2 = CreateBinObjArray(what,quantity2,flavour);
301 AliError(Form("No bin for Quantity %s. Done nothing.",quantity2));
305 TString meshQuantity(Form("%s VS %s - %s",quantity1,quantity2,flavour));
307 for ( Int_t i1 = 0; i1 <= a1->GetLast(); ++i1 )
309 Range* r1 = static_cast<Range*>(a1->At(i1));
311 for ( Int_t i2 = 0; i2 <= a2->GetLast(); ++i2 )
313 Range* r2 = static_cast<Range*>(a2->At(i2));
315 AddBin(what,meshQuantity,r2->Xmin(),r2->Xmax(),r1->Xmin(),r1->Xmax(),Form("%s VS %s",r1->Flavour().Data(),r2->Flavour().Data()));
324 TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(what));
327 TString sQuantity1(quantity1);
328 TString sQuantity2(quantity2);
330 sQuantity1.ToUpper();
331 sQuantity2.ToUpper();
333 while ( ( r = static_cast<Range*>(next())) )
335 if ( r->Quantity() == quantity1 ||
336 r->Quantity() == quantity2 )
344 //______________________________________________________________________________
345 TObjArray* AliAnalysisMuMuBinning::CreateWhatArray() const
347 /// Create a TObjString array with the names of the what we're holding results for
348 /// Returned array must be delete by user
350 TObjArray* whatArray(0x0);
352 TIter nextwhat(fBins);
355 while ( ( what = static_cast<TObjString*>(nextwhat()) ) )
359 whatArray = new TObjArray;
360 whatArray->SetOwner(kTRUE);
362 whatArray->Add(new TObjString(*what));
367 //______________________________________________________________________________
368 TObjArray* AliAnalysisMuMuBinning::CreateQuantityArray() const
370 /// Create a TObjString array with the names of the binning Quantitys
371 /// Returned array must be delete by user
373 TObjArray* QuantityArray(0x0);
375 TIter nextwhat(fBins);
378 while ( ( what = static_cast<TObjString*>(nextwhat()) ) )
380 TObjArray* whats = static_cast<TObjArray*>(fBins->GetValue(what->String()));
385 while ( ( r = static_cast<Range*>(next())) )
389 QuantityArray = new TObjArray;
390 QuantityArray->SetOwner(kTRUE);
392 if ( !QuantityArray->FindObject(r->Quantity()) )
394 QuantityArray->Add(new TObjString(r->Quantity()));
398 return QuantityArray;
401 //______________________________________________________________________________
402 Bool_t AliAnalysisMuMuBinning::IsEqual(const TObject* obj) const
404 /// Return kTRUE if obj is an AliAnalysisMuMuBinning object and is
407 if ( obj->IsA() == AliAnalysisMuMuBinning::Class() )
409 const AliAnalysisMuMuBinning* other = static_cast<const AliAnalysisMuMuBinning*>(obj);
411 TIter nextOther(other->fBins);
414 while ( ( str = static_cast<TObjString*>(nextOther()) ) )
416 TObject* o = fBins->GetValue(str->String());
417 if (!o) return kFALSE;
418 if (o->IsA() != TObjArray::Class()) return kFALSE;
420 TObjArray* thisArray = static_cast<TObjArray*>(o);
422 o = other->fBins->GetValue(str->String());
423 if (!o) return kFALSE;
424 if (o->IsA() != TObjArray::Class()) return kFALSE;
426 TObjArray* otherArray = static_cast<TObjArray*>(o);
428 Int_t n = thisArray->GetEntries();
430 if ( n != otherArray->GetEntries() ) return kFALSE;
432 for ( Int_t i = 0; i < n; ++i )
434 Range* thisRange = static_cast<Range*>(thisArray->At(i));
435 Range* otherRange = static_cast<Range*>(otherArray->At(i));
437 if ( !thisRange->IsEqual(otherRange) ) return kFALSE;
447 //______________________________________________________________________________
448 Long64_t AliAnalysisMuMuBinning::Merge(TCollection* list)
452 // Merge a list of AliAnalysisMuMuBinning objects with this
453 // Returns the number of merged objects (including this).
457 if (list->IsEmpty()) return 1;
463 while ( ( currObj = next() ) )
465 AliAnalysisMuMuBinning* binning = dynamic_cast<AliAnalysisMuMuBinning*>(currObj);
468 AliFatal(Form("object named \"%s\" is a %s instead of an AliAnalysisMuMuBinning!", currObj->GetName(), currObj->ClassName()));
472 if ( IsEqual(binning) )
474 // nothing to do if we have the same binning already ;-)
478 AliWarning("Implement me!");
479 std::cout << ">>>> this=" << std::endl;
481 std::cout << ">>>> other=" << std::endl;
490 //______________________________________________________________________________
491 AliAnalysisMuMuBinning*
492 AliAnalysisMuMuBinning::Project(const char* what, const char* quantity, const char* flavour) const
494 /// Create a sub-binning object with only the bins pertaining to (what,Quantity)
496 TObjArray* bins = CreateBinObjArray(what,quantity,flavour);
497 if (!bins) return 0x0;
498 AliAnalysisMuMuBinning* p = new AliAnalysisMuMuBinning;
500 AliAnalysisMuMuBinning::Range* bin;
501 TString sQuantity(quantity);
504 while ( ( bin = static_cast<AliAnalysisMuMuBinning::Range*>(next())) )
506 if (bin->Quantity()!=sQuantity || bin->Flavour()!=flavour)
508 AliDebug(1,Form("sQuantity=%s flavour=%s bin=%s => skip",sQuantity.Data(),flavour,bin->AsString().Data()));
512 p->AddBin(what,bin->Quantity(),bin->Xmin(),bin->Xmax(),bin->Ymin(),bin->Ymax(),bin->Flavour().Data());
521 //______________________________________________________________________________
522 void AliAnalysisMuMuBinning::Print(Option_t* /*opt*/) const
528 std::cout << "Empty object. No bin defined. " << std::endl;
532 TIter nextwhat(fBins);
535 while ( ( str = static_cast<TObjString*>(nextwhat()) ) )
537 std::cout << "what : " << str->String().Data() << std::endl;
538 TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(str->String()));
543 while ( ( r = static_cast<Range*>(next()) ) )
545 std::cout << Form("BIN %3d ",i++);
551 //______________________________________________________________________________
552 //______________________________________________________________________________
553 //______________________________________________________________________________
554 //______________________________________________________________________________
556 //______________________________________________________________________________
557 AliAnalysisMuMuBinning::Range::Range(const char* what, const char* quantity,
558 Double_t xmin, Double_t xmax,
559 Double_t ymin, Double_t ymax,
561 : TObject(), fWhat(what), fQuantity(quantity),
562 fXmin(xmin), fXmax(xmax), fYmin(ymin), fYmax(ymax),
570 //______________________________________________________________________________
571 TString AliAnalysisMuMuBinning::Range::AsString() const
573 /// Return a string representation of this range
575 if ( IsIntegrated()) return Quantity().Data();
579 if ( fFlavour.Length() > 0 )
581 s.Form("%s_%s_%05.2f_%05.2f",Quantity().Data(),Flavour().Data(),Xmin(),Xmax());
585 s.Form("%s_%05.2f_%05.2f",Quantity().Data(),Xmin(),Xmax());
590 s += TString::Format("_%06.2f_%06.2f",Ymin(),Ymax());
593 s.ReplaceAll(" ","");
594 s.ReplaceAll("+","");
595 s.ReplaceAll("-","m");
600 //______________________________________________________________________________
601 Int_t AliAnalysisMuMuBinning::Range::Compare(const TObject* obj) const
603 // Must return -1 if this is smaller
604 // than obj, 0 if objects are equal and 1 if this is larger than obj.
605 const Range* other = static_cast<const Range*>(obj);
607 int s = strcmp(What().Data(),other->What().Data());
611 s = strcmp(Quantity().Data(),other->Quantity().Data());
615 s = strcmp(Flavour().Data(),other->Flavour().Data());
619 // if ( IsIntegrated() && other->IsIntegrated() ) return 0;
621 if ( Xmin() < other->Xmin() )
625 else if ( Xmin() > other->Xmin() )
631 if ( Xmax() < other->Xmax() )
635 else if ( Xmax() > other->Xmax() )
640 if ( Ymin() < other->Ymin() )
644 else if ( Ymin() > other->Ymin() )
650 if ( Ymax() < other->Ymax() )
654 else if ( Ymax() > other->Ymax() )
664 //______________________________________________________________________________
665 Bool_t AliAnalysisMuMuBinning::Range::IsInRange(Double_t x, Double_t y) const
667 /// If Range is 1D, returns true if x is in range
668 /// If Range is 2D, returns true if (x,y) is in range
670 if ( IsIntegrated() )
678 return ( x >= Xmin() && x < Xmax() && y >= Ymin() && y < Ymax());
682 return ( x >= Xmin() && x < Xmax() );
687 //______________________________________________________________________________
688 Bool_t AliAnalysisMuMuBinning::Range::IsIntegrated() const
690 /// Whether we're a null object (aka integrated) or not
692 Xmin() >= TMath::Limits<Double_t>::Max() &&
693 Ymin() >= TMath::Limits<Double_t>::Max() &&
694 Xmax() >= TMath::Limits<Double_t>::Max() &&
695 Ymax() >= TMath::Limits<Double_t>::Max() ;
699 //______________________________________________________________________________
700 void AliAnalysisMuMuBinning::Range::Print(Option_t* /*opt*/) const
706 std::cout << Form("%s : %s : INTEGRATED",What().Data(),Quantity().Data()) << std::endl;
711 std::cout << Form("%s : %s : %5.2f : %5.2f",What().Data(),Quantity().Data(),Xmin(),Xmax());
715 std::cout << Form(" ; %5.2f : %5.2f",Ymin(),Ymax());
718 if (Flavour().Length()>0)
720 std::cout << " - " << Flavour().Data();
723 std::cout << "->" << AsString().Data() << std::endl;