const AliRawDataHeader* cdh = NULL;
if (AliHLTComponent::ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL) != 0) return (AliHLTUInt64_t)0;
+ if ((cdh->GetL1TriggerMessage() & 0x1) == 0x1) return 0x0; // invalid for software triggers.
// trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
AliHLTUInt64_t triggerMask = cdh->GetTriggerClasses();
return triggerMask;
const AliRawDataHeader* cdh = NULL;
if (AliHLTComponent::ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL, true) != 0) return false;
+ if ((cdh->GetL1TriggerMessage() & 0x1) == 0x1) return false; // invalid for software triggers.
// trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
AliHLTUInt64_t triggerMask = cdh->GetTriggerClasses();
const AliRawDataHeader* cdh = NULL;
int result = AliHLTComponent::ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL, true);
if (result != 0) return result;
+ if ((cdh->GetL1TriggerMessage() & 0x1) == 0x1) return 0; // invalid for software triggers.
// trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
AliHLTUInt64_t triggerMask = cdh->GetTriggerClasses();
const AliRawDataHeader* cdh = NULL;
if (AliHLTComponent::ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL, true) != 0) return AliHLTReadoutList();
+ if ((cdh->GetL1TriggerMessage() & 0x1) == 0x1) return AliHLTReadoutList(); // invalid for software triggers.
// trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
AliHLTUInt64_t triggerMask = cdh->GetTriggerClasses();
indexUpdtDCSEvent=i;
} else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
fEventType=fpInputBlocks[i].fSpecification;
+ if (fEventType != gkAliEventTypeConfiguration and
+ fEventType != gkAliEventTypeReadPreprocessor
+ )
+ {
+ // We can actually get the event type from the CDH if it is valid.
+ // Otherwise just use the specification of the input block.
+ const AliRawDataHeader* cdh;
+ if (ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL) == 0)
+ {
+ fEventType = ExtractEventTypeFromCDH(cdh);
+ }
+ }
// skip always in case of gkAliEventTypeConfiguration
if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
// see header file for function documentation
if (pTgt) *pTgt=fEventType;
return (fEventType==gkAliEventTypeData ||
- fEventType==gkAliEventTypeDataReplay ||
- fEventType==gkAliEventTypeCalibration);
+ fEventType==gkAliEventTypeDataReplay);
}
int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
return 0;
}
+AliHLTUInt32_t AliHLTComponent::ExtractEventTypeFromCDH(const AliRawDataHeader* cdh)
+{
+ // see header file for function documentation
+
+ UChar_t l1msg = cdh->GetL1TriggerMessage();
+ if ((l1msg & 0x1) == 0x0) return gkAliEventTypeData;
+ // The L2SwC bit must be one if we got here, i.e. l1msg & 0x1 == 0x1.
+ if (((l1msg >> 2) & 0xF) == 0xE) return gkAliEventTypeStartOfRun;
+ if (((l1msg >> 2) & 0xF) == 0xF) return gkAliEventTypeEndOfRun;
+ // Check the C1T bit to see if this is a calibration event,
+ // if not then it must be some other software trigger event.
+ if (((l1msg >> 6) & 0x1) == 0x1) return gkAliEventTypeCalibration;
+ return gkAliEventTypeSoftware;
+}
+
int AliHLTComponent::LoggingVarargs(AliHLTComponentLogSeverity severity,
const char* originClass, const char* originFunc,
const char* file, int line, ... ) const
* AliRawDataHeader* cdh;
* ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL);
* \endcode
- * @return the zero on success and one of the following error codes on failure.
+ * @return zero on success or one of the following error codes on failure.
* if a non-zero error code is returned then none of the output parameters are
* modified.
* \li -ENOENT The <i>trigData</i> structure size is wrong.
* [out] @param list The output readout list to fill.
* [in] @param printErrors If true then error messages are generated as necessary
* and suppressed otherwise.
- * @return the zero on success or one of the error codes returned by ExtractTriggerData.
+ * @return zero on success or one of the error codes returned by ExtractTriggerData.
*/
static int GetReadoutList(
const AliHLTComponentTriggerData& trigData, AliHLTReadoutList& list,
{
return ExtractTriggerData(trigData, NULL, NULL, NULL, &list, printErrors);
}
+
+ /**
+ * Extracts the event type from the given Common Data Header.
+ * [in] @param cdh The Common Data Header to extract the event type from.
+ * @return the event type code from the CDH.
+ */
+ static AliHLTUInt32_t ExtractEventTypeFromCDH(const AliRawDataHeader* cdh);
/**
* Stopwatch type for benchmarking.
* 14 Adding new data block type for HLT global trigger counters.
* Adding data block type for ESD content
* Adding data block type for forwarded component table blocks
+ * Adding new event type for software triggers.
*/
#define ALIHLT_DATA_TYPES_VERSION 14
const AliHLTUInt32_t gkAliEventTypeCorruptID=8;
/** Calibration eventType specification */
const AliHLTUInt32_t gkAliEventTypeCalibration=16;
+ /** Software eventType specification */
+ const AliHLTUInt32_t gkAliEventTypeSoftware=24;
/** DataReplay eventType specification */
const AliHLTUInt32_t gkAliEventTypeDataReplay=32;
/** Configuration eventType specification */
// reset and prepare for new data
fpHLTOUTTask->Reset();
}
- if (eventtype) {
- // TODO: translate RawReader event types into the HLT event types
- // this needs to be done after the analysis framework has been extended to
- // handle all different cases correctly
+ if (eventtype == 0) {
+ eventtype = gkAliEventTypeData;
}
- if ((iResult=ProcessTasks(i, trgMask, timestamp, gkAliEventTypeData))>=0) {
+ if ((iResult=ProcessTasks(i, trgMask, timestamp, eventtype))>=0) {
fGoodEvents++;
iCount++;
} else {
trigData.fStructSize=sizeof(trigData);
trigData.fDataSize=sizeof(AliHLTEventTriggerData);
memset(&evtTrigData, 0, trigData.fDataSize);
+ // Setup the CDH in the trigger data, based on the event type and CTP trigger.
evtTrigData.fCommonHeaderWordCnt=gkAliHLTCommonHeaderCount;
+ AliHLTUInt8_t l1msg = 0x0;
+ switch (eventType)
+ {
+ case gkAliEventTypeData: l1msg = 0x00; break;
+ case gkAliEventTypeDataReplay: l1msg = 0x00; break;
+ case gkAliEventTypeStartOfRun: l1msg = (0xE << 2) | 0x01; break;
+ case gkAliEventTypeEndOfRun: l1msg = (0xF << 2) | 0x01; break;
+ case gkAliEventTypeCalibration: l1msg = (0x1 << 6) | 0x01; break;
+ case gkAliEventTypeSoftware: l1msg = 0x01; break;
+ }
+ evtTrigData.fCommonHeader[1] = AliHLTUInt32_t(l1msg) << 14;
evtTrigData.fCommonHeader[5]=trgMask&0xffffffff;
trgMask>>=32;
evtTrigData.fCommonHeader[6]=trgMask&0x3ffff;
* just one trigger menu item in a priority group then the groups expressions are
* explicit. On the other hand, for multiple items in a group they form implicit
* expression fragments.
+ *
+ * \note CTP trigger class names can be used in the trigger menu since the global
+ * trigger will generate and add corresponding trigger decision objects to the
+ * logic on the fly.
+ * In addition, for software triggers, a special SOFTWARE trigger decision is
+ * generated and the SOFTWARE name can be used in the trigger menu for this.
+ * If the software trigger is a calibration event then a trigger decision with
+ * the name CALIBRATION is generated instead. START_OF_DATA and END_OF_DATA
+ * symbols are similarly defined for the start and end of data events respectively.
*/
class AliHLTTriggerMenu : public TObject
{
lib_LTLIBRARIES = libHLTbase.la
# version info for the library
-LIBRARY_VERSION = '9:0:0'
+LIBRARY_VERSION = '10:0:0'
# MODDIR is set by the AliRoot build system and denotes the topdir
# of the module, we must set it since the package definition libHLTbase.pkg
#include "AliCDBManager.h"
#include "AliCDBStorage.h"
#include "AliCDBEntry.h"
+#include "AliRawDataHeader.h"
#include "TUUID.h"
#include "TROOT.h"
#include "TSystem.h"
fDebugMode(false),
fRuntimeCompile(true),
fDeleteCodeFile(false),
+ fMakeSoftwareTriggers(true),
fCodeFileName(),
fClassName(),
fCTPDecisions(NULL),
fBits(0),
fDataEventsOnly(true),
fMonitorPeriod(-1),
- fUniqueID(0)
+ fUniqueID(0),
+ fSoftwareTrigger(true, "SOFTWARE"),
+ fTotalEventCounter(0)
{
// Default constructor.
fClassName = "";
fCodeFileName = "";
fDeleteCodeFile = false;
+ fMakeSoftwareTriggers = true;
const char* configFileName = NULL;
const char* codeFileName = NULL;
fIncludePaths.Clear();
}
continue;
}
+
+ if (strcmp(argv[i], "-dont-make-software-triggers") == 0)
+ {
+ fMakeSoftwareTriggers = false;
+ continue;
+ }
HLTError("Unknown option '%s'.", argv[i]);
return -EINVAL;
SetDescription(menu->DefaultDescription());
SetTriggerDomain(menu->DefaultTriggerDomain());
+ fTotalEventCounter = 0;
return 0;
}
if (pCTPData) {
AddCTPDecisions(fTrigger, pCTPData, GetTriggerData());
}
-
+
+ bool softwareTriggerIsValid = FillSoftwareTrigger();
+ if (softwareTriggerIsValid)
+ {
+ fTrigger->Add(&fSoftwareTrigger, kAliHLTDataTypeTriggerDecision, kAliHLTVoidDataSpec);
+ }
+
// Calculate the global trigger result and trigger domain, then create and push
// back the new global trigger decision object.
TString description;
);
decision.SetUniqueID(fUniqueID);
- decision.SetCounters(fTrigger->GetCounters(), GetEventCount()+1);
+ decision.SetCounters(fTrigger->GetCounters(), fTotalEventCounter+1);
if (fTrigger->CallFailed()) return -EPROTO;
TClonesArray shortInfo(TNamed::Class(), GetNumberOfInputBlocks());
// modifies the kCanDelete bit and nothing else.
if (!TestBit(kSkipCTP) && CTPData()) decision.AddInputObjectRef(const_cast<AliHLTCTPData*>(CTPData()));
+ if (softwareTriggerIsValid and TestBit(kIncludeInput)) decision.AddTriggerInput(fSoftwareTrigger);
+
static UInt_t lastTime=0;
TDatime time;
if (time.Get()-lastTime>60) {
if (fTrigger->CallFailed()) return -EPROTO;
return -ENOSPC;
}
+
+ ++fTotalEventCounter;
return 0;
}
}
+bool AliHLTGlobalTriggerComponent::FillSoftwareTrigger()
+{
+ // Fills the fSoftwareTrigger structure.
+ const AliRawDataHeader* cdh;
+ if (ExtractTriggerData(*GetTriggerData(), NULL, NULL, &cdh, NULL) != 0) return false;
+ UChar_t l1msg = cdh->GetL1TriggerMessage();
+ if ((l1msg & 0x1) == 0x0) return false; // skip physics events.
+ // From here on everything must be a software trigger.
+ if (((l1msg >> 2) & 0xF) == 0xE)
+ {
+ fSoftwareTrigger.Name("START_OF_DATA");
+ fSoftwareTrigger.Description("Generated internal start of data trigger.");
+ }
+ else if (((l1msg >> 2) & 0xF) == 0xF)
+ {
+ fSoftwareTrigger.Name("END_OF_DATA");
+ fSoftwareTrigger.Description("Generated internal end of data trigger.");
+ }
+ else if (((l1msg >> 6) & 0x1) == 0x1)
+ {
+ fSoftwareTrigger.Name("CALIBRATION");
+ fSoftwareTrigger.Description("Generated internal calibration trigger.");
+ }
+ else
+ {
+ fSoftwareTrigger.Name("SOFTWARE");
+ fSoftwareTrigger.Description("Generated internal software trigger.");
+ }
+ UInt_t detectors = cdh->GetSubDetectors();
+ fSoftwareTrigger.ReadoutList( AliHLTReadoutList(Int_t(detectors)) );
+ return true;
+}
+
+
int AliHLTGlobalTriggerComponent::PrintStatistics(const AliHLTGlobalTrigger* pTrigger, AliHLTComponentLogSeverity level, int offset) const
{
// print some statistics
/// @brief Declaration of the AliHLTGlobalTriggerComponent component class.
#include "AliHLTTrigger.h"
+#include "AliHLTTriggerDecision.h"
#include "TClonesArray.h"
class AliHLTTriggerMenu;
* \li -monitoring[=n] <br>
* enable monitoring trigger once every n seconds, enable for every event if
* parameter n is omitted
+ * \li -dont-make-software-triggers <br>
+ * This option prevents the Common Data Header from being interpreted to generate
+ * software event input triggers for the trigger menu. Normally the following default
+ * triggers are available in the trigger menu:
+ * START_OF_DATA - start of data event.
+ * END_OF_DATA - end of data event.
+ * SOFTWARE - general software trigger.
+ * CALIBRATION - calibration trigger.
+ * With this option these will not be automatically generated by the global trigger.
*
* <h2>Configuration:</h2>
* Configured from CDB but can be overridden with the -config argument.
/**
* Add trigger decisions according to the active CTP trigger classes
- * An internal TclonesArray holds the trigger decisions to be added. The trigger
+ * An internal TClonesArray holds the trigger decisions to be added. The trigger
* decisions are updated according to the active CTP trigger mask.
* \param pTrigger The instance of the global trigger
* \param pCTPData Instance of the CTP data
* \param trigData Current trigger data, if NULL, the active trigger data from the CTP data is used
*/
int AddCTPDecisions(AliHLTGlobalTrigger* pTrigger, const AliHLTCTPData* pCTPData, const AliHLTComponentTriggerData* trigData);
+
+ /**
+ * This method handles the software trigger by checking the Common Data Header
+ * and filling fSoftwareTrigger with appropriate information for one of the
+ * following triggers: START_OF_DATA, END_OF_DATA, SOFTWARE or CALIBRATION, if
+ * it is indicated in the CDH L1 trigger message.
+ * \returns true if the trigger decision object was filled and false otherwise.
+ */
+ bool FillSoftwareTrigger();
/**
* Print some statistics based on the trigger counters
bool fDebugMode; //! Indicates if the generated global trigger class should be in debug mode.
bool fRuntimeCompile; //! Indicates if the generated global trigger class should be compiled
bool fDeleteCodeFile; //! If true then the code file indicated by fCodeFileName should be deleted during DoDeinit.
+ bool fMakeSoftwareTriggers; //! Indicates if the software triggers should be filled automatically or not.
TString fCodeFileName; //! base file name of the generated code for the global trigger
TString fClassName; //! The generated/loaded trigger class name.
TClonesArray* fCTPDecisions; //! AliHLTTriggerDecision objects for the CTP classes
bool fDataEventsOnly; //! Flag indicating if only data events are processed with trigger logic.
int fMonitorPeriod; //! Period of the monitoring trigger in s, -1 means monitoring trigger off
UInt_t fUniqueID; //! Unique ID for the decision output objects.
+ AliHLTTriggerDecision fSoftwareTrigger; //! Software or calibration trigger decision object to be added to trigger logic.
+ AliHLTUInt64_t fTotalEventCounter; //! Counts the total number of events handled.
static const char* fgkTriggerMenuCDBPath; //! The path string to read the trigger menu from the CDB.
# increment age.
# 6. If any interfaces have been removed since the last public release, then
# set age to 0.
-LIBRARY_VERSION = '1:0:0'
+LIBRARY_VERSION = '2:0:0'
# library sources
# The source files are specified in libAliHLTTrigger.pkg
config.SetDefaultConditionOperator("&&");
}
+/**
+ * This will make a configuration that will test software triggers.
+ */
+void SoftwareTriggersTestConfig()
+{
+ AliHLTGlobalTriggerConfig config("Software triggers test config");
+ config.AddSymbol("domainPHOS", "AliHLTTriggerDomain", "", "AliHLTTriggerDomain(\"*******:PHOS\")");
+ config.AddSymbol("domainSPD", "AliHLTTriggerDomain", "", "AliHLTTriggerDomain(\"*******:SPD\")");
+ config.AddItem(5, "START_OF_DATA", "START_OF_DATA", "Start of data");
+ config.AddItem(4, "END_OF_DATA", "END_OF_DATA", "End of data");
+ config.AddItem(3, "SOFTWARE", "domainSPD", "Software trigger");
+ config.AddItem(2, "CALIBRATION", "domainPHOS", "Calibration trigger");
+ config.AddItem(1, "triggerMUON", "triggerMUON", "MUON trigger");
+}
+
/**
* Top level configuration routine for the global trigger component tests.
*/
case 2: PrescalarTestConfig(); break;
case 3: SymbolTestConfig(); break;
case 4: ComplexTestConfig(); break;
+ case 5: SoftwareTriggersTestConfig(); break;
default: AliHLTGlobalTriggerConfig config("Empty test config");
}
}
gSystem->Exec(command);
}
+/**
+ * Runs a global trigger test chain to test L0 software triggers.
+ * \param config The configuration version to pass to TriggerConfig.C
+ * \param usecint If true then the global trigger component uses CINT to interpret
+ * the code rather than compiling it.
+ * \param debug If true then the global trigger component generates extra debug
+ * statements in the on the fly AliHLTGlobalTriggerImp_*.cxx file.
+ * \param customClass Names the custom class that should be loaded from the file
+ * <i>\<customClass\>.cxx</i>. This is useful for debugging only. i.e. you can
+ * edit a generated logic file and test it by hand.
+ */
+void RunTriggerSW(int config = 0, bool usecint = false, bool debug = false, const char* customClass = NULL)
+{
+ AliHLTSystem sys;
+ sys.ScanOptions("ECS=CTP_TRIGGER_CLASS=00:TRIGGER-ALL:00-01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17");
+ sys.LoadComponentLibraries("libAliHLTUtil.so");
+ sys.LoadComponentLibraries("libAliHLTTRD.so");
+ sys.LoadComponentLibraries("libAliHLTMUON.so");
+ sys.LoadComponentLibraries("libAliHLTTrigger.so");
+ if (debug)
+ {
+ AliLog::SetGlobalLogLevel(AliLog::kMaxType);
+ sys.SetGlobalLoggingLevel(kHLTLogAll);
+ }
+
+ TString cmdline = "-datatype ROOTTOBJ 'HLT ' ";
+ for (int i = 1; i <= 8; i++)
+ {
+ if (i > 1) cmdline += " -nextevent";
+ cmdline += Form(" -datafile testInputFile%d.root", i);
+ }
+ AliHLTConfiguration pub("pub", "ROOTFilePublisher", NULL, cmdline.Data());
+
+ cmdline = Form("-config $ALICE_ROOT/HLT/trigger/test/TriggerConfig.C(%d)"
+ " -includepath $ALICE_ROOT/include -includepath $ALICE_ROOT/HLT/BASE"
+ " -includepath $ALICE_ROOT/HLT/trigger -include AliHLTEventSummary.h"
+ " -process-all-events",
+ config
+ );
+ if (customClass != NULL) cmdline += Form(" -usecode %s.cxx %s", customClass, customClass);
+ if (usecint) cmdline += " -cint";
+ if (debug) cmdline += " -debug";
+ AliHLTConfiguration proc("proc", "HLTGlobalTrigger", "pub", cmdline.Data());
+
+ AliHLTConfiguration sink("sink", "ROOTFileWriter", "proc", "-datafile testOutputFile.root -concatenate-events");
+
+ sys.BuildTaskList("sink");
+ sys.Run(
+ 1, // Number of events to process.
+ 0, // Stop chain at end of run.
+ 0x1, // Active CTP trigger mask.
+ 0, // Time stamp.
+ gkAliEventTypeSoftware // Event type.
+ );
+ sys.Run(
+ 1, // Number of events to process.
+ 0, // Stop chain at end of run.
+ 0x1, // Active CTP trigger mask.
+ 0, // Time stamp.
+ gkAliEventTypeCalibration // Event type.
+ );
+ sys.Run(
+ 1, // Number of events to process.
+ 1, // Stop chain at end of run.
+ 0x1, // Active CTP trigger mask.
+ 0, // Time stamp.
+ 0 // Event type.
+ );
+}
+
+/**
+ * This method calls the RunTriggerSW method in an independant aliroot process.
+ * This is necessary since we get memory corruption if we run too many instances of
+ * AliHLTSystem in the same process.
+ */
+void CallRunTriggerSW(
+ int config = 0, bool usecint = false, bool debug = false,
+ const char* customClass = NULL, bool showOutput = false
+ )
+{
+ const char* redirection = "> /dev/null";
+ const char* classNameString = "NULL";
+ if (showOutput) redirection = "";
+ if (customClass != NULL) classNameString = Form("\"%s\"", customClass);
+ const char* command = Form(
+ "aliroot %s <<EOF\n"
+ "gSystem->Load(\"libAliHLTUtil.so\");\n"
+ "gSystem->Load(\"libAliHLTTRD.so\");\n"
+ "gSystem->Load(\"libAliHLTMUON.so\");\n"
+ "gSystem->Load(\"libAliHLTTrigger.so\");\n"
+ "gSystem->SetIncludePath(\"-I${ALICE_ROOT}/include"
+ " -I${ALICE_ROOT}/HLT/BASE -I${ALICE_ROOT}/HLT/trigger\");\n"
+ ".L $ALICE_ROOT/HLT/trigger/test/testGlobalTriggerComponent.C+\n"
+ "RunTriggerSW(%d,%d,%d,%s);\n"
+ "EOF\n",
+ redirection,
+ config,
+ usecint,
+ debug,
+ classNameString
+ );
+ gSystem->Exec(command);
+}
+
/**
* Checks that a particular decision is as expected and prints error messages
* if it is not.
return true;
}
+/**
+ * This routine is used to check if the global Trigger counters are correct.
+ * \param testName The name of the test being run.
+ * \param eventNum The number of the event being checked.
+ * \param decision The global trigger decision being checked.
+ * \param expectedCounters The expected counters.
+ * \returns true if the decision is as expected.
+ */
+bool CheckCounters(
+ const char* testName,
+ int eventNum,
+ AliHLTGlobalTriggerDecision* decision,
+ const TArrayL64& expectedCounters
+ )
+{
+ if (decision->Counters().GetSize() != expectedCounters.GetSize())
+ {
+ cerr << "ERROR (Test: " << testName
+ << "): The result does not have the required number of counters for event "
+ << eventNum << ". Got " << decision->Counters().GetSize() << " but expected "
+ << expectedCounters.GetSize() << "." << endl;
+ return false;
+ }
+ for (Int_t i = 0; i < expectedCounters.GetSize(); ++i)
+ {
+ if (decision->Counters()[i] != expectedCounters[i])
+ {
+ cerr << "ERROR (Test: " << testName
+ << "): The result does not have the correct counter value for event "
+ << eventNum << ". Got a value " << decision->Counters()[i]
+ << " for counter " << i << ", but expected a value of "
+ << expectedCounters[i] << "." << endl;
+ return false;
+ }
+ }
+ return true;
+}
+
+/// Routine for checking the result of the SoftwareTriggersTestConfig() config in TriggerConfig.C
+bool CheckSoftwareTriggerTestConfig(const char* testName = "Software trigger config")
+{
+ AliHLTGlobalTriggerDecision* decision = NULL;
+ bool result = false;
+
+ AliHLTTriggerDomain domainPHOS("*******:PHOS");
+ domainPHOS.Remove(AliHLTReadoutList("PHOS"));
+ AliHLTTriggerDomain domainSPD("*******:SPD");
+ domainSPD.Remove(AliHLTReadoutList("ITSSPD"));
+ AliHLTTriggerDomain domainMUON("TRACKS:MUON");
+ domainMUON.Add(AliHLTReadoutList("MUONTRK MUONTRG"));
+
+ TFile* file = new TFile("testOutputFile.root", "READ");
+ TArrayL64 expectedCounters;
+ expectedCounters.Set(6);
+
+ decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;1"));
+ result = Check(testName, 1, decision, true, AliHLTTriggerDomain(), "Start of data");
+ if (! result) goto cleanup;
+ expectedCounters[0] = 1; expectedCounters[5] = 1;
+ result = CheckCounters(testName, 1, decision, expectedCounters);
+ if (! result) goto cleanup;
+
+ decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;2"));
+ result = Check(testName, 2, decision, true, domainSPD, "Software trigger");
+ if (! result) goto cleanup;
+ expectedCounters[2] = 1; expectedCounters[5] = 2;
+ result = CheckCounters(testName, 2, decision, expectedCounters);
+ if (! result) goto cleanup;
+
+ decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;3"));
+ result = Check(testName, 3, decision, true, domainPHOS, "Calibration trigger");
+ if (! result) goto cleanup;
+ expectedCounters[3] = 1; expectedCounters[5] = 3;
+ result = CheckCounters(testName, 3, decision, expectedCounters);
+ if (! result) goto cleanup;
+
+ decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;4"));
+ result = Check(testName, 4, decision, true, domainMUON, "MUON trigger");
+ if (! result) goto cleanup;
+ expectedCounters[4] = 1; expectedCounters[5] = 4;
+ result = CheckCounters(testName, 4, decision, expectedCounters);
+ if (! result) goto cleanup;
+
+ decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;5"));
+ result = Check(testName, 5, decision, true, AliHLTTriggerDomain(), "End of data");
+ if (! result) goto cleanup;
+ expectedCounters[1] = 1; expectedCounters[5] = 5;
+ result = CheckCounters(testName, 5, decision, expectedCounters);
+ if (! result) goto cleanup;
+
+ delete file;
+ return true;
+
+cleanup:
+ if (decision != NULL)
+ {
+ cout << "========== Dumping incorrect decision ========== " << endl;
+ decision->Print();
+ }
+ delete file;
+ return false;
+}
+
+/**
+ * This method performs the same task as for CheckDifferentModes, but trying to
+ * test the behaviour of the global HLT trigger component with L0 software triggers.
+ * \param version The trigger menu configuration version to use in <i>RunTrigger</i>.
+ * \param testName The name of the test being run.
+ * \param customClass Name of the custom class as passed to <i>RunTrigger</i>.
+ * \param showOutput If true then the output from the RunTriggerSW method is not suppressed.
+ * \returns true if the different checks succeeded and false otherwise.
+ */
+bool CheckDifferentSWTestModes(
+ int version, const char* testName,
+ const char* customClass = NULL, bool showOutput = false
+ )
+{
+ TString name = testName;
+ name += " in debug mode";
+ cout << "#################### Running test: " << name.Data() << " ####################" << endl;
+ CallRunTriggerSW(version, false, true, customClass, showOutput);
+ if (! CheckSoftwareTriggerTestConfig(testName)) return false;
+ gSystem->Exec("rm -f testOutputFile.root"); // Cleanup output file for next test.
+
+ name = testName;
+ cout << "#################### Running test: " << name.Data() << " ####################" << endl;
+ CallRunTriggerSW(version, false, false, customClass, showOutput);
+ if (! CheckSoftwareTriggerTestConfig(testName)) return false;
+ gSystem->Exec("rm -f testOutputFile.root"); // Cleanup output file for next test.
+
+ name = testName;
+ name += " interpreted with CINT in debug mode";
+ cout << "#################### Running test: " << name.Data() << " ####################" << endl;
+ CallRunTriggerSW(version, true, true, customClass, showOutput);
+ if (! CheckSoftwareTriggerTestConfig(testName)) return false;
+ gSystem->Exec("rm -f testOutputFile.root"); // Cleanup output file for next test.
+
+ name = testName;
+ name += " interpreted with CINT";
+ cout << "#################### Running test: " << name.Data() << " ####################" << endl;
+ CallRunTriggerSW(version, true, false, customClass, showOutput);
+ if (! CheckSoftwareTriggerTestConfig(testName)) return false;
+ gSystem->Exec("rm -f testOutputFile.root"); // Cleanup output file for next test.
+
+ return true;
+}
+
/**
* Runs several tests for the AliHLTGlobalTriggerComponent class.
* We specifically test if the global trigger menu configuration is interpreted
case 2: function = CheckPrescalarTestConfig; break;
case 3: function = CheckSymbolTestConfig; break;
case 4: function = CheckComplexTestConfig; break;
+ case 5: break;
default:
cerr << "ERROR: Invalid value for configVersion specified." << endl;
return false;
}
- bool result = CheckDifferentModes(
- function,
- configVersion,
- Form("Config version %d", configVersion),
- numOfEvents,
- customClass,
- true
- );
+ bool result = false;
+ if (configVersion != 5)
+ {
+ result = CheckDifferentModes(
+ function,
+ configVersion,
+ Form("Config version %d", configVersion),
+ numOfEvents,
+ customClass,
+ true
+ );
+ }
+ else
+ {
+ result = CheckDifferentSWTestModes(
+ configVersion,
+ Form("Config version %d", configVersion),
+ customClass,
+ true
+ );
+ }
return result;
}
if (! CheckDifferentModes(CheckPrescalarTestConfig, 2, "Prescalar config", numOfEvents, customClass)) return false;
if (! CheckDifferentModes(CheckSymbolTestConfig, 3, "Symbol config", numOfEvents, customClass)) return false;
if (! CheckDifferentModes(CheckComplexTestConfig, 4, "Complex config", numOfEvents, customClass)) return false;
+ if (! CheckDifferentSWTestModes(5, "Software trigger config", customClass)) return false;
// Cleanup all temporary files generated.
gSystem->Exec("rm -f testOutputFile.root testInputFile*.root AliHLTGlobalTriggerImpl*");