]>
Commit | Line | Data |
---|---|---|
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 | ||
47 | ClassImp(AliAODMuonReplicator) | |
48 | ||
49 | //_____________________________________________________________________________ | |
50 | AliAODMuonReplicator::AliAODMuonReplicator(const char* name, const char* title, | |
14d6fad5 | 51 | AliAnalysisCuts* trackCut, |
52 | AliAnalysisCuts* vertexCut, | |
53 | Int_t mcMode) | |
54 | :AliAODBranchReplicator(name,title), | |
26ba01d4 | 55 | fTrackCut(trackCut), fTracks(0x0), |
3d270be0 | 56 | fVertexCut(vertexCut), fVertices(0x0), |
57 | fDimuons(0x0), | |
14d6fad5 | 58 | fList(0x0), |
59 | fMCParticles(0x0), | |
60 | fMCHeader(0x0), | |
61 | fMCMode(mcMode), | |
62 | fLabelMap(), | |
63 | fParticleSelected() | |
26ba01d4 | 64 | { |
65 | // default ctor | |
66 | } | |
67 | ||
68 | //_____________________________________________________________________________ | |
69 | AliAODMuonReplicator::~AliAODMuonReplicator() | |
70 | { | |
71 | // dtor | |
72 | delete fTrackCut; | |
73 | delete fVertexCut; | |
74 | delete fList; | |
75 | } | |
76 | ||
14d6fad5 | 77 | //_____________________________________________________________________________ |
78 | void 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 | //_____________________________________________________________________________ | |
91 | Bool_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 | //_____________________________________________________________________________ | |
101 | void 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 | //_____________________________________________________________________________ | |
127 | Int_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 | //_____________________________________________________________________________ | |
136 | void 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; | |
14d6fad5 | 165 | |
166 | while ( ( mt = static_cast<AliAODTrack*>(nextMT()) ) ) | |
167 | { | |
168 | Int_t label = mt->GetLabel(); | |
169 | ||
170 | while ( label >= 0 ) | |
171 | { | |
172 | SelectParticle(label); | |
173 | AliAODMCParticle* mother = static_cast<AliAODMCParticle*>(mcParticles->UncheckedAt(label)); | |
174 | if (!mother) | |
175 | { | |
176 | AliError("Got a null mother ! Check that !"); | |
177 | label = -1; | |
178 | } | |
179 | else | |
180 | { | |
181 | label = mother->GetMother(); | |
182 | } | |
183 | } | |
184 | } | |
185 | ||
186 | CreateLabelMap(source); | |
187 | ||
188 | // Actual filtering and label remapping (shamelessly taken for the implementation of AliAODHandler::StoreMCParticles) | |
189 | TIter nextMC(mcParticles); | |
190 | AliAODMCParticle* p; | |
191 | Int_t nmc(0); | |
192 | Int_t nmcout(0); | |
193 | ||
194 | while ( ( p = static_cast<AliAODMCParticle*>(nextMC()) ) ) | |
195 | { | |
196 | AliAODMCParticle c(*p); | |
197 | ||
198 | if ( IsParticleSelected(nmc) ) | |
199 | { | |
200 | // | |
201 | Int_t d0 = p->GetDaughter(0); | |
202 | Int_t d1 = p->GetDaughter(1); | |
203 | Int_t m = p->GetMother(); | |
204 | ||
205 | // other than for the track labels, negative values mean | |
206 | // no daughter/mother so preserve it | |
207 | ||
208 | if(d0<0 && d1<0) | |
209 | { | |
210 | // no first daughter -> no second daughter | |
211 | // nothing to be done | |
212 | // second condition not needed just for sanity check at the end | |
213 | c.SetDaughter(0,d0); | |
214 | c.SetDaughter(1,d1); | |
215 | } else if(d1 < 0 && d0 >= 0) | |
216 | { | |
217 | // Only one daughter | |
218 | // second condition not needed just for sanity check at the end | |
219 | if(IsParticleSelected(d0)) | |
220 | { | |
221 | c.SetDaughter(0,GetNewLabel(d0)); | |
222 | } else | |
223 | { | |
224 | c.SetDaughter(0,-1); | |
225 | } | |
226 | c.SetDaughter(1,d1); | |
227 | } | |
228 | else if (d0 > 0 && d1 > 0 ) | |
229 | { | |
230 | // we have two or more daughters loop on the stack to see if they are | |
231 | // selected | |
232 | Int_t d0tmp = -1; | |
233 | Int_t d1tmp = -1; | |
234 | for (int id = d0; id<=d1;++id) | |
235 | { | |
236 | if (IsParticleSelected(id)) | |
237 | { | |
238 | if(d0tmp==-1) | |
239 | { | |
240 | // first time | |
241 | d0tmp = GetNewLabel(id); | |
242 | d1tmp = d0tmp; // this is to have the same schema as on the stack i.e. with one daugther d0 and d1 are the same | |
243 | } | |
244 | else d1tmp = GetNewLabel(id); | |
245 | } | |
246 | } | |
247 | c.SetDaughter(0,d0tmp); | |
248 | c.SetDaughter(1,d1tmp); | |
249 | } else | |
250 | { | |
251 | AliError(Form("Unxpected indices %d %d",d0,d1)); | |
252 | } | |
253 | ||
254 | if ( m < 0 ) | |
255 | { | |
256 | c.SetMother(m); | |
257 | } else | |
258 | { | |
259 | if (IsParticleSelected(m)) | |
260 | { | |
261 | c.SetMother(GetNewLabel(m)); | |
262 | } | |
263 | else | |
264 | { | |
265 | AliError(Form("PROBLEM Mother not selected %d", m)); | |
266 | } | |
267 | } | |
268 | ||
269 | new ((*fMCParticles)[nmcout++]) AliAODMCParticle(c); | |
270 | } | |
271 | ||
272 | ++nmc; | |
273 | } | |
274 | ||
275 | // now remap the tracks... | |
276 | ||
277 | TIter nextTrack(fTracks); | |
278 | AliAODTrack* t; | |
279 | ||
280 | while ( ( t = static_cast<AliAODTrack*>(nextTrack()) ) ) | |
281 | { | |
282 | t->SetLabel(GetNewLabel(t->GetLabel())); | |
283 | } | |
284 | ||
285 | } | |
286 | else if ( mcParticles ) | |
287 | { | |
288 | // simple copy of input MC particles to ouput MC particles | |
289 | TIter nextMC(mcParticles); | |
290 | AliAODMCParticle* p; | |
291 | Int_t nmcout(0); | |
292 | ||
293 | while ( ( p = static_cast<AliAODMCParticle*>(nextMC()) ) ) | |
294 | { | |
295 | new ((*fMCParticles)[nmcout++]) AliAODMCParticle(*p); | |
296 | } | |
297 | } | |
298 | ||
299 | AliDebug(1,Form("input mc %d output mc %d", | |
300 | mcParticles ? mcParticles->GetEntries() : 0, | |
301 | fMCParticles ? fMCParticles->GetEntries() : 0)); | |
302 | ||
303 | } | |
304 | ||
26ba01d4 | 305 | //_____________________________________________________________________________ |
306 | TList* AliAODMuonReplicator::GetList() const | |
307 | { | |
308 | // return (and build if not already done) our internal list of managed objects | |
309 | if (!fList) | |
310 | { | |
3d270be0 | 311 | fTracks = new TClonesArray("AliAODTrack",30); |
26ba01d4 | 312 | fTracks->SetName("tracks"); |
3d270be0 | 313 | |
314 | fVertices = new TClonesArray("AliAODVertex",2); | |
26ba01d4 | 315 | fVertices->SetName("vertices"); |
14d6fad5 | 316 | |
3d270be0 | 317 | fDimuons = new TClonesArray("AliAODDimuon",2); |
318 | fDimuons->SetName("dimuons"); | |
319 | ||
320 | fList = new TList; | |
321 | fList->SetOwner(kTRUE); | |
322 | ||
26ba01d4 | 323 | fList->Add(fTracks); |
324 | fList->Add(fVertices); | |
3d270be0 | 325 | fList->Add(fDimuons); |
14d6fad5 | 326 | |
327 | if ( fMCMode > 0 ) | |
328 | { | |
329 | fMCHeader = new AliAODMCHeader; | |
330 | fMCParticles = new TClonesArray("AliAODMCParticle",1000); | |
331 | fMCParticles->SetName(AliAODMCParticle::StdBranchName()); | |
332 | fList->Add(fMCHeader); | |
333 | fList->Add(fMCParticles); | |
334 | } | |
26ba01d4 | 335 | } |
336 | return fList; | |
337 | } | |
338 | ||
339 | //_____________________________________________________________________________ | |
340 | void AliAODMuonReplicator::ReplicateAndFilter(const AliAODEvent& source) | |
341 | { | |
342 | // Replicate (and filter if filters are there) the relevant parts we're interested in AODEvent | |
343 | ||
26ba01d4 | 344 | assert(fTracks!=0x0); |
345 | fTracks->Clear("C"); | |
346 | TIter next(source.GetTracks()); | |
347 | AliAODTrack* t; | |
348 | Int_t ntracks(0); | |
14d6fad5 | 349 | Int_t input(0); |
26ba01d4 | 350 | |
351 | while ( ( t = static_cast<AliAODTrack*>(next()) ) ) | |
352 | { | |
14d6fad5 | 353 | if ( t->IsMuonTrack() ) |
354 | { | |
355 | ++input; | |
356 | } | |
357 | ||
26ba01d4 | 358 | if ( !fTrackCut || fTrackCut->IsSelected(t) ) |
359 | { | |
360 | new((*fTracks)[ntracks++]) AliAODTrack(*t); | |
361 | } | |
362 | } | |
363 | ||
364 | assert(fVertices!=0x0); | |
365 | fVertices->Clear("C"); | |
366 | TIter nextV(source.GetVertices()); | |
367 | AliAODVertex* v; | |
368 | Int_t nvertices(0); | |
369 | ||
370 | while ( ( v = static_cast<AliAODVertex*>(nextV()) ) ) | |
371 | { | |
372 | if ( !fVertexCut || fVertexCut->IsSelected(v) ) | |
373 | { | |
374 | AliAODVertex* tmp = v->CloneWithoutRefs(); | |
375 | new((*fVertices)[nvertices++]) AliAODVertex(*tmp); | |
376 | delete tmp; | |
377 | } | |
378 | } | |
379 | ||
3d270be0 | 380 | fDimuons->Clear("C"); |
381 | ||
382 | // as there might be a track cut (different from the one of the main filtering), | |
383 | // we must recreate the dimuon completely from scratch to be 100% safe... | |
384 | ||
385 | Int_t ndimuons(0); | |
386 | ||
387 | for ( Int_t i = 0; i < ntracks; ++i ) | |
388 | { | |
389 | for ( Int_t j = i+1; j < ntracks; ++j ) | |
390 | { | |
391 | new((*fDimuons)[ndimuons++]) AliAODDimuon(fTracks->At(i),fTracks->At(j)); | |
392 | } | |
393 | } | |
14d6fad5 | 394 | |
395 | AliDebug(1,Form("input mu tracks=%d tracks=%d vertices=%d ndimuons=%d", | |
396 | input,fTracks->GetEntries(),fVertices->GetEntries(),fDimuons->GetEntries())); | |
397 | ||
398 | // Finally, deal with MC information, if needed | |
399 | ||
400 | if ( fMCMode > 0 ) | |
401 | { | |
402 | FilterMC(source); | |
403 | } | |
26ba01d4 | 404 | } |
405 |