]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Adding trigger domain and trigger decision classes. AliHLTTrigger now produces an...
authoraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 27 Nov 2008 01:55:50 +0000 (01:55 +0000)
committeraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 27 Nov 2008 01:55:50 +0000 (01:55 +0000)
Also adding a skeleton class for the global HLT trigger component.
Cleaning up some documentation.

13 files changed:
HLT/libAliHLTTrigger.pkg
HLT/trigger/AliHLTDomainEntry.h
HLT/trigger/AliHLTGlobalTriggerComponent.cxx [new file with mode: 0644]
HLT/trigger/AliHLTGlobalTriggerComponent.h [new file with mode: 0644]
HLT/trigger/AliHLTGlobalTriggerDecision.cxx [new file with mode: 0644]
HLT/trigger/AliHLTGlobalTriggerDecision.h [new file with mode: 0644]
HLT/trigger/AliHLTReadoutList.h
HLT/trigger/AliHLTTrigger.cxx
HLT/trigger/AliHLTTrigger.h
HLT/trigger/AliHLTTriggerDecision.cxx [new file with mode: 0644]
HLT/trigger/AliHLTTriggerDecision.h [new file with mode: 0644]
HLT/trigger/AliHLTTriggerDomain.cxx [new file with mode: 0644]
HLT/trigger/AliHLTTriggerDomain.h [new file with mode: 0644]

index baa35c6b42b1ffe6cdc3deae5b19b34a839a0602..044d0f546b84b09960945d091b1fd9c62a906ae2 100644 (file)
 # will be created from the names of the header files
 CLASS_HDRS:= \
                 AliHLTTrigger.h                             \
+                AliHLTTriggerDecision.h                     \
+                AliHLTTriggerDomain.h                       \
+                AliHLTDomainEntry.h                         \
+                AliHLTReadoutList.h                         \
+                AliHLTGlobalTriggerDecision.h               \
+                AliHLTGlobalTriggerComponent.h              \
                 AliHLTTriggerAgent.h                        \
                 AliHLTEventSummary.h                        \
                 AliHLTEventSummaryProducerComponent.h       \
                 AliHLTRunSummary.h                          \
                 AliHLTRunSummaryProducerComponent.h         \
-               AliHLTTriggerSelectiveReadoutComponent.h    \
+                AliHLTTriggerSelectiveReadoutComponent.h    \
                 AliHLTTriggerMonitoringComponent.h
 
 
index 89bb7dee4dab3cfe8d042366c43fa5d696f50957..56da6b8978be22062ba8ec70d9220f8704557204 100644 (file)
 #include "TObject.h"
 #include "AliHLTDataTypes.h"
 
+/**
+ * \class AliHLTDomainEntry
+ * The AliHLTDomainEntry class is used to store information identifying a particular
+ * HLT internal data block, or set of data blocks using wild card values. This
+ * class is used by AliHLTTriggerDomain to store a list of data block classes
+ * that should be readout by the HLT. The information identifying a data block is
+ * the following:
+ *  - the data block type
+ *  - the data block's origin (detector name)
+ *  - the data block's specification (detector specific bits)
+ * Several useful operators and methods are defined to help manipulate this
+ * information in the AliHLTTriggerDomain class.
+ */
 class AliHLTDomainEntry : public TObject
 {
  public:
diff --git a/HLT/trigger/AliHLTGlobalTriggerComponent.cxx b/HLT/trigger/AliHLTGlobalTriggerComponent.cxx
new file mode 100644 (file)
index 0000000..0387d86
--- /dev/null
@@ -0,0 +1,58 @@
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        *
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ *                                                                        *
+ * Primary Authors: Artur Szostak <artursz@iafrica.com>                   *
+ *                  for The ALICE HLT Project.                            *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/// @file   AliHLTGlobalTriggerComponent.cxx
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date   26 Nov 2008
+/// @brief  Implementation of the AliHLTGlobalTriggerComponent component class.
+///
+/// The AliHLTGlobalTriggerComponentComponent class applies the global HLT trigger to all
+/// trigger information produced by components deriving from AliHLTTrigger.
+
+#include "AliHLTGlobalTriggerComponent.h"
+
+ClassImp(AliHLTGlobalTriggerComponent)
+
+
+AliHLTGlobalTriggerComponent::AliHLTGlobalTriggerComponent() :
+       AliHLTTrigger()
+{
+  // Default constructor.
+}
+
+
+AliHLTGlobalTriggerComponent::~AliHLTGlobalTriggerComponent()
+{
+  // Default destructor.
+}
+
+
+void AliHLTGlobalTriggerComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
+{
+  // Returns the output data size estimate.
+
+  constBase = strlen(GetTriggerName()) + 1;
+  inputMultiplier = 1;
+}
+
+
+int AliHLTGlobalTriggerComponent::DoTrigger()
+{
+  // This method will apply the global trigger decision.
+
+  //TODO
+  return 0;
+}
diff --git a/HLT/trigger/AliHLTGlobalTriggerComponent.h b/HLT/trigger/AliHLTGlobalTriggerComponent.h
new file mode 100644 (file)
index 0000000..75a8cde
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef ALIHLTGLOBALTRIGGERCOMPONENT_H
+#define ALIHLTGLOBALTRIGGERCOMPONENT_H
+/* This file is property of and copyright by the ALICE HLT Project        *
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ * See cxx source for full Copyright notice                               */
+
+/// @file   AliHLTGlobalTriggerComponent.h
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date   26 Nov 2008
+/// @brief  Declaration of the AliHLTGlobalTriggerComponent component class.
+
+#include "AliHLTTrigger.h"
+
+/**
+ * \class AliHLTGlobalTriggerComponent
+ * This class applies the global HLT trigger to all trigger information produced
+ * by components deriving from AliHLTTrigger.
+ * Any information delivered by other components in data blocks that contain
+ * TObjects can also be used for the trigger algorithm.
+ */
+class AliHLTGlobalTriggerComponent : public AliHLTTrigger
+{
+ public:
+  AliHLTGlobalTriggerComponent();
+  virtual ~AliHLTGlobalTriggerComponent();
+  
+  /**
+   * Inherited from AliHLTTrigger.
+   * @return string containing the global trigger name.
+   */
+  virtual const char* GetTriggerName() const { return "HLTGlobalTrigger"; };
+
+  /**
+   * Returns extra output data types this trigger generates.
+   * This returns an kAliHLTDataTypeTObject in <i>list</i>.
+   * @param list <i>[out]</i>: The list of data types to be filled.
+   */
+  virtual void GetOutputDataTypes(AliHLTComponentDataTypeList& list) const
+  {
+    list.push_back(kAliHLTDataTypeTObject);
+  }
+
+  /**
+   * Get a ratio by how much the data volume is shrunk or enhanced.
+   * The method returns a size proportional to the trigger name string length
+   * for constBase, and 1 for inputMultiplier.
+   * @param constBase        <i>[out]</i>: additive part, independent of the
+   *                                   input data volume  
+   * @param inputMultiplier  <i>[out]</i>: multiplication ratio
+   */
+  virtual void GetOutputDataSize(unsigned long& constBase, double& inputMultiplier);
+
+ protected:
+
+  /// Not implemented. Do not allow copying of this object.
+  AliHLTGlobalTriggerComponent(const AliHLTGlobalTriggerComponent& obj);
+  /// Not implemented. Do not allow copying of this object.
+  AliHLTGlobalTriggerComponent& operator = (const AliHLTGlobalTriggerComponent& obj);
+
+  /**
+   * Applies the global HLT trigger.
+   * @return Zero is returned on success and a negative error code on failure.
+   */
+  virtual int DoTrigger();
+  
+ private:
+  
+  ClassDef(AliHLTGlobalTriggerComponent, 0) // Global HLT trigger component class which produces the final trigger decision and readout list.
+};
+
+#endif // ALIHLTGLOBALTRIGGERCOMPONENT_H
+
diff --git a/HLT/trigger/AliHLTGlobalTriggerDecision.cxx b/HLT/trigger/AliHLTGlobalTriggerDecision.cxx
new file mode 100644 (file)
index 0000000..e4e7460
--- /dev/null
@@ -0,0 +1,92 @@
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        *
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ *                                                                        *
+ * Primary Authors: Artur Szostak <artursz@iafrica.com>                   *
+ *                  for The ALICE HLT Project.                            *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/// @file   AliHLTGlobalTriggerDecision.cxx
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date   26 Nov 2008
+/// @brief  Implementation of the AliHLTGlobalTriggerDecision class.
+/// 
+/// The global trigger decision class stores the global HLT decision.
+
+#include "AliHLTGlobalTriggerDecision.h"
+#include "Riostream.h"
+
+ClassImp(AliHLTGlobalTriggerDecision)
+
+
+AliHLTGlobalTriggerDecision::AliHLTGlobalTriggerDecision() :
+  AliHLTTriggerDecision(),
+  fContributingTriggers(AliHLTTriggerDecision::Class()),
+  fCounters()
+{
+  // Default constructor.
+}
+
+
+AliHLTGlobalTriggerDecision::AliHLTGlobalTriggerDecision(
+    bool result, const AliHLTReadoutList& readoutList,
+    const AliHLTTriggerDomain& triggerDomain, const char* description
+  ) :
+  AliHLTTriggerDecision(result, "HLTGlobalTrigger", readoutList, triggerDomain, description),
+  fContributingTriggers(AliHLTTriggerDecision::Class()),
+  fCounters()
+{
+  // Constructor specifying multiple information fields.
+  
+  Result(result);
+}
+
+
+AliHLTGlobalTriggerDecision::~AliHLTGlobalTriggerDecision()
+{
+  // Default destructor.
+}
+
+
+void AliHLTGlobalTriggerDecision::Print(Option_t* option) const
+{
+  // Prints the contents of the trigger decision.
+  
+  TString opt(option);
+  if (opt.Contains("short"))
+  {
+    cout << "Global ";
+    AliHLTTriggerDecision::Print(option);
+    cout << "==================== Input trigger decisions ====================";
+    for (Int_t i = 0; i < NumberOfTriggerInputs(); i++)
+    {
+      TriggerInput(i)->Print(option);
+    }
+  }
+  else
+  {
+    cout << "Global ";
+    AliHLTTriggerDecision::Print(option);
+    cout << "#################### Input trigger decisions ####################";
+    for (Int_t i = 0; i < NumberOfTriggerInputs(); i++)
+    {
+      cout << "-------------------- Input trigger decision " << i << " --------------------";
+      TriggerInput(i)->Print(option);
+    }
+    cout << "#################### Event class counters ####################";
+    cout << "Counter\tValue" << endl;
+    for (Int_t i = 0; i < fCounters.GetSize(); i++)
+    {
+      cout << i << "\t" << fCounters[i] << endl;
+    }
+  }
+}
+
diff --git a/HLT/trigger/AliHLTGlobalTriggerDecision.h b/HLT/trigger/AliHLTGlobalTriggerDecision.h
new file mode 100644 (file)
index 0000000..c9254d0
--- /dev/null
@@ -0,0 +1,89 @@
+#ifndef ALIHLTGLOBALTRIGGERDECISION_H
+#define ALIHLTGLOBALTRIGGERDECISION_H
+/* This file is property of and copyright by the ALICE HLT Project        *
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ * See cxx source for full Copyright notice                               */
+
+/// @file   AliHLTGlobalTriggerDecision.h
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date   26 Nov 2008
+/// @brief  Declaration of the AliHLTGlobalTriggerDecision class storing the global HLT decision.
+
+#include "AliHLTTriggerDecision.h"
+#include "TArrayL.h"
+
+class AliHLTGlobalTriggerDecision : public AliHLTTriggerDecision
+{
+ public:
+  
+  /**
+   * Default constructor.
+   */
+  AliHLTGlobalTriggerDecision();
+  
+  /**
+   * Constructor specifying multiple information fields.
+   * \param result  The result of the global trigger decision.
+   * \param readoutList  The DDL readout list for the global trigger decision.
+   * \param triggerDomain  The trigger domain for the global trigger decision.
+   * \param description  The description of (reason for) the global trigger decision.
+   */
+  AliHLTGlobalTriggerDecision(
+      bool result, const AliHLTReadoutList& readoutList,
+      const AliHLTTriggerDomain& triggerDomain, const char* description = ""
+    );
+  
+  /**
+   * Default destructor.
+   */
+  virtual ~AliHLTGlobalTriggerDecision();
+  
+  /**
+   * Inherited from TObject, this prints the contents of the trigger decision.
+   * \param option  Can be "short" which will print the short format.
+   */
+  virtual void Print(Option_t* option = "") const;
+  
+  /**
+   * Returns the number of trigger inputs that contributed to this global trigger decision.
+   */
+  Int_t NumberOfTriggerInputs() const { return fContributingTriggers.GetEntriesFast(); }
+  
+  /**
+   * Returns the i'th trigger input object in fContributingTriggers.
+   */
+  const AliHLTTriggerDecision* TriggerInput(Int_t i) const
+  {
+    return static_cast<const AliHLTTriggerDecision*>( fContributingTriggers[i] );
+  }
+  
+  /**
+   * Returns the list of trigger inputs used when making the global HLT trigger decision.
+   */
+  const TClonesArray& TriggerInputs() const { return fContributingTriggers; }
+  
+  /**
+   * Adds a trigger input to the list of triggers that were considered when making
+   * this global trigger decision.
+   * \param decision  The trigger decision object to add.
+   */
+  void AddTriggerInput(const AliHLTTriggerDecision& decision)
+  {
+    new (fContributingTriggers[fContributingTriggers.GetEntriesFast()]) AliHLTTriggerDecision(decision);
+  }
+  
+  /**
+   * Returns the event trigger counters associated with the global trigger classes.
+   */
+  const TArrayL& Counters() const { return fCounters; }
+  
+ private:
+  
+  TClonesArray fContributingTriggers;  /// The list of contributing trigger decisions from all AliHLTTrigger components that were considered.
+  TArrayL fCounters;  /// Event trigger counters. One counter for each trigger class in the global trigger.
+  
+  ClassDef(AliHLTGlobalTriggerDecision, 1) // Contains the HLT global trigger decision and information contributing to the decision.
+};
+
+#endif // ALIHLTGLOBALTRIGGERDECISION_H
+
index 7a9a01b4befe8772a215b9e8dba018ffc21e7f55..3117bcc5fe65672d240592eafdb09e9c82e5998d 100644 (file)
 #include "TObject.h"
 #include "AliHLTDataTypes.h"
 
+/**
+ * \class AliHLTReadoutList
+ * This class is used as an interface or wrapper to the AliHLTEventDDL structure.
+ * It makes it easy to manipulate the bits in this structure, which define what DDLs
+ * should be readout by DAQ.
+ * Several operators are also overloaded which are meant to be used in the trigger
+ * menu specification for the AliHLTGlobalTrigger. It allows one to construct
+ * expressions for the readout lists, which is necessary to be able to evaluate
+ * or compose the final readout list, given multiple input readout lists received
+ * from individual components that derive from AliHLTTrigger.
+ * The operators implemented are:
+ *  |  applies a bitwise or on the DDL bits.
+ *  &  applies a bitwise and on the DDL bits.
+ *  ^  applies a bitwise xor on the DDL bits.
+ *  ~  applies a bitwise not on the DDL bits.
+ *  +  synonym for the '|' operator.
+ *  -  unsets the bits in readout list A that are set in readout list B.
+ *      This effectively applies A & (A ^ B).
+ */
 class AliHLTReadoutList : public TObject
 {
  public:
index ed33337f379b493f8c78866f58989cbca879733a..49f4d8a8e9b058b57ce60b5af80eddbff99b913f 100644 (file)
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 
+/// @file   AliHLTTrigger.h
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date   12 Aug 2008
+/// @brief  Implementation of the AliHLTTrigger base component class.
+///
+/// The AliHLTTrigger class is the base class from which all HLT trigger components
+/// should be derived.
+
 #include "AliHLTTrigger.h"
-#include "TObjString.h"
+#include "AliHLTTriggerDecision.h"
 
 ClassImp(AliHLTTrigger)
 
@@ -26,7 +34,9 @@ AliHLTTrigger::AliHLTTrigger() :
        fTriggerData(NULL),
        fDecisionMade(false),
        fTriggerEventResult(0),
-       fReadoutList()
+       fDescription(),
+       fReadoutList(),
+       fTriggerDomain()
 {
   /// Default constructor sets pointers to NULL.
 }
@@ -42,7 +52,7 @@ void AliHLTTrigger::GetOutputDataSize(unsigned long& constBase, double& inputMul
 {
   /// Returns output data size estimate.
 
-  constBase = strlen(GetTriggerName()) + sizeof(TObjString) + 1;
+  constBase = sizeof(AliHLTTriggerDecision);
   inputMultiplier = 1;
 }
 
@@ -66,10 +76,6 @@ int AliHLTTrigger::DoEvent(const AliHLTComponentEventData& evtData, AliHLTCompon
     TriggerEvent(false);
   }
 
-//TODO
-//  result = PushBack(&fReadoutList, kAliHLTDataTypeTObject|kAliHLTDataOriginOut);
-//  if (result != 0) return result;
-
   // Cleanup
   fEventData = NULL;
   fTriggerData = NULL;
@@ -82,8 +88,7 @@ void AliHLTTrigger::TriggerEvent(bool value)
   /// Sets the trigger decision for the current event.
   
   if (fTriggerEventResult != 0) return;  // Do not do anything if a previous call failed.
-  TObjString triggerResult(GetTriggerName());
-  triggerResult.SetBit(BIT(14), value);  // Use bit 14 for the boolean decision.
+  AliHLTTriggerDecision triggerResult(value, GetTriggerName(), fReadoutList, fTriggerDomain, fDescription);
   fTriggerEventResult = PushBack(&triggerResult, kAliHLTDataTypeTObject|kAliHLTDataOriginOut);
 }
 
index 71e107d6602a12abc17e03d27f4d7eeb45480a34..64d8185ee9b4364868b9e5836fb7d13d94ce0c09 100644 (file)
@@ -1,11 +1,22 @@
 #ifndef ALIHLTTRIGGER_H
 #define ALIHLTTRIGGER_H
-/* This file is property of and copyright by the ALICE HLT Project        * 
+/* This file is property of and copyright by the ALICE HLT Project        *
  * ALICE Experiment at CERN, All rights reserved.                         *
  * See cxx source for full Copyright notice                               */
 
+/// @file   AliHLTTrigger.cxx
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date   12 Aug 2008
+/// @brief  Declaration of the AliHLTTrigger base component class.
+
 #include "AliHLTProcessor.h"
+#include "AliHLTReadoutList.h"
+#include "AliHLTTriggerDomain.h"
 
+/**
+ * \class AliHLTTrigger
+ * This is the base class from which all HLT trigger components should inherit.
+ */
 class AliHLTTrigger : public AliHLTProcessor
 {
  public:
@@ -40,15 +51,14 @@ class AliHLTTrigger : public AliHLTProcessor
    * Returns extra output data types this trigger generates.
    * This returns an empty list by default.
    * @param list <i>[out]</i>: The list of data types to be filled.
+   * \note The underlying non const version of GetOutputDataTypes adds the value
+   *    kAliHLTDataTypeTObject to the list.
    */
-  virtual void GetOutputDataTypes(AliHLTComponentDataTypeList& list) const
-  {
-    list.push_back(kAliHLTDataTypeTObject);
-  }
+  virtual void GetOutputDataTypes(AliHLTComponentDataTypeList& /*list*/) const {}
 
   /**
-   * Get a ratio by how much the data volume is shrinked or enhanced.
-   * The method returns a size proporional to the trigger name string length
+   * Get a ratio by how much the data volume is shrunk or enhanced.
+   * The method returns a size proportional to the trigger name string length
    * for constBase, and 1 for inputMultiplier.
    * @param constBase        <i>[out]</i>: additive part, independent of the
    *                                   input data volume  
@@ -65,7 +75,7 @@ class AliHLTTrigger : public AliHLTProcessor
 
   /**
    * This method needs to be implemented by child classes to implement the actual
-   * trigger algorithm. A possitive trigger decision is made by calling the TriggerEvent
+   * trigger algorithm. A positive trigger decision is made by calling the TriggerEvent
    * method with TriggerEvent(true), or TriggerEvent(false) for a negative result
    * (no trigger).
    * If the AliHLTComponentEventData structure is needed for the current event being
@@ -125,15 +135,48 @@ class AliHLTTrigger : public AliHLTProcessor
     AliHLTComponent::SetDDLBit(fReadoutList, ddlId, state);
   }
   
+  /**
+   * Returns the DDL readout list.
+   */
+  const AliHLTReadoutList& GetReadoutList() const { return fReadoutList; }
+
   /**
    * Returns the DDL readout list for modification by hand.
    */
-  const AliHLTEventDDL& GetReadoutList() const { return fReadoutList; }
+  AliHLTReadoutList& GetReadoutList() { return fReadoutList; }
 
   /**
-   * Returns the DDL readout list.
+   * Sets the readout list object.
+   * \param value  The new value to use for the readout list.
+   */
+  void SetReadoutList(const AliHLTReadoutList& value) { fReadoutList = value; }
+  
+  /**
+   * Returns the trigger domain object.
    */
-  AliHLTEventDDL& GetReadoutList() { return fReadoutList; }
+  const AliHLTTriggerDomain& GetTriggerDomain() const { return fTriggerDomain; }
+
+  /**
+   * Returns the trigger domain object for modification.
+   */
+  AliHLTTriggerDomain& GetTriggerDomain() { return fTriggerDomain; }
+
+  /**
+   * Sets the trigger domain object.
+   * \param value  The new value to use for the trigger domain.
+   */
+  void SetTriggerDomain(const AliHLTTriggerDomain& value) { fTriggerDomain = value; }
+  
+  /**
+   * Returns the trigger description string.
+   */
+  const char* GetDescription() const { return fDescription.Data(); }
+  
+  /**
+   * Sets the trigger description string.
+   * \param value  The new value to use for the description string.
+   */
+  void SetDescription(const char* value) { fDescription = value; }
 
  private:
  
@@ -155,21 +198,25 @@ class AliHLTTrigger : public AliHLTProcessor
   /**
    * Inherited from AliHLTComponent. This method is replaced with one that is
    * symmetric to GetInputDataTypes that returns void, so we make this method
-   * private.
+   * private. The list will always contain kAliHLTDataTypeTObject, including whatever
+   * values were added by the const version of GetOutputDataTypes.
    * @param list     list to receive the output data types.
    * @return the number of elements in the list.
    */
   virtual int GetOutputDataTypes(AliHLTComponentDataTypeList& list)
   {
-    GetOutputDataTypes(list);
+    const AliHLTTrigger* t = this; t->GetOutputDataTypes(list);
+    list.push_back(kAliHLTDataTypeTObject);
     return list.size();
   }
   
-  const AliHLTComponentEventData* fEventData; ///! Event data for the current event. Only valid inside DoTrigger.
-  AliHLTComponentTriggerData* fTriggerData; ///! Trigger data for the current event. Only valid inside DoTrigger.
-  bool fDecisionMade;  ///! Flag indicating if the trigger decision has been made for this trigger yet.
-  int fTriggerEventResult;  ///! Result returned by PushBack method in the TriggerEvent method.
-  AliHLTEventDDL fReadoutList; ///! The readout DDL list.
+  const AliHLTComponentEventData* fEventData; //! Event data for the current event. Only valid inside DoTrigger.
+  AliHLTComponentTriggerData* fTriggerData; //! Trigger data for the current event. Only valid inside DoTrigger.
+  bool fDecisionMade;  //! Flag indicating if the trigger decision has been made for this trigger yet.
+  int fTriggerEventResult;  //! Result returned by PushBack method in the TriggerEvent method.
+  TString fDescription;   //! The description to use for the trigger decision.
+  AliHLTReadoutList fReadoutList; //! The DDL readout list object for the current event being processed.
+  AliHLTTriggerDomain fTriggerDomain; //! The trigger domain object for the current event being processed.
   
   ClassDef(AliHLTTrigger, 0) // Base class for HLT triggers.
 
diff --git a/HLT/trigger/AliHLTTriggerDecision.cxx b/HLT/trigger/AliHLTTriggerDecision.cxx
new file mode 100644 (file)
index 0000000..f9aef3f
--- /dev/null
@@ -0,0 +1,87 @@
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        *
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ *                                                                        *
+ * Primary Authors: Artur Szostak <artursz@iafrica.com>                   *
+ *                  for The ALICE HLT Project.                            *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/// @file   AliHLTTriggerDecision.cxx
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date   21 Nov 2008
+/// @brief  Implementation of the AliHLTTriggerDecision class.
+/// 
+/// The trigger decision class stores the HLT decision from an AliHLTTrigger component.
+
+#include "AliHLTTriggerDecision.h"
+#include "Riostream.h"
+
+ClassImp(AliHLTTriggerDecision)
+
+
+AliHLTTriggerDecision::AliHLTTriggerDecision() :
+  TObject(),
+  fName(),
+  fDescription(),
+  fReadoutList(),
+  fTriggerDomain()
+{
+  // Default constructor.
+}
+
+
+AliHLTTriggerDecision::AliHLTTriggerDecision(bool result, const char* name) :
+  TObject(),
+  fName(name),
+  fDescription(),
+  fReadoutList(),
+  fTriggerDomain()
+{
+  // Constructor specifying the name and result of the trigger decision.
+  
+  Result(result);
+}
+
+
+AliHLTTriggerDecision::AliHLTTriggerDecision(
+    bool result, const char* name, const AliHLTReadoutList& readoutList,
+    const AliHLTTriggerDomain& triggerDomain, const char* description
+  ) :
+  TObject(),
+  fName(name),
+  fDescription(description),
+  fReadoutList(readoutList),
+  fTriggerDomain(triggerDomain)
+{
+  // Constructor specifying all information fields.
+  
+  Result(result);
+}
+
+
+AliHLTTriggerDecision::~AliHLTTriggerDecision()
+{
+  // Default destructor.
+}
+
+
+void AliHLTTriggerDecision::Print(Option_t* option) const
+{
+  // Prints the contents of the trigger decision.
+  
+  cout << "Trigger (" << fName.Data() << ") result = " << Result() << endl;
+  TString opt(option);
+  if (opt.Contains("short")) return;
+  cout << "Description = \"" << fDescription.Data() << "\"" << endl;
+  fReadoutList.Print();
+  fTriggerDomain.Print();
+}
+
diff --git a/HLT/trigger/AliHLTTriggerDecision.h b/HLT/trigger/AliHLTTriggerDecision.h
new file mode 100644 (file)
index 0000000..dab60b9
--- /dev/null
@@ -0,0 +1,148 @@
+#ifndef ALIHLTTRIGGERDECISION_H
+#define ALIHLTTRIGGERDECISION_H
+/* This file is property of and copyright by the ALICE HLT Project        *
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ * See cxx source for full Copyright notice                               */
+
+/// @file   AliHLTTriggerDecision.h
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date   21 Nov 2008
+/// @brief  Declaration of the AliHLTTriggerDecision class storing the a AliHLTTrigger component's decision.
+
+#include "TString.h"
+#include "AliHLTReadoutList.h"
+#include "AliHLTTriggerDomain.h"
+
+/**
+ * \class AliHLTTriggerDecision
+ * Stores the information and result of a trigger decision made by a component
+ * deriving from AliHLTTrigger. The information includes the DDL readout list
+ * indicating which DDLs to readout and the trigger domain specifying which HLT
+ * raw data blocks to forward to HLTOUT.
+ */
+class AliHLTTriggerDecision : public TObject
+{
+ public:
+  
+  /**
+   * Default constructor.
+   */
+  AliHLTTriggerDecision();
+  
+  /**
+   * Constructor specifying the result and trigger name.
+   * \param result  The result of the trigger decision.
+   * \param name  The name of the trigger decision. Should be the name of the
+   *     AliHLTTrigger component.
+   */
+  AliHLTTriggerDecision(bool result, const char* name);
+  
+  /**
+   * Constructor specifying all information fields.
+   * \param result  The result of the trigger decision.
+   * \param name  The name of the trigger decision. Should be the name of the
+   *     AliHLTTrigger component.
+   * \param readoutList  The DDL readout list for the trigger decision.
+   * \param triggerDomain  The trigger domain for the trigger decision.
+   * \param description  The description of (reason for) the trigger decision.
+   */
+  AliHLTTriggerDecision(
+      bool result, const char* name, const AliHLTReadoutList& readoutList,
+      const AliHLTTriggerDomain& triggerDomain, const char* description = ""
+    );
+  
+  /**
+   * Default destructor.
+   */
+  virtual ~AliHLTTriggerDecision();
+  
+  /**
+   * Inherited from TObject. Returns the name of the trigger decision.
+   */
+  virtual const char* GetName() const { return fName.Data(); }
+  
+  /**
+   * Inherited from TObject. This prints the contents of the trigger decision.
+   * \param option  Can be "short" which will print the short format.
+   */
+  virtual void Print(Option_t* option = "") const;
+  
+  /**
+   * Returns the result of the trigger decision.
+   * \returns true if the event was triggered and should be readout.
+   */
+  bool EventTriggered() const { return Result(); }
+  
+  /**
+   * Returns the result of the trigger decision.
+   * The decision is stored in bit 15 of the fBits field.
+   * \returns true if the event was triggered and should be readout.
+   */
+  bool Result() const { return TestBit(15) == 1; }
+  
+  /**
+   * Sets the result of the trigger decision.
+   * The decision is stored in bit 15 of the fBits field.
+   * \param value  The value to set; true if the event triggered and should be
+   *     readout and false otherwise.
+   */
+  void Result(bool value) { SetBit(15, value); }
+  
+  /**
+   * Returns the name of the trigger decision.
+   */
+  const char* Name() const { return fName.Data(); }
+  
+  /**
+   * Sets the name of the trigger decision.
+   */
+  void Name(const char* name) { fName = name; }
+  
+  /**
+   * Returns the description of (reason for) the trigger decision.
+   */
+  const char* Description() const { return fDescription.Data(); }
+  
+  /**
+   * Sets the description of the trigger decision.
+   */
+  void Description(const char* value) { fDescription = value; }
+  
+  /**
+   * Returns the DDL readout list associated with this trigger decision.
+   */
+  const AliHLTReadoutList& ReadoutList() const { return fReadoutList; }
+  
+  /**
+   * Returns the DDL readout list associated with this trigger decision for
+   * modification.
+   */
+  AliHLTReadoutList& ReadoutList() { return fReadoutList; }
+  
+  /**
+   * Sets the DDL readout list associated with this trigger decision.
+   */
+  void ReadoutList(const AliHLTReadoutList& value) { fReadoutList = value; }
+  
+  /**
+   * Returns the trigger domain associated with this trigger decision.
+   */
+  const AliHLTTriggerDomain& TriggerDomain() const { return fTriggerDomain; }
+  
+  /**
+   * Sets the trigger domain associated with this trigger decision.
+   */
+  void TriggerDomain(const AliHLTTriggerDomain& value) { fTriggerDomain = value; }
+  
+ private:
+  
+  TString fName; /// The name of the trigger decision. Should be the name of the trigger component that generated it.
+  TString fDescription; /// Optional descriptive text giving the reason for the trigger.
+  AliHLTReadoutList fReadoutList; /// The readout DDL list.
+  AliHLTTriggerDomain fTriggerDomain;  /// The trigger domain associated with this trigger. i.e. the HLT data blocks to read out.
+  
+  ClassDef(AliHLTTriggerDecision, 1) // HLT trigger decision object storing information about the readout list, trigger domain and result.
+};
+
+#endif // ALIHLTTRIGGERDECISION_H
+
diff --git a/HLT/trigger/AliHLTTriggerDomain.cxx b/HLT/trigger/AliHLTTriggerDomain.cxx
new file mode 100644 (file)
index 0000000..7687fe9
--- /dev/null
@@ -0,0 +1,825 @@
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        *
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ *                                                                        *
+ * Primary Authors: Artur Szostak <artursz@iafrica.com>                   *
+ *                  for The ALICE HLT Project.                            *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/// @file   AliHLTTriggerDomain.cxx
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date   19 Nov 2008
+/// @brief  Implementation of the AliHLTTriggerDomain class.
+///
+/// The trigger domain class is the set of HLT raw data block types that should
+/// be readout and sent to HLTOUT.
+
+#include "AliHLTTriggerDomain.h"
+#include "AliHLTDomainEntry.h"
+#include "Riostream.h"
+
+ClassImp(AliHLTTriggerDomain)
+
+
+AliHLTTriggerDomain::AliHLTTriggerDomain() :
+  TObject(), fEntries(AliHLTDomainEntry::Class(), 10)
+{
+  // Default constructor.
+}
+
+
+AliHLTTriggerDomain::AliHLTTriggerDomain(const AliHLTTriggerDomain& domain) :
+  TObject(domain),
+  fEntries(AliHLTDomainEntry::Class(), domain.fEntries.GetEntriesFast())
+{
+  // Copy constructor performs a deep copy.
+  // See header file for more details.
+  
+  for (Int_t i = 0; i < domain.fEntries.GetEntriesFast(); i++)
+  {
+    const AliHLTDomainEntry* entry = static_cast<const AliHLTDomainEntry*>( domain.fEntries[i] );
+    new (fEntries[fEntries.GetEntriesFast()]) AliHLTDomainEntry(*entry);
+  }
+}
+
+
+AliHLTTriggerDomain::~AliHLTTriggerDomain()
+{
+  // Default destructor.
+}
+
+
+void AliHLTTriggerDomain::Add(const AliHLTDomainEntry& entry)
+{
+  // Adds a new domain entry to the trigger domain.
+  // See header file for more details.
+  
+  AliHLTDomainEntry intersect;
+  bool anythingRemoved = false;
+  bool alreadyInSet = false;
+  
+  // Get the initial size of the fEntries array since we might add things to the
+  // end during the calculation.
+  Int_t count = fEntries.GetEntriesFast();
+  
+  // Go through each entry that is already in fEntries and see if we can remove
+  // it because it will become redundant, or if we need to patch exclusion entries
+  // by adding inclusive intersects, or if we do not even need to add the new entry
+  // because it is already part of the trigger domain.
+  for (Int_t i = 0; i < count; i++)
+  {
+    const AliHLTDomainEntry* ientry = static_cast<const AliHLTDomainEntry*>(fEntries[i]);
+    if (ientry->Inclusive())
+    {
+      if (entry.SubsetOf(*ientry))
+      {
+        alreadyInSet = true;
+      }
+      else if (ientry->SubsetOf(entry))
+      {
+        fEntries.RemoveAt(i);
+        anythingRemoved = true;
+      }
+    }
+    else
+    {
+      if (ientry->SubsetOf(entry))
+      {
+        fEntries.RemoveAt(i);
+        anythingRemoved = true;
+      }
+      else if (entry.SubsetOf(*ientry))
+      {
+        alreadyInSet = false;
+      }
+      else if (ientry->IntersectWith(entry, intersect))
+      {
+        new (fEntries[fEntries.GetEntriesFast()]) AliHLTDomainEntry(kFALSE, intersect);
+        alreadyInSet = true;
+      }
+    }
+  }
+  
+  // Check if we need to compress the array and if we need to add the new entry.
+  if (anythingRemoved) fEntries.Compress();
+  if (not alreadyInSet)
+  {
+    new (fEntries[fEntries.GetEntriesFast()]) AliHLTDomainEntry(kFALSE, entry);
+  }
+}
+
+
+void AliHLTTriggerDomain::Add(const AliHLTComponentDataType& datatype)
+{
+  // Adds a new domain entry with the given data type to the trigger domain.
+  // But the data block specification is set to the any matching wild card.
+  // See header file for more details.
+  
+  Add(AliHLTDomainEntry(datatype));
+}
+
+
+void AliHLTTriggerDomain::Add(const char* blocktype, const char* origin)
+{
+  // Adds a new domain entry with the given data type and origin to the trigger domain.
+  // But the data block specification is set to the any matching wild card.
+  // See header file for more details.
+  
+  Add(AliHLTDomainEntry(blocktype, origin));
+}
+
+
+void AliHLTTriggerDomain::Add(const AliHLTComponentDataType& datatype, UInt_t spec)
+{
+  // Adds a new domain entry to the trigger domain with the data type and data block
+  // specification bits.
+  // See header file for more details.
+  
+  Add(AliHLTDomainEntry(datatype, spec));
+}
+
+
+void AliHLTTriggerDomain::Add(const char* blocktype, const char* origin, UInt_t spec)
+{
+  // Adds a new domain entry to the trigger domain with the given data type, origin
+  // and data block specification bits.
+  // See header file for more details.
+  
+  Add(AliHLTDomainEntry(blocktype, origin, spec));
+}
+
+
+void AliHLTTriggerDomain::Remove(const AliHLTDomainEntry& entry)
+{
+  // Removes the given domain entry from the trigger domain.
+  // See header file for more details.
+
+  AliHLTDomainEntry intersect;
+  bool anythingRemoved = false;
+  bool addToExcludeSet = false;
+  
+  // Get the initial size of the fEntries array since we might add things to the
+  // end during the calculation.
+  Int_t count = fEntries.GetEntriesFast();
+  
+  // We need to go through all existing entries and see if they need to be removed
+  // because they would become redundant when we add the new 'entry' to the end of
+  // the fEntries list. We also need to check if the new entry needs to be added
+  // at all because the trigger domain might already not contain those entries.
+  // Lastly, some intersection entries might need to be added to patch up existing
+  // inclusive trigger domain entries (rules / patterns).
+  for (Int_t i = 0; i < count; i++)
+  {
+    const AliHLTDomainEntry* ientry = static_cast<const AliHLTDomainEntry*>(fEntries[i]);
+    if (ientry->Inclusive())
+    {
+      if (ientry->SubsetOf(entry))
+      {
+        fEntries.RemoveAt(i);
+        anythingRemoved = true;
+      }
+      else if (entry.SubsetOf(*ientry))
+      {
+        addToExcludeSet = true;
+      }
+      else if (ientry->IntersectWith(entry, intersect))
+      {
+        new (fEntries[fEntries.GetEntriesFast()]) AliHLTDomainEntry(kTRUE, intersect);
+      }
+    }
+    else
+    {
+      if (entry.SubsetOf(*ientry))
+      {
+        addToExcludeSet = false;
+      }
+      else if (ientry->SubsetOf(entry))
+      {
+        fEntries.RemoveAt(i);
+        anythingRemoved = true;
+      }
+    }
+  }
+  
+  // Check if we need to compress the array and if we need to add the new entry.
+  if (anythingRemoved) fEntries.Compress();
+  if (addToExcludeSet)
+  {
+    new (fEntries[fEntries.GetEntriesFast()]) AliHLTDomainEntry(kTRUE, entry);
+  }
+}
+
+
+void AliHLTTriggerDomain::Remove(const AliHLTComponentDataType& datatype)
+{
+  // Removes the domain entries that have the given data type from the trigger domain.
+  // See header file for more details.
+  
+  Remove(AliHLTDomainEntry(datatype));
+}
+
+
+void AliHLTTriggerDomain::Remove(const char* blocktype, const char* origin)
+{
+  // Removes the domain entries that have the given data type and origin from the
+  // trigger domain.
+  // See header file for more details.
+  
+  Remove(AliHLTDomainEntry(blocktype, origin));
+}
+
+
+void AliHLTTriggerDomain::Remove(const AliHLTComponentDataType& datatype, UInt_t spec)
+{
+  // Removes the domain entries that have the given data type and data block
+  // specification bits from the trigger domain.
+  // See header file for more details.
+  
+  Remove(AliHLTDomainEntry(datatype, spec));
+}
+
+
+void AliHLTTriggerDomain::Remove(const char* blocktype, const char* origin, UInt_t spec)
+{
+  // Removes the domain entries that have the given data type, origin and data
+  // block specification bits from the trigger domain.
+  // See header file for more details.
+  
+  Remove(AliHLTDomainEntry(blocktype, origin, spec));
+}
+
+
+bool AliHLTTriggerDomain::Contains(const AliHLTDomainEntry& entry) const
+{
+  // Checks to see if the given domain entry is part of the trigger domain set.
+  // See header file for more details.
+
+  // Simply go through the whole list of fEntries and for each entry see if the
+  // given domain entry 'entry' being checked matches. If there is a match then
+  // update the result depending on the entry type. i.e. set to false if the entry
+  // in fEntries is an exclusion and set to true if it is an inclusion.
+  bool result = false;
+  for (Int_t i = 0; i < fEntries.GetEntriesFast(); i++)
+  {
+    const AliHLTDomainEntry* ientry = static_cast<const AliHLTDomainEntry*>(fEntries[i]);
+    if (ientry->Inclusive())
+    {
+      if (*ientry == entry) result = true;
+    }
+    else
+    {
+      if (entry.SubsetOf(*ientry)) result = false;
+    }
+  }
+  return result;
+}
+
+
+bool AliHLTTriggerDomain::IncludeInReadout(const AliHLTComponentBlockData* block) const
+{
+  // Checks to see if the given data block is part of the trigger domain set and
+  // should be readout.
+  // See header file for more details.
+
+  // Same algorithm as for Contains() but applied directly to the data block
+  // descriptor structure.
+  AliHLTDomainEntry blockEntry(block->fDataType, block->fSpecification);
+  bool result = false;
+  for (Int_t i = 0; i < fEntries.GetEntriesFast(); i++)
+  {
+    const AliHLTDomainEntry* entry = static_cast<const AliHLTDomainEntry*>(fEntries[i]);
+    if (entry->Inclusive())
+    {
+      if (*entry == block) result = true;
+    }
+    else
+    {
+      if (blockEntry.SubsetOf(*entry)) result = false;
+    }
+  }
+  return result;
+}
+
+
+void AliHLTTriggerDomain::Clear(Option_t* option)
+{
+  // Clears the trigger domain (Removes all entries).
+  
+  fEntries.Clear(option);
+}
+
+
+void AliHLTTriggerDomain::Print(Option_t* /*option*/) const
+{
+  // Prints the trigger domain entries in the order that they are applied.
+  // See header file for more details.
+
+  cout << "Trigger domain rules (applied in order of first to last):" << endl;
+  for (Int_t i = 0; i < fEntries.GetEntriesFast(); i++)
+  {
+    const AliHLTDomainEntry* entry = static_cast<const AliHLTDomainEntry*>( fEntries[i] );
+    if (entry->Inclusive())
+    {
+      cout << "Include ";
+    }
+    else
+    {
+      cout << "Exclude ";
+    }
+    entry->Print();
+  }
+  if (fEntries.GetEntriesFast() == 0)
+  {
+    cout << "(empty)" << endl;
+  }
+}
+
+
+AliHLTTriggerDomain& AliHLTTriggerDomain::operator = (const AliHLTTriggerDomain& domain)
+{
+  // Assignment operator performs a deep copy.
+  // See header file for more details.
+  
+  if (this == &domain) return *this;
+  TObject::operator = (domain);
+  fEntries.Clear();
+  for (Int_t i = 0; i < domain.fEntries.GetEntriesFast(); i++)
+  {
+    const AliHLTDomainEntry* entry = static_cast<const AliHLTDomainEntry*>( domain.fEntries[i] );
+    new (fEntries[fEntries.GetEntriesFast()]) AliHLTDomainEntry(*entry);
+  }
+  return *this;
+}
+
+
+AliHLTTriggerDomain& AliHLTTriggerDomain::operator |= (const AliHLTTriggerDomain& domain)
+{
+  // This operator performs the set union.
+  // See header file for more details.
+  
+  // Note that we partition the fEntries array into 3 regions for this calculation.
+  //   - 0..entriesCount-1 : contains the initial entries of this trigger domain.
+  //   - entriesCount..startOfIntersects-1 : is space reserved for the new entries
+  //       from 'domain'.
+  //   - startOfIntersects..fEntries.GetEntriesFast()-1 : This will grow as we add
+  //       all the new domain intersections created during the calculation.
+  //
+  // Get the number of entries now before we start adding more entries from 'domain'.
+  Int_t count = fEntries.GetEntriesFast();
+  // Mark the start location for new intersection entries.
+  Int_t startOfIntersects = count + domain.fEntries.GetEntriesFast();
+  Int_t newIndex = startOfIntersects;
+
+  // Allocate and initialise a single block of memory so that we do not call new twice.
+  bool* buffer = new bool[startOfIntersects];
+  for (Int_t i = 0; i < startOfIntersects; i++) buffer[i] = false;
+  bool* removeThisEntry = buffer;
+  bool* removeDomainEntry = buffer + count;
+
+  AliHLTDomainEntry intersect;
+  
+  // The idea behind this algorithm is that we need to add all inclusion domain
+  // entries from 'domain' to this object that will not be redundant, but for
+  // the exclusion entries we patch the fEntries rule set by adding the appropriate
+  // intersections to the end of fEntries.
+  for (Int_t i = 0; i < domain.fEntries.GetEntriesFast(); i++)
+  {
+    const AliHLTDomainEntry* newEntry = static_cast<const AliHLTDomainEntry*>( domain.fEntries[i] );
+    for (Int_t j = 0; j < count; j++)
+    {
+      const AliHLTDomainEntry* currentEntry = static_cast<const AliHLTDomainEntry*>( fEntries[j] );
+      if (currentEntry->Inclusive() and newEntry->Inclusive())
+      {
+        // If either entry is a subset of the other then we do not need to add
+        // both, so make sure to remove the one that is redundant.
+        if (newEntry->SubsetOf(*currentEntry))
+        {
+          removeDomainEntry[i] = true;
+        }
+        else if (currentEntry->SubsetOf(*newEntry))
+        {
+          removeThisEntry[j] = true;
+        }
+      }
+      else
+      {
+        if (newEntry->IntersectWith(*currentEntry, intersect))
+        {
+          // We can remove all intersections that were already added that will
+          // become redundant when this intersection is added to fEntries.
+          MarkForDeletionSubsetsOf(intersect, startOfIntersects);
+          
+          // Make the new intersection entry an exclusion if the newEntry and
+          // currentEntry flags are the same.
+          bool exclude = newEntry->Exclusive() == currentEntry->Exclusive();
+          new (fEntries[newIndex++]) AliHLTDomainEntry(exclude, intersect);
+          
+          // We can also remove entries that are subsets of another entry in the
+          // opposite list, since they will be redundant when everything is merged
+          // together. For example, remove entry x from fEntries if it is a subset
+          // of entry y in domain.fEntries.
+          if (currentEntry->IdenticalTo(intersect)) removeThisEntry[j] = true;
+          if (newEntry->IdenticalTo(intersect)) removeDomainEntry[i] = true;
+        }
+      }
+    }
+  }
+
+  MergeEntries(removeThisEntry, count, removeDomainEntry, startOfIntersects, domain);
+  delete [] buffer;
+  Optimise();
+  return *this;
+}
+
+
+AliHLTTriggerDomain& AliHLTTriggerDomain::operator ^= (const AliHLTTriggerDomain& domain)
+{
+  // This operator performs the set union, less the set intersect (something like and xor).
+  // See header file for more details.
+  
+  // Note that we partition the fEntries array into 3 regions for this calculation.
+  //   - 0..entriesCount-1 : contains the initial entries of this trigger domain.
+  //   - entriesCount..startOfIntersects-1 : is space reserved for the new entries
+  //       from 'domain'.
+  //   - startOfIntersects..fEntries.GetEntriesFast()-1 : This will grow as we add
+  //       all the new domain intersections created during the calculation.
+  //
+  // Get the number of entries now before we start adding more entries from 'domain'.
+  Int_t count = fEntries.GetEntriesFast();
+  // Mark the start location for new intersection entries.
+  Int_t startOfIntersects = count + domain.fEntries.GetEntriesFast();
+  Int_t newIndex = startOfIntersects;
+
+  // Allocate and initialise a single block of memory so that we do not call new twice.
+  bool* buffer = new bool[startOfIntersects];
+  for (Int_t i = 0; i < startOfIntersects; i++) buffer[i] = false;
+  bool* removeThisEntry = buffer;
+  bool* removeDomainEntry = buffer + count;
+
+  AliHLTDomainEntry intersect;
+  
+  // This algorithm is similar to the case for the set union (operator |=), except
+  // that we make sure to remove from the trigger domain all parts where the entries
+  // from fEntries and domain.fEntries intersect.
+  // This is done by adding the intersections to the end of fEntries such that they
+  // effectively remove those overlapping trigger domain entries when calculating
+  // IncludeInReadout() or Contains().
+  for (Int_t i = 0; i < domain.fEntries.GetEntriesFast(); i++)
+  {
+    const AliHLTDomainEntry* newEntry = static_cast<const AliHLTDomainEntry*>( domain.fEntries[i] );
+    for (Int_t j = 0; j < count; j++)
+    {
+      const AliHLTDomainEntry* currentEntry = static_cast<const AliHLTDomainEntry*>( fEntries[j] );
+      if (newEntry->IntersectWith(*currentEntry, intersect))
+      {
+        // We can remove all intersections that were already added that will
+        // become redundant when this intersection is added to fEntries.
+        MarkForDeletionSubsetsOf(intersect, startOfIntersects);
+        
+        // Make the new intersection entry an exclusion if the newEntry and
+        // currentEntry flags are the same.
+        bool exclude = newEntry->Exclusive() == currentEntry->Exclusive();
+        new (fEntries[newIndex++]) AliHLTDomainEntry(exclude, intersect);
+        
+        // We can also remove entries that are subsets of another entry in the
+        // opposite list, since they will be redundant when everything is merged
+        // together. For example, remove entry x from fEntries if it is a subset
+        // of entry y in domain.fEntries.
+        if (currentEntry->IdenticalTo(intersect)) removeThisEntry[j] = true;
+        if (newEntry->IdenticalTo(intersect)) removeDomainEntry[i] = true;
+      }
+    }
+  }
+
+  MergeEntries(removeThisEntry, count, removeDomainEntry, startOfIntersects, domain);
+  delete [] buffer;
+  Optimise();
+  return *this;
+}
+
+
+AliHLTTriggerDomain& AliHLTTriggerDomain::operator -= (const AliHLTTriggerDomain& domain)
+{
+  // This operator performs the set difference.
+  // See header file for more details.
+  
+  // Mark the number of entries in fEntries now before we start adding more
+  // entries from 'domain' or intersections.
+  Int_t startOfIntersects = fEntries.GetEntriesFast();
+  Int_t newIndex = startOfIntersects;
+  
+  AliHLTDomainEntry intersect;
+  
+  // To compute the set difference we need to remove all all parts that overlap
+  // with 'domain'. i.e. we need to find all the intersects between the domain
+  // entries in fEntries and those in domain.fEntries, and add the intersects
+  // to the fEntries list, such that they will cancel or remove the overlapping
+  // parts of the two trigger domains.
+  for (Int_t i = 0; i < domain.fEntries.GetEntriesFast(); i++)
+  {
+    const AliHLTDomainEntry* checkEntry = static_cast<const AliHLTDomainEntry*>( domain.fEntries[i] );
+    if (checkEntry->Inclusive())
+    {
+      // For inclusive entries we need to find the overlaps with the inclusive
+      // entries in fEntries and add exclusive entries that will remove that
+      // part of the trigger domain set.
+      for (Int_t j = 0; j < startOfIntersects; j++)
+      {
+        AliHLTDomainEntry* currentEntry = static_cast<AliHLTDomainEntry*>( fEntries[j] );
+        
+        // We only need to consider the case where both entries are inclusive,
+        // since an exclusion in fEntries already eliminates those data blocks
+        // from the trigger domain set.
+        if (currentEntry->Exclusive()) continue;
+        
+        if (checkEntry->IntersectWith(*currentEntry, intersect))
+        {
+          // We can remove all intersections that were already added that will
+          // become redundant when this intersection is added to fEntries.
+          MarkForDeletionSubsetsOf(intersect, startOfIntersects);
+          
+          new (fEntries[newIndex++]) AliHLTDomainEntry(kTRUE, intersect);
+          if (currentEntry->IdenticalTo(intersect))
+          {
+            currentEntry->SetBit(14, true);
+          }
+        }
+      }
+    }
+    else
+    {
+      // For an exclusive entry in 'domain' we need to find the intersections with
+      // all of fEntries and re-apply these with the same exclude flags.
+      for (Int_t j = 0; j < startOfIntersects; j++)
+      {
+        AliHLTDomainEntry* currentEntry = static_cast<AliHLTDomainEntry*>( fEntries[j] );
+        if (checkEntry->IntersectWith(*currentEntry, intersect))
+        {
+          // We can remove all intersections that were already added that will
+          // become redundant when this intersection is added to fEntries.
+          MarkForDeletionSubsetsOf(intersect, startOfIntersects);
+          
+          new (fEntries[newIndex++]) AliHLTDomainEntry(currentEntry->Exclusive(), intersect);
+        }
+      }
+    }
+  }
+
+  RemoveMarkedEntries();
+  Optimise();
+  return *this;
+}
+
+
+AliHLTTriggerDomain AliHLTTriggerDomain::operator ~ () const
+{
+  // Performs a set complement of the trigger domain.
+  
+  // The set complement is calculated by creating a new trigger domain which
+  // accepts all possible data blocks, and then apply all the trigger domain
+  // entries (rules / patterns) from top to bottom, but apply them with the
+  // opposite meaning. For example, this->fEntries contains an inclusive domain
+  // entry then remove it from the new trigger domain 'result', but if it is
+  // an exclusion then add it.
+  AliHLTTriggerDomain result;
+  result.Add(kAliHLTAnyDataType);
+  for (Int_t i = 0; i < fEntries.GetEntriesFast(); i++)
+  {
+    const AliHLTDomainEntry* entry = static_cast<const AliHLTDomainEntry*>( fEntries[i] );
+    if (entry->Inclusive())
+    {
+      result.Remove(*entry);
+    }
+    else
+    {
+      result.Add(*entry);
+    }
+  }
+  return result;
+}
+
+
+AliHLTTriggerDomain AliHLTTriggerDomain::operator & (const AliHLTTriggerDomain& domain) const
+{
+  // This operator finds the set intersect.
+  // See header file for more details.
+  
+  AliHLTTriggerDomain result;
+  Int_t newIndex = 0;
+  AliHLTDomainEntry intersect;
+  
+  // To find the set intersect we need to compare each entry in 'domain' to those
+  // of fEntries. For each inclusive entry in 'domain' we need to add to the result
+  // the intersect between it and each entry of fEntries, with the same exclude flag
+  // value as the domain entry from fEntries.
+  // However, in principle, for the exclusion entries in 'domain' we just add them
+  // to the result, since those entries do not form part of the 'domain' trigger
+  // domain set, so they should not form part of the result (remember any data block
+  // must be contained in both trigger domains for a set intersect).
+  // In actual fact we just add the intersect of the exclusion entries in 'domain'
+  // with those of fEntries to the result. This has the same overall effect, but
+  // makes sure that all exclusion entries are always subsets of inclusion entries.
+  for (Int_t i = 0; i < domain.fEntries.GetEntriesFast(); i++)
+  {
+    const AliHLTDomainEntry* checkEntry = static_cast<const AliHLTDomainEntry*>( domain.fEntries[i] );
+    if (checkEntry->Inclusive())
+    {
+      for (Int_t j = 0; j < fEntries.GetEntriesFast(); j++)
+      {
+        AliHLTDomainEntry* currentEntry = static_cast<AliHLTDomainEntry*>( fEntries[j] );
+        if (checkEntry->IntersectWith(*currentEntry, intersect))
+        {
+          // We can remove all entries that were already added to the result that
+          // will become redundent because they are subsets of the new entry.
+          result.MarkForDeletionSubsetsOf(intersect, 0);
+          
+          new (result.fEntries[newIndex++]) AliHLTDomainEntry(currentEntry->Exclusive(), intersect);
+        }
+      }
+    }
+    else
+    {
+      for (Int_t j = 0; j < fEntries.GetEntriesFast(); j++)
+      {
+        AliHLTDomainEntry* currentEntry = static_cast<AliHLTDomainEntry*>( fEntries[j] );
+        if (checkEntry->IntersectWith(*currentEntry, intersect))
+        {
+          // We can remove all entries that were already added to the result that
+          // will become redundant because they are subsets of the new entry.
+          result.MarkForDeletionSubsetsOf(intersect, 0);
+          
+          new (result.fEntries[newIndex++]) AliHLTDomainEntry(kTRUE, intersect);
+        }
+      }
+    }
+  }
+
+  result.RemoveMarkedEntries();
+  result.Optimise();
+  return result;
+}
+
+
+void AliHLTTriggerDomain::MergeEntries(
+    const bool* removeThisEntry, Int_t entriesCount,
+    const bool* removeDomainEntry, Int_t startOfIntersects,
+    const AliHLTTriggerDomain& domain
+  )
+{
+  // Merges the entries in this trigger domain with the ones in 'domain', while
+  // removing all entries that were marked for removal.
+  // See header file for more information.
+  
+  bool anythingRemoved = false;
+  
+  // Remember this method is used at the end of the calculation of the binary operators
+  // and that fEntries is expected to be partitioned into 3 regions.
+  //   - 0..entriesCount-1 : contains the original (initial) entries of this trigger domain.
+  //   - entriesCount..startOfIntersects-1 : is space reserved for the new entries
+  //       from the given trigger domain 'domain' being processed.
+  //   - startOfIntersects..fEntries.GetEntriesFast()-1 : contains all new domain entry
+  //       intersection created and added to fEntries.
+  //
+  // First we need to remove all entries marked for removal from the original entries.
+  for (Int_t i = 0; i < entriesCount; i++)
+  {
+    if (removeThisEntry[i])
+    {
+      fEntries.RemoveAt(i);
+      anythingRemoved = true;
+    }
+  }
+  
+  // Now we copy over all the new entries from 'domain' which were not marked for removal
+  // and indicate anythingRemoved = true since there will now be gaps in the clones array
+  // that need to be compressed away later.
+  for (Int_t i = 0; i < domain.fEntries.GetEntriesFast(); i++)
+  {
+    if (removeDomainEntry[i])
+    {
+      anythingRemoved = true;
+    }
+    else
+    {
+      const AliHLTDomainEntry* newEntry = static_cast<const AliHLTDomainEntry*>( domain.fEntries[i] );
+      new (fEntries[entriesCount+i]) AliHLTDomainEntry(*newEntry);
+    }
+  }
+  
+  // Finally remove all new intersection entries that were marked for removal by
+  // the MarkForDeletionSubsetsOf method.
+  for (Int_t i = startOfIntersects; i < fEntries.GetEntriesFast(); i++)
+  {
+    const AliHLTDomainEntry* ientry = static_cast<const AliHLTDomainEntry*>( fEntries[i] );
+    if (ientry->TestBit(14))
+    {
+      fEntries.RemoveAt(i);
+      anythingRemoved = true;
+    }
+  }
+  if (anythingRemoved) fEntries.Compress();
+}
+
+
+void AliHLTTriggerDomain::MarkForDeletionSubsetsOf(const AliHLTDomainEntry& entry, Int_t min)
+{
+  // Marks for deletion all the entries in this trigger domain that are subsets
+  // of the given entry.
+  // See header file for more information.
+
+  AliHLTDomainEntry intersect;
+  for (Int_t i = min; i < fEntries.GetEntriesFast(); i++)
+  {
+    AliHLTDomainEntry* ientry = static_cast<AliHLTDomainEntry*>( fEntries[i] );
+    if (ientry->TestBit(14)) continue;
+    if (ientry->SubsetOf(entry))
+    {
+      ientry->SetBit(14, true);
+    }
+  }
+}
+
+
+void AliHLTTriggerDomain::RemoveMarkedEntries()
+{
+  // Removes all entries in this trigger domain which were marked for removal..
+  // See header file for more information.
+  
+  bool anythingRemoved = false;
+  for (Int_t i = 0; i < fEntries.GetEntriesFast(); i++)
+  {
+    const AliHLTDomainEntry* ientry = static_cast<const AliHLTDomainEntry*>( fEntries[i] );
+    if (ientry->TestBit(14))
+    {
+      fEntries.RemoveAt(i);
+      anythingRemoved = true;
+    }
+  }
+  if (anythingRemoved) fEntries.Compress();
+}
+
+
+void AliHLTTriggerDomain::Optimise()
+{
+  // Removes redundant trigger domain entries from the trigger domain.
+  // See header file for more information.
+
+  AliHLTDomainEntry intersect;
+  
+  // Check that the first entry is not and exclusion which would be redundent.
+  if (fEntries.GetEntriesFast() == 0) return;
+  AliHLTDomainEntry* firstEntry = static_cast<AliHLTDomainEntry*>( fEntries[0] );
+  if (firstEntry->Exclusive()) firstEntry->SetBit(14, true);
+  
+  for (Int_t i = 1; i < fEntries.GetEntriesFast(); i++)
+  {
+    AliHLTDomainEntry* ientry = static_cast<AliHLTDomainEntry*>( fEntries[i] );
+    
+    // For the i'th entry in fEntries, compare it in reverse order with all other
+    // entries that are before it and look for redundant ones, i.e. that are subsets
+    // of the i'th entry.
+    for (Int_t j = i-1; j >= 0; j--)
+    {
+      AliHLTDomainEntry* jentry = static_cast<AliHLTDomainEntry*>( fEntries[j] );
+      if (jentry->TestBit(14)) continue;
+      // Find entries that intersect
+      if (jentry->SubsetOf(*ientry))
+      {
+        // jentry is a subset of ientry so it is redundant because for all values
+        // ientry will override jentry when calling IncludeInReadout.
+        jentry->SetBit(14, true);
+      }
+      else if (*ientry == *jentry)
+      {
+        // If intersecting entries have opposite exclude flags then search no further,
+        // we know that we will need this entry for correct behaviour of IncludeInReadout.
+        if (ientry->Inclusive() == jentry->Exclusive()) goto processNextEntry;
+        
+        if (ientry->SubsetOf(*jentry))
+        {
+          ientry->SetBit(14, true);
+          goto processNextEntry;
+        }
+      }
+    }
+    
+    // If we got to this point then we hit the top of the trigger domain rules
+    // (pattern matching) list without hitting any and overlapping entries.
+    // So now we need to check if ientry is an exclusion. If it is, then it is
+    // redundant and we can mark it for removal.
+    if (ientry->Exclusive()) ientry->SetBit(14, true);
+    
+    processNextEntry: ;
+  }
+  
+  RemoveMarkedEntries();
+}
+
diff --git a/HLT/trigger/AliHLTTriggerDomain.h b/HLT/trigger/AliHLTTriggerDomain.h
new file mode 100644 (file)
index 0000000..34e7d3c
--- /dev/null
@@ -0,0 +1,412 @@
+#ifndef ALIHLTTRIGGERDOMAIN_H
+#define ALIHLTTRIGGERDOMAIN_H
+/* This file is property of and copyright by the ALICE HLT Project        *
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ * See cxx source for full Copyright notice                               */
+
+/// @file   AliHLTDomainEntry.h
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date   19 Nov 2008
+/// @brief  Declaration of the AliHLTTriggerDomain class used to store the set of data block types to readout.
+
+#include "TObject.h"
+#include "TClonesArray.h"
+#include "AliHLTDataTypes.h"
+
+class AliHLTDomainEntry;
+
+/**
+ * \class AliHLTTriggerDomain
+ * The trigger domain class is the set of HLT raw data block types that should
+ * be readout and sent to HLTOUT.
+ * It is implemented as a list of domain entries, where each domain entry is
+ * like a rule, or pattern to match against. When trying to decide if a given
+ * data block falls within the trigger domain, i.e. is part of the readout, the
+ * domain entries are applied one after the other from top to bottom. Two kinds
+ * of domain entries, inclusive and exclusive are possible, which indicate if a
+ * data block type or range, is part of the trigger domain or not. As we process
+ * the domain entries we update our decision of whether the data block is part
+ * of the trigger domain or not. If the domain entry is an inclusion then we update
+ * the decision to true, if it is an exclusion then we update the decision to false.
+ * The value of the result after applying the last domain entry then indicates
+ * if the data block is part of the trigger domain or not.
+ * In this way we can specify trigger domains as sets to arbitrary complexity
+ * and manipulate them as mathematical sets accordingly.
+ *
+ * The other feature of the AliHLTTriggerDomain class is that it overloads the
+ * following operators to provide set like behaviour:
+ *   |  this provides the set union operation (The + operator does the same).
+ *   &  this provides the set intersect operation.
+ *   -  this provides the set difference operation.
+ *   ^  this provides an exclusive or (xor) operation. i.e. given two sets A and B
+ *        the result C is given by:
+ *        C = {x : x elf A and not x elf B, or x elf B and not x elf A}
+ *        where 'elf' means "is an element of".
+ *   ~  this returns the set complement.
+ * These operators then allow expressions to be formed from trigger domain objects
+ * which behave like sets.
+ */
+class AliHLTTriggerDomain : public TObject
+{
+ public:
+  
+  /**
+   * Default constructor.
+   */
+  AliHLTTriggerDomain();
+  
+  /**
+   * Copy constructor performs a deep copy.
+   * \param domain  The domain entry to copy from.
+   */
+  AliHLTTriggerDomain(const AliHLTTriggerDomain& domain);
+  
+  /**
+   * Default destructor.
+   */
+  virtual ~AliHLTTriggerDomain();
+  
+  /**
+   * Adds the given entry to this trigger domain as an inclusive entry.
+   * Existing entries are modified as required to optimise the trigger domain
+   * rule / pattern matching list.
+   * \param entry  The domain entry object to add.
+   * \note The entry.Exclusive() flag is ignored and is treated as if it was kFALSE.
+   */
+  void Add(const AliHLTDomainEntry& entry);
+  
+  /**
+   * Adds the given data type to the trigger domain such that all data blocks
+   * that match this type will form part of the trigger domain.
+   * \param datatype  The data block type and origin to match.
+   */
+  void Add(const AliHLTComponentDataType& datatype);
+  
+  /**
+   * Adds the given data type and origin to the trigger domain such that all data
+   * blocks that match will form part of this trigger domain.
+   * \param blocktype  The data block type string of the data block that must match.
+   *    The value of kAliHLTAnyDataTypeID can be used to specify the 'any' type
+   *    wild card value.
+   * \param origin  The origin of the data block, such as the detector name, that
+   *    must match. The value of kAliHLTDataOriginAny can be used to specify the
+   *    'any' origin wild card value.
+   */
+  void Add(const char* blocktype, const char* origin);
+  
+  /**
+   * Adds the given data type with particular specification bits to the trigger
+   * domain, such that all data blocks that match these will form part of this
+   * trigger domain.
+   * \param datatype  The data block type and origin that must match.
+   * \param spec  The specification bits that must match.
+   */
+  void Add(const AliHLTComponentDataType& datatype, UInt_t spec);
+  
+  /**
+   * Adds the given data type, origin and specification bits of data blocks that
+   * should form part of this trigger domain.
+   * \param blocktype  The data block type string of the data block that must match.
+   *    The value of kAliHLTAnyDataTypeID can be used to specify the 'any' type
+   *    wild card value.
+   * \param origin  The origin of the data block, such as the detector name, that
+   *    must match. The value of kAliHLTDataOriginAny can be used to specify the
+   *    'any' origin wild card value.
+   * \param spec  The specification bits that must match.
+   */
+  void Add(const char* blocktype, const char* origin, UInt_t spec);
+  
+  /**
+   * Removes or modifies all entries from the trigger domain, such that data blocks
+   * that match the given domain entry will not form part of this trigger domain.
+   * Existing entries are modified as required to optimise the trigger domain
+   * rule / pattern matching list.
+   * \param entry  The domain entry object to indicating values that should be removed.
+   * \note The entry.Exclusive() flag is ignored and is treated as if it was kTRUE.
+   */
+  void Remove(const AliHLTDomainEntry& entry);
+  
+  /**
+   * Removes the given data type from the trigger domain, such that all data blocks
+   * that match this type will not form part of the trigger domain.
+   * \param datatype  The data block type and origin that must match the blocks not
+   *    forming part of this trigger domain.
+   */
+  void Remove(const AliHLTComponentDataType& datatype);
+  
+  /**
+   * Removes the given data type and origin from the trigger domain, such that all
+   * data blocks that match these will not form part of the trigger domain.
+   * \param blocktype  The data block type string that must match the data blocks
+   *    not forming part of this trigger domain.
+   *    The value of kAliHLTAnyDataTypeID can be used to specify the 'any' type
+   *    wild card value.
+   * \param origin  The origin string, such as the detector name, that must match
+   *    the data blocks not forming part of this trigger domain.
+   *    The value of kAliHLTDataOriginAny can be used to specify the 'any' origin
+   *    wild card value.
+   */
+  void Remove(const char* blocktype, const char* origin);
+  
+  /**
+   * Removes the given data type with given specification bit from the trigger
+   * domain, such that all data blocks that match these will not form part of the
+   * trigger domain.
+   * \param datatype  The data block type and origin that must match the blocks
+   *    not forming part of this trigger domain.
+   * \param spec  The specification bits that must match for the blocks that do
+   *    not form part of this trigger domain.
+   */
+  void Remove(const AliHLTComponentDataType& datatype, UInt_t spec);
+  
+  /**
+   * Removes the given data type, origin and specification from the trigger domain,
+   * such that all data blocks that match these will not form part of the trigger
+   * domain.
+   * \param blocktype  The data block type string that must match the data blocks
+   *    not forming part of this trigger domain.
+   *    The value of kAliHLTAnyDataTypeID can be used to specify the 'any' type
+   *    wild card value.
+   * \param origin  The origin string, such as the detector name, that must match
+   *    the data blocks not forming part of this trigger domain.
+   *    The value of kAliHLTDataOriginAny can be used to specify the 'any' origin
+   *    wild card value.
+   * \param spec  The specification bits that must match for the blocks that do
+   *    not form part of this trigger domain.
+   */
+  void Remove(const char* blocktype, const char* origin, UInt_t spec);
+  
+  /**
+   * This checks to see if the given entry (or class of entries, if the entry uses
+   * wild card values) is part of the trigger domain.
+   * \param entry  This is the entry to check for.
+   * \return  true if data blocks that match the entry are part of this
+   *    trigger domain and false otherwise.
+   * \note If the block contains the 'any' wild card values for the data type
+   *    origin or specification, then the inclusive domains are treated
+   *    optimistically and the exclusive domains pessimistically. This means that
+   *    the wild card values are assumed to fall within the trigger domain for the
+   *    optimistic case, but fall outside the domain for the pessimistic case.
+   */
+  bool Contains(const AliHLTDomainEntry& entry) const;
+  
+  /**
+   * This checks to see if the given data block should be included in the HLT readout.
+   * \param block  The data block descriptor to check.
+   * \return  true if data block forms part of this trigger domain and should
+   *    be part of the readout and false otherwise.
+   * \note If the block contains the 'any' wild card values for the data type
+   *    or origin, then the inclusive domains are treated optimistically and the
+   *    exclusive domains pessimistically. This means that the wild card values
+   *    are assumed to fall within the trigger domain for the optimistic case,
+   *    but fall outside the domain for the pessimistic case.
+   */
+  bool IncludeInReadout(const AliHLTComponentBlockData* block) const;
+  
+  /**
+   * This checks to see if the given data block should not be included in the
+   * HLT readout.
+   * \param block  The data block descriptor to check.
+   * \return  true if data block does not form part of this trigger domain and
+   *    false otherwise.
+   */
+  bool ExcludeFromReadout(const AliHLTComponentBlockData* block) const
+  {
+    return ! IncludeInReadout(block);
+  }
+  
+  /**
+   * This method removes all entries in the trigger domain list, giving us and
+   * empty trigger domain set.
+   * \param  option  This is passed onto the internal fEntries TClonesArray.
+   * The method is inherited from TObject.
+   */
+  virtual void Clear(Option_t* option = "");
+  
+  /**
+   * Prints all the domain entries in this trigger domain in the order in which
+   * they are applied and if they are inclusive or exclusive.
+   * \param  option  This is not used by this method.
+   * The method is inherited from TObject.
+   */
+  virtual void Print(Option_t* option = "") const;
+
+  /**
+   * Assignment operator performs a deep copy.
+   * \param domain  The domain entry to copy from.
+   * \return  A reference to this object.
+   */
+  AliHLTTriggerDomain& operator = (const AliHLTTriggerDomain& domain);
+  
+  /**
+   * This operator adds all domain entries in <i>domain</i> to this trigger domain
+   * in such a way, so as to effectively perform a set union.
+   * \param domain  The domain object on the right hand side of the operator.
+   * \return  A reference to this object.
+   */
+  AliHLTTriggerDomain& operator |= (const AliHLTTriggerDomain& domain);
+  
+  /**
+   * This operator adds all domain entries in <i>domain</i> that do not exist in
+   * this trigger domain, but removes all entries that do exist, effectively
+   * performing an exclusive or (xor) operation.
+   * i.e. given two sets A and B the result C is given by:
+   *    C = {x : x elf A and not x elf B, or x elf B and not x elf A}
+   * where 'elf' means "is an element of".
+   * \param domain  The domain object on the right hand side of the operator.
+   * \return  A reference to this object.
+   */
+  AliHLTTriggerDomain& operator ^= (const AliHLTTriggerDomain& domain);
+  
+  /**
+   * This operator removes all domain entries from this trigger domain that do
+   * not also exist in <i>domain</i>, effectively performing a set intersect.
+   * \param domain  The domain object on the right hand side of the operator.
+   * \return  A reference to this object.
+   */
+  AliHLTTriggerDomain& operator &= (const AliHLTTriggerDomain& domain)
+  {
+    return this->operator = (*this & domain);
+  }
+  
+  /**
+   * This operator performs the same operation as the '|=' operator.
+   * \param domain  The domain object on the right hand side of the operator.
+   * \return  A reference to this object.
+   */
+  AliHLTTriggerDomain& operator += (const AliHLTTriggerDomain& domain)
+  {
+    return operator |= (domain);
+  }
+  
+  /**
+   * This operator removes all domain entries from this trigger domain that exisit
+   * in <i>domain</i>, effectively implementing a set difference.
+   * \param domain  The domain object on the right hand side of the operator.
+   * \return  A reference to this object.
+   */
+  AliHLTTriggerDomain& operator -= (const AliHLTTriggerDomain& domain);
+  
+  /**
+   * This operator returns the set complement of the trigger domain.
+   * \return  The complement of this trigger domain, such that any data block that
+   *    returns true for AliHLTTriggerDomain::IncludeInReadout() for this trigger
+   *    domain, will return false for the same method call in the returned object.
+   */
+  AliHLTTriggerDomain operator ~ () const;
+  
+  /**
+   * This operator performs a set union between this trigger domain and <i>domain</i>.
+   * \param domain  The domain object on the right hand side of the operator.
+   * \return  a trigger domain object R, such that for each data block D, we will have
+   *    R.IncludeInReadout(D) == this->IncludeInReadout(D) or domain.IncludeInReadout(D)
+   */
+  AliHLTTriggerDomain operator | (const AliHLTTriggerDomain& domain) const;
+  
+  /**
+   * This operator performs an exclusive or (xor) like operation between this trigger
+   * domain and <i>domain</i>.
+   * \param domain  The domain object on the right hand side of the operator.
+   * \return  a trigger domain object R, such that for each data block D, we will have
+   *    R.IncludeInReadout(D) == this->IncludeInReadout(D) xor domain.IncludeInReadout(D)
+   */
+  AliHLTTriggerDomain operator ^ (const AliHLTTriggerDomain& domain) const
+  {
+    AliHLTTriggerDomain result = *this;
+    return result.operator ^= (domain);
+  }
+  
+  /**
+   * This operator performs a set intersect operation between this trigger domain
+   * and <i>domain</i>.
+   * \param domain  The domain object on the right hand side of the operator.
+   * \return  a trigger domain object R, such that for each data block D, we will have
+   *    R.IncludeInReadout(D) == this->IncludeInReadout(D) and domain.IncludeInReadout(D)
+   */
+  AliHLTTriggerDomain operator & (const AliHLTTriggerDomain& domain) const;
+  
+  /**
+   * This operator performs the same operation as the '|' operator.
+   * \param domain  The domain object on the right hand side of the operator.
+   * \return  a trigger domain object R, such that for each data block D, we will have
+   *    R.IncludeInReadout(D) == this->IncludeInReadout(D) or domain.IncludeInReadout(D)
+   */
+  AliHLTTriggerDomain operator + (const AliHLTTriggerDomain& domain) const
+  {
+    AliHLTTriggerDomain result = *this;
+    return result.operator += (domain);
+  }
+  
+  /**
+   * This operator implements the set difference between this trigger domain and
+   * <i>domain</i>.
+   * \param domain  The domain object on the right hand side of the operator.
+   * \return  a trigger domain object R, such that for each data block D, we will have
+   *    R.IncludeInReadout(D) == this->IncludeInReadout(D) and not domain.IncludeInReadout(D)
+   */
+  AliHLTTriggerDomain operator - (const AliHLTTriggerDomain& domain) const
+  {
+    AliHLTTriggerDomain result = *this;
+    return result.operator -= (domain);
+  }
+  
+ private:
+  
+  /**
+   * This method merges the domain entries from <i>domain</i> by copying them into
+   * fEntries, but only the ones not marked for removal in <i>removeDomainEntry</i>.
+   * Any entries that were marked for removal in fEntries are also removed.
+   * \param removeThisEntry  Flags which indicate if the corresponding fEntries[i]
+   *    should be removed.
+   * \param entriesCount The number of entries in <i>removeThisEntry</i>.
+   * \param removeDomainEntry  Flags which indicate if the corresponding domain.fEntries[i]
+   *    was marked for removal or not. If marked for removal then it will not be copied
+   *    into this trigger domain. The size of the array is given by domain.GetEntriesFast().
+   * \param startOfIntersects  This is the start location of the new intersection domain
+   *    entries that were added to fEntries. i.e. fEntries[startOfIntersects] is the
+   *    first new intersect entry.
+   */
+  void MergeEntries(
+      const bool* removeThisEntry, Int_t entriesCount,
+      const bool* removeDomainEntry, Int_t startOfIntersects,
+      const AliHLTTriggerDomain& domain
+    );
+  
+  /**
+   * Goes throught the list of domain entries in fEntries from the first entry
+   * indicated by 'min' to the end of the list and marks for deletion all entries
+   * in fEntries that are subsets of 'entry'.
+   * The entries are marked by setting the 14'th bit in fBits with a call to
+   * AliHLTDomainEntry::SetBit(14, true).
+   * \param entry  The entry that should be the super set of the entries we mark
+   *    for removal.
+   * \param min  This is the first entry we consider, all the way up to
+   *    fEntries.GetEntriesFast() - 1.
+   */
+  void MarkForDeletionSubsetsOf(const AliHLTDomainEntry& entry, Int_t min);
+  
+  /**
+   * Removes all entries in this trigger domain which were marked for removal.
+   * These are all domain entries that have the 14'th bit set in their fBits field
+   * with a call to AliHLTDomainEntry::SetBit(14, true).
+   */
+  void RemoveMarkedEntries();
+  
+  /**
+   * Removes any redundant trigger domain entries from the fEntries list.
+   * Entries that are subsets of each other are removed. Also exclusive entries
+   * that are not subsets of any inclusive entry are also removed, because we
+   * implicitly assume a data block does not form part of the trigger domain,
+   * unless explicitly included with an inclusive domain entry. So these kinds
+   * of entries are redundant.
+   */
+  void Optimise();
+  
+  TClonesArray fEntries;  /// The list of domain entries used to decide if a data block forms part of trigger domain set.
+  
+  ClassDef(AliHLTTriggerDomain, 1) // This is a list of internal HLT data block types which should be forwarded for readout.
+
+};
+
+#endif // ALIHLTTRIGGERDOMAIN_H
+