1 /**************************************************************************
2 * Copyright(c) 1998-2007, 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 //-------------------------------------------------------------------------
20 // Author: Markus Oldenburg, CERN
21 //-------------------------------------------------------------------------
26 #include <TFriendElement.h>
27 #include <TProcessID.h>
28 #include <TCollection.h>
29 #include "Riostream.h"
30 #include "AliAODEvent.h"
31 #include "AliAODHeader.h"
32 #include "AliAODTrack.h"
33 #include "AliAODDimuon.h"
37 // definition of std AOD member names
38 const char* AliAODEvent::fAODListName[kAODListN] = {"header",
55 //______________________________________________________________________________
56 AliAODEvent::AliAODEvent() :
58 fAODObjects(new TList()),
77 // default constructor
80 //______________________________________________________________________________
81 AliAODEvent::AliAODEvent(const AliAODEvent& aod):
83 fAODObjects(new TList()),
86 fHeader(new AliAODHeader(*aod.fHeader)),
87 fTracks(new TClonesArray(*aod.fTracks)),
88 fVertices(new TClonesArray(*aod.fVertices)),
89 fV0s(new TClonesArray(*aod.fV0s)),
90 fCascades(new TClonesArray(*aod.fCascades)),
91 fTracklets(new AliAODTracklets(*aod.fTracklets)),
92 fJets(new TClonesArray(*aod.fJets)),
93 fEmcalCells(new AliAODCaloCells(*aod.fEmcalCells)),
94 fPhosCells(new AliAODCaloCells(*aod.fPhosCells)),
95 fCaloClusters(new TClonesArray(*aod.fCaloClusters)),
96 fFmdClusters(new TClonesArray(*aod.fFmdClusters)),
97 fPmdClusters(new TClonesArray(*aod.fPmdClusters)),
98 fDimuons(new TClonesArray(*aod.fDimuons)),
99 fAODVZERO(new AliAODVZERO(*aod.fAODVZERO)),
100 fAODZDC(new AliAODZDC(*aod.fAODZDC))
105 AddObject(fVertices);
107 AddObject(fCascades);
108 AddObject(fTracklets);
110 AddObject(fEmcalCells);
111 AddObject(fPhosCells);
112 AddObject(fCaloClusters);
113 AddObject(fFmdClusters);
114 AddObject(fPmdClusters);
116 AddObject(fAODVZERO);
118 fConnected = aod.fConnected;
123 //______________________________________________________________________________
124 AliAODEvent & AliAODEvent::operator=(const AliAODEvent& aod) {
126 // Assignment operator
128 if(&aod == this) return *this;
129 AliVEvent::operator=(aod);
131 // This assumes that the list is already created
132 // and that the virtual void Copy(Tobject&) function
133 // is correctly implemented in the derived class
134 // otherwise only TObject::Copy() will be used
136 if((fAODObjects->GetSize()==0)&&(aod.fAODObjects->GetSize()>=kAODListN)){
137 // We cover the case that we do not yet have the
138 // standard content but the source has it
142 // Here we have the standard content without user additions, but the content is
143 // not matching the aod source.
145 // Iterate the list of source objects
146 TIter next(aod.GetList());
149 while ((its = next())) {
150 name = its->GetName();
151 // Check if we have this object type in out list
152 TObject *mine = fAODObjects->FindObject(name);
154 // We have to create the same type of object.
155 TClass* pClass=TClass::GetClass(its->ClassName());
157 AliWarning(Form("Can not find class description for entry %s (%s)\n",
158 its->ClassName(), name.Data()));
161 mine=(TObject*)pClass->New();
163 // not in this: can be added to list
164 AliWarning(Form("%s:%d Could not find %s for copying \n",
165 (char*)__FILE__,__LINE__,name.Data()));
168 if(mine->InheritsFrom("TNamed")) {
169 ((TNamed*)mine)->SetName(name);
170 } else if(mine->InheritsFrom("TCollection")){
171 if(mine->InheritsFrom("TClonesArray")) {
172 TClonesArray *itscl = dynamic_cast<TClonesArray*>(its);
174 AliWarning(Form("Class description for entry %s (%s) not TClonesArray\n",
175 its->ClassName(), name.Data()));
179 dynamic_cast<TClonesArray*>(mine)->SetClass(itscl->GetClass(), itscl->GetSize());
181 dynamic_cast<TCollection*>(mine)->SetName(name);
183 AliDebug(1, Form("adding object %s of type %s", mine->GetName(), mine->ClassName()));
186 // Now we have an object of the same type and name, but different content.
187 if(!its->InheritsFrom("TCollection")){
188 // simple objects (do they have a Copy method that calls operator= ?)
190 } else if (its->InheritsFrom("TClonesArray")) {
191 // Create or expand the tclonesarray pointers
192 // so we can directly copy to the object
193 TClonesArray *its_tca = (TClonesArray*)its;
194 TClonesArray *mine_tca = (TClonesArray*)mine;
195 // this leaves the capacity of the TClonesArray the same
196 // except for a factor of 2 increase when size > capacity
197 // does not release any memory occupied by the tca
198 Int_t its_entries = its_tca->GetEntriesFast();
199 mine_tca->ExpandCreate(its_entries);
200 for(int i=0; i<its_entries; i++){
202 TObject *mine_tca_obj = mine_tca->At(i);
203 TObject *its_tca_obj = its_tca->At(i);
204 // no need to delete first
205 // pointers within the class should be handled by Copy()...
206 // Can there be Empty slots?
207 its_tca_obj->Copy(*mine_tca_obj);
210 AliWarning(Form("%s:%d cannot copy TCollection \n",
211 (char*)__FILE__,__LINE__));
214 fConnected = aod.fConnected;
219 //______________________________________________________________________________
220 AliAODEvent::~AliAODEvent()
223 if(!fConnected) delete fAODObjects;
227 //______________________________________________________________________________
228 void AliAODEvent::AddObject(TObject* obj)
230 // Add an object to the list of objects.
231 // Please be aware that in order to increase performance you should
232 // refrain from using TObjArrays (if possible). Use TClonesArrays, instead.
234 if ( !fAODObjects->FindObject(obj) )
236 fAODObjects->AddLast(obj);
240 //______________________________________________________________________________
241 void AliAODEvent::RemoveObject(TObject* obj)
243 // Removes an object from the list of objects.
245 fAODObjects->Remove(obj);
248 //______________________________________________________________________________
249 TObject *AliAODEvent::FindListObject(const char *objName) const
251 // Return the pointer to the object with the given name.
253 return fAODObjects->FindObject(objName);
256 //______________________________________________________________________________
257 void AliAODEvent::CreateStdContent()
259 // create the standard AOD content and set pointers
261 // create standard objects and add them to the TList of objects
262 AddObject(new AliAODHeader());
263 AddObject(new TClonesArray("AliAODTrack", 0));
264 AddObject(new TClonesArray("AliAODVertex", 0));
265 AddObject(new TClonesArray("AliAODv0", 0));
266 AddObject(new TClonesArray("AliAODcascade", 0));
267 AddObject(new AliAODTracklets());
268 AddObject(new TClonesArray("AliAODJet", 0));
269 AddObject(new AliAODCaloCells());
270 AddObject(new AliAODCaloCells());
271 AddObject(new TClonesArray("AliAODCaloCluster", 0));
272 AddObject(new TClonesArray("AliAODFmdCluster", 0));
273 AddObject(new TClonesArray("AliAODPmdCluster", 0));
274 AddObject(new TClonesArray("AliAODDimuon", 0));
275 AddObject(new AliAODVZERO());
276 AddObject(new AliAODZDC());
280 // read back pointers
286 void AliAODEvent::MakeEntriesReferencable()
288 // Make all entries referencable in a subsequent process
290 TIter next(fAODObjects);
292 while ((obj = next()))
294 if(obj->InheritsFrom("TCollection"))
296 AssignIDtoCollection((TCollection*)obj);
301 //______________________________________________________________________________
302 void AliAODEvent::SetStdNames()
304 // introduce the standard naming
306 if(fAODObjects->GetEntries()==kAODListN){
307 for(int i = 0;i < fAODObjects->GetEntries();i++){
308 TObject *fObj = fAODObjects->At(i);
309 if(fObj->InheritsFrom("TNamed")){
310 ((TNamed*)fObj)->SetName(fAODListName[i]);
312 else if(fObj->InheritsFrom("TClonesArray")){
313 ((TClonesArray*)fObj)->SetName(fAODListName[i]);
318 printf("%s:%d SetStdNames() Wrong number of Std Entries \n",(char*)__FILE__,__LINE__);
322 void AliAODEvent::CreateStdFolders()
324 // Create the standard folder structure
325 if(fAODFolder)delete fAODFolder;
326 fAODFolder = gROOT->GetRootFolder()->AddFolder("AOD", "AOD");
327 if(fAODObjects->GetEntries()==kAODListN){
328 for(int i = 0;i < fAODObjects->GetEntries();i++){
329 TObject *fObj = fAODObjects->At(i);
330 if(fObj->InheritsFrom("TClonesArray")){
331 fAODFolder->AddFolder(fAODListName[i], fAODListName[i], (TCollection*) fObj);
333 fAODFolder->AddFolder(fAODListName[i], fAODListName[i], 0);
338 printf("%s:%d CreateStdFolders() Wrong number of Std Entries \n",(char*)__FILE__,__LINE__);
342 //______________________________________________________________________________
343 void AliAODEvent::GetStdContent()
345 // set pointers for standard content
347 fHeader = (AliAODHeader*)fAODObjects->FindObject("header");
348 fTracks = (TClonesArray*)fAODObjects->FindObject("tracks");
349 fVertices = (TClonesArray*)fAODObjects->FindObject("vertices");
350 fV0s = (TClonesArray*)fAODObjects->FindObject("v0s");
351 fCascades = (TClonesArray*)fAODObjects->FindObject("cascades");
352 fTracklets = (AliAODTracklets*)fAODObjects->FindObject("tracklets");
353 fJets = (TClonesArray*)fAODObjects->FindObject("jets");
354 fEmcalCells = (AliAODCaloCells*)fAODObjects->FindObject("emcalCells");
355 fPhosCells = (AliAODCaloCells*)fAODObjects->FindObject("phosCells");
356 fCaloClusters = (TClonesArray*)fAODObjects->FindObject("caloClusters");
357 fFmdClusters = (TClonesArray*)fAODObjects->FindObject("fmdClusters");
358 fPmdClusters = (TClonesArray*)fAODObjects->FindObject("pmdClusters");
359 fDimuons = (TClonesArray*)fAODObjects->FindObject("dimuons");
360 fAODVZERO = (AliAODVZERO*)fAODObjects->FindObject("AliAODVZERO");
361 fAODZDC = (AliAODZDC*)fAODObjects->FindObject("AliAODZDC");
364 //______________________________________________________________________________
365 void AliAODEvent::ResetStd(Int_t trkArrSize,
368 Int_t cascadeArrSize,
376 // deletes content of standard arrays and resets size
380 if (trkArrSize > fTracks->GetSize())
381 fTracks->Expand(trkArrSize);
385 if (vtxArrSize > fVertices->GetSize())
386 fVertices->Expand(vtxArrSize);
390 if (v0ArrSize > fV0s->GetSize())
391 fV0s->Expand(v0ArrSize);
395 if (cascadeArrSize > fCascades->GetSize())
396 fCascades->Expand(cascadeArrSize);
400 if (jetSize > fJets->GetSize())
401 fJets->Expand(jetSize);
404 fCaloClusters->Delete();
405 if (caloClusSize > fCaloClusters->GetSize())
406 fCaloClusters->Expand(caloClusSize);
409 fFmdClusters->Delete();
410 if (fmdClusSize > fFmdClusters->GetSize())
411 fFmdClusters->Expand(fmdClusSize);
414 fPmdClusters->Delete();
415 if (pmdClusSize > fPmdClusters->GetSize())
416 fPmdClusters->Expand(pmdClusSize);
420 if (dimuonArrSize > fDimuons->GetSize())
421 fDimuons->Expand(dimuonArrSize);
424 fTracklets->DeleteContainer();
426 fPhosCells->DeleteContainer();
428 fEmcalCells->DeleteContainer();
431 void AliAODEvent::ClearStd()
433 // clears the standard arrays
439 fVertices ->Delete();
443 fCascades ->Delete();
445 fTracklets ->DeleteContainer();
449 fEmcalCells ->DeleteContainer();
451 fPhosCells ->DeleteContainer();
453 fCaloClusters ->Delete();
455 fFmdClusters ->Clear();
457 fPmdClusters ->Clear();
462 //_________________________________________________________________
463 Int_t AliAODEvent::GetPHOSClusters(TRefArray *clusters) const
465 // fills the provided TRefArray with all found phos clusters
469 AliAODCaloCluster *cl = 0;
470 Bool_t first = kTRUE;
471 for (Int_t i = 0; i < GetNumberOfCaloClusters() ; i++) {
472 if ( (cl = GetCaloCluster(i)) ) {
475 new (clusters) TRefArray(TProcessID::GetProcessWithUID(cl));
479 //printf("IsPHOS cluster %d, E %2.3f Size: %d \n",i,cl->E(),clusters->GetEntriesFast());
483 return clusters->GetEntriesFast();
486 //_________________________________________________________________
487 Int_t AliAODEvent::GetEMCALClusters(TRefArray *clusters) const
489 // fills the provided TRefArray with all found emcal clusters
492 AliAODCaloCluster *cl = 0;
493 Bool_t first = kTRUE;
494 for (Int_t i = 0; i < GetNumberOfCaloClusters(); i++) {
495 if ( (cl = GetCaloCluster(i)) ) {
498 new (clusters) TRefArray(TProcessID::GetProcessWithUID(cl));
502 //printf("IsEMCal cluster %d, E %2.3f Size: %d \n",i,cl->E(),clusters->GetEntriesFast());
506 return clusters->GetEntriesFast();
510 //______________________________________________________________________________
511 Int_t AliAODEvent::GetMuonTracks(TRefArray *muonTracks) const
513 // fills the provided TRefArray with all found muon tracks
517 AliAODTrack *track = 0;
518 for (Int_t iTrack = 0; iTrack < GetNTracks(); iTrack++) {
519 track = GetTrack(iTrack);
520 if (track->IsMuonTrack()) {
521 muonTracks->Add(track);
525 return muonTracks->GetEntriesFast();
529 //______________________________________________________________________________
530 Int_t AliAODEvent::GetNumberOfMuonTracks() const
532 // get number of muon tracks
534 for (Int_t iTrack = 0; iTrack < GetNTracks(); iTrack++) {
535 if ((GetTrack(iTrack))->IsMuonTrack()) {
543 //______________________________________________________________________________
544 void AliAODEvent::ReadFromTree(TTree *tree, Option_t* opt /*= ""*/)
546 // Connects aod event to tree
549 AliWarning("Zero Pointer to Tree \n");
553 if(!tree->GetTree())tree->LoadTree(0);
555 // Try to find AliAODEvent
556 AliAODEvent *aodEvent = 0;
557 aodEvent = (AliAODEvent*)tree->GetTree()->GetUserInfo()->FindObject("AliAODEvent");
559 // This event is connected to the tree by definition, just say so
560 aodEvent->SetConnected();
561 // Check if already connected to tree
562 TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("AODObjectsConnectedToTree"));
563 if (connectedList && (strcmp(opt, "reconnect"))) {
564 // If connected use the connected list of objects
566 fAODObjects = connectedList;
572 // prevent a memory leak when reading back the TList
573 // if (!(strcmp(opt, "reconnect"))) fAODObjects->Delete();
575 // create a new TList from the UserInfo TList...
576 // copy constructor does not work...
577 // fAODObjects = (TList*)(aodEvent->GetList()->Clone());
578 fAODObjects = (TList*)aodEvent->GetList();
579 fAODObjects->SetOwner(kTRUE);
580 if(fAODObjects->GetEntries()<kAODListN)
582 AliWarning(Form("AliAODEvent::ReadFromTree() TList contains less than the standard contents %d < %d"
583 " That might be fine though (at least for filtered AODs)",fAODObjects->GetEntries(),kAODListN));
586 // Let's find out whether we have friends
587 TList* friendL = tree->GetTree()->GetListOfFriends();
592 while ((fe = (TFriendElement*)next())){
593 aodEvent = (AliAODEvent*)(fe->GetTree()->GetUserInfo()->FindObject("AliAODEvent"));
595 printf("No UserInfo on tree \n");
598 // TList* objL = (TList*)(aodEvent->GetList()->Clone());
599 TList* objL = (TList*)aodEvent->GetList();
600 printf("Get list of object from tree %d !!\n", objL->GetEntries());
601 TIter nextobject(objL);
603 while((obj = nextobject()))
605 printf("Adding object from friend %s !\n", obj->GetName());
606 fAODObjects->Add(obj);
607 } // object "branch" loop
611 // set the branch addresses
612 TIter next(fAODObjects);
614 while((el=(TNamed*)next())){
615 TString bname(el->GetName());
616 // check if branch exists under this Name
617 TBranch *br = tree->GetTree()->GetBranch(bname.Data());
619 tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
621 br = tree->GetBranch(Form("%s.",bname.Data()));
623 tree->SetBranchAddress(Form("%s.",bname.Data()),fAODObjects->GetObjectRef(el));
626 printf("%s %d AliAODEvent::ReadFromTree() No Branch found with Name %s. \n",
627 (char*)__FILE__,__LINE__,bname.Data());
632 // when reading back we are not owner of the list
633 // must not delete it
634 fAODObjects->SetOwner(kTRUE);
635 fAODObjects->SetName("AODObjectsConnectedToTree");
636 // we are not owner of the list objects
637 // must not delete it
638 tree->GetUserInfo()->Add(fAODObjects);
642 // we can't get the list from the user data, create standard content
643 // and set it by hand
645 TIter next(fAODObjects);
647 while((el=(TNamed*)next())){
648 TString bname(el->GetName());
649 tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
652 // when reading back we are not owner of the list
653 // must not delete it
654 fAODObjects->SetOwner(kTRUE);
657 //______________________________________________________________________________
658 Int_t AliAODEvent::GetNumberOfPileupVerticesSPD() const{
659 // count number of SPD pileup vertices
660 Int_t nVertices=GetNumberOfVertices();
661 Int_t nPileupVertices=0;
662 for(Int_t iVert=0; iVert<nVertices; iVert++){
663 AliAODVertex *v=GetVertex(iVert);
664 if(v->GetType()==AliAODVertex::kPileupSPD) nPileupVertices++;
666 return nPileupVertices;
668 //______________________________________________________________________________
669 Int_t AliAODEvent::GetNumberOfPileupVerticesTracks() const{
670 // count number of track pileup vertices
671 Int_t nVertices=GetNumberOfVertices();
672 Int_t nPileupVertices=0;
673 for(Int_t iVert=0; iVert<nVertices; iVert++){
674 AliAODVertex *v=GetVertex(iVert);
675 if(v->GetType()==AliAODVertex::kPileupTracks) nPileupVertices++;
677 return nPileupVertices;
679 //______________________________________________________________________________
680 AliAODVertex* AliAODEvent::GetPrimaryVertexSPD() const{
681 // Get SPD primary vertex
682 Int_t nVertices=GetNumberOfVertices();
683 for(Int_t iVert=0; iVert<nVertices; iVert++){
684 AliAODVertex *v=GetVertex(iVert);
685 if(v->GetType()==AliAODVertex::kMainSPD) return v;
689 //______________________________________________________________________________
690 AliAODVertex* AliAODEvent::GetPileupVertexSPD(Int_t iV) const{
691 // Get pile-up vertex iV
692 Int_t nVertices=GetNumberOfVertices();
694 for(Int_t iVert=0; iVert<nVertices; iVert++){
695 AliAODVertex *v=GetVertex(iVert);
696 if(v->GetType()==AliAODVertex::kPileupSPD){
697 if(counter==iV) return v;
703 //______________________________________________________________________________
704 AliAODVertex* AliAODEvent::GetPileupVertexTracks(Int_t iV) const{
705 // Get pile-up vertex iV
706 Int_t nVertices=GetNumberOfVertices();
708 for(Int_t iVert=0; iVert<nVertices; iVert++){
709 AliAODVertex *v=GetVertex(iVert);
710 if(v->GetType()==AliAODVertex::kPileupTracks){
711 if(counter==iV) return v;
717 //______________________________________________________________________________
718 Bool_t AliAODEvent::IsPileupFromSPD(Int_t minContributors,
720 Double_t nSigmaZdist,
721 Double_t nSigmaDiamXY,
722 Double_t nSigmaDiamZ) const{
724 // This function checks if there was a pile up
725 // reconstructed with SPD
727 AliAODVertex *mainV=GetPrimaryVertexSPD();
728 if(!mainV) return kFALSE;
729 Int_t nc1=mainV->GetNContributors();
730 if(nc1<1) return kFALSE;
731 Int_t nPileVert=GetNumberOfPileupVerticesSPD();
732 if(nPileVert==0) return kFALSE;
733 Int_t nVertices=GetNumberOfVertices();
735 for(Int_t iVert=0; iVert<nVertices; iVert++){
736 AliAODVertex *pv=GetVertex(iVert);
737 if(pv->GetType()!=AliAODVertex::kPileupSPD) continue;
738 Int_t nc2=pv->GetNContributors();
739 if(nc2>=minContributors){
740 Double_t z1=mainV->GetZ();
741 Double_t z2=pv->GetZ();
742 Double_t distZ=TMath::Abs(z2-z1);
743 Double_t distZdiam=TMath::Abs(z2-GetDiamondZ());
744 Double_t cutZdiam=nSigmaDiamZ*TMath::Sqrt(GetSigma2DiamondZ());
745 if(GetSigma2DiamondZ()<0.0001)cutZdiam=99999.; //protection for missing z diamond information
746 if(distZ>minZdist && distZdiam<cutZdiam){
747 Double_t x2=pv->GetX();
748 Double_t y2=pv->GetY();
749 Double_t distXdiam=TMath::Abs(x2-GetDiamondX());
750 Double_t distYdiam=TMath::Abs(y2-GetDiamondY());
751 Double_t cov1[6],cov2[6];
752 mainV->GetCovarianceMatrix(cov1);
753 pv->GetCovarianceMatrix(cov2);
754 Double_t errxDist=TMath::Sqrt(cov2[0]+GetSigma2DiamondX());
755 Double_t erryDist=TMath::Sqrt(cov2[2]+GetSigma2DiamondY());
756 Double_t errzDist=TMath::Sqrt(cov1[5]+cov2[5]);
757 Double_t cutXdiam=nSigmaDiamXY*errxDist;
758 if(GetSigma2DiamondX()<0.0001)cutXdiam=99999.; //protection for missing diamond information
759 Double_t cutYdiam=nSigmaDiamXY*erryDist;
760 if(GetSigma2DiamondY()<0.0001)cutYdiam=99999.; //protection for missing diamond information
761 if( (distXdiam<cutXdiam) && (distYdiam<cutYdiam) && (distZ>nSigmaZdist*errzDist) ){
770 //______________________________________________________________________________
771 void AliAODEvent::Print(Option_t *) const
773 // Print the names of the all branches
774 TIter next(fAODObjects);
776 Printf(">>>>> AOD Content <<<<<");
777 while((el=(TNamed*)next())){
778 Printf(">> %s ",el->GetName());
780 Printf(">>>>> <<<<<");
785 void AliAODEvent::AssignIDtoCollection(const TCollection* col)
787 // Static method which assigns a ID to each object in a collection
788 // In this way the objects are marked as referenced and written with
789 // an ID. This has the advantage that TRefs to this objects can be
790 // written by a subsequent process.
793 while ((obj = next()))
794 TProcessID::AssignID(obj);
797 Bool_t AliAODEvent::IsPileupFromSPDInMultBins() const {
798 Int_t nTracklets=GetTracklets()->GetNumberOfTracklets();
799 if(nTracklets<20) return IsPileupFromSPD(3,0.8);
800 else if(nTracklets<50) return IsPileupFromSPD(4,0.8);
801 else return IsPileupFromSPD(5,0.8);