Improved functionality of AliRsnDaughterDef::MatchesDaughter()
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnFunction.cxx
CommitLineData
13f28255 1//
2// Class AliRsnFunction
3//
4// This class defines a base classe to implement a function
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//
e0baff8c 14// The user who implements a kind of computation type should inherit from
15// this class and override the virtual functions defined in it, which
13f28255 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
13f28255 22#include <TString.h>
b2b08ca2 23#include <TAxis.h>
13f28255 24
25#include "AliLog.h"
26
13f28255 27#include "AliRsnDaughter.h"
28#include "AliRsnEvent.h"
29#include "AliRsnPairDef.h"
2dab9030 30#include "AliRsnMother.h"
31#include "AliRsnValue.h"
13f28255 32
33#include "AliRsnFunction.h"
34
35ClassImp(AliRsnFunction)
36
37//________________________________________________________________________________________
11ed73f6 38AliRsnFunction::AliRsnFunction(Bool_t single, Bool_t useTH1) :
2a1c7696 39 TObject(),
40 fPairDef(0x0),
41 fAxisList("AliRsnValue", 0),
42 fPair(0x0),
43 fEvent(0x0),
11ed73f6 44 fDaughter(0x0),
45 fSingle(single),
2a1c7696 46 fUseTH1(useTH1),
47 fSize(0),
48 fH1(0x0),
49 fHSparse(0x0)
13f28255 50{
5eb970a4 51//
b2028424 52// Constructor.
5eb970a4 53//
8a22fe6f 54}
13f28255 55
56//________________________________________________________________________________________
5eb970a4 57AliRsnFunction::AliRsnFunction(const AliRsnFunction &copy) :
2a1c7696 58 TObject(copy),
59 fPairDef(copy.fPairDef),
60 fAxisList(copy.fAxisList),
61 fPair(copy.fPair),
62 fEvent(copy.fEvent),
11ed73f6 63 fDaughter(copy.fDaughter),
64 fSingle(copy.fSingle),
2a1c7696 65 fUseTH1(copy.fUseTH1),
66 fSize(copy.fSize),
67 fH1(0x0),
68 fHSparse(0x0)
13f28255 69{
5eb970a4 70//
71// Copy constructor.
72//
13f28255 73}
74
75//________________________________________________________________________________________
5eb970a4 76const AliRsnFunction& AliRsnFunction::operator=(const AliRsnFunction& copy)
13f28255 77{
5eb970a4 78//
79// Assignment operator.
80//
81
2a1c7696 82 fPairDef = copy.fPairDef;
83 fPair = copy.fPair;
84 fEvent = copy.fEvent;
11ed73f6 85 fDaughter = copy.fDaughter;
86 fSingle = copy.fSingle;
2a1c7696 87 fUseTH1 = copy.fUseTH1;
88 fSize = copy.fSize;
5eb970a4 89
2a1c7696 90 if (fH1) delete fH1;
91 fH1 = 0x0;
5eb970a4 92
2a1c7696 93 if (fHSparse) delete fHSparse;
94 fHSparse = 0x0;
95
96 return (*this);
13f28255 97}
98
99//________________________________________________________________________________________
b2028424 100const char* AliRsnFunction::GetName() const
13f28255 101{
5eb970a4 102//
103// Defines the name of this object according to
104// the function type and binning
105//
13f28255 106
2a1c7696 107 TString name("");
e0baff8c 108
2a1c7696 109 TObjArrayIter next(&fAxisList);
110 AliRsnValue *axis = 0;
13f28255 111
2a1c7696 112 while ((axis = (AliRsnValue*)next())) {
113 if (name.Length() > 1) name += '_';
114 name += axis->GetName();
115 }
13f28255 116
2a1c7696 117 return name.Data();
5eb970a4 118}
119
b2028424 120//________________________________________________________________________________________
32992791 121Bool_t AliRsnFunction::AddAxis(AliRsnValue *const axis)
5eb970a4 122{
32992791 123//
124// Try to add a new axis to this function.
125// The operation succeeds only if the related value object
11ed73f6 126// has a target compatible with the function type:
127// -- 'single' functions, for tracks/events: AliRsnDaughter or AliRsnEvent
128// -- 'not single' functions, for pairs/events : AliRsnMother or AliRsnEvent
32992791 129// otherwise the axis is not added.
130//
131// If more than 3 axes are added, switch to THnSparseF output.
132// NOTE: this can cause large files and high memory occupancy.
133//
134
2a1c7696 135 RSNTARGET target = axis->GetTargetType();
11ed73f6 136 if (target == AliRsnTarget::kDaughter && !fSingle) {
137 AliError("An axis with 'AliRsnDaughter' target is not allowed in a non-single function");
138 return kFALSE;
139 }
140 if (target == AliRsnTarget::kMother && fSingle) {
141 AliError("An axis with 'AliRsnMother' target is not allowed in a single function");
2a1c7696 142 return kFALSE;
143 }
144
145 Int_t size = fAxisList.GetEntries();
146 new(fAxisList[size]) AliRsnValue(*axis);
147
148 if (fAxisList.GetEntries() > 3) {
149 AliWarning("Adding more than 3 axes will produce a THnSparseD output.");
150 fUseTH1 = kFALSE;
151 }
152
153 return kTRUE;
13f28255 154}
155
156//________________________________________________________________________________________
eb079724 157TH1* AliRsnFunction::CreateHistogram(const char *histoName, const char *histoTitle)
13f28255 158{
5eb970a4 159//
160// Creates and returns the histogram defined using
161// arguments fo name and title, and the first histoDef for binning.
162// Variable-sized histogram binning is always called, due to use of histoDef,
163// even if the bins are equal, since they are defined in this class.
164// Eventually present histoDef's in other slots of array (1, 2) are ignored.
165//
0d73200d 166// This version produces a THnSparseF.
eb079724 167//
13f28255 168
2a1c7696 169 fSize = fAxisList.GetEntries();
170 if (!fSize) {
171 AliError("No axes defined");
172 return 0x0;
173 } else if (fSize > 3) {
174 AliError("Too many axes defined for a TH1 object");
175 return 0x0;
176 }
177
178 // retrieve binnings for main and secondary axes
179 AliRsnValue *fcnAxis;
180 TArrayD array[3];
181 for (Int_t i = 0; i < fSize; i++) {
182 fcnAxis = (AliRsnValue*)fAxisList.At(i);
183 if (!fcnAxis) {
184 AliError("Empty axis");
185 array[i].Set(2);
186 array[i][0] = -1E5;
187 array[i][1] = -1E5;
188 continue;
189 } else {
190 array[i] = fcnAxis->GetArray();
191 }
192 }
193
194 // create histogram depending on the number of axes
195 switch (fSize) {
196 case 1:
197 fH1 = new TH1F(histoName, histoTitle, array[0].GetSize() - 1, array[0].GetArray());
198 break;
199 case 2:
200 fH1 = new TH2F(histoName, histoTitle, array[0].GetSize() - 1, array[0].GetArray(), array[1].GetSize() - 1, array[1].GetArray());
201 break;
202 case 3:
203 fH1 = new TH3F(histoName, histoTitle, array[0].GetSize() - 1, array[0].GetArray(), array[1].GetSize() - 1, array[1].GetArray(), array[2].GetSize() - 1, array[2].GetArray());
204 break;
205 }
206 fH1->Sumw2();
207
208 return fH1;
eb079724 209}
210
211//________________________________________________________________________________________
0d73200d 212THnSparseF* AliRsnFunction::CreateHistogramSparse(const char *histoName, const char *histoTitle)
eb079724 213{
214//
215// Creates and returns the histogram defined using
216// arguments fo name and title, and the first histoDef for binning.
217// Variable-sized histogram binning is always called, due to use of histoDef,
218// even if the bins are equal, since they are defined in this class.
219// Eventually present histoDef's in other slots of array (1, 2) are ignored.
220//
0d73200d 221// This version produces a THnSparseF.
eb079724 222//
223
2a1c7696 224 fSize = fAxisList.GetEntries();
225 if (!fSize) {
226 AliError("No axes defined");
227 return 0x0;
228 }
229
230 // initialize the array of number of bins for each axis
231 // taking it from the stored values, while for the bins
232 // they are set as summied and defined later
233 Double_t dummyD;
234 Int_t *nbins = new Int_t[fSize];
235 AliRsnValue *fcnAxis = 0;
236 for (Int_t i = 0; i < fSize; i++) {
237 fcnAxis = (AliRsnValue*)fAxisList.At(i);
238 if (!fcnAxis) {
239 nbins[i] = 1;
240 AliError("Empty axis");
241 continue;
242 }
243 nbins[i] = fcnAxis->GetArray().GetSize() - 1;
244 }
245
246 // create histogram
247 fHSparse = new THnSparseF(histoName, histoTitle, fSize, nbins, &dummyD, &dummyD);
248 fHSparse->Sumw2();
249
250 // update the various axes using the definitions given in the array of axes here
251 for (Int_t i = 0; i < fSize; i++) {
252 fcnAxis = (AliRsnValue*)fAxisList.At(i);
253 if (!fcnAxis) {
254 AliError("Empty axis: doing unique bin betweeen -100000 and 100000");
255 continue;
256 }
257 fHSparse->SetBinEdges(i, fcnAxis->GetArray().GetArray());
258 }
259
260 delete [] nbins;
261
262 return fHSparse;
5eb970a4 263}
264
eb079724 265
5eb970a4 266//________________________________________________________________________________________
267Bool_t AliRsnFunction::Fill()
268{
269//
270// Fill function histogram with values computed from given input object.
271//
b2028424 272
2a1c7696 273 AliDebug(AliLog::kDebug + 2, "->");
274
275 Int_t i;
276 Double_t *values = new Double_t[fSize];
277 Bool_t computeOK = kFALSE;
278
279 AliRsnValue *fcnAxis = 0;
280 for (i = 0; i < fSize; i++) {
281 values[i] = 0.0;
282 fcnAxis = (AliRsnValue*)fAxisList.At(i);
283 if (!fcnAxis) continue;
284 switch (fcnAxis->GetTargetType()) {
285 case AliRsnTarget::kMother:
11ed73f6 286 if (!fSingle) {
287 fcnAxis->SetSupportObject(fPairDef);
288 computeOK = fcnAxis->Eval(fPair);
289 }
290 else {
291 AliError(Form("Allowed targets are daughters and events; cannot use axis '%s' which has target '%s'", fcnAxis->GetName(), fcnAxis->GetTargetTypeName()));
292 computeOK = kFALSE;
293 }
2a1c7696 294 break;
295 case AliRsnTarget::kEvent:
296 computeOK = fcnAxis->Eval(fEvent);
297 break;
11ed73f6 298 case AliRsnTarget::kDaughter:
299 if (fSingle) {
300 computeOK = fcnAxis->Eval(fDaughter);
301 }
302 else {
303 AliError(Form("Allowed targets are daughters and events; cannot use axis '%s' which has target '%s'", fcnAxis->GetName(), fcnAxis->GetTargetTypeName()));
304 computeOK = kFALSE;
305 }
306 break;
2a1c7696 307 default:
308 AliError(Form("Allowed targets are mothers and events; cannot use axis '%s' which has target '%s'", fcnAxis->GetName(), fcnAxis->GetTargetTypeName()));
309 computeOK = kFALSE;
310 }
311 if (computeOK) values[i] = ((Float_t)fcnAxis->GetComputedValue());
312 }
313
314 // fill histogram
315 if (fUseTH1) {
316 // check presence of output histogram
317 if (!fH1) {
318 AliError("Required a TH1 which is not initialized");
319 delete [] values;
320 return kFALSE;
321 }
322
323 // fill according to dimensions
324 switch (fSize) {
325 case 1: {
326 TH1F *h1 = (TH1F*)fH1;
327 h1->Fill(values[0]);
328 }
329 break;
330 case 2: {
331 TH2F *h2 = (TH2F*)fH1;
332 h2->Fill(values[0], values[1]);
333 }
334 break;
335 case 3: {
336 TH3F *h3 = (TH3F*)fH1;
337 h3->Fill(values[0], values[1], values[2]);
338 }
339 break;
340 default:
341 AliError(Form("Wrong size : %d", fSize));
342 delete [] values;
343 return kFALSE;
344 }
345 } else {
346 // check presence of output histogram
347 if (!fHSparse) {
348 AliError("Required a THnSparseF which is not initialized");
349 delete [] values;
350 return kFALSE;
351 }
352
353 fHSparse->Fill(values);
354 }
355
356 delete [] values;
357
358 AliDebug(AliLog::kDebug + 2, "->");
359 return kTRUE;
13f28255 360}