]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG3/muon/AliAODMuonReplicator.cxx
fixes from Laurent for the MC branch in the AOD filters
[u/mrichter/AliRoot.git] / PWG3 / muon / AliAODMuonReplicator.cxx
CommitLineData
26ba01d4 1/**************************************************************************
2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
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**************************************************************************/
15
16// $Id$
17
3d270be0 18//
19// Implementation of a branch replicator
20// to produce slim muon and dimuon aods.
21//
22// This replicator is in charge of replicating the tracks,vertices and dimuons
23// branches of the standard AOD into muon AODs (AliAOD.Muons.root and
24// AliAOD.Dimuons.root)
25//
26// The tracks are filtered so that only muon tracks (and only muon tracks
27// that pass the trackCut if present) make it to the output aods
28//
29// The vertices are filtered so that only the primary vertices make it
30// to the output aods.
31//
32// The dimuons are recreated here, according to the set of tracks
33// that pass the trackCut (that set may be the same as the input set,
34// but to be 100% safe, we always recreate the dimuons).
35//
36// Author: L. Aphecetche (Subatech)
37
26ba01d4 38#include "AliAODMuonReplicator.h"
39#include "AliAnalysisCuts.h"
40#include "AliAODEvent.h"
41#include "AliAODTrack.h"
3d270be0 42#include "AliAODDimuon.h"
14d6fad5 43#include "AliAODMCHeader.h"
44#include "AliAODMCParticle.h"
26ba01d4 45#include <cassert>
46
47ClassImp(AliAODMuonReplicator)
48
49//_____________________________________________________________________________
50AliAODMuonReplicator::AliAODMuonReplicator(const char* name, const char* title,
14d6fad5 51 AliAnalysisCuts* trackCut,
52 AliAnalysisCuts* vertexCut,
53 Int_t mcMode)
54:AliAODBranchReplicator(name,title),
26ba01d4 55fTrackCut(trackCut), fTracks(0x0),
3d270be0 56fVertexCut(vertexCut), fVertices(0x0),
57fDimuons(0x0),
14d6fad5 58fList(0x0),
59fMCParticles(0x0),
60fMCHeader(0x0),
61fMCMode(mcMode),
62fLabelMap(),
63fParticleSelected()
26ba01d4 64{
65 // default ctor
66}
67
68//_____________________________________________________________________________
69AliAODMuonReplicator::~AliAODMuonReplicator()
70{
71 // dtor
72 delete fTrackCut;
73 delete fVertexCut;
74 delete fList;
75}
76
14d6fad5 77//_____________________________________________________________________________
78void AliAODMuonReplicator::SelectParticle(Int_t i)
79{
80 // taking the absolute values here, need to take care
81 // of negative daughter and mother
82 // IDs when setting!
83
84 if (!IsParticleSelected(TMath::Abs(i)))
85 {
86 fParticleSelected.Add(TMath::Abs(i),1);
87 }
88}
89
90//_____________________________________________________________________________
91Bool_t AliAODMuonReplicator::IsParticleSelected(Int_t i)
92{
93 // taking the absolute values here, need to take
94 // care with negative daughter and mother
95 // IDs when setting!
96 return (fParticleSelected.GetValue(TMath::Abs(i))==1);
97}
98
99
100//_____________________________________________________________________________
101void AliAODMuonReplicator::CreateLabelMap(const AliAODEvent& source)
102{
103 //
104 // this should be called once all selections are done
105 //
106
107 fLabelMap.Delete();
108
109 TClonesArray* mcParticles = static_cast<TClonesArray*>(source.FindListObject(AliAODMCParticle::StdBranchName()));
110
111 Int_t i(0);
112 Int_t j(0);
113
114 TIter next(mcParticles);
115
116 while ( next() )
117 {
118 if (IsParticleSelected(i))
119 {
120 fLabelMap.Add(i,j++);
121 }
122 ++i;
123 }
124}
125
126//_____________________________________________________________________________
127Int_t AliAODMuonReplicator::GetNewLabel(Int_t i)
128{
129 // Gets the label from the new created Map
130 // Call CreatLabelMap before
131 // otherwise only 0 returned
132 return fLabelMap.GetValue(TMath::Abs(i));
133}
134
135//_____________________________________________________________________________
136void AliAODMuonReplicator::FilterMC(const AliAODEvent& source)
137{
138 // Filter MC information
139
140 fMCHeader->Reset();
141 fMCParticles->Clear("C");
142
143 AliAODMCHeader* mcHeader(0x0);
144 TClonesArray* mcParticles(0x0);
145
146 fParticleSelected.Delete();
147
148 if ( !fTracks->GetEntries() ) return;
149 // only copy MC information for events where there's at least one muon track
150
151 mcHeader = static_cast<AliAODMCHeader*>(source.FindListObject(AliAODMCHeader::StdBranchName()));
152
153 if ( mcHeader )
154 {
155 *fMCHeader = *mcHeader;
156 }
157
158 mcParticles = static_cast<TClonesArray*>(source.FindListObject(AliAODMCParticle::StdBranchName()));
159
160 if ( mcParticles && fMCMode>=2 )
161 {
162 // loop on (kept) muon tracks to find their ancestors
163 TIter nextMT(fTracks);
164 AliAODTrack* mt;
165 int outLabel(0);
166
167 while ( ( mt = static_cast<AliAODTrack*>(nextMT()) ) )
168 {
169 Int_t label = mt->GetLabel();
170
171 while ( label >= 0 )
172 {
173 SelectParticle(label);
174 AliAODMCParticle* mother = static_cast<AliAODMCParticle*>(mcParticles->UncheckedAt(label));
175 if (!mother)
176 {
177 AliError("Got a null mother ! Check that !");
178 label = -1;
179 }
180 else
181 {
182 label = mother->GetMother();
183 }
184 }
185 }
186
187 CreateLabelMap(source);
188
189 // Actual filtering and label remapping (shamelessly taken for the implementation of AliAODHandler::StoreMCParticles)
190 TIter nextMC(mcParticles);
191 AliAODMCParticle* p;
192 Int_t nmc(0);
193 Int_t nmcout(0);
194
195 while ( ( p = static_cast<AliAODMCParticle*>(nextMC()) ) )
196 {
197 AliAODMCParticle c(*p);
198
199 if ( IsParticleSelected(nmc) )
200 {
201 //
202 Int_t d0 = p->GetDaughter(0);
203 Int_t d1 = p->GetDaughter(1);
204 Int_t m = p->GetMother();
205
206 // other than for the track labels, negative values mean
207 // no daughter/mother so preserve it
208
209 if(d0<0 && d1<0)
210 {
211 // no first daughter -> no second daughter
212 // nothing to be done
213 // second condition not needed just for sanity check at the end
214 c.SetDaughter(0,d0);
215 c.SetDaughter(1,d1);
216 } else if(d1 < 0 && d0 >= 0)
217 {
218 // Only one daughter
219 // second condition not needed just for sanity check at the end
220 if(IsParticleSelected(d0))
221 {
222 c.SetDaughter(0,GetNewLabel(d0));
223 } else
224 {
225 c.SetDaughter(0,-1);
226 }
227 c.SetDaughter(1,d1);
228 }
229 else if (d0 > 0 && d1 > 0 )
230 {
231 // we have two or more daughters loop on the stack to see if they are
232 // selected
233 Int_t d0tmp = -1;
234 Int_t d1tmp = -1;
235 for (int id = d0; id<=d1;++id)
236 {
237 if (IsParticleSelected(id))
238 {
239 if(d0tmp==-1)
240 {
241 // first time
242 d0tmp = GetNewLabel(id);
243 d1tmp = d0tmp; // this is to have the same schema as on the stack i.e. with one daugther d0 and d1 are the same
244 }
245 else d1tmp = GetNewLabel(id);
246 }
247 }
248 c.SetDaughter(0,d0tmp);
249 c.SetDaughter(1,d1tmp);
250 } else
251 {
252 AliError(Form("Unxpected indices %d %d",d0,d1));
253 }
254
255 if ( m < 0 )
256 {
257 c.SetMother(m);
258 } else
259 {
260 if (IsParticleSelected(m))
261 {
262 c.SetMother(GetNewLabel(m));
263 }
264 else
265 {
266 AliError(Form("PROBLEM Mother not selected %d", m));
267 }
268 }
269
270 new ((*fMCParticles)[nmcout++]) AliAODMCParticle(c);
271 }
272
273 ++nmc;
274 }
275
276 // now remap the tracks...
277
278 TIter nextTrack(fTracks);
279 AliAODTrack* t;
280
281 while ( ( t = static_cast<AliAODTrack*>(nextTrack()) ) )
282 {
283 t->SetLabel(GetNewLabel(t->GetLabel()));
284 }
285
286 }
287 else if ( mcParticles )
288 {
289 // simple copy of input MC particles to ouput MC particles
290 TIter nextMC(mcParticles);
291 AliAODMCParticle* p;
292 Int_t nmcout(0);
293
294 while ( ( p = static_cast<AliAODMCParticle*>(nextMC()) ) )
295 {
296 new ((*fMCParticles)[nmcout++]) AliAODMCParticle(*p);
297 }
298 }
299
300 AliDebug(1,Form("input mc %d output mc %d",
301 mcParticles ? mcParticles->GetEntries() : 0,
302 fMCParticles ? fMCParticles->GetEntries() : 0));
303
304}
305
26ba01d4 306//_____________________________________________________________________________
307TList* AliAODMuonReplicator::GetList() const
308{
309 // return (and build if not already done) our internal list of managed objects
310 if (!fList)
311 {
3d270be0 312 fTracks = new TClonesArray("AliAODTrack",30);
26ba01d4 313 fTracks->SetName("tracks");
3d270be0 314
315 fVertices = new TClonesArray("AliAODVertex",2);
26ba01d4 316 fVertices->SetName("vertices");
14d6fad5 317
3d270be0 318 fDimuons = new TClonesArray("AliAODDimuon",2);
319 fDimuons->SetName("dimuons");
320
321 fList = new TList;
322 fList->SetOwner(kTRUE);
323
26ba01d4 324 fList->Add(fTracks);
325 fList->Add(fVertices);
3d270be0 326 fList->Add(fDimuons);
14d6fad5 327
328 if ( fMCMode > 0 )
329 {
330 fMCHeader = new AliAODMCHeader;
331 fMCParticles = new TClonesArray("AliAODMCParticle",1000);
332 fMCParticles->SetName(AliAODMCParticle::StdBranchName());
333 fList->Add(fMCHeader);
334 fList->Add(fMCParticles);
335 }
26ba01d4 336 }
337 return fList;
338}
339
340//_____________________________________________________________________________
341void AliAODMuonReplicator::ReplicateAndFilter(const AliAODEvent& source)
342{
343 // Replicate (and filter if filters are there) the relevant parts we're interested in AODEvent
344
26ba01d4 345 assert(fTracks!=0x0);
346 fTracks->Clear("C");
347 TIter next(source.GetTracks());
348 AliAODTrack* t;
349 Int_t ntracks(0);
14d6fad5 350 Int_t input(0);
26ba01d4 351
352 while ( ( t = static_cast<AliAODTrack*>(next()) ) )
353 {
14d6fad5 354 if ( t->IsMuonTrack() )
355 {
356 ++input;
357 }
358
26ba01d4 359 if ( !fTrackCut || fTrackCut->IsSelected(t) )
360 {
361 new((*fTracks)[ntracks++]) AliAODTrack(*t);
362 }
363 }
364
365 assert(fVertices!=0x0);
366 fVertices->Clear("C");
367 TIter nextV(source.GetVertices());
368 AliAODVertex* v;
369 Int_t nvertices(0);
370
371 while ( ( v = static_cast<AliAODVertex*>(nextV()) ) )
372 {
373 if ( !fVertexCut || fVertexCut->IsSelected(v) )
374 {
375 AliAODVertex* tmp = v->CloneWithoutRefs();
376 new((*fVertices)[nvertices++]) AliAODVertex(*tmp);
377 delete tmp;
378 }
379 }
380
3d270be0 381 fDimuons->Clear("C");
382
383 // as there might be a track cut (different from the one of the main filtering),
384 // we must recreate the dimuon completely from scratch to be 100% safe...
385
386 Int_t ndimuons(0);
387
388 for ( Int_t i = 0; i < ntracks; ++i )
389 {
390 for ( Int_t j = i+1; j < ntracks; ++j )
391 {
392 new((*fDimuons)[ndimuons++]) AliAODDimuon(fTracks->At(i),fTracks->At(j));
393 }
394 }
14d6fad5 395
396 AliDebug(1,Form("input mu tracks=%d tracks=%d vertices=%d ndimuons=%d",
397 input,fTracks->GetEntries(),fVertices->GetEntries(),fDimuons->GetEntries()));
398
399 // Finally, deal with MC information, if needed
400
401 if ( fMCMode > 0 )
402 {
403 FilterMC(source);
404 }
26ba01d4 405}
406