]>
Commit | Line | Data |
---|---|---|
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 | 50 | ClassImp(AliAODMuonReplicator) |
8dda6345 | 51 | /// \endcond |
26ba01d4 | 52 | |
53 | //_____________________________________________________________________________ | |
54 | AliAODMuonReplicator::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 | 61 | fTrackCut(trackCut), fTracks(0x0), |
3d270be0 | 62 | fVertexCut(vertexCut), fVertices(0x0), |
63 | fDimuons(0x0), | |
5393f2c0 | 64 | fVZERO(0x0), |
3493cd3f | 65 | fTZERO(0x0), |
8dda6345 | 66 | fHeader(0x0), |
67 | fTracklets(0x0), | |
68 | fZDC(0x0), | |
14d6fad5 | 69 | fList(0x0), |
70 | fMCParticles(0x0), | |
71 | fMCHeader(0x0), | |
72 | fMCMode(mcMode), | |
73 | fLabelMap(), | |
8dda6345 | 74 | fParticleSelected(), |
75 | fReplicateHeader(replicateHeader), | |
76 | fReplicateTracklets(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 | //_____________________________________________________________________________ | |
91 | AliAODMuonReplicator::~AliAODMuonReplicator() | |
92 | { | |
8dda6345 | 93 | /// dtor |
26ba01d4 | 94 | delete fTrackCut; |
95 | delete fVertexCut; | |
96 | delete fList; | |
97 | } | |
98 | ||
14d6fad5 | 99 | //_____________________________________________________________________________ |
100 | void 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 | //_____________________________________________________________________________ | |
113 | Bool_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 | //_____________________________________________________________________________ | |
123 | void 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 | //_____________________________________________________________________________ | |
149 | Int_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 | //_____________________________________________________________________________ | |
158 | void 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 | //_____________________________________________________________________________ |
328 | TList* 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 | //_____________________________________________________________________________ | |
384 | void 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 |