1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 //-------------------------------------------------------------------------
17 // Class AliRsnPairSimple
18 //-------------------------------------------------------------------------
19 // This class computes the invariant mass spectrum of a specified pair of
20 // particles, throughout a list of AliRsnEvents, and returns it as a TH1D.
21 // This object is not supposed to be used directly: an AliRsnAnalysis
22 // should be initialized in a macro and filled with one or more AliRsnPairSimple's
23 // which are then processed with a given sample of events.
25 // author: A. Pulvirenti
26 // email : alberto.pulvirenti@ct.infn.it
27 //-------------------------------------------------------------------------
29 #include <Riostream.h>
34 #include <TClonesArray.h>
37 #include "AliRsnMCInfo.h"
38 #include "AliRsnDaughter.h"
39 #include "AliRsnEvent.h"
40 #include "AliRsnCut.h"
41 #include "AliRsnCutMgr.h"
42 #include "AliRsnPairDef.h"
43 #include "AliRsnPID.h"
45 #include "AliRsnPairSimple.h"
47 ClassImp(AliRsnPairSimple)
49 //--------------------------------------------------------------------------------------------------------
50 AliRsnPairSimple::AliRsnPairSimple(AliRsnPairDef *pd, const char *name, const char *title) :
52 fPIDMethod(AliRsnPID::kNone),
54 fStoreOnlyTrue(kFALSE),
63 // This constructor allows to define some of the initialization values:
64 // - name and title of the object
65 // - histogram binning and edges
66 // The other parameters are initialized as in the default constructor.
69 //--------------------------------------------------------------------------------------------------------
70 AliRsnPairSimple::AliRsnPairSimple(const AliRsnPairSimple ©) :
72 fPIDMethod(copy.fPIDMethod),
73 fForMixing(copy.fForMixing),
74 fStoreOnlyTrue(copy.fStoreOnlyTrue),
77 fPairDef(copy.fPairDef),
83 // Default behavior as a copy constructor for what concerns non-array data-members.
84 // The arrays are cloned if they are not NULL.
87 //--------------------------------------------------------------------------------------------------------
88 const AliRsnPairSimple& AliRsnPairSimple::operator=(const AliRsnPairSimple ©)
91 // Assignment operator.
92 // Default behavior like copy constructor.
94 SetName(copy.GetName());
95 SetTitle(copy.GetTitle());
99 fPairDef = copy.fPairDef;
101 fPIDMethod = copy.fPIDMethod;
102 fForMixing = copy.fForMixing;
103 fStoreOnlyTrue = copy.fStoreOnlyTrue;
104 if (copy.fHistogram) fHistogram = (TH1D*)(copy.fHistogram->Clone());
110 //--------------------------------------------------------------------------------------------------------
111 void AliRsnPairSimple::Clear(Option_t* /*option*/)
114 // Clear arrays and histogram.
115 // For the sake of security, all pointers are also set explicitly to NULL.
123 //--------------------------------------------------------------------------------------------------------
124 void AliRsnPairSimple::InitHistograms()
127 // Initialize histograms
130 Int_t nbins = fPairDef->GetNBins();
131 Double_t min = fPairDef->GetMin(), max = fPairDef->GetMax();
133 if (strlen(GetName()) > 0) {
134 fHistogram = new TH1D(GetName(), GetTitle(), nbins, min, max);
135 fHistogramMC = new TH1D(Form("MC_%s", GetName()), Form("%s (MC)", GetTitle()), nbins, min, max);
138 Char_t name[200], title[200];
139 strcpy(name, GetHistName());
140 strcpy(title, GetHistTitle());
141 fHistogram = new TH1D(name, title, nbins, min, max);
142 fHistogramMC = new TH1D(Form("MC_%s", name), Form("%s (MC)", title), nbins, min, max);
145 fHistogramMC->Sumw2();
148 const char* AliRsnPairSimple::GetHistName ()
151 // Creates the histogram name, given a cut manager
155 strName.Append(AliRsnPID::ParticleName(fPairDef->GetType(0)));
157 strName += fPairDef->GetCharge(0);
160 strName.Append(AliRsnPID::ParticleName(fPairDef->GetType(1)));
162 strName += fPairDef->GetCharge(1);
166 strName.Append("cuts:");
167 strName.Append(fCuts->GetName());
170 strName.Append("NoCuts");
172 if (fStoreOnlyTrue) strName.Append("_true");
173 if (fForMixing) strName.Append("_mix");
175 return strName.Data();
178 const char* AliRsnPairSimple::GetHistTitle()
181 // Creates the histogram title, given a cut manager
184 TString strName("Inv. mass of ");
185 strName.Append(AliRsnPID::ParticleName(fPairDef->GetType(0), kFALSE));
189 strName += fPairDef->GetCharge(0);
191 strName.Append(" and ");
192 strName.Append(AliRsnPID::ParticleName(fPairDef->GetType(1), kFALSE));
196 strName += fPairDef->GetCharge(1);
199 strName.Append(" [cuts: ");
200 strName.Append(fCuts->GetTitle());
201 strName.Append("] ");
204 strName.Append(" [No cuts] ");
206 if (fStoreOnlyTrue) strName.Append(" [true pairs]");
207 if (fForMixing) strName.Append(" [event mixing]");
209 return strName.Data();
212 //--------------------------------------------------------------------------------------------------------
213 Stat_t AliRsnPairSimple::Process(AliRsnEvent *event1, AliRsnEvent *event2)
216 // Scans the two events specified in argument to fill the histogram.
217 // This method essentially calls the AliRsnPairSimple::Fill() method one or many times.
218 // When the "noPID" argument is kFALSE, the analysis is done with identified particles
219 // and this causes the Fill() method to be called only once, for the two lists of
220 // identified particles of the two kinds specified in AliRsnPairSimple datamembers.
221 // When the "noPID" argument is kTRUE, the analysis is done with all collections
222 // of particles of the same sign as specified in the two arguments of the pair.
224 // Particles of type #1 are taken in 'event1', and particles of type #2 are taken in 'event2'.
225 // When doing single-event analysis (for resonance signal or like-sign background),
226 // the second argument can be simply skipped.
227 // When doing event mixing, the two arguments must be not null and different.
228 // If argument #1 is NULL, an error is raised, while if argument #2 is NULL, no error is raised,
229 // and 'event2' argument is set equal to 'event1' (= single event processing).
231 // Return value is the total number of pairs processed.
235 // argument #1 cannot be NULL
236 AliError("Argument #1 cannot be NULL.");
240 // if argument #2 is NULL, it is put equal to argument #1
244 AliError("No pairdef defined");
248 AliError("Histograms not initialized");
252 // assign pointers to the list of indexes to be used
253 TArrayI *listCharged1 = 0x0, *listCharged2 = 0x0;
254 //if (pidMethod == AliRsnPID::kNone) {
255 listCharged1 = event1->GetCharged(fPairDef->GetCharge(0));
256 listCharged2 = event2->GetCharged(fPairDef->GetCharge(1));
259 //listCharged1 = event1->GetTracksArray(pidMethod, fPairDef->GetCharge(0), fPairDef->GetType(0));
260 //listCharged2 = event2->GetTracksArray(pidMethod, fPairDef->GetCharge(1), fPairDef->GetType(1));
262 if (!listCharged1 || !listCharged2) return 0.0;
263 TArrayI &list1 = *listCharged1;
264 TArrayI &list2 = *listCharged2;
266 Int_t i1, i2, start2;
268 AliRsnDaughter *track1 = 0x0, *track2 = 0x0;
270 // loop on particle of type 1 (in first event)
271 for (i1 = 0; i1 < list1.GetSize(); i1++) {
272 track1 = event1->GetTrack(list1[i1]);
273 //if (!track1) continue;
274 if (!fCuts->IsSelected(AliRsnCut::kParticle, track1)) continue;
275 // loop on particle of type 2 (in second event)
276 // in case we are building a like-sign histogram with particles
277 // of the same type in the same event, we must avoid that
278 // each pair is computed twice
280 if (listCharged1 == listCharged2) start2 = i1 + 1;
281 for (i2 = start2; i2 < list2.GetSize(); i2++) {
282 track2 = event2->GetTrack(list2[i2]);
283 //if (!track2) continue;
284 if (!fCuts->IsSelected(AliRsnCut::kParticle, track2)) continue;
285 nPairs += Process(track1, track2);
292 //_____________________________________________________________________________
293 Stat_t AliRsnPairSimple::Process
294 (AliRsnDaughter *track1, AliRsnDaughter *track2)
297 // Checks the single tracks and the pair against track cuts and,
298 // if the cuts are passed, fill the histograms with a weight
299 // given by the product of the appropriate PID probabilities of both.
300 // The method returns a boolean success value for eventually counting.
303 // setup pair and check pair cuts
304 fPair.SetPair(track1, track2);
305 if (!fCuts->IsSelected(AliRsnCut::kPair, &fPair)) return 0.0;
307 // if there is a request to process only the pairs born from a true resonance
308 // this is checked here
309 if (fStoreOnlyTrue && !fPair.IsTruePair(fPairDef->GetMotherPDG())) return 0.0;
311 // computation variables
312 Double_t mass1 = fPairDef->GetMass(0);
313 Double_t mass2 = fPairDef->GetMass(1);
314 Double_t invmass, invmassMC, weight;
316 // assign nominal masses to daughters
320 // if we are here, all cuts are passed - fill histograms
321 invmass = fPair.GetInvMass(mass1, mass2);
322 invmassMC = fPair.GetInvMassMC(mass1, mass2);
323 if (fPIDMethod == AliRsnPID::kNone) {
324 fHistogram->Fill(invmass);
325 fHistogramMC->Fill(invmassMC);
326 if (fPairDef->IsLikeSign() && !fPairDef->HasEqualTypes()) {
329 if (fCuts->IsSelected(AliRsnCut::kPair, &fPair)) {
330 invmass = fPair.GetInvMass(mass2, mass1);
331 invmassMC = fPair.GetInvMassMC(mass2, mass1);
332 fHistogram->Fill(invmass);
333 fHistogramMC->Fill(invmassMC);
338 weight = fPairDef->ComputeWeight(track1, track2);
340 fHistogram->Fill(invmass, weight);
341 fHistogramMC->Fill(invmassMC, weight);
343 // if we are treating a like-sign pair with different types for track #1 and #2,
344 // we must also exchange the tracks and fill again the histogram
345 if (fPairDef->IsLikeSign() && !fPairDef->HasEqualTypes()) {
348 if (fCuts->IsSelected(AliRsnCut::kPair, &fPair)) {
349 weight = fPairDef->ComputeWeight(track2, track1);
350 invmass = fPair.GetInvMass(mass2, mass1);
351 invmassMC = fPair.GetInvMassMC(mass2, mass1);
353 fHistogram->Fill(invmass, weight);
354 fHistogramMC->Fill(invmassMC, weight);