]>
Commit | Line | Data |
---|---|---|
4ddfc222 | 1 | // $Id$ |
2 | ||
3 | /************************************************************************** | |
9be2600f | 4 | * This file is property of and copyright by the ALICE HLT Project * |
5 | * ALICE Experiment at CERN, All rights reserved. * | |
4ddfc222 | 6 | * * |
9be2600f | 7 | * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> * |
8 | * for The ALICE HLT Project. * | |
4ddfc222 | 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 AliHLTFilePublisher.cxx | |
20 | @author Matthias Richter | |
21 | @date | |
22 | @brief HLT file publisher component implementation. */ | |
23 | ||
24 | #if __GNUC__>= 3 | |
25 | using namespace std; | |
26 | #endif | |
27 | ||
28 | #include "AliHLTFilePublisher.h" | |
0449b3c8 | 29 | #include "AliLog.h" |
4ddfc222 | 30 | #include <TObjString.h> |
31 | #include <TMath.h> | |
32 | #include <TFile.h> | |
33 | ||
4ddfc222 | 34 | |
35 | /** ROOT macro for the implementation of ROOT specific class methods */ | |
36 | ClassImp(AliHLTFilePublisher) | |
37 | ||
38 | AliHLTFilePublisher::AliHLTFilePublisher() | |
39 | : | |
40 | AliHLTDataSource(), | |
4ddfc222 | 41 | fpCurrent(NULL), |
d397a3b2 | 42 | fEvents(), |
0449b3c8 | 43 | fMaxSize(0), |
44 | fOpenFilesAtStart(false) | |
4ddfc222 | 45 | { |
46 | // see header file for class documentation | |
47 | // or | |
48 | // refer to README to build package | |
49 | // or | |
50 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
51 | ||
52 | // make the lists owners of their objects in order to automatically | |
53 | // de-allocate the objects | |
d397a3b2 | 54 | fEvents.SetOwner(); |
4ddfc222 | 55 | } |
56 | ||
57 | AliHLTFilePublisher::~AliHLTFilePublisher() | |
58 | { | |
59 | // see header file for class documentation | |
60 | ||
61 | // file list and file name list are owner of their objects and | |
62 | // delete all the objects | |
63 | } | |
64 | ||
65 | const char* AliHLTFilePublisher::GetComponentID() | |
66 | { | |
67 | // see header file for class documentation | |
68 | return "FilePublisher"; | |
69 | } | |
70 | ||
71 | AliHLTComponentDataType AliHLTFilePublisher::GetOutputDataType() | |
72 | { | |
73 | // see header file for class documentation | |
d397a3b2 | 74 | return kAliHLTVoidDataType; |
4ddfc222 | 75 | } |
76 | ||
77 | void AliHLTFilePublisher::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) | |
78 | { | |
79 | // see header file for class documentation | |
80 | constBase=fMaxSize; | |
81 | inputMultiplier=1.0; | |
82 | } | |
83 | ||
84 | AliHLTComponent* AliHLTFilePublisher::Spawn() | |
85 | { | |
86 | // see header file for class documentation | |
87 | return new AliHLTFilePublisher; | |
88 | } | |
89 | ||
90 | int AliHLTFilePublisher::DoInit( int argc, const char** argv ) | |
91 | { | |
92 | // see header file for class documentation | |
93 | ||
94 | //HLTDebug("%d %s", argc, argv[0]); | |
95 | int iResult=0; | |
96 | TString argument=""; | |
97 | int bMissingParam=0; | |
fe050813 | 98 | int bHaveDatatype=0; |
99 | int bHaveSpecification=0; | |
0449b3c8 | 100 | fOpenFilesAtStart = false; |
d397a3b2 | 101 | AliHLTComponentDataType currDataType=kAliHLTVoidDataType; |
102 | AliHLTUInt32_t currSpecification=kAliHLTVoidDataSpec; | |
103 | EventFiles* pCurrEvent=NULL; | |
4ddfc222 | 104 | for (int i=0; i<argc && iResult>=0; i++) { |
105 | argument=argv[i]; | |
106 | if (argument.IsNull()) continue; | |
107 | ||
108 | // -datafile | |
109 | if (argument.CompareTo("-datafile")==0) { | |
110 | if ((bMissingParam=(++i>=argc))) break; | |
fe050813 | 111 | if (!bHaveDatatype) { |
112 | HLTWarning("no data type available so far, please set data type and specification before the file name. The first available data type will be set for all files preceding it"); | |
113 | } | |
d397a3b2 | 114 | FileDesc* pDesc=new FileDesc(argv[i], currDataType, currSpecification); |
115 | if (pDesc) { | |
116 | iResult=InsertFile(pCurrEvent, pDesc); | |
4ddfc222 | 117 | } else { |
118 | iResult=-ENOMEM; | |
119 | } | |
120 | ||
121 | // -datafilelist | |
122 | } else if (argument.CompareTo("-datafilelist")==0) { | |
123 | if ((bMissingParam=(++i>=argc))) break; | |
124 | HLTWarning("-datafilelist option not yet implemented"); | |
125 | ||
126 | // -datatype | |
127 | } else if (argument.CompareTo("-datatype")==0) { | |
128 | if ((bMissingParam=(++i>=argc))) break; | |
d397a3b2 | 129 | memcpy(&currDataType.fID, argv[i], TMath::Min(kAliHLTComponentDataTypefIDsize, (Int_t)strlen(argv[i]))); |
4ddfc222 | 130 | if ((bMissingParam=(++i>=argc))) break; |
d397a3b2 | 131 | memcpy(&currDataType.fOrigin, argv[i], TMath::Min(kAliHLTComponentDataTypefOriginSize, (Int_t)strlen(argv[i]))); |
fe050813 | 132 | if (bHaveDatatype==0 && pCurrEvent && iResult>=0) { |
133 | // this is a workaround to make old tutorials working which contain | |
134 | // the arguments in the wrong sequence | |
135 | TList& files=*pCurrEvent; // type conversion operator defined | |
136 | TObjLink *flnk=files.FirstLink(); | |
fe050813 | 137 | while (flnk) { |
138 | FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject()); | |
139 | if (pFileDesc) { | |
140 | pFileDesc->SetDataType(currDataType); | |
141 | } | |
142 | flnk=flnk->Next(); | |
143 | } | |
144 | } | |
145 | bHaveDatatype=1; | |
4ddfc222 | 146 | |
147 | // -dataspec | |
148 | } else if (argument.CompareTo("-dataspec")==0) { | |
149 | if ((bMissingParam=(++i>=argc))) break; | |
150 | TString parameter(argv[i]); | |
151 | parameter.Remove(TString::kLeading, ' '); // remove all blanks | |
152 | if (parameter.IsDigit()) { | |
d397a3b2 | 153 | currSpecification=(AliHLTUInt32_t)parameter.Atoi(); |
4ddfc222 | 154 | } else if (parameter.BeginsWith("0x") && |
155 | parameter.Replace(0,2,"",0).IsHex()) { | |
d397a3b2 | 156 | sscanf(parameter.Data(),"%x", &currSpecification); |
4ddfc222 | 157 | } else { |
158 | HLTError("wrong parameter for argument %s, number expected", argument.Data()); | |
159 | iResult=-EINVAL; | |
160 | } | |
fe050813 | 161 | if (bHaveSpecification==0 && pCurrEvent && iResult>=0) { |
162 | // this is a workaround to make old tutorials working which contain | |
163 | // the arguments in the wrong sequence | |
164 | TList& files=*pCurrEvent; // type conversion operator defined | |
165 | TObjLink *flnk=files.FirstLink(); | |
fe050813 | 166 | while (flnk) { |
167 | FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject()); | |
168 | if (pFileDesc) { | |
169 | pFileDesc->SetSpecification(currSpecification); | |
170 | } | |
171 | flnk=flnk->Next(); | |
172 | } | |
173 | } | |
174 | bHaveSpecification=1; | |
d397a3b2 | 175 | // -nextevent |
176 | } else if (argument.CompareTo("-nextevent")==0) { | |
177 | InsertEvent(pCurrEvent); | |
0449b3c8 | 178 | } else if (argument.CompareTo("-open_files_at_start")==0) { |
179 | fOpenFilesAtStart = true; | |
4ddfc222 | 180 | } else { |
181 | if ((iResult=ScanArgument(argc-i, &argv[i]))==-EINVAL) { | |
182 | HLTError("unknown argument %s", argument.Data()); | |
183 | break; | |
184 | } else if (iResult==-EPROTO) { | |
185 | bMissingParam=1; | |
186 | break; | |
187 | } else if (iResult>=0) { | |
188 | i+=iResult; | |
189 | iResult=0; | |
190 | } | |
191 | } | |
192 | } | |
d397a3b2 | 193 | InsertEvent(pCurrEvent); |
194 | ||
4ddfc222 | 195 | if (bMissingParam) { |
196 | HLTError("missing parameter for argument %s", argument.Data()); | |
197 | iResult=-EINVAL; | |
198 | } | |
d397a3b2 | 199 | if (fEvents.GetSize()==0) { |
4ddfc222 | 200 | HLTError("the publisher needs at least one file argument"); |
201 | iResult=-EINVAL; | |
202 | } | |
0449b3c8 | 203 | if (iResult>=0) iResult=OpenFiles(fOpenFilesAtStart); |
4ddfc222 | 204 | if (iResult<0) { |
d397a3b2 | 205 | fEvents.Clear(); |
206 | } | |
207 | return iResult; | |
208 | } | |
209 | ||
210 | int AliHLTFilePublisher::InsertFile(EventFiles* &pCurrEvent, FileDesc* pDesc) | |
211 | { | |
f3506ea2 | 212 | // see header file for class documentation |
d397a3b2 | 213 | int iResult=0; |
214 | if (pDesc) { | |
215 | if (pCurrEvent==NULL) { | |
216 | pCurrEvent=new EventFiles; | |
217 | if (pCurrEvent!=NULL) { | |
218 | } else { | |
219 | iResult=-ENOMEM; | |
220 | } | |
221 | } | |
222 | if (iResult>=0 && pCurrEvent!=NULL) { | |
223 | HLTDebug("Insert file %p to event %p", pDesc, pCurrEvent); | |
224 | pCurrEvent->Add(pDesc); | |
225 | } | |
226 | } else { | |
227 | iResult=-EINVAL; | |
228 | } | |
229 | return iResult; | |
230 | } | |
231 | ||
232 | int AliHLTFilePublisher::InsertEvent(EventFiles* &pEvent) | |
233 | { | |
f3506ea2 | 234 | // see header file for class documentation |
d397a3b2 | 235 | int iResult=0; |
236 | if (pEvent) { | |
237 | HLTDebug("Inserted event %p", pEvent); | |
238 | fEvents.Add(pEvent); | |
239 | pEvent=NULL; | |
4ddfc222 | 240 | } |
241 | return iResult; | |
242 | } | |
243 | ||
244 | int AliHLTFilePublisher::ScanArgument(int argc, const char** argv) | |
245 | { | |
246 | // see header file for class documentation | |
247 | ||
248 | // there are no other arguments than the standard ones | |
249 | if (argc==0 && argv==NULL) { | |
250 | // this is just to get rid of the warning "unused parameter" | |
251 | } | |
0449b3c8 | 252 | return -EINVAL; |
4ddfc222 | 253 | } |
254 | ||
0449b3c8 | 255 | int AliHLTFilePublisher::OpenFiles(bool keepOpen) |
4ddfc222 | 256 | { |
257 | // see header file for class documentation | |
258 | int iResult=0; | |
d397a3b2 | 259 | TObjLink *lnk=fEvents.FirstLink(); |
4ddfc222 | 260 | while (lnk && iResult>=0) { |
d397a3b2 | 261 | EventFiles* pEventDesc=dynamic_cast<EventFiles*>(lnk->GetObject()); |
262 | if (pEventDesc) { | |
263 | HLTDebug("open files for event %p", pEventDesc); | |
264 | TList& files=*pEventDesc; // type conversion operator defined | |
265 | TObjLink *flnk=files.FirstLink(); | |
266 | int eventSize=0; | |
267 | while (flnk && iResult>=0) { | |
268 | FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject()); | |
269 | if (pFileDesc) { | |
270 | int size=pFileDesc->OpenFile(); | |
0449b3c8 | 271 | if (not keepOpen) pFileDesc->CloseFile(); |
d397a3b2 | 272 | if (size<0) { |
273 | iResult=size; | |
274 | HLTError("can not open file %s", pFileDesc->GetName()); | |
275 | } else { | |
276 | eventSize+=size; | |
277 | } | |
4ddfc222 | 278 | } |
d397a3b2 | 279 | flnk=flnk->Next(); |
4ddfc222 | 280 | } |
d397a3b2 | 281 | HLTDebug("event %p size %d", pEventDesc, eventSize); |
282 | if (fMaxSize<eventSize) fMaxSize=eventSize; | |
283 | } else { | |
284 | HLTError("can not get event descriptor for TObjLink"); | |
4ddfc222 | 285 | } |
286 | lnk = lnk->Next(); | |
287 | } | |
288 | ||
289 | return iResult; | |
290 | } | |
291 | ||
292 | int AliHLTFilePublisher::DoDeinit() | |
293 | { | |
294 | // see header file for class documentation | |
295 | int iResult=0; | |
d397a3b2 | 296 | fEvents.Clear(); |
4ddfc222 | 297 | return iResult; |
298 | } | |
299 | ||
b6800be0 | 300 | int AliHLTFilePublisher::GetEvent( const AliHLTComponentEventData& /*evtData*/, |
301 | AliHLTComponentTriggerData& /*trigData*/, | |
d397a3b2 | 302 | AliHLTUInt8_t* outputPtr, |
303 | AliHLTUInt32_t& size, | |
304 | vector<AliHLTComponentBlockData>& outputBlocks ) | |
4ddfc222 | 305 | { |
f3506ea2 | 306 | // see header file for class documentation |
4ddfc222 | 307 | int iResult=0; |
b6800be0 | 308 | TObjLink *lnk=fpCurrent; |
d397a3b2 | 309 | if (lnk==NULL) lnk=fEvents.FirstLink(); |
4ddfc222 | 310 | fpCurrent=lnk; |
311 | if (lnk) { | |
d397a3b2 | 312 | EventFiles* pEventDesc=dynamic_cast<EventFiles*>(lnk->GetObject()); |
313 | if (pEventDesc) { | |
314 | HLTDebug("publishing files for event %p", pEventDesc); | |
315 | TList& files=*pEventDesc; // type conversion operator defined | |
316 | TObjLink *flnk=files.FirstLink(); | |
317 | int iTotalSize=0; | |
318 | while (flnk && iResult>=0) { | |
319 | FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject()); | |
0449b3c8 | 320 | if (not fOpenFilesAtStart) pFileDesc->OpenFile(); |
d397a3b2 | 321 | TFile* pFile=NULL; |
322 | if (pFileDesc && (pFile=*pFileDesc)!=NULL) { | |
323 | int iCopy=pFile->GetSize(); | |
324 | pFile->Seek(0); | |
325 | if (iCopy+iTotalSize<=(int)size) { | |
326 | if (pFile->ReadBuffer((char*)outputPtr+iTotalSize, iCopy)!=0) { | |
327 | // ReadBuffer returns 1 in case of failure and 0 in case of success | |
328 | iResult=-EIO; | |
329 | } else { | |
330 | AliHLTComponentBlockData bd; | |
331 | FillBlockData(bd); | |
332 | bd.fPtr=outputPtr; | |
333 | bd.fOffset=iTotalSize; | |
334 | bd.fSize=iCopy; | |
335 | bd.fDataType=*pFileDesc; // type conversion operator defined | |
336 | bd.fSpecification=*pFileDesc; // type conversion operator defined | |
337 | outputBlocks.push_back(bd); | |
338 | iTotalSize+=iCopy; | |
339 | } | |
340 | } else { | |
341 | // output buffer too small, update GetOutputDataSize for the second trial | |
342 | fMaxSize=iCopy; | |
343 | iResult=-ENOSPC; | |
344 | } | |
0449b3c8 | 345 | if (not fOpenFilesAtStart) pFileDesc->CloseFile(); |
d397a3b2 | 346 | } else { |
347 | HLTError("no file available"); | |
348 | iResult=-EFAULT; | |
349 | } | |
350 | flnk=flnk->Next(); | |
b6800be0 | 351 | } |
d397a3b2 | 352 | size=iTotalSize; |
4ddfc222 | 353 | } else { |
d397a3b2 | 354 | HLTError("can not get event descriptor from list link"); |
4ddfc222 | 355 | iResult=-EFAULT; |
356 | } | |
357 | } else { | |
358 | iResult=-ENOENT; | |
359 | } | |
b6800be0 | 360 | if (iResult>=0 && fpCurrent) fpCurrent=fpCurrent->Next(); |
361 | ||
4ddfc222 | 362 | return iResult; |
363 | } | |
364 | ||
d397a3b2 | 365 | // AliHLTComponentDataType AliHLTFilePublisher::GetCurrentDataType() const |
366 | // { | |
367 | // return kAliHLTVoidDataType; | |
368 | // } | |
369 | ||
370 | // AliHLTUInt32_t AliHLTFilePublisher::GetCurrentSpecification() const | |
371 | // { | |
372 | // return 0; | |
373 | // } | |
374 | ||
375 | AliHLTFilePublisher::FileDesc::FileDesc(const char* name, AliHLTComponentDataType dt, AliHLTUInt32_t spec) | |
376 | : | |
377 | TObject(), | |
378 | fName(name), | |
379 | fpInstance(NULL), | |
380 | fDataType(dt), | |
381 | fSpecification(spec) | |
382 | { | |
f3506ea2 | 383 | // see header file for class documentation |
384 | // or | |
385 | // refer to README to build package | |
386 | // or | |
387 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
d397a3b2 | 388 | } |
0449b3c8 | 389 | |
d397a3b2 | 390 | AliHLTFilePublisher::FileDesc::~FileDesc() |
4ddfc222 | 391 | { |
f3506ea2 | 392 | // see header file for class documentation |
0449b3c8 | 393 | CloseFile(); |
394 | } | |
395 | ||
396 | void AliHLTFilePublisher::FileDesc::CloseFile() | |
397 | { | |
f3506ea2 | 398 | // see header file for class documentation |
0449b3c8 | 399 | if (fpInstance) |
400 | { | |
401 | // Unfortunately had to use AliLog mechanisms rather that AliHLTLogging because | |
402 | // AliHLTFilePublisher::FileDesc does not derive from AliHLTLogging. It would | |
403 | // become a rather heavy class if it did. | |
404 | #ifdef __DEBUG | |
405 | AliDebugGeneral("AliHLTFilePublisher::FileDesc", | |
406 | 2, Form("File %s has been closed.", fName.Data()) | |
407 | ); | |
408 | #endif | |
409 | delete fpInstance; | |
410 | } | |
d397a3b2 | 411 | fpInstance=NULL; |
4ddfc222 | 412 | } |
413 | ||
d397a3b2 | 414 | int AliHLTFilePublisher::FileDesc::OpenFile() |
4ddfc222 | 415 | { |
f3506ea2 | 416 | // see header file for class documentation |
d397a3b2 | 417 | int iResult=0; |
418 | TString fullFN= fName + "?filetype=raw"; | |
419 | fpInstance = new TFile(fullFN); | |
420 | if (fpInstance) { | |
421 | if (fpInstance->IsZombie()==0) { | |
422 | iResult=fpInstance->GetSize(); | |
0449b3c8 | 423 | #ifdef __DEBUG |
424 | AliDebugGeneral("AliHLTFilePublisher::FileDesc", | |
425 | 2, Form("File %s has been opened.", fName.Data()) | |
426 | ); | |
427 | #endif | |
d397a3b2 | 428 | } else { |
429 | iResult=-ENOENT; | |
430 | } | |
431 | } | |
432 | return iResult; | |
4ddfc222 | 433 | } |