1 /*************************************************************************
2 * Copyright(c) 1998-2008, 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 #include "AliFlowMSPHistograms.h"
19 #include <TObjString.h>
22 AliFlowMSPHistograms::AliFlowMSPHistograms()
23 : TNamed(),fVarNames(),fPAvg(),fPProd(),fXName()
25 // Default constructor for root IO
26 //std::cerr << "Default constructor called" << std::endl;
29 AliFlowMSPHistograms::AliFlowMSPHistograms(const AliFlowMSPHistograms &x)
30 : TNamed(),fVarNames(),fPAvg(x.fPAvg),fPProd(x.fPProd),fXName(x.fXName)
32 // Copy constructor, clone all the TProfiles from the other object
33 // The copy constructor made a shallow copy, i.e. all entries point to the originial profiles.
34 // Therefore we need to Clone each entry.
35 for( int i=0; i<fVarNames.GetEntries(); ++i ) {
36 TObjString *org=(TObjString *)(fVarNames[i]);
37 fVarNames[i]=new TObjString(*org);
39 fVarNames.SetOwner(kTRUE);
41 for( int i=0; i<fPAvg.GetEntries(); ++i ) {
42 TProfile *org=(TProfile *)(fPAvg[i]);
43 fPAvg[i]=org->Clone();
45 fPAvg.SetOwner(kTRUE);
47 for( int i=0; i<fPProd.GetEntries(); ++i ) {
48 TProfile *org=(TProfile *)(fPProd[i]);
49 fPProd[i]=org->Clone();
51 fPProd.SetOwner(kTRUE);
54 AliFlowMSPHistograms::AliFlowMSPHistograms(const int dim, const char *name, const int nBins, const double xmin, const double xmax)
55 : TNamed(name,"MSP histograms"),fVarNames(),fPAvg(),fPProd(),fXName()
57 Init(dim, name, nBins, xmin, xmax);
60 AliFlowMSPHistograms::AliFlowMSPHistograms(const int dim, const char *name, const int nBins, const double *xBins)
61 : TNamed(name,"MSP histograms"),fVarNames(),fPAvg(),fPProd(),fXName()
63 Init(dim, name, nBins, xBins);
66 AliFlowMSPHistograms::~AliFlowMSPHistograms()
68 // Destructor. All histograms are owned by this object and will be deleted here.
73 void AliFlowMSPHistograms::Init(const int dim, const char *name, const int nBins, const double *xBins)
75 // Initialize all profiles after deleting the existing profiles
76 // Variable binning is used for the xaxis
78 fVarNames.SetOwner(kTRUE);
79 fPAvg.SetOwner(kTRUE);
80 fPProd.SetOwner(kTRUE);
85 fXName=""; // Name of x-axis
89 for(int i=0; i<dim; ++i) {
94 fVarNames.AddAtAndExpand(new TObjString(vname),i);
97 for(int i=0; i<dim; ++i) {
98 profileName=name; profileName+=i;
99 fPAvg[i] = new TProfile(profileName.Data(), "", nBins, xBins, "s");
100 Avg(i)->SetXTitle(name);
101 Avg(i)->SetDirectory(0);
105 for(int i=0; i<dim; ++i) for(int j=0; j<=i; ++j) {
106 profileName=name; profileName+=i; profileName+=j;
107 fPProd[Idx(i,j)]=new TProfile(profileName.Data(), "", nBins, xBins, "s");
108 Prod(i,j)->SetXTitle(name);
109 Prod(i,j)->SetDirectory(0);
116 void AliFlowMSPHistograms::Init(const int dim, const char *name, const int nBins, const double xmin, const double xmax)
118 // Initialize all profiles after deleting the existing profiles
119 // Fixed size binning is used
121 fVarNames.SetOwner(kTRUE);
122 fPAvg.SetOwner(kTRUE);
123 fPProd.SetOwner(kTRUE);
128 fXName=""; // Name of x-axis
132 for(int i=0; i<dim; ++i) {
137 fVarNames.AddAtAndExpand(new TObjString(vname),i);
140 for(int i=0; i<dim; ++i) {
141 profileName=name; profileName+=i;
142 fPAvg[i] = new TProfile(profileName.Data(), "", nBins, xmin, xmax, "s");
143 Avg(i)->SetXTitle(name);
144 Avg(i)->SetDirectory(0);
148 for(int i=0; i<dim; ++i) for(int j=0; j<=i; ++j) {
149 profileName=name; profileName+=i; profileName+=j;
150 fPProd[Idx(i,j)]=new TProfile(profileName.Data(), "", nBins, xmin, xmax, "s");
151 Prod(i,j)->SetXTitle(name);
152 Prod(i,j)->SetDirectory(0);
159 void AliFlowMSPHistograms::SetVarName(const char *name, const int i)
161 if( i<0 || i>NVars() ) return;
163 TObjString *old=(TObjString *)(fVarNames.At(i));
166 fVarNames.RemoveAt(i);
168 fVarNames.AddAtAndExpand(new TObjString(name),i);
172 void AliFlowMSPHistograms::SetVarName(const TString name, const int i)
174 if( i<0 || i>=NVars() ) return;
176 TObjString *old=(TObjString *)fVarNames.At(i);
179 fVarNames.RemoveAt(i);
181 fVarNames.AddAtAndExpand(new TObjString(name),i);
185 const char * AliFlowMSPHistograms::VarName(const int i) const
187 if( i<0 || i>=NVars() ) return 0;
188 return ((TObjString *)fVarNames.At(i))->String().Data();
191 void AliFlowMSPHistograms::Fill(const double x, const double *par, const double *wpar)
193 // Fill all profiles in the bin corresponding to x with the averages needed for the covariance matrix
195 for(int i=0; i<dim; ++i) {
196 Avg(i)->Fill(x,par[i],wpar[i]);
197 for(int j=0; j<=i; ++j) {
198 Prod(i,j)->Fill(x,par[i]*par[j],wpar[i]*wpar[j]);
203 double AliFlowMSPHistograms::Average(const int bin, const int i)const
205 if( bin<=0 ) { // Average over all Xbins
207 Avg(i)->GetStats(stats);
208 double w=stats[0]; // sum of weights
209 double y=stats[4]; // sum of w*y
212 return Avg(i)->GetBinContent(bin);
215 double AliFlowMSPHistograms::Covariance(const int bin, const int i, const int j)const
217 double x,wx,y,wy,xy,wxy;
219 if( bin<=0 ) { // Special case: sum over all bins
221 Avg(i)->GetStats(stats);
222 wx=stats[0]; // sum of weights from TProfile
223 x=(wx>0?stats[4]/wx:0); // weighted mean from TProfile
225 Avg(j)->GetStats(stats);
227 y=(wy>0?stats[4]/wy:0);
229 Prod(i,j)->GetStats(stats);
231 xy=(wxy>0?stats[4]/wxy:0);
233 x=Avg(i)->GetBinContent(bin); // weighted average per bin from TProfile
234 wx=Avg(i)->GetBinEntries(bin); // sum of weights per bin from TProfile
235 y=Avg(j)->GetBinContent(bin);
236 wy=Avg(j)->GetBinEntries(bin);
237 xy=Prod(i,j)->GetBinContent(bin);
238 wxy=Prod(i,j)->GetBinEntries(bin);
240 return Covariance(x, y, xy, wx, wy, wxy);
243 Long64_t AliFlowMSPHistograms::Merge(TCollection *c)
245 // Merge all MSPHistograms in the collection with this
246 // The operator+= is used for this
247 // No compatibility checks are done here, only the number of variables has to be compattible
248 // The profiles are added, assuming the TProfile::Add function does more checks
250 if( c->IsEmpty() ) return 0;
252 // Loop over given collection of AliFlowMSPHistograms
253 AliFlowMSPHistograms *toMerge=0;
256 while ( (toMerge=dynamic_cast<AliFlowMSPHistograms *>(next())) ) {
263 AliFlowMSPHistograms &AliFlowMSPHistograms::operator+=(const AliFlowMSPHistograms &x)
265 // Merge this with another AliFlowMSPHistograms object.
266 // The variable names are neither checked nor changed, only the number of variables is checked
267 // The profiles are added using the TProfile::Add() function
270 if( x.NVars() != nvars ) {
271 std::cout << "Trying to merge incompattible MSPHistograms. NVars: " << x.NVars() << "!=" << nvars << std::endl;
275 for(int i=0; i<nvars; ++i) { // Loop over averages histograms
276 Avg(i)->Add(x.Avg(i));
277 for(int j=0; j<=i; ++j) { // Loop over products histograms
278 Prod(i,j)->Add(x.Prod(i,j));
284 AliFlowMSPHistograms &AliFlowMSPHistograms::operator=(const AliFlowMSPHistograms &x)
286 // Assignment, clone all the TProfiles from the other object
287 // We need to Clone each entry and delete existing ones.
288 for( int i=0; i<fVarNames.GetEntries(); ++i ) {
289 TObjString *org=(TObjString *)(x.fVarNames[i]);
291 fVarNames[i]=new TObjString(*org);
293 fVarNames.SetOwner(kTRUE);
295 for( int i=0; i<fPAvg.GetEntries(); ++i ) {
296 TProfile *org=(TProfile *)(x.fPAvg[i]);
298 fPAvg[i]=org->Clone();
300 fPAvg.SetOwner(kTRUE);
302 for( int i=0; i<fPProd.GetEntries(); ++i ) {
303 TProfile *org=(TProfile *)(x.fPProd[i]);
305 fPProd[i]=org->Clone();
307 fPProd.SetOwner(kTRUE);
311 TObject *AliFlowMSPHistograms::Clone(const char *n) const
313 AliFlowMSPHistograms *x=new AliFlowMSPHistograms(*this);
318 // Private functions...................................................................................
320 double AliFlowMSPHistograms::Covariance(double x, double y, double xy, double wx, double wy, double wxy)const
322 // Calculate the estimated covariance between two variables
323 // inputs are the measured averages of x, y and xy and the corresponding sums of weights
324 // These are taken from TProfile::GetBinContent(ibin) and TProfile::GetBinEntries(ibin)
325 // See also equations C12-C16 in Ante's thesis
327 double enumerator=(xy-x*y)*wxy;
328 double denominator= wx*wy-wxy;
330 if(TMath::Abs(enumerator)<=1e-50*TMath::Abs(denominator) ) { // TODO Get smallest Double_t from root ??
333 if( TMath::Abs(denominator)<=1e-50*TMath::Abs(enumerator) ) { // protect against infinity
336 double result=enumerator/denominator;
340 void AliFlowMSPHistograms::UpdateTitles(int k)
342 // Update the titles of all (k<0) or the profiles for variable k using the variable and parameter names
343 // Parameter and x variable names should be set before this function is called
347 for(int i=0; i<dim; ++i) {
349 Avg(i)->SetXTitle(XName());
350 TString profileTitle="<"; profileTitle+=VarName(i); profileTitle+=">";
351 Avg(i)->SetYTitle(profileTitle.Data());
352 profileTitle+=" vs "; profileTitle+=XName();
353 Avg(i)->SetTitle(profileTitle.Data());
357 for(int i=0; i<dim; ++i) for(int j=0; j<=i; ++j) {
358 if( i==k || j==k || k<0 ) {
359 Prod(i,j)->SetXTitle(XName());
360 TString profileTitle="<"; profileTitle+=VarName(i); profileTitle+="*"; profileTitle+=VarName(j); profileTitle+=">";
361 Prod(i,j)->SetYTitle(profileTitle.Data());
362 profileTitle+=" vs "; profileTitle+=XName();
363 Prod(i,j)->SetTitle(profileTitle.Data());