diff --git a/Event/xAOD/xAODTrigger/xAODTrigger/versions/eFexEMRoIAuxContainer_v1.h b/Event/xAOD/xAODTrigger/xAODTrigger/versions/eFexEMRoIAuxContainer_v1.h
index bf6af04d71b5111a7adb1c13568c84462f4c5c3f..a9942f9ed5cb5155accd1737af7f98edd341a72b 100644
--- a/Event/xAOD/xAODTrigger/xAODTrigger/versions/eFexEMRoIAuxContainer_v1.h
+++ b/Event/xAOD/xAODTrigger/xAODTrigger/versions/eFexEMRoIAuxContainer_v1.h
@@ -1,7 +1,7 @@
 // Dear emacs, this is -*- c++ -*-
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // $Id: eFexEMRoIAuxContainer_v1.h 631149 2014-11-26 12:26:18Z krasznaa $
@@ -46,9 +46,13 @@ namespace xAOD {
       std::vector< uint16_t > rhadEM;
       std::vector< uint16_t > wstotNumerator;
       std::vector< uint16_t > wstotDenominator;
-      std::vector< uint16_t > et;
-      std::vector< uint8_t >  eta;
-      std::vector< uint8_t >  phi;
+     //std::vector< uint16_t > et;
+     //std::vector< uint8_t >  eta;
+     //std::vector< uint8_t >  phi;
+
+      std::vector< float > et;
+      std::vector< float >  eta;
+      std::vector< float >  phi;
       std::vector< char >     isTOB;
       std::vector< uint32_t > thrPattern;
 
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/CMakeLists.txt b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/CMakeLists.txt
index e8473a6c76e59eb961009e1fb608b7118ed0291b..cd61df6dd5f30afa2b2c1ca98ff968544f71de95 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/CMakeLists.txt
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/CMakeLists.txt
@@ -14,7 +14,7 @@ atlas_add_library( L1CaloFEXSimLib
                    PUBLIC_HEADERS L1CaloFEXSim
                    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
                    PRIVATE_INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
-                   LINK_LIBRARIES ${ROOT_LIBRARIES} AthContainers AthLinks AthenaBaseComps AthenaKernel CaloEvent CaloIdentifier CxxUtils GaudiKernel Identifier L1CaloFEXToolInterfaces StoreGateLib xAODBase xAODCore xAODTrigL1Calo xAODTruth
+                   LINK_LIBRARIES ${ROOT_LIBRARIES} AthContainers AthLinks AthenaBaseComps AthenaKernel CaloEvent CaloIdentifier CxxUtils GaudiKernel Identifier L1CaloFEXToolInterfaces StoreGateLib xAODBase xAODCore xAODTrigL1Calo xAODTruth xAODTrigger
                    PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES} ${CLHEP_LIBRARIES} SGTools xAODJet )
 
 atlas_add_component( L1CaloFEXSim
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXDriver.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXDriver.h
index 74f06ac8da74b1fa340343c7c9d64ad0da507af3..847523dad1cfd4ce9f1cad5f5214a93648a3767e 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXDriver.h
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXDriver.h
@@ -19,6 +19,7 @@
 #include "CaloIdentifier/CaloIdManager.h"
 #include "CaloIdentifier/CaloCell_SuperCell_ID.h"
 #include "L1CaloFEXSim/eFEXOutputCollection.h"
+#include "xAODTrigger/eFexEMRoIContainer.h"
 
 class CaloIdManager;
 
@@ -35,6 +36,7 @@ class eFEXDriver : public AthAlgorithm
   virtual StatusCode initialize();
   virtual StatusCode execute(/*const EventContext& ctx*/);// const;
   StatusCode finalize();
+  virtual StatusCode testEDM(); 
 
  private:
 
@@ -46,6 +48,8 @@ class eFEXDriver : public AthAlgorithm
 
   SG::ReadHandleKey<CaloCellContainer> m_scellsCollectionSGKey {this, "SCell", "SCell", "SCell"};
 
+  SG::ReadHandleKey<xAOD::eFexEMRoIContainer> m_eEDMKey {this, "myEDM", "L1_eEMRoI", "Reading container of eFexEMRoIs"};
+
   ToolHandle<IeTowerBuilder> m_eTowerBuilderTool {this, "eTowerBuilderTool", "LVL1::eTowerBuilder", "Tool that builds eTowers for simulation"};
   ToolHandle<IeSuperCellTowerMapper> m_eSuperCellTowerMapperTool {this, "eSuperCellTowerMapperTool", "LVL1::eSuperCellTowerMapper", "Tool that maps supercells to eTowers"};
   ToolHandle<IeFEXSysSim> m_eFEXSysSimTool {this, "eFEXSysSimTool", "LVL1::eFEXSysSim", "Tool that creates the eFEX System Simulation"};
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXFPGA.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXFPGA.h
index 7552b150a0f944d219cb6a0c5de196defee8b7bc..9ad528b8cb11ff3070ae4f0451b02a14233cfd4a 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXFPGA.h
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXFPGA.h
@@ -16,14 +16,11 @@
 #include "AthenaBaseComps/AthAlgTool.h"
 #include "AthenaKernel/CLASS_DEF.h"
 #include "L1CaloFEXToolInterfaces/IeFEXFPGA.h"
-#include "L1CaloFEXSim/eTower.h"
 #include "L1CaloFEXSim/eTowerContainer.h"
 #include "L1CaloFEXToolInterfaces/IeFEXtauAlgo.h"
 #include "L1CaloFEXToolInterfaces/IeFEXegAlgo.h"
-#include "CaloEvent/CaloCellContainer.h"
-#include "CaloIdentifier/CaloIdManager.h"
-#include "CaloIdentifier/CaloCell_SuperCell_ID.h"
 #include "L1CaloFEXSim/eFEXOutputCollection.h"
+
 #include <vector>
 
 namespace LVL1 {
@@ -47,32 +44,33 @@ namespace LVL1 {
     virtual ~eFEXFPGA();
 
     virtual StatusCode init(int id, int efexid) override ;
-
     virtual StatusCode execute() override ;
-
     virtual void reset() override ;
-
-    virtual int ID() override {return m_id;}
+    virtual int getID() override {return m_id;}
 
     virtual void SetTowersAndCells_SG( int [][6] ) override ;
-
     virtual void SetIsoWP(std::vector<unsigned int> &, std::vector<unsigned int> &, unsigned int &) override ;
 
+    /**Form a tob word out of the potential candidate EM tob */
+    virtual uint32_t formEmTOB(int &, int &) override ;
+
+    virtual std::vector <uint32_t> getEmTOBs() override ;
+
+
     /** Internal data */
   private:
+    static bool etSort (uint32_t i,uint32_t j) { return (((i >> 0 ) & 0xfff)>((j >> 0 ) & 0xfff)); }
 
     int m_id;
     int m_efexid;
-
+    std::vector< uint32_t > m_tobwords;
     int m_eTowersIDs [10][6];
-    std::map<int,eTower> m_eTowersColl;
-
-    CaloCellContainer m_sCellsCollection;
 
     SG::ReadHandleKey<LVL1::eTowerContainer> m_eFEXFPGA_eTowerContainerKey {this, "MyETowers", "eTowerContainer", "Input container for eTowers"};
 
     //SG::ReadHandleKey<eFEXOutputCollection> m_eFEXFPGA_eFEXOutputCollectionKey {this, "MyOutputs", "eFEXOutputCollection", "Input container for eFEXOutputCollection"};
 
+
     ToolHandle<IeFEXtauAlgo> m_eFEXtauAlgoTool {this, "eFEXtauAlgoTool", "LVL1::eFEXtauAlgo", "Tool that runs the eFEX tau algorithm"};
     ToolHandle<IeFEXegAlgo> m_eFEXegAlgoTool {this, "eFEXegAlgoTool", "LVL1::eFEXegAlgo", "Tool that runs the eFEX e/gamma algorithm"};
     
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXSim.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXSim.h
index 8824dee6a2d69dfbff2ed2cc5398888d33f1ce34..c35560b942366578fa008850ca659a4f58a31936 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXSim.h
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXSim.h
@@ -57,16 +57,20 @@ namespace LVL1 {
 
     virtual StatusCode NewExecute(int tmp[10][18]) override;
 
+    virtual std::vector<uint32_t> getEmTOBs() override;
+
     /** Internal data */
   private:
+    static bool etSort (uint32_t i,uint32_t j) { return (((i >> 0 ) & 0xfff)>((j >> 0 ) & 0xfff)); }
 
     int m_id;
-
     int m_eTowersIDs [10][18];
-    std::map<int,eTower> m_eTowersColl;
+    //std::map<int,eTower> m_eTowersColl;
     CaloCellContainer m_sCellsCollection;
     std::vector<eFEXFPGA*> m_eFEXFPGACollection;
 
+    std::vector<std::vector<uint32_t> > m_tobWords;
+
     ToolHandle<IeFEXFPGA> m_eFEXFPGATool {this, "eFEXFPGATool", "LVL1::eFEXFPGA", "Tool that simulates the FPGA hardware"};
 
     
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXSysSim.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXSysSim.h
index 2ca89ff463904cc1f7c6bdb14a3b6c3bcdd6a4ac..dc4ea7f5edb904c1be49a9ab803786070567aaa2 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXSysSim.h
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/eFEXSysSim.h
@@ -22,6 +22,9 @@
 #include "CaloIdentifier/CaloIdManager.h"
 #include "CaloIdentifier/CaloCell_SuperCell_ID.h"
 
+#include "xAODTrigger/eFexEMRoIContainer.h"
+#include "xAODTrigger/eFexEMRoIAuxContainer.h"
+
 namespace LVL1 {
   
   //Doxygen class description below:
@@ -55,8 +58,14 @@ namespace LVL1 {
 
     virtual int calcTowerID(int eta, int phi, int mod) override ;
 
+    /**Create and fill a new eFexEMRoI object (corresponding to this window), and return a pointer to it*/
+    virtual StatusCode fillEDM(uint8_t eFEXNumber, uint32_t tobWord) override ; 
+
+
     /** Internal data */
   private:
+    std::unique_ptr< xAOD::eFexEMRoIContainer > m_eContainer;
+    std::unique_ptr< xAOD::eFexEMRoIAuxContainer > m_eAuxContainer;
 
     std::vector<eFEXSim*>  m_eFEXCollection;
     
@@ -65,7 +74,11 @@ namespace LVL1 {
     SG::ReadHandleKey<LVL1::eTowerContainer> m_eTowerContainerSGKey {this, "MyETowers", "eTowerContainer", "Input container for eTowers"};
     SG::ReadHandleKey<CaloCellContainer> m_scellsCollectionSGKey {this, "SCell", "SCell", "SCell"};
 
-    std::map<int,eTower> m_eTowersColl;
+    SG::WriteHandleKey< xAOD::eFexEMRoIContainer > m_eFexOutKey {this,"Key_eFexEMOutputContainer","L1_eEMRoI","Output eFexEM container"};
+
+    //std::map<int,eTower> m_eTowersColl;
+
+    std::map<int, std::vector<uint32_t> > m_allEmTobs;
     
   };
   
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXDriver.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXDriver.cxx
index d46fb3d1aa2811d383ca8190b55ceb7b2dba19e1..1932ded584190a6bf280dc3bb200341741105543 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXDriver.cxx
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXDriver.cxx
@@ -13,6 +13,7 @@
 
 #include "L1CaloFEXSim/eTower.h"
 #include "L1CaloFEXSim/eTowerBuilder.h"
+#include "L1CaloFEXSim/eTowerContainer.h"
 #include "L1CaloFEXSim/eFEXDriver.h"
 
 #include "L1CaloFEXSim/eSuperCellTowerMapper.h"
@@ -30,7 +31,8 @@
 #include "StoreGate/WriteHandle.h"
 #include "StoreGate/ReadHandle.h"
 
-#include "L1CaloFEXSim/eTowerContainer.h"
+#include "xAODTrigger/eFexEMRoI.h"
+#include "xAODTrigger/eFexEMRoIContainer.h"
 
 #include <cassert>
 #include "SGTools/TestStore.h"
@@ -84,6 +86,8 @@ StatusCode eFEXDriver::initialize()
 
   ATH_CHECK( m_eTowerContainerSGKey.initialize() );
 
+  ATH_CHECK( m_eEDMKey.initialize() );
+
   //ATH_CHECK( m_eFEXOutputCollectionSGKey.initialize() );
 
   return StatusCode::SUCCESS;
@@ -154,6 +158,9 @@ StatusCode eFEXDriver::finalize()
   // STEP 6 - Run THE eFEXSysSim
   ATH_CHECK(m_eFEXSysSimTool->execute());
 
+  ///STEP 6.5 - test the EDM
+  ATH_CHECK(testEDM());
+
   // STEP 7 - Close and clean the event  
   m_eFEXSysSimTool->cleanup();
   m_eSuperCellTowerMapperTool->reset();
@@ -165,6 +172,36 @@ StatusCode eFEXDriver::finalize()
 
   return StatusCode::SUCCESS;
 }
-  
+
+
+  StatusCode eFEXDriver::testEDM(){
+
+    const xAOD::eFexEMRoI* myRoI = 0;
+    
+    SG::ReadHandle<xAOD::eFexEMRoIContainer> myRoIContainer(m_eEDMKey);
+    if(!myRoIContainer.isValid()){
+      ATH_MSG_FATAL("Could not retrieve EDM Container " << m_eEDMKey.key());
+      return StatusCode::FAILURE;
+    }
+
+    ATH_MSG_DEBUG("----got container: " << myRoIContainer.key());
+
+    for(const auto& it : * myRoIContainer){
+      myRoI = it;
+      ATH_MSG_DEBUG("EDM eFex Number: " 
+		    << +myRoI->eFexNumber() // returns an 8 bit unsigned integer referring to the eFEX number 
+		    << " et: " 
+		    << myRoI->et() // returns the et value of the EM cluster in MeV
+		    << " eta: "
+		    << myRoI->eta() // returns a floating point global eta (will be at full precision 0.025, but currently only at 0.1)
+		    << " phi: "
+		    << myRoI->phi() // returns a floating point global phi
+		    << " is TOB? "
+		    << +myRoI->isTOB() // returns 1 if true, returns 0 if xTOB
+		    );
+    }
+
+    return StatusCode::SUCCESS;
+  }
   
 } // end of LVL1 namespace
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXFPGA.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXFPGA.cxx
index 69c66efb0c6f68d3a6f392eabbd33710d3575e28..e0007e0e39822c2014fcf983e6d6e1f5ecb79131 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXFPGA.cxx
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXFPGA.cxx
@@ -9,7 +9,6 @@
 //     email                : jacob.julian.kempster@cern.ch
 //  ***************************************************************************/
 #include "L1CaloFEXSim/eFEXFPGA.h"
-#include "L1CaloFEXSim/eTower.h"
 #include "L1CaloFEXSim/eTowerContainer.h"
 #include "L1CaloFEXSim/eFEXegAlgo.h"
 #include "L1CaloFEXSim/eFEXegTOB.h"
@@ -30,7 +29,6 @@
 #include "StoreGate/ReadHandle.h"
 #include "SGTools/TestStore.h"
 
-
 namespace LVL1 {
 
   // default constructor for persistency
@@ -40,19 +38,20 @@ eFEXFPGA::eFEXFPGA(const std::string& type,const std::string& name,const IInterf
 {
   declareInterface<IeFEXFPGA>(this);
 }
-  
+ 
     
   /** Destructor */
   eFEXFPGA::~eFEXFPGA()
   {
   }
 
-//================ Initialisation =================================================
+//---------------- Initialisation -------------------------------------------------
   
 StatusCode eFEXFPGA::initialize()
 {
 
   ATH_CHECK(m_eFEXFPGA_eTowerContainerKey.initialize());
+
   //ATH_CHECK(m_eFEXFPGA_eFEXOutputCollectionKey.initialize());
   return StatusCode::SUCCESS;
 }
@@ -76,6 +75,8 @@ void eFEXFPGA::reset(){
 
 StatusCode eFEXFPGA::execute(){
 
+  m_tobwords.clear();
+
   SG::ReadHandle<eTowerContainer> jk_eFEXFPGA_eTowerContainer(m_eFEXFPGA_eTowerContainerKey/*,ctx*/);
   if(!jk_eFEXFPGA_eTowerContainer.isValid()){
     ATH_MSG_FATAL("Could not retrieve jk_eFEXFPGA_eTowerContainer " << m_eFEXFPGA_eTowerContainerKey.key() );
@@ -95,7 +96,7 @@ StatusCode eFEXFPGA::execute(){
   
   StatusCode sc_tobs = evtStore()->retrieve(eFEXOutputs, "eFEXOutputCollection");
   if(sc_tobs == StatusCode::SUCCESS){ }
-  else if(sc_tobs == StatusCode::FAILURE) {ATH_MSG_DEBUG("\n==== eFEXegAlgo ========= Failed to find eFEXOutputCollection in eFEXFPGA"); }
+  else if(sc_tobs == StatusCode::FAILURE) {ATH_MSG_DEBUG("\n---- eFEXegAlgo --------- Failed to find eFEXOutputCollection in eFEXFPGA"); }
   
 
   for(int ieta = 1; ieta < 5; ieta++) {
@@ -135,6 +136,12 @@ StatusCode eFEXFPGA::execute(){
       SetIsoWP(RetaCoreEnv,tempThrs,RetaWP);
       SetIsoWP(RhadCoreEnv,tempThrs,RhadWP);
       SetIsoWP(WstotCoreEnv,tempThrs,WstotWP);
+      int eta_ind = ieta - 1;
+      int phi_ind = iphi - 1;    
+
+
+      uint32_t tobword = formEmTOB(eta_ind,phi_ind);
+      if ( tobword != 0 ) m_tobwords.push_back(tobword);
 
       std::unique_ptr<eFEXegTOB> tmp_tob = m_eFEXegAlgoTool->geteFEXegTOB();
       
@@ -169,7 +176,10 @@ StatusCode eFEXFPGA::execute(){
     }
   }
 
-  // =============== TAU =============
+
+  //ATH_CHECK(store())
+
+  // --------------- TAU -------------
   for(int ieta = 1; ieta < 5; ieta++)
   {
     for(int iphi = 1; iphi < 9; iphi++)
@@ -197,10 +207,35 @@ StatusCode eFEXFPGA::execute(){
     }
   }
 
+
   return StatusCode::SUCCESS;
 
 }
 
+
+
+std::vector<uint32_t> eFEXFPGA::getEmTOBs()
+{
+  auto tobsSort = m_tobwords;
+
+  ATH_MSG_DEBUG("number of tobs: " <<tobsSort.size() << " in FPGA: " << m_id << " before truncation");
+
+  // sort tobs by their et (last 12 bits of the 32 bit tob word)
+  std::sort (tobsSort.begin(), tobsSort.end(), etSort);
+
+  /*
+  for(auto &j : tobsSort){
+    std::cout << "values: post sort " << std::bitset<32>(j) << std::endl;
+  }
+  */
+
+  // return the top 6 highest ET TOBs from the FPGA
+  tobsSort.resize(6);
+  return tobsSort;
+
+}
+
+
 void eFEXFPGA::SetTowersAndCells_SG(int tmp_eTowersIDs_subset[][6]){
     
   int rows = 10;
@@ -209,7 +244,7 @@ void eFEXFPGA::SetTowersAndCells_SG(int tmp_eTowersIDs_subset[][6]){
   std::copy(&tmp_eTowersIDs_subset[0][0], &tmp_eTowersIDs_subset[0][0]+(10*6),&m_eTowersIDs[0][0]);
   
   if(false){ //this prints out the eTower IDs that each FPGA is responsible for
-    ATH_MSG_DEBUG("\n==== eFEXFPGA ========= FPGA (" << m_id << ") IS RESPONSIBLE FOR eTOWERS :");
+    ATH_MSG_DEBUG("\n---- eFEXFPGA --------- FPGA (" << m_id << ") IS RESPONSIBLE FOR eTOWERS :");
     for (int thisRow=rows-1; thisRow>=0; thisRow--){
       for (int thisCol=0; thisCol<cols; thisCol++){
 	if(thisCol != cols-1){ ATH_MSG_DEBUG("|  " << m_eTowersIDs[thisRow][thisCol] << "  "); }
@@ -220,6 +255,7 @@ void eFEXFPGA::SetTowersAndCells_SG(int tmp_eTowersIDs_subset[][6]){
   
 }
 
+
 void eFEXFPGA::SetIsoWP(std::vector<unsigned int> & CoreEnv, std::vector<unsigned int> & thresholds, unsigned int & workingPoint) {
 
   bool CoreOverflow = false;
@@ -258,6 +294,34 @@ void eFEXFPGA::SetIsoWP(std::vector<unsigned int> & CoreEnv, std::vector<unsigne
 
 }
 
+
+
+
+uint32_t eFEXFPGA::formEmTOB(int & ieta, int & iphi)
+{
+  uint32_t tobWord = 0;
+  const unsigned int eFexTobstep = 100;
+
+
+  //returns a unsigned integer et value corresponding to the... eFEX EM cluster? in MeV
+  unsigned int et = m_eFEXegAlgoTool->getET();
+  unsigned int eFexTobEt = et/eFexTobstep;//steps of 100 MeV for the TOB
+
+  if (eFexTobEt > 0xfff) eFexTobEt = 0xfff; //truncate at 12 bits, set to max value of 4095, 0xfff, or 111111111111
+  int eta = ieta;
+  int phi = iphi;
+
+  //Create bare minimum tob word with et, eta, phi, and fpga index, bitshifted to the appropriate locations
+  tobWord = tobWord + eFexTobEt + (phi << 24) + (eta << 27) + (m_id << 30);
+
+  ATH_MSG_DEBUG("tobword with et, eta, phi, fpga: " << std::bitset<32>(tobWord) );
+
+  //some arbitrary cut so that we're not flooded with tobs. to be taken from the Trigger menu in the future!
+  unsigned int minEtThreshold = 30;
+  if (et < minEtThreshold) return 0;  
+  else return tobWord;
+
+}
   
 } // end of namespace bracket
 
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXSim.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXSim.cxx
index c99a2b9e51ee2a1aa49e76689789abd73685a6fe..89a1b8055d6fc02f2875180bb9de28d931252b20 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXSim.cxx
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXSim.cxx
@@ -29,14 +29,14 @@ namespace LVL1 {
   }
 
 
-  //================ Initialisation =================================================
+  //---------------- Initialisation -------------------------------------------------
 
   StatusCode eFEXSim::initialize()
   {
     return StatusCode::SUCCESS;
   }
 
-  //================ Finalisation =================================================
+  //---------------- Finalisation -------------------------------------------------
 
   StatusCode eFEXSim::finalize()
   {
@@ -75,7 +75,8 @@ namespace LVL1 {
  }
 
 StatusCode eFEXSim::NewExecute(int tmp_eTowersIDs_subset[10][18]){
-  
+  m_tobWords.clear();
+
   std::copy(&tmp_eTowersIDs_subset[0][0], &tmp_eTowersIDs_subset[0][0]+(10*18),&m_eTowersIDs[0][0]);
 
   int tmp_eTowersIDs_subset_FPGA[10][6];
@@ -92,6 +93,7 @@ StatusCode eFEXSim::NewExecute(int tmp_eTowersIDs_subset[10][18]){
   ATH_CHECK(m_eFEXFPGATool->init(0, m_id));
   m_eFEXFPGATool->SetTowersAndCells_SG(tmp_eTowersIDs_subset_FPGA);
   ATH_CHECK(m_eFEXFPGATool->execute());
+  m_tobWords.push_back(m_eFEXFPGATool->getEmTOBs());
   m_eFEXFPGATool->reset();
   //FPGA 0----------------------------------------------------------------------------------------------------------------------------------------------
   
@@ -105,6 +107,7 @@ StatusCode eFEXSim::NewExecute(int tmp_eTowersIDs_subset[10][18]){
   ATH_CHECK(m_eFEXFPGATool->init(1, m_id));
   m_eFEXFPGATool->SetTowersAndCells_SG(tmp_eTowersIDs_subset_FPGA);
   ATH_CHECK(m_eFEXFPGATool->execute());
+  m_tobWords.push_back(m_eFEXFPGATool->getEmTOBs());
   m_eFEXFPGATool->reset();
   //FPGA 1----------------------------------------------------------------------------------------------------------------------------------------------
 
@@ -119,6 +122,7 @@ StatusCode eFEXSim::NewExecute(int tmp_eTowersIDs_subset[10][18]){
   ATH_CHECK(m_eFEXFPGATool->init(2, m_id));
   m_eFEXFPGATool->SetTowersAndCells_SG(tmp_eTowersIDs_subset_FPGA);
   ATH_CHECK(m_eFEXFPGATool->execute());
+  m_tobWords.push_back(m_eFEXFPGATool->getEmTOBs());
   m_eFEXFPGATool->reset();
   //FPGA 2----------------------------------------------------------------------------------------------------------------------------------------------
 
@@ -132,6 +136,7 @@ StatusCode eFEXSim::NewExecute(int tmp_eTowersIDs_subset[10][18]){
   ATH_CHECK(m_eFEXFPGATool->init(3, m_id));
   m_eFEXFPGATool->SetTowersAndCells_SG(tmp_eTowersIDs_subset_FPGA);
   ATH_CHECK(m_eFEXFPGATool->execute());
+  m_tobWords.push_back(m_eFEXFPGATool->getEmTOBs());
   m_eFEXFPGATool->reset();
   //FPGA 3----------------------------------------------------------------------------------------------------------------------------------------------
 
@@ -139,6 +144,37 @@ StatusCode eFEXSim::NewExecute(int tmp_eTowersIDs_subset[10][18]){
 
 }
 
+
+std::vector<uint32_t> eFEXSim::getEmTOBs()
+{
+
+  std::vector<uint32_t> tobsSort;
+  tobsSort.clear();
+  bool first = true;
+
+  // concatonate tobs from the fpgas
+  for(auto &j : m_tobWords){
+    if (first) tobsSort = j;
+    else tobsSort.insert(tobsSort.end(),j.begin(),j.end());
+    first = false;
+  }
+
+  ATH_MSG_DEBUG("number of tobs: " <<tobsSort.size() << " in eFEX: " << m_id);
+
+  // sort the tobs from the fpgas by their et (last 12 bits of 32 bit word)
+  std::sort (tobsSort.begin(), tobsSort.end(), etSort);
+
+  /*
+  for(auto &j : tobsSort){
+    std::cout << "values: post sort " << std::bitset<32>(j) << std::endl;
+  }
+  */
+
+  // return the tob 6 highest ET TOBs from the efex
+  tobsSort.resize(6);
+  return tobsSort;
+}
+
 void eFEXSim::SetTowersAndCells_SG(int tmp_eTowersIDs_subset[10][18]){ // METHOD USING ONLY IDS
 
   std::copy(&tmp_eTowersIDs_subset[0][0], &tmp_eTowersIDs_subset[0][0]+(10*18),&m_eTowersIDs[0][0]);
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXSysSim.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXSysSim.cxx
index cb47ef03620e4e4e15cde7ec218fa3979fc2e854..2f913756fc7810fedbad2301d0134c5dfd299dce 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXSysSim.cxx
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/eFEXSysSim.cxx
@@ -21,6 +21,9 @@
 #include "StoreGate/ReadHandle.h"
 #include "GaudiKernel/ServiceHandle.h"
 
+#include "xAODTrigger/eFexEMRoI.h"
+#include "xAODTrigger/eFexEMRoIContainer.h"
+#include "xAODTrigger/eFexEMRoIAuxContainer.h"
 
 #include <ctime>
 
@@ -42,7 +45,7 @@ namespace LVL1 {
   //{
   //}
 
-  //================ Initialisation =================================================
+  //---------------- Initialisation -------------------------------------------------
 
   StatusCode eFEXSysSim::initialize()
   {
@@ -51,10 +54,12 @@ namespace LVL1 {
 
     ATH_CHECK( m_eFEXSimTool.retrieve() );
 
+    ATH_CHECK(m_eFexOutKey.initialize());
+
     return StatusCode::SUCCESS;
   }
 
-  //================ Finalisation =================================================
+  //---------------- Finalisation -------------------------------------------------
 
   StatusCode eFEXSysSim::finalize()
   {
@@ -69,7 +74,7 @@ namespace LVL1 {
   void eFEXSysSim::cleanup()  {
 
     m_eFEXCollection.clear();
-    m_eTowersColl.clear();
+    //m_eTowersColl.clear();
 
   }
 
@@ -98,7 +103,7 @@ namespace LVL1 {
     // 0.7 -> 2.5
 
     // boundaries in phi: 0.2, 1.0, 1.8, 2.6, 3.4, 4.2, 5.0, 5.8
-    // Written explicityl with REAL boundaries in eta (overlaps must occur for sliding window algorithms!)
+    // Written explicitly with REAL boundaries in phi (overlaps must occur for sliding window algorithms!)
     // 0.1 -> 1.1
     // 0.9 -> 1.9
     // 1.7 -> 2.7
@@ -120,7 +125,10 @@ namespace LVL1 {
     int embEta = 13; int embPhi = 1; int embMod = 100000;
     int initialEMB = calcTowerID(embEta,embPhi,embMod); //100833;
 
-    for (int thisEFEX=0; thisEFEX<=21; thisEFEX+=3){
+    int maxPhi = 8;//maximum number of efexes in phi
+    int eFEXa = 160;//changed from 0
+
+    for (int thisEFEX=eFEXa; thisEFEX<eFEXa+maxPhi; thisEFEX++){
       
       if(fexcounter > 0){ initialEMEC += 8; initialTRANS += 8; initialEMB += 8; } // TODO // SOMEHOW REMOVE HARD-CODING?
 
@@ -139,7 +147,7 @@ namespace LVL1 {
 
 	  int towerid = initialEMEC - (thisCol * 64) + thisRow;
 
-	  if( (thisEFEX == 21) && (thisRow >= 7)){ towerid -= 64; };
+	  if( (thisEFEX-eFEXa == maxPhi-1) && (thisRow >= 7)){ towerid -= 64; };
 	  
 	  tmp_eTowersIDs_subset[thisRow][thisCol] = towerid;
 	  tmp_eTowersColl_subset.insert( std::map<int, eTower>::value_type(towerid,  *(this_eTowerContainer->findTower(towerid))));
@@ -154,7 +162,7 @@ namespace LVL1 {
 
 	int towerid = initialTRANS + thisRow;
 
-	if( (thisEFEX == 21) && (thisRow >= 7)){ towerid -= 64; };
+	if( (thisEFEX-eFEXa == maxPhi-1) && (thisRow >= 7)){ towerid -= 64; };
 
 	tmp_eTowersIDs_subset[thisRow][10] = towerid;
 	tmp_eTowersColl_subset.insert( std::map<int, eTower>::value_type(towerid,  *(this_eTowerContainer->findTower(towerid))));
@@ -169,7 +177,7 @@ namespace LVL1 {
 
 	  int towerid = initialEMB - ( (thisCol-11) * 64) + thisRow;
 
-	  if( (thisEFEX == 21) && (thisRow >= 7)){ towerid -= 64; };
+	  if( (thisEFEX-eFEXa == maxPhi-1) && (thisRow >= 7)){ towerid -= 64; };
 
 	  tmp_eTowersIDs_subset[thisRow][thisCol] = towerid;
 	  tmp_eTowersColl_subset.insert( std::map<int, eTower>::value_type(towerid,  *(this_eTowerContainer->findTower(towerid))));
@@ -196,6 +204,7 @@ namespace LVL1 {
 
       m_eFEXSimTool->init(thisEFEX);
       ATH_CHECK(m_eFEXSimTool->NewExecute(tmp_eTowersIDs_subset));
+      m_allEmTobs.insert( std::map<int, std::vector<uint32_t> >::value_type(thisEFEX, (m_eFEXSimTool->getEmTOBs() ) ));
       m_eFEXSimTool->reset();
 
       fexcounter++;
@@ -209,8 +218,9 @@ namespace LVL1 {
     int initialEMB_neg = calcTowerID(embnegEta,embnegPhi,embnegMod); //100513;
     int embposEta = 0; int embposPhi = 1; int embposMod = 200000;
     int initialEMB_pos = calcTowerID(embposEta,embposPhi,embposMod); //200001;
+    int eFEXb = 176;
 
-    for (int thisEFEX=1; thisEFEX<=22; thisEFEX+=3){
+    for (int thisEFEX=eFEXb; thisEFEX-eFEXb<maxPhi; thisEFEX++){
 
       if(fexcounter > 0){  initialEMB_neg += 8; initialEMB_pos += 8; }
       
@@ -238,7 +248,7 @@ namespace LVL1 {
 	    towerid = tmp_initEMB + ( (thisCol-9) * 64) + thisRow;
 	  }
 
-	  if( (thisEFEX == 22) && (thisRow >= 7)){ towerid -= 64; };
+	  if( (thisEFEX-eFEXb == maxPhi-1) && (thisRow >= 7)){ towerid -= 64; };
 
           tmp_eTowersIDs_subset[thisRow][thisCol] = towerid;
 
@@ -266,6 +276,7 @@ namespace LVL1 {
       //tool use instead
       m_eFEXSimTool->init(thisEFEX);
       ATH_CHECK(m_eFEXSimTool->NewExecute(tmp_eTowersIDs_subset));
+      m_allEmTobs.insert( std::map<int, std::vector<uint32_t> >::value_type(thisEFEX, (m_eFEXSimTool->getEmTOBs() ) ));
       m_eFEXSimTool->reset();
 
       fexcounter++;
@@ -282,8 +293,9 @@ namespace LVL1 {
     initialTRANS = calcTowerID(transEta,transPhi,transMod); //400897;
     embEta = 7; embPhi = 1; embMod = 200000;
     initialEMB = calcTowerID(embEta,embPhi,embMod); //200449;
+    int eFEXc = 192;
 
-    for (int thisEFEX=2; thisEFEX<=23; thisEFEX+=3){
+    for (int thisEFEX=eFEXc; thisEFEX-eFEXc<maxPhi; thisEFEX++){
 
       if(fexcounter > 0){ initialEMEC += 8; initialTRANS += 8; initialEMB += 8; }
 
@@ -301,7 +313,7 @@ namespace LVL1 {
         for(int thisRow=0; thisRow<rows; thisRow++){
           int towerid = initialEMB + ( (thisCol) * 64) + thisRow;
 
-          if( (thisEFEX == 23) && (thisRow >= 7)){ towerid -= 64; };
+          if( (thisEFEX-eFEXc == maxPhi-1) && (thisRow >= 7)){ towerid -= 64; };
 
           tmp_eTowersIDs_subset[thisRow][thisCol] = towerid;
           tmp_eTowersColl_subset.insert( std::map<int, eTower>::value_type(towerid,  *(this_eTowerContainer->findTower(towerid))));
@@ -314,7 +326,7 @@ namespace LVL1 {
       for(int thisRow = 0; thisRow < rows; thisRow++){
         int towerid = initialTRANS + thisRow;
 
-        if( (thisEFEX == 23) && (thisRow >= 7)){ towerid -= 64; };
+        if( (thisEFEX-eFEXc == maxPhi-1) && (thisRow >= 7)){ towerid -= 64; };
 
         tmp_eTowersIDs_subset[thisRow][7] = towerid;
         tmp_eTowersColl_subset.insert( std::map<int, eTower>::value_type(towerid,  *(this_eTowerContainer->findTower(towerid))));
@@ -327,7 +339,7 @@ namespace LVL1 {
         for(int thisRow=0; thisRow<rows; thisRow++){
           int towerid = initialEMEC + ( (thisCol-8) * 64) + thisRow;
 
-          if( (thisEFEX == 23) && (thisRow >= 7)){ towerid -= 64; };
+          if( (thisEFEX-eFEXc == maxPhi-1) && (thisRow >= 7)){ towerid -= 64; };
 
           tmp_eTowersIDs_subset[thisRow][thisCol] = towerid;
           tmp_eTowersColl_subset.insert( std::map<int, eTower>::value_type(towerid,  *(this_eTowerContainer->findTower(towerid))));
@@ -354,16 +366,28 @@ namespace LVL1 {
       //tool use instead
       m_eFEXSimTool->init(thisEFEX);
       ATH_CHECK(m_eFEXSimTool->NewExecute(tmp_eTowersIDs_subset));
+      m_allEmTobs.insert( std::map<int, std::vector<uint32_t> >::value_type(thisEFEX, (m_eFEXSimTool->getEmTOBs() ) ));
       m_eFEXSimTool->reset();
 
       fexcounter++;
 
     }
     
-    //Collate TOBS returned from eFEXSims. Should that be here?
-    // ToDo
-    // To implement
-    // {--Implement--}
+
+    m_eContainer = std::make_unique<xAOD::eFexEMRoIContainer> ();
+    m_eAuxContainer = std::make_unique<xAOD::eFexEMRoIAuxContainer> ();
+    m_eContainer->setStore(m_eAuxContainer.get());
+
+    // iterate over all Em Tobs and fill EDM with them
+    for( auto const& [efex, tobs] : m_allEmTobs ){
+      for(auto &tob : tobs){
+	ATH_CHECK(fillEDM(efex,tob));
+      }
+    }
+    
+    SG::WriteHandle<xAOD::eFexEMRoIContainer> outputeFexHandle(m_eFexOutKey/*, ctx*/);
+    ATH_MSG_DEBUG("  write: " << outputeFexHandle.key() << " = " << "..." );
+    ATH_CHECK(outputeFexHandle.record(std::move(m_eContainer),std::move(m_eAuxContainer)));
 
 
     //Send TOBs to bytestream?
@@ -374,6 +398,23 @@ namespace LVL1 {
     return StatusCode::SUCCESS;
 
   }
+  
+
+  StatusCode eFEXSysSim::fillEDM(uint8_t eFexNum, uint32_t tobWord){
+
+    uint8_t eFEXNumber = eFexNum; 
+    uint32_t tobWord0 = tobWord;
+    uint32_t tobWord1 = 0;
+        
+    xAOD::eFexEMRoI* myEDM = new xAOD::eFexEMRoI();
+    m_eContainer->push_back( myEDM );
+
+    myEDM->initialize(eFEXNumber, tobWord0, tobWord1);
+    ATH_MSG_DEBUG(" setting eFEX Number:  " << +myEDM->eFexNumber() << " et: " << myEDM->et() << " eta: " << myEDM->eta() <<  " phi: " << myEDM->phi() );
+
+    return StatusCode::SUCCESS;
+
+  }
 
   
 } // end of namespace bracket
diff --git a/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IeFEXFPGA.h b/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IeFEXFPGA.h
index b862b6eafd5dfc32bbcd04048636e04a729e361d..d94aa1a1227f651d569d9e362081f2d2dff2f853 100644
--- a/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IeFEXFPGA.h
+++ b/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IeFEXFPGA.h
@@ -3,7 +3,7 @@
 */
 
 //***************************************************************************
-//                           eFEXFPGA.h  -
+//                           IeFEXFPGA.h  -
 //                              -------------------
 //     begin                : 23 03 2019
 //     email                :  jacob.julian.kempster@cern.ch
@@ -14,10 +14,7 @@
 
 
 #include "GaudiKernel/IAlgTool.h"
-#include "L1CaloFEXSim/eTower.h"
-#include "CaloEvent/CaloCellContainer.h"
-#include "CaloIdentifier/CaloIdManager.h"
-#include "CaloIdentifier/CaloCell_SuperCell_ID.h"
+#include "xAODTrigger/eFexEMRoI.h"
 
 namespace LVL1 {
   
@@ -37,12 +34,18 @@ Interface definition for eFEXFPGA
 
     virtual void reset() = 0;
 
-    virtual int ID() = 0;
+    virtual int getID() = 0;
 
     virtual void SetTowersAndCells_SG(int [][6]) = 0;
     
     virtual void SetIsoWP(std::vector<unsigned int> &, std::vector<unsigned int> &, unsigned int &) = 0;
 
+    virtual uint32_t formEmTOB(int &, int &) = 0;
+
+    virtual std::vector<uint32_t> getEmTOBs() = 0; 
+
+    // static virtual bool etSort(uint32_t &, uint32_t &) = 0;
+
   private:
 
   };
diff --git a/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IeFEXSim.h b/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IeFEXSim.h
index 8bf6935dcd66f707c82991e91fbad03e7bafd09b..00bfdc027965ac56437475af3414c641d82f6f85 100644
--- a/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IeFEXSim.h
+++ b/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IeFEXSim.h
@@ -38,6 +38,7 @@ Interface definition for eFEXSim
     virtual void SetTowersAndCells_SG(int tmp[10][18]) = 0;
 
     virtual StatusCode NewExecute(int tmp[10][18]) = 0;
+    virtual std::vector<uint32_t> getEmTOBs() = 0;
 
   private:
 
diff --git a/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IeFEXSysSim.h b/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IeFEXSysSim.h
index 0c99ad230ff5f11315f3478f9958c0e9797a5e52..da08124bdc857719d375bdb3b91475345506c2cb 100644
--- a/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IeFEXSysSim.h
+++ b/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IeFEXSysSim.h
@@ -37,6 +37,8 @@ Interface definition for eFEXSysSim
 
     virtual int calcTowerID(int eta, int phi, int mod) = 0 ;
     
+    virtual StatusCode fillEDM(uint8_t eFEXNumber, uint32_t tobWord) = 0;
+
   private:
 
   };