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 **************************************************************************/
18 //_________________________________________________________________________
19 ///////////////////////////////////////////////////////////////////////////
24 // Reads particles and tracks and
25 // puts them to the AliAOD objects and eventually, if needed, buffers AliAODs in AliAODRun(s)
27 // User loops over events calling method Next. In case of success this method returns 0.
28 // In case of error or if there is no more events to read, non-0 value is returned
30 // Reading can be rewound to the beginning using method Rewind.
32 // Tracks are read to the fEventRec (contains reconstructed tracks)
33 // and fEventSim (corresponding MC simulated data) data members,
34 // that are of the type AliAOD.
36 // If a given reader has ability of reading both, reconstructed and simulated data,
37 // these are structured in AODs so a "n'th" simulated particle
38 // (the one stored in the fEventSim at slot n)
39 // corresponds to the n'th reconstructed track (the one stored in the fEventRec at slot n).
41 // The same reconstructed track can be present more than ones in the AOD,
42 // but with a different PID. In this case
43 // pointer to the corresponding MC simulated particles is also present more than ones.
44 // This situation happens if you want to read all particles
45 // with PID probability of being , e.g., pion higher than 60%
46 // and being kaon higher than 40%. Than, if a given track has probability Ppid(pi)=52% and Ppid(K)=48%
47 // than it is read twise.
49 // Provides functionality for both buffering and non-buffering reading
50 // This can be switched on/off via method SetEventBuffering(bool)
51 // The main method that inheriting classes need to implement is ReadNext()
52 // that read next event in queue.
55 // Bool_t ReadsRec() const; specifies if reader is able to read simulated particles
56 // Bool_t ReadsSim() const; specifies if reader is able to read reconstructed tracks
57 // void Rewind(); rewind reading to the beginning
59 // This class provides full functionality for reading from many sources
60 // User can provide TObjArray of TObjStrings (SetDirs method or via parameter
61 // in the constructor) which desribes paths of directories to search data in.
62 // If none specified current directory is searched.
64 // Piotr.Skowronski@cern.ch
66 ///////////////////////////////////////////////////////////////////////////
69 #include <TGliteXmlEventlist.h>
71 #include <TObjArray.h>
72 #include <TObjString.h>
77 #include "AliAODParticleCut.h"
78 #include "AliAODRun.h"
80 #include "AliReader.h"
85 /*************************************************************************************/
87 AliReader::AliReader():
89 fCuts(new TObjArray()),
99 fBufferEvents(kFALSE),
107 /*************************************************************************************/
109 AliReader::AliReader(TObjArray* dirs):
111 fCuts(new TObjArray()),
121 fBufferEvents(kFALSE),
127 //ctor with array of directories to read as parameter
129 /*************************************************************************************/
130 AliReader::AliReader(const AliReader& in):
132 fEventList((in.fEventList)?(TGliteXmlEventlist*)in.fEventList->Clone():0x0),
133 fCuts((in.fCuts)?(TObjArray*)in.fCuts->Clone():0x0),
134 fDirs((in.fDirs)?(TObjArray*)in.fDirs->Clone():0x0),
143 fBufferEvents(in.fBufferEvents),
152 AliReader::~AliReader()
162 delete fTrackCounter;
165 /*************************************************************************************/
167 AliReader& AliReader::operator=(const AliReader& in)
170 if (this == &in) return *this;
171 TNamed::operator=( (const TNamed&)in );
173 fCuts = (in.fCuts)?(TObjArray*)in.fCuts->Clone():0x0;
174 fDirs = (in.fDirs)?(TObjArray*)in.fDirs->Clone():0x0;
183 fBufferEvents = in.fBufferEvents;
190 /*************************************************************************************/
192 Int_t AliReader::Next()
194 //moves to next event
196 //if asked to read up to event nb. fLast, and it is overcome, report no more events
197 if ((fNEventsRead >= fLast) && (fLast > 0) ) return kTRUE;
199 if (fTrackCounter == 0x0)//create Track Counter
201 fTrackCounter = new TH1I("trackcounter","Track Counter",20000,0,20000);
202 fTrackCounter->SetDirectory(0x0);
205 do //if asked to read from event fFirst, rewind to it
207 if ( ReadNext() == kTRUE) //if no more evets, return it
209 }while (fNEventsRead < fFirst);
213 if (fBlend) Blend();//Mix particles order
215 if (fBufferEvents)//store events if buffering is on
217 if ( ReadsRec() && fEventRec)
218 fRunRec->SetEvent(fNEventsRead-1-fFirst,fEventRec);
219 if ( ReadsSim() && fEventSim)
220 fRunSim->SetEvent(fNEventsRead-1-fFirst,fEventSim);
224 /*************************************************************************************/
226 void AliReader::AddParticleCut(AliAODParticleCut* cut)
228 //sets the new cut. MAKES A COPY OF THE CUT !!!!
230 if (!cut) //if cut is NULL return with error
232 Error("AddParticleType","NULL pointers are not accepted any more.\nIf You want to accept all particles of this type, set an empty cut ");
235 AliAODParticleCut *c = (AliAODParticleCut*)cut->Clone();
238 /********************************************************************/
240 AliAOD* AliReader::GetEventSim(Int_t n)
242 //returns Nth event with simulated particles
243 if (ReadsSim() == kFALSE)
245 Error("GetParticleEvent","This reader is not able to provide simulated particles.");
251 if (ReadsSim() && (fRunSim == 0x0)) fRunSim = new AliAODRun();
252 if (ReadsRec() && (fRunRec == 0x0)) fRunRec = new AliAODRun();
254 if (Read(fRunSim,fRunRec))
256 Error("GetParticleEvent","Error in reading");
259 else fIsRead = kTRUE;
261 return fRunSim->GetEvent(n);
263 /********************************************************************/
265 AliAOD* AliReader::GetEventRec(Int_t n)
267 //returns Nth event with reconstructed tracks
268 if (ReadsRec() == kFALSE)
270 Error("GetTrackEvent","This reader is not able to provide recosntructed tracks.");
275 if (ReadsSim() && (fRunSim == 0x0)) fRunSim = new AliAODRun();
276 if (ReadsRec() && (fRunRec == 0x0)) fRunRec = new AliAODRun();
278 if(Read(fRunSim,fRunRec))
280 Error("GetTrackEvent","Error in reading");
283 else fIsRead = kTRUE;
285 return fRunRec->GetEvent(n);
287 /********************************************************************/
289 Int_t AliReader::GetNumberOfSimEvents()
291 //returns number of events of particles
292 if (ReadsSim() == kFALSE)
294 Error("GetNumberOfPartEvents","This reader is not able to provide simulated particles.");
300 if (ReadsSim() && (fRunSim == 0x0)) fRunSim = new AliAODRun();
301 if (ReadsRec() && (fRunRec == 0x0)) fRunRec = new AliAODRun();
303 if (Read(fRunSim,fRunRec))
305 Error("GetNumberOfPartEvents","Error in reading");
308 else fIsRead = kTRUE;
310 return fRunSim->GetNumberOfEvents();
312 /********************************************************************/
314 Int_t AliReader::GetNumberOfRecEvents()
316 //returns number of events of tracks
317 if (ReadsRec() == kFALSE)
319 Error("GetNumberOfTrackEvents","This reader is not able to provide recosntructed tracks.");
324 if (ReadsSim() && (fRunSim == 0x0)) fRunSim = new AliAODRun();
325 if (ReadsRec() && (fRunRec == 0x0)) fRunRec = new AliAODRun();
327 if(Read(fRunSim,fRunRec))
329 Error("GetNumberOfTrackEvents","Error in reading");
332 else fIsRead = kTRUE;
334 return fRunRec->GetNumberOfEvents();
336 /********************************************************************/
338 Int_t AliReader::Read(AliAODRun* particles, AliAODRun *tracks)
340 //reads data and puts put to the particles and tracks objects
341 //reurns 0 if everything is OK
345 if ( ReadsSim() && (particles == 0x0) ) //check if an object is instatiated
347 Error("Read"," particles object must be instatiated before passing it to the reader");
350 if ( ReadsRec() && (tracks == 0x0) ) //check if an object is instatiated
352 Error("Read"," tracks object must be instatiated before passing it to the reader");
356 if (ReadsSim()) particles->Reset();//clear runs == delete all old events
357 if (ReadsRec()) tracks->Reset();
362 while(Next() == kFALSE)
364 if (ReadsRec()) tracks->SetEvent(i,fEventRec);
365 if (ReadsSim()) particles->SetEvent(i,fEventSim);
370 /*************************************************************************************/
372 Bool_t AliReader::Rejected(AliVAODParticle* p)
374 //Method examines whether particle meets all cut and particle type criteria
376 if(p==0x0)//of corse we not pass NULL pointers
378 Warning("Rejected()","No Pasaran! We never accept NULL pointers");
381 //if no particle is specified, we pass all particles
382 //excluding NULL pointers, of course
383 if ( fCuts->GetEntriesFast() == 0 ) return kFALSE; //if no cut specified accept all particles
384 for(Int_t i=0; i<fCuts->GetEntriesFast(); i++)
386 AliAODParticleCut &cut = *((AliAODParticleCut*)fCuts->At(i));
387 if(!cut.Rejected(p)) return kFALSE; //accepted
390 return kTRUE;//not accepted
392 /*************************************************************************************/
394 Bool_t AliReader::Rejected(Int_t pid)
396 //this method checks if any of existing cuts accepts this pid particles
397 //or any cuts accepts all particles
402 if ( fCuts->GetEntriesFast() == 0 ) return kFALSE; //if no cut specified accept all particles
404 for(Int_t i=0; i<fCuts->GetEntriesFast(); i++)
406 AliAODParticleCut &cut = *((AliAODParticleCut*)fCuts->At(i));
407 //if some of cuts accepts all particles or some accepts particles of this type, accept
408 if ( (cut.GetPID() == 0) || (cut.GetPID() == pid) ) return kFALSE;
412 /*************************************************************************************/
414 TString AliReader::GetDirName(Int_t entry)
416 //returns directory name of next one to read
417 TString retval;//return value
432 if ( (entry >= fDirs->GetEntries()) || (entry < 0))//if out of bounds return empty string
433 { //note that entry==0 is accepted even if array is empty (size=0)
434 if ( (fDirs->GetEntries() == 0) && (entry == 0) )
439 AliDebug(1,Form("Index %d out of bounds",entry));
445 TClass *objclass = fDirs->At(entry)->IsA();
446 TClass *stringclass = TObjString::Class();
448 TObjString *dir = (TObjString*)objclass->DynamicCast(stringclass,fDirs->At(entry));
452 Error("GetDirName","Object in TObjArray is not a TObjString or its descendant");
455 AliDebug(1,Form("Returned ok %s",dir->String().Data()));
456 retval = dir->String();
459 /*************************************************************************************/
461 void AliReader::Blend()
463 //randomly change positions of the particles after reading
464 //is used to check if some distributions (of many particle properties)
465 //depend on the order of particles
466 //(tracking gives particles Pt sorted)
471 npart = fEventSim->GetNumberOfParticles();
476 npart = fEventRec->GetNumberOfParticles();
482 for (Int_t i = 2; i < npart; i++)
484 Int_t with = gRandom->Integer(i);
485 // Info("Blend","%d %d",i, with);
486 if (fEventSim) fEventSim->SwapParticles(i,with);
487 if (fEventRec) fEventRec->SwapParticles(i,with);
490 /*************************************************************************************/
492 void AliReader::WriteTrackCounter() const
494 //writes the counter histogram
496 if (fTrackCounter) fTrackCounter->Write(0,TObject::kOverwrite);
499 Warning("WriteTrackCounter","Counter is NULL");