//* provided "as is" without express or implied warranty. *
//**************************************************************************
-/** @file AliHLTOUTComponent.cxx
- @author Matthias Richter
- @date
- @brief The HLTOUT data sink component similar to HLTOUT nodes
-*/
+// @file AliHLTOUTComponent.cxx
+// @author Matthias Richter
+// @date
+// @brief The HLTOUT data sink component similar to HLTOUT nodes
+// @note Used in the AliRoot environment only.
#if __GNUC__>= 3
using namespace std;
#include "AliHLTOUT.h"
#include "AliHLTHOMERLibManager.h"
#include "AliHLTHOMERWriter.h"
+#include "AliHLTErrorGuard.h"
#include "AliDAQ.h" // equipment Ids
#include "AliRawDataHeader.h" // Common Data Header
#include <TDatime.h> // seed for TRandom
#include <TFile.h>
#include <TTree.h>
#include <TArrayC.h>
+#include <TSystem.h>
/** ROOT macro for the implementation of ROOT specific class methods */
ClassImp(AliHLTOUTComponent)
-AliHLTOUTComponent::AliHLTOUTComponent()
- :
- AliHLTOfflineDataSink(),
- fWriters(),
- fNofDDLs(10),
- fIdFirstDDL(7680), // 0x1e<<8
- fBuffer(),
- fpLibManager(NULL),
- fpDigitFile(NULL),
- fpDigitTree(NULL),
- fppDigitArrays(NULL),
- fReservedWriter(-1),
- fReservedData(0)
+AliHLTOUTComponent::AliHLTOUTComponent(EType type)
+ : AliHLTOfflineDataSink()
+ , fWriters()
+ , fNofDDLs(10)
+ , fIdFirstDDL(7680) // 0x1e<<8
+ , fBuffer()
+ , fpLibManager(NULL)
+ , fOptions(0)
+ , fDigitFileName("HLT.Digits.root")
+ , fpDigitFile(NULL)
+ , fpDigitTree(NULL)
+ , fppDigitArrays(NULL)
+ , fReservedWriter(-1)
+ , fReservedData(0)
+ , fType(type)
{
// see header file for class documentation
// or
assert(fIdFirstDDL==AliDAQ::DdlIDOffset("HLT"));
fIdFirstDDL=AliDAQ::DdlIDOffset("HLT");
*/
+
+ if (fType!=kGlobal && fType!=kDigits && fType!=kRaw) {
+ ALIHLTERRORGUARD(1, "invalid component type %d", fType);
+ }
}
int AliHLTOUTComponent::fgOptions=kWriteRawFiles|kWriteDigits;
const char* AliHLTOUTComponent::GetComponentID()
{
// see header file for class documentation
- return "HLTOUT";
+ switch (fType) {
+ case kDigits: return "HLTOUTdigits";
+ case kRaw: return "HLTOUTraw";
+ case kGlobal:
+ default:
+ return "HLTOUT";
+ }
+ return NULL;
}
void AliHLTOUTComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
AliHLTComponent* AliHLTOUTComponent::Spawn()
{
// see header file for class documentation
- return new AliHLTOUTComponent;
+ return new AliHLTOUTComponent(fType);
}
int AliHLTOUTComponent::DoInit( int argc, const char** argv )
{
// see header file for class documentation
int iResult=0;
- TString argument="";
- int bMissingParam=0;
- for (int i=0; i<argc && iResult>=0; i++) {
- argument=argv[i];
- if (argument.IsNull()) continue;
-
- // -links
- if (argument.CompareTo("-links")==0) {
- if ((bMissingParam=(++i>=argc))) break;
- TString parameter(argv[i]);
- parameter.Remove(TString::kLeading, ' '); // remove all blanks
- if (parameter.IsDigit()) {
- fNofDDLs=parameter.Atoi();
- } else {
- HLTError("wrong parameter for argument %s, number expected", argument.Data());
- iResult=-EINVAL;
- }
- } else {
- HLTError("unknown argument %s", argument.Data());
- iResult=-EINVAL;
- break;
- }
- }
- if (bMissingParam) {
- HLTError("missing parameter for argument %s", argument.Data());
- iResult=-EINVAL;
- }
- if (iResult>=0) {
+
+ switch (fType) {
+ case kDigits:
+ fOptions|=kWriteDigits; fOptions&=~kWriteRawFiles;
+ HLTInfo("initializing HLTOUT component for digits generation");
+ break;
+ case kRaw:
+ fOptions|=kWriteRawFiles; fOptions&=~kWriteDigits;
+ HLTInfo("initializing HLTOUT component for raw data generation");
+ break;
+ case kGlobal:
+ default:
+ fOptions=fgOptions;
}
+ if ((iResult=ConfigureFromArgumentString(argc, argv))<0) return iResult;
+
+ // Make sure there is no library manager before we try and create a new one.
+ if (fpLibManager) {
+ delete fpLibManager;
+ fpLibManager=NULL;
+ }
+
+ // Create a new library manager and allocate the appropriate number of
+ // HOMER writers for the HLTOUT component.
fpLibManager=new AliHLTHOMERLibManager;
if (fpLibManager) {
int writerNo=0;
return iResult;
}
+int AliHLTOUTComponent::ScanConfigurationArgument(int argc, const char** argv)
+{
+ // see header file for class documentation
+ if (argc<=0) return 0;
+ int i=0;
+ TString argument=argv[i];
+ const char* key="";
+
+ // -links n
+ // specify number of ddl links
+ if (argument.CompareTo("-links")==0) {
+ if (++i>=argc) return -EPROTO;
+ TString parameter(argv[i]);
+ parameter.Remove(TString::kLeading, ' '); // remove all blanks
+ if (parameter.IsDigit()) {
+ fNofDDLs=parameter.Atoi();
+ } else {
+ HLTError("wrong parameter for argument %s, number expected", argument.Data());
+ return -EINVAL;
+ }
+
+ return 2;
+ }
+
+ // -digitfile name
+ if (argument.CompareTo("-digitfile")==0) {
+ if (++i>=argc) return -EPROTO;
+ fDigitFileName=argv[i];
+
+ return 2;
+ }
+
+ // -rawout
+ key="-rawout";
+ if (argument.Contains(key)) {
+ argument.ReplaceAll(key, "");
+ if (argument.IsNull()) {
+ fOptions|=kWriteRawFiles;
+ } else if (argument.CompareTo("=off")==0) {
+ fOptions&=~kWriteRawFiles;
+ } else if (argument.CompareTo("=on")==0) {
+ fOptions|=kWriteRawFiles;
+ } else {
+ HLTError("invalid parameter for argument %s: possible %s=off/%s=on", key, key, key);
+ return -EPROTO;
+ }
+
+ return 1;
+ }
+
+ // -digitout
+ key="-digitout";
+ if (argument.Contains(key)) {
+ argument.ReplaceAll(key, "");
+ if (argument.IsNull()) {
+ fOptions|=kWriteDigits;
+ } else if (argument.CompareTo("=off")==0) {
+ fOptions&=~kWriteDigits;
+ } else if (argument.CompareTo("=on")==0) {
+ fOptions|=kWriteDigits;
+ } else {
+ HLTError("invalid parameter for argument %s: possible %s=off/%s=on", key, key, key);
+ return -EPROTO;
+ }
+
+ return 1;
+ }
+
+ // unknown argument
+ return -EINVAL;
+}
+
int AliHLTOUTComponent::DoDeinit()
{
// see header file for class documentation
assert(*element);
// wanted to have a dynamic_cast<AliHLTHOMERWriter*> here, but this results into
// undefined symbol when loading the library
- (*element)->Clear();
- if (*element!=NULL) fpLibManager->DeleteWriter((AliHLTHOMERWriter*)(*element));
+ if (*element!=NULL) {
+ (*element)->Clear();
+ fpLibManager->DeleteWriter((AliHLTHOMERWriter*)(*element));
+ } else {
+ HLTError("writer instance is NULL");
+ }
element=fWriters.erase(element);
}
}
+ if (fpLibManager) {
+ delete fpLibManager;
+ fpLibManager=NULL;
+ }
if (fpDigitTree) {
delete fpDigitTree;
int iResult=0;
HLTInfo("write %d output block(s)", evtData.fBlockCnt);
int writerNo=0;
+ int blockCount=0;
AliHLTUInt32_t eventType=gkAliEventTypeUnknown;
bool bIsDataEvent=IsDataEvent(&eventType);
if (iResult>=0) {
// different fields in the homer header, which is an array of 64 bit
// words.
fWriters[writerNo]->AddBlock(homerHeader, blocks[n].fPtr);
+ blockCount++;
}
}
- if (iResult>=0 && !bIsDataEvent) {
+ if (iResult>=0 && !bIsDataEvent && fNofDDLs>=2) {
// data blocks from a special event are kept to be added to the
- // following event.
+ // following event. In the current implementation at least 2 DDLs
+ // are required to allow to keep the blocks of the SOR event and
+ // include it in the first event. If only one writer is available
+ // the blocks are ignored. For the moment this is not expexted to
+ // be a problem since components should not gererate anything on
+ // SOR/EOR. The only case is the list of AliHLTComponentTableEntry
+ // transmitted for component statistics in debug mode.
if (fReservedWriter>=0) {
HLTWarning("overriding previous buffer of non-data event data blocks");
}
// TODO: not yet clear whether it is smart to send the event id of
// this special event or if it should be set from the id of the
// following event where the data will be added
- if ((bufferSize=FillOutputBuffer(evtData.fEventID, fWriters[writerNo], pBuffer))>0) {
+ if (blockCount>0 && (bufferSize=FillOutputBuffer(evtData.fEventID, fWriters[writerNo], pBuffer))>0) {
fReservedWriter=writerNo;
fReservedData=bufferSize;
}
fWriters[writerNo]->Clear();
+ } else if (iResult>=0 && !bIsDataEvent && fNofDDLs<2 && blockCount>0) {
+ HLTWarning("ignoring %d block(s) for special event of type %d: at least 2 DDLs are required", blockCount, eventType);
+ }
+
+ if (iResult>=0 && bIsDataEvent) {
+ iResult=Write(GetEventCount(), GetRunLoader());
}
return iResult;
}
-int AliHLTOUTComponent::FillESD(int eventNo, AliRunLoader* runLoader, AliESDEvent* /*esd*/)
+
+int AliHLTOUTComponent::FillESD(int /*eventNo*/, AliRunLoader* /*runLoader*/, AliESDEvent* /*esd*/)
+{
+ // see header file for class documentation
+ // 2010-04-14 nothing to do any more. The data is written at the end of
+ // DumpEvent
+ return 0;
+}
+
+int AliHLTOUTComponent::Write(int eventNo, AliRunLoader* runLoader)
{
// see header file for class documentation
int iResult=0;
if (fWriters.size()==0) return 0;
-
+
if (fReservedWriter>=0) {
- if (fgOptions&kWriteDigits) WriteDigitArray(fReservedWriter, &fBuffer[0], fReservedData);
- if (fgOptions&kWriteRawFiles) WriteRawFile(eventNo, runLoader, fReservedWriter, &fBuffer[0], fReservedData);
+ if (fOptions&kWriteDigits) WriteDigitArray(fReservedWriter, &fBuffer[0], fReservedData);
+ if (fOptions&kWriteRawFiles) WriteRawFile(eventNo, runLoader, fReservedWriter, &fBuffer[0], fReservedData);
fReservedData=0;
}
int bufferSize=0;
if ((bufferSize=FillOutputBuffer(eventNo, fWriters[*ddlno], pBuffer))>0) {
- if (fgOptions&kWriteDigits) WriteDigitArray(*ddlno, pBuffer, bufferSize);
- if (fgOptions&kWriteRawFiles) WriteRawFile(eventNo, runLoader, *ddlno, pBuffer, bufferSize);
+ if (fOptions&kWriteDigits) WriteDigitArray(*ddlno, pBuffer, bufferSize);
+ if (fOptions&kWriteRawFiles) WriteRawFile(eventNo, runLoader, *ddlno, pBuffer, bufferSize);
}
fWriters[*ddlno]->Clear();
ddlno++;
}
- if (fgOptions&kWriteDigits) WriteDigits(eventNo, runLoader);
+ if (fOptions&kWriteDigits) WriteDigits(eventNo, runLoader);
return iResult;
}
// version does not really matter since we do not add decision data
pHLTH->fVersion=AliHLTOUT::kVersion1;
- pCDH->fSize=sizeof(AliRawDataHeader)+pHLTH->fLength;
+ pCDH->fSize=bufferSize;
pCDH->fStatusMiniEventID|=0x1<<(AliHLTOUT::kCDHStatusFlagsOffset + AliHLTOUT::kCDHFlagsHLTPayload);
pBuffer=&fBuffer[0];
{
// see header file for class documentation
int iResult=0;
- const char* digitFileName="HLT.Digits.root";
if (!fpDigitFile) {
- fpDigitFile=new TFile(digitFileName, "RECREATE");
+ fpDigitFile=new TFile(fDigitFileName, "RECREATE");
}
if (fpDigitFile && !fpDigitFile->IsZombie()) {
if (!fpDigitTree) {
}
}
if (fpDigitTree) {
+#ifdef __DEBUG
int res=fpDigitTree->Fill();
HLTDebug("writing digit tree: %d", res);
fpDigitFile->cd();
res=fpDigitTree->Write("",TObject::kOverwrite);
HLTDebug("writing digit tree: %d", res);
+#else
+ fpDigitTree->Fill();
+ fpDigitFile->cd();
+ fpDigitTree->Write("",TObject::kOverwrite);
+#endif
if (fppDigitArrays) for (int i=0; i<fNofDDLs; i++) {
if (fppDigitArrays[i]) fppDigitArrays[i]->Set(0);
}
errorMsg=" (suppressing further error messages)";
}
if (GetEventCount()<5) {
- HLTError("can not open HLT digit file %s%s", digitFileName, errorMsg);
+ HLTError("can not open HLT digit file %s%s", fDigitFileName.Data(), errorMsg);
}
iResult=-EBADF;
}
assert(fileName!=NULL);
TString filePath;
filePath.Form("raw%d/", eventNo);
+ if (gSystem->AccessPathName(filePath)) {
+ TString command="mkdir "; command+=filePath;
+ gSystem->Exec(command);
+ }
filePath+=fileName;
if (fileName) {
ios::openmode filemode=(ios::openmode)0;
// see header file for class documentation
fgOptions&=~options;
}
+
+bool AliHLTOUTComponent::TestGlobalOption(unsigned int option)
+{
+ // see header file for class documentation
+ return (fgOptions&option)!=0;
+}