c5123824 |
1 | // $Id$ |
2 | |
3 | //************************************************************************** |
4 | //* This file is property of and copyright by the ALICE HLT Project * |
5 | //* ALICE Experiment at CERN, All rights reserved. * |
6 | //* * |
7 | //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> * |
8 | //* for The ALICE HLT Project. * |
9 | //* * |
10 | //* Permission to use, copy, modify and distribute this software and its * |
11 | //* documentation strictly for non-commercial purposes is hereby granted * |
12 | //* without fee, provided that the above copyright notice appears in all * |
13 | //* copies and that both the copyright notice and this permission notice * |
14 | //* appear in the supporting documentation. The authors make no claims * |
15 | //* about the suitability of this software for any purpose. It is * |
16 | //* provided "as is" without express or implied warranty. * |
17 | //************************************************************************** |
18 | |
19 | /** @file AliHLTEsdManager.cxx |
20 | @author Matthias Richter |
21 | @date |
22 | @brief Manager for merging and writing of HLT ESDs |
23 | */ |
24 | |
25 | #include "AliHLTEsdManager.h" |
26 | #include "AliHLTComponent.h" |
27 | #include "AliESDEvent.h" |
28 | #include "AliHLTMessage.h" |
29 | #include "AliESDEvent.h" |
30 | #include "TFile.h" |
31 | #include "TTree.h" |
32 | #include "TClass.h" |
33 | #include "TObject.h" |
62ff1e23 |
34 | #include "TObjectTable.h" |
c5123824 |
35 | |
36 | /** ROOT macro for the implementation of ROOT specific class methods */ |
37 | ClassImp(AliHLTEsdManager) |
38 | |
39 | AliHLTEsdManager::AliHLTEsdManager() |
40 | : |
41 | fESDs() |
42 | { |
43 | // see header file for class documentation |
44 | // or |
45 | // refer to README to build package |
46 | // or |
47 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt |
48 | } |
49 | |
50 | AliHLTEsdManager::~AliHLTEsdManager() |
51 | { |
52 | // see header file for class documentation |
62ff1e23 |
53 | for (unsigned int i=0; i<fESDs.size(); i++) { |
54 | if (fESDs[i]) { |
55 | delete fESDs[i]; |
56 | } |
57 | fESDs[i]=NULL; |
58 | } |
c5123824 |
59 | } |
60 | |
61 | AliHLTEsdManager::AliHLTEsdListEntry* AliHLTEsdManager::Find(AliHLTComponentDataType dt) const |
62 | { |
63 | // see header file for class documentation |
64 | AliHLTEsdListEntry* pEntry=NULL; |
65 | for (unsigned int i=0; i<fESDs.size(); i++) { |
62ff1e23 |
66 | if (fESDs[i] && *(fESDs[i])==dt) { |
67 | pEntry=const_cast<AliHLTEsdListEntry*>(fESDs[i]); |
c5123824 |
68 | } |
69 | } |
70 | return pEntry; |
71 | } |
72 | |
73 | int AliHLTEsdManager::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size, |
74 | AliHLTComponentDataType dt, AliESDEvent* tgtesd, int eventno) |
75 | { |
76 | // see header file for class documentation |
77 | if (!pBuffer && size<=0) return -EINVAL; |
78 | int iResult=0; |
79 | AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer); |
80 | if (firstWord==size-sizeof(AliHLTUInt32_t)) { |
81 | HLTDebug("create object from block %s size %d", AliHLTComponent::DataType2Text(dt).c_str(), size); |
82 | AliHLTMessage msg(const_cast<AliHLTUInt8_t*>(pBuffer), size); |
83 | TClass* objclass=msg.GetClass(); |
84 | TObject* pObj=msg.ReadObject(objclass); |
85 | if (pObj && objclass) { |
86 | HLTDebug("object %p type %s created", pObj, objclass->GetName()); |
87 | AliESDEvent* pESD=dynamic_cast<AliESDEvent*>(pObj); |
88 | TTree* pTree=NULL; |
89 | if (!pESD) { |
90 | pTree=dynamic_cast<TTree*>(pObj); |
91 | if (pTree) { |
92 | pESD=new AliESDEvent; |
93 | pESD->CreateStdContent(); |
94 | if (pTree->GetEntries()>0) { |
95 | if (pTree->GetEntries()>1) { |
96 | HLTWarning("only one entry allowed for ESD embedded into tree, data block %s contains tree with %d entires, taking first entry", |
97 | AliHLTComponent::DataType2Text(dt).c_str(), pTree->GetEntries()); |
98 | } |
99 | pESD->ReadFromTree(pTree); |
100 | pTree->GetEvent(0); |
101 | } |
102 | } else { |
103 | HLTWarning("tree of data block %s has no events, skipping data block", AliHLTComponent::DataType2Text(dt).c_str()); |
104 | } |
105 | } |
106 | if (pESD) { |
107 | AliHLTEsdListEntry* entry=Find(dt); |
108 | if (!entry) { |
62ff1e23 |
109 | AliHLTEsdListEntry* newEntry=new AliHLTEsdListEntry(dt); |
c5123824 |
110 | fESDs.push_back(newEntry); |
111 | } |
112 | if (tgtesd) { |
113 | } |
114 | entry=Find(dt); |
115 | if (entry) { |
116 | entry->WriteESD(pESD, eventno); |
117 | } else { |
118 | HLTError("internal mismatch, can not create list entry"); |
119 | iResult=-ENOMEM; |
120 | } |
121 | } else { |
122 | HLTWarning("data block %s is not of class type AliESDEvent, ignoring ...", AliHLTComponent::DataType2Text(dt).c_str()); |
123 | } |
124 | if (pTree) { |
125 | // ESD has been created and must be cleaned up |
126 | delete pESD; |
127 | pESD=NULL; |
128 | } |
129 | delete pObj; |
130 | pObj=NULL; |
131 | } else { |
132 | } |
133 | } |
134 | return iResult; |
135 | } |
136 | |
137 | AliHLTEsdManager::AliHLTEsdListEntry::AliHLTEsdListEntry(AliHLTComponentDataType dt) |
138 | : |
139 | fName(), |
140 | fpFile(NULL), |
141 | fpTree(NULL), |
142 | fpEsd(NULL), |
143 | fDt(dt) |
144 | { |
145 | // see header file for class documentation |
146 | } |
147 | |
c5123824 |
148 | AliHLTEsdManager::AliHLTEsdListEntry::~AliHLTEsdListEntry() |
149 | { |
150 | // see header file for class documentation |
151 | if (fpTree) { |
62ff1e23 |
152 | fpTree->GetUserInfo()->Clear(); |
c5123824 |
153 | delete fpTree; |
154 | fpTree=NULL; |
155 | } |
156 | |
62ff1e23 |
157 | // due to the Root garbage collection the ESD object might already be |
158 | // deleted since the pTree->GetUserInfo()->Add(pESD) adds the ESD object to |
159 | // an internal list which is cleaned when the tree is deleted |
160 | if (fpEsd && gObjectTable->PtrIsValid(fpEsd)) { |
c5123824 |
161 | delete fpEsd; |
c5123824 |
162 | } |
62ff1e23 |
163 | fpEsd=NULL; |
c5123824 |
164 | |
165 | if (fpFile) { |
166 | fpFile->Close(); |
167 | delete fpFile; |
168 | fpFile=NULL; |
169 | } |
170 | } |
171 | |
172 | bool AliHLTEsdManager::AliHLTEsdListEntry::operator==(AliHLTComponentDataType dt) const |
173 | { |
174 | // see header file for class documentation |
175 | return fDt==dt; |
176 | } |
177 | |
178 | int AliHLTEsdManager::AliHLTEsdListEntry::WriteESD(AliESDEvent* pESD, int eventno) |
179 | { |
180 | // see header file for class documentation |
181 | if (!pESD) return -EINVAL; |
182 | int iResult=0; |
183 | if (!fpFile) { |
184 | TString origin; |
185 | origin.Insert(0, fDt.fOrigin, kAliHLTComponentDataTypefOriginSize); |
186 | origin.Remove(TString::kTrailing, ' '); |
187 | origin.ToUpper(); |
188 | fName="AliHLT"; fName+=origin; |
189 | if (fDt!=kAliHLTDataTypeESDObject && |
190 | fDt!=kAliHLTDataTypeESDTree) { |
191 | |
192 | HLTWarning("non-standard ESD type %s", AliHLTComponent::DataType2Text(fDt).c_str()); |
193 | TString id; |
194 | id.Insert(0, fDt.fID, kAliHLTComponentDataTypefIDsize); |
195 | id.Remove(TString::kTrailing, ' '); |
196 | id.ToUpper(); |
197 | fName+="_"; fName+=id; fName+=".root"; |
198 | } else { |
199 | fName+="ESDs.root"; |
200 | fpFile=new TFile(fName, "RECREATE"); |
201 | } |
202 | } |
203 | if (fpFile && !fpFile->IsZombie() && iResult>=0) { |
204 | if (!fpTree) { |
205 | fpTree=new TTree("esdTree", "Tree with HLT ESD objects"); |
206 | if (!fpTree) { |
207 | iResult=-ENOMEM; |
62ff1e23 |
208 | } else { |
209 | fpTree->SetDirectory(0); |
c5123824 |
210 | } |
211 | } |
212 | if (fpTree && iResult>=0) { |
213 | if (!fpEsd) { |
214 | // create the ESD structure for filling into the tree |
215 | fpEsd=new AliESDEvent; |
216 | if (fpEsd) { |
217 | fpEsd->CreateStdContent(); |
62ff1e23 |
218 | fpTree->GetUserInfo()->Add(fpEsd); |
c5123824 |
219 | } else { |
220 | iResult=-ENOMEM; |
221 | } |
222 | } else { |
223 | fpEsd->ResetStdContent(); |
224 | } |
225 | if (eventno>=0) { |
226 | // synchronize and add empty events |
227 | for (int i=fpTree->GetEntries(); i<eventno; i++) { |
228 | fpTree->Fill(); |
229 | } |
230 | if (fpTree->GetEntries()>eventno) { |
231 | HLTWarning("event %d ESD of type %s already written, skipping additional data block", eventno, AliHLTComponent::DataType2Text(fDt).c_str()); |
232 | } |
233 | } |
234 | if (fpEsd) { |
235 | // we need to copy the ESD, I did not find an approptiate |
236 | // method, the workaround is to save the ESD in a temporary |
237 | // tree, read the content back into the ESD structure |
238 | // used for filling |
239 | TTree* dummy=new TTree("dummy","dummy"); |
240 | if (dummy) { |
62ff1e23 |
241 | /* |
242 | dummy->SetDirectory(0); |
c5123824 |
243 | pESD->WriteToTree(dummy); |
244 | dummy->Fill(); |
62ff1e23 |
245 | dummy->GetUserInfo()->Add(pESD); |
c5123824 |
246 | fpEsd->ReadFromTree(dummy); |
247 | dummy->GetEvent(0); |
62ff1e23 |
248 | */ |
249 | fpEsd->WriteToTree(fpTree); |
c5123824 |
250 | fpTree->Fill(); |
62ff1e23 |
251 | dummy->GetUserInfo()->Clear(); |
c5123824 |
252 | delete dummy; |
253 | } else { |
254 | iResult=-ENOMEM; |
255 | } |
256 | } else { |
257 | iResult=-ENOMEM; |
258 | } |
259 | if (iResult>=0) { |
260 | fpTree->Write("",TObject::kOverwrite); |
261 | } |
262 | } |
263 | } |
264 | return iResult; |
265 | } |