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. */
28 #include "AliHLTFilePublisher.h"
30 #include <TObjString.h>
34 /** the global object for component registration */
35 AliHLTFilePublisher gAliHLTFilePublisher;
37 /** ROOT macro for the implementation of ROOT specific class methods */
38 ClassImp(AliHLTFilePublisher)
40 AliHLTFilePublisher::AliHLTFilePublisher()
46 fOpenFilesAtStart(false)
48 // see header file for class documentation
50 // refer to README to build package
52 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
54 // make the lists owners of their objects in order to automatically
55 // de-allocate the objects
59 AliHLTFilePublisher::~AliHLTFilePublisher()
61 // see header file for class documentation
63 // file list and file name list are owner of their objects and
64 // delete all the objects
67 const char* AliHLTFilePublisher::GetComponentID()
69 // see header file for class documentation
70 return "FilePublisher";
73 AliHLTComponentDataType AliHLTFilePublisher::GetOutputDataType()
75 // see header file for class documentation
76 return kAliHLTVoidDataType;
79 void AliHLTFilePublisher::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
81 // see header file for class documentation
86 AliHLTComponent* AliHLTFilePublisher::Spawn()
88 // see header file for class documentation
89 return new AliHLTFilePublisher;
92 int AliHLTFilePublisher::DoInit( int argc, const char** argv )
94 // see header file for class documentation
96 //HLTDebug("%d %s", argc, argv[0]);
101 int bHaveSpecification=0;
102 fOpenFilesAtStart = false;
103 AliHLTComponentDataType currDataType=kAliHLTVoidDataType;
104 AliHLTUInt32_t currSpecification=kAliHLTVoidDataSpec;
105 EventFiles* pCurrEvent=NULL;
106 for (int i=0; i<argc && iResult>=0; i++) {
108 if (argument.IsNull()) continue;
111 if (argument.CompareTo("-datafile")==0) {
112 if ((bMissingParam=(++i>=argc))) break;
113 if (!bHaveDatatype) {
114 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");
116 FileDesc* pDesc=new FileDesc(argv[i], currDataType, currSpecification);
118 iResult=InsertFile(pCurrEvent, pDesc);
124 } else if (argument.CompareTo("-datafilelist")==0) {
125 if ((bMissingParam=(++i>=argc))) break;
126 HLTWarning("-datafilelist option not yet implemented");
129 } else if (argument.CompareTo("-datatype")==0) {
130 if ((bMissingParam=(++i>=argc))) break;
131 memcpy(&currDataType.fID, argv[i], TMath::Min(kAliHLTComponentDataTypefIDsize, (Int_t)strlen(argv[i])));
132 if ((bMissingParam=(++i>=argc))) break;
133 memcpy(&currDataType.fOrigin, argv[i], TMath::Min(kAliHLTComponentDataTypefOriginSize, (Int_t)strlen(argv[i])));
134 if (bHaveDatatype==0 && pCurrEvent && iResult>=0) {
135 // this is a workaround to make old tutorials working which contain
136 // the arguments in the wrong sequence
137 TList& files=*pCurrEvent; // type conversion operator defined
138 TObjLink *flnk=files.FirstLink();
140 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
142 pFileDesc->SetDataType(currDataType);
150 } else if (argument.CompareTo("-dataspec")==0) {
151 if ((bMissingParam=(++i>=argc))) break;
152 TString parameter(argv[i]);
153 parameter.Remove(TString::kLeading, ' '); // remove all blanks
154 if (parameter.IsDigit()) {
155 currSpecification=(AliHLTUInt32_t)parameter.Atoi();
156 } else if (parameter.BeginsWith("0x") &&
157 parameter.Replace(0,2,"",0).IsHex()) {
158 sscanf(parameter.Data(),"%x", &currSpecification);
160 HLTError("wrong parameter for argument %s, number expected", argument.Data());
163 if (bHaveSpecification==0 && pCurrEvent && iResult>=0) {
164 // this is a workaround to make old tutorials working which contain
165 // the arguments in the wrong sequence
166 TList& files=*pCurrEvent; // type conversion operator defined
167 TObjLink *flnk=files.FirstLink();
169 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
171 pFileDesc->SetSpecification(currSpecification);
176 bHaveSpecification=1;
178 } else if (argument.CompareTo("-nextevent")==0) {
179 InsertEvent(pCurrEvent);
180 } else if (argument.CompareTo("-open_files_at_start")==0) {
181 fOpenFilesAtStart = true;
183 if ((iResult=ScanArgument(argc-i, &argv[i]))==-EINVAL) {
184 HLTError("unknown argument %s", argument.Data());
186 } else if (iResult==-EPROTO) {
189 } else if (iResult>=0) {
195 InsertEvent(pCurrEvent);
198 HLTError("missing parameter for argument %s", argument.Data());
201 if (fEvents.GetSize()==0) {
202 HLTError("the publisher needs at least one file argument");
205 if (iResult>=0) iResult=OpenFiles(fOpenFilesAtStart);
212 int AliHLTFilePublisher::InsertFile(EventFiles* &pCurrEvent, FileDesc* pDesc)
216 if (pCurrEvent==NULL) {
217 pCurrEvent=new EventFiles;
218 if (pCurrEvent!=NULL) {
223 if (iResult>=0 && pCurrEvent!=NULL) {
224 HLTDebug("Insert file %p to event %p", pDesc, pCurrEvent);
225 pCurrEvent->Add(pDesc);
233 int AliHLTFilePublisher::InsertEvent(EventFiles* &pEvent)
237 HLTDebug("Inserted event %p", pEvent);
244 int AliHLTFilePublisher::ScanArgument(int argc, const char** argv)
246 // see header file for class documentation
248 // there are no other arguments than the standard ones
249 if (argc==0 && argv==NULL) {
250 // this is just to get rid of the warning "unused parameter"
255 int AliHLTFilePublisher::OpenFiles(bool keepOpen)
257 // see header file for class documentation
259 TObjLink *lnk=fEvents.FirstLink();
260 while (lnk && iResult>=0) {
261 EventFiles* pEventDesc=dynamic_cast<EventFiles*>(lnk->GetObject());
263 HLTDebug("open files for event %p", pEventDesc);
264 TList& files=*pEventDesc; // type conversion operator defined
265 TObjLink *flnk=files.FirstLink();
267 while (flnk && iResult>=0) {
268 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
270 int size=pFileDesc->OpenFile();
271 if (not keepOpen) pFileDesc->CloseFile();
274 HLTError("can not open file %s", pFileDesc->GetName());
281 HLTDebug("event %p size %d", pEventDesc, eventSize);
282 if (fMaxSize<eventSize) fMaxSize=eventSize;
284 HLTError("can not get event descriptor for TObjLink");
292 int AliHLTFilePublisher::DoDeinit()
294 // see header file for class documentation
300 int AliHLTFilePublisher::GetEvent( const AliHLTComponentEventData& /*evtData*/,
301 AliHLTComponentTriggerData& /*trigData*/,
302 AliHLTUInt8_t* outputPtr,
303 AliHLTUInt32_t& size,
304 vector<AliHLTComponentBlockData>& outputBlocks )
307 TObjLink *lnk=fpCurrent;
308 if (lnk==NULL) lnk=fEvents.FirstLink();
311 EventFiles* pEventDesc=dynamic_cast<EventFiles*>(lnk->GetObject());
313 HLTDebug("publishing files for event %p", pEventDesc);
314 TList& files=*pEventDesc; // type conversion operator defined
315 TObjLink *flnk=files.FirstLink();
317 while (flnk && iResult>=0) {
318 FileDesc* pFileDesc=dynamic_cast<FileDesc*>(flnk->GetObject());
319 if (not fOpenFilesAtStart) pFileDesc->OpenFile();
321 if (pFileDesc && (pFile=*pFileDesc)!=NULL) {
322 int iCopy=pFile->GetSize();
324 if (iCopy+iTotalSize<=(int)size) {
325 if (pFile->ReadBuffer((char*)outputPtr+iTotalSize, iCopy)!=0) {
326 // ReadBuffer returns 1 in case of failure and 0 in case of success
329 AliHLTComponentBlockData bd;
332 bd.fOffset=iTotalSize;
334 bd.fDataType=*pFileDesc; // type conversion operator defined
335 bd.fSpecification=*pFileDesc; // type conversion operator defined
336 outputBlocks.push_back(bd);
340 // output buffer too small, update GetOutputDataSize for the second trial
344 if (not fOpenFilesAtStart) pFileDesc->CloseFile();
346 HLTError("no file available");
353 HLTError("can not get event descriptor from list link");
359 if (iResult>=0 && fpCurrent) fpCurrent=fpCurrent->Next();
364 // AliHLTComponentDataType AliHLTFilePublisher::GetCurrentDataType() const
366 // return kAliHLTVoidDataType;
369 // AliHLTUInt32_t AliHLTFilePublisher::GetCurrentSpecification() const
374 AliHLTFilePublisher::FileDesc::FileDesc(const char* name, AliHLTComponentDataType dt, AliHLTUInt32_t spec)
384 AliHLTFilePublisher::FileDesc::~FileDesc()
389 void AliHLTFilePublisher::FileDesc::CloseFile()
393 // Unfortunately had to use AliLog mechanisms rather that AliHLTLogging because
394 // AliHLTFilePublisher::FileDesc does not derive from AliHLTLogging. It would
395 // become a rather heavy class if it did.
397 AliDebugGeneral("AliHLTFilePublisher::FileDesc",
398 2, Form("File %s has been closed.", fName.Data())
406 int AliHLTFilePublisher::FileDesc::OpenFile()
409 TString fullFN= fName + "?filetype=raw";
410 fpInstance = new TFile(fullFN);
412 if (fpInstance->IsZombie()==0) {
413 iResult=fpInstance->GetSize();
415 AliDebugGeneral("AliHLTFilePublisher::FileDesc",
416 2, Form("File %s has been opened.", fName.Data())