]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG/muon/AliAODMuonReplicator.cxx
Merge branch 'feature-movesplit'
[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
737c3d9e 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
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
737c3d9e 208 if ( mcParticles && fMCMode==3 )
209 {
210 // loop on MC muon tracks to find their ancestors
211 for ( Int_t ipart=0; ipart<mcParticles->GetEntries(); ipart++ )
212 {
213 AliAODMCParticle* mcp = static_cast<AliAODMCParticle*>(mcParticles->UncheckedAt(ipart));
214 if ( TMath::Abs(mcp->PdgCode()) != 13 ) continue;
215 Int_t label = ipart;
216
217 while ( label >= 0 )
218 {
219 SelectParticle(label);
220 AliAODMCParticle* mother = static_cast<AliAODMCParticle*>(mcParticles->UncheckedAt(label));
221 if (!mother)
222 {
223 AliError("Got a null mother ! Check that !");
224 label = -1;
225 }
226 else
227 {
228 label = mother->GetMother();
229 }
230 }
231 }
232 }
233
14d6fad5 234 CreateLabelMap(source);
235
236 // Actual filtering and label remapping (shamelessly taken for the implementation of AliAODHandler::StoreMCParticles)
237 TIter nextMC(mcParticles);
238 AliAODMCParticle* p;
239 Int_t nmc(0);
240 Int_t nmcout(0);
241
242 while ( ( p = static_cast<AliAODMCParticle*>(nextMC()) ) )
243 {
244 AliAODMCParticle c(*p);
245
246 if ( IsParticleSelected(nmc) )
247 {
248 //
249 Int_t d0 = p->GetDaughter(0);
250 Int_t d1 = p->GetDaughter(1);
251 Int_t m = p->GetMother();
252
253 // other than for the track labels, negative values mean
254 // no daughter/mother so preserve it
255
256 if(d0<0 && d1<0)
257 {
258 // no first daughter -> no second daughter
259 // nothing to be done
260 // second condition not needed just for sanity check at the end
261 c.SetDaughter(0,d0);
262 c.SetDaughter(1,d1);
263 } else if(d1 < 0 && d0 >= 0)
264 {
265 // Only one daughter
266 // second condition not needed just for sanity check at the end
267 if(IsParticleSelected(d0))
268 {
269 c.SetDaughter(0,GetNewLabel(d0));
270 } else
271 {
272 c.SetDaughter(0,-1);
273 }
274 c.SetDaughter(1,d1);
275 }
276 else if (d0 > 0 && d1 > 0 )
277 {
278 // we have two or more daughters loop on the stack to see if they are
279 // selected
280 Int_t d0tmp = -1;
281 Int_t d1tmp = -1;
282 for (int id = d0; id<=d1;++id)
283 {
284 if (IsParticleSelected(id))
285 {
286 if(d0tmp==-1)
287 {
288 // first time
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
291 }
292 else d1tmp = GetNewLabel(id);
293 }
294 }
295 c.SetDaughter(0,d0tmp);
296 c.SetDaughter(1,d1tmp);
297 } else
298 {
299 AliError(Form("Unxpected indices %d %d",d0,d1));
300 }
301
302 if ( m < 0 )
303 {
304 c.SetMother(m);
305 } else
306 {
307 if (IsParticleSelected(m))
308 {
309 c.SetMother(GetNewLabel(m));
310 }
311 else
312 {
313 AliError(Form("PROBLEM Mother not selected %d", m));
314 }
315 }
316
317 new ((*fMCParticles)[nmcout++]) AliAODMCParticle(c);
318 }
319
320 ++nmc;
321 }
322
323 // now remap the tracks...
324
325 TIter nextTrack(fTracks);
326 AliAODTrack* t;
327
328 while ( ( t = static_cast<AliAODTrack*>(nextTrack()) ) )
329 {
330 t->SetLabel(GetNewLabel(t->GetLabel()));
331 }
332
333 }
334 else if ( mcParticles )
335 {
336 // simple copy of input MC particles to ouput MC particles
337 TIter nextMC(mcParticles);
338 AliAODMCParticle* p;
339 Int_t nmcout(0);
340
341 while ( ( p = static_cast<AliAODMCParticle*>(nextMC()) ) )
342 {
343 new ((*fMCParticles)[nmcout++]) AliAODMCParticle(*p);
344 }
345 }
346
347 AliDebug(1,Form("input mc %d output mc %d",
348 mcParticles ? mcParticles->GetEntries() : 0,
349 fMCParticles ? fMCParticles->GetEntries() : 0));
350
351}
352
26ba01d4 353//_____________________________________________________________________________
354TList* AliAODMuonReplicator::GetList() const
355{
8dda6345 356 /// return (and build if not already done) our internal list of managed objects
26ba01d4 357 if (!fList)
358 {
8dda6345 359 if ( fReplicateHeader )
360 {
361 fHeader = new AliAODHeader;
362 }
363
364 if ( fReplicateTracklets )
365 {
366 fTracklets = new AliAODTracklets;
367 fTracklets->SetName("tracklets");
368 }
369
3d270be0 370 fTracks = new TClonesArray("AliAODTrack",30);
f7cc8591 371 fTracks->SetName("tracks");
3d270be0 372
373 fVertices = new TClonesArray("AliAODVertex",2);
f7cc8591 374 fVertices->SetName("vertices");
14d6fad5 375
f7cc8591 376 fDimuons = new TClonesArray("AliAODDimuon",20);
3d270be0 377 fDimuons->SetName("dimuons");
378
5393f2c0 379 fVZERO = new AliAODVZERO;
380
3493cd3f 381 fTZERO = new AliAODTZERO;
382
8dda6345 383 fZDC = new AliAODZDC;
384
3d270be0 385 fList = new TList;
386 fList->SetOwner(kTRUE);
387
8dda6345 388 fList->Add(fHeader);
26ba01d4 389 fList->Add(fTracks);
390 fList->Add(fVertices);
8dda6345 391 fList->Add(fTracklets);
3d270be0 392 fList->Add(fDimuons);
5393f2c0 393 fList->Add(fVZERO);
3493cd3f 394 fList->Add(fTZERO);
8dda6345 395 fList->Add(fZDC);
eb7548df 396
14d6fad5 397 if ( fMCMode > 0 )
398 {
399 fMCHeader = new AliAODMCHeader;
400 fMCParticles = new TClonesArray("AliAODMCParticle",1000);
401 fMCParticles->SetName(AliAODMCParticle::StdBranchName());
402 fList->Add(fMCHeader);
403 fList->Add(fMCParticles);
404 }
26ba01d4 405 }
406 return fList;
407}
408
409//_____________________________________________________________________________
410void AliAODMuonReplicator::ReplicateAndFilter(const AliAODEvent& source)
411{
8dda6345 412 /// Replicate (and filter if filters are there) the relevant
413 /// parts we're interested in AODEvent
26ba01d4 414
26ba01d4 415 assert(fTracks!=0x0);
eb7548df 416
8dda6345 417 if (fReplicateHeader)
418 {
0a918d8d 419 AliAODHeader * header = dynamic_cast<AliAODHeader*>(source.GetHeader());
420 if(!header) AliFatal("Not a standard AOD");
421 *fHeader = *(header);
8dda6345 422 }
423
424 if (fReplicateTracklets)
425 {
426 *fTracklets = *(source.GetTracklets());
427 }
428
5393f2c0 429 *fVZERO = *(source.GetVZEROData());
3493cd3f 430
431 *fTZERO = *(source.GetTZEROData());
432
8dda6345 433 *fZDC = *(source.GetZDCData());
434
26ba01d4 435 fTracks->Clear("C");
436 TIter next(source.GetTracks());
437 AliAODTrack* t;
f7cc8591 438 Int_t nMuons=0;
439 Int_t inputMuons=0;
26ba01d4 440
f7cc8591 441 while (( t = static_cast<AliAODTrack*>(next()) )) {
442
443 if (t->IsMuonTrack() || t->IsMuonGlobalTrack()) ++inputMuons; // just a counter: MUON and MUON+MFT tracks before track cuts are applied
444
445 // MUON and MUON+MFT tracks selected // AU
446 if (!fTrackCut || fTrackCut->IsSelected(t)) {
447 new ((*fTracks)[nMuons++]) AliAODTrack(*t);
26ba01d4 448 }
f7cc8591 449
26ba01d4 450 }
451
452 assert(fVertices!=0x0);
453 fVertices->Clear("C");
454 TIter nextV(source.GetVertices());
455 AliAODVertex* v;
456 Int_t nvertices(0);
457
f7cc8591 458 while ( ( v = static_cast<AliAODVertex*>(nextV()) ) ) {
459 if ( !fVertexCut || fVertexCut->IsSelected(v) ) {
26ba01d4 460 AliAODVertex* tmp = v->CloneWithoutRefs();
eb7548df 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...)
465 // we set it here
466 copiedVertex->SetNContributors(v->GetNContributors());
26ba01d4 467 delete tmp;
468 }
469 }
470
3d270be0 471 fDimuons->Clear("C");
472
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...
475
f7cc8591 476 Int_t nDimuons=0;
3d270be0 477
f7cc8591 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));
484 }
3d270be0 485 }
486 }
14d6fad5 487
488 AliDebug(1,Form("input mu tracks=%d tracks=%d vertices=%d ndimuons=%d",
f7cc8591 489 inputMuons,fTracks->GetEntries(),fVertices->GetEntries(),fDimuons->GetEntries()));
14d6fad5 490
491 // Finally, deal with MC information, if needed
492
f7cc8591 493 if (fMCMode>0) FilterMC(source);
494
26ba01d4 495}
496