LCOV - code coverage report
Current view: top level - HLT/BASE - AliHLTOUTComponent.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 30 322 9.3 %
Date: 2016-06-14 17:26:59 Functions: 7 22 31.8 %

          Line data    Source code
       1             : // $Id$
       2             : 
       3             : //**************************************************************************
       4             : //* This file is property of and copyright by the                          * 
       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   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.
      24             : 
      25             : #include <cassert>
      26             : //#include <iostream>
      27             : #include "AliHLTOUTComponent.h"
      28             : #include "AliHLTOUT.h"
      29             : #include "AliHLTHOMERLibManager.h"
      30             : #include "AliHLTHOMERWriter.h"
      31             : #include "AliHLTErrorGuard.h"
      32             : #include "AliDAQ.h" // equipment Ids
      33             : #include "AliRawDataHeaderV3.h" // Common Data Header 
      34             : #include <TDatime.h> // seed for TRandom
      35             : #include <TRandom.h> // random int generation for DDL no
      36             : #include <TFile.h>
      37             : #include <TTree.h>
      38             : #include <TArrayC.h>
      39             : #include <TSystem.h>
      40             : 
      41             : using namespace std;
      42             : 
      43             : /** ROOT macro for the implementation of ROOT specific class methods */
      44         126 : ClassImp(AliHLTOUTComponent)
      45             : 
      46             : AliHLTOUTComponent::AliHLTOUTComponent(EType type)
      47           3 :   : AliHLTDataSink()
      48           3 :   , fWriters()
      49           3 :   , fNofDDLs(10)
      50           3 :   , fIdFirstDDL(7680) // 0x1e<<8
      51           3 :   , fBuffer()
      52           3 :   , fpLibManager(NULL)
      53           3 :   , fOptions(0)
      54           3 :   , fDigitFileName("HLT.Digits.root")
      55           3 :   , fpDigitFile(NULL)
      56           3 :   , fpDigitTree(NULL)
      57           3 :   , fppDigitArrays(NULL)
      58           3 :   , fReservedWriter(-1)
      59           3 :   , fReservedData(0)
      60           3 :   , fType(type)
      61           3 :   , fRoundRobinCounter(0)
      62          15 : {
      63             :   // The HLTOUT data sink component which models the behavior of the HLTOUT
      64             :   // nodes of the HLT cluster.
      65             :   // The HLTOUT component is attached at the end of a chain. It stores all input
      66             :   // block in the HOMER format, distributed over a number of DDL link. The data
      67             :   // is stored in a digit file or in raw ddl files.
      68           6 :   fIdFirstDDL=AliDAQ::DdlIDOffset("HLT");
      69           6 :   fNofDDLs=AliDAQ::NumberOfDdls("HLT");
      70             :   
      71           6 :   if (fType!=kGlobal && fType!=kDigits && fType!=kRaw) {
      72           0 :     ALIHLTERRORGUARD(1, "invalid component type %d", fType);
      73             :   }
      74           6 : }
      75             : 
      76             : int AliHLTOUTComponent::fgOptions=kWriteRawFiles|kWriteDigits;
      77             : 
      78             : AliHLTOUTComponent::~AliHLTOUTComponent()
      79          18 : {
      80             :   // destructor
      81           3 :   if (fpLibManager) delete fpLibManager;
      82           3 :   fpLibManager=NULL;
      83           9 : }
      84             : 
      85             : const char* AliHLTOUTComponent::GetComponentID()
      86             : {
      87             :   // overloaded from AliHLTComponent: get component id
      88         372 :   switch (fType) {
      89          62 :   case kDigits: return "HLTOUTdigits";
      90          61 :   case kRaw:    return "HLTOUTraw";
      91             :   case kGlobal:
      92             :   default:
      93          63 :     return "HLTOUT";
      94             :   }
      95             :   return NULL;
      96         186 : }
      97             : 
      98             : void AliHLTOUTComponent::GetInputDataTypes( AliHLTComponentDataTypeList& list)
      99             : {
     100             :   // overloaded from AliHLTComponent: indicate input data types
     101           0 :   list.clear();
     102           0 :   list.push_back(kAliHLTAnyDataType);
     103           0 : }
     104             : 
     105             : AliHLTComponent* AliHLTOUTComponent::Spawn()
     106             : {
     107             :   // overloaded from AliHLTComponent: create instance
     108           0 :   return new AliHLTOUTComponent(fType);
     109           0 : }
     110             : 
     111             : int AliHLTOUTComponent::DoInit( int argc, const char** argv )
     112             : {
     113             :   // overloaded from AliHLTComponent: initialization
     114             :   int iResult=0;
     115             : 
     116           0 :   switch (fType) {
     117             :   case kDigits:
     118           0 :     fOptions|=kWriteDigits; fOptions&=~kWriteRawFiles;
     119           0 :     HLTInfo("initializing HLTOUT component for digits generation");
     120             :     break;
     121             :   case kRaw:
     122           0 :     fOptions|=kWriteRawFiles; fOptions&=~kWriteDigits;
     123           0 :     HLTInfo("initializing HLTOUT component for raw data generation");
     124             :     break;
     125             :   case kGlobal:
     126             :   default:
     127           0 :     fOptions=fgOptions;
     128           0 :   }
     129             : 
     130           0 :   if ((iResult=ConfigureFromArgumentString(argc, argv))<0) return iResult;
     131             : 
     132             :   // Create a new library manager and allocate the appropriate number of
     133             :   // HOMER writers for the HLTOUT component.
     134           0 :   if (!fpLibManager) fpLibManager=new AliHLTHOMERLibManager;
     135           0 :   if (fpLibManager) {
     136             :     int writerNo=0;
     137           0 :     for (writerNo=0; writerNo<fNofDDLs; writerNo++) {
     138           0 :       AliHLTMonitoringWriter* pWriter=fpLibManager->OpenWriter();
     139           0 :       if (pWriter) {
     140             :         HLTDebug("HOMER writer %p added", pWriter);
     141           0 :         fWriters.push_back(pWriter);
     142             :       } else {
     143           0 :         HLTError("can not open HOMER writer");
     144             :         iResult=-ENODEV;
     145           0 :         break;
     146             :       }
     147           0 :     }
     148           0 :   } else {
     149             :     iResult=-ENOMEM;
     150             :   }
     151             : 
     152           0 :   return iResult;
     153           0 : }
     154             : 
     155             : int AliHLTOUTComponent::ScanConfigurationArgument(int argc, const char** argv)
     156             : {
     157             :   // overloaded from AliHLTComponent: argument scan
     158           0 :   if (argc<=0) return 0;
     159             :   int i=0;
     160           0 :   TString argument=argv[i];
     161             :   const char* key="";
     162             : 
     163             :   // -links n
     164             :   // specify number of ddl links
     165           0 :   if (argument.CompareTo("-links")==0) {
     166           0 :     if (++i>=argc) return -EPROTO;
     167           0 :     TString parameter(argv[i]);
     168           0 :     parameter.Remove(TString::kLeading, ' '); // remove all blanks
     169           0 :     if (parameter.IsDigit()) {
     170           0 :       fNofDDLs=parameter.Atoi();
     171             :     } else {
     172           0 :       HLTError("wrong parameter for argument %s, number expected", argument.Data());
     173           0 :       return -EINVAL;
     174             :     }
     175             : 
     176           0 :     return 2;
     177           0 :   } 
     178             : 
     179             :   // -digitfile name
     180           0 :   if (argument.CompareTo("-digitfile")==0) {
     181           0 :     if (++i>=argc) return -EPROTO;
     182           0 :     fDigitFileName=argv[i];
     183             : 
     184           0 :     return 2;
     185             :   }
     186             : 
     187             :   // -rawout
     188             :   key="-rawout";
     189           0 :   if (argument.Contains(key)) {
     190           0 :     argument.ReplaceAll(key, "");
     191           0 :     if (argument.IsNull()) {
     192           0 :       fOptions|=kWriteRawFiles;
     193           0 :     } else if (argument.CompareTo("=off")==0) {
     194           0 :       fOptions&=~kWriteRawFiles;
     195           0 :     } else if (argument.CompareTo("=on")==0) {
     196           0 :       fOptions|=kWriteRawFiles;
     197             :     } else {
     198           0 :       HLTError("invalid parameter for argument %s: possible %s=off/%s=on", key, key, key);
     199           0 :       return -EPROTO;
     200             :     }
     201             : 
     202           0 :     return 1;
     203             :   }
     204             : 
     205             :   // -digitout
     206             :   key="-digitout";
     207           0 :   if (argument.Contains(key)) {
     208           0 :     argument.ReplaceAll(key, "");
     209           0 :     if (argument.IsNull()) {
     210           0 :       fOptions|=kWriteDigits;
     211           0 :     } else if (argument.CompareTo("=off")==0) {
     212           0 :       fOptions&=~kWriteDigits;
     213           0 :     } else if (argument.CompareTo("=on")==0) {
     214           0 :       fOptions|=kWriteDigits;
     215             :     } else {
     216           0 :       HLTError("invalid parameter for argument %s: possible %s=off/%s=on", key, key, key);
     217           0 :       return -EPROTO;
     218             :     }
     219             : 
     220           0 :     return 1;
     221             :   }
     222             : 
     223             :   // -distribute-blocks
     224             :   key="-distribute-blocks";
     225           0 :   if (argument.CompareTo(key)==0) {
     226           0 :     fRoundRobinCounter=-1;
     227             : 
     228           0 :     return 1;
     229             :   }
     230             : 
     231             :   // unknown argument
     232           0 :   return -EINVAL;
     233           0 : }
     234             : 
     235             : int AliHLTOUTComponent::DoDeinit()
     236             : {
     237             :   // overloaded from AliHLTComponent: cleanup
     238             :   int iResult=0;
     239             : 
     240           0 :   if (fpLibManager) {
     241           0 :     AliHLTMonitoringWriterPVector::iterator element=fWriters.begin();
     242           0 :     while (element!= fWriters.end()) {
     243           0 :       assert(*element);
     244             :       // wanted to have a dynamic_cast<AliHLTHOMERWriter*> here, but this results into
     245             :       // undefined symbol when loading the library
     246           0 :       if (*element!=NULL) {
     247           0 :         (*element)->Clear();
     248           0 :         fpLibManager->DeleteWriter((AliHLTHOMERWriter*)(*element));
     249           0 :       } else {
     250           0 :         HLTError("writer instance is NULL");
     251             :       }
     252           0 :       element=fWriters.erase(element);
     253             :     }
     254           0 :   }
     255           0 :   if (fpLibManager) {
     256           0 :     delete fpLibManager;
     257           0 :     fpLibManager=NULL;
     258           0 :   }
     259             : 
     260           0 :   if (fpDigitTree) {
     261           0 :     delete fpDigitTree;
     262           0 :     fpDigitTree=NULL;
     263           0 :   }
     264             : 
     265           0 :   if (fpDigitFile) {
     266           0 :     fpDigitFile->Close();
     267           0 :     delete fpDigitFile;
     268           0 :     fpDigitFile=NULL;
     269           0 :   }
     270             : 
     271           0 :   if (fppDigitArrays) {
     272           0 :     for (int i=0; i<fNofDDLs; i++) {
     273           0 :       if (fppDigitArrays[i]) delete fppDigitArrays[i];
     274             :     }
     275           0 :     delete[] fppDigitArrays;
     276           0 :     fppDigitArrays=NULL;
     277           0 :   }
     278             :   
     279           0 :   return iResult;
     280             : }
     281             : 
     282             : int AliHLTOUTComponent::DumpEvent( const AliHLTComponentEventData& evtData,
     283             :                          const AliHLTComponentBlockData* blocks, 
     284             :                          AliHLTComponentTriggerData& /*trigData*/ )
     285             : {
     286             :   // overloaded from AliHLTDataSink: event processing
     287             :   int iResult=0;
     288           0 :   HLTInfo("write %d output block(s)", evtData.fBlockCnt);
     289             :   int writerNo=0;
     290             :   int blockCount=0;
     291           0 :   AliHLTUInt32_t eventType=gkAliEventTypeUnknown;
     292           0 :   bool bIsDataEvent=IsDataEvent(&eventType);
     293           0 :   if (iResult>=0) {
     294           0 :     homer_uint64 homerHeader[kCount_64b_Words];
     295           0 :     HOMERBlockDescriptor homerDescriptor(homerHeader);
     296           0 :     for (int n=0; n<(int)evtData.fBlockCnt; n++ ) {
     297           0 :       if (blocks[n].fDataType==kAliHLTDataTypeEvent ||
     298           0 :           blocks[n].fDataType==kAliHLTDataTypeSOR ||
     299           0 :           blocks[n].fDataType==kAliHLTDataTypeEOR ||
     300           0 :           blocks[n].fDataType==kAliHLTDataTypeComConf ||
     301           0 :           blocks[n].fDataType==kAliHLTDataTypeUpdtDCS)
     302             :         {
     303             :           // the special events have to be ignored.
     304             :           continue;
     305             :         }
     306           0 :       if (!bIsDataEvent &&
     307           0 :           (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             :         }
     319           0 :       memset( homerHeader, 0, sizeof(homer_uint64)*kCount_64b_Words );
     320           0 :       homerDescriptor.Initialize();
     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           0 :       memcpy(&id, blocks[n].fDataType.fID, sizeof(homer_uint64));
     329           0 :       memcpy(((AliHLTUInt8_t*)&origin)+sizeof(homer_uint32), blocks[n].fDataType.fOrigin, sizeof(homer_uint32));
     330           0 :       homerDescriptor.SetType(AliHLTOUT::ByteSwap64(id));
     331           0 :       homerDescriptor.SetSubType1(AliHLTOUT::ByteSwap64(origin));
     332           0 :       homerDescriptor.SetSubType2(blocks[n].fSpecification);
     333           0 :       homerDescriptor.SetBlockSize(blocks[n].fSize);
     334           0 :       if (bIsDataEvent) {
     335           0 :         writerNo=ShuffleWriters(fWriters, blocks[n].fSize);
     336           0 :       }
     337           0 :       assert(writerNo>=0 && writerNo<(int)fWriters.size());
     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           0 :       fWriters[writerNo]->AddBlock(homerHeader, blocks[n].fPtr);
     345           0 :       blockCount++;
     346           0 :     }
     347           0 :   }
     348             : 
     349           0 :   if (iResult>=0 && !bIsDataEvent && fNofDDLs>=2) {
     350             :     // data blocks from a special event are kept to be added to the
     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.
     358           0 :     if (fReservedWriter>=0) {
     359           0 :       HLTWarning("overriding previous buffer of non-data event data blocks");
     360             :     }
     361           0 :     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
     366           0 :     if (blockCount>0 && (bufferSize=FillOutputBuffer(evtData.fEventID, fWriters[writerNo], pBuffer))>0) {
     367           0 :       fReservedWriter=writerNo;
     368           0 :       fReservedData=bufferSize;
     369           0 :     }
     370           0 :     fWriters[writerNo]->Clear();
     371           0 :   } else if (iResult>=0 && !bIsDataEvent && fNofDDLs<2 && blockCount>0) {
     372           0 :     HLTWarning("ignoring %d block(s) for special event of type %d: at least 2 DDLs are required", blockCount, eventType);
     373             :   }
     374             : 
     375           0 :   if (iResult>=0 && bIsDataEvent) {
     376           0 :     iResult=Write(GetEventCount());
     377           0 :   }
     378             : 
     379           0 :   if (fRoundRobinCounter>=0) {
     380           0 :     if (++fRoundRobinCounter>=fNofDDLs) fRoundRobinCounter=0;
     381             :   }
     382             : 
     383           0 :   return iResult;
     384           0 : }
     385             : 
     386             : int AliHLTOUTComponent::Write(int eventNo)
     387             : {
     388             :   // write digits and raw files for the current event
     389             :   int iResult=0;
     390             : 
     391           0 :   if (fWriters.size()==0) return 0;
     392             : 
     393           0 :   if (fReservedWriter>=0) {
     394           0 :     if (fOptions&kWriteDigits) WriteDigitArray(fReservedWriter, &fBuffer[0], fReservedData);
     395           0 :     if (fOptions&kWriteRawFiles) WriteRawFile(eventNo, fReservedWriter, &fBuffer[0], fReservedData);
     396           0 :     fReservedData=0;
     397           0 :   }
     398             : 
     399             :   // search for the writer with the biggest data volume in order to allocate the
     400             :   // output buffer of sufficient size
     401           0 :   vector<int> sorted;
     402           0 :   for (size_t i=0; i<fWriters.size(); i++) {
     403           0 :     if ((int)i==fReservedWriter) continue;    
     404           0 :     assert(fWriters[i]);
     405           0 :     if (fWriters[i]) {
     406           0 :       if (sorted.size()==0 || fWriters[i]->GetTotalMemorySize()<=fWriters[sorted[0]]->GetTotalMemorySize()) {
     407           0 :         sorted.push_back(i);
     408             :       } else {
     409           0 :         sorted.insert(sorted.begin(), i);
     410             :       }
     411             :     }
     412             :   }
     413           0 :   fReservedWriter=-1;
     414             : 
     415           0 :   vector<int>::iterator ddlno=sorted.begin();
     416           0 :   while (ddlno!=sorted.end()) {
     417           0 :     const AliHLTUInt8_t* pBuffer=NULL;
     418             :     int bufferSize=0;
     419             :     
     420           0 :     if ((bufferSize=FillOutputBuffer(eventNo, fWriters[*ddlno], pBuffer))>0) {
     421           0 :       if (fOptions&kWriteDigits) WriteDigitArray(*ddlno, pBuffer, bufferSize);
     422           0 :       if (fOptions&kWriteRawFiles &&
     423           0 :           (fRoundRobinCounter<0 || fRoundRobinCounter==*ddlno))
     424           0 :         WriteRawFile(eventNo, *ddlno, pBuffer, bufferSize);
     425             :     }
     426           0 :     fWriters[*ddlno]->Clear();
     427           0 :     ddlno++;
     428           0 :   }
     429           0 :   if (fOptions&kWriteDigits) WriteDigits(eventNo);
     430             :   return iResult;
     431           0 : }
     432             : 
     433             : int AliHLTOUTComponent::ShuffleWriters(AliHLTMonitoringWriterPVector &list, AliHLTUInt32_t /*size*/)
     434             : {
     435             :   /// get a writer for the next block
     436             :   /// in round robin mode (like the online HLTOUT) all blocks of one event go to the same link
     437             :   /// this is now also the default behavior of the HLTOUTComponent and indicated by
     438             :   /// fRoundRobinCounter>=0
     439             :   /// Writers are selected randomly otherwise.
     440           0 :   if (fRoundRobinCounter>=0) {
     441           0 :     if (fRoundRobinCounter==fReservedWriter) {
     442           0 :       if (++fRoundRobinCounter>=fNofDDLs) fRoundRobinCounter=0;
     443           0 :       if (fRoundRobinCounter==fReservedWriter) {
     444           0 :         HLTWarning("there are not enough links to use a reserved writer, discarding data in reserved writer %d (total %d)",
     445             :                    fReservedWriter, fNofDDLs);
     446           0 :         fReservedWriter=-1;
     447           0 :       }
     448             :     }
     449           0 :     return fRoundRobinCounter;
     450             :   }
     451             : 
     452             :   int iResult=-ENOENT;
     453           0 :   assert(list.size()>0);
     454           0 :   if (list.size()==0) return iResult;
     455           0 :   vector<int> writers;
     456             :   size_t i=0;
     457           0 :   for (i=0; i<list.size(); i++) {
     458           0 :     if ((int)i==fReservedWriter) continue;
     459           0 :     if (list[i]->GetTotalMemorySize()==0)
     460           0 :       writers.push_back(i);
     461           0 :     else if (iResult<0 ||
     462           0 :              list[i]->GetTotalMemorySize()<list[iResult]->GetTotalMemorySize())
     463           0 :       iResult=i;
     464             :       
     465             :   }
     466           0 :   if (writers.size()>0) {
     467           0 :     iResult=writers[0];
     468           0 :     if (writers.size()>0) {
     469             :       // shuffle among the empty writers
     470           0 :       TDatime dt;
     471           0 :       TRandom rand;
     472           0 :       rand.SetSeed(dt.Get()*(iResult+1));
     473           0 :       i=rand.Integer(writers.size()-1);
     474           0 :       assert(i>0 && i<writers.size()-1);
     475           0 :       iResult=writers[i];
     476           0 :     }
     477             :   } else {
     478             :     // take the writer with the least data volume
     479           0 :     assert(iResult>=0);
     480             :   }
     481             :   return iResult;
     482           0 : }
     483             : 
     484             : int AliHLTOUTComponent::FillOutputBuffer(int eventNo, AliHLTMonitoringWriter* pWriter, const AliHLTUInt8_t* &pBuffer)
     485             : {
     486             :   // prepare the output buffer for writing, consists of
     487             :   // - CDH
     488             :   // - HLTOUT header
     489             :   // - HOMER data
     490             :   // buffer is allocated internally and data is valid until next call
     491             :   int iResult=0;
     492             :   unsigned int bufferSize=0;
     493             : 
     494             :   // space for common data header
     495             :   bufferSize+=sizeof(AliRawDataHeaderV3);
     496             : 
     497             :   // space for HLT event header
     498             :   bufferSize+=sizeof(AliHLTOUT::AliHLTOUTEventHeader);
     499             : 
     500             :   // space for payload from the writer
     501           0 :   if (pWriter) bufferSize+=pWriter->GetTotalMemorySize();
     502             : 
     503             :   // payload data must be aligned to 32bit
     504           0 :   bufferSize=(bufferSize+3)/4;
     505           0 :   bufferSize*=4;
     506             : 
     507           0 :   if (bufferSize>fBuffer.size())
     508           0 :     fBuffer.resize(bufferSize);
     509             : 
     510             :   // reset the last 32bit word, rest will be overwritten
     511           0 :   memset(&fBuffer[bufferSize-4], 0, 4);
     512             : 
     513           0 :   if (bufferSize<=fBuffer.size()) {
     514           0 :     AliRawDataHeaderV3* pCDH=reinterpret_cast<AliRawDataHeaderV3*>(&fBuffer[0]);
     515           0 :     AliHLTOUT::AliHLTOUTEventHeader* pHLTH=reinterpret_cast<AliHLTOUT::AliHLTOUTEventHeader*>(&fBuffer[sizeof(AliRawDataHeaderV3)]);
     516           0 :     *pCDH = AliRawDataHeaderV3();  // Fill with default values.
     517           0 :     memset(pHLTH, 0, sizeof(AliHLTOUT::AliHLTOUTEventHeader));
     518             : 
     519           0 :     if (pWriter) {
     520             :       // copy payload
     521           0 :       pWriter->Copy(&fBuffer[sizeof(AliRawDataHeaderV3)+sizeof(AliHLTOUT::AliHLTOUTEventHeader)], 0, 0, 0, 0);
     522           0 :       pHLTH->fLength=pWriter->GetTotalMemorySize();
     523             :       // set status bit to indicate HLT payload
     524           0 :       pCDH->fStatusMiniEventID|=0x1<<(AliHLTOUT::kCDHStatusFlagsOffset+AliHLTOUT::kCDHFlagsHLTPayload);
     525           0 :     }
     526           0 :     pHLTH->fLength+=sizeof(AliHLTOUT::AliHLTOUTEventHeader);
     527             :     // pHLTH->fEventIDLow is already set to zero in memset above.
     528           0 :     pHLTH->fEventIDLow = eventNo;
     529             :     // version does not really matter since we do not add decision data
     530           0 :     pHLTH->fVersion=AliHLTOUT::kVersion1;
     531             : 
     532           0 :     pCDH->fSize=bufferSize;
     533           0 :     pCDH->fStatusMiniEventID|=0x1<<(AliHLTOUT::kCDHStatusFlagsOffset + AliHLTOUT::kCDHFlagsHLTPayload);
     534             :     
     535           0 :     pBuffer=&fBuffer[0];
     536             :     iResult=(int)bufferSize;
     537           0 :   } else {
     538           0 :     pBuffer=NULL;
     539             :     iResult=-ENOMEM;
     540             :   }
     541             : 
     542           0 :   return iResult;
     543             : }
     544             : 
     545             : int AliHLTOUTComponent::WriteDigitArray(int hltddl, const AliHLTUInt8_t* pBuffer, unsigned int bufferSize)
     546             : {
     547             :   // wite a buffer to the associated digit array
     548             :   int iResult=0;
     549           0 :   assert(hltddl<fNofDDLs);
     550           0 :   if (hltddl>=fNofDDLs) return -ERANGE;
     551             : 
     552           0 :   if (!fppDigitArrays) {
     553           0 :     fppDigitArrays=new TArrayC*[fNofDDLs];
     554           0 :     if (fppDigitArrays) {
     555           0 :       for (int i=0; i<fNofDDLs; i++) {
     556           0 :         fppDigitArrays[i]=new TArrayC(0);
     557             :       }
     558           0 :     }
     559             :   }
     560           0 :   if (fppDigitArrays && fppDigitArrays[hltddl]) {
     561           0 :     fppDigitArrays[hltddl]->Set(bufferSize, reinterpret_cast<const Char_t*>(pBuffer));
     562           0 :   } else {
     563             :     iResult=-ENOMEM;    
     564             :   }
     565           0 :   return iResult;
     566           0 : }
     567             : 
     568             : int AliHLTOUTComponent::WriteDigits(int /*eventNo*/)
     569             : {
     570             :   // fill tree with digit arrays and write to file
     571             :   // all links must be written, even in round robin mode, where all links but one
     572             :   // do not contain any data blocks.
     573             :   // This is a limitation of storing the links in a tree
     574             :   int iResult=0;
     575           0 :   if (!fpDigitFile) {
     576           0 :     fpDigitFile=new TFile(fDigitFileName, "RECREATE");
     577           0 :   }
     578           0 :   if (fpDigitFile && !fpDigitFile->IsZombie()) {
     579           0 :     if (!fpDigitTree) {
     580           0 :       fpDigitTree=new TTree("rawhltout","HLTOUT raw data");
     581           0 :       if (fpDigitTree && fppDigitArrays) {
     582           0 :         for (int i=0; i<fNofDDLs; i++) {
     583           0 :           const char* branchName=AliDAQ::DdlFileName("HLT", i);
     584           0 :           if (fppDigitArrays[i]) fpDigitTree->Branch(branchName, "TArrayC", &fppDigitArrays[i], 32000/*just as the default*/, 0);
     585             :         }
     586           0 :       }
     587             :     }
     588           0 :     if (fpDigitTree) {
     589             : #ifdef __DEBUG
     590             :       int res=fpDigitTree->Fill();
     591             :       HLTDebug("writing digit tree: %d", res);
     592             :       fpDigitFile->cd();
     593             :       res=fpDigitTree->Write("",TObject::kOverwrite);
     594             :       HLTDebug("writing digit tree: %d", res);
     595             : #else
     596           0 :       fpDigitTree->Fill();
     597           0 :       fpDigitFile->cd();
     598           0 :       fpDigitTree->Write("",TObject::kOverwrite);
     599             : #endif
     600           0 :       if (fppDigitArrays) for (int i=0; i<fNofDDLs; i++) {
     601           0 :         if (fppDigitArrays[i]) fppDigitArrays[i]->Set(0);
     602           0 :       }
     603             :     }
     604             :   } else {
     605             :     const char* errorMsg="";
     606           0 :     if (GetEventCount()==5) {
     607             :       errorMsg=" (suppressing further error messages)";
     608           0 :     }
     609           0 :     if (GetEventCount()<5) {
     610           0 :       HLTError("can not open HLT digit file %s%s", fDigitFileName.Data(), errorMsg);
     611             :     }
     612             :     iResult=-EBADF;
     613             :   }
     614           0 :   return iResult;
     615           0 : }
     616             : 
     617             : int AliHLTOUTComponent::WriteRawFile(int eventNo, int hltddl, const AliHLTUInt8_t* pBuffer, unsigned int bufferSize)
     618             : {
     619             :   // write buffer to raw file in the current directory
     620             :   // creates the event raw directories in the current directory
     621             :   int iResult=0;
     622           0 :   const char* fileName=AliDAQ::DdlFileName("HLT", hltddl);
     623           0 :   assert(fileName!=NULL);
     624           0 :   TString filePath;
     625           0 :   filePath.Form("raw%d/", eventNo);
     626           0 :   if (gSystem->AccessPathName(filePath)!=0) {
     627             :     // note: AccessPathName return 0 if the path is existing
     628           0 :     TString command="mkdir "; command+=filePath;
     629           0 :     gSystem->Exec(command);
     630           0 :   }
     631           0 :   filePath+=fileName;
     632           0 :   if (fileName) {
     633             :     ios::openmode filemode=(ios::openmode)0;
     634           0 :     ofstream rawfile(filePath.Data(), filemode);
     635           0 :     if (rawfile.good()) {
     636           0 :       if (pBuffer && bufferSize>0) {
     637           0 :         rawfile.write(reinterpret_cast<const char*>(pBuffer), bufferSize);
     638             :       } else {
     639           0 :         HLTWarning("writing zero length raw data file %s");
     640             :       }
     641             :       HLTDebug("wrote %d byte(s) to file %s", bufferSize, filePath.Data());
     642             :     } else {
     643           0 :       HLTError("can not open file %s for writing", filePath.Data());
     644             :       iResult=-EBADF;
     645             :     }
     646           0 :     rawfile.close();
     647           0 :   }
     648             :   return iResult;
     649           0 : }
     650             : 
     651             : void AliHLTOUTComponent::SetGlobalOption(unsigned int options)
     652             : {
     653             :   // set the global options
     654           0 :   fgOptions|=options;
     655           0 : }
     656             : 
     657             : void AliHLTOUTComponent::ClearGlobalOption(unsigned int options)
     658             : {
     659             :   // reset the global options
     660           0 :   fgOptions&=~options;
     661           0 : }
     662             : 
     663             : bool AliHLTOUTComponent::TestGlobalOption(unsigned int option)
     664             : {
     665             :   // check option
     666           0 :   return (fgOptions&option)!=0;
     667             : }

Generated by: LCOV version 1.11