]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/util/AliHLTFilePublisher.cxx
enhanced functionality to publish multiple equipment ids and insert empty blocks...
[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) {
145 if ((bMissingParam=(++i>=argc))) break;
d397a3b2 146 memcpy(&currDataType.fID, argv[i], TMath::Min(kAliHLTComponentDataTypefIDsize, (Int_t)strlen(argv[i])));
4ddfc222 147 if ((bMissingParam=(++i>=argc))) break;
d397a3b2 148 memcpy(&currDataType.fOrigin, argv[i], TMath::Min(kAliHLTComponentDataTypefOriginSize, (Int_t)strlen(argv[i])));
8a106878 149
150 // add all different data types to the list
151 AliHLTComponentDataTypeList::iterator element=fOutputDataTypes.begin();
152 while (element!=fOutputDataTypes.end() && *element!=currDataType) element++;
153 if (element==fOutputDataTypes.end()) fOutputDataTypes.push_back(currDataType);
154
fe050813 155 if (bHaveDatatype==0 && pCurrEvent && iResult>=0) {
156 // this is a workaround to make old tutorials working which contain
157 // the arguments in the wrong sequence
158 TList& files=*pCurrEvent; // type conversion operator defined
159 TObjLink *flnk=files.FirstLink();
fe050813 160 while (flnk) {
161 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
162 if (pFileDesc) {
163 pFileDesc->SetDataType(currDataType);
164 }
165 flnk=flnk->Next();
166 }
167 }
168 bHaveDatatype=1;
4ddfc222 169
170 // -dataspec
171 } else if (argument.CompareTo("-dataspec")==0) {
172 if ((bMissingParam=(++i>=argc))) break;
173 TString parameter(argv[i]);
174 parameter.Remove(TString::kLeading, ' '); // remove all blanks
175 if (parameter.IsDigit()) {
d397a3b2 176 currSpecification=(AliHLTUInt32_t)parameter.Atoi();
4ddfc222 177 } else if (parameter.BeginsWith("0x") &&
178 parameter.Replace(0,2,"",0).IsHex()) {
d397a3b2 179 sscanf(parameter.Data(),"%x", &currSpecification);
4ddfc222 180 } else {
181 HLTError("wrong parameter for argument %s, number expected", argument.Data());
182 iResult=-EINVAL;
183 }
fe050813 184 if (bHaveSpecification==0 && pCurrEvent && iResult>=0) {
185 // this is a workaround to make old tutorials working which contain
186 // the arguments in the wrong sequence
187 TList& files=*pCurrEvent; // type conversion operator defined
188 TObjLink *flnk=files.FirstLink();
fe050813 189 while (flnk) {
190 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
191 if (pFileDesc) {
192 pFileDesc->SetSpecification(currSpecification);
193 }
194 flnk=flnk->Next();
195 }
196 }
197 bHaveSpecification=1;
d397a3b2 198 // -nextevent
199 } else if (argument.CompareTo("-nextevent")==0) {
200 InsertEvent(pCurrEvent);
0449b3c8 201 } else if (argument.CompareTo("-open_files_at_start")==0) {
202 fOpenFilesAtStart = true;
4ddfc222 203 } else {
204 if ((iResult=ScanArgument(argc-i, &argv[i]))==-EINVAL) {
205 HLTError("unknown argument %s", argument.Data());
206 break;
207 } else if (iResult==-EPROTO) {
208 bMissingParam=1;
209 break;
210 } else if (iResult>=0) {
211 i+=iResult;
212 iResult=0;
213 }
214 }
215 }
d397a3b2 216 InsertEvent(pCurrEvent);
217
4ddfc222 218 if (bMissingParam) {
219 HLTError("missing parameter for argument %s", argument.Data());
220 iResult=-EINVAL;
221 }
d397a3b2 222 if (fEvents.GetSize()==0) {
4ddfc222 223 HLTError("the publisher needs at least one file argument");
224 iResult=-EINVAL;
225 }
0449b3c8 226 if (iResult>=0) iResult=OpenFiles(fOpenFilesAtStart);
4ddfc222 227 if (iResult<0) {
d397a3b2 228 fEvents.Clear();
229 }
230 return iResult;
231}
232
233int AliHLTFilePublisher::InsertFile(EventFiles* &pCurrEvent, FileDesc* pDesc)
234{
f3506ea2 235 // see header file for class documentation
d397a3b2 236 int iResult=0;
237 if (pDesc) {
238 if (pCurrEvent==NULL) {
239 pCurrEvent=new EventFiles;
240 if (pCurrEvent!=NULL) {
241 } else {
242 iResult=-ENOMEM;
243 }
244 }
245 if (iResult>=0 && pCurrEvent!=NULL) {
246 HLTDebug("Insert file %p to event %p", pDesc, pCurrEvent);
247 pCurrEvent->Add(pDesc);
248 }
249 } else {
250 iResult=-EINVAL;
251 }
252 return iResult;
253}
254
255int AliHLTFilePublisher::InsertEvent(EventFiles* &pEvent)
256{
f3506ea2 257 // see header file for class documentation
d397a3b2 258 int iResult=0;
259 if (pEvent) {
260 HLTDebug("Inserted event %p", pEvent);
261 fEvents.Add(pEvent);
262 pEvent=NULL;
4ddfc222 263 }
264 return iResult;
265}
266
267int AliHLTFilePublisher::ScanArgument(int argc, const char** argv)
268{
269 // see header file for class documentation
270
271 // there are no other arguments than the standard ones
272 if (argc==0 && argv==NULL) {
273 // this is just to get rid of the warning "unused parameter"
274 }
0449b3c8 275 return -EINVAL;
4ddfc222 276}
277
0449b3c8 278int AliHLTFilePublisher::OpenFiles(bool keepOpen)
4ddfc222 279{
280 // see header file for class documentation
281 int iResult=0;
d397a3b2 282 TObjLink *lnk=fEvents.FirstLink();
4ddfc222 283 while (lnk && iResult>=0) {
d397a3b2 284 EventFiles* pEventDesc=dynamic_cast<EventFiles*>(lnk->GetObject());
285 if (pEventDesc) {
286 HLTDebug("open files for event %p", pEventDesc);
287 TList& files=*pEventDesc; // type conversion operator defined
288 TObjLink *flnk=files.FirstLink();
289 int eventSize=0;
290 while (flnk && iResult>=0) {
291 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
292 if (pFileDesc) {
293 int size=pFileDesc->OpenFile();
0449b3c8 294 if (not keepOpen) pFileDesc->CloseFile();
d397a3b2 295 if (size<0) {
296 iResult=size;
297 HLTError("can not open file %s", pFileDesc->GetName());
298 } else {
299 eventSize+=size;
300 }
4ddfc222 301 }
d397a3b2 302 flnk=flnk->Next();
4ddfc222 303 }
d397a3b2 304 HLTDebug("event %p size %d", pEventDesc, eventSize);
305 if (fMaxSize<eventSize) fMaxSize=eventSize;
306 } else {
307 HLTError("can not get event descriptor for TObjLink");
4ddfc222 308 }
309 lnk = lnk->Next();
310 }
311
312 return iResult;
313}
314
315int AliHLTFilePublisher::DoDeinit()
316{
317 // see header file for class documentation
318 int iResult=0;
d397a3b2 319 fEvents.Clear();
4ddfc222 320 return iResult;
321}
322
b6800be0 323int AliHLTFilePublisher::GetEvent( const AliHLTComponentEventData& /*evtData*/,
324 AliHLTComponentTriggerData& /*trigData*/,
d397a3b2 325 AliHLTUInt8_t* outputPtr,
326 AliHLTUInt32_t& size,
7bcd6cad 327 AliHLTComponentBlockDataList& outputBlocks )
4ddfc222 328{
f3506ea2 329 // see header file for class documentation
4ddfc222 330 int iResult=0;
b6800be0 331 TObjLink *lnk=fpCurrent;
d397a3b2 332 if (lnk==NULL) lnk=fEvents.FirstLink();
4ddfc222 333 fpCurrent=lnk;
334 if (lnk) {
d397a3b2 335 EventFiles* pEventDesc=dynamic_cast<EventFiles*>(lnk->GetObject());
336 if (pEventDesc) {
337 HLTDebug("publishing files for event %p", pEventDesc);
338 TList& files=*pEventDesc; // type conversion operator defined
339 TObjLink *flnk=files.FirstLink();
340 int iTotalSize=0;
341 while (flnk && iResult>=0) {
342 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
0449b3c8 343 if (not fOpenFilesAtStart) pFileDesc->OpenFile();
d397a3b2 344 TFile* pFile=NULL;
345 if (pFileDesc && (pFile=*pFileDesc)!=NULL) {
346 int iCopy=pFile->GetSize();
347 pFile->Seek(0);
348 if (iCopy+iTotalSize<=(int)size) {
349 if (pFile->ReadBuffer((char*)outputPtr+iTotalSize, iCopy)!=0) {
350 // ReadBuffer returns 1 in case of failure and 0 in case of success
351 iResult=-EIO;
352 } else {
353 AliHLTComponentBlockData bd;
354 FillBlockData(bd);
355 bd.fPtr=outputPtr;
356 bd.fOffset=iTotalSize;
357 bd.fSize=iCopy;
358 bd.fDataType=*pFileDesc; // type conversion operator defined
359 bd.fSpecification=*pFileDesc; // type conversion operator defined
360 outputBlocks.push_back(bd);
361 iTotalSize+=iCopy;
8a106878 362// TString msg;
363// msg.Form("get file %s ", pFile->GetName());
364// msg+="data type \'%s\'";
365// PrintDataTypeContent(bd.fDataType, msg.Data());
d397a3b2 366 }
367 } else {
368 // output buffer too small, update GetOutputDataSize for the second trial
369 fMaxSize=iCopy;
370 iResult=-ENOSPC;
371 }
0449b3c8 372 if (not fOpenFilesAtStart) pFileDesc->CloseFile();
d397a3b2 373 } else {
374 HLTError("no file available");
375 iResult=-EFAULT;
376 }
377 flnk=flnk->Next();
b6800be0 378 }
d397a3b2 379 size=iTotalSize;
4ddfc222 380 } else {
d397a3b2 381 HLTError("can not get event descriptor from list link");
4ddfc222 382 iResult=-EFAULT;
383 }
384 } else {
385 iResult=-ENOENT;
386 }
b6800be0 387 if (iResult>=0 && fpCurrent) fpCurrent=fpCurrent->Next();
388
4ddfc222 389 return iResult;
390}
391
d397a3b2 392// AliHLTComponentDataType AliHLTFilePublisher::GetCurrentDataType() const
393// {
394// return kAliHLTVoidDataType;
395// }
396
397// AliHLTUInt32_t AliHLTFilePublisher::GetCurrentSpecification() const
398// {
399// return 0;
400// }
401
402AliHLTFilePublisher::FileDesc::FileDesc(const char* name, AliHLTComponentDataType dt, AliHLTUInt32_t spec)
403 :
404 TObject(),
405 fName(name),
406 fpInstance(NULL),
407 fDataType(dt),
408 fSpecification(spec)
409{
f3506ea2 410 // see header file for class documentation
411 // or
412 // refer to README to build package
413 // or
414 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
d397a3b2 415}
0449b3c8 416
d397a3b2 417AliHLTFilePublisher::FileDesc::~FileDesc()
4ddfc222 418{
f3506ea2 419 // see header file for class documentation
0449b3c8 420 CloseFile();
421}
422
423void AliHLTFilePublisher::FileDesc::CloseFile()
424{
f3506ea2 425 // see header file for class documentation
0449b3c8 426 if (fpInstance)
427 {
428 // Unfortunately had to use AliLog mechanisms rather that AliHLTLogging because
429 // AliHLTFilePublisher::FileDesc does not derive from AliHLTLogging. It would
430 // become a rather heavy class if it did.
431#ifdef __DEBUG
432 AliDebugGeneral("AliHLTFilePublisher::FileDesc",
433 2, Form("File %s has been closed.", fName.Data())
434 );
435#endif
436 delete fpInstance;
437 }
d397a3b2 438 fpInstance=NULL;
4ddfc222 439}
440
d397a3b2 441int AliHLTFilePublisher::FileDesc::OpenFile()
4ddfc222 442{
f3506ea2 443 // see header file for class documentation
d397a3b2 444 int iResult=0;
445 TString fullFN= fName + "?filetype=raw";
446 fpInstance = new TFile(fullFN);
447 if (fpInstance) {
448 if (fpInstance->IsZombie()==0) {
449 iResult=fpInstance->GetSize();
0449b3c8 450#ifdef __DEBUG
451 AliDebugGeneral("AliHLTFilePublisher::FileDesc",
452 2, Form("File %s has been opened.", fName.Data())
453 );
454#endif
d397a3b2 455 } else {
456 iResult=-ENOENT;
457 }
458 }
459 return iResult;
4ddfc222 460}