1 /**************************************************************************
2 * Copyright(c) 1998-2013, 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 **************************************************************************/
19 /// Implementation of an AliAODBranchReplicator to produce slim muon and dimuon aods.
21 /// This replicator is in charge of replicating the tracks,vertices,dimuons
22 /// (vzero, tzero, zdc, and, optionally, the SPD tracklets) branches
23 /// of the standard AOD into muon AODs (AliAOD.Muons.root and AliAOD.Dimuons.root)
25 /// The tracks are filtered so that only muon tracks (and only muon tracks
26 /// that pass the trackCut if present) make it to the output aods
28 /// The vertices are filtered so that only the primary (and pileup) vertices make it
29 /// to the output aods.
31 /// The dimuons are recreated here, according to the set of tracks
32 /// that pass the trackCut (that set may be the same as the input set,
33 /// but to be 100% safe, we always recreate the dimuons).
35 /// \author L. Aphecetche (Subatech)
37 #include "AliAODMuonReplicator.h"
39 #include "AliAODDimuon.h"
40 #include "AliAODEvent.h"
41 #include "AliAODMCHeader.h"
42 #include "AliAODMCParticle.h"
43 #include "AliAODTZERO.h"
44 #include "AliAODTrack.h"
45 #include "AliAODVZERO.h"
46 #include "AliAnalysisCuts.h"
50 ClassImp(AliAODMuonReplicator)
53 //_____________________________________________________________________________
54 AliAODMuonReplicator::AliAODMuonReplicator(const char* name, const char* title,
55 AliAnalysisCuts* trackCut,
56 AliAnalysisCuts* vertexCut,
58 Bool_t replicateHeader,
59 Bool_t replicateTracklets)
60 :AliAODBranchReplicator(name,title),
61 fTrackCut(trackCut), fTracks(0x0),
62 fVertexCut(vertexCut), fVertices(0x0),
75 fReplicateHeader(replicateHeader),
76 fReplicateTracklets(replicateTracklets)
80 /// \param trackCut if present will filter out tracks
81 /// \param vertexCut if present will filter out vertices
82 /// \param mcMode what to do with MC information (0: skip it, 1: copy all,
83 /// 2: copy only for events with at least one muon )
84 /// \param replicateHeader whether or not to handle the replication of the
86 /// \param replicateTracklets whether or not to include the SPD tracklets branch
90 //_____________________________________________________________________________
91 AliAODMuonReplicator::~AliAODMuonReplicator()
99 //_____________________________________________________________________________
100 void AliAODMuonReplicator::SelectParticle(Int_t i)
102 /// taking the absolute values here, need to take care
103 /// of negative daughter and mother
104 /// IDs when setting!
106 if (!IsParticleSelected(TMath::Abs(i)))
108 fParticleSelected.Add(TMath::Abs(i),1);
112 //_____________________________________________________________________________
113 Bool_t AliAODMuonReplicator::IsParticleSelected(Int_t i)
115 /// taking the absolute values here, need to take
116 /// care with negative daughter and mother
117 /// IDs when setting!
118 return (fParticleSelected.GetValue(TMath::Abs(i))==1);
122 //_____________________________________________________________________________
123 void AliAODMuonReplicator::CreateLabelMap(const AliAODEvent& source)
126 // this should be called once all selections are done
131 TClonesArray* mcParticles = static_cast<TClonesArray*>(source.FindListObject(AliAODMCParticle::StdBranchName()));
136 TIter next(mcParticles);
140 if (IsParticleSelected(i))
142 fLabelMap.Add(i,j++);
148 //_____________________________________________________________________________
149 Int_t AliAODMuonReplicator::GetNewLabel(Int_t i)
151 /// Gets the label from the new created Map
152 /// Call CreatLabelMap before
153 /// otherwise only 0 returned
154 return fLabelMap.GetValue(TMath::Abs(i));
157 //_____________________________________________________________________________
158 void AliAODMuonReplicator::FilterMC(const AliAODEvent& source)
160 /// Filter MC information
163 fMCParticles->Clear("C");
165 AliAODMCHeader* mcHeader(0x0);
166 TClonesArray* mcParticles(0x0);
168 fParticleSelected.Delete();
170 if ( fMCMode==2 && !fTracks->GetEntries() ) return;
171 // for fMCMode==2 we only copy MC information for events where there's at least one muon track
173 mcHeader = static_cast<AliAODMCHeader*>(source.FindListObject(AliAODMCHeader::StdBranchName()));
177 *fMCHeader = *mcHeader;
180 mcParticles = static_cast<TClonesArray*>(source.FindListObject(AliAODMCParticle::StdBranchName()));
182 if ( mcParticles && fMCMode>=2 )
184 // loop on (kept) muon tracks to find their ancestors
185 TIter nextMT(fTracks);
188 while ( ( mt = static_cast<AliAODTrack*>(nextMT()) ) )
190 Int_t label = mt->GetLabel();
194 SelectParticle(label);
195 AliAODMCParticle* mother = static_cast<AliAODMCParticle*>(mcParticles->UncheckedAt(label));
198 AliError("Got a null mother ! Check that !");
203 label = mother->GetMother();
208 if ( mcParticles && fMCMode==3 )
210 // loop on MC muon tracks to find their ancestors
211 for ( Int_t ipart=0; ipart<mcParticles->GetEntries(); ipart++ )
213 AliAODMCParticle* mcp = static_cast<AliAODMCParticle*>(mcParticles->UncheckedAt(ipart));
214 if ( TMath::Abs(mcp->PdgCode()) != 13 ) continue;
219 SelectParticle(label);
220 AliAODMCParticle* mother = static_cast<AliAODMCParticle*>(mcParticles->UncheckedAt(label));
223 AliError("Got a null mother ! Check that !");
228 label = mother->GetMother();
234 CreateLabelMap(source);
236 // Actual filtering and label remapping (shamelessly taken for the implementation of AliAODHandler::StoreMCParticles)
237 TIter nextMC(mcParticles);
242 while ( ( p = static_cast<AliAODMCParticle*>(nextMC()) ) )
244 AliAODMCParticle c(*p);
246 if ( IsParticleSelected(nmc) )
249 Int_t d0 = p->GetDaughter(0);
250 Int_t d1 = p->GetDaughter(1);
251 Int_t m = p->GetMother();
253 // other than for the track labels, negative values mean
254 // no daughter/mother so preserve it
258 // no first daughter -> no second daughter
259 // nothing to be done
260 // second condition not needed just for sanity check at the end
263 } else if(d1 < 0 && d0 >= 0)
266 // second condition not needed just for sanity check at the end
267 if(IsParticleSelected(d0))
269 c.SetDaughter(0,GetNewLabel(d0));
276 else if (d0 > 0 && d1 > 0 )
278 // we have two or more daughters loop on the stack to see if they are
282 for (int id = d0; id<=d1;++id)
284 if (IsParticleSelected(id))
289 d0tmp = GetNewLabel(id);
290 d1tmp = d0tmp; // this is to have the same schema as on the stack i.e. with one daugther d0 and d1 are the same
292 else d1tmp = GetNewLabel(id);
295 c.SetDaughter(0,d0tmp);
296 c.SetDaughter(1,d1tmp);
299 AliError(Form("Unxpected indices %d %d",d0,d1));
307 if (IsParticleSelected(m))
309 c.SetMother(GetNewLabel(m));
313 AliError(Form("PROBLEM Mother not selected %d", m));
317 new ((*fMCParticles)[nmcout++]) AliAODMCParticle(c);
323 // now remap the tracks...
325 TIter nextTrack(fTracks);
328 while ( ( t = static_cast<AliAODTrack*>(nextTrack()) ) )
330 t->SetLabel(GetNewLabel(t->GetLabel()));
334 else if ( mcParticles )
336 // simple copy of input MC particles to ouput MC particles
337 TIter nextMC(mcParticles);
341 while ( ( p = static_cast<AliAODMCParticle*>(nextMC()) ) )
343 new ((*fMCParticles)[nmcout++]) AliAODMCParticle(*p);
347 AliDebug(1,Form("input mc %d output mc %d",
348 mcParticles ? mcParticles->GetEntries() : 0,
349 fMCParticles ? fMCParticles->GetEntries() : 0));
353 //_____________________________________________________________________________
354 TList* AliAODMuonReplicator::GetList() const
356 /// return (and build if not already done) our internal list of managed objects
359 if ( fReplicateHeader )
361 fHeader = new AliAODHeader;
364 if ( fReplicateTracklets )
366 fTracklets = new AliAODTracklets;
367 fTracklets->SetName("tracklets");
370 fTracks = new TClonesArray("AliAODTrack",30);
371 fTracks->SetName("tracks");
373 fVertices = new TClonesArray("AliAODVertex",2);
374 fVertices->SetName("vertices");
376 fDimuons = new TClonesArray("AliAODDimuon",20);
377 fDimuons->SetName("dimuons");
379 fVZERO = new AliAODVZERO;
381 fTZERO = new AliAODTZERO;
383 fZDC = new AliAODZDC;
386 fList->SetOwner(kTRUE);
390 fList->Add(fVertices);
391 fList->Add(fTracklets);
392 fList->Add(fDimuons);
399 fMCHeader = new AliAODMCHeader;
400 fMCParticles = new TClonesArray("AliAODMCParticle",1000);
401 fMCParticles->SetName(AliAODMCParticle::StdBranchName());
402 fList->Add(fMCHeader);
403 fList->Add(fMCParticles);
409 //_____________________________________________________________________________
410 void AliAODMuonReplicator::ReplicateAndFilter(const AliAODEvent& source)
412 /// Replicate (and filter if filters are there) the relevant
413 /// parts we're interested in AODEvent
415 assert(fTracks!=0x0);
417 if (fReplicateHeader)
419 AliAODHeader * header = dynamic_cast<AliAODHeader*>(source.GetHeader());
420 if(!header) AliFatal("Not a standard AOD");
421 *fHeader = *(header);
424 if (fReplicateTracklets)
426 *fTracklets = *(source.GetTracklets());
429 *fVZERO = *(source.GetVZEROData());
431 *fTZERO = *(source.GetTZEROData());
433 *fZDC = *(source.GetZDCData());
436 TIter next(source.GetTracks());
441 while (( t = static_cast<AliAODTrack*>(next()) )) {
443 if (t->IsMuonTrack() || t->IsMuonGlobalTrack()) ++inputMuons; // just a counter: MUON and MUON+MFT tracks before track cuts are applied
445 // MUON and MUON+MFT tracks selected // AU
446 if (!fTrackCut || fTrackCut->IsSelected(t)) {
447 new ((*fTracks)[nMuons++]) AliAODTrack(*t);
452 assert(fVertices!=0x0);
453 fVertices->Clear("C");
454 TIter nextV(source.GetVertices());
458 while ( ( v = static_cast<AliAODVertex*>(nextV()) ) ) {
459 if ( !fVertexCut || fVertexCut->IsSelected(v) ) {
460 AliAODVertex* tmp = v->CloneWithoutRefs();
461 AliAODVertex* copiedVertex = new((*fVertices)[nvertices++]) AliAODVertex(*tmp);
462 // to insure the main vertex retains the ncontributors information
463 // (which is otherwise computed dynamically from
464 // references to tracks, which we do not keep in muon aods...)
466 copiedVertex->SetNContributors(v->GetNContributors());
471 fDimuons->Clear("C");
473 // as there might be a track cut (different from the one of the main filtering),
474 // we must recreate the dimuon completely from scratch to be 100% safe...
478 // Dimuons built of 2 MUON tracks or 2 MUON+MFT tracks // AU
479 for (Int_t i=0; i<nMuons; ++i) {
480 for (Int_t j=i+1; j<nMuons; ++j) {
481 if ( (((AliAODTrack*) fTracks->At(i))->IsMuonTrack() && ((AliAODTrack*) fTracks->At(j))->IsMuonTrack()) ||
482 (((AliAODTrack*) fTracks->At(i))->IsMuonGlobalTrack() && ((AliAODTrack*) fTracks->At(j))->IsMuonGlobalTrack()) ) {
483 new((*fDimuons)[nDimuons++]) AliAODDimuon(fTracks->At(i), fTracks->At(j));
488 AliDebug(1,Form("input mu tracks=%d tracks=%d vertices=%d ndimuons=%d",
489 inputMuons,fTracks->GetEntries(),fVertices->GetEntries(),fDimuons->GetEntries()));
491 // Finally, deal with MC information, if needed
493 if (fMCMode>0) FilterMC(source);