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