From 067c67dc993856faafffb7d2c0d799c6cd63f094 Mon Sep 17 00:00:00 2001
From: Felix Friedrich <felixf@cern.ch>
Date: Thu, 14 Aug 2014 08:38:39 +0200
Subject: [PATCH] fix bug in case of cosmics (Jira ATLASRECTS-958)
 (tauRec-04-05-03-02)

---
 Reconstruction/tauRec/cmt/requirements        |  69 ++
 .../depreciated/TauEflowAddCaloInfo.cxx       | 291 ++++++
 .../tauRec/depreciated/TauEflowAddCaloInfo.h  |  53 ++
 .../depreciated/TauEflowTrackMatchCells.cxx   | 529 +++++++++++
 .../depreciated/TauEflowTrackMatchCells.h     |  93 ++
 .../tauRec/depreciated/TauEflowVariables.cxx  | 840 +++++++++++++++++
 .../tauRec/depreciated/TauEflowVariables.h    |  80 ++
 .../depreciated/TauOriginCorrectionTool.cxx   | 215 +++++
 .../depreciated/TauOriginCorrectionTool.h     |  96 ++
 .../TauPi0CrakowClusterCreator.cxx            | 454 +++++++++
 .../depreciated/TauPi0CrakowClusterCreator.h  |  64 ++
 .../depreciated/TauPi0CreatorChooser.cxx      | 184 ++++
 .../tauRec/depreciated/TauPi0CreatorChooser.h |  49 +
 .../depreciated/TauPi0EflowCreateROI.cxx      | 514 ++++++++++
 .../tauRec/depreciated/TauPi0EflowCreateROI.h |  90 ++
 .../depreciated/TauSetTracksAndCharge.cxx     |  85 ++
 .../depreciated/TauSetTracksAndCharge.h       |  45 +
 Reconstruction/tauRec/doc/mainpage.h          |  23 +
 .../tauRec/python/TauAlgorithmsHolder.py      | 879 ++++++++++++++++++
 .../tauRec/python/TauConversionAlgorithms.py  | 223 +++++
 .../tauRec/python/TauRecAODBuilder.py         | 119 +++
 Reconstruction/tauRec/python/TauRecBuilder.py | 289 ++++++
 Reconstruction/tauRec/python/tauRecFlags.py   | 123 +++
 .../tauRec/python/tauTrackSlimmer.py          |  90 ++
 .../tauRec/share/EMTES_Fits_Oct2010.root      | Bin 0 -> 12844 bytes
 .../tauRec/share/EnergyCalibrationLC2011.root | Bin 0 -> 57427 bytes
 .../tauRec/share/EnergyCalibrationLC2012.root | Bin 0 -> 60589 bytes
 .../EnergyCalibrationLC2012_retuned.root      | Bin 0 -> 64273 bytes
 .../tauRec/share/LCTES_Fits_May2011.root      | Bin 0 -> 9042 bytes
 .../share/Pi0ClusterMaker_Bonn_jobOptions.py  | 292 ++++++
 .../Pi0ClusterMaker_Crakow_jobOptions.py      | 106 +++
 Reconstruction/tauRec/share/TauAODList.py     |  86 ++
 Reconstruction/tauRec/share/TauESDList.py     |  92 ++
 .../share/tauMerged_trackslim_jobOptions.py   |   7 +
 .../tauRec/share/tauRecAOD_jobOptions.py      |  10 +
 .../tauRec/share/tauRec_RTT_topOptions.py     |  62 ++
 Reconstruction/tauRec/share/tauRec_config.py  |  81 ++
 .../tauRec/share/tauRec_jobOptions.py         |  41 +
 .../tauRec/src/CaloClusterVariables.cxx       | 203 ++++
 Reconstruction/tauRec/src/JetSeedBuilder.cxx  | 209 +++++
 .../tauRec/src/LockTauContainers.cxx          |  55 ++
 .../tauRec/src/PhotonConversionPID.cxx        | 151 +++
 .../tauRec/src/PhotonConversionVertex.cxx     | 149 +++
 Reconstruction/tauRec/src/TauAxisSetter.cxx   | 161 ++++
 Reconstruction/tauRec/src/TauBuilder.cxx      | 373 ++++++++
 Reconstruction/tauRec/src/TauCalibrateEM.cxx  | 197 ++++
 Reconstruction/tauRec/src/TauCalibrateLC.cxx  | 265 ++++++
 .../tauRec/src/TauCellVariables.cxx           | 402 ++++++++
 .../tauRec/src/TauCommonCalcVars.cxx          | 226 +++++
 .../tauRec/src/TauConversionFinder.cxx        | 153 +++
 .../tauRec/src/TauConversionTagger.cxx        | 179 ++++
 .../tauRec/src/TauElectronVetoVariables.cxx   | 390 ++++++++
 .../tauRec/src/TauGenericPi0Cone.cxx          | 107 +++
 .../tauRec/src/TauPi0BonnClusterCreator.cxx   | 602 ++++++++++++
 .../tauRec/src/TauPi0BonnCreateROI.cxx        | 763 +++++++++++++++
 .../tauRec/src/TauPi0BonnParser.cxx           | 361 +++++++
 .../tauRec/src/TauPi0BonnScoreCalculator.cxx  | 244 +++++
 .../tauRec/src/TauPi0BonnSelector.cxx         | 148 +++
 Reconstruction/tauRec/src/TauProcessor.cxx    | 231 +++++
 Reconstruction/tauRec/src/TauShotFinder.cxx   | 554 +++++++++++
 .../tauRec/src/TauShotVariableHelpers.cxx     | 357 +++++++
 .../tauRec/src/TauSubstructureVariables.cxx   | 352 +++++++
 Reconstruction/tauRec/src/TauTestDump.cxx     | 127 +++
 Reconstruction/tauRec/src/TauToolBase.cxx     | 111 +++
 Reconstruction/tauRec/src/TauTrackFilter.cxx  | 359 +++++++
 .../tauRec/src/TauTrackFilterUtils.cxx        | 266 ++++++
 Reconstruction/tauRec/src/TauTrackFinder.cxx  | 607 ++++++++++++
 Reconstruction/tauRec/src/TauTrackSlimmer.cxx | 177 ++++
 Reconstruction/tauRec/src/TauVertexFinder.cxx | 216 +++++
 .../tauRec/src/TauVertexVariables.cxx         | 327 +++++++
 .../tauRec/src/components/tauRec_entries.cxx  | 116 +++
 .../tauRec/src/components/tauRec_load.cxx     |   6 +
 .../tauRec/src/tauCalibrateWeightTool.cxx     | 395 ++++++++
 .../tauRec/tauRec/CaloClusterVariables.h      |  81 ++
 Reconstruction/tauRec/tauRec/JetSeedBuilder.h |  54 ++
 Reconstruction/tauRec/tauRec/KineUtils.h      |  70 ++
 .../tauRec/tauRec/LockTauContainers.h         |  31 +
 .../tauRec/tauRec/PhotonConversionPID.h       |  46 +
 .../tauRec/tauRec/PhotonConversionVertex.h    |  88 ++
 Reconstruction/tauRec/tauRec/TauAxisSetter.h  |  48 +
 Reconstruction/tauRec/tauRec/TauBuilder.h     |  55 ++
 Reconstruction/tauRec/tauRec/TauCalibrateEM.h |  50 +
 Reconstruction/tauRec/tauRec/TauCalibrateLC.h |  58 ++
 .../tauRec/tauRec/TauCandidateData.h          | 106 +++
 .../tauRec/tauRec/TauCellVariables.h          |  49 +
 .../tauRec/tauRec/TauCommonCalcVars.h         |  36 +
 .../tauRec/tauRec/TauConversionFinder.h       |  48 +
 .../tauRec/tauRec/TauConversionTagger.h       |  51 +
 .../tauRec/tauRec/TauElectronVetoVariables.h  |  36 +
 .../tauRec/tauRec/TauGenericPi0Cone.h         |  43 +
 .../tauRec/tauRec/TauPi0BonnClusterCreator.h  | 109 +++
 .../tauRec/tauRec/TauPi0BonnCreateROI.h       | 127 +++
 .../tauRec/tauRec/TauPi0BonnParser.h          |  92 ++
 .../tauRec/tauRec/TauPi0BonnScoreCalculator.h |  77 ++
 .../tauRec/tauRec/TauPi0BonnSelector.h        |  46 +
 Reconstruction/tauRec/tauRec/TauProcessor.h   |  49 +
 Reconstruction/tauRec/tauRec/TauShotFinder.h  | 158 ++++
 .../tauRec/tauRec/TauShotVariableHelpers.h    |  79 ++
 .../tauRec/tauRec/TauSubstructureVariables.h  |  50 +
 Reconstruction/tauRec/tauRec/TauTestDump.h    |  35 +
 Reconstruction/tauRec/tauRec/TauToolBase.h    |  73 ++
 Reconstruction/tauRec/tauRec/TauTrackFilter.h |  47 +
 .../tauRec/tauRec/TauTrackFilterUtils.h       |  46 +
 Reconstruction/tauRec/tauRec/TauTrackFinder.h | 142 +++
 .../tauRec/tauRec/TauTrackSlimmer.h           |  51 +
 .../tauRec/tauRec/TauVertexFinder.h           |  70 ++
 .../tauRec/tauRec/TauVertexVariables.h        |  64 ++
 Reconstruction/tauRec/tauRec/TrackSort.h      |  44 +
 .../tauRec/tauRec/tauCalibrateWeightTool.h    |  77 ++
 109 files changed, 18199 insertions(+)
 create mode 100755 Reconstruction/tauRec/cmt/requirements
 create mode 100644 Reconstruction/tauRec/depreciated/TauEflowAddCaloInfo.cxx
 create mode 100644 Reconstruction/tauRec/depreciated/TauEflowAddCaloInfo.h
 create mode 100644 Reconstruction/tauRec/depreciated/TauEflowTrackMatchCells.cxx
 create mode 100644 Reconstruction/tauRec/depreciated/TauEflowTrackMatchCells.h
 create mode 100644 Reconstruction/tauRec/depreciated/TauEflowVariables.cxx
 create mode 100644 Reconstruction/tauRec/depreciated/TauEflowVariables.h
 create mode 100644 Reconstruction/tauRec/depreciated/TauOriginCorrectionTool.cxx
 create mode 100644 Reconstruction/tauRec/depreciated/TauOriginCorrectionTool.h
 create mode 100644 Reconstruction/tauRec/depreciated/TauPi0CrakowClusterCreator.cxx
 create mode 100644 Reconstruction/tauRec/depreciated/TauPi0CrakowClusterCreator.h
 create mode 100644 Reconstruction/tauRec/depreciated/TauPi0CreatorChooser.cxx
 create mode 100644 Reconstruction/tauRec/depreciated/TauPi0CreatorChooser.h
 create mode 100644 Reconstruction/tauRec/depreciated/TauPi0EflowCreateROI.cxx
 create mode 100644 Reconstruction/tauRec/depreciated/TauPi0EflowCreateROI.h
 create mode 100644 Reconstruction/tauRec/depreciated/TauSetTracksAndCharge.cxx
 create mode 100644 Reconstruction/tauRec/depreciated/TauSetTracksAndCharge.h
 create mode 100644 Reconstruction/tauRec/doc/mainpage.h
 create mode 100644 Reconstruction/tauRec/python/TauAlgorithmsHolder.py
 create mode 100644 Reconstruction/tauRec/python/TauConversionAlgorithms.py
 create mode 100644 Reconstruction/tauRec/python/TauRecAODBuilder.py
 create mode 100644 Reconstruction/tauRec/python/TauRecBuilder.py
 create mode 100644 Reconstruction/tauRec/python/tauRecFlags.py
 create mode 100644 Reconstruction/tauRec/python/tauTrackSlimmer.py
 create mode 100644 Reconstruction/tauRec/share/EMTES_Fits_Oct2010.root
 create mode 100644 Reconstruction/tauRec/share/EnergyCalibrationLC2011.root
 create mode 100644 Reconstruction/tauRec/share/EnergyCalibrationLC2012.root
 create mode 100644 Reconstruction/tauRec/share/EnergyCalibrationLC2012_retuned.root
 create mode 100644 Reconstruction/tauRec/share/LCTES_Fits_May2011.root
 create mode 100644 Reconstruction/tauRec/share/Pi0ClusterMaker_Bonn_jobOptions.py
 create mode 100644 Reconstruction/tauRec/share/Pi0ClusterMaker_Crakow_jobOptions.py
 create mode 100644 Reconstruction/tauRec/share/TauAODList.py
 create mode 100644 Reconstruction/tauRec/share/TauESDList.py
 create mode 100644 Reconstruction/tauRec/share/tauMerged_trackslim_jobOptions.py
 create mode 100644 Reconstruction/tauRec/share/tauRecAOD_jobOptions.py
 create mode 100644 Reconstruction/tauRec/share/tauRec_RTT_topOptions.py
 create mode 100644 Reconstruction/tauRec/share/tauRec_config.py
 create mode 100644 Reconstruction/tauRec/share/tauRec_jobOptions.py
 create mode 100644 Reconstruction/tauRec/src/CaloClusterVariables.cxx
 create mode 100644 Reconstruction/tauRec/src/JetSeedBuilder.cxx
 create mode 100644 Reconstruction/tauRec/src/LockTauContainers.cxx
 create mode 100644 Reconstruction/tauRec/src/PhotonConversionPID.cxx
 create mode 100644 Reconstruction/tauRec/src/PhotonConversionVertex.cxx
 create mode 100644 Reconstruction/tauRec/src/TauAxisSetter.cxx
 create mode 100644 Reconstruction/tauRec/src/TauBuilder.cxx
 create mode 100644 Reconstruction/tauRec/src/TauCalibrateEM.cxx
 create mode 100644 Reconstruction/tauRec/src/TauCalibrateLC.cxx
 create mode 100644 Reconstruction/tauRec/src/TauCellVariables.cxx
 create mode 100644 Reconstruction/tauRec/src/TauCommonCalcVars.cxx
 create mode 100644 Reconstruction/tauRec/src/TauConversionFinder.cxx
 create mode 100644 Reconstruction/tauRec/src/TauConversionTagger.cxx
 create mode 100644 Reconstruction/tauRec/src/TauElectronVetoVariables.cxx
 create mode 100644 Reconstruction/tauRec/src/TauGenericPi0Cone.cxx
 create mode 100644 Reconstruction/tauRec/src/TauPi0BonnClusterCreator.cxx
 create mode 100644 Reconstruction/tauRec/src/TauPi0BonnCreateROI.cxx
 create mode 100644 Reconstruction/tauRec/src/TauPi0BonnParser.cxx
 create mode 100644 Reconstruction/tauRec/src/TauPi0BonnScoreCalculator.cxx
 create mode 100644 Reconstruction/tauRec/src/TauPi0BonnSelector.cxx
 create mode 100644 Reconstruction/tauRec/src/TauProcessor.cxx
 create mode 100644 Reconstruction/tauRec/src/TauShotFinder.cxx
 create mode 100644 Reconstruction/tauRec/src/TauShotVariableHelpers.cxx
 create mode 100644 Reconstruction/tauRec/src/TauSubstructureVariables.cxx
 create mode 100644 Reconstruction/tauRec/src/TauTestDump.cxx
 create mode 100644 Reconstruction/tauRec/src/TauToolBase.cxx
 create mode 100644 Reconstruction/tauRec/src/TauTrackFilter.cxx
 create mode 100644 Reconstruction/tauRec/src/TauTrackFilterUtils.cxx
 create mode 100644 Reconstruction/tauRec/src/TauTrackFinder.cxx
 create mode 100644 Reconstruction/tauRec/src/TauTrackSlimmer.cxx
 create mode 100644 Reconstruction/tauRec/src/TauVertexFinder.cxx
 create mode 100644 Reconstruction/tauRec/src/TauVertexVariables.cxx
 create mode 100755 Reconstruction/tauRec/src/components/tauRec_entries.cxx
 create mode 100755 Reconstruction/tauRec/src/components/tauRec_load.cxx
 create mode 100644 Reconstruction/tauRec/src/tauCalibrateWeightTool.cxx
 create mode 100644 Reconstruction/tauRec/tauRec/CaloClusterVariables.h
 create mode 100644 Reconstruction/tauRec/tauRec/JetSeedBuilder.h
 create mode 100644 Reconstruction/tauRec/tauRec/KineUtils.h
 create mode 100644 Reconstruction/tauRec/tauRec/LockTauContainers.h
 create mode 100644 Reconstruction/tauRec/tauRec/PhotonConversionPID.h
 create mode 100644 Reconstruction/tauRec/tauRec/PhotonConversionVertex.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauAxisSetter.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauBuilder.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauCalibrateEM.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauCalibrateLC.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauCandidateData.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauCellVariables.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauCommonCalcVars.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauConversionFinder.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauConversionTagger.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauElectronVetoVariables.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauGenericPi0Cone.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauPi0BonnClusterCreator.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauPi0BonnCreateROI.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauPi0BonnParser.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauPi0BonnScoreCalculator.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauPi0BonnSelector.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauProcessor.h
 create mode 100755 Reconstruction/tauRec/tauRec/TauShotFinder.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauShotVariableHelpers.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauSubstructureVariables.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauTestDump.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauToolBase.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauTrackFilter.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauTrackFilterUtils.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauTrackFinder.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauTrackSlimmer.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauVertexFinder.h
 create mode 100644 Reconstruction/tauRec/tauRec/TauVertexVariables.h
 create mode 100644 Reconstruction/tauRec/tauRec/TrackSort.h
 create mode 100644 Reconstruction/tauRec/tauRec/tauCalibrateWeightTool.h

diff --git a/Reconstruction/tauRec/cmt/requirements b/Reconstruction/tauRec/cmt/requirements
new file mode 100755
index 00000000000..149e2b92bcc
--- /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 00000000000..70934763f1a
--- /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 00000000000..ae12b5802f3
--- /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 00000000000..0df1ab35be2
--- /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 00000000000..824d2883e5e
--- /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 00000000000..d999dd57e69
--- /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 00000000000..266a3bb2c78
--- /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 00000000000..83a9081867e
--- /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 00000000000..cf9ce2a30d2
--- /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 00000000000..bb898a340c5
--- /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 00000000000..9d47fd05676
--- /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 00000000000..6508437694e
--- /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 00000000000..49fc73ad4ff
--- /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 00000000000..ef06f1f6857
--- /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 00000000000..ba3f0057dfe
--- /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 00000000000..cf3dea0f39e
--- /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 00000000000..deb5f695046
--- /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 00000000000..6191183cd74
--- /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 00000000000..97c802cf765
--- /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 00000000000..9212a547725
--- /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 00000000000..87afc51c54f
--- /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 00000000000..558fa7ca9a7
--- /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 00000000000..055b099e236
--- /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 00000000000..2b357ff9407
--- /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
GIT binary patch
literal 12844
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

literal 0
HcmV?d00001

diff --git a/Reconstruction/tauRec/share/EnergyCalibrationLC2011.root b/Reconstruction/tauRec/share/EnergyCalibrationLC2011.root
new file mode 100644
index 0000000000000000000000000000000000000000..ce496c79bb2c8bbbd94c9ebe8a41b0e1747341c1
GIT binary patch
literal 57427
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
K)n5xV4E`@RC;eIg

literal 0
HcmV?d00001

diff --git a/Reconstruction/tauRec/share/EnergyCalibrationLC2012.root b/Reconstruction/tauRec/share/EnergyCalibrationLC2012.root
new file mode 100644
index 0000000000000000000000000000000000000000..fd9fb8b7483d558448d5d8387a2d751b6c44ca7e
GIT binary patch
literal 60589
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
NZ<P%a^t*2t{{W5-AQb=r

literal 0
HcmV?d00001

diff --git a/Reconstruction/tauRec/share/EnergyCalibrationLC2012_retuned.root b/Reconstruction/tauRec/share/EnergyCalibrationLC2012_retuned.root
new file mode 100644
index 0000000000000000000000000000000000000000..b0413b95b96feadfad36f4ed58cec6071fdf95ff
GIT binary patch
literal 64273
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%0AOUfmS#!WYOr2KOGmR9!*?V
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
bukd_$L4qmZaz-kGN@xbl4I57M;?jQrH*CJz

literal 0
HcmV?d00001

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
GIT binary patch
literal 9042
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

literal 0
HcmV?d00001

diff --git a/Reconstruction/tauRec/share/Pi0ClusterMaker_Bonn_jobOptions.py b/Reconstruction/tauRec/share/Pi0ClusterMaker_Bonn_jobOptions.py
new file mode 100644
index 00000000000..f49fb74a0b5
--- /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 00000000000..d6ab9bd268f
--- /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 00000000000..b6bd7ee829c
--- /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 00000000000..7dcca4c0e3c
--- /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 00000000000..d1f8d7c42be
--- /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 00000000000..ec6246dca06
--- /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 00000000000..e0bd3f1054e
--- /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 00000000000..1bb562aecc1
--- /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 00000000000..7ab848bf341
--- /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 00000000000..736e9a40c0a
--- /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 00000000000..a9a23826f38
--- /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 00000000000..528ee0bcca4
--- /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 00000000000..362c328ec64
--- /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 00000000000..df6806e74e2
--- /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 00000000000..677388c6123
--- /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 00000000000..bab7cd3870c
--- /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 00000000000..dd81f02987c
--- /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 00000000000..dc4cc3f1db3
--- /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 00000000000..d30423c9d14
--- /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 00000000000..ff2ad3048e0
--- /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 00000000000..f5636b97b40
--- /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 00000000000..75b705bdfd5
--- /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 00000000000..f788db96a04
--- /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 00000000000..6dd3de18e22
--- /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 00000000000..8843a927e60
--- /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 00000000000..4c824dc37bc
--- /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 00000000000..efea376fd40
--- /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 00000000000..c4dbb38b2c7
--- /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 00000000000..8202b9a183b
--- /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 00000000000..1d47aa9c2b0
--- /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 00000000000..0075f5b51d0
--- /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 00000000000..203437ef846
--- /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 00000000000..30dd7035112
--- /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 00000000000..fd1748b3ec2
--- /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 00000000000..8ce8a56656b
--- /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 00000000000..acf573be1b8
--- /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 00000000000..24a9d1ccac9
--- /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 00000000000..c022555997e
--- /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 00000000000..5ae7b168557
--- /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 00000000000..ae95c3f0367
--- /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 00000000000..c0235b1b7b9
--- /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 00000000000..e4171128090
--- /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 00000000000..84f141f2296
--- /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 00000000000..c3dff174ba0
--- /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 00000000000..9b34c1b6d99
--- /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 00000000000..1f9cec13fcb
--- /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 00000000000..28d5e0bf257
--- /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 00000000000..917b2f37911
--- /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 00000000000..961274b1dff
--- /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 00000000000..b07abfa376c
--- /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 00000000000..0608e5a0dca
--- /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 00000000000..8b46391c97c
--- /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 00000000000..a3921820407
--- /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 00000000000..4b3f11c3462
--- /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 00000000000..7498f6a32d7
--- /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 00000000000..dae7f12d5b4
--- /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 00000000000..71e548d15c1
--- /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 00000000000..5166e7cf9e1
--- /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 00000000000..4cfc2806603
--- /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 00000000000..f3f41c8fbae
--- /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 00000000000..47afcbe3282
--- /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 00000000000..d22cb783839
--- /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 00000000000..0e168202660
--- /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 00000000000..dce779fc024
--- /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 00000000000..cd99b1a7e0c
--- /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 00000000000..67a4766f3e0
--- /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 00000000000..be77ee5ae86
--- /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 00000000000..95511c0b0a5
--- /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 00000000000..e2e9b76f8d4
--- /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 00000000000..f6482faaa45
--- /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 00000000000..d42af44f555
--- /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 00000000000..8be96fe86e7
--- /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 00000000000..4a20fe3f3b4
--- /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 00000000000..443f965f46c
--- /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 00000000000..3281f4b0937
--- /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 00000000000..26ab2eb6194
--- /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 00000000000..3a8ea5dccf5
--- /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 00000000000..eb830c5ea95
--- /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 00000000000..0952a84161d
--- /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 00000000000..c73088aad2a
--- /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
-- 
GitLab