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