]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG/muondep/AliAnalysisMuMuResult.cxx
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / PWG / muondep / AliAnalysisMuMuResult.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15
16 ///
17 /// Base class to hold a set of results for the same quantity,
18 /// computed using various methods, each with their errors
19 ///
20 /// author: Laurent Aphecetche (Subatech)
21 ///
22
23 #include "AliAnalysisMuMuResult.h"
24
25 ClassImp(AliAnalysisMuMuResult)
26
27 #include "THashList.h"
28 #include "TLine.h"
29 #include "TList.h"
30 #include "TMap.h"
31 #include "TMath.h"
32 #include "TObjArray.h"
33 #include "TParameter.h"
34 #include "AliLog.h"
35 #include <map>
36
37 //_____________________________________________________________________________
38 AliAnalysisMuMuResult::AliAnalysisMuMuResult(const char* name, const char* title) :
39 TNamed(name,title),
40 fSubResults(0x0),
41 fMap(0x0),
42 fMother(0x0),
43 fKeys(0x0),
44 fWeight(0.0),
45 fAlias(),
46 fSubResultsToBeIncluded(0x0)
47 {
48   /// default ctor
49 }
50
51 //_____________________________________________________________________________
52 AliAnalysisMuMuResult::AliAnalysisMuMuResult(const AliAnalysisMuMuResult& rhs)
53 :
54 TNamed(rhs),
55 fSubResults(0x0),
56 fMap(0x0),
57 fMother(0x0),
58 fKeys(0x0),
59 fWeight(rhs.fWeight),
60 fAlias(),
61 fSubResultsToBeIncluded(0x0)
62 {
63   /// copy ctor
64   /// Note that the mother is lost
65   /// fKeys remains 0x0 so it will be recomputed if need be
66
67   if (rhs.fSubResults)
68   {
69     fSubResults = static_cast<TObjArray*>(rhs.fSubResults->Clone());
70   }
71   
72   if ( rhs.fMap )
73   {
74     fMap = static_cast<TMap*>(rhs.fMap->Clone());
75   }
76   
77   if ( rhs.fAlias.Length() > 0 )
78   {
79     fAlias = rhs.fAlias;
80   }
81   
82   if ( rhs.fSubResultsToBeIncluded )
83   {
84     fSubResultsToBeIncluded = static_cast<TList*>(rhs.fSubResultsToBeIncluded->Clone());
85   }
86
87 }
88
89 //_____________________________________________________________________________
90 AliAnalysisMuMuResult& AliAnalysisMuMuResult::operator=(const AliAnalysisMuMuResult& rhs)
91 {
92   /// Assignment operator
93   
94   if (this!=&rhs)
95   {
96     delete fMap;
97     delete fSubResults;
98     delete fSubResultsToBeIncluded;
99     
100     fMap = 0x0;
101     fSubResults = 0x0;
102     fKeys = 0x0;
103     fSubResultsToBeIncluded = 0x0;
104     
105     if (rhs.fSubResults)
106     {
107       fSubResults = static_cast<TObjArray*>(rhs.fSubResults->Clone());
108     }
109     
110     if ( rhs.fMap )
111     {
112       fMap = static_cast<TMap*>(rhs.fMap->Clone());
113     }
114
115     if ( rhs.fSubResultsToBeIncluded )
116     {
117       fSubResultsToBeIncluded = static_cast<TList*>(rhs.fSubResultsToBeIncluded->Clone());
118     }
119
120     static_cast<TNamed&>(*this)=rhs;
121
122     fWeight = rhs.fWeight;
123     fAlias="";
124     
125     if ( rhs.fAlias.Length() > 0 )
126     {
127       fAlias = rhs.fAlias;
128     }
129   }
130   
131   return *this;
132 }
133
134 //_____________________________________________________________________________
135 AliAnalysisMuMuResult::~AliAnalysisMuMuResult()
136 {
137   // dtor
138   delete fMap;
139   delete fSubResults;
140   delete fKeys;
141   delete fSubResultsToBeIncluded;
142 }
143
144 //_____________________________________________________________________________
145 void AliAnalysisMuMuResult::AdoptSubResult(AliAnalysisMuMuResult* r)
146 {
147   /// Adopt (i.e. becomes owner) of a subresult
148   if (!fSubResults)
149   {
150     fSubResults = new TObjArray;
151     fSubResults->SetOwner(kTRUE);
152   }
153
154   fSubResults->Add(r);
155   
156   SubResultsToBeIncluded()->Add(new TObjString(r->Alias()));
157 }
158
159 //_____________________________________________________________________________
160 TObject* AliAnalysisMuMuResult::Clone(const char* /*newname*/) const
161 {
162   /// Clone this result
163   return new AliAnalysisMuMuResult(*this);
164 }
165
166
167 //_____________________________________________________________________________
168 Double_t AliAnalysisMuMuResult::ErrorAB(Double_t a, Double_t aerr, Double_t b, Double_t berr)
169 {
170   /// Compute the quadratic sum of 2 errors
171
172   Double_t e(0.0);
173   
174   if ( TMath::Abs(a) > 1E-12 )
175   {
176     e += (aerr*aerr)/(a*a);
177   }
178   
179   if ( TMath::Abs(b) > 1E-12 )
180   {
181     e += (berr*berr)/(b*b);
182   }
183   
184   return TMath::Sqrt(e);
185 }
186
187 //_____________________________________________________________________________
188 Double_t AliAnalysisMuMuResult::ErrorABC(Double_t a, Double_t aerr, Double_t b, Double_t berr, Double_t c, Double_t cerror)
189 {
190   /// Compute the quadratic sum of 3 errors
191   
192   Double_t e(0.0);
193   
194   if ( TMath::Abs(a) > 1E-12 )
195   {
196     e += (aerr*aerr)/(a*a);
197   }
198   
199   if ( TMath::Abs(b) > 1E-12 )
200   {
201     e += (berr*berr)/(b*b);
202   }
203   
204   if ( TMath::Abs(c) > 1E-12 )
205   {
206     e += (cerror*cerror)/(c*c);
207   }
208   
209   return TMath::Sqrt(e);
210 }
211
212 //_____________________________________________________________________________
213 Double_t AliAnalysisMuMuResult::ErrorABCD(Double_t a, Double_t aerr, Double_t b, Double_t berr, Double_t c, Double_t cerror, Double_t d, Double_t derror)
214 {
215   /// Compute the quadratic sum of 4 errors
216   
217   Double_t e(0.0);
218   
219   if ( TMath::Abs(a) > 1E-12 )
220   {
221     e += (aerr*aerr)/(a*a);
222   }
223   
224   if ( TMath::Abs(b) > 1E-12 )
225   {
226     e += (berr*berr)/(b*b);
227   }
228   
229   if ( TMath::Abs(c) > 1E-12 )
230   {
231     e += (cerror*cerror)/(c*c);
232   }
233
234   if ( TMath::Abs(d) > 1E-12 )
235   {
236     e += (derror*derror)/(d*d);
237   }
238
239   return TMath::Sqrt(e);
240 }
241
242 //_____________________________________________________________________________
243 Double_t AliAnalysisMuMuResult::ErrorABCDE(Double_t a, Double_t aerr, Double_t b, Double_t berr, Double_t c, Double_t cerror, Double_t d, Double_t derror, Double_t ee, Double_t eeerror)
244 {
245   /// Compute the quadratic sum of 4 errors
246   
247   Double_t e(0.0);
248   
249   if ( TMath::Abs(a) > 1E-12 )
250   {
251     e += (aerr*aerr)/(a*a);
252   }
253   
254   if ( TMath::Abs(b) > 1E-12 )
255   {
256     e += (berr*berr)/(b*b);
257   }
258   
259   if ( TMath::Abs(c) > 1E-12 )
260   {
261     e += (cerror*cerror)/(c*c);
262   }
263   
264   if ( TMath::Abs(d) > 1E-12 )
265   {
266     e += (derror*derror)/(d*d);
267   }
268
269   if ( TMath::Abs(e) > 1E-12 )
270   {
271     e += (eeerror*eeerror)/(ee*ee);
272   }
273
274   return TMath::Sqrt(e);
275 }
276
277
278 //_____________________________________________________________________________
279 void AliAnalysisMuMuResult::Exclude(const char* subResultList)
280 {
281   // exclude some subresult names from the list of subresult
282   // to be used when computing the mean 
283   
284   TString slist(subResultList);
285   
286   TString tobeincluded = GetSubResultNameList();
287   
288   if ( slist == "*" )
289   {
290     Exclude(tobeincluded);
291     return;
292   }
293   
294   if ( fSubResultsToBeIncluded )
295   {
296     TObjArray* a = slist.Tokenize(",");
297     TIter nextA(a);
298     TObjString* s;
299
300     while ( ( s = static_cast<TObjString*>(nextA())) )
301     {
302       TObject* o = fSubResultsToBeIncluded->FindObject(s->String());
303       fSubResultsToBeIncluded->Remove(o);
304     }
305     
306     delete a;
307   }
308 }
309
310 //_____________________________________________________________________________
311 Double_t AliAnalysisMuMuResult::GetErrorStat(const char* name, const char* subResultName) const
312 {
313   // compute the mean value from all subresults that are included
314   
315   if ( strlen(subResultName) > 0 )
316   {
317     if ( !fSubResults)
318     {
319       AliError(Form("No subresult from which I could get the %s one...",subResultName));
320       return TMath::Limits<Double_t>::Max();
321     }
322     AliAnalysisMuMuResult* sub = static_cast<AliAnalysisMuMuResult*>(fSubResults->FindObject(subResultName));
323     if (!sub)
324     {
325       AliError(Form("Could not get subresult named %s",subResultName));
326       return TMath::Limits<Double_t>::Max();
327     }
328     return sub->GetErrorStat(name);
329   }
330   
331   if ( fMap )
332   {
333     TObjArray* p = static_cast<TObjArray*>(fMap->GetValue(name));
334     if (p)
335     {
336       TParameter<double>* val = static_cast<TParameter<double>*>(p->At(kErrorStat));
337       return val->GetVal();
338     }
339   }
340   
341   TIter next(fSubResults);
342   AliAnalysisMuMuResult* r;
343   Int_t n(0);
344   Double_t v1(0);
345   Double_t v2(0);
346   Double_t d(0);
347   
348   Double_t mean = GetValue(name);
349   
350   while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
351   {    
352     if ( IsIncluded(r->Alias()) && r->HasValue(name) )
353     {
354       Double_t error = r->GetErrorStat(name);
355       if (error)
356       {
357         v1 += 1.0/(error*error);
358         v2 += 1.0/(error*error*error*error);
359        
360         d += ( (r->GetValue(name) - mean)*(r->GetValue(name)-mean) / (error*error));
361       }
362       ++n;
363     }
364   }
365   
366   if ( n<1 ) return 0.0;
367   
368   if ( n == 1 )
369   {
370     next.Reset();
371     while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
372     {
373       if ( IsIncluded(r->Alias()) && r->HasValue(name) )
374       {
375         return r->GetErrorStat(name);
376       }
377     }
378     return 0.0;
379   }
380   
381   Double_t variance= (1.0/v1)*(1.0/(n-1))*d;
382     // variance corrected by over/under-estimation of errors
383     // i.e. scaled by chisquare per ndf
384   
385   return TMath::Sqrt(variance);
386 }
387
388 //_____________________________________________________________________________
389 Double_t AliAnalysisMuMuResult::GetRMS(const char* name, const char* subResultName) const
390 {
391   // compute the rms of the subresults
392   // returns zero if no subresults
393
394   if ( strlen(subResultName) > 0 )
395   {
396     if ( !fSubResults)
397     {
398       AliError(Form("No subresult from which I could get the %s one...",subResultName));
399       return TMath::Limits<Double_t>::Max();
400     }
401     AliAnalysisMuMuResult* sub = static_cast<AliAnalysisMuMuResult*>(fSubResults->FindObject(subResultName));
402     if (!sub)
403     {
404       AliError(Form("Could not get subresult named %s",subResultName));
405       return TMath::Limits<Double_t>::Max();
406     }
407     return sub->GetRMS(name);
408   }
409   
410   if ( fMap )
411   {
412     TObjArray* p = static_cast<TObjArray*>(fMap->GetValue(name));
413     if (p)
414     {
415       TParameter<double>* val = static_cast<TParameter<double>*>(p->At(kRMS));
416       return val ? val->GetVal() : 0.0; // val can be null for old results which did not have the rms set
417     }
418   }
419   
420   TIter next(fSubResults);
421   AliAnalysisMuMuResult* r;
422   Double_t v1(0);
423   Double_t v2(0);
424   Double_t sum(0);
425   Int_t n(0);
426   
427   Double_t xmean = GetValue(name);
428   
429   while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
430   {
431     if ( IsIncluded(r->Alias()) && r->HasValue(name) )
432     {
433       if ( r->GetErrorStat(name) > 0 )
434       {
435         Double_t ei = r->GetErrorStat(name);
436         Double_t wi = 1.0/(ei*ei);
437         v1 += wi;
438         v2 += wi*wi;
439         Double_t diff = r->GetValue(name) - xmean;
440         sum += wi*diff*diff;
441         ++n;
442       }
443     }
444   }
445   
446   if ( n < 1 ) return 0.0;
447   
448   if ( n == 1 )
449   {
450     next.Reset();
451     while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
452     {
453       if ( IsIncluded(r->Alias()) && r->HasValue(name) )
454       {
455         return r->GetRMS(name);
456       }
457     }
458   }
459   
460   Double_t unbiased = TMath::Sqrt( (v1/(v1*v1-v2)) * sum);
461   
462   Double_t biased = TMath::Sqrt( sum/v1 );
463   
464   AliDebug(1,Form("v1 %e v1*v1 %e v2 %e -> biased %e unbiased %e (ratio %e)",v1,v1*v1,v2,biased,unbiased,unbiased/biased));
465   
466   return unbiased;
467 }
468
469 //_____________________________________________________________________________
470 TString AliAnalysisMuMuResult::GetSubResultNameList() const
471 {
472   // get a comma separated list of our subresult aliases
473   TString tobeincluded;
474   TIter next(fSubResults);
475   AliAnalysisMuMuResult* r;
476   
477   while ( ( r = static_cast<AliAnalysisMuMuResult*>(next())) )
478   {
479     if (tobeincluded.Length()>0) tobeincluded+=",";
480     tobeincluded += r->Alias();
481   }
482   return tobeincluded;
483 }
484
485 //_____________________________________________________________________________
486 Double_t AliAnalysisMuMuResult::GetValue(const char* name, const char* subResultName) const
487 {
488   // get a value (either directly or by computing the mean of the subresults)
489   
490   if ( strlen(subResultName) > 0 )
491   {
492     if ( !fSubResults)
493     {
494       AliError(Form("No subresult from which I could get the %s one...",subResultName));
495       return TMath::Limits<Double_t>::Max();
496     }
497     AliAnalysisMuMuResult* sub = static_cast<AliAnalysisMuMuResult*>(fSubResults->FindObject(subResultName));
498     if (!sub)
499     {
500       AliError(Form("Could not get subresult named %s",subResultName));
501       return TMath::Limits<Double_t>::Max();
502     }
503     return sub->GetValue(name);
504   }
505   
506   if (fMap)
507   {
508     TObjArray* p = static_cast<TObjArray*>(fMap->GetValue(name));
509     if (p)
510     {
511       TParameter<double>* val = static_cast<TParameter<double>*>(p->At(kValue));
512       return val->GetVal();
513     }
514   }
515   
516   // compute the mean value from all subresults
517   TIter next(fSubResults);
518   AliAnalysisMuMuResult* r;
519   Double_t mean(0);
520   Double_t errorSum(0.0);
521   
522   while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
523   {
524     if ( IsIncluded(r->Alias()) && r->HasValue(name) )
525     {
526       Double_t e = r->GetErrorStat(name);
527       Double_t e2 = e*e;
528       if ( e != 0.0 )
529       {
530         mean += r->GetValue(name)/e2;
531         errorSum += 1.0/e2;
532       }
533     }
534   }
535   if ( errorSum != 0.0 )
536   {
537     return mean/errorSum;
538   }
539   else
540   {
541     return TMath::Limits<Double_t>::Max();
542   }
543 }
544
545 //_____________________________________________________________________________
546 Bool_t AliAnalysisMuMuResult::HasValue(const char* name, const char* subResultName) const
547 {
548   /// Whether this result (or subresult if subResultName is provided) has a property
549   /// named "name"
550   
551   if ( strlen(subResultName) > 0 )
552   {
553     if ( !fSubResults)
554     {
555       AliError(Form("No subresult from which I could get the %s one...",subResultName));
556       return kFALSE;
557     }
558     AliAnalysisMuMuResult* sub = static_cast<AliAnalysisMuMuResult*>(fSubResults->FindObject(subResultName));
559     if (!sub)
560     {
561       AliError(Form("Could not get subresult named %s",subResultName));
562       return kFALSE;
563     }
564     return sub->HasValue(name);
565   }
566
567   if ( fMap && ( fMap->GetValue(name) != 0x0 ) )
568   {
569     return kTRUE;
570   }
571   
572   TIter next(fSubResults);
573   AliAnalysisMuMuResult* r;
574
575   while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
576   {
577     if ( r->HasValue(name) ) return kTRUE;
578   }
579   
580   return kFALSE;
581 }
582
583 //_____________________________________________________________________________
584 void AliAnalysisMuMuResult::Include(const char* subResultList)
585 {
586   // (re)include some subresult names
587   
588   TString slist(subResultList);
589
590   if ( slist.Length()==0 )
591   {
592     Exclude("*");
593     return;
594   }
595   
596   if ( slist == "*" )
597   {
598     slist = GetSubResultNameList();
599   }
600
601   TObjArray* a = slist.Tokenize(",");
602   a->SetOwner(kFALSE);
603   TIter next(a);
604   TObjString* s;
605   
606   while ( ( s = static_cast<TObjString*>(next()) ) )
607   {
608     if (!fSubResultsToBeIncluded )
609     {
610       fSubResultsToBeIncluded = new TList;
611       fSubResultsToBeIncluded->SetOwner(kTRUE);
612     }
613     if (!IsIncluded(s->String()))
614     {
615       fSubResultsToBeIncluded->Add(s);      
616     }
617   }
618   
619   delete a;
620 }
621
622 //_____________________________________________________________________________
623 Bool_t AliAnalysisMuMuResult::IsIncluded(const TString& alias) const
624 {
625   // whether that subresult alias should be included when computing means, etc...
626   
627   if (!fSubResultsToBeIncluded) return kTRUE;
628   
629   return ( fSubResultsToBeIncluded->FindObject(alias) != 0x0 );
630 }
631
632 //_____________________________________________________________________________
633 THashList* AliAnalysisMuMuResult::Keys() const
634 {
635   /// Return the complete list of keys we're using
636   if (!fKeys)
637   {
638     fKeys = new THashList;
639     fKeys->SetOwner(kTRUE);
640     TIter next(fMap);
641     TObjString* key;
642     
643     while ( ( key = static_cast<TObjString*>(next()) ) )
644     {
645       if ( !fKeys->FindObject(key->String()) )
646       {
647         fKeys->Add(new TObjString(key->String()));
648       }
649     }
650     
651     AliAnalysisMuMuResult* r;
652     TIter nextResult(fSubResults);
653     
654     while ( ( r = static_cast<AliAnalysisMuMuResult*>(nextResult())) )
655     {
656       TIter nextHL(r->Keys());
657       TObjString* s;
658       
659       while ( ( s = static_cast<TObjString*>(nextHL())) )
660       {
661         if ( !fKeys->FindObject(s->String()) )
662         {
663           fKeys->Add(new TObjString(s->String()));
664         }
665       }
666     }
667
668   }
669   return fKeys;
670 }
671
672 //_____________________________________________________________________________
673 Long64_t AliAnalysisMuMuResult::Merge(TCollection* list)
674 {
675   /// Merge method
676   ///
677   /// Merge a list of AliAnalysisMuMuResult objects with this
678   /// Returns the number of merged objects (including this).
679   ///
680   /// Note that the merging is to be understood here as a weighed mean operation
681   
682   if (!list) return 0;
683   
684   if (list->IsEmpty()) return 1;
685   
686   TIter next(list);
687   TObject* currObj;
688
689   Double_t sumw(Weight()); // sum of weights
690   
691   while ( ( currObj = next() ) )
692   {
693     AliAnalysisMuMuResult* result = dynamic_cast<AliAnalysisMuMuResult*>(currObj);
694     if (!result)
695     {
696       AliFatal(Form("object named \"%s\" is a %s instead of an AliAnalysisMuMuResult!", currObj->GetName(), currObj->ClassName()));
697       continue;
698     }
699     
700     sumw += result->Weight();
701   }
702   
703   TIter nextKey(Keys());
704   TObjString* key;
705   
706   while ( ( key = static_cast<TObjString*>(nextKey())) )
707   {
708     Double_t value = GetValue(key->String())*Weight()/sumw;
709     Double_t e = GetErrorStat(key->String());
710     Double_t e2 = e*e*Weight()*Weight()/sumw/sumw;
711
712     next.Reset();
713     
714     while ( ( currObj = next() ) )
715     {
716       AliAnalysisMuMuResult* result = dynamic_cast<AliAnalysisMuMuResult*>(currObj);
717     
718       if (!result)
719       { 
720         continue;
721       }
722       
723       if (!result->HasValue(key->String()))
724       {
725         AliError(Form("Did not find key %s in of the result to merge",key->String().Data()));
726         continue;
727       }
728       
729       // can only merge under the condition we have the same bin
730     
731       Double_t w = result->Weight()/sumw;
732       
733       Double_t w2 = w*w;
734       
735       value += result->GetValue(key->String())*w;
736       e2 += result->GetErrorStat(key->String())*result->GetErrorStat(key->String())*w2;
737       
738     }
739     
740     Set(key->String(),
741         value,
742         TMath::Sqrt(e2));
743   }
744   
745   TIter nextSubresult(fSubResults);
746   AliAnalysisMuMuResult* r;
747   
748   while ( ( r = static_cast<AliAnalysisMuMuResult*>(nextSubresult())) )
749   {
750     TList sublist;
751
752     next.Reset();
753     
754     while ( ( currObj = next() ) )
755     {
756       sublist.Add(currObj);
757     }
758
759     r->Merge(&sublist);
760   }
761   
762   fWeight = sumw;
763   
764   return list->GetEntries()+1;
765 }
766
767 //_____________________________________________________________________________
768 Int_t AliAnalysisMuMuResult::NofIncludedSubResults(const char* name) const
769 {
770   // Return the number of subresults which have key name and are included
771   
772   TIter next(fSubResults);
773   AliAnalysisMuMuResult* r;
774   Int_t n(0);
775   while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
776   {
777     if ( IsIncluded(r->Alias()) && r->HasValue(name) )
778     {
779       ++n;
780     }
781   }
782   return n;
783 }
784
785 //_____________________________________________________________________________
786 void AliAnalysisMuMuResult::Print(Option_t* opt) const
787 {
788   /// printout
789   
790   TString sopt(opt);
791   sopt.ToUpper();
792   
793   for ( Int_t i = 0; i < 9; ++i )
794   {
795     sopt.ReplaceAll(Form("%d",i),"");
796   }
797   
798   TString pot(sopt);
799   pot.ReplaceAll("ALL","");
800   pot.ReplaceAll("FULL","");
801
802   std::cout << pot.Data();
803   
804     if ( fAlias.Length() > 0 )
805     {
806       std::cout << Form("%s - ",fAlias.Data());
807     }
808   
809     std::cout << Form("%s %s %s",
810                       GetName(),GetTitle(),fWeight > 0.0 ? Form(" WEIGHT %e",fWeight) : "");
811   
812   if ( fSubResults && fSubResults->GetEntries()>1 )
813   {
814     std::cout << " (" << fSubResults->GetEntries() << " subresults)";
815   }
816
817   std::cout << std::endl;
818   
819   TIter next(Keys());
820   TObjString* key;
821   
822   while ( ( key = static_cast<TObjString*>(next())) )
823   {
824     PrintValue(key->String().Data(),pot.Data(),
825                GetValue(key->String()),
826                GetErrorStat(key->String()),
827                GetRMS(key->String()));
828   }
829
830   if ( fSubResults /* && fSubResults->GetEntries() > 1 */ && ( sopt.Contains("ALL") || sopt.Contains("FULL") ) )
831   {
832     std::cout << pot.Data() << "\t===== sub results ===== " << std::endl;
833     
834     sopt += "\t\t";
835     
836     TIter nextSubresult(fSubResults);
837     AliAnalysisMuMuResult* r;
838     
839     while ( ( r = static_cast<AliAnalysisMuMuResult*>(nextSubresult()) ) )
840     {
841       if ( !IsIncluded(r->Alias()) )
842       {
843         std::cout << " [EXCLUDED]";
844       }
845       r->Print(sopt.Data());
846     }
847   }
848 }
849
850 //_____________________________________________________________________________
851 void AliAnalysisMuMuResult::PrintValue(const char* key, const char* opt,
852                                        Double_t value, Double_t errorStat, Double_t rms) const
853 {
854   // print one value and its associated error
855   
856   if ( TString(key).Contains("AccEff") )
857   {
858     std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f %% (%5.2f %%)",key,value*100,errorStat*100,
859                              value != 0.0 ? errorStat*100.0/value : 0.0 );
860     
861     if ( rms )
862     {
863       std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
864     }
865
866     std::cout << std::endl;
867   }
868   else if ( TString(key).BeginsWith("Sigma") ||  TString(key).BeginsWith("Mean") )
869   {
870     std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f (%5.2f %%) MeV/c^2",key,value*1E3,1E3*errorStat,
871                              value != 0.0 ? errorStat*100.0/value : 0.0);
872     
873     if ( rms )
874     {
875       std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
876     }
877
878     std::cout << std::endl;
879   }
880   else if ( TString(key).Contains("Nof") || ( TString(key).Contains("Fnorm") && !TString(key).Contains("persion") ) )
881   {
882     std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f (%5.2f %%)",key,value,errorStat,
883                              value != 0.0 ? errorStat*100.0/value : 0.0);
884     
885     if ( rms )
886     {
887       std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
888     }
889     std::cout << std::endl;
890   }
891   else if ( value > 1E-3 && value < 1E3 )
892   {
893     std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f (%5.2f %%)",key,value,errorStat,
894                              value != 0.0 ? errorStat*100.0/value : 0.0);
895     if ( rms )
896     {
897       std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
898     }
899     std::cout << std::endl;
900   }
901   else
902   {
903     std::cout << opt << Form("\t\t%20s %9.2e +- %9.2e (%5.2f %%)",key,value,errorStat,
904                              value != 0.0 ? errorStat*100.0/value : 0.0);
905     if ( rms )
906     {
907       std::cout << Form(" RMS %9.2e (%5.2f %%)",rms,100.0*rms/value);
908     }
909     std::cout << std::endl;
910   }
911 }
912
913 //_____________________________________________________________________________
914 void AliAnalysisMuMuResult::Scale(Double_t w)
915 {
916   /// Scale all our internal values by value
917   
918   TIter next(Keys());
919   TObjString* key;
920   
921   while ( ( key = static_cast<TObjString*>(next())) )
922   {
923     Double_t value = GetValue(key->String());
924     Double_t error = GetErrorStat(key->String());
925     Double_t rms = GetRMS(key->String());
926     
927     Set(key->String(),value*w,error*w,rms*w);
928   }
929
930 }
931
932 //_____________________________________________________________________________
933 void AliAnalysisMuMuResult::Set(const char* name, Double_t value, Double_t errorStat, Double_t rms)
934 {
935   /// Set a (value,error) pair with a given name
936   
937   if ( !fMap )
938   {
939     fMap = new TMap;
940     fMap->SetOwnerKeyValue(kTRUE,kTRUE);
941   }
942   
943   TObjArray* p = static_cast<TObjArray*>(fMap->GetValue(name));
944   if (!p)
945   {
946     p = new TObjArray(4);
947     
948     p->SetOwner(kTRUE);
949     
950     p->AddAt(new TParameter<Double_t>(name,value),kValue);
951     p->AddAt(new TParameter<Double_t>(name,errorStat),kErrorStat);
952     p->AddAt(new TParameter<Double_t>(name,rms),kRMS);
953     
954     fMap->Add(new TObjString(name),p);
955   }
956   else
957   {
958     static_cast<TParameter<double>*>(p->At(kValue))->SetVal(value);
959     static_cast<TParameter<double>*>(p->At(kErrorStat))->SetVal(errorStat);
960     static_cast<TParameter<double>*>(p->At(kRMS))->SetVal(rms);
961   }
962 }
963
964 //_____________________________________________________________________________
965 AliAnalysisMuMuResult*
966 AliAnalysisMuMuResult::SubResult(const char* subResultName) const
967 {
968   /// get a given subresult
969   if (!fSubResults)
970   {
971     return 0x0;
972   }
973   TIter next(fSubResults);
974   AliAnalysisMuMuResult* r;
975   while ( ( r = static_cast<AliAnalysisMuMuResult*>(next())) )
976   {
977     if ( r->Alias() == subResultName )
978     {
979       return r;
980     }
981   }
982   return 0x0;
983 }
984
985 //_____________________________________________________________________________
986 TList* AliAnalysisMuMuResult::SubResultsToBeIncluded() const
987 {
988   if (!fSubResultsToBeIncluded)
989   {
990     fSubResultsToBeIncluded = new TList;
991     fSubResultsToBeIncluded->SetOwner(kTRUE);
992   }
993   return fSubResultsToBeIncluded;
994 }
995