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