Added:
authoraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 2 Jul 2008 09:08:48 +0000 (09:08 +0000)
committeraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 2 Jul 2008 09:08:48 +0000 (09:08 +0000)
Adding AliHLTMUONESDMaker to convert dHLT reconstructed Manso track and trigger record data to AliESDEvent format.
Changes:
Adding options to AliHLTMUONDigitPublisherComponent for -ddlid to use DDL equipment ID numbers and -exclude_chamber, -exclude_detelem to optionally mask out specific chambers or detector elements.
AliHLTMUONRootifierComponent now generates the specification bits for output data blocks properly.
Small changes to AliHLTMUONMansoTrackerFSMComponent, AliHLTMUONTriggerReconstructorComponent, AliHLTMUONHitReconstructorComponent and AliHLTMUONDecisionComponent to handle the fOffset value properly for robustness.

14 files changed:
HLT/MUON/AliHLTMUONConstants.cxx
HLT/MUON/AliHLTMUONConstants.h
HLT/MUON/HLTMUONLinkDef.h
HLT/MUON/OfflineInterface/AliHLTMUONAgent.cxx
HLT/MUON/OfflineInterface/AliHLTMUONDigitPublisherComponent.cxx
HLT/MUON/OfflineInterface/AliHLTMUONDigitPublisherComponent.h
HLT/MUON/OfflineInterface/AliHLTMUONESDMaker.cxx [new file with mode: 0644]
HLT/MUON/OfflineInterface/AliHLTMUONESDMaker.h [new file with mode: 0644]
HLT/MUON/OfflineInterface/AliHLTMUONRootifierComponent.cxx
HLT/MUON/OnlineAnalysis/AliHLTMUONDecisionComponent.cxx
HLT/MUON/OnlineAnalysis/AliHLTMUONHitReconstructorComponent.cxx
HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.cxx
HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructorComponent.cxx
HLT/libAliHLTMUON.pkg

index 91bb8b0..c598307 100644 (file)
@@ -165,6 +165,10 @@ AliHLTMUONConstants::fgkPairsDecisionBlockDataType = (AliHLTComponentDataType){
        kAliHLTDataOriginAny
 } | kAliHLTDataOriginMUON;
 
+const AliHLTComponentDataType
+AliHLTMUONConstants::fgkESDDataType = kAliHLTDataTypeESDObject | kAliHLTDataOriginMUON;
+
+
 const char* AliHLTMUONConstants::fgkRecHitsSourceId = "MUONRecHitsSource";
 const char* AliHLTMUONConstants::fgkTriggerRecordsSourceId = "MUONTriggerRecordsSource";
 const char* AliHLTMUONConstants::fgkTracksSourceId = "MUONTracksSource";
@@ -173,6 +177,7 @@ const char* AliHLTMUONConstants::fgkTriggerReconstructorId = "MUONTriggerReconst
 const char* AliHLTMUONConstants::fgkHitReconstructorId = "MUONHitReconstructor";
 const char* AliHLTMUONConstants::fgkMansoTrackerFSMId = "MUONMansoTrackerFSM";
 const char* AliHLTMUONConstants::fgkDecisionComponentId = "MUONDecisionComponent";
+const char* AliHLTMUONConstants::fgkESDMakerId = "MUONESDMaker";
 const char* AliHLTMUONConstants::fgkRootifierComponentId = "MUONRootifier";
 const char* AliHLTMUONConstants::fgkEmptyEventFilterComponentId = "MUONEmptyEventFilter";
 const char* AliHLTMUONConstants::fgkDataCheckerComponentId = "MUONDataChecker";
index d45a1a6..dfefa00 100644 (file)
@@ -155,6 +155,11 @@ public:
        {
                return fgkPairsDecisionBlockDataType;
        }
+
+       static const AliHLTComponentDataType& ESDDataType()
+       {
+               return fgkESDDataType;
+       }
        
        static const char* RecHitsSourceId()
        {
@@ -196,6 +201,11 @@ public:
                return fgkDecisionComponentId;
        }
        
+       static const char* ESDMakerId()
+       {
+               return fgkESDMakerId;
+       }
+       
        static const char* RootifierComponentId()
        {
                return fgkRootifierComponentId;
@@ -257,6 +267,7 @@ private:
        static const AliHLTComponentDataType fgkMansoCandidatesBlockDataType; // Debugging information about a track candidate generated by the Manso algorithm.
        static const AliHLTComponentDataType fgkSinglesDecisionBlockDataType; // Trigger decision block type for single track decisions.
        static const AliHLTComponentDataType fgkPairsDecisionBlockDataType; // Trigger decision block type for pairs of particles.
+       static const AliHLTComponentDataType fgkESDDataType; // The ESD data type with origin equal to MUON.
        
        // Component ID names:
        static const char* fgkRecHitsSourceId; // Name of source component for reconstructed hits for debugging.
@@ -267,6 +278,7 @@ private:
        static const char* fgkHitReconstructorId; // Centre of gravity cluster finder component name.
        static const char* fgkMansoTrackerFSMId; // Manso tracker FSM implementation component name.
        static const char* fgkDecisionComponentId; // dHLT decision component name.
+       static const char* fgkESDMakerId; // Name of ESD maker component which converts dHLT data to AliESDEvent classes.
        static const char* fgkRootifierComponentId; // The name of the event filter debugging component.
        static const char* fgkEmptyEventFilterComponentId; // The name of the event filter debugging component.
        static const char* fgkDataCheckerComponentId; // Name of data checking component for debugging.
index a6b272a..bc86de7 100644 (file)
@@ -46,6 +46,7 @@
 #pragma link C++ class AliHLTMUONHitReconstructorComponent+;
 #pragma link C++ class AliHLTMUONMansoTrackerFSMComponent+;
 #pragma link C++ class AliHLTMUONDecisionComponent+;
+#pragma link C++ class AliHLTMUONESDMaker+;
 #pragma link C++ class AliHLTMUONRecHit+;
 #pragma link C++ class AliHLTMUONRecHit::AliChannel+;
 #pragma link C++ class AliHLTMUONTriggerRecord+;
index 7d2a31c..bdb6be9 100644 (file)
@@ -32,6 +32,7 @@
 #include "AliHLTMUONTriggerReconstructorComponent.h"
 #include "AliHLTMUONMansoTrackerFSMComponent.h"
 #include "AliHLTMUONDecisionComponent.h"
+#include "AliHLTMUONESDMaker.h"
 #include "AliHLTMUONEmptyEventFilterComponent.h"
 #include "AliHLTMUONDataCheckerComponent.h"
 #include "AliRawReader.h"
@@ -328,6 +329,7 @@ int AliHLTMUONAgent::RegisterComponents(AliHLTComponentHandler* pHandler) const
        pHandler->AddComponent(new AliHLTMUONTriggerReconstructorComponent);
        pHandler->AddComponent(new AliHLTMUONMansoTrackerFSMComponent);
        pHandler->AddComponent(new AliHLTMUONDecisionComponent);
+       pHandler->AddComponent(new AliHLTMUONESDMaker);
        pHandler->AddComponent(new AliHLTMUONEmptyEventFilterComponent);
        pHandler->AddComponent(new AliHLTMUONDataCheckerComponent);
        return 0;
index 1301c88..5959c5a 100644 (file)
@@ -44,6 +44,7 @@
 #include "AliMpCDB.h"
 #include "AliMpDDL.h"
 #include "AliMpDDLStore.h"
+#include "AliMpDEManager.h"
 #include "AliMpTriggerCrate.h"
 #include "AliMpConstants.h"
 #include "AliBitPacking.h"
@@ -77,7 +78,9 @@ AliHLTMUONDigitPublisherComponent::AliHLTMUONDigitPublisherComponent() :
        fCurrentEventIndex(0),
        fMakeScalars(false),
        fMCDataInterface(NULL),
-       fDataInterface(NULL)
+       fDataInterface(NULL),
+       fChamberExclusionList(0),
+       fDetElemExclusionList(0)
 {
        /// Default constructor.
 }
@@ -130,6 +133,205 @@ AliHLTComponent* AliHLTMUONDigitPublisherComponent::Spawn()
 }
 
 
+int AliHLTMUONDigitPublisherComponent::ParseChamberString(const char* str)
+{
+       /// Parses a string with the following format:
+       ///   <number>|<number>-<number>[,<number>|<number>-<number>]...
+       /// For example: 1  1,2,3  1-2   1,2-4,5  etc...
+       /// Chamber numbers must be in the range [1..10] for tracking chambers.
+       /// All valid tracking chamber numbers will added to fChamberExclusionList.
+       /// @param str  The string to parse.
+       /// @return  Zero on success and EINVAL if there is a parse error.
+       
+       char* end = const_cast<char*>(str);
+       long lastChamber = -1;
+       do
+       {
+               // Parse the next number.
+               char* current = end;
+               long chamber = strtol(current, &end, 0);
+               
+               // Check for parse errors of the number.
+               if (current == end)
+               {
+                       HLTError("Expected a number in the range [1..%d] but got '%s'.",
+                               AliMUONConstants::NTrackingCh(), current
+                       );
+                       return -EINVAL;
+               }
+               if (chamber < 1 or AliMUONConstants::NTrackingCh() < chamber)
+               {
+                       HLTError("Received the chamber number %d, which is outside the valid range of [1..%d].",
+                               chamber, AliMUONConstants::NTrackingCh()
+                       );
+                       return -EINVAL;
+               }
+               
+               // Skip any whitespace after the number
+               while (*end != '\0' and (*end == ' ' or *end == '\t' or *end == '\r' or *end == '\n')) end++;
+               
+               // Check if we are dealing with a list or range, or if we are at
+               // the end of the string.
+               if (*end == '-')
+               {
+                       lastChamber = chamber;
+                       end++;
+                       continue;
+               }
+               else if (*end == ',')
+               {
+                       assert( 1 <= chamber and chamber <= AliMUONConstants::NTrackingCh() );
+                       Int_t size = fChamberExclusionList.GetSize();
+                       fChamberExclusionList.Set(size+1);
+                       fChamberExclusionList[size] = chamber-1;
+                       end++;
+               }
+               else if (*end == '\0')
+               {
+                       assert( 1 <= chamber and chamber <= AliMUONConstants::NTrackingCh() );
+                       Int_t size = fChamberExclusionList.GetSize();
+                       fChamberExclusionList.Set(size+1);
+                       fChamberExclusionList[size] = chamber-1;
+               }
+               else
+               {
+                       HLTError("Could not understand parameter list '%s'. Expected '-', ','"
+                                 " or end of line, but received '%c' at character %d.",
+                               str, *end, (int)(end - str) +1
+                       );
+                       return -EINVAL;
+               }
+               
+               // Set the range of chambers to publish for.
+               if (lastChamber > 0)
+               {
+                       Int_t min, max;
+                       if (lastChamber < chamber)
+                       {
+                               min = lastChamber;
+                               max = chamber;
+                       }
+                       else
+                       {
+                               min = chamber;
+                               max = lastChamber;
+                       }
+                       assert( min >= 1 );
+                       assert( max <= AliMUONConstants::NTrackingCh() );
+                       for (Int_t i = min; i <= max; i++)
+                       {
+                               Int_t size = fChamberExclusionList.GetSize();
+                               fChamberExclusionList.Set(size+1);
+                               fChamberExclusionList[size] = i-1;
+                       }
+               }
+               lastChamber = -1;
+       }
+       while (*end != '\0');
+       return 0;
+}
+
+
+int AliHLTMUONDigitPublisherComponent::ParseDetElemString(const char* str)
+{
+       /// Parses a string with the following format:
+       ///   <number>|<number>-<number>[,<number>|<number>-<number>]...
+       /// For example: 100  100,201,208  100-104   105,202-204,503  etc...
+       /// Detector element numbers must be in the range [100..1099] for tracking stations.
+       /// All valid detector element numbers will added to fDetElemExclusionList.
+       /// @param str  The string to parse.
+       /// @return  Zero on success and EINVAL if there is a parse error.
+       
+       char* end = const_cast<char*>(str);
+       long lastDetElem = -1;
+       do
+       {
+               // Parse the next number.
+               char* current = end;
+               long detElem = strtol(current, &end, 0);
+               
+               // Check for parse errors of the number.
+               if (current == end)
+               {
+                       HLTError("Expected a number in the range [100..1099] but got '%s'.",
+                               current
+                       );
+                       return -EINVAL;
+               }
+               if (detElem < 100 or 1099 < detElem)
+               {
+                       HLTError("Received the detector element ID number of %d,"
+                               " which is outside the valid range of [100..1099].",
+                               detElem
+                       );
+                       return -EINVAL;
+               }
+               
+               // Skip any whitespace after the number
+               while (*end != '\0' and (*end == ' ' or *end == '\t' or *end == '\r' or *end == '\n')) end++;
+               
+               // Check if we are dealing with a list or range, or if we are at
+               // the end of the string.
+               if (*end == '-')
+               {
+                       lastDetElem = detElem;
+                       end++;
+                       continue;
+               }
+               else if (*end == ',')
+               {
+                       assert( 100 <= detElem and detElem <= 1099 );
+                       Int_t size = fDetElemExclusionList.GetSize();
+                       fDetElemExclusionList.Set(size+1);
+                       fDetElemExclusionList[size] = detElem-1;
+                       end++;
+               }
+               else if (*end == '\0')
+               {
+                       assert( 100 <= detElem and detElem <= 1099 );
+                       Int_t size = fDetElemExclusionList.GetSize();
+                       fDetElemExclusionList.Set(size+1);
+                       fDetElemExclusionList[size] = detElem-1;
+               }
+               else
+               {
+                       HLTError("Could not understand parameter list '%s'. Expected '-', ','"
+                                 " or end of line, but received '%c' at character %d.",
+                               str, *end, (int)(end - str) +1
+                       );
+                       return -EINVAL;
+               }
+               
+               // Set the range of detector elements to publish for.
+               if (lastDetElem > 0)
+               {
+                       Int_t min, max;
+                       if (lastDetElem < detElem)
+                       {
+                               min = lastDetElem;
+                               max = detElem;
+                       }
+                       else
+                       {
+                               min = detElem;
+                               max = lastDetElem;
+                       }
+                       assert( min >= 100 );
+                       assert( max <= 1099 );
+                       for (Int_t i = min; i <= max; i++)
+                       {
+                               Int_t size = fDetElemExclusionList.GetSize();
+                               fDetElemExclusionList.Set(size+1);
+                               fDetElemExclusionList[size] = i-1;
+                       }
+               }
+               lastDetElem = -1;
+       }
+       while (*end != '\0');
+       return 0;
+}
+
+
 int AliHLTMUONDigitPublisherComponent::DoInit(int argc, const char** argv)
 {
        /// Inherited from AliHLTComponent.
@@ -152,6 +354,8 @@ int AliHLTMUONDigitPublisherComponent::DoInit(int argc, const char** argv)
        fDDL = -1;
        fCurrentEventIndex = 0;
        fMakeScalars = false;
+       fChamberExclusionList.Set(0);
+       fDetElemExclusionList.Set(0);
        bool simdata = false;
        bool recdata = false;
        bool firstEventSet = false;
@@ -178,7 +382,7 @@ int AliHLTMUONDigitPublisherComponent::DoInit(int argc, const char** argv)
                {
                        if (argc <= i+1)
                        {
-                               HLTError("DDL number not specified. It must be in the range [21..22]" );
+                               HLTError("DDL number not specified. It must be in the range [1..22]" );
                                return -EINVAL;
                        }
                
@@ -186,12 +390,12 @@ int AliHLTMUONDigitPublisherComponent::DoInit(int argc, const char** argv)
                        unsigned long num = strtoul(argv[i+1], &cpErr, 0);
                        if (cpErr == NULL or *cpErr != '\0')
                        {
-                               HLTError("Cannot convert '%s' to a DDL Number.", argv[i+1]);
+                               HLTError("Cannot convert '%s' to a DDL number.", argv[i+1]);
                                return -EINVAL;
                        }
                        if (num < 1 or 22 < num)
                        {
-                               HLTError("The DDL ID number must be in the range [1..22].");
+                               HLTError("The DDL number must be in the range [1..22].");
                                return -EINVAL;
                        }
                        fDDL = num - 1; // Convert to DDL number in the range 0..21
@@ -199,6 +403,35 @@ int AliHLTMUONDigitPublisherComponent::DoInit(int argc, const char** argv)
                        i++;
                        continue;
                }
+               if (strcmp(argv[i], "-ddlid") == 0)
+               {
+                       if (argc <= i+1)
+                       {
+                               HLTError("DDL equipment ID number not specified."
+                                       " It must be in the range [2560..2579] or [2816..2817]."
+                               );
+                               return -EINVAL;
+                       }
+               
+                       char* cpErr = NULL;
+                       unsigned long num = strtoul(argv[i+1], &cpErr, 0);
+                       if (cpErr == NULL or *cpErr != '\0')
+                       {
+                               HLTError("Cannot convert '%s' to a DDL equipment ID number.", argv[i+1]);
+                               return -EINVAL;
+                       }
+                       fDDL = AliHLTMUONUtils::EquipIdToDDLNumber(num); // Convert to DDL number in the range 0..21
+                       if (fDDL < 0 or 21 < fDDL)
+                       {
+                               HLTError("The DDL equipment ID number must be in the range"
+                                       " [2560..2579] or [2816..2817]."
+                               );
+                               return -EINVAL;
+                       }
+                       
+                       i++;
+                       continue;
+               }
                if (strcmp(argv[i], "-firstevent") == 0)
                {
                        if (eventNumLitSet)
@@ -237,6 +470,36 @@ int AliHLTMUONDigitPublisherComponent::DoInit(int argc, const char** argv)
                        eventNumLitSet = true;
                        continue;
                }
+               if (strcmp(argv[i], "-exclude_chamber") == 0)
+               {
+                       if (argc <= i+1)
+                       {
+                               HLTError("Expected a chamber number, a range eg. '1-10', or a list eg."
+                                       " '1,2,3' after '-exclude_chamber'."
+                               );
+                               return -EINVAL;
+                       }
+                       
+                       int result = ParseChamberString(argv[i+1]);
+                       if (result != 0) return result;
+                       i++;
+                       continue;
+               }
+               if (strcmp(argv[i], "-exclude_detelem") == 0)
+               {
+                       if (argc <= i+1)
+                       {
+                               HLTError("Expected a detector element ID number, a range eg. '100-108',"
+                                       " or a list eg. '100,102,301' after '-exclude_detelem'."
+                               );
+                               return -EINVAL;
+                       }
+                       
+                       int result = ParseDetElemString(argv[i+1]);
+                       if (result != 0) return result;
+                       i++;
+                       continue;
+               }
                
                HLTError("Unknown option '%s'.", argv[i]);
                return -EINVAL;
@@ -530,6 +793,26 @@ AliHLTMUONDigitPublisherComponent::Digits2BusPatchMap(
   
   while ( ( digit = static_cast<AliMUONVDigit*>(next()) ) )
   {
+    // Check if we should exclude digits from a particular chamber or detector element.
+    bool excludeDigit = false;
+    for (Int_t i = 0; i < fDetElemExclusionList.GetSize(); i++)
+    {
+      if (digit->DetElemId() == fDetElemExclusionList[i])
+      {
+        excludeDigit = true;
+        break;
+      }
+    }
+    for (Int_t i = 0; i < fChamberExclusionList.GetSize(); i++)
+    {
+      if (AliMpDEManager::GetChamberId(digit->DetElemId()) == fChamberExclusionList[i])
+      {
+        excludeDigit = true;
+        break;
+      }
+    }
+    if (excludeDigit) continue;
+  
     charge = digit->ADC();
     if ( charge > kMAXADC )
     {
index 1ca547d..cd4fc6a 100644 (file)
@@ -14,6 +14,7 @@
 ///
 
 #include "AliHLTOfflineDataSource.h"
+#include "TArrayI.h"
 
 #if __GNUC__ && __GNUC__ < 3
 #define std
@@ -43,6 +44,9 @@ class AliMUONDataInterface;
  *       dimuon trigger.<br>
  *
  * Optional arguments:<br>
+ * \li -ddlid <br>
+ *       This is an alternative to using -ddl which allows specifying a DDL in
+ *       terms of the DDL equipment IDs.<br>
  * \li -makescalars <br>
  *       If set then the scalar events will be generated for the trigger DDLs.
  *       (default is not to generate the scalars)<br>
@@ -102,6 +106,9 @@ private:
        AliHLTMUONDigitPublisherComponent(const AliHLTMUONDigitPublisherComponent& /*obj*/);
        AliHLTMUONDigitPublisherComponent& operator = (const AliHLTMUONDigitPublisherComponent& /*obj*/);
        
+       int ParseChamberString(const char* str);
+       int ParseDetElemString(const char* str);
+       
        /////////////////////////////////////////////////////////////////////////////////////////
        // Methods copied from AliMUONRawWriter.
        //TODO: This is not ideal. We should have AliMUONRawWriter re-factored so that
@@ -141,6 +148,9 @@ private:
        AliMUONMCDataInterface* fMCDataInterface; ///< Access to MUON MC-related data.
        AliMUONDataInterface* fDataInterface; ///< Access to MUON data.
        
+       TArrayI fChamberExclusionList;  //! Exclusion list for tracking chambers.
+       TArrayI fDetElemExclusionList;  //! Exclusion list for tracking detector elements.
+       
        ClassDef(AliHLTMUONDigitPublisherComponent, 0)  // dHLT component for publishing DDL streams from digits on the fly.
 };
 
diff --git a/HLT/MUON/OfflineInterface/AliHLTMUONESDMaker.cxx b/HLT/MUON/OfflineInterface/AliHLTMUONESDMaker.cxx
new file mode 100644 (file)
index 0000000..efc193d
--- /dev/null
@@ -0,0 +1,381 @@
+/**************************************************************************
+ * 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   AliHLTMUONESDMaker.cxx
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date   30 June 2008
+/// @brief  Implementation of the AliHLTMUONESDMaker component.
+///
+/// The ESD maker component converts dHLT raw internal reconstructed information
+/// into AliESDEvent objects.
+///
+
+#include "AliHLTMUONESDMaker.h"
+#include "AliHLTMUONEvent.h"
+#include "AliHLTMUONConstants.h"
+#include "AliHLTMUONUtils.h"
+#include "AliHLTMUONRecHit.h"
+#include "AliHLTMUONTriggerRecord.h"
+#include "AliHLTMUONMansoTrack.h"
+#include "AliHLTMUONDecision.h"
+#include "AliMUONConstants.h"
+#include "AliMUONVCluster.h"
+#include "AliESDEvent.h"
+#include "AliESDRun.h"
+#include "AliESDMuonTrack.h"
+#include "AliESDMuonCluster.h"
+#include "TClonesArray.h"
+#include <cmath>
+#include <cassert>
+
+
+ClassImp(AliHLTMUONESDMaker);
+
+
+AliHLTMUONESDMaker::AliHLTMUONESDMaker() :
+       AliHLTMUONProcessor(),
+       fWarnForUnexpecedBlock(false),
+       fMakeMinimalESD(false)
+{
+       /// Default constructor.
+}
+
+
+AliHLTMUONESDMaker::~AliHLTMUONESDMaker()
+{
+       /// Default destructor.
+}
+
+
+int AliHLTMUONESDMaker::DoInit(int argc, const char** argv)
+{
+       /// Inherited from AliHLTComponent.
+       /// Parses the command line parameters and initialises the component.
+       
+       HLTInfo("Initialising dHLT ESD maker component.");
+       
+       fWarnForUnexpecedBlock = false;
+       fMakeMinimalESD = false;
+       
+       for (int i = 0; i < argc; i++)
+       {
+               if (strcmp(argv[i], "-make_minimal_esd") == 0)
+               {
+                       fMakeMinimalESD = true;
+                       continue;
+               }
+               
+               if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
+               {
+                       fWarnForUnexpecedBlock = true;
+                       continue;
+               }
+
+               HLTError("Unknown option '%s'.", argv[i]);
+               return -EINVAL;
+       }
+       
+       return 0;
+}
+
+
+int AliHLTMUONESDMaker::DoDeinit()
+{
+       /// Inherited from AliHLTComponent. Performs a cleanup of the component.
+       
+       HLTInfo("Deinitialising dHLT ESD maker component.");
+       return 0;
+}
+
+
+const char* AliHLTMUONESDMaker::GetComponentID()
+{
+       /// Inherited from AliHLTComponent. Returns the component ID.
+       
+       return AliHLTMUONConstants::ESDMakerId();
+}
+
+
+AliHLTComponentDataType AliHLTMUONESDMaker::GetOutputDataType()
+{
+       /// Inherited from AliHLTComponent.
+       /// Returns the ESD object data type with MUON origin.
+       
+       return AliHLTMUONConstants::ESDDataType();
+}
+
+
+void AliHLTMUONESDMaker::GetInputDataTypes(
+               vector<AliHLTComponentDataType>& list
+       )
+{
+       /// Inherited from AliHLTProcessor.
+       /// Returns the list of expected input data types.
+       
+       list.push_back(AliHLTMUONConstants::TriggerRecordsBlockDataType());
+       list.push_back(AliHLTMUONConstants::MansoTracksBlockDataType());
+}
+
+
+void AliHLTMUONESDMaker::GetOutputDataSize(
+               unsigned long& constBase, double& inputMultiplier
+       )
+{
+       /// Inherited from AliHLTComponent.
+       /// Returns an estimate of the expected output data size.
+       
+       constBase = sizeof(AliESDEvent);
+       inputMultiplier = 10;
+}
+
+
+AliHLTComponent* AliHLTMUONESDMaker::Spawn()
+{
+       /// Inherited from AliHLTComponent. Creates a new object instance.
+       
+       return new AliHLTMUONESDMaker();
+}
+
+
+int AliHLTMUONESDMaker::DoEvent(
+               const AliHLTComponentEventData& /*evtData*/,
+               AliHLTComponentTriggerData& /*trigData*/
+       )
+{
+       /// Inherited from AliHLTProcessor. Processes the new event data.
+       
+       AliESDEvent event;
+       AliHLTUInt32_t clusterIndex = 0;  // for the cluster unique ID.
+       
+       // Create and fill in the standard ESD objects or just create the muon
+       // tracks array if so requested.
+       if (fMakeMinimalESD)
+       {
+               TClonesArray* muonTracks = new TClonesArray("AliESDMuonTrack",0);
+               muonTracks->SetName("MuonTracks");
+               event.AddObject(muonTracks);
+               event.GetStdContent();
+       }
+       else
+       {
+               event.CreateStdContent();
+               event.SetRunNumber(GetRunNo());
+       }
+       
+       const AliHLTComponentBlockData* block = NULL;
+       AliHLTUInt32_t specification = 0;  // Contains the output data block spec bits.
+       std::vector<const AliHLTMUONTriggerRecordStruct*> triggerRecords;
+
+       // First process the blocks of trigger records. We simply mark each trigger
+       // record in the triggerRecords array.
+       for (int i = 0; i < GetNumberOfInputBlocks(); i++)
+       {
+               block = GetInputBlock(i);
+               assert( block != NULL );
+               
+               HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
+                       i, DataType2Text(block->fDataType).c_str(), block->fPtr, block->fSize
+               );
+               
+               if (block->fDataType == AliHLTMUONConstants::TriggerRecordsBlockDataType())
+               {
+                       specification |= block->fSpecification;
+                       AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
+                       ptr += block->fOffset;
+                       AliHLTMUONTriggerRecordsBlockReader inblock(ptr, block->fSize);
+                       if (not BlockStructureOk(inblock)) continue;
+                       
+                       for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
+                       {
+                               triggerRecords.push_back(&inblock[n]);
+                       }
+               }
+               else
+               {
+                       if (block->fDataType != AliHLTMUONConstants::MansoTracksBlockDataType())
+                       {
+                               // Log a message indicating that we got a data block that we
+                               // do not know how to handle.
+                               if (fWarnForUnexpecedBlock)
+                                       HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
+                                               DataType2Text(block->fDataType).c_str(), block->fSpecification
+                                       );
+                               else
+                                       HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
+                                               DataType2Text(block->fDataType).c_str(), block->fSpecification
+                                       );
+                       }
+               }
+       }
+       
+       // Now we can look for tracks to add. We needed the ROOT trigger records
+       // and reco hits created before we can create track objects.
+       for (block = GetFirstInputBlock(AliHLTMUONConstants::MansoTracksBlockDataType());
+            block != NULL;
+            block = GetNextInputBlock()
+           )
+       {
+               specification |= block->fSpecification;
+               AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
+               ptr += block->fOffset;
+               AliHLTMUONMansoTracksBlockReader inblock(ptr, block->fSize);
+               if (not BlockStructureOk(inblock)) continue;
+               
+               for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
+               {
+                       const AliHLTMUONMansoTrackStruct& t = inblock[n];
+                       AliESDMuonTrack muTrack;
+                       
+                       AliHLTMUONParticleSign sign;
+                       bool hitset[4];
+                       AliHLTMUONUtils::UnpackMansoTrackFlags(
+                                       t.fFlags, sign, hitset
+                               );
+                       
+                       double signVal = 0;
+                       switch (sign)
+                       {
+                       case kSignMinus:   signVal = +1.; break;
+                       case kSignUnknown: signVal =  0.; break;
+                       case kSignPlus:    signVal = -1.; break;
+                       default:
+                               HLTWarning("Got a track with an invalid sign value: %d", int(sign));
+                       }
+                       
+                       TVector3 mom(t.fPx, t.fPy, t.fPz);
+                       if (mom.Mag() != 0)
+                               muTrack.SetInverseBendingMomentum(signVal/mom.Mag());
+                       else
+                               muTrack.SetInverseBendingMomentum(0.);
+                       muTrack.SetThetaX(atan2(t.fPx, t.fPz));
+                       muTrack.SetThetaY(atan2(t.fPy, t.fPz));
+                       muTrack.SetZ(0.);
+                       muTrack.SetBendingCoor(0.);
+                       muTrack.SetNonBendingCoor(0.);
+                       
+                       // The Manso algorithm assumes the information at the
+                       // Distance of Closest Approach and chamber 1 is the same
+                       // as the vertex.
+                       if (mom.Mag() != 0)
+                               muTrack.SetInverseBendingMomentumAtDCA(1./mom.Mag());
+                       else
+                               muTrack.SetInverseBendingMomentumAtDCA(0.);
+                       muTrack.SetThetaXAtDCA(atan2(t.fPx, t.fPz));
+                       muTrack.SetThetaYAtDCA(atan2(t.fPy, t.fPz));
+                       muTrack.SetBendingCoorAtDCA(0.);
+                       muTrack.SetNonBendingCoorAtDCA(0.);
+                       
+                       if (mom.Mag() != 0)
+                               muTrack.SetInverseBendingMomentumUncorrected(1./mom.Mag());
+                       else
+                               muTrack.SetInverseBendingMomentumUncorrected(0.);
+                       muTrack.SetThetaXUncorrected(atan2(t.fPx, t.fPz));
+                       muTrack.SetThetaYUncorrected(atan2(t.fPy, t.fPz));
+                       muTrack.SetZUncorrected(0.);
+                       muTrack.SetBendingCoorUncorrected(0.);
+                       muTrack.SetNonBendingCoorUncorrected(0.);
+                       
+                       muTrack.SetChi2(t.fChi2);
+                       
+                       // Fill in the track hit points.
+                       Int_t nHits = 0;
+                       for (int i = 0; i < 4; i++)
+                       {
+                               if (not hitset[i]) continue;
+                               
+                               AliHLTUInt8_t chamber;
+                               AliHLTUInt16_t detElemId;
+                               AliHLTMUONUtils::UnpackRecHitFlags(t.fHit[i].fFlags, chamber, detElemId);
+                               
+                               AliESDMuonCluster cluster;
+                               cluster.SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, clusterIndex++));
+                               cluster.SetXYZ(t.fHit[i].fX, t.fHit[i].fY, t.fHit[i].fZ);
+                               cluster.SetErrXY(    // Use nominal values.
+                                               AliMUONConstants::DefaultNonBendingReso(),
+                                               AliMUONConstants::DefaultBendingReso()
+                                       );
+                               cluster.SetCharge(-1.);   // Indicate no total charge calculated.
+                               cluster.SetChi2(-1.);   // Indicate no fit made.
+                               muTrack.AddCluster(cluster);
+                               nHits++;
+                               muTrack.AddInMuonClusterMap(i+6);
+                       }
+                       
+                       // Find the corresponding trigger record.
+                       const AliHLTMUONTriggerRecordStruct* trigrec = NULL;
+                       for (size_t k = 0; k < triggerRecords.size(); k++)
+                       {
+                               if (triggerRecords[k]->fId == t.fTrigRec)
+                               {
+                                       trigrec = triggerRecords[k];
+                                       break;
+                               }
+                       }
+                       // If the trigger record was found then fill its hit information also.
+                       if (trigrec != NULL)
+                       {
+                               AliHLTMUONParticleSign trsign;
+                               bool trhitset[4];
+                               AliHLTMUONUtils::UnpackTriggerRecordFlags(
+                                               trigrec->fFlags, trsign, trhitset
+                                       );
+                               
+                               for (int i = 0; i < 4; i++)
+                               {
+                                       if (not trhitset[i]) continue;
+                                       
+                                       AliHLTUInt8_t chamber;
+                                       AliHLTUInt16_t detElemId;
+                                       AliHLTMUONUtils::UnpackRecHitFlags(trigrec->fHit[i].fFlags, chamber, detElemId);
+                               
+                                       AliESDMuonCluster cluster;
+                                       cluster.SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, clusterIndex++));
+                                       cluster.SetXYZ(
+                                                       trigrec->fHit[i].fX,
+                                                       trigrec->fHit[i].fY,
+                                                       trigrec->fHit[i].fZ
+                                               );
+                                       cluster.SetErrXY(    // Use nominal values.
+                                                       AliMUONConstants::TriggerNonBendingReso(),
+                                                       AliMUONConstants::TriggerBendingReso()
+                                               );
+                                       cluster.SetCharge(-1.);   // Indicate no total charge calculated.
+                                       cluster.SetChi2(-1.);   // Indicate no fit made.
+                                       muTrack.AddCluster(cluster);
+                                       nHits++;
+                                       muTrack.AddInMuonClusterMap(i+10);
+                               }
+                       }
+                       else
+                       {
+                               HLTWarning("Trigger record (ID = %d) not found for track ID = %d.",
+                                       t.fTrigRec, t.fId
+                               );
+                       }
+                       
+                       muTrack.SetNHit(nHits);
+                       event.AddMuonTrack(&muTrack);
+               }
+       }
+       
+       PushBack(&event, AliHLTMUONConstants::ESDDataType(), specification);
+       
+       return 0;
+}
+
diff --git a/HLT/MUON/OfflineInterface/AliHLTMUONESDMaker.h b/HLT/MUON/OfflineInterface/AliHLTMUONESDMaker.h
new file mode 100644 (file)
index 0000000..c46c735
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef ALIHLTMUONESDMAKER_H
+#define ALIHLTMUONESDMAKER_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   AliHLTMUONESDMaker.h
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date   30 June 2008
+/// @brief  Component for converting dHLT raw data into AliESDEvent objects.
+///
+
+#include "AliHLTMUONProcessor.h"
+
+/**
+ * @class AliHLTMUONESDMaker
+ * The component is used to convert dHLT reconstructed data into AliESDEvent
+ * objects which can be stored in ROOT files during offline reconstruction.
+ * Only the dHLT track and trigger record data is converted, then filled in the ESD.
+ * These should then be merged together with ESDs from all the other parts of
+ * HLT (eg. TPC HLT).<br>
+ * This component can also be run online to have ESDs directly in the raw
+ * HLT output data stream.<br>
+ *
+ * Component ID: \b MUONESDMaker <br>
+ * Library: \b libAliHLTMUON.so  <br>
+ *
+ * Optional arguments:<br>
+ * \li -make_minimal_esd <br>
+ *       Indicates that AliESDEvent objects should be created with only the TClonesArray
+ *       for the muon tracks created. (default is to generate all standard ESD objects)<br>
+ * \li -warn_on_unexpected_block <br>
+ *       If set, then warning messages are generated for any data block types that
+ *       were not expected. (default is to generate only debug messages)<br>
+ *
+ * @ingroup alihlt_dimuon_component
+ */
+class AliHLTMUONESDMaker : public AliHLTMUONProcessor
+{
+public:
+
+       AliHLTMUONESDMaker();
+       virtual ~AliHLTMUONESDMaker();
+       
+       virtual const char* GetComponentID();
+
+       virtual void GetInputDataTypes(vector<AliHLTComponentDataType>& list);
+       virtual AliHLTComponentDataType GetOutputDataType();
+       virtual void GetOutputDataSize(unsigned long& constBase, double& inputMultiplier);
+
+       virtual AliHLTComponent* Spawn();
+
+protected:
+
+       virtual int DoInit(int argc, const char** argv);
+       virtual int DoDeinit();
+       virtual int DoEvent(const AliHLTComponentEventData& evtData, AliHLTComponentTriggerData& trigData);
+       using AliHLTProcessor::DoEvent;
+       
+private:
+
+       // Prevent copying of these objects.
+       AliHLTMUONESDMaker(const AliHLTMUONESDMaker& /*object*/);
+       AliHLTMUONESDMaker& operator = (const AliHLTMUONESDMaker& /*object*/);
+       
+       bool fWarnForUnexpecedBlock;  /// Flag indicating if we should log a warning if we got a block of an unexpected type.
+       bool fMakeMinimalESD;  /// Flag to indicate if a minimal ESD object should be created.
+
+       ClassDef(AliHLTMUONESDMaker, 0); // Component for converting dHLT reconstructed data into the ESD format.
+};
+
+#endif // ALIHLTMUONESDMAKER_H
index fd155cd..fadf9c3 100644 (file)
@@ -167,6 +167,7 @@ int AliHLTMUONRootifierComponent::DoEvent(
        
        AliHLTMUONEvent event(evtData.fEventID);
        const AliHLTComponentBlockData* block = NULL;
+       AliHLTUInt32_t specification = 0;  // Contains the output data block spec bits.
 
        // First process the blocks of reconstructed hits and trigger records.
        for (int i = 0; i < GetNumberOfInputBlocks(); i++)
@@ -180,6 +181,7 @@ int AliHLTMUONRootifierComponent::DoEvent(
                
                if (block->fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
                {
+                       specification |= block->fSpecification;
                        AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
                        ptr += block->fOffset;
                        AliHLTMUONRecHitsBlockReader inblock(ptr, block->fSize);
@@ -221,6 +223,7 @@ int AliHLTMUONRootifierComponent::DoEvent(
                }
                else if (block->fDataType == AliHLTMUONConstants::TriggerRecordsBlockDataType())
                {
+                       specification |= block->fSpecification;
                        AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
                        ptr += block->fOffset;
                        AliHLTMUONTriggerRecordsBlockReader inblock(ptr, block->fSize);
@@ -300,6 +303,7 @@ int AliHLTMUONRootifierComponent::DoEvent(
             block = GetNextInputBlock()
            )
        {
+               specification |= block->fSpecification;
                AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
                ptr += block->fOffset;
                AliHLTMUONMansoTracksBlockReader inblock(ptr, block->fSize);
@@ -409,6 +413,7 @@ int AliHLTMUONRootifierComponent::DoEvent(
             block = GetNextInputBlock()
            )
        {
+               specification |= block->fSpecification;
                AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
                ptr += block->fOffset;
                AliHLTMUONSinglesDecisionBlockReader inblock(ptr, block->fSize);
@@ -470,6 +475,7 @@ int AliHLTMUONRootifierComponent::DoEvent(
             block = GetNextInputBlock()
            )
        {
+               specification |= block->fSpecification;
                AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
                ptr += block->fOffset;
                AliHLTMUONPairsDecisionBlockReader inblock(ptr, block->fSize);
@@ -551,7 +557,7 @@ int AliHLTMUONRootifierComponent::DoEvent(
        }
        event.Add(triggerDecision);
        
-       PushBack(&event, "ROOTEVNT", "MUON");
+       PushBack(&event, "ROOTEVNT", "MUON", specification);
        
        return 0;
 }
index 2f83b44..aee12a4 100644 (file)
@@ -341,7 +341,10 @@ int AliHLTMUONDecisionComponent::DoEvent(
                        // contributed to the output data.
                        specification |= blocks[n].fSpecification;
                        
-                       AliHLTMUONMansoTracksBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
+                       AliHLTMUONMansoTracksBlockReader inblock(
+                                       reinterpret_cast<char*>(blocks[n].fPtr) + blocks[n].fOffset,
+                                       blocks[n].fSize
+                               );
                        if (not BlockStructureOk(inblock)) continue;
                        
                        for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
index 0d74189..2fb1f00 100644 (file)
@@ -437,8 +437,9 @@ int AliHLTMUONHitReconstructorComponent::DoEvent(
                
                AliHLTUInt32_t totalDDLSize = blocks[n].fSize / sizeof(AliHLTUInt32_t);
                AliHLTUInt32_t ddlRawDataSize = totalDDLSize - fHitRec->GetkDDLHeaderSize();
-               AliHLTUInt32_t* buffer = reinterpret_cast<AliHLTUInt32_t*>(blocks[n].fPtr)
-                       + fHitRec->GetkDDLHeaderSize();
+               AliHLTUInt32_t* buffer = reinterpret_cast<AliHLTUInt32_t*>(
+                               reinterpret_cast<char*>(blocks[n].fPtr) + blocks[n].fOffset
+                       ) + fHitRec->GetkDDLHeaderSize();
                AliHLTUInt32_t nofHit = block.MaxNumberOfEntries();
 
 #ifdef DEBUG
index ea256ed..238e3a4 100644 (file)
@@ -299,7 +299,10 @@ int AliHLTMUONMansoTrackerFSMComponent::DoEvent(
                {
                        specification |= blocks[n].fSpecification;
                        
-                       AliHLTMUONRecHitsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
+                       AliHLTMUONRecHitsBlockReader inblock(
+                                       reinterpret_cast<char*>(blocks[n].fPtr) + blocks[n].fOffset,
+                                       blocks[n].fSize
+                               );
                        if (not BlockStructureOk(inblock)) continue;
                        
                        if (inblock.Nentries() != 0)
@@ -335,7 +338,10 @@ int AliHLTMUONMansoTrackerFSMComponent::DoEvent(
                if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
                        continue;
                
-               AliHLTMUONTriggerRecordsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
+               AliHLTMUONTriggerRecordsBlockReader inblock(
+                               reinterpret_cast<char*>(blocks[n].fPtr) + blocks[n].fOffset,
+                               blocks[n].fSize
+                       );
                if (not BlockStructureOk(inblock)) continue;
                
                DebugTrace("Processing a trigger block with "
index 60d62d1..fba0d69 100644 (file)
@@ -493,7 +493,9 @@ int AliHLTMUONTriggerReconstructorComponent::DoEvent(
                        );
                        continue;
                }
-               AliRawDataHeader* header = reinterpret_cast<AliRawDataHeader*>(blocks[n].fPtr);
+               AliRawDataHeader* header = reinterpret_cast<AliRawDataHeader*>(
+                               reinterpret_cast<char*>(blocks[n].fPtr) + blocks[n].fOffset
+                       );
                AliHLTUInt32_t payloadSize = totalDDLSize - sizeof(AliRawDataHeader);
                AliHLTUInt8_t* buffer = reinterpret_cast<AliHLTUInt8_t*>(header + 1);
                AliHLTUInt32_t nofTrigRec = block.MaxNumberOfEntries();
index e986cbd..5bdebd3 100644 (file)
@@ -8,6 +8,7 @@ CLASS_HDRS :=   OfflineInterface/AliHLTMUONAgent.h \
                OfflineInterface/AliHLTMUONRecHitsSource.h \
                OfflineInterface/AliHLTMUONDigitPublisherComponent.h \
                OfflineInterface/AliHLTMUONRootifierComponent.h \
+               OfflineInterface/AliHLTMUONESDMaker.h \
                OnlineAnalysis/AliHLTMUONTriggerReconstructorComponent.h \
                OnlineAnalysis/AliHLTMUONHitReconstructorComponent.h \
                OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.h \