2 // Class AliRsnListOutput
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)
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
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.
19 // author: A. Pulvirenti (email: alberto.pulvirenti@ct.infn.it)
22 #include <Riostream.h>
26 #include "AliRsnValue.h"
27 #include "AliRsnLoop.h"
29 #include "AliRsnListOutput.h"
31 ClassImp(AliRsnListOutput)
33 //________________________________________________________________________________________
34 AliRsnListOutput::AliRsnListOutput(const char *name, AliRsnListOutput::EOut type) :
47 // Requires a name for this object (which will be used to name the output object)
48 // and the definition of the output type from the built-in enumeration.
52 //________________________________________________________________________________________
53 AliRsnListOutput::AliRsnListOutput(const AliRsnListOutput ©) :
55 fSkipFailed(copy.fSkipFailed),
58 fValues(copy.fValues),
59 fNValues(copy.fNValues),
66 // Since the pointer objects must be initialized in a second step,
67 // they are never copied, and then they are initialized to zero.
71 //________________________________________________________________________________________
72 const AliRsnListOutput& AliRsnListOutput::operator=(const AliRsnListOutput& copy)
75 // Assignment operator.
76 // Same consideration as the copiy constructor. In this case, there is
77 // the possibility to have the output objects alreasy initialized, but
78 // they are anyway reset.
81 TNamed::operator=(copy);
83 fSkipFailed = copy.fSkipFailed;
86 fValues = copy.fValues;
87 fNValues = copy.fNValues;
97 //__________________________________________________________________________________________________
98 AliRsnListOutput::~AliRsnListOutput()
102 // Deletes the output objects.
108 //__________________________________________________________________________________________________
109 void AliRsnListOutput::Reset()
112 // Clear all output objects. In general, only one will be initialized at a time.
118 //_____________________________________________________________________________
119 void AliRsnListOutput::AddValue(AliRsnValue *value)
122 // Adds a value computation object to the list.
125 fValues.AddLast(value);
129 //________________________________________________________________________________________
130 Bool_t AliRsnListOutput::Init(const char *prefix, TList *list)
133 // Initializes the output for this object.
134 // What kind of output depends on the 'fType' data member,
135 // and in case it is a CF container, also on the 'fSteps'.
136 // The object is named with the following criterion:
137 // <prefix>_<name>_<type>_<varList>
142 // all output objects are cleared
145 // count values and set dimension of arrays
146 // do also some checks for a good match between type and output
147 fNValues = fValues.GetEntries();
149 AliError("Need at least 1 value");
152 if (fType == kHistoDefault && fNValues > 3) {
153 AliInfo(Form("NValues = %d > 3 --> cannot use a normal histogram, need to use a sparse", fNValues));
154 fType = kHistoSparse;
157 // resize the output array
158 fArray.Set(fNValues);
161 TString name(Form("%s_%s", prefix, GetName()));
162 AliRsnValue *val = 0x0;
163 for (i = 0; i < fNValues; i++) {
166 AliError(Form("Slot %d in value list is NULL", i));
170 name += val->GetName();
174 TObject *object = 0x0;
176 // initialize appropriate output object
177 // and, if successful, insert into the list
180 name.Append("_hist");
181 object = CreateHistogram(name.Data());
184 name.Append("_hsparse");
185 object = CreateHistogramSparse(name.Data());
189 object = CreateCFContainer(name.Data());
192 AliWarning("Wrong type output or initialization failure");
196 //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 fIndex = fList->IndexOf(object);
206 //________________________________________________________________________________________
207 TH1* AliRsnListOutput::CreateHistogram(const char *name)
210 // Initialize the 'default' TH1 output object.
211 // In case one of the expected axes is NULL, the initialization fails.
214 // we expect to have maximum 3 axes in this case
215 Int_t i, nbins[3] = {0, 0, 0};
217 for (i = 0; i < fNValues; i++) {
218 AliRsnValue *val = GetValue(i);
220 AliError(Form("Expected axis %d is NULL", i));
223 nbins[i] = GetValue(i)->GetArray().GetSize() - 1;
224 array[i] = GetValue(i)->GetArray();
229 // create histogram depending on the number of axes
232 hist = new TH1F(name, "", nbins[0], array[0].GetArray());
235 hist = new TH2F(name, "", nbins[0], array[0].GetArray(), nbins[1], array[1].GetArray());
238 hist = new TH3F(name, "", nbins[0], array[0].GetArray(), nbins[1], array[1].GetArray(), nbins[2], array[2].GetArray());
241 AliError(Form("Wrong number of dimensions: %d", fNValues))
245 if (hist) hist->Sumw2();
249 //________________________________________________________________________________________
250 THnSparseF* AliRsnListOutput::CreateHistogramSparse(const char *name)
253 // Initialize the THnSparse output object.
254 // In case one of the expected axes is NULL, the initialization fails.
257 // retrieve binnings and sizes of all axes
258 // since the check for null values is done in Init(),
259 // we assume that here they must all be well defined
260 Int_t i, *nbins = new Int_t[fNValues];
261 TArrayD *array = new TArrayD[fNValues];
262 for (i = 0; i < fNValues; i++) {
263 nbins[i] = GetValue(i)->GetArray().GetSize() - 1;
264 array[i] = GetValue(i)->GetArray();
268 THnSparseF *hist = new THnSparseF(name, "", fNValues, nbins);
271 // update the various axes using the definitions given in the array of axes here
272 for (i = 0; i < fNValues; i++) {
273 hist->GetAxis(i)->Set(nbins[i], array[i].GetArray());
283 //________________________________________________________________________________________
284 AliCFContainer* AliRsnListOutput::CreateCFContainer(const char *name)
287 // Initialize the AliCFContainer output object.
288 // In case one of the expected axes is NULL, the initialization fails.
291 // retrieve binnings and sizes of all axes
292 // since the check for null values is done in Init(),
293 // we assume that here they must all be well defined
294 Int_t i, *nbins = new Int_t[fNValues];
295 TArrayD *array = new TArrayD[fNValues];
296 for (i = 0; i < fNValues; i++) {
297 nbins[i] = GetValue(i)->GetArray().GetSize() - 1;
298 array[i] = GetValue(i)->GetArray();
302 AliCFContainer *cont = new AliCFContainer(name, "", fSteps, fNValues, nbins);
304 // set the bin limits for each axis
305 for (i = 0; i < fNValues; i++) {
306 cont->SetBinLimits(i, array[i].GetArray());
316 //________________________________________________________________________________________
317 Bool_t AliRsnListOutput::Fill(TObject *target, Int_t step)
320 // Uses the passed argument to compute all values.
321 // If all computations were successful, fill the output
322 // Second argument (step) is needed only in case of CF containers.
323 // Return value is the AND of all computation successes.
329 Bool_t globalOK = kTRUE;
330 AliRsnValue *val = 0x0;
331 for (i = 0; i < fNValues; i++) {
334 AliError("NULL value found");
337 globalOK = globalOK && val->Eval(target);
338 fArray[i] = (Double_t)val->GetComputedValue();
340 if (!globalOK && fSkipFailed) return kFALSE;
343 if (!fList || fIndex < 0) {
344 AliError("List not initialized");
347 TObject *obj = fList->At(fIndex);
349 AliError("Null pointer");
354 //AliInfo(Form("[%s] Object index, name, type = %d, %s (%s)", GetName(), fIndex, obj->GetName(), obj->ClassName()));
357 if (obj->IsA() == TH1F::Class()) {
358 TH1F *h = (TH1F*)obj;
361 } else if (obj->IsA() == TH2F::Class()) {
362 TH2F *h = (TH2F*)obj;
363 h->Fill(fArray[0], fArray[1]);
365 } else if (obj->IsA() == TH3F::Class()) {
366 TH3F *h = (TH3F*)obj;
367 h->Fill(fArray[0], fArray[1], fArray[2]);
369 } else if (obj->InheritsFrom(THnSparse::Class())) {
370 THnSparseF *h = (THnSparseF*)obj;
371 h->Fill(fArray.GetArray());
373 } else if (obj->InheritsFrom(AliCFContainer::Class())) {
374 AliCFContainer *c = (AliCFContainer*)obj;
375 c->Fill(fArray.GetArray(), step);
378 AliError(Form("Not handled class '%s'", obj->ClassName()));