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),
53 // see header file for class documentation
55 // refer to README to build package
57 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
59 // make the lists owners of their objects in order to automatically
60 // de-allocate the objects
64 AliHLTFilePublisher::~AliHLTFilePublisher()
66 // see header file for class documentation
68 // file list and file name list are owner of their objects and
69 // delete all the objects
72 const char* AliHLTFilePublisher::GetComponentID()
74 // see header file for class documentation
75 return "FilePublisher";
78 AliHLTComponentDataType AliHLTFilePublisher::GetOutputDataType()
80 // see header file for class documentation
81 if (fOutputDataTypes.size()==0) return kAliHLTVoidDataType;
82 else if (fOutputDataTypes.size()==1) return fOutputDataTypes[0];
83 return kAliHLTMultipleDataType;
86 int AliHLTFilePublisher::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
88 // see header file for class documentation
89 tgtList.assign(fOutputDataTypes.begin(), fOutputDataTypes.end());
90 HLTInfo("%s %p provides %d output data types", GetComponentID(), this, fOutputDataTypes.size());
91 return fOutputDataTypes.size();
94 void AliHLTFilePublisher::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
96 // see header file for class documentation
101 AliHLTComponent* AliHLTFilePublisher::Spawn()
103 // see header file for class documentation
104 return new AliHLTFilePublisher;
107 int AliHLTFilePublisher::DoInit( int argc, const char** argv )
109 // see header file for class documentation
111 //HLTDebug("%d %s", argc, argv[0]);
116 int bHaveSpecification=0;
117 fOpenFilesAtStart = false;
118 AliHLTComponentDataType currDataType=kAliHLTVoidDataType;
119 AliHLTUInt32_t currSpecification=kAliHLTVoidDataSpec;
120 EventFiles* pCurrEvent=NULL;
121 for (int i=0; i<argc && iResult>=0; i++) {
123 if (argument.IsNull()) continue;
126 if (argument.CompareTo("-datafile")==0) {
127 if ((bMissingParam=(++i>=argc))) break;
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");
131 FileDesc* pDesc=new FileDesc(argv[i], currDataType, currSpecification);
133 iResult=InsertFile(pCurrEvent, pDesc);
139 } else if (argument.CompareTo("-datafilelist")==0) {
140 if ((bMissingParam=(++i>=argc))) break;
141 HLTWarning("-datafilelist option not yet implemented");
144 } else if (argument.CompareTo("-datatype")==0) {
145 currDataType=kAliHLTVoidDataType;
146 if ((bMissingParam=(++i>=argc))) break;
147 memcpy(&currDataType.fID, argv[i], TMath::Min(kAliHLTComponentDataTypefIDsize, (Int_t)strlen(argv[i])));
148 if ((bMissingParam=(++i>=argc))) break;
149 memcpy(&currDataType.fOrigin, argv[i], TMath::Min(kAliHLTComponentDataTypefOriginSize, (Int_t)strlen(argv[i])));
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);
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();
162 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
164 pFileDesc->SetDataType(currDataType);
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()) {
177 currSpecification=(AliHLTUInt32_t)parameter.Atoi();
178 } else if (parameter.BeginsWith("0x") &&
179 parameter.Replace(0,2,"",0).IsHex()) {
180 sscanf(parameter.Data(),"%x", &currSpecification);
182 HLTError("wrong parameter for argument %s, number expected", argument.Data());
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();
191 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
193 pFileDesc->SetSpecification(currSpecification);
198 bHaveSpecification=1;
200 } else if (argument.CompareTo("-nextevent")==0) {
201 InsertEvent(pCurrEvent);
202 } else if (argument.CompareTo("-open_files_at_start")==0) {
203 fOpenFilesAtStart = true;
205 if ((iResult=ScanArgument(argc-i, &argv[i]))==-EINVAL) {
206 HLTError("unknown argument %s", argument.Data());
208 } else if (iResult==-EPROTO) {
211 } else if (iResult>=0) {
217 InsertEvent(pCurrEvent);
220 HLTError("missing parameter for argument %s", argument.Data());
223 if (fEvents.GetSize()==0) {
224 HLTError("the publisher needs at least one file argument");
227 if (iResult>=0) iResult=OpenFiles(fOpenFilesAtStart);
234 int AliHLTFilePublisher::InsertFile(EventFiles* &pCurrEvent, FileDesc* pDesc)
236 // see header file for class documentation
239 if (pCurrEvent==NULL) {
240 pCurrEvent=new EventFiles;
241 if (pCurrEvent!=NULL) {
246 if (iResult>=0 && pCurrEvent!=NULL) {
247 HLTDebug("Insert file %p to event %p", pDesc, pCurrEvent);
248 pCurrEvent->Add(pDesc);
256 int AliHLTFilePublisher::InsertEvent(EventFiles* &pEvent)
258 // see header file for class documentation
261 HLTDebug("Inserted event %p", pEvent);
268 int AliHLTFilePublisher::ScanArgument(int argc, const char** argv)
270 // see header file for class documentation
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"
279 int AliHLTFilePublisher::OpenFiles(bool keepOpen)
281 // see header file for class documentation
283 TObjLink *lnk=fEvents.FirstLink();
284 while (lnk && iResult>=0) {
285 EventFiles* pEventDesc=dynamic_cast<EventFiles*>(lnk->GetObject());
287 HLTDebug("open files for event %p", pEventDesc);
288 TList& files=*pEventDesc; // type conversion operator defined
289 TObjLink *flnk=files.FirstLink();
291 while (flnk && iResult>=0) {
292 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
294 int size=pFileDesc->OpenFile();
295 if (not keepOpen) pFileDesc->CloseFile();
298 HLTError("can not open file %s", pFileDesc->GetName());
305 HLTDebug("event %p size %d", pEventDesc, eventSize);
306 if (fMaxSize<eventSize) fMaxSize=eventSize;
308 HLTError("can not get event descriptor for TObjLink");
316 int AliHLTFilePublisher::DoDeinit()
318 // see header file for class documentation
324 int AliHLTFilePublisher::GetEvent( const AliHLTComponentEventData& /*evtData*/,
325 AliHLTComponentTriggerData& /*trigData*/,
326 AliHLTUInt8_t* outputPtr,
327 AliHLTUInt32_t& size,
328 AliHLTComponentBlockDataList& outputBlocks )
330 // see header file for class documentation
332 TObjLink *lnk=fpCurrent;
333 if (lnk==NULL) lnk=fEvents.FirstLink();
336 EventFiles* pEventDesc=dynamic_cast<EventFiles*>(lnk->GetObject());
338 HLTDebug("publishing files for event %p", pEventDesc);
339 TList& files=*pEventDesc; // type conversion operator defined
340 TObjLink *flnk=files.FirstLink();
342 while (flnk && iResult>=0) {
343 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
344 if (not fOpenFilesAtStart) pFileDesc->OpenFile();
346 if (pFileDesc && (pFile=*pFileDesc)!=NULL) {
347 int iCopy=pFile->GetSize();
349 if (iCopy+iTotalSize<=(int)size) {
350 if (pFile->ReadBuffer((char*)outputPtr+iTotalSize, iCopy)!=0) {
351 // ReadBuffer returns 1 in case of failure and 0 in case of success
354 AliHLTComponentBlockData bd;
357 bd.fOffset=iTotalSize;
359 bd.fDataType=*pFileDesc; // type conversion operator defined
360 bd.fSpecification=*pFileDesc; // type conversion operator defined
361 outputBlocks.push_back(bd);
364 // msg.Form("get file %s ", pFile->GetName());
365 // msg+="data type \'%s\'";
366 // PrintDataTypeContent(bd.fDataType, msg.Data());
369 // output buffer too small, update GetOutputDataSize for the second trial
373 if (not fOpenFilesAtStart) pFileDesc->CloseFile();
375 HLTError("no file available");
382 HLTError("can not get event descriptor from list link");
388 if (iResult>=0 && fpCurrent) fpCurrent=fpCurrent->Next();
393 // AliHLTComponentDataType AliHLTFilePublisher::GetCurrentDataType() const
395 // return kAliHLTVoidDataType;
398 // AliHLTUInt32_t AliHLTFilePublisher::GetCurrentSpecification() const
403 AliHLTFilePublisher::FileDesc::FileDesc(const char* name, AliHLTComponentDataType dt, AliHLTUInt32_t spec)
411 // see header file for class documentation
413 // refer to README to build package
415 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
418 AliHLTFilePublisher::FileDesc::~FileDesc()
420 // see header file for class documentation
424 void AliHLTFilePublisher::FileDesc::CloseFile()
426 // see header file for class documentation
429 // Unfortunately had to use AliLog mechanisms rather that AliHLTLogging because
430 // AliHLTFilePublisher::FileDesc does not derive from AliHLTLogging. It would
431 // become a rather heavy class if it did.
433 AliDebugGeneral("AliHLTFilePublisher::FileDesc",
434 2, Form("File %s has been closed.", fName.Data())
442 int AliHLTFilePublisher::FileDesc::OpenFile()
444 // see header file for class documentation
446 TString fullFN= fName + "?filetype=raw";
447 fpInstance = new TFile(fullFN);
449 if (fpInstance->IsZombie()==0) {
450 iResult=fpInstance->GetSize();
452 AliDebugGeneral("AliHLTFilePublisher::FileDesc",
453 2, Form("File %s has been opened.", fName.Data())