From dea096f32a290c148bf8555e21bf365e3d1d537c Mon Sep 17 00:00:00 2001
From: Mark Sutton <mark.sutton@cern.ch>
Date: Wed, 28 May 2014 11:52:54 +0200
Subject: [PATCH] move to use only RoiDescriptors (TrigT2CaloTau-00-06-21)

---
 .../TrigT2CaloTau/T2CalibrationTau.h          |   52 +
 .../TrigT2CaloTau/TrigT2CaloTau/T2CaloTau.h   |  147 ++
 .../TrigT2CaloTau/T2CaloTauErrorHandler.h     |   25 +
 .../TrigT2CaloTau/T2CaloTauErrorMon.h         |   53 +
 .../TrigT2CaloTau/TauAllCaloDRFex.h           |   93 ++
 .../TrigT2CaloTau/cmt/requirements            |   43 +
 .../TrigT2CaloTau/doc/mainpage.h              |   35 +
 .../python/TrigT2CaloTauConfig.py             |  104 ++
 .../python/TrigT2CaloTauMonitoring.py         |  109 ++
 .../TrigT2CaloTau/src/T2CaloTau.cxx           |  647 +++++++++
 .../TrigT2CaloTau/src/TauAllCaloDRFex.cxx     | 1186 +++++++++++++++++
 .../src/components/TrigT2CaloTau_entries.cxx  |   12 +
 .../src/components/TrigT2CaloTau_load.cxx     |    3 +
 13 files changed, 2509 insertions(+)
 create mode 100755 Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CalibrationTau.h
 create mode 100755 Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CaloTau.h
 create mode 100755 Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CaloTauErrorHandler.h
 create mode 100755 Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CaloTauErrorMon.h
 create mode 100644 Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/TauAllCaloDRFex.h
 create mode 100755 Trigger/TrigAlgorithms/TrigT2CaloTau/cmt/requirements
 create mode 100644 Trigger/TrigAlgorithms/TrigT2CaloTau/doc/mainpage.h
 create mode 100755 Trigger/TrigAlgorithms/TrigT2CaloTau/python/TrigT2CaloTauConfig.py
 create mode 100755 Trigger/TrigAlgorithms/TrigT2CaloTau/python/TrigT2CaloTauMonitoring.py
 create mode 100755 Trigger/TrigAlgorithms/TrigT2CaloTau/src/T2CaloTau.cxx
 create mode 100644 Trigger/TrigAlgorithms/TrigT2CaloTau/src/TauAllCaloDRFex.cxx
 create mode 100755 Trigger/TrigAlgorithms/TrigT2CaloTau/src/components/TrigT2CaloTau_entries.cxx
 create mode 100755 Trigger/TrigAlgorithms/TrigT2CaloTau/src/components/TrigT2CaloTau_load.cxx

diff --git a/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CalibrationTau.h b/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CalibrationTau.h
new file mode 100755
index 00000000000..8bad3b2b7a6
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CalibrationTau.h
@@ -0,0 +1,52 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ********************************************************************
+//
+// NAME:     T2CalibrationTau.h
+// PACKAGE:  Trigger/TrigAlgorithms/TrigT2CaloTau
+//
+// AUTHOR:   D.O. Damazio
+//
+// Object only designed to understand cluster calibration
+// Should be used by EM and Tau people in the near future
+// It should be possible to introduce the calibration configuration
+// from a jobOption file. Not possible now.
+//
+// ********************************************************************
+
+#ifndef TRIGT2CALOTAU_T2CALIBRATIONTAU
+#define TRIGT2CALOTAU_T2CALIBRATIONTAU
+#include <vector>
+#include <math.h>
+#include "TrigT2CaloCommon/T2Calibration.h"
+
+class T2CalibrationTau : public T2Calibration {
+public:
+
+/** Constructor */
+	T2CalibrationTau() : T2Calibration(){}
+/** Destructor */
+	~T2CalibrationTau(){}
+
+        // The two methods of this class, initialize and Calib, are virtual 
+        // in the base class T2Calibration and implemented there as for the 
+        // moment calibration is the same for egamma/tau. For an specific 
+        // calibration override these methods.        
+ 
+	// In the initialize, one should provide a vector with the
+	// Eta limits (eg.: 0-2.5), the dimensions of the correction
+	// vector (eg: 2 100 - for 2 lines of one hundred constants - the
+	// first line is the eta of that bin and the second brings
+	// the calibration constant for that bin
+//	void initialize(const std::vector<float>& limit, const std::vector<int>&
+//		dimension, const std::vector<float>& correction);
+
+	// This, for a given cluster eta and energy (not being used yet),
+	// provides the calibration constant
+//	double Calib( const double ClusterEta, const double EnergyCluster);
+
+};
+
+#endif
diff --git a/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CaloTau.h b/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CaloTau.h
new file mode 100755
index 00000000000..ceb0bc81305
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CaloTau.h
@@ -0,0 +1,147 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ********************************************************************
+// 
+// NAME:     T2Calo.h
+// PACKAGE:  Trigger/TrigAlgorithms/TrigT2CaloTau
+// 
+// AUTHORS:   M.P. Casado
+// 	      C. Osuna
+// updates: 3/3/11 ccuenca, added new vars for monitoring
+// 
+// - Add new variables to allow job option control of eta/phi regions 
+//   used in each tool.  Also hardcode in eta ranges and granularities
+//   for all layers and add a new function so that tools can adjust the
+//   number of strips used in energy sums for changes in granularity.
+//   The goal is to try to sample a constant eta/phi area.   - R. Soluk 
+// ********************************************************************
+
+#ifndef TRIGT2CALOTAU_T2CALOTAU_H 
+#define TRIGT2CALOTAU_T2CALOTAU_H
+
+#include <string>
+#include "GaudiKernel/ToolHandle.h"
+#include "TrigInterfaces/FexAlgo.h"
+#include "TrigT2CaloCommon/T2CaloBase.h"
+#include "TrigT2CaloCalibration/IT2HadCalibTool.h"
+#include "TrigT2CaloTau/T2CaloTauErrorMon.h"
+#include "TrigCaloEvent/TrigTauCluster.h"
+
+class StoreGateSvc;
+namespace HLT
+{
+    class TriggerElement;
+}
+class IAlgToolCalo;
+
+class T2CaloTau : public T2CaloBase
+{
+public:
+    /** Constructor */
+    T2CaloTau(const std::string & name, ISvcLocator* pSvcLocator);
+    /** Destructor */
+    ~T2CaloTau();
+    /** HLT method to execute */
+    HLT::ErrorCode hltExecute(const HLT::TriggerElement* inputTE, HLT::TriggerElement* outputTE);
+
+    /** HLT method to initialize */
+    HLT::ErrorCode hltInitialize();
+    /** HLT method to finalize */
+    HLT::ErrorCode hltFinalize();
+
+private:
+    // Properties:
+
+    /** SG key for TrigTauCluster*/
+    std::string m_trigTauClusterKey;
+
+    /** not used */
+    int m_index;
+
+    /** EMRadius variable for monitoring */
+    double m_EMRadius;
+    /** EMRadius3S variable for monitoring */
+    double m_EMRadius3S;
+    /** CaloRadius variable for monitoring */
+    double m_CaloRadius;
+
+    /** HadRad variable for monitoring */
+    double m_HadRad;
+
+    /** Isofrac variable for monitoring */
+    double m_IsoFrac    ;
+    /** stripWidth variable for monitoring*/
+    double m_StripWidth ;
+
+    /** Fraction of EM energy over total energy in a normal (dR<0.3) cone for monitoring */
+    double m_EMFraction;
+
+    /** Raw Et in wide 0.3 cone for monitoring */
+    double m_EtRawWide;
+
+    /** EM Energy in (dR<0.2) cone for monitoring */
+    double m_EMEnMedium;
+    /** HAD Energy in (dR<0.2) cone for monitoring */
+    double m_HADEnMedium;
+
+    /** EM Energy in (dR<0.1) cone for monitoring */
+    double m_EMEnNarrow;
+    /** HAD Energy in (dR<0.1) cone for monitoring */
+    double m_HADEnNarrow;
+    /** Raw Et in medium cone for monitoring */
+    double m_EtRawMedium;
+    /** Raw Et in medium cone for monitoring (EM Sampling 0) */
+    double m_EtRawMediumEM0;
+    /** Raw Et in medium cone for monitoring (EM Sampling 1) */
+    double m_EtRawMediumEM1;
+    /** Raw Et in medium cone for monitoring (EM Sampling 2) */
+    double m_EtRawMediumEM2;
+    /** Raw Et in medium cone for monitoring (EM Sampling 3) */
+    double m_EtRawMediumEM3;
+    /** Raw Et in medium cone for monitoring (Had Sampling 0) */
+    double m_EtRawMediumHad0;
+    /** Raw Et in medium cone for monitoring (Had Sampling 1) */
+    double m_EtRawMediumHad1;
+    /** Raw Et in medium cone for monitoring (Had Sampling 2) */
+    double m_EtRawMediumHad2;
+
+    /** EtRawNarrow/EtRawMedium */
+    double m_CoreFraction;
+
+    /** eta of seed of L1 ROI */
+    double m_EtaL1        ;
+    /** phi of seed of L1 ROI */
+    double m_PhiL1        ;
+
+    /** eta of seed of calo Cluster */
+    double m_Eta        ;
+    /** phi of seed of calo Cluster */
+    double m_Phi        ;
+    /** Difference in Eta at L2 and L1 for monitoring */
+    double m_dEtaL2Tau_RoI   ;
+    /** Difference in Phi at L2 and L1 for monitoring */
+    double m_dPhiL2Tau_RoI   ;
+
+    /** counter for conversion error */
+    unsigned int m_conversionError;
+    /** counter for algorithm error */
+    unsigned int m_algorithmError;
+    /** error monitoring of cluster quality */
+    std::vector<unsigned char> m_quality;
+
+    /** Should or not storeCells into a cell container attached to output RoI */
+    bool m_storeCells;
+    /** container pointer */
+    CaloCellContainer* m_Container;
+
+    /** option to update RoiDescriptor after execution (important for following trigger chain steps) */
+    bool        m_updateRoiDescriptor;
+
+    /** phi, eta EM width */
+    double m_phiWidthEM;
+    double m_etaWidthEM;
+};
+
+#endif
diff --git a/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CaloTauErrorHandler.h b/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CaloTauErrorHandler.h
new file mode 100755
index 00000000000..8fde34fa3a7
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CaloTauErrorHandler.h
@@ -0,0 +1,25 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGT2CALOTAU_T2CALOTAUERRORHANDLER_H 
+#define TRIGT2CALOTAU_T2CALOTAUERRORHANDLER_H
+
+namespace TAUCLUSTERROR {
+
+    /** enumerate tau-specific errors */
+    enum TAUCLUSTERROR{
+      FAILPRESEED=31,
+      FAILSEED=30,
+      HADS1E0=11,
+      HADS2E0=10,
+      HADS3E0=9,
+      EMS0E0=15,
+      EMS1E0=14,
+      EMS2E0=13,
+      EMS3E0=12
+    };
+
+
+}
+#endif
diff --git a/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CaloTauErrorMon.h b/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CaloTauErrorMon.h
new file mode 100755
index 00000000000..9288f4befa1
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/T2CaloTauErrorMon.h
@@ -0,0 +1,53 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGT2CALOTAU_T2CALOTAUERRORMON_H 
+#define TRIGT2CALOTAU_T2CALOTAUERRORMON_H
+#include "TrigT2CaloTau/T2CaloTauErrorHandler.h"
+
+namespace TAUCLUSTMON {
+
+    /** enumerate tau-specific errors for monitoring */
+    enum TAUCLUSTMON{
+      LARPROB=0,
+      TILEPROB=1,
+      ROBPROB=2,
+      RODPROB=3,
+      FAILSEED=4,
+      FAILPRESEED=5,
+      EMS0E0=6,
+      EMS1E0=7,
+      EMS2E0=8,
+      EMS3E0=9,
+      HADS1E0=10,
+      HADS2E0=11,
+      HADS3E0=12,
+      OTHERERRORS=13,
+      GOODCLUST=14,
+      ALLCLUST=15
+    };
+
+    bool GetClusterError(unsigned int bit,uint32_t error ) { return ((error >> bit)&0x1)!=0 ;}
+
+    void FillErrorMonitoring(uint32_t error, std::vector<unsigned char> * quality){
+      bool isError=false;
+      if ( 0x000000FF & error ) {isError=true; quality->push_back(LARPROB); }
+      if ( 0x0FFF0000 & error ) {isError=true; quality->push_back(TILEPROB); }
+      if ( 0x10000000 & error ) {isError=true; quality->push_back(ROBPROB); }
+      if ( 0x20000000 & error ) {isError=true; quality->push_back(RODPROB); }
+      if ( GetClusterError( TAUCLUSTERROR::FAILSEED    , error) ) {isError=true; quality->push_back(FAILSEED); }
+      if ( GetClusterError( TAUCLUSTERROR::FAILPRESEED , error) ) {isError=true; quality->push_back(FAILPRESEED); }
+      if ( GetClusterError( TAUCLUSTERROR::EMS0E0      , error) ) {isError=true; quality->push_back(EMS0E0); }
+      if ( GetClusterError( TAUCLUSTERROR::EMS1E0      , error) ) {isError=true; quality->push_back(EMS1E0); }
+      if ( GetClusterError( TAUCLUSTERROR::EMS2E0      , error) ) {isError=true; quality->push_back(EMS2E0); }
+      if ( GetClusterError( TAUCLUSTERROR::EMS3E0      , error) ) {isError=true; quality->push_back(EMS3E0); }
+      if ( GetClusterError( TAUCLUSTERROR::HADS1E0     , error) ) {isError=true; quality->push_back(HADS1E0); }
+      if ( GetClusterError( TAUCLUSTERROR::HADS2E0     , error) ) {isError=true; quality->push_back(HADS2E0); }
+      if ( GetClusterError( TAUCLUSTERROR::HADS3E0     , error) ) {isError=true; quality->push_back(HADS3E0); }
+      if (isError==false && error>0 ) {quality->push_back(OTHERERRORS); }
+    }
+
+}
+#endif
+
diff --git a/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/TauAllCaloDRFex.h b/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/TauAllCaloDRFex.h
new file mode 100644
index 00000000000..fac6702f6f9
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigT2CaloTau/TrigT2CaloTau/TauAllCaloDRFex.h
@@ -0,0 +1,93 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ********************************************************************
+// 
+// NAME:     TauAllCaloDRFex.h
+// PACKAGE:  Trigger/TrigAlgorithms/TrigT2CaloTau
+// 
+// AUTHOR:   Olga Igonkina (Nikhef), Pilar Casado (IFAE), Mogens Dam (NBI)
+// 
+// CREATED: June-09
+//
+// DESCRIPTION: Tool to compute calorimeter tau variables in EM and HAD
+// ********************************************************************
+
+#ifndef TRIGT2CALOTAU_TAUALLCALODRFEX_H 
+#define TRIGT2CALOTAU_TAUALLCALODRFEX_H
+
+
+#include "TrigT2CaloCommon/IAlgToolCalo.h"
+#include "GaudiKernel/AlgTool.h"
+#include "TrigCaloEvent/TrigTauCluster.h"
+#include "TrigT2CaloTau/T2CaloTauErrorHandler.h"
+#include "CaloInterface/ICalorimeterNoiseTool.h"
+
+class TauAllCaloDRFex : public IAlgToolCalo
+{
+public:
+    /** Constructor */
+    TauAllCaloDRFex(const std::string& type, const std::string& name, const IInterface* parent);
+    /** virtual Destructor */
+    virtual ~TauAllCaloDRFex();
+    /** execute method of IAlgToolCalo */
+    using IAlgToolCalo::execute;
+    /** execute method */
+
+    /// take two roi descriptors into the shower
+    HLT::ErrorCode execute(TrigTauCluster &rtrigTauCluster, const IRoiDescriptor& roi );
+
+    //    HLT::ErrorCode execute(TrigTauCluster &rtrigTauCluster, double phiWidth, 
+    //                           double etaWidth, double phiWidthEM,
+    //                           double etaWidthEM, double RoIeta, double RoIphi);
+
+    //    HLT::ErrorCode execute(TrigTauCluster &rtrigTauCluster,double phiWidth, 
+    //         double etaWidth, double RoIeta, double RoIphi);
+
+    /** initialize function **/
+    StatusCode initialize();
+    
+private:
+    /** Energy threshold for numStrips counting */
+    double m_stripEthr;  
+
+    /** dR cut for reconstruction of the seed */
+    double m_dRSeed;  
+    /** dR cut for full region, Wide (previously called Normal)  */
+    double m_dRConeWide;  
+    /** dR cut for Medium region (previously called Med)  */
+    double m_dRConeMedium;
+    /** dR cut for Narrow region (previously called Nar)  */
+    double m_dRConeNarrow;
+    /** dR cut for EM region (previously called Normal)  */
+    double m_dRConeEM;  
+
+    /** Variable to control noise substraction  */
+    bool m_applyNoiseCut;
+    /** Switch to choose between square or linear radius */
+    bool m_squareRadius;
+    /** Number of sigmas for noise cut  */
+    double m_noiseNSigmaCut;
+    /** int for hecQualityCut */
+    int m_hecQualityCut;
+
+  /** choose default width: 0 Narrow, 1 Medium, 2 Wide (Normal) */
+    int m_defaultWidth;
+
+
+    /** Tool for noise substraction  */
+    ToolHandle<ICalorimeterNoiseTool> m_noiseTool;
+
+    double emRadiusAllSampl(const TrigTauClusterDetails* clusterDetails, int maxEmSamp=100);
+    double caloRadius(const TrigTauClusterDetails* clusterDetails);
+    double coreFraction(const TrigTauClusterDetails* clusterDetails);
+    double emFraction(const TrigTauCluster* ptrigTauCluster);
+    double hadRadius(const TrigTauClusterDetails* clusterDetails);
+    double calcEnergyPhi(double energyNegPhi, double energyPosPhi, double EnergyWidNegPhi, double EnergyWidPosPhi, double energyNegPhiConv);
+    bool getdR(double compPhi, double compEta, double etaCell, double phiCell, double dRCut, double& dR);
+    double getEMEnergy(const TrigTauClusterDetails* clusterDetails, int widthChoice);
+    double getHADEnergy(const TrigTauClusterDetails* clusterDetails, int widthChoice);
+};
+
+#endif
diff --git a/Trigger/TrigAlgorithms/TrigT2CaloTau/cmt/requirements b/Trigger/TrigAlgorithms/TrigT2CaloTau/cmt/requirements
new file mode 100755
index 00000000000..65310caf1b9
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigT2CaloTau/cmt/requirements
@@ -0,0 +1,43 @@
+package TrigT2CaloTau 
+
+author Pilar Casado <casado@ifae.es>
+author Denis Oliveira <Denis.Oliveira.Damazio@cern.ch>
+author Carlos Osuna <Carlos.Osuna.Escamilla@cern.ch>
+author Xin Wu <Xin.Wu@cern.ch>
+
+use AtlasPolicy         AtlasPolicy-*
+use GaudiInterface      GaudiInterface-*             External
+#use AtlasAIDA           AtlasAIDA-00-*               External
+#use StoreGate           StoreGate-*                  Control
+
+use AtlasROOT 		AtlasROOT-* 			External
+
+#use ByteStreamData      ByteStreamData-*             Event
+#use LArByteStream       LArByteStream-*              LArCalorimeter/LArCnv
+#use LArRecEvent         LArRecEvent-*                LArCalorimeter
+#use LArRawUtils         LArRawUtils-*                LArCalorimeter
+#use LArRecEvent         LArRecEvent-*                LArCalorimeter
+#use TileEvent           TileEvent-*                  TileCalorimeter
+#use Identifier          Identifier-*                 DetectorDescription
+use CaloInterface       CaloInterface-*              Calorimeter
+use TrigT2CaloCommon    TrigT2CaloCommon-*           Trigger/TrigAlgorithms
+ 
+use TrigInterfaces      TrigInterfaces-*             Trigger/TrigSteer
+#use RegionSelector      RegionSelector-*          DetectorDescription
+use TrigSteeringEvent   TrigSteeringEvent-*          Trigger/TrigEvent
+use TrigCaloEvent       TrigCaloEvent-*              Trigger/TrigEvent
+#use TrigTimeAlgs        TrigTimeAlgs-*               Trigger/TrigTools
+#use TrigMonitorBase     TrigMonitorBase-*            Trigger/TrigMonitoring
+#use ByteStreamCnvSvcBase ByteStreamCnvSvcBase-*      Event
+use TrigT2CaloCalibration TrigT2CaloCalibration-*    Trigger/TrigTools
+
+private
+use AthenaKernel	AthenaKernel-*		     Control
+use CaloEvent           CaloEvent-*                  Calorimeter
+use CaloGeoHelpers      CaloGeoHelpers-*             Calorimeter
+use CaloIdentifier      CaloIdentifier-*             Calorimeter
+use TrigT1Interfaces    TrigT1Interfaces-*           Trigger/TrigT1
+
+apply_pattern dual_use_library files=*.cxx
+apply_pattern declare_joboptions files="*.txt *.py"
+apply_pattern declare_python_modules files="*.py"
diff --git a/Trigger/TrigAlgorithms/TrigT2CaloTau/doc/mainpage.h b/Trigger/TrigAlgorithms/TrigT2CaloTau/doc/mainpage.h
new file mode 100644
index 00000000000..9c99d62b71f
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigT2CaloTau/doc/mainpage.h
@@ -0,0 +1,35 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+
+@mainpage
+@author Carlos Osuna
+@author Stefania Xella
+@author M. Pilar Casado
+@author Olga Igonkina
+
+@section TrigT2CaloTauOverview  Overview
+This package is in charge of the calorimeter reconstruction in
+the trigger LVL2 for taus. It builds a set of shower shape variables
+to discriminate jet and taus.
+Deposited energy is available in 3 different window sizes for all sampling.
+
+@ref used_TrigT2CaloTau
+
+@ref requirements_TrigT2CaloTau
+
+*/
+
+/**
+@page used_TrigT2CaloTau Used Packages
+@htmlinclude used_packages.html
+*/
+
+/**
+@page requirements_TrigT2CaloTau Requirements
+@include requirements
+
+
+*/
diff --git a/Trigger/TrigAlgorithms/TrigT2CaloTau/python/TrigT2CaloTauConfig.py b/Trigger/TrigAlgorithms/TrigT2CaloTau/python/TrigT2CaloTauConfig.py
new file mode 100755
index 00000000000..a53ce9b16fd
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigT2CaloTau/python/TrigT2CaloTauConfig.py
@@ -0,0 +1,104 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+#------------------------------------------------
+# T2CaloTau Calibration Options
+#------------------------------------------------
+
+from TrigT2CaloTau.TrigT2CaloTauConf import T2CaloTau, TauAllCaloDRFex
+
+from CaloTools.CaloNoiseToolDefault import CaloNoiseToolDefault
+theCaloNoiseTool=CaloNoiseToolDefault()
+
+from AthenaCommon.AppMgr import ToolSvc
+ToolSvc+=theCaloNoiseTool
+
+from AthenaCommon.Constants import VERBOSE,DEBUG,INFO
+
+#Make changes to TauAllCaloDRFex parameters here:
+
+class TauAllCaloDRFexConfig (TauAllCaloDRFex):
+   __slots__ = []
+   def __init__ (self, name="TauAllCaloDRFexConfig",tdRNar=0.1,tdRMed=0.2,tdRWid=0.4,tdefWidth=2):
+       super(TauAllCaloDRFexConfig, self).__init__(name)
+       # here put your customizations
+       self.CaloNoiseTool  = theCaloNoiseTool
+       self.applyNoiseCut  = True
+       self.noiseNSigmaCut = 2.
+       self.hecQualityCut  = 0              
+       self.dRSeed         = 0.15
+       self.StripEthr      = 200.
+       self.defaultWidth   = tdefWidth #Sets which width size is saved for EMEnergy (0:Narrow,1:Medium,2:Wide)
+       self.dRConeNarrow   = tdRNar
+       self.dRConeMedium   = tdRMed
+       self.dRConeWide     = tdRWid
+
+
+## configurable class
+class T2CaloTau_Tau_custom (T2CaloTau):
+   __slots__ = []
+   def __init__ (self, name="T2CaloTau_Tau_custom"): 
+       super(T2CaloTau_Tau_custom, self).__init__(name)
+       self.EtaWidth = 0.4
+       self.PhiWidth = 0.4
+       self.EtaWidthForID = 0.3
+       self.PhiWidthForID = 0.3
+     
+       tauAllCaloDRFex = TauAllCaloDRFexConfig()
+
+       self.IAlgToolList=[tauAllCaloDRFex]
+       self.TimerNtuple="T2CaloTau.T2CaTautTot"
+       self.TrigTauClusterKey = "T2CaloTrigTauCluster"
+
+#       monitoring part. To switch off do in topOption TriggerFlags.enableMonitoring = []
+       from TrigT2CaloTau.TrigT2CaloTauMonitoring import T2CaloTauValidationMonitoring, T2CaloTauOnlineMonitoring, T2CaloTauCosmicMonitoring 
+       validation = T2CaloTauValidationMonitoring()        
+       online     = T2CaloTauOnlineMonitoring()
+       cosmic     = T2CaloTauCosmicMonitoring()
+
+       from TrigTimeMonitor.TrigTimeHistToolConfig import TrigTimeHistToolConfig
+       time = TrigTimeHistToolConfig("Time")
+
+       self.AthenaMonTools = [ time, validation, online, cosmic ]
+
+
+## calo monitoring class
+class T2CaloTau_cells (T2CaloTau_Tau_custom):
+   __slots__ = []
+   def __init__ (self, name="T2CaloTau_cells"): 
+       super(T2CaloTau_cells, self).__init__(name)
+       # here put your customizations
+       self.IAlgToolList= [TauAllCaloDRFexConfig('tauAllCaloDRFexCells')]
+       # Save cells
+       for item in self.IAlgToolList:
+         item.SaveCellsInContainer=True
+         item.ThresholdKeepCells=-100000.
+         item.hecQualityCut=0
+         item.CaloNoiseTool=theCaloNoiseTool
+         item.applyNoiseCut=False
+         item.noiseNSigmaCut=2.
+
+       self.StoreCells=True
+       self.EtaWidth = 0.4
+       self.PhiWidth = 0.4
+       self.TimerNtuple="T2CaloTau.T2CaTautTot"
+       self.TrigTauClusterKey = "T2CaloTrigTauCluster"
+
+
+############### to be imported by the menu ###############
+
+# default class (2011)
+class T2CaloTau_Tau (T2CaloTau_Tau_custom):
+   __slots__ = []
+   #def __init__ (self, name="T2CaloTau_Tau"):
+   def __init__ (self, name="T2CaloTau_Tau"):
+      T2CaloTau_Tau_custom.__init__(self,name)
+      tauAllCaloDRFex = TauAllCaloDRFexConfig(tdRNar=0.1,tdRMed=0.2,tdRWid=0.4,tdefWidth=2) # use Wide (Nor in 2011), cone size 0.4
+      self.IAlgToolList=[tauAllCaloDRFex]
+      
+# class for 2012: uses Medium cone size as default
+class T2CaloTau_Tau_Med (T2CaloTau_Tau_custom):
+   __slots__ = []
+   def __init__ (self, name="T2CaloTau_Tau_Med"):
+      T2CaloTau_Tau_custom.__init__(self,name)
+      tauAllCaloDRFex = TauAllCaloDRFexConfig(tdRNar=0.1,tdRMed=0.2,tdRWid=0.4,tdefWidth=1) # use Medium cone size (0.2) variables
+      self.IAlgToolList=[tauAllCaloDRFex]
diff --git a/Trigger/TrigAlgorithms/TrigT2CaloTau/python/TrigT2CaloTauMonitoring.py b/Trigger/TrigAlgorithms/TrigT2CaloTau/python/TrigT2CaloTauMonitoring.py
new file mode 100755
index 00000000000..2d831bbe61f
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigT2CaloTau/python/TrigT2CaloTauMonitoring.py
@@ -0,0 +1,109 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+################# Validation, DQ checks
+from TrigMonitorBase.TrigGenericMonitoringToolConfig import defineHistogram, TrigGenericMonitoringToolConfig 
+
+# Set labels for error monitoring histogram. The order has to match with T2CaloTauErrorMon.h file! Number has to match with histo definition.
+errorlabels = 'LAr_Problem:Tile_Problem:N_ROBs<requested:empty_ROD_block:Fail_Seed:Fail_PreSeed:EM_S0_E0:EM_S1_E0:EM_S2_E0:EM_S3_E0:HAD_S1_E0:HAD_S2_E0:HAD_S3_E0:Other_Errors:Good_Clusters:All_Clusters'
+
+class T2CaloTauOnlineMonitoring(TrigGenericMonitoringToolConfig):
+    def __init__ (self, name="T2CaloTauOnlineMonitoring"):
+        super(T2CaloTauOnlineMonitoring, self).__init__(name)
+        self.defineTarget("Online")
+        
+        self.Histograms += [ defineHistogram('EMRadius',     type='TH1F', title="L2CaloTau FEX EMRadius;EMRadius; nevents",                                                   xbins=100, xmin=-0.5, xmax=1.5) ]
+        self.Histograms += [ defineHistogram('EMRadius3S',   type='TH1F', title="L2CaloTau FEX EMRadius3S;EMRadius3S; nevents",                                               xbins=100, xmin=-0.5, xmax=1.5) ]
+        self.Histograms += [ defineHistogram('HadRad',       type='TH1F', title="L2CaloTau FEX HadRad;HadRad; nevents",                                                       xbins=100, xmin=-0.5, xmax=1.5) ]
+        self.Histograms += [ defineHistogram('CaloRadius',   type='TH1F', title="L2CaloTau FEX CaloRadius;CaloRadius; nevents",                                               xbins=100, xmin=-0.5, xmax=1.5) ]
+
+        self.Histograms += [ defineHistogram('IsoFrac',      type='TH1F', title="L2CaloTau FEX IsoFrac;IsoFrac; nevents",                                                     xbins=80, xmin=-1.0, xmax=3.0) ]
+        self.Histograms += [ defineHistogram('StripWidth',   type='TH1F', title="L2CaloTau FEX StripWidth;StripWidth; nevents",                                               xbins=70, xmin=-0.1, xmax=0.6) ]
+
+        self.Histograms += [ defineHistogram('EMFraction',   type='TH1F', title="L2CaloTau FEX EM Energy Fraction;EMFraction; nevents",                                       xbins=90, xmin=-0.6, xmax=1.2) ]
+
+        ##Medium: cone 0.2
+        self.Histograms += [ defineHistogram('EMEnMedium',     type='TH1F', title="L2CaloTau FEX EMEnMedium in (dR<0.2) cone;EMEnMedium [MeV]; nevents",                            xbins=171, xmin=-13000, xmax=500000) ]
+        self.Histograms += [ defineHistogram('HADEnMedium',    type='TH1F', title="L2CaloTau FEX HADEnMedium in (dR<0.2) cone;HADEnMedium [MeV]; nevents",                          xbins=171, xmin=-13000, xmax=500000) ]
+
+        ##Narrow: cone 0.1
+        self.Histograms += [ defineHistogram('EMEnNarrow',   type='TH1F', title="L2CaloTau FEX EMEnNarrow in (dR<0.1) cone;EMEnNarrow [MeV]; nevents",                        xbins=171, xmin=-13000, xmax=500000) ]
+        self.Histograms += [ defineHistogram('HADEnNarrow',  type='TH1F', title="L2CaloTau FEX HADEnNarrow in (dR<0.1) cone;HADEnNarrow [MeV]; nevents",                      xbins=171, xmin=-13000, xmax=500000) ]
+
+        self.Histograms += [ defineHistogram('EtRawMedium',     type='TH1F', title="L2CaloTau FEX EtRaw in a medium (dR<0.2) cone;EtRawMedium [MeV]; nevents",                      xbins=171, xmin=-13000, xmax=500000) ] 
+        self.Histograms += [ defineHistogram('EtRawMediumEM0',  type='TH1F', title="L2CaloTau FEX EtRaw in a medium (dR<0.2) cone - Layer 0 of EM;EtRawMediumEM0 [MeV]; nevents",   xbins=171, xmin=-13000, xmax=500000) ]
+        self.Histograms += [ defineHistogram('EtRawMediumEM1',  type='TH1F', title="L2CaloTau FEX EtRaw in a medium (dR<0.2) cone - Layer 1 of EM;EtRawMediumEM1 [MeV]; nevents",   xbins=171, xmin=-13000, xmax=500000) ]
+        self.Histograms += [ defineHistogram('EtRawMediumEM2',  type='TH1F', title="L2CaloTau FEX EtRaw in a medium (dR<0.2) cone - Layer 2 of EM;EtRawMediumEM2 [MeV]; nevents",   xbins=171, xmin=-13000, xmax=500000) ]
+        self.Histograms += [ defineHistogram('EtRawMediumEM3',  type='TH1F', title="L2CaloTau FEX EtRaw in a medium (dR<0.2) cone - Layer 3 of EM;EtRawMediumEM3 [MeV]; nevents",   xbins=171, xmin=-13000, xmax=500000) ]
+        self.Histograms += [ defineHistogram('EtRawMediumHad0', type='TH1F', title="L2CaloTau FEX EtRaw in a medium (dR<0.2) cone - Layer 0 of Had;EtRawMediumHad0 [MeV]; nevents", xbins=171, xmin=-13000, xmax=500000) ]
+        self.Histograms += [ defineHistogram('EtRawMediumHad1', type='TH1F', title="L2CaloTau FEX EtRaw in a medium (dR<0.2) cone - Layer 1 of Had;EtRawMediumHad1 [MeV]; nevents", xbins=171, xmin=-13000, xmax=500000) ]
+        self.Histograms += [ defineHistogram('EtRawMediumHad2', type='TH1F', title="L2CaloTau FEX EtRaw in a medium (dR<0.2) cone - Layer 2 of Had;EtRawMediumHad2 [MeV]; nevents", xbins=171, xmin=-13000, xmax=500000) ]
+
+        self.Histograms += [ defineHistogram('CoreFraction', type='TH1F', title="EtRawNarrow/EtRawMedium; Core Fraction; nevents",  xbins=70, xmin=-0.2, xmax=1.2) ]
+
+        self.Histograms += [ defineHistogram('EtaL1, PhiL1', type='TH2F', title="L1 ROI Eta vs Phi in T2CaloTau FEX; #eta; #varphi; nevents",                                 xbins=51, xmin=-2.55, xmax=2.55,
+                                                                                                                                                                              ybins=65, ymin=-3.1415936-0.098174/2., ymax=3.1415936+0.098174/2.)]
+
+        self.Histograms += [ defineHistogram('EtaL1',        type='TH1F', title="T2CaloTau L1 Eta; Eta; nevents",                                                             xbins=80, xmin=-4, xmax=4) ]
+        self.Histograms += [ defineHistogram('PhiL1',        type='TH1F', title="T2CaloTau L1 Phi; Phi; nevents",                                                             xbins=65, xmin=-3.1415936-0.098174/2., xmax=3.1415936+0.098174/2.)]
+
+        self.Histograms += [ defineHistogram('Eta',          type='TH1F', title="T2CaloTau FEX Eta; Eta; nevents",                                                            xbins=80, xmin=-4, xmax=4) ]
+        self.Histograms += [ defineHistogram('Phi',          type='TH1F', title="T2CaloTau FEX Phi; Phi; nevents",                                                            xbins=65, xmin=-3.1415936-0.098174/2., xmax=3.1415936+0.098174/2.)]
+
+        self.Histograms += [ defineHistogram('dEtaL2Tau_RoI, dPhiL2Tau_RoI', type='TH2F', title="dEta vs dPhi in L2CaloTau FEX; Delta-eta; Delta-phi",                        xbins=40 , xmin=-0.2, xmax=0.2,
+                                                                                                                                                                              ybins=40 , ymin=-0.2, ymax=0.2) ]
+
+        self.Histograms += [ defineHistogram('ConversionErrors',type='TH1F',title='L2CaloTau Conversion Errors; # Errors; # Clusters',xbins=10,xmin=0,xmax=10)]
+        self.Histograms += [ defineHistogram('AlgorithmErrors', type='TH1F',title='L2CaloTau Algorithm Errors; # Errors; # Clusters', xbins=10,xmin=0,xmax=10)]
+        self.Histograms += [ defineHistogram('Quality',         type='TH1I',title='L2CaloTau FEX Error bit mask; Error; # Clusters',  xbins=16,xmin=0,xmax=16,labels=errorlabels )]
+
+########## ##############################################################
+#  add validation specific histograms. 
+#  If you ever remove histograms from Online - move them into Validation
+#
+#########################################################################
+class T2CaloTauValidationMonitoring(T2CaloTauOnlineMonitoring):
+    def __init__ (self, name="T2CaloTauValidationMonitoring"):
+        super(T2CaloTauValidationMonitoring, self).__init__(name)
+        self.defineTarget("Validation")
+
+########## ##############################################################
+#  add cosmic specific histograms. 
+#
+#########################################################################
+class T2CaloTauCosmicMonitoring(T2CaloTauOnlineMonitoring):
+    def __init__ (self, name="T2CaloTauCosmicMonitoring"):
+        super(T2CaloTauCosmicMonitoring, self).__init__(name)
+        self.defineTarget("Cosmic")
+
+        self.Histograms += [ defineHistogram('EtaL2vsL1', type='TH1F', title="L2CaloTau FEX Eta_L2 - Eta_L1; dEta; nevents", xbins=40, xmin=-0.4, xmax=0.4) ]
+        self.Histograms += [ defineHistogram('PhiL2vsL1', type='TH1F', title="L2CaloTau FEX Phi_L2 - Phi_L1; dPhi; nevents", xbins=40, xmin=-0.4, xmax=0.4) ]
+        self.Histograms += [ defineHistogram('EMFraction', type='TH1F', title="L2CaloTau FEX EM Energy Fraction;EMFraction; nevents",xbins=90, xmin=-0.6, xmax=1.2) ]
+        self.Histograms += [ defineHistogram('EMEnMedium', type='TH1F', title="L2CaloTau FEX EMEnMedium in (dR<0.3) cone;EMEnMedium [MeV]; nevents", xbins=54, xmin=-12000, xmax=150000) ]
+        self.Histograms += [ defineHistogram('HADEnMedium', type='TH1F', title="L2CaloTau FEX HADEnMedium in (dR<0.3) cone;HADEnMedium [MeV]; nevents", xbins=54, xmin=-12000, xmax=150000) ]
+        self.Histograms += [ defineHistogram('EMEnNarrow', type='TH1F', title="L2CaloTau FEX EMEnNarrow in (dR<0.1) cone;EMEnNarrow [MeV]; nevents", xbins=54, xmin=-12000, xmax=150000) ]
+        self.Histograms += [ defineHistogram('HADEnNarrow', type='TH1F', title="L2CaloTau FEX HADEnNarrow in (dR<0.1) cone;HADEnNarrow [MeV]; nevents", xbins=54, xmin=-12000, xmax=150000) ]
+
+class TrigT2CaloTauTimeMonitoring(TrigGenericMonitoringToolConfig) :
+	   def __init__ (self, name="TrigT2CaloTauTimeMonitoring"):
+	      super(TrigT2CaloTauTimeMonitoring,self).__init__(name)
+	      self.defineTarget("Time")
+	     
+	      types_list=['Total','RegSel','BSCnv','Algor','SaveEM']
+	      tools_list=['ESamp2','ESamp1','EaEmEn','EHadEn']
+	      for tool in tools_list:
+	         for type in types_list:
+	             hist_title=tool+type
+	             thismax=1.0
+	             if ( (type.find("RegSel")>-1) or (type.find("SaveEM")>-1) ):
+	                thismax=0.2
+	             if ( (type.find("Algor")>-1) ):
+	                thismax=0.5
+	             self.Histograms+= [defineHistogram (hist_title,
+	                                            type='TH1F',title=hist_title
+	                                            ,xbins=40,xmin=0.0,xmax=thismax)]
+	      self.Histograms+= [defineHistogram ('TotalTime',
+	                                            type='TH1F',title=hist_title
+	                                            ,xbins=50,xmin=0.0,xmax=5)]
+	      self.Histograms += [ defineHistogram('Eta, TotalTime',
+	                type='TH2F', title="#eta vs. time", xbins=50, xmin=-2.5,
+	                xmax=2.5, ybins=50, ymin=0, ymax=5) ]
diff --git a/Trigger/TrigAlgorithms/TrigT2CaloTau/src/T2CaloTau.cxx b/Trigger/TrigAlgorithms/TrigT2CaloTau/src/T2CaloTau.cxx
new file mode 100755
index 00000000000..96585af816d
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigT2CaloTau/src/T2CaloTau.cxx
@@ -0,0 +1,647 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ********************************************************************
+// 
+// NAME:     T2CaloTau.cxx
+// PACKAGE:  Trigger/TrigAlgorithms/TrigT2CaloTau
+// 
+// AUTHOR:   M.P. Casado
+//           S.R. Armstrong
+// updates: 3/3/11 ccuenca, added new vars for monitoring
+// 
+// - Add variables for job option controlled region limits, set defaults
+//   to most likely values.
+// - Add function EtaPhiRange to return the maximum and minimum eta or phi
+//   values to use when calculating energy sums over a region  - R. Soluk
+// ********************************************************************
+
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/IToolSvc.h"
+#include "GaudiKernel/StatusCode.h"
+#include "GaudiKernel/ITHistSvc.h"
+
+#include "TrigT1Interfaces/RecEmTauRoI.h"
+#include "TrigT1Interfaces/TrigT1Interfaces_ClassDEF.h"
+#include "TrigSteeringEvent/TrigRoiDescriptor.h"                               
+
+#include "CaloEvent/CaloCluster.h"
+#include "CaloEvent/CaloClusterContainer.h"
+#include "TrigCaloEvent/TrigTauCluster.h"
+#include "TrigCaloEvent/TrigTauClusterDetails.h"
+#include "TrigCaloEvent/TrigTauClusterDetailsContainer.h"
+
+#include "TrigT2CaloCommon/T2CaloBase.h"
+#include "TrigT2CaloCommon/IAlgToolCalo.h"
+#include "TrigT2CaloCommon/phiutils.h"
+#include "TrigT2CaloTau/T2CaloTau.h"
+
+//#include <TH1F.h>
+#include "AthenaKernel/errorcheck.h"
+
+#define NEG_ENERGY_CLUSTER HLT::Reason::USERDEF_1
+#define NULL_ENERGY_SAMPLING HLT::Reason::USERDEF_2
+
+class ISvcLocator;
+
+T2CaloTau::T2CaloTau(const std::string & name, ISvcLocator* pSvcLocator) : T2CaloBase(name, pSvcLocator),
+    m_storeCells(false),
+    m_updateRoiDescriptor(false),
+    m_phiWidthEM(0.4), 
+    m_etaWidthEM(0.4)
+{
+
+    //properties
+    declareProperty("TrigTauClusterKey",   m_trigTauClusterKey = "T2CaloTrigTauCluster");
+
+    declareProperty("StoreCells",          m_storeCells,"store cells in container attached to RoI");
+    declareProperty("updateRoiDescriptor", m_updateRoiDescriptor, "option to update RoiDescriptor after execution");
+    declareProperty("PhiWidthEM",          m_phiWidthEM, "phi width EM calo");
+    declareProperty("EtaWidthEM",          m_etaWidthEM, "eta width EM calo");
+
+    //Monitored variables
+    declareMonitoredVariable("EMRadius", m_EMRadius);
+    declareMonitoredVariable("EMRadius3S", m_EMRadius3S);
+    declareMonitoredVariable("CaloRadius", m_CaloRadius);
+    declareMonitoredVariable("HadRad", m_HadRad);
+    
+    declareMonitoredVariable("IsoFrac", m_IsoFrac);
+    declareMonitoredVariable("StripWidth", m_StripWidth);
+    
+    declareMonitoredVariable("EMFraction", m_EMFraction);
+    
+    //Wide, cone 0.3 (Wide in TrigTauClusterDetails)
+    declareMonitoredVariable("EtRawWide", m_EtRawWide);
+    
+    //Medium, cone 0.2 (Medium in TrigTauClusterDetails)
+    declareMonitoredVariable("EMEnMedium", m_EMEnMedium);
+    declareMonitoredVariable("HADEnMedium", m_HADEnMedium);
+    
+    //Narrow, cone 0.1 (Narrow in TrigTauClusterDetails)
+    declareMonitoredVariable("EMEnNarrow", m_EMEnNarrow);
+    declareMonitoredVariable("HADEnNarrow", m_HADEnNarrow);
+    
+    declareMonitoredVariable("EtRawMedium",     m_EtRawMedium);
+    declareMonitoredVariable("EtRawMediumEM0",  m_EtRawMediumEM0);
+    declareMonitoredVariable("EtRawMediumEM1",  m_EtRawMediumEM1);
+    declareMonitoredVariable("EtRawMediumEM2",  m_EtRawMediumEM2);
+    declareMonitoredVariable("EtRawMediumEM3",  m_EtRawMediumEM3);
+    declareMonitoredVariable("EtRawMediumHad0", m_EtRawMediumHad0);
+    declareMonitoredVariable("EtRawMediumHad1", m_EtRawMediumHad1);
+    declareMonitoredVariable("EtRawMediumHad2", m_EtRawMediumHad2);
+
+
+    //EtNarrow/EtWide ratio
+    declareMonitoredVariable("CoreFraction",     m_CoreFraction);
+
+    declareMonitoredVariable("EtaL1",            m_EtaL1);
+    declareMonitoredVariable("PhiL1",            m_PhiL1);
+    declareMonitoredVariable("Eta",              m_Eta);
+    declareMonitoredVariable("Phi",              m_Phi);
+    declareMonitoredVariable("dEtaL2Tau_RoI",    m_dEtaL2Tau_RoI);
+    declareMonitoredVariable("dPhiL2Tau_RoI",    m_dPhiL2Tau_RoI);
+
+    declareMonitoredVariable("ConversionErrors", m_conversionError);
+    declareMonitoredVariable("AlgorithmErrors",  m_algorithmError);
+
+    declareMonitoredStdContainer("Quality", m_quality);
+}
+
+T2CaloTau::~T2CaloTau()
+{
+}
+
+HLT::ErrorCode T2CaloTau::hltInitialize()
+{
+    //  MsgStream log(msgSvc(), name());
+
+    //  IToolSvc* toolSvc;
+    //  service("ToolSvc",toolSvc);
+
+    ToolHandleArray<IAlgToolCalo>::iterator it = m_emAlgTools.begin();
+    for(; it != m_emAlgTools.end(); ++it)
+    {
+        StatusCode sc = it->retrieve();
+        if(sc.isFailure())
+        {
+            msg() << MSG::ERROR << "Unable to initialize tool " << *it << endreq;
+            return HLT::BAD_ALGO_CONFIG ;
+        }
+        if(msgLvl() <= MSG::DEBUG)
+        {
+            msg() << MSG::DEBUG << "REGTEST: Created " << *it << " AlgTool" << endreq;
+        }
+        (*it)->setCellContainerPointer(&m_Container);
+    }
+
+    if(msgLvl() <= MSG::DEBUG)
+    {
+        if(m_updateRoiDescriptor)
+        {
+            msg() << MSG::DEBUG << "REGTEST: TrigRoiDescriptor will be updated " << endreq;
+        }
+        else
+        {
+            msg() << MSG::DEBUG << "REGTEST: TrigRoiDescriptor will NOT be updated " << endreq;
+        }
+    }
+
+    if(m_storeCells && msgLvl() <= MSG::DEBUG)
+    {
+        msg() << MSG::DEBUG << "REGTEST: will store cells in output " << endreq;
+    }
+
+    return HLT::OK;
+}
+
+HLT::ErrorCode T2CaloTau::hltFinalize()
+{
+    if(msgLvl() <= MSG::DEBUG)
+    {
+        msg() << MSG::DEBUG << " hltFinalize is done" << endreq;
+    }
+    return HLT::OK;
+}
+
+HLT::ErrorCode T2CaloTau::hltExecute(const HLT::TriggerElement* inputTE, HLT::TriggerElement* outputTE)
+{
+    // Time total T2Calo execution time.
+    if(timerSvc()) m_timer[0]->start();      
+
+    m_conversionError = 0;
+    m_algorithmError = 0;
+    // reset quality vector for monitoring
+    m_quality.clear();
+
+    m_EMRadius = -99.0;
+    m_EMRadius3S = -99.0;
+    m_CaloRadius = -99.0;
+    m_HadRad = -99.0;
+
+    m_IsoFrac = -99.0;
+    m_StripWidth = -99.0;
+
+    m_EMFraction = -99.0;
+
+    m_EtRawWide = -99.0;
+
+    m_EMEnMedium = -99.0;
+    m_HADEnMedium = -99.0;
+
+    m_EMEnNarrow = -99.0;
+    m_HADEnNarrow = -99.0;
+
+    m_EtRawMedium = -99.0;
+    m_EtRawMediumEM0 = -99.0;
+    m_EtRawMediumEM1 = -99.0;
+    m_EtRawMediumEM2 = -99.0;
+    m_EtRawMediumEM3 = -99.0;
+    m_EtRawMediumHad0 = -99.0;
+    m_EtRawMediumHad1 = -99.0;
+    m_EtRawMediumHad2 = -99.0;
+
+    m_CoreFraction = -99.0;
+
+    m_EtaL1 = -99.0;
+    m_PhiL1 = -99.0;
+    m_Eta = -99.0;
+    m_Phi = -99.0;
+    m_dEtaL2Tau_RoI = -99.0;
+    m_dPhiL2Tau_RoI = -99.0;  
+
+
+#ifndef NDEBUG
+    if(msgLvl() <= MSG::DEBUG)
+    {
+        msg() << MSG::INFO << "in execute()" << endreq;
+    }
+#endif
+
+    // Some debug output:
+#ifndef NDEBUG
+    if(msgLvl() <= MSG::DEBUG)
+    {
+        msg() << MSG::DEBUG << "output TE ID: " << outputTE->getId() << endreq;
+    }
+#endif
+
+    // Some debug output:
+#ifndef NDEBUG
+    if(msgLvl() <= MSG::DEBUG)
+    {
+        msg() << MSG::DEBUG << "input TE ID: " << inputTE->getId() << endreq;
+    }
+#endif
+    const TrigRoiDescriptor* roiDescriptor = 0;
+    HLT::ErrorCode st = getFeature(inputTE, roiDescriptor);  
+
+    if(st == HLT::OK && roiDescriptor)
+    {
+#ifndef NDEBUG // Will not be executed in optimised build                               
+        if(msgLvl() <= MSG::DEBUG)
+        {        
+            msg() << MSG::DEBUG  << " RoI id " << roiDescriptor->roiId() 
+                  << " LVL1 id " << roiDescriptor->l1Id() 
+		  << *roiDescriptor << endreq;
+	    //                  << " located at   phi = " <<  roiDescriptor->phi0() 
+            //      << ", eta = " << roiDescriptor->eta0() << endreq;
+        }
+#endif
+    }
+    else
+    {
+        msg() <<  MSG::WARNING << " Failed to find RoiDescriptor " << endreq;
+        return HLT::ERROR;
+    }
+
+    // Some debug output:
+
+    if(msgLvl() <= MSG::DEBUG)
+    {
+        msg() << MSG::DEBUG  << "Message to count events. LVL1 phi="
+              << roiDescriptor->phi()
+              << " & LVL1 eta="
+              << roiDescriptor->eta() << " " << roiDescriptor
+              << endreq;
+    }
+
+
+    // End LVL1 part
+    //    double RoIeta = roiDescriptor->eta();
+    //    double RoIphi = roiDescriptor->phi();
+
+    const TrigTauClusterDetails * pDetails= new TrigTauClusterDetails();
+
+    std::string key = "";  
+    HLT::ErrorCode  hltstatusD = recordAndAttachFeature(outputTE, pDetails, key, "TrigT2CaloTauDetails");
+    if(hltstatusD != HLT::OK)
+    {
+        if (msgLvl() <= MSG::DEBUG)
+        {
+            msg() << MSG::ERROR << "Write of TrigTauClusterDetails into outputTE failed" << endreq;
+        }
+        return hltstatusD;
+    }
+
+    // retrieve TrigTauClusterDetails from the TE
+    ElementLink< TrigTauClusterDetailsContainer > ELDetails;
+    HLT::ErrorCode stat = getFeatureLink< TrigTauClusterDetailsContainer, TrigTauClusterDetails >( outputTE, ELDetails );
+
+    if(stat == HLT::OK && ELDetails.isValid())
+    {
+        if(msgLvl() <= MSG::DEBUG)
+        { 
+            (*ELDetails)->print(msg()); 
+        }
+    }
+    else
+    {
+        if(msgLvl() <= MSG::DEBUG)
+        { 
+            msg() << MSG::DEBUG << "Failed to get TrigTauClusterDetails" << endreq; 
+        }
+        return HLT::MISSING_FEATURE;
+    }
+
+    TrigTauCluster* ptrigTauCluster = new TrigTauCluster(ELDetails.getStorableObjectPointer(), ELDetails.index(), 0.0, -10.0, -10.0, 0);
+    // Energies, EMRadius and other variables are initialized at the 
+    // TrigTauCluster creation time.
+
+    // Add RoI word to TrigTauCluster
+    ptrigTauCluster->setRoIword(roiDescriptor->roiWord());
+
+    // zeros the container per RoI
+    m_Container = 0;
+
+    HLT::ErrorCode ToolStat = HLT::OK; // define flag to monitor problems with tools without stopping the sequence.
+
+
+    /// generate the new roiDescriptor with the correct sizes
+
+    const TrigRoiDescriptor* _roi = roiDescriptor; 
+
+    TrigRoiDescriptor* roi   = new TrigRoiDescriptor( _roi->eta(), _roi->eta()-m_etaWidth, _roi->eta()+m_etaWidth,
+						      _roi->phi(), HLT::wrap_phi(_roi->phi()-m_phiWidth), HLT::wrap_phi(_roi->phi()+m_phiWidth) );
+
+    /// this isn't needed 
+    //  TrigRoiDescriptor* roiEM = new TrigRoiDescriptor( _roi->eta(), _roi->eta()-m_etaWidthEM, _roi->eta()+m_etaWidthE<,
+    //	  					          _roi->phi(), HLT::wrap_phi(_roi->phi()-m_phiWidthEM), HLT::wrap_phi(_roi->phi()+m_phiWidthEM) );
+
+    msg() << MSG::DEBUG << "Using RoIs " << *roi << endreq;
+
+    ToolHandleArray<IAlgToolCalo>::iterator it = m_emAlgTools.begin();
+    if(timerSvc()) m_timer[1]->start();
+    uint32_t error = 0;
+    for(; it < m_emAlgTools.end(); it++)
+    {
+        //        HLT::ErrorCode stat = (*it)->execute(*ptrigTauCluster, m_phiWidth, m_etaWidth, m_phiWidthEM, m_etaWidthEM, RoIeta, RoIphi);
+        //       HLT::ErrorCode stat = (*it)->execute(*ptrigTauCluster, *roi, *roiEM );
+        HLT::ErrorCode stat = (*it)->execute(*ptrigTauCluster, *roi );
+        if(stat.reason() == NEG_ENERGY_CLUSTER)
+        {
+            msg() << MSG::DEBUG << (*it)->name() << " Found a cluster with E~<=0. CONTINUE execution. " << endreq;
+            // do not forget to delete trigTauCluster of attach it to storegate if return
+            // return  stat; // uncomment to avaid running on the remaining tools.
+            ToolStat = stat;
+        }
+        if(stat.reason() == NULL_ENERGY_SAMPLING)
+        {
+            msg() << MSG::DEBUG << (*it)->name() << " Found E==0 in this sampling. CONTINUE execution. " << endreq;
+            // do not forget to delete trigTauCluster of attach it to storegate if return
+            // return  stat; // uncomment to avaid running on the remaining tools.
+            ToolStat = stat;
+            // since userdefined errors are not monitored (reason=continue)
+            // fill our own variable with T2CaloTau related errors
+        }
+        if(stat == HLT::TOOL_FAILURE)
+        {
+            msg() << MSG::WARNING << "T2CaloTau AlgTool " << (*it)->name() << "  returned Failure" << endreq;
+            // if tool has returned this failure, then loadingCollection has failed and it
+            // does not make sense to keep this TrigTauCluster - we would not learn anything from it
+            delete ptrigTauCluster;
+            delete pDetails;	
+            return  stat;
+        }
+        uint32_t in_error = (*it)->report_error();
+        if(0x0FFF00FF & in_error) m_conversionError++;
+        if(0xF0000000 & in_error) m_algorithmError++;
+
+        error |= in_error;
+    }
+
+    // convert bits into fixed-size vector variable for error monitoring
+    TAUCLUSTMON::FillErrorMonitoring(error, &m_quality);
+    // Fill ALLCLUST bin for all clusters, so we can know the relative importance of each error with this normalization.
+    m_quality.push_back(TAUCLUSTMON::ALLCLUST);
+    // Fill GOODCLUST for clusters without errors
+    if(!error) m_quality.push_back(TAUCLUSTMON::GOODCLUST);
+
+    // OI  Now, ensure that phi is [-pi,pi] indepedent on what tools do...
+    while(ptrigTauCluster->phi() < -M_PI) ptrigTauCluster->setPhi(ptrigTauCluster->phi() + 2.0 * M_PI);
+    while(ptrigTauCluster->phi() >  M_PI) ptrigTauCluster->setPhi(ptrigTauCluster->phi() - 2.0 * M_PI);
+
+    // 
+    // Get L1 RoiDescriptor
+    const TrigRoiDescriptor* roiL1Descriptor = 0;
+    HLT::ErrorCode tmpStatus = getFeature( inputTE, roiL1Descriptor, "initialRoI" );
+
+    //Fill monitored variables
+    const TrigTauClusterDetails* clusterDetails = ptrigTauCluster->clusterDetails();
+    double coshEta = cosh(ptrigTauCluster->eta());
+
+    m_EMRadius    = clusterDetails->EMRadius(2);
+    m_EMRadius3S  = ptrigTauCluster->EMRadius3S();
+    m_CaloRadius  = ptrigTauCluster->CaloRadius();
+    m_HadRad      = ptrigTauCluster->HadRadius();
+    m_IsoFrac     = ptrigTauCluster->IsoFrac();
+    m_StripWidth  = ptrigTauCluster->stripWidth();
+    m_EMFraction  = ptrigTauCluster->EMFrac();
+
+    //wide: cone 0.3 -> wide at TrigTauClusterDetails
+    m_EtRawWide = (clusterDetails->EMenergyWide(0)
+                + clusterDetails->EMenergyWide(1)
+                + clusterDetails->EMenergyWide(2)
+                + clusterDetails->EMenergyWide(3)
+                + clusterDetails->HADenergyWide(0)
+                + clusterDetails->HADenergyWide(1)
+                + clusterDetails->HADenergyWide(2)) / coshEta;
+
+    //medium: cone 0.2 -> medium at TrigTauClusterDetails. In previus version of the code, Wide instead of Medium
+    m_EMEnMedium = clusterDetails->EMenergyMedium(0)
+               + clusterDetails->EMenergyMedium(1)
+               + clusterDetails->EMenergyMedium(2)
+               + clusterDetails->EMenergyMedium(3); 
+    m_HADEnMedium = clusterDetails->HADenergyMedium(0)
+                + clusterDetails->HADenergyMedium(1)
+                + clusterDetails->HADenergyMedium(2);
+
+    //narrow: cone 0.1 -> narrow at TrigTauClusterDetails
+    m_EMEnNarrow = clusterDetails->EMenergyNarrow(0)
+                 + clusterDetails->EMenergyNarrow(1)
+                 + clusterDetails->EMenergyNarrow(2)
+                 + clusterDetails->EMenergyNarrow(3);
+    m_HADEnNarrow = clusterDetails->HADenergyNarrow(0)
+                  + clusterDetails->HADenergyNarrow(1)
+                  + clusterDetails->HADenergyNarrow(2);
+
+    m_EtRawMediumEM0 = clusterDetails->EMenergyMedium(0) / coshEta;
+    m_EtRawMediumEM1 = clusterDetails->EMenergyMedium(1) / coshEta;
+    m_EtRawMediumEM2 = clusterDetails->EMenergyMedium(2) / coshEta;
+    m_EtRawMediumEM3 = clusterDetails->EMenergyMedium(3) / coshEta;
+    m_EtRawMediumHad0 = clusterDetails->HADenergyMedium(0) / coshEta;
+    m_EtRawMediumHad1 = clusterDetails->HADenergyMedium(1) / coshEta;
+    m_EtRawMediumHad2 = clusterDetails->HADenergyMedium(2) / coshEta;
+
+    m_EtRawMedium = m_EtRawMediumEM0 + m_EtRawMediumEM1 + m_EtRawMediumEM2 + m_EtRawMediumEM3 + m_EtRawMediumHad0 + m_EtRawMediumHad1 + m_EtRawMediumHad2;
+
+    m_CoreFraction = ptrigTauCluster->CoreFrac();
+
+    m_Eta = ptrigTauCluster->eta();
+    m_Phi = ptrigTauCluster->phi();
+    if(roiL1Descriptor)
+    {
+        m_EtaL1 = roiL1Descriptor->eta();
+        m_PhiL1 = roiL1Descriptor->phi();
+    }
+
+    m_dEtaL2Tau_RoI = m_Eta - m_EtaL1;
+    m_dPhiL2Tau_RoI = m_Phi - m_PhiL1;
+    //   m_dEtaL2Tau_RoI = ptrigTauCluster->eta() - roiL1Descriptor->eta0();
+    //   m_dPhiL2Tau_RoI = ptrigTauCluster->phi() - roiL1Descriptor->phi0();
+
+    if(m_dPhiL2Tau_RoI > M_PI)  m_dPhiL2Tau_RoI -= 2 * M_PI;
+    if(m_dPhiL2Tau_RoI < -M_PI) m_dPhiL2Tau_RoI += 2 * M_PI;
+
+
+    if(m_EtRawWide > 495000.) m_EtRawWide = 499000.;
+
+    if(m_EMEnMedium > 495000.) m_EMEnMedium = 499000.;
+    if(m_HADEnMedium > 495000.) m_HADEnMedium = 499000.;
+
+    if(m_EMEnNarrow > 495000.) m_EMEnNarrow = 499000.;
+    if(m_HADEnNarrow > 495000.) m_HADEnNarrow = 499000.;
+
+    if(m_EtRawMedium > 495000.) m_EtRawMedium = 499000.;
+    if(m_EtRawMediumEM0 > 495000.) m_EtRawMediumEM0 = 499000.;
+    if(m_EtRawMediumEM1 > 495000.) m_EtRawMediumEM1 = 499000.;
+    if(m_EtRawMediumEM2 > 495000.) m_EtRawMediumEM2 = 499000.;
+    if(m_EtRawMediumEM3 > 495000.) m_EtRawMediumEM3 = 499000.;
+    if(m_EtRawMediumHad0 > 495000.) m_EtRawMediumHad0 = 499000.;
+    if(m_EtRawMediumHad1 > 495000.) m_EtRawMediumHad1 = 499000.;
+    if(m_EtRawMediumHad2 > 495000.) m_EtRawMediumHad2 = 499000.;
+
+    // Cluster quality is a collection of possible errors
+    // No error => quality=0
+    ptrigTauCluster->setquality(error);
+
+    if(timerSvc()) m_timer[1]->stop();
+
+
+    if(msgLvl() <= MSG::DEBUG)
+    {
+        // Print out Cluster produced
+        //    msg() << MSG::DEBUG << "TEST-TEST-TEST-TEST" << endreq;
+        msg() << MSG::DEBUG << " REGTEST: eta/phi = "<< m_Eta << "/" << m_Phi << endreq;
+        //msg() << MSG::DEBUG << " REGTEST: etaL1/phiL1 = "<< m_EtaL1 << "/" << m_PhiL1 << endreq;
+        msg() << MSG::DEBUG << " REGTEST: EMenergy0Narrow/Medium/Wide = "<< (*ptrigTauCluster).clusterDetails()->EMenergyNarrow(0) 
+              << "/" << (*ptrigTauCluster).clusterDetails()->EMenergyMedium(0) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->EMenergyWide(0) << endreq;
+        msg() << MSG::DEBUG << " REGTEST: EMenergy1Narrow/Medium/Wide = "
+              << (*ptrigTauCluster).clusterDetails()->EMenergyNarrow(1) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->EMenergyMedium(1) << "/"
+              << (*ptrigTauCluster).clusterDetails()->EMenergyWide(1) << endreq;
+        msg() << MSG::DEBUG << " REGTEST: EMenergy2Narrow/Medium/Wide = "
+              << (*ptrigTauCluster).clusterDetails()->EMenergyNarrow(2) << "/"
+              << (*ptrigTauCluster).clusterDetails()->EMenergyMedium(2) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->EMenergyWide(2) <<  endreq;
+        msg() << MSG::DEBUG << " REGTEST: EMenergy3Narrow/Medium/Wide = "
+              << (*ptrigTauCluster).clusterDetails()->EMenergyNarrow(3) << "/"
+              << (*ptrigTauCluster).clusterDetails()->EMenergyMedium(3) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->EMenergyWide(3) << endreq;
+        msg() << MSG::DEBUG << " REGTEST: HADenergy0Narrow/Medium/Wide = "
+              << (*ptrigTauCluster).clusterDetails()->HADenergyNarrow(0) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->HADenergyMedium(0) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->HADenergyWide(0) << endreq;
+        msg() << MSG::DEBUG << " REGTEST: HADenergy1Narrow/Medium/Wide = "
+              << (*ptrigTauCluster).clusterDetails()->HADenergyNarrow(1) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->HADenergyMedium(1) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->HADenergyWide(1) << endreq;
+        msg() << MSG::DEBUG << " REGTEST: HADenergy2Narrow/Medium/Wide = "
+              << (*ptrigTauCluster).clusterDetails()->HADenergyNarrow(2) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->HADenergyMedium(2) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->HADenergyWide(2) << endreq;
+
+        msg() << MSG::DEBUG << " REGTEST: EMRadius0/1/2/3 = "
+              << (*ptrigTauCluster).clusterDetails()->EMRadius(0) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->EMRadius(1) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->EMRadius(2) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->EMRadius(3) << endreq;
+
+        msg() << MSG::DEBUG << " REGTEST: HADRadius0/1/2 = "
+              << (*ptrigTauCluster).clusterDetails()->HADRadius(0) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->HADRadius(1) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->HADRadius(2) << endreq;
+
+        msg() << MSG::DEBUG << " REGTEST: EMenergyWidth0/1/2/3 = "
+              << (*ptrigTauCluster).clusterDetails()->EMenergyWidth(0) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->EMenergyWidth(1) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->EMenergyWidth(2) << "/" 
+              << (*ptrigTauCluster).clusterDetails()->EMenergyWidth(3) << endreq;
+
+        msg() << MSG::DEBUG << " REGTEST: EMenergy/Hadenergy =  "
+              << (*ptrigTauCluster).EMenergy() << "/" 
+              << (*ptrigTauCluster).HADenergy() << "/" 
+              <<  endreq;
+        msg() << MSG::DEBUG << " REGTEST: numStripCells/stripWidth/IsoFrac = "
+              << (*ptrigTauCluster).numStripCells() << "/" 
+              << (*ptrigTauCluster).stripWidth() << "/"
+              << m_IsoFrac << endreq;
+        msg() << MSG::DEBUG << " REGTEST: RoIWord = "
+              << (*ptrigTauCluster).RoIword() << endreq;
+    }  
+
+    //// From egamma. This is already done inside the tools for tau! but maybe would like to change at some point...
+    //  if ( error ) {
+    //    // Clustering failed. Transmit ahead L1
+    //    ptrigTauCluster->setEta(etaL1);
+    //    ptrigTauCluster->setPhi(phiL1);
+    //    ptrigTauCluster->setEnergy(0.0);
+    //  }
+
+    key = "";
+    HLT::ErrorCode hltstatus = recordAndAttachFeature(outputTE, ptrigTauCluster, key, "TrigT2CaloTau");
+    if(hltstatus != HLT::OK)
+    {
+        if (msgLvl() <= MSG::DEBUG)
+        {
+            msg() << MSG::ERROR << "Write of TrigTauCluster into outputTE failed" << endreq;
+        }
+        return hltstatus;
+    }
+
+    if(m_storeCells)
+    {
+        if(m_Container != 0)
+        {
+            HLT::ErrorCode hltstatus = recordAndAttachFeature(outputTE, m_Container, key, "TrigT2CaloTauCells");
+            if(msgLvl() <= MSG::DEBUG)
+            {
+                msg() << MSG::DEBUG << " recorded " <<  m_Container->size() << " cells "<< endreq;
+            }
+            if(hltstatus != HLT::OK)
+            {
+#ifndef NDEBUG
+                if(msgLvl() <= MSG::DEBUG)
+                {
+                    msg() << MSG::ERROR << "Write of TrigTauClusterCells into outputTE failed" << endreq;
+                }
+#endif
+                if(m_timersvc) m_timer[0]->stop();
+                return hltstatus;
+            }
+        } // End of if to check whether there is a container
+    } // End of if to check the option is ok
+
+    // Create a new RoiDescriptor with updated eta and phi.
+    // Note that the steering will propagate l1Id and roiId automatically
+    // so no need to set them.
+
+    if(m_updateRoiDescriptor)
+    {
+
+      /// what size should we create this roi with ??? 
+      /// use some new parameters
+      
+      double _eta = ptrigTauCluster->eta();
+      double _phi = ptrigTauCluster->phi();
+      
+      TrigRoiDescriptor* newRoiDescriptor   = new TrigRoiDescriptor( roiDescriptor->roiWord(), 
+								     roiDescriptor->l1Id(), 
+								     roiDescriptor->roiId(), 
+								     _eta, _eta-m_etaWidthForID, _eta+m_etaWidthForID,
+								     _phi, HLT::wrap_phi(_phi-m_phiWidthForID), HLT::wrap_phi(_phi+m_phiWidthForID) );
+    
+      /// obsolete constructor 
+      //      TrigRoiDescriptor* newRoiDescriptor = new TrigRoiDescriptor(roiDescriptor->roiWord(), 
+      //								  roiDescriptor->l1Id(), 
+      //								  roiDescriptor->roiId(), 
+      //								  ptrigTauCluster->eta(), 
+      //								  ptrigTauCluster->phi());
+
+        if(msgLvl() <= MSG::DEBUG)
+        {
+            msg() << MSG::DEBUG  << "Recorded an RoiDescriptor "
+                  << " phi " << newRoiDescriptor->phi()
+                  << " eta " << newRoiDescriptor->eta() << "  " << *newRoiDescriptor << endreq;
+        }
+
+        hltstatus = attachFeature(outputTE, newRoiDescriptor, "TrigT2CaloTau"); 
+
+        if(hltstatus != HLT::OK)
+        {
+            if(msgLvl() <= MSG::DEBUG)
+            {
+                msg() << MSG::ERROR << "Write of newRoiDescriptor into outputTE failed" << endreq;
+            }
+            return hltstatus;
+        }
+    }
+    // Some debug output:
+#ifndef NDEBUG
+    if(msgLvl() <= MSG::DEBUG)
+    {
+        msg() << MSG::DEBUG
+              << "We assume success, set TE with id "
+              << outputTE->getId()
+              << " active to signal positive result."
+              << endreq;
+    }
+#endif
+
+    // Time total T2CaloT2Calo execution time.
+    if(timerSvc()) m_timer[0]->stop();      
+
+    //return HLT::OK;
+    return ToolStat;
+}
diff --git a/Trigger/TrigAlgorithms/TrigT2CaloTau/src/TauAllCaloDRFex.cxx b/Trigger/TrigAlgorithms/TrigT2CaloTau/src/TauAllCaloDRFex.cxx
new file mode 100644
index 00000000000..d6dbb06c565
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigT2CaloTau/src/TauAllCaloDRFex.cxx
@@ -0,0 +1,1186 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ********************************************************************
+//
+// NAME:     TauAllCaloDRFex.cxx
+// PACKAGE:  Trigger/TrigAlgorithms/TrigT2CaloTau
+//
+// AUTHOR:   Olga Igonkina (Nikhef), M. Pilar Casado (IFAE), Mogens Dam (NBI)
+//           based on TauEmEnFex.cxx
+//
+// CREATED: Jun-09
+//
+// DESCRIPTION: Tool to compute LVL2 Calo tau variables at
+//              EM sampling 2
+// ********************************************************************
+
+#include "CaloIdentifier/LArEM_ID.h"
+
+#include "CaloEvent/CaloCluster.h"
+#include "TrigCaloEvent/TrigTauCluster.h"
+#include "TrigCaloEvent/TrigTauClusterDetails.h"
+#include "CaloGeoHelpers/CaloSampling.h"
+
+#include "TrigT2CaloTau/TauAllCaloDRFex.h"
+#include "TrigT2CaloCommon/Calo_Def.h"
+#include "TrigSteeringEvent/Enums.h"
+
+#define NEG_ENERGY_CLUSTER HLT::Reason::USERDEF_1
+#define NULL_ENERGY_SAMPLING HLT::Reason::USERDEF_2
+
+TauAllCaloDRFex::TauAllCaloDRFex(const std::string& type, const std::string& name, const IInterface* parent) : IAlgToolCalo(type, name, parent)
+{
+    declareProperty("StripEthr",      m_stripEthr);
+    declareProperty("dRSeed",         m_dRSeed,         "dR cut for reconstruction of the seed ");    
+    declareProperty("CaloNoiseTool",  m_noiseTool,      "Tool Handle for noise tool");
+    declareProperty("applyNoiseCut",  m_applyNoiseCut,  "swithch on/off noise suppression");
+    declareProperty("noiseNSigmaCut", m_noiseNSigmaCut, "number of sigmas for 2 sided noise substraction");
+    declareProperty("hecQualityCut",  m_hecQualityCut,  "Control for HEC Quality");
+    declareProperty("defaultWidth",   m_defaultWidth,   "default width to be saved");
+    declareProperty("dRConeNarrow",   m_dRConeNarrow,   "dR cut for full region (Narrow) ");
+    declareProperty("dRConeMedium",   m_dRConeMedium,   "dR cut for full region (Medium) ");
+    declareProperty("dRConeWide",     m_dRConeWide,     "dR cut for full region (Wide) ");
+    m_saveCells = false;
+}
+
+TauAllCaloDRFex::~TauAllCaloDRFex()
+{
+}
+
+StatusCode TauAllCaloDRFex::initialize()
+{
+  StatusCode sc = IAlgToolCalo::initialize();
+  if( sc.isFailure() ) return sc;
+  (*m_log)  << MSG::INFO << "REGTEST initialized with:" << endreq;
+  (*m_log)  << MSG::INFO << "REGTEST dRSeed="           << m_dRSeed         << endreq;
+  (*m_log)  << MSG::INFO << "REGTEST StripEthr="        << m_stripEthr      << endreq;
+  (*m_log)  << MSG::INFO << "REGTEST CaloNoiseTool="    << m_noiseTool      << endreq;
+  (*m_log)  << MSG::INFO << "REGTEST applyNoiseCut="    << m_applyNoiseCut  << endreq;
+  (*m_log)  << MSG::INFO << "REGTEST noiseNSigmaCut="   << m_noiseNSigmaCut << endreq;
+  (*m_log)  << MSG::INFO << "REGTEST hecQualityCut="    << m_hecQualityCut  << endreq;
+  (*m_log)  << MSG::INFO << "REGTEST defaultWidth="     << m_defaultWidth   << endreq;
+  (*m_log)  << MSG::INFO << "REGTEST dRConeNarrow="     << m_dRConeNarrow   << endreq;
+  (*m_log)  << MSG::INFO << "REGTEST dRConeMedium="     << m_dRConeMedium   << endreq;
+  (*m_log)  << MSG::INFO << "REGTEST dRConeWide="       << m_dRConeWide     << endreq;
+  
+  if(   m_saveCells && (*m_log).level() <= MSG::DEBUG )
+    (*m_log) << MSG::DEBUG << "REGTEST: store cells with Et> " << m_cellkeepthr << endreq;
+  
+  if ( !m_timersvc.empty() )
+    {     
+      m_timer[0] = m_timersvc->addItem("T2CaloTau.Tools.Total");
+      m_timer[1] = m_timersvc->addItem("T2CaloTau.Tools.RegSel");
+      m_timer[2] = m_timersvc->addItem("T2CaloTau.Tools.DataPrep");
+      m_timer[3] = m_timersvc->addItem("T2CaloTau.Tools.Algorithmic");
+      m_timer[4] = m_timersvc->addItem("T2CaloTau.Tools.Saving");
+    }
+  
+  // noise suppression
+  if(m_applyNoiseCut!=0)
+    {
+      if(m_noiseTool.retrieve().isFailure())
+        {
+          (*m_log) << MSG::FATAL << "Unable to find CaloNoiseTool" << endreq;
+          return StatusCode::FAILURE;
+        }
+    }
+  
+  return sc;
+}
+
+
+HLT::ErrorCode TauAllCaloDRFex::execute( TrigTauCluster &rtrigTauCluster,
+					 const IRoiDescriptor& roi )
+{
+  
+  // Time total AlgTool time 
+  if (!m_timersvc.empty()) m_timer[0]->start();      
+  // reset error
+  m_error = 0x0;
+  
+  //these aren't used:
+  //  phiWidthEM = 0.;
+  //  etaWidthEM = 0.;
+
+  //samplings
+  const unsigned int NSamplings = 7;
+  int samplings[NSamplings]     = {0,1,2,3,0,1,2};
+  DETID detectorID[NSamplings]  = {TTEM,TTEM,TTEM,TTEM,TTHEC,TTHEC,TTHEC};
+  
+
+  // Time to access RegionSelector
+  if (!m_timersvc.empty()) m_timer[1]->start();      
+  if (!m_timersvc.empty()) m_timer[1]->pause();      
+  // Time to access Collection (and ByteStreamCnv ROBs)
+  if (!m_timersvc.empty()) m_timer[2]->start();      
+  if (!m_timersvc.empty()) m_timer[2]->pause();    
+
+  
+  // Algorithmic time
+  if (!m_timersvc.empty()) m_timer[3]->start();      
+  double seedPhi = roi.phi();
+  double seedEta = roi.eta();
+  
+  if ((*m_log).level()<=MSG::DEBUG)
+    (*m_log) << MSG::DEBUG << " Seed position (L1) eta/phi=" << seedEta << "/" << seedPhi << endreq;
+  
+
+  double energyEta = 0.;
+  double energyPhi = 0.;
+  
+  // Variables to take care of phi wrap-around
+  double energyNegPhi     = 0.; 
+  double energyNegPhiConv = 0.; 
+  double energyPosPhi     = 0.; 
+  
+  double EnergyMediumPosPhi = 0;
+  double EnergyMediumNegPhi = 0;
+  
+  //  double etamin = std::max(-2.5,RoIeta - etaWidth);
+  //  double etamax = std::min( 2.5,RoIeta + etaWidth);
+    
+  //  double phimin = RoIphi - phiWidth;
+  //  double phimax = RoIphi + phiWidth;
+
+  //  while (phimin < 0) phimin += 2. * M_PI;
+  //  while (phimax > 2*M_PI) phimax -= 2. * M_PI;
+
+
+  //------------------ step 1 : clusterization -----------------------------------
+  // loop over all samplings 
+  if ((*m_log).level()<=MSG::DEBUG)
+    (*m_log) << MSG::DEBUG << " Start clusterization "<< endreq;
+
+  for(unsigned int is=0; is<NSamplings;++is)
+    {
+      if ((*m_log).level()<=MSG::DEBUG)
+	(*m_log) << MSG::DEBUG << "LAr sampling "<< samplings[is]<< endreq;
+
+      if (!m_timersvc.empty()) { m_timer[3]->pause();  m_timer[1]->resume();}
+      //      m_data->RegionSelector(samplings[is], etamin, etamax, phimin, phimax, detectorID[is]);
+      m_data->RegionSelector(samplings[is], roi, detectorID[is]);
+      if (!m_timersvc.empty()) {m_timer[1]->pause();  m_timer[2]->resume(); }
+      if ( m_data->LoadCollections(m_iBegin,m_iEnd).isFailure() ){
+	if ((*m_log).level()<=MSG::DEBUG)
+	  (*m_log) << MSG::DEBUG << " can not LoadCollections " << *m_iBegin << " " << *m_iEnd << endreq;
+	return  HLT::TOOL_FAILURE; 
+      }
+      m_error|=m_data->report_error(); 
+      if (!m_timersvc.empty()){ m_timer[2]->pause();  m_timer[3]->resume(); }
+      
+      for(m_it = m_iBegin;m_it != m_iEnd; ++m_it)
+	{
+	  const LArCell*  cell = *m_it;
+	  double etaCell = cell->eta();
+	  double phiCell = cell->phi();
+          double dR;
+          if( ! getdR(seedPhi, seedEta, etaCell, phiCell, m_dRSeed, dR) )
+              continue;
+
+	  float energyCell = cell->energy();
+	  if (m_applyNoiseCut) {
+	    double rms = m_noiseTool->getNoise(cell, ICalorimeterNoiseTool::TOTALNOISE);
+	    if ( fabs(energyCell) < m_noiseNSigmaCut * rms) 
+	      continue;
+	  }
+
+	  if (detectorID[is]==TTHEC) { 
+	    if (energyCell < -5e3) continue;
+	    if ((m_hecQualityCut!=0) && (((cell->quality())&&0xffff) > m_hecQualityCut) ) continue;
+	  }
+	  energyEta += energyCell * etaCell ;
+	  
+	  if (phiCell > 0.){
+	    EnergyMediumPosPhi += energyCell;
+	    energyPosPhi       += energyCell * phiCell;
+	  } else {
+	    energyNegPhi       += energyCell * phiCell;
+	    energyNegPhiConv   += energyCell * (phiCell+2.0*M_PI);
+	    EnergyMediumNegPhi += energyCell;
+	  }
+	  
+	} // end of loop over EM sampling   
+    } // end loop over EM LAr
+  
+  // Region Selector, no sample needed
+  // Get detector offline ID's for Collections
+  
+  //  m_data->RegionSelector(0,etamin,etamax,phimin,phimax,TILE);
+  m_data->RegionSelector( 0, roi, TILE );
+  if (!m_timersvc.empty()) m_timer[1]->pause();
+
+  for (unsigned int iR=0;iR< m_data->TileContSize();iR++)
+    {
+      if (!m_timersvc.empty()) m_timer[2]->resume();
+      // For the first sample you will create the containers
+      // For the others no
+      if ( m_data->LoadCollections(m_itBegin,m_itEnd,iR,!iR).isFailure() ){
+	return  HLT::TOOL_FAILURE;
+      }
+      m_error|=m_data->report_error(); 
+      // Finished to access Collection
+      if (!m_timersvc.empty()) { m_timer[2]->pause(); m_timer[3]->resume(); }
+      
+      
+      for(m_itt = m_itBegin;m_itt != m_itEnd; ++m_itt)
+	{
+	  const CaloCell* cell = (*m_itt);
+
+	  double etaCell = cell->eta();
+	  double phiCell = cell->phi();
+          double dR;
+          if (! getdR(seedPhi, seedEta, etaCell, phiCell, m_dRSeed, dR) )
+              continue;
+
+	  float energyCell = cell->energy();
+	  
+	  if (m_applyNoiseCut) {
+	      if (! m_noiseTool->isEOverNSigma( cell, m_noiseNSigmaCut, 
+						ICalorimeterNoiseTool::MAXSYMMETRYHANDLING, 
+						ICalorimeterNoiseTool::TOTALNOISE) )
+                  continue;
+          }
+	  
+	  energyEta += energyCell * etaCell ;
+	  
+	  if ((*m_log).level()<=MSG::DEBUG)
+	    (*m_log) << MSG::DEBUG << "take cell E="<<energyCell << " Eta/Phi="<<etaCell << "/"<<phiCell<< endreq;
+	  
+	  if (phiCell > 0.){
+	    EnergyMediumPosPhi += energyCell;
+	    energyPosPhi +=energyCell * phiCell;
+	  } else {
+	    energyNegPhi +=energyCell * phiCell;
+	    energyNegPhiConv += energyCell * ( phiCell+2.0*M_PI);
+	    EnergyMediumNegPhi += energyCell;
+	  }
+	  
+	} // end of loop over Tile cells
+    } // end loop over Tile samplings
+  
+
+  
+
+
+  // End options for cluster position
+  //---------------- step 2 calculation of variables
+  
+  HLT::ErrorCode StatError = HLT::OK; // define flag for cluster with negative energy or sampling with 0 energy.
+  
+  // Phi wrap-around
+  if ( (EnergyMediumNegPhi + EnergyMediumPosPhi) > 0. ){           // dont divide by zero
+    energyEta /= (EnergyMediumNegPhi + EnergyMediumPosPhi) ;
+    energyPhi = calcEnergyPhi(energyNegPhi, energyPosPhi, EnergyMediumNegPhi, EnergyMediumPosPhi, energyNegPhiConv);
+  } else {
+    if ((*m_log).level()<=MSG::DEBUG)
+      (*m_log) << MSG::DEBUG <<"REGTEST problems finding seed: negative energy = "<< EnergyMediumNegPhi + EnergyMediumPosPhi 
+	       <<" eta/phi = "<< energyEta<<" / "<<energyPhi <<" . Seed set to L1 direction: eta/phi = "
+	       <<roi.eta()<<" / "<<roi.phi()<<  endreq;
+    energyEta = roi.eta() ; // if Cluster energy is null or negative, set L1 position
+    energyPhi = roi.phi() ;
+    SetClusterError(TAUCLUSTERROR::FAILSEED);
+
+    StatError =  HLT::ErrorCode(HLT::Action::CONTINUE, NEG_ENERGY_CLUSTER);
+  }
+  
+  if ((*m_log).level()<=MSG::DEBUG)
+    (*m_log) << MSG::DEBUG <<"REGTEST Pre-seed eta/phi " << seedEta<<"/"<<seedPhi << " => Cluster eta/phi = "<< energyEta << "/"<< energyPhi << endreq;
+  
+  while (energyPhi < -M_PI) energyPhi= energyPhi + 2. * M_PI;
+  while (energyPhi > M_PI)  energyPhi= energyPhi - 2. * M_PI;
+  
+  float dPhiL1 = fabs(energyPhi - seedPhi);
+  if( dPhiL1 > M_PI ) dPhiL1 = 2*M_PI - dPhiL1;  
+  
+  // If seed is too far from pre seed, means that something has happened, probably too small energy deposition
+  if ( fabs(energyEta - seedEta)> m_dRSeed || fabs(dPhiL1)> m_dRSeed){
+    if ((*m_log).level()<=MSG::DEBUG)
+      (*m_log) << MSG::DEBUG <<"REGTEST problems finding seed: eta/phi = "<<energyEta<<" / "<<energyPhi
+	       <<" too far from L1 eta/phi = "<< seedEta<<" / "<<seedPhi 
+	       <<" . Energy = "<< EnergyMediumNegPhi + EnergyMediumPosPhi<<  endreq;
+    energyEta=roi.eta();
+    energyPhi=roi.phi();
+    // this a similar case as above: energy is too small to calculate a good seed position. they should be monitored together.
+    SetClusterError(TAUCLUSTERROR::FAILSEED);
+    StatError =  HLT::ErrorCode(HLT::Action::CONTINUE, NEG_ENERGY_CLUSTER); 
+  }
+  
+  const TrigTauClusterDetails* pDetailsConst = rtrigTauCluster.clusterDetails();
+  TrigTauClusterDetails* pDetails = const_cast<TrigTauClusterDetails*> (pDetailsConst); // why do not we have function for that, if needed?
+  
+  if (!m_timersvc.empty()) m_timer[3]->pause();      
+  // Time to store cluster quantities
+  if (!m_timersvc.empty()) m_timer[4]->start();      
+  rtrigTauCluster.setEta(energyEta);
+  rtrigTauCluster.setPhi(energyPhi);
+  if (!m_timersvc.empty()) m_timer[4]->pause();      
+  if (!m_timersvc.empty()) m_timer[3]->resume();      
+  
+  ClearClusterError(TAUCLUSTERROR::EMS0E0); // this bit might at some point be set by the common data access
+  ClearClusterError(TAUCLUSTERROR::EMS1E0); // this bit might at some point be set by the common data access
+  ClearClusterError(TAUCLUSTERROR::EMS2E0); // this bit might at some point be set by the common data access
+  ClearClusterError(TAUCLUSTERROR::EMS3E0); // this bit might at some point be set by the common data access
+  
+  ClearClusterError(TAUCLUSTERROR::HADS1E0);  
+  ClearClusterError(TAUCLUSTERROR::HADS2E0);  
+  ClearClusterError(TAUCLUSTERROR::HADS3E0);  
+  
+  if ((*m_log).level()<=MSG::DEBUG)
+	(*m_log) << MSG::DEBUG << " Start shape calculation "<< endreq;
+  
+
+  int    numStripCell           = 0;
+  int    numTotalCells          = 0;
+                                
+  int    nEmCellsNarrow         = 0;
+  int    nEmCellsMed            = 0;
+  int    nEmCellsWide           = 0;
+
+  int    nHadCellsNarrow[3]     = {0,0,0};
+  int    nHadCellsMed[3]        = {0,0,0};
+  int    nHadCellsWide [3]      = {0,0,0};
+  
+  
+  double emRadiusNarrow         = 0;
+  double emRadiusMed            = 0;
+  double emRadiusWide           = 0;
+
+  double hadRadiusNarrow[3]     = {0.0,0.0,0.0};
+  double hadRadiusMed[3]        = {0.0,0.0,0.0};
+  double hadRadiusWide[3]       = {0.0,0.0,0.0};
+
+
+  double emEnergyNarrow         = 0;
+  double emEnergyMed            = 0;
+  double emEnergyWide           = 0;
+
+  double hadEnergyNarrow[3]     = {0.0,0.0,0.0};
+  double hadEnergyMed[3]        = {0.0,0.0,0.0};
+  double hadEnergyWide[3]       = {0.0,0.0,0.0};
+
+
+  double emWeightEtaNarrow      = 0.0;
+  double emWeightEtaMed         = 0.0;
+  double emWeightEtaWide        = 0.0;
+
+  double hadWeightEtaNarrow[3]  = {0.0,0.0,0.0};
+  double hadWeightEtaMed[3]     = {0.0,0.0,0.0};
+  double hadWeightEtaWide[3]    = {0.0,0.0,0.0};
+
+
+  double emWeightEta2Narrow     = 0.0;
+  double emWeightEta2Med        = 0.0;
+  double emWeightEta2Wide       = 0.0;
+
+  double hadWeightEta2Narrow[3] = {0.0,0.0,0.0};
+  double hadWeightEta2Med[3]    = {0.0,0.0,0.0};
+  double hadWeightEta2Wide[3]   = {0.0,0.0,0.0};
+
+
+  
+  
+
+
+
+  //loop over LAr samplings
+  for(unsigned int is=0; is<NSamplings;++is){
+    
+    emRadiusNarrow     = 0.;
+    emRadiusMed        = 0.;
+    emRadiusWide       = 0.;
+                       
+    nEmCellsNarrow     = 0;
+    nEmCellsMed        = 0;
+    nEmCellsWide       = 0;
+                       
+    emRadiusNarrow     = 0.;
+    emRadiusMed        = 0.;
+    emRadiusWide       = 0.;
+                       
+    emEnergyNarrow     = 0.;
+    emEnergyMed        = 0.;
+    emEnergyWide       = 0.;
+
+    emWeightEtaNarrow  = 0.;
+    emWeightEtaMed     = 0.;
+    emWeightEtaWide    = 0.;
+
+    emWeightEta2Narrow = 0.;
+    emWeightEta2Med    = 0.;
+    emWeightEta2Wide   = 0.;
+
+    
+    //get data
+    if (!m_timersvc.empty()){ m_timer[3]->pause();  m_timer[1]->resume(); }
+
+    // m_data->RegionSelector(samplings[is],etamin,etamax,phimin,phimax,detectorID[is]);
+    m_data->RegionSelector( samplings[is], roi, detectorID[is] );
+
+    if (!m_timersvc.empty()) { m_timer[1]->pause(); m_timer[2]->resume(); }
+
+    if ( m_data->LoadCollections(m_iBegin,m_iEnd).isFailure() ){
+      if ((*m_log).level()<=MSG::DEBUG)
+          (*m_log) << MSG::DEBUG << " can not LoadCollections " << *m_iBegin << " " << *m_iEnd << endreq;
+      return  HLT::TOOL_FAILURE; 
+    }
+    m_error|=m_data->report_error(); 
+    if (!m_timersvc.empty()){ m_timer[2]->pause();   m_timer[3]->resume(); }
+    
+    if ( m_saveCells ){ 
+      m_data->storeCells(m_iBegin,m_iEnd,*m_CaloCellContPoint,m_cellkeepthr,100000);
+    } 
+  
+
+    //loop over cells per sampling
+    for(m_it = m_iBegin;m_it != m_iEnd; ++m_it) {
+      const LArCell*  cell = *m_it;
+      double etaCell = cell->eta();
+      double phiCell = cell->phi();          
+      double dR      = 0.0;
+      //effectively applying the dR<m_dRConeWide cut
+      if ( !getdR(energyPhi, energyEta, etaCell, phiCell,m_dRConeWide , dR) ) continue;
+
+      float energyCell = cell->energy();
+      
+      
+      // Count cells
+      if ( is < 4 ) {
+        nEmCellsWide += 1;
+        if( dR < m_dRConeMedium ) {
+          nEmCellsMed += 1;
+          if( dR < m_dRConeNarrow )
+              nEmCellsNarrow += 1;
+        }
+      } else {
+        nHadCellsWide[samplings[is]] += 1;
+        if( dR < m_dRConeMedium ) {
+          nHadCellsMed[samplings[is]] += 1;
+          if( dR < m_dRConeNarrow )
+              nHadCellsNarrow[samplings[is]] += 1;
+        }
+      }        
+
+      //count n cells
+      numTotalCells = rtrigTauCluster.numTotCells();
+      numTotalCells = numTotalCells + 1;
+      rtrigTauCluster.setNumTotCells(numTotalCells);
+      
+      //Noise subtraction
+      if (m_applyNoiseCut) {
+        double rms = m_noiseTool->getNoise(cell, ICalorimeterNoiseTool::TOTALNOISE);
+        if ( fabs(energyCell) < m_noiseNSigmaCut * rms) 
+          continue;
+      }
+      
+      if (detectorID[is]==TTHEC) {
+        if (energyCell < -5e3) continue;
+        if ((m_hecQualityCut!=0) && (((cell->quality())&&0xffff) > m_hecQualityCut) ) continue;
+      }           
+
+      if ( is < 4 ) {
+        emRadiusWide     += energyCell * dR;
+        emEnergyWide     += energyCell; 
+        emWeightEta2Wide += energyCell * etaCell * etaCell;
+        emWeightEtaWide  += energyCell * etaCell;
+        
+      } else {
+        hadRadiusWide[samplings[is]]     += energyCell * dR;
+        hadEnergyWide[samplings[is]]     += energyCell; 
+        hadWeightEta2Wide[samplings[is]] += energyCell * etaCell * etaCell;
+        hadWeightEtaWide[samplings[is]]  += energyCell * etaCell;
+      }
+
+      if ( (is==1) && (energyCell > m_stripEthr ) ) numStripCell += 1;  
+
+      
+      if( dR < m_dRConeMedium ) {
+	if( is < 4 ) {
+          emRadiusMed     += energyCell * dR; 
+          emEnergyMed     += energyCell;
+          emWeightEta2Med += energyCell * etaCell * etaCell;
+          emWeightEtaMed  += energyCell * etaCell;
+        } else {
+          hadRadiusMed[samplings[is]]     += energyCell * dR;
+          hadEnergyMed[samplings[is]]     += energyCell;
+          hadWeightEta2Med[samplings[is]] += energyCell * etaCell * etaCell;
+          hadWeightEtaMed[samplings[is]]  += energyCell * etaCell;
+        }
+        
+        if( dR < m_dRConeNarrow ) {
+          if( is < 4 ) {
+            emRadiusNarrow     += energyCell * dR; 
+            emEnergyNarrow     += energyCell;
+            emWeightEta2Narrow += energyCell * etaCell * etaCell;
+            emWeightEtaNarrow  += energyCell * etaCell;
+          } else {
+            hadRadiusNarrow[samplings[is]]     += energyCell * dR;
+            hadEnergyNarrow[samplings[is]]     += energyCell;
+            hadWeightEta2Narrow[samplings[is]] += energyCell * etaCell * etaCell;
+            hadWeightEtaNarrow[samplings[is]]  += energyCell * etaCell;
+          }
+        }
+      }
+    } // end of loop over cells  
+
+    
+    //Set clusterWidth and emRadius for EM Samplings
+    if ( is < 4 ) {
+
+      double clusterWidthWide;
+      double clusterWidthMed;
+      double clusterWidthNarrow;
+      
+      //Wide
+      if ( (emEnergyWide > 0.) && (nEmCellsWide > 0) ) {
+        clusterWidthWide = 
+            (emWeightEta2Wide/emEnergyWide) -
+            (emWeightEtaWide/emEnergyWide)*
+            (emWeightEtaWide/emEnergyWide);
+        
+        clusterWidthWide > 0.? clusterWidthWide = 
+            sqrt(clusterWidthWide) : -99.;
+        
+        emRadiusWide = emRadiusWide / emEnergyWide ;
+      } else { 
+        if(nEmCellsWide == 0) {
+          clusterWidthWide = 0.;
+          emRadiusWide     = 0. ;
+
+	  /// What is this code for?? why is it hardcoded with values like eta=1.8 ???
+	  
+          // if E==0 in a dR<0.3 region, probably means problems with unpacking.
+          if ((is < 4) && 
+              (samplings[is]==0) && 
+              ((fabs(energyEta) - m_dRConeWide) < (1.8 - (0.025/2) - 0.05) ) &&
+              ((fabs(roi.etaMinus())<(1.8-1e-7)) || (fabs(roi.etaPlus())<(1.8-1e-7)) ) 
+              ) {
+            SetClusterError(TAUCLUSTERROR::EMS0E0);
+            StatError =  HLT::ErrorCode(HLT::Action::CONTINUE, NULL_ENERGY_SAMPLING);
+          }
+          if ((is < 4) && (samplings[is]==1)) {
+            SetClusterError(TAUCLUSTERROR::EMS1E0);
+            StatError =  HLT::ErrorCode(HLT::Action::CONTINUE, NULL_ENERGY_SAMPLING);
+          }
+          if ((is < 4) && (samplings[is]==2)) {
+            SetClusterError(TAUCLUSTERROR::EMS2E0);
+            StatError =  HLT::ErrorCode(HLT::Action::CONTINUE, NULL_ENERGY_SAMPLING);
+          } 
+          if ((is < 4) && (samplings[is]==3)) {
+            SetClusterError(TAUCLUSTERROR::EMS3E0);          
+            StatError =  HLT::ErrorCode(HLT::Action::CONTINUE, NULL_ENERGY_SAMPLING);
+          }
+        }
+        else {
+          clusterWidthWide = -99.;
+          emRadiusWide     = -99.;
+        }
+      }
+      
+      //Medium
+      if ( (emEnergyMed > 0.) && (nEmCellsMed > 0) ) {
+        clusterWidthMed = 
+	  (emWeightEta2Med/emEnergyMed) -
+	  (emWeightEtaMed/emEnergyMed)*
+	  (emWeightEtaMed/emEnergyMed);
+        
+        clusterWidthMed > 0.? clusterWidthMed = 
+            sqrt(clusterWidthMed) : -99.;
+        
+        emRadiusMed = emRadiusMed / emEnergyMed ;
+      } else { 
+        if( nEmCellsMed == 0 ) {
+          clusterWidthMed = 0.;
+          emRadiusMed     = 0. ;
+        } else {
+          clusterWidthMed = -99.;
+          emRadiusMed     = -99.;
+        }
+      }
+      
+    
+      //Narrow
+      if ( (emEnergyNarrow > 0.) && (nEmCellsNarrow > 0) ) {
+        clusterWidthNarrow = 
+	  (emWeightEta2Narrow/emEnergyNarrow) -
+	  (emWeightEtaNarrow /emEnergyNarrow)*
+	  (emWeightEtaNarrow /emEnergyNarrow);
+        
+        clusterWidthNarrow > 0.? clusterWidthNarrow = 
+	  sqrt(clusterWidthNarrow) : -99.;
+        
+        emRadiusNarrow = emRadiusNarrow / emEnergyNarrow ;
+      } else { 
+        if( nEmCellsNarrow == 0 ) {
+          clusterWidthNarrow = 0.;
+          emRadiusNarrow     = 0. ;
+	} else {
+          clusterWidthNarrow = -99.;
+          emRadiusNarrow     = -99.;
+        }
+      }
+      
+      if (!m_timersvc.empty()){ m_timer[3]->pause();  m_timer[4]->resume(); }
+      
+      float emRad     = -1.0;
+      float clusWidth = -1.0;
+      switch (m_defaultWidth) {
+      case 0:
+        emRad     = emRadiusNarrow;
+        clusWidth = clusterWidthNarrow;
+        break;
+      case 1:
+        emRad     = emRadiusMed;
+        clusWidth = clusterWidthMed;
+        break;
+      case 2:
+        emRad     = emRadiusWide;
+        clusWidth = clusterWidthWide;
+        break;
+      }
+      
+      pDetails->setEMRadius      (samplings[is],emRad);
+      pDetails->setEMenergyWidth (samplings[is],clusWidth);
+      
+      pDetails->setEMenergyNarrow(samplings[is],emEnergyNarrow);
+      pDetails->setEMenergyMedium(samplings[is],emEnergyMed);
+      pDetails->setEMenergyWide  (samplings[is],emEnergyWide);
+      
+      //if samplings==2 in the first 4 samples
+      if (samplings[is]==2) {
+	if(emEnergyMed != 0) rtrigTauCluster.setIsoFrac( (emEnergyMed - emEnergyNarrow) / emEnergyMed );
+        else rtrigTauCluster.setIsoFrac(-99. );
+      }
+    } 
+    if (!m_timersvc.empty()){ m_timer[4]->pause();   m_timer[3]->resume(); }
+  } 
+  
+  if (!m_timersvc.empty()) m_timer[3]->pause();      
+
+  if (!m_timersvc.empty()) m_timer[4]->resume();      
+  rtrigTauCluster.setNumStripCells    (numStripCell);
+  rtrigTauCluster.setStripWidthOffline(rtrigTauCluster.EMenergyWidth(1));
+  rtrigTauCluster.setStripWidth       (rtrigTauCluster.EMenergyWidth(2));
+  rtrigTauCluster.setEMRadius2        (rtrigTauCluster.EMRadius(2));
+  rtrigTauCluster.setEMenergy         (getEMEnergy(pDetails, m_defaultWidth) );
+
+  if (!m_timersvc.empty()){ m_timer[4]->pause(); m_timer[3]->resume(); }
+  if (!m_timersvc.empty()) { m_timer[3]->pause(); m_timer[1]->resume();}
+
+  //  m_data->RegionSelector(0,etamin,etamax,phimin,phimax,TILE);
+  m_data->RegionSelector( 0, roi, TILE );
+  if (!m_timersvc.empty()) m_timer[1]->pause();
+
+  
+
+  // Tile energy
+  for (unsigned int iR=0; iR<m_data->TileContSize(); iR++) {
+    
+    if (!m_timersvc.empty()) m_timer[2]->resume();
+    if ( m_data->LoadCollections(m_itBegin,m_itEnd,iR,!iR).isFailure() ){
+      return  HLT::TOOL_FAILURE;
+    }
+    m_error|=m_data->report_error(); 
+    if ( m_saveCells ){ 
+      m_data->storeCells(m_itBegin,m_itEnd,*m_CaloCellContPoint,m_cellkeepthr,100000); 
+    } 
+    if (!m_timersvc.empty()) { m_timer[2]->pause(); m_timer[3]->resume();}
+    
+    //loop over tile cells
+    for(m_itt = m_itBegin;m_itt != m_itEnd; ++m_itt) {
+      const CaloCell*  cell = (*m_itt);
+      double etaCell = cell->eta();
+      double phiCell = cell->phi();
+      double dR      = 0.0;
+      if (!getdR(energyPhi, energyEta, etaCell, phiCell, m_dRConeWide, dR) )
+          continue;
+
+      float energyCell = cell->energy();
+      
+      
+      //samp = CaloSampling::getSampling(*cell);
+      //CaloSampling::CaloSample samp = CaloSampling::getSampling(*(*m_itt));
+      CaloSampling::CaloSample samp = (*m_itt)->caloDDE()->getSampling();
+
+      int idxsamp = -99;
+      if (CaloSampling::TileBar0 == samp ||
+	  CaloSampling::TileExt0 == samp) {
+	idxsamp = 0; 
+      } else if (CaloSampling::TileBar1 == samp ||
+		 CaloSampling::TileExt1 == samp) {
+	idxsamp = 1;
+      } else if (CaloSampling::TileBar2 == samp ||
+		 CaloSampling::TileExt2 == samp) {
+	idxsamp = 2;
+      }else continue;
+      if( idxsamp<0 ) continue;
+      
+      // Count this cell
+      numTotalCells=rtrigTauCluster.numTotCells();
+      rtrigTauCluster.setNumTotCells(numTotalCells++);
+
+      // Count cells
+      nHadCellsWide[idxsamp] += 1;
+      if( dR < m_dRConeMedium ) {
+        nHadCellsMed[idxsamp] += 1;
+        if( dR < m_dRConeNarrow )
+            nHadCellsNarrow[idxsamp] += 1;
+      }
+
+      if (m_applyNoiseCut) {
+        if (! m_noiseTool->isEOverNSigma( cell, m_noiseNSigmaCut,
+                                          ICalorimeterNoiseTool::MAXSYMMETRYHANDLING,
+                                          ICalorimeterNoiseTool::TOTALNOISE) )
+            continue;
+      }
+      
+      hadRadiusWide[idxsamp]     += energyCell * dR;
+      hadEnergyWide[idxsamp]     += energyCell;          
+      hadWeightEta2Wide[idxsamp] += energyCell * etaCell * etaCell;
+      hadWeightEtaWide[idxsamp]  += energyCell * etaCell;
+
+      if( dR < m_dRConeMedium ) {
+        hadRadiusMed[idxsamp]     += energyCell * dR;
+        hadEnergyMed[idxsamp]     += energyCell;
+        hadWeightEta2Med[idxsamp] += energyCell * etaCell * etaCell;
+        hadWeightEtaMed[idxsamp]  += energyCell * etaCell;
+
+        if( dR < m_dRConeNarrow ) {
+          hadRadiusNarrow[idxsamp]     += energyCell * dR;
+          hadEnergyNarrow[idxsamp]     += energyCell;
+          hadWeightEta2Narrow[idxsamp] += energyCell * etaCell * etaCell;
+          hadWeightEtaNarrow[idxsamp]  += energyCell * etaCell;
+	}
+      }
+    } // end loop over cells
+  } // end loop over collections
+  
+  
+  //Fix had variables
+  for(int sampling=0; sampling<3;++sampling){
+    // calculate cluster width in a region (Eta/Phi)StripsEM2Nor from jobO
+    // ??? ClearClusterError(TAUCLUSTERROR::EMS2E0); // this bit might at some point be set by the common data access
+    
+    double clusterWidthWide;
+    double clusterWidthMed;
+    double clusterWidthNarrow;
+
+    //HadWide
+    if ( hadEnergyWide[sampling] > 0.  &&  nHadCellsWide[sampling] > 0 ) {
+      clusterWidthWide = 
+          (hadWeightEta2Wide[sampling]/hadEnergyWide[sampling]) -
+          (hadWeightEtaWide[sampling]/hadEnergyWide[sampling])*
+          (hadWeightEtaWide[sampling]/hadEnergyWide[sampling]);
+
+      clusterWidthWide > 0.? clusterWidthWide = 
+          sqrt(clusterWidthWide) : -99.;
+      
+      hadRadiusWide[sampling] = hadRadiusWide[sampling] / hadEnergyWide[sampling] ;
+    } else {
+      if(nHadCellsWide[sampling] == 0) {
+        clusterWidthWide         = 0.;
+        hadRadiusWide[sampling]  = 0. ;
+
+        // if E==0 in a dR<0.3 region, probably means problems with unpacking.
+	if ( sampling==0)  SetClusterError(TAUCLUSTERROR::HADS1E0);
+	if ( sampling==1)  SetClusterError(TAUCLUSTERROR::HADS2E0);
+	if ( sampling==2)  SetClusterError(TAUCLUSTERROR::HADS3E0);
+        StatError =  HLT::ErrorCode(HLT::Action::CONTINUE, NULL_ENERGY_SAMPLING);
+      } else {
+        clusterWidthWide         = -99.;
+        hadRadiusWide[sampling]  = -99.;
+      }
+    }
+
+    //HadMed
+    if ( hadEnergyMed[sampling] > 0.  &&  nHadCellsMed[sampling] > 0 ) {
+      clusterWidthMed = 
+          (hadWeightEta2Med[sampling]/hadEnergyMed[sampling]) -
+          (hadWeightEtaMed[sampling]/hadEnergyMed[sampling])*
+          (hadWeightEtaMed[sampling]/hadEnergyMed[sampling]);
+
+      clusterWidthMed > 0.? clusterWidthMed = 
+          sqrt(clusterWidthMed) : -99.;
+      
+      hadRadiusMed[sampling] = hadRadiusMed[sampling] / hadEnergyMed[sampling] ;
+    } else {
+      if(nHadCellsMed[sampling] == 0) {
+        clusterWidthMed         = 0.;
+        hadRadiusMed[sampling]  = 0. ;
+      } else {
+        clusterWidthMed         = -99.;
+        hadRadiusMed[sampling]  = -99.;
+      }
+    }
+
+
+    //HadNarrow
+    if ( hadEnergyNarrow[sampling] > 0.  &&  nHadCellsNarrow[sampling] > 0 ) {
+      clusterWidthNarrow = 
+          (hadWeightEta2Narrow[sampling]/hadEnergyNarrow[sampling]) -
+          (hadWeightEtaNarrow[sampling]/hadEnergyNarrow[sampling])*
+          (hadWeightEtaNarrow[sampling]/hadEnergyNarrow[sampling]);
+
+      clusterWidthNarrow > 0.? clusterWidthNarrow = 
+          sqrt(clusterWidthNarrow) : -99.;
+      
+      hadRadiusNarrow[sampling] = hadRadiusNarrow[sampling] / hadEnergyNarrow[sampling] ;
+    } else {
+      if(nHadCellsNarrow[sampling] == 0) {
+        clusterWidthNarrow         = 0.;
+        hadRadiusNarrow[sampling]  = 0. ;
+      } else {
+        clusterWidthNarrow         = -99.;
+        hadRadiusNarrow[sampling]  = -99.;
+      }
+    }
+
+    if (!m_timersvc.empty()) {m_timer[3]->pause();  m_timer[4]->resume(); }
+
+    //set values
+    float hadRad     = -1.0;
+    float clusWidth = -1.0;
+    switch (m_defaultWidth) {
+    case 0:
+      hadRad    = hadRadiusNarrow[sampling];
+      clusWidth = clusterWidthNarrow;
+      break;
+    case 1:
+      hadRad    = hadRadiusMed[sampling];
+      clusWidth = clusterWidthMed;
+      break;
+    case 2:
+      hadRad    = hadRadiusWide[sampling];
+      clusWidth = clusterWidthWide;
+      break;
+    }
+
+    pDetails->setHADRadius      (sampling,hadRad);
+    pDetails->setHADenergyWidth (sampling,clusWidth);
+
+    pDetails->setHADenergyNarrow(sampling,hadEnergyNarrow[sampling]);
+    pDetails->setHADenergyMedium(sampling,hadEnergyMed[sampling]);
+    pDetails->setHADenergyWide  (sampling,hadEnergyWide[sampling]);
+    
+    if (!m_timersvc.empty()){ m_timer[4]->pause();  m_timer[3]->resume(); }
+  }
+  
+  if (!m_timersvc.empty()){ m_timer[3]->pause();  m_timer[4]->resume();}
+  
+
+  //set Raw and Had energy
+  rtrigTauCluster.setHADenergy( getHADEnergy(pDetails, m_defaultWidth) );
+  rtrigTauCluster.setRawEnergy( rtrigTauCluster.rawEnergy() + rtrigTauCluster.EMenergy() + rtrigTauCluster.HADenergy() );
+
+  if ( m_log->level() <= MSG::DEBUG)
+      (*m_log)<<MSG::DEBUG 
+              << "REGTEST  Record energy RawE" << rtrigTauCluster.rawEnergy() 
+              << "Had " << rtrigTauCluster.HADenergy() << endreq;
+  
+  if (!m_timersvc.empty()){ m_timer[4]->pause();  m_timer[3]->resume();}
+  
+
+  //set Radius
+  float caloRad    = caloRadius(pDetails);
+  float emRadius3S = emRadiusAllSampl(pDetails, 3);
+  float coreFrac   = coreFraction(pDetails);
+  float emFrac     = emFraction(&rtrigTauCluster);
+  float hadRad     = hadRadius(pDetails);
+  
+  if (!m_timersvc.empty()){ m_timer[3]->pause();  m_timer[4]->resume();}
+  
+  rtrigTauCluster.setCaloRadius(caloRad);
+  rtrigTauCluster.setEMRadius3S(emRadius3S);
+  rtrigTauCluster.setCoreFrac(coreFrac);
+  rtrigTauCluster.setEMFrac(emFrac);
+  rtrigTauCluster.setHadRadius(hadRad);
+  
+  if (!m_timersvc.empty()) {
+    m_timer[1]->stop(); 
+    m_timer[2]->stop(); 
+    m_timer[3]->stop();   
+    m_timer[4]->stop(); 
+    m_timer[0]->stop();      
+  }
+  
+  //  return HLT::OK;
+  return StatError;
+  
+}
+
+double TauAllCaloDRFex::emRadiusAllSampl(const TrigTauClusterDetails* clusterDetails, int maxEmSamp)
+{
+  double emRadAll = 0.0;
+  double totEn    = 0.0;
+  
+  double emEnergy[4];
+  
+  for (int iS=0; iS<4 && iS < maxEmSamp; iS++) {
+    switch (m_defaultWidth) {
+    case 0:
+      emEnergy[iS] = clusterDetails->EMenergyNarrow(iS);
+      break;
+    case 1:
+      emEnergy[iS] = clusterDetails->EMenergyMedium(iS);
+      break;
+    case 2:
+      emEnergy[iS] = clusterDetails->EMenergyWide(iS);
+      break;
+    }
+  }
+
+  for(int emSamp = 0; emSamp <= 3 && emSamp < maxEmSamp; emSamp++) {
+    if( emEnergy[emSamp] > 0.0 && fabs(clusterDetails->EMRadius(emSamp)) < 90.0) {
+      emRadAll += emEnergy[emSamp] * clusterDetails->EMRadius(emSamp);
+      totEn    += emEnergy[emSamp];
+    }
+  }
+  
+  if (totEn > 0.0) {
+    return emRadAll / totEn;
+  }
+  return -99.0;
+}
+
+double TauAllCaloDRFex::caloRadius(const TrigTauClusterDetails* clusterDetails)
+{
+  double caloRad  = 0.0;
+  double totEn    = 0.0;
+
+  double emEnergy[4];
+  double hadEnergy[3];
+
+  for (int iS=0; iS<4; iS++) {
+    switch (m_defaultWidth) {
+    case 0:
+      emEnergy[iS] = clusterDetails->EMenergyNarrow(iS);
+      if (iS<3) 
+          hadEnergy[iS] = clusterDetails->HADenergyNarrow(iS);
+      break;
+    case 1:
+      emEnergy[iS] = clusterDetails->EMenergyMedium(iS);
+      if (iS<3) 
+          hadEnergy[iS] = clusterDetails->HADenergyMedium(iS);
+      break;
+    case 2:
+      emEnergy[iS] = clusterDetails->EMenergyWide(iS);
+      if (iS<3) 
+          hadEnergy[iS] = clusterDetails->HADenergyWide(iS);
+      break;
+    }
+  }
+  
+  
+  for(int emSamp = 0; emSamp <= 3; emSamp++) {
+    if( emEnergy[emSamp] > 0.0  &&  fabs(clusterDetails->EMRadius(emSamp)) < 90.0) {
+      caloRad += emEnergy[emSamp] * clusterDetails->EMRadius(emSamp);
+      totEn   += emEnergy[emSamp];
+    }
+  }
+  for(int hadSamp = 0; hadSamp <= 2; hadSamp++) {
+    if( hadEnergy[hadSamp] > 0.0 && fabs(clusterDetails->HADRadius(hadSamp)) < 90.0) {
+      caloRad += hadEnergy[hadSamp] * clusterDetails->HADRadius(hadSamp);
+      totEn   += hadEnergy[hadSamp];
+    }
+  }
+  if(totEn > 0.0) {
+        return caloRad / totEn;
+  }
+  return -99.0;
+}
+
+double TauAllCaloDRFex::hadRadius(const TrigTauClusterDetails* clusterDetails)
+{
+  double hadRad = 0.0;
+  double totEn  = 0.0;
+  
+  double hadEnergy[3];
+  
+  for (int iS=0; iS<3; iS++) {
+    switch (m_defaultWidth) {
+    case 0:
+      hadEnergy[iS] = clusterDetails->HADenergyNarrow(iS);
+      break;
+    case 1:
+      hadEnergy[iS] = clusterDetails->HADenergyMedium(iS);
+      break;
+    case 2:
+      hadEnergy[iS] = clusterDetails->HADenergyWide(iS);
+      break;
+    }
+  }
+  
+  
+  for(int hadSamp = 0; hadSamp <= 2; hadSamp++) {
+    if(hadEnergy[hadSamp] > 0.0 && fabs(clusterDetails->HADRadius(hadSamp)) < 90.0) {
+      hadRad += hadEnergy[hadSamp] * clusterDetails->HADRadius(hadSamp);
+      totEn  += hadEnergy[hadSamp];
+    }
+  }
+
+  if(totEn > 0.0) {
+    return hadRad / totEn;
+  }
+  return -99.0;
+}
+
+
+
+double TauAllCaloDRFex::coreFraction(const TrigTauClusterDetails* clusterDetails)
+{
+    double ERawNarrow = (clusterDetails->EMenergyNarrow(0)
+                       + clusterDetails->EMenergyNarrow(1)
+                       + clusterDetails->EMenergyNarrow(2)
+                       + clusterDetails->EMenergyNarrow(3)
+                       + clusterDetails->HADenergyNarrow(0)
+                       + clusterDetails->HADenergyNarrow(1)
+                       + clusterDetails->HADenergyNarrow(2));
+    
+    double ERawMedium = (clusterDetails->EMenergyMedium(0)
+                     + clusterDetails->EMenergyMedium(1)
+                     + clusterDetails->EMenergyMedium(2)
+                     + clusterDetails->EMenergyMedium(3)
+                     + clusterDetails->HADenergyMedium(0)
+                     + clusterDetails->HADenergyMedium(1)
+                     + clusterDetails->HADenergyMedium(2));
+    
+    if(ERawMedium > 0.0) {
+      return ERawNarrow / ERawMedium;
+    }
+    return -99.0;  
+}
+
+double TauAllCaloDRFex::emFraction(const TrigTauCluster* ptrigTauCluster)
+{
+  float totEn = ptrigTauCluster->EMenergy() + ptrigTauCluster->HADenergy();
+  if(totEn != 0.0) {
+    return ptrigTauCluster->EMenergy() / totEn;
+  } 
+
+  return -99.0;
+}
+
+double TauAllCaloDRFex::calcEnergyPhi(double energyNegPhi, double energyPosPhi, double EnergyMediumNegPhi, double EnergyMediumPosPhi, double energyNegPhiConv)
+{
+  double AvgNegPhi = 0.;
+  double AvgPosPhi = 0.;
+  double energyPhi = 0.;
+
+    if (EnergyMediumNegPhi > 0. ){
+      AvgNegPhi = energyNegPhi / EnergyMediumNegPhi;
+    } else {
+      AvgNegPhi = -999.0;
+    }
+    
+    if (EnergyMediumPosPhi > 0. ){
+      AvgPosPhi = energyPosPhi / EnergyMediumPosPhi;
+    } else {
+      AvgPosPhi = -999.0;
+    }
+    
+    if (AvgPosPhi==-999.0) {
+      if (AvgNegPhi != -999.0) {
+        energyPhi = AvgNegPhi;
+      }
+    }
+    
+    if (AvgNegPhi==-999.0) {
+      if (AvgPosPhi != -999.0) {
+        energyPhi = AvgPosPhi;
+      }
+    }
+    
+    if (AvgNegPhi != -999.0 && AvgPosPhi != -999.0) {
+      if ( (AvgNegPhi > (-M_PI/2.0)) && (AvgPosPhi < (M_PI/2.0)) ) {
+        energyPhi = (energyNegPhi + energyPosPhi)/ 
+	  (EnergyMediumNegPhi + EnergyMediumPosPhi);
+      } else {
+        if ((AvgNegPhi < (-M_PI/2.0)) && (AvgPosPhi > (M_PI/2.0))) {
+          energyPhi = (energyNegPhiConv + energyPosPhi)/
+	    (EnergyMediumNegPhi + EnergyMediumPosPhi);
+          if (energyPhi > M_PI) {
+            energyPhi = energyPhi - 2*M_PI;
+          }
+        }
+      }
+    }
+  return energyPhi;
+}
+
+bool TauAllCaloDRFex::getdR(double compPhi, double compEta, double etaCell, double phiCell, double dRCut, double& dR)
+{
+
+  float dEta = fabs(etaCell - compEta);
+  if( dEta > dRCut ) return false;
+  float dPhi = fabs(phiCell - compPhi);
+  if( dPhi > M_PI ) dPhi = 2*M_PI - dPhi;
+  if( dPhi > dRCut ) return false;
+  dR = std::sqrt(dEta*dEta + dPhi*dPhi);
+  if( dR > dRCut )  return false;
+  return true;
+
+}
+
+double TauAllCaloDRFex::getEMEnergy(const TrigTauClusterDetails* clusterDetails, int widthChoice)
+{
+  double EMEnergy;
+  switch (widthChoice)
+  {
+    case 0:
+       EMEnergy = (clusterDetails->EMenergyNarrow(0)+
+                   clusterDetails->EMenergyNarrow(1)+
+                   clusterDetails->EMenergyNarrow(2)+
+                   clusterDetails->EMenergyNarrow(3));
+       break;
+    case 1:
+       EMEnergy = (clusterDetails->EMenergyMedium(0)+
+                   clusterDetails->EMenergyMedium(1)+
+                   clusterDetails->EMenergyMedium(2)+
+                   clusterDetails->EMenergyMedium(3));
+       break;
+    case 2:
+       EMEnergy = (clusterDetails->EMenergyWide(0)+
+                   clusterDetails->EMenergyWide(1)+
+                   clusterDetails->EMenergyWide(2)+
+                   clusterDetails->EMenergyWide(3));
+       break;       
+    default:
+       EMEnergy = (clusterDetails->EMenergyNarrow(0)+
+                   clusterDetails->EMenergyNarrow(1)+
+                   clusterDetails->EMenergyNarrow(2)+
+                   clusterDetails->EMenergyNarrow(3));
+
+  }  
+  return EMEnergy;
+}
+
+double TauAllCaloDRFex::getHADEnergy(const TrigTauClusterDetails* clusterDetails, int widthChoice)
+{
+  double HADEnergy;
+  switch (widthChoice)
+  {
+    case 0:
+       HADEnergy = (clusterDetails->HADenergyNarrow(0)+
+                    clusterDetails->HADenergyNarrow(1)+
+                    clusterDetails->HADenergyNarrow(2));
+       break;
+    case 1:
+       HADEnergy = (clusterDetails->HADenergyMedium(0)+
+                    clusterDetails->HADenergyMedium(1)+
+                    clusterDetails->HADenergyMedium(2));
+       break;
+    case 2:
+       HADEnergy = (clusterDetails->HADenergyWide(0)+
+                    clusterDetails->HADenergyWide(1)+
+                    clusterDetails->HADenergyWide(2));
+       break;       
+    default:
+       HADEnergy = (clusterDetails->HADenergyNarrow(0)+
+                    clusterDetails->HADenergyNarrow(1)+
+                    clusterDetails->HADenergyNarrow(2));
+
+  }  
+  
+  return HADEnergy;
+}
diff --git a/Trigger/TrigAlgorithms/TrigT2CaloTau/src/components/TrigT2CaloTau_entries.cxx b/Trigger/TrigAlgorithms/TrigT2CaloTau/src/components/TrigT2CaloTau_entries.cxx
new file mode 100755
index 00000000000..9c0c61d7168
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigT2CaloTau/src/components/TrigT2CaloTau_entries.cxx
@@ -0,0 +1,12 @@
+#include "TrigT2CaloTau/T2CaloTau.h"
+#include "TrigT2CaloTau/TauAllCaloDRFex.h"
+#include "GaudiKernel/DeclareFactoryEntries.h"
+
+DECLARE_ALGORITHM_FACTORY( T2CaloTau )
+
+DECLARE_TOOL_FACTORY( TauAllCaloDRFex )
+
+DECLARE_FACTORY_ENTRIES(TrigT2CaloTau) {
+    DECLARE_ALGORITHM( T2CaloTau );
+    DECLARE_TOOL( TauAllCaloDRFex );
+}
diff --git a/Trigger/TrigAlgorithms/TrigT2CaloTau/src/components/TrigT2CaloTau_load.cxx b/Trigger/TrigAlgorithms/TrigT2CaloTau/src/components/TrigT2CaloTau_load.cxx
new file mode 100755
index 00000000000..403d72d77fc
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigT2CaloTau/src/components/TrigT2CaloTau_load.cxx
@@ -0,0 +1,3 @@
+#include "GaudiKernel/LoadFactoryEntries.h"
+
+LOAD_FACTORY_ENTRIES(TrigT2CaloTau)
-- 
GitLab