trigger/AliHLTTriggerMonitoringComponent.cxx
trigger/AliHLTTriggerPhosClusterEnergy.cxx
trigger/AliHLTTriggerPhosMip.cxx
+trigger/AliHLTMuonSpectroScalars.cxx
+trigger/AliHLTMuonSpectroTriggerComponent.cxx
)
# fill list of header files from list of source files
AliHLTGlobalTriggerConfig.h \
AliHLTGlobalTriggerComponent.h \
AliHLTTriggerBarrelMultiplicity.h \
- AliHLTD0Trigger.h \
- AliHLTD0toKpi.h \
- AliHLTTriggerITSMultiplicity.h \
+ AliHLTD0Trigger.h \
+ AliHLTD0toKpi.h \
+ AliHLTTriggerITSMultiplicity.h \
AliHLTTriggerBarrelCosmic.h \
AliHLTTriggerAgent.h \
AliHLTEventSummary.h \
AliHLTTriggerDetectorGeom.h \
AliHLTTriggerDetectorGeomRectangle.h \
AliHLTTriggerDecisionParameters.h \
- AliHLTTriggerGammaConversion.h
+ AliHLTTriggerGammaConversion.h \
+ AliHLTMuonSpectroScalars.h \
+ AliHLTMuonSpectroTriggerComponent.h
# library sources
MODULE_SRCS:= $(CLASS_HDRS:.h=.cxx)
# enable automatic generation.
MODULE_DHDR:= AliHLTTriggerLinkDef.h
-EINCLUDE := HLT/BASE HLT/BASE/util HLT/trigger HLT/TPCLib HLT/TRD TRD HLT/ITS
+EINCLUDE := HLT/BASE HLT/BASE/util HLT/trigger HLT/TPCLib HLT/TRD TRD HLT/ITS HLT/MUON MUON
LIBRARY_DEP := -lHLTbase
--- /dev/null
+// $Id: $
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project *
+ * All rights reserved. *
+ * *
+ * Primary Authors: *
+ * Artur Szostak <artursz@iafrica.com> *
+ * *
+ * 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 AliHLTMuonSpectroScalars.cxx
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date 9 Nov 2009
+/// @brief Implementation of the muon spectrometer trigger scalars.
+///
+/// This implements the trigger scalars for the muon spectrometer that can be used
+/// in the HLT global trigger and/or added to the AliHLTEventSummary.
+
+#include "AliHLTMuonSpectroScalars.h"
+#include "AliLog.h"
+#include "TObjArray.h"
+#include "TObjString.h"
+#include "TString.h"
+#include "Riostream.h"
+
+ClassImp(AliHLTMuonSpectroScalars);
+ClassImp(AliHLTMuonSpectroScalars::AliScalar);
+
+
+AliHLTMuonSpectroScalars::AliHLTMuonSpectroScalars() :
+ TObject(),
+ fScalars(AliHLTMuonSpectroScalars::AliScalar::Class(), 128),
+ fIndex(128),
+ fIndexValid(false)
+{
+ // Default constructor.
+
+ fIndex.SetOwner(kFALSE);
+}
+
+
+AliHLTMuonSpectroScalars::AliHLTMuonSpectroScalars(const AliHLTMuonSpectroScalars& obj) :
+ TObject(obj),
+ fScalars(obj.fScalars),
+ fIndex(obj.fIndex),
+ fIndexValid(obj.fIndexValid)
+{
+ // Copy constructor performs a deep copy.
+
+ fIndex.SetOwner(kFALSE);
+}
+
+
+AliHLTMuonSpectroScalars::~AliHLTMuonSpectroScalars()
+{
+ // Default destructor.
+
+ Clear();
+}
+
+
+void AliHLTMuonSpectroScalars::Add(const char* name, const char* description, Double_t value)
+{
+ // Adds a new scalar.
+
+ new (fScalars[fScalars.GetEntriesFast()]) AliScalar(value, name, description);
+ fIndexValid = false; // Invalidate the index.
+}
+
+
+bool AliHLTMuonSpectroScalars::Exists(const char* name) const
+{
+ // Checks if the scalar exists or not.
+
+ if (not fIndexValid) MakeIndex();
+ AliScalar tmpobj(0, name, "");
+ Int_t n = fIndex.BinarySearch(&tmpobj);
+ if (n == -1) return false;
+ return true;
+}
+
+
+AliHLTMuonSpectroScalars::AliScalar* AliHLTMuonSpectroScalars::GetScalarN(UInt_t n)
+{
+ // Fetch the n'th scalar object.
+
+ if (n >= NumberOfScalars())
+ {
+ AliError(Form("Value 'n' is out of bounds. Should be in the range [0..%d].", NumberOfScalars()-1));
+ return NULL;
+ }
+ return static_cast<AliScalar*>( fScalars.UncheckedAt(Int_t(n)) );
+}
+
+
+const AliHLTMuonSpectroScalars::AliScalar* AliHLTMuonSpectroScalars::GetScalarN(UInt_t n) const
+{
+ // Fetch the n'th scalar object.
+
+ if (n >= NumberOfScalars())
+ {
+ AliError(Form("Value 'n' is out of bounds. Should be in the range [0..%d].", NumberOfScalars()-1));
+ return NULL;
+ }
+ return static_cast<const AliScalar*>( fScalars.UncheckedAt(Int_t(n)) );
+}
+
+
+AliHLTMuonSpectroScalars::AliScalar* AliHLTMuonSpectroScalars::GetScalar(const char* name)
+{
+ // Fetch the named scalar object.
+
+ if (not fIndexValid) MakeIndex();
+ AliScalar tmpobj(0, name, "");
+ Int_t n = fIndex.BinarySearch(&tmpobj);
+ if (n == -1)
+ {
+ AliError(Form("Scalar '%s' could not be found.", name));
+ return NULL;
+ }
+ return static_cast<AliScalar*>( fIndex.UncheckedAt(n) );
+}
+
+
+const AliHLTMuonSpectroScalars::AliScalar* AliHLTMuonSpectroScalars::GetScalar(const char* name) const
+{
+ // Fetch the named scalar object.
+
+ if (not fIndexValid) MakeIndex();
+ AliScalar tmpobj(0, name, "");
+ Int_t n = fIndex.BinarySearch(&tmpobj);
+ if (n == -1)
+ {
+ AliError(Form("Scalar '%s' could not be found.", name));
+ return NULL;
+ }
+ return static_cast<const AliScalar*>( fIndex.UncheckedAt(n) );
+}
+
+
+Double_t AliHLTMuonSpectroScalars::GetN(UInt_t n) const
+{
+ // Fetches the n'th scalar value.
+
+ const AliScalar* scalar = GetScalarN(n);
+ if (scalar == NULL) return 0;
+ return scalar->Value();
+}
+
+
+Double_t AliHLTMuonSpectroScalars::Get(const char* name) const
+{
+ // Fetches the n'th scalar value.
+
+ const AliScalar* scalar = GetScalar(name);
+ if (scalar == NULL) return 0;
+ return scalar->Value();
+}
+
+
+bool AliHLTMuonSpectroScalars::SetN(UInt_t n, Double_t value)
+{
+ // Sets the n'th scalar value.
+
+ AliScalar* scalar = GetScalarN(n);
+ if (scalar == NULL) return false;
+ scalar->Value(value);
+ return true;
+}
+
+
+bool AliHLTMuonSpectroScalars::Set(const char* name, Double_t value)
+{
+ // Sets the named scalar value.
+
+ AliScalar* scalar = GetScalar(name);
+ if (scalar == NULL) return false;
+ scalar->Value(value);
+ return true;
+}
+
+
+bool AliHLTMuonSpectroScalars::IncrementN(UInt_t n, UInt_t count)
+{
+ // Increments the n'th scalar by a value of 'count'.
+
+ AliScalar* scalar = GetScalarN(n);
+ if (scalar == NULL) return false;
+ scalar->Increment(count);
+ return true;
+}
+
+
+bool AliHLTMuonSpectroScalars::Increment(const char* name, UInt_t count)
+{
+ // Increments the named scalar by a value of 'count'.
+
+ AliScalar* scalar = GetScalar(name);
+ if (scalar == NULL) return false;
+ scalar->Increment(count);
+ return true;
+}
+
+
+const char* AliHLTMuonSpectroScalars::Name(UInt_t n) const
+{
+ // Fetches the n'th scalar's name.
+
+ const AliScalar* scalar = GetScalarN(n);
+ if (scalar == NULL) return NULL;
+ return scalar->Name();
+}
+
+
+const char* AliHLTMuonSpectroScalars::Description(UInt_t n) const
+{
+ // Fetches the n'th scalar's description.
+
+ const AliScalar* scalar = GetScalarN(n);
+ if (scalar == NULL) return NULL;
+ return scalar->Description();
+}
+
+
+void AliHLTMuonSpectroScalars::Reset()
+{
+ // Sets all the scalar values to zero.
+
+ for (Int_t i = 0; i < fScalars.GetEntriesFast(); ++i)
+ {
+ AliScalar* scalar = static_cast<AliScalar*>( fScalars.UncheckedAt(i) );
+ scalar->Value(0);
+ }
+}
+
+
+void AliHLTMuonSpectroScalars::Clear(Option_t* option)
+{
+ // Clears the array of scalars.
+
+ fScalars.Delete(option);
+ fIndex.Clear();
+}
+
+
+void AliHLTMuonSpectroScalars::Copy(TObject& object) const
+{
+ // Performs a deep copy.
+
+ if (object.IsA() != AliHLTMuonSpectroScalars::Class())
+ {
+ AliError(Form("Cannot copy to an object of type '%s'.", object.ClassName()));
+ return;
+ }
+ AliHLTMuonSpectroScalars* obj = static_cast<AliHLTMuonSpectroScalars*>(&object);
+ *obj = *this;
+}
+
+
+TObject* AliHLTMuonSpectroScalars::FindObject(const char* name) const
+{
+ // Finds the scalar object by name.
+
+ if (fIndexValid)
+ {
+ AliScalar tmpobj(0, name, "");
+ Int_t n = fIndex.BinarySearch(&tmpobj);
+ if (n != -1) return fIndex.UncheckedAt(n);
+ }
+ else
+ {
+ return fScalars.FindObject(name);
+ }
+ return NULL;
+}
+
+
+TObject* AliHLTMuonSpectroScalars::FindObject(const TObject* obj) const
+{
+ // Finds the scalar object with the same name as obj->GetName().
+
+ return FindObject(obj->GetName());
+}
+
+
+void AliHLTMuonSpectroScalars::Print(Option_t* option) const
+{
+ // Prints the muon spectrometer's HLT trigger scalars.
+
+ TString opt = option;
+ if (opt == "compact")
+ {
+ if (NumberOfScalars() > 0)
+ cout << GetN(0);
+ for (UInt_t i = 1; i < NumberOfScalars(); ++i) cout << ", " << GetN(i);
+ cout << endl;
+ return;
+ }
+
+ // Calculate the maximum field width required to keep things aligned.
+ int fieldwidth = 0;
+ for (Int_t i = 0; i < fScalars.GetEntriesFast(); ++i)
+ {
+ AliScalar* scalar = static_cast<AliScalar*>( fScalars.UncheckedAt(i) );
+ int length = strlen(scalar->Description());
+ if (length > fieldwidth) fieldwidth = length;
+ }
+ if (fieldwidth > 80) fieldwidth = 80;
+
+ cout << "HLT muon spectrometer trigger scalars:" << endl;
+ for (Int_t i = 0; i < fScalars.GetEntriesFast(); ++i)
+ {
+ AliScalar* scalar = static_cast<AliScalar*>( fScalars.UncheckedAt(i) );
+ cout << setw(fieldwidth) << scalar->Description() << setw(0)
+ << " = " << scalar->Value() << endl;
+ }
+ if (fScalars.GetEntriesFast() == 0) cout << "(none)" << endl;
+}
+
+
+AliHLTMuonSpectroScalars& AliHLTMuonSpectroScalars::operator = (const AliHLTMuonSpectroScalars& obj)
+{
+ // Performs a deep copy.
+
+ if (this == &obj) return *this;
+ fScalars.Delete();
+ for (Int_t i = 0; i < obj.fScalars.GetEntriesFast(); ++i)
+ {
+ AliScalar* scalar = static_cast<AliScalar*>( obj.fScalars.UncheckedAt(i) );
+ Add(scalar->Name(), scalar->Description(), scalar->Value());
+ }
+ MakeIndex();
+ return *this;
+}
+
+
+bool AliHLTMuonSpectroScalars::operator == (const AliHLTMuonSpectroScalars& obj) const
+{
+ // Compares two scalar objects.
+
+ if (not fIndexValid) MakeIndex();
+ if (fScalars.GetEntriesFast() != obj.fScalars.GetEntriesFast()) return false;
+ for (Int_t i = 0; i < obj.fScalars.GetEntriesFast(); ++i)
+ {
+ AliScalar* scalar1 = static_cast<AliScalar*>( obj.fScalars.UncheckedAt(i) );
+ Int_t n = fIndex.BinarySearch(scalar1);
+ if (n == -1) return false;
+ AliScalar* scalar2 = static_cast<AliScalar*>( fIndex.UncheckedAt(n) );
+ if (scalar1->Value() != scalar2->Value()) return false;
+ }
+ return true;
+}
+
+
+void AliHLTMuonSpectroScalars::MakeIndex() const
+{
+ // Makes the index fIndex required for faster searching in fScalars.
+
+ fIndex.Clear();
+ for (Int_t i = 0; i < fScalars.GetEntriesFast(); ++i)
+ {
+ fIndex.Add(fScalars.UncheckedAt(i));
+ }
+ fIndex.Sort();
+ fIndexValid = true;
+}
+
+
+void AliHLTMuonSpectroScalars::AliScalar::Copy(TObject& object) const
+{
+ // Performs a deep copy.
+
+ if (object.IsA() != AliHLTMuonSpectroScalars::AliScalar::Class())
+ {
+ AliError(Form("Cannot copy to an object of type '%s'.", object.ClassName()));
+ return;
+ }
+ AliHLTMuonSpectroScalars::AliScalar* obj = static_cast<AliHLTMuonSpectroScalars::AliScalar*>(&object);
+ *obj = *this;
+}
--- /dev/null
+//-*- Mode: C++ -*-
+// $Id: $
+#ifndef AliHLTMUONSPECTROSCALARS_H
+#define AliHLTMUONSPECTROSCALARS_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 AliHLTMuonSpectroScalars.h
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date 9 Nov 2009
+/// @brief Declares the scalars class for the muon spectrometer.
+
+#include "TObject.h"
+#include "TObjArray.h"
+#include "TClonesArray.h"
+
+/**
+ * @class AliHLTMuonSpectroScalars
+ * @brief Muon spectrometer HLT trigger summary scalars.
+ *
+ * This scalars class contains summary information such as the number of tracks found,
+ * number of pairs found and so on, all within the muon spectrometer.
+ * Objects of this class are generated by the AliHLTMuonSpectroTriggerComponent to
+ * be used in the HLT global trigger and/or added to the AliHLTEventSummary object.
+ *
+ * \ingroup alihlt_trigger_components
+ */
+class AliHLTMuonSpectroScalars : public TObject
+{
+public:
+ /**
+ * Scalar class to store all the required information for a muon spectrometer scalar.
+ */
+ class AliScalar : public TObject
+ {
+ public:
+ /// Default constructor
+ AliScalar() : TObject(), fValue(0), fName(), fDescription() {}
+
+ /// Constructor to set some initial values.
+ AliScalar(Double_t value, const char* name, const char* description) :
+ TObject(), fValue(value), fName(name), fDescription(description)
+ {}
+
+ /// Default destructor
+ virtual ~AliScalar() {}
+
+ /// Inherited from TObject. Returns the name of the scalar.
+ virtual const char* GetName() const { return fName; }
+
+ /// Inherited from TObject. Returns the description of the scalar.
+ virtual const char* GetTitle() const {return fDescription; }
+
+ /// Inherited from TObject. Compares two scalar names.
+ virtual Int_t Compare(const TObject *obj) const
+ {
+ return fName.CompareTo(obj->GetName());
+ }
+
+ /// Inherited from TObject. Returns true.
+ virtual Bool_t IsSortable() const { return kTRUE; }
+
+ /**
+ * Inherited from TObject.
+ * Returns true if the names of the scalars are the same.
+ */
+ virtual Bool_t IsEqual(const TObject *obj) const
+ {
+ return fName == obj->GetName();
+ }
+
+ /// Resets the scalar value.
+ virtual void Clear(Option_t* /*option*/ = "") { fValue = 0; }
+
+ /// Inherited form TObject. Performs a deep copy.
+ virtual void Copy(TObject& object) const;
+
+ /// Returns the value of the scalar.
+ Double_t Value() const { return fValue; }
+
+ /**
+ * Sets a new value for the scalar.
+ * \param value The new value to use. If negative then 0 is used instead.
+ */
+ void Value(Double_t value) { fValue = value >= 0 ? value : 0; }
+
+ /// Increments the scalar value by 'count'.
+ void Increment(UInt_t count = 1) { fValue += count; }
+
+ /// Returns the name of the scalar.
+ const char* Name() const { return fName.Data(); }
+
+ /// Returns the description string for the scalar.
+ const char* Description() const { return fDescription.Data(); }
+
+ /// Checks if two scalar objects are equal.
+ bool operator == (const AliScalar& x) const
+ {
+ return fValue == x.fValue and fName == x.fName
+ and fDescription == x.fDescription;
+ }
+
+ /// Checks if two scalar objects are not equal.
+ bool operator != (const AliScalar& x) const
+ {
+ return not (this->operator == (x));
+ }
+
+ private:
+ Double_t fValue; /// The scalar value.
+ TString fName; /// The name of the scalar.
+ TString fDescription; /// A description of what the scalar represents.
+
+ ClassDef(AliScalar, 1); // A scalar value for the muon spectrometer.
+ };
+
+ /// Default constructor.
+ AliHLTMuonSpectroScalars();
+
+ /// The copy constructor performs a deep copy.
+ AliHLTMuonSpectroScalars(const AliHLTMuonSpectroScalars& obj);
+
+ /// Default destructor.
+ virtual ~AliHLTMuonSpectroScalars();
+
+ /**
+ * Adds a new scalar to the end of the scalars list.
+ * \param name The name of the scalar value.
+ * \param description A short description of the scalar value.
+ * \param value The value of the new scalar.
+ */
+ void Add(const char* name, const char* description, Double_t value = 0);
+
+ /// Returns the number of scalar values.
+ UInt_t NumberOfScalars() const { return UInt_t(fScalars.GetEntriesFast()); }
+
+ /// Checks to see if the named scalar exists.
+ bool Exists(const char* name) const;
+
+ /**
+ * Fetches the n'th scalar object.
+ * \param n The scalar object to fetch.
+ * \returns the n'th scalar object, otherwise NULL if <i>n</i> was out of range.
+ */
+ AliScalar* GetScalarN(UInt_t n);
+ const AliScalar* GetScalarN(UInt_t n) const;
+
+ /**
+ * Fetches the named scalar object. Will apply a binary search for the object.
+ * This means rebuilding the internal index if necessary.
+ * \param name The name of the scalar object.
+ * \returns the found scalar object, otherwise NULL if it was not found.
+ */
+ AliScalar* GetScalar(const char* name);
+ const AliScalar* GetScalar(const char* name) const;
+
+ /**
+ * Fetches the n'th scalar value.
+ * \param n The scalar number to fetch.
+ * \returns the n'th scalar, otherwise 0 if <i>n</i> was out of range.
+ */
+ Double_t GetN(UInt_t n) const;
+
+ /**
+ * Fetches the a scalar value by name.
+ * \param name The name of the scalar.
+ * \returns the scalar's value, otherwise 0 if it could not be found.
+ */
+ Double_t Get(const char* name) const;
+
+ /**
+ * Sets the n'th scalar value.
+ * \param n The scalar number to set.
+ * \param value The new value for the scalar.
+ * \returns true if the scalar could be set, otherwise false which means
+ * that <i>n</i> was out of range.
+ */
+ bool SetN(UInt_t n, Double_t value);
+
+ /**
+ * Sets the named scalar's value.
+ * \param name The name of the scalar to set.
+ * \param value The new value for the scalar.
+ * \returns true if the scalar could be set, otherwise false which means
+ * that it was not found.
+ */
+ bool Set(const char* name, Double_t value);
+
+ /**
+ * Increments the n'th scalar by a value of 'count'.
+ * \param n The scalar number to increment.
+ * \param count The number to increment the scalar by. The default is 1.
+ * \returns true if the scalar could be incremented, otherwise false
+ * which means that <i>n</i> was out of range.
+ */
+ bool IncrementN(UInt_t n, UInt_t count = 1);
+
+ /**
+ * Increments the n'th scalar by a value of 'count'.
+ * \param name The name of the scalar to set.
+ * \param count The number to increment the scalar by. The default is 1.
+ * \returns true if the scalar could be incremented, otherwise false
+ * which means that it could not be found.
+ */
+ bool Increment(const char* name, UInt_t count = 1);
+
+ /**
+ * Returns the name of the n'th scalar.
+ * \param n The scalar number for which to return the name.
+ * \returns the n'th scalar's name, otherwise NULL if <i>n</i> was out of range.
+ */
+ const char* Name(UInt_t n) const;
+
+ /**
+ * Returns the description string for the n'th scalar.
+ * \param n The scalar number for which to return the description.
+ * \returns the n'th scalar's description, otherwise NULL if <i>n</i> was out of range.
+ */
+ const char* Description(UInt_t n) const;
+
+ /// Resets all scalar values to zero.
+ void Reset();
+
+ /**
+ * Removes all the scalars from the internal array.
+ * \param option This is passed onto the internal Delete method.
+ */
+ virtual void Clear(Option_t* option = "");
+
+ /// Inherited form TObject. Performs a deep copy.
+ virtual void Copy(TObject& object) const;
+
+ /// Finds the scalar object by name. Will not apply a binary search if fIndex
+ /// was invalidated.
+ virtual TObject* FindObject(const char* name) const;
+
+ /// Finds the scalar object with the same name as obj->GetName().
+ /// Will not apply a binary search if fIndex was invalidated.
+ virtual TObject* FindObject(const TObject* obj) const;
+
+ /**
+ * Inherited from TObject, this prints the contents of this summary object.
+ * \param option Can be "compact", which will just print all the values on one line.
+ */
+ virtual void Print(Option_t* option = "") const;
+
+ /**
+ * The assignment operator performs a deep copy.
+ */
+ AliHLTMuonSpectroScalars& operator = (const AliHLTMuonSpectroScalars& obj);
+
+ /// Returns the n'th scalar value or -1 if n is out of range.
+ Double_t operator [] (UInt_t n) const { return GetN(n); }
+
+ /// Returns the named scalar value or -1 if not found.
+ Double_t operator [] (const TString& name) const { return Get(name.Data()); }
+
+ /**
+ * Comparison operator to check if two scalar objects have the same values.
+ * \note The description strings are not checked so they could be different
+ * and the order of the scalars does not matter either.
+ */
+ bool operator == (const AliHLTMuonSpectroScalars& obj) const;
+
+ /**
+ * Comparison operator to check if two scalar objects are different.
+ * \note The description strings are not checked, only the values
+ * and the order of the scalars does not matter either.
+ */
+ bool operator != (const AliHLTMuonSpectroScalars& obj) const
+ {
+ return not (this->operator == (obj));
+ }
+
+private:
+
+ /// Creates the index required for faster searches of the fScalars array.
+ void MakeIndex() const;
+
+ TClonesArray fScalars; /// The list of scalars. Contains AliScalar objects.
+ mutable TObjArray fIndex; //! A sorted index of the scalars for faster searches.
+ mutable bool fIndexValid; //! Indicates that the index is valid.
+
+ ClassDef(AliHLTMuonSpectroScalars, 1); // HLT trigger scalars for the muon spectrometer.
+};
+
+#endif // AliHLTMUONSPECTROSCALARS_H
--- /dev/null
+// $Id: $
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project *
+ * All rights reserved. *
+ * *
+ * Primary Authors: *
+ * Artur Szostak <artursz@iafrica.com> *
+ * *
+ * 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 AliHLTMuonSpectroTriggerComponent.cxx
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date 9 Nov 2009
+/// @brief Implementation of the muon spectrometer trigger component.
+///
+/// The AliHLTMuonSpectroTriggerComponent component is used to generate the HLT
+/// trigger for the muon spectrometer.
+
+#include "AliHLTMuonSpectroTriggerComponent.h"
+#include "AliHLTTriggerDecision.h"
+#include "AliHLTMuonSpectroScalars.h"
+#include "AliHLTMUONDataBlockReader.h"
+#include "AliHLTMUONConstants.h"
+#include "AliHLTMUONUtils.h"
+#include "AliMUONTriggerDDLDecoderEventHandler.h"
+
+ClassImp(AliHLTMuonSpectroTriggerComponent);
+
+
+AliHLTMuonSpectroTriggerComponent::AliHLTMuonSpectroTriggerComponent() :
+ AliHLTTrigger(),
+ fBufferSizeConst(1024*16),
+ fBufferSizeMultiplier(1),
+ fMakeStats(false),
+ fTriggerHits(false),
+ fTriggerTrigRecs(false),
+ fTriggerTracks(true),
+ fTriggerDimuons(true)
+{
+ // Default constructor.
+}
+
+
+AliHLTMuonSpectroTriggerComponent::~AliHLTMuonSpectroTriggerComponent()
+{
+ // Default destructor.
+}
+
+
+void AliHLTMuonSpectroTriggerComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list) const
+{
+ // Returns the list of input types expected.
+
+ list.push_back(AliHLTMUONConstants::TriggerRecordsBlockDataType());
+ list.push_back(AliHLTMUONConstants::RecHitsBlockDataType());
+ list.push_back(AliHLTMUONConstants::MansoTracksBlockDataType());
+ list.push_back(AliHLTMUONConstants::SinglesDecisionBlockDataType());
+ list.push_back(AliHLTMUONConstants::PairsDecisionBlockDataType());
+}
+
+
+void AliHLTMuonSpectroTriggerComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list) const
+{
+ // Return the output data types generated.
+
+ list.push_back(kAliHLTDataTypeTriggerDecision);
+ list.push_back(kAliHLTDataTypeEventStatistics|kAliHLTDataOriginHLT);
+}
+
+
+void AliHLTMuonSpectroTriggerComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
+{
+ // Returns the output data size estimate.
+
+ constBase = fBufferSizeConst;
+ inputMultiplier = fBufferSizeMultiplier;
+}
+
+
+AliHLTComponent* AliHLTMuonSpectroTriggerComponent::Spawn()
+{
+ // Creates and returns a new instance.
+
+ return new AliHLTMuonSpectroTriggerComponent;
+}
+
+
+Int_t AliHLTMuonSpectroTriggerComponent::DoInit(int argc, const char** argv)
+{
+ // Initialise the component.
+
+ fMakeStats = false;
+ fTriggerHits = false;
+ fTriggerTrigRecs = false;
+ fTriggerTracks = false;
+ fTriggerDimuons = false;
+
+ for (int i = 0; i < argc; i++)
+ {
+ if (strcmp(argv[i], "-makestats") == 0)
+ {
+ fMakeStats = true;
+ continue;
+ }
+ if (strcmp(argv[i], "-triggerhits") == 0)
+ {
+ fTriggerHits = true;
+ continue;
+ }
+ if (strcmp(argv[i], "-triggertrigrecs") == 0)
+ {
+ fTriggerTrigRecs = true;
+ continue;
+ }
+ if (strcmp(argv[i], "-triggertracks") == 0)
+ {
+ fTriggerTracks = true;
+ continue;
+ }
+ if (strcmp(argv[i], "-triggerdimuons") == 0)
+ {
+ fTriggerDimuons = true;
+ continue;
+ }
+ if (strcmp(argv[i], "-triggerany") == 0)
+ {
+ fTriggerHits = true;
+ fTriggerTrigRecs = true;
+ fTriggerTracks = true;
+ fTriggerDimuons = true;
+ continue;
+ }
+
+ HLTError("Unknown option '%s'.", argv[i]);
+ return -EINVAL;
+ } // for loop
+
+ // If nothing was turned on to trigger then turn everything on by default.
+ if (fTriggerHits == false and fTriggerTrigRecs == false
+ and fTriggerTracks == false and fTriggerDimuons == false
+ )
+ {
+ fTriggerTracks = true;
+ fTriggerDimuons = true;
+ }
+
+ return 0;
+}
+
+
+Int_t AliHLTMuonSpectroTriggerComponent::DoDeinit()
+{
+ // Cleans up the component.
+
+ return 0;
+}
+
+
+int AliHLTMuonSpectroTriggerComponent::DoTrigger()
+{
+ // Applies the trigger for the HLT.
+
+ int result = 0;
+
+ bool gothits = false;
+ bool gottrigrecs = false;
+ bool gottracks = false;
+ bool gotsingles = false;
+ bool gotpairs = false;
+ UInt_t nhits = 0;
+ UInt_t nhitsMTR = 0;
+ UInt_t nhitsMCH = 0;
+ UInt_t nhitsCh[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ UInt_t ntrigrecs = 0;
+ UInt_t nL0plus = 0;
+ UInt_t nL0minus = 0;
+ UInt_t ntracksMT = 0; // from Manso track blocks.
+ UInt_t ntracksSD = 0; // from singles decision blocks
+ UInt_t nplus = 0;
+ UInt_t nminus = 0;
+ UInt_t nlowpt = 0;
+ UInt_t nhighpt = 0;
+ Double_t minpt = -1;
+ Double_t maxpt = -1;
+ UInt_t nlikeany = 0;
+ UInt_t nlikelow = 0;
+ UInt_t nlikehigh = 0;
+ UInt_t nunlikeany = 0;
+ UInt_t nunlikelow = 0;
+ UInt_t nunlikehigh = 0;
+ UInt_t nlowmass = 0;
+ UInt_t nhighmass = 0;
+ Double_t minmass = -1;
+ Double_t maxmass = -1;
+
+
+ AliHLTComponentDataType blockType = AliHLTMUONConstants::TriggerRecordsBlockDataType();
+ for (const AliHLTComponentBlockData* block = GetFirstInputBlock(blockType);
+ block != NULL;
+ block = GetNextInputBlock()
+ )
+ {
+ AliHLTMUONTriggerRecordsBlockReader trigRecsBlock(block->fPtr, block->fSize);
+ if (not IsBlockOk(trigRecsBlock, blockType))
+ {
+ HLTWarning("Skipping problematic block '%s'", DataType2Text(blockType).c_str());
+ continue;
+ }
+ gothits = true;
+
+ ntrigrecs += trigRecsBlock.Nentries();
+ for (AliHLTUInt32_t i = 0; i < trigRecsBlock.Nentries(); ++i)
+ {
+ AliHLTMUONParticleSign sign;
+ bool hitset[4];
+ AliHLTMUONUtils::UnpackTriggerRecordFlags(trigRecsBlock[i].fFlags, sign, hitset);
+ switch (sign)
+ {
+ case kSignPlus: ++nL0plus; break;
+ case kSignMinus: ++nL0minus; break;
+ default: break;
+ }
+ for (int j = 0; j < 4; ++j)
+ {
+ if (hitset[j])
+ {
+ ++nhitsCh[j+10];
+ ++nhits;
+ ++nhitsMTR;
+ }
+ }
+ }
+ }
+
+ blockType = AliHLTMUONConstants::RecHitsBlockDataType();
+ for (const AliHLTComponentBlockData* block = GetFirstInputBlock(blockType);
+ block != NULL;
+ block = GetNextInputBlock()
+ )
+ {
+ AliHLTMUONRecHitsBlockReader hitsBlock(block->fPtr, block->fSize);
+ if (not IsBlockOk(hitsBlock, blockType))
+ {
+ HLTWarning("Skipping problematic block '%s'", DataType2Text(blockType).c_str());
+ continue;
+ }
+ gottrigrecs = true;
+
+ nhits += hitsBlock.Nentries();
+ nhitsMCH += hitsBlock.Nentries();
+ for (AliHLTUInt32_t i = 0; i < hitsBlock.Nentries(); ++i)
+ {
+ AliHLTUInt8_t chamber;
+ AliHLTUInt16_t detElemId;
+ AliHLTMUONUtils::UnpackRecHitFlags(hitsBlock[i].fFlags, chamber, detElemId);
+ if (chamber < 10)
+ {
+ ++nhitsCh[chamber];
+ }
+ else
+ {
+ HLTWarning("Received a reconstructed hit which indicates"
+ " an invalid chamber number of %d. The expected"
+ " range is [0..9]. The data blockis probably corrupt.",
+ int(chamber)
+ );
+ }
+ }
+ }
+
+ blockType = AliHLTMUONConstants::MansoTracksBlockDataType();
+ for (const AliHLTComponentBlockData* block = GetFirstInputBlock(blockType);
+ block != NULL;
+ block = GetNextInputBlock()
+ )
+ {
+ AliHLTMUONMansoTracksBlockReader tracksBlock(block->fPtr, block->fSize);
+ if (not IsBlockOk(tracksBlock, blockType))
+ {
+ HLTWarning("Skipping problematic block '%s'", DataType2Text(blockType).c_str());
+ continue;
+ }
+ gottracks = true;
+
+ ntracksMT += tracksBlock.Nentries();
+ for (AliHLTUInt32_t i = 0; i < tracksBlock.Nentries(); ++i)
+ {
+ AliHLTMUONParticleSign sign;
+ bool hitset[4];
+ AliHLTMUONUtils::UnpackMansoTrackFlags(tracksBlock[i].fFlags, sign, hitset);
+ switch (sign)
+ {
+ case kSignPlus: ++nplus; break;
+ case kSignMinus: ++nminus; break;
+ default: break;
+ }
+ }
+ }
+
+ blockType = AliHLTMUONConstants::SinglesDecisionBlockDataType();
+ for (const AliHLTComponentBlockData* block = GetFirstInputBlock(blockType);
+ block != NULL;
+ block = GetNextInputBlock()
+ )
+ {
+ AliHLTMUONSinglesDecisionBlockReader singlesBlock(block->fPtr, block->fSize);
+ if (not IsBlockOk(singlesBlock, blockType))
+ {
+ HLTWarning("Skipping problematic block '%s'", DataType2Text(blockType).c_str());
+ continue;
+ }
+ gotsingles = true;
+
+ ntracksSD += singlesBlock.Nentries();
+ nlowpt += singlesBlock.BlockHeader().fNlowPt;
+ nhighpt += singlesBlock.BlockHeader().fNhighPt;
+ for (AliHLTUInt32_t i = 0; i < singlesBlock.Nentries(); ++i)
+ {
+ if (singlesBlock[i].fPt < minpt or minpt == -1) minpt = singlesBlock[i].fPt;
+ if (singlesBlock[i].fPt > maxpt or maxpt == -1) maxpt = singlesBlock[i].fPt;
+ }
+ }
+
+ blockType = AliHLTMUONConstants::PairsDecisionBlockDataType();
+ for (const AliHLTComponentBlockData* block = GetFirstInputBlock(blockType);
+ block != NULL;
+ block = GetNextInputBlock()
+ )
+ {
+ AliHLTMUONPairsDecisionBlockReader pairsBlock(block->fPtr, block->fSize);
+ if (not IsBlockOk(pairsBlock, blockType))
+ {
+ HLTWarning("Skipping problematic block '%s'", DataType2Text(blockType).c_str());
+ continue;
+ }
+ gotpairs = true;
+
+ nunlikeany += pairsBlock.BlockHeader().fNunlikeAnyPt;
+ nlikeany += pairsBlock.BlockHeader().fNlikeAnyPt;
+ // Dont use the other scalars from the pair decisions block header because
+ // they are much more restrictive. They count pairs where both tracks pass
+ // the low or high pT cut. But we want to relax this to just one track needs
+ // to pass the pT cut.
+ for (AliHLTUInt32_t i = 0; i < pairsBlock.Nentries(); ++i)
+ {
+ if (pairsBlock[i].fInvMass < minmass or minmass == -1) minmass = pairsBlock[i].fInvMass;
+ if (pairsBlock[i].fInvMass > maxmass or maxmass == -1) maxmass = pairsBlock[i].fInvMass;
+ bool highMass, lowMass, unlike;
+ AliHLTUInt8_t highPtCount, lowPtCount;
+ AliHLTMUONUtils::UnpackPairDecisionBits(
+ pairsBlock[i].fTriggerBits, highMass, lowMass, unlike,
+ highPtCount, lowPtCount
+ );
+ if (unlike)
+ {
+ if (lowPtCount >= 1) ++nunlikelow;
+ if (highPtCount >= 1) ++nunlikehigh;
+ if (lowMass) ++nlowmass;
+ if (highMass) ++nhighmass;
+ }
+ else
+ {
+ if (lowPtCount >= 1) ++nlikelow;
+ if (highPtCount >= 1) ++nlikehigh;
+ }
+ }
+ }
+
+ // Select the largest value for nTracks since we might only get this information
+ // from singles decision blocks.
+ UInt_t ntracks = ntracksSD > ntracksMT ? ntracksSD : ntracksMT;
+
+ bool triggeredOnHits = fTriggerHits and nhitsMCH > 0;
+ bool triggeredOnTrigRecs = fTriggerTrigRecs and ntrigrecs > 0;
+ bool triggeredOnTracks = fTriggerTracks and ntracks > 0;
+ bool triggeredOnDimuons = fTriggerDimuons and (nunlikeany > 0
+ or nunlikelow > 0 or nunlikehigh > 0 or nlowmass > 0 or nhighmass > 0);
+
+ if (triggeredOnDimuons)
+ {
+ SetDescription("Dimuon in muon spectrometer");
+ SetTriggerDomain(AliHLTTriggerDomain("*******:MUON"));
+ }
+ else if (triggeredOnTracks)
+ {
+ SetDescription("Tracks in muon spectrometer");
+ SetTriggerDomain(AliHLTTriggerDomain("*******:MUON"));
+ }
+ else if (triggeredOnTrigRecs)
+ {
+ SetDescription("Muon trigger chambers triggered");
+ if (triggeredOnHits)
+ {
+ SetReadoutList(AliHLTReadoutList(AliHLTReadoutList::kMUONTRG | AliHLTReadoutList::kMUONTRK));
+ SetTriggerDomain(AliHLTTriggerDomain("TRIGRECS:MUON,RECHITS :MUON"));
+ }
+ else
+ {
+ SetReadoutList(AliHLTReadoutList(AliHLTReadoutList::kMUONTRG));
+ SetTriggerDomain(AliHLTTriggerDomain("TRIGRECS:MUON"));
+ }
+ }
+ else if (triggeredOnHits)
+ {
+ SetDescription("Hits in muon tracking chambers");
+ SetReadoutList(AliHLTReadoutList(AliHLTReadoutList::kMUONTRK));
+ SetTriggerDomain(AliHLTTriggerDomain("RECHITS :MUON"));
+ }
+ else
+ {
+ SetDescription("Not triggered");
+ SetTriggerDomain(AliHLTTriggerDomain());
+ }
+
+ if (triggeredOnDimuons or triggeredOnTracks or triggeredOnTrigRecs or triggeredOnHits)
+ {
+ result = TriggerEvent();
+ if (result == -ENOSPC) goto increaseBuffer;
+ if (result != 0) return result;
+ }
+
+ if (fMakeStats)
+ {
+ AliHLTMuonSpectroScalars scalars;
+ if (gothits and gottrigrecs) scalars.Add("NHits", "Total number of hits", nhits);
+ if (gottrigrecs) scalars.Add("NHitsMTR", "Number of hits in trigger chambers", nhitsMTR);
+ if (gothits)
+ {
+ scalars.Add("NHitsMCH", "Number of hits in tracking chambers", nhitsMCH);
+ for (int i = 0; i < 10; i++)
+ {
+ scalars.Add(Form("NHitsCh%d", i+1), Form("Number of hits in chamber %d", i+1), nhitsCh[i]);
+ }
+ }
+ if (gottrigrecs)
+ {
+ for (int i = 10; i < 14; i++)
+ {
+ scalars.Add(Form("NHitsCh%d", i+1), Form("Number of hits in chamber %d", i+1), nhitsCh[i]);
+ }
+ scalars.Add("NTrigRecs", "Total number of trigger records", ntrigrecs);
+ scalars.Add("NL0+", "Number of positive sign tracks in L0", nL0plus);
+ scalars.Add("NL0-", "Number of negative sign tracks in L0", nL0minus);
+ }
+ if (gottracks or gotsingles) scalars.Add("NTracks", "Total number of tracks", ntracks);
+ if (gottracks)
+ {
+ scalars.Add("N+", "Number of positive sign tracks", nplus);
+ scalars.Add("N-", "Number of negative sign tracks", nminus);
+ }
+ if (gotsingles)
+ {
+ scalars.Add("NLowPt", "Number of low pT tracks", nlowpt);
+ scalars.Add("NHighPt", "Number of high pT tracks", nhighpt);
+ scalars.Add("MinPt", "Minimum pT found (GeV/c)", minpt);
+ scalars.Add("MaxPt", "Maximum pT found (GeV/c)", maxpt);
+ }
+ if (gotpairs)
+ {
+ scalars.Add("NLikeAny", "Number of like sign track pairs", nlikeany);
+ scalars.Add("NLikeLow", "Number of like sign pairs with at least 1 low pT track.", nlikelow);
+ scalars.Add("NLikeHigh", "Number of like sign pairs with at least 1 high pT track.", nlikehigh);
+ scalars.Add("NUnlikeAny", "Number of unlike sign track pairs", nunlikeany);
+ scalars.Add("NUnlikeLow", "Number of unlike sign pairs with at least 1 low pT track.", nunlikelow);
+ scalars.Add("NUnlikeHigh", "Number of unlike sign pairs with at least 1 high pT track.", nunlikehigh);
+ scalars.Add("NLowMass", "Number of low mass dimuons", nlowmass);
+ scalars.Add("NHighMass", "Number of high mass dimuons", nhighmass);
+ scalars.Add("MinMass", "Minimum invariant mass found for dimuon (GeV/c^2)", minmass);
+ scalars.Add("MaxMass", "Maximum invariant mass found for dimuon (GeV/c^2)", maxmass);
+ }
+
+ result = PushBack(&scalars, kAliHLTDataTypeEventStatistics|kAliHLTDataOriginHLT);
+ if (result == -ENOSPC) goto increaseBuffer;
+ }
+ return result;
+
+increaseBuffer:
+ // Increase the estimated buffer space required since the PushBack
+ // or TriggerEvent methods indicate that they ran out of buffer space.
+ fBufferSizeConst += 1024*1024;
+ fBufferSizeMultiplier *= 2.;
+ return -ENOSPC;
+}
+
+
+template <typename BlockReader>
+bool AliHLTMuonSpectroTriggerComponent::IsBlockOk(
+ const BlockReader& reader, const AliHLTComponentDataType& type
+ ) const
+{
+ // Method for checking the block structure.
+
+ if (not reader.BufferSizeOk())
+ {
+ string name = DataType2Text(type).c_str();
+ size_t headerSize = sizeof(typename BlockReader::HeaderType);
+ if (reader.BufferSize() < headerSize)
+ {
+ HLTError("Received a '%s' data block with a size of %d bytes,"
+ " which is smaller than the minimum valid size of %d bytes."
+ " The block must be corrupt.",
+ name.c_str(), reader.BufferSize(), headerSize
+ );
+ }
+
+ size_t expectedWidth = sizeof(typename BlockReader::ElementType);
+ if (reader.CommonBlockHeader().fRecordWidth != expectedWidth)
+ {
+ HLTError("Received a '%s' data block with a record"
+ " width of %d bytes, but the expected value is %d bytes."
+ " The block might be corrupt.",
+ name.c_str(),
+ reader.CommonBlockHeader().fRecordWidth,
+ expectedWidth
+ );
+ }
+
+ HLTError("Received a '%s' data block with a size of %d bytes,"
+ " but the block header claims the block should be %d bytes."
+ " The block might be corrupt.",
+ name.c_str(), reader.BufferSize(), reader.BytesUsed()
+ );
+ return false;
+ }
+ return true;
+}
--- /dev/null
+//-*- Mode: C++ -*-
+// $Id: $
+#ifndef AliHLTMUONSPECTROTRIGGERCOMPONENT_H
+#define AliHLTMUONSPECTROTRIGGERCOMPONENT_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 AliHLTMuonSpectroTriggerComponent.h
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date 9 Nov 2009
+/// @brief Declares the trigger component for the muon spectrometer.
+
+#include "AliHLTTrigger.h"
+
+/**
+ * \class AliHLTMuonSpectroTriggerComponent
+ * \brief Muon spectrometer trigger component.
+ *
+ * This component takes the HLT MUON decision generated by the AliHLTMUONDecisionComponent
+ * and creates a HLT trigger suitable for the HLT global trigger framework. Some
+ * optional summary statistics scalars can be generated with the "-makestats" option.
+ * This extra statistics information is filled in the AliHLTMuonSpectroScalars object,
+ * and written to a kAliHLTDataTypeEventStatistics type data block. Thus, the scalars
+ * object can be automatically added to the AliHLTEventSummary object by the
+ * AliHLTEventSummaryProducerComponent.
+ *
+ * <h2>General properties:</h2>
+ *
+ * Component ID: \b MuonSpectroTrigger <br>
+ * Library: \b libAliHLTTrigger.so <br>
+ * Input Data Types: \li AliHLTMUONConstants::TriggerRecordsBlockDataType() = "TRIGRECS:MUON" <br>
+ * \li AliHLTMUONConstants::RecHitsBlockDataType() = "RECHITS :MUON" <br>
+ * \li AliHLTMUONConstants::MansoTracksBlockDataType() = "MANTRACK:MUON" <br>
+ * \li AliHLTMUONConstants::SinglesDecisionBlockDataType() = "DECIDSIN:MUON" <br>
+ * \li AliHLTMUONConstants::PairsDecisionBlockDataType() = "DECIDPAR:MUON" <br>
+ * Output Data Types: \li kAliHLTDataTypeTriggerDecision = "TRIG_DEC:HLT " <br>
+ * \li kAliHLTDataTypeReadoutList = "HLTRDLST:HLT " <br>
+ * \li kAliHLTDataTypeEventStatistics|kAliHLTDataOriginHLT = "EV_STATI:HLT " <br>
+ *
+ * <h2>Mandatory arguments:</h2>
+ * None.
+ *
+ * <h2>Optional arguments:</h2>
+ * \li -makestats <br>
+ * If specified then the summary statistics scalars object is generated as output.
+ * The default is not to generate the statistics object. <br>
+ * \li -triggerhits <br>
+ * Indicates that the component should trigger if any hits are found in the muon
+ * spectrometer tracking chambers. This option requires that this trigger component
+ * receives the reconstructed hits data blocks. <br>
+ * \li -triggertrigrecs <br>
+ * Indicates that the component should trigger if any trigger records are found.
+ * This option requires that this trigger component receives the trigger records
+ * data blocks. <br>
+ * \li -triggertracks <br>
+ * Indicates that the component should trigger if any Manso tracks are found.
+ * This option requires that this trigger component receives the Manso track
+ * or singles decision data blocks. <br>
+ * \li -triggerdimuons <br>
+ * Indicates that the component should trigger if any dimuon pairs are found.
+ * This option requires that this trigger component receives the pairs decision
+ * data blocks. <br>
+ * \li -triggerany <br>
+ * This option indicates that the trigger component should trigger if anything was
+ * reconstructed in the muon spectrometer by the dHLT at all. <br>
+ *
+ * \note If none of the "triggerhits", "-triggertrigrecs", "-triggertracks" or "-triggerdimuons"
+ * options are specified then the default triggering mode is to trigger on tracks
+ * and dimuon pairs. <br>
+ *
+ * <h2>Configuration:</h2>
+ * Currently there is no configuration required.
+ *
+ * <h2>Default CDB entries:</h2>
+ * None.
+ *
+ * <h2>Performance:</h2>
+ * Under a millisecond per event.
+ *
+ * <h2>Memory consumption:</h2>
+ * Memory consumption is minimal. It should be less than 1 MBytes.
+ *
+ * <h2>Output size:</h2>
+ * Requires up to 4 kBytes
+ *
+ * \ingroup alihlt_trigger_components
+ */
+class AliHLTMuonSpectroTriggerComponent : public AliHLTTrigger
+{
+public:
+ AliHLTMuonSpectroTriggerComponent();
+ virtual ~AliHLTMuonSpectroTriggerComponent();
+
+ /**
+ * Inherited from AliHLTTrigger.
+ * @return string containing the global trigger name.
+ */
+ virtual const char* GetTriggerName() const { return "MuonSpectroTrigger"; }
+
+ /**
+ * Inherited from AliHLTTrigger. Returns the following input data types
+ * handled by this component:
+ * AliHLTMUONConstants::TriggerRecordsBlockDataType() = "TRIGRECS:MUON"
+ * AliHLTMUONConstants::RecHitsBlockDataType() = "RECHITS :MUON"
+ * AliHLTMUONConstants::MansoTracksBlockDataType() = "MANTRACK:MUON"
+ * AliHLTMUONConstants::SinglesDecisionBlockDataType() = "DECIDSIN:MUON"
+ * AliHLTMUONConstants::PairsDecisionBlockDataType() = "DECIDPAR:MUON"
+ * @param list <i>[out]</i>: The list of data types to be filled.
+ */
+ virtual void GetInputDataTypes(AliHLTComponentDataTypeList& list) const;
+
+ /**
+ * Inherited from AliHLTTrigger. Returns the following output types generated
+ * by this component:
+ * kAliHLTDataTypeTriggerDecision
+ * kAliHLTDataTypeEventStatistics|kAliHLTDataOriginHLT
+ * Including the type kAliHLTDataTypeReadoutList implicitly.
+ * @param list <i>[out]</i>: The list of data types to be filled.
+ */
+ virtual void GetOutputDataTypes(AliHLTComponentDataTypeList& list) const;
+
+ /**
+ * Inherited from AliHLTTrigger. Returns the estimated data volume required
+ * in bytes: constBase + input_volume * 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);
+
+ /**
+ * Inherited from AliHLTComponent.
+ * \returns a new instance of AliHLTMuonSpectroTriggerComponent.
+ */
+ virtual AliHLTComponent* Spawn();
+
+protected:
+
+ /**
+ * Inherited from AliHLTComponent. Initialises the component.
+ * \param argc The number of arguments in argv.
+ * \param argv Array of component argument strings.
+ * \returns Zero on success and negative number on failure.
+ */
+ virtual Int_t DoInit(int argc, const char** argv);
+
+ /**
+ * Inherited from AliHLTComponent. Cleans up the component.
+ * \returns Zero on success and negative number on failure.
+ */
+ virtual Int_t DoDeinit();
+
+ /**
+ * Inherited from AliHLTComponent. Makes a trigger decision for the muon
+ * spectrometer.
+ * @return Zero is returned on success and a negative error code on failure.
+ */
+ virtual int DoTrigger();
+
+private:
+
+ /// Not implemented. Do not allow copying of this class.
+ AliHLTMuonSpectroTriggerComponent(const AliHLTMuonSpectroTriggerComponent& /*obj*/);
+ /// Not implemented. Do not allow copying of this class.
+ AliHLTMuonSpectroTriggerComponent& operator = (const AliHLTMuonSpectroTriggerComponent& /*obj*/);
+
+ /**
+ * Method for checking the structure of a data block.
+ * \param reader The reader for the data block.
+ * \param type The data block type as given by the pub/sub framework.
+ * \returns true if the data block structure is OK and false otherwise.
+ */
+ template <typename BlockReader>
+ bool IsBlockOk(const BlockReader& reader, const AliHLTComponentDataType& type) const;
+
+ unsigned long fBufferSizeConst; //! Constant size estimate for GetOutputDataSize.
+ double fBufferSizeMultiplier; //! Buffer size multiplier estimate for GetOutputDataSize.
+ bool fMakeStats; //! Indicates if the statistics scalars object should be generated or not.
+ bool fTriggerHits; //! If true then the component will trigger on any hits in the tracking chambers.
+ bool fTriggerTrigRecs; //! If true then the component will trigger on any trigger records.
+ bool fTriggerTracks; //! If true then the component will trigger on any tracks found.
+ bool fTriggerDimuons; //! If true then the component will trigger on any dimuons.
+
+ ClassDef(AliHLTMuonSpectroTriggerComponent, 0); // Trigger component for the muon spectrometer.
+};
+
+#endif // AliHLTMUONSPECTROTRIGGERCOMPONENT_H
#include "AliHLTTriggerPhosMip.h"
#include "AliHLTTriggerTrdClusterMultiplicity.h"
#include "AliHLTTriggerGammaConversion.h"
+#include "AliHLTMuonSpectroTriggerComponent.h"
/** global instance for agent registration */
AliHLTTriggerAgent gAliHLTTriggerAgent;
pHandler->AddComponent(new AliHLTTriggerPhosMip);
pHandler->AddComponent(new AliHLTTriggerTrdClusterMultiplicity);
pHandler->AddComponent(new AliHLTTriggerGammaConversion);
+ pHandler->AddComponent(new AliHLTMuonSpectroTriggerComponent);
return 0;
}
} else {
HLTWarning("No inputs for %s found, skipping component", configurationId.Data());
}
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // The muon spectrometer trigger
+ configurationId = "TRIGGER-Muon-Spectrometer";
+
+ // define the inputsfor the muon spectrometer trigger.
+ if (pHandler->FindConfiguration("dHLT-sim-fromRaw")) {
+ triggerInputs = "dHLT-sim-fromRaw";
+ }
+ else if (pHandler->FindConfiguration("dHLT-sim")) {
+ triggerInputs = "dHLT-sim";
+ }
+ else if (pHandler->FindConfiguration("dHLT-sim-fromMC")) {
+ triggerInputs = "dHLT-sim-fromMC";
+ }
+
+ if (triggerInputs.Length() > 0) {
+ HLTInfo("Configuring inputs for %s: %s", configurationId.Data(), triggerInputs.Data());
+ pHandler->CreateConfiguration(configurationId.Data(), "MuonSpectroTrigger", triggerInputs.Data(), "-makestats");
+ if (triggerOutputs.Length() > 0) triggerOutputs += " ";
+ triggerOutputs += configurationId;
+ } else {
+ HLTWarning("No inputs for %s found, skipping component.", configurationId.Data());
+ }
/////////////////////////////////////////////////////////////////////////////////////
//
{
// see header file for class documentation
- return "libAliHLTUtil.so libAliHLTRCU.so libAliHLTTPC.so libAliHLTITS.so libAliHLTGlobal.so";
+ return "libAliHLTUtil.so libAliHLTRCU.so libAliHLTTPC.so libAliHLTITS.so libAliHLTGlobal.so libAliHLTMUON.so";
}
int AliHLTTriggerAgent::GetHandlerDescription(AliHLTComponentDataType dt,
#pragma link C++ class AliHLTTriggerDetectorGeomRectangle+;
#pragma link C++ class AliHLTTriggerDecisionParameters+;
#pragma link C++ class AliHLTTriggerGammaConversion+;
+#pragma link C++ class AliHLTMuonSpectroScalars+;
+#pragma link C++ class AliHLTMuonSpectroScalars::AliScalar+;
+#pragma link C++ class AliHLTMuonSpectroTriggerComponent+;
#endif
Int_t lastRun = AliCDBRunRange::Infinity()
)
{
+ gSystem->Load("libAliHLTUtil.so");
+ gSystem->Load("libAliHLTTRD.so");
+ gSystem->Load("libAliHLTMUON.so");
gSystem->Load("libAliHLTTrigger.so");
// Setup the CDB default storage and run number.
// NOTE: always make sure that the global HLT output and the HLT DDLs are included
// in the readout, i.e. add domainHLTOUT|domainHLTDDL to the trigger domain
config.AddItem("BarrelMultiplicityTrigger", "BarrelMultiplicityTrigger|domainHLTOUT|domainALLDDL", "charged barrel track multiplicity triggered");
+ config.AddItem("MuonSpectroTrigger", "MuonSpectroTrigger|domainHLTOUT|domainALLDDL", "Muon spectrometer triggered");
///////////////////////////////////////////////////////////////////////////////////////////
// default domain in case there is no global trigger
AM_CPPFLAGS = -I$(top_srcdir)/BASE \
-I$(srcdir)/.. \
+ -I$(top_srcdir)/MUON \
+ -I$(ALICE_ROOT)/MUON \
@ALIROOT_CPPFLAGS@ \
-I@ROOTINCDIR@
EXTRA_DIST =
-check_PROGRAMS = testTriggerDomain testGlobalTriggerComponent
+check_PROGRAMS = testTriggerDomain testGlobalTriggerComponent testMuonSpectroTrigger
testTriggerDomain_SOURCES = testTriggerDomain.C
testGlobalTriggerComponent_SOURCES = testGlobalTriggerComponent.C
+testMuonSpectroTrigger_SOURCES = testMuonSpectroTrigger.C
# linker flags
LDADD_COMMON = $(top_builddir)/BASE/libHLTbase.la \
+ $(top_builddir)/MUON/libAliHLTMUON.la \
$(top_builddir)/trigger/libAliHLTTrigger.la
LDFLAGS_COMMON = -L@ROOTLIBDIR@ \
@ROOTLIBS@ \
testGlobalTriggerComponent_LDFLAGS = $(LDFLAGS_COMMON)
+testMuonSpectroTrigger_LDADD = $(LDADD_COMMON)
+
+testMuonSpectroTrigger_LDFLAGS = $(LDFLAGS_COMMON)
+
TESTS = $(check_PROGRAMS)
--- /dev/null
+/**************************************************************************
+ * 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 testMuonSpectroTrigger.C
+ * @author Artur Szostak <artursz@iafrica.com>
+ * @date 11 Nov 2008
+ *
+ * This macro is used to test the AliHLTMuonSpectroTriggerComponent class.
+ * A basic test is run with the AliHLTSystem framework to check that the dHLT
+ * decision is interpreted correctly and the summary statistics generated properly.
+ */
+
+#if defined(__CINT__) && (! defined(__MAKECINT__))
+#error This macro must be compiled. Try running as testMuonSpectroTrigger.C++, but remember to load the libAliHLTTrigger.so and libAliHLTMUON.so libraries first.
+#endif
+
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include "TSystem.h"
+#include "TClassTable.h"
+#include "TFile.h"
+#include "AliLog.h"
+#include "AliHLTReadoutList.h"
+#include "AliHLTTriggerDomain.h"
+#include "AliHLTTriggerDecision.h"
+#include "AliHLTMuonSpectroScalars.h"
+#include "AliHLTMUONDataBlockWriter.h"
+#include "AliHLTMUONUtils.h"
+#include "AliHLTSystem.h"
+#include "AliHLTConfiguration.h"
+#include "Riostream.h"
+#include <stdio.h>
+#endif
+
+/**
+ * Writes the indicated buffer to the given file name.
+ * \returns true if the file was written correctly and false otherwise.
+ */
+bool WriteFile(const char* filename, void* buffer, unsigned int size)
+{
+ FILE* file = fopen(filename, "w");
+ if (file == NULL)
+ {
+ cerr << "ERROR: Could not create file: " << filename << endl;
+ return false;
+ }
+ fwrite(buffer, size, 1, file);
+ fclose(file);
+ return true;
+}
+
+/**
+ * Generates some sample input data and writes it into 6 files named
+ * testSinglesDecisionInputFile1.dat ... testSinglesDecisionInputFile3.dat and
+ * testPairsDecisionInputFile1.dat ... testPairsDecisionInputFile3.dat
+ */
+void GenerateInputData()
+{
+ if (gClassTable->GetID("AliHLTMuonSpectroTriggerComponent") < 0)
+ {
+ gSystem->Load("libAliHLTUtil.so");
+ gSystem->Load("libAliHLTTRD.so");
+ gSystem->Load("libAliHLTTrigger.so");
+ }
+
+ // Allocate two 1 MByte buffers, this will be more than enough space.
+ unsigned int bufferSize = 1024*1024;
+ void* buffer1 = new char[bufferSize];
+ void* buffer2 = new char[bufferSize];
+
+ AliHLTMUONSinglesDecisionBlockWriter singlesBlock(buffer1, bufferSize);
+ singlesBlock.InitCommonHeader();
+ AliHLTMUONSinglesDecisionBlockStruct& singlesHeader = singlesBlock.BlockHeader();
+ singlesHeader.fNlowPt = 2;
+ singlesHeader.fNhighPt = 1;
+ singlesBlock.SetNumberOfEntries(3);
+ AliHLTMUONTrackDecisionStruct& track1 = singlesBlock[0];
+ track1.fTrackId = 1;
+ track1.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits(false, false);
+ track1.fPt = 0.9;
+ AliHLTMUONTrackDecisionStruct& track2 = singlesBlock[1];
+ track2.fTrackId = 2;
+ track2.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits(false, true);
+ track2.fPt = 1.8;
+ AliHLTMUONTrackDecisionStruct& track3 = singlesBlock[2];
+ track3.fTrackId = 3;
+ track3.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits(true, true);
+ track3.fPt = 3.1;
+
+ AliHLTMUONPairsDecisionBlockWriter pairsBlock(buffer2, bufferSize);
+ pairsBlock.InitCommonHeader();
+ AliHLTMUONPairsDecisionBlockStruct& pairsHeader = pairsBlock.BlockHeader();
+ pairsHeader.fNunlikeAnyPt = 1;
+ pairsHeader.fNunlikeLowPt = 1;
+ pairsHeader.fNunlikeHighPt = 1;
+ pairsHeader.fNlikeAnyPt = 2;
+ pairsHeader.fNlikeLowPt = 2;
+ pairsHeader.fNlikeHighPt = 1;
+ pairsHeader.fNmassAny = 1;
+ pairsHeader.fNmassLow = 1;
+ pairsHeader.fNmassHigh = 0;
+ pairsBlock.SetNumberOfEntries(3);
+ AliHLTMUONPairDecisionStruct& pair1 = pairsBlock[0];
+ pair1.fTrackAId = 1;
+ pair1.fTrackBId = 2;
+ pair1.fTriggerBits = AliHLTMUONUtils::PackPairDecisionBits(false, false, false, 0, 1);
+ pair1.fInvMass = 0.1;
+ AliHLTMUONPairDecisionStruct& pair2 = pairsBlock[1];
+ pair2.fTrackAId = 1;
+ pair2.fTrackBId = 3;
+ pair2.fTriggerBits = AliHLTMUONUtils::PackPairDecisionBits(false, true, true, 1, 1);
+ pair2.fInvMass = 3.1;
+ AliHLTMUONPairDecisionStruct& pair3 = pairsBlock[2];
+ pair3.fTrackAId = 2;
+ pair3.fTrackBId = 3;
+ pair3.fTriggerBits = AliHLTMUONUtils::PackPairDecisionBits(true, true, false, 1, 2);
+ pair3.fInvMass = 10.1;
+
+ if (! WriteFile("testSinglesDecisionInputFile1.dat", buffer1, singlesBlock.BytesUsed())) return;
+ if (! WriteFile("testPairsDecisionInputFile1.dat", buffer2, pairsBlock.BytesUsed())) return;
+
+ singlesHeader.fNlowPt = 2;
+ singlesHeader.fNhighPt = 1;
+ singlesBlock.SetNumberOfEntries(2);
+ track1.fTrackId = 4;
+ track1.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits(false, true);
+ track1.fPt = 1.2;
+ track2.fTrackId = 5;
+ track2.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits(true, true);
+ track2.fPt = 2.3;
+
+ pairsHeader.fNunlikeAnyPt = 1;
+ pairsHeader.fNunlikeLowPt = 1;
+ pairsHeader.fNunlikeHighPt = 1;
+ pairsHeader.fNlikeAnyPt = 0;
+ pairsHeader.fNlikeLowPt = 0;
+ pairsHeader.fNlikeHighPt = 0;
+ pairsHeader.fNmassAny = 1;
+ pairsHeader.fNmassLow = 1;
+ pairsHeader.fNmassHigh = 1;
+ pairsBlock.SetNumberOfEntries(1);
+ pair1.fTrackAId = 4;
+ pair1.fTrackBId = 5;
+ pair1.fTriggerBits = AliHLTMUONUtils::PackPairDecisionBits(true, true, true, 1, 2);
+ pair1.fInvMass = 9.7;
+
+ if (! WriteFile("testSinglesDecisionInputFile2.dat", buffer1, singlesBlock.BytesUsed())) return;
+ if (! WriteFile("testPairsDecisionInputFile2.dat", buffer2, pairsBlock.BytesUsed())) return;
+
+ singlesHeader.fNlowPt = 0;
+ singlesHeader.fNhighPt = 0;
+ singlesBlock.SetNumberOfEntries(1);
+ track1.fTrackId = 6;
+ track1.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits(false, false);
+ track1.fPt = 0.6;
+
+ pairsHeader.fNunlikeAnyPt = 0;
+ pairsHeader.fNunlikeLowPt = 0;
+ pairsHeader.fNunlikeHighPt = 0;
+ pairsHeader.fNlikeAnyPt = 0;
+ pairsHeader.fNlikeLowPt = 0;
+ pairsHeader.fNlikeHighPt = 0;
+ pairsHeader.fNmassAny = 0;
+ pairsHeader.fNmassLow = 0;
+ pairsHeader.fNmassHigh = 0;
+ pairsBlock.SetNumberOfEntries(0);
+
+ if (! WriteFile("testSinglesDecisionInputFile3.dat", buffer1, singlesBlock.BytesUsed())) return;
+ if (! WriteFile("testPairsDecisionInputFile3.dat", buffer2, pairsBlock.BytesUsed())) return;
+}
+
+/**
+ * Runs a small test chain for the muon spectrometer trigger component.
+ * \param debug If true then full logging is turned on.
+ * \param numOfEvents The number of events to run the chain for.
+ */
+void RunTrigger(bool debug = false, int numOfEvents = 3)
+{
+ AliHLTSystem sys;
+ 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 DECIDSIN MUON ";
+ for (int i = 1; i <= 3; i++)
+ {
+ if (i > 1) cmdline += " -nextevent";
+ cmdline += Form(" -datafile testSinglesDecisionInputFile%d.dat", i);
+ }
+ AliHLTConfiguration pub1("pub1", "FilePublisher", NULL, cmdline.Data());
+
+ cmdline = "-datatype DECIDPAR MUON ";
+ for (int i = 1; i <= 3; i++)
+ {
+ if (i > 1) cmdline += " -nextevent";
+ cmdline += Form(" -datafile testPairsDecisionInputFile%d.dat", i);
+ }
+ AliHLTConfiguration pub2("pub2", "FilePublisher", NULL, cmdline.Data());
+
+ AliHLTConfiguration proc("proc", "MuonSpectroTrigger", "pub1 pub2", "-makestats -triggerdimuons");
+ AliHLTConfiguration sink("sink", "ROOTFileWriter", "proc", "-datafile testMuonTriggerOutputFile.root -concatenate-events");
+
+ sys.BuildTaskList("sink");
+ sys.Run(numOfEvents);
+}
+
+
+/**
+ * Checks that a particular decision and summary object are as expected and prints
+ * error messages if there are any problems with the results.
+ * \param eventNum The number of the event being checked.
+ * \param decision The trigger decision being checked.
+ * \param scalars The scalars object being checked.
+ * \param expectedResult The expected global trigger result.
+ * \param expectedDomain The expected resulting trigger domain.
+ * \param expectedDescription The expected resulting trigger description.
+ * \param expectedScalars The expected resulting scalars.
+ * \returns true if the decision and scalars are as expected.
+ */
+bool Check(
+ int eventNum,
+ AliHLTTriggerDecision* decision,
+ AliHLTMuonSpectroScalars* scalars,
+ bool expectedResult,
+ AliHLTTriggerDomain expectedDomain,
+ TString expectedDescription,
+ AliHLTMuonSpectroScalars& expectedScalars
+ )
+{
+ if (decision == NULL)
+ {
+ cerr << "ERROR: No decision found where expected for event "
+ << eventNum << "." << endl;
+ return false;
+ }
+ if (decision->Result() != expectedResult)
+ {
+ cerr << "ERROR: The result does not match the expected value for event "
+ << eventNum << ". Got " << decision->Result() << " but expected "
+ << expectedResult << "." << endl;
+ return false;
+ }
+ if (decision->TriggerDomain() != expectedDomain)
+ {
+ cerr << "ERROR: The domain does not match the expected value for event "
+ << eventNum << ". Got:" << endl;
+ decision->TriggerDomain().Print();
+ cerr << "but expected:" << endl;
+ expectedDomain.Print();
+ return false;
+ }
+ if (decision->Description() != expectedDescription)
+ {
+ cerr << "ERROR: The description does not match the expected value for event "
+ << eventNum << ". Got '" << decision->Description() << "' but expected '"
+ << expectedDescription << "'." << endl;
+ return false;
+ }
+ if (*scalars != expectedScalars)
+ {
+ cerr << "ERROR: The scalars summary object does not match the expected one for event "
+ << eventNum << ". Expected the following scalar values:" << endl;
+ expectedScalars.Print();
+ return false;
+ }
+ return true;
+}
+
+
+/// Routine for checking the results of the chain run in RunTrigger.
+bool CheckResults()
+{
+ AliHLTTriggerDecision* decision = NULL;
+ AliHLTMuonSpectroScalars* scalars = NULL;
+ bool result = false;
+
+ AliHLTTriggerDomain domainMUON("*******:MUON");
+ //domainMUON.Add(AliHLTReadoutList("MUONTRK"));
+
+ AliHLTMuonSpectroScalars emptyScalars;
+
+ AliHLTMuonSpectroScalars scalarsEvent1;
+ scalarsEvent1.Add("NTracks", "", 3);
+ scalarsEvent1.Add("NLowPt", "", 2);
+ scalarsEvent1.Add("NHighPt", "", 1);
+ scalarsEvent1.Add("MinPt", "", 0.9f);
+ scalarsEvent1.Add("MaxPt", "", 3.1f);
+ scalarsEvent1.Add("NLikeAny", "", 2);
+ scalarsEvent1.Add("NLikeLow", "", 2);
+ scalarsEvent1.Add("NLikeHigh", "", 1);
+ scalarsEvent1.Add("NUnlikeAny", "", 1);
+ scalarsEvent1.Add("NUnlikeLow", "", 1);
+ scalarsEvent1.Add("NUnlikeHigh", "", 1);
+ scalarsEvent1.Add("NLowMass", "", 1);
+ scalarsEvent1.Add("NHighMass", "", 0);
+ scalarsEvent1.Add("MinMass", "", 0.1f);
+ scalarsEvent1.Add("MaxMass", "", 10.1f);
+
+ AliHLTMuonSpectroScalars scalarsEvent2;
+ scalarsEvent2.Add("NTracks", "", 2);
+ scalarsEvent2.Add("NLowPt", "", 2);
+ scalarsEvent2.Add("NHighPt", "", 1);
+ scalarsEvent2.Add("MinPt", "", 1.2f);
+ scalarsEvent2.Add("MaxPt", "", 2.3f);
+ scalarsEvent2.Add("NLikeAny", "", 0);
+ scalarsEvent2.Add("NLikeLow", "", 0);
+ scalarsEvent2.Add("NLikeHigh", "", 0);
+ scalarsEvent2.Add("NUnlikeAny", "", 1);
+ scalarsEvent2.Add("NUnlikeLow", "", 1);
+ scalarsEvent2.Add("NUnlikeHigh", "", 1);
+ scalarsEvent2.Add("NLowMass", "", 1);
+ scalarsEvent2.Add("NHighMass", "", 1);
+ scalarsEvent2.Add("MinMass", "", 9.7f);
+ scalarsEvent2.Add("MaxMass", "", 9.7f);
+
+ AliHLTMuonSpectroScalars scalarsEvent3;
+ scalarsEvent3.Add("NTracks", "", 1);
+ scalarsEvent3.Add("NLowPt", "", 0);
+ scalarsEvent3.Add("NHighPt", "", 0);
+ scalarsEvent3.Add("MinPt", "", 0.6f);
+ scalarsEvent3.Add("MaxPt", "", 0.6f);
+ scalarsEvent3.Add("NLikeAny", "", 0);
+ scalarsEvent3.Add("NLikeLow", "", 0);
+ scalarsEvent3.Add("NLikeHigh", "", 0);
+ scalarsEvent3.Add("NUnlikeAny", "", 0);
+ scalarsEvent3.Add("NUnlikeLow", "", 0);
+ scalarsEvent3.Add("NUnlikeHigh", "", 0);
+ scalarsEvent3.Add("NLowMass", "", 0);
+ scalarsEvent3.Add("NHighMass", "", 0);
+ scalarsEvent3.Add("MinMass", "", -1);
+ scalarsEvent3.Add("MaxMass", "", -1);
+
+ TFile* file = new TFile("testMuonTriggerOutputFile.root", "READ");
+
+ // First event is the Start-Of-Run
+ decision = dynamic_cast<AliHLTTriggerDecision*>(file->Get("MuonSpectroTrigger;1"));
+ scalars = dynamic_cast<AliHLTMuonSpectroScalars*>(file->Get("AliHLTMuonSpectroScalars;1"));
+ result = Check(0, decision, scalars, false, AliHLTTriggerDomain(), "Not triggered", emptyScalars);
+ if (! result) goto cleanup;
+ // Now we have the 3 data events:
+ decision = dynamic_cast<AliHLTTriggerDecision*>(file->Get("MuonSpectroTrigger;2"));
+ scalars = dynamic_cast<AliHLTMuonSpectroScalars*>(file->Get("AliHLTMuonSpectroScalars;2"));
+ result = Check(1, decision, scalars, true, domainMUON, "Dimuon in muon spectrometer", scalarsEvent1);
+ if (! result) goto cleanup;
+ decision = dynamic_cast<AliHLTTriggerDecision*>(file->Get("MuonSpectroTrigger;3"));
+ scalars = dynamic_cast<AliHLTMuonSpectroScalars*>(file->Get("AliHLTMuonSpectroScalars;3"));
+ result = Check(2, decision, scalars, true, domainMUON, "Dimuon in muon spectrometer", scalarsEvent2);
+ if (! result) goto cleanup;
+ decision = dynamic_cast<AliHLTTriggerDecision*>(file->Get("MuonSpectroTrigger;4"));
+ scalars = dynamic_cast<AliHLTMuonSpectroScalars*>(file->Get("AliHLTMuonSpectroScalars;4"));
+ result = Check(3, decision, scalars, false, AliHLTTriggerDomain(), "Not triggered", scalarsEvent3);
+ if (! result) goto cleanup;
+ // and finally the End-Of-Run event.
+ decision = dynamic_cast<AliHLTTriggerDecision*>(file->Get("MuonSpectroTrigger;5"));
+ scalars = dynamic_cast<AliHLTMuonSpectroScalars*>(file->Get("AliHLTMuonSpectroScalars;5"));
+ result = Check(4, decision, scalars, false, AliHLTTriggerDomain(), "Not triggered", emptyScalars);
+ if (! result) goto cleanup;
+
+ delete file;
+ return true;
+
+cleanup:
+ if (decision != NULL)
+ {
+ cout << "========== Dumping received decision result ========== " << endl;
+ decision->Print();
+ cout << "=========== Dumping received scalars result ========== " << endl;
+ scalars->Print();
+ }
+ delete file;
+ return false;
+}
+
+
+/**
+ * Runs the unit test for the AliHLTMuonSpectroTriggerComponent class.
+ * \param debug If specified then the HLT chain is run with full logging enabled.
+ * \returns true if the class passed the test and false otherwise.
+ */
+bool testMuonSpectroTrigger(bool debug = false)
+{
+ GenerateInputData();
+ RunTrigger(debug);
+ if (! CheckResults()) return false;
+
+ // Cleanup all temporary files generated.
+ gSystem->Exec("rm -f testMuonTriggerOutputFile.root test*DecisionInputFile*.root");
+ return true;
+}
+
+
+#ifndef __MAKECINT__
+
+int main(int /*argc*/, const char** /*argv*/)
+{
+ bool resultOk = testMuonSpectroTrigger();
+ if (not resultOk) return 1;
+ return 0;
+}
+
+#endif // __MAKECINT__