]>
Commit | Line | Data |
---|---|---|
03d23846 | 1 | // |
2 | // Mini-Output | |
3 | // All the definitions needed for building a RSN histogram | |
4 | // including: | |
5 | // -- properties of resonance (mass, PDG code if needed) | |
6 | // -- properties of daughters (assigned mass, charges) | |
7 | // -- definition of output histogram | |
8 | // | |
9 | ||
10 | #include "Riostream.h" | |
11 | ||
12 | #include "TH1.h" | |
13 | #include "TH2.h" | |
14 | #include "TH3.h" | |
15 | #include "TList.h" | |
16 | #include "THnSparse.h" | |
17 | #include "TString.h" | |
18 | #include "TClonesArray.h" | |
19 | ||
20 | #include "AliRsnMiniParticle.h" | |
21 | #include "AliRsnMiniPair.h" | |
22 | #include "AliRsnMiniEvent.h" | |
23 | ||
24 | #include "AliLog.h" | |
25 | #include "AliRsnCutSet.h" | |
26 | #include "AliRsnMiniAxis.h" | |
27 | #include "AliRsnMiniOutput.h" | |
28 | #include "AliRsnMiniValue.h" | |
29 | ||
30 | ClassImp(AliRsnMiniOutput) | |
31 | ||
32 | //__________________________________________________________________________________________________ | |
33 | AliRsnMiniOutput::AliRsnMiniOutput() : | |
34 | TNamed(), | |
35 | fOutputType(kTypes), | |
36 | fComputation(kComputations), | |
37 | fMotherPDG(0), | |
38 | fMotherMass(0.0), | |
39 | fPairCuts(0x0), | |
40 | fOutputID(-1), | |
41 | fAxes("AliRsnMiniAxis", 0), | |
42 | fComputed(0), | |
43 | fPair(), | |
44 | fList(0x0) | |
45 | { | |
46 | // | |
47 | // Constructor | |
48 | // | |
49 | ||
50 | fCutID[0] = fCutID[1] = -1; | |
51 | fDaughter[0] = fDaughter[1] = AliRsnDaughter::kUnknown; | |
52 | fCharge[0] = fCharge[1] = 0; | |
53 | } | |
54 | ||
55 | //__________________________________________________________________________________________________ | |
56 | AliRsnMiniOutput::AliRsnMiniOutput(const char *name, EOutputType type, EComputation src) : | |
57 | TNamed(name, ""), | |
58 | fOutputType(type), | |
59 | fComputation(src), | |
60 | fMotherPDG(0), | |
61 | fMotherMass(0.0), | |
62 | fPairCuts(0x0), | |
63 | fOutputID(-1), | |
64 | fAxes("AliRsnMiniAxis", 0), | |
65 | fComputed(0), | |
66 | fPair(), | |
67 | fList(0x0) | |
68 | { | |
69 | // | |
70 | // Constructor | |
71 | // | |
72 | ||
73 | fCutID[0] = fCutID[1] = -1; | |
74 | fDaughter[0] = fDaughter[1] = AliRsnDaughter::kUnknown; | |
75 | fCharge[0] = fCharge[1] = 0; | |
76 | } | |
77 | ||
78 | //__________________________________________________________________________________________________ | |
79 | AliRsnMiniOutput::AliRsnMiniOutput(const char *name, const char *outType, const char *compType) : | |
80 | TNamed(name, ""), | |
81 | fOutputType(kTypes), | |
82 | fComputation(kComputations), | |
83 | fMotherPDG(0), | |
84 | fMotherMass(0.0), | |
85 | fPairCuts(0x0), | |
86 | fOutputID(-1), | |
87 | fAxes("AliRsnMiniAxis", 0), | |
88 | fComputed(0), | |
89 | fPair(), | |
90 | fList(0x0) | |
91 | { | |
92 | // | |
93 | // Constructor, with a more user friendly implementation, where | |
94 | // the user sets the type of output and computations through conventional strings: | |
95 | // | |
96 | // Output: | |
97 | // -- "HIST" --> common histogram (up to 3 dimensions) | |
98 | // -- "SPARSE" --> sparse histogram | |
99 | // | |
100 | // Computation: | |
101 | // -- "EVENT" --> event-only computations | |
102 | // -- "PAIR" --> track pair computations (default) | |
103 | // -- "MIX" --> event mixing (like track pair, but different events) | |
104 | // -- "TRUE" --> true pairs (like track pair, but checking that come from same mother) | |
105 | // -- "MOTHER" --> mother (loop on MC directly for mothers --> denominator of efficiency) | |
106 | // | |
107 | ||
108 | TString input; | |
109 | ||
110 | // understand output type | |
111 | input = outType; | |
112 | input.ToUpper(); | |
113 | if (!input.CompareTo("HIST")) | |
114 | fOutputType = kHistogram; | |
115 | else if (!input.CompareTo("SPARSE")) | |
116 | fOutputType = kHistogramSparse; | |
117 | else | |
118 | AliWarning(Form("String '%s' does not define a meaningful output type", outType)); | |
119 | ||
120 | // understand computation type | |
121 | input = compType; | |
122 | input.ToUpper(); | |
123 | if (!input.CompareTo("EVENT")) | |
124 | fComputation = kEventOnly; | |
125 | else if (!input.CompareTo("PAIR")) | |
126 | fComputation = kTrackPair; | |
127 | else if (!input.CompareTo("MIX")) | |
128 | fComputation = kTrackPairMix; | |
129 | else if (!input.CompareTo("TRUE")) | |
130 | fComputation = kTruePair; | |
131 | else if (!input.CompareTo("MOTHER")) | |
132 | fComputation = kMother; | |
133 | else | |
134 | AliWarning(Form("String '%s' does not define a meaningful computation type", compType)); | |
135 | ||
136 | fCutID[0] = fCutID[1] = -1; | |
137 | fDaughter[0] = fDaughter[1] = AliRsnDaughter::kUnknown; | |
138 | fCharge[0] = fCharge[1] = 0; | |
139 | } | |
140 | ||
141 | //__________________________________________________________________________________________________ | |
142 | AliRsnMiniOutput::AliRsnMiniOutput(const AliRsnMiniOutput ©) : | |
143 | TNamed(copy), | |
144 | fOutputType(copy.fOutputType), | |
145 | fComputation(copy.fComputation), | |
146 | fMotherPDG(copy.fMotherPDG), | |
147 | fMotherMass(copy.fMotherMass), | |
148 | fPairCuts(copy.fPairCuts), | |
149 | fOutputID(copy.fOutputID), | |
150 | fAxes(copy.fAxes), | |
151 | fComputed(copy.fComputed), | |
152 | fPair(), | |
153 | fList(copy.fList) | |
154 | { | |
155 | // | |
156 | // Copy constructor | |
157 | // | |
158 | ||
159 | Int_t i; | |
160 | for (i = 0; i < 2; i++) { | |
161 | fCutID[i] = copy.fCutID[i]; | |
162 | fDaughter[i] = copy.fDaughter[i]; | |
163 | fCharge[i] = copy.fCharge[i]; | |
164 | } | |
165 | } | |
166 | ||
167 | //__________________________________________________________________________________________________ | |
168 | AliRsnMiniOutput& AliRsnMiniOutput::operator=(const AliRsnMiniOutput ©) | |
169 | { | |
170 | // | |
171 | // Assignment operator | |
172 | // | |
173 | ||
174 | fOutputType = copy.fOutputType; | |
175 | fComputation = copy.fComputation; | |
176 | fMotherPDG = copy.fMotherPDG; | |
177 | fMotherMass = copy.fMotherMass; | |
178 | fPairCuts = copy.fPairCuts; | |
179 | fOutputID = copy.fOutputID; | |
180 | fAxes = copy.fAxes; | |
181 | fComputed = copy.fComputed; | |
182 | fList = copy.fList; | |
183 | ||
184 | Int_t i; | |
185 | for (i = 0; i < 2; i++) { | |
186 | fCutID[i] = copy.fCutID[i]; | |
187 | fDaughter[i] = copy.fDaughter[i]; | |
188 | fCharge[i] = copy.fCharge[i]; | |
189 | } | |
190 | ||
191 | return (*this); | |
192 | } | |
193 | ||
194 | ||
195 | //__________________________________________________________________________________________________ | |
196 | void AliRsnMiniOutput::AddAxis(Int_t i, Int_t nbins, Double_t min, Double_t max) | |
197 | { | |
198 | // | |
199 | // Create a new axis reference | |
200 | // | |
201 | ||
202 | Int_t size = fAxes.GetEntries(); | |
203 | new (fAxes[size]) AliRsnMiniAxis(i, nbins, min, max); | |
204 | } | |
205 | ||
206 | //__________________________________________________________________________________________________ | |
207 | void AliRsnMiniOutput::AddAxis(Int_t i, Double_t min, Double_t max, Double_t step) | |
208 | { | |
209 | // | |
210 | // Create a new axis reference | |
211 | // | |
212 | ||
213 | Int_t size = fAxes.GetEntries(); | |
214 | new (fAxes[size]) AliRsnMiniAxis(i, min, max, step); | |
215 | } | |
216 | ||
217 | //__________________________________________________________________________________________________ | |
218 | void AliRsnMiniOutput::AddAxis(Int_t i, Int_t nbins, Double_t *values) | |
219 | { | |
220 | // | |
221 | // Create a new axis reference | |
222 | // | |
223 | ||
224 | Int_t size = fAxes.GetEntries(); | |
225 | new (fAxes[size]) AliRsnMiniAxis(i, nbins, values); | |
226 | } | |
227 | ||
228 | //__________________________________________________________________________________________________ | |
229 | Bool_t AliRsnMiniOutput::Init(const char *prefix, TList *list) | |
230 | { | |
231 | // | |
232 | // Initialize properly the histogram and add it to the argument list | |
233 | // | |
234 | ||
235 | if (!list) { | |
236 | AliError("Required an output list"); | |
237 | return kFALSE; | |
238 | } | |
239 | ||
240 | fList = list; | |
241 | ||
242 | switch (fOutputType) { | |
243 | case kHistogram: | |
244 | CreateHistogram(Form("hist_%s_%s", prefix, GetName())); | |
245 | return kTRUE; | |
246 | case kHistogramSparse: | |
247 | CreateHistogramSparse(Form("hsparse_%s_%s", prefix, GetName())); | |
248 | return kTRUE; | |
249 | default: | |
250 | AliError("Wrong output histogram definition"); | |
251 | return kFALSE; | |
252 | } | |
253 | } | |
254 | ||
255 | //__________________________________________________________________________________________________ | |
256 | void AliRsnMiniOutput::CreateHistogram(const char *name) | |
257 | { | |
258 | // | |
259 | // Initialize the 'default' TH1 output object. | |
260 | // In case one of the expected axes is NULL, the initialization fails. | |
261 | // | |
262 | ||
263 | Int_t size = fAxes.GetEntries(); | |
264 | AliInfo(Form("Histogram name = '%s', with %d axes", name, size)); | |
265 | ||
266 | // we expect to have maximum 3 axes in this case | |
267 | AliRsnMiniAxis *xAxis = 0x0, *yAxis = 0x0, *zAxis = 0x0; | |
268 | if (size >= 1) xAxis = (AliRsnMiniAxis*)fAxes[0]; | |
269 | if (size >= 2) yAxis = (AliRsnMiniAxis*)fAxes[1]; | |
270 | if (size >= 3) zAxis = (AliRsnMiniAxis*)fAxes[2]; | |
271 | ||
272 | // create histogram depending on the number of axes | |
273 | TH1 *h1 = 0x0; | |
274 | if (xAxis && yAxis && zAxis) { | |
275 | h1 = new TH3F(name, "", xAxis->NBins(), xAxis->BinArray(), yAxis->NBins(), yAxis->BinArray(), zAxis->NBins(), zAxis->BinArray()); | |
276 | } else if (xAxis && yAxis) { | |
277 | h1 = new TH2F(name, "", xAxis->NBins(), xAxis->BinArray(), yAxis->NBins(), yAxis->BinArray()); | |
278 | } else if (xAxis) { | |
279 | h1 = new TH1F(name, "", xAxis->NBins(), xAxis->BinArray()); | |
280 | } else { | |
281 | AliError("No axis was initialized"); | |
282 | return; | |
283 | } | |
284 | ||
285 | // switch the correct computation of errors | |
286 | if (h1 && fList) { | |
287 | h1->Sumw2(); | |
288 | fList->Add(h1); | |
289 | fOutputID = fList->IndexOf(h1); | |
290 | } | |
291 | } | |
292 | ||
293 | //________________________________________________________________________________________ | |
294 | void AliRsnMiniOutput::CreateHistogramSparse(const char *name) | |
295 | { | |
296 | // | |
297 | // Initialize the THnSparse output object. | |
298 | // In case one of the expected axes is NULL, the initialization fails. | |
299 | // | |
300 | ||
301 | // retrieve binnings and sizes of all axes | |
302 | // since the check for null values is done in Init(), | |
303 | // we assume that here they must all be well defined | |
304 | Int_t size = fAxes.GetEntries(); | |
305 | Int_t i, *nbins = new Int_t[size]; | |
306 | for (i = 0; i < size; i++) { | |
307 | AliRsnMiniAxis *axis = (AliRsnMiniAxis*)fAxes[i]; | |
308 | nbins[i] = axis->NBins(); | |
309 | } | |
310 | ||
311 | // create fHSparseogram | |
312 | THnSparseF *h1 = new THnSparseF(name, "", size, nbins); | |
313 | ||
314 | // update the various axes using the definitions given in the array of axes here | |
315 | for (i = 0; i < size; i++) { | |
316 | AliRsnMiniAxis *axis = (AliRsnMiniAxis*)fAxes[i]; | |
317 | h1->GetAxis(i)->Set(nbins[i], axis->BinArray()); | |
318 | } | |
319 | ||
320 | // clear heap | |
321 | delete [] nbins; | |
322 | ||
323 | // add to list | |
324 | if (h1 && fList) { | |
325 | h1->Sumw2(); | |
326 | fList->Add(h1); | |
327 | fOutputID = fList->IndexOf(h1); | |
328 | } | |
329 | } | |
330 | ||
331 | //________________________________________________________________________________________ | |
332 | Bool_t AliRsnMiniOutput::Fill(AliRsnMiniEvent *event, TClonesArray *valueList) | |
333 | { | |
334 | // | |
335 | // Compute values for event-based computations (does not use the pair) | |
336 | // | |
337 | ||
338 | // check computation type | |
339 | if (fComputation != kEventOnly) { | |
340 | AliError("This method can be called only for event-based computations"); | |
341 | return kFALSE; | |
342 | } | |
343 | ||
344 | // get computed values | |
345 | if (!ComputeValues(event, valueList)) return kFALSE; | |
346 | ||
347 | // call filling method | |
348 | return FillHistogram(); | |
349 | } | |
350 | ||
351 | //________________________________________________________________________________________ | |
352 | Bool_t AliRsnMiniOutput::Fill(const AliRsnMiniPair *pair, AliRsnMiniEvent *event, TClonesArray *valueList) | |
353 | { | |
354 | // | |
355 | // Compute values for mother-based computations | |
356 | // | |
357 | ||
358 | // check computation type | |
359 | if (fComputation != kMother) { | |
360 | AliError("This method can be called only for mother-based computations"); | |
361 | return kFALSE; | |
362 | } | |
363 | ||
364 | // copy passed pair info | |
365 | fPair = (*pair); | |
366 | ||
367 | // check pair against cuts | |
368 | if (fPairCuts) if (!fPairCuts->IsSelected(&fPair)) return kFALSE; | |
369 | ||
370 | // get computed values | |
371 | if (!ComputeValues(event, valueList)) return kFALSE; | |
372 | ||
373 | // call filling method | |
374 | return FillHistogram(); | |
375 | } | |
376 | ||
377 | //________________________________________________________________________________________ | |
378 | Bool_t AliRsnMiniOutput::Fill | |
379 | (AliRsnMiniParticle *p1, AliRsnMiniParticle *p2, AliRsnMiniEvent *event, TClonesArray *valueList) | |
380 | { | |
381 | // | |
382 | // Compute values for pair-based comptuations | |
383 | // | |
384 | ||
385 | // check computation type | |
386 | if (fComputation != kTrackPair && fComputation != kTrackPairMix && fComputation != kTruePair) { | |
387 | AliError("This method can be called only for pair-based computations"); | |
388 | return kFALSE; | |
389 | } | |
390 | ||
391 | // require that the two particles are well defined | |
392 | if (!p1 || !p2) { | |
393 | AliError("Required two particles"); | |
394 | return kFALSE; | |
395 | } | |
396 | ||
397 | // match check #1: first particle with first def, second particle with second def | |
398 | // match check #2: first particle with second def, second particle with first def | |
399 | if (p1->Charge() == fCharge[0] && p1->HasCutBit(fCutID[0]) && p2->Charge() == fCharge[1] && p2->HasCutBit(fCutID[1])) { | |
400 | fPair.Fill(p1, p2, GetMass(0), GetMass(1), fMotherMass); | |
401 | } else if (p1->Charge() == fCharge[1] && p1->HasCutBit(fCutID[1]) && p2->Charge() == fCharge[0] && p2->HasCutBit(fCutID[0])) { | |
402 | fPair.Fill(p2, p1, GetMass(0), GetMass(1), fMotherMass); | |
403 | } else { | |
404 | AliDebugClass(1, "Pair does not match definition in any order"); | |
405 | return kFALSE; | |
406 | } | |
407 | ||
408 | // if required, check that this is a true pair | |
409 | if (fComputation == kTruePair) { | |
410 | //cout << fPair.Mother() << ' ' << fPair.MotherPDG() << ' '; | |
411 | //cout << p1->PDG() << " (" << p1->Mother() << ") "; | |
412 | //cout << p2->PDG() << " (" << p2->Mother() << ")" << endl; | |
413 | if (fPair.Mother() < 0) { | |
414 | return kFALSE; | |
415 | } else if (TMath::Abs(fPair.MotherPDG()) != fMotherPDG) { | |
416 | return kFALSE; | |
417 | } | |
418 | //cout << fPair.Mother() << ' ' << fPair.MotherPDG() << ' ' << p1->PDG() << ' ' << p2->PDG() << endl; | |
419 | Bool_t decayMatch = kFALSE; | |
420 | if (p1->PDGAbs() == AliRsnDaughter::SpeciesPDG(fDaughter[0]) && p2->PDGAbs() == AliRsnDaughter::SpeciesPDG(fDaughter[1])) | |
421 | decayMatch = kTRUE; | |
422 | if (p2->PDGAbs() == AliRsnDaughter::SpeciesPDG(fDaughter[0]) && p1->PDGAbs() == AliRsnDaughter::SpeciesPDG(fDaughter[1])) | |
423 | decayMatch = kTRUE; | |
424 | //cout << " DECAY MATCH = " << (decayMatch ? " OK " : " NO ") << endl; | |
425 | if (!decayMatch) return kFALSE; | |
426 | } | |
427 | ||
428 | // check pair against cuts | |
429 | if (fPairCuts) if (!fPairCuts->IsSelected(&fPair)) return kFALSE; | |
430 | ||
431 | // get computed values | |
432 | if (!ComputeValues(event, valueList)) return kFALSE; | |
433 | ||
434 | // call filling method | |
435 | return FillHistogram(); | |
436 | } | |
437 | ||
438 | //________________________________________________________________________________________ | |
439 | Bool_t AliRsnMiniOutput::ComputeValues(AliRsnMiniEvent *event, TClonesArray *valueList) | |
440 | { | |
441 | // | |
442 | // Using the arguments and the internal 'fPair' data member, | |
443 | // compute all values to be stored in the histogram | |
444 | // | |
445 | ||
446 | // check size of computed array | |
447 | Int_t size = fAxes.GetEntries(); | |
448 | if (fComputed.GetSize() != size) fComputed.Set(size); | |
449 | ||
450 | Int_t i, ival, nval = valueList->GetEntries(); | |
451 | ||
452 | for (i = 0; i < size; i++) { | |
453 | fComputed[i] = 1E20; | |
454 | AliRsnMiniAxis *axis = (AliRsnMiniAxis*)fAxes[i]; | |
455 | if (!axis) { | |
456 | AliError("Null axis"); | |
457 | continue; | |
458 | } | |
459 | ival = axis->GetValueID(); | |
460 | if (ival < 0 || ival >= nval) { | |
461 | AliError(Form("Required value #%d, while maximum is %d", ival, nval)); | |
462 | continue; | |
463 | } | |
464 | AliRsnMiniValue *val = (AliRsnMiniValue*)valueList->At(ival); | |
465 | if (!val) { | |
466 | AliError(Form("Value in position #%d is NULL", ival)); | |
467 | continue; | |
468 | } | |
469 | // if none of the above exit points is taken, compute value | |
470 | fComputed[i] = val->Eval(&fPair, event); | |
471 | } | |
472 | ||
473 | return kTRUE; | |
474 | } | |
475 | ||
476 | //________________________________________________________________________________________ | |
477 | Bool_t AliRsnMiniOutput::FillHistogram() | |
478 | { | |
479 | // | |
480 | // Fills the internal histogram using the current values stored in the | |
481 | // 'fComputed' array, in the order as they are stored, up to the max | |
482 | // dimension of the initialized histogram itself. | |
483 | // | |
484 | ||
485 | // retrieve object from list | |
486 | if (!fList) { | |
487 | AliError("List pointer is NULL"); | |
488 | return kFALSE; | |
489 | } | |
490 | TObject *obj = fList->At(fOutputID); | |
491 | ||
492 | if (obj->InheritsFrom(TH1F::Class())) { | |
493 | ((TH1F*)obj)->Fill(fComputed[0]); | |
494 | } else if (obj->InheritsFrom(TH2F::Class())) { | |
495 | ((TH2F*)obj)->Fill(fComputed[0], fComputed[1]); | |
496 | } else if (obj->InheritsFrom(TH3F::Class())) { | |
497 | ((TH3F*)obj)->Fill(fComputed[0], fComputed[1], fComputed[2]); | |
498 | } else if (obj->InheritsFrom(THnSparseF::Class())) { | |
499 | ((THnSparseF*)obj)->Fill(fComputed.GetArray()); | |
500 | } else { | |
501 | AliError("No output initialized"); | |
502 | return kFALSE; | |
503 | } | |
504 | ||
505 | return kTRUE; | |
506 | } |