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 // $Id: AliNanoAODReplicator.cxx 56492 2012-05-15 18:42:47Z pcrochet $
18 // Implementation of a branch replicator
19 // to produce nanoAODs.
22 // This replicator is in charge of replicating the tracks,vertices,headers
23 // branches of a standard AOD or ESD file into a nanoAODs
24 // (AliAOD.Special.root)
26 // The class was inspired by AliAODMuonReplicator
28 // Author: Michele Floris, michele.floris@cern.ch
34 class AliAODRecoDecay;
36 #include "AliAODDimuon.h"
37 #include "AliAODEvent.h"
38 #include "AliAODMCHeader.h"
39 #include "AliAODMCParticle.h"
40 #include "AliAODTZERO.h"
41 #include "AliAODTrack.h"
42 #include "AliAODVZERO.h"
43 #include "AliAnalysisCuts.h"
45 #include "AliExternalTrackParam.h"
48 #include "AliPIDResponse.h"
51 #include "AliESDtrack.h"
52 #include "TObjArray.h"
53 #include "AliAnalysisFilter.h"
54 #include "AliNanoAODTrack.h"
57 #include <TDatabasePDG.h>
61 #include "AliVEvent.h"
62 #include "AliVVertex.h"
63 #include "AliVTrack.h"
64 #include "AliVertexerTracks.h"
65 #include "AliKFVertex.h"
66 #include "AliESDEvent.h"
67 #include "AliESDVertex.h"
68 #include "AliESDtrackCuts.h"
69 #include "AliAODEvent.h"
70 #include "AliAnalysisFilter.h"
72 #include "AliNanoAODReplicator.h"
75 #include "AliNanoAODHeader.h"
76 #include "AliNanoAODCustomSetter.h"
81 ClassImp(AliNanoAODReplicator)
83 //_____________________________________________________________________________
84 AliNanoAODReplicator::AliNanoAODReplicator() :
85 AliAODBranchReplicator(),
86 fTrackCut(0), fTracks(0x0), fHeader(0x0), fNTracksVariables(0), // FIXME: Start using cuts, and check if fNTracksVariables is needed
97 // Default ctor. we need it to avoid instantiating a wrong mapping when reading from file
100 AliNanoAODReplicator::AliNanoAODReplicator(const char* name, const char* title,
101 const char * varlist,
102 AliAnalysisCuts* trackCut,
105 AliAODBranchReplicator(name,title),
107 fTrackCut(trackCut), fTracks(0x0), fHeader(0x0), fNTracksVariables(0), // FIXME: Start using cuts, and check if fNTracksVariables is needed
116 fVarListHeader(""),// FIXME: this should be set to a meaningful value: add an arg to the constructor
120 AliNanoAODTrackMapping * tm =new AliNanoAODTrackMapping(fVarList);
121 fNTracksVariables = tm->GetSize();
125 //_____________________________________________________________________________
126 AliNanoAODReplicator::~AliNanoAODReplicator()
133 //_____________________________________________________________________________
134 void AliNanoAODReplicator::SelectParticle(Int_t i)
136 // taking the absolute values here, need to take care
137 // of negative daughter and mother
140 if (!IsParticleSelected(TMath::Abs(i)))
142 fParticleSelected.Add(TMath::Abs(i),1);
146 //_____________________________________________________________________________
147 Bool_t AliNanoAODReplicator::IsParticleSelected(Int_t i)
149 // taking the absolute values here, need to take
150 // care with negative daughter and mother
152 return (fParticleSelected.GetValue(TMath::Abs(i))==1);
156 //_____________________________________________________________________________
157 void AliNanoAODReplicator::CreateLabelMap(const AliAODEvent& source)
160 // this should be called once all selections are done
161 // This method associates to the original index of the mc particle
162 // (i) the new one (j). J runs only over particles which are
168 TClonesArray* mcParticles = static_cast<TClonesArray*>(source.FindListObject(AliAODMCParticle::StdBranchName()));
171 Int_t i(0); // We need i, we cannot rely on part->GetLabel, because some of the original mc particles are not kept in the stack, apparently
173 TIter next(mcParticles);
177 if (IsParticleSelected(i))
179 fLabelMap.Add(i,j++);
180 // std::cout << i << "->" << j-1 << std::endl;
188 //_____________________________________________________________________________
189 Int_t AliNanoAODReplicator::GetNewLabel(Int_t i)
191 // Gets the label from the new created Map
192 // Call CreatLabelMap before
193 // otherwise only 0 returned
194 return fLabelMap.GetValue(TMath::Abs(i));
197 //_____________________________________________________________________________
198 void AliNanoAODReplicator::FilterMC(const AliAODEvent& source)
200 // Filter MC information
203 AliAODMCHeader* mcHeader(0x0);
204 TClonesArray* mcParticles(0x0);
206 fParticleSelected.Delete();
208 // std::cout << "MC Mode: " << fMCMode << ", Tracks " << fTracks->GetEntries() << std::endl;
210 if ( fMCMode>=2 && !fTracks->GetEntries() ) {
213 // for fMCMode==1 we only copy MC information for events where there's at least one muon track
215 mcHeader = static_cast<AliAODMCHeader*>(source.FindListObject(AliAODMCHeader::StdBranchName()));
219 *fMCHeader = *mcHeader;
223 mcParticles = static_cast<TClonesArray*>(source.FindListObject(AliAODMCParticle::StdBranchName()));
225 if ( mcParticles && fMCMode>=2 )
227 // keep all primaries
228 TIter nextPart(mcParticles);
229 static Int_t iev = -1; // FIXME: remove this (debug)
231 AliAODMCParticle * prim = 0;
232 Int_t iprim = 0; // We need iprim, we cannot rely on part->GetLabel, because some of the original mc particles are not kept in the stack, apparently
233 // also select all charged primaries
234 while ((prim = (AliAODMCParticle*) nextPart())) {
235 if(prim->IsPhysicalPrimary() && prim->Charge()) SelectParticle(iprim);
238 // std::cout << "IEV " << iev << std::endl;
239 // std::cout << " PART " << iprim << " " << prim->IsPhysicalPrimary() <<","<<prim->Charge() << "=" << IsParticleSelected(iprim) << std::endl;
248 // loop on (kept) tracks to find their ancestors
249 TIter nextTRACK(fTracks);
250 AliNanoAODTrack* track;
252 while ( ( track = static_cast<AliNanoAODTrack*>(nextTRACK()) ) )
254 Int_t label = TMath::Abs(track->GetLabel());
258 SelectParticle(label);
259 AliAODMCParticle* mother = static_cast<AliAODMCParticle*>(mcParticles->UncheckedAt(label));
262 AliError(Form("Got a null mother ! Check that ! (label %d",label)); // FIXME: I think this error is not needed
267 label = mother->GetMother();// do not only keep particles which created a track, but all their mothers
272 CreateLabelMap(source);
274 // Actual filtering and label remapping (shamelessly taken for the implementation of AliAODHandler::StoreMCParticles)
275 TIter nextMC(mcParticles);
277 Int_t nmc(0); // We need nmc, we cannot rely on part->GetLabel, because some of the original mc particles are not kept in the stack, apparently
280 while ( ( p = static_cast<AliAODMCParticle*>(nextMC()) ) )
282 AliAODMCParticle c(*p);
284 if ( IsParticleSelected(nmc) )
287 Int_t d0 = p->GetDaughter(0);
288 Int_t d1 = p->GetDaughter(1);
289 Int_t m = p->GetMother();
291 // other than for the track labels, negative values mean
292 // no daughter/mother so preserve it
296 // no first daughter -> no second daughter
297 // nothing to be done
298 // second condition not needed just for sanity check at the end
301 } else if(d1 < 0 && d0 >= 0)
304 // second condition not needed just for sanity check at the end
305 if(IsParticleSelected(d0))
307 c.SetDaughter(0,GetNewLabel(d0));
314 else if (d0 > 0 && d1 > 0 )
316 // we have two or more daughters loop on the stack to see if they are
320 for (int id = d0; id<=d1;++id)
322 if (IsParticleSelected(id))
327 d0tmp = GetNewLabel(id);
328 d1tmp = d0tmp; // this is to have the same schema as on the stack i.e. with one daugther d0 and d1 are the same
330 else d1tmp = GetNewLabel(id);
333 c.SetDaughter(0,d0tmp);
334 c.SetDaughter(1,d1tmp);
337 AliFatal(Form("Unxpected indices %d %d",d0,d1));
345 if (IsParticleSelected(m))
347 c.SetMother(GetNewLabel(m));
349 // else // FIXME: re-enable this checj. Sometimes it gets here. Still to be understood why
351 // // AliError(Form("PROBLEM Mother not selected %d", m));
355 new ((*fMCParticles)[nmcout++]) AliAODMCParticle(c);
359 } //closes loop over MC particles
361 // now remap the tracks...
363 TIter nextTrack(fTracks);
365 // std::cout << "Remapping tracks" << std::endl;
367 while ( ( t = dynamic_cast<AliNanoAODTrack*>(nextTrack()) ) )
370 t->SetLabel(GetNewLabel(t->GetLabel()));
373 } // closes fMCMode == 1
374 else if ( mcParticles )
376 // simple copy of input MC particles to ouput MC particles
377 TIter nextMC(mcParticles);
381 while ( ( p = static_cast<AliAODMCParticle*>(nextMC()) ) )
383 new ((*fMCParticles)[nmcout++]) AliAODMCParticle(*p);
387 AliDebug(1,Form("input mc %d output mc %d",
388 mcParticles ? mcParticles->GetEntries() : 0,
389 fMCParticles ? fMCParticles->GetEntries() : 0));
391 Printf("input mc %d output mc %d",
392 mcParticles ? mcParticles->GetEntries() : 0,
393 fMCParticles ? fMCParticles->GetEntries() : 0);
398 // //_____________________________________________________________________________
399 TList* AliNanoAODReplicator::GetList() const
401 // return (and build if not already done) our internal list of managed objects
406 fList->SetOwner(kTRUE);
408 fTracks = new TClonesArray("AliNanoAODTrack");
409 fTracks->SetName("tracks"); // TODO: consider the possibility to use a different name to distinguish in AliAODEvent
412 fHeader = new AliNanoAODHeader(2);// TODO: to be customized
413 fHeader->SetName("header"); // TODO: consider the possibility to use a different name to distinguish in AliAODEvent
417 fVertices = new TClonesArray("AliAODVertex",2);
418 fVertices->SetName("vertices");
421 fList->Add(fVertices);
425 fMCHeader = new AliAODMCHeader;
426 fMCParticles = new TClonesArray("AliAODMCParticle",1000);
427 fMCParticles->SetName(AliAODMCParticle::StdBranchName());
428 fList->Add(fMCHeader);
429 fList->Add(fMCParticles);
435 //_____________________________________________________________________________
436 void AliNanoAODReplicator::ReplicateAndFilter(const AliAODEvent& source)
437 //void AliNanoAODReplicator::ReplicateAndFilter(AliAODEvent *source)
439 // Replicate (and filter if filters are there) the relevant parts we're interested in AODEvent
442 // assert(fTracks!=0x0);
444 //*fTZERO = *(source.GetTZEROData());
449 assert(fVertices!=0x0);
450 fVertices->Clear("C");
453 AliFatal(Form("fMCMode = %d, but MC header not found", fMCMode));
457 AliFatal(Form("fMCMode = %d, but MC particles not found", fMCMode));
459 fMCParticles->Clear("C");
464 AliAODVertex *vtx = source.GetPrimaryVertex();
466 // TODO: implement header!
467 // *fHeader = *source.GetHeader();
469 // Set custom variables in the header if the callback is set
470 fCustomSetter->SetNanoAODHeader(&source, fHeader);
475 const Int_t entries = source.GetNumberOfTracks();
477 Double_t pos[3],cov[6];
479 vtx->GetCovarianceMatrix(cov);
481 if(entries<=0) return;
483 if(vtx->GetNContributors()<1) {
485 vtx =source.GetPrimaryVertexSPD();
486 if(vtx->GetNContributors()<1) { // FIXME: Keep this cut?
487 Info("AliNanoAODReplicator","No good vertex, skip event");
488 return; // NO GOOD VERTEX, SKIP EVENT
493 for(Int_t j=0; j<entries; j++){
495 AliVTrack *track = (AliVTrack*)source.GetTrack(j);
497 AliAODTrack *aodtrack =(AliAODTrack*)track;// FIXME DYNAMIC CAST?
498 if(!fTrackCut->IsSelected(aodtrack)) continue;
500 AliNanoAODTrack * special = new AliNanoAODTrack (aodtrack, fVarList);
502 if(fCustomSetter) fCustomSetter->SetNanoAODTrack(aodtrack, special);
503 (*fTracks)[ntracks++] = special;
504 //new((*fTracks)[ntrac\ks++])
506 //----------------------------------------------------------
508 TIter nextV(source.GetVertices());
512 while ( ( v = static_cast<AliAODVertex*>(nextV()) ) )
514 AliAODVertex* tmp = v->CloneWithoutRefs();
515 AliAODVertex* copiedVertex = new((*fVertices)[nvertices++]) AliAODVertex(*tmp);
517 // to insure the main vertex retains the ncontributors information
518 // (which is otherwise computed dynamically from
519 // references to tracks, which we do not keep in muon aods...)
522 copiedVertex->SetNContributors(v->GetNContributors());
524 // fVertices->Delete();
525 // delete copiedVertex;
530 AliDebug(1,Form("input mu tracks=%d tracks=%d vertices=%d",
531 input,fTracks->GetEntries(),fVertices->GetEntries()));
534 // Finally, deal with MC information, if needed
545 //-----------------------------------------------------------------------------
547 //----------------------------------------------------------------------------
550 //-----------------------------------------------------------------------------
552 // AliAODVertex* AliNanoAODReplicator::PrimaryVertex(const TObjArray *trkArray,
553 // AliAODEvent &event) const
555 // // Returns primary vertex to be used for this candidate
556 // //AliCodeTimerAuto("",0);
558 // AliESDVertex *vertexESD = 0;
559 // AliAODVertex *vertexAOD = 0;
562 // if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) {
563 // // primary vertex from the input event
565 // vertexESD = new AliESDVertex(*fV1);
568 // // primary vertex specific to this candidate
570 // Int_t nTrks = trkArray->GetEntriesFast();
571 // AliVertexerTracks *vertexer = new AliVertexerTracks(event.GetMagneticField());
573 // if(fRecoPrimVtxSkippingTrks) {
574 // // recalculating the vertex
576 // if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraint")) {
577 // Float_t diamondcovxy[3];
578 // event.GetDiamondCovXY(diamondcovxy);
579 // Double_t pos[3]={event.GetDiamondX(),event.GetDiamondY(),0.};
580 // Double_t cov[6]={diamondcovxy[0],diamondcovxy[1],diamondcovxy[2],0.,0.,10.*10.};
581 // AliESDVertex *diamond = new AliESDVertex(pos,cov,1.,1);
582 // vertexer->SetVtxStart(diamond);
583 // delete diamond; diamond=NULL;
584 // if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraintOnlyFitter"))
585 // vertexer->SetOnlyFitter();
587 // Int_t skipped[1000];
588 // Int_t nTrksToSkip=0,id;
589 // AliExternalTrackParam *t = 0;
590 // for(Int_t i=0; i<nTrks; i++) {
591 // t = (AliExternalTrackParam*)trkArray->UncheckedAt(i);
592 // id = (Int_t)t->GetID();
593 // if(id<0) continue;
594 // skipped[nTrksToSkip++] = id;
597 // // For AOD, skip also tracks without covariance matrix
599 // Double_t covtest[21];
600 // for(Int_t j=0; j<event.GetNumberOfTracks(); j++) {
601 // AliVTrack *vtrack = (AliVTrack*)event.GetTrack(j);
602 // if(!vtrack->GetCovarianceXYZPxPyPz(covtest)) {
603 // id = (Int_t)vtrack->GetID();
604 // if(id<0) continue;
605 // skipped[nTrksToSkip++] = id;
609 // for(Int_t ijk=nTrksToSkip; ijk<1000; ijk++) skipped[ijk]=-1;
611 // vertexer->SetSkipTracks(nTrksToSkip,skipped);
612 // vertexESD = (AliESDVertex*)vertexer->FindPrimaryVertex(event);
614 // } else if(fRmTrksFromPrimVtx && nTrks>0) {
615 // // removing the prongs tracks
617 // TObjArray rmArray(nTrks);
618 // UShort_t *rmId = new UShort_t[nTrks];
619 // AliESDtrack *esdTrack = 0;
620 // AliESDtrack *t = 0;
621 // for(Int_t i=0; i<nTrks; i++) {
622 // t = (AliESDtrack*)trkArray->UncheckedAt(i);
623 // esdTrack = new AliESDtrack(*t);
624 // rmArray.AddLast(esdTrack);
625 // if(esdTrack->GetID()>=0) {
626 // rmId[i]=(UShort_t)esdTrack->GetID();
631 // Float_t diamondxy[2]={event.GetDiamondX(),event.GetDiamondY()};
632 // vertexESD = vertexer->RemoveTracksFromVertex(fV1,&rmArray,rmId,diamondxy);
633 // delete [] rmId; rmId=NULL;
638 // if(!vertexESD) return vertexAOD;
639 // if(vertexESD->GetNContributors()<=0) {
640 // //AliDebug(2,"vertexing failed");
641 // delete vertexESD; vertexESD=NULL;
645 // delete vertexer; vertexer=NULL;
649 // // convert to AliAODVertex
650 // Double_t pos[3],cov[6],chi2perNDF;
651 // vertexESD->GetXYZ(pos); // position
652 // vertexESD->GetCovMatrix(cov); //covariance matrix
653 // chi2perNDF = vertexESD->GetChi2toNDF();
654 // delete vertexESD; vertexESD=NULL;
656 // vertexAOD = new AliAODVertex(pos,cov,chi2perNDF);
661 //_____________________________________________________________________________
665 // //---------------------------------------------------------------------------
667 void AliNanoAODReplicator::Terminate(){