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 91bb8b0ccdbf02b59742e0769571b7f0cd73c832..c598307d35d2c43b42598ed67b67cb37662b221e 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 d45a1a62eec194805985b124e1b357ba5a2bcda3..dfefa003b0019c5c831fa78a6994ebdbcfb45297 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 a6b272a1d3b277155a9fff730dea422a803c0953..bc86de7bc8e3fe47f44f5e1cddac96a4b03820e0 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 7d2a31cf4a62b135fb1329a7ce53e2137986699d..bdb6be9d9d4ea3de08226a117f97deffbeaa21a1 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 1301c88f5a7f735fa80b17760d3e1227be57b8a4..5959c5a10f8253f6dca95fee46edc181670d1268 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 1ca547db52c3edbc567cbc41243ac854c032dddb..cd4fc6a682d0a59e505cb2c652cac48e04c8459b 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 fd155cdad9398a61edca20e4e9ce833646e11355..fadf9c364845996c7c0b8fcb85381f27d489d65b 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 2f83b44da3491d69e62a0b3bf398acfffe0e3df5..aee12a43e38d8085cb099260dc7cd0612a649131 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 0d741891826ce399fee679d875b67931c0a1b79e..2fb1f00c72c606ee6d7c8cec0d819bde82088381 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 ea256ed318b0657a2f08ee5e11ceeddc7e28aa24..238e3a466deb135d8010542e931bf9e00eedf893 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 60d62d1cb91e24a0fe4a82b6c16f39a769df4e82..fba0d6907dba633881f0e8e99d011748144a9436 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 e986cbdc2cdbd92012089fdd236befb8e8a63305..5bdebd3505a4cbe4d0ce24ceb682651be578ad6a 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 \