1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 /// Base class to hold a set of results for the same quantity,
18 /// computed using various methods, each with their errors
20 /// author: Laurent Aphecetche (Subatech)
23 #include "AliAnalysisMuMuResult.h"
25 ClassImp(AliAnalysisMuMuResult)
27 #include "THashList.h"
32 #include "TObjArray.h"
33 #include "TParameter.h"
37 //_____________________________________________________________________________
38 AliAnalysisMuMuResult::AliAnalysisMuMuResult(const char* name, const char* title) :
46 fSubResultsToBeIncluded(0x0)
51 //_____________________________________________________________________________
52 AliAnalysisMuMuResult::AliAnalysisMuMuResult(const AliAnalysisMuMuResult& rhs)
61 fSubResultsToBeIncluded(0x0)
64 /// Note that the mother is lost
65 /// fKeys remains 0x0 so it will be recomputed if need be
69 fSubResults = static_cast<TObjArray*>(rhs.fSubResults->Clone());
74 fMap = static_cast<TMap*>(rhs.fMap->Clone());
77 if ( rhs.fAlias.Length() > 0 )
82 if ( rhs.fSubResultsToBeIncluded )
84 fSubResultsToBeIncluded = static_cast<TList*>(rhs.fSubResultsToBeIncluded->Clone());
89 //_____________________________________________________________________________
90 AliAnalysisMuMuResult& AliAnalysisMuMuResult::operator=(const AliAnalysisMuMuResult& rhs)
92 /// Assignment operator
98 delete fSubResultsToBeIncluded;
103 fSubResultsToBeIncluded = 0x0;
107 fSubResults = static_cast<TObjArray*>(rhs.fSubResults->Clone());
112 fMap = static_cast<TMap*>(rhs.fMap->Clone());
115 if ( rhs.fSubResultsToBeIncluded )
117 fSubResultsToBeIncluded = static_cast<TList*>(rhs.fSubResultsToBeIncluded->Clone());
120 static_cast<TNamed&>(*this)=rhs;
122 fWeight = rhs.fWeight;
125 if ( rhs.fAlias.Length() > 0 )
134 //_____________________________________________________________________________
135 AliAnalysisMuMuResult::~AliAnalysisMuMuResult()
141 delete fSubResultsToBeIncluded;
144 //_____________________________________________________________________________
145 void AliAnalysisMuMuResult::AdoptSubResult(AliAnalysisMuMuResult* r)
147 /// Adopt (i.e. becomes owner) of a subresult
150 fSubResults = new TObjArray;
151 fSubResults->SetOwner(kTRUE);
156 SubResultsToBeIncluded()->Add(new TObjString(r->Alias()));
159 //_____________________________________________________________________________
160 TObject* AliAnalysisMuMuResult::Clone(const char* /*newname*/) const
162 /// Clone this result
163 return new AliAnalysisMuMuResult(*this);
167 //_____________________________________________________________________________
168 Double_t AliAnalysisMuMuResult::ErrorAB(Double_t a, Double_t aerr, Double_t b, Double_t berr)
170 /// Compute the quadratic sum of 2 errors
174 if ( TMath::Abs(a) > 1E-12 )
176 e += (aerr*aerr)/(a*a);
179 if ( TMath::Abs(b) > 1E-12 )
181 e += (berr*berr)/(b*b);
184 return TMath::Sqrt(e);
187 //_____________________________________________________________________________
188 Double_t AliAnalysisMuMuResult::ErrorABC(Double_t a, Double_t aerr, Double_t b, Double_t berr, Double_t c, Double_t cerror)
190 /// Compute the quadratic sum of 3 errors
194 if ( TMath::Abs(a) > 1E-12 )
196 e += (aerr*aerr)/(a*a);
199 if ( TMath::Abs(b) > 1E-12 )
201 e += (berr*berr)/(b*b);
204 if ( TMath::Abs(c) > 1E-12 )
206 e += (cerror*cerror)/(c*c);
209 return TMath::Sqrt(e);
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)
215 /// Compute the quadratic sum of 4 errors
219 if ( TMath::Abs(a) > 1E-12 )
221 e += (aerr*aerr)/(a*a);
224 if ( TMath::Abs(b) > 1E-12 )
226 e += (berr*berr)/(b*b);
229 if ( TMath::Abs(c) > 1E-12 )
231 e += (cerror*cerror)/(c*c);
234 if ( TMath::Abs(d) > 1E-12 )
236 e += (derror*derror)/(d*d);
239 return TMath::Sqrt(e);
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)
245 /// Compute the quadratic sum of 4 errors
249 if ( TMath::Abs(a) > 1E-12 )
251 e += (aerr*aerr)/(a*a);
254 if ( TMath::Abs(b) > 1E-12 )
256 e += (berr*berr)/(b*b);
259 if ( TMath::Abs(c) > 1E-12 )
261 e += (cerror*cerror)/(c*c);
264 if ( TMath::Abs(d) > 1E-12 )
266 e += (derror*derror)/(d*d);
269 if ( TMath::Abs(e) > 1E-12 )
271 e += (eeerror*eeerror)/(ee*ee);
274 return TMath::Sqrt(e);
278 //_____________________________________________________________________________
279 void AliAnalysisMuMuResult::Exclude(const char* subResultList)
281 // exclude some subresult names from the list of subresult
282 // to be used when computing the mean
284 TString slist(subResultList);
286 TString tobeincluded = GetSubResultNameList();
290 Exclude(tobeincluded);
294 if ( fSubResultsToBeIncluded )
296 TObjArray* a = slist.Tokenize(",");
300 while ( ( s = static_cast<TObjString*>(nextA())) )
302 TObject* o = fSubResultsToBeIncluded->FindObject(s->String());
303 fSubResultsToBeIncluded->Remove(o);
310 //_____________________________________________________________________________
311 Double_t AliAnalysisMuMuResult::GetErrorStat(const char* name, const char* subResultName) const
313 // compute the mean value from all subresults that are included
315 if ( strlen(subResultName) > 0 )
319 AliError(Form("No subresult from which I could get the %s one...",subResultName));
320 return TMath::Limits<Double_t>::Max();
322 AliAnalysisMuMuResult* sub = static_cast<AliAnalysisMuMuResult*>(fSubResults->FindObject(subResultName));
325 AliError(Form("Could not get subresult named %s",subResultName));
326 return TMath::Limits<Double_t>::Max();
328 return sub->GetErrorStat(name);
333 TObjArray* p = static_cast<TObjArray*>(fMap->GetValue(name));
336 TParameter<double>* val = static_cast<TParameter<double>*>(p->At(kErrorStat));
337 return val->GetVal();
341 TIter next(fSubResults);
342 AliAnalysisMuMuResult* r;
348 Double_t mean = GetValue(name);
350 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
352 if ( IsIncluded(r->Alias()) && r->HasValue(name) )
354 Double_t error = r->GetErrorStat(name);
357 v1 += 1.0/(error*error);
358 v2 += 1.0/(error*error*error*error);
360 d += ( (r->GetValue(name) - mean)*(r->GetValue(name)-mean) / (error*error));
366 if ( n<1 ) return 0.0;
371 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
373 if ( IsIncluded(r->Alias()) && r->HasValue(name) )
375 return r->GetErrorStat(name);
380 Double_t variance= (1.0/v1)*(1.0/(n-1))*d;
381 // variance corrected by over/under-estimation of errors
382 // i.e. scaled by chisquare per ndf
384 return TMath::Sqrt(variance);
387 //_____________________________________________________________________________
388 Double_t AliAnalysisMuMuResult::GetRMS(const char* name, const char* subResultName) const
390 // compute the rms of the subresults
391 // returns zero if no subresults
393 if ( strlen(subResultName) > 0 )
397 AliError(Form("No subresult from which I could get the %s one...",subResultName));
398 return TMath::Limits<Double_t>::Max();
400 AliAnalysisMuMuResult* sub = static_cast<AliAnalysisMuMuResult*>(fSubResults->FindObject(subResultName));
403 AliError(Form("Could not get subresult named %s",subResultName));
404 return TMath::Limits<Double_t>::Max();
406 return sub->GetRMS(name);
411 TObjArray* p = static_cast<TObjArray*>(fMap->GetValue(name));
414 TParameter<double>* val = static_cast<TParameter<double>*>(p->At(kRMS));
415 return val ? val->GetVal() : 0.0; // val can be null for old results which did not have the rms set
419 TIter next(fSubResults);
420 AliAnalysisMuMuResult* r;
426 Double_t xmean = GetValue(name);
428 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
430 if ( IsIncluded(r->Alias()) && r->HasValue(name) )
432 if ( r->GetErrorStat(name) > 0 )
434 Double_t ei = r->GetErrorStat(name);
435 Double_t wi = 1.0/(ei*ei);
438 Double_t diff = r->GetValue(name) - xmean;
445 if ( n < 1 ) return 0.0;
450 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
452 if ( IsIncluded(r->Alias()) && r->HasValue(name) )
454 return r->GetRMS(name);
459 Double_t unbiased = TMath::Sqrt( (v1/(v1*v1-v2)) * sum);
461 Double_t biased = TMath::Sqrt( sum/v1 );
463 AliDebug(1,Form("v1 %e v1*v1 %e v2 %e -> biased %e unbiased %e (ratio %e)",v1,v1*v1,v2,biased,unbiased,unbiased/biased));
468 //_____________________________________________________________________________
469 TString AliAnalysisMuMuResult::GetSubResultNameList() const
471 // get a comma separated list of our subresult aliases
472 TString tobeincluded;
473 TIter next(fSubResults);
474 AliAnalysisMuMuResult* r;
476 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next())) )
478 if (tobeincluded.Length()>0) tobeincluded+=",";
479 tobeincluded += r->Alias();
484 //_____________________________________________________________________________
485 Double_t AliAnalysisMuMuResult::GetValue(const char* name, const char* subResultName) const
487 // get a value (either directly or by computing the mean of the subresults)
489 if ( strlen(subResultName) > 0 )
493 AliError(Form("No subresult from which I could get the %s one...",subResultName));
494 return TMath::Limits<Double_t>::Max();
496 AliAnalysisMuMuResult* sub = static_cast<AliAnalysisMuMuResult*>(fSubResults->FindObject(subResultName));
499 AliError(Form("Could not get subresult named %s",subResultName));
500 return TMath::Limits<Double_t>::Max();
502 return sub->GetValue(name);
507 TObjArray* p = static_cast<TObjArray*>(fMap->GetValue(name));
510 TParameter<double>* val = static_cast<TParameter<double>*>(p->At(kValue));
511 return val->GetVal();
515 // compute the mean value from all subresults
516 TIter next(fSubResults);
517 AliAnalysisMuMuResult* r;
519 Double_t errorSum(0.0);
521 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
523 if ( IsIncluded(r->Alias()) && r->HasValue(name) )
525 Double_t e = r->GetErrorStat(name);
529 mean += r->GetValue(name)/e2;
534 if ( errorSum != 0.0 )
536 return mean/errorSum;
540 return TMath::Limits<Double_t>::Max();
544 //_____________________________________________________________________________
545 Bool_t AliAnalysisMuMuResult::HasValue(const char* name, const char* subResultName) const
547 /// Whether this result (or subresult if subResultName is provided) has a property
550 if ( strlen(subResultName) > 0 )
554 AliError(Form("No subresult from which I could get the %s one...",subResultName));
557 AliAnalysisMuMuResult* sub = static_cast<AliAnalysisMuMuResult*>(fSubResults->FindObject(subResultName));
560 AliError(Form("Could not get subresult named %s",subResultName));
563 return sub->HasValue(name);
566 if ( fMap && ( fMap->GetValue(name) != 0x0 ) )
571 TIter next(fSubResults);
572 AliAnalysisMuMuResult* r;
574 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
576 if ( r->HasValue(name) ) return kTRUE;
582 //_____________________________________________________________________________
583 void AliAnalysisMuMuResult::Include(const char* subResultList)
585 // (re)include some subresult names
587 TString slist(subResultList);
589 if ( slist.Length()==0 )
597 slist = GetSubResultNameList();
600 TObjArray* a = slist.Tokenize(",");
605 while ( ( s = static_cast<TObjString*>(next()) ) )
607 if (!fSubResultsToBeIncluded )
609 fSubResultsToBeIncluded = new TList;
610 fSubResultsToBeIncluded->SetOwner(kTRUE);
612 if (!IsIncluded(s->String()))
614 fSubResultsToBeIncluded->Add(s);
621 //_____________________________________________________________________________
622 Bool_t AliAnalysisMuMuResult::IsIncluded(const TString& alias) const
624 // whether that subresult alias should be included when computing means, etc...
626 if (!fSubResultsToBeIncluded) return kTRUE;
628 return ( fSubResultsToBeIncluded->FindObject(alias) != 0x0 );
631 //_____________________________________________________________________________
632 THashList* AliAnalysisMuMuResult::Keys() const
634 /// Return the complete list of keys we're using
637 fKeys = new THashList;
638 fKeys->SetOwner(kTRUE);
642 while ( ( key = static_cast<TObjString*>(next()) ) )
644 if ( !fKeys->FindObject(key->String()) )
646 fKeys->Add(new TObjString(key->String()));
650 AliAnalysisMuMuResult* r;
651 TIter nextResult(fSubResults);
653 while ( ( r = static_cast<AliAnalysisMuMuResult*>(nextResult())) )
655 TIter nextHL(r->Keys());
658 while ( ( s = static_cast<TObjString*>(nextHL())) )
660 if ( !fKeys->FindObject(s->String()) )
662 fKeys->Add(new TObjString(s->String()));
671 //_____________________________________________________________________________
672 Long64_t AliAnalysisMuMuResult::Merge(TCollection* list)
676 /// Merge a list of AliAnalysisMuMuResult objects with this
677 /// Returns the number of merged objects (including this).
679 /// Note that the merging is to be understood here as a weighed mean operation
683 if (list->IsEmpty()) return 1;
688 Double_t sumw(Weight()); // sum of weights
690 while ( ( currObj = next() ) )
692 AliAnalysisMuMuResult* result = dynamic_cast<AliAnalysisMuMuResult*>(currObj);
695 AliFatal(Form("object named \"%s\" is a %s instead of an AliAnalysisMuMuResult!", currObj->GetName(), currObj->ClassName()));
699 sumw += result->Weight();
702 TIter nextKey(Keys());
705 while ( ( key = static_cast<TObjString*>(nextKey())) )
707 Double_t value = GetValue(key->String())*Weight()/sumw;
708 Double_t e = GetErrorStat(key->String());
709 Double_t e2 = e*e*Weight()*Weight()/sumw/sumw;
713 while ( ( currObj = next() ) )
715 AliAnalysisMuMuResult* result = dynamic_cast<AliAnalysisMuMuResult*>(currObj);
722 if (!result->HasValue(key->String()))
724 AliError(Form("Did not find key %s in of the result to merge",key->String().Data()));
728 // can only merge under the condition we have the same bin
730 Double_t w = result->Weight()/sumw;
734 value += result->GetValue(key->String())*w;
735 e2 += result->GetErrorStat(key->String())*result->GetErrorStat(key->String())*w2;
744 TIter nextSubresult(fSubResults);
745 AliAnalysisMuMuResult* r;
747 while ( ( r = static_cast<AliAnalysisMuMuResult*>(nextSubresult())) )
753 while ( ( currObj = next() ) )
755 sublist.Add(currObj);
763 return list->GetEntries()+1;
766 //_____________________________________________________________________________
767 Int_t AliAnalysisMuMuResult::NofIncludedSubResults(const char* name) const
769 // Return the number of subresults which have key name and are included
771 TIter next(fSubResults);
772 AliAnalysisMuMuResult* r;
774 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
776 if ( IsIncluded(r->Alias()) && r->HasValue(name) )
784 //_____________________________________________________________________________
785 void AliAnalysisMuMuResult::Print(Option_t* opt) const
792 for ( Int_t i = 0; i < 9; ++i )
794 sopt.ReplaceAll(Form("%d",i),"");
798 pot.ReplaceAll("ALL","");
799 pot.ReplaceAll("FULL","");
801 std::cout << pot.Data();
803 if ( fAlias.Length() > 0 )
805 std::cout << Form("%s - ",fAlias.Data());
808 std::cout << Form("%s %s %s",
809 GetName(),GetTitle(),fWeight > 0.0 ? Form(" WEIGHT %e",fWeight) : "");
811 if ( fSubResults && fSubResults->GetEntries()>1 )
813 std::cout << " (" << fSubResults->GetEntries() << " subresults)";
816 std::cout << std::endl;
821 while ( ( key = static_cast<TObjString*>(next())) )
823 PrintValue(key->String().Data(),pot.Data(),
824 GetValue(key->String()),
825 GetErrorStat(key->String()),
826 GetRMS(key->String()));
829 if ( fSubResults /* && fSubResults->GetEntries() > 1 */ && ( sopt.Contains("ALL") || sopt.Contains("FULL") ) )
831 std::cout << pot.Data() << "\t===== sub results ===== " << std::endl;
835 TIter nextSubresult(fSubResults);
836 AliAnalysisMuMuResult* r;
838 while ( ( r = static_cast<AliAnalysisMuMuResult*>(nextSubresult()) ) )
840 if ( !IsIncluded(r->Alias()) )
842 std::cout << " [EXCLUDED]";
844 r->Print(sopt.Data());
849 //_____________________________________________________________________________
850 void AliAnalysisMuMuResult::PrintValue(const char* key, const char* opt,
851 Double_t value, Double_t errorStat, Double_t rms) const
853 // print one value and its associated error
855 if ( TString(key).Contains("AccEff") )
857 std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f %% (%5.2f %%)",key,value*100,errorStat*100,
858 value != 0.0 ? errorStat*100.0/value : 0.0 );
862 std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
865 std::cout << std::endl;
867 else if ( TString(key).BeginsWith("Sigma") || TString(key).BeginsWith("Mean") )
869 std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f (%5.2f %%) MeV/c^2",key,value*1E3,1E3*errorStat,
870 value != 0.0 ? errorStat*100.0/value : 0.0);
874 std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
877 std::cout << std::endl;
879 else if ( TString(key).Contains("Nof") || ( TString(key).Contains("Fnorm") && !TString(key).Contains("persion") ) )
881 std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f (%5.2f %%)",key,value,errorStat,
882 value != 0.0 ? errorStat*100.0/value : 0.0);
886 std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
888 std::cout << std::endl;
890 else if ( value > 1E-3 && value < 1E3 )
892 std::cout << opt << Form("\t\t%20s %9.2f +- %5.2f (%5.2f %%)",key,value,errorStat,
893 value != 0.0 ? errorStat*100.0/value : 0.0);
896 std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
898 std::cout << std::endl;
902 std::cout << opt << Form("\t\t%20s %9.2e +- %9.2e (%5.2f %%)",key,value,errorStat,
903 value != 0.0 ? errorStat*100.0/value : 0.0);
906 std::cout << Form(" RMS %9.2e (%5.2f %%)",rms,100.0*rms/value);
908 std::cout << std::endl;
912 //_____________________________________________________________________________
913 void AliAnalysisMuMuResult::Scale(Double_t w)
915 /// Scale all our internal values by value
920 while ( ( key = static_cast<TObjString*>(next())) )
922 Double_t value = GetValue(key->String());
923 Double_t error = GetErrorStat(key->String());
924 Double_t rms = GetRMS(key->String());
926 Set(key->String(),value*w,error*w,rms*w);
931 //_____________________________________________________________________________
932 void AliAnalysisMuMuResult::Set(const char* name, Double_t value, Double_t errorStat, Double_t rms)
934 /// Set a (value,error) pair with a given name
939 fMap->SetOwnerKeyValue(kTRUE,kTRUE);
942 TObjArray* p = static_cast<TObjArray*>(fMap->GetValue(name));
945 p = new TObjArray(4);
949 p->AddAt(new TParameter<Double_t>(name,value),kValue);
950 p->AddAt(new TParameter<Double_t>(name,errorStat),kErrorStat);
951 p->AddAt(new TParameter<Double_t>(name,rms),kRMS);
953 fMap->Add(new TObjString(name),p);
957 static_cast<TParameter<double>*>(p->At(kValue))->SetVal(value);
958 static_cast<TParameter<double>*>(p->At(kErrorStat))->SetVal(errorStat);
959 static_cast<TParameter<double>*>(p->At(kRMS))->SetVal(rms);
963 //_____________________________________________________________________________
964 AliAnalysisMuMuResult*
965 AliAnalysisMuMuResult::SubResult(const char* subResultName) const
967 /// get a given subresult
972 TIter next(fSubResults);
973 AliAnalysisMuMuResult* r;
974 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next())) )
976 if ( r->Alias() == subResultName )
984 //_____________________________________________________________________________
985 TList* AliAnalysisMuMuResult::SubResultsToBeIncluded() const
987 if (!fSubResultsToBeIncluded)
989 fSubResultsToBeIncluded = new TList;
990 fSubResultsToBeIncluded->SetOwner(kTRUE);
992 return fSubResultsToBeIncluded;