]>
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), | |
45 | fSumw2(0) | |
46 | { | |
47 | // Constructor | |
48 | } | |
49 | ||
50 | AliTHn::AliTHn(const Char_t* name, const Char_t* title,const Int_t nSelStep, const Int_t nVarIn, const Int_t* nBinIn) : | |
51 | AliCFContainer(name, title, nSelStep, nVarIn, nBinIn), | |
52 | fNBins(0), | |
53 | fNVars(nVarIn), | |
54 | fNSteps(nSelStep), | |
55 | fValues(0), | |
56 | fSumw2(0) | |
57 | { | |
58 | // Constructor | |
59 | ||
60 | fNBins = 1; | |
61 | for (Int_t i=0; i<fNVars; i++) | |
62 | fNBins *= nBinIn[i]; | |
63 | ||
64 | Init(); | |
65 | } | |
66 | ||
67 | void AliTHn::Init() | |
68 | { | |
69 | // initialize | |
70 | ||
71 | fValues = new TArrayF*[fNSteps]; | |
72 | fSumw2 = new TArrayF*[fNSteps]; | |
73 | ||
74 | for (Int_t i=0; i<fNSteps; i++) | |
75 | { | |
76 | fValues[i] = 0; | |
77 | fSumw2[i] = 0; | |
78 | } | |
79 | } | |
80 | ||
81 | AliTHn::AliTHn(const AliTHn &c) : | |
82 | AliCFContainer(), | |
83 | fNBins(0), | |
84 | fNVars(0), | |
85 | fNSteps(0), | |
86 | fValues(0), | |
87 | fSumw2(0) | |
88 | { | |
89 | // | |
90 | // AliTHn copy constructor | |
91 | // | |
92 | ||
93 | ((AliTHn &) c).Copy(*this); | |
94 | } | |
95 | ||
96 | AliTHn::~AliTHn() | |
97 | { | |
98 | // Destructor | |
99 | ||
100 | DeleteContainers(); | |
101 | ||
102 | if (fValues) | |
103 | { | |
104 | delete fValues; | |
105 | fValues = 0; | |
106 | } | |
107 | ||
108 | if (fSumw2) | |
109 | { | |
110 | delete fSumw2; | |
111 | fSumw2 = 0; | |
112 | } | |
113 | } | |
114 | ||
115 | void AliTHn::DeleteContainers() | |
116 | { | |
117 | // delete data containers | |
118 | ||
119 | for (Int_t i=0; i<fNSteps; i++) | |
120 | { | |
121 | if (fValues && fValues[i]) | |
122 | { | |
123 | delete fValues[i]; | |
124 | fValues[i] = 0; | |
125 | } | |
126 | ||
127 | if (fSumw2 && fSumw2[i]) | |
128 | { | |
129 | delete fSumw2[i]; | |
130 | fSumw2[i] = 0; | |
131 | } | |
132 | } | |
133 | } | |
134 | ||
135 | //____________________________________________________________________ | |
136 | AliTHn &AliTHn::operator=(const AliTHn &c) | |
137 | { | |
138 | // assigment operator | |
139 | ||
140 | if (this != &c) | |
141 | ((AliTHn &) c).Copy(*this); | |
142 | ||
143 | return *this; | |
144 | } | |
145 | ||
146 | //____________________________________________________________________ | |
147 | void AliTHn::Copy(TObject& c) const | |
148 | { | |
149 | // copy function | |
150 | ||
151 | AliTHn& target = (AliTHn &) c; | |
152 | ||
153 | AliCFContainer::Copy(target); | |
154 | ||
155 | target.fNSteps = fNSteps; | |
156 | target.fNBins = fNBins; | |
157 | target.fNVars = fNVars; | |
158 | ||
159 | target.Init(); | |
160 | ||
161 | for (Int_t i=0; i<fNSteps; i++) | |
162 | { | |
163 | if (fValues[i]) | |
164 | target.fValues[i] = new TArrayF(*(fValues[i])); | |
165 | else | |
166 | target.fValues[i] = 0; | |
167 | ||
168 | if (fSumw2[i]) | |
169 | target.fSumw2[i] = new TArrayF(*(fSumw2[i])); | |
170 | else | |
171 | target.fSumw2[i] = 0; | |
172 | } | |
173 | } | |
174 | ||
175 | //____________________________________________________________________ | |
176 | Long64_t AliTHn::Merge(TCollection* list) | |
177 | { | |
178 | // Merge a list of AliTHn objects with this (needed for | |
179 | // PROOF). | |
180 | // Returns the number of merged objects (including this). | |
181 | ||
182 | if (!list) | |
183 | return 0; | |
184 | ||
185 | if (list->IsEmpty()) | |
186 | return 1; | |
187 | ||
188 | AliCFContainer::Merge(list); | |
189 | ||
190 | TIterator* iter = list->MakeIterator(); | |
191 | TObject* obj; | |
192 | ||
193 | Int_t count = 0; | |
194 | while ((obj = iter->Next())) { | |
195 | ||
196 | AliTHn* entry = dynamic_cast<AliTHn*> (obj); | |
197 | if (entry == 0) | |
198 | continue; | |
199 | ||
200 | for (Int_t i=0; i<fNSteps; i++) | |
201 | { | |
202 | if (entry->fValues[i]) | |
203 | { | |
204 | if (!fValues[i]) | |
205 | fValues[i] = new TArrayF(fNBins); | |
206 | ||
207 | for (Long64_t l = 0; l<fNBins; l++) | |
208 | fValues[i]->GetArray()[l] += entry->fValues[i]->GetArray()[l]; | |
209 | } | |
210 | ||
211 | if (entry->fSumw2[i]) | |
212 | { | |
213 | if (!fSumw2[i]) | |
214 | fSumw2[i] = new TArrayF(fNBins); | |
215 | ||
216 | for (Long64_t l = 0; l<fNBins; l++) | |
217 | fSumw2[i]->GetArray()[l] += entry->fSumw2[i]->GetArray()[l]; | |
218 | } | |
219 | } | |
220 | ||
221 | count++; | |
222 | } | |
223 | ||
224 | return count+1; | |
225 | } | |
226 | ||
227 | void AliTHn::Fill(const Double_t *var, Int_t istep, Double_t weight) | |
228 | { | |
229 | // fills an entry | |
230 | ||
231 | // calculate global bin index | |
232 | Long64_t bin = 0; | |
233 | for (Int_t i=0; i<fNVars; i++) | |
234 | { | |
235 | bin *= GetAxis(i, 0)->GetNbins(); | |
236 | ||
237 | Int_t tmpBin = GetAxis(i, 0)->FindBin(var[i]); | |
238 | // Printf("%d", tmpBin); | |
239 | // under/overflow not supported | |
240 | if (tmpBin < 1 || tmpBin > GetAxis(i, 0)->GetNbins()) | |
241 | return; | |
242 | ||
243 | // bins start from 0 here | |
244 | bin += tmpBin - 1; | |
245 | // Printf("%lld", bin); | |
246 | } | |
247 | ||
248 | if (!fValues[istep]) | |
249 | { | |
250 | fValues[istep] = new TArrayF(fNBins); | |
251 | AliInfo(Form("Created values container for step %d", istep)); | |
252 | } | |
253 | ||
254 | if (weight != 1) | |
255 | { | |
256 | // initialize with already filled entries (which have been filled with weight == 1), in this case fSumw2 := fValues | |
257 | if (!fSumw2[istep]) | |
258 | { | |
259 | fSumw2[istep] = new TArrayF(*fValues[istep]); | |
260 | AliInfo(Form("Created sumw2 container for step %d", istep)); | |
261 | } | |
262 | } | |
263 | ||
264 | fValues[istep]->GetArray()[bin] += weight; | |
265 | if (fSumw2[istep]) | |
266 | fSumw2[istep]->GetArray()[bin] += weight * weight; | |
267 | ||
268 | // Printf("%f", fValues[istep][bin]); | |
269 | ||
270 | // debug | |
271 | // AliCFContainer::Fill(var, istep, weight); | |
272 | } | |
273 | ||
274 | Long64_t AliTHn::GetGlobalBinIndex(const Int_t* binIdx) | |
275 | { | |
276 | // calculates global bin index | |
277 | // binIdx contains TAxis bin indexes | |
278 | // here bin count starts at 0 because we do not have over/underflow bins | |
279 | ||
280 | Long64_t bin = 0; | |
281 | for (Int_t i=0; i<fNVars; i++) | |
282 | { | |
283 | bin *= GetAxis(i, 0)->GetNbins(); | |
284 | bin += binIdx[i] - 1; | |
285 | } | |
286 | ||
287 | return bin; | |
288 | } | |
289 | ||
290 | void AliTHn::FillParent() | |
291 | { | |
292 | // fills the information stored in the buffer in this class into the baseclass containers | |
293 | ||
294 | for (Int_t i=0; i<fNSteps; i++) | |
295 | { | |
296 | if (!fValues[i]) | |
297 | continue; | |
298 | ||
299 | Float_t* source = fValues[i]->GetArray(); | |
300 | // if fSumw2 is not stored, the sqrt of the number of bin entries in source is filled below; otherwise we use fSumw2 | |
301 | Float_t* sourceSumw2 = source; | |
302 | if (fSumw2[i]) | |
303 | sourceSumw2 = fSumw2[i]->GetArray(); | |
304 | ||
305 | THnSparse* target = GetGrid(i)->GetGrid(); | |
306 | ||
307 | Int_t* binIdx = new Int_t[fNVars]; | |
308 | for (Int_t j=0; j<fNVars; j++) | |
309 | binIdx[j] = 1; | |
310 | ||
311 | Long64_t count = 0; | |
312 | ||
313 | while (1) | |
314 | { | |
315 | // for (Int_t j=0; j<fNVars; j++) | |
316 | // printf("%d ", binIdx[j]); | |
317 | ||
318 | Long64_t globalBin = GetGlobalBinIndex(binIdx); | |
319 | // Printf(" --> %lld", globalBin); | |
320 | ||
321 | if (source[globalBin] != 0) | |
322 | { | |
323 | target->SetBinContent(binIdx, source[globalBin]); | |
324 | target->SetBinError(binIdx, TMath::Sqrt(sourceSumw2[globalBin])); | |
325 | ||
326 | count++; | |
327 | } | |
328 | ||
329 | binIdx[fNVars-1]++; | |
330 | ||
331 | for (Int_t j=fNVars-1; j>0; j--) | |
332 | { | |
333 | if (binIdx[j] > target->GetAxis(j)->GetNbins()) | |
334 | { | |
335 | binIdx[j] = 1; | |
336 | binIdx[j-1]++; | |
337 | } | |
338 | } | |
339 | ||
340 | if (binIdx[0] > target->GetAxis(0)->GetNbins()) | |
341 | break; | |
342 | } | |
343 | ||
344 | AliInfo(Form("Step %d: copied %lld entries out of %lld bins", i, count, GetGlobalBinIndex(binIdx))); | |
345 | } | |
346 | } |