]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/sim/AliHLTOUTComponent.cxx
initializing equipment id offset from AliDAQ
[u/mrichter/AliRoot.git] / HLT / sim / AliHLTOUTComponent.cxx
CommitLineData
c4228ec4 1// $Id$
2
c5123824 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//**************************************************************************
c4228ec4 18
e2640fbd 19// @file AliHLTOUTComponent.cxx
20// @author Matthias Richter
21// @date
22// @brief The HLTOUT data sink component similar to HLTOUT nodes
23// @note Used in the AliRoot environment only.
c4228ec4 24
c4228ec4 25#if __GNUC__>= 3
26using namespace std;
27#endif
28
4b113031 29#include <cassert>
13398559 30//#include <iostream>
c4228ec4 31#include "AliHLTOUTComponent.h"
4b113031 32#include "AliHLTOUT.h"
64defa03 33#include "AliHLTHOMERLibManager.h"
4b113031 34#include "AliHLTHOMERWriter.h"
6a904136 35#include "AliHLTErrorGuard.h"
a183f221 36#include "AliDAQ.h" // equipment Ids
4b113031 37#include "AliRawDataHeader.h" // Common Data Header
38#include <TDatime.h> // seed for TRandom
39#include <TRandom.h> // random int generation for DDL no
c5123824 40#include <TFile.h>
41#include <TTree.h>
42#include <TArrayC.h>
6a904136 43#include <TSystem.h>
c4228ec4 44
45/** ROOT macro for the implementation of ROOT specific class methods */
46ClassImp(AliHLTOUTComponent)
47
6a904136 48AliHLTOUTComponent::AliHLTOUTComponent(EType type)
e2640fbd 49 : AliHLTOfflineDataSink()
50 , fWriters()
51 , fNofDDLs(10)
52 , fIdFirstDDL(7680) // 0x1e<<8
53 , fBuffer()
54 , fpLibManager(NULL)
6a904136 55 , fOptions(0)
e2640fbd 56 , fDigitFileName("HLT.Digits.root")
57 , fpDigitFile(NULL)
58 , fpDigitTree(NULL)
59 , fppDigitArrays(NULL)
60 , fReservedWriter(-1)
61 , fReservedData(0)
6a904136 62 , fType(type)
c4228ec4 63{
64 // see header file for class documentation
65 // or
66 // refer to README to build package
67 // or
68 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
4b113031 69
398bd766 70 fIdFirstDDL=AliDAQ::DdlIDOffset("HLT");
4b113031 71 fNofDDLs=AliDAQ::NumberOfDdls("HLT");
44dc7683 72
6a904136 73 if (fType!=kGlobal && fType!=kDigits && fType!=kRaw) {
74 ALIHLTERRORGUARD(1, "invalid component type %d", fType);
75 }
c4228ec4 76}
77
2c0e5942 78int AliHLTOUTComponent::fgOptions=kWriteRawFiles|kWriteDigits;
79
c4228ec4 80AliHLTOUTComponent::~AliHLTOUTComponent()
81{
82 // see header file for class documentation
a183f221 83 if (fpLibManager) delete fpLibManager;
84 fpLibManager=NULL;
c4228ec4 85}
86
87const char* AliHLTOUTComponent::GetComponentID()
88{
89 // see header file for class documentation
6a904136 90 switch (fType) {
91 case kDigits: return "HLTOUTdigits";
92 case kRaw: return "HLTOUTraw";
93 case kGlobal:
94 default:
95 return "HLTOUT";
96 }
97 return NULL;
c4228ec4 98}
99
100void AliHLTOUTComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
101{
102 // see header file for class documentation
103 list.clear();
104 list.push_back(kAliHLTAnyDataType);
105}
106
107AliHLTComponent* AliHLTOUTComponent::Spawn()
108{
109 // see header file for class documentation
6a904136 110 return new AliHLTOUTComponent(fType);
c4228ec4 111}
112
113int AliHLTOUTComponent::DoInit( int argc, const char** argv )
114{
115 // see header file for class documentation
116 int iResult=0;
6a904136 117
118 switch (fType) {
119 case kDigits:
120 fOptions|=kWriteDigits; fOptions&=~kWriteRawFiles;
121 HLTInfo("initializing HLTOUT component for digits generation");
122 break;
123 case kRaw:
124 fOptions|=kWriteRawFiles; fOptions&=~kWriteDigits;
125 HLTInfo("initializing HLTOUT component for raw data generation");
126 break;
127 case kGlobal:
128 default:
129 fOptions=fgOptions;
130 }
131
3d24abe7 132 if ((iResult=ConfigureFromArgumentString(argc, argv))<0) return iResult;
c4228ec4 133
1b820a65 134 // Make sure there is no library manager before we try and create a new one.
135 if (fpLibManager) {
136 delete fpLibManager;
137 fpLibManager=NULL;
138 }
139
140 // Create a new library manager and allocate the appropriate number of
141 // HOMER writers for the HLTOUT component.
a183f221 142 fpLibManager=new AliHLTHOMERLibManager;
143 if (fpLibManager) {
144 int writerNo=0;
145 for (writerNo=0; writerNo<fNofDDLs; writerNo++) {
146 AliHLTMonitoringWriter* pWriter=fpLibManager->OpenWriter();
147 if (pWriter) {
a8420176 148 HLTDebug("HOMER writer %p added", pWriter);
a183f221 149 fWriters.push_back(pWriter);
150 } else {
c5123824 151 HLTError("can not open HOMER writer");
5db0e774 152 iResult=-ENODEV;
a183f221 153 break;
154 }
4b113031 155 }
a183f221 156 } else {
157 iResult=-ENOMEM;
4b113031 158 }
159
c4228ec4 160 return iResult;
161}
162
e2640fbd 163int AliHLTOUTComponent::ScanConfigurationArgument(int argc, const char** argv)
164{
165 // see header file for class documentation
166 if (argc<=0) return 0;
167 int i=0;
168 TString argument=argv[i];
169 const char* key="";
170
171 // -links n
172 // specify number of ddl links
173 if (argument.CompareTo("-links")==0) {
174 if (++i>=argc) return -EPROTO;
175 TString parameter(argv[i]);
176 parameter.Remove(TString::kLeading, ' '); // remove all blanks
177 if (parameter.IsDigit()) {
178 fNofDDLs=parameter.Atoi();
179 } else {
180 HLTError("wrong parameter for argument %s, number expected", argument.Data());
181 return -EINVAL;
182 }
183
184 return 2;
185 }
186
187 // -digitfile name
188 if (argument.CompareTo("-digitfile")==0) {
189 if (++i>=argc) return -EPROTO;
190 fDigitFileName=argv[i];
191
192 return 2;
193 }
194
195 // -rawout
196 key="-rawout";
197 if (argument.Contains(key)) {
198 argument.ReplaceAll(key, "");
199 if (argument.IsNull()) {
6a904136 200 fOptions|=kWriteRawFiles;
e2640fbd 201 } else if (argument.CompareTo("=off")==0) {
6a904136 202 fOptions&=~kWriteRawFiles;
e2640fbd 203 } else if (argument.CompareTo("=on")==0) {
6a904136 204 fOptions|=kWriteRawFiles;
e2640fbd 205 } else {
206 HLTError("invalid parameter for argument %s: possible %s=off/%s=on", key, key, key);
207 return -EPROTO;
208 }
209
210 return 1;
211 }
212
213 // -digitout
214 key="-digitout";
215 if (argument.Contains(key)) {
216 argument.ReplaceAll(key, "");
217 if (argument.IsNull()) {
6a904136 218 fOptions|=kWriteDigits;
e2640fbd 219 } else if (argument.CompareTo("=off")==0) {
6a904136 220 fOptions&=~kWriteDigits;
e2640fbd 221 } else if (argument.CompareTo("=on")==0) {
6a904136 222 fOptions|=kWriteDigits;
e2640fbd 223 } else {
224 HLTError("invalid parameter for argument %s: possible %s=off/%s=on", key, key, key);
225 return -EPROTO;
226 }
227
228 return 1;
229 }
230
231 // unknown argument
232 return -EINVAL;
233}
234
c4228ec4 235int AliHLTOUTComponent::DoDeinit()
236{
237 // see header file for class documentation
238 int iResult=0;
4b113031 239
a183f221 240 if (fpLibManager) {
241 AliHLTMonitoringWriterPVector::iterator element=fWriters.begin();
242 while (element!= fWriters.end()) {
243 assert(*element);
b9dd5a11 244 // wanted to have a dynamic_cast<AliHLTHOMERWriter*> here, but this results into
245 // undefined symbol when loading the library
c74eec40 246 if (*element!=NULL) {
1b820a65 247 (*element)->Clear();
248 fpLibManager->DeleteWriter((AliHLTHOMERWriter*)(*element));
c74eec40 249 } else {
250 HLTError("writer instance is NULL");
251 }
a183f221 252 element=fWriters.erase(element);
253 }
4b113031 254 }
1b820a65 255 if (fpLibManager) {
256 delete fpLibManager;
257 fpLibManager=NULL;
258 }
c5123824 259
260 if (fpDigitTree) {
261 delete fpDigitTree;
262 fpDigitTree=NULL;
263 }
264
265 if (fpDigitFile) {
266 fpDigitFile->Close();
267 delete fpDigitFile;
268 fpDigitFile=NULL;
269 }
270
271 if (fppDigitArrays) {
272 for (int i=0; i<fNofDDLs; i++) {
273 if (fppDigitArrays[i]) delete fppDigitArrays[i];
274 }
275 delete[] fppDigitArrays;
276 fppDigitArrays=NULL;
277 }
c4228ec4 278
279 return iResult;
280}
281
282int AliHLTOUTComponent::DumpEvent( const AliHLTComponentEventData& evtData,
283 const AliHLTComponentBlockData* blocks,
284 AliHLTComponentTriggerData& /*trigData*/ )
285{
286 // see header file for class documentation
287 int iResult=0;
2c0e5942 288 HLTInfo("write %d output block(s)", evtData.fBlockCnt);
6478b06b 289 int writerNo=0;
3d24abe7 290 int blockCount=0;
6478b06b 291 AliHLTUInt32_t eventType=gkAliEventTypeUnknown;
292 bool bIsDataEvent=IsDataEvent(&eventType);
4b113031 293 if (iResult>=0) {
294 homer_uint64 homerHeader[kCount_64b_Words];
295 HOMERBlockDescriptor homerDescriptor(homerHeader);
296 for (int n=0; n<(int)evtData.fBlockCnt; n++ ) {
6478b06b 297 if (blocks[n].fDataType==kAliHLTDataTypeEvent ||
298 blocks[n].fDataType==kAliHLTDataTypeSOR ||
299 blocks[n].fDataType==kAliHLTDataTypeEOR ||
300 blocks[n].fDataType==kAliHLTDataTypeComConf ||
301 blocks[n].fDataType==kAliHLTDataTypeUpdtDCS)
302 {
303 // the special events have to be ignored.
304 continue;
305 }
306 if (!bIsDataEvent &&
307 (blocks[n].fDataType!=kAliHLTDataTypeComponentTable))
308 {
309 // In simulation, there are no SOR and EOR events created. Thats
310 // why all data blocks of those events are currently ignored.
311 // Strictly speaking, components should not create output blocks
312 // on the SOR/EOR event
313 //
314 // Exeptions: some blocks are added, the buffer must be prepared and
315 // kept since the pointers will be invalid
316 // - kAliHLTDataTypeComponentTable component table entries
317 continue;
318 }
4b113031 319 memset( homerHeader, 0, sizeof(homer_uint64)*kCount_64b_Words );
320 homerDescriptor.Initialize();
44dc7683 321 // for some traditional reason the TCPDumpSubscriber swaps the bytes
322 // of the data type id and data type origin. Actually I do not understand
323 // the corresponding code line
324 // homerBlock.SetType( blocks[n].fDataType.fID );
325 // this compiles in the PubSub framework and in addition does a byte swap
326 homer_uint64 id=0;
327 homer_uint64 origin=0;
328 memcpy(&id, blocks[n].fDataType.fID, sizeof(homer_uint64));
329 memcpy(((AliHLTUInt8_t*)&origin)+sizeof(homer_uint32), blocks[n].fDataType.fOrigin, sizeof(homer_uint32));
ff3b6fed 330 homerDescriptor.SetType(AliHLTOUT::ByteSwap64(id));
c5123824 331 homerDescriptor.SetSubType1(AliHLTOUT::ByteSwap64(origin));
44dc7683 332 homerDescriptor.SetSubType2(blocks[n].fSpecification);
a8420176 333 homerDescriptor.SetBlockSize(blocks[n].fSize);
6478b06b 334 if (bIsDataEvent) {
335 writerNo=ShuffleWriters(fWriters, blocks[n].fSize);
336 }
13398559 337 assert(writerNo>=0 && writerNo<(int)fWriters.size());
a8420176 338 // I'm puzzled by the different headers, buffers etc. used in the
339 // HOMER writer/data. In additional, there is no type check as there
340 // are void pointers used and names mixed.
341 // It seems that HOMERBlockDescriptor is just a tool to set the
342 // different fields in the homer header, which is an array of 64 bit
343 // words.
344 fWriters[writerNo]->AddBlock(homerHeader, blocks[n].fPtr);
3d24abe7 345 blockCount++;
4b113031 346 }
347 }
348
3d24abe7 349 if (iResult>=0 && !bIsDataEvent && fNofDDLs>=2) {
6478b06b 350 // data blocks from a special event are kept to be added to the
3d24abe7 351 // following event. In the current implementation at least 2 DDLs
352 // are required to allow to keep the blocks of the SOR event and
353 // include it in the first event. If only one writer is available
354 // the blocks are ignored. For the moment this is not expexted to
355 // be a problem since components should not gererate anything on
356 // SOR/EOR. The only case is the list of AliHLTComponentTableEntry
357 // transmitted for component statistics in debug mode.
6478b06b 358 if (fReservedWriter>=0) {
359 HLTWarning("overriding previous buffer of non-data event data blocks");
360 }
361 const AliHLTUInt8_t* pBuffer=NULL;
362 int bufferSize=0;
363 // TODO: not yet clear whether it is smart to send the event id of
364 // this special event or if it should be set from the id of the
365 // following event where the data will be added
3d24abe7 366 if (blockCount>0 && (bufferSize=FillOutputBuffer(evtData.fEventID, fWriters[writerNo], pBuffer))>0) {
6478b06b 367 fReservedWriter=writerNo;
368 fReservedData=bufferSize;
369 }
370 fWriters[writerNo]->Clear();
3d24abe7 371 } else if (iResult>=0 && !bIsDataEvent && fNofDDLs<2 && blockCount>0) {
372 HLTWarning("ignoring %d block(s) for special event of type %d: at least 2 DDLs are required", blockCount, eventType);
373 }
374
375 if (iResult>=0 && bIsDataEvent) {
376 iResult=Write(GetEventCount(), GetRunLoader());
6478b06b 377 }
378
4b113031 379 return iResult;
380}
381
3d24abe7 382
970e430a 383int AliHLTOUTComponent::FillESD(int /*eventNo*/, AliRunLoader* /*runLoader*/, AliESDEvent* /*esd*/)
3d24abe7 384{
385 // see header file for class documentation
386 // 2010-04-14 nothing to do any more. The data is written at the end of
387 // DumpEvent
388 return 0;
389}
390
391int AliHLTOUTComponent::Write(int eventNo, AliRunLoader* runLoader)
4b113031 392{
393 // see header file for class documentation
394 int iResult=0;
6478b06b 395
4b113031 396 if (fWriters.size()==0) return 0;
3d24abe7 397
6478b06b 398 if (fReservedWriter>=0) {
6a904136 399 if (fOptions&kWriteDigits) WriteDigitArray(fReservedWriter, &fBuffer[0], fReservedData);
400 if (fOptions&kWriteRawFiles) WriteRawFile(eventNo, runLoader, fReservedWriter, &fBuffer[0], fReservedData);
6478b06b 401 fReservedData=0;
402 }
403
4b113031 404 // search for the writer with the biggest data volume in order to allocate the
405 // output buffer of sufficient size
4b113031 406 vector<int> sorted;
d76bc02a 407 for (size_t i=0; i<fWriters.size(); i++) {
6478b06b 408 if ((int)i==fReservedWriter) continue;
4b113031 409 assert(fWriters[i]);
410 if (fWriters[i]) {
a8420176 411 if (sorted.size()==0 || fWriters[i]->GetTotalMemorySize()<=fWriters[sorted[0]]->GetTotalMemorySize()) {
4b113031 412 sorted.push_back(i);
a8420176 413 } else {
414 sorted.insert(sorted.begin(), i);
4b113031 415 }
416 }
4b113031 417 }
6478b06b 418 fReservedWriter=-1;
4b113031 419
420 vector<int>::iterator ddlno=sorted.begin();
421 while (ddlno!=sorted.end()) {
422 const AliHLTUInt8_t* pBuffer=NULL;
423 int bufferSize=0;
424
b9dd5a11 425 if ((bufferSize=FillOutputBuffer(eventNo, fWriters[*ddlno], pBuffer))>0) {
6a904136 426 if (fOptions&kWriteDigits) WriteDigitArray(*ddlno, pBuffer, bufferSize);
427 if (fOptions&kWriteRawFiles) WriteRawFile(eventNo, runLoader, *ddlno, pBuffer, bufferSize);
4b113031 428 }
a8420176 429 fWriters[*ddlno]->Clear();
4b113031 430 ddlno++;
431 }
6a904136 432 if (fOptions&kWriteDigits) WriteDigits(eventNo, runLoader);
4b113031 433 return iResult;
434}
435
d76bc02a 436int AliHLTOUTComponent::ShuffleWriters(AliHLTMonitoringWriterPVector &list, AliHLTUInt32_t /*size*/)
4b113031 437{
438 // see header file for class documentation
439 int iResult=-ENOENT;
440 assert(list.size()>0);
441 if (list.size()==0) return iResult;
442 vector<int> writers;
d76bc02a 443 size_t i=0;
4b113031 444 for (i=0; i<list.size(); i++) {
6478b06b 445 if ((int)i==fReservedWriter) continue;
4b113031 446 if (list[i]->GetTotalMemorySize()==0)
447 writers.push_back(i);
448 else if (iResult<0 ||
449 list[i]->GetTotalMemorySize()<list[iResult]->GetTotalMemorySize())
450 iResult=i;
451
452 }
453 if (writers.size()>0) {
454 iResult=writers[0];
455 if (writers.size()>0) {
456 // shuffle among the empty writers
457 TDatime dt;
458 TRandom rand;
459 rand.SetSeed(dt.Get()*(iResult+1));
460 i=rand.Integer(writers.size()-1);
461 assert(i>0 && i<writers.size()-1);
462 iResult=writers[i];
463 }
464 } else {
465 // take the writer with the least data volume
466 assert(iResult>=0);
467 }
468 return iResult;
469}
470
a183f221 471int AliHLTOUTComponent::FillOutputBuffer(int eventNo, AliHLTMonitoringWriter* pWriter, const AliHLTUInt8_t* &pBuffer)
4b113031 472{
473 // see header file for class documentation
474 int iResult=0;
d76bc02a 475 unsigned int bufferSize=0;
4b113031 476
477 // space for common data header
478 bufferSize+=sizeof(AliRawDataHeader);
a8420176 479 assert(sizeof(AliRawDataHeader)==32);
4b113031 480
481 // space for HLT event header
482 bufferSize+=sizeof(AliHLTOUT::AliHLTOUTEventHeader);
483
484 // space for payload from the writer
485 if (pWriter) bufferSize+=pWriter->GetTotalMemorySize();
486
737bab1f 487 // payload data must be aligned to 32bit
488 bufferSize=(bufferSize+3)/4;
489 bufferSize*=4;
490
4b113031 491 if (bufferSize>fBuffer.size())
492 fBuffer.resize(bufferSize);
493
737bab1f 494 // reset the last 32bit word, rest will be overwritten
495 memset(&fBuffer[bufferSize-4], 0, 4);
496
4b113031 497 if (bufferSize<=fBuffer.size()) {
498 AliRawDataHeader* pCDH=reinterpret_cast<AliRawDataHeader*>(&fBuffer[0]);
499 AliHLTOUT::AliHLTOUTEventHeader* pHLTH=reinterpret_cast<AliHLTOUT::AliHLTOUTEventHeader*>(&fBuffer[sizeof(AliRawDataHeader)]);
c2b283d6 500 *pCDH = AliRawDataHeader(); // Fill with default values.
4b113031 501 memset(pHLTH, 0, sizeof(AliHLTOUT::AliHLTOUTEventHeader));
44dc7683 502
4b113031 503 if (pWriter) {
504 // copy payload
505 pWriter->Copy(&fBuffer[sizeof(AliRawDataHeader)+sizeof(AliHLTOUT::AliHLTOUTEventHeader)], 0, 0, 0, 0);
506 pHLTH->fLength=pWriter->GetTotalMemorySize();
507 // set status bit to indicate HLT payload
13398559 508 pCDH->fStatusMiniEventID|=0x1<<(AliHLTOUT::kCDHStatusFlagsOffset+AliHLTOUT::kCDHFlagsHLTPayload);
4b113031 509 }
510 pHLTH->fLength+=sizeof(AliHLTOUT::AliHLTOUTEventHeader);
c2b283d6 511 // pHLTH->fEventIDLow is already set to zero in memset above.
512 pHLTH->fEventIDLow = eventNo;
44dc7683 513 // version does not really matter since we do not add decision data
514 pHLTH->fVersion=AliHLTOUT::kVersion1;
4b113031 515
31d7df34 516 pCDH->fSize=bufferSize;
44dc7683 517 pCDH->fStatusMiniEventID|=0x1<<(AliHLTOUT::kCDHStatusFlagsOffset + AliHLTOUT::kCDHFlagsHLTPayload);
c4228ec4 518
4b113031 519 pBuffer=&fBuffer[0];
a8420176 520 iResult=(int)bufferSize;
4b113031 521 } else {
522 pBuffer=NULL;
523 iResult=-ENOMEM;
c4228ec4 524 }
525
526 return iResult;
527}
528
c5123824 529int AliHLTOUTComponent::WriteDigitArray(int hltddl, const AliHLTUInt8_t* pBuffer, unsigned int bufferSize)
530{
531 // see header file for class documentation
532 int iResult=0;
533 assert(hltddl<fNofDDLs);
534 if (hltddl>=fNofDDLs) return -ERANGE;
535
536 if (!fppDigitArrays) {
537 fppDigitArrays=new TArrayC*[fNofDDLs];
538 if (fppDigitArrays) {
539 for (int i=0; i<fNofDDLs; i++) {
540 fppDigitArrays[i]=new TArrayC(0);
541 }
542 }
543 }
544 if (fppDigitArrays && fppDigitArrays[hltddl]) {
545 fppDigitArrays[hltddl]->Set(bufferSize, reinterpret_cast<const Char_t*>(pBuffer));
546 } else {
547 iResult=-ENOMEM;
548 }
549 return iResult;
550}
551
552int AliHLTOUTComponent::WriteDigits(int /*eventNo*/, AliRunLoader* /*runLoader*/)
c4228ec4 553{
554 // see header file for class documentation
555 int iResult=0;
c5123824 556 if (!fpDigitFile) {
e2640fbd 557 fpDigitFile=new TFile(fDigitFileName, "RECREATE");
c5123824 558 }
559 if (fpDigitFile && !fpDigitFile->IsZombie()) {
560 if (!fpDigitTree) {
561 fpDigitTree=new TTree("rawhltout","HLTOUT raw data");
562 if (fpDigitTree && fppDigitArrays) {
563 for (int i=0; i<fNofDDLs; i++) {
564 const char* branchName=AliDAQ::DdlFileName("HLT", i);
565 if (fppDigitArrays[i]) fpDigitTree->Branch(branchName, "TArrayC", &fppDigitArrays[i], 32000/*just as the default*/, 0);
566 }
567 }
568 }
569 if (fpDigitTree) {
d1035b66 570#ifdef __DEBUG
c5123824 571 int res=fpDigitTree->Fill();
572 HLTDebug("writing digit tree: %d", res);
573 fpDigitFile->cd();
574 res=fpDigitTree->Write("",TObject::kOverwrite);
575 HLTDebug("writing digit tree: %d", res);
d1035b66 576#else
577 fpDigitTree->Fill();
578 fpDigitFile->cd();
579 fpDigitTree->Write("",TObject::kOverwrite);
580#endif
c5123824 581 if (fppDigitArrays) for (int i=0; i<fNofDDLs; i++) {
582 if (fppDigitArrays[i]) fppDigitArrays[i]->Set(0);
583 }
584 }
585 } else {
586 const char* errorMsg="";
587 if (GetEventCount()==5) {
588 errorMsg=" (suppressing further error messages)";
589 }
590 if (GetEventCount()<5) {
e2640fbd 591 HLTError("can not open HLT digit file %s%s", fDigitFileName.Data(), errorMsg);
c5123824 592 }
593 iResult=-EBADF;
594 }
c4228ec4 595 return iResult;
596}
4b113031 597
a8420176 598int AliHLTOUTComponent::WriteRawFile(int eventNo, AliRunLoader* /*runLoader*/, int hltddl, const AliHLTUInt8_t* pBuffer, unsigned int bufferSize)
4b113031 599{
600 // see header file for class documentation
601 int iResult=0;
602 const char* fileName=AliDAQ::DdlFileName("HLT", hltddl);
4b113031 603 assert(fileName!=NULL);
a8420176 604 TString filePath;
605 filePath.Form("raw%d/", eventNo);
6a904136 606 if (gSystem->AccessPathName(filePath)) {
607 TString command="mkdir "; command+=filePath;
608 gSystem->Exec(command);
609 }
a8420176 610 filePath+=fileName;
4b113031 611 if (fileName) {
612 ios::openmode filemode=(ios::openmode)0;
613 ofstream rawfile(filePath.Data(), filemode);
614 if (rawfile.good()) {
615 if (pBuffer && bufferSize>0) {
616 rawfile.write(reinterpret_cast<const char*>(pBuffer), bufferSize);
617 } else {
618 HLTWarning("writing zero length raw data file %s");
619 }
620 HLTDebug("wrote %d byte(s) to file %s", bufferSize, filePath.Data());
621 } else {
622 HLTError("can not open file %s for writing", filePath.Data());
623 iResult=-EBADF;
624 }
625 rawfile.close();
626 }
627 return iResult;
628}
2c0e5942 629
630void AliHLTOUTComponent::SetGlobalOption(unsigned int options)
631{
632 // see header file for class documentation
633 fgOptions|=options;
634}
635
636void AliHLTOUTComponent::ClearGlobalOption(unsigned int options)
637{
638 // see header file for class documentation
639 fgOptions&=~options;
640}
6a904136 641
642bool AliHLTOUTComponent::TestGlobalOption(unsigned int option)
643{
644 // see header file for class documentation
645 return (fgOptions&option)!=0;
646}