Added the dimuon trigger decision component, its default configuration CDB entries...
authoraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 2 May 2008 18:55:50 +0000 (18:55 +0000)
committeraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 2 May 2008 18:55:50 +0000 (18:55 +0000)
The dHLTdumpraw utility has been updated to dump multiple files.

15 files changed:
HLT/ConfigMUON/DecisionComponent/Run0_999999999_v0_s0.root [new file with mode: 0644]
HLT/MUON/AliHLTMUONConstants.cxx
HLT/MUON/AliHLTMUONConstants.h
HLT/MUON/AliHLTMUONPairsDecisionBlockStruct.h
HLT/MUON/AliHLTMUONSinglesDecisionBlockStruct.h
HLT/MUON/HLTMUONLinkDef.h
HLT/MUON/OfflineInterface/AliHLTMUONAgent.cxx
HLT/MUON/OnlineAnalysis/AliHLTMUONCalculations.cxx
HLT/MUON/OnlineAnalysis/AliHLTMUONCalculations.h
HLT/MUON/OnlineAnalysis/AliHLTMUONDecisionComponent.cxx [new file with mode: 0644]
HLT/MUON/OnlineAnalysis/AliHLTMUONDecisionComponent.h [new file with mode: 0644]
HLT/MUON/macros/CreateDefaultCDBEntries.C [new file with mode: 0644]
HLT/MUON/macros/RunChain.C
HLT/MUON/utils/dHLTdumpraw.cxx
HLT/libAliHLTMUON.pkg

diff --git a/HLT/ConfigMUON/DecisionComponent/Run0_999999999_v0_s0.root b/HLT/ConfigMUON/DecisionComponent/Run0_999999999_v0_s0.root
new file mode 100644 (file)
index 0000000..9c21607
Binary files /dev/null and b/HLT/ConfigMUON/DecisionComponent/Run0_999999999_v0_s0.root differ
index 0c33aad..c49e3f5 100644 (file)
@@ -182,3 +182,5 @@ const char* AliHLTMUONConstants::fgkTriggerCalibratorId = "MUONTriggerCalibrator
 const char* AliHLTMUONConstants::fgkTrackerCalibratorId = "MUONTrackerCalibrator";
 const char* AliHLTMUONConstants::fgkEmptyEventFilterComponentId = "MUONEmptyEventFilterComponent";
 
+const char* AliHLTMUONConstants::fgkDecisionComponentCDBPath = "HLT/ConfigMUON/DecisionComponent";
+
index 6f159f5..d0a19a5 100644 (file)
@@ -216,6 +216,11 @@ public:
        {
                return fgkEmptyEventFilterComponentId;
        }
+       
+       static const char* DecisionComponentCDBPath()
+       {
+               return fgkDecisionComponentCDBPath;
+       }
 
 private:
 
@@ -262,6 +267,9 @@ private:
        static const char* fgkTriggerCalibratorId; // Trigger calibration component name.
        static const char* fgkTrackerCalibratorId; // Tracking stations calibration component name.
        static const char* fgkEmptyEventFilterComponentId; // The name of the event filter debugging component.
+       
+       // CDB path entries to configuration information.
+       static const char* fgkDecisionComponentCDBPath; // Path to CDB entry for trigger decision component.
 };
 
 #endif // ALIHLTMUONCONSTANTS_H
index bd5ed64..a14d928 100644 (file)
@@ -86,7 +86,7 @@ struct AliHLTMUONPairsDecisionBlockStruct
        // pt > low pt cut and unlike sign.
        AliHLTUInt32_t fNmassLow;
        
-       // Number of pairs that have invariant mass > low mass cut,
+       // Number of pairs that have invariant mass > high mass cut,
        // pt > high pt cut and unlike sign.
        AliHLTUInt32_t fNmassHigh;
 
index 342ac48..82a93a3 100644 (file)
@@ -35,6 +35,8 @@ struct AliHLTMUONTrackDecisionStruct
        // Reserved bits should be set to zero.
        // hipt == passed high pt cut. lopt == passed low pt cut.
        AliHLTUInt32_t fTriggerBits;
+       
+       AliHLTFloat32_t fPt; // The calculated transverse momentum of the track in (GeV/c).
 };
 
 /**
@@ -65,6 +67,7 @@ inline std::ostream& operator << (
 {
        stream  << "{fTrackId = " << trig.fTrackId << ", fTriggerBits = "
                << std::showbase << std::hex << trig.fTriggerBits << std::dec
+               << ", fPt = " << trig.fPt
                << "}";
        return stream;
 }
@@ -85,7 +88,8 @@ inline bool operator == (
                const AliHLTMUONTrackDecisionStruct& b
        )
 {
-       return a.fTrackId == b.fTrackId and a.fTriggerBits == b.fTriggerBits;
+       return a.fTrackId == b.fTrackId and a.fTriggerBits == b.fTriggerBits
+               and a.fPt == b.fPt;
 }
 
 inline bool operator != (
index 97d75cd..52105f7 100644 (file)
@@ -41,6 +41,7 @@
 #pragma link C++ class AliHLTMUONTriggerReconstructorComponent+;
 #pragma link C++ class AliHLTMUONHitReconstructorComponent+;
 #pragma link C++ class AliHLTMUONMansoTrackerFSMComponent+;
+#pragma link C++ class AliHLTMUONDecisionComponent+;
 #pragma link C++ class AliHLTMUONRecHit+;
 #pragma link C++ class AliHLTMUONRecHit::Channel+;
 #pragma link C++ class AliHLTMUONTriggerRecord+;
index 12f4568..341d388 100644 (file)
@@ -29,6 +29,7 @@
 #include "AliHLTMUONHitReconstructorComponent.h"
 #include "AliHLTMUONTriggerReconstructorComponent.h"
 #include "AliHLTMUONMansoTrackerFSMComponent.h"
+#include "AliHLTMUONDecisionComponent.h"
 #include "AliHLTMUONEmptyEventFilterComponent.h"
 #include "AliRunLoader.h"
 
@@ -118,6 +119,7 @@ int AliHLTMUONAgent::RegisterComponents(AliHLTComponentHandler* pHandler) const
        pHandler->AddComponent(new AliHLTMUONHitReconstructorComponent);
        pHandler->AddComponent(new AliHLTMUONTriggerReconstructorComponent);
        pHandler->AddComponent(new AliHLTMUONMansoTrackerFSMComponent);
+       pHandler->AddComponent(new AliHLTMUONDecisionComponent);
        pHandler->AddComponent(new AliHLTMUONEmptyEventFilterComponent);
        return 0;
 }
index 40c7ef0..36fde54 100644 (file)
@@ -97,3 +97,37 @@ void AliHLTMUONCalculations::QBL(AliHLTFloat32_t value)
        // It is c/1e9, where c is the speed of light.
        fgQBLScaled = value * 2.99792458e8 / 1e9;
 }
+
+
+AliHLTFloat32_t AliHLTMUONCalculations::ComputeMass(
+               AliHLTFloat32_t massA,
+               AliHLTFloat32_t pxA,
+               AliHLTFloat32_t pyA,
+               AliHLTFloat32_t pzA,
+               AliHLTFloat32_t massB,
+               AliHLTFloat32_t pxB,
+               AliHLTFloat32_t pyB,
+               AliHLTFloat32_t pzB
+       )
+{
+       /// Calculates the invariant mass for a pair of particles.
+       /// \param massA Mmass in GeV/c of particle A.
+       /// \param pxA  X component of the momentum in GeV/c for particle A.
+       /// \param pyA  Y component of the momentum in GeV/c for particle A.
+       /// \param pzA  Z component of the momentum in GeV/c for particle A.
+       /// \param massB  Mass in GeV/c of particle B.
+       /// \param pxB  X component of the momentum in GeV/c for particle B.
+       /// \param pyB  Y component of the momentum in GeV/c for particle B.
+       /// \param pzB  Z component of the momentum in GeV/c for particle B.
+       /// \return  The invariant mass in GeV/c^2 or -1 if there was a problem
+       ///          in the calculation due to bad input parameters.
+       
+       AliHLTFloat32_t massA2 = massA*massA;
+       AliHLTFloat32_t massB2 = massB*massB;
+       AliHLTFloat32_t energyA = sqrt(massA2 + pxA*pxA + pyA*pyA + pzA*pzA);
+       AliHLTFloat32_t energyB = sqrt(massB2 + pxB*pxB + pyB*pyB + pzB*pzB);
+       AliHLTFloat32_t mass2 = massA2 + massB2 + 2. * (energyA*energyB - pxA*pxB - pyA*pyB - pzA*pzB);
+       if (mass2 < 0.) return -1.;
+       return sqrt(mass2);
+}
+
index 7cc588d..9e5281a 100644 (file)
@@ -15,8 +15,8 @@
 #include "AliHLTMUONDataTypes.h"
 
 /*
- * Note: this class is not reentrant so thread protection must be explicit in
- * any multi-threaded usage.
+ * Note: this class uses static global variables so thread protection must be
+ * explicit in any multi-threaded usage.
  */
 class AliHLTMUONCalculations
 {
@@ -50,7 +50,19 @@ public:
        static AliHLTFloat32_t Px() { return fgPx; }
        static AliHLTFloat32_t Py() { return fgPy; }
        static AliHLTFloat32_t Pz() { return fgPz; }
-               
+       
+       /// Calculates the invariant mass for a pair of particles.
+       static AliHLTFloat32_t ComputeMass(
+                       AliHLTFloat32_t massA,
+                       AliHLTFloat32_t pxA,
+                       AliHLTFloat32_t pyA,
+                       AliHLTFloat32_t pzA,
+                       AliHLTFloat32_t massB,
+                       AliHLTFloat32_t pxB,
+                       AliHLTFloat32_t pyB,
+                       AliHLTFloat32_t pzB
+               );
+       
 private:
 
        // Prevent destroying or creating of this object.
diff --git a/HLT/MUON/OnlineAnalysis/AliHLTMUONDecisionComponent.cxx b/HLT/MUON/OnlineAnalysis/AliHLTMUONDecisionComponent.cxx
new file mode 100644 (file)
index 0000000..a18e37a
--- /dev/null
@@ -0,0 +1,832 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+/* $Id: $ */
+
+///
+///  @file   AliHLTMUONDecisionComponent.cxx
+///  @author Artur Szostak <artursz@iafrica.com>
+///  @date   30 April 2008
+///  @brief  Implementation of the decision component for dimuon HLT triggering.
+///
+// class documentation is in the header file.
+
+#include "AliHLTMUONDecisionComponent.h"
+#include "AliHLTMUONConstants.h"
+#include "AliHLTMUONUtils.h"
+#include "AliHLTMUONCalculations.h"
+#include "AliHLTMUONDataBlockReader.h"
+#include "AliHLTMUONDataBlockWriter.h"
+#include "AliCDBEntry.h"
+#include "AliCDBManager.h"
+#include "TObjString.h"
+#include "TString.h"
+#include <cstdlib>
+#include <cstring>
+#include <cerrno>
+#include <cmath>
+#include <new>
+
+
+// Helper type for memory allocation.
+typedef const AliHLTMUONMansoTrackStruct* AliHLTMUONMansoTrackStructP;
+
+
+ClassImp(AliHLTMUONDecisionComponent);
+
+
+AliHLTMUONDecisionComponent::AliHLTMUONDecisionComponent() :
+       AliHLTProcessor(),
+       fMaxTracks(1),
+       fTrackCount(0),
+       fTracks(new AliHLTMUONMansoTrackStructP[fMaxTracks]),
+       fLowPtCut(1.),  // 1 GeV/c cut
+       fHighPtCut(2.),  // 2 GeV/c cut
+       fLowMassCut(2.5),  // 2.7 GeV/c^2 cut
+       fHighMassCut(7.),  // 8 GeV/c^2 cut
+       fWarnForUnexpecedBlock(false)
+{
+       ///
+       /// Default constructor.
+       ///
+}
+
+
+AliHLTMUONDecisionComponent::~AliHLTMUONDecisionComponent()
+{
+       ///
+       /// Default destructor deletes the fTracks array.
+       ///
+       
+       assert(fTracks != NULL);
+       delete [] fTracks;
+}
+
+
+const char* AliHLTMUONDecisionComponent::GetComponentID()
+{
+       ///
+       /// Inherited from AliHLTComponent. Returns the component ID.
+       ///
+       
+       return AliHLTMUONConstants::DecisionComponentId();
+}
+
+
+void AliHLTMUONDecisionComponent::GetInputDataTypes(
+               vector<AliHLTComponentDataType>& list
+       )
+{
+       ///
+       /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
+       ///
+       
+       assert( list.empty() );
+       list.push_back( AliHLTMUONConstants::MansoTracksBlockDataType() );
+}
+
+
+AliHLTComponentDataType AliHLTMUONDecisionComponent::GetOutputDataType()
+{
+       /// Inherited from AliHLTComponent. Returns kAliHLTMultipleDataType
+       /// refer to GetOutputDataTypes for all returned data types.
+       
+       return kAliHLTMultipleDataType;
+}
+
+
+int AliHLTMUONDecisionComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
+{
+       /// Inherited from AliHLTComponent. Returns the output data types.
+       
+       assert( list.empty() );
+       list.push_back( AliHLTMUONConstants::SinglesDecisionBlockDataType() );
+       list.push_back( AliHLTMUONConstants::PairsDecisionBlockDataType() );
+       return 1;
+}
+
+
+void AliHLTMUONDecisionComponent::GetOutputDataSize(
+               unsigned long& constBase, double& inputMultiplier
+       )
+{
+       ///
+       /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
+       ///
+       
+       constBase = sizeof(AliHLTMUONSinglesDecisionBlockStruct);
+       constBase += sizeof(AliHLTMUONPairsDecisionBlockStruct);
+       inputMultiplier = 1;
+}
+
+
+AliHLTComponent* AliHLTMUONDecisionComponent::Spawn()
+{
+       ///
+       /// Inherited from AliHLTComponent. Creates a new object instance.
+       ///
+       
+       return new AliHLTMUONDecisionComponent;
+}
+
+
+int AliHLTMUONDecisionComponent::DoInit(int argc, const char** argv)
+{
+       ///
+       /// Inherited from AliHLTComponent.
+       /// Parses the command line parameters and initialises the component.
+       ///
+       
+       HLTInfo("Initialising dHLT trigger decision component.");
+       
+       bool lowPtCutSet = false;
+       bool highPtCutSet = false;
+       bool lowMassCutSet = false;
+       bool highMassCutSet = false;
+       fWarnForUnexpecedBlock = false;
+       
+       for (int i = 0; i < argc; i++)
+       {
+               if (strcmp( argv[i], "-lowptcut" ) == 0)
+               {
+                       if (argc <= i+1)
+                       {
+                               HLTError("The value for the low pT cut was not specified.");
+                               return -EINVAL;
+                       }
+                       
+                       char* cpErr = NULL;
+                       double num = strtod(argv[i+1], &cpErr);
+                       if (cpErr == NULL or *cpErr != '\0')
+                       {
+                               HLTError("Cannot convert '%s' to a floating point number.", argv[i+1]);
+                               return -EINVAL;
+                       }
+                       fLowPtCut = (AliHLTFloat32_t)num;
+                       lowPtCutSet = true;
+                       
+                       i++;
+                       continue;
+               }
+               
+               if (strcmp( argv[i], "-highptcut" ) == 0)
+               {
+                       if (argc <= i+1)
+                       {
+                               HLTError("The value for the high pT cut was not specified.");
+                               return -EINVAL;
+                       }
+                       
+                       char* cpErr = NULL;
+                       double num = strtod(argv[i+1], &cpErr);
+                       if (cpErr == NULL or *cpErr != '\0')
+                       {
+                               HLTError("Cannot convert '%s' to a floating point number.", argv[i+1]);
+                               return -EINVAL;
+                       }
+                       fHighPtCut = (AliHLTFloat32_t)num;
+                       highPtCutSet = true;
+                       
+                       i++;
+                       continue;
+               }
+               
+               if (strcmp( argv[i], "-lowmasscut" ) == 0)
+               {
+                       if (argc <= i+1)
+                       {
+                               HLTError("The value for the low invariant mass cut was not specified.");
+                               return -EINVAL;
+                       }
+                       
+                       char* cpErr = NULL;
+                       double num = strtod(argv[i+1], &cpErr);
+                       if (cpErr == NULL or *cpErr != '\0')
+                       {
+                               HLTError("Cannot convert '%s' to a floating point number.", argv[i+1]);
+                               return -EINVAL;
+                       }
+                       fLowMassCut = (AliHLTFloat32_t)num;
+                       lowMassCutSet = true;
+                       
+                       i++;
+                       continue;
+               }
+               
+               if (strcmp( argv[i], "-highmasscut" ) == 0)
+               {
+                       if (argc <= i+1)
+                       {
+                               HLTError("The value for the high invariant mass cut was not specified.");
+                               return -EINVAL;
+                       }
+                       
+                       char* cpErr = NULL;
+                       double num = strtod(argv[i+1], &cpErr);
+                       if (cpErr == NULL or *cpErr != '\0')
+                       {
+                               HLTError("Cannot convert '%s' to a floating point number.", argv[i+1]);
+                               return -EINVAL;
+                       }
+                       fHighMassCut = (AliHLTFloat32_t)num;
+                       highMassCutSet = true;
+                       
+                       i++;
+                       continue;
+               }
+               
+               if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
+               {
+                       fWarnForUnexpecedBlock = true;
+                       continue;
+               }
+
+               HLTError("Unknown option '%s'.", argv[i]);
+               return -EINVAL;
+       }
+       
+       // Read cut parameters from CDB if they were not specified on the command line.
+       if (not lowPtCutSet or not highPtCutSet or not lowMassCutSet or not highMassCutSet)
+       {
+               int result = ReadConfigFromCDB(
+                               NULL,
+                               not lowPtCutSet, not highPtCutSet,
+                               not lowMassCutSet, not highMassCutSet
+                       );
+               if (result != 0) return result;
+       }
+       
+       HLTDebug("Using the following cut parameters:");
+       HLTDebug("              Low pT cut = %f GeV/c", fLowPtCut);
+       HLTDebug("             High pT cut = %f GeV/c", fHighPtCut);
+       HLTDebug("  Low invariant mass cut = %f GeV/c^2", fLowMassCut);
+       HLTDebug(" High invariant mass cut = %f GeV/c^2", fHighMassCut);
+       
+       return 0;
+}
+
+
+int AliHLTMUONDecisionComponent::DoDeinit()
+{
+       ///
+       /// Inherited from AliHLTComponent. Performs a cleanup of the component.
+       ///
+       
+       HLTInfo("Deinitialising dHLT trigger decision component.");
+       return 0;
+}
+
+
+int AliHLTMUONDecisionComponent::Reconfigure(const char* cdbEntry, const char* componentId)
+{
+       /// Inherited from AliHLTComponent. Reconfigures the component from CDB.
+       
+       if (strcmp(componentId, GetComponentID()) == 0)
+       {
+               HLTInfo("Reading new entries for cut parameters from CDB.");
+               int result = ReadConfigFromCDB(cdbEntry);
+               HLTDebug("Using the following new cut parameters:");
+               HLTDebug("              Low pT cut = %f GeV/c", fLowPtCut);
+               HLTDebug("             High pT cut = %f GeV/c", fHighPtCut);
+               HLTDebug("  Low invariant mass cut = %f GeV/c^2", fLowMassCut);
+               HLTDebug(" High invariant mass cut = %f GeV/c^2", fHighMassCut);
+               return result;
+       }
+       else
+               return 0;
+}
+
+
+int AliHLTMUONDecisionComponent::DoEvent(
+               const AliHLTComponentEventData& evtData,
+               const AliHLTComponentBlockData* blocks,
+               AliHLTComponentTriggerData& /*trigData*/,
+               AliHLTUInt8_t* outputPtr,
+               AliHLTUInt32_t& size,
+               std::vector<AliHLTComponentBlockData>& outputBlocks
+       )
+{
+       ///
+       /// Inherited from AliHLTProcessor. Processes the new event data.
+       ///
+       
+       AliHLTUInt32_t specification = 0;  // Contains the output data block spec bits.
+       
+       // Loop over all input blocks in the event with track data and add pointers
+       // to the tracks into the tracks array. These will be used later by the
+       // trigger algorithm to get to the individual tracks.
+       fTrackCount = 0; // reset number of tracks in array.
+       for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
+       {
+               if (blocks[n].fDataType == AliHLTMUONConstants::MansoTracksBlockDataType())
+               {
+                       // Build up the specification which indicates what DDLs
+                       // contributed to the output data.
+                       specification |= blocks[n].fSpecification;
+                       
+                       AliHLTMUONMansoTracksBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
+                       if (not inblock.BufferSizeOk())
+                       {
+                               size_t headerSize = sizeof(AliHLTMUONMansoTracksBlockReader::HeaderType);
+                               if (blocks[n].fSize < headerSize)
+                               {
+                                       HLTError("Received a manso tracks data block with a size of %d bytes,"
+                                               " which is smaller than the minimum valid header size of %d bytes."
+                                               " The block must be corrupt.",
+                                               blocks[n].fSize, headerSize
+                                       );
+                                       continue;
+                               }
+                               
+                               size_t expectedWidth = sizeof(AliHLTMUONMansoTracksBlockReader::ElementType);
+                               if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
+                               {
+                                       HLTError("Received a manso tracks data block with a record"
+                                               " width of %d bytes, but the expected value is %d bytes."
+                                               " The block might be corrupt.",
+                                               inblock.CommonBlockHeader().fRecordWidth, expectedWidth
+                                       );
+                                       continue;
+                               }
+                               
+                               HLTError("Received a manso tracks data block with a size of %d bytes,"
+                                       " but the block header claims the block should be %d bytes."
+                                       " The block might be corrupt.",
+                                       blocks[n].fSize, inblock.BytesUsed()
+                               );
+                               continue;
+                       }
+                       
+                       for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
+                       {
+                               int result = AddTrack(&inblock[i]);
+                               if (result != 0)
+                               {
+                                       size = 0; // Important to tell framework that nothing was generated.
+                                       return result;
+                               }
+                       }
+               }
+               else if (blocks[n].fDataType != AliHLTMUONConstants::MansoTracksBlockDataType())
+               {
+                       // Log a message indicating that we got a data block that we
+                       // do not know how to handle.
+                       char id[kAliHLTComponentDataTypefIDsize+1];
+                       for (int i = 0; i < kAliHLTComponentDataTypefIDsize; i++)
+                               id[i] = blocks[n].fDataType.fID[i];
+                       id[kAliHLTComponentDataTypefIDsize] = '\0';
+                       char origin[kAliHLTComponentDataTypefOriginSize+1];
+                       for (int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++)
+                               origin[i] = blocks[n].fDataType.fOrigin[i];
+                       origin[kAliHLTComponentDataTypefOriginSize] = '\0';
+                       
+                       if (fWarnForUnexpecedBlock)
+                               HLTWarning("Received a data block of a type we cannot handle: %s origin: %s",
+                                       static_cast<char*>(id), static_cast<char*>(origin)
+                               );
+                       else
+                               HLTDebug("Received a data block of a type we cannot handle: %s origin: %s",
+                                       static_cast<char*>(id), static_cast<char*>(origin)
+                               );
+               }
+       }
+       
+       // Now we can create our two new output data blocks for the single tracks
+       // and track pairs.
+       AliHLTMUONSinglesDecisionBlockWriter singlesBlock(outputPtr, size);
+       
+       if (not singlesBlock.InitCommonHeader())
+       {
+               Logging(kHLTLogError,
+                       "AliHLTMUONDecisionComponent::DoEvent",
+                       "Buffer overflow",
+                       "The buffer is only %d bytes in size. We need a minimum of"
+                       " %d bytes for the singles output data block.",
+                       size, sizeof(AliHLTMUONSinglesDecisionBlockWriter::HeaderType)
+               );
+               size = 0; // Important to tell framework that nothing was generated.
+               return -ENOBUFS;
+       }
+       
+       if (not singlesBlock.SetNumberOfEntries(fTrackCount))
+       {
+               AliHLTUInt32_t bytesneeded = sizeof(AliHLTMUONSinglesDecisionBlockWriter::HeaderType)
+                       + fTrackCount * sizeof(AliHLTMUONSinglesDecisionBlockWriter::ElementType);
+               HLTError("The buffer is only %d bytes in size. We need a minimum of"
+                       " %d bytes for the singles output data block.",
+                       size, bytesneeded
+               );
+               size = 0; // Important to tell framework that nothing was generated.
+               return -ENOBUFS;
+       }
+       
+       AliHLTMUONPairsDecisionBlockWriter pairsBlock(
+                       outputPtr + singlesBlock.BytesUsed(),
+                       size - singlesBlock.BytesUsed()
+               );
+       
+       if (not pairsBlock.InitCommonHeader())
+       {
+               Logging(kHLTLogError,
+                       "AliHLTMUONDecisionComponent::DoEvent",
+                       "Buffer overflow",
+                       "The buffer is only %d bytes in size. We need a minimum of"
+                       " %d bytes for the pairs output data block.",
+                       size,
+                       sizeof(AliHLTMUONPairsDecisionBlockWriter::HeaderType) + singlesBlock.BytesUsed()
+               );
+               size = 0; // Important to tell framework that nothing was generated.
+               return -ENOBUFS;
+       }
+       
+       AliHLTUInt32_t numOfPairs = fTrackCount * (fTrackCount-1) / 2;
+       if (not pairsBlock.SetNumberOfEntries(numOfPairs))
+       {
+               AliHLTUInt32_t bytesneeded = sizeof(AliHLTMUONPairsDecisionBlockWriter::HeaderType)
+                       + fTrackCount * sizeof(AliHLTMUONPairsDecisionBlockWriter::ElementType)
+                       + singlesBlock.BytesUsed();
+               HLTError("The buffer is only %d bytes in size. We need a minimum of"
+                       " %d bytes for the pairs output data block.",
+                       size, bytesneeded
+               );
+               size = 0; // Important to tell framework that nothing was generated.
+               return -ENOBUFS;
+       }
+       
+       ApplyTriggerAlgorithm(
+                       singlesBlock.BlockHeader(),
+                       singlesBlock.GetArray(),
+                       pairsBlock.BlockHeader(),
+                       pairsBlock.GetArray()
+               );
+       
+       AliHLTComponentBlockData sbd;
+       FillBlockData(sbd);
+       sbd.fPtr = outputPtr;
+       sbd.fOffset = 0;
+       sbd.fSize = singlesBlock.BytesUsed();
+       sbd.fDataType = AliHLTMUONConstants::SinglesDecisionBlockDataType();
+       sbd.fSpecification = specification;
+       outputBlocks.push_back(sbd);
+       size = singlesBlock.BytesUsed();
+       
+       AliHLTComponentBlockData pbd;
+       FillBlockData(pbd);
+       pbd.fPtr = outputPtr;
+       pbd.fOffset = singlesBlock.BytesUsed();
+       pbd.fSize = pairsBlock.BytesUsed();
+       pbd.fDataType = AliHLTMUONConstants::PairsDecisionBlockDataType();
+       pbd.fSpecification = specification;
+       outputBlocks.push_back(pbd);
+       size += pairsBlock.BytesUsed();
+       
+       return 0;
+}
+
+
+int AliHLTMUONDecisionComponent::ReadConfigFromCDB(
+               const char* path,
+               bool setLowPtCut, bool setHighPtCut,
+               bool setLowMassCut, bool setHighMassCut
+       )
+{
+       /// Reads the cut parameters from the CDB.
+       
+       assert(AliCDBManager::Instance() != NULL);
+       
+       const char* pathToEntry = AliHLTMUONConstants::DecisionComponentCDBPath();
+       if (path != NULL)
+               pathToEntry = path;
+       
+       AliCDBEntry* entry = AliCDBManager::Instance()->Get(pathToEntry);
+       if (entry == NULL)
+       {
+               HLTError("Could not get the CDB entry for \"%s\".", pathToEntry);
+               return -EIO;
+       }
+       
+       TObject* obj = entry->GetObject();
+       if (obj == NULL)
+       {
+               HLTError("Configuration object for \"%s\" is missing.", pathToEntry);
+               return -ENOENT;
+       }
+       
+       if (obj->IsA() != TMap::Class())
+       {
+               HLTError("Wrong type for configuration object in \"%s\". Found a %s but we need a TMap.",
+                       pathToEntry, obj->ClassName()
+               );
+               return -EPROTO;
+       }
+       TMap* map = dynamic_cast<TMap*>(obj);
+       
+       if (setLowPtCut)
+       {
+               TPair* pair = static_cast<TPair*>(map->FindObject("lowptcut"));
+               if (pair == NULL)
+               {
+                       HLTError("Configuration object for \"%s\" does not contain the low pT cut value.",
+                               pathToEntry
+                       );
+                       return -ENOENT;
+               }
+               TObject* valueObj = pair->Value();
+               if (valueObj->IsA() != TObjString::Class())
+               {
+                       HLTError("The low pT cut parameter found in configuration object \"%s\""
+                               " is not a TObjString. Found an object of type %s instead.",
+                               pathToEntry, valueObj->ClassName()
+                       );
+                       return -EPROTO;
+               }
+               TString value = dynamic_cast<TObjString*>(valueObj)->GetString();
+               if (not value.IsFloat())
+               {
+                       HLTError("The low pT cut parameter found in configuration object \"%s\""
+                               "is not a floating point string; found \"%s\".",
+                               pathToEntry, value.Data()
+                       );
+                       return -EPROTO;
+               }
+               fLowPtCut = (AliHLTFloat32_t) value.Atof();
+       }
+       
+       if (setHighPtCut)
+       {
+               TPair* pair = static_cast<TPair*>(map->FindObject("highptcut"));
+               if (pair == NULL)
+               {
+                       HLTError("Configuration object for \"%s\" does not contain the high pT cut value.",
+                               pathToEntry
+                       );
+                       return -ENOENT;
+               }
+               TObject* valueObj = pair->Value();
+               if (valueObj->IsA() != TObjString::Class())
+               {
+                       HLTError("The high pT cut parameter found in configuration object \"%s\""
+                               " is not a TObjString. Found an object of type %s instead.",
+                               pathToEntry, valueObj->ClassName()
+                       );
+                       return -EPROTO;
+               }
+               TString value = dynamic_cast<TObjString*>(valueObj)->GetString();
+               if (not value.IsFloat())
+               {
+                       HLTError("The high pT cut parameter found in configuration object \"%s\""
+                               "is not a floating point string; found \"%s\".",
+                               pathToEntry, value.Data()
+                       );
+                       return -EPROTO;
+               }
+               fHighPtCut = (AliHLTFloat32_t) value.Atof();
+       }
+       
+       if (setLowMassCut)
+       {
+               TPair* pair = static_cast<TPair*>(map->FindObject("lowmasscut"));
+               if (pair == NULL)
+               {
+                       HLTError("Configuration object for \"%s\" does not contain the low invariant mass cut value.",
+                               pathToEntry
+                       );
+                       return -ENOENT;
+               }
+               TObject* valueObj = pair->Value();
+               if (valueObj->IsA() != TObjString::Class())
+               {
+                       HLTError("The low invariant mass cut parameter found in configuration object \"%s\""
+                               " is not a TObjString. Found an object of type %s instead.",
+                               pathToEntry, valueObj->ClassName()
+                       );
+                       return -EPROTO;
+               }
+               TString value = dynamic_cast<TObjString*>(valueObj)->GetString();
+               if (not value.IsFloat())
+               {
+                       HLTError("The low invariant mass cut parameter found in configuration object \"%s\""
+                               "is not a floating point string; found \"%s\".",
+                               pathToEntry, value.Data()
+                       );
+                       return -EPROTO;
+               }
+               fLowMassCut = (AliHLTFloat32_t) value.Atof();
+       }
+       
+       if (setHighMassCut)
+       {
+               TPair* pair = static_cast<TPair*>(map->FindObject("highmasscut"));
+               if (pair == NULL)
+               {
+                       HLTError("Configuration object for \"%s\" does not contain the high invariant mass cut value.",
+                               pathToEntry
+                       );
+                       return -ENOENT;
+               }
+               TObject* valueObj = pair->Value();
+               if (valueObj->IsA() != TObjString::Class())
+               {
+                       HLTError("The high invariant mass cut parameter found in configuration object \"%s\""
+                               " is not a TObjString. Found an object of type %s instead.",
+                               pathToEntry, valueObj->ClassName()
+                       );
+                       return -EPROTO;
+               }
+               TString value = dynamic_cast<TObjString*>(valueObj)->GetString();
+               if (not value.IsFloat())
+               {
+                       HLTError("The high invariant mass cut parameter found in configuration object \"%s\""
+                               "is not a floating point string; found \"%s\".",
+                               pathToEntry, value.Data()
+                       );
+                       return -EPROTO;
+               }
+               fHighMassCut = (AliHLTFloat32_t) value.Atof();
+       }
+       
+       return 0;
+}
+
+
+int AliHLTMUONDecisionComponent::AddTrack(const AliHLTMUONMansoTrackStruct* track)
+{
+       /// Adds a track to the internal track list for future reference in
+       /// ApplyTriggerAlgorithm when we actually apply the trigger algorithm.
+
+       assert(fTrackCount <= fMaxTracks);
+       assert(fTracks != NULL);
+       
+       if (fTrackCount == fMaxTracks)
+       {
+               // Buffer full so we need to resize it.
+               const AliHLTMUONMansoTrackStruct** tmp = NULL;
+               try
+               {
+                       tmp = new AliHLTMUONMansoTrackStructP[fMaxTracks+1];
+               }
+               catch (const std::bad_alloc&)
+               {
+                       HLTError("Could not allocate more memory for the track array.");
+                       return -ENOMEM;
+               }
+               
+               // Copy over the exisiting data and then delete the old array.
+               memcpy(tmp, fTracks, sizeof(AliHLTMUONMansoTrackStructP)*fTrackCount);
+               delete [] fTracks;
+               fTracks = tmp;
+               fMaxTracks = fMaxTracks+1;
+       }
+       
+       fTracks[fTrackCount] = track;
+       fTrackCount++;
+       return 0;
+}
+
+
+void AliHLTMUONDecisionComponent::ApplyTriggerAlgorithm(
+               AliHLTMUONSinglesDecisionBlockStruct& singlesHeader,
+               AliHLTMUONTrackDecisionStruct* singlesDecision,
+               AliHLTMUONPairsDecisionBlockStruct& pairsHeader,
+               AliHLTMUONPairDecisionStruct* pairsDecision
+       )
+{
+       /// This method applies the dHLT trigger decision algorithm to all the
+       /// tracks found in the input data.
+
+       // Zero the trigger counters for single tracks.
+       singlesHeader.fNlowPt = 0;
+       singlesHeader.fNhighPt = 0;
+
+       // Zero the trigger counters for pairs.
+       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;
+       
+       // For the single tracks we check if a track has pT larger than either
+       // the low or high pT cut. If it does then we increment the appropriate
+       // counters in the header.
+       for (AliHLTUInt32_t n = 0; n < fTrackCount; n++)
+       {
+               const AliHLTMUONMansoTrackStruct* track = fTracks[n];
+               AliHLTMUONTrackDecisionStruct& decision = singlesDecision[n];
+               
+               bool passedHighPtCut = false;
+               bool passedLowPtCut = false;
+               
+               AliHLTFloat32_t pt = sqrt(track->fPx * track->fPx + track->fPy * track->fPy);
+               
+               if (pt > fHighPtCut)
+               {
+                       passedHighPtCut = true;
+                       singlesHeader.fNlowPt++;
+               }
+               if (pt > fLowPtCut)
+               {
+                       passedLowPtCut = true;
+                       singlesHeader.fNhighPt++;
+               }
+               
+               decision.fTrackId = track->fId;
+               decision.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits(
+                               passedHighPtCut, passedLowPtCut
+                       );
+               decision.fPt = pt;
+       }
+       
+       // Now we generate all the possible pairs of tracks and fill in the
+       // trigger information. This will consist of calculating the invariant
+       // mass for the pair, checking if it passes the low or high mass cut
+       // and incrementing the appropriate statistics.
+       AliHLTUInt32_t currentPair = 0;
+       for (AliHLTUInt32_t i = 0; i < fTrackCount; i++)
+       for (AliHLTUInt32_t j = i+1; j < fTrackCount; j++)
+       {
+               const AliHLTMUONMansoTrackStruct* tracki = fTracks[i];
+               const AliHLTMUONMansoTrackStruct* trackj = fTracks[j];
+               const AliHLTMUONTrackDecisionStruct& trackidecision = singlesDecision[i];
+               const AliHLTMUONTrackDecisionStruct& trackjdecision = singlesDecision[j];
+               AliHLTMUONPairDecisionStruct& decision = pairsDecision[currentPair];
+               
+               AliHLTFloat32_t muMass = 0.1056583568; // muon mass in GeV/c^2
+               
+               AliHLTFloat32_t mass = AliHLTMUONCalculations::ComputeMass(
+                               muMass, tracki->fPx, tracki->fPy, tracki->fPz,
+                               muMass, trackj->fPx, trackj->fPy, trackj->fPz
+                       );
+               
+               AliHLTMUONParticleSign signi, signj;
+               bool hitset[4];
+               AliHLTMUONUtils::UnpackMansoTrackFlags(tracki->fFlags, signi, hitset);
+               AliHLTMUONUtils::UnpackMansoTrackFlags(trackj->fFlags, signj, hitset);
+               
+               AliHLTUInt8_t highPtCount = 0;
+               if (trackidecision.fPt > fHighPtCut) highPtCount++;
+               if (trackjdecision.fPt > fHighPtCut) highPtCount++;
+               AliHLTUInt8_t lowPtCount = 0;
+               if (trackidecision.fPt > fLowPtCut) lowPtCount++;
+               if (trackjdecision.fPt > fLowPtCut) lowPtCount++;
+               
+               bool unlikeSign = (signi == kSignMinus and signj == kSignPlus) or
+                                 (signi == kSignPlus  and signj == kSignMinus);
+               
+               bool passedHighMassCut = false;
+               bool passedLowMassCut = false;
+               if (unlikeSign)
+               {
+                       pairsHeader.fNunlikeAnyPt++;
+                       if (lowPtCount == 2) pairsHeader.fNunlikeLowPt++;
+                       if (highPtCount == 2) pairsHeader.fNunlikeHighPt++;
+                       
+                       if (mass > fHighMassCut)
+                       {
+                               passedHighMassCut = true;
+                               if (highPtCount == 2) pairsHeader.fNmassHigh++;
+                       }
+                       if (mass > fLowMassCut)
+                       {
+                               passedLowMassCut = true;
+                               pairsHeader.fNmassAny++;
+                               if (lowPtCount == 2) pairsHeader.fNmassLow++;
+                       }
+               }
+               else
+               {
+                       pairsHeader.fNlikeAnyPt++;
+                       if (lowPtCount == 2) pairsHeader.fNlikeLowPt++;
+                       if (highPtCount == 2) pairsHeader.fNlikeHighPt++;
+               }
+               
+               decision.fTrackAId = tracki->fId;
+               decision.fTrackBId = trackj->fId;
+               decision.fTriggerBits = AliHLTMUONUtils::PackPairDecisionBits(
+                               passedHighMassCut, passedLowMassCut, unlikeSign,
+                               highPtCount, lowPtCount
+                       );
+               decision.fInvMass = mass;
+               
+               currentPair++;
+       }
+       
+       assert( currentPair == fTrackCount * (fTrackCount-1) / 2 );
+}
+
diff --git a/HLT/MUON/OnlineAnalysis/AliHLTMUONDecisionComponent.h b/HLT/MUON/OnlineAnalysis/AliHLTMUONDecisionComponent.h
new file mode 100644 (file)
index 0000000..dd5c4bd
--- /dev/null
@@ -0,0 +1,125 @@
+#ifndef AliHLTMUONDECISIONCOMPONENT_H
+#define AliHLTMUONDECISIONCOMPONENT_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                               */
+
+/* $Id: $ */
+
+///
+///  @file   AliHLTMUONDecisionComponent.h
+///  @author Artur Szostak <artursz@iafrica.com>
+///  @date   30 April 2008
+///  @brief  Declares the decision component for dimuon HLT triggering.
+///
+
+#include "AliHLTProcessor.h"
+#include "AliHLTMUONDataTypes.h"
+#include <vector>
+
+#if __GNUC__ && __GNUC__ < 3
+#define std
+#endif
+
+extern "C" struct AliHLTMUONMansoTrackStruct;
+extern "C" struct AliHLTMUONTrackDecisionStruct;
+extern "C" struct AliHLTMUONPairDecisionStruct;
+extern "C" struct AliHLTMUONSinglesDecisionBlockStruct;
+extern "C" struct AliHLTMUONPairsDecisionBlockStruct;
+
+
+/**
+ * @class AliHLTMUONDecisionComponent
+ * @brief Dimuon HLT trigger decision component.
+ *
+ * This class implements the dimuon HLT trigger decision component.
+ * The dimuon trigger decision is generated by first applying two pT cuts to the
+ * single tracks: a low cut for the J/psi family and a high cut for the upsilon
+ * family. From the tracks that pass the cuts, we count them and build up some
+ * statistics like the number of tracks passing the low or high pT cut.
+ * The algorithm then looks at pairs of tracks and similarly counts the number
+ * like sign or unlike sign pairs where both tracks passed the low or high pT cut
+ * or pairs that did not pass any cuts.
+ * At this point the invariant mass of the pairs is calculated and two mass cuts
+ * are applied. The number of pairs that pass the low or high mass cut are then
+ * counted. The results are encoded into two data blocks, one for trigger decisions
+ * for single tracks and another for the track pairs.
+ */
+class AliHLTMUONDecisionComponent : public AliHLTProcessor
+{
+public:
+       AliHLTMUONDecisionComponent();
+       virtual ~AliHLTMUONDecisionComponent();
+
+       // Public functions to implement the AliHLTProcessor interface.
+       // These functions are required for the registration process.
+       virtual const char* GetComponentID();
+       virtual void GetInputDataTypes(AliHLTComponentDataTypeList& list);
+       virtual AliHLTComponentDataType GetOutputDataType();
+       virtual int GetOutputDataTypes(AliHLTComponentDataTypeList& list);
+       virtual void GetOutputDataSize(unsigned long& constBase, double& inputMultiplier);
+       virtual AliHLTComponent* Spawn();
+
+protected:
+
+       // Protected functions to implement the AliHLTProcessor interface.
+       // These functions provide initialization as well as the actual processing
+       // capabilities of the component.
+       virtual int DoInit(int argc, const char** argv);
+       virtual int DoDeinit();
+       virtual int Reconfigure(const char* cdbEntry, const char* componentId);
+       virtual int DoEvent(
+                       const AliHLTComponentEventData& evtData,
+                       const AliHLTComponentBlockData* blocks,
+                       AliHLTComponentTriggerData& trigData,
+                       AliHLTUInt8_t* outputPtr,
+                       AliHLTUInt32_t& size,
+                       std::vector<AliHLTComponentBlockData>& outputBlocks
+               );
+       
+       using AliHLTProcessor::DoEvent;
+
+private:
+
+       // Do not allow copying of this class.
+       AliHLTMUONDecisionComponent(const AliHLTMUONDecisionComponent& /*obj*/);
+       AliHLTMUONDecisionComponent& operator = (const AliHLTMUONDecisionComponent& /*obj*/);
+       
+       /**
+        * Reads the cut parameters from the CDB.
+        * \param path  The relative CDB path to use for the CDB entry.
+        *              If NULL the default value is used.
+        * \param setLowPtCut  Indicates if the low pT cut should be set (default true).
+        * \param setHighPtCut  Indicates if the high pT cut should be set (default true).
+        * \param setLowMassCut  Indicates if the low invariant mass cut should be set (default true).
+        * \param setHighMassCut  Indicates if the high invariant mass cut should be set (default true).
+        * \return 0 is returned on success and a non-zero value to indicate failure.
+        */
+       int ReadConfigFromCDB(
+                       const char* path = NULL,
+                       bool setLowPtCut = true, bool setHighPtCut = true,
+                       bool setLowMassCut = true, bool setHighMassCut = true
+               );
+       
+       int AddTrack(const AliHLTMUONMansoTrackStruct* track);
+       
+       void ApplyTriggerAlgorithm(
+                       AliHLTMUONSinglesDecisionBlockStruct& singlesHeader,
+                       AliHLTMUONTrackDecisionStruct* singlesDecision,
+                       AliHLTMUONPairsDecisionBlockStruct& pairsHeader,
+                       AliHLTMUONPairDecisionStruct* pairsDecision
+               );
+
+       AliHLTUInt32_t fMaxTracks; /// The maximum number of elements that can be stored in fTracks.
+       AliHLTUInt32_t fTrackCount;  /// The current number of elements stored in fTracks.
+       const AliHLTMUONMansoTrackStruct** fTracks;  /// Pointers to the track structures in input data blocks.
+       AliHLTFloat32_t fLowPtCut;  /// The low pT cut value to apply to tracks. [GeV/c]
+       AliHLTFloat32_t fHighPtCut;  /// The high pT cut value to apply to tracks. [GeV/c]
+       AliHLTFloat32_t fLowMassCut;  /// The low invariant mass cut value to apply to tracks. [GeV/c^2]
+       AliHLTFloat32_t fHighMassCut;  /// The high invariant mass cut value to apply to tracks. [GeV/c^2]
+       bool fWarnForUnexpecedBlock;  /// Flag indicating if we should log a warning if we got a block of an unexpected type.
+       
+       ClassDef(AliHLTMUONDecisionComponent, 0);  // Trigger decision component for the dimuon HLT.
+};
+
+#endif // AliHLTMUONDECISIONCOMPONENT_H
diff --git a/HLT/MUON/macros/CreateDefaultCDBEntries.C b/HLT/MUON/macros/CreateDefaultCDBEntries.C
new file mode 100644 (file)
index 0000000..e767a03
--- /dev/null
@@ -0,0 +1,89 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+/* $Id: $ */
+
+/**
+ * \ingroup macros
+ * \file CreateDefaultCDBEntries.C
+ * \brief Macro for generating default CDB entries for dHLT.
+ *
+ * This macro is used to generate some default CDB entries for the dHLT.
+ * It is an experts macro so make sure you know what you are doing.
+ *
+ * The simplest way to run this macro with defaults is to copy "rootlogon.C" from
+ * $ALICE_ROOT/HLT/MUON/macros into your current working directory, then from
+ * the shell command prompt run the following command:
+ * \code
+ *   > aliroot -b -q -l $ALICE_ROOT/HLT/MUON/macros/CreateDefaultCDBEntries.C+
+ * \endcode
+ *
+ * \author Artur Szostak <artursz@iafrica.com>
+ */
+
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include "AliCDBManager.h"
+#include "AliCDBStorage.h"
+#include "AliCDBEntry.h"
+#include "AliHLTMUONConstants.h"
+#include "TMap.h"
+#include "TObjString.h"
+#include "TString.h"
+#include <iostream>
+using std::cerr;
+using std::endl;
+#endif
+
+/**
+ * Generates default CDB entries in the given CDB storage (local by default)
+ * \param cdbPath  The path to the local storage.
+ */
+void CreateDefaultCDBEntries(const char* cdbPath = "local://$ALICE_ROOT")
+{
+       // Setup the CDB default storage and run number.
+       AliCDBManager* cdbManager = AliCDBManager::Instance();
+       if (cdbManager == NULL)
+       {
+               cerr << "ERROR: Global CDB manager object does not exist." << endl;
+               return;
+       }
+       
+       AliCDBStorage* storage = cdbManager->GetStorage(cdbPath);
+       if (storage == NULL)
+       {
+               cerr << "ERROR: Could not get storage for: " << cdbPath << endl;
+               return;
+       }
+       
+       Int_t verison = 0;
+       Int_t firstRun = 0;
+       Int_t lastRun = AliCDBRunRange::Infinity();
+       
+       // Create and store the configuration parameters for the trigger decision cuts.
+       TMap* cuts = new TMap;
+       cuts->SetOwner(kTRUE);
+       cuts->Add(new TObjString("lowptcut"), new TObjString("1"));
+       cuts->Add(new TObjString("highptcut"), new TObjString("2"));
+       cuts->Add(new TObjString("lowmasscut"), new TObjString("2.5"));
+       cuts->Add(new TObjString("highmasscut"), new TObjString("7"));
+       
+       const char* path = AliHLTMUONConstants::DecisionComponentCDBPath();
+       AliCDBId id(path, firstRun, lastRun, verison);
+       AliCDBMetaData* metaData = new AliCDBMetaData();
+       metaData->SetResponsible("dimuon HLT");
+       metaData->SetComment("Trigger decision cuts for dimuon HLT.");
+       storage->Put(cuts, id, metaData);
+}
index e9fdd81..01e431a 100644 (file)
@@ -134,6 +134,7 @@ void RunChain(
        bool minLogging = false;
        bool useRootWriter = false;
        bool makeTracksOnly = false;
+       bool buildDecisionComp = true;
        
        // Parse the chainType, output, dataSource and logLevel option strings:
        TString outOpt = output;
@@ -172,6 +173,7 @@ void RunChain(
        {
                buildDDLFilePubs = true;
                buildDDLRecoComps = true;
+               buildDecisionComp = false;
        }
        else if (chainOpt.CompareTo("tracker", TString::kIgnoreCase) == 0)
        {
@@ -379,6 +381,12 @@ void RunChain(
        {
                AliHLTConfiguration tracker("tracker", "MUONMansoTrackerFSM", "recDDL13 recDDL14 recDDL15 recDDL16 recDDL17 recDDL18 recDDL19 recDDL20 recDDL21 recDDL22", "");
        }
+       
+       // Build the dHLT trigger decision component if enabled.
+       if (buildDecisionComp)
+       {
+               AliHLTConfiguration decision("decision", "MUONDecisionComponent", "tracker", "");
+       }
 
        // Build the data sink to subscribe only to what has been created and
        // to the data source we actaully want.
@@ -393,6 +401,11 @@ void RunChain(
                        sources += "tracker ";
                sources += "recDDL13 recDDL14 recDDL15 recDDL16 recDDL17 recDDL18 recDDL19 recDDL20 recDDL21 recDDL22";
        }
+       if (buildDecisionComp)
+       {
+               // Add the trigger decision component if it was enabled.
+               sources += " decision";
+       }
        if (useRootWriter)
        {
                AliHLTConfiguration convert("convert", "MUONRootifier", sources, "");
index 4b03a79..dbbde5e 100644 (file)
@@ -789,7 +789,10 @@ int DumpTrackDecisionStruct(
        AliHLTMUONUtils::UnpackTrackDecisionBits(decision->fTriggerBits, highPt, lowPt);
        cout << setw(7) << left << (highPt ? "yes" : "no");
        cout << setw(8) << left << (lowPt ? "yes" : "no");
-       cout << setw(0) << endl;
+       
+       result = CheckField(decision->fPt, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << setw(0) << decision->fPt << endl;
 
        return result;
 }
@@ -814,9 +817,9 @@ int DumpSinglesDecisionBlock(
        AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
        
        // Print the data block record entries.
-       cout << "           |        Trigger Bits" << endl;
-       cout << "Track ID   | Raw         HighPt LowPt" << endl;
-       cout << "--------------------------------------" << endl;
+       cout << "           |        Trigger Bits      |" << endl;
+       cout << "Track ID   | Raw         HighPt LowPt | pT" << endl;
+       cout << "----------------------------------------------------" << endl;
        const AliHLTMUONTrackDecisionStruct* entry = block.GetArray();
        for(AliHLTUInt32_t i = 0; i < nentries; i++)
        {
@@ -1161,29 +1164,33 @@ int ReadFile(const char* filename, char*& buffer, unsigned long& bufferSize)
 /**
  * Prints the command line usage of this program to standard error.
  */
-void PrintUsage()
+void PrintUsage(bool asError = true)
 {
-       cerr << "Usage: dHLTdumpraw [-help|-h] [-continue] [-type <typename>] <filename>" << endl;
-       cerr << "Where <filename> is the name of a file containing a raw data block." << endl;
-       cerr << "Options:" << endl;
-       cerr << " -help | -h" << endl;
-       cerr << "       Displays this message." << endl;
-       cerr << " -continue" << endl;
-       cerr << "       If specified, the program will try to continue parsing the data block" << endl;
-       cerr << "       as much as possible rather than stopping at the first error." << endl;
-       cerr << " -type <typename>" << endl;
-       cerr << "       Forces the contents of the file to be interpreted as a specific" << endl;
-       cerr << "       type of data block. Where <typename> can be one of:" << endl;
-       cerr << "         trigrecs - trigger records data." << endl;
-       cerr << "         trigrecsdebug - debugging information about trigger records." << endl;
-       cerr << "         trigchannels - channel debugging in." << endl;
-       cerr << "         rechits - reconstructed hits data." << endl;
-       cerr << "         channels - channel debugging information from hit reconstruction." << endl;
-       cerr << "         clusters - cluster debugging information from hit reconstruction." << endl;
-       cerr << "         mansotracks - partial tracks from Manso algorithm." << endl;
-       cerr << "         mansocandidates - track candidates considered in the Manso algorithm." << endl;
-       cerr << "         singlesdecision - trigger decisions for single tracks." << endl;
-       cerr << "         pairsdecision - trigger decisions for track pairs." << endl;
+       std::ostream& os = asError ? cerr : cout;
+       os << "Usage: dHLTdumpraw [-help|-h] [-continue] [-type <typename>] <filename>" << endl;
+       os << "Where <filename> is the name of a file containing a raw data block." << endl;
+       os << "Options:" << endl;
+       os << " -help | -h" << endl;
+       os << "       Displays this message." << endl;
+       os << " -continue" << endl;
+       os << "       If specified, the program will try to continue parsing the data block" << endl;
+       os << "       as much as possible rather than stopping at the first error." << endl;
+       os << " -type <typename>" << endl;
+       os << "       Forces the contents of the subsequent files specified on the command" << endl;
+       os << "       line to be interpreted as a specific type of data block." << endl;
+       os << "       Where <typename> can be one of:" << endl;
+       os << "         trigrecs - trigger records data." << endl;
+       os << "         trigrecsdebug - debugging information about trigger records." << endl;
+       os << "         trigchannels - channel debugging in." << endl;
+       os << "         rechits - reconstructed hits data." << endl;
+       os << "         channels - channel debugging information from hit reconstruction." << endl;
+       os << "         clusters - cluster debugging information from hit reconstruction." << endl;
+       os << "         mansotracks - partial tracks from Manso algorithm." << endl;
+       os << "         mansocandidates - track candidates considered in the Manso algorithm." << endl;
+       os << "         singlesdecision - trigger decisions for single tracks." << endl;
+       os << "         pairsdecision - trigger decisions for track pairs." << endl;
+       os << "         autodetect - the type of the data block will be automatically" << endl;
+       os << "                      detected." << endl;
 }
 
 /**
@@ -1243,27 +1250,33 @@ AliHLTMUONDataBlockType ParseCommandLineType(const char* type)
  * Parses the command line.
  * @param argc  Number of arguments as given in main().
  * @param argv  Array of arguments as given in main().
- * @param filename  Receives the pointer to the file name string.
- * @param type      Receives the type of the data block expected, i.e. the
- *                  value of the -type flag.
+ * @param filenames  Pointer to buffer storing file name strings.
+ * @param numOfFiles  Receives the number of file name strings that were found
+ *                    and added to 'filenames'.
+ * @param filetypes  Array that receives the type of the data block expected, i.e.
+ *                   the value of the -type flag for the corresponding file.
  * @return  A status flag suitable for returning from main(), containing either
  *          EXIT_SUCCESS or CMDLINE_ERROR.
  */
 int ParseCommandLine(
-               int argc, const char** argv,
-               const char*& filename, bool& continueParse,
-               AliHLTMUONDataBlockType& type
+               int argc,
+               const char** argv,
+               const char** filenames,
+               int& numOfFiles,
+               bool& continueParse,
+               AliHLTMUONDataBlockType* filetypes
        )
 {
-       filename = NULL;
+       numOfFiles = 0;
        continueParse = false;
+       AliHLTMUONDataBlockType currentType = kUnknownDataBlock;
 
        // Parse the command line.
        for (int i = 1; i < argc; i++)
        {
                if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "-h") == 0)
                {
-                       PrintUsage();
+                       PrintUsage(false);
                        return EXIT_SUCCESS;
                }
                else if (strcmp(argv[i], "-continue") == 0)
@@ -1272,29 +1285,36 @@ int ParseCommandLine(
                }
                else if (strcmp(argv[i], "-type") == 0)
                {
-                       // Now we need to parse the typename in the command line.
-                       type = ParseCommandLineType(argv[++i]);
-                       if (type == kUnknownDataBlock) return CMDLINE_ERROR;
-               }
-               else
-               {
-                       if (filename != NULL)
+                       if (++i >= argc)
                        {
-                               cerr << "ERROR: Only one file can be specified, but got '"
-                                       << argv[i] << "', with '" << filename
-                                       << "' specified earlier." << endl << endl;
+                               cerr << "ERROR: Missing a type specifier" << endl;
                                PrintUsage();
                                return CMDLINE_ERROR;
                        }
+                       // Now we need to parse the typename in the command line.
+                       if (strcmp(argv[i], "autodetect") == 0)
+                       {
+                               currentType = kUnknownDataBlock;
+                       }
                        else
-                               filename = argv[i];
+                       {
+                               currentType = ParseCommandLineType(argv[i]);
+                               if (currentType == kUnknownDataBlock) return CMDLINE_ERROR;
+                       }
+               }
+               else
+               {
+                       assert( numOfFiles < argc );
+                       filenames[numOfFiles] = argv[i];
+                       filetypes[numOfFiles] = currentType;
+                       numOfFiles++;
                }
        }
        
-       // Now check that we have the filename and all the flags we need.
-       if (filename == NULL)
+       // Now check that we have at least one filename and all the flags we need.
+       if (numOfFiles == 0)
        {
-               cerr << "ERROR: Missing a file name. You must specify a file to process."
+               cerr << "ERROR: Missing a file name. You must specify at least one file to process."
                        << endl << endl;
                PrintUsage();
                return CMDLINE_ERROR;
@@ -1306,25 +1326,39 @@ int ParseCommandLine(
 
 int main(int argc, const char** argv)
 {
-       const char* filename = NULL;
+       int numOfFiles = 0;
        bool continueParse = false;
        int returnCode = EXIT_SUCCESS;
-       AliHLTMUONDataBlockType type = kUnknownDataBlock;
        char* buffer = NULL;
 
        try
        {
-               returnCode = ParseCommandLine(argc, argv, filename, continueParse, type);
+               // There will be at least 'argc' number of filenames.
+               typedef const char* AnsiString;
+               const char** filename = new AnsiString[argc];
+               AliHLTMUONDataBlockType* filetype = new AliHLTMUONDataBlockType[argc];
+               
+               returnCode = ParseCommandLine(argc, argv, filename, numOfFiles, continueParse, filetype);
 
-               if (returnCode == EXIT_SUCCESS and filename != NULL)
+               if (returnCode == EXIT_SUCCESS)
                {
-                       unsigned long bufferSize = 0;
-                       returnCode = ReadFile(filename, buffer, bufferSize);
-                       if (returnCode == EXIT_SUCCESS)
-                               returnCode = ParseBuffer(buffer, bufferSize, continueParse, type);
-                       if (buffer != NULL) delete [] buffer;
+                       for (int i = 0; i < numOfFiles; i++)
+                       {
+                               unsigned long bufferSize = 0;
+                               returnCode = ReadFile(filename[i], buffer, bufferSize);
+                               if (returnCode != EXIT_SUCCESS) break;
+                               int result = ParseBuffer(buffer, bufferSize, continueParse, filetype[i]);
+                               if (buffer != NULL) delete [] buffer;
+                               if (result != EXIT_SUCCESS)
+                               {
+                                       returnCode = result;
+                                       if (not continueParse) break;
+                               }
+                       }
                }
                
+               delete [] filename;
+               delete [] filetype;
        }
        catch (...)
        {
@@ -1332,6 +1366,6 @@ int main(int argc, const char** argv)
                returnCode = FATAL_ERROR;
                if (buffer != NULL) delete [] buffer;
        }
-
+       
        return returnCode;
 }
index 34e4882..214d7be 100644 (file)
@@ -10,6 +10,7 @@ CLASS_HDRS :=         OfflineInterface/AliHLTMUONAgent.h \
                OnlineAnalysis/AliHLTMUONTriggerReconstructorComponent.h \
                OnlineAnalysis/AliHLTMUONHitReconstructorComponent.h \
                OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.h \
+               OnlineAnalysis/AliHLTMUONDecisionComponent.h \
                utils/AliHLTMUONEmptyEventFilterComponent.h \
                AliHLTMUONRecHit.h \
                AliHLTMUONTriggerRecord.h \