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);
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
385 return TMath::Sqrt(variance);
388 //_____________________________________________________________________________
389 Double_t AliAnalysisMuMuResult::GetRMS(const char* name, const char* subResultName) const
391 // compute the rms of the subresults
392 // returns zero if no subresults
394 if ( strlen(subResultName) > 0 )
398 AliError(Form("No subresult from which I could get the %s one...",subResultName));
399 return TMath::Limits<Double_t>::Max();
401 AliAnalysisMuMuResult* sub = static_cast<AliAnalysisMuMuResult*>(fSubResults->FindObject(subResultName));
404 AliError(Form("Could not get subresult named %s",subResultName));
405 return TMath::Limits<Double_t>::Max();
407 return sub->GetRMS(name);
412 TObjArray* p = static_cast<TObjArray*>(fMap->GetValue(name));
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
420 TIter next(fSubResults);
421 AliAnalysisMuMuResult* r;
427 Double_t xmean = GetValue(name);
429 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
431 if ( IsIncluded(r->Alias()) && r->HasValue(name) )
433 if ( r->GetErrorStat(name) > 0 )
435 Double_t ei = r->GetErrorStat(name);
436 Double_t wi = 1.0/(ei*ei);
439 Double_t diff = r->GetValue(name) - xmean;
446 if ( n < 1 ) return 0.0;
451 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
453 if ( IsIncluded(r->Alias()) && r->HasValue(name) )
455 return r->GetRMS(name);
460 Double_t unbiased = TMath::Sqrt( (v1/(v1*v1-v2)) * sum);
462 Double_t biased = TMath::Sqrt( sum/v1 );
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));
469 //_____________________________________________________________________________
470 TString AliAnalysisMuMuResult::GetSubResultNameList() const
472 // get a comma separated list of our subresult aliases
473 TString tobeincluded;
474 TIter next(fSubResults);
475 AliAnalysisMuMuResult* r;
477 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next())) )
479 if (tobeincluded.Length()>0) tobeincluded+=",";
480 tobeincluded += r->Alias();
485 //_____________________________________________________________________________
486 Double_t AliAnalysisMuMuResult::GetValue(const char* name, const char* subResultName) const
488 // get a value (either directly or by computing the mean of the subresults)
490 if ( strlen(subResultName) > 0 )
494 AliError(Form("No subresult from which I could get the %s one...",subResultName));
495 return TMath::Limits<Double_t>::Max();
497 AliAnalysisMuMuResult* sub = static_cast<AliAnalysisMuMuResult*>(fSubResults->FindObject(subResultName));
500 AliError(Form("Could not get subresult named %s",subResultName));
501 return TMath::Limits<Double_t>::Max();
503 return sub->GetValue(name);
508 TObjArray* p = static_cast<TObjArray*>(fMap->GetValue(name));
511 TParameter<double>* val = static_cast<TParameter<double>*>(p->At(kValue));
512 return val->GetVal();
516 // compute the mean value from all subresults
517 TIter next(fSubResults);
518 AliAnalysisMuMuResult* r;
520 Double_t errorSum(0.0);
522 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
524 if ( IsIncluded(r->Alias()) && r->HasValue(name) )
526 Double_t e = r->GetErrorStat(name);
530 mean += r->GetValue(name)/e2;
535 if ( errorSum != 0.0 )
537 return mean/errorSum;
541 return TMath::Limits<Double_t>::Max();
545 //_____________________________________________________________________________
546 Bool_t AliAnalysisMuMuResult::HasValue(const char* name, const char* subResultName) const
548 /// Whether this result (or subresult if subResultName is provided) has a property
551 if ( strlen(subResultName) > 0 )
555 AliError(Form("No subresult from which I could get the %s one...",subResultName));
558 AliAnalysisMuMuResult* sub = static_cast<AliAnalysisMuMuResult*>(fSubResults->FindObject(subResultName));
561 AliError(Form("Could not get subresult named %s",subResultName));
564 return sub->HasValue(name);
567 if ( fMap && ( fMap->GetValue(name) != 0x0 ) )
572 TIter next(fSubResults);
573 AliAnalysisMuMuResult* r;
575 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
577 if ( r->HasValue(name) ) return kTRUE;
583 //_____________________________________________________________________________
584 void AliAnalysisMuMuResult::Include(const char* subResultList)
586 // (re)include some subresult names
588 TString slist(subResultList);
590 if ( slist.Length()==0 )
598 slist = GetSubResultNameList();
601 TObjArray* a = slist.Tokenize(",");
606 while ( ( s = static_cast<TObjString*>(next()) ) )
608 if (!fSubResultsToBeIncluded )
610 fSubResultsToBeIncluded = new TList;
611 fSubResultsToBeIncluded->SetOwner(kTRUE);
613 if (!IsIncluded(s->String()))
615 fSubResultsToBeIncluded->Add(s);
622 //_____________________________________________________________________________
623 Bool_t AliAnalysisMuMuResult::IsIncluded(const TString& alias) const
625 // whether that subresult alias should be included when computing means, etc...
627 if (!fSubResultsToBeIncluded) return kTRUE;
629 return ( fSubResultsToBeIncluded->FindObject(alias) != 0x0 );
632 //_____________________________________________________________________________
633 THashList* AliAnalysisMuMuResult::Keys() const
635 /// Return the complete list of keys we're using
638 fKeys = new THashList;
639 fKeys->SetOwner(kTRUE);
643 while ( ( key = static_cast<TObjString*>(next()) ) )
645 if ( !fKeys->FindObject(key->String()) )
647 fKeys->Add(new TObjString(key->String()));
651 AliAnalysisMuMuResult* r;
652 TIter nextResult(fSubResults);
654 while ( ( r = static_cast<AliAnalysisMuMuResult*>(nextResult())) )
656 TIter nextHL(r->Keys());
659 while ( ( s = static_cast<TObjString*>(nextHL())) )
661 if ( !fKeys->FindObject(s->String()) )
663 fKeys->Add(new TObjString(s->String()));
672 //_____________________________________________________________________________
673 Long64_t AliAnalysisMuMuResult::Merge(TCollection* list)
677 /// Merge a list of AliAnalysisMuMuResult objects with this
678 /// Returns the number of merged objects (including this).
680 /// Note that the merging is to be understood here as a weighed mean operation
684 if (list->IsEmpty()) return 1;
689 Double_t sumw(Weight()); // sum of weights
691 while ( ( currObj = next() ) )
693 AliAnalysisMuMuResult* result = dynamic_cast<AliAnalysisMuMuResult*>(currObj);
696 AliFatal(Form("object named \"%s\" is a %s instead of an AliAnalysisMuMuResult!", currObj->GetName(), currObj->ClassName()));
700 sumw += result->Weight();
703 TIter nextKey(Keys());
706 while ( ( key = static_cast<TObjString*>(nextKey())) )
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;
714 while ( ( currObj = next() ) )
716 AliAnalysisMuMuResult* result = dynamic_cast<AliAnalysisMuMuResult*>(currObj);
723 if (!result->HasValue(key->String()))
725 AliError(Form("Did not find key %s in of the result to merge",key->String().Data()));
729 // can only merge under the condition we have the same bin
731 Double_t w = result->Weight()/sumw;
735 value += result->GetValue(key->String())*w;
736 e2 += result->GetErrorStat(key->String())*result->GetErrorStat(key->String())*w2;
745 TIter nextSubresult(fSubResults);
746 AliAnalysisMuMuResult* r;
748 while ( ( r = static_cast<AliAnalysisMuMuResult*>(nextSubresult())) )
754 while ( ( currObj = next() ) )
756 sublist.Add(currObj);
764 return list->GetEntries()+1;
767 //_____________________________________________________________________________
768 Int_t AliAnalysisMuMuResult::NofIncludedSubResults(const char* name) const
770 // Return the number of subresults which have key name and are included
772 TIter next(fSubResults);
773 AliAnalysisMuMuResult* r;
775 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next()) ) )
777 if ( IsIncluded(r->Alias()) && r->HasValue(name) )
785 //_____________________________________________________________________________
786 void AliAnalysisMuMuResult::Print(Option_t* opt) const
793 for ( Int_t i = 0; i < 9; ++i )
795 sopt.ReplaceAll(Form("%d",i),"");
799 pot.ReplaceAll("ALL","");
800 pot.ReplaceAll("FULL","");
802 std::cout << pot.Data();
804 if ( fAlias.Length() > 0 )
806 std::cout << Form("%s - ",fAlias.Data());
809 std::cout << Form("%s %s %s",
810 GetName(),GetTitle(),fWeight > 0.0 ? Form(" WEIGHT %e",fWeight) : "");
812 if ( fSubResults && fSubResults->GetEntries()>1 )
814 std::cout << " (" << fSubResults->GetEntries() << " subresults)";
817 std::cout << std::endl;
822 while ( ( key = static_cast<TObjString*>(next())) )
824 PrintValue(key->String().Data(),pot.Data(),
825 GetValue(key->String()),
826 GetErrorStat(key->String()),
827 GetRMS(key->String()));
830 if ( fSubResults /* && fSubResults->GetEntries() > 1 */ && ( sopt.Contains("ALL") || sopt.Contains("FULL") ) )
832 std::cout << pot.Data() << "\t===== sub results ===== " << std::endl;
836 TIter nextSubresult(fSubResults);
837 AliAnalysisMuMuResult* r;
839 while ( ( r = static_cast<AliAnalysisMuMuResult*>(nextSubresult()) ) )
841 if ( !IsIncluded(r->Alias()) )
843 std::cout << " [EXCLUDED]";
845 r->Print(sopt.Data());
850 //_____________________________________________________________________________
851 void AliAnalysisMuMuResult::PrintValue(const char* key, const char* opt,
852 Double_t value, Double_t errorStat, Double_t rms) const
854 // print one value and its associated error
856 if ( TString(key).Contains("AccEff") )
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 );
863 std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
866 std::cout << std::endl;
868 else if ( TString(key).BeginsWith("Sigma") || TString(key).BeginsWith("Mean") )
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);
875 std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
878 std::cout << std::endl;
880 else if ( TString(key).Contains("Nof") || ( TString(key).Contains("Fnorm") && !TString(key).Contains("persion") ) )
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);
887 std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
889 std::cout << std::endl;
891 else if ( value > 1E-3 && value < 1E3 )
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);
897 std::cout << Form(" RMS %9.2f (%5.2f %%)",rms,100.0*rms/value);
899 std::cout << std::endl;
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);
907 std::cout << Form(" RMS %9.2e (%5.2f %%)",rms,100.0*rms/value);
909 std::cout << std::endl;
913 //_____________________________________________________________________________
914 void AliAnalysisMuMuResult::Scale(Double_t w)
916 /// Scale all our internal values by value
921 while ( ( key = static_cast<TObjString*>(next())) )
923 Double_t value = GetValue(key->String());
924 Double_t error = GetErrorStat(key->String());
925 Double_t rms = GetRMS(key->String());
927 Set(key->String(),value*w,error*w,rms*w);
932 //_____________________________________________________________________________
933 void AliAnalysisMuMuResult::Set(const char* name, Double_t value, Double_t errorStat, Double_t rms)
935 /// Set a (value,error) pair with a given name
940 fMap->SetOwnerKeyValue(kTRUE,kTRUE);
943 TObjArray* p = static_cast<TObjArray*>(fMap->GetValue(name));
946 p = new TObjArray(4);
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);
954 fMap->Add(new TObjString(name),p);
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);
964 //_____________________________________________________________________________
965 AliAnalysisMuMuResult*
966 AliAnalysisMuMuResult::SubResult(const char* subResultName) const
968 /// get a given subresult
973 TIter next(fSubResults);
974 AliAnalysisMuMuResult* r;
975 while ( ( r = static_cast<AliAnalysisMuMuResult*>(next())) )
977 if ( r->Alias() == subResultName )
985 //_____________________________________________________________________________
986 TList* AliAnalysisMuMuResult::SubResultsToBeIncluded() const
988 if (!fSubResultsToBeIncluded)
990 fSubResultsToBeIncluded = new TList;
991 fSubResultsToBeIncluded->SetOwner(kTRUE);
993 return fSubResultsToBeIncluded;