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>
25 #include "AliCFContainer.h"
27 #include "AliRsnValue.h"
28 #include "AliRsnLoop.h"
30 #include "AliRsnListOutput.h"
32 ClassImp(AliRsnListOutput)
34 //________________________________________________________________________________________
35 AliRsnListOutput::AliRsnListOutput(const char *name, AliRsnListOutput::EOut type) :
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.
53 //________________________________________________________________________________________
54 AliRsnListOutput::AliRsnListOutput(const AliRsnListOutput ©) :
56 fSkipFailed(copy.fSkipFailed),
59 fValues(copy.fValues),
60 fNValues(copy.fNValues),
67 // Since the pointer objects must be initialized in a second step,
68 // they are never copied, and then they are initialized to zero.
72 //________________________________________________________________________________________
73 const AliRsnListOutput& AliRsnListOutput::operator=(const AliRsnListOutput& copy)
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.
82 TNamed::operator=(copy);
84 fSkipFailed = copy.fSkipFailed;
87 fValues = copy.fValues;
88 fNValues = copy.fNValues;
98 //__________________________________________________________________________________________________
99 AliRsnListOutput::~AliRsnListOutput()
103 // Deletes the output objects.
109 //__________________________________________________________________________________________________
110 void AliRsnListOutput::Reset()
113 // Clear all output objects. In general, only one will be initialized at a time.
119 //_____________________________________________________________________________
120 void AliRsnListOutput::AddValue(AliRsnValue *value)
123 // Adds a value computation object to the list.
126 fValues.AddLast(value);
130 //________________________________________________________________________________________
131 Bool_t AliRsnListOutput::Init(const char *prefix, TList *list)
134 // Initializes the output for this object.
135 // What kind of output depends on the 'fType' data member,
136 // and in case it is a CF container, also on the 'fSteps'.
137 // The object is named with the following criterion:
138 // <prefix>_<name>_<type>_<varList>
143 // all output objects are cleared
146 // count values and set dimension of arrays
147 // do also some checks for a good match between type and output
148 fNValues = fValues.GetEntries();
150 AliError("Need at least 1 value");
153 if (fType == kHistoDefault && fNValues > 3) {
154 AliInfo(Form("NValues = %d > 3 --> cannot use a normal histogram, need to use a sparse", fNValues));
155 fType = kHistoSparse;
158 // resize the output array
159 fArray.Set(fNValues);
162 TString name(Form("%s_%s", prefix, GetName()));
163 AliRsnValue *val = 0x0;
164 for (i = 0; i < fNValues; i++) {
167 AliError(Form("Slot %d in value list is NULL", i));
171 name += val->GetName();
175 TObject *object = 0x0;
177 // initialize appropriate output object
178 // and, if successful, insert into the list
181 name.Append("_hist");
182 object = CreateHistogram(name.Data());
185 name.Append("_hsparse");
186 object = CreateHistogramSparse(name.Data());
190 object = CreateCFContainer(name.Data());
193 AliWarning("Wrong type output or initialization failure");
197 //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()));
200 fIndex = fList->IndexOf(object);
207 //________________________________________________________________________________________
208 TH1* AliRsnListOutput::CreateHistogram(const char *name)
211 // Initialize the 'default' TH1 output object.
212 // In case one of the expected axes is NULL, the initialization fails.
215 // we expect to have maximum 3 axes in this case
216 Int_t i, nbins[3] = {0, 0, 0};
218 for (i = 0; i < fNValues; i++) {
219 AliRsnValue *val = GetValue(i);
221 AliError(Form("Expected axis %d is NULL", i));
224 nbins[i] = GetValue(i)->GetArray().GetSize() - 1;
225 array[i] = GetValue(i)->GetArray();
230 // create histogram depending on the number of axes
233 hist = new TH1F(name, "", nbins[0], array[0].GetArray());
236 hist = new TH2F(name, "", nbins[0], array[0].GetArray(), nbins[1], array[1].GetArray());
239 hist = new TH3F(name, "", nbins[0], array[0].GetArray(), nbins[1], array[1].GetArray(), nbins[2], array[2].GetArray());
242 AliError(Form("Wrong number of dimensions: %d", fNValues));
246 if (hist) hist->Sumw2();
250 //________________________________________________________________________________________
251 THnSparseF* AliRsnListOutput::CreateHistogramSparse(const char *name)
254 // Initialize the THnSparse output object.
255 // In case one of the expected axes is NULL, the initialization fails.
258 // retrieve binnings and sizes of all axes
259 // since the check for null values is done in Init(),
260 // we assume that here they must all be well defined
261 Int_t i, *nbins = new Int_t[fNValues];
262 TArrayD *array = new TArrayD[fNValues];
263 for (i = 0; i < fNValues; i++) {
264 nbins[i] = GetValue(i)->GetArray().GetSize() - 1;
265 array[i] = GetValue(i)->GetArray();
269 THnSparseF *hist = new THnSparseF(name, "", fNValues, nbins);
272 // update the various axes using the definitions given in the array of axes here
273 for (i = 0; i < fNValues; i++) {
274 hist->GetAxis(i)->Set(nbins[i], array[i].GetArray());
284 //________________________________________________________________________________________
285 AliCFContainer* AliRsnListOutput::CreateCFContainer(const char *name)
288 // Initialize the AliCFContainer output object.
289 // In case one of the expected axes is NULL, the initialization fails.
292 // retrieve binnings and sizes of all axes
293 // since the check for null values is done in Init(),
294 // we assume that here they must all be well defined
295 Int_t i, *nbins = new Int_t[fNValues];
296 TArrayD *array = new TArrayD[fNValues];
297 for (i = 0; i < fNValues; i++) {
298 nbins[i] = GetValue(i)->GetArray().GetSize() - 1;
299 array[i] = GetValue(i)->GetArray();
303 AliCFContainer *cont = new AliCFContainer(name, "", fSteps, fNValues, nbins);
305 // set the bin limits for each axis
306 for (i = 0; i < fNValues; i++) {
307 cont->SetBinLimits(i, array[i].GetArray());
317 //________________________________________________________________________________________
318 Bool_t AliRsnListOutput::Fill(TObject *target, Int_t step)
321 // Uses the passed argument to compute all values.
322 // If all computations were successful, fill the output
323 // Second argument (step) is needed only in case of CF containers.
324 // Return value is the AND of all computation successes.
330 Bool_t globalOK = kTRUE;
331 AliRsnValue *val = 0x0;
332 for (i = 0; i < fNValues; i++) {
335 AliError("NULL value found");
338 globalOK = globalOK && val->Eval(target);
339 fArray[i] = (Double_t)val->GetComputedValue();
341 if (!globalOK && fSkipFailed) return kFALSE;
344 if (!fList || fIndex < 0) {
345 AliError("List not initialized");
348 TObject *obj = fList->At(fIndex);
350 AliError("Null pointer");
355 //AliInfo(Form("[%s] Object index, name, type = %d, %s (%s)", GetName(), fIndex, obj->GetName(), obj->ClassName()));
358 if (obj->IsA() == TH1F::Class()) {
359 TH1F *h = (TH1F*)obj;
362 } else if (obj->IsA() == TH2F::Class()) {
363 TH2F *h = (TH2F*)obj;
364 h->Fill(fArray[0], fArray[1]);
366 } else if (obj->IsA() == TH3F::Class()) {
367 TH3F *h = (TH3F*)obj;
368 h->Fill(fArray[0], fArray[1], fArray[2]);
370 } else if (obj->InheritsFrom(THnSparse::Class())) {
371 THnSparseF *h = (THnSparseF*)obj;
372 h->Fill(fArray.GetArray());
374 } else if (obj->InheritsFrom(AliCFContainer::Class())) {
375 AliCFContainer *c = (AliCFContainer*)obj;
376 c->Fill(fArray.GetArray(), step);
379 AliError(Form("Not handled class '%s'", obj->ClassName()));