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 **************************************************************************/
17 // *** Class AliRsnEvent ***
19 // A container for a collection of AliRsnDaughter objects from an event.
20 // Contains also the primary vertex, useful for some cuts.
21 // In order to retrieve easily the tracks which have been identified
22 // as a specific type and charge, there is an array of indexes which
23 // allows to avoid to loop on all tracks and have only the neede ones.
25 // authors: A. Pulvirenti (email: alberto.pulvirenti@ct.infn.it)
26 // M. Vala (email: martin.vala@cern.ch)
29 #include <Riostream.h>
34 #include "AliRsnDaughter.h"
35 #include "AliRsnEvent.h"
36 #include "AliRsnMCInfo.h"
40 //_____________________________________________________________________________
41 AliRsnEvent::AliRsnEvent() :
42 TNamed("rsnEvent", ""),
52 fSelPIDType(AliRsnPID::kUnknown),
54 fSelPIDMethod(AliRsnDaughter::kRealistic),
58 // Default constructor
59 // (implemented but not recommended for direct use)
63 //_____________________________________________________________________________
64 AliRsnEvent::AliRsnEvent(const AliRsnEvent &event) :
69 fPhiMean(event.fPhiMean),
75 fSelPIDType(AliRsnPID::kUnknown),
77 fSelPIDMethod(AliRsnDaughter::kRealistic),
82 // Copies all the tracks from the argument's collection
83 // to this' one, and then recreates the PID index arrays,
84 // trusting on the PID informations in the copied tracks.
87 // during track copy, counts how many faults happen
88 Int_t errors = Fill(event.fTracks);
89 if (errors) AliWarning(Form("%d errors occurred in copy", errors));
91 // fill PID index arrays
94 if (event.fNoPID) fNoPID = new AliRsnPIDIndex(* (event.fNoPID));
95 if (event.fPerfectPID) fPerfectPID = new AliRsnPIDIndex(* (event.fPerfectPID));
96 if (event.fRealisticPID) fRealisticPID = new AliRsnPIDIndex(* (event.fRealisticPID));
99 //_____________________________________________________________________________
100 AliRsnEvent& AliRsnEvent::operator= (const AliRsnEvent &event)
103 // Works in the same way as the copy constructor.
105 // copy name and title
106 SetName(event.GetName());
107 SetTitle(event.GetTitle());
109 // copy primary vertex and initialize track counter to 0
115 fPhiMean = event.fPhiMean;
118 // add tracks from array of argument
119 Int_t errors = Fill(event.fTracks);
120 if (errors) AliWarning(Form("%d errors occurred in copy", errors));
126 if (!fNoPID) fNoPID = new AliRsnPIDIndex(* (event.fNoPID));
127 else (*fNoPID) = * (event.fNoPID);
129 if (event.fPerfectPID)
131 if (!fPerfectPID) fPerfectPID = new AliRsnPIDIndex(* (event.fPerfectPID));
132 else (*fPerfectPID) = * (event.fPerfectPID);
134 if (event.fRealisticPID)
136 if (!fRealisticPID) fRealisticPID = new AliRsnPIDIndex(* (event.fRealisticPID));
137 else (*fRealisticPID) = * (event.fRealisticPID);
140 // return this object
144 //_____________________________________________________________________________
145 AliRsnEvent::~AliRsnEvent()
149 // Deletes the TClonesArray, after clearing its content.
150 // Other memory-allocating arrays are cleared by their
151 // destructor, which is automatically called from here.
155 if (fTracks) delete fTracks;
158 //_____________________________________________________________________________
159 void AliRsnEvent::Init()
162 // Initialize TClonesArray data-member.
165 fTracks = new TClonesArray("AliRsnDaughter", 1);
166 //fTracks->BypassStreamer (kFALSE);
169 //_____________________________________________________________________________
170 void AliRsnEvent::Clear(Option_t* /*option*/)
173 // Empties the collections (does not delete the objects).
174 // The track collection is emptied only at the end.
175 // Since some objects could be uninitialized, some
176 // "if" statement are used.
179 if (fTracks) fTracks->Delete();
184 delete fRealisticPID;
188 //_____________________________________________________________________________
189 AliRsnDaughter* AliRsnEvent::AddTrack(AliRsnDaughter track)
192 // Stores a new track into the array and returns
193 // a reference pointer to it (which is NULL in case of errors).
196 Int_t nextIndex = fTracks->GetEntriesFast();
197 TClonesArray &tracks = (*fTracks);
198 AliRsnDaughter *copy = new(tracks[nextIndex]) AliRsnDaughter(track);
202 //_____________________________________________________________________________
203 AliRsnDaughter* AliRsnEvent::GetTrack(Int_t index)
206 // Returns one track in the collection
207 // given the absolute index in the global TClonesArray
209 return (AliRsnDaughter*) fTracks->UncheckedAt(index);
212 //_____________________________________________________________________________
213 TArrayI* AliRsnEvent::GetCharged(Char_t sign)
216 // Returns an array with the indexes of all tracks with a given charge
217 // (arg can be '+' or '-'), irrespective of its PID.
218 // When the argument is wrong, a NULL pointer is returned.
220 if (fNoPID) return fNoPID->GetTracksArray(sign, AliRsnPID::kUnknown);
224 //_____________________________________________________________________________
225 TArrayI * AliRsnEvent::GetTracksArray
226 (AliRsnDaughter::EPIDMethod pidtype, Char_t sign, AliRsnPID::EType type)
229 // Returns an array of indexes of all tracks in this event
230 // which match the charge sign and PID type in the arguments,
231 // according to one of the allowed PID methods (perfect or realistic).
232 // It retrieves this array from the AliRsnPIDIndex data members.
233 // If the arguments are wrong a NULL pointer is returned.
238 case AliRsnDaughter::kRealistic:
241 return fRealisticPID->GetTracksArray(sign, type);
244 case AliRsnDaughter::kPerfect:
247 return fPerfectPID->GetTracksArray(sign, type);
250 case AliRsnDaughter::kNoPID:
253 return fNoPID->GetTracksArray(sign, AliRsnPID::kUnknown);
257 AliError("Handled PID methods here are only fNoPID,kPerfect and kRealistic. Nothing done.");
263 //_____________________________________________________________________________
264 void AliRsnEvent::FillPIDArrays(Int_t arraySizeInit)
267 // Initializes and fills the AliRsnPIDIndex objects containing
268 // arrays of indexes for each possible charge and PID type.
269 // This method is the unique way to do this, for safety reasons.
272 if (fNoPID) delete fNoPID;
273 if (fPerfectPID) delete fPerfectPID;
274 if (fRealisticPID) delete fRealisticPID;
275 fNoPID = new AliRsnPIDIndex(arraySizeInit);
276 fPerfectPID = new AliRsnPIDIndex(arraySizeInit);
277 fRealisticPID = new AliRsnPIDIndex(arraySizeInit);
279 // set the default type to Realistic
280 AliRsnDaughter::SetPIDMethod(AliRsnDaughter::kRealistic);
282 // loop on tracks and create references
284 Int_t i, icharge, type;
286 AliRsnMCInfo *mcinfo = 0;
287 AliRsnDaughter *track = 0;
288 TObjArrayIter iter(fTracks);
289 while ((track = (AliRsnDaughter*) iter.Next()))
291 charge = track->Charge();
292 type = (Int_t) track->PIDType(prob);
293 i = fTracks->IndexOf(track);
294 mcinfo = track->GetMCInfo();
295 if (charge > 0) icharge = 0;
296 else if (charge < 0) icharge = 1;
299 AliError("Found particle with ZERO charge!!!");
302 // add to charged array
303 fNoPID->AddIndex(i, icharge, (Int_t) AliRsnPID::kUnknown);
304 // add to realistic PID array
305 fRealisticPID->AddIndex(i, icharge, (Int_t) type);
306 // add to perfect PID array (needs MCInfo present)
309 fPerfectPID->AddIndex(i, icharge, (Int_t) AliRsnPID::InternalType(mcinfo->PDG()));
313 // adjusts the size of arrays
314 if (fNoPID) fNoPID->SetCorrectIndexSize();
315 if (fPerfectPID) fPerfectPID->SetCorrectIndexSize();
316 if (fRealisticPID) fRealisticPID->SetCorrectIndexSize();
319 //_____________________________________________________________________________
320 void AliRsnEvent::Print(Option_t *option) const
323 // Lists the details of the event, and the ones of each
325 // The options are passed to AliRsnDaughter::Print().
326 // Look at that method to understand option values.
329 cout << "...Multiplicity : " << fTracks->GetEntries() << endl;
330 cout << "...Primary vertex : " << fPVx << ' ' << fPVy << ' ' << fPVz << endl;
332 TObjArrayIter iter(fTracks);
333 AliRsnDaughter *d = 0;
334 while ((d = (AliRsnDaughter*) iter.Next()))
336 cout << "....Track #" << fTracks->IndexOf(d) << endl;
341 //_____________________________________________________________________________
342 void AliRsnEvent::MakeComputations()
345 // Computes all required overall variables:
347 // - mean phi of tracks
357 fMult = fTracks->GetEntries();
364 AliRsnDaughter *d = 0;
365 TObjArrayIter next(fTracks);
366 while ( (d = (AliRsnDaughter*)next()) ) fPhiMean += d->Phi();
367 fPhiMean /= (Double_t)fMult;
372 //_____________________________________________________________________________
373 void AliRsnEvent::CorrectByPrimaryVertex()
376 // Corrects the X,Y,Z position of DCA vertex of all tracks
377 // by the amount of stored primary vertex
380 TObjArrayIter iter(fTracks);
381 AliRsnDaughter *d = 0;
382 while ((d = (AliRsnDaughter*) iter.Next())) {
383 d->ShiftZero(fPVx, fPVy, fPVz);
388 //_____________________________________________________________________________
389 Int_t AliRsnEvent::GetMultiplicity() const
392 // Get number of all tracks
395 if (!fTracks) return 0;
396 return fTracks->GetEntries();
400 //_____________________________________________________________________________
401 Int_t AliRsnEvent::GetNCharged(Char_t sign)
404 // Get number of charged tracks
408 icharge = ChargeIndex(sign);
409 if (icharge < 0) return 0;
410 TArrayI *charged = GetCharged(sign);
411 if (!charged) return 0;
412 return charged->GetSize();
415 //_____________________________________________________________________________
416 Int_t AliRsnEvent::Fill(TObjArray *array)
419 // Fills the data-member TClonesArray of tracks with
420 // the ones stored in the array passed as argument.
421 // If this data-member is already present, it is cleared.
422 // Returns the number of tracks which raised problems
423 // while attempting to add them. Zero is the best.
426 // clear the array if it is already instantiated,
427 // create if otherwise
428 if (fTracks) fTracks->Delete();
431 // copy argument entries into data-member
433 AliRsnDaughter *track = 0;
434 TObjArrayIter iter(array);
435 while ((track = (AliRsnDaughter*) iter.Next()))
437 AliRsnDaughter *ref = AddTrack(*track);
440 AliWarning(Form("Problem occurred when copying track #%d from passed array", array->IndexOf(track)));
448 //_____________________________________________________________________________
449 Int_t AliRsnEvent::ChargeIndex(Char_t sign) const
451 // Returns the array index corresponding to charge
452 // 0 for positive, 1 for negative
455 if (sign == '+') return 0;
456 else if (sign == '-') return 1;
459 AliError(Form("Character '%c' not recognized as charge sign", sign));
463 //_____________________________________________________________________________
464 inline void AliRsnEvent::SetSelection
465 (AliRsnPID::EType pid, Char_t charge, AliRsnDaughter::EPIDMethod meth, AliRsnCutSet *cuts)
468 // Set all selection parameters at once
471 SetSelectionPIDType(pid);
472 SetSelectionCharge(charge);
473 SetSelectionPIDMethod(meth);
474 SetSelectionTrackCuts(cuts);
477 //_____________________________________________________________________________
478 AliRsnDaughter* AliRsnEvent::GetLeadingParticle(Double_t ptMin)
481 // Searches the collection of all particles with given PID type and charge,
482 // and returns the one with largest momentum, provided that it is greater than 1st argument.
483 // If one specifies AliRsnPID::kUnknown as type or AliRsnDaughter::kNoPID as method,
484 // the check is done over all particles irrespectively of their PID.
485 // If the sign argument is '+' or '-', the check is done over the particles of that charge,
486 // otherwise it is done irrespectively of the charge.
490 TArrayI *array = 0x0;
491 AliRsnDaughter *track1 = 0x0, *track2 = 0x0, *leading = 0x0;
493 if (fSelCharge == '+' || fSelCharge == '-') {
494 // if the charge '+' or '-' does simply the search
495 array = GetTracksArray(fSelPIDMethod, fSelCharge, fSelPIDType);
496 for (i = 0; i < array->GetSize(); i++) {
497 track1 = (AliRsnDaughter *) fTracks->At(array->At(i));
498 if (!track1) continue;
499 if (track1->Pt() < ptMin) continue;
500 if (!CutPass(track1)) continue;
501 ptMin = track1->Pt();
506 track1 = GetLeadingParticle(ptMin);
507 track2 = GetLeadingParticle(ptMin);
508 if (track1 && track2) {
509 if (track1->Pt() > track2->Pt()) leading = track1;
510 else leading = track2;
512 else if (track1) leading = track1;
513 else if (track2) leading = track2;
520 //_____________________________________________________________________________
521 Double_t AliRsnEvent::GetAverageMomentum(Int_t &count)
524 // Loops on the list of tracks and computes average total momentum.
528 Double_t pmean = 0.0;
529 TArrayI *array = 0x0;
530 AliRsnDaughter *d = 0x0;
532 if (fSelCharge == '+' || fSelCharge == '-') {
533 // if the charge '+' or '-' does simply the search
535 array = GetTracksArray(fSelPIDMethod, fSelCharge, fSelPIDType);
536 for (i = 0; i < array->GetSize(); i++) {
537 d = (AliRsnDaughter *) fTracks->At(array->At(i));
539 if (!CutPass(d)) continue;
543 if (count > 0) pmean /= (Double_t)count;
547 Int_t countP, countM;
548 Double_t pmeanP = GetAverageMomentum(countP);
549 Double_t pmeanM = GetAverageMomentum(countM);
550 if (countP && countM) {
551 pmean = (pmeanP * (Double_t)countP + pmeanM * (Double_t)countM) / (countP + countM);
552 count = countP + countM;
571 //_____________________________________________________________________________
572 Bool_t AliRsnEvent::GetAngleDistrWRLeading
573 (Double_t &angleMean, Double_t &angleRMS, Double_t ptMin)
576 // Takes the leading particle and computes the mean and RMS
577 // of the distribution of directions of all other tracks
578 // with respect to the direction of leading particle.
581 AliRsnDaughter *leading = GetLeadingParticle(ptMin);
582 if (!leading) return kFALSE;
585 Double_t angle, angle2Mean;
586 AliRsnDaughter *trk = 0x0;
587 TObjArrayIter next(fTracks);
589 angleMean = angle2Mean = 0.0;
591 while ( (trk = (AliRsnDaughter*)next()) )
593 if (trk == leading) continue;
595 angle = leading->AngleTo(trk);
598 angle2Mean += angle * angle;
602 if (!count) return kFALSE;
604 angleMean /= (Double_t)count;
605 angle2Mean /= (Double_t)count;
606 angleRMS = TMath::Sqrt(angle2Mean - angleMean*angleMean);