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