]>
Commit | Line | Data |
---|---|---|
c865cb1d | 1 | // |
2 | // Class AliRsnListOutput | |
3 | // | |
4 | // This class defines a base classe to implement a Output | |
5 | // which uses the internal RSN package event format (AliRsnEvent). | |
6 | // It contains some default flags which turn out to be useful: | |
7 | // - a flag to select only the "true" pairs (tracks from same resonance) | |
8 | // - a flag to know if the computation is done over two events (mixing) | |
9 | // | |
10 | // Any kind of analysis object should be implemented as inheriting from this | |
11 | // because the AliRsnAnalyzer which executes the analysis will accept a collection | |
12 | // of such objects, in order to have a unique format of processing method | |
13 | // | |
14 | // The user who implements a kind of computation type should inherit from | |
15 | // this class and override the virtual Outputs defined in it, which | |
16 | // initialize the final output histogram and define how to process data. | |
17 | // | |
18 | // | |
19 | // author: A. Pulvirenti (email: alberto.pulvirenti@ct.infn.it) | |
20 | // | |
21 | ||
22 | #include <Riostream.h> | |
61f275d1 | 23 | #include <TList.h> |
24 | #include <TCollection.h> | |
c865cb1d | 25 | |
26 | #include "AliLog.h" | |
b63357a0 | 27 | #include "AliCFContainer.h" |
c865cb1d | 28 | |
29 | #include "AliRsnValue.h" | |
61f275d1 | 30 | #include "AliRsnValueDaughter.h" |
31 | #include "AliRsnValueEvent.h" | |
c865cb1d | 32 | #include "AliRsnLoop.h" |
33 | ||
34 | #include "AliRsnListOutput.h" | |
35 | ||
36 | ClassImp(AliRsnListOutput) | |
37 | ||
38 | //________________________________________________________________________________________ | |
39 | AliRsnListOutput::AliRsnListOutput(const char *name, AliRsnListOutput::EOut type) : | |
40 | TNamed(name, ""), | |
f34f960b | 41 | fSkipFailed(kTRUE), |
c865cb1d | 42 | fType(type), |
43 | fSteps(0), | |
44 | fValues(0), | |
45 | fNValues(0), | |
46 | fList(0x0), | |
47 | fIndex(-1), | |
48 | fArray(0) | |
49 | { | |
50 | // | |
51 | // Constructor. | |
52 | // Requires a name for this object (which will be used to name the output object) | |
53 | // and the definition of the output type from the built-in enumeration. | |
54 | // | |
55 | } | |
56 | ||
57 | //________________________________________________________________________________________ | |
58 | AliRsnListOutput::AliRsnListOutput(const AliRsnListOutput ©) : | |
59 | TNamed(copy), | |
f34f960b | 60 | fSkipFailed(copy.fSkipFailed), |
c865cb1d | 61 | fType(copy.fType), |
62 | fSteps(copy.fSteps), | |
63 | fValues(copy.fValues), | |
64 | fNValues(copy.fNValues), | |
65 | fList(copy.fList), | |
66 | fIndex(copy.fIndex), | |
67 | fArray(0) | |
68 | { | |
69 | // | |
70 | // Copy constructor. | |
71 | // Since the pointer objects must be initialized in a second step, | |
72 | // they are never copied, and then they are initialized to zero. | |
73 | // | |
74 | } | |
75 | ||
76 | //________________________________________________________________________________________ | |
61f275d1 | 77 | AliRsnListOutput &AliRsnListOutput::operator=(const AliRsnListOutput ©) |
c865cb1d | 78 | { |
79 | // | |
80 | // Assignment operator. | |
81 | // Same consideration as the copiy constructor. In this case, there is | |
82 | // the possibility to have the output objects alreasy initialized, but | |
83 | // they are anyway reset. | |
84 | // | |
85 | ||
61f275d1 | 86 | TNamed::operator=(copy); |
87 | if (this == ©) | |
88 | return *this; | |
89 | fSkipFailed = copy.fSkipFailed; | |
90 | fType = copy.fType; | |
91 | fSteps = copy.fSteps; | |
92 | fValues = copy.fValues; | |
93 | fNValues = copy.fNValues; | |
94 | fList = copy.fList; | |
95 | fIndex = copy.fIndex; | |
96 | fArray = copy.fArray; | |
97 | ||
c865cb1d | 98 | Reset(); |
99 | ||
100 | return (*this); | |
101 | } | |
102 | ||
103 | //__________________________________________________________________________________________________ | |
104 | AliRsnListOutput::~AliRsnListOutput() | |
105 | { | |
106 | // | |
107 | // Destructor. | |
108 | // Deletes the output objects. | |
109 | // | |
110 | ||
111 | Reset(); | |
112 | } | |
113 | ||
114 | //__________________________________________________________________________________________________ | |
115 | void AliRsnListOutput::Reset() | |
116 | { | |
117 | // | |
118 | // Clear all output objects. In general, only one will be initialized at a time. | |
119 | // | |
120 | ||
121 | fList = 0x0; | |
122 | } | |
123 | ||
124 | //_____________________________________________________________________________ | |
125 | void AliRsnListOutput::AddValue(AliRsnValue *value) | |
126 | { | |
127 | // | |
128 | // Adds a value computation object to the list. | |
129 | // | |
130 | ||
131 | fValues.AddLast(value); | |
132 | } | |
133 | ||
134 | ||
135 | //________________________________________________________________________________________ | |
136 | Bool_t AliRsnListOutput::Init(const char *prefix, TList *list) | |
137 | { | |
138 | // | |
139 | // Initializes the output for this object. | |
140 | // What kind of output depends on the 'fType' data member, | |
141 | // and in case it is a CF container, also on the 'fSteps'. | |
142 | // The object is named with the following criterion: | |
143 | // <prefix>_<name>_<type>_<varList> | |
144 | // | |
145 | ||
146 | Int_t i; | |
147 | ||
148 | // all output objects are cleared | |
149 | Reset(); | |
150 | ||
151 | // count values and set dimension of arrays | |
152 | // do also some checks for a good match between type and output | |
153 | fNValues = fValues.GetEntries(); | |
154 | if (fNValues < 1) { | |
155 | AliError("Need at least 1 value"); | |
156 | return kFALSE; | |
157 | } | |
158 | if (fType == kHistoDefault && fNValues > 3) { | |
159 | AliInfo(Form("NValues = %d > 3 --> cannot use a normal histogram, need to use a sparse", fNValues)); | |
160 | fType = kHistoSparse; | |
161 | } | |
61f275d1 | 162 | |
c865cb1d | 163 | // resize the output array |
164 | fArray.Set(fNValues); | |
165 | ||
3da8cef7 | 166 | |
167 | Bool_t isPair=kFALSE; | |
168 | ||
c865cb1d | 169 | // create the name |
3da8cef7 | 170 | TString name(GetName()); |
171 | if (!name.CompareTo("pair")) isPair = kTRUE; | |
172 | if (isPair) name = ""; | |
173 | else name.Prepend("."); | |
174 | name.Prepend(prefix); | |
175 | ||
176 | // TString name(Form("%s.%s", prefix, GetName())); | |
c865cb1d | 177 | AliRsnValue *val = 0x0; |
178 | for (i = 0; i < fNValues; i++) { | |
179 | val = GetValue(i); | |
180 | if (!val) { | |
181 | AliError(Form("Slot %d in value list is NULL", i)); | |
182 | return kFALSE; | |
183 | } | |
3da8cef7 | 184 | if (!isPair) { |
185 | name += '_'; | |
186 | name += val->GetName(); | |
187 | } | |
c865cb1d | 188 | } |
61f275d1 | 189 | |
c865cb1d | 190 | // allowed objects |
191 | TObject *object = 0x0; | |
192 | ||
193 | // initialize appropriate output object | |
194 | // and, if successful, insert into the list | |
195 | switch (fType) { | |
196 | case kHistoDefault: | |
3da8cef7 | 197 | // name.Append("_hist"); |
c865cb1d | 198 | object = CreateHistogram(name.Data()); |
199 | break; | |
200 | case kHistoSparse: | |
3da8cef7 | 201 | // name.Append("_hsparse"); |
c865cb1d | 202 | object = CreateHistogramSparse(name.Data()); |
203 | break; | |
204 | case kCFContainer: | |
3da8cef7 | 205 | // name.Append("_cf"); |
c865cb1d | 206 | object = CreateCFContainer(name.Data()); |
207 | break; | |
208 | default: | |
209 | AliWarning("Wrong type output or initialization failure"); | |
210 | } | |
61f275d1 | 211 | |
c865cb1d | 212 | if (object) { |
213 | //AliInfo(Form("[%s]: initializing output '%s' (obj name = '%s') with %d values and format %d [%s]", GetName(), name.Data(), object->GetName(), fNValues, fType, object->ClassName())); | |
214 | fList = list; | |
215 | fList->Add(object); | |
216 | fIndex = fList->IndexOf(object); | |
217 | return kTRUE; | |
218 | } | |
219 | ||
220 | return kFALSE; | |
221 | } | |
222 | ||
223 | //________________________________________________________________________________________ | |
61f275d1 | 224 | TH1 *AliRsnListOutput::CreateHistogram(const char *name) |
c865cb1d | 225 | { |
226 | // | |
227 | // Initialize the 'default' TH1 output object. | |
228 | // In case one of the expected axes is NULL, the initialization fails. | |
229 | // | |
230 | ||
231 | // we expect to have maximum 3 axes in this case | |
232 | Int_t i, nbins[3] = {0, 0, 0}; | |
233 | TArrayD array[3]; | |
234 | for (i = 0; i < fNValues; i++) { | |
235 | AliRsnValue *val = GetValue(i); | |
236 | if (!val) { | |
237 | AliError(Form("Expected axis %d is NULL", i)); | |
238 | return 0x0; | |
239 | } | |
240 | nbins[i] = GetValue(i)->GetArray().GetSize() - 1; | |
241 | array[i] = GetValue(i)->GetArray(); | |
242 | } | |
61f275d1 | 243 | |
c865cb1d | 244 | TH1 *hist = 0x0; |
245 | ||
246 | // create histogram depending on the number of axes | |
247 | switch (fNValues) { | |
248 | case 1: | |
249 | hist = new TH1F(name, "", nbins[0], array[0].GetArray()); | |
250 | break; | |
251 | case 2: | |
252 | hist = new TH2F(name, "", nbins[0], array[0].GetArray(), nbins[1], array[1].GetArray()); | |
253 | break; | |
254 | case 3: | |
255 | hist = new TH3F(name, "", nbins[0], array[0].GetArray(), nbins[1], array[1].GetArray(), nbins[2], array[2].GetArray()); | |
256 | break; | |
257 | default: | |
739706ae | 258 | //AliError(Form("Wrong number of dimensions: %d", fNValues)) |
259 | return 0x0; | |
c865cb1d | 260 | } |
261 | ||
262 | if (hist) hist->Sumw2(); | |
263 | return hist; | |
264 | } | |
265 | ||
266 | //________________________________________________________________________________________ | |
61f275d1 | 267 | THnSparseF *AliRsnListOutput::CreateHistogramSparse(const char *name) |
c865cb1d | 268 | { |
269 | // | |
270 | // Initialize the THnSparse output object. | |
271 | // In case one of the expected axes is NULL, the initialization fails. | |
272 | // | |
273 | ||
274 | // retrieve binnings and sizes of all axes | |
275 | // since the check for null values is done in Init(), | |
276 | // we assume that here they must all be well defined | |
277 | Int_t i, *nbins = new Int_t[fNValues]; | |
278 | TArrayD *array = new TArrayD[fNValues]; | |
279 | for (i = 0; i < fNValues; i++) { | |
280 | nbins[i] = GetValue(i)->GetArray().GetSize() - 1; | |
281 | array[i] = GetValue(i)->GetArray(); | |
282 | } | |
283 | ||
284 | // create histogram | |
285 | THnSparseF *hist = new THnSparseF(name, "", fNValues, nbins); | |
286 | hist->Sumw2(); | |
287 | ||
288 | // update the various axes using the definitions given in the array of axes here | |
3da8cef7 | 289 | AliRsnValue *val = 0x0; |
c865cb1d | 290 | for (i = 0; i < fNValues; i++) { |
3da8cef7 | 291 | val = GetValue(i); |
292 | if (val) hist->GetAxis(i)->SetName(val->GetName()); | |
c865cb1d | 293 | hist->GetAxis(i)->Set(nbins[i], array[i].GetArray()); |
294 | } | |
295 | ||
296 | // clear heap | |
297 | delete [] nbins; | |
298 | delete [] array; | |
299 | ||
300 | return hist; | |
301 | } | |
302 | ||
303 | //________________________________________________________________________________________ | |
61f275d1 | 304 | AliCFContainer *AliRsnListOutput::CreateCFContainer(const char *name) |
c865cb1d | 305 | { |
306 | // | |
307 | // Initialize the AliCFContainer output object. | |
308 | // In case one of the expected axes is NULL, the initialization fails. | |
309 | // | |
310 | ||
311 | // retrieve binnings and sizes of all axes | |
312 | // since the check for null values is done in Init(), | |
313 | // we assume that here they must all be well defined | |
314 | Int_t i, *nbins = new Int_t[fNValues]; | |
315 | TArrayD *array = new TArrayD[fNValues]; | |
316 | for (i = 0; i < fNValues; i++) { | |
317 | nbins[i] = GetValue(i)->GetArray().GetSize() - 1; | |
318 | array[i] = GetValue(i)->GetArray(); | |
319 | } | |
320 | ||
321 | // create object | |
322 | AliCFContainer *cont = new AliCFContainer(name, "", fSteps, fNValues, nbins); | |
323 | ||
324 | // set the bin limits for each axis | |
325 | for (i = 0; i < fNValues; i++) { | |
326 | cont->SetBinLimits(i, array[i].GetArray()); | |
327 | } | |
328 | ||
329 | // clear heap | |
330 | delete [] nbins; | |
331 | delete [] array; | |
332 | ||
333 | return cont; | |
334 | } | |
335 | ||
336 | //________________________________________________________________________________________ | |
337 | Bool_t AliRsnListOutput::Fill(TObject *target, Int_t step) | |
338 | { | |
339 | // | |
340 | // Uses the passed argument to compute all values. | |
341 | // If all computations were successful, fill the output | |
342 | // Second argument (step) is needed only in case of CF containers. | |
343 | // Return value is the AND of all computation successes. | |
344 | // | |
345 | ||
346 | Int_t i; | |
347 | ||
348 | // do computations | |
349 | Bool_t globalOK = kTRUE; | |
350 | AliRsnValue *val = 0x0; | |
351 | for (i = 0; i < fNValues; i++) { | |
352 | val = GetValue(i); | |
353 | if (!val) { | |
354 | AliError("NULL value found"); | |
355 | return kFALSE; | |
356 | } | |
357 | globalOK = globalOK && val->Eval(target); | |
358 | fArray[i] = (Double_t)val->GetComputedValue(); | |
359 | } | |
f34f960b | 360 | if (!globalOK && fSkipFailed) return kFALSE; |
61f275d1 | 361 | |
c865cb1d | 362 | // retrieve object |
363 | if (!fList || fIndex < 0) { | |
364 | AliError("List not initialized"); | |
365 | return kFALSE; | |
366 | } | |
367 | TObject *obj = fList->At(fIndex); | |
368 | if (!obj) { | |
369 | AliError("Null pointer"); | |
370 | return kFALSE; | |
371 | } | |
61f275d1 | 372 | |
c865cb1d | 373 | // check |
374 | //AliInfo(Form("[%s] Object index, name, type = %d, %s (%s)", GetName(), fIndex, obj->GetName(), obj->ClassName())); | |
375 | ||
376 | // fill output | |
377 | if (obj->IsA() == TH1F::Class()) { | |
61f275d1 | 378 | TH1F *h = (TH1F *)obj; |
c865cb1d | 379 | h->Fill(fArray[0]); |
380 | return kTRUE; | |
381 | } else if (obj->IsA() == TH2F::Class()) { | |
61f275d1 | 382 | TH2F *h = (TH2F *)obj; |
c865cb1d | 383 | h->Fill(fArray[0], fArray[1]); |
384 | return kTRUE; | |
385 | } else if (obj->IsA() == TH3F::Class()) { | |
61f275d1 | 386 | TH3F *h = (TH3F *)obj; |
c865cb1d | 387 | h->Fill(fArray[0], fArray[1], fArray[2]); |
388 | return kTRUE; | |
389 | } else if (obj->InheritsFrom(THnSparse::Class())) { | |
61f275d1 | 390 | THnSparseF *h = (THnSparseF *)obj; |
c865cb1d | 391 | h->Fill(fArray.GetArray()); |
392 | return kTRUE; | |
393 | } else if (obj->InheritsFrom(AliCFContainer::Class())) { | |
61f275d1 | 394 | AliCFContainer *c = (AliCFContainer *)obj; |
c865cb1d | 395 | c->Fill(fArray.GetArray(), step); |
396 | return kTRUE; | |
397 | } else { | |
398 | AliError(Form("Not handled class '%s'", obj->ClassName())); | |
399 | return kFALSE; | |
400 | } | |
401 | } | |
61f275d1 | 402 | |
403 | //________________________________________________________________________________________ | |
404 | Bool_t AliRsnListOutput::Fill(AliRsnEvent *ev, AliRsnDaughter *d) | |
405 | { | |
406 | // | |
407 | // Uses the passed argument to compute all values. | |
408 | // If all computations were successful, fill the output | |
409 | // Return value is the AND of all computation successes. | |
410 | // | |
411 | ||
412 | // retrieve object | |
413 | if (!fList || fIndex < 0) { | |
414 | AliError("List not initialized"); | |
415 | return kFALSE; | |
416 | } | |
417 | TObject *obj = fList->At(fIndex); | |
418 | if (!obj) { | |
419 | AliError("Null pointer"); | |
420 | return kFALSE; | |
421 | } | |
422 | ||
423 | ||
424 | TIter next(&fValues); | |
425 | AliRsnValue *val; | |
426 | Int_t i=0; | |
427 | Bool_t globalOK = kTRUE; | |
428 | Double_t values[fValues.GetEntries()]; | |
429 | while ((val = (AliRsnValue *)next())) { | |
430 | if (val->InheritsFrom(AliRsnValueDaughter::Class())) { | |
431 | if (!d && fSkipFailed) return kFALSE; | |
432 | globalOK = globalOK && val->Eval(d); | |
433 | } else if (val->InheritsFrom(AliRsnValueEvent::Class())) { | |
434 | if (!ev && fSkipFailed) return kFALSE; | |
435 | globalOK = globalOK && val->Eval(ev); | |
436 | } | |
437 | values[i] = (Double_t)val->GetComputedValue(); | |
438 | if (!globalOK && fSkipFailed) return kFALSE; | |
439 | i++; | |
440 | } | |
441 | ||
442 | // fill output | |
443 | if (obj->IsA() == TH1F::Class()) { | |
444 | TH1F *h = (TH1F *)obj; | |
445 | h->Fill(values[0]); | |
446 | return kTRUE; | |
447 | } else if (obj->IsA() == TH2F::Class()) { | |
448 | TH2F *h = (TH2F *)obj; | |
449 | h->Fill(values[0], values[1]); | |
450 | return kTRUE; | |
451 | } else if (obj->IsA() == TH3F::Class()) { | |
452 | TH3F *h = (TH3F *)obj; | |
453 | h->Fill(values[0], values[1], values[2]); | |
454 | return kTRUE; | |
455 | } else if (obj->InheritsFrom(THnSparse::Class())) { | |
456 | THnSparseF *h = (THnSparseF *)obj; | |
457 | h->Fill(values); | |
458 | return kTRUE; | |
459 | } else { | |
460 | AliError(Form("Not handled class '%s'", obj->ClassName())); | |
461 | return kFALSE; | |
462 | } | |
463 | } |