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" |
34 | |
35 | /** ROOT macro for the implementation of ROOT specific class methods */ |
36 | ClassImp(AliHLTEsdManager) |
37 | |
38 | AliHLTEsdManager::AliHLTEsdManager() |
39 | : |
40 | fESDs() |
41 | { |
42 | // see header file for class documentation |
43 | // or |
44 | // refer to README to build package |
45 | // or |
46 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt |
47 | } |
48 | |
49 | AliHLTEsdManager::~AliHLTEsdManager() |
50 | { |
51 | // see header file for class documentation |
52 | } |
53 | |
54 | AliHLTEsdManager::AliHLTEsdListEntry* AliHLTEsdManager::Find(AliHLTComponentDataType dt) const |
55 | { |
56 | // see header file for class documentation |
57 | AliHLTEsdListEntry* pEntry=NULL; |
58 | for (unsigned int i=0; i<fESDs.size(); i++) { |
59 | if (fESDs[i]==dt) { |
60 | pEntry=const_cast<AliHLTEsdListEntry*>(&fESDs[i]); |
61 | } |
62 | } |
63 | return pEntry; |
64 | } |
65 | |
66 | int AliHLTEsdManager::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size, |
67 | AliHLTComponentDataType dt, AliESDEvent* tgtesd, int eventno) |
68 | { |
69 | // see header file for class documentation |
70 | if (!pBuffer && size<=0) return -EINVAL; |
71 | int iResult=0; |
72 | AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer); |
73 | if (firstWord==size-sizeof(AliHLTUInt32_t)) { |
74 | HLTDebug("create object from block %s size %d", AliHLTComponent::DataType2Text(dt).c_str(), size); |
75 | AliHLTMessage msg(const_cast<AliHLTUInt8_t*>(pBuffer), size); |
76 | TClass* objclass=msg.GetClass(); |
77 | TObject* pObj=msg.ReadObject(objclass); |
78 | if (pObj && objclass) { |
79 | HLTDebug("object %p type %s created", pObj, objclass->GetName()); |
80 | AliESDEvent* pESD=dynamic_cast<AliESDEvent*>(pObj); |
81 | TTree* pTree=NULL; |
82 | if (!pESD) { |
83 | pTree=dynamic_cast<TTree*>(pObj); |
84 | if (pTree) { |
85 | pESD=new AliESDEvent; |
86 | pESD->CreateStdContent(); |
87 | if (pTree->GetEntries()>0) { |
88 | if (pTree->GetEntries()>1) { |
89 | HLTWarning("only one entry allowed for ESD embedded into tree, data block %s contains tree with %d entires, taking first entry", |
90 | AliHLTComponent::DataType2Text(dt).c_str(), pTree->GetEntries()); |
91 | } |
92 | pESD->ReadFromTree(pTree); |
93 | pTree->GetEvent(0); |
94 | } |
95 | } else { |
96 | HLTWarning("tree of data block %s has no events, skipping data block", AliHLTComponent::DataType2Text(dt).c_str()); |
97 | } |
98 | } |
99 | if (pESD) { |
100 | AliHLTEsdListEntry* entry=Find(dt); |
101 | if (!entry) { |
102 | AliHLTEsdListEntry newEntry(dt); |
103 | fESDs.push_back(newEntry); |
104 | } |
105 | if (tgtesd) { |
106 | } |
107 | entry=Find(dt); |
108 | if (entry) { |
109 | entry->WriteESD(pESD, eventno); |
110 | } else { |
111 | HLTError("internal mismatch, can not create list entry"); |
112 | iResult=-ENOMEM; |
113 | } |
114 | } else { |
115 | HLTWarning("data block %s is not of class type AliESDEvent, ignoring ...", AliHLTComponent::DataType2Text(dt).c_str()); |
116 | } |
117 | if (pTree) { |
118 | // ESD has been created and must be cleaned up |
119 | delete pESD; |
120 | pESD=NULL; |
121 | } |
122 | delete pObj; |
123 | pObj=NULL; |
124 | } else { |
125 | } |
126 | } |
127 | return iResult; |
128 | } |
129 | |
130 | AliHLTEsdManager::AliHLTEsdListEntry::AliHLTEsdListEntry(AliHLTComponentDataType dt) |
131 | : |
132 | fName(), |
133 | fpFile(NULL), |
134 | fpTree(NULL), |
135 | fpEsd(NULL), |
136 | fDt(dt) |
137 | { |
138 | // see header file for class documentation |
139 | } |
140 | |
141 | AliHLTEsdManager::AliHLTEsdListEntry::AliHLTEsdListEntry(const AliHLTEsdListEntry& src) |
142 | : |
143 | AliHLTLogging(), |
144 | fName(src.fName), |
145 | fpFile(src.fpFile), |
146 | fpTree(src.fpTree), |
147 | fpEsd(src.fpEsd), |
148 | fDt(src.fDt) |
149 | { |
150 | // copy constructor copies everything including pointers |
151 | } |
152 | |
153 | AliHLTEsdManager::AliHLTEsdListEntry& AliHLTEsdManager::AliHLTEsdListEntry::operator=(const AliHLTEsdListEntry& src) |
154 | { |
155 | // assignment operator copies everything including pointers |
156 | fName=src.fName; |
157 | fpFile=src.fpFile; |
158 | fpTree=src.fpTree; |
159 | fpEsd=src.fpEsd; |
160 | fDt=src.fDt; |
161 | return *this; |
162 | } |
163 | |
164 | AliHLTEsdManager::AliHLTEsdListEntry::~AliHLTEsdListEntry() |
165 | { |
166 | // see header file for class documentation |
167 | if (fpTree) { |
168 | delete fpTree; |
169 | fpTree=NULL; |
170 | } |
171 | |
172 | if (fpEsd) { |
173 | delete fpEsd; |
174 | fpEsd=NULL; |
175 | } |
176 | |
177 | if (fpFile) { |
178 | fpFile->Close(); |
179 | delete fpFile; |
180 | fpFile=NULL; |
181 | } |
182 | } |
183 | |
184 | bool AliHLTEsdManager::AliHLTEsdListEntry::operator==(AliHLTComponentDataType dt) const |
185 | { |
186 | // see header file for class documentation |
187 | return fDt==dt; |
188 | } |
189 | |
190 | int AliHLTEsdManager::AliHLTEsdListEntry::WriteESD(AliESDEvent* pESD, int eventno) |
191 | { |
192 | // see header file for class documentation |
193 | if (!pESD) return -EINVAL; |
194 | int iResult=0; |
195 | if (!fpFile) { |
196 | TString origin; |
197 | origin.Insert(0, fDt.fOrigin, kAliHLTComponentDataTypefOriginSize); |
198 | origin.Remove(TString::kTrailing, ' '); |
199 | origin.ToUpper(); |
200 | fName="AliHLT"; fName+=origin; |
201 | if (fDt!=kAliHLTDataTypeESDObject && |
202 | fDt!=kAliHLTDataTypeESDTree) { |
203 | |
204 | HLTWarning("non-standard ESD type %s", AliHLTComponent::DataType2Text(fDt).c_str()); |
205 | TString id; |
206 | id.Insert(0, fDt.fID, kAliHLTComponentDataTypefIDsize); |
207 | id.Remove(TString::kTrailing, ' '); |
208 | id.ToUpper(); |
209 | fName+="_"; fName+=id; fName+=".root"; |
210 | } else { |
211 | fName+="ESDs.root"; |
212 | fpFile=new TFile(fName, "RECREATE"); |
213 | } |
214 | } |
215 | if (fpFile && !fpFile->IsZombie() && iResult>=0) { |
216 | if (!fpTree) { |
217 | fpTree=new TTree("esdTree", "Tree with HLT ESD objects"); |
218 | if (!fpTree) { |
219 | iResult=-ENOMEM; |
220 | } |
221 | } |
222 | if (fpTree && iResult>=0) { |
223 | if (!fpEsd) { |
224 | // create the ESD structure for filling into the tree |
225 | fpEsd=new AliESDEvent; |
226 | if (fpEsd) { |
227 | fpEsd->CreateStdContent(); |
228 | fpEsd->WriteToTree(fpTree); |
229 | } else { |
230 | iResult=-ENOMEM; |
231 | } |
232 | } else { |
233 | fpEsd->ResetStdContent(); |
234 | } |
235 | if (eventno>=0) { |
236 | // synchronize and add empty events |
237 | for (int i=fpTree->GetEntries(); i<eventno; i++) { |
238 | fpTree->Fill(); |
239 | } |
240 | if (fpTree->GetEntries()>eventno) { |
241 | HLTWarning("event %d ESD of type %s already written, skipping additional data block", eventno, AliHLTComponent::DataType2Text(fDt).c_str()); |
242 | } |
243 | } |
244 | if (fpEsd) { |
245 | // we need to copy the ESD, I did not find an approptiate |
246 | // method, the workaround is to save the ESD in a temporary |
247 | // tree, read the content back into the ESD structure |
248 | // used for filling |
249 | TTree* dummy=new TTree("dummy","dummy"); |
250 | if (dummy) { |
251 | pESD->WriteToTree(dummy); |
252 | dummy->Fill(); |
253 | fpEsd->ReadFromTree(dummy); |
254 | dummy->GetEvent(0); |
255 | fpTree->Fill(); |
256 | delete dummy; |
257 | } else { |
258 | iResult=-ENOMEM; |
259 | } |
260 | } else { |
261 | iResult=-ENOMEM; |
262 | } |
263 | if (iResult>=0) { |
264 | fpTree->Write("",TObject::kOverwrite); |
265 | } |
266 | } |
267 | } |
268 | return iResult; |
269 | } |