From 091e10eb7df8f9048e3604c3a4d2823a08908770 Mon Sep 17 00:00:00 2001
From: Attila Krasznahorkay <krasznaa@cern.ch>
Date: Wed, 12 Mar 2014 13:32:46 +0100
Subject: [PATCH] Fixing the python configuration after the last change
 (AnalysisTriggerAlgs-00-01-35)

---
 .../AnalysisTriggerAlgs/cmt/requirements      |  37 +
 .../AnalysisTriggerAlgs/doc/mainpage.h        |  51 ++
 .../python/AnalysisTriggerAlgsConfig.py       | 101 +++
 .../share/AnalysisTrigger_jobOptions.py       |   6 +
 .../share/Data09MuCTPIFix_jobOfragment.py     |  40 +
 .../share/FakeHLT_jobOptions.py               |   0
 .../src/MuCTPI_RDOToRoIBResult.cxx            | 132 +++
 .../src/MuCTPI_RDOToRoIBResult.h              |  53 ++
 .../src/RoIBResultToAOD.cxx                   | 762 ++++++++++++++++
 .../AnalysisTriggerAlgs/src/RoIBResultToAOD.h | 103 +++
 .../src/RoIBResultToxAOD.cxx                  | 851 ++++++++++++++++++
 .../src/RoIBResultToxAOD.h                    | 128 +++
 .../AnalysisTriggerAlgs_entries.cxx           |  25 +
 .../components/AnalysisTriggerAlgs_load.cxx   |   2 +
 14 files changed, 2291 insertions(+)
 create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/cmt/requirements
 create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/doc/mainpage.h
 create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/python/AnalysisTriggerAlgsConfig.py
 create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/AnalysisTrigger_jobOptions.py
 create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/Data09MuCTPIFix_jobOfragment.py
 create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/FakeHLT_jobOptions.py
 create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.cxx
 create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.h
 create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.cxx
 create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.h
 create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.cxx
 create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.h
 create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_entries.cxx
 create mode 100644 PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_load.cxx

diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/cmt/requirements b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/cmt/requirements
new file mode 100644
index 00000000000..1a64b47ab89
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/cmt/requirements
@@ -0,0 +1,37 @@
+package AnalysisTriggerAlgs
+
+author Tadashi.Maeno       <Tadashi.Maeno@cern.ch>
+author Attila Kraznahorkay Jr. <Attila.Krasznahorkay@cern.ch>
+author Alan Watson         <Alan.Watson@cern.ch>
+author Wolfgang Ehrenfeld  <Wolfgang.Ehrenfeld@desy.de>
+
+private
+
+use AtlasPolicy           AtlasPolicy-*
+use GaudiInterface        GaudiInterface-*          External
+use AtlasCLHEP            AtlasCLHEP-*              External
+use AthenaKernel          AthenaKernel-*            Control
+use AthenaBaseComps       AthenaBaseComps-*         Control
+use StoreGate             StoreGate-*               Control
+use EventInfo             EventInfo-*               Event
+use xAODTrigger		  xAODTrigger-*		    Event/xAOD
+use xAODTriggerCnv	  xAODTriggerCnv-*	    Event/xAOD
+
+
+# LVL1 simulation packages:
+use TrigT1Interfaces      TrigT1Interfaces-*        Trigger/TrigT1
+use TrigT1Result          TrigT1Result-*            Trigger/TrigT1
+use TrigT1CaloEvent       TrigT1CaloEvent-*         Trigger/TrigT1
+use TrigT1CaloToolInterfaces TrigT1CaloToolInterfaces-* Trigger/TrigT1
+
+# Trigger configuration packages:
+use TrigConfInterfaces     TrigConfInterfaces-*     Trigger/TrigConfiguration
+use TrigConfL1Data         TrigConfL1Data-*         Trigger/TrigConfiguration
+
+use AnalysisTriggerEvent  AnalysisTriggerEvent-*    PhysicsAnalysis/AnalysisTrigger
+
+library AnalysisTriggerAlgs *.cxx components/*.cxx
+apply_pattern component_library
+
+apply_pattern declare_joboptions files="*.py"
+apply_pattern declare_python_modules files="*.py"
diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/doc/mainpage.h b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/doc/mainpage.h
new file mode 100644
index 00000000000..8b7d0b37953
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/doc/mainpage.h
@@ -0,0 +1,51 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+@mainpage AnalysisTriggerAlgs Package
+
+@author Tadashi.Maeno <Tadashi.Maeno@cern.ch>
+@author Attila Kraznahorkay Jr. <Attila.Krasznahorkay@cern.ch>
+@author Alan Watson <Alan.Watson@cern.ch>
+@author Wolfgang Ehrenfeld <Wolfgang.Ehrenfeld@desy.de>
+
+@section AnalysisTriggerAlgsIntro Introduction
+
+This package contains some algorithms to create Trigger ESD/AOD objects.
+
+@section AnalysisTriggerAlgsOverview Class Overview
+  The AnalysisTriggerAlgs package contains of following classes:
+
+  - RoIBResultToAOD: convert ROIB::RoIBResult into CTP_Decision and LVL1_ROI.
+                     One important feature is the rebuilding of the trigger type.
+		     For the configuration see section \ref AnalysisTriggerAlgsJobOptions.
+
+@section AnalysisTriggerAlgsJobOptions Job Options
+  The algorithms of the AnalysisTriggerAlgs package can be configured using configurables.
+  For an example see AnalysisTrigger_jobOptions.py:
+  @include AnalysisTrigger_jobOptions.py
+
+  Configuration classes for the RoIBResultToAOD algorithm are:
+  - AnalysisTriggerAlgsConfig::DefaultRoIBResultToAOD: common setup (do not use directly)
+  - AnalysisTriggerAlgsConfig::RoIBResultToAOD: configuration for running in a reconstruciton job
+  - AnalysisTriggerAlgsConfig::RoIBResultToAODLegacy: configuration for running in a reconstruciton job rebuilding the LVL1 trigger type
+
+  The list of properties for each algorithm can be found here:
+  - @link RoIBResultToAOD::RoIBResultToAOD @endlink
+
+@section AnalysisTriggerAlgs Extra Pages
+
+- @ref used_AnalysisTriggerAlgs
+- @ref requirements_AnalysisTriggerAlgs
+*/
+
+/**
+   @page used_AnalysisTriggerAlgs Used Packages
+   @htmlinclude used_packages.html
+*/
+
+/**
+   @page requirements_AnalysisTriggerAlgs Requirements
+   @include requirements
+*/
diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/python/AnalysisTriggerAlgsConfig.py b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/python/AnalysisTriggerAlgsConfig.py
new file mode 100644
index 00000000000..208e1e489fe
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/python/AnalysisTriggerAlgsConfig.py
@@ -0,0 +1,101 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+
+# Import the genConf made configurable:
+from AnalysisTriggerAlgs.AnalysisTriggerAlgsConf import RoIBResultToxAOD as genConfRoIBResultToAOD
+
+class DefaultRoIBResultToAOD( genConfRoIBResultToAOD ):
+
+    def __init__( self, name = "DefaultRoIBResultToAOD" ):
+        super( DefaultRoIBResultToAOD, self ).__init__( name )
+
+        # Get a logger:
+        from AthenaCommon.Logging import logging
+        log = logging.getLogger( 'RoIBResultToAOD' )
+
+        #
+        # Get the handle to the LVL1 config service:
+        #
+        from AthenaCommon.AppMgr import ServiceMgr
+        if hasattr( ServiceMgr, "TrigConfigSvc" ):
+            log.info( "Using ServiceMgr.TrigConfigSvc for LVL1 configuration" )
+            lvl1ConfigSvc = ServiceMgr.TrigConfigSvc
+        elif hasattr( ServiceMgr, "LVL1ConfigSvc" ):
+            log.info( "Using ServiceMgr.LVL1ConfigSvc for LVL1 configuration" )
+            lvl1ConfigSvc = ServiceMgr.LVL1ConfigSvc
+        else:
+            log.warning( "Did not find a configured LVL1 configuration service!" )
+            log.warning( "Will assume that one called 'TrigConf::TrigConfigSvc/TrigConfigSvc'" )
+            log.warning( "will be available at runtime. --> The job could crash later on!" )
+            lvl1ConfigSvc = "TrigConf::TrigConfigSvc/TrigConfigSvc" # Hopefully it will be configured correctly
+                                                                    # later on in the job configuration...
+
+        # Set the handle for the algorithm:
+        self.LVL1ConfigSvc = lvl1ConfigSvc
+
+        #
+        # Set up the L1Calo tools:
+        #
+        from AthenaCommon.AppMgr import ToolSvc
+
+        log.info( "will add L1EmTauTools instance to ToolSvc" )
+        from TrigT1CaloTools.TrigT1CaloToolsConf import LVL1__L1EmTauTools
+        theL1EmTauTools = LVL1__L1EmTauTools( "L1EmTauTools" )
+        theL1EmTauTools.LVL1ConfigSvc = lvl1ConfigSvc
+        ToolSvc += theL1EmTauTools
+        self.L1EmTauTools = ToolSvc.L1EmTauTools
+
+        log.info( "will add L1JetTools instance to ToolSvc" )
+        from TrigT1CaloTools.TrigT1CaloToolsConf import LVL1__L1JetTools
+        theL1JetTools = LVL1__L1JetTools( "L1JetTools" )
+        theL1JetTools.LVL1ConfigSvc = lvl1ConfigSvc
+        ToolSvc += theL1JetTools
+        self.L1JetTools = ToolSvc.L1JetTools
+
+        #
+        # Set up the muon RoI services:
+        #
+        if not hasattr( ServiceMgr, 'LVL1RPC::RPCRecRoiSvc' ):
+            log.info( "will setup LVL1RPC::RPCRecRoiSvc and add instance to ServiceMgr" )
+            from TrigT1RPCRecRoiSvc.TrigT1RPCRecRoiConfig import RPCRecRoiConfig
+            ServiceMgr += RPCRecRoiConfig()
+        else:
+            log.info( "will _not_ add LVL1RPC::RPCRecRoiSvc instance to ServiceMgr since it already exists" )
+
+        if not hasattr( ServiceMgr, 'LVL1TGC::TGCRecRoiSvc' ):
+            log.info( "will setup LVL1RPC::TGCRecRoiSvc and add instance to ServiceMgr" )
+            from TrigT1TGCRecRoiSvc.TrigT1TGCRecRoiConfig import TGCRecRoiConfig
+            ServiceMgr += TGCRecRoiConfig()
+        else:
+            log.info( "will _not_ add LVL1RPC::TGCRecRoiSvc instance to ServiceMgr since it already exists" )
+
+
+    def setDefaults( self, handle ):
+        # switch off reading of Muon/Calo inputs if subsystem is not running
+        from AthenaCommon.DetFlags import DetFlags
+        handle.DoCalo = DetFlags.detdescr.Calo_on()
+        handle.DoMuon = DetFlags.detdescr.Muon_on()
+
+class RoIBResultToAOD( DefaultRoIBResultToAOD ):
+
+    def __init__( self, name = "RoIBResultToAOD" ):
+        super( RoIBResultToAOD, self ).__init__( name )
+
+    def setDefaults( self, handle ):
+        DefaultRoIBResultToAOD.setDefaults( handle )
+
+class RoIBResultToAODLegacy( DefaultRoIBResultToAOD ):
+
+    def __init__(self, name = "RoIBResultToAODLegacy"):
+        super( RoIBResultToAODLegacy, self ).__init__( name )
+
+        # configure legacy trigger type building
+        self.EGammaItem = ["iEM25I","iEM15I","iMU10+EM15I"]
+        self.TauHadItem = ["iHA25I+TM30"]
+        self.JetItem    = ["iJT200","i3JT90","i4JT65","iJT60+TM60"]
+        self.ESumItem   = ["iHA25I+TM30","iJT60+TM60"]
+        self.HighMuItem = ["iMU20"]
+        self.LowMuItem  = ["i2MU6","iMU10+EM15I"]
+
+    def setDefaults( self, handle ):
+        DefaultRoIBResultToAOD.setDefaults( handle )
diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/AnalysisTrigger_jobOptions.py b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/AnalysisTrigger_jobOptions.py
new file mode 100644
index 00000000000..91d3785e806
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/AnalysisTrigger_jobOptions.py
@@ -0,0 +1,6 @@
+
+from AthenaCommon.AlgSequence import AlgSequence
+topSequence = AlgSequence()
+
+from AnalysisTriggerAlgs.AnalysisTriggerAlgsConfig import RoIBResultToAOD
+topSequence += RoIBResultToAOD("RoIBResultToAOD")
diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/Data09MuCTPIFix_jobOfragment.py b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/Data09MuCTPIFix_jobOfragment.py
new file mode 100644
index 00000000000..d0ef7dd2376
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/Data09MuCTPIFix_jobOfragment.py
@@ -0,0 +1,40 @@
+# $Id: Data09MuCTPIFix_jobOfragment.py 275499 2010-01-27 18:25:00Z krasznaa $
+#
+# JobOptions fragment fixing the LVL1_ROI object in the ESD files for the
+# problem in the MuCTPI. (Present for all 2009 collision data.)
+#
+
+# Create a new logger, saving the old one if it already exists with this name:
+if "logger" in dir(): orig_logger = logger
+from AthenaCommon.Logging import logging
+logger = logging.getLogger( "Data09MuCTPIFix" )
+
+# Set up the trigger configuration:
+from TriggerJobOpts.TriggerConfigGetter import TriggerConfigGetter
+TriggerConfigGetter( "ReadPool" )
+logger.info( "Set up the trigger configuration service" )
+
+# Access the algorithm sequence:
+from AthenaCommon.AlgSequence import AlgSequence
+theJob = AlgSequence()
+
+#
+# Fix the RoIBResult object based on the MuCTPI_RDO:
+#
+from AnalysisTriggerAlgs.AnalysisTriggerAlgsConf import MuCTPI_RDOToRoIBResult
+theJob += MuCTPI_RDOToRoIBResult()
+theJob.MuCTPI_RDOToRoIBResult.RoIBOutputKey = "CorrectRoIBResult"
+logger.info( "Added the RoIBResult object fixer algorithm" )
+
+#
+# Create the LVL1_ROI object with the correct muon content.
+# Warning: The Calo RoIs should be taken from the original LVL1_ROI object!
+#
+from AnalysisTriggerAlgs.AnalysisTriggerAlgsConfig import RoIBResultToAOD
+theJob += RoIBResultToAOD()
+theJob.RoIBResultToAOD.DoCalo = False
+theJob.RoIBResultToAOD.RoIBResultInputKey = "CorrectRoIBResult"
+theJob.RoIBResultToAOD.LVL1_ROIOutputKey = "LVL1_ROI"
+
+# Restore the original logger if necessary:
+if "orig_logger" in dir(): logger = orig_logger
diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/FakeHLT_jobOptions.py b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/share/FakeHLT_jobOptions.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.cxx b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.cxx
new file mode 100644
index 00000000000..00ca790692e
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.cxx
@@ -0,0 +1,132 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: MuCTPI_RDOToRoIBResult.cxx 275499 2010-01-27 18:25:00Z krasznaa $
+
+// STL include(s):
+#include <iomanip>
+
+// Gaudi/Athena include(s):
+#include "AthenaKernel/errorcheck.h"
+
+// Trigger include(s):
+#include "TrigT1Result/MuCTPI_RDO.h"
+#include "TrigT1Result/RoIBResult.h"
+#include "TrigT1Result/MuCTPIResult.h"
+#include "TrigT1Result/MuCTPIRoI.h"
+
+// Local include(s):
+#include "MuCTPI_RDOToRoIBResult.h"
+
+MuCTPI_RDOToRoIBResult::MuCTPI_RDOToRoIBResult( const std::string& name,
+                                                ISvcLocator* pSvcLocator )
+   : AthAlgorithm( name, pSvcLocator ) {
+
+   declareProperty( "MuCTPIInputKey", m_muctpiInputKey = "MUCTPI_RDO" );
+   declareProperty( "RoIBInputKey", m_roibInputKey = "RoIBResult" );
+   declareProperty( "RoIBOutputKey", m_roibOutputKey = "CorrectRoIBResult" );
+}
+
+StatusCode MuCTPI_RDOToRoIBResult::execute() {
+
+   ATH_MSG_DEBUG( "Executing the MuCTPI RoI fixer algorithm" );
+
+   //
+   // Retrieve the (hopefully) correct MuCTPI_RDO object:
+   //
+   const MuCTPI_RDO* muctpi_rdo = 0;
+   CHECK( evtStore()->retrieve( muctpi_rdo, m_muctpiInputKey ) );
+   ATH_MSG_VERBOSE( "Retrieved the MuCTPI_RDO object with key: "
+                    << m_muctpiInputKey );
+
+   //
+   // Retrieve the (muon-wise) wrong RoIBResult object:
+   //
+   const ROIB::RoIBResult* roibresult = 0;
+   CHECK( evtStore()->retrieve( roibresult, m_roibInputKey ) );
+   ATH_MSG_VERBOSE( "Retrieved the old RoIBResult object with key:"
+                    << m_roibInputKey );
+
+   // Create the correct RoI vector from the RDO data:
+   ATH_MSG_VERBOSE( "Now creating the correct RoIs..." );
+   std::vector< ROIB::MuCTPIRoI > roi_vector;
+
+   uint32_t bcid = multiplicityBCID( muctpi_rdo->candidateMultiplicity() );
+
+   //
+   // Loop over all "data words" and select the ones that should've been
+   // sent ot LVL2:
+   //
+   std::vector< uint32_t >::const_iterator dword_itr = muctpi_rdo->dataWord().begin();
+   std::vector< uint32_t >::const_iterator dword_end = muctpi_rdo->dataWord().end();
+   for( ; dword_itr != dword_end; ++dword_itr ) {
+
+      // Select which candidates should've gone to LVL2:
+      if( roiBCID( *dword_itr ) != bcid ) continue;
+      if( ! roiAccepted( *dword_itr ) ) continue;
+
+      // Save the candidate:
+      roi_vector.push_back( ROIB::MuCTPIRoI( toRoIWord( *dword_itr ) ) );
+      ATH_MSG_VERBOSE( "  - Processed data word: 0x" << std::hex << std::setw( 8 )
+                       << std::setfill( '0' ) << *dword_itr );
+   }
+
+   //
+   // Create the new MuCTPI result:
+   //
+   ROIB::MuCTPIResult newResult( roibresult->muCTPIResult().header(),
+                                 roibresult->muCTPIResult().trailer(),
+                                 roi_vector );
+
+   //
+   // Create and save the new RoIBResult object:
+   //
+   ROIB::RoIBResult* new_roibresult = new ROIB::RoIBResult( newResult,
+                                                            roibresult->cTPResult(),
+                                                            roibresult->jetEnergyResult(),
+                                                            roibresult->eMTauResult() );
+   CHECK( evtStore()->record( new_roibresult, m_roibOutputKey ) );
+   ATH_MSG_VERBOSE( "Saved the fixed RoIBResult object with key: "
+                    << m_roibOutputKey );
+
+   return StatusCode::SUCCESS;
+}
+
+/**
+ * @param multi_word Multiplicity word from the MuCTPI_RDO object
+ * @returns The BCID stored in the multiplicity word
+ */
+uint32_t MuCTPI_RDOToRoIBResult::multiplicityBCID( uint32_t multi_word ) {
+
+   return ( ( multi_word >> 18 ) & 0x7 );
+}
+
+/**
+ * @param data_word Data word from the MuCTPI_RDO object
+ * @returns The RoI word created from the data word
+ */
+uint32_t MuCTPI_RDOToRoIBResult::toRoIWord( uint32_t data_word ) {
+
+   return ( ( ( data_word & 0x8000000 ) >> 4 ) | ( ( data_word & 0x3fe0000 ) >> 3 ) |
+            ( data_word & 0x3fff ) );
+}
+
+/**
+ * @param data_word Data word from the MuCTPI_RDO object
+ * @returns the BCID stored in the data word
+ */
+uint32_t MuCTPI_RDOToRoIBResult::roiBCID( uint32_t data_word ) {
+
+   return ( ( data_word >> 14 ) & 0x7 );
+}
+
+/**
+ * @param data_word Data word from the MuCTPI_RDO object
+ * @returns <code>true</code> if the candidate was destined to go to LVL2,
+ *          <code>false</code> otherwise
+ */
+bool MuCTPI_RDOToRoIBResult::roiAccepted( uint32_t data_word ) {
+
+   return ( ( data_word >> 26 ) & 0x1 );
+}
diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.h b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.h
new file mode 100644
index 00000000000..5165d0f4e29
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/MuCTPI_RDOToRoIBResult.h
@@ -0,0 +1,53 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: MuCTPI_RDOToRoIBResult.h 275499 2010-01-27 18:25:00Z krasznaa $
+#ifndef ANALYSISTRIGGERALGS_MUCTPI_RDOTOROIBRESULT_H
+#define ANALYSISTRIGGERALGS_MUCTPI_RDOTOROIBRESULT_H
+
+// STL include(s):
+#include <string>
+
+// Gaudi/Athena include(s):
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+/**
+ *  @short Algorithm fixing the muon RoI information in the data
+ *
+ *         This algorithm can create a fixed ROIB::RoIBResult object from the
+ *         incorrect object in the data, plus the MuCTPI_RDO readout data.
+ *
+ * @author Attila Krasznahorkay Jr.
+ *
+ * $Revision: 275499 $
+ * $Date: 2010-01-27 19:25:00 +0100 (Wed, 27 Jan 2010) $
+ */
+class MuCTPI_RDOToRoIBResult : public AthAlgorithm {
+
+public:
+   /// Regular algorithm constructor
+   MuCTPI_RDOToRoIBResult( const std::string& name, ISvcLocator* pSvcLocator );
+
+   /// Regular algorithm execure function
+   virtual StatusCode execute();
+
+private:
+   /// Extract the BCID stored in the multiplicity word
+   static uint32_t multiplicityBCID( uint32_t multi_word );
+   /// Transform a data word into an RoI word
+   static uint32_t toRoIWord( uint32_t data_word );
+   /// Extract the BCID stored in the data word
+   static uint32_t roiBCID( uint32_t data_word );
+   /// Extract whether the candidate was accepted to be sent to LVL2
+   static bool roiAccepted( uint32_t data_word );
+
+   std::string m_muctpiInputKey; ///< Key of the MuCTPI_RDO object
+   std::string m_roibInputKey; ///< Key of the old (incorrect) RoIBResult object
+   std::string m_roibOutputKey; ///< Key of the new (correct) RoIBResult object
+
+}; // class MuCTPI_RDOToRoIBResult
+
+#endif // ANALYSISTRIGGERALGS_MUCTPI_RDOTOROIBRESULT_H
diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.cxx b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.cxx
new file mode 100644
index 00000000000..d7a1022abf2
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.cxx
@@ -0,0 +1,762 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: RoIBResultToAOD.cxx 587265 2014-03-12 09:45:45Z krasznaa $
+
+// STL include(s):
+#include <algorithm>
+#include <cmath>
+
+// Gaudi/Athena include(s):
+#include "AthenaKernel/errorcheck.h"
+#include "CLHEP/Units/SystemOfUnits.h"
+#include "EventInfo/EventInfo.h"
+#include "EventInfo/EventID.h"
+#include "EventInfo/EventType.h"
+#include "EventInfo/TriggerInfo.h"
+
+// LVL1 trigger include(s):
+#include "TrigT1Interfaces/TriggerTypeWord.h"
+#include "TrigT1Interfaces/RecMuonRoI.h"
+#include "TrigT1Interfaces/RecMuonRoiSvc.h"
+#include "TrigT1Interfaces/RecEmTauRoI.h"
+#include "TrigT1Interfaces/RecJetRoI.h"
+#include "TrigT1Interfaces/RecEnergyRoI.h"
+#include "TrigT1Interfaces/JEPRoIDecoder.h"
+#include "TrigT1Interfaces/TrigT1CaloDefs.h"
+#include "TrigT1Result/RoIBResult.h"
+#include "TrigT1Result/CTPResult.h"
+#include "TrigT1CaloToolInterfaces/IL1EmTauTools.h"
+#include "TrigT1CaloToolInterfaces/IL1JetTools.h"
+#include "TrigT1CaloEvent/TriggerTowerCollection.h"
+#include "TrigT1CaloEvent/JetElementCollection.h"
+#include "TrigT1CaloEvent/CPMTower.h"
+#include "TrigT1CaloEvent/JetInput.h"
+#include "TrigConfL1Data/L1DataDef.h"
+#include "TrigConfL1Data/TriggerThreshold.h"
+
+// Trigger configuration interface includes:
+#include "TrigConfL1Data/CTPConfig.h"
+#include "TrigConfL1Data/Menu.h"
+#include "TrigConfL1Data/TriggerItem.h"
+
+// Include for the configuration service:
+#include "TrigConfInterfaces/ILVL1ConfigSvc.h"
+
+// LVL1 AOD event include(s):
+#include "AnalysisTriggerEvent/CTP_Decision.h"
+#include "AnalysisTriggerEvent/LVL1_ROI.h"
+
+// Local include(s):
+#include "RoIBResultToAOD.h"
+
+using namespace TrigConf;
+
+RoIBResultToAOD::RoIBResultToAOD( const std::string& name, ISvcLocator* pSvcLocator )
+  : AthAlgorithm( name, pSvcLocator ),
+    m_configSvc( "TrigConf::LVL1ConfigSvc/LVL1ConfigSvc", name ),
+    m_recRPCRoiSvc( LVL1::ID_RecRpcRoiSvc, name ),
+    m_recTGCRoiSvc( LVL1::ID_RecTgcRoiSvc, name ),
+    m_EmTauTool( "LVL1::L1EmTauTools/L1EmTauTools" ),
+    m_JetTool( "LVL1::L1JetTools/L1JetTools" ) {
+
+   // services
+   declareProperty( "LVL1ConfigSvc", m_configSvc, "LVL1 Config Service");
+   declareProperty( "RecRpcRoiSvc", m_recRPCRoiSvc, "RPC Rec Roi Service");
+   declareProperty( "RecTgcRoiSvc", m_recTGCRoiSvc, "TGC Rec Roi Service");
+
+   // tools
+   declareProperty( "L1EmTauTools", m_EmTauTool,
+                    "Tool for calculation of EmTau trigger sums per RoI");
+   declareProperty( "L1JetTools", m_JetTool,
+                    "Tool for calculation of Jet cluster sums per RoI");
+
+   // Properties: input selection
+   declareProperty( "DoCalo", m_doCalo = true, "Use inputs from Calo system" );
+   declareProperty( "DoMuon", m_doMuon = true, "Use inputs from Muon system" );
+
+   // Properties: rebuilding trigger type
+   declareProperty( "EGammaItem", m_egammaItem,
+                    "List of LVL1 items for e/gamma trigger type" );
+   declareProperty( "TauHadItem", m_tauhadItem,
+                    "List of LVL1 items for tau trigger type" );
+   declareProperty( "JetItem", m_jetItem,
+                    "List of LVL1 items for jet trigger type" );
+   declareProperty( "ESumItem", m_esumItem,
+                    "List of LVL1 items for energy sum trigger type" );
+   declareProperty( "HighMuItem", m_highmuItem,
+                    "List of LVL1 items for high pt muon trigger type" );
+   declareProperty( "LowMuItem", m_lowmuItem,
+                    "List of LVL1 items for low pt muon trigger type" );
+
+   // Properties: StoreGate keys
+   m_TriggerTowerLocation       = LVL1::TrigT1CaloDefs::TriggerTowerLocation;
+   m_JetElementLocation         = LVL1::TrigT1CaloDefs::JetElementLocation;
+   declareProperty( "TriggerTowerLocation", m_TriggerTowerLocation ) ;
+   declareProperty( "JetElementLocation",   m_JetElementLocation ) ;
+   declareProperty( "RoIBResultInputKey", m_roibInputKey = "RoIBResult" );
+   declareProperty( "LVL1_ROIOutputKey", m_lvl1RoIOutputKey = "LVL1_ROI" );
+
+   m_retrievedEmTauTool = false;
+   m_retrievedJetTool = false;
+
+}
+
+// Initialize
+StatusCode RoIBResultToAOD::initialize() {
+
+   ATH_MSG_INFO( "initializing " << name()
+                 << " - package version " << PACKAGE_VERSION );
+
+   // Print system info
+   if( m_doCalo == false ) {
+      ATH_MSG_WARNING( "Inputs from LVL1 Calo systems switched off" );
+   }
+   if( m_doMuon == false ) {
+      ATH_MSG_WARNING( "Inputs from LVL1 Muon systems switched off" );
+   }
+
+   // Connect to the LVL1ConfigSvc for the trigger configuration:
+   CHECK( m_configSvc.retrieve() );
+   ATH_MSG_DEBUG( "Connected to " << m_configSvc.typeAndName() );
+
+   if( m_doMuon ) {
+
+      // Get the RPC RecRoI service
+      CHECK( m_recRPCRoiSvc.retrieve() );
+      ATH_MSG_DEBUG( "Connected to " << m_recRPCRoiSvc.typeAndName() );
+
+      // Get the TGC RecRoI service
+      CHECK( m_recTGCRoiSvc.retrieve() );
+      ATH_MSG_DEBUG( "Connected to " << m_recTGCRoiSvc.typeAndName() );
+
+   } // if (m_doMuon)
+
+   if( m_doCalo ) {
+
+      // Get tools
+      CHECK( m_EmTauTool.retrieve() );
+      ATH_MSG_DEBUG( "Got " << m_EmTauTool.typeAndName() );
+      m_retrievedEmTauTool = true;
+
+      CHECK( m_JetTool.retrieve() );
+      ATH_MSG_DEBUG( "Got " << m_JetTool.typeAndName() );
+      m_retrievedJetTool = true;
+
+   } // if (m_doCalo)
+
+   return StatusCode::SUCCESS;
+}
+
+// finalize
+StatusCode RoIBResultToAOD::finalize() {
+
+   ATH_MSG_INFO( "Finalizing " << name()
+                 << " - package version " << PACKAGE_VERSION );
+
+   return StatusCode::SUCCESS;
+}
+
+// execute
+StatusCode RoIBResultToAOD::execute() {
+
+   ATH_MSG_DEBUG( "in execute()" );
+
+   ///////////////////////////////////////////////////////////////////////////
+   // build CTP decision
+   if( buildCTP_Decision().isFailure() ) {
+      ATH_MSG_WARNING( "Problems building CTP_Decision" );
+   }
+
+   ///////////////////////////////////////////////////////////////////////////
+   // Trigger Info
+
+   // retrieve event info
+   const DataHandle< EventInfo > eventInfoBeg;
+   const DataHandle< EventInfo > eventInfoEnd;
+   CHECK( evtStore()->retrieve( eventInfoBeg, eventInfoEnd ) );
+   if( eventInfoBeg == eventInfoEnd ) {
+      ATH_MSG_ERROR( "No event info objects" );
+      return StatusCode::RECOVERABLE;
+   }
+
+   // get key
+   const std::string eventInfoKey = eventInfoBeg.key();
+
+   // build TriggerInfo
+   EventInfo* eventInfo = const_cast< EventInfo* >( eventInfoBeg.cptr() );
+   TriggerInfo* tInfo = eventInfo->trigger_info();
+   TriggerInfo* triggerInfo;
+   if( tInfo != 0 ) {
+      triggerInfo = new TriggerInfo( *tInfo );
+   } else {
+      triggerInfo = new TriggerInfo( 0, 0, 0,
+                                     std::vector< TriggerInfo::number_type>( 0 ),
+                                     std::vector< TriggerInfo::number_type>( 0 ),
+                                     std::vector< TriggerInfo::StreamTag>( 0 ) );
+   }
+
+   // set TriggerInfo
+   eventInfo->setTriggerInfo( triggerInfo );
+
+   // dump
+   ATH_MSG_DEBUG( MSG::dec << "EventInfo:" << eventInfoKey );
+   ATH_MSG_DEBUG( *( eventInfo->event_ID() ) );
+   ATH_MSG_DEBUG( "[TimeStamp] = " << eventInfo->event_ID()->time_stamp() );
+   ATH_MSG_DEBUG( "[Type] = " << eventInfo->event_type()->user_type() );
+   ATH_MSG_DEBUG( "[BitMask]" );
+   for( EventType::BitMaskIterator bitIt = eventInfo->event_type()->bit_mask_begin();
+        bitIt != eventInfo->event_type()->bit_mask_end(); ++bitIt ) {
+      ATH_MSG_DEBUG( *bitIt );
+   }
+
+   if( triggerInfo != 0 ) {
+      ATH_MSG_DEBUG( MSG::hex << "[L1ID] = "<< triggerInfo->extendedLevel1ID() );
+      ATH_MSG_DEBUG( "[TriggerType] = "<< triggerInfo->level1TriggerType() );
+      ATH_MSG_DEBUG( "[L1Info] = "<< triggerInfo->level1TriggerInfo() );
+      ATH_MSG_DEBUG( "[L2Info] = "<< triggerInfo->level2TriggerInfo() );
+      ATH_MSG_DEBUG( "[EFInfo]" );
+      const std::vector< TriggerInfo::number_type >& efInfo = triggerInfo->eventFilterInfo();
+      for( std::vector< TriggerInfo::number_type >::const_iterator itEF = efInfo.begin();
+           itEF != efInfo.end(); ++itEF ) {
+         ATH_MSG_DEBUG( *itEF );
+      }
+   }
+
+   ///////////////////////////////////////////////////////////////////////////
+   // build LVL1 ROI
+
+   LVL1_ROI *lvl1ROI = new LVL1_ROI;
+
+   ///////////////////////////////////////////////////////////////////////////
+   // retrive L1 result
+
+   const ROIB::RoIBResult *result = 0;
+   if( evtStore()->retrieve( result, m_roibInputKey ).isFailure() ) {
+      ATH_MSG_WARNING( "Could not retrieve RoIBResult. Building empty LVL1_ROI" );
+      result = 0;
+   }
+
+   ///////////////////////////////////////////////////////////////////////////
+   // Muon ROI
+
+   if( m_doMuon == true ) addMuonRoI( result, lvl1ROI );
+
+   ///////////////////////////////////////////////////////////////////////////
+   // EmTau ROI
+
+   if( m_doCalo == true ) addEmTauRoI( result, lvl1ROI );
+
+   ///////////////////////////////////////////////////////////////////////////
+   // JetEnergy ROI
+
+   if( m_doCalo == true ) addJetEnergyRoI( result, lvl1ROI );
+
+   ///////////////////////////////////////////////////////////////////////////
+   // record LVL1 ROI
+
+   CHECK( evtStore()->record( lvl1ROI, m_lvl1RoIOutputKey ) );
+   CHECK( evtStore()->setConst( lvl1ROI ) );
+
+   return StatusCode::SUCCESS;
+}
+
+StatusCode RoIBResultToAOD::buildCTP_Decision() {
+
+   ATH_MSG_DEBUG( "building CTP decision" );
+
+   CTP_Decision* ctpDecision = new CTP_Decision;
+
+   // retrive L1 result
+   const ROIB::RoIBResult *result = 0;
+   if( evtStore()->retrieve( result, m_roibInputKey ).isSuccess() ) {
+
+      // Trigger Type Word
+      bool triggerTypeLegacyFlag = false;
+      uint32_t triggerTypeWord = result->cTPResult().header().triggerType();
+
+      if( triggerTypeWord == 0 ) { // switch to legacy mode
+         ATH_MSG_DEBUG( "Building TriggerType word" );
+         triggerTypeWord = LVL1::TriggerTypeWord::Physics |
+            LVL1::TriggerTypeWord::PriorityLevel;
+         triggerTypeLegacyFlag = true;
+      }
+
+      // store TAV vector in CTP decision object
+      const std::vector< ROIB::CTPRoI > tav = result->cTPResult().TAV();
+      for( size_t i( 0 ); i < tav.size(); ++i ) {
+         ctpDecision->setWord( i, tav[ i ].roIWord() );
+      }
+
+      // search for passed items in TAV vector from CTP result
+      const std::bitset< 256 > items = ROIB::convertToBitset( tav );
+
+      for(TrigConf::ItemContainer::const_iterator item = m_configSvc->ctpConfig()->menu().items().begin(); 
+          item != m_configSvc->ctpConfig()->menu().items().end(); ++item ) {
+         if( items[ ( *item )->ctpId() ] ) {
+            // add item name to CTP_Decision
+            const std::string& itemName = ( *item )->name();
+            ctpDecision->setItem( itemName );
+            ATH_MSG_VERBOSE( "Item : " << itemName );
+
+            if( triggerTypeLegacyFlag ) {
+               ///////// compute Trigger Type Word
+               ///////// This is temporary implementation for DC2 and will be moved to
+               ///////// CTP simulation
+               // e/gamma
+               if( m_egammaItem.end() != std::find( m_egammaItem.begin(), m_egammaItem.end(),
+                                                    itemName ) )
+                  triggerTypeWord |= LVL1::TriggerTypeWord::Egamma;
+
+               // tau/hadron
+               if( m_tauhadItem.end() != std::find( m_tauhadItem.begin(), m_tauhadItem.end(),
+                                                    itemName ) )
+                  triggerTypeWord |= LVL1::TriggerTypeWord::TauHdr;
+
+               // jet
+               if( m_jetItem.end() != std::find( m_jetItem.begin(), m_jetItem.end(),
+                                                 itemName ) )
+                  triggerTypeWord |= LVL1::TriggerTypeWord::Jet;
+
+               // energy sum
+               if( m_esumItem.end() != std::find( m_esumItem.begin(), m_esumItem.end(),
+                                                  itemName ) )
+                  triggerTypeWord |= LVL1::TriggerTypeWord::EnergySum;
+
+               // high pT muon
+               if( m_highmuItem.end() != std::find( m_highmuItem.begin(), m_highmuItem.end(),
+                                                    itemName ) )
+                  triggerTypeWord |= LVL1::TriggerTypeWord::HighPtMuon;
+
+               // low pT muon
+               if( m_lowmuItem.end() != std::find( m_lowmuItem.begin(), m_lowmuItem.end(),
+                                                   itemName ) )
+                  triggerTypeWord |= LVL1::TriggerTypeWord::LowPtMuon;
+            } // if (triggerTypeLegacyFlag)
+         } // if (items[(*item)->ctpId()])
+      } // for
+
+      // set Trigger Type Word
+      ctpDecision->setTriggerTypeWord( triggerTypeWord );
+      ATH_MSG_DEBUG( "CTP_Decision: \n" + ctpDecision->dump() );
+
+   } else {
+      ATH_MSG_WARNING( "Could not retrieve RoIBResult, building empty CTP_Decision" );
+   }
+
+   // record CTP Decision
+   CHECK( evtStore()->record( ctpDecision, "CTP_Decision" ) );
+   CHECK( evtStore()->setConst( ctpDecision ) );
+
+   return StatusCode::SUCCESS;
+}
+
+void RoIBResultToAOD::addEmTauRoI( const ROIB::RoIBResult* result, LVL1_ROI* lvl1ROI ) {
+
+   ATH_MSG_DEBUG( "building EmTauRoI" );
+
+   // empty input
+   if( result == 0 ) return;
+
+   // Digit scale for calorimeter trigger
+   float caloTrigScale = m_configSvc->thresholdConfig()->caloInfo().globalScale() * CLHEP::GeV;
+   ATH_MSG_DEBUG( "caloTrigScale = " << caloTrigScale );
+
+   /** Get EmTau Thresholds from configSvc. Also fill a map of threshold names while
+       we are here - will be useful later */
+
+   std::vector< TrigConf::TriggerThreshold* > thresholds =
+      m_configSvc->ctpConfig()->menu().thresholdVector();
+   std::vector< TrigConf::TriggerThreshold* > caloThresholds;
+   std::map< int, std::string > thresholdNames;
+   for( std::vector< TrigConf::TriggerThreshold* >::const_iterator it = thresholds.begin();
+        it != thresholds.end(); ++it ) {
+      if( ( *it )->type() == L1DataDef::emType() || ( *it )->type() == L1DataDef::tauType() ) {
+         caloThresholds.push_back( *it );
+         thresholdNames.insert( std::map< int, std::string >::value_type( ( *it )->thresholdNumber(), ( *it )->name() ) );
+      }
+   }
+
+   // Tool to reconstruct EM/tau cluster & isolation sums
+   //   - need to form tower map for RoI reconstruction
+   const DataVector< LVL1::TriggerTower >* storedTTs;
+   std::map< int, LVL1::CPMTower* > cpmtowers;
+   if( m_retrievedEmTauTool ) {
+      if( evtStore()->contains< TriggerTowerCollection >( m_TriggerTowerLocation ) ) {
+         StatusCode sc = evtStore()->retrieve( storedTTs, m_TriggerTowerLocation );
+         if( sc.isSuccess() ) m_EmTauTool->mapTowers( storedTTs, &cpmtowers );
+         else ATH_MSG_WARNING( "Error retrieving TriggerTowers" );
+      }
+      else ATH_MSG_DEBUG( "No TriggerTowerCollection found at "
+                          << m_TriggerTowerLocation );
+   }
+
+   // get EmTau Result
+   const std::vector< ROIB::EMTauResult >& emtauResult = result->eMTauResult();
+
+   // reconstruct ROI
+   ATH_MSG_DEBUG( "EmTau ROI" );
+   std::vector< ROIB::EMTauResult >::const_iterator itEMR  = emtauResult.begin();
+   std::vector< ROIB::EMTauResult >::const_iterator itEMRe = emtauResult.end();
+   for( ; itEMR != itEMRe; ++itEMR ) {
+      const std::vector< ROIB::EMTauRoI >& emtauRoIV = itEMR->roIVec();
+      std::vector< ROIB::EMTauRoI >::const_iterator itEM  = emtauRoIV.begin();
+      std::vector< ROIB::EMTauRoI >::const_iterator itEMe = emtauRoIV.end();
+      for( ; itEM != itEMe; ++itEM ) {
+
+         uint32_t roIWord = itEM->roIWord();
+         ATH_MSG_DEBUG( "About to create RecEmTauRoI : " << MSG::hex
+                        << std::setw( 8 ) << roIWord << MSG::dec );
+
+         // RecRoI
+         LVL1::RecEmTauRoI recRoI( roIWord, &caloThresholds );
+
+         // AOD component
+         // ATLAS standard phi convention differs from L1 hardware convention
+         double roiPhi = recRoI.phi();
+         if( roiPhi > M_PI ) roiPhi -= 2 * M_PI;
+         EmTau_ROI roi( roIWord, recRoI.eta(), roiPhi, roIWord & 0xFFFF );
+
+         // fired thresholds
+         std::vector< unsigned int >* thrV = recRoI.thresholdsPassed();
+         std::vector< unsigned int >::const_iterator itTh  = thrV->begin();
+         std::vector< unsigned int >::const_iterator itThE = thrV->end();
+         for( ; itTh != itThE; ++itTh ) {
+            double thrValue = recRoI.triggerThreshold(*itTh)* CLHEP::GeV;
+            std::string thrName = "NameNotFound";
+            if ( thresholdNames.find( *itTh - 1 ) != thresholdNames.end() ) {
+               thrName = thresholdNames[ *itTh - 1 ];
+            }
+
+            roi.addThresholdValue( thrValue );
+            roi.addThresholdName( thrName );
+
+            ATH_MSG_DEBUG( "EmTau Thr : " << thrName
+                           << ", value = "   << thrValue );
+         }
+         delete thrV;
+
+         // Cluster ET values, reconstructed from TriggerTowers
+         if( m_retrievedEmTauTool ) {
+            m_EmTauTool->formSums( roIWord, &cpmtowers );
+            roi.setCore( m_EmTauTool->Core() * caloTrigScale );
+            roi.setEMClus( m_EmTauTool->EMClus() * caloTrigScale );
+            roi.setTauClus( m_EmTauTool->TauClus() * caloTrigScale );
+            roi.setEMIsol( m_EmTauTool->EMIsol() * caloTrigScale );
+            roi.setHadIsol( m_EmTauTool->HadIsol() * caloTrigScale );
+            roi.setHadCore( m_EmTauTool->HadCore() * caloTrigScale );
+         }
+
+         lvl1ROI->addEmTauROI( roi );
+      }
+   }
+
+   for( std::map< int, LVL1::CPMTower* >::iterator i = cpmtowers.begin();
+        i != cpmtowers.end(); ++i ) delete i->second;   
+
+   return;
+}
+
+void RoIBResultToAOD::addJetEnergyRoI( const ROIB::RoIBResult* result, LVL1_ROI* lvl1ROI ) {
+
+   ATH_MSG_DEBUG( "building JetEnergyRoI" );
+
+   // empty input
+   if( result == 0 ) return;
+
+   // Digit scale for calorimeter trigger
+   float caloTrigScale = m_configSvc->thresholdConfig()->caloInfo().globalScale() * CLHEP::GeV;
+   ATH_MSG_DEBUG( "caloTrigScale = " << caloTrigScale );
+
+   /** Get Jet/Energy Thresholds from configSvc. Also fill maps of threshold names while
+       we are here - will be useful later.
+
+       Unfortunately there are 3 types of jet threshold and 3 types of ET trigger threshold,
+       so this bit doesn't look very elegant */
+
+   std::vector< TrigConf::TriggerThreshold* > thresholds =
+      m_configSvc->ctpConfig()->menu().thresholdVector();
+   std::vector<TrigConf::TriggerThreshold*> jetThresholds;
+   std::vector<TrigConf::TriggerThreshold*> energyThresholds;
+   std::vector<TrigConf::TriggerThreshold*> jetEnergyThresholds;
+   std::map<int, std::string> jetNames;
+   std::map<int, std::string> jfNames;
+   std::map<int, std::string> jbNames;
+   std::map<int, std::string> xeNames;
+   std::map<int, std::string> teNames;
+   std::map<int, std::string> xsNames;
+   std::map<int, std::string> jeNames;
+
+   for( std::vector<TrigConf::TriggerThreshold*>::const_iterator it = thresholds.begin();
+        it != thresholds.end(); ++it ) {
+      if( ( *it )->type() == L1DataDef::jetType() ) {
+         jetThresholds.push_back( *it );
+         jetNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+      else if( ( *it )->type() == L1DataDef::jfType() ) {
+         jetThresholds.push_back( *it );
+         jfNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+      else if( ( *it )->type() == L1DataDef::jbType() ) {
+         jetThresholds.push_back( *it );
+         jbNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+      else if( ( *it )->type() == L1DataDef::xeType() ) {
+         energyThresholds.push_back( *it );
+         xeNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+      else if( ( *it )->type() == L1DataDef::teType() ) {
+         energyThresholds.push_back( *it );
+         teNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+      else if( ( *it )->type() == L1DataDef::xsType() ) {
+         energyThresholds.push_back( *it );
+         xsNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+      else if( ( *it )->type() == L1DataDef::jeType() ) {
+         jetEnergyThresholds.push_back( *it );
+         jeNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+   }
+
+   // Tool to reconstruct Jet cluster ET sums
+   //   - form input map ready for analysis
+   const DataVector< LVL1::JetElement >* storedJEs;
+   std::map< int, LVL1::JetInput* > jetInputs;
+   if( m_retrievedJetTool ) {
+      if( evtStore()->contains< JetElementCollection >( m_JetElementLocation ) ) {
+         StatusCode sc = evtStore()->retrieve( storedJEs, m_JetElementLocation );
+         if( sc.isSuccess() ) m_JetTool->mapJetInputs( storedJEs, &jetInputs );
+         else ATH_MSG_WARNING( "Error retrieving JetElements" );
+      }
+      else ATH_MSG_DEBUG( "No JetElementCollection found at "
+                          << m_JetElementLocation );
+   }
+
+   // get JetEnergy Result
+   const std::vector< ROIB::JetEnergyResult >& jetenergyResult = result->jetEnergyResult();
+
+   // reconstruct ROI
+   std::vector< ROIB::JetEnergyResult >::const_iterator itJETR  = jetenergyResult.begin();
+   std::vector< ROIB::JetEnergyResult >::const_iterator itJETRe = jetenergyResult.end();
+   for( ; itJETR != itJETRe; ++itJETR ) {
+      const std::vector< ROIB::JetEnergyRoI >& jetenergyRoIV = itJETR->roIVec();
+      std::vector< ROIB::JetEnergyRoI >::const_iterator itJET  = jetenergyRoIV.begin();
+      std::vector< ROIB::JetEnergyRoI >::const_iterator itJETe = jetenergyRoIV.end();
+      for( ; itJET != itJETe; ++itJET ) {
+         uint32_t roIWord = itJET->roIWord();
+
+         ATH_MSG_DEBUG( "Jet RoI, RoIWord = " << MSG::hex << std::setw( 8 )
+                        << roIWord << MSG::dec );
+
+         // RoI type
+         LVL1::JEPRoIDecoder conv;
+         int roiType = conv.roiType( roIWord );
+
+         // Jet ROI
+         if( roiType == LVL1::TrigT1CaloDefs::JetRoIWordType ) {
+            // RecRoI
+            LVL1::RecJetRoI recRoI( roIWord, &jetThresholds );
+
+            // AOD component
+            // Convert to ATLAS phi convention
+            double roiPhi = recRoI.phi();
+            if( roiPhi > M_PI ) roiPhi -= 2 * M_PI;
+            Jet_ROI roi( roIWord, recRoI.eta(), roiPhi, roIWord & 0xFFF );
+
+            // fired Jet thresholds
+            std::vector< unsigned int >* thrV = recRoI.thresholdsPassed();
+            std::vector< unsigned int >::const_iterator itTh  = thrV->begin();
+            std::vector< unsigned int >::const_iterator itThE = thrV->end();
+            for( ; itTh != itThE; ++itTh ) {
+               double thrValue = recRoI.triggerThreshold(*itTh)* CLHEP::GeV;
+               std::string thrName = "NameNotFound";
+               if (!recRoI.isForwardJet()) {
+                  if (jetNames.find(*itTh-1) != jetNames.end()) thrName = jetNames[*itTh-1];
+               }
+               else if (recRoI.eta() > 0) {
+                  if (jfNames.find(*itTh-1) != jfNames.end()) thrName = jfNames[*itTh-1];
+               }
+               else {
+                  if (jbNames.find(*itTh-1) != jbNames.end()) thrName = jbNames[*itTh-1];
+               }
+
+               roi.addThresholdValue( thrValue );
+               roi.addThresholdName( thrName );
+
+               ATH_MSG_DEBUG( "Jet Thr : " << thrName
+                              << ", value = " << thrValue );
+            }
+            delete thrV;
+
+            // Jet Cluster ET sums
+            if (m_retrievedJetTool) {
+               m_JetTool->formSums(roIWord, &jetInputs);
+               roi.setET4x4(m_JetTool->ET4x4()*caloTrigScale);
+               roi.setET6x6(m_JetTool->ET6x6()*caloTrigScale);
+               roi.setET8x8(m_JetTool->ET8x8()*caloTrigScale);
+            }
+
+            lvl1ROI->addJetROI(roi);
+         }
+         // Jet ET ROI
+         else if( roiType == LVL1::TrigT1CaloDefs::JetEtRoIWordType ) {
+            // AOD component
+            JetET_ROI roi( roIWord, roIWord & 0xF );
+
+            // fired Jet ET thresholds
+            for( unsigned int i = 0; i < TrigT1CaloDefs::numOfJetEtSumThresholds; ++i ) {
+               if( ( roIWord >> i ) & 0x1 ) {
+                  std::string thrName = "NameNotFound";
+                  if (jeNames.find(i) != jfNames.end()) thrName = jeNames[i];
+                  roi.addThreshold( thrName );
+                  ATH_MSG_DEBUG( "JetEt Thr : " << thrName );
+               }
+            }
+
+            lvl1ROI->addJetETROI(roi);
+         }
+         // EnergySum ROI
+         else if ( roiType == LVL1::TrigT1CaloDefs::EnergyRoIWordType0 ) {
+            uint32_t roiWord0 = roIWord;
+            ATH_MSG_DEBUG( "ET RoIWord 0 : " << MSG::hex << std::setw( 8 )
+                           << roiWord0 << MSG::dec );
+            ++itJET;
+            uint32_t roiWord1 = itJET->roIWord();
+            ATH_MSG_DEBUG( "ET RoIWord 1 : " << MSG::hex << std::setw( 8 )
+                           << roiWord1 << MSG::dec );
+            ++itJET;
+            uint32_t roiWord2 = itJET->roIWord();
+            ATH_MSG_DEBUG( "ET RoIWord 2 : " << MSG::hex << std::setw( 8 )
+                           << roiWord2 << MSG::dec );
+
+            // RecRoI
+            LVL1::RecEnergyRoI recRoI( roiWord0, roiWord1, roiWord2, &energyThresholds );
+
+            // Overflow bits  
+            unsigned int overflows = 0;  
+            if (conv.energyOverflow(roiWord0)) overflows |= 0x1;  
+            if (conv.energyOverflow(roiWord1)) overflows |= 0x2;  
+            if (conv.energyOverflow(roiWord2)) overflows |= 0x4;
+
+            // AOD component
+            EnergySum_ROI roi( roiWord0, roiWord1, roiWord2,
+                               recRoI.energyX() * caloTrigScale,
+                               recRoI.energyY() * caloTrigScale,
+                               recRoI.energyT() * caloTrigScale,
+                               ( roiWord1 >> 16 ) & 0xFF, ( roiWord2 >> 16 ) & 0xFF,
+                               ( roiWord0 >> 16 ) & 0xFF, overflows );
+
+            // fired summed ET thresholds
+            std::vector< unsigned int >* thrEtMiss = recRoI.etMissThresholdsPassed();
+            std::vector< unsigned int >::const_iterator itThEtMiss  = thrEtMiss->begin();
+            for( ; itThEtMiss != thrEtMiss->end(); ++itThEtMiss ) {
+               std::string thrName = "NameNotFound";
+               if( xeNames.find( *itThEtMiss - 1 ) != xeNames.end() ) {
+                  thrName = xeNames[ *itThEtMiss - 1 ];
+               }
+               roi.addThreshold( thrName );
+               ATH_MSG_DEBUG( "ETmiss threshold : " << thrName );
+            }
+            delete thrEtMiss;
+
+            // fired missing ET thresholds
+            std::vector< unsigned int >* thrSumEt = recRoI.sumEtThresholdsPassed();
+            std::vector< unsigned int >::const_iterator itThSumEt  = thrSumEt->begin();
+            for( ; itThSumEt != thrSumEt->end(); ++itThSumEt ) {
+               std::string thrName = "NameNotFound";
+               if( teNames.find( *itThSumEt - 1 ) != teNames.end() ) {
+                  thrName = teNames[ *itThSumEt - 1 ];
+               }
+               roi.addThreshold( thrName );
+               ATH_MSG_DEBUG( "SumET threshold : " << thrName );
+            }
+            delete thrSumEt;
+
+            // fired missing ET  significance thresholds
+            std::vector< unsigned int >* thrMETSig = recRoI.mEtSigThresholdsPassed();
+            std::vector< unsigned int >::const_iterator itThMETSig  = thrMETSig->begin();
+            for( ; itThMETSig != thrMETSig->end(); ++itThMETSig ) {
+               std::string thrName = "NameNotFound";
+               if( xsNames.find( *itThMETSig - 1 ) != xsNames.end() ) {
+                  thrName = xsNames[ *itThMETSig - 1 ];
+               }
+               roi.addThreshold( thrName );
+               ATH_MSG_DEBUG( "METSig threshold : " << thrName );
+            }
+            delete thrMETSig;
+
+            lvl1ROI->addEnergySumROI(roi);
+         }
+      }
+   }
+
+   for( std::map< int, LVL1::JetInput* >::iterator i = jetInputs.begin();
+        i != jetInputs.end(); ++i ) {
+      delete i->second;
+   }
+
+   return;
+}
+
+void RoIBResultToAOD::addMuonRoI( const ROIB::RoIBResult* result, LVL1_ROI* lvl1ROI ) {
+
+   ATH_MSG_DEBUG( "in buildMuonRoI()" );
+
+   // empty input
+   if( result == 0 ) return;
+
+   /** Get Muon Thresholds from configSvc. Also fill a map of threshold names while
+       we are here - will be useful later */
+
+   std::vector< TrigConf::TriggerThreshold* > thresholds =
+      m_configSvc->ctpConfig()->menu().thresholdVector();
+   std::vector< TrigConf::TriggerThreshold* > muonThresholds;
+   std::map< int, std::string > thresholdNames;
+   for( std::vector< TrigConf::TriggerThreshold* >::const_iterator it = thresholds.begin();
+        it != thresholds.end(); ++it ) {
+      if( ( *it )->type() == L1DataDef::muonType() ) {
+         muonThresholds.push_back( *it );
+         thresholdNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+   }
+
+   // get Muon ROI
+   const std::vector< ROIB::MuCTPIRoI >& muonRoIV = result->muCTPIResult().roIVec();
+
+   // reconstruct ROI
+   ATH_MSG_DEBUG( "Muon ROI" );
+   std::vector< ROIB::MuCTPIRoI >::const_iterator itMU  = muonRoIV.begin();
+   std::vector< ROIB::MuCTPIRoI >::const_iterator itMUe = muonRoIV.end();
+   for ( ; itMU != itMUe; ++itMU ) {
+
+      uint32_t roIWord = itMU->roIWord();
+
+      ATH_MSG_DEBUG( MSG::hex << std::setw( 8 ) << roIWord );
+
+      if( ( m_recRPCRoiSvc == false ) || ( m_recTGCRoiSvc == false ) ) {
+         continue;
+      }
+
+      // RecRoI
+      LVL1::RecMuonRoI recRoI( roIWord, m_recRPCRoiSvc.operator->(),
+                               m_recTGCRoiSvc.operator->(), &muonThresholds );
+
+      double thrValue = recRoI.getThresholdValue() * CLHEP::GeV;
+      int index = recRoI.getThresholdNumber() - 1;
+      std::string thrName = "NameNotFound";
+      if( thresholdNames.find(index) != thresholdNames.end() ) {
+         thrName = thresholdNames[ index ];
+      }
+
+      // AOD component
+      Muon_ROI roi( roIWord, recRoI.eta(), recRoI.phi(), thrName, thrValue );
+
+      lvl1ROI->addMuonROI( roi );
+      ATH_MSG_DEBUG( "Muon Thr : " << thrName << ", value = " << thrValue );
+
+   } // for ( ; itMU != itMUe; ++itMU )
+
+   return;
+}
diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.h b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.h
new file mode 100644
index 00000000000..ee85e2ae954
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToAOD.h
@@ -0,0 +1,103 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: RoIBResultToAOD.h 452138 2011-08-04 11:10:41Z krasznaa $
+#ifndef ANALYSISTRIGGERALGS_ROIBRESULTTOAOD_H
+#define ANALYSISTRIGGERALGS_ROIBRESULTTOAOD_H
+
+// Gaudi/Athena include(s):
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "StoreGate/DataHandle.h"
+
+// Forward declaration(s):
+class StoreGateSvc;
+class LVL1_ROI;
+namespace TrigConf {
+  class ILVL1ConfigSvc;
+}
+namespace LVL1 {
+  class RecMuonRoiSvc;
+  class IL1EmTauTools;
+  class IL1JetTools;
+}
+namespace ROIB {
+  class RoIBResult;
+}
+
+/**
+ *  @short RoIB result to AOD converter
+ * 
+ *  The RoIBResultToAOD algorithm builds the CTP_Decision and 
+ *  LVL1_ROI objects from the LVL1 ROIB::RoIBResult object. 
+ *  In addition the TriggerType of the CTP can be rebuild,
+ *  when zero in the input object.
+ *
+ *  The CTP_Decision and LVL1_ROI objects are stored in ESD/AOD.
+ *
+ *    $Id: RoIBResultToAOD.h 452138 2011-08-04 11:10:41Z krasznaa $        
+ *
+ * @author Tadashi Maeno <Tadashi.Maeno@cern.ch>
+ * @author Attila Kraznahorkay Jr. <Attila.Krasznahorkay@cern.ch>
+ * @author Alan Watson <Alan.Watson@cern.ch>
+ * @author Wolfgang Ehrenfeld <Wolfgang.Menges@desy.de>
+ * @author last commit \$Author: watsona $
+ *
+ */
+
+class RoIBResultToAOD : public AthAlgorithm {
+
+public:
+   RoIBResultToAOD( const std::string& name, ISvcLocator* pSvcLocator );
+
+   StatusCode initialize();
+   StatusCode finalize();
+   StatusCode execute();
+
+private:
+   /// build CTP_Decision from CTPResult stored in ROIB::RoIBResult
+   StatusCode buildCTP_Decision();
+   /// add EmTauRoi to LVL1_ROI from EmTauResult stored in ROIB::RoIBResult
+   void addEmTauRoI(const ROIB::RoIBResult*, LVL1_ROI*);
+   /// add JetEnergyRoi to LVL1_ROI from JetEnergyResult stored in ROIB::RoIBResult
+   void addJetEnergyRoI(const ROIB::RoIBResult*, LVL1_ROI*);
+   /// add MuonRoi to LVL1_ROI from MuCTPIResult stored in ROIB::RoIBResult
+   void addMuonRoI(const ROIB::RoIBResult*, LVL1_ROI*);
+
+   // services
+   ServiceHandle<TrigConf::ILVL1ConfigSvc> m_configSvc;               //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink
+
+   ServiceHandle<LVL1::RecMuonRoiSvc> m_recRPCRoiSvc;                 //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink
+   ServiceHandle<LVL1::RecMuonRoiSvc> m_recTGCRoiSvc;                 //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink
+
+   // tools
+   ToolHandle<LVL1::IL1EmTauTools> m_EmTauTool;                       //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink
+   ToolHandle<LVL1::IL1JetTools> m_JetTool;                           //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink
+   bool m_retrievedEmTauTool;
+   bool m_retrievedJetTool;
+
+   // Data object StoreGate keys
+   std::string m_TriggerTowerLocation;
+   std::string m_JetElementLocation;
+   std::string m_roibInputKey;
+   std::string m_lvl1RoIOutputKey;
+  
+   // properties
+   bool        m_doCalo;                                              //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink
+   bool        m_doMuon;                                              //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink
+
+   // trigger items for each TTW bit
+   std::vector< std::string > m_egammaItem;                           //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink
+   std::vector< std::string > m_tauhadItem;                           //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink
+   std::vector< std::string > m_jetItem;                              //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink
+   std::vector< std::string > m_esumItem;                             //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink
+   std::vector< std::string > m_highmuItem;                           //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink
+   std::vector< std::string > m_lowmuItem;                            //!< property, see @link RoIBResultToAOD::RoIBResultToAOD @endlink
+
+}; // class RoIBResultToAOD
+
+#endif // ANALYSISTRIGGERALGS_ROIBRESULTTOAOD_H
diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.cxx b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.cxx
new file mode 100644
index 00000000000..f84c8dec2cb
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.cxx
@@ -0,0 +1,851 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: RoIBResultToxAOD.cxx 587265 2014-03-12 09:45:45Z krasznaa $
+
+// STL include(s):
+#include <algorithm>
+#include <cmath>
+
+// Gaudi/Athena include(s):
+#include "AthenaKernel/errorcheck.h"
+#include "CLHEP/Units/SystemOfUnits.h"
+#include "EventInfo/EventInfo.h"
+#include "EventInfo/EventID.h"
+#include "EventInfo/EventType.h"
+#include "EventInfo/TriggerInfo.h"
+
+// LVL1 trigger include(s):
+#include "TrigT1Interfaces/TriggerTypeWord.h"
+#include "TrigT1Interfaces/RecMuonRoI.h"
+#include "TrigT1Interfaces/RecMuonRoiSvc.h"
+#include "TrigT1Interfaces/RecEmTauRoI.h"
+#include "TrigT1Interfaces/RecJetRoI.h"
+#include "TrigT1Interfaces/RecEnergyRoI.h"
+#include "TrigT1Interfaces/JEPRoIDecoder.h"
+#include "TrigT1Interfaces/TrigT1CaloDefs.h"
+#include "TrigT1Result/RoIBResult.h"
+#include "TrigT1Result/CTPResult.h"
+#include "TrigT1CaloToolInterfaces/IL1EmTauTools.h"
+#include "TrigT1CaloToolInterfaces/IL1JetTools.h"
+#include "TrigT1CaloEvent/TriggerTowerCollection.h"
+#include "TrigT1CaloEvent/JetElementCollection.h"
+#include "TrigT1CaloEvent/CPMTower.h"
+#include "TrigT1CaloEvent/JetInput.h"
+#include "TrigConfL1Data/L1DataDef.h"
+#include "TrigConfL1Data/TriggerThreshold.h"
+
+// Trigger configuration interface includes:
+#include "TrigConfL1Data/CTPConfig.h"
+#include "TrigConfL1Data/Menu.h"
+#include "TrigConfL1Data/TriggerItem.h"
+
+// Include for the configuration service:
+#include "TrigConfInterfaces/ILVL1ConfigSvc.h"
+
+// LVL1 AOD event include(s):
+#include "AnalysisTriggerEvent/CTP_Decision.h"
+#include "AnalysisTriggerEvent/LVL1_ROI.h"
+
+// xAOD include(s):
+#include "xAODTrigger/MuonRoIContainer.h"
+#include "xAODTrigger/MuonRoIAuxContainer.h"
+#include "xAODTrigger/EmTauRoIContainer.h"
+#include "xAODTrigger/EmTauRoIAuxContainer.h"
+#include "xAODTrigger/EnergySumRoI.h"
+#include "xAODTrigger/EnergySumRoIAuxInfo.h"
+#include "xAODTrigger/JetEtRoI.h"
+#include "xAODTrigger/JetEtRoIAuxInfo.h"
+#include "xAODTrigger/JetRoIContainer.h"
+#include "xAODTrigger/JetRoIAuxContainer.h"
+
+
+// Local include(s):
+#include "RoIBResultToxAOD.h"
+
+using namespace TrigConf;
+using namespace xAODMaker;
+
+RoIBResultToxAOD::RoIBResultToxAOD( const std::string& name, ISvcLocator* pSvcLocator )
+  : AthAlgorithm( name, pSvcLocator ),
+    m_configSvc( "TrigConf::LVL1ConfigSvc/LVL1ConfigSvc", name ),
+    m_recRPCRoiSvc( LVL1::ID_RecRpcRoiSvc, name ),
+    m_recTGCRoiSvc( LVL1::ID_RecTgcRoiSvc, name ),
+    m_EmTauTool( "LVL1::L1EmTauTools/L1EmTauTools" ),
+    m_JetTool( "LVL1::L1JetTools/L1JetTools" ),
+    m_MuCnvTool( "xAODMaker::MuonRoICnvTool/MuonRoICnvTool", this ),
+    m_EmTauCnvTool( "xAODMaker::EmTauRoICnvTool/EmTauRoICnvTool", this ),
+    m_EsumCnvTool( "xAODMaker::EnergySumRoICnvTool/EnergySumRoICnvTool", this ),
+    m_JetEtCnvTool( "xAODMaker::JetEtRoICnvTool/JetEtRoICnvTool", this ),
+    m_JetCnvTool( "xAODMaker::JetRoICnvTool/JetRoICnvTool", this )
+ {
+
+   // services
+   declareProperty( "LVL1ConfigSvc", m_configSvc, "LVL1 Config Service");
+   declareProperty( "RecRpcRoiSvc", m_recRPCRoiSvc, "RPC Rec Roi Service");
+   declareProperty( "RecTgcRoiSvc", m_recTGCRoiSvc, "TGC Rec Roi Service");
+
+   // tools
+   declareProperty( "L1EmTauTools", m_EmTauTool,
+                    "Tool for calculation of EmTau trigger sums per RoI");
+   declareProperty( "L1JetTools", m_JetTool,
+                    "Tool for calculation of Jet cluster sums per RoI");
+
+   // Properties: input selection
+   declareProperty( "DoCalo", m_doCalo = true, "Use inputs from Calo system" );
+   declareProperty( "DoMuon", m_doMuon = true, "Use inputs from Muon system" );
+
+   // Properties: rebuilding trigger type
+   declareProperty( "EGammaItem", m_egammaItem,
+                    "List of LVL1 items for e/gamma trigger type" );
+   declareProperty( "TauHadItem", m_tauhadItem,
+                    "List of LVL1 items for tau trigger type" );
+   declareProperty( "JetItem", m_jetItem,
+                    "List of LVL1 items for jet trigger type" );
+   declareProperty( "ESumItem", m_esumItem,
+                    "List of LVL1 items for energy sum trigger type" );
+   declareProperty( "HighMuItem", m_highmuItem,
+                    "List of LVL1 items for high pt muon trigger type" );
+   declareProperty( "LowMuItem", m_lowmuItem,
+                    "List of LVL1 items for low pt muon trigger type" );
+
+   // Properties: StoreGate keys
+   m_TriggerTowerLocation       = LVL1::TrigT1CaloDefs::TriggerTowerLocation;
+   m_JetElementLocation         = LVL1::TrigT1CaloDefs::JetElementLocation;
+   declareProperty( "TriggerTowerLocation", m_TriggerTowerLocation ) ;
+   declareProperty( "JetElementLocation",   m_JetElementLocation ) ;
+   declareProperty( "RoIBResultInputKey", m_roibInputKey = "RoIBResult" );
+   declareProperty( "LVL1_ROIOutputKey", m_lvl1RoIOutputKey = "LVL1_ROI" );
+
+   declareProperty( "xAODKeyMu", m_xaodKeyMu = "LVL1MuonRoIs" );
+   declareProperty( "xAODKeyEmTau", m_xaodKeyEmTau = "LVL1EmTauRoIs" );
+   declareProperty( "xAODKeyEsum", m_xaodKeyEsum = "LVL1EnergySumRoI" );
+   declareProperty( "xAODKeyJetEt", m_xaodKeyJetEt = "LVL1JetEtRoI" );
+   declareProperty( "xAODKeyJet", m_xaodKeyJet = "LVL1JetRoIs" );
+
+   m_retrievedEmTauTool = false;
+   m_retrievedJetTool = false;
+
+}
+
+// Initialize
+StatusCode RoIBResultToxAOD::initialize() {
+
+   ATH_MSG_INFO( "initializing " << name()
+                 << " - package version " << PACKAGE_VERSION );
+
+   // Print system info
+   if( m_doCalo == false ) {
+      ATH_MSG_WARNING( "Inputs from LVL1 Calo systems switched off" );
+   }
+   if( m_doMuon == false ) {
+      ATH_MSG_WARNING( "Inputs from LVL1 Muon systems switched off" );
+   }
+
+   // Connect to the LVL1ConfigSvc for the trigger configuration:
+   CHECK( m_configSvc.retrieve() );
+   ATH_MSG_DEBUG( "Connected to " << m_configSvc.typeAndName() );
+
+   if( m_doMuon ) {
+
+      // Get the RPC RecRoI service
+      CHECK( m_recRPCRoiSvc.retrieve() );
+      ATH_MSG_DEBUG( "Connected to " << m_recRPCRoiSvc.typeAndName() );
+
+      // Get the TGC RecRoI service
+      CHECK( m_recTGCRoiSvc.retrieve() );
+      ATH_MSG_DEBUG( "Connected to " << m_recTGCRoiSvc.typeAndName() );
+
+   } // if (m_doMuon)
+
+   if( m_doCalo ) {
+
+      // Get tools
+      CHECK( m_EmTauTool.retrieve() );
+      ATH_MSG_DEBUG( "Got " << m_EmTauTool.typeAndName() );
+      m_retrievedEmTauTool = true;
+
+      CHECK( m_JetTool.retrieve() );
+      ATH_MSG_DEBUG( "Got " << m_JetTool.typeAndName() );
+      m_retrievedJetTool = true;
+
+   } // if (m_doCalo)
+
+   return StatusCode::SUCCESS;
+}
+
+// finalize
+StatusCode RoIBResultToxAOD::finalize() {
+
+   ATH_MSG_INFO( "Finalizing " << name()
+                 << " - package version " << PACKAGE_VERSION );
+
+   return StatusCode::SUCCESS;
+}
+
+// execute
+StatusCode RoIBResultToxAOD::execute() {
+
+   ATH_MSG_DEBUG( "in execute()" );
+
+   ///////////////////////////////////////////////////////////////////////////
+   // Trigger Info
+
+   // retrieve event info
+   const DataHandle< EventInfo > eventInfoBeg;
+   const DataHandle< EventInfo > eventInfoEnd;
+   CHECK( evtStore()->retrieve( eventInfoBeg, eventInfoEnd ) );
+   if( eventInfoBeg == eventInfoEnd ) {
+      ATH_MSG_ERROR( "No event info objects" );
+      return StatusCode::RECOVERABLE;
+   }
+
+   // get key
+   const std::string eventInfoKey = eventInfoBeg.key();
+
+   // build TriggerInfo
+   EventInfo* eventInfo = const_cast< EventInfo* >( eventInfoBeg.cptr() );
+   TriggerInfo* tInfo = eventInfo->trigger_info();
+   TriggerInfo* triggerInfo;
+   if( tInfo != 0 ) {
+      triggerInfo = new TriggerInfo( *tInfo );
+   } else {
+      triggerInfo = new TriggerInfo( 0, 0, 0,
+                                     std::vector< TriggerInfo::number_type>( 0 ),
+                                     std::vector< TriggerInfo::number_type>( 0 ),
+                                     std::vector< TriggerInfo::StreamTag>( 0 ) );
+   }
+
+   // set TriggerInfo
+   eventInfo->setTriggerInfo( triggerInfo );
+
+   // dump
+   ATH_MSG_DEBUG( MSG::dec << "EventInfo:" << eventInfoKey );
+   ATH_MSG_DEBUG( *( eventInfo->event_ID() ) );
+   ATH_MSG_DEBUG( "[TimeStamp] = " << eventInfo->event_ID()->time_stamp() );
+   ATH_MSG_DEBUG( "[Type] = " << eventInfo->event_type()->user_type() );
+   ATH_MSG_DEBUG( "[BitMask]" );
+   for( EventType::BitMaskIterator bitIt = eventInfo->event_type()->bit_mask_begin();
+        bitIt != eventInfo->event_type()->bit_mask_end(); ++bitIt ) {
+      ATH_MSG_DEBUG( *bitIt );
+   }
+
+   if( triggerInfo != 0 ) {
+      ATH_MSG_DEBUG( MSG::hex << "[L1ID] = "<< triggerInfo->extendedLevel1ID() );
+      ATH_MSG_DEBUG( "[TriggerType] = "<< triggerInfo->level1TriggerType() );
+      ATH_MSG_DEBUG( "[L1Info] = "<< triggerInfo->level1TriggerInfo() );
+      ATH_MSG_DEBUG( "[L2Info] = "<< triggerInfo->level2TriggerInfo() );
+      ATH_MSG_DEBUG( "[EFInfo]" );
+      const std::vector< TriggerInfo::number_type >& efInfo = triggerInfo->eventFilterInfo();
+      for( std::vector< TriggerInfo::number_type >::const_iterator itEF = efInfo.begin();
+           itEF != efInfo.end(); ++itEF ) {
+         ATH_MSG_DEBUG( *itEF );
+      }
+   }
+
+   ///////////////////////////////////////////////////////////////////////////
+   // build LVL1 ROI
+
+   LVL1_ROI *lvl1ROI = new LVL1_ROI;
+
+   ///////////////////////////////////////////////////////////////////////////
+   // retrive L1 result
+
+   const ROIB::RoIBResult *result = 0;
+   if( evtStore()->retrieve( result, m_roibInputKey ).isFailure() ) {
+      ATH_MSG_WARNING( "Could not retrieve RoIBResult. Building empty LVL1_ROI" );
+      result = 0;
+   }
+
+   ///////////////////////////////////////////////////////////////////////////
+   // Muon ROI
+
+   if( m_doMuon == true ) addMuonRoI( result, lvl1ROI );
+
+   ///////////////////////////////////////////////////////////////////////////
+   // EmTau ROI
+
+   if( m_doCalo == true ) addEmTauRoI( result, lvl1ROI );
+
+   ///////////////////////////////////////////////////////////////////////////
+   // JetEnergy ROI
+
+   if( m_doCalo == true ) addJetEnergyRoI( result, lvl1ROI );
+
+   ///////////////////////////////////////////////////////////////////////////
+   // record LVL1 ROI in xAOD format
+
+   CHECK( convertToxAOD(lvl1ROI) );
+
+   ///////////////////////////////////////////////////////////////////////////
+   // delete LVL1 ROI
+   delete lvl1ROI;
+
+   return StatusCode::SUCCESS;
+}
+
+StatusCode RoIBResultToxAOD::buildCTP_Decision() {
+
+   ATH_MSG_DEBUG( "building CTP decision" );
+
+   CTP_Decision* ctpDecision = new CTP_Decision;
+
+   // retrive L1 result
+   const ROIB::RoIBResult *result = 0;
+   if( evtStore()->retrieve( result, m_roibInputKey ).isSuccess() ) {
+
+      // Trigger Type Word
+      bool triggerTypeLegacyFlag = false;
+      uint32_t triggerTypeWord = result->cTPResult().header().triggerType();
+
+      if( triggerTypeWord == 0 ) { // switch to legacy mode
+         ATH_MSG_DEBUG( "Building TriggerType word" );
+         triggerTypeWord = LVL1::TriggerTypeWord::Physics |
+            LVL1::TriggerTypeWord::PriorityLevel;
+         triggerTypeLegacyFlag = true;
+      }
+
+      // store TAV vector in CTP decision object
+      const std::vector< ROIB::CTPRoI > tav = result->cTPResult().TAV();
+      for( size_t i( 0 ); i < tav.size(); ++i ) {
+         ctpDecision->setWord( i, tav[ i ].roIWord() );
+      }
+
+      // search for passed items in TAV vector from CTP result
+      const std::bitset< 256 > items = ROIB::convertToBitset( tav );
+
+      ATH_MSG_DEBUG( "Iterating Items on " << m_configSvc->ctpConfig() );
+      for(TrigConf::ItemContainer::const_iterator item = m_configSvc->ctpConfig()->menu().items().begin(); 
+          item != m_configSvc->ctpConfig()->menu().items().end(); ++item ) {
+	ATH_MSG_DEBUG( "try getting item name" );
+         if( items[ ( *item )->ctpId() ] ) {
+            // add item name to CTP_Decision
+            const std::string& itemName = ( *item )->name();
+            ctpDecision->setItem( itemName );
+            ATH_MSG_VERBOSE( "Item : " << itemName );
+
+            if( triggerTypeLegacyFlag ) {
+               ///////// compute Trigger Type Word
+               ///////// This is temporary implementation for DC2 and will be moved to
+               ///////// CTP simulation
+               // e/gamma
+               if( m_egammaItem.end() != std::find( m_egammaItem.begin(), m_egammaItem.end(),
+                                                    itemName ) )
+                  triggerTypeWord |= LVL1::TriggerTypeWord::Egamma;
+
+               // tau/hadron
+               if( m_tauhadItem.end() != std::find( m_tauhadItem.begin(), m_tauhadItem.end(),
+                                                    itemName ) )
+                  triggerTypeWord |= LVL1::TriggerTypeWord::TauHdr;
+
+               // jet
+               if( m_jetItem.end() != std::find( m_jetItem.begin(), m_jetItem.end(),
+                                                 itemName ) )
+                  triggerTypeWord |= LVL1::TriggerTypeWord::Jet;
+
+               // energy sum
+               if( m_esumItem.end() != std::find( m_esumItem.begin(), m_esumItem.end(),
+                                                  itemName ) )
+                  triggerTypeWord |= LVL1::TriggerTypeWord::EnergySum;
+
+               // high pT muon
+               if( m_highmuItem.end() != std::find( m_highmuItem.begin(), m_highmuItem.end(),
+                                                    itemName ) )
+                  triggerTypeWord |= LVL1::TriggerTypeWord::HighPtMuon;
+
+               // low pT muon
+               if( m_lowmuItem.end() != std::find( m_lowmuItem.begin(), m_lowmuItem.end(),
+                                                   itemName ) )
+                  triggerTypeWord |= LVL1::TriggerTypeWord::LowPtMuon;
+            } // if (triggerTypeLegacyFlag)
+         } // if (items[(*item)->ctpId()])
+      } // for
+
+      // set Trigger Type Word
+      ctpDecision->setTriggerTypeWord( triggerTypeWord );
+      ATH_MSG_DEBUG( "CTP_Decision: \n" + ctpDecision->dump() );
+
+   } else {
+      ATH_MSG_WARNING( "Could not retrieve RoIBResult, building empty CTP_Decision" );
+   }
+
+   // record CTP Decision
+   CHECK( evtStore()->record( ctpDecision, "CTP_Decision" ) );
+   CHECK( evtStore()->setConst( ctpDecision ) );
+
+   return StatusCode::SUCCESS;
+}
+
+void RoIBResultToxAOD::addEmTauRoI( const ROIB::RoIBResult* result, LVL1_ROI* lvl1ROI ) {
+
+   ATH_MSG_DEBUG( "building EmTauRoI" );
+
+   // empty input
+   if( result == 0 ) return;
+
+   // Digit scale for calorimeter trigger
+   float caloTrigScale = m_configSvc->thresholdConfig()->caloInfo().globalScale() * CLHEP::GeV;
+   ATH_MSG_DEBUG( "caloTrigScale = " << caloTrigScale );
+
+   /** Get EmTau Thresholds from configSvc. Also fill a map of threshold names while
+       we are here - will be useful later */
+
+   std::vector< TrigConf::TriggerThreshold* > thresholds =
+      m_configSvc->ctpConfig()->menu().thresholdVector();
+   std::vector< TrigConf::TriggerThreshold* > caloThresholds;
+   std::map< int, std::string > thresholdNames;
+   for( std::vector< TrigConf::TriggerThreshold* >::const_iterator it = thresholds.begin();
+        it != thresholds.end(); ++it ) {
+      if( ( *it )->type() == L1DataDef::emType() || ( *it )->type() == L1DataDef::tauType() ) {
+         caloThresholds.push_back( *it );
+         thresholdNames.insert( std::map< int, std::string >::value_type( ( *it )->thresholdNumber(), ( *it )->name() ) );
+      }
+   }
+
+   // Tool to reconstruct EM/tau cluster & isolation sums
+   //   - need to form tower map for RoI reconstruction
+   const DataVector< LVL1::TriggerTower >* storedTTs;
+   std::map< int, LVL1::CPMTower* > cpmtowers;
+   if( m_retrievedEmTauTool ) {
+      if( evtStore()->contains< TriggerTowerCollection >( m_TriggerTowerLocation ) ) {
+         StatusCode sc = evtStore()->retrieve( storedTTs, m_TriggerTowerLocation );
+         if( sc.isSuccess() ) m_EmTauTool->mapTowers( storedTTs, &cpmtowers );
+         else ATH_MSG_WARNING( "Error retrieving TriggerTowers" );
+      }
+      else ATH_MSG_DEBUG( "No TriggerTowerCollection found at "
+                          << m_TriggerTowerLocation );
+   }
+
+   // get EmTau Result
+   const std::vector< ROIB::EMTauResult >& emtauResult = result->eMTauResult();
+
+   // reconstruct ROI
+   ATH_MSG_DEBUG( "EmTau ROI" );
+   std::vector< ROIB::EMTauResult >::const_iterator itEMR  = emtauResult.begin();
+   std::vector< ROIB::EMTauResult >::const_iterator itEMRe = emtauResult.end();
+   for( ; itEMR != itEMRe; ++itEMR ) {
+      const std::vector< ROIB::EMTauRoI >& emtauRoIV = itEMR->roIVec();
+      std::vector< ROIB::EMTauRoI >::const_iterator itEM  = emtauRoIV.begin();
+      std::vector< ROIB::EMTauRoI >::const_iterator itEMe = emtauRoIV.end();
+      for( ; itEM != itEMe; ++itEM ) {
+
+         uint32_t roIWord = itEM->roIWord();
+         ATH_MSG_DEBUG( "About to create RecEmTauRoI : " << MSG::hex
+                        << std::setw( 8 ) << roIWord << MSG::dec );
+
+         // RecRoI
+         LVL1::RecEmTauRoI recRoI( roIWord, &caloThresholds );
+
+         // AOD component
+         // ATLAS standard phi convention differs from L1 hardware convention
+         double roiPhi = recRoI.phi();
+         if( roiPhi > M_PI ) roiPhi -= 2 * M_PI;
+         EmTau_ROI roi( roIWord, recRoI.eta(), roiPhi, roIWord & 0xFFFF );
+
+         // fired thresholds
+         std::vector< unsigned int >* thrV = recRoI.thresholdsPassed();
+         std::vector< unsigned int >::const_iterator itTh  = thrV->begin();
+         std::vector< unsigned int >::const_iterator itThE = thrV->end();
+         for( ; itTh != itThE; ++itTh ) {
+            double thrValue = recRoI.triggerThreshold(*itTh)* CLHEP::GeV;
+            std::string thrName = "NameNotFound";
+            if ( thresholdNames.find( *itTh - 1 ) != thresholdNames.end() ) {
+               thrName = thresholdNames[ *itTh - 1 ];
+            }
+
+            roi.addThresholdValue( thrValue );
+            roi.addThresholdName( thrName );
+
+            ATH_MSG_DEBUG( "EmTau Thr : " << thrName
+                           << ", value = "   << thrValue );
+         }
+         delete thrV;
+
+         // Cluster ET values, reconstructed from TriggerTowers
+         if( m_retrievedEmTauTool ) {
+            m_EmTauTool->formSums( roIWord, &cpmtowers );
+            roi.setCore( m_EmTauTool->Core() * caloTrigScale );
+            roi.setEMClus( m_EmTauTool->EMClus() * caloTrigScale );
+            roi.setTauClus( m_EmTauTool->TauClus() * caloTrigScale );
+            roi.setEMIsol( m_EmTauTool->EMIsol() * caloTrigScale );
+            roi.setHadIsol( m_EmTauTool->HadIsol() * caloTrigScale );
+            roi.setHadCore( m_EmTauTool->HadCore() * caloTrigScale );
+         }
+
+         lvl1ROI->addEmTauROI( roi );
+      }
+   }
+
+   for( std::map< int, LVL1::CPMTower* >::iterator i = cpmtowers.begin();
+        i != cpmtowers.end(); ++i ) delete i->second;   
+
+   return;
+}
+
+void RoIBResultToxAOD::addJetEnergyRoI( const ROIB::RoIBResult* result, LVL1_ROI* lvl1ROI ) {
+
+   ATH_MSG_DEBUG( "building JetEnergyRoI" );
+
+   // empty input
+   if( result == 0 ) return;
+
+   // Digit scale for calorimeter trigger
+   float caloTrigScale = m_configSvc->thresholdConfig()->caloInfo().globalScale() * CLHEP::GeV;
+   ATH_MSG_DEBUG( "caloTrigScale = " << caloTrigScale );
+
+   /** Get Jet/Energy Thresholds from configSvc. Also fill maps of threshold names while
+       we are here - will be useful later.
+
+       Unfortunately there are 3 types of jet threshold and 3 types of ET trigger threshold,
+       so this bit doesn't look very elegant */
+
+   std::vector< TrigConf::TriggerThreshold* > thresholds =
+      m_configSvc->ctpConfig()->menu().thresholdVector();
+   std::vector<TrigConf::TriggerThreshold*> jetThresholds;
+   std::vector<TrigConf::TriggerThreshold*> energyThresholds;
+   std::vector<TrigConf::TriggerThreshold*> jetEnergyThresholds;
+   std::map<int, std::string> jetNames;
+   std::map<int, std::string> jfNames;
+   std::map<int, std::string> jbNames;
+   std::map<int, std::string> xeNames;
+   std::map<int, std::string> teNames;
+   std::map<int, std::string> xsNames;
+   std::map<int, std::string> jeNames;
+
+   for( std::vector<TrigConf::TriggerThreshold*>::const_iterator it = thresholds.begin();
+        it != thresholds.end(); ++it ) {
+      if( ( *it )->type() == L1DataDef::jetType() ) {
+         jetThresholds.push_back( *it );
+         jetNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+      else if( ( *it )->type() == L1DataDef::jfType() ) {
+         jetThresholds.push_back( *it );
+         jfNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+      else if( ( *it )->type() == L1DataDef::jbType() ) {
+         jetThresholds.push_back( *it );
+         jbNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+      else if( ( *it )->type() == L1DataDef::xeType() ) {
+         energyThresholds.push_back( *it );
+         xeNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+      else if( ( *it )->type() == L1DataDef::teType() ) {
+         energyThresholds.push_back( *it );
+         teNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+      else if( ( *it )->type() == L1DataDef::xsType() ) {
+         energyThresholds.push_back( *it );
+         xsNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+      else if( ( *it )->type() == L1DataDef::jeType() ) {
+         jetEnergyThresholds.push_back( *it );
+         jeNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+   }
+
+   // Tool to reconstruct Jet cluster ET sums
+   //   - form input map ready for analysis
+   const DataVector< LVL1::JetElement >* storedJEs;
+   std::map< int, LVL1::JetInput* > jetInputs;
+   if( m_retrievedJetTool ) {
+      if( evtStore()->contains< JetElementCollection >( m_JetElementLocation ) ) {
+         StatusCode sc = evtStore()->retrieve( storedJEs, m_JetElementLocation );
+         if( sc.isSuccess() ) m_JetTool->mapJetInputs( storedJEs, &jetInputs );
+         else ATH_MSG_WARNING( "Error retrieving JetElements" );
+      }
+      else ATH_MSG_DEBUG( "No JetElementCollection found at "
+                          << m_JetElementLocation );
+   }
+
+   // get JetEnergy Result
+   const std::vector< ROIB::JetEnergyResult >& jetenergyResult = result->jetEnergyResult();
+
+   // reconstruct ROI
+   std::vector< ROIB::JetEnergyResult >::const_iterator itJETR  = jetenergyResult.begin();
+   std::vector< ROIB::JetEnergyResult >::const_iterator itJETRe = jetenergyResult.end();
+   for( ; itJETR != itJETRe; ++itJETR ) {
+      const std::vector< ROIB::JetEnergyRoI >& jetenergyRoIV = itJETR->roIVec();
+      std::vector< ROIB::JetEnergyRoI >::const_iterator itJET  = jetenergyRoIV.begin();
+      std::vector< ROIB::JetEnergyRoI >::const_iterator itJETe = jetenergyRoIV.end();
+      for( ; itJET != itJETe; ++itJET ) {
+         uint32_t roIWord = itJET->roIWord();
+
+         ATH_MSG_DEBUG( "Jet RoI, RoIWord = " << MSG::hex << std::setw( 8 )
+                        << roIWord << MSG::dec );
+
+         // RoI type
+         LVL1::JEPRoIDecoder conv;
+         int roiType = conv.roiType( roIWord );
+
+         // Jet ROI
+         if( roiType == LVL1::TrigT1CaloDefs::JetRoIWordType ) {
+            // RecRoI
+            LVL1::RecJetRoI recRoI( roIWord, &jetThresholds );
+
+            // AOD component
+            // Convert to ATLAS phi convention
+            double roiPhi = recRoI.phi();
+            if( roiPhi > M_PI ) roiPhi -= 2 * M_PI;
+            Jet_ROI roi( roIWord, recRoI.eta(), roiPhi, roIWord & 0xFFF );
+
+            // fired Jet thresholds
+            std::vector< unsigned int >* thrV = recRoI.thresholdsPassed();
+            std::vector< unsigned int >::const_iterator itTh  = thrV->begin();
+            std::vector< unsigned int >::const_iterator itThE = thrV->end();
+            for( ; itTh != itThE; ++itTh ) {
+               double thrValue = recRoI.triggerThreshold(*itTh)* CLHEP::GeV;
+               std::string thrName = "NameNotFound";
+               if (!recRoI.isForwardJet()) {
+                  if (jetNames.find(*itTh-1) != jetNames.end()) thrName = jetNames[*itTh-1];
+               }
+               else if (recRoI.eta() > 0) {
+                  if (jfNames.find(*itTh-1) != jfNames.end()) thrName = jfNames[*itTh-1];
+               }
+               else {
+                  if (jbNames.find(*itTh-1) != jbNames.end()) thrName = jbNames[*itTh-1];
+               }
+
+               roi.addThresholdValue( thrValue );
+               roi.addThresholdName( thrName );
+
+               ATH_MSG_DEBUG( "Jet Thr : " << thrName
+                              << ", value = " << thrValue );
+            }
+            delete thrV;
+
+            // Jet Cluster ET sums
+            if (m_retrievedJetTool) {
+               m_JetTool->formSums(roIWord, &jetInputs);
+               roi.setET4x4(m_JetTool->ET4x4()*caloTrigScale);
+               roi.setET6x6(m_JetTool->ET6x6()*caloTrigScale);
+               roi.setET8x8(m_JetTool->ET8x8()*caloTrigScale);
+            }
+
+            lvl1ROI->addJetROI(roi);
+         }
+         // Jet ET ROI
+         else if( roiType == LVL1::TrigT1CaloDefs::JetEtRoIWordType ) {
+            // AOD component
+            JetET_ROI roi( roIWord, roIWord & 0xF );
+
+            // fired Jet ET thresholds
+            for( unsigned int i = 0; i < TrigT1CaloDefs::numOfJetEtSumThresholds; ++i ) {
+               if( ( roIWord >> i ) & 0x1 ) {
+                  std::string thrName = "NameNotFound";
+                  if (jeNames.find(i) != jfNames.end()) thrName = jeNames[i];
+                  roi.addThreshold( thrName );
+                  ATH_MSG_DEBUG( "JetEt Thr : " << thrName );
+               }
+            }
+
+            lvl1ROI->addJetETROI(roi);
+         }
+         // EnergySum ROI
+         else if ( roiType == LVL1::TrigT1CaloDefs::EnergyRoIWordType0 ) {
+            uint32_t roiWord0 = roIWord;
+            ATH_MSG_DEBUG( "ET RoIWord 0 : " << MSG::hex << std::setw( 8 )
+                           << roiWord0 << MSG::dec );
+            ++itJET;
+            uint32_t roiWord1 = itJET->roIWord();
+            ATH_MSG_DEBUG( "ET RoIWord 1 : " << MSG::hex << std::setw( 8 )
+                           << roiWord1 << MSG::dec );
+            ++itJET;
+            uint32_t roiWord2 = itJET->roIWord();
+            ATH_MSG_DEBUG( "ET RoIWord 2 : " << MSG::hex << std::setw( 8 )
+                           << roiWord2 << MSG::dec );
+
+            // RecRoI
+            LVL1::RecEnergyRoI recRoI( roiWord0, roiWord1, roiWord2, &energyThresholds );
+
+            // Overflow bits  
+            unsigned int overflows = 0;  
+            if (conv.energyOverflow(roiWord0)) overflows |= 0x1;  
+            if (conv.energyOverflow(roiWord1)) overflows |= 0x2;  
+            if (conv.energyOverflow(roiWord2)) overflows |= 0x4;
+
+            // AOD component
+            EnergySum_ROI roi( roiWord0, roiWord1, roiWord2,
+                               recRoI.energyX() * caloTrigScale,
+                               recRoI.energyY() * caloTrigScale,
+                               recRoI.energyT() * caloTrigScale,
+                               ( roiWord1 >> 16 ) & 0xFF, ( roiWord2 >> 16 ) & 0xFF,
+                               ( roiWord0 >> 16 ) & 0xFF, overflows );
+
+            // fired summed ET thresholds
+            std::vector< unsigned int >* thrEtMiss = recRoI.etMissThresholdsPassed();
+            std::vector< unsigned int >::const_iterator itThEtMiss  = thrEtMiss->begin();
+            for( ; itThEtMiss != thrEtMiss->end(); ++itThEtMiss ) {
+               std::string thrName = "NameNotFound";
+               if( xeNames.find( *itThEtMiss - 1 ) != xeNames.end() ) {
+                  thrName = xeNames[ *itThEtMiss - 1 ];
+               }
+               roi.addThreshold( thrName );
+               ATH_MSG_DEBUG( "ETmiss threshold : " << thrName );
+            }
+            delete thrEtMiss;
+
+            // fired missing ET thresholds
+            std::vector< unsigned int >* thrSumEt = recRoI.sumEtThresholdsPassed();
+            std::vector< unsigned int >::const_iterator itThSumEt  = thrSumEt->begin();
+            for( ; itThSumEt != thrSumEt->end(); ++itThSumEt ) {
+               std::string thrName = "NameNotFound";
+               if( teNames.find( *itThSumEt - 1 ) != teNames.end() ) {
+                  thrName = teNames[ *itThSumEt - 1 ];
+               }
+               roi.addThreshold( thrName );
+               ATH_MSG_DEBUG( "SumET threshold : " << thrName );
+            }
+            delete thrSumEt;
+
+            // fired missing ET  significance thresholds
+            std::vector< unsigned int >* thrMETSig = recRoI.mEtSigThresholdsPassed();
+            std::vector< unsigned int >::const_iterator itThMETSig  = thrMETSig->begin();
+            for( ; itThMETSig != thrMETSig->end(); ++itThMETSig ) {
+               std::string thrName = "NameNotFound";
+               if( xsNames.find( *itThMETSig - 1 ) != xsNames.end() ) {
+                  thrName = xsNames[ *itThMETSig - 1 ];
+               }
+               roi.addThreshold( thrName );
+               ATH_MSG_DEBUG( "METSig threshold : " << thrName );
+            }
+            delete thrMETSig;
+
+            lvl1ROI->addEnergySumROI(roi);
+         }
+      }
+   }
+
+   for( std::map< int, LVL1::JetInput* >::iterator i = jetInputs.begin();
+        i != jetInputs.end(); ++i ) {
+      delete i->second;
+   }
+
+   return;
+}
+
+void RoIBResultToxAOD::addMuonRoI( const ROIB::RoIBResult* result, LVL1_ROI* lvl1ROI ) {
+
+   ATH_MSG_DEBUG( "in buildMuonRoI()" );
+
+   // empty input
+   if( result == 0 ) return;
+
+   /** Get Muon Thresholds from configSvc. Also fill a map of threshold names while
+       we are here - will be useful later */
+
+   std::vector< TrigConf::TriggerThreshold* > thresholds =
+      m_configSvc->ctpConfig()->menu().thresholdVector();
+   std::vector< TrigConf::TriggerThreshold* > muonThresholds;
+   std::map< int, std::string > thresholdNames;
+   for( std::vector< TrigConf::TriggerThreshold* >::const_iterator it = thresholds.begin();
+        it != thresholds.end(); ++it ) {
+      if( ( *it )->type() == L1DataDef::muonType() ) {
+         muonThresholds.push_back( *it );
+         thresholdNames.insert(std::map<int, std::string>::value_type((*it)->thresholdNumber(),(*it)->name()));
+      }
+   }
+
+   // get Muon ROI
+   const std::vector< ROIB::MuCTPIRoI >& muonRoIV = result->muCTPIResult().roIVec();
+
+   // reconstruct ROI
+   ATH_MSG_DEBUG( "Muon ROI" );
+   std::vector< ROIB::MuCTPIRoI >::const_iterator itMU  = muonRoIV.begin();
+   std::vector< ROIB::MuCTPIRoI >::const_iterator itMUe = muonRoIV.end();
+   for ( ; itMU != itMUe; ++itMU ) {
+
+      uint32_t roIWord = itMU->roIWord();
+
+      ATH_MSG_DEBUG( MSG::hex << std::setw( 8 ) << roIWord );
+
+      if( ( m_recRPCRoiSvc == false ) || ( m_recTGCRoiSvc == false ) ) {
+         continue;
+      }
+
+      // RecRoI
+      LVL1::RecMuonRoI recRoI( roIWord, m_recRPCRoiSvc.operator->(),
+                               m_recTGCRoiSvc.operator->(), &muonThresholds );
+
+      double thrValue = recRoI.getThresholdValue() * CLHEP::GeV;
+      int index = recRoI.getThresholdNumber() - 1;
+      std::string thrName = "NameNotFound";
+      if( thresholdNames.find(index) != thresholdNames.end() ) {
+         thrName = thresholdNames[ index ];
+      }
+
+      // AOD component
+      Muon_ROI roi( roIWord, recRoI.eta(), recRoI.phi(), thrName, thrValue );
+
+      lvl1ROI->addMuonROI( roi );
+      ATH_MSG_DEBUG( "Muon Thr : " << thrName << ", value = " << thrValue );
+
+   } // for ( ; itMU != itMUe; ++itMU )
+
+   return;
+}
+
+StatusCode RoIBResultToxAOD::convertToxAOD(LVL1_ROI* aod){
+
+  ATH_MSG_DEBUG( "converting to xAOD" );
+  ATH_MSG_DEBUG( "number of Muon RoIs: " << aod->getMuonROIs().size() );
+  ATH_MSG_DEBUG( "number of EmTau RoIs: " << aod->getEmTauROIs().size() );
+  ATH_MSG_DEBUG( "number of Jet RoIs: " << aod->getJetROIs().size() );
+  ATH_MSG_DEBUG( "number of JetEt RoIs: " << aod->getJetEtROIs().size() );
+  ATH_MSG_DEBUG( "number of Esum RoIs: " << aod->getEnergySumROIs().size() );
+
+
+  ////////////////////////////////
+  /// Muon RoIs
+  xAOD::MuonRoIAuxContainer* mu_aux = new xAOD::MuonRoIAuxContainer();
+  xAOD::MuonRoIContainer* mu_xaod = new xAOD::MuonRoIContainer();
+  mu_xaod->setStore( mu_aux );
+
+  CHECK( m_MuCnvTool->convert( aod, mu_xaod ) );
+  CHECK( evtStore()->record( mu_aux, m_xaodKeyMu + "Aux." ) );
+  CHECK( evtStore()->record( mu_xaod, m_xaodKeyMu ) );    
+
+  ////////////////////////////////
+  /// EmTau RoIs
+
+  xAOD::EmTauRoIAuxContainer* emtau_aux = new xAOD::EmTauRoIAuxContainer();
+  xAOD::EmTauRoIContainer* emtau_xaod = new xAOD::EmTauRoIContainer();
+  emtau_xaod->setStore( emtau_aux );
+
+  CHECK( m_EmTauCnvTool->convert( aod, emtau_xaod ) );
+  CHECK( evtStore()->record( emtau_aux, m_xaodKeyEmTau + "Aux." ) );
+  CHECK( evtStore()->record( emtau_xaod, m_xaodKeyEmTau ) );
+
+  ////////////////////////////////
+  /// EnergySum RoIs
+  xAOD::EnergySumRoIAuxInfo* esum_aux = new xAOD::EnergySumRoIAuxInfo();
+  xAOD::EnergySumRoI* esum_xaod = new xAOD::EnergySumRoI();
+  esum_xaod->setStore( esum_aux );
+
+  CHECK( m_EsumCnvTool->convert( aod, esum_xaod ) );
+  CHECK( evtStore()->record( esum_aux, m_xaodKeyEsum + "Aux." ) );
+  CHECK( evtStore()->record( esum_xaod, m_xaodKeyEsum ) );
+
+  ////////////////////////////////
+  /// JetEt RoIs
+  xAOD::JetEtRoIAuxInfo* jetet_aux = new xAOD::JetEtRoIAuxInfo();
+  xAOD::JetEtRoI* jetet_xaod = new xAOD::JetEtRoI();
+  jetet_xaod->setStore( jetet_aux );
+
+  CHECK( m_JetEtCnvTool->convert( aod, jetet_xaod ) );
+  CHECK( evtStore()->record( jetet_aux, m_xaodKeyJetEt + "Aux." ) );
+  CHECK( evtStore()->record( jetet_xaod, m_xaodKeyJetEt ) );
+
+  ////////////////////////////////
+  /// Jet RoIs
+  xAOD::JetRoIAuxContainer* jet_aux = new xAOD::JetRoIAuxContainer();
+  xAOD::JetRoIContainer* jet_xaod = new xAOD::JetRoIContainer();
+  jet_xaod->setStore( jet_aux );
+
+  CHECK( m_JetCnvTool->convert( aod, jet_xaod ) );
+  CHECK( evtStore()->record( jet_aux, m_xaodKeyJet + "Aux." ) );
+  CHECK( evtStore()->record( jet_xaod, m_xaodKeyJet ) );
+
+  return StatusCode::SUCCESS;
+}
diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.h b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.h
new file mode 100644
index 00000000000..a4923b847da
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/RoIBResultToxAOD.h
@@ -0,0 +1,128 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: RoIBResultToxAOD.h 587265 2014-03-12 09:45:45Z krasznaa $
+#ifndef ANALYSISTRIGGERALGS_ROIBRESULTTOXAOD_H
+#define ANALYSISTRIGGERALGS_ROIBRESULTTOXAOD_H
+
+// Gaudi/Athena include(s):
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "StoreGate/DataHandle.h"
+
+// xAOD include(s):
+#include "xAODTriggerCnv/IMuonRoICnvTool.h"
+#include "xAODTriggerCnv/IEmTauRoICnvTool.h"
+#include "xAODTriggerCnv/IEnergySumRoICnvTool.h"
+#include "xAODTriggerCnv/IJetEtRoICnvTool.h"
+#include "xAODTriggerCnv/IJetRoICnvTool.h"
+
+// Forward declaration(s):
+class StoreGateSvc;
+class LVL1_ROI;
+namespace TrigConf {
+  class ILVL1ConfigSvc;
+}
+namespace LVL1 {
+  class RecMuonRoiSvc;
+  class IL1EmTauTools;
+  class IL1JetTools;
+}
+namespace ROIB {
+  class RoIBResult;
+}
+
+/**
+ *  @short RoIB result to xAOD converter
+ *
+ *  This is a slightly adapted version of the original RoIBResultToAOD 
+ *  algorithm. Going the route through the LVL1_ROI structure was 
+ *  needed due to the interface of the AOD->xAOD ROI converters
+ *
+ *  The RoIBResultToxAOD algorithm builds the CTP_Decision and 
+ *  LVL1_ROI objects from the LVL1 ROIB::RoIBResult object. 
+ *  In addition the TriggerType of the CTP can be rebuild,
+ *  when zero in the input object.
+ *
+ *  The CTP_Decision and LVL1_ROI objects are stored in ESD/AOD.
+ *
+ *    $Id: RoIBResultToxAOD.h 587265 2014-03-12 09:45:45Z krasznaa $
+ *
+ * @author Tadashi Maeno <Tadashi.Maeno@cern.ch>
+ * @author Attila Kraznahorkay Jr. <Attila.Krasznahorkay@cern.ch>
+ * @author Alan Watson <Alan.Watson@cern.ch>
+ * @author Wolfgang Ehrenfeld <Wolfgang.Menges@desy.de>
+ * @author last commit \$Author: watsona $
+ *
+ */
+class RoIBResultToxAOD : public AthAlgorithm {
+
+public:
+   RoIBResultToxAOD( const std::string& name, ISvcLocator* pSvcLocator );
+
+   StatusCode initialize();
+   StatusCode finalize();
+   StatusCode execute();
+
+private:
+   /// build CTP_Decision from CTPResult stored in ROIB::RoIBResult
+   StatusCode buildCTP_Decision();
+   /// add EmTauRoi to LVL1_ROI from EmTauResult stored in ROIB::RoIBResult
+   void addEmTauRoI(const ROIB::RoIBResult*, LVL1_ROI*);
+   /// add JetEnergyRoi to LVL1_ROI from JetEnergyResult stored in ROIB::RoIBResult
+   void addJetEnergyRoI(const ROIB::RoIBResult*, LVL1_ROI*);
+   /// add MuonRoi to LVL1_ROI from MuCTPIResult stored in ROIB::RoIBResult
+   void addMuonRoI(const ROIB::RoIBResult*, LVL1_ROI*);
+   /// convert AOD ROI objects to xAOD objects
+   StatusCode convertToxAOD(LVL1_ROI*);
+
+   // services
+   ServiceHandle<TrigConf::ILVL1ConfigSvc> m_configSvc;               //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink
+
+   ServiceHandle<LVL1::RecMuonRoiSvc> m_recRPCRoiSvc;                 //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink
+   ServiceHandle<LVL1::RecMuonRoiSvc> m_recTGCRoiSvc;                 //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink
+
+   // tools
+   ToolHandle<LVL1::IL1EmTauTools> m_EmTauTool;                       //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink
+   ToolHandle<LVL1::IL1JetTools> m_JetTool;                           //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink
+   bool m_retrievedEmTauTool;
+   bool m_retrievedJetTool;
+
+   // xAOD conversion tools:
+   std::string m_xaodKeyMu;
+   std::string m_xaodKeyEmTau;
+   std::string m_xaodKeyEsum;
+   std::string m_xaodKeyJetEt;
+   std::string m_xaodKeyJet;
+
+   ToolHandle< xAODMaker::IMuonRoICnvTool > m_MuCnvTool;
+   ToolHandle< xAODMaker::IEmTauRoICnvTool > m_EmTauCnvTool;
+   ToolHandle< xAODMaker::IEnergySumRoICnvTool > m_EsumCnvTool;
+   ToolHandle< xAODMaker::IJetEtRoICnvTool > m_JetEtCnvTool;
+   ToolHandle< xAODMaker::IJetRoICnvTool > m_JetCnvTool;
+
+   // Data object StoreGate keys
+   std::string m_TriggerTowerLocation;
+   std::string m_JetElementLocation;
+   std::string m_roibInputKey;
+   std::string m_lvl1RoIOutputKey;
+
+   // properties
+   bool        m_doCalo;                                              //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink
+   bool        m_doMuon;                                              //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink
+
+   // trigger items for each TTW bit
+   std::vector< std::string > m_egammaItem;                           //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink
+   std::vector< std::string > m_tauhadItem;                           //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink
+   std::vector< std::string > m_jetItem;                              //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink
+   std::vector< std::string > m_esumItem;                             //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink
+   std::vector< std::string > m_highmuItem;                           //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink
+   std::vector< std::string > m_lowmuItem;                            //!< property, see @link RoIBResultToxAOD::RoIBResultToxAOD @endlink
+
+}; // class RoIBResultToxAOD
+
+#endif // ANALYSISTRIGGERALGS_ROIBRESULTTOXAOD_H
diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_entries.cxx b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_entries.cxx
new file mode 100644
index 00000000000..c2ef5a4e1e9
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_entries.cxx
@@ -0,0 +1,25 @@
+// $Id: AnalysisTriggerAlgs_entries.cxx 587265 2014-03-12 09:45:45Z krasznaa $
+
+// Gaudi/Athena include(s):
+#include "GaudiKernel/DeclareFactoryEntries.h"
+
+// Local include(s):
+#include "../RoIBResultToAOD.h"
+#include "../RoIBResultToxAOD.h"
+#include "../MuCTPI_RDOToRoIBResult.h"
+
+//
+// Declare the algorithm(s):
+//
+DECLARE_ALGORITHM_FACTORY( RoIBResultToxAOD )
+DECLARE_ALGORITHM_FACTORY( RoIBResultToAOD )
+DECLARE_ALGORITHM_FACTORY( MuCTPI_RDOToRoIBResult )
+
+
+DECLARE_FACTORY_ENTRIES( AnalysisTriggerAlgs ) {
+
+   DECLARE_ALGORITHM( RoIBResultToAOD )
+   DECLARE_ALGORITHM( RoIBResultToxAOD )
+   DECLARE_ALGORITHM( MuCTPI_RDOToRoIBResult )
+
+}
diff --git a/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_load.cxx b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_load.cxx
new file mode 100644
index 00000000000..5db77df46b5
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisTrigger/AnalysisTriggerAlgs/src/components/AnalysisTriggerAlgs_load.cxx
@@ -0,0 +1,2 @@
+#include "GaudiKernel/LoadFactoryEntries.h"
+LOAD_FACTORY_ENTRIES(AnalysisTriggerAlgs)
-- 
GitLab