Line data Source code
1 : // $Id$
2 :
3 : ///**************************************************************************
4 : ///* This file is property of and copyright by the *
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 AliHLTFilePublisher.cxx
20 : /// @author Matthias Richter
21 : /// @date
22 : /// @brief HLT file publisher component implementation. */
23 : ///
24 :
25 : #include "AliHLTFilePublisher.h"
26 : #include "AliHLTErrorGuard.h"
27 : #include "AliLog.h"
28 : #include <TMath.h>
29 : #include <TFile.h>
30 :
31 : using namespace std;
32 :
33 : /** ROOT macro for the implementation of ROOT specific class methods */
34 8 : ClassImp(AliHLTFilePublisher)
35 :
36 : AliHLTFilePublisher::AliHLTFilePublisher()
37 : :
38 9 : AliHLTDataSource(),
39 9 : fpCurrent(NULL),
40 9 : fEvents(),
41 9 : fMaxSize(0),
42 9 : fOpenFilesAtStart(false),
43 9 : fOutputDataTypes(),
44 9 : fIsRaw(kTRUE)
45 33 : {
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
54 9 : fEvents.SetOwner();
55 12 : }
56 :
57 : AliHLTFilePublisher::~AliHLTFilePublisher()
58 30 : {
59 : // destructor
60 :
61 : // file list and file name list are owner of their objects and
62 : // delete all the objects
63 15 : }
64 :
65 : const char* AliHLTFilePublisher::GetComponentID()
66 : {
67 : // overloaded from AliHLTComponent
68 624 : return "FilePublisher";
69 : }
70 :
71 : AliHLTComponentDataType AliHLTFilePublisher::GetOutputDataType()
72 : {
73 : // overloaded from AliHLTComponent
74 0 : if (fOutputDataTypes.size()==0) return kAliHLTVoidDataType;
75 0 : else if (fOutputDataTypes.size()==1) return fOutputDataTypes[0];
76 0 : return kAliHLTMultipleDataType;
77 0 : }
78 :
79 : int AliHLTFilePublisher::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
80 : {
81 : // overloaded from AliHLTComponent
82 0 : tgtList.assign(fOutputDataTypes.begin(), fOutputDataTypes.end());
83 0 : HLTInfo("%s %p provides %d output data types", GetComponentID(), this, fOutputDataTypes.size());
84 0 : return fOutputDataTypes.size();
85 : }
86 :
87 : void AliHLTFilePublisher::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
88 : {
89 : // overloaded from AliHLTComponent
90 0 : constBase=fMaxSize;
91 0 : inputMultiplier=1.0;
92 0 : }
93 :
94 : AliHLTComponent* AliHLTFilePublisher::Spawn()
95 : {
96 : // overloaded from AliHLTComponent
97 0 : return new AliHLTFilePublisher;
98 0 : }
99 :
100 : int AliHLTFilePublisher::DoInit( int argc, const char** argv )
101 : {
102 : // overloaded from AliHLTComponent: initialization
103 : int iResult=0;
104 0 : fOpenFilesAtStart = false;
105 0 : if ((iResult=ConfigureFromArgumentString(argc, argv))<0) return iResult;
106 :
107 0 : if (iResult>=0 && fEvents.GetSize()==0) {
108 0 : HLTError("the publisher needs at least one file argument");
109 : iResult=-EINVAL;
110 0 : }
111 0 : if (iResult>=0) iResult=OpenFiles(fOpenFilesAtStart);
112 0 : if (iResult<0) {
113 0 : fEvents.Clear();
114 0 : }
115 0 : return iResult;
116 0 : }
117 :
118 : int AliHLTFilePublisher::ScanConfigurationArgument(int argc, const char** argv)
119 : {
120 : // overloaded from AliHLTComponent: argument scan
121 : //HLTDebug("%d %s", argc, argv[0]);
122 : int iResult=0;
123 0 : TString argument="";
124 : int bMissingParam=0;
125 : int bHaveDatatype=0;
126 : int bHaveSpecification=0;
127 0 : AliHLTComponentDataType currDataType=kAliHLTVoidDataType;
128 0 : AliHLTUInt32_t currSpecification=kAliHLTVoidDataSpec;
129 0 : EventFiles* pCurrEvent=NULL;
130 : int i=0;
131 0 : for (; i<argc && iResult>=0; i++) {
132 0 : argument=argv[i];
133 0 : if (argument.IsNull()) continue;
134 :
135 : // -datafile
136 0 : if (argument.CompareTo("-datafile")==0) {
137 0 : if ((bMissingParam=(++i>=argc))) break;
138 0 : if (!bHaveDatatype) {
139 0 : 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");
140 : }
141 0 : FileDesc* pDesc=new FileDesc(argv[i], currDataType, currSpecification, fIsRaw);
142 0 : if (pDesc) {
143 0 : iResult=InsertFile(pCurrEvent, pDesc);
144 0 : } else {
145 : iResult=-ENOMEM;
146 : }
147 :
148 : // -datafilelist
149 0 : } else if (argument.CompareTo("-datafilelist")==0) {
150 0 : if ((bMissingParam=(++i>=argc))) break;
151 0 : TString input=argv[i];
152 0 : input+="?filetype=raw";
153 0 : TFile* pFile=new TFile(input);
154 0 : if (pFile && !pFile->IsZombie()) {
155 0 : pFile->Seek(0);
156 0 : TArrayC buffer;
157 0 : buffer.Set(pFile->GetSize()+1);
158 0 : if (pFile->ReadBuffer(buffer.GetArray(), pFile->GetSize())==0) {
159 0 : const char* argbuffer=buffer.GetArray();
160 0 : if ((iResult=ConfigureFromArgumentString(1, &argbuffer))<0) {
161 : iResult=-EPROTO;
162 : }
163 0 : } else {
164 0 : HLTError("failed to read configuration from file %s", argv[i]);
165 : iResult=-EIO;
166 : }
167 0 : } else {
168 0 : HLTError("can not open configuration file %s", argv[i]);
169 : iResult=-ENOENT;
170 : }
171 :
172 : // -datatype
173 0 : } else if (argument.CompareTo("-datatype")==0) {
174 0 : currDataType=kAliHLTVoidDataType;
175 0 : if ((bMissingParam=(++i>=argc))) break;
176 0 : memcpy(&currDataType.fID, argv[i], TMath::Min(kAliHLTComponentDataTypefIDsize, (Int_t)strlen(argv[i])));
177 0 : if ((bMissingParam=(++i>=argc))) break;
178 0 : memcpy(&currDataType.fOrigin, argv[i], TMath::Min(kAliHLTComponentDataTypefOriginSize, (Int_t)strlen(argv[i])));
179 :
180 : // add all different data types to the list
181 0 : AliHLTComponentDataTypeList::iterator element=fOutputDataTypes.begin();
182 0 : while (element!=fOutputDataTypes.end() && *element!=currDataType) element++;
183 0 : if (element==fOutputDataTypes.end()) fOutputDataTypes.push_back(currDataType);
184 :
185 0 : if (bHaveDatatype==0 && pCurrEvent && iResult>=0) {
186 : // this is a workaround to make old tutorials working which contain
187 : // the arguments in the wrong sequence
188 0 : TList& files=*pCurrEvent; // type conversion operator defined
189 0 : TObjLink *flnk=files.FirstLink();
190 0 : while (flnk) {
191 0 : FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
192 0 : if (pFileDesc) {
193 0 : pFileDesc->SetDataType(currDataType);
194 0 : }
195 0 : flnk=flnk->Next();
196 : }
197 0 : }
198 : bHaveDatatype=1;
199 :
200 : // -dataspec
201 0 : } else if (argument.CompareTo("-dataspec")==0) {
202 0 : if ((bMissingParam=(++i>=argc))) break;
203 0 : TString parameter(argv[i]);
204 0 : parameter.Remove(TString::kLeading, ' '); // remove all blanks
205 0 : if (parameter.IsDigit()) {
206 0 : currSpecification=(AliHLTUInt32_t)parameter.Atoi();
207 0 : } else if (parameter.BeginsWith("0x") &&
208 0 : parameter.Replace(0,2,"",0).IsHex()) {
209 0 : sscanf(parameter.Data(),"%x", &currSpecification);
210 : } else {
211 0 : HLTError("wrong parameter for argument %s, number expected", argument.Data());
212 : iResult=-EINVAL;
213 : }
214 0 : if (bHaveSpecification==0 && pCurrEvent && iResult>=0) {
215 : // this is a workaround to make old tutorials working which contain
216 : // the arguments in the wrong sequence
217 0 : TList& files=*pCurrEvent; // type conversion operator defined
218 0 : TObjLink *flnk=files.FirstLink();
219 0 : while (flnk) {
220 0 : FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
221 0 : if (pFileDesc) {
222 0 : pFileDesc->SetSpecification(currSpecification);
223 0 : }
224 0 : flnk=flnk->Next();
225 : }
226 0 : }
227 : bHaveSpecification=1;
228 : // -nextevent
229 0 : } else if (argument.CompareTo("-nextevent")==0) {
230 0 : InsertEvent(pCurrEvent);
231 0 : } else if (argument.CompareTo("-open_files_at_start")==0) {
232 0 : fOpenFilesAtStart = true;
233 0 : } else {
234 0 : if ((iResult=ScanArgument(argc-i, &argv[i]))==-EINVAL) {
235 0 : HLTError("unknown argument %s", argument.Data());
236 : break;
237 0 : } else if (iResult==-EPROTO) {
238 : bMissingParam=1;
239 0 : break;
240 0 : } else if (iResult>=0) {
241 0 : i+=iResult;
242 : iResult=0;
243 0 : }
244 : }
245 : }
246 0 : InsertEvent(pCurrEvent);
247 :
248 0 : if (bMissingParam) {
249 0 : HLTError("missing parameter for argument %s", argument.Data());
250 : iResult=-EINVAL;
251 0 : }
252 :
253 0 : if (iResult>=0) return i;
254 0 : return iResult;
255 0 : }
256 :
257 : int AliHLTFilePublisher::InsertFile(EventFiles* &pCurrEvent, FileDesc* pDesc)
258 : {
259 : // add file to event descriptor
260 : int iResult=0;
261 0 : if (pDesc) {
262 0 : if (pCurrEvent==NULL) {
263 0 : pCurrEvent=new EventFiles;
264 0 : if (pCurrEvent!=NULL) {
265 : } else {
266 : iResult=-ENOMEM;
267 : }
268 : }
269 0 : if (iResult>=0 && pCurrEvent!=NULL) {
270 : HLTDebug("Insert file %p to event %p", pDesc, pCurrEvent);
271 0 : pCurrEvent->Add(pDesc);
272 0 : }
273 : } else {
274 : iResult=-EINVAL;
275 : }
276 0 : return iResult;
277 0 : }
278 :
279 : int AliHLTFilePublisher::InsertEvent(EventFiles* &pEvent)
280 : {
281 : // insert eventfiles descriptor to publishing list
282 : int iResult=0;
283 0 : if (pEvent) {
284 : HLTDebug("Inserted event %p", pEvent);
285 0 : fEvents.Add(pEvent);
286 0 : pEvent=NULL;
287 0 : }
288 0 : return iResult;
289 : }
290 :
291 : int AliHLTFilePublisher::ScanArgument(int argc, const char** argv)
292 : {
293 : // scan argument
294 :
295 : // there are no other arguments than the standard ones
296 0 : if (argc==0 && argv==NULL) {
297 : // this is just to get rid of the warning "unused parameter"
298 : }
299 0 : return -EINVAL;
300 : }
301 :
302 : int AliHLTFilePublisher::OpenFiles(bool keepOpen)
303 : {
304 : // open files for consistency check, and keep optionally open
305 : int iResult=0;
306 0 : TObjLink *lnk=fEvents.FirstLink();
307 0 : while (lnk && iResult>=0) {
308 0 : EventFiles* pEventDesc=dynamic_cast<EventFiles*>(lnk->GetObject());
309 0 : if (pEventDesc) {
310 : HLTDebug("open files for event %p", pEventDesc);
311 0 : TList& files=*pEventDesc; // type conversion operator defined
312 0 : TObjLink *flnk=files.FirstLink();
313 : int eventSize=0;
314 0 : while (flnk && iResult>=0) {
315 0 : FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
316 0 : if (pFileDesc) {
317 0 : int size=pFileDesc->OpenFile();
318 0 : if (not keepOpen) pFileDesc->CloseFile();
319 0 : if (size<0) {
320 : iResult=size;
321 0 : HLTError("can not open file %s", pFileDesc->GetName());
322 : } else {
323 0 : eventSize+=size;
324 : }
325 0 : }
326 0 : flnk=flnk->Next();
327 : }
328 : HLTDebug("event %p size %d", pEventDesc, eventSize);
329 0 : if (fMaxSize<eventSize) fMaxSize=eventSize;
330 0 : } else {
331 0 : HLTError("can not get event descriptor for TObjLink");
332 : }
333 0 : lnk = lnk->Next();
334 : }
335 :
336 0 : return iResult;
337 : }
338 :
339 : int AliHLTFilePublisher::DoDeinit()
340 : {
341 : // overloaded from AliHLTComponent: cleanup
342 : int iResult=0;
343 0 : fEvents.Clear();
344 0 : return iResult;
345 : }
346 :
347 : int AliHLTFilePublisher::GetEvent( const AliHLTComponentEventData& /*evtData*/,
348 : AliHLTComponentTriggerData& /*trigData*/,
349 : AliHLTUInt8_t* outputPtr,
350 : AliHLTUInt32_t& size,
351 : AliHLTComponentBlockDataList& outputBlocks )
352 : {
353 : // overloaded from AliHLTDataSource: event processing
354 :
355 : // process data events only
356 0 : if (!IsDataEvent()) return 0;
357 0 : AliHLTUInt32_t capacity=size;
358 0 : size=0;
359 :
360 : int iResult=0;
361 0 : TObjLink *lnk=fpCurrent;
362 0 : if (lnk==NULL) lnk=fEvents.FirstLink();
363 0 : fpCurrent=lnk;
364 0 : if (lnk) {
365 0 : EventFiles* pEventDesc=dynamic_cast<EventFiles*>(lnk->GetObject());
366 0 : if (pEventDesc) {
367 : HLTDebug("publishing files for event %p", pEventDesc);
368 0 : TList& files=*pEventDesc; // type conversion operator defined
369 0 : TObjLink *flnk=files.FirstLink();
370 : int iTotalSize=0;
371 0 : while (flnk && iResult>=0) {
372 0 : if (!flnk->GetObject()) {
373 0 : ALIHLTERRORGUARD(5, "internal mismatch in Root list iterator");
374 0 : continue;
375 : }
376 0 : FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
377 0 : if (!pFileDesc) {
378 0 : ALIHLTERRORGUARD(5, "internal mismatch, invalid object type for dynamic_cast");
379 0 : continue;
380 : }
381 :
382 0 : if (not fOpenFilesAtStart) pFileDesc->OpenFile();
383 : TFile* pFile=NULL;
384 0 : if (pFileDesc && (pFile=*pFileDesc)!=NULL) {
385 0 : int iCopy=pFile->GetSize();
386 0 : pFile->Seek(0);
387 0 : if (iCopy+iTotalSize<=(int)capacity) {
388 0 : if (pFile->ReadBuffer((char*)outputPtr+iTotalSize, iCopy)!=0) {
389 : // ReadBuffer returns 1 in case of failure and 0 in case of success
390 : iResult=-EIO;
391 0 : } else {
392 0 : AliHLTComponentBlockData bd;
393 0 : FillBlockData(bd);
394 0 : bd.fPtr=outputPtr;
395 0 : bd.fOffset=iTotalSize;
396 0 : bd.fSize=iCopy;
397 0 : bd.fDataType=*pFileDesc; // type conversion operator defined
398 0 : bd.fSpecification=*pFileDesc; // type conversion operator defined
399 0 : outputBlocks.push_back(bd);
400 : iTotalSize+=iCopy;
401 : // TString msg;
402 : // msg.Form("get file %s ", pFile->GetName());
403 : // msg+="data type \'%s\'";
404 : // PrintDataTypeContent(bd.fDataType, msg.Data());
405 0 : }
406 : } else {
407 : // output buffer too small, update GetOutputDataSize for the second trial
408 0 : fMaxSize=iCopy;
409 : iResult=-ENOSPC;
410 : }
411 0 : if (not fOpenFilesAtStart) pFileDesc->CloseFile();
412 0 : } else {
413 0 : HLTError("no file available");
414 : iResult=-EFAULT;
415 : }
416 0 : flnk=flnk->Next();
417 0 : }
418 0 : size=iTotalSize;
419 0 : } else {
420 0 : HLTError("can not get event descriptor from list link");
421 : iResult=-EFAULT;
422 : }
423 0 : } else {
424 : iResult=-ENOENT;
425 : }
426 0 : if (iResult>=0 && fpCurrent) fpCurrent=fpCurrent->Next();
427 :
428 : return iResult;
429 0 : }
430 :
431 : AliHLTFilePublisher::FileDesc::FileDesc(const char* name, AliHLTComponentDataType dt, AliHLTUInt32_t spec, Bool_t isRaw)
432 : :
433 0 : TObject(),
434 0 : fIsRaw(isRaw),
435 0 : fName(name),
436 0 : fpInstance(NULL),
437 0 : fDataType(dt),
438 0 : fSpecification(spec)
439 0 : {
440 : // file descriptor helper structure
441 0 : }
442 :
443 : AliHLTFilePublisher::FileDesc::~FileDesc()
444 0 : {
445 : // destructor
446 0 : CloseFile();
447 0 : }
448 :
449 : void AliHLTFilePublisher::FileDesc::CloseFile()
450 : {
451 : // close file
452 0 : if (fpInstance)
453 : {
454 : // Unfortunately had to use AliLog mechanisms rather that AliHLTLogging because
455 : // AliHLTFilePublisher::FileDesc does not derive from AliHLTLogging. It would
456 : // become a rather heavy class if it did.
457 : #ifdef __DEBUG
458 : AliDebugGeneral("AliHLTFilePublisher::FileDesc",
459 : 2, Form("File %s has been closed.", fName.Data())
460 : );
461 : #endif
462 0 : delete fpInstance;
463 : }
464 0 : fpInstance=NULL;
465 0 : }
466 :
467 : int AliHLTFilePublisher::FileDesc::OpenFile()
468 : {
469 : // open file
470 : int iResult=0;
471 :
472 0 : TString fullFN="";
473 :
474 0 : if ( fIsRaw ) fullFN = fName + "?filetype=raw";
475 0 : else fullFN = fName;
476 :
477 0 : fpInstance = TFile::Open(fullFN);
478 0 : if (fpInstance) {
479 0 : if (fpInstance->IsZombie()==0) {
480 0 : iResult=fpInstance->GetSize();
481 : #ifdef __DEBUG
482 : AliDebugGeneral("AliHLTFilePublisher::FileDesc",
483 : 2, Form("File %s has been opened.", fName.Data())
484 : );
485 : #endif
486 0 : } else {
487 : iResult=-ENOENT;
488 : }
489 : }
490 : return iResult;
491 0 : }
|