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