]>
Commit | Line | Data |
---|---|---|
94ef1a28 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-2007, 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 | //----------------------------------------------------------------------------- | |
17 | /// \class AliCounterCollection | |
18 | /// | |
19 | /// generic class to handle a collection of counters | |
20 | /// | |
21 | /// \author Philippe Pillot | |
22 | //----------------------------------------------------------------------------- | |
23 | ||
24 | #include "AliCounterCollection.h" | |
25 | ||
26 | #include <AliLog.h> | |
27 | ||
28 | #include <TString.h> | |
29 | #include <TObjString.h> | |
30 | #include <TObjArray.h> | |
31 | #include <THnSparse.h> | |
32 | #include <THashList.h> | |
33 | #include <TArrayI.h> | |
34 | #include <TH1D.h> | |
35 | #include <TH2D.h> | |
36 | #include <TCollection.h> | |
37 | ||
38 | ClassImp(AliCounterCollection) | |
39 | ||
40 | //----------------------------------------------------------------------- | |
41 | AliCounterCollection::AliCounterCollection(const char* name) : | |
42 | TNamed(name,name), | |
43 | fRubrics(new THashList(10)), | |
44 | fRubricsSize(new TArrayI(10)), | |
d810835e | 45 | fCounters(0x0), |
46 | fWeightedCounters(kFALSE) | |
94ef1a28 | 47 | { |
48 | /// Constructor | |
49 | fRubrics->SetOwner(); | |
50 | } | |
51 | ||
52 | //----------------------------------------------------------------------- | |
53 | AliCounterCollection::~AliCounterCollection() | |
54 | { | |
55 | /// Destructor | |
56 | delete fRubrics; | |
57 | delete fRubricsSize; | |
58 | delete fCounters; | |
59 | } | |
60 | ||
61 | //----------------------------------------------------------------------- | |
62 | void AliCounterCollection::Clear(Option_t*) | |
63 | { | |
64 | /// Clear counters | |
65 | fRubrics->Clear(); | |
66 | fRubricsSize->Reset(); | |
67 | delete fCounters; fCounters = 0x0; | |
d810835e | 68 | fWeightedCounters = kFALSE; |
94ef1a28 | 69 | } |
70 | ||
71 | //----------------------------------------------------------------------- | |
72 | void AliCounterCollection::AddRubric(TString name, TString listOfKeyWords) | |
73 | { | |
74 | /// Add a new rubric with the complete list of related key words separated by "/". | |
75 | /// If the key word "any" is not defined, the overall statistics is | |
76 | /// assumed to be the sum of the statistics under each key word. | |
77 | ||
78 | name.ToUpper(); | |
79 | listOfKeyWords.ToUpper(); | |
80 | ||
81 | if (fRubrics->Contains(name.Data())) { | |
82 | AliError(Form("rubric named %s already exist",name.Data())); | |
83 | return; | |
84 | } | |
85 | ||
86 | // add the list of autorized key words | |
87 | TObjArray* rubric = listOfKeyWords.Tokenize("/"); | |
88 | CleanListOfStrings(rubric); | |
89 | rubric->SetName(name.Data()); | |
90 | Int_t nRubrics = fRubrics->GetSize(); | |
91 | rubric->SetUniqueID(nRubrics); | |
92 | fRubrics->AddLast(rubric); | |
93 | ||
94 | // save the number of autorized key words (expand the array if needed) | |
95 | if (nRubrics+1 > fRubricsSize->GetSize()) fRubricsSize->Set(2*fRubricsSize->GetSize()); | |
96 | (*fRubricsSize)[nRubrics] = rubric->GetEntriesFast(); | |
97 | } | |
98 | ||
99 | //----------------------------------------------------------------------- | |
100 | void AliCounterCollection::AddRubric(TString name, Int_t maxNKeyWords) | |
101 | { | |
102 | /// Add a new rubric containing at maximum maxNKeyWords key words. | |
103 | /// Key words will be added as the counters get filled until the maximum is reached. | |
104 | /// If the key word "any" is never defined, the overall statistics is | |
105 | /// assumed to be the sum of the statistics under each key word. | |
106 | ||
107 | name.ToUpper(); | |
108 | ||
109 | if (fRubrics->Contains(name.Data())) { | |
110 | AliError(Form("rubric named %s already exist",name.Data())); | |
111 | return; | |
112 | } | |
113 | ||
114 | // create the empty rubric | |
115 | TObjString* rubric = new TObjString(name.Data()); | |
116 | Int_t nRubrics = fRubrics->GetSize(); | |
117 | rubric->SetUniqueID(nRubrics); | |
118 | fRubrics->AddLast(rubric); | |
119 | ||
120 | // save the maximum number of autorized key words | |
121 | if (nRubrics+1 > fRubricsSize->GetSize()) fRubricsSize->Set(2*fRubricsSize->GetSize()); | |
122 | (*fRubricsSize)[nRubrics] = maxNKeyWords; | |
123 | } | |
124 | ||
125 | //----------------------------------------------------------------------- | |
d810835e | 126 | void AliCounterCollection::Init(Bool_t weightedCounters) |
94ef1a28 | 127 | { |
128 | /// Initialize the internal counters from the added rubrics. | |
129 | ||
130 | // create the counters | |
131 | delete fCounters; | |
d810835e | 132 | fWeightedCounters = weightedCounters; |
133 | if (fWeightedCounters) | |
134 | fCounters = new THnSparseT<TArrayF>("hCounters", "hCounters", fRubrics->GetSize(), fRubricsSize->GetArray(), 0x0, 0x0); | |
135 | else | |
136 | fCounters = new THnSparseT<TArrayI>("hCounters", "hCounters", fRubrics->GetSize(), fRubricsSize->GetArray(), 0x0, 0x0); | |
94ef1a28 | 137 | |
138 | // loop over axis | |
139 | TObject* rubric = 0x0; | |
140 | TIter nextRubric(fRubrics); | |
141 | while ((rubric = nextRubric())) { | |
142 | TAxis* axis = fCounters->GetAxis((Int_t)rubric->GetUniqueID()); | |
143 | ||
144 | // set axis name | |
145 | axis->SetName(rubric->GetName()); | |
146 | ||
147 | // set labels if already known | |
148 | TObjArray* keyWords = dynamic_cast<TObjArray*>(rubric); | |
149 | if (keyWords) { | |
150 | TObjString* label = 0x0; | |
151 | Int_t bin = 1; | |
152 | TIter nextLabel(keyWords); | |
153 | while ((label = static_cast<TObjString*>(nextLabel()))) axis->SetBinLabel(bin++, label->String().Data()); | |
154 | } | |
155 | ||
156 | } | |
157 | ||
158 | } | |
159 | ||
6f5626c7 | 160 | //----------------------------------------------------------------------- |
161 | Int_t AliCounterCollection::GetNActiveBins(Int_t dim) | |
162 | { | |
163 | /// return the number of labels in that rubric. | |
164 | THashList* labels = fCounters->GetAxis(dim)->GetLabels(); | |
165 | return (labels) ? labels->GetSize() : 0; | |
166 | } | |
167 | ||
168 | //----------------------------------------------------------------------- | |
169 | Bool_t AliCounterCollection::ContainsAny(Int_t dim) | |
170 | { | |
171 | /// return kTRUE if that rubric contains the keyWord "ANY". | |
172 | THashList* labels = fCounters->GetAxis(dim)->GetLabels(); | |
173 | return (labels && labels->Contains("ANY")); | |
174 | } | |
175 | ||
94ef1a28 | 176 | //----------------------------------------------------------------------- |
177 | const Int_t* AliCounterCollection::FindBins(const TString& externalKey, Bool_t allocate, Int_t& nEmptySlots) | |
178 | { | |
179 | /// Return the corresponding bins ordered by rubric or 0x0 if externalKey is not valid. | |
180 | /// The externalKey format must be rubric:keyWord/rubric:keyWord/rubric:keyWord/... | |
181 | /// If allocate = kTRUE, new key words are added to the corresponding rubric if possible. | |
182 | /// If a rubric is not filled in, the coresponding slot contain -1 in the array. | |
183 | /// It is the responsability of the user to delete the returned array. | |
184 | ||
185 | // produce an empty array of keys | |
186 | Int_t nRubrics = fRubrics->GetSize(); | |
187 | Int_t* bins = new Int_t[nRubrics]; | |
6f5626c7 | 188 | for (Int_t i=0; i<nRubrics; i++) bins[i] = -1; |
94ef1a28 | 189 | nEmptySlots = nRubrics; |
190 | Bool_t isValid = kTRUE; | |
191 | ||
192 | // get the list of rubric:keyWord pairs | |
193 | TObjArray* rubricKeyPairs = externalKey.Tokenize("/"); | |
194 | ||
195 | // loop over each rubric:keyWord pair | |
196 | TObjString* pair = 0x0; | |
197 | TIter next(rubricKeyPairs); | |
198 | while ((pair = static_cast<TObjString*>(next()))) { | |
199 | ||
200 | // get both rubric and associated key word | |
201 | TObjArray* rubricKeyPair = pair->String().Tokenize(":"); | |
202 | ||
203 | // check the format of the pair | |
204 | if (rubricKeyPair->GetEntriesFast() != 2) { | |
205 | AliError("invalid key format"); | |
206 | isValid = kFALSE; | |
207 | delete rubricKeyPair; | |
208 | break; | |
209 | } | |
210 | ||
211 | // get the axis corresponding to that rubric | |
212 | Int_t dim = FindDim(static_cast<TObjString*>(rubricKeyPair->UncheckedAt(0))->String()); | |
213 | if (dim < 0) { | |
214 | isValid = kFALSE; | |
215 | delete rubricKeyPair; | |
216 | break; | |
217 | } | |
218 | ||
219 | // find the bin corresponding to that key word | |
220 | Int_t bin = FindBin(dim, static_cast<TObjString*>(rubricKeyPair->UncheckedAt(1))->String(), allocate); | |
221 | if (bin < 0) { | |
222 | isValid = kFALSE; | |
223 | delete rubricKeyPair; | |
224 | break; | |
225 | } | |
226 | ||
227 | // check if the array of keys already contains something for that rubric | |
228 | if (bins[dim] >= 0) { | |
229 | AliWarning("key already given for that rubric --> ignored"); | |
230 | delete rubricKeyPair; | |
231 | continue; | |
232 | } | |
233 | ||
234 | // store the corresponding bin for that slot | |
235 | bins[dim] = bin; | |
236 | nEmptySlots--; | |
237 | ||
238 | // clean memory | |
239 | delete rubricKeyPair; | |
240 | } | |
241 | ||
242 | // delete the array in case of problem | |
243 | if (!isValid) { | |
244 | delete[] bins; | |
245 | bins = 0x0; | |
246 | nEmptySlots = nRubrics; | |
247 | } | |
248 | ||
249 | // clean memory | |
250 | delete rubricKeyPairs; | |
251 | ||
252 | return bins; | |
253 | } | |
254 | ||
255 | //----------------------------------------------------------------------- | |
256 | Int_t AliCounterCollection::FindDim(const TString& rubricName) const | |
257 | { | |
258 | /// Return the dimension corresponding to that rubric (or -1 in case of failure). | |
259 | TObject* rubric = fRubrics->FindObject(rubricName.Data()); | |
260 | if (!rubric) { | |
261 | AliError(Form("invalid rubric: %s",rubricName.Data())); | |
262 | return -1; | |
263 | } | |
264 | return (Int_t) rubric->GetUniqueID(); | |
265 | } | |
266 | ||
267 | //----------------------------------------------------------------------- | |
268 | Int_t AliCounterCollection::FindBin(Int_t dim, const TString& keyWord, Bool_t allocate) | |
269 | { | |
270 | /// Return the bin number corresponding to that key word (or -1 in case of failure). | |
271 | /// If allocate = kTRUE, try to add the key word if possible. | |
272 | ||
273 | TAxis* axis = fCounters->GetAxis(dim); | |
274 | ||
275 | // look for the bin corresponding to keyWord | |
276 | THashList* labels = axis->GetLabels(); | |
277 | TObjString* label = (labels) ? static_cast<TObjString*>(labels->FindObject(keyWord.Data())) : 0x0; | |
278 | Int_t bin = (label) ? (Int_t)label->GetUniqueID() : -1; | |
279 | ||
280 | // in case the keyWord does not exist, try to add it if required | |
281 | if (bin<0 && allocate) { | |
282 | Int_t nLabels = (labels) ? labels->GetSize() : 0; | |
283 | if (nLabels < axis->GetNbins()) { | |
284 | bin = nLabels+1; | |
285 | axis->SetBinLabel(bin, keyWord.Data()); | |
286 | } | |
287 | } | |
288 | ||
289 | if (bin<0) AliError(Form("invalid key word: %s:%s",axis->GetName(),keyWord.Data())); | |
290 | ||
291 | return bin; | |
292 | } | |
293 | ||
6f5626c7 | 294 | //----------------------------------------------------------------------- |
295 | Short_t** AliCounterCollection::DecodeSelection(const TString& selections, const TObjArray& displayedRubrics) | |
296 | { | |
297 | /// Tag the selected keywords in each rubric (-1=subtract; 0=discard; 1=add). Format: | |
298 | /// "rubric:[any-]keyWord,keyWord,../rubric:[any-]keyWord,.." (order does not matter). | |
299 | /// It is the responsability of the user to delete the returned array. | |
300 | ||
301 | // produce an empty array of selected keys | |
302 | Int_t nRubrics = fCounters->GetNdimensions(); | |
303 | Short_t** selects = new Short_t*[nRubrics]; | |
304 | for (Int_t i=0; i<nRubrics; i++) selects[i] = 0x0; | |
305 | ||
306 | // get the list of rubric:LisOfKeyWord pairs | |
307 | TObjArray* rubricKeyPairs = selections.Tokenize("/"); | |
308 | ||
309 | // loop over each rubric:keyWord pair | |
310 | TObjString* pair = 0x0; | |
311 | TIter next(rubricKeyPairs); | |
312 | while ((pair = static_cast<TObjString*>(next()))) { | |
313 | ||
314 | // get both rubric and associated list of key words | |
315 | TObjArray* rubricKeyPair = pair->String().Tokenize(":"); | |
316 | ||
317 | // check the format of the pair | |
318 | if (rubricKeyPair->GetEntriesFast() != 2) { | |
319 | AliError("invalid key format"); | |
320 | delete rubricKeyPair; | |
321 | delete rubricKeyPairs; | |
322 | for (Int_t i=0; i<nRubrics; i++) if (selects[i]) delete[] selects[i]; | |
323 | delete[] selects; | |
324 | return 0x0; | |
325 | } | |
326 | ||
327 | // check wether to select or to discard the keyWords | |
328 | Int_t include = kTRUE; | |
329 | TString ListOfKeyWords(static_cast<TObjString*>(rubricKeyPair->UncheckedAt(1))->String()); | |
330 | if (ListOfKeyWords.BeginsWith("ANY-")) { | |
331 | ListOfKeyWords.Remove(0,4); | |
332 | include = kFALSE; | |
333 | } | |
334 | ||
335 | // select the key words | |
336 | const TString& rubric = static_cast<TObjString*>(rubricKeyPair->UncheckedAt(0))->String(); | |
337 | if (!Select(include, rubric, ListOfKeyWords, displayedRubrics.Contains(rubric.Data()), selects)) { | |
338 | delete rubricKeyPair; | |
339 | delete rubricKeyPairs; | |
340 | for (Int_t i=0; i<nRubrics; i++) if (selects[i]) delete[] selects[i]; | |
341 | delete[] selects; | |
342 | return 0x0; | |
343 | } | |
344 | ||
345 | // clean memory | |
346 | delete rubricKeyPair; | |
347 | } | |
348 | ||
349 | // clean memory | |
350 | delete rubricKeyPairs; | |
351 | ||
352 | // complete the selection of other rubrics | |
353 | for (Int_t i=0; i<nRubrics; i++) { | |
354 | ||
355 | // skip already processed rubrics | |
356 | if (selects[i]) continue; | |
357 | ||
358 | // create the list of bins | |
359 | Int_t nBins = GetNActiveBins(i) + 1; | |
360 | selects[i] = new Short_t[nBins]; | |
361 | ||
362 | // select all key words or only the key work "ANY" | |
363 | if (ContainsAny(i) && !displayedRubrics.Contains(fCounters->GetAxis(i)->GetName())) { | |
364 | memset(selects[i], 0, sizeof(Short_t) * nBins); | |
365 | selects[i][FindBin(i, "ANY", kFALSE)] = 1; | |
366 | } else for (Int_t j=0; j<nBins; j++) selects[i][j] = 1; | |
367 | ||
368 | } | |
369 | ||
370 | return selects; | |
371 | } | |
372 | ||
373 | //----------------------------------------------------------------------- | |
374 | Bool_t AliCounterCollection::Select(Bool_t include, const TString& rubric, const TString& keywords, | |
375 | Bool_t displayed, Short_t* selectBins[]) | |
376 | { | |
377 | /// Tag the selected keywords (separated by ',') in that rubric (-1=subtract; 0=discard; 1=add). | |
378 | ||
379 | Int_t dim = FindDim(rubric); | |
380 | if (dim < 0) return kFALSE; | |
381 | ||
382 | if (selectBins[dim]) { | |
383 | AliWarning(Form("selection already made for rubric %s --> ignored",rubric.Data())); | |
384 | return kTRUE; | |
385 | } | |
386 | ||
387 | // get list of key words to select | |
388 | TObjArray* keys = keywords.Tokenize(","); | |
389 | if (keys->GetEntriesFast() == 0) { | |
390 | AliError(Form("no key word specified for rubric %s",rubric.Data())); | |
391 | delete keys; | |
392 | return kFALSE; | |
393 | } | |
394 | ||
395 | // create the list of bins | |
396 | Int_t nBins = GetNActiveBins(dim) + 1; | |
397 | selectBins[dim] = new Short_t[nBins]; | |
398 | ||
399 | // select/unselect all bins | |
400 | Bool_t containsAny = ContainsAny(dim); | |
401 | if (include || (containsAny && !displayed)) { | |
402 | memset(selectBins[dim], 0, sizeof(Short_t) * nBins); | |
403 | if (!include) selectBins[dim][FindBin(dim, "ANY", kFALSE)] = 1; | |
404 | } else for (Int_t j=0; j<nBins; j++) selectBins[dim][j] = 1; | |
405 | ||
406 | // select/unselect specific key words | |
407 | TObjString* key = 0x0; | |
408 | TIter nextKey(keys); | |
409 | while ((key = static_cast<TObjString*>(nextKey()))) { | |
410 | ||
411 | // special case of key word "ANY" | |
412 | if (key->String() == "ANY") { | |
413 | ||
414 | if (containsAny) { | |
415 | ||
416 | Int_t binAny = FindBin(dim, "ANY", kFALSE); | |
417 | if (include) selectBins[dim][binAny] = 1; | |
418 | else selectBins[dim][binAny] = 0; | |
419 | ||
420 | } else { | |
421 | ||
422 | if (include) for (Int_t j=0; j<nBins; j++) selectBins[dim][j] = 1; | |
423 | else memset(selectBins[dim], 0, sizeof(Short_t) * nBins); | |
424 | ||
425 | } | |
426 | ||
427 | } else { // other cases | |
428 | ||
429 | // find the corresponding bin | |
430 | Int_t bin = FindBin(dim, key->String().Data(), kFALSE); | |
431 | if (bin < 0) { | |
432 | delete keys; | |
433 | return kFALSE; | |
434 | } | |
435 | ||
436 | // select/unselect it | |
437 | if (include) selectBins[dim][bin] = 1; | |
438 | else if (containsAny && !displayed) selectBins[dim][bin] = -1; | |
439 | else selectBins[dim][bin] = 0; | |
440 | ||
441 | } | |
442 | ||
443 | } | |
444 | ||
445 | // clean memory | |
446 | delete keys; | |
447 | ||
448 | return kTRUE; | |
449 | } | |
450 | ||
94ef1a28 | 451 | //----------------------------------------------------------------------- |
452 | void AliCounterCollection::CleanListOfStrings(TObjArray* list) | |
453 | { | |
454 | /// Make sure all strings appear only once in this list | |
455 | ||
456 | // remove multiple-occurrence | |
457 | Int_t nEntries = list->GetEntriesFast(); | |
458 | for (Int_t i = 0; i < nEntries; i++) { | |
459 | TObjString* entry1 = static_cast<TObjString*>(list->UncheckedAt(i)); | |
460 | if (!entry1) continue; | |
461 | for (Int_t j = i+1; j < nEntries; j++) { | |
462 | TObjString* entry2 = static_cast<TObjString*>(list->UncheckedAt(j)); | |
463 | if (entry2 && entry2->IsEqual(entry1)) { | |
464 | AliWarning(Form("multiple-occurence of string \"%s\" --> removed",entry2->String().Data())); | |
465 | list->RemoveAt(j); | |
466 | } | |
467 | } | |
468 | } | |
469 | ||
470 | // remove empty slots | |
471 | list->Compress(); | |
472 | } | |
473 | ||
474 | //----------------------------------------------------------------------- | |
475 | void AliCounterCollection::Count(TString externalKey, Int_t value) | |
d810835e | 476 | { |
477 | /// Add "value" to the counter referenced by "externalKey". | |
478 | /// The externalKey format must be rubric:keyWord/rubric:keyWord/rubric:keyWord/... | |
479 | if (value > 0) CountAsDouble(externalKey, (Double_t)value); | |
480 | else if (value < 0) AliError("cannot count negative values"); | |
481 | } | |
482 | ||
483 | //----------------------------------------------------------------------- | |
484 | void AliCounterCollection::Count(TString externalKey, Double_t value) | |
485 | { | |
486 | /// Add "value" to the counter referenced by "externalKey". | |
487 | /// The externalKey format must be rubric:keyWord/rubric:keyWord/rubric:keyWord/... | |
488 | if (fWeightedCounters) CountAsDouble(externalKey, value); | |
489 | else AliError("non-weighted counters can only be filled with intergers"); | |
490 | } | |
491 | ||
492 | //----------------------------------------------------------------------- | |
493 | void AliCounterCollection::CountAsDouble(TString externalKey, Double_t value) | |
94ef1a28 | 494 | { |
495 | /// Add "value" to the counter referenced by "externalKey". | |
496 | /// The externalKey format must be rubric:keyWord/rubric:keyWord/rubric:keyWord/... | |
497 | ||
94ef1a28 | 498 | if (!fCounters) { |
499 | AliError("counters are not initialized"); | |
500 | return; | |
501 | } | |
502 | ||
503 | externalKey.ToUpper(); | |
504 | ||
505 | // convert external to internal key | |
506 | Int_t nEmptySlots = 0; | |
507 | const Int_t* bins = FindBins(externalKey, kTRUE, nEmptySlots); | |
508 | if (!bins) return; | |
509 | ||
510 | // check for empty slots | |
511 | if (nEmptySlots > 0) { | |
512 | AliError("incomplete key"); | |
513 | delete[] bins; | |
514 | return; | |
515 | } | |
516 | ||
517 | // increment the corresponding counter | |
d810835e | 518 | fCounters->AddBinContent(bins, value); |
94ef1a28 | 519 | |
520 | // clean memory | |
521 | delete[] bins; | |
522 | } | |
523 | ||
524 | //----------------------------------------------------------------------- | |
525 | void AliCounterCollection::Print(const Option_t* opt) const | |
526 | { | |
527 | /// Print every individual counters if opt=="", else call "Print(TString rubrics=opt, TString selections="")". | |
528 | ||
529 | if (strcmp(opt,"")) { | |
530 | const_cast<AliCounterCollection*>(this)->Print(opt, ""); | |
531 | return; | |
532 | } | |
533 | ||
534 | if (!fCounters) { | |
535 | AliError("counters are not initialized"); | |
536 | return; | |
537 | } | |
538 | ||
539 | if (fCounters->GetNbins() == 0) { | |
540 | printf("\nall counters are empty\n\n"); | |
541 | return; | |
542 | } | |
543 | ||
544 | Int_t nRubrics = fCounters->GetNdimensions(); | |
545 | Int_t* bins = new Int_t[nRubrics]; | |
546 | ||
547 | // loop over every filled counters | |
548 | for (Long64_t i=0; i<fCounters->GetNbins(); ++i) { | |
549 | ||
550 | // get the content of the bin | |
d810835e | 551 | Double_t value = fCounters->GetBinContent(i, bins); |
94ef1a28 | 552 | |
553 | // build the corresponding counter name | |
554 | TString counter; | |
555 | for (Int_t j=0; j<nRubrics; j++) counter += Form("/%s",fCounters->GetAxis(j)->GetBinLabel(bins[j])); | |
556 | counter += "/"; | |
557 | ||
558 | // print value | |
d810835e | 559 | if (fWeightedCounters) printf("\n%s %g", counter.Data(), value); |
560 | else printf("\n%s %d", counter.Data(), (Int_t)value); | |
94ef1a28 | 561 | } |
562 | printf("\n\n"); | |
563 | ||
564 | // clean memory | |
565 | delete[] bins; | |
566 | } | |
567 | ||
568 | //----------------------------------------------------------------------- | |
d649ab79 | 569 | TString AliCounterCollection::GetKeyWords(TString rubric) const |
570 | { | |
571 | /// return the list of key words for the given rubric. | |
572 | ||
573 | TString keyWords = ""; | |
574 | ||
575 | if (!fCounters) { | |
576 | AliError("counters are not initialized"); | |
577 | return keyWords; | |
578 | } | |
579 | ||
580 | rubric.ToUpper(); | |
581 | ||
582 | // get the dimension corresponding to that rubric | |
583 | Int_t dim = FindDim(rubric); | |
584 | if (dim < 0) return keyWords; | |
585 | ||
586 | // build list of key words | |
587 | TObjString* label = 0x0; | |
588 | TIter nextLabel(fCounters->GetAxis(dim)->GetLabels()); | |
589 | while ((label = static_cast<TObjString*>(nextLabel()))) keyWords += Form("%s,",label->String().Data()); | |
590 | keyWords.Remove(TString::kTrailing, ','); | |
591 | ||
592 | return keyWords; | |
593 | } | |
594 | ||
d810835e | 595 | //----------------------------------------------------------------------- |
596 | Double_t AliCounterCollection::GetSum(TString selections) | |
597 | { | |
598 | /// Get the overall statistics for the given selection (result is integrated over not specified rubrics): | |
599 | /// - format of "selections" is rubric:[any-]keyWord,keyWord,../rubric:[any-]keyWord,.. (order does not matter). | |
600 | ||
601 | if (!fCounters) { | |
602 | AliError("counters are not initialized"); | |
603 | return 0.; | |
604 | } | |
605 | ||
606 | selections.ToUpper(); | |
607 | ||
608 | // decode the selections | |
609 | Short_t** select = DecodeSelection(selections, TObjArray()); | |
610 | if (!select) return 0.; | |
611 | ||
612 | // loop over every filled counters and compute integral | |
613 | Double_t sum = 0.; | |
614 | Int_t nDims = fCounters->GetNdimensions(); | |
615 | Int_t* coord = new Int_t[nDims]; | |
616 | for (Long64_t i=0; i<fCounters->GetNbins(); ++i) { | |
617 | ||
618 | // get the content of the counter | |
619 | Double_t value = fCounters->GetBinContent(i, coord); | |
620 | ||
621 | // discard not selected counters and compute the selection factor | |
622 | Int_t selectionFactor = 1; | |
623 | for (Int_t dim = 0; dim < nDims && selectionFactor != 0; dim++) selectionFactor *= select[dim][coord[dim]]; | |
624 | if (selectionFactor == 0) continue; | |
625 | ||
626 | // compute integral | |
627 | sum += selectionFactor * value; | |
628 | } | |
629 | ||
630 | // clean memory | |
631 | for (Int_t iDim=0; iDim<nDims; iDim++) delete[] select[iDim]; | |
632 | delete[] select; | |
633 | delete[] coord; | |
634 | ||
635 | return sum; | |
636 | } | |
637 | ||
d649ab79 | 638 | //----------------------------------------------------------------------- |
94ef1a28 | 639 | void AliCounterCollection::PrintKeyWords() const |
640 | { | |
641 | /// Print the full list of key words. | |
642 | ||
643 | if (!fCounters) { | |
644 | AliError("counters are not initialized"); | |
645 | return; | |
646 | } | |
647 | ||
648 | // loop over rubrics | |
649 | Int_t nRubrics = fCounters->GetNdimensions(); | |
650 | for (Int_t iDim=0; iDim<nRubrics; iDim++) { | |
651 | TAxis* axis = fCounters->GetAxis(iDim); | |
652 | ||
653 | // print rubric's name | |
654 | printf("\n%s:", axis->GetName()); | |
655 | ||
656 | // loop over key words | |
657 | Bool_t first = kTRUE; | |
658 | TObjString* label = 0x0; | |
659 | TIter nextLabel(axis->GetLabels()); | |
660 | while ((label = static_cast<TObjString*>(nextLabel()))) { | |
661 | ||
662 | //print key word's name | |
663 | if (first) { | |
664 | printf("%s", label->String().Data()); | |
665 | first = kFALSE; | |
666 | } else printf(",%s", label->String().Data()); | |
667 | ||
668 | } | |
669 | } | |
670 | printf("\n\n"); | |
671 | } | |
672 | ||
673 | //----------------------------------------------------------------------- | |
674 | void AliCounterCollection::PrintValue(TString selections) | |
675 | { | |
676 | /// Print value of selected counter. | |
6f5626c7 | 677 | /// format of "selections" is rubric:keyWord/rubric:keyWord/rubric:keyWord/... |
94ef1a28 | 678 | |
679 | if (!fCounters) { | |
680 | AliError("counters are not initialized"); | |
681 | return; | |
682 | } | |
683 | ||
684 | selections.ToUpper(); | |
685 | ||
686 | // convert external to internal key | |
687 | Int_t nEmptySlots = 0; | |
688 | const Int_t* selectedBins = FindBins(selections, kFALSE, nEmptySlots); | |
689 | if (!selectedBins) return; | |
690 | ||
691 | // check for empty slots | |
692 | if (nEmptySlots > 0) { | |
693 | AliError("incomplete key"); | |
694 | delete[] selectedBins; | |
695 | return; | |
696 | } | |
697 | ||
698 | // print value | |
d810835e | 699 | if (fWeightedCounters) printf("\n%g\n\n", fCounters->GetBinContent(selectedBins)); |
700 | else printf("\n%d\n\n", (Int_t) fCounters->GetBinContent(selectedBins)); | |
94ef1a28 | 701 | |
702 | // clean memory | |
703 | delete[] selectedBins; | |
704 | } | |
705 | ||
706 | //----------------------------------------------------------------------- | |
707 | void AliCounterCollection::Print(TString rubrics, TString selections) | |
708 | { | |
709 | /// Print desired rubrics for the given selection: | |
710 | /// - format of "rubrics" is rubric1/rubric2/.. (order matters only for output). | |
6f5626c7 | 711 | /// - format of "selections" is rubric:[any-]keyWord,keyWord,../rubric:[any-]keyWord,.. (order does not matter). |
94ef1a28 | 712 | /// If "data" contains 1 rubric, the output will be one counter for each element of that rubric. |
713 | /// If "data" contains 2 rubrics, the output will be an array of counters, rubric1 vs rubric2. | |
714 | /// If "data" contains 3 rubrics, the output will be an array rubric1 vs rubric2 for each element in rubric3. | |
715 | /// ... | |
716 | /// Results are integrated over rubrics not specified neither in "rubrics" nor in "selections". | |
717 | ||
718 | if (!fCounters) { | |
719 | AliError("counters are not initialized"); | |
720 | return; | |
721 | } | |
722 | ||
723 | rubrics.ToUpper(); | |
724 | selections.ToUpper(); | |
725 | ||
726 | // get the rubrics to print | |
727 | TObjArray* rubricsToPrint = rubrics.Tokenize("/"); | |
728 | if (rubricsToPrint->GetEntriesFast() == 0) { | |
729 | delete rubricsToPrint; | |
730 | return; | |
731 | } | |
732 | ||
733 | // remove rubrics called twice | |
734 | CleanListOfStrings(rubricsToPrint); | |
735 | ||
736 | // project counters in the rubrics to print according to the selections | |
737 | TObject* hist = Projection(*rubricsToPrint, selections); | |
738 | if (!hist) { | |
739 | delete rubricsToPrint; | |
740 | return; | |
741 | } | |
742 | ||
743 | // print counters | |
744 | Int_t nRubricsToPrint = rubricsToPrint->GetEntriesFast(); | |
6f5626c7 | 745 | if (nRubricsToPrint == 1 && (static_cast<TH1D*>(hist))->GetEntries() > 0) |
94ef1a28 | 746 | PrintList(static_cast<TH1D*>(hist)); |
6f5626c7 | 747 | else if (nRubricsToPrint == 2 && (static_cast<TH2D*>(hist))->GetEntries() > 0) |
94ef1a28 | 748 | PrintArray(static_cast<TH2D*>(hist)); |
6f5626c7 | 749 | else if (nRubricsToPrint > 2 && (static_cast<THnSparse*>(hist))->GetEntries() > 0) |
94ef1a28 | 750 | PrintListOfArrays(static_cast<THnSparse*>(hist)); |
751 | else | |
752 | printf("\nselected counters are empty\n\n"); | |
753 | ||
754 | // clean memory | |
755 | delete rubricsToPrint; | |
756 | delete hist; | |
757 | } | |
758 | ||
759 | //----------------------------------------------------------------------- | |
6f5626c7 | 760 | void AliCounterCollection::PrintSum(TString selections) |
94ef1a28 | 761 | { |
6f5626c7 | 762 | /// Print the overall statistics for the given selection (result is integrated over not specified rubrics): |
763 | /// - format of "selections" is rubric:[any-]keyWord,keyWord,../rubric:[any-]keyWord,.. (order does not matter). | |
d810835e | 764 | Double_t sum = GetSum(selections); |
765 | if (fWeightedCounters) printf("\n%g\n\n", sum); | |
766 | else printf("\n%d\n\n", (Int_t)sum); | |
94ef1a28 | 767 | } |
768 | ||
769 | //----------------------------------------------------------------------- | |
770 | void AliCounterCollection::PrintList(const TH1D* hist) const | |
771 | { | |
772 | /// Print the content of 1D histogram as a list. | |
773 | ||
774 | // set the format to print labels | |
775 | THashList* labels = hist->GetXaxis()->GetLabels(); | |
d810835e | 776 | TString format = ""; |
777 | if (fWeightedCounters) format = Form("\n%%%ds %%9g",GetMaxLabelSize(labels)); | |
778 | else format = Form("\n%%%ds %%9d",GetMaxLabelSize(labels)); | |
94ef1a28 | 779 | |
780 | // print value for each label | |
781 | TObjString* label = 0x0; | |
782 | TIter nextLabel(labels); | |
783 | while ((label = static_cast<TObjString*>(nextLabel()))) { | |
784 | Int_t bin = (Int_t) label->GetUniqueID(); | |
d810835e | 785 | if (fWeightedCounters) printf(format.Data(), label->String().Data(), hist->GetBinContent(bin)); |
786 | else printf(format.Data(), label->String().Data(), (Int_t) hist->GetBinContent(bin)); | |
94ef1a28 | 787 | } |
788 | printf("\n\n"); | |
789 | } | |
790 | ||
791 | //----------------------------------------------------------------------- | |
792 | void AliCounterCollection::PrintArray(const TH2D* hist) const | |
793 | { | |
794 | /// Print the content of 2D histogram as an array. | |
795 | ||
796 | // set the format to print labels in X direction | |
797 | THashList* labelsX = hist->GetXaxis()->GetLabels(); | |
798 | TString formatX(Form("\n%%%ds ",GetMaxLabelSize(labelsX))); | |
799 | ||
800 | // set the format to print labels in Y direction and values | |
801 | THashList* labelsY = hist->GetYaxis()->GetLabels(); | |
802 | Int_t maxLabelSizeY = TMath::Max(9, GetMaxLabelSize(labelsY)); | |
803 | TString formatYs(Form("%%%ds ",maxLabelSizeY)); | |
804 | TString formatYd(Form("%%%dd ",maxLabelSizeY)); | |
d810835e | 805 | TString formatYg(Form("%%%dg ",maxLabelSizeY)); |
94ef1a28 | 806 | |
807 | // print labels in Y axis | |
808 | printf(formatX.Data()," "); | |
809 | TObjString* labelY = 0x0; | |
810 | TIter nextLabelY(labelsY); | |
811 | while ((labelY = static_cast<TObjString*>(nextLabelY()))) | |
812 | printf(formatYs.Data(), labelY->String().Data()); | |
813 | ||
814 | // fill array for each label in X axis | |
815 | TObjString* labelX = 0x0; | |
816 | TIter nextLabelX(labelsX); | |
817 | while ((labelX = static_cast<TObjString*>(nextLabelX()))) { | |
818 | Int_t binX = (Int_t) labelX->GetUniqueID(); | |
819 | ||
820 | // print label X | |
821 | printf(formatX.Data(), labelX->String().Data()); | |
822 | ||
823 | // print value for each label in Y axis | |
824 | nextLabelY.Reset(); | |
825 | while ((labelY = static_cast<TObjString*>(nextLabelY()))) { | |
826 | Int_t binY = (Int_t) labelY->GetUniqueID(); | |
d810835e | 827 | if (fWeightedCounters) printf(formatYg.Data(), hist->GetBinContent(binX, binY)); |
828 | else printf(formatYd.Data(), (Int_t) hist->GetBinContent(binX, binY)); | |
94ef1a28 | 829 | } |
830 | } | |
831 | printf("\n\n"); | |
832 | } | |
833 | ||
834 | //----------------------------------------------------------------------- | |
835 | void AliCounterCollection::PrintListOfArrays(const THnSparse* hist) const | |
836 | { | |
837 | /// Print the content of nD histogram as a list of arrays. | |
838 | ||
839 | // set the format to print labels in X direction | |
840 | THashList* labelsX = hist->GetAxis(0)->GetLabels(); | |
841 | TString formatX(Form("\n%%%ds ",GetMaxLabelSize(labelsX))); | |
842 | ||
843 | // set the format to print labels in Y direction and values | |
844 | THashList* labelsY = hist->GetAxis(1)->GetLabels(); | |
845 | Int_t maxLabelSizeY = TMath::Max(9, GetMaxLabelSize(labelsY)); | |
846 | TString formatYs(Form("%%%ds ",maxLabelSizeY)); | |
847 | TString formatYd(Form("%%%dd ",maxLabelSizeY)); | |
d810835e | 848 | TString formatYg(Form("%%%dg ",maxLabelSizeY)); |
94ef1a28 | 849 | |
850 | // create a list containing each combination of labels refering the arrays to be printout | |
851 | TList listOfCombis; | |
852 | listOfCombis.SetOwner(); | |
853 | ||
854 | // add a first empty combination | |
855 | Int_t nDim = hist->GetNdimensions(); | |
856 | listOfCombis.AddLast(new TObjArray(nDim-2)); | |
857 | ||
858 | // loop over the nDim-2 other rubrics | |
859 | for (Int_t i=2; i<nDim; i++) { | |
860 | ||
861 | // save the last label of that rubic | |
862 | THashList* labels = hist->GetAxis(i)->GetLabels(); | |
863 | TObjString* lastLabel = (labels) ? static_cast<TObjString*>(labels->Last()) : 0x0; | |
864 | if (!lastLabel) return; | |
865 | ||
866 | // prepare iteration over the list of labels | |
867 | TIter nextLabel(labels); | |
868 | ||
869 | // loop over existing combinations | |
870 | TObjLink* lnk = listOfCombis.FirstLink(); | |
871 | while (lnk) { | |
872 | ||
873 | // get the current combination | |
874 | TObjArray* currentCombi = static_cast<TObjArray*>(lnk->GetObject()); | |
875 | ||
876 | // loop over labels in the current rubric | |
877 | nextLabel.Reset(); | |
878 | TObjString* label = 0x0; | |
879 | while ((label = static_cast<TObjString*>(nextLabel()))) { | |
880 | ||
881 | // stop at the last one | |
882 | if (label == lastLabel) break; | |
883 | ||
884 | // copy the current combination, add the current label to it and add it to the list of combinations | |
885 | TObjArray* combi = new TObjArray(*currentCombi); | |
886 | combi->AddLast(label); | |
887 | listOfCombis.AddBefore(lnk, combi); | |
888 | } | |
889 | ||
890 | // add the last label to the current combination | |
891 | currentCombi->AddLast(lastLabel); | |
892 | ||
893 | lnk = lnk->Next(); | |
894 | } | |
895 | ||
896 | } | |
897 | ||
898 | // create bin coordinates to access individual counters | |
899 | Int_t* bins = new Int_t[nDim]; | |
900 | ||
901 | // loop over each combination of labels | |
902 | TObjArray* combi = 0x0; | |
903 | TIter nextCombi(&listOfCombis); | |
904 | while ((combi = static_cast<TObjArray*>(nextCombi()))) { | |
905 | ||
906 | // make the name of the combination and fill the corresponding bin coordinates | |
907 | TString combiName = "/"; | |
908 | for (Int_t i=2; i<nDim; i++) { | |
909 | TObjString* label = static_cast<TObjString*>(combi->UncheckedAt(i-2)); | |
910 | combiName += Form("%s/",label->String().Data()); | |
911 | bins[i] = (Int_t)label->GetUniqueID(); | |
912 | } | |
913 | ||
914 | // skip empty array | |
915 | Bool_t empty = kTRUE; | |
916 | TObjString* labelX = 0x0; | |
917 | TObjString* labelY = 0x0; | |
918 | TIter nextLabelX(labelsX); | |
919 | TIter nextLabelY(labelsY); | |
920 | while ((labelX = static_cast<TObjString*>(nextLabelX()))) { | |
921 | bins[0] = (Int_t) labelX->GetUniqueID(); | |
922 | nextLabelY.Reset(); | |
923 | while ((labelY = static_cast<TObjString*>(nextLabelY()))) { | |
924 | bins[1] = (Int_t) labelY->GetUniqueID(); | |
925 | if (((Int_t) hist->GetBinContent(bins)) > 0) { | |
926 | empty = kFALSE; | |
927 | break; | |
928 | } | |
929 | } | |
930 | if (!empty) break; | |
931 | } | |
932 | if (empty) continue; | |
933 | ||
934 | // print the name of the combination of labels refering the incoming array | |
935 | printf("\n%s:\n",combiName.Data()); | |
936 | ||
937 | // print labels in Y axis | |
938 | printf(formatX.Data()," "); | |
939 | nextLabelY.Reset(); | |
940 | while ((labelY = static_cast<TObjString*>(nextLabelY()))) | |
941 | printf(formatYs.Data(), labelY->String().Data()); | |
942 | ||
943 | // fill array for each label in X axis | |
944 | nextLabelX.Reset(); | |
945 | while ((labelX = static_cast<TObjString*>(nextLabelX()))) { | |
946 | bins[0] = (Int_t) labelX->GetUniqueID(); | |
947 | ||
948 | // print label X | |
949 | printf(formatX.Data(), labelX->String().Data()); | |
950 | ||
951 | // print value for each label in Y axis | |
952 | nextLabelY.Reset(); | |
953 | while ((labelY = static_cast<TObjString*>(nextLabelY()))) { | |
954 | bins[1] = (Int_t) labelY->GetUniqueID(); | |
d810835e | 955 | if (fWeightedCounters) printf(formatYg.Data(), hist->GetBinContent(bins)); |
956 | else printf(formatYd.Data(), (Int_t) hist->GetBinContent(bins)); | |
94ef1a28 | 957 | } |
958 | } | |
959 | printf("\n\n"); | |
960 | } | |
961 | ||
962 | // clean memory | |
963 | delete[] bins; | |
964 | } | |
965 | ||
966 | //----------------------------------------------------------------------- | |
967 | Int_t AliCounterCollection::GetMaxLabelSize(THashList* labels) const | |
968 | { | |
969 | /// Return the number of characters of the longest label. | |
970 | Int_t maxLabelSize = 0; | |
971 | TObjString* label = 0x0; | |
972 | TIter nextLabel(labels); | |
973 | while ((label = static_cast<TObjString*>(nextLabel()))) | |
974 | maxLabelSize = TMath::Max(maxLabelSize, label->String().Length()); | |
975 | return maxLabelSize; | |
976 | } | |
977 | ||
978 | //----------------------------------------------------------------------- | |
0dc8b856 | 979 | TH1D* AliCounterCollection::Get(TString rubric, TString selections) |
94ef1a28 | 980 | { |
0dc8b856 | 981 | /// Get counters of the rubric "rubric" for the given "selection". |
6f5626c7 | 982 | /// Format of "selections" is rubric:[any-]keyWord,keyWord,../rubric:[any-]keyWord,.. (order does not matter). |
94ef1a28 | 983 | /// Results are integrated over rubrics not specified neither in "rubric1" nor in "selections". |
984 | /// It is the responsability of the user to delete the returned histogram. | |
985 | ||
986 | if (!fCounters) { | |
987 | AliError("counters are not initialized"); | |
988 | return 0x0; | |
989 | } | |
990 | ||
991 | rubric.ToUpper(); | |
992 | selections.ToUpper(); | |
993 | ||
994 | // fill the rubrics to print | |
995 | TObjArray rubricsToPrint(1); | |
996 | rubricsToPrint.SetOwner(); | |
997 | rubricsToPrint.AddLast(new TObjString(rubric.Data())); | |
998 | ||
999 | // project counters in the rubrics to print according to the selections | |
1000 | TH1D* hist = static_cast<TH1D*>(Projection(rubricsToPrint, selections)); | |
1001 | ||
0dc8b856 | 1002 | // make it ready to display |
94ef1a28 | 1003 | if (hist) { |
1004 | ||
0dc8b856 | 1005 | // remove statistic box |
94ef1a28 | 1006 | hist->SetStats(kFALSE); |
1007 | ||
0dc8b856 | 1008 | // prepare X axis |
94ef1a28 | 1009 | TAxis* axis = hist->GetXaxis(); |
1010 | THashList* labels = axis->GetLabels(); | |
1011 | Int_t nLabels = (labels) ? labels->GetSize() : 1; | |
1012 | axis->SetRange(1,nLabels); | |
1013 | axis->SetNdivisions(1,kFALSE); | |
1014 | axis->SetTitle(rubric.Data()); | |
1015 | ||
0dc8b856 | 1016 | // prepare Y axis |
94ef1a28 | 1017 | hist->GetYaxis()->SetTitle("Counts"); |
1018 | } | |
1019 | ||
1020 | return hist; | |
1021 | } | |
1022 | ||
1023 | //----------------------------------------------------------------------- | |
0dc8b856 | 1024 | TH2D* AliCounterCollection::Get(TString rubric1, TString rubric2, TString selections) |
94ef1a28 | 1025 | { |
0dc8b856 | 1026 | /// Get counters of the "rubric1" vs "rubric2" for the given "selection". |
6f5626c7 | 1027 | /// Format of "selections" is rubric:[any-]keyWord,keyWord,../rubric:[any-]keyWord,.. (order does not matter). |
94ef1a28 | 1028 | /// Results are integrated over rubrics not specified neither in "rubric1", "rubric2" nor in "selections". |
1029 | /// It is the responsability of the user to delete the returned histogram. | |
1030 | ||
1031 | if (!fCounters) { | |
1032 | AliError("counters are not initialized"); | |
1033 | return 0x0; | |
1034 | } | |
1035 | ||
1036 | rubric1.ToUpper(); | |
1037 | rubric2.ToUpper(); | |
1038 | selections.ToUpper(); | |
1039 | ||
1040 | // fill the rubrics to print | |
1041 | TObjArray rubricsToPrint(2); | |
1042 | rubricsToPrint.SetOwner(); | |
1043 | rubricsToPrint.AddLast(new TObjString(rubric2.Data())); | |
1044 | rubricsToPrint.AddLast(new TObjString(rubric1.Data())); | |
1045 | ||
1046 | // project counters in the rubrics to print according to the selections | |
1047 | TH2D* hist = static_cast<TH2D*>(Projection(rubricsToPrint, selections)); | |
1048 | ||
1049 | // draw counters | |
1050 | if (hist) { | |
1051 | ||
0dc8b856 | 1052 | // remove statistic box |
94ef1a28 | 1053 | hist->SetStats(kFALSE); |
1054 | ||
0dc8b856 | 1055 | // prepare X axis |
94ef1a28 | 1056 | TAxis* axisX = hist->GetXaxis(); |
1057 | THashList* labelsX = axisX->GetLabels(); | |
1058 | Int_t nLabelsX = (labelsX) ? labelsX->GetSize() : 1; | |
1059 | axisX->SetRange(1,nLabelsX); | |
1060 | axisX->SetNdivisions(1,kFALSE); | |
1061 | axisX->SetTitle(rubric2.Data()); | |
1062 | ||
0dc8b856 | 1063 | // prepare Y axis |
94ef1a28 | 1064 | TAxis* axisY = hist->GetYaxis(); |
1065 | THashList* labelsY = axisY->GetLabels(); | |
1066 | Int_t nLabelsY = (labelsY) ? labelsY->GetSize() : 1; | |
1067 | axisY->SetRange(1,nLabelsY); | |
1068 | axisY->SetNdivisions(1,kFALSE); | |
1069 | axisY->SetTitle(rubric1.Data()); | |
1070 | } | |
1071 | ||
1072 | return hist; | |
1073 | } | |
1074 | ||
0dc8b856 | 1075 | //----------------------------------------------------------------------- |
1076 | TH1D* AliCounterCollection::Draw(TString rubric, TString selections) | |
1077 | { | |
1078 | /// Draw counters of the rubric "rubric" for the given "selection". | |
1079 | /// Format of "selections" is rubric:[any-]keyWord,keyWord,../rubric:[any-]keyWord,.. (order does not matter). | |
1080 | /// Results are integrated over rubrics not specified neither in "rubric1" nor in "selections". | |
1081 | /// It is the responsability of the user to delete the returned histogram. | |
1082 | TH1D* hist = Get(rubric, selections); | |
1083 | if (hist) hist->Draw("htext"); | |
1084 | return hist; | |
1085 | } | |
1086 | ||
1087 | //----------------------------------------------------------------------- | |
1088 | TH2D* AliCounterCollection::Draw(TString rubric1, TString rubric2, TString selections) | |
1089 | { | |
1090 | /// Draw counters of the "rubric1" vs "rubric2" for the given "selection". | |
1091 | /// Format of "selections" is rubric:[any-]keyWord,keyWord,../rubric:[any-]keyWord,.. (order does not matter). | |
1092 | /// Results are integrated over rubrics not specified neither in "rubric1", "rubric2" nor in "selections". | |
1093 | /// It is the responsability of the user to delete the returned histogram. | |
1094 | TH2D* hist = Get(rubric1, rubric2, selections); | |
1095 | if (hist) hist->Draw("text"); | |
1096 | return hist; | |
1097 | } | |
1098 | ||
94ef1a28 | 1099 | //----------------------------------------------------------------------- |
1100 | TObject* AliCounterCollection::Projection(const TObjArray& data, const TString& selections) | |
1101 | { | |
1102 | /// Return desired "data" for the given "selection" stored in a new histogram or 0x0 in case of failure. | |
1103 | /// The type of the histogram (TH1D, TH2D or THnSparse) depend on the number of data. | |
1104 | /// It is the responsability of the user to delete the returned histogram. | |
1105 | ||
6f5626c7 | 1106 | // decode the selections |
1107 | Short_t** select = DecodeSelection(selections, data); | |
1108 | if (!select) return 0x0; | |
1109 | ||
1110 | // define name and dimensions of projection histo | |
1111 | TString name(fCounters->GetName()); | |
1112 | Int_t nDims = fCounters->GetNdimensions(); | |
1113 | Int_t nTargetDims = data.GetEntriesFast(); | |
1114 | TArrayI targetDims(nTargetDims); | |
1115 | TArrayI nNewBins(nTargetDims); | |
1116 | TArrayI* OldToNewCoord = new TArrayI[nTargetDims]; | |
1117 | for (Int_t i=0; i<nTargetDims; i++) { | |
1118 | ||
1119 | // histo name | |
1120 | name += Form("_%s",static_cast<TObjString*>(data.UncheckedAt(i))->String().Data()); | |
1121 | ||
1122 | // find target dims | |
94ef1a28 | 1123 | targetDims[i] = FindDim(static_cast<TObjString*>(data.UncheckedAt(i))->String()); |
6f5626c7 | 1124 | |
1125 | // set number of selected bins in the target dims and make the correspondence between old and new coordinates | |
1126 | nNewBins[i] = 0; | |
1127 | if (targetDims[i] > -1) { | |
1128 | Int_t nBins = GetNActiveBins(targetDims[i]) + 1; | |
1129 | OldToNewCoord[i].Set(nBins); | |
1130 | for (Int_t j=1; j<nBins; j++) if (select[targetDims[i]][j] > 0) OldToNewCoord[i][j] = ++nNewBins[i]; | |
1131 | } | |
1132 | ||
1133 | // clean memory and return 0x0 in case of problem | |
1134 | if (nNewBins[i] == 0) { | |
1135 | for (Int_t iDim=0; iDim<nDims; iDim++) delete[] select[iDim]; | |
1136 | delete[] select; | |
1137 | delete[] OldToNewCoord; | |
94ef1a28 | 1138 | return 0x0; |
1139 | } | |
6f5626c7 | 1140 | |
94ef1a28 | 1141 | } |
1142 | ||
6f5626c7 | 1143 | // define title of projection histo |
1144 | TString title = "Selections: "; | |
1145 | TString selectionString(selections); | |
1146 | selectionString.Remove(TString::kBoth, '/'); | |
1147 | if (selectionString.Length() > 0) title += Form("%s/", selectionString.Data()); | |
1148 | TObject* rub = 0x0; | |
1149 | TIter nextRubric(fRubrics); | |
1150 | while ((rub = nextRubric())) { | |
1151 | if (selectionString.Contains(Form("%s:",rub->GetName()))) continue; | |
1152 | if (data.Contains(rub->GetName())) continue; | |
1153 | title += Form("%s:ANY/", rub->GetName()); | |
94ef1a28 | 1154 | } |
6f5626c7 | 1155 | title.ReplaceAll("/", " "); |
94ef1a28 | 1156 | |
6f5626c7 | 1157 | // Create new histograms |
1158 | TObject* hist; | |
1159 | if (nTargetDims == 1) hist = new TH1D(name.Data(), title.Data(), nNewBins[0], 0., 1.); | |
1160 | else if (nTargetDims == 2) hist = new TH2D(name.Data(), title.Data(), nNewBins[0], 0., 1., nNewBins[1], 0., 1.); | |
d810835e | 1161 | else if (fWeightedCounters) hist = new THnSparseT<TArrayF>(name.Data(), title.Data(), nTargetDims, nNewBins.GetArray(), 0x0, 0x0); |
6f5626c7 | 1162 | else hist = new THnSparseT<TArrayI>(name.Data(), title.Data(), nTargetDims, nNewBins.GetArray(), 0x0, 0x0); |
94ef1a28 | 1163 | |
6f5626c7 | 1164 | // Set new axis labels |
1165 | TObjString* label; | |
1166 | if (nTargetDims < 3) { | |
94ef1a28 | 1167 | |
6f5626c7 | 1168 | // X axis |
1169 | TIter nextLabelX(fCounters->GetAxis(targetDims[0])->GetLabels()); | |
1170 | while ((label = static_cast<TObjString*>(nextLabelX()))) { | |
1171 | if (select[targetDims[0]][label->GetUniqueID()] > 0) { | |
1172 | static_cast<TH1*>(hist)->GetXaxis()->SetBinLabel(OldToNewCoord[0][label->GetUniqueID()], label->String().Data()); | |
1173 | } | |
94ef1a28 | 1174 | } |
1175 | ||
6f5626c7 | 1176 | // Y axis if any |
1177 | if (nTargetDims == 2) { | |
1178 | TIter nextLabelY(fCounters->GetAxis(targetDims[1])->GetLabels()); | |
1179 | while ((label = static_cast<TObjString*>(nextLabelY()))) { | |
1180 | if (select[targetDims[1]][label->GetUniqueID()] > 0) { | |
1181 | static_cast<TH1*>(hist)->GetYaxis()->SetBinLabel(OldToNewCoord[1][label->GetUniqueID()], label->String().Data()); | |
1182 | } | |
1183 | } | |
1184 | } | |
94ef1a28 | 1185 | |
6f5626c7 | 1186 | } else { |
94ef1a28 | 1187 | |
6f5626c7 | 1188 | // all axes |
1189 | for (Int_t i=0; i<nTargetDims; i++) { | |
1190 | TIter nextLabel(fCounters->GetAxis(targetDims[i])->GetLabels()); | |
1191 | while ((label = static_cast<TObjString*>(nextLabel()))) { | |
1192 | if (select[targetDims[i]][label->GetUniqueID()] > 0) { | |
1193 | static_cast<THnSparse*>(hist)->GetAxis(i)->SetBinLabel(OldToNewCoord[i][label->GetUniqueID()], label->String().Data()); | |
1194 | } | |
1195 | } | |
94ef1a28 | 1196 | } |
1197 | ||
6f5626c7 | 1198 | } |
1199 | ||
1200 | // loop over every filled counters | |
1201 | Int_t* coord = new Int_t[nDims]; | |
1202 | Int_t* newCoord = new Int_t[nTargetDims]; | |
1203 | Int_t nEntries = 0; | |
1204 | for (Long64_t i=0; i<fCounters->GetNbins(); ++i) { | |
94ef1a28 | 1205 | |
6f5626c7 | 1206 | // get the content of the counter |
1207 | Double_t value = fCounters->GetBinContent(i, coord); | |
94ef1a28 | 1208 | |
6f5626c7 | 1209 | // discard not selected counters and compute the selection factor |
1210 | Int_t selectionFactor = 1; | |
1211 | for (Int_t dim = 0; dim < nDims && selectionFactor != 0; dim++) selectionFactor *= select[dim][coord[dim]]; | |
1212 | if (selectionFactor == 0) continue; | |
94ef1a28 | 1213 | |
6f5626c7 | 1214 | // find new coordinates in the projection histo |
1215 | for (Int_t d = 0; d < nTargetDims; ++d) newCoord[d] = OldToNewCoord[d][coord[targetDims[d]]]; | |
1216 | ||
1217 | // fill projection histo | |
1218 | if (nTargetDims < 3) { | |
1219 | Int_t linBin = (nTargetDims == 1) ? newCoord[0] : static_cast<TH1*>(hist)->GetBin(newCoord[0], newCoord[1]); | |
1220 | static_cast<TH1*>(hist)->AddBinContent(linBin, selectionFactor*value); | |
1221 | } else static_cast<THnSparse*>(hist)->AddBinContent(newCoord, selectionFactor*value); | |
94ef1a28 | 1222 | |
6f5626c7 | 1223 | nEntries++; |
94ef1a28 | 1224 | } |
1225 | ||
6f5626c7 | 1226 | // update the number of entries |
1227 | if (nTargetDims < 3) static_cast<TH1*>(hist)->SetEntries(nEntries); | |
1228 | else static_cast<THnSparse*>(hist)->SetEntries(nEntries); | |
1229 | ||
94ef1a28 | 1230 | // clean memory |
6f5626c7 | 1231 | for (Int_t iDim=0; iDim<nDims; iDim++) delete[] select[iDim]; |
1232 | delete[] select; | |
1233 | delete[] coord; | |
1234 | delete[] newCoord; | |
1235 | delete[] OldToNewCoord; | |
94ef1a28 | 1236 | |
1237 | return hist; | |
1238 | } | |
1239 | ||
1240 | //----------------------------------------------------------------------- | |
1241 | Int_t* AliCounterCollection::CheckConsistency(const AliCounterCollection* c) | |
1242 | { | |
1243 | /// Consistency check of the two counter collections. To be consistent, both counters | |
1244 | /// must have the same rubrics with the same list of authorized key words if any. | |
1245 | /// Return the correspondence between the local rubric ordering and the one of the other counter, | |
1246 | /// or 0x0 in case of problem. It is the responsability of the user to delete the returned array. | |
1247 | ||
1248 | if (!fCounters || !c->fCounters) { | |
1249 | AliError("counters are not initialized"); | |
1250 | return 0x0; | |
1251 | } | |
1252 | ||
d810835e | 1253 | // check if both counters are weighted or not |
1254 | if (c->fWeightedCounters != fWeightedCounters) AliWarning("merging non-weighted with weigthed counters"); | |
1255 | ||
94ef1a28 | 1256 | // check if the number of rubrics is the same |
1257 | Int_t nRubrics = fRubrics->GetSize(); | |
1258 | if (c->fRubrics->GetSize() != nRubrics) { | |
1259 | AliError("both counters do not contain the same number of rubrics"); | |
1260 | return 0x0; | |
1261 | } | |
1262 | ||
1263 | Int_t* otherDims = new Int_t[nRubrics]; | |
1264 | ||
1265 | // loop over local rubrics | |
1266 | TObject* rubric1 = 0x0; | |
1267 | TIter nextRubric(fRubrics); | |
1268 | while ((rubric1 = nextRubric())) { | |
1269 | ||
1270 | // find that rubric in the other counter | |
1271 | TObject* rubric2 = c->fRubrics->FindObject(rubric1->GetName()); | |
1272 | if (!rubric2) { | |
1273 | AliError(Form("the other counter does not contain the rubric %s", rubric1->GetName())); | |
1274 | delete[] otherDims; | |
1275 | return 0x0; | |
1276 | } | |
1277 | ||
1278 | // check the list of authorized key words if any | |
1279 | TObjArray* keyWords1 = dynamic_cast<TObjArray*>(rubric1); | |
1280 | TObjArray* keyWords2 = dynamic_cast<TObjArray*>(rubric2); | |
1281 | if (keyWords1 && keyWords2) { | |
1282 | ||
1283 | // check if the number of key words is the same | |
1284 | if (keyWords1->GetEntriesFast() != keyWords2->GetEntriesFast()) { | |
1285 | AliError("that rubric does not contain the same number of authorized key words in both counters"); | |
1286 | delete[] otherDims; | |
1287 | return 0x0; | |
1288 | } | |
1289 | ||
1290 | // loop over local key words | |
1291 | TObjString* keyWord = 0x0; | |
1292 | TIter nextKeyWord(keyWords1); | |
1293 | while ((keyWord = static_cast<TObjString*>(nextKeyWord()))) { | |
1294 | ||
1295 | // find that key word in the corresponding rubric of the other counter | |
1296 | if (!keyWords2->FindObject(keyWord->String().Data())) { | |
1297 | AliError(Form("rubric %s does not contain the key word %s in the other counter", rubric1->GetName(), keyWord->String().Data())); | |
1298 | delete[] otherDims; | |
1299 | return 0x0; | |
1300 | } | |
1301 | ||
1302 | } | |
1303 | ||
1304 | } else if (keyWords1 || keyWords2) { | |
1305 | ||
1306 | // that rubric has not been initialized the same way in both counter | |
1307 | if (keyWords1) { | |
1308 | AliError(Form("rubric %s of the other counter does not contain a list of authorized key words while this does", rubric1->GetName())); | |
1309 | } else { | |
1310 | AliError(Form("rubric %s of this counter does not contain a list of authorized key words while the other does", rubric1->GetName())); | |
1311 | } | |
1312 | delete[] otherDims; | |
1313 | return 0x0; | |
1314 | ||
1315 | } | |
1316 | ||
1317 | // save the correspondence of rubric IDs in both counters | |
1318 | otherDims[rubric1->GetUniqueID()] = rubric2->GetUniqueID(); | |
1319 | ||
1320 | } | |
1321 | ||
1322 | return otherDims; | |
1323 | } | |
1324 | ||
1325 | //----------------------------------------------------------------------- | |
1326 | void AliCounterCollection::Add(const AliCounterCollection* counter) | |
1327 | { | |
1328 | /// Add the given AliCounterCollections to this. They must have the | |
1329 | /// same rubrics with the same list of authorized key words if any. | |
1330 | ||
1331 | // check the consistency between the other counter and this and get the correspondences between rubric IDs. | |
1332 | Int_t* otherDims = CheckConsistency(counter); | |
1333 | if (!otherDims) return; | |
1334 | ||
1335 | Int_t nRubrics = fCounters->GetNdimensions(); | |
1336 | Int_t* thisBins = new Int_t[nRubrics]; | |
1337 | Int_t* otherBins = new Int_t[nRubrics]; | |
1338 | ||
1339 | // loop over every filled bins inside the other counter | |
1340 | for (Long64_t i = 0; i < counter->fCounters->GetNbins(); i++) { | |
1341 | ||
1342 | // get the content of the bin | |
1343 | Double_t value = counter->fCounters->GetBinContent(i, otherBins); | |
1344 | ||
1345 | // convert "other" bin coordinates to "this" bin coordinates | |
1346 | Bool_t ok = kTRUE; | |
1347 | for (Int_t dim = 0; dim < nRubrics; dim++) { | |
1348 | TString label = counter->fCounters->GetAxis(otherDims[dim])->GetBinLabel(otherBins[otherDims[dim]]); | |
1349 | thisBins[dim] = FindBin(dim, label, kTRUE); | |
1350 | if (thisBins[dim] < 0) { | |
1351 | AliError("this counter is full, unable to add that key word"); | |
1352 | ok = kFALSE; | |
1353 | break; | |
1354 | } | |
1355 | } | |
1356 | if (!ok) continue; | |
1357 | ||
1358 | // increment the corresponding local counter | |
1359 | fCounters->AddBinContent(thisBins, value); | |
1360 | } | |
1361 | ||
1362 | // clean memory | |
1363 | delete[] otherDims; | |
1364 | delete[] thisBins; | |
1365 | delete[] otherBins; | |
1366 | } | |
1367 | ||
1368 | //----------------------------------------------------------------------- | |
1369 | Long64_t AliCounterCollection::Merge(TCollection* list) | |
1370 | { | |
1371 | /// Merge this with a list of AliCounterCollections. All AliCounterCollections provided | |
1372 | /// must have the same rubrics with the same list of authorized key words if any. | |
1373 | ||
1374 | if (!list || !fCounters) return 0; | |
1375 | if (list->IsEmpty()) return (Long64_t)fCounters->GetEntries(); | |
1376 | ||
1377 | TIter next(list); | |
1378 | const TObject* obj = 0x0; | |
1379 | while ((obj = next())) { | |
1380 | ||
1381 | // check that "obj" is an object of the class AliCounterCollection | |
1382 | const AliCounterCollection* counter = dynamic_cast<const AliCounterCollection*>(obj); | |
1383 | if (!counter) { | |
1384 | AliError(Form("object named %s is not AliCounterCollection! Skipping it.", counter->GetName())); | |
1385 | continue; | |
1386 | } | |
1387 | ||
1388 | // merge counter to this one | |
1389 | Add(counter); | |
1390 | ||
1391 | } | |
1392 | ||
1393 | return (Long64_t)fCounters->GetEntries(); | |
1394 | } | |
1395 | ||
1396 | //----------------------------------------------------------------------- | |
1397 | void AliCounterCollection::Sort(Option_t* opt, Bool_t asInt) | |
1398 | { | |
1399 | /// Sort rubrics defined without a list of authorized key words or all rubrics if opt=="all". | |
1400 | /// If asInt=kTRUE, key words are ordered as interger instead of alphabetically. | |
1401 | ||
1402 | if (!fCounters) { | |
1403 | AliError("counters are not initialized"); | |
1404 | return; | |
1405 | } | |
1406 | ||
1407 | Bool_t all = (!strcasecmp(opt, "all")); | |
1408 | ||
1409 | Bool_t somethingToSort = kFALSE; | |
1410 | Int_t nRubrics = fRubrics->GetSize(); | |
1411 | Bool_t* rubricsToSort = new Bool_t[nRubrics]; | |
1412 | memset(rubricsToSort, kFALSE, sizeof(Bool_t) * nRubrics); | |
1413 | ||
1414 | // choose rubrics to sort | |
1415 | TObject* rubric = 0x0; | |
1416 | TIter nextRubric(fRubrics); | |
1417 | while ((rubric = nextRubric())) { | |
1418 | ||
1419 | if (all || dynamic_cast<TObjString*>(rubric)) { | |
1420 | ||
1421 | // check if something to sort | |
1422 | THashList* labels = fCounters->GetAxis((Int_t)rubric->GetUniqueID())->GetLabels(); | |
1423 | if (!labels || labels->GetSize() < 2) continue; | |
1424 | ||
1425 | // select that rubric | |
1426 | rubricsToSort[(Int_t)rubric->GetUniqueID()] = kTRUE; | |
1427 | somethingToSort = kTRUE; | |
1428 | ||
1429 | } | |
1430 | ||
1431 | } | |
1432 | ||
1433 | // sort selected rubrics if any | |
1434 | if (somethingToSort) Sort(rubricsToSort, asInt); | |
1435 | ||
1436 | // clean memory | |
1437 | delete[] rubricsToSort; | |
1438 | } | |
1439 | ||
1440 | //----------------------------------------------------------------------- | |
1441 | void AliCounterCollection::SortRubric(TString rubric, Bool_t asInt) | |
1442 | { | |
1443 | /// Sort only that rubric. If asInt=kTRUE, key words are ordered as interger instead of alphabetically. | |
1444 | ||
1445 | if (!fCounters) { | |
1446 | AliError("counters are not initialized"); | |
1447 | return; | |
1448 | } | |
1449 | ||
1450 | rubric.ToUpper(); | |
1451 | ||
1452 | // find the rubric to sort | |
1453 | Int_t dim = FindDim(rubric); | |
1454 | if (dim < 0) return; | |
1455 | ||
1456 | // check if something to sort | |
1457 | THashList* labels = fCounters->GetAxis(dim)->GetLabels(); | |
1458 | if (!labels || labels->GetSize() < 2) return; | |
1459 | ||
1460 | // select that rubric | |
1461 | Int_t nRubrics = fRubrics->GetSize(); | |
1462 | Bool_t* rubricsToSort = new Bool_t[nRubrics]; | |
1463 | memset(rubricsToSort, kFALSE, sizeof(Bool_t) * nRubrics); | |
1464 | rubricsToSort[dim] = kTRUE; | |
1465 | ||
1466 | // sort it | |
1467 | Sort(rubricsToSort, asInt); | |
1468 | ||
1469 | // clean memory | |
1470 | delete[] rubricsToSort; | |
1471 | } | |
1472 | ||
1473 | //----------------------------------------------------------------------- | |
1474 | void AliCounterCollection::Sort(const Bool_t* rubricsToSort, Bool_t asInt) | |
1475 | { | |
1476 | /// Sort labels (alphabetically or as integer) in each rubric flagged in "rubricsToSort". | |
1477 | ||
1478 | // create a new counter | |
1479 | THnSparse* oldCounters = fCounters; | |
1480 | Int_t nRubrics = fRubrics->GetSize(); | |
d810835e | 1481 | if (fWeightedCounters) |
1482 | fCounters = new THnSparseT<TArrayF>("hCounters", "hCounters", nRubrics, fRubricsSize->GetArray(), 0x0, 0x0); | |
1483 | else | |
1484 | fCounters = new THnSparseT<TArrayI>("hCounters", "hCounters", nRubrics, fRubricsSize->GetArray(), 0x0, 0x0); | |
94ef1a28 | 1485 | Int_t** newBins = new Int_t*[nRubrics]; |
1486 | ||
1487 | // define the new axes | |
1488 | for (Int_t i=0; i<nRubrics; i++) { | |
1489 | TAxis* oldAxis = oldCounters->GetAxis(i); | |
1490 | TAxis* newAxis = fCounters->GetAxis(i); | |
1491 | ||
1492 | // set the name of the new axis | |
1493 | newAxis->SetName(oldAxis->GetName()); | |
1494 | ||
1495 | // get old labels | |
1496 | THashList* oldLabels = oldAxis->GetLabels(); | |
1497 | if (!oldLabels) continue; | |
1498 | ||
1499 | // sort them if required | |
1500 | if (rubricsToSort[i]) { | |
1501 | if (asInt) { oldLabels = SortAsInt(oldLabels); } | |
1502 | else { oldLabels->Sort(); } | |
1503 | } | |
1504 | ||
1505 | // set labels in the new axis and save the correspondence between new and old bins | |
1506 | newBins[i] = new Int_t[oldLabels->GetSize()+1]; | |
1507 | TObjString* label = 0x0; | |
1508 | Int_t bin = 1; | |
1509 | TIter nextLabel(oldLabels); | |
1510 | while ((label = static_cast<TObjString*>(nextLabel()))) { | |
1511 | newAxis->SetBinLabel(bin, label->String().Data()); | |
1512 | newBins[i][(Int_t)label->GetUniqueID()] = bin; | |
1513 | bin++; | |
1514 | } | |
1515 | ||
1516 | // clean memory | |
1517 | if (rubricsToSort[i] && asInt) delete oldLabels; | |
1518 | } | |
1519 | ||
1520 | // fill the new counters | |
1521 | Int_t* oldCoor = new Int_t[nRubrics]; | |
1522 | Int_t* newCoor = new Int_t[nRubrics]; | |
1523 | for (Long64_t i = 0; i < oldCounters->GetNbins(); i++) { | |
1524 | Double_t value = oldCounters->GetBinContent(i, oldCoor); | |
1525 | for (Int_t dim = 0; dim < nRubrics; dim++) newCoor[dim] = newBins[dim][oldCoor[dim]]; | |
1526 | fCounters->AddBinContent(newCoor, value); | |
1527 | } | |
1528 | ||
1529 | // clean memory | |
1530 | for (Int_t i=0; i<nRubrics; i++) delete[] newBins[i]; | |
1531 | delete[] newBins; | |
1532 | delete[] oldCoor; | |
1533 | delete[] newCoor; | |
1534 | delete oldCounters; | |
1535 | } | |
1536 | ||
1537 | //----------------------------------------------------------------------- | |
1538 | THashList* AliCounterCollection::SortAsInt(const THashList* labels) | |
1539 | { | |
1540 | /// Return a list (not owner) of labels sorted assuming they are integers. | |
1541 | /// It is the responsability of user to delete the returned list. | |
1542 | ||
1543 | THashList* sortedLabels = new THashList(labels->GetSize()); | |
1544 | TIter nextSortedLabel(sortedLabels); | |
1545 | ||
1546 | // loop over labels | |
1547 | TObjString* label = 0x0; | |
1548 | TIter nextLabel(labels); | |
1549 | while ((label = static_cast<TObjString*>(nextLabel()))) { | |
1550 | ||
1551 | // find where to add it | |
1552 | TObjString* sortedLabel = 0x0; | |
1553 | nextSortedLabel.Reset(); | |
1554 | while ((sortedLabel = static_cast<TObjString*>(nextSortedLabel())) && | |
1555 | (sortedLabel->String().Atoi() <= label->String().Atoi())) {} | |
1556 | ||
1557 | // add it | |
1558 | if (sortedLabel) sortedLabels->AddBefore(sortedLabel, label); | |
1559 | else sortedLabels->AddLast(label); | |
1560 | } | |
1561 | ||
1562 | return sortedLabels; | |
1563 | } | |
1564 |