]>
Commit | Line | Data |
---|---|---|
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 | ||
37 | ClassImp(AliTHn) | |
38 | ||
39 | AliTHn::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 | ||
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), | |
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 | ||
69 | void 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 | ||
83 | AliTHn::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 | ||
106 | AliTHn::~AliTHn() | |
107 | { | |
108 | // Destructor | |
109 | ||
110 | DeleteContainers(); | |
111 | ||
03631860 | 112 | delete[] fValues; |
113 | delete[] fSumw2; | |
114 | delete[] axisCache; | |
85bfac17 | 115 | |
85bfac17 | 116 | } |
117 | ||
118 | void 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 | //____________________________________________________________________ | |
139 | AliTHn &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 | //____________________________________________________________________ | |
178 | void 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 | //____________________________________________________________________ | |
207 | Long64_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 | ||
258 | void 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 | ||
313 | Long64_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 | 329 | void 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 | ||
394 | void 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 | ||
401 | void 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 | } |