Porting old TriggerSource to the AliRoot-HLT framework proper.
authorszostak <szostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sun, 16 Sep 2007 18:25:14 +0000 (18:25 +0000)
committerszostak <szostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sun, 16 Sep 2007 18:25:14 +0000 (18:25 +0000)
HLT/MUON/AliHLTMUONConstants.cxx
HLT/MUON/AliHLTMUONConstants.h
HLT/MUON/AliHLTMUONUtils.cxx
HLT/MUON/AliHLTMUONUtils.h
HLT/MUON/OfflineInterface/AliHLTMUONTriggerRecordsSource.cxx [new file with mode: 0644]
HLT/MUON/OfflineInterface/AliHLTMUONTriggerRecordsSource.h [new file with mode: 0644]
HLT/MUON/OnlineAnalysis/AliHLTMUONCalculations.cxx
HLT/MUON/OnlineAnalysis/AliHLTMUONCalculations.h

index 6708318..22f47fd 100644 (file)
@@ -1,15 +1,17 @@
 /**************************************************************************
- * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
+ * This file is property of and copyright by the ALICE HLT Project        * 
+ * All rights reserved.                                                   *
  *                                                                        *
- * Author: The ALICE Off-line Project.                                    *
- * Contributors are mentioned in the code where appropriate.              *
+ * Primary Authors:                                                       *
+ *   Indranil Das <indra.das@saha.ac.in>                                  *
+ *   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          *
+ * about the suitability of this software for any purpose. It is          * 
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 
@@ -181,4 +183,9 @@ AliHLTMUONConstants::fgkPairsDecisionBlockDataType = {
 };
 
 const char* AliHLTMUONConstants::fgkRecHitsSourceId = "DimuRecHitsSource";
+const char* AliHLTMUONConstants::fgkTriggerRecordsSourceId = "DimuTriggerRecordsSource";
+const char* AliHLTMUONConstants::fgkMansoTracksSourceId = "DimuMansoTracksSource";
+const char* AliHLTMUONConstants::fgkTriggerReconstructorId = "DimuTriggerReconstructor";
+const char* AliHLTMUONConstants::fgkHitReconstructorId = "DimuHitReconstructor";
 const char* AliHLTMUONConstants::fgkMansoTrackerFSMId = "DimuMansoTrackerFSM";
+const char* AliHLTMUONConstants::fgkDecisionComponentId = "DimuDecisionComponent";
index 3f3bdeb..5d38a18 100644 (file)
@@ -1,7 +1,21 @@
 #ifndef ALIHLTMUONCONSTANTS_H
 #define ALIHLTMUONCONSTANTS_H
-/* Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice                               */
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        * 
+ * All rights reserved.                                                   *
+ *                                                                        *
+ * Primary Authors:                                                       *
+ *   Indranil Das <indra.das@saha.ac.in>                                  *
+ *   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$ */
 
@@ -158,10 +172,35 @@ public:
                return fgkRecHitsSourceId;
        }
        
+       static const char* TriggerRecordsSourceId()
+       {
+               return fgkTriggerRecordsSourceId;
+       }
+       
+       static const char* MansoTracksSourceId()
+       {
+               return fgkMansoTracksSourceId;
+       }
+       
+       static const char* TriggerReconstructorId()
+       {
+               return fgkTriggerReconstructorId;
+       }
+       
+       static const char* HitReconstructorId()
+       {
+               return fgkHitReconstructorId;
+       }
+       
        static const char* MansoTrackerFSMId()
        {
                return fgkMansoTrackerFSMId;
        }
+       
+       static const char* DecisionComponentId()
+       {
+               return fgkDecisionComponentId;
+       }
 
 private:
 
@@ -199,8 +238,13 @@ private:
        static const AliHLTComponentDataType fgkPairsDecisionBlockDataType; // Trigger decision block type for pairs of particles.
        
        // Component ID names:
-       static const char* fgkRecHitsSourceId; // Reconstructed hit component name.
+       static const char* fgkRecHitsSourceId; // Name of source component for reconstructed hits for debugging.
+       static const char* fgkTriggerRecordsSourceId; // Name of source component for trigger records for debugging.
+       static const char* fgkMansoTracksSourceId; // Name of source component for Manso tracks for debugging.
+       static const char* fgkTriggerReconstructorId; // Trigger record reconstructor component name.
+       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.
 };
 
 #endif // ALIHLTMUONCONSTANTS_H
index 312a3dd..a885dbd 100644 (file)
@@ -38,7 +38,7 @@
 
 
 AliHLTUInt32_t AliHLTMUONUtils::PackTriggerRecordFlags(
-               AliHLTMUONParticleSign sign, bool hitset[4]
+               AliHLTMUONParticleSign sign, const bool hitset[4]
        )
 {
        AliHLTUInt32_t flags;
@@ -65,10 +65,10 @@ void AliHLTMUONUtils::UnpackTriggerRecordFlags(
        case 0x40000000: sign = kSignPlus;    break;
        default:         sign = kSignUnknown; break;
        }
-       hitset[0] = (flags & 0x1) == 1;
-       hitset[1] = (flags & 0x2) == 1;
-       hitset[2] = (flags & 0x4) == 1;
-       hitset[3] = (flags & 0x8) == 1;
+       hitset[0] = (flags & 0x1) == 0x1;
+       hitset[1] = (flags & 0x2) == 0x2;
+       hitset[2] = (flags & 0x4) == 0x4;
+       hitset[3] = (flags & 0x8) == 0x8;
 }
 
 
@@ -114,6 +114,35 @@ void AliHLTMUONUtils::UnpackPairDecisionBits(
 }
 
 
+AliHLTUInt32_t AliHLTMUONUtils::PackSpecBits(
+               const bool ddl[22]
+       )
+{
+       // Pack the bits into the following format:
+       //   bit:   [        31 - 22        ][     21     ][     20     ][  19 - 0 ]
+       //   field: [ reserved, set to zero ][ TRGDDL2816 ][ TRGDDL2817 ][ TRKDDLS ]
+       // Meaning of field acronyms:
+       //   TRGDDL2816 - Trigger DDL number 2816.
+       //   TRGDDL2817 - Trigger DDL number 2817.
+       //   TRKDDLS - Tracking DDL flags where bit 0 will be for DDL number 2560,
+       //             bit 1 for DDL no. 2561 etc. up to bit 19 which is for DDL 2579.
+       AliHLTUInt32_t bits = 0;
+       for (int i = 0; i < 22; i++)
+               bits |= (ddl[i] ? 0x1 : 0x0) << i;
+       return bits;
+}
+
+
+void AliHLTMUONUtils::UnpackSpecBits(
+               AliHLTUInt32_t bits, bool ddl[22]
+       )
+{
+       // Perform the inverse operation of PackSpecBits.
+       for (int i = 0; i < 22; i++)
+               ddl[i] = ((bits >> i) & 0x1) == 1;
+}
+
+
 bool AliHLTMUONUtils::HeaderOk(
                const AliHLTMUONTriggerRecordsBlockStruct& block,
                WhyNotValid* reason
index 93d72ef..4fa6fb8 100644 (file)
@@ -50,7 +50,7 @@ public:
         * @return  Returns the 32 bit packed word.
         */
        static AliHLTUInt32_t PackTriggerRecordFlags(
-                       AliHLTMUONParticleSign sign, bool hitset[4]
+                       AliHLTMUONParticleSign sign, const bool hitset[4]
                );
 
        /**
@@ -76,7 +76,7 @@ public:
         * @return  Returns the 32 bit packed word.
         */
        static AliHLTUInt32_t PackMansoTrackFlags(
-                       AliHLTMUONParticleSign sign, bool hitset[4]
+                       AliHLTMUONParticleSign sign, const bool hitset[4]
                )
        {
                return PackTriggerRecordFlags(sign, hitset);
@@ -162,6 +162,34 @@ public:
                        AliHLTUInt8_t& highPtCount, // [out]
                        AliHLTUInt8_t& lowPtCount // [out]
                );
+       
+       /**
+        * This packs the given parameters into the 32bit Pub/Sub specification
+        * word in the data block descriptor.
+        *
+        * @param ddl  The list of DDLs forming part of the readout. ddl[0]
+        *             indicates DDL number 2560, ddl[1] is for DDL 2561 and so
+        *             on up to ddl[19]. ddl[20] and ddl[21] will be for the
+        *             trigger DDLs 2816 and 2817 respectively.
+        * @return  Returns the 32 bit packed specification word.
+        */
+       static AliHLTUInt32_t PackSpecBits(
+                       const bool ddl[22]
+               );
+       
+       /**
+        * This unpacks the AliHLTMUONPairDecisionStruct::fTriggerBits bits into
+        * its component fields.
+        * @param bits  The Pub/Sub specification word from a data block descriptor.
+        * @param ddl  The output list of DDLs forming part of the readout. ddl[0]
+        *             indicates DDL number 2560, ddl[1] is for DDL 2561 and so
+        *             on up to ddl[19]. ddl[20] and ddl[21] will be for the
+        *             trigger DDLs 2816 and 2817 respectively.
+        */
+       static void UnpackSpecBits(
+                       AliHLTUInt32_t bits, // [in]
+                       bool ddl[22] // [out]
+               );
 
        /**
         * These codes indicate the reason why a data block failed its
diff --git a/HLT/MUON/OfflineInterface/AliHLTMUONTriggerRecordsSource.cxx b/HLT/MUON/OfflineInterface/AliHLTMUONTriggerRecordsSource.cxx
new file mode 100644 (file)
index 0000000..61a50a4
--- /dev/null
@@ -0,0 +1,553 @@
+/**************************************************************************
+ * 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   AliHLTMUONTriggerRecordsSource.cxx
+ * @author Artur Szostak <artursz@iafrica.com>
+ * @date   
+ * @brief  Implementation of the AliHLTMUONTriggerRecordsSource component.
+ */
+
+#include "AliHLTMUONTriggerRecordsSource.h"
+#include "AliHLTMUONConstants.h"
+#include "AliHLTMUONUtils.h"
+#include "AliHLTMUONDataBlockWriter.h"
+#include "AliHLTMUONCalculations.h"
+#include "AliMUONMCDataInterface.h"
+#include "AliMUONDataInterface.h"
+#include "AliMUONHit.h"
+#include "AliMUONRawCluster.h"
+#include "AliMUONConstants.h"
+#include "AliMUONVClusterStore.h"
+#include "AliMUONVHitStore.h"
+#include "mapping/AliMpCDB.h"
+#include "mapping/AliMpDDLStore.h"
+#include "mapping/AliMpLocalBoard.h"
+#include "mapping/AliMpTriggerCrate.h"
+#include "mapping/AliMpDEManager.h"
+#include "mapping/AliMpDetElement.h"
+#include "AliLog.h"
+#include "TClonesArray.h"
+#include <cstdlib>
+#include <cstdio>
+#include <cerrno>
+#include <cassert>
+#include <new>
+
+namespace
+{
+       // The global object used for automatic component registration.
+       // Note DO NOT use this component for calculation!
+       AliHLTMUONTriggerRecordsSource gAliHLTMUONTriggerRecordsSource;
+       
+       //TODO: The following method should be in MUON/mapping
+       Int_t FindDDLOfDetElement(Int_t detElemId)
+       {
+               // Find what the DDL ID number is for a detector element from
+               // trigger chambers 11 to 14. We first have to find the local
+               // board associated with the detector element and then we can
+               // associate that local board to the trigger crate which has
+               // the DDL number specified.
+               AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
+               if (ddlStore == NULL) return -1;
+               Int_t ddl = -1, boardIndex = 1;
+               do
+               {
+                       AliMpLocalBoard* board = ddlStore->GetLocalBoard(boardIndex++);
+                       if (board == NULL) break;
+                       if (board->HasDEId(detElemId))
+                       {
+                               AliMpTriggerCrate* crate = ddlStore->GetTriggerCrate(board->GetCrate());
+                               if (crate == NULL) continue;
+                               ddl = crate->GetDdlId();
+                               break;
+                       }
+               }
+               while (ddl == -1);
+               return ddl;
+       }
+
+}
+
+
+ClassImp(AliHLTMUONTriggerRecordsSource);
+
+
+AliHLTMUONTriggerRecordsSource::AliHLTMUONTriggerRecordsSource() :
+       AliHLTOfflineDataSource(),
+       fMCDataInterface(NULL),
+       fDataInterface(NULL),
+       fBuildFromHits(false),
+       fSelection(kWholePlane)
+{
+}
+
+
+AliHLTMUONTriggerRecordsSource::~AliHLTMUONTriggerRecordsSource()
+{
+       assert( fMCDataInterface == NULL );
+       assert( fDataInterface == NULL );
+}
+
+
+int AliHLTMUONTriggerRecordsSource::DoInit(int argc, const char** argv)
+{
+       assert( fMCDataInterface == NULL );
+       assert( fDataInterface == NULL );
+       
+       // Parse the command line arguments:
+       bool hitdata = false;
+       bool simdata = false;
+       bool recdata = false;
+       
+       for (int i = 0; i < argc; i++)
+       {
+               if (strcmp(argv[i], "-hitdata") == 0)
+               {
+                       hitdata = true;
+               }
+               else if (strcmp(argv[i], "-simdata") == 0)
+               {
+                       simdata = true;
+               }
+               else if (strcmp(argv[i], "-recdata") == 0)
+               {
+                       recdata = true;
+               }
+               else if (strcmp(argv[i], "-plane") == 0)
+               {
+                       i++;
+                       if (i >= argc)
+                       {
+                               Logging(kHLTLogError,
+                                       "AliHLTMUONTriggerRecordsSource::DoInit",
+                                       "Missing parameter",
+                                       "Expected one of 'left', 'right' or 'all' after '-plane'."
+                               );
+                               return EINVAL;
+                       }
+                       if (strcmp(argv[i], "left") == 0)
+                               fSelection = kLeftPlane;
+                       else if (strcmp(argv[i], "right") == 0)
+                               fSelection = kRightPlane;
+                       else if (strcmp(argv[i], "all") == 0)
+                               fSelection = kWholePlane;
+                       else
+                       {
+                               Logging(kHLTLogError,
+                                       "AliHLTMUONTriggerRecordsSource::DoInit",
+                                       "Invalid parameter",
+                                       "The parameter '%s' is invalid and must be one of 'left',"
+                                         " 'right' or 'all'.",
+                                       argv[i]
+                               );
+                               return EINVAL;
+                       }
+               }
+               else
+               {
+                       Logging(kHLTLogError,
+                               "AliHLTMUONTriggerRecordsSource::DoInit",
+                               "Unknown argument",
+                               "The argument '%s' is invalid.",
+                               argv[i]
+                       );
+                       return EINVAL;
+               }
+       }
+
+       // Check that one and only one of the the -hitdata, -simdata or
+       // -recdata parameters was specified on the command line.
+       if ((not hitdata and not simdata and not recdata) or
+           (not hitdata and simdata and recdata) or
+           (hitdata and not simdata and recdata) or
+           (hitdata and simdata and not recdata) or
+           (hitdata and simdata and recdata)
+          )
+       {
+               Logging(kHLTLogError,
+                       "AliHLTMUONTriggerRecordsSource::DoInit",
+                       "Missing arguments",
+                       "Must have one and only one of -hitdata, -simdata or -recdata specified."
+               );
+               return EINVAL;
+       }
+       
+       // Must load the mapping data for AliMpTriggerCrate::GetDdlId()  //TODO AliMpTriggerCrate => AliMpDetElement
+       // to return useful information later on.
+       AliMpCDB::LoadDDLStore();
+       
+       // Now we can initialise the data interface objects and loaders.
+       fBuildFromHits = hitdata;
+       if (hitdata or simdata)
+       {
+               const char* message = fBuildFromHits ?
+                       "Loading simulated GEANT hits with AliMUONMCDataInterface."
+                       : "Loading simulated local trigger objects with AliMUONMCDataInterface.";
+                               
+               Logging(kHLTLogDebug, "AliHLTMUONTriggerRecordsSource::DoInit",
+                       "Data interface", message
+               );
+               
+               try
+               {
+                       fMCDataInterface = new AliMUONMCDataInterface("galice.root");
+               }
+               catch (const std::bad_alloc&)
+               {
+                       Logging(kHLTLogError,
+                               "AliHLTMUONTriggerRecordsSource::DoInit",
+                               "Out of memory",
+                               "Not enough memory to allocate AliMUONMCDataInterface."
+                       );
+                       return ENOMEM;
+               }
+       }
+       else if (recdata)
+       {
+               Logging(kHLTLogDebug,
+                       "AliHLTMUONTriggerRecordsSource::DoInit",
+                       "Data interface",
+                       "Loading reconstructed local trigger objects with AliMUONDataInterface."
+               );
+               
+               try
+               {
+                       fDataInterface = new AliMUONDataInterface("galice.root");
+               }
+               catch (const std::bad_alloc&)
+               {
+                       Logging(kHLTLogError,
+                               "AliHLTMUONTriggerRecordsSource::DoInit",
+                               "Out of memory",
+                               "Not enough memory to allocate AliMUONDataInterface."
+                       );
+                       return ENOMEM;
+               }
+       }
+       
+       return 0;
+}
+
+
+int AliHLTMUONTriggerRecordsSource::DoDeinit()
+{
+       if (fMCDataInterface != NULL)
+       {
+               delete fMCDataInterface;
+               fMCDataInterface = NULL;
+       }
+       if (fDataInterface != NULL)
+       {
+               delete fDataInterface;
+               fDataInterface = NULL;
+       }
+       return 0;
+}
+
+
+const char* AliHLTMUONTriggerRecordsSource::GetComponentID()
+{
+       return AliHLTMUONConstants::TriggerRecordsSourceId();
+}
+
+
+AliHLTComponentDataType AliHLTMUONTriggerRecordsSource::GetOutputDataType()
+{
+       return AliHLTMUONConstants::TriggerRecordsBlockDataType();
+}
+
+
+void AliHLTMUONTriggerRecordsSource::GetOutputDataSize(
+               unsigned long& constBase, double& inputMultiplier
+       )
+{
+       constBase = sizeof(AliHLTMUONTriggerRecordsBlockStruct) +
+               sizeof(AliHLTMUONTriggerRecordStruct) * AliMUONConstants::NTriggerCircuit();
+       inputMultiplier = 0;
+}
+
+
+AliHLTComponent* AliHLTMUONTriggerRecordsSource::Spawn()
+{
+       return new AliHLTMUONTriggerRecordsSource();
+}
+
+
+int AliHLTMUONTriggerRecordsSource::GetEvent(
+               const AliHLTComponentEventData& evtData,
+               AliHLTComponentTriggerData& /*trigData*/,
+               AliHLTUInt8_t* outputPtr, 
+               AliHLTUInt32_t& size,
+               vector<AliHLTComponentBlockData>& outputBlocks
+       )
+{
+       assert( fMCDataInterface != NULL or fDataInterface != NULL );
+
+       AliHLTInt32_t trigRecId = 0;
+
+       // Check the size of the event descriptor structure.
+       if (evtData.fStructSize < sizeof(AliHLTComponentEventData))
+       {
+               Logging(kHLTLogError,
+                       "AliHLTMUONTriggerRecordsSource::GetEvent",
+                       "Invalid event descriptor",
+                       "The event descriptor (AliHLTComponentEventData) size is"
+                         " smaller than expected. It claims to be %d bytes, but"
+                         " we expect it to be %d bytes.",
+                       evtData.fStructSize,
+                       sizeof(AliHLTComponentEventData)
+               );
+               size = 0; // Important to tell framework that nothing was generated.
+               return EINVAL;
+       }
+       
+       // Use the fEventID as the event number to load, check it and load that
+       // event with the runloader.
+       UInt_t eventnumber = UInt_t(evtData.fEventID);
+       UInt_t maxevent = fMCDataInterface != NULL ?
+               UInt_t(fMCDataInterface->NumberOfEvents())
+               : UInt_t(fDataInterface->NumberOfEvents());
+       if ( eventnumber >= maxevent )
+       {
+               Logging(kHLTLogError,
+                       "AliHLTMUONTriggerRecordsSource::GetEvent",
+                       "Bad event ID",
+                       "The event number (%d) is larger than the available number"
+                         " of events on file (%d).",
+                       eventnumber,
+                       maxevent
+               );
+               size = 0; // Important to tell framework that nothing was generated.
+               return EINVAL;
+       }
+       
+       // Create and initialise a new data block.
+       AliHLTMUONTriggerRecordsBlockWriter block(outputPtr, size);
+       if (not block.InitCommonHeader())
+       {
+               Logging(kHLTLogError,
+                       "AliHLTMUONTriggerRecordsSource::GetEvent",
+                       "Buffer too small",
+                       "There is not enough buffer space to create a new data block."
+                         " We require at least %d bytes but the buffer is only %d bytes.",
+                       sizeof(AliHLTMUONTriggerRecordsBlockWriter::HeaderType),
+                       block.BufferSize()
+               );
+               size = 0; // Important to tell framework that nothing was generated.
+               return ENOBUFS;
+       }
+       
+       // Initialise the DDL list containing the DDLs which contributed to the
+       // data block. These are required to create the specification word later.
+       bool ddlList[22];
+       for (Int_t i = 0; i < 22; i++)
+               ddlList[i] = false;
+       
+       if (fMCDataInterface != NULL and fBuildFromHits)
+       {
+               Logging(kHLTLogDebug,
+                       "AliHLTMUONTriggerRecordsSource::GetEvent",
+                       "Filling triggers",
+                       "Filling data block with trigger records from GEANT hits for event %d.",
+                       eventnumber
+               );
+               
+               // Loop over all tracks, extract the hits from chambers 11 to 14 and
+               // create trigger records from them to write to the data block.
+               Int_t ntracks = fMCDataInterface->NumberOfTracks(eventnumber);
+               for (Int_t i = 0; i < ntracks; ++i)
+               {
+                       AliMUONHit* hit11 = NULL;
+                       AliMUONHit* hit12 = NULL;
+                       AliMUONHit* hit13 = NULL;
+                       AliMUONHit* hit14 = NULL;
+                       Int_t ddl11 = -1;
+                       Int_t ddl12 = -1;
+                       Int_t ddl13 = -1;
+                       Int_t ddl14 = -1;
+                       
+                       AliMUONVHitStore* hitStore = fMCDataInterface->HitStore(eventnumber,i);
+                       AliMUONHit* hit;
+                       TIter next(hitStore->CreateIterator());
+                       while ( ( hit = static_cast<AliMUONHit*>(next()) ) )
+                       {
+                               // Select only hits on trigger chambers.
+                               if (hit->Chamber() <= AliMUONConstants::NTrackingCh()) continue;
+                               
+                               // Only select hits from the given part of the plane
+                               if (fSelection == kLeftPlane and not (hit->Xref() < 0)) continue;
+                               if (fSelection == kRightPlane and not (hit->Xref() >= 0)) continue;
+                               
+                               // Workout which DDL this hit should be readout of.
+                               Int_t ddl = FindDDLOfDetElement(hit->DetElemId());
+                               if (not (0 <= ddl and ddl < 22))
+                               {
+                                       ddl = -1;
+                                       Logging(kHLTLogError,
+                                               "AliHLTMUONTriggerRecordsSource::GetEvent",
+                                               "No DDL ID",
+                                               "Could not find the DDL ID from which readout would take place."
+                                       );
+                               }
+                               
+                               switch (hit->Chamber())
+                               {
+                               case 11: hit11 = hit; ddl11 = ddl; break;
+                               case 12: hit12 = hit; ddl12 = ddl; break;
+                               case 13: hit13 = hit; ddl13 = ddl; break;
+                               case 14: hit14 = hit; ddl14 = ddl; break;
+                               default: break;
+                               }
+                       }
+                       
+                       // Check that there are at least 3 of 4 hits on the trigger chambers.
+                       Int_t hitCount = 0;
+                       if (hit11 != NULL) hitCount++;
+                       if (hit12 != NULL) hitCount++;
+                       if (hit13 != NULL) hitCount++;
+                       if (hit14 != NULL) hitCount++;
+                       if (hitCount < 3) continue;
+                               
+                       AliHLTMUONTriggerRecordStruct* trigRec = block.AddEntry();
+                       if (trigRec == NULL)
+                       {
+                               Logging(kHLTLogError,
+                                       "AliHLTMUONTriggerRecordsSource::GetEvent",
+                                       "Buffer overflow",
+                                       "There is not enough buffer space to add more trigger records."
+                                         " We overflowed the buffer which is only %d bytes.",
+                                       block.BufferSize()
+                               );
+                               size = 0; // Important to tell framework that nothing was generated.
+                               return ENOBUFS;
+                       }
+                       
+                       // Fill the new trigger record with the hit information.
+                       bool hitset[4] = {false, false, false, false};
+                       AliHLTFloat32_t x1 = 0, y1 = 0, y2 = 0, z1 = 0, z2 = 0;
+                       if (hit11 != NULL)
+                       {
+                               trigRec->fHit[0].fX = hit11->Xref();
+                               trigRec->fHit[0].fY = hit11->Yref();
+                               trigRec->fHit[0].fZ = hit11->Zref();
+                               hitset[0] = true;
+                               x1 = hit11->Xref();
+                               y1 = hit11->Yref();
+                               z1 = hit11->Zref();
+                       }
+                       if (hit12 != NULL)
+                       {
+                               trigRec->fHit[1].fX = hit12->Xref();
+                               trigRec->fHit[1].fY = hit12->Yref();
+                               trigRec->fHit[1].fZ = hit12->Zref();
+                               hitset[1] = true;
+                               x1 = hit12->Xref();
+                               y1 = hit12->Yref();
+                               z1 = hit12->Zref();
+                       }
+                       if (hit13 != NULL)
+                       {
+                               trigRec->fHit[2].fX = hit13->Xref();
+                               trigRec->fHit[2].fY = hit13->Yref();
+                               trigRec->fHit[2].fZ = hit13->Zref();
+                               hitset[2] = true;
+                               y2 = hit13->Yref();
+                               z2 = hit13->Zref();
+                       }
+                       if (hit14 != NULL)
+                       {
+                               trigRec->fHit[3].fX = hit14->Xref();
+                               trigRec->fHit[3].fY = hit14->Yref();
+                               trigRec->fHit[3].fZ = hit14->Zref();
+                               hitset[3] = true;
+                               y2 = hit14->Yref();
+                               z2 = hit14->Zref();
+                       }
+                       
+                       bool calculated = AliHLTMUONCalculations::ComputeMomentum(x1, y1, y2, z1, z2);
+                       if (not calculated)
+                               Logging(kHLTLogDebug,
+                                       "AliHLTMUONTriggerRecordsSource::GetEvent",
+                                       "Calculation failure",
+                                       "Something went wrong when calculating the momentum from"
+                                         " x1 = %f, y1 = %f, y2 = %f, z1 = %f, z2 = %f.",
+                                       x1, y1, y2, z1, z2
+                               );
+                       
+                       trigRec->fId = trigRecId++;
+                       trigRec->fFlags = AliHLTMUONUtils::PackTriggerRecordFlags(
+                                       AliHLTMUONCalculations::Sign(), hitset
+                               );
+                       trigRec->fPx = AliHLTMUONCalculations::Px();
+                       trigRec->fPy = AliHLTMUONCalculations::Py();
+                       trigRec->fPz = AliHLTMUONCalculations::Pz();
+                       
+                       // Mark the DDLs over which this trigger record would be readout.
+                       if (ddl11 != -1) ddlList[ddl11] = true;
+                       if (ddl12 != -1) ddlList[ddl12] = true;
+                       if (ddl13 != -1) ddlList[ddl13] = true;
+                       if (ddl14 != -1) ddlList[ddl14] = true;
+               }
+       }
+       else if (fMCDataInterface != NULL and not fBuildFromHits)
+       {
+               Logging(kHLTLogDebug,
+                       "AliHLTMUONTriggerRecordsSource::GetEvent",
+                       "Filling triggers",
+                       "Filling data block with simulated local triggers for event %d.",
+                       eventnumber
+               );
+               
+               AliFatal("Sorry, -simdata option not yet implemented!");
+               // TODO
+       }
+       else if (fDataInterface != NULL)
+       {
+               Logging(kHLTLogDebug,
+                       "AliHLTMUONTriggerRecordsSource::GetEvent",
+                       "Filling triggers",
+                       "Filling data block with reconstructed local triggers for event %d.",
+                       eventnumber
+               );
+               // TODO
+               AliFatal("Sorry, -recdata option not yet implemented!");
+       }
+       else
+       {
+               Logging(kHLTLogError,
+                       "AliHLTMUONTriggerRecordsSource::GetEvent",
+                       "Missing data interface",
+                       "Neither AliMUONDataInterface nor AliMUONMCDataInterface were created."
+               );
+               size = 0; // Important to tell framework that nothing was generated.
+               return EFAULT;
+       }
+       
+       AliHLTComponentBlockData bd;
+       FillBlockData(bd);
+       bd.fPtr = outputPtr;
+       bd.fOffset = 0;
+       bd.fSize = block.BytesUsed();
+       bd.fDataType = AliHLTMUONConstants::TriggerRecordsBlockDataType();
+       bd.fSpecification = AliHLTMUONUtils::PackSpecBits(ddlList);
+       outputBlocks.push_back(bd);
+       size = block.BytesUsed();
+
+       return 0;
+}
diff --git a/HLT/MUON/OfflineInterface/AliHLTMUONTriggerRecordsSource.h b/HLT/MUON/OfflineInterface/AliHLTMUONTriggerRecordsSource.h
new file mode 100644 (file)
index 0000000..e75fc71
--- /dev/null
@@ -0,0 +1,103 @@
+#ifndef ALIHLTMUONTRIGGERRECORDSSOURCE_H
+#define ALIHLTMUONTRIGGERRECORDSSOURCE_H
+/**************************************************************************
+ * 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   AliHLTMUONTriggerRecordsSource.h
+ * @author Artur Szostak <artursz@iafrica.com>
+ * @date   
+ * @brief  Class for generating trigger record data blocks from AliRoot data.
+ */
+
+#include "AliHLTOfflineDataSource.h"
+
+class AliMUONMCDataInterface;
+class AliMUONDataInterface;
+
+/**
+ * AliHLTMUONTriggerRecordsSource is a HLT-AliRoot data source object which generates
+ * and serves AliHLTMUONTriggerRecordsBlockStruct type data blocks to the HLT system.
+ * This is meant as a debugging utility which can optionally generate the data
+ * blocks from simulated GEANT hits, simulated local trigger objects or MUON
+ * offline reconstructed local trigger objects.
+ *
+ * Command line flags:
+ *  -hitdata
+ *      Specify this option to publish trigger records constructed from GEANT hits.
+ *  -simdata
+ *      Specify this option to publish trigger records constructed from simulated
+ *      local trigger objects.
+ *  -recdata
+ *      Specify this option to publish trigger records constructed from offline
+ *      reconstructed local trigger objects.
+ *  -plane left|right|all
+ *      Specifies if data from the left (x < 0), right (x >= 0) or the whole XY
+ *      plane should be published.
+ */
+class AliHLTMUONTriggerRecordsSource : public AliHLTOfflineDataSource
+{
+public:
+
+       AliHLTMUONTriggerRecordsSource();
+       virtual ~AliHLTMUONTriggerRecordsSource();
+       
+       virtual int GetEvent(
+                       const AliHLTComponentEventData& evtData,
+                       AliHLTComponentTriggerData& trigData,
+                       AliHLTUInt8_t* outputPtr, 
+                       AliHLTUInt32_t& size,
+                       vector<AliHLTComponentBlockData>& outputBlocks
+               );
+       
+       virtual const char* GetComponentID();
+
+       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();
+       
+private:
+
+       // Prevent copying of these objects.
+       AliHLTMUONTriggerRecordsSource(const AliHLTMUONTriggerRecordsSource& /*object*/);
+       AliHLTMUONTriggerRecordsSource& operator = (const AliHLTMUONTriggerRecordsSource& /*object*/);
+       
+       AliMUONMCDataInterface* fMCDataInterface; //! access to MUON MC-related data
+       AliMUONDataInterface* fDataInterface; //! access to MUON data
+       bool fBuildFromHits;  //! Flag indicating if trigger records should be built from GEANT hits.
+
+       enum SelectionType
+       {
+               kLeftPlane,  // everything from x < 0
+               kRightPlane, // everything from x >= 0
+               kWholePlane  // for all x
+       };
+
+       SelectionType fSelection; //! Indicates if we should publish from the left, right or whole XY plane.
+
+       ClassDef(AliHLTMUONTriggerRecordsSource, 0); // dHLT data source for trigger record data blocks.
+};
+
+#endif // ALIHLTMUONTRIGGERRECORDSSOURCE_H
index 303c8ab..6fa48f0 100644 (file)
 #include "AliHLTMUONCalculations.h"
 #include <cmath>
 
+AliHLTFloat32_t AliHLTMUONCalculations::fgZf = -975.0;
+AliHLTFloat32_t AliHLTMUONCalculations::fgQBL = 3.0;
+AliHLTMUONParticleSign AliHLTMUONCalculations::fgSign = kSignUnknown;
+AliHLTFloat32_t AliHLTMUONCalculations::fgPx = 0;
+AliHLTFloat32_t AliHLTMUONCalculations::fgPy = 0;
+AliHLTFloat32_t AliHLTMUONCalculations::fgPz = 0;
+
+
+bool AliHLTMUONCalculations::ComputeMomentum(
+               AliHLTFloat32_t x1,
+               AliHLTFloat32_t y1, AliHLTFloat32_t y2,
+               AliHLTFloat32_t z1, AliHLTFloat32_t z2
+       )
+{
+       AliHLTFloat64_t z2mz1 = z2 - z1;
+       if (z2mz1 == 0 or z1 == 0)
+       {
+               fgSign = kSignUnknown;
+               fgPx = fgPy = fgPz = 0;
+               return false;
+       }
+       AliHLTFloat64_t thetaTimesZf = (y1*z2 - y2*z1) / z2mz1;
+       AliHLTFloat64_t xf = x1 * fgZf / z1;
+       AliHLTFloat64_t yf = y2 - ((y2-y1) * (z2-fgZf)) / z2mz1;
+
+       if (thetaTimesZf == 0)
+       {
+               fgSign = kSignUnknown;
+               fgPx = fgPy = fgPz = 0;
+               return false;
+       }
+       // Note: 2.99792458e8/1e9 is the conversion factor for GeV.
+       // It is c/1e9, where c is the speed of light.
+       AliHLTFloat64_t pDivZf = (fgQBL * /*2.99792458e8/1e9*/0.3 / thetaTimesZf);
+       AliHLTFloat64_t p = pDivZf * fgZf;
+       pDivZf = fabs(pDivZf);
+       
+       if (p < 0)
+               fgSign = kSignMinus;
+       else if (p > 0)
+               fgSign = kSignPlus;
+       else
+               fgSign = kSignUnknown;
+       
+       fgPx = AliHLTFloat32_t( pDivZf * xf );
+       fgPy = AliHLTFloat32_t( pDivZf * yf );
+       fgPz = AliHLTFloat32_t( sqrt(p*p - fgPx*fgPx - fgPy*fgPy) );
+       // fgPz must be the same sign as fgZf else it could not have been measured.
+       if (fgZf < 0) fgPz = -fgPz;
+
+       return true;
+}
+
 
 AliHLTFloat32_t AliHLTMUONCalculateSignedPt(
                register AliHLTFloat32_t x1,
index bfba640..e774e26 100644 (file)
@@ -83,5 +83,41 @@ AliHLTFloat32_t AliHLTMUONCalculateSignedPt(
                register AliHLTFloat32_t zf, register AliHLTFloat32_t qBL,
                AliHLTFloat32_t& p
        );
+       
+       
+class AliHLTMUONCalculations
+{
+public:
+
+       static bool ComputeMomentum(
+                       AliHLTFloat32_t x1,
+                       AliHLTFloat32_t y1, AliHLTFloat32_t y2,
+                       AliHLTFloat32_t z1, AliHLTFloat32_t z2
+               );
+               
+       static AliHLTFloat32_t Zf() { return fgZf; }
+       static void Zf(AliHLTFloat32_t value) { fgZf = value; }
+       static AliHLTFloat32_t QBL() { return fgQBL; }
+       static void QBL(AliHLTFloat32_t value) { fgQBL = value; }
+       
+       static AliHLTMUONParticleSign Sign() { return fgSign; }
+       static AliHLTFloat32_t Px() { return fgPx; }
+       static AliHLTFloat32_t Py() { return fgPy; }
+       static AliHLTFloat32_t Pz() { return fgPz; }
+               
+private:
+
+       // Prevent destroying or creating of this object.
+       AliHLTMUONCalculations();
+       ~AliHLTMUONCalculations();
+
+       static AliHLTFloat32_t fgZf;  // The Z coordinate of the middle of the dipole magnetic field.
+       static AliHLTFloat32_t fgQBL; // The integrated field strength times unit charge (T.m.)
+       
+       static AliHLTMUONParticleSign fgSign;  // The calculated sign.
+       static AliHLTFloat32_t fgPx;  // The calculated X momentum.
+       static AliHLTFloat32_t fgPy;  // The calculated Y momentum.
+       static AliHLTFloat32_t fgPz;  // The calculated Z momentum.
+};
 
 #endif // ALIHLTMUONCALCULATIONS_H