]>
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> | |
23 | ||
24 | #include "AliLog.h" | |
b63357a0 | 25 | #include "AliCFContainer.h" |
c865cb1d | 26 | |
27 | #include "AliRsnValue.h" | |
28 | #include "AliRsnLoop.h" | |
29 | ||
30 | #include "AliRsnListOutput.h" | |
31 | ||
32 | ClassImp(AliRsnListOutput) | |
33 | ||
34 | //________________________________________________________________________________________ | |
35 | AliRsnListOutput::AliRsnListOutput(const char *name, AliRsnListOutput::EOut type) : | |
36 | TNamed(name, ""), | |
f34f960b | 37 | fSkipFailed(kTRUE), |
c865cb1d | 38 | fType(type), |
39 | fSteps(0), | |
40 | fValues(0), | |
41 | fNValues(0), | |
42 | fList(0x0), | |
43 | fIndex(-1), | |
44 | fArray(0) | |
45 | { | |
46 | // | |
47 | // Constructor. | |
48 | // Requires a name for this object (which will be used to name the output object) | |
49 | // and the definition of the output type from the built-in enumeration. | |
50 | // | |
51 | } | |
52 | ||
53 | //________________________________________________________________________________________ | |
54 | AliRsnListOutput::AliRsnListOutput(const AliRsnListOutput ©) : | |
55 | TNamed(copy), | |
f34f960b | 56 | fSkipFailed(copy.fSkipFailed), |
c865cb1d | 57 | fType(copy.fType), |
58 | fSteps(copy.fSteps), | |
59 | fValues(copy.fValues), | |
60 | fNValues(copy.fNValues), | |
61 | fList(copy.fList), | |
62 | fIndex(copy.fIndex), | |
63 | fArray(0) | |
64 | { | |
65 | // | |
66 | // Copy constructor. | |
67 | // Since the pointer objects must be initialized in a second step, | |
68 | // they are never copied, and then they are initialized to zero. | |
69 | // | |
70 | } | |
71 | ||
72 | //________________________________________________________________________________________ | |
73 | const AliRsnListOutput& AliRsnListOutput::operator=(const AliRsnListOutput& copy) | |
74 | { | |
75 | // | |
76 | // Assignment operator. | |
77 | // Same consideration as the copiy constructor. In this case, there is | |
78 | // the possibility to have the output objects alreasy initialized, but | |
79 | // they are anyway reset. | |
80 | // | |
81 | ||
e6f3a909 | 82 | TNamed::operator=(copy); |
83 | if (this == ©) | |
84 | return *this; | |
85 | fSkipFailed = copy.fSkipFailed; | |
86 | fType = copy.fType; | |
87 | fSteps = copy.fSteps; | |
88 | fValues = copy.fValues; | |
89 | fNValues = copy.fNValues; | |
90 | fList = copy.fList; | |
91 | fIndex = copy.fIndex; | |
92 | fArray = copy.fArray; | |
93 | ||
c865cb1d | 94 | Reset(); |
95 | ||
96 | return (*this); | |
97 | } | |
98 | ||
99 | //__________________________________________________________________________________________________ | |
100 | AliRsnListOutput::~AliRsnListOutput() | |
101 | { | |
102 | // | |
103 | // Destructor. | |
104 | // Deletes the output objects. | |
105 | // | |
106 | ||
107 | Reset(); | |
108 | } | |
109 | ||
110 | //__________________________________________________________________________________________________ | |
111 | void AliRsnListOutput::Reset() | |
112 | { | |
113 | // | |
114 | // Clear all output objects. In general, only one will be initialized at a time. | |
115 | // | |
116 | ||
117 | fList = 0x0; | |
118 | } | |
119 | ||
120 | //_____________________________________________________________________________ | |
121 | void AliRsnListOutput::AddValue(AliRsnValue *value) | |
122 | { | |
123 | // | |
124 | // Adds a value computation object to the list. | |
125 | // | |
126 | ||
127 | fValues.AddLast(value); | |
128 | } | |
129 | ||
130 | ||
131 | //________________________________________________________________________________________ | |
132 | Bool_t AliRsnListOutput::Init(const char *prefix, TList *list) | |
133 | { | |
134 | // | |
135 | // Initializes the output for this object. | |
136 | // What kind of output depends on the 'fType' data member, | |
137 | // and in case it is a CF container, also on the 'fSteps'. | |
138 | // The object is named with the following criterion: | |
139 | // <prefix>_<name>_<type>_<varList> | |
140 | // | |
141 | ||
142 | Int_t i; | |
143 | ||
144 | // all output objects are cleared | |
145 | Reset(); | |
146 | ||
147 | // count values and set dimension of arrays | |
148 | // do also some checks for a good match between type and output | |
149 | fNValues = fValues.GetEntries(); | |
150 | if (fNValues < 1) { | |
151 | AliError("Need at least 1 value"); | |
152 | return kFALSE; | |
153 | } | |
154 | if (fType == kHistoDefault && fNValues > 3) { | |
155 | AliInfo(Form("NValues = %d > 3 --> cannot use a normal histogram, need to use a sparse", fNValues)); | |
156 | fType = kHistoSparse; | |
157 | } | |
158 | ||
159 | // resize the output array | |
160 | fArray.Set(fNValues); | |
161 | ||
162 | // create the name | |
163 | TString name(Form("%s_%s", prefix, GetName())); | |
164 | AliRsnValue *val = 0x0; | |
165 | for (i = 0; i < fNValues; i++) { | |
166 | val = GetValue(i); | |
167 | if (!val) { | |
168 | AliError(Form("Slot %d in value list is NULL", i)); | |
169 | return kFALSE; | |
170 | } | |
171 | name += '_'; | |
172 | name += val->GetName(); | |
173 | } | |
174 | ||
175 | // allowed objects | |
176 | TObject *object = 0x0; | |
177 | ||
178 | // initialize appropriate output object | |
179 | // and, if successful, insert into the list | |
180 | switch (fType) { | |
181 | case kHistoDefault: | |
182 | name.Append("_hist"); | |
183 | object = CreateHistogram(name.Data()); | |
184 | break; | |
185 | case kHistoSparse: | |
186 | name.Append("_hsparse"); | |
187 | object = CreateHistogramSparse(name.Data()); | |
188 | break; | |
189 | case kCFContainer: | |
190 | name.Append("_cf"); | |
191 | object = CreateCFContainer(name.Data()); | |
192 | break; | |
193 | default: | |
194 | AliWarning("Wrong type output or initialization failure"); | |
195 | } | |
196 | ||
197 | if (object) { | |
198 | //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())); | |
199 | fList = list; | |
200 | fList->Add(object); | |
201 | fIndex = fList->IndexOf(object); | |
202 | return kTRUE; | |
203 | } | |
204 | ||
205 | return kFALSE; | |
206 | } | |
207 | ||
208 | //________________________________________________________________________________________ | |
209 | TH1* AliRsnListOutput::CreateHistogram(const char *name) | |
210 | { | |
211 | // | |
212 | // Initialize the 'default' TH1 output object. | |
213 | // In case one of the expected axes is NULL, the initialization fails. | |
214 | // | |
215 | ||
216 | // we expect to have maximum 3 axes in this case | |
217 | Int_t i, nbins[3] = {0, 0, 0}; | |
218 | TArrayD array[3]; | |
219 | for (i = 0; i < fNValues; i++) { | |
220 | AliRsnValue *val = GetValue(i); | |
221 | if (!val) { | |
222 | AliError(Form("Expected axis %d is NULL", i)); | |
223 | return 0x0; | |
224 | } | |
225 | nbins[i] = GetValue(i)->GetArray().GetSize() - 1; | |
226 | array[i] = GetValue(i)->GetArray(); | |
227 | } | |
228 | ||
229 | TH1 *hist = 0x0; | |
230 | ||
231 | // create histogram depending on the number of axes | |
232 | switch (fNValues) { | |
233 | case 1: | |
234 | hist = new TH1F(name, "", nbins[0], array[0].GetArray()); | |
235 | break; | |
236 | case 2: | |
237 | hist = new TH2F(name, "", nbins[0], array[0].GetArray(), nbins[1], array[1].GetArray()); | |
238 | break; | |
239 | case 3: | |
240 | hist = new TH3F(name, "", nbins[0], array[0].GetArray(), nbins[1], array[1].GetArray(), nbins[2], array[2].GetArray()); | |
241 | break; | |
242 | default: | |
739706ae | 243 | //AliError(Form("Wrong number of dimensions: %d", fNValues)) |
244 | return 0x0; | |
c865cb1d | 245 | } |
246 | ||
247 | if (hist) hist->Sumw2(); | |
248 | return hist; | |
249 | } | |
250 | ||
251 | //________________________________________________________________________________________ | |
252 | THnSparseF* AliRsnListOutput::CreateHistogramSparse(const char *name) | |
253 | { | |
254 | // | |
255 | // Initialize the THnSparse output object. | |
256 | // In case one of the expected axes is NULL, the initialization fails. | |
257 | // | |
258 | ||
259 | // retrieve binnings and sizes of all axes | |
260 | // since the check for null values is done in Init(), | |
261 | // we assume that here they must all be well defined | |
262 | Int_t i, *nbins = new Int_t[fNValues]; | |
263 | TArrayD *array = new TArrayD[fNValues]; | |
264 | for (i = 0; i < fNValues; i++) { | |
265 | nbins[i] = GetValue(i)->GetArray().GetSize() - 1; | |
266 | array[i] = GetValue(i)->GetArray(); | |
267 | } | |
268 | ||
269 | // create histogram | |
270 | THnSparseF *hist = new THnSparseF(name, "", fNValues, nbins); | |
271 | hist->Sumw2(); | |
272 | ||
273 | // update the various axes using the definitions given in the array of axes here | |
274 | for (i = 0; i < fNValues; i++) { | |
275 | hist->GetAxis(i)->Set(nbins[i], array[i].GetArray()); | |
276 | } | |
277 | ||
278 | // clear heap | |
279 | delete [] nbins; | |
280 | delete [] array; | |
281 | ||
282 | return hist; | |
283 | } | |
284 | ||
285 | //________________________________________________________________________________________ | |
286 | AliCFContainer* AliRsnListOutput::CreateCFContainer(const char *name) | |
287 | { | |
288 | // | |
289 | // Initialize the AliCFContainer output object. | |
290 | // In case one of the expected axes is NULL, the initialization fails. | |
291 | // | |
292 | ||
293 | // retrieve binnings and sizes of all axes | |
294 | // since the check for null values is done in Init(), | |
295 | // we assume that here they must all be well defined | |
296 | Int_t i, *nbins = new Int_t[fNValues]; | |
297 | TArrayD *array = new TArrayD[fNValues]; | |
298 | for (i = 0; i < fNValues; i++) { | |
299 | nbins[i] = GetValue(i)->GetArray().GetSize() - 1; | |
300 | array[i] = GetValue(i)->GetArray(); | |
301 | } | |
302 | ||
303 | // create object | |
304 | AliCFContainer *cont = new AliCFContainer(name, "", fSteps, fNValues, nbins); | |
305 | ||
306 | // set the bin limits for each axis | |
307 | for (i = 0; i < fNValues; i++) { | |
308 | cont->SetBinLimits(i, array[i].GetArray()); | |
309 | } | |
310 | ||
311 | // clear heap | |
312 | delete [] nbins; | |
313 | delete [] array; | |
314 | ||
315 | return cont; | |
316 | } | |
317 | ||
318 | //________________________________________________________________________________________ | |
319 | Bool_t AliRsnListOutput::Fill(TObject *target, Int_t step) | |
320 | { | |
321 | // | |
322 | // Uses the passed argument to compute all values. | |
323 | // If all computations were successful, fill the output | |
324 | // Second argument (step) is needed only in case of CF containers. | |
325 | // Return value is the AND of all computation successes. | |
326 | // | |
327 | ||
328 | Int_t i; | |
329 | ||
330 | // do computations | |
331 | Bool_t globalOK = kTRUE; | |
332 | AliRsnValue *val = 0x0; | |
333 | for (i = 0; i < fNValues; i++) { | |
334 | val = GetValue(i); | |
335 | if (!val) { | |
336 | AliError("NULL value found"); | |
337 | return kFALSE; | |
338 | } | |
339 | globalOK = globalOK && val->Eval(target); | |
340 | fArray[i] = (Double_t)val->GetComputedValue(); | |
341 | } | |
f34f960b | 342 | if (!globalOK && fSkipFailed) return kFALSE; |
c865cb1d | 343 | |
344 | // retrieve object | |
345 | if (!fList || fIndex < 0) { | |
346 | AliError("List not initialized"); | |
347 | return kFALSE; | |
348 | } | |
349 | TObject *obj = fList->At(fIndex); | |
350 | if (!obj) { | |
351 | AliError("Null pointer"); | |
352 | return kFALSE; | |
353 | } | |
354 | ||
355 | // check | |
356 | //AliInfo(Form("[%s] Object index, name, type = %d, %s (%s)", GetName(), fIndex, obj->GetName(), obj->ClassName())); | |
357 | ||
358 | // fill output | |
359 | if (obj->IsA() == TH1F::Class()) { | |
360 | TH1F *h = (TH1F*)obj; | |
361 | h->Fill(fArray[0]); | |
362 | return kTRUE; | |
363 | } else if (obj->IsA() == TH2F::Class()) { | |
364 | TH2F *h = (TH2F*)obj; | |
365 | h->Fill(fArray[0], fArray[1]); | |
366 | return kTRUE; | |
367 | } else if (obj->IsA() == TH3F::Class()) { | |
368 | TH3F *h = (TH3F*)obj; | |
369 | h->Fill(fArray[0], fArray[1], fArray[2]); | |
370 | return kTRUE; | |
371 | } else if (obj->InheritsFrom(THnSparse::Class())) { | |
372 | THnSparseF *h = (THnSparseF*)obj; | |
373 | h->Fill(fArray.GetArray()); | |
374 | return kTRUE; | |
375 | } else if (obj->InheritsFrom(AliCFContainer::Class())) { | |
376 | AliCFContainer *c = (AliCFContainer*)obj; | |
377 | c->Fill(fArray.GetArray(), step); | |
378 | return kTRUE; | |
379 | } else { | |
380 | AliError(Form("Not handled class '%s'", obj->ClassName())); | |
381 | return kFALSE; | |
382 | } | |
383 | } |