]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG/muon/AliAnalysisMuMuBinning.cxx
AliErrors related to zero weight removed
[u/mrichter/AliRoot.git] / PWG / muon / AliAnalysisMuMuBinning.cxx
1 #include "AliAnalysisMuMuBinning.h"
2
3 //
4 // AliAnalysisMuMuBinning.h : a class to hold bins of various sizes
5 //
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.
9 // 
10 // author: L. Aphecetche (Subatech)
11 //
12
13 #include "AliLog.h"
14 #include "Riostream.h"
15 #include "TMap.h"
16 #include "TMath.h"
17 #include "TObjArray.h"
18 #include "TObjString.h"
19 #include <cassert>
20
21 ClassImp(AliAnalysisMuMuBinning::Range)
22 ClassImp(AliAnalysisMuMuBinning)
23
24 //______________________________________________________________________________
25 AliAnalysisMuMuBinning::AliAnalysisMuMuBinning(const char* name, const char* title)
26 : TNamed(name,title), fBins(0x0)
27 {
28   // default ctor
29 }
30
31 //______________________________________________________________________________
32 AliAnalysisMuMuBinning::AliAnalysisMuMuBinning(const AliAnalysisMuMuBinning& rhs)
33 : TNamed(), fBins(0x0)
34 {
35   // copy ctor
36   TObjArray* bins = rhs.CreateBinObjArray();
37   TIter next(bins);
38   AliAnalysisMuMuBinning::Range* b;
39   
40   while ( ( b = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
41   {
42     AddBin(*b);
43   }
44 }
45
46 //______________________________________________________________________________
47 AliAnalysisMuMuBinning& AliAnalysisMuMuBinning::operator=(const AliAnalysisMuMuBinning& rhs)
48 {
49   // assignment  operator
50   
51   if ( this != &rhs )
52   {
53     delete fBins;
54     fBins = 0x0;
55     TObjArray* bins = rhs.CreateBinObjArray();
56     TIter next(bins);
57     AliAnalysisMuMuBinning::Range* b;
58   
59     while ( ( b = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
60     {
61       AddBin(*b);
62     }
63   }
64   return *this;
65 }
66
67 //______________________________________________________________________________
68 AliAnalysisMuMuBinning::~AliAnalysisMuMuBinning()
69 {
70   // dtor
71   delete fBins;
72 }
73
74 //______________________________________________________________________________
75 void AliAnalysisMuMuBinning::AddBin(const AliAnalysisMuMuBinning::Range& bin)
76 {
77   /// add one bin
78   AddBin(bin.What().Data(),bin.Quantity().Data(),
79          bin.Xmin(),bin.Xmax(),
80          bin.Ymin(),bin.Ymax(),bin.Flavour());
81 }
82
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,
87                                     const char* flavour)
88 {
89   /// Add a bin
90   /// Note that what and Quantity are not case sensitive.
91   if (!fBins)
92   {
93     fBins = new TMap;
94     fBins->SetOwnerKeyValue(kTRUE,kTRUE);
95   }
96   
97   TString swhat(what);
98   swhat.ToUpper();
99   
100   TString sQuantity(quantity);
101   sQuantity.ToUpper();
102   
103   TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(swhat.Data()));
104   if (!b)
105   {
106     b = new TObjArray;
107     b->SetOwner(kTRUE);
108     fBins->Add(new TObjString(swhat),b);
109   }
110
111   Range* r = new Range(swhat.Data(),sQuantity.Data(),xmin,xmax,ymin,ymax,flavour);
112   
113   if ( b->FindObject(r) )
114   {
115     AliDebug(1,Form("Trying to add an already existing bin : %s. Not doing it.",r->AsString().Data()));
116     delete r;
117   }
118   else
119   {
120     b->Add(r);
121     
122     TString bQuantity(Form("%s-%s",swhat.Data(),sQuantity.Data()));
123     
124     TString name(GetName());
125     
126     if ( !name.Contains(bQuantity) )
127     {
128       if (name.Length()>0)
129       {
130         name += " ";
131       }
132         
133       name += bQuantity;
134       SetName(name);
135     }
136   }
137   
138   b->Sort();
139 }
140
141 //______________________________________________________________________________
142 Double_t* AliAnalysisMuMuBinning::CreateBinArray() const
143 {
144   /// Create a (variable) bin array suitable for TH1 constructor
145   /// The returned array must be deleted by the user
146   /// (using delete[] )
147   
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;
153   Int_t i(0);
154   while ( ( b = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
155   {
156     bins[i] = b->Xmin();
157     ++i;
158   }
159
160   b = static_cast<AliAnalysisMuMuBinning::Range*>(binArray->At(binArray->GetEntries()-1));
161   
162   bins[i] = b->Xmax();
163   
164   delete binArray;
165   return bins;
166 }
167
168 //______________________________________________________________________________
169 TObjArray* AliAnalysisMuMuBinning::CreateBinObjArray() const
170 {
171   /// Get the list of all the bins
172   /// The returned array must be deleted by the user
173   
174   TObjArray* a = new TObjArray;
175   a->SetOwner(kTRUE);
176
177   TIter nextwhat(fBins);
178   TObjString* what;
179   
180   while ( ( what = static_cast<TObjString*>(nextwhat()) ) )
181   {
182     TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(what->String().Data()));
183     TIter next(b);
184     Range* r;
185   
186     while ( ( r = static_cast<Range*>(next()) ) )
187     {
188       a->Add(r->Clone());
189     }
190   }
191   
192   if ( a->GetLast() < 0 )
193   {
194     delete a;
195     a = 0x0;
196   }
197   return a;
198 }
199
200 //______________________________________________________________________________
201 TObjArray* AliAnalysisMuMuBinning::CreateBinObjArray(const char* what) const
202 {
203   /// Get the list of bins for a given what 
204   /// The returned array must be deleted by the user
205   
206   if (!fBins) return 0x0;
207   
208   TObjArray* a = new TObjArray;
209   a->SetOwner(kTRUE);
210   
211   TString swhat(what);
212   swhat.ToUpper();
213   
214   TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(swhat.Data()));
215   if (!b) return 0x0;
216   
217   TIter next(b);
218   Range* r;
219   
220   while ( ( r = static_cast<Range*>(next()) ) )
221   {
222     a->Add(r->Clone());
223   }
224   
225   if ( a->GetLast() < 0 )
226   {
227     delete a;
228     a = 0x0;
229   }
230   return a;
231 }
232
233
234 //______________________________________________________________________________
235 TObjArray* AliAnalysisMuMuBinning::CreateBinObjArray(const char* what, const char* quantity, const char* flavour) const
236 {
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
240   
241   TObjArray* a = new TObjArray;
242   a->SetOwner(kTRUE);
243   
244   TString swhat(what);
245   swhat.ToUpper();
246
247   TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(swhat.Data()));
248   if (!b) return 0x0;
249   
250   TIter next(b);
251   Range* r;
252
253   TString sQuantity(quantity);
254   sQuantity.ToUpper();
255
256   TString sflavour(flavour);
257   
258   TObjArray* Quantitys = sQuantity.Tokenize(",");
259   TObjString* oneQuantity;
260   TIter nextQuantity(Quantitys);
261   
262   while ( ( r = static_cast<Range*>(next()) ) )
263   {
264     nextQuantity.Reset();
265     while ( ( oneQuantity = static_cast<TObjString*>(nextQuantity()) ) )
266     {
267       if ( r->Quantity() == oneQuantity->String() &&
268           ( ( sflavour.Length() > 0 && r->Flavour() == sflavour.Data() ) || sflavour.Length()==0 ) )
269       {
270         a->Add(r->Clone());
271       }
272     }
273   }
274   
275   if ( a->GetLast() < 0 )
276   {
277     delete a;
278     a = 0x0;
279   }
280   
281   delete Quantitys;
282   return a;
283 }
284
285 //______________________________________________________________________________
286 Double_t* AliAnalysisMuMuBinning::CreateBinArrayY() const
287 {
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[] )
291   
292   TObjArray* binArray = CreateBinObjArray();
293   if (!binArray) return 0x0;
294   
295   AliAnalysisMuMuBinning::Range* firstBin = static_cast<AliAnalysisMuMuBinning::Range*>(binArray->First());
296   
297   Double_t* binsY = new Double_t[binArray->GetEntries()+1];
298   
299   Double_t minY = firstBin->Ymin();
300   Double_t maxY = firstBin->Ymax();
301   
302   if ( !(minY < maxY))
303   {
304     std::cout << "No 2D binning" << std::endl;
305     delete binsY;
306     delete binArray;
307     return 0x0;
308   }
309   
310   TIter next(binArray);
311   AliAnalysisMuMuBinning::Range* b;
312   Int_t i(0);
313   while ( ( b = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
314   {
315     if ( (i != 0) && (minY == b->Ymin()) ) break;
316     
317     binsY[i] = b->Ymin();
318     ++i;
319   }
320   
321   b = static_cast<AliAnalysisMuMuBinning::Range*>(binArray->At(i-1));
322   
323   binsY[i] = b->Ymax();
324   
325   Double_t* bins = new Double_t[i + 1];
326   
327   for (Int_t j = 0 ; j < (i+1) ; j++)
328   {
329     bins[j] = binsY[j];
330   }
331   
332   delete binArray;
333   delete[] binsY;
334   return bins;
335 }
336
337 //______________________________________________________________________________
338 Int_t AliAnalysisMuMuBinning::GetNBinsX() const
339 {
340   /// Gets the number of x bins, suitable for TH1
341   
342   
343   TObjArray* binArray = CreateBinObjArray();
344   if (!binArray) return 0;
345   
346   Double_t binsX(0);
347   
348   
349   TIter next(binArray);
350   AliAnalysisMuMuBinning::Range* b;
351   Int_t i(0);
352   while ( ( b = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
353   {
354     if ( (i != 0) && (binsX == b->Xmin()) ) continue;
355     
356     binsX = b->Xmin();
357     ++i;
358   }
359   
360   delete binArray;
361   return i;
362 }
363
364 //______________________________________________________________________________
365 Int_t AliAnalysisMuMuBinning::GetNBinsY() const
366 {
367   /// Gets the number of x bins, suitable for TH1
368   
369   
370   TObjArray* binArray = CreateBinObjArray();
371   if (!binArray) return 0x0;
372   
373   Double_t binsY(0);
374   
375   AliAnalysisMuMuBinning::Range* firstBin = static_cast<AliAnalysisMuMuBinning::Range*>(binArray->First());
376   
377   Double_t minY = firstBin->Ymin();
378   Double_t maxY = firstBin->Ymax();
379   
380   if ( !(minY < maxY))
381   {
382     std::cout << "No 2D binning" << std::endl;
383     delete binArray;
384     return 0;
385   }
386   
387   TIter next(binArray);
388   AliAnalysisMuMuBinning::Range* b;
389   Int_t i(0);
390   while ( ( b = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
391   {
392     if ( (i != 0) && (minY == b->Ymin()) ) break;
393     
394     binsY = b->Ymin();
395     ++i;
396   }
397   
398   delete binArray;
399   return i;
400 }
401
402 //______________________________________________________________________________
403 Double_t* AliAnalysisMuMuBinning::CreateBinArrayX() const
404 {
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[] )
408   
409   TObjArray* binArray = CreateBinObjArray();
410   if (!binArray) return 0x0;
411   
412   Double_t* binsX = new Double_t[binArray->GetEntries()+1];
413   
414   
415   TIter next(binArray);
416   AliAnalysisMuMuBinning::Range* b;
417   Int_t i(0);
418   while ( ( b = static_cast<AliAnalysisMuMuBinning::Range*>(next()) ) )
419   {
420     if ( (i != 0) && (binsX[i-1] == b->Xmin()) ) continue;
421     
422     binsX[i] = b->Xmin();
423     ++i;
424   }
425   
426   b = static_cast<AliAnalysisMuMuBinning::Range*>(binArray->At(binArray->GetEntries()-1));
427   
428   binsX[i] = b->Xmax();
429   
430   Double_t* bins = new Double_t[i + 1];
431   
432   for (Int_t j = 0 ; j < (i+1) ; j++)
433   {
434     bins[j] = binsX[j];
435   }
436   
437   delete binArray;
438   delete[] binsX;
439   return bins;
440 }
441
442 //______________________________________________________________________________
443 void AliAnalysisMuMuBinning::CreateMesh(const char* what,
444                                         const char* quantity1, const char* quantity2,
445                                         const char* flavour,
446                                         Bool_t remove12)
447 {
448   /// Create 2D bins from existing 1d ones of Quantity1 and Quantity2
449   TObjArray* a1 = CreateBinObjArray(what,quantity1,flavour);
450   if (!a1)
451   {
452     AliError(Form("No bin for Quantity %s. Done nothing.",quantity1));
453     return;
454   }
455   TObjArray* a2 = CreateBinObjArray(what,quantity2,flavour);
456   if (!a2)
457   {
458     AliError(Form("No bin for Quantity %s. Done nothing.",quantity2));
459     return;
460   }
461   
462   TString meshQuantity(Form("%s VS %s - %s",quantity1,quantity2,flavour));
463   
464   for ( Int_t i1 = 0; i1 <= a1->GetLast(); ++i1 )
465   {
466     Range* r1 = static_cast<Range*>(a1->At(i1));
467
468     for ( Int_t i2 = 0; i2 <= a2->GetLast(); ++i2 )
469     {
470       Range* r2 = static_cast<Range*>(a2->At(i2));
471       
472       AddBin(what,meshQuantity,r2->Xmin(),r2->Xmax(),r1->Xmin(),r1->Xmax(),Form("%s VS %s",r1->Flavour().Data(),r2->Flavour().Data()));
473     }
474   }
475   
476   delete a1;
477   delete a2;
478
479   if ( remove12 )
480   {
481     TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(what));
482     TIter next(b);
483     Range* r;
484     TString sQuantity1(quantity1);
485     TString sQuantity2(quantity2);
486
487     sQuantity1.ToUpper();
488     sQuantity2.ToUpper();
489     
490     while ( ( r = static_cast<Range*>(next())) )
491     {
492       if ( r->Quantity() == quantity1 ||
493            r->Quantity() == quantity2 )
494       {
495         b->Remove(r);
496       }
497     }
498   }
499 }
500
501 //______________________________________________________________________________
502 TObjArray* AliAnalysisMuMuBinning::CreateWhatArray() const
503 {
504   /// Create a TObjString array with the names of the what we're holding results for
505   /// Returned array must be delete by user
506   
507   TObjArray* whatArray(0x0);
508   
509   TIter nextwhat(fBins);
510   TObjString* what;
511
512   while ( ( what = static_cast<TObjString*>(nextwhat()) ) )
513   {
514     if (!whatArray)
515     {
516       whatArray = new TObjArray;
517       whatArray->SetOwner(kTRUE);
518     }
519     whatArray->Add(new TObjString(*what));
520   }
521   return whatArray;
522 }
523
524 //______________________________________________________________________________
525 TObjArray* AliAnalysisMuMuBinning::CreateQuantityArray() const
526 {
527   /// Create a TObjString array with the names of the binning Quantitys
528   /// Returned array must be delete by user
529
530   TObjArray* QuantityArray(0x0);
531   
532   TIter nextwhat(fBins);
533   TObjString* what;
534   
535   while ( ( what = static_cast<TObjString*>(nextwhat()) ) )
536   {
537     TObjArray* whats = static_cast<TObjArray*>(fBins->GetValue(what->String()));
538     
539     TIter next(whats);
540     Range* r;
541     
542     while ( ( r = static_cast<Range*>(next())) )
543     {
544       if (!QuantityArray)
545       {
546         QuantityArray = new TObjArray;
547         QuantityArray->SetOwner(kTRUE);
548       }
549       if ( !QuantityArray->FindObject(r->Quantity()) )
550       {
551         QuantityArray->Add(new TObjString(r->Quantity()));
552       }
553     }
554   }
555   return QuantityArray;
556 }
557
558 //______________________________________________________________________________
559 Bool_t AliAnalysisMuMuBinning::IsEqual(const TObject* obj) const
560 {
561   /// Return kTRUE if obj is an AliAnalysisMuMuBinning object and is
562   /// equal to *this
563   
564   if ( obj->IsA() == AliAnalysisMuMuBinning::Class() )
565   {
566     const AliAnalysisMuMuBinning* other = static_cast<const AliAnalysisMuMuBinning*>(obj);
567     
568     TIter nextOther(other->fBins);
569     TObjString* str;
570     
571     while ( ( str = static_cast<TObjString*>(nextOther()) ) )
572     {
573       TObject* o = fBins->GetValue(str->String());
574       if (!o) return kFALSE;
575       if (o->IsA() != TObjArray::Class()) return kFALSE;
576
577       TObjArray* thisArray = static_cast<TObjArray*>(o);
578
579       o = other->fBins->GetValue(str->String());
580       if (!o) return kFALSE;
581       if (o->IsA() != TObjArray::Class()) return kFALSE;
582       
583       TObjArray* otherArray = static_cast<TObjArray*>(o);
584       
585       Int_t n = thisArray->GetEntries();
586       
587       if ( n != otherArray->GetEntries() ) return kFALSE;
588       
589       for ( Int_t i = 0; i < n; ++i )
590       {
591         Range* thisRange = static_cast<Range*>(thisArray->At(i));
592         Range* otherRange = static_cast<Range*>(otherArray->At(i));
593         
594         if ( !thisRange->IsEqual(otherRange) ) return kFALSE;
595       }
596     }
597     return kTRUE;
598   }
599   
600   return kFALSE;
601 }
602
603
604 //______________________________________________________________________________
605 Long64_t AliAnalysisMuMuBinning::Merge(TCollection* list)
606 {
607   /// Merge method
608   
609   // Merge a list of AliAnalysisMuMuBinning objects with this
610   // Returns the number of merged objects (including this).
611   
612   if (!list) return 0;
613   
614   if (list->IsEmpty()) return 1;
615   
616   TIter next(list);
617   TObject* currObj;
618   Int_t count(0);
619   
620   while ( ( currObj = next() ) )
621   {
622     AliAnalysisMuMuBinning* binning = dynamic_cast<AliAnalysisMuMuBinning*>(currObj);
623     if (!binning)
624     {
625       AliFatal(Form("object named \"%s\" is a %s instead of an AliAnalysisMuMuBinning!", currObj->GetName(), currObj->ClassName()));
626       continue;
627     }
628     
629     if ( IsEqual(binning) )
630     {
631       // nothing to do if we have the same binning already ;-)
632     }
633     else
634     {
635       AliWarning("Implement me!");
636       std::cout << ">>>> this=" << std::endl;
637       Print();
638       std::cout << ">>>> other=" << std::endl;
639       binning->Print();
640     }
641     ++count;
642   }
643   
644   return count+1;
645 }
646
647 //______________________________________________________________________________
648 AliAnalysisMuMuBinning*
649 AliAnalysisMuMuBinning::Project(const char* what, const char* quantity, const char* flavour) const
650 {
651   /// Create a sub-binning object with only the bins pertaining to (what,Quantity)
652   
653   TObjArray* bins = CreateBinObjArray(what,quantity,flavour);
654   if (!bins) return 0x0;
655   AliAnalysisMuMuBinning* p = new AliAnalysisMuMuBinning;
656   TIter next(bins);
657   AliAnalysisMuMuBinning::Range* bin;
658   TString sQuantity(quantity);
659   sQuantity.ToUpper();
660   
661   while ( ( bin = static_cast<AliAnalysisMuMuBinning::Range*>(next())) )
662   {
663     if  (bin->Quantity()!=sQuantity || bin->Flavour()!=flavour)
664     {
665       AliDebug(1,Form("sQuantity=%s flavour=%s bin=%s => skip",sQuantity.Data(),flavour,bin->AsString().Data()));
666       continue;
667     }
668     {
669       p->AddBin(what,bin->Quantity(),bin->Xmin(),bin->Xmax(),bin->Ymin(),bin->Ymax(),bin->Flavour().Data());
670     }
671   }
672   
673   delete bins;
674   
675   return p;
676 }
677
678 //______________________________________________________________________________
679 void AliAnalysisMuMuBinning::Print(Option_t* /*opt*/) const
680 {
681   /// Print the bins
682   
683   if (!fBins)
684   {
685     std::cout << "Empty object. No bin defined. " << std::endl;
686     return;
687   }
688   
689   TIter nextwhat(fBins);
690   TObjString* str;
691   
692   while ( ( str = static_cast<TObjString*>(nextwhat()) ) )
693   {
694     std::cout << "what : " << str->String().Data() << std::endl;
695     TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(str->String()));
696     TIter next(b);
697     Range* r(0x0);
698     next.Reset();
699     Int_t i(1);
700     while ( ( r = static_cast<Range*>(next()) ) )
701     {
702       std::cout << Form("BIN %3d ",i++);
703       r->Print();
704     }
705   }
706 }
707
708 //______________________________________________________________________________
709 //______________________________________________________________________________
710 //______________________________________________________________________________
711 //______________________________________________________________________________
712
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,
717                                      const char* flavour)
718 : TObject(), fWhat(what), fQuantity(quantity),
719   fXmin(xmin), fXmax(xmax), fYmin(ymin), fYmax(ymax),
720   fFlavour(flavour)
721 {
722   /// ctor
723   fWhat.ToUpper();
724   fQuantity.ToUpper();
725 }
726
727 //______________________________________________________________________________
728 TString AliAnalysisMuMuBinning::Range::AsString() const
729 {
730   /// Return a string representation of this range
731   
732   if ( IsIntegrated()) return Quantity().Data();
733   
734   TString s;
735   
736   if ( fFlavour.Length() > 0 )
737   {
738     s.Form("%s_%s_%05.2f_%05.2f",Quantity().Data(),Flavour().Data(),Xmin(),Xmax());
739   }
740   else
741   {
742     s.Form("%s_%05.2f_%05.2f",Quantity().Data(),Xmin(),Xmax());
743   }
744   
745   if (Is2D())
746   {
747     s += TString::Format("_%06.2f_%06.2f",Ymin(),Ymax());
748   }
749
750   s.ReplaceAll(" ","");
751   s.ReplaceAll("+","");
752   s.ReplaceAll("-","m");
753
754   return s;
755 }
756
757 //______________________________________________________________________________
758 Int_t   AliAnalysisMuMuBinning::Range::Compare(const TObject* obj) const
759 {
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);
763   
764   int s = strcmp(What().Data(),other->What().Data());
765   
766   if ( s ) return s;
767   
768   s = strcmp(Quantity().Data(),other->Quantity().Data());
769   
770   if (s) return s;
771   
772   s = strcmp(Flavour().Data(),other->Flavour().Data());
773   
774   if (s) return s;
775   
776 //  if ( IsIntegrated() && other->IsIntegrated() ) return 0;
777   
778   if ( Xmin() < other->Xmin() )
779   {
780     return -1;
781   }
782   else if ( Xmin() > other->Xmin() )
783   {
784     return 1;
785   }
786   else
787   {
788     if  ( Xmax() < other->Xmax() )
789     {
790       return -1;
791     }
792     else if ( Xmax() > other->Xmax() )
793     {
794       return 1;
795     }
796     else {
797       if ( Ymin() < other->Ymin() )
798       {
799         return -1;
800       }
801       else if ( Ymin() > other->Ymin() )
802       {
803         return 1;
804       }
805       else
806       {
807         if ( Ymax() < other->Ymax() )
808         {
809           return -1;
810         }
811         else if ( Ymax() > other->Ymax() )
812         {
813           return 1;
814         }
815       }
816     }
817   }
818   return 0;
819 }
820
821 //______________________________________________________________________________
822 Bool_t AliAnalysisMuMuBinning::Range::IsInRange(Double_t x, Double_t y) const
823 {
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
826   
827   if ( IsIntegrated() )
828   {
829     return kTRUE;
830   }
831   else
832   {
833     if ( Is2D() )
834     {
835       return ( x >= Xmin() && x < Xmax() && y >= Ymin() && y < Ymax());
836     }
837     else
838     {
839       return ( x >= Xmin() && x < Xmax() );
840     }
841   }
842 }
843
844 //______________________________________________________________________________
845 Bool_t AliAnalysisMuMuBinning::Range::IsIntegrated() const
846 {
847   /// Whether we're a null object (aka integrated) or not
848   return
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() ;
853 }
854
855
856 //______________________________________________________________________________
857 void AliAnalysisMuMuBinning::Range::Print(Option_t* /*opt*/) const
858 {
859   /// Output to stdout
860   
861   if (IsIntegrated())
862   {
863     std::cout << Form("%s : %s : INTEGRATED",What().Data(),Quantity().Data()) << std::endl;
864   
865     return;
866   }
867   
868   std::cout << Form("%s : %s : %5.2f : %5.2f",What().Data(),Quantity().Data(),Xmin(),Xmax());
869   
870   if (Is2D())
871   {
872     std::cout << Form(" ; %5.2f : %5.2f",Ymin(),Ymax());
873   }
874   
875   if (Flavour().Length()>0)
876   {
877     std::cout << " - " << Flavour().Data();
878   }
879   
880   std::cout << "->" << AsString().Data() << std::endl;
881   
882 }
883
884