3 /**************************************************************************
4 * This file is property of and copyright by the ALICE HLT Project *
5 * ALICE Experiment at CERN, All rights reserved. *
7 * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 * for The ALICE HLT Project. *
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 **************************************************************************/
19 /** @file AliHLTFilePublisher.cxx
20 @author Matthias Richter
22 @brief HLT file publisher component implementation. */
24 // see header file for class documentation
26 // refer to README to build package
28 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
34 #include "AliHLTFilePublisher.h"
36 //#include <TObjString.h>
41 /** ROOT macro for the implementation of ROOT specific class methods */
42 ClassImp(AliHLTFilePublisher)
44 AliHLTFilePublisher::AliHLTFilePublisher()
50 fOpenFilesAtStart(false),
54 // see header file for class documentation
56 // refer to README to build package
58 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
60 // make the lists owners of their objects in order to automatically
61 // de-allocate the objects
65 AliHLTFilePublisher::~AliHLTFilePublisher()
67 // see header file for class documentation
69 // file list and file name list are owner of their objects and
70 // delete all the objects
73 const char* AliHLTFilePublisher::GetComponentID()
75 // see header file for class documentation
76 return "FilePublisher";
79 AliHLTComponentDataType AliHLTFilePublisher::GetOutputDataType()
81 // see header file for class documentation
82 if (fOutputDataTypes.size()==0) return kAliHLTVoidDataType;
83 else if (fOutputDataTypes.size()==1) return fOutputDataTypes[0];
84 return kAliHLTMultipleDataType;
87 int AliHLTFilePublisher::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
89 // see header file for class documentation
90 tgtList.assign(fOutputDataTypes.begin(), fOutputDataTypes.end());
91 HLTInfo("%s %p provides %d output data types", GetComponentID(), this, fOutputDataTypes.size());
92 return fOutputDataTypes.size();
95 void AliHLTFilePublisher::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
97 // see header file for class documentation
102 AliHLTComponent* AliHLTFilePublisher::Spawn()
104 // see header file for class documentation
105 return new AliHLTFilePublisher;
108 int AliHLTFilePublisher::DoInit( int argc, const char** argv )
110 // see header file for class documentation
112 //HLTDebug("%d %s", argc, argv[0]);
117 int bHaveSpecification=0;
118 fOpenFilesAtStart = false;
119 AliHLTComponentDataType currDataType=kAliHLTVoidDataType;
120 AliHLTUInt32_t currSpecification=kAliHLTVoidDataSpec;
121 EventFiles* pCurrEvent=NULL;
122 for (int i=0; i<argc && iResult>=0; i++) {
124 if (argument.IsNull()) continue;
127 if (argument.CompareTo("-datafile")==0) {
128 if ((bMissingParam=(++i>=argc))) break;
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");
132 FileDesc* pDesc=new FileDesc(argv[i], currDataType, currSpecification, fIsRaw);
134 iResult=InsertFile(pCurrEvent, pDesc);
140 } else if (argument.CompareTo("-datafilelist")==0) {
141 if ((bMissingParam=(++i>=argc))) break;
142 HLTWarning("-datafilelist option not yet implemented");
145 } else if (argument.CompareTo("-datatype")==0) {
146 currDataType=kAliHLTVoidDataType;
147 if ((bMissingParam=(++i>=argc))) break;
148 memcpy(&currDataType.fID, argv[i], TMath::Min(kAliHLTComponentDataTypefIDsize, (Int_t)strlen(argv[i])));
149 if ((bMissingParam=(++i>=argc))) break;
150 memcpy(&currDataType.fOrigin, argv[i], TMath::Min(kAliHLTComponentDataTypefOriginSize, (Int_t)strlen(argv[i])));
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);
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();
163 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
165 pFileDesc->SetDataType(currDataType);
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()) {
178 currSpecification=(AliHLTUInt32_t)parameter.Atoi();
179 } else if (parameter.BeginsWith("0x") &&
180 parameter.Replace(0,2,"",0).IsHex()) {
181 sscanf(parameter.Data(),"%x", &currSpecification);
183 HLTError("wrong parameter for argument %s, number expected", argument.Data());
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();
192 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
194 pFileDesc->SetSpecification(currSpecification);
199 bHaveSpecification=1;
201 } else if (argument.CompareTo("-nextevent")==0) {
202 InsertEvent(pCurrEvent);
203 } else if (argument.CompareTo("-open_files_at_start")==0) {
204 fOpenFilesAtStart = true;
206 if ((iResult=ScanArgument(argc-i, &argv[i]))==-EINVAL) {
207 HLTError("unknown argument %s", argument.Data());
209 } else if (iResult==-EPROTO) {
212 } else if (iResult>=0) {
218 InsertEvent(pCurrEvent);
221 HLTError("missing parameter for argument %s", argument.Data());
224 if (fEvents.GetSize()==0) {
225 HLTError("the publisher needs at least one file argument");
228 if (iResult>=0) iResult=OpenFiles(fOpenFilesAtStart);
235 int AliHLTFilePublisher::InsertFile(EventFiles* &pCurrEvent, FileDesc* pDesc)
237 // see header file for class documentation
240 if (pCurrEvent==NULL) {
241 pCurrEvent=new EventFiles;
242 if (pCurrEvent!=NULL) {
247 if (iResult>=0 && pCurrEvent!=NULL) {
248 HLTDebug("Insert file %p to event %p", pDesc, pCurrEvent);
249 pCurrEvent->Add(pDesc);
257 int AliHLTFilePublisher::InsertEvent(EventFiles* &pEvent)
259 // see header file for class documentation
262 HLTDebug("Inserted event %p", pEvent);
269 int AliHLTFilePublisher::ScanArgument(int argc, const char** argv)
271 // see header file for class documentation
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"
280 int AliHLTFilePublisher::OpenFiles(bool keepOpen)
282 // see header file for class documentation
284 TObjLink *lnk=fEvents.FirstLink();
285 while (lnk && iResult>=0) {
286 EventFiles* pEventDesc=dynamic_cast<EventFiles*>(lnk->GetObject());
288 HLTDebug("open files for event %p", pEventDesc);
289 TList& files=*pEventDesc; // type conversion operator defined
290 TObjLink *flnk=files.FirstLink();
292 while (flnk && iResult>=0) {
293 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
295 int size=pFileDesc->OpenFile();
296 if (not keepOpen) pFileDesc->CloseFile();
299 HLTError("can not open file %s", pFileDesc->GetName());
306 HLTDebug("event %p size %d", pEventDesc, eventSize);
307 if (fMaxSize<eventSize) fMaxSize=eventSize;
309 HLTError("can not get event descriptor for TObjLink");
317 int AliHLTFilePublisher::DoDeinit()
319 // see header file for class documentation
325 int AliHLTFilePublisher::GetEvent( const AliHLTComponentEventData& /*evtData*/,
326 AliHLTComponentTriggerData& /*trigData*/,
327 AliHLTUInt8_t* outputPtr,
328 AliHLTUInt32_t& size,
329 AliHLTComponentBlockDataList& outputBlocks )
331 // see header file for class documentation
333 // process data events only
334 if (!IsDataEvent()) return 0;
335 AliHLTUInt32_t capacity=size;
339 TObjLink *lnk=fpCurrent;
340 if (lnk==NULL) lnk=fEvents.FirstLink();
343 EventFiles* pEventDesc=dynamic_cast<EventFiles*>(lnk->GetObject());
345 HLTDebug("publishing files for event %p", pEventDesc);
346 TList& files=*pEventDesc; // type conversion operator defined
347 TObjLink *flnk=files.FirstLink();
349 while (flnk && iResult>=0) {
350 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
351 if (not fOpenFilesAtStart) pFileDesc->OpenFile();
353 if (pFileDesc && (pFile=*pFileDesc)!=NULL) {
354 int iCopy=pFile->GetSize();
356 if (iCopy+iTotalSize<=(int)capacity) {
357 if (pFile->ReadBuffer((char*)outputPtr+iTotalSize, iCopy)!=0) {
358 // ReadBuffer returns 1 in case of failure and 0 in case of success
361 AliHLTComponentBlockData bd;
364 bd.fOffset=iTotalSize;
366 bd.fDataType=*pFileDesc; // type conversion operator defined
367 bd.fSpecification=*pFileDesc; // type conversion operator defined
368 outputBlocks.push_back(bd);
371 // msg.Form("get file %s ", pFile->GetName());
372 // msg+="data type \'%s\'";
373 // PrintDataTypeContent(bd.fDataType, msg.Data());
376 // output buffer too small, update GetOutputDataSize for the second trial
380 if (not fOpenFilesAtStart) pFileDesc->CloseFile();
382 HLTError("no file available");
389 HLTError("can not get event descriptor from list link");
395 if (iResult>=0 && fpCurrent) fpCurrent=fpCurrent->Next();
400 // AliHLTComponentDataType AliHLTFilePublisher::GetCurrentDataType() const
402 // return kAliHLTVoidDataType;
405 // AliHLTUInt32_t AliHLTFilePublisher::GetCurrentSpecification() const
410 AliHLTFilePublisher::FileDesc::FileDesc(const char* name, AliHLTComponentDataType dt, AliHLTUInt32_t spec, Bool_t isRaw)
419 // see header file for class documentation
421 // refer to README to build package
423 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
426 AliHLTFilePublisher::FileDesc::~FileDesc()
428 // see header file for class documentation
432 void AliHLTFilePublisher::FileDesc::CloseFile()
434 // see header file for class documentation
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.
441 AliDebugGeneral("AliHLTFilePublisher::FileDesc",
442 2, Form("File %s has been closed.", fName.Data())
450 int AliHLTFilePublisher::FileDesc::OpenFile()
452 // see header file for class documentation
457 if ( fIsRaw ) fullFN = fName + "?filetype=raw";
460 fpInstance = TFile::Open(fullFN);
462 if (fpInstance->IsZombie()==0) {
463 iResult=fpInstance->GetSize();
465 AliDebugGeneral("AliHLTFilePublisher::FileDesc",
466 2, Form("File %s has been opened.", fName.Data())