]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG/Tools/AliTHn.cxx
reduce memory usage
[u/mrichter/AliRoot.git] / PWG / Tools / AliTHn.cxx
CommitLineData
85bfac17 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/* $Id: AliTHn.cxx 20164 2007-08-14 15:31:50Z morsch $ */
17
18//
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)
24//
25// the derivation from THnSparse is obviously against many OO rules. correct would be a common baseclass of THnSparse and THn.
26//
27// Author: Jan Fiete Grosse-Oetringhaus
28
29#include "AliTHn.h"
30#include "TList.h"
31#include "TCollection.h"
32#include "AliLog.h"
33#include "TArrayF.h"
34#include "THnSparse.h"
35#include "TMath.h"
36
37ClassImp(AliTHn)
38
39AliTHn::AliTHn() :
40 AliCFContainer(),
41 fNBins(0),
42 fNVars(0),
43 fNSteps(0),
44 fValues(0),
eed401dc 45 fSumw2(0),
46 axisCache(0)
85bfac17 47{
48 // Constructor
49}
50
51AliTHn::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),
53 fNBins(0),
54 fNVars(nVarIn),
55 fNSteps(nSelStep),
56 fValues(0),
eed401dc 57 fSumw2(0),
58 axisCache(0)
85bfac17 59{
60 // Constructor
61
62 fNBins = 1;
63 for (Int_t i=0; i<fNVars; i++)
64 fNBins *= nBinIn[i];
65
66 Init();
67}
68
69void AliTHn::Init()
70{
71 // initialize
72
73 fValues = new TArrayF*[fNSteps];
74 fSumw2 = new TArrayF*[fNSteps];
75
76 for (Int_t i=0; i<fNSteps; i++)
77 {
78 fValues[i] = 0;
79 fSumw2[i] = 0;
80 }
81}
82
83AliTHn::AliTHn(const AliTHn &c) :
03631860 84 AliCFContainer(c),
85 fNBins(c.fNBins),
86 fNVars(c.fNVars),
87 fNSteps(c.fNSteps),
88 fValues(new TArrayF*[c.fNSteps]),
89 fSumw2(new TArrayF*[c.fNSteps]),
eed401dc 90 axisCache(0)
85bfac17 91{
92 //
93 // AliTHn copy constructor
94 //
95
03631860 96 memset(fValues,0,fNSteps*sizeof(TArrayF*));
97 memset(fSumw2,0,fNSteps*sizeof(TArrayF*));
98
99 for (Int_t i=0; i<fNSteps; i++) {
100 if (c.fValues[i]) fValues[i] = new TArrayF(*(c.fValues[i]));
101 if (c.fSumw2[i]) fSumw2[i] = new TArrayF(*(c.fSumw2[i]));
102 }
103
85bfac17 104}
105
106AliTHn::~AliTHn()
107{
108 // Destructor
109
110 DeleteContainers();
111
03631860 112 delete[] fValues;
113 delete[] fSumw2;
114 delete[] axisCache;
85bfac17 115
85bfac17 116}
117
118void AliTHn::DeleteContainers()
119{
120 // delete data containers
121
122 for (Int_t i=0; i<fNSteps; i++)
123 {
124 if (fValues && fValues[i])
125 {
126 delete fValues[i];
127 fValues[i] = 0;
128 }
129
130 if (fSumw2 && fSumw2[i])
131 {
132 delete fSumw2[i];
133 fSumw2[i] = 0;
134 }
135 }
136}
137
138//____________________________________________________________________
139AliTHn &AliTHn::operator=(const AliTHn &c)
140{
141 // assigment operator
142
03631860 143 if (this != &c) {
144 AliCFContainer::operator=(c);
145 fNBins=c.fNBins;
146 fNVars=c.fNVars;
03631860 147 if(fNSteps) {
148 for(Int_t i=0; i< fNSteps; ++i) {
149 delete fValues[i];
150 delete fSumw2[i];
151 }
152 delete [] fValues;
153 delete [] fSumw2;
3e1096ac 154 }
155 fNSteps=c.fNSteps;
156 if(fNSteps) {
03631860 157 fValues=new TArrayF*[fNSteps];
158 fSumw2=new TArrayF*[fNSteps];
159 memset(fValues,0,fNSteps*sizeof(TArrayF*));
160 memset(fSumw2,0,fNSteps*sizeof(TArrayF*));
161
162 for (Int_t i=0; i<fNSteps; i++) {
163 if (c.fValues[i]) fValues[i] = new TArrayF(*(c.fValues[i]));
164 if (c.fSumw2[i]) fSumw2[i] = new TArrayF(*(c.fSumw2[i]));
165 }
3e1096ac 166 } else {
167 fValues = 0;
168 fSumw2 = 0;
03631860 169 }
170 delete [] axisCache;
32aa0326 171 axisCache = new TAxis*[fNVars];
25a9e954 172 memcpy(axisCache, c.axisCache, fNVars*sizeof(TAxis*));
03631860 173 }
85bfac17 174 return *this;
175}
176
177//____________________________________________________________________
178void AliTHn::Copy(TObject& c) const
179{
180 // copy function
181
182 AliTHn& target = (AliTHn &) c;
183
184 AliCFContainer::Copy(target);
185
186 target.fNSteps = fNSteps;
187 target.fNBins = fNBins;
188 target.fNVars = fNVars;
189
190 target.Init();
191
192 for (Int_t i=0; i<fNSteps; i++)
193 {
194 if (fValues[i])
195 target.fValues[i] = new TArrayF(*(fValues[i]));
196 else
197 target.fValues[i] = 0;
198
199 if (fSumw2[i])
200 target.fSumw2[i] = new TArrayF(*(fSumw2[i]));
201 else
202 target.fSumw2[i] = 0;
203 }
204}
205
206//____________________________________________________________________
207Long64_t AliTHn::Merge(TCollection* list)
208{
209 // Merge a list of AliTHn objects with this (needed for
210 // PROOF).
211 // Returns the number of merged objects (including this).
212
213 if (!list)
214 return 0;
215
216 if (list->IsEmpty())
217 return 1;
218
219 AliCFContainer::Merge(list);
220
221 TIterator* iter = list->MakeIterator();
222 TObject* obj;
223
224 Int_t count = 0;
225 while ((obj = iter->Next())) {
226
227 AliTHn* entry = dynamic_cast<AliTHn*> (obj);
228 if (entry == 0)
229 continue;
230
231 for (Int_t i=0; i<fNSteps; i++)
232 {
233 if (entry->fValues[i])
234 {
235 if (!fValues[i])
236 fValues[i] = new TArrayF(fNBins);
237
238 for (Long64_t l = 0; l<fNBins; l++)
239 fValues[i]->GetArray()[l] += entry->fValues[i]->GetArray()[l];
240 }
241
242 if (entry->fSumw2[i])
243 {
244 if (!fSumw2[i])
245 fSumw2[i] = new TArrayF(fNBins);
246
247 for (Long64_t l = 0; l<fNBins; l++)
248 fSumw2[i]->GetArray()[l] += entry->fSumw2[i]->GetArray()[l];
249 }
250 }
251
252 count++;
253 }
254
255 return count+1;
256}
257
258void AliTHn::Fill(const Double_t *var, Int_t istep, Double_t weight)
259{
260 // fills an entry
261
eed401dc 262 // fill axis cache
263 if (!axisCache)
264 {
265 axisCache = new TAxis*[fNVars];
266 for (Int_t i=0; i<fNVars; i++)
267 axisCache[i] = GetAxis(i, 0);
268 }
269
85bfac17 270 // calculate global bin index
271 Long64_t bin = 0;
272 for (Int_t i=0; i<fNVars; i++)
273 {
eed401dc 274 bin *= axisCache[i]->GetNbins();
85bfac17 275
eed401dc 276 Int_t tmpBin = axisCache[i]->FindBin(var[i]);
85bfac17 277// Printf("%d", tmpBin);
278 // under/overflow not supported
eed401dc 279 if (tmpBin < 1 || tmpBin > axisCache[i]->GetNbins())
85bfac17 280 return;
281
282 // bins start from 0 here
283 bin += tmpBin - 1;
284// Printf("%lld", bin);
285 }
286
287 if (!fValues[istep])
288 {
289 fValues[istep] = new TArrayF(fNBins);
290 AliInfo(Form("Created values container for step %d", istep));
291 }
292
293 if (weight != 1)
294 {
295 // initialize with already filled entries (which have been filled with weight == 1), in this case fSumw2 := fValues
296 if (!fSumw2[istep])
297 {
298 fSumw2[istep] = new TArrayF(*fValues[istep]);
299 AliInfo(Form("Created sumw2 container for step %d", istep));
300 }
301 }
302
303 fValues[istep]->GetArray()[bin] += weight;
304 if (fSumw2[istep])
305 fSumw2[istep]->GetArray()[bin] += weight * weight;
306
307// Printf("%f", fValues[istep][bin]);
308
309 // debug
310// AliCFContainer::Fill(var, istep, weight);
311}
312
313Long64_t AliTHn::GetGlobalBinIndex(const Int_t* binIdx)
314{
315 // calculates global bin index
316 // binIdx contains TAxis bin indexes
317 // here bin count starts at 0 because we do not have over/underflow bins
318
319 Long64_t bin = 0;
320 for (Int_t i=0; i<fNVars; i++)
321 {
322 bin *= GetAxis(i, 0)->GetNbins();
323 bin += binIdx[i] - 1;
324 }
325
326 return bin;
327}
328
1bba939a 329void AliTHn::FillContainer(AliCFContainer* cont)
85bfac17 330{
1bba939a 331 // fills the information stored in the buffer in this class into the container <cont>
85bfac17 332
333 for (Int_t i=0; i<fNSteps; i++)
334 {
335 if (!fValues[i])
336 continue;
337
338 Float_t* source = fValues[i]->GetArray();
339 // if fSumw2 is not stored, the sqrt of the number of bin entries in source is filled below; otherwise we use fSumw2
340 Float_t* sourceSumw2 = source;
341 if (fSumw2[i])
342 sourceSumw2 = fSumw2[i]->GetArray();
343
1bba939a 344 THnSparse* target = cont->GetGrid(i)->GetGrid();
85bfac17 345
346 Int_t* binIdx = new Int_t[fNVars];
c32a0ca9 347 Int_t* nBins = new Int_t[fNVars];
85bfac17 348 for (Int_t j=0; j<fNVars; j++)
c32a0ca9 349 {
85bfac17 350 binIdx[j] = 1;
c32a0ca9 351 nBins[j] = target->GetAxis(j)->GetNbins();
352 }
85bfac17 353
354 Long64_t count = 0;
355
356 while (1)
357 {
358// for (Int_t j=0; j<fNVars; j++)
359// printf("%d ", binIdx[j]);
360
361 Long64_t globalBin = GetGlobalBinIndex(binIdx);
362// Printf(" --> %lld", globalBin);
363
364 if (source[globalBin] != 0)
365 {
366 target->SetBinContent(binIdx, source[globalBin]);
367 target->SetBinError(binIdx, TMath::Sqrt(sourceSumw2[globalBin]));
368
369 count++;
370 }
371
372 binIdx[fNVars-1]++;
373
374 for (Int_t j=fNVars-1; j>0; j--)
375 {
c32a0ca9 376 if (binIdx[j] > nBins[j])
85bfac17 377 {
378 binIdx[j] = 1;
379 binIdx[j-1]++;
380 }
381 }
382
c32a0ca9 383 if (binIdx[0] > nBins[0])
85bfac17 384 break;
385 }
386
387 AliInfo(Form("Step %d: copied %lld entries out of %lld bins", i, count, GetGlobalBinIndex(binIdx)));
c32a0ca9 388
389 delete[] binIdx;
390 delete[] nBins;
1bba939a 391 }
392}
393
394void AliTHn::FillParent()
395{
396 // fills the information stored in the buffer in this class into the baseclass containers
397
398 FillContainer(this);
c32a0ca9 399}
400
401void AliTHn::ReduceAxis()
402{
403 // "removes" one axis by summing over the axis and putting the entry to bin 1
404 // TODO presently only implemented for the last axis
405
406 Int_t axis = fNVars-1;
407
408 for (Int_t i=0; i<fNSteps; i++)
409 {
410 if (!fValues[i])
411 continue;
412
413 Float_t* source = fValues[i]->GetArray();
414 Float_t* sourceSumw2 = 0;
415 if (fSumw2[i])
416 sourceSumw2 = fSumw2[i]->GetArray();
417
418 THnSparse* target = GetGrid(i)->GetGrid();
419
420 Int_t* binIdx = new Int_t[fNVars];
421 Int_t* nBins = new Int_t[fNVars];
422 for (Int_t j=0; j<fNVars; j++)
423 {
424 binIdx[j] = 1;
425 nBins[j] = target->GetAxis(j)->GetNbins();
426 }
427
428 Long64_t count = 0;
429
430 while (1)
431 {
432 // sum over axis <axis>
433 Float_t sumValues = 0;
434 Float_t sumSumw2 = 0;
435 for (Int_t j=1; j<=nBins[axis]; j++)
436 {
437 binIdx[axis] = j;
438 Long64_t globalBin = GetGlobalBinIndex(binIdx);
439 sumValues += source[globalBin];
440 source[globalBin] = 0;
441
442 if (sourceSumw2)
443 {
444 sumSumw2 += sourceSumw2[globalBin];
445 sourceSumw2[globalBin] = 0;
446 }
447 }
448 binIdx[axis] = 1;
449
450 Long64_t globalBin = GetGlobalBinIndex(binIdx);
451 source[globalBin] = sumValues;
452 if (sourceSumw2)
453 sourceSumw2[globalBin] = sumSumw2;
454
455 count++;
456
457 // next bin
458 binIdx[fNVars-2]++;
459
460 for (Int_t j=fNVars-2; j>0; j--)
461 {
462 if (binIdx[j] > nBins[j])
463 {
464 binIdx[j] = 1;
465 binIdx[j-1]++;
466 }
467 }
468
469 if (binIdx[0] > nBins[0])
470 break;
471 }
472
473 AliInfo(Form("Step %d: reduced %lld bins to %lld entries", i, GetGlobalBinIndex(binIdx), count));
474
475 delete[] binIdx;
476 delete[] nBins;
85bfac17 477 }
478}