diff --git a/Reconstruction/tauRec/cmt/requirements b/Reconstruction/tauRec/cmt/requirements
new file mode 100755
index 0000000000000000000000000000000000000000..149e2b92bcc021d1e74f26ed272fffad11048c36
--- /dev/null
+++ b/Reconstruction/tauRec/cmt/requirements
@@ -0,0 +1,69 @@
+package tauRec
+
+author S. Rajagopalan <srinir@bnl.gov>
+
+public
+use  AtlasPolicy                AtlasPolicy-*                   
+use  AthenaBaseComps            AthenaBaseComps-*               Control
+use  AthenaKernel               AthenaKernel-*                  Control
+use  CxxUtils                   CxxUtils-*                      Control
+use  AtlasBoost                 AtlasBoost-*                    External
+use  AtlasROOT                  AtlasROOT-*                     External
+use  CaloInterface              CaloInterface-*                 Calorimeter
+use  CaloUtils                  CaloUtils-*                     Calorimeter
+use  AthLinks                   AthLinks-*                      Control
+use  GaudiInterface             GaudiInterface-*                External
+use  ITrackToVertex             ITrackToVertex-*                Reconstruction/RecoTools
+#use  JetMomentTools             JetMomentTools-*                Reconstruction/Jet
+use  JetEDM                     JetEDM-*                        Reconstruction/Jet
+use  Particle                   Particle-*                      Reconstruction
+use  ParticleEvent              ParticleEvent-*                 PhysicsAnalysis/AnalysisCommon
+use  tauEvent                   tauEvent-*                      Reconstruction
+use  xAODTau                    xAODTau-*                       Event/xAOD
+use  xAODJet                    xAODJet-*                       Event/xAOD
+use  xAODTracking               xAODTracking-*                  Event/xAOD
+use  xAODCaloEvent              xAODCaloEvent-*                 Event/xAOD
+use  xAODPFlow                  xAODPFlow-*                     Event/xAOD
+
+private
+use  AthContainers              AthContainers-*                 Control
+use  CaloEvent                  CaloEvent-*                     Calorimeter
+use  EventKernel                EventKernel-*                   Event
+use  CaloGeoHelpers             CaloGeoHelpers-*                Calorimeter
+use  AnalysisUtils              AnalysisUtils-*                 PhysicsAnalysis/AnalysisCommon
+use  AtlasAIDA                  AtlasAIDA-*                     External
+use  AtlasCLHEP                 AtlasCLHEP-*                    External
+use  AtlasDetDescr              AtlasDetDescr-*                 DetectorDescription
+use  CaloIdentifier             CaloIdentifier-*                Calorimeter
+use  EventInfo                  EventInfo-*                     Event
+use  FourMom                    FourMom-*                       Event
+use  FourMomUtils               FourMomUtils-*                  Event
+use  NavFourMom                 NavFourMom-*                    Event
+use  InDetRecToolInterfaces     InDetRecToolInterfaces-*        InnerDetector/InDetRecTools
+use  JetEvent                   JetEvent-*                      Reconstruction/Jet
+use  PathResolver               PathResolver-*                  Tools
+use  RecoToolInterfaces         RecoToolInterfaces-*            Reconstruction/RecoTools
+use  TrkParameters              TrkParameters-*                 Tracking/TrkEvent
+use  TrkParticleBase            TrkParticleBase-*               Tracking/TrkEvent
+use  TrkTrackSummary            TrkTrackSummary-*               Tracking/TrkEvent
+use  TrkVertexFitterInterfaces  TrkVertexFitterInterfaces-*     Tracking/TrkVertexFitter
+use  TrkVertexFitters           TrkVertexFitters-*              Tracking/TrkVertexFitter
+use  TrkToolInterfaces          TrkToolInterfaces-*             Tracking/TrkTools
+use TrkVxEdmCnv                 TrkVxEdmCnv-*           Tracking/TrkVertexFitter
+use TrkLinks                    TrkLinks-*              Tracking/TrkEvent
+use  VxVertex                   VxVertex-*                      Tracking/TrkEvent
+end_private
+
+
+public
+
+#macro_append tauRec_shlibflags "-L$(ROOTSYS)/lib -lCore -lCint -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lm -ldl -lpthread -rdynamic"
+macro_append ROOT_linkopts " -lTMVA"
+
+apply_pattern dual_use_library files="*.cxx *.c"
+
+apply_pattern declare_joboptions files="*.txt *.py"
+
+apply_pattern declare_runtime files="*.root *.dat *.xml" 
+
+apply_pattern declare_python_modules files="*.py"
diff --git a/Reconstruction/tauRec/depreciated/TauEflowAddCaloInfo.cxx b/Reconstruction/tauRec/depreciated/TauEflowAddCaloInfo.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..70934763f1a31ec6795fb083b71b7fb905c2edff
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauEflowAddCaloInfo.cxx
@@ -0,0 +1,291 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        tau1p3pAddCaloInfo.cxx
+// package:     Reconstruction/tauRec
+// authors:     Lukasz Janyst, Anna Kaczmarska
+// date:        2005-07-05
+//
+// Tool to calculate identification variables (calo + tracking)
+//
+// MODIFIED:
+// 11/09/2006 - (AK) correcting statusCode
+// 08/10/2006 - (AK) change of detRCoreCaloCut, detRIsolCaloCut
+//                   input parameters names
+// 03/07/2009 - (AK) changing closest*TrkVertCell accessors to the "old-EDM" ones
+//-----------------------------------------------------------------------------
+
+//TODO: revisit StatusCode
+
+#include <algorithm>
+#include <math.h>
+#include <sstream>
+
+#include "GaudiKernel/Property.h"
+
+#include "FourMom/P4EEtaPhiM.h"
+
+#include "CaloUtils/CaloCellList.h"
+#include "CaloEvent/CaloCluster.h"
+#include "CaloEvent/CaloCell.h"
+#include "AtlasDetDescr/AtlasDetectorID.h"
+#include "CaloIdentifier/CaloID.h"
+#include "CaloIdentifier/CaloCell_ID.h"
+#include "CaloGeoHelpers/CaloSampling.h"
+
+#include "tauEvent/TauCommonDetails.h"
+#include "tauEvent/TauCommonExtraDetails.h"
+#include "tauRec/KineUtils.h"
+#include "tauRec/TauOriginCorrectionTool.h"
+
+#include "tauRec/TauEflowAddCaloInfo.h"
+
+//-------------------------------------------------------------------------
+// Constructor
+//-------------------------------------------------------------------------
+
+TauEflowAddCaloInfo::TauEflowAddCaloInfo(const std::string &type,
+        const std::string &name,
+        const IInterface *parent) :
+TauToolBase(type, name, parent),
+m_detRCoreCaloCut(0.2),
+m_detRIsolCaloCut(0.4),
+m_ETCellMinCut(100.0),
+m_ETStripMinCut(200.0),
+m_detaStripCut(0.2),
+m_doCellCorrection(false), //FF: don't do cell correction by default
+m_tauOriginCorrTool("") {
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("detRCoreCaloCut", m_detRCoreCaloCut);
+    declareProperty("detRIsolCaloCut", m_detRIsolCaloCut);
+    declareProperty("ETCellMinCut", m_ETCellMinCut);
+    declareProperty("ETStripMinCut", m_ETStripMinCut);
+    declareProperty("detaStripCut", m_detaStripCut);
+    declareProperty("CellCorrection", m_doCellCorrection);
+    declareProperty("OriginCorrectionTool", m_tauOriginCorrTool);
+
+}
+
+
+//-------------------------------------------------------------------------
+// Destructor
+//-------------------------------------------------------------------------
+
+TauEflowAddCaloInfo::~TauEflowAddCaloInfo() { }
+
+
+//-------------------------------------------------------------------------
+// Initializer
+//-------------------------------------------------------------------------
+
+StatusCode TauEflowAddCaloInfo::initialize() {
+
+    ATH_MSG_VERBOSE(name() << " RconeTauCut            = " << m_detRIsolCaloCut);
+    ATH_MSG_VERBOSE(name() << " RconeCoreCut           = " << m_detRCoreCaloCut);
+    ATH_MSG_VERBOSE(name() << " ETCellMinCut           = " << m_ETCellMinCut);
+    ATH_MSG_VERBOSE(name() << " ETStripMinCut          = " << m_ETStripMinCut);
+    ATH_MSG_VERBOSE(name() << " detaStripCut           = " << m_detaStripCut);
+
+    if (m_tauOriginCorrTool.retrieve().isFailure()) {
+        ATH_MSG_ERROR("Cannot find tool named <" << m_tauOriginCorrTool << ">");
+        return StatusCode::FAILURE;
+    }
+    ATH_MSG_VERBOSE("tau Origin Correction Tool <" << m_tauOriginCorrTool << "> retrieved");
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauEflowAddCaloInfo::eventInitialize(TauCandidateData * /*data*/) 
+{
+    if (m_doCellCorrection) {
+        // Cell Origin Correction Tool initializeEvent is not called automatically
+        // -> call from here
+        return m_tauOriginCorrTool->eventInitialize();
+    }
+    return StatusCode::SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// Execution
+//-------------------------------------------------------------------------
+
+StatusCode TauEflowAddCaloInfo::execute(TauCandidateData *data) {
+
+    Analysis::TauJet *pTau = data->tau;
+    Analysis::TauCommonDetails *pDetails = dynamic_cast<Analysis::TauCommonDetails *> (data->details);
+    Analysis::TauCommonExtraDetails *pExtraDetails = dynamic_cast<Analysis::TauCommonExtraDetails *> (data->extraDetails);
+
+    if (pTau->numTrack() == 0) {
+        ATH_MSG_VERBOSE("tau has no tracks -> skip EflowAddCaloInfo");
+        return StatusCode::SUCCESS;
+    }
+
+    if (!pDetails || !pExtraDetails) {
+        ATH_MSG_ERROR("TauCommon(Extra)Details object not valid");
+        return StatusCode::FAILURE;
+    }
+
+    StatusCode sc;
+
+
+    //-----------------------------------------------------------------
+    // Variable initialization
+    //-----------------------------------------------------------------
+    int nStrips = 0;
+    double sumETR02 = 0;
+    double sumETR01 = 0;
+    double sumET012 = 0;
+    double sumDetET012 = 0;
+    double stripEta = 0;
+    double stripEta2 = 0;
+    double stripET = 0;
+    double detPhi = 999.;
+    double detEta = 999.;
+    double detCell = 999.;
+    double sumETotherHAD = 0;
+    double sumETotherEM = 0;
+    double sumETchrgHAD = 0;
+    double stripWidth2 = 0;
+    double Rem = 0;
+    double fracETR12 = 0;
+
+    //-----------------------------------------------------------------
+    // Loop on cells placed there by TauEflowTrackMatchCells
+    //-----------------------------------------------------------------
+    if (!pTau->cellCluster()) return StatusCode::FAILURE;
+    
+    //use tau vertex to correct cell position
+    if (m_doCellCorrection) {
+        m_tauOriginCorrTool->setOriginSource(pTau->origin());
+    }
+
+    const CaloCluster *pCluster = pTau->cellCluster();
+    CaloCluster::cell_iterator cellItr = pCluster->cell_begin();
+    CaloCluster::cell_iterator cellItrE = pCluster->cell_end();
+
+    const CaloCell *pCell;
+
+    //loop on cells connected to object
+    for (; cellItr != cellItrE; ++cellItr) {
+
+        pCell = (*cellItr);
+        
+        // correct cell for tau vertex
+        if (m_doCellCorrection) {
+             m_tauOriginCorrTool->correctCell(pCell);
+        }      
+        double cellPhi = pCell->phi();
+        double cellEta = pCell->eta();
+        double cellET  = pCell->et();
+        double cellEnergy = pCell->energy();
+        
+        if (m_doCellCorrection) {
+             m_tauOriginCorrTool->resetCell(pCell);
+        }
+
+        if (cellET < m_ETCellMinCut) continue;
+
+        int sampling = pCell->caloDDE()->getSampling();
+        if (sampling > 3 && sampling < 8) sampling = sampling - 4;
+
+        int i = 2;
+        if (sampling < 4) i = sampling;
+
+        const CaloCell* ccEta = pExtraDetails->closestEtaTrkVertCell(0, i);
+        const CaloCell* ccPhi = pExtraDetails->closestPhiTrkVertCell(0, i);
+
+        if (ccPhi) {
+            detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, ccPhi->phi());
+        } else {
+            detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, pTau->track(0)->phi());
+        }
+
+        if (ccEta) {
+            detEta = Tau1P3PKineUtils::deltaEta(cellEta, ccEta->eta());
+        } else {
+            detEta = Tau1P3PKineUtils::deltaEta(cellEta, pTau->track(0)->eta());
+        }
+
+        detCell = Tau1P3PKineUtils::deltaR(detPhi, detEta);
+
+
+        //-------------------------------------------------------------
+        // Cuts
+        //-------------------------------------------------------------
+        if (detCell > m_detRIsolCaloCut) continue;
+
+        if (detCell > m_detRCoreCaloCut) {
+            if (sampling > 3) {
+                sumETotherHAD += cellEnergy / cosh(cellEta);
+            } else {
+                sumETotherEM += cellET;
+            }
+        }
+
+        if (detCell > m_detRCoreCaloCut) continue;
+
+        if (sampling > 2) sumETchrgHAD += cellET;
+
+        if (sampling == 1 && cellET > m_ETStripMinCut) {
+            const CaloCell* ccEta1 = *pExtraDetails->closestEtaTrkVertCell()[0][1];
+
+            detEta = Tau1P3PKineUtils::deltaEta(cellEta, ccEta1->eta());
+
+            if (std::fabs(detEta) < m_detaStripCut) {
+                ++nStrips;
+            }
+        }
+
+        if (detCell < m_detRCoreCaloCut) sumETR02 += cellET;
+
+        if (detCell < m_detRCoreCaloCut / 2.) sumETR01 += cellET;
+
+        if (sampling > 2) continue;
+
+        sumET012 += cellET;
+        sumDetET012 += cellET * detCell;
+
+        if (sampling != 1) continue;
+
+        stripEta += cellEta * cellET;
+        stripEta2 += cellEta * cellEta * cellET;
+        stripET += cellET;        
+    }  // end cell loop
+
+    if (sumET012 > 0) Rem = sumDetET012 / sumET012;
+
+    if (sumETR02 > 0) fracETR12 = (sumETR02 - sumETR01) / sumETR02;
+
+    if (stripET > 0.0) stripWidth2 = (stripEta2 / stripET - stripEta * stripEta / stripET / stripET);
+
+
+    //-----------------------------------------------------------------
+    // Set properties
+    //-----------------------------------------------------------------
+    ATH_MSG_VERBOSE(name() << " taurec nStrips " << nStrips);
+    pDetails->setSeedTrk_nStrip(nStrips);
+
+    ATH_MSG_VERBOSE(name() << " Rem " << Rem);
+    pDetails->setSeedTrk_EMRadius(Rem);
+
+    ATH_MSG_VERBOSE(name() << " fracETR1 " << fracETR12);
+    pDetails->setSeedTrk_isolFrac(fracETR12);
+
+    ATH_MSG_VERBOSE(name() << " stripWidth2 " << stripWidth2);
+    pDetails->setSeedTrk_stripWidth2(stripWidth2);
+
+    ATH_MSG_VERBOSE(name() << " sumETotherHAD " << sumETotherHAD);
+    pDetails->setSeedTrk_etIsolHad(sumETotherHAD);
+
+    ATH_MSG_VERBOSE(name() << " sumETotherEM " << sumETotherEM);
+    pDetails->setSeedTrk_etIsolEM(sumETotherEM);
+
+    ATH_MSG_VERBOSE(name() << " sumETchrgHAD " << sumETchrgHAD);
+    pDetails->setSeedTrk_etChrgHad(sumETchrgHAD);
+
+    return sc;
+
+}
diff --git a/Reconstruction/tauRec/depreciated/TauEflowAddCaloInfo.h b/Reconstruction/tauRec/depreciated/TauEflowAddCaloInfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..ae12b5802f3f12d3e1a97bafacb62034dc089a4b
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauEflowAddCaloInfo.h
@@ -0,0 +1,53 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUEFLOWADDCALOINFO_H
+#define	TAUREC_TAUEFLOWADDCALOINFO_H
+
+#include "tauRec/TauToolBase.h"
+
+class TauOriginCorrectionTool;
+
+/**
+ * @brief Calculate calorimeter variables and their distances to the leading tau track. 
+ * 
+ *  Use cells placed there by TauEflowTrackMatchCells.
+ *  This tool was formerly named as tau1p3pAddCaloInfo.
+ * 
+ * @authors Lukasz Janyst, Anna Kaczmarska
+ * 
+ */
+
+class TauEflowAddCaloInfo : public TauToolBase {
+public:
+
+    TauEflowAddCaloInfo(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+
+    virtual ~TauEflowAddCaloInfo();
+    
+    virtual StatusCode initialize();
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode eventInitialize(TauCandidateData *data);
+
+
+private:
+    double m_detRCoreCaloCut;
+    double m_detRIsolCaloCut;
+    double m_ETCellMinCut;
+    double m_ETStripMinCut;
+    double m_detaStripCut;
+    
+    /** 
+     * enable cell origin correction 
+     * eta and phi of the cells are corrected wrt to the origin of the tau vertex
+    */
+    bool m_doCellCorrection;
+    ToolHandle<TauOriginCorrectionTool> m_tauOriginCorrTool;
+
+};
+
+#endif	/* TAUREC_TAUEFLOWADDCALOINFO_H */
+
diff --git a/Reconstruction/tauRec/depreciated/TauEflowTrackMatchCells.cxx b/Reconstruction/tauRec/depreciated/TauEflowTrackMatchCells.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0df1ab35be2a5d0006da437f975c20504fa690d3
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauEflowTrackMatchCells.cxx
@@ -0,0 +1,529 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        tau1p3pTrackMatchCells.cxx
+// package:     Reconstruction/tauRec
+// authors:     Tadeusz Szymocha, Anna Kaczmarska
+// date:        2005-07-01
+//
+// Tool for building CaloCluster of cells associated with 
+// a given track.
+//
+// MODIFIED:
+// 08/10/2006 - (AK) change of m_RconeTauCut -> m_detRIsolCaloCut
+// 18/03/2008 - (AK) changing cone for cell preselection 0.8->0.45
+// 11/04/2008 - (AK) moving select cone size to tool properties
+// 30/06/2008 - (AK) (for MW) fix of memory leak
+// 16/03/2010 - (AK) initialization of triggerFlag variable 
+// 17/03/2010 - (AK) change to P4Helpers
+// 16/05/2010 - (FF) pointer p_measPer never used (coverity 22628)
+//-----------------------------------------------------------------------------
+
+//TODO: change statuscode failure --> recoverable
+
+#include "tauRec/TauEflowTrackMatchCells.h"
+
+#include "tauEvent/TauCommonDetails.h"
+#include "tauEvent/TauCommonExtraDetails.h"
+#include "tauRec/KineUtils.h"
+#include "tauRec/TauOriginCorrectionTool.h"
+
+#include <CaloEvent/CaloCluster.h>
+#include <CaloUtils/CaloClusterStoreHelper.h>
+#include "CaloInterface/ICaloNoiseTool.h"
+#include "CaloUtils/CaloCellList.h"
+#include "CaloEvent/CaloCell.h"
+#include "CaloIdentifier/CaloCell_ID.h"
+
+#include "FourMomUtils/P4Helpers.h"
+#include "FourMom/P4EEtaPhiM.h"
+
+#include <GaudiKernel/ListItem.h>
+#include <algorithm>
+
+static void delete_cluster(std::pair<Analysis::TauJet * const, CaloCluster *> &pr) {
+    pr.first->cellClusterLink().reset();
+    delete pr.second;
+}
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+
+TauEflowTrackMatchCells::TauEflowTrackMatchCells(const std::string &type,
+    const std::string &name,
+    const IInterface *parent) :
+TauToolBase(type, name, parent),
+m_cellsContainerName("AllCalo"),
+m_detRIsolCaloCut(0.4),
+m_useNoiseSigma(1),
+m_AbsNoiseSigma_cut(2),
+m_selectConeSize(0.45),
+m_doCellCorrection(false), //FF: don't do cell correction by default
+m_tauOriginCorrTool("")  {
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("CellsContainerName", m_cellsContainerName);
+    // declare large fixed cone for creating subcollection of cells (cluster)
+    declareProperty("detRIsolCaloCut", m_detRIsolCaloCut);
+    // declare options for noise/weighting
+    declareProperty("useNoiseSigma", m_useNoiseSigma);
+    declareProperty("AbsNoiseSigma_cut", m_AbsNoiseSigma_cut);
+    declareProperty("CaloNoiseTool", m_noiseTool, "Tool Handle for noise tool");
+    declareProperty("ClusterContainerName", m_clusterContainerName = "Tau1P3PCellCluster");
+    //ak
+    declareProperty("ClusterEMContainerName", m_clusterEMContainerName = "Tau1P3PCellEM012ClusterContainer");
+    declareProperty("selectConeSize", m_selectConeSize);
+    declareProperty("CellCorrection", m_doCellCorrection);
+    declareProperty("OriginCorrectionTool", m_tauOriginCorrTool);
+}
+
+
+//-----------------------------------------------------------------------------
+// Destructor
+//-----------------------------------------------------------------------------
+
+TauEflowTrackMatchCells::~TauEflowTrackMatchCells() {
+}
+
+//-------------------------------------------------------------------------
+// Initializer
+//-------------------------------------------------------------------------
+
+StatusCode TauEflowTrackMatchCells::initialize() {
+    ATH_MSG_VERBOSE(name() << " CellsContainerName = " << m_cellsContainerName);
+    ATH_MSG_VERBOSE(name() << " RconeTauCut        = " << m_detRIsolCaloCut);
+    ATH_MSG_VERBOSE(name() << " selectConeSize     = " << m_selectConeSize);
+
+    //Create Noise Tools:
+    if (m_useNoiseSigma != 0) {
+        // SL changes to retrieval of CaloNoiseTool
+        if (m_noiseTool.retrieve().isFailure()) {
+            ATH_MSG_FATAL("Unable to retrieve CaloNoiseTool");
+            return StatusCode::FAILURE;
+        }
+    }
+    
+    if (m_tauOriginCorrTool.retrieve().isFailure()) {
+        ATH_MSG_ERROR("Cannot find tool named <" << m_tauOriginCorrTool << ">");
+        return StatusCode::FAILURE;
+    }
+    ATH_MSG_VERBOSE("tau Origin Correction Tool <" << m_tauOriginCorrTool << "> retrieved");
+    
+    return StatusCode::SUCCESS;
+}
+
+
+//-----------------------------------------------------------------------------
+// Event Initializer
+//-----------------------------------------------------------------------------
+
+StatusCode TauEflowTrackMatchCells::eventInitialize(TauCandidateData *) {
+    m_clusterMap.clear();
+    
+    if (m_doCellCorrection) {
+        // Cell Origin Correction Tool initializeEvent is not called automatically
+        // -> call from here
+        return m_tauOriginCorrTool->eventInitialize();
+    }
+    return StatusCode::SUCCESS;
+}
+
+
+//-------------------------------------------------------------------------
+// Event Finalizer
+//-------------------------------------------------------------------------
+
+StatusCode TauEflowTrackMatchCells::eventFinalize(TauCandidateData *data) {
+
+    MsgStream rLog(msgSvc(), name());
+
+    StatusCode sc;
+
+    //----------------------------------------------------------------------
+    // Check if we're running in the trigger
+    //----------------------------------------------------------------------
+    bool triggerFlag = false;
+    sc = data->getObject("InTrigger?", triggerFlag);
+    if (sc.isSuccess() && triggerFlag) {
+        //------------------------------------------------------------------
+        // Delete all the clusters
+        //------------------------------------------------------------------
+        std::for_each(m_clusterMap.begin(), m_clusterMap.end(), delete_cluster);
+
+        Analysis::TauDetailsContainer *pCont = data->detailsContainer;
+        Analysis::TauDetailsContainer::iterator it1;
+        for (it1 = pCont->begin(); it1 != pCont->end(); ++it1) {
+            Analysis::TauDetails *td = *it1;
+            Analysis::TauCommonDetails *det = dynamic_cast<Analysis::TauCommonDetails *> (td);
+            if (det) {
+                delete det->cellEM012Cluster();
+                det->cellEM012ClusterLink().reset();
+            }
+        }
+        return StatusCode::SUCCESS;
+    }
+
+    //----------------------------------------------------------------------
+    // Create cluster container
+    //----------------------------------------------------------------------
+    CaloClusterContainer *clusterContainer = new CaloClusterContainer();
+    //XXX need to check if we need this tool anymore. For now just make it fail all the time
+    sc = StatusCode::FAILURE;
+    // sc = CaloClusterStoreHelper::recordClusters(&*evtStore(),
+    //     clusterContainer,
+    //     m_clusterContainerName,
+    //     rLog);
+
+    //----------------------------------------------------------------------
+    // Put all clusters in the container
+    //----------------------------------------------------------------------
+    std::map<Analysis::TauJet *, CaloCluster *> ::iterator it;
+    for (it = m_clusterMap.begin(); it != m_clusterMap.end(); ++it)
+        clusterContainer->push_back((*it).second);
+
+    //ak 
+    std::sort(clusterContainer->begin(), clusterContainer->end(), OrderClust());
+
+    //---------------------------------------------------------------------
+    // Record cluster container
+    //---------------------------------------------------------------------
+    //XXX need to check if we need this tool anymore. For now just make it fail all the time
+    sc = StatusCode::FAILURE;
+    // sc = CaloClusterStoreHelper::finalizeClusters(&*evtStore(),
+    //     clusterContainer,
+    //     m_clusterContainerName,
+    //     rLog);
+
+
+    //---------------------------------------------------------------------
+    // Set up element links
+    //---------------------------------------------------------------------
+    for (it = m_clusterMap.begin(); it != m_clusterMap.end(); ++it)
+        (*it).first->setCellCluster(clusterContainer, (*it).second);
+
+    //----------------------------------------------------------------------
+    // Create EM cluster container
+    //----------------------------------------------------------------------
+    CaloClusterContainer *clusterEMContainer = new CaloClusterContainer();
+    //XXX need to check if we need this tool anymore. For now just make it fail all the time
+    sc = StatusCode::FAILURE;
+    // sc = CaloClusterStoreHelper::recordClusters(&*evtStore(),
+    //     clusterEMContainer,
+    //     m_clusterEMContainerName,
+    //     rLog);
+
+    //----------------------------------------------------------------------
+    // Put all clusters in the container
+    //----------------------------------------------------------------------
+    Analysis::TauDetailsContainer *pCont = data->detailsContainer;
+    Analysis::TauDetailsContainer::iterator it1;
+    for (it1 = pCont->begin(); it1 != pCont->end(); ++it1) {
+        Analysis::TauDetails *td = *it1;
+        Analysis::TauCommonDetails *det = dynamic_cast<Analysis::TauCommonDetails *> (td);
+        if (det) {
+            if (det->cellEM012Cluster()) {
+                clusterEMContainer->push_back(const_cast<CaloCluster *> (det->cellEM012Cluster()));
+            }
+        }
+    }
+
+    //---------------------------------------------------------------------
+    // Record cluster container
+    //---------------------------------------------------------------------
+    //XXX need to check if we need this tool anymore. For now just make it fail all the time
+    sc = StatusCode::FAILURE;
+    // sc = CaloClusterStoreHelper::finalizeClusters(&*evtStore(),
+    //     clusterEMContainer,
+    //     m_clusterEMContainerName,
+    //     rLog);
+
+    //---------------------------------------------------------------------
+    // Set up element links
+    //---------------------------------------------------------------------
+    for (it1 = pCont->begin(); it1 != pCont->end(); ++it1) {
+        Analysis::TauDetails *td = *it1;
+        Analysis::TauCommonDetails *det = dynamic_cast<Analysis::TauCommonDetails *> (td);
+        if (det) {
+            if (det->cellEM012Cluster()) {
+                det->setCellEM012Cluster(clusterEMContainer, det->cellEM012Cluster());
+            }
+        }
+    }
+
+    return sc;
+}
+
+//-----------------------------------------------------------------------------
+// Cleanup, in case this candidate was rejected later
+//-----------------------------------------------------------------------------
+
+void TauEflowTrackMatchCells::cleanup(TauCandidateData *data) {
+
+    //-------------------------------------------------------------------------
+    // Cleanup cluster
+    //-------------------------------------------------------------------------
+    Analysis::TauJet *pTau = data->tau;
+    std::map<Analysis::TauJet *, CaloCluster *> ::iterator it;
+    it = m_clusterMap.find(pTau);
+
+    if (it != m_clusterMap.end()) {
+        delete (*it).second;
+        m_clusterMap.erase(it);
+    }
+
+    pTau->cellClusterLink().reset();
+
+    //-------------------------------------------------------------------------
+    // Cleanup EM012Cluster
+    //-------------------------------------------------------------------------
+    Analysis::TauCommonDetails *pDetails = dynamic_cast<Analysis::TauCommonDetails *> (data->details);
+    if (pDetails) {
+        delete pDetails->cellEM012Cluster();
+        pDetails->cellEM012ClusterLink().reset();
+    }
+}
+
+
+//-------------------------------------------------------------------------
+// Execution
+//-------------------------------------------------------------------------
+
+StatusCode TauEflowTrackMatchCells::execute(TauCandidateData *data) {
+
+    // Analysis::TauJet *pTau = data->tau;
+    // Analysis::TauCommonDetails *pDetails = dynamic_cast<Analysis::TauCommonDetails *> (data->details);
+    // Analysis::TauCommonExtraDetails *pExtraDetails = dynamic_cast<Analysis::TauCommonExtraDetails *> (data->extraDetails);
+
+    // //
+    // if (pTau->numTrack()==0) {
+    //     ATH_MSG_VERBOSE("tau has no tracks -> skip TrackMatchCells");
+    //     return StatusCode::SUCCESS;
+    // }
+    
+    // if ( !pDetails || !pExtraDetails) {
+    //   ATH_MSG_ERROR("TauCommon(Extra)Details object not valid");
+    //   return StatusCode::FAILURE;
+    // }
+
+    // StatusCode sc;
+
+    
+    // //---------------------------------------------------------------------
+    // // Retrieve CaloCellCollection from StoreGate
+    // //---------------------------------------------------------------------
+    // const CaloCellContainer *pCellContainer;
+
+    // sc = data->getObject("CellContainer", pCellContainer);
+    // if (sc.isFailure() || !pCellContainer) {
+    //     sc = evtStore()->retrieve(pCellContainer, m_cellsContainerName);
+    //     if (sc.isFailure()) {
+    //         ATH_MSG_INFO("TrackMatchCells: Unable to retrieve " << m_cellsContainerName << " from TES");
+    //     }
+    // }
+
+    // xAOD::CaloCluster *pCluster = CaloClusterStoreHelper::makeCluster();
+    // xAOD::CaloCluster *pClusterEM = CaloClusterStoreHelper::makeCluster();
+
+    // //put cluster into object
+    // pTau->cellClusterLink().reset();
+    // pTau->cellClusterLink().setElement(pCluster);
+    // m_clusterMap[pTau] = pCluster;
+
+    // pDetails->cellEM012ClusterLink().reset();
+    // pDetails->cellEM012ClusterLink().setElement(pClusterEM);
+
+    // //---------------------------------------------------------------------
+    // // Loop over cells collection and find closest cell at a given layer
+    // // from track impact point at vertex and propagated in magnetic field
+    // //---------------------------------------------------------------------
+
+    // const int nTr = 10;
+    // const int nSa = 4;
+
+    // double detEtaCellMin[nTr][nSa], detPhiCellMin[nTr][nSa];
+    // double detEtaCellMinCh[nTr][nSa], detPhiCellMinCh[nTr][nSa];
+    // double detEtaVertMin[nSa], detPhiVertMin[4];
+
+    // const CaloCell * pTmpEtaCell[nTr][nSa];
+    // const CaloCell * pTmpPhiCell[nTr][nSa];
+    // const CaloCell * pTmpEtaVertCell[nSa];
+    // const CaloCell * pTmpPhiVertCell[nSa];
+
+
+    // for (int i = 0; i < nSa; ++i) {
+    //     detEtaVertMin[i] = 9999.;
+    //     detPhiVertMin[i] = 9999.;
+
+    //     pTmpEtaVertCell[i] = 0;
+    //     pTmpPhiVertCell[i] = 0;
+
+    //     for (int j = 0; j < nTr; ++j) {
+    //         detEtaCellMin[j][i] = 9999.;
+    //         detPhiCellMin[j][i] = 9999.;
+
+    //         detEtaCellMinCh[j][i] = 9999.;
+    //         detPhiCellMinCh[j][i] = 9999.;
+
+    //         pTmpEtaCell[j][i] = 0;
+    //         pTmpPhiCell[j][i] = 0;
+    //     }
+    // }
+
+    // const CaloCell *pCell;
+    // pCell = 0;
+
+    // /* FF:  
+    // //do cell selection
+    // CaloCellList *celllist = new CaloCellList(pCellContainer);
+    // celllist->select(pTau->track(0)->eta(), pTau->track(0)->phi(), m_selectConeSize);
+
+    // if (celllist->ncells() == 0) {
+    //     delete celllist;
+    //     return StatusCode::FAILURE;
+    // }
+    
+    // CaloCellList::list_iterator itr = celllist->begin();
+    // CaloCellList::list_iterator itrE = celllist->end();
+    //  */
+     
+     
+    // //use tau vertex to correct cell position
+    // if (m_doCellCorrection) {
+    //     m_tauOriginCorrTool->setOriginSource(pTau->origin());
+    // }
+
+    // //FF: use cells already associated to jet seed
+    // // this is valid until m_selectConeSize is < or about 0.4
+    // typedef NavigationToken<CaloCell, NavigationDefaults::DefaultWeight, CaloCellIDFcn> token_t;
+    // token_t nt;
+    // pTau->fillToken(nt);
+
+    // token_t::const_iterator itr = nt.begin();
+    // token_t::const_iterator itrE = nt.end();
+    // //
+
+    // //loop over cells and calculate the variables  
+    // for (; itr != itrE; itr++) {
+    //     pCell = *itr;
+        
+    //     // correct cell for tau vertex
+    //     if (m_doCellCorrection) {
+    //          m_tauOriginCorrTool->correctCell(pCell);
+    //     }
+        
+    //     double cellPhi = pCell->phi();
+    //     double cellEta = pCell->eta();
+    //     double cellEnergy = pCell->energy();
+        
+    //     if (m_doCellCorrection) {
+    //          m_tauOriginCorrTool->resetCell(pCell);
+    //     }
+
+    //     double detCell = P4Helpers::deltaR(*pTau->track(0), cellEta, cellPhi);
+
+    //     // collect all cells (remove noisy cells ) in a fixed
+    //     // large cone around candidate (at vertex)
+    //     if (detCell > m_detRIsolCaloCut) continue;
+
+    //     int isCellAccepted = 1;
+
+    //     if (m_useNoiseSigma == 1) {
+    //         double noiseSigma;
+    //         noiseSigma = m_noiseTool->getNoise(*itr, ICalorimeterNoiseTool::ELECTRONICNOISE_HIGHESTGAIN);
+    //         if (fabs(cellEnergy) < m_AbsNoiseSigma_cut * noiseSigma) isCellAccepted = 0;
+
+    //     }
+
+    //     // add cells above the noise to the associated cluster
+    //     if (isCellAccepted == 1) pCluster->addCell(pCellContainer, pCell, 1.0);
+
+    //     // find position nominal position of the closest cell at each layer
+    //     int samp = CaloSampling::getSampling(*pCell);
+    //     if (samp > 3 && samp < 8) samp = samp - 4;
+
+    //     //ak
+    //     if (samp < 3 && isCellAccepted == 1) pClusterEM->addCell(pCellContainer, pCell, 1.0);
+
+    //     // consider only sampling < 4
+    //     if (samp >= 4) continue;
+
+    //     double detPhiVert = Tau1P3PKineUtils::deltaPhi(cellPhi, pTau->phi());
+    //     double detEtaVert = Tau1P3PKineUtils::deltaEta(cellEta, pTau->eta());
+
+    //     if (detEtaVert < detEtaVertMin[samp]) {
+    //         detEtaVertMin[samp] = detEtaVert;
+    //         pTmpEtaVertCell[samp] = pCell;
+    //     }
+
+    //     if (detPhiVert < detPhiVertMin[samp]) {
+    //         detPhiVertMin[samp] = detPhiVert;
+    //         pTmpPhiVertCell[samp] = pCell;
+    //     }
+
+    //     //for each track connected to tau object
+    //     for (unsigned itr = 0; itr < pTau->numTrack(); itr++) {
+    //         // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks)
+    //         if (itr >= 9) break;
+
+    //         double detEtaCell[nTr];
+    //         double detPhiCell[nTr];
+    //         detEtaCell[itr] = Tau1P3PKineUtils::deltaEta(cellEta, pExtraDetails->etaTrkCaloSamp()[itr][samp]);
+    //         detPhiCell[itr] = Tau1P3PKineUtils::deltaPhi(cellPhi, pExtraDetails->phiTrkCaloSamp()[itr][samp]);
+
+    //         //FIX ME! Should we look for different cell in eta and
+    //         //in phi? ot the closest one?
+
+    //         if (detEtaCell[itr] < detEtaCellMin[itr][samp]) {
+    //             detEtaCellMin[itr][samp] = detEtaCell[itr];
+    //             pTmpEtaCell[itr][samp] = pCell;
+    //         }
+
+    //         if (detPhiCell[itr] < detPhiCellMin[itr][samp]) {
+    //             detPhiCellMin[itr][samp] = detPhiCell[itr];
+    //             pTmpPhiCell[itr][samp] = pCell;
+    //         }
+
+    //         // for better collection of energy around charged track...
+    //         // correct if possible and consider only
+    //         // cells with really deposited energy
+    //         if (isCellAccepted == 0) continue;
+
+    //         if (detEtaCell[itr] < detEtaCellMinCh[itr][samp]) {
+    //             detEtaCellMinCh[itr][samp] = detEtaCell[itr];
+    //             pTmpEtaCell[itr][samp] = pCell;
+    //         }
+
+    //         if (detPhiCell[itr] < detPhiCellMinCh[itr][samp]) {
+    //             detPhiCellMinCh[itr][samp] = detPhiCell[itr];
+    //             pTmpPhiCell[itr][samp] = pCell;
+    //         }
+    //     } // end track loop 
+        
+    // } // end cell loop 
+
+    // // loop over sampling
+    // for (int i = 0; i < 4; i++) {
+    //     if (pTmpEtaVertCell[i]) pExtraDetails->setClosestEtaTrkVertCell(pTmpEtaVertCell[i], pCellContainer, 0, i);
+    //     if (pTmpPhiVertCell[i]) pExtraDetails->setClosestPhiTrkVertCell(pTmpPhiVertCell[i], pCellContainer, 0, i);
+
+    //     for (unsigned itr = 0; itr < pTau->numTrack(); itr++) {
+    //         // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks)
+    //         if (itr >= 9) break;
+    //         if (pTmpEtaCell[itr][i]) pExtraDetails->setClosestEtaTrkCell(pTmpEtaCell[itr][i], pCellContainer, itr, i);
+    //         if (pTmpPhiCell[itr][i]) pExtraDetails->setClosestPhiTrkCell(pTmpPhiCell[itr][i], pCellContainer, itr, i);
+    //     }
+    // }
+
+    // //FF:
+    // //delete celllist;
+
+    // return sc;
+  return StatusCode::SUCCESS;
+}
+
+
+
+
diff --git a/Reconstruction/tauRec/depreciated/TauEflowTrackMatchCells.h b/Reconstruction/tauRec/depreciated/TauEflowTrackMatchCells.h
new file mode 100644
index 0000000000000000000000000000000000000000..824d2883e5e3259c68e27f75bf216e44e0f155dd
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauEflowTrackMatchCells.h
@@ -0,0 +1,93 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUEFLOWTRACKMATCHCELLS_H
+#define TAUREC_TAUEFLOWTRACKMATCHCELLS_H
+
+#include <map>
+
+#include "GaudiKernel/ToolHandle.h"
+#include "CaloInterface/ICalorimeterNoiseTool.h"
+#include "CaloEvent/CaloClusterContainer.h"
+
+#include "tauRec/TauToolBase.h"
+
+class TauOriginCorrectionTool;
+
+/**
+ * @brief Tool for building CaloCluster of cells associated with a given tau.
+ * 
+ *  This tool was formerly named as tau1p3pTrackMatchCells.
+ * 
+ * @authors Tadeusz Szymocha, Anna Kaczmarska
+ * 
+ */
+
+class TauEflowTrackMatchCells : public TauToolBase
+{
+  public:
+
+    TauEflowTrackMatchCells(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+
+    virtual ~TauEflowTrackMatchCells();
+
+    virtual StatusCode initialize();
+    virtual StatusCode eventInitialize(TauCandidateData *data);
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode eventFinalize(TauCandidateData *data);
+
+    virtual void cleanup(TauCandidateData *data);
+
+  private:
+    std::string m_cellsContainerName;
+    std::string m_clusterContainerName;
+
+    //!  large fixed cone to collect cells around the track
+    double m_detRIsolCaloCut;
+
+    //!  use noise tool to estimate sigma
+    double m_useNoiseSigma;
+
+    //!  threshold to suppress noisy cells
+    double m_AbsNoiseSigma_cut;
+
+    //! cone for cell pre-selection
+    double m_selectConeSize;
+
+    //! tool for noise
+    ToolHandle <ICalorimeterNoiseTool> m_noiseTool;
+
+    std::map<Analysis::TauJet *, CaloCluster *> m_clusterMap;
+
+    std::string m_clusterEMContainerName;
+    
+    /** 
+     * enable cell origin correction 
+     * eta and phi of the cells are corrected wrt to the origin of the tau vertex
+    */
+    bool m_doCellCorrection;
+    ToolHandle<TauOriginCorrectionTool> m_tauOriginCorrTool;
+
+};
+
+//TODO: same as in CaloClusterVariables! --> move both to KinUtils.h?
+//-------------------------------------------------------------------------
+//! Descending order by energy
+//-------------------------------------------------------------------------
+
+struct OrderClust
+{
+    bool operator()(const CaloCluster *t1, const CaloCluster * t2) const {
+      //FF:: don't need a warning here
+      //if (t1->et() == t2->et()) {
+      //      std::cout << " tauRec:tau1p3pTrackMatchCells WARNING  Found two clusters with the same et ! " << t1->et() << std::endl;
+      //  }
+        return t1->et() < t2->et();
+    }
+};
+
+
+#endif
diff --git a/Reconstruction/tauRec/depreciated/TauEflowVariables.cxx b/Reconstruction/tauRec/depreciated/TauEflowVariables.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d999dd57e6919e29e9242b909b1f6d15938d305e
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauEflowVariables.cxx
@@ -0,0 +1,840 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        tau1p3pAddEflowInfo.cxx
+// package:     Reconstruction/tauRec
+// authors:     Tadeusz Szymocha, Anna Kaczmarska
+// date:        2006-02-09
+//
+// This tool builds energy flow quantities.
+//
+// MODIFIED:
+// 07/10/2005 - (LJ) Proper deletion of Pi0 clusters
+// 14/09/2006 - (LJ,AK) temporaty solution for removing cells
+//               from object in order to avoid problems with 
+//               casting CaloCellContainer to
+//               INavigable4MomentumCollection
+// 07/10/2005 - (LJ) Proper deletion of Pi0 clusters
+// 08/10/2006 - (AK) change of RconeCoreCut parameter name
+//                  fixing wrong reading of extrapolation point for
+//                  endcap in fillTopoClusterInfo
+// 03/11/2006 - (AK) added filling sumEM  
+// 07/11/2006 - (AK) preselection with cuts on MVisEflow, MTrk3P, ETeflow / ETcalo variables
+// 24/11/2006 - (AK) correcting phi barycenter calculation
+// 26/11/2006 - (ERW) corrected eflow calculation
+// 13/07/2007 - (AK) dynamic allocation of arrays
+// 23/04/2007 - (AK) adding writing pi0 container
+// 10/07/2007 - (AK) allowing ntrack>3 candidates 
+// 19/06/2007 - (ERW) removing writting pi0 container -> delegated to tau1p3pCreatePi0Cluster.cxx
+// 07/07/2007 - (ERW) removing filling sumEM -> delegated to tau1p3pCreatePi0Cluster.cxx
+// 04/01/2008 - (AK) adding low cut on etcalo/etflow
+// 10/06/2008 - (AK) fixing floating point exceptions (bug 37635)
+// 30/09/2008 - (AK) memory fragmentation fixes (bug 41937)
+// 09/10/2009 - (AK) correcting unchecked SC (bug 56754)
+// 17/05/2011 - (FF) add initializer for array (line 276) (coverity 20321)
+//-----------------------------------------------------------------------------
+
+//TODO: change statuscode failure to recoverable
+//TODO: AllCalo hardcoded
+
+#include <algorithm>
+#include <math.h>
+#include <sstream>
+
+#include "GaudiKernel/Property.h"
+#include "GaudiKernel/ListItem.h"
+#include "GaudiKernel/IToolSvc.h"
+
+#include "FourMom/P4EEtaPhiM.h"
+
+#include "CaloUtils/CaloCellList.h"
+#include "CaloEvent/CaloCluster.h"
+#include "CaloEvent/CaloCell.h"
+#include "AtlasDetDescr/AtlasDetectorID.h"
+#include "CaloIdentifier/CaloID.h"
+#include "CaloIdentifier/CaloCell_ID.h"
+#include "CaloGeoHelpers/CaloSampling.h"
+#include "CaloGeoHelpers/CaloPhiRange.h"
+
+#include "tauEvent/TauCommonDetails.h"
+#include "tauEvent/TauCommonExtraDetails.h"
+#include "tauRec/KineUtils.h"
+#include "tauRec/TauOriginCorrectionTool.h"
+#include "tauRec/TauEflowVariables.h"
+
+
+//-------------------------------------------------------------------------
+// Constructor
+//-------------------------------------------------------------------------
+
+TauEflowVariables::TauEflowVariables(const std::string &type,
+    const std::string &name,
+    const IInterface *parent) :
+TauToolBase(type, name, parent),
+m_detRCoreCaloCut(0.2),
+m_dphiEMCLCut(0.0375),
+m_detaEMCLCut(0.0375),
+m_dphiEMCLFACCut(2),
+m_detaEMCLFACCut(3),
+m_dphiChrgEMCut(0.0375),
+m_detaChrgEMCut(0.0375),
+m_CaloClusterContainerName("EMTopoCluster"),
+m_recoTopoClusterETCut(200.0),
+m_recoEtaCut(2.5),
+m_TrackTopoClusPhi2Cut(0.0375),
+m_TrackTopoClusEta1Cut(0.01),
+m_MVisEflowCut(10000),
+m_MTrk3PCut(10000),
+m_ETeflow_ETcaloCut(10.),
+m_ETeflow_ETcaloCutMin(0.1),
+m_maxClusterEta(4.0),
+m_useEMTopoClusters(true),
+m_doCellCorrection(false), //FF: don't do cell correction by default
+m_tauOriginCorrTool("") {
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("detRCoreCaloCut", m_detRCoreCaloCut);
+    declareProperty("dphiEMCLCut", m_dphiEMCLCut);
+    declareProperty("detaEMCLCut", m_detaEMCLCut);
+    declareProperty("dphiEMCLFACCut", m_dphiEMCLFACCut);
+    declareProperty("detaEMCLFACCut", m_detaEMCLFACCut);
+    declareProperty("dphiChrgEMCut", m_dphiChrgEMCut);
+    declareProperty("detaChrgEMCut", m_detaChrgEMCut);
+    declareProperty("CaloClusterContainerName", m_CaloClusterContainerName);
+    declareProperty("RecoTopoClusterETCut", m_recoTopoClusterETCut);
+    declareProperty("RecoEtaCut", m_recoEtaCut);
+    declareProperty("TrackTopoClusPhi2Cut", m_TrackTopoClusPhi2Cut);
+    declareProperty("TrackTopoClusEta1Cut", m_TrackTopoClusEta1Cut);
+    declareProperty("MVisEflowCut", m_MVisEflowCut);
+    declareProperty("MTrk3PCut", m_MTrk3PCut);
+    declareProperty("ETeflow_ETcaloCut", m_ETeflow_ETcaloCut);
+    declareProperty("ETeflow_ETcaloCutMin", m_ETeflow_ETcaloCutMin);
+    declareProperty("MaxClusterEta", m_maxClusterEta);
+    declareProperty("useEMTopoClusters", m_useEMTopoClusters);
+    declareProperty("CellCorrection", m_doCellCorrection);
+    declareProperty("OriginCorrectionTool", m_tauOriginCorrTool);
+}
+
+
+//-------------------------------------------------------------------------
+// Destructor
+//-------------------------------------------------------------------------
+
+TauEflowVariables::~TauEflowVariables() {
+}
+
+StatusCode TauEflowVariables::eventFinalize(TauCandidateData *) {
+
+    std::vector<int>().swap(m_isTopoClusQualif);
+    std::vector<int>().swap(m_closestTopoClusCell);
+    std::vector<double>().swap(m_TopoClustPhi);
+    std::vector<double>().swap(m_closestTopoClusCellPhi);
+    std::vector<double>().swap(m_closestTopoClusCellEta);
+    std::vector<double>().swap(m_TopoClusPhi);
+    std::vector<double>().swap(m_TopoClusEta);
+
+    return StatusCode::SUCCESS;
+}
+
+
+//-------------------------------------------------------------------------
+// Initializer
+//-------------------------------------------------------------------------
+
+StatusCode TauEflowVariables::initialize() {
+
+    StatusCode sc;
+
+    ATH_MSG_VERBOSE(name() << " RconeCoreCut           = " << m_detRCoreCaloCut);
+    ATH_MSG_VERBOSE(name() << " ETStripMinCut          = " << m_ETStripMinCut);
+    ATH_MSG_VERBOSE(name() << " detaStripCut           = " << m_detaStripCut);
+
+    //---------------------------------------------------------------------
+    // Retrieve pointer to ToolSvc
+    //---------------------------------------------------------------------
+    IToolSvc *pToolSvc;
+    sc = service("ToolSvc", pToolSvc);
+    if (sc.isFailure()) {
+        ATH_MSG_FATAL("Unable to retrieve pointer to ToolSvc");
+        return sc;
+    }
+    if (m_tauOriginCorrTool.retrieve().isFailure()) {
+        ATH_MSG_ERROR("Cannot find tool named <" << m_tauOriginCorrTool << ">");
+        return StatusCode::FAILURE;
+    }
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauEflowVariables::eventInitialize(TauCandidateData * /*data*/) 
+{
+    if (m_doCellCorrection) {
+        // Cell Origin Correction Tool initializeEvent is not called automatically
+        // -> call from here
+        return m_tauOriginCorrTool->eventInitialize();
+    }
+    return StatusCode::SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// Execution
+//-------------------------------------------------------------------------
+
+StatusCode TauEflowVariables::execute(TauCandidateData *data) {
+
+    Analysis::TauJet *pTau = data->tau;
+    Analysis::TauCommonDetails *pDetails = dynamic_cast<Analysis::TauCommonDetails *> (data->details);
+    Analysis::TauCommonExtraDetails *pExtraDetails = dynamic_cast<Analysis::TauCommonExtraDetails *> (data->extraDetails);
+
+    //
+    if (pTau->numTrack()==0) {
+        ATH_MSG_VERBOSE("tau has no tracks -> skip Eflow");
+        return StatusCode::SUCCESS;
+    }
+    
+    if ( !pDetails || !pExtraDetails) {
+      ATH_MSG_ERROR("TauCommon(Extra)Details object not valid");
+      return StatusCode::FAILURE;
+    }
+    
+    StatusCode sc;
+    
+    const CaloCellContainer *pCellContainer = 0;
+
+    // for tau trigger
+    sc = data->getObject("CellContainer", pCellContainer);
+    if (sc.isFailure() || !pCellContainer) {
+        // retrieve at the normal way
+        //TODO: AllCalo hardcoded!!
+        sc = evtStore()->retrieve(pCellContainer, "AllCalo");
+        if (sc.isFailure()) {
+            ATH_MSG_ERROR("Unable to find cell container");
+            return StatusCode::FAILURE;
+        }
+    }
+
+    const int nTr = 10;
+    double sumETCellsEM01Trk[nTr];
+    double sumETCellsChrgEMTrk[nTr];
+    double resChrgEMTrk[nTr];
+
+    for (int i = 0; i < nTr; ++i) {
+        sumETCellsEM01Trk[i] = 0.;
+        sumETCellsChrgEMTrk[i] = 0.;
+        resChrgEMTrk[i] = 0.;
+    }
+
+    double sumETcalo = 0.0;
+    double sumETcaloHAD = 0.0;
+    double sumETcaloEM = 0.0;
+    double sumETCellsEMCL = 0.0;
+    double sumETCellsNeuEM = 0.0;
+    double sumETCellsChrgEM = 0.0;
+    double sumETCellsChrgHAD = 0.0;
+    double sumETeflow = 0.0;
+    double resChrgEM = 0.0;
+    double resNeuEM = 0.0;
+    double resChrgEMTrkTot = 0.0;
+    double pttot = 0.0;
+
+    m_nTopoclust = 0;
+
+    //fill information about EM Clusters
+    if (m_useEMTopoClusters) {
+        sc = fillTopoClusterInfo(data);
+        if (sc.isFailure()) return sc;
+    }
+
+    //use tau vertex to correct cell position
+    if (m_doCellCorrection) {
+        m_tauOriginCorrTool->setOriginSource(pTau->origin());
+    }
+
+    //-----------------------------------------------------------------
+    // Loop on cells stored in object placed there by TauEflowTrackMatchCells
+    //-----------------------------------------------------------------
+    xAOD::CaloCluster* EMCLCluster = CaloClusterStoreHelper::makeCluster(pCellContainer);
+    xAOD::CaloCluster* NeuEMCluster = CaloClusterStoreHelper::makeCluster(pCellContainer);
+
+    const CaloCluster *pCluster = pTau->cellCluster();
+    CaloCluster::cell_iterator cellIter = pCluster->cell_begin();
+    CaloCluster::cell_iterator cellIterE = pCluster->cell_end();
+
+    const CaloCell *pCell;
+
+    for (; cellIter != cellIterE; ++cellIter) {
+        pCell = *cellIter;
+        
+        // correct cell for tau vertex
+        if (m_doCellCorrection) {
+             m_tauOriginCorrTool->correctCell(pCell);
+        }
+        
+        double cellEta = pCell->eta();
+        double cellPhi = pCell->phi();
+        double cellEt = pCell->et();
+        
+        if (m_doCellCorrection) {
+            m_tauOriginCorrTool->resetCell(pCell);
+        }  
+
+        int sampling = pCell->caloDDE()->getSampling();
+        if (sampling > 3 && sampling < 8) sampling = sampling - 4;
+
+        double detPhi, detEta, detPhiTrk[nTr] = {0.}, detEtaTrk[nTr] = {0.};
+
+        int i = 2;
+        if (sampling < 4) i = sampling;
+
+        if (pExtraDetails->closestPhiTrkVertCell(0, i))
+            detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, pExtraDetails->closestPhiTrkVertCell(0, i)->phi());
+        else
+            detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, pTau->track(0)->phi());
+
+        if (pExtraDetails->closestEtaTrkVertCell(0, i))
+            detEta = Tau1P3PKineUtils::deltaEta(cellEta, pExtraDetails->closestEtaTrkVertCell(0, i)->eta());
+        else
+            detEta = Tau1P3PKineUtils::deltaEta(cellEta, pTau->track(0)->eta());
+
+        double detCell = Tau1P3PKineUtils::deltaR(detPhi, detEta);
+
+        if (detCell > m_detRCoreCaloCut) continue;
+
+        //for each track connected to object
+        for (unsigned itr = 0; itr < pTau->numTrack(); ++itr) {
+            // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks)
+            if (itr >= 9) break;
+
+            detPhiTrk[itr] = 0.;
+            detEtaTrk[itr] = 0.;
+
+            if (pExtraDetails->closestPhiTrkCell(itr, i))
+                detPhiTrk[itr] = Tau1P3PKineUtils::deltaPhi(cellPhi, pExtraDetails->closestPhiTrkCell(itr, i)->phi());
+            else
+                detPhiTrk[itr] = Tau1P3PKineUtils::deltaPhi(cellPhi, pExtraDetails->phiTrkCaloSamp()[0][i]);
+
+            if (pExtraDetails->closestEtaTrkCell(itr, i))
+                detEtaTrk[itr] = Tau1P3PKineUtils::deltaEta(cellEta, pExtraDetails->closestEtaTrkCell(itr, i)->eta());
+            else
+                detEtaTrk[itr] = Tau1P3PKineUtils::deltaEta(cellEta, pExtraDetails->etaTrkCaloSamp()[0][i]);
+        }
+
+        sumETcalo += cellEt;
+
+        if (sampling < 4) sumETcaloEM += cellEt;
+        else sumETcaloHAD += cellEt;
+
+        int isCellBooked = 0;
+
+        //-----------------------------------------------------------------
+        // sumETCellsEMCL - first iteration for 
+        //-----------------------------------------------------------------
+        if (sampling <= 2) {
+            int kPi0 = -1;
+            for (int ic = 0; ic < m_nTopoclust; ++ic) {
+                if (m_isTopoClusQualif[ic] != 1) continue;
+
+                double detPhi, detEta, Rcone;
+
+                detPhi = Tau1P3PKineUtils::deltaPhi(pTau->phi(), m_TopoClusPhi[ic]);
+                detEta = Tau1P3PKineUtils::deltaEta(pTau->eta(), m_TopoClusEta[ic]);
+                Rcone = Tau1P3PKineUtils::deltaR(detPhi, detEta);
+                if (Rcone > m_detRCoreCaloCut) continue;
+
+                ++kPi0;
+
+                if (m_closestTopoClusCell[ic] != 0) {
+                    detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, m_closestTopoClusCellPhi[ic]);
+                    detEta = Tau1P3PKineUtils::deltaEta(cellEta, m_closestTopoClusCellEta[ic]);
+                } else {
+                    detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, m_TopoClusPhi[ic]);
+                    detEta = Tau1P3PKineUtils::deltaEta(cellEta, m_TopoClusEta[ic]);
+                }
+
+                if (detEta < m_detaEMCLCut && detPhi < m_dphiEMCLCut) {
+                    if (!isCellBooked) {
+                        sumETCellsEMCL += cellEt;
+                        EMCLCluster->addCell(pCellContainer->findIndex(pCell->caloDDE()->calo_hash()), 1.0);
+
+                        isCellBooked = 1;
+                    }
+                }
+                if (isCellBooked) break;
+            } // end track loop
+        }
+
+        if (isCellBooked) continue; // go to next cell
+
+        //-----------------------------------------------------------------
+        // sumETCellsChrgEM 
+        //-----------------------------------------------------------------
+        //for each track connected to tau object
+        for (unsigned itr = 0; itr < pTau->numTrack(); ++itr) {
+            // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks)
+            if (itr >= 9) break;
+
+            if (sampling <= 3 && detEtaTrk[itr] < m_detaChrgEMCut && detPhiTrk[itr] < m_dphiChrgEMCut) {
+                if (!isCellBooked) {
+                    sumETCellsChrgEM += cellEt;
+                    sumETCellsChrgEMTrk[itr] += cellEt;
+                    if (sampling <= 1) sumETCellsEM01Trk[itr] += cellEt;
+                    isCellBooked = 1;
+                }
+            }
+            if (isCellBooked) break;
+        } // end track loop
+
+        if (isCellBooked) continue; // go to next cell
+
+        //-----------------------------------------------------------------
+        // sumETCellsEMCL - second iteration for  
+        //-----------------------------------------------------------------
+        if (sampling <= 2) {
+            for (int ic = 0; ic < m_nTopoclust; ++ic) {
+                if (m_isTopoClusQualif[ic] != 1) continue;
+
+                double detPhi, detEta, Rcone;
+
+                detPhi = Tau1P3PKineUtils::deltaPhi(pTau->phi(), m_TopoClusPhi[ic]);
+                detEta = Tau1P3PKineUtils::deltaEta(pTau->eta(), m_TopoClusEta[ic]);
+                Rcone = Tau1P3PKineUtils::deltaR(detPhi, detEta);
+                if (Rcone > m_detRCoreCaloCut) continue;
+
+                if (m_closestTopoClusCell[ic] != 0) {
+                    detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, m_closestTopoClusCellPhi[ic]);
+                    detEta = Tau1P3PKineUtils::deltaEta(cellEta, m_closestTopoClusCellEta[ic]);
+                } else {
+                    detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, m_TopoClusPhi[ic]);
+                    detEta = Tau1P3PKineUtils::deltaEta(cellEta, m_TopoClusEta[ic]);
+                }
+
+                if (detEta < m_detaEMCLFACCut * m_detaEMCLCut && detPhi < m_dphiEMCLFACCut * m_dphiEMCLCut) {
+                    if (!isCellBooked) {
+                        sumETCellsEMCL += cellEt;
+                        EMCLCluster->addCell(pCellContainer->findIndex(pCell->caloDDE()->calo_hash()), 1.0);
+
+                        isCellBooked = 1;
+                    }
+                }
+                if (isCellBooked) break;
+            } // end track loop
+        }
+        if (isCellBooked) continue; // go to next cell
+
+        //-----------------------------------------------------------------
+        // sumETCellsNeuEM - from still not booked cells
+        //-----------------------------------------------------------------
+        //erw: layer 3 removed from sumETCellsNeuEM
+        if (sampling < 3) {
+            sumETCellsNeuEM += cellEt;
+            NeuEMCluster->addCell(pCellContainer->findIndex(pCell->caloDDE()->calo_hash()), 1.0);
+            isCellBooked = 1;
+        }
+        if (isCellBooked) continue; // go to next cell
+
+        //-----------------------------------------------------------------
+        // sumETCellsChrgHAD - from still not booked cells
+        //-----------------------------------------------------------------
+        //erw: layer 3 added to sumETCellsChrgHAD
+        if (sampling >= 3) {
+            sumETCellsChrgHAD += cellEt;
+            isCellBooked = 1;
+        }
+
+        // at this point cell should be booked already, print warning if it is not
+        if (!isCellBooked) ATH_MSG_WARNING("Please check why cell is not booked");
+    } // end cell loop
+
+    //-----------------------------------------------------------------
+    // calculate energy flow variables
+    //-----------------------------------------------------------------
+    //for 1 prong
+    if (pTau->numTrack() == 1) {
+        double leadTrkPt = pTau->track(0)->pt();
+
+        if ((sumETCellsEM01Trk[0] / leadTrkPt) < 0.05) {
+            resChrgEM = sumETCellsChrgEM - 0.7 * leadTrkPt;
+            if (resChrgEM < 0.0) resChrgEM = 0.0;
+            sumETeflow = sumETCellsEMCL + sumETCellsNeuEM + leadTrkPt + resChrgEM;
+        } else if ((sumETCellsEM01Trk[0] / leadTrkPt) > 0.05 && (sumETCellsChrgHAD / leadTrkPt) > 0.4) {
+            resChrgEM = 2.5 * sumETCellsEM01Trk[0];
+
+            if (resChrgEM > sumETCellsChrgEM) resChrgEM = sumETCellsChrgEM;
+            sumETeflow = sumETCellsEMCL + sumETCellsNeuEM + leadTrkPt + resChrgEM;
+        } else {
+            resChrgEM = sumETCellsChrgEM - 0.65 * leadTrkPt;
+            if (resChrgEM < 0.0) resChrgEM = 0.0;
+            resNeuEM = -0.1 * leadTrkPt;
+
+            if ((resNeuEM + sumETCellsNeuEM) < 0.0) resNeuEM = 0.0;
+
+            sumETeflow = sumETCellsEMCL + sumETCellsNeuEM + leadTrkPt + resChrgEM + resNeuEM;
+        }
+
+        pExtraDetails->setSumPtTrk(leadTrkPt);
+
+        ATH_MSG_VERBOSE(name() << " sumETCellsEMCL " << sumETCellsEMCL);
+        pDetails->setSeedTrk_etEMCL(sumETCellsEMCL);
+
+        ATH_MSG_VERBOSE(name() << " sumETCellsNeuEM " << sumETCellsNeuEM);
+        pDetails->setSeedTrk_etNeuEM(sumETCellsNeuEM);
+
+        ATH_MSG_VERBOSE(name() << " sumETCellsChrgEM " << sumETCellsChrgEM);
+        pDetails->setSeedTrk_etChrgEM(sumETCellsChrgEM);
+
+        ATH_MSG_VERBOSE(name() << " sumETCellsEM01Trk " << sumETCellsEM01Trk[0] << " " << pDetails->seedTrk_etChrgEM01Trk(0));
+        pDetails->addSeedTrk_etChrgEM01Trk(sumETCellsEM01Trk[0]);
+
+        ATH_MSG_VERBOSE(name() << " resChrgEM " << resChrgEM);
+        pDetails->addSeedTrk_etResChrgEMTrk(resChrgEM);
+
+        ATH_MSG_VERBOSE(name() << " resNeuEM " << resNeuEM);
+        pDetails->setSeedTrk_etResNeuEM(resNeuEM);
+
+        ATH_MSG_VERBOSE(name() << " sumETcaloEM " << sumETcaloEM);
+        pDetails->setSeedTrk_etEMAtEMScale(sumETcaloEM);
+
+        ATH_MSG_VERBOSE(name() << " sumETcaloHAD " << sumETcaloHAD);
+        pDetails->setSeedTrk_etHadAtEMScale(sumETcaloHAD);
+    } else {
+        resChrgEMTrkTot = 0.;
+        double sumETCellsChrgEMTrkTot = 0.;
+
+        for (unsigned itr = 0; itr < pTau->numTrack(); ++itr) {
+            // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks)
+            if (itr >= 9) break;
+
+            double trkPt = pTau->track(itr)->pt();
+
+            pttot += trkPt;
+            sumETCellsChrgEMTrkTot += sumETCellsChrgEMTrk[itr];
+
+            if ((sumETCellsChrgEMTrk[itr] - 0.7 * trkPt) > 0)
+                resChrgEMTrk[itr] = sumETCellsChrgEMTrk[itr] - 0.7 * trkPt;
+
+            resChrgEMTrkTot += resChrgEMTrk[itr];
+
+            ATH_MSG_VERBOSE(name() << " 3p resChrgEM: track-> " << itr << " resChrgEMTrk(track) " << resChrgEMTrk[itr]);
+            pDetails->addSeedTrk_etResChrgEMTrk(resChrgEMTrk[itr]);
+
+            ATH_MSG_VERBOSE("taurec 3p sumETCellsEM01Trk " << itr << " " << sumETCellsEM01Trk[itr] << " " << pDetails->seedTrk_etChrgEM01Trk(itr));
+            pDetails->addSeedTrk_etChrgEM01Trk(sumETCellsEM01Trk[itr]);
+        } // end track loop
+
+        resNeuEM = -0.1 * pttot;
+        if ((resNeuEM + sumETCellsNeuEM) < 0.0) resNeuEM = -sumETCellsNeuEM;
+
+        sumETeflow = sumETCellsEMCL + sumETCellsNeuEM + pttot + resChrgEMTrkTot + resNeuEM;
+
+        pExtraDetails->setSumPtTrk(pttot);
+
+        ATH_MSG_VERBOSE(name() << " 3p sumETCellsEMCL " << sumETCellsEMCL);
+        pDetails->setSeedTrk_etEMCL(sumETCellsEMCL);
+
+        ATH_MSG_VERBOSE(name() << " 3p  sumETCellsNeuEM " << sumETCellsNeuEM);
+        pDetails->setSeedTrk_etNeuEM(sumETCellsNeuEM);
+
+        ATH_MSG_VERBOSE(name() << " 3p  sumETCellsChrgEM " << sumETCellsChrgEMTrkTot);
+        pDetails->setSeedTrk_etChrgEM(sumETCellsChrgEMTrkTot);
+
+        ATH_MSG_VERBOSE(name() << " 3p resNeuEM " << resNeuEM);
+        pDetails->setSeedTrk_etResNeuEM(resNeuEM);
+
+        ATH_MSG_VERBOSE(name() << " 3p  sumETcaloEM " << sumETcaloEM);
+        pDetails->setSeedTrk_etEMAtEMScale(sumETcaloEM);
+
+        ATH_MSG_VERBOSE(name() << " 3p  sumETcaloHAD " << sumETcaloHAD);
+        pDetails->setSeedTrk_etHadAtEMScale(sumETcaloHAD);
+    }
+
+    // calculate tau visible mass from Eflow
+    double MVisEflow = 0.;
+    if (EMCLCluster->et() != 0) {
+        xAOD::CaloCluster::cell_iterator cellIter = EMCLCluster->cell_begin();
+        xAOD::CaloCluster::cell_iterator cellIterE = EMCLCluster->cell_end();
+        const CaloCell *pCell;
+        double sumEMeta = 0;
+        double sumEMphi = 0;
+        double resphi = 0;
+        CaloPhiRange phiRange;
+        for (; cellIter != cellIterE; ++cellIter) {
+            pCell = *cellIter;
+            if (m_doCellCorrection) {
+                m_tauOriginCorrTool->correctCell(pCell);
+            }
+            
+            sumEMeta += pCell->et() * pCell->eta();
+            resphi = phiRange.diff(pCell->phi(), pTau->phi());
+            sumEMphi += pCell->et() * resphi;
+            
+            if (m_doCellCorrection) {
+                m_tauOriginCorrTool->resetCell(pCell);
+            }
+        }
+
+        double phiPi0 = phiRange.fix((sumEMphi / EMCLCluster->et()) + pTau->phi());
+        double etaPi0 = sumEMeta / sumETCellsEMCL;
+        if (etaPi0 < -1. * m_maxClusterEta) etaPi0 = -1. * m_maxClusterEta;
+        else if (etaPi0 > m_maxClusterEta) etaPi0 = m_maxClusterEta;
+
+        // correct for vertex position as given by seeding track
+        // as short-cut assumed that radius is 1600mm    
+        
+        //TODO: 
+        //should Perigee retrieved wrt tau origin?
+        //tracks are selected by quality cuts wrt tau origin so code below might be correct too.       
+        
+        //for 1 prong only
+        if (pTau->numTrack() == 1) {
+            double zvert = (pTau->track(0)->measuredPerigee())->parameters()[Trk::z0];
+            etaPi0 = asinh(sinh(etaPi0) - zvert / 1600.);
+        }
+
+        double pxPi0 = (sumETeflow - pttot) * cos(phiPi0);
+        double pyPi0 = (sumETeflow - pttot) * sin(phiPi0);
+        double pzPi0 = (sumETeflow - pttot) * sinh(etaPi0);
+        double ePi0 = (sumETeflow - pttot) * cosh(etaPi0);
+        double pxPiCh = pttot * cos(pTau->phi());
+        double pyPiCh = pttot * sin(pTau->phi());
+        double pzPiCh = pttot * sinh(pTau->eta());
+        double ePiCh = pttot * cosh(pTau->eta());
+
+        double mass = (ePi0 + ePiCh) * (ePi0 + ePiCh) - (pxPi0 + pxPiCh) * (pxPi0 + pxPiCh)
+            - (pyPi0 + pyPiCh) * (pyPi0 + pyPiCh) - (pzPi0 + pzPiCh) * (pzPi0 + pzPiCh);
+
+        if (mass > 0.) MVisEflow = sqrt(mass);
+    } else if (NeuEMCluster->et() != 0) {
+        xAOD::CaloCluster::cell_iterator cellIter = NeuEMCluster->cell_begin();
+        xAOD::CaloCluster::cell_iterator cellIterE = NeuEMCluster->cell_end();
+        const CaloCell *pCell;
+        double sumEMeta = 0;
+        double sumEMphi = 0;
+        double resphi = 0;
+        CaloPhiRange phiRange;
+        for (; cellIter != cellIterE; ++cellIter) {
+            pCell = *cellIter;
+            
+            if (m_doCellCorrection) {
+                m_tauOriginCorrTool->correctCell(pCell);
+            }
+            
+            sumEMeta += pCell->et() * pCell->eta();
+            resphi = phiRange.diff(pCell->phi(), pTau->phi());
+            sumEMphi += pCell->et() * resphi;
+            
+            if (m_doCellCorrection) {
+                m_tauOriginCorrTool->resetCell(pCell);
+            }            
+        }
+
+        double phi = phiRange.fix((sumEMphi / NeuEMCluster->et()) + pTau->phi());
+        double eta = sumEMeta / sumETCellsNeuEM;
+
+        if (eta < -1. * m_maxClusterEta) eta = -1. * m_maxClusterEta;
+        else if (eta > m_maxClusterEta) eta = m_maxClusterEta;
+
+        // correct for vertex position as given by seeding track
+        // as short-cut assumed that radius is 1600mm
+        
+        //TODO: 
+        //should Perigee retrieved wrt tau origin?
+        //tracks are selected by quality cuts wrt tau origin so code below might be correct too.    
+
+        //for 1 prong only
+        if (pTau->numTrack() == 1) {
+            double zvert = pTau->track(0)->measuredPerigee()->parameters()[Trk::z0];
+            eta = asinh(sinh(eta) - zvert / 1600.);
+        }
+
+        double px = (sumETeflow - pttot) * cos(phi);
+        double py = (sumETeflow - pttot) * sin(phi);
+        double pz = (sumETeflow - pttot) * sinh(eta);
+        double e = (sumETeflow - pttot) * cosh(eta);
+        double pxCh = pttot * cos(pTau->phi());
+        double pyCh = pttot * sin(pTau->phi());
+        double pzCh = pttot * sinh(pTau->eta());
+        double eCh = pttot * cosh(pTau->eta());
+
+        double mass = (e + eCh) * (e + eCh) - (px + pxCh) * (px + pxCh)
+            - (py + pyCh) * (py + pyCh) - (pz + pzCh) * (pz + pzCh);
+        if (mass > 0.) MVisEflow = sqrt(mass);
+    }
+
+    //add final 4-momentum of tau
+    //FF: uncommented pTau->setE(sumETeflow / pTau->sinTh());
+    pDetails->setEtEflow(sumETeflow);
+    pDetails->setMEflow(MVisEflow);
+    ATH_MSG_VERBOSE(name() << " tau mass vis " << pDetails->etEflow() << " tau eflow " << pDetails->etEflow());
+
+    delete EMCLCluster;
+    delete NeuEMCluster;
+
+    //Preselection
+    if ((pDetails->seedCalo_etEMAtEMScale() + pDetails->seedCalo_etHadAtEMScale()) == 0.) return StatusCode::FAILURE;
+
+    /*
+    if (MVisEflow > m_MVisEflowCut ||
+        sumETeflow / (pDetails->seedCalo_etEMAtEMScale() + pDetails->seedCalo_etHadAtEMScale()) > m_ETeflow_ETcaloCut ||
+        sumETeflow / (pDetails->seedCalo_etEMAtEMScale() + pDetails->seedCalo_etHadAtEMScale()) < m_ETeflow_ETcaloCutMin
+        ) sc = StatusCode::FAILURE;
+    //TODO: Really FAILURE??   
+    */
+    //adding some discrimination variables to the object
+
+    if (pDetails->seedTrk_etEMAtEMScale() + pDetails->seedTrk_etHadAtEMScale() !=0 ) {
+      pDetails->setSeedTrk_isolFracWide((pDetails->seedTrk_etIsolEM() + pDetails->seedTrk_etIsolHad()) / (pDetails->seedTrk_etEMAtEMScale() + pDetails->seedTrk_etHadAtEMScale()));
+    }
+
+    double totpt = 0;
+    for (unsigned itr = 0; itr < pTau->numTrack(); ++itr) {
+        totpt += pTau->track(itr)->pt();
+    }
+
+    double etoverpttot = pDetails->seedTrk_etChrgHad() / totpt;
+    pDetails->setSeedTrk_etChrgHadOverSumTrkPt(etoverpttot);
+
+    return StatusCode::SUCCESS;
+
+}
+
+
+//-------------------------------------------------------------------------
+// fill EM cluster info
+// TODO: need clusters and cells here also correction for tau vertex?
+// but what is aabout detector crack region cuts?
+// they should use uncorrected coordinates, or?
+//-------------------------------------------------------------------------
+
+StatusCode TauEflowVariables::fillTopoClusterInfo(TauCandidateData *data) {
+
+    StatusCode sc;
+
+    Analysis::TauJet *pTau = data->tau;
+    Analysis::TauCommonExtraDetails *pExtraDetails = dynamic_cast<Analysis::TauCommonExtraDetails *> (data->extraDetails);
+
+    //---------------------------------------------------------------------
+    // Retrieve calo cluster container from StoreGate
+    //---------------------------------------------------------------------
+    const CaloClusterContainer *pTopoContainer;
+    sc = evtStore()->retrieve(pTopoContainer, m_CaloClusterContainerName);
+
+    if (sc.isFailure()) {
+        ATH_MSG_WARNING("No " << m_CaloClusterContainerName << " found in TES");
+        ATH_MSG_WARNING("will not use information about tau EM topo clusters");     
+        m_useEMTopoClusters = false;
+        return StatusCode::RECOVERABLE;
+    }
+
+    ATH_MSG_VERBOSE(name() << " " << m_CaloClusterContainerName << " found " << pTopoContainer->size());
+
+    int ntopo = pTopoContainer->size();
+
+    m_isTopoClusQualif.resize(ntopo);
+    m_TopoClustPhi.resize(ntopo);
+    m_closestTopoClusCell.resize(ntopo);
+    m_closestTopoClusCellPhi.resize(ntopo);
+    m_closestTopoClusCellEta.resize(ntopo);
+    m_TopoClusPhi.resize(ntopo);
+    m_TopoClusEta.resize(ntopo);
+
+    for (int i = 0; i < ntopo; ++i) {
+        m_isTopoClusQualif[i] = 0;
+        m_TopoClustPhi[i] = 0.;
+        m_closestTopoClusCell[i] = 0;
+        m_closestTopoClusCellPhi[i] = 0;
+        m_closestTopoClusCellEta[i] = 0;
+        m_TopoClusPhi[i] = 0.;
+        m_TopoClusEta[i] = 0.;
+    }
+
+    //---------------------------------------------------------------------
+    // Get pointer to fist and last cluster in the calo cluster container
+    //---------------------------------------------------------------------
+    CaloClusterContainer::const_iterator topoIter = pTopoContainer->begin();
+    CaloClusterContainer::const_iterator topoIterE = pTopoContainer->end();
+
+    const CaloCluster *pTopo;
+    int iclust = 0;
+
+    for (; topoIter != topoIterE; ++topoIter) {
+        pTopo = *topoIter;
+
+        //---------------------------------------------------------------------
+        // Skip if cluster outside rapidity range or below pT threshold
+        //---------------------------------------------------------------------
+        if (std::fabs(pTopo->eta()) > m_recoEtaCut) continue;
+        if (pTopo->et() < m_recoTopoClusterETCut) continue;
+
+        //-------------------------------------------------------------
+        // Look for the closest cluster to tau track(s)
+        //-------------------------------------------------------------
+        double detEtaMin1 = 9999.0;
+        double detPhiMin2 = 9999.0;
+        double detPhi, detEta, detPhiCrude, detEtaCrude;
+        m_isTopoClusQualif[iclust] = 1;
+
+        //loop ontracks in object
+        for (unsigned itr = 0; itr < pTau->numTrack(); ++itr) {
+            // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks)
+            if (itr >= 9) break;
+
+            // very crude treatement of crack region
+            int isampling = 1;
+
+            detEtaCrude = Tau1P3PKineUtils::deltaEta(pExtraDetails->etaTrkCaloSamp()[itr][isampling], pTopo->eta());
+            detEta = Tau1P3PKineUtils::deltaEta(pExtraDetails->etaTrkCaloSamp()[itr][isampling], pTopo->getVariable(CaloVariableType::ETA, CaloSampling::EMB1, true));
+
+            if (detEtaCrude < detEta) detEta = detEtaCrude;
+            if (detEta < detEtaMin1) detEtaMin1 = detEta;
+
+            // very crude treatement of crack region
+            isampling = 2;
+
+            detPhiCrude = Tau1P3PKineUtils::deltaPhi(pExtraDetails->phiTrkCaloSamp()[itr][isampling], pTopo->phi());
+            detPhi = Tau1P3PKineUtils::deltaPhi(pExtraDetails->phiTrkCaloSamp()[itr][isampling], pTopo->getVariable(CaloVariableType::PHI, CaloSampling::EMB2, true));
+
+            if (detPhiCrude < detPhi) detPhi = detPhiCrude;
+            if (detPhi < detPhiMin2) detPhiMin2 = detPhi;
+        }
+
+        if (detPhiMin2 < m_TrackTopoClusPhi2Cut) m_isTopoClusQualif[iclust] = 0;
+        if (detEtaMin1 < m_TrackTopoClusEta1Cut) m_isTopoClusQualif[iclust] = 0;
+
+        m_TopoClusPhi[iclust] = pTopo->phi();
+        m_TopoClusEta[iclust] = pTopo->eta();
+
+        double detRCellMin = 9999.0;
+        const CaloCell *pTmpCell = 0;
+        const CaloCell *pCell;
+
+        CaloCluster::cell_iterator cellItr = pTopo->cell_begin();
+        CaloCluster::cell_iterator cellItrE = pTopo->cell_end();
+        for (; cellItr != cellItrE; ++cellItr) {
+            pCell = *cellItr;
+            if (pCell->caloDDE()->getSampling() == 2) {
+                double detPhi = Tau1P3PKineUtils::deltaPhi(pCell->phi(), pTopo->phi());
+                double detEta = Tau1P3PKineUtils::deltaEta(pCell->eta(), pTopo->eta());
+                double detRCell = Tau1P3PKineUtils::deltaR(detPhi, detEta);
+
+                if (detRCell < detRCellMin) {
+                    detRCellMin = detRCell;
+                    pTmpCell = pCell;
+                }
+            }
+        }
+        if (pTmpCell) {
+            m_closestTopoClusCell[iclust] = 1;
+            m_closestTopoClusCellPhi[iclust] = pTmpCell->phi();
+            m_closestTopoClusCellEta[iclust] = pTmpCell->eta();
+        }
+
+        ++iclust;
+    }
+
+    m_nTopoclust = iclust;
+
+    return StatusCode::SUCCESS;
+}
+
diff --git a/Reconstruction/tauRec/depreciated/TauEflowVariables.h b/Reconstruction/tauRec/depreciated/TauEflowVariables.h
new file mode 100644
index 0000000000000000000000000000000000000000..266a3bb2c780ae672a6191a94f448b5a4b41553e
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauEflowVariables.h
@@ -0,0 +1,80 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUEFLOWVARIABLES_H
+#define TAUREC_TAUEFLOWVARIABLES_H
+
+#include <vector>
+#include "EventKernel/INavigable4Momentum.h"
+#include "CaloUtils/CaloClusterStoreHelper.h"
+
+#include "tauRec/TauToolBase.h"
+
+class TauOriginCorrectionTool;
+
+/**
+ * @brief Class for building energy flow quantities.
+ * 
+ *  This tool was formerly named as tau1p3pAddEflowInfo. 
+ * 
+ * @author Tadeusz Szymocha, Anna Kaczmarska
+ */
+
+class TauEflowVariables : public TauToolBase {
+public:
+    TauEflowVariables(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+
+    virtual ~TauEflowVariables();
+    virtual StatusCode initialize();
+    virtual StatusCode eventInitialize(TauCandidateData *data);
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode eventFinalize(TauCandidateData *data);
+
+    StatusCode fillTopoClusterInfo(TauCandidateData *data);
+
+
+private:
+
+    std::string m_trackContainerName;
+    double m_detRCoreCaloCut;
+    double m_ETCellMinCut;
+    double m_ETStripMinCut;
+    double m_detaStripCut;
+    double m_dphiEMCLCut;
+    double m_detaEMCLCut;
+    double m_dphiEMCLFACCut;
+    double m_detaEMCLFACCut;
+    double m_dphiChrgEMCut;
+    double m_detaChrgEMCut;
+    std::string m_CaloClusterContainerName;
+    double m_recoTopoClusterETCut;
+    double m_recoEtaCut;
+    double m_TrackTopoClusPhi2Cut;
+    double m_TrackTopoClusEta1Cut;
+    double m_TopoClusEtha1Cut;
+    double m_MVisEflowCut;
+    double m_MTrk3PCut;
+    double m_ETeflow_ETcaloCut;
+    double m_ETeflow_ETcaloCutMin;
+    double m_maxClusterEta;
+    bool m_useEMTopoClusters;
+
+    int m_nTopoclust;
+
+    std::vector<int> m_isTopoClusQualif;
+    std::vector<double> m_TopoClustPhi;
+    std::vector<int> m_closestTopoClusCell;
+    std::vector<double> m_closestTopoClusCellPhi;
+    std::vector<double> m_closestTopoClusCellEta;
+    std::vector<double> m_TopoClusPhi;
+    std::vector<double> m_TopoClusEta;
+    
+    bool m_doCellCorrection; //!< enable cell origin correction
+    ToolHandle<TauOriginCorrectionTool> m_tauOriginCorrTool;
+};
+
+
+#endif
diff --git a/Reconstruction/tauRec/depreciated/TauOriginCorrectionTool.cxx b/Reconstruction/tauRec/depreciated/TauOriginCorrectionTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..83a9081867efe96980abad89715455e96ece4ad8
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauOriginCorrectionTool.cxx
@@ -0,0 +1,215 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*********************************************************
+NAME: TauOriginCorrectionTool.cxx
+PACKAGE: Reconstruction/tauRec
+AUTHORS: Felix Friedrich <felix.friedrich@cern.ch>
+DATE: May 12, 2011
+
+PURPOSE: correct cells and cluster for vertex shift
+inspired by Reconstruction/Jet/JetCalibTools/src/JetCaloOrigin.cxx
+and
+Reconstruction/Jet/JetMomentTools/src/JetOriginCorrectionTool.cxx
+
+ *************************************************************/
+
+#include "CaloEvent/CaloCell.h"
+#include "CaloEvent/CaloCluster.h"
+// This class was removed. If we want to revive this tool we need to switch to the xAOD::CaloVertexedCluster interface
+// #include "CaloUtils/CaloClusterVertexCorrection.h"
+#include "JetEvent/Jet.h"
+#include "CLHEP/Geometry/Vector3D.h"
+// #include "VxVertex/VxContainer.h"
+
+#include "xAODTracking/VertexContainer.h"
+
+#include "tauRec/TauOriginCorrectionTool.h"
+
+
+TauOriginCorrectionTool::TauOriginCorrectionTool( const std::string& type, const std::string& name, const IInterface* parent ) :
+    AthAlgTool(type, name, parent),
+    m_originPosition(3,0),
+    m_useJVA(false),
+    m_usePrimaryVertex(false),
+    m_useBeamSpot(false),
+    m_evnInitCalled(false),
+    m_primVtxName("PrimaryVertices"),
+    // m_primVtxName("VxPrimaryCandidate"),
+    m_beamConditionsService("BeamCondSvc", name)
+{
+    declareInterface<TauOriginCorrectionTool>( this );
+
+    declareProperty("OriginPosition", m_originPosition);
+    declareProperty("UseJVA", m_useJVA);
+    declareProperty("UsePrimaryVertex", m_usePrimaryVertex);
+    declareProperty("UseBeamSpot", m_useBeamSpot);
+    declareProperty("VertexContainerKey",m_primVtxName = "VxPrimaryCandidate");
+    declareProperty("BeamConditionsSvc", m_beamConditionsService);
+    declareProperty("OriginMomentName", m_OriginMomName = "OriginIndex");
+
+}
+
+//*************************************************************************************************
+StatusCode TauOriginCorrectionTool::initialize()
+{
+    if(m_useBeamSpot) {
+        if(m_beamConditionsService.retrieve().isFailure() ) {
+            ATH_MSG_ERROR( "Cannot find service named <" << m_beamConditionsService << ">");
+            return StatusCode::FAILURE;
+        } 
+    }
+
+    return StatusCode::SUCCESS;
+}
+
+//*************************************************************************************************
+StatusCode TauOriginCorrectionTool::eventInitialize()
+{
+    // skip if already called
+    if (m_evnInitCalled) return StatusCode::SUCCESS;
+    
+    // get VxContainer - must be retrieved in eventInitialize
+    if(m_usePrimaryVertex || m_useJVA) { 
+        StatusCode sc = evtStore()->retrieve(m_vxContainer, m_primVtxName);
+        if (sc.isFailure()) {
+            ATH_MSG_DEBUG("Could not retrieve VxContainer <" << m_primVtxName << "> during initialize() " );
+            return StatusCode::SUCCESS;
+        }
+        m_evnInitCalled = true;
+    }
+    return StatusCode::SUCCESS;
+}
+
+//*************************************************************************************************
+// set the origin source
+// jet is only used if useJVA is enabled
+void TauOriginCorrectionTool::setOriginSource(const Jet* jet) {
+    m_jetOrigin = chooseOrigin(jet);
+}
+
+//*************************************************************************************************
+// set the origin source by hand
+void TauOriginCorrectionTool::setOriginSource(const Trk::RecVertex* vertex) {
+    // set origin by hand
+    if (vertex) {
+      m_jetOrigin = Amg::Vector3D(vertex->position().x(), vertex->position().y(), vertex->position().z());
+    }
+    else {
+      m_jetOrigin = Amg::Vector3D(0,0,0);
+    }
+}
+
+//*************************************************************************************************
+// set the origin source by hand
+void TauOriginCorrectionTool::setOriginSource(const xAOD::Vertex* vertex) {
+    // set origin by hand
+    if (vertex) {
+      m_jetOrigin = Amg::Vector3D(vertex->position().x(), vertex->position().y(), vertex->position().z());
+    }
+    else {
+      m_jetOrigin = Amg::Vector3D(0,0,0);
+    }
+}
+
+//*************************************************************************************************
+// set a new cell vertex
+void TauOriginCorrectionTool::correctCell(const CaloCell* cell) {
+    cell->zVertex(&m_jetOrigin);
+}
+
+//*************************************************************************************************
+// reset cell 
+void TauOriginCorrectionTool::resetCell(const CaloCell* cell) {
+    cell->zVertex(0,true);
+}
+
+//*************************************************************************************************
+// set a new cluster vertex 
+void TauOriginCorrectionTool::correctCluster(const CaloCluster* cluster) {
+    // CaloClusterVertexCorrection::setVertex(cluster, &m_jetOrigin);
+}
+
+//*************************************************************************************************
+// reset cluster vertex
+void TauOriginCorrectionTool::resetCluster(const CaloCluster* cluster) {
+    // CaloClusterVertexCorrection::resetVertex(cluster);
+}
+
+// try to get the origin of the jet
+// not not really needed at the moment, because using JVA is switched off by default
+Amg::Vector3D TauOriginCorrectionTool::chooseOrigin(const Jet* jet)
+{  
+    // Cascade in order of priority
+    // If one fails, go to the next approach
+
+    // JetVertexAssociation
+    if(m_useJVA) {
+        ATH_MSG_VERBOSE("TauOriginCorrectionTool::chooseOrigin In useJVA");
+        unsigned int originIndex(jet->getMoment(m_OriginMomName)); // No way to know if this has been filled at the moment
+        ATH_MSG_VERBOSE("TauOriginCorrectionTool::chooseOrigin Just got originIndex moment "<< originIndex);
+        if (originIndex > m_vxContainer->size()) {
+            ATH_MSG_WARNING("Index of jet origin (" << originIndex
+                    << ") is larger than the size of the vertex container (" 
+                    << m_vxContainer->size() << "), we return (0,0,0)");
+            return Amg::Vector3D (0, 0, 0);
+        }
+        ATH_MSG_VERBOSE("TauOriginCorrectionTool::chooseOrigin Just before getting position of vertex");
+        Amg::Vector3D primaryVertex = (*(m_vxContainer->at(originIndex))).position();
+        ATH_MSG_VERBOSE("Found a primary vertex at ("
+                << primaryVertex.x() <<  ","
+                << primaryVertex.y() <<  ","
+                << primaryVertex.z() <<  ")"
+                );
+        return Amg::Vector3D (primaryVertex.x(), primaryVertex.y(), primaryVertex.z());
+    }
+
+    // PrimaryVertex
+    if(m_usePrimaryVertex) {  
+        if(m_vxContainer) {
+            // At least 1 vertex
+            if(m_vxContainer->size()>0) {
+                // More than 1 track pointing to the vertex
+                if((*m_vxContainer->begin())->nTrackParticles() > 1) {
+                    Amg::Vector3D primaryVertex = (*(m_vxContainer->begin()))->position();
+
+                    ATH_MSG_VERBOSE("Found a primary vertex at ("
+                            << primaryVertex.x() <<  ","
+                            << primaryVertex.y() <<  ","
+                            << primaryVertex.z() <<  ")"
+                            );
+
+                    return Amg::Vector3D (primaryVertex.x(), primaryVertex.y(), primaryVertex.z());
+                }        
+                ATH_MSG_DEBUG("Couldn't find a primary vertex! Try next approach" );
+            }
+        }
+    }
+
+    // BeamSpot
+    if(m_useBeamSpot) {
+        if(m_beamConditionsService) {
+            if(!m_beamConditionsService.empty()) {
+                Amg::Vector3D beamSpot = m_beamConditionsService->beamVtx().position();
+
+                ATH_MSG_VERBOSE("Found a beam spot at ("
+                        << beamSpot.x() <<  ","
+                        << beamSpot.y() <<  ","
+                        << beamSpot.z() <<  ")"
+                        );
+
+                return Amg::Vector3D (beamSpot.x(), beamSpot.y(), beamSpot.z());
+            }
+        }
+        ATH_MSG_DEBUG("Couldn't find a beam spot! Try next approach" );
+    }
+
+    // Set Vertex Position by Hand
+    if(m_originPosition.size() == 3)
+        return Amg::Vector3D (m_originPosition[0], m_originPosition[1], m_originPosition[2]);
+
+    // Last ditch default: (0,0,0)
+    return Amg::Vector3D (0,0,0);
+
+}
diff --git a/Reconstruction/tauRec/depreciated/TauOriginCorrectionTool.h b/Reconstruction/tauRec/depreciated/TauOriginCorrectionTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..cf9ce2a30d2fa2f858bb58b4a496aeee3fc7e8b5
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauOriginCorrectionTool.h
@@ -0,0 +1,96 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUORIGINCORRECTIONTOOL_H
+#define TAUREC_TAUORIGINCORRECTIONTOOL_H
+
+#include <vector>
+#include "AthenaBaseComps/AthAlgTool.h" 
+#include "GaudiKernel/ToolHandle.h"
+#include "InDetBeamSpotService/IBeamCondSvc.h"
+
+#include "xAODTracking/Vertex.h"
+#include "xAODTracking/VertexContainer.h"
+#include "xAODTracking/TrackParticle.h"
+
+class Jet;
+class CaloCell;
+class CaloCluster;
+//class xAOD::VertexContainer;
+
+//namespace HepGeom {
+//    template<class T> class Vector3D;
+//}
+namespace Trk {
+  class RecVertex;
+}
+
+static const InterfaceID IID_ITauOriginCorrectionTool("TauOriginCorrectionTool",1,0);
+
+/**
+ * @brief Correct cells and cluster for vertex shift.
+ * 
+ *  Inspired by Reconstruction/Jet/JetCalibTools/JetCalibTools/JetCaloOrigin.h
+ * 
+ * @author Felix Friedrich
+ */
+
+class TauOriginCorrectionTool :  public AthAlgTool
+{
+    public:
+        TauOriginCorrectionTool( const std::string& type, const std::string& name, const IInterface* parent ) ;
+        virtual ~TauOriginCorrectionTool(){};
+
+        static const InterfaceID& interfaceID() { return IID_ITauOriginCorrectionTool; }
+
+        virtual StatusCode initialize()  ;
+        virtual StatusCode eventInitialize()  ;
+        virtual StatusCode finalize() { return StatusCode::SUCCESS; } ;
+
+        virtual void setOriginSource(const Jet* jet);
+        virtual void setOriginSource(const Trk::RecVertex* vertex); 
+	virtual void setOriginSource(const xAOD::Vertex* vertex); 
+	
+        virtual void correctCell(const CaloCell* cell);
+        virtual void resetCell(const CaloCell* cell);
+
+        virtual void correctCluster(const CaloCluster* cluster);
+        virtual void resetCluster(const CaloCluster* cluster);
+
+        // Return the vertex chosen
+        Amg::Vector3D chooseOrigin(const Jet* jet_in);
+
+
+    private:
+
+        // 3-vector pointing to a default origin
+        std::vector<double> m_originPosition;
+
+        // Choice of origin:
+        // Try the JetVertexAssociation
+        bool m_useJVA;
+        // Try retrieving primary vertex
+        bool m_usePrimaryVertex;
+        // Try retrieving beamspot
+        bool m_useBeamSpot;
+        
+        bool m_evnInitCalled;
+
+        // origin
+        Amg::Vector3D m_jetOrigin;
+
+        // Vertex Container Name
+        std::string m_primVtxName;
+
+        //JVA Moment Name
+        std::string m_OriginMomName;
+
+        // Pointer to the vertex container
+        const xAOD::VertexContainer* m_vxContainer;
+
+        // Pointer to the beamspot handle
+        ServiceHandle<IBeamCondSvc> m_beamConditionsService;
+
+};
+#endif
diff --git a/Reconstruction/tauRec/depreciated/TauPi0CrakowClusterCreator.cxx b/Reconstruction/tauRec/depreciated/TauPi0CrakowClusterCreator.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..bb898a340c50a09b50add3438d8f5d645ad8350f
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauPi0CrakowClusterCreator.cxx
@@ -0,0 +1,454 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauPi0CrakowClusterCreator.cxx
+// package:     Reconstruction/tauRec
+// authors:     Elzbieta Richter-Was 
+// date:        19/06/2007
+//
+// This tool classifies Pi0 clusters, adapted from tau1P3PCreatePi0Clus.cxx
+//-----------------------------------------------------------------------------
+
+#include <algorithm>
+#include <math.h>
+#include <sstream>
+
+#include "GaudiKernel/ListItem.h"
+#include "GaudiKernel/IToolSvc.h"
+#include "GaudiKernel/Property.h"
+
+#include "CaloUtils/CaloCellList.h"
+#include "CaloEvent/CaloCluster.h"
+#include "CaloEvent/CaloCell.h"
+#include "AtlasDetDescr/AtlasDetectorID.h"
+#include "CaloIdentifier/CaloID.h"
+#include "CaloIdentifier/CaloCell_ID.h"
+#include "CaloGeoHelpers/CaloSampling.h"
+#include "CaloGeoHelpers/CaloPhiRange.h"
+#include "AnalysisUtils/AnalysisMisc.h"
+#include "CaloUtils/CaloClusterStoreHelper.h"
+
+#include "tauEvent/TauCommonDetails.h"
+#include "tauEvent/TauCommonExtraDetails.h"
+#include "tauRec/KineUtils.h"
+#include "tauRec/TauPi0CrakowClusterCreator.h"
+
+//-------------------------------------------------------------------------
+// Constructor
+//-------------------------------------------------------------------------
+
+TauPi0CrakowClusterCreator::TauPi0CrakowClusterCreator(const std::string &type,
+    const std::string &name,
+    const IInterface *parent) :
+TauToolBase(type, name, parent),
+m_detRCoreCaloCut(0.2),
+m_recoTopoClusterETCut(1000.0),
+m_recoEtaCut(2.5),
+m_detTrkClusMin(0.0375),
+m_fracEM01verEM(0.1),
+m_CaloClusterContainerName("EMTopoCluster"),
+m_pi0ContainerName("Tau1P3PPi0ClusterContainer") {
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("detRCoreCaloCut", m_detRCoreCaloCut);
+    declareProperty("RecoTopoClusterETCut", m_recoTopoClusterETCut);
+    declareProperty("RecoEtaCut", m_recoEtaCut);
+    declareProperty("detTrkClusMin", m_detTrkClusMin);
+    declareProperty("fracEM01verEM", m_fracEM01verEM);
+    declareProperty("CaloClusterContainerName", m_CaloClusterContainerName);
+    declareProperty("Pi0ClusterContainer", m_pi0ContainerName);
+
+}
+
+
+//-------------------------------------------------------------------------
+// Destructor
+//-------------------------------------------------------------------------
+
+TauPi0CrakowClusterCreator::~TauPi0CrakowClusterCreator() {
+}
+
+
+//-------------------------------------------------------------------------
+// Initializer
+//-------------------------------------------------------------------------
+
+StatusCode TauPi0CrakowClusterCreator::initialize() {
+
+    ATH_MSG_VERBOSE(name() << " detRCoreCaloCut       = " << m_detRCoreCaloCut);
+    ATH_MSG_VERBOSE(name() << " RecoTopoClusterETCut  = " << m_recoTopoClusterETCut);
+    ATH_MSG_VERBOSE(name() << " detTrkClusMin         = " << m_detTrkClusMin);
+    ATH_MSG_VERBOSE(name() << " fracEM01verEM         = " << m_fracEM01verEM);
+
+
+    StatusCode sc;
+
+    //---------------------------------------------------------------------
+    // Retrieve pointer to ToolSvc
+    //---------------------------------------------------------------------
+    IToolSvc *pToolSvc;
+    sc = service("ToolSvc", pToolSvc);
+    if (sc.isFailure()) {
+        ATH_MSG_FATAL("Unable to retrieve pointer to ToolSvc");
+        return sc;
+    }
+
+    return StatusCode::SUCCESS;
+}
+
+
+//-----------------------------------------------------------------------------
+// Delete Pi0 clusters
+//-----------------------------------------------------------------------------
+
+static void do_delete(CaloCluster *cluster) {
+    delete cluster;
+}
+
+
+//-------------------------------------------------------------------------
+// Event Initializer
+//-------------------------------------------------------------------------
+
+StatusCode TauPi0CrakowClusterCreator::eventInitialize(TauCandidateData *) {
+    m_pi0Map.clear();
+    return StatusCode::SUCCESS;
+}
+
+
+
+//-------------------------------------------------------------------------
+// Event Finalizer
+//-------------------------------------------------------------------------
+
+StatusCode TauPi0CrakowClusterCreator::eventFinalize(TauCandidateData *) {
+
+    MsgStream rLog(msgSvc(), name());
+
+    StatusCode sc;
+
+    //---------------------------------------------------------------------
+    // Create container for Pi0
+    //---------------------------------------------------------------------
+    CaloClusterContainer *pPi0Container = new CaloClusterContainer();
+    //XXX need to check if we need this tool anymore. For now just make it fail all the time
+    sc = StatusCode::FAILURE;
+    // sc = CaloClusterStoreHelper::recordClusters(&*evtStore(),
+    //     pPi0Container,
+    //     m_pi0ContainerName,
+    //     rLog);
+
+
+    //---------------------------------------------------------------------
+    // Put all clusters into the container
+    //---------------------------------------------------------------------
+    std::map<Analysis::TauCommonDetails *, std::vector<CaloCluster *> > ::iterator it;
+    std::vector<CaloCluster *> ::iterator clustIt;
+
+    for (it = m_pi0Map.begin(); it != m_pi0Map.end(); ++it) {
+        for (clustIt = (*it).second.begin(); clustIt != (*it).second.end(); ++clustIt) {
+            pPi0Container->push_back(*clustIt);
+        }
+        AnalysisUtils::Sort::pT(pPi0Container);
+    }
+
+    //----------------------------------------------------------------------
+    // Register cluster container in StoreGate
+    //----------------------------------------------------------------------
+    //XXX need to check if we need this tool anymore. For now just make it fail all the time
+    sc = StatusCode::FAILURE;
+    // sc = CaloClusterStoreHelper::finalizeClusters(&*evtStore(),
+    //     pPi0Container,
+    //     m_pi0ContainerName,
+    //     rLog);
+
+
+    //---------------------------------------------------------------------
+    // Set element links
+    //---------------------------------------------------------------------
+    for (it = m_pi0Map.begin(); it != m_pi0Map.end(); ++it) {
+        (*it).first->pi0LinkVec().clear();
+        for (clustIt = (*it).second.begin(); clustIt != (*it).second.end(); ++clustIt) {
+            (*it).first->addPi0(*clustIt, pPi0Container);
+        }
+    }
+
+    return sc;
+}
+
+
+//-------------------------------------------------------------------------
+// Execution
+//-------------------------------------------------------------------------
+
+StatusCode TauPi0CrakowClusterCreator::execute(TauCandidateData *data) {
+
+    // Analysis::TauJet *pTau = data->tau;
+    // Analysis::TauCommonDetails *pDetails = dynamic_cast<Analysis::TauCommonDetails *> (data->details);
+    // Analysis::TauCommonExtraDetails *pExtraDetails = dynamic_cast<Analysis::TauCommonExtraDetails *> (data->extraDetails);
+
+    // //
+    // if (pTau->numTrack()==0) {
+    //     ATH_MSG_VERBOSE("tau has no tracks -> skip CrakowClusterCreator");
+    //     return StatusCode::SUCCESS;
+    // }
+    
+    // if ( !pDetails || !pExtraDetails) {
+    //   ATH_MSG_ERROR("TauCommon(Extra)Details object not valid");
+    //   return StatusCode::FAILURE;
+    // }
+        
+    // StatusCode sc;    
+
+    // //FIX ME! needed only for cell coping
+    // const CaloCellContainer *pCellContainer;
+
+    // //for tau trigger
+    // sc = data->getObject("CellContainer", pCellContainer);
+
+    // if (sc.isFailure() || !pCellContainer) {
+    //     //TODO: AllCalo hardcoded!!
+    //     sc = evtStore()->retrieve(pCellContainer, "AllCalo");
+    //     if (sc.isFailure()) {
+    //         ATH_MSG_ERROR("Unable to find all calo container");
+    //         return StatusCode::FAILURE;
+    //     }
+    // }
+
+    // //---------------------------------------------------------------------
+    // // Retrieve calo cluster container from StoreGate
+    // //---------------------------------------------------------------------
+    // const CaloClusterContainer *pTopoContainer = 0;
+    // sc = evtStore()->retrieve(pTopoContainer, m_CaloClusterContainerName);
+
+    // if (sc.isFailure()) {
+    //     ATH_MSG_FATAL("No " << m_CaloClusterContainerName << " found in TES");
+    //     return sc;
+    // }
+
+
+    // double resPhiPi0 = 0;
+
+    // CaloPhiRange phiRange;
+
+    // std::vector<CaloCluster *> clusterPi0;
+    // const CaloCluster *pTopo;
+    
+    // //FF:
+    // //TODO: need cluster to be correct wrt tau origin?
+    // //Can not oversee impact, so leave everything as it is for the moment
+
+    // //---------------------------------------------------------------------
+    // // Start classifying clusters
+    // //---------------------------------------------------------------------
+    // CaloClusterContainer::const_iterator topoIter = pTopoContainer->begin();
+    // CaloClusterContainer::const_iterator topoIterE = pTopoContainer->end();
+
+    // for (; topoIter != topoIterE; ++topoIter) {
+
+    //     pTopo = *topoIter;
+
+    //     //---------------------------------------------------------------------
+    //     // Skip if cluster outside rapidity range or below pT threshold
+    //     //---------------------------------------------------------------------
+    //     if (pTopo->et() < m_recoTopoClusterETCut) continue;
+
+
+    //     double zvert = pTau->track(0)->measuredPerigee()->parameters()[Trk::z0];
+    //     double etazv = 0;
+    //     if (fabs(pTopo->eta()) < 1.45) {
+    //         double aeta = fabs(pTopo->eta());
+    //         double r = 1691. - 39.4884 * aeta - 23.556412 * aeta*aeta; // FIXME  approximate shower depth in barrel
+    //         double z = r * sinh(pTopo->eta());
+    //         double x = (z - zvert) / r;
+    //         etazv = logf(x + sqrt(1. + x * x));
+    //     } else {
+    //         double z = 3920; // FIXME approximate shower depth in emec
+    //         if (pTopo->eta() < 0) z = -3920;
+    //         double r = z / sinh(pTopo->eta());
+    //         double x = (z - zvert) / r;
+    //         etazv = logf(x + sqrt(1. + x * x));
+    //     }
+
+    //     //---------------------------------------------------------------------
+    //     // Skip if cluster outside tauCore region
+    //     //---------------------------------------------------------------------
+    //     double detPhi = phiRange.diff(pTopo->phi(), pTau->phi());
+    //     double detEta = etazv - pTau->eta();
+
+    //     if (sqrt(detPhi * detPhi + detEta * detEta) > m_detRCoreCaloCut) continue;
+
+
+    //     //-------------------------------------------------------------
+    //     // Check if cluster separated from track, skip otherwise
+    //     //-------------------------------------------------------------
+    //     int isTopoClusQualif = 1;
+
+    //     //loop on tracks in the object
+    //     for (unsigned itr = 0; itr < pTau->numTrack(); ++itr) {
+    //         // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks)
+    //         if (itr >= 9) break;
+
+    //         int isampling = 2;
+
+    //         double detEta = fabs(pExtraDetails->etaTrkCaloSamp()[itr][isampling] - etazv);
+    //         double detPhi = fabs(phiRange.diff(pExtraDetails->phiTrkCaloSamp()[itr][isampling], pTopo->phi()));
+
+    //         if (sqrt(detPhi * detPhi + detEta * detEta) < m_detTrkClusMin) isTopoClusQualif = 0;
+    //     }
+
+
+    //     if (isTopoClusQualif == 0) continue;
+
+
+    //     //-------------------------------------------------------------
+    //     // Check if cluster has energy deposition in EM01, skip otherwise
+    //     //-------------------------------------------------------------
+    //     double e_emb0 = (double) pTopo->getVariable(CaloVariableType::ENERGY, CaloSampling::PreSamplerB, 1);
+    //     double e_emb1 = (double) pTopo->getVariable(CaloVariableType::ENERGY, CaloSampling::EMB1, 1);
+    //     //ak_unused double e_emb2 = (float)pTopo->getVariable(CaloVariableType::ENERGY,CaloSampling::EMB2,1); 
+    //     double e_eme0 = (double) pTopo->getVariable(CaloVariableType::ENERGY, CaloSampling::PreSamplerE, 1);
+    //     double e_eme1 = (double) pTopo->getVariable(CaloVariableType::ENERGY, CaloSampling::EME1, 1);
+    //     //ak_unused double e_eme2 = (float)pTopo->getVariable(CaloVariableType::ENERGY,CaloSampling::EME2,1); 
+
+
+    //     if ((e_emb0 + e_eme0 + e_emb1 + e_eme1) < m_fracEM01verEM * pTopo->e()) continue;
+
+    //     //-------------------------------------------------------------
+    //     // Cluster accepted, include in bary-center calculation
+    //     //-------------------------------------------------------------
+
+    //     // calculate energy weighted  (eta,phi)
+    //     double resPhi = phiRange.diff(pTopo->phi(), pTau->phi());
+    //     resPhiPi0 += resPhi * pTopo->e();
+
+    //     ATH_MSG_VERBOSE(name() << " accepted topoForTaus clusters "
+    //         << " energy " << pTopo->et()
+    //         << " phi  " << pTopo->phi()
+    //         << " eta " << pTopo->eta()
+    //         );
+
+    //     //-------------------------------------------------------------
+    //     // Cluster accepted, store in Pi0Cluster collection
+    //     //-------------------------------------------------------------
+
+    //     //create temp cluster for cells storing
+    // 	xAOD::CaloCluster *pPi0cluster = CaloClusterStoreHelper::makeCluster(pCellContainer);
+
+    //     //copy cells from selected cluster into created pi0 cluster
+    //     CaloCluster::cell_iterator cellIter = pTopo->cell_begin();
+    //     CaloCluster::cell_iterator cellIterE = pTopo->cell_end();
+
+    //     for (; cellIter != cellIterE; ++cellIter) {
+    // 	  //XXX still need to check this implementation
+    // 	  pPi0cluster->addCell(cellIter.getElement().index(), 1.0);
+    //     }
+
+    //     clusterPi0.push_back(pPi0cluster);
+    //     pDetails->addPi0(pPi0cluster, 0);
+    // }
+
+    // m_pi0Map[pDetails] = clusterPi0;
+
+
+    // /***** FIXME...
+    // //  loop over pi0 clusters correction
+    // //  correct position for zvertex
+    // //  calculate barycentre
+    // //  store as sumEM
+    //  ***********/
+
+    // if (clusterPi0.empty()) {
+    //     // no cluster found --> leave
+    //     return StatusCode::SUCCESS;
+    // }
+
+    // //---------------------------------------------------------------------
+    // // Calculate and register energy weighted bary-center 4-momenta
+    // // corrected for the z-vertex position
+    // //---------------------------------------------------------------------
+
+    // float sumEMeta = 0;
+    // float sumEMphi = 0;
+    // float sumEMet = 0;
+    // float sumEMe = 0;
+
+    // for (unsigned ipi0 = 0; ipi0 < clusterPi0.size(); ++ipi0) {
+    //     const CaloCluster *pPi0Clus = clusterPi0[ipi0];
+    //     sumEMeta += pPi0Clus->et() * pPi0Clus->eta();
+    //     float resphi = phiRange.diff(pPi0Clus->phi(), pTau->phi());
+    //     sumEMphi += pPi0Clus->et() * resphi;
+    //     sumEMet += pPi0Clus->et();
+    //     sumEMe += pPi0Clus->e();
+    // }
+
+    // float phiPi0 = phiRange.fix(sumEMphi / sumEMet + pTau->phi());
+    // float etaPi0 = sumEMeta / sumEMet;
+    // float ePi0 = sumEMe;
+
+    // //-------------------------------------------------------------
+    // // Correct for vertex position of the leading track
+    // //-------------------------------------------------------------
+    // double zvert = pTau->track(0)->measuredPerigee()->parameters()[Trk::z0];
+    // float etaPi0zv;
+    // if (fabs(etaPi0) < 1.45) {
+    //     double aeta = fabs(etaPi0);
+    //     double r = 1691. - 39.4884 * aeta - 23.556412 * aeta*aeta; // FIXME  approximate shower depth in barrel
+    //     double z = r * sinh(etaPi0);
+    //     double x = (z - zvert) / r;
+    //     etaPi0zv = logf(x + sqrt(1. + x * x));
+    // } else {
+    //     double z = 3920; // FIXME approximate shower depth in emec
+    //     if (etaPi0 < 0) z = -3920;
+    //     double r = z / sinh(etaPi0);
+    //     double x = (z - zvert) / r;
+    //     etaPi0zv = logf(x + sqrt(1. + x * x));
+    // }
+
+    // ATH_MSG_VERBOSE(name() << " final combined Pi0 4-momenta "
+    //     << " energy " << ePi0
+    //     << " phi  " << phiPi0
+    //     << " etaZV " << etaPi0zv
+    //     );
+
+    // double pxPi0 = ePi0 / cosh(etaPi0zv) * cos(phiPi0);
+    // double pyPi0 = ePi0 / cosh(etaPi0zv) * sin(phiPi0);
+    // double pzPi0 = ePi0 / cosh(etaPi0zv) * sinh(etaPi0zv);
+
+    // // FIXME calculated with mass less hypothesis
+    // CLHEP::HepLorentzVector sumem(pxPi0, pyPi0, pzPi0, ePi0);
+    // pDetails->setSumPi0Vec(sumem);
+
+    // ATH_MSG_VERBOSE(name() << " final Pi0 4-momenta (retrieve) "
+    //     << " energy " << pDetails->sumPi0Vec().e()
+    //     << " phi  " << pDetails->sumPi0Vec().phi()
+    //     << " etaZV " << pDetails->sumPi0Vec().eta()
+    //     );
+
+
+    return StatusCode::SUCCESS;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Cleanup, in case this candidate was rejected later
+//-----------------------------------------------------------------------------
+
+void TauPi0CrakowClusterCreator::cleanup(TauCandidateData *data) {
+
+    Analysis::TauCommonDetails *pDetails = dynamic_cast<Analysis::TauCommonDetails *> (data->details);
+    std::map<Analysis::TauCommonDetails *, std::vector<CaloCluster *> > ::iterator it;
+    it = m_pi0Map.find(pDetails);
+
+    if (it != m_pi0Map.end()) {
+        std::for_each((*it).second.begin(), (*it).second.end(), do_delete);
+        m_pi0Map.erase(it);
+    }
+}
+
+
+
+
diff --git a/Reconstruction/tauRec/depreciated/TauPi0CrakowClusterCreator.h b/Reconstruction/tauRec/depreciated/TauPi0CrakowClusterCreator.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d47fd0567673b0f36c1b9e64d46ae72bbe2b2f2
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauPi0CrakowClusterCreator.h
@@ -0,0 +1,64 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TauPi0CrakowClusterCreator_H
+#define	TAUREC_TauPi0CrakowClusterCreator_H
+
+#include "tauRec/TauToolBase.h"
+#include <map>
+
+namespace Analysis {
+    class TauCommonDetails;
+}
+class CaloCluster;
+
+/**
+ * @brief Class for creating Pi0 clusters from EMtopoForTaus collection.
+ * 
+ * @author Elzbieta Richter-Was
+ * 
+ */
+
+class TauPi0CrakowClusterCreator : public TauToolBase {
+public:
+
+    TauPi0CrakowClusterCreator(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+
+    virtual ~TauPi0CrakowClusterCreator();
+    
+    virtual StatusCode initialize();
+    virtual StatusCode eventInitialize(TauCandidateData *data);
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode eventFinalize(TauCandidateData *data);
+    
+    virtual void cleanup(TauCandidateData *data);
+    StatusCode fillTopoClusterInfo(TauCandidateData *data);
+
+
+private:
+
+    std::string m_trackContainerName;
+    double m_detRCoreCaloCut;
+    double m_recoTopoClusterETCut;
+    double m_recoEtaCut;
+    double m_detTrkClusMin;
+    double m_fracEM01verEM;
+    std::string m_CaloClusterContainerName;
+
+    int m_nTopoClust;
+
+    std::vector<int> m_isTopoClusQualif;
+    std::vector<double> m_TopoClustPhi;
+    std::vector<double> m_TopoClusEta;
+
+    std::string m_pi0ContainerName;
+
+    // CaloCluster with all cells  after hypothesis of Pi0
+    std::map<Analysis::TauCommonDetails *, std::vector<CaloCluster *> > m_pi0Map;
+};
+
+#endif	/* TauPi0CrakowClusterCreator_H */
+
diff --git a/Reconstruction/tauRec/depreciated/TauPi0CreatorChooser.cxx b/Reconstruction/tauRec/depreciated/TauPi0CreatorChooser.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6508437694e08d89d43a779dfff4efc50d6631f3
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauPi0CreatorChooser.cxx
@@ -0,0 +1,184 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauPi0CreatorChooser.cxx
+// package:     Reconstruction/tauEvent
+// authors:     Veit Scharf
+// date:        2008-10-23
+//-----------------------------------------------------------------------------
+
+#include <algorithm>
+#include "GaudiKernel/MsgStream.h"
+#include "CaloEvent/CaloCluster.h"
+#include "CaloUtils/CaloClusterStoreHelper.h"
+#include "tauEvent/TauCommonDetails.h"
+#include "tauRec/TauPi0CreatorChooser.h"
+
+//-------------------------------------------------------------------------
+// Constructor
+//-------------------------------------------------------------------------
+
+TauPi0CreatorChooser::TauPi0CreatorChooser(const std::string& type,
+    const std::string& name,
+    const IInterface *parent) :
+TauToolBase(type, name, parent),
+m_tau1p3pCreatePi0ClusTool("tau1p3pCreatePi0Clus"),
+m_tauCommonCreatePi0ClusTool("TauCommonCreatePi0Clus"),
+m_pi0ClusterContainerName("Tau1P3PPi0ClusterContainer") {
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("Tau1p3pCreatePi0ClusTool", m_tau1p3pCreatePi0ClusTool);
+    declareProperty("TauCommonCreatePi0ClusTool", m_tauCommonCreatePi0ClusTool);
+    declareProperty("Pi0ClusterContainer", m_pi0ClusterContainerName);
+}
+
+//-------------------------------------------------------------------------
+// Destructor
+//-------------------------------------------------------------------------
+
+TauPi0CreatorChooser::~TauPi0CreatorChooser() {
+}
+
+StatusCode TauPi0CreatorChooser::initialize() {
+
+    StatusCode sc;
+
+    sc = m_tau1p3pCreatePi0ClusTool.retrieve();
+    if (sc.isFailure()) {
+        ATH_MSG_ERROR("Could not retrieve tau1p3pCreatePi0ClusTool.");
+        return sc;
+    }
+
+    sc = m_tauCommonCreatePi0ClusTool.retrieve();
+    if (sc.isFailure()) {
+        ATH_MSG_ERROR("Could not retrieve tauCommonCreatePi0ClusTool.");
+        return sc;
+    }
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauPi0CreatorChooser::eventInitialize(TauCandidateData* data) {
+
+    StatusCode sc;
+    sc = m_tau1p3pCreatePi0ClusTool->eventInitialize(data);
+    if (sc.isFailure()) {
+        return sc;
+    }
+
+    sc = m_tauCommonCreatePi0ClusTool->eventInitialize(data);
+    if (sc.isFailure()) {
+        return sc;
+    }
+
+    m_tauDetails.clear();
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauPi0CreatorChooser::execute(TauCandidateData* data) {
+
+    StatusCode sc;
+
+    m_tauDetails.push_back(dynamic_cast<Analysis::TauCommonDetails*> (data->details));
+    if (data->tau->numTrack() != 1)
+        sc = m_tau1p3pCreatePi0ClusTool->execute(data);
+    else
+        sc = m_tauCommonCreatePi0ClusTool->execute(data);
+
+    return sc;
+}
+
+void TauPi0CreatorChooser::cleanup(TauCandidateData* data) {
+    if (data->tau->numTrack() != 1)
+        m_tau1p3pCreatePi0ClusTool->cleanup(data);
+    else
+        m_tauCommonCreatePi0ClusTool->cleanup(data);
+
+    std::vector<Analysis::TauCommonDetails*>::iterator i = std::find(m_tauDetails.begin(),
+        m_tauDetails.end(),
+        dynamic_cast<Analysis::TauCommonDetails*> (data->details));
+
+    if (i != m_tauDetails.end())
+        m_tauDetails.erase(i);
+
+    return;
+}
+
+StatusCode TauPi0CreatorChooser::eventFinalize(TauCandidateData* /* data */) {
+
+    // Do not call eventFinalize methods of the child tools. They would record
+    // two CaloClusterContainers with the same name. Instead do the work here.
+    ATH_MSG_INFO("TauPi0CreatorChooser::eventFinalize");
+
+    MsgStream rLog(msgSvc(), name());
+
+    StatusCode sc;
+
+
+   
+    CaloClusterContainer *pPi0ClusterContainer = new CaloClusterContainer();
+
+    //XXX need to check if we need this tool anymore. For now just make it fail all the time
+    sc = StatusCode::FAILURE;
+    // sc = CaloClusterStoreHelper::recordClusters(&*evtStore(),
+    //         pPi0ClusterContainer,
+    //         m_pi0ClusterContainerName,
+    //         rLog);
+    
+    std::vector<Analysis::TauCommonDetails*>::iterator dataIt(m_tauDetails.begin()),
+        dataItE(m_tauDetails.end());
+
+
+    if (sc.isFailure()) {
+        ATH_MSG_WARNING("Could not create CaloClusterContainer: " << m_pi0ClusterContainerName << ". No pi0's will be stored.");
+
+        // remove all pi0s if registering the container fails.
+        for (; dataIt != dataItE; ++dataIt) {
+            if (*dataIt) (*dataIt)->pi0LinkVec().clear();
+        }
+
+        return StatusCode::SUCCESS;
+    }
+
+    // store clusters in the new container
+    for (dataIt = m_tauDetails.begin(); dataIt != dataItE; ++dataIt) {
+        for (unsigned i = 0; i < (*dataIt)->nPi0(); ++i) {
+            pPi0ClusterContainer->push_back(const_cast<CaloCluster*>((*dataIt)->pi0(i)));
+        }
+    }
+
+    //XXX need to check if we need this tool anymore. For now just make it fail all the time
+    sc = StatusCode::FAILURE; 
+    // sc = CaloClusterStoreHelper::finalizeClusters(&*evtStore(),
+    //     pPi0ClusterContainer,
+    //     m_pi0ClusterContainerName,
+    //     rLog);
+
+    if (sc.isFailure()) {
+        ATH_MSG_WARNING("Could not finalize CaloClusterContainer " << m_pi0ClusterContainerName << ". No pi0's will be stored.");
+        // remove all pi0s if registering the container fails.
+        for (; dataIt != dataItE; ++dataIt) {
+            if (*dataIt) (*dataIt)->pi0LinkVec().clear();
+        }
+        return StatusCode::SUCCESS;
+    }
+
+    // update links in Tau1P3PDetails
+    std::vector<const CaloCluster*> tmp;
+    for (dataIt = m_tauDetails.begin(); dataIt != dataItE; ++dataIt) {
+        tmp.clear();
+        for (unsigned i = 0; i < (*dataIt)->nPi0(); ++i) {
+            tmp.push_back((*dataIt)->pi0(i));
+        }
+        (*dataIt)->pi0LinkVec().clear();
+        for (unsigned i = 0; i < tmp.size(); ++i) {
+            (*dataIt)->addPi0(tmp.at(i), pPi0ClusterContainer);
+        }
+    }
+
+    return StatusCode::SUCCESS;
+}
+
diff --git a/Reconstruction/tauRec/depreciated/TauPi0CreatorChooser.h b/Reconstruction/tauRec/depreciated/TauPi0CreatorChooser.h
new file mode 100644
index 0000000000000000000000000000000000000000..49fc73ad4ff38136940df7c128db938016b1deaf
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauPi0CreatorChooser.h
@@ -0,0 +1,49 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUPI0CREATERCHOOSER_H
+#define	TAUREC_TAUPI0CREATERCHOOSER_H
+
+#include "GaudiKernel/ToolHandle.h"
+#include "tauRec/TauToolBase.h"
+#include <vector>
+#include <string>
+
+namespace Analysis {
+    class TauCommonDetails;
+}
+
+/**
+ * @brief Tool to select the correct Pi0 Finder.
+ * 
+ *  Part of the "Bonn" Pi0 Finder algorithm.
+ *
+ * @author  Veit Scharf
+ */
+
+class TauPi0CreatorChooser : public TauToolBase {
+public:
+    TauPi0CreatorChooser(const std::string& type,
+            const std::string& name,
+            const IInterface *parent);
+    virtual ~TauPi0CreatorChooser();
+
+    virtual StatusCode initialize();
+    virtual StatusCode eventInitialize(TauCandidateData *data);
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode eventFinalize(TauCandidateData *data);
+    virtual void cleanup(TauCandidateData *data);
+
+private:
+
+    ToolHandle<TauToolBase> m_tau1p3pCreatePi0ClusTool;
+    ToolHandle<TauToolBase> m_tauCommonCreatePi0ClusTool;
+
+    std::vector<Analysis::TauCommonDetails*> m_tauDetails;
+    std::string m_pi0ClusterContainerName;
+};
+
+
+#endif	/* TAUREC_TAUPI0CREATERCHOOSER_H */
+
diff --git a/Reconstruction/tauRec/depreciated/TauPi0EflowCreateROI.cxx b/Reconstruction/tauRec/depreciated/TauPi0EflowCreateROI.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ef06f1f6857ff68156f8c4520351e0f158cd226b
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauPi0EflowCreateROI.cxx
@@ -0,0 +1,514 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        tau1p3pTrackCreateROI.cxx
+// package:     Reconstruction/tauRec
+// authors:     Elzbieta Richter-Was  (addapted from tau1p3pTrackMatchCells.cxx)
+// date:        June2007
+//
+// Tool for collecting cells for tauROI
+//
+// 17/03/2010: AK: change to P4Helpers
+// 16/05/2010 - (FF) pointer p_measPer never used (coverity 22627)
+//-----------------------------------------------------------------------------
+
+//TODO: statuscode failure --> recoverable
+//TODO: rename!
+
+#include "GaudiKernel/ListItem.h"
+
+#include "CaloEvent/CaloCluster.h"
+#include "CaloUtils/CaloClusterStoreHelper.h"
+#include "CaloInterface/ICaloNoiseTool.h"
+#include "CaloUtils/CaloCellList.h"
+#include "CaloEvent/CaloCell.h"
+#include "CaloIdentifier/CaloCell_ID.h"
+#include "CaloEvent/CaloClusterContainer.h"
+
+#include "tauRec/KineUtils.h"
+
+#include "tauRec/TauOriginCorrectionTool.h"
+#include "tauRec/TauPi0EflowCreateROI.h"
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+
+TauPi0EflowCreateROI::TauPi0EflowCreateROI(const std::string &type,
+    const std::string &name,
+    const IInterface *parent) :
+TauToolBase(type, name, parent),
+m_cellsContainerName("AllCalo"),
+m_cellsOutputContainerName("TauCells"),
+m_detRIsolCaloCut(0.4),
+m_detRCoreCaloCut(0.2),
+m_useNoiseSigma(1),
+m_AbsNoiseSigma_cut(2),
+m_detRChrgEMCut(0.0375),
+m_removeChrgEM01(0),
+m_removeChrgEM2(0),
+m_fillCellContainer(false),
+m_pCellOutputContainer(0) ,
+m_doCellCorrection(false), //FF: don't do cell correction by default
+m_tauOriginCorrTool("")
+{
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("CellsContainerName", m_cellsContainerName);
+    declareProperty("CellsOutputContainerName", m_cellsOutputContainerName);
+    // declare options for noise/weighting
+    declareProperty("useNoiseSigma", m_useNoiseSigma);
+    declareProperty("AbsNoiseSigma_cut", m_AbsNoiseSigma_cut);
+    declareProperty("CaloNoiseTool", m_noiseTool, "Tool Handle for noise tool");
+    // declare large fixed cone for creating subcollection of cells (cluster)
+    declareProperty("detRCoreCaloCut", m_detRCoreCaloCut);
+    declareProperty("detRChrgEMCut", m_detRChrgEMCut);
+    declareProperty("removeChrgEM01", m_removeChrgEM01);
+    declareProperty("removeChrgEM2", m_removeChrgEM2);
+    declareProperty("detRIsolCaloCut", m_detRIsolCaloCut);
+    declareProperty("fillCellContainer", m_fillCellContainer);
+    declareProperty("CaloCellMakerToolNames", m_caloCellMakerToolNames);
+    declareProperty("CellCorrection", m_doCellCorrection);
+    declareProperty("OriginCorrectionTool", m_tauOriginCorrTool);
+}
+
+
+//-----------------------------------------------------------------------------
+// Destructor
+//-----------------------------------------------------------------------------
+
+TauPi0EflowCreateROI::~TauPi0EflowCreateROI() {
+}
+
+//-----------------------------------------------------------------------------
+// Event Initializer
+//-----------------------------------------------------------------------------
+
+StatusCode TauPi0EflowCreateROI::eventFinalize(TauCandidateData *) {
+
+        
+    if (m_fillCellContainer) {
+
+        StatusCode sc;
+        
+        std::vector<ICaloCellMakerTool*>::iterator itrTool = m_caloCellMakerTools.begin();
+        std::vector<ICaloCellMakerTool*>::iterator endTool = m_caloCellMakerTools.end();
+
+        unsigned int index = 0;
+
+        ATH_MSG_DEBUG("Order and check container " << m_cellsOutputContainerName << " with " << m_caloCellMakerTools.size() << " tools");
+        for (; itrTool != endTool; ++itrTool) {
+
+            ATH_MSG_DEBUG("Calling tool " << m_caloCellMakerToolNames[index]);
+
+            ListItem theItem(m_caloCellMakerToolNames[index]);
+
+            sc = (*itrTool)->process(m_pCellOutputContainer);
+
+            if (sc.isFailure()) {
+                ATH_MSG_ERROR("Error executing tool " << m_caloCellMakerToolNames[index]);
+                //TODO: return something?
+            }
+            ++index;
+        }
+
+        ATH_MSG_DEBUG("setConst container " << m_cellsOutputContainerName);
+        sc = evtStore()->setConst(m_pCellOutputContainer);
+        if (sc.isFailure()) {
+            ATH_MSG_ERROR("Error while setting const: " << m_cellsOutputContainerName);
+        }
+    }
+    
+    return StatusCode::SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Event Initializer
+//-----------------------------------------------------------------------------
+
+StatusCode TauPi0EflowCreateROI::eventInitialize(TauCandidateData *) {
+
+    StatusCode sc;
+
+    const CaloCell_ID* cellID;
+    sc = detStore()->retrieve(cellID);
+    if (sc.isFailure()) {
+        ATH_MSG_ERROR("Unable to retrieve caloCell_ID helper from DetectorStore");
+        return sc;
+    }
+
+    //Build bitmap to keep track which cells have been added to CellContainer;
+    IdentifierHash hashMax;
+
+    // Get hash range
+    hashMax = cellID->calo_cell_hash_max();
+    ATH_MSG_VERBOSE("CaloCell Hash Max: " << hashMax);
+    m_addedCellsMap.resize(hashMax, false);
+    for (unsigned i = 0; i < hashMax; i++) {
+        m_addedCellsMap[i] = false;
+    }
+    //ak
+    m_clusterMap.clear();
+
+    // output cell container
+    // record here EMtopocluster
+    //---------------------------------------------------------------------
+    if (m_fillCellContainer) {
+        m_pCellOutputContainer = new CaloCellContainer(SG::VIEW_ELEMENTS);
+        ATH_MSG_VERBOSE("record container " << m_cellsOutputContainerName);
+        sc = evtStore()->record(m_pCellOutputContainer, m_cellsOutputContainerName);
+
+        if (sc.isFailure()) {
+            ATH_MSG_INFO("Unable to record " << m_cellsOutputContainerName << " to TES");
+        }
+    }
+    
+    if (m_doCellCorrection) {
+        // Cell Origin Correction Tool initializeEvent is not called automatically
+        // -> call from here
+        sc = m_tauOriginCorrTool->eventInitialize();
+        if (sc.isFailure()) {
+            ATH_MSG_ERROR("Unable to retrieve TauOriginCorrectionTool");
+            return sc;
+        }
+    }
+
+    return StatusCode::SUCCESS;
+}
+
+
+//-------------------------------------------------------------------------
+// Initializer
+//-------------------------------------------------------------------------
+
+StatusCode TauPi0EflowCreateROI::initialize() {
+
+    ATH_MSG_VERBOSE(name() << " CellsContainerName = " << m_cellsContainerName);
+    ATH_MSG_VERBOSE(name() << " RconeTauCut        = " << m_detRIsolCaloCut);
+
+    //Create Noise Tools:
+    if (m_useNoiseSigma != 0) {
+        // SL changes to retrieval of CaloNoiseTool
+        if (m_noiseTool.retrieve().isFailure()) {
+            ATH_MSG_FATAL("Unable to find tool for Calorimeter Noise ");
+            return StatusCode::FAILURE;
+        }
+    }
+
+    StatusCode sc;
+    //---------------------------------------------------------------------
+    // Get pointer to Tool Service
+    //---------------------------------------------------------------------
+    IToolSvc *pToolSvc;
+    sc = service("ToolSvc", pToolSvc);
+    if (sc.isFailure()) {
+        ATH_MSG_FATAL("Tool Service not found");
+        return StatusCode::FAILURE;
+    }
+
+    //---------------------------------------------------------------------
+    // Need some tools for cells 
+    //---------------------------------------------------------------------
+    std::vector<std::string>::const_iterator itrName = m_caloCellMakerToolNames.begin();
+    std::vector<std::string>::const_iterator endName = m_caloCellMakerToolNames.end();
+
+    IAlgTool* algtool;
+    for (; itrName != endName; ++itrName) {
+
+        ListItem theItem(*itrName);
+
+        ATH_MSG_DEBUG("Retrieving " << *itrName);
+        sc = pToolSvc->retrieveTool(theItem.type(), theItem.name(), algtool);
+
+        if (sc.isFailure()) {
+            ATH_MSG_INFO("Unable to find tool for " << (*itrName));
+        } else {
+            ATH_MSG_INFO((*itrName) << " successfully retrieved");
+
+            m_caloCellMakerTools.push_back(dynamic_cast<ICaloCellMakerTool*> (algtool));
+        }
+    }
+    
+    if (m_tauOriginCorrTool.retrieve().isFailure()) {
+        ATH_MSG_ERROR("Cannot find tool named <" << m_tauOriginCorrTool << ">");
+        return StatusCode::FAILURE;
+    }
+
+    return StatusCode::SUCCESS;
+}
+
+
+//-------------------------------------------------------------------------
+// Execution
+//-------------------------------------------------------------------------
+
+StatusCode TauPi0EflowCreateROI::execute(TauCandidateData *data) {
+    
+  xAOD::TauJet *pTau = data->xAODTau;
+
+    if (pTau->numTrack()==0) {
+        ATH_MSG_VERBOSE("tau has no tracks -> skip TrackCreateROI");
+        return StatusCode::SUCCESS;
+    }
+
+    StatusCode sc;
+
+    //---------------------------------------------------------------------
+    // Retrieve CaloCellCollection from StoreGate
+    //---------------------------------------------------------------------
+    const CaloCellContainer *pCellContainer;
+    sc = evtStore()->retrieve(pCellContainer, m_cellsContainerName);
+    if (sc.isFailure()) {
+        ATH_MSG_INFO("TrackCreateROI: Unable to retrieve " << m_cellsContainerName << " from TES");
+    } else {
+        ATH_MSG_VERBOSE("TrackCreateROI: Successfully retrieved " << m_cellsContainerName << " from TES");
+    }
+
+
+    // output cell container
+    /*
+    CaloCellContainer *pCellOutputContainer;
+    if (m_fillCellContainer) {
+        sc = evtStore()->retrieve(pCellOutputContainer, m_cellsOutputContainerName);
+        if (sc.isFailure()) {
+            ATH_MSG_INFO("TrackCreateROI: Unable to retrieve " << m_cellsOutputContainerName << " from TES");
+        } else {
+            ATH_MSG_VERBOSE("TrackCreateROI: Successfully retrieved " << m_cellsOutputContainerName << " from TES with size = " << pCellOutputContainer->size());
+        }
+    }
+    */
+
+    //---------------------------------------------------------------------
+    // Loop over cells collection and find closest cell at a given layer
+    // from track impact point at vertex and propagated in magnetic field
+    //---------------------------------------------------------------------
+
+    //do cell selection
+    //TODO: ATTENTION: distance 0.8 is hardcoded!!
+    CaloCellList *celllist = new CaloCellList(pCellContainer);       
+    celllist->select(pTau->track(0)->eta(), pTau->track(0)->phi(), 0.8);
+
+    if (celllist->ncells() == 0) {
+        delete celllist;
+        return StatusCode::FAILURE;
+    }
+
+    // scan ROI twice: first to classify the case, second time to classify cells
+
+    float sumEM01ChrgTrk = 0;
+    float sumEM2Chrg = 0;
+    float sumHADChrg = 0;
+    
+    //use tau vertex to correct cell position
+    if (m_doCellCorrection && pTau->vertexLink()) {
+      m_tauOriginCorrTool->setOriginSource( ( *pTau->vertexLink() ) );
+    }
+
+    const CaloCell *pCell;
+    pCell = 0;
+
+    CaloCellList::list_iterator itr = celllist->begin();
+    CaloCellList::list_iterator itrE = celllist->end();
+    for (; itr != itrE; ++itr) {
+        pCell = *itr;
+        
+        //correct cell
+        if (m_doCellCorrection) {
+            m_tauOriginCorrTool->correctCell(pCell);
+        }
+        
+        double cellPhi = pCell->phi();
+        double cellEta = pCell->eta();
+        double cellET  = pCell->et();
+        
+        if (m_doCellCorrection) {
+             m_tauOriginCorrTool->resetCell(pCell);
+        }
+
+	// XXXXstill need to migrate track extrapolation
+        double detCell = Tau1P3PKineUtils::deltaR(pTau->track(0)->eta(),pTau->track(0)->phi(), cellEta, cellPhi);
+	// double detCell = P4Helpers::deltaR(*pTau->track(0), cellEta, cellPhi);
+
+        // collect all cells (remove noisy cells ) in a fixed
+        // large cone around candidate (at vertex)
+        if (detCell > m_detRIsolCaloCut) continue;
+
+        // find position nominal position of the closest cell at each layer
+        int sampling = pCell->caloDDE()->getSampling();
+        if (sampling == 4) sampling = 0;
+        if (sampling == 5) sampling = 1;
+        if (sampling == 6) sampling = 2;
+        if (sampling == 7) sampling = 3;
+
+        if (sampling >= 3) sumHADChrg += cellET;
+
+        if (sampling < 4) //ak
+        {
+            //for each track connected to tau object
+            for (unsigned int itr = 0; itr < pTau->numTrack(); ++itr) {
+                // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks)
+                if (itr >= 9) break;
+
+                double detEtaCell;
+                double detPhiCell;
+                // detEtaCell = Tau1P3PKineUtils::deltaEta(cellEta, pExtraDetails->etaTrkCaloSamp()[itr][sampling]);
+                // detPhiCell = Tau1P3PKineUtils::deltaPhi(cellPhi, pExtraDetails->phiTrkCaloSamp()[itr][sampling]);
+		// XXXXstill need to migrate track extrapolation
+                detEtaCell = Tau1P3PKineUtils::deltaEta(cellEta, pTau->track(itr)->eta());
+                detPhiCell = Tau1P3PKineUtils::deltaPhi(cellPhi, pTau->track(itr)->phi());
+
+                //FIX ME! Should we look for different cell in eta and 
+                //in phi? ot the closest one?
+                double detRCell = sqrt(detEtaCell * detEtaCell + detPhiCell * detPhiCell);
+                if (detRCell < m_detRChrgEMCut) {
+                    if (sampling == 0 || sampling == 1) sumEM01ChrgTrk += cellET;
+                    if (sampling == 2) sumEM2Chrg += cellET;
+                }
+            }
+        } //ak
+    } // end cell loop
+
+    float category = 0;
+    float maxEM2Chrg = 0;
+    if (sumEM01ChrgTrk < 0.05 * pTau->track(0)->pt()) {
+        category = 1;
+    } else if (sumEM01ChrgTrk >= 0.05 * pTau->track(0)->pt() && sumHADChrg > 0.40 * pTau->track(0)->pt()) {
+        category = 2;
+        maxEM2Chrg = sumEM2Chrg - 2.5 * sumEM01ChrgTrk;
+    }
+
+    float maxEMChrg = 0;
+    if (category == 1 || category == 2) {
+        maxEMChrg = 0.70 * pTau->track(0)->pt();
+    } else {
+        maxEMChrg = 0.65 * pTau->track(0)->pt();
+    }
+
+    // if track was not interacting early, defined by finding 40% of trackPT in EM3+HAD,
+    // subtract cells only from EM2
+    // if energy deposition in EM01, don't subtract in EM2 more then allowing up to 
+    // 2.5*EM01 left in EM2
+
+    //counting subtracted cells, do not allow for more subtraction than 70% of track pt
+    unsigned int counter = 0;
+
+    float sumEMChrg = 0;
+    sumEM2Chrg = 0.;
+
+    itr = celllist->begin();
+    for (; itr != itrE; ++itr) {
+        pCell = *itr;
+        
+        //correct cell
+        if (m_doCellCorrection) {
+            m_tauOriginCorrTool->correctCell(pCell);
+        }
+        
+        double cellPhi = pCell->phi();
+        double cellEta = pCell->eta();
+        double cellET  = pCell->et();
+        double cellEnergy = pCell->energy();
+        
+        if (m_doCellCorrection) {
+             m_tauOriginCorrTool->resetCell(pCell);
+        }
+
+        double detCell = Tau1P3PKineUtils::deltaR(pTau->track(0)->eta(),pTau->track(0)->phi(), cellEta, cellPhi);
+        // double detCell = P4Helpers::deltaR(*pTau->track(0), cellEta, cellPhi);
+
+        // collect all cells (remove noisy cells ) in a fixed
+        // large cone around candidate (at vertex)
+        if (detCell > m_detRIsolCaloCut) continue;
+
+        int isCellAccepted = 1;
+
+        if (m_useNoiseSigma == 1) {
+            double noiseSigma;
+            noiseSigma = m_noiseTool->getNoise(*itr, ICalorimeterNoiseTool::ELECTRONICNOISE_HIGHESTGAIN);
+            if (fabs(cellEnergy) < m_AbsNoiseSigma_cut * noiseSigma) isCellAccepted = 0;
+        }
+
+        // find position nominal position of the closest cell at each layer
+        int sampling = pCell->caloDDE()->getSampling();
+        if (sampling == 4) sampling = 0;
+        if (sampling == 5) sampling = 1;
+        if (sampling == 6) sampling = 2;
+        if (sampling == 7) sampling = 3;
+
+        if (sampling >= 3) isCellAccepted = 0;
+
+        if (isCellAccepted == 0) continue;
+
+        // remove cells in vicinity of the track
+        //TODO: if not necessary!
+        if (sampling < 4) //ak
+        {
+            //for each track connected to tau object
+            for (unsigned int itr = 0; itr < pTau->numTrack(); ++itr) {
+                // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks)
+                if (itr >= 9) break;
+
+                double detEtaCell;
+                double detPhiCell;
+                // detEtaCell = Tau1P3PKineUtils::deltaEta(cellEta, pExtraDetails->etaTrkCaloSamp()[itr][sampling]);
+                // detPhiCell = Tau1P3PKineUtils::deltaPhi(cellPhi, pExtraDetails->phiTrkCaloSamp()[itr][sampling]);
+		// XXXXstill need to migrate track extrapolation
+                detEtaCell = Tau1P3PKineUtils::deltaEta(cellEta, pTau->track(itr)->eta());
+                detPhiCell = Tau1P3PKineUtils::deltaPhi(cellPhi, pTau->track(itr)->phi());
+
+                //FIX ME! Should we look for different cell in eta and 
+                //in phi? of the closest one?
+
+                double detRCell = sqrt(detEtaCell * detEtaCell + detPhiCell * detPhiCell);
+                if (detRCell < m_detRChrgEMCut) {
+
+                    if (m_removeChrgEM2 == 1 && sampling == 2) {
+                        if (sumEMChrg + cellET < maxEMChrg) {
+                            if (category == 2 && (sumEM2Chrg + cellET < maxEM2Chrg)) {
+                                isCellAccepted = 0;
+                                sumEMChrg += cellET;
+                                sumEM2Chrg += cellET;
+                            } else {
+                                isCellAccepted = 0;
+                                sumEMChrg += cellET;
+                            }
+                        }
+                    }
+                    if (m_removeChrgEM01 == 1 && (sampling == 0 || sampling == 1) && category != 2) {
+                        if (sumEMChrg + cellET < maxEMChrg) {
+                            isCellAccepted = 0;
+                            sumEMChrg += cellET;
+                        }
+                    }
+
+                }
+
+            }
+        } //ak
+
+
+        if (isCellAccepted == 0) continue;
+
+        // add accepted cells to the container
+        if (m_fillCellContainer && m_pCellOutputContainer != 0) {
+            //Ask cell for it's hash
+            const IdentifierHash cellHash = pCell->caloDDE()->calo_hash();
+            //Check it this cell is already part of reducedCellContainer
+            if (!m_addedCellsMap[cellHash]) {
+                ++counter;
+                m_pCellOutputContainer->push_back(pCell);
+                m_addedCellsMap[cellHash] = true;
+            } else
+                ATH_MSG_VERBOSE("Cell with hash " << cellHash << "added more than once.");
+        }              
+    } //end 2nd cell loop
+
+    delete celllist;
+
+    ATH_MSG_DEBUG("Added " << counter << "cells to container " << m_cellsOutputContainerName);
+    
+
+    return sc;
+}
diff --git a/Reconstruction/tauRec/depreciated/TauPi0EflowCreateROI.h b/Reconstruction/tauRec/depreciated/TauPi0EflowCreateROI.h
new file mode 100644
index 0000000000000000000000000000000000000000..ba3f0057dfe7df94b95d6862f5bb934b935ec7f5
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauPi0EflowCreateROI.h
@@ -0,0 +1,90 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAU1P3PTRACKCREATEROI_H
+#define TAUREC_TAU1P3PTRACKCREATEROI_H
+
+#include "tauRec/TauToolBase.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "CaloInterface/ICalorimeterNoiseTool.h"
+#include "CaloInterface/ICaloCellMakerTool.h"
+#include <map>
+
+class ICaloNoiseTool;
+class CaloCellContainer;
+class TauOriginCorrectionTool;
+
+/**
+ * @brief Class for collecting cells for tau ROI.
+ * 
+ *  This tool was fomerly named as tau1p3pTrackCreateROI.
+ * 
+ * @author Elzbieta Richter-Was
+ * 
+ */
+
+class TauPi0EflowCreateROI : public TauToolBase {
+public:
+
+    TauPi0EflowCreateROI(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+
+    virtual ~TauPi0EflowCreateROI();
+
+    virtual StatusCode initialize();
+    virtual StatusCode eventInitialize(TauCandidateData *data);
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode eventFinalize(TauCandidateData *data);
+
+
+private:
+
+    std::string m_cellsContainerName;
+    std::string m_cellsOutputContainerName;
+    std::string m_clusterContainerName;
+
+    //!  large fixed cone to collect cells around the track
+    double m_detRIsolCaloCut;
+
+    //!  large fixed cone to collect cells around the track
+    double m_detRCoreCaloCut;
+
+    //!  use noise tool to estimate sigma
+    double m_useNoiseSigma;
+
+    //!  threshold to suppress noisy cells
+    double m_AbsNoiseSigma_cut;
+
+    //!  threshold to suppress cell from being used for topo clustering
+    double m_detRChrgEMCut;
+
+    //!  threshold to suppress cell from being used for topo clustering
+    double m_removeChrgEM01;
+
+    //!  threshold to suppress cell from being used for topo clustering
+    double m_removeChrgEM2;
+
+    // ! flag to decide wether we fill an output cell container to be later use for other clustering
+    bool m_fillCellContainer;
+
+    //! tool for noise
+    ToolHandle<ICalorimeterNoiseTool> m_noiseTool;
+
+    std::map<Analysis::TauJet *, CaloCluster *> m_clusterMap;
+
+    std::vector<bool> m_addedCellsMap;
+    
+    std::vector<std::string> m_caloCellMakerToolNames ;
+    std::vector<ICaloCellMakerTool*> m_caloCellMakerTools ;
+    
+    CaloCellContainer * m_pCellOutputContainer;
+    
+    bool m_doCellCorrection; //<! enable cell origin correction
+    ToolHandle<TauOriginCorrectionTool> m_tauOriginCorrTool;
+
+};
+
+
+#endif
diff --git a/Reconstruction/tauRec/depreciated/TauSetTracksAndCharge.cxx b/Reconstruction/tauRec/depreciated/TauSetTracksAndCharge.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..cf3dea0f39ee85c028c360507f722422f430cd64
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauSetTracksAndCharge.cxx
@@ -0,0 +1,85 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "tauRec/TauCandidateData.h"
+#include "tauRec/TauSetTracksAndCharge.h"
+#include "tauEvent/TauJetParameters.h"
+
+#include <GaudiKernel/IToolSvc.h>
+#include <GaudiKernel/ListItem.h>
+
+//-------------------------------------------------------------------------
+// Constructor
+//-------------------------------------------------------------------------
+TauSetTracksAndCharge::TauSetTracksAndCharge(const std::string &type,
+    const std::string &name,
+    const IInterface *parent) :
+TauToolBase(type, name, parent),
+m_trackContainerName("TrackParticleCandidate") {
+    declareInterface<TauToolBase > (this);
+    declareProperty("TrackContainer", m_trackContainerName);
+}
+
+
+//-------------------------------------------------------------------------
+// Destructor
+//-------------------------------------------------------------------------
+TauSetTracksAndCharge::~TauSetTracksAndCharge() {
+}
+
+
+//-------------------------------------------------------------------------
+// Initializer
+//-------------------------------------------------------------------------
+StatusCode TauSetTracksAndCharge::initialize() {
+    return StatusCode::SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// Execution
+//-------------------------------------------------------------------------
+StatusCode TauSetTracksAndCharge::execute(TauCandidateData *data) {
+
+    StatusCode sc;
+    const Rec::TrackParticleContainer *trackContainer;
+
+    //SX changes needed by trigger
+    sc = data->getObject("TrackContainer", trackContainer);
+
+    if (sc == StatusCode::FAILURE || !trackContainer) {
+
+        ATH_MSG_DEBUG("no TrackParticleContainer for trigger");
+
+            StatusCode sc = evtStore()->retrieve(trackContainer, m_trackContainerName);
+        if (sc.isFailure() || !trackContainer) {
+            ATH_MSG_WARNING("Unable to retrieve track particle container <" << m_trackContainerName << ">!");
+            return StatusCode::SUCCESS;
+        }
+    }
+
+    Analysis::TauJet *pTau = data->tau;
+
+    double charge = 0;
+    
+    for (unsigned int i = 0; i != pTau->seedCalo_numTrack(); ++i) {
+        
+        charge += pTau->track(i)->charge();
+
+        // add tracks to global tau track collection
+        pTau->addTrack(trackContainer, pTau->track(i));
+    }
+    
+    ATH_MSG_INFO("seedCalo_numTrack = " << pTau->seedCalo_numTrack());
+    ATH_MSG_INFO("numTrack = " << pTau->numTrack());    
+    
+    // save charge
+    ATH_MSG_DEBUG("charge from tracks: " << charge << " will be saved in tau candidate as: " << (int)charge);
+    pTau->set_charge((int) charge);
+
+    return StatusCode::SUCCESS;
+}
+
+
+
+
diff --git a/Reconstruction/tauRec/depreciated/TauSetTracksAndCharge.h b/Reconstruction/tauRec/depreciated/TauSetTracksAndCharge.h
new file mode 100644
index 0000000000000000000000000000000000000000..deb5f695046da6b735224153e287698475577b29
--- /dev/null
+++ b/Reconstruction/tauRec/depreciated/TauSetTracksAndCharge.h
@@ -0,0 +1,45 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUSETTRACKSANDCHARGE_H
+#define	TAUREC_TAUSETTRACKSANDCHARGE_H
+
+#include "tauRec/TauToolBase.h"
+#include "GaudiKernel/ToolHandle.h"
+
+class TauCandidateData;
+
+/**
+ * @brief      Class to set number of tracks and charge of the tau (depreciated!)
+ * 
+ * @author  Felix Friedrich
+ */
+
+class TauSetTracksAndCharge: public TauToolBase
+{
+
+    public:
+
+        //-------------------------------------------------------------
+        //! Constructor
+        //-------------------------------------------------------------
+        TauSetTracksAndCharge( const std::string& type,
+                const std::string& name,
+                const IInterface* parent);
+
+        //-------------------------------------------------------------
+        //! Destructor
+        //-------------------------------------------------------------
+        virtual ~TauSetTracksAndCharge();
+
+        virtual StatusCode execute( TauCandidateData *data );
+        virtual StatusCode initialize();
+
+
+    private: 
+        std::string m_trackContainerName;
+};
+
+#endif	/* TAUSETTRACKSANDCHARGE_H */
+
diff --git a/Reconstruction/tauRec/doc/mainpage.h b/Reconstruction/tauRec/doc/mainpage.h
new file mode 100644
index 0000000000000000000000000000000000000000..6191183cd74dcbc445c810ba0f8f170325eb8cb6
--- /dev/null
+++ b/Reconstruction/tauRec/doc/mainpage.h
@@ -0,0 +1,23 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+
+@mainpage tauRec
+@author Srini Rajagopalan, Michael Heldmann, Elzbieta Richter-Was, Lukasz Janyst, Stan Lai, Nico Meyer, Anna Kaczmarska, Felix Friedrich
+
+@section Introduction
+
+This is the tauRec package. It holds algorithms to reconstruct hadronically decaying tau candidates. The tau reconstruction is using a calorimeter seeded approach. Tracks are collected in a cone around the calorimeter seed and associated to the tau candidate. An own tau energy scale is set.
+
+Packages used by tauRec are listed here:
+
+@htmlinclude used_packages.html
+
+The requirements file for tauRec is shown here:
+
+@include requirements
+
+
+*/
diff --git a/Reconstruction/tauRec/python/TauAlgorithmsHolder.py b/Reconstruction/tauRec/python/TauAlgorithmsHolder.py
new file mode 100644
index 0000000000000000000000000000000000000000..97c802cf7654f5ec200bf84a1ee1e5d0117c8117
--- /dev/null
+++ b/Reconstruction/tauRec/python/TauAlgorithmsHolder.py
@@ -0,0 +1,879 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+################################################################################
+##
+#@file TauAlgorithmsHolder.py
+#
+#@brief All tau algorithms needed for tau reconstruction are configured here.
+#
+#@author Felix Friedrich <felix.friedrich@cern.ch>
+################################################################################
+
+from AthenaCommon.SystemOfUnits import *
+from AthenaCommon.Constants import *
+
+cached_instances = {}
+
+sPrefix = 'tauRec_'
+bAODmode = False
+
+# standard container names
+_DefaultVertexContainer = "PrimaryVertices"
+_DefaultTrackContainer ="InDetTrackParticles"
+
+######################################################################## 
+def setPrefix(prefix): 
+    global sPrefix 
+    sPrefix = prefix 
+    
+######################################################################## 
+def setAODmode(mode): 
+    global bAODmode 
+    bAODmode = mode
+
+
+########################################################################
+# Atlas Extrapolator
+def getAtlasExtrapolator():
+    _name = sPrefix + 'theAtlasExtrapolator'
+    
+    from AthenaCommon.AppMgr import ToolSvc
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    #Configure the extrapolator
+    from TrkExTools.AtlasExtrapolator import AtlasExtrapolator
+    theAtlasExtrapolator=AtlasExtrapolator(name = _name)
+    theAtlasExtrapolator.DoCaloDynamic = False # this turns off dynamic
+    
+    ToolSvc += theAtlasExtrapolator
+    cached_instances[_name] = theAtlasExtrapolator
+    return theAtlasExtrapolator
+
+########################################################################
+# JetSeedBuilder
+def getJetSeedBuilder(seed_collection_name):
+    _name = sPrefix + 'JetSeedBuilder'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import JetSeedBuilder
+    JetSeedBuilder = JetSeedBuilder(name = _name,
+            JetCollection = seed_collection_name,
+            maxDist = 0.2,
+            minPt = 10.*GeV,
+            SwitchJetsEmScale = False)
+            
+    cached_instances[_name] = JetSeedBuilder
+    return JetSeedBuilder
+
+########################################################################
+# Tau energy calibration and tau axis direction
+def getTauAxis():
+    _name = sPrefix + 'TauAxis'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import TauAxisSetter
+    TauAxisSetter = TauAxisSetter(  name = _name, 
+                                    ClusterCone = 0.2,
+                                    CellCorrection = True)
+                                    
+    cached_instances[_name] = TauAxisSetter                
+    return TauAxisSetter
+
+########################################################################
+# Tau energy calibration
+def getEnergyCalibrationLC(correctEnergy=True, correctAxis=False, postfix=''):
+ 
+    _name = sPrefix +'EnergyCalibrationLC' + postfix
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import TauCalibrateLC
+    TauCalibrateLC = TauCalibrateLC(name = _name,
+            calibrationFile = "EnergyCalibrationLC2012_retuned.root",
+            doEnergyCorrection = correctEnergy,
+            doAxisCorrection = correctAxis)
+            
+    cached_instances[_name] = TauCalibrateLC                
+    return TauCalibrateLC
+
+########################################################################
+# Tau cell variables calculation
+def getCellVariables(cellConeSize=0.2, prefix=''):
+    #if prefix is not given, take global one 
+    if not prefix: 
+        prefix=sPrefix 
+ 
+    _name = prefix + 'CellVariables'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import TauCellVariables
+    TauCellVariables = TauCellVariables(name = _name,
+            CellEthreshold = 0.2*GeV,
+            StripEthreshold = 0.2*GeV,
+            EMSumThreshold = 0.5*GeV,
+            EMSumRadius = 0.2,
+            CellCone = cellConeSize,
+            CellCorrection = True)
+            
+    cached_instances[_name] = TauCellVariables   
+    return TauCellVariables
+
+########################################################################
+# ExtrapolateToCaloTool
+def getExtrapolateToCaloTool():
+    _name = sPrefix + 'ExtrapolateToCaloTool'
+    
+    from AthenaCommon.AppMgr import ToolSvc
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from TrackToCalo.TrackToCaloConf import ExtrapolateToCaloTool
+    tauExtrapolateToCaloTool=ExtrapolateToCaloTool(name = _name, Extrapolator = getAtlasExtrapolator())
+    
+    ToolSvc += tauExtrapolateToCaloTool  
+    cached_instances[_name] = tauExtrapolateToCaloTool
+    return tauExtrapolateToCaloTool   
+
+                
+########################################################################
+# calibrate tau at EM scale
+def getEnergyCalibrationEM():
+    _name = sPrefix + 'EnergyCalibrationEM'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import TauCalibrateEM
+    TauCalibrateEM = TauCalibrateEM(name = _name, response_functions_file = "EMTES_Fits_Oct2010.root")
+    
+    cached_instances[_name] = TauCalibrateEM
+    return TauCalibrateEM
+
+########################################################################
+########################################################################
+# Tracking Tools
+# TODO: rearrange
+########################################################################
+
+
+########################################################################
+# TauFullLinearizedTrackFactory
+def getTauFullLinearizedTrackFactory():
+    _name = sPrefix + 'TauFullLinearizedTrackFactory'
+    
+    from AthenaCommon.AppMgr import ToolSvc
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from TrkVertexFitterUtils.TrkVertexFitterUtilsConf import Trk__FullLinearizedTrackFactory
+    TauFullLinearizedTrackFactory=Trk__FullLinearizedTrackFactory(name = _name, Extrapolator = getAtlasExtrapolator())
+    
+    ToolSvc += TauFullLinearizedTrackFactory
+    cached_instances[_name] = TauFullLinearizedTrackFactory
+    return TauFullLinearizedTrackFactory
+
+########################################################################
+# TauCrossDistancesSeedFinder
+def getTauCrossDistancesSeedFinder():
+    _name = 'TauCrossDistancesSeedFinder'
+
+    from AthenaCommon.AppMgr import ToolSvc
+
+    if _name in cached_instances:
+        return cached_instances[_name]
+
+    #first the seed finder utils
+    from TrkVertexSeedFinderUtils.TrkVertexSeedFinderUtilsConf import Trk__SeedNewtonTrkDistanceFinder
+    TauNewtonTrkDistanceFinder = Trk__SeedNewtonTrkDistanceFinder( name = sPrefix+'TauSeedNewtonTrkDistanceFinder')
+    ToolSvc += TauNewtonTrkDistanceFinder
+    
+    #then the seed finder tools
+    from TrkVertexSeedFinderTools.TrkVertexSeedFinderToolsConf import Trk__CrossDistancesSeedFinder
+    TauCrossDistancesSeedFinder = Trk__CrossDistancesSeedFinder( name = _name, TrkDistanceFinder=TauNewtonTrkDistanceFinder)
+
+    cached_instances[_name] = TauCrossDistancesSeedFinder
+    ToolSvc +=TauCrossDistancesSeedFinder
+    return TauCrossDistancesSeedFinder
+
+########################################################################
+# TauAdaptiveVertexFitter
+def getTauAdaptiveVertexFitter():
+    _name = sPrefix + 'TauAdaptiveVertexFitter'
+    
+    from AthenaCommon.AppMgr import ToolSvc
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    #then the fitter utils
+    from TrkVertexFitterUtils.TrkVertexFitterUtilsConf import Trk__ImpactPoint3dEstimator
+    TauInDetImpactPoint3dEstimator = Trk__ImpactPoint3dEstimator(name = sPrefix+'TauTrkImpactPoint3dEstimator', Extrapolator = getAtlasExtrapolator())
+    ToolSvc += TauInDetImpactPoint3dEstimator
+    
+    from TrkVertexFitterUtils.TrkVertexFitterUtilsConf import Trk__DetAnnealingMaker
+    TauDetAnnealingMaker = Trk__DetAnnealingMaker(name = sPrefix+'TauDetAnnealingMaker', SetOfTemperatures = [ 64, 32, 16, 8, 4, 2, 1 ] )
+    ToolSvc += TauDetAnnealingMaker
+    
+    #then the fitters (smoother + adaptive with smoothing + fast billoir)
+    from TrkVertexFitters.TrkVertexFittersConf import Trk__SequentialVertexSmoother
+    TauSequentialVertexSmoother = Trk__SequentialVertexSmoother(name = sPrefix+'TauSequentialVertexSmoother')
+    ToolSvc += TauSequentialVertexSmoother
+     
+    from TrkVertexFitters.TrkVertexFittersConf import Trk__AdaptiveVertexFitter
+    TauAdaptiveVertexFitter = Trk__AdaptiveVertexFitter(name = _name, 
+                                                        SeedFinder=getTauCrossDistancesSeedFinder(), 
+                                                        ImpactPoint3dEstimator=TauInDetImpactPoint3dEstimator, 
+                                                        VertexSmoother=TauSequentialVertexSmoother, 
+                                                        AnnealingMaker=TauDetAnnealingMaker,
+                                                        LinearizedTrackFactory=getTauFullLinearizedTrackFactory(),
+                                                        XAODConverter="Trk::VxCandidateXAODVertex/VertexInternalEdmFactory")
+    
+    cached_instances[_name] = TauAdaptiveVertexFitter
+    ToolSvc +=TauAdaptiveVertexFitter
+    return TauAdaptiveVertexFitter
+
+########################################################################
+# TauTrackToVertexIPEstimator
+def getTauTrackToVertexIPEstimator():
+    _name = sPrefix + 'TauTrackToVertexIPEstimator'
+    
+    from AthenaCommon.AppMgr import ToolSvc
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from TrkVertexFitterUtils.TrkVertexFitterUtilsConf import Trk__TrackToVertexIPEstimator
+    TauTrackToVertexIPEstimator = Trk__TrackToVertexIPEstimator(name = _name,
+                                                                Extrapolator=getAtlasExtrapolator(),
+                                                                LinearizedTrackFactory=getTauFullLinearizedTrackFactory())
+    cached_instances[_name] = TauTrackToVertexIPEstimator
+    ToolSvc += TauTrackToVertexIPEstimator
+    return TauTrackToVertexIPEstimator                                     
+
+########################################################################
+# lock tau containers
+def getContainerLock():
+    _name = sPrefix + 'TauContainerLock'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import LockTauContainers
+    LockTauContainers = LockTauContainers(name = _name)
+    
+    cached_instances[_name] = LockTauContainers 
+    return LockTauContainers       
+
+#########################################################################
+# Tau Variables
+# TODO: rename + rearrange
+def getTauCommonCalcVars():
+    _name = sPrefix + 'TauCommonCalcVars'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import TauCommonCalcVars
+    TauCommonCalcVars = TauCommonCalcVars(name = _name)
+    
+    cached_instances[_name] = TauCommonCalcVars    
+    return TauCommonCalcVars
+
+#########################################################################
+# Tau Test
+def getTauTestDump():
+    _name = sPrefix + 'TauTestDump'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import TauTestDump
+    TauTestDump = TauTestDump(name = _name)
+    
+    cached_instances[_name] = TauTestDump
+    return TauTestDump
+
+#########################################################################
+# Tau Vertex Variables
+def getTauVertexVariables():
+    _name = sPrefix + 'TauVertexVariables'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+
+    from tauRec.tauRecFlags import jobproperties
+    useOldSeedFinderAPI = jobproperties.tauRecFlags.useOldVertexFitterAPI()
+
+    from tauRec.tauRecConf import TauVertexVariables
+    TauVertexVariables = TauVertexVariables(  name = _name,
+                                            PrimaryVertexKey  = _DefaultVertexContainer,                                            
+                                            TrackToVertexIPEstimator = getTauTrackToVertexIPEstimator(),
+                                            VertexFitter = getTauAdaptiveVertexFitter(),
+                                            #VertexFitter = "Trk::AdaptiveVertexFitter/InDetAdaptiveVxFitterTool",
+                                            SeedFinder = getTauCrossDistancesSeedFinder(),
+                                            XAODConverter = "Trk::VxCandidateXAODVertex/VertexInternalEdmFactory", # ATM only needed in case old API is used
+                                            TrackParticleContainer = _DefaultTrackContainer, # ATM only needed in case old API is used
+                                            useOldSeedFinderAPI = useOldSeedFinderAPI,
+                                            #OutputLevel = 2                                            
+                                              )
+    
+    cached_instances[_name] = TauVertexVariables    
+    return TauVertexVariables
+
+#########################################################################
+# Tau Variables
+# TODO: rename + rerrange
+def getTauSubstructure():
+    _name = sPrefix + 'TauSubstructure'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import TauSubstructureVariables
+    TauSubstructureVariables = TauSubstructureVariables(  name = _name,
+                                                          # parameters for CaloIsoCorrected variable
+                                                          maxPileUpCorrection = 4000., #MeV
+                                                          pileUpAlpha = 1.0,
+                                                          VertexCorrection = True,
+                                                          inAODmode = bAODmode)
+    
+    cached_instances[_name] = TauSubstructureVariables
+    return TauSubstructureVariables
+
+#########################################################################
+# ele veto variables
+def getElectronVetoVars():
+    _name = sPrefix + 'TauElectronVetoVars'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import TauElectronVetoVariables
+    TauElectronVetoVariables = TauElectronVetoVariables(name = _name,
+                                                        CellCorrection = True,
+                                                        TTCExtrapolator = getExtrapolateToCaloTool())
+    
+    cached_instances[_name] = TauElectronVetoVariables
+    return TauElectronVetoVariables
+
+
+#########################################################################
+# cell weight tool
+def getCellWeightTool():
+    _name = sPrefix + 'CellWeightTool'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    #from CaloClusterCorrection.CaloClusterCorrectionConf import H1WeightToolCSC12Generic    
+    from CaloRec.CaloTopoClusterFlags import jobproperties
+    # -- auto configure weight tool
+    finder = jobproperties.CaloTopoClusterFlags.cellWeightRefFinder.get_Value()
+    size   = jobproperties.CaloTopoClusterFlags.cellWeightRefSize.get_Value()
+    signal = jobproperties.CaloTopoClusterFlags.cellWeightRefSignal.get_Value()
+    
+    from CaloClusterCorrection.StandardCellWeightCalib import getCellWeightTool
+    CaloWeightTool = getCellWeightTool(finder,size,signal)
+    from AthenaCommon.AppMgr import ToolSvc
+    ToolSvc += CaloWeightTool
+    
+    cached_instances[_name] = CaloWeightTool
+    return CaloWeightTool
+
+#########################################################################
+# Bonn Pi0 algo
+# Cluster finder for Pi0 algo
+def getBonnPi0ClusterFinder():    
+    _name = sPrefix + 'BonnPi0ClusterFinder'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from CaloRec.CaloRecConf import CaloCellContainerFinalizerTool
+    TauCellContainerFinalizer = CaloCellContainerFinalizerTool(name=sPrefix+'tauPi0CellContainerFinalizer')
+    
+    from AthenaCommon.AppMgr import ToolSvc
+    ToolSvc += TauCellContainerFinalizer
+    
+    from tauRec.tauRecConf import TauPi0BonnCreateROI
+    TauPi0BonnCreateROI = TauPi0BonnCreateROI(name = _name,
+        CaloWeightTool = getCellWeightTool(),
+        ExtrapolateToCaloTool = getExtrapolateToCaloTool(),
+        CellMakerTool = TauCellContainerFinalizer,
+        #LonParFile = "longitudinal_para.dat",
+        #LatParFile = "lateral_para.dat",
+        LatParFile = "lateral_para.root",
+        #OriginCorrectionTool = getTauCellCorrection(),
+        ChargedPFOContainerName = 'TauPi0ChargedPFOContainer',
+        )
+    
+    cached_instances[_name] = TauPi0BonnCreateROI
+    return TauPi0BonnCreateROI
+
+#####################
+# create Pi0 clusters
+def getBonnPi0ClusterCreator():
+    _name = sPrefix + 'BonnPi0ClusterCreator'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import TauPi0BonnClusterCreator
+    TauPi0BonnClusterCreator = TauPi0BonnClusterCreator(name = _name,
+        ExtrapolateToCaloTool = getExtrapolateToCaloTool(),
+        InputPi0ClusterContainerName = 'TauPi0SubtractedClusterContainer',
+        OutputPi0ClusterContainerName = 'TauPi0ClusterContainer',
+        NeutralPFOContainerName= 'TauPi0NeutralPFOContainer',
+        )
+    
+    cached_instances[_name] = TauPi0BonnClusterCreator
+    return TauPi0BonnClusterCreator
+
+#####################
+# calculate MVA scores of pi0 clusters
+def getPi0BonnScoreCalculator():
+    _name = sPrefix + 'BonnPi0ScoreCalculator'
+
+    if _name in cached_instances:
+        return cached_instances[_name]
+
+    from tauRec.tauRecConf import TauPi0BonnScoreCalculator
+    TauPi0BonnScoreCalculator = TauPi0BonnScoreCalculator(name = _name,
+        ReaderOption = 'Silent:!Color',
+        BDTWeightFile = 'TauPi0BonnBDTWeights.xml',
+        )
+
+    cached_instances[_name] = TauPi0BonnScoreCalculator
+    return TauPi0BonnScoreCalculator
+
+#####################
+# select pi0 clusters
+def getPi0BonnSelector():
+    _name = sPrefix + 'BonnPi0Selector'
+
+    if _name in cached_instances:
+        return cached_instances[_name]
+
+    from tauRec.tauRecConf import TauPi0BonnSelector
+    TauPi0BonnSelector = TauPi0BonnSelector(name = _name,
+        ClusterEtCut         = (2100.*MeV,2500.*MeV,2600.*MeV,2400.*MeV,1900.*MeV),
+        ClusterBDTCut_1prong = (0.46,0.39,0.51,0.47,0.54),
+        ClusterBDTCut_mprong = (0.47,0.52,0.60,0.55,0.50),
+        )
+
+    cached_instances[_name] = TauPi0BonnSelector
+    return TauPi0BonnSelector
+
+
+
+
+#########################################################################
+# Photon Shot Finder algo
+def getTauShotFinder():    
+    _name = sPrefix + 'TauShotFinder'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    #from CaloRec.CaloRecConf import CaloCellContainerFinalizerTool
+    #TauCellContainerFinalizer = CaloCellContainerFinalizerTool(name=sPrefix+'tauShotCellContainerFinalizer')
+    #from AthenaCommon.AppMgr import ToolSvc
+    #ToolSvc += TauCellContainerFinalizer
+    
+    from tauRec.tauRecConf import TauShotFinder
+    TauShotFinder = TauShotFinder(name = _name,
+        CaloWeightTool = getCellWeightTool(),
+        ReaderOption = "Silent:!Color",
+        BDTWeightFile_barrel =  "TauShotsBDTWeights.xml",
+        BDTWeightFile_endcap1 = "TauShotsBDTWeights.xml",
+        BDTWeightFile_endcap2 = "TauShotsBDTWeights.xml",
+        NCellsInEta           = 5,
+        MinPtCut              = (400.*MeV,320.*MeV,9999999.*MeV,350.*MeV,320.*MeV),
+        AutoDoubleShotCut     = (10000.*MeV,10000.*MeV,9999999.*MeV,10000.*MeV,10000.*MeV),
+        MergedBDTScoreCut     = (-9999999.,-9999999.,-9999999.,-9999999.,-9999999.),
+        )
+    cached_instances[_name] = TauShotFinder
+    return TauShotFinder
+
+
+
+
+
+
+#########################################################################
+def getInDetTrackSelectorTool():
+    _name = sPrefix + 'InDetTrackSelectorTool'  
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    #Configures tau track selector tool (should eventually check whether an existing one is available)
+    from InDetTrackSelectorTool.InDetTrackSelectorToolConf import InDet__InDetDetailedTrackSelectorTool
+    InDetTrackSelectorTool = InDet__InDetDetailedTrackSelectorTool(name = _name,
+                                                                pTMin                = 1000.,
+                                                                IPd0Max              = 1.,
+                                                                IPz0Max              = 1.5, 
+                                                                useTrackSummaryInfo  = True,
+                                                                nHitBLayer           = 0, 
+                                                                nHitPix              = 2,  # PixelHits + PixelDeadSensors
+                                                                nHitSct              = 0,  # SCTHits + SCTDeadSensors
+                                                                nHitSi               = 7,  # PixelHits + SCTHits + PixelDeadSensors + SCTDeadSensors
+                                                                nHitTrt              = 0,  # nTRTHits
+                                                                useSharedHitInfo     = False,
+                                                                nSharedBLayer        = 99999,
+                                                                nSharedPix           = 99999,
+                                                                nSharedSct           = 99999,
+                                                                nSharedSi            = 99999,
+                                                                useTrackQualityInfo  = True,
+                                                                fitChi2OnNdfMax      = 99999,
+                                                                TrackSummaryTool     = None,
+                                                                Extrapolator         = getAtlasExtrapolator())
+                                                                
+    from AthenaCommon.AppMgr import ToolSvc
+    ToolSvc += InDetTrackSelectorTool
+    
+    cached_instances[_name] = InDetTrackSelectorTool
+    return InDetTrackSelectorTool
+
+
+############################################################################
+# setup up JVA tools
+def setupTauJVFTool():
+    from AthenaCommon.AppMgr import ToolSvc
+
+    """
+    #Configures tau track selector tool for TJVA
+    from InDetTrackSelectorTool.InDetTrackSelectorToolConf import InDet__InDetDetailedTrackSelectorTool
+    InDetTrackSelectorToolForTJVA = InDet__InDetDetailedTrackSelectorTool(name = sPrefix + 'InDetTrackSelectorToolForTJVA',
+                                                                pTMin                = 1000.,
+                                                                IPd0Max              = 9999.*mm,
+                                                                IPz0Max              = 9999.*mm,                                                                 
+                                                                nHitPix              = 2,  # PixelHits + PixelDeadSensors
+                                                                nHitSct              = 0,  # SCTHits + SCTDeadSensors
+                                                                nHitSi               = 7,  # PixelHits + SCTHits + PixelDeadSensors + SCTDeadSensors
+                                                                fitChi2OnNdfMax      = 99999,
+                                                                TrackSummaryTool     = None,
+                                                                Extrapolator         = getAtlasExtrapolator())        
+        
+    ToolSvc += InDetTrackSelectorToolForTJVA
+    """
+    from JetRec.JetRecConf import JetAlgorithm
+    jetTrackAlg = JetAlgorithm("JetTrackAlg_forTaus")
+
+    """
+    from JetRecTools.JetRecToolsConf import JetTrackSelectionTool
+    ToolSvc += JetTrackSelectionTool(InputContainer = _DefaultTrackContainer, 
+                                     OutputContainer="JetSelectedTracks_forTaus", 
+                                     Selector=InDetTrackSelectorToolForTJVA, 
+                                     OutputLevel=2
+                                     # what is about ptmin, eta min/max???
+                                     )
+    """
+
+    from JetRecTools.JetRecToolsConf import TrackVertexAssociationTool
+    ToolSvc += TrackVertexAssociationTool(TrackParticleContainer = _DefaultTrackContainer ,
+                                          TrackVertexAssociation="JetTrackVtxAssoc_forTaus", 
+                                          VertexContainer= _DefaultVertexContainer,
+                                          MaxTransverseDistance = 2.5 *mm,
+                                          MaxLongitudinalDistance = 2 *mm, 
+                                          #OutputLevel=2
+                                          )
+    #jetTrackAlg.Tools = [ToolSvc.JetTrackSelectionTool , ToolSvc.TrackVertexAssociationTool ]                                          
+    jetTrackAlg.Tools = [ToolSvc.TrackVertexAssociationTool ]                                          
+    
+    from AthenaCommon.AlgSequence import AlgSequence
+    topSequence = AlgSequence()    
+    topSequence+=jetTrackAlg
+    
+#########################################################################
+def getTauVertexFinder(doUseTJVA=False):
+    _name = sPrefix + 'TauVertexFinder'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    if doUseTJVA:
+        setupTauJVFTool()
+    
+    # Algorithm that overwrites numTrack() and charge() of all tauJets in the container
+    from tauRec.tauRecConf import TauVertexFinder
+    TauVertexFinder = TauVertexFinder(name = _name,
+                                      UseTJVA                 = doUseTJVA,
+                                      PrimaryVertexContainer  = _DefaultVertexContainer,
+                                      AssociatedTracks="GhostTrack", # OK??
+                                      TrackVertexAssociation="JetTrackVtxAssoc_forTaus"
+                                      )
+    
+    cached_instances[_name] = TauVertexFinder         
+    return TauVertexFinder 
+
+#########################################################################
+def getTrackToVertexTool():
+    _name = sPrefix + 'TrackToVertexTool'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from TrackToVertex.TrackToVertexConf import Reco__TrackToVertex
+    TrackToVertexTool = Reco__TrackToVertex( name = _name,
+                                             Extrapolator = getAtlasExtrapolator())
+                                             
+    from AthenaCommon.AppMgr import ToolSvc
+    ToolSvc += TrackToVertexTool
+    
+    cached_instances[_name] = TrackToVertexTool
+    return TrackToVertexTool
+
+########################################################################
+# Tau-Track Association
+def getTauTrackFinder():
+    _name = sPrefix + 'TauTrackFinder'
+    
+    if _name in cached_instances:
+        return cached_instances[_name] 
+    
+    from tauRec.tauRecConf import TauTrackFinder
+    TauTrackFinder = TauTrackFinder(name = _name,
+                                    MaxJetDrTau = 0.2,
+                                    MaxJetDrWide          = 0.4,
+                                    TrackSelectorToolTau  = getInDetTrackSelectorTool(),
+                                    TrackParticleContainer    = _DefaultTrackContainer,
+                                    TrackToVertexTool         = getTrackToVertexTool(),
+                                    TTCExtrapolator = getExtrapolateToCaloTool()                                    
+                                    #maxDeltaZ0wrtLeadTrk = 2, #in mm
+                                    #removeTracksOutsideZ0wrtLeadTrk = True
+                                    )
+    
+    cached_instances[_name] = TauTrackFinder      
+    return TauTrackFinder
+
+########################################################################
+# TauTrackFilter
+def getTauTrackFilter():
+    _name = sPrefix + 'TauTrackFilter'
+    from tauRec.tauRecConf import TauTrackFilter
+    TauTrackFilter = TauTrackFilter(name = _name, TrackContainerName=_DefaultTrackContainer)
+    cached_instances[_name] = TauTrackFilter
+    return TauTrackFilter
+
+########################################################################
+# TauGenericPi0Cone
+def getTauGenericPi0Cone():
+    _name = sPrefix + 'TauGenericPi0Cone'
+    from tauRec.tauRecConf import TauGenericPi0Cone
+    TauGenericPi0Cone = TauGenericPi0Cone(name = _name)
+    cached_instances[_name] = TauGenericPi0Cone
+    return TauGenericPi0Cone
+
+#end
+
+""" obsolete methods
+
+########################################################################
+# Tau Origin Cell Correction Tool
+def getTauCellCorrection():
+    _name = sPrefix + 'TauCellCorrection'
+    
+    from AthenaCommon.AppMgr import ToolSvc
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+
+    from tauRec.tauRecConf import TauOriginCorrectionTool
+    TauCellCorrectionTool = TauOriginCorrectionTool(name = _name,
+            UseJVA = False,  #not using JetVertexAssociation, b/c JetRec doesn't use it too
+            UsePrimaryVertex = True,
+            UseBeamSpot = True,
+            VertexContainerKey = "PrimaryVertices")
+    
+    ToolSvc += TauCellCorrectionTool
+    cached_instances[_name] = TauCellCorrectionTool         
+    return TauCellCorrectionTool
+
+#########################################################################
+# CaloNoiseTool
+def getCaloNoiseTool():
+    _name = 'CaloNoiseTool'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from CaloTools.CaloNoiseToolDefault import CaloNoiseToolDefault
+    theCaloNoiseTool = CaloNoiseToolDefault()
+    
+    from AthenaCommon.AppMgr import ToolSvc
+    ToolSvc += theCaloNoiseTool
+    
+    cached_instances[_name] = theCaloNoiseTool
+    return theCaloNoiseTool
+
+#########################################################################
+# tau1p3p track match cells
+def getTauEflowTrackMatchCells():
+    _name = sPrefix + 'EflowTrackMatchCells'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import TauEflowTrackMatchCells
+    TauEflowTrackMatchCells = TauEflowTrackMatchCells(name = _name,
+                detRIsolCaloCut   = 0.4,
+                useNoiseSigma     = 1,
+                AbsNoiseSigma_cut = 2,
+                CaloNoiseTool     = getCaloNoiseTool(),
+                selectConeSize    = 0.45, #not used anymore
+                CellCorrection = True,
+                OriginCorrectionTool = getTauCellCorrection()) 
+    
+    cached_instances[_name] = TauEflowTrackMatchCells         
+    return TauEflowTrackMatchCells
+
+#########################################################################
+# tau1p3p AddCaloInfo
+def getTauEflowAddCaloInfo():
+    _name = sPrefix + 'EflowAddCaloInfo'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import TauEflowAddCaloInfo
+    TauEflowAddCaloInfo = TauEflowAddCaloInfo(name = _name,
+                detRCoreCaloCut     = 0.2,
+                detRIsolCaloCut     = 0.4,
+                ETCellMinCut        = 0.1*GeV,
+                ETStripMinCut       = 0.2*GeV,
+                detaStripCut        = 0.2,
+                CellCorrection = True,
+                OriginCorrectionTool = getTauCellCorrection())  
+    
+    cached_instances[_name] = TauEflowAddCaloInfo         
+    return TauEflowAddCaloInfo
+
+#########################################################################
+# tau1p3p eflow info
+def getTauEflowVariables():
+    _name = sPrefix + 'EflowVariables'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import TauEflowVariables
+    TauEflowVariables = TauEflowVariables(name = _name,
+                detRCoreCaloCut = 0.2,
+                dphiEMCLCut     = 0.0375,
+                detaEMCLCut     = 0.0375,
+                dphiEMCLFACCut  = 2,
+                detaEMCLFACCut  = 3,
+                dphiChrgEMCut   = 0.0375,
+                detaChrgEMCut   = 0.0375,
+                CaloClusterContainerName = "EMTopoForTaus", #TODO: rec.scoping<3 case??
+                RecoTopoClusterETCut     = 0.2*GeV,
+                RecoEtaCut               = 2.5,
+                TrackTopoClusPhi2Cut     = 0.0375,
+                TrackTopoClusEta1Cut     = 0.01,
+                MVisEflowCut             = 10.*GeV,
+                MTrk3PCut                = 10.*GeV,
+                ETeflow_ETcaloCut        = 10.,
+                ETeflow_ETcaloCutMin     = 0.1,
+                useEMTopoClusters        = True,
+                CellCorrection = True,
+                OriginCorrectionTool = getTauCellCorrection())
+    
+    cached_instances[_name] = TauEflowVariables         
+    return TauEflowVariables  
+    
+#####################
+# Pi0 Creator Chooser
+def getPi0CreatorChooser():
+    _name = sPrefix + 'Pi0CreatorChooser'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from AthenaCommon.AppMgr import ToolSvc
+    ToolSvc += getBonnPi0ClusterCreator()
+    ToolSvc += getCrakowPi0ClusterCreator()
+    
+    from tauRec.tauRecConf import TauPi0CreatorChooser
+    TauPi0CreatorChooser = TauPi0CreatorChooser(name = _name,
+                Tau1p3pCreatePi0ClusTool = getCrakowPi0ClusterCreator(),
+                TauCommonCreatePi0ClusTool = getBonnPi0ClusterCreator())
+    
+    cached_instances[_name] = TauPi0CreatorChooser
+    return TauPi0CreatorChooser 
+
+#########################################################################
+# Crakow Pi0/eflow algorithm
+# Cluster/Cellfinder for Pi0/Eflow algos
+def getPi0EflowCreateROI():
+    _name = sPrefix + 'TauPi0EflowCreateROI'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import TauPi0EflowCreateROI
+    TauPi0EflowCreateROI = TauPi0EflowCreateROI( name = _name,
+                detRIsolCaloCut   = 0.4,
+                detRCoreCaloCut   = 0.2,
+                useNoiseSigma     = 0,
+                AbsNoiseSigma_cut = 2,
+                removeChrgEM01    = 1,
+                removeChrgEM2     = 1,
+                detRChrgEMCut     = 0.0375,
+                # Added by SL
+                fillCellContainer = TRUE,
+                CellsOutputContainerName = "TauCells",
+                CaloNoiseTool     = getCaloNoiseTool(),
+                CaloCellMakerToolNames = ["CaloCellContainerFinalizerTool/cellfinalizerForTaus","CaloCellContainerCheckerTool/cellcheckForTaus"],
+                CellCorrection = True,
+                OriginCorrectionTool = getTauCellCorrection())   
+    
+    cached_instances[_name] = TauPi0EflowCreateROI
+    return TauPi0EflowCreateROI
+
+################
+# Pi0 Clustering
+def getCrakowPi0ClusterCreator():
+    _name = sPrefix + 'CrakowPi0ClusterCreator'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+    
+    from tauRec.tauRecConf import TauPi0CrakowClusterCreator
+    TauPi0CrakowClusterCreator = TauPi0CrakowClusterCreator( name = _name,
+                detRCoreCaloCut = 0.2,
+                CaloClusterContainerName = "EMTopoForTaus",  #TODO: rec.scoping<3 case??
+                RecoTopoClusterETCut     = 1.0*GeV,
+                RecoEtaCut               = 2.5,
+                detTrkClusMin            = 0.0375,
+                fracEM01verEM            = 0.1)
+    
+    cached_instances[_name] = TauPi0CrakowClusterCreator
+    return TauPi0CrakowClusterCreator  
+
+########################################################################
+# set track infos (charge + global track collection)
+def getTauSetTracksAndCharge():
+    _name = sPrefix + 'TauSetTracksAndCharge'
+    
+    if _name in cached_instances:
+        return cached_instances[_name] 
+    
+    from tauRec.tauRecConf import TauSetTracksAndCharge
+    TauSetTracksAndCharge = TauSetTracksAndCharge(name = _name, TrackContainer    = "TrackParticleCandidate")
+    
+    cached_instances[_name] = TauSetTracksAndCharge        
+    return TauSetTracksAndCharge
+
+"""
diff --git a/Reconstruction/tauRec/python/TauConversionAlgorithms.py b/Reconstruction/tauRec/python/TauConversionAlgorithms.py
new file mode 100644
index 0000000000000000000000000000000000000000..9212a547725dee20e613e15e4c0f83781b66f0f4
--- /dev/null
+++ b/Reconstruction/tauRec/python/TauConversionAlgorithms.py
@@ -0,0 +1,223 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+################################################################################
+##
+#@file TauConversionsAlgorithms.py
+#
+#@brief Algorithms for new ConversionFinder are configured here.
+#
+# This file contains two functions:
+#     1) getTauConversionFinderTool():
+#             Returns the TauTool which assigns the conversion tracks to taujets
+#     2) getPhotonConversionTool():
+#             Returns the TauTool which finds conversion vertices
+# Not a standalaone - meant to be used in other job options file
+#
+#
+#@author KG Tan
+#@date May 2011
+################################################################################
+
+
+from tauRec.tauRecFlags import jobproperties
+
+def getTauConversionFinderTool():
+    if jobproperties.tauRecFlags.useVertexBasedConvFinder():
+        inputConversionContainerName = "ConversionsVertex_Container"
+        minEProb = 0.04
+    else:
+        inputConversionContainerName = "ConversionsPID_Container"
+        minEProb = 0.9
+    from tauRec.tauRecConf import TauConversionFinder
+    TauConversionFinder = TauConversionFinder(
+                              ConversionCandidatesName  = inputConversionContainerName,
+                              TrackContainerName        = "InDetTrackParticles",
+                              DoNormalTracks            = True,
+                              #DoLooseTracks             = False,
+                              MinElectronProbability    = minEProb,
+                              AdjustTauCharge           = False
+                          )
+    return TauConversionFinder
+
+def getPhotonConversionTool():
+    
+    if jobproperties.tauRecFlags.useVertexBasedConvFinder():
+        from AthenaCommon.AppMgr import ToolSvc
+        
+        name = "_PhotonConversionVertex"
+
+        #Configure the extrapolator
+        from TrkExTools.AtlasExtrapolator import AtlasExtrapolator
+        theAtlasExtrapolator=AtlasExtrapolator(name = 'theAtlasExtrapolator'+name)
+        theAtlasExtrapolator.DoCaloDynamic = False # this turns off dynamic
+        ToolSvc += theAtlasExtrapolator
+
+        from TrkMagFieldTools.TrkMagFieldToolsConf import Trk__MagneticFieldTool
+        InDetMagField = Trk__MagneticFieldTool('InDetMagField'+name)
+        ToolSvc += InDetMagField
+
+        #
+        # Setup track summary tool
+        #
+        from TrkTrackSummaryTool.AtlasTrackSummaryTool import AtlasTrackSummaryTool
+        MyInDetTrackSummaryTool = AtlasTrackSummaryTool(name = "MyInDetTrackSummaryTool"+name)
+        ToolSvc += MyInDetTrackSummaryTool
+
+        from TrkVKalVrtFitter.TrkVKalVrtFitterConf import Trk__TrkVKalVrtFitter
+        InDetConversionVxFitterTool = Trk__TrkVKalVrtFitter(name                = "InDetConversionVxFitter"+name,
+                                                            Extrapolator        = theAtlasExtrapolator,
+                                                            IterationNumber     = 30,
+                                                            MakeExtendedVertex  = True,
+                                                            FirstMeasuredPoint  = True,
+                                                            MagFieldSvc         = InDetMagField,
+                                                            Robustness          = 6,
+                                                            usePhiCnst          = False,
+                                                            useThetaCnst        = False,
+                                                            FirstMeasuredPointLimit = True, 
+                                                            InputParticleMasses = [0.511,0.511],
+                                                            VertexForConstraint = [0.,0.,0.],
+                                                            CovVrtForConstraint = [0.015*0.015,0.,0.015*0.015,0.,0.,10000.*10000.])
+        ToolSvc += InDetConversionVxFitterTool 
+        print      InDetConversionVxFitterTool
+
+        # Distance of minimum approach utility
+        #
+        from TrkVertexSeedFinderUtils.TrkVertexSeedFinderUtilsConf import Trk__SeedNewtonTrkDistanceFinder
+        InDetConversionTrkDistanceFinder = Trk__SeedNewtonTrkDistanceFinder(name = 'InDetConversionTrkDistanceFinder'+name)
+        ToolSvc += InDetConversionTrkDistanceFinder 
+        print      InDetConversionTrkDistanceFinder
+
+        # Straight line propagator needed to clean-up single track conversions
+        #
+        from TrkExSlPropagator.TrkExSlPropagatorConf import Trk__StraightLinePropagator as Propagator
+        InDetConversionPropagator = Propagator(name = 'InDetConversionPropagator'+name)
+        ToolSvc += InDetConversionPropagator
+        print      InDetConversionPropagator
+
+        # Helper Tool
+        #
+        from InDetConversionFinderTools.InDetConversionFinderToolsConf import InDet__ConversionFinderUtils
+        InDetConversionHelper = InDet__ConversionFinderUtils(name = "InDetConversionFinderUtils"+name)
+        ToolSvc += InDetConversionHelper
+        print      InDetConversionHelper
+
+        # Track selector tool
+        #
+        from InDetTrackSelectorTool.InDetTrackSelectorToolConf import InDet__InDetConversionTrackSelectorTool
+        InDetConversionTrackSelector = InDet__InDetConversionTrackSelectorTool(name          = "InDetConversionTrackSelector"+name,
+                                                                            TrackSummaryTool = MyInDetTrackSummaryTool,
+                                                                            Extrapolator     = theAtlasExtrapolator, 
+                                                                            maxSiD0          = 10000.,  #50.0,
+                                                                            maxTrtD0         = 10000.,  #100.,
+                                                                            maxSiZ0          = 10000.,  #350.0,
+                                                                            maxTrtZ0         = 10000.,  #1400.,
+                                                                            minPt            = 300, #InDetNewTrackingCuts.minSecondaryPt()
+                                                                            RatioCut1        = 0.0,     #0.5,
+                                                                            RatioCut2        = 0.0,
+                                                                            RatioCut3        = 0.0)
+
+        ToolSvc += InDetConversionTrackSelector
+        print      InDetConversionTrackSelector
+
+
+        # Track pairs selector
+        #
+        from InDetConversionFinderTools.InDetConversionFinderToolsConf import InDet__TrackPairsSelector
+        InDetConversionTrackPairsSelector = InDet__TrackPairsSelector(name                     = "InDetConversionTrackPairsSelector"+name,
+                                                                    ConversionFinderHelperTool = InDetConversionHelper,
+                                                                    DistanceTool               = InDetConversionTrkDistanceFinder,
+                                                                    MaxFirstHitRadius          = 10000.,
+                                                                    MaxEta                     = [0.12,10000.,10000.],      #[0.5,1.0,0.5])
+                                                                    MaxDistBetweenTracks       = [6.6,10000.,10000.],     #[6.,80.,30.]
+                                                                    MaxInitDistance            = [10000.,10000.,10000.],
+                                                                    MinTrackAngle              = 0.)
+        ToolSvc += InDetConversionTrackPairsSelector
+        print      InDetConversionTrackPairsSelector
+
+        # Vertex point estimator
+        #
+        from InDetConversionFinderTools.InDetConversionFinderToolsConf import InDet__VertexPointEstimator
+        InDetConversionVtxPointEstimator = InDet__VertexPointEstimator(name                = "InDetConversionVtxPointEstimator"+name,
+                                                                    MaxTrkXYDiffAtVtx      = [10000.,10000.,10000.],
+                                                                    MaxTrkZDiffAtVtx       = [10000.,10000.,10000.],
+                                                                    MaxTrkXYValue          = [10000.,10000.,10000.],
+                                                                    MinArcLength           = [-10000., -10000., -10000.],
+                                                                    MaxArcLength           = [10000., 10000., 10000.],
+                                                                    MinDeltaR              = [-10000.,-10000.,-10000.],
+                                                                    MaxDeltaR              = [10000.,10000.,10000.],
+                                                                    MaxHl                  = [10000.,10000.,10000.],
+                                                                    MaxPhi                 = [0.034, 10000., 10000.]) #[0.05, 0.1, 0.1])
+        ToolSvc += InDetConversionVtxPointEstimator
+        print      InDetConversionVtxPointEstimator
+
+        # Conversion post selector
+        #
+        from InDetConversionFinderTools.InDetConversionFinderToolsConf import InDet__ConversionPostSelector
+        InDetConversionPostSelector = InDet__ConversionPostSelector(name             = "InDetConversionPostSelector"+name,
+                                                                    MaxChi2Vtx       = [10000.,10000.,10000.],              #[40.,100.,80.],
+                                                                    MaxInvariantMass = [45.,25000.,25000.],     #[60.,60.,30.],
+                                                                    MinFitMomentum   = [0.,0.,0.],                 #[2000.,2000.,2000.],
+                                                                    MinRadius        = [23.4,-10000.,-10000.],  #[30.,35.,250.],
+                                                                    MinPt            = 0.,
+                                                                    MaxdR            = 10000.,                    #-250.,
+                                                                    MaxPhiVtxTrk     = 0.046)  #0.2)
+        ToolSvc += InDetConversionPostSelector
+        print      InDetConversionPostSelector
+
+        # Single track conversion tool
+        #
+        from InDetConversionFinderTools.InDetConversionFinderToolsConf import InDet__SingleTrackConversionTool
+        InDetSingleTrackConversion = InDet__SingleTrackConversionTool(name                     = "InDetSingleTrackConversionTool"+name,
+                                                                    ConversionFinderHelperTool = InDetConversionHelper,
+                                                                    TrackSummaryTool           = MyInDetTrackSummaryTool,
+                                                                    Extrapolator               = theAtlasExtrapolator,
+                                                                    MinInitialHitRadius        = 70.,
+                                                                    MinRatioOfHLhits           = 0.95)
+        ToolSvc += InDetSingleTrackConversion
+        print      InDetSingleTrackConversion
+
+        from InDetConversionFinderTools.InDetConversionFinderToolsConf import InDet__InDetConversionFinderTools
+        MyInDetConversionFinderTools = InDet__InDetConversionFinderTools(name                  = "InDetConversionFinderTools"+name,
+                                                                    VertexFitterTool           = InDetConversionVxFitterTool,
+                                                                    TrackSelectorTool          = InDetConversionTrackSelector,
+                                                                    TrackPairsSelector         = InDetConversionTrackPairsSelector,
+                                                                    ConversionFinderHelperTool = InDetConversionHelper,
+                                                                    VertexPointEstimator       = InDetConversionVtxPointEstimator,
+                                                                    PostSelector               = InDetConversionPostSelector,
+                                                                    SingleTrackConversionTool  = InDetSingleTrackConversion,
+                                                                    Extrapolator               = theAtlasExtrapolator,
+                                                                    TrackParticleCollection    = "InDetTrackParticles",
+                                                                    RemoveTrtTracks            = False,
+                                                                    IsConversion               = True)
+        ToolSvc += MyInDetConversionFinderTools
+        print      MyInDetConversionFinderTools
+
+        from tauRec.tauRecConf import PhotonConversionVertex
+        photonConv = PhotonConversionVertex(name                        = "PhotonConversionVertex",
+                                    TauRecContainer                     = "TauRecContainer",
+                                    TrackParticleContainer              = "InDetTrackParticles",
+                                    OutputConversionVertexContainerName = "ConversionsVertex_Container",
+                                    MaxTauJetDr                         = 0.5,
+                                    ConversionFinderTool                = MyInDetConversionFinderTools)
+        
+        return photonConv
+
+    else:
+        from tauRec.tauRecConf import PhotonConversionPID
+        photonConv = PhotonConversionPID(ConversionCandidatesName = "ConversionCandidate", 
+                                         ConversionOutputName = "ConversionsPID_Container",
+                                         ElectronProbability = 0.9)
+        return photonConv
+
+def getTauConversionTaggerTool():
+    if jobproperties.tauRecFlags.useNewPIDBasedConvFinder():
+        #Anything we need to do to run the tool
+        #Handled in TauRecBuilder.py
+        pass
+    else:
+        #Anything we need to do to avoid running the tool goes here
+        #Handled in TauRecBuilder.py
+        pass
+    from tauRec.tauRecConf import TauConversionTagger
+    TauConversionTagger = TauConversionTagger(ConversionTaggerVersion = 1)
+    return TauConversionTagger
diff --git a/Reconstruction/tauRec/python/TauRecAODBuilder.py b/Reconstruction/tauRec/python/TauRecAODBuilder.py
new file mode 100644
index 0000000000000000000000000000000000000000..87afc51c54f4a7e3f1b6c2fd6bdb40148661b89a
--- /dev/null
+++ b/Reconstruction/tauRec/python/TauRecAODBuilder.py
@@ -0,0 +1,119 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+################################################################################
+##
+#@file TauRecAODBuilder.py
+#
+#@brief Main steering file to rerun parts of tau reconstruction on AODs. 
+#
+# Only algorithms which don't need cell level informations can be used.
+# This is an example of how to run tauRec on AODs and should later be called by AODCalib, AODFix or TauD3PDMaker.
+# Copied from TauRecBuilder.py/TauRecBuilder::TauRecVariablesProcessor.
+#
+# Algorithms schedule here are independent from the standard tauRec chain.
+#
+#@author Felix Friedrich
+#
+################################################################################
+
+
+import os, sys, string
+
+from AthenaCommon.Logging import logging
+from AthenaCommon.SystemOfUnits import *
+from AthenaCommon.Constants import *
+from AthenaCommon.AlgSequence import AlgSequence
+import traceback
+
+from RecExConfig.Configured import Configured
+
+################################################################################
+## @class TauRecAODProcessor
+# Calculate Tau variables and properties on AODs.
+################################################################################
+class TauRecAODProcessor ( Configured ) :
+    """Calculate remaining Tau variables and properties. Use informations available also in AODs, so no cell level is needed."""
+    
+    _outputType = "Analysis::TauJetContainer"
+    _outputKey = "TauRecContainer"
+    _outputDetailsType = "Analysis::TauDetailsContainer"
+    _outputDetailsKey = "TauRecDetailsContainer"
+    
+    def __init__(self, name = "TauProcessorAODTools", inAODmode=True, doBonnPi0Clus=False, msglevel=3, ignoreExistingDataObject=True, sequence = None):
+        self.name = name
+        self.doBonnPi0Clus = doBonnPi0Clus
+        self.msglevel = msglevel
+        self.AODmode = inAODmode
+        self.sequence = sequence
+        if sequence is None:
+           self.sequence = AlgSequence() 
+        Configured.__init__(self, ignoreExistingDataObject=ignoreExistingDataObject)
+    
+    
+    def configure(self):
+        mlog = logging.getLogger ('TauRecAODProcessor::configure:')
+        mlog.info('entering')
+        
+        import tauRec.TauAlgorithmsHolder as taualgs
+        
+        ########################################################################
+        # Tau Modifier Algos 
+        ########################################################################
+        try:
+            from tauRec.tauRecConf import TauProcessor
+            #TauProcessor.OutputLevel = 2
+            self._TauProcessorHandle = TauProcessor(
+                name = self.name,
+                TauContainer             = self._outputKey,
+                TauDetailsContainer      = self._outputDetailsKey,
+                runOnAOD                 = self.AODmode)
+        
+        except Exception:
+            mlog.error("could not get handle to TauProcessor")
+            print traceback.format_exc()
+            return False
+        
+        
+        tools = []
+        try:
+            taualgs.setAODmode(True)
+            ## ATTENTION ##################################################################################
+            # running these tau tools on AODs will lead to inconsistency with standard tau reconstruction
+            ###############################################################################################
+            #tools.append(taualgs.getTauVertexFinder(doUseTJVA=True)) 
+            tools.append(taualgs.getTauAxis()) ##needed to set correct variables for energy calibration
+            #tools.append(taualgs.getTauTrackFinder())
+            tools.append(taualgs.getEnergyCalibrationLC(correctEnergy=True, correctAxis=False, postfix='_onlyEnergy'))
+            
+            tools.append(taualgs.getTauVertexVariables())
+            tools.append(taualgs.getTauCommonCalcVars())
+            tools.append(taualgs.getTauSubstructure())
+            tools.append(taualgs.getEnergyCalibrationLC(correctEnergy=False, correctAxis=True, postfix='_onlyAxis'))                    
+
+            # Run the conversion tagger if flagged to do so
+            import tauRec.TauConversionAlgorithms
+            from tauRec.tauRecFlags import jobproperties
+            if jobproperties.tauRecFlags.useNewPIDBasedConvFinder():
+                tools.append(tauRec.TauConversionAlgorithms.getTauConversionTaggerTool())
+
+            # for testing purpose
+            #tools.append(taualgs.getTauTestDump())
+                        
+            self.TauProcessorHandle().Tools = tools
+        
+        except Exception:
+            mlog.error("could not append tools to TauProcessor")
+            print traceback.format_exc()
+            return False
+        
+        self.sequence += self.TauProcessorHandle()  
+        
+        return True    
+    
+    #############################################################################################
+    # Helpers
+    #############################################################################################
+    
+    def TauProcessorHandle(self):
+        return self._TauProcessorHandle
+
diff --git a/Reconstruction/tauRec/python/TauRecBuilder.py b/Reconstruction/tauRec/python/TauRecBuilder.py
new file mode 100644
index 0000000000000000000000000000000000000000..558fa7ca9a7675ad276f4b5df9ce67f9735da218
--- /dev/null
+++ b/Reconstruction/tauRec/python/TauRecBuilder.py
@@ -0,0 +1,289 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+################################################################################
+##
+#@file TauRecBuilder.py
+#
+#@brief Main steering file to set up the different tau reconstruction steps.
+#
+#@author N. Meyer
+#@author A. Kaczmarska
+#@author Felix Friedrich
+#
+################################################################################
+
+import os, sys, string
+
+from AthenaCommon.Logging import logging
+from AthenaCommon.SystemOfUnits import *
+from AthenaCommon.Constants import *
+from AthenaCommon.BeamFlags import jobproperties
+import traceback
+
+from RecExConfig.Configured import Configured
+
+# global tauRec config keys
+_outputType = "xAOD::TauJetContainer_v1"
+_outputKey = "TauRecContainer"
+_outputAuxType = "xAOD::TauJetAuxContainer_v1"
+_outputAuxKey = "TauRecContainerAux."
+_track_collection = "InDetTrackParticles"
+_jet_collection = "AntiKt4LCTopoJets"
+
+################################################################################
+## @class TauRecCoreBuilder
+# Build proper tau candidates and associate tracks, vertex and cells
+################################################################################
+class TauRecCoreBuilder ( Configured ) :
+    """Build proper tau candidates and associate tracks, vertex and cells. 
+    Calculate properties based on cell informations. 
+    Find clusters used for Pi0 identification and eflow variables.
+    PhotonConversion will be run here too.
+    """
+  
+    _output     = { _outputType:_outputKey , _outputAuxType:_outputAuxKey }
+    
+    def __init__(self, name = "TauCoreBuilder",doBonnPi0Clus=False, doTJVA=False, msglevel=3, ignoreExistingDataObject=True):
+        self.name = name
+        self.doBonnPi0Clus = doBonnPi0Clus
+        self.do_TJVA = doTJVA
+        self.msglevel = msglevel
+        Configured.__init__(self, ignoreExistingDataObject=ignoreExistingDataObject)
+
+ 
+    def configure(self):
+        mlog = logging.getLogger ('TauCoreBuilder.py::configure:')
+        mlog.info('entering')
+        
+        
+        from RecExConfig.RecFlags import rec    
+        
+        # xxx ToDo: still needed?        
+        from RecExConfig.ObjKeyStore import objKeyStore
+        objKeyStore.addManyTypesStreamESD(self._output)
+        objKeyStore.addManyTypesStreamAOD(self._output)              
+        
+        from AthenaCommon.AlgSequence import AlgSequence
+        topSequence = AlgSequence()
+        
+        import tauRec.TauAlgorithmsHolder as taualgs
+        
+        ########################################################################
+        # TauBuilder
+        # create the taus
+        try:
+            from tauRec.tauRecConf import TauBuilder 
+            self._TauBuilderHandle = TauBuilder(
+                name = self.name,
+                SeedContainer            = _jet_collection,
+                TauContainer             = _outputKey,
+                TauAuxContainer          = _outputAuxKey,
+                MaxEta = 2.5,
+                MinPt = 10.*GeV,
+                doCreateTauContainers = True)
+        except Exception:
+            mlog.error("could not get handle to TauBuilder")
+            print traceback.format_exc()
+            return False
+        
+        
+        tools = []
+        try:
+            tools.append(taualgs.getJetSeedBuilder(_jet_collection))
+            tools.append(taualgs.getTauVertexFinder(doUseTJVA=self.do_TJVA)) 
+            tools.append(taualgs.getTauAxis())
+            tools.append(taualgs.getTauTrackFinder())
+            tools.append(taualgs.getEnergyCalibrationLC(correctEnergy=True, correctAxis=False, postfix='_onlyEnergy'))
+            tools.append(taualgs.getCellVariables())
+            tools.append(taualgs.getElectronVetoVars())
+            #
+            tools.append(taualgs.getTauTrackFilter())
+            tools.append(taualgs.getTauGenericPi0Cone())
+            #
+            #tools.append(taualgs.getPi0EflowCreateROI())
+            tools.append(taualgs.getTauShotFinder()) 
+            if self.doBonnPi0Clus:
+                tools.append(taualgs.getBonnPi0ClusterFinder())
+
+            #####################################################################
+            ## Tau Conversation Finder (found no one talking here...)
+            ## TODO: talk with KG about the status of the new PhotonConversionFinder 
+            ## new PhotonConversionFinder is currently disabled (time consumption!)
+            ## old one is still in use
+            import tauRec.TauConversionAlgorithms
+            from tauRec.tauRecFlags import jobproperties
+            if jobproperties.tauRecFlags.useNewPIDBasedConvFinder():
+                #Needs to run alone
+                tools.append(tauRec.TauConversionAlgorithms.getTauConversionTaggerTool())
+            else:
+                #Need to run together, they will select either PID or vertex based on another flag
+                tools.append(tauRec.TauConversionAlgorithms.getPhotonConversionTool())
+                tools.append(tauRec.TauConversionAlgorithms.getTauConversionFinderTool())
+            
+            #tools.append(taualgs.getContainerLock())
+            self.TauBuilderHandle().Tools = tools
+            
+        except Exception:
+            mlog.error("could not append tools to TauBuilder")
+            print traceback.format_exc()
+            return False
+        
+        # run first part of Tau Builder
+        topSequence += self.TauBuilderHandle()
+        
+        return True
+        
+    # Helpers 
+    def TauBuilderHandle(self):
+        return self._TauBuilderHandle
+    
+    def outputKey(self):
+         return self._output[self._outputType]
+    
+    def outputType(self):
+         return self._outputType
+
+
+
+################################################################################
+## @class TauRecPi0EflowProcessor
+# Calculate eflow information and run the Pi0 finder algorithms
+################################################################################
+class TauRecPi0EflowProcessor ( Configured ) :
+    """Calculate eflow information and run the Pi0 finder algorithms.
+    This needs to be done in a separate step, because first special cluster and cell container have to be build.
+    """
+       
+    def __init__(self, name = "TauProcessorPi0EflowTools",doBonnPi0Clus=False, msglevel=3, ignoreExistingDataObject=True):
+        self.name = name
+        self.doBonnPi0Clus = doBonnPi0Clus
+        self.msglevel = msglevel
+        Configured.__init__(self,ignoreExistingDataObject=ignoreExistingDataObject)
+    
+    def configure(self):
+        mlog = logging.getLogger ('TauRecPi0EflowProcessor::configure:')
+        mlog.info('entering')
+        
+        
+        from AthenaCommon.AlgSequence import AlgSequence
+        topSequence = AlgSequence()
+        
+        import tauRec.TauAlgorithmsHolder as taualgs
+        
+        ########################################################################
+        # Tau Modifier Algos 
+        ########################################################################
+        try:
+            from tauRec.tauRecConf import TauProcessor
+            self._TauProcessorHandle = TauProcessor(
+                name = self.name,
+                TauContainer             = _outputKey,
+                TauAuxContainer          = _outputAuxKey,
+            )
+        except Exception:
+            mlog.error("could not get handle to TauProcessor")
+            print traceback.format_exc()
+            return False
+             
+        tools = []
+        try:
+            #tools.append(taualgs.getTauEflowTrackMatchCells())
+            #tools.append(taualgs.getTauEflowAddCaloInfo())  
+            #tools.append(taualgs.getTauEflowVariables())     
+      
+            if self.doBonnPi0Clus: tools.append(taualgs.getBonnPi0ClusterCreator())
+            
+            self.TauProcessorHandle().Tools = tools
+            
+        except Exception:
+            mlog.error("could not append tools to TauProcessor")
+            print traceback.format_exc()
+            return False   
+        
+        topSequence += self.TauProcessorHandle()  
+        
+        return True    
+    
+    # Helpers
+    def TauProcessorHandle(self):
+        return self._TauProcessorHandle
+
+
+################################################################################
+## @class TauRecVariablesProcessor
+# Calculate remaining Tau variables and properties
+################################################################################
+class TauRecVariablesProcessor ( Configured ) :
+    """Calculate remaining Tau variables and properties. 
+    Use informations available also in AODs, so no cell level is needed.
+    """
+    
+    def __init__(self, name = "TauRecVariablesProcessor", inAODmode=False, doBonnPi0Clus=False, msglevel=3, ignoreExistingDataObject=True):
+        self.name = name
+        self.doBonnPi0Clus = doBonnPi0Clus
+        self.msglevel = msglevel
+        self.AODmode = inAODmode 
+        Configured.__init__(self, ignoreExistingDataObject=ignoreExistingDataObject)
+    
+    
+    def configure(self):
+        mlog = logging.getLogger ('TauRecVariablesProcessor::configure:')
+        mlog.info('entering')
+        
+        
+        from AthenaCommon.AlgSequence import AlgSequence
+        topSequence = AlgSequence()
+        
+        import tauRec.TauAlgorithmsHolder as taualgs
+        
+        ########################################################################
+        # Tau Modifier Algos 
+        ########################################################################
+        try:
+            from tauRec.tauRecConf import TauProcessor
+            self._TauProcessorHandle = TauProcessor(
+                name = self.name,
+                TauContainer             = _outputKey,
+                TauAuxContainer          = _outputAuxKey,
+                runOnAOD                 = self.AODmode)
+        
+        except Exception:
+            mlog.error("could not get handle to TauProcessor")
+            print traceback.format_exc()
+            return False
+             
+        tools = []
+        try:
+            #tools.append(taualgs.getEnergyCalibrationEM())
+            # don't run 2nd vertex finder in case of cosmics
+            if not jobproperties.Beam.beamType()=="cosmics":
+                tools.append(taualgs.getTauVertexVariables())
+            tools.append(taualgs.getTauCommonCalcVars())
+            tools.append(taualgs.getTauSubstructure())
+            if self.doBonnPi0Clus: 
+                tools.append(taualgs.getPi0BonnScoreCalculator())
+                tools.append(taualgs.getPi0BonnSelector())
+            tools.append(taualgs.getEnergyCalibrationLC(correctEnergy=False, correctAxis=True, postfix='_onlyAxis'))
+            #
+            ## for testing purpose
+            #tools.append(taualgs.getTauTestDump())
+            #
+            ## lock tau containers -> must be the last tau tool!!
+            #tools.append(taualgs.getContainerLock())
+                        
+            self.TauProcessorHandle().Tools = tools
+        
+        except Exception:
+            mlog.error("could not append tools to TauProcessor")
+            print traceback.format_exc()
+            return False
+        
+        topSequence += self.TauProcessorHandle()  
+        
+        return True    
+    
+    # Helpers
+    def TauProcessorHandle(self):
+        return self._TauProcessorHandle
+
+#end
diff --git a/Reconstruction/tauRec/python/tauRecFlags.py b/Reconstruction/tauRec/python/tauRecFlags.py
new file mode 100644
index 0000000000000000000000000000000000000000..055b099e236a9304be83ab18f9db33ff62a5dd38
--- /dev/null
+++ b/Reconstruction/tauRec/python/tauRecFlags.py
@@ -0,0 +1,123 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+################################################################################
+##
+#@file tauRecFlags.py
+#
+#@brief define some tauRec flags 
+################################################################################
+
+#=======================================================================
+# imports
+#=======================================================================
+from AthenaCommon.JobProperties import JobProperty, JobPropertyContainer
+from AthenaCommon.JobProperties import jobproperties
+
+
+class Enabled(JobProperty):
+    """ if all tau algorithm to be enabled
+    """
+    statusOn=True
+    allowedTypes=['bool']
+    StoredValue=True
+
+class doTauRec(JobProperty):
+    """ if TauRec to be enabled
+    """
+    statusOn=True
+    allowedTypes=['bool']
+    StoredValue=True
+    def get_Value(self):
+        return self.statusOn and self.StoredValue and jobproperties.tauRecFlags.Enabled()
+
+
+class doRunTauDiscriminant(JobProperty):
+    """ switch for TauDiscriminant running
+    """
+    statusOn=True
+    allowedTypes=['bool']
+    StoredValue=True
+
+
+class useVertexBasedConvFinder(JobProperty):
+    """ switch for PhotonConversionVertex.cxx/h conversion veto
+    """
+    statusOn=True
+    allowedTypes=['bool']
+    StoredValue=False
+
+class useNewPIDBasedConvFinder(JobProperty):
+    """ switch for TauConversionTagger.cxx/h conversion veto
+    """
+    statusOn=True
+    allowedTypes=['bool']
+    StoredValue=True
+
+class doPanTau(JobProperty):
+    """ if pantau should run after tauRec
+    """
+    statusOn=True
+    allowedTypes=['bool']
+    StoredValue=True
+
+class doBonnPi0(JobProperty):
+    """ switch on new (Bonn) Pi0 Finder
+    """
+    statusOn=True
+    allowedTypes=['bool']
+    StoredValue=False
+
+class useOldVertexFitterAPI(JobProperty):
+    """ use the old (AOD-style) API of the AdaptiveVertexFitter.
+    The AdaptiveVertexFitter is used for finding the tau decay vertex (aka. secondary vertex) and called in TauVertexVariables.
+    """
+    statusOn=True
+    allowedTypes=['bool']
+    StoredValue=False
+
+
+# Defines a sub-container for the algorithm switches
+class tauRecFlags(JobPropertyContainer):
+    """ tau information """
+
+# add the tau flags container to the top container 
+jobproperties.add_Container(tauRecFlags)
+
+# I want always the following flags in the Rec container  
+_list_tau=[Enabled,doTauRec,doRunTauDiscriminant,useVertexBasedConvFinder,useNewPIDBasedConvFinder,doPanTau,doBonnPi0,useOldVertexFitterAPI]
+for j in _list_tau: 
+    jobproperties.tauRecFlags.add_JobProperty(j)
+del _list_tau
+
+
+
+#################################################
+#### AOD flags ##################################
+#                                               #
+# only for re-running tau reco on AODs          #
+# !not for normal reconstruction!               #
+#################################################
+
+class doUpdate(JobProperty):
+    """ update the tau containers (if running in AODmode)
+    """
+    statusOn=True
+    allowedTypes=['bool']
+    StoredValue=False
+
+class tauRecAODFlags(JobPropertyContainer):
+    """ tau information if re-running on AODs """
+
+# add the tau flags container to the top container 
+jobproperties.add_Container(tauRecAODFlags)
+
+# I want always the following flags in the Rec container  
+_list_tau=[doUpdate]
+for j in _list_tau: 
+    jobproperties.tauRecAODFlags.add_JobProperty(j)
+del _list_tau
+
+
+
+#=======================================================================
+    
diff --git a/Reconstruction/tauRec/python/tauTrackSlimmer.py b/Reconstruction/tauRec/python/tauTrackSlimmer.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b357ff9407524a81289a0997c0f9a928bc7a651
--- /dev/null
+++ b/Reconstruction/tauRec/python/tauTrackSlimmer.py
@@ -0,0 +1,90 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# 
+# AUTHOR: A.Kaczmarska (using egamma example)
+# CREATED: July 12 2007
+#
+
+from AthenaCommon.Logging import logging
+from AthenaCommon.SystemOfUnits import *
+from AthenaCommon.Constants import *
+import traceback
+import EventKernel.ParticleDataType
+
+from RecExConfig.Configured import Configured
+
+from AthenaCommon.AppMgr import ServiceMgr as svcMgr
+from AthenaServices.Configurables import ThinningSvc
+if not hasattr(svcMgr, 'ThinningSvc'):
+  svcMgr += ThinningSvc(OutputLevel=INFO)
+svcMgr.ThinningSvc.Streams += ['StreamAOD']
+
+
+class tauTrackSlimmer ( Configured ) :
+    #_outputType = "TrackCollection"
+    #_outputKey = "Tracks"
+
+    #_output = { _outputType: _outputKey }
+
+    def configure(self):
+        mlog = logging.getLogger ('tauTrackSlimmer.py::configure:')
+        mlog.info('entering')
+    
+
+        # configure TauTrackSlimmer here:
+        try:
+            from tauRec.tauRecConf import TauTrackSlimmer
+            theTauTrackSlimmer = TauTrackSlimmer(
+                "tauTrackSlimmer",
+                TauContainer="TauRecContainer",
+                FilterTaus=True,
+                maxNTrack = 4,
+                maxCharge = 2,
+                maxEmRadius = 0.2,
+                maxIsoFrac = 0.5
+                )
+        except Exception:
+            mlog.error("could not get handle to tauTrackSlimmer")
+            print traceback.format_exc()
+            return False
+        self._TauBuilderHandle = theTauTrackSlimmer
+        
+        # take care of the slimming Tool
+        try:
+            from TrkTrackSlimmingTool.TrkTrackSlimmingToolConf import Trk__TrackSlimmingTool as ConfigurableTrackSlimmingTool
+            theTrackSlimmer=ConfigurableTrackSlimmingTool(
+                name = "tauTrackSlimmerTool",
+                KeepParameters = True,
+                KeepOutliers   = True
+                )
+        except Exception:
+            mlog.error("could not get handle to  tauTrackSlimmer")
+            print traceback.format_exc()
+            return False
+        from AthenaCommon.AppMgr import ToolSvc
+        ToolSvc+=theTrackSlimmer
+
+        #output:
+        from RecExConfig.ObjKeyStore import objKeyStore
+        # output to AOD (cluster container only!):
+        #DR objKeyStore.addStreamAOD(self.outputType(),self.outputKey())
+
+        # add to topsequence 
+        mlog.info("now adding to topSequence")
+
+        from AthenaCommon.AlgSequence import AlgSequence
+        topSequence = AlgSequence()
+        topSequence += theTauTrackSlimmer
+
+
+        return True
+
+##     def tauTrackSlimmerHandle(self):
+##         return self._tauTrackSlimmerHandle
+
+##     def outputType(self):
+##         return self._outputType
+
+##     def outputKey(self) :
+##         return self._outputKey
+    
diff --git a/Reconstruction/tauRec/share/EMTES_Fits_Oct2010.root b/Reconstruction/tauRec/share/EMTES_Fits_Oct2010.root
new file mode 100644
index 0000000000000000000000000000000000000000..ffc5088be80e7cd0204774071ae094d79119e322
Binary files /dev/null and b/Reconstruction/tauRec/share/EMTES_Fits_Oct2010.root differ
diff --git a/Reconstruction/tauRec/share/EnergyCalibrationLC2011.root b/Reconstruction/tauRec/share/EnergyCalibrationLC2011.root
new file mode 100644
index 0000000000000000000000000000000000000000..ce496c79bb2c8bbbd94c9ebe8a41b0e1747341c1
Binary files /dev/null and b/Reconstruction/tauRec/share/EnergyCalibrationLC2011.root differ
diff --git a/Reconstruction/tauRec/share/EnergyCalibrationLC2012.root b/Reconstruction/tauRec/share/EnergyCalibrationLC2012.root
new file mode 100644
index 0000000000000000000000000000000000000000..fd9fb8b7483d558448d5d8387a2d751b6c44ca7e
Binary files /dev/null and b/Reconstruction/tauRec/share/EnergyCalibrationLC2012.root differ
diff --git a/Reconstruction/tauRec/share/EnergyCalibrationLC2012_retuned.root b/Reconstruction/tauRec/share/EnergyCalibrationLC2012_retuned.root
new file mode 100644
index 0000000000000000000000000000000000000000..b0413b95b96feadfad36f4ed58cec6071fdf95ff
Binary files /dev/null and b/Reconstruction/tauRec/share/EnergyCalibrationLC2012_retuned.root differ
diff --git a/Reconstruction/tauRec/share/LCTES_Fits_May2011.root b/Reconstruction/tauRec/share/LCTES_Fits_May2011.root
new file mode 100644
index 0000000000000000000000000000000000000000..63a0d6805f4de9ebe5fe2e176b15256eac873edc
Binary files /dev/null and b/Reconstruction/tauRec/share/LCTES_Fits_May2011.root differ
diff --git a/Reconstruction/tauRec/share/Pi0ClusterMaker_Bonn_jobOptions.py b/Reconstruction/tauRec/share/Pi0ClusterMaker_Bonn_jobOptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..f49fb74a0b519687cbd449d7e2838d1fd023ba6d
--- /dev/null
+++ b/Reconstruction/tauRec/share/Pi0ClusterMaker_Bonn_jobOptions.py
@@ -0,0 +1,292 @@
+################################################################################
+##
+#@file Pi0ClusterMaker_Bonn_jobOptions.py
+#
+#@brief jobOption to create clusters for the "Bonn" Pi0 Finder.
+#
+# Use cell container created by TauRecCoreBuilder as an input.
+# Most settings copied from /Calorimeter/CaloRec/python/CaloClusterTopoGetter.py
+################################################################################
+
+from CaloUtils.CaloUtilsConf import CaloLCClassificationTool, CaloLCWeightTool, CaloLCOutOfClusterTool, CaloLCDeadMaterialTool
+
+from CaloClusterCorrection.CaloClusterCorrectionConf import CaloClusterLocalCalib
+#>> new PL May 4, 2009
+from CaloClusterCorrection.CaloClusterCorrectionConf import CaloClusterCellWeightCalib
+#<<
+
+from CaloRec.CaloRecConf import CaloTopoClusterMaker, CaloTopoClusterSplitter, CaloClusterMomentsMaker, CaloClusterMaker
+from CaloRec.CaloTopoClusterFlags import jobproperties
+from AthenaCommon.SystemOfUnits import deg, GeV, MeV
+from AthenaCommon.GlobalFlags import globalflags
+
+
+from CaloTools.CaloNoiseToolDefault import CaloNoiseToolDefault
+theCaloNoiseTool = CaloNoiseToolDefault()
+
+# configure cell weight calibration
+if jobproperties.CaloTopoClusterFlags.doCellWeightCalib():
+    from CaloClusterCorrection.CaloClusterCorrectionConf import H1WeightToolCSC12Generic
+    from CaloClusterCorrection.StandardCellWeightCalib   import H1Calibration, getCellWeightTool
+    CellWeights = CaloClusterCellWeightCalib("CellWeights")
+    # -- configure weight tool
+    finder = jobproperties.CaloTopoClusterFlags.cellWeightRefFinder.get_Value()
+    size   = jobproperties.CaloTopoClusterFlags.cellWeightRefSize.get_Value()
+    signal = jobproperties.CaloTopoClusterFlags.cellWeightRefSignal.get_Value()
+    WeightTool  = getCellWeightTool(finder,size,signal)
+    # -- connect weight tool
+    CellWeights.CellSignalWeightTool    = WeightTool
+    CellWeights                        += WeightTool
+    #-- default properties
+    CellWeights.Direction               = "AbsSignal"   #-- use absolute cell energies for eta/phi calculation 
+    CellWeights.BelowThresholdLikeAll   = True          #-- treat clusters below thresholds the same as all others
+    CellWeights.BelowThresholdDirection = "AbsSignal"   #-- alternative direction calculation for below threshold clusters,
+                                                        #   ignored if BelowThresholdLikeAll = True
+    CellWeights.EnergyThreshold         = 0.0*MeV       #-- threshold for possible change of direction calculation
+    CellWeights.IgnoreGeoWeights        = False         #-- ignore geometrical cell signal weights if True
+    
+# now configure local hadronic calibration
+if jobproperties.CaloTopoClusterFlags.doTopoClusterLocalCalib():
+    # tools used by tools
+    # EMFrac   = EMFracClusterClassificationTool("EMFrac")
+    # EMFrac.ClassificationKey   = "EMFracClassify"
+    # EMFrac.UseEMFractionSpread = False
+    # EMFrac.MaxEMFraction       = 0.5
+    # 
+    # H1Weight = H1ClusterCellWeightTool("H1Weight")
+    # H1Weight.CorrectionKey       = "H1ClusterCellWeights"
+    # H1Weight.SignalOverNoiseCut  = 2.0
+    # H1Weight.CaloNoiseTool       = theCaloNoiseTool
+    # 
+    # OOCC     = OutOfClusterCorrectionTool("OOCC")
+    # OOCC.CorrectionKey       = "OOCCorrection"
+    # 
+    # OOCCPi0  = OutOfClusterCorrectionTool("OOCCPi0")
+    # OOCCPi0.CorrectionKey    = "OOCPi0Correction"
+    
+    # tools used by tools
+    LCClassify   = CaloLCClassificationTool("LCClassify")
+    LCClassify.ClassificationKey   = "EMFracClassify"
+    LCClassify.UseSpread = False
+    LCClassify.MaxProbability = 0.5
+    LCClassify.StoreClassificationProbabilityInAOD = True
+
+    LCWeight = CaloLCWeightTool("LCWeight")
+    LCWeight.CorrectionKey       = "H1ClusterCellWeights"
+    LCWeight.SignalOverNoiseCut  = 2.0
+    LCWeight.CaloNoiseTool       = theCaloNoiseTool
+    LCWeight.UseHadProbability   = True
+
+    LCOut     = CaloLCOutOfClusterTool("LCOut")
+    LCOut.CorrectionKey       = "OOCCorrection"
+    LCOut.UseEmProbability    = False
+    LCOut.UseHadProbability   = True
+    
+    LCOutPi0  = CaloLCOutOfClusterTool("LCOutPi0")
+    LCOutPi0.CorrectionKey    = "OOCPi0Correction"
+    LCOutPi0.UseEmProbability  = True
+    LCOutPi0.UseHadProbability = False
+    
+    #DMTool   = DeadMaterialCorrectionTool2("DMTool")
+    #DMTool.HadDMCoeffKey       = "HadDMCoeff2"
+    #DMTool.SignalOverNoiseCut  = 1.0
+    #DMTool.ClusterRecoStatus   = 0
+    #DMTool.WeightModeDM        = 2 
+    #DMTool.CaloNoiseTool       = theCaloNoiseTool
+    
+    LCDeadMaterial   = CaloLCDeadMaterialTool("LCDeadMaterial")
+    LCDeadMaterial.HadDMCoeffKey       = "HadDMCoeff2"
+    LCDeadMaterial.ClusterRecoStatus   = 0
+    LCDeadMaterial.WeightModeDM        = 2 
+    LCDeadMaterial.UseHadProbability   = True
+
+    # correction tools using tools
+    LocalCalib = CaloClusterLocalCalib ("LocalCalibForTaus")
+    LocalCalib.ClusterClassificationTool     = [LCClassify]
+    #LocalCalib.ClusterRecoStatus             = [2]
+    LocalCalib.ClusterRecoStatus             = [1,2]
+    LocalCalib.LocalCalibTools               = [LCWeight]
+    
+    LocalCalib += LCClassify
+    LocalCalib += LCWeight
+
+    OOCCalib   = CaloClusterLocalCalib ("OOCCalibForTaus")
+    #OOCCalib.ClusterRecoStatus   = [2]
+    OOCCalib.ClusterRecoStatus   = [1,2]
+    OOCCalib.LocalCalibTools     = [LCOut]
+
+    OOCCalib += LCOut
+
+    OOCPi0Calib   = CaloClusterLocalCalib ("OOCPi0CalibForTaus")
+    #OOCPi0Calib.ClusterRecoStatus   = [1]
+    OOCPi0Calib.ClusterRecoStatus   = [1,2]
+    OOCPi0Calib.LocalCalibTools     = [LCOutPi0]
+
+    OOCPi0Calib += LCOutPi0
+
+    DMCalib    = CaloClusterLocalCalib ("DMCalibForTaus")
+    DMCalib.ClusterRecoStatus   = [1,2]
+    #DMCalib.LocalCalibToolNames = [DMTool.getFullName()]
+    #DMCalib += DMTool
+    DMCalib.LocalCalibTools      = [LCDeadMaterial]
+
+    DMCalib += LCDeadMaterial
+
+TopoClusterForTaus = CaloTopoClusterMaker("TauPi0TopoClusterMaker")
+
+TopoClusterForTaus.CellsName = "TauCommonPi0CellContainer"
+TopoClusterForTaus.CalorimeterNames=["LAREM"]
+TopoClusterForTaus.SeedSamplingNames = [
+    "PreSamplerB", "EMB1", "EMB2",
+    "PreSamplerE", "EME1", "EME2"
+    ]
+TopoClusterForTaus.CaloNoiseTool                     = theCaloNoiseTool
+TopoClusterForTaus.UseCaloNoiseTool                  = True
+TopoClusterForTaus.UsePileUpNoise                    = True
+TopoClusterForTaus.NeighborOption                    = "super3D"
+TopoClusterForTaus.RestrictHECIWandFCalNeighbors     = False
+TopoClusterForTaus.CellThresholdOnEorAbsEinSigma     = 0.0
+TopoClusterForTaus.NeighborThresholdOnEorAbsEinSigma = 2.0
+TopoClusterForTaus.SeedThresholdOnEorAbsEinSigma     = 4.0
+TopoClusterForTaus.SeedCutsInAbsE                    = True
+TopoClusterForTaus.ClusterEtorAbsEtCut               = 0.5*GeV
+TopoClusterForTaus.TwoGaussianNoise                  = jobproperties.CaloTopoClusterFlags.doTwoGaussianNoise()
+
+
+TopoSplitterForTaus = CaloTopoClusterSplitter("TauPi0TopoSplitter")
+# cells from the following samplings will be able to form local
+# maxima. The excluded samplings are PreSamplerB, EMB1,
+# PreSamplerE, EME1, all Tile samplings, all HEC samplings and the
+# two rear FCal samplings.
+TopoSplitterForTaus.SamplingNames = ["EMB2","EME2"]
+# cells from the following samplings will also be able to form
+# local maxima but only if they are not overlapping in eta and phi
+# with local maxima in previous samplings from the primary list.
+TopoSplitterForTaus.SecondarySamplingNames = ["EMB1","EME1"]
+TopoSplitterForTaus.ShareBorderCells = True
+TopoSplitterForTaus.RestrictHECIWandFCalNeighbors  = False
+
+TopoMomentsForTaus = CaloClusterMomentsMaker ("TauPi0TopoMoments")
+TopoMomentsForTaus.MaxAxisAngle = 30*deg
+TopoMomentsForTaus.OutputLevel = INFO
+TopoMomentsForTaus.MomentsNames = [
+    "FIRST_PHI" 
+    ,"FIRST_ETA"
+    ,"SECOND_R" 
+    ,"SECOND_LAMBDA"
+    ,"DELTA_PHI"
+    ,"DELTA_THETA"
+    ,"DELTA_ALPHA" 
+    ,"CENTER_X"
+    ,"CENTER_Y"
+    ,"CENTER_Z"
+    ,"CENTER_MAG"
+    ,"CENTER_LAMBDA"
+    ,"LATERAL"
+    ,"LONGITUDINAL"
+    ,"ENG_FRAC_EM" 
+    ,"ENG_FRAC_MAX" 
+    ,"ENG_FRAC_CORE" 
+    ,"FIRST_ENG_DENS" 
+    ,"SECOND_ENG_DENS"
+    ,"ISOLATION"
+    ]
+
+#TopoMomentsForTaus.AODMomentsNames = [ 
+#    "FIRST_ETA"
+#    ,"SECOND_R"
+#    ,"SECOND_LAMBDA"
+#    ,"DELTA_PHI"
+#    ,"DELTA_THETA"
+#    ,"CENTER_MAG"
+#    ,"CENTER_LAMBDA"
+#    ,"LATERAL"
+#    ,"LONGITUDINAL"
+#    ,"ENG_FRAC_EM"
+#    ,"ENG_FRAC_MAX"
+#    ,"ENG_FRAC_CORE"
+#    ,"FIRST_ENG_DENS"
+#    ,"SECOND_ENG_DENS"
+#    ,"ISOLATION"
+#    ]
+
+#if jobproperties.CaloTopoClusterFlags.lockTopoClusterSamplingEnergies() or jobproperties.CaloTopoClusterFlags.lockTopoClusterSamplingVariables():
+#    LockVariables = CaloClusterLockVars("LockVariables")
+#    LockVariables.FixBasicEnergy = True
+#    LockVariables.LockedSamplingVariables = []
+#    if jobproperties.CaloTopoClusterFlags.lockTopoClusterSamplingEnergies():
+#        LockVariables.LockedSamplingVariables += [
+#            "Energy", "Max_Energy"]
+#    if jobproperties.CaloTopoClusterFlags.lockTopoClusterSamplingVariables():    
+#        LockVariables.LockedSamplingVariables += [
+#            "Eta", "Phi", "Delta_Eta",
+#            "Delta_Phi", "Max_Eta", "Max_Phi"
+#            ]
+#                
+#if jobproperties.CaloTopoClusterFlags.printTopoClusters():
+#    PrintCaloCluster = CaloClusterPrinter("PrintCaloCluster")
+#    PrintCaloCluster.PrintFirstOnly = True
+#    PrintCaloCluster.PrintFrequency = 1
+#    PrintCaloCluster.EnergyUnit     = 1.0*GeV
+
+cluster_container = 'TauPi0SubtractedClusterContainer'
+CaloTopoForTausMaker = CaloClusterMaker ("TauPi0BonnSubtractedClusterMaker")
+CaloTopoForTausMaker.ClustersOutputName=cluster_container
+CaloTopoForTausMaker.ClusterMakerTools=[
+    TopoClusterForTaus.getFullName(),
+    TopoSplitterForTaus.getFullName()]
+CaloTopoForTausMaker.ClusterCorrectionTools = [
+    TopoMomentsForTaus.getFullName()]
+
+CaloTopoForTausMaker += TopoClusterForTaus
+CaloTopoForTausMaker += TopoSplitterForTaus
+CaloTopoForTausMaker += TopoMomentsForTaus
+
+#if jobproperties.CaloTopoClusterFlags.lockTopoClusterSamplingEnergies() or jobproperties.CaloTopoClusterFlags.lockTopoClusterSamplingVariables():
+#    CaloTopoForTausMaker.ClusterCorrectionTools += [
+#        LockVariables.getFullName()]
+#    CaloTopoForTausMaker += LockVariables
+
+if jobproperties.CaloTopoClusterFlags.doCellWeightCalib():
+    CaloTopoForTausMaker.ClusterCorrectionTools += [
+        CellWeights.getFullName() ]
+    CaloTopoForTausMaker += CellWeights
+    
+if jobproperties.CaloTopoClusterFlags.doTopoClusterLocalCalib():
+    CaloTopoForTausMaker.ClusterCorrectionTools += [
+        LocalCalib.getFullName(),
+        OOCCalib.getFullName(),
+        OOCPi0Calib.getFullName(),
+        DMCalib.getFullName()]
+    CaloTopoForTausMaker.KeepCorrectionToolAndContainerNames += [
+        LocalCalib.getFullName(),"CaloTopoForTausMaker"]
+    #    CaloTopoForTausMaker.KeepEachCorrection=True
+    CaloTopoForTausMaker += LocalCalib
+    CaloTopoForTausMaker += OOCCalib
+    CaloTopoForTausMaker += OOCPi0Calib
+    CaloTopoForTausMaker += DMCalib
+                                    
+#if jobproperties.CaloTopoClusterFlags.printTopoClusters():
+#    CaloTopoForTausMaker.ClusterCorrectionTools += [
+#        PrintCaloCluster.getFullName()]
+#    CaloTopoForTausMaker += PrintCaloCluster
+    
+#
+# pool/cool part
+#
+if jobproperties.CaloTopoClusterFlags.doTopoClusterLocalCalib():
+    from CaloRec import CaloClusterTopoCoolFolder
+    if globalflags.DetDescrVersion().startswith("Rome"):
+        CaloTopoForTausMaker.LocalCalibForTaus.LCClassify.MaxProbability = 0.85
+        CaloTopoForTausMaker.LocalCalibForTaus.LCClassify.UseNormalizedEnergyDensity = False 
+    else:   
+        CaloTopoForTausMaker.LocalCalibForTaus.LCClassify.MaxProbability = 0.50
+        CaloTopoForTausMaker.LocalCalibForTaus.LCClassify.UseNormalizedEnergyDensity = True
+
+#CaloCell2TopoClusterForTausMapper =   CaloCell2ClusterMapper("CaloCell2Pi0ClusterForTausMapper")
+#CaloCell2TopoClusterForTausMapper.ClustersName = cluster_container 
+#CaloCell2TopoClusterForTausMapper.MapOutputName = "CaloCell2Pi0ClusterForTaus"
+
+topSequence += CaloTopoForTausMaker
+#topSequence += CaloCell2TopoClusterForTausMapper
+
diff --git a/Reconstruction/tauRec/share/Pi0ClusterMaker_Crakow_jobOptions.py b/Reconstruction/tauRec/share/Pi0ClusterMaker_Crakow_jobOptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..d6ab9bd268f7e2bc8e9ba0ca5bc0d62a1a57b18b
--- /dev/null
+++ b/Reconstruction/tauRec/share/Pi0ClusterMaker_Crakow_jobOptions.py
@@ -0,0 +1,106 @@
+################################################################################
+##
+#@file Pi0ClusterMaker_Crakow_jobOptions.py
+#
+#@brief jobOption to create clusters for the "Crakow" Pi0 Finder.
+#
+# Use cell container created by TauRecCoreBuilder as an input.
+################################################################################
+from CaloRec.CaloRecConf import CaloTopoClusterMaker, CaloTopoClusterSplitter, CaloClusterMomentsMaker, CaloClusterMaker, CaloCell2ClusterMapper
+from CaloRec.CaloTopoClusterFlags import jobproperties
+from AthenaCommon.SystemOfUnits import deg, GeV, MeV
+from AthenaCommon.AlgSequence import AlgSequence
+from AthenaCommon.GlobalFlags import globalflags
+
+
+from CaloTools.CaloNoiseToolDefault import CaloNoiseToolDefault
+theCaloNoiseTool = CaloNoiseToolDefault()
+from AthenaCommon.AppMgr import ToolSvc
+ToolSvc += theCaloNoiseTool
+
+TopoClusterForTaus = CaloTopoClusterMaker("TopoClusterForTaus")
+
+TopoClusterForTaus.CellsNames = ["TauCells"]
+#TopoClusterForTaus.OutputLevel=2
+TopoClusterForTaus.CalorimeterNames=["LAREM"]
+TopoClusterForTaus.SeedSamplingNames = [
+	  "PreSamplerB", "EMB1", "EMB2",
+	  "PreSamplerE", "EME1", "EME2"
+          ]
+TopoClusterForTaus.CaloNoiseTool=theCaloNoiseTool
+TopoClusterForTaus.UseCaloNoiseTool=True
+TopoClusterForTaus.UsePileUpNoise=True
+TopoClusterForTaus.NeighborOption = "super3D"
+TopoClusterForTaus.RestrictHECIWandFCalNeighbors  = False
+TopoClusterForTaus.CellThresholdOnEorAbsEinSigma     =    0.0
+TopoClusterForTaus.NeighborThresholdOnEorAbsEinSigma =    2.0
+TopoClusterForTaus.SeedThresholdOnEorAbsEinSigma  =    4.0
+TopoClusterForTaus.SeedCutsInAbsE                 = True
+TopoClusterForTaus.ClusterEtorAbsEtCut            = 1*GeV
+
+
+TopoSplitterForTaus = CaloTopoClusterSplitter("TopoSplitterForTaus")
+# cells from the following samplings will be able to form local
+# maxima. The excluded samplings are PreSamplerB, EMB1,
+# PreSamplerE, EME1, all Tile samplings, all HEC samplings and the
+# two rear FCal samplings.
+#
+#TopoSplitterForTaus.OutputLevel=2
+TopoSplitterForTaus.SamplingNames = ["EMB2","EME2"]
+# cells from the following samplings will also be able to form
+# local maxima but only if they are not overlapping in eta and phi
+# with local maxima in previous samplings from the primary list.
+#
+TopoSplitterForTaus.SecondarySamplingNames = ["EMB1","EME1"]
+TopoSplitterForTaus.ShareBorderCells = True
+TopoSplitterForTaus.RestrictHECIWandFCalNeighbors  = False
+
+TopoMomentsForTaus = CaloClusterMomentsMaker ("TopoMomentsForTaus")
+TopoMomentsForTaus.MaxAxisAngle = 30*deg
+TopoMomentsForTaus.OutputLevel = INFO
+TopoMomentsForTaus.MomentsNames = [
+   "FIRST_PHI" 
+  ,"FIRST_ETA"
+  ,"SECOND_R" 
+  ,"SECOND_LAMBDA"
+  ,"DELTA_PHI"
+  ,"DELTA_THETA"
+  ,"DELTA_ALPHA" 
+  ,"CENTER_X"
+  ,"CENTER_Y"
+  ,"CENTER_Z"
+  ,"CENTER_LAMBDA"
+  ,"LATERAL"
+  ,"LONGITUDINAL"
+  ,"FIRST_ENG_DENS" 
+  ,"ENG_FRAC_EM" 
+  ,"ENG_FRAC_MAX" 
+  ,"ENG_FRAC_CORE" 
+  ,"FIRST_ENG_DENS" 
+  ,"SECOND_ENG_DENS" 
+]
+
+
+CaloTopoForTausMaker = CaloClusterMaker ("CaloTopoForTausMaker")
+CaloTopoForTausMaker.ClustersOutputName="EMTopoForTaus"
+CaloTopoForTausMaker.ClusterMakerTools=[
+    TopoClusterForTaus.getFullName(),
+    TopoSplitterForTaus.getFullName()]
+CaloTopoForTausMaker.ClusterCorrectionTools = [
+    TopoMomentsForTaus.getFullName()]
+
+CaloTopoForTausMaker += TopoClusterForTaus
+CaloTopoForTausMaker += TopoSplitterForTaus
+CaloTopoForTausMaker += TopoMomentsForTaus
+
+CaloCell2TopoClusterForTausMapper =   CaloCell2ClusterMapper("CaloCell2TopoClusterForTausMapper")
+CaloCell2TopoClusterForTausMapper.ClustersName = "EMTopoForTaus"
+CaloCell2TopoClusterForTausMapper.MapOutputName = "CaloCell2TopoClusterForTaus"
+
+
+topSequence += CaloTopoForTausMaker
+topSequence += CaloCell2TopoClusterForTausMapper
+    
+
+    
+
diff --git a/Reconstruction/tauRec/share/TauAODList.py b/Reconstruction/tauRec/share/TauAODList.py
new file mode 100644
index 0000000000000000000000000000000000000000..b6bd7ee829c72cfc83b7b2721b63fdc4f5c974d8
--- /dev/null
+++ b/Reconstruction/tauRec/share/TauAODList.py
@@ -0,0 +1,86 @@
+################################################################################
+##
+#@file TauAODList.py
+#
+#@brief List AOD output containers. 
+################################################################################
+
+#------------------------------------------------------------------------------
+# AOD output list
+#------------------------------------------------------------------------------
+TauAODList = []
+
+#------------------------------------------------------------------------------
+# Tau1P3P cell cluster
+#------------------------------------------------------------------------------
+#TauAODList += [ "CaloClusterContainer#Tau1P3PCellCluster" ]
+
+#------------------------------------------------------------------------------
+# TauRec cell cluster
+#------------------------------------------------------------------------------
+#TauAODList += [ "CaloClusterContainer#TauRecCellCluster" ]
+
+#------------------------------------------------------------------------------
+# Tau1P3P Pi0 cluster
+#------------------------------------------------------------------------------
+TauAODList += [ "xAOD::CaloClusterContainer_v1#TauPi0ClusterContainer" ]
+TauAODList += [ "xAOD::CaloClusterAuxContainer_v1#TauPi0ClusterContainerAux." ]
+
+#------------------------------------------------------------------------------
+# Tau1P3P cell EM012 cluster
+#------------------------------------------------------------------------------
+#TauAODList += [ "CaloClusterContainer#Tau1P3PCellEM012ClusterContainer" ]
+
+#------------------------------------------------------------------------------
+# Tau1P3P main containers
+#------------------------------------------------------------------------------
+#TauAODList += [ "Analysis::TauJetContainer#Tau1P3PContainer" ]
+#TauAODList += [ "Analysis::TauDetailsContainer#Tau1P3PDetailsContainer" ]
+
+#------------------------------------------------------------------------------
+# TauRec main containers
+#------------------------------------------------------------------------------
+#TauAODList += [ "Analysis::TauJetContainer#TauRecContainer" ]
+#TauAODList += [ "Analysis::TauDetailsContainer#TauRecDetailsContainer" ]
+#TauAODList += [ "Analysis::TauDetailsContainer#TauPi0CandidateDetailsContainer" ]
+
+#------------------------------------------------------------------------------
+# TauRec main xAOD containers
+#------------------------------------------------------------------------------
+TauAODList += [ "xAOD::TauJetContainer_v1#TauRecContainer" ]
+TauAODList += [ "xAOD::TauJetAuxContainer_v1#TauRecContainerAux." ]
+
+#------------------------------------------------------------------------------
+# Secondary Vertex for Tau Decay
+#------------------------------------------------------------------------------
+TauAODList += [ "xAOD::VertexContainer_v1#TauSecondaryVertexContainer" ]
+TauAODList += [ "xAOD::VertexAuxContainer_v1#TauSecondaryVertexContainerAux.-vxTrackAtVertex" ]
+
+#------------------------------------------------------------------------------
+# Shot PFOs
+#------------------------------------------------------------------------------
+TauAODList += [ "xAOD::PFOContainer_v1#TauShotPFOContainer" ]
+TauAODList += [ "xAOD::PFOAuxContainer_v1#TauShotPFOContainerAux." ]
+
+#------------------------------------------------------------------------------
+# Cell-based charged PFOs
+#------------------------------------------------------------------------------
+TauAODList += [ "xAOD::PFOContainer_v1#TauPi0ChargedPFOContainer" ]
+TauAODList += [ "xAOD::PFOAuxContainer_v1#TauPi0ChargedPFOContainerAux." ]
+
+#------------------------------------------------------------------------------
+# Cell-based neutral PFOs
+#------------------------------------------------------------------------------
+TauAODList += [ "xAOD::PFOContainer_v1#TauPi0NeutralPFOContainer" ]
+TauAODList += [ "xAOD::PFOAuxContainer_v1#TauPi0NeutralPFOContainerAux." ]
+
+#-------------------------------------------------------------------------
+# eflowObjects for tau
+#--------------------------------------------------------------------------
+#TauAODList += [ "eflowObjectContainer#eflowObjects_tauMode" ]
+TauAODList += [ "xAOD::PFOContainer_v1#neutralTauPFO_eflowRec" ]
+TauAODList += [ "xAOD::PFOAuxContainer_v1#neutralTauPFO_eflowRecAux." ]
+TauAODList += [ "xAOD::PFOContainer_v1#chargedTauPFO_eflowRec" ]
+TauAODList += [ "xAOD::PFOAuxContainer_v1#chargedTauPFO_eflowRecAux." ]
+
+
diff --git a/Reconstruction/tauRec/share/TauESDList.py b/Reconstruction/tauRec/share/TauESDList.py
new file mode 100644
index 0000000000000000000000000000000000000000..7dcca4c0e3c838e81f8613656a2eb1423f75430c
--- /dev/null
+++ b/Reconstruction/tauRec/share/TauESDList.py
@@ -0,0 +1,92 @@
+################################################################################
+##
+#@file TauESDList.py
+#
+#@brief List ESD output containers. 
+################################################################################
+
+#------------------------------------------------------------------------------
+# ESD output list
+#------------------------------------------------------------------------------
+TauESDList = []
+
+#------------------------------------------------------------------------------
+# Tau1P3P cell cluster
+#------------------------------------------------------------------------------
+TauESDList += [ "CaloClusterContainer#Tau1P3PCellCluster" ]
+TauESDList += [ "CaloCellLinkContainer#Tau1P3PCellCluster_Link" ]
+TauESDList += [ "CaloShowerContainer#Tau1P3PCellCluster_Data" ]
+
+#------------------------------------------------------------------------------
+# TauRec cell cluster
+#------------------------------------------------------------------------------
+TauESDList += [ "CaloClusterContainer#TauRecCellCluster" ]
+TauESDList += [ "CaloCellLinkContainer#TauRecCellCluster_Link" ]
+TauESDList += [ "CaloShowerContainer#TauRecCellCluster_Data" ]
+
+#------------------------------------------------------------------------------
+# Tau1P3P Pi0 cluster
+#------------------------------------------------------------------------------
+TauESDList += [ "CaloClusterContainer#TauPi0ClusterContainer" ]
+TauESDList += [ "CaloCellLinkContainer#TauPi0ClusterContainer_Link" ]
+TauESDList += [ "CaloShowerContainer#TauPi0ClusterContainer_Data" ]
+#TauESDList += [ "CaloCellContainer#TauCommonPi0CellContainer" ]  # for studies of the cell-based algorithm
+
+#------------------------------------------------------------------------------
+# Tau shot clusters
+#------------------------------------------------------------------------------
+TauESDList += [ "CaloClusterContainer#TauShotClusterContainer" ]
+TauESDList += [ "CaloCellLinkContainer#TauShotClusterContainer_Link" ]
+TauESDList += [ "CaloShowerContainer#TauShotClusterContainer_Data" ]
+
+#------------------------------------------------------------------------------
+# Shot PFOs
+#------------------------------------------------------------------------------
+TauESDList += [ "xAOD::PFOContainer_v1#TauShotPFOContainer" ]
+TauESDList += [ "xAOD::PFOAuxContainer_v1#TauShotPFOContainerAux." ]
+
+#------------------------------------------------------------------------------
+# Cell-based charged PFOs
+#------------------------------------------------------------------------------
+TauESDList += [ "xAOD::PFOContainer_v1#TauPi0ChargedPFOContainer" ]
+TauESDList += [ "xAOD::PFOAuxContainer_v1#TauPi0ChargedPFOContainerAux." ]
+
+#------------------------------------------------------------------------------
+# Cell-based neutral PFOs
+#------------------------------------------------------------------------------
+TauESDList += [ "xAOD::PFOContainer_v1#TauPi0NeutralPFOContainer" ]
+TauESDList += [ "xAOD::PFOAuxContainer_v1#TauPi0NeutralPFOContainerAux." ]
+
+#------------------------------------------------------------------------------
+# Secondary Vertex for Tau Decay
+#------------------------------------------------------------------------------
+TauESDList += [ "xAOD::VertexContainer_v1#TauSecondaryVertexContainer" ]
+TauESDList += [ "xAOD::VertexAuxContainer_v1#TauSecondaryVertexContainerAux.-vxTrackAtVertex" ]
+                                     
+#------------------------------------------------------------------------------
+# Tau1P3P cell EM012 cluster
+#------------------------------------------------------------------------------
+TauESDList += [ "CaloClusterContainer#Tau1P3PCellEM012ClusterContainer" ]
+TauESDList += [ "CaloCellLinkContainer#Tau1P3PCellEM012ClusterContainer_Link" ]
+TauESDList += [ "CaloShowerContainer#Tau1P3PCellEM012ClusterContainer_Data" ]
+                                     
+
+#------------------------------------------------------------------------------
+# Tau1P3P main containers
+#------------------------------------------------------------------------------
+TauESDList += [ "Analysis::TauJetContainer#Tau1P3PContainer" ]
+TauESDList += [ "Analysis::TauDetailsContainer#Tau1P3PDetailsContainer" ]
+TauESDList += [ "Analysis::TauDetailsContainer#Tau1P3PExtraDetailsContainer" ]
+
+#------------------------------------------------------------------------------
+# TauRec main containers
+#------------------------------------------------------------------------------
+TauESDList += [ "Analysis::TauJetContainer#TauRecContainer" ]
+TauESDList += [ "Analysis::TauDetailsContainer#TauRecDetailsContainer" ]
+TauESDList += [ "Analysis::TauDetailsContainer#TauRecExtraDetailsContainer" ]
+TauESDList += [ "Analysis::TauDetailsContainer#TauPi0CandidateDetailsContainer" ]
+
+#-------------------------------------------------------------------------
+# eflowObjects for tau
+#--------------------------------------------------------------------------
+TauESDList += [ "eflowObjectContainer#eflowObjects_tauMode" ]
diff --git a/Reconstruction/tauRec/share/tauMerged_trackslim_jobOptions.py b/Reconstruction/tauRec/share/tauMerged_trackslim_jobOptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..d1f8d7c42be27397b9957ac03f01eca802bfb663
--- /dev/null
+++ b/Reconstruction/tauRec/share/tauMerged_trackslim_jobOptions.py
@@ -0,0 +1,7 @@
+from RecExConfig.RecFlags import rec 
+if rec.ScopingLevel()<=3:
+  from ParticleBuilderOptions.AODFlags import AODFlags
+  if AODFlags.TauTrackSlimmer:
+    from tauRec.tauTrackSlimmer import tauTrackSlimmer
+    tauTrackSlimmer()
+
diff --git a/Reconstruction/tauRec/share/tauRecAOD_jobOptions.py b/Reconstruction/tauRec/share/tauRecAOD_jobOptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..ec6246dca06ed51089551463c0c078efb2127382
--- /dev/null
+++ b/Reconstruction/tauRec/share/tauRecAOD_jobOptions.py
@@ -0,0 +1,10 @@
+################################################################################
+##
+#@file tauRecAOD_jobOptions.py
+#
+#@brief jobOption to setup parts of the tau reconstruction chain to run on AODs.
+#
+#@author Felix Friedrich <felix.friedrich@cern.ch>
+################################################################################
+from tauRec.TauRecAODBuilder import TauRecAODProcessor
+TauRecAODProcessor(inAODmode=True)
\ No newline at end of file
diff --git a/Reconstruction/tauRec/share/tauRec_RTT_topOptions.py b/Reconstruction/tauRec/share/tauRec_RTT_topOptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..e0bd3f1054e781e91b4cf532a223b44d093a5721
--- /dev/null
+++ b/Reconstruction/tauRec/share/tauRec_RTT_topOptions.py
@@ -0,0 +1,62 @@
+
+DetDescrVersion="ATLAS-CSC-01-02-00"
+
+
+doESD = True # if false, all algorithms are switched off by defaults 
+###########################
+donewTracking=True
+doxKalman=True
+doiPatRec=True
+doEmCluster=True
+doCaloCluster=True
+doCaloTopoCluster=True
+
+doMoore=False
+doMuonboy=False
+doConversion=False
+doBtagging=False
+doEgamma=True
+doJetRec=True
+doTauRec=True
+doMuonIDStandAlone=False
+doMuonIDCombined=False
+doMuidLowPt=False
+doMuGirl=False
+doStaco=False
+doMuTag=False
+doTileMuID=False
+doMissingET=False
+doObjMissingET=False
+doEFlow=False
+doEFlowJet= False
+doTrigger=False
+doAtlfast=False
+############################
+doWriteESD = False
+doWriteTAG = False
+doWriteAOD = True
+doTrigger = False
+doHist = False
+doAOD = True
+doCBNT=True
+
+# number of event to process
+#EvtMax= 5 
+EvtMax=-1
+
+if not 'BTaggingFlags' in dir():
+    from BTagging.BTaggingFlags import BTaggingFlags
+    BTaggingFlags.JetFitterTag=False
+    #BTaggingFlags.OutputLevel=INFO
+
+#disable atlfast
+from ParticleBuilderOptions.AODFlags import AODFlags
+AODFlags.FastSimulation=False
+
+include ("RecExCommon/RecExCommon_flags.py")
+#DetFlags.Calo_setOff()
+DetFlags.Muon_setOff()
+
+include ("RecExCommon/RecExCommon_topOptions.py")
+#CBNT_TruthParticle.NMaxTruthParticles = 3000
+
diff --git a/Reconstruction/tauRec/share/tauRec_config.py b/Reconstruction/tauRec/share/tauRec_config.py
new file mode 100644
index 0000000000000000000000000000000000000000..1bb562aecc1ef26481ebd97f47196f3f167cadbb
--- /dev/null
+++ b/Reconstruction/tauRec/share/tauRec_config.py
@@ -0,0 +1,81 @@
+################################################################################
+##
+#@file tauRec_config.py
+#
+#@brief Main RecExCommon entry point for the tau reconstruction chain including run of tau identification algorithms.
+#
+# This file calls the dedicated main jobOptions of tauRec and TauDiscriminant. 
+# Checks make sure that detector conditions are valid to run tau reconstruction.
+# Tau identification will only be run if tau reconstruction was setup correctly.
+#
+################################################################################
+from RecExConfig.RecFlags import rec 
+from tauRec.tauRecFlags import jobproperties
+from JetRec.JetRecFlags import jobproperties
+from AthenaCommon.BeamFlags import jobproperties
+
+
+#switch off TauDiscriminant for cosmic
+if jobproperties.Beam.beamType()=="cosmics":
+    jobproperties.tauRecFlags.doRunTauDiscriminant=False
+
+#disable tau in case we run on RDO/RAW and jets are disabled as well:
+if jobproperties.tauRecFlags.doTauRec() and rec.readRDO() and not rec.doJetMissingETTag():
+    from AthenaCommon.Logging import logging
+    logTauRecConfig = logging.getLogger( 'tauRec_config' )
+    logTauRecConfig.warning("Running on RDO/RAW files but doJetMissingETTag=False. Tau reco need jets --> tau reconstruction disabled!!")
+    jobproperties.tauRecFlags.doTauRec=False
+
+
+if jobproperties.tauRecFlags.doTauRec() and ( rec.readESD() or  ( DetFlags.haveRIO.ID_on() and DetFlags.haveRIO.Calo_on() ) ) :
+    _tauFail=True
+
+    # the main tau reconstruction part
+    try:    
+        include( "tauRec/tauRec_jobOptions.py" )
+        _tauFail=False
+    except Exception:
+        treatException("Could not set up merged tauRec. Switched off !")
+         
+    if not _tauFail:  
+        # call eflowRec in tau mode now
+        if recAlgs.doEFlow():        
+            try:
+                include("eflowRec/eflowRec_config_DC14_Tau.py")
+            except Exception:
+                treatException("could not setup eflowRec")
+        
+        #jobproperties.tauRecFlags.doPanTau=False
+        # call PanTau now
+        if jobproperties.tauRecFlags.doPanTau():
+            try:
+                include("PanTauAnalysis/JobOptions_Main_PanTau.py")
+            except Exception:
+                treatException("Could not setup PanTau")
+                jobproperties.tauRecFlags.doPanTau = False
+        
+        # call TauDiscriminant
+        if jobproperties.tauRecFlags.doRunTauDiscriminant():
+            try:
+                include("TauDiscriminant/TauDiscri_jobOptions.py" )      
+            except Exception:
+                treatException("Could not set up TauDiscriminant. Switched off !")
+
+    if _tauFail and jobproperties.tauRecFlags.doTauRec():
+        jobproperties.tauRecFlags.doTauRec=False
+        del _tauFail
+else:
+    if jobproperties.tauRecFlags.doTauRec():
+        jobproperties.tauRecFlags.doTauRec=False
+
+#XXX switch this off until xAOD migration is finished
+#if rec.doWritexAOD():
+#    from AthenaCommon.AlgSequence import AlgSequence
+#    sequence = AlgSequence()
+#    # Add the tau converter algorithm:
+#    outkey = "TauRecContainer"
+#    from xAODTauCnv.xAODTauCnvConf import xAODMaker__TauJetCnvAlg
+#    tauAlg = xAODMaker__TauJetCnvAlg()
+#    #tauAlg.OutputLevel = 1
+#    sequence += tauAlg
+#    
diff --git a/Reconstruction/tauRec/share/tauRec_jobOptions.py b/Reconstruction/tauRec/share/tauRec_jobOptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ab848bf3415719201ebcc643503dc05f4b64d40
--- /dev/null
+++ b/Reconstruction/tauRec/share/tauRec_jobOptions.py
@@ -0,0 +1,41 @@
+################################################################################
+##
+#@file tauRec_jobOptions.py
+#
+#@brief Main jobOption to setup tau reconstruction chain.
+#
+#@author Felix Friedrich <felix.friedrich@cern.ch>
+################################################################################
+
+#TODO: everything needed here?
+from RecExConfig.RecFlags import rec
+from AthenaCommon.BeamFlags import jobproperties
+from AthenaCommon.GlobalFlags import globalflags
+import AthenaCommon.SystemOfUnits as Units
+from tauRec.tauRecFlags import jobproperties as taujp
+
+# use Tau Jet Vertex Association Tool
+# each Tau candidate gets its own primary vertex
+# and the tracks are selected accroding to this vertex
+_doTJVA = True
+
+# Bonn Pi0-finding algorithm
+_doBonnPi0Clus = taujp.tauRecFlags.doBonnPi0() #False by default
+_doBonnPi0Clus = True 
+
+# the TauCoreBuilder
+from tauRec.TauRecBuilder import TauRecCoreBuilder
+TauRecCoreBuilder(doBonnPi0Clus=_doBonnPi0Clus, doTJVA=_doTJVA)
+
+
+#include("tauRec/Pi0ClusterMaker_Crakow_jobOptions.py")
+if _doBonnPi0Clus:
+    include("tauRec/Pi0ClusterMaker_Bonn_jobOptions.py")
+
+from tauRec.TauRecBuilder import TauRecPi0EflowProcessor
+TauRecPi0EflowProcessor(doBonnPi0Clus=_doBonnPi0Clus)
+
+from tauRec.TauRecBuilder import TauRecVariablesProcessor
+TauRecVariablesProcessor(doBonnPi0Clus=_doBonnPi0Clus)
+
+
diff --git a/Reconstruction/tauRec/src/CaloClusterVariables.cxx b/Reconstruction/tauRec/src/CaloClusterVariables.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..736e9a40c0a90cf56485f97bf1b43f8fb2dce973
--- /dev/null
+++ b/Reconstruction/tauRec/src/CaloClusterVariables.cxx
@@ -0,0 +1,203 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "tauRec/CaloClusterVariables.h"
+#include "tauEvent/TauJet.h"
+#include "boost/foreach.hpp"
+#include "math.h"
+
+const double CaloClusterVariables::DEFAULT = -1111.;
+
+//****************************************
+// constructor
+//****************************************
+
+CaloClusterVariables::CaloClusterVariables() :
+m_numConstit((int) DEFAULT),
+m_effNumConstit_int((int) DEFAULT),
+m_effNumConstit(DEFAULT),
+m_aveRadius(DEFAULT),
+m_aveEffRadius(DEFAULT),
+m_totMass(DEFAULT),
+m_effMass(DEFAULT),
+m_totEnergy(DEFAULT),
+m_effEnergy(DEFAULT),
+m_numCells(0),
+m_doVertexCorrection(false) {
+}
+
+//*******************************************
+// update/fill the cluster based variables
+//*******************************************
+
+bool CaloClusterVariables::update(const xAOD::TauJet* pTau) {
+
+    if (!pTau) return false;
+    const xAOD::Jet* pSeed = *pTau->jetLink();
+    if(!pSeed) return false;
+
+    xAOD::JetConstituentVector::const_iterator nav_it = pSeed->getConstituents().begin();
+    xAOD::JetConstituentVector::const_iterator nav_itE = pSeed->getConstituents().end();
+    const xAOD::CaloCluster* pCluster;
+   
+    unsigned int sumCells = 0;
+
+    std::vector<xAOD::CaloVertexedCluster> constituents;
+    for (; nav_it != nav_itE; ++nav_it) {
+      pCluster = dynamic_cast<const xAOD::CaloCluster*> ( (*nav_it)->rawConstituent() );
+      if (!pCluster) continue;
+
+      // XXX moved the calculation of num cells up because later on we don't have access to the actual clusters anymore
+      sumCells += pCluster->size();
+
+      // correct cluster
+      if (pTau->vertexLink() && m_doVertexCorrection)
+        constituents.emplace_back (*pCluster, (*pTau->vertexLink())->position());
+      else
+        constituents.emplace_back (*pCluster);
+    }
+
+    this->m_numConstit = (int) constituents.size();
+
+    // Order constituents by energy
+    sort(constituents.begin(), constituents.end(), CaloClusterCompare());
+
+    //****************************************
+    // Looping over all constituents
+    //****************************************
+
+    double sum_px = 0;
+    double sum_py = 0;
+    double sum_pz = 0;
+    double sum_e = 0;
+    double sum_of_E2 = 0;
+    double sum_radii = 0;
+    CLHEP::HepLorentzVector centroid = calculateTauCentroid(this->m_numConstit, constituents);
+
+    for (const xAOD::CaloVertexedCluster& c : constituents) {
+        double energy = c.e();
+        sum_of_E2 += energy*energy;
+
+        double px = c.p4().Px();
+        double py = c.p4().Py();
+        double pz = c.p4().Pz();
+        // FF: phi is wrong in case px,py AND pz is negative when using HepLorentzVector(px,py,pz,1)
+        // because phi = atan(py/px)
+        // in trigger many clusters have negative energies/momentum
+        // negative values of px and py are only treated correctly if pz is positive.
+        // Otherwise px and py must be taken as positive values
+        // so using cluster eta/phi directly instead of creating a HLV.
+        //CLHEP::HepLorentzVector constituentHLV(px, py, pz, 1);
+        //sum_radii += centroid.deltaR(constituentHLV);
+        double dr = std::sqrt( std::pow(c.eta() - centroid.eta(),2) + std::pow(c.phi() - centroid.phi(),2));
+        sum_radii += dr;
+        sum_e += energy;
+        sum_px += px;
+        sum_py += py;
+        sum_pz += pz;
+    }
+
+    // Sum up the energy for constituents
+    this->m_totEnergy = sum_e;
+
+    // Calculate the mass of the constituents
+    if (this->m_numConstit < 2) this->m_totMass = DEFAULT;
+    else {
+        double mass2 = sum_e * sum_e - (sum_px * sum_px + sum_py * sum_py + sum_pz * sum_pz);
+        this->m_totMass = mass2 > 0 ? sqrt(mass2) : -sqrt(-mass2);
+    }
+
+    // Calculate the average radius of the constituents wrt the tau centroid
+    this->m_aveRadius = this->m_numConstit > 0 ? sum_radii / this->m_numConstit : DEFAULT;
+
+    // sum of cells for the tau candidate
+    this->m_numCells = sumCells;
+    
+    // Effective number of constituents
+    this->m_effNumConstit = sum_of_E2 > 0 ? (sum_e * sum_e) / (sum_of_E2) : DEFAULT;
+
+    this->m_effNumConstit_int = int(ceil(this->m_effNumConstit));
+
+    // A problem!
+    if (this->m_effNumConstit_int > this->m_numConstit) return false;
+
+    // Avoid segfault, happens when we try to iterate below if sum_of_E2 was 0 or negative
+    if (this->m_effNumConstit_int < 0) return false;
+
+    //****************************************
+    // Now: Looping over effective constituents
+    //****************************************
+
+    sum_px = 0;
+    sum_py = 0;
+    sum_pz = 0;
+    sum_e = 0;
+    sum_of_E2 = 0;
+    sum_radii = 0;
+    centroid = calculateTauCentroid(this->m_effNumConstit_int, constituents);
+
+    int icount = this->m_effNumConstit_int;
+    for (const xAOD::CaloVertexedCluster& c : constituents) {
+      if (icount <= 0) break;
+      --icount;
+
+        double energy = c.e();
+	//XXXchange to use tlorentzvector
+        double px = c.p4().Px();
+        double py = c.p4().Py();
+        double pz = c.p4().Pz();
+        // FF: see comment above
+        //CLHEP::HepLorentzVector constituentHLV(px, py, pz, 1);
+        //sum_radii += centroid.deltaR(constituentHLV);
+        double dr = std::sqrt( std::pow(c.eta() - centroid.eta(),2) + std::pow(c.phi() - centroid.phi(),2));
+        sum_radii += dr;
+
+        sum_e += energy;
+        sum_px += px;
+        sum_py += py;
+        sum_pz += pz;
+    }
+
+    // Sum up the energy for effective constituents
+    this->m_effEnergy = sum_e;
+
+    // Calculate the mass of the constituents
+    if (this->m_effNumConstit_int < 2) this->m_effMass = DEFAULT;
+    else {
+        double mass2 = sum_e * sum_e - (sum_px * sum_px + sum_py * sum_py + sum_pz * sum_pz);
+        this->m_effMass = mass2 > 0 ? sqrt(mass2) : -sqrt(-mass2);
+    }
+
+    // Calculate the average radius of the constituents wrt the tau centroid
+    this->m_aveEffRadius = this->m_effNumConstit_int > 0 ? sum_radii / this->m_effNumConstit_int : DEFAULT;
+
+    return true;
+}
+
+
+//*****************************************
+// Calculate the geometrical center of the
+// tau constituents
+//*****************************************
+CLHEP::HepLorentzVector CaloClusterVariables::calculateTauCentroid(int nConst, const std::vector<xAOD::CaloVertexedCluster>& constituents) {
+
+    double px = 0;
+    double py = 0;
+    double pz = 0;
+    double current_px, current_py, current_pz, modulus;
+
+    for (const xAOD::CaloVertexedCluster& c : constituents) {
+      if (nConst <= 0) break;
+      --nConst;
+        current_px = c.p4().Px();
+        current_py = c.p4().Py();
+        current_pz = c.p4().Pz();
+        modulus = sqrt(current_px * current_px + current_py * current_py + current_pz * current_pz);
+        px += current_px / modulus;
+        py += current_py / modulus;
+        pz += current_pz / modulus;
+    }
+    CLHEP::HepLorentzVector centroid(px, py, pz, 1);
+    return centroid;
+}
diff --git a/Reconstruction/tauRec/src/JetSeedBuilder.cxx b/Reconstruction/tauRec/src/JetSeedBuilder.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a9a23826f38b7a2a8d491d61de11c8846ffeee64
--- /dev/null
+++ b/Reconstruction/tauRec/src/JetSeedBuilder.cxx
@@ -0,0 +1,209 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/********************************************************************
+NAME:     JetSeedBuilder.cxx
+PACKAGE:  offline/Reconstruction/tauRec
+AUTHORS:  N. Meyer
+CREATED:  Nov 27 2007
+
+17/03/2010: AK: change to P4Helpers
+16/05/2011: FF: fix rare case if no jet_seed found at all (coverity 21744)
+  Dec 2011: FF: changes for tauRec4
+ ********************************************************************/
+
+#include "EventKernel/SignalStateHelper.h"
+#include "FourMomUtils/P4Helpers.h"
+
+#include "xAODJet/Jet.h"
+#include "xAODJet/JetContainer.h"
+
+#include "xAODTau/TauJetContainer.h"
+#include "xAODTau/TauJetAuxContainer.h"
+#include "xAODTau/TauJet.h"
+
+#include "tauRec/JetSeedBuilder.h"
+
+//-------------------------------------------------------------------------
+// Constructor
+//-------------------------------------------------------------------------
+
+JetSeedBuilder::JetSeedBuilder(const std::string& type,
+		const std::string& name,
+		const IInterface * parent) :
+		TauToolBase(type, name, parent),
+		m_jetCollectionName("AntiKt4LCTopoJets"),
+		m_maxJetdist(0.1),
+		m_minJetPt(10000.0),
+		m_switch_jets_em_scale(false) {
+	declareInterface<TauToolBase > (this);
+	declareProperty("JetCollection", m_jetCollectionName);
+	declareProperty("maxDist", m_maxJetdist);
+	declareProperty("minPt", m_minJetPt);
+	declareProperty("SwitchJetsEmScale", m_switch_jets_em_scale);
+}
+
+//-------------------------------------------------------------------------
+// Destructor
+//-------------------------------------------------------------------------
+
+JetSeedBuilder::~JetSeedBuilder() {
+}
+
+//-------------------------------------------------------------------------
+// initialize
+//-------------------------------------------------------------------------
+
+StatusCode JetSeedBuilder::initialize() {
+	return StatusCode::SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// Event Finalize
+//-------------------------------------------------------------------------
+
+StatusCode JetSeedBuilder::eventFinalize(TauCandidateData *) {
+	return StatusCode::SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// execute
+//-------------------------------------------------------------------------
+
+StatusCode JetSeedBuilder::execute(TauCandidateData * data) {
+
+	xAOD::TauJet *pTau = data->xAODTau;
+
+	if (pTau == NULL) {
+		ATH_MSG_ERROR("no candidate given");
+		return StatusCode::FAILURE;
+	}
+
+	StatusCode sc;
+
+	ATH_MSG_DEBUG("Starting execute");
+
+	bool inTrigger = false;
+	if (data->hasObject("InTrigger?")) {
+		sc = data->getObject("InTrigger?", inTrigger);
+	}
+
+	if(inTrigger)
+		ATH_MSG_DEBUG("inTrigger read properly");
+
+	const xAOD::JetContainer *pJetColl;
+
+	if (sc.isSuccess() && inTrigger) {
+		// called by Trigger
+		// retrieve JetCollection for trigger
+		ATH_MSG_DEBUG("Try to retrieve object from DataContainer");
+		//sc = data->getObject("JetCollection", pJetColl);
+		// Try a different approach: grab it directly
+		sc = true;
+		pJetColl = data->seedContainer;
+		if (sc.isFailure() || !pJetColl) {
+			ATH_MSG_DEBUG("no JetCollection for trigger available");
+			ATH_MSG_DEBUG("retrieve standard JetCollection <" << m_jetCollectionName << ">");
+			// retrieve standard jet collection
+			sc = evtStore()->retrieve(pJetColl, m_jetCollectionName);
+			if (sc.isFailure()) {
+				ATH_MSG_WARNING("no JetCollection retrieved");
+				return StatusCode::FAILURE;
+			}
+		}
+	} else {
+		// called by offline tauRec
+		// retrieve standard jet collection
+		sc = evtStore()->retrieve(pJetColl, m_jetCollectionName);
+		if (sc.isFailure()) {
+			ATH_MSG_WARNING("no JetCollection retrieved");
+			return StatusCode::FAILURE;
+		}
+	}
+
+	ATH_MSG_DEBUG("Pulling out the seed");
+
+	const xAOD::Jet* pJetSeed = data->seed;
+	if (!pJetSeed) {
+		ATH_MSG_DEBUG("seed is not a jet -> tau will not be reconstructed");
+		return StatusCode::FAILURE;
+	}
+
+	ATH_MSG_DEBUG("Seed extracted");
+	ATH_MSG_DEBUG("seed is Jet with"
+			<< " pt=" << pJetSeed->pt()
+			<< " eta=" << pJetSeed->eta()
+			<< " phi=" << pJetSeed->phi()
+	);
+
+	xAOD::TauJetContainer::iterator itTau = data->xAODTauContainer->begin();
+	xAOD::TauJetContainer::iterator itTauE = data->xAODTauContainer->end();
+
+	for (; itTau != itTauE; ++itTau) {
+		if ( (*itTau)->jetLink().isValid() ) {
+			if ( pJetSeed == ( * (*itTau)->jetLink() ) ) {
+				ATH_MSG_DEBUG("seed already used");
+				return StatusCode::FAILURE;
+			}
+		}
+	}
+
+	///XXX need to decide whether to remove this, because there's no author flag in xAOD::TauJet
+
+	//***********************************************************************
+	// set author to both-seeded because we don't want to break any analysis
+	// most of the analyses are using author==3 or author==1
+	// so setting author=3 should be safe for everybody
+	// calo seeded tau
+	// pTau->setAuthor(TauJetParameters::tauRec);
+	// // track seeded tau
+	// pTau->setAuthor(TauJetParameters::tau1P3P);
+	//***********************************************************************
+
+	//
+	// ATTENTION: direction will be overwritten later by TauAxis and TauEnergyCalibration
+	//
+	if (inTrigger && pJetSeed->e() < 0) {
+		// SL/SX trigger mode with negative jet_seed - do not set TauJet eta and phi in JetSeedBuilder
+		ATH_MSG_DEBUG("TauJet eta/phi will be set in Level2 Trigger for negative energy jet");
+
+		pTau->setDetail(xAOD::TauJetParameters::seedCalo_eta , static_cast<float>( pTau->eta() ) );
+		pTau->setDetail(xAOD::TauJetParameters::seedCalo_phi , static_cast<float>( pTau->phi() ) );
+
+		pTau->setP4(pJetSeed->pt(),pTau->eta(),pTau->phi(),0.0);
+
+	} else {
+		if (m_switch_jets_em_scale) {
+			ATH_MSG_INFO("trying to set seed jet signal state to EMSCALE, but this code has not been migrated to xAOD::Jet yet");
+			//XXX still need to look up how signal states are handled for the xAOD jets
+			// SignalStateHelper sigstateH(P4SignalState::JETEMSCALE);
+			// sigstateH.controlObject(pJetSeed);
+		}
+
+		pTau->setDetail(xAOD::TauJetParameters::seedCalo_eta , static_cast<float>( pJetSeed->eta() ) );
+		pTau->setDetail(xAOD::TauJetParameters::seedCalo_phi , static_cast<float>( pJetSeed->phi() ) );
+		if ( pJetSeed->pt() > 1e-7)
+			pTau->setP4(static_cast<float>( pJetSeed->pt() ) ,static_cast<float>( pJetSeed->eta() ) ,static_cast<float>( pJetSeed->phi() ) ,0.0 );
+		else
+			pTau->setP4(static_cast<float>( pJetSeed->pt() ) ,static_cast<float>( pJetSeed->eta() ) ,static_cast<float>( pJetSeed->phi() ) , 0.0 );
+
+		//store 4-vector of seed
+		pTau->setP4( xAOD::TauJetParameters::JetSeed, pJetSeed->pt(), pJetSeed->eta(), pJetSeed->phi(), pJetSeed->m() );
+	}
+
+	// set now the link to the jet seed
+	pTau->setJet(pJetColl, pJetSeed);
+
+	if ( pTau->jetLink().isValid() ) {
+		ATH_MSG_DEBUG("seed associated with tau is Jet with"
+				<< " pt=" << (*pTau->jetLink())->pt()
+				<< " eta=" << (*pTau->jetLink())->eta()
+				<< " phi=" << (*pTau->jetLink())->phi()
+		);
+	}
+
+	return StatusCode::SUCCESS;
+}
+
+
diff --git a/Reconstruction/tauRec/src/LockTauContainers.cxx b/Reconstruction/tauRec/src/LockTauContainers.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..528ee0bcca49852506c0a5e51e4a3c00f7cebd00
--- /dev/null
+++ b/Reconstruction/tauRec/src/LockTauContainers.cxx
@@ -0,0 +1,55 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "xAODTau/TauJetContainer.h"
+#include "xAODTau/TauJetAuxContainer.h"
+
+#include "tauRec/LockTauContainers.h"
+
+//**********************************
+// Constructor
+//**********************************
+
+LockTauContainers::LockTauContainers(
+        const std::string& type,
+        const std::string& name,
+        const IInterface* parent) :
+TauToolBase(type, name, parent) {
+    declareInterface<TauToolBase > (this);
+}
+
+
+//************************************
+// event finalize method
+//************************************
+
+StatusCode LockTauContainers::eventFinalize(TauCandidateData *data) {
+    ATH_MSG_VERBOSE("LockTauContainers::eventFinialize");
+    
+    //-------------------------------------------------------------------------
+    // Lock Containers
+    //-------------------------------------------------------------------------
+    
+    xAOD::TauJetContainer* pContainer = data->xAODTauContainer;
+    xAOD::TauJetAuxContainer *pAuxContainer = data->tauAuxContainer;
+
+    StatusCode sc;
+
+    if (pContainer)
+        sc = evtStore()->setConst(pContainer);
+    if (sc.isFailure()) {
+        ATH_MSG_ERROR("Cannot set tau container to const");
+        return StatusCode::FAILURE;
+    }
+
+    if (pAuxContainer)
+        sc = evtStore()->setConst(pAuxContainer);
+    if (sc.isFailure()) {
+        ATH_MSG_ERROR("Cannot set tau aux container to const");
+        return StatusCode::FAILURE;
+    }
+
+    ATH_MSG_VERBOSE("all tau containers are now locked");
+    return StatusCode::SUCCESS;
+}
diff --git a/Reconstruction/tauRec/src/PhotonConversionPID.cxx b/Reconstruction/tauRec/src/PhotonConversionPID.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..362c328ec64b094c4da10f867a224a9acaedbd11
--- /dev/null
+++ b/Reconstruction/tauRec/src/PhotonConversionPID.cxx
@@ -0,0 +1,151 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/********************************************************************
+NAME:     PhotonConversionPID.cxx
+PACKAGE:  offline/Reconstruction/tauRec
+AUTHORS:  Michael Boehler <michael.boehler@desy.de>
+CREATED:  November 2008
+ ********************************************************************/
+
+#include "tauRec/PhotonConversionPID.h"
+
+#include "xAODTracking/VertexContainer.h" 
+#include "TrkParticleBase/LinkToTrackParticleBase.h"
+#include "TrkTrackSummary/TrackSummary.h"
+#include "AthContainers/ConstDataVector.h"
+
+PhotonConversionPID::PhotonConversionPID(const std::string& type,
+    const std::string& name,
+    const IInterface* parent) :
+TauToolBase(type, name, parent),
+m_ownPolicy(static_cast<int> (SG::VIEW_ELEMENTS)) {
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("OwnPolicy", m_ownPolicy);
+    declareProperty("ConversionCandidatesName", m_ConversionCandidatesName = "ConversionCandidate");
+    declareProperty("ConversionOutputName", m_ConversionOutputName = "ConversionsPID_Container");
+    declareProperty("ElectronProbability", m_eProb_cut = 0.9);
+}
+
+/********************************************************************/
+PhotonConversionPID::~PhotonConversionPID() {
+}
+
+/********************************************************************/
+StatusCode PhotonConversionPID::initialize() {
+    return StatusCode::SUCCESS;
+}
+
+/********************************************************************/
+StatusCode PhotonConversionPID::finalize() {
+    return StatusCode::SUCCESS;
+}
+
+/********************************************************************/
+StatusCode PhotonConversionPID::eventFinalize(TauCandidateData* /*data*/) {
+
+    // ------------------------------------------------------------------ 
+    //               Retrieving VxCandidates (conversions)
+    // ------------------------------------------------------------------ 
+    const xAOD::VertexContainer* ConvContainer;
+    StatusCode sc = evtStore()->retrieve(ConvContainer, m_ConversionCandidatesName);
+
+    if (sc.isFailure() || !ConvContainer) {
+        ATH_MSG_DEBUG(" No VxCandidates container found in TDS !!");
+        return StatusCode::SUCCESS;
+    } else {
+        ATH_MSG_VERBOSE("Processing Conversion Container Name = " << m_ConversionCandidatesName);
+    }
+
+    ATH_MSG_DEBUG("VxContainer " << m_ConversionCandidatesName << " contains " << ConvContainer->size() << " vertices. ");
+
+
+    // ------------------------------------------------------------------------------------------------- 
+    //      Create and record the empty container VxCandidates (conversions after PID)
+    // ------------------------------------------------------------------------------------------------- 
+    ATH_MSG_DEBUG(" Recording identified conversion collection with key: " << m_ConversionOutputName);
+
+    ConstDataVector<xAOD::VertexContainer>* ConversionContainerPID = new ConstDataVector<xAOD::VertexContainer>(static_cast<SG::OwnershipPolicy> (m_ownPolicy));
+
+    sc = evtStore()->record(ConversionContainerPID, m_ConversionOutputName);
+    if (sc.isFailure()) {
+        ATH_MSG_ERROR("execute() : cannot record CaloCellContainer " << m_ConversionOutputName);
+        return sc;
+    }
+
+    // Loop over ConversionVertex Container:
+    xAOD::VertexContainer::const_iterator itr = ConvContainer->begin();
+    xAOD::VertexContainer::const_iterator itrE = ConvContainer->end();
+
+    for (; itr != itrE; ++itr) {
+
+        const xAOD::Vertex* vxcand = (*itr);
+
+        ATH_MSG_VERBOSE("Tracks at vertex: " << vxcand->nTrackParticles());
+
+        bool isTrk1_Conv = false;
+        bool isTrk2_Conv = false;
+
+        // loop over all tracks of the vertex
+        for (unsigned int i = 0; i < vxcand->nTrackParticles(); i++) {
+            /*
+            // these lines navigate from a VxCandidate to the track summary of each track at vertex
+            Trk::VxTrackAtVertex* tmpVxAtVtx = (*trklist)[i];
+            Trk::ITrackLink* trkLink = tmpVxAtVtx->trackOrParticleLink();
+            Trk::LinkToTrackParticleBase * linkToTrack_part = dynamic_cast<Trk::LinkToTrackParticleBase *> (trkLink);
+            if (!linkToTrack_part) {
+                ATH_MSG_WARNING("dynamic_cast of LinkToTrackParticleBase failed");
+                continue;
+            }
+
+            const Trk::TrackParticleBase* TP_Base = linkToTrack_part->cachedElement();
+            if (!TP_Base) {
+                ATH_MSG_WARNING("could not get TrackParticleBase from linkToTrack_part");
+                continue;
+            }
+
+            const Trk::TrackSummary* summary = TP_Base->trackSummary();
+            */
+            const xAOD::TrackParticle *track = vxcand->trackParticle(i);
+            float eProbabilityComb;
+            if (track && track->summaryValue(eProbabilityComb, xAOD::SummaryType::eProbabilityComb)) {
+                //---------------------------------------------------------------
+                // Checks ID of Conversion Candidates (eProb based on TRT PID)
+                ATH_MSG_VERBOSE("Track " << i + 1 << "  PID: " << eProbabilityComb);
+
+                if (eProbabilityComb > m_eProb_cut) {
+
+                    // both conv tracks pass PID cut (in case of double track conv)
+                    if (i == 0) {
+                        isTrk1_Conv = true;
+                    }
+                    if (i == 1 || vxcand->nTrackParticles() == 1) {
+                        isTrk2_Conv = true;
+                    }
+                }
+
+                //------------------------------------------------------------------
+                // after both tracks have been tested and passed the PID cut the 
+                // Conversions are stored in the new Conversion Container
+                if (isTrk1_Conv == true && isTrk2_Conv == true) {
+                    ATH_MSG_VERBOSE("                   Conversion accepted");
+                    ConversionContainerPID->push_back(vxcand);
+                }
+
+
+            } else {
+                // here a new track summary can be provided (not yet implemented)
+                ATH_MSG_WARNING("No Track Summary has been found! NO Photon Conversion Identification has been made!!!! ");
+            }
+
+        } // end track loop
+    } // end vertex loop
+
+    ATH_MSG_DEBUG("After ID " << ConversionContainerPID->size() << " Conversion are stored in " << m_ConversionOutputName);
+
+    return StatusCode::SUCCESS;
+}
+
+/********************************************************************/
diff --git a/Reconstruction/tauRec/src/PhotonConversionVertex.cxx b/Reconstruction/tauRec/src/PhotonConversionVertex.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..df6806e74e25756af01872e404cbf69a2aa9f614
--- /dev/null
+++ b/Reconstruction/tauRec/src/PhotonConversionVertex.cxx
@@ -0,0 +1,149 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/********************************************************************
+NAME:     PhotonConversionVertex.cxx
+PACKAGE:  offline/Reconstruction/tauRec
+AUTHORS:  KG Tan <Kong.Guan.Tan@cern.ch>
+CREATED:  May 2011
+
+This tool identifies conversion candidates in/near (definable) a
+tau decay cone by reconstructing the conversion vertices and
+applying a set of cuts optimized for tau conversions on the vertex
+parameters.
+ ********************************************************************/
+
+#include "tauRec/PhotonConversionVertex.h"
+
+#include "tauEvent/TauJetContainer.h"
+#include "xAODTracking/TrackParticleContainer.h"
+#include "xAODTracking/VertexContainer.h"
+#include "InDetRecToolInterfaces/IVertexFinder.h"
+#include "AthContainers/ConstDataVector.h"
+
+PhotonConversionVertex::PhotonConversionVertex(const std::string& type,
+    const std::string& name,
+    const IInterface* parent) :
+TauToolBase(type, name, parent),
+m_vertexFinderTool("InDet::InDetConversionFinderTools") {
+    declareInterface<TauToolBase > (this);
+    declareProperty("TauRecContainer", m_inputTauJetContainerName = "TauRecContainer");
+    declareProperty("TrackParticleContainer", m_inputTrackParticleContainerName = "InDetTrackParticles");
+    declareProperty("OutputConversionVertexContainerName", m_outputConversionVertexContainerName = "ConversionsVertex_Container");
+    declareProperty("MaxTauJetDr", m_maxTauJetDr = 0.5);
+    declareProperty("ConversionFinderTool", m_vertexFinderTool);
+}
+
+PhotonConversionVertex::~PhotonConversionVertex() {
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+StatusCode PhotonConversionVertex::initialize() {
+    // Get the VertexFinderTool
+    if (!retrieveTool(m_vertexFinderTool)) return StatusCode::FAILURE;
+
+    return StatusCode::SUCCESS;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+StatusCode PhotonConversionVertex::finalize() {
+    return StatusCode::SUCCESS;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+StatusCode PhotonConversionVertex::eventFinalize(TauCandidateData *data) {
+    // get the jet container from TauCandidateData, or the StoreGate if it can't find it
+    xAOD::TauJetContainer* tauJetCont = data->xAODTauContainer;
+    if (!tauJetCont) {
+        if (!openContainer(tauJetCont, m_inputTauJetContainerName))
+            return StatusCode::FAILURE;
+    }
+
+    // get the track particle container from StoreGate
+    const xAOD::TrackParticleContainer* trackParticleCont = 0;
+    if (!openContainer(trackParticleCont, m_inputTrackParticleContainerName)) return StatusCode::FAILURE;
+
+    // Define container to store
+    xAOD::VertexContainer* conversionCandidatesVxCont = 0;
+    xAOD::VertexAuxContainer* conversionCandidatesVxContAux = 0;
+    std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*> convContPair;
+
+    // Redo conversion over the tau seed cones, or over entire region
+    if (m_maxTauJetDr > 0.) {
+
+        if (tauJetCont->size() > 0) {
+
+            // Create a temporary TrackParticle container that contains tracks within the tau seed cones
+            ConstDataVector<xAOD::TrackParticleContainer> tempCont (SG::VIEW_ELEMENTS);
+            for (xAOD::TrackParticleContainer::const_iterator tpcItr = trackParticleCont->begin(); tpcItr != trackParticleCont->end(); ++tpcItr) {
+                double minTauDr = getMinDrTauDecay(tauJetCont, *tpcItr);
+                if (minTauDr < m_maxTauJetDr) {
+                    tempCont.push_back(*tpcItr);
+                }
+            }
+            ATH_MSG_VERBOSE("Number of tracks within tau seed cones for conversion finding: " << tempCont.size());
+
+            // Run the conversion finding algorithm over the tau seed cones
+            convContPair = m_vertexFinderTool->findVertex(tempCont.asDataVector());
+            conversionCandidatesVxCont = convContPair.first;
+            conversionCandidatesVxContAux = convContPair.second;
+        } else
+            conversionCandidatesVxCont = new xAOD::VertexContainer(); // No need to run conversion finding if no tracks are found!
+        	conversionCandidatesVxContAux = new xAOD::VertexAuxContainer(); // No need to run conversion finding if no tracks are found!
+
+    } else {
+        ATH_MSG_VERBOSE("Running over entire region! Number of tracks: " << trackParticleCont->size());
+
+        // Run the conversion finding algorithm over the entire region!
+        convContPair = m_vertexFinderTool->findVertex(trackParticleCont);
+        conversionCandidatesVxCont = convContPair.first;
+        conversionCandidatesVxContAux = convContPair.second;
+    }
+
+    // Perform the storing
+    ATH_MSG_VERBOSE("Number of conversion vertices found: " << conversionCandidatesVxCont->size());
+    conversionCandidatesVxCont->setStore( conversionCandidatesVxContAux );
+    if (!saveContainer(conversionCandidatesVxCont, m_outputConversionVertexContainerName)) return StatusCode::FAILURE;
+    if (!saveContainer(conversionCandidatesVxContAux, m_outputConversionVertexContainerName+"Aux")) return StatusCode::FAILURE;
+
+    return StatusCode::SUCCESS;
+}
+
+template <class T>
+bool PhotonConversionVertex::openContainer(T* &container, std::string containerName) {
+    StatusCode sc = evtStore()->retrieve(container, containerName);
+    if (!container || sc.isFailure())
+        ATH_MSG_FATAL("Container (" << containerName << ") not found in StoreGate");
+    return container;
+}
+
+template <class T>
+bool PhotonConversionVertex::saveContainer(T* &container, std::string containerName) {
+    StatusCode sc = evtStore()->record(container, containerName);
+    if (!container || sc.isFailure())
+        ATH_MSG_FATAL("Container (" << containerName << ") cannot be saved in StoreGate");
+    return container;
+}
+
+template <class T>
+bool PhotonConversionVertex::retrieveTool(T &tool) {
+    if (tool.retrieve().isFailure()) {
+        ATH_MSG_FATAL("Failed to retrieve tool " << tool);
+        return false;
+    } else {
+        ATH_MSG_VERBOSE("Retrieved tool " << tool);
+    }
+    return true;
+}
+
+double PhotonConversionVertex::getMinDrTauDecay(const xAOD::TauJetContainer* tauJetCont, const xAOD::TrackParticle *trackParticle) {
+    double minDR = 99999.;
+    for (xAOD::TauJetContainer::const_iterator tjcItr = tauJetCont->begin(); tjcItr != tauJetCont->end(); ++tjcItr) {
+        const xAOD::TauJet *tauJet = *tjcItr;
+        double dR = trackParticle->p4().DeltaR(tauJet->p4());
+        if (dR < minDR) minDR = dR;
+    }
+    return minDR;
+}
diff --git a/Reconstruction/tauRec/src/TauAxisSetter.cxx b/Reconstruction/tauRec/src/TauAxisSetter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..677388c61237d02b5d495948cb43ecd6665a19e7
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauAxisSetter.cxx
@@ -0,0 +1,161 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "CLHEP/Vector/LorentzVector.h"
+#include "CLHEP/Units/SystemOfUnits.h"
+#include "FourMomUtils/P4Helpers.h"
+#include "FourMom/P4EEtaPhiM.h"
+#include "JetEvent/Jet.h"
+#include "CaloEvent/CaloCluster.h"
+
+//tau
+#include "tauRec/TauCandidateData.h"
+
+#include "xAODTau/TauJetContainer.h"
+#include "xAODTau/TauJetAuxContainer.h"
+#include "xAODTau/TauJet.h"
+
+#include "CaloUtils/CaloVertexedCluster.h"
+
+#include "tauRec/TauAxisSetter.h"
+
+/********************************************************************/
+TauAxisSetter::TauAxisSetter(const std::string& type,
+        const std::string& name,
+        const IInterface* parent):
+TauToolBase(type, name, parent),
+m_clusterCone(0.2),
+m_doCellCorrection(false)
+{
+    declareInterface<TauToolBase > (this);
+    declareProperty("ClusterCone", m_clusterCone);
+    declareProperty("tauContainerKey", tauContainerKey = "TauRecContainer");
+    declareProperty("CellCorrection", m_doCellCorrection);
+}
+
+/********************************************************************/
+TauAxisSetter::~TauAxisSetter() { }
+
+/********************************************************************/
+StatusCode TauAxisSetter::initialize()
+{
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauAxisSetter::eventInitialize(TauCandidateData * /*data*/) 
+{
+    return StatusCode::SUCCESS;
+      
+}
+
+/********************************************************************/
+StatusCode TauAxisSetter::execute(TauCandidateData *data)
+{
+
+  xAOD::TauJet *pTau = data->xAODTau;
+
+    if (pTau == NULL) {
+        ATH_MSG_ERROR("no candidate given");
+        return StatusCode::FAILURE;
+    }
+
+    const xAOD::Jet* pJetSeed = (*pTau->jetLink());
+    if (!pJetSeed) {
+        ATH_MSG_WARNING("tau does not have jet seed for LC calibration");
+        return StatusCode::SUCCESS;
+    }
+
+    xAOD::JetConstituentVector::const_iterator cItr = pJetSeed->getConstituents().begin();
+    xAOD::JetConstituentVector::const_iterator cItrE = pJetSeed->getConstituents().end();
+
+    ///////////////////////////////////////////////////////////////////////////
+    //calculate barycenter
+    TLorentzVector sumAllClusterVector;
+    TLorentzVector tempClusterVector;
+    for (; cItr != cItrE; ++cItr) {
+      tempClusterVector.SetPtEtaPhiE( (*cItr)->pt(), (*cItr)->eta(), (*cItr)->phi(), (*cItr)->e() );
+
+      sumAllClusterVector += tempClusterVector;
+    }
+    TLorentzVector BaryCenter; 
+    BaryCenter.SetPtEtaPhiM(1., sumAllClusterVector.Eta(), sumAllClusterVector.Phi(), 0.);
+
+    
+    ///////////////////////////////////////////////////////////////////////////
+    // calculate detector axis
+    TLorentzVector tauDetectorAxis;
+    // count number of constituents in core cone. could be zero!
+    int nConstituents = 0;
+    for (cItr = pJetSeed->getConstituents().begin(); cItr != cItrE; ++cItr) {
+	tempClusterVector.SetPtEtaPhiE( (*cItr)->pt(), (*cItr)->eta(), (*cItr)->phi(), (*cItr)->e() );
+
+	ATH_MSG_VERBOSE("cluster in detector axis loop:" << (*cItr)->pt()<< " " << (*cItr)->eta() << " " << (*cItr)->phi()  << " " << (*cItr)->e() );
+	ATH_MSG_VERBOSE("delta R is " << BaryCenter.DeltaR(tempClusterVector) );
+
+        if (BaryCenter.DeltaR(tempClusterVector) > m_clusterCone)
+            continue;
+
+	nConstituents++;
+	tauDetectorAxis += tempClusterVector;
+    }
+    
+    if  (nConstituents == 0)
+      {
+	ATH_MSG_WARNING("this tau candidate does not have any constituent clusters! breaking off tau tool chain and not recording this candidate!");
+        return StatusCode::FAILURE;
+      }
+
+    ATH_MSG_VERBOSE("jet axis:" << (*pTau->jetLink())->pt()<< " " << (*pTau->jetLink())->eta() << " " << (*pTau->jetLink())->phi()  << " " << (*pTau->jetLink())->e() );
+    // save values for detector axis.
+    // FixMe: consider dropping these details variables as they are duplicated in the detector axis 4 vector
+    pTau->setDetail(xAOD::TauJetParameters::LC_TES_precalib , static_cast<float>( tauDetectorAxis.Pt() ) );		  
+    pTau->setDetail(xAOD::TauJetParameters::seedCalo_eta, static_cast<float>( tauDetectorAxis.Eta() ) );
+    pTau->setDetail(xAOD::TauJetParameters::seedCalo_phi, static_cast<float>( tauDetectorAxis.Phi() ) );
+    ATH_MSG_VERBOSE("detector axis:" << tauDetectorAxis.Pt()<< " " << tauDetectorAxis.Eta() << " " << tauDetectorAxis.Phi()  << " " << tauDetectorAxis.E() );
+
+    // detectorAxis (set default) 
+    pTau->setP4(tauDetectorAxis.Pt(), tauDetectorAxis.Eta(), tauDetectorAxis.Phi(), pTau->m());
+    // save detectorAxis 
+    pTau->setP4(xAOD::TauJetParameters::DetectorAxis, tauDetectorAxis.Pt(), tauDetectorAxis.Eta(), tauDetectorAxis.Phi(), tauDetectorAxis.M());
+
+    ///////////////////////////////////////////////////////////////////////////
+    // calculate tau intermediate axis (corrected for tau vertex)
+    TLorentzVector tauInterAxis;
+    
+    for (cItr = pJetSeed->getConstituents().begin(); cItr != cItrE; ++cItr) {
+      tempClusterVector.SetPtEtaPhiE( (*cItr)->pt(), (*cItr)->eta(), (*cItr)->phi(), (*cItr)->e() );
+      if (BaryCenter.DeltaR(tempClusterVector) > m_clusterCone)
+	continue;
+      
+      const xAOD::CaloCluster* cluster = dynamic_cast<const xAOD::CaloCluster*>( (*cItr)->rawConstituent() ); 
+      if (!cluster) continue;
+         
+      if (pTau->vertexLink())
+        tauInterAxis += xAOD::CaloVertexedCluster(*cluster, (*pTau->vertexLink())->position()).p4();
+      else
+        tauInterAxis += xAOD::CaloVertexedCluster(*cluster).p4();
+    }
+
+    // save values for tau intermediate axis
+    // energy will be overwritten by EnergyCalibrationLC (if correctEnergy is enabled)
+    // direction will be overwritten by EnergyCalibrationLC (if correctAxis is enabled)
+
+    // intermediate axis( set default) 
+    pTau->setP4(tauInterAxis.Pt(), tauInterAxis.Eta(), tauInterAxis.Phi(), pTau->m());
+
+    ATH_MSG_VERBOSE("tau axis:" << tauInterAxis.Pt()<< " " << tauInterAxis.Eta() << " " << tauInterAxis.Phi()  << " " << tauInterAxis.E() );
+    
+    // save intermediateAxis 
+    pTau->setP4(xAOD::TauJetParameters::IntermediateAxis, tauInterAxis.Pt(), tauInterAxis.Eta(), tauInterAxis.Phi(), tauInterAxis.M());
+
+    return StatusCode::SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Finalize
+//-----------------------------------------------------------------------------
+StatusCode TauAxisSetter::finalize()
+{
+    return StatusCode::SUCCESS;
+}
diff --git a/Reconstruction/tauRec/src/TauBuilder.cxx b/Reconstruction/tauRec/src/TauBuilder.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..bab7cd3870c2daf140cd56c1cb8e2a13bb1f3a7f
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauBuilder.cxx
@@ -0,0 +1,373 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauBuilder.cxx
+// package:     Reconstruction/tauRec
+// authors:     Srini Rajagopalan, Michael Heldmann, Lukasz Janyst,
+//              Anna Kaczmarska
+// date:        2007-02-13
+// modification: 
+//              15/04/2008 - (AK) fixing memory leak bug #35463
+//              19/05/2011 - (KG) added EndAthTools to transition between AlgTools and AthAlgTools
+//              22/05/2011 - (FF) changed to inherit from AthAlgorithm
+//              23/05/2011 - (FF) removed EndAthTools -> transition finished
+//              01/12/2011 - (FF) remove track seeded containers
+//-----------------------------------------------------------------------------
+
+#include "tauRec/TauBuilder.h"
+
+#include "xAODJet/Jet.h"
+#include "xAODJet/JetContainer.h"
+
+#include "xAODTau/TauJetContainer.h"
+#include "xAODTau/TauJetAuxContainer.h"
+#include "xAODTau/TauDefs.h"
+
+#include "GaudiKernel/ListItem.h"
+#include "tauRec/TauCandidateData.h"
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+
+TauBuilder::TauBuilder(const std::string &name,
+    ISvcLocator * pSvcLocator) :
+AthAlgorithm(name, pSvcLocator),
+m_tauContainerName("TauRecContainer"),
+m_tauAuxContainerName("TauRecContainerAux."),
+m_seedContainerName(""),
+m_maxEta(2.5),
+m_minPt(10000),
+m_doCreateTauContainers(false),
+m_tools(this) //make tools private
+{
+    declareProperty("TauContainer", m_tauContainerName);
+    declareProperty("TauAuxContainer", m_tauAuxContainerName);
+    declareProperty("SeedContainer", m_seedContainerName);
+    declareProperty("MaxEta", m_maxEta);
+    declareProperty("MinPt", m_minPt);
+    declareProperty("doCreateTauContainers", m_doCreateTauContainers);
+    declareProperty("Tools", m_tools, "List of TauToolBase tools");
+}
+
+//-----------------------------------------------------------------------------
+// Destructor
+//-----------------------------------------------------------------------------
+
+TauBuilder::~TauBuilder() {
+}
+
+//-----------------------------------------------------------------------------
+// Initializer
+//-----------------------------------------------------------------------------
+
+StatusCode TauBuilder::initialize() {
+    StatusCode sc;
+
+    //ATH_MSG_INFO("FF::TauBuilder :: initialize()");
+
+    //-------------------------------------------------------------------------
+    // No tools allocated!
+    //-------------------------------------------------------------------------
+    if (m_tools.size() == 0) {
+        ATH_MSG_ERROR("no tools given!");
+        return StatusCode::FAILURE;
+    }
+
+    //-------------------------------------------------------------------------
+    // Allocate tools
+    //-------------------------------------------------------------------------
+    ToolHandleArray<TauToolBase> ::iterator itT = m_tools.begin();
+    ToolHandleArray<TauToolBase> ::iterator itTE = m_tools.end();
+    ATH_MSG_INFO("List of tools in execution sequence:");
+    ATH_MSG_INFO("------------------------------------");
+
+    unsigned int tool_count = 0;
+
+    for (; itT != itTE; ++itT) {
+        sc = itT->retrieve();
+        if (sc.isFailure()) {
+            ATH_MSG_WARNING("Cannot find tool named <" << *itT << ">");
+        } else {
+            ++tool_count;
+            ATH_MSG_INFO((*itT)->type() << " - " << (*itT)->name());
+        }
+    }
+    ATH_MSG_INFO(" ");
+    ATH_MSG_INFO("------------------------------------");
+
+    if (tool_count == 0) {
+        ATH_MSG_ERROR("could not allocate any tool!");
+        return StatusCode::FAILURE;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    return StatusCode::SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Finalizer
+//-----------------------------------------------------------------------------
+
+StatusCode TauBuilder::finalize() {
+    return StatusCode::SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Execution
+//-----------------------------------------------------------------------------
+
+StatusCode TauBuilder::execute() {
+  //ATH_MSG_INFO("FF::TauBuilder :: execute()");
+  StatusCode sc;
+
+  TauCandidateData rTauData;
+
+  xAOD::TauJetContainer * pContainer = 0;
+  xAOD::TauJetAuxContainer* pAuxContainer = 0;
+
+
+
+    if (m_doCreateTauContainers) {        
+        //-------------------------------------------------------------------------
+        // Create and Record containers
+        //-------------------------------------------------------------------------
+
+      pContainer = new xAOD::TauJetContainer();
+      sc = evtStore()->record( pContainer, m_tauContainerName ) ;
+      if (sc.isFailure()) {
+	ATH_MSG_ERROR("Unable to record TauContainer in TDS");
+	delete pContainer;
+	return StatusCode::FAILURE;
+      }
+
+      pAuxContainer = new xAOD::TauJetAuxContainer();
+      sc = evtStore()->record( pAuxContainer, m_tauAuxContainerName ) ;
+      if (sc.isFailure()) {
+	ATH_MSG_ERROR("Unable to record TauContainer in TDS");
+	delete pContainer;
+	return StatusCode::FAILURE;
+      }
+      
+      pContainer->setStore( pAuxContainer );
+      ATH_MSG_DEBUG( "Recorded xAOD tau jets with key: "
+                      << m_tauAuxContainerName );
+
+      // pExtraDetailsContainer = new Analysis::TauDetailsContainer();
+        // sc = evtStore()->record(pExtraDetailsContainer, m_tauExtraDetailsContainerName);
+        // if (sc.isFailure()) {
+        //     ATH_MSG_ERROR("Unable to record TauDetailsContainer in TDS");
+        //     delete pExtraDetailsContainer;
+        //     return StatusCode::FAILURE;
+        // }
+
+	// pPi0CandidateDetailsContainer = new Analysis::TauDetailsContainer();
+	// sc = evtStore()->record(pPi0CandidateDetailsContainer, "TauPi0CandidateDetailsContainer");
+        // if (sc.isFailure()) {
+        //     ATH_MSG_ERROR("Unable to record TauPi0CandidateDetailsContainer in TDS");
+        //     delete pPi0CandidateDetailsContainer;
+        //     return StatusCode::FAILURE;
+        // }
+
+
+    } else {
+        //-------------------------------------------------------------------------
+        // retrieve Tau Containers from StoreGate
+        //-------------------------------------------------------------------------
+        sc = evtStore()->retrieve(pContainer, m_tauContainerName);
+        if (sc.isFailure()) {
+            ATH_MSG_FATAL("Failed to retrieve " << m_tauContainerName);
+            return StatusCode::FAILURE;
+        }
+
+        sc = evtStore()->retrieve(pAuxContainer, m_tauAuxContainerName);
+        if (sc.isFailure()) {
+            ATH_MSG_FATAL("Failed to retrieve " << m_tauAuxContainerName);
+            return StatusCode::FAILURE;
+        }
+
+	// sc = evtStore()->retrieve(pExtraDetailsContainer, m_tauExtraDetailsContainerName);
+        // if (sc.isFailure()) {
+        //     ATH_MSG_FATAL("Failed to retrieve " << m_tauExtraDetailsContainerName);
+        //     return StatusCode::FAILURE;
+        // }
+
+        // sc = evtStore()->retrieve(pPi0CandidateDetailsContainer, "TauPi0CandidateDetailsContainer");
+        // if (sc.isFailure()) {
+        //     ATH_MSG_FATAL("Failed to retrieve " << "TauPi0CandidateDetailsContainer");
+        //     return StatusCode::FAILURE;
+        // }
+    }
+
+    // set TauCandidate properties
+    rTauData.xAODTau = 0;
+    rTauData.xAODTauContainer = pContainer;
+    rTauData.tauAuxContainer = pAuxContainer;
+    
+
+    //XXX leave this here for now until xAOD migration is completed
+    /*
+    rTauData.tauContainer = 0;
+    rTauData.detailsContainer = 0;
+    rTauData.extraDetailsContainer = 0;
+    rTauData.pi0DetailsContainer = 0;
+    rTauData.tau = 0;
+    rTauData.details = 0;
+    rTauData.extraDetails = 0;
+    rTauData.pi0Details = 0;
+    */
+    rTauData.seed = 0;
+    rTauData.seedContainer = 0;
+
+    //-------------------------------------------------------------------------
+    // Initialize tools for this event
+    //-------------------------------------------------------------------------
+    ToolHandleArray<TauToolBase> ::iterator itT = m_tools.begin();
+    ToolHandleArray<TauToolBase> ::iterator itTE = m_tools.end();
+    for (; itT != itTE; ++itT) {
+        sc = (*itT)->eventInitialize(&rTauData);
+        if (sc != StatusCode::SUCCESS)
+            return StatusCode::FAILURE;
+    }
+
+    ////////////////////////////////////////////////////////
+
+    
+    //---------------------------------------------------------------------
+    // Retrieve seed Container from TDS, return `failure' if not
+    // existing
+    //---------------------------------------------------------------------
+    const xAOD::JetContainer * pSeedContainer;
+    sc = evtStore()->retrieve(pSeedContainer, m_seedContainerName);
+    // XXX still need to fix this. Currently only handle jets
+    // const DataHandle<INavigable4MomentumCollection> pSeedContainer;
+    // sc = evtStore()->retrieve(pSeedContainer, m_seedContainerName);
+    if (sc.isFailure() || !pSeedContainer) {
+        ATH_MSG_FATAL("No seed container with key:" << m_seedContainerName);
+        return StatusCode::FAILURE;
+    }
+
+    //---------------------------------------------------------------------
+    // Loop over seeds
+    //---------------------------------------------------------------------
+    xAOD::JetContainer::const_iterator itS = pSeedContainer->begin();
+    xAOD::JetContainer::const_iterator itSE = pSeedContainer->end();
+    // XXX still need to fix this. Currently only handle jets
+    // INavigable4MomentumCollection::const_iterator itS = pSeedContainer->begin();
+    // INavigable4MomentumCollection::const_iterator itSE = pSeedContainer->end();
+
+    ATH_MSG_VERBOSE("Number of seeds in the container: " << pSeedContainer->size());
+
+    rTauData.seedContainer = pSeedContainer;
+
+    for (; itS != itSE; ++itS) {
+      const xAOD::Jet *pSeed = (*itS);
+        ATH_MSG_VERBOSE("Seeds eta:" << pSeed->eta() << ", pt:" << pSeed->pt());
+
+        if (fabs(pSeed->eta()) > m_maxEta) {
+            ATH_MSG_VERBOSE("--> Seed rejected, eta out of range!");
+            continue;
+        }
+
+        if (fabs(pSeed->pt()) < m_minPt) {
+            ATH_MSG_VERBOSE("--> Seed rejected, pt out of range!");
+            continue;
+        }
+
+        rTauData.seed = pSeed;
+
+        //-----------------------------------------------------------------
+        // Seed passed cuts --> create tau candidate
+        //-----------------------------------------------------------------
+        rTauData.xAODTau          = new xAOD::TauJet();
+        rTauData.xAODTauContainer->push_back( rTauData.xAODTau );
+
+        //-----------------------------------------------------------------
+        // Process the candidate
+        //-----------------------------------------------------------------
+        ToolHandleArray<TauToolBase>::iterator itT = m_tools.begin();
+        ToolHandleArray<TauToolBase>::iterator itTE = m_tools.end();
+
+        //-----------------------------------------------------------------
+        // Loop stops when Failure indicated by one of the tools
+        //-----------------------------------------------------------------
+        for (; itT != itTE; ++itT) {
+            ATH_MSG_VERBOSE("Invoking tool " << (*itT)->name());
+
+            sc = (*itT)->execute(&rTauData);
+
+            if (sc.isFailure())
+                break;
+        }
+
+        if (sc.isSuccess()) {
+            
+         
+            ATH_MSG_VERBOSE("The tau candidate has been registered");
+
+            //-----------------------------------------------------------------
+            // Process the candidate using endTools
+            //-----------------------------------------------------------------
+            //keep this here for future use (in case more than one seeding algo exist)
+            /*
+            ToolHandleArray<TauToolBase> ::iterator p_itET = m_endTools.begin();
+            ToolHandleArray<TauToolBase> ::iterator p_itETE = m_endTools.end();
+            for (; p_itET != p_itETE; ++p_itET) {
+                ATH_MSG_VERBOSE("Invoking endTool " << (*p_itET)->name());
+                p_sc = (*p_itET)->execute(&rTauData);
+                if (p_sc.isFailure())
+                    break;
+            }
+             */
+            //////////////////////////////////////////////////////
+
+        } else if (!sc.isSuccess()) {
+            //TODO:cleanup of EndTools not necessary??
+            //keep this here for future use (in case more than one seeding algo exist)
+            /*
+            ToolHandleArray<TauToolBase> ::iterator p_itT1 = m_tools.begin();
+            for (; p_itT1 != p_itT; ++p_itT1)
+                (*p_itT1)->cleanup(&rTauData);
+            (*p_itT1)->cleanup(&rTauData);
+             */
+	  rTauData.xAODTauContainer->pop_back();
+        } else
+	  rTauData.xAODTauContainer->pop_back();
+    }
+
+
+
+    //-------------------------------------------------------------------------
+    // Finalize tools for this event
+    //-------------------------------------------------------------------------
+    //TODO: line below necessary?
+    rTauData.xAODTau = 0;
+
+    itT = m_tools.begin();
+    itTE = m_tools.end();
+    for (; itT != itTE; ++itT) {
+        sc = (*itT)->eventFinalize(&rTauData);
+        if (sc != StatusCode::SUCCESS)
+            return StatusCode::FAILURE;
+    }
+
+    //keep this here for future use (in case more than one seeding algo exist)
+    /*
+    p_itET = m_endTools.begin();
+    p_itETE = m_endTools.end();
+    for (; p_itET != p_itETE; ++p_itET) {
+        p_sc = (*p_itET)->eventFinalize(&rTauData);
+        if (p_sc != StatusCode::SUCCESS)
+            return StatusCode::FAILURE;
+    }
+     */
+
+    ///////////////////////////////////////////////////////
+
+    // locking of containers is moved to separate tau tool
+
+    return StatusCode::SUCCESS;
+}
diff --git a/Reconstruction/tauRec/src/TauCalibrateEM.cxx b/Reconstruction/tauRec/src/TauCalibrateEM.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..dd81f02987c6ebeee775eebb47c32f49acc55316
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauCalibrateEM.cxx
@@ -0,0 +1,197 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "TFile.h"
+#include "TF1.h"
+#include "GaudiKernel/Property.h"
+#include <PathResolver/PathResolver.h>
+#include "CLHEP/Units/SystemOfUnits.h"
+#include "EventKernel/SignalStateHelper.h"
+#include "JetEvent/Jet.h"
+
+#include "xAODTau/TauJet.h"
+#include "tauRec/TauCandidateData.h"
+#include "tauRec/TauToolBase.h"
+#include "tauRec/TauCalibrateEM.h"
+
+using CLHEP::GeV;
+
+//-------------------------------------------------------------------------
+// Constructor
+//------------------------------------------------------------------------
+
+TauCalibrateEM::TauCalibrateEM(const std::string& type,
+    const std::string& name,
+    const IInterface* parent) :
+TauToolBase(type, name, parent) {
+    declareInterface<TauToolBase > (this);
+    declareProperty("response_functions_file", m_response_functions_file = "EMTES_Fits_Oct2010.root");
+}
+
+//-------------------------------------------------------------------------
+// Destructor
+//-------------------------------------------------------------------------
+
+TauCalibrateEM::~TauCalibrateEM() {
+}
+
+//-------------------------------------------------------------------------
+// initialize
+//-------------------------------------------------------------------------
+
+StatusCode TauCalibrateEM::initialize() {
+
+    std::string response_functions_path = PathResolver::find_file(m_response_functions_file, "DATAPATH");
+    TFile* f = TFile::Open(response_functions_path.c_str(), "READ");
+
+    m_f1_1p_lem = new TF1(*((TF1*) f->Get("OneP_LowEMF_Eta_All")));
+    m_f1_1p_hem_barrel = new TF1(*((TF1*) f->Get("OneP_HighEMF_Eta_0")));
+    m_f1_1p_hem_crack = new TF1(*((TF1*) f->Get("OneP_HighEMF_Eta_1")));
+    m_f1_1p_hem_endcap = new TF1(*((TF1*) f->Get("OneP_HighEMF_Eta_2")));
+    m_f1_mp_barrel = new TF1(*((TF1*) f->Get("MultiP_Eta_0")));
+    m_f1_mp_crack = new TF1(*((TF1*) f->Get("MultiP_Eta_1")));
+    m_f1_mp_endcap = new TF1(*((TF1*) f->Get("MultiP_Eta_2")));
+
+    m_min_1p_lem.first = m_f1_1p_lem->GetMinimumX(1.5, 3.0);
+    m_min_1p_lem.second = m_f1_1p_lem->Eval(m_min_1p_lem.first);
+    m_min_1p_hem_barrel.first = m_f1_1p_hem_barrel->GetMinimumX(1.5, 3.0);
+    m_min_1p_hem_barrel.second = m_f1_1p_hem_barrel->Eval(m_min_1p_hem_barrel.first);
+    m_min_1p_hem_crack.first = m_f1_1p_hem_crack->GetMinimumX(1.5, 3.0);
+    m_min_1p_hem_crack.second = m_f1_1p_hem_crack->Eval(m_min_1p_hem_crack.first);
+    m_min_1p_hem_endcap.first = m_f1_1p_hem_endcap->GetMinimumX(1.5, 3.0);
+    m_min_1p_hem_endcap.second = m_f1_1p_hem_endcap->Eval(m_min_1p_hem_endcap.first);
+    m_min_mp_barrel.first = m_f1_mp_barrel->GetMinimumX(2.0, 3.0);
+    m_min_mp_barrel.second = m_f1_mp_barrel->Eval(m_min_mp_barrel.first);
+    m_min_mp_crack.first = m_f1_mp_crack->GetMinimumX(2.0, 3.0);
+    m_min_mp_crack.second = m_f1_mp_crack->Eval(m_min_mp_crack.first);
+    m_min_mp_endcap.first = m_f1_mp_endcap->GetMinimumX(2.5, 3.5);
+    m_min_mp_endcap.second = m_f1_mp_endcap->Eval(m_min_mp_endcap.first);
+
+    f->Close();
+    return StatusCode::SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// execute
+//-------------------------------------------------------------------------
+
+StatusCode TauCalibrateEM::execute(TauCandidateData *data) {
+    xAOD::TauJet *pTau = data->xAODTau;
+
+    if (pTau == NULL) {
+        ATH_MSG_ERROR("no candidate given");
+        return StatusCode::FAILURE;
+    }
+
+    const xAOD::Jet* pJetSeed = (*pTau->jetLink());
+
+    // XXX still need to migrate to signalstate handling of xAOD::Jet
+    // SignalStateHelper sigstateH(P4SignalState::JETEMSCALE);
+    // sigstateH.controlObject(pJetSeed);
+
+    float emscale_ptEM = 0;
+    float emscale_ptHad = 0;
+    
+    if ( !pTau->detail( xAOD::TauJetParameters::etEMAtEMScale, emscale_ptEM ) ) 
+      {
+	ATH_MSG_DEBUG("retrieval of tau detail failed. not calculating new em scale pt");
+	return StatusCode::SUCCESS;
+      }
+
+    if ( !pTau->detail( xAOD::TauJetParameters::etHadAtEMScale, emscale_ptHad ) )
+      {
+	ATH_MSG_DEBUG("retrieval of tau detail failed. not calculating new em scale pt");
+	return StatusCode::SUCCESS;
+      }
+
+    double emscale_pt = emscale_ptEM + emscale_ptHad;
+    double emscale_eta = pJetSeed->eta();
+    double emfrac = (emscale_pt != 0) ? emscale_ptEM / emscale_pt : 0.;
+
+
+    ATH_MSG_DEBUG("input variables: em_pt " << emscale_pt << " eta " << emscale_eta << " ntrack " << pTau->nTracks() << " emfrac " << emfrac);
+
+    double new_pt = evaluate_new_pt(emscale_pt / GeV, fabs(emscale_eta), pTau->nTracks(), emfrac);
+
+
+    // do NOT set TauJet energy, as this will be done in tauCalibrateLC
+    //tau->setE( new_pt * GeV * cosh( tau->eta() ) );
+
+    // instead fill place holder in TauCommonDetails
+    //pDetails->setSeedCalo_etEMCalib(new_pt * GeV);
+    
+    pTau->setDetail( xAOD::TauJetParameters::EM_TES_scale, static_cast<float>( new_pt * GeV ) );
+
+    return StatusCode::SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Finalize
+//-----------------------------------------------------------------------------
+
+StatusCode TauCalibrateEM::finalize() {
+    delete m_f1_1p_lem;
+    delete m_f1_1p_hem_barrel;
+    delete m_f1_1p_hem_crack;
+    delete m_f1_1p_hem_endcap;
+    delete m_f1_mp_barrel;
+    delete m_f1_mp_crack;
+    delete m_f1_mp_endcap;
+
+    return StatusCode::SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// calculate new tau pt at EM scale
+//-----------------------------------------------------------------------------
+
+double TauCalibrateEM::evaluate_new_pt(double pt, double eta, int ntrack, double emfrac) {
+
+    if (pt <= 0)return 0;
+    double ln_pt = log(pt);
+    if (ln_pt > 8.5) return pt;
+
+    if (ntrack <= 1) {
+        // corrections for single prong taus
+
+        if (emfrac < 0.15) {
+            // corrections for low EMF      
+            if (ln_pt < m_min_1p_lem.first) return pt / m_min_1p_lem.second;
+            else return pt / m_f1_1p_lem->Eval(ln_pt);
+        } else {
+            // corrections for high EMF
+
+            if (eta < 1.3) {
+                if (ln_pt < m_min_1p_hem_barrel.first) return pt / m_min_1p_hem_barrel.second;
+                else return pt / m_f1_1p_hem_barrel->Eval(ln_pt);
+            } else if (eta < 1.6) {
+                if (ln_pt < m_min_1p_hem_crack.first) return pt / m_min_1p_hem_crack.second;
+                else return pt / m_f1_1p_hem_crack->Eval(ln_pt);
+            } else {
+                if (ln_pt < m_min_1p_hem_endcap.first) return pt / m_min_1p_hem_endcap.second;
+                else return pt / m_f1_1p_hem_endcap->Eval(ln_pt);
+            }
+        }
+
+    } else {
+        // corrections for multi-prong taus
+
+        if (eta < 1.3) {
+            if (ln_pt < m_min_mp_barrel.first) return pt / m_min_mp_barrel.second;
+            else return pt / m_f1_mp_barrel->Eval(ln_pt);
+        } else if (eta < 1.6) {
+            if (ln_pt < m_min_mp_crack.first) return pt / m_min_mp_crack.second;
+            else return pt / m_f1_mp_crack->Eval(ln_pt);
+        } else {
+            if (ln_pt < m_min_mp_endcap.first) return pt / m_min_mp_endcap.second;
+            else return pt / m_f1_mp_endcap->Eval(ln_pt);
+        }
+    }
+
+    return pt;
+}
+
+// EOF
+
+
diff --git a/Reconstruction/tauRec/src/TauCalibrateLC.cxx b/Reconstruction/tauRec/src/TauCalibrateLC.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..dc4cc3f1db3b9cd644d84a15f7f1c75a240f1a20
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauCalibrateLC.cxx
@@ -0,0 +1,265 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "PathResolver/PathResolver.h"
+#include "CLHEP/Vector/LorentzVector.h"
+#include "CLHEP/Units/SystemOfUnits.h"
+
+// root
+#include "TFile.h"
+#include "TF1.h"
+#include "TH1D.h"
+
+//tau
+#include "xAODTau/TauJet.h"
+#include "tauRec/TauCandidateData.h"
+#include "tauRec/TauCalibrateLC.h"
+
+using CLHEP::GeV;
+
+/********************************************************************/
+TauCalibrateLC::TauCalibrateLC(const std::string& type,
+    const std::string& name,
+    const IInterface* parent) :
+TauToolBase(type, name, parent),
+m_doEnergyCorr(false),
+m_doAxisCorr(false),
+m_printMissingContainerINFO(true),
+m_clusterCone(0.2)  //not used
+{
+    declareInterface<TauToolBase > (this);
+    declareProperty("tauContainerKey", tauContainerKey = "TauRecContainer");
+    declareProperty("calibrationFile", calibrationFile = "EnergyCalibrationLC2012.root");
+    declareProperty("vertexContainerKey", vertexContainerKey = "PrimaryVertices");
+    declareProperty("doEnergyCorrection", m_doEnergyCorr);
+    declareProperty("doAxisCorrection",    m_doAxisCorr);
+    declareProperty("ClusterCone", m_clusterCone); //not used
+}
+
+/********************************************************************/
+TauCalibrateLC::~TauCalibrateLC() {
+}
+
+/********************************************************************/
+StatusCode TauCalibrateLC::initialize() {
+    std::string fullPath = PathResolver::find_file(calibrationFile, "DATAPATH");
+    TFile * file = TFile::Open(fullPath.c_str(), "READ");
+
+    if (!file) {
+        ATH_MSG_FATAL("Failed to open " << fullPath);
+        return StatusCode::FAILURE;
+    }
+
+    // get the histogram defining eta binning
+    std::string key = "etaBinning";
+    TObject * obj = file->Get(key.c_str());
+    if (obj) {
+        etaBinHist = dynamic_cast<TH1 *> (obj);
+        TH1 * tmp = const_cast<TH1*> (etaBinHist);
+        tmp->SetDirectory(0);
+    } else {
+        ATH_MSG_FATAL("Failed to get an object with  key " << key);
+        return StatusCode::FAILURE;
+    }
+
+    //retrieve number of eta bins from file
+    m_nEtaBins = etaBinHist->GetNbinsX(); //member var
+    if (m_nEtaBins==6)
+        ATH_MSG_INFO("using 2011 tau energy calibration");
+    else if (m_nEtaBins==5)
+        ATH_MSG_INFO("using 2012 tau energy calibration");
+    else {
+        ATH_MSG_FATAL("Wrong or broken tau energy calibration file");
+        return StatusCode::FAILURE;
+    }
+    
+    // get the histogram with eta corrections
+    key = "etaCorrection";
+    obj = file->Get(key.c_str());
+    if (obj) {
+        etaCorrectionHist = dynamic_cast<TH1 *> (obj);
+        TH1 * tmp = const_cast<TH1*> (etaCorrectionHist);
+        tmp->SetDirectory(0);
+    } else {
+        ATH_MSG_FATAL("Failed to get an object with  key " << key);
+        return StatusCode::FAILURE;
+    }
+
+    TString tmpSlopKey[nProngBins] = {"slopeNPV1P", "slopeNPV3P"};
+    TString tmpFuncBase[nProngBins] = {"OneP_Eta_", "MultiP_Eta_"};
+
+    for (int i = 0; i < nProngBins; i++) {
+        obj = file->Get(tmpSlopKey[i]); // get pile-up slope histograms
+        if (obj) {
+            slopeNPVHist[i] = dynamic_cast<TH1 *> (obj);
+            TH1 * tmp = const_cast<TH1*> (slopeNPVHist[i]);
+            tmp->SetDirectory(0);
+        } else {
+            ATH_MSG_FATAL("Failed to get an object with  key " << tmpSlopKey[i]);
+            return StatusCode::FAILURE;
+        }
+
+        for (int j = 0; j < m_nEtaBins; j++) {
+            TString key = tmpFuncBase[i];
+            key += j;
+            TObject * obj = file->Get(key);
+            if (obj) {
+                calibFunc[i][j] = dynamic_cast<TF1*> (obj);
+            } else {
+                ATH_MSG_FATAL("Failed to get an object with  key " << key);
+                return StatusCode::FAILURE;
+            }
+        }
+    }
+    m_averageNPV = slopeNPVHist[0]->GetBinContent(0); // underflow is the average number of reconstructed primary vertices
+    m_minNTrackAtVertex = static_cast<unsigned int> (slopeNPVHist[0]->GetBinContent(slopeNPVHist[0]->GetNbinsX() + 1)); //overflow is the minimum number of tracks at vertex 
+
+    ATH_MSG_DEBUG("averageNPV                                 = " << m_averageNPV);
+    ATH_MSG_DEBUG("minimum number of tracks at primary vertex = " << m_minNTrackAtVertex);
+
+    file->Close();
+
+    return StatusCode::SUCCESS;
+}
+
+/********************************************************************/
+StatusCode TauCalibrateLC::execute(TauCandidateData *data) 
+{ 
+    xAOD::TauJet *pTau = data->xAODTau;
+
+    if (pTau == NULL) {
+        ATH_MSG_ERROR("no candidate given");
+        return StatusCode::FAILURE;
+    }
+       
+    // energy calibration depends on number of tracks - 1p or Mp
+    int prongBin = 1; //Mp
+    if (pTau->nTracks() <= 1) prongBin = 0; //1p
+
+    // set tau energy scale 
+    if (m_doEnergyCorr) {
+
+        // get detector axis values
+	double eta = pTau->etaDetectorAxis();
+        double absEta = std::abs(eta);
+        int etaBin = etaBinHist->GetXaxis()->FindBin(absEta) - 1;
+        
+        if (etaBin>=m_nEtaBins) etaBin = m_nEtaBins-1; // correction from last bin should be applied on all taus outside stored eta range
+
+        // get primary vertex container
+        StatusCode sc;
+        const xAOD::VertexContainer * vxContainer = 0;
+
+        // for tau trigger
+        bool inTrigger = false;
+        if (data->hasObject("InTrigger?")) sc = data->getObject("InTrigger?", inTrigger);
+        // FF: March, 2014
+        // this is for later purpose. At the moment no offset correction is used in case of tau trigger (see below)
+        if (sc.isSuccess() && inTrigger)   sc = data->getObject("VxPrimaryCandidate", vxContainer);
+        
+        if (!inTrigger || !vxContainer || sc.isFailure() ) {
+            // try standard 
+            if (evtStore()->retrieve(vxContainer, vertexContainerKey).isFailure() || !vxContainer) {
+              if (m_printMissingContainerINFO) {
+                ATH_MSG_WARNING(vertexContainerKey << " container not found --> skip TauEnergyCalibrationLC (no further info) ");
+                m_printMissingContainerINFO=false;
+              }
+                return StatusCode::SUCCESS;
+            }
+        }
+    
+        xAOD::VertexContainer::const_iterator vx_iter = vxContainer->begin();
+        xAOD::VertexContainer::const_iterator vx_end = vxContainer->end();
+        int nVertex = 0;
+        for (; vx_iter != vx_end; ++vx_iter) {
+            if ((*vx_iter)->nTrackParticles() >= m_minNTrackAtVertex)
+                ++nVertex;
+        }
+                
+	ATH_MSG_DEBUG("calculated nVertex " << nVertex );           
+
+
+        // get detector axis energy
+        // was saved by TauAxisSetter
+        double energyLC = pTau->p4(xAOD::TauJetParameters::DetectorAxis).E() / GeV;            //was sumClusterVector.e() / GeV;
+	
+        if (energyLC <= 0) {
+            ATH_MSG_DEBUG("tau energy at LC scale is " << energyLC << "--> set energy=0.001");           
+            //TODO: we can not set tau energy to 0 due to bug in P4Helpers during deltaR calculation
+            //will set it to 0.001 MeV
+	    pTau->setP4(0.001, pTau->eta(), pTau->phi(), pTau->m());
+            return StatusCode::SUCCESS;
+        }
+
+        double slopeNPV = slopeNPVHist[prongBin]->GetBinContent(etaBin + 1);
+        double offset = slopeNPV * (nVertex - m_averageNPV);
+
+        // FF: March,2014
+        // no offset correction for trigger        
+        if (inTrigger) offset = 0.;
+
+        if (energyLC - offset <= 0) {
+            ATH_MSG_DEBUG("after pile-up correction energy would be = " << energyLC - offset << " --> setting offset=0 now!");
+            offset = 0;
+        }
+
+        // apply offset correction
+        double energyPileupCorr = energyLC - offset;
+
+        double calibConst = 1.0;
+        if (energyPileupCorr > 0 and energyPileupCorr < 10000) // from 0 to 10 TeV
+        {
+            calibConst = calibFunc[prongBin][etaBin]->Eval(energyPileupCorr);
+
+            if (calibConst <= 0) {
+                ATH_MSG_DEBUG("calibration constant = " << calibConst);
+                ATH_MSG_DEBUG("prongBin             = " << prongBin);
+                ATH_MSG_DEBUG("etaBin               = " << etaBin);
+                ATH_MSG_DEBUG("energyPileupCorr     = " << energyPileupCorr);
+                ATH_MSG_DEBUG("energyLC             = " << energyLC);
+                calibConst = 1.0;
+            }
+        }
+
+        double energyFinal = energyPileupCorr / calibConst;
+
+	pTau->setP4(energyFinal * GeV / cosh( pTau->eta() ), pTau->eta(), pTau->phi(), pTau->m());
+
+	pTau->setP4(xAOD::TauJetParameters::TauEnergyScale, pTau->pt(), pTau->eta(), pTau->phi(), pTau->m());
+      
+ 	pTau->setDetail(xAOD::TauJetParameters::TESCalibConstant, static_cast<float>( calibConst ) );
+	pTau->setDetail(xAOD::TauJetParameters::TESOffset, static_cast<float>( offset * GeV ) );
+      
+        ATH_MSG_DEBUG("Energy at LC scale = " << energyLC << " pile-up offset " << offset << " calib. const. = " << calibConst << " final energy = " << energyFinal);
+    }
+    
+    // final tau axis
+    if (m_doAxisCorr) {
+
+        // get tau intermediate axis values
+        double eta = pTau->eta();
+        double absEta = std::abs(eta);
+        double etaCorr = eta;
+
+        if (absEta)
+            etaCorr = (eta / absEta)*(absEta - etaCorrectionHist->GetBinContent(etaCorrectionHist->GetXaxis()->FindBin(absEta)));
+
+        ATH_MSG_DEBUG("eta " << eta << "; corrected eta = " << etaCorr);
+
+	pTau->setP4( pTau->e() / cosh( etaCorr ), etaCorr, pTau->phi(), pTau->m());
+
+	pTau->setP4(xAOD::TauJetParameters::TauEtaCalib, pTau->pt(), pTau->eta(), pTau->phi(), pTau->m());
+     
+    }
+
+    return StatusCode::SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Finalize
+//-----------------------------------------------------------------------------
+
+StatusCode TauCalibrateLC::finalize() {
+    return StatusCode::SUCCESS;
+}
diff --git a/Reconstruction/tauRec/src/TauCellVariables.cxx b/Reconstruction/tauRec/src/TauCellVariables.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d30423c9d1445e6e546e6a48fad41127e81959a1
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauCellVariables.cxx
@@ -0,0 +1,402 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/********************************************************************
+NAME:     TauCellVariables.cxx
+PACKAGE:  offline/Reconstruction/tauRec
+AUTHORS:  S. Rajagopalan
+CREATED:  March 15, 2001
+
+Aug 2001: Add (e,px,py,pz) for sum of EM cells (FEP)
+Veto cell if track is within 0.8*size. Hence 1 cell if track
+is in center, more otherwise.
+ 
+Sep 2001: Take account of larger cells in third layer
+
+Nov 2001: Omit third layer of EM calorimeter from EM sums. This layer
+can become quite thick in the barrel, so it is more likely to
+be hadronic, while photons are mainly contained in the first
+two layers. (D. Lissauer suggested this.)
+
+Dec 2002: Add tau likelihood calculation.
+Feb 2003: Fix phi wrapping for et-weighted phi calculation.
+Jan 2004: Use CLHEP units. Use phi = (-pi,pi].
+Feb 2004: Fix identifiers, add taucmsdrdR
+March 2004: Fix CaloCluster -> CaloEnergyCluster
+Jul 2004: force -PI < phi < PI
+Jul 2004: move to I4Momentum
+Aug 2004: admit arbitrary seeds
+23/10/2006 - (AK) fixing some compilation warnings (unused parameter)
+18/04/2007 - (AK) fixing some compilation warnings (unused parameter)
+18/01/2008 - (NM) use etaCalo/phiCalo for merged algo, set tauJet eta/phi if not set by tau1p3p
+16/03/2010 - (AK) use the cell id instead of the pointer
+17/03/2010 - (AK) change to P4Helpers
+16/05/2011 - (FF) introduce possibility to correct cell origin wrt to primary vertex and beamspot
+Jan 2012   - (FF) add cellEnergyRing variables
+ ********************************************************************/
+
+#include <algorithm> 
+#include <math.h>
+#include <vector>
+#include <sstream>
+
+#include "GaudiKernel/Property.h"
+#include "CLHEP/Units/SystemOfUnits.h"
+
+#include "AtlasDetDescr/AtlasDetectorID.h"
+#include "CaloUtils/CaloCellList.h"
+#include "CaloEvent/CaloCluster.h"
+#include "CaloEvent/CaloCell.h"
+#include "CaloEvent/CaloSamplingHelper.h"
+#include "CaloUtils/CaloVertexedCell.h"
+#include "CaloIdentifier/CaloID.h"
+#include "CaloIdentifier/CaloCell_ID.h"
+#include "CaloGeoHelpers/CaloSampling.h"
+#include "Particle/TrackParticle.h"
+#include "FourMom/P4EEtaPhiM.h"
+
+#include "xAODTau/TauJet.h"
+#include "xAODJet/Jet.h"
+#include "tauRec/KineUtils.h"
+#include "tauRec/TauCellVariables.h"
+
+using CLHEP::GeV;
+
+TauCellVariables::TauCellVariables(const std::string& type,
+    const std::string& name,
+    const IInterface* parent) :
+TauToolBase(type, name, parent),
+m_cellEthr(0.2 * GeV),
+m_stripEthr(0.2 * GeV),
+m_EMSumThr(0.5 * GeV),
+m_EMSumR(0.2),
+m_cellCone(0.2),
+m_doCellCorrection(false) //FF: don't do cell correction by default
+{
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("CellEthreshold", m_cellEthr);
+    declareProperty("StripEthreshold", m_stripEthr);
+    declareProperty("EMSumThreshold", m_EMSumThr);
+    declareProperty("EMSumRadius", m_EMSumR);
+    declareProperty("CellCone", m_cellCone);
+    declareProperty("CellCorrection", m_doCellCorrection);
+}
+
+TauCellVariables::~TauCellVariables() {
+}
+
+StatusCode TauCellVariables::initialize() {
+    
+    ATH_MSG_VERBOSE("TauCellVariables::initialize"); // DEBUG
+    
+    StatusCode sc;
+
+    // retrieve all helpers from det store
+    sc = detStore()->retrieve(m_emid);
+    if (sc.isFailure()) {
+        ATH_MSG_ERROR("Unable to retrieve LArEM_ID helper from DetectorStore");
+        return sc;
+    }
+    ATH_MSG_VERBOSE("Storegate retrieved"); // DEBUG
+
+    sc = detStore()->retrieve(m_tileid);
+    if (sc.isFailure()) {
+        ATH_MSG_ERROR("Unable to retrieve TileID helper from DetectorStore");
+        return sc;
+    }
+    ATH_MSG_VERBOSE("TileID from DetectorStore"); // DEBUG
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauCellVariables::eventInitialize(TauCandidateData * /*data*/) {
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauCellVariables::execute(TauCandidateData *data) {
+
+    ATH_MSG_VERBOSE("execute"); // DEBUG
+
+    AtlasDetectorID AtlasID;
+
+    int numStripCell = 0;
+    int numEMCell = 0;
+
+    double sumCellE = 0.;
+    double sumEMCellE = 0.;
+
+    double eta = 0.;
+    double phi = 0.;
+    double stripEta = 0.;
+    double stripEta2 = 0.;
+
+    double EMRadius = 0.;
+
+    double sumStripET = 0.;
+    double sumCellET = 0.;
+    double sumEMCellET = 0.;
+    double sumCellET12 = 0.;
+
+    double ET1Sum = 0;
+
+    double EMET1Sum = 0;
+    double EMET4Sum = 0;
+
+    double HadRadius = 0.;
+    double sumHadCellET = 0.;
+
+    double cellEta, cellPhi, cellET, cellEnergy;
+    
+    std::vector<double> vCellRingEnergy(8,0.); //size=8, init with 0.
+
+    ///////////////////////////////////////////
+    
+    xAOD::TauJet *pTau = data->xAODTau;
+
+    if (pTau == NULL) {
+        ATH_MSG_ERROR("no candidate given");
+        return StatusCode::FAILURE;
+    }
+
+    ///////////////////////////////////////////
+    
+    ATH_MSG_VERBOSE("get cluster position, use for cell loop");
+
+    ATH_MSG_VERBOSE("position is eta=" << pTau->eta() << " phi=" << pTau->phi() );
+
+    //use tau vertex to correct cell position
+    bool applyCellCorrection = false;
+    if (m_doCellCorrection && pTau->vertexLink()) {
+       applyCellCorrection = true;
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // loop over all cells of the tau (placed there by the TauSeedBuilder)
+  
+    const xAOD::Jet* pJetSeed = (*pTau->jetLink());
+    if (!pJetSeed) {
+      ATH_MSG_WARNING("tau does not have jet seed for cell variable calculation");
+      return StatusCode::SUCCESS;
+    }
+
+    xAOD::JetConstituentVector::const_iterator cItr = pJetSeed->getConstituents().begin();
+    xAOD::JetConstituentVector::const_iterator cItrE = pJetSeed->getConstituents().end();
+
+    unsigned int num_cells = 0;
+
+    std::bitset<200000> cellSeen;
+
+    for (; cItr != cItrE; ++cItr) {
+      
+      const xAOD::CaloCluster* cluster = dynamic_cast<const xAOD::CaloCluster*>( (*cItr)->rawConstituent() ); 
+
+      CaloClusterCellLink::const_iterator firstcell = cluster->getCellLinks()->begin();
+      CaloClusterCellLink::const_iterator lastcell = cluster->getCellLinks()->end();
+      
+
+      // ATH_MSG_VERBOSE( "in loop over clusters and cells : cluster  phi= " << cluster->phi() << ", eta= " << cluster->eta()<< ", energy= " << cluster->e() << ", et= " <<cluster->pt() );
+    
+    const CaloCell *cell;
+    double dR;
+    
+    //loop over cells and calculate the variables
+    for (; firstcell != lastcell; ++firstcell) {
+        cell = *firstcell;
+
+
+	if (cellSeen.test(cell->caloDDE()->calo_hash())) {
+	  //already encountered this cell
+	  continue;
+	}
+	else {
+	  //New cell
+	  cellSeen.set(cell->caloDDE()->calo_hash());
+	}
+        ++num_cells;
+
+	// ATH_MSG_VERBOSE( "in loop over clusters and cells : phi= " << cell->phi() << ", eta= " << cell->eta()<< ", energy= " << cell->energy() << ", et= " <<cell->et() );
+
+        // correct cell for tau vertex
+        if (applyCellCorrection) {
+          //ATH_MSG_INFO( "before cell correction: phi= " << cell->phi() << ", eta= " << cell->eta()<< ", energy= " << cell->energy() << ", et= " <<cell->et() );
+          CaloVertexedCell vxCell (*cell, (*pTau->vertexLink())->position());
+          cellPhi = vxCell.phi();
+          cellEta = vxCell.eta();
+          cellET = vxCell.et();
+          cellEnergy = vxCell.energy();
+        }
+        else {
+          cellPhi = cell->phi();
+          cellEta = cell->eta();
+          cellET = cell->et();
+          cellEnergy = cell->energy();          
+        }
+        
+        CaloSampling::CaloSample calo = cell->caloDDE()->getSampling();
+
+        // Use cells those are in DR < m_cellCone of eta,phi of tau intermediate axis:
+	dR = Tau1P3PKineUtils::deltaR(pTau->eta(),pTau->phi(),cellEta,cellPhi);
+        
+        if (dR < m_cellCone) {
+            // Global sums
+            sumCellE += cellEnergy;
+
+            eta += cellEnergy * cellEta;
+
+            // Must handle phi wrapping! Compute relative to cluster phi:
+            double dphicc = cellPhi - pTau->phi();
+            if (dphicc > M_PI) dphicc = dphicc - 2 * M_PI;
+            if (dphicc < -M_PI) dphicc = dphicc + 2 * M_PI;
+            
+            phi += cellEnergy*dphicc;
+
+            // If cell is an EM cell, include in sum for EM radius and for
+            // total EM (e,px,py,pz)
+            // Nov 2000: Only include first 2 layers in EM
+
+            if (dR < 0.1) ET1Sum += cellET;
+
+            if ((calo == CaloSampling::PreSamplerB) ||
+                (calo == CaloSampling::PreSamplerE) ||
+
+                (calo == CaloSampling::EMB1) ||
+                (calo == CaloSampling::EME1) ||
+
+                (calo == CaloSampling::EMB2) ||
+                (calo == CaloSampling::EME2) ||
+
+                (calo == CaloSampling::EMB3) ||
+                (calo == CaloSampling::EME3)) {
+                if (dR < 0.1) EMET1Sum += cellET;
+                if (dR < m_cellCone) EMET4Sum += cellET;
+            }
+
+            if ((calo == CaloSampling::PreSamplerB) ||
+                (calo == CaloSampling::PreSamplerE) ||
+
+                (calo == CaloSampling::EMB1) ||
+                (calo == CaloSampling::EME1) ||
+
+                (calo == CaloSampling::EMB2) ||
+                (calo == CaloSampling::EME2)) {
+
+                sumEMCellE += cellEnergy;
+
+                // If cell is a strip cell, sum for stripET calculation:
+                if (((calo == CaloSampling::EMB1) ||
+                    (calo == CaloSampling::EME1)) // to be investigated
+                    && (fabs(cellEta) < 2.5)) {
+                    sumStripET += cellET;
+                    stripEta += cellEta * cellET;
+                    stripEta2 += pow(cellEta, 2) * cellET;
+                    if (cellEnergy > m_stripEthr) numStripCell += 1;
+                } // end of strip cells
+
+                EMRadius += dR*cellET;
+                sumEMCellET += cellET;
+                if (cellEnergy > m_cellEthr) numEMCell += 1;
+
+            }// end of EM cells
+            else { // HAD cells
+                HadRadius += dR*cellET;
+                sumHadCellET += cellET;
+            }
+
+            //  Sum cells in 0.1 < DR < 0.2 for Econe calculation
+            sumCellET += cellET;
+            if (dR > 0.1 && dR < 0.2) sumCellET12 += cellET;
+
+        }// end of dR <  m_cellCone
+        else {
+            // nothing
+        }
+
+        // vCellRingEnergy[0] is a dummy value
+        if (dR < 0.05) vCellRingEnergy[1] += cellET;
+        if (dR >= 0.05 && dR < 0.075) vCellRingEnergy[2] += cellET;
+        if (dR >= 0.075 && dR < 0.1) vCellRingEnergy[3] += cellET;
+        if (dR >= 0.1 && dR < 0.125) vCellRingEnergy[4] += cellET;
+        if (dR >= 0.125 && dR < 0.15) vCellRingEnergy[5] += cellET;
+        if (dR >= 0.15 && dR < 0.2) vCellRingEnergy[6] += cellET;
+        if (dR >= 0.2 && dR < 0.4) vCellRingEnergy[7] += cellET;
+
+    } // end of loop over CaloCells
+
+    }// end of loop over seed jet constituents
+
+    ATH_MSG_DEBUG(num_cells << " cells in seed");
+
+    //////////////////////////////////////////////////////////////////////////
+    // save variables
+    // keep this here until we know nobody complains that these were removed together with all extra details variables
+    // pExtraDetails->setSeedCalo_sumCellEnergy(sumCellE);
+    // pExtraDetails->setSeedCalo_sumEMCellEnergy(sumEMCellE);
+    // pExtraDetails->setSeedCalo_nEMCell(numEMCell);
+    // pExtraDetails->setSeedCalo_stripEt(sumStripET);
+    //
+
+    pTau->setDetail(xAOD::TauJetParameters::nStrip , numStripCell );
+
+    // if (fabs(EMET4Sum) > 0.000001)
+    //     pExtraDetails->setSeedCalo_EMCentFrac(EMET1Sum / EMET4Sum);
+    // else
+    //     pExtraDetails->setSeedCalo_EMCentFrac(0);
+
+    if (fabs(sumStripET) > 0.000001) {
+        stripEta = stripEta / sumStripET;
+        stripEta2 = stripEta2 / sumStripET;
+    } else {
+        stripEta = 0;
+        stripEta2 = -1.0;
+    }
+
+    pTau->setDetail(xAOD::TauJetParameters::stripWidth2 , static_cast<float>(stripEta2 - stripEta * stripEta) );
+
+    if (fabs(sumEMCellET) > 0.000001) {
+        EMRadius = EMRadius / sumEMCellET;
+    } else {
+        EMRadius = -1.0;
+    }
+    if (fabs(sumHadCellET) > 0.000001) {
+        HadRadius = HadRadius / sumHadCellET;
+    } else {
+        HadRadius = -1.0;
+    }
+    
+    pTau->setDetail(xAOD::TauJetParameters::EMRadius , static_cast<float>( EMRadius ) );
+    pTau->setDetail(xAOD::TauJetParameters::etEMAtEMScale , static_cast<float>( sumEMCellET ) );
+    pTau->setDetail(xAOD::TauJetParameters::hadRadius , static_cast<float>( HadRadius ) );
+    pTau->setDetail(xAOD::TauJetParameters::etHadAtEMScale , static_cast<float>( sumHadCellET ) );
+    
+    if (fabs(sumCellET) > 0.000001) {
+      pTau->setDetail(xAOD::TauJetParameters::centFrac , static_cast<float>( ET1Sum / sumCellET ) );
+      pTau->setDetail(xAOD::TauJetParameters::isolFrac , static_cast<float>( sumCellET12 / sumCellET ) );
+    } else {
+      pTau->setDetail(xAOD::TauJetParameters::centFrac , static_cast<float>( 0.0 ) );
+      pTau->setDetail(xAOD::TauJetParameters::isolFrac , static_cast<float>( -1.0 ) );
+    }
+
+    //save cell ring energies
+
+    pTau->setDetail(xAOD::TauJetParameters::cellBasedEnergyRing1 , static_cast<float>( vCellRingEnergy[1] ) );
+
+    pTau->setDetail(xAOD::TauJetParameters::cellBasedEnergyRing2 , static_cast<float>( vCellRingEnergy[2] ) );
+
+    pTau->setDetail(xAOD::TauJetParameters::cellBasedEnergyRing3 , static_cast<float>( vCellRingEnergy[3] ) );
+
+    pTau->setDetail(xAOD::TauJetParameters::cellBasedEnergyRing4 , static_cast<float>( vCellRingEnergy[4] ) );
+
+    pTau->setDetail(xAOD::TauJetParameters::cellBasedEnergyRing5 , static_cast<float>( vCellRingEnergy[5] ) );
+
+    pTau->setDetail(xAOD::TauJetParameters::cellBasedEnergyRing6 , static_cast<float>( vCellRingEnergy[6] ) );
+
+    pTau->setDetail(xAOD::TauJetParameters::cellBasedEnergyRing7 , static_cast<float>( vCellRingEnergy[7] ) );
+
+    return StatusCode::SUCCESS;
+}
+
+
+
+
diff --git a/Reconstruction/tauRec/src/TauCommonCalcVars.cxx b/Reconstruction/tauRec/src/TauCommonCalcVars.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ff2ad3048e02b654837450066d54e1dca5720f1b
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauCommonCalcVars.cxx
@@ -0,0 +1,226 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauCommonCalcVars.cxx
+// package:     Reconstruction/tauRec
+// authors:     Stan Lai
+// date:        2008-05-18
+// 
+// This class calculates tau variables after core seed reconstruction           
+//
+// 17/03/2010: (AK) change to P4Helpers
+// 16/05/2011: (FF) fix if primaryVertexContainer==NULL (coverity 21734)
+//   Dez 2011: (FF) switch to full LC calibrated tau 4-vector for some variables
+//-----------------------------------------------------------------------------
+//TODO: rename
+
+#include <GaudiKernel/IToolSvc.h>
+#include <GaudiKernel/ListItem.h>
+
+#include "tauRec/TauCandidateData.h"
+
+#include "tauRec/TauCommonCalcVars.h"
+#include "tauRec/KineUtils.h"
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+
+TauCommonCalcVars::TauCommonCalcVars(const std::string &type,
+    const std::string &name,
+    const IInterface *parent) :
+TauToolBase(type, name, parent) {
+    declareInterface<TauToolBase > (this);
+}
+
+//-----------------------------------------------------------------------------
+// Destructor
+//-----------------------------------------------------------------------------
+
+TauCommonCalcVars::~TauCommonCalcVars() {
+}
+
+
+//-----------------------------------------------------------------------------
+// Initializer
+//-----------------------------------------------------------------------------
+
+StatusCode TauCommonCalcVars::initialize() {
+    return StatusCode::SUCCESS;
+}
+
+
+//-----------------------------------------------------------------------------
+// Finalizer
+//-----------------------------------------------------------------------------
+
+StatusCode TauCommonCalcVars::finalize() {
+    return StatusCode::SUCCESS;
+}
+
+
+//-----------------------------------------------------------------------------
+// Execution
+//-----------------------------------------------------------------------------
+StatusCode TauCommonCalcVars::execute(TauCandidateData *data) {
+
+    xAOD::TauJet *pTau = data->xAODTau;
+
+    if (pTau == NULL) {
+        ATH_MSG_ERROR("no candidate given");
+        return StatusCode::FAILURE;
+    }
+
+    /////////////////////////////////////////////////
+    // Calculate variables that are always valid   
+    ////////////////////////////////////////////////
+
+    // Leading track pT and et/pt(lead track)
+    if (pTau->nTracks() > 0) {
+      pTau->setDetail( xAOD::TauJetParameters::leadTrkPt, static_cast<float>( pTau->track(0)->pt() ) );
+      
+      float emscale_ptEM = 0;
+      float emscale_ptHad = 0;
+      
+      if ( !pTau->detail( xAOD::TauJetParameters::etEMAtEMScale, emscale_ptEM ) ) 
+	{
+	  ATH_MSG_DEBUG("retrieval of tau detail failed. stopping calculation of further variables");
+	  return StatusCode::SUCCESS;
+	}
+
+      if ( !pTau->detail( xAOD::TauJetParameters::etHadAtEMScale, emscale_ptHad ) )
+	{
+	  ATH_MSG_DEBUG("retrieval of tau detail failed. stopping calculation of further variables");
+	  return StatusCode::SUCCESS;
+	}
+      
+      //EM scale
+
+      pTau->setDetail( xAOD::TauJetParameters::etOverPtLeadTrk, static_cast<float>( (emscale_ptEM + emscale_ptHad) / pTau->track(0)->pt() ) );
+
+        //switch to LC energy scale
+        //pDetails->setEtOverPtLeadTrk(pDetails->LC_TES_precalib() / fabs(pTau->track(0)->pt()));
+    }
+
+    // XXX still need to decide whether we want to fill loose track variables anymore
+    // // Leading loose track pT and et/pt(lead loose track)
+    // if (pDetails->nLooseTrk() > 0) {
+    //     pDetails->setLeadLooseTrkPt(pDetails->looseTrk(0)->pt());
+    //     //EM scale
+    //     pDetails->setEtOverPtLeadLooseTrk((pDetails->seedCalo_etHadCalib() + pDetails->seedCalo_etEMCalib()) / fabs(pDetails->looseTrk(0)->pt()));
+    //     //LC scale
+    //     //pDetails->setEtOverPtLeadLooseTrk(pDetails->LC_TES_precalib() / fabs(pDetails->looseTrk(0)->pt()));
+    // }
+
+    // invariant mass of track system
+    if ((pTau->nTracks() + pTau->nWideTracks()) > 0) {
+
+        TLorentzVector sumOfTrackVector;
+	TLorentzVector tempTrackVector;
+
+        for (unsigned int i = 0; i != pTau->nTracks(); ++i)
+	  {
+	    tempTrackVector.SetPtEtaPhiM( pTau->track(i)->pt(),  pTau->track(i)->eta(),  pTau->track(i)->phi(),  pTau->track(i)->m());
+            sumOfTrackVector += tempTrackVector;
+	  }
+        for (unsigned int i = 0; i != pTau->nWideTracks(); ++i)
+	  {
+	    tempTrackVector.SetPtEtaPhiM( pTau->wideTrack(i)->pt(),  pTau->wideTrack(i)->eta(),  pTau->wideTrack(i)->phi(),  pTau->wideTrack(i)->m());
+            sumOfTrackVector += tempTrackVector;
+	  }
+
+	pTau->setDetail( xAOD::TauJetParameters::massTrkSys, static_cast<float>( sumOfTrackVector.M() ) );
+	float tempfloat = 0;
+	if ( pTau->detail( xAOD::TauJetParameters::massTrkSys, tempfloat ) )
+		ATH_MSG_VERBOSE("set massTrkSys " << tempfloat);
+    }
+
+    // width of track system squared (trkWidth2)
+    if (pTau->nTracks() > 1) {
+
+        double leadTrkPhi = pTau->track(0)->phi();
+        double leadTrkEta = pTau->track(0)->eta();
+
+        double ptSum = 0;
+        double sumWeightedDR = 0;
+        double sumWeightedDR2 = 0;
+
+        for (unsigned int i = 0; i != pTau->nTracks(); ++i) {
+
+	  double deltaR = Tau1P3PKineUtils::deltaR(leadTrkEta, leadTrkPhi, pTau->track(i)->eta(), pTau->track(i)->phi() );     
+
+	  ptSum += pTau->track(i)->pt();
+	  sumWeightedDR += deltaR * (pTau->track(i)->pt());
+	  sumWeightedDR2 += deltaR * deltaR * (pTau->track(i)->pt());
+        }
+
+        for (unsigned int i = 0; i != pTau->nWideTracks(); ++i) {
+
+	  double deltaR = Tau1P3PKineUtils::deltaR(leadTrkEta, leadTrkPhi, pTau->wideTrack(i)->eta(), pTau->wideTrack(i)->phi() );     
+	  
+	  ptSum += pTau->wideTrack(i)->pt();
+	  sumWeightedDR += deltaR * (pTau->wideTrack(i)->pt());
+	  sumWeightedDR2 += deltaR * deltaR * (pTau->wideTrack(i)->pt());
+        }
+
+        double trkWidth2 = sumWeightedDR2 / ptSum - sumWeightedDR * sumWeightedDR / ptSum / ptSum;
+
+        if (trkWidth2 > 0.) pTau->setDetail( xAOD::TauJetParameters::trkWidth2, static_cast<float>( trkWidth2 ) );
+        else pTau->setDetail( xAOD::TauJetParameters::trkWidth2, static_cast<float>( 0. ) );
+    }
+
+    // Calculation for seedCalo_trkAvgDist and seedCalo_trkRmsDist
+    
+    //FF: use now the 4-vector of the tau intermediate axis
+    //P4EEtaPhiM P4CaloSeed(1., pDetails->seedCalo_eta(), pDetails->seedCalo_phi(), 0.);
+
+    if ((pTau->nWideTracks() + pTau->nTracks()) > 0) {
+
+        double ptSum = 0;
+        double sumWeightedDR = 0;
+        double sumWeightedDR2 = 0;
+
+        for (unsigned int i = 0; i != pTau->nTracks(); ++i) {
+
+          double deltaR = Tau1P3PKineUtils::deltaR(pTau->eta(), pTau->phi(), pTau->track(i)->eta(), pTau->track(i)->phi() );     
+	
+	  ptSum += pTau->track(i)->pt();
+	  sumWeightedDR += deltaR * (pTau->track(i)->pt());
+	  sumWeightedDR2 += deltaR * deltaR * (pTau->track(i)->pt());
+        }
+
+        for (unsigned int i = 0; i != pTau->nWideTracks(); ++i) {
+
+          double deltaR = Tau1P3PKineUtils::deltaR(pTau->eta(), pTau->phi(), pTau->wideTrack(i)->eta(), pTau->wideTrack(i)->phi() );     
+          
+	  ptSum += pTau->wideTrack(i)->pt();
+	  sumWeightedDR += deltaR * (pTau->wideTrack(i)->pt());
+	  sumWeightedDR2 += deltaR * deltaR * (pTau->wideTrack(i)->pt());
+        }
+
+        if (ptSum > 0.0001) {
+	  // seedCalo_trkAvgDist
+	  pTau->setDetail( xAOD::TauJetParameters::trkAvgDist, static_cast<float>( sumWeightedDR / ptSum ) );
+
+	  float tempfloat;
+	  if ( pTau->detail( xAOD::TauJetParameters::trkAvgDist, tempfloat ) )
+	    ATH_MSG_VERBOSE("set seedCalo_trkAvgDist " << tempfloat );
+
+	  // seedCalo_trkRmsDist
+	  double trkRmsDist2 = sumWeightedDR2 / ptSum - sumWeightedDR * sumWeightedDR / ptSum / ptSum;
+	  if (trkRmsDist2 > 0) {
+	    pTau->setDetail( xAOD::TauJetParameters::trkRmsDist, static_cast<float>( sqrt(trkRmsDist2) ) );
+	  } else {
+	    pTau->setDetail( xAOD::TauJetParameters::trkRmsDist, static_cast<float>( 0. ) );
+	  }
+	  if ( pTau->detail( xAOD::TauJetParameters::trkRmsDist, tempfloat ) )
+	    ATH_MSG_VERBOSE("set seedCalo_trkRmsDist " << tempfloat );
+        }
+    }
+
+    return StatusCode::SUCCESS;
+}
+
+
diff --git a/Reconstruction/tauRec/src/TauConversionFinder.cxx b/Reconstruction/tauRec/src/TauConversionFinder.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f5636b97b408c362522f38894119611cbdd0999c
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauConversionFinder.cxx
@@ -0,0 +1,153 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/********************************************************************
+NAME:     TauConversionFinder.cxx
+PACKAGE:  offline/Reconstruction/tauRec
+AUTHORS:  Michael Boehler <michael.boehler@desy.de>
+CREATED:  November 2008
+
+This tool identifies if a tau track is reconstructed as photon 
+conversion track too.
+ ********************************************************************/
+
+#include "tauRec/TauConversionFinder.h"
+
+#include "xAODTracking/VertexContainer.h" 
+#include "GaudiKernel/IToolSvc.h"
+#include "TrkParticleBase/LinkToTrackParticleBase.h"
+
+/********************************************************************/
+TauConversionFinder::TauConversionFinder(const std::string& type,
+    const std::string& name,
+    const IInterface* parent) :
+TauToolBase(type, name, parent) {
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("ConversionCandidatesName", m_ConversionCandidatesName = "ConversionsPID_Container"); //ConversionCandidate
+    declareProperty("TrackContainerName", m_trackContainerName = "InDetTrackParticles");
+    declareProperty("DoNormalTracks", m_do_normal = true);
+    declareProperty("MinElectronProbability", m_eProb_cut = 0.9);
+    declareProperty("AdjustTauCharge", m_adjust_tau_charge = false);
+
+}
+
+/********************************************************************/
+TauConversionFinder::~TauConversionFinder() {
+}
+
+/********************************************************************/
+StatusCode TauConversionFinder::initialize() {
+    ATH_MSG_VERBOSE("TauConversionFinder Initialising");
+
+    return StatusCode::SUCCESS;
+}
+
+/********************************************************************/
+StatusCode TauConversionFinder::finalize() {
+    ATH_MSG_VERBOSE("TauConversionFinder Finalizing");
+
+    return StatusCode::SUCCESS;
+}
+
+/********************************************************************/
+StatusCode TauConversionFinder::eventFinalize(TauCandidateData *data) {
+
+    StatusCode sc;
+
+    const Rec::TrackParticleContainer *trackContainer;
+
+    //TODO: trigger uses getObject
+    sc = evtStore()->retrieve(trackContainer, m_trackContainerName);
+    if (sc.isFailure() || !trackContainer) {
+        ATH_MSG_DEBUG(" No track container found in TDS !!");
+        return StatusCode::SUCCESS;
+    }
+
+    // ------------------------------------------------------------------ 
+    //               Retrieving VxCandidates (conversions)
+    // ------------------------------------------------------------------   
+    const xAOD::VertexContainer* ConvContainer;
+
+    sc = evtStore()->retrieve(ConvContainer, m_ConversionCandidatesName);
+    if (sc.isFailure() || !ConvContainer) {
+        ATH_MSG_DEBUG(" No VxCandidates container found in TDS !!");
+        return StatusCode::SUCCESS;
+    } else {
+        ATH_MSG_VERBOSE("Processing Conversion Container Name = " << m_ConversionCandidatesName);
+    }
+    ATH_MSG_VERBOSE("VxContainer " << m_ConversionCandidatesName << " contains " << ConvContainer->size() << " vertices. ");
+
+    // ------------------------------------------------------------------ 
+    //                    Check number of Tau Tracks
+    // ------------------------------------------------------------------ 
+    if (!m_do_normal) { 
+        return StatusCode::SUCCESS;
+    }
+
+    // running in eventFinalize
+    // therefore need to loop over all tau candidates 
+    xAOD::TauJetContainer *pTauJetCont = data->xAODTauContainer;
+    for (xAOD::TauJetContainer::iterator tjcItr = pTauJetCont->begin(); tjcItr != pTauJetCont->end(); ++tjcItr) {
+        
+        xAOD::TauJet *pTau = *tjcItr;
+        if (pTau == NULL) {
+            ATH_MSG_DEBUG("no candidate given");
+            continue;
+        }
+
+        unsigned int numTracks = pTau->nTracks();
+
+        m_numProng = numTracks;
+
+        if (m_do_normal)
+            ATH_MSG_VERBOSE("Number of tau tracks before ConversionFinder (TauJet): " << m_numProng);
+
+        // Loop over Conversion Container placed by TauPhotonConversionFinder
+        xAOD::VertexContainer::const_iterator itr = ConvContainer->begin();
+        xAOD::VertexContainer::const_iterator itrE = ConvContainer->end();
+        for (; itr != itrE; ++itr) {
+
+            const xAOD::Vertex* vxcand = (*itr);
+
+            for (unsigned int i = 0; i < vxcand->nTrackParticles(); ++i) {
+
+                const Trk::Track* conv_trk = vxcand->trackParticle(i)->track();
+                // just check if the track is reconstructed only by TRT
+                //--------------------------------------------
+                // Find conversion in normal tau tracks
+                if (m_do_normal) {
+                    for (unsigned int j = 0; j < numTracks; ++j) {
+                        const xAOD::TrackParticle *pTauTrack = pTau->track(j);
+                        const Trk::Track* tau_trk_def = pTauTrack->track();
+
+                        if (conv_trk == tau_trk_def) {
+                            if (conv_trk->trackSummary()->getPID(Trk::eProbabilityComb) > m_eProb_cut) {
+                                bool isConversionTrack = false;
+                                for (unsigned int k = 0; k < pTau->nConversionTracks(); k++) {
+                                    if (pTau->conversionTrack(k)->track() == pTau->track(j)->track())
+                                        isConversionTrack = true;
+                                }
+                                if (isConversionTrack) {
+                                    pTau->addConversionTrackLink(pTau->conversionTrackLinks().at(j));
+                                    if (m_adjust_tau_charge)
+                                        pTau->setCharge(pTau->charge() - pTau->track(j)->charge());
+
+                                    m_numProng--;
+                                }
+                            }
+                        }
+                    }
+                }
+            }//end of loop over Tracks at vertex
+        }// end of loop over VxContainer
+
+        if (m_do_normal)
+            ATH_MSG_VERBOSE("Number of tau tracks after ConversionFinder (TauJet): " << m_numProng);
+    }// end of loop over TauJetContainer
+
+    return StatusCode::SUCCESS;
+}
+
+/********************************************************************/
diff --git a/Reconstruction/tauRec/src/TauConversionTagger.cxx b/Reconstruction/tauRec/src/TauConversionTagger.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..75b705bdfd50e568d2a54965929365f7642168fc
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauConversionTagger.cxx
@@ -0,0 +1,179 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauConversionTagger.cxx
+// package:     Reconstruction/tauRec
+// authors:     Dimitris Varouchas
+// date:        2013-11-08
+//
+//
+//-----------------------------------------------------------------------------
+//TODO:
+
+#include <GaudiKernel/IToolSvc.h>
+#include <GaudiKernel/ListItem.h>
+
+#include "FourMomUtils/P4Helpers.h"
+#include "FourMom/P4EEtaPhiM.h"
+#include "CLHEP/Vector/LorentzVector.h"
+#include "Particle/TrackParticle.h"
+
+#include "EventInfo/EventInfo.h"
+#include "EventInfo/EventID.h"
+#include "TrkParameters/TrackParameters.h"
+
+#include "tauRec/TauCandidateData.h"
+#include "tauEvent/TauCommonDetails.h"
+#include "tauEvent/TauJetParameters.h"
+
+#include "tauRec/TauConversionTagger.h"
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+
+TauConversionTagger::TauConversionTagger(const std::string &type,
+    const std::string &name,
+    const IInterface *parent) :
+        TauToolBase(type, name, parent),
+        m_trackToVertexTool("Reco::TrackToVertex")
+{
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("ConversionTaggerVersion", m_ConvTaggerVer = 1);
+    declareProperty("TrackContainerName", m_trackContainerName = "InDetTrackParticles");
+    declareProperty("TrackToVertexTool", m_trackToVertexTool);
+    declareProperty ("TRTRatio", m_doTRTRatio = true);
+    declareProperty ("FullInfo", m_storeFullSummary = false);
+}
+
+//-----------------------------------------------------------------------------
+// Destructor
+//-----------------------------------------------------------------------------
+
+TauConversionTagger::~TauConversionTagger() {
+}
+
+
+//-----------------------------------------------------------------------------
+// Initializer
+//-----------------------------------------------------------------------------
+
+StatusCode TauConversionTagger::initialize() {
+    return StatusCode::SUCCESS;
+}
+
+
+//-----------------------------------------------------------------------------
+// Finalizer
+//-----------------------------------------------------------------------------
+
+StatusCode TauConversionTagger::finalize() {
+    return StatusCode::SUCCESS;
+}
+
+
+//-----------------------------------------------------------------------------
+// Execution
+//-----------------------------------------------------------------------------
+StatusCode TauConversionTagger::execute(TauCandidateData *data) {
+  xAOD::TauJet *pTau = data->xAODTau;
+
+  StatusCode sc;
+
+  sc = m_trackToVertexTool.retrieve();
+  if(sc.isFailure()) {
+    ATH_MSG_ERROR("Could not retrieve TrackToVertexTool");
+    return StatusCode::FAILURE;
+  } 
+
+  for(unsigned int j=0; j<pTau->nTracks(); j++ ) {
+
+    const xAOD::TrackParticle *TauJetTrack = pTau->track(j);
+    const Trk::Perigee* perigee = m_trackToVertexTool->perigeeAtVertex(*TauJetTrack, (*pTau->vertexLink())->position());
+
+    // Declare TrackSummary info
+    // Note: all must be of type uint8_t for summaryValue filling to work in xAOD
+    // TODO: check if these default values are sane
+    uint8_t nBLHits             = 0;
+    uint8_t expectBLayerHit     = 0;
+    uint8_t nTRTHighTHits       = 0;
+    uint8_t nTRTHighTOutliers   = 0;
+    float   nTRTHighT_outl      = 0.;
+    uint8_t nTRTXenon           = 0;
+    uint8_t nTRTHits            = 0;
+    uint8_t nTRTOutliers        = 0;
+
+    // Fill TrackSummary info
+    TauJetTrack->summaryValue(nBLHits,xAOD::numberOfBLayerHits);
+    TauJetTrack->summaryValue(expectBLayerHit,xAOD::expectBLayerHit);
+    TauJetTrack->summaryValue(nTRTHighTHits,xAOD::numberOfTRTHighThresholdHits);
+    TauJetTrack->summaryValue(nTRTHighTOutliers,xAOD::numberOfTRTHighThresholdOutliers);
+    nTRTHighT_outl = nTRTHighTHits + nTRTHighTOutliers;
+    TauJetTrack->summaryValue(nTRTXenon,xAOD::numberOfTRTXenonHits);
+    TauJetTrack->summaryValue(nTRTHits,xAOD::numberOfTRTHits);
+    TauJetTrack->summaryValue(nTRTOutliers,xAOD::numberOfTRTOutliers);
+
+    // TODO: check if default value is sane
+    m_TRTHighTOutliersRatio = 0.;
+    if (m_doTRTRatio || m_storeFullSummary) {
+      if (nTRTXenon > 0)
+        m_TRTHighTOutliersRatio = nTRTHighT_outl / nTRTXenon;
+      else if (nTRTHits + nTRTOutliers > 0)
+        m_TRTHighTOutliersRatio = nTRTHighT_outl / (nTRTHits+nTRTOutliers);
+    }
+
+    double pt = TauJetTrack->pt();
+    double d0 = perigee->parameters()[Trk::d0];
+
+
+    m_TrkIsConv = false;
+
+    float Rconv = sqrt (fabs(d0)*pt/(0.15*2.));
+
+    if ( m_ConvTaggerVer==0 ) {
+
+      m_a_cut[0][0]=0.0003;  m_b_cut[0][0]=0.1725;
+      m_a_cut[0][1]=0.0003;  m_b_cut[0][1]=0.2025;
+
+      if ( nBLHits==0 && expectBLayerHit ){
+	      if( m_TRTHighTOutliersRatio > -m_a_cut[0][0]*Rconv + m_b_cut[0][0] ) m_TrkIsConv=true;
+      }
+      else {
+    	  if( m_TRTHighTOutliersRatio > -m_a_cut[0][1]*Rconv + m_b_cut[0][1] ) m_TrkIsConv=true;
+    	}
+    }
+
+    else if ( m_ConvTaggerVer==1 ) {
+
+      m_a_cut[1][0]=0.0003;  m_b_cut[1][0]=0.1725;
+      m_a_cut[1][1]=0.0003;  m_b_cut[1][1]=0.2025;
+
+
+      if(nBLHits==0 ){
+      	if( m_TRTHighTOutliersRatio > -m_a_cut[1][0]*Rconv + m_b_cut[1][0] ) m_TrkIsConv=true;
+      }
+      else {
+      	if( m_TRTHighTOutliersRatio > -m_a_cut[1][1]*Rconv + m_b_cut[1][1] ) m_TrkIsConv=true;
+      }
+    }
+
+    else {
+
+      ATH_MSG_WARNING("No tau conversion tagger compatible with version "<<m_ConvTaggerVer);
+      return false;
+    }
+
+    ATH_MSG_VERBOSE("Is tau track a conversion? : " << m_TrkIsConv);
+    if (m_TrkIsConv)
+      pTau->addConversionTrackLink((&pTau->trackLinks())->at(j));
+
+    delete perigee; //cleanup necessary to prevent mem leak
+	
+  }
+
+  return StatusCode::SUCCESS;
+}
+
diff --git a/Reconstruction/tauRec/src/TauElectronVetoVariables.cxx b/Reconstruction/tauRec/src/TauElectronVetoVariables.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f788db96a049e8c50471b06b7a3a209e54643ef9
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauElectronVetoVariables.cxx
@@ -0,0 +1,390 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        tau1p3pEleVeto.cxx
+// package:     Reconstruction/tauRec
+// authors:     Zofia Czyczula
+// date:        2006-09-27
+//
+// 
+// This tool veto electrons.
+//
+// MODIFIED:
+// 02-04-2007 - (AK) protection against missing egamma Collection
+// 25-03-2008 - (AK for ZC) upgade of the code
+// 28-03-1008 - (AK) fix for protection against missing egamma Collection 
+//               ERROR->WARNING
+// 15/04/2008 - (AK) fixing compilation warning bug #35463
+// 03-10-2008 - (ZC) upgarade of the code 
+// 16/03/2010 - (AK) use the cell id instead of the pointer 
+//-----------------------------------------------------------------------------
+
+////
+//TODO: this is cell based and use tracking variables -> can not run on AOD 
+//TODO: rename
+//
+
+#include <algorithm>
+#include <math.h>
+#include <sstream>
+
+#include "GaudiKernel/ListItem.h"
+#include "GaudiKernel/IToolSvc.h"
+#include "GaudiKernel/Property.h"
+
+#include "CaloUtils/CaloCellList.h"
+#include "CaloEvent/CaloCluster.h"
+#include "CaloEvent/CaloCell.h"
+#include "CaloUtils/CaloVertexedCell.h"
+#include "AtlasDetDescr/AtlasDetectorID.h"
+#include "CaloIdentifier/CaloID.h"
+#include "CaloIdentifier/CaloCell_ID.h"
+#include "CaloGeoHelpers/CaloSampling.h"
+
+#include "xAODTau/TauJet.h"
+#include "xAODJet/Jet.h"
+#include "tauRec/KineUtils.h"
+
+#include "RecoToolInterfaces/IExtrapolateToCaloTool.h"
+#include "tauRec/TauElectronVetoVariables.h"
+
+using CLHEP::GeV;
+
+//-------------------------------------------------------------------------
+// Constructor
+//-------------------------------------------------------------------------
+TauElectronVetoVariables::TauElectronVetoVariables(const std::string &type,
+        const std::string &name,
+        const IInterface *parent):
+TauToolBase(type, name, parent),
+m_doCellCorrection(false), //FF: don't do cell correction by default
+m_trackToCalo("")
+{
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("CellCorrection", m_doCellCorrection);
+    declareProperty("TTCExtrapolator", m_trackToCalo, "public track extrapolator tool to match track with caloseed");
+}
+
+//-------------------------------------------------------------------------
+// Destructor
+//-------------------------------------------------------------------------
+TauElectronVetoVariables::~TauElectronVetoVariables() { }
+
+//-------------------------------------------------------------------------
+// Initializer
+//-------------------------------------------------------------------------
+StatusCode TauElectronVetoVariables::initialize()
+{
+    if (m_trackToCalo.retrieve().isFailure()) {
+      ATH_MSG_ERROR("Cannot find tool named <" << m_trackToCalo << ">");
+      return StatusCode::FAILURE;
+    }
+    return StatusCode::SUCCESS;
+}
+StatusCode TauElectronVetoVariables::eventInitialize(TauCandidateData * /*data*/)
+{
+    return StatusCode::SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// Execution
+//-------------------------------------------------------------------------
+StatusCode TauElectronVetoVariables::execute(TauCandidateData *data)
+{
+
+  xAOD::TauJet *pTau = data->xAODTau;
+
+    if (pTau == NULL) {
+        ATH_MSG_ERROR("no candidate given");
+        return StatusCode::FAILURE;
+    }
+
+
+    if (pTau->nTracks() < 1) {
+        return StatusCode::SUCCESS;
+    }
+
+    ATH_MSG_VERBOSE(name() << " in execute() ...");
+
+    float detPhiTrk = 0.;
+    float detEtaTrk = 0.;
+    float clEtaTrk = 0.;
+    float distEtaTrk = 0.;
+
+    float energy_3phi[101] = {0.0};
+    float eta[101] = {0.0};
+    int max1 = 0;
+    int max2 = 0;
+    int max = 0;
+    int n = 0;
+    float Emax1 = 0.;
+    float Emax2 = 0.;
+    float etamaxcut = 0.158;
+    float phimaxcut = 0.1;
+    float signum_eta = 0.;
+
+    signum_eta = pTau->track(0)->eta() / fabs(pTau->track(0)->eta());
+
+    float sumETCellsLAr = 0.;
+    float eta0cut = 0.075;
+    float eta1cut = 0.0475;
+    float eta2cut = 0.075;
+    float eta3cut = 1.5;
+    float phi0cut = 0.3;
+    float phi1cut = 0.3;
+    float phi2cut = 0.075;
+    float phi3cut = 0.075;
+    float etareg = 0.;
+    float etacase1 = 1.8;
+    float etagran1 = 0.00315;
+    float etagran2 = 0.00415;
+    float sumETCellsHad1 = 0.;
+    float etahadcut = 0.2;
+    float phihadcut = 0.2;
+
+    const CaloCell *pCell;
+
+    //use tau vertex to correct cell position
+    bool applyCellCorrection = false;
+    if (m_doCellCorrection && pTau->vertexLink()) {
+       applyCellCorrection = true;
+    }
+
+    //---------------------------------------------------------------------
+    // Calculate eta, phi impact point of leading track at calorimeter layers EM 0,1,2,3
+    //---------------------------------------------------------------------
+    const DataVector< const Trk::TrackParameters >* pTrk = m_trackToCalo->getParametersInCalo( ( *pTau->track(0) ) , Trk::pion, Trk::alongMomentum); //FIXME
+  
+    const int numOfsampEM = 4;
+    double eta_extrapol[4];
+    double phi_extrapol[4];
+
+    for (int i = 0; i < numOfsampEM; ++i) {
+      eta_extrapol[i] = -11111.;
+      phi_extrapol[i] = -11111.;
+    }
+
+
+    if (pTrk && (*pTrk)[IExtrapolateToCaloTool::PreSampler]) {
+      eta_extrapol[0] = (*pTrk)[IExtrapolateToCaloTool::PreSampler]->position().eta();
+      phi_extrapol[0] = (*pTrk)[IExtrapolateToCaloTool::PreSampler]->position().phi();
+    }
+    
+    if (pTrk && (*pTrk)[IExtrapolateToCaloTool::Strips]) {
+      eta_extrapol[1] = (*pTrk)[IExtrapolateToCaloTool::Strips]->position().eta();
+      phi_extrapol[1] = (*pTrk)[IExtrapolateToCaloTool::Strips]->position().phi();
+    }
+	
+    if (pTrk && (*pTrk)[IExtrapolateToCaloTool::Middle]) {
+      eta_extrapol[2] = (*pTrk)[IExtrapolateToCaloTool::Middle]->position().eta();
+      phi_extrapol[2] = (*pTrk)[IExtrapolateToCaloTool::Middle]->position().phi();
+    }
+    
+    if (pTrk && (*pTrk)[IExtrapolateToCaloTool::Back]) {
+      eta_extrapol[3] = (*pTrk)[IExtrapolateToCaloTool::Back]->position().eta();
+      phi_extrapol[3] = (*pTrk)[IExtrapolateToCaloTool::Back]->position().phi();
+    }
+    
+
+
+
+    for (int i = 0; i < numOfsampEM; ++i) {
+      if ( eta_extrapol[i] < -11110. || phi_extrapol[i] < -11110. )
+	{
+	  ATH_MSG_WARNING("extrapolation of leading track to calo surfaces failed for sampling : " << i );
+	  return StatusCode::SUCCESS;
+	}
+    }
+
+    const xAOD::Jet* pJetSeed = (*pTau->jetLink());
+    if (!pJetSeed) {
+      ATH_MSG_WARNING("tau does not have jet seed for electron veto cell variable calculation");
+      return StatusCode::SUCCESS;
+    }
+
+    xAOD::JetConstituentVector::const_iterator cItr = pJetSeed->getConstituents().begin();
+    xAOD::JetConstituentVector::const_iterator cItrE = pJetSeed->getConstituents().end();
+
+    std::bitset<200000> cellSeen;
+
+    for (; cItr != cItrE; ++cItr) {
+      
+      const xAOD::CaloCluster* cluster = dynamic_cast<const xAOD::CaloCluster*>( (*cItr)->rawConstituent() ); 
+      
+      CaloClusterCellLink::const_iterator pCellIter  = cluster->getCellLinks()->begin();
+      CaloClusterCellLink::const_iterator pCellIterE = cluster->getCellLinks()->end();
+     
+
+      double cellPhi;
+      double cellEta;
+      double cellET;
+    for (; pCellIter != pCellIterE; pCellIter++) {
+
+        pCell = *pCellIter;
+	
+	if (cellSeen.test(pCell->caloDDE()->calo_hash())) {
+	  //already encountered this cell
+	  continue;
+	}
+	else {
+	  //New cell
+	  cellSeen.set(pCell->caloDDE()->calo_hash());
+	}
+
+
+        if (applyCellCorrection) {
+          //ATH_MSG_INFO( "before cell correction: phi= " << cell->phi() << ", eta= " << cell->eta()<< ", energy= " << cell->energy() << ", et= " <<cell->et() );
+          CaloVertexedCell vxCell (*pCell, (*pTau->vertexLink())->position());
+          cellPhi = vxCell.phi();
+          cellEta = vxCell.eta();
+          cellET = vxCell.et();
+        }
+        else {
+          cellPhi = pCell->phi();
+          cellEta = pCell->eta();
+          cellET = pCell->et();
+        }
+	
+        int sampling = pCell->caloDDE()->getSampling();
+        if (sampling == 4) sampling = 0;
+        if (sampling == 5) sampling = 1;
+        if (sampling == 6) sampling = 2;
+        if (sampling == 7) sampling = 3;
+        if (sampling == 18) sampling = 12;
+        if (sampling == 8) sampling = 12;
+        if (sampling == 15) sampling = 12;
+        if (sampling == 19) sampling = 13;
+        if (sampling == 16) sampling = 13;
+        if (sampling == 20) sampling = 14;
+        if (sampling == 17) sampling = 14;
+	
+        int i = 2;
+        if (sampling < 4) i = sampling;
+        if (sampling == 12 || sampling == 13 || sampling == 14) i = 3;
+
+        detPhiTrk = Tau1P3PKineUtils::deltaPhi( cellPhi, phi_extrapol[i] );
+	detEtaTrk = std::fabs( cellEta - eta_extrapol[i] );
+	clEtaTrk = eta_extrapol[i];
+	distEtaTrk = cellEta - eta_extrapol[i];
+
+        if ((sampling == 0 && detEtaTrk < eta0cut && detPhiTrk < phi0cut) ||
+                (sampling == 1 && detEtaTrk < eta1cut && detPhiTrk < phi1cut) ||
+                (sampling == 2 && detEtaTrk < eta2cut && detPhiTrk < phi2cut) ||
+                (sampling == 3 && detEtaTrk < eta3cut && detPhiTrk < phi3cut)) {
+
+            sumETCellsLAr += cellET;
+        }
+
+        if (sampling == 12 && detEtaTrk < etahadcut && detPhiTrk < phihadcut) sumETCellsHad1 += cellET;
+
+        if (fabs(cellEta) > 0.8 && fabs(cellEta) <= 1.2 && (sampling == 13 || sampling == 14) && detEtaTrk < etahadcut && detPhiTrk < phihadcut) {
+            sumETCellsHad1 += cellET;
+        }
+
+        if (fabs(pTau->track(0)->eta()) <= 1.7) {
+            if (sampling == 1 && detEtaTrk < etamaxcut && detPhiTrk <= phimaxcut) {
+                if ((fabs(cellEta) < 1.37 || fabs(cellEta) > 1.52) && fabs(cellEta) < 1.85) {
+                    if (fabs(clEtaTrk) <= etacase1 && fabs(cellEta) <= etacase1) {
+                        n = 50 + int(distEtaTrk / etagran1);
+                    }
+                    if (fabs(clEtaTrk) <= etacase1 && fabs(cellEta) > etacase1) {
+                        n = 50 + int(signum_eta * ((etacase1 - fabs(clEtaTrk)) / etagran1 + (-etacase1 + fabs(cellEta)) / etagran2));
+                    }
+                    energy_3phi[n] = energy_3phi[n] + cellET / GeV;
+                    eta[n] = signum_eta * (clEtaTrk - cellEta);
+                } else {
+                    energy_3phi[n] = 0;
+                    eta[n] = 0;
+                }
+            }
+        } else {
+            energy_3phi[n] = 0;
+            eta[n] = 0;
+        }
+
+        if (fabs(cellEta) <= etacase1) {
+            etareg = 0.00315;
+        } else {
+            etareg = 0.00415;
+        }
+        
+    } //end cell loop
+
+    }// end jet constituent loop
+
+    for (int m1 = 0; m1 < 101; m1++) {
+        if ((energy_3phi[m1] > Emax1)) {
+            Emax1 = energy_3phi[m1];
+            max1 = m1;
+        }
+    }
+
+    for (int m2 = 1; m2 < 100; m2++) {
+        if (m2 == max1) continue;
+
+        if ((energy_3phi[m2] > Emax2) && (energy_3phi[m2] > energy_3phi[m2 - 1]) && (energy_3phi[m2] > energy_3phi[m2 + 1])) {
+            Emax2 = energy_3phi[m2];
+            max2 = m2;
+        }
+    }
+
+    if (fabs(eta[max1]) >= etareg) {
+        max = max1;
+    } else {
+        max = max2;
+    }
+
+
+    float TRTratio = -9999.0;
+    uint8_t TRTHTHits;
+    uint8_t TRTHTOutliers;
+    uint8_t TRTHits;
+    uint8_t TRTOutliers;
+      
+    if ( !pTau->track(0)->summaryValue( TRTHits, xAOD::SummaryType::numberOfTRTHits ) )
+      {
+	ATH_MSG_DEBUG("retrieval of track summary value failed. Not filling electron veto variables for this one prong candidate");
+	return StatusCode::SUCCESS;
+      }
+    if ( !pTau->track(0)->summaryValue( TRTHTHits, xAOD::SummaryType::numberOfTRTHighThresholdHits ) )
+      {
+	ATH_MSG_DEBUG("retrieval of track summary value failed. Not filling electron veto variables for this one prong candidate");
+	return StatusCode::SUCCESS;
+      }
+    if ( !pTau->track(0)->summaryValue( TRTOutliers, xAOD::SummaryType::numberOfTRTOutliers ) )
+      {
+	ATH_MSG_DEBUG("retrieval of track summary value failed. Not filling electron veto variables for this one prong candidate");
+	return StatusCode::SUCCESS;
+      }
+    if ( !pTau->track(0)->summaryValue( TRTHTOutliers, xAOD::SummaryType::numberOfTRTHighThresholdOutliers ) )
+      {
+	ATH_MSG_DEBUG("retrieval of track summary value failed. Not filling electron veto variables for this one prong candidate");
+	return StatusCode::SUCCESS;
+      }
+      
+
+      if (TRTHits + TRTOutliers != 0) {
+	TRTratio = float( TRTHTHits + TRTHTOutliers) / float( TRTHits + TRTOutliers );
+        } else {
+            TRTratio = 0.0;
+        }
+    // }
+
+    pTau->setDetail(xAOD::TauJetParameters::TRT_NHT_OVER_NLT , TRTratio );
+    pTau->setDetail(xAOD::TauJetParameters::secMaxStripEt , energy_3phi[max] );
+    pTau->setDetail(xAOD::TauJetParameters::hadLeakEt , static_cast<float>( sumETCellsHad1 / ( pTau->track(0)->pt() ) ) );
+    pTau->setDetail(xAOD::TauJetParameters::sumEMCellEtOverLeadTrkPt , static_cast<float>( ( sumETCellsLAr / ( pTau->track(0)->pt() ) ) ) );
+
+    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    //delete the trackparemeters returned by tracktocalo
+    if (pTrk) delete pTrk;
+
+    return StatusCode::SUCCESS;
+}
+
+
+
+
diff --git a/Reconstruction/tauRec/src/TauGenericPi0Cone.cxx b/Reconstruction/tauRec/src/TauGenericPi0Cone.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6dd3de18e22dd01b1ea2e6a77175d1e98e4c2e19
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauGenericPi0Cone.cxx
@@ -0,0 +1,107 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauGenericPi0Cone.cxx
+// package:     Reconstruction/tauRec
+// authors:     Robert Clarke, Blake Burghgrave
+// date:        2014-01-04
+//
+//
+//-----------------------------------------------------------------------------
+
+#include <GaudiKernel/IToolSvc.h>
+#include <GaudiKernel/ListItem.h>
+
+#include "FourMomUtils/P4Helpers.h"
+#include "FourMom/P4EEtaPhiM.h"
+#include "Particle/TrackParticle.h"
+
+#include "tauRec/TauCandidateData.h"
+#include "tauEvent/TauCommonDetails.h"
+#include "tauEvent/TauJetParameters.h"
+
+#include "tauRec/TauGenericPi0Cone.h"
+#include "tauRec/TauTrackFilterUtils.h"
+
+#include "TLorentzVector.h"
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+
+TauGenericPi0Cone::TauGenericPi0Cone(const std::string &type,
+    const std::string &name,
+    const IInterface *parent) :
+TauToolBase(type, name, parent) {
+    declareInterface<TauToolBase > (this);
+}
+
+
+//-----------------------------------------------------------------------------
+// Destructor
+//-----------------------------------------------------------------------------
+
+TauGenericPi0Cone::~TauGenericPi0Cone() {
+}
+
+
+//-----------------------------------------------------------------------------
+// Initializer
+//-----------------------------------------------------------------------------
+
+StatusCode TauGenericPi0Cone::initialize() {
+    ATH_MSG_VERBOSE("TauGenericPi0Cone Initialising");
+
+    return StatusCode::SUCCESS;
+}
+
+
+//-----------------------------------------------------------------------------
+// Finalizer
+//-----------------------------------------------------------------------------
+
+StatusCode TauGenericPi0Cone::finalize() {
+    ATH_MSG_VERBOSE("TauGenericPi0Cone Finalizing");
+
+    return StatusCode::SUCCESS;
+}
+
+
+//-----------------------------------------------------------------------------
+// Execution
+//-----------------------------------------------------------------------------
+StatusCode TauGenericPi0Cone::execute(TauCandidateData *data) {
+    ATH_MSG_VERBOSE("TauGenericPi0Cone Executing");
+
+    xAOD::TauJet *pTau = data->xAODTau;
+
+    TLorentzVector tau;
+    tau.SetPtEtaPhiE(pTau->pt(),
+                     pTau->eta(),
+                     pTau->phi(),
+                     pTau->e());
+
+    int nProng = pTau->trackFilterProngs();
+    int flag = pTau->trackFilterQuality();
+    float pi0angle = 0.; //TODO sane default value
+
+    // Get pi0 cone
+    if(flag != 0){
+        int recProng = 0;
+        if((nProng == 3)||(nProng == 2)) recProng = 3;
+        if(nProng == 1) recProng = 1;
+        pi0angle = TauTrackFilterUtils::ComputePi0Cone(recProng,tau);
+     }
+
+    // Convert to dR.
+    m_pi0conedr = std::min(pi0angle*cosh(tau.Eta()), 0.2);
+
+    // Store result
+    pTau->setPi0ConeDR(m_pi0conedr);
+
+    return StatusCode::SUCCESS;
+}
+
diff --git a/Reconstruction/tauRec/src/TauPi0BonnClusterCreator.cxx b/Reconstruction/tauRec/src/TauPi0BonnClusterCreator.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8843a927e6071220de142fcc04d5a587e9f52a9f
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauPi0BonnClusterCreator.cxx
@@ -0,0 +1,602 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauPi0BonnClusterCreator.cxx
+// package:     Reconstruction/tauEvent
+// authors:     Benedict Winter, Will Davey
+// date:        2012-10-09
+//
+//-----------------------------------------------------------------------------
+
+#include <vector>
+
+#include "CaloUtils/CaloClusterStoreHelper.h"
+#include "CaloGeoHelpers/CaloSampling.h"
+#include "AnalysisUtils/AnalysisMisc.h"
+#include "FourMomUtils/P4Helpers.h"
+
+#include "tauRec/TauPi0BonnClusterCreator.h"
+
+#include "RecoToolInterfaces/IExtrapolateToCaloTool.h"
+
+using std::vector;
+using std::string;
+
+//-------------------------------------------------------------------------
+// Constructor
+//-------------------------------------------------------------------------
+
+TauPi0BonnClusterCreator::TauPi0BonnClusterCreator( 
+    const string& type,
+    const string& name,
+    const IInterface *parent) 
+
+    : TauToolBase(type, name, parent)
+    , m_trackToCaloTool("")
+    , m_cellContainerName("TauCommonPi0CellContainer") 
+    , m_inputPi0ClusterContainerName("TauPi0BonnSubtractedClusterContainer")
+    , m_outputPi0ClusterContainerName("TauPi0BonnClusterContainer")
+    , m_neutralPFOContainerName("TauPi0BonnNeutralPFOContainer")
+    , m_clusterEtCut(500.)
+{
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("ExtrapolateToCaloTool",         m_trackToCaloTool);
+    declareProperty("CellContainerName",             m_cellContainerName);
+    declareProperty("InputPi0ClusterContainerName",  m_inputPi0ClusterContainerName);
+    declareProperty("OutputPi0ClusterContainerName", m_outputPi0ClusterContainerName);
+    declareProperty("NeutralPFOContainerName",       m_neutralPFOContainerName);
+    declareProperty("ClusterEtCut",                  m_clusterEtCut);
+}
+
+//-------------------------------------------------------------------------
+// Destructor
+//-------------------------------------------------------------------------
+
+TauPi0BonnClusterCreator::~TauPi0BonnClusterCreator() 
+{
+}
+
+
+StatusCode TauPi0BonnClusterCreator::initialize() 
+{
+    CHECK( m_trackToCaloTool.retrieve() );
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauPi0BonnClusterCreator::eventInitialize(TauCandidateData * /*data*/) 
+{
+    // create new CaloClusterContainer 
+    // this container will later persistified
+    // so it will get ownership of the objects
+    m_pOutputPi0CaloClusterContainer = new xAOD::CaloClusterContainer(SG::OWN_ELEMENTS);
+    ATH_MSG_VERBOSE("record container " << m_outputPi0ClusterContainerName);
+    //---------------------------------------------------------------------
+    // Create container for Pi0
+    //---------------------------------------------------------------------
+    m_pOutputPi0CaloClusterContainer = CaloClusterStoreHelper::makeContainer(&*evtStore(),   
+									     m_outputPi0ClusterContainerName,    
+									     msg()                  
+									     );
+
+    //---------------------------------------------------------------------
+    // Create neutral PFO container
+    //---------------------------------------------------------------------
+    m_neutralPFOContainer = new xAOD::PFOContainer();
+    CHECK( evtStore()->record(m_neutralPFOContainer, m_neutralPFOContainerName ) );
+    m_neutralPFOAuxStore = new xAOD::PFOAuxContainer();
+    CHECK( evtStore()->record( m_neutralPFOAuxStore, m_neutralPFOContainerName + "Aux." ) );
+    m_neutralPFOContainer->setStore(m_neutralPFOAuxStore);
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauPi0BonnClusterCreator::execute(TauCandidateData *data) 
+{
+    xAOD::TauJet *pTau = data->xAODTau;
+
+    //---------------------------------------------------------------------
+    // only run shower subtraction on 1-5 prong taus 
+    //---------------------------------------------------------------------
+    if (pTau->nTracks() == 0 || pTau->nTracks() >5 ) {
+        return StatusCode::SUCCESS;
+    }
+    ATH_MSG_DEBUG("ClusterCreator: new tau. \tpt = " << pTau->pt() << "\teta = " << pTau->eta() << "\tphi = " << pTau->phi() << "\tnprongs = " << pTau->nTracks());
+
+    //---------------------------------------------------------------------
+    // get tau tracks
+    //---------------------------------------------------------------------
+    vector<const xAOD::TrackParticle*> tracks;
+    for(unsigned iTrack = 0; iTrack<pTau->nTracks();++iTrack){
+      const xAOD::TrackParticle* track = pTau->track(iTrack);
+      tracks.push_back(track);
+    }
+
+    //---------------------------------------------------------------------
+    // retrieve the CaloClusterContainer created by the CaloClusterMaker
+    //---------------------------------------------------------------------
+    const xAOD::CaloClusterContainer *pPi0ClusterContainer;
+    CHECK( evtStore()->retrieve(pPi0ClusterContainer, m_inputPi0ClusterContainerName) );
+
+    //---------------------------------------------------------------------
+    // extrapolate track to calo layers 
+    //---------------------------------------------------------------------
+    vector<vector<float> > tracksEtaAtSampling;
+    vector<vector<float> > tracksPhiAtSampling;
+    for(unsigned iTrack = 0; iTrack<pTau->nTracks();++iTrack){
+      const xAOD::TrackParticle* track = pTau->track(iTrack);
+      vector<float> trackEtaAtSampling;
+      vector<float> trackPhiAtSampling;
+      this->getExtrapolatedPositions(track,trackEtaAtSampling,trackPhiAtSampling);
+      tracksEtaAtSampling.push_back(trackEtaAtSampling);
+      tracksPhiAtSampling.push_back(trackPhiAtSampling);
+    }
+
+    //---------------------------------------------------------------------
+    // TODO: May want to use tau vertex in the future to calculate some cluster moments (DELTA_THETA, etc.).
+    // Doesn't help now, since all moments are calculated wrt 0.0.0 atm.
+    //---------------------------------------------------------------------
+
+
+    // Retrieve Ecal1 shots and match them to clusters
+    //---------------------------------------------------------------------
+    std::vector<const xAOD::PFO*> shotVector;
+    unsigned nShots = pTau->nShot_PFOs();
+    for(unsigned iShot=0;iShot<nShots;++iShot){
+        const xAOD::PFO* thisShot = pTau->shot_PFO(iShot);
+        shotVector.push_back( thisShot );
+    }
+    std::map<unsigned, xAOD::CaloCluster*> clusterToShotMap = getClusterToShotMap(shotVector, pPi0ClusterContainer, pTau);
+
+    xAOD::CaloClusterContainer::const_iterator clusterItr   (pPi0ClusterContainer->begin()),
+                                               clusterItrEnd(pPi0ClusterContainer->end());
+    for (; clusterItr != clusterItrEnd; ++clusterItr){
+        
+        // selection
+        if ((*clusterItr)->pt() < m_clusterEtCut)   continue;
+        // Cluster container has clusters for all taus.
+        // Only run on clusters that belong to this tau
+        if ((*clusterItr)->p4().DeltaR(pTau->p4()) > .4) continue;
+
+        // Get shots in this cluster. Need to use (CaloCluster*) (*clusterItr) 
+        // (not a copy!) since the pointer will otherwise be different than in clusterToShotMap
+        std::vector<unsigned> shotsInCluster = getShotsMatchedToCluster( shotVector, clusterToShotMap, (xAOD::CaloCluster*) (*clusterItr));
+
+        // Make a copy of the cluster to store in output container.
+        xAOD::CaloCluster* pPi0Cluster = new xAOD::CaloCluster( *(*clusterItr) );
+
+        // store pi0 calo cluster in the output container
+        m_pOutputPi0CaloClusterContainer->push_back(pPi0Cluster);
+
+        // Calculate input variables for fake supression. 
+        // Do this before applying the vertex correction, 
+        // since the position of the cluster in the 
+        // calorimeter is required.
+        float EM1CoreFrac = getEM1CoreFrac(pPi0Cluster);
+        float asymmetryInEM1WRTTrk = getAsymmetryInEM1WRTTrk(pPi0Cluster, tracksEtaAtSampling, tracksPhiAtSampling);
+        int NHitsInEM1 = getNPhotons(shotVector, shotsInCluster);
+        vector<int> NPosECellsInLayer = getNPosECells(pPi0Cluster);
+        vector<float> firstEtaWRTClusterPositionInLayer = get1stEtaMomWRTCluster(pPi0Cluster);
+        vector<float> secondEtaWRTClusterPositionInLayer = get2ndEtaMomWRTCluster(pPi0Cluster);
+
+        // Retrieve cluster moments that are used for fake supression and that are not stored in AOD
+        // for every cluster. Do this after applying the vertex correction, since the moments 
+        // (especcially DELTA_PHI and DELTA_THETA) must be calculated WRT the tau vertex
+        double CENTER_MAG = 0.0;
+        double FIRST_ETA = 0.0;
+        double SECOND_R = 0.0;
+        double SECOND_LAMBDA = 0.0;
+        double DELTA_PHI = 0.0;
+        double DELTA_THETA = 0.0;
+        double CENTER_LAMBDA = 0.0;
+        double LATERAL = 0.0;
+        double LONGITUDINAL = 0.0;
+        double ENG_FRAC_EM = 0.0;
+        double ENG_FRAC_MAX = 0.0;
+        double ENG_FRAC_CORE = 0.0;
+        double SECOND_ENG_DENS = 0.0;
+
+        // TODO: Replace numbers by human readable enums
+        if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 404, CENTER_MAG) ) ATH_MSG_WARNING("Couldn't retrieve CENTER_MAG moment. Set it to 0.");
+
+        if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 102, FIRST_ETA) )       ATH_MSG_WARNING("Couldn't retrieve FIRST_ETA moment. Set it to 0.");
+        if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 201, SECOND_R) )        ATH_MSG_WARNING("Couldn't retrieve SECOND_R moment. Set it to 0.");
+        if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 202, SECOND_LAMBDA) )   ATH_MSG_WARNING("Couldn't retrieve SECOND_LAMBDA moment. Set it to 0.");
+        if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 301, DELTA_PHI) )       ATH_MSG_WARNING("Couldn't retrieve DELTA_PHI moment. Set it to 0.");
+        if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 302, DELTA_THETA) )     ATH_MSG_WARNING("Couldn't retrieve DELTA_THETA moment. Set it to 0.");
+        if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 501, CENTER_LAMBDA) )   ATH_MSG_WARNING("Couldn't retrieve CENTER_LAMBDA moment. Set it to 0.");
+        if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 601, LATERAL) )         ATH_MSG_WARNING("Couldn't retrieve LATERAL moment. Set it to 0.");
+        if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 602, LONGITUDINAL) )    ATH_MSG_WARNING("Couldn't retrieve LONGITUDINAL moment. Set it to 0.");
+        if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 701, ENG_FRAC_EM) )     ATH_MSG_WARNING("Couldn't retrieve ENG_FRAC_EM moment. Set it to 0.");
+        if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 702, ENG_FRAC_MAX) )    ATH_MSG_WARNING("Couldn't retrieve ENG_FRAC_MAX moment. Set it to 0.");
+        if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 703, ENG_FRAC_CORE) )   ATH_MSG_WARNING("Couldn't retrieve ENG_FRAC_CORE moment. Set it to 0.");
+        if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 805, SECOND_ENG_DENS) ) ATH_MSG_WARNING("Couldn't retrieve SECOND_ENG_DENS moment. Set it to 0.");
+
+       	float E_EM1 = pPi0Cluster->eSample(CaloSampling::EMB1) + pPi0Cluster->eSample(CaloSampling::EME1);
+	      float E_EM2 = pPi0Cluster->eSample(CaloSampling::EMB2) + pPi0Cluster->eSample(CaloSampling::EME2);
+        
+        // create neutral PFO. Set BDTScore to dummy value <-1. The BDT score is calculated within TauPi0BonnSelector.cxx.
+        xAOD::PFO* neutralPFO = new xAOD::PFO();
+        m_neutralPFOContainer->push_back( neutralPFO );
+
+        // Create element link from tau to neutral PFO
+        ElementLink<xAOD::PFOContainer> PFOElementLink;
+        PFOElementLink.toContainedElement( *m_neutralPFOContainer, neutralPFO );
+        pTau->addCellBased_Neutral_PFOLink( PFOElementLink );
+
+        // Set PFO variables
+        ElementLink<xAOD::CaloClusterContainer> clusElementLink;
+        clusElementLink.toContainedElement( *m_pOutputPi0CaloClusterContainer, pPi0Cluster );
+        neutralPFO->setClusterLink( clusElementLink );
+        
+        neutralPFO->setP4( (float) pPi0Cluster->pt(), (float) pPi0Cluster->eta(), (float) pPi0Cluster->phi(), (float) pPi0Cluster->m());
+        neutralPFO->setBDTPi0Score( (float) -9999. );
+        neutralPFO->setCharge( 0. );
+
+        neutralPFO->setCenterMag( (float) CENTER_MAG);
+
+        neutralPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::nPi0, -1);
+        neutralPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::nPi0Proto, -1);
+
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_FIRST_ETA,       (float) FIRST_ETA);
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_SECOND_R,        (float) SECOND_R);
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_SECOND_LAMBDA,   (float) SECOND_LAMBDA);
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_DELTA_PHI,       (float) DELTA_PHI);
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_DELTA_THETA,     (float) DELTA_THETA);
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_CENTER_LAMBDA,   (float) CENTER_LAMBDA);
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_LATERAL,         (float) LATERAL);
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_LONGITUDINAL,    (float) LONGITUDINAL);
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_ENG_FRAC_EM,     (float) ENG_FRAC_EM);
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_ENG_FRAC_MAX,    (float) ENG_FRAC_MAX);
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_ENG_FRAC_CORE,   (float) ENG_FRAC_CORE);
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_SECOND_ENG_DENS, (float) SECOND_ENG_DENS);
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_energy_EM1,      (float) E_EM1);
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_energy_EM2,      (float) E_EM2);
+
+
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_EM1CoreFrac, EM1CoreFrac);
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_asymmetryInEM1WRTTrk, asymmetryInEM1WRTTrk);
+        neutralPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::cellBased_NHitsInEM1, NHitsInEM1);
+        neutralPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::cellBased_NPosECells_PS,  NPosECellsInLayer.at(0));
+        neutralPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::cellBased_NPosECells_EM1, NPosECellsInLayer.at(1));
+        neutralPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::cellBased_NPosECells_EM2, NPosECellsInLayer.at(2));
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_firstEtaWRTClusterPosition_EM1, firstEtaWRTClusterPositionInLayer.at(1));
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_firstEtaWRTClusterPosition_EM2, firstEtaWRTClusterPositionInLayer.at(2));
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_secondEtaWRTClusterPosition_EM1, secondEtaWRTClusterPositionInLayer.at(1));
+        neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_secondEtaWRTClusterPosition_EM2, secondEtaWRTClusterPositionInLayer.at(2));
+
+        // Store shot element links in neutral PFO
+        std::vector<ElementLink<xAOD::IParticleContainer> > shotlinks;
+        for(unsigned iShot = 0;iShot<shotsInCluster.size();++iShot){
+            ElementLink<xAOD::PFOContainer> shotPFOElementLink = pTau->shot_PFOLinks().at(shotsInCluster.at(iShot));
+            ElementLink<xAOD::IParticleContainer> shotElementLink;
+            shotPFOElementLink.toPersistent();
+            shotElementLink.resetWithKeyAndIndex( shotPFOElementLink.persKey(), shotPFOElementLink.persIndex() ); 
+            if (!shotElementLink.isValid()) ATH_MSG_WARNING("Created an invalid element link to xAOD track particle");
+            shotlinks.push_back(shotElementLink);
+        }
+        if(!neutralPFO->setAssociatedParticleLinks( xAOD::PFODetails::TauShot,shotlinks)) 
+            ATH_MSG_WARNING("Couldn't add shot links to neutral PFO!");
+    }
+    return StatusCode::SUCCESS;
+}
+
+
+StatusCode TauPi0BonnClusterCreator::eventFinalize(TauCandidateData *) 
+{
+    // pt sort container at the end of the event
+    // if(m_pOutputPi0CaloClusterContainer->size()) AnalysisUtils::Sort::pT(m_pOutputPi0CaloClusterContainer);
+
+    //----------------------------------------------------------------------
+    // Register cluster container in StoreGate
+    //----------------------------------------------------------------------
+    CHECK( CaloClusterStoreHelper::finalizeClusters(&(*evtStore()),
+                                                    m_pOutputPi0CaloClusterContainer,
+                                                    m_outputPi0ClusterContainerName,
+                                                    msg()));
+  
+    return StatusCode::SUCCESS;
+}
+
+// Functions used to calculate BDT variables other than those provided by the CaloClusterMomentsMaker
+float TauPi0BonnClusterCreator::getEM1CoreFrac(
+    const xAOD::CaloCluster* pi0Candidate)
+{
+    float coreEnergy=0.;
+    float sumEPosCellsEM1=0.;
+
+    const CaloClusterCellLink* theCellLink = pi0Candidate->getCellLinks();
+    CaloClusterCellLink::const_iterator cellInClusterItr  = theCellLink->begin();
+    CaloClusterCellLink::const_iterator cellInClusterItrE = theCellLink->end();
+    for(;cellInClusterItr!=cellInClusterItrE;++cellInClusterItr){
+        CaloCell* cellInCluster = (CaloCell*) *cellInClusterItr;
+        int sampling = cellInCluster->caloDDE()->getSampling();
+        if(sampling!=1 && sampling!=5) continue;
+        float cellE = cellInCluster->e() * cellInClusterItr.weight();
+        if(cellE<=0) continue;
+        sumEPosCellsEM1 += cellE;
+        float cellEtaWRTCluster = cellInCluster->eta()-pi0Candidate->eta();
+        float cellPhiWRTCluster = P4Helpers::deltaPhi(cellInCluster->phi(), pi0Candidate->phi());
+        if(fabs(cellPhiWRTCluster) > 0.05 || fabs(cellEtaWRTCluster) > 2 * 0.025/8.) continue;
+        coreEnergy+=cellE;
+    }
+    if(sumEPosCellsEM1<=0.) return 0.;
+    return coreEnergy/sumEPosCellsEM1;
+}
+
+// Function to determine asymmetry with respect to track. For > 1 track give smallest asymmetry.
+float TauPi0BonnClusterCreator::getAsymmetryInEM1WRTTrk(
+    const xAOD::CaloCluster* pi0Candidate, 
+    const vector<vector<float> > tracksEtaAtSampling,
+    const vector<vector<float> > tracksPhiAtSampling)
+{
+    float minAsymmetryInEM1WRTTrk=2.;  // minimum asymmetryWRT tracks
+    vector<vector<float> > asymmetriesInEM1WRTTrks;
+    vector<float> asymmetryInEM1WRTTrk;
+    asymmetryInEM1WRTTrk.push_back(0.); // here the energy in negative eta direction WRT the track will be stored
+    asymmetryInEM1WRTTrk.push_back(0.); // here the energy in positive eta direction WRT the track will be stored
+    asymmetryInEM1WRTTrk.push_back(0.); // here the energy in negative phi direction WRT the track will be stored
+    asymmetryInEM1WRTTrk.push_back(0.); // here the energy in positive phi direction WRT the track will be stored
+    for(unsigned iTrack = 0; iTrack<tracksEtaAtSampling.size();++iTrack){
+      asymmetriesInEM1WRTTrks.push_back(asymmetryInEM1WRTTrk);
+    }
+
+    float sumEPosCellsEM1=0.;
+    const CaloClusterCellLink* theCellLink = pi0Candidate->getCellLinks();
+    CaloClusterCellLink::const_iterator cellInClusterItr  = theCellLink->begin();
+    CaloClusterCellLink::const_iterator cellInClusterItrE = theCellLink->end();
+    for(;cellInClusterItr!=cellInClusterItrE;++cellInClusterItr){
+        CaloCell* cellInCluster = (CaloCell*) *cellInClusterItr;
+        int sampling = cellInCluster->caloDDE()->getSampling();
+        if(sampling!=1 && sampling!=5) continue;
+        float cellE = cellInCluster->e() * cellInClusterItr.weight();
+        if(cellE<=0) continue;
+        sumEPosCellsEM1 += cellE;
+        for(unsigned iTrack = 0; iTrack<tracksEtaAtSampling.size();++iTrack){
+            float cellEtaWRTTrack = cellInCluster->eta() - tracksEtaAtSampling.at(iTrack).at(sampling);
+            float cellPhiWRTTrack = P4Helpers::deltaPhi(cellInCluster->phi(), tracksPhiAtSampling.at(iTrack).at(sampling));
+
+            if(cellEtaWRTTrack<0) asymmetriesInEM1WRTTrks.at(iTrack).at(0)+=cellE;
+            else asymmetriesInEM1WRTTrks.at(iTrack).at(1)+=cellE;
+            if(cellPhiWRTTrack<0) asymmetriesInEM1WRTTrks.at(iTrack).at(2)+=cellE;
+            else asymmetriesInEM1WRTTrks.at(iTrack).at(3)+=cellE;
+        }
+    }
+    if(sumEPosCellsEM1<=0.) return 0.; // default value for clusters with no energy in EM1
+    // calculate asymmetry WRT the tracks and determine minimum asymmetry
+    for(unsigned iTrack = 0; iTrack<tracksEtaAtSampling.size();++iTrack){
+        for(unsigned int iEntry=0;iEntry<asymmetriesInEM1WRTTrks.at(iTrack).size();++iEntry){
+            asymmetriesInEM1WRTTrks.at(iTrack).at(iEntry)/=sumEPosCellsEM1;
+            if(asymmetriesInEM1WRTTrks.at(iTrack).at(iEntry)>=1.) asymmetriesInEM1WRTTrks.at(iTrack).at(iEntry)=0.999;
+        }
+        float asymmetryToThisTrack = fabs((asymmetriesInEM1WRTTrks.at(iTrack).at(1)-asymmetriesInEM1WRTTrks.at(iTrack).at(0))*
+                                          (asymmetriesInEM1WRTTrks.at(iTrack).at(3)-asymmetriesInEM1WRTTrks.at(iTrack).at(2)));
+        if(asymmetryToThisTrack<minAsymmetryInEM1WRTTrk) minAsymmetryInEM1WRTTrk = asymmetryToThisTrack;
+    }
+    return minAsymmetryInEM1WRTTrk;
+}
+
+
+// Do cluster to shot matching. 
+// A cluster is matched to a shot if the seed cell of the shot is in the cluster
+std::map<unsigned, xAOD::CaloCluster*> TauPi0BonnClusterCreator::getClusterToShotMap(
+    const std::vector<const xAOD::PFO*> shotVector, 
+    const xAOD::CaloClusterContainer* pPi0ClusterContainer,
+    xAOD::TauJet *pTau)
+{
+    std::map<unsigned, xAOD::CaloCluster*> clusterToShotMap;
+    for(unsigned iShot = 0;iShot<shotVector.size();++iShot){
+        int seedHash_int = -1;
+        if( shotVector.at(iShot)->attribute(xAOD::PFODetails::PFOAttributes::tauShots_seedHash, seedHash_int) == false) {
+            std::cout << "WARNING: Couldn't find seed hash. Set it to -1, no cluster will be associated to shot." << std::endl;
+        }
+        const IdentifierHash seedHash = (const IdentifierHash) seedHash_int; 
+        xAOD::CaloClusterContainer::const_iterator clusterItr   (pPi0ClusterContainer->begin()),
+                                                   clusterItrEnd(pPi0ClusterContainer->end());
+        float weightInCluster=-1.;
+        float weightInPreviousCluster=-1;
+        for (; clusterItr != clusterItrEnd; ++clusterItr){
+            xAOD::CaloCluster* cluster = (xAOD::CaloCluster*) (*clusterItr);
+            weightInCluster=-1.;
+            if (cluster->p4().Et() < m_clusterEtCut) continue; // Not interested in clusters that fail the Et cut
+            // Cluster container has clusters for all taus.
+            // Only run on clusters that belong to this tau
+            if (cluster->p4().DeltaR(pTau->p4()) > .4)  continue;
+            const CaloClusterCellLink* theCellLink = cluster->getCellLinks();
+            CaloClusterCellLink::const_iterator cellItr  = theCellLink->begin();
+            CaloClusterCellLink::const_iterator cellItrE = theCellLink->end();
+            for(;cellItr!=cellItrE; ++cellItr){
+                CaloCell* cellInCluster = (CaloCell*) *cellItr;
+                // Check if seed cell is in cluster.
+                if(cellInCluster->caloDDE()->calo_hash()!=seedHash) continue;
+                weightInCluster = cellItr.weight();
+                // found cell, no need to loop over other cells
+                break;
+            }
+            if(weightInCluster<0) continue;
+            // Check if cell was already found in a previous cluster
+            if(weightInPreviousCluster<0){
+                // Cell not found in a previous cluster. 
+                // Have to check whether cell is shared with other cluster
+                clusterToShotMap[iShot] = cluster;
+                weightInPreviousCluster = weightInCluster;
+            }
+            else{
+                // Cell has been found in a previous cluster
+                // assign shot to this cluster if it has larger weight for the cell
+                // otherwise the shots keeps assigned to the previous cluster
+                if(weightInCluster>weightInPreviousCluster){
+                    clusterToShotMap[iShot] = cluster;
+                }
+                // No need to loop over other clusters as cells can not be shared by more than two clusters
+                break;
+            }
+        }
+    }
+    return clusterToShotMap;
+}
+
+std::vector<unsigned> TauPi0BonnClusterCreator::getShotsMatchedToCluster(
+    const std::vector<const xAOD::PFO*> shotVector,
+    std::map<unsigned, xAOD::CaloCluster*> clusterToShotMap, 
+    xAOD::CaloCluster* pPi0Cluster)
+{
+    std::vector<unsigned> shotsMatchedToCluster;
+    for(unsigned iShot = 0;iShot<shotVector.size();++iShot){
+        std::map<unsigned, xAOD::CaloCluster*>::iterator itr = clusterToShotMap.find(iShot);
+        if(itr==clusterToShotMap.end()) continue;
+        if(itr->second!=pPi0Cluster) continue;
+        shotsMatchedToCluster.push_back(iShot);
+    }
+    return shotsMatchedToCluster;
+}
+
+int TauPi0BonnClusterCreator::getNPhotons(
+    const std::vector<const xAOD::PFO*> shotVector,
+    std::vector<unsigned> shotsInCluster
+    )
+{
+    int nPhotons = 0;
+    for(unsigned iShot = 0;iShot<shotsInCluster.size();++iShot){
+        int curNPhotons=0;
+        if(shotVector.at(shotsInCluster.at(iShot))->attribute(xAOD::PFODetails::PFOAttributes::tauShots_nPhotons,curNPhotons) == false)
+            ATH_MSG_WARNING("Can't find NHitsInEM1. Set it to 0.");
+        nPhotons+=curNPhotons;
+    }
+    return nPhotons;
+}
+
+vector<int> TauPi0BonnClusterCreator::getNPosECells(
+    const xAOD::CaloCluster* pi0Candidate)
+{
+    vector<int> nPosECellsInLayer(3,0); // 3 layers initialised with 0 +ve cells
+
+    const CaloClusterCellLink* theCellLink = pi0Candidate->getCellLinks();
+    CaloClusterCellLink::const_iterator cellInClusterItr  = theCellLink->begin();
+    CaloClusterCellLink::const_iterator cellInClusterItrE = theCellLink->end();
+
+    for(;cellInClusterItr!=cellInClusterItrE; ++cellInClusterItr){
+        CaloCell* cellInCluster = (CaloCell*) *cellInClusterItr;
+        int sampling = cellInCluster->caloDDE()->getSampling();
+        // Get cell layer: PSB and PSE belong to layer 0,  
+        // EMB1 and EME1 to layer 1, EMB2 and EME2 to layer 2. 
+        // Cells in EMB3 and EME3 have already been removed 
+        // during subtraction.
+        int cellLayer = sampling%4;  
+        if(cellInCluster->e() > 0) nPosECellsInLayer[cellLayer]++;
+    }
+    return nPosECellsInLayer;
+}
+
+
+vector<float> TauPi0BonnClusterCreator::get1stEtaMomWRTCluster(
+    const xAOD::CaloCluster* pi0Candidate)
+{
+    vector<float> firstEtaWRTClusterPositionInLayer (4, 0.);  //init with 0. for 0-3 layers
+    vector<float> sumEInLayer (4, 0.); //init with 0. for 0-3 layers
+
+    const CaloClusterCellLink* theCellLink = pi0Candidate->getCellLinks();
+    CaloClusterCellLink::const_iterator cellInClusterItr  = theCellLink->begin();
+    CaloClusterCellLink::const_iterator cellInClusterItrE = theCellLink->end();
+
+    for(;cellInClusterItr!=cellInClusterItrE;++cellInClusterItr){
+        CaloCell* cellInCluster = (CaloCell*) *cellInClusterItr;
+        int sampling = cellInCluster->caloDDE()->getSampling();
+        // Get cell layer: PSB and PSE belong to layer 0,  
+        // EMB1 and EME1 to layer 1, EMB2 and EME2 to layer 2. 
+        // Cells in EMB3 and EME3 (layer 3) have already been removed 
+        // during subtraction.
+        int cellLayer = sampling%4;
+        
+        float cellEtaWRTClusterPos=cellInCluster->eta()-pi0Candidate->eta();
+        float cellE=cellInCluster->e();
+        if(cellE<=0) continue;
+        firstEtaWRTClusterPositionInLayer[cellLayer]+=cellEtaWRTClusterPos*cellE;
+        sumEInLayer[cellLayer]+=cellE;
+    }
+
+    for(int iLayer=0;iLayer<4;++iLayer){
+        if(sumEInLayer[iLayer]!=0) 
+            firstEtaWRTClusterPositionInLayer[iLayer]/=fabs(sumEInLayer[iLayer]);
+        else firstEtaWRTClusterPositionInLayer[iLayer]=0.;
+    }
+    return firstEtaWRTClusterPositionInLayer;
+}
+
+vector<float> TauPi0BonnClusterCreator::get2ndEtaMomWRTCluster(
+    const xAOD::CaloCluster* pi0Candidate)
+{
+      vector<float> secondEtaWRTClusterPositionInLayer (4, 0.); //init with 0. for 0-3 layers
+      vector<float> sumEInLayer (4, 0.); //init with 0. for 0-3 layers
+
+      const CaloClusterCellLink* theCellLink = pi0Candidate->getCellLinks();
+      CaloClusterCellLink::const_iterator cellInClusterItr  = theCellLink->begin();
+      CaloClusterCellLink::const_iterator cellInClusterItrE = theCellLink->end();
+
+      for(;cellInClusterItr!=cellInClusterItrE;++cellInClusterItr){
+            CaloCell* cellInCluster = (CaloCell*) *cellInClusterItr;
+            int sampling = cellInCluster->caloDDE()->getSampling();
+            // Get cell layer: PSB and PSE belong to layer 0,  
+            // EMB1 and EME1 to layer 1, EMB2 and EME2 to layer 2. 
+            // Cells in EMB3 and EME3 (layer 3) have already been removed 
+            // during subtraction.
+            int cellLayer = sampling%4;
+
+            float cellEtaWRTClusterPos=cellInCluster->eta()-pi0Candidate->eta();
+            float cellE=cellInCluster->e();
+            if(cellE<=0) continue;
+            secondEtaWRTClusterPositionInLayer[cellLayer]+=cellEtaWRTClusterPos*cellEtaWRTClusterPos*cellE;
+            sumEInLayer[cellLayer]+=cellE;
+      }
+
+      for(int iLayer=0;iLayer<4;++iLayer){
+            if(sumEInLayer[iLayer]!=0) 
+                secondEtaWRTClusterPositionInLayer[iLayer]/=fabs(sumEInLayer[iLayer]);
+            else secondEtaWRTClusterPositionInLayer[iLayer]=0.;
+      }
+      return secondEtaWRTClusterPositionInLayer;
+}
+
+void TauPi0BonnClusterCreator::getExtrapolatedPositions(
+    const xAOD::TrackParticle * track,
+    vector<float> &trackToCaloEta,
+    vector<float> &trackToCaloPhi)
+{
+    for (int layer = 0 ; layer != CaloCell_ID::MINIFCAL0; ++layer) {
+        // Only need to extrapolate to Ecal1 (samplings 1 and 5)
+        if(layer!=1 && layer!=5){
+          trackToCaloEta.push_back(-99999.);
+          trackToCaloPhi.push_back(-99999.);
+          continue;
+        }
+        ATH_MSG_DEBUG( "Try extrapolation of track with pt = " << track->pt() << ", eta " << track->eta() << ", phi" << track->phi() << " to layer " << layer);
+        // extrapolate track to layer 
+        const Trk::TrackParameters* param_at_calo = 0;
+        param_at_calo = m_trackToCaloTool->extrapolate(
+                *track,
+                (CaloCell_ID::CaloSample) layer,
+                0.0, Trk::alongMomentum, Trk::pion);
+
+        // store if track extrapolation successful, else use dummy values 
+        if(param_at_calo){
+            ATH_MSG_DEBUG( "Extrapolated track with eta=" << track->eta()
+                            << " phi="<<track->phi()
+                            << " to eta=" << param_at_calo->position().eta()
+                            << " phi="<<param_at_calo->position().phi() 
+                            );
+            trackToCaloEta.push_back(param_at_calo->position().eta());
+            trackToCaloPhi.push_back(param_at_calo->position().phi());
+            delete param_at_calo;
+        }
+        else {
+            ATH_MSG_DEBUG( "Could not extrapolate track with eta = " << track->eta()
+                            << " phi=" << track->phi() 
+                            );
+            trackToCaloEta.push_back(-99999.); //Use something huge to flag the
+            trackToCaloPhi.push_back(-99999.); //track as useless
+        }
+    }
+}
+
diff --git a/Reconstruction/tauRec/src/TauPi0BonnCreateROI.cxx b/Reconstruction/tauRec/src/TauPi0BonnCreateROI.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4c824dc37bc4146503ea3fc75d0b144f343e88ae
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauPi0BonnCreateROI.cxx
@@ -0,0 +1,763 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauPi0BonnCreateROI.cxx
+// package:     Reconstruction/tauEvent
+// authors:     Will Davey
+// date:        2012-10-09
+//
+//-----------------------------------------------------------------------------
+
+#include <TString.h>
+#include <TH1.h>
+
+#include "GaudiKernel/IToolSvc.h"
+
+#include "PathResolver/PathResolver.h"
+#include "CaloEvent/CaloCellContainer.h"
+#include "CaloEvent/CaloClusterContainer.h"
+#include "CaloIdentifier/CaloCell_ID.h"
+#include "CaloUtils/CaloCellList.h"
+#include "AthContainers/OwnershipPolicy.h"
+#include "NavFourMom/INavigable4MomentumCollection.h"
+
+#include "xAODCaloEvent/CaloCluster.h"
+
+#include "tauRec/TauPi0BonnCreateROI.h"
+#include "tauRec/TauPi0BonnParser.h"
+
+#include "tauEvent/TauPi0Details.h"
+#include "tauEvent/TauShot.h"
+
+#include "CaloInterface/IHadronicCalibrationTool.h"
+#include "RecoToolInterfaces/IExtrapolateToCaloTool.h"
+#include "CaloInterface/ICaloCellMakerTool.h"
+#include "CaloIdentifier/CaloCell_ID.h"
+
+using std::max;
+using std::min;
+using std::vector;
+using std::string;
+//using xAOD::PFO; // required for subtration in EM1
+
+
+//-------------------------------------------------------------------------
+// Constructor
+//-------------------------------------------------------------------------
+
+TauPi0BonnCreateROI::TauPi0BonnCreateROI(   const string& type,
+                                            const string& name,
+                                            const IInterface *parent) 
+    : TauToolBase(type, name, parent)
+    , m_caloWeightTool("H1WeightToolCSC12Generic")
+    , m_trackToCaloTool("")
+    , m_cellMakerTool("")
+    , m_calo_dd_man(NULL)
+    , m_calo_id(NULL)
+    , m_latParser(new TauPi0BonnParser())
+    , m_caloCellContainerName("AllCalo")
+    , m_clusterContainerName("CaloCalTopoCluster")
+    , m_pPi0CellContainer(NULL)
+    , m_pi0CellContainerName("TauCommonPi0CellContainer")
+    , m_chargedPFOContainerName("TauPi0BonnChargedPFOContainer")
+{
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("CaloWeightTool", m_caloWeightTool);
+    declareProperty("ExtrapolateToCaloTool", m_trackToCaloTool);
+    declareProperty("CellMakerTool", m_cellMakerTool);
+    
+    declareProperty("CaloCellContainerName",   m_caloCellContainerName); // TODO: May be replaced using tau clusters
+    declareProperty("ClusterContainerName",    m_clusterContainerName);   // TODO: May be replaced using tau clusters
+    declareProperty("Pi0CellContainerName",    m_pi0CellContainerName);
+    declareProperty("ChargedPFOContainerName", m_chargedPFOContainerName);
+
+    declareProperty("LatParFile", m_latParFile );
+}
+
+//-------------------------------------------------------------------------
+// Destructor
+//-------------------------------------------------------------------------
+
+TauPi0BonnCreateROI::~TauPi0BonnCreateROI() {
+}
+
+StatusCode TauPi0BonnCreateROI::initialize() {
+    
+    // retrieve tools
+    ATH_MSG_DEBUG( "Retrieving tools" );
+    CHECK( m_caloWeightTool.retrieve() );
+    CHECK( m_trackToCaloTool.retrieve() );
+    CHECK( m_cellMakerTool.retrieve() );
+
+    // initialize calo cell geo
+    m_calo_dd_man  = CaloDetDescrManager::instance();
+    m_calo_id      = m_calo_dd_man->getCaloCell_ID();
+
+
+    ////////////////////////////////////////////////////////////
+    // Load lateral parameterisation 
+    ////////////////////////////////////////////////////////////
+    // check file given for lateral shower parameteristaion 
+    if( m_latParFile == "" ){
+        ATH_MSG_ERROR( "No lateral shower parameterisation given" );
+        return StatusCode::FAILURE;
+    }
+    // parse lateral config file 
+    m_latParser->parseROOTFile( PathResolver::find_file(m_latParFile, "DATAPATH") );
+    
+    // set addresses of all varaibles that can be used in the para.
+    m_latParser->setVar( "PT",     m_pt ); 
+    m_latParser->setVar( "ABSETA", m_abseta); 
+    m_latParser->setVar( "HADF",   m_hadf); 
+    m_latParser->setVar( "SAMP",   m_sampling); 
+
+    // hadf bot used atm. TODO: REMOVE?
+    m_hadf = 0.;
+
+    // check that parser loaded correctly, and that the required 
+    // variables are configured
+    if( !m_latParser->checkInitialisationStatus() ){
+        ATH_MSG_ERROR( "Failure loading lateral shower parameterisation" );
+        ATH_MSG_ERROR( "Parser stream: " << m_latParser->getStream() );
+        return StatusCode::FAILURE;
+    }
+
+    // Create vector with default values
+    for (int layer = 0 ; layer != CaloCell_ID::FCAL0; ++layer) {
+        m_defaultValues.push_back(-10.);
+        m_defaultValuesZero.push_back(0.);
+    } 
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauPi0BonnCreateROI::eventInitialize(TauCandidateData * /*data*/) {
+
+    
+    const CaloCell_ID* cellID;
+    if((detStore()->retrieve(cellID)).isFailure()){
+        ATH_MSG_ERROR("Unable to retrieve caloCell_ID helper from DetectorStore");
+        return StatusCode::FAILURE;
+    }
+
+    // Get hash range
+    IdentifierHash hashMax;
+    hashMax = cellID->calo_cell_hash_max();
+    ATH_MSG_VERBOSE("CaloCell Hash Max: " << hashMax);
+
+    // Reset addedCellsMap
+    m_addedCellsMap.clear();
+    for (unsigned i = 0; i < hashMax; i++) {
+        m_addedCellsMap.push_back(NULL);
+    }
+
+    // Reset hist maps
+    m_trackHistMapBarrel.clear();
+    m_trackHistMapEndcap.clear();
+
+    //---------------------------------------------------------------------
+    // Create CustomCellContainer and register in StoreGate
+    //---------------------------------------------------------------------
+    m_pPi0CellContainer = new CaloCellContainer(SG::OWN_ELEMENTS);
+    CHECK( evtStore()->record(m_pPi0CellContainer, m_pi0CellContainerName) );
+
+    // symlink as INavigable4MomentumCollection (as in CaloRec/CaloCellMaker)
+    CHECK(evtStore()->symLink(m_pPi0CellContainer, static_cast<INavigable4MomentumCollection*> (0)));
+
+    //---------------------------------------------------------------------
+    // Create charged PFO container
+    //---------------------------------------------------------------------
+    m_chargedPFOContainer = new xAOD::PFOContainer();
+    CHECK( evtStore()->record(m_chargedPFOContainer, m_chargedPFOContainerName ) );
+    m_chargedPFOAuxStore = new xAOD::PFOAuxContainer();
+    CHECK( evtStore()->record( m_chargedPFOAuxStore, m_chargedPFOContainerName + "Aux." ) );
+    m_chargedPFOContainer->setStore(m_chargedPFOAuxStore);
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauPi0BonnCreateROI::execute(TauCandidateData *data) {
+
+    xAOD::TauJet *pTau = data->xAODTau;
+
+    // Any tau needs to have PFO vectors. Set empty vectors before nTrack cut
+    vector<ElementLink<xAOD::PFOContainer> > empty;
+    pTau->setCellBased_Charged_PFOLinks(empty);
+    pTau->setCellBased_Neutral_PFOLinks(empty);
+    pTau->setCellBased_Pi0_PFOLinks(empty);
+
+    // Any tau needs to have PanTauCellBasedProto 4mom. Set it to 0 before nTrack cut
+    pTau->setP4(xAOD::TauJetParameters::PanTauCellBasedProto, 0.0, 0.0, 0.0, 0.0);
+
+    //---------------------------------------------------------------------
+    // only run shower subtraction on 1-5 prong taus 
+    //---------------------------------------------------------------------
+    if (pTau->nTracks() == 0 || pTau->nTracks() >5 ) {
+        return StatusCode::SUCCESS;
+    }
+    ATH_MSG_DEBUG("new tau. \tpt = " << pTau->pt() << "\teta = " << pTau->eta() << "\tphi = " << pTau->phi() << "\tnprongs = " << pTau->nTracks());
+
+    //---------------------------------------------------------------------
+    // get tau tracks
+    //---------------------------------------------------------------------
+    vector<const xAOD::TrackParticle*> tracks;
+    for(unsigned iTrack = 0; iTrack<pTau->nTracks();++iTrack){
+        const xAOD::TrackParticle* track = pTau->track(iTrack);
+        tracks.push_back(track);
+    }
+
+    //---------------------------------------------------------------------
+    // retrieve cells around tau 
+    //---------------------------------------------------------------------
+    
+    // get all calo cell container
+    const CaloCellContainer *pCellContainer = NULL;
+    CHECK( evtStore()->retrieve(pCellContainer, m_caloCellContainerName) );
+    
+    // get only EM cells within dR<0.2
+    vector<CaloCell_ID::SUBCALO> emSubCaloBlocks;
+    emSubCaloBlocks.push_back(CaloCell_ID::LAREM);
+    boost::scoped_ptr<CaloCellList> pCells(new CaloCellList(pCellContainer,emSubCaloBlocks)); 
+
+    // TODO: change hardcoded 0.2 to tau cone variable, (or func. from TauJet?)
+    pCells->select(pTau->eta(), pTau->phi(), 0.4); 
+
+    //---------------------------------------------------------------------
+    // prepare extrapolation of tracks to calo layers 
+    //---------------------------------------------------------------------
+    // clear vectors related to track extrapolation
+    // have to do that for each tau so it cannot be done in eventInitialize,
+    // which is called once per event (and not once per tau)
+    m_tracksEtaAtSampling.clear();
+    m_tracksPhiAtSampling.clear();
+    m_extrapolatedSamplings.clear();
+    // Fill with default values
+    for(int layer = 0 ; layer != CaloCell_ID::FCAL0; ++layer) {
+         m_extrapolatedSamplings.push_back(false);
+    }
+    //vector<float> E_sub_track;
+    for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){
+        m_tracksEtaAtSampling.push_back( m_defaultValues );
+        m_tracksPhiAtSampling.push_back( m_defaultValues );
+        //E_sub_track.push_back( 0. );
+    }
+
+    //---------------------------------------------------------------------
+    // get energy in HCal associated to the different tracks
+    //---------------------------------------------------------------------
+    const xAOD::CaloClusterContainer* clusterContainer = NULL;
+    CHECK( evtStore()->retrieve( clusterContainer, m_clusterContainerName ) );
+
+    vector<double> EestInEcal = this->getEstEcalEnergy(tracks,clusterContainer,pTau);
+
+    //Create charged PFOs
+    for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){
+        const xAOD::TrackParticle* track = tracks.at(iTrack);
+        xAOD::PFO* chargedPFO = new xAOD::PFO();
+        m_chargedPFOContainer->push_back(chargedPFO);
+        ElementLink<xAOD::TrackParticleContainer> myTrackLink = pTau->trackLinks().at(iTrack);
+        if(!chargedPFO->setTrackLink(myTrackLink)) ATH_MSG_WARNING("Could not add Track to PFO");
+        chargedPFO->setCharge(track->charge());
+        chargedPFO->setP4(track->pt(),track->eta(),track->phi(),track->m());
+        // Create element link from tau to charged PFO
+        ElementLink<xAOD::PFOContainer> PFOElementLink;
+        PFOElementLink.toContainedElement( *m_chargedPFOContainer, chargedPFO );
+        pTau->addCellBased_Charged_PFOLink( PFOElementLink );
+        // Store energy to subtract/subtracted for the track in CenterMag variable. This variables is otherwise never used for charged PFOs
+        chargedPFO->setCenterMag( (float) EestInEcal.at(iTrack));
+    }
+
+    // Optional: Subtraction in EM1 (part 1 of 3)
+    // FIXME: xAOD migration of subtration in EM1
+    /*
+    //---------------------------------------------------------------------
+    // get cells in EM1 associated to the different tracks
+    //---------------------------------------------------------------------
+    std::vector<IdentifierHash> pipmCellHash;
+    const std::vector<TauShot*> shotVector = pPi0Details->shotVector();
+
+    for(unsigned iShot = 0;iShot<shotVector.size();++iShot){
+        TauShot* currentShot = shotVector.at(iShot);
+        const CaloCell* seedCell = currentShot->seedCell();
+
+        int samp = seedCell->caloDDE()->getSampling();
+        double seedEta = seedCell->eta();
+
+        // Don't match shots in crack region. Cells are so large that pi0s are likely to be in the same cell.
+        if( (samp == 1 && fabs(seedEta)>1.4) || (samp == 5 && fabs(seedEta) < 1.5) ) continue;
+
+        // Subtract 3 cells
+        double shotPt = currentShot->pt3();
+
+        for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){
+            // Do not match shots to tracks, which have E_est < shotPt
+            if(EestInEcal.at(iTrack)<shotPt) continue;
+
+            // Do not match shots to tracks that have shotPt > 20% of the track pt. 
+            // The shot is unlikely to come from the charged pion in this case
+            double maxFrac = 0.20;
+            if(tracks.at(iTrack)->pt() * maxFrac < shotPt) continue;
+
+            // check if tracks have been extrapolated to this sampling. Do so if this is not the case
+            if(m_extrapolatedSamplings.at(samp)==false){
+                this->getExtrapolatedPositions(tracks,samp);
+                ATH_MSG_DEBUG("Extr to layer " << samp << "\teta = " << m_tracksEtaAtSampling.at(iTrack).at(samp) << "\tphi = " << m_tracksPhiAtSampling.at(iTrack).at(samp));
+                m_extrapolatedSamplings.at(samp)=true;
+            }
+            // Check if shot is close to the extrapolated track
+            double AbsDEta = fabs( seedEta - m_tracksEtaAtSampling.at(iTrack).at(samp));
+            double AbsDPhi = fabs( seedCell->phi() - m_tracksPhiAtSampling.at(iTrack).at(samp)); 
+            double cellWidthEta = seedCell->caloDDE()->deta();
+            double cellWidthPhi = seedCell->caloDDE()->dphi();
+            double allowedDev = 0.001;
+            if( (AbsDEta > cellWidthEta/2.+allowedDev) || (AbsDPhi > cellWidthPhi/2.+allowedDev) ) continue;
+
+            // Assign shot to track
+
+            // Store shot cells in pipmCellHash
+            double shotE = 0.;
+            std::vector<std::vector<const CaloCell*> > shotCells = currentShot->getCellVector(m_calo_id);
+            int nCells_eta = shotCells.at(0).size();
+            int seedIndex = nCells_eta/2;
+            int windowSize = 3; // must be 1, 3 or 5
+            if( windowSize%2!=1 && windowSize > nCells_eta) ATH_MSG_WARNING("Set window size for subtractionin EM1 properly! No energy will be subtracted in EM1");
+            for(int iCell = 0; iCell != nCells_eta; ++iCell ){
+                if(fabs(iCell-seedIndex)>windowSize/2) continue;
+                double wtCell0=0.;
+                double wtCell1=0.;
+                if(shotCells.at(0).at(iCell) != NULL){
+                    wtCell0 = m_caloWeightTool->wtCell(shotCells.at(0).at(iCell));
+                    shotE+=shotCells.at(0).at(iCell)->e()*wtCell0;
+                    pipmCellHash.push_back(shotCells.at(0).at(iCell)->caloDDE()->calo_hash());
+                }
+                if(shotCells.at(1).at(iCell) != NULL){
+                    wtCell1 = m_caloWeightTool->wtCell(shotCells.at(1).at(iCell));
+                    shotE+=shotCells.at(1).at(iCell)->e()*wtCell1;
+                    pipmCellHash.push_back(shotCells.at(1).at(iCell)->caloDDE()->calo_hash());
+                }
+            }
+            // Reduce EestInEcal by shot energy. ShotE is slightly more preciese than shotPt*cosh(currentShot->cluster()->eta()) (difference<1MeV)
+            EestInEcal.at(iTrack) -= shotE;
+            // Set number of photons in shot to 0.
+            currentShot->setNPhotons(0);
+            ATH_MSG_DEBUG("Assigned shot " << iShot << " to track " << iTrack << ". \tshotE = "<< shotE << "\tshotEta = " << seedEta << "\tshotPhi = " << seedCell->phi());
+        }
+    }
+    */
+
+    //---------------------------------------------------------------------
+    // Start creating output container:
+    // PS:  Don't do subtraction, just put cells in output container
+    // EM1: Set energies of cells to 0 that have been matched to a track. Put cells in output container.
+    // EM2: Sum up subtraction weights for each track. Have to normalize and subtract after this loop.
+    //---------------------------------------------------------------------
+
+    // Create vectors that will be used in a second loop over EM2 cells, only
+    // vector of cells
+    std::vector<const CaloCell*> EM2Cells;
+    // vector of lateral weights for each cell and each track. Cells are in same order as in EM2Cells vector
+    std::vector<std::vector<double> > cellSubWeights;
+    // vector of sum of lateral weights for each track. Will be used for the normalization
+    std::vector<double> sumCellSubWeights;
+    for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){
+        sumCellSubWeights.push_back(0.);
+    }
+
+    CaloCellList::list_iterator cellItr(pCells->begin()), cellItrE(pCells->end());
+    for(; cellItr != cellItrE; ++cellItr) {
+        const CaloCell* cell = (*cellItr);
+
+        // get cell sampling
+        int samp = cell->caloDDE()->getSampling();
+
+        // only keep cells that are in PS, EM1 and EM2.
+        if(samp>=7 || samp == 3 ) continue;
+
+        if( samp!=2 && samp != 6 ){ // PS and EM1
+            // Optional: Subtraction in EM1 (part 2 of 3)
+            /*
+            // Check if cell is in EM1 and if it is matched to a track
+            bool isPipmCell = false;
+            if(samp == 1 || samp == 5){
+                //Ask cell for it's hash
+                const IdentifierHash cellHash = cell->caloDDE()->calo_hash();
+
+                for(unsigned iPipmCellHash=0;iPipmCellHash<pipmCellHash.size();++iPipmCellHash){
+                    if(pipmCellHash.at(iPipmCellHash)==cellHash){
+                        ATH_MSG_DEBUG("Set cell energy to 0. " << "eta = " << cell->eta() << "\tphi = " << cell->phi() << "\tE = " << cell->e());
+                        isPipmCell = true;
+                        break;
+                    }
+                }
+            }
+            */
+            double subtractedEnergy = 0.;
+
+            // Optional: Subtraction in EM1 (part 3 of 3)
+            // if(isPipmCell == true) subtractedEnergy = cell->e();
+
+            // Store cell in output container
+            storeCell(cell, subtractedEnergy);
+        }
+        else{ // EM2
+
+            // Current procedure in crack region: Linear Interpolation from 1.375 to 1.475 
+            double interpolationFactorForCrack = 1.;
+            double crackMax = 1.475;
+            double crackMin = 1.375;
+            double crackW   = crackMax - crackMin;
+            if(samp!=0 && samp<4 && fabs(cell->eta())>crackMin)
+                interpolationFactorForCrack=1.-(fabs(cell->eta())-crackMin)/crackW;
+            if(samp>3  && fabs(cell->eta())<crackMax)
+                interpolationFactorForCrack=1.-(crackMax-fabs(cell->eta()))/crackW;
+
+            // Store weights of this cell for each track
+            vector<double> thisCellSubWeights;
+            double sumThisCellSubWeights = 0.;
+            for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){
+                // Don't need to determine weights if no energy is to be subtracted for this track
+                if( EestInEcal.at(iTrack)==0. ){
+                    thisCellSubWeights.push_back(0.);
+                    continue;
+                }
+
+                // Get info on track
+                const xAOD::TrackParticle* track = tracks.at(iTrack);
+                
+                // check if tracks have been extrapolated to this sampling. Do so if this is not the case
+                if(m_extrapolatedSamplings.at(samp)==false){
+                    this->getExtrapolatedPositions(tracks,samp);
+                    ATH_MSG_DEBUG("Extr to layer " << samp << "\teta = " << m_tracksEtaAtSampling.at(iTrack).at(samp) << "\tphi = " << m_tracksPhiAtSampling.at(iTrack).at(samp));
+                    m_extrapolatedSamplings.at(samp)=true;
+                }
+
+                // set extrapolated track direction
+                TLorentzVector extTrack;
+
+                extTrack.SetPtEtaPhiE(track->pt(), m_tracksEtaAtSampling.at(iTrack).at(samp), m_tracksPhiAtSampling.at(iTrack).at(samp), track->e());
+
+                // get eta/phi distance of cell to track
+                double deltaEta = extTrack.Eta()-cell->eta();
+                double deltaPhi = TVector2::Phi_mpi_pi( extTrack.Phi() - cell->phi());
+
+                // TODO:
+                // - Determine lateral weight using TH1
+                double cellWidthEta = cell->caloDDE()->deta();
+                double cellWidthPhi = cell->caloDDE()->dphi();
+                double cellSubWeight = getLatWeight(samp, deltaEta, deltaPhi, cellWidthEta, cellWidthPhi, iTrack, track);
+
+
+                // Get final weight by multiplying with interpolationFactorForCrack
+                cellSubWeight*=interpolationFactorForCrack;
+                sumCellSubWeights.at(iTrack)+=cellSubWeight;
+                thisCellSubWeights.push_back(cellSubWeight);
+                sumThisCellSubWeights+=cellSubWeight;
+            }
+            if(sumThisCellSubWeights == 0.){
+                // No need to run subtraction in the second loop
+                storeCell(cell, 0.);
+            }
+            else{
+                EM2Cells.push_back(cell);
+                cellSubWeights.push_back(thisCellSubWeights);
+            }
+        }
+    }
+    // Loop over EM2 cells. Subtract energy assigned to the cell and store it in the output cell container. 
+    for(unsigned iCell=0; iCell!= EM2Cells.size();++iCell){
+        const CaloCell* cell = EM2Cells.at(iCell);
+
+        // Get cell weight 
+        double wtCell = m_caloWeightTool->wtCell(cell);
+        // wtCell=0 (happens very rarely)  would cause a FPE later
+        if( wtCell == 0. ) continue;
+
+        // Determine how much energy to subtract
+        double subtractedEnergy = 0.;
+        for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){
+            if(EestInEcal.at(iTrack)==0. || sumCellSubWeights.at(iTrack)==0.) continue;
+            subtractedEnergy+=EestInEcal.at(iTrack)*cellSubWeights.at(iCell).at(iTrack)/sumCellSubWeights.at(iTrack);
+            // E_sub_track.at(iTrack)+=EestInEcal.at(iTrack)*cellSubWeights.at(iCell).at(iTrack)/sumCellSubWeights.at(iTrack);
+        }
+        // Store cell in output container
+        storeCell(cell, subtractedEnergy);
+    }
+    // Check if total amount of subtracted energy is correct
+    /*
+    for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){
+        ATH_MSG_INFO("EestInEcal.at(iTrack) = "<<EestInEcal.at(iTrack)<<"\tE_sub_track.at(iTrack) = "<<E_sub_track.at(iTrack)<<"\tsumCellSubWeights.at(iTrack) = "<<sumCellSubWeights.at(iTrack));
+    }
+    */
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauPi0BonnCreateROI::eventFinalize(TauCandidateData* /* data */) {
+
+    //---------------------------------------------------------------------
+    // use the m_cellMakerTool to finalize the 
+    // custom CaloCellContainer
+    //---------------------------------------------------------------------
+    CHECK( m_cellMakerTool->process(static_cast<CaloCellContainer*> (m_pPi0CellContainer)) );
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauPi0BonnCreateROI::finalize() {
+    // delete TH1 from parser
+    return StatusCode::SUCCESS;
+}
+
+void TauPi0BonnCreateROI::getExtrapolatedPositions(
+    vector<const xAOD::TrackParticle*> tracks,
+    int sampling)
+{
+    for (unsigned iTrack = 0 ; iTrack < tracks.size(); ++iTrack ) {
+        // extrapolate track to sampling 
+        // FIXME: xAOD migration as soon as tool is available
+        ATH_MSG_DEBUG( "Try extrapolation of track with pt = " << tracks.at(iTrack)->pt() << ", eta " << tracks.at(iTrack)->eta() << ", phi" << tracks.at(iTrack)->phi() 
+                      << " to layer " << sampling);
+        const Trk::TrackParameters* param_at_calo = 0;
+        param_at_calo = m_trackToCaloTool->extrapolate( 
+                *tracks.at(iTrack),
+                (CaloCell_ID::CaloSample) sampling, 
+                0.0, Trk::alongMomentum, Trk::pion);
+     
+        // store if track extrapolation successful, else use dummy values 
+        if(param_at_calo){
+            ATH_MSG_DEBUG( "Extrapolated track with eta=" << tracks.at(iTrack)->eta() 
+                            << " phi="<<tracks.at(iTrack)->phi() 
+                            << " to eta=" << param_at_calo->position().eta() 
+                            << " phi="<<param_at_calo->position().phi() 
+                            );
+            m_tracksEtaAtSampling.at(iTrack).at(sampling)=param_at_calo->position().eta();
+            m_tracksPhiAtSampling.at(iTrack).at(sampling)=param_at_calo->position().phi();
+            delete param_at_calo;
+        } 
+        else ATH_MSG_DEBUG("Could not extrapolate track with pt = " << tracks.at(iTrack)->pt() << ", eta " << tracks.at(iTrack)->eta() << ", phi" << tracks.at(iTrack)->phi()
+                          << " to layer " << sampling);
+        //just keep default values in case extrapolation failed
+    }
+}
+
+vector<double> TauPi0BonnCreateROI::getEstEcalEnergy(
+    vector<const xAOD::TrackParticle*> tracks,
+    const xAOD::CaloClusterContainer* clusterContainer, 
+    const xAOD::TauJet* rtau)
+{
+    // Vector that stores hadronic energy associated to one track
+    vector<double> EHcal;
+        for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){
+        EHcal.push_back(0.);
+    }
+
+    ATH_MSG_DEBUG("new tau. eta = " << rtau->eta() << "\t phi = " << rtau->phi() );
+        
+    xAOD::CaloClusterContainer::const_iterator clusterItr  = clusterContainer->begin();
+    xAOD::CaloClusterContainer::const_iterator clusterItrE = clusterContainer->end();
+
+    int clusterNumber = -1;
+    
+    for(;clusterItr!=clusterItrE;++clusterItr){
+        const xAOD::CaloCluster* cluster = (xAOD::CaloCluster*) *clusterItr;
+
+        double deltaEtaToTau = rtau->eta()-cluster->eta();
+        double deltaPhiToTau = TVector2::Phi_mpi_pi( rtau->phi() - cluster->phi());
+
+        // Check deltaR^2<0.2^2 instead of deltaR<0.2, because it is computationally less expensive.
+        double deltaRToTau_squared = deltaEtaToTau*deltaEtaToTau+deltaPhiToTau*deltaPhiToTau;
+        if(deltaRToTau_squared>0.04) continue;
+        
+
+        clusterNumber++;
+
+        ATH_MSG_DEBUG("Cluster number << " << clusterNumber << "\t energy = " << cluster->e() << "\t eta = " << cluster->eta() << "\t phi = " << cluster->phi() <<
+                     "\t deltaEtaToTau = " << deltaEtaToTau << "\t deltaPhiToTau = " << deltaPhiToTau << "\t deltaRToTau_squared = " << deltaRToTau_squared );
+
+           
+        // Get sample with maximum energy and cluster energy in Hcal
+        vector<double> energyInSamples=m_defaultValuesZero;
+        // Get energy in Hcal samplings: Loop over cells
+        const CaloClusterCellLink* theCellLink = cluster->getCellLinks(); 
+
+        CaloClusterCellLink::const_iterator cellInClusterItr  = theCellLink->begin();
+        CaloClusterCellLink::const_iterator cellInClusterItrE = theCellLink->end();
+
+        for(;cellInClusterItr!=cellInClusterItrE;++cellInClusterItr){
+            CaloCell* cellInCluster = (CaloCell*) *cellInClusterItr;
+            int sampling = cellInCluster->caloDDE()->getSampling();
+            if(sampling <= 2 || (sampling >=4 && sampling <=6 ) || sampling >= CaloCell_ID::FCAL0) continue;
+            energyInSamples.at(sampling) += cellInCluster->e()*cellInClusterItr.weight();
+        }
+
+
+        double cluster_EHcal = 0.;
+        int maxSample = -1;
+        double maxESample = 0.;
+        for(unsigned iSample = 0; iSample < energyInSamples.size(); ++iSample){
+            if(iSample == 3 || iSample >= 7 ) cluster_EHcal+=energyInSamples.at(iSample);
+            if(energyInSamples.at(iSample)<maxESample) continue;
+            maxSample = iSample;
+            maxESample = energyInSamples.at(iSample);
+        }
+        // Apply cryostat correction
+        if(energyInSamples.at(3) > 0. && energyInSamples.at(12) > 0.){
+            cluster_EHcal += m_caloWeightTool->wtCryo() * sqrt(energyInSamples.at(3)*energyInSamples.at(12));
+        }
+
+        
+        if(cluster_EHcal <= 0.){
+            ATH_MSG_DEBUG("cluster_EHcal = " << cluster_EHcal/1000. << "<=0. Skip this cluster for Hcal estimate.");
+            continue;
+        }
+        
+        // check if tracks have been extrapolated to this sampling. Do so if this is not the case
+        if(m_extrapolatedSamplings.at(maxSample)==false){
+           this->getExtrapolatedPositions(tracks,maxSample);
+           ATH_MSG_DEBUG("Extrapolate to layer " << maxSample << "\teta = " 
+                         << m_tracksEtaAtSampling.at(0).at(maxSample) << "\t phi = " << m_tracksPhiAtSampling.at(0).at(maxSample) );
+           m_extrapolatedSamplings.at(maxSample)=true;
+        }
+
+        // Assign cluster to track
+        int closestTrack = -1;
+        //double dEtaClosestTrack = 10;
+        //double dPhiClosestTrack = 10;
+        double dRToClosestTrack_squared = 0.16; // XXX can be tuned later
+        for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){
+            const xAOD::TrackParticle* track = tracks.at(iTrack);
+
+
+            // set extrapolated track direction
+            TLorentzVector extTrack;
+            ATH_MSG_DEBUG("filling extrapolated Track number " << iTrack << ", pt = " << track->pt() << ", eta = " << m_tracksEtaAtSampling.at(iTrack).at(maxSample) << ", phi " <<  m_tracksPhiAtSampling.at(iTrack).at(maxSample) << ", e = " << track->e() );
+
+            extTrack.SetPtEtaPhiE(track->pt(), m_tracksEtaAtSampling.at(iTrack).at(maxSample), m_tracksPhiAtSampling.at(iTrack).at(maxSample), track->e());
+
+            // get eta/phi distance of cell to track
+            double deltaEta = extTrack.Eta()-cluster->eta();
+            double deltaPhi = TVector2::Phi_mpi_pi( extTrack.Phi() - cluster->phi());;
+
+            double deltaRToTrack_squared = deltaEta*deltaEta+deltaPhi*deltaPhi;
+            ATH_MSG_DEBUG("Track number " << iTrack << ", extTrack.Eta() = " << extTrack.Eta() << ", extTrack.Phi() = " << extTrack.Phi());
+            
+            if(deltaRToTrack_squared>=dRToClosestTrack_squared) continue;
+            closestTrack = iTrack;
+            //dEtaClosestTrack = deltaEta;
+            //dPhiClosestTrack = deltaPhi;
+            dRToClosestTrack_squared = deltaRToTrack_squared;
+        }
+        if(closestTrack == -1 && dRToClosestTrack_squared > 0.04){
+            //ATH_MSG_DEBUG("dRToClosestTrack_squared = " << dRToClosestTrack_squared << ", dEta = " << dEtaClosestTrack << ", dPhi = " << dPhiClosestTrack 
+            //                << ". Skip cluster for Hcal estimate. \tcluster_EHcal = " << cluster_EHcal/1000.);
+            continue; // Didn't find a track
+        }
+        EHcal.at(closestTrack) += cluster_EHcal;
+        ATH_MSG_DEBUG("Cluster associated to track " << closestTrack << "\tcluster_EHcal = " << cluster_EHcal/1000.);
+    }
+    // Get energy estimate in ECAL
+    vector<double> E_ests;
+    for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){
+        double E_est = tracks.at(iTrack)->e()-EHcal.at(iTrack);
+        // energy cant be less than 0
+        if(E_est < 0) E_est = 0.;
+        // energy cant be more than track momentum
+        if(E_est > tracks.at(iTrack)->e()) E_est = tracks.at(iTrack)->e();
+        E_ests.push_back(E_est);
+    }
+    return E_ests;
+}
+
+double TauPi0BonnCreateROI::getLatWeight(int samp,
+                                        double deltaEta,
+                                        double deltaPhi,
+                                        double cellWidthEta,
+                                        double cellWidthPhi,
+                                        unsigned trackNumber,
+                                        const xAOD::TrackParticle* track
+                                       )
+{
+    // No need to subtract very far away from the track
+    if(fabs(deltaEta)>0.15 || fabs(deltaPhi)>0.15) return 0.;
+
+    TH1* histo;
+
+    // Store histograms in order to speed up the algorithm
+    // The 
+
+    // Check if TH1 is already in one of the maps
+    std::map<int, TH1*>::iterator itr;
+    if( samp==2 ) itr = m_trackHistMapBarrel.find(trackNumber);
+    else          itr = m_trackHistMapEndcap.find(trackNumber);
+
+    if( (samp==2 && itr != m_trackHistMapBarrel.end()) || (samp==6 && itr != m_trackHistMapEndcap.end()) ){
+        histo = itr->second;
+    }
+    else{
+        //---------------------------------------------------------------------
+        // Need to get bin key and histogram from parser
+        // set variables that can be used for parameterisation 
+        // Note: if value outside bin range, parser will choose first or last 
+        //       bin
+        //---------------------------------------------------------------------
+        m_pt     = track->pt();
+        m_abseta = fabs(track->eta());
+        // FIXME: Preliminary fix for crack:
+        if(m_abseta>1.34 && samp==2 ) m_abseta = 1.34;
+        if(m_abseta<1.56 && samp==6 ) m_abseta = 1.56;
+        m_sampling = (double) samp;
+        string key = m_latParser->getBinKey();
+
+        ATH_MSG_DEBUG("m_pt = " << m_pt << "\tm_abseta = " << m_abseta << "\tm_hadf = " << m_hadf << "\tm_sampling = " << m_sampling << "\tkey = " << key);
+
+        histo = m_latParser->getTH1();
+
+        if(samp==2) m_trackHistMapBarrel[trackNumber] = histo;
+        else        m_trackHistMapEndcap[trackNumber] = histo;
+    }
+    
+    // Get cell weight from histogram
+    int bin = histo->FindBin(fabs(deltaEta), deltaPhi*track->charge());
+    double cellWeight = histo->GetBinContent(bin);
+
+    // multiply by cell area in order to account for varying cell sizes in the endcap
+    cellWeight*=cellWidthEta*cellWidthPhi;
+
+    return cellWeight;
+}
+
+void TauPi0BonnCreateROI::storeCell(const CaloCell* cell, 
+                                    double subtractedEnergy){
+    // Store cell in output container if it is a new cell
+    // Produce a copy of the cell, in order to prevent 
+    // the energy of the original cell to be changed. 
+    // Store unweighted cells, since the cell weights are applied during reclustering
+    
+    //Ask cell for it's hash
+    const IdentifierHash cellHash = cell->caloDDE()->calo_hash();
+    //Check if this cell is already part of reducedCellContainer
+    bool isNewCell = (m_addedCellsMap.at(cellHash)==NULL);
+
+    if(isNewCell){
+        CaloCell* copyCell = cell->clone();
+        if(subtractedEnergy>0.){
+            // Get cell weight 
+            double wtCell = m_caloWeightTool->wtCell(cell);
+            // wtCell=0 (happens very rarely)  would cause a FPE
+            if( wtCell != 0. ) copyCell->setEnergy( cell->e() - subtractedEnergy/wtCell );
+        }
+        m_pPi0CellContainer->push_back(const_cast<CaloCell*> (copyCell));
+        m_addedCellsMap[cellHash] = copyCell;
+    }
+    // If the cell has been already stored the energy is subtracted for the already existing copy
+    else if(subtractedEnergy>0.){
+        CaloCell* copyCell = m_addedCellsMap.at(cellHash);
+        // Get cell weight 
+        double wtCell = m_caloWeightTool->wtCell(cell);
+        // wtCell=0 (happens very rarely)  would cause a FPE
+        if( wtCell != 0. ) copyCell->setEnergy( cell->e() - subtractedEnergy/wtCell );
+    }
+}
+
diff --git a/Reconstruction/tauRec/src/TauPi0BonnParser.cxx b/Reconstruction/tauRec/src/TauPi0BonnParser.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..efea376fd4005e28487901e965ae69658c186f08
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauPi0BonnParser.cxx
@@ -0,0 +1,361 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauPi0BonnParser 
+// package:     Reconstruction/tauEvent
+// authors:     Will Davey <will.davey@cern.ch> 
+// date:        2012-09-13
+//
+//-----------------------------------------------------------------------------
+
+#include "tauRec/TauPi0BonnParser.h"
+
+#include "TFile.h"
+#include "TParameter.h"
+#include "TVectorF.h"
+#include "TObjString.h"
+#include "TObjArray.h"
+
+#include <iostream>
+#include <assert.h>
+#include <string>
+#include <sstream>
+#include <fstream>
+#include <stdlib.h>
+
+using namespace std;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+TauPi0BonnParser::TauPi0BonnParser()
+    : m_max_traceback(1000)
+{
+}
+
+TauPi0BonnParser::~TauPi0BonnParser()
+{
+	// because we own the pointer of the histograms, we need to delete them here
+	std::map<std::string,TH1*>::iterator it=m_hist_map.begin();
+	for (;it!=m_hist_map.end(); ++it) delete it->second;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void TauPi0BonnParser::setMaxTraceback(int i){
+    m_max_traceback = i;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool TauPi0BonnParser::setVar( const string& key, double& val ){
+    if(m_curr_val_map.find(key)==m_curr_val_map.end()){
+        this->msg( "ERROR: var: "+key+" not in map" ); 
+        return false;
+    }
+    m_curr_val_map[key] = &val;
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+TH1* TauPi0BonnParser::getTH1(){
+    string key = this->getBinKey();
+    return m_hist_map[key];
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+string TauPi0BonnParser::getStream(){
+    return m_stream;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void TauPi0BonnParser::msg( const string& str ){
+    m_stream += str+"\n";
+    int length = m_stream.size();
+    if( length>m_max_traceback ) m_stream = m_stream.substr(m_stream.size()-m_max_traceback,m_max_traceback);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// get bin key from a list of bin indices
+string TauPi0BonnParser::getBinKey( const vector<int>& bin_indices ){
+    string key = "";
+    for( unsigned int j=0; j<bin_indices.size();j++) {
+        if( j!=0 ) key += "_";
+        key += m_bin_order.at(j);
+        key += Form("%d",bin_indices.at(j));
+    }
+    return key;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// get bin key from a list of var values
+string TauPi0BonnParser::getBinKey(){
+    // get current stored values of input variables
+    vector<double> vals = this->getCurrentVals();
+    // create vector to store bins corresponding to vals of input vars
+    vector<int> bin_indices;
+    
+    for( unsigned int i=0; i<vals.size();i++ ){
+        // get variable name and current value
+        string key = m_bin_order.at(i);
+        double val = vals.at(i);
+
+        // retrieve binning
+        vector<double> bin_edges = m_bin_map[key];
+
+        // determine bin index
+        int index = 0;
+        for( unsigned int j=0; j<bin_edges.size()-1; j++ ){
+            // return index 0 if before first bin
+            if( val < bin_edges.front() ) break;
+            // return last bin (n-2) if after last bin
+            if( val > bin_edges.back() ){
+                index = bin_edges.size()-2;
+                break;
+            }
+            if( val >= bin_edges.at(j) && val < bin_edges.at(j+1) ){
+                index = j; 
+                break;
+            }
+        }
+        bin_indices.push_back(index);
+    }
+    return this->getBinKey(bin_indices);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+vector<double> TauPi0BonnParser::getCurrentVals(){
+    vector<double> current_vals;
+    vector<string>::iterator itr = m_bin_order.begin();
+    for( ; itr!=m_bin_order.end(); itr++ ){			
+        // dont try to access null pointer if user hasn't configured properly
+			if ( m_curr_val_map[*itr] == NULL ) {
+        current_vals.push_back(-9999.);
+			}
+			else{
+				current_vals.push_back( (*m_curr_val_map[*itr]) );
+      }
+    }
+    return current_vals;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool TauPi0BonnParser::parseTDirectory( 
+    TDirectory* dir,
+    vector<int> current_bin_store,
+    int current_index)
+{
+    // make sure current_bin_store can accommodate map entries
+    while( current_bin_store.size()<m_bin_map.size() ) current_bin_store.push_back(0);
+
+    // initialise iterator
+    if( current_index == -1 ) current_index = 0;
+    // increment iterator if this is a recursion
+    else current_index++;
+    
+    // get binning for current variable
+    string key = m_bin_order.at(current_index);
+    vector<double> bin_edges = m_bin_map[key];
+
+    // looping over bins for current variable (dont count last bin top edge!)
+    for( unsigned int i=0; i<bin_edges.size()-1; i++ ){
+        // store the iterator for the current variable (is passed in recursion)
+        current_bin_store.at(current_index) = i; 
+
+        // once final variable reached, retrieve info from config file
+        if( current_index == (int)(m_bin_order.size()-1) ){
+            string bin_key = getBinKey( current_bin_store );
+        
+            /* 
+            // attempt to retrieve from file 
+            TVectorF* pvec = (TVectorF*) dir->Get(bin_key.c_str());
+            if( !pvec ){
+                msg( string("Failed to find ")+bin_key+" in dir.");
+                dir->ls();
+                return false;
+            }
+
+            // store as std::vector
+            vector<double> new_vec;
+            for( int j=0;j<pvec->GetNoElements();j++) new_vec.push_back((*pvec)(j));
+            m_hist_map[bin_key]=new_vec;
+            */
+
+            TH1* hist = (TH1*) dir->Get(bin_key.c_str());
+            if( !hist ){
+                msg( string("Failed to find ")+bin_key+" in dir.");
+                dir->ls();
+                return false;
+            }
+
+            // store as TH1
+            hist->SetDirectory(0);
+            m_hist_map[bin_key]=(TH1*)hist; //no clone in case SetDirectory(0) is used ->Clone();
+
+        }
+        else{
+            // recursively call to loop through all binning combinations
+            if( !this->parseTDirectory(
+                    dir, 
+                    current_bin_store,
+                    current_index) 
+                    )
+            {
+                msg( "ERROR parsing TDirectory" ); 
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool TauPi0BonnParser::parseROOTFile( string filename, string directory ){
+
+    // open input file
+    TFile* file = TFile::Open( filename.c_str() );
+    if( !file ){
+        msg( string("cant load file ")+filename );
+        return false;
+    }
+
+    // get directory
+    TDirectory* dir = file->GetDirectory(directory.c_str());
+    if( !dir ){
+        msg( string("dir: ")+directory+" not in file: "+filename);
+        return false;
+    }    
+
+    // number of binning variables 
+    TParameter<int>* NDIM = (TParameter<int>*)dir->Get("NDIM");
+    if( !NDIM ){
+        msg( "config file invalid format!"); 
+        return false;
+    }
+
+    // ';' seperated list of binning variable identifiers 
+    TObjString* BIN_VARS = (TObjString*) dir->Get("BIN_VARS");
+    if( !BIN_VARS ){
+        msg( "config file invalid format!"); 
+        return false;
+    }
+       
+    TString BIN_VARS_ts = BIN_VARS->GetString();
+    TIterator* BIN_VARS_itr = BIN_VARS_ts.Tokenize(';')->MakeIterator();
+    while( TObject* obj = BIN_VARS_itr->Next() ){
+        string key = obj->GetName();
+        m_bin_map[key] = vector<double>();
+        m_curr_val_map[key] = NULL;
+        m_bin_order.push_back(key);
+        //cout << "key: " << key << endl;
+    }
+
+    // load binning for variables 
+    map<string,vector<double> >::iterator itrMap = m_bin_map.begin();
+    for(; itrMap!=m_bin_map.end(); itrMap++ ){
+        itrMap->second.clear();
+        TVectorF* vec = (TVectorF*) dir->Get(Form("%s_BINS",itrMap->first.c_str()));
+        //assert(vec);
+				if (!vec) continue;
+        // cout << "itrMap->first = " <<  itrMap->first << endl;
+        for( int i=0; i<vec->GetNoElements(); i++ ){
+            itrMap->second.push_back( (*vec)(i+1) );
+            // cout << "bin" << i << ": " << (*vec)(i+1) << endl;
+        }
+    }
+
+    // parse all bin combinations in TDirectory
+    if( !this->parseTDirectory(dir) ){
+        msg( "failed parsing bins in TDirectory - invalid format!");
+        return false;
+    }
+
+    file->Close();
+
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool TauPi0BonnParser::checkConfig( 
+    vector<int> current_bin_store,
+    int current_index)
+{
+    // make sure current_bin_store can accommodate map entries
+    while( current_bin_store.size()<m_bin_map.size() ) current_bin_store.push_back(0);
+
+    // initialise iterator
+    if( current_index == -1 ) current_index = 0;
+    // increment iterator if this is a recursion
+    else current_index++;
+    
+    // get binning for current variable
+    string key = m_bin_order.at(current_index);
+    vector<double> bin_edges = m_bin_map[key];
+
+    // looping over bins for current variable (dont count last bin top edge!)
+    for( unsigned int i=0; i<bin_edges.size()-1; i++ ){
+        // store the iterator for the current variable (is passed in recursion)
+        current_bin_store.at(current_index) = i; 
+
+        // once final variable reached, retrieve info from config file
+        if( current_index == (int)(m_bin_order.size()-1) ){
+            string bin_key = getBinKey( current_bin_store );
+    
+            if( m_hist_map.find(bin_key) == m_hist_map.end() ){
+                msg( bin_key + " not loaded!" ); 
+                return false;
+            }
+        }
+        else{
+            // recursively call to loop through all binning combinations
+            if( !this->checkConfig(
+                    current_bin_store,
+                    current_index) 
+                    )
+            {
+                msg( string("failed checkConfig") ); 
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool TauPi0BonnParser::checkInitialisationStatus(){
+    
+    // check at least something loaded
+    if( m_bin_order.size() <= 0 ){
+        msg( "nothing loaded" );
+        return false;
+    }
+
+	
+    // check addresses set for all corresponding varaibles
+    map<string,double*>::iterator itr = m_curr_val_map.begin();
+    for( ; itr!=m_curr_val_map.end(); itr++ ){
+        if( itr->second == NULL ){
+            msg( string("Address of ") + itr->first + " not set!" );
+            return false;
+        }
+    }
+  
+
+    if( !this->checkConfig() ){
+        msg( "Failed loading variables" );
+        return false;
+    }
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void TauPi0BonnParser::summary(){
+    // FIXME: Write new summary function?
+    /*
+    map<std::string,TH1*>::iterator itrMap = m_hist_map.begin();
+    for( ; itrMap!=m_hist_map.end(); itrMap++ ){
+        cout << itrMap->first << ": ";
+        for( unsigned int k=0; k<itrMap->second.size(); k++) cout << " " << Form( "%.2f",itrMap->second.at(k));
+        cout << endl;
+    }
+    */
+}
+
diff --git a/Reconstruction/tauRec/src/TauPi0BonnScoreCalculator.cxx b/Reconstruction/tauRec/src/TauPi0BonnScoreCalculator.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c4dbb38b2c7d52a656977cddd711efe9bf0fc2e1
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauPi0BonnScoreCalculator.cxx
@@ -0,0 +1,244 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauPi0BonnScoreCalculator.cxx
+// package:     Reconstruction/tauRec
+// authors:     Benedict Winter, Will Davey
+// date:        2012-10-09
+//
+//-----------------------------------------------------------------------------
+
+#include <vector>
+
+#include "tauRec/TauPi0BonnScoreCalculator.h"
+#include "xAODPFlow/PFO.h"
+
+#include "TMVA/Reader.h"
+
+#include "PathResolver/PathResolver.h"
+
+using std::vector;
+using std::string;
+
+//-------------------------------------------------------------------------
+// Constructor
+//-------------------------------------------------------------------------
+
+TauPi0BonnScoreCalculator::TauPi0BonnScoreCalculator( 
+    const string& type,
+    const string& name,
+    const IInterface *parent) 
+
+    : TauToolBase(type, name, parent)
+    , m_readerOption("Silent:!Color")
+{
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("ReaderOption",            m_readerOption);
+    declareProperty("BDTWeightFile",           m_weightfile);
+}
+
+//-------------------------------------------------------------------------
+// Destructor
+//-------------------------------------------------------------------------
+
+TauPi0BonnScoreCalculator::~TauPi0BonnScoreCalculator() 
+{
+}
+
+
+StatusCode TauPi0BonnScoreCalculator::initialize() 
+{
+  //---------------------------------------------------------------------
+  // Create TMVA reader
+  //---------------------------------------------------------------------
+  m_tmvaReader = new TMVA::Reader(TString(m_readerOption));
+
+  if (msgLvl(MSG::DEBUG)) m_tmvaReader->SetVerbose(true);
+
+  int spectator = 1.;
+  m_tmvaReader->AddSpectator( "nTau"                            ,&spectator);
+  m_tmvaReader->AddSpectator( "nTau_test : = nTau%5"            ,&spectator);
+  m_tmvaReader->AddSpectator( "Sample"                          ,&spectator);
+  m_tmvaReader->AddSpectator( "Pi0Cluster_type"                 ,&spectator);
+  m_tmvaReader->AddSpectator( "Pi0Cluster_BDTScore_old"         ,&spectator);
+  m_tmvaReader->AddVariable( "Pi0Cluster_Abs_FIRST_ETA"         ,&m_FIRST_ETA);
+  m_tmvaReader->AddVariable( "Pi0Cluster_SECOND_R"              ,&m_SECOND_R);
+//  m_tmvaReader->AddVariable( "Pi0Cluster_SECOND_LAMBDA"         ,&m_SECOND_LAMBDA);
+//  m_tmvaReader->AddVariable( "Pi0Cluster_Abs_DELTA_PHI"         ,&m_Abs_DELTA_PHI);
+//  m_tmvaReader->AddVariable( "Pi0Cluster_Abs_DELTA_THETA"       ,&m_Abs_DELTA_THETA);
+  m_tmvaReader->AddVariable( "Pi0Cluster_CENTER_LAMBDA_helped"  ,&m_CENTER_LAMBDA_helped);
+//  m_tmvaReader->AddVariable( "Pi0Cluster_LATERAL"               ,&m_LATERAL);
+//  m_tmvaReader->AddVariable( "Pi0Cluster_LONGITUDINAL"          ,&m_LONGITUDINAL);
+  m_tmvaReader->AddVariable( "Pi0Cluster_ENG_FRAC_EM"           ,&m_ENG_FRAC_EM);
+//  m_tmvaReader->AddVariable( "Pi0Cluster_ENG_FRAC_MAX"          ,&m_ENG_FRAC_MAX);
+  m_tmvaReader->AddVariable( "Pi0Cluster_ENG_FRAC_CORE"         ,&m_ENG_FRAC_CORE);
+  m_tmvaReader->AddVariable( "Pi0Cluster_log_SECOND_ENG_DENS"   ,&m_log_SECOND_ENG_DENS);
+  m_tmvaReader->AddVariable( "Pi0Cluster_EcoreOverEEM1"         ,&m_EcoreOverEEM1);
+  m_tmvaReader->AddVariable( "Pi0Cluster_AsymmetryWRTTrack"     ,&m_AsymmetryWRTTrack);
+// m_tmvaReader->AddVariable( "Pi0Cluster_NHitsInEM1"             ,&m_NHitsInEM1);
+// m_tmvaReader->AddVariable( "Pi0Cluster_NPosECells_PS"          ,&m_NPosCells_PS);
+  m_tmvaReader->AddVariable( "Pi0Cluster_NPosECells_EM1"        ,&m_NPosCells_EM1);
+  m_tmvaReader->AddVariable( "Pi0Cluster_NPosECells_EM2"        ,&m_NPosCells_EM2);
+//  m_tmvaReader->AddVariable( "Pi0Cluster_AbsFirstEtaWRTClusterPosition_EM1" ,&m_firstEtaWRTCluster_EM1);
+//  m_tmvaReader->AddVariable( "Pi0Cluster_AbsFirstEtaWRTClusterPosition_EM2" ,&m_firstEtaWRTCluster_EM2);
+  m_tmvaReader->AddVariable( "Pi0Cluster_secondEtaWRTClusterPosition_EM1" ,&m_secondEtaWRTCluster_EM1);
+  m_tmvaReader->AddVariable( "Pi0Cluster_secondEtaWRTClusterPosition_EM2" ,&m_secondEtaWRTCluster_EM2);
+//  m_tmvaReader->AddVariable( "Pi0Cluster_energy_EM1"            ,&m_energy_EM1);
+//  m_tmvaReader->AddVariable( "Pi0Cluster_energy_EM2"            ,&m_energy_EM2);
+
+  if (bookMethod(m_tmvaReader, "BDT method").isFailure()) return StatusCode::FAILURE;
+ 
+  return StatusCode::SUCCESS;
+}
+
+StatusCode TauPi0BonnScoreCalculator::finalize()
+{
+  StatusCode sc = AlgTool::finalize();
+  delete m_tmvaReader;
+  return sc;
+}
+
+
+StatusCode TauPi0BonnScoreCalculator::execute(TauCandidateData *data) 
+{
+    xAOD::TauJet *tauJet = data->xAODTau;
+    //---------------------------------------------------------------------
+    // only run on 1-5 prong taus 
+    //---------------------------------------------------------------------
+    if (tauJet->nTracks() == 0 || tauJet->nTracks() >5 ) {
+        return StatusCode::SUCCESS;
+    }
+    ATH_MSG_DEBUG("ScoreCalculator: new tau. \tpt = " << tauJet->pt() << "\teta = " << tauJet->eta() << "\tphi = " << tauJet->phi() << "\tnprongs = " << tauJet->nTracks());
+
+    //---------------------------------------------------------------------
+    // retrieve neutral PFOs from tau, calculate BDT scores and store them in PFO
+    //---------------------------------------------------------------------
+    unsigned nNeutPFO = tauJet->nCellBased_Neutral_PFOs();
+    for(unsigned int iNeutPFO=0; iNeutPFO<nNeutPFO; iNeutPFO++) {
+        const xAOD::PFO* curNeutPFO_const = tauJet->cellBased_Neutral_PFO( iNeutPFO );
+        float BDTScore = calculateScore(curNeutPFO_const);
+        xAOD::PFO* curNeutPFO = const_cast<xAOD::PFO*>(curNeutPFO_const);
+        curNeutPFO->setBDTPi0Score((float) BDTScore);
+    }
+
+    ATH_MSG_DEBUG("End of TauPi0BonnScoreCalculator::execute");
+
+    return StatusCode::SUCCESS;
+}
+
+
+float TauPi0BonnScoreCalculator::calculateScore(const xAOD::PFO* neutralPFO)
+{
+    m_FIRST_ETA=0.;
+    m_SECOND_R=0.;
+    m_SECOND_LAMBDA=0.;
+    m_Abs_DELTA_PHI=0.;
+    m_Abs_DELTA_THETA=0.;
+    m_CENTER_LAMBDA_helped=0.;
+    m_LATERAL=0.;
+    m_LONGITUDINAL=0.;
+    m_ENG_FRAC_EM=0.;
+    m_ENG_FRAC_MAX=0.;
+    m_ENG_FRAC_CORE=0.;
+    m_log_SECOND_ENG_DENS=0.;
+    m_EcoreOverEEM1=0.;
+    m_AsymmetryWRTTrack=0.;
+    // Need to convert int variables to floats after retrieving them
+    int NHitsInEM1=0;
+    int NPosCells_PS=0;
+    int NPosCells_EM1=0;
+    int NPosCells_EM2=0;
+    m_firstEtaWRTCluster_EM1=0.;
+    m_firstEtaWRTCluster_EM2=0.;
+    m_secondEtaWRTCluster_EM1=0.;
+    m_secondEtaWRTCluster_EM2=0.;
+    m_energy_EM1=0.;
+    m_energy_EM2=0.;
+
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_FIRST_ETA,m_FIRST_ETA) == false)
+        ATH_MSG_WARNING("Can't find FIRST_ETA. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_SECOND_R,m_SECOND_R) == false)
+        ATH_MSG_WARNING("Can't find SECOND_R. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_SECOND_LAMBDA,m_SECOND_LAMBDA) == false)
+        ATH_MSG_WARNING("Can't find SECOND_LAMBDA. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_DELTA_PHI,m_Abs_DELTA_PHI) == false)
+        ATH_MSG_WARNING("Can't find DELTA_PHI. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_DELTA_THETA,m_Abs_DELTA_THETA) == false)
+        ATH_MSG_WARNING("Can't find DELTA_THETA. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_CENTER_LAMBDA,m_CENTER_LAMBDA_helped) == false) 
+        ATH_MSG_WARNING("Can't find CENTER_LAMBDA. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_LATERAL,m_LATERAL) == false)
+        ATH_MSG_WARNING("Can't find LATERAL. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_LONGITUDINAL,m_LONGITUDINAL) == false) 
+        ATH_MSG_WARNING("Can't find LONGITUDINAL. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_ENG_FRAC_EM,m_ENG_FRAC_EM) == false) 
+        ATH_MSG_WARNING("Can't find ENG_FRAC_EM. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_ENG_FRAC_MAX,m_ENG_FRAC_MAX) == false) 
+        ATH_MSG_WARNING("Can't find ENG_FRAC_MAX. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_ENG_FRAC_CORE,m_ENG_FRAC_CORE) == false) 
+        ATH_MSG_WARNING("Can't find ENG_FRAC_CORE. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_SECOND_ENG_DENS,m_log_SECOND_ENG_DENS) == false) 
+        ATH_MSG_WARNING("Can't find SECOND_ENG_DENS. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_EM1CoreFrac,m_EcoreOverEEM1) == false) 
+        ATH_MSG_WARNING("Can't find EM1CoreFrac. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_asymmetryInEM1WRTTrk,m_AsymmetryWRTTrack) == false) 
+        ATH_MSG_WARNING("Can't find asymmetryInEM1WRTTrk. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_NHitsInEM1,NHitsInEM1) == false) 
+        ATH_MSG_WARNING("Can't find NHitsInEM1. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_NPosECells_PS,NPosCells_PS) == false) 
+        ATH_MSG_WARNING("Can't find NPosECells_PS. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_NPosECells_EM1,NPosCells_EM1) == false) 
+        ATH_MSG_WARNING("Can't find NPosECells_EM1. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_NPosECells_EM2,NPosCells_EM2) == false) 
+        ATH_MSG_WARNING("Can't find NPosECells_EM2. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_firstEtaWRTClusterPosition_EM1,m_firstEtaWRTCluster_EM1) == false) 
+        ATH_MSG_WARNING("Can't find firstEtaWRTClusterPosition_EM1. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_firstEtaWRTClusterPosition_EM2,m_firstEtaWRTCluster_EM2) == false) 
+        ATH_MSG_WARNING("Can't find firstEtaWRTClusterPosition_EM2. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_secondEtaWRTClusterPosition_EM1,m_secondEtaWRTCluster_EM1) == false) 
+        ATH_MSG_WARNING("Can't find secondEtaWRTClusterPosition_EM1. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_secondEtaWRTClusterPosition_EM2,m_secondEtaWRTCluster_EM2) == false) 
+        ATH_MSG_WARNING("Can't find secondEtaWRTClusterPosition_EM2. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_energy_EM1,m_energy_EM1) == false) 
+        ATH_MSG_WARNING("Can't find energy_EM1. Set it to 0.");
+    if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_energy_EM2,m_energy_EM2) == false) 
+        ATH_MSG_WARNING("Can't find energy_EM2. Set it to 0.");
+    // Apply variable transformations
+    m_Abs_DELTA_PHI   = fabs(m_Abs_DELTA_PHI);
+    m_Abs_DELTA_THETA = fabs(m_Abs_DELTA_THETA);
+    m_CENTER_LAMBDA_helped = fmin(m_CENTER_LAMBDA_helped, 1000.);
+    if(m_log_SECOND_ENG_DENS==0.) m_log_SECOND_ENG_DENS=-50.;
+    else m_log_SECOND_ENG_DENS = log(m_log_SECOND_ENG_DENS);
+    // Convert ints to floats so they can be read by the TMVA reader
+    m_NHitsInEM1 = (float) NHitsInEM1;
+    m_NPosCells_PS = (float) NPosCells_PS;
+    m_NPosCells_EM1 = (float) NPosCells_EM1;
+    m_NPosCells_EM2 = (float) NPosCells_EM2;
+
+    // Calculate BDT score
+    float BDTScore = m_tmvaReader->EvaluateMVA( "BDT method" );
+     
+    return BDTScore;
+}
+
+StatusCode TauPi0BonnScoreCalculator::bookMethod(TMVA::Reader *reader, const std::string &methodName) const 
+{
+    if (m_weightfile == ""){
+        ATH_MSG_ERROR("No weight file given");
+        return StatusCode::FAILURE;
+    }
+    std::string resolvedFileName = PathResolver::find_file(m_weightfile, "DATAPATH");
+    if (resolvedFileName != "") {
+        ATH_MSG_DEBUG( "Parameterisation file found: " << resolvedFileName );
+    } 
+    else {
+        ATH_MSG_ERROR( "Parameterisation file " << m_weightfile << " not found" );
+        return StatusCode::FAILURE;
+    }
+    reader->BookMVA( methodName, resolvedFileName);
+    return StatusCode::SUCCESS;
+}
+
diff --git a/Reconstruction/tauRec/src/TauPi0BonnSelector.cxx b/Reconstruction/tauRec/src/TauPi0BonnSelector.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8202b9a183b4cf39d4cef5c6fee3826d4b98c6f8
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauPi0BonnSelector.cxx
@@ -0,0 +1,148 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauPi0BonnSelector.cxx
+// package:     Reconstruction/tauRec
+// authors:     Benedict Winter, Will Davey
+// date:        2012-10-09
+//
+//-----------------------------------------------------------------------------
+
+#include <vector>
+
+#include "tauRec/TauPi0BonnSelector.h"
+#include "FourMomUtils/P4Helpers.h"
+
+#include "CaloUtils/CaloVertexedCluster.h"
+
+
+using std::vector;
+using std::string;
+
+//-------------------------------------------------------------------------
+// Constructor
+//-------------------------------------------------------------------------
+
+TauPi0BonnSelector::TauPi0BonnSelector( 
+    const string& type,
+    const string& name,
+    const IInterface *parent) 
+
+    : TauToolBase(type, name, parent)
+{
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("ClusterEtCut",             m_clusterEtCut);
+    declareProperty("ClusterBDTCut_1prong",     m_clusterBDTCut_1prong);
+    declareProperty("ClusterBDTCut_mprong",     m_clusterBDTCut_mprong);
+}
+
+//-------------------------------------------------------------------------
+// Destructor
+//-------------------------------------------------------------------------
+
+TauPi0BonnSelector::~TauPi0BonnSelector() 
+{
+}
+
+StatusCode TauPi0BonnSelector::initialize()
+{
+  return StatusCode::SUCCESS;
+}
+
+StatusCode TauPi0BonnSelector::execute(TauCandidateData *data) 
+{
+    xAOD::TauJet *tauJet = data->xAODTau;
+    //---------------------------------------------------------------------
+    // only run on 1-5 prong taus 
+    //---------------------------------------------------------------------
+    if (tauJet->nTracks() == 0 || tauJet->nTracks() >5 ) {
+        return StatusCode::SUCCESS;
+    }
+
+
+    //---------------------------------------------------------------------
+    // retrieve neutral PFOs from tau. Apply selection and create links to
+    // Pi0NeutralPFOs 
+    //---------------------------------------------------------------------
+    unsigned nNeutPFO = tauJet->nCellBased_Neutral_PFOs();
+    for(unsigned int iNeutPFO=0; iNeutPFO<nNeutPFO; iNeutPFO++) {
+        const xAOD::PFO* curNeutPFO_const = tauJet->cellBased_Neutral_PFO( iNeutPFO );
+
+        // Get eta bin
+        int etaBin = getPi0Cluster_etaBin( curNeutPFO_const->p4().Eta() );
+
+        // Preselection
+        if(curNeutPFO_const->p4().Et() < m_clusterEtCut.at(etaBin)) continue;
+        if(tauJet->p4().DeltaR(curNeutPFO_const->p4()) > 0.2) continue; // FIXME replace by shrinking cone
+
+        // BDT Selection
+        float BDTScore = curNeutPFO_const->bdtPi0Score();
+        if( (tauJet->nTracks()==1 && BDTScore < m_clusterBDTCut_1prong.at(etaBin)) || (tauJet->nTracks()>1 && BDTScore < m_clusterBDTCut_mprong.at(etaBin)) ) continue;
+
+        // Set number of pi0s
+        int nHitsInEM1 = 0;
+        if(!curNeutPFO_const->attribute(xAOD::PFODetails::cellBased_NHitsInEM1, nHitsInEM1)) ATH_MSG_WARNING("Couldn't retrieve nHitsInEM1. Will set it to 0.");
+        xAOD::PFO* curNeutPFO = const_cast<xAOD::PFO*>(curNeutPFO_const);
+        if(nHitsInEM1<3){ 
+            curNeutPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::nPi0, 1);
+            curNeutPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::nPi0Proto, 1);
+        }   
+        else{ 
+            curNeutPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::nPi0, 2);
+            curNeutPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::nPi0Proto, 2);
+        }
+
+        // Set element link to Pi0tagged PFO
+        ElementLink<xAOD::PFOContainer> pfoLink = tauJet->cellBased_Neutral_PFOLinks().at(iNeutPFO);
+        tauJet->addCellBased_Pi0_PFOLink(pfoLink);
+    }
+    // Calculate visTau hlv and store it in pPi0Details.
+    TLorentzVector p4 = getP4(tauJet);
+    tauJet->setP4(xAOD::TauJetParameters::PanTauCellBasedProto, p4.Pt(),p4.Eta(),p4.Phi(),p4.M());
+    // tauJet->setPtPanTauCellBasedProto( p4.Pt());
+    // tauJet->setEtaPanTauCellBasedProto(p4.Eta());
+    // tauJet->setPhiPanTauCellBasedProto(p4.Phi());
+    // tauJet->setEPanTauCellBasedProto(  p4.E());
+    // tauJet->setMPanTauCellBasedProto(  p4.M());
+    
+    return StatusCode::SUCCESS;
+}
+
+int TauPi0BonnSelector::getPi0Cluster_etaBin(double Pi0Cluster_eta){
+    int Pi0Cluster_etaBin = -1;
+    double Pi0Cluster_noCorr_ABSeta = fabs(Pi0Cluster_eta);
+
+    if( Pi0Cluster_noCorr_ABSeta < 0.80 ) Pi0Cluster_etaBin = 0;
+    else if( Pi0Cluster_noCorr_ABSeta < 1.40 ) Pi0Cluster_etaBin = 1;
+    else if( Pi0Cluster_noCorr_ABSeta < 1.50 ) Pi0Cluster_etaBin = 2;
+    else if( Pi0Cluster_noCorr_ABSeta < 1.90 ) Pi0Cluster_etaBin = 3;
+    else Pi0Cluster_etaBin = 4;
+    return Pi0Cluster_etaBin;
+}
+
+TLorentzVector TauPi0BonnSelector::getP4(xAOD::TauJet* tauJet)
+{
+    // Get 4mom of first charged PFO, which is available for all taus that are treated in this algorithm
+    const xAOD::PFO* firstChargedPFO = tauJet->cellBased_Charged_PFO( 0 );
+    TLorentzVector p4 = firstChargedPFO->p4();
+    // Add other PFO momenta
+    unsigned nChargedPFO = tauJet->nCellBased_Charged_PFOs();
+    for(unsigned int iChargedPFO=1; iChargedPFO<nChargedPFO; iChargedPFO++){
+        const xAOD::PFO* curChargedPFO = tauJet->cellBased_Charged_PFO( iChargedPFO );
+        p4+=curChargedPFO->p4();
+    }
+    unsigned nPi0NeutPFO = tauJet->nCellBased_Pi0_PFOs();
+    for(unsigned int iPi0NeutPFO=0; iPi0NeutPFO<nPi0NeutPFO; iPi0NeutPFO++){
+       const xAOD::PFO* curPi0NeutPFO = tauJet->cellBased_Pi0_PFO( iPi0NeutPFO );
+       if (tauJet->vertexLink())
+        p4+= xAOD::CaloVertexedCluster(*curPi0NeutPFO->cluster(0) , (*tauJet->vertexLink())->position()).p4();
+       else
+        p4+= xAOD::CaloVertexedCluster(*curPi0NeutPFO->cluster(0)).p4();
+
+    }
+    return p4;
+}
+
diff --git a/Reconstruction/tauRec/src/TauProcessor.cxx b/Reconstruction/tauRec/src/TauProcessor.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1d47aa9c2b05624e95ffee5e07d574338be94fc6
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauProcessor.cxx
@@ -0,0 +1,231 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "GaudiKernel/ListItem.h"
+
+#include "xAODTau/TauJetContainer.h"
+
+#include "tauRec/TauProcessor.h"
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+TauProcessor::TauProcessor(const std::string &name,
+    ISvcLocator * pSvcLocator) :
+AthAlgorithm(name, pSvcLocator),
+m_tauContainerName("TauRecContainer"),
+m_tauAuxContainerName("TauRecContainerAux."),
+m_AODmode(false),
+m_tools(this) //make tools private
+{
+    declareProperty("TauContainer", m_tauContainerName);
+    declareProperty("TauAuxContainer", m_tauAuxContainerName);
+    declareProperty("Tools", m_tools, "List of TauToolBase tools");
+    declareProperty("runOnAOD", m_AODmode); //AODS are input file
+    
+}
+
+//-----------------------------------------------------------------------------
+// Destructor
+//-----------------------------------------------------------------------------
+TauProcessor::~TauProcessor() {
+}
+
+//-----------------------------------------------------------------------------
+// Initializer
+//-----------------------------------------------------------------------------
+StatusCode TauProcessor::initialize() {
+
+
+    //ATH_MSG_INFO("FF::TauProcessor :: initialize()");
+
+    //-------------------------------------------------------------------------
+    // No tools allocated!
+    //-------------------------------------------------------------------------
+    if (m_tools.size() == 0) {
+        ATH_MSG_ERROR("no tools given!");
+        return StatusCode::FAILURE;
+    }
+
+    StatusCode sc;
+    
+    //-------------------------------------------------------------------------
+    // Allocate tools
+    //-------------------------------------------------------------------------
+    ToolHandleArray<TauToolBase> ::iterator itT = m_tools.begin();
+    ToolHandleArray<TauToolBase> ::iterator itTE = m_tools.end();
+    ATH_MSG_INFO("List of tools in execution sequence:");
+    ATH_MSG_INFO("------------------------------------");
+
+    unsigned int tool_count = 0;
+
+    for (; itT != itTE; ++itT) {
+        sc = itT->retrieve();
+        if (sc.isFailure()) {
+            ATH_MSG_WARNING("Cannot find tool named <" << *itT << ">");
+        } else {
+            ++tool_count;
+            ATH_MSG_INFO((*itT)->type() << " - " << (*itT)->name());
+        }
+    }
+    ATH_MSG_INFO(" ");
+    ATH_MSG_INFO("------------------------------------");
+
+    if (tool_count == 0) {
+        ATH_MSG_ERROR("could not allocate any tool!");
+        return StatusCode::FAILURE;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    return StatusCode::SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Finalizer
+//-----------------------------------------------------------------------------
+StatusCode TauProcessor::finalize() {
+    return StatusCode::SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Execution
+//-----------------------------------------------------------------------------
+StatusCode TauProcessor::execute() {
+
+    StatusCode sc;
+
+    TauCandidateData rTauData;
+
+    const xAOD::TauJetContainer*     pContainer = 0;
+    const xAOD::TauJetAuxContainer*     pAuxContainer = 0;
+
+    //-------------------------------------------------------------------------
+    // retrieve Tau Containers from StoreGate
+    //-------------------------------------------------------------------------
+    sc = evtStore()->retrieve(pContainer, m_tauContainerName);
+    if (sc.isFailure()) {
+      if (m_AODmode) {
+        // don't exit Athena if there is no Tau Container in (D)AODs when running in AOD mode
+        // just exit TauProcessor
+        // reason: somebody might use slimmed (D)AODs, where not needed containers are not present
+        ATH_MSG_WARNING("Failed to retrieve " << m_tauContainerName << "! Will exit TauProcessor now!!");
+        return StatusCode::SUCCESS;
+      }
+      else {
+        ATH_MSG_FATAL("Failed to retrieve " << m_tauContainerName);
+        return StatusCode::FAILURE;
+      }
+    } 
+    rTauData.xAODTauContainer = const_cast<xAOD::TauJetContainer*>(pContainer);  
+
+    sc = evtStore()->retrieve(pAuxContainer, m_tauAuxContainerName);
+    if (sc.isFailure()) {
+      if (m_AODmode) {
+        // don't exit Athena if there is no Tau AuxContainer in (D)AODs when running in AOD mode
+        // just exit TauProcessor
+        // reason: somebody might use slimmed (D)AODs, where not needed containers are not present
+        ATH_MSG_WARNING("Failed to retrieve " << m_tauAuxContainerName << "! Will exit TauProcessor now!!");
+        return StatusCode::SUCCESS;
+      }
+      else {
+        ATH_MSG_FATAL("Failed to retrieve " << m_tauAuxContainerName);
+        return StatusCode::FAILURE;
+      }
+    } 
+    rTauData.tauAuxContainer = const_cast<xAOD::TauJetAuxContainer*>(pAuxContainer);  
+
+    // set TauCandidate properties
+    rTauData.xAODTau = 0;
+    /*
+    rTauData.tau = 0;
+    rTauData.details = 0;
+    rTauData.extraDetails = 0;
+    rTauData.pi0Details = 0;
+    */
+    rTauData.seed = 0;
+    rTauData.seedContainer = 0;
+
+    //-------------------------------------------------------------------------
+    // Initialize tools for this event
+    //-------------------------------------------------------------------------
+    ToolHandleArray<TauToolBase> ::iterator itT = m_tools.begin();
+    ToolHandleArray<TauToolBase> ::iterator itTE = m_tools.end();
+    for (; itT != itTE; ++itT) {
+        sc = (*itT)->eventInitialize(&rTauData);
+        if (sc != StatusCode::SUCCESS)
+            return StatusCode::FAILURE;
+    }
+
+    ////////////////////////////////////////////////////////
+
+    //loop over taus
+    xAOD::TauJetContainer::const_iterator tau_it  = pContainer->begin();
+    xAOD::TauJetContainer::const_iterator tau_end = pContainer->end();
+    
+    for(; tau_it != tau_end; ++tau_it) {
+        
+        //-----------------------------------------------------------------
+        // set tau candidate data for easy handling
+        //-----------------------------------------------------------------
+        rTauData.xAODTau          = const_cast<xAOD::TauJet * >( *tau_it);
+	rTauData.seed = ( *rTauData.xAODTau->jetLink() );
+
+        //-----------------------------------------------------------------
+        // Process the candidate
+        //-----------------------------------------------------------------
+        ToolHandleArray<TauToolBase>::iterator itT = m_tools.begin();
+        ToolHandleArray<TauToolBase>::iterator itTE = m_tools.end();
+
+        //-----------------------------------------------------------------
+        // Loop stops when Failure indicated by one of the tools
+        //-----------------------------------------------------------------
+        for (; itT != itTE; ++itT) {
+            ATH_MSG_VERBOSE("Invoking tool " << (*itT)->name());
+
+            sc = (*itT)->execute(&rTauData);
+
+            if (sc.isFailure())
+                break;
+        }
+
+        if (sc.isSuccess()) {
+          
+            ATH_MSG_VERBOSE("The tau candidate has been modified");
+
+        } else if (!sc.isSuccess()) {
+            //TODO:cleanup of EndTools not necessary??
+            //keep this here for future use (in case more than one seeding algo exist)
+            /*
+            ToolHandleArray<TauToolBase> ::iterator p_itT1 = m_tools.begin();
+            for (; p_itT1 != p_itT; ++p_itT1)
+                (*p_itT1)->cleanup(&rTauData);
+            (*p_itT1)->cleanup(&rTauData);
+             */
+            //delete rTauData.tau;
+        } else  {
+            //delete rTauData.tau;
+            }
+    }
+
+
+
+    //-------------------------------------------------------------------------
+    // Finalize tools for this event
+    //-------------------------------------------------------------------------
+
+    itT = m_tools.begin();
+    itTE = m_tools.end();
+    for (; itT != itTE; ++itT) {
+        sc = (*itT)->eventFinalize(&rTauData);
+        if (sc != StatusCode::SUCCESS)
+            return StatusCode::FAILURE;
+    }
+
+
+    ///////////////////////////////////////////////////////
+    // locking of containers is moved to separate tau tool
+
+    return StatusCode::SUCCESS;
+}
diff --git a/Reconstruction/tauRec/src/TauShotFinder.cxx b/Reconstruction/tauRec/src/TauShotFinder.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0075f5b51d0f505b7237ff8583174af6712b7903
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauShotFinder.cxx
@@ -0,0 +1,554 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauShotFinder.cxx
+// package:     Reconstruction/tauRec
+// authors:     Will Davey, Benedict Winter, Stephanie Yuen
+// date:        2013-05-22
+//
+//-----------------------------------------------------------------------------
+
+#include <boost/scoped_ptr.hpp>
+
+#include "GaudiKernel/IToolSvc.h"
+
+#include "CaloEvent/CaloCellContainer.h"
+#include "xAODCaloEvent/CaloClusterContainer.h"
+#include "xAODCaloEvent/CaloClusterKineHelper.h"
+#include "CaloIdentifier/CaloCell_ID.h"
+#include "CaloIdentifier/LArNeighbours.h"
+#include "CaloUtils/CaloClusterStoreHelper.h"
+#include "CaloUtils/CaloCellList.h"
+#include "CaloUtils/CaloCellESort.h"
+#include "CaloInterface/IHadronicCalibrationTool.h"
+#include "FourMomUtils/P4Helpers.h"
+#include "tauRec/TauShotFinder.h"
+#include "tauRec/TauShotVariableHelpers.h"
+#include "TMVA/Reader.h"
+#include "PathResolver/PathResolver.h"
+#include "xAODPFlow/PFOContainer.h"
+#include "xAODPFlow/PFOAuxContainer.h"
+#include "xAODPFlow/PFO.h"
+
+using std::vector;
+using std::string;
+
+//-------------------------------------------------------------------------
+// Constructor
+//-------------------------------------------------------------------------
+
+TauShotFinder::TauShotFinder(   const string& type,
+                                const string& name,
+                                const IInterface *parent) 
+    : TauToolBase(type, name, parent)
+    , m_caloWeightTool("H1WeightToolCSC12Generic")
+    , m_caloCellContainerName("AllCalo")
+    , m_shotClusterContainer(NULL)
+    , m_shotClusterContainerName("TauShotClusterContainer")
+    , m_shotPFOContainerName("TauShotPFOContainer")
+    , m_calo_dd_man(NULL)
+    , m_calo_id(NULL)
+{
+    declareInterface<TauToolBase > (this);
+    declareProperty("CaloWeightTool", m_caloWeightTool);
+    declareProperty("CaloCellContainerName", m_caloCellContainerName); 
+    declareProperty("ShotClusterContainerName", m_shotClusterContainerName);
+    declareProperty("ShotPFOContainerName",  m_shotPFOContainerName);
+    declareProperty("ReaderOption",          m_readerOption);
+    declareProperty("BDTWeightFile_barrel",  m_weightfile_barrel);
+    declareProperty("BDTWeightFile_endcap1", m_weightfile_endcap1);
+    declareProperty("BDTWeightFile_endcap2", m_weightfile_endcap2);
+    declareProperty("NCellsInEta",           m_nCellsInEta);
+    declareProperty("MinPtCut",              m_minPtCut);
+    declareProperty("AutoDoubleShotCut",     m_autoDoubleShotCut);
+    declareProperty("MergedBDTScoreCut",     m_mergedBDTScoreCut);
+}
+
+//-------------------------------------------------------------------------
+// Destructor
+//-------------------------------------------------------------------------
+
+TauShotFinder::~TauShotFinder() {
+}
+
+StatusCode TauShotFinder::initialize() {
+    
+    // retrieve tools
+    ATH_MSG_DEBUG( "Retrieving tools" );
+    CHECK( m_caloWeightTool.retrieve() );
+
+    // initialize calo cell geo
+    m_calo_dd_man  = CaloDetDescrManager::instance();
+    m_calo_id      = m_calo_dd_man->getCaloCell_ID();
+
+    //---------------------------------------------------------------------
+    // Create TMVA readers
+    //---------------------------------------------------------------------
+    m_tmvaReader_barrel = new TMVA::Reader(TString(m_readerOption));
+    if (msgLvl(MSG::DEBUG)) m_tmvaReader_barrel->SetVerbose(true);
+    m_tmvaReader_barrel->AddVariable("(shot_pt_3-shot_pt)/shot_pt_3",&G_PTFRAC);
+    m_tmvaReader_barrel->AddVariable("shot_stdpt_5"                 ,&G_STDPT_5 );
+    m_tmvaReader_barrel->AddVariable("shot_stdeta_5"                ,&G_STDETA_5 );
+    m_tmvaReader_barrel->AddVariable("shot_deltapt_min"             ,&G_DELTAPT_MIN );
+
+    m_tmvaReader_endcap1 = new TMVA::Reader(TString(m_readerOption));
+    if (msgLvl(MSG::DEBUG)) m_tmvaReader_endcap1->SetVerbose(true);
+    m_tmvaReader_endcap1->AddVariable("(shot_pt_3-shot_pt)/shot_pt_3",&G_PTFRAC);
+    m_tmvaReader_endcap1->AddVariable("shot_stdpt_5"                 ,&G_STDPT_5 );
+    m_tmvaReader_endcap1->AddVariable("shot_stdeta_5"                ,&G_STDETA_5 );
+    m_tmvaReader_endcap1->AddVariable("shot_deltapt_min"             ,&G_DELTAPT_MIN );
+
+    m_tmvaReader_endcap2 = new TMVA::Reader(TString(m_readerOption));
+    if (msgLvl(MSG::DEBUG)) m_tmvaReader_endcap2->SetVerbose(true);
+    m_tmvaReader_endcap2->AddVariable("(shot_pt_3-shot_pt)/shot_pt_3",&G_PTFRAC);
+    m_tmvaReader_endcap2->AddVariable("shot_stdpt_5"                 ,&G_STDPT_5 );
+    m_tmvaReader_endcap2->AddVariable("shot_stdeta_5"                ,&G_STDETA_5 );
+    m_tmvaReader_endcap2->AddVariable("shot_deltapt_min"             ,&G_DELTAPT_MIN );
+
+    if (bookMethod(m_tmvaReader_barrel, m_tmvaReader_endcap1, m_tmvaReader_endcap2, "BDT method").isFailure()) return StatusCode::FAILURE;
+
+    // setupCuts();
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauShotFinder::finalize()
+{
+  StatusCode sc = AlgTool::finalize();
+  delete m_tmvaReader_barrel;
+  delete m_tmvaReader_endcap1;
+  delete m_tmvaReader_endcap2;
+  return sc;
+}
+
+StatusCode TauShotFinder::eventInitialize(TauCandidateData * /*data*/) {
+
+    //---------------------------------------------------------------------
+    // Create Shot ClusterContainer and register in StoreGate
+    //---------------------------------------------------------------------
+    m_shotClusterContainer = CaloClusterStoreHelper::makeContainer(&*evtStore(),   
+								 m_shotClusterContainerName,    
+								 msg()                  
+								 );
+
+    //---------------------------------------------------------------------
+    // Create Shot PFO container
+    //---------------------------------------------------------------------
+    m_PFOShotContainer = new xAOD::PFOContainer();
+    CHECK( evtStore()->record(m_PFOShotContainer, m_shotPFOContainerName ) );
+    m_PFOShotAuxStore = new xAOD::PFOAuxContainer();
+    CHECK( evtStore()->record( m_PFOShotAuxStore, m_shotPFOContainerName + "Aux." ) );
+    m_PFOShotContainer->setStore(m_PFOShotAuxStore);
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TauShotFinder::execute(TauCandidateData *data) {
+
+    xAOD::TauJet *pTau = data->xAODTau;
+    
+    //---------------------------------------------------------------------
+    // only run shower subtraction on 1-5 prong taus 
+    //---------------------------------------------------------------------
+    if (pTau->nTracks() == 0 || pTau->nTracks() >5 ) {
+       return StatusCode::SUCCESS;
+    }
+    ATH_MSG_DEBUG("");
+    ATH_MSG_DEBUG("New tau");
+
+    //---------------------------------------------------------------------
+    // retrieve cells around tau 
+    //---------------------------------------------------------------------
+    // get all calo cell container
+    const CaloCellContainer *pCellContainer = NULL;
+    CHECK( evtStore()->retrieve(pCellContainer, m_caloCellContainerName) );
+    
+    // get only EM cells within dR<0.2
+    // TODO: might be possible to select only EM1 cells, but probbaly wont 
+    //       speed things up much anyway
+    vector<CaloCell_ID::SUBCALO> emSubCaloBlocks;
+    emSubCaloBlocks.push_back(CaloCell_ID::LAREM);
+    boost::scoped_ptr<CaloCellList> pCells(new CaloCellList(pCellContainer,emSubCaloBlocks)); 
+
+    // TODO: change hardcoded 0.2 to tau cone variable, (or func. from TauJet?)
+    pCells->select(pTau->eta(), pTau->phi(), 0.4); 
+
+    // Dump cells into a std::vector since CaloCellList wont allow sorting
+    // (maybe this can be done faster at some point).
+    // Also apply very basic preselection
+    std::vector<const CaloCell*> cells;
+    CaloCellList::list_iterator cellItr = pCells->begin();
+    for(; cellItr!=pCells->end();++cellItr){
+        // require cells above 100 MeV
+        if( (*cellItr)->pt()*m_caloWeightTool->wtCell(*cellItr) < 100. ) continue;
+        // require cells in EM1 
+        int samp = (*cellItr)->caloDDE()->getSampling();
+        if( !( samp == CaloCell_ID::EMB1 || samp == CaloCell_ID::EME1 ) ) continue;
+        cells.push_back(*cellItr);
+    }
+    // sort cells in descending pt 
+    std::sort(cells.begin(),cells.end(),ptSort(*this));
+    
+    //---------------------------------------------------------------------
+    // shot seeding 
+    //---------------------------------------------------------------------
+    // get seed cells
+    std::vector<const CaloCell*> seedCells; 
+    std::set<IdentifierHash> seedCellHashes;
+    cellItr = cells.begin();
+    for(; cellItr != cells.end(); ++cellItr) {
+        const CaloCell* cell = (*cellItr);
+        const IdentifierHash cellHash = cell->caloDDE()->calo_hash();
+
+        // apply seed selection on nearest neighbours
+        std::vector<IdentifierHash> nextEta, prevEta;
+        m_calo_id->get_neighbours(cellHash,LArNeighbours::nextInEta,nextEta);
+        m_calo_id->get_neighbours(cellHash,LArNeighbours::prevInEta,prevEta);
+        std::vector<IdentifierHash> neighbours = nextEta;
+        neighbours.insert(neighbours.end(),prevEta.begin(),prevEta.end()); 
+        bool status = true;
+        std::vector<IdentifierHash>::iterator hashItr = neighbours.begin();
+        for(;hashItr!=neighbours.end();++hashItr){
+            // must not be next to seed cell (TODO: maybe this requirement can be removed)
+            if( seedCellHashes.find(*hashItr) != seedCellHashes.end() ){
+                status = false;
+                break;
+            }
+            // must be maximum
+            const CaloCell* neigCell = pCellContainer->findCell(*hashItr);
+            if( !neigCell ) continue;
+            if( neigCell->pt()*m_caloWeightTool->wtCell(neigCell) >= cell->pt()*m_caloWeightTool->wtCell(cell) ){
+                status = false;
+                break;
+            }
+        }
+        if( !status ) continue;        
+        seedCells.push_back(cell); 
+        seedCellHashes.insert(cellHash);
+    } // preselected cells
+    ATH_MSG_DEBUG("seedCells.size() = " << seedCells.size());
+    
+    // merge across phi and construct shots
+    while( seedCells.size() ){
+        
+        const CaloCell* cell = seedCells.front(); 
+        const IdentifierHash seedHash = cell->caloDDE()->calo_hash();
+
+        // look for match across phi in current seeds
+        const CaloCell* nextPhi = NULL;
+        const CaloCell* prevPhi = NULL;
+        for( cellItr = seedCells.begin(); cellItr!=seedCells.end(); ++cellItr){
+            if( (*cellItr) == cell ) continue;
+            IdentifierHash shotCellHash = (*cellItr)->caloDDE()->calo_hash();
+            if( this->isPhiNeighbour(seedHash,shotCellHash,true) )       nextPhi = (*cellItr);
+            else if( this->isPhiNeighbour(seedHash,shotCellHash,false) ) prevPhi = (*cellItr);
+        }
+       
+        const CaloCell* mergePhi = NULL;
+        if( nextPhi && prevPhi ){
+            // take higest-pt if merged up and down
+            if( nextPhi->pt()*m_caloWeightTool->wtCell(nextPhi) > prevPhi->pt()*m_caloWeightTool->wtCell(prevPhi) ) mergePhi = nextPhi;
+            else                                mergePhi = prevPhi;
+        }
+        else if (nextPhi) mergePhi = nextPhi;
+        else if (prevPhi) mergePhi = prevPhi;
+
+        // get neighbours in 5x1 window
+        std::vector<const CaloCell*> windowNeighbours = this->getNeighbours(pCellContainer,cell,2);
+        if( mergePhi ){
+            std::vector<const CaloCell*> mergeCells = this->getNeighbours(pCellContainer,mergePhi,2);
+            windowNeighbours.push_back(mergePhi);
+            windowNeighbours.insert(windowNeighbours.end(),mergeCells.begin(),mergeCells.end());
+        }
+
+        
+        // create seed cluster
+        xAOD::CaloCluster* shotCluster = CaloClusterStoreHelper::makeCluster(pCellContainer);
+        shotCluster->getCellLinks()->reserve(windowNeighbours.size()+1);
+        shotCluster->addCell(pCellContainer->findIndex(seedHash), 1.);
+        cellItr = windowNeighbours.begin();
+        for( ; cellItr!=windowNeighbours.end(); ++cellItr)
+            shotCluster->addCell(pCellContainer->findIndex((*cellItr)->caloDDE()->calo_hash()),1.0);
+        CaloClusterKineHelper::calculateKine(shotCluster,true,true);
+        m_shotClusterContainer->push_back(shotCluster);
+        
+        // create shot PFO and store it in output container
+        xAOD::PFO* shot = new xAOD::PFO();
+        m_PFOShotContainer->push_back( shot );
+
+        // Create element link from tau to shot
+        ElementLink<xAOD::PFOContainer> PFOElementLink;
+        PFOElementLink.toContainedElement( *m_PFOShotContainer, shot );
+        pTau->addShot_PFOLink( PFOElementLink );
+       
+        if( mergePhi ){
+            // interpolate position
+            double dPhi = TVector2::Phi_mpi_pi( mergePhi->phi() - cell->phi());
+            double ratio = mergePhi->pt()*m_caloWeightTool->wtCell(mergePhi)/(cell->pt()*m_caloWeightTool->wtCell(cell) + mergePhi->pt()*m_caloWeightTool->wtCell(mergePhi));
+            float phi = cell->phi()+dPhi*ratio;
+            float pt = cell->pt()*m_caloWeightTool->wtCell(cell)+mergePhi->pt()*m_caloWeightTool->wtCell(mergePhi);
+
+            shot->setP4( (float) pt, (float) cell->eta(), (float) phi, (float) cell->m());
+        }
+        else shot->setP4( (float) cell->pt()*m_caloWeightTool->wtCell(cell), (float) cell->eta(), (float) cell->phi(), (float) cell->m());
+        
+        shot->setBDTPi0Score( (float) -9999. );
+        shot->setCharge( 0. );
+        double center_mag = 0.0;
+        // No need to calculate cluster moments atm.
+        //if( !shotCluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 404, center_mag) ) ATH_MSG_WARNING("Couldn't retrieve CENTER_MAG moment. Set it to 0.");
+        shot->setCenterMag( (float) center_mag);
+        
+        ElementLink<xAOD::CaloClusterContainer> clusElementLink;
+        clusElementLink.toContainedElement( *m_shotClusterContainer, shotCluster );
+        shot->setClusterLink( clusElementLink );
+        shot->setAttribute<int>(xAOD::PFODetails::PFOAttributes::tauShots_nCellsInEta, m_nCellsInEta);
+        shot->setAttribute<int>(xAOD::PFODetails::PFOAttributes::tauShots_seedHash, seedHash);
+
+        // Get cell block for variable calculations
+        std::vector<std::vector<const CaloCell*> > cellBlock = TauShotVariableHelpers::getCellBlock(shot, m_calo_id);
+
+        // Some DEBUG statements
+        if (msgLvl(MSG::DEBUG)) { 
+          if(cell->pt()*m_caloWeightTool->wtCell(cell)>300){
+            ATH_MSG_DEBUG("");
+            ATH_MSG_DEBUG("New shot. \t block size phi = " << cellBlock.size() << " \t block size eta = " << cellBlock.at(0).size() << "\t shot->pt() = " << shot->pt());
+            for(unsigned iCellPhi = 0; iCellPhi<cellBlock.size();++iCellPhi){
+              for(unsigned iCellEta = 0; iCellEta<cellBlock.at(iCellPhi).size();++iCellEta){
+                const CaloCell* cell = cellBlock.at(iCellPhi).at(iCellEta);
+                if( cell==NULL ) ATH_MSG_DEBUG("Cell" << iCellPhi << iCellEta << ": \t NULL" );
+                else            ATH_MSG_DEBUG("Cell"<<iCellPhi<<iCellEta<<":\tPt = "<< cell->pt()*m_caloWeightTool->wtCell(cell)<<"\teta = "<<cell->eta()<<"\tphi = "<<cell->phi());
+              }
+            }
+          }
+        }
+
+        // set variables used for photon counting
+        m_pt1=TauShotVariableHelpers::ptWindow(cellBlock,1,m_caloWeightTool);
+        m_pt3=TauShotVariableHelpers::ptWindow(cellBlock,3,m_caloWeightTool);
+        m_pt5=TauShotVariableHelpers::ptWindow(cellBlock,5,m_caloWeightTool);
+        m_ws5=TauShotVariableHelpers::ws5(cellBlock,m_caloWeightTool);
+        m_sdevEta5_WRTmean=TauShotVariableHelpers::sdevEta_WRTmean(cellBlock,m_caloWeightTool);
+        m_sdevEta5_WRTmode=TauShotVariableHelpers::sdevEta_WRTmode(cellBlock,m_caloWeightTool);
+        m_sdevPt5=TauShotVariableHelpers::sdevPt(cellBlock,m_caloWeightTool);
+        m_deltaPt12_min=TauShotVariableHelpers::deltaPt12_min(cellBlock,m_caloWeightTool);
+        m_Fside_3not1=TauShotVariableHelpers::Fside(cellBlock,3,1,m_caloWeightTool);
+        m_Fside_5not1=TauShotVariableHelpers::Fside(cellBlock,5,1,m_caloWeightTool);
+        m_Fside_5not3=TauShotVariableHelpers::Fside(cellBlock,5,3,m_caloWeightTool);
+        m_fracSide_3not1=TauShotVariableHelpers::fracSide(cellBlock,3,1,m_caloWeightTool);
+        m_fracSide_5not1=TauShotVariableHelpers::fracSide(cellBlock,5,1,m_caloWeightTool);
+        m_fracSide_5not3=TauShotVariableHelpers::fracSide(cellBlock,5,3,m_caloWeightTool);
+        m_pt1OverPt3=TauShotVariableHelpers::ptWindowFrac(cellBlock,3,1,m_caloWeightTool);
+        m_pt3OverPt5=TauShotVariableHelpers::ptWindowFrac(cellBlock,5,3,m_caloWeightTool);
+
+        // Same variable names as in Stephanie's private code
+        G_PTFRAC=m_fracSide_3not1;
+        G_STDPT_5=m_sdevPt5;
+        G_STDETA_5=fmin(m_sdevEta5_WRTmean,0.0036);
+        G_DELTAPT_MIN=fmax(-1000.,fmin(m_deltaPt12_min,2000));
+
+        // Calculate BDT scores
+        int etaBin = getEtaBin(cell->eta());
+        float mergedBDTScore=getMergedBDTScore(etaBin);
+
+        ////////////////////////////////////////////////////////////////////////////////////////////
+        // Calculate number of photons in shot
+        ////////////////////////////////////////////////////////////////////////////////////////////
+        int nPhotons = getNPhotons(etaBin, mergedBDTScore, m_pt1);
+
+        ////////////////////////////////////////////////////////////////////////////////////////////
+        // Set variables in shot PFO
+        ////////////////////////////////////////////////////////////////////////////////////////////
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_pt1, m_pt1);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_pt3, m_pt3);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_pt5, m_pt5);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_ws5, m_ws5);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_sdevEta5_WRTmean, m_sdevEta5_WRTmean);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_sdevEta5_WRTmode, m_sdevEta5_WRTmode);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_sdevPt5, m_sdevPt5);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_deltaPt12_min, m_deltaPt12_min);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_Fside_3not1, m_Fside_3not1);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_Fside_5not1, m_Fside_5not1);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_Fside_5not3, m_Fside_5not3);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_fracSide_3not1, m_fracSide_3not1);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_fracSide_5not1, m_fracSide_5not1);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_fracSide_5not3, m_fracSide_5not3);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_pt1OverPt3, m_pt1OverPt3);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_pt3OverPt5, m_pt3OverPt5);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_mergedScore, mergedBDTScore);
+        shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_signalScore, -1.);
+        shot->setAttribute<int>(xAOD::PFODetails::PFOAttributes::tauShots_nPhotons, nPhotons);
+
+        // remove shot(s) from list
+        vector<const CaloCell*>::iterator cellItrNonConst;
+        cellItrNonConst = std::find(seedCells.begin(),seedCells.end(),cell);
+        seedCells.erase(cellItrNonConst);
+        if( mergePhi ){
+            cellItrNonConst = std::find(seedCells.begin(),seedCells.end(),mergePhi);
+            seedCells.erase(cellItrNonConst);
+        }
+
+        /*
+        ATH_MSG_DEBUG("Storing shot. pt: " << shot->pt()
+                        << ", eta: " << shot->eta()
+                        << ", phi: " << shot->phi()
+                        );
+        */
+          
+    } // seed cells
+    
+    
+    return StatusCode::SUCCESS;
+}
+
+void TauShotFinder::cleanup(TauCandidateData* /* data */) {
+    return;
+}
+
+StatusCode TauShotFinder::eventFinalize(TauCandidateData* /* data */) {
+    CHECK( CaloClusterStoreHelper::finalizeClusters(&*evtStore(),
+                            m_shotClusterContainer,
+                            m_shotClusterContainerName,
+                            msg()) );
+
+    return StatusCode::SUCCESS;
+}
+
+std::vector<const CaloCell*> TauShotFinder::getNeighbours(const CaloCellContainer* pCellContainer, 
+                                           const CaloCell* cell, 
+                                           int maxDepth)
+{
+    std::vector<const CaloCell*> cells;
+    this->addNeighbours(pCellContainer,cell,cells,0,maxDepth,true);  //next
+    this->addNeighbours(pCellContainer,cell,cells,0,maxDepth,false); //prev
+    return cells; 
+}
+
+void TauShotFinder::addNeighbours(const CaloCellContainer* pCellContainer,
+                                  const CaloCell* cell, 
+                                  std::vector<const CaloCell*>& cells,
+                                  int depth,
+                                  int maxDepth,
+                                  bool next)
+{
+    depth++; 
+    if( depth > maxDepth ) return;
+
+    const IdentifierHash cellHash = cell->caloDDE()->calo_hash();
+    std::vector<IdentifierHash> neigHashes;
+    if( next )
+        m_calo_id->get_neighbours(cellHash,LArNeighbours::nextInEta,neigHashes);
+    else
+        m_calo_id->get_neighbours(cellHash,LArNeighbours::prevInEta,neigHashes);
+    
+    std::vector<IdentifierHash>::iterator hashItr = neigHashes.begin();
+    for( ; hashItr!=neigHashes.end(); ++hashItr ){
+        const CaloCell* newCell = pCellContainer->findCell(*hashItr);
+        if(!newCell)continue;
+        cells.push_back(newCell);
+        this->addNeighbours(pCellContainer,newCell,cells,depth,maxDepth,next);
+        // no EM1 cell should have more than one neighbor. Just add this neigbor for now
+        // FIXME: Check whether it happens that a cell has > 1 neighbors
+        break; 
+    } 
+}
+
+bool TauShotFinder::isPhiNeighbour(IdentifierHash cell1Hash, IdentifierHash cell2Hash, bool next){
+    std::vector<IdentifierHash> neigHashes;
+    if( next ) m_calo_id->get_neighbours(cell1Hash,LArNeighbours::nextInPhi,neigHashes);
+    else       m_calo_id->get_neighbours(cell1Hash,LArNeighbours::prevInPhi,neigHashes);
+    std::vector<IdentifierHash>::iterator itr = neigHashes.begin();
+    for( ; itr!=neigHashes.end(); ++itr ){
+        if(cell2Hash == (*itr)) return true;
+    } 
+    return false;
+}
+
+float TauShotFinder::getEtaBin(float seedEta){
+    float absSeedEta=fabs(seedEta);
+    if(fabs(absSeedEta)<0.80)      return 0; // Central Barrel
+    else if(fabs(absSeedEta)<1.39) return 1; // Outer Barrel
+    else if(fabs(absSeedEta)<1.51) return 2; // crack
+    else if(fabs(absSeedEta)<1.80) return 3; // endcap, fine granularity
+    else return 4;                           // endcap, coarse granularity
+}
+
+float TauShotFinder::getMergedBDTScore(int etaBin){
+    float BDTScore = -1;
+    if(etaBin==0)      BDTScore = m_tmvaReader_barrel->EvaluateMVA( "BDT method" );  // barrel1
+    else if(etaBin==1) BDTScore = m_tmvaReader_barrel->EvaluateMVA( "BDT method" );  // barrel2
+    else if(etaBin==2) BDTScore = m_tmvaReader_barrel->EvaluateMVA( "BDT method" );  // just use barrel BDT for now to check how it looks in data
+    else if(etaBin==3) BDTScore = m_tmvaReader_endcap1->EvaluateMVA( "BDT method" ); // endcap1
+    else if(etaBin==4) BDTScore = m_tmvaReader_endcap2->EvaluateMVA( "BDT method" ); // endcap2
+    return BDTScore;
+}
+
+float TauShotFinder::getNPhotons(int etaBin, float mergedBDTScore, float seedEnergy){
+    if(etaBin==2) return 0; // no photon counting in crack atm
+    ATH_MSG_DEBUG("etaBin = " << etaBin  << ", seedEnergy = " << seedEnergy << ", m_minPtCut.at(etaBin) = " << m_minPtCut.at(etaBin) << "m_autoDoubleShotCut.at(etaBin) = " 
+      << m_autoDoubleShotCut.at(etaBin) << ", mergedBDTScore = " << mergedBDTScore << ", m_mergedBDTScoreCut.at(etaBin) = " << m_mergedBDTScoreCut.at(etaBin) );
+    if( seedEnergy < m_minPtCut.at(etaBin) ) return 0;
+    if( seedEnergy > m_autoDoubleShotCut.at(etaBin) ) return 2;
+    if( mergedBDTScore < m_mergedBDTScoreCut.at(etaBin) ) return 2;
+    return 1;
+}
+
+// some really slick c++ way of doing sort (since we need to use the member m_caloWeightTool)
+// how about learing a thing or two from python...
+TauShotFinder::ptSort::ptSort( const TauShotFinder& info ) : m_info(info) { } 
+bool TauShotFinder::ptSort::operator()( const CaloCell* c1, const CaloCell* c2 ){
+     return  c1->pt()*m_info.m_caloWeightTool->wtCell(c1) > c2->pt()*m_info.m_caloWeightTool->wtCell(c2);  
+}
+
+StatusCode TauShotFinder::bookMethod(TMVA::Reader *reader_barrel, 
+                                     TMVA::Reader *reader_endcap1, 
+                                     TMVA::Reader *reader_endcap2, 
+                                     const std::string &methodName) const 
+{
+    if (m_weightfile_barrel == ""){
+        ATH_MSG_ERROR("No weight m_weightfile_barrel given");
+        return StatusCode::FAILURE;
+    }
+    if (m_weightfile_endcap1 == ""){
+        ATH_MSG_ERROR("No weight m_weightfile_endcap1 given");
+        return StatusCode::FAILURE;
+    }
+    if (m_weightfile_endcap2 == ""){
+        ATH_MSG_ERROR("No weight m_weightfile_endcap2 given");
+        return StatusCode::FAILURE;
+    }
+    std::string resolvedFileName = PathResolver::find_file(m_weightfile_barrel, "DATAPATH");
+    if (resolvedFileName != ""){
+        ATH_MSG_DEBUG( "Parameterisation file found: " << resolvedFileName );
+    }
+    else {
+        ATH_MSG_ERROR( "Parameterisation file " << m_weightfile_barrel << " not found" );
+        return StatusCode::FAILURE;
+    }
+    reader_barrel->BookMVA( methodName, resolvedFileName);
+
+    resolvedFileName = PathResolver::find_file(m_weightfile_endcap1, "DATAPATH");
+    if (resolvedFileName != ""){
+        ATH_MSG_DEBUG( "Parameterisation file found: " << resolvedFileName );
+    }
+    else {
+        ATH_MSG_ERROR( "Parameterisation file " << m_weightfile_endcap1 << " not found" );
+        return StatusCode::FAILURE;
+    }
+    reader_endcap1->BookMVA( methodName, resolvedFileName);
+
+    resolvedFileName = PathResolver::find_file(m_weightfile_endcap2, "DATAPATH");
+    if (resolvedFileName != ""){
+        ATH_MSG_DEBUG( "Parameterisation file found: " << resolvedFileName );
+    }
+    else {
+        ATH_MSG_ERROR( "Parameterisation file " << m_weightfile_endcap2 << " not found" );
+        return StatusCode::FAILURE;
+    }
+    reader_endcap2->BookMVA( methodName, resolvedFileName);
+    return StatusCode::SUCCESS;
+}
+
+// EOF
diff --git a/Reconstruction/tauRec/src/TauShotVariableHelpers.cxx b/Reconstruction/tauRec/src/TauShotVariableHelpers.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..203437ef846dd03a802030ac19499975502a95fe
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauShotVariableHelpers.cxx
@@ -0,0 +1,357 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @brief implementation of photon shot variable calculation 
+ * 
+ * @author Will Davey <will.davey@cern.ch> 
+ * @author Benedict Winter <benedict.tobias.winter@cern.ch>
+ * @author Stephanie Yuen <stephanie.yuen@cern.ch> 
+ */
+
+#include "tauRec/TauShotVariableHelpers.h"
+
+using xAOD::PFO;
+using std::vector;
+
+namespace TauShotVariableHelpers {
+    std::vector<std::vector<const CaloCell*> > getCellBlock(xAOD::PFO* shot, const CaloCell_ID* calo_id){
+        std::vector<std::vector<const CaloCell*> > cellVector;
+        std::vector<const CaloCell*> oneEtaLayer;
+        int nCellsInEta = 0;
+        if( shot->attribute(xAOD::PFODetails::PFOAttributes::tauShots_nCellsInEta, nCellsInEta) == false) {
+            std::cout << "WARNING: Couldn't find nCellsInEta. Return empty cell block." << std::endl;
+            return cellVector;
+        }
+        int seedHash = 0;
+        if( shot->attribute(xAOD::PFODetails::PFOAttributes::tauShots_seedHash, seedHash) == false) {
+            std::cout << "WARNING: Couldn't find seed hash. Return empty cell block." << std::endl;
+            return cellVector;
+        }
+        for(int iCell=0;iCell<nCellsInEta;++iCell) oneEtaLayer.push_back(NULL);
+        // have two layers in phi
+        cellVector.push_back(oneEtaLayer);
+        cellVector.push_back(oneEtaLayer);
+        // get cluster from shot
+        const xAOD::CaloCluster* cluster = shot->cluster(0);
+        const CaloClusterCellLink* theCellLink = cluster->getCellLinks();
+        CaloClusterCellLink::const_iterator cellItr  = theCellLink->begin();
+        CaloClusterCellLink::const_iterator cellItrE = theCellLink->end();
+
+        // get seed cell from shot cluster
+        const CaloCell* seedCell=NULL;
+        for(;cellItr!=cellItrE;++cellItr){
+            if((*cellItr)->caloDDE()->calo_hash()!=(unsigned) seedHash) continue;
+            seedCell = *cellItr;
+            break;
+        }
+        if(seedCell==NULL){
+          std::cout << "WARNING: Couldn't find seed cell in shot cluster. Return empty cell block." << std::endl;
+        }
+        
+        // get merged cell in phi. Keep NULL if shot is not merged across phi
+        const CaloCell* mergedCell = NULL;
+        std::vector<IdentifierHash> nextInPhi;
+        std::vector<IdentifierHash> prevInPhi;
+        calo_id->get_neighbours(seedCell->caloDDE()->calo_hash(),LArNeighbours::nextInPhi,nextInPhi);
+        calo_id->get_neighbours(seedCell->caloDDE()->calo_hash(),LArNeighbours::prevInPhi,prevInPhi);
+        for(cellItr=theCellLink->begin();cellItr!=cellItrE;++cellItr){
+            std::vector<IdentifierHash>::iterator itr = nextInPhi.begin();
+            for( ; itr!=nextInPhi.end(); ++itr ){
+                if((*cellItr)->caloDDE()->calo_hash() != (*itr)) continue;
+                mergedCell = (*cellItr);
+                break;
+            }
+            if(mergedCell!=NULL) break;
+            itr = prevInPhi.begin();
+            for( ; itr!=prevInPhi.end(); ++itr ){
+                if((*cellItr)->caloDDE()->calo_hash() != (*itr)) continue;
+                mergedCell = (*cellItr);
+                break;
+            }
+            if(mergedCell!=NULL) break;
+        }
+        // store cells in the eta layer, which contains the seed cell
+        int nCellsFromSeed = 1;
+        const CaloCell* lastCell = seedCell;
+        cellVector.at(0).at(nCellsInEta/2) = seedCell; // store seed cell
+        std::vector<IdentifierHash> next;
+        while(lastCell!=NULL && nCellsFromSeed<nCellsInEta/2+1){
+            calo_id->get_neighbours(lastCell->caloDDE()->calo_hash(),LArNeighbours::nextInEta,next);
+            lastCell = NULL;
+            for(cellItr=theCellLink->begin();cellItr!=cellItrE;++cellItr){
+                std::vector<IdentifierHash>::iterator itr = next.begin();
+                for( ; itr!=next.end(); ++itr ){
+                    if((*cellItr)->caloDDE()->calo_hash() != (*itr)) continue;
+                    cellVector.at(0).at(nCellsInEta/2+nCellsFromSeed) = (*cellItr);
+                    lastCell = (*cellItr);
+                }
+            }
+            nCellsFromSeed++;
+        }
+        nCellsFromSeed = 1;
+        lastCell = seedCell;
+        while(lastCell!=NULL && nCellsFromSeed<nCellsInEta/2+1){
+            calo_id->get_neighbours(lastCell->caloDDE()->calo_hash(),LArNeighbours::prevInEta,next);
+            lastCell = NULL;
+            for(cellItr=theCellLink->begin();cellItr!=cellItrE;++cellItr){
+                std::vector<IdentifierHash>::iterator itr = next.begin();
+                for( ; itr!=next.end(); ++itr ){
+                    if((*cellItr)->caloDDE()->calo_hash() != (*itr)) continue;
+                    cellVector.at(0).at(nCellsInEta/2-nCellsFromSeed) = (*cellItr);
+                    lastCell = (*cellItr);
+                }
+            }
+            nCellsFromSeed++;
+        }
+        // store cells in the eta layer, which contains the merged cell
+        int nCellsFromMerged = 1;
+        lastCell = mergedCell; // is NULL if shot is not merged
+        cellVector.at(1).at(nCellsInEta/2) = mergedCell; // store merged cell
+        while(lastCell!=NULL && nCellsFromMerged<nCellsInEta/2+1){
+            calo_id->get_neighbours(lastCell->caloDDE()->calo_hash(),LArNeighbours::nextInEta,next);
+            lastCell = NULL;
+            for(cellItr=theCellLink->begin();cellItr!=cellItrE;++cellItr){
+                std::vector<IdentifierHash>::iterator itr = next.begin();
+                for( ; itr!=next.end(); ++itr ){
+                    if((*cellItr)->caloDDE()->calo_hash() != (*itr)) continue;
+                    cellVector.at(1).at(nCellsInEta/2+nCellsFromMerged) = (*cellItr);
+                    lastCell = (*cellItr);
+                }
+            }
+            nCellsFromMerged++;
+        }
+        nCellsFromMerged = 1;
+        lastCell = mergedCell;
+        while(lastCell!=NULL && nCellsFromMerged<nCellsInEta/2+1){
+            calo_id->get_neighbours(lastCell->caloDDE()->calo_hash(),LArNeighbours::prevInEta,next);
+            lastCell = NULL;
+            for(cellItr=theCellLink->begin();cellItr!=cellItrE;++cellItr){
+                std::vector<IdentifierHash>::iterator itr = next.begin();
+                for( ; itr!=next.end(); ++itr ){
+                    if((*cellItr)->caloDDE()->calo_hash() != (*itr)) continue;
+                    cellVector.at(1).at(nCellsInEta/2-nCellsFromMerged) = (*cellItr);
+                    lastCell = (*cellItr);
+                }
+            }
+            nCellsFromMerged++;
+        }
+        return cellVector;
+    
+    }
+
+
+    float mean_eta(vector<vector<const CaloCell*> > shotCells, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){
+        float sumEta=0.;
+        float sumWeight=0.;
+        vector<vector<const CaloCell*> >::iterator itrPhi = shotCells.begin();
+        for( ; itrPhi!=shotCells.end(); ++itrPhi ){
+            vector<const CaloCell*>::iterator itrEta = itrPhi->begin();
+            for( ; itrEta!=itrPhi->end(); ++itrEta ){
+                if((*itrEta) == NULL) continue;
+                sumWeight += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta);
+                sumEta    += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta) * (*itrEta)->eta();
+            }
+        }
+        if(sumWeight<=0.) return -99999.;
+        return sumEta/sumWeight;
+    }
+
+    float mean_pt(vector<vector<const CaloCell*> > shotCells, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){
+        float sumPt=0.;
+        int nCells = 0;
+        vector<vector<const CaloCell*> >::iterator itrPhi = shotCells.begin();
+        for( ; itrPhi!=shotCells.end(); ++itrPhi ){
+            vector<const CaloCell*>::iterator itrEta = itrPhi->begin();
+            for( ; itrEta!=itrPhi->end(); ++itrEta ){
+                if((*itrEta) == NULL) continue;
+                sumPt  += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta);
+                nCells ++;
+            }
+        }
+        if(nCells==0) return -99999.;
+        return sumPt/nCells;
+    }
+
+    float ptWindow(vector<vector<const CaloCell*> > shotCells, int windowSize, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){
+        // window size should be odd and noti be larger than eta window of shotCells
+        int nCells_eta = shotCells.at(0).size();
+        int seedIndex = nCells_eta/2;
+        if( windowSize%2!=1 )        return 0.;
+        if( windowSize > nCells_eta) return 0.;
+        float ptWindow  = 0.;
+        for(int iCell = 0; iCell != nCells_eta; ++iCell ){
+            if(fabs(iCell-seedIndex)>windowSize/2) continue;
+            if(shotCells.at(0).at(iCell) != NULL) ptWindow+=shotCells.at(0).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(iCell));
+            if(shotCells.at(1).at(iCell) != NULL) ptWindow+=shotCells.at(1).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(iCell));
+        }
+        return ptWindow;
+    }
+
+    float ws5(vector<vector<const CaloCell*> > shotCells, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){
+        int nCells_eta = shotCells.at(0).size();
+        int seedIndex = nCells_eta/2;
+        float sumWeight=0.;
+        float sumDev2=0.;
+        vector<vector<const CaloCell*> >::iterator itrPhi = shotCells.begin();
+        for( ; itrPhi!=shotCells.end(); ++itrPhi ){
+            for(unsigned iCell = 0; iCell != itrPhi->size(); ++iCell ){
+                if(itrPhi->at(iCell) == NULL) continue;
+                sumWeight += itrPhi->at(iCell)->pt()*m_caloWeightTool->wtCell(itrPhi->at(iCell));
+                sumDev2   += itrPhi->at(iCell)->pt()*m_caloWeightTool->wtCell(itrPhi->at(iCell)) * pow(iCell-seedIndex,2);
+            }
+        }
+        if(sumWeight<=0. || sumDev2 <0.) return -99999.;
+        return sqrt( sumDev2 / sumWeight );
+    }
+
+    float sdevEta_WRTmean(vector<vector<const CaloCell*> > shotCells, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){
+        float mean = mean_eta(shotCells, m_caloWeightTool); 
+        float sumWeight=0.;
+        float sumDev2=0.;
+        vector<vector<const CaloCell*> >::iterator itrPhi = shotCells.begin();
+        for( ; itrPhi!=shotCells.end(); ++itrPhi ){
+            vector<const CaloCell*>::iterator itrEta = itrPhi->begin();
+            for( ; itrEta!=itrPhi->end(); ++itrEta ){
+                if((*itrEta) == NULL) continue;
+                sumWeight += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta);
+                sumDev2   += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta) * pow((*itrEta)->eta() - mean,2);
+            }
+        }
+        if(sumWeight<=0. || sumDev2 <0.) return -99999.;
+        return sqrt( sumDev2 / sumWeight );
+    }
+
+    float sdevEta_WRTmode(vector<vector<const CaloCell*> > shotCells, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){
+        int nCells_eta = shotCells.at(0).size();
+        int seedIndex = nCells_eta/2;
+        float mode = shotCells.at(0).at(seedIndex)->eta();
+        float sumWeight=0.;
+        float sumDev2=0.;
+        vector<vector<const CaloCell*> >::iterator itrPhi = shotCells.begin();
+        for( ; itrPhi!=shotCells.end(); ++itrPhi ){
+            vector<const CaloCell*>::iterator itrEta = itrPhi->begin();
+            for( ; itrEta!=itrPhi->end(); ++itrEta ){
+                if((*itrEta) == NULL) continue;
+                sumWeight += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta);
+                sumDev2   += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta) * pow((*itrEta)->eta() - mode,2);
+            }
+        }
+        if(sumWeight<=0. || sumDev2 <0.) return -99999.;
+        return sqrt( sumDev2 / sumWeight );
+    }
+
+    float sdevPt(vector<vector<const CaloCell*> > shotCells, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){
+        float mean = mean_pt(shotCells, m_caloWeightTool);
+        float sumWeight=0.;
+        float sumDev2=0.;
+        vector<vector<const CaloCell*> >::iterator itrPhi = shotCells.begin();
+        for( ; itrPhi!=shotCells.end(); ++itrPhi ){
+            vector<const CaloCell*>::iterator itrEta = itrPhi->begin();
+            for( ; itrEta!=itrPhi->end(); ++itrEta ){
+                if((*itrEta) == NULL) continue;
+                sumWeight += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta);
+                sumDev2   += pow((*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta) - mean,2);
+            }
+        }
+        if(sumWeight<=0. || sumDev2 <0.) return -99999.;
+        return sqrt(sumDev2)/sumWeight;
+    }
+
+    float deltaPt12_min(vector<vector<const CaloCell*> > shotCells, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){
+        int nCells_eta = shotCells.at(0).size();
+        int seedIndex = nCells_eta/2;
+        bool haveLeft  = false;
+        bool haveRight = false;
+        float deltaPt_left  = 0.;
+        float deltaPt_right = 0.;
+        if(shotCells.at(0).at(seedIndex-1)!=NULL && shotCells.at(0).at(seedIndex-2)!=NULL){
+            haveLeft  = true;
+            deltaPt_left =  shotCells.at(0).at(seedIndex-1)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(seedIndex-1))
+                           -shotCells.at(0).at(seedIndex-2)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(seedIndex-2));
+            if(shotCells.at(1).at(seedIndex-1)!=NULL && shotCells.at(1).at(seedIndex-2)!=NULL){
+                deltaPt_left += shotCells.at(1).at(seedIndex-1)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(seedIndex-1))
+                               -shotCells.at(1).at(seedIndex-2)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(seedIndex-2));
+            }
+        }
+        if(shotCells.at(0).at(seedIndex+1)!=NULL && shotCells.at(0).at(seedIndex+2)!=NULL){
+            haveRight = true;
+            deltaPt_right =  shotCells.at(0).at(seedIndex+1)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(seedIndex+1))
+                            -shotCells.at(0).at(seedIndex+2)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(seedIndex+2));
+            if(shotCells.at(1).at(seedIndex+1)!=NULL && shotCells.at(1).at(seedIndex+2)!=NULL){
+                deltaPt_right += shotCells.at(1).at(seedIndex+1)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(seedIndex+1))
+                                -shotCells.at(1).at(seedIndex+2)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(seedIndex+1));
+            }
+        }
+        if(haveLeft && haveRight) return fmin(deltaPt_left,deltaPt_right);
+        if(haveLeft)              return deltaPt_left;
+        if(haveRight)             return deltaPt_right;
+        else                      return -1.;
+    }
+
+
+    float Fside(vector<vector<const CaloCell*> > shotCells, int largerWindow, int smallerWindow, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){
+        // window sizes should be odd and windows should be not larger than eta window of shotCells
+        int nCells_eta = shotCells.at(0).size();
+        int seedIndex = nCells_eta/2;
+        if( largerWindow%2!=1 || smallerWindow%2!=1) return 0.;
+        if( largerWindow <= smallerWindow)           return 0.;
+        if( largerWindow > nCells_eta)   return 0.;
+        float pt_largerWindow  = 0.;
+        float pt_smallerWindow = 0.;
+        for(int iCell = 0; iCell != nCells_eta; ++iCell ){
+            if(fabs(iCell-seedIndex)>largerWindow/2) continue;
+            if(shotCells.at(0).at(iCell)!=NULL) pt_largerWindow+=shotCells.at(0).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(iCell));
+            if(shotCells.at(1).at(iCell)!=NULL) pt_largerWindow+=shotCells.at(1).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(iCell));
+            if(fabs(iCell-seedIndex)>smallerWindow/2) continue;
+            if(shotCells.at(0).at(iCell)!=NULL) pt_smallerWindow+=shotCells.at(0).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(iCell));
+            if(shotCells.at(1).at(iCell)!=NULL) pt_smallerWindow+=shotCells.at(1).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(iCell));
+        }
+        if(pt_smallerWindow==0.) return -99999.;
+        return (pt_largerWindow-pt_smallerWindow)/pt_smallerWindow;
+    }
+
+    float fracSide(vector<vector<const CaloCell*> > shotCells, int largerWindow, int smallerWindow, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){
+        // window sizes should be odd and windows should be not larger than eta window of shotCells
+        int nCells_eta = shotCells.at(0).size();
+        int seedIndex = nCells_eta/2;
+        if( largerWindow%2!=1 || smallerWindow%2!=1) return 0.;
+        if( largerWindow <= smallerWindow)           return 0.;
+        if( largerWindow > nCells_eta)   return 0.;
+        float pt_largerWindow  = 0.;
+        float pt_smallerWindow = 0.;
+        for(int iCell = 0; iCell != nCells_eta; ++iCell ){
+            if(fabs(iCell-seedIndex)>largerWindow/2) continue;
+            if(shotCells.at(0).at(iCell)!=NULL) pt_largerWindow+=shotCells.at(0).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(iCell));
+            if(shotCells.at(1).at(iCell)!=NULL) pt_largerWindow+=shotCells.at(1).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(iCell));
+            if(fabs(iCell-seedIndex)>smallerWindow/2) continue;
+            if(shotCells.at(0).at(iCell)!=NULL) pt_smallerWindow+=shotCells.at(0).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(iCell));
+            if(shotCells.at(1).at(iCell)!=NULL) pt_smallerWindow+=shotCells.at(1).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(iCell));
+        }
+        if(pt_largerWindow==0.) return -99999.;
+        return (pt_largerWindow-pt_smallerWindow)/pt_largerWindow;
+    }
+
+    float ptWindowFrac(vector<vector<const CaloCell*> > shotCells, int largerWindow, int smallerWindow, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){
+        // window sizes should be odd and windows should be not larger than eta window of shotCells
+        int nCells_eta = shotCells.at(0).size();
+        int seedIndex = nCells_eta/2;
+        if( largerWindow%2!=1 || smallerWindow%2!=1) return 0.;
+        if( largerWindow <= smallerWindow)           return 0.;
+        if( largerWindow > nCells_eta)   return 0.;
+        float pt_largerWindow  = 0.;
+        float pt_smallerWindow = 0.;
+        for(int iCell = 0; iCell != nCells_eta; ++iCell ){
+            if(fabs(iCell-seedIndex)>largerWindow/2) continue;
+            if(shotCells.at(0).at(iCell)!=NULL) pt_largerWindow+=shotCells.at(0).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(iCell));
+            if(shotCells.at(1).at(iCell)!=NULL) pt_largerWindow+=shotCells.at(1).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(iCell));
+            if(fabs(iCell-seedIndex)>smallerWindow/2) continue;
+            if(shotCells.at(0).at(iCell)!=NULL) pt_smallerWindow+=shotCells.at(0).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(iCell));
+            if(shotCells.at(1).at(iCell)!=NULL) pt_smallerWindow+=shotCells.at(1).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(iCell));
+        }
+        if(pt_largerWindow==0.) return -99999.;
+        return pt_smallerWindow/pt_largerWindow;
+    }
+}
+
diff --git a/Reconstruction/tauRec/src/TauSubstructureVariables.cxx b/Reconstruction/tauRec/src/TauSubstructureVariables.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..30dd7035112353b5a268a473424b6946234bb9be
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauSubstructureVariables.cxx
@@ -0,0 +1,352 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//********************************************************************//
+// NAME:     TauSubstructureVariables.cxx                             //
+// PACKAGE:  offline/Reconstruction/tauRec                            //
+// AUTHORS:  M. Trottier-McDonald                                     //
+// CREATED:  January 11 2010                                          //
+//********************************************************************//
+
+#include <algorithm> 
+#include <math.h>
+#include <sstream>
+
+#include "GaudiKernel/Property.h"
+#include "FourMomUtils/P4Helpers.h"
+
+#include "AnalysisUtils/AnalysisMisc.h"
+
+#include "xAODJet/Jet.h"
+#include "xAODTau/TauJet.h"
+
+#include "tauRec/CaloClusterVariables.h"
+#include "tauRec/TauSubstructureVariables.h"
+
+#include "tauRec/KineUtils.h"
+#include "CaloUtils/CaloVertexedCluster.h"
+//#include "CaloEvent/CaloVertexedCluster.h"
+
+using CLHEP::GeV;
+
+const double TauSubstructureVariables::DEFAULT = -1111.;
+
+//**********************************
+// Constructor
+//**********************************
+
+TauSubstructureVariables::TauSubstructureVariables(
+		const std::string& type,
+		const std::string& name,
+		const IInterface* parent) :
+		TauToolBase(type, name, parent),
+		m_maxPileUpCorrection(4 * GeV),
+		m_pileUpAlpha(1.0),
+		m_doVertexCorrection(false), //FF: don't do cell correction by default
+		m_inAODmode(false) {
+	declareInterface<TauToolBase > (this);
+	declareProperty("maxPileUpCorrection", m_maxPileUpCorrection);
+	declareProperty("pileUpAlpha", m_pileUpAlpha);
+	declareProperty("VertexCorrection", m_doVertexCorrection);
+	declareProperty("inAODmode", m_inAODmode);
+}
+
+
+//**********************************
+// Destructor
+//**********************************
+
+TauSubstructureVariables::~TauSubstructureVariables() {
+}
+
+
+//***********************************
+// Initialize method
+//***********************************
+
+StatusCode TauSubstructureVariables::initialize() {
+	return StatusCode::SUCCESS;
+}
+
+StatusCode TauSubstructureVariables::eventInitialize(TauCandidateData * /*data*/) {
+	return StatusCode::SUCCESS;
+}
+
+
+//************************************
+// Execute method
+//************************************
+
+StatusCode TauSubstructureVariables::execute(TauCandidateData *data) {
+	// Getting our hands on the TauJet object
+	//----------------------------------------
+	xAOD::TauJet* pTau = data->xAODTau;
+
+	// Getting the jet seed
+	// By asking taujet instead of TauCandidateData->seed, we take advantage of the machinery already
+	// in place to retrieve a jet seed for track only candidates.
+	//------------------------------------------------------------------------------------------------
+	const xAOD::Jet* taujetseed = (*pTau->jetLink());
+
+	//*****************************************************
+	// calculate some tau substructure variables
+	//*****************************************************
+
+	CaloClusterVariables CaloClusterVariablesTool;
+	CaloClusterVariablesTool.setVertexCorrection(m_doVertexCorrection);
+
+	bool isFilled = CaloClusterVariablesTool.update(pTau);
+
+	if (!isFilled) {
+		if (!taujetseed) ATH_MSG_DEBUG("Taujet->jet() pointer is NULL: calo cluster variables will be set to -1111");
+		else ATH_MSG_DEBUG("problem in calculating calo cluster variables -> will be set to -1111");
+
+		pTau->setDetail(xAOD::TauJetParameters::numCells , static_cast<int>(0) );
+		pTau->setDetail(xAOD::TauJetParameters::numTopoClusters , static_cast<int>(DEFAULT) );
+		pTau->setDetail(xAOD::TauJetParameters::numEffTopoClusters , static_cast<float>(DEFAULT) );
+		pTau->setDetail(xAOD::TauJetParameters::topoInvMass,  static_cast<float>(DEFAULT) );
+		pTau->setDetail(xAOD::TauJetParameters::effTopoInvMass,  static_cast<float>(DEFAULT) );
+		pTau->setDetail(xAOD::TauJetParameters::topoMeanDeltaR,  static_cast<float>(DEFAULT) );
+		pTau->setDetail(xAOD::TauJetParameters::effTopoMeanDeltaR,  static_cast<float>(DEFAULT) );
+
+	} else {
+		// Getting the variables
+		//-----------------------
+		double TopoInvMass = CaloClusterVariablesTool.totalMass();
+		double EffTopoInvMass = CaloClusterVariablesTool.effectiveMass();
+		unsigned int NumTopoClusters = CaloClusterVariablesTool.numConstituents();
+		double NumEffTopoClusters = CaloClusterVariablesTool.effectiveNumConstituents();
+		double TopoMeanDeltaR = CaloClusterVariablesTool.averageRadius();
+		double EffTopoMeanDeltaR = CaloClusterVariablesTool.averageEffectiveRadius();
+		unsigned int Ncells = CaloClusterVariablesTool.numCells();
+
+		ATH_MSG_VERBOSE(" Substructure variables: ");
+		ATH_MSG_VERBOSE("-------------------------");
+		ATH_MSG_VERBOSE("       TopoInvMass: " << TopoInvMass);
+		ATH_MSG_VERBOSE("    EffTopoInvMass: " << EffTopoInvMass);
+		ATH_MSG_VERBOSE("   NumTopoClusters: " << NumTopoClusters);
+		ATH_MSG_VERBOSE("NumEffTopoClusters: " << NumEffTopoClusters);
+		ATH_MSG_VERBOSE("    TopoMeanDeltaR: " << TopoMeanDeltaR);
+		ATH_MSG_VERBOSE(" EffTopoMeanDeltaR: " << EffTopoMeanDeltaR);
+		ATH_MSG_VERBOSE("          NumCells: " << Ncells);
+
+		//Record the variables
+		//---------------------
+
+		if (!m_inAODmode) pTau->setDetail(xAOD::TauJetParameters::numCells ,  static_cast<int>  (Ncells)             );
+		pTau->setDetail(xAOD::TauJetParameters::numTopoClusters            ,  static_cast<int>  (NumTopoClusters)    );
+		pTau->setDetail(xAOD::TauJetParameters::numEffTopoClusters         ,  static_cast<float>(NumEffTopoClusters) );
+		pTau->setDetail(xAOD::TauJetParameters::topoInvMass                ,  static_cast<float>(TopoInvMass)	     );
+		pTau->setDetail(xAOD::TauJetParameters::effTopoInvMass             ,  static_cast<float>(EffTopoInvMass)     );
+		pTau->setDetail(xAOD::TauJetParameters::topoMeanDeltaR             ,  static_cast<float>(TopoMeanDeltaR)     );
+		pTau->setDetail(xAOD::TauJetParameters::effTopoMeanDeltaR          ,  static_cast<float>(EffTopoMeanDeltaR)  );
+
+	}
+
+	//*****************************************************
+	// calculate some new cluster based ID variables
+	//*****************************************************
+
+	if (taujetseed == NULL) {
+
+		// No jet seed? Warning! Fill variables with dummy values
+		//--------------------------------------------------------
+
+		ATH_MSG_DEBUG("Taujet->jet() pointer is NULL: substructure variables will be set to -1111");
+
+		pTau->setDetail(xAOD::TauJetParameters::lead2ClusterEOverAllClusterE, static_cast<float>(DEFAULT)  );
+		pTau->setDetail(xAOD::TauJetParameters::lead3ClusterEOverAllClusterE, static_cast<float>(DEFAULT)  );
+		pTau->setDetail(xAOD::TauJetParameters::caloIso           	    	, static_cast<float>(DEFAULT)  );
+		pTau->setDetail(xAOD::TauJetParameters::caloIsoCorrected            , static_cast<float>(DEFAULT)  );
+		pTau->setDetail(xAOD::TauJetParameters::dRmax                       , static_cast<float>(DEFAULT)  );
+
+		return StatusCode::SUCCESS;
+	}
+
+	// New cluster-based variables
+	float totalEnergy(0.);
+	float calo_iso(0.);
+	float dr(0.);
+
+	unsigned int num_clusters(0);
+	const xAOD::CaloCluster* incluster;
+	std::vector<const xAOD::CaloCluster*> vClusters;
+
+	// loop over all clusters of the jet seed
+	xAOD::JetConstituentVector jcv = taujetseed->getConstituents();
+	xAOD::JetConstituentVector::const_iterator nav_it   = jcv.begin();
+	xAOD::JetConstituentVector::const_iterator nav_itE  = jcv.end();
+	for (; nav_it != nav_itE; ++nav_it) {
+		++num_clusters;
+
+		incluster = dynamic_cast<const xAOD::CaloCluster*>( (*nav_it)->rawConstituent() );
+		if (!incluster) continue;
+
+		// save all clusters of jet seed
+		vClusters.push_back(incluster);
+
+		// calc total energy
+		totalEnergy += incluster->e();
+
+		//apply Vertex correction on a temporary
+		TLorentzVector tempclusvec;
+		if (m_doVertexCorrection && pTau->vertexLink())
+			tempclusvec = xAOD::CaloVertexedCluster(*incluster, (*pTau->vertexLink())->position()).p4();
+		else
+			tempclusvec = xAOD::CaloVertexedCluster(*incluster).p4();
+
+		dr = Tau1P3PKineUtils::deltaR(pTau->eta(),pTau->phi(), tempclusvec.Eta(), tempclusvec.Phi());
+		if (0.2 <= dr && dr < 0.4) {
+			calo_iso += tempclusvec.Et();
+		}
+	}
+
+	// now sort cluster by energy
+	AnalysisUtils::Sort::e(&vClusters);
+
+	// determine energy sum of leading 2 and leading 3 clusters
+	float sum2LeadClusterE(0.);
+	float sum3LeadClusterE(0.);
+	std::vector<const xAOD::CaloCluster*>::const_iterator icluster(vClusters.begin());
+	std::vector<const xAOD::CaloCluster*>::const_iterator icluster_end(vClusters.end());
+
+	for (; icluster != icluster_end && icluster != vClusters.begin() + 3; ++icluster) {
+		if (icluster < vClusters.begin() + 2) {
+			sum2LeadClusterE += (*icluster)->e();
+		}
+		sum3LeadClusterE += (*icluster)->e();
+	}
+
+	//record variables
+	if (totalEnergy != 0) {
+		ATH_MSG_VERBOSE(" lead2ClusterEOverAllClusterE: " << sum2LeadClusterE / totalEnergy);
+		ATH_MSG_VERBOSE(" lead3ClusterEOverAllClusterE: " << sum3LeadClusterE / totalEnergy);
+
+		pTau->setDetail(xAOD::TauJetParameters::lead2ClusterEOverAllClusterE, static_cast<float>(sum2LeadClusterE / totalEnergy)  );
+		pTau->setDetail(xAOD::TauJetParameters::lead3ClusterEOverAllClusterE, static_cast<float>(sum3LeadClusterE / totalEnergy)  );
+	}
+
+	ATH_MSG_VERBOSE(" caloIso: " << calo_iso);
+	pTau->setDetail(xAOD::TauJetParameters::caloIso, static_cast<float>(calo_iso)  );
+
+
+	// calculate calorimeter energies in different layers
+	float PSSEnergy(0.);
+	float EMEnergy(0.);
+	float HADEnergy(0.);
+	icluster = vClusters.begin();
+	for (; icluster != icluster_end; ++icluster) {
+		float clEnergy = (*icluster)->e();
+
+		//Calculate the fractions of energy in different calorimeter layers
+		const xAOD::CaloCluster *cl = *icluster;
+		float PreSampler = cl->eSample(CaloSampling::PreSamplerB) + cl->eSample(CaloSampling::PreSamplerE);
+		float EMLayer1   = cl->eSample(CaloSampling::EMB1) + cl->eSample(CaloSampling::EME1);
+		float EMLayer2   = cl->eSample(CaloSampling::EMB2) + cl->eSample(CaloSampling::EME2);
+
+		float Energy = cl->rawE();
+		float PSSF = Energy != 0 ? (PreSampler + EMLayer1) / Energy : 0;
+		float EM2F = Energy != 0 ? EMLayer2 / Energy : 0;
+		float EMF = PSSF + EM2F;
+
+		PSSEnergy += PSSF * clEnergy;
+		EMEnergy  += EMF * clEnergy;
+		HADEnergy += (Energy != 0) ? (1 - EMF) * clEnergy : 0;
+	}
+
+	// calculate trk momentum
+	float trkSysMomentum(0.);
+	for (unsigned int i(0); i < pTau->nTracks(); ++i) {
+		trkSysMomentum += pTau->track(i)->pt()	* cosh(pTau->track(i)->eta());
+	}
+
+	float fPSSFraction 			= (totalEnergy != 0) ? PSSEnergy / totalEnergy : DEFAULT;
+	float fChPIEMEOverCaloEME 	= (EMEnergy != 0) ? (trkSysMomentum - HADEnergy) / EMEnergy : DEFAULT;
+	float fEMPOverTrkSysP 		= DEFAULT;
+	if (pTau->nTracks() > 0) fEMPOverTrkSysP = (trkSysMomentum != 0) ? EMEnergy / trkSysMomentum : DEFAULT;
+
+	pTau->setDetail(xAOD::TauJetParameters::PSSFraction,		static_cast<float>(fPSSFraction));
+	pTau->setDetail(xAOD::TauJetParameters::ChPiEMEOverCaloEME,	static_cast<float>(fChPIEMEOverCaloEME));
+	pTau->setDetail(xAOD::TauJetParameters::EMPOverTrkSysP,		static_cast<float>(fEMPOverTrkSysP));
+
+
+	// get primary vertex container
+	// CALO_ISO_CORRECTED
+	// JVF and PT_PILEUP
+	// jvf and sumPtTrk are now a vector and the old run1-type jvf value is stored in the 0-th element
+	// sumPtTrk is calculated wrt Vertices
+
+	float jvf(0.0);
+	float sumPtTrk(0.0);
+
+	// for tau trigger: JVF and sumPtTrack are not available
+	bool inTrigger = false;
+	StatusCode sc;
+	if (data->hasObject("InTrigger?")) sc = data->getObject("InTrigger?", inTrigger);
+
+	if (!sc.isSuccess() || !inTrigger)
+	{
+		std::vector<float> sumPtTrkvec;
+		std::vector<float> jvfvec;
+
+		// ToDo still need to check if the 500MeV threshold is correct
+		taujetseed->getAttribute(xAOD::JetAttribute::SumPtTrkPt500, sumPtTrkvec);
+		taujetseed->getAttribute(xAOD::JetAttribute::JVF, jvfvec);
+
+		if (!jvfvec.empty() && !sumPtTrkvec.empty()) {
+			// ToDo need to check if first vertex is the vertex we want to use here!
+			jvf = jvfvec[0];
+			sumPtTrk = sumPtTrkvec[0];
+		}
+		else {
+			ATH_MSG_WARNING("jvf value vector and/or sumPtTrk vector returned from seed jet is empty!");
+		}
+	}
+
+	float pt_pileup = (1.0 - jvf) * sumPtTrk;
+
+	const float max_pileup_correction = m_maxPileUpCorrection;
+	const float alpha = m_pileUpAlpha;
+	float pileup_correction = alpha * pt_pileup;
+
+	ATH_MSG_VERBOSE("   --------------------------------------");
+	ATH_MSG_VERBOSE("   Pile-up correction parameter");
+	ATH_MSG_VERBOSE("   -> sumPtTrk:        " << sumPtTrk);
+	ATH_MSG_VERBOSE("   -> jvf:             " << jvf);
+	ATH_MSG_VERBOSE("   -> pt_pileup:       " << pt_pileup);
+	ATH_MSG_VERBOSE("   -> alpha:           " << alpha);
+	ATH_MSG_VERBOSE("   -> max pileup corr: " << max_pileup_correction);
+
+	if (pileup_correction > max_pileup_correction) {
+		pileup_correction = max_pileup_correction;
+	}
+	const float calo_iso_corrected = calo_iso - pileup_correction;
+
+	ATH_MSG_VERBOSE("   -> pileup corr:     " << pileup_correction);
+	ATH_MSG_VERBOSE("   --------------------------------------");
+
+	//record variable
+	ATH_MSG_VERBOSE(" caloIsoCorrected: " << calo_iso_corrected);
+	pTau->setDetail(xAOD::TauJetParameters::caloIsoCorrected, static_cast<float>(calo_iso_corrected)  );
+
+	// calculate dRMax
+	unsigned int numTrack(pTau->nTracks());
+	if (numTrack > 0) {
+		float dRmin = -1 * -1111;
+		float dRmax = -1111;
+		float dR;
+
+		for (unsigned int i(0); i < numTrack; ++i) {
+			if (pTau->track(i) == 0) continue;
+			dR = Tau1P3PKineUtils::deltaR( pTau->track(i)->eta(), pTau->track(i)->phi(), pTau->eta(), pTau->phi() );
+			if (dRmin > dR) dRmin = dR;
+			if (dRmax < dR) dRmax = dR;
+		}
+		//record variable
+		ATH_MSG_VERBOSE(" dRmax: " << dRmax);
+		pTau->setDetail(xAOD::TauJetParameters::dRmax, static_cast<float>(dRmax)  );
+	}
+
+	return StatusCode::SUCCESS;
+}
diff --git a/Reconstruction/tauRec/src/TauTestDump.cxx b/Reconstruction/tauRec/src/TauTestDump.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..fd1748b3ec26318babb4b8509a56a091649ee1e7
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauTestDump.cxx
@@ -0,0 +1,127 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauTestDump.cxx
+// package:     Reconstruction/tauRec
+// authors:     Felix Friedrich
+// date:        2012-11-05
+// 
+//-----------------------------------------------------------------------------
+
+#include <GaudiKernel/IToolSvc.h>
+#include <GaudiKernel/ListItem.h>
+
+#include "FourMomUtils/P4Helpers.h"
+#include "FourMom/P4EEtaPhiM.h"
+#include "CLHEP/Vector/LorentzVector.h"
+#include "Particle/TrackParticle.h"
+
+
+#include "tauRec/TauCandidateData.h"
+//#include "tauEvent/TauCommonDetails.h"
+//#include "tauEvent/TauPi0Details.h"
+//#include "tauEvent/TauPi0Cluster.h"
+#include "xAODTau/TauJet.h"
+
+//#include "tauEvent/TauJetParameters.h"        
+
+#include "tauRec/TauTestDump.h"
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+
+TauTestDump::TauTestDump(const std::string &type,
+    const std::string &name,
+    const IInterface *parent) :
+TauToolBase(type, name, parent) {
+    declareInterface<TauToolBase > (this);
+}
+
+//-----------------------------------------------------------------------------
+// Destructor
+//-----------------------------------------------------------------------------
+
+TauTestDump::~TauTestDump() {
+}
+
+
+//-----------------------------------------------------------------------------
+// Initializer
+//-----------------------------------------------------------------------------
+
+StatusCode TauTestDump::initialize() {
+    return StatusCode::SUCCESS;
+}
+
+
+//-----------------------------------------------------------------------------
+// Finalizer
+//-----------------------------------------------------------------------------
+
+StatusCode TauTestDump::finalize() {
+    return StatusCode::SUCCESS;
+}
+
+
+//-----------------------------------------------------------------------------
+// Execution
+//-----------------------------------------------------------------------------
+StatusCode TauTestDump::execute(TauCandidateData *data) {
+
+    ATH_MSG_INFO("=== TAU TEST DUMP BEGIN ==================== ");
+  
+    xAOD::TauJet *pTau = data->xAODTau;
+    
+    if (pTau == NULL) {
+        ATH_MSG_ERROR("no candidate given");
+        return StatusCode::FAILURE;
+    }
+
+    ATH_MSG_INFO("Tau recorded with: pt="<< pTau->pt() <<", eta=" <<pTau->eta()<<", phi="<<pTau->phi());
+    float tfFlightPathSig;
+    float ipSigLeadTrk;
+    pTau->detail(xAOD::TauJetParameters::ipSigLeadTrk, ipSigLeadTrk);
+    pTau->detail(xAOD::TauJetParameters::trFlightPathSig,tfFlightPathSig );
+    ATH_MSG_INFO(" numTrack="<<pTau->nTracks() << ", tfFlightPathSig=" << tfFlightPathSig <<", ipSigLeadTrk=" << ipSigLeadTrk );
+    
+    //stop here
+    return StatusCode::SUCCESS;
+    
+    if (pTau->nTracks() != 1) {
+      // Bonn Pi0 calculated only for 1p taus --> leave test case
+      ATH_MSG_INFO("Bonn Pi0 calculated only for 1p taus --> leave test case");
+      return StatusCode::SUCCESS;
+    }
+
+    // Default PFO pi0
+    ATH_MSG_INFO("dumping pi0 standard");
+    if (pTau->nPi0_PFOs()>0) {
+	    for (unsigned int i=0; i<pTau->nPi0_PFOs();++i) ATH_MSG_INFO(pTau->pi0_PFO(i)->e()<< " ");
+    }
+    else ATH_MSG_INFO("no pi0 cand");
+
+    // Cell-based PFO pi0
+    ATH_MSG_INFO("dumping pi0 cell-based");
+    if (pTau->nCellBased_Pi0_PFOs()>0) {
+	    for (unsigned int i=0; i<pTau->nCellBased_Pi0_PFOs();++i) ATH_MSG_INFO(pTau->cellBased_Pi0_PFO(i)->e()<< " ");
+    }
+    else ATH_MSG_INFO("no pi0 cand");
+
+    // EFlow PF0 pi0
+    ATH_MSG_INFO("dumping pi0 eflow");
+    if (pTau->nEflowRec_Pi0_PFOs()>0) {
+	    for (unsigned int i=0; i<pTau->nEflowRec_Pi0_PFOs();++i) ATH_MSG_INFO(pTau->eflowRec_Pi0_PFO(i)->e()<< " ");
+    }
+    else ATH_MSG_INFO("no pi0 cand");
+
+    ATH_MSG_INFO("end dumping pi0");
+    
+    ATH_MSG_INFO("=== TAU TEST DUMP END ==================== ");
+
+    return StatusCode::SUCCESS;
+}
+
+
diff --git a/Reconstruction/tauRec/src/TauToolBase.cxx b/Reconstruction/tauRec/src/TauToolBase.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8ce8a56656b38981bf7e09510a2508f85cf16e48
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauToolBase.cxx
@@ -0,0 +1,111 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauBuilderHelper.cxx
+// package:     Reconstruction/tauEvent
+// authors:     Lukasz Janyst
+// date:        2007-02-13
+//
+//  MODIFICATIONS
+// 2008-04-22: (nicom) moved setObject()/getObject() to TauCandidateData
+//-----------------------------------------------------------------------------
+
+#include "tauRec/TauToolBase.h"
+
+static const InterfaceID TauToolBaseID( "TauToolBase", 1, 0 );
+
+const InterfaceID& TauToolBase::interfaceID() {
+    return TauToolBaseID;
+}
+
+
+//-------------------------------------------------------------------------
+// Constructor
+//-------------------------------------------------------------------------
+TauToolBase :: TauToolBase( const std::string &type,
+        const std::string &name,
+        const IInterface  *parent ):
+    AthAlgTool(type, name, parent)
+{
+}
+
+//-------------------------------------------------------------------------
+// Destructor
+//-------------------------------------------------------------------------
+TauToolBase :: ~TauToolBase()
+{
+}
+
+//-------------------------------------------------------------------------
+// Initializer
+//-------------------------------------------------------------------------
+StatusCode TauToolBase :: initialize()
+{
+    return StatusCode :: SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// Initializer
+//-------------------------------------------------------------------------
+StatusCode TauToolBase :: eventInitialize( TauCandidateData *)
+{
+    return StatusCode :: SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// Execute
+//-------------------------------------------------------------------------
+StatusCode TauToolBase :: execute( TauCandidateData * )
+{
+    return StatusCode :: SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// Cleanup
+//-------------------------------------------------------------------------
+void TauToolBase :: cleanup( TauCandidateData * )
+{
+}
+
+//-------------------------------------------------------------------------
+// Finalizer
+//-------------------------------------------------------------------------
+StatusCode TauToolBase :: eventFinalize( TauCandidateData * )
+{
+    return StatusCode :: SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// Finalizer
+//-------------------------------------------------------------------------
+StatusCode TauToolBase :: finalize()
+{
+    return StatusCode :: SUCCESS;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// Helpers
+template <class T>
+bool TauToolBase::openContainer(T* &container, std::string containerName, bool printFATAL) {
+    StatusCode sc = evtStore()->retrieve(container, containerName);
+    if (sc.isFailure() || !container) {
+      if (printFATAL) ATH_MSG_FATAL("Container (" << containerName << ") not found in StoreGate");
+      return 0;
+    }
+    return container;
+}
+
+template <class T>
+bool TauToolBase::retrieveTool(T & tool) {
+    if (tool.retrieve().isFailure()) {
+        ATH_MSG_FATAL("Failed to retrieve tool " << tool);
+        return false;
+    } else {
+        ATH_MSG_VERBOSE("Retrieved tool " << tool);
+    }
+    return true;
+}
+
diff --git a/Reconstruction/tauRec/src/TauTrackFilter.cxx b/Reconstruction/tauRec/src/TauTrackFilter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..acf573be1b86830228ac233cd96bae928cd0f003
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauTrackFilter.cxx
@@ -0,0 +1,359 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauTrackFilter.cxx
+// package:     Reconstruction/tauRec
+// authors:     Robert Clarke, Blake Burghgrave
+// date:        2014-01-04
+//
+//
+//-----------------------------------------------------------------------------
+
+#include <GaudiKernel/IToolSvc.h>
+#include <GaudiKernel/ListItem.h>
+
+#include "FourMomUtils/P4Helpers.h"
+#include "FourMom/P4EEtaPhiM.h"
+
+#include "tauRec/TauCandidateData.h"
+
+#include "tauRec/TauTrackFilter.h"
+#include "tauRec/TauTrackFilterUtils.h"
+
+#include "xAODTracking/TrackParticleContainer.h"
+
+#include "TLorentzVector.h"
+
+void TrackFilterAlg(TLorentzVector tau,
+                    std::vector<TLorentzVector>* inputtracks20,
+                    std::vector<int>* inputtracks20charge,
+                    std::vector<TLorentzVector>* inputtracks40,
+                    std::vector<int>* inputtracks40charge,
+                    std::vector<TLorentzVector>* outputtracksgood,
+                    std::vector<int>* outputtracksgoodcharge,
+                    std::vector<TLorentzVector>* outputtracksbad,
+                    std::vector<int>* outputtracksbadcharge,
+                    int& nProng,
+                    int& flag);
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+
+TauTrackFilter::TauTrackFilter(const std::string &type,
+    const std::string &name,
+    const IInterface *parent) :
+TauToolBase(type, name, parent) {
+    declareInterface<TauToolBase > (this);
+
+    declareProperty("TrackContainerName", m_trackContainerName = "InDetTrackParticles");
+}
+
+//-----------------------------------------------------------------------------
+// Destructor
+//-----------------------------------------------------------------------------
+
+TauTrackFilter::~TauTrackFilter() {
+}
+
+
+//-----------------------------------------------------------------------------
+// Initializer
+//-----------------------------------------------------------------------------
+
+StatusCode TauTrackFilter::initialize() {
+    ATH_MSG_VERBOSE("TauTrackFilter Initialising");
+
+    return StatusCode::SUCCESS;
+}
+
+
+//-----------------------------------------------------------------------------
+// Finalizer
+//-----------------------------------------------------------------------------
+
+StatusCode TauTrackFilter::finalize() {
+    ATH_MSG_VERBOSE("TauTrackFilter Finalizing");
+
+    return StatusCode::SUCCESS;
+}
+
+
+//-----------------------------------------------------------------------------
+// Execution
+//-----------------------------------------------------------------------------
+StatusCode TauTrackFilter::execute(TauCandidateData *data) {
+    ATH_MSG_VERBOSE("TauTrackFilter Executing");
+
+    xAOD::TauJet *pTau = data->xAODTau;
+
+    StatusCode sc;
+
+    const xAOD::TrackParticleContainer *trackContainer;
+
+    //TODO: trigger uses getObject
+    sc = evtStore()->retrieve(trackContainer, m_trackContainerName);
+    if (sc.isFailure() || !trackContainer) {
+        ATH_MSG_DEBUG(" No track container found in TDS !!");
+        return StatusCode::SUCCESS;
+    }
+
+    TLorentzVector tau;
+    tau.SetPtEtaPhiE(pTau->pt(),
+                     pTau->eta(),
+                     pTau->phi(),
+                     pTau->e());
+
+    std::vector<TLorentzVector>* inputtracks20 = new std::vector<TLorentzVector>;
+    std::vector<TLorentzVector>* inputtracks40 = new std::vector<TLorentzVector>;
+    std::vector<int>* inputtracks20charge = new std::vector<int>;
+    std::vector<int>* inputtracks40charge = new std::vector<int>;
+    std::vector<TLorentzVector>* outputtracksgood = new std::vector<TLorentzVector>;
+    std::vector<TLorentzVector>* outputtracksbad = new std::vector<TLorentzVector>;
+    std::vector<int>* outputtracksgoodcharge = new std::vector<int>;
+    std::vector<int>* outputtracksbadcharge = new std::vector<int>;
+    int nProng = 0;
+    int flag = 0;
+
+    std::vector<unsigned int> inputtracks20index;
+    std::vector<unsigned int> inputtracks40index;
+
+    m_TrkPass.clear();
+
+    for(unsigned int j=0; j<pTau->nTracks(); j++ ) {
+        const xAOD::TrackParticle *TauJetTrack = pTau->track(j);
+        TLorentzVector inputTrack;
+        inputTrack.SetPtEtaPhiE(TauJetTrack->pt(),
+                                TauJetTrack->eta(),
+                                TauJetTrack->phi(),
+                                TauJetTrack->e()); // TODO Assume track has charged pion mass?
+        //TODO dR cut to put only correct tracks in inputtracks20 and inputtracks40
+        float dR = tau.DeltaR(inputTrack);
+        if (dR < 0.2) {
+            inputtracks20->push_back(inputTrack);
+            inputtracks20charge->push_back(TauJetTrack->charge());
+            inputtracks20index.push_back(j);
+        }
+        else if (dR < 0.4) {
+            inputtracks40->push_back(inputTrack);
+            inputtracks40charge->push_back(TauJetTrack->charge());
+            inputtracks40index.push_back(j);
+        }
+
+        // Add default status to track pass/fail member.
+        m_TrkPass.push_back(false);
+    }
+
+    // Run the main algorithm
+    TrackFilterAlg(tau,
+                   inputtracks20,
+                   inputtracks20charge,
+                   inputtracks40,
+                   inputtracks40charge,
+                   outputtracksgood,
+                   outputtracksgoodcharge,
+                   outputtracksbad,
+                   outputtracksbadcharge,
+                   nProng,
+                   flag);
+
+    // Store results
+    for (unsigned int j=0; j<outputtracksgood->size(); j++ ) {
+        for (unsigned int k=0; k<inputtracks20->size(); k++ ) {
+            if (outputtracksgood->at(j) == inputtracks20->at(k)) {
+                m_TrkPass.at(inputtracks20index.at(k)) = true;
+            }
+        }
+        for (unsigned int k=0; k<inputtracks40->size(); k++ ) {
+            if (outputtracksgood->at(j) == inputtracks40->at(k)) {
+                m_TrkPass.at(inputtracks40index.at(k)) = true;
+            }
+        }
+    }
+    m_nProng = nProng;
+    m_flag = flag;
+
+    // Cleanup
+    delete inputtracks20;
+    delete inputtracks20charge;
+    delete inputtracks40;
+    delete inputtracks40charge;
+    delete outputtracksgood;
+    delete outputtracksbad;
+    delete outputtracksgoodcharge;
+    delete outputtracksbadcharge;
+
+    // Set values in EDM
+    for (unsigned int numTrack=0; numTrack<m_TrkPass.size(); numTrack++) {
+      pTau->setTrackFilterPass(numTrack, m_TrkPass.at(numTrack));
+    }
+    pTau->setTrackFilterProngs(m_nProng);
+    pTau->setTrackFilterQuality(m_flag);
+
+    return StatusCode::SUCCESS;
+}
+
+
+//-----------------------------------------------------------------------------
+// Main algorithm
+//-----------------------------------------------------------------------------
+void TrackFilterAlg(TLorentzVector tau,
+                    std::vector<TLorentzVector>* inputtracks20,
+                    std::vector<int>* inputtracks20charge,
+                    std::vector<TLorentzVector>* inputtracks40,
+                    std::vector<int>* inputtracks40charge,
+                    std::vector<TLorentzVector>* outputtracksgood,
+                    std::vector<int>* outputtracksgoodcharge,
+                    std::vector<TLorentzVector>* outputtracksbad,
+                    std::vector<int>* outputtracksbadcharge,
+                    int& nProng,
+                    int& flag) {
+
+   std::vector<TauTrackFilterUtils::TrackInfo> unsorted,tracks,SScombination;
+   TauTrackFilterUtils::TrackInfo track;
+   unsigned int tracknum = inputtracks20->size();
+   unsigned int widetracknum = inputtracks40->size();
+   for(unsigned int i=0;i<tracknum;i++){
+      track.p4 = (*inputtracks20)[i];
+      track.charge = (*inputtracks20charge)[i];
+      unsorted.push_back(track);
+   }
+   while (unsorted.size() > 0){
+      float trackP = unsorted[0].p4.P();
+      int index = 0;
+      for(unsigned int i=1;i<unsorted.size();i++){
+         if(unsorted[i].p4.P() > trackP){
+            index = i;
+            trackP = unsorted[i].p4.P();
+         }
+      }
+      tracks.push_back(unsorted[index]);
+      tracks[tracks.size()-1].index = tracks.size()-1;
+      unsorted.erase(unsorted.begin()+index);            
+   }
+//Step 2: Test 3 Prong Hypothesis
+//Step 2a: Arrange combinations of tracks for testing
+   
+   bool test3prong = true, test2prong = true, test1prong = true;
+   for(unsigned int i=0;i<widetracknum;i++){
+   	outputtracksbad->push_back((*inputtracks40)[i]);
+   	outputtracksbadcharge->push_back((*inputtracks40charge)[i]);
+   }
+   if(tracknum > 4){ //Anything with more than 4 tracks is a fake.
+      flag = 0;
+      test3prong = false;
+      test2prong = false;
+      test1prong = false;
+   }
+   if(tracknum < 3) test3prong = false; //Don't test 3 prong if fewer than 3 tracks
+   if(tracknum < 2) test2prong = false; //Don't test 2 prong if fewer than 2 tracks
+   if(tracknum < 1){
+      flag = 0;
+      test1prong = false; //Don't test 1 prong if no tracks within dR < 0.2 of tau
+   }
+   if(test3prong){
+		//Test 3 Highest pT Tracks
+      bool isSS = false;
+      std::vector<TauTrackFilterUtils::TrackInfo> combination;
+      int charge = 0; TLorentzVector threetrack;
+      for(unsigned int i=0;i<3;i++){
+      	combination.push_back(tracks[i]); //Only Care about 3 Highest pT Tracks
+         charge+=tracks[i].charge;
+         threetrack+=tracks[i].p4;
+      }
+      if((tracknum == 3) && (abs(charge)!=1)) isSS = true; //Reject all same-sign combinations
+//Step 2b: Check kinematics of track combinations against shrinking cones and mass boundaries
+//         for(unsigned int i=0;i<combinations.size();i++){
+		bool goodcombo = false;
+		if(tracknum == 4){
+      	char eqn[] = "pol2";
+   		float a[] = {1.51673, -0.000150534, 2.64226e-06};
+			float mass99 = TauTrackFilterUtils::Compute1dim(tau.P(),a,3,eqn);
+			if((threetrack.M() < mass99)&&(TauTrackFilterUtils::pass3prong(combination,tau))){
+				goodcombo=true;
+				flag = 2;
+			}
+         else flag = 0;
+         test1prong=false;
+         test2prong=false;
+		}
+      else if(TauTrackFilterUtils::pass3prong(combination, tau)){
+         goodcombo=true;
+         flag = 1;
+      }
+      if(goodcombo){  //A Combination is found which passes 3prong hypothesis
+         for(unsigned int i=0;i<combination.size();i++){
+            if (isSS) SScombination.push_back(combination[i]);
+            outputtracksgood->push_back(combination[i].p4);
+            outputtracksgoodcharge->push_back(combination[i].charge);
+         }
+         if(isSS) flag = 0;
+         else flag = 1;
+         nProng = 3;
+         test1prong = false;
+         test2prong = false;
+         if(!test1prong){ //Fill Bad Track in the Case of 4 trk taus
+            if(tracknum == 4){
+            	outputtracksbad->push_back(tracks[3].p4);
+            	outputtracksbadcharge->push_back(tracks[3].charge);
+            }
+         }
+      }
+   }//End 3 Prong Test Conditional
+   if (test2prong){
+      std::vector<TauTrackFilterUtils::TrackInfo> pair;
+      for(unsigned int i=0;i<2;i++) pair.push_back(tracks[i]);
+      if(TauTrackFilterUtils::pass2prong(pair,tau)){
+      	nProng = 2;
+         for(unsigned int i=0;i<pair.size();i++){ //Fill Good Tracks
+            outputtracksgood->push_back(pair[i].p4);
+            outputtracksgoodcharge->push_back(pair[i].charge);
+         }
+         test1prong = false;
+         if(tracknum == 3){
+            flag = 2;
+         	outputtracksbad->push_back(tracks[2].p4); //Fill Bad Track in Case of 3 trk Taus
+         	outputtracksbadcharge->push_back(tracks[2].charge);
+         }
+         else flag = 1; //Good 2 Prong if only 2 trks
+      }
+   }//End 2 Prong Test Conditional
+//Step 4: Check tracks that don't pass 2 prong hypothesis against 1 prong hypothesis
+     if (test1prong){
+         char eqn[] = "([0]*exp([1]*x))*pol6(2)+[9]";
+         float a[10];
+         a[0] = 0.079586;
+         a[1] = -0.0289929;
+         a[2] = 7.06684;
+         a[3] = -0.158835;
+         a[4] = 0.000607181;
+         a[5] = 6.8445e-05;
+         a[6] = -6.79205e-07;
+         a[7] = 2.13158e-09;
+         a[8] = -5.11643e-13;
+         a[9] = 0.030376;
+         float ratio10 = TauTrackFilterUtils::Compute1dim(tau.P(),a,10,eqn);
+         bool goodcase = false;
+         if(tracknum == 1) goodcase = true;
+         if(tracknum == 2){
+            if(tracks[1].p4.Pt()/tracks[0].p4.Pt() < ratio10) goodcase = true; //Test 2trk taus most likely to actually be 1pngs
+         }
+         if((TauTrackFilterUtils::pass1prong(tracks[0].p4,tau))&&(goodcase)){ //A track is found which passes 1prong hypothesis
+            outputtracksgood->push_back(tracks[0].p4);
+            outputtracksgoodcharge->push_back(tracks[0].charge);
+            nProng = 1;
+            if (tracknum == 2){
+               flag = 2;
+            	outputtracksbad->push_back(tracks[1].p4); //Fill Bad Track in Case of 3 trk Taus
+            	outputtracksbadcharge->push_back(tracks[1].charge);
+            }
+            else flag = 1;
+         }
+         else flag = 0; //Fake Tau
+     }//End 1 Prong Test Conditional
+
+     return;
+}
+
diff --git a/Reconstruction/tauRec/src/TauTrackFilterUtils.cxx b/Reconstruction/tauRec/src/TauTrackFilterUtils.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..24a9d1ccac98e8bd4057fde6d066252133181a26
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauTrackFilterUtils.cxx
@@ -0,0 +1,266 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauTrackFilterUtils.cxx
+// package:     Reconstruction/tauRec
+// authors:     Robert Clarke, Blake Burghgrave
+// date:        2014-01-13
+//
+//
+//-----------------------------------------------------------------------------
+
+#include "TF1.h"
+#include "TLorentzVector.h"
+#include "tauRec/TauTrackFilterUtils.h"
+#include <vector>
+#include <iostream>
+#include <string>
+
+using namespace TauTrackFilterUtils;
+
+bool TauTrackFilterUtils::pass3prong(std::vector<TauTrackFilterUtils::TrackInfo> combination,TLorentzVector tau){
+
+   //Step 1: calculate angles
+   TauTrackFilterUtils::TrackPair lp, lm, sp, ls, ms, mp;
+   
+   lm.angle = fabs(combination[0].p4.Angle(combination[1].p4.Vect()));
+   lm.mass = (combination[0].p4+combination[1].p4).M();
+   lm.charge = combination[0].charge*combination[1].charge;
+   ls.angle = fabs(combination[0].p4.Angle(combination[2].p4.Vect()));
+   ls.mass = (combination[0].p4+combination[2].p4).M();
+   ls.charge = combination[0].charge*combination[2].charge;
+   ms.angle = fabs(combination[1].p4.Angle(combination[2].p4.Vect()));
+   ms.mass = (combination[1].p4+combination[2].p4).M();
+   ms.charge = combination[1].charge*combination[2].charge;
+
+	lp = lm;
+	if(ls.angle > lp.angle){
+		mp = lp;
+		lp = ls;
+	}
+	else mp = ls;
+	if(ms.angle > lp.angle){
+		sp = mp;
+		mp = lp;
+		lp = ms;
+	}   
+	else if(ms.angle > mp.angle){
+		sp = mp;
+		mp = ms;
+	}
+	else sp = ms;
+
+   //if (lp.angle < mp.angle) ATH_MSG_WARNING("Largest angle is smaller than medium angle!");
+   //if (lp.angle < sp.angle) ATH_MSG_WARNING("Largest angle is smaller than smallest angle!");
+   //if (mp.angle < sp.angle) ATH_MSG_WARNING("Medium angle is smaller than smallest angle!");
+   
+   //Step 3: calculate 99% angles
+   float lp99 = 0, sp99 = 0, lm99 = 0, ls99 = 0;
+   float p = tau.P(), eta = fabs(tau.Eta());
+   
+   float a[9][4];
+   int npar = 4, npol = 3;
+
+a[0][0] = 0.179041; a[1][0] = -0.0531058; a[2][0] = 0; 
+a[0][1] = -0.0146875; a[1][1] = 0.00414247; a[2][1] = -0.000612045; 
+a[0][2] = 0.0188939; a[1][2] = -0.00452375; a[2][2] = 0.00120015; 
+a[0][3] = 58.3066; a[1][3] = -48.2594; a[2][3] = 26.8864; 
+   lp99 = ComputeAngle(p,eta,a,npar,npol);
+a[0][0] = 0.0741985; a[1][0] = -0.0181941; a[2][0] = 0; 
+a[0][1] = -0.0149252; a[1][1] = 0.00512965; a[2][1] = -0.00125462; 
+a[0][2] = 0.00802004; a[1][2] = -0.00252272; a[2][2] = 0.000761022; 
+a[0][3] = 25.0145; a[1][3] = 0; a[2][3] = 0; 
+   sp99 = ComputeAngle(p,eta,a,npar,npol);
+a[0][0] = 0.102084; a[1][0] = -0.0256446; a[2][0] = 0; 
+a[0][1] = -0.014259; a[1][1] = 0.00465467; a[2][1] = -0.00122856; 
+a[0][2] = 0.010552; a[1][2] = -0.00176856; a[2][2] = 0.000446776; 
+a[0][3] = 36.0848; a[1][3] = -16.1489; a[2][3] = 10.2994; 
+   lm99 = ComputeAngle(p,eta,a,npar,npol);
+a[0][0] = 0.152783; a[1][0] = -0.0390978; a[2][0] = 0; 
+a[0][1] = -0.0139914; a[1][1] = 0.00352551; a[2][1] = -0.000624039; 
+a[0][2] = 0.0159925; a[1][2] = -0.00332104; a[2][2] = 0.00100568; 
+a[0][3] = 43.5804; a[1][3] = -18.681; a[2][3] = 6.29988; 
+   ls99 = ComputeAngle(p,eta,a,npar,npol);
+	   
+   //Step 4: compare angles and track masses, pass if all pass, fail otherwise
+   if((lp.angle > lp99)||(sp.angle > sp99)||(lm.angle > lm99)||(ls.angle > ls99)) return false; //One or more of the angles has failed - not a three prong tau
+   return true; //Track combination is a 3prong candidate!
+} //End pass3prong (efficiency studies)
+
+bool TauTrackFilterUtils::pass2prong(std::vector<TauTrackFilterUtils::TrackInfo> pair,TLorentzVector tau){
+   float angle = fabs(pair[0].p4.Angle(pair[1].p4.Vect()));
+   int  charge = pair[0].charge*pair[1].charge;
+
+   // Used to have more vars, but some were unused.
+   //float lt99 = 0, mt99 = 0, st99 = 0, ct99 = 0, lp99 = 0, mp99 = 0, sp99 = 0, los99 = 0, sos99 = 0, ss99 = 0, lm99 = 0, ls99 = 0, ms99 = 0;
+   float lp99 = 0, mp99 = 0, sp99 = 0, los99 = 0, sos99 = 0, ss99 = 0, lm99 = 0;
+   float p = tau.P(), eta = fabs(tau.Eta());
+   
+   float a[9][4];
+   int npar = 4, npol = 9;
+
+   a[0][0] = 0.0584232; a[1][0] = -0.0177642; a[2][0] = 0; a[3][0] = 0; a[4][0] = 0; a[5][0] = 0; a[6][0] = 0; a[7][0] = 0; a[8][0] = 0; 
+   a[0][1] = 0.0447435; a[1][1] = -0.659295; a[2][1] = 2.99202; a[3][1] = -6.10742; a[4][1] = 6.34017; a[5][1] = -3.49095; a[6][1] = 0.972228; a[7][1] = -0.107807; a[8][1] = 0; 
+   a[0][2] = -0.249078; a[1][2] = 3.75779; a[2][2] = -18.9563; a[3][2] = 45.4474; a[4][2] = -59.333; a[5][2] = 44.722; a[6][2] = -19.4586; a[7][2] = 4.54039; a[8][2] = -0.4399; 
+   a[0][3] = 124.481; a[1][3] = -1129.76; a[2][3] = 5198.92; a[3][3] = -10538.1; a[4][3] = 10741.4; a[5][3] = -5757; a[6][3] = 1548.86; a[7][3] = -164.644; a[8][3] = 0; 
+   //lt99 = ComputeAngle(p,eta,a,npar,npol);
+a[0][0] = 0.057286; a[1][0] = -0.0168061; a[2][0] = 0; a[3][0] = 0; a[4][0] = 0; a[5][0] = 0; a[6][0] = 0; a[7][0] = 0; a[8][0] = 0; 
+a[0][1] = 0.0640448; a[1][1] = -0.922493; a[2][1] = 4.10239; a[3][1] = -8.19704; a[4][1] = 8.35619; a[5][1] = -4.52961; a[6][1] = 1.24415; a[7][1] = -0.136244; a[8][1] = 0; 
+a[0][2] = -0.222389; a[1][2] = 3.34829; a[2][2] = -16.8256; a[3][2] = 40.1156; a[4][2] = -52.0129; a[5][2] = 38.9152; a[6][2] = -16.8076; a[7][2] = 3.89426; a[8][2] = -0.374831; 
+a[0][3] = 97.8443; a[1][3] = -804.025; a[2][3] = 3412.76; a[3][3] = -6058.05; a[4][3] = 5028.88; a[5][3] = -1940.87; a[6][3] = 281.19; a[7][3] = 0; a[8][3] = 0; 
+   //ct99 = ComputeAngle(p,eta,a,npar,npol);
+   npol = 3;
+a[0][0] = 0.0665222; a[1][0] = 0; a[2][0] = 0; 
+a[0][1] = -0.018755; a[1][1] = 0.00258183; a[2][1] = 0; 
+a[0][2] = 0.045607; a[1][2] = -0.0234824; a[2][2] = 0.00375319; 
+a[0][3] = 43.8011; a[1][3] = -10.0462; a[2][3] = 0; 
+   //mt99 = ComputeAngle(p,eta,a,npar,npol);
+a[0][0] = 0.156972; a[1][0] = -0.0333305; a[2][0] = 0; 
+a[0][1] = -0.0231364; a[1][1] = 0.0120482; a[2][1] = -0.00289192; 
+a[0][2] = 0.0490898; a[1][2] = -0.0273084; a[2][2] = 0.00547379; 
+a[0][3] = 33.1651; a[1][3] = 0; a[2][3] = 0; 
+   //st99 = ComputeAngle(p,eta,a,npar,npol);
+a[0][0] = 0.179041; a[1][0] = -0.0531058; a[2][0] = 0; 
+a[0][1] = -0.0146875; a[1][1] = 0.00414247; a[2][1] = -0.000612045; 
+a[0][2] = 0.0188939; a[1][2] = -0.00452375; a[2][2] = 0.00120015; 
+a[0][3] = 58.3066; a[1][3] = -48.2594; a[2][3] = 26.8864; 
+   lp99 = ComputeAngle(p,eta,a,npar,npol);
+a[0][0] = 0.142962; a[1][0] = -0.0397119; a[2][0] = 0; 
+a[0][1] = -0.014084; a[1][1] = 0.00437622; a[2][1] = -0.000992845; 
+a[0][2] = 0.0145659; a[1][2] = -0.00270987; a[2][2] = 0.00079432; 
+a[0][3] = 42.4831; a[1][3] = -25.893; a[2][3] = 13.6075; 
+   mp99 = ComputeAngle(p,eta,a,npar,npol);
+a[0][0] = 0.0741985; a[1][0] = -0.0181941; a[2][0] = 0; 
+a[0][1] = -0.0149252; a[1][1] = 0.00512965; a[2][1] = -0.00125462; 
+a[0][2] = 0.00802004; a[1][2] = -0.00252272; a[2][2] = 0.000761022; 
+a[0][3] = 25.0145; a[1][3] = 0; a[2][3] = 0; 
+   sp99 = ComputeAngle(p,eta,a,npar,npol);
+a[0][0] = 0.177021; a[1][0] = -0.0800858; a[2][0] = 0.017266; 
+a[0][1] = -0.0145132; a[1][1] = 0.00508756; a[2][1] = -0.00133994; 
+a[0][2] = 0.0174059; a[1][2] = -0.00407948; a[2][2] = 0.00130897; 
+a[0][3] = 59.5959; a[1][3] = -51.819; a[2][3] = 28.742; 
+   los99 = ComputeAngle(p,eta,a,npar,npol);
+a[0][0] = 0.126153; a[1][0] = -0.0504026; a[2][0] = 0.0100601; 
+a[0][1] = -0.01373; a[1][1] = 0.0040825; a[2][1] = -0.00103933; 
+a[0][2] = 0.0121626; a[1][2] = -0.00239224; a[2][2] = 0.000832398; 
+a[0][3] = 43.6455; a[1][3] = -34.4061; a[2][3] = 17.558; 
+   sos99 = ComputeAngle(p,eta,a,npar,npol);
+a[0][0] = 0.159394; a[1][0] = -0.0461081; a[2][0] = 0; 
+a[0][1] = -0.0148102; a[1][1] = 0.00429109; a[2][1] = -0.000670516; 
+a[0][2] = 0.0167114; a[1][2] = -0.00539364; a[2][2] = 0.00175181; 
+a[0][3] = 48.371; a[1][3] = -35.9336; a[2][3] = 19.3991; 
+   ss99 = ComputeAngle(p,eta,a,npar,npol);
+a[0][0] = 0.102084; a[1][0] = -0.0256446; a[2][0] = 0; 
+a[0][1] = -0.014259; a[1][1] = 0.00465467; a[2][1] = -0.00122856; 
+a[0][2] = 0.010552; a[1][2] = -0.00176856; a[2][2] = 0.000446776; 
+a[0][3] = 36.0848; a[1][3] = -16.1489; a[2][3] = 10.2994; 
+   lm99 = ComputeAngle(p,eta,a,npar,npol);
+a[0][0] = 0.152783; a[1][0] = -0.0390978; a[2][0] = 0; 
+a[0][1] = -0.0139914; a[1][1] = 0.00352551; a[2][1] = -0.000624039; 
+a[0][2] = 0.0159925; a[1][2] = -0.00332104; a[2][2] = 0.00100568; 
+a[0][3] = 43.5804; a[1][3] = -18.681; a[2][3] = 6.29988; 
+   //ls99 = ComputeAngle(p,eta,a,npar,npol);
+a[0][0] = 0.160615; a[1][0] = -0.0284831; a[2][0] = -0.00879631; 
+a[0][1] = -0.0140811; a[1][1] = 0.00344844; a[2][1] = -0.000421752; 
+a[0][2] = 0.0173056; a[1][2] = -0.00371573; a[2][2] = 0.00112158; 
+a[0][3] = 59.28; a[1][3] = -48.2821; a[2][3] = 26.3103; 
+   //ms99 = ComputeAngle(p,eta,a,npar,npol);
+   
+   if ((angle < lm99)&&((angle < lp99)||(angle < mp99)||(angle < sp99))){   
+   	if((charge == -1)&&((angle < los99)||(angle < sos99))) return true;
+   	else if((charge == 1)&&(angle < ss99)) return true;
+   	else return false;
+   }
+   else return false;
+} //End pass2prong
+
+bool TauTrackFilterUtils::pass1prong(TLorentzVector track,TLorentzVector tau){
+   //Step 1: Compute Angle Between Track and Tau
+   float angle = fabs(track.Angle(tau.Vect()));
+   //Step 2: Compute 99% angle
+   float p = tau.P(), eta = fabs(tau.Eta());
+   
+   int npar = 4, npol = 3;
+   float a[3][4];
+   
+   a[0][0] = 0.120777; a[1][0] = -0.0261681; a[2][0] = 0;
+   a[0][1] = -0.0307174; a[1][1] = 0.0170112; a[2][1] = -0.00381298;
+   a[0][2] = 0.0662689; a[1][2] = -0.0402811; a[2][2] = 0.00760013;
+   a[0][3] = 24.512; a[1][3] = 0; a[2][3] = 0;
+   float angle99 = ComputeAngle(p,eta,a,npar,npol);
+
+   //Step 3: compare angles and return decision
+   if(angle > angle99) return false; //Track angle exceeds kinematic boundary
+   else return true;
+} //End pass1prong
+
+float TauTrackFilterUtils::ComputePi0Cone(int recProngs,TLorentzVector tau){
+   float angle = -1;
+   float atrue = 0, arec = 0;
+   float p = tau.P(), eta = fabs(tau.Eta());   
+   int npar = 4, npol = 9;
+   float a[9][4];
+   switch(recProngs){
+      case 3:  //3 Prong Case
+      	npol = 7;
+         a[0][0] = 0.0457602; a[1][0] = 1.80062; a[2][0] = -6.82921; a[3][0] = 10.8605; a[4][0] = -8.52901; a[5][0] = 3.24106; a[6][0] = -0.473647;
+         a[0][1] = -0.017874; a[1][1] = -0.0502181; a[2][1] = 0.162668; a[3][1] = -0.172266; a[4][1] = 0.0783324; a[5][1] = -0.013098; a[6][1] = 0;
+         a[0][2] = 0.0266511; a[1][2] = -0.013319; a[2][2] = 0.00289217; a[3][2] = 0; a[4][2] = 0; a[5][2] = 0; a[6][2] = 0;
+         a[0][3] = 237.828; a[1][3] = -2836.67; a[2][3] = 11074.1; a[3][3] = -18578.5; a[4][3] = 15086.9; a[5][3] = -5828.12; a[6][3] = 856.684;
+         atrue = ComputeAngle(p,eta,a,npar,npol);
+         npar = 3;
+         npol = 5;
+         a[0][0] = 0.178252; a[1][0] = 0.057474; a[2][0] = -0.256742; a[3][0] = 0.156772; a[4][0] = -0.0283407;
+         a[0][1] = -0.00950538; a[1][1] = 0.00363589; a[2][1] = -0.00157984; a[3][1] = 0; a[4][1] = 0;
+         a[0][2] = 0.0227538; a[1][2] = -0.0642722; a[2][2] = 0.121818; a[3][2] = -0.0679845; a[4][2] = 0.0115837;
+         arec = ComputeAngle(p,eta,a,npar,npol,(char*)"[0]*exp([1]*x)+[2]");
+         break;
+      case 1: //1 Prong Case
+         npol = 6;
+         a[0][0] = 0.203158; a[1][0] = 0.269746; a[2][0] = -1.22961; a[3][0] = 1.41234; a[4][0] = -0.670384; a[5][0] = 0.114524;
+         a[0][1] = -0.0300622; a[1][1] = -0.0115786; a[2][1] = 0.07541; a[3][1] = -0.0782728; a[4][1] = 0.0334031; a[5][1] = -0.0052381;
+         a[0][2] = 0.0423083; a[1][2] = -0.0284378; a[2][2] = 0.0237394; a[3][2] = -0.0168315; a[4][2] = 0.0040657; a[5][2] = 0;
+         a[0][3] = 45.0612; a[1][3] = -458.353; a[2][3] = 1521.8; a[3][3] = -1895.88; a[4][3] = 1000.72; a[5][3] = -187.091;
+         atrue = ComputeAngle(p,eta,a,npar,npol);
+         a[0][0] = 0.168639; a[1][0] = -0.325194; a[2][0] = 1.4594; a[3][0] = -3.20592; a[4][0] = 3.50676; a[5][0] = -2.0571; a[6][0] = 0.621729; a[7][0] = -0.0758951; a[8][0] = 0;
+         a[0][1] = -0.0103477; a[1][1] = 0; a[2][1] = 0; a[3][1] = 0; a[4][1] = 0; a[5][1] = 0; a[6][1] = 0; a[7][1] = 0; a[8][1] = 0;
+         a[0][2] = 0.0325721; a[1][2] = -0.0496515; a[2][2] = 0.0773747; a[3][2] = -0.0396844; a[4][2] = 0.00615314; a[5][2] = 0; a[6][2] = 0; a[7][2] = 0; a[8][2] = 0;
+         arec = ComputeAngle(p,eta,a,npar,npol,(char*)"[0]*exp([1]*x)+[2]");
+         break;
+      default:
+         //ATH_MSG_WARNING("Incorrect number of prongs!");
+         return angle;
+   }
+   if (atrue > arec) angle = atrue;
+   else angle = arec;
+   return angle;
+} //End ComputePi0Cone
+
+float TauTrackFilterUtils::ComputeAngle(float p, float eta, float a[9][4], int npar, int npol, char eqn[]){
+   char name[10];
+   char poleqn[10];
+   
+   //TF1* etacoeff[npar]; //FIXME variable length array, use something like: = new TF1[npar];
+   std::vector<TF1> etacoeff;
+   TF1* pcone = new TF1("pcone",eqn); 
+   for(int i=0;i<npar;i++){
+      sprintf(name,"p%i",i);
+      sprintf(poleqn,"pol%i",npol);
+      etacoeff.push_back(TF1(name,poleqn));
+      for(int j=0;j<npol;j++) etacoeff.at(i).SetParameter(j,a[j][i]);
+		  pcone->SetParameter(i,etacoeff.at(i).Eval(eta));
+   }
+   float angle = pcone->Eval(p);
+   delete pcone;
+   return angle;
+}
+
+float TauTrackFilterUtils::Compute1dim(float p, float a[10], int npar, char eqn[]){
+   TF1* pcone = new TF1("pcone",eqn); 
+   for(int i=0;i<npar;i++) pcone->SetParameter(i,a[i]);
+   float angle = pcone->Eval(p);
+   delete pcone;
+   return angle;
+}
diff --git a/Reconstruction/tauRec/src/TauTrackFinder.cxx b/Reconstruction/tauRec/src/TauTrackFinder.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c022555997ee5391d38fea2f63dda16f2db69672
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauTrackFinder.cxx
@@ -0,0 +1,607 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "RecoToolInterfaces/IExtrapolateToCaloTool.h"
+#include "TrkToolInterfaces/ITrackSelectorTool.h"
+
+#include "xAODTau/TauJet.h"
+#include "xAODTau/TauJetContainer.h"
+
+#include "tauRec/TauTrackFinder.h"
+#include "tauRec/KineUtils.h"
+#include "tauRec/TrackSort.h"
+
+
+TauTrackFinder::TauTrackFinder(const std::string& type,
+		const std::string& name,
+		const IInterface* parent) :
+		TauToolBase(type, name, parent),
+		m_trackToCalo(""),
+		m_trackSelectorTool_tau(""),
+		m_trackToVertexTool("Reco::TrackToVertex"),
+		m_z0maxDelta(1000),
+		m_applyZ0cut(false),
+		m_storeInOtherTrks(true)
+{
+	declareInterface<TauToolBase > (this);
+	declareProperty("MaxJetDrTau", m_maxJetDr_tau = 0.2);
+	declareProperty("MaxJetDrWide", m_maxJetDr_wide = 0.4);
+	declareProperty("TrackSelectorToolTau", m_trackSelectorTool_tau);
+	declareProperty("TrackParticleContainer", m_inputTrackParticleContainerName = "InDetTrackParticles");
+	declareProperty("TTCExtrapolator", m_trackToCalo, "public track extrapolator tool to match track with caloseed");
+    declareProperty("TrackToVertexTool",m_trackToVertexTool);
+	declareProperty("maxDeltaZ0wrtLeadTrk", m_z0maxDelta);
+	declareProperty("removeTracksOutsideZ0wrtLeadTrk", m_applyZ0cut);
+    declareProperty("StoreRemovedCoreWideTracksInOtherTracks", m_storeInOtherTrks = true);
+}
+
+TauTrackFinder::~TauTrackFinder() {
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+StatusCode TauTrackFinder::initialize() {
+
+	// Get the TrackSelectorTool
+	if (!retrieveTool(m_trackSelectorTool_tau)) return StatusCode::FAILURE;
+
+	// Get the TJVA
+	if (!retrieveTool(m_trackToVertexTool)) return StatusCode::FAILURE;
+	if (!retrieveTool(m_trackToCalo)) return StatusCode::FAILURE;
+
+	return StatusCode::SUCCESS;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+StatusCode TauTrackFinder::finalize() {
+	return StatusCode::SUCCESS;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+StatusCode TauTrackFinder::eventInitialize(TauCandidateData*) {
+	return StatusCode::SUCCESS;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+StatusCode TauTrackFinder::eventFinalize(TauCandidateData*) {
+	return StatusCode::SUCCESS;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+StatusCode TauTrackFinder::execute(TauCandidateData * data) {
+
+	ATH_MSG_VERBOSE("TauTrackFinder Executing");
+
+	xAOD::TauJet *pTau = data->xAODTau;
+
+	StatusCode sc;
+	// get the track particle container from StoreGate
+	const xAOD::TrackParticleContainer* trackParticleCont = 0;
+
+	//for tau trigger
+	bool inTrigger = false;
+	if (data->hasObject("InTrigger?")) sc = data->getObject("InTrigger?", inTrigger);
+	if (sc.isSuccess() && inTrigger)   sc = data->getObject( "TrackContainer", trackParticleCont );
+
+	if( !inTrigger || !trackParticleCont || sc.isFailure() ) {
+		// try standard
+		if (!openContainer(trackParticleCont, m_inputTrackParticleContainerName)) {
+			if (!inTrigger) return StatusCode::FAILURE; // in offline we don't reconstruct tau candidates without having a track container
+			else return StatusCode::SUCCESS; // we don't want stop trigger if there is no track container
+		}
+	}
+
+	std::vector<const xAOD::TrackParticle*> tauTracks;
+	std::vector<const xAOD::TrackParticle*> wideTracks;
+	std::vector<const xAOD::TrackParticle*> otherTracks;
+
+	const xAOD::Vertex* pVertex = pTau->vertexLink()!=0 ? (*pTau->vertexLink()) : NULL;
+	// retrieve tracks wrt a vertex
+	// as a vertex is used: tau origin / PV / beamspot / 0,0,0 (in this order, depending on availability)
+	getTauTracksFromPV(pTau, trackParticleCont, pVertex, tauTracks, wideTracks, otherTracks);
+
+
+	this->resetDeltaZ0Cache();
+	// remove core and wide tracks outside a maximal delta z0 wrt lead core track
+	if (m_applyZ0cut) {
+		this->removeOffsideTracksWrtLeadTrk(tauTracks, wideTracks, otherTracks, pVertex, m_z0maxDelta);
+	}
+
+	//clear tracks first (needed for "rerun mode" if called on AODs again)
+	pTau->clearTrackLinks();
+	pTau->clearWideTrackLinks();
+	pTau->clearOtherTrackLinks();
+
+	bool alreadyUsed = false;
+	//check for tracks used in multiple taus
+	for (std::vector<const xAOD::TrackParticle*>::iterator track_it = tauTracks.begin(); track_it != tauTracks.end() ;)
+	{
+		alreadyUsed = false;
+
+		//loop over all up-to-now reconstructed tau candidates
+		xAOD::TauJetContainer::const_iterator tau_it = data->xAODTauContainer->begin();
+		xAOD::TauJetContainer::const_iterator tau_end = data->xAODTauContainer->end();
+		for( ; tau_it != tau_end; tau_it++ )
+		{
+			//loop over core tracks
+			for (unsigned int j = 0; j < (*tau_it)->nTracks(); ++j)
+			{
+				if ((*track_it) == (*tau_it)->track(j))
+				{
+					ATH_MSG_WARNING("Found a track that is identical with a track already associated to another tau. Will not add this track to more than one tau candidate");
+					alreadyUsed = true;
+				}
+			}
+		}
+
+		//if this track has already been used by another tau, don't associate it to this new one
+		if (alreadyUsed)    track_it = tauTracks.erase(track_it);
+		else ++track_it;
+	}
+
+
+	// associated track to tau candidate and calculate charge
+	float charge = 0;
+	for (unsigned int i = 0; i < tauTracks.size(); ++i) {
+		const xAOD::TrackParticle* trackParticle = tauTracks.at(i);
+
+		ATH_MSG_VERBOSE(name() 	<< " adding core track nr: " << i
+				<< " eta " << trackParticle->eta()
+				<< " phi " << trackParticle->phi()
+		);
+		charge += trackParticle->charge();
+		ElementLink<xAOD::TrackParticleContainer> linkToTrackParticle;
+		linkToTrackParticle.toContainedElement(*trackParticleCont, trackParticle);
+		pTau->addTrackLink(linkToTrackParticle);
+		ATH_MSG_VERBOSE(name() 	<< " added core track nr: " << i
+				<< " eta " << pTau->track(i)->eta()
+				<< " phi " << pTau->track(i)->phi()
+		);
+	}
+	// set the charge, which is defined by the core tau tracks only
+	pTau->setCharge(charge);
+
+	/// FIXME hide the logic to create element links inside xAODTau
+	/// was
+	// for (unsigned int i = 0; i < wideTracks.size(); ++i)
+	//     details->addSeedCalo_wideTrk(trackParticleCont, wideTracks.at(i));
+	for (unsigned int i = 0; i < wideTracks.size(); ++i) {
+		const xAOD::TrackParticle* trackParticle = wideTracks.at(i);
+
+		ATH_MSG_VERBOSE(name() 	<< " adding wide track nr: " << i
+				<< " eta " << trackParticle->eta()
+				<< " phi " << trackParticle->phi()
+		);
+		ElementLink<xAOD::TrackParticleContainer> linkToTrackParticle;
+		linkToTrackParticle.toContainedElement(*trackParticleCont, trackParticle);
+		pTau->addWideTrackLink(linkToTrackParticle);
+		ATH_MSG_VERBOSE(name() 	<< " added wide track nr: " << i
+				<< " eta " << pTau->wideTrack(i)->eta()
+				<< " phi " << pTau->wideTrack(i)->phi()
+		);
+	}
+
+	/// was
+	// for (unsigned int i = 0; i < otherTracks.size(); ++i)
+	//     details->addOtherTrk(trackParticleCont, otherTracks.at(i));
+	for (unsigned int i = 0; i < otherTracks.size(); ++i) {
+		const xAOD::TrackParticle* trackParticle = otherTracks.at(i);
+
+		ATH_MSG_VERBOSE(name() 	<< " adding other track nr: " << i
+				<< " eta " << trackParticle->eta()
+				<< " phi " << trackParticle->phi()
+		);
+		ElementLink<xAOD::TrackParticleContainer> linkToTrackParticle;
+		linkToTrackParticle.toContainedElement(*trackParticleCont, trackParticle);
+		pTau->addOtherTrackLink(linkToTrackParticle);
+		ATH_MSG_VERBOSE(name() 	<< " added other track nr: " << i
+				<< " eta " << pTau->otherTrack(i)->eta()
+				<< " phi " << pTau->otherTrack(i)->phi()
+		);
+	}
+
+
+	ATH_MSG_DEBUG("numTrack: " << "/" << pTau->nTracks());
+	ATH_MSG_DEBUG("charge: " << "/" << pTau->charge());
+
+	// extrapolate core tracks to calorimeter surface
+	// store information only in ExtraDetailsContainer
+	sc = extrapolateToCaloSurface(data);
+	if (sc.isFailure() && !sc.isRecoverable()) {
+		ATH_MSG_ERROR("couldn't extrapolate tracks to calo surface");
+		return StatusCode::FAILURE;
+	}
+
+	return StatusCode::SUCCESS;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+TauTrackFinder::TauTrackType TauTrackFinder::tauTrackType( const xAOD::TauJet* pTau,
+		const xAOD::TrackParticle* trackParticle,
+		const xAOD::Vertex* primaryVertex)
+{
+	//ATH_MSG_VERBOSE("tau axis:" << pTau->hlv().perp()<< " " << pTau->hlv().eta() << " " << pTau->hlv().phi()  << " " << pTau->hlv().e() );
+	double dR = Tau1P3PKineUtils::deltaR(pTau->eta(),pTau->phi(),trackParticle->eta(),trackParticle->phi());
+
+	if (dR > m_maxJetDr_wide) return NotTauTrack;
+
+	if (m_trackSelectorTool_tau->decision(*trackParticle, primaryVertex)) {
+		if (dR > m_maxJetDr_tau)
+			return TauTrackWide;
+		else
+			return TauTrackCore;
+	} else
+		return TauTrackOther;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+void TauTrackFinder::getTauTracksFromPV( const xAOD::TauJet* pTau,
+		const xAOD::TrackParticleContainer* trackParticleCont,
+		const xAOD::Vertex* primaryVertex,
+		std::vector<const xAOD::TrackParticle*> &tauTracks,
+		std::vector<const xAOD::TrackParticle*> &wideTracks,
+		std::vector<const xAOD::TrackParticle*> &otherTracks)
+{
+	for (xAOD::TrackParticleContainer::const_iterator tpcItr = trackParticleCont->begin(); tpcItr != trackParticleCont->end(); ++tpcItr) {
+		const xAOD::TrackParticle *trackParticle = *tpcItr;
+
+		TauTrackType type = tauTrackType(pTau, trackParticle, primaryVertex);
+
+		if (type == TauTrackCore)
+			tauTracks.push_back(trackParticle);
+		else if (type == TauTrackWide)
+			wideTracks.push_back(trackParticle);
+		else if (type == TauTrackOther)
+			otherTracks.push_back(trackParticle);
+
+	}
+	std::sort(tauTracks.begin(), tauTracks.end(), TrackSort());
+	std::sort(wideTracks.begin(), wideTracks.end(), TrackSort());
+	std::sort(otherTracks.begin(), otherTracks.end(), TrackSort());
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+StatusCode TauTrackFinder::extrapolateToCaloSurface(TauCandidateData *data) {
+
+	xAOD::TauJet *pTau = data->xAODTau;
+
+	if (pTau == NULL) {
+		ATH_MSG_ERROR("no candidate given");
+		return StatusCode::FAILURE;
+	}
+
+	const int numOfsampEM = 4;
+
+	for (unsigned int itr = 0; itr < 10 && itr < pTau->nTracks(); ++itr) {
+
+		const xAOD::TrackParticle *orgTrack = pTau->track(itr);
+
+		//---------------------------------------------------------------------
+		// Extrapolate to all layers
+		//---------------------------------------------------------------------
+		const DataVector< const Trk::TrackParameters >* pTrk = m_trackToCalo->getParametersInCalo(*orgTrack, Trk::pion, Trk::alongMomentum); //FIXME
+
+		//---------------------------------------------------------------------
+		// Calculate eta, phi impact point at calorimeter layers EM 0,1,2,3
+		//---------------------------------------------------------------------
+		double eta_extrapol[4];
+		double phi_extrapol[4];
+
+		for (int i = 0; i < numOfsampEM; ++i) {
+			eta_extrapol[i] = -11111.;
+			phi_extrapol[i] = -11111.;
+		}
+
+		// XXX commenting this out as long as it's not clear whether these variables will be stored in xAOD::TauJet
+		// if (pTrk && (*pTrk)[IExtrapolateToCaloTool::PreSampler]) {
+		// 	eta_extrapol[0] = (*pTrk)[IExtrapolateToCaloTool::PreSampler]->position().eta();
+		// 	phi_extrapol[0] = (*pTrk)[IExtrapolateToCaloTool::PreSampler]->position().phi();
+		// }
+
+		if (pTrk && (*pTrk)[IExtrapolateToCaloTool::Strips]) {
+			eta_extrapol[1] = (*pTrk)[IExtrapolateToCaloTool::Strips]->position().eta();
+			phi_extrapol[1] = (*pTrk)[IExtrapolateToCaloTool::Strips]->position().phi();
+
+		if (msgLvl(MSG::VERBOSE)) 
+		  { //only if desired msg level is requested
+		    ATH_MSG_VERBOSE(name() << " extrapolation in strip layer : "  
+				    << " track nr " << itr
+				    << " impact point eta " << eta_extrapol[1]
+				    << " impact point phi " << phi_extrapol[1]
+				    );
+		  }
+	
+		pTau->setTrackEtaStrip( itr,  (*pTrk)[IExtrapolateToCaloTool::Strips]->position().eta() );
+		pTau->setTrackPhiStrip( itr,  (*pTrk)[IExtrapolateToCaloTool::Strips]->position().phi() );
+		
+		if (msgLvl(MSG::VERBOSE)) 
+		  { //only if desired msg level is requested
+		    ATH_MSG_VERBOSE(name() << " extrapolation in strip layer stored in tau : "  
+				    << " track nr " << itr
+				    << " impact point eta " << pTau->trackEtaStrip(itr)
+				    << " impact point phi " << pTau->trackPhiStrip(itr)
+				    );
+		  }
+	
+		}
+
+		// XXX commenting this out as long as it's not clear whether these variables will be stored in xAOD::TauJet
+		// if (pTrk && (*pTrk)[IExtrapolateToCaloTool::Middle]) {
+		// 	eta_extrapol[2] = (*pTrk)[IExtrapolateToCaloTool::Middle]->position().eta();
+		// 	phi_extrapol[2] = (*pTrk)[IExtrapolateToCaloTool::Middle]->position().phi();
+		// }
+
+		// if (pTrk && (*pTrk)[IExtrapolateToCaloTool::Back]) {
+		// 	eta_extrapol[3] = (*pTrk)[IExtrapolateToCaloTool::Back]->position().eta();
+		// 	phi_extrapol[3] = (*pTrk)[IExtrapolateToCaloTool::Back]->position().phi();
+		// }
+
+
+		// for (int i = 0; i < numOfsampEM; ++i) {
+		//     pExtraDetails->etaLooseTrkCaloSamp()[itr][i] = eta_extrapol[i];
+		//     pExtraDetails->phiLooseTrkCaloSamp()[itr][i] = phi_extrapol[i];
+		// }
+
+		// // in the past this was filled by tau1P3PTrackMatchCalo
+		// for (int i = 0; i < numOfsampEM; ++i) {
+		//     pExtraDetails->etaTrkCaloSamp()[itr][i] = eta_extrapol[i];
+		//     pExtraDetails->phiTrkCaloSamp()[itr][i] = phi_extrapol[i];
+		// }
+
+		if (pTrk) delete pTrk;
+
+		// XXX commenting this out as long as it's not clear whether these variables will be stored in xAOD::TauJet
+		// if (msgLvl(MSG::VERBOSE)) { //only if desired msg level is requested
+		//   for (int i = 0; i < numOfsampEM; ++i) {
+		//     ATH_MSG_VERBOSE(name() << " extrapolation for loose trk in samp : " << i
+		//                     << " track nr " << itr
+		//                     << " impact point eta " << pExtraDetails->etaLooseTrkCaloSamp()[itr][i]
+		//                     << " impact point phi " << pExtraDetails->phiLooseTrkCaloSamp()[itr][i]
+		//                     );
+		//     ATH_MSG_VERBOSE(name() << " extrapolation in samp : " << i
+		//                     << " track nr " << itr
+		//                     << " impact point eta " << pExtraDetails->etaTrkCaloSamp()[itr][i]
+		//                     << " impact point phi " << pExtraDetails->phiTrkCaloSamp()[itr][i]
+		//                     );
+		//   }
+		// }
+
+	}
+
+	return StatusCode::SUCCESS;
+
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+void TauTrackFinder::removeOffsideTracksWrtLeadTrk(std::vector<const Rec::TrackParticle*> &tauTracks,
+                                       std::vector<const Rec::TrackParticle*> &wideTracks,
+                                       std::vector<const Rec::TrackParticle*> &otherTracks,
+                                       const Trk::RecVertex* tauOrigin,
+                                       double maxDeltaZ0)
+{
+    float MAX=1e5;
+    this->resetDeltaZ0Cache();
+
+    // need at least one core track to have a leading trk to compare with
+    if (tauTracks.size()<1) return;
+
+    //check if position is available for origin
+    /** FIXME: This causes compilation error after eigen migration
+    if (tauOrigin)
+        if (!tauOrigin->position())
+            tauOrigin = 0;
+    */
+
+    // get lead trk parameters
+    const Rec::TrackParticle *leadTrack = tauTracks.at(0);
+    float z0_leadTrk = getZ0(leadTrack, tauOrigin);
+
+    if (z0_leadTrk > MAX-1) return; // bad lead trk -> do nothing
+
+    ATH_MSG_VERBOSE("before z0 cut: #coreTracks=" << tauTracks.size() << ", #wideTracks=" << wideTracks.size() << ", #otherTracks=" << otherTracks.size());
+
+    std::vector<const Rec::TrackParticle*>::iterator itr;
+
+    // check core tracks
+    // skip leading track, because it is the reference
+    itr = tauTracks.begin()+1;
+    while (itr!=tauTracks.end()) {
+        float z0 = getZ0(*itr, tauOrigin);
+        float deltaZ0=z0 - z0_leadTrk;
+
+        ATH_MSG_VERBOSE("core Trks: deltaZ0= " << deltaZ0);
+        m_vDeltaZ0coreTrks.push_back(deltaZ0);
+
+        if ( fabs(deltaZ0) < maxDeltaZ0 ) {++itr;}
+        else {
+            if (m_storeInOtherTrks) otherTracks.push_back(*itr);
+            itr = tauTracks.erase(itr); //remove from core track collection
+        }
+    }
+
+    // check wide tracks
+    itr = wideTracks.begin();
+    while (itr!=wideTracks.end()) {
+        float z0 = getZ0(*itr, tauOrigin);
+        float deltaZ0=z0 - z0_leadTrk;
+
+        ATH_MSG_VERBOSE("wide Trks: deltaZ0= " << deltaZ0);
+        m_vDeltaZ0wideTrks.push_back(deltaZ0);
+
+        if ( fabs(deltaZ0) < maxDeltaZ0 ) { ++itr; }
+        else {
+            if (m_storeInOtherTrks) otherTracks.push_back(*itr);
+            itr = wideTracks.erase(itr); //remove from wide track collection
+        }
+    }
+
+    ATH_MSG_VERBOSE("after z0 cut: #coreTracks=" << tauTracks.size() << ", #wideTracks=" << wideTracks.size() << ", #otherTracks=" << otherTracks.size());
+
+    // sort again
+    std::sort(tauTracks.begin(), tauTracks.end(), TrackSort());
+    std::sort(wideTracks.begin(), wideTracks.end(), TrackSort());
+    std::sort(otherTracks.begin(), otherTracks.end(), TrackSort());
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+void TauTrackFinder::removeOffsideTracksWrtLeadTrk(std::vector<const xAOD::TrackParticle*> &tauTracks,
+						   std::vector<const xAOD::TrackParticle*> &wideTracks,
+						   std::vector<const xAOD::TrackParticle*> &otherTracks,
+						   const xAOD::Vertex* tauOrigin,
+						   double maxDeltaZ0)
+{
+    float MAX=1e5;
+    this->resetDeltaZ0Cache();
+
+    // need at least one core track to have a leading trk to compare with
+    if (tauTracks.size()<1) return;
+
+    //check if position is available for origin
+    /** FIXME: This causes compilation error after eigen migration
+    if (tauOrigin)
+        if (!tauOrigin->position())
+            tauOrigin = 0;
+    */
+
+    // get lead trk parameters
+    const xAOD::TrackParticle *leadTrack = tauTracks.at(0);
+    float z0_leadTrk = getZ0(leadTrack, tauOrigin);
+
+    if (z0_leadTrk > MAX-1) return; // bad lead trk -> do nothing
+
+    ATH_MSG_VERBOSE("before z0 cut: #coreTracks=" << tauTracks.size() << ", #wideTracks=" << wideTracks.size() << ", #otherTracks=" << otherTracks.size());
+
+    std::vector<const xAOD::TrackParticle*>::iterator itr;
+
+    // check core tracks
+    // skip leading track, because it is the reference
+    itr = tauTracks.begin()+1;
+    while (itr!=tauTracks.end()) {
+        float z0 = getZ0(*itr, tauOrigin);
+        float deltaZ0=z0 - z0_leadTrk;
+
+        ATH_MSG_VERBOSE("core Trks: deltaZ0= " << deltaZ0);
+        m_vDeltaZ0coreTrks.push_back(deltaZ0);
+
+        if ( fabs(deltaZ0) < maxDeltaZ0 ) {++itr;}
+        else {
+            if (m_storeInOtherTrks) otherTracks.push_back(*itr);
+            itr = tauTracks.erase(itr); //remove from core track collection
+        }
+    }
+
+    // check wide tracks
+    itr = wideTracks.begin();
+    while (itr!=wideTracks.end()) {
+        float z0 = getZ0(*itr, tauOrigin);
+        float deltaZ0=z0 - z0_leadTrk;
+
+        ATH_MSG_VERBOSE("wide Trks: deltaZ0= " << deltaZ0);
+        m_vDeltaZ0wideTrks.push_back(deltaZ0);
+
+        if ( fabs(deltaZ0) < maxDeltaZ0 ) { ++itr; }
+        else {
+            if (m_storeInOtherTrks) otherTracks.push_back(*itr);
+            itr = wideTracks.erase(itr); //remove from wide track collection
+        }
+    }
+
+    ATH_MSG_VERBOSE("after z0 cut: #coreTracks=" << tauTracks.size() << ", #wideTracks=" << wideTracks.size() << ", #otherTracks=" << otherTracks.size());
+
+    // sort again
+    std::sort(tauTracks.begin(), tauTracks.end(), TrackSort());
+    std::sort(wideTracks.begin(), wideTracks.end(), TrackSort());
+    std::sort(otherTracks.begin(), otherTracks.end(), TrackSort());
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+float TauTrackFinder::getZ0(const Rec::TrackParticle* track, const Trk::RecVertex* vertex)
+{
+    float MAX=1e5;
+
+    if (!track) return MAX;
+    if (!track->measuredPerigee()->covariance()) {
+         ATH_MSG_WARNING("Bad track; can't find perigee at vertex.");
+         return MAX;
+    }
+
+    const Trk::Perigee* perigee = 0;
+    if (vertex) perigee = m_trackToVertexTool->perigeeAtVertex(*track, vertex->position());
+    else        perigee = m_trackToVertexTool->perigeeAtVertex(*track); //will use beamspot or 0,0,0 instead
+
+    if (!perigee) {
+        ATH_MSG_WARNING("Bad track; can't find perigee at vertex.");
+        return MAX;
+    }
+
+    float z0 = perigee->parameters()[Trk::z0];
+
+    delete perigee; //cleanup necessary to prevent mem leak
+
+    return z0;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+float TauTrackFinder::getZ0(const xAOD::TrackParticle* track, const xAOD::Vertex* vertex)
+{
+    float MAX=1e5;
+
+    if (!track) return MAX;
+
+    const Trk::Perigee* perigee = 0;
+    if (vertex) perigee = m_trackToVertexTool->perigeeAtVertex(*track, vertex->position());
+    else        perigee = m_trackToVertexTool->perigeeAtVertex(*track); //will use beamspot or 0,0,0 instead
+
+    if (!perigee) {
+        ATH_MSG_WARNING("Bad track; can't find perigee at vertex.");
+        return MAX;
+    }
+
+    float z0 = perigee->parameters()[Trk::z0];
+
+    delete perigee; //cleanup necessary to prevent mem leak
+
+    return z0;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+void TauTrackFinder::getDeltaZ0Values(std::vector<float>& vDeltaZ0coreTrks, std::vector<float>& vDeltaZ0wideTrks)
+{
+  vDeltaZ0coreTrks.clear();
+  vDeltaZ0coreTrks = m_vDeltaZ0coreTrks;
+
+  vDeltaZ0wideTrks.clear();
+  vDeltaZ0wideTrks = m_vDeltaZ0wideTrks;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+void TauTrackFinder::resetDeltaZ0Cache()
+{
+    m_vDeltaZ0coreTrks.clear();
+    m_vDeltaZ0wideTrks.clear();
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// Helpers
+template <class T>
+bool TauTrackFinder::openContainer(T* &container, std::string containerName, bool printFATAL) {
+    StatusCode sc = evtStore()->retrieve(container, containerName);
+    if (sc.isFailure() || !container) {
+      if (printFATAL) ATH_MSG_FATAL("Container (" << containerName << ") not found in StoreGate");
+      return 0;
+    }
+    return container;
+}
+
+template <class T>
+bool TauTrackFinder::retrieveTool(T & tool) {
+    if (tool.retrieve().isFailure()) {
+        ATH_MSG_FATAL("Failed to retrieve tool " << tool);
+        return false;
+    } else {
+        ATH_MSG_VERBOSE("Retrieved tool " << tool);
+    }
+    return true;
+}
diff --git a/Reconstruction/tauRec/src/TauTrackSlimmer.cxx b/Reconstruction/tauRec/src/TauTrackSlimmer.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5ae7b16855724ac3eb8e7a9e86f32af8c8010183
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauTrackSlimmer.cxx
@@ -0,0 +1,177 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauTrackSlimmer.cxx
+// package:     Reconstruction/tauRec
+// authors:     Anna Kaczmarska, Lukasz Janyst
+// 
+// This class builds Slim Track objects for taus in the AOD 
+//             
+// date:        2008-01-17
+// 15/04/2008 - (AK) fixing compilation warning bug #35463 
+// 25/02/2009 - (AK) adding  declareProperty thinSvc
+// 22/01/2010 - (AK) adding protection against size 0 track collection 
+//-----------------------------------------------------------------------------
+
+#include "tauRec/TauTrackSlimmer.h"
+
+#include "tauEvent/TauJetContainer.h"
+#include "tauEvent/TauJet.h"
+#include "tauEvent/TauCommonDetails.h"
+
+#include "GaudiKernel/ListItem.h"
+#include <cmath>
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+TauTrackSlimmer::TauTrackSlimmer( const std::string &name,
+        ISvcLocator * pSvcLocator ) :
+    AthAlgorithm( name, pSvcLocator ),
+    m_thinningSvc( "ThinningSvc",  name ),
+    m_filterTaus(false),
+    m_maxNTrack(4),
+    m_maxCharge(2),
+    m_maxEmRadius(0.2),
+    m_maxIsoFrac(0.5)
+{
+    // Name of the thinningSvc
+    declareProperty( "thinSvc", m_thinningSvc, "Name of the thinningSvc" ); 
+    declareProperty( "TauContainer", m_tauContainerName );
+    declareProperty( "FilterTaus", m_filterTaus );
+    declareProperty( "maxNTrack", m_maxNTrack );
+    declareProperty( "maxCharge", m_maxCharge );
+    declareProperty( "maxEmRadius", m_maxEmRadius );
+    declareProperty( "maxIsoFrac", m_maxIsoFrac );
+}
+
+//-----------------------------------------------------------------------------
+// Destructor
+//-----------------------------------------------------------------------------
+TauTrackSlimmer::~TauTrackSlimmer()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Initialiezer
+//-----------------------------------------------------------------------------
+StatusCode TauTrackSlimmer::initialize()
+{
+
+    ATH_MSG_VERBOSE( "TauTrackSlimmer :: initialize()" );
+
+    /*
+       sc = service( "StoreGateSvc", evtStore() );
+       if( sc.isFailure() )
+       {
+       log << MSG :: ERROR;
+       log << "Unable to retrieve pointer to StoreGateSvc";
+       log );
+       return StatusCode :: FAILURE;
+       }
+     */
+    if ( m_thinningSvc.retrieve().isFailure() )
+    {
+        ATH_MSG_ERROR( "Unable to retrieve pointer to IThinningSvc" );
+        return StatusCode :: FAILURE;
+    }
+    return StatusCode :: SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Finalizer
+//-----------------------------------------------------------------------------
+StatusCode TauTrackSlimmer :: finalize()
+{
+    return StatusCode::SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Execution
+//-----------------------------------------------------------------------------
+StatusCode TauTrackSlimmer::execute()
+{
+    using namespace Analysis;
+
+    StatusCode sc;
+
+    //---------------------------------------------------------------------------
+    // Retrieve tau jet container
+    //---------------------------------------------------------------------------
+    const Analysis::TauJetContainer  *tauContainer;
+    sc = evtStore()->retrieve( tauContainer, m_tauContainerName );
+
+    if( sc.isFailure() || ! tauContainer )
+    {
+        ATH_MSG_DEBUG( "No tau container found!" );
+        return StatusCode :: SUCCESS;
+    }
+
+    //---------------------------------------------------------------------------
+    // Retrieve track container
+    //---------------------------------------------------------------------------
+    const TrackCollection* tracks = 0;
+    sc = evtStore()->retrieve( tracks, "Tracks" );
+
+    if( sc.isFailure() || !tracks ){
+        ATH_MSG_WARNING( "No track container found in TDS" );
+        return StatusCode :: SUCCESS;
+    }
+
+    if(tracks->size() == 0){
+        ATH_MSG_DEBUG( "empty track container found in TDS" );
+        return StatusCode :: SUCCESS;
+    }
+
+    //---------------------------------------------------------------------------
+    // Initialize vector of bools
+    //---------------------------------------------------------------------------
+    std::vector<bool> selected;
+    selected.resize( tracks->size(), false );
+
+    //---------------------------------------------------------------------------
+    // Initialize iterators
+    //---------------------------------------------------------------------------
+    Analysis::TauJetContainer :: const_iterator ftau = tauContainer->begin();
+    Analysis::TauJetContainer :: const_iterator etau = tauContainer->end();
+
+    //---------------------------------------------------------------------------
+    // Loop over taus
+    //---------------------------------------------------------------------------
+
+    for(; ftau != etau; ++ftau )
+    {
+
+        const Analysis::TauCommonDetails*  p_taudetails = (*ftau)->details<const Analysis::TauCommonDetails>();
+
+        if (m_filterTaus) {
+
+            if ((*ftau)->numTrack() > m_maxNTrack) continue;
+            if (std::abs((*ftau)->charge()) > m_maxCharge) continue;
+            if ( p_taudetails) {
+                if (p_taudetails->seedCalo_EMRadius() > m_maxEmRadius) continue;
+                if (p_taudetails->seedCalo_isolFrac() > m_maxIsoFrac) continue;
+            }
+
+        }
+
+        for( unsigned itr = 0; itr < (*ftau)->numTrack(); ++itr )
+            selected[(*ftau)->track(itr)->trackElementLink()->index()] = true;
+    }
+
+
+
+    //---------------------------------------------------------------------------
+    // Invoke the thinning service
+    //---------------------------------------------------------------------------
+    sc = m_thinningSvc->filter( *tracks, selected, IThinningSvc :: Operator :: Or );
+    if( sc.isFailure() )
+    {
+        ATH_MSG_ERROR( "Failed to thin Tracks associated to taus" );
+        return StatusCode :: SUCCESS;
+    }
+
+    return StatusCode :: SUCCESS;
+}
diff --git a/Reconstruction/tauRec/src/TauVertexFinder.cxx b/Reconstruction/tauRec/src/TauVertexFinder.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ae95c3f03674dd8e0ca631571bdcca3ed2fef006
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauVertexFinder.cxx
@@ -0,0 +1,216 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "tauRec/TauVertexFinder.h"
+
+#include "VxVertex/RecVertex.h"
+#include "VxVertex/VxCandidate.h"
+
+#include "xAODTracking/VertexContainer.h"
+#include "xAODTracking/Vertex.h"
+
+#include "xAODTau/TauJetContainer.h"
+#include "xAODTau/TauJetAuxContainer.h"
+#include "xAODTau/TauJet.h"
+
+TauVertexFinder::TauVertexFinder(const std::string& type,
+    const std::string& name,
+    const IInterface* parent) :
+TauToolBase(type, name, parent),
+m_printMissingContainerINFO(true),
+m_maxJVF(-100.),
+m_assocTracksName(""),
+m_trackVertexAssocName("")
+{
+    declareInterface<TauToolBase > (this);
+    declareProperty("UseTJVA", m_useTJVA=true);
+    declareProperty("PrimaryVertexContainer", m_inputPrimaryVertexContainerName = "PrimaryVertices");
+    declareProperty("AssociatedTracks",m_assocTracksName);
+    declareProperty("TrackVertexAssociation",m_trackVertexAssocName);
+}
+
+TauVertexFinder::~TauVertexFinder() {
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+StatusCode TauVertexFinder::initialize() {
+    if (m_useTJVA) ATH_MSG_INFO("using TJVA to determine tau vertex");
+    return StatusCode::SUCCESS;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+StatusCode TauVertexFinder::finalize() {
+    return StatusCode::SUCCESS;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+StatusCode TauVertexFinder::eventInitialize(TauCandidateData*) {
+    return StatusCode::SUCCESS;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+StatusCode TauVertexFinder::eventFinalize(TauCandidateData*) {
+    return StatusCode::SUCCESS;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+StatusCode TauVertexFinder::execute(TauCandidateData * data) {
+  
+  xAOD::TauJet *tauJet = data->xAODTau;
+  
+  // get the primary vertex container from StoreGate
+  //do it here because of tau trigger
+  const xAOD::VertexContainer* vxContainer = 0;
+  const xAOD::Vertex* primaryVertex = 0;
+  
+  StatusCode sc;
+  //for tau trigger
+  sc = data->getObject("VxPrimaryCandidate", vxContainer);
+  
+  if (sc.isFailure() || !vxContainer) { //not in trigger mode or no vxContainer was set by trigger
+        ATH_MSG_DEBUG("no VxPrimaryCandidateContainer for trigger -> try standard way");
+        if (!openContainer(vxContainer, m_inputPrimaryVertexContainerName)) {
+          if (m_printMissingContainerINFO) {
+            ATH_MSG_INFO(m_inputPrimaryVertexContainerName << " container not found --> skip TauVertexFinder (no further info)");
+            m_printMissingContainerINFO=false;
+          }
+          return StatusCode::SUCCESS;
+        }
+
+        // find default PrimaryVertex (needed if TJVA is switched off or fails)
+        // see: https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/VertexReselectionOnAOD
+        // code adapted from 
+        // https://svnweb.cern.ch/trac/atlasoff/browser/Tracking/TrkEvent/VxVertex/trunk/VxVertex/PrimaryVertexSelector.h
+        if (vxContainer->size()>0) {   
+          // simple loop through and get the primary vertex
+          xAOD::VertexContainer::const_iterator vxIter    = vxContainer->begin();
+          xAOD::VertexContainer::const_iterator vxIterEnd = vxContainer->end();
+          for ( size_t ivtx = 0; vxIter != vxIterEnd; ++vxIter, ++ivtx ){
+            // the first and only primary vertex candidate is picked
+            if ( (*vxIter)->vertexType() ==  xAOD::VxType::PriVtx){
+              primaryVertex = (*vxIter);
+              break;
+            }
+          }
+        }
+    }
+    else { // trigger mode
+      // find default PrimaryVertex (highest sum pt^2)
+      if (vxContainer->size()>0) primaryVertex = (*vxContainer)[0];
+    }
+    
+    ATH_MSG_VERBOSE("size of VxPrimaryContainer is: "  << vxContainer->size() );
+    
+    // associate vertex to tau
+    if (primaryVertex) tauJet->setVertex(vxContainer, primaryVertex);
+       
+    //stop here if TJVA is disabled or vertex container is empty
+    if (!m_useTJVA || vxContainer->size()==0) return StatusCode::SUCCESS;
+
+    // try to find new PV with TJVA
+    ATH_MSG_DEBUG("TJVA enabled -> try to find new PV for the tau candidate");
+
+    ElementLink<xAOD::VertexContainer> newPrimaryVertexLink = getPV_TJVA(tauJet, vxContainer );
+    if (newPrimaryVertexLink.isValid()) {
+      // set new primary vertex
+      // will overwrite default one which was set above
+      tauJet->setVertexLink(newPrimaryVertexLink);
+      // save highest JVF value
+      tauJet->setDetail(xAOD::TauJetParameters::TauJetVtxFraction,static_cast<float>(m_maxJVF));
+      ATH_MSG_DEBUG("TJVA vertex found and set");
+    }
+    else {
+      ATH_MSG_DEBUG("couldn't find new PV for TJVA");
+    }
+
+    return StatusCode::SUCCESS;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ElementLink<xAOD::VertexContainer> TauVertexFinder::getPV_TJVA(const xAOD::TauJet* pTau, const xAOD::VertexContainer* vertices)
+{
+	const xAOD::Jet* pJetSeed = (*pTau->jetLink());
+
+    // the implementation follows closely the example given in modifyJet(...) in https://svnweb.cern.ch/trac/atlasoff/browser/Reconstruction/Jet/JetMomentTools/trunk/Root/JetVertexFractionTool.cxx#15
+
+    // Get the tracks associated to the jet
+    std::vector<const xAOD::TrackParticle*> assocTracks;
+    if (! pJetSeed->getAssociatedObjects(m_assocTracksName, assocTracks)) {
+    	ATH_MSG_ERROR("Could not retrieve the AssociatedObjects named \""<< m_assocTracksName <<"\" from jet");
+    	return ElementLink<xAOD::VertexContainer>();
+    }
+
+    // Get the TVA object
+    const jet::TrackVertexAssociation* tva = NULL;
+    if (evtStore()->retrieve(tva,m_trackVertexAssocName).isFailure()) {
+    	ATH_MSG_ERROR("Could not retrieve the TrackVertexAssociation from evtStore: " << m_trackVertexAssocName);
+    	return ElementLink<xAOD::VertexContainer>();
+    }
+
+    // Calculate Jet Vertex Fraction
+    std::vector<float> jvf;
+    jvf.resize(vertices->size());
+    for (size_t iVertex = 0; iVertex < vertices->size(); ++iVertex) {
+      jvf.at(iVertex) = getJetVertexFraction(vertices->at(iVertex),assocTracks,tva);
+    }
+    
+    // Get the highest JVF vertex and store maxJVF for later use
+    // Note: the official JetMomentTools/JetVertexFractionTool doesn't provide any possibility to access the JVF value, but just the vertex.
+    m_maxJVF=-100.;
+    size_t maxIndex = 0;
+    for (size_t iVertex = 0; iVertex < jvf.size(); ++iVertex) {
+    	if (jvf.at(iVertex) > m_maxJVF) {
+          m_maxJVF = jvf.at(iVertex);
+          maxIndex = iVertex;
+        }
+    }
+
+    // Set the highest JVF vertex
+    ElementLink<xAOD::VertexContainer> vtxlink = ElementLink<xAOD::VertexContainer>(*vertices,vertices->at(maxIndex)->index());
+
+    return vtxlink;
+}
+
+// reimplementation of JetVertexFractionTool::getJetVertexFraction(const xAOD::Vertex* vertex, const std::vector<const xAOD::TrackParticle*>& tracks, const jet::TrackVertexAssociation* tva) const
+// avoid to call this specific tool only for this easy purpose
+// see https://svnweb.cern.ch/trac/atlasoff/browser/Reconstruction/Jet/JetMomentTools/trunk/Root/JetVertexFractionTool.cxx
+float TauVertexFinder::getJetVertexFraction(const xAOD::Vertex* vertex, const std::vector<const xAOD::TrackParticle*>& tracks, const jet::TrackVertexAssociation* tva) const
+{
+    float sumTrackPV = 0;
+    float sumTrackAll = 0;
+    for (size_t iTrack = 0; iTrack < tracks.size(); ++iTrack)
+    {
+        const xAOD::TrackParticle* track = tracks.at(iTrack);
+        const xAOD::Vertex* ptvtx = tva->associatedVertex(track);
+        if (ptvtx != nullptr) {  // C++11 feature
+        	if (ptvtx->index() == vertex->index()) sumTrackPV += track->pt();
+        }
+        sumTrackAll += track->pt();
+
+    }
+    return sumTrackAll!=0 ? sumTrackPV/sumTrackAll : 0;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// Helpers
+template <class T>
+bool TauVertexFinder::openContainer(T* &container, std::string containerName, bool printFATAL) {
+    StatusCode sc = evtStore()->retrieve(container, containerName);
+    if (sc.isFailure() || !container) {
+      if (printFATAL) ATH_MSG_FATAL("Container (" << containerName << ") not found in StoreGate");
+      return 0;
+    }
+    return container;
+}
+
+template <class T>
+bool TauVertexFinder::retrieveTool(T & tool) {
+    if (tool.retrieve().isFailure()) {
+        ATH_MSG_FATAL("Failed to retrieve tool " << tool);
+        return false;
+    } else {
+        ATH_MSG_VERBOSE("Retrieved tool " << tool);
+    }
+    return true;
+}
diff --git a/Reconstruction/tauRec/src/TauVertexVariables.cxx b/Reconstruction/tauRec/src/TauVertexVariables.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c0235b1b7b98e34c8f9612a686994d5409863a62
--- /dev/null
+++ b/Reconstruction/tauRec/src/TauVertexVariables.cxx
@@ -0,0 +1,327 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#include "Particle/TrackParticle.h"
+#include "Particle/TrackParticleContainer.h"
+#include "TrkParameters/TrackParameters.h"
+
+#include "xAODTracking/TrackParticleContainer.h"
+
+#include "TrkVertexFitterInterfaces/ITrackToVertexIPEstimator.h"
+#include "TrkVertexFitterInterfaces/IVertexFitter.h"
+#include "TrkVertexFitterInterfaces/IVertexSeedFinder.h"
+#include "TrkVertexFitters/AdaptiveVertexFitter.h"
+#include "TrkVxEdmCnv/IVxCandidateXAODVertex.h"
+#include "TrkLinks/LinkToXAODTrackParticle.h"
+
+#include "tauRec/TauCandidateData.h"
+#include "tauRec/TauVertexVariables.h"
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+
+TauVertexVariables::TauVertexVariables(const std::string &type,
+		const std::string &name,
+		const IInterface *parent) :
+		TauToolBase(type, name, parent),
+		m_primaryVertexKey("PrimaryVertices"),
+		m_useOldSeedFinderAPI(false),
+		m_fitTool("Trk::AdaptiveVertexFitter"),
+		m_SeedFinder("Trk::CrossDistancesSeedFinder"),
+		m_xaodConverter("Trk::VxCandidateXAODVertex"),
+		m_pSecVtxContainer(0),
+		m_pSecVtxAuxContainer(0){
+	declareInterface<TauToolBase > (this);
+	declareProperty("PrimaryVertexKey", m_primaryVertexKey);
+	declareProperty("TrackParticleContainer", m_inputTrackParticleContainerName = "InDetTrackParticles");
+	declareProperty("TrackToVertexIPEstimator", m_trackToVertexIPEstimator);
+	declareProperty("VertexFitter", m_fitTool);
+	declareProperty("SeedFinder", m_SeedFinder);
+	declareProperty("XAODConverter",m_xaodConverter);
+	declareProperty("useOldSeedFinderAPI",m_useOldSeedFinderAPI);
+}
+
+//-----------------------------------------------------------------------------
+// Destructor
+//-----------------------------------------------------------------------------
+
+TauVertexVariables::~TauVertexVariables() {
+}
+
+
+//-----------------------------------------------------------------------------
+// Initializer
+//-----------------------------------------------------------------------------
+
+StatusCode TauVertexVariables::initialize() {
+	CHECK( m_trackToVertexIPEstimator.retrieve() );
+	CHECK( m_fitTool.retrieve() );
+	CHECK( m_SeedFinder.retrieve() );
+	if (m_useOldSeedFinderAPI) CHECK( m_xaodConverter.retrieve() );
+
+	if (m_useOldSeedFinderAPI) {
+		ATH_MSG_INFO("using AOD-style API of the AdaptiveVertexFitter");
+	}
+	else {
+		ATH_MSG_INFO("using new xAOD-style API of the AdaptiveVertexFitter");
+	}
+
+	return StatusCode::SUCCESS;
+}
+
+StatusCode TauVertexVariables::eventInitialize(TauCandidateData * data) {
+
+	StatusCode sc;
+	bool inTrigger = false;
+	if (data->hasObject("InTrigger?"))
+		sc = data->getObject("InTrigger?", inTrigger);
+
+	// Only store the vertex containers if we are offline?
+	if(!sc.isSuccess() || !inTrigger)
+	{
+		// Secondary Vertex Container for tau decay vertex
+		m_pSecVtxContainer = new xAOD::VertexContainer();
+		m_pSecVtxAuxContainer = new xAOD::VertexAuxContainer();
+		m_pSecVtxContainer->setStore( m_pSecVtxAuxContainer );
+
+		CHECK( evtStore()->record( m_pSecVtxContainer, "TauSecondaryVertexContainer" ) );
+		CHECK( evtStore()->record( m_pSecVtxAuxContainer, "TauSecondaryVertexContainerAux." ) );
+	}
+
+	return StatusCode::SUCCESS;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Finalizer
+//-----------------------------------------------------------------------------
+StatusCode TauVertexVariables::finalize() {
+	return StatusCode::SUCCESS;
+}
+
+
+//-----------------------------------------------------------------------------
+// Execution
+//-----------------------------------------------------------------------------
+StatusCode TauVertexVariables::execute(TauCandidateData *data) {
+
+	ATH_MSG_DEBUG("executing TauVertexVariables");
+
+	xAOD::TauJet *pTau = data->xAODTau;
+
+	if (pTau == NULL) {
+		ATH_MSG_ERROR("no candidate given");
+		return StatusCode::FAILURE;
+	}
+
+	// impact parameter variables for standard tracks
+	if (pTau->nTracks() > 0) {
+		const Trk::ImpactParametersAndSigma * myIPandSigma(0);
+
+		if (pTau->vertexLink()) {
+			const xAOD::Vertex* vxcand = *(pTau->vertexLink()) ;
+			//check if vertex has a valid type (skip if vertex has type NoVtx)
+			if (vxcand->vertexType() > 0) {
+				myIPandSigma = m_trackToVertexIPEstimator->estimate(pTau->track(0), *pTau->vertexLink());
+			}
+		}
+
+		if (myIPandSigma != 0) {
+			pTau->setDetail(xAOD::TauJetParameters::ipSigLeadTrk, (float)( myIPandSigma->IPd0 / myIPandSigma->sigmad0 ));
+			pTau->setDetail(xAOD::TauJetParameters::ipZ0SinThetaSigLeadTrk, (float)( myIPandSigma->IPz0SinTheta / myIPandSigma->sigmaz0SinTheta ));
+		} else {
+			ATH_MSG_DEBUG("trackToVertexIPestimator failed for a standard track!");
+			pTau->setDetail(xAOD::TauJetParameters::ipSigLeadTrk, (float)(-999.));
+			pTau->setDetail(xAOD::TauJetParameters::ipZ0SinThetaSigLeadTrk, (float)(-999.));
+		}
+		delete myIPandSigma;
+	}
+
+	float ipSigLeadTrk;
+	float ipZ0SinThetaSigLeadTrk;
+
+	if (pTau->detail(xAOD::TauJetParameters::ipSigLeadTrk, ipSigLeadTrk))
+		ATH_MSG_VERBOSE("IP significance lead track " << ipSigLeadTrk);
+	if (pTau->detail(xAOD::TauJetParameters::ipZ0SinThetaSigLeadTrk, ipZ0SinThetaSigLeadTrk))
+		ATH_MSG_VERBOSE("IP Z0 significance lead track " << ipZ0SinThetaSigLeadTrk);
+
+	//try to find secondary vertex
+	//look for secondary vertex if more than 1 track
+	pTau->setDetail(xAOD::TauJetParameters::trFlightPathSig, (float)(-1111.));
+	if (pTau->nTracks() < 2) {
+		return StatusCode::SUCCESS;
+	}
+
+	// for tau trigger
+	bool inTrigger = false;
+	StatusCode sc;
+	if (data->hasObject("InTrigger?")) sc = data->getObject("InTrigger?", inTrigger);
+
+	const xAOD::VertexContainer* vxContainer = 0;
+	if (sc.isSuccess() && inTrigger)   sc = data->getObject("VxPrimaryCandidate", vxContainer);
+	// retrieve vertex container, exit if not found
+	else sc = evtStore()->retrieve(vxContainer, m_primaryVertexKey);
+
+	if (sc.isFailure() || !vxContainer) {
+		ATH_MSG_WARNING("No vertex container found. Skipping secondary vertex fitting.");
+		return StatusCode::SUCCESS;
+	}
+
+	const xAOD::TrackParticleContainer* trackParticleCont = 0;
+	if (inTrigger)   sc = data->getObject( "TrackContainer", trackParticleCont );
+	// retrieve track particle container, exit if not found
+	else sc = evtStore()->retrieve(trackParticleCont, m_inputTrackParticleContainerName);
+	if (sc.isFailure() || !trackParticleCont) {
+		ATH_MSG_WARNING("No track particle container found. Skipping secondary vertex fitting.");
+		return StatusCode::SUCCESS;
+	}
+
+	// get xAOD TrackParticles and Trk::Tracks
+	std::vector<const xAOD::TrackParticle*> xaodTracks;
+	std::vector<const Trk::Track*> origTracks;
+	for (unsigned i = 0; i < pTau->nTracks(); ++i) {
+		xaodTracks.push_back(pTau->track(i));
+		ATH_MSG_VERBOSE("xAOD::TrackParticle " <<i<<": "<< pTau->track(i)->pt() << " "  << pTau->track(i)->eta()  << " "  << pTau->track(i)->phi());
+		if (pTau->track(i)->track()) {
+			origTracks.push_back(pTau->track(i)->track());
+
+			// for debugging
+			/*
+            ATH_MSG_DEBUG("Trk::Track " <<i<<": "<< (*pTau->track(i)->track())->pt() << " "  << (*pTau->track(i)->track())->eta()  << " "  << (*pTau->track(i)->track())->phi());
+            const Trk::TrackParameters * tmpMeasPer = (*pTau->track(i)->track())->perigeeParameters();
+			const AmgSymMatrix(5)* cov = tmpMeasPer->covariance();
+			ATH_MSG_DEBUG("   TrackParameters: pT="<< tmpMeasPer->pT() << ", eta="  << tmpMeasPer->eta()  << ", x="  << tmpMeasPer->position().x() << ", y="<< tmpMeasPer->position().y() <<", z="<< tmpMeasPer->position().z());
+			ATH_MSG_DEBUG("   covariance ="<< *cov);
+			 */
+			// for debugging
+		}
+		else {
+			ATH_MSG_WARNING("no Trk::Track for xAOD::TrackParticle");
+		}
+	}
+
+	// get the starting point for the fit using Trk::Tracks
+	Trk::Vertex* seedPoint = new Trk::Vertex(m_SeedFinder->findSeed(origTracks));
+	ATH_MSG_VERBOSE("seedPoint x/y/perp=" << seedPoint->position().x() << " "<< seedPoint->position().y() << " "<< seedPoint->position().perp());
+	if (!seedPoint) {
+		ATH_MSG_WARNING("no seedPoint: Can not calculate secondary vertex!");
+		return StatusCode::SUCCESS;
+	}
+
+	// fitting the vertex itself
+	xAOD::Vertex* xAODvertex(0);
+	if (!m_useOldSeedFinderAPI) { // use new xAOD API of VertexFitter
+		xAODvertex = m_fitTool->fit(xaodTracks, *seedPoint);
+		if (xAODvertex && !inTrigger) {
+			ATH_MSG_VERBOSE("using new xAOD API: Secondary Vertex found and recorded! x="<<xAODvertex->position().x()<< ", y="<<xAODvertex->position().y()<<", perp="<<xAODvertex->position().perp());
+			m_pSecVtxContainer->push_back(xAODvertex);
+		}
+	}
+	else { // use standard AOD-style API of VertexFitter
+		Trk::VxCandidate* tmpVxCandidate = m_fitTool->fit(origTracks, *seedPoint);
+		if (tmpVxCandidate) {
+			ATH_MSG_VERBOSE("using old AOD API:Secondary Vertex found and recorded! x="<<tmpVxCandidate->recVertex().position().x()<< ", y="<<tmpVxCandidate->recVertex().position().y()<<", perp="<<tmpVxCandidate->recVertex().position().perp());
+
+			//******************************************************************
+			// convert VxCandidate to xAOD::Vertex
+			//******************************************************************
+
+			// assigning the input xAOD tracks to the fitted vertex
+			// this means: after that procedure the Trk::VxCandidate knows already the links to the xAOD tracks (which have to be identical with the Trk:Tracks used in the VertexFitter!)
+			// this is needed for the converting, otherwise the new xAODVertex don't have the track links
+			if(tmpVxCandidate->vxTrackAtVertex() != 0 && tmpVxCandidate->vxTrackAtVertex()->size() !=0) {
+				for(unsigned int i = 0; i <xaodTracks.size(); ++i) {
+					Trk::LinkToXAODTrackParticle * linkTT = new Trk::LinkToXAODTrackParticle;
+					linkTT->setElement(xaodTracks[i]);
+					linkTT->setStorableObject(*trackParticleCont);
+					// vxtrackatvertex takes ownership!
+					(*(tmpVxCandidate->vxTrackAtVertex()))[i]->setOrigTrack(linkTT);
+				}
+			}
+
+			xAODvertex = new xAOD::Vertex();
+			if (!inTrigger) m_pSecVtxContainer->push_back(xAODvertex);
+			// perform the final converting now
+			if( m_xaodConverter->createXAODVertex(*tmpVxCandidate,xAODvertex).isFailure() ) {
+				ATH_MSG_ERROR("Failed to create xAODVertex for VxCandidate. Don't set any secondary vertex for tau!");
+				return StatusCode::SUCCESS;
+			}
+			delete tmpVxCandidate;
+		}
+	}
+	delete seedPoint;
+
+	if (!xAODvertex) {
+		ATH_MSG_WARNING("no secondary vertex found!");
+		return StatusCode::SUCCESS;
+	}
+
+	// get the transverse flight path significance
+	float trFlightPS = trFlightPathSig(data, xAODvertex);
+	pTau->setDetail(xAOD::TauJetParameters::trFlightPathSig, (float)(trFlightPS));
+	ATH_MSG_VERBOSE("transverse flight path significance="<<trFlightPS);
+
+	// Note, we only attach the 2nd vertex if at offline, otherwise, break the trigger persistency
+	if  (!inTrigger) {
+		pTau->setSecondaryVertex(m_pSecVtxContainer, xAODvertex); 		// set the link to the vertex
+	}
+	else {
+		delete xAODvertex; // delete the vertex when in trigger mode, because we can not save it
+	}
+
+	return StatusCode::SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// calculate the transverse flight path significance
+//-------------------------------------------------------------------------
+double TauVertexVariables::trFlightPathSig(TauCandidateData *data, const xAOD::Vertex *secVertex) {
+
+	const xAOD::TauJet *pTau = data->xAODTau;
+
+	if (!secVertex) {
+		ATH_MSG_WARNING("No secondary vertex information for calculation of transverse flight path significance");
+		return -11111.;
+	}
+
+	const xAOD::Vertex* pVertex = 0;
+	if (pTau->vertexLink()) pVertex = *pTau->vertexLink();
+	if (!pVertex) {
+		ATH_MSG_WARNING("No primary vertex information for calculation of transverse flight path significance");
+		return -11111.;
+	}
+
+	double fpx = secVertex->position().x() - pVertex->position().x();
+	double fpy = secVertex->position().y() - pVertex->position().y();
+	double fpt = (secVertex->position() - pVertex->position()).perp();
+
+	if (fpt == 0) {
+		ATH_MSG_WARNING("delta pt of (secVtx - priVtx) is 0!");
+		return -11111.;
+	}
+
+	double sigma_fpt2 = (fpx * fpx * secVertex->covariancePosition()(Trk::x, Trk::x) +
+			fpx * fpy * secVertex->covariancePosition()(Trk::x, Trk::y) +
+			fpy * fpx * secVertex->covariancePosition()(Trk::y, Trk::x) +
+			fpy * fpy * secVertex->covariancePosition()(Trk::y, Trk::y)) / (fpt * fpt);
+
+	if (sigma_fpt2 <= 0) {
+		ATH_MSG_WARNING("sigma delta pt of (secVtx - priVtx) is 0!");
+		return -11111.;
+	}
+
+	double sigma_fpt = sqrt(sigma_fpt2);
+	double sign = 0;
+
+	if (fpx * pTau->p4().Px() + fpy * pTau->p4().Py() > 0.) sign = 1.;
+	else sign = -1.;
+
+	//ATH_MSG_INFO(sign << " " <<fpt << " " << sigma_fpt << " " << sign * fpt / sigma_fpt);
+	return sign * fpt / sigma_fpt;
+}
+
diff --git a/Reconstruction/tauRec/src/components/tauRec_entries.cxx b/Reconstruction/tauRec/src/components/tauRec_entries.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..e4171128090922acc63ac2e1d75e911af9b15b15
--- /dev/null
+++ b/Reconstruction/tauRec/src/components/tauRec_entries.cxx
@@ -0,0 +1,116 @@
+#include "tauRec/TauBuilder.h"
+#include "tauRec/JetSeedBuilder.h"
+#include "tauRec/LockTauContainers.h"
+#include "tauRec/TauAxisSetter.h"
+#include "tauRec/TauCalibrateEM.h"
+#include "tauRec/TauCalibrateLC.h"
+#include "tauRec/TauCellVariables.h"
+//#include "tauRec/TauOriginCorrectionTool.h"
+#include "tauRec/TauProcessor.h"
+#include "tauRec/TauTrackFinder.h"
+#include "tauRec/TauVertexFinder.h"
+#include "tauRec/TauElectronVetoVariables.h"
+//#include "tauRec/TauPi0EflowCreateROI.h"
+#include "tauRec/TauCommonCalcVars.h"
+//#include "tauRec/TauEflowAddCaloInfo.h"
+//#include "tauRec/TauEflowTrackMatchCells.h"
+//#include "tauRec/TauEflowVariables.h"
+#include "tauRec/TauShotFinder.h"
+#include "tauRec/TauPi0BonnClusterCreator.h"
+#include "tauRec/TauPi0BonnCreateROI.h"
+#include "tauRec/TauPi0BonnScoreCalculator.h"
+#include "tauRec/TauPi0BonnSelector.h"
+//#include "tauRec/TauPi0CrakowClusterCreator.h"
+//#include "tauRec/TauPi0CreatorChooser.h"
+#include "tauRec/TauSubstructureVariables.h"
+#include "tauRec/TauConversionFinder.h"
+#include "tauRec/PhotonConversionPID.h"
+#include "tauRec/PhotonConversionVertex.h"
+#include "tauRec/TauConversionTagger.h"
+#include "tauRec/TauVertexVariables.h"
+#include "tauRec/tauCalibrateWeightTool.h"  //for trigger
+#include "tauRec/TauTrackSlimmer.h"
+#include "tauRec/TauTrackFilter.h"
+#include "tauRec/TauGenericPi0Cone.h"
+#include "tauRec/TauTestDump.h"
+
+
+
+#include "GaudiKernel/DeclareFactoryEntries.h"
+
+DECLARE_ALGORITHM_FACTORY( TauBuilder   )
+DECLARE_ALGORITHM_FACTORY( TauProcessor )
+DECLARE_TOOL_FACTORY( JetSeedBuilder             )
+DECLARE_TOOL_FACTORY( LockTauContainers          )
+DECLARE_TOOL_FACTORY( TauAxisSetter         )
+DECLARE_TOOL_FACTORY( TauCalibrateEM             )
+DECLARE_TOOL_FACTORY( TauCalibrateLC             )
+DECLARE_TOOL_FACTORY( TauCellVariables           )
+//DECLARE_TOOL_FACTORY( TauOriginCorrectionTool    )
+DECLARE_TOOL_FACTORY( TauTrackFinder             )
+DECLARE_TOOL_FACTORY( TauVertexFinder            )
+DECLARE_TOOL_FACTORY( TauElectronVetoVariables             )
+//DECLARE_TOOL_FACTORY( TauPi0EflowCreateROI      )
+DECLARE_TOOL_FACTORY( TauCommonCalcVars          )
+//DECLARE_TOOL_FACTORY( TauEflowAddCaloInfo        )
+//DECLARE_TOOL_FACTORY( TauEflowTrackMatchCells    )
+//DECLARE_TOOL_FACTORY( TauEflowVariables          )
+DECLARE_TOOL_FACTORY( TauShotFinder              )
+DECLARE_TOOL_FACTORY( TauPi0BonnClusterCreator   )
+DECLARE_TOOL_FACTORY( TauPi0BonnCreateROI        )
+DECLARE_TOOL_FACTORY( TauPi0BonnScoreCalculator  )
+DECLARE_TOOL_FACTORY( TauPi0BonnSelector        )
+//DECLARE_TOOL_FACTORY( TauPi0CrakowClusterCreator )
+//DECLARE_TOOL_FACTORY( TauPi0CreatorChooser       )
+DECLARE_TOOL_FACTORY( TauSubstructureVariables     )
+DECLARE_TOOL_FACTORY( PhotonConversionPID )
+DECLARE_TOOL_FACTORY( PhotonConversionVertex )
+DECLARE_TOOL_FACTORY( TauConversionFinder )
+DECLARE_TOOL_FACTORY( TauConversionTagger )
+DECLARE_TOOL_FACTORY( TauVertexVariables )
+DECLARE_TOOL_FACTORY( tauCalibrateWeightTool )
+DECLARE_TOOL_FACTORY( TauTrackFilter )
+DECLARE_TOOL_FACTORY( TauGenericPi0Cone )
+DECLARE_TOOL_FACTORY( TauTestDump )
+DECLARE_ALGORITHM_FACTORY( TauTrackSlimmer )
+
+
+DECLARE_FACTORY_ENTRIES(tauRec) {
+    DECLARE_ALGORITHM(TauBuilder)
+    DECLARE_ALGORITHM(TauProcessor)
+    DECLARE_TOOL(JetSeedBuilder)
+    DECLARE_TOOL(LockTauContainers)
+    DECLARE_TOOL(TauAxisSetter)
+    DECLARE_TOOL(TauCalibrateEM)
+    DECLARE_TOOL(TauCalibrateLC)
+    DECLARE_TOOL(TauCellVariables)
+    //DECLARE_TOOL(TauOriginCorrectionTool)
+    DECLARE_TOOL(TauTrackFinder)
+    DECLARE_TOOL(TauVertexFinder)
+    DECLARE_TOOL( TauElectronVetoVariables )
+    //DECLARE_TOOL( TauPi0EflowCreateROI      )
+    DECLARE_TOOL( TauCommonCalcVars          )
+    //DECLARE_TOOL( TauEflowAddCaloInfo        )
+    //DECLARE_TOOL( TauEflowTrackMatchCells    )
+    //DECLARE_TOOL( TauEflowVariables          )
+    DECLARE_TOOL( TauShotFinder              )
+    DECLARE_TOOL( TauPi0BonnClusterCreator   )
+    DECLARE_TOOL( TauPi0BonnCreateROI        )
+    DECLARE_TOOL( TauPi0BonnScoreCalculator  )
+    DECLARE_TOOL( TauPi0BonnSelector         )
+    //DECLARE_TOOL( TauPi0CrakowClusterCreator )
+    //DECLARE_TOOL( TauPi0CreatorChooser       )
+    DECLARE_TOOL( TauSubstructureVariables     )
+    DECLARE_TOOL( PhotonConversionPID )
+    DECLARE_TOOL( PhotonConversionVertex )
+    DECLARE_TOOL( TauConversionFinder )
+    DECLARE_TOOL( TauConversionTagger )
+    DECLARE_TOOL( TauVertexVariables  )   
+    DECLARE_TOOL( tauCalibrateWeightTool )         
+      DECLARE_TOOL( TauTestDump )
+    DECLARE_ALGORITHM( TauTrackSlimmer )
+/*
+      DECLARE_ALGORITHM( TauTrackSlimmer )
+      DECLARE_ALGORITHM( TauAODDetailsCleaner )
+         */
+}
diff --git a/Reconstruction/tauRec/src/components/tauRec_load.cxx b/Reconstruction/tauRec/src/components/tauRec_load.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..84f141f229697d96091655254891da3c42d3baed
--- /dev/null
+++ b/Reconstruction/tauRec/src/components/tauRec_load.cxx
@@ -0,0 +1,6 @@
+#include "GaudiKernel/LoadFactoryEntries.h"
+
+LOAD_FACTORY_ENTRIES(tauRec)
+
+
+
diff --git a/Reconstruction/tauRec/src/tauCalibrateWeightTool.cxx b/Reconstruction/tauRec/src/tauCalibrateWeightTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c3dff174ba0052771a5f11f32f294a3cdf290629
--- /dev/null
+++ b/Reconstruction/tauRec/src/tauCalibrateWeightTool.cxx
@@ -0,0 +1,395 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/********************************************************************
+(depreciated!)
+
+NAME:     tauCalibrateWeightTool.cxx
+PACKAGE:  offline/Reconstruction/tauRec
+
+AUTHORS:  M.Heldmann
+CREATED:  March 22, 2005
+MODIFIED: July 15, 2005 ( Include pT dependent correction )
+23/10/2006 - (AK) fixing some compilation warnings (unused parameter)
+18/04/2007 - (AK) fixing some compilation warnings (unused parameter)
+29/06/2007 - (SL) fixing some compilation warnings
+13/12/2008 - (AK) change to extrapolation of TP instead of Track+code cleaning
+16/03/2010 - (AK) use the cell id instead of the pointer
+17/03/2010 - (AK) change to P4Helpers
+14/12/2011 - (FF) change to use tau axis  and numTrack (not seedCalo_)
+ ********************************************************************/
+#include "tauRec/TauCandidateData.h"
+#include "tauEvent/TauCommonDetails.h"
+#include "CaloEvent/CaloCluster.h"
+#include "CaloEvent/CaloCell.h"
+#include "AtlasDetDescr/AtlasDetectorID.h"
+#include "CaloIdentifier/CaloID.h"
+#include "CaloGeoHelpers/CaloSampling.h"
+
+#include "CLHEP/Units/SystemOfUnits.h"
+
+// INCLUDE GAUDI HEADER FILES:
+#include "GaudiKernel/Property.h"
+#include "AIDA/IHistogram1D.h"
+
+#include <algorithm> 
+#include <math.h>
+
+#include "FourMomUtils/P4Helpers.h"
+#include "FourMom/P4EEtaPhiM.h"
+
+#include "CaloInterface/IHadronicCalibrationTool.h"
+#include "TF1.h"
+
+#include "tauRec/tauCalibrateWeightTool.h"
+/********************************************************************/
+
+tauCalibrateWeightTool::tauCalibrateWeightTool(const std::string& type,
+        const std::string& name,
+        const IInterface* parent): 
+    TauToolBase( type, name, parent ),
+    m_calibrateType( tauCalibrateWeightTool::calCells ),
+    m_caloWeightTool(this),
+    m_cellWeightTool("CellWeightTool2004"),
+    m_applyCellWeightEM(true),
+    m_applyCellWeightHad(true),
+    m_applyPtEtaCorrFactors(true),
+    m_validCaloWeightTool(true),
+    m_doEtaInterpolation(false),
+    m_cellCone(0.4)
+{
+    declareInterface<TauToolBase>( this );
+
+    declareProperty( "calibrateType", m_calibrateType );
+    // Calibration Tool 
+    declareProperty("CellWeightTool",m_cellWeightTool);
+    declareProperty("ApplyCellWeightEM", m_applyCellWeightEM);
+    declareProperty("ApplyCellWeightHad", m_applyCellWeightHad);
+    declareProperty("ApplyPtEtaCorrFactors", m_applyPtEtaCorrFactors);
+    declareProperty("pTNumberOfBins", m_nptbins );
+    declareProperty("etaNumberOfBins", m_netabins );
+
+    declareProperty("pTPoints",m_ptpoints=std::vector<float>(10,0));
+    declareProperty("etaPoints",m_etapoints=std::vector<float>(10,0));
+    declareProperty("pTetaCorrectionsNtr1",m_ptetacorrectionsntr1=std::vector<float>(100,0));
+    declareProperty("pTetaCorrectionsNtr23",m_ptetacorrectionsntr23=std::vector<float>(100,0));
+
+    declareProperty("FudgeFactor",m_fudge=1);
+    declareProperty("DoEtaInterpolation", m_doEtaInterpolation);
+    declareProperty("CellCone",m_cellCone);
+    declareProperty("CaloWeightTool",m_caloWeightTool);
+}
+
+tauCalibrateWeightTool::~tauCalibrateWeightTool()
+{ 
+}
+
+StatusCode tauCalibrateWeightTool::initialize()
+{ 
+    StatusCode sc;
+    ATH_MSG_INFO( "Calibrating using fitted weights. " );
+
+    // retrieve all helpers from det store
+    sc = detStore()->retrieve(m_emid);
+    if (sc.isFailure()) {
+        ATH_MSG_ERROR( "Unable to retrieve LArEM_ID helper from DetectorStore" );
+        return sc;
+    }
+
+    sc = detStore()->retrieve(m_tileid);
+    if (sc.isFailure()) {
+        ATH_MSG_ERROR( "Unable to retrieve TileID helper from DetectorStore" );
+        return sc;
+    }
+
+    // Tool service
+    IToolSvc* myToolSvc;
+    sc = service("ToolSvc",myToolSvc);
+    if ( sc.isFailure() ) {				        
+        ATH_MSG_FATAL( "Tool Service not found" );
+        return StatusCode::FAILURE;         
+    }
+
+    // Fetch cell weight tool
+    sc = m_caloWeightTool.retrieve();
+    if ( sc.isFailure() ) {
+        ATH_MSG_ERROR( "Cannot find tool named <" << m_cellWeightTool << ">" );
+        m_validCaloWeightTool = false;         
+
+        return StatusCode::FAILURE;
+    }
+    else {
+        if( m_caloWeightTool != 0 ) {
+            ATH_MSG_INFO( "Will use the CaloWeightTool named: " << m_cellWeightTool );
+            m_validCaloWeightTool = true; 
+        }
+    }
+
+    if ( (int)m_ptpoints.size() != m_nptbins || (int)m_etapoints.size() != m_netabins ) {
+        ATH_MSG_FATAL( "wrong number of points for interpolation" );
+        return StatusCode::FAILURE;
+    }
+
+    for ( int i = 0; i < m_nptbins - 1; ++i ) {
+        if ( m_ptpoints[i] >= m_ptpoints[i+1]) {
+            ATH_MSG_FATAL( "Correction factor coordinates must be ordered in Pt and unique" );
+            return StatusCode::FAILURE;
+        }
+    }
+    m_ptpoints.push_back(0);     //makes the boundary conditions easyer to handle
+
+    for ( int i = 0; i < m_netabins - 1; ++i ) {
+        if ( m_etapoints[i] >= m_etapoints[i+1]) {
+            ATH_MSG_FATAL( "Correction factor coordinates must be ordered in eta and unique" );
+            return StatusCode::FAILURE;
+        }
+    }
+    m_etapoints.push_back(0);
+
+    if ( (int)m_ptetacorrectionsntr1.size() != (m_nptbins * m_netabins) ) {
+        ATH_MSG_FATAL( "Wrong number of correction factors for 1 Track" );
+        return StatusCode::FAILURE;
+    }
+
+    if ( (int)m_ptetacorrectionsntr23.size() != (m_nptbins * m_netabins) ) {
+        ATH_MSG_FATAL( "Wrong number of correction factors for 2 and 3 Tracks" );
+        return StatusCode::FAILURE;
+    }
+
+    return StatusCode::SUCCESS;
+}
+
+/********************************************************************/
+StatusCode tauCalibrateWeightTool::execute( TauCandidateData */*data*/ )
+{ 
+	/*
+	 * FF: March 2014
+	 * This Tool is not migrated yet to xAOD. Unclear if still needed. Only client was TauTrigger.
+	 * FF will investigate.
+	 *
+	 *
+    Analysis :: TauJet *tau = data->tau;
+    Analysis :: TauCommonDetails *details = dynamic_cast<Analysis :: TauCommonDetails *>(data->details);
+
+    // Detector identifiers
+    AtlasDetectorID AtlasID;
+
+    // Variables for sums
+    double sumEM = 0;
+    double sumE = 0;
+    double sumAccb3 = 0;
+    double sumHad = 0;
+    double sumTile1 = 0;
+
+    double sumScint = 0;
+    double sumGap   = 0;
+
+    double dR;
+
+    // loop over all cells of the tau (placed there by the tauSeedBuilder)
+    typedef NavigationToken<CaloCell,NavigationDefaults::DefaultWeight,CaloCellIDFcn> token_t;
+    token_t nt;
+
+    tau->fillToken( nt );
+
+    token_t::const_iterator nt_iter = nt.begin();
+    token_t::const_iterator nt_end = nt.end();
+
+    const CaloCell *cell;
+
+    double etaSeed = tau->eta(); //FF  details->seedCalo_eta();
+    double phiSeed = tau->phi(); //FF  details->seedCalo_phi();
+
+    P4EEtaPhiM P4Seed( 1., etaSeed, phiSeed, 0. );	
+
+    for ( ; nt_iter != nt_end; nt_iter++ ) {
+        cell = (*nt_iter);
+
+        // Cell ET and index for ET range
+        // This is made symmetric around zero so that noise (not yet included)
+        // does not produce a shift.
+        double cellET = cell->et();
+
+        CaloSampling::CaloSample calo = cell->caloDDE()->getSampling();
+
+        // Use cells that are in DR < m_cellCone of eta,phi of jet:
+        dR = P4Helpers::deltaR( P4Seed, cell->eta(), cell->phi() );
+
+        if ( dR < m_cellCone ) {
+            double calWeight = 1.;
+
+            // Check which kind of calib tools have been selected
+            // and Get calibration weight 
+
+            if (m_validCaloWeightTool) calWeight = m_caloWeightTool->wtCell( cell ); 
+
+            sumE += cell->e();
+
+            switch ( calo ) {
+                case CaloSampling::PreSamplerB:
+                case CaloSampling::PreSamplerE:
+                case CaloSampling::EMB1:
+                case CaloSampling::EME1:
+                case CaloSampling::EMB2:
+                case CaloSampling::EME2:
+                    sumEM += (m_applyCellWeightEM ? calWeight*cellET : cellET);
+                    break;
+                case CaloSampling::EMB3:
+                    sumAccb3 += cellET;
+
+                case CaloSampling::EME3:
+                    // Only include first two EM layers in EM sum; add third to HAD
+                    // Keep track of ACCB3 for cryostat correction below
+                    sumHad += (m_applyCellWeightHad ? calWeight*cellET : cellET);
+                    break;
+
+                case CaloSampling::TileBar0:
+                    sumTile1 += cellET;
+
+                case CaloSampling::TileBar1:
+                case CaloSampling::TileBar2:
+                    sumHad += (m_applyCellWeightHad ? calWeight*cellET : cellET);
+                    break;
+                case CaloSampling::TileExt0:
+                case CaloSampling::TileExt1:
+                case CaloSampling::TileExt2:
+                    sumHad += (m_applyCellWeightHad ? calWeight*cellET : cellET);
+                    break;
+                case CaloSampling::TileGap1:      
+                    // scintillator ?
+                    // Gap Scintillator is included in Gap
+                    // Hence do NOT add it separately
+                    // MH I don't know what's it like now .... but I guess its seperated
+                    sumScint += cellET;
+                case CaloSampling::TileGap2:
+                case CaloSampling::TileGap3:
+                    sumHad += (m_applyCellWeightHad ? calWeight*cellET : cellET);
+                    sumGap += cellET;
+                    break;
+                case CaloSampling::HEC0:
+                case CaloSampling::HEC1:
+                case CaloSampling::HEC2:
+                case CaloSampling::HEC3:
+                    sumHad += (m_applyCellWeightHad ? calWeight*cellET : cellET);
+                    break;
+                case CaloSampling::FCAL0:
+                case CaloSampling::FCAL1:
+                case CaloSampling::FCAL2:
+	        case CaloSampling::MINIFCAL0:
+	        case CaloSampling::MINIFCAL1:
+	        case CaloSampling::MINIFCAL2:
+	        case CaloSampling::MINIFCAL3:
+                case CaloSampling::Unknown:
+                    break;
+            }
+        }         // end dR cut
+        else
+        {
+            ATH_MSG_VERBOSE( "cell with energy " << cell->e() << " outside of cell cone" );
+        }
+
+    }         // end cell loop
+
+    // Cryostat correction uses geometric mean of last layer of EM and
+    // first layer of tile:
+
+    if(sumAccb3<0.) sumAccb3=0.;
+    if(sumTile1<0.) sumTile1=0.;
+
+    double wtCryo = 1.;    
+
+    if (m_validCaloWeightTool) wtCryo = m_caloWeightTool->wtCryo();
+    double sumCryo = (m_applyCellWeightHad ? wtCryo*sqrt(sumAccb3*sumTile1) : sqrt(sumAccb3*sumTile1));
+
+    // Weight fudge factor. The H1 weights are taken to be independent of
+    // eta. This factor is applied to the hadronic energy to produce a
+    // more uniform response.
+
+    details->setSeedCalo_etEMCalib(sumEM);
+    details->setSeedCalo_etHadCalib((sumHad+sumCryo));
+
+    double et = details->seedCalo_etEMCalib()+details->seedCalo_etHadCalib();
+    double eta = fabs( etaSeed );
+    double corr = 1;
+
+    if (m_applyPtEtaCorrFactors) {    
+
+        ATH_MSG_VERBOSE( "energy: " << details->seedCalo_etEMCalib() << " " <<details->seedCalo_etHadCalib() << " " << sumEM <<" "<<sumHad<<" "<<sumCryo );
+
+        int lowpt_idx = 0;
+        int loweta_idx = 0;
+
+        double lowpt_frac = 0;
+        double loweta_frac = 0;
+
+        while ( lowpt_idx < m_nptbins-1 && et > m_ptpoints[lowpt_idx+1] )
+            lowpt_idx++;
+
+        lowpt_frac = ( m_ptpoints[lowpt_idx+1] - et ) / ( m_ptpoints[lowpt_idx+1] - m_ptpoints[lowpt_idx] );   // will be >1 if et is out of bounds
+
+        if ( lowpt_frac > 1 )
+            lowpt_frac =  1;
+        if( lowpt_frac < 0 ) {   //should never happen, only if ptNumberOfBins is set wrong (which is checked now)
+            ATH_MSG_ERROR( "FIXME: lowpt_frac < 0 !!" );
+        }
+
+        while ( loweta_idx < m_netabins-1 && eta > m_etapoints[loweta_idx+1] )
+            loweta_idx++;
+
+        if(m_doEtaInterpolation)
+            loweta_frac = ( m_etapoints[loweta_idx+1] - eta ) / ( m_etapoints[loweta_idx+1] - m_etapoints[loweta_idx] );   // will be >1 if eta is out of bounds, 
+        else
+            loweta_frac = 1;    
+
+        if ( loweta_frac > 1)
+            loweta_frac = 1;
+        if( loweta_frac < 0 ) {    //should never happen, only if etaNumberOfBins is set wrong
+            ATH_MSG_ERROR( "FIXME: loweta_frac < 0 !!" );
+        }
+
+        double coeff_matrix[2][2] = { {0, 0}, {0, 0} };
+
+        //FF changed from seeddCalo_numTrack to numTrack
+        if ( tau->numTrack() <= 1 ) {
+            coeff_matrix[0][0] = m_ptetacorrectionsntr1[lowpt_idx*m_netabins+loweta_idx];
+            if( lowpt_idx < m_nptbins-1 )
+                coeff_matrix[1][0] = m_ptetacorrectionsntr1[(lowpt_idx+1)*m_netabins+loweta_idx];
+            if( loweta_idx < m_netabins-1 )
+                coeff_matrix[0][1] = m_ptetacorrectionsntr1[lowpt_idx*m_netabins+(loweta_idx+1)];
+            if( lowpt_idx < m_nptbins-1 && loweta_idx < m_netabins-1 )
+                coeff_matrix[1][1] = m_ptetacorrectionsntr1[(lowpt_idx+1)*m_netabins+(loweta_idx+1)];
+        } else {
+            coeff_matrix[0][0] = m_ptetacorrectionsntr23[lowpt_idx*m_netabins+loweta_idx];
+            if( lowpt_idx < m_nptbins-1 )
+                coeff_matrix[1][0] = m_ptetacorrectionsntr23[(lowpt_idx+1)*m_netabins+loweta_idx];
+            if( loweta_idx < m_netabins-1 )
+                coeff_matrix[0][1] = m_ptetacorrectionsntr23[lowpt_idx*m_netabins+(loweta_idx+1)];
+            if( lowpt_idx < m_nptbins-1 && loweta_idx < m_netabins-1 )
+                coeff_matrix[1][1] = m_ptetacorrectionsntr23[(lowpt_idx+1)*m_netabins+(loweta_idx+1)];
+        }
+
+        corr = ( coeff_matrix[0][0] * lowpt_frac * loweta_frac ) + ( coeff_matrix[1][0] * (1-lowpt_frac) * loweta_frac );
+        corr += ( coeff_matrix[0][1] * lowpt_frac * (1-loweta_frac) ) + ( coeff_matrix[1][1] * (1-lowpt_frac) * (1-loweta_frac) );
+
+    } // end if (m_applyPtEtaCorrFactors)
+
+    ATH_MSG_VERBOSE( "corrected energy: " << et << "*" << corr << "=" << et*corr );
+
+
+    //tau->setE( et*cosh( details->seedCalo_eta() )*corr*m_fudge );
+	*/
+
+    //return StatusCode::SUCCESS;
+	// print error so that everybody knows this tool isn't working in case it is called.
+	ATH_MSG_ERROR( "This Tool is not yet migrated to xAOD!" );
+	return StatusCode::SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Finalize
+//-----------------------------------------------------------------------------
+StatusCode tauCalibrateWeightTool :: finalize()
+{
+    return StatusCode :: SUCCESS;
+}
diff --git a/Reconstruction/tauRec/tauRec/CaloClusterVariables.h b/Reconstruction/tauRec/tauRec/CaloClusterVariables.h
new file mode 100644
index 0000000000000000000000000000000000000000..9b34c1b6d99c4daea16185379721b974fa8007c1
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/CaloClusterVariables.h
@@ -0,0 +1,81 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef CALOCLUSTERVARIABLES_H
+#define CALOCLUSTERVARIABLES_H
+
+#include <vector>
+#include "CaloUtils/CaloVertexedCluster.h"
+//#include "CaloEvent/CaloVertexedCluster.h"
+#include "CxxUtils/fpcompare.h"
+#include "xAODTau/TauJet.h"
+
+/** Provide calculations of cluster based variables using the clusters associated to the jet seed of the tau candidate. */
+class CaloClusterVariables {
+public:
+
+    static const double DEFAULT;
+
+    CaloClusterVariables();
+
+    ~CaloClusterVariables() {
+    }
+
+    bool update(const xAOD::TauJet* tau); //!< update the internal variables for the given tau
+
+    void setVertexCorrection(bool flag) {m_doVertexCorrection=flag;}
+
+    // ID Variables
+    unsigned int numConstituents() { return (unsigned int) m_numConstit; }
+
+    double totalMass()     { return m_totMass; }
+    double effectiveMass() { return m_effMass; }
+    
+    double effectiveNumConstituents()  { return m_effNumConstit; }
+    int effectiveNumConstituents_int() { return m_effNumConstit_int; }
+
+    double averageEffectiveRadius() { return m_aveEffRadius; }
+    double averageRadius()          { return m_aveRadius; }
+
+    // Energy Variables
+    double totalEnergy()     { return m_totEnergy; }
+    double effectiveEnergy() { return m_effEnergy; }
+
+    //cells
+    unsigned int numCells() { return m_numCells; }
+
+private:
+    int m_numConstit;
+    int m_effNumConstit_int;
+    double m_effNumConstit;
+    double m_aveRadius;
+    double m_aveEffRadius;
+    double m_totMass;
+    double m_effMass;
+    double m_totEnergy;
+    double m_effEnergy;
+    unsigned int m_numCells;
+
+    /** Calculate the geometrical center of the tau constituents */
+		CLHEP::HepLorentzVector calculateTauCentroid(int nConst, const std::vector<xAOD::CaloVertexedCluster>& constituents);
+    
+    /** 
+     * Enable cell origin correction.
+     * Eta and phi of the cells are corrected wrt to the origin of the tau vertex
+     */
+    bool m_doVertexCorrection;
+};
+
+//-------------------------------------------------------------------------
+//! Descending order by energy
+//-------------------------------------------------------------------------
+struct CaloClusterCompare { 
+  bool operator()(const xAOD::CaloVertexedCluster& left, const xAOD::CaloVertexedCluster& right) {
+        //volatile double leftE = left.e();
+        //volatile double rightE = right.e();
+        return CxxUtils::fpcompare::greater (left.e(),right.e());
+    }
+};
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/JetSeedBuilder.h b/Reconstruction/tauRec/tauRec/JetSeedBuilder.h
new file mode 100644
index 0000000000000000000000000000000000000000..1f9cec13fcbd379dcbb62493dd3766e43c0284f1
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/JetSeedBuilder.h
@@ -0,0 +1,54 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_JETSEEDBUILDER_H
+#define	TAUREC_JETSEEDBUILDER_H
+
+#include "tauRec/TauToolBase.h"
+
+
+/**
+ * @brief Class to build tauRec seeds from topojets.
+ * 
+ *  Sets the jet ElementLink and basic kinematic variables in TauJet by searching a matching jet to the tau direction.
+ *  Also the mass of the tau is set to 0.
+ *  With tauRec4 the JetSeedBuilder method is the only one to search for a tau candidates. 
+ *  The author of the tau candidate is set 1 (former calo-only seeded) and 3 (former calo+track-seeded) to keep backwards compatibility.
+ *  
+ * @author N.Meyer <nicom@cern.ch>
+ * @author Felix Friedrich
+*/
+
+class JetSeedBuilder : public TauToolBase {
+public:
+
+    //-------------------------------------------------------------
+    //! Constructor
+    //-------------------------------------------------------------
+    JetSeedBuilder(const std::string& type,
+            const std::string& name,
+            const IInterface * parent);
+
+    //-------------------------------------------------------------
+    //! Destructor
+    //-------------------------------------------------------------
+    virtual ~JetSeedBuilder();
+
+    virtual StatusCode initialize();
+
+    virtual StatusCode execute(TauCandidateData * data);
+
+    virtual StatusCode eventFinalize(TauCandidateData *data);
+
+    virtual void cleanup(TauCandidateData *) { }
+
+private:
+    std::string m_jetCollectionName;
+    float m_maxJetdist;
+    float m_minJetPt;
+    bool m_switch_jets_em_scale;
+};
+
+#endif	/* JETSEEDBUILDER_H */
+
diff --git a/Reconstruction/tauRec/tauRec/KineUtils.h b/Reconstruction/tauRec/tauRec/KineUtils.h
new file mode 100644
index 0000000000000000000000000000000000000000..28d5e0bf25734cf82cbdb1f5d5c1e94bc585fd6f
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/KineUtils.h
@@ -0,0 +1,70 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_KINEUTILS_H
+#define TAUREC_KINEUTILS_H
+
+
+#include <string>
+#include "TVector2.h"
+
+//static const double kPI  = 3.1415927;
+//static const double k2PI = 2*3.1415927;
+
+//!
+//! @class Tau1P3PKineUtils
+//! @brief Provides methods for simple kinematical calculations
+//!
+//! Provides methods for simple kinematical calculations: absolute value
+//! of difference in pseudorapidity, in phi position, half-opening angle
+//! in ( eta, phi ) space
+//!
+
+class Tau1P3PKineUtils
+{
+    public:
+        //!
+        //! Calculates absolute value for difference in eta position
+        //!
+        //! @param x eta position of object 1
+        //! @param y eta position of object 2
+        //!
+        static double deltaEta(double eta1, double eta2) { return std::fabs( eta1 - eta2);} 
+
+        //!
+        //! Calculates absolute value for difference in phi position,
+        //! corrected for 2pi symmetry
+        //!
+        //! @param x phi  position of object 1
+        //! @param y phi  position of object 2
+        //!
+
+        /*
+        static double deltaPhi(double phi1, double phi2)
+        {
+
+            double dphi = std :: fabs( phi1 - phi2 );
+            if( dphi  >  kPI ) dphi -= k2PI;
+            return std :: fabs( dphi );
+        }
+        */
+        static double deltaPhi(double phi1, double phi2)
+        {
+            return TVector2::Phi_mpi_pi(phi1-phi2);
+        }
+
+        //!
+        //! Calculates half-opening angle in (eta,phi) space
+        //!
+        //! @param x detphi of two objects 
+        //! @param y deteta of two objects
+        //!
+        static double deltaR(double de,double dp) { return std::sqrt(de*de+dp*dp); }
+        static double deltaR(double eta1, double phi1, double eta2, double phi2) {
+        	return std::sqrt(deltaEta(eta1,eta2)*deltaEta(eta1,eta2)+deltaPhi(phi1,phi2)*deltaPhi(phi1,phi2));
+        }
+
+};
+
+#endif 
diff --git a/Reconstruction/tauRec/tauRec/LockTauContainers.h b/Reconstruction/tauRec/tauRec/LockTauContainers.h
new file mode 100644
index 0000000000000000000000000000000000000000..917b2f379110e4dfe344d9eec4bfc494b296bb41
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/LockTauContainers.h
@@ -0,0 +1,31 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_LOCKTAUCONTAINERS_H
+#define	TAUREC_LOCKTAUCONTAINERS_H
+
+#include "tauRec/TauToolBase.h"
+
+/**
+ * @brief  Set tau containers to const to prevent downstream modification.
+ * 
+ * @author Felix Friedrich
+ */
+
+class LockTauContainers : public TauToolBase
+{
+    public: 
+        LockTauContainers(const std::string& type,
+                const std::string& name,
+                const IInterface* parent);
+
+        ~LockTauContainers() { }
+
+        virtual StatusCode initialize()                      { return StatusCode::SUCCESS; }
+        virtual StatusCode execute( TauCandidateData* )      { return StatusCode::SUCCESS; }
+        virtual StatusCode eventFinalize( TauCandidateData *data );
+};
+
+#endif	/* TAUREC_LOCKTAUCONTAINERS_H */
+
diff --git a/Reconstruction/tauRec/tauRec/PhotonConversionPID.h b/Reconstruction/tauRec/tauRec/PhotonConversionPID.h
new file mode 100644
index 0000000000000000000000000000000000000000..961274b1dff118f52165465bd15abbe68390bb94
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/PhotonConversionPID.h
@@ -0,0 +1,46 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_PHOTONCONVERSIONPID_H
+#define TAUREC_PHOTONCONVERSIONPID_H
+
+#include "tauRec/TauToolBase.h"
+
+/**
+ * @brief This tool identifies Conversion Candidates via a cut on the electron probability provided by the TRT PID Tool. 
+ * 
+ *  Such Photon Conversions are needed e.g. to find Photon Conversions within the tau decay cone.
+ * 
+ * @author M. Boehler
+ */
+
+class PhotonConversionPID : public TauToolBase {
+public:
+    //-------------------------------------------------------------
+    //! Constructor
+    //-------------------------------------------------------------
+
+    PhotonConversionPID(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+
+    //-------------------------------------------------------------
+    //! Destructor
+    //-------------------------------------------------------------
+    ~PhotonConversionPID();
+
+    virtual StatusCode initialize();
+    virtual StatusCode finalize();
+    virtual StatusCode eventFinalize(TauCandidateData *data);
+
+private:
+    int m_ownPolicy;
+
+    std::string m_ConversionCandidatesName;
+    std::string m_ConversionOutputName;
+
+    double m_eProb_cut;
+};
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/PhotonConversionVertex.h b/Reconstruction/tauRec/tauRec/PhotonConversionVertex.h
new file mode 100644
index 0000000000000000000000000000000000000000..b07abfa376cb6655b1dd996ff81cf5cc257d5855
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/PhotonConversionVertex.h
@@ -0,0 +1,88 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_PHOTONCONVERSIONVERTEX_H
+#define TAUREC_PHOTONCONVERSIONVERTEX_H
+
+#include "tauRec/TauToolBase.h"
+#include "GaudiKernel/ToolHandle.h"
+
+namespace Analysis {
+    class TauJetContainer;
+}
+
+namespace Rec {
+    class TrackParticle;
+}
+
+namespace InDet {
+    class IVertexFinder;
+}
+
+/**
+ * @brief Class that runs the tau conversion finding algorithm
+ * 
+ *  This tool identifies conversion candidates
+ *  in/near (definable) a tau decay cone by reconstructing the conversion vertices 
+ *  and applying a set of cuts optimized for tau conversions on the vertex parameters.
+ * 
+ * @author KG Tan <Kong.Guan.Tan@cern.ch>
+ * 
+ */
+
+class PhotonConversionVertex : public TauToolBase {
+public:
+    //-------------------------------------------------------------
+    //! Constructor and Destructor
+    //-------------------------------------------------------------
+    PhotonConversionVertex(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+    ~PhotonConversionVertex();
+
+    //-------------------------------------------------------------
+    //! Algorithm functions
+    //-------------------------------------------------------------
+    virtual StatusCode initialize();
+    virtual StatusCode finalize();
+    virtual StatusCode eventFinalize(TauCandidateData *data);
+
+private:
+    //-------------------------------------------------------------
+    //! Convenience functions to handle storegate objects
+    //-------------------------------------------------------------
+    template <class T>
+    bool openContainer(T* &container, std::string containerName);
+
+    template <class T>
+    bool saveContainer(T* &container, std::string containerName);
+
+    template <class T>
+    bool retrieveTool(T &tool);
+
+    //-------------------------------------------------------------
+    //! Gets the minimum dR between a particle and a set of taus
+    //-------------------------------------------------------------
+    double getMinDrTauDecay(const xAOD::TauJetContainer* tauJetCont, const xAOD::TrackParticle *trackParticle);
+
+private:
+    //-------------------------------------------------------------
+    //! Storegate names of input containers and output containers
+    //-------------------------------------------------------------
+    std::string m_inputTauJetContainerName;
+    std::string m_inputTrackParticleContainerName;
+    std::string m_outputConversionVertexContainerName;
+
+    //-------------------------------------------------------------
+    //! Input parameters for conversion finding
+    //-------------------------------------------------------------
+    double m_maxTauJetDr;
+
+    //-------------------------------------------------------------
+    //! Tool used by conversion finding, initialised in job options
+    //-------------------------------------------------------------
+    ToolHandle<InDet::IVertexFinder> m_vertexFinderTool;
+};
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/TauAxisSetter.h b/Reconstruction/tauRec/tauRec/TauAxisSetter.h
new file mode 100644
index 0000000000000000000000000000000000000000..0608e5a0dca95341537c1478700ff0046f6c7a77
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauAxisSetter.h
@@ -0,0 +1,48 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUAXISSETTER_H
+#define TAUREC_TAUAXISSETTER_H
+
+#include "tauRec/TauToolBase.h"
+
+
+/**
+ * @brief Set Tau "Detector Axis" and "Intermediate Axis". 
+ * 
+ *  Note that both axes starts from the barycenter of the cluster associated to the jet seed. 
+ *  Then only the 4-vectors of clusters in a cone of dR around these barycenter are summed up, forming the new axis.
+ *  For the "Intermediate Axis" the clusters are correct wrt tau vertex in this step (barycenter remains the same).
+ *  Using this procedure, the axes are different from the original jet seed axis.
+ * 
+ * @author Margar Simonyan
+ * @author Felix Friedrich
+ *                                                                              
+ */
+
+class TauAxisSetter : public TauToolBase {
+public:
+
+    TauAxisSetter(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+    ~TauAxisSetter();
+
+    virtual StatusCode initialize();
+    virtual StatusCode eventInitialize(TauCandidateData * data);
+    virtual StatusCode finalize();
+    virtual StatusCode execute(TauCandidateData *data);
+
+private:
+    std::string tauContainerKey;
+    
+    double m_clusterCone;
+    /** 
+     * enable cell origin correction 
+     * eta and phi of the cells are corrected wrt to the origin of the tau vertex
+     */
+    bool m_doCellCorrection;
+};
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/TauBuilder.h b/Reconstruction/tauRec/tauRec/TauBuilder.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b46391c97c312129f012aaefd251a46b66f5f3d
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauBuilder.h
@@ -0,0 +1,55 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUBUILDER_H
+#define TAUREC_TAUBUILDER_H
+
+#include "GaudiKernel/ToolHandle.h"
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+#include "tauRec/TauToolBase.h"
+
+/**
+ * @brief       Main class for tau candidate building and processing.
+ * 
+ *  This class loop over seeds from the seed container, 
+ *  creates a new tau candidate if seed is passing the given cuts,
+ *  and run the given tau tools on the created tau candidate.
+ *  If a tool fails the tau candidate will be removed.
+ * 
+ * @authors     Srini Rajagopalan, Michael Heldmann, Lukasz Janyst, Anna Kaczmarska, Felix Friedrich
+ */
+
+class TauBuilder : public AthAlgorithm
+{
+  public:
+    //-----------------------------------------------------------------
+    // Constructor and destructor
+    //-----------------------------------------------------------------
+    TauBuilder(const std::string &name, ISvcLocator *pSvcLocator);
+    ~TauBuilder();
+
+    //-----------------------------------------------------------------
+    // Gaudi algorithm hooks
+    //-----------------------------------------------------------------
+    virtual StatusCode initialize();
+    virtual StatusCode execute();
+    virtual StatusCode finalize();
+
+  private:
+    std::string m_tauContainerName;             //!< tau output container
+    std::string m_tauAuxContainerName;             //!< tau output aux store container
+    std::string m_seedContainerName;            //!< seed input container
+    double m_maxEta; //!< only build taus with eta_seed < m_maxeta
+    double m_minPt;  //!< only build taus with pt_seed > m_minpt
+    
+    /** switch to create tau containers, 
+     * if false tau containers will be updated only 
+     */ 
+    bool m_doCreateTauContainers;               
+    
+    ToolHandleArray<TauToolBase> m_tools;  //!< tools to process tau candidates
+} ;
+
+#endif // TAUREC_TAUBUILDER_H
diff --git a/Reconstruction/tauRec/tauRec/TauCalibrateEM.h b/Reconstruction/tauRec/tauRec/TauCalibrateEM.h
new file mode 100644
index 0000000000000000000000000000000000000000..a3921820407648a8d7b20c229b5f52f87f89a55e
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauCalibrateEM.h
@@ -0,0 +1,50 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUCALIBRATEEM_H
+#define	TAUREC_TAUCALIBRATEEM_H
+
+#include <string>
+#include <tauRec/TauToolBase.h>
+
+class TF1;
+
+/** implementation of tau EM energy scale (depreciated) */
+class TauCalibrateEM : public TauToolBase {
+public:
+    TauCalibrateEM(const std::string& type, const std::string& name, const IInterface* parent);
+    ~TauCalibrateEM();
+
+    virtual StatusCode initialize();
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode finalize();
+
+private:
+    // private methods
+    double evaluate_new_pt(double pt, double eta, int ntrack, double emfrac);
+
+    // configurables
+    std::string m_response_functions_file;
+
+    // private data
+    TF1* m_f1_1p_lem;
+    TF1* m_f1_1p_hem_barrel;
+    TF1* m_f1_1p_hem_crack;
+    TF1* m_f1_1p_hem_endcap;
+    TF1* m_f1_mp_barrel;
+    TF1* m_f1_mp_crack;
+    TF1* m_f1_mp_endcap;
+
+    std::pair<double, double> m_min_1p_lem;
+    std::pair<double, double> m_min_1p_hem_barrel;
+    std::pair<double, double> m_min_1p_hem_crack;
+    std::pair<double, double> m_min_1p_hem_endcap;
+    std::pair<double, double> m_min_mp_barrel;
+    std::pair<double, double> m_min_mp_crack;
+    std::pair<double, double> m_min_mp_endcap;
+
+};
+
+#endif	/* TAUCALIBRATEEM_H */
+
diff --git a/Reconstruction/tauRec/tauRec/TauCalibrateLC.h b/Reconstruction/tauRec/tauRec/TauCalibrateLC.h
new file mode 100644
index 0000000000000000000000000000000000000000..4b3f11c3462f0d3c8bbe495a5bdcc2c9d5e1afba
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauCalibrateLC.h
@@ -0,0 +1,58 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUCALIBRATELC_H
+#define TAUREC_TAUCALIBRATELC_H
+
+#include "tauRec/TauToolBase.h"
+
+class TH1;
+class TF1;
+
+/**
+ * @brief Implementation of tau energy scale (TES) with eta and pile-up correction.
+ * 
+ *  The energy and eta (direction) correction are done separatly and steered by flags.
+ * 
+ * @author Margar Simonyan
+ * @author Felix Friedrich
+ *                                                                              
+ */
+
+class TauCalibrateLC : public TauToolBase {
+public:
+
+    TauCalibrateLC(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+    ~TauCalibrateLC();
+
+    virtual StatusCode initialize();
+    virtual StatusCode finalize();
+    virtual StatusCode execute(TauCandidateData *data);
+
+private:
+    std::string tauContainerKey;
+    std::string vertexContainerKey;
+    std::string calibrationFile; //!< energy calibration file
+
+    static const int nProngBins = 2;
+
+    const TF1 * calibFunc[nProngBins][10]; //maximum 10 eta bins; might not be used on the whole 
+    const TH1 * slopeNPVHist[nProngBins];
+    const TH1 * etaBinHist;
+    const TH1 * etaCorrectionHist;
+
+    unsigned int m_minNTrackAtVertex;
+    int    m_nEtaBins;
+    double m_averageNPV;
+
+    bool m_doEnergyCorr; //!< switch for energy correction
+    bool m_doAxisCorr;   //!< switch for eta correction
+    bool m_printMissingContainerINFO;
+
+  double m_clusterCone; //obsolete
+};
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/TauCandidateData.h b/Reconstruction/tauRec/tauRec/TauCandidateData.h
new file mode 100644
index 0000000000000000000000000000000000000000..7498f6a32d77c199cd9c499a9c3ecce25b44d747
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauCandidateData.h
@@ -0,0 +1,106 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_CANDIDATE_DATA_H
+#define TAUREC_CANDIDATE_DATA_H
+//-----------------------------------------------------------------------------
+// file:        TauCandidateData.h
+// package:     Reconstruction/tauEvent
+// authors:     Lukasz Janyst
+// date:        2007-02-13
+//
+//  MODIFICATIONS
+// 2008-04-22 nicom: moved setObject()/getObject() to TauCandidateData
+//
+//-----------------------------------------------------------------------------
+
+#include <string>
+#include <map>
+#include <boost/any.hpp>
+
+#include "tauEvent/TauJet.h"
+#include "tauEvent/TauJetContainer.h"
+#include "tauEvent/TauDetails.h"
+#include "tauEvent/TauDetailsContainer.h"
+
+
+#include "xAODTau/TauJet.h"
+#include "xAODTau/TauJetContainer.h"
+#include "xAODTau/TauJetAuxContainer.h"
+#include "xAODJet/Jet.h"
+
+
+/**
+ * @brief   The tau candidate object.
+ * 
+ *  Holds all containers and information needed for the tau reconstruction process.
+ * 
+ * @authors    Lukasz Janyst
+ */
+
+struct TauCandidateData
+{
+    //-----------------------------------------------------------------
+    //! Associate some object to a key - this is meant to be used by
+    //! TrigTauRec to pass container pointers to tauRec tools
+    //-----------------------------------------------------------------
+    template <typename P>
+        void setObject( std :: string key, P ptr );
+
+    //-----------------------------------------------------------------
+    //! Check if something has been associated with given key
+    //-----------------------------------------------------------------
+    bool hasObject( std :: string key ) const;
+
+    //-----------------------------------------------------------------
+    //! Get the pointer associated with given key, if types don't
+    //! match boost :: bad_any_cast exception is thrown
+    //-----------------------------------------------------------------
+    template <typename P>
+        StatusCode getObject( std :: string key, P &ptr );
+  
+    xAOD::TauJet *xAODTau;
+    xAOD::TauJetContainer* xAODTauContainer;
+    xAOD::TauJetAuxContainer *tauAuxContainer;
+    //think about changing this to IParticle
+    const xAOD::Jet  *seed;
+    const xAOD::JetContainer *seedContainer;
+    unsigned int                        detailsNum;
+
+    std :: map<std :: string, boost :: any> m_ptrMap;
+};
+
+//-------------------------------------------------------------------------
+// Set pointer
+//-------------------------------------------------------------------------
+    template <typename P>
+inline void TauCandidateData :: setObject( std :: string key, P ptr )
+{
+    m_ptrMap[key] = ptr;
+}
+
+//-------------------------------------------------------------------------
+// Get pointer
+//-------------------------------------------------------------------------
+    template <typename P>
+inline StatusCode TauCandidateData :: getObject( std :: string key, P &ptr )
+{
+    std :: map< std :: string, boost :: any> :: iterator p_it;
+    p_it = m_ptrMap.find( key );
+    if( p_it == m_ptrMap.end() )
+        return StatusCode :: FAILURE;
+
+    ptr = boost :: any_cast<P>( (*p_it).second );
+    return StatusCode :: SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// Test if any pointer has been associated with given key
+//-------------------------------------------------------------------------
+inline bool TauCandidateData :: hasObject( std :: string key ) const
+{
+    return m_ptrMap.find( key ) != m_ptrMap.end();
+}
+
+#endif // TAU_CANDIDATE_DATA
diff --git a/Reconstruction/tauRec/tauRec/TauCellVariables.h b/Reconstruction/tauRec/tauRec/TauCellVariables.h
new file mode 100644
index 0000000000000000000000000000000000000000..dae7f12d5b417f135f4d3d8440006444e63ac6d9
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauCellVariables.h
@@ -0,0 +1,49 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUCELLVARIABLES_H
+#define	TAUREC_TAUCELLVARIABLES_H
+
+#include "tauRec/TauToolBase.h"
+
+class LArEM_ID;
+class TileID;
+
+/**
+ * @brief Calculate tau calorimeter variables from cell information.
+ * 
+ * @authors  Srini Rajagopalan, Anna Kaczmarska, Felix Friedrich
+ */
+
+class TauCellVariables : public TauToolBase {
+
+public:
+    TauCellVariables(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+    ~TauCellVariables();
+
+    virtual StatusCode initialize();
+    virtual StatusCode eventInitialize(TauCandidateData *data);
+    virtual StatusCode execute(TauCandidateData *data);
+
+private:
+    double m_cellEthr;  //!< EM cell E threshold
+    double m_stripEthr; //!< cell E threshold for strips
+    double m_EMSumThr;  //!< threshold for 4-vector EM sum
+    double m_EMSumR;    //!< radius for 4-vector EM sum
+    double m_cellCone;  //!< outer cone for cells used in calculations
+
+    const LArEM_ID* m_emid;
+    const TileID* m_tileid;
+
+    /** 
+     * enable cell origin correction 
+     * eta and phi of the cells are corrected wrt to the origin of the tau vertex
+     */
+    bool m_doCellCorrection;
+};
+
+#endif	/* TAUREC_TAUCELLVARIABLES_H */
+
diff --git a/Reconstruction/tauRec/tauRec/TauCommonCalcVars.h b/Reconstruction/tauRec/tauRec/TauCommonCalcVars.h
new file mode 100644
index 0000000000000000000000000000000000000000..71e548d15c15923b56f8af69d4e9ce3782fd2eb2
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauCommonCalcVars.h
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUCOMMONCALCVARS_H
+#define TAUREC_TAUCOMMONCALCVARS_H
+
+#include "tauRec/TauToolBase.h"
+
+
+/**
+ * @brief Calculate variables which rely on tracks and precalculated cell/cluster information.
+ * 
+ *  All variables here can be recalculated using AODs.
+ * 
+ * @author Stan Lai
+ * @author Felix Friedrich
+ */
+
+class TauCommonCalcVars : public TauToolBase {
+public:
+    //-----------------------------------------------------------------
+    // Constructor and destructor
+    //-----------------------------------------------------------------
+    TauCommonCalcVars(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+    ~TauCommonCalcVars();
+    
+    virtual StatusCode initialize();                 
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode finalize();  
+
+};
+
+#endif // TAUREC_TAUCOMMONCALCVARS_H
diff --git a/Reconstruction/tauRec/tauRec/TauConversionFinder.h b/Reconstruction/tauRec/tauRec/TauConversionFinder.h
new file mode 100644
index 0000000000000000000000000000000000000000..5166e7cf9e1752dd0d4f7161367bc49291e2937d
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauConversionFinder.h
@@ -0,0 +1,48 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUCONVERSIONFINDER_H
+#define TAUREC_TAUCONVERSIONFINDER_H
+
+#include <tauRec/TauToolBase.h>
+
+/**
+ * @brief This tool identifies if a tau track is reconstructed as photon conversion track too.
+ * 
+ * @author M. Boehler
+ */
+
+class TauConversionFinder : public TauToolBase {
+public:
+    //-------------------------------------------------------------
+    //! Constructor
+    //-------------------------------------------------------------
+    TauConversionFinder(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+
+    //-------------------------------------------------------------
+    //! Destructor
+    //-------------------------------------------------------------
+    ~TauConversionFinder();
+
+    virtual StatusCode initialize();
+    virtual StatusCode eventFinalize(TauCandidateData *data);
+    virtual StatusCode finalize();
+
+private:
+    std::string m_vxCandidatesName;
+    std::string m_trackContainerName;
+    std::string m_ConversionCandidatesName;
+
+    bool m_do_normal;
+    double m_eProb_cut;
+    bool m_adjust_tau_charge;
+
+    int m_numLooseProng;
+    int m_numProng;
+
+};
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/TauConversionTagger.h b/Reconstruction/tauRec/tauRec/TauConversionTagger.h
new file mode 100644
index 0000000000000000000000000000000000000000..4cfc2806603b624b6d3ea356b90f11b4583d6100
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauConversionTagger.h
@@ -0,0 +1,51 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUCONVERSIONTAGGER_H
+#define	TAUREC_TAUCONVERSIONTAGGER_H
+
+#include "tauRec/TauToolBase.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "ITrackToVertex/ITrackToVertex.h"
+
+/**
+ * @brief This tool identifies if a tau track originates from a photon conversion track.
+ * 
+ * @author D. Varouchas
+ */
+
+
+class TauConversionTagger : public TauToolBase {
+public:
+    //-------------------------------------------------------------
+    //! Constructor
+    //-------------------------------------------------------------
+    TauConversionTagger(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+
+    //-------------------------------------------------------------
+    //! Destructor
+    //-------------------------------------------------------------
+    ~TauConversionTagger();
+
+    virtual StatusCode initialize();
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode finalize();
+
+private:
+    
+    std::string m_trackContainerName;
+
+    int m_ConvTaggerVer; 
+    bool m_TrkIsConv;
+    bool m_storeFullSummary;
+    bool m_doTRTRatio;
+    float m_a_cut[2][2], m_b_cut[2][2];	    
+    float m_TRTHighTOutliersRatio;
+    ToolHandle<Reco::ITrackToVertex> m_trackToVertexTool;
+
+};
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/TauElectronVetoVariables.h b/Reconstruction/tauRec/tauRec/TauElectronVetoVariables.h
new file mode 100644
index 0000000000000000000000000000000000000000..f3f41c8fbae181c708d1a98e805391d700d67fa5
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauElectronVetoVariables.h
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAU1P3PELEVETO_H
+#define TAUREC_TAU1P3PELEVETO_H
+
+#include "tauRec/TauToolBase.h"
+
+class IExtrapolateToCaloTool;
+
+/**
+ * @brief Calculate variables sensitive on electrons.
+ * 
+ *  The variables are mainly used by the electron veto in the TauDiscriminant package.
+ * 
+ * @author Zofia Czyczula
+ */
+
+class TauElectronVetoVariables : public TauToolBase {
+public:
+
+    TauElectronVetoVariables(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+
+    virtual ~TauElectronVetoVariables();
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode initialize();
+    virtual StatusCode eventInitialize(TauCandidateData *data);
+    
+    bool m_doCellCorrection; //!< enable cell origin correction
+    ToolHandle<IExtrapolateToCaloTool> m_trackToCalo;
+};
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/TauGenericPi0Cone.h b/Reconstruction/tauRec/tauRec/TauGenericPi0Cone.h
new file mode 100644
index 0000000000000000000000000000000000000000..47afcbe32829fd6d538bfe712d76d106648f7c38
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauGenericPi0Cone.h
@@ -0,0 +1,43 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauGenericPi0Cone.h
+// package:     Reconstruction/tauRec
+// authors:     Robert Clarke, Blake Burghgrave
+// date:        2014-01-04
+//
+//
+//-----------------------------------------------------------------------------
+
+#ifndef TAUREC_TAUGENERICPI0CONE_H
+#define	TAUREC_TAUGENERICPI0CONE_H
+
+#include "tauRec/TauToolBase.h"
+
+class TauGenericPi0Cone : public TauToolBase {
+public:
+    //-------------------------------------------------------------
+    //! Constructor
+    //-------------------------------------------------------------
+    TauGenericPi0Cone(const std::string& type,
+                   const std::string& name,
+                   const IInterface* parent);
+
+    //-------------------------------------------------------------
+    //! Destructor
+    //-------------------------------------------------------------
+    ~TauGenericPi0Cone();
+
+    virtual StatusCode initialize();
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode finalize();
+
+private:
+    
+    float m_pi0conedr;
+
+};
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/TauPi0BonnClusterCreator.h b/Reconstruction/tauRec/tauRec/TauPi0BonnClusterCreator.h
new file mode 100644
index 0000000000000000000000000000000000000000..d22cb783839d6566551e385f05760433d762454d
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauPi0BonnClusterCreator.h
@@ -0,0 +1,109 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUPI0BONNCLUSTERCREATOR_H
+#define	TAUREC_TAUPI0BONNCLUSTERCREATOR_H
+
+#include <string>
+#include <vector>
+#include "tauRec/TauToolBase.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "tauRec/TauToolBase.h"
+#include "xAODPFlow/PFOAuxContainer.h"
+
+using std::vector;
+
+class IExtrapolateToCaloTool;
+
+/**
+ * @brief Creates Pi0 clusters ("Bonn" Pi0 Finder).
+ * 
+ * @author Veit Scharf
+ * @author Will Davey <will.davey@cern.ch> 
+ * @author Benedict Winter <benedict.tobias.winter@cern.ch> 
+ */
+
+class TauPi0BonnClusterCreator : public TauToolBase {
+public:
+    TauPi0BonnClusterCreator(const std::string& type,
+            const std::string& name,
+            const IInterface *parent);
+    virtual ~TauPi0BonnClusterCreator();
+
+    virtual StatusCode initialize();
+    virtual StatusCode eventInitialize(TauCandidateData *data);
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode eventFinalize(TauCandidateData *data);
+    
+private:
+
+
+    /** @brief fraction of cluster enegry in central EM1 cells */
+    float getEM1CoreFrac( const xAOD::CaloCluster* /*pi0Candidate*/);
+    
+    /** @brief asymmetry of cluster energy distribution in EM1 w.r.t. the tracks  */
+    float getAsymmetryInEM1WRTTrk( const xAOD::CaloCluster*  /*pi0Candidate*/, 
+                                   const vector<vector<float> > /*tracksEtaAtSampling*/, 
+                                   const vector<vector<float> > /*tracksPhiAtSampling*/);
+
+
+    /** @brief number of cells from cluster with positive energy in PS, EM1 and EM2 */
+    vector<int> getNPosECells( const xAOD::CaloCluster* /*pi0Candidate*/);
+
+    std::map<unsigned, xAOD::CaloCluster*> getClusterToShotMap(
+        const std::vector<const xAOD::PFO*> shotVector,
+        const xAOD::CaloClusterContainer* pPi0ClusterContainer,
+        xAOD::TauJet *pTau);
+
+    std::vector<unsigned> getShotsMatchedToCluster(
+        const std::vector<const xAOD::PFO*> shotVector,
+        std::map<unsigned, xAOD::CaloCluster*> clusterToShotMap,
+        xAOD::CaloCluster* pPi0Cluster);
+
+    int getNPhotons( const std::vector<const xAOD::PFO*> /*shotVector*/, 
+                     std::vector<unsigned> /*shotsInCluster*/);
+
+    /** @brief first eta moment in PS, EM1 and EM2 w.r.t cluster eta: (eta_i - eta_cluster) */
+    vector<float> get1stEtaMomWRTCluster( const xAOD::CaloCluster* /*pi0Candidate*/);
+
+    /** @brief second eta moment in PS, EM1 and EM2 w.r.t cluster eta: (eta_i - eta_cluster)^2 */ 
+    vector<float> get2ndEtaMomWRTCluster(const xAOD::CaloCluster* /*pi0Candidate*/);
+
+    /** @brief get extrapolated track position at each layer */ 
+    void getExtrapolatedPositions( const xAOD::TrackParticle* /*track*/,
+                                   vector<float>&            /*trackToCaloEta*/,
+                                   vector<float>&            /*trackToCaloPhi*/);
+
+
+
+    /** @brief tool handles */
+    ToolHandle<IExtrapolateToCaloTool> m_trackToCaloTool;
+   
+    /** @brief all calo cell container name */
+    std::string m_cellContainerName;
+    
+    /** @brief input cluster container of pi0 candidates */
+    // TODO: input cluster container name
+    std::string m_inputPi0ClusterContainerName;
+    
+    /** @brief output cluster container of pi0 candidates */
+    // TODO: output cluster container name
+    std::string m_outputPi0ClusterContainerName;
+
+    /** @brief new neutral PFO container and name */
+    xAOD::PFOContainer* m_neutralPFOContainer;
+    std::string m_neutralPFOContainerName;
+    xAOD::PFOAuxContainer* m_neutralPFOAuxStore;
+    
+
+    /** @brief pt threshold for pi0 candidate clusters */
+    double m_clusterEtCut;
+
+    /** @brief output cluster container */
+    xAOD::CaloClusterContainer*  m_pOutputPi0CaloClusterContainer;
+
+};
+
+#endif	/* TAUPI0BONNCLUSTERCREATOR_H */
+
diff --git a/Reconstruction/tauRec/tauRec/TauPi0BonnCreateROI.h b/Reconstruction/tauRec/tauRec/TauPi0BonnCreateROI.h
new file mode 100644
index 0000000000000000000000000000000000000000..0e168202660506455cfcfbb8c6df4bd96bae59e2
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauPi0BonnCreateROI.h
@@ -0,0 +1,127 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUPI0BONNCREATEROI_H
+#define	TAUREC_TAUPI0BONNCREATEROI_H
+
+#include <string>
+#include <vector>
+#include <boost/scoped_ptr.hpp>
+#include <map>
+
+#include "GaudiKernel/ToolHandle.h"
+#include "tauRec/TauToolBase.h"
+
+#include "xAODPFlow/PFOAuxContainer.h"
+#include "xAODCaloEvent/CaloClusterContainer.h"
+#include "xAODTau/TauJet.h"
+
+
+
+class IHadronicCalibrationTool;
+class IExtrapolateToCaloTool;
+class ICaloCellMakerTool;
+class TauOriginCorrectionTool;
+class TauPi0BonnParser;
+/**
+ * @brief Create ROIs for the "Bonn" Pi0 Finder.
+ * 
+ * @author Veit Scharf
+ * @author Will Davey <will.davey@cern.ch> 
+ * @author Benedict Winter <benedict.tobias.winter@cern.ch> 
+ */
+
+class TauPi0BonnCreateROI : public TauToolBase {
+public:
+    TauPi0BonnCreateROI(const std::string& type,
+            const std::string& name,
+            const IInterface *parent);
+    virtual ~TauPi0BonnCreateROI();
+
+    virtual StatusCode initialize();
+    virtual StatusCode eventInitialize(TauCandidateData *data);
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode eventFinalize(TauCandidateData *data);
+    virtual StatusCode finalize();
+
+private:
+
+    /** @brief get extrapolated track position at each layer */
+    void getExtrapolatedPositions( std::vector<const xAOD::TrackParticle*>, 
+                                   int sampling);
+
+
+    /** @brief get hadronic energy associated to the tracks */
+    std::vector<double> getEstEcalEnergy( std::vector<const xAOD::TrackParticle*>,
+                                          const xAOD::CaloClusterContainer*, 
+                                          const xAOD::TauJet*); 
+  
+    /** @brief get cell weight from lateral shape */
+    double getLatWeight( int   /* samp     */,
+                        double /* deltaEta */,
+                        double /* deltaPhi */,
+                        double /* cellWidthEta */,
+                        double /* cellWidthPhi */,
+                        unsigned   /* trackNumber  */,
+                        const xAOD::TrackParticle* /* track */
+                        );
+
+    /** @brief store cell in output container */ 
+    void storeCell(const CaloCell* /* cell*/, 
+                   double          /* subtractedEnergy */);
+
+
+    /** @brief tool handles */
+    ToolHandle<IHadronicCalibrationTool> m_caloWeightTool;
+    ToolHandle<IExtrapolateToCaloTool> m_trackToCaloTool;
+    ToolHandle<ICaloCellMakerTool> m_cellMakerTool;
+
+    /** @brief calo cell navigation */
+    const CaloDetDescrManager* m_calo_dd_man;
+    const CaloCell_ID* m_calo_id;
+   
+    /** @brief lateral shower parameteristaion parser */
+    boost::scoped_ptr<TauPi0BonnParser> m_latParser;
+    std::string m_latParFile;    
+
+ 
+    /** @brief all calo cell container name */
+    std::string m_caloCellContainerName; // TODO: replace with tau clusters? 
+  
+    /** @brief all cluster container name */
+    std::string m_clusterContainerName;  // TODO: replace with tau clusters?
+ 
+    /** @brief output cell container and name*/ 
+    CaloCellContainer *m_pPi0CellContainer;
+    std::string m_pi0CellContainerName;
+
+    /** @brief new charged PFO container and name */
+    xAOD::PFOContainer* m_chargedPFOContainer;
+    std::string m_chargedPFOContainerName;
+    xAOD::PFOAuxContainer* m_chargedPFOAuxStore;
+
+    /** @brief map of tracks to normalization factors*/
+    std::map<int, TH1*> m_trackHistMapBarrel;
+    std::map<int, TH1*> m_trackHistMapEndcap;
+
+    /** @brief variables used for shower parameteristaion */
+    double m_pt;
+    double m_abseta;
+    double m_hadf;
+    double m_sampling; // its really an int but just use double
+                      // should function correctly in parser
+
+    /** @brief hash map in order to keep track, which cells have been added to output cell container*/
+    std::vector<CaloCell*> m_addedCellsMap;
+
+    /** @brief extrapolated position of tracks and vector of bools to keep track for which sampleings this has already been done */
+    std::vector<std::vector<double> > m_tracksEtaAtSampling;
+    std::vector<std::vector<double> > m_tracksPhiAtSampling;
+    std::vector<bool> m_extrapolatedSamplings;
+    std::vector<double> m_defaultValues;
+    std::vector<double> m_defaultValuesZero;
+};
+
+#endif	/* TAUPI0BONNCREATEROI_H */
+
diff --git a/Reconstruction/tauRec/tauRec/TauPi0BonnParser.h b/Reconstruction/tauRec/tauRec/TauPi0BonnParser.h
new file mode 100644
index 0000000000000000000000000000000000000000..dce779fc024b81f35165883f581c39ed4f49fb4e
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauPi0BonnParser.h
@@ -0,0 +1,92 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUPI0BONNPARSER_H
+#define	TAUREC_TAUPI0BONNPARSER_H
+
+#include <string>
+#include <map>
+#include <vector>
+#include <fstream>
+#include "TH1.h"
+class TDirectory;
+
+/**
+ * @brief Parser to read in shower parameterisations for BonnPi0CreateROI
+ * 
+ * @author Will Davey <will.davey@cern.ch> 
+ */
+
+
+class TauPi0BonnParser {
+
+    public:
+        /** constructor */
+        TauPi0BonnParser();
+        /** destructor */
+        ~TauPi0BonnParser();
+
+        /** parse input ROOT file */
+        bool parseROOTFile(std::string config_file, std::string directory = "");
+
+        /** set the address of an input variable */
+        bool setVar( const std::string& key, double& val);
+
+        /** get vector of input parameters */
+        TH1* getTH1();
+
+        /** get multi-dimensional bin key using stored vals */
+        std::string getBinKey();
+        
+        /** summary of config */
+        void summary();
+
+        /** get status of initialisation */
+        bool checkInitialisationStatus();
+
+        /** get string stream (filled incase of errors) */
+        std::string getStream();
+        
+        /** set maximum length of the stream buffer */
+        void setMaxTraceback(int);
+
+    private:
+      
+        /** get multi-dimensional bin key from list of bin indices */
+        std::string getBinKey( const std::vector<int>& bin_indices );
+
+        /** get vector of current values of input parameters */
+        std::vector<double> getCurrentVals();
+
+        /** parse TDirectory */
+        bool parseTDirectory( TDirectory*, 
+                            std::vector<int> current_bin_store = std::vector<int>(),
+                            int current_index = -1
+                            );
+
+        /** check m_par_map is filled with correct keys, given input var binning */
+        bool checkConfig(   std::vector<int> current_bin_store = std::vector<int>(),
+                            int current_index = -1
+                            );
+
+				/** set the stream */
+        void msg( const std::string& theMessage );
+														
+		private:
+        /** maintain parsed bin order */ 
+        std::vector<std::string> m_bin_order;
+        /** map var names to bin edges */ 
+        std::map<std::string,std::vector<double> > m_bin_map;
+        /** map multi-dimensional bin key to input vectors */
+        std::map<std::string,TH1*> m_hist_map;
+        /** map var names to current values */
+        std::map<std::string,double*> m_curr_val_map;
+        /** error stream */
+        std::string m_stream;
+        /** maximum length of the error stream buffer */
+        int m_max_traceback;
+};
+
+
+#endif	/* TAUPI0BONNPARSER_H */
diff --git a/Reconstruction/tauRec/tauRec/TauPi0BonnScoreCalculator.h b/Reconstruction/tauRec/tauRec/TauPi0BonnScoreCalculator.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd99b1a7e0c1d01a79ee23c9f8644252f3ecb164
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauPi0BonnScoreCalculator.h
@@ -0,0 +1,77 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUPI0BONNSCORECALCULATOR_H
+#define	TAUREC_TAUPI0BONNSCORECALCULATOR_H
+
+#include <string>
+#include "tauRec/TauToolBase.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "xAODPFlow/PFO.h"
+
+namespace TMVA{
+    class Reader;
+}
+
+/**
+ * @brief Selectes pi0Candidates ("Bonn" Pi0 Finder).
+ * 
+ * @author Veit Scharf
+ * @author Will Davey <will.davey@cern.ch> 
+ * @author Benedict Winter <benedict.tobias.winter@cern.ch> 
+ */
+
+class TauPi0BonnScoreCalculator : public TauToolBase {
+public:
+    TauPi0BonnScoreCalculator(const std::string& type,
+            const std::string& name,
+            const IInterface *parent);
+    virtual ~TauPi0BonnScoreCalculator();
+
+    virtual StatusCode initialize();
+    virtual StatusCode finalize();
+    virtual StatusCode execute(TauCandidateData *data);
+
+private:
+
+    std::string m_readerOption;
+    TMVA::Reader *m_tmvaReader;
+
+    std::string m_weightfile;
+
+    float m_FIRST_ETA;
+    float m_SECOND_R;
+    float m_SECOND_LAMBDA;
+    float m_Abs_DELTA_PHI;
+    float m_Abs_DELTA_THETA;
+    float m_CENTER_LAMBDA_helped;
+    float m_LATERAL;
+    float m_LONGITUDINAL;
+    float m_ENG_FRAC_EM;
+    float m_ENG_FRAC_MAX;
+    float m_ENG_FRAC_CORE;
+    float m_log_SECOND_ENG_DENS;
+    float m_EcoreOverEEM1;
+    float m_AsymmetryWRTTrack;
+    float m_NHitsInEM1;
+    float m_NPosCells_PS;
+    float m_NPosCells_EM1;
+    float m_NPosCells_EM2;
+    float m_firstEtaWRTCluster_EM1;
+    float m_firstEtaWRTCluster_EM2;
+    float m_secondEtaWRTCluster_EM1;
+    float m_secondEtaWRTCluster_EM2;
+    float m_energy_EM1;
+    float m_energy_EM2;
+
+    /** @brief function used to calculate BDT score */
+    float calculateScore(const xAOD::PFO* neutralPFO);
+
+    /** @brief Book TMVA methods. */
+    StatusCode bookMethod(TMVA::Reader *reader, const std::string &methodName) const;
+
+};
+
+#endif	/* TAUPI0BONNSCORECALCULATOR_H */
+
diff --git a/Reconstruction/tauRec/tauRec/TauPi0BonnSelector.h b/Reconstruction/tauRec/tauRec/TauPi0BonnSelector.h
new file mode 100644
index 0000000000000000000000000000000000000000..67a4766f3e0564f01f7fece61e5ac888e8dc44a8
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauPi0BonnSelector.h
@@ -0,0 +1,46 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUPI0BONNSELECTOR_H
+#define	TAUREC_TAUPI0BONNSELECTOR_H
+
+#include <string>
+#include "tauRec/TauToolBase.h"
+#include "GaudiKernel/ToolHandle.h"
+
+class CaloCluster;
+namespace Analysis {
+    class TauCommonDetails;
+    class TauPi0Details;
+}
+
+/**
+ * @brief Selectes pi0Candidates ("Bonn" Pi0 Finder).
+ * 
+ * @author Veit Scharf
+ * @author Will Davey <will.davey@cern.ch> 
+ * @author Benedict Winter <benedict.tobias.winter@cern.ch> 
+ */
+
+class TauPi0BonnSelector : public TauToolBase {
+public:
+    TauPi0BonnSelector(const std::string& type,
+            const std::string& name,
+            const IInterface *parent);
+    virtual ~TauPi0BonnSelector();
+    virtual StatusCode initialize();
+    virtual StatusCode execute(TauCandidateData *data);
+
+private:
+
+    std::vector<float> m_clusterEtCut;
+    std::vector<float> m_clusterBDTCut_1prong;
+    std::vector<float> m_clusterBDTCut_mprong;
+    /** @brief function used to get eta bin of Pi0Cluster */
+    int getPi0Cluster_etaBin(double Pi0Cluster_eta);
+    /** @brief function used to calculate the visible tau 4 momentum */
+    TLorentzVector getP4(xAOD::TauJet* tauJet);
+};
+
+#endif	/* TAUPI0BONNSELECTOR_H */
diff --git a/Reconstruction/tauRec/tauRec/TauProcessor.h b/Reconstruction/tauRec/tauRec/TauProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..be77ee5ae866f80d933ef7c05576a5a0539cbca2
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauProcessor.h
@@ -0,0 +1,49 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUPROCESSOR_H
+#define TAUREC_TAUPROCESSOR_H
+
+#include "GaudiKernel/ToolHandle.h"
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+#include "tauRec/TauToolBase.h"
+
+/**
+ * @brief       Main class for tau candidate building and processing.
+ * 
+ *  This class loop over tau candidates in the tau container placed there by the TauBuilder
+ *  and runs the given tau tools on the tau candidates. The tau objects are !!modified!!.
+ *  If a tool fails, the tau reconstruction will be aborted.
+ *  This algorithm has an AOD mode to skip TauExtraDetailsContainer, that is not available in AODs.
+ * 
+ *  (This algorithm was inspired by TauBuilder.)
+ * 
+ * @authors  Felix Friedrich
+ */
+
+class TauProcessor: public AthAlgorithm
+{
+    public:
+        //-----------------------------------------------------------------
+        // Contructor and destructor
+        //-----------------------------------------------------------------
+        TauProcessor( const std::string &name, ISvcLocator *pSvcLocator );
+        ~TauProcessor();
+
+        //-----------------------------------------------------------------
+        // Gaudi algorithm hooks
+        //-----------------------------------------------------------------
+        virtual StatusCode initialize();
+        virtual StatusCode execute();
+        virtual StatusCode finalize();
+
+    private:
+        std :: string                 m_tauContainerName;
+	std :: string                 m_tauAuxContainerName; 
+        bool                          m_AODmode;
+        ToolHandleArray<TauToolBase>  m_tools;
+};
+
+#endif // TAUREC_TAUPROCESSOR_H
diff --git a/Reconstruction/tauRec/tauRec/TauShotFinder.h b/Reconstruction/tauRec/tauRec/TauShotFinder.h
new file mode 100755
index 0000000000000000000000000000000000000000..95511c0b0a5b7822d5ed31c44c924ab544755118
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauShotFinder.h
@@ -0,0 +1,158 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUSHOTFINDER_H
+#define	TAUREC_TAUSHOTFINDER_H
+
+//#include <string>
+//#include <vector>
+//#include <map>
+
+#include "GaudiKernel/ToolHandle.h"
+#include "tauRec/TauToolBase.h"
+#include "xAODPFlow/PFOAuxContainer.h"
+#include "xAODCaloEvent/CaloClusterAuxContainer.h"
+
+//#include "CaloIdentifier/CaloCell_ID.h"
+
+class CaloDetDescrManager;
+class CaloCell_ID;
+class IHadronicCalibrationTool;
+
+namespace TMVA{
+    class Reader;
+}
+
+/**
+ * @brief Find photon shots in the EM1 strip layer.
+ * 
+ * @author Will Davey <will.davey@cern.ch> 
+ * @author Benedict Winter <benedict.tobias.winter@cern.ch>
+ * @author Stephanie Yuen <stephanie.yuen@cern.ch> 
+ */
+
+class TauShotFinder : public TauToolBase {
+public:
+    TauShotFinder(const std::string& type,
+            const std::string& name,
+            const IInterface *parent);
+    virtual ~TauShotFinder();
+
+    virtual StatusCode initialize();
+    virtual StatusCode eventInitialize(TauCandidateData *data);
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode eventFinalize(TauCandidateData *data);
+    virtual StatusCode finalize();
+
+    virtual void cleanup(TauCandidateData *data);
+
+
+
+private:
+
+    /** @brief tool handles */
+    ToolHandle<IHadronicCalibrationTool> m_caloWeightTool;
+
+    /** @brief all calo cell container name */
+    std::string m_caloCellContainerName;
+    /** @brief new shot cluster container and name */ 
+    xAOD::CaloClusterContainer* m_shotClusterContainer;
+    std::string m_shotClusterContainerName;
+    xAOD::CaloClusterAuxContainer* m_shotClusterAuxStore;
+
+    /** @brief new shot PFO container and name */
+    xAOD::PFOContainer* m_PFOShotContainer;
+    std::string m_shotPFOContainerName;
+    xAOD::PFOAuxContainer* m_PFOShotAuxStore;
+
+
+    /** @brief calo cell navigation */
+    const CaloDetDescrManager* m_calo_dd_man;
+    const CaloCell_ID* m_calo_id;
+
+    /** @brief readers */
+    std::string m_readerOption;
+
+    TMVA::Reader *m_tmvaReader_barrel;
+    std::string m_weightfile_barrel;
+
+    TMVA::Reader *m_tmvaReader_endcap1;
+    std::string m_weightfile_endcap1;
+
+    TMVA::Reader *m_tmvaReader_endcap2;
+    std::string m_weightfile_endcap2;
+
+    /** @brief Thanks C++ for ruining my day */
+    struct ptSort
+    { 
+         ptSort( const TauShotFinder& info );
+         const TauShotFinder& m_info;
+         bool operator()( const CaloCell* c1, const CaloCell* c2 );
+    };
+
+    /** @brief get neighbour cells */
+    std::vector<const CaloCell*> getNeighbours(const CaloCellContainer*,const CaloCell*,int /*maxDepth*/);
+
+    void addNeighbours(const CaloCellContainer*,
+                       const CaloCell* cell,
+                       std::vector<const CaloCell*>& cells,
+                       int depth,
+                       int maxDepth,
+                       bool next);
+
+    bool isPhiNeighbour(IdentifierHash cell1Hash, IdentifierHash cell2Hash, bool next);
+
+    /** @brief get eta bin */
+    float getEtaBin(float /*seedEta*/);
+  
+    /** @brief get merged BDTscore */
+    float getMergedBDTScore(int /*etaBin*/);
+
+    /** @brief get NPhotons in shot */
+    float getNPhotons(int /*etaBin*/, 
+                      float /*mergedBDTScore*/, 
+                      float /*seedEnergy*/);
+
+    /** @brief Book TMVA methods. */
+    StatusCode bookMethod(TMVA::Reader *reader_barrel, 
+                          TMVA::Reader *reader_endcap1, 
+                          TMVA::Reader *reader_endcap2, 
+                          const std::string &methodName) const;
+
+    // number of cells in eta
+    int m_nCellsInEta;
+
+    // cut values
+    std::vector<float> m_minPtCut;
+    std::vector<float> m_autoDoubleShotCut;
+    std::vector<float> m_mergedBDTScoreCut;
+  
+    // BDT input variables
+    float m_pt1;
+    float m_pt3;
+    float m_pt5;
+    float m_ws5;
+    float m_sdevEta5_WRTmean;
+    float m_sdevEta5_WRTmode;
+    float m_sdevPt5;
+    float m_deltaPt12_min;
+    float m_Fside_3not1;
+    float m_Fside_5not1;
+    float m_Fside_5not3;
+    float m_fracSide_3not1;
+    float m_fracSide_5not1;
+    float m_fracSide_5not3;
+    float m_pt1OverPt3;
+    float m_pt3OverPt5;
+
+    // FIXME: same variable names as in Stephanie's private code atm
+    float G_PTFRAC;
+    float G_STDPT_5;
+    float G_STDETA_5;
+    float G_DELTAPT_MIN;
+
+};
+
+#endif	/* TAUSHOTFINDER_H */
+
diff --git a/Reconstruction/tauRec/tauRec/TauShotVariableHelpers.h b/Reconstruction/tauRec/tauRec/TauShotVariableHelpers.h
new file mode 100644
index 0000000000000000000000000000000000000000..e2e9b76f8d4ad315c4b9bb865265230825274f4c
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauShotVariableHelpers.h
@@ -0,0 +1,79 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @brief implementation of photon shot variable calculation 
+ * 
+ * @author Will Davey <will.davey@cern.ch> 
+ * @author Benedict Winter <benedict.tobias.winter@cern.ch>
+ * @author Stephanie Yuen <stephanie.yuen@cern.ch> 
+ */
+
+#ifndef TAUSHOTVARIABLEHELPERS_H
+#define TAUSHOTVARIABLEHELPERS_H
+
+#include "xAODPFlow/PFO.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "CaloInterface/IHadronicCalibrationTool.h"
+
+namespace TauShotVariableHelpers {
+
+    /** @brief get cell block with (currently) 5x2 cells in correct order for variable calculations */
+    std::vector<std::vector<const CaloCell*> > getCellBlock(xAOD::PFO* shot,
+                                                            const CaloCell_ID* calo_id);
+
+    /** @brief mean eta, used by other functions */
+    float mean_eta(std::vector<std::vector<const CaloCell*> > /*shotCells*/, 
+                   ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/);
+
+    /** @brief mean pt, used by other functions */ 
+    float mean_pt(std::vector<std::vector<const CaloCell*> > /*shotCells*/, 
+                  ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/);
+
+    /** @brief pt in windows */
+    float ptWindow(std::vector<std::vector<const CaloCell*> > /*shotCells*/, 
+                   int /*windowSize*/, 
+                   ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/);
+
+    /** @brief ws5 variable (egamma) */
+    float ws5(std::vector<std::vector<const CaloCell*> > /*shotCells*/, 
+                          ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/);
+
+    /** @brief standard deviation in eta WRT mean */
+    float sdevEta_WRTmean(std::vector<std::vector<const CaloCell*> > /*shotCells*/, 
+                          ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/);
+
+    /** @brief standard deviation in eta WRT mode */
+    float sdevEta_WRTmode(std::vector<std::vector<const CaloCell*> > /*shotCells*/, 
+                          ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/);
+
+    /** @brief normalized standard deviation in pt */
+    float sdevPt(std::vector<std::vector<const CaloCell*> > /*shotCells*/, 
+                             ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/);
+
+    /** @brief pT diff b/w lead and sub-lead cell */
+    float deltaPt12_min(std::vector<std::vector<const CaloCell*> > /*shotCells*/, 
+                        ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/);
+
+    /** @brief Fside variable (egamma) */
+    float Fside(std::vector<std::vector<const CaloCell*> > /*shotCells*/, 
+                int /*largerWindow*/, 
+                int /*smallerWindow*/, 
+                ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/);
+
+    /** @brief similar than Fside but in unit of eta instead of number of cells */
+    float fracSide(std::vector<std::vector<const CaloCell*> > /*shotCells*/, 
+                   int /*largerWindow*/, 
+                   int /*smallerWindow*/, 
+                   ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/);
+
+    /** @brief pt window fraction */
+    float ptWindowFrac(std::vector<std::vector<const CaloCell*> > /*shotCells*/, 
+                       int /*largerWindow*/, 
+                       int /*smallerWindow*/, 
+                       ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/);
+}
+
+#endif // TAUSHOTVARIABLEHELPERS_H
+
diff --git a/Reconstruction/tauRec/tauRec/TauSubstructureVariables.h b/Reconstruction/tauRec/tauRec/TauSubstructureVariables.h
new file mode 100644
index 0000000000000000000000000000000000000000..f6482faaa45c73a841e069023abdaeaa5fd8eda4
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauSubstructureVariables.h
@@ -0,0 +1,50 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUSUBSTRUCTUREBUILDER_H
+#define TAUREC_TAUSUBSTRUCTUREBUILDER_H
+
+#include "tauRec/TauToolBase.h"
+
+/**
+ * @brief Calculate variables from the tau substructure.
+ * 
+ * @author M. Trottier-McDonald
+ * @author Felix Friedrich
+ * 
+ */
+
+class TauSubstructureVariables : public TauToolBase
+{
+    public: 
+        
+        static const double DEFAULT;
+
+        TauSubstructureVariables(const std::string& type,
+                const std::string& name,
+                const IInterface* parent);
+
+        ~TauSubstructureVariables();
+
+        virtual StatusCode execute( TauCandidateData *data );
+
+        virtual StatusCode initialize();
+        virtual StatusCode eventInitialize(TauCandidateData *data);
+
+    private:
+        /** Maximal pile up correction in GeV for a tau candidate.
+         *  Used for the caloIso corrected variable.
+         */
+        double m_maxPileUpCorrection; 
+        double m_pileUpAlpha;         //!< slope of the pileup correction
+        
+        /** 
+         * enable cell origin correction 
+         * eta and phi of the cells are corrected wrt to the origin of the tau vertex
+         */
+        bool m_doVertexCorrection;
+        bool m_inAODmode; //!< don't update everything if running on AODs
+};
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/TauTestDump.h b/Reconstruction/tauRec/tauRec/TauTestDump.h
new file mode 100644
index 0000000000000000000000000000000000000000..d42af44f555003858cf43376f8b0d96843b3a997
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauTestDump.h
@@ -0,0 +1,35 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUTESTDUMP_H
+#define TAUREC_TAUTESTDUMP_H
+
+#include "tauRec/TauToolBase.h"
+
+
+/**
+ * @brief Tau Tool for developing, testing and debugging 
+ * 
+ *  
+ * 
+ * @author Felix Friedrich
+ */
+
+class TauTestDump : public TauToolBase {
+public:
+    //-----------------------------------------------------------------
+    // Constructor and destructor
+    //-----------------------------------------------------------------
+    TauTestDump(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+    ~TauTestDump();
+    
+    virtual StatusCode initialize();                 
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode finalize();  
+
+};
+
+#endif // TAUREC_TAUTESTDUMP_H
diff --git a/Reconstruction/tauRec/tauRec/TauToolBase.h b/Reconstruction/tauRec/tauRec/TauToolBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..8be96fe86e7495be3a775fc0484f6da502df406c
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauToolBase.h
@@ -0,0 +1,73 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TOOLBASE_TAU_H
+#define TOOLBASE_TAU_H
+
+#include <string>
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "tauRec/TauCandidateData.h"
+
+/**
+ * @brief The base class for all tau tools.
+ * 
+ * @author Lukasz Janyst
+ */
+
+class TauToolBase: public AthAlgTool
+{
+    public:
+        TauToolBase( const std::string &type,
+                const std::string &name,
+                const IInterface  *parent );
+        virtual ~TauToolBase();
+
+        //-----------------------------------------------------------------
+        //! InterfaceID implementation needed for ToolHandle
+        //-----------------------------------------------------------------
+        static const InterfaceID& interfaceID();
+
+        //-----------------------------------------------------------------
+        //! Tool initializer
+        //-----------------------------------------------------------------
+        virtual StatusCode initialize();
+
+        //-----------------------------------------------------------------
+        //! Event initializer - called at the beginning of each event
+        //-----------------------------------------------------------------
+        virtual StatusCode eventInitialize( TauCandidateData *data );
+
+        //-----------------------------------------------------------------
+        //! Execute - called for each tau candidate
+        //-----------------------------------------------------------------
+        virtual StatusCode execute( TauCandidateData *data );
+
+        //-----------------------------------------------------------------
+        //! Cleanup - called for each tau rejected candidate
+        //-----------------------------------------------------------------
+        virtual void cleanup( TauCandidateData *data );
+
+        //-----------------------------------------------------------------
+        //! Event finalizer - called at the end of each event
+        //-----------------------------------------------------------------
+        virtual StatusCode eventFinalize( TauCandidateData *data );
+
+        //-----------------------------------------------------------------
+        //! Finalizer
+        //-----------------------------------------------------------------
+        virtual StatusCode finalize();
+
+        //-------------------------------------------------------------
+        //! Convenience functions to handle storegate objects
+        //-------------------------------------------------------------
+        template <class T>
+        bool openContainer(T* &container, std::string containerName, bool printFATAL=false);
+
+        template <class T>
+        bool retrieveTool(T &tool);
+
+};
+
+#endif // TOOLBASE_TAU_H
diff --git a/Reconstruction/tauRec/tauRec/TauTrackFilter.h b/Reconstruction/tauRec/tauRec/TauTrackFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..4a20fe3f3b4f34568e02a3372450cbbbf33409cc
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauTrackFilter.h
@@ -0,0 +1,47 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauTrackFilter.h
+// package:     Reconstruction/tauRec
+// authors:     Robert Clarke, Blake Burghgrave
+// date:        2014-01-04
+//
+//
+//-----------------------------------------------------------------------------
+
+#ifndef TAUREC_TAUTRACKFILTER_H
+#define	TAUREC_TAUTRACKFILTER_H
+
+#include "tauRec/TauToolBase.h"
+
+class TauTrackFilter : public TauToolBase {
+public:
+    //-------------------------------------------------------------
+    //! Constructor
+    //-------------------------------------------------------------
+    TauTrackFilter(const std::string& type,
+                   const std::string& name,
+                   const IInterface* parent);
+
+    //-------------------------------------------------------------
+    //! Destructor
+    //-------------------------------------------------------------
+    ~TauTrackFilter();
+
+    virtual StatusCode initialize();
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode finalize();
+
+private:
+    
+    std::string m_trackContainerName;
+    std::vector<bool> m_TrkPass;
+    int m_nProng;
+    int m_flag;
+    //TODO some of this probably need to be public to be useful...
+
+};
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/TauTrackFilterUtils.h b/Reconstruction/tauRec/tauRec/TauTrackFilterUtils.h
new file mode 100644
index 0000000000000000000000000000000000000000..443f965f46cd9f53e9f8b1d01344793507c35ff3
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauTrackFilterUtils.h
@@ -0,0 +1,46 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------------------------
+// file:        TauTrackFilterUtils.h
+// package:     Reconstruction/tauRec
+// authors:     Robert Clarke, Blake Burghgrave
+// date:        2014-01-13
+//
+//
+//-----------------------------------------------------------------------------
+
+#ifndef TAUREC_TAUTRACKFILTERUTILS_H
+#define	TAUREC_TAUTRACKFILTERUTILS_H
+
+#include "TF1.h"
+#include "TLorentzVector.h"
+#include <vector>
+#include <iostream>
+#include <string>
+
+namespace TauTrackFilterUtils {
+
+    struct TrackInfo{
+        TLorentzVector p4;
+        int            charge;
+        int            index;
+    };
+
+    struct TrackPair{
+        float angle;
+        float mass;
+        int charge;
+    };
+
+    bool     pass3prong(std::vector<TauTrackFilterUtils::TrackInfo> combination,TLorentzVector tau);
+    bool     pass2prong(std::vector<TauTrackFilterUtils::TrackInfo> pair,TLorentzVector tau);
+    bool     pass1prong(TLorentzVector track,TLorentzVector tau);
+    float    ComputePi0Cone(int recProngs,TLorentzVector tau);
+    float    ComputeAngle(float p, float eta, float a[9][4], int npar, int npol, char eqn[] = (char*)"[0]*exp([1]*x)+[2]+[3]/(x*x)");
+    float    Compute1dim(float p, float a[10], int npar, char eqn[]);
+
+}
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/TauTrackFinder.h b/Reconstruction/tauRec/tauRec/TauTrackFinder.h
new file mode 100644
index 0000000000000000000000000000000000000000..3281f4b0937aa6b6870212f166aff3b43e2644e5
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauTrackFinder.h
@@ -0,0 +1,142 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUTRACKFINDER_H
+#define TAUREC_TAUTRACKFINDER_H
+
+#include "tauRec/TauToolBase.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "ITrackToVertex/ITrackToVertex.h"
+
+#include "xAODTracking/Vertex.h"
+#include "xAODTracking/TrackParticle.h"
+#include "xAODTracking/TrackParticleContainer.h"
+
+class IExtrapolateToCaloTool;
+namespace Trk {
+	class ITrackSelectorTool;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** 
+ * @brief Associate tracks to the tau candidate.
+ * 
+ *  The tracks have to pass dedicated quality criteria and have to 
+ *  match to a primary vertex consistent with the tau origin.
+ * 
+ * @author KG Tan <Kong.Guan.Tan@cern.ch>
+ * @author Felix Friedrich
+ */
+
+class TauTrackFinder : public TauToolBase {
+public:
+    //-------------------------------------------------------------
+    //! Constructor and Destructor
+    //-------------------------------------------------------------
+    TauTrackFinder(const std::string& type, const std::string& name, const IInterface* parent);
+    ~TauTrackFinder();
+
+    //-------------------------------------------------------------
+    //! Enumerator defining type of tau track
+    //-------------------------------------------------------------
+    enum TauTrackType
+    {
+        TauTrackCore  = 0,
+        TauTrackWide  = 1,
+        TauTrackOther = 2,
+        NotTauTrack   = 3
+    };
+
+    //-------------------------------------------------------------
+    //! Algorithm functions
+    //-------------------------------------------------------------
+    virtual StatusCode initialize();
+    virtual StatusCode eventInitialize(TauCandidateData *data);
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode eventFinalize(TauCandidateData *data);
+    virtual StatusCode finalize();
+    
+    //-------------------------------------------------------------
+    //! Extrapolate track eta and phi to the calorimeter middle surface
+    //-------------------------------------------------------------
+    StatusCode extrapolateToCaloSurface(TauCandidateData *data);
+
+    TauTrackType tauTrackType( const xAOD::TauJet* tauJet,
+    		const xAOD::TrackParticle* trackParticle,
+    		const xAOD::Vertex* primaryVertex);
+
+    void getTauTracksFromPV( const xAOD::TauJet* tauJet,
+    		const xAOD::TrackParticleContainer* trackParticleCont,
+    		const xAOD::Vertex* primaryVertex,
+    		std::vector<const xAOD::TrackParticle*> &tauTracks,
+    		std::vector<const xAOD::TrackParticle*> &wideTracks,
+    		std::vector<const xAOD::TrackParticle*> &otherTracks);
+
+    // old style AOD version
+    void removeOffsideTracksWrtLeadTrk(std::vector<const Rec::TrackParticle*> &tauTracks,
+                                           std::vector<const Rec::TrackParticle*> &wideTracks,
+                                           std::vector<const Rec::TrackParticle*> &otherTracks,
+                                           const Trk::RecVertex* tauOrigin,
+                                           double maxDeltaZ0);
+
+    // new xAOD version
+    void removeOffsideTracksWrtLeadTrk(std::vector<const xAOD::TrackParticle*> &tauTracks,
+                                           std::vector<const xAOD::TrackParticle*> &wideTracks,
+                                           std::vector<const xAOD::TrackParticle*> &otherTracks,
+                                           const xAOD::Vertex* tauOrigin,
+                                           double maxDeltaZ0);
+
+    void  getDeltaZ0Values(std::vector<float>& vDeltaZ0coreTrks, std::vector<float>& vDeltaZ0wideTrks);
+    void  resetDeltaZ0Cache();
+
+private:
+    //-------------------------------------------------------------
+    //! Some internally used functions
+    //-------------------------------------------------------------
+    float getZ0(const Rec::TrackParticle* track, const Trk::RecVertex* vertex);  //AOD version
+    float getZ0(const xAOD::TrackParticle* track, const xAOD::Vertex* vertex);   //xAOD version
+
+private:
+    //-------------------------------------------------------------
+    //! Storegate names of input containers and output containers
+    //-------------------------------------------------------------
+    std::string m_inputTauJetContainerName;
+    std::string m_inputTrackParticleContainerName;
+    std::string m_inputPrimaryVertexContainerName;
+
+    //-------------------------------------------------------------
+    //! tools
+    //-------------------------------------------------------------
+    ToolHandle<IExtrapolateToCaloTool> m_trackToCalo;
+    ToolHandle<Trk::ITrackSelectorTool> m_trackSelectorTool_tau;
+    ToolHandle<Reco::ITrackToVertex> m_trackToVertexTool;
+    
+    //-------------------------------------------------------------
+    //! Input parameters for algorithm
+    //-------------------------------------------------------------
+    double  m_maxJetDr_tau;
+    double  m_maxJetDr_wide;
+    
+    //-------------------------------------------------------------
+    // z0 cuts
+    //-------------------------------------------------------------
+    float m_z0maxDelta;
+    bool m_applyZ0cut;
+    bool m_storeInOtherTrks;
+    std::vector<float> m_vDeltaZ0coreTrks;
+    std::vector<float> m_vDeltaZ0wideTrks;
+
+    //-------------------------------------------------------------
+    //! Convenience functions to handle storegate objects
+    //-------------------------------------------------------------
+    template <class T>
+    bool openContainer(T* &container, std::string containerName, bool printFATAL=false);
+
+    template <class T>
+    bool retrieveTool(T &tool);
+
+};
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/TauTrackSlimmer.h b/Reconstruction/tauRec/tauRec/TauTrackSlimmer.h
new file mode 100644
index 0000000000000000000000000000000000000000..26ab2eb6194fc3d7b832ed93a8018e73a352f67f
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauTrackSlimmer.h
@@ -0,0 +1,51 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TRACKSLIMMER_TAU_H
+#define TAUREC_TRACKSLIMMER_TAU_H
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "AthenaKernel/IThinningSvc.h"
+#include "ParticleEvent/ParticleBase.h"
+#include <string>
+
+class StoreGateSvc;
+
+/**
+ * @brief Class for tau tracks slimming.
+ * 
+ * @author Anna Kaczmarska, Lukasz Janyst
+ */
+
+class TauTrackSlimmer: public AthAlgorithm
+{
+    public:
+
+        //-----------------------------------------------------------------
+        // Contructor and destructor
+        //-----------------------------------------------------------------
+        TauTrackSlimmer( const std::string &name, ISvcLocator *pSvcLocator );
+        ~TauTrackSlimmer();
+
+        //-----------------------------------------------------------------
+        // Gaudi algorithm hooks
+        //-----------------------------------------------------------------
+        virtual StatusCode initialize();
+        virtual StatusCode execute();
+        virtual StatusCode finalize();
+
+    private:
+        std :: string                 m_tauContainerName;
+        ServiceHandle<IThinningSvc>   m_thinningSvc;
+        bool                          m_filterTaus;
+        unsigned                      m_maxNTrack;
+        ChargeType                    m_maxCharge;
+        double                        m_maxEmRadius;
+        double                        m_maxIsoFrac;
+
+
+};
+
+#endif // TAUREC_TRACKSLIMMER_TAU_H
diff --git a/Reconstruction/tauRec/tauRec/TauVertexFinder.h b/Reconstruction/tauRec/tauRec/TauVertexFinder.h
new file mode 100644
index 0000000000000000000000000000000000000000..3a8ea5dccf5345823cd55e6aa908ee2a7bb98aeb
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauVertexFinder.h
@@ -0,0 +1,70 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUVERTEXFINDER_H
+#define TAUREC_TAUVERTEXFNIDER_H
+
+#include "tauRec/TauToolBase.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "xAODTracking/VertexContainer.h"
+#include "JetEDM/TrackVertexAssociation.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+/** 
+ * @brief Associate a vertex (origin) to the tau candidate.
+ * 
+ *  The vertex has to be consistent with the origin of tau jet seed.
+ *  The vertex is determined in the following order: TJVA -> first PV in vertex container -> 0
+ *  Attention: all downstream tau variables will be calculated to the vertex set here!
+ * 
+ * @author KG Tan <Kong.Guan.Tan@cern.ch>
+ * @author Felix Friedrich <Felix.Friedrich@cern.ch>
+ */
+
+class TauVertexFinder : public TauToolBase {
+public:
+    //-------------------------------------------------------------
+    //! Constructor and Destructor
+    //-------------------------------------------------------------
+    TauVertexFinder(const std::string& type, const std::string& name, const IInterface* parent);
+    ~TauVertexFinder();
+
+    //-------------------------------------------------------------
+    //! Algorithm functions
+    //-------------------------------------------------------------
+    virtual StatusCode initialize();
+    virtual StatusCode eventInitialize(TauCandidateData *data);
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode eventFinalize(TauCandidateData *data);
+    virtual StatusCode finalize();
+
+    ElementLink<xAOD::VertexContainer> getPV_TJVA(const xAOD::TauJet* tauJet, const xAOD::VertexContainer* vertices);
+
+private:
+    float getJetVertexFraction(const xAOD::Vertex* vertex, const std::vector<const xAOD::TrackParticle*>& tracks, const jet::TrackVertexAssociation* tva) const;
+        
+    //-------------------------------------------------------------
+    //! Convenience functions to handle storegate objects
+    //-------------------------------------------------------------
+    template <class T>
+    bool openContainer(T* &container, std::string containerName, bool printFATAL=false);
+
+    template <class T>
+    bool retrieveTool(T &tool);
+
+private:
+    bool m_printMissingContainerINFO;
+    float m_maxJVF;
+
+    //-------------------------------------------------------------
+    //! Configureables
+    //-------------------------------------------------------------
+    bool m_useTJVA;
+    std::string m_inputPrimaryVertexContainerName;
+    std::string m_assocTracksName;
+    std::string m_trackVertexAssocName;    
+};
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/TauVertexVariables.h b/Reconstruction/tauRec/tauRec/TauVertexVariables.h
new file mode 100644
index 0000000000000000000000000000000000000000..eb830c5ea95adac6c89e42c2660c7b1806580e1e
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TauVertexVariables.h
@@ -0,0 +1,64 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUVERTEXVARIABLES_H
+#define	TAUREC_TAUVERTEXVARIABLES_H
+
+#include "xAODTracking/VertexContainer.h"
+#include "xAODTracking/VertexAuxContainer.h"
+#include "tauRec/TauToolBase.h"
+#include "GaudiKernel/ToolHandle.h"
+
+// forwards
+class TauCandidateData;
+namespace Trk {
+	class ITrackToVertexIPEstimator;
+    class IVertexFitter;
+    class IVertexSeedFinder;
+    class IVxCandidateXAODVertex;
+}
+
+/**
+ *  
+ * @brief Class for calculating vertex variables.
+ *
+ * @authors Stan Lai, Felix Friedrich
+ */
+
+class TauVertexVariables : public TauToolBase {
+public:
+    //-----------------------------------------------------------------
+    // Constructor and destructor
+    //-----------------------------------------------------------------
+    TauVertexVariables(const std::string& type,
+            const std::string& name,
+            const IInterface* parent);
+    ~TauVertexVariables();
+    
+    virtual StatusCode initialize();
+    virtual StatusCode execute(TauCandidateData *data);
+    virtual StatusCode eventInitialize(TauCandidateData *data);
+    virtual StatusCode finalize();
+    
+    //-------------------------------------------------------------
+    //! determines the transverse flight path significance from
+    //! the primary vertex and the secondary vertex of tau candidate
+    //-------------------------------------------------------------
+    double trFlightPathSig(TauCandidateData *data, const xAOD::Vertex *secVertex);
+
+private:
+    std::string m_primaryVertexKey;
+    std::string m_inputTrackParticleContainerName;
+    bool m_useOldSeedFinderAPI;
+    ToolHandle< Trk::ITrackToVertexIPEstimator > m_trackToVertexIPEstimator;
+    ToolHandle< Trk::IVertexFitter >     m_fitTool; //!< Pointer to the base class of the fit algtools
+    ToolHandle< Trk::IVertexSeedFinder > m_SeedFinder;
+    ToolHandle< Trk::IVxCandidateXAODVertex > m_xaodConverter;  // necessary to convert VxCandidate to xAOD::Vertex in case old API is used
+
+    xAOD::VertexContainer* m_pSecVtxContainer;
+    xAOD::VertexAuxContainer* m_pSecVtxAuxContainer;
+};
+
+#endif	/* TAUREC_TAUVERTEXVARIABLES_H */
+
diff --git a/Reconstruction/tauRec/tauRec/TrackSort.h b/Reconstruction/tauRec/tauRec/TrackSort.h
new file mode 100644
index 0000000000000000000000000000000000000000..0952a84161d9cae68e396e0d55fb7542f73cbba7
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/TrackSort.h
@@ -0,0 +1,44 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TRACKSORT_H
+#define TAUREC_TRACKSORT_H
+
+#include "Particle/TrackParticle.h"
+#include "Particle/TrackParticleContainer.h"
+#include "xAODTracking/TrackParticle.h"
+#include "AthLinks/ElementLink.h"
+
+/**
+ * @brief Helper method to sort tracks
+ * 
+ * Usage:
+ * sort(track_begin, track_end, tauTrackSort);
+ * We want pt0 > pt1 > ..., so the test on ptInvVert is < .
+ * 
+ */
+
+class TrackSort {
+
+    public:
+        TrackSort(){ };
+
+        bool operator() (const ElementLink<Rec::TrackParticleContainer>& t1, const ElementLink<Rec::TrackParticleContainer> &t2) const
+        {
+            return fabs( (*t1)->pt() ) > fabs( (*t2)->pt() );
+        };
+
+        bool operator() ( const Rec::TrackParticle *t1, const Rec::TrackParticle *t2 ) const
+        {
+            return fabs( t1->pt() ) > fabs( t2->pt() );
+        };
+
+        bool operator() ( const xAOD::TrackParticle *t1, const xAOD::TrackParticle *t2 ) const
+        {
+            return fabs( t1->pt() ) > fabs( t2->pt() );
+        };
+
+};
+
+#endif
diff --git a/Reconstruction/tauRec/tauRec/tauCalibrateWeightTool.h b/Reconstruction/tauRec/tauRec/tauCalibrateWeightTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..c73088aad2affda80be2727e3da35ea57b277970
--- /dev/null
+++ b/Reconstruction/tauRec/tauRec/tauCalibrateWeightTool.h
@@ -0,0 +1,77 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAUREC_TAUCALIBRATEWEIGHTTOOL_H
+#define TAUREC_TAUCALIBRATEWEIGHTTOOL_H
+/********************************************************************
+(depreciated!)
+
+NAME:     tauCalibrateWeightTool.h
+PACKAGE:  offline/Reconstruction/tauRec
+AUTHORS:  M.Heldmann
+CREATED:  March 15, 2005
+
+See comments in tauCalibrateWeightTool.cxx.
+
+13/12/2008 - (AK) change to extrapolation of TP instead of Track+code cleaning
+ ********************************************************************/
+
+#include "tauRec/TauToolBase.h"
+#include "GaudiKernel/ToolHandle.h"
+
+
+class TauCandidateData;
+class LArEM_ID;
+class TileID;
+class IHistogram1D;
+class IHadronicCalibrationTool;
+
+//-------------------------------------------------------------
+//! Class for applying H1-weighting on calorimeter cells and fudge factor for tau energy
+//-------------------------------------------------------------
+class tauCalibrateWeightTool : public TauToolBase
+{
+    public:
+        enum calibrateType { calCells = 0, calJets, calTracks, calCluster, calTopocluster };
+
+        tauCalibrateWeightTool(const std::string& type,
+                const std::string& name,
+                const IInterface* parent);
+        ~tauCalibrateWeightTool();
+
+        virtual StatusCode initialize();
+        virtual StatusCode finalize();
+        virtual StatusCode execute( TauCandidateData *data );
+
+        // Accessor methods:
+
+    private:
+        int m_calibrateType;
+        ToolHandle<IHadronicCalibrationTool> m_caloWeightTool;
+
+        const LArEM_ID* m_emid;
+        const TileID* m_tileid;
+
+        std::string m_cellWeightTool;
+        std::vector<float> m_poly;
+
+        bool m_applyCellWeightEM;
+        bool m_applyCellWeightHad;
+        bool m_applyPtEtaCorrFactors;
+        bool m_validCaloWeightTool;
+        bool m_doEtaInterpolation;
+
+        float m_fudge;
+        double m_cellCone;
+
+        int m_nptbins;
+        int m_netabins;
+
+        std::vector<float> m_ptpoints;
+        std::vector<float> m_etapoints;
+        std::vector<float> m_ptetacorrectionsntr1;
+        std::vector<float> m_ptetacorrectionsntr23;
+};
+
+#endif