BlockFilter component added; minor corrections
[u/mrichter/AliRoot.git] / HLT / BASE / util / AliHLTFileWriter.cxx
1 // $Id$
2
3 /**************************************************************************
4  * This file is property of and copyright by the ALICE HLT Project        * 
5  * ALICE Experiment at CERN, All rights reserved.                         *
6  *                                                                        *
7  * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8  *                  for The ALICE HLT Project.                            *
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   AliHLTFileWriter.cxx
20     @author Matthias Richter
21     @date   
22     @brief  HLT file writer component implementation. */
23
24 #if __GNUC__>= 3
25 using namespace std;
26 #endif
27
28 #include "AliHLTFileWriter.h"
29 #include <TObjArray.h>
30 #include <TObjString.h>
31 #include <TSystem.h>
32 //#include <TMath.h>
33 //#include <TFile.h>
34
35 /** ROOT macro for the implementation of ROOT specific class methods */
36 ClassImp(AliHLTFileWriter)
37
38 AliHLTFileWriter::AliHLTFileWriter()
39   :
40   AliHLTDataSink(),
41   fBaseName(""),
42   fExtension(""),
43   fDirectory(""),
44   fSubDirFormat(""),
45   fIdFormat(""),
46   fSpecFormat(""),
47   fBlcknoFormat(""),
48   fCurrentFileName(""),
49   fMode(0)
50 {
51   // see header file for class documentation
52   // or
53   // refer to README to build package
54   // or
55   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
56 }
57
58 AliHLTFileWriter::~AliHLTFileWriter()
59 {
60   // see header file for class documentation
61
62   // file list and file name list are owner of their objects and
63   // delete all the objects
64 }
65
66 const char* AliHLTFileWriter::GetComponentID()
67 {
68   // see header file for class documentation
69   return "FileWriter";
70 }
71
72 void AliHLTFileWriter::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
73 {
74   // see header file for class documentation
75   list.clear();
76   list.push_back(kAliHLTAnyDataType);
77 }
78
79 AliHLTComponent* AliHLTFileWriter::Spawn()
80 {
81   // see header file for class documentation
82   return new AliHLTFileWriter;
83 }
84
85 int AliHLTFileWriter::DoInit( int argc, const char** argv )
86 {
87   // see header file for class documentation
88   int iResult=0;
89   TString argument="";
90   int bMissingParam=0;
91   for (int i=0; i<argc && iResult>=0; i++) {
92     argument=argv[i];
93     if (argument.IsNull()) continue;
94
95     // -basename
96     if (argument.CompareTo("-datafile")==0) {
97       if ((bMissingParam=(++i>=argc))) break;
98       fBaseName=argv[i];
99       TObjArray* pTokens=fBaseName.Tokenize(".");
100       if (pTokens) {
101         int iEntries=pTokens->GetEntries();
102         if (iEntries>1) {
103           int i=0;
104           fBaseName=((TObjString*)pTokens->At(i++))->GetString();
105           while (i<iEntries-1) {
106             fBaseName+="." + ((TObjString*)pTokens->At(i++))->GetString();
107           }
108           fExtension=((TObjString*)pTokens->At(i))->GetString();
109         }
110         delete pTokens;
111       }
112
113       // -directory
114     } else if (argument.CompareTo("-directory")==0) {
115       if ((bMissingParam=(++i>=argc))) break;
116       fDirectory=argv[i];
117
118       // -subdir
119     } else if (argument.BeginsWith("-subdir")) {
120       argument.ReplaceAll("-subdir", "");
121       if (argument.BeginsWith("=")) {
122         fSubDirFormat=argument.Replace(0,1,"");
123       } else {
124         fSubDirFormat="event%03d";
125       }
126
127       // -idfmt
128     } else if (argument.BeginsWith("-idfmt")) {
129       argument.ReplaceAll("-idfmt", "");
130       if (argument.BeginsWith("=")) {
131         fIdFormat=argument.Replace(0,1,"");
132       }
133
134       // -specfmt
135     } else if (argument.BeginsWith("-specfmt")) {
136       argument.ReplaceAll("-specfmt", "");
137       if (argument.BeginsWith("=")) {
138         fSpecFormat=argument.Replace(0,1,"");
139       } else {
140         fSpecFormat="_0x%08x";
141       }
142
143       // -blcknofmt
144     } else if (argument.BeginsWith("-blcknofmt")) {
145       argument.ReplaceAll("-blcknofmt", "");
146       if (argument.BeginsWith("=")) {
147         fBlcknoFormat=argument.Replace(0,1,"");
148       } else {
149         fBlcknoFormat="_0x%02x";
150       }
151
152       // -enumeration
153     } else if (argument.CompareTo("-enumerate")==0) {
154       SetMode(kEnumerate);
155
156       // -concatenate-blocks
157     } else if (argument.CompareTo("-concatenate-blocks")==0) {
158       SetMode(kConcatenateBlocks);
159
160       // -concatenate-events
161     } else if (argument.CompareTo("-concatenate-events")==0) {
162       SetMode(kConcatenateEvents);
163
164     } else {
165       if ((iResult=ScanArgument(argc-i, &argv[i]))==-EINVAL) {
166         HLTError("unknown argument %s", argument.Data());
167         break;
168       } else if (iResult==-EPROTO) {
169         bMissingParam=1;
170         break;
171       } else if (iResult>=0) {
172         i+=iResult;
173         iResult=0;
174       }
175     }
176   }
177   if (bMissingParam) {
178     HLTError("missing parameter for argument %s", argument.Data());
179     iResult=-EINVAL;
180   }
181   if (iResult>=0) {
182     if (fIdFormat.IsNull() && fSubDirFormat.IsNull()) {
183       // set the default format string for the id if it is not set and
184       // no sub dirs set (the sub dir than contains the id)
185       fIdFormat="_0x%08x";
186     }
187     iResult=InitWriter();
188   }
189
190   return iResult;
191 }
192
193 int AliHLTFileWriter::InitWriter()
194 {
195   // see header file for class documentation
196   
197   // fCurrentFileName is used in dump event, just touched her to avoid
198   // coding convention violation RC11. The function can not be declared
199   // const since it is just the default implementation, overloaded
200   // virtual function might not be const
201   fCurrentFileName="";
202   return 0; // note: this doesn't mean 'error'
203 }
204
205 int AliHLTFileWriter::ScanArgument(int argc, const char** argv)
206 {
207   // see header file for class documentation
208
209   // there are no other arguments than the standard ones
210   if (argc==0 && argv==NULL) {
211     // this is just to get rid of the warning "unused parameter"
212   }
213   // fCurrentFileName is used in dump event, just touched her to avoid
214   // coding convention violation RC11. The function can not be declared
215   // const since it is just the default implementation, overloaded
216   // virtual function might not be const
217   fCurrentFileName="";
218   return -EINVAL;
219 }
220
221 int AliHLTFileWriter::DoDeinit()
222 {
223   // see header file for class documentation
224   int iResult=CloseWriter();
225   ClearMode(kEnumerate);
226   return iResult;
227 }
228
229 int AliHLTFileWriter::CloseWriter()
230 {
231   // see header file for class documentation
232
233   // fCurrentFileName is used in dump event, just touched her to avoid
234   // coding convention violation RC11. The function can not be declared
235   // const since it is just the default implementation, overloaded
236   // virtual function might not be const
237   fCurrentFileName="";
238   return 0; // note: this doesn't mean 'error'
239 }
240
241 int AliHLTFileWriter::DumpEvent( const AliHLTComponentEventData& evtData,
242                          const AliHLTComponentBlockData* blocks, 
243                          AliHLTComponentTriggerData& trigData )
244 {
245   // see header file for class documentation
246   int iResult=0;
247   if (CheckMode(kConcatenateEvents)==0) {
248     // reset the current file name in order to open a new file
249     // for the first block. If events are concatenated, the current
250     // file name stays in order to be opended in append mode.
251     fCurrentFileName="";
252   }
253   for (int n=0; n<(int)evtData.fBlockCnt; n++ ) {
254     //HLTDebug("block %d out of %d", n, evtData.fBlockCnt);
255     TString filename;
256     //HLTDebug("dataspec 0x%x", blocks[n].fSpecification);
257     iResult=BuildFileName(evtData.fEventID, n, blocks[n].fDataType, blocks[n].fSpecification, filename);
258     ios::openmode filemode=(ios::openmode)0;
259     if (fCurrentFileName.CompareTo(filename)==0) {
260       // append to the file
261       filemode=ios::app;
262     } else {
263       // store the file for the next block
264       fCurrentFileName=filename;
265     }
266     if (iResult>=0) {
267       ofstream dump(filename.Data(), filemode);
268       if (dump.good()) {
269         dump.write((static_cast<const char*>(blocks[n].fPtr)), blocks[n].fSize);
270         HLTDebug("wrote %d byte(s) to file %s", blocks[n].fSize, filename.Data());
271       } else {
272         HLTError("can not open file %s for writing", filename.Data());
273         iResult=-EBADF;
274       }
275       dump.close();
276     }
277   }
278   if (trigData.fStructSize==0) {
279     // this is just to get rid of the warning "unused parameter"
280   }
281   return iResult;
282 }
283
284 int AliHLTFileWriter::BuildFileName(const AliHLTEventID_t eventID, const int blockID,
285                                     const AliHLTComponentDataType& dataType,
286                                     const AliHLTUInt32_t specification,
287                                     TString& filename)
288 {
289   // see header file for class documentation
290   int iResult=0;
291   //HLTDebug("build file name for event %d block %d", eventID, blockID);
292   filename="";
293   if (!fDirectory.IsNull()) {
294     filename+=fDirectory;
295     if (!filename.EndsWith("/"))
296       filename+="/";
297   }
298   if (!fSubDirFormat.IsNull()) {
299     filename+=Form(fSubDirFormat, eventID);
300     if (!filename.EndsWith("/"))
301       filename+="/";
302   }
303   if (filename.EndsWith("/")) {
304     gSystem->mkdir(filename);
305   }
306   if (!fBaseName.IsNull())
307     filename+=fBaseName;
308   else
309     filename+="event";
310   if (!CheckMode(kConcatenateEvents)) {
311     if (!CheckMode(kEnumerate)) {
312       if (eventID!=kAliHLTVoidEventID && !fIdFormat.IsNull()) {
313         filename+=Form(fIdFormat, eventID);
314       }
315     } else {
316       filename+=Form("_%d", GetEventCount());
317     }
318   }
319   if (blockID>=0 && !CheckMode(kConcatenateBlocks)) {
320     if (!fBlcknoFormat.IsNull())
321       filename+=Form(fBlcknoFormat, blockID);
322     if (dataType!=kAliHLTVoidDataType) {
323       filename+="_";
324       filename+=AliHLTComponent::DataType2Text(dataType).data();
325     }
326     if (!fSpecFormat.IsNull())
327       filename+=Form(fSpecFormat, specification);
328   }
329   if (!fExtension.IsNull())
330     filename+="." + fExtension;
331   filename.ReplaceAll(" ", "");
332   return iResult;
333 }
334
335 int AliHLTFileWriter::SetMode(Short_t mode) 
336 {
337   // see header file for class documentation
338   fMode|=mode;
339   //HLTDebug("mode set to 0x%x", fMode);
340   return fMode;
341 }
342
343 int AliHLTFileWriter::ClearMode(Short_t mode)
344 {
345   // see header file for class documentation
346   fMode&=~mode;
347   //HLTDebug("mode set to 0x%x", fMode);
348   return fMode;
349 }
350
351 int AliHLTFileWriter::CheckMode(Short_t mode) const
352 {
353   // see header file for class documentation
354
355   //HLTDebug("check mode 0x%x for flag 0x%x: %d", fMode, mode, (fMode&mode)!=0);
356   return (fMode&mode)!=0;
357 }