]>
Commit | Line | Data |
---|---|---|
ec4af4c1 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-2007, 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 | ||
18 | //------------------------------------------------------------------------- | |
19 | // Implementation of the Virtual Event Handler Interface for AOD | |
20 | // Author: Andreas Morsch, CERN | |
21 | //------------------------------------------------------------------------- | |
22 | ||
052994fb | 23 | |
ec4af4c1 | 24 | #include <TTree.h> |
e910dd36 | 25 | #include <TFile.h> |
7970f4ac | 26 | #include <TString.h> |
da97a08a | 27 | #include <TExMap.h> |
e910dd36 | 28 | |
da97a08a | 29 | #include "AliLog.h" |
ec4af4c1 | 30 | #include "AliAODHandler.h" |
31 | #include "AliAODEvent.h" | |
da97a08a | 32 | #include "AliAODTracklets.h" |
33 | #include "AliStack.h" | |
34 | #include "AliAODMCParticle.h" | |
35 | #include "AliMCEventHandler.h" | |
36 | #include "AliMCEvent.h" | |
ec4af4c1 | 37 | |
38 | ClassImp(AliAODHandler) | |
39 | ||
40 | //______________________________________________________________________________ | |
41 | AliAODHandler::AliAODHandler() : | |
f3214a54 | 42 | AliVEventHandler(), |
78f7f935 | 43 | fIsStandard(kTRUE), |
da97a08a | 44 | fFillAOD(kTRUE), |
7c3a9fbf | 45 | fNeedsHeaderReplication(kFALSE), |
75754ba8 | 46 | fNeedsTracksBranchReplication(kFALSE), |
47 | fNeedsVerticesBranchReplication(kFALSE), | |
48 | fNeedsV0sBranchReplication(kFALSE), | |
49 | fNeedsTrackletsBranchReplication(kFALSE), | |
50 | fNeedsPMDClustersBranchReplication(kFALSE), | |
51 | fNeedsJetsBranchReplication(kFALSE), | |
52 | fNeedsFMDClustersBranchReplication(kFALSE), | |
53 | fNeedsCaloClustersBranchReplication(kFALSE), | |
54 | fAODIsReplicated(kFALSE), | |
ec4af4c1 | 55 | fAODEvent(NULL), |
da97a08a | 56 | fMCEventH(NULL), |
e910dd36 | 57 | fTreeA(NULL), |
58 | fFileA(NULL), | |
7970f4ac | 59 | fFileName("") |
ec4af4c1 | 60 | { |
61 | // default constructor | |
62 | } | |
63 | ||
64 | //______________________________________________________________________________ | |
65 | AliAODHandler::AliAODHandler(const char* name, const char* title): | |
f3214a54 | 66 | AliVEventHandler(name, title), |
78f7f935 | 67 | fIsStandard(kTRUE), |
da97a08a | 68 | fFillAOD(kTRUE), |
7c3a9fbf | 69 | fNeedsHeaderReplication(kFALSE), |
75754ba8 | 70 | fNeedsTracksBranchReplication(kFALSE), |
71 | fNeedsVerticesBranchReplication(kFALSE), | |
72 | fNeedsV0sBranchReplication(kFALSE), | |
73 | fNeedsTrackletsBranchReplication(kFALSE), | |
74 | fNeedsPMDClustersBranchReplication(kFALSE), | |
75 | fNeedsJetsBranchReplication(kFALSE), | |
76 | fNeedsFMDClustersBranchReplication(kFALSE), | |
77 | fNeedsCaloClustersBranchReplication(kFALSE), | |
78 | fAODIsReplicated(kFALSE), | |
ec4af4c1 | 79 | fAODEvent(NULL), |
da97a08a | 80 | fMCEventH(NULL), |
e910dd36 | 81 | fTreeA(NULL), |
82 | fFileA(NULL), | |
7970f4ac | 83 | fFileName("") |
ec4af4c1 | 84 | { |
85 | } | |
86 | ||
87 | //______________________________________________________________________________ | |
88 | AliAODHandler::~AliAODHandler() | |
89 | { | |
6989bff3 | 90 | delete fAODEvent; |
91 | if(fFileA){ | |
92 | // is already handled in TerminateIO | |
93 | fFileA->Close(); | |
94 | delete fFileA; | |
95 | } | |
96 | delete fTreeA; | |
6989bff3 | 97 | // destructor |
ec4af4c1 | 98 | } |
99 | ||
7970f4ac | 100 | //______________________________________________________________________________ |
300d5701 | 101 | Bool_t AliAODHandler::Init(Option_t* opt) |
ec4af4c1 | 102 | { |
6989bff3 | 103 | // Initialize IO |
104 | // | |
105 | // Create the AODevent object | |
106 | if(!fAODEvent){ | |
ec4af4c1 | 107 | fAODEvent = new AliAODEvent(); |
78f7f935 | 108 | if (fIsStandard) fAODEvent->CreateStdContent(); |
6989bff3 | 109 | } |
110 | // | |
111 | // File opening according to execution mode | |
7970f4ac | 112 | TString option(opt); |
113 | option.ToLower(); | |
114 | if (option.Contains("proof")) { | |
6989bff3 | 115 | // proof |
7970f4ac | 116 | if (option.Contains("special")) { |
117 | // File for tree already opened on slave -> merging via files | |
118 | fFileA = gFile; | |
119 | CreateTree(1); | |
120 | } else { | |
121 | // Merging in memory | |
122 | CreateTree(0); | |
123 | } | |
6989bff3 | 124 | } else { |
125 | // local and grid | |
26b9ac7a | 126 | TDirectory *owd = gDirectory; |
7970f4ac | 127 | fFileA = new TFile(fFileName.Data(), "RECREATE"); |
6989bff3 | 128 | CreateTree(1); |
26b9ac7a | 129 | owd->cd(); |
6989bff3 | 130 | } |
131 | return kTRUE; | |
ec4af4c1 | 132 | } |
133 | ||
da97a08a | 134 | |
135 | void AliAODHandler::StoreMCParticles(){ | |
136 | ||
137 | // | |
138 | // Remap the labels from ESD stack and store | |
139 | // the AODMCParticles, makes only sense if we have | |
140 | // the mcparticles branch | |
141 | // has to be done here since we cannot know in advance | |
142 | // which particles are needed (e.g. by the tracks etc.) | |
143 | // | |
144 | // Particles have been selected by AliMCEventhanlder->SelectParticle() | |
145 | // To use the MCEventhandler here we need to set it from the outside | |
146 | // can vanish when Handler go to the ANALYSISalice library | |
147 | ||
148 | TClonesArray *mcarray = (TClonesArray*)fAODEvent->FindListObject(AliAODMCParticle::StdBranchName()); | |
149 | if(!mcarray)return; | |
150 | mcarray->Delete(); | |
151 | ||
152 | // Get the MC Infos.. Handler needs to be set before | |
153 | // while adding the branch | |
154 | // This needs to be done, not to depend on the AnalysisManager | |
155 | ||
156 | if(!fMCEventH)return; | |
157 | if(!fMCEventH->MCEvent())return; | |
158 | AliStack *pStack = fMCEventH->MCEvent()->Stack(); | |
159 | if(!pStack)return; | |
160 | ||
161 | fMCEventH->CreateLabelMap(); | |
162 | ||
163 | // First store the AliAODParticlesMC | |
164 | ||
165 | Int_t np = pStack->GetNtrack(); | |
166 | Int_t nprim = pStack->GetNprimary(); | |
167 | ||
168 | ||
169 | Int_t j = 0; | |
170 | TClonesArray& l = *mcarray; | |
171 | ||
172 | for(int i = 0;i < np;++i){ | |
173 | if(fMCEventH->IsParticleSelected(i)){ | |
174 | ||
175 | Int_t flag = 0; | |
176 | TParticle *part = pStack->Particle(i); | |
177 | if(i<nprim)flag |= AliAODMCParticle::kPrimary; | |
178 | if(pStack->IsPhysicalPrimary(i))flag |= AliAODMCParticle::kPhysicalPrim; | |
179 | ||
180 | if(fMCEventH->GetNewLabel(i)!=j){ | |
181 | AliError(Form("MISMATCH New label %d j: %d",fMCEventH->GetNewLabel(i),j)); | |
182 | } | |
183 | AliAODMCParticle mcpart_tmp(part,i,flag); | |
184 | ||
185 | // | |
186 | Int_t d0 = mcpart_tmp.GetDaughter(0); | |
187 | Int_t d1 = mcpart_tmp.GetDaughter(1); | |
188 | Int_t m = mcpart_tmp.GetMother(); | |
189 | ||
190 | // other than for the track labels, negative values mean | |
191 | // no daughter/mother so preserve it | |
192 | ||
193 | if(d0<0 && d1<0){ | |
194 | // no first daughter -> no second daughter | |
195 | // nothing to be done | |
196 | // second condition not needed just for sanity check at the end | |
197 | mcpart_tmp.SetDaughter(0,d0); | |
198 | mcpart_tmp.SetDaughter(1,d1); | |
199 | } | |
200 | else if(d1 < 0 && d0 >= 0){ | |
201 | // Only one daughter | |
202 | // second condition not needed just for sanity check at the end | |
203 | if(fMCEventH->IsParticleSelected(d0)){ | |
204 | mcpart_tmp.SetDaughter(0,fMCEventH->GetNewLabel(d0)); | |
205 | } | |
206 | else{ | |
207 | mcpart_tmp.SetDaughter(0,-1); | |
208 | } | |
209 | mcpart_tmp.SetDaughter(1,d1); | |
210 | } | |
211 | else if (d0 > 0 && d1 > 0 ){ | |
212 | // we have two or more daughters loop on the stack to see if they are | |
213 | // selected | |
214 | Int_t d0_tmp = -1; | |
215 | Int_t d1_tmp = -1; | |
216 | for(int id = d0; id<=d1;++id){ | |
217 | if(fMCEventH->IsParticleSelected(id)){ | |
218 | if(d0_tmp==-1){ | |
219 | // first time | |
220 | d0_tmp = fMCEventH->GetNewLabel(id); | |
221 | d1_tmp = d0_tmp; // this is to have the same schema as on the stack i.e. with one daugther d0 and d1 are the same | |
222 | } | |
223 | else d1_tmp = fMCEventH->GetNewLabel(id); | |
224 | } | |
225 | } | |
226 | mcpart_tmp.SetDaughter(0,d0_tmp); | |
227 | mcpart_tmp.SetDaughter(1,d1_tmp); | |
228 | } | |
229 | else{ | |
230 | AliError(Form("Unxpected indices %d %d",d0,d1)); | |
231 | } | |
232 | ||
233 | if(m<0){ | |
234 | mcpart_tmp.SetMother(m); | |
235 | } | |
236 | else{ | |
237 | if(fMCEventH->IsParticleSelected(m))mcpart_tmp.SetMother(fMCEventH->GetNewLabel(m)); | |
238 | else AliError("PROBLEM Mother not selected"); | |
239 | } | |
240 | ||
241 | new (l[j++]) AliAODMCParticle(mcpart_tmp); | |
242 | ||
243 | } | |
244 | } | |
245 | AliInfo(Form("AliAODHandler::StoreMCParticles: Selected %d (Primaries %d / total %d) after validation", | |
246 | j,nprim,np)); | |
247 | ||
248 | // Set the labels in the AOD output... | |
249 | // Remapping | |
250 | ||
251 | // AODTracks | |
252 | TClonesArray* tracks = fAODEvent->GetTracks(); | |
253 | if(tracks){ | |
254 | for(int it = 0; it < fAODEvent->GetNTracks();++it){ | |
255 | AliAODTrack *track = fAODEvent->GetTrack(it); | |
256 | ||
257 | if(TMath::Abs(track->GetLabel())>np||track->GetLabel()==0){ | |
258 | AliWarning(Form("Wrong ESD track label %d",track->GetLabel())); | |
259 | } | |
260 | if(fMCEventH->GetNewLabel(track->GetLabel())==0){ | |
261 | AliWarning(Form("New label not found for %d",track->GetLabel())); | |
262 | } | |
263 | track->SetLabel(fMCEventH->GetNewLabel(track->GetLabel())); | |
264 | } | |
265 | } | |
266 | ||
267 | // AOD calo cluster | |
268 | TClonesArray *clusters = fAODEvent->GetCaloClusters(); | |
269 | if(clusters){ | |
270 | for (Int_t iClust = 0;iClust < fAODEvent->GetNCaloClusters(); ++iClust) { | |
271 | AliAODCaloCluster * cluster = fAODEvent->GetCaloCluster(iClust); | |
272 | UInt_t nLabel = cluster->GetNLabel(); | |
273 | // Ugly but do not want to fragment memory by creating | |
274 | // new Int_t (nLabel) | |
275 | Int_t* labels = const_cast<Int_t*>(cluster->GetLabels()); | |
276 | if (labels){ | |
277 | for(UInt_t i = 0;i < nLabel;++i){ | |
278 | labels[i] = fMCEventH->GetNewLabel(cluster->GetLabel(i)); | |
279 | } | |
280 | } | |
281 | // cluster->SetLabels(labels,nLabel); | |
282 | }// iClust | |
283 | }// clusters | |
284 | ||
285 | // AOD tracklets | |
286 | AliAODTracklets *tracklets = fAODEvent->GetTracklets(); | |
287 | if(tracklets){ | |
288 | for(int it = 0;it < tracklets->GetNumberOfTracklets();++it){ | |
289 | int label0 = tracklets->GetLabel(it,0); | |
290 | int label1 = tracklets->GetLabel(it,1); | |
291 | if(label0>=0)label0 = fMCEventH->GetNewLabel(label0); | |
292 | if(label1>=0)label1 = fMCEventH->GetNewLabel(label1); | |
293 | tracklets->SetLabel(it,0,label0); | |
294 | tracklets->SetLabel(it,1,label1); | |
295 | } | |
296 | } | |
297 | ||
298 | } | |
299 | ||
5f380da9 | 300 | Bool_t AliAODHandler::FinishEvent() |
ec4af4c1 | 301 | { |
da97a08a | 302 | // Fill data structures |
303 | if(fFillAOD){ | |
f4e5f8d5 | 304 | fAODEvent->MakeEntriesReferencable(); |
da97a08a | 305 | StoreMCParticles(); |
ec4af4c1 | 306 | FillTree(); |
da97a08a | 307 | } |
308 | ||
309 | if (fIsStandard) fAODEvent->ResetStd(); | |
310 | // Reset AOD replication flag | |
311 | fAODIsReplicated = kFALSE; | |
312 | return kTRUE; | |
ec4af4c1 | 313 | } |
314 | ||
7970f4ac | 315 | //______________________________________________________________________________ |
ec4af4c1 | 316 | Bool_t AliAODHandler::Terminate() |
317 | { | |
318 | // Terminate | |
319 | AddAODtoTreeUserInfo(); | |
320 | return kTRUE; | |
321 | } | |
322 | ||
7970f4ac | 323 | //______________________________________________________________________________ |
ec4af4c1 | 324 | Bool_t AliAODHandler::TerminateIO() |
325 | { | |
326 | // Terminate IO | |
21501411 | 327 | if (fFileA) { |
328 | fFileA->Close(); | |
329 | delete fFileA; | |
330 | } | |
ec4af4c1 | 331 | return kTRUE; |
332 | } | |
333 | ||
7970f4ac | 334 | //______________________________________________________________________________ |
954526ed | 335 | void AliAODHandler::CreateTree(Int_t flag) |
ec4af4c1 | 336 | { |
337 | // Creates the AOD Tree | |
f3214a54 | 338 | fTreeA = new TTree("aodTree", "AliAOD tree"); |
ec4af4c1 | 339 | fTreeA->Branch(fAODEvent->GetList()); |
954526ed | 340 | if (flag == 0) fTreeA->SetDirectory(0); |
ec4af4c1 | 341 | } |
342 | ||
7970f4ac | 343 | //______________________________________________________________________________ |
ec4af4c1 | 344 | void AliAODHandler::FillTree() |
345 | { | |
346 | // Fill the AOD Tree | |
da97a08a | 347 | fTreeA->Fill(); |
ec4af4c1 | 348 | } |
349 | ||
7970f4ac | 350 | //______________________________________________________________________________ |
ec4af4c1 | 351 | void AliAODHandler::AddAODtoTreeUserInfo() |
352 | { | |
353 | // Add aod event to tree user info | |
da97a08a | 354 | fTreeA->GetUserInfo()->Add(fAODEvent); |
ec4af4c1 | 355 | } |
490e9023 | 356 | |
7970f4ac | 357 | //______________________________________________________________________________ |
0134949d | 358 | void AliAODHandler::AddBranch(const char* cname, void* addobj) |
490e9023 | 359 | { |
360 | // Add a new branch to the aod | |
361 | TDirectory *owd = gDirectory; | |
362 | if (fFileA) { | |
363 | fFileA->cd(); | |
364 | } | |
0134949d | 365 | char** apointer = (char**) addobj; |
366 | TObject* obj = (TObject*) *apointer; | |
367 | fTreeA->Branch(obj->GetName(), cname, addobj); | |
368 | fAODEvent->AddObject(obj); | |
490e9023 | 369 | owd->cd(); |
370 | } | |
7970f4ac | 371 | |
372 | //______________________________________________________________________________ | |
373 | void AliAODHandler::SetOutputFileName(const char* fname) | |
374 | { | |
375 | // Set file name. | |
376 | fFileName = fname; | |
377 | } | |
378 | ||
379 | //______________________________________________________________________________ | |
380 | const char *AliAODHandler::GetOutputFileName() | |
381 | { | |
382 | // Get file name. | |
383 | return fFileName.Data(); | |
384 | } |