From b570e22ad6f6a06949c9afb135822c434d5d1d02 Mon Sep 17 00:00:00 2001
From: Sergi Rodriguez Bosca <sergi.rodriguez@cern.ch>
Date: Mon, 5 Apr 2021 06:09:15 +0000
Subject: [PATCH] L1Calo BitWise Offline Software Simulation. jFEX Tau
 Algorithm

---
 .../L1CaloFEXSim/L1CaloFEXSim/jFEXFPGA.h      |  18 +-
 .../L1CaloFEXSim/jFEXNtupleWriter.h           |  19 +
 .../L1CaloFEXSim/jFEXOutputCollection.h       |   6 +
 .../L1CaloFEXSim/jFEXSmallRJetAlgo.h          |   7 +-
 .../L1CaloFEXSim/L1CaloFEXSim/jFEXtauAlgo.h   | 106 +++++
 .../L1CaloFEXSim/L1CaloFEXSim/jFEXtauTOB.h    |  52 +++
 .../src/components/FEXDriver_entries.cxx      |   3 +
 .../L1CaloFEX/L1CaloFEXSim/src/jFEXFPGA.cxx   | 397 +++++++++++++-----
 .../L1CaloFEXSim/src/jFEXNtupleWriter.cxx     |  73 +++-
 .../L1CaloFEXSim/src/jFEXOutputCollection.cxx |  29 ++
 .../L1CaloFEXSim/src/jFEXSmallRJetAlgo.cxx    |  94 +++--
 .../L1CaloFEXSim/src/jFEXtauAlgo.cxx          | 280 ++++++++++++
 .../L1CaloFEX/L1CaloFEXSim/src/jFEXtauTOB.cxx |  77 ++++
 .../L1CaloFEXToolInterfaces/IjFEXFPGA.h       |   3 +
 .../IjFEXSmallRJetAlgo.h                      |   5 +-
 .../L1CaloFEXToolInterfaces/IjFEXtauAlgo.h    |  54 +++
 16 files changed, 1058 insertions(+), 165 deletions(-)
 create mode 100644 Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXtauAlgo.h
 create mode 100644 Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXtauTOB.h
 create mode 100644 Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXtauAlgo.cxx
 create mode 100644 Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXtauTOB.cxx
 create mode 100644 Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXtauAlgo.h

diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXFPGA.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXFPGA.h
index 7192e99bcd5..1df64e942a1 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXFPGA.h
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXFPGA.h
@@ -20,6 +20,7 @@
 #include "L1CaloFEXSim/jTowerContainer.h"
 #include "L1CaloFEXToolInterfaces/IjFEXSmallRJetAlgo.h"
 #include "L1CaloFEXToolInterfaces/IjFEXLargeRJetAlgo.h"
+#include "L1CaloFEXToolInterfaces/IjFEXtauAlgo.h"
 #include "CaloEvent/CaloCellContainer.h"
 #include "CaloIdentifier/CaloIdManager.h"
 #include "CaloIdentifier/CaloCell_SuperCell_ID.h"
@@ -62,18 +63,27 @@ namespace LVL1 {
     virtual uint32_t formLargeRJetTOB(int &, int &) override;
     virtual std::vector <uint32_t> getSmallRJetTOBs() override;
     virtual std::vector <uint32_t> getLargeRJetTOBs() override;
+
+    /**Form a tob word out of the potential candidate Tau tob */
+    virtual uint32_t formTauTOB(int &, int &) override;
+    virtual std::vector <uint32_t> getTauTOBs() override;    
+    
  
    /** Internal data */
   private:
     static bool etSort(uint32_t i, uint32_t j){ return (((i >> 0 ) & 0x7ff)> ((j >> 0) & 0x7ff));}
-
+    static bool etTauSort(uint32_t i, uint32_t j) {
+      return (((i >> 0 ) & 0x7ff000)> ((j >> 0) & 0x7ff000));
+    }
     int m_id;
     int m_jfexid;
     std::vector<uint32_t> m_SRJet_tobwords;
     std::vector<uint32_t> m_LRJet_tobwords;
+    std::vector<uint32_t> m_tau_tobwords;
 
-    int m_jTowersIDs_Wide [FEXAlgoSpaceDefs::jFEX_algoSpace_height][FEXAlgoSpaceDefs::jFEX_wide_algoSpace_width];
-    int m_jTowersIDs_Thin [FEXAlgoSpaceDefs::jFEX_algoSpace_height][FEXAlgoSpaceDefs::jFEX_thin_algoSpace_width];
+    int m_jTowersIDs_Wide [FEXAlgoSpaceDefs::jFEX_algoSpace_height][FEXAlgoSpaceDefs::jFEX_wide_algoSpace_width] = {0};
+    int m_jTowersIDs_Thin [FEXAlgoSpaceDefs::jFEX_algoSpace_height][FEXAlgoSpaceDefs::jFEX_thin_algoSpace_width] = {0};
+    int m_jTowersIDs      [FEXAlgoSpaceDefs::jFEX_algoSpace_height][FEXAlgoSpaceDefs::jFEX_thin_algoSpace_width] = {0};
     std::map<int,jTower> m_jTowersColl;
 
     CaloCellContainer m_sCellsCollection;
@@ -84,7 +94,7 @@ namespace LVL1 {
 
     ToolHandle<IjFEXSmallRJetAlgo> m_jFEXSmallRJetAlgoTool {this, "jFEXSmallRJetAlgoTool", "LVL1::jFEXSmallRJetAlgo", "Tool that runs the jFEX Small R Jet algorithm"};
     ToolHandle<IjFEXLargeRJetAlgo> m_jFEXLargeRJetAlgoTool {this, "jFEXLargeRJetAlgoTool", "LVL1::jFEXLargeRJetAlgo", "Tool that runs the jFEX Large R Jet algorithm"};
-    //ToolHandle<IjFEXtauAlgo> m_jFEXtauAlgoTool {this, "jFEXtauAlgoTool", "LVL1::jFEXtauAlgo", "Tool that runs the jFEX tau algorithm"};
+    ToolHandle<IjFEXtauAlgo> m_jFEXtauAlgoTool             {this, "jFEXtauAlgoTool"      , "LVL1::jFEXtauAlgo"      , "Tool that runs the jFEX tau algorithm"};
     //ToolHandle<IjFEXegAlgo> m_jFEXegAlgoTool {this, "jFEXegAlgoTool", "LVL1::jFEXegAlgo", "Tool that runs the jFEX e/gamma algorithm"};
     
   };
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXNtupleWriter.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXNtupleWriter.h
index dd4234bace8..d49337c99b9 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXNtupleWriter.h
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXNtupleWriter.h
@@ -66,12 +66,31 @@ private:
   std::vector<float> m_largeRJetTOB_phi;
   std::vector<float> m_largeRJetTOB_ET;
 
+  std::vector<int> m_tau_isLocalMax;
+  std::vector<int> m_tau_TT_ID;
+  std::vector<int> m_tau_ET;
+  std::vector<int> m_tau_clusterET;
+  std::vector<int> m_tau_eta;
+  std::vector<int> m_tau_phi;
+  std::vector<int> m_tau_realeta;
+  std::vector<int> m_tau_ISO;
+  std::vector<int> m_tau_jFEXid;
+  std::vector<int> m_tau_FPGAid;
+  
+  std::vector<int> m_tau_TOB_word;
+  std::vector<int> m_tau_TOB_ET;
+  std::vector<int> m_tau_TOB_eta;
+  std::vector<int> m_tau_TOB_phi;
+  std::vector<int> m_tau_TOB_ISO;
+  std::vector<int> m_tau_TOB_Sat;
+
 //std::string m_jet_container_name = "AntiKt10TruthJets";
 
   TTree *m_myTree;
  
   StatusCode loadsmallRJetAlgoVariables();
   StatusCode loadlargeRJetAlgoVariables();
+  StatusCode loadtauAlgoVariables();
 //  StatusCode loadTruthElectron();
 //  StatusCode loadTruthJets();
 //  StatusCode loadTruthTau();
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXOutputCollection.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXOutputCollection.h
index c2772838496..09b5fc3c11d 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXOutputCollection.h
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXOutputCollection.h
@@ -30,15 +30,21 @@ namespace LVL1 {
     void fill_smallRJet();
     void addValue_largeRJet(std::string, float);
     void fill_largeRJet();
+    void addValue_tau(std::string, int);
+    void fill_tau();
     int size();
+    int tausize();
     std::map<std::string, float>* get_smallRJet(int);
     std::map<std::string, float>* get_largeRJet(int);
+    std::map<std::string, int>* get_tau(int);
 
   private:
     std::map<std::string, float> m_values_tem_smallRJet;
     std::vector<std::map<std::string, float>*> m_allvalues_smallRJet;
     std::map<std::string, float> m_values_tem_largeRJet;
     std::vector<std::map<std::string, float>*> m_allvalues_largeRJet;
+    std::map<std::string, int> m_values_tem_tau;
+    std::vector<std::map<std::string, int>*> m_allvalues_tau;
   };
 }
 
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXSmallRJetAlgo.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXSmallRJetAlgo.h
index 09e2d90692e..491bf0c155f 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXSmallRJetAlgo.h
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXSmallRJetAlgo.h
@@ -39,14 +39,14 @@ namespace LVL1 {
     virtual ~jFEXSmallRJetAlgo();
 
     virtual StatusCode safetyTest() override;
-    virtual void setup(int inputTable[5][5]) override;
-    virtual void setupCluster(int inputTable[4][5]) override;
+    virtual void setup(int inputTable[7][7], bool barrel_region) override;
     virtual unsigned int getRealPhi() override;
     virtual unsigned int getRealEta() override;   
     virtual unsigned int getTTowerET() override;
     virtual void buildSeeds() override; 
     virtual bool isSeedLocalMaxima() override; 
     virtual unsigned int getSmallClusterET() override;
+    virtual unsigned int getSmallETRing() override;
     virtual std::unique_ptr<jFEXSmallRJetTOB> getSmallRJetTOBs() override;
   //  virtual jFEXSmallRJetTOB* getSmallRJetTOBs() override;
 //LVL1::jFEXSmallRJetAlgoTOB * LVL1::jFEXSmallRJetAlgo::getSmallRJetTOB()
@@ -55,10 +55,11 @@ protected:
 
   private:
         SG::ReadHandleKey<LVL1::jTowerContainer> m_jFEXSmallRJetAlgo_jTowerContainerKey {this, "MyjTowers", "jTowerContainer", "Input container for jTowers"};
-        int m_jFEXalgoTowerID[5][5];
+        int m_jFEXalgoTowerID[7][7];
         int m_jFEXalgoSearchWindowSeedET[5][5];
         int m_smallRJetClusterIDs[4][5];
 	bool m_seedSet;
+        bool m_barrel_region;
   };
 
 
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXtauAlgo.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXtauAlgo.h
new file mode 100644
index 00000000000..b4407fb180a
--- /dev/null
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXtauAlgo.h
@@ -0,0 +1,106 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration  
+*/
+//***************************************************************************  
+//		jFEXtauAlgo - Algorithm for Tau Algorithm in jFEX
+//                              -------------------
+//     begin                : 18 02 2021
+//     email                : Sergi.Rodriguez@cern.ch
+//***************************************************************************
+
+#ifndef jFEXtauAlgo_H
+#define jFEXtauAlgo_H
+
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "L1CaloFEXToolInterfaces/IjFEXtauAlgo.h"
+#include "AthenaKernel/CLASS_DEF.h"
+#include "L1CaloFEXSim/jFEXtauTOB.h"
+#include "L1CaloFEXSim/jTowerContainer.h"
+
+#include "CaloEvent/CaloCellContainer.h"
+#include "CaloIdentifier/CaloIdManager.h" 
+#include "CaloIdentifier/CaloCell_SuperCell_ID.h"
+#include "AthenaBaseComps/AthAlgorithm.h" 
+#include "StoreGate/StoreGateSvc.h" 
+
+
+namespace LVL1 {
+
+  class jFEXtauAlgo : public AthAlgTool, virtual public IjFEXtauAlgo{
+
+  public:
+    /** Constructors **/
+    jFEXtauAlgo(const std::string& type, const std::string& name, const IInterface* parent);
+   
+    /** standard Athena-Algorithm method **/
+    virtual StatusCode initialize() override;
+
+    /** Destructor **/
+    virtual ~jFEXtauAlgo();
+
+    virtual StatusCode safetyTest() override;
+    virtual void setup(int TTwindow[5][5], int seed[3][3]) override;
+    virtual int getTTowerET(unsigned int row_=1 ,unsigned int col_=1 ) override; // arguments 2,2 to get the central TT from m_TTwindow[5][5]
+    virtual int getRealPhi(unsigned int row_=1 ,unsigned int col_=1 ) override; // arguments 2,2 to get the central TT from m_TTwindow[5][5]
+    virtual int getRealEta(unsigned int row_=1 ,unsigned int col_=1 ) override; // arguments 2,2 to get the central TT from m_TTwindow[5][5]   
+
+    virtual void buildSeeds() override; 
+    virtual bool isSeedLocalMaxima() override;
+    virtual void setFirstEtRing(int First_ETring[])  override;
+    virtual int getClusterEt() override;
+    virtual int getIsLocalMaxima() override;
+    virtual int getFirstEtRing()  override;
+    
+    
+    virtual std::unique_ptr<jFEXtauTOB> getTauTOBs(int mphi, int meta) override;
+    virtual void Represent(int var_=0, int dim_=3) override; 
+
+    
+// virtual jFEXtauAlgo* getTauTOBs() override;
+//LVL1::jFEXtauAlgoTOB * LVL1::jFEXtauAlgo::getTauTOB()
+    
+protected:
+
+  private:
+        SG::ReadHandleKey<LVL1::jTowerContainer> m_jFEXtauAlgo_jTowerContainerKey {this, "MyjTowers", "jTowerContainer", "Input container for jTowers"};
+        int realValue(int ID, int eta);
+        int m_SeedIDs[3][3]={0};
+        int m_SeedConditions_ET[3][3]={0};
+        int m_SeedCluster_ET[3][3]={0};
+        int m_TTwindow[5][5]={0};
+        int m_ClusterEt = 0;
+        int m_TauIsolation = 0;
+        //int m_tauClusterIDs[4][5];
+	      bool m_seedSet=false;
+	      bool m_isLocalMaxima=false;
+
+        struct color {
+            std::string RED      ="\033[1;31m";
+            std::string ORANGE   ="\033[1;38;5;208m";
+            std::string YELLOW   ="\033[1;33m";
+            std::string GREEN    ="\033[1;32m";
+            std::string BLUE     ="\033[1;34m";
+            std::string PURPLE   ="\033[1;35m";
+            std::string END      ="\033[0m";
+            std::string B_BLUE   ="\033[1;44m";
+            std::string B_PURPLE ="\033[1;45m";
+            std::string B_ORANGE ="\033[1;48;5;208;30m";
+            std::string B_GRAY   ="\033[1;100m";
+            std::string B_RED    ="\033[1;41m";
+            std::string B_GREEN  ="\033[1;42m";
+        } m_color;
+
+
+
+        
+  };
+
+
+
+}//end of namespace
+
+
+CLASS_DEF( LVL1::jFEXtauAlgo , 121222945 , 1 )
+
+#endif
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXtauTOB.h b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXtauTOB.h
new file mode 100644
index 00000000000..cb1ee024163
--- /dev/null
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/L1CaloFEXSim/jFEXtauTOB.h
@@ -0,0 +1,52 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+//***************************************************************************
+//              jFEXtauTOB - TOBs Tau Algorithm in jFEX
+//                              -------------------
+//     begin                : 18 02 2021
+//     email                : Sergi.Rodriguez@cern.ch
+//***************************************************************************
+
+
+#ifndef JFEX_TAU_TOB_H
+#define JFEX_TAU_TOB_H
+#include "AthenaKernel/CLASS_DEF.h"
+
+namespace LVL1 {
+  class jFEXtauTOB
+  {
+ 
+  private:
+    unsigned int m_eta;
+    unsigned int m_phi;
+    unsigned int m_ET;
+    unsigned int m_Iso;
+    unsigned int m_Sat;
+
+
+  public:
+    jFEXtauTOB();
+    ~jFEXtauTOB() {};
+
+    void setET(unsigned int);
+    void setPhi(unsigned int);
+    void setEta(unsigned int);
+    void setIso(unsigned int);
+    void setSat(unsigned int);
+    unsigned int GetEta();
+    unsigned int GetPhi();
+    unsigned int GetET();
+    unsigned int GetIso();
+    unsigned int GetSat();
+
+
+    
+
+  };
+  
+
+} //end of namespace
+
+CLASS_DEF( LVL1::jFEXtauTOB , 207986940 , 1 )
+#endif 
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/components/FEXDriver_entries.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/components/FEXDriver_entries.cxx
index de9582c9c3c..d4573d17b55 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/components/FEXDriver_entries.cxx
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/components/FEXDriver_entries.cxx
@@ -14,9 +14,11 @@
 #include "L1CaloFEXSim/jFEXSim.h"
 #include "L1CaloFEXSim/jFEXFPGA.h"
 #include "L1CaloFEXSim/jFEXSmallRJetAlgo.h"
+#include "L1CaloFEXSim/jFEXtauAlgo.h"
 #include "L1CaloFEXSim/jFEXLargeRJetAlgo.h"
 #include "L1CaloFEXSim/jFEXNtupleWriter.h"
 
+
 using namespace LVL1;
 
 DECLARE_COMPONENT(eFEXDriver)
@@ -36,5 +38,6 @@ DECLARE_COMPONENT(jTowerBuilder)
 DECLARE_COMPONENT(jSuperCellTowerMapper)
 DECLARE_COMPONENT(jFEXFPGA)
 DECLARE_COMPONENT(jFEXSmallRJetAlgo)
+DECLARE_COMPONENT(jFEXtauAlgo)
 DECLARE_COMPONENT(jFEXLargeRJetAlgo)
 DECLARE_COMPONENT(jFEXNtupleWriter)
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXFPGA.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXFPGA.cxx
index f1a124ebd86..0ba439061b4 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXFPGA.cxx
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXFPGA.cxx
@@ -17,8 +17,8 @@
 #include "L1CaloFEXSim/jFEXLargeRJetAlgo.h" 
 #include "L1CaloFEXSim/jFEXOutputCollection.h" 
 #include "L1CaloFEXSim/FEXAlgoSpaceDefs.h"
-//#include "L1CaloFEXSim/jFEXtauAlgo.h" //for the future
-//#include "L1CaloFEXSim/jFEXtauTOB.h" //for the future
+#include "L1CaloFEXSim/jFEXtauAlgo.h" //the future is now
+#include "L1CaloFEXSim/jFEXtauTOB.h"  //the future is now
 #include "CaloEvent/CaloCellContainer.h"
 #include "CaloIdentifier/CaloIdManager.h"
 #include "CaloIdentifier/CaloCell_SuperCell_ID.h"
@@ -42,12 +42,12 @@ jFEXFPGA::jFEXFPGA(const std::string& type,const std::string& name,const IInterf
 {
   declareInterface<IjFEXFPGA>(this);
 }
-  
-    
-  /** Destructor */
-  jFEXFPGA::~jFEXFPGA()
-  {
-  }
+
+
+/** Destructor */
+jFEXFPGA::~jFEXFPGA()
+{
+}
 
 //================ Initialisation =================================================
   
@@ -58,7 +58,7 @@ StatusCode jFEXFPGA::initialize()
   //ATH_CHECK(m_jFEXFPGA_jFEXOutputCollectionKey.initialize());
   return StatusCode::SUCCESS;
 }
-  
+
 
 StatusCode jFEXFPGA::init(int id, int jfexid)
 {
@@ -69,144 +69,262 @@ StatusCode jFEXFPGA::init(int id, int jfexid)
 
 }
 
-void jFEXFPGA::reset(){
+void jFEXFPGA::reset() {
 
   m_id = -1;
   m_jfexid = -1;
+  m_tau_tobwords.clear();
 
 }
 
-StatusCode jFEXFPGA::execute(){
+StatusCode jFEXFPGA::execute() {
 
   SG::ReadHandle<jTowerContainer> jk_jFEXFPGA_jTowerContainer(m_jFEXFPGA_jTowerContainerKey/*,ctx*/);
-  if(!jk_jFEXFPGA_jTowerContainer.isValid()){
+  if(!jk_jFEXFPGA_jTowerContainer.isValid()) {
     ATH_MSG_FATAL("Could not retrieve jk_jFEXFPGA_jTowerContainer " << m_jFEXFPGA_jTowerContainerKey.key() );
     return StatusCode::FAILURE;
   }
 
 
-//-----------jFEXSmallRJetAlgo----------------- 
+  //-----------jFEXSmallRJetAlgo-----------------
   ATH_MSG_DEBUG("==== jFEXSmallRJetAlgo ========");
   jFEXOutputCollection* jFEXOutputs;
   StatusCode sc_tobs = evtStore()->retrieve(jFEXOutputs, "jFEXOutputCollection");
 
-  if(sc_tobs == StatusCode::FAILURE){ATH_MSG_DEBUG("\n==== jFEXSmallRJetAlgo ======== Failed to find jFEXOutputCollection in jFEXFPGA");}
- 
-  for(int ieta = 1; ieta < 30; ieta++){
-    for(int iphi = 1; iphi < 15; iphi++){
-
-      //To note: Thin mapping needs to be fixed in order to see correct outputs.
-      int tobtable[5][5]={
-      {m_jTowersIDs_Thin[ieta +2][iphi -2], m_jTowersIDs_Thin[ieta +2][iphi -1], m_jTowersIDs_Thin[ieta +2][iphi], m_jTowersIDs_Thin[ieta +2][iphi +1], m_jTowersIDs_Thin[ieta +2][iphi +2]},
-      {m_jTowersIDs_Thin[ieta +1][iphi -2], m_jTowersIDs_Thin[ieta +1][iphi -1], m_jTowersIDs_Thin[ieta +1][iphi], m_jTowersIDs_Thin[ieta +1][iphi +1], m_jTowersIDs_Thin[ieta +1][iphi +2]},
-      {m_jTowersIDs_Thin[ieta][iphi -2], m_jTowersIDs_Thin[ieta][iphi -1], m_jTowersIDs_Thin[ieta][iphi], m_jTowersIDs_Thin[ieta][iphi +1], m_jTowersIDs_Thin[ieta][iphi +2]},
-      {m_jTowersIDs_Thin[ieta -1][iphi -2], m_jTowersIDs_Thin[ieta -1][iphi -1], m_jTowersIDs_Thin[ieta -1][iphi], m_jTowersIDs_Thin[ieta -1][iphi +1], m_jTowersIDs_Thin[ieta -1][iphi +2]},
-      {m_jTowersIDs_Thin[ieta -2][iphi -2], m_jTowersIDs_Thin[ieta -2][iphi -1], m_jTowersIDs_Thin[ieta -2][iphi], m_jTowersIDs_Thin[ieta -2][iphi +1], m_jTowersIDs_Thin[ieta -2][iphi +2]}
+  if(sc_tobs == StatusCode::FAILURE) {
+    ATH_MSG_DEBUG("\n==== jFEXSmallRJetAlgo ======== Failed to find jFEXOutputCollection in jFEXFPGA");
+  }
+
+  int Jets_eta_limit = -99;
+  bool barrel_region = false;
  
-	};
+  if(m_jfexid > 0 && m_jfexid < 5){
+    Jets_eta_limit = FEXAlgoSpaceDefs::jFEX_thin_algoSpace_width -8;
 
-      
+    barrel_region = true;
+  //  return StatusCode::SUCCESS;
+  }
+
+  if(m_jfexid == 0 || m_jfexid == 5){
 
-      int largeETRing_IDs[15][15];
-      for(int i = -7; i< 8; i++ ){
-        for(int j = -7; j< 8; j++){
-          largeETRing_IDs[7 +i][7 +j] = m_jTowersIDs_Thin[ieta + i][iphi +j];
+    Jets_eta_limit = FEXAlgoSpaceDefs::jFEX_wide_algoSpace_width -8;
+    //return StatusCode::SUCCESS;
+  }
+
+  
+  for(int mphi = 8; mphi < 24; mphi++) {   
+    for(int meta = 8; meta < Jets_eta_limit; meta++) {
+
+
+    //create search window including towerIDs required for seeding.
+    int SRJet_SearchWindow[7][7] = {0};
+    for(int i = -3 ; i <4; i++){
+      for(int j = -3; j <4; j++){
+        if(barrel_region){SRJet_SearchWindow[3 + i][3 + j] = m_jTowersIDs_Thin[mphi + i][meta +j];}
+        else{SRJet_SearchWindow[3 + i][3 + j] = m_jTowersIDs_Wide[mphi + i][meta +j];}
+      }
+    }
+      int largeRCluster_IDs[15][15]= {0};
+      for(int i = -7; i< 8; i++ ) {
+        for(int j = -7; j< 8; j++) {
+          largeRCluster_IDs[7 +i][7 +j] = m_jTowersIDs_Thin[mphi + i][meta +j];
         }
       }
       //remove corners from large ET ring
-      for(int i =4; i <8; i++){
-        if( i != 7){
-          largeETRing_IDs[7 +i][14] = 0;
-          largeETRing_IDs[7 +i][0] = 0;
-          largeETRing_IDs[7 -i][14] = 0;
-          largeETRing_IDs[7 -i][0] = 0;
+      for(int i =4; i <8; i++) {
+        if( i != 7) {
+          largeRCluster_IDs[7 +i][14] = 0;
+          largeRCluster_IDs[7 +i][0] = 0;
+          largeRCluster_IDs[7 -i][14] = 0;
+          largeRCluster_IDs[7 -i][0] = 0;
         }
 
-        largeETRing_IDs[14][7 +i] = 0;
-        largeETRing_IDs[14][7 -i] = 0;
-        largeETRing_IDs[0][7 +i] = 0;
-        largeETRing_IDs[0][7 -i] = 0;
-        largeETRing_IDs[13][13] = 0;
-        largeETRing_IDs[1][1] = 0;
-        largeETRing_IDs[13][1] = 0;
-        largeETRing_IDs[1][13] = 0;       
+        largeRCluster_IDs[14][7 +i] = 0;
+        largeRCluster_IDs[14][7 -i] = 0;
+        largeRCluster_IDs[0][7 +i] = 0;
+        largeRCluster_IDs[0][7 -i] = 0;
+        largeRCluster_IDs[13][13] = 0;
+        largeRCluster_IDs[1][1] = 0;
+        largeRCluster_IDs[13][1] = 0;
+        largeRCluster_IDs[1][13] = 0;
       }
 
-      int smallRCluster_IDs[4][5];
-      for(int i =-2; i< 2; i++){
-        smallRCluster_IDs[i +2][0] = m_jTowersIDs_Thin[ieta +i][iphi +3];
-        smallRCluster_IDs[i +2][1] = m_jTowersIDs_Thin[ieta +i][iphi -3];  
-        smallRCluster_IDs[i +2][2] = m_jTowersIDs_Thin[ieta +3][iphi +i];
-        smallRCluster_IDs[i +2][3] = m_jTowersIDs_Thin[ieta -3][iphi +i];
-      }
-
-       //this prevents adding ET from small RT ring
-      for(int i = -3; i< 4; i++){
-        for(int j = -3; j<4 ; j++){
-          if(!(i == 3 && j == -3) || !(i == -3 && j == 3) || !(i == 3 && j == 3) || !(i == -3 && j == -3)){
-            largeETRing_IDs[7 +i][7 +j] = 0; 
+      //this prevents adding ET from small RT ring
+      for(int i = -3; i< 4; i++) {
+        for(int j = -3; j<4 ; j++) {
+          if(!(i == 3 && j == -3) || !(i == -3 && j == 3) || !(i == 3 && j == 3) || !(i == -3 && j == -3)) {
+            largeRCluster_IDs[7 +i][7 +j] = 0;
           }
         }
-      }    
-      
-      ATH_CHECK( m_jFEXSmallRJetAlgoTool.retrieve()); 
-      ATH_CHECK( m_jFEXSmallRJetAlgoTool->safetyTest());
-      m_jFEXSmallRJetAlgoTool->setup(tobtable); 
-      m_jFEXSmallRJetAlgoTool->setupCluster(smallRCluster_IDs);
-      m_jFEXLargeRJetAlgoTool->setupCluster(largeETRing_IDs);      
+      }
+
+
+      m_jFEXSmallRJetAlgoTool->setup(SRJet_SearchWindow, barrel_region);
+      m_jFEXLargeRJetAlgoTool->setupCluster(largeRCluster_IDs);
+
 
       //These are plots of the central TT for each 5x5 search window.
       jFEXOutputs->addValue_smallRJet("smallRJet_ET", m_jFEXSmallRJetAlgoTool->getTTowerET());
-      jFEXOutputs->addValue_smallRJet("smallRJet_phi",m_jFEXSmallRJetAlgoTool->getRealPhi()/10.) ;
-      jFEXOutputs->addValue_smallRJet("smallRJet_eta",m_jFEXSmallRJetAlgoTool->getRealEta()/10.) ;     
+      jFEXOutputs->addValue_smallRJet("smallRJet_phi",m_jFEXSmallRJetAlgoTool->getRealPhi()) ;
+      jFEXOutputs->addValue_smallRJet("smallRJet_eta",m_jFEXSmallRJetAlgoTool->getRealEta()) ;
 
       m_jFEXSmallRJetAlgoTool->buildSeeds();
       bool SRJet_LM = m_jFEXSmallRJetAlgoTool->isSeedLocalMaxima();
-      jFEXOutputs->addValue_smallRJet("smallRJet_isCentralTowerSeed", SRJet_LM); 
+      jFEXOutputs->addValue_smallRJet("smallRJet_isCentralTowerSeed",  SRJet_LM);
 
-      if(!SRJet_LM){continue;} //skip below if not LM
+      std::unique_ptr<jFEXSmallRJetTOB> tmp_tob = m_jFEXSmallRJetAlgoTool->getSmallRJetTOBs();
 
-      std::unique_ptr<jFEXSmallRJetTOB> tmp_SRJet_tob = m_jFEXSmallRJetAlgoTool->getSmallRJetTOBs();
-         
-      bool TOB_saturated = false;
+      uint32_t tobword = formSmallRJetTOB(mphi, meta);
+      if ( tobword != 0 ) m_SRJet_tobwords.push_back(tobword);
+
+      //bool TOB_saturated = false;
       int smallClusterET = m_jFEXSmallRJetAlgoTool->getSmallClusterET();
-      if (smallClusterET/200. > 11) TOB_saturated = true;
-      
+      //if (smallClusterET/200. > 0x7ff){ATH_MSG_DEBUG("SRJet TOB is saturated"); TOB_saturated = true;}
+
       // for plotting variables in TOBS- internal check:
-      jFEXOutputs->addValue_smallRJet("smallRJetTOB_eta", tmp_SRJet_tob->setEta(ieta));
-      jFEXOutputs->addValue_smallRJet("smallRJetTOB_phi", tmp_SRJet_tob->setPhi(iphi));
-      jFEXOutputs->addValue_smallRJet("smallRJetTOB_ET", smallClusterET);    
-      jFEXOutputs->addValue_smallRJet("smallRJetTOB_sat", TOB_saturated);  
-
-      uint32_t SRJet_tobword = formSmallRJetTOB(ieta, iphi);
-      if ( SRJet_tobword != 0 ) m_SRJet_tobwords.push_back(SRJet_tobword);
-          
-      jFEXOutputs->fill_smallRJet();  
-
-      ATH_MSG_DEBUG("==== jFEXLargeRJetAlgo ========"); 
-      //LargeRJetAlgo is here as SmallRJetlocalMaxima is a requirement
-      unsigned int largeClusterET = m_jFEXLargeRJetAlgoTool->getLargeClusterET(m_jFEXSmallRJetAlgoTool->getSmallClusterET(),m_jFEXLargeRJetAlgoTool->getRingET());
-      ATH_MSG_DEBUG("jFEXFPGA: large RJet algo, check large cluster ET: "<< largeClusterET); 
-      jFEXOutputs->addValue_largeRJet("largeRJet_ET", largeClusterET);
-
-      std::unique_ptr<jFEXLargeRJetTOB> tmp_LRJet_tob = m_jFEXLargeRJetAlgoTool->getLargeRJetTOBs();
-
-      jFEXOutputs->addValue_largeRJet("largeRJetTOB_ET", largeClusterET);
-      jFEXOutputs->addValue_largeRJet("largeRJetTOB_phi", tmp_LRJet_tob->setPhi(iphi));
-      jFEXOutputs->addValue_largeRJet("largeRJetTOB_eta", tmp_LRJet_tob->setEta(ieta));
-  
-      uint32_t LRJet_tobword = formLargeRJetTOB(ieta, iphi);
-      if ( LRJet_tobword != 0 ) m_LRJet_tobwords.push_back(LRJet_tobword);
+      jFEXOutputs->addValue_smallRJet("smallRJetTOB_eta",tmp_tob->setEta(meta));
+      jFEXOutputs->addValue_smallRJet("smallRJetTOB_phi",tmp_tob->setPhi(mphi));
+      jFEXOutputs->addValue_smallRJet("smallRJetTOB_ET",smallClusterET);
+      jFEXOutputs->fill_smallRJet();
+
+      if(!SRJet_LM) {
+        continue;
+      }
+
+      if(SRJet_LM){
+        //LargeRJetAlgo is here as SmallRJetlocalMaxima is a requirement
+        unsigned int largeClusterET = m_jFEXLargeRJetAlgoTool->getLargeClusterET(m_jFEXSmallRJetAlgoTool->getSmallClusterET(),m_jFEXLargeRJetAlgoTool->getRingET());
+        jFEXOutputs->addValue_largeRJet("largeRJet_ET", largeClusterET);
+
+        std::unique_ptr<jFEXLargeRJetTOB> tmp_tob = m_jFEXLargeRJetAlgoTool->getLargeRJetTOBs();
+
+        jFEXOutputs->addValue_largeRJet("largeRJetTOB_ET", largeClusterET);
+        jFEXOutputs->addValue_largeRJet("largeRJetTOB_phi", tmp_tob->setPhi(meta));
+        jFEXOutputs->addValue_largeRJet("largeRJetTOB_eta", tmp_tob->setEta(mphi));
+
+        uint32_t tobword = formLargeRJetTOB(mphi, meta);
+        if ( tobword != 0 ) m_LRJet_tobwords.push_back(tobword);
+
+
+        jFEXOutputs->fill_largeRJet();
+      }
+
+    }
+  }
+
+
+//******************************** TAU **********************************************
+
 
-      jFEXOutputs->fill_largeRJet();
-          
-    }//iphi loop
-  }//end of ieta loop
+  memset(m_jTowersIDs, 0, sizeof(m_jTowersIDs[0][0]) * FEXAlgoSpaceDefs::jFEX_algoSpace_height*FEXAlgoSpaceDefs::jFEX_thin_algoSpace_width); // Reseting m_jTowersIDs array with 0
 
+  int max_meta=16;
+  if(m_jfexid ==0){
+    for(int i=0;i<FEXAlgoSpaceDefs::jFEX_algoSpace_height;i++){
+      for(int j=0;j<FEXAlgoSpaceDefs::jFEX_wide_algoSpace_width;j++){
+        if(j==17){
+          break;
+        }
+        m_jTowersIDs[i][j]=m_jTowersIDs_Wide[i][j];
+      }
+    }
+    
     return StatusCode::SUCCESS;
-} //end of the execute function 
+    
+  } 
+  else if(m_jfexid ==5 ){ 
+
+    // Filling m_jTowersIDs with the m_jTowersIDs_Wide ID values up to 2.5 eta 
+    for(int i=0;i<FEXAlgoSpaceDefs::jFEX_algoSpace_height;i++){
+      for(int j=0;j<FEXAlgoSpaceDefs::jFEX_wide_algoSpace_width;j++){
+        if(j==17){
+          break;
+        }
+        m_jTowersIDs[i][j]=m_jTowersIDs_Wide[i][j];
+      }
+    }
 
-  void jFEXFPGA::SetTowersAndCells_SG(int tmp_jTowersIDs_subset[][FEXAlgoSpaceDefs::jFEX_wide_algoSpace_width]){
+    max_meta++; // increase max of eta because te core module has one more TT to be considered
+  }
+  else{
+    //For Module 1,2,3,4 (central modules) the m_jTowersIDs array is m_jTowersIDs_Thin
+    std::copy(&m_jTowersIDs_Thin[0][0], &m_jTowersIDs_Thin[0][0] + FEXAlgoSpaceDefs::jFEX_algoSpace_height*FEXAlgoSpaceDefs::jFEX_thin_algoSpace_width, &m_jTowersIDs[0][0]);
+  }
+    
+  ATH_MSG_DEBUG("============================ jFEXtauAlgo ============================");
+  for(int mphi = 8; mphi < 24; mphi++) {   
+    for(int meta = 8; meta < max_meta; meta++) {    
+
+      int TT_seed_ID[3][3]={0};
+      int TT_searchWindow_ID[5][5]={0};
+      int TT_First_ETring[36]={0};
+      int First_ETring_it = 0;
+      
+      for(int i = -3; i< 4; i++ ) {
+          for(int j = -3; j< 4; j++) {
+              if(sqrt(pow(i,2)+pow(j,2))<3){
+                TT_searchWindow_ID[i+2][j+2] = m_jTowersIDs[mphi +i][meta +j]; // Search window for the tau algo used for the LocalMaxima studies
+              }
+              
+              if(sqrt(pow(i,2)+pow(j,2))<2){
+                  TT_seed_ID[i+1][j+1] = m_jTowersIDs[mphi +i][meta +j]; // Seed 0.3x0.3 in phi-eta plane
+              }
+              else if(sqrt(pow(i,2)+pow(j,2))<4){
+                TT_First_ETring[First_ETring_it]= m_jTowersIDs[mphi +i][meta +j]; // First energy ring, will be used as tau ISO
+                ++First_ETring_it;
+                
+              } 
+          }
+      }
+
+      
+
+      ATH_CHECK( m_jFEXSmallRJetAlgoTool.retrieve());
+      ATH_CHECK( m_jFEXSmallRJetAlgoTool->safetyTest());
+
+      ATH_CHECK( m_jFEXtauAlgoTool.retrieve());
+      ATH_CHECK( m_jFEXtauAlgoTool->safetyTest());
+      m_jFEXtauAlgoTool->setup(TT_searchWindow_ID,TT_seed_ID);
+      m_jFEXtauAlgoTool->buildSeeds();
+      //bool is_tau_LocalMax = m_jFEXtauAlgoTool->isSeedLocalMaxima();
+      m_jFEXtauAlgoTool->isSeedLocalMaxima();
+      m_jFEXtauAlgoTool->setFirstEtRing(TT_First_ETring);
+
+
+      jFEXOutputs->addValue_tau("tau_ET", m_jFEXtauAlgoTool->getTTowerET());
+      jFEXOutputs->addValue_tau("tau_clusterET", m_jFEXtauAlgoTool->getClusterEt());
+      jFEXOutputs->addValue_tau("tau_eta",abs(m_jFEXtauAlgoTool->getRealEta())) ;
+      jFEXOutputs->addValue_tau("tau_phi",m_jFEXtauAlgoTool->getRealPhi()) ;
+      jFEXOutputs->addValue_tau("tau_realeta",m_jFEXtauAlgoTool->getRealEta()) ;
+      jFEXOutputs->addValue_tau("tau_ISO",m_jFEXtauAlgoTool->getFirstEtRing()) ;
+      jFEXOutputs->addValue_tau("tau_TT_ID",TT_seed_ID[1][1]) ;
+      jFEXOutputs->addValue_tau("tau_isLocalMax",m_jFEXtauAlgoTool->getIsLocalMaxima()) ;
+      jFEXOutputs->addValue_tau("tau_jFEXid",m_jfexid) ;
+      jFEXOutputs->addValue_tau("tau_FPGAid",m_id) ;
+    
+      uint32_t tobword = formTauTOB(mphi, meta);
+      if ( tobword != 0 ){
+        m_tau_tobwords.push_back(tobword);
+      }
+    
+      std::unique_ptr<jFEXtauTOB> tmp_tob = m_jFEXtauAlgoTool->getTauTOBs(mphi, meta);
+      // for plotting variables in TOBS- internal check:
+      jFEXOutputs->addValue_tau("tau_TOB_word" ,tobword);
+      jFEXOutputs->addValue_tau("tau_TOB_ET" ,tmp_tob->GetET());
+      jFEXOutputs->addValue_tau("tau_TOB_eta",tmp_tob->GetEta());
+      jFEXOutputs->addValue_tau("tau_TOB_phi",tmp_tob->GetPhi());
+      jFEXOutputs->addValue_tau("tau_TOB_ISO" ,tmp_tob->GetIso());
+      jFEXOutputs->addValue_tau("tau_TOB_Sat" ,tmp_tob->GetSat());        
+        
+      jFEXOutputs->fill_tau();
+
+    }
+  }
+
+  return StatusCode::SUCCESS;
+} //end of the execute function
+
+void jFEXFPGA::SetTowersAndCells_SG(int tmp_jTowersIDs_subset[][FEXAlgoSpaceDefs::jFEX_wide_algoSpace_width]){
     
   const int rows = FEXAlgoSpaceDefs::jFEX_algoSpace_height;
   const int cols = sizeof tmp_jTowersIDs_subset[0] / sizeof tmp_jTowersIDs_subset[0][0];
@@ -275,7 +393,7 @@ std::vector <uint32_t> jFEXFPGA::getLargeRJetTOBs()
 
 
 
-uint32_t jFEXFPGA::formSmallRJetTOB(int & ieta, int & iphi)  
+uint32_t jFEXFPGA::formSmallRJetTOB(int & iphi, int &ieta )  
 {
   uint32_t tobWord = 0;
   const unsigned int jFEXETResolution = 200; //LSB is 200MeV
@@ -304,7 +422,7 @@ uint32_t jFEXFPGA::formSmallRJetTOB(int & ieta, int & iphi)
   else return tobWord;
 }
 
-uint32_t jFEXFPGA::formLargeRJetTOB(int & ieta, int & iphi)
+uint32_t jFEXFPGA::formLargeRJetTOB(int & iphi, int &ieta )
 {
   uint32_t tobWord = 0;
   const unsigned int jFEXETResolution = 200; //LSB is 200MeV
@@ -312,18 +430,18 @@ uint32_t jFEXFPGA::formLargeRJetTOB(int & ieta, int & iphi)
   unsigned int et = m_jFEXLargeRJetAlgoTool->getLargeClusterET(m_jFEXSmallRJetAlgoTool->getSmallClusterET(),m_jFEXLargeRJetAlgoTool->getRingET());
   unsigned int jFEXLargeRJetTOBEt = et/jFEXETResolution;
 
-  if (jFEXLargeRJetTOBEt > 0x1fff) jFEXLargeRJetTOBEt = 0x1fff;  //0x1fff is 13 bits
+
 
   int eta = ieta;
   int phi = iphi;
   int Sub = 0; //9 bits reserved
-  int Sat = 0; //1 bit for saturation flag, not coded yet
- 
+  int Sat = 1; //1 bit for saturation flag, not coded yet
+
   if (jFEXLargeRJetTOBEt > 0x1fff){
-    jFEXLargeRJetTOBEt = 0x1fff;//0x1fff is 12 bits
+    jFEXLargeRJetTOBEt = 0x1fff;  //0x1fff is 13 bits
     Sat = 1;
-  }
-
+  } 
+  
   //create basic tobword with 32 bits
   tobWord = tobWord + jFEXLargeRJetTOBEt + (phi << 13) + (eta << 17) + (Sub << 22) + (Sat << 31);
 
@@ -336,6 +454,61 @@ uint32_t jFEXFPGA::formLargeRJetTOB(int & ieta, int & iphi)
 }
 
 
+uint32_t jFEXFPGA::formTauTOB(int & iphi, int &ieta )
+{
+  uint32_t tobWord = 0;
+  const unsigned int jFEXETResolution = 200; //LSB is 200MeV
+
+  int eta = ieta-8; // needed to substract 8 to be in the FPGA core area
+  int phi = iphi-8; // needed to substract 8 to be in the FPGA core area
+  int sat = 0; //1 bit for saturation flag, not coded yet
+
+  unsigned int et = m_jFEXtauAlgoTool->getClusterEt()/jFEXETResolution;
+  if (et > 0x7ff) { //0x7ff is 11 bits
+    ATH_MSG_DEBUG("Et saturated: " << et );
+    et = 0x7ff;
+    sat=1;
+  }
+
+
+
+  unsigned int iso = m_jFEXtauAlgoTool->getFirstEtRing()/jFEXETResolution;
+  if (iso > 0x7ff) iso = 0x7ff;  //0x7ff is 11 bits
+
+  
+  //create basic tobword with 32 bits
+  tobWord = tobWord + (eta << 27) + (phi << 23) + (et << 12) + (iso << 1) + sat ;
+  
+  ATH_MSG_DEBUG("tobword tau with eta, phi, et, iso and sat : " << std::bitset<32>(tobWord) );
+
+  //arbitary et threshold to not overflow the TOBs
+
+  unsigned int minEtThreshold = 30;
+  if (et < minEtThreshold) return 0;
+  else return tobWord;
+
+}
+
+
+std::vector <uint32_t> jFEXFPGA::getTauTOBs()
+{
+  auto tobsSort = m_tau_tobwords;
+
+  ATH_MSG_DEBUG("number of tau tobs: " << tobsSort.size() << " in FPGA: " << m_id<< " before truncation");
+  // sort tobs by their et ( 13 bits of the 32 bit tob word)
+  std::sort (tobsSort.begin(), tobsSort.end(), etTauSort);
+  tobsSort.resize(6);
+  return tobsSort;
+
+}
+
+
+
+
+
+
+
+
   
 } // end of namespace bracket
 
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXNtupleWriter.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXNtupleWriter.cxx
index b0dc890710d..14c233cdeab 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXNtupleWriter.cxx
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXNtupleWriter.cxx
@@ -59,7 +59,7 @@ StatusCode LVL1::jFEXNtupleWriter::initialize () {
   m_myTree->Branch ("smallRJet_eta",  &m_smallRJet_eta);
   m_myTree->Branch ("smallRJet_phi",  &m_smallRJet_phi);
   m_myTree->Branch ("smallRJet_ET",  &m_smallRJet_ET);
-  m_myTree->Branch("smallRJet", &m_smallRJet_Sat);
+  m_myTree->Branch ("smallRJet", &m_smallRJet_Sat);
   m_myTree->Branch ("smallRJet_nTOBs",  &m_smallRJet_nTOBs, "nTOBs");
   m_myTree->Branch ("smallRJet_isCentralTowerSeed",  &m_smallRJet_isCentralTowerSeed);
   
@@ -75,6 +75,29 @@ StatusCode LVL1::jFEXNtupleWriter::initialize () {
   m_myTree->Branch ("largeRJetTOB_phi", &m_largeRJetTOB_phi);
   m_myTree->Branch ("largeRJetTOB_ET", &m_largeRJetTOB_ET);
 
+  
+  m_myTree->Branch ("tau_TT_ID" ,  &m_tau_TT_ID);
+  m_myTree->Branch ("tau_isLocalMax" ,  &m_tau_isLocalMax);
+  m_myTree->Branch ("tau_ET" ,  &m_tau_ET);
+  m_myTree->Branch ("tau_clusterET" ,  &m_tau_clusterET);
+  m_myTree->Branch ("tau_eta",  &m_tau_eta);
+  m_myTree->Branch ("tau_phi",  &m_tau_phi);
+  m_myTree->Branch ("tau_realeta",  &m_tau_realeta);
+  m_myTree->Branch ("tau_ISO",  &m_tau_ISO);
+  m_myTree->Branch ("tau_jFEXid",  &m_tau_jFEXid);
+  m_myTree->Branch ("tau_FPGAid",  &m_tau_FPGAid);
+
+  m_myTree->Branch ("tau_TOB_word",  &m_tau_TOB_word);
+  m_myTree->Branch ("tau_TOB_ET",  &m_tau_TOB_ET);
+  m_myTree->Branch ("tau_TOB_eta",  &m_tau_TOB_eta);
+  m_myTree->Branch ("tau_TOB_phi",  &m_tau_TOB_phi);
+  m_myTree->Branch ("tau_TOB_ISO",  &m_tau_TOB_ISO);
+  m_myTree->Branch ("tau_TOB_Sat",  &m_tau_TOB_Sat);
+
+
+
+  
+
   return StatusCode::SUCCESS;
 }
 
@@ -91,6 +114,7 @@ StatusCode LVL1::jFEXNtupleWriter::execute () {
 
   CHECK(loadsmallRJetAlgoVariables());
   CHECK(loadlargeRJetAlgoVariables());
+  CHECK(loadtauAlgoVariables());
 //CHECK()
 
 
@@ -152,6 +176,53 @@ StatusCode LVL1::jFEXNtupleWriter::loadlargeRJetAlgoVariables() {
   return StatusCode::SUCCESS;
 }
 
+StatusCode LVL1::jFEXNtupleWriter::loadtauAlgoVariables() {
+
+  m_tau_TT_ID.clear();
+  m_tau_jFEXid.clear();
+  m_tau_FPGAid.clear();
+  m_tau_isLocalMax.clear();
+  m_tau_ET.clear();
+  m_tau_clusterET.clear();
+  m_tau_eta.clear();
+  m_tau_phi.clear();
+  m_tau_realeta.clear();
+  m_tau_ISO.clear();
+
+  m_tau_TOB_word.clear();
+  m_tau_TOB_ET.clear();
+  m_tau_TOB_eta.clear();
+  m_tau_TOB_phi.clear();
+  m_tau_TOB_ISO.clear();
+  m_tau_TOB_Sat.clear();
+
+  
+  for (int i = 0; i < m_jFEXOutputCollection->tausize(); i++)
+  {
+    m_tau_isLocalMax.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_isLocalMax"]);
+    m_tau_TT_ID.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_TT_ID"]);
+    m_tau_jFEXid.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_jFEXid"]);
+    m_tau_FPGAid.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_FPGAid"]);
+    m_tau_ET.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_ET"]);
+    m_tau_clusterET.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_clusterET"]);
+    m_tau_eta.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_eta"]); 
+    m_tau_phi.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_phi"]);
+    m_tau_realeta.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_realeta"]);
+    m_tau_ISO.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_ISO"]);
+
+
+    
+    m_tau_TOB_word.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_TOB_word"]);
+    m_tau_TOB_ET.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_TOB_ET"]);
+    m_tau_TOB_eta.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_TOB_eta"]);
+    m_tau_TOB_phi.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_TOB_phi"]);
+    m_tau_TOB_ISO.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_TOB_ISO"]);
+    m_tau_TOB_Sat.push_back((*(m_jFEXOutputCollection->get_tau(i)))["tau_TOB_Sat"]);
+
+  }
+  return StatusCode::SUCCESS;
+}
+
 
 
 
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXOutputCollection.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXOutputCollection.cxx
index dad9c378eaf..991496c080f 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXOutputCollection.cxx
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXOutputCollection.cxx
@@ -20,6 +20,11 @@ LVL1::jFEXOutputCollection::~jFEXOutputCollection()
  for(auto iValues: m_allvalues_largeRJet){
    delete iValues;
   }
+  
+ for(auto iValues: m_allvalues_tau){
+   delete iValues;
+  }
+  
 }
 
 void LVL1::jFEXOutputCollection::clear() 
@@ -30,6 +35,9 @@ void LVL1::jFEXOutputCollection::clear()
   for(auto iValues : m_allvalues_largeRJet){
     iValues->clear();
   }
+  for(auto iValues : m_allvalues_tau){
+    iValues->clear();
+  }
 }
 
 void LVL1::jFEXOutputCollection::addValue_smallRJet(std::string key, float value)
@@ -42,6 +50,11 @@ void LVL1::jFEXOutputCollection::addValue_largeRJet(std::string key, float value
  m_values_tem_largeRJet.insert(std::make_pair(key, value));
 }
 
+void LVL1::jFEXOutputCollection::addValue_tau(std::string key, int value)
+{
+ m_values_tem_tau.insert(std::make_pair(key, value));
+}
+
 void LVL1::jFEXOutputCollection::fill_smallRJet()
 {
   std::map<std::string, float>* values_local = new std::map<std::string, float>(m_values_tem_smallRJet);
@@ -56,6 +69,13 @@ void LVL1::jFEXOutputCollection::fill_largeRJet()
   m_values_tem_largeRJet.clear();
 
 }
+void LVL1::jFEXOutputCollection::fill_tau()
+{
+  std::map<std::string, int>* values_local = new std::map<std::string, int>(m_values_tem_tau);
+  m_allvalues_tau.push_back(values_local);
+  m_values_tem_tau.clear();
+
+}
 
 
 int LVL1::jFEXOutputCollection::size()
@@ -63,6 +83,11 @@ int LVL1::jFEXOutputCollection::size()
   return m_allvalues_smallRJet.size();
 }
 
+int LVL1::jFEXOutputCollection::tausize()
+{
+  return m_allvalues_tau.size();
+}
+
 std::map<std::string, float>* LVL1::jFEXOutputCollection::get_smallRJet(int location)
 {
   return m_allvalues_smallRJet[location];
@@ -71,3 +96,7 @@ std::map<std::string, float>* LVL1::jFEXOutputCollection::get_largeRJet(int loca
 {
   return m_allvalues_smallRJet[location];
 }
+std::map<std::string, int>* LVL1::jFEXOutputCollection::get_tau(int location)
+{
+  return m_allvalues_tau[location];
+}
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXSmallRJetAlgo.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXSmallRJetAlgo.cxx
index 32c881f63ca..16ae5792de5 100644
--- a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXSmallRJetAlgo.cxx
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXSmallRJetAlgo.cxx
@@ -54,9 +54,11 @@ StatusCode LVL1::jFEXSmallRJetAlgo::safetyTest(){
   return StatusCode::SUCCESS;
 }
 
-void LVL1::jFEXSmallRJetAlgo::setup(int inputTable[5][5]) {
+void LVL1::jFEXSmallRJetAlgo::setup(int inputTable[7][7], bool barrel_region) {
 
-  std::copy(&inputTable[0][0], &inputTable[0][0] + 25, &m_jFEXalgoTowerID[0][0]);
+  std::copy(&inputTable[0][0], &inputTable[0][0] + 49, &m_jFEXalgoTowerID[0][0]);
+
+  m_barrel_region = barrel_region;
 
 }
  
@@ -64,7 +66,7 @@ void LVL1::jFEXSmallRJetAlgo::setup(int inputTable[5][5]) {
 unsigned int LVL1::jFEXSmallRJetAlgo::getTTowerET(){
  SG::ReadHandle<jTowerContainer> jk_jFEXSmallRJetAlgo_jTowerContainer(m_jFEXSmallRJetAlgo_jTowerContainerKey/*,ctx*/);
 
- const LVL1::jTower * tmpTower = jk_jFEXSmallRJetAlgo_jTowerContainer->findTower(m_jFEXalgoTowerID[2][2]);
+ const LVL1::jTower * tmpTower = jk_jFEXSmallRJetAlgo_jTowerContainer->findTower(m_jFEXalgoTowerID[3][3]);
  unsigned int et = tmpTower->getTotalET();  
  return et;
 }
@@ -73,7 +75,7 @@ unsigned int LVL1::jFEXSmallRJetAlgo::getRealPhi() {
 
   SG::ReadHandle<jTowerContainer> jk_jFEXSmallRJetAlgo_jTowerContainer(m_jFEXSmallRJetAlgo_jTowerContainerKey/*,ctx*/);
   
-  unsigned int phi = jk_jFEXSmallRJetAlgo_jTowerContainer->findTower(m_jFEXalgoTowerID[2][2])->phi();
+  unsigned int phi = jk_jFEXSmallRJetAlgo_jTowerContainer->findTower(m_jFEXalgoTowerID[3][3])->phi();
   return phi;
 }
 //Gets Eta of the TT
@@ -81,33 +83,35 @@ unsigned int LVL1::jFEXSmallRJetAlgo::getRealEta() {
 
   SG::ReadHandle<jTowerContainer> jk_jFEXSmallRJetAlgo_jTowerContainer(m_jFEXSmallRJetAlgo_jTowerContainerKey/*,ctx*/);
 
-  unsigned int eta = jk_jFEXSmallRJetAlgo_jTowerContainer->findTower(m_jFEXalgoTowerID[2][2])->eta();
+  unsigned int eta = jk_jFEXSmallRJetAlgo_jTowerContainer->findTower(m_jFEXalgoTowerID[3][3])->eta();
   return eta;
 }
 //this function calculates seed for a given TT
 void LVL1::jFEXSmallRJetAlgo::buildSeeds()
 {
-  ATH_MSG_DEBUG("--------jFEXSmallRJetAlgo::buildsSeeds ----------------");
+
   m_seedSet = false;
   SG::ReadHandle<jTowerContainer> jk_jFEXSmallRJetAlgo_jTowerContainer(m_jFEXSmallRJetAlgo_jTowerContainerKey);
 
-  for(int mphi = 0; mphi < 5; mphi++){
-    for(int meta = 0; meta<5; meta++){
+  for(int mphi = 1; mphi < 6; mphi++){
+    for(int meta = 1; meta< 6; meta++){
       int et_tmp = 0;
-      int seedTotalET = 0;
-  
+      int seedTotalET = 0;  
       for(int ieta = -1; ieta < 2; ieta++){
         for(int iphi = -1; iphi < 2; iphi++){
           const LVL1::jTower * tmpTower = jk_jFEXSmallRJetAlgo_jTowerContainer->findTower(m_jFEXalgoTowerID[meta + ieta][mphi + iphi]);
-
-         //seed calculation	    	
-	  et_tmp = tmpTower->getTotalET();  
+          //for that TT, build the seed
+          //here we sum TT ET to calculate seed	    	
+	        et_tmp = tmpTower->getTotalET();  //in the fcal it already only considers the EM layer as the hcal layer 1 and 2 are considered seperate jTower Objects
           seedTotalET += et_tmp;
        	  }
     	}
-   	m_jFEXalgoSearchWindowSeedET[meta][mphi] = seedTotalET;
+   	m_jFEXalgoSearchWindowSeedET[meta -1][mphi -1] = seedTotalET;
       	}
+
      }    
+
+
     m_seedSet = true;
 }
 
@@ -116,26 +120,29 @@ void LVL1::jFEXSmallRJetAlgo::buildSeeds()
 bool LVL1::jFEXSmallRJetAlgo::isSeedLocalMaxima()
 {
   if(m_seedSet == false){
-    ATH_MSG_DEBUG("Local Maxima not checked due to seed not calculated.");
+    //ATH_MSG_DEBUG("Local Maxima not checked due to seed not calculated.");
   }
   if(m_seedSet == true){
-    //here put the 24 conditions to determine if the [2][2] TT seed is a local maxima.
-    int central_seed = m_jFEXalgoSearchWindowSeedET[2][2];
-    for (int ieta = 0; ieta < 5; ieta++){
-      for (int iphi = 0; iphi < 5; iphi++){
+
+    //ATH_MSG_DEBUG("Local Maxima checking begins.");
+    //here put the 24 conditions to determine if the [3][3] TT seed is a local maxima.
+
+    int central_seed = m_jFEXalgoSearchWindowSeedET[3][3];
+    for (int ieta = 1; ieta < 6; ieta++){
+      for (int iphi = 1; iphi < 6; iphi++){
 
         //avoid comparing central seed to itself  
- 	if ((ieta == 2) && (iphi == 2)){
+ 	if ((ieta == 3) && (iphi == 3)){
           continue;
       	}
         //strictly less than central
-	if( (iphi >= ieta) && !(ieta == 3 && iphi == 3) && !(ieta == 4 && iphi == 4) ){
+	if( (iphi >= ieta) && !(ieta == 4 && iphi == 4) && !(ieta == 5 && iphi == 5) ){
 	  if(central_seed<m_jFEXalgoSearchWindowSeedET[ieta][iphi]){
 	    return false;
 	  }  
 	}	
 	//less than or equal to central 
-	if((ieta > iphi) || (ieta == 3 && iphi == 3) || (ieta == 4 && iphi == 4)){
+	if((ieta > iphi) || (ieta == 4 && iphi == 4) || (ieta == 5 && iphi == 5)){
           if(central_seed<= m_jFEXalgoSearchWindowSeedET[ieta][iphi]){
 	    return false;
 	    }	
@@ -143,17 +150,10 @@ bool LVL1::jFEXSmallRJetAlgo::isSeedLocalMaxima()
        }
      }
   }  
-  return true;
-}
-
-void LVL1::jFEXSmallRJetAlgo::setupCluster(int inputTable[4][5]) {
-
-  std::copy(&inputTable[0][0], &inputTable[0][0] + 20, &m_smallRJetClusterIDs[0][0]);
 
+  return true;
 }
 
-
-
 //in this clustering func, the central TT in jet is the parameters
 unsigned int LVL1::jFEXSmallRJetAlgo::getSmallClusterET(){
 
@@ -161,25 +161,34 @@ unsigned int LVL1::jFEXSmallRJetAlgo::getSmallClusterET(){
 
   //first summing search window (25 TTs)
   unsigned int searchWindowET = 0;
-  for(int neta = 0; neta< 5; neta++){ 
-    for(int nphi = 0; nphi< 5; nphi++){
+  for(int neta = 0; neta< 7; neta++){ 
+    for(int nphi = 0; nphi< 7; nphi++){
       const LVL1::jTower * tmpTower = jk_jFEXSmallRJetAlgo_jTowerContainer->findTower(m_jFEXalgoTowerID[neta][nphi]);
       searchWindowET += tmpTower->getTotalET();
     }
   } 
 
-  //secondly summing over energy ring ET (20 TTs)
-  unsigned int clusterBoarderET = 0;
-  for(int n = 0; n< 4; n++){
-    for(int m = 0; m< 5; m++){
+  //corners removed in 7x7 window to obtain SmallRJetCluser ET;
+  int cornersET = 0;  
 
-      const LVL1::jTower * tmpTower = jk_jFEXSmallRJetAlgo_jTowerContainer->findTower(m_smallRJetClusterIDs[n][m]);
-      clusterBoarderET += tmpTower->getTotalET();
-    }
-  }
+  const LVL1::jTower * tmpTower_a = jk_jFEXSmallRJetAlgo_jTowerContainer->findTower(m_jFEXalgoTowerID[0][0]);
+  cornersET += tmpTower_a->getTotalET();
+  const LVL1::jTower * tmpTower_b = jk_jFEXSmallRJetAlgo_jTowerContainer->findTower(m_jFEXalgoTowerID[6][6]);
+  cornersET += tmpTower_b->getTotalET(); 
+  const LVL1::jTower * tmpTower_c = jk_jFEXSmallRJetAlgo_jTowerContainer->findTower(m_jFEXalgoTowerID[0][6]);
+  cornersET += tmpTower_c->getTotalET();
+  const LVL1::jTower * tmpTower_d = jk_jFEXSmallRJetAlgo_jTowerContainer->findTower(m_jFEXalgoTowerID[6][0]);
+  cornersET += tmpTower_d->getTotalET();
+
+  //SR Jet Energy cluster
+  int SRJetClusterET = searchWindowET = cornersET;
 
- int smallRclusterET = searchWindowET + clusterBoarderET;
- return smallRclusterET;
+  return SRJetClusterET;
+}
+
+unsigned int LVL1::jFEXSmallRJetAlgo::getSmallETRing(){
+  int SmallETRing = getSmallClusterET() - m_jFEXalgoSearchWindowSeedET[3][3];   
+  return SmallETRing;
 }
          
 std::unique_ptr<jFEXSmallRJetTOB> LVL1::jFEXSmallRJetAlgo::getSmallRJetTOBs(){
@@ -200,3 +209,4 @@ std::unique_ptr<jFEXSmallRJetTOB> LVL1::jFEXSmallRJetAlgo::getSmallRJetTOBs(){
 
 
 }// end of namespace LVL1
+
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXtauAlgo.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXtauAlgo.cxx
new file mode 100644
index 00000000000..b486718f74b
--- /dev/null
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXtauAlgo.cxx
@@ -0,0 +1,280 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration  
+*/
+//***************************************************************************  
+//		jFEXtauAlgo - Algorithm for Tau Algorithm in jFEX
+//                              -------------------
+//     begin                : 18 02 2021
+//     email                : Sergi.Rodriguez@cern.ch
+//***************************************************************************
+#include <iostream>
+#include <vector>
+#include <stdio.h>
+#include <math.h>
+#include "L1CaloFEXSim/jFEXtauAlgo.h"
+#include "L1CaloFEXSim/jFEXtauTOB.h"
+#include "L1CaloFEXSim/jTower.h"
+#include "L1CaloFEXSim/jTowerContainer.h"
+#include "CaloEvent/CaloCellContainer.h"
+#include "CaloIdentifier/CaloIdManager.h"
+#include "CaloIdentifier/CaloCell_SuperCell_ID.h"
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "StoreGate/StoreGateSvc.h"
+
+namespace LVL1{
+
+//Default Constructor
+LVL1::jFEXtauAlgo::jFEXtauAlgo(const std::string& type, const std::string& name, const IInterface* parent): AthAlgTool(type, name, parent) {
+    declareInterface<IjFEXtauAlgo>(this);
+}
+
+/** Destructor */
+LVL1::jFEXtauAlgo::~jFEXtauAlgo() {
+}
+
+StatusCode LVL1::jFEXtauAlgo::initialize() {
+    ATH_CHECK(m_jFEXtauAlgo_jTowerContainerKey.initialize());
+    return StatusCode::SUCCESS;
+}
+
+//calls container for TT
+StatusCode LVL1::jFEXtauAlgo::safetyTest() {
+
+    SG::ReadHandle<jTowerContainer> jk_jFEXtauAlgo_jTowerContainer(m_jFEXtauAlgo_jTowerContainerKey);
+    if(! jk_jFEXtauAlgo_jTowerContainer.isValid()) {
+        ATH_MSG_FATAL("Could not retrieve  jk_jFEXtauAlgo_jTowerContainer " << m_jFEXtauAlgo_jTowerContainerKey.key());
+        return StatusCode::FAILURE;
+    }
+
+    return StatusCode::SUCCESS;
+}
+
+void LVL1::jFEXtauAlgo::setup(int TTwindow[5][5], int seed[3][3]) {
+
+    ATH_MSG_DEBUG(m_color.BLUE<<"---------------- jFEXtauAlgo::setup ----------------"<<m_color.END);
+    std::copy(&TTwindow[0][0], &TTwindow[0][0] + 25, &m_TTwindow[0][0]);
+    std::copy(&seed[0][0], &seed[0][0] + 9 , &m_SeedIDs[0][0]);
+
+}
+     
+//TOB for Tau Algo
+/*LVL1::jFEXtauAlgoTOB * LVL1::jFEXtauAlgo::getTauTOB()
+{
+  jFEXtauAlgoTOB *tob = new jFEXtauTOB();
+//  unsigned int et = getTTowerET();
+//  unsigned int phi = getTTowerET;
+//  unsigned int eta = getRealPhi();
+//  tob->setEta();
+//  tob->setPhi();
+//  tob->setET(et);
+ // tob->setRes();
+ // tob->setSat();
+  return tob;
+}
+
+*/
+
+
+
+
+//this function calculates seed for a given TT
+void LVL1::jFEXtauAlgo::buildSeeds()
+{
+    ATH_MSG_DEBUG("---------------- jFEXtauAlgo::buildsSeeds ----------------");
+    m_seedSet = false;
+    SG::ReadHandle<jTowerContainer> jk_jFEXtauAlgo_jTowerContainer(m_jFEXtauAlgo_jTowerContainerKey);
+    
+    for(int mphi = 0; mphi<3; mphi++) {
+        for(int meta = 0; meta<3; meta++) {
+
+            int et_tmp = 0;
+            int seedTotalET = 0;
+
+            for(int iphi = -1; iphi < 2; iphi++) {
+                for(int ieta = -1; ieta < 2; ieta++) {
+
+                    const LVL1::jTower * tmpTower = jk_jFEXtauAlgo_jTowerContainer->findTower(m_TTwindow[(mphi+1) + iphi][(meta+1) + ieta]);
+                    et_tmp = tmpTower->getTotalET();
+                    seedTotalET += et_tmp;
+                }
+            }
+            m_SeedCluster_ET[mphi][meta] = seedTotalET;
+
+            const LVL1::jTower * tmpTower = jk_jFEXtauAlgo_jTowerContainer->findTower(m_TTwindow[(mphi+1)][(meta+1)]);
+            et_tmp = tmpTower->getTotalET();
+            m_SeedConditions_ET[mphi][meta] = et_tmp;
+        }
+    }
+
+    m_seedSet = true;
+    ATH_MSG_DEBUG("---------------- jFEXtauAlgo::buildsSeeds finished ----------------");
+
+
+}
+
+
+//check if central TT is a local maxima
+bool LVL1::jFEXtauAlgo::isSeedLocalMaxima(){
+    m_isLocalMaxima=false;
+    m_ClusterEt = m_SeedCluster_ET[1][1];
+    
+    if(m_seedSet == false) {
+        ATH_MSG_DEBUG("Local Maxima not checked due to seed not calculated.");
+    }
+    if(m_seedSet == true) {
+        ATH_MSG_DEBUG("Local Maxima checking begins.");
+        //here put the 8 conditions to determine if the [1][1] TT seed is a local maxima.
+        int central_seed = m_SeedConditions_ET[1][1];
+        for (int iphi = 0; iphi < 3; iphi++) {
+            for (int ieta = 0; ieta < 3; ieta++) {
+
+                //avoid comparing central seed to itself
+                if ((ieta == 1) && (iphi == 1)) {
+                    continue;
+                }
+                else if( (iphi > ieta) || (ieta==2 && iphi==2) ) { //strictly less than central
+                    if(central_seed<=m_SeedConditions_ET[iphi][ieta]) {
+                        return false;
+                    }
+                }
+                else if((ieta > iphi) || (ieta == 0 && iphi == 0)) { //less than or equal to central
+                    if(central_seed< m_SeedConditions_ET[iphi][ieta]) {
+                        return false;
+                    }
+                }
+
+            }
+        }
+    }
+    m_isLocalMaxima=true;
+    
+
+    
+    ATH_MSG_DEBUG("Local Maxima found. with ClusterET = "<<m_ClusterEt);
+    return true;
+}
+
+
+         
+std::unique_ptr<jFEXtauTOB> LVL1::jFEXtauAlgo::getTauTOBs(int mphi, int meta){
+
+  std::unique_ptr<jFEXtauTOB> tob = std::make_unique<jFEXtauTOB>();
+
+
+  tob->setET(m_ClusterEt);
+  tob->setPhi(mphi-8); // coord within the FPGA core area
+  tob->setEta(meta-8); // coord within the FPGA core area
+  tob->setIso(m_TauIsolation);
+  tob->setSat(0);
+  return tob;
+}
+
+
+
+
+void LVL1::jFEXtauAlgo::Represent(int var_,int dim_) {
+    int rows_ = dim_;
+    int colums_ = dim_;
+    int row_center= (int) rows_/2;
+    int col_center= (int) colums_/2;
+
+
+    for(int i = 0; i< rows_; i++ ) {
+        //if(i == 0) printf("%3s %s%4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %s\n -7 ","","",-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,"");
+        //else printf("%3d ",i);
+        for(int j = 0; j< colums_; j++) {
+            std::string col_= "";
+            if(sqrt(pow(i-row_center,2)+pow(j-col_center,2))<2) {
+                col_= m_color.B_RED; //RED
+                if((i-row_center)==0 and (j-col_center)==0) col_= m_color.B_PURPLE;  //PURPLE
+            }
+            else if(sqrt(pow(i-row_center,2)+pow(j-col_center,2))<4) col_= m_color.B_ORANGE; //ORANGE
+            else if(sqrt(pow(i-row_center,2)+pow(j-col_center,2))<8) col_= m_color.B_BLUE; //BLUE
+            else col_= m_color.B_GRAY; //GREY
+
+            if(var_==0) printf("%s%4.1f %s",col_.c_str(),sqrt(pow(i,2)+pow(j,2)),"\033[0m");
+            if(var_==1) printf("%s%d-%d %6d%s ",col_.c_str(),i,j,m_SeedIDs[i][j],"\033[0m");  //Trigger Tower ID
+            if(var_==2) printf("%s%6d%s ",col_.c_str(),getTTowerET(i,j),"\033[0m");  //Trigger Tower ID
+            if(var_==3) printf("%s%6d%s ",col_.c_str(),getRealEta(i,j),"\033[0m");  //Trigger Tower ID
+            if(var_==4) printf("%s%6d%s ",col_.c_str(),getRealPhi(i,j),"\033[0m");  //Trigger Tower ID
+            if(var_==5) printf("%s%2d-%2d%s ",col_.c_str(),i,j,"\033[0m");
+            if(var_==6){
+              if(m_SeedConditions_ET[i][j]<m_SeedConditions_ET[1][1]) col_= m_color.B_GREEN;
+              printf("%s%6d<%6d%6d%s ",col_.c_str(),m_SeedConditions_ET[i][j],m_SeedConditions_ET[1][1],(int)(m_SeedConditions_ET[i][j]<m_SeedConditions_ET[1][1]),"\033[0m");  //Trigger Tower ID
+            } 
+            if(var_==7) printf("%s%6d%s ",col_.c_str(),m_TTwindow[i][j],"\033[0m");
+            if(var_==8) printf("%s%6d%s ",col_.c_str(),getTTowerET(i,j),"\033[0m");
+        }
+        printf("\n");
+    }
+    printf("\n");
+
+}
+
+
+
+
+
+//Gets the ET for the TT. This ET is EM + HAD
+int LVL1::jFEXtauAlgo::getTTowerET(unsigned int row_,unsigned int col_) {
+    SG::ReadHandle<jTowerContainer> jk_jFEXtauAlgo_jTowerContainer(m_jFEXtauAlgo_jTowerContainerKey);
+    const LVL1::jTower * tmpTower = jk_jFEXtauAlgo_jTowerContainer->findTower(m_SeedIDs[row_][col_]);
+    return tmpTower->getTotalET();
+}
+//Gets Phi of the TT
+int LVL1::jFEXtauAlgo::getRealPhi(unsigned int row_,unsigned int col_) {
+
+    SG::ReadHandle<jTowerContainer> jk_jFEXtauAlgo_jTowerContainer(m_jFEXtauAlgo_jTowerContainerKey);
+    const LVL1::jTower * tmpTower = jk_jFEXtauAlgo_jTowerContainer->findTower(m_SeedIDs[row_][col_]);
+    
+    return tmpTower->phi();
+}
+//Gets Eta of the TT
+int LVL1::jFEXtauAlgo::getRealEta(unsigned int row_,unsigned int col_) {
+
+    SG::ReadHandle<jTowerContainer> jk_jFEXtauAlgo_jTowerContainer(m_jFEXtauAlgo_jTowerContainerKey);
+    const LVL1::jTower * tmpTower = jk_jFEXtauAlgo_jTowerContainer->findTower(m_SeedIDs[row_][col_]);
+    return realValue(m_SeedIDs[row_][col_],tmpTower->eta()); //return positive ETA for even TTs ID 2XX.XXX.. etc and negative ETA for odd TTs ID 1XX.XXX.. and so on
+    //return tmpTower->eta();
+}
+
+//Gets the seed total ET
+int LVL1::jFEXtauAlgo::getClusterEt() {
+    return m_ClusterEt;
+}
+
+
+//Gets the Isolation/FirstEtRing of jFEX Tau
+
+void LVL1::jFEXtauAlgo::setFirstEtRing(int First_ETring[36]) {
+
+  ATH_MSG_DEBUG("Calculating the jFEXTau ISO");
+  m_TauIsolation=0;
+
+  for(int i=0;i<36;i++){
+    SG::ReadHandle<jTowerContainer> jk_jFEXtauAlgo_jTowerContainer(m_jFEXtauAlgo_jTowerContainerKey);
+    const LVL1::jTower * tmpTower = jk_jFEXtauAlgo_jTowerContainer->findTower(First_ETring[i]);
+    m_TauIsolation += tmpTower->getTotalET();
+  }
+  
+}
+
+int LVL1::jFEXtauAlgo::getFirstEtRing() {
+  
+  return m_TauIsolation;
+}
+
+//Gets the seed total ET
+int LVL1::jFEXtauAlgo::getIsLocalMaxima() {
+
+    return m_isLocalMaxima;
+}
+
+int LVL1::jFEXtauAlgo::realValue(int ID, int eta){
+
+  return ((int)(ID/pow(10,5)) % 10) % 2==0 ?  eta : -eta ;
+  
+}
+
+
+}// end of namespace LVL1
diff --git a/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXtauTOB.cxx b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXtauTOB.cxx
new file mode 100644
index 00000000000..95ed5de9501
--- /dev/null
+++ b/Trigger/TrigT1/L1CaloFEX/L1CaloFEXSim/src/jFEXtauTOB.cxx
@@ -0,0 +1,77 @@
+/*
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+//***************************************************************************
+//              jFEXtauTOB - TOBs Tau Algorithm in jFEX
+//                              -------------------
+//     begin                : 18 02 2021
+//     email                : Sergi.Rodriguez@cern.ch
+//***************************************************************************
+
+#include "L1CaloFEXSim/jFEXtauTOB.h"
+
+
+LVL1::jFEXtauTOB::jFEXtauTOB():
+  m_eta{99999},
+  m_phi{99999},
+  m_ET{99999},
+  m_Iso{99999},
+  m_Sat{99999}
+{}
+
+//in total, 32 bits
+//eta 5 bits local eta coord within fpga core area
+//phi 4 bits local " "
+//E_T 11 bits, transverse energy
+//ISO. 11 bits reserved
+//Saturation, 1 bit, on jFEX input	
+
+void LVL1::jFEXtauTOB::setEta(unsigned int eta)
+{
+  m_eta = eta;
+}
+
+void LVL1::jFEXtauTOB::setPhi(unsigned int phi)
+{
+  m_phi = phi;
+}
+
+void LVL1::jFEXtauTOB::setET(unsigned int et)
+{
+  m_ET = et;
+}
+
+void LVL1::jFEXtauTOB::setIso(unsigned int Iso)
+{
+  m_Iso = Iso;
+}
+
+void LVL1::jFEXtauTOB::setSat(unsigned int sat)
+{
+  m_Sat = sat;
+}
+
+unsigned int LVL1::jFEXtauTOB::GetEta()
+{
+  return m_eta;	
+}
+
+unsigned int  LVL1::jFEXtauTOB::GetPhi()
+{
+  return m_phi;  
+}
+
+unsigned int  LVL1::jFEXtauTOB::GetET()
+{
+  return m_ET;
+}
+
+unsigned int  LVL1::jFEXtauTOB::GetIso()
+{
+  return m_Iso;
+}
+
+unsigned int  LVL1::jFEXtauTOB::GetSat()
+{
+  return m_Sat;
+}
diff --git a/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXFPGA.h b/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXFPGA.h
index 52ec8fd538d..6b4a2c26cc5 100644
--- a/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXFPGA.h
+++ b/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXFPGA.h
@@ -45,6 +45,9 @@ Interface definition for jFEXFPGA
     virtual std::vector<uint32_t> getSmallRJetTOBs() = 0;
     virtual std::vector<uint32_t> getLargeRJetTOBs() = 0;
 
+    virtual uint32_t formTauTOB(int &, int &) =0;
+    virtual std::vector<uint32_t> getTauTOBs() = 0;
+
     virtual void SetTowersAndCells_SG(int [][FEXAlgoSpaceDefs::jFEX_wide_algoSpace_width]) = 0;
     virtual void SetTowersAndCells_SG(int [][FEXAlgoSpaceDefs::jFEX_thin_algoSpace_width]) = 0;
 
diff --git a/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXSmallRJetAlgo.h b/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXSmallRJetAlgo.h
index a2312f456c4..ed12b0a8b7f 100644
--- a/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXSmallRJetAlgo.h
+++ b/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXSmallRJetAlgo.h
@@ -23,15 +23,14 @@ namespace LVL1{
     public:
       static const InterfaceID& interfaceID ( ) ;
       virtual StatusCode safetyTest() = 0;
-      virtual void setup(int inputTable[5][5]) = 0;
-      virtual void setupCluster(int inputTable[4][5]) =0;
+      virtual void setup(int inputTable[7][7], bool barrel_region) = 0;
       virtual bool isSeedLocalMaxima() = 0;
       virtual void buildSeeds() = 0;
       virtual unsigned int getRealPhi() =0;
       virtual unsigned int getRealEta() =0;
       virtual unsigned int getTTowerET() = 0;
       virtual unsigned int getSmallClusterET() =0;
-      //virtual unsigned int getClusterET(int smallRJetClusterIDs[4][5]) =0;
+      virtual unsigned int getSmallETRing() =0;
       virtual std::unique_ptr<jFEXSmallRJetTOB> getSmallRJetTOBs() = 0; 
 
    private:
diff --git a/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXtauAlgo.h b/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXtauAlgo.h
new file mode 100644
index 00000000000..c1ed875b0bf
--- /dev/null
+++ b/Trigger/TrigT1/L1CaloFEXToolInterfaces/L1CaloFEXToolInterfaces/IjFEXtauAlgo.h
@@ -0,0 +1,54 @@
+/*
+ Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+*/
+//***************************************************************************
+//             Interface for jFEXtauAlgo - Algorithm for Tau Algorithm in jFEX
+//                              -------------------
+//     begin                : 18 02 2021
+//     email                : Sergi.Rodriguez@cern.ch
+//***************************************************************************
+
+#ifndef IjFEXtauAlgo_H
+#define IjFEXtauAlgo_H
+
+#include "GaudiKernel/IAlgTool.h"
+#include "L1CaloFEXSim/jFEXtauTOB.h"
+#include "L1CaloFEXSim/jTowerContainer.h"
+
+namespace LVL1 {
+
+static const InterfaceID IID_IjFEXtauAlgo("LVL1::IjFEXtauAlgo",1, 0);
+
+class IjFEXtauAlgo : virtual public IAlgTool {
+    public:
+        static const InterfaceID& interfaceID ( ) ;
+        virtual StatusCode safetyTest() = 0;
+        virtual void setup(int TTwindow[5][5], int seed[3][3]) = 0;
+        //virtual void setupCluster(int inputTable[4][5]) =0;
+        virtual bool isSeedLocalMaxima() = 0;
+        virtual void buildSeeds() = 0;
+        virtual void setFirstEtRing(int First_ETring[]) =0;
+
+        virtual int getTTowerET(unsigned int row_=1 ,unsigned int col_=1 ) =0; 
+        virtual int getRealPhi(unsigned int row_=1 ,unsigned int col_=1 )  =0; 
+        virtual int getRealEta(unsigned int row_=1 ,unsigned int col_=1 )  =0;
+        virtual int getClusterEt()  =0;
+        virtual int getIsLocalMaxima()  =0;
+        virtual int getFirstEtRing()  =0;
+        
+
+        virtual std::unique_ptr<jFEXtauTOB> getTauTOBs(int, int) = 0;
+        virtual void Represent(int,int) =0;
+        
+
+    private:
+
+};
+inline const InterfaceID& LVL1::IjFEXtauAlgo::interfaceID()
+{
+    return IID_IjFEXtauAlgo;
+}
+
+}
+#endif
+
-- 
GitLab