3 // All the definitions needed for building a RSN histogram
5 // -- properties of resonance (mass, PDG code if needed)
6 // -- properties of daughters (assigned mass, charges)
7 // -- definition of output histogram
10 #include "Riostream.h"
16 #include "THnSparse.h"
18 #include "TClonesArray.h"
20 #include "AliRsnMiniParticle.h"
21 #include "AliRsnMiniPair.h"
22 #include "AliRsnMiniEvent.h"
25 #include "AliRsnCutSet.h"
26 #include "AliRsnMiniAxis.h"
27 #include "AliRsnMiniOutput.h"
28 #include "AliRsnMiniValue.h"
30 ClassImp(AliRsnMiniOutput)
32 //__________________________________________________________________________________________________
33 AliRsnMiniOutput::AliRsnMiniOutput() :
36 fComputation(kComputations),
41 fAxes("AliRsnMiniAxis", 0),
50 fCutID[0] = fCutID[1] = -1;
51 fDaughter[0] = fDaughter[1] = AliRsnDaughter::kUnknown;
52 fCharge[0] = fCharge[1] = 0;
55 //__________________________________________________________________________________________________
56 AliRsnMiniOutput::AliRsnMiniOutput(const char *name, EOutputType type, EComputation src) :
64 fAxes("AliRsnMiniAxis", 0),
73 fCutID[0] = fCutID[1] = -1;
74 fDaughter[0] = fDaughter[1] = AliRsnDaughter::kUnknown;
75 fCharge[0] = fCharge[1] = 0;
78 //__________________________________________________________________________________________________
79 AliRsnMiniOutput::AliRsnMiniOutput(const char *name, const char *outType, const char *compType) :
82 fComputation(kComputations),
87 fAxes("AliRsnMiniAxis", 0),
93 // Constructor, with a more user friendly implementation, where
94 // the user sets the type of output and computations through conventional strings:
97 // -- "HIST" --> common histogram (up to 3 dimensions)
98 // -- "SPARSE" --> sparse histogram
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)
110 // understand output type
113 if (!input.CompareTo("HIST"))
114 fOutputType = kHistogram;
115 else if (!input.CompareTo("SPARSE"))
116 fOutputType = kHistogramSparse;
118 AliWarning(Form("String '%s' does not define a meaningful output type", outType));
120 // understand computation type
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;
134 AliWarning(Form("String '%s' does not define a meaningful computation type", compType));
136 fCutID[0] = fCutID[1] = -1;
137 fDaughter[0] = fDaughter[1] = AliRsnDaughter::kUnknown;
138 fCharge[0] = fCharge[1] = 0;
141 //__________________________________________________________________________________________________
142 AliRsnMiniOutput::AliRsnMiniOutput(const AliRsnMiniOutput ©) :
144 fOutputType(copy.fOutputType),
145 fComputation(copy.fComputation),
146 fMotherPDG(copy.fMotherPDG),
147 fMotherMass(copy.fMotherMass),
148 fPairCuts(copy.fPairCuts),
149 fOutputID(copy.fOutputID),
151 fComputed(copy.fComputed),
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];
167 //__________________________________________________________________________________________________
168 AliRsnMiniOutput& AliRsnMiniOutput::operator=(const AliRsnMiniOutput ©)
171 // Assignment operator
174 fOutputType = copy.fOutputType;
175 fComputation = copy.fComputation;
176 fMotherPDG = copy.fMotherPDG;
177 fMotherMass = copy.fMotherMass;
178 fPairCuts = copy.fPairCuts;
179 fOutputID = copy.fOutputID;
181 fComputed = copy.fComputed;
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];
195 //__________________________________________________________________________________________________
196 void AliRsnMiniOutput::AddAxis(Int_t i, Int_t nbins, Double_t min, Double_t max)
199 // Create a new axis reference
202 Int_t size = fAxes.GetEntries();
203 new (fAxes[size]) AliRsnMiniAxis(i, nbins, min, max);
206 //__________________________________________________________________________________________________
207 void AliRsnMiniOutput::AddAxis(Int_t i, Double_t min, Double_t max, Double_t step)
210 // Create a new axis reference
213 Int_t size = fAxes.GetEntries();
214 new (fAxes[size]) AliRsnMiniAxis(i, min, max, step);
217 //__________________________________________________________________________________________________
218 void AliRsnMiniOutput::AddAxis(Int_t i, Int_t nbins, Double_t *values)
221 // Create a new axis reference
224 Int_t size = fAxes.GetEntries();
225 new (fAxes[size]) AliRsnMiniAxis(i, nbins, values);
228 //__________________________________________________________________________________________________
229 Bool_t AliRsnMiniOutput::Init(const char *prefix, TList *list)
232 // Initialize properly the histogram and add it to the argument list
236 AliError("Required an output list");
242 switch (fOutputType) {
244 CreateHistogram(Form("hist_%s_%s", prefix, GetName()));
246 case kHistogramSparse:
247 CreateHistogramSparse(Form("hsparse_%s_%s", prefix, GetName()));
250 AliError("Wrong output histogram definition");
255 //__________________________________________________________________________________________________
256 void AliRsnMiniOutput::CreateHistogram(const char *name)
259 // Initialize the 'default' TH1 output object.
260 // In case one of the expected axes is NULL, the initialization fails.
263 Int_t size = fAxes.GetEntries();
264 AliInfo(Form("Histogram name = '%s', with %d axes", name, size));
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];
272 // create histogram depending on the number of axes
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());
279 h1 = new TH1F(name, "", xAxis->NBins(), xAxis->BinArray());
281 AliError("No axis was initialized");
285 // switch the correct computation of errors
289 fOutputID = fList->IndexOf(h1);
293 //________________________________________________________________________________________
294 void AliRsnMiniOutput::CreateHistogramSparse(const char *name)
297 // Initialize the THnSparse output object.
298 // In case one of the expected axes is NULL, the initialization fails.
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();
311 // create fHSparseogram
312 THnSparseF *h1 = new THnSparseF(name, "", size, nbins);
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());
327 fOutputID = fList->IndexOf(h1);
331 //________________________________________________________________________________________
332 Bool_t AliRsnMiniOutput::Fill(AliRsnMiniEvent *event, TClonesArray *valueList)
335 // Compute values for event-based computations (does not use the pair)
338 // check computation type
339 if (fComputation != kEventOnly) {
340 AliError("This method can be called only for event-based computations");
344 // get computed values
345 if (!ComputeValues(event, valueList)) return kFALSE;
347 // call filling method
348 return FillHistogram();
351 //________________________________________________________________________________________
352 Bool_t AliRsnMiniOutput::Fill(const AliRsnMiniPair *pair, AliRsnMiniEvent *event, TClonesArray *valueList)
355 // Compute values for mother-based computations
358 // check computation type
359 if (fComputation != kMother) {
360 AliError("This method can be called only for mother-based computations");
364 // copy passed pair info
367 // check pair against cuts
368 if (fPairCuts) if (!fPairCuts->IsSelected(&fPair)) return kFALSE;
370 // get computed values
371 if (!ComputeValues(event, valueList)) return kFALSE;
373 // call filling method
374 return FillHistogram();
377 //________________________________________________________________________________________
378 Bool_t AliRsnMiniOutput::Fill
379 (AliRsnMiniParticle *p1, AliRsnMiniParticle *p2, AliRsnMiniEvent *event, TClonesArray *valueList)
382 // Compute values for pair-based comptuations
385 // check computation type
386 if (fComputation != kTrackPair && fComputation != kTrackPairMix && fComputation != kTruePair) {
387 AliError("This method can be called only for pair-based computations");
391 // require that the two particles are well defined
393 AliError("Required two particles");
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);
404 AliDebugClass(1, "Pair does not match definition in any order");
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) {
415 } else if (TMath::Abs(fPair.MotherPDG()) != fMotherPDG) {
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]))
422 if (p2->PDGAbs() == AliRsnDaughter::SpeciesPDG(fDaughter[0]) && p1->PDGAbs() == AliRsnDaughter::SpeciesPDG(fDaughter[1]))
424 //cout << " DECAY MATCH = " << (decayMatch ? " OK " : " NO ") << endl;
425 if (!decayMatch) return kFALSE;
428 // check pair against cuts
429 if (fPairCuts) if (!fPairCuts->IsSelected(&fPair)) return kFALSE;
431 // get computed values
432 if (!ComputeValues(event, valueList)) return kFALSE;
434 // call filling method
435 return FillHistogram();
438 //________________________________________________________________________________________
439 Bool_t AliRsnMiniOutput::ComputeValues(AliRsnMiniEvent *event, TClonesArray *valueList)
442 // Using the arguments and the internal 'fPair' data member,
443 // compute all values to be stored in the histogram
446 // check size of computed array
447 Int_t size = fAxes.GetEntries();
448 if (fComputed.GetSize() != size) fComputed.Set(size);
450 Int_t i, ival, nval = valueList->GetEntries();
452 for (i = 0; i < size; i++) {
454 AliRsnMiniAxis *axis = (AliRsnMiniAxis*)fAxes[i];
456 AliError("Null axis");
459 ival = axis->GetValueID();
460 if (ival < 0 || ival >= nval) {
461 AliError(Form("Required value #%d, while maximum is %d", ival, nval));
464 AliRsnMiniValue *val = (AliRsnMiniValue*)valueList->At(ival);
466 AliError(Form("Value in position #%d is NULL", ival));
469 // if none of the above exit points is taken, compute value
470 fComputed[i] = val->Eval(&fPair, event);
476 //________________________________________________________________________________________
477 Bool_t AliRsnMiniOutput::FillHistogram()
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.
485 // retrieve object from list
487 AliError("List pointer is NULL");
490 TObject *obj = fList->At(fOutputID);
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());
501 AliError("No output initialized");