HLT TRD on-line track matching and trigger (Felix Rettig, Stefan Kirsch)
authorjklein <jklein@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 3 Dec 2012 14:25:55 +0000 (14:25 +0000)
committerjklein <jklein@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 3 Dec 2012 14:25:55 +0000 (14:25 +0000)
- remove AliHLTTRDGlobalMonitorComponent
- replace AliHLTTRDMonitorComponent
- add AliTRDonlineTrackingDataContainer,
  AliHLTTRDPreprocessorComponent,
  AliHLTTRDTriggerComponent
- register trigger component in AliHLTTriggerAgent
- provide TRD trigger clean-up for electron triggers by
  rejecting fake tracks by matching with global tracks
- includes bug fixes for problems in test runs

16 files changed:
HLT/CMakelibAliHLTTRD.pkg
HLT/CMakelibAliHLTTrigger.pkg
HLT/TRD/AliHLTTRDAgent.cxx
HLT/TRD/AliHLTTRDDefinitions.cxx
HLT/TRD/AliHLTTRDDefinitions.h
HLT/TRD/AliHLTTRDGlobalMonitorComponent.cxx [deleted file]
HLT/TRD/AliHLTTRDGlobalMonitorComponent.h [deleted file]
HLT/TRD/AliHLTTRDMonitorComponent.cxx
HLT/TRD/AliHLTTRDMonitorComponent.h
HLT/TRD/AliHLTTRDPreprocessorComponent.cxx [new file with mode: 0644]
HLT/TRD/AliHLTTRDPreprocessorComponent.h [new file with mode: 0644]
HLT/TRD/AliTRDonlineTrackingDataContainer.cxx [new file with mode: 0644]
HLT/TRD/AliTRDonlineTrackingDataContainer.h [new file with mode: 0644]
HLT/trigger/AliHLTTRDTriggerComponent.cxx [new file with mode: 0644]
HLT/trigger/AliHLTTRDTriggerComponent.h [new file with mode: 0644]
HLT/trigger/AliHLTTriggerAgent.cxx

index d073e95..d018d15 100644 (file)
@@ -47,7 +47,8 @@ set ( CLASS_HDRS
     AliHLTTRDTrackHistoComponent.h
     AliHLTTRDHistoMergerComponent.h
     AliHLTTRDMonitorComponent.h
-    AliHLTTRDGlobalMonitorComponent.h
+    AliTRDonlineTrackingDataContainer.h
+    AliHLTTRDPreprocessorComponent.h
     )
 
 string (REPLACE ".h" ".cxx" MODULE_SRCS "${CLASS_HDRS}")
index c39fceb..a282871 100644 (file)
@@ -56,6 +56,7 @@ set ( CLASS_HDRS
     AliHLTTriggerCounters.h
     AliHLTTriggerCaloClusterEnergy.h
     AliHLTTriggerEmcalElectron.h       
+   AliHLTTRDTriggerComponent.h
 # uncomment if fastjet is installed
 #    AliHLTTriggerFastJet.h
 # ---------------------------------
index 7b83815..30456c7 100644 (file)
@@ -43,8 +43,8 @@ AliHLTTRDAgent gAliHLTTRDAgent;
 #include "AliHLTTRDHistoMergerComponent.h"
 #include "AliHLTTRDOfflineClusterizerComponent.h"
 #include "AliHLTTRDOfflineTrackerV1Component.h"
+#include "AliHLTTRDPreprocessorComponent.h"
 #include "AliHLTTRDMonitorComponent.h"
-#include "AliHLTTRDGlobalMonitorComponent.h"
 
 /** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTTRDAgent)
@@ -103,8 +103,8 @@ int AliHLTTRDAgent::RegisterComponents(AliHLTComponentHandler* pHandler) const
   pHandler->AddComponent(new AliHLTTRDHistoMergerComponent);
   pHandler->AddComponent(new AliHLTTRDOfflineClusterizerComponent);
   pHandler->AddComponent(new AliHLTTRDOfflineTrackerV1Component);
+  pHandler->AddComponent(new AliHLTTRDPreprocessorComponent);
   pHandler->AddComponent(new AliHLTTRDMonitorComponent);
-  pHandler->AddComponent(new AliHLTTRDGlobalMonitorComponent);
   return 0;
 }
 
index 658d337..ddb5ddc 100644 (file)
@@ -35,6 +35,8 @@ const AliHLTComponentDataType AliHLTTRDDefinitions::fgkHiLvlClusterDataType = {
 
 const AliHLTComponentDataType AliHLTTRDDefinitions::fgkTracksDataType = { sizeof(AliHLTComponentDataType), {'T','R','A','C','K','S','S','A'},{'T','R','D',' '}};;
 
+const AliHLTComponentDataType AliHLTTRDDefinitions::fgkOnlineDataType = { sizeof(AliHLTComponentDataType), {'T','R','A','C','K','D','A','T'},{'T','R','D',' '}};;
+
 const AliHLTComponentDataType AliHLTTRDDefinitions::fgkHiLvlTracksDataType = { sizeof(AliHLTComponentDataType), {'H','I','T','R','A','C','K','S'},{'T','R','D',' '}};;
 
 const AliHLTComponentDataType AliHLTTRDDefinitions::fgkMCMtrackletDataType = { sizeof(AliHLTComponentDataType), {'M','C','M','T','R','L','E','T'},{'T','R','D',' '}};;
index 729658b..22d89be 100644 (file)
@@ -3,7 +3,7 @@
 
 #ifndef ALIHLTTRDDEFINITIONS_H
 #define ALIHLTTRDDEFINITIONS_H
-//* This file is property of and copyright by the ALICE HLT Project        * 
+//* 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                               *
 
@@ -15,7 +15,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 //                                                                           //
-//  The HLT definitions for TRD                                              //  
+//  The HLT definitions for TRD                                              //
 //                                                                           //
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
@@ -27,22 +27,22 @@ class AliHLTTRDDefinitions
 public:
   AliHLTTRDDefinitions();
   virtual ~AliHLTTRDDefinitions();
-  
-  static const AliHLTComponentDataType fgkDigitsDataType;  // TRD digits 
+
+  static const AliHLTComponentDataType fgkDigitsDataType;  // TRD digits
   static const AliHLTComponentDataType fgkClusterDataType; // Cluster
   static const AliHLTComponentDataType fgkHiLvlClusterDataType; // Cluster for offline comparation
   static const AliHLTComponentDataType fgkTracksDataType; // Stand Alone tracks
+  static const AliHLTComponentDataType fgkOnlineDataType; // Online tracking data
   static const AliHLTComponentDataType fgkHiLvlTracksDataType; // Stand Alone tracks for offline comparation
   static const AliHLTComponentDataType fgkMCMtrackletDataType; // MCM tracklet Data
   static const AliHLTComponentDataType fgkMCMcalibrationDataType; // MCM Calibration data
   static const AliHLTComponentDataType fgkCalibrationDataType; // Calibration with TRDtracks
-  static const AliHLTComponentDataType fgkEORCalibrationDataType;//Calibration end of run 
+  static const AliHLTComponentDataType fgkEORCalibrationDataType;//Calibration end of run
 
   static const AliHLTComponentDataType fgkSimpleIntegerDataType;//Sample
 
   ClassDef(AliHLTTRDDefinitions, 0)
-    
+
 };
 
 #endif
-
diff --git a/HLT/TRD/AliHLTTRDGlobalMonitorComponent.cxx b/HLT/TRD/AliHLTTRDGlobalMonitorComponent.cxx
deleted file mode 100644 (file)
index 1fb9345..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-// $Id$
-//**************************************************************************
-//* This file is property of and copyright by the ALICE HLT Project        * 
-//* ALICE Experiment at CERN, All rights reserved.                         *
-//*                                                                        *
-//* Primary Authors: Felix Rettig, Stefan Kirsch                           *
-//*                  for The ALICE HLT Project.                            *
-//*                                                                        *
-//* Permission to use, copy, modify and distribute this software and its   *
-//* documentation strictly for non-commercial purposes is hereby granted   *
-//* without fee, provided that the above copyright notice appears in all   *
-//* copies and that both the copyright notice and this permission notice   *
-//* appear in the supporting documentation. The authors make no claims     *
-//* about the suitability of this software for any purpose. It is          *
-//* provided "as is" without express or implied warranty.                  *
-//**************************************************************************
-
-/// @file   AliHLTTRDGlobalMonitorComponent.cxx
-/// @author Felix Rettig, Stefan Kirsch
-/// @date   2011-08-02
-/// @brief  A processing component for TRD tracking/trigger data on CN-level
-///
-
-#include "AliHLTTRDGlobalMonitorComponent.h"
-#include "AliHLTDataTypes.h"
-#include "AliHLTTRDDefinitions.h"
-#include "TH1F.h"
-#include "TH1I.h"
-#include "TH2I.h"
-#include "TObjString.h"
-#include "TObjArray.h"
-
-#define TRDMODULES 18
-#define TRDMAXDDLSIZE 10000
-
-/** ROOT macro for the implementation of ROOT specific class methods */
-ClassImp(AliHLTTRDGlobalMonitorComponent)
-
-AliHLTTRDGlobalMonitorComponent::AliHLTTRDGlobalMonitorComponent()
-  :
-    fHistArray(NULL)
-  , fHistTrackletY(NULL)
-  , fHistTrackletDy(NULL)
-  , fHistTrackletZ(NULL)
-  , fHistTrackletPID(NULL)
-  , fHistTrackletYDy(NULL)
-  , fHistTrackletHC(NULL)
-  , fHistTrackletBadY(NULL)
-  , fHistTrackletBadPID(NULL)
-  , fHistFirstTrackletTime(NULL)
-  , fHistLastTrackletTime(NULL)
-  , fHistTmuTime(NULL)
-  , fHistSmuTime(NULL)
-  , fHistTrackPt(NULL)
-  , fHistTrackPID(NULL)
-  , fHistTrackStack(NULL)
-  , fHistTrackletsTrack(NULL)
-  , fHistTrackletsTrackHpt(NULL)
-  , fHistTriggerContribs(NULL)
-{
-  // see header file for class documentation
-  // or
-  // refer to README to build package
-  // or
-  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
-}
-
-AliHLTTRDGlobalMonitorComponent::~AliHLTTRDGlobalMonitorComponent()
-{
-  // see header file for class documentation
-}
-
-const char* AliHLTTRDGlobalMonitorComponent::GetComponentID()
-{
-  // see header file for class documentation
-  return "TRDGlobalMonitorComponent";
-}
-
-void AliHLTTRDGlobalMonitorComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
-{
-  // see header file for class documentation
-  // list.push_back(AliHLTTRDDefinitions::fgkSimpleIntegerDataType);
-  list.push_back(kAliHLTDataTypeTObject | kAliHLTDataOriginTRD);
-}
-
-AliHLTComponentDataType AliHLTTRDGlobalMonitorComponent::GetOutputDataType()
-{
-  // see header file for class documentation
-  return (kAliHLTDataTypeTObjArray | kAliHLTDataOriginTRD);
-}
-
-void AliHLTTRDGlobalMonitorComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
-{
-  // see header file for class documentation
-  constBase = 10000000;
-  inputMultiplier = 0;
-}
-
-AliHLTComponent* AliHLTTRDGlobalMonitorComponent::Spawn()
-{
-  // see header file for class documentation
-  return new AliHLTTRDGlobalMonitorComponent;
-}
-
-int AliHLTTRDGlobalMonitorComponent::DoInit( int /*argc*/, const char** /*argv*/ )
-{
-  fHistArray = new TObjArray(25);
-  if(!fHistArray)
-    return -ENOMEM;
-  fHistArray->SetOwner(kTRUE);
-
-  fHistTrackletY = new TH1I("hist_tracklets_y", "Y-Position of online tracklets", 256, -4096, 4096);
-  fHistArray->AddLast(fHistTrackletY);
-
-  fHistTrackletDy = new TH1I("hist_tracklets_dy", "Deflections of online tracklets", 128, -64, 64);
-  fHistArray->AddLast(fHistTrackletDy);
-
-  fHistTrackletZ = new TH1I("hist_tracklets_z", "Z-Position of online tracklets", 12, 0, 12);
-  fHistArray->AddLast(fHistTrackletZ);
-
-  fHistTrackletPID = new TH1I("hist_tracklets_pid", "PID of online tracklets", 256, 0, 256);
-  fHistArray->AddLast(fHistTrackletPID);
-
-  fHistTrackletYDy = new TH2I("hist_tracklets_y_dy", "Tracklet deflection vs. tracklet position", 256, -4096, 4096, 64, -64, 64);
-  fHistArray->AddLast(fHistTrackletYDy);
-
-  fHistTrackletHC = new TH2I("hist_tracklets_hc", "Number of online tracklets by HC", 18, 0, 18, 60, 0, 60);
-  fHistArray->AddLast(fHistTrackletHC);
-
-  fHistTrackletBadY = new TH2I("hist_tracklets_bad_y", "Number of online tracklets with bad y-position by stack", 18, 0, 18, 5, 0, 5);
-  fHistArray->AddLast(fHistTrackletBadY);
-
-  fHistTrackletBadPID = new TH2I("hist_tracklets_bad_pid", "Number of online tracklets with bad PID value by stack", 18, 0, 18, 5, 0, 5);
-  fHistArray->AddLast(fHistTrackletBadPID);
-
-  fHistFirstTrackletTime = new TH1F("hist_first_tracklet_time", "Arrival time of first tracklet", 160, 0., 8.);
-  fHistArray->AddLast(fHistFirstTrackletTime);
-
-  fHistLastTrackletTime = new TH1F("hist_last_tracklet_time", "Arrival time of last tracklet", 160, 0., 8.);
-  fHistArray->AddLast(fHistLastTrackletTime);
-
-  fHistTmuTime = new TH1F("hist_tmu_time", "Tracking done time TMU-level", 160, 0., 8.);
-  fHistArray->AddLast(fHistTmuTime);
-
-  fHistSmuTime = new TH1F("hist_smu_time", "Tracking done time SMU-level", 160, 0., 8.);
-  fHistArray->AddLast(fHistSmuTime);
-
-  fHistTrackPt = new TH1F("hist_tracks_pt", "Transverse momentum of GTU  tracks", 100, 0., 20.);
-  fHistArray->AddLast(fHistTrackPt);
-
-  fHistTrackPID = new TH1I("hist_tracks_pid", "PID value of GTU  tracks", 256, 0, 256);
-  fHistArray->AddLast(fHistTrackPID);
-
-  fHistTrackStack = new TH2I("hist_tracks_stack", "Number of GTU tracks by stack", 18, 0, 18, 5, 0, 5);
-  fHistArray->AddLast(fHistTrackStack);
-
-  fHistTrackletsTrack = new TH1I("hist_tracklets_track", "Tracklets per GTU track", 7, 0, 7);
-  fHistArray->AddLast(fHistTrackletsTrack);
-
-  fHistTrackletsTrackHpt = new TH1I("hist_tracklets_track_hpt", "Tracklets per high-pt GTU track", 7, 0, 7);
-  fHistArray->AddLast(fHistTrackletsTrackHpt);
-
-  fHistTriggerContribs = new TH2I("hist_trigger_contribs", "Trigger contributions by segment", 18, 0, 18, 12, 0, 12);
-  fHistArray->AddLast(fHistTriggerContribs);
-
-  return 0;
-}
-
-int AliHLTTRDGlobalMonitorComponent::DoDeinit()
-{
-  if(fHistArray){
-    fHistArray->Clear();
-    delete fHistArray;
-    fHistArray=NULL;
-  }
-  return 0;
-}
-
-int AliHLTTRDGlobalMonitorComponent::DoEvent( const AliHLTComponentEventData& /*evtData*/, AliHLTComponentTriggerData& /*trigData*/)
-{
-  int iResult=0;
-  //  Int_t totaleventsize=0;
-
-  /*
-  //Loop over integers
-  for (const AliHLTComponentBlockData* pBlock = GetFirstInputBlock(AliHLTTRDDefinitions::fgkSimpleIntegerDataType);
-       pBlock!=NULL && iResult>=0;
-       pBlock=GetNextInputBlock()) {
-    // extract DDL id from specification
-    int ddlnum=-1;
-    for (unsigned pos=0; pos<8*sizeof(AliHLTUInt32_t); pos++) {
-      if (pBlock->fSpecification & (0x1<<pos)) {
-       if (ddlnum>=0) {
-         HLTWarning("Can not uniquely identify DDL number from specification, skipping data block %s 0x%08x",
-                    DataType2Text(pBlock->fDataType).c_str(),
-                    pBlock->fSpecification);
-         ddlnum=-1;
-         break;
-       }
-       ddlnum=pos;
-      }
-    }
-    if (ddlnum<0 || ddlnum >= TRDMODULES) continue;
-
-    if ( pBlock->fSize < sizeof(Int_t) ) {
-      HLTWarning("block size (%d) smaller than expected size (%d)!", pBlock->fSize, sizeof(Int_t) );
-      continue;
-    } 
-
-    Int_t* eventsize = (Int_t *) pBlock->fPtr;
-    if(*eventsize > TRDMAXDDLSIZE)
-      HLTWarning("eventsize (%d) larger than histogram range (%d)", *eventsize, TRDMAXDDLSIZE);
-    // Fill histo of ddl
-    TH1F* h = dynamic_cast<TH1F*>(fHistoArray->At(ddlnum));
-    h->Fill((Double_t)*eventsize);
-
-    totaleventsize += *eventsize;
-  }
-  */
-
-  // reset the high-level histograms, the accumulation over events is done in the lower level
-  fHistTrackletY->Reset();
-  fHistTrackletDy->Reset();
-  fHistTrackletZ->Reset();
-  fHistTrackletPID->Reset();
-  fHistTrackletYDy->Reset();
-  fHistTrackletHC->Reset();
-  fHistTrackletBadY->Reset();
-  fHistTrackletBadPID->Reset();
-  fHistFirstTrackletTime->Reset();
-  fHistLastTrackletTime->Reset();
-  fHistTmuTime->Reset();
-  fHistSmuTime->Reset();
-  fHistTrackPt->Reset();
-  fHistTrackPID->Reset();
-  fHistTrackStack->Reset();
-  fHistTrackletsTrack->Reset();
-  fHistTrackletsTrackHpt->Reset();
-  fHistTriggerContribs->Reset();
-
-  // loop over TObject-based input data
-  for (const TObject* obj = 
-        GetFirstInputObject(kAliHLTDataTypeTObject | kAliHLTDataOriginTRD, "TObjArray");
-       obj!=NULL && iResult>=0;
-       obj=GetNextInputObject()) {
-    // extract DDL id from specification
-    int ddlnum=-1;
-    AliHLTUInt32_t specification = GetSpecification(obj);
-    for (unsigned pos=0; pos<8*sizeof(AliHLTUInt32_t); pos++) {
-      if (specification & (0x1<<pos)) {
-        if (ddlnum>=0) {
-          HLTWarning("Can not uniquely identify DDL number from specification, skipping data block %s 0x%08x",
-                    DataType2Text(GetDataType(obj)).c_str(),
-                    specification);
-          ddlnum=-1;
-          break;
-        }
-             ddlnum=pos;
-      }
-    }
-    if (ddlnum<0 || ddlnum >= TRDMODULES) continue;
-    
-    // input object is a TObjArray containing the actual data containers
-    const TObjArray* histArray = dynamic_cast<const TObjArray*>(obj);
-    if (!histArray){
-      HLTWarning("Received object was not a TObjAarray");
-      continue;
-    }
-
-    // extract data containers and process the data
-
-    TH1I *hist1 = (TH1I*)histArray->FindObject("hist_tracklets_y");
-    if (hist1){
-      fHistTrackletY->Add(hist1);
-    } else
-      HLTWarning("Tracklet y-position histogram not found!");
-
-    hist1 = (TH1I*)histArray->FindObject("hist_tracklets_dy");
-    if (hist1){
-      fHistTrackletDy->Add(hist1);
-    } else
-      HLTWarning("Tracklet deflection histogram not found!");
-
-    hist1 = (TH1I*)histArray->FindObject("hist_tracklets_z");
-    if (hist1){
-      fHistTrackletZ->Add(hist1);
-    } else
-      HLTWarning("Tracklet z-position histogram not found!");
-
-    hist1 = (TH1I*)histArray->FindObject("hist_tracklets_pid");
-    if (hist1){
-      fHistTrackletPID->Add(hist1);
-    } else
-      HLTWarning("Tracklet PID histogram not found!");
-
-    TH2I *hist2 = (TH2I*)histArray->FindObject("hist_tracklets_y_dy");
-    if (hist2){
-      fHistTrackletYDy->Add(hist2);
-    } else
-      HLTWarning("Tracklet y vs. dy histogram not found!");
-
-    hist2 = (TH2I*)histArray->FindObject("hist_tracklets_hc");
-    if (hist2){
-      fHistTrackletHC->Add(hist2);
-    } else
-      HLTWarning("Tracklet number histogram not found!");
-
-    hist2 = (TH2I*)histArray->FindObject("hist_tracklets_bad_y");
-    if (hist2){
-      fHistTrackletBadY->Add(hist2);
-    } else
-      HLTWarning("Tracklet number with bad y-position histogram not found!");
-
-    hist2 = (TH2I*)histArray->FindObject("hist_tracklets_bad_pid");
-    if (hist2){
-      fHistTrackletBadPID->Add(hist2);
-    } else
-      HLTWarning("Tracklet number with bad y-position histogram not found!");
-
-    TH1F *hist3 = (TH1F*)histArray->FindObject("hist_first_tracklet_time");
-    if (hist3){
-      fHistFirstTrackletTime->Add(hist3);
-    } else
-      HLTWarning("First tracklet arrival  histogram not found!");
-
-    hist3 = (TH1F*)histArray->FindObject("hist_last_tracklet_time");
-    if (hist3){
-      fHistLastTrackletTime->Add(hist3);
-    } else
-      HLTWarning("Last tracklet arrival time histogram not found!");
-
-    hist3 = (TH1F*)histArray->FindObject("hist_tmu_time");
-    if (hist3){
-      fHistTmuTime->Add(hist3);
-    } else
-      HLTWarning("TMU-level tracking done time histogram not found!");
-
-    hist3 = (TH1F*)histArray->FindObject("hist_smu_time");
-    if (hist3){
-      fHistSmuTime->Add(hist3);
-    } else
-      HLTWarning("SMU-level tracking done time histogram not found!");
-
-    hist3 = (TH1F*)histArray->FindObject("hist_tracks_pt");
-    if (hist3){
-      fHistTrackPt->Add(hist3);
-    } else
-      HLTWarning("Track pt histogram not found!");
-
-    hist1 = (TH1I*)histArray->FindObject("hist_tracks_pid");
-    if (hist1){
-      fHistTrackPID->Add(hist1);
-    } else
-      HLTWarning("Tracklet PID histogram not found!");
-
-    hist2 = (TH2I*)histArray->FindObject("hist_tracks_stack");
-    if (hist2){
-      fHistTrackStack->Add(hist2);
-    } else
-      HLTWarning("Track number histogram not found!");
-
-    hist1 = (TH1I*)histArray->FindObject("hist_tracklets_track");
-    if (hist1){
-      fHistTrackletsTrack->Add(hist1);
-    } else
-      HLTWarning("Tracklets per GTU track histogram not found!");
-
-    hist1 = (TH1I*)histArray->FindObject("hist_tracklets_track_hpt");
-    if (hist1){
-      fHistTrackletsTrackHpt->Add(hist1);
-    } else
-      HLTWarning("Tracklets per high-pt GTU track histogram not found!");
-
-    hist2 = (TH2I*)histArray->FindObject("hist_trigger_contribs");
-    if (hist2){
-      fHistTriggerContribs->Add(hist2);
-    } else
-      HLTWarning("Trigger contribution histogram not found!");
-
-  }
-
-  iResult = PushBack(fHistArray, 
-                    (kAliHLTDataTypeTObjArray | kAliHLTDataOriginTRD), 
-                    //Specification: all 18 bits (links) set
-                    (0xFFFFFFFF >> (32 - TRDMODULES) )
-                    );
-                      
-  return iResult;
-}
-
-int AliHLTTRDGlobalMonitorComponent::Configure(const char* /*arguments*/)
-{
-  // see header file for class documentation
-  int iResult=0;
-
-  return iResult;
-}
-
-int AliHLTTRDGlobalMonitorComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
-{
-  // see header file for class documentation
-  int iResult=0;
-
-  return iResult;
-}
diff --git a/HLT/TRD/AliHLTTRDGlobalMonitorComponent.h b/HLT/TRD/AliHLTTRDGlobalMonitorComponent.h
deleted file mode 100644 (file)
index 54da1e3..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-//-*- Mode: C++ -*-
-// $Id$
-#ifndef ALIHLTTRDGLOBALMONITORCOMPONENT_H
-#define ALIHLTTRDGLOBALMONITORCOMPONENT_H
-
-//* This file is property of and copyright by the ALICE HLT Project        * 
-//* ALICE Experiment at CERN, All rights reserved.                         *
-//* See cxx source for full Copyright notice                               */
-
-/// @file   AliHLTTRDGlobalMonitorComponent.h
-/// @author Felix Rettig, Stefan Kirsch
-/// @date   2011-08-02
-/// @brief  A processing component for TRD tracking/trigger data on CN-level
-/// @ingroup alihlt_trd_components
-
-#include "AliHLTProcessor.h"
-
-class TObjArray;
-class TH1I;
-class TH2I;
-class TH1F;
-
-class AliHLTTRDGlobalMonitorComponent : public AliHLTProcessor {
-public:
-  AliHLTTRDGlobalMonitorComponent();
-  virtual ~AliHLTTRDGlobalMonitorComponent();
-
-  // AliHLTComponent interface functions
-  const char* GetComponentID();
-  void GetInputDataTypes( vector<AliHLTComponentDataType>& list);
-  AliHLTComponentDataType GetOutputDataType();
-  void GetOutputDataSize( unsigned long& constBase, double& inputMultiplier );
-  AliHLTComponent* Spawn();
-
- protected:
-  // AliHLTComponent interface functions
-  int DoInit( int argc, const char** argv );
-  int DoDeinit();
-  int DoEvent( const AliHLTComponentEventData& evtData, AliHLTComponentTriggerData& trigData);
-  int Reconfigure(const char* cdbEntry, const char* chainId);
-
-  using AliHLTProcessor::DoEvent;
-
-private:
-  /** copy constructor prohibited */
-  AliHLTTRDGlobalMonitorComponent(const AliHLTTRDGlobalMonitorComponent&);
-  /** assignment operator prohibited */
-  AliHLTTRDGlobalMonitorComponent& operator=(const AliHLTTRDGlobalMonitorComponent&);
-
-  int Configure(const char* arguments);
-
-  /** data **/
-  TObjArray* fHistArray;
-  TH1I *fHistTrackletY;   // tracklet y-positions from all stacks
-  TH1I *fHistTrackletDy;  // tracklet deflections from all stacks
-  TH1I *fHistTrackletZ;   // tracklet z-positions from all stacks
-  TH1I *fHistTrackletPID; // tracklet PID values from all stacks
-  TH2I *fHistTrackletYDy; // tracklet deflection vs. position from all stacks
-  TH2I *fHistTrackletHC;  // tracklet numbers by half-chamber from all stacks
-  TH2I *fHistTrackletBadY; // tracklet numbers with invalid y-position by stack from all stacks
-  TH2I *fHistTrackletBadPID; // tracklet numbers with invalid PID value by stack from all stacks
-  TH1F *fHistFirstTrackletTime; // arrival time of the first tracklet of each link
-  TH1F *fHistLastTrackletTime; // arrival time of the last tracklet of each link
-  TH1F *fHistTmuTime;     // tracking done time for each TMU
-  TH1F *fHistSmuTime;     // tracking done time for each SMU
-  TH1F *fHistTrackPt;     // transverse momentum of GTU tracks from all stacks
-  TH1I *fHistTrackPID;    // PID of GTU tracks from all stacks
-  TH2I *fHistTrackStack;  // GTU track numbers by stack from all stacks
-  TH1I *fHistTrackletsTrack; // tracklets per GTU track from all stacks
-  TH1I *fHistTrackletsTrackHpt; // tracklets per high-pt GTU track from all stacks
-  TH2I *fHistTriggerContribs; // sector-level trigger contributions from all stacks
-  ClassDef(AliHLTTRDGlobalMonitorComponent, 0)
-};
-#endif
index 14e691f..ab6220a 100644 (file)
@@ -1,8 +1,10 @@
 // $Id$
 //**************************************************************************
-//* This file is property of and copyright by the ALICE HLT Project        * 
+//* This file is property of and copyright by the ALICE HLT Project        *
 //* ALICE Experiment at CERN, All rights reserved.                         *
 //*                                                                        *
+//* Primary Authors: Felix Rettig, Stefan Kirsch                           *
+//*                  for The ALICE HLT Project.                            *
 //*                                                                        *
 //* Permission to use, copy, modify and distribute this software and its   *
 //* documentation strictly for non-commercial purposes is hereby granted   *
 
 /// @file   AliHLTTRDMonitorComponent.cxx
 /// @author Felix Rettig, Stefan Kirsch
-/// @date   2011-08-02
-/// @brief  A processing component for TRD tracking/trigger data on FEP-level
-/// @ingroup alihlt_trd_components
-
-#include "AliHLTTRDMonitorComponent.h"
-#include "AliLog.h"
-#include "AliHLTDataTypes.h"
-#include "AliRawReaderMemory.h"
-#include "AliHLTTRDDefinitions.h"
-
-#include "AliTRDdigitsManager.h"
-#include "AliTRDrawStream.h"
-#include "AliTRDtrackletWord.h"
-#include "AliESDTrdTracklet.h"
-#include "AliESDTrdTrack.h"
+/// @date   2012-08-16
+/// @brief  The TRD monitoring component
+///
 
+#include <cstdlib>
 #include "TH1I.h"
 #include "TH2I.h"
-#include "TH1F.h"
+#include "TH2F.h"
+#include "TObjString.h"
+#include "TObjArray.h"
+#include "TClonesArray.h"
+#include "TFile.h"
+#include "AliESDtrack.h"
+#include "AliHLTDataTypes.h"
+#include "AliHLTTRDDefinitions.h"
+#include "AliHLTLogging.h"
+#include "AliHLTTRDMonitorComponent.h"
+#include "AliTRDonlineTrackingDataContainer.h"
 
+#define TRDMODULES 18
 
-/** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTTRDMonitorComponent)
 
-AliHLTTRDMonitorComponent::AliHLTTRDMonitorComponent()
-  : AliHLTProcessor()
-  , fTrackletArray(NULL)
-  , fGtuTrackArray(NULL)
-  , fRawReaderMem(NULL)
-  , fDigitsManagerTrd(NULL)
-  , fRawReaderTrd(NULL)
-  , fHistArray(NULL)
-  , fHistTrackletY(NULL)
-  , fHistTrackletDy(NULL)
-  , fHistTrackletZ(NULL)
-  , fHistTrackletPID(NULL)
-  , fHistTrackletYDy(NULL)
-  , fHistTrackletHC(NULL)
-  , fHistTrackletBadY(NULL)
-  , fHistTrackletBadPID(NULL)
-  , fHistFirstTrackletTime(NULL)
-  , fHistLastTrackletTime(NULL)
-  , fHistTmuTime(NULL)
-  , fHistSmuTime(NULL)
-  , fHistTrackPt(NULL)
-  , fHistTrackStack(NULL)
-  , fHistTrackletsTrack(NULL)
-  , fHistTrackletsTrackHpt(NULL)
-  , fHistTrackPID(NULL)
-  , fHistTriggerContribs(NULL)
+#define LogError( ... ) { HLTError(__VA_ARGS__); if (fDebugLevel >= 1) { DbgLog("ERROR", __VA_ARGS__); } }
+#define LogInfo( ... ) { HLTInfo(__VA_ARGS__); if (fDebugLevel >= 1) { DbgLog("INFO", __VA_ARGS__); } }
+#define LogInspect( ... ) { HLTDebug(__VA_ARGS__); if (fDebugLevel >= 1) { DbgLog("INSPECT", __VA_ARGS__); } }
+#define LogDebug( ... ) { if (fDebugLevel >= 1) { HLTInfo(__VA_ARGS__); DbgLog("DEBUG", __VA_ARGS__); } }
+
+AliHLTTRDMonitorComponent::AliHLTTRDMonitorComponent() : AliHLTProcessor(),
+  fTrackHighPtThreshold(2.3),
+  fHistoMode(1),
+  fTrackingDataDebugOutput(kFALSE),
+  fDebugLevel(0),
+  fWriteHistos(kFALSE),
+  fEventId(fgkInvalidEventId),
+  fTrackingData(NULL),
+  fHistArray(NULL),
+  fHistEventTypes(NULL),
+  fHistTrackletY(NULL),
+  fHistTrackletDy(NULL),
+  fHistTrackletYDy(NULL),
+  fHistTrackletZ(NULL),
+  fHistTrackletPID(NULL),
+  fHistTrackletsHCId(NULL),
+  fHistTrackPt(NULL),
+  fHistTrackPID(NULL),
+  fHistTrackLayers(NULL),
+  fHistTrackLayersHighPt(NULL),
+  fHistTracksStack(NULL),
+  fHistTrackletTimingStack(NULL),
+  fHistTrackingTiming(NULL),
+  fHistTriggerContribs(NULL)
 {
-  // constructor
 }
 
-AliHLTTRDMonitorComponent::~AliHLTTRDMonitorComponent()
-{
-  // destructor
+AliHLTTRDMonitorComponent::~AliHLTTRDMonitorComponent() {
 }
 
-const char* AliHLTTRDMonitorComponent::GetComponentID()
-{ 
-  // component property: id
+const char* AliHLTTRDMonitorComponent::GetComponentID() {
   return "TRDMonitorComponent";
 }
 
-void AliHLTTRDMonitorComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
-{
-  // component property: list of input data types
-  list.push_back(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTRD);
+void AliHLTTRDMonitorComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list) {
+  list.push_back(kAliHLTDataTypeTObject | kAliHLTDataOriginTRD);
 }
 
-AliHLTComponentDataType AliHLTTRDMonitorComponent::GetOutputDataType()
-{
-  // component property: output data type
-  return kAliHLTMultipleDataType;
+AliHLTComponentDataType AliHLTTRDMonitorComponent::GetOutputDataType() {
+  return (kAliHLTDataTypeTObjArray | kAliHLTDataOriginTRD);
 }
 
-int AliHLTTRDMonitorComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
-
-{
-  // see header file for class documentation
-  tgtList.clear();
-  //  tgtList.push_back(AliHLTTRDDefinitions::fgkSimpleIntegerDataType);
-  tgtList.push_back(kAliHLTDataTypeTObject | kAliHLTDataOriginTRD);
-  return tgtList.size();
-}
-
-void AliHLTTRDMonitorComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
-{
-  // component property: output size estimator
-  constBase = 5000000;
+void AliHLTTRDMonitorComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) {
+  constBase = 10000000;
   inputMultiplier = 0;
 }
 
-void AliHLTTRDMonitorComponent::GetOCDBObjectDescription( TMap* const /*targetMap*/)
-{
-  // Get a list of OCDB object description.
-  // The list of objects is provided in a TMap
-  // - key: complete OCDB path, e.g. GRP/GRP/Data
-  // - value: short description why the object is needed
-  // Key and value objects created inside this class go into ownership of
-  // target TMap.
-  //if (!targetMap) return;
-  //targetMap->Add(new TObjString("HLT/ConfigSample/SampleRawAnalysis"),
-  //               new TObjString("configuration object"));
-}
-
-AliHLTComponent* AliHLTTRDMonitorComponent::Spawn()
-{
-  // Spawn function, return new class instance
+AliHLTComponent* AliHLTTRDMonitorComponent::Spawn() {
   return new AliHLTTRDMonitorComponent;
 }
 
-int AliHLTTRDMonitorComponent::DoInit( int /*argc*/, const char** /*argv*/ )
-{
-
-  int iResult=0;
+int AliHLTTRDMonitorComponent::Configure(const char* /*arguments*/) {
+  return 0;
+}
 
-  // init stage 1: default values for all data members
+int AliHLTTRDMonitorComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/) {
+  return 0;
+}
 
-  // init stage 2: read configuration object
-  // ScanConfigurationArgument() needs to be implemented
-  // HLT component configuration objects are located in the HLT/ConfigDET
-  // of the OCDB. TObjString configuration objects can be generated with
-  // the macro HLT/exa/makeComponentConfigurationObject.C, e.g.
-  // aliroot -b -q -l $ALICE_ROOT/HLT/exa/makeComponentConfigurationObject.C'("HLT/ConfigSample/SampleRawAnalysis", "")'
-  //TString cdbPath="HLT/ConfigSample/";
-  //cdbPath+=GetComponentID();
-  //iResult=ConfigureFromCDBTObjString(cdbPath);
+int AliHLTTRDMonitorComponent::DoInit(int argc, const char** argv) {
 
-  // init stage 3: read the component arguments
-  //if (iResult>=0) {
-  //  iResult=ConfigureFromArgumentString(argc, argv);
-  //}
+  int iResult = 0;
 
-  // implement the component initialization
-  // Matthias 2011-08-24: this has to go into ScanConfigurationArgument
   do {
 
-    fRawReaderMem = new AliRawReaderMemory; 
-    if (!fRawReaderMem) {
-      iResult=-ENOMEM;
-      break;
-    }
-
-    fTrackletArray = new TClonesArray("AliTRDtrackletWord", 500);
-    if (!fTrackletArray) {
-      iResult=-ENOMEM;
-      break;
-    }
-
-    fGtuTrackArray = new TClonesArray("AliESDTrdTrack", 50);
-    if (!fGtuTrackArray){
-      iResult=-ENOMEM;
-      break;
-    }
-
-    fDigitsManagerTrd = new AliTRDdigitsManager();
-    if (!fDigitsManagerTrd) {
-      iResult=-ENOMEM;
-      break;
-    }
-    fDigitsManagerTrd->CreateArrays();
-
-    fRawReaderTrd = new AliTRDrawStream(fRawReaderMem);
-    if (!fRawReaderTrd) {
-      iResult=-ENOMEM;
+    fTrackingData = new AliTRDonlineTrackingDataContainer();
+    fTrackingData->SetGtuPtMultiplier(-1.); // this component does not know about the B-field direction
+    if (!fTrackingData) {
+      iResult = -ENOMEM;
       break;
     }
 
-    fRawReaderTrd->SetDigitsManager(fDigitsManagerTrd);
-    // fRawReaderTrd->SetDigitsManager(NULL);  // FIXME may be used to improve performance, needs a fix to be committed by TRD
-    fRawReaderTrd->SetTrackletArray(fTrackletArray);
-    fRawReaderTrd->SetTrackArray(fGtuTrackArray);
-  
-    // Disable raw reader error messages that could flood HLT logbook
-    fRawReaderTrd->SetErrorDebugLevel( AliTRDrawStream::kLinkMonitor, 1 );
-
     fHistArray = new TObjArray(25);
-    if(!fHistArray){
+    if(!fHistArray)
       return -ENOMEM;
-      break;
-    }
     fHistArray->SetOwner(kTRUE);
 
-    fHistTrackletY = new TH1I("hist_tracklets_y", "Y-Position of online tracklets", 256, -4096, 4096);
-    if (!fHistTrackletY){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTrackletY);
-
-    fHistTrackletDy = new TH1I("hist_tracklets_dy", "Deflection of online tracklets", 128, -64, 64);
-    if (!fHistTrackletDy){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTrackletDy);
+  } while (0);
 
-    fHistTrackletZ = new TH1I("hist_tracklets_z", "Z-Position of online tracklets", 12, 0, 12);
-    if (!fHistTrackletZ){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTrackletZ);
+  if (iResult < 0){
 
-    fHistTrackletPID = new TH1I("hist_tracklets_pid", "PID of online tracklets", 256, 0, 256);
-    if (!fHistTrackletPID){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTrackletPID);
+    if (fHistArray) delete fHistArray;
+    fHistArray = NULL;
 
-    fHistTrackletYDy = new TH2I("hist_tracklets_y_dy", "Tracklet deflection vs. tracklet position", 256, -4096, 4096, 64, -64, 64);
-    if (!fHistTrackletYDy){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTrackletYDy);
+    if (fTrackingData) delete fTrackingData;
+    fTrackingData = NULL;
 
-    fHistTrackletHC = new TH2I("hist_tracklets_hc", "Number of online tracklets by HC", 18, 0, 18, 60, 0, 60);
-    if (!fHistTrackletHC){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTrackletHC);
+  }
 
-    fHistTrackletBadY = new TH2I("hist_tracklets_bad_y", "Number of online tracklets with bad y-position by HC", 18, 0, 18, 5, 0, 5);
-    if (!fHistTrackletBadY){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTrackletBadY);
+  fHistEventTypes = new TH1I("trdmon_event_types", "event types analysed;event type;abundance", 10, 0, 10);
+  fHistEventTypes->GetXaxis()->SetBinLabel(1, "any");
+  fHistEventTypes->GetXaxis()->SetBinLabel(2, "data");
+  fHistEventTypes->GetXaxis()->SetBinLabel(3, "track(lets) present");
+  fHistArray->AddLast(fHistEventTypes);
 
-    fHistTrackletBadPID = new TH2I("hist_tracklets_bad_pid", "Number of online tracklets with bad y-position by HC", 18, 0, 18, 5, 0, 5);
-    if (!fHistTrackletBadPID){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTrackletBadPID);
+  fHistTrackletY = new TH1I("trdmon_tracklet_y", "tracklet y-position;y (cm);abundance", 125, -75, 75);
+  fHistArray->AddLast(fHistTrackletY);
 
-    fHistFirstTrackletTime = new TH1F("hist_first_tracklet_time", "Arrival time of first tracklet", 160, 0., 8.);
-    if (!fHistFirstTrackletTime){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistFirstTrackletTime);
+  fHistTrackletDy = new TH1I("trdmon_tracklet_dy", "tracklet deflection;#Delta y (140 #mu m);abundance", 140, -70, 70);
+  fHistArray->AddLast(fHistTrackletDy);
 
-    fHistLastTrackletTime = new TH1F("hist_last_tracklet_time", "Arrival time of last tracklet", 160, 0., 8.);
-    if (!fHistLastTrackletTime){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistLastTrackletTime);
+  fHistTrackletYDy = new TH2I("trdmon_tracklet_y_dy", "tracklet y-deflection vs. y-position;y (160 #mu m);#Delta y (140 #mu m);", 256, -4096, 4096, 140, -70, 70);
+  fHistArray->AddLast(fHistTrackletYDy);
 
-    fHistTmuTime = new TH1F("hist_tmu_time", "Tracking done time at TMU-level", 160, 0., 8.);
-    if (!fHistTmuTime){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTmuTime);
+  fHistTrackletZ = new TH1I("trdmon_tracklet_z", "tracklet z-position;z (padrow);abundance", 16, 0, 16);
+  fHistArray->AddLast(fHistTrackletZ);
 
-    fHistSmuTime = new TH1F("hist_smu_time", "Tracking done time at SMU-level", 160, 0., 8.);
-    if (!fHistSmuTime){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistSmuTime);
+  fHistTrackletPID = new TH1I("trdmon_tracklet_pid", "tracklet PID;PID (a.u.);abundance", 256, 0, 256);
+  fHistArray->AddLast(fHistTrackletPID);
 
-    fHistTrackPt = new TH1F("hist_tracks_pt", "Transverse momentum of GTU tracks", 100, 0., 20.);
-    if (!fHistTrackPt){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTrackPt);
+  fHistTrackletsHCId = new TH2F("trdmon_tracklets_hc", "tracklet number by HC;TRD sector;TRD half-chamber",
+                               18, 0, 18, 60, 0, 60);
+  fHistArray->AddLast(fHistTrackletsHCId);
 
-    fHistTrackPID = new TH1I("hist_tracks_pid", "PID of online tracks", 256, 0, 256);
-    if (!fHistTrackPID){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTrackPID);
+  fHistTrackletTimingStack = new TH2I("trdmon_tracklet_timing_stack", "tracklet timing;TRD stack; time after L0 (us)",
+                                      90, 0., 90, 270, 0., 9.);
+  fHistArray->AddLast(fHistTrackletTimingStack);
 
-    fHistTrackStack = new TH2I("hist_tracks_stack", "Number of GTU tracks by stack", 18, 0, 18, 5, 0, 5);
-    if (!fHistTrackStack){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTrackStack);
+  fHistTrackPt = new TH1I("trdmon_track_pt", "p_{T} of TRD online tracks;p_{T}^{TRD, online} (GeV/c);abundance", 200, -20, 20.);
+  fHistArray->AddLast(fHistTrackPt);
 
-    fHistTrackletsTrack = new TH1I("hist_tracklets_track", "Tracklets per GTU track", 7, 0, 7);
-    if (!fHistTrackletsTrack){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTrackletsTrack);
+  fHistTrackPID = new TH1I("trdmon_track_pid", "PID of TRD online tracks;PID^{TRD, online} (a.u.);abundance", 256, 0, 256);
+  fHistArray->AddLast(fHistTrackPID);
 
-    fHistTrackletsTrackHpt = new TH1I("hist_tracklets_track_hpt", "Tracklets per high-pt GTU track", 7, 0, 7);
-    if (!fHistTrackletsTrackHpt){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTrackletsTrackHpt);
+  fHistTrackLayers = new TH1I("trdmon_track_layers", "contributing layers to TRD online tracks;contributing layers;abundance", 7, 0, 7);
+  fHistArray->AddLast(fHistTrackLayers);
 
-    fHistTriggerContribs = new TH2I("hist_trigger_contribs", "Trigger contributions by segment", 18, 0, 18, 12, 0, 12);
-    if (!fHistTriggerContribs){
-      return -ENOMEM;
-      break;
-    }
-    fHistArray->AddLast(fHistTriggerContribs);
+  fHistTrackLayersHighPt = new TH1I("trdmon_track_layers_hpt", "contributing layers to TRD online tracks;contributing layers;abundance", 7, 0, 7);
+  fHistArray->AddLast(fHistTrackLayersHighPt);
 
-  } while (0);
+  fHistTracksStack = new TH2F("trdmon_tracks_stack", "tracks by stack;TRD sector;TRD stack",
+                               18, 0, 18, 5, 0, 5);
+  fHistArray->AddLast(fHistTracksStack);
 
-  if (iResult<0) {
-    // implement cleanup
-    if (fRawReaderMem) delete fRawReaderMem;
-    fRawReaderMem=NULL;
+  const Double_t trackingTimesTimeBin = 0.025; // us
+  const Double_t trackingTimesMaxTime = 12.;   // us
+  fHistTrackingTiming = new TH2I("trdmon_tracking_timing", "tracking timing;;time after L0 (#mu s);",
+              4, 0, 4, (Int_t)(trackingTimesMaxTime/trackingTimesTimeBin), 0., trackingTimesMaxTime);
+  fHistTrackingTiming->GetXaxis()->SetBinLabel(1, "tracklet start");
+  fHistTrackingTiming->GetXaxis()->SetBinLabel(2, "tracklet end");
+  fHistTrackingTiming->GetXaxis()->SetBinLabel(3, "stack done");
+  fHistTrackingTiming->GetXaxis()->SetBinLabel(4, "sector done");
+  fHistArray->AddLast(fHistTrackingTiming);
 
-    if (fRawReaderTrd) delete fRawReaderTrd;
-    fRawReaderTrd=NULL;
+  fHistTriggerContribs = new TH2I("trdmon_trigger_contribs", "TRD internal contributions by sector;TRD sector;trigger contribution;",
+                                 18, 0, 18, 12, 0, 12);
+  fHistTrackingTiming->GetYaxis()->SetBinLabel(1, "trg0");
+  fHistTrackingTiming->GetYaxis()->SetBinLabel(2, "trg1");
+  fHistTrackingTiming->GetYaxis()->SetBinLabel(3, "trg2");
+  fHistTrackingTiming->GetYaxis()->SetBinLabel(4, "trg3");
+  fHistTrackingTiming->GetYaxis()->SetBinLabel(5, "trg4");
+  fHistTrackingTiming->GetYaxis()->SetBinLabel(6, "trg5");
+  fHistTrackingTiming->GetYaxis()->SetBinLabel(7, "trg5");
+  fHistTrackingTiming->GetYaxis()->SetBinLabel(8, "T");
+  fHistArray->AddLast(fHistTriggerContribs);
 
-    if (fTrackletArray) delete fTrackletArray;
-    fTrackletArray = NULL;
+ vector<const char*> remainingArgs;
+ for (int i = 0; i < argc; ++i)
+   remainingArgs.push_back(argv[i]);
 
-    if (fGtuTrackArray) delete fGtuTrackArray;
-    fGtuTrackArray = NULL;
+ if (argc > 0)
+   ConfigureFromArgumentString(remainingArgs.size(), &(remainingArgs[0]));
 
-    if (fHistArray) delete fHistArray;
-    fHistArray = NULL;
+  return 0;
+}
 
-    fHistTrackletY = NULL;
-    fHistTrackletDy = NULL;
-    fHistTrackletZ = NULL;
-    fHistTrackletPID = NULL;
-    fHistTrackletYDy = NULL;
-    fHistTrackletHC = NULL;
-    fHistTrackletBadY = NULL;
-    fHistTrackletBadPID = NULL;
-    fHistTrackPt = NULL;
-    fHistTrackStack = NULL;
-    fHistFirstTrackletTime = NULL;
-    fHistLastTrackletTime = NULL;
-    fHistTmuTime = NULL;
-    fHistSmuTime = NULL;
-    fHistTrackPt = NULL;
-    fHistTrackStack = NULL;
-    fHistTrackletsTrack = NULL;
-    fHistTrackletsTrackHpt = NULL;
-    fHistTrackPID = NULL;
-    fHistTriggerContribs = NULL;
+int AliHLTTRDMonitorComponent::DoDeinit() {
+
+  if ((fHistoMode == 1) && (fWriteHistos)){
+    TFile out("mon_out/mon_hists.root", "RECREATE");
+    if (!out.IsZombie()) {
+      out.cd();
+      UInt_t numHists = fHistArray->GetEntries();
+      for (UInt_t iHist = 0; iHist < numHists; ++iHist)
+       if (fHistArray->At(iHist))
+         fHistArray->At(iHist)->Write();
+      out.Close();
+    }
   }
 
-  return iResult;
+  if (fHistArray) delete fHistArray;
+  fHistArray = NULL;
+
+  if (fTrackingData) delete fTrackingData;
+  fTrackingData = NULL;
+
+  return 0;
 }
 
-int AliHLTTRDMonitorComponent::ScanConfigurationArgument(int /*argc*/, const char** /*argv*/)
+int AliHLTTRDMonitorComponent::ScanConfigurationArgument(int argc, const char** argv)
 {
-  // Scan configuration arguments
-  // Return the number of processed arguments
-  //        -EPROTO if argument format error (e.g. number expected but not found)
-  //
-  // The AliHLTComponent base class implements a parsing loop for argument strings and
-  // arrays of strings which is invoked by ConfigureFromArgumentString/ConfigureFromCDBTObjString
-  // The component needs to implement ScanConfigurationArgument in order to decode the arguments.
-
-  /*
-  int i=0;
-  TString argument=argv[i];
-
-  if (argument.IsNull()) return 0;
-
-  // -mandatory1 arg
-  if (argument.CompareTo("-mandatory1")==0) {
-    if (++i>=argc) return -EINVAL;
-    HLTInfo("got \'-mandatory1\' argument: %s", argv[i]);
-    return 2; // keyword + 1 argument
-  }
 
-  // -optional1 arg
-  if (argument.CompareTo("-optional1")==0) {
-    if (++i>=argc) return -EINVAL;
-    HLTInfo("got \'-optional1\' argument: %s", argv[i]);
-    return 2; // keyword + 1 argument
+  if (argc <= 0)
+    return 0;
+
+  UShort_t iArg = 0;
+  TString argument(argv[iArg]);
+
+  if (!argument.CompareTo("-write-histograms")){
+    LogInfo("writing of histograms enabled.");
+    fWriteHistos = kTRUE; // enable histogram writing, for debugging/tuning only!
+    return 1;
   }
 
-  // -verbose
-  if (argument.CompareTo("-verbose")==0) {
-    fVerbosity=1;
-    return 1; // only keyword
+  if (!argument.CompareTo("-debug")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fDebugLevel = argument.Atoi();
+    LogInfo("debug level set to %d.", fDebugLevel);
+    return 2;
   }
-  */
+
   return 0;
+
 }
 
-int AliHLTTRDMonitorComponent::DoDeinit()
-{
-  // component cleanup, delete all instances of helper classes here
-  if (fRawReaderMem) delete fRawReaderMem;
-  fRawReaderMem=NULL;
+void AliHLTTRDMonitorComponent::DbgLog(const char* prefix, ...){
+#ifdef __TRDHLTDEBUG
+  AliHLTEventID_t eventNumber = fEventId;
+  Int_t fRunNumber = -1;
+  printf("TRDHLTGM %s-X-%s: [MON] %s",
+        (fRunNumber >= 0) ? Form("%06d", fRunNumber) : "XXXXXX",
+        (eventNumber != fgkInvalidEventId) ? Form("%05llu", eventNumber) : "XXXXX",
+        (strlen(prefix) > 0) ? Form("<%s> ", prefix) : "");
+#endif
+  va_list args;
+  va_start(args, prefix);
+  char* fmt = va_arg(args, char*);
+  vprintf(fmt, args);
+  printf("\n");
+  va_end(args);
+}
 
-  if (fRawReaderTrd) delete fRawReaderTrd;
-  fRawReaderTrd=NULL;
+int AliHLTTRDMonitorComponent::PrepareTRDData() {
 
-  if (fTrackletArray) delete fTrackletArray;
-  fTrackletArray = NULL;
+  int result = 1;
 
-  if (fGtuTrackArray) delete fGtuTrackArray;
-  fGtuTrackArray = NULL;
-  
-  if (fHistArray) delete fHistArray;
-  fHistArray = NULL;
+  fTrackingData->Clear();
+  for (const AliHLTComponentBlockData* datablock = GetFirstInputBlock(AliHLTTRDDefinitions::fgkOnlineDataType);
+       datablock != NULL;
+       datablock = GetNextInputBlock())
+    {
+      fTrackingData->Decompress(datablock->fPtr, datablock->fSize, kTRUE);
+    }
 
-  fHistTrackletY = NULL;
-  fHistTrackletDy = NULL;
-  fHistTrackletY = NULL;
-  fHistTrackletDy = NULL;
-  fHistTrackletZ = NULL;
-  fHistTrackletPID = NULL;
-  fHistTrackletHC = NULL;
-  fHistTrackletBadY = NULL;
-  fHistTrackletBadPID = NULL;
-  fHistFirstTrackletTime = NULL;
-  fHistLastTrackletTime = NULL;
-  fHistTmuTime = NULL;
-  fHistSmuTime = NULL;
-  fHistTrackPt = NULL;
-  fHistTrackStack = NULL;
-  fHistTrackletsTrack = NULL;
-  fHistTrackletsTrackHpt = NULL;
-  fHistTrackPID = NULL;
-  fHistTriggerContribs = NULL;
+  fTrackingData->PrintSummary("monitor component");
+
+  return result;
 
-  return 0;
 }
 
-int AliHLTTRDMonitorComponent::DoEvent(const AliHLTComponentEventData& /*evtData*/,
-                                             AliHLTComponentTriggerData& /*trigData*/)
-{
-  // event processing function
-  int iResult=0;
-
-  // check if this is a data event, there are a couple of special events
-  // which should be ignored for normal processing
-  if (!IsDataEvent()) return 0;
-
-  // #FIXME: Also take care of SOR, EOR, etc...
-
-  // loop over the raw input data blocks and set up the rawreader
-  for (const AliHLTComponentBlockData* pBlock = GetFirstInputBlock(kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTRD);
-       pBlock!=NULL && iResult>=0;
-       pBlock=GetNextInputBlock()) {
-    // extract DDL id from specification
-    int ddlnum=-1;
-    for (unsigned pos=0; pos<8*sizeof(AliHLTUInt32_t); pos++) {
-      if (pBlock->fSpecification & (0x1<<pos)) {
-             if (ddlnum>=0) {
-               // this is just an example, please avoid warnings in every event since those will
-               // saturate the logging system. Consider AliHLTErrorGuard for such cases, e.g.
-               // ALIHLTERRORGUARD(5, "nasty error, first occurence in event %d", event);
-               // this will show the error 5 times and then a summary at the end
-               HLTWarning("Can not uniquely identify DDL number from specification, skipping data block %s 0x%08x",
-                    DataType2Text(pBlock->fDataType).c_str(),
-                    pBlock->fSpecification);
-               ddlnum=-1;
-               break;
-             }
-             ddlnum=pos;
+void AliHLTTRDMonitorComponent::DumpTrackingData(){
+  TString trklStr("");
+  TString matchStr("");
+  UShort_t layerMask;
+
+  if (fTrackingData->GetNumTracklets() + fTrackingData->GetNumTracks() == 0)
+    return;
+
+  for (UShort_t iStack = 0; iStack < fkTRDStacks; ++iStack){
+    for (Int_t iTrk = 0; iTrk < fTrackingData->GetNumTracks(iStack); ++iTrk){
+
+      layerMask = fTrackingData->GetTrackLayerMask(iStack, iTrk);
+      trklStr = Form("trkl: ");
+      for (Short_t iLayer = 5; iLayer >= 0; --iLayer){
+       if ((layerMask >> iLayer) & 1)
+         trklStr += Form("0x%08x (%+8.3f)  ",
+                         fTrackingData->GetTrackTrackletWord(iStack, iTrk, iLayer),
+                         fTrackingData->GetTrackTrackletLocalY(iStack, iTrk, iLayer));
+       else
+         trklStr += "---------------------  ";
+      } // loop over layers
+      trklStr.Remove(trklStr.Length() - 2, 2);
+
+      if (fTrackingDataDebugOutput){
+
+       printf("###DOTDB EV%04llu  GTU TRACK - S%02d-%d  pt: %+7.2f  pid: %3d  lm: 0x%02x %s\n",
+              fEventId,
+              iStack/5, iStack%5, fTrackingData->GetTrackPt(iStack, iTrk), fTrackingData->GetTrackPID(iStack, iTrk),
+              layerMask, trklStr.Data());
       }
-    }
-    if (ddlnum<0) continue;
-    ddlnum += 1024;
-
-    // add data block to rawreader
-    if(!fRawReaderMem->AddBuffer((UChar_t*) pBlock->fPtr, pBlock->fSize, ddlnum)){
-      HLTError("Could not add buffer of data block  %s, 0x%08x to rawreader",
-              DataType2Text(pBlock->fDataType).c_str(),
-              pBlock->fSpecification);
-      continue;
-    }
 
-    // read and process TRD tracklet and GTU tracks from event
-    fTrackletArray->Clear();
-    fGtuTrackArray->Clear();
-    fRawReaderTrd->ReadEvent();
-
-    // read and process tracking/trigger flags
-    UInt_t iSector = ddlnum-1024;
-    UInt_t trgflags = fRawReaderTrd->GetTriggerFlags(iSector);
-    //UInt_t done_tmu = (trgflags >> 27) & 0x1f;
-    //UInt_t done_smu = (trgflags >> 22) & 0x1f;
-    Float_t smu_timing = ((trgflags >> 12) & 0x3ff) * 0.0083333; // tracking finished after L0, in us
-    UInt_t ctb_fired =  trgflags & 0xfff;
-
-    /*
-      printf("Trigger flags sector %02d: 0x%08x - ctb=0x%03x  tmu-done=0x%x smu-done=0x%x  smu-time: %.2fus\n", 
-          iSector, trgflags,
-          ctb_fired,
-          done_tmu,
-          done_smu,
-          smu_timing
-          );
-    */
-    fHistSmuTime->Fill(smu_timing);
-
-    for (int iCtb=0; iCtb<12; iCtb++){
-      if ((ctb_fired >> iCtb) & 1)
-        fHistTriggerContribs->Fill(iSector, iCtb, 1);
-    }
+      // paranoia checks
+      for (Short_t iLayer = 5; iLayer >= 0; --iLayer){
+       if (((layerMask >> iLayer) & 1) && (fTrackingData->GetTrackTrackletWord(iStack, iTrk, iLayer) == 0x10001000))
+         LogError("invalid layer mask / tracklet value combination A", "");
+
+       if ((((layerMask >> iLayer) & 1) == 0) && (fTrackingData->GetTrackTrackletWord(iStack, iTrk, iLayer) != 0x10001000))
+         LogError("invalid layer mask / tracklet value combination B", "");
+      }
+
+    } // loop over tracks in stack
+  } // loop over stacks
+
+}
+
 
-    Float_t first_tracklet_timing[5]={0};
-    Float_t last_tracklet_timing[5]={0};
-    Float_t tmu_timing[5]={0};
-    ULong64_t trkflags;
-
-    for (int iStack=0; iStack<5; iStack++){
-      trkflags = fRawReaderTrd->GetTrkFlags(iSector, iStack);
-      tmu_timing[iStack]=(trkflags & 0x3ff) * 0.02;
-      first_tracklet_timing[iStack]=((trkflags >> 20) & 0x3ff) * 0.008;
-      last_tracklet_timing[iStack]=((trkflags >> 10) & 0x3ff) * 0.008;
-      /*
-      printf("  Stack %02d_%d: 0x%016llx - first tracklet: %.2fus  last tracklet: %.2fus  tmu timing: %.2fus\n",
-            iSector, iStack, trkflags, 
-            first_tracklet_timing[iStack], last_tracklet_timing[iStack], tmu_timing[iStack]
-            );
-      */
-      fHistFirstTrackletTime->Fill(first_tracklet_timing[iStack]);
-      fHistLastTrackletTime->Fill(last_tracklet_timing[iStack]);
-      fHistTmuTime->Fill(tmu_timing[iStack]);
+int AliHLTTRDMonitorComponent::ProcessTRDData(){
+
+  UInt_t numTracklets;
+  UInt_t numTracks;
+
+  if (fHistoMode == 0){
+    UInt_t numHists = fHistArray->GetEntries();
+    for (UInt_t iHist = 0; iHist < numHists; ++iHist)
+      if (fHistArray->At(iHist))
+       dynamic_cast<TH1*>(fHistArray->At(iHist))->Reset();
+  }
+
+  // tracklets
+  for (UInt_t iDet = 0; iDet < fkTRDChambers; ++iDet){
+    numTracklets = fTrackingData->GetNumTracklets(iDet);
+    for (UInt_t iTrkl = 0; iTrkl < numTracklets; ++iTrkl){
+      fHistTrackletY->Fill(fTrackingData->GetTrackletLocalY(iDet, iTrkl));
+      fHistTrackletDy->Fill(fTrackingData->GetTrackletBinDy(iDet, iTrkl));
+      fHistTrackletYDy->Fill(fTrackingData->GetTrackletBinY(iDet, iTrkl), fTrackingData->GetTrackletBinDy(iDet, iTrkl));
+      fHistTrackletZ->Fill(fTrackingData->GetTrackletBinZ(iDet, iTrkl));
+      fHistTrackletPID->Fill(fTrackingData->GetTrackletPID(iDet, iTrkl));
+      Int_t hc = fTrackingData->GetTrackletHCId(iDet, iTrkl);
+      fHistTrackletsHCId->Fill(hc/60, hc%60);
     }
+  }
+
+  for (UShort_t iStack = 0; iStack < fkTRDStacks; ++iStack){
+    // timing
+    fHistTrackletTimingStack->Fill(iStack, fTrackingData->GetTrackletStartTime(iStack/5, iStack%5));
+    fHistTrackletTimingStack->Fill(iStack, fTrackingData->GetTrackletEndTime(iStack/5, iStack%5));
+    fHistTrackingTiming->Fill(0., fTrackingData->GetTrackletStartTime(iStack/5, iStack%5));
+    fHistTrackingTiming->Fill(1., fTrackingData->GetTrackletEndTime(iStack/5, iStack%5));
+    fHistTrackingTiming->Fill(2., fTrackingData->GetTMUTrackingDoneTime(iStack/5, iStack%5));
+
+    // GTU tracks
+    numTracks = fTrackingData->GetNumTracks(iStack);
+    fHistTracksStack->Fill(iStack/5, iStack%5, numTracks);
+    for (UInt_t iTrk = 0; iTrk < numTracks; ++iTrk){
+      Double_t gpt = fTrackingData->GetTrackPt(iStack, iTrk);
+      fHistTrackPt->Fill(gpt);
+      fHistTrackPID->Fill(fTrackingData->GetTrackPID(iStack, iTrk));
+      fHistTrackLayers->Fill(fTrackingData->GetTrackLayerNum(iStack, iTrk));
+      if (gpt >= fTrackHighPtThreshold)
+       fHistTrackLayersHighPt->Fill(fTrackingData->GetTrackLayerNum(iStack, iTrk));
+    } // loop over tracks in stack
+  } // loop over stacks
+
+  for (UShort_t iSector = 0; iSector < fkTRDSectors; ++iSector){
+    fHistTrackingTiming->Fill(3., fTrackingData->GetSMUTrackingDoneTime(iSector), fkTRDStacksPerSector);
+
+    UInt_t sectorTrgFlags = fTrackingData->GetSectorTrgContribs(iSector);
+    for (UShort_t iTrgCtb = 0; iTrgCtb < 12; ++iTrgCtb)
+      if ((sectorTrgFlags >> iTrgCtb) & 1)
+       fHistTriggerContribs->Fill(iSector, iTrgCtb);
+  }
+
+  return kTRUE;
+}
+
+int AliHLTTRDMonitorComponent::DoEvent(const AliHLTComponentEventData& evtData,
+                                      AliHLTComponentTriggerData& /*trigData*/) {
 
-    for (int iTracklet = 0; iTracklet < fTrackletArray->GetEntriesFast(); iTracklet++) {
-      AliTRDtrackletWord *trackletWord = (AliTRDtrackletWord*) ((*fTrackletArray)[iTracklet]);
-      AliESDTrdTracklet tracklet(trackletWord->GetTrackletWord(), trackletWord->GetHCId());
-      /*
-      printf("TRDMSG: TRD tracklet found: 0x%08x  - y=%+5d  dy=%+3d  pid=%3d\n",
-            tracklet.GetTrackletWord(),
-            tracklet.GetBinY(),
-            tracklet.GetBinDy(),
-            tracklet.GetPID());
-      */
-      // fill some basic histograms right here
-      fHistTrackletY->Fill(tracklet.GetBinY());
-      fHistTrackletDy->Fill(tracklet.GetBinDy());
-      fHistTrackletZ->Fill(tracklet.GetBinZ());
-      fHistTrackletPID->Fill(tracklet.GetPID());
-      fHistTrackletYDy->Fill(tracklet.GetBinY(), tracklet.GetBinDy());
-      fHistTrackletHC->Fill(tracklet.GetHCId()/60, tracklet.GetHCId()%60);
-
-      if (TMath::Abs(tracklet.GetBinY()) >= 3682) 
-        fHistTrackletBadY->Fill(tracklet.GetHCId()/60, (tracklet.GetHCId()%60)/12);
-
-      if (tracklet.GetPID() < 40)
-        fHistTrackletBadPID->Fill(tracklet.GetHCId()/60, (tracklet.GetHCId()%60)/12);
+  int iResult = 0;
+  fEventId = evtData.fEventID;
+  fHistEventTypes->Fill(0.);
 
+  LogDebug("### START DoEvent [event id: %llu, %d blocks, size: %d]",
+          fEventId, evtData.fBlockCnt, evtData.fStructSize);
+
+  if (!IsDataEvent()) {  // process data events only
+    LogDebug("### END   DoEvent [event id: %llu, %d blocks, size: %d] (skipped: no data event)",
+            fEventId, evtData.fBlockCnt, evtData.fStructSize);
+    return iResult;
+  }
+
+  fHistEventTypes->Fill(1.);
+
+  fTrackingData->SetLogPrefix(Form("TRDHLTGM XXXXXX-%05llu: [MON] {TrkDat} ", fEventId));
+
+  do {
+
+    // access to TRD specific data from AliHLTTRDPreprocessorComponent
+    if (!PrepareTRDData()){
+      LogError("access to TRD data failed. Skipping event...", "");
+      break;
     }
 
-    for (int iTrack = 0; iTrack < fGtuTrackArray->GetEntriesFast(); iTrack++) {
-      AliESDTrdTrack *trdTrack = (AliESDTrdTrack*) ((*fGtuTrackArray)[iTrack]);
-      /*
-      printf("TRDMSG: GTU track found: 0x%016llx - Stack %02d_%d  pt=%.3fGeV/c\n",
-            trdTrack->GetTrackWord(0),
-            trdTrack->GetSector(), trdTrack->GetStack(),
-            trdTrack->Pt());
-      */
-      fHistTrackPt->Fill(trdTrack->Pt());
-      fHistTrackStack->Fill(trdTrack->GetSector(), trdTrack->GetStack());
-      fHistTrackPID->Fill(trdTrack->GetPID());
-
-      Int_t layers=0;
-      Int_t layer_mask = trdTrack->GetLayerMask();
-      for (Int_t iLayer=0; iLayer<6; iLayer++)
-       if ((layer_mask >> iLayer) & 1)
-         layers++;
-      fHistTrackletsTrack->Fill(layers);
-      if (TMath::Abs(trdTrack->Pt()) >= 3.)
-        fHistTrackletsTrackHpt->Fill(layers);
+    if (fTrackingData->GetNumTracks() + fTrackingData->GetNumTracklets() == 0) {
+      LogDebug("no TRD-relevant information, skipping further event processing");
+      break;
     }
 
-    // do more complex processing here, preferably in a dedicated class
+    fHistEventTypes->Fill(2.);
 
-    // push  TObject-based data to output
-    iResult = PushBack(fHistArray, 
-                      (kAliHLTDataTypeTObject | kAliHLTDataOriginTRD), 
-                      pBlock->fSpecification);
+    // DumpTrackingData();
 
-    if (iResult < 0)                                  
+    if (!ProcessTRDData()) {
+      LogError("processing of TRD data failed, skipping further event processing");
       break;
-                      
-    // clear the rawreader
-    fRawReaderMem->ClearBuffers();    
-  }
+    }
 
-  return iResult;
-}
+    break;
 
-int AliHLTTRDMonitorComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
-{
-  // reconfigure the component from the specified CDB entry, or default CDB entry
-  // function is invoked by the framework if a reconfigure command was received.
-  // 
-  int iResult=0;
-  /*
-  TString cdbPath;
-  if (cdbEntry) {
-    cdbPath=cdbEntry;
-  } else {
-    cdbPath="HLT/ConfigSample/";
-    cdbPath+=GetComponentID();
-  }
-  AliInfoClass(Form("reconfigure '%s' from entry %s%s", chainId, cdbPath.Data(), cdbEntry?"":" (default)"));
-  iResult=ConfigureFromCDBTObjString(cdbPath);
-  */
-  return iResult;
-}
+  } while (1);
+
+  PushBack(fHistArray, (kAliHLTDataTypeTObjArray | kAliHLTDataOriginTRD), 0x3fffff);
+
+  LogDebug("### END   DoEvent [event id: %llu, %d blocks, size: %d]",
+                     fEventId, evtData.fBlockCnt, evtData.fStructSize);
 
-int AliHLTTRDMonitorComponent::ReadPreprocessorValues(const char* /*modules*/)
-{
-  // read the preprocessor values for the detectors in the modules list
-  // function is invoked by the framework if the pendolino indivates an update
-  // of online calibration objects, e.g temperature and pressure measurements.
-  int iResult=0;
-  /*
-  TString detectors(modules!=NULL?modules:"");
-  AliInfoClass(Form("read preprocessor values for detector(s): %s", detectors.IsNull()?"none":detectors.Data()));
-  */
   return iResult;
 }
index 13515d4..e23baaa 100644 (file)
@@ -3,69 +3,24 @@
 #ifndef ALIHLTTRDMONITORCOMPONENT_H
 #define ALIHLTTRDMONITORCOMPONENT_H
 
-//* This file is property of and copyright by the ALICE HLT Project        * 
+//* This file is property of and copyright by the ALICE HLT Project        *
 //* ALICE Experiment at CERN, All rights reserved.                         *
 //* See cxx source for full Copyright notice                               */
 
 /// @file   AliHLTTRDMonitorComponent.h
 /// @author Felix Rettig, Stefan Kirsch
-/// @date   2011-08-02
-/// @brief  A FEP-level processing component for TRD tracking/trigger data
+/// @date   2012-08-16
+/// @brief  The TRD monitoring component
 /// @ingroup alihlt_trd_components
 
 #include "AliHLTProcessor.h"
 
-class AliRawReaderMemory;
-class TTree;
-class AliTRDdigitsManager;
-class AliTRDrawStream;
-class TH1F;
+class TObjArray;
 class TH1I;
 class TH2I;
 class TH2F;
+class AliTRDonlineTrackingDataContainer;
 
-/**
- * @class AliHLTTRDMonitorComponent
- * Component fetches raw data input objects in DDL format and extracts tracklets and GTU tracks.
- *  It also instantiates a RawReader in order to be used with some reconstruction.
- *
- * More information and examples can be found here (relative to $ALICE_ROOT):
- * 
- * -- HLT/BASE/AliHLTComponent.h/.cxx,  HLT/BASE/AliHLTProcessor.h/.cxx
- *    Interface definition and description
- * -- HLT/SampleLib: example implementations of components
- *
- *
- * <h2>General properties:</h2>
- *
- * Component ID: \b AliHLTTRDMonitorComponent <br>
- * Library: \b libAliHLTTRD.so     <br>
- * Input Data Types: @ref kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTRD <br>
- * Output Data Types: @ref kAliHLTTrackDataTypeID|kAliHLTDataOriginTRD <br>
- *
- * <h2>Mandatory arguments:</h2>
- * none     
- *
- * <h2>Optional arguments:</h2>
- * none
- *
- * <h2>Configuration:</h2>
- * none
- *
- * <h2>Default CDB entries:</h2>
- * none
- *
- * <h2>Performance:</h2>
- * minmal
- *
- * <h2>Memory consumption:</h2>
- * don't know yet
- *
- * <h2>Output size:</h2>
- * not very much
- *
- * @ingroup The component has no output data.
- */
 class AliHLTTRDMonitorComponent : public AliHLTProcessor {
 public:
   AliHLTTRDMonitorComponent();
@@ -75,21 +30,16 @@ public:
   const char* GetComponentID();
   void GetInputDataTypes( vector<AliHLTComponentDataType>& list);
   AliHLTComponentDataType GetOutputDataType();
-  int GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList);
   void GetOutputDataSize( unsigned long& constBase, double& inputMultiplier );
-  void GetOCDBObjectDescription( TMap* const targetMap);
-
-  // Spawn function, return new class instance
   AliHLTComponent* Spawn();
 
  protected:
   // AliHLTComponent interface functions
   int DoInit( int argc, const char** argv );
   int DoDeinit();
-  int DoEvent( const AliHLTComponentEventData& evtData, AliHLTComponentTriggerData& trigData);
   int ScanConfigurationArgument(int argc, const char** argv);
+  int DoEvent( const AliHLTComponentEventData& evtData, AliHLTComponentTriggerData& trigData);
   int Reconfigure(const char* cdbEntry, const char* chainId);
-  int ReadPreprocessorValues(const char* modules);
 
   using AliHLTProcessor::DoEvent;
 
@@ -99,37 +49,49 @@ private:
   /** assignment operator prohibited */
   AliHLTTRDMonitorComponent& operator=(const AliHLTTRDMonitorComponent&);
 
-  // trd specific data
-  TClonesArray* fTrackletArray;
-  TClonesArray *fGtuTrackArray;
+  int Configure(const char* arguments);
+
+  void DbgLog(const char* prefix, ... );
+
+  int PrepareTRDData();
+  void DumpTrackingData();
+  int ProcessTRDData();
 
-  // rawreader instance
-  AliRawReaderMemory* fRawReaderMem;
-  AliTRDdigitsManager *fDigitsManagerTrd;
-  AliTRDrawStream*    fRawReaderTrd; 
+  static const AliHLTEventID_t fgkInvalidEventId = 0xffffffffffffffffllu;
+  static const unsigned int fkTRDChambers = 540;             //! number of chambers in TRD
+  static const unsigned int fkTRDStacks = 90;                //! number of stacks in TRD
+  static const unsigned int fkTRDStacksPerSector = 5;        //! number of stacks per sector in TRD
+  static const unsigned int fkTRDSectors = 18;               //! number of sectors in TRD
+  static const unsigned int fkMaxRefTracksPerStack = 1000;   //! maximum number of ref tracks per stack
+
+  Double_t fTrackHighPtThreshold;           //! high-pt track pt threshold
+  Bool_t fHistoMode;                        //! histogramming mode, 0: single event, 1: accumulative (debugging)
+  Bool_t fTrackingDataDebugOutput;          //! switch on/off tracking data text dump
+
+  UShort_t fDebugLevel;                                      //! debug level, 0: debug off
+  Bool_t fWriteHistos;                                       //! switch on/off histogram writing
+
+  AliHLTEventID_t fEventId;                                  //! hlt internal event id
+  AliTRDonlineTrackingDataContainer* fTrackingData;          //! container for TRD tracking data
 
-  // FEE statistics data
   TObjArray* fHistArray;
-  TH1I *fHistTrackletY;
-  TH1I *fHistTrackletDy;
-  TH1I *fHistTrackletZ;
-  TH1I *fHistTrackletPID;
-  TH2I *fHistTrackletYDy;
-  TH2I *fHistTrackletHC;
-  TH2I *fHistTrackletBadY;
-  TH2I *fHistTrackletBadPID;
-  TH1F *fHistFirstTrackletTime;
-  TH1F *fHistLastTrackletTime;
-  // GTU statistics data
-  TH1F *fHistTmuTime;
-  TH1F *fHistSmuTime;
-  TH1F *fHistTrackPt;
-  TH2I *fHistTrackStack;
-  TH1I *fHistTrackletsTrack;
-  TH1I *fHistTrackletsTrackHpt;
-  TH1I *fHistTrackPID;
-  TH2I *fHistTriggerContribs;
+  TH1I* fHistEventTypes;                                     //! counting of event types
+  TH1I* fHistTrackletY;                                      //! tracklet y-positions from all stacks
+  TH1I* fHistTrackletDy;                                     //! tracklet deflections from all stacks
+  TH2I* fHistTrackletYDy;                                    //! tracklet deflections vs. y-positions
+  TH1I* fHistTrackletZ;                                      //! tracklet z-positions from all stacks
+  TH1I* fHistTrackletPID;                                    //! tracklet PID values from all stacks
+  TH2F* fHistTrackletsHCId;                                  //! number of tracklets per half-chamber
+  TH1I* fHistTrackPt;                                        //! transverse momentum of GTU tracks from all stacks
+  TH1I* fHistTrackPID;                                       //! PID of GTU tracks from all stacks
+  TH1I* fHistTrackLayers;                                    //! contributing layers per GTU track
+  TH1I* fHistTrackLayersHighPt;                              //! contributing layer per high-pt GTU track
+  TH2F* fHistTracksStack;                                    //! GTU tracks per stack
+  TH2I* fHistTrackletTimingStack;                            //! tracklet arrival timing by stack
+  TH2I* fHistTrackingTiming;                                 //! tracking timing
+  TH2I* fHistTriggerContribs;                                //! trigger contributions by sector
 
   ClassDef(AliHLTTRDMonitorComponent, 0)
 };
+
 #endif
diff --git a/HLT/TRD/AliHLTTRDPreprocessorComponent.cxx b/HLT/TRD/AliHLTTRDPreprocessorComponent.cxx
new file mode 100644 (file)
index 0000000..20b7de5
--- /dev/null
@@ -0,0 +1,454 @@
+// $Id$
+//**************************************************************************
+//* This file is property of and copyright by the ALICE HLT Project        *
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//*                                                                        *
+//* Permission to use, copy, modify and distribute this software and its   *
+//* documentation strictly for non-commercial purposes is hereby granted   *
+//* without fee, provided that the above copyright notice appears in all   *
+//* copies and that both the copyright notice and this permission notice   *
+//* appear in the supporting documentation. The authors make no claims     *
+//* about the suitability of this software for any purpose. It is          *
+//* provided "as is" without express or implied warranty.                  *
+//**************************************************************************
+
+/// @file   AliHLTTRDPreprocessorComponent.cxx
+/// @author Felix Rettig, Stefan Kirsch
+/// @date   2012-08-16
+/// @brief  A pre-processing component for TRD tracking/trigger data on FEP-level
+/// @ingroup alihlt_trd_components
+
+#include <cstdlib>
+#include "TList.h"
+#include "AliLog.h"
+#include "AliHLTDataTypes.h"
+#include "AliHLTTRDDefinitions.h"
+#include "AliHLTTRDPreprocessorComponent.h"
+#include "AliTRDdigitsManager.h"
+#include "AliRawReaderMemory.h"
+#include "AliTRDrawStream.h"
+#include "AliTRDtrackletWord.h"
+#include "AliESDTrdTracklet.h"
+#include "AliESDTrdTrack.h"
+#include "AliTRDonlineTrackingDataContainer.h"
+
+ClassImp(AliHLTTRDPreprocessorComponent)
+
+#define LogError( ... ) { HLTError(__VA_ARGS__); if (fDebugLevel >= 1) { DbgLog("ERROR", __VA_ARGS__); } }
+#define LogInfo( ... ) { HLTInfo(__VA_ARGS__); if (fDebugLevel >= 1) { DbgLog("INFO", __VA_ARGS__); } }
+#define LogInspect( ... ) { HLTDebug(__VA_ARGS__); if (fDebugLevel >= 1) { DbgLog("INSPECT", __VA_ARGS__); } }
+#define LogDebug( ... ) { if (fDebugLevel >= 1) { HLTInfo(__VA_ARGS__); DbgLog("DEBUG", __VA_ARGS__); } }
+
+AliHLTTRDPreprocessorComponent::AliHLTTRDPreprocessorComponent() :
+  AliHLTProcessor(),
+  fDebugLevel(0),
+  fEventId(fgkInvalidEventId),
+  fTrackletArray(NULL),
+  fGtuTrackArray(NULL),
+  fRawReaderMem(NULL),
+  fDigitsManagerTrd(NULL),
+  fRawReaderTrd(NULL),
+  fTrackingData(NULL)
+{
+  // constructor
+}
+
+AliHLTTRDPreprocessorComponent::~AliHLTTRDPreprocessorComponent() {
+  // destructor
+}
+
+const char* AliHLTTRDPreprocessorComponent::GetComponentID() {
+  return "TRDPreprocessorComponent";
+}
+
+void AliHLTTRDPreprocessorComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list) {
+  list.push_back(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTRD);
+}
+
+AliHLTComponentDataType AliHLTTRDPreprocessorComponent::GetOutputDataType() {
+  return kAliHLTMultipleDataType;
+}
+
+int AliHLTTRDPreprocessorComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList) {
+  tgtList.clear();
+  tgtList.push_back(kAliHLTDataTypeTObject | kAliHLTDataOriginTRD);
+  return tgtList.size();
+}
+
+void AliHLTTRDPreprocessorComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier ) {
+  constBase = 5000000;
+  inputMultiplier = 0;
+}
+
+void AliHLTTRDPreprocessorComponent::GetOCDBObjectDescription( TMap* const /*targetMap*/) {
+}
+
+AliHLTComponent* AliHLTTRDPreprocessorComponent::Spawn(){
+  return new AliHLTTRDPreprocessorComponent;
+}
+
+int AliHLTTRDPreprocessorComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/) {
+  return 0;
+}
+
+int AliHLTTRDPreprocessorComponent::ReadPreprocessorValues(const char* /*modules*/){
+  return 0;
+}
+
+int AliHLTTRDPreprocessorComponent::ScanConfigurationArgument(int argc, const char** argv){
+
+  if (argc <= 0)
+    return 0;
+
+  UShort_t iArg = 0;
+  TString argument(argv[iArg]);
+
+  if (!argument.CompareTo("-debug")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fDebugLevel = argument.Atoi();
+    LogInfo("debug level set to %d.", fDebugLevel);
+    return 2;
+  }
+
+  return 0;
+}
+
+int AliHLTTRDPreprocessorComponent::DoInit(int argc, const char** argv){
+
+  int iResult = 0;
+
+  do {
+
+    fRawReaderMem = new AliRawReaderMemory;
+    if (!fRawReaderMem) {
+      iResult=-ENOMEM;
+      break;
+    }
+
+    fTrackletArray = new TClonesArray("AliTRDtrackletWord", 500);
+    if (!fTrackletArray) {
+      iResult=-ENOMEM;
+      break;
+    }
+    fTrackletArray->BypassStreamer(kTRUE);  //## needed for performance improvement?
+
+    fGtuTrackArray = new TClonesArray("AliESDTrdTrack", 50);
+    if (!fGtuTrackArray){
+      iResult=-ENOMEM;
+      break;
+    }
+
+    fRawReaderTrd = new AliTRDrawStream(fRawReaderMem);
+    if (!fRawReaderTrd) {
+      iResult=-ENOMEM;
+      break;
+    }
+
+    if (kFALSE){ // do not create digits manager for reader -> do not process ADC raw data
+      fDigitsManagerTrd = new AliTRDdigitsManager();
+      if (!fDigitsManagerTrd) {
+       iResult=-ENOMEM;
+       break;
+      }
+      fDigitsManagerTrd->CreateArrays();
+      fRawReaderTrd->SetDigitsManager(fDigitsManagerTrd);
+    }
+
+    fRawReaderTrd->SetDigitsManager(fDigitsManagerTrd);
+    fRawReaderTrd->SetTrackletArray(fTrackletArray);
+    fRawReaderTrd->SetTrackArray(fGtuTrackArray);
+
+    // Disable raw reader error messages that could flood HLT logbook
+    AliLog::SetClassDebugLevel("AliTRDrawStream", 0);
+    fRawReaderTrd->SetErrorDebugLevel(AliTRDrawStream::kLinkMonitor, 1);
+
+    fTrackingData = new AliTRDonlineTrackingDataContainer();
+    if (!fTrackingData){
+      iResult=-ENOMEM;
+      break;
+    }
+
+  } while (0);
+
+  if (iResult < 0) {
+
+    if (fTrackingData) delete fTrackingData;
+    fTrackingData = NULL;
+
+    if (fRawReaderTrd) delete fRawReaderTrd;
+    fRawReaderTrd = NULL;
+
+    if (fRawReaderMem) delete fRawReaderMem;
+    fRawReaderMem = NULL;
+
+    if (fDigitsManagerTrd) delete fDigitsManagerTrd;
+    fDigitsManagerTrd = NULL;
+
+    if (fGtuTrackArray) delete fGtuTrackArray;
+    fGtuTrackArray = NULL;
+
+    if (fTrackletArray) delete fTrackletArray;
+    fTrackletArray = NULL;
+
+  }
+
+  vector<const char*> remainingArgs;
+  for (int i = 0; i < argc; ++i)
+    remainingArgs.push_back(argv[i]);
+
+  if (argc > 0)
+    ConfigureFromArgumentString(remainingArgs.size(), &(remainingArgs[0]));
+
+  return iResult;
+}
+
+int AliHLTTRDPreprocessorComponent::DoDeinit() {
+
+  if (fTrackingData) delete fTrackingData;
+  fTrackingData = NULL;
+
+  if (fRawReaderTrd) delete fRawReaderTrd;
+  fRawReaderTrd = NULL;
+
+  if (fRawReaderMem) delete fRawReaderMem;
+  fRawReaderMem = NULL;
+
+  if (fGtuTrackArray) delete fGtuTrackArray;
+  fGtuTrackArray = NULL;
+
+  if (fTrackletArray) delete fTrackletArray;
+  fTrackletArray = NULL;
+
+  return 0;
+}
+
+//void AliHLTTRDPreprocessorComponent::DbgLog(const char* prefix, const char* msg){
+//  AliHLTEventID_t eventNumber = fEventId;
+//  int runNumber = -1;
+//  printf("TRDGM %s-%s: [PRE] %s%s\n",
+//      (runNumber >= 0) ? Form("%06d", runNumber) : "XXXXXX",
+//      (eventNumber != fgkInvalidEventId) ? Form("%05llu", eventNumber) : "XXXXX",
+//      (strlen(prefix) > 0) ? Form("<%s> ", prefix) : "", msg);
+//}
+
+
+void AliHLTTRDPreprocessorComponent::DbgLog(const char* prefix, ...){
+#ifdef __TRDHLTDEBUG
+  AliHLTEventID_t eventNumber = fEventId;
+  int runNumber = -1;
+  printf("TRDHLTGM %s-X-%s: [PRE] %s",
+        (runNumber >= 0) ? Form("%06d", runNumber) : "XXXXXX",
+        (eventNumber != fgkInvalidEventId) ? Form("%05llu", eventNumber) : "XXXXX",
+        (strlen(prefix) > 0) ? Form("<%s> ", prefix) : "");
+#endif
+  va_list args;
+  va_start(args, prefix);
+  char* fmt = va_arg(args, char*);
+  vprintf(fmt, args);
+  printf("\n");
+  va_end(args);
+}
+
+
+int AliHLTTRDPreprocessorComponent::DoEvent(const AliHLTComponentEventData& hltEventData,
+                                           AliHLTComponentTriggerData& /*trigData*/) {
+
+  fEventId = hltEventData.fEventID;
+  fTrackingData->SetLogPrefix(Form("TRDHLTGM XXXXXX-%05llu: [PRE] {TrkDat} ", hltEventData.fEventID));
+
+  LogDebug("### START DoEvent [event id: %llu, %d blocks, size: %d]",
+          hltEventData.fEventID, hltEventData.fBlockCnt, hltEventData.fStructSize);
+
+  // event processing function
+  int iResult = 0;
+  UInt_t sourceSectors = 0;
+
+  fTrackingData->Clear();
+  fTrackletArray->Clear();
+  fGtuTrackArray->Clear();
+
+  if (!IsDataEvent()) { // process data events only
+    LogDebug("### END   DoEvent [event id: %llu, %d blocks, size: %d] (skipped: no data event)",
+            hltEventData.fEventID, hltEventData.fBlockCnt, hltEventData.fStructSize);
+    return iResult;
+  }
+
+  TString infoStr("");
+
+  // #FIXME: Also take care of SOR, EOR, etc...
+
+  // loop over all incoming TRD raw data blocks
+  for (const AliHLTComponentBlockData* pBlock = GetFirstInputBlock(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTRD);
+       pBlock != NULL && iResult >= 0;
+       pBlock = GetNextInputBlock()) {
+
+    int trdSector = -1;
+
+    // determine sector from block specification
+    for (unsigned pos = 0; pos < 8*sizeof(AliHLTUInt32_t); pos++) {
+      if (pBlock->fSpecification & (0x1 << pos)) {
+       if (trdSector >= 0) {
+         HLTWarning("Cannot uniquely identify DDL number from specification, skipping data block %s 0x%08x",
+                    DataType2Text(pBlock->fDataType).c_str(),
+                    pBlock->fSpecification);
+         trdSector = -1;
+         break;
+       }
+       trdSector = pos;
+      }
+    }
+    if (trdSector < 0) continue;
+
+    // add data block to rawreader
+    infoStr += Form("%02d, ", trdSector);
+    sourceSectors |= pBlock->fSpecification;
+    if(!fRawReaderMem->AddBuffer((UChar_t*) pBlock->fPtr, pBlock->fSize, trdSector + 1024)){
+      LogError("Could not add buffer of data block  %s, 0x%08x to rawreader",
+              DataType2Text(pBlock->fDataType).c_str(),
+              pBlock->fSpecification);
+      continue;
+    }
+
+  } // loop over all incoming TRD raw data blocks
+
+  if (sourceSectors){
+    infoStr.Remove(infoStr.Length() - 2, 2);
+    LogDebug("preprocessing data from sectors: %s...", infoStr.Data());
+  } else {
+    LogDebug("### END   DoEvent [event id: %llu, %d blocks, size: %d] (skipping: no TRD data)",
+                       hltEventData.fEventID, hltEventData.fBlockCnt, hltEventData.fStructSize);
+    return iResult;
+  }
+
+  // extract header info, TRD tracklets and tracks from raw data
+  fRawReaderTrd->ReadEvent();
+
+  // read and store header info
+  for (UShort_t iSector = 0; iSector < 18; ++iSector){
+    if ((sourceSectors >> iSector) & 1){
+      fTrackingData->SetSectorTrgWord(iSector, fRawReaderTrd->GetTriggerFlags(iSector));
+      for (UShort_t iStack = 0; iStack < 5; ++iStack)
+       fTrackingData->SetStackTrgWord(iSector, iStack, fRawReaderTrd->GetTrkFlags(iSector, iStack));
+    }
+  }
+
+//  //## dbg only!!!!
+//  for (UShort_t iSector = 0; iSector < 18; ++iSector){
+//    fTrackingData->SetSectorTrgWord(iSector, 0x2345352 ^ (iSector + 34));
+//    for (UShort_t iStack = 0; iStack < 5; ++iStack){
+//      ULong64_t dwl = ((ULong64_t)0xaffe << 16) | (ULong64_t)iSector << 8 | iStack;
+//      ULong64_t dw = (((ULong64_t)0xbead << 16) | (ULong64_t)iSector << 8 | iStack) | ((ULong64_t)dwl << 32);
+//      fTrackingData->SetStackTrgWord(iSector, iStack, dw);
+//    }
+//  }
+
+  // read and process TRD tracklets
+  Int_t trackletIndex[1080] = { 0 };
+  TList trklList;
+  Int_t iTrkl = 0;
+  trklList.SetOwner(kFALSE);
+  AliTRDrawStream::SortTracklets(fTrackletArray, trklList, trackletIndex);
+  TIter trackletIter(&trklList);
+  while (AliTRDtrackletBase* tracklet = (AliTRDtrackletBase*) trackletIter()) {
+
+    // tracklet data to tracking data for transport to other HLT components
+    fTrackingData->AddTracklet(tracklet->GetHCId(), tracklet->GetTrackletWord());
+
+//    // conversion to AliESDTrdTracklet only for testing
+//    // label -2, we assume it's always raw tracklets here
+//    AliESDTrdTracklet esdTracklet(tracklet->GetTrackletWord(), tracklet->GetHCId(), -2);
+//    Int_t det = esdTracklet.GetDetector();
+//    if (kFALSE){
+//      printf("TRDPreproc: TRD tracklet %3d - S%02d-%d-%d (det %3d): 0x%08x  - y=%+5d  dy=%+3d  pid=%3d\n",
+//          iTrkl, det/30, (det%30)/6, det%6, det,
+//          esdTracklet.GetTrackletWord(), esdTracklet.GetBinY(), esdTracklet.GetBinDy(), esdTracklet.GetPID());
+//    }
+
+    ++iTrkl;
+  }
+
+  // read and process GTU tracks
+  UInt_t numGtuTracks = fGtuTrackArray->GetEntriesFast();
+  AliESDTrdTrack *trdTrack = NULL;
+  UInt_t stack;
+  Int_t refIndex[6];
+
+  for (UInt_t iTrack = 0; iTrack < numGtuTracks; iTrack++) {
+    trdTrack = (AliESDTrdTrack*) ((*fGtuTrackArray)[iTrack]);
+    if (trdTrack){
+
+      AliTRDrawStream::AssignTracklets(trdTrack, trackletIndex, refIndex);
+      stack = trdTrack->GetStack();
+
+      for (Int_t iLayer = 0; iLayer < 6; ++iLayer) {
+       AliESDTrdTracklet *trkl = (refIndex[iLayer] > -1) ? (AliESDTrdTracklet*) trklList.At(refIndex[iLayer]) : 0x0;
+       if (trkl)
+         trdTrack->AddTrackletReference(trkl, iLayer);
+      }
+
+      fTrackingData->AddTrack(trdTrack);
+
+//      for (Int_t iLayer = 0; iLayer < 6; ++iLayer) {
+//     Int_t det = trdTrack->GetSector()*30 + stack*6 + iLayer;
+//
+//     AliESDTrdTracklet *trkl = refIndex[iLayer] > -1 ? (AliESDTrdTracklet*) trklList.At(refIndex[iLayer]) : 0x0;
+//     if (trkl) {
+//       AliDebugClass(5, Form("adding tracklet with index %i: 0x%08x",
+//                             refIndex[iLayer], trkl->GetTrackletWord()));
+//       if (trkl->GetDetector() != det)
+//         AliErrorClass(Form("inconsistent assignment of tracklet 0x%08x in det %i to track in %i",
+//                            trkl->GetTrackletWord(), trkl->GetDetector(), det));
+//       trdTrack->AddTrackletReference(trkl, iLayer);
+//     }
+//      }
+//
+//      UInt_t pid = 0;
+//      UShort_t lyrNum = 0;
+//      TString trackletInfo("");
+//      for (UShort_t iLayer = 0; iLayer < 6; ++iLayer){
+//     AliESDTrdTracklet* trkl = trdTrack->GetTracklet(5 - iLayer);
+//     if (trkl){
+//       trackletInfo += Form("0x%08x  ", trkl->GetTrackletWord());
+//       pid += trkl->GetPID();
+//       lyrNum++;
+//     } else
+//       trackletInfo += "----------  ";
+//      }
+//      trackletInfo.Remove(trackletInfo.Length() - 2, 2);
+//      pid /= lyrNum;
+//
+//      Int_t pidDiff = trdTrack->GetPID() - pid;
+//
+//      UInt_t lm = trdTrack->GetLayerMask();
+//      DbgLog("", Form("GTU track %d - S%02d-%d pt=%+.3f lm=(L5)%d%d%d%d%d%d(L0) [%s] [pid %s: %d|%d]",
+//                   iTrack, trdTrack->GetSector(), trdTrack->GetStack(), trdTrack->Pt(),
+//                   (lm >> 5) & 0x1, (lm >> 4) & 0x1, (lm >> 3) & 0x1,
+//                   (lm >> 2) & 0x1, (lm >> 1) & 0x1, (lm >> 0) & 0x1,
+//                   trackletInfo.Data(),
+//                   (TMath::Abs(pidDiff) <= 1) ? "ok" : "mismatch",
+//                   trdTrack->GetPID(), pid));
+//
+
+    } else
+      LogError("GTU track %d is NULL!\n", iTrack);
+  } // loop over GTU tracks
+
+  fRawReaderMem->ClearBuffers();
+
+  if (sourceSectors){
+    LogDebug("pushing data for sectors: 0x%05x", sourceSectors);
+    // transport of TRD tracklets and GTU tracks via tracking data container
+    void* buffer;
+    UInt_t bufferSize;
+    fTrackingData->PrintSummary("preproc component");
+    fTrackingData->Compress(buffer, bufferSize);
+    iResult += PushBack(buffer, bufferSize, AliHLTTRDDefinitions::fgkOnlineDataType, sourceSectors);
+    free(buffer);
+  }
+
+  LogDebug("### END   DoEvent [event id: %llu, %d blocks, size: %d]",
+                     hltEventData.fEventID, hltEventData.fBlockCnt, hltEventData.fStructSize);
+
+  return iResult;
+}
diff --git a/HLT/TRD/AliHLTTRDPreprocessorComponent.h b/HLT/TRD/AliHLTTRDPreprocessorComponent.h
new file mode 100644 (file)
index 0000000..5359809
--- /dev/null
@@ -0,0 +1,125 @@
+//-*- Mode: C++ -*-
+// $Id$
+#ifndef ALIHLTTRDPREPROCESSORCOMPONENT_H
+#define ALIHLTTRDPREPROCESSORCOMPONENT_H
+
+//* This file is property of and copyright by the ALICE HLT/TRD Project    *
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               */
+
+/// @file   AliHLTTRDPreprocessorComponent.h
+/// @author Felix Rettig, Stefan Kirsch
+/// @date   2012-08-16
+/// @brief  A FEP-level pre-processing component for TRD tracking/trigger data
+/// @ingroup alihlt_trd_components
+
+#include "AliHLTProcessor.h"
+
+class AliRawReaderMemory;
+class TTree;
+class AliTRDdigitsManager;
+class AliTRDrawStream;
+class AliTRDonlineTrackingDataContainer;
+class TH1F;
+class TH1I;
+class TH2I;
+class TH2F;
+
+/**
+ * @class AliHLTTRDPreprocessorComponent
+ * Component fetches raw data input objects in DDL format and extracts tracklets and GTU tracks.
+ *  It also instantiates a RawReader in order to be used with some reconstruction.
+ *
+ * More information and examples can be found here (relative to $ALICE_ROOT):
+ *
+ * -- HLT/BASE/AliHLTComponent.h/.cxx,  HLT/BASE/AliHLTProcessor.h/.cxx
+ *    Interface definition and description
+ * -- HLT/SampleLib: example implementations of components
+ *
+ *
+ * <h2>General properties:</h2>
+ *
+ * Component ID: \b TRDPreprocessorComponent <br>
+ * Library: \b libAliHLTTRD.so     <br>
+ * Input Data Types: @ref kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTRD <br>
+ * Output Data Types: @ref kAliHLTTrackDataTypeID|kAliHLTDataOriginTRD <br>
+ *
+ * <h2>Mandatory arguments:</h2>
+ * none
+ *
+ * <h2>Optional arguments:</h2>
+ * none
+ *
+ * <h2>Configuration:</h2>
+ * none
+ *
+ * <h2>Default CDB entries:</h2>
+ * none
+ *
+ * <h2>Performance:</h2>
+ * minmal
+ *
+ * <h2>Memory consumption:</h2>
+ * don't know yet
+ *
+ * <h2>Output size:</h2>
+ * not very much
+ *
+ * @ingroup The component has no output data.
+ */
+class AliHLTTRDPreprocessorComponent : public AliHLTProcessor {
+public:
+  AliHLTTRDPreprocessorComponent();
+  virtual ~AliHLTTRDPreprocessorComponent();
+
+  // AliHLTComponent interface functions
+  const char* GetComponentID();
+  void GetInputDataTypes( vector<AliHLTComponentDataType>& list);
+  AliHLTComponentDataType GetOutputDataType();
+  int GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList);
+  void GetOutputDataSize( unsigned long& constBase, double& inputMultiplier );
+  void GetOCDBObjectDescription( TMap* const targetMap);
+
+  // Spawn function, return new class instance
+  AliHLTComponent* Spawn();
+
+ protected:
+  // AliHLTComponent interface functions
+  int DoInit( int argc, const char** argv );
+  int DoDeinit();
+  int DoEvent( const AliHLTComponentEventData& evtData, AliHLTComponentTriggerData& trigData);
+  int ScanConfigurationArgument(int argc, const char** argv);
+  int Reconfigure(const char* cdbEntry, const char* chainId);
+  int ReadPreprocessorValues(const char* modules);
+
+  using AliHLTProcessor::DoEvent;
+
+private:
+  /** copy constructor prohibited */
+  AliHLTTRDPreprocessorComponent(const AliHLTTRDPreprocessorComponent&);
+  /** assignment operator prohibited */
+  AliHLTTRDPreprocessorComponent& operator=(const AliHLTTRDPreprocessorComponent&);
+
+  void DbgLog(const char* prefix, ...);
+
+  // general
+  static const AliHLTEventID_t fgkInvalidEventId = 18446744073709551615llu;
+
+  UShort_t fDebugLevel;                              //! set debug checks/output level, 0: debug off
+  AliHLTEventID_t fEventId;                          //! event ID
+
+  // trd specific data
+  TClonesArray* fTrackletArray;                      //! internal tracklet array
+  TClonesArray *fGtuTrackArray;                      //! internal track array
+
+  // rawreader instance
+  AliRawReaderMemory* fRawReaderMem;                 //! TRD raw reader memory instance
+  AliTRDdigitsManager *fDigitsManagerTrd;            //! TRD digits manager instance
+  AliTRDrawStream*    fRawReaderTrd;                 //! TRD raw stream instance
+
+  AliTRDonlineTrackingDataContainer* fTrackingData;  //! internal tracking data container
+
+  ClassDef(AliHLTTRDPreprocessorComponent, 0)
+};
+
+#endif
diff --git a/HLT/TRD/AliTRDonlineTrackingDataContainer.cxx b/HLT/TRD/AliTRDonlineTrackingDataContainer.cxx
new file mode 100644 (file)
index 0000000..6adefcd
--- /dev/null
@@ -0,0 +1,645 @@
+#include <cstdlib>
+#include "TString.h"
+#include "AliHLTLogging.h"
+#include "AliTRDonlineTrackingDataContainer.h"
+
+
+ClassImp(AliTRDonlineTrackingDataContainer)
+
+const Float_t AliTRDonlineTrackingDataContainer::fgkBinWidthY   = 160e-4; // 160 um
+
+AliTRDonlineTrackingDataContainer::AliTRDonlineTrackingDataContainer() : AliHLTLogging(),
+  fGtuPtMultiplier(1.),
+  fStoreGtuInfo(kTRUE),
+  fLogPrefix(NULL)
+{
+  fLogPrefix = new TString("");
+  Clear();
+}
+
+AliTRDonlineTrackingDataContainer::AliTRDonlineTrackingDataContainer(const AliTRDonlineTrackingDataContainer& /*cont*/) : AliHLTLogging(),
+  fGtuPtMultiplier(1.),
+  fStoreGtuInfo(kTRUE),
+  fLogPrefix(NULL)
+{
+  fLogPrefix = new TString("");
+  Clear();
+}
+
+AliTRDonlineTrackingDataContainer::~AliTRDonlineTrackingDataContainer(){
+  if (fLogPrefix)
+    delete fLogPrefix;
+  fLogPrefix = NULL;
+}
+
+void AliTRDonlineTrackingDataContainer::Clear(const Option_t*) {
+  memset(fNumTracklets, 0, sizeof(UInt_t)*fgkNumChambers);
+  memset(fNumTracks, 0, sizeof(UInt_t)*fgkNumStacks);
+
+  memset(fSectorTrgWords, 0, sizeof(UInt_t)*fgkNumSectors);
+  memset(fStackTrgWords, 0, sizeof(ULong64_t)*fgkNumSectors*fgkNumStacksPerSector);
+
+  //## todo: only for debugging, may be removed without harm
+//  memset(fTrackletWords, 0, sizeof(UInt_t)*fgkNumChambers*fgkMaxTrackletsPerChamber);
+//  memset(fTrackletHCId, 0, sizeof(UInt_t)*fgkNumChambers*fgkMaxTrackletsPerChamber);
+//  memset(fTrackWords, 0, sizeof(ULong64_t)*fgkNumStacks*fgkMaxTracksPerStack);
+//  memset(fTrackExtWords, 0, sizeof(ULong64_t)*fgkNumStacks*fgkMaxTracksPerStack);
+//  memset(fTrackTrackletWords, 0, sizeof(UInt_t)*fgkNumStacks*fgkMaxTracksPerStack*fgkNumLayers);
+}
+
+Int_t AliTRDonlineTrackingDataContainer::GetNumTracklets() {
+  Int_t count = 0;
+  for (UShort_t det = 0; det < fgkNumChambers; ++det)
+    count += fNumTracklets[det];
+  return count;
+}
+
+Int_t AliTRDonlineTrackingDataContainer::GetNumTracklets(const UInt_t det) {
+  return fNumTracklets[det];
+}
+
+Int_t AliTRDonlineTrackingDataContainer::GetNumTracks() {
+  Int_t count = 0;
+  for (UShort_t stack = 0; stack < fgkNumStacks; ++stack)
+    count += fNumTracks[stack];
+  return count;
+}
+
+Int_t AliTRDonlineTrackingDataContainer::GetNumTracks(const UShort_t stack){
+  return fNumTracks[stack];
+}
+
+Int_t AliTRDonlineTrackingDataContainer::GetTrackletBinY(const UInt_t det, const UInt_t trackletIndex) {
+  UInt_t trackletWord = fTrackletWords[det][trackletIndex];
+  if (trackletWord & 0x1000) {
+    return -((~(trackletWord - 1)) & 0x1fff);
+  }
+  else {
+    return (trackletWord & 0x1fff);
+  }
+}
+
+Int_t AliTRDonlineTrackingDataContainer::GetTrackletBinDy(const UInt_t det, const UInt_t trackletIndex) {
+  UInt_t trackletWord = fTrackletWords[det][trackletIndex];
+  if (trackletWord & (1 << 19))
+    return -((~((trackletWord >> 13) - 1)) & 0x7f);
+  else
+    return ((trackletWord >> 13) & 0x7f);
+};
+
+Int_t AliTRDonlineTrackingDataContainer::GetTrackletBinZ(const UInt_t det, const UInt_t trackletIndex) {
+  return ((fTrackletWords[det][trackletIndex] >> 20) & 0xf);
+}
+
+Int_t AliTRDonlineTrackingDataContainer::GetTrackletPID(const UInt_t det, const UInt_t trackletIndex) {
+  return ((fTrackletWords[det][trackletIndex] >> 24) & 0xff);
+};
+
+Float_t AliTRDonlineTrackingDataContainer::GetTrackletLocalY(const UInt_t det, const UInt_t trackletIndex) {
+  return GetTrackletBinY(det, trackletIndex) * fgkBinWidthY;
+}
+
+AliESDTrdTracklet* AliTRDonlineTrackingDataContainer::GetTracklet(const UInt_t det, const UInt_t trackletIndex) {
+  AliESDTrdTracklet* trkl = NULL;
+  if ((det < fgkNumChambers) && (trackletIndex < fNumTracklets[det])){
+    trkl = new AliESDTrdTracklet(fTrackletWords[det][trackletIndex], fTrackletHCId[det][trackletIndex], -1);
+  }
+  return trkl;
+}
+
+AliESDTrdTrack* AliTRDonlineTrackingDataContainer::GetTrack(const UInt_t stack, const UInt_t trackIndex, const Bool_t constructTracklets){
+  AliESDTrdTrack* trk = NULL;
+  if ((stack < fgkNumStacks) && (trackIndex < fNumTracks[stack])){
+    trk = new AliESDTrdTrack();
+    ULong64_t tw = fTrackWords[stack][trackIndex];
+    ULong64_t etw = fTrackWords[stack][trackIndex];
+    trk->SetLayerMask(GetTrackLayerMask(stack, trackIndex));
+    trk->SetA(GetTrackA(stack, trackIndex));
+    trk->SetB( (((tw >> 20) & 0x3ffff) ^ 0x20000) - 0x20000);
+    trk->SetC( (((tw >> 8)  &  0xffff) ^  0x8000) -  0x8000);
+    trk->SetPID(GetTrackPID(stack, trackIndex));
+    trk->SetSector(stack/5);
+    trk->SetStack(stack%5);
+    trk->SetLabel(-3);
+    trk->SetFlags((etw >> 52) & 0x7ff);
+    trk->SetReserved((etw >> 49) & 0x7);
+    trk->SetY((etw >> 36) & 0x1fff);
+    trk->SetTrackletIndex((etw >>  0) & 0x3f, 0);
+    trk->SetTrackletIndex((etw >>  6) & 0x3f, 1);
+    trk->SetTrackletIndex((etw >> 12) & 0x3f, 2);
+    trk->SetTrackletIndex((etw >> 18) & 0x3f, 3);
+    trk->SetTrackletIndex((etw >> 24) & 0x3f, 4);
+    trk->SetTrackletIndex((etw >> 30) & 0x3f, 5);
+
+    if (constructTracklets) {
+      for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer){
+       AliESDTrdTracklet * trkl = new AliESDTrdTracklet(GetTrackTrackletWord(stack, trackIndex, iLayer), 2*(stack*6 + iLayer));
+       trk->AddTrackletReference(trkl, iLayer);
+      }
+    }
+
+  } else {
+    HLTError("invalid stack (%d) or track index (%d) in GetTrack", stack, trackIndex);
+  }
+  return trk;
+}
+
+Double_t AliTRDonlineTrackingDataContainer::GetTrackPt(const UInt_t stack, const UInt_t trackIndex){
+
+  // calculate pt from a as done in hardware
+  const Int_t maskIdLut[64] = {
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0,
+    -1, -1, -1, -1, -1, -1, -1,  1, -1, -1, -1,  2, -1,  3,  4,  5,
+    -1, -1, -1, -1, -1, -1, -1,  6, -1, -1, -1,  7, -1,  8,  9, 10,
+    -1, -1, -1, 11, -1, 12, 13, 14, -1, 15, 16, 17, 18, 19, 20, 21
+  };
+
+  const Int_t c1Lut[32] = {
+    -2371, -2474, -2474, -2474, -2563, -2448, -2578, -2578,
+    -2578, -2670, -2557, -2578, -2578, -2670, -2557, -2578,
+    -2670, -2557, -2763, -2557, -2644, -2523,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1
+  };
+
+  Int_t a = GetTrackA(stack, trackIndex);
+  UShort_t lm = GetTrackLayerMask(stack, trackIndex);
+
+  if (a != 0) {
+    Int_t layerMaskId = maskIdLut[lm];
+    Int_t c1 = c1Lut[layerMaskId];
+    Int_t c1Ext = c1 << 8;
+    Int_t ptRawStage4 = c1Ext / ((a >> 2) != 0 ? (a >> 2) : 1 );
+    Int_t ptRawComb4 = ptRawStage4;
+    Int_t ptExtComb4 = (ptRawComb4 > 0) ? ptRawComb4 + 33 : ptRawComb4 - 30;
+
+    return ((-ptExtComb4/2) / 128.) * fGtuPtMultiplier;
+  }
+  else
+    return 0.;
+
+}
+
+UShort_t AliTRDonlineTrackingDataContainer::GetTrackLayerNum(const UInt_t stack, const UInt_t trackIndex) {
+  UShort_t num = 0;
+  UShort_t layerMask = GetTrackLayerMask(stack, trackIndex);
+  for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer)
+    if ((layerMask >> iLayer) & 1)
+      num++;
+  return num;
+}
+
+UInt_t AliTRDonlineTrackingDataContainer::GetTrackTrackletWord(const UInt_t stack, const UInt_t trackIndex, const UShort_t layer) {
+  return fTrackTrackletWords[stack][trackIndex][layer];
+}
+
+
+Int_t AliTRDonlineTrackingDataContainer::GetTrackTrackletBinY(const UInt_t stack, const UInt_t trackIndex, const UShort_t layer) {
+  UInt_t trackletWord = fTrackTrackletWords[stack][trackIndex][layer];
+  if (trackletWord & 0x1000) {
+    return -((~(trackletWord - 1)) & 0x1fff);
+  }
+  else {
+    return (trackletWord & 0x1fff);
+  }
+}
+
+Int_t AliTRDonlineTrackingDataContainer::GetTrackAddInfo(const UShort_t stack, const UInt_t trackIndex) {
+  return fTrackAddInfo[stack][trackIndex];
+}
+
+Float_t AliTRDonlineTrackingDataContainer::GetTrackTrackletLocalY(const UInt_t stack, const UInt_t trackIndex, const UShort_t layer) {
+  return GetTrackTrackletBinY(stack, trackIndex, layer) * fgkBinWidthY;
+}
+
+Int_t AliTRDonlineTrackingDataContainer::GetTrackTrackletBinZ(const UInt_t stack, const UInt_t trackIndex, const UShort_t layer) {
+  return ((fTrackTrackletWords[stack][trackIndex][layer] >> 20) & 0xf);
+}
+
+UShort_t AliTRDonlineTrackingDataContainer::GetTrackTrackletPID(const UInt_t stack, const UInt_t trackIndex, const UShort_t layer) {
+  return ((fTrackTrackletWords[stack][trackIndex][layer] >> 24) & 0xff);
+}
+
+Int_t AliTRDonlineTrackingDataContainer::AddTracklet(const UInt_t HCId, const UInt_t trackletWord) {
+  UShort_t det = HCId/2;
+  Int_t pos = fNumTracklets[det]++;
+  fTrackletWords[det][pos] = trackletWord;
+  fTrackletHCId[det][pos] = HCId;
+  return pos;
+}
+
+Int_t AliTRDonlineTrackingDataContainer::AddTracklet(const AliESDTrdTracklet* tracklet) {
+  return AddTracklet(tracklet->GetHCId(), tracklet->GetTrackletWord());
+}
+
+Int_t AliTRDonlineTrackingDataContainer::AddTrack(const UShort_t stack,
+                                                 const ULong64_t trackWord, const ULong64_t extTrackWord,
+                                                 const UInt_t trackletWords[6], const Int_t addInfo){
+  Int_t pos = fNumTracks[stack]++;
+  fTrackWords[stack][pos] = trackWord;
+  fTrackExtWords[stack][pos] = extTrackWord;
+  fTrackAddInfo[stack][pos] = addInfo;
+  for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer){
+    fTrackTrackletWords[stack][pos][iLayer] = trackletWords[iLayer];
+  }
+  return pos;
+}
+
+Int_t AliTRDonlineTrackingDataContainer::AddTrack(const AliESDTrdTrack* track, const Int_t addInfo) {
+
+  UInt_t trackletWords[fgkNumLayers];
+  UShort_t lm = track->GetLayerMask();
+  Bool_t checkOk = kTRUE;
+  for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer){
+    if ((lm >> iLayer) & 1){
+      if (track->GetTracklet(iLayer))
+       trackletWords[iLayer] = track->GetTracklet(iLayer)->GetTrackletWord();
+      else
+       checkOk = kFALSE;  // inconsistency between layer mask and tracklet pointers: do not use this track
+    } else
+      trackletWords[iLayer] = fgkInvalidTrackletWord;
+  }
+
+  if (checkOk){
+    return AddTrack(track->GetSector()*5 + track->GetStack(),
+                   track->GetTrackWord(0), track->GetExtendedTrackWord(0), trackletWords, addInfo);
+  } else {
+    // DbgLog("ERROR", "Ignoring GTU track with inconsistency between layer mask and tracklet pointers");
+    printf("<ERROR> Ignoring GTU track with inconsistency between layer mask and tracklet pointers\n");
+    return -1;
+  }
+
+}
+
+void AliTRDonlineTrackingDataContainer::SetTrackAddInfo(const UShort_t stack, const UInt_t trackIndex, const Int_t addInfo) {
+  fTrackAddInfo[stack][trackIndex] = addInfo;
+}
+
+void AliTRDonlineTrackingDataContainer::SetGtuPtMultiplierFromMagField(const Double_t magField) {
+  if (magField > 0)
+    fGtuPtMultiplier = -1.;
+  else
+    fGtuPtMultiplier = 1.;
+}
+
+void AliTRDonlineTrackingDataContainer::PrintBuffer(const void* buffer, const UInt_t sizeInBytes, const char* identifier) {
+
+  UInt_t* buf = (UInt_t*)buffer;
+  UInt_t currPos = 0;
+  TString str("");
+  TString ident(identifier);
+
+  HLTDebug("BUFFER DUMP for <%s>", ident.Data());
+
+  while (currPos < sizeInBytes/4){
+
+    str = Form("%06d: 0x%08x  ", currPos, buf[currPos]);
+
+    if (currPos == 0){  // leading magic constant
+
+      if (buf[currPos++] == fgkLeadingMagicConst)
+       str += "correct leading magic constant";
+      else
+       str += Form("incorrect leading magic constant, should be 0x%08x",
+                   fgkLeadingMagicConst);
+    }
+
+    if (currPos == sizeInBytes/4 - 1){
+
+      if (buf[sizeInBytes/4 - 1] == fgkTrailingMagicConst)
+       str += "correct trailing magic constant";
+      else
+       str += Form("incorrect trailing magic constant, should be 0x%08x",
+                   fgkTrailingMagicConst);
+    }
+
+    currPos++;
+
+    HLTDebug(str.Data());
+
+  }
+
+}
+
+void AliTRDonlineTrackingDataContainer::PrintSummary(const char* identifier){
+
+  TString ident(identifier);
+
+  HLTDebug("TRDGM AliTRDonlineTrackingDataContainer <%s> summary: %5d tracklets, %2d tracks, %6ld bytes comp. mem size",
+          ident.Data(), GetNumTracklets(), GetNumTracks(), DataWordsNeeded()*sizeof(UInt_t));
+
+}
+
+inline UInt_t AliTRDonlineTrackingDataContainer::MakeDataHeader(){
+  if (fStoreGtuInfo)
+    return (fgkHeaderTypeData << 28) | (1 << 16) | DataWordsNeeded();
+  else
+    return (fgkHeaderTypeData << 28) | DataWordsNeeded();
+}
+
+inline UInt_t AliTRDonlineTrackingDataContainer::MakeStackHeader(const UShort_t stack,
+                                                                const Bool_t trackletsPresent,
+                                                                const Bool_t tracksPresent,
+                                                                const UInt_t size){
+  return
+    (fgkHeaderTypeStack << 28) |
+    (((tracksPresent) ? 1 : 0) << 27) |
+    (((trackletsPresent) ? 1 : 0) << 26) |
+    ((stack & 0xff) << 16) | (size & 0xffff);
+}
+
+inline Int_t AliTRDonlineTrackingDataContainer::StackFromStackHeader(const UInt_t stackHeader) {
+  return (stackHeader >> 16) & 0xff;
+}
+
+inline UInt_t AliTRDonlineTrackingDataContainer::SizeFromStackHeader(const UInt_t stackHeader) {
+  return stackHeader & 0xffff;
+}
+
+inline UInt_t AliTRDonlineTrackingDataContainer::MakeTrackletHeader(const UShort_t halfChamber){
+  return (fgkHeaderTypeTracklet << 28) | ((halfChamber & 0xfff) << 16) | 0x2;
+}
+
+inline Int_t AliTRDonlineTrackingDataContainer::HCIdFromTrackletHeader(const UInt_t trackletHeader) {
+  return (trackletHeader >> 16) & 0xfff;
+}
+
+inline UInt_t AliTRDonlineTrackingDataContainer::MakeTrackHeader(const UShort_t stack){
+  return (fgkHeaderTypeTrack << 28) | ((stack & 0xff) << 16) | 12;
+}
+
+inline UInt_t AliTRDonlineTrackingDataContainer::MakeGtuHeader(const Bool_t storeInfo){
+  if (storeInfo)
+    return (fgkHeaderTypeGtu << 28) | (1 << 16) | (1 + 18 + 2*90);
+  else
+    return (fgkHeaderTypeGtu << 28) | 1;
+}
+
+inline Bool_t AliTRDonlineTrackingDataContainer::StoreGtuInfoFromDataHeader(const UInt_t dataHeader){
+  return ((dataHeader >> 16) & 1);
+}
+
+inline Bool_t AliTRDonlineTrackingDataContainer::GtuInfoPresentFromGtuHeader(const UInt_t gtuHeader){
+  return ((gtuHeader >> 16) & 1);
+}
+
+inline UInt_t AliTRDonlineTrackingDataContainer::DataWordsNeeded() {
+
+  UInt_t size = 0;
+
+  size += 1;                              // leading magic word
+  size += 1;                              // overall data header
+  size += 90;                             // stack headers
+  size += GetNumTracklets()*(1 + 1);      // tracklets (mark + trackword)
+  size += GetNumTracks()*(1 + 4 + 1 + 6); // GTU tracks (mark + trackword[2] + exttrackword[2] + addInfo + 6*trackletword)
+  size += 1;                              // crosscheck word
+  size += 1;                              // trailing magic word
+
+  if (fStoreGtuInfo)
+    size += 1 + 18 + 2*90;                // trigger header + 18 sector trigger words, 90 stack tracking done words[2]
+  else
+    size += 1;                            // trigger header only
+
+  return size;
+}
+
+inline UInt_t calcCheck(const UInt_t prevCrc, const UInt_t c) {
+  // CCITT 16 bit (X^16 + X^12 + X^5 + 1).
+  UInt_t crc = prevCrc;
+  crc  = (unsigned char)(crc >> 8) | (crc << 8);
+  crc ^= c;
+  crc ^= (unsigned char)(crc & 0xff) >> 4;
+  crc ^= (crc << 8) << 4;
+  crc ^= ((crc & 0xff) << 4) << 1;
+  return (crc);
+}
+
+Bool_t AliTRDonlineTrackingDataContainer::Compress(void* &buffer, UInt_t &sizeInBytes){
+
+  // TString ptrInfo("COMPRESS CALLED: [");
+
+  UInt_t bufSize = sizeof(UInt_t)*DataWordsNeeded();
+  UInt_t* buf = (UInt_t*)malloc(bufSize);
+  UInt_t crosscheck = fgkCrosscheckSeed;
+  UInt_t lastStackHeaderPos;
+
+  if (!buf){
+    HLTError("Could not allocate %d bytes for buffer", bufSize);
+    return kFALSE;
+  }
+
+  memset(buf, 0, bufSize);
+  // ptrInfo += Form(" memset(%p, 0, %d) -> %p - %p, ", buf, bufSize, buf, (char*)buf + bufSize);
+  UInt_t currPos = 0;
+  UInt_t det;
+
+  // ptrInfo += Form(" lowest write addr: %p, ", &(buf[currPos]));
+  buf[currPos++] = fgkLeadingMagicConst;
+  buf[currPos++] = MakeDataHeader();
+  for (UShort_t iStack = 0; iStack < 90; ++iStack){
+
+    // add stack info
+    lastStackHeaderPos = currPos;
+    buf[currPos++] = MakeStackHeader(iStack, 1, 1, 0);
+
+    // add tracklet infos
+    for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer){
+      det = iStack*fgkNumLayers + iLayer;
+      for (UInt_t iTrkl = 0; iTrkl < fNumTracklets[det]; ++iTrkl){
+       buf[currPos++] = MakeTrackletHeader(fTrackletHCId[det][iTrkl]);
+       buf[currPos++] = fTrackletWords[det][iTrkl];
+      }
+    }
+
+    // add track infos
+    for (UInt_t iTrk = 0; iTrk < fNumTracks[iStack]; ++iTrk){
+      buf[currPos++] = MakeTrackHeader(iStack);
+      buf[currPos++] = fTrackWords[iStack][iTrk] & 0xffffffff;
+      buf[currPos++] = (fTrackWords[iStack][iTrk] >> 32) & 0xffffffff;
+      buf[currPos++] = fTrackExtWords[iStack][iTrk] & 0xffffffff;
+      buf[currPos++] = (fTrackExtWords[iStack][iTrk] >> 32) & 0xffffffff;
+      buf[currPos++] = fTrackAddInfo[iStack][iTrk];
+      for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer)
+       buf[currPos++] = fTrackTrackletWords[iStack][iTrk][iLayer];
+    }
+
+    buf[lastStackHeaderPos] = MakeStackHeader(iStack,
+                                             ((GetNumTracklets() > 0) ? 1 : 0),
+                                             ((GetNumTracks() > 0) ? 1 : 0),
+                                             currPos - lastStackHeaderPos); // update size  //## todo: check off-by-one issues
+
+  } // loop over all stacks
+
+  // add Gtu header info
+  buf[currPos++] = MakeGtuHeader(fStoreGtuInfo);
+  if (fStoreGtuInfo){
+    // store trigger info from GTU headers
+    for (UShort_t iSector = 0; iSector < fgkNumSectors; ++iSector)
+      buf[currPos++] = fSectorTrgWords[iSector];
+    for (UShort_t iSector = 0; iSector < fgkNumSectors; ++iSector){
+      for (UShort_t iStack = 0; iStack < fgkNumStacksPerSector; ++iStack){
+       buf[currPos++] = fStackTrgWords[iSector][iStack] & 0xffffffff;
+       buf[currPos++] = (fStackTrgWords[iSector][iStack] >> 32) & 0xffffffff;
+      }
+    }
+  }
+
+  // calc crosscheck
+  for (UInt_t ofs = 1; ofs < currPos; ++ofs)
+    crosscheck = calcCheck(crosscheck, buf[ofs]);
+
+  buf[currPos++] = crosscheck;
+  buf[currPos++] = fgkTrailingMagicConst;
+  // ptrInfo += Form(" highest write addr: %p, %d]", &(buf[currPos - 1]), (currPos-1)*4);
+
+  if (sizeof(UInt_t)*currPos != bufSize){
+    HLTError("inconsistent memory layout! (%ld %d)", sizeof(UInt_t)*currPos, bufSize);
+  }
+
+//  for (UInt_t ofs = 0; ofs < bufSize/4; ++ofs)
+//    printf("%04d: 0x%08x\n", ofs, buf[ofs]);
+
+  buffer = buf;
+  sizeInBytes = bufSize;
+
+  // DbgLog("", ptrInfo.Data());
+
+  return kFALSE;
+}
+
+Bool_t AliTRDonlineTrackingDataContainer::Decompress(const void* buffer, const UInt_t sizeInBytes, const Bool_t cumulative, const Bool_t verbose) {
+
+  // TString ptrInfo(Form("DECOMPRESS CALLED: [buf: %p, size: %d - %p - %p, ", buffer, sizeInBytes, buffer, (char*)buffer + sizeInBytes));
+
+  UInt_t* buf = (UInt_t*)buffer;
+  UInt_t currPos = 0;
+  UInt_t crosscheck = fgkCrosscheckSeed;
+  UInt_t stackHeader;
+  UInt_t gtuInfoHeader = 0;
+  Int_t stack = 0;
+  UInt_t size = 0;
+
+  if (!cumulative)
+    Clear();
+
+  if (buf[currPos++] != fgkLeadingMagicConst){
+    HLTError("invalid data: leading mark should be 0x%08x, is 0x%08x", fgkLeadingMagicConst, buf[currPos - 1]);
+    return kFALSE;
+  } else if (verbose)
+    HLTError("0x%05d: 0x%08x  correct leading mark", currPos, buf[currPos - 1]);
+
+  UInt_t overallDataHeader = buf[currPos++];
+  if ((overallDataHeader >> 28) != fgkHeaderTypeData){
+    HLTError("invalid data header: 0x%08x", overallDataHeader);
+    return kFALSE;
+  } else {
+    fStoreGtuInfo = StoreGtuInfoFromDataHeader(overallDataHeader);
+  }
+
+  if (buf[sizeInBytes/4 - 1] != fgkTrailingMagicConst){
+    HLTError("invalid data: trailing mark should be 0x%08x, is 0x%08x", fgkTrailingMagicConst, buf[sizeInBytes/4 - 1]);
+    return kFALSE;
+  } else if (verbose){
+    HLTDebug("0x%05d: 0x%08x  correct trailing mark", sizeInBytes/4 - 1, buf[sizeInBytes/4 - 1]);
+  }
+
+  while (currPos < (sizeInBytes/4) - 2) { // stack-level loop
+
+    stackHeader = buf[currPos++];
+
+    // stack header + encapsulated tracklet and track data
+    if (((stackHeader >> 28) & 0xf) == fgkHeaderTypeStack){
+      stack = StackFromStackHeader(stackHeader);
+      size = SizeFromStackHeader(stackHeader);
+
+      if (verbose){
+       HLTDebug("STACK HEADER: 0x%08x - S%02d-%d, size: %d  [checksum: 0x%08x]", stackHeader, stack/5, stack%5, size, buf[sizeInBytes/4 - 2]);
+      }
+
+      while (currPos < sizeInBytes/4 - 2){
+
+       if (((buf[currPos] >> 28) & 0xf) == fgkHeaderTypeTracklet){
+         UInt_t trklHdr = buf[currPos++];
+         UInt_t trklWord = buf[currPos++];
+         AddTracklet(HCIdFromTrackletHeader(trklHdr), trklWord);
+         if (verbose){
+           HLTDebug("Tracklet: 0x%08x 0x%08x", trklHdr, trklWord);
+         }
+       } else if (((buf[currPos] >> 28) & 0xf) == fgkHeaderTypeTrack){
+         UInt_t trkHdr = buf[currPos++];
+         if (trkHdr == 0)
+           HLTError("ERROR", "invalid track header");
+         ULong64_t trackWord = buf[currPos++];
+         trackWord |= ((ULong64_t)buf[currPos++] << 32);
+         ULong64_t extTrackWord = buf[currPos++];
+         extTrackWord |= ((ULong64_t)buf[currPos++] << 32);
+         UInt_t addInfo = buf[currPos++];
+         UInt_t trackletWords[6];
+         for (UShort_t iLayer = 0; iLayer < fgkNumLayers; ++iLayer){
+           trackletWords[iLayer] = buf[currPos++];
+         }
+         AddTrack(stack, trackWord, extTrackWord, trackletWords, addInfo);
+         if (verbose){
+           HLTDebug("GTU track: 0x%016llx 0x%016llx", trackWord, extTrackWord);
+         }
+       } else if (((buf[currPos] >> 28) & 0xf) == fgkHeaderTypeStack){
+       //printf("next stack header\n");
+         break;
+       } else if (((buf[currPos] >> 28) & 0xf) == fgkHeaderTypeGtu){
+         gtuInfoHeader = buf[currPos];
+         break;
+       } else {
+         HLTError("unknown data block: 0x%08x", buf[currPos]);
+         break;
+       }
+      }
+
+      if (gtuInfoHeader)
+       break;
+
+    } else {
+      HLTError("invalid header while analyzing tracking data block: 0x%08x - S%02d-%d, size: %d",
+                          stackHeader, stack/5, stack%5, size);
+      break;
+    }
+
+  } // stack-level loop
+
+  // GTU header data loop
+  if (((gtuInfoHeader >> 28) & 0xf) == fgkHeaderTypeGtu) {
+    UInt_t gtuHeader = buf[currPos++];
+    HLTInfo("gtu header: 0x%08x", gtuHeader);
+    if (GtuInfoPresentFromGtuHeader(gtuHeader)){
+      for (UShort_t iSector = 0; iSector < fgkNumSectors; ++iSector)
+       fSectorTrgWords[iSector] = buf[currPos++];
+      for (UShort_t iSector = 0; iSector < fgkNumSectors; ++iSector){
+       for (UShort_t iStack = 0; iStack < fgkNumStacksPerSector; ++iStack){
+         UInt_t low = buf[currPos++];
+         UInt_t high = buf[currPos++];
+         fStackTrgWords[iSector][iStack] = ((ULong64_t)high << 32) | low;
+       }
+      }
+    }
+  } else {
+    HLTError("expected GtuInfoHeader at position %d, but is 0x%08x",
+                        currPos, buf[currPos]);
+  }
+
+  if (currPos != (sizeInBytes/4) - 2){
+    HLTError("invalid read position after analyzing tracking data block.");
+    return kFALSE;
+  }
+
+  for (UInt_t ofs = 1; ofs < sizeInBytes/4 - 2; ++ofs)
+    crosscheck = calcCheck(crosscheck, buf[ofs]);
+
+  if (crosscheck != buf[sizeInBytes/4 - 2]){  // compare recalculated checksum with the one in the data
+    HLTError("decompress checksum mismatch: should be 0x%08x, is 0x%08x",
+          crosscheck, buf[sizeInBytes/4 - 2]);
+    return kFALSE;
+  }
+
+  // HLTDebug(ptrInfo.Data());
+
+  return kTRUE;
+
+}
diff --git a/HLT/TRD/AliTRDonlineTrackingDataContainer.h b/HLT/TRD/AliTRDonlineTrackingDataContainer.h
new file mode 100644 (file)
index 0000000..0dd7f24
--- /dev/null
@@ -0,0 +1,138 @@
+#ifndef ALITRDONLINETRACKINGDATACONTAINER_H
+#define ALITRDONLINETRACKINGDATACONTAINER_H
+
+#include "AliESDTrdTracklet.h"
+#include "AliESDTrdTrack.h"
+#include "AliHLTLogging.h"
+
+class AliTRDonlineTrackingDataContainer : public AliHLTLogging {
+ public:
+  AliTRDonlineTrackingDataContainer();
+  AliTRDonlineTrackingDataContainer(const AliTRDonlineTrackingDataContainer& cont);
+  ~AliTRDonlineTrackingDataContainer();
+
+  void SetLogPrefix(const char* prefix) { *fLogPrefix = prefix; };
+  void SetGtuPtMultiplier(const Double_t mult) { fGtuPtMultiplier = mult; }
+  void SetGtuPtMultiplierFromMagField(const Double_t magField);
+
+  void Clear(const Option_t* = "");
+  Int_t AddTracklet(const UInt_t HCId, const UInt_t trackletWord);
+  Int_t AddTracklet(const AliESDTrdTracklet* tracklet);
+  Int_t AddTrack(const UShort_t stack, const ULong64_t trackWord, const ULong64_t extTrackWord, const UInt_t trackletWords[6], const Int_t addInfo = -1);
+  Int_t AddTrack(const AliESDTrdTrack* track, const Int_t addInfo = -1);
+
+  void SetTrackAddInfo(const UShort_t stack, const UInt_t trackIndex, const Int_t addInfo);
+  void SetSectorTrgWord(const UShort_t sector, const UInt_t trgWord) { fSectorTrgWords[sector] = trgWord; };
+  void SetStackTrgWord(const UShort_t sector, const UShort_t stack, const ULong64_t trgWord) { fStackTrgWords[sector][stack] = trgWord; };
+
+  Int_t GetNumTracklets();
+  Int_t GetNumTracklets(const UInt_t det);
+  Int_t GetNumTracks();
+  Int_t GetNumTracks(const UShort_t stack);
+
+  Int_t GetTrackletHCId(const UInt_t det, const UInt_t trackletIndex) { return fTrackletHCId[det][trackletIndex]; };
+  Int_t GetTrackletBinY(const UInt_t det, const UInt_t trackletIndex);
+  Int_t GetTrackletBinDy(const UInt_t det, const UInt_t trackletIndex);
+  Int_t GetTrackletBinZ(const UInt_t det, const UInt_t trackletIndex);
+  Int_t GetTrackletPID(const UInt_t det, const UInt_t trackletIndex);
+  Float_t GetTrackletLocalY(const UInt_t det, const UInt_t trackletIndex);
+
+  AliESDTrdTracklet* GetTracklet(const UInt_t det, const UInt_t trackletIndex);
+  AliESDTrdTrack* GetTrack(const UInt_t stack, const UInt_t trackIndex, const Bool_t constructTracklets = kTRUE);
+  Int_t GetTrackAddInfo(const UShort_t stack, const UInt_t trackIndex);
+
+  inline Int_t GetTrackLayerMask(const UInt_t stack, const UInt_t trackIndex){
+    return (fTrackWords[stack][trackIndex] >> 56) & 0x3f;
+  }
+
+  inline Int_t GetTrackA(const UInt_t stack, const UInt_t trackIndex){
+    return (((fTrackWords[stack][trackIndex] >> 38) & 0x3ffff) ^ 0x20000) - 0x20000;
+  }
+
+  inline Int_t GetTrackPID(const UInt_t stack, const UInt_t trackIndex){
+    return fTrackWords[stack][trackIndex] & 0xff;
+  }
+
+  Double_t GetTrackPt(const UInt_t stack, const UInt_t trackIndex);
+  UShort_t GetTrackLayerNum(const UInt_t stack, const UInt_t trackIndex);
+  UInt_t GetTrackTrackletWord(const UInt_t stack, const UInt_t trackIndex, const UShort_t layer);
+  Int_t GetTrackTrackletBinY(const UInt_t stack, const UInt_t trackIndex, const UShort_t layer);
+  Float_t GetTrackTrackletLocalY(const UInt_t stack, const UInt_t trackIndex, const UShort_t layer);
+  Int_t GetTrackTrackletBinZ(const UInt_t stack, const UInt_t trackIndex, const UShort_t layer);
+  UShort_t GetTrackTrackletPID(const UInt_t stack, const UInt_t trackIndex, const UShort_t layer);
+
+  UInt_t GetSectorTrgWord(const UShort_t sector) { return fSectorTrgWords[sector]; };
+  ULong64_t GetStackTrgWord(const UShort_t sector, const UShort_t stack) { return fStackTrgWords[sector][stack]; };
+  UInt_t GetSectorTrgContribs(const UShort_t sector) { return fSectorTrgWords[sector] & 0x3ff; };
+  Float_t GetTrackletStartTime(const UShort_t sector, const UShort_t stack) { return ((fStackTrgWords[sector][stack] >> 20) & 0x3ff)*1./125.; };
+  Float_t GetTrackletEndTime(const UShort_t sector, const UShort_t stack) { return ((fStackTrgWords[sector][stack] >> 10) & 0x3ff)*1./125.; };
+  Float_t GetTMUTrackingDoneTime(const UShort_t sector, const UShort_t stack) { return ((fStackTrgWords[sector][stack] >> 0) & 0x3ff)*1./50.; };
+  Float_t GetSMUTrackingDoneTime(const UShort_t sector) { return ((fSectorTrgWords[sector] >> 12) & 0x3ff)*1./120.; };
+
+  Bool_t Compress(void* &buffer, UInt_t &sizeInBytes);
+  Bool_t Decompress(const void* buffer, const UInt_t sizeInBytes, const Bool_t cumulative = kFALSE, const Bool_t verbose = kFALSE);
+
+  void PrintBuffer(const void* buffer, const UInt_t sizeInBytes, const char* identifier);
+  void PrintSummary(const char* identifier = "none");
+
+ protected:
+
+  AliTRDonlineTrackingDataContainer& operator=(const AliTRDonlineTrackingDataContainer &rhs); // not implemented
+
+  static const unsigned int fgkLeadingMagicConst = 0x1234face;    //! header magic constant
+  static const unsigned int fgkHeaderTypeData = 0xe;              //! header type constant
+  static const unsigned int fgkHeaderTypeStack = 0xa;             //! header type constant
+  static const unsigned int fgkHeaderTypeTracklet = 0xb;          //! header type constant
+  static const unsigned int fgkHeaderTypeTrack = 0xc;             //! header type constant
+  static const unsigned int fgkHeaderTypeGtu = 0xd;               //! header type constant
+  static const unsigned int fgkCrosscheckSeed = 0xc5f3a19b;       //! crosscheck seed constant
+  static const unsigned int fgkInvalidTrackletWord = 0x10001000;  //! marking invalid tracklet word
+  static const unsigned int fgkTrailingMagicConst = 0x5678beaf;   //! trailer magic constant
+
+  static const unsigned int fgkNumLayers = 6;                     //! number of TRD layers
+  static const unsigned int fgkNumStacks = 90;                    //! number of TRD stacks
+  static const unsigned int fgkNumChambers = 540;                 //! number of TRD chambers
+  static const unsigned int fgkNumStacksPerSector = 5;            //! number of TRD stacks per sector
+  static const unsigned int fgkNumSectors = 18;                   //! number of TRD sectors
+  static const unsigned int fgkMaxTrackletsPerChamber = 1024;     //! maximum number of tracklets per chamber
+  static const unsigned int fgkMaxTracksPerStack = 32;            //! maximum number of tracks per stack
+  static const Float_t fgkBinWidthY;                              //! geometric TRD constant
+
+  Double_t fGtuPtMultiplier;                                         //! factor for sign correction
+  Bool_t fStoreGtuInfo;                                              //! controls storage of GTU header info upon compress
+  TString* fLogPrefix;                                               //! log message prefix
+
+  UInt_t fNumTracklets[fgkNumChambers];                              //! number of tracklets by chamber
+  UInt_t fTrackletWords[fgkNumChambers][fgkMaxTrackletsPerChamber];  //! tracklet words by chamber
+  UInt_t fTrackletHCId[fgkNumChambers][fgkMaxTrackletsPerChamber];   //! half-chambeer to tracklets
+
+  UInt_t fNumTracks[fgkNumStacks];                                               //! number of tracks by stack
+  ULong64_t fTrackWords[fgkNumStacks][fgkMaxTracksPerStack];                     //! track words by stack
+  ULong64_t fTrackExtWords[fgkNumStacks][fgkMaxTracksPerStack];                  //! extended track words by stack
+  UInt_t fTrackTrackletWords[fgkNumStacks][fgkMaxTracksPerStack][fgkNumLayers];  //! tracklet words by track and stack
+  Int_t fTrackAddInfo[fgkNumStacks][fgkMaxTracksPerStack];                       //! additional info to tracks by stack
+
+  UInt_t fSectorTrgWords[fgkNumSectors];                                         //! sector trigger words
+  ULong64_t fStackTrgWords[fgkNumSectors][fgkNumStacksPerSector];                //! stack trigger words (=TMU tracking done words)
+
+  UInt_t DataWordsNeeded();
+  UInt_t MakeDataHeader();
+  UInt_t MakeStackHeader(const UShort_t stack, const Bool_t trackletsPresent,
+                        const Bool_t tracksPresent, const UInt_t size);
+  UInt_t MakeTrackletHeader(const UShort_t det);
+  UInt_t MakeTrackHeader(const UShort_t stack);
+  UInt_t MakeGtuHeader(const Bool_t storeInfo);
+
+  Int_t StackFromStackHeader(const UInt_t stackHeader);
+  UInt_t SizeFromStackHeader(const UInt_t stackHeader);
+  Int_t HCIdFromTrackletHeader(const UInt_t trackletHeader);
+  Bool_t StoreGtuInfoFromDataHeader(const UInt_t dataHeader);
+  Bool_t GtuInfoPresentFromGtuHeader(const UInt_t gtuHeader);
+
+  UShort_t ExtractTrackLayerMask(const ULong64_t trackWord);
+  UShort_t ExtractTrackPID(const ULong64_t trackWord);
+
+  ClassDef(AliTRDonlineTrackingDataContainer, 1);
+};
+
+#endif
diff --git a/HLT/trigger/AliHLTTRDTriggerComponent.cxx b/HLT/trigger/AliHLTTRDTriggerComponent.cxx
new file mode 100644 (file)
index 0000000..bb1d202
--- /dev/null
@@ -0,0 +1,1857 @@
+// $Id$
+//**************************************************************************
+//* This file is property of and copyright by the ALICE HLT Project        *
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//*                                                                        *
+//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
+//*                  Jochen Thaeder <jochen@thaeder.de>                    *
+//*                  for The ALICE HLT Project.                            *
+//*                                                                        *
+//* Permission to use, copy, modify and distribute this software and its   *
+//* documentation strictly for non-commercial purposes is hereby granted   *
+//* without fee, provided that the above copyright notice appears in all   *
+//* copies and that both the copyright notice and this permission notice   *
+//* appear in the supporting documentation. The authors make no claims     *
+//* about the suitability of this software for any purpose. It is          *
+//* provided "as is" without express or implied warranty.                  *
+//**************************************************************************
+
+/// @file   AliHLTTRDTriggerComponent.cxx
+/// @author Felix Rettig, Stefan Kirsch
+/// @date   2012-08-16
+/// @brief
+
+#include <cstdlib>
+#include "TSystem.h"
+#include "TObjArray.h"
+#include "TObjString.h"
+#include "TFile.h"
+#include "TH1I.h"
+#include "TH2I.h"
+#include "AliESDtrack.h"
+#include "AliESDEvent.h"
+#include "AliHLTTRDDefinitions.h"
+#include "AliHLTTriggerDecision.h"
+#include "AliHLTDomainEntry.h"
+#include "AliHLTLogging.h"
+#include "AliHLTErrorGuard.h"
+#include "AliHLTGlobalBarrelTrack.h"
+#include "AliESDtrackCuts.h"
+//#include "AliHLTESDTrackCuts.h"
+#include "AliGeomManager.h"
+#include "AliHLTComponentBenchmark.h"
+#include "AliHLTTRDTriggerComponent.h"
+#include "AliTRDonlineTrackingDataContainer.h"
+#include "AliTRDpadPlane.h"
+
+ClassImp(AliHLTTRDTriggerComponent)
+
+#define LogError( ... ) { HLTError(__VA_ARGS__); if (fDebugLevel >= 1) { DbgLog("ERROR", __VA_ARGS__); } }
+#define LogInfo( ... ) { HLTInfo(__VA_ARGS__); if (fDebugLevel >= 1) { DbgLog("INFO", __VA_ARGS__); } }
+#define LogInspect( ... ) { HLTDebug(__VA_ARGS__); if (fDebugLevel >= 1) { DbgLog("INSPECT", __VA_ARGS__); } }
+#define LogDebug( ... ) { if (fDebugLevel >= 1) { HLTInfo(__VA_ARGS__); DbgLog("DEBUG", __VA_ARGS__); } }
+
+AliHLTTRDTriggerComponent::AliHLTTRDTriggerComponent() :
+  AliHLTTrigger(),
+  fName(),
+  fRefTrackSelectionEtaLimit(0.9),
+  fRefTrackSelectionVertexXYLimit(20.),
+  fRefTrackSelectionVertexZLimit(30.),
+  fRefTrackSelectionPtThreshold(0.7),
+  fMatchRatingThreshold(0.25),
+  fElectronTriggerPtThresholdHSE(3.),
+  fElectronTriggerPIDThresholdHSE(144),
+  fElectronTriggerPtThresholdHQU(2.),
+  fElectronTriggerPIDThresholdHQU(164),
+  fApplyRefTrackCuts(kFALSE),
+  fElectronTriggerOnL1TrgOnly(kFALSE),
+  fHistoMode(1),
+  fDebugLevel(0),
+  fExtendedHistos(kFALSE),
+  fEventRendering(kFALSE),
+  fPushHistos(kFALSE),
+  fWriteHistos(kFALSE),
+  fEventId(fgkInvalidEventId),
+  fRunNumber(-1),
+  fChunkId(NULL),
+  fSectorsWithData(0),
+  fIsMinBiasEvent(kFALSE),
+  fIsTRDElectronEvent(kFALSE),
+  fESDtracksPresent(kFALSE),
+  fHLTtracksPresent(kFALSE),
+  fTRDGeometry(NULL),
+  fEsdEvent(NULL),
+  fTrackingData(NULL),
+  fHLTTracks(NULL),
+  fRefTrackCuts(NULL),
+#ifdef __TRDHLTDEBUG
+  fEventDisplay(NULL),
+  fBenchmark(NULL),
+#endif
+  fHistArray(NULL),
+  fHistMatchRating(NULL),
+  fHistMatchRatingByPt(NULL),
+  fHistMatchRatingByPid(NULL),
+  fHistTrackPt(NULL),
+  fHistTrackPtMatched(NULL),
+  fHistTrackPtCorr(NULL),
+  fHistTrackPid(NULL),
+  fHistTrackPidMatched(NULL),
+  fHistElectronCandidatePt(NULL),
+  fHistElectronCandidateMatchedPt(NULL),
+  fHistElectronCandidatePid(NULL),
+  fHistElectronCandidateMatchedPid(NULL),
+  fHistRefTrackPid(NULL),
+  fHistMatchedRefTrackPid(NULL),
+  fHistPIDvsTruncPID(NULL),
+  fHistElectronFalsePIDvsTruncPID(NULL),
+  fHistElectronConfirmedPIDvsTruncPID(NULL),
+  fHistTrackMatchingCombinations(NULL),
+  fHistElectronTriggerBaseMinBias(NULL),
+  fHistElectronTriggerBaseTrdL1(NULL)
+{
+}
+
+const char* AliHLTTRDTriggerComponent::fgkDefaultOCDBEntry = "HLT/ConfigHLT/TRDTrigger";
+const char* AliHLTTRDTriggerComponent::fgkTriggerDecisionElectronHSE = "TRD-ELECTRON-HSE";
+const char* AliHLTTRDTriggerComponent::fgkTriggerDecisionElectronHQU = "TRD-ELECTRON-HQU";
+
+AliHLTTRDTriggerComponent::~AliHLTTRDTriggerComponent()
+{
+}
+
+const char* AliHLTTRDTriggerComponent::GetTriggerName() const
+{
+  if (!fName.IsNull())
+    return fName.Data();
+  else
+    return "TRDTriggerComponent";
+}
+
+AliHLTComponent* AliHLTTRDTriggerComponent::Spawn()
+{
+  return new AliHLTTRDTriggerComponent;
+}
+
+int AliHLTTRDTriggerComponent::DoInit(int argc, const char** argv)
+{
+  int iResult = 0;
+
+  do {
+
+    fChunkId = new TString("XXXXX");
+#ifdef __TRDHLTDEBUG
+    if (fChunkId){
+      // chunk identification for debug output
+      *fChunkId = gSystem->WorkingDirectory();
+      fChunkId->Remove(0, fChunkId->Last('/') + 1);
+      if (fChunkId->Contains("hlt_trd_comp"))
+       *fChunkId = "L";
+    } else {
+      iResult = -ENOMEM;
+      break;
+    }
+#endif
+
+    AliGeomManager::LoadGeometry();
+
+    fTRDGeometry = new AliTRDgeometry();
+    if (!fTRDGeometry) {
+      iResult = -ENOMEM;
+      break;
+    }
+
+    fTrackingData = new AliTRDonlineTrackingDataContainer();
+    if (!fTrackingData) {
+      iResult = -ENOMEM;
+      break;
+    }
+
+    fHLTTracks = new vector<AliHLTGlobalBarrelTrack>;
+    if (!fHLTTracks) {
+      iResult = -ENOMEM;
+      break;
+    }
+
+    fRefTrackCuts = new AliESDtrackCuts("AliESDtrackCuts", "No track cuts");
+    if (fRefTrackCuts){
+      // fRefTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE, 0);
+      fRefTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
+      fRefTrackCuts->SetEtaRange(-0.8, 0.8);
+    } else {
+      iResult = -ENOMEM;
+      break;
+    }
+
+    fHistArray = new TObjArray(25);
+    if(!fHistArray)
+      return -ENOMEM;
+    fHistArray->SetOwner(kTRUE);
+
+    fHistMatchRating = new TH1I("trdtrg_match_rating", "Match rating distribution HLT tracks vs. GTU track;match rating;abundance;",
+                               1./0.02, 0., 1.);
+    fHistArray->AddLast(fHistMatchRating);
+
+    fHistMatchRatingByPt = new TH2I("trdtrg_match_rating_pt", "Match rating distribution HLT tracks vs. GTU track by p_{T};match rating m;p_{T}^{TRD,online} (GeV/c)",
+                                   1./0.02, 0., 1., 20./0.02, 0., 20.);
+    fHistArray->AddLast(fHistMatchRatingByPt);
+
+    fHistMatchRatingByPid = new TH2I("trdtrg_match_rating_pid", "Match rating distribution HLT tracks vs. GTU track by PID;match rating m;PID (a.u.)",
+                                    1./0.02, 0., 1., 256, 0, 256);
+    fHistArray->AddLast(fHistMatchRatingByPid);
+
+    fHistTrackPt = new TH1I("trdtrg_track_pt", "GTU track p_{T};GTU track p_{T} (GeV/c);abundance", 200, -20, 20.);
+    fHistArray->AddLast(fHistTrackPt);
+
+    fHistTrackPtMatched = new TH1I("trdtrg_matched_track_pt", "matched GTU track p_{T};GTU track p_{T} (GeV/c);abundance", 200, -20, 20.);
+    fHistArray->AddLast(fHistTrackPtMatched);
+
+    fHistTrackPtCorr = new TH2I("trdtrg_track_pt_corr", "HLT vs. GTU track p_{T};p_{T}^{HLT} (GeV/c);p_{T}^{GTU} (GeV/c)",
+              400, -40., 40., 400, -40., 40.);
+    fHistArray->AddLast(fHistTrackPtCorr);
+
+    fHistTrackPid = new TH1I("trdtrg_track_pid", "GTU track PID;GTU track PID (a.u.);abundance", 256, 0, 256);
+    fHistArray->AddLast(fHistTrackPid);
+
+    fHistTrackPidMatched = new TH1I("trdtrg_matched_track_pid", "matched GTU track PID;GTU track PID (a.u.);abundance", 256, 0, 256);
+    fHistArray->AddLast(fHistTrackPidMatched);
+
+    fHistTrackMatchingCombinations = new TH2I("trdtrg_matching_combinations", "HLT-GTU track matching combinations;set;combinations to check;",
+                                             10, 0, 10, 2000, 0, 10000);
+    fHistArray->AddLast(fHistTrackMatchingCombinations);
+
+    fHistElectronTriggerBaseMinBias = new TH1I("trdtrg_electron_trigger_base_mb", "min. bias base numbers for electron trigger analysis;set;abundance;",
+                                             10, 0, 10);
+    fHistElectronTriggerBaseMinBias->GetXaxis()->SetBinLabel(1, "min. bias events");
+    fHistElectronTriggerBaseMinBias->GetXaxis()->SetBinLabel(2, "TRD L1 electron triggered");
+    fHistElectronTriggerBaseMinBias->GetXaxis()->SetBinLabel(3, "TRD HLT electron triggered");
+    fHistArray->AddLast(fHistElectronTriggerBaseMinBias);
+
+    fHistElectronTriggerBaseTrdL1 = new TH1I("trdtrg_electron_trigger_base_l1", "TRD L1 base numbers for electron trigger analysis;set;abundance;",
+                                             10, 0, 10);
+    fHistElectronTriggerBaseTrdL1->GetXaxis()->SetBinLabel(1, "TRD L1 electron triggered");
+    fHistElectronTriggerBaseTrdL1->GetXaxis()->SetBinLabel(2, "TRD HLT electron triggered");
+    fHistArray->AddLast(fHistElectronTriggerBaseTrdL1);
+
+    fHistElectronCandidatePt = new TH1I("trdtrg_electron_candidate_pt", "GTU electron candidate p_{T};GTU track p_{T} (GeV/c);abundance", 200, -20, 20.);
+    fHistArray->AddLast(fHistElectronCandidatePt);
+
+    fHistElectronCandidateMatchedPt = new TH1I("trdtrg_electron_candidate_matched_pt", "matching GTU electron candidate p_{T};GTU track p_{T} (GeV/c);abundance", 200, -20, 20.);
+    fHistArray->AddLast(fHistElectronCandidateMatchedPt);
+
+    fHistElectronCandidatePid = new TH1I("trdtrg_electron_candidate_pid", "GTU electron candidate PID;GTU track PID (a.u.);abundance", 256, 0, 256);
+    fHistArray->AddLast(fHistElectronCandidatePid);
+
+    fHistElectronCandidateMatchedPid = new TH1I("trdtrg_electron_candidate_matched_pid", "matching GTU electron candidate PID;GTU track PID (a.u.);abundance", 256, 0, 256);
+    fHistArray->AddLast(fHistElectronCandidateMatchedPid);
+
+  } while (0);
+
+  if (iResult < 0){
+
+    if (fHistArray) delete fHistArray;
+    fHistArray = NULL;
+
+    if (fTRDGeometry) delete fTRDGeometry;
+    fTRDGeometry = NULL;
+
+    if (fRefTrackCuts) delete fRefTrackCuts;
+    fRefTrackCuts = NULL;
+
+    if (fHLTTracks) delete fHLTTracks;
+    fHLTTracks = NULL;
+
+    if (fTrackingData) delete fTrackingData;
+    fTrackingData = NULL;
+
+    if (fChunkId) delete fChunkId;
+    fChunkId = NULL;
+
+  }
+
+  // check if the -triggername argument is used, the trigger name determines the following initialization
+  vector<const char*> remainingArgs;
+  for (int i = 0; i < argc; ++i) {
+    if (strcmp(argv[i], "-triggername") == 0) {
+      if (++i < argc){
+       fName = argv[i];
+      } else {
+       LogError("invalid parameter for argument '-triggername', string expected");
+       return -EINVAL;
+      }
+      continue;
+    }
+    remainingArgs.push_back(argv[i]);
+  }
+
+  TString cdbPath;
+  if (!fName.IsNull()) {
+    cdbPath = "HLT/ConfigHLT/";
+    cdbPath += fName;
+  } else {
+    cdbPath = fgkDefaultOCDBEntry;
+  }
+
+  LogInfo("cdbPath = <%s>", cdbPath.Data());
+  iResult = ConfigureFromCDBObject(cdbPath);
+
+  if (iResult >= 0 && argc > 0)
+    iResult = ConfigureFromArgumentString(remainingArgs.size(), &(remainingArgs[0]));
+
+  return iResult;
+}
+
+int AliHLTTRDTriggerComponent::DoDeinit()
+{
+
+#ifdef __TRDHLTDEBUG
+  if (fEventDisplay) delete fEventDisplay;
+  fEventDisplay = NULL;
+#endif
+
+  if ((fHistoMode == 1) && (fWriteHistos)){
+    TFile out("trg_out/trg_hists.root", "RECREATE");
+    if (!out.IsZombie()) {
+      out.cd();
+      UInt_t numHists = fHistArray->GetEntries();
+      for (UInt_t iHist = 0; iHist < numHists; ++iHist)
+       if (fHistArray->At(iHist))
+         fHistArray->At(iHist)->Write();
+      out.Close();
+    }
+  }
+
+  if (fHistArray) delete fHistArray;
+  fHistArray = NULL;
+
+  if (fRefTrackCuts) delete fRefTrackCuts;
+  fRefTrackCuts = NULL;
+
+  if (!fHLTTracks) delete fHLTTracks;
+  fHLTTracks = NULL;
+
+  if (fTrackingData) delete fTrackingData;
+  fTrackingData = NULL;
+
+  if (fTRDGeometry) delete fTRDGeometry;
+  fTRDGeometry = NULL;
+
+  if (fChunkId) delete fChunkId;
+  fChunkId = NULL;
+
+  return 0;
+}
+
+int AliHLTTRDTriggerComponent::Reconfigure(const char* cdbEntry, const char* /*chainId*/)
+{
+  TString cdbPath;
+  if (!cdbEntry || cdbEntry[0] == 0) {
+    if (!fName.IsNull()) {
+      cdbPath = "HLT/ConfigHLT/";
+      cdbPath += fName;
+    } else {
+      cdbPath = fgkDefaultOCDBEntry;
+    }
+  } else
+    cdbPath = cdbEntry;
+
+  return ConfigureFromCDBObject(cdbPath);
+}
+
+int AliHLTTRDTriggerComponent::ReadPreprocessorValues(const char* /*modules*/)
+{
+  return 0;
+}
+
+Int_t AliHLTTRDTriggerComponent::ConfigureFromCDBObject(TString /*cdbPath*/)
+{
+  return 0;
+}
+
+int AliHLTTRDTriggerComponent::ScanConfigurationArgument(int argc, const char** argv)
+{
+
+  if (argc <= 0)
+    return 0;
+
+  UShort_t iArg = 0;
+  TString argument(argv[iArg]);
+
+  if (!argument.CompareTo("-match-sel-eta")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fRefTrackSelectionEtaLimit = argument.Atof();
+    LogInfo("ref track selection eta limit set to %.1f.", fRefTrackSelectionEtaLimit);
+    return 2;
+  }
+
+  if (!argument.CompareTo("-match-sel-vxy")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fRefTrackSelectionVertexXYLimit = argument.Atof();
+    LogInfo("ref track selection vertex xy limit set to %.1f.", fRefTrackSelectionVertexXYLimit);
+    return 2;
+  }
+
+  if (!argument.CompareTo("-match-sel-vz")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fRefTrackSelectionVertexZLimit = argument.Atof();
+    LogInfo("ref track selection vertex z limit set to %.1f.", fRefTrackSelectionVertexZLimit);
+    return 2;
+  }
+
+  if (!argument.CompareTo("-match-sel-pt")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fRefTrackSelectionPtThreshold = argument.Atof();
+    LogInfo("ref track selection pt threshold set to %.1f GeV/c.", fRefTrackSelectionPtThreshold);
+    return 2;
+  }
+
+  if (!argument.CompareTo("-match-rating")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fMatchRatingThreshold = argument.Atof();
+    LogInfo("match rating threshold set to %.2f GeV/c.", fMatchRatingThreshold);
+    return 2;
+  }
+
+  if (!argument.CompareTo("-histo-mode")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fHistoMode = argument.Atoi();
+    LogInfo("histo mode set to %d", fHistoMode);
+    return 2;
+  }
+
+  if (!argument.CompareTo("-trghse")){
+    LogInfo("TRD HLT electron trigger HSE enabled.");
+    return 1;
+  }
+
+  if (!argument.CompareTo("-hse-pt")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fElectronTriggerPtThresholdHSE = argument.Atof();
+    LogInfo("pt threshold for HSE trigger set to %.1f GeV/c.", fElectronTriggerPtThresholdHSE);
+    return 2;
+  }
+
+  if (!argument.CompareTo("-hse-pid")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fElectronTriggerPIDThresholdHSE = argument.Atof();
+    LogInfo("PID threshold for HSE trigger set to %d.", fElectronTriggerPIDThresholdHSE);
+    return 2;
+  }
+
+  if (!argument.CompareTo("-trghqu")){
+    LogInfo("TRD HLT electron trigger HQU enabled.");
+    return 1;
+  }
+
+  if (!argument.CompareTo("-hqu-pt")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fElectronTriggerPtThresholdHQU = argument.Atof();
+    LogInfo("pt threshold for HQU trigger set to %.1f GeV/c.", fElectronTriggerPtThresholdHQU);
+    return 2;
+  }
+
+  if (!argument.CompareTo("-hqu-pid")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fElectronTriggerPIDThresholdHQU = argument.Atof();
+    LogInfo("PID threshold for HQU trigger set to %.1f GeV/c.", fElectronTriggerPIDThresholdHQU);
+    return 2;
+  }
+
+  if (!argument.CompareTo("-l1-only")){
+    LogInfo("evaluation of electron trigger only for events with TRD L1 electron trigger enabled.");
+    fElectronTriggerOnL1TrgOnly = kTRUE;
+    return 1;
+  }
+
+  if (!argument.CompareTo("-histo-ext")){
+    LogInfo("extended histogramming enabled.");
+    fExtendedHistos = kTRUE; // enable extended histogramming, for debugging/tuning only!
+
+    if (!fHistRefTrackPid){
+      fHistRefTrackPid = new TH2I("trdtrg_reftrack_pid", "TPC dE/dx by p_{T} for matching GTU tracks;p_{T} (GeV/c);dE/dx (a. u.)",
+                                 500, 0., 10., 500, 0., 500);
+      fHistArray->AddLast(fHistRefTrackPid);
+    }
+
+    if (!fHistMatchedRefTrackPid){
+      fHistMatchedRefTrackPid = new TH2I("trdtrg_matched_reftrack_pid", "TPC dE/dx by p_{T} for matching GTU tracks;p_{T} (GeV/c);dE/dx (a. u.)",
+                                        500, 0., 10., 500, 0., 500);
+      fHistArray->AddLast(fHistMatchedRefTrackPid);
+    }
+
+    if (!fHistPIDvsTruncPID){
+      fHistPIDvsTruncPID = new TH2I("trdtrg_pid_trunc_pid", "GTU track PID vs. truncated PID;PID (a.u.);truncated PID (a. u.)",
+                                   256, 0., 256., 256, 0., 256.);
+      fHistArray->AddLast(fHistPIDvsTruncPID);
+    }
+
+    if (!fHistElectronFalsePIDvsTruncPID){
+      fHistElectronFalsePIDvsTruncPID = new TH2I("trdtrg_electron_false_pid_trunc_pid", "false electron PID vs. truncated PID;PID (a.u.);truncated PID (a. u.)",
+                                                256, 0., 256., 256, 0., 256.);
+      fHistArray->AddLast(fHistElectronFalsePIDvsTruncPID);
+    }
+
+    if (!fHistElectronConfirmedPIDvsTruncPID){
+      fHistElectronConfirmedPIDvsTruncPID = new TH2I("trdtrg_electron_confirmed_pid_trunc_pid", "confirmed electron PID vs. truncated PID;PID (a.u.);truncated PID (a. u.)",
+                                                    256, 0., 256., 256, 0., 256.);
+      fHistArray->AddLast(fHistElectronConfirmedPIDvsTruncPID);
+    }
+
+    return 1;
+  }
+
+  if (!argument.CompareTo("-ref-cuts")){
+    LogInfo("ref track cuts for matching enabled.");
+    fApplyRefTrackCuts = kTRUE;
+    return 1;
+  }
+
+  if (!argument.CompareTo("-push-histograms")){
+    LogInfo("pushing of histograms enabled.");
+    fPushHistos = kTRUE; // enable histogram pushing, for debugging/tuning only!
+    return 1;
+  }
+
+  if (!argument.CompareTo("-write-histograms")){
+    LogInfo("writing of histograms enabled.");
+    fWriteHistos = kTRUE; // enable histogram writing, for debugging/tuning only!
+    return 1;
+  }
+
+  if (!argument.CompareTo("-render")){
+#ifdef __TRDHLTDEBUG
+    LogInfo("rendering of interesting events enabled.");
+    if (!fEventDisplay)
+      fEventDisplay = new AliTRDtrackingEventDisplay();
+      LogInfo("event rendering activated. this is for debugging only!");
+    fEventRendering = kTRUE; // enable event rendering, for debugging/tuning only!
+#endif
+    return 1;
+  }
+
+  if (!argument.CompareTo("-debug")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fDebugLevel = argument.Atoi();
+    LogInfo("debug level set to %d.", fDebugLevel);
+    return 2;
+  }
+
+  if (!argument.CompareTo("-ref-pt")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    Float_t minPt, maxPt;
+    fRefTrackCuts->GetPtRange(minPt, maxPt);
+    maxPt = argument.Atof();
+    fRefTrackCuts->SetPtRange(minPt, maxPt);
+    LogInfo("ref track pt range set to %.1f .. %.1f GeV/c.", minPt, maxPt);
+    return 2;
+  }
+
+  if (!argument.CompareTo("-ref-tdca")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fRefTrackCuts->SetMaxDCAToVertexXY(argument.Atof());
+    LogInfo("ref track DCA transverse threshold set to %.3f", argument.Atof());
+    return 2;
+  }
+
+  if (!argument.CompareTo("-ref-ldca")){
+    if (++iArg >= argc) return -EPROTO;
+    argument = argv[iArg];
+    fRefTrackCuts->SetMaxDCAToVertexZ(argument.Atof());
+    LogInfo("ref track longitudinal DCA threshold set to %.3f", argument.Atof());
+    return 2;
+  }
+
+  return 1;
+}
+
+void AliHLTTRDTriggerComponent::ScanTriggerClasses(const char* firedTriggerClasses) {
+
+  fIsMinBiasEvent = kFALSE;
+
+  TString trg(firedTriggerClasses);
+  if (trg.Index("CINT7WU-S-NOPF-ALL") >= 0)
+    fIsMinBiasEvent = kTRUE;
+
+  if (trg.Index("CINT8WU-S-NOPF-ALL") >= 0)
+    fIsMinBiasEvent = kTRUE;
+
+}
+
+Bool_t AliHLTTRDTriggerComponent::CheckRefTrackCuts(AliESDtrack* track){
+
+  // cuts by cut class
+  if (fApplyRefTrackCuts)
+    return fRefTrackCuts->AcceptTrack(track) ? kTRUE : kFALSE;
+
+  // simple custom cuts
+  Float_t dcaToVertexXY, dcaToVertexZ;
+  track->GetImpactParametersTPC(dcaToVertexXY, dcaToVertexZ);
+  // LogDebug("IMPACT TPC %.4f  %.4f", dcaToVertexXY, dcaToVertexZ);
+
+  if ((dcaToVertexXY > fRefTrackSelectionVertexXYLimit) || (dcaToVertexZ >= fRefTrackSelectionVertexZLimit))
+    return kFALSE;
+
+  if (TMath::Abs(track->Eta()) > fRefTrackSelectionEtaLimit)
+    return kFALSE;
+
+  return kTRUE;
+}
+
+
+void AliHLTTRDTriggerComponent::DbgLog(const char* prefix, ...){
+#ifdef __TRDHLTDEBUG
+  AliHLTEventID_t eventNumber = fEventId;
+  printf("TRDHLTGM %s-%s-%s: [TRG] %s",
+        (fRunNumber >= 0) ? Form("%06d", fRunNumber) : "XXXXXX",
+        fChunkId->Data(),
+        (eventNumber != fgkInvalidEventId) ? Form("%05llu", eventNumber) : "XXXXX",
+        (strlen(prefix) > 0) ? Form("<%s> ", prefix) : "");
+#endif
+  va_list args;
+  va_start(args, prefix);
+  char* fmt = va_arg(args, char*);
+  vprintf(fmt, args);
+  printf("\n");
+  va_end(args);
+}
+
+int AliHLTTRDTriggerComponent::PrepareESDData(){
+
+  int result = 0;
+  fESDtracksPresent = kFALSE;
+
+  // check access to ESD event data
+  const TObject* obj = GetFirstInputObject(kAliHLTAllDataTypes, "AliESDEvent");
+  fEsdEvent = dynamic_cast<AliESDEvent*>(const_cast<TObject*>(obj));
+
+  if (fEsdEvent) {
+    fEsdEvent->GetStdContent();
+    fRunNumber = fEsdEvent->GetRunNumber();
+    fESDtracksPresent = kTRUE;
+    unsigned int numTracks = fEsdEvent->GetNumberOfTracks();
+
+    // process trigger classes
+    ScanTriggerClasses(fEsdEvent->GetFiredTriggerClasses().Data());
+
+    LogDebug("ESD event data: %d ESD tracks [event num: %d] [minbias: %d (fired:%s)]",
+                   numTracks, fEsdEvent->GetEventNumberInFile(), fIsMinBiasEvent, fEsdEvent->GetFiredTriggerClasses().Data());
+
+    // process ESD tracks
+    if ((fDebugLevel >= 2) || fExtendedHistos){
+      AliESDtrack* esdTrack;
+      TString paramStr("");
+      for (unsigned int iTrack = 0; iTrack < numTracks; ++iTrack) {
+       esdTrack = fEsdEvent->GetTrack(iTrack);
+
+       if (fExtendedHistos){
+         fHistRefTrackPid->Fill(esdTrack->Pt(), esdTrack->GetTPCsignal());
+       }
+
+       if (fDebugLevel >= 2){
+         paramStr = "";
+         if (esdTrack){
+
+           if (esdTrack->GetInnerParam())
+             paramStr += "I";
+
+           if (esdTrack->GetOuterParam())
+             paramStr += "O";
+
+           LogDebug("ESD track %4d - pt: %+.2fGeV/c  [params: S%s]", iTrack, esdTrack->GetSignedPt(), paramStr.Data());
+         } else
+           LogError("ESD data for track %d invalid", iTrack);
+       }
+
+      } // loop over ESD tracks
+    }
+
+    fTrackingData->SetGtuPtMultiplierFromMagField(fEsdEvent->GetMagneticField()); // used for sign correction
+
+    result = 1;
+
+  }
+
+  return result;
+
+}
+
+int AliHLTTRDTriggerComponent::PrepareHLTData(){
+
+  int iResult = 0;
+  UInt_t numHLTTracks = 0;
+  fHLTtracksPresent = kFALSE;
+
+  if (!fHLTTracks){
+    LogError("HLT track vector instance not available.");
+    return 0;
+  }
+
+  fHLTTracks->clear();
+
+  for (const AliHLTComponentBlockData *pBlock = GetFirstInputBlock(kAliHLTDataTypeTrack | kAliHLTDataOriginTPC);
+       pBlock != NULL; pBlock = GetNextInputBlock()) {
+    LogDebug("#hlttrk - data block with HLT raw tracks received");
+    fHLTtracksPresent = kTRUE;
+
+    // vector<AliHLTGlobalBarrelTrack> hltTracks;
+    if ((iResult = AliHLTGlobalBarrelTrack::ConvertTrackDataArray(reinterpret_cast<const AliHLTTracksData*>(pBlock->fPtr), pBlock->fSize, *fHLTTracks)) >= 0) {
+      for (vector<AliHLTGlobalBarrelTrack>::iterator element = fHLTTracks->begin();
+          element != fHLTTracks->end(); element++) {
+
+       numHLTTracks++;
+       //## AliHLTGlobalBarrelTrack -> AliKalmanTrack -> AliExternalTrackParam
+
+      } // loop over HLT tracks
+    }
+  } // loop over data blocks
+
+  LogDebug("#hlttrk - %d HLT raw tracks found", numHLTTracks);
+
+  return iResult;
+
+}
+
+int AliHLTTRDTriggerComponent::PrepareTRDData() {
+
+  int result = 1;
+
+  fSectorsWithData = 0;
+  fTrackingData->Clear();
+  for (const AliHLTComponentBlockData* datablock = GetFirstInputBlock(AliHLTTRDDefinitions::fgkOnlineDataType);
+       datablock != NULL;
+       datablock = GetNextInputBlock())
+    {
+      fSectorsWithData |= datablock->fSpecification;
+      fTrackingData->Decompress(datablock->fPtr, datablock->fSize, kTRUE);
+    }
+
+  fTrackingData->SetGtuPtMultiplierFromMagField(GetBz()); // used for sign correction
+
+  fTrackingData->PrintSummary("trigger component");
+
+  return result;
+
+}
+
+int AliHLTTRDTriggerComponent::MatchTRDTracksESD(){
+
+  if (!fEsdEvent) {
+    LogError("ESD event data not available in MatchTRDTracks().");
+    return 0;
+  }
+
+  if (fHistoMode == 0){
+    UInt_t numHists = fHistArray->GetEntries();
+    for (UInt_t iHist = 0; iHist < numHists; ++iHist)
+      if (fHistArray->At(iHist))
+       dynamic_cast<TH1*>(fHistArray->At(iHist))->Reset();
+  }
+
+  int result = 1;
+  unsigned int numRefTracks = fEsdEvent->GetNumberOfTracks();
+  unsigned int numGtuTracks;
+  Int_t refTrackIndices[fkMaxRefTracksPerStack];
+  UInt_t refTrackCount = 0;
+  Bool_t isRelevant;
+  Double_t distY, distZ;
+  Double_t matchRating;
+  Double_t bestMatchRating;
+  Int_t bestMatchRefIndex;
+  AliESDtrack* refTrack = NULL;
+  UInt_t numComparisonsDone = 0;
+  UInt_t numUnmatchedTracks = 0;
+  UInt_t numMatchedTracks = 0;
+  Double_t magField = fEsdEvent->GetMagneticField();
+
+  for (UShort_t iStack = 0; iStack < fkTRDStacks; ++iStack) {
+    numGtuTracks = fTrackingData->GetNumTracks(iStack);
+    refTrackCount = 0;
+
+    // preselect ESD relevant ESD tracks
+    for (UInt_t iRefTrack = 0; iRefTrack < numRefTracks; ++iRefTrack) {
+      refTrack = fEsdEvent->GetTrack(iRefTrack);
+      isRelevant = (refTrack->Pt() >= fRefTrackSelectionPtThreshold); //## implement properly
+      if (isRelevant){
+       if (refTrackCount < fkMaxRefTracksPerStack)
+         refTrackIndices[refTrackCount++] = iRefTrack;
+       else {
+         LogError("number of HLT tracks exceeding limit of %d. Skipping some tracks.", fkMaxRefTracksPerStack);
+         break;
+       }
+      }
+    }
+
+    // try to match GTU track with ref tracks
+    for (UInt_t iGtuTrack = 0; iGtuTrack < numGtuTracks; ++iGtuTrack) {
+      bestMatchRating = 0.;
+      bestMatchRefIndex = -1;
+      Double_t gpt = fTrackingData->GetTrackPt(iStack, iGtuTrack);
+      UShort_t gpid = fTrackingData->GetTrackPID(iStack, iGtuTrack);
+      UShort_t layerMask = fTrackingData->GetTrackLayerMask(iStack, iGtuTrack);
+
+      Float_t trklLocalY[fkTRDLayers];
+      Int_t trklBinZ[fkTRDLayers];
+      for (UShort_t iLayer = 0; iLayer < fkTRDLayers; ++iLayer){
+       if ((layerMask >> iLayer) & 1){
+         trklLocalY[iLayer] = fTrackingData->GetTrackTrackletLocalY(iStack, iGtuTrack, iLayer);
+         trklBinZ[iLayer] = fTrackingData->GetTrackTrackletBinZ(iStack, iGtuTrack, iLayer);
+       }
+      }
+
+      for (UInt_t iRefTrack = 0; iRefTrack < refTrackCount; ++iRefTrack) {
+       refTrack = fEsdEvent->GetTrack(refTrackIndices[iRefTrack]);
+
+//     if (!CheckRefTrackCuts(refTrack))
+//       continue;
+
+       numComparisonsDone++;
+
+//     if ((!refTrack->GetOuterParam()) && (!refTrack->GetInnerParam()))  // use tracks with TPC outer param only (all HLT tracks have it anyways)
+//       continue;
+
+       Int_t distRes = EstimateTrackDistance(refTrack, iStack, layerMask, trklLocalY, trklBinZ,
+                                             magField, &distY, &distZ);
+
+       if (fDebugLevel >= 3){
+         printf("CHECKMATCH = %i   distY %.2f   distZ %.2f   pt: %.2f   %.2f\n",
+               distRes, distY, distZ, gpt, refTrack->GetSignedPt());
+       }
+
+       if (distRes == 0){
+         matchRating = RateTrackMatch(distY, distZ, gpt, refTrack->GetSignedPt());
+       } else {
+         matchRating = 0.;
+       }
+
+       if ((matchRating >= fMatchRatingThreshold) && (matchRating > bestMatchRating)) {
+         bestMatchRefIndex = refTrackIndices[iRefTrack];
+         bestMatchRating = matchRating;
+       } else if (matchRating > bestMatchRating)
+         bestMatchRating = matchRating;
+
+//     DbgLog("", Form("#match - comparing GTU track %d in S%02d-%d with ref track %d: [gpt: %+5.2f rpt: %+5.2f] dy: %.1f dz: %.1f rating: %.1f",
+//                     iGtuTrack, iStack/5, iStack%5, refTrackIndices[iRefTrack],
+//                     fTrackingData->GetTrackPt(iStack, iGtuTrack), refTrack->GetSignedPt(),
+//                     distY, distZ, matchRating));
+
+      } // loop over ref tracks in stack
+
+      fHistMatchRating->Fill(bestMatchRating);
+      fHistMatchRatingByPt->Fill(bestMatchRating, TMath::Abs(gpt));
+      fHistMatchRatingByPid->Fill(bestMatchRating, gpid);
+      fHistTrackPt->Fill(gpt);
+      fHistTrackPid->Fill(gpid);
+
+      if (fExtendedHistos){
+       fHistMatchedRefTrackPid->Fill(refTrack->Pt(), refTrack->GetTPCsignal());
+      }
+
+      if (bestMatchRefIndex >= 0){
+       // GTU track has matching reference track
+       refTrack = fEsdEvent->GetTrack(bestMatchRefIndex);
+       Double_t rpt = refTrack->GetSignedPt();
+       LogDebug("#match - match found: rating %.2f, gpt: %+5.2f, rpt: %+5.2f (%i) -> diff: %.2f%%",
+                           bestMatchRating,gpt, rpt, bestMatchRefIndex, (gpt - rpt)/rpt*100.);
+       fTrackingData->SetTrackAddInfo(iStack, iGtuTrack, bestMatchRefIndex);
+       if (fDebugLevel >= 3){
+         LogDebug("#match-info rating: %.2f gpt: %+.2f  matchref: %d  rpt: %+.2f       gpid: %d  S%02d-%d %d   rpid: %.3f",
+                         bestMatchRating, gpt, bestMatchRefIndex, rpt, gpid,
+                         iStack/5, iStack%5, iGtuTrack, refTrack->GetTPCsignal());
+       }
+       numMatchedTracks++;
+
+       fHistTrackPtMatched->Fill(gpt);
+       fHistTrackPtCorr->Fill(rpt, gpt);
+       fHistTrackPidMatched->Fill(gpid);
+
+      } else {
+       if (fDebugLevel >= 3){
+         LogDebug("#match-info rating: %.2f gpt: %+.2f  no ref matching  gpid: %d  S%02d-%d %d",
+                         bestMatchRating, gpt, gpid,
+                         iStack/5, iStack%5, iGtuTrack);
+       }
+       numUnmatchedTracks++;
+      }
+
+    } // loop over gtu tracks in stack
+
+  } // loop over stacks
+
+  LogInfo("#match - %d matched GTU tracks, %d unmatched",
+                     numMatchedTracks, numUnmatchedTracks);
+
+  fHistTrackMatchingCombinations->Fill(0., (Double_t)(numRefTracks * fTrackingData->GetNumTracks()));  // index 0: full combinatorics
+  fHistTrackMatchingCombinations->Fill(1., numComparisonsDone);  // index 1: track matching comparisons actually done
+
+  return result;
+
+}
+
+int AliHLTTRDTriggerComponent::MatchTRDTracksHLT(){
+
+  if (!fHLTTracks){
+    LogError("HLT track data available.");
+    return 0;
+  }
+
+  Double_t magField = GetBz();
+  unsigned int numGtuTracks;
+  unsigned int numHLTTracks = 0;
+  Bool_t isRelevant;
+  Double_t distY, distZ;
+  Double_t matchRating;
+  Double_t bestMatchRating;
+  Int_t bestMatchRefIndex;
+  UInt_t numComparisonsDone = 0;
+  UInt_t numUnmatchedTracks = 0;
+  UInt_t numMatchedTracks = 0;
+
+  Bool_t hltTrackPreSel[fkMaxRefTracks];
+  UInt_t iHltTrack;
+
+  for (UShort_t iStack = 0; iStack < fkTRDStacks; ++iStack) {
+    numGtuTracks = fTrackingData->GetNumTracks(iStack);
+
+    // preselect relevant HLT tracks
+    iHltTrack = 0;
+    for (vector<AliHLTGlobalBarrelTrack>::iterator element = fHLTTracks->begin();
+        element != fHLTTracks->end(); element++) {
+      numHLTTracks++;
+      isRelevant = (element->Pt() >= fRefTrackSelectionPtThreshold); //## implement properly
+
+      //## use cuts here
+      hltTrackPreSel[iHltTrack++] = isRelevant;
+      if (iHltTrack >= fkMaxRefTracks)
+       LogError("maximum number of HLT tracks exceeded.");
+    } // loop over HLT tracks;
+
+    // search for matching HLT track for each GTU track
+    for (UInt_t iGtuTrack = 0; iGtuTrack < numGtuTracks; ++iGtuTrack) {
+      bestMatchRating = 0.;
+      bestMatchRefIndex = -1;
+      Double_t gpt = fTrackingData->GetTrackPt(iStack, iGtuTrack);
+      UShort_t gpid = fTrackingData->GetTrackPID(iStack, iGtuTrack);
+      UShort_t layerMask = fTrackingData->GetTrackLayerMask(iStack, iGtuTrack);
+
+      Float_t trklLocalY[fkTRDLayers];
+      Int_t trklBinZ[fkTRDLayers];
+      for (UShort_t iLayer = 0; iLayer < fkTRDLayers; ++iLayer){
+       if ((layerMask >> iLayer) & 1){
+         trklLocalY[iLayer] = fTrackingData->GetTrackTrackletLocalY(iStack, iGtuTrack, iLayer);
+         trklBinZ[iLayer] = fTrackingData->GetTrackTrackletBinZ(iStack, iGtuTrack, iLayer);
+       }
+      }
+
+      iHltTrack = 0;
+      for (vector<AliHLTGlobalBarrelTrack>::iterator element = fHLTTracks->begin();
+          element != fHLTTracks->end(); element++) {
+       if (!hltTrackPreSel[iHltTrack]){
+         iHltTrack++;
+         continue;
+       }
+
+       // compare GTU track and relevant HLT track
+       numComparisonsDone++;
+
+       AliHLTGlobalBarrelTrack hltPar(*element);
+       Int_t distRes = EstimateTrackDistance(&hltPar, iStack, layerMask, trklLocalY, trklBinZ,
+                                              magField, &distY, &distZ);
+
+       if (fDebugLevel >= 3){
+         printf("CHECKMATCH = %i   distY %.2f   distZ %.2f   pt: %.2f   %.2f\n",
+                distRes, distY, distZ, gpt, element->GetSignedPt());
+       }
+
+       if (distRes == 0){
+         matchRating = RateTrackMatch(distY, distZ, gpt, element->GetSignedPt());
+       } else {
+         matchRating = 0.;
+       }
+
+       if ((matchRating >= fMatchRatingThreshold) && (matchRating > bestMatchRating)) {
+         bestMatchRefIndex = iHltTrack;
+         bestMatchRating = matchRating;
+       } else if (matchRating > bestMatchRating)
+         bestMatchRating = matchRating;
+
+
+       iHltTrack++;
+      } // loop over HLT tracks;
+
+      fHistMatchRating->Fill(bestMatchRating);
+      fHistMatchRatingByPt->Fill(bestMatchRating, TMath::Abs(gpt));
+      fHistMatchRatingByPid->Fill(bestMatchRating, gpid);
+      fHistTrackPt->Fill(gpt);
+      fHistTrackPid->Fill(gpid);
+
+      if (bestMatchRefIndex >= 0){
+       // GTU track has matching reference track
+       Double_t rpt = fHLTTracks->at(bestMatchRefIndex).GetSignedPt();
+       LogDebug("#match - match found: rating %.2f, gpt: %+5.2f, rpt: %+5.2f (%i) -> diff: %.2f%%",
+                           bestMatchRating,gpt, rpt, bestMatchRefIndex, (gpt - rpt)/rpt*100.);
+       fTrackingData->SetTrackAddInfo(iStack, iGtuTrack, bestMatchRefIndex);
+
+//     if (fExtendedHistos){
+//       fHistMatchedRefTrackPid->Fill(element->Pt(), element->GetTPCsignal());
+//     }
+//
+//     if (fDebugLevel >= 3){
+//       LogDebug("#match-info rating: %.2f gpt: %+.2f  matchref: %d  rpt: %+.2f       gpid: %d  S%02d-%d %d   rpid: %.3f",
+//                       bestMatchRating, gpt, bestMatchRefIndex, rpt, gpid,
+//                       iStack/5, iStack%5, iGtuTrack, refTrack->GetTPCsignal());
+//     }
+       numMatchedTracks++;
+
+       fHistTrackPtMatched->Fill(gpt);
+       fHistTrackPtCorr->Fill(rpt, gpt);
+       fHistTrackPidMatched->Fill(gpid);
+
+      } else {
+       if (fDebugLevel >= 3){
+         LogDebug("#match-info rating: %.2f gpt: %+.2f  no ref matching  gpid: %d  S%02d-%d %d",
+                         bestMatchRating, gpt, gpid,
+                         iStack/5, iStack%5, iGtuTrack);
+       }
+       numUnmatchedTracks++;
+      }
+
+    } // loop over gtu tracks
+  } // loop over stacks
+
+  LogInfo("#match - %d matched GTU tracks, %d unmatched (%d comparisons)",
+         numMatchedTracks, numUnmatchedTracks, numComparisonsDone);
+
+  fHistTrackMatchingCombinations->Fill(0., (Double_t)(numHLTTracks * fTrackingData->GetNumTracks()));  // index 0: full combinatorics
+  fHistTrackMatchingCombinations->Fill(1., numComparisonsDone);  // index 1: track matching comparisons actually done
+
+  return kTRUE;
+}
+
+int AliHLTTRDTriggerComponent::MatchTRDTracks(){
+
+  if (!fEsdEvent) {
+    LogError("ESD event data not available in MatchTRDTracks().");
+    return 0;
+  }
+
+  if (fHistoMode == 0){
+    UInt_t numHists = fHistArray->GetEntries();
+    for (UInt_t iHist = 0; iHist < numHists; ++iHist)
+      if (fHistArray->At(iHist))
+       dynamic_cast<TH1*>(fHistArray->At(iHist))->Reset();
+  }
+
+  int result = 1;
+  unsigned int numRefTracks = fEsdEvent->GetNumberOfTracks();
+  unsigned int numGtuTracks;
+  Int_t refTrackIndices[fkMaxRefTracksPerStack];
+  UInt_t refTrackCount = 0;
+  Bool_t isRelevant;
+  Double_t distY, distZ;
+  Double_t matchRating;
+  Double_t bestMatchRating;
+  Int_t bestMatchRefIndex;
+  AliESDtrack* refTrack;
+  UInt_t numComparisonsDone = 0;
+  UInt_t numUnmatchedTracks = 0;
+  UInt_t numMatchedTracks = 0;
+
+  for (UShort_t iStack = 0; iStack < fkTRDStacks; ++iStack) {
+    numGtuTracks = fTrackingData->GetNumTracks(iStack);
+    refTrackCount = 0;
+
+    // preselect ESD relevant ESD tracks
+    for (UInt_t iRefTrack = 0; iRefTrack < numRefTracks; ++iRefTrack) {
+      refTrack = fEsdEvent->GetTrack(iRefTrack);
+      isRelevant = (refTrack->Pt() >= fRefTrackSelectionPtThreshold);
+      if (isRelevant){
+       if (refTrackCount < fkMaxRefTracksPerStack)
+         refTrackIndices[refTrackCount++] = iRefTrack;
+       else {
+         LogError("number of HLT tracks exceeding limit of %d. Skipping some tracks.", fkMaxRefTracksPerStack);
+         break;
+       }
+      }
+    }
+
+    // try to match GTU track with ref tracks
+    for (UInt_t iGtuTrack = 0; iGtuTrack < numGtuTracks; ++iGtuTrack) {
+      bestMatchRating = 0.;
+      bestMatchRefIndex = -1;
+      Double_t gpt = fTrackingData->GetTrackPt(iStack, iGtuTrack);
+      UShort_t gpid = fTrackingData->GetTrackPID(iStack, iGtuTrack);
+      UShort_t layerMask = fTrackingData->GetTrackLayerMask(iStack, iGtuTrack);
+
+      for (UInt_t iRefTrack = 0; iRefTrack < refTrackCount; ++iRefTrack) {
+       refTrack = fEsdEvent->GetTrack(refTrackIndices[iRefTrack]);
+
+       if (!CheckRefTrackCuts(refTrack))
+         continue;
+
+       numComparisonsDone++;
+
+//     if ((!refTrack->GetOuterParam()) && (!refTrack->GetInnerParam()))  // use tracks with TPC outer param only (all HLT tracks have it anyways)
+//       continue;
+
+       Float_t trklLocalY[fkTRDLayers];
+       Int_t trklBinZ[fkTRDLayers];
+       for (UShort_t iLayer = 0; iLayer < fkTRDLayers; ++iLayer){
+         if ((layerMask >> iLayer) & 1){
+           trklLocalY[iLayer] = fTrackingData->GetTrackTrackletLocalY(iStack, iGtuTrack, iLayer);
+           trklBinZ[iLayer] = fTrackingData->GetTrackTrackletBinZ(iStack, iGtuTrack, iLayer);
+         }
+       }
+
+       Int_t distRes = EstimateTrackDistance(refTrack, iStack, layerMask, trklLocalY, trklBinZ,
+                                             fEsdEvent->GetMagneticField(), &distY, &distZ);
+
+       if (distRes == 0){
+         matchRating = RateTrackMatch(distY, distZ, gpt, refTrack->GetSignedPt());
+       } else {
+         matchRating = 0.;
+       }
+
+       if ((matchRating >= fMatchRatingThreshold) && (matchRating > bestMatchRating)) {
+         bestMatchRefIndex = refTrackIndices[iRefTrack];
+         bestMatchRating = matchRating;
+       } else if (matchRating > bestMatchRating)
+         bestMatchRating = matchRating;
+
+//     DbgLog("", Form("#match - comparing GTU track %d in S%02d-%d with ref track %d: [gpt: %+5.2f rpt: %+5.2f] dy: %.1f dz: %.1f rating: %.1f",
+//                     iGtuTrack, iStack/5, iStack%5, refTrackIndices[iRefTrack],
+//                     fTrackingData->GetTrackPt(iStack, iGtuTrack), refTrack->GetSignedPt(),
+//                     distY, distZ, matchRating));
+
+      } // loop over ref tracks in stack
+
+      fHistMatchRating->Fill(bestMatchRating);
+      fHistMatchRatingByPt->Fill(bestMatchRating, TMath::Abs(gpt));
+      fHistMatchRatingByPid->Fill(bestMatchRating, gpid);
+      fHistTrackPt->Fill(gpt);
+      fHistTrackPid->Fill(gpid);
+
+      if (bestMatchRefIndex >= 0){
+       // GTU track has matching reference track
+       refTrack = fEsdEvent->GetTrack(bestMatchRefIndex);
+       Double_t rpt = refTrack->GetSignedPt();
+       LogDebug("#match - match found: rating %.2f, gpt: %+5.2f, rpt: %+5.2f (%i) -> diff: %.2f%%",
+                           bestMatchRating,gpt, rpt, bestMatchRefIndex, (gpt - rpt)/rpt*100.);
+       fTrackingData->SetTrackAddInfo(iStack, iGtuTrack, bestMatchRefIndex);
+
+       if (fExtendedHistos){
+         fHistMatchedRefTrackPid->Fill(refTrack->Pt(), refTrack->GetTPCsignal());
+       }
+
+       if (fDebugLevel >= 3){
+         LogDebug("#match-info rating: %.2f gpt: %+.2f  matchref: %d  rpt: %+.2f       gpid: %d  S%02d-%d %d   rpid: %.3f",
+                         bestMatchRating, gpt, bestMatchRefIndex, rpt, gpid,
+                         iStack/5, iStack%5, iGtuTrack, refTrack->GetTPCsignal());
+       }
+       numMatchedTracks++;
+
+       fHistTrackPtMatched->Fill(gpt);
+       fHistTrackPtCorr->Fill(rpt, gpt);
+       fHistTrackPidMatched->Fill(gpid);
+
+      } else {
+       if (fDebugLevel >= 3){
+         LogDebug("#match-info rating: %.2f gpt: %+.2f  no ref matching  gpid: %d  S%02d-%d %d",
+                         bestMatchRating, gpt, gpid,
+                         iStack/5, iStack%5, iGtuTrack);
+       }
+       numUnmatchedTracks++;
+      }
+
+    } // loop over gtu tracks in stack
+
+  } // loop over stacks
+
+  LogInfo("#match - %d matched GTU tracks, %d unmatched",
+                     numMatchedTracks, numUnmatchedTracks);
+
+  fHistTrackMatchingCombinations->Fill(0., (Double_t)(numRefTracks * fTrackingData->GetNumTracks()));  // index 0: full combinatorics
+  fHistTrackMatchingCombinations->Fill(1., numComparisonsDone);  // index 1: track matching comparisons actually done
+
+  return result;
+}
+
+void AliHLTTRDTriggerComponent::DumpTrackingData(){
+
+  if (fTrackingData->GetNumTracklets() + fTrackingData->GetNumTracks() == 0)
+    return;
+
+  TString trklStr("");
+  TString matchStr("");
+  UShort_t layerMask;
+
+//  for (UShort_t iSector = 0; iSector < 18; ++iSector){
+//    if (fTrackingData->GetSectorTrgWord(iSector) != ((UInt_t)0x2345352 ^ ((UInt_t)iSector + 34)))
+//      LogError("invalid sector trigger word in sector %02d: trg word is 0x%08x, should be 0x%08x",
+//            iSector, fTrackingData->GetSectorTrgWord(iSector), ((UInt_t)0x2345352 ^ ((UInt_t)iSector + 34)));
+//    for (UShort_t iStack = 0; iStack < 5; ++iStack){
+//      ULong64_t dwl = ((ULong64_t)0xaffe << 16) | (ULong64_t)iSector << 8 | iStack;
+//      ULong64_t dw = (((ULong64_t)0xbead << 16) | (ULong64_t)iSector << 8 | iStack) | ((ULong64_t)dwl << 32);
+//      if (fTrackingData->GetStackTrgWord(iSector, iStack) != dw)
+//     LogError("stack %02d-%d trg word is 0x%016llx, should be 0x%016llx",
+//              iSector, iStack, fTrackingData->GetStackTrgWord(iSector, iStack), dw);
+//    }
+//  }
+
+  for (UShort_t iStack = 0; iStack < fkTRDStacks; ++iStack){
+    for (Int_t iTrk = 0; iTrk < fTrackingData->GetNumTracks(iStack); ++iTrk){
+
+      layerMask = fTrackingData->GetTrackLayerMask(iStack, iTrk);
+
+      trklStr = Form("trkl: ");
+      for (Short_t iLayer = 5; iLayer >= 0; --iLayer){
+       if ((layerMask >> iLayer) & 1)
+         trklStr += Form("0x%08x (%+8.3f)  ",
+                         fTrackingData->GetTrackTrackletWord(iStack, iTrk, iLayer),
+                         fTrackingData->GetTrackTrackletLocalY(iStack, iTrk, iLayer));
+       else
+         trklStr += "---------------------  ";
+      } // loop over layers
+      trklStr.Remove(trklStr.Length() - 2, 2);
+
+      if (fTrackingData->GetTrackAddInfo(iStack, iTrk) >= 0){
+       Double_t rpt = (fESDtracksPresent) ?  fEsdEvent->GetTrack(fTrackingData->GetTrackAddInfo(iStack, iTrk))->GetSignedPt() :
+         fHLTTracks->at(fTrackingData->GetTrackAddInfo(iStack, iTrk)).GetSignedPt();
+       matchStr = Form("mpt: %+7.2f", rpt);
+      } else
+       matchStr = "unmatched";
+
+      if (fDebugLevel >= 3){
+
+       printf("###DOTDA EV%04llu  GTU TRACK - S%02d-%d  pt: %+7.2f  pid: %3d  lm: 0x%02x %s  %s\n",
+              fEventId,
+              iStack/5, iStack%5, fTrackingData->GetTrackPt(iStack, iTrk), fTrackingData->GetTrackPID(iStack, iTrk),
+              layerMask, trklStr.Data(),
+              matchStr.Data());
+
+       printf("###DOTDB EV%04llu  GTU TRACK - S%02d-%d  pt: %+7.2f  pid: %3d  lm: 0x%02x %s\n",
+              fEventId,
+              iStack/5, iStack%5, fTrackingData->GetTrackPt(iStack, iTrk), fTrackingData->GetTrackPID(iStack, iTrk),
+              layerMask, trklStr.Data());
+      }
+
+
+      // paranoia checks
+      for (Short_t iLayer = 5; iLayer >= 0; --iLayer){
+       if (((layerMask >> iLayer) & 1) && (fTrackingData->GetTrackTrackletWord(iStack, iTrk, iLayer) == 0x10001000))
+         LogError("invalid layer mask / tracklet value combination A");
+
+       if ((((layerMask >> iLayer) & 1) == 0) && (fTrackingData->GetTrackTrackletWord(iStack, iTrk, iLayer) != 0x10001000))
+         LogError("invalid layer mask / tracklet value combination B");
+      }
+
+    } // loop over tracks in stack
+  } // loop over stacks
+
+}
+
+void AliHLTTRDTriggerComponent::AssignTrackInfo(TString* infoStr, const UInt_t stack, const UInt_t trackIndex, const char* flagStr) {
+
+  TString flags(flagStr);
+  Bool_t appendRefData = kFALSE;
+
+  if (fTrackingData->GetTrackAddInfo(stack, trackIndex) >= 0){
+    appendRefData = kTRUE;
+    if (flags.First('M') < 0)
+      flags += "M";
+  }
+
+  *infoStr = Form("EXCH-TRK-INFO DS<%s> CH<%s> EV%05llu SEC%02d-%d-%d  gpt: %+6.1f  gpid: %3d  flags: %s",
+                 "TRDHLTTRG",
+                 fChunkId->Data(), fEventId,
+                 stack/5, stack%5, trackIndex,
+                 fTrackingData->GetTrackPt(stack, trackIndex),
+                 fTrackingData->GetTrackPID(stack, trackIndex), flags.Data());
+
+  if (appendRefData){
+    Double_t rpt = (fESDtracksPresent) ? fEsdEvent->GetTrack(fTrackingData->GetTrackAddInfo(stack, trackIndex))->GetSignedPt() :
+      fHLTTracks->at(fTrackingData->GetTrackAddInfo(stack, trackIndex)).GetSignedPt();
+    *infoStr += Form("  rpt: %+6.1f", rpt);
+  }
+
+}
+
+#ifdef __TRDHLTDEBUG
+void AliHLTTRDTriggerComponent::RenderEvent(const Bool_t showGtuTracks, const Bool_t showTracklets, const Bool_t showRefTracks) {
+
+  if ((!fEventDisplay) || (!fEsdEvent))
+    return;
+
+  LogDebug("rendering event");
+
+  const Float_t refTrackPtDisplayThreshold = 0.7;
+  const Float_t trackPtEmphasizeThreshold = 1.8;
+
+  fEventDisplay->Reset();
+  fEventDisplay->SetMagField(fEsdEvent->GetMagneticField());
+  for (UInt_t iDet = 0; iDet < fkTRDStacks*fkTRDLayers; ++iDet)
+    fEventDisplay->SetChamberState(iDet/fkTRDLayers, iDet%6, ((fSectorsWithData >> (iDet/30)) & 1) );
+
+  if (showTracklets){
+    for (UShort_t iDet = 0; iDet < fkTRDStacks*fkTRDLayers; ++iDet){
+      UInt_t numTrkl = fTrackingData->GetNumTracklets(iDet);
+      for (UInt_t iTrkl = 0; iTrkl < numTrkl; ++iTrkl){
+       fEventDisplay->AddTracklet(fTrackingData->GetTracklet(iDet, iTrkl));
+      }
+    }
+  }
+
+  if (showGtuTracks){
+    for (UShort_t iStack = 0; iStack < fkTRDStacks; ++iStack){
+      for (Int_t iTrk = 0; iTrk < fTrackingData->GetNumTracks(iStack); ++iTrk){
+       AliESDTrdTrack* track = fTrackingData->GetTrack(iStack, iTrk);
+       Int_t trkIndex = fEventDisplay->AddTrack(track, (TMath::Abs(track->Pt()) >= trackPtEmphasizeThreshold) ? (kMagenta + 2) : kMagenta, 1, 1);
+       if (fTrackingData->GetTrackAddInfo(iStack, iTrk) >= 0)
+         fEventDisplay->SetTrackTrackletStyle(trkIndex, kRed, 12);
+       else
+         fEventDisplay->SetTrackTrackletStyle(trkIndex, kViolet - 5, 12);
+      }
+    }
+  }
+
+  unsigned int numRefTracks = fEsdEvent->GetNumberOfTracks();
+  unsigned int numRefTracksRendered = 0;
+  if (showRefTracks){
+    // check for some marks for rendering
+    UShort_t marks[40000];
+    memset(marks, 0, sizeof(UShort_t)*40000);
+    for (UShort_t iStack = 0; iStack < fkTRDStacks; ++iStack){
+      for (Int_t iTrk = 0; iTrk < fTrackingData->GetNumTracks(iStack); ++iTrk){
+       if (fTrackingData->GetTrackAddInfo(iStack, iTrk) >= 0){
+         marks[fTrackingData->GetTrackAddInfo(iStack, iTrk)] |= 1;
+         if (
+             (fTrackingData->GetTrackPID(iStack, iTrk) >= fElectronTriggerPIDThresholdHQU) &&
+             (TMath::Abs(fTrackingData->GetTrackPt(iStack, iTrk)) >= fElectronTriggerPtThresholdHQU))
+           marks[fTrackingData->GetTrackAddInfo(iStack, iTrk)] |= 2;
+       }
+      }
+    }
+
+    // add to rendering
+    for (unsigned int iTrack = 0; iTrack < numRefTracks; ++iTrack){
+      AliESDtrack* track = fEsdEvent->GetTrack(iTrack);
+      if ((track->Pt() >= refTrackPtDisplayThreshold) || (marks[iTrack] != 0)){
+       Color_t color = (track->Pt() >= trackPtEmphasizeThreshold) ? (kGray + 2) : kGray;
+       UShort_t width = 1;
+       UShort_t style = 1;
+       if (marks[iTrack] & 0x2){
+         color = kRed + 1;
+         width = 6;
+       }
+       if (!CheckRefTrackCuts(track))
+         style = 2;
+
+       fEventDisplay->AddTrack(track, color, width, style);
+       numRefTracksRendered++;
+      }
+    }
+  }
+
+  if (!fEventDisplay->IsEmpty()){
+    fEventDisplay->SetTitle("");
+    fEventDisplay->SetSetupText("HLT", Form("%.1f#scale[0.5]{ }/#scale[0.5]{ }%.1f",
+                                         refTrackPtDisplayThreshold, trackPtEmphasizeThreshold));
+    fEventDisplay->SetBottomText(Form("%05i-%s-%05llu",
+                                     fRunNumber, fChunkId->Data(), fEventId));
+    fEventDisplay->SetBottomTextRight(Form("%d (%d) HLT tracks, %d tracklets, %d GTU tracks",
+                                          numRefTracks,
+                                          numRefTracksRendered,
+                                          fTrackingData->GetNumTracklets(),
+                                          fTrackingData->GetNumTracks()));
+    fEventDisplay->SetLook(AliTRDtrackingEventDisplay::dmMediumLight);
+    fEventDisplay->SetDisplayMode(AliTRDtrackingEventDisplay::dmFullXY);
+    fEventDisplay->SaveToFile(Form("display/event-%s-%05llu.eps",
+                                  fChunkId->Data(), fEventId));
+  }
+
+}
+#endif
+
+Bool_t AliHLTTRDTriggerComponent::TRDElectronTrigger(const char *ident, const Double_t minPt, const UShort_t minPID){
+
+  LogDebug("Electron trigger processing (%s: pt>=%.1f, pid>=%d)...", ident, minPt, minPID);
+
+  UInt_t numTracks;
+  Bool_t highPtElectronSeenGTU = kFALSE;
+  Bool_t highPtElectronSeen = kFALSE;
+  UInt_t truncMeanPID = 0;
+  TString trackExchangeInfo("");
+  TString flags("");
+
+  UInt_t trdSectorTrgContribs = 0;
+  for (UShort_t iSector = 0; iSector < fkTRDSectors; ++iSector)
+    trdSectorTrgContribs |= fTrackingData->GetSectorTrgContribs(iSector);
+  if ((trdSectorTrgContribs >> 5) & 0x3)
+    fIsTRDElectronEvent = kTRUE;
+  else
+    fIsTRDElectronEvent = kFALSE;
+
+  if (fIsMinBiasEvent)
+    fHistElectronTriggerBaseMinBias->Fill(0.);
+
+  if (fIsTRDElectronEvent)
+    fHistElectronTriggerBaseTrdL1->Fill(0.);
+
+  if ((fElectronTriggerOnL1TrgOnly) && (!fIsTRDElectronEvent)){
+    // evaluate trigger for events with TRD L1 electron trigger fired
+    DbgLog("skipping %s electron trigger evaluation for event, because no TRD trigger flag set (ctbs: 0x%02x)",
+          ident, trdSectorTrgContribs);
+    return 0;
+  }
+
+  for (UShort_t iStack = 0; iStack < fkTRDStacks; ++iStack){
+    numTracks = fTrackingData->GetNumTracks(iStack);
+    for (UInt_t iTrk = 0; iTrk < numTracks; ++iTrk){
+      Double_t gpt = fTrackingData->GetTrackPt(iStack, iTrk);
+      Bool_t trdElectronCandidate = kFALSE;
+      Bool_t hltElectronCandidate = kFALSE;
+
+      // re-evaluate GTU only decision for comparison
+      if (
+         (TMath::Abs(gpt) >= minPt) &&
+         (fTrackingData->GetTrackPID(iStack, iTrk) >= minPID)
+         ) {
+       trdElectronCandidate = kTRUE;
+       highPtElectronSeenGTU = kTRUE;
+       fHistElectronCandidatePt->Fill(gpt);
+       fHistElectronCandidatePid->Fill(fTrackingData->GetTrackPID(iStack, iTrk));
+
+       if (fExtendedHistos){
+
+         // idea to be checked
+         truncMeanPID = 0;
+         Short_t minLyr = -1;
+         UShort_t minValue = 255;
+         Short_t maxLyr = -1;
+         UShort_t maxValue = 0;
+         UShort_t lyrCount = 0;
+         UInt_t layerMask = fTrackingData->GetTrackLayerMask(iStack, iTrk);
+
+         // scan for min & max values
+         for (UShort_t iLayer = 0; iLayer < fkTRDLayers; ++iLayer){
+           if ((layerMask >> iLayer) & 1){
+             if (fTrackingData->GetTrackTrackletPID(iStack, iTrk, iLayer) < minValue){
+               minValue = fTrackingData->GetTrackTrackletPID(iStack, iTrk, iLayer);
+               minLyr = iLayer;
+             }
+             if (fTrackingData->GetTrackTrackletPID(iStack, iTrk, iLayer) > maxValue){
+               maxValue = fTrackingData->GetTrackTrackletPID(iStack, iTrk, iLayer);
+               maxLyr = iLayer;
+             }
+           }
+         } // loop over layers
+
+         // calculate trunc mean
+         for (UShort_t iLayer = 0; iLayer < fkTRDLayers; ++iLayer){
+           if (((layerMask >> iLayer) & 1) && (iLayer != minLyr) && (iLayer != maxLyr)){
+             truncMeanPID += fTrackingData->GetTrackTrackletPID(iStack, iTrk, iLayer);
+             lyrCount++;
+           }
+         } // loop over layers
+         truncMeanPID = TMath::Nint((Double_t)(truncMeanPID)/(Double_t)(lyrCount));
+
+         fHistPIDvsTruncPID->Fill(fTrackingData->GetTrackPID(iStack, iTrk), truncMeanPID);
+         if (fTrackingData->GetTrackAddInfo(iStack, iTrk) < 0)
+           fHistElectronFalsePIDvsTruncPID->Fill(fTrackingData->GetTrackPID(iStack, iTrk), truncMeanPID);
+
+       }
+
+       LogInspect("#hlt-trd-trg - GTU flagged %s %s high-pt electron seen in S%02d-%d: pt: %+6.1f  pid: %d  [id: S%02d-%d-%d] [trunc-pid: %d]",
+                  (fTrackingData->GetTrackAddInfo(iStack, iTrk) < 0) ? "unmatched" : "matched", ident,
+                  iStack/5, iStack%5,
+                  gpt, fTrackingData->GetTrackPID(iStack, iTrk),
+                  iStack/5, iStack%5, iTrk,
+                  truncMeanPID);
+      }
+
+      // evaluate HLT-level trigger decision using match information
+      if (
+         (fTrackingData->GetTrackAddInfo(iStack, iTrk) >= 0) &&
+         (TMath::Abs(gpt) >= minPt) &&
+         (fTrackingData->GetTrackPID(iStack, iTrk) >= minPID)
+         ) {
+       hltElectronCandidate = kTRUE;
+       highPtElectronSeen = kTRUE;
+
+       fHistElectronCandidateMatchedPt->Fill(gpt);
+       fHistElectronCandidateMatchedPid->Fill(fTrackingData->GetTrackPID(iStack, iTrk));
+
+       if (fExtendedHistos){
+         fHistElectronConfirmedPIDvsTruncPID->Fill(fTrackingData->GetTrackPID(iStack, iTrk), truncMeanPID);
+       }
+
+       Double_t rpt = (fESDtracksPresent) ? fEsdEvent->GetTrack(fTrackingData->GetTrackAddInfo(iStack, iTrk))->GetSignedPt() :
+         fHLTTracks->at(fTrackingData->GetTrackAddInfo(iStack, iTrk)).GetSignedPt();
+       LogInspect("#hlt-trd-trg - HLT matched %s high-pt electron seen in S%02d-%d: gpt: %+6.1f  gpid: %d   rpt: %+6.1f  [id: S%02d-%d-%d]",
+                  ident, iStack/5, iStack%5, fTrackingData->GetTrackPt(iStack, iTrk), fTrackingData->GetTrackPID(iStack, iTrk),
+                  rpt, iStack/5, iStack%5, iTrk);
+      }
+
+      // log output for subsequent offline analysis
+      if ((fDebugLevel >= 3) && (trdElectronCandidate || hltElectronCandidate)){
+       trackExchangeInfo = "";
+       flags = "";
+       if (trdElectronCandidate)
+         flags += "G";
+       if (hltElectronCandidate)
+         flags += "H";
+       AssignTrackInfo(&trackExchangeInfo, iStack, iTrk, flags.Data());
+       LogDebug("%s\n", trackExchangeInfo.Data());
+      }
+
+    } // loop over tracks in stack
+  } // loop over stacks
+
+  if (highPtElectronSeenGTU || highPtElectronSeen){
+    LogInspect("#hlt-trd-trg - event triggered by %s electron trigger (TRD L1: %d, TRD HLT: %d)",
+              ident, highPtElectronSeenGTU, highPtElectronSeen);
+  }
+
+  if (highPtElectronSeenGTU){
+    if (fIsMinBiasEvent)
+      fHistElectronTriggerBaseMinBias->Fill(1.);
+  }
+
+  if (highPtElectronSeen){
+    if (fIsMinBiasEvent)
+      fHistElectronTriggerBaseMinBias->Fill(2.);
+    if (fIsTRDElectronEvent)
+      fHistElectronTriggerBaseTrdL1->Fill(1.);
+  }
+
+  return (highPtElectronSeen) ? kTRUE : kFALSE;
+}
+
+
+int AliHLTTRDTriggerComponent::DoTrigger()
+{
+
+  fEsdEvent = NULL;
+  fRunNumber = -1;
+  int iResult = 0;
+  UShort_t firedTriggers = 0;
+
+  const AliHLTComponentEventData* hltEventData = GetEventData();
+  fEventId = hltEventData->fEventID;
+  LogDebug("### START DoTrigger [event id: %llu, %d blocks, size: %d]",
+                     fEventId, hltEventData->fBlockCnt, hltEventData->fStructSize);
+
+//  LogDebug("### START DoTrigger [event id: %llu, %d blocks, size: %d]",
+//                   fEventId, hltEventData->fBlockCnt, hltEventData->fStructSize);
+
+  if (!IsDataEvent()) {  // process data events only
+    IgnoreEvent();
+    LogDebug("### END   DoTrigger [event id: %llu, %d blocks, size: %d] (skipped: no data event)",
+            fEventId, hltEventData->fBlockCnt, hltEventData->fStructSize);
+    return iResult;
+  }
+
+  fTrackingData->SetLogPrefix(Form("TRDHLTGM XXXXXX-%05llu: [TRG] {TrkDat} ", fEventId));
+
+  do {
+
+    // access to TRD specific data from AliHLTTRDPreprocessorComponent
+    if (!PrepareTRDData()){
+      LogError("access to TRD data failed. Skipping event...");
+      break;
+    }
+
+    if (fTrackingData->GetNumTracks() + fTrackingData->GetNumTracklets() == 0) {
+      LogDebug("no trigger-relevant TRD information, skipping further event processing");
+      break;
+    }
+
+    // access to ESD data
+    if (!PrepareESDData()){
+      LogInfo("access to ESD event data failed.");
+    }
+
+    // access to alternative HLT data
+    if (!fESDtracksPresent){
+      if (!PrepareHLTData()){
+       LogError("access to HLT event data failed.");
+      }
+    }
+
+    // match TRD and HLT tracks
+    if (fESDtracksPresent){
+      if (!MatchTRDTracksESD()){
+       LogError("matching TRD tracks to ESD tracks failed. Skipping event...");
+       break;
+      }
+    } else if (fHLTtracksPresent){
+      if (!MatchTRDTracksHLT()){
+       LogError("matching TRD tracks to HLT tracks failed. Skipping event...");
+       break;
+      }
+    } else {
+      LogError("No HLT track information available. Skipping event...");
+      break;
+    }
+
+//    if (!MatchTRDTracks()){
+//      LogError("matching TRD tracks to TPC tracks failed. Skipping event...");
+//      break;
+//    }
+
+    if (fDebugLevel >= 1)
+      DumpTrackingData();
+
+    // evaluate electron trigger conditions
+    if (TRDElectronTrigger("HSE", fElectronTriggerPtThresholdHSE, fElectronTriggerPIDThresholdHSE))
+      firedTriggers |= fkElectronTriggerHSE;
+
+    if (TRDElectronTrigger("HQU", fElectronTriggerPtThresholdHQU, fElectronTriggerPIDThresholdHQU))
+      firedTriggers |= fkElectronTriggerHQU;
+
+    break;
+
+  } while (1);
+
+
+  // trigger decision
+  TString description("");
+  if (firedTriggers & fkElectronTriggerHSE){
+    if (description.Length() > 0)
+      description += " ";
+    description += fgkTriggerDecisionElectronHSE;
+  }
+
+  if (firedTriggers & fkElectronTriggerHQU){
+    if (description.Length() > 0)
+      description += " ";
+    description += fgkTriggerDecisionElectronHQU;
+  }
+
+  SetDescription(description.Data());
+  AliHLTTriggerDecision decision((firedTriggers) ? kTRUE : kFALSE,
+                                GetTriggerName(),
+                                GetReadoutList(),
+                                GetDescription()
+                                );
+  TriggerEvent(&decision, kAliHLTDataTypeTObject | kAliHLTDataOriginOut);
+
+  if (firedTriggers){
+    LogInspect("TRD HLT trigger fired for event: description: >%s<, flags: 0x%04x",
+              description.Data(), firedTriggers);
+#ifdef __TRDHLTDEBUG
+    if (fEventRendering)
+      RenderEvent();
+#endif
+  } else {
+    LogDebug("TRD HLT trigger did not fire for event");
+  }
+
+  if (fPushHistos){
+    PushBack(fHistArray, (kAliHLTDataTypeTObjArray | kAliHLTDataOriginTRD), 0x3fffff);
+  }
+
+  LogDebug("### END   DoTrigger [event id: %llu, %d blocks, size: %d]",
+                     fEventId, hltEventData->fBlockCnt, hltEventData->fStructSize);
+
+  return iResult;
+}
+
+Bool_t AliHLTTRDTriggerComponent::TrackPlaneIntersect(AliExternalTrackParam *trk, Double_t pnt[3], Double_t norm[3], Double_t mag){
+
+  UInt_t its = 0;
+  Double_t r = 290.;
+  Double_t dist = 99999, dist_prev = 99999;
+  Double_t x[3] = {0., 0., 0.};
+  Bool_t ret = kTRUE;
+
+  dist = (x[0] - pnt[0]) * norm[0] + (x[1] - pnt[1]) *norm[1] + (x[2] - pnt[2]) * norm[2];
+
+  while(TMath::Abs(dist) > 0.1) {
+
+    trk->GetXYZAt(r, mag, x);
+
+    if ((x[0] * x[0] + x[1] * x[1]) < 100.) {  // extrapolation to radius failed
+      ret = kFALSE;
+      break;
+    }
+
+    //distance between current track position and plane
+    dist_prev = TMath::Abs(dist);
+    dist = (x[0] - pnt[0]) * norm[0] + (x[1] - pnt[1]) * norm[1];
+    r -= dist;
+    its++;
+    if(TMath::Abs(dist) >= dist_prev ||
+       (r > 380.) || (r < 100.)){
+      ret = kFALSE;
+      break;
+    }
+  }
+
+  for (Int_t i=0; i<3; i++){
+    if(ret)
+      pnt[i] = x[i];
+    else
+      pnt[i] = 0.;
+  }
+
+  return kTRUE;
+}
+
+
+Double_t AliHLTTRDTriggerComponent::RateTrackMatch(Double_t distY, Double_t distZ, Double_t rpt, Double_t gpt){
+
+  // maximum limits for spatial distance
+  if ((distY > 5.) || (distZ > 20.))
+    return 0.;
+
+  // same pt sign required
+  if ((rpt * gpt) < 0.)
+    return 0.;
+
+  Double_t rating_distY = -0.1 * distY + 1.;
+  Double_t rating_distZ = -0.025 * distZ + 1.;
+  Double_t rating_ptDiff = 1. - TMath::Abs((TMath::Abs(rpt) > 0.000001) ? ((gpt-rpt)/rpt) : 0.);
+
+  if (rating_ptDiff <  0.)
+    rating_ptDiff = 0.2;
+
+  Double_t total = rating_distY * rating_distZ * rating_ptDiff;
+
+//  DbgLog("", Form("#matching: rating:   dy: %.3f   dz: %.3f   dpt: %.3f     -> total: %.3f",
+//                 rating_distY, rating_distZ, rating_ptDiff, total));
+
+  if (total > 1.)
+    LogError("track match rating exceeds limit of 1.0: %.3f", total);
+
+  return total;
+}
+
+Int_t AliHLTTRDTriggerComponent::EstimateTrackDistance(AliESDtrack *esd_track,
+                                                       const UShort_t stack,
+                                                       const UShort_t layerMask,
+                                                       const Float_t trklLocalY[6], const Int_t trklBinZ[6],
+                                                       Double_t mag, Double_t *ydist, Double_t *zdist){
+  if (!esd_track)
+    return -3;
+
+  AliExternalTrackParam* refParam = NULL;
+  if (esd_track->GetOuterParam())
+    refParam = new AliExternalTrackParam(*(esd_track->GetOuterParam()));
+  if (!refParam)
+    refParam = new AliExternalTrackParam(*(esd_track));
+
+  Int_t res = EstimateTrackDistance(refParam, stack, layerMask, trklLocalY, trklBinZ, mag, ydist, zdist);
+
+  if (refParam)
+    delete refParam;
+
+  return res;
+
+}
+
+Int_t AliHLTTRDTriggerComponent::EstimateTrackDistance(AliExternalTrackParam *refParam,
+                                                       const UShort_t stack,
+                                                       const UShort_t layerMask,
+                                                       const Float_t trklLocalY[6], const Int_t trklBinZ[6],
+                                                       Double_t mag, Double_t *ydist, Double_t *zdist){
+
+  Float_t diff_y = 0;
+  Float_t diff_z = 0;
+  Int_t nLayers = 0;
+  Double_t xtrkl[3];
+  Double_t ptrkl[3];
+  Double_t ptrkl2[3];
+  UInt_t trklDet;
+  UShort_t trklLayer;
+  UInt_t stack_gtu;
+  UShort_t stackInSector;
+
+  AliTRDpadPlane* padPlane;
+
+  for (UShort_t iLayer = 0; iLayer < 6; iLayer++){
+    if ((layerMask >> iLayer) & 1){
+      trklDet = stack*6 + iLayer;
+      trklLayer = iLayer;
+      stack_gtu = stack;
+      stackInSector = stack % 5;
+
+      // local coordinates of the outer end point of the tracklet
+      xtrkl[0] = AliTRDgeometry::AnodePos();
+      xtrkl[1] = trklLocalY[iLayer];
+
+      padPlane = fTRDGeometry->GetPadPlane(trklLayer, stackInSector);
+      if(stackInSector == 2){ // corrected version by Felix Muecke
+       xtrkl[2] = padPlane->GetRowPos(trklBinZ[iLayer]) - (padPlane->GetRowSize(trklBinZ[iLayer]))/2. - padPlane->GetRowPos(6);
+      } else {
+       xtrkl[2] = padPlane->GetRowPos(trklBinZ[iLayer]) - (padPlane->GetRowSize(trklBinZ[iLayer]))/2. - padPlane->GetRowPos(8);
+      }
+
+      // transform to global coordinates
+      TGeoHMatrix *matrix = fTRDGeometry->GetClusterMatrix(trklDet);
+      if (!matrix){
+       LogError("invalid TRD cluster matrix in EstimateTrackDistance for detector %i", trklDet);
+       return -5;
+      }
+      matrix->LocalToMaster(xtrkl, ptrkl);
+      fTRDGeometry->RotateBack((stack/5) * 30, ptrkl, ptrkl2);  // ptrkl2 now contains the global position of the outer end point of the tracklet
+
+      // calculate parameterization of plane representing the tracklets layer
+      Double_t layer_zero_local[3] = {0., 0.,  0.};
+      Double_t layer_zero_global[3], layer_zero_global2[3];
+
+      matrix->LocalToMaster(layer_zero_local, layer_zero_global);
+      fTRDGeometry->RotateBack(trklDet, layer_zero_global, layer_zero_global2); // layer_zero_global2 points to chamber origin in global coords
+
+      Double_t layer_ref_local[3] = {AliTRDgeometry::AnodePos(), 0.,  0.};
+      Double_t layer_ref_global[3], layer_ref_global2[3];
+
+      matrix->LocalToMaster(layer_ref_local, layer_ref_global);
+      fTRDGeometry->RotateBack(trklDet, layer_ref_global, layer_ref_global2); // layer_ref_global2 points to center anode pos within plane in global coords
+
+      Double_t n0[3] = {layer_ref_global2[0]-layer_zero_global2[0],
+                       layer_ref_global2[1]-layer_zero_global2[1],
+                       layer_ref_global2[2]-layer_zero_global2[2]};
+
+      Double_t n_len = TMath::Sqrt(n0[0]*n0[0] + n0[1]*n0[1] + n0[2]*n0[2]);
+      if (n_len == 0.){ // This should never happen
+       //printf("<ERROR> divison by zero in estimate_track_distance!");
+       n_len = 1.;
+      }
+      Double_t n[3] = {n0[0]/n_len, n0[1]/n_len, n0[2]/n_len}; // normal vector of plane
+
+      Bool_t isects = TrackPlaneIntersect(refParam, layer_ref_global2, n, mag); // find intersection point between track and TRD layer
+
+      if (isects == kFALSE){ // extrapolation fails, because track never reaches the TRD radius
+       return -1;
+      }
+
+      Double_t m[2] = {ptrkl2[0] - layer_ref_global2[0], ptrkl2[1] - layer_ref_global2[1]};
+      Double_t len_m = TMath::Sqrt(m[0]*m[0] + m[1]*m[1]);
+      diff_y += len_m;
+      diff_z += TMath::Abs(ptrkl2[2] - layer_ref_global2[2]);
+      nLayers++;
+    }
+  }
+
+  if (nLayers > 0){
+    *ydist = diff_y / nLayers;
+    *zdist = diff_z / nLayers;
+    return 0;
+  } else {
+    LogError("invalid number of contributing layers (%d) in EstimateTrackDistance()", nLayers);
+    return -4;
+  }
+}
diff --git a/HLT/trigger/AliHLTTRDTriggerComponent.h b/HLT/trigger/AliHLTTRDTriggerComponent.h
new file mode 100644 (file)
index 0000000..491172c
--- /dev/null
@@ -0,0 +1,178 @@
+//-*- Mode: C++ -*-
+// $Id$
+#ifndef ALIHLTTRDTRIGGERCOMPONENT_H
+#define ALIHLTTRDTRIGGERCOMPONENT_H
+
+//* This file is property of and copyright by the ALICE HLT Project        *
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               *
+
+/// @file   AliHLTTRDTriggerComponent.h
+/// @author Felix Rettig, Stefan Kirsch
+/// @date   2012-08-16
+/// @brief
+
+#include "TString.h"
+#include "AliHLTTrigger.h"
+#include "AliESDEvent.h"
+#include "AliESDTrdTrack.h"
+#include "AliExternalTrackParam.h"
+#include "AliTRDgeometry.h"
+#ifdef __TRDHLTDEBUG
+  #include "AliTRDtrackingEventDisplay.h"
+#endif
+
+#define trd_det_lsi(det) ((det) / 6)               // convert TRD detector/chamber 0-539 index to linear stack index 0-89
+#define trd_det_lyr(det) ((det) % 6)               // convert detector (=chamber) number 0-539 to local layer 0-5
+#define trd_det_si(det) (((det) % 30) / 6)         // convert detector (=chamber) number 0-539 to local stack index 0-4
+
+class TObjArray;
+class TH1I;
+class TH2I;
+class AliHLTComponentBenchmark;
+class AliESDtrack;
+class AliHLTGlobalBarrelTrack;
+class AliESDtrackCuts;
+class AliHLTESDTrackCuts;
+class AliTRDonlineTrackingDataContainer;
+
+/**
+ * @class  AliHLTTRDTriggerComponent
+ */
+class AliHLTTRDTriggerComponent : public AliHLTTrigger
+{
+ public:
+
+  AliHLTTRDTriggerComponent();
+  virtual ~AliHLTTRDTriggerComponent();
+
+  virtual const char* GetTriggerName() const;
+  virtual AliHLTComponent* Spawn();
+
+ protected:
+  int DoInit(int argc, const char** argv);
+  int DoDeinit();
+  int Reconfigure(const char* cdbEntry, const char* chainId);
+  int ReadPreprocessorValues(const char* modules);
+  int ConfigureFromCDBObject(TString cdbPath);
+  int ScanConfigurationArgument(int argc, const char** argv);
+
+ private:
+  AliHLTTRDTriggerComponent (const AliHLTTRDTriggerComponent&);
+  AliHLTTRDTriggerComponent& operator=(const AliHLTTRDTriggerComponent&);
+  virtual int DoTrigger();
+
+  Bool_t CheckRefTrackCuts(AliESDtrack* track);
+
+  // TRD-trigger specific
+  void ScanTriggerClasses(const char* firedTriggerClasses);
+  int PrepareESDData();
+  int PrepareHLTData();
+  int PrepareTRDData();
+  int MatchTRDTracks();
+  int MatchTRDTracksESD();
+  int MatchTRDTracksHLT();
+  Bool_t TRDElectronTrigger(const char *ident, const Double_t minPt, const UShort_t minPID);
+
+  Bool_t TrackPlaneIntersect(AliExternalTrackParam *trk, Double_t pnt[3], Double_t norm[3], Double_t mag);
+
+  Int_t EstimateTrackDistance(AliExternalTrackParam *refParam,
+                                const UShort_t stack,
+                                const UShort_t layerMask,
+                                const Float_t trklLocalY[6], const Int_t trklBinZ[6],
+                                Double_t mag, Double_t *ydist, Double_t *zdist);
+
+  Int_t EstimateTrackDistance(AliESDtrack *esd_track,
+                                const UShort_t stack,
+                                const UShort_t layerMask,
+                                const Float_t trklLocalY[6], const Int_t trklBinZ[6],
+                                Double_t mag, Double_t *ydist, Double_t *zdist);
+
+  Double_t RateTrackMatch(Double_t distY, Double_t distZ, Double_t rpt, Double_t gpt);
+
+  void DumpTrackingData();
+  void AssignTrackInfo(TString* infoStr, const UInt_t stack, const UInt_t trackIndex, const char* flagStr = "");
+#ifdef __TRDHLTDEBUG
+  void RenderEvent(const Bool_t showGtuTracks = kTRUE, const Bool_t showTracklets = kTRUE, const Bool_t showRefTracks = kTRUE);
+#endif
+  void DbgLog(const char* prefix, ...);
+
+  TString  fName;                           //! trigger name
+  Double_t fRefTrackSelectionEtaLimit;      //! ref track preselection maximum eta
+  Double_t fRefTrackSelectionVertexXYLimit; //! ref track preselection maximum distance to ip in XY plane
+  Double_t fRefTrackSelectionVertexZLimit;  //! ref track preselection maximum distance to ip in Z
+  Double_t fRefTrackSelectionPtThreshold;   //! pt threshold for ref track preselection in GeV/c
+  Double_t fMatchRatingThreshold;           //! track match rating threshold
+  Double_t fElectronTriggerPtThresholdHSE;  //! pt threshold for HSE electron trigger
+  UShort_t fElectronTriggerPIDThresholdHSE; //! PID threshold for HSE electron trigger
+  Double_t fElectronTriggerPtThresholdHQU;  //! pt threshold for HQU electron trigger
+  UShort_t fElectronTriggerPIDThresholdHQU; //! PID threshold for HQU electron trigger
+  Bool_t fApplyRefTrackCuts;                //! switch on/off ref track cuts for matching
+  Bool_t fElectronTriggerOnL1TrgOnly;       //! run electron trigger only for events with L1 electron trigger
+  UShort_t fHistoMode;                      //! histogramming mode, 0: single event, 1: accumulative (debugging)
+  UShort_t fDebugLevel;                     //! set debug checks/output level, 0: debug off
+  Bool_t fExtendedHistos;                   //! switch on/off additional histograms
+  Bool_t fEventRendering;                   //! switch on/off event rendering
+  Bool_t fPushHistos;                       //! switch on/off pushing of histograms event by event
+  Bool_t fWriteHistos;                      //! switch on/off histogram writing on deinit
+
+  static const char* fgkDefaultOCDBEntry;                    //! default OCDB entry
+  static const char* fgkTriggerDecisionElectronHSE;          //! electron trigger flag string
+  static const char* fgkTriggerDecisionElectronHQU;          //! electron trigger flag string
+
+  static const AliHLTEventID_t fgkInvalidEventId = 0xffffffffffffffffllu;
+  static const unsigned int fkTRDLayers = 6;                 //! number of layers per stack in TRD
+  static const unsigned int fkTRDStacks = 90;                //! number of stacks in TRD
+  static const unsigned int fkTRDSectors = 18;               //! number of sectors in TRD
+  static const unsigned int fkMaxRefTracksPerStack = 25000;  //! maximum number of ref tracks per stack
+  static const unsigned int fkMaxRefTracks = 25000;          //! maximum number of ref tracks
+
+  static const unsigned int fkElectronTriggerHSE = 0x1;      //! HSE electron trigger flag
+  static const unsigned int fkElectronTriggerHQU = 0x2;      //! HSE electron trigger flag
+
+  AliHLTEventID_t fEventId;                                  //! hlt internal event id
+  Int_t fRunNumber;                                          //! run number
+  TString* fChunkId;                                         //! chunk identifier
+  UInt_t fSectorsWithData;                                   //! data present flags for each sector
+  Bool_t fIsMinBiasEvent;                                    //! indicates a minimum bias event
+  Bool_t fIsTRDElectronEvent;                                //! indicates a TRD L1 electron triggered event
+  Bool_t fESDtracksPresent;                                  //! indicates that ESD tracks are present
+  Bool_t fHLTtracksPresent;                                  //! indicates that HLT raw tracks are present
+
+  AliTRDgeometry* fTRDGeometry;                              //! instance of TRD geometry
+  AliESDEvent* fEsdEvent;                                    //! current ESD event
+  AliTRDonlineTrackingDataContainer* fTrackingData;          //! container for TRD tracking data
+  vector<AliHLTGlobalBarrelTrack>* fHLTTracks;               //! HLT raw tracks
+  AliESDtrackCuts* fRefTrackCuts;                            //! reference track cuts
+
+#ifdef __TRDHLTDEBUG
+  AliTRDtrackingEventDisplay* fEventDisplay;                 //! event rendering
+  AliHLTComponentBenchmark* fBenchmark;                      //! benchmark instance
+#endif
+
+  TObjArray* fHistArray;
+  TH1I* fHistMatchRating;                                    //! histo
+  TH2I* fHistMatchRatingByPt;                                //! histo
+  TH2I* fHistMatchRatingByPid;                               //! histo
+  TH1I* fHistTrackPt;                                        //! histo
+  TH1I* fHistTrackPtMatched;                                 //! histo
+  TH2I* fHistTrackPtCorr;                                    //! histo
+  TH1I* fHistTrackPid;                                       //! histo
+  TH1I* fHistTrackPidMatched;                                //! histo
+  TH1I* fHistElectronCandidatePt;                            //! histo
+  TH1I* fHistElectronCandidateMatchedPt;                     //! histo
+  TH1I* fHistElectronCandidatePid;                           //! histo
+  TH1I* fHistElectronCandidateMatchedPid;                    //! histo
+  TH2I* fHistRefTrackPid;                                    //! histo
+  TH2I* fHistMatchedRefTrackPid;                             //! histo
+  TH2I* fHistPIDvsTruncPID;                                  //! histo
+  TH2I* fHistElectronFalsePIDvsTruncPID;                     //! histo
+  TH2I* fHistElectronConfirmedPIDvsTruncPID;                 //! histo
+  TH2I* fHistTrackMatchingCombinations;                      //! histo
+  TH1I* fHistElectronTriggerBaseMinBias;                     //! histo
+  TH1I* fHistElectronTriggerBaseTrdL1;                       //! histo
+
+  ClassDef(AliHLTTRDTriggerComponent, 0)
+};
+
+#endif //ALIHLTTRDTRIGGERCOMPONENT_H
index af92f8b..6c1f069 100644 (file)
@@ -54,6 +54,7 @@
 //#include "AliHLTTriggerFastJet.h"
 #include "AliHLTFastJetMonitorComponent.h"
 #include "AliHLTEmcalElectronMonitorComponent.h"
+#include "AliHLTTRDTriggerComponent.h"
 
 /** global instance for agent registration */
 AliHLTTriggerAgent gAliHLTTriggerAgent;
@@ -100,6 +101,7 @@ int AliHLTTriggerAgent::RegisterComponents(AliHLTComponentHandler* pHandler) con
   //pHandler->AddComponent(new AliHLTTriggerFastJet);
   pHandler->AddComponent(new AliHLTFastJetMonitorComponent);
   pHandler->AddComponent(new AliHLTEmcalElectronMonitorComponent);
+  pHandler->AddComponent(new AliHLTTRDTriggerComponent);
  return 0;
 }