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",
54 //______________________________________________________________________________
55 AliAODEvent::AliAODEvent() :
57 fAODObjects(new TList()),
75 // default constructor
78 //______________________________________________________________________________
79 AliAODEvent::AliAODEvent(const AliAODEvent& aod):
81 fAODObjects(new TList()),
84 fHeader(new AliAODHeader(*aod.fHeader)),
85 fTracks(new TClonesArray(*aod.fTracks)),
86 fVertices(new TClonesArray(*aod.fVertices)),
87 fV0s(new TClonesArray(*aod.fV0s)),
88 fCascades(new TClonesArray(*aod.fCascades)),
89 fTracklets(new AliAODTracklets(*aod.fTracklets)),
90 fJets(new TClonesArray(*aod.fJets)),
91 fEmcalCells(new AliAODCaloCells(*aod.fEmcalCells)),
92 fPhosCells(new AliAODCaloCells(*aod.fPhosCells)),
93 fCaloClusters(new TClonesArray(*aod.fCaloClusters)),
94 fFmdClusters(new TClonesArray(*aod.fFmdClusters)),
95 fPmdClusters(new TClonesArray(*aod.fPmdClusters)),
96 fDimuons(new TClonesArray(*aod.fDimuons)),
97 fAODVZERO(new AliAODVZERO(*aod.fAODVZERO))
102 AddObject(fVertices);
104 AddObject(fCascades);
105 AddObject(fTracklets);
107 AddObject(fEmcalCells);
108 AddObject(fPhosCells);
109 AddObject(fCaloClusters);
110 AddObject(fFmdClusters);
111 AddObject(fPmdClusters);
113 AddObject(fAODVZERO);
114 fConnected = aod.fConnected;
119 //______________________________________________________________________________
120 AliAODEvent & AliAODEvent::operator=(const AliAODEvent& aod) {
122 // Assignment operator
124 if(&aod == this) return *this;
125 AliVEvent::operator=(aod);
127 // This assumes that the list is already created
128 // and that the virtual void Copy(Tobject&) function
129 // is correctly implemented in the derived class
130 // otherwise only TObject::Copy() will be used
132 if((fAODObjects->GetSize()==0)&&(aod.fAODObjects->GetSize()>=kAODListN)){
133 // We cover the case that we do not yet have the
134 // standard content but the source has it
138 // Here we have the standard content without user additions, but the content is
139 // not matching the aod source.
141 // Iterate the list of source objects
142 TIter next(aod.GetList());
145 while ((its = next())) {
146 name = its->GetName();
147 // Check if we have this object type in out list
148 TObject *mine = fAODObjects->FindObject(name);
150 // We have to create the same type of object.
151 TClass* pClass=TClass::GetClass(its->ClassName());
153 AliWarning(Form("Can not find class description for entry %s (%s)\n",
154 its->ClassName(), name.Data()));
157 mine=(TObject*)pClass->New();
159 // not in this: can be added to list
160 AliWarning(Form("%s:%d Could not find %s for copying \n",
161 (char*)__FILE__,__LINE__,name.Data()));
164 if(mine->InheritsFrom("TNamed")) {
165 ((TNamed*)mine)->SetName(name);
166 } else if(mine->InheritsFrom("TCollection")){
167 if(mine->InheritsFrom("TClonesArray")) {
168 TClonesArray *itscl = dynamic_cast<TClonesArray*>(its);
170 AliWarning(Form("Class description for entry %s (%s) not TClonesArray\n",
171 its->ClassName(), name.Data()));
175 dynamic_cast<TClonesArray*>(mine)->SetClass(itscl->GetClass(), itscl->GetSize());
177 dynamic_cast<TCollection*>(mine)->SetName(name);
179 AliDebug(1, Form("adding object %s of type %s", mine->GetName(), mine->ClassName()));
182 // Now we have an object of the same type and name, but different content.
183 if(!its->InheritsFrom("TCollection")){
184 // simple objects (do they have a Copy method that calls operator= ?)
186 } else if (its->InheritsFrom("TClonesArray")) {
187 // Create or expand the tclonesarray pointers
188 // so we can directly copy to the object
189 TClonesArray *its_tca = (TClonesArray*)its;
190 TClonesArray *mine_tca = (TClonesArray*)mine;
191 // this leaves the capacity of the TClonesArray the same
192 // except for a factor of 2 increase when size > capacity
193 // does not release any memory occupied by the tca
194 Int_t its_entries = its_tca->GetEntriesFast();
195 mine_tca->ExpandCreate(its_entries);
196 for(int i=0; i<its_entries; i++){
198 TObject *mine_tca_obj = mine_tca->At(i);
199 TObject *its_tca_obj = its_tca->At(i);
200 // no need to delete first
201 // pointers within the class should be handled by Copy()...
202 // Can there be Empty slots?
203 its_tca_obj->Copy(*mine_tca_obj);
206 AliWarning(Form("%s:%d cannot copy TCollection \n",
207 (char*)__FILE__,__LINE__));
210 fConnected = aod.fConnected;
215 //______________________________________________________________________________
216 AliAODEvent::~AliAODEvent()
219 if(fAODObjects&&!fConnected)
229 //______________________________________________________________________________
230 void AliAODEvent::AddObject(TObject* obj)
232 // Add an object to the list of objects.
233 // Please be aware that in order to increase performance you should
234 // refrain from using TObjArrays (if possible). Use TClonesArrays, instead.
236 fAODObjects->AddLast(obj);
239 //______________________________________________________________________________
240 void AliAODEvent::RemoveObject(TObject* obj)
242 // Removes an object from the list of objects.
244 fAODObjects->Remove(obj);
247 //______________________________________________________________________________
248 TObject *AliAODEvent::FindListObject(const char *objName) const
250 // Return the pointer to the object with the given name.
252 return fAODObjects->FindObject(objName);
255 //______________________________________________________________________________
256 void AliAODEvent::CreateStdContent()
258 // create the standard AOD content and set pointers
260 // create standard objects and add them to the TList of objects
261 AddObject(new AliAODHeader());
262 AddObject(new TClonesArray("AliAODTrack", 0));
263 AddObject(new TClonesArray("AliAODVertex", 0));
264 AddObject(new TClonesArray("AliAODv0", 0));
265 AddObject(new TClonesArray("AliAODcascade", 0));
266 AddObject(new AliAODTracklets());
267 AddObject(new TClonesArray("AliAODJet", 0));
268 AddObject(new AliAODCaloCells());
269 AddObject(new AliAODCaloCells());
270 AddObject(new TClonesArray("AliAODCaloCluster", 0));
271 AddObject(new TClonesArray("AliAODFmdCluster", 0));
272 AddObject(new TClonesArray("AliAODPmdCluster", 0));
273 AddObject(new TClonesArray("AliAODDimuon", 0));
274 AddObject(new AliAODVZERO());
278 // read back pointers
284 void AliAODEvent::MakeEntriesReferencable()
286 // Make all entries referencable in a subsequent process
288 TIter next(fAODObjects);
290 while ((obj = next()))
292 if(obj->InheritsFrom("TCollection"))
294 AssignIDtoCollection((TCollection*)obj);
299 //______________________________________________________________________________
300 void AliAODEvent::SetStdNames()
302 // introduce the standard naming
304 if(fAODObjects->GetEntries()==kAODListN){
305 for(int i = 0;i < fAODObjects->GetEntries();i++){
306 TObject *fObj = fAODObjects->At(i);
307 if(fObj->InheritsFrom("TNamed")){
308 ((TNamed*)fObj)->SetName(fAODListName[i]);
310 else if(fObj->InheritsFrom("TClonesArray")){
311 ((TClonesArray*)fObj)->SetName(fAODListName[i]);
316 printf("%s:%d SetStdNames() Wrong number of Std Entries \n",(char*)__FILE__,__LINE__);
320 void AliAODEvent::CreateStdFolders()
322 // Create the standard folder structure
323 if(fAODFolder)delete fAODFolder;
324 fAODFolder = gROOT->GetRootFolder()->AddFolder("AOD", "AOD");
325 if(fAODObjects->GetEntries()==kAODListN){
326 for(int i = 0;i < fAODObjects->GetEntries();i++){
327 TObject *fObj = fAODObjects->At(i);
328 if(fObj->InheritsFrom("TClonesArray")){
329 fAODFolder->AddFolder(fAODListName[i], fAODListName[i], (TCollection*) fObj);
331 fAODFolder->AddFolder(fAODListName[i], fAODListName[i], 0);
336 printf("%s:%d CreateStdFolders() Wrong number of Std Entries \n",(char*)__FILE__,__LINE__);
340 //______________________________________________________________________________
341 void AliAODEvent::GetStdContent()
343 // set pointers for standard content
345 fHeader = (AliAODHeader*)fAODObjects->FindObject("header");
346 fTracks = (TClonesArray*)fAODObjects->FindObject("tracks");
347 fVertices = (TClonesArray*)fAODObjects->FindObject("vertices");
348 fV0s = (TClonesArray*)fAODObjects->FindObject("v0s");
349 fCascades = (TClonesArray*)fAODObjects->FindObject("cascades");
350 fTracklets = (AliAODTracklets*)fAODObjects->FindObject("tracklets");
351 fJets = (TClonesArray*)fAODObjects->FindObject("jets");
352 fEmcalCells = (AliAODCaloCells*)fAODObjects->FindObject("emcalCells");
353 fPhosCells = (AliAODCaloCells*)fAODObjects->FindObject("phosCells");
354 fCaloClusters = (TClonesArray*)fAODObjects->FindObject("caloClusters");
355 fFmdClusters = (TClonesArray*)fAODObjects->FindObject("fmdClusters");
356 fPmdClusters = (TClonesArray*)fAODObjects->FindObject("pmdClusters");
357 fDimuons = (TClonesArray*)fAODObjects->FindObject("dimuons");
358 fAODVZERO = (AliAODVZERO*)fAODObjects->FindObject("AliAODVZERO");
361 //______________________________________________________________________________
362 void AliAODEvent::ResetStd(Int_t trkArrSize,
365 Int_t cascadeArrSize,
373 // deletes content of standard arrays and resets size
376 if (trkArrSize > fTracks->GetSize())
377 fTracks->Expand(trkArrSize);
380 if (vtxArrSize > fVertices->GetSize())
381 fVertices->Expand(vtxArrSize);
384 if (v0ArrSize > fV0s->GetSize())
385 fV0s->Expand(v0ArrSize);
388 if (cascadeArrSize > fCascades->GetSize())
389 fCascades->Expand(cascadeArrSize);
392 if (jetSize > fJets->GetSize())
393 fJets->Expand(jetSize);
395 fCaloClusters->Delete();
396 if (caloClusSize > fCaloClusters->GetSize())
397 fCaloClusters->Expand(caloClusSize);
399 fFmdClusters->Delete();
400 if (fmdClusSize > fFmdClusters->GetSize())
401 fFmdClusters->Expand(fmdClusSize);
403 fPmdClusters->Delete();
404 if (pmdClusSize > fPmdClusters->GetSize())
405 fPmdClusters->Expand(pmdClusSize);
408 if (dimuonArrSize > fDimuons->GetSize())
409 fDimuons->Expand(dimuonArrSize);
411 // Reset the tracklets
412 fTracklets->DeleteContainer();
413 fPhosCells->DeleteContainer();
414 fEmcalCells->DeleteContainer();
418 void AliAODEvent::ClearStd()
420 // clears the standard arrays
423 fVertices ->Delete();
425 fCascades ->Delete();
426 fTracklets ->DeleteContainer();
428 fEmcalCells ->DeleteContainer();
429 fPhosCells ->DeleteContainer();
430 fCaloClusters ->Delete();
431 fFmdClusters ->Clear();
432 fPmdClusters ->Clear();
436 //_________________________________________________________________
437 Int_t AliAODEvent::GetPHOSClusters(TRefArray *clusters) const
439 // fills the provided TRefArray with all found phos clusters
443 AliAODCaloCluster *cl = 0;
444 Bool_t first = kTRUE;
445 for (Int_t i = 0; i < GetNumberOfCaloClusters() ; i++) {
446 if ( (cl = GetCaloCluster(i)) ) {
449 new (clusters) TRefArray(TProcessID::GetProcessWithUID(cl));
453 //printf("IsPHOS cluster %d, E %2.3f Size: %d \n",i,cl->E(),clusters->GetEntriesFast());
457 return clusters->GetEntriesFast();
460 //_________________________________________________________________
461 Int_t AliAODEvent::GetEMCALClusters(TRefArray *clusters) const
463 // fills the provided TRefArray with all found emcal clusters
466 AliAODCaloCluster *cl = 0;
467 Bool_t first = kTRUE;
468 for (Int_t i = 0; i < GetNumberOfCaloClusters(); i++) {
469 if ( (cl = GetCaloCluster(i)) ) {
472 new (clusters) TRefArray(TProcessID::GetProcessWithUID(cl));
476 //printf("IsEMCal cluster %d, E %2.3f Size: %d \n",i,cl->E(),clusters->GetEntriesFast());
480 return clusters->GetEntriesFast();
484 //______________________________________________________________________________
485 Int_t AliAODEvent::GetMuonTracks(TRefArray *muonTracks) const
487 // fills the provided TRefArray with all found muon tracks
491 AliAODTrack *track = 0;
492 for (Int_t iTrack = 0; iTrack < GetNTracks(); iTrack++) {
493 track = GetTrack(iTrack);
494 if (track->IsMuonTrack()) {
495 muonTracks->Add(track);
499 return muonTracks->GetEntriesFast();
503 //______________________________________________________________________________
504 Int_t AliAODEvent::GetNumberOfMuonTracks() const
506 // get number of muon tracks
508 for (Int_t iTrack = 0; iTrack < GetNTracks(); iTrack++) {
509 if ((GetTrack(iTrack))->IsMuonTrack()) {
517 void AliAODEvent::ReadFromTree(TTree *tree, Option_t* opt /*= ""*/)
519 // Connects aod event to tree
522 Printf("%s %d AliAODEvent::ReadFromTree() Zero Pointer to Tree \n",(char*)__FILE__,__LINE__);
526 if(!tree->GetTree())tree->LoadTree(0);
528 // Try to find AliAODEvent
529 AliAODEvent *aodEvent = 0;
530 aodEvent = (AliAODEvent*)tree->GetTree()->GetUserInfo()->FindObject("AliAODEvent");
532 // Check if already connected to tree
533 TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("AODObjectsConnectedToTree"));
534 if (connectedList && (strcmp(opt, "reconnect"))) {
535 // If connected use the connected list of objects
536 fAODObjects->Delete();
537 fAODObjects = connectedList;
543 // prevent a memory leak when reading back the TList
544 // if (!(strcmp(opt, "reconnect"))) fAODObjects->Delete();
546 // create a new TList from the UserInfo TList...
547 // copy constructor does not work...
548 fAODObjects = (TList*)(aodEvent->GetList()->Clone());
549 fAODObjects->SetOwner(kTRUE);
550 if(fAODObjects->GetEntries()<kAODListN){
551 printf("%s %d AliAODEvent::ReadFromTree() TList contains less than the standard contents %d < %d \n",
552 (char*)__FILE__,__LINE__,fAODObjects->GetEntries(),kAODListN);
555 // Let's find out whether we have friends
556 TList* friendL = tree->GetTree()->GetListOfFriends();
561 while ((fe = (TFriendElement*)next())){
562 aodEvent = (AliAODEvent*)(fe->GetTree()->GetUserInfo()->FindObject("AliAODEvent"));
564 printf("No UserInfo on tree \n");
567 TList* objL = (TList*)(aodEvent->GetList()->Clone());
568 printf("Get list of object from tree %d !!\n", objL->GetEntries());
569 TIter nextobject(objL);
571 while((obj = nextobject()))
573 printf("Adding object from friend %s !\n", obj->GetName());
574 fAODObjects->Add(obj);
575 } // object "branch" loop
581 // set the branch addresses
582 TIter next(fAODObjects);
584 while((el=(TNamed*)next())){
585 TString bname(el->GetName());
586 // check if branch exists under this Name
587 TBranch *br = tree->GetTree()->GetBranch(bname.Data());
589 tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
591 br = tree->GetBranch(Form("%s.",bname.Data()));
593 tree->SetBranchAddress(Form("%s.",bname.Data()),fAODObjects->GetObjectRef(el));
596 printf("%s %d AliAODEvent::ReadFromTree() No Branch found with Name %s. \n",
597 (char*)__FILE__,__LINE__,bname.Data());
602 // when reading back we are not owner of the list
603 // must not delete it
604 fAODObjects->SetOwner(kTRUE);
605 fAODObjects->SetName("AODObjectsConnectedToTree");
606 // we are not owner of the list objects
607 // must not delete it
608 tree->GetUserInfo()->Add(fAODObjects);
612 // we can't get the list from the user data, create standard content
613 // and set it by hand
615 TIter next(fAODObjects);
617 while((el=(TNamed*)next())){
618 TString bname(el->GetName());
619 tree->SetBranchAddress(bname.Data(),fAODObjects->GetObjectRef(el));
622 // when reading back we are not owner of the list
623 // must not delete it
624 fAODObjects->SetOwner(kTRUE);
627 //______________________________________________________________________________
628 Int_t AliAODEvent::GetNumberOfPileupVerticesSPD() const{
629 // count number of SPD pileup vertices
630 Int_t nVertices=GetNumberOfVertices();
631 Int_t nPileupVertices=0;
632 for(Int_t iVert=0; iVert<nVertices; iVert++){
633 AliAODVertex *v=GetVertex(iVert);
634 if(v->GetType()==AliAODVertex::kPileupSPD) nPileupVertices++;
636 return nPileupVertices;
638 //______________________________________________________________________________
639 Int_t AliAODEvent::GetNumberOfPileupVerticesTracks() const{
640 // count number of track pileup vertices
641 Int_t nVertices=GetNumberOfVertices();
642 Int_t nPileupVertices=0;
643 for(Int_t iVert=0; iVert<nVertices; iVert++){
644 AliAODVertex *v=GetVertex(iVert);
645 if(v->GetType()==AliAODVertex::kPileupTracks) nPileupVertices++;
647 return nPileupVertices;
649 //______________________________________________________________________________
650 AliAODVertex* AliAODEvent::GetPrimaryVertexSPD() const{
652 Int_t nVertices=GetNumberOfVertices();
653 for(Int_t iVert=0; iVert<nVertices; iVert++){
654 AliAODVertex *v=GetVertex(iVert);
655 if(v->GetType()==AliAODVertex::kMainSPD) return v;
659 //______________________________________________________________________________
660 AliAODVertex* AliAODEvent::GetPileupVertexSPD(Int_t iV) const{
662 Int_t nVertices=GetNumberOfVertices();
664 for(Int_t iVert=0; iVert<nVertices; iVert++){
665 AliAODVertex *v=GetVertex(iVert);
666 if(v->GetType()==AliAODVertex::kPileupSPD){
667 if(counter==iV) return v;
673 //______________________________________________________________________________
674 AliAODVertex* AliAODEvent::GetPileupVertexTracks(Int_t iV) const{
676 Int_t nVertices=GetNumberOfVertices();
678 for(Int_t iVert=0; iVert<nVertices; iVert++){
679 AliAODVertex *v=GetVertex(iVert);
680 if(v->GetType()==AliAODVertex::kPileupTracks){
681 if(counter==iV) return v;
687 //______________________________________________________________________________
688 Bool_t AliAODEvent::IsPileupFromSPD(Int_t minContributors,
690 Double_t nSigmaZdist,
691 Double_t nSigmaDiamXY,
692 Double_t nSigmaDiamZ) const{
694 // This function checks if there was a pile up
695 // reconstructed with SPD
697 AliAODVertex *mainV=GetPrimaryVertexSPD();
698 if(!mainV) return kFALSE;
699 Int_t nc1=mainV->GetNContributors();
700 if(nc1<1) return kFALSE;
701 Int_t nPileVert=GetNumberOfPileupVerticesSPD();
702 if(nPileVert==0) return kFALSE;
703 Int_t nVertices=GetNumberOfVertices();
705 for(Int_t iVert=0; iVert<nVertices; iVert++){
706 AliAODVertex *pv=GetVertex(iVert);
707 if(pv->GetType()!=AliAODVertex::kPileupSPD) continue;
708 Int_t nc2=pv->GetNContributors();
709 if(nc2>=minContributors){
710 Double_t z1=mainV->GetZ();
711 Double_t z2=pv->GetZ();
712 Double_t distZ=TMath::Abs(z2-z1);
713 Double_t distZdiam=TMath::Abs(z2-GetDiamondZ());
714 Double_t cutZdiam=nSigmaDiamZ*TMath::Sqrt(GetSigma2DiamondZ());
715 if(GetSigma2DiamondZ()<0.0001)cutZdiam=99999.; //protection for missing z diamond information
716 if(distZ>minZdist && distZdiam<cutZdiam){
717 Double_t x2=pv->GetX();
718 Double_t y2=pv->GetY();
719 Double_t distXdiam=TMath::Abs(x2-GetDiamondX());
720 Double_t distYdiam=TMath::Abs(y2-GetDiamondY());
721 Double_t cov1[6],cov2[6];
722 mainV->GetCovarianceMatrix(cov1);
723 pv->GetCovarianceMatrix(cov2);
724 Double_t errxDist=TMath::Sqrt(cov2[0]+GetSigma2DiamondX());
725 Double_t erryDist=TMath::Sqrt(cov2[2]+GetSigma2DiamondY());
726 Double_t errzDist=TMath::Sqrt(cov1[5]+cov2[5]);
727 Double_t cutXdiam=nSigmaDiamXY*errxDist;
728 if(GetSigma2DiamondX()<0.0001)cutXdiam=99999.; //protection for missing diamond information
729 Double_t cutYdiam=nSigmaDiamXY*erryDist;
730 if(GetSigma2DiamondY()<0.0001)cutYdiam=99999.; //protection for missing diamond information
731 if( (distXdiam<cutXdiam) && (distYdiam<cutYdiam) && (distZ>nSigmaZdist*errzDist) ){
740 //______________________________________________________________________________
741 void AliAODEvent::Print(Option_t *) const
743 // Print the names of the all branches
744 TIter next(fAODObjects);
746 Printf(">>>>> AOD Content <<<<<");
747 while((el=(TNamed*)next())){
748 Printf(">> %s ",el->GetName());
750 Printf(">>>>> <<<<<");
755 void AliAODEvent::AssignIDtoCollection(TCollection* col)
757 // Static method which assigns a ID to each object in a collection
758 // In this way the objects are marked as referenced and written with
759 // an ID. This has the advantage that TRefs to this objects can be
760 // written by a subsequent process.
763 while ((obj = next()))
764 TProcessID::AssignID(obj);
767 Bool_t AliAODEvent::IsPileupFromSPDInMultBins() const {
768 Int_t nTracklets=GetTracklets()->GetNumberOfTracklets();
769 if(nTracklets<20) return IsPileupFromSPD(3,0.8);
770 else if(nTracklets<50) return IsPileupFromSPD(4,0.8);
771 else return IsPileupFromSPD(5,0.8);