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 **************************************************************************/
16 /* $Id: AliTHn.cxx 20164 2007-08-14 15:31:50Z morsch $ */
19 // this storage container is optimized for small memory usage
20 // under/over flow bins do not exist
21 // sumw2 structure is float only and only create when the weight != 1
22 // all histogram functionality (projections, axis, ranges, etc) are taken from THnSparse by propagating
23 // the information up into the THnSparse structure (in the ananalysis *after* data processing and merging)
25 // the derivation from THnSparse is obviously against many OO rules. correct would be a common baseclass of THnSparse and THn.
27 // Author: Jan Fiete Grosse-Oetringhaus
31 #include "TCollection.h"
34 #include "THnSparse.h"
51 AliTHn::AliTHn(const Char_t* name, const Char_t* title,const Int_t nSelStep, const Int_t nVarIn, const Int_t* nBinIn) :
52 AliCFContainer(name, title, nSelStep, nVarIn, nBinIn),
63 for (Int_t i=0; i<fNVars; i++)
73 fValues = new TArrayF*[fNSteps];
74 fSumw2 = new TArrayF*[fNSteps];
76 for (Int_t i=0; i<fNSteps; i++)
83 AliTHn::AliTHn(const AliTHn &c) :
93 // AliTHn copy constructor
96 ((AliTHn &) c).Copy(*this);
124 void AliTHn::DeleteContainers()
126 // delete data containers
128 for (Int_t i=0; i<fNSteps; i++)
130 if (fValues && fValues[i])
136 if (fSumw2 && fSumw2[i])
144 //____________________________________________________________________
145 AliTHn &AliTHn::operator=(const AliTHn &c)
147 // assigment operator
150 ((AliTHn &) c).Copy(*this);
155 //____________________________________________________________________
156 void AliTHn::Copy(TObject& c) const
160 AliTHn& target = (AliTHn &) c;
162 AliCFContainer::Copy(target);
164 target.fNSteps = fNSteps;
165 target.fNBins = fNBins;
166 target.fNVars = fNVars;
170 for (Int_t i=0; i<fNSteps; i++)
173 target.fValues[i] = new TArrayF(*(fValues[i]));
175 target.fValues[i] = 0;
178 target.fSumw2[i] = new TArrayF(*(fSumw2[i]));
180 target.fSumw2[i] = 0;
184 //____________________________________________________________________
185 Long64_t AliTHn::Merge(TCollection* list)
187 // Merge a list of AliTHn objects with this (needed for
189 // Returns the number of merged objects (including this).
197 AliCFContainer::Merge(list);
199 TIterator* iter = list->MakeIterator();
203 while ((obj = iter->Next())) {
205 AliTHn* entry = dynamic_cast<AliTHn*> (obj);
209 for (Int_t i=0; i<fNSteps; i++)
211 if (entry->fValues[i])
214 fValues[i] = new TArrayF(fNBins);
216 for (Long64_t l = 0; l<fNBins; l++)
217 fValues[i]->GetArray()[l] += entry->fValues[i]->GetArray()[l];
220 if (entry->fSumw2[i])
223 fSumw2[i] = new TArrayF(fNBins);
225 for (Long64_t l = 0; l<fNBins; l++)
226 fSumw2[i]->GetArray()[l] += entry->fSumw2[i]->GetArray()[l];
236 void AliTHn::Fill(const Double_t *var, Int_t istep, Double_t weight)
243 axisCache = new TAxis*[fNVars];
244 for (Int_t i=0; i<fNVars; i++)
245 axisCache[i] = GetAxis(i, 0);
248 // calculate global bin index
250 for (Int_t i=0; i<fNVars; i++)
252 bin *= axisCache[i]->GetNbins();
254 Int_t tmpBin = axisCache[i]->FindBin(var[i]);
255 // Printf("%d", tmpBin);
256 // under/overflow not supported
257 if (tmpBin < 1 || tmpBin > axisCache[i]->GetNbins())
260 // bins start from 0 here
262 // Printf("%lld", bin);
267 fValues[istep] = new TArrayF(fNBins);
268 AliInfo(Form("Created values container for step %d", istep));
273 // initialize with already filled entries (which have been filled with weight == 1), in this case fSumw2 := fValues
276 fSumw2[istep] = new TArrayF(*fValues[istep]);
277 AliInfo(Form("Created sumw2 container for step %d", istep));
281 fValues[istep]->GetArray()[bin] += weight;
283 fSumw2[istep]->GetArray()[bin] += weight * weight;
285 // Printf("%f", fValues[istep][bin]);
288 // AliCFContainer::Fill(var, istep, weight);
291 Long64_t AliTHn::GetGlobalBinIndex(const Int_t* binIdx)
293 // calculates global bin index
294 // binIdx contains TAxis bin indexes
295 // here bin count starts at 0 because we do not have over/underflow bins
298 for (Int_t i=0; i<fNVars; i++)
300 bin *= GetAxis(i, 0)->GetNbins();
301 bin += binIdx[i] - 1;
307 void AliTHn::FillContainer(AliCFContainer* cont)
309 // fills the information stored in the buffer in this class into the container <cont>
311 for (Int_t i=0; i<fNSteps; i++)
316 Float_t* source = fValues[i]->GetArray();
317 // if fSumw2 is not stored, the sqrt of the number of bin entries in source is filled below; otherwise we use fSumw2
318 Float_t* sourceSumw2 = source;
320 sourceSumw2 = fSumw2[i]->GetArray();
322 THnSparse* target = cont->GetGrid(i)->GetGrid();
324 Int_t* binIdx = new Int_t[fNVars];
325 Int_t* nBins = new Int_t[fNVars];
326 for (Int_t j=0; j<fNVars; j++)
329 nBins[j] = target->GetAxis(j)->GetNbins();
336 // for (Int_t j=0; j<fNVars; j++)
337 // printf("%d ", binIdx[j]);
339 Long64_t globalBin = GetGlobalBinIndex(binIdx);
340 // Printf(" --> %lld", globalBin);
342 if (source[globalBin] != 0)
344 target->SetBinContent(binIdx, source[globalBin]);
345 target->SetBinError(binIdx, TMath::Sqrt(sourceSumw2[globalBin]));
352 for (Int_t j=fNVars-1; j>0; j--)
354 if (binIdx[j] > nBins[j])
361 if (binIdx[0] > nBins[0])
365 AliInfo(Form("Step %d: copied %lld entries out of %lld bins", i, count, GetGlobalBinIndex(binIdx)));
372 void AliTHn::FillParent()
374 // fills the information stored in the buffer in this class into the baseclass containers
379 void AliTHn::ReduceAxis()
381 // "removes" one axis by summing over the axis and putting the entry to bin 1
382 // TODO presently only implemented for the last axis
384 Int_t axis = fNVars-1;
386 for (Int_t i=0; i<fNSteps; i++)
391 Float_t* source = fValues[i]->GetArray();
392 Float_t* sourceSumw2 = 0;
394 sourceSumw2 = fSumw2[i]->GetArray();
396 THnSparse* target = GetGrid(i)->GetGrid();
398 Int_t* binIdx = new Int_t[fNVars];
399 Int_t* nBins = new Int_t[fNVars];
400 for (Int_t j=0; j<fNVars; j++)
403 nBins[j] = target->GetAxis(j)->GetNbins();
410 // sum over axis <axis>
411 Float_t sumValues = 0;
412 Float_t sumSumw2 = 0;
413 for (Int_t j=1; j<=nBins[axis]; j++)
416 Long64_t globalBin = GetGlobalBinIndex(binIdx);
417 sumValues += source[globalBin];
418 source[globalBin] = 0;
422 sumSumw2 += sourceSumw2[globalBin];
423 sourceSumw2[globalBin] = 0;
428 Long64_t globalBin = GetGlobalBinIndex(binIdx);
429 source[globalBin] = sumValues;
431 sourceSumw2[globalBin] = sumSumw2;
438 for (Int_t j=fNVars-2; j>0; j--)
440 if (binIdx[j] > nBins[j])
447 if (binIdx[0] > nBins[0])
451 AliInfo(Form("Step %d: reduced %lld bins to %lld entries", i, GetGlobalBinIndex(binIdx), count));