]>
Commit | Line | Data |
---|---|---|
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 | |
25 | using namespace std; | |
26 | #endif | |
27 | ||
28 | #include "AliHLTFileWriter.h" | |
4b31e06b | 29 | #include "AliHLTBlockDataCollection.h" |
e74abd18 | 30 | #include <TObjArray.h> |
31 | #include <TObjString.h> | |
5ab95e9a | 32 | #include <TSystem.h> |
5df0cbb9 | 33 | //#include <TMath.h> |
34 | //#include <TFile.h> | |
4b31e06b | 35 | #include <cassert> |
e74abd18 | 36 | |
e74abd18 | 37 | /** ROOT macro for the implementation of ROOT specific class methods */ |
38 | ClassImp(AliHLTFileWriter) | |
39 | ||
40 | AliHLTFileWriter::AliHLTFileWriter() | |
41 | : | |
42 | AliHLTDataSink(), | |
4b31e06b | 43 | fpBlockDataCollection(NULL), |
e74abd18 | 44 | fBaseName(""), |
45 | fExtension(""), | |
46 | fDirectory(""), | |
5ab95e9a | 47 | fSubDirFormat(""), |
6daf06e2 | 48 | fIdFormat("_0x%08x"), |
5ab95e9a | 49 | fSpecFormat(""), |
652cf9d2 | 50 | fBlcknoFormat("_0x%02x"), |
e74abd18 | 51 | fCurrentFileName(""), |
52 | fMode(0) | |
4b31e06b | 53 | , fpBurstBuffer(NULL) |
54 | , fBurstBufferSize(0) | |
55 | , fBurstBlocks() | |
56 | , fBurstBlockEvents() | |
a9c4e244 | 57 | , fPublisherConfName() |
58 | , fPublisherConfEvent(-1) | |
e74abd18 | 59 | { |
60 | // see header file for class documentation | |
61 | // or | |
62 | // refer to README to build package | |
63 | // or | |
64 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
65 | } | |
66 | ||
e74abd18 | 67 | AliHLTFileWriter::~AliHLTFileWriter() |
68 | { | |
69 | // see header file for class documentation | |
70 | ||
71 | // file list and file name list are owner of their objects and | |
72 | // delete all the objects | |
73 | } | |
74 | ||
4b31e06b | 75 | int AliHLTFileWriter::SetDefaults() |
76 | { | |
77 | // see header file for class documentation | |
78 | fBaseName=""; | |
79 | fExtension=""; | |
80 | fDirectory=""; | |
81 | fSubDirFormat=""; | |
82 | fIdFormat="_0x%08x"; | |
83 | fSpecFormat=""; | |
84 | fBlcknoFormat="_0x%02x"; | |
85 | fCurrentFileName=""; | |
86 | fMode=0; | |
87 | fpBurstBuffer=NULL; | |
88 | fBurstBufferSize=0; | |
89 | fBurstBlocks.clear(); | |
90 | fBurstBlockEvents.clear(); | |
a9c4e244 | 91 | fPublisherConfEvent=-1; |
4b31e06b | 92 | return 0; |
93 | } | |
94 | ||
e74abd18 | 95 | const char* AliHLTFileWriter::GetComponentID() |
96 | { | |
97 | // see header file for class documentation | |
98 | return "FileWriter"; | |
99 | } | |
100 | ||
101 | void AliHLTFileWriter::GetInputDataTypes( vector<AliHLTComponentDataType>& list) | |
102 | { | |
103 | // see header file for class documentation | |
104 | list.clear(); | |
6daf06e2 | 105 | list.push_back(kAliHLTAllDataTypes); |
e74abd18 | 106 | } |
107 | ||
108 | AliHLTComponent* AliHLTFileWriter::Spawn() | |
109 | { | |
110 | // see header file for class documentation | |
111 | return new AliHLTFileWriter; | |
112 | } | |
113 | ||
114 | int AliHLTFileWriter::DoInit( int argc, const char** argv ) | |
115 | { | |
116 | // see header file for class documentation | |
117 | int iResult=0; | |
4b31e06b | 118 | fpBlockDataCollection=new AliHLTBlockDataCollection; |
e74abd18 | 119 | TString argument=""; |
120 | int bMissingParam=0; | |
4b31e06b | 121 | char* cpErr=NULL; |
122 | int i=0; | |
123 | for (; i<argc && iResult>=0; i++) { | |
124 | cpErr=NULL; | |
e74abd18 | 125 | argument=argv[i]; |
126 | if (argument.IsNull()) continue; | |
127 | ||
128 | // -basename | |
129 | if (argument.CompareTo("-datafile")==0) { | |
130 | if ((bMissingParam=(++i>=argc))) break; | |
131 | fBaseName=argv[i]; | |
132 | TObjArray* pTokens=fBaseName.Tokenize("."); | |
133 | if (pTokens) { | |
77fd699f | 134 | int iEntries=pTokens->GetEntriesFast(); |
e74abd18 | 135 | if (iEntries>1) { |
f7561f8d | 136 | int n=0; |
137 | fBaseName=((TObjString*)pTokens->At(n++))->GetString(); | |
138 | while (n<iEntries-1) { | |
139 | fBaseName+="." + ((TObjString*)pTokens->At(n++))->GetString(); | |
e74abd18 | 140 | } |
f7561f8d | 141 | fExtension=((TObjString*)pTokens->At(n))->GetString(); |
e74abd18 | 142 | } |
143 | delete pTokens; | |
144 | } | |
145 | ||
146 | // -directory | |
147 | } else if (argument.CompareTo("-directory")==0) { | |
148 | if ((bMissingParam=(++i>=argc))) break; | |
149 | fDirectory=argv[i]; | |
150 | ||
5ab95e9a | 151 | // -subdir |
152 | } else if (argument.BeginsWith("-subdir")) { | |
153 | argument.ReplaceAll("-subdir", ""); | |
154 | if (argument.BeginsWith("=")) { | |
155 | fSubDirFormat=argument.Replace(0,1,""); | |
2cb9ea42 | 156 | if (strchr(fSubDirFormat.Data(), '%')==NULL) { |
157 | fSubDirFormat+="%lu"; | |
158 | } | |
5ab95e9a | 159 | } else { |
488eca05 | 160 | fSubDirFormat="event%03lu"; |
5ab95e9a | 161 | } |
6daf06e2 | 162 | // no additional eventno in the filename unless set again |
163 | // the sub dir contains the id | |
164 | fIdFormat=""; | |
5ab95e9a | 165 | |
166 | // -idfmt | |
167 | } else if (argument.BeginsWith("-idfmt")) { | |
168 | argument.ReplaceAll("-idfmt", ""); | |
169 | if (argument.BeginsWith("=")) { | |
170 | fIdFormat=argument.Replace(0,1,""); | |
171 | } | |
172 | ||
173 | // -specfmt | |
174 | } else if (argument.BeginsWith("-specfmt")) { | |
175 | argument.ReplaceAll("-specfmt", ""); | |
176 | if (argument.BeginsWith("=")) { | |
177 | fSpecFormat=argument.Replace(0,1,""); | |
178 | } else { | |
179 | fSpecFormat="_0x%08x"; | |
180 | } | |
181 | ||
6daf06e2 | 182 | // -blocknofmt |
183 | } else if (argument.BeginsWith("-blcknofmt") || | |
184 | argument.BeginsWith("-blocknofmt")) { | |
185 | // for the sake of backward compatibility we consider also the | |
186 | // old argument with typo for a while | |
5ab95e9a | 187 | argument.ReplaceAll("-blcknofmt", ""); |
6daf06e2 | 188 | argument.ReplaceAll("-blocknofmt", ""); |
5ab95e9a | 189 | if (argument.BeginsWith("=")) { |
190 | fBlcknoFormat=argument.Replace(0,1,""); | |
191 | } else { | |
192 | fBlcknoFormat="_0x%02x"; | |
193 | } | |
194 | ||
e74abd18 | 195 | // -enumeration |
196 | } else if (argument.CompareTo("-enumerate")==0) { | |
197 | SetMode(kEnumerate); | |
198 | ||
199 | // -concatenate-blocks | |
200 | } else if (argument.CompareTo("-concatenate-blocks")==0) { | |
201 | SetMode(kConcatenateBlocks); | |
202 | ||
203 | // -concatenate-events | |
204 | } else if (argument.CompareTo("-concatenate-events")==0) { | |
205 | SetMode(kConcatenateEvents); | |
206 | ||
a9c4e244 | 207 | // -publisher-conf |
208 | } else if (argument.CompareTo("-publisher-conf")==0) { | |
209 | if ((bMissingParam=(++i>=argc))) break; | |
210 | fPublisherConfName=argv[i]; | |
211 | ||
6b7f77cf | 212 | // -write-all-events |
213 | } else if (argument.CompareTo("-write-all-events")==0) { | |
214 | SetMode(kWriteAllEvents); | |
215 | ||
216 | // -write-all-blocks | |
217 | } else if (argument.CompareTo("-write-all-blocks")==0) { | |
218 | SetMode(kWriteAllBlocks); | |
219 | ||
220 | // -write-all | |
221 | } else if (argument.CompareTo("-write-all")==0) { | |
222 | SetMode(kWriteAllEvents); | |
223 | SetMode(kWriteAllBlocks); | |
224 | ||
4b31e06b | 225 | // -burst-buffer |
226 | } else if (argument.CompareTo("-burst-buffer")==0) { | |
227 | if ((bMissingParam=(++i>=argc))) break; | |
228 | fBurstBufferSize = strtoul( argv[i], &cpErr ,0); | |
229 | if ( *cpErr ) break; | |
230 | ||
2cb9ea42 | 231 | // -skip-datatype |
232 | } else if(argument.CompareTo("-skip-datatype")==0){ | |
233 | SetMode(kSkipDataType); | |
234 | ||
4b31e06b | 235 | // check for selection arguments (AliHLTBlockDataCollection) |
236 | } else if (fpBlockDataCollection && | |
237 | (iResult=fpBlockDataCollection->ScanArgument(argc-i, &argv[i]))>0) { | |
238 | i+=iResult-1; | |
239 | iResult=0; | |
e74abd18 | 240 | } else { |
241 | if ((iResult=ScanArgument(argc-i, &argv[i]))==-EINVAL) { | |
242 | HLTError("unknown argument %s", argument.Data()); | |
243 | break; | |
244 | } else if (iResult==-EPROTO) { | |
245 | bMissingParam=1; | |
246 | break; | |
13ce8aae | 247 | } else if (iResult>0) { |
248 | i+=iResult-1; | |
e74abd18 | 249 | iResult=0; |
250 | } | |
251 | } | |
252 | } | |
4b31e06b | 253 | |
254 | if (cpErr && *cpErr) { | |
255 | HLTError("Cannot convert specifier '%s' for argument '%s'", argv[i], argument.Data()); | |
256 | iResult=-EINVAL; | |
257 | } else if (bMissingParam) { | |
e74abd18 | 258 | HLTError("missing parameter for argument %s", argument.Data()); |
259 | iResult=-EINVAL; | |
260 | } | |
4b31e06b | 261 | if (fpBlockDataCollection && |
262 | (iResult<0 || fpBlockDataCollection->IsEmpty())) { | |
263 | delete fpBlockDataCollection; | |
264 | fpBlockDataCollection=NULL; | |
265 | } | |
266 | if (iResult>=0 && fBurstBufferSize>0) { | |
267 | if (!CheckMode(kConcatenateBlocks) || !CheckMode(kConcatenateEvents)) { | |
268 | HLTError("burst write currently only supported for mode kConcatenateBlocks AND kConcatenateEvents"); | |
269 | iResult=-EINVAL; | |
270 | } else { | |
271 | fpBurstBuffer=new AliHLTUInt8_t[fBurstBufferSize]; | |
272 | if (!fpBurstBuffer) { | |
273 | iResult=-ENOMEM; | |
274 | fBurstBufferSize=0; | |
275 | } | |
276 | } | |
277 | } | |
278 | ||
a9c4e244 | 279 | if (!fPublisherConfName.IsNull()) { |
280 | if (CheckMode(kConcatenateBlocks) || CheckMode(kConcatenateEvents)) { | |
281 | fPublisherConfName=""; | |
282 | HLTWarning("option 'concatenate blocks/events' collides with writing of FilePublisher configuration, ignoring option '-publisher-conf'"); | |
283 | } | |
284 | } | |
285 | ||
e74abd18 | 286 | if (iResult>=0) { |
287 | iResult=InitWriter(); | |
07cd8230 | 288 | if (!fDirectory.IsNull()) { |
289 | gSystem->mkdir(fDirectory); | |
290 | } | |
e74abd18 | 291 | } |
292 | ||
293 | return iResult; | |
294 | } | |
295 | ||
296 | int AliHLTFileWriter::InitWriter() | |
297 | { | |
298 | // see header file for class documentation | |
5df0cbb9 | 299 | |
300 | // fCurrentFileName is used in dump event, just touched her to avoid | |
301 | // coding convention violation RC11. The function can not be declared | |
302 | // const since it is just the default implementation, overloaded | |
303 | // virtual function might not be const | |
304 | fCurrentFileName=""; | |
e74abd18 | 305 | return 0; // note: this doesn't mean 'error' |
306 | } | |
307 | ||
6daf06e2 | 308 | int AliHLTFileWriter::ScanArgument(int /*argc*/, const char** /*argv*/) |
e74abd18 | 309 | { |
310 | // see header file for class documentation | |
311 | ||
312 | // there are no other arguments than the standard ones | |
5df0cbb9 | 313 | // fCurrentFileName is used in dump event, just touched her to avoid |
314 | // coding convention violation RC11. The function can not be declared | |
315 | // const since it is just the default implementation, overloaded | |
316 | // virtual function might not be const | |
317 | fCurrentFileName=""; | |
e74abd18 | 318 | return -EINVAL; |
319 | } | |
320 | ||
321 | int AliHLTFileWriter::DoDeinit() | |
322 | { | |
323 | // see header file for class documentation | |
4b31e06b | 324 | int iResult=0; |
325 | if (fpBurstBuffer) { | |
326 | if ((iResult=BurstWrite())<0) { | |
327 | HLTError("failed BurstWrite"); | |
328 | } | |
329 | delete [] fpBurstBuffer; | |
330 | fpBurstBuffer=NULL; | |
331 | fBurstBufferSize=0; | |
332 | fBurstBlocks.clear(); | |
333 | fBurstBlockEvents.clear(); | |
334 | } | |
335 | ||
336 | iResult=CloseWriter(); | |
e74abd18 | 337 | ClearMode(kEnumerate); |
4b31e06b | 338 | |
339 | if (fpBlockDataCollection) delete fpBlockDataCollection; | |
340 | fpBlockDataCollection=NULL; | |
341 | ||
342 | SetDefaults(); | |
e74abd18 | 343 | return iResult; |
344 | } | |
345 | ||
346 | int AliHLTFileWriter::CloseWriter() | |
347 | { | |
348 | // see header file for class documentation | |
5df0cbb9 | 349 | |
350 | // fCurrentFileName is used in dump event, just touched her to avoid | |
351 | // coding convention violation RC11. The function can not be declared | |
352 | // const since it is just the default implementation, overloaded | |
353 | // virtual function might not be const | |
354 | fCurrentFileName=""; | |
6daf06e2 | 355 | return 0; |
e74abd18 | 356 | } |
357 | ||
358 | int AliHLTFileWriter::DumpEvent( const AliHLTComponentEventData& evtData, | |
fdb4ca9e | 359 | AliHLTComponentTriggerData& /*trigData*/ ) |
e74abd18 | 360 | { |
361 | // see header file for class documentation | |
362 | int iResult=0; | |
6b7f77cf | 363 | if (!IsDataEvent() && !CheckMode(kWriteAllEvents)) return 0; |
364 | ||
e74abd18 | 365 | if (CheckMode(kConcatenateEvents)==0) { |
366 | // reset the current file name in order to open a new file | |
367 | // for the first block. If events are concatenated, the current | |
368 | // file name stays in order to be opended in append mode. | |
369 | fCurrentFileName=""; | |
370 | } | |
bdc4041c | 371 | |
372 | if (!fPublisherConfName.IsNull() && fPublisherConfEvent>=0) { | |
373 | // write '-nextevent' command for all but the first event | |
374 | ofstream conf(fPublisherConfName.Data(), ios::app); | |
375 | if (conf.good()) { | |
376 | conf << "-nextevent " << endl; | |
377 | } | |
378 | conf.close(); | |
379 | } | |
380 | ||
fdb4ca9e | 381 | const AliHLTComponentBlockData* pDesc=NULL; |
382 | ||
383 | int blockno=0; | |
6daf06e2 | 384 | for (pDesc=GetFirstInputBlock(); pDesc!=NULL; pDesc=GetNextInputBlock(), blockno++) { |
4b31e06b | 385 | if (fpBlockDataCollection) { |
386 | if (!fpBlockDataCollection->IsSelected(*pDesc)) continue; | |
387 | } else if (pDesc->fDataType==(kAliHLTAnyDataType|kAliHLTDataOriginPrivate) && !CheckMode(kWriteAllBlocks)) | |
6b7f77cf | 388 | continue; |
fdb4ca9e | 389 | HLTDebug("block %d out of %d", blockno, evtData.fBlockCnt); |
4b31e06b | 390 | iResult=ScheduleBlock(blockno, evtData.fEventID, pDesc); |
e74abd18 | 391 | } |
e74abd18 | 392 | return iResult; |
393 | } | |
394 | ||
5ab95e9a | 395 | int AliHLTFileWriter::BuildFileName(const AliHLTEventID_t eventID, const int blockID, |
396 | const AliHLTComponentDataType& dataType, | |
397 | const AliHLTUInt32_t specification, | |
398 | TString& filename) | |
e74abd18 | 399 | { |
400 | // see header file for class documentation | |
401 | int iResult=0; | |
402 | //HLTDebug("build file name for event %d block %d", eventID, blockID); | |
403 | filename=""; | |
6b7f77cf | 404 | |
405 | AliHLTUInt32_t eventType=gkAliEventTypeUnknown; | |
6b7f77cf | 406 | |
e74abd18 | 407 | if (!fDirectory.IsNull()) { |
408 | filename+=fDirectory; | |
5ab95e9a | 409 | if (!filename.EndsWith("/")) |
e74abd18 | 410 | filename+="/"; |
411 | } | |
5ab95e9a | 412 | if (!fSubDirFormat.IsNull()) { |
413 | filename+=Form(fSubDirFormat, eventID); | |
414 | if (!filename.EndsWith("/")) | |
415 | filename+="/"; | |
416 | } | |
417 | if (filename.EndsWith("/")) { | |
418 | gSystem->mkdir(filename); | |
419 | } | |
488eca05 | 420 | |
421 | IsDataEvent(&eventType); | |
8516ea4c | 422 | if (CheckMode(kWriteAllEvents) && !CheckMode(kConcatenateEvents)) { |
423 | if (eventType==gkAliEventTypeStartOfRun) filename+="SOR_"; | |
424 | else if (eventType==gkAliEventTypeEndOfRun) filename+="EOR_"; | |
425 | } | |
488eca05 | 426 | |
e74abd18 | 427 | if (!fBaseName.IsNull()) |
428 | filename+=fBaseName; | |
429 | else | |
430 | filename+="event"; | |
431 | if (!CheckMode(kConcatenateEvents)) { | |
432 | if (!CheckMode(kEnumerate)) { | |
5ab95e9a | 433 | if (eventID!=kAliHLTVoidEventID && !fIdFormat.IsNull()) { |
434 | filename+=Form(fIdFormat, eventID); | |
e74abd18 | 435 | } |
436 | } else { | |
437 | filename+=Form("_%d", GetEventCount()); | |
438 | } | |
439 | } | |
440 | if (blockID>=0 && !CheckMode(kConcatenateBlocks)) { | |
5ab95e9a | 441 | if (!fBlcknoFormat.IsNull()) |
442 | filename+=Form(fBlcknoFormat, blockID); | |
2cb9ea42 | 443 | if (dataType!=kAliHLTVoidDataType && |
444 | !CheckMode(kSkipDataType)) { | |
e74abd18 | 445 | filename+="_"; |
446 | filename+=AliHLTComponent::DataType2Text(dataType).data(); | |
447 | } | |
5ab95e9a | 448 | if (!fSpecFormat.IsNull()) |
449 | filename+=Form(fSpecFormat, specification); | |
e74abd18 | 450 | } |
451 | if (!fExtension.IsNull()) | |
452 | filename+="." + fExtension; | |
453 | filename.ReplaceAll(" ", ""); | |
454 | return iResult; | |
455 | } | |
456 | ||
457 | int AliHLTFileWriter::SetMode(Short_t mode) | |
458 | { | |
459 | // see header file for class documentation | |
460 | fMode|=mode; | |
461 | //HLTDebug("mode set to 0x%x", fMode); | |
462 | return fMode; | |
463 | } | |
464 | ||
465 | int AliHLTFileWriter::ClearMode(Short_t mode) | |
466 | { | |
467 | // see header file for class documentation | |
468 | fMode&=~mode; | |
469 | //HLTDebug("mode set to 0x%x", fMode); | |
470 | return fMode; | |
471 | } | |
472 | ||
5df0cbb9 | 473 | int AliHLTFileWriter::CheckMode(Short_t mode) const |
e74abd18 | 474 | { |
475 | // see header file for class documentation | |
476 | ||
477 | //HLTDebug("check mode 0x%x for flag 0x%x: %d", fMode, mode, (fMode&mode)!=0); | |
478 | return (fMode&mode)!=0; | |
479 | } | |
4b31e06b | 480 | |
481 | int AliHLTFileWriter::ScheduleBlock(int blockno, const AliHLTEventID_t& eventID, | |
482 | const AliHLTComponentBlockData* pDesc) | |
483 | { | |
484 | // see header file for class documentation | |
485 | int iResult=0; | |
486 | if (fpBurstBuffer==NULL || | |
bb7774d6 | 487 | (fBurstBlocks.size()==0 && pDesc->fSize>fBurstBufferSize) ) { |
4b31e06b | 488 | return WriteBlock(blockno, eventID, pDesc); |
489 | } | |
490 | AliHLTComponentBlockData bd=*pDesc; | |
491 | bd.fPtr=NULL; | |
492 | if (fBurstBlocks.size()>0) { | |
493 | bd.fOffset=fBurstBlocks.back().fOffset+fBurstBlocks.back().fSize; | |
494 | } else { | |
495 | bd.fOffset=0; | |
496 | } | |
497 | if (bd.fOffset+bd.fSize>fBurstBufferSize) { | |
498 | if ((iResult=BurstWrite())>=0) { | |
499 | iResult=WriteBlock(blockno, eventID, pDesc); | |
500 | } | |
501 | } else { | |
502 | memcpy(fpBurstBuffer+bd.fOffset, pDesc->fPtr, bd.fSize); | |
503 | fBurstBlocks.push_back(bd); | |
504 | fBurstBlockEvents.push_back(eventID); | |
505 | } | |
506 | ||
507 | return iResult; | |
508 | } | |
509 | ||
510 | int AliHLTFileWriter::BurstWrite() | |
511 | { | |
512 | // see header file for class documentation | |
513 | int iResult=0; | |
514 | if (fBurstBlocks.size()==0) return 0; | |
515 | assert(fBurstBlocks.size()==fBurstBlockEvents.size()); | |
516 | HLTDebug("writing %d postponed blocks", fBurstBlocks.size()); | |
517 | int blockno=0; | |
518 | AliHLTComponentBlockDataList::iterator block=fBurstBlocks.begin(); | |
519 | AliHLTComponentBlockDataList::iterator firstBlock=block; | |
520 | vector<AliHLTEventID_t>::iterator event=fBurstBlockEvents.begin(); | |
521 | if (CheckMode(kConcatenateEvents)) { | |
522 | block=fBurstBlocks.end()-1; | |
523 | event=fBurstBlockEvents.end()-1; | |
524 | } | |
bdc4041c | 525 | |
4b31e06b | 526 | for (; block!=fBurstBlocks.end() && iResult>=0; block++, event++, blockno++) { |
527 | if (event!=fBurstBlockEvents.begin() && *event!=*(event-1)) { | |
528 | blockno=0; | |
529 | } | |
530 | if (CheckMode(kConcatenateEvents)) { | |
531 | // all blocks in the burst buffer are written in one go | |
532 | // just the block descriptor is updated appropriately | |
533 | (*block).fSize+=(*block).fOffset; | |
534 | (*block).fPtr=fpBurstBuffer; | |
535 | } else if (CheckMode(kConcatenateBlocks)) { | |
536 | // all blocks of the same event are written in one go | |
537 | // just the block descriptor is updated appropriately | |
538 | if (event+1==fBurstBlockEvents.end() || | |
539 | *event!=*(event+1)) { | |
540 | (*block).fSize+=(*block).fOffset-(*firstBlock).fOffset; | |
541 | (*block).fPtr=fpBurstBuffer+(*firstBlock).fOffset; | |
542 | firstBlock=block+1; | |
543 | } else { | |
544 | // coninue if it wasn't the last block of this event | |
545 | continue; | |
546 | } | |
547 | } else { | |
548 | (*block).fPtr=fpBurstBuffer+(*block).fOffset; | |
549 | } | |
550 | (*block).fOffset=0; | |
551 | iResult=WriteBlock(blockno, *event, &(*block)); | |
552 | } | |
553 | fBurstBlocks.clear(); | |
554 | fBurstBlockEvents.clear(); | |
555 | ||
556 | return iResult; | |
557 | } | |
558 | ||
559 | int AliHLTFileWriter::WriteBlock(int blockno, const AliHLTEventID_t& eventID, | |
560 | const AliHLTComponentBlockData* pDesc) | |
561 | { | |
562 | // see header file for class documentation | |
563 | int iResult=0; | |
564 | TString filename; | |
565 | HLTDebug("dataspec 0x%x", pDesc->fSpecification); | |
566 | iResult=BuildFileName(eventID, blockno, pDesc->fDataType, pDesc->fSpecification, filename); | |
567 | ios::openmode filemode=(ios::openmode)0; | |
568 | if (fCurrentFileName.CompareTo(filename)==0) { | |
569 | // append to the file | |
570 | filemode=ios::app; | |
571 | } else { | |
572 | // store the file for the next block | |
573 | fCurrentFileName=filename; | |
574 | } | |
575 | if (iResult>=0) { | |
576 | ofstream dump(filename.Data(), filemode); | |
577 | if (dump.good()) { | |
578 | dump.write((static_cast<const char*>(pDesc->fPtr)), pDesc->fSize); | |
579 | HLTDebug("wrote %d byte(s) to file %s", pDesc->fSize, filename.Data()); | |
580 | } else { | |
581 | HLTError("can not open file %s for writing", filename.Data()); | |
582 | iResult=-EBADF; | |
583 | } | |
584 | dump.close(); | |
585 | } | |
a9c4e244 | 586 | if (iResult>=0 && !fPublisherConfName.IsNull()) { |
587 | if (!CheckMode(kConcatenateBlocks) && | |
588 | !CheckMode(kConcatenateEvents)) { | |
589 | // append if not the first entry | |
590 | if (fPublisherConfEvent>=0) filemode=ios::app; | |
591 | else filemode=(ios::openmode)0; | |
592 | ofstream conf(fPublisherConfName.Data(), filemode); | |
593 | if (conf.good()) { | |
a9c4e244 | 594 | conf << "-datatype "; |
595 | conf << DataType2Text(pDesc->fDataType, 3); | |
af056b7b | 596 | conf << " -dataspec "; |
597 | TString specstr; specstr.Form("0x%08x", pDesc->fSpecification); | |
598 | conf << specstr; | |
a9c4e244 | 599 | conf << " -datafile "; |
600 | conf << filename; | |
601 | conf << endl; | |
602 | } else { | |
603 | fPublisherConfName=""; | |
604 | HLTError("can not open file %s for writing of configuration commands", fPublisherConfName.Data()); | |
605 | } | |
606 | conf.close(); | |
bdc4041c | 607 | fPublisherConfEvent=GetEventCount(); |
a9c4e244 | 608 | } else { |
609 | fPublisherConfName=""; | |
610 | HLTWarning("option 'concatenate blocks/events' collides with writing of FilePublisher configuration, disable ..."); | |
611 | } | |
612 | } | |
4b31e06b | 613 | return iResult; |
614 | } |