]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG/muon/AliAnalysisMuMuBinning.cxx
expand particle map when needed
[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 void AliAnalysisMuMuBinning::CreateMesh(const char* what,
287                                         const char* quantity1, const char* quantity2,
288                                         const char* flavour,
289                                         Bool_t remove12)
290 {
291   /// Create 2D bins from existing 1d ones of Quantity1 and Quantity2
292   TObjArray* a1 = CreateBinObjArray(what,quantity1,flavour);
293   if (!a1)
294   {
295     AliError(Form("No bin for Quantity %s. Done nothing.",quantity1));
296     return;
297   }
298   TObjArray* a2 = CreateBinObjArray(what,quantity2,flavour);
299   if (!a2)
300   {
301     AliError(Form("No bin for Quantity %s. Done nothing.",quantity2));
302     return;
303   }
304   
305   TString meshQuantity(Form("%s VS %s - %s",quantity1,quantity2,flavour));
306   
307   for ( Int_t i1 = 0; i1 <= a1->GetLast(); ++i1 )
308   {
309     Range* r1 = static_cast<Range*>(a1->At(i1));
310
311     for ( Int_t i2 = 0; i2 <= a2->GetLast(); ++i2 )
312     {
313       Range* r2 = static_cast<Range*>(a2->At(i2));
314       
315       AddBin(what,meshQuantity,r2->Xmin(),r2->Xmax(),r1->Xmin(),r1->Xmax(),Form("%s VS %s",r1->Flavour().Data(),r2->Flavour().Data()));
316     }
317   }
318   
319   delete a1;
320   delete a2;
321
322   if ( remove12 )
323   {
324     TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(what));
325     TIter next(b);
326     Range* r;
327     TString sQuantity1(quantity1);
328     TString sQuantity2(quantity2);
329
330     sQuantity1.ToUpper();
331     sQuantity2.ToUpper();
332     
333     while ( ( r = static_cast<Range*>(next())) )
334     {
335       if ( r->Quantity() == quantity1 ||
336            r->Quantity() == quantity2 )
337       {
338         b->Remove(r);
339       }
340     }
341   }
342 }
343
344 //______________________________________________________________________________
345 TObjArray* AliAnalysisMuMuBinning::CreateWhatArray() const
346 {
347   /// Create a TObjString array with the names of the what we're holding results for
348   /// Returned array must be delete by user
349   
350   TObjArray* whatArray(0x0);
351   
352   TIter nextwhat(fBins);
353   TObjString* what;
354
355   while ( ( what = static_cast<TObjString*>(nextwhat()) ) )
356   {
357     if (!whatArray)
358     {
359       whatArray = new TObjArray;
360       whatArray->SetOwner(kTRUE);
361     }
362     whatArray->Add(new TObjString(*what));
363   }
364   return whatArray;
365 }
366
367 //______________________________________________________________________________
368 TObjArray* AliAnalysisMuMuBinning::CreateQuantityArray() const
369 {
370   /// Create a TObjString array with the names of the binning Quantitys
371   /// Returned array must be delete by user
372
373   TObjArray* QuantityArray(0x0);
374   
375   TIter nextwhat(fBins);
376   TObjString* what;
377   
378   while ( ( what = static_cast<TObjString*>(nextwhat()) ) )
379   {
380     TObjArray* whats = static_cast<TObjArray*>(fBins->GetValue(what->String()));
381     
382     TIter next(whats);
383     Range* r;
384     
385     while ( ( r = static_cast<Range*>(next())) )
386     {
387       if (!QuantityArray)
388       {
389         QuantityArray = new TObjArray;
390         QuantityArray->SetOwner(kTRUE);
391       }
392       if ( !QuantityArray->FindObject(r->Quantity()) )
393       {
394         QuantityArray->Add(new TObjString(r->Quantity()));
395       }
396     }
397   }
398   return QuantityArray;
399 }
400
401 //______________________________________________________________________________
402 Bool_t AliAnalysisMuMuBinning::IsEqual(const TObject* obj) const
403 {
404   /// Return kTRUE if obj is an AliAnalysisMuMuBinning object and is
405   /// equal to *this
406   
407   if ( obj->IsA() == AliAnalysisMuMuBinning::Class() )
408   {
409     const AliAnalysisMuMuBinning* other = static_cast<const AliAnalysisMuMuBinning*>(obj);
410     
411     TIter nextOther(other->fBins);
412     TObjString* str;
413     
414     while ( ( str = static_cast<TObjString*>(nextOther()) ) )
415     {
416       TObject* o = fBins->GetValue(str->String());
417       if (!o) return kFALSE;
418       if (o->IsA() != TObjArray::Class()) return kFALSE;
419
420       TObjArray* thisArray = static_cast<TObjArray*>(o);
421
422       o = other->fBins->GetValue(str->String());
423       if (!o) return kFALSE;
424       if (o->IsA() != TObjArray::Class()) return kFALSE;
425       
426       TObjArray* otherArray = static_cast<TObjArray*>(o);
427       
428       Int_t n = thisArray->GetEntries();
429       
430       if ( n != otherArray->GetEntries() ) return kFALSE;
431       
432       for ( Int_t i = 0; i < n; ++i )
433       {
434         Range* thisRange = static_cast<Range*>(thisArray->At(i));
435         Range* otherRange = static_cast<Range*>(otherArray->At(i));
436         
437         if ( !thisRange->IsEqual(otherRange) ) return kFALSE;
438       }
439     }
440     return kTRUE;
441   }
442   
443   return kFALSE;
444 }
445
446
447 //______________________________________________________________________________
448 Long64_t AliAnalysisMuMuBinning::Merge(TCollection* list)
449 {
450   /// Merge method
451   
452   // Merge a list of AliAnalysisMuMuBinning objects with this
453   // Returns the number of merged objects (including this).
454   
455   if (!list) return 0;
456   
457   if (list->IsEmpty()) return 1;
458   
459   TIter next(list);
460   TObject* currObj;
461   Int_t count(0);
462   
463   while ( ( currObj = next() ) )
464   {
465     AliAnalysisMuMuBinning* binning = dynamic_cast<AliAnalysisMuMuBinning*>(currObj);
466     if (!binning)
467     {
468       AliFatal(Form("object named \"%s\" is a %s instead of an AliAnalysisMuMuBinning!", currObj->GetName(), currObj->ClassName()));
469       continue;
470     }
471     
472     if ( IsEqual(binning) )
473     {
474       // nothing to do if we have the same binning already ;-)
475     }
476     else
477     {
478       AliWarning("Implement me!");
479       std::cout << ">>>> this=" << std::endl;
480       Print();
481       std::cout << ">>>> other=" << std::endl;
482       binning->Print();
483     }
484     ++count;
485   }
486   
487   return count+1;
488 }
489
490 //______________________________________________________________________________
491 AliAnalysisMuMuBinning*
492 AliAnalysisMuMuBinning::Project(const char* what, const char* quantity, const char* flavour) const
493 {
494   /// Create a sub-binning object with only the bins pertaining to (what,Quantity)
495   
496   TObjArray* bins = CreateBinObjArray(what,quantity,flavour);
497   if (!bins) return 0x0;
498   AliAnalysisMuMuBinning* p = new AliAnalysisMuMuBinning;
499   TIter next(bins);
500   AliAnalysisMuMuBinning::Range* bin;
501   TString sQuantity(quantity);
502   sQuantity.ToUpper();
503   
504   while ( ( bin = static_cast<AliAnalysisMuMuBinning::Range*>(next())) )
505   {
506     if  (bin->Quantity()!=sQuantity || bin->Flavour()!=flavour)
507     {
508       AliDebug(1,Form("sQuantity=%s flavour=%s bin=%s => skip",sQuantity.Data(),flavour,bin->AsString().Data()));
509       continue;
510     }
511     {
512       p->AddBin(what,bin->Quantity(),bin->Xmin(),bin->Xmax(),bin->Ymin(),bin->Ymax(),bin->Flavour().Data());
513     }
514   }
515   
516   delete bins;
517   
518   return p;
519 }
520
521 //______________________________________________________________________________
522 void AliAnalysisMuMuBinning::Print(Option_t* /*opt*/) const
523 {
524   /// Print the bins
525   
526   if (!fBins)
527   {
528     std::cout << "Empty object. No bin defined. " << std::endl;
529     return;
530   }
531   
532   TIter nextwhat(fBins);
533   TObjString* str;
534   
535   while ( ( str = static_cast<TObjString*>(nextwhat()) ) )
536   {
537     std::cout << "what : " << str->String().Data() << std::endl;
538     TObjArray* b = static_cast<TObjArray*>(fBins->GetValue(str->String()));
539     TIter next(b);
540     Range* r(0x0);
541     next.Reset();
542     Int_t i(1);
543     while ( ( r = static_cast<Range*>(next()) ) )
544     {
545       std::cout << Form("BIN %3d ",i++);
546       r->Print();
547     }
548   }
549 }
550
551 //______________________________________________________________________________
552 //______________________________________________________________________________
553 //______________________________________________________________________________
554 //______________________________________________________________________________
555
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,
560                                      const char* flavour)
561 : TObject(), fWhat(what), fQuantity(quantity),
562   fXmin(xmin), fXmax(xmax), fYmin(ymin), fYmax(ymax),
563   fFlavour(flavour)
564 {
565   /// ctor
566   fWhat.ToUpper();
567   fQuantity.ToUpper();
568 }
569
570 //______________________________________________________________________________
571 TString AliAnalysisMuMuBinning::Range::AsString() const
572 {
573   /// Return a string representation of this range
574   
575   if ( IsIntegrated()) return Quantity().Data();
576   
577   TString s;
578   
579   if ( fFlavour.Length() > 0 )
580   {
581     s.Form("%s_%s_%05.2f_%05.2f",Quantity().Data(),Flavour().Data(),Xmin(),Xmax());
582   }
583   else
584   {
585     s.Form("%s_%05.2f_%05.2f",Quantity().Data(),Xmin(),Xmax());
586   }
587   
588   if (Is2D())
589   {
590     s += TString::Format("_%06.2f_%06.2f",Ymin(),Ymax());
591   }
592
593   s.ReplaceAll(" ","");
594   s.ReplaceAll("+","");
595   s.ReplaceAll("-","m");
596
597   return s;
598 }
599
600 //______________________________________________________________________________
601 Int_t   AliAnalysisMuMuBinning::Range::Compare(const TObject* obj) const
602 {
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);
606   
607   int s = strcmp(What().Data(),other->What().Data());
608   
609   if ( s ) return s;
610   
611   s = strcmp(Quantity().Data(),other->Quantity().Data());
612   
613   if (s) return s;
614   
615   s = strcmp(Flavour().Data(),other->Flavour().Data());
616   
617   if (s) return s;
618   
619 //  if ( IsIntegrated() && other->IsIntegrated() ) return 0;
620   
621   if ( Xmin() < other->Xmin() )
622   {
623     return -1;
624   }
625   else if ( Xmin() > other->Xmin() )
626   {
627     return 1;
628   }
629   else
630   {
631     if  ( Xmax() < other->Xmax() )
632     {
633       return -1;
634     }
635     else if ( Xmax() > other->Xmax() )
636     {
637       return 1;
638     }
639     else {
640       if ( Ymin() < other->Ymin() )
641       {
642         return -1;
643       }
644       else if ( Ymin() > other->Ymin() )
645       {
646         return 1;
647       }
648       else
649       {
650         if ( Ymax() < other->Ymax() )
651         {
652           return -1;
653         }
654         else if ( Ymax() > other->Ymax() )
655         {
656           return 1;
657         }
658       }
659     }
660   }
661   return 0;
662 }
663
664 //______________________________________________________________________________
665 Bool_t AliAnalysisMuMuBinning::Range::IsInRange(Double_t x, Double_t y) const
666 {
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
669   
670   if ( IsIntegrated() )
671   {
672     return kTRUE;
673   }
674   else
675   {
676     if ( Is2D() )
677     {
678       return ( x >= Xmin() && x < Xmax() && y >= Ymin() && y < Ymax());
679     }
680     else
681     {
682       return ( x >= Xmin() && x < Xmax() );
683     }
684   }
685 }
686
687 //______________________________________________________________________________
688 Bool_t AliAnalysisMuMuBinning::Range::IsIntegrated() const
689 {
690   /// Whether we're a null object (aka integrated) or not
691   return
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() ;
696 }
697
698
699 //______________________________________________________________________________
700 void AliAnalysisMuMuBinning::Range::Print(Option_t* /*opt*/) const
701 {
702   /// Output to stdout
703   
704   if (IsIntegrated())
705   {
706     std::cout << Form("%s : %s : INTEGRATED",What().Data(),Quantity().Data()) << std::endl;
707   
708     return;
709   }
710   
711   std::cout << Form("%s : %s : %5.2f : %5.2f",What().Data(),Quantity().Data(),Xmin(),Xmax());
712   
713   if (Is2D())
714   {
715     std::cout << Form(" ; %5.2f : %5.2f",Ymin(),Ymax());
716   }
717   
718   if (Flavour().Length()>0)
719   {
720     std::cout << " - " << Flavour().Data();
721   }
722   
723   std::cout << "->" << AsString().Data() << std::endl;
724   
725 }
726
727