From 3989672dac7a23855c619dfc31f53fa264571176 Mon Sep 17 00:00:00 2001
From: Scott Snyder <scott.snyder@cern.ch>
Date: Tue, 5 Aug 2014 04:49:05 +0200
Subject: [PATCH] Fix use of ParticleData. (egammaD3PDAnalysis-00-02-16)

---
 .../egammaD3PDAnalysis/cmt/requirements       |  39 ++
 .../D3PDMaker/egammaD3PDAnalysis/ispellwords  | 394 ++++++++++++++++++
 .../python/PhotonTruthConfig.py               |  67 +++
 .../python/TileGapConfig.py                   |  68 +++
 .../python/TileGapSelectionGetter.py          |  71 ++++
 .../egammaD3PDAnalysis/python/__init__.py     |  22 +
 .../python/egammaCalcOQConfig.py              |  63 +++
 .../python/egammaDeltaEmax2Config.py          |  65 +++
 .../python/egammaMaxECellAlgConfig.py         |  61 +++
 .../python/egammaNbCellsGainAlgConfig.py      |  61 +++
 .../python/egammaShowerDepthAlg.py            |  33 ++
 .../python/egammaShowerDepthConfig.py         |  59 +++
 .../python/egammaSumCellsGainAlgConfig.py     |  61 +++
 .../python/egammaTimeCorrConfig.py            |  69 +++
 .../python/egammaTopoIsoConfig.py             |  81 ++++
 .../python/egammaTruthParticleConfig.py       |  58 +++
 .../src/ElectronRedoOQAlg.cxx                 |  32 ++
 .../src/ElectronRedoOQAlg.h                   |  48 +++
 .../src/PhotonRedoOQAlg.cxx                   |  32 ++
 .../egammaD3PDAnalysis/src/PhotonRedoOQAlg.h  |  48 +++
 .../egammaD3PDAnalysis/src/PhotonTruthAlg.cxx |  90 ++++
 .../egammaD3PDAnalysis/src/PhotonTruthAlg.h   |  73 ++++
 .../src/PhotonTruthTool.cxx                   | 314 ++++++++++++++
 .../egammaD3PDAnalysis/src/PhotonTruthTool.h  | 139 ++++++
 .../src/TileGapSelectionAlg.cxx               |  88 ++++
 .../src/TileGapSelectionAlg.h                 |  67 +++
 .../egammaD3PDAnalysis/src/TileGapSumAlg.cxx  | 108 +++++
 .../egammaD3PDAnalysis/src/TileGapSumAlg.h    |  75 ++++
 .../src/clusterHasCells.cxx                   |  30 ++
 .../egammaD3PDAnalysis/src/clusterHasCells.h  |  32 ++
 .../components/egammaD3PDAnalysis_entries.cxx |  70 ++++
 .../components/egammaD3PDAnalysis_load.cxx    |  13 +
 .../src/egammaCalcOQAlg.cxx                   | 111 +++++
 .../egammaD3PDAnalysis/src/egammaCalcOQAlg.h  |  72 ++++
 .../src/egammaDeltaEmax2Alg.cxx               |  87 ++++
 .../src/egammaDeltaEmax2Alg.h                 |  73 ++++
 .../src/egammaMaxECellAlg.cxx                 | 127 ++++++
 .../src/egammaMaxECellAlg.h                   |  75 ++++
 .../src/egammaNbCellsGainAlg.cxx              | 155 +++++++
 .../src/egammaNbCellsGainAlg.h                |  70 ++++
 .../src/egammaRedoOQAlg.cxx                   |  82 ++++
 .../egammaD3PDAnalysis/src/egammaRedoOQAlg.h  | 129 ++++++
 .../src/egammaRedoOQAlg.icc                   |  82 ++++
 .../src/egammaShowerDepthAlg.cxx              | 112 +++++
 .../src/egammaShowerDepthAlg.h                | 104 +++++
 .../src/egammaSumCellsGainAlg.cxx             | 156 +++++++
 .../src/egammaSumCellsGainAlg.h               |  70 ++++
 .../src/egammaTimeCorrAlg.cxx                 | 109 +++++
 .../src/egammaTimeCorrAlg.h                   |  86 ++++
 .../src/egammaTopoIsoAlg.cxx                  | 137 ++++++
 .../egammaD3PDAnalysis/src/egammaTopoIsoAlg.h |  99 +++++
 .../egammaD3PDAnalysis/src/egammaTruthAlg.cxx | 304 ++++++++++++++
 .../egammaD3PDAnalysis/src/egammaTruthAlg.h   | 124 ++++++
 53 files changed, 4895 insertions(+)
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/cmt/requirements
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/ispellwords
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/PhotonTruthConfig.py
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/TileGapConfig.py
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/TileGapSelectionGetter.py
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/__init__.py
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaCalcOQConfig.py
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaDeltaEmax2Config.py
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaMaxECellAlgConfig.py
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaNbCellsGainAlgConfig.py
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaShowerDepthAlg.py
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaShowerDepthConfig.py
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaSumCellsGainAlgConfig.py
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaTimeCorrConfig.py
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaTopoIsoConfig.py
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaTruthParticleConfig.py
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/ElectronRedoOQAlg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/ElectronRedoOQAlg.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonRedoOQAlg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonRedoOQAlg.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthAlg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthAlg.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthTool.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthTool.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSelectionAlg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSelectionAlg.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSumAlg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSumAlg.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/clusterHasCells.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/clusterHasCells.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/components/egammaD3PDAnalysis_entries.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/components/egammaD3PDAnalysis_load.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaCalcOQAlg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaCalcOQAlg.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaDeltaEmax2Alg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaDeltaEmax2Alg.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaMaxECellAlg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaMaxECellAlg.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaNbCellsGainAlg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaNbCellsGainAlg.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaRedoOQAlg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaRedoOQAlg.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaRedoOQAlg.icc
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaShowerDepthAlg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaShowerDepthAlg.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaSumCellsGainAlg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaSumCellsGainAlg.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTimeCorrAlg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTimeCorrAlg.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTopoIsoAlg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTopoIsoAlg.h
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTruthAlg.cxx
 create mode 100644 PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTruthAlg.h

diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/cmt/requirements b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/cmt/requirements
new file mode 100644
index 00000000000..b5999042d68
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/cmt/requirements
@@ -0,0 +1,39 @@
+package egammaD3PDAnalysis
+
+use AtlasPolicy                AtlasPolicy-*     
+
+
+private
+use GaudiInterface             GaudiInterface-*        External
+use AtlasBoost                 AtlasBoost-*            External
+use HepPDT                     v*                      LCG_Interfaces
+use CxxUtils                   CxxUtils-*              Control
+use AthenaKernel               AthenaKernel-*          Control
+use AthenaBaseComps            AthenaBaseComps-*       Control
+use AthContainers              AthContainers-*         Control
+use xAODCaloEvent              xAODCaloEvent-*         Event/xAOD
+use xAODEgamma                 xAODEgamma-*            Event/xAOD
+use xAODTruth                  xAODTruth-*             Event/xAOD
+use CaloGeoHelpers             CaloGeoHelpers-*        Calorimeter
+use CaloEvent                  CaloEvent-*             Calorimeter
+use CaloClusterCorrection      CaloClusterCorrection-* Calorimeter
+use CaloRec                    CaloRec-*               Calorimeter
+use CaloInterface              CaloInterface-*         Calorimeter
+use LArTools                   LArTools-*              LArCalorimeter
+use FourMomUtils               FourMomUtils-*          Event
+use EventKernel                EventKernel-*           Event
+use EventInfo                  EventInfo*              Event
+use VxVertex                   VxVertex-*              Tracking/TrkEvent
+use RecoToolInterfaces         RecoToolInterfaces-*    Reconstruction/RecoTools
+use TrackToCalo                TrackToCalo-*           Reconstruction/RecoTools
+use egammaInterfaces           egammaInterfaces-*      Reconstruction/egamma
+use egammaEvent                egammaEvent-*           Reconstruction/egamma
+use D3PDMakerInterfaces        D3PDMakerInterfaces-*   PhysicsAnalysis/D3PDMaker
+use D3PDMakerUtils             D3PDMakerUtils-*        PhysicsAnalysis/D3PDMaker
+use MCTruthClassifier          MCTruthClassifier-*     PhysicsAnalysis
+end_private
+
+
+library egammaD3PDAnalysis *.cxx components/*.cxx
+apply_pattern component_library
+apply_pattern declare_python_modules files="*.py"
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/ispellwords b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/ispellwords
new file mode 100644
index 00000000000..a1a1d121e61
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/ispellwords
@@ -0,0 +1,394 @@
+personal_ws-1.1 en 393 
+egammaUserDataConfig
+DecaytoElectron
+AOD
+detStoreKey
+mvaptcone
+PDMakerAnalysis
+GaudiKernel
+EleRawClusterAlgGetter
+DCA
+egammaIsolationMVATopTool
+PhotonTruthAlgGetter
+PhotonTopoIsoAlgClusterGetter
+CaloRec
+GenParticle's
+CCbarMeson
+TileGapSelectionGetter
+StrangeBaryon
+TruthTool
+PDEgammaTruthCnvTool
+RawClusterAlg
+PhotonTruthTool
+GamRawClusterAlg
+getGenPart
+DefOrigOfElectron
+TILEGAPSUMCONTAINER
+ZBoson
+Gaudi
+AthenaBaseComps
+scott
+PhotonContainer
+NonPrimary
+UnConverted
+EventKernel
+DecaytoMuon
+cmt
+WZMSSM
+egammaDeltaEmax
+trackToVertexTool
+PrimaryVertex
+EG's
+eg's
+GamAlg
+ITrackToVertex
+TileGapSelectionAlg
+ele
+DefOrigOfPhoton
+gam
+TruthParticleBuilder
+egammaInterfacesEnumsDict
+BottomMeson
+dijets
+AuditStop
+StrangeMeson
+destructor
+BkgMuon
+fillCfgDb
+parton
+informations
+CBNT
+Geant
+McAtNLo
+hepMCLink
+egammaIsIsoAlg
+cxx
+egammaMCTruthClassifier
+PhotonTopoIsoAlgPhotonGetter
+ispellwords
+BkgPhoton
+cfgDb
+PhotonEtIsoMax
+MonitorService
+NuRTau
+egammaMCTruthClassifierDefs
+icc
+LightBaryon
+deltaRMatchCut
+StoreGateSvc
+UnknownMuon
+genconf
+genConf
+BkgElectron
+evt
+IsoPhoton
+EleRawClusterAlg
+FSR
+VertexContainerName
+ThreeProng
+Rconv
+isPhotonFromHardProc
+PDMakerUtils
+calibHitsShowerDepth
+egtruth
+BBbarMeson
+IegammaSwTool
+StoreGate
+egammaInterfaces
+DalitzDec
+AuditRestart
+TrackToCalo
+beamspot
+TrackParticleTruthCollection
+RTruthConv
+CharmedBaryon
+COOLFolder
+deltaPhiMatchCut
+Derue
+IPs
+egamma
+ElectronRedoOQAlg
+iso
+ExtrapolTrackToCaloToolElectron
+UnknownTau
+OneProng
+TruthIsolationTool
+IsoTool
+AuditFinalize
+AuditBeginRun
+isIso
+topo
+egammaShowerDepthAlg
+OutputContainerName
+muonEvent
+showerdefault
+MSSM
+locator
+configureD
+NonInteract
+IsoTypes
+defOutComeOfTau
+AuditStart
+IsoElectron
+egammaSwTool
+egammaswtool
+MsgStream
+IsoMuon
+muon
+CaloAffectedToolDefault
+userdata
+UserData
+Fedin
+NumOfParents
+QuarkWeakDec
+RconvMC
+PhotonRedoOQAlg
+bool
+NonIsoMuon
+PionDecay
+McEvents
+lum
+tileGapSum
+MonitorSvc
+namespace
+HepMC
+CaloCellContainer
+VxCvPtr
+TruthParticle
+unconv
+getMother
+TYPENAME
+brem
+egammaTrackImpactGetter
+pdgId
+egammaTruthToCaloAlg
+QCD
+McParticleEvent
+MotherBarcode
+snyder
+TrkVertexFitterInterfaces
+egammaTrackImpactAlg
+NuclInteraction
+Nucl
+egammaCalcOQGetter
+TrackParticleContainerName
+PiZero
+init
+IegammaMCTruthClassifierDev
+ParticleTruth
+isDummy
+egammaShowerDepthGetter
+TruthParticleContainer
+Extrapolator
+thePhotMoth
+trackClassifier
+pvunbiased
+etaCalo
+SGKEY
+BkgTau
+GamRawClusterAlgGetter
+PhotonConv
+DetectorStore
+pos
+NumOfDaug
+SingleMuon
+FourMomUtils
+Pythia
+ClusterCorrectionTools
+PhotonTruthAlg
+RegisterForContextService
+barcode
+Sep
+RecoToolInterfaces
+useG
+ErrorMax
+PhotonGetter
+TauLep
+NonIsoElectron
+LightMeson
+McEventsOutput
+pions
+conv
+AuditAlgorithms
+TES
+SingleTau
+RemoveEmpty
+TileGapCells
+PDAnalysis
+isBrem
+CompHep
+egammaswtoolnone
+UnknownPhoton
+SinglePhot
+CaloDetDescr
+egammaD
+TileGapSumCellGetter
+AuditInitialize
+UDPrefix
+AthenaKernel
+ChangeLog
+isem
+CellGetter
+TileGapClusterGetter
+src
+egammas
+EleAlg
+itrMother
+isFromHardProc
+DefOrigOfTau
+GaudiHandle
+ElectrMagInter
+NuclFrag
+checkreq
+TruthD
+str
+NonDefined
+IegammaMCTruthclassifier
+CLIDSvc
+queryInterface
+egammaTruthFilterTool
+AllCalo
+Econv
+egammaCalcOQAlg
+ToolWithConstantsMixin
+ErrorCount
+DetStore
+NuclearFragments
+EvtStore
+ConfigurableDb
+GenEvent
+TrackParticleTruth
+svcloc
+GeneratorObjects
+CaloClusterContainer
+AODCellContainer
+TruthHelper
+PDMaker
+PreD
+NonIsoPhoton
+useCallback
+IsolationMVATools
+newClust
+FIXME
+GamGetter
+releaseElement
+TileGapSumGetter
+IsoTightness
+egammaRedoOQAlg
+itrk
+PDAlgSeqName
+zconv
+isConv
+egammaIsIsoGetter
+FiveProng
+trackToVertexIPEstimator
+NumOfSiHitsCut
+egammaPhotonMatch
+AuditEndRun
+PhotonTopoIsoAlg
+CaloUtils
+AuditReinitialize
+DefOrigOfMuon
+PhotonAnalysisUtils
+TrkParameters
+phiCalo
+McEventCollection
+NuREle
+IsoTau
+WBosonLRSM
+NonDefinedOutCome
+EleGetter
+JPsi
+NonIsoTau
+MothOriVert
+IExtrapolateToCaloTool
+PromptPhot
+isolations
+wrt
+Higgs
+deltaEmax
+ElectronPtMin
+topoEtcone
+objKeyStore
+templated
+AuditTools
+VxPrimaryCandidate
+CheckOrigOfBkgElec
+eg
+CaloClusterCorrection
+el
+particleTruthClassifier
+itrDaug
+HiggsMSSM
+EgammaTruthToCalo
+Et
+etamax
+EtaMax
+OutputKey
+EndVert
+egammaEvent
+AuditExecute
+AlgTool
+DataModel
+ExtrapolTrackToCaloToolPhoton
+NucReact
+DoEtIsolations
+KaonDecay
+RawClustersName
+TileGapSumAlg
+LQ
+SingleElec
+NavFourMom
+HighLum
+TileGapSelection
+phtdRtoTrCut
+OutputCellContainerName
+TrackParticle
+OutputLevel
+OQ
+ZTruthConv
+ClusterCorrectionTool
+ClusterGetter
+TrackParticleCandidate
+WBoson
+ElMagProc
+SG
+pv
+DoPileup
+mcEventItr
+py
+UserDataSvc
+UD
+ISRPhot
+PDMakerInterfaces
+truePart
+egammaTruth
+UnknownOutCome
+sigd
+UndrPhot
+PDAnalysisConf
+BremPhot
+RawClustersAssocName
+VxVertex
+configurables
+getTrkGenParticle
+MCTruthClassifier
+sigz
+FSRPhot
+CheckOrigBkgElec
+CaloEvent
+ZconvMC
+PhotonPtMin
+UnknownElectron
+CaloAffectedTool
+TrkParticleBase
+EgammaTruthToCaloGetter
+genParticle
+ElectronContainer
+const
+CharmedMeson
+BottomBaryon
+NuRMu
+Alg
+nuclons
+egammaOQFlagsBuilder
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/PhotonTruthConfig.py b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/PhotonTruthConfig.py
new file mode 100644
index 00000000000..1d44c720cbf
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/PhotonTruthConfig.py
@@ -0,0 +1,67 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# $Id$
+#
+# @file egammaD3PDAnalysis/python/PhotonTruthConfig.py
+# @author scott snyder <snyder@bnl.gov>
+# @date Nov, 2011
+# @brief Configure PhotonTruthAlg to fill UserData.
+#
+
+
+from D3PDMakerConfig.D3PDMakerFlags          import D3PDMakerFlags
+from D3PDMakerCoreComps.resolveSGKey         import resolveSGKey
+from AthenaCommon.AlgSequence                import AlgSequence
+from RecExConfig.RecFlags                    import rec
+import D3PDMakerCoreComps
+import egammaD3PDAnalysis
+
+
+def PhotonTruthConfig \
+        (seq = AlgSequence(D3PDMakerFlags.PreD3PDAlgSeqName()),
+         prefix = '',
+         sgkey = D3PDMakerFlags.ElectronSGKey(),
+         typeName = 'ElectronContainer',
+         allowMissing = False):
+    """Configure PhotonTruthAlg for D3PD making.
+
+    SEQ is the Gaudi sequence to which the algorithm should be added.
+    Default is that given by PreD3PDAlgSeqName.
+
+    PREFIX is a prefix to add to the name of the algorithm scheduled.
+
+    SGKEY/TYPENAME is the StoreGate key of the input electron container
+    and the name of its type.
+
+    If ALLOWMISSING is true, don't fail if the SG key doesn't exist.
+"""
+
+    if not rec.doTruth():
+        return
+
+    if (not D3PDMakerFlags.MakeEgammaUserData() or
+        D3PDMakerFlags.HaveEgammaUserData()):
+        return
+
+    DVGetter = D3PDMakerCoreComps.SGDataVectorGetterTool
+    resolved_sgkey = resolveSGKey (typeName, sgkey)
+    auxprefix = (D3PDMakerFlags.EgammaUserDataPrefix() + '_' +
+                 resolved_sgkey + '_')
+
+    from TruthD3PDMaker.MCTruthClassifierConfig \
+         import D3PDMCTruthClassifier
+    ptaname = 'PhotonTruthAlg_' + resolved_sgkey
+    if not hasattr (seq, ptaname):
+        seq += egammaD3PDAnalysis.PhotonTruthAlg \
+               (ptaname,
+                PhotonGetter = DVGetter
+                  (prefix + 'PhotonTruthAlgGetter',
+                   TypeName = typeName,
+                   SGKey = sgkey),
+                AllowMissing = allowMissing,
+                AuxPrefix = auxprefix,
+                TruthTool = egammaD3PDAnalysis.PhotonTruthTool
+                  ('D3PD__PhotonTruthTool',
+                   Classifier = D3PDMCTruthClassifier))
+
+    return
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/TileGapConfig.py b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/TileGapConfig.py
new file mode 100644
index 00000000000..da5fc6ea161
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/TileGapConfig.py
@@ -0,0 +1,68 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# $Id$
+#
+# @file egammaD3PDAnalysis/python/TileGapConfig.py
+# @author sss
+# @date Jul, 2014
+# @brief Configure TileGapSumAlg to fill aux data.
+#
+
+
+from D3PDMakerConfig.D3PDMakerFlags            import D3PDMakerFlags
+from D3PDMakerCoreComps.resolveSGKey           import resolveSGKey
+from D3PDMakerCoreComps                        import SGDataVectorGetterTool
+from egammaD3PDAnalysis.TileGapSelectionGetter import TileGapSelectionGetter
+from AthenaCommon.AlgSequence                  import AlgSequence
+import D3PDMakerCoreComps
+import egammaD3PDAnalysis
+
+
+def TileGapConfig \
+    (seq = AlgSequence(D3PDMakerFlags.PreD3PDAlgSeqName()),
+     prefix = '',
+     sgkey = 'egClusterCollection',
+     typeName = 'DataVector<xAOD::CaloCluster_v1>',
+     allowMissing = False):
+    """Configure egammaMaxECellAlg for D3PD making.
+
+    SEQ is the Gaudi sequence to which the algorithm should be added.
+    Default is that given by PreD3PDAlgSeqName.
+
+    PREFIX is a prefix to add to the name of the algorithm scheduled.
+
+    SGKEY/TYPENAME is the StoreGate key of the input electron container
+    and the name of its type.
+
+    If ALLOWMISSING is true, don't fail if the SG key doesn't exist.
+    """
+
+    if (not D3PDMakerFlags.MakeEgammaUserData() or
+        D3PDMakerFlags.HaveEgammaUserData()):
+        return
+
+    DVGetter = D3PDMakerCoreComps.SGDataVectorGetterTool
+    resolved_sgkey = resolveSGKey (typeName, sgkey)
+    auxprefix = (D3PDMakerFlags.EgammaUserDataPrefix() + '_' +
+                 resolved_sgkey + '_')
+
+    algName = 'TileGapSumAlg' + resolved_sgkey
+    if not hasattr (seq, algName):
+
+        gapsel = TileGapSelectionGetter (seq)
+        myAlg = egammaD3PDAnalysis.TileGapSumAlg \
+                (algName,
+                 ClusterGetter = DVGetter
+                    (prefix + 'TileGapAlgGetter',
+                    TypeName = typeName,
+                    SGKey = sgkey),
+                 CellGetter = SGDataVectorGetterTool
+                    (prefix + 'TileGapAlgCellGetter',
+                     SGKey = gapsel.outputKey(),
+                     TypeName = gapsel.outputType()),
+                 AllowMissing = allowMissing,
+                 AuxPrefix = auxprefix,)
+
+        seq += myAlg
+
+    return
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/TileGapSelectionGetter.py b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/TileGapSelectionGetter.py
new file mode 100644
index 00000000000..b0820af63f4
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/TileGapSelectionGetter.py
@@ -0,0 +1,71 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# $Id$
+#
+# @file egammaD3PDAnalysis/python/TileGapSelectionGetter.py
+# @author scott snyder <snyder@bnl.gov>
+# @date Mar, 2011
+# @brief Configure algorithm to select calorimeter cells for tile gap sum.
+#
+
+
+from RecExConfig.Configured                  import Configured
+from AthenaCommon.AlgSequence                import AlgSequence
+from D3PDMakerCoreComps.resolveSGKey         import resolveSGKey
+from D3PDMakerCoreComps                      import SGObjGetterTool
+import egammaD3PDAnalysis
+
+
+class TileGapSelectionGetter ( Configured )  :
+    _outputType = "CaloCellContainer"
+    _output = { _outputType : "TileGapCells" }
+    _cellsSGKey = 'AllCalo,AODCellContainer'
+
+
+    def __init__ (self,
+                  seq = AlgSequence(),
+                  *args, **kw):
+        self.seq = seq
+        Configured.__init__ (self, *args, **kw)
+        return
+
+        
+    def configure(self):
+        from AthenaCommon.Logging import logging
+        mlog = logging.getLogger( 'TileGapSelectionGetter::configure:' )
+        mlog.info ('entering')
+
+        import traceback
+        try:
+            from RecExConfig.ObjKeyStore import objKeyStore
+            cellsname = resolveSGKey ('CaloCellContainer', self._cellsSGKey)
+            alg = egammaD3PDAnalysis.TileGapSelectionAlg \
+                    ('TileGapSelection',
+                     Getter = SGObjGetterTool ('TileGapSelectionGetter',
+                                               SGKey = cellsname,
+                                               TypeName = 'CaloCellContainer'),
+                     OutputCellContainerName = self.outputKey())
+
+            self.seq += alg
+
+            # register output in objKeyStore
+            objKeyStore.addTransient (self.outputType(),self.outputKey())
+
+            self._handle = alg
+
+        except:
+            mlog.error ("Error configuring TileGapSelectionAlg.")
+            traceback.print_exc()
+
+        return True
+
+
+    def handle (self):
+        return self._handle
+
+    # would work only if one output object type
+    def outputKey(self):
+        return self._output[self._outputType]
+
+    def outputType(self):
+        return self._outputType
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/__init__.py b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/__init__.py
new file mode 100644
index 00000000000..59abdbbff9c
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/__init__.py
@@ -0,0 +1,22 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# $Id$
+#
+# @file egammaD3PDMakerAnalysis/python/__init__.py
+# @author scott snyder <snyder@bnl.gov>
+# @date Nov, 2009
+# @brief Bring configurables into module namespace.
+#
+# Allows `egammaD3PDAnalysisConf.D3PD__foo' to be referred to as
+# `egammaD3PDAnalysis.foo'.
+#
+
+
+import egammaD3PDAnalysisConf
+for k, v in egammaD3PDAnalysisConf.__dict__.items():
+    if k.startswith ('D3PD__'):
+        globals()[k[6:]] = v
+
+# Bring this into this scope.
+from egammaShowerDepthAlg import egammaShowerDepthAlg
+
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaCalcOQConfig.py b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaCalcOQConfig.py
new file mode 100644
index 00000000000..50dd5986001
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaCalcOQConfig.py
@@ -0,0 +1,63 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# $Id$
+#
+# @file egammaD3PDAnalysis/python/egammaCalcOQConfig.py
+# @author scott snyder <snyder@bnl.gov>
+# @date Nov, 2011
+# @brief Configure egammaCalcOQAlg to fill UserData.
+#
+
+
+from D3PDMakerConfig.D3PDMakerFlags          import D3PDMakerFlags
+from D3PDMakerCoreComps.resolveSGKey         import resolveSGKey
+from AthenaCommon.AlgSequence                import AlgSequence
+from egammaTools.egammaOQFlagsBuilderBase    import egammaOQFlagsBuilderBase
+import D3PDMakerCoreComps
+import egammaD3PDAnalysis
+
+
+def egammaCalcOQConfig \
+        (seq = AlgSequence(D3PDMakerFlags.PreD3PDAlgSeqName()),
+         prefix = '',
+         sgkey = D3PDMakerFlags.ElectronSGKey(),
+         typeName = 'ElectronContainer',
+         allowMissing = False):
+    """Configure egammaTopoIsoAlg for D3PD making.
+
+    SEQ is the Gaudi sequence to which the algorithm should be added.
+    Default is that given by PreD3PDAlgSeqName.
+
+    PREFIX is a prefix to add to the name of the algorithm scheduled.
+
+    SGKEY/TYPENAME is the StoreGate key of the input electron container
+    and the name of its type.
+
+    If ALLOWMISSING is true, don't fail if the SG key doesn't exist.
+"""
+
+    if (not D3PDMakerFlags.MakeEgammaUserData() or
+        D3PDMakerFlags.HaveEgammaUserData()):
+        return
+
+    DVGetter = D3PDMakerCoreComps.SGDataVectorGetterTool
+    resolved_sgkey = resolveSGKey (typeName, sgkey)
+    udprefix = (D3PDMakerFlags.EgammaUserDataPrefix() + '_' +
+                resolved_sgkey + '_')
+
+    oqname = 'egammaCalcOQAlg_' + resolved_sgkey
+    if not hasattr (seq, oqname):
+        from AthenaCommon.AppMgr import ToolSvc
+        ToolSvc += egammaOQFlagsBuilderBase()
+        seq += egammaD3PDAnalysis.egammaCalcOQAlg \
+               (oqname,
+                egammaOQFlagsBuilder = egammaOQFlagsBuilderBase(),
+                Getter = DVGetter
+                  (prefix + 'egammaCalcOQGetter',
+                   TypeName = typeName,
+                   SGKey = sgkey),
+                AllowMissing = allowMissing,
+                UDPrefix = udprefix
+                )
+
+    return
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaDeltaEmax2Config.py b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaDeltaEmax2Config.py
new file mode 100644
index 00000000000..d220a80454f
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaDeltaEmax2Config.py
@@ -0,0 +1,65 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# $Id$
+#
+# @file egammaD3PDAnalysis/python/egammaDeltaEmax2Config.py
+# @author scott snyder <snyder@bnl.gov>
+# @date Nov, 2011
+# @brief Configure egammaDeltaEmax2Alg to fill UserData.
+#
+
+
+from D3PDMakerConfig.D3PDMakerFlags          import D3PDMakerFlags
+from D3PDMakerCoreComps.resolveSGKey         import resolveSGKey
+from AthenaCommon.AlgSequence                import AlgSequence
+import D3PDMakerCoreComps
+import egammaD3PDAnalysis
+
+
+def egammaDeltaEmax2Config \
+        (seq = AlgSequence(D3PDMakerFlags.PreD3PDAlgSeqName()),
+         prefix = '',
+         sgkey = D3PDMakerFlags.ElectronSGKey(),
+         typeName = 'DataVector<xAOD::Electron_v1>',
+         allowMissing = False):
+    """Configure egammaDeltaEmax2Alg for D3PD making.
+
+    SEQ is the Gaudi sequence to which the algorithm should be added.
+    Default is that given by PreD3PDAlgSeqName.
+
+    PREFIX is a prefix to add to the name of the algorithm scheduled.
+
+    SGKEY/TYPENAME is the StoreGate key of the input electron container
+    and the name of its type.
+
+    If ALLOWMISSING is true, don't fail if the SG key doesn't exist.
+"""
+
+    if (not D3PDMakerFlags.MakeEgammaUserData() or
+        D3PDMakerFlags.HaveEgammaUserData()):
+        return
+
+    DVGetter = D3PDMakerCoreComps.SGDataVectorGetterTool
+    resolved_sgkey = resolveSGKey (typeName, sgkey)
+    auxprefix = (D3PDMakerFlags.EgammaUserDataPrefix() + '_' +
+                 resolved_sgkey + '_')
+
+    emax2name = 'DeltaEmax2Alg_' + resolved_sgkey
+    if not hasattr (seq, emax2name):
+        highlum = False
+        if typeName == 'ElectronContainer':
+            from AthenaCommon.BeamFlags import jobproperties        
+            if jobproperties.Beam.numberOfCollisions() >= 20 :
+                highlum = True
+
+        seq += egammaD3PDAnalysis.egammaDeltaEmax2Alg \
+               (emax2name,
+                Getter = DVGetter 
+                  (prefix + 'DeltaEmax2Getter',
+                   TypeName = typeName,
+                   SGKey = sgkey),
+                AllowMissing = allowMissing,
+                HighLum = highlum,
+                AuxPrefix = auxprefix)
+
+    return
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaMaxECellAlgConfig.py b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaMaxECellAlgConfig.py
new file mode 100644
index 00000000000..bed7affe811
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaMaxECellAlgConfig.py
@@ -0,0 +1,61 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# $Id$
+#
+# @file egammaD3PDAnalysis/python/egamaMaxECellAlgConfig.py
+# @author Nikiforos K. Nikiforou <nikiforo@cern.ch> modified from egammaIsIsoConfig.py by scott snyder <snyder@bnl.gov>
+# @date Jun, 2012
+# @brief Configure egamaMaxECellAlg to fill aux data.
+#
+
+
+from D3PDMakerConfig.D3PDMakerFlags          import D3PDMakerFlags
+from D3PDMakerCoreComps.resolveSGKey         import resolveSGKey
+from AthenaCommon.AlgSequence                import AlgSequence
+import D3PDMakerCoreComps
+import egammaD3PDAnalysis
+
+
+def egammaMaxECellAlgConfig \
+    (seq = AlgSequence(D3PDMakerFlags.PreD3PDAlgSeqName()),
+    prefix = '',
+    sgkey = D3PDMakerFlags.ElectronSGKey(),
+    typeName = 'ElectronContainer',
+    allowMissing = False):
+    """Configure egammaMaxECellAlg for D3PD making.
+
+    SEQ is the Gaudi sequence to which the algorithm should be added.
+    Default is that given by PreD3PDAlgSeqName.
+
+    PREFIX is a prefix to add to the name of the algorithm scheduled.
+
+    SGKEY/TYPENAME is the StoreGate key of the input electron container
+    and the name of its type.
+
+    If ALLOWMISSING is true, don't fail if the SG key doesn't exist.
+    """
+
+    if (not D3PDMakerFlags.MakeEgammaUserData() or
+        D3PDMakerFlags.HaveEgammaUserData()):
+        return
+
+    DVGetter = D3PDMakerCoreComps.SGDataVectorGetterTool
+    resolved_sgkey = resolveSGKey (typeName, sgkey)
+    auxprefix = (D3PDMakerFlags.EgammaUserDataPrefix() + '_' +
+                 resolved_sgkey + '_')
+
+    algName = 'egammaMaxECellAlg' + resolved_sgkey
+    if not hasattr (seq, algName):
+        
+        myAlg = egammaD3PDAnalysis.egammaMaxECellAlg \
+                (algName,
+                Getter = DVGetter
+                    (prefix + 'egammaMaxECellAlgGetter',
+                    TypeName = typeName,
+                    SGKey = sgkey),
+                AllowMissing = allowMissing,
+                AuxPrefix = auxprefix,)
+
+        seq += myAlg
+
+    return
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaNbCellsGainAlgConfig.py b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaNbCellsGainAlgConfig.py
new file mode 100644
index 00000000000..6b49a2eb40f
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaNbCellsGainAlgConfig.py
@@ -0,0 +1,61 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# $Id: egammaNbCellsGainAlgConfig.py 
+#
+# @file egammaD3PDAnalysis/python/egamaNbCellsGainAlgConfig.py
+# @date Aug. 2013
+# @brief Configure egamaNbCellsGainAlg to fill UserData.
+#
+
+
+from D3PDMakerConfig.D3PDMakerFlags          import D3PDMakerFlags
+from D3PDMakerCoreComps.resolveSGKey         import resolveSGKey
+from AthenaCommon.AlgSequence                import AlgSequence
+import D3PDMakerCoreComps
+import egammaD3PDAnalysis
+
+
+
+def egammaNbCellsGainAlgConfig \
+    (seq = AlgSequence(D3PDMakerFlags.PreD3PDAlgSeqName()),
+    prefix = '',
+    sgkey = D3PDMakerFlags.ElectronSGKey(),
+    typeName = 'ElectronContainer',
+    allowMissing = False):
+    """Configure egammaNbCellsGainAlg for D3PD making.
+
+    SEQ is the Gaudi sequence to which the algorithm should be added.
+    Default is that given by PreD3PDAlgSeqName.
+
+    PREFIX is a prefix to add to the name of the algorithm scheduled.
+
+    SGKEY/TYPENAME is the StoreGate key of the input electron container
+    and the name of its type.
+
+    If ALLOWMISSING is true, don't fail if the SG key doesn't exist.
+    """
+
+    if (not D3PDMakerFlags.MakeEgammaUserData() or
+        D3PDMakerFlags.HaveEgammaUserData()):
+        return
+
+    DVGetter = D3PDMakerCoreComps.SGDataVectorGetterTool
+    resolved_sgkey = resolveSGKey (typeName, sgkey)
+    auxprefix = (D3PDMakerFlags.EgammaUserDataPrefix() + '_' +
+                 resolved_sgkey + '_')
+
+    algName = 'egammaNbCellsGainAlg' + resolved_sgkey
+    if not hasattr (seq, algName):
+        
+        myAlg = egammaD3PDAnalysis.egammaNbCellsGainAlg \
+                (algName,
+                Getter = DVGetter
+                    (prefix + 'egammaNbCellsGainAlgGetter',
+                    TypeName = typeName,
+                    SGKey = sgkey),
+                AllowMissing = allowMissing,
+                AuxPrefix = auxprefix,)
+
+        seq += myAlg
+
+    return
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaShowerDepthAlg.py b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaShowerDepthAlg.py
new file mode 100644
index 00000000000..42f161d2bd6
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaShowerDepthAlg.py
@@ -0,0 +1,33 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# $Id$
+#
+# @file egammaD3PDMakerAnalysis/python/egammaShowerDepthAlg.py
+# @author scott snyder <snyder@bnl.gov>
+# @date Aug, 2010
+# @brief Configure the shower depth algorithm.
+#
+
+
+from egammaD3PDAnalysis import egammaD3PDAnalysisConf
+from D3PDMakerConfig.D3PDMakerFlags import D3PDMakerFlags
+
+def egammaShowerDepthAlg (name, **kwin):
+    # Set up database access.
+    folder  = '/CALO/CaloSwClusterCorrections/calhits'
+    tag = D3PDMakerFlags.EgammaShowerDepthTag()
+    if not tag:
+        tag = '@GLOBAL'
+
+    # Create the algorithm.
+    kw = {'prefix' : 'ele55.',
+          'COOLFolder' : '' }
+    kw.update (kwin)
+    alg = egammaD3PDAnalysisConf.D3PD__egammaShowerDepthAlg (name, **kw)
+
+    from CaloClusterCorrection.common import config_from_cool
+    config_from_cool (alg, folder, tag)
+
+    return alg
+
+    
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaShowerDepthConfig.py b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaShowerDepthConfig.py
new file mode 100644
index 00000000000..d28fb244266
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaShowerDepthConfig.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# $Id$
+#
+# @file egammaD3PDAnalysis/python/egammaShowerDepthConfig.py
+# @author scott snyder <snyder@bnl.gov>
+# @date Nov, 2011
+# @brief Configure egammaShowerDepthAlg to fill UserData.
+#
+
+
+from D3PDMakerConfig.D3PDMakerFlags          import D3PDMakerFlags
+from D3PDMakerCoreComps.resolveSGKey         import resolveSGKey
+from AthenaCommon.AlgSequence                import AlgSequence
+import D3PDMakerCoreComps
+import egammaD3PDAnalysis
+
+
+def egammaShowerDepthConfig \
+        (seq = AlgSequence(D3PDMakerFlags.PreD3PDAlgSeqName()),
+         prefix = '',
+         sgkey = D3PDMakerFlags.ElectronSGKey(),
+         typeName = 'DataVector<xAOD::Electron_v1>',
+         allowMissing = False):
+    """Configure egammaShowerDepthAlg for D3PD making.
+
+    SEQ is the Gaudi sequence to which the algorithm should be added.
+    Default is that given by PreD3PDAlgSeqName.
+
+    PREFIX is a prefix to add to the name of the algorithm scheduled.
+
+    SGKEY/TYPENAME is the StoreGate key of the input electron container
+    and the name of its type.
+
+    If ALLOWMISSING is true, don't fail if the SG key doesn't exist.
+"""
+
+    if (not D3PDMakerFlags.MakeEgammaUserData() or
+        D3PDMakerFlags.HaveEgammaUserData()):
+        return
+
+    DVGetter = D3PDMakerCoreComps.SGDataVectorGetterTool
+    resolved_sgkey = resolveSGKey (typeName, sgkey)
+    auxprefix = (D3PDMakerFlags.EgammaUserDataPrefix() + '_' +
+                 resolved_sgkey + '_')
+
+    depthname = 'egammaShowerDepthAlg_' + resolved_sgkey
+    if not hasattr (seq, depthname):
+        seq += egammaD3PDAnalysis.egammaShowerDepthAlg \
+               (depthname,
+                Getter = DVGetter
+                  (prefix + 'egammaShowerDepthGetter',
+                   TypeName = typeName,
+                   SGKey = sgkey),
+                AllowMissing = allowMissing,
+                AuxPrefix = auxprefix
+                )
+
+    return
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaSumCellsGainAlgConfig.py b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaSumCellsGainAlgConfig.py
new file mode 100644
index 00000000000..5c69fa35708
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaSumCellsGainAlgConfig.py
@@ -0,0 +1,61 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# $Id: egammaSumCellsGainAlgConfig.py 604352 2014-07-01 04:52:11Z ssnyder $
+#
+# @file egammaD3PDAnalysis/python/egamaSumCellsGainAlgConfig.py
+# @author Mike Hance
+# @date Aug. 2013
+# @brief Configure egamaSumCellsGainAlgAlg to fill UserData.
+#
+
+
+from D3PDMakerConfig.D3PDMakerFlags          import D3PDMakerFlags
+from D3PDMakerCoreComps.resolveSGKey         import resolveSGKey
+from AthenaCommon.AlgSequence                import AlgSequence
+import D3PDMakerCoreComps
+import egammaD3PDAnalysis
+
+
+def egammaSumCellsGainAlgConfig \
+    (seq = AlgSequence(D3PDMakerFlags.PreD3PDAlgSeqName()),
+    prefix = '',
+    sgkey = D3PDMakerFlags.ElectronSGKey(),
+    typeName = 'ElectronContainer',
+    allowMissing = False):
+    """Configure egammaSumCellsGainAlg for D3PD making.
+
+    SEQ is the Gaudi sequence to which the algorithm should be added.
+    Default is that given by PreD3PDAlgSeqName.
+
+    PREFIX is a prefix to add to the name of the algorithm scheduled.
+
+    SGKEY/TYPENAME is the StoreGate key of the input electron container
+    and the name of its type.
+
+    If ALLOWMISSING is true, don't fail if the SG key doesn't exist.
+    """
+
+    if (not D3PDMakerFlags.MakeEgammaUserData() or
+        D3PDMakerFlags.HaveEgammaUserData()):
+        return
+
+    DVGetter = D3PDMakerCoreComps.SGDataVectorGetterTool
+    resolved_sgkey = resolveSGKey (typeName, sgkey)
+    auxprefix = (D3PDMakerFlags.EgammaUserDataPrefix() + '_' +
+                 resolved_sgkey + '_')
+
+    algName = 'egammaSumCellsGainAlg' + resolved_sgkey
+    if not hasattr (seq, algName):
+        
+        myAlg = egammaD3PDAnalysis.egammaSumCellsGainAlg \
+                (algName,
+                Getter = DVGetter
+                    (prefix + 'egammaSumCellsGainAlgGetter',
+                    TypeName = typeName,
+                    SGKey = sgkey),
+                AllowMissing = allowMissing,
+                AuxPrefix = auxprefix,)
+
+        seq += myAlg
+
+    return
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaTimeCorrConfig.py b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaTimeCorrConfig.py
new file mode 100644
index 00000000000..fa9d632c450
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaTimeCorrConfig.py
@@ -0,0 +1,69 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# $Id$
+#
+# @file egammaD3PDAnalysis/python/egammaTimeCorrConfig.py
+# @author Nikiforos K. Nikiforou <nikiforo@cern.ch> modified from egammaIsIsoConfig.py by scott snyder <snyder@bnl.gov>
+# @date Jun, 2012
+# @brief Configure egammaTimeCorrAlg to fill UserData.
+#
+
+
+from D3PDMakerConfig.D3PDMakerFlags          import D3PDMakerFlags
+from D3PDMakerCoreComps.resolveSGKey         import resolveSGKey
+from AthenaCommon.AlgSequence                import AlgSequence
+import D3PDMakerCoreComps
+import egammaD3PDAnalysis
+
+
+def egammaTimeCorrConfig \
+    (seq = AlgSequence(D3PDMakerFlags.PreD3PDAlgSeqName()),
+    prefix = '',
+    sgkey = D3PDMakerFlags.ElectronSGKey(),
+     typeName = 'DataVector<xAOD::Electron_v1>',
+    allowMissing = False):
+    """Configure egammaTimeCorrAlg for D3PD making.
+
+    SEQ is the Gaudi sequence to which the algorithm should be added.
+    Default is that given by PreD3PDAlgSeqName.
+
+    PREFIX is a prefix to add to the name of the algorithm scheduled.
+
+    SGKEY/TYPENAME is the StoreGate key of the input electron container
+    and the name of its type.
+
+    If ALLOWMISSING is true, don't fail if the SG key doesn't exist.
+    """
+
+    if (not D3PDMakerFlags.MakeEgammaUserData() or
+        D3PDMakerFlags.HaveEgammaUserData()):
+        return
+
+    DVGetter = D3PDMakerCoreComps.SGDataVectorGetterTool
+    resolved_sgkey = resolveSGKey (typeName, sgkey)
+    auxprefix = (D3PDMakerFlags.EgammaUserDataPrefix() + '_' +
+                 resolved_sgkey + '_')
+
+    algName = 'egammaTimeCorrAlg' + resolved_sgkey
+    if not hasattr (seq, algName):
+        
+        from IOVDbSvc.CondDB import conddb
+        
+        conddb.addFolder("LAR_OFL","/LAR/TimeCorrectionOfl/NonRunCon <tag>LARTimeCorrectionOflNonRunCon-00</tag>",force=True)
+        conddb.addFolder("LAR_OFL","/LAR/TimeCorrectionOfl/RunCon <tag>LARTimeCorrectionOflRunCon-00</tag>",force=True)
+       
+        from CaloClusterCorrection.CaloClusterTimeTool import GetCaloClusterTimeTool 
+        myCaloClusterTimeTool=GetCaloClusterTimeTool("caloClusterTimeTool", "/LAR/TimeCorrectionOfl/NonRunCon","/LAR/TimeCorrectionOfl/RunCon")
+    
+        seq += egammaD3PDAnalysis.egammaTimeCorrAlg \
+                (algName,
+                Getter = DVGetter
+                    (prefix + 'egammaTimeCorrGetter',
+                    TypeName = typeName,
+                    SGKey = sgkey),
+                AllowMissing = allowMissing,
+                AuxPrefix = auxprefix,
+                CaloClusterTimeTool = myCaloClusterTimeTool,
+                                    )
+
+    return
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaTopoIsoConfig.py b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaTopoIsoConfig.py
new file mode 100644
index 00000000000..4c9be582d50
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaTopoIsoConfig.py
@@ -0,0 +1,81 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# $Id$
+#
+# @file egammaD3PDAnalysis/python/egammaTopoIsoConfig.py
+# @author scott snyder <snyder@bnl.gov>
+# @date Nov, 2011
+# @brief Configure egammaTopoIsoAlg to fill UserData.
+#
+
+
+from D3PDMakerConfig.D3PDMakerFlags          import D3PDMakerFlags
+from D3PDMakerCoreComps.resolveSGKey         import resolveSGKey
+from AthenaCommon.AlgSequence                import AlgSequence
+from egammaCaloTools.egammaTopoIsoToolBase   import egammaTopoIsoToolBase
+import D3PDMakerCoreComps
+import egammaD3PDAnalysis
+
+
+def egammaTopoIsoConfig \
+        (seq = AlgSequence(D3PDMakerFlags.PreD3PDAlgSeqName()),
+         prefix = '',
+         sgkey = D3PDMakerFlags.ElectronSGKey(),
+         typeName = 'ElectronContainer',
+         allowMissing = False,
+         UsePositiveClusters = False,
+         UseEMScale = True):
+    """Configure egammaTopoIsoAlg for D3PD making.
+
+    SEQ is the Gaudi sequence to which the algorithm should be added.
+    Default is that given by PreD3PDAlgSeqName.
+
+    PREFIX is a prefix to add to the name of the algorithm scheduled.
+
+    SGKEY/TYPENAME is the StoreGate key of the input electron container
+    and the name of its type.
+
+    If ALLOWMISSING is true, don't fail if the SG key doesn't exist.
+"""
+
+    if (not D3PDMakerFlags.MakeEgammaUserData() or
+        D3PDMakerFlags.HaveEgammaUserData()):
+        return
+
+    DVGetter = D3PDMakerCoreComps.SGDataVectorGetterTool
+    resolved_sgkey = resolveSGKey (typeName, sgkey)
+    auxprefix = (D3PDMakerFlags.EgammaUserDataPrefix() + '_' +
+                 resolved_sgkey + '_')
+
+    if not UseEMScale:
+        egammaTopoIsoToolName = "egammaCalTopoIsoToolBase" 
+        egammaTopoIsoTool = egammaTopoIsoToolBase(egammaTopoIsoToolName) 
+        egammaTopoIsoTool.UseEMScale = False
+    else:
+        egammaTopoIsoToolName = "egammaEMTopoIsoToolBase"
+        egammaTopoIsoTool = egammaTopoIsoToolBase(egammaTopoIsoToolName)
+        egammaTopoIsoTool.UseEMScale = True
+        
+    from AthenaCommon.AppMgr import ToolSvc
+    if egammaTopoIsoTool not in ToolSvc:
+        ToolSvc += egammaTopoIsoTool
+
+    etianame = 'egammaTopoIsoAlg_' + resolved_sgkey
+    if not hasattr (seq, etianame):
+        seq += egammaD3PDAnalysis.egammaTopoIsoAlg \
+               (etianame,
+                EgammaGetter = DVGetter
+                  (prefix +'egammaTopoIsoAlgEgammaGetter',
+                   TypeName = typeName,
+                   SGKey = sgkey),
+                ClusterGetter = DVGetter
+                  (prefix + 'egammaTopoIsoAlgClusterGetter',
+                   TypeName = 'DataVector<xAOD::CaloCluster_v1>',
+                   SGKey = D3PDMakerFlags.ClusterSGKey()),
+                UseEMScale = UseEMScale,
+                PositiveEnergyClusters = UsePositiveClusters,
+                TopoIsoTool = egammaTopoIsoTool,
+                AllowMissing = allowMissing,
+                AuxPrefix = auxprefix)
+
+    return
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaTruthParticleConfig.py b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaTruthParticleConfig.py
new file mode 100644
index 00000000000..99b018158db
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/python/egammaTruthParticleConfig.py
@@ -0,0 +1,58 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# $Id$
+#
+# @file egammaD3PDAnalysis/python/egammaTruthParticleConfig.py
+# @author scott snyder <snyder@bnl.gov>
+# @date Mar, 2011
+# @brief Configure algorithms to build filtered TruthParticleContainer
+#        for egamma truth.
+#
+
+
+import egammaD3PDAnalysis
+import D3PDMakerCoreComps
+from D3PDMakerConfig.D3PDMakerFlags           import D3PDMakerFlags
+from McParticleAlgs.JobOptCfg                 import createMcAodBuilder
+from RecExConfig.RecFlags                     import rec
+from AthenaCommon.AlgSequence                 import AlgSequence
+from RecExConfig.ObjKeyStore                  import cfgKeyStore
+from AthenaCommon                             import CfgMgr
+
+
+def egammaTruthParticleConfig \
+        (seq = AlgSequence(D3PDMakerFlags.PreD3PDAlgSeqName()),
+         sgkey = 'egammaTruth',
+         prefix = '',
+         doPileup     = D3PDMakerFlags.TruthDoPileup(),
+         **kwargs):
+    
+    if not rec.doTruth():
+        return
+
+    # Is the container already in SG?
+    if cfgKeyStore.isInInput ('DataVector<xAOD::TruthParticle_v1>', sgkey):
+        return
+
+    algname = prefix + sgkey + 'Builder'
+    if not hasattr (seq, algname):
+        from AthenaCommon.AppMgr import ToolSvc
+        from TrackToCalo.ExtrapolateToCaloToolBase import \
+             ExtrapolateToCaloToolFactory
+        extrap = ExtrapolateToCaloToolFactory (depth='showerdefault',
+                                               straightLine=False)
+        ToolSvc += extrap
+
+        seq += egammaD3PDAnalysis.egammaTruthAlg (
+            algname,
+            InputKey = D3PDMakerFlags.TruthSGKey(),
+            OutputKey = sgkey,
+            ExtrapolTrackToCaloTool = extrap,
+            AuxPrefix = D3PDMakerFlags.EgammaUserDataPrefix())
+            
+        cfgKeyStore.addTransient ('DataVector<xAOD::TruthParticle_v1>', sgkey)
+
+    return
+
+    
+    
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/ElectronRedoOQAlg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/ElectronRedoOQAlg.cxx
new file mode 100644
index 00000000000..339f4dfce97
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/ElectronRedoOQAlg.cxx
@@ -0,0 +1,32 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/ElectronRedoOQAlg.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Dec, 2010
+ * @brief Recalculate OQ flags for Electron objects.
+ */
+
+
+#include "ElectronRedoOQAlg.h"
+
+
+namespace D3PD {
+
+
+/**
+ * @brief Standard Gaudi algorithm constructor.
+ * @param name The algorithm name.
+ * @param svcloc The service locator.
+ */
+ElectronRedoOQAlg::ElectronRedoOQAlg (const std::string& name,
+                                      ISvcLocator* svcloc)
+  : egammaRedoOQAlg<xAOD::ElectronContainer, xAOD::ElectronAuxContainer> (name, svcloc)
+{
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/ElectronRedoOQAlg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/ElectronRedoOQAlg.h
new file mode 100644
index 00000000000..72a8fb23208
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/ElectronRedoOQAlg.h
@@ -0,0 +1,48 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/ElectronRedoOQAlg.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Dec, 2010
+ * @brief Recalculate OQ flags for Electron objects.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_ELECTRONREDOOQALG_H
+#define EGAMMAD3PDANALYSIS_ELECTRONREDOOQALG_H
+
+
+#include "egammaRedoOQAlg.h"
+#include "xAODEgamma/ElectronContainer.h"
+#include "xAODEgamma/ElectronAuxContainer.h"
+
+
+namespace D3PD {
+
+
+/**
+ * @brief Recalculate OQ flags for Electron objects.
+ */
+class ElectronRedoOQAlg
+  : public egammaRedoOQAlg<xAOD::ElectronContainer, xAOD::ElectronAuxContainer>
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  ElectronRedoOQAlg (const std::string& name,
+                     ISvcLocator* svcloc);
+};
+
+
+} // namespace D3PD
+
+
+#endif // not EGAMMAD3PDANALYSIS_ELECTRONREDOOQALG_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonRedoOQAlg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonRedoOQAlg.cxx
new file mode 100644
index 00000000000..36b29f627ee
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonRedoOQAlg.cxx
@@ -0,0 +1,32 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/PhotonRedoOQAlg.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Dec, 2010
+ * @brief Recalculate OQ flags for Photon objects.
+ */
+
+
+#include "PhotonRedoOQAlg.h"
+
+
+namespace D3PD {
+
+
+/**
+ * @brief Standard Gaudi algorithm constructor.
+ * @param name The algorithm name.
+ * @param svcloc The service locator.
+ */
+PhotonRedoOQAlg::PhotonRedoOQAlg (const std::string& name,
+                                      ISvcLocator* svcloc)
+  : egammaRedoOQAlg<xAOD::PhotonContainer, xAOD::PhotonAuxContainer> (name, svcloc)
+{
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonRedoOQAlg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonRedoOQAlg.h
new file mode 100644
index 00000000000..d057685197c
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonRedoOQAlg.h
@@ -0,0 +1,48 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/PhotonRedoOQAlg.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Dec, 2010
+ * @brief Recalculate OQ flags for Photon objects.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_PHOTONREDOOQALG_H
+#define EGAMMAD3PDANALYSIS_PHOTONREDOOQALG_H
+
+
+#include "egammaRedoOQAlg.h"
+#include "xAODEgamma/PhotonContainer.h"
+#include "xAODEgamma/PhotonAuxContainer.h"
+
+
+namespace D3PD {
+
+
+/**
+ * @brief Recalculate OQ flags for Photon objects.
+ */
+class PhotonRedoOQAlg
+  : public egammaRedoOQAlg<xAOD::PhotonContainer, xAOD::PhotonAuxContainer>
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  PhotonRedoOQAlg (const std::string& name,
+                   ISvcLocator* svcloc);
+};
+
+
+} // namespace D3PD
+
+
+#endif // not EGAMMAD3PDANALYSIS_PHOTONREDOOQALG_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthAlg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthAlg.cxx
new file mode 100644
index 00000000000..02248192048
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthAlg.cxx
@@ -0,0 +1,90 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/PhotonTruthAlg.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov, 2009
+ * @brief Analyze @c GenParticle's matching photons and make UD decorations.
+ */
+
+
+#include "PhotonTruthAlg.h"
+#include "PhotonTruthTool.h"
+#include "D3PDMakerInterfaces/ICollectionGetterTool.h"
+#include "xAODEgamma/Photon.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace D3PD {
+
+
+PhotonTruthAlg::PhotonTruthAlg (const std::string& name,
+                                ISvcLocator* svcloc)
+  : AthAlgorithm (name, svcloc),
+    m_truthTool ("D3PD::PhotonTruthTool", this),
+    m_photonGetter (this)
+{
+  declareProperty ("AuxPrefix", m_auxPrefix,
+                   "Prefix to add to aux data items.");
+  declareProperty ("TruthTool", m_truthTool,
+                   "Photon truth analysis tool instance.");
+  declareProperty ("PhotonGetter", m_photonGetter,
+                   "Getter instance for the input photon objects.");
+  declareProperty ("AllowMissing", m_allowMissing = false,
+                   "If true, don't complain if input objects are missing.");
+}
+
+
+/**
+ * @brief Standard Gaudi @c initialize method.
+ */
+StatusCode PhotonTruthAlg::initialize()
+{
+  CHECK( AthAlgorithm::initialize() );
+  CHECK( m_truthTool.retrieve() );
+  CHECK( m_photonGetter.retrieve() );
+  CHECK( m_photonGetter->configureD3PD<xAOD::Photon>() );
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Standard Gaudi @c execute method.
+ */
+StatusCode PhotonTruthAlg::execute()
+{
+#define DECOR(TYPE,N) xAOD::Photon::Decorator<TYPE> N (m_auxPrefix + #N)
+  DECOR(bool,  truth_isConv);
+  DECOR(float, truth_Rconv);
+  DECOR(float, truth_zconv);
+  DECOR(bool,  truth_isPhotonFromHardProc);
+  DECOR(bool,  truth_isFromHardProc);
+  DECOR(bool,  truth_isBrem);
+#undef DECOR
+
+  CHECK( m_photonGetter->reset (m_allowMissing) );
+  while (const xAOD::Photon* g =
+         m_photonGetter->next<xAOD::Photon>())
+  {
+    const xAOD::TruthParticle* p = m_truthTool->toTruthParticle (*g);
+
+    truth_isConv(*g) = m_truthTool->getMCConv (p,
+                                               truth_Rconv(*g),
+                                               truth_zconv(*g));
+
+    truth_isPhotonFromHardProc(*g) = m_truthTool->isPromptPhotonMC(p);
+    truth_isFromHardProc(*g) = m_truthTool->isPromptParticleMC(p);
+
+    truth_isBrem(*g)  = !truth_isPhotonFromHardProc(*g) && m_truthTool->isQuarkBremMC(p) ;
+
+    m_photonGetter->releaseElement (g);
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthAlg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthAlg.h
new file mode 100644
index 00000000000..34974356758
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthAlg.h
@@ -0,0 +1,73 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/PhotonTruthAlg.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov, 2009
+ * @brief Analyze @c GenParticle's matching photons and make UD decorations.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_PHOTONTRUTHALG_H
+#define EGAMMAD3PDANALYSIS_PHOTONTRUTHALG_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+
+
+namespace D3PD {
+
+
+class PhotonTruthTool;
+class ICollectionGetterTool;
+
+
+/**
+ * @brief Analyze @a GenParticle's matching photons and made UD decorations.
+ */
+class PhotonTruthAlg
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  PhotonTruthAlg (const std::string& name,
+                  ISvcLocator* svcloc);
+
+
+  /// Standard Gaudi @c initialize method.
+  virtual StatusCode initialize();
+
+
+  /// Standard Gaudi @c execute method.
+  virtual StatusCode execute();
+
+
+private:
+  /// Property: Prefix to add to aux data items.
+  std::string m_auxPrefix;
+
+  /// Property: Truth analysis tool.
+  ToolHandle<PhotonTruthTool> m_truthTool;
+
+  /// Property: Getter for input photon objects.
+  ToolHandle<ICollectionGetterTool> m_photonGetter;
+
+  /// Property: If true, don't complain if input objects are missing.
+  bool m_allowMissing;
+};
+
+
+} // namespace D3PD
+
+
+#endif // EGAMMAD3PDANALYSIS_PHOTONTRUTHALG_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthTool.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthTool.cxx
new file mode 100644
index 00000000000..d0b8d7b124f
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthTool.cxx
@@ -0,0 +1,314 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/PhotonTruthTool.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov, 2009
+ * @brief Helpers to categorize photon TruthParticle's.
+ */
+
+
+#include "PhotonTruthTool.h"
+#include "xAODEgamma/Photon.h"
+#include "AthenaKernel/errorcheck.h"
+#include <vector>
+#include <math.h>
+
+
+using HepGeom::Point3D;
+
+
+namespace D3PD {
+
+
+/**
+ * @brief Standard Gaudi tool constructor.
+ * @param type The name of the tool type.
+ * @param name The tool name.
+ * @param parent The tool's Gaudi parent.
+ */
+PhotonTruthTool::PhotonTruthTool (const std::string& type,
+                                  const std::string& name,
+                                  const  IInterface* parent)
+  : AthAlgTool (type, name, parent),
+    m_classifier ("MCTruthClassifier")
+{
+  declareProperty ("Classifier", m_classifier, "Classifier tool instance.");
+  declareProperty ("ZTruthConv",     m_zTruthConv = 50e3);
+  declareProperty ("RTruthConv",     m_rTruthConv = 800);
+  declareProperty ("UseG4Particles", m_useG4Particles = false);
+}
+
+
+/**
+ * @brief Standard Gaudi @c initialize method.
+ */
+StatusCode PhotonTruthTool::initialize()
+{
+  CHECK( AthAlgTool::initialize() );
+  CHECK( m_classifier.retrieve() );
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Standard Gaudi @c queryInterface method.
+ */
+StatusCode
+PhotonTruthTool::queryInterface( const InterfaceID& riid, void** ppvIf )
+{
+  if ( riid == PhotonTruthTool::interfaceID() )  {
+    *ppvIf = static_cast<PhotonTruthTool*> (this);
+    addRef();
+    return StatusCode::SUCCESS;
+  }
+
+  return AthAlgTool::queryInterface( riid, ppvIf );
+}
+
+
+/**
+ * @brief Go from a photon to a matching @c TruthParticle.
+ * @param g The input photon.
+ * @return The matching @c TruthParticle, or null.
+ */
+const xAOD::TruthParticle*
+PhotonTruthTool::toTruthParticle (const xAOD::Photon& g) const
+{
+  m_classifier->particleTruthClassifier (&g);
+  return m_classifier->getGenPart();
+}
+
+
+/**
+ * @brief Check a truth particle for a conversion.
+ * @param truePart The  particle to check.
+ * @param[out] RconvMC Radius of the conversion.
+ * @param[out] ZconvMC Z of the conversion.
+ * @return True if this is a conversion; otherwise false.
+ */
+bool
+PhotonTruthTool::getMCConv (const xAOD::TruthParticle* truePart,
+                            float& RconvMC,
+                            float& ZconvMC) const
+{
+  RconvMC = +9.999e+10 ;
+  ZconvMC = +9.999e+10 ;
+  if (!truePart) return false;
+
+  const xAOD::TruthVertex* v = truePart->decayVtx();
+  if (!v || v->nOutgoingParticles() < 2)
+    return false;
+
+  int pdgId  = truePart->pdgId();
+
+  RconvMC = v->perp();
+  ZconvMC = v->z();
+
+  bool OKint = ( RconvMC < m_rTruthConv ) && ( fabs(ZconvMC) < m_zTruthConv );
+
+  if ( pdgId == 22 ) { // photon
+    if ( v->nOutgoingParticles() == 2 ) {
+      int pdgChild[2];
+      for ( unsigned u=0; u<2 ; ++u)
+        pdgChild[u] = v->outgoingParticle(u)->pdgId();
+      if ( pdgChild[0]+pdgChild[1]==0 && pdgChild[0]*pdgChild[1]==-121 ) {
+        // gamma -> e+e-
+	return OKint ;
+      }
+    }
+  }
+  else if ( fabs(pdgId) == 11 ) { // e+/e-
+    v = truePart->prodVtx();
+    if ( v->nIncomingParticles()==1 && v->nOutgoingParticles()==2 ) {
+      int pdgBrother[2] ;
+      for ( unsigned u=0 ; u<2 ; ++u )
+        pdgBrother[u] = v->outgoingParticle(u)->pdgId();
+      if ( pdgBrother[0]+pdgBrother[1]==(22+pdgId) &&
+           pdgBrother[0]*pdgBrother[1]==(22*pdgId) )
+      {
+        // e(+/-) -> e(+/-)gamma
+	return OKint ;
+      }
+    }
+  }
+  return false ;
+}
+
+
+/**
+ * @brief Test for a prompt photon.
+ */
+bool PhotonTruthTool::isPromptPhotonMC
+  (const xAOD::TruthParticle* truePart)  const
+{
+  return ( isFinalStatePhotonMC(truePart) && isPromptParticleMC(truePart) ) ;
+}
+
+
+/**
+ * @brief Test for a prompt particle.
+ */
+bool PhotonTruthTool::isPromptParticleMC
+  (const xAOD::TruthParticle* truePart)  const
+{
+  if ( truePart == 0 ) return false ;
+  const std::vector<const xAOD::TruthParticle*> mothers =
+    getMothers(truePart);
+  unsigned nmothers = mothers.size() ;
+  if ( nmothers == 0 ) {
+    // particles with NO mother are NEVER classified as PROMPT:
+    return false ;
+  }
+  else if ( nmothers == 1 ) {
+    // particles with ONE mother are classified as PROMPT if coming
+    // from non-QCD-boson decay:
+    // (including exotics like heavy bosons, MSSM Higgs, graviton)
+    int aPdgMother = abs(mothers[0]->pdgId());
+    return  (( aPdgMother>=23 && aPdgMother<=39 ) || aPdgMother==5000039 ) ;
+  }
+  else {
+    // particles with more mothers are classified as PROMPT
+    // if they come from at least 1 parton:
+    // (is this sensible?)
+    int nParentPartons = 0 ;
+    for ( unsigned u=0 ; u<nmothers ; ++u ) {
+      int pdgMother = mothers[u]->pdgId() ;
+      if ( pdgMother==21 || ( fabs(pdgMother)<7 && pdgMother!=0 ) )
+        ++nParentPartons ;
+    }
+    return ( nParentPartons >= 1 ) ;
+  }
+}
+
+
+/**
+ * @brief Test for a brem.
+ */
+bool PhotonTruthTool::isQuarkBremMC
+  (const xAOD::TruthParticle* truePart)  const
+{
+  if ( ! isFinalStatePhotonMC(truePart) ) return false ;
+  const std::vector<const xAOD::TruthParticle*> mothers =
+    getMothers(truePart) ;
+  if ( mothers.size() != 1 )  return false ;
+  int pdgMother = mothers[0]->pdgId() ;
+  return ( pdgMother==21 || ( fabs(pdgMother)<7 && pdgMother!=0 ) ) ;
+}
+
+
+/**
+ * @brief Test for a final-state photon.
+ */
+bool PhotonTruthTool::isFinalStatePhotonMC
+  (const xAOD::TruthParticle* truePart) const
+{
+  /*
+  if ( truePart == 0 ) return false ;
+  if ( truePart->genParticle()->barcode() >= 200000 ) return false ;
+  if ( truePart->genParticle()->status() != 1 ) return false ;
+  if ( truePart->pdgId() != 22 ) return false ;
+  return true ;
+  */
+  return ( isFinalState(truePart) && truePart->pdgId()==22 ) ;
+}
+
+
+/**
+ * @brief Test for a final-state particle.
+ */
+bool
+PhotonTruthTool::isFinalState(const xAOD::TruthParticle* truePart) const
+{
+  /*
+  if ( truePart->genParticle() == 0 ) return false ;
+  int status = truePart->genParticle()->status() ;
+  return ( status == 1 ) ;
+  */
+  if ( truePart==0 ) return false ;
+  // decayed in generator?
+  if ( truePart->status()!=1 ) return false ; 
+  // 
+  if ( ! m_useG4Particles ) {
+    return ( truePart->barcode() < 200000 ) ;
+  }
+  else {
+    // if it is a photon, keep it regardless of its Geant interaction
+    if ( truePart->pdgId()==22 ) return true ; 
+    // reject Geant electron from conversion
+    if ( abs(truePart->pdgId())==11 && truePart->barcode()>=200000 ) {
+      const xAOD::TruthParticle* mother = getMother(truePart) ;
+      if ( mother!=0 && mother->pdgId()==22 )  return false ;
+    }
+
+    // reject particles interacted in detector
+    const xAOD::TruthVertex* v = truePart->decayVtx();
+    if (!v) return false;// should never happen, but just in case...
+    if ( v->nOutgoingParticles()>0 ) { 
+      if ( v->perp()<m_rTruthConv 
+	   && fabs(v->z())<m_zTruthConv )  return false ;
+    }
+  } // end if ( ! m_useG4Particles ) 
+  return true ;
+}
+
+
+/**
+ * @brief Get the mother vertex for @a p.
+ */
+const xAOD::TruthVertex*
+PhotonTruthTool::getMotherVert(const xAOD::TruthParticle* p) const
+{
+  const xAOD::TruthVertex* v = p->prodVtx();
+
+  // if mother is a duplicate, try climbing up the tree by one step...
+  while (v && v->nIncomingParticles() == 1 &&
+         v->incomingParticle(0)->pdgId() == p->pdgId())
+  {
+    p = v->incomingParticle(0);
+    v = p->prodVtx();
+  }
+
+  return v;
+}
+
+
+/**
+ * @brief Get the (first) mother particle of @a p.
+ */
+const xAOD::TruthParticle*
+PhotonTruthTool::getMother(const xAOD::TruthParticle* p) const
+{
+  const xAOD::TruthVertex* v = getMotherVert (p);
+
+  if (!v || v->nIncomingParticles() == 0)
+    return 0;
+
+  return v->incomingParticle(0);
+}
+
+
+/**
+ * @brief Return list of mother particles of @a p.
+ */
+std::vector<const xAOD::TruthParticle*>
+PhotonTruthTool::getMothers(const xAOD::TruthParticle* p) const
+{
+  std::vector<const xAOD::TruthParticle*> out;
+  const xAOD::TruthVertex* v = getMotherVert (p);
+
+  if (v) {
+    int n = v->nIncomingParticles();
+    out.reserve (n);
+    for (int i = 0; i < n; i++)
+      out.push_back (v->incomingParticle(i));
+  }
+
+  return out;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthTool.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthTool.h
new file mode 100644
index 00000000000..94cfeb66d40
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/PhotonTruthTool.h
@@ -0,0 +1,139 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/PhotonTruthTool.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov, 2009
+ * @brief Helpers to categorize photon TruthParticle's.
+ *
+ * Adapted from code in PhotonAnalysisUtils.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_PHOTONTRUTHTOOL_H
+#define EGAMMAD3PDANALYSIS_PHOTONTRUTHTOOL_H
+
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "MCTruthClassifier/IMCTruthClassifier.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "xAODEgamma/Photon.h"
+#include "xAODTruth/TruthParticle.h"
+#include "xAODTruth/TruthVertex.h"
+#include <string>
+
+
+namespace D3PD {
+
+
+/// Interface definition.
+static const InterfaceID IID_PhotonTruthTool ("D3PD::PhotonTruthTool", 1, 0);
+
+
+class PhotonTruthTool
+  : public AthAlgTool
+{
+public:
+  /// Gaudi interface definition.
+  static const InterfaceID& interfaceID() { return IID_PhotonTruthTool; }
+
+  /**
+   * @brief Standard Gaudi tool constructor.
+   * @param type The name of the tool type.
+   * @param name The tool name.
+   * @param parent The tool's Gaudi parent.
+   */
+  PhotonTruthTool (const std::string& type,
+                   const std::string& name,
+                   const IInterface* parent);
+
+
+  /// Standard Gaudi @c initialize method.
+  virtual StatusCode initialize();
+
+
+  /// Standard Gaudi @c queryInterface method.
+  virtual StatusCode queryInterface( const InterfaceID& riid,
+                                     void** ppvIf );
+
+
+  /**
+   * @brief Go from a photon to a matching @c TruthParticle.
+   * @param g The input photon.
+   * @return The matching @c TruthParticle, or null.
+   */
+  const xAOD::TruthParticle*
+  toTruthParticle (const xAOD::Photon& g) const;
+
+
+  /**
+   * @brief Check a truth particle for a conversion.
+   * @param truePart The  particle to check.
+   * @param[out] RconvMC Radius of the conversion.
+   * @param[out] ZconvMC Z of the conversion.
+   * @return True if this is a conversion; otherwise false.
+   */
+  bool getMCConv (const xAOD::TruthParticle* truePart,
+                  float& RconvMC,
+                  float& ZconvMC) const;
+
+
+  /// Test for a prompt photon.
+  bool isPromptPhotonMC (const xAOD::TruthParticle* truePart)  const;
+
+
+  /// Test for a prompt particle.
+  bool isPromptParticleMC (const xAOD::TruthParticle* truePart)  const;
+
+
+  /// Test for a brem.
+  bool isQuarkBremMC (const xAOD::TruthParticle* truePart)  const;
+
+
+private:
+  /// Test for a final-state photon.
+  bool isFinalStatePhotonMC (const xAOD::TruthParticle* truePart) const;
+
+  
+  /// Test for a final-state particle.
+  bool isFinalState(const xAOD::TruthParticle* truePart)  const;
+
+
+  /// Get the (first) mother particle of @a p.
+  const xAOD::TruthParticle*
+  getMother(const xAOD::TruthParticle* p) const;
+
+
+  /// Get the mother vertex for @a p.
+  const xAOD::TruthVertex*
+  getMotherVert(const xAOD::TruthParticle* p) const;
+
+
+  /// Return list of mother particles of @a p.
+  std::vector<const xAOD::TruthParticle*>
+  getMothers(const xAOD::TruthParticle* p) const;
+
+
+  /// Property: classifier tool.
+  ToolHandle<IMCTruthClassifier> m_classifier;
+
+  /// Property: Conversion vertex z cut.
+  float m_zTruthConv;
+
+  /// Property: Conversion vertex r cut.
+  float m_rTruthConv;
+
+  /// Property.
+  bool m_useG4Particles;
+};
+
+
+} // namespace D3PD
+
+
+#endif // EGAMMAD3PDANALYSIS_PHOTONTRUTHTOOL_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSelectionAlg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSelectionAlg.cxx
new file mode 100644
index 00000000000..b62aec57a3d
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSelectionAlg.cxx
@@ -0,0 +1,88 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/TileGapSelectionAlg.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Mar, 2011
+ * @brief Select tile gap cells from a cell container into a new container.
+ */
+
+
+#include "TileGapSelectionAlg.h"
+#include "D3PDMakerInterfaces/IObjGetterTool.h"
+#include "CaloEvent/CaloCellContainer.h"
+#include "CaloEvent/CaloSamplingHelper.h"
+#include "CaloGeoHelpers/CaloSampling.h"
+#include "AthContainers/OwnershipPolicy.h"
+#include "AthContainers/ConstDataVector.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace D3PD {
+
+
+/**
+ * @brief Standard Gaudi algorithm constructor.
+ * @param name The algorithm name.
+ * @param svcloc The service locator.
+ */
+TileGapSelectionAlg::TileGapSelectionAlg (const std::string& name,
+                                          ISvcLocator* svcloc)
+  : AthAlgorithm (name, svcloc),
+    m_getter (this)
+{
+  declareProperty ("Getter", m_getter,
+                   "Getter instance for the input calorimeter cells.");
+  declareProperty ("OutputCellContainerName", m_outputCellContainerName,
+                   "StoreGate key for the output cell container.");
+}
+
+
+/**
+ * @brief Standard Gaudi @c initialize method.
+ */
+StatusCode TileGapSelectionAlg::initialize()
+{
+  CHECK( AthAlgorithm::initialize() );
+  CHECK( m_getter.retrieve() );
+  CHECK( m_getter->configureD3PD<CaloCellContainer>() );
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Standard Gaudi @c execute method.
+ */
+StatusCode TileGapSelectionAlg::execute()
+{
+  // Get the input container.
+  const CaloCellContainer* ccc = m_getter->get<CaloCellContainer>();
+  if (!ccc) {
+    REPORT_MESSAGE(MSG::WARNING) << "Can't find input CaloCellContainer.";
+    return StatusCode::SUCCESS;
+  }
+
+  // Make the output container.
+  ConstDataVector<CaloCellContainer>* gapcells =
+    new ConstDataVector<CaloCellContainer> (SG::VIEW_ELEMENTS);
+  CHECK( evtStore()->record (gapcells, m_outputCellContainerName) );
+
+  CaloCellContainer::const_iterator f_cell =
+    ccc->beginConstCalo(CaloCell_ID::TILE);
+  CaloCellContainer::const_iterator l_cell =
+    ccc->endConstCalo(CaloCell_ID::TILE);
+  for ( ; f_cell!=l_cell; ++f_cell)
+  {
+    const CaloCell* cell = *f_cell; 
+    if (CaloSampling::TileGap3 ==  CaloSamplingHelper::getSampling( *cell ))
+      gapcells->push_back (cell);
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSelectionAlg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSelectionAlg.h
new file mode 100644
index 00000000000..6d25e65bf30
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSelectionAlg.h
@@ -0,0 +1,67 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/TileGapSelectionAlg.h>
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Mar, 2011
+ * @brief Select tile gap cells from a cell container into a new container.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_TILEGAPSELECTIONALG_H
+#define EGAMMAD3PDANALYSIS_TILEGAPSELECTIONALG_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+#include <string>
+
+
+namespace D3PD {
+
+
+class IObjGetterTool;
+
+
+/**
+ * @brief Select tile gap cells from a cell container into a new container.
+ */
+class TileGapSelectionAlg
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  TileGapSelectionAlg (const std::string& name,
+                       ISvcLocator* svcloc);
+
+
+  /// Standard Gaudi @c initialize method.
+  virtual StatusCode initialize();
+
+
+  /// Standard Gaudi @c execute method.
+  virtual StatusCode execute();
+
+
+private:
+  /// Property: Getter for the input collection.
+  ToolHandle<IObjGetterTool> m_getter;
+
+  /// Property: SG key for output cell container.
+  std::string m_outputCellContainerName;
+};
+
+
+} // namespace D3PD
+
+
+#endif // not EGAMMAD3PDANALYSIS_TILEGAPSELECTIONALG_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSumAlg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSumAlg.cxx
new file mode 100644
index 00000000000..660aa094818
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSumAlg.cxx
@@ -0,0 +1,108 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/TileGapSumAlg.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Mar, 2011
+ * @brief Sum tile gap cells in a rectangular region around clusters.
+ */
+
+
+#include "TileGapSumAlg.h"
+#include "D3PDMakerInterfaces/ICollectionGetterTool.h"
+#include "xAODCaloEvent/CaloCluster.h"
+#include "CaloEvent/CaloCell.h"
+#include "CaloGeoHelpers/CaloPhiRange.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace D3PD {
+
+
+/**
+ * @brief Standard Gaudi algorithm constructor.
+ * @param name The algorithm name.
+ * @param svcloc The service locator.
+ */
+TileGapSumAlg::TileGapSumAlg (const std::string& name,
+                              ISvcLocator* svcloc)
+  : AthAlgorithm (name, svcloc),
+    m_clusterGetter (this),
+    m_cellGetter (this)
+{
+  declareProperty ("AuxPrefix", m_auxPrefix,
+                   "Prefix to add to aux data items.");
+
+  declareProperty ("AllowMissing", m_allowMissing = false,
+                   "If true, don't complain if input objects are missing.");
+
+  declareProperty ("ClusterGetter", m_clusterGetter,
+                   "Getter instance for the input cluster objects.");
+
+  declareProperty ("CellGetter", m_cellGetter,
+                   "Getter instance for the input cell objects.  "
+                   "Should have already been selected for only tile gap cells.");
+}
+
+
+/**
+ * @brief Standard Gaudi @c initialize method.
+ */
+StatusCode TileGapSumAlg::initialize()
+{
+  CHECK( AthAlgorithm::initialize() );
+  CHECK( m_clusterGetter.retrieve() );
+  CHECK( m_clusterGetter->configureD3PD<xAOD::CaloCluster>() );
+  CHECK( m_cellGetter.retrieve() );
+  CHECK( m_cellGetter->configureD3PD<CaloCell>() );
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Standard Gaudi @c execute method.
+ */
+StatusCode TileGapSumAlg::execute()
+{
+  CHECK( m_clusterGetter->reset (m_allowMissing) );
+
+  xAOD::CaloCluster::Decorator<float> tileGapSum (m_auxPrefix + "tileGapSum");
+
+  while (const xAOD::CaloCluster* clust =
+         m_clusterGetter->next<xAOD::CaloCluster>())
+  {
+    static CaloPhiRange range;
+
+    // FIXME: Constants copied from gap correction code --- would be better
+    // not to hard code these!
+    double deta = 0.2;
+    double dphi = 2*M_PI/64;
+
+    double etacl = clust->eta();
+    double phicl = range.fix (clust->phi());
+
+    CHECK( m_cellGetter->reset (m_allowMissing) );
+    tileGapSum(*clust) = 0;
+    while (const CaloCell* cell = m_cellGetter->next<CaloCell>())
+    {
+      if (std::abs (etacl - cell->eta()) <= deta &&
+          std::abs (range.fix (phicl - cell->phi())) <= dphi)
+      {
+        tileGapSum(*clust) += cell->energy();
+      }
+      m_cellGetter->releaseElement (cell);
+    }
+
+    m_clusterGetter->releaseElement (clust);
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSumAlg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSumAlg.h
new file mode 100644
index 00000000000..9d30802ef20
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/TileGapSumAlg.h
@@ -0,0 +1,75 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/TileGapSumAlg.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Mar, 2011
+ * @brief Sum tile gap cells in a rectangular region around clusters.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_TILEGAPSUMALG_H
+#define EGAMMAD3PDANALYSIS_TILEGAPSUMALG_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+#include <string>
+
+
+namespace D3PD {
+
+
+class ICollectionGetterTool;
+
+
+/**
+ * @brief Sum tile gap cells in a rectangular region around clusters
+ *        and store as a decoration.
+ */
+class TileGapSumAlg
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  TileGapSumAlg (const std::string& name,
+                 ISvcLocator* svcloc);
+
+
+  /// Standard Gaudi @c initialize method.
+  virtual StatusCode initialize();
+
+
+  /// Standard Gaudi @c execute method.
+  virtual StatusCode execute();
+
+
+private:
+  /// Property: Prefix to add to aux data items.
+  std::string m_auxPrefix;
+
+  /// Property: If true, don't complain if input objects are missing.
+  bool m_allowMissing; 
+
+  /// Property: Getter for input cluster objects.
+  ToolHandle<ICollectionGetterTool> m_clusterGetter;
+
+  /// Property: Getter for input cell objects.
+  /// Should have already been selected for only tile gap cells.
+  ToolHandle<ICollectionGetterTool> m_cellGetter;
+};
+
+
+} // namespace D3PD
+
+
+#endif // not EGAMMAD3PDANALYSIS_TILEGAPSUMALG_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/clusterHasCells.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/clusterHasCells.cxx
new file mode 100644
index 00000000000..bab40ab692a
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/clusterHasCells.cxx
@@ -0,0 +1,30 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/clusterHasCells.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2012
+ * @brief Helper to test if a cluster has cells available.
+ */
+
+
+#include "clusterHasCells.h"
+
+
+namespace D3PD {
+
+
+bool clusterHasCells (const xAOD::CaloCluster* cl)
+{
+  if (!cl) return false;
+  if (!cl->getCellLinks()) return false;
+  if (!cl->getCellLinks()->getCellContainer()) return false;
+  if (!cl->size()) return false;
+  return true;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/clusterHasCells.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/clusterHasCells.h
new file mode 100644
index 00000000000..9a52a8e218d
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/clusterHasCells.h
@@ -0,0 +1,32 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/clusterHasCells.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2012
+ * @brief Helper to test if a cluster has cells available.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_CLUSTERHASCELLS_H
+#define EGAMMAD3PDANALYSIS_CLUSTERHASCELLS_H
+
+
+#include "xAODCaloEvent/CaloCluster.h"
+
+
+namespace D3PD {
+
+
+bool clusterHasCells (const xAOD::CaloCluster* cl);
+
+
+}
+
+
+#endif // not EGAMMAD3PDANALYSIS_CLUSTERHASCELLS_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/components/egammaD3PDAnalysis_entries.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/components/egammaD3PDAnalysis_entries.cxx
new file mode 100644
index 00000000000..d5c43960c66
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/components/egammaD3PDAnalysis_entries.cxx
@@ -0,0 +1,70 @@
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/components/egammaD3PDAnalysis_entries.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Aug, 2009
+ * @brief List Gaudi components.
+ */
+
+
+#include "../egammaDeltaEmax2Alg.h"
+#include "../egammaShowerDepthAlg.h"
+#include "../PhotonTruthAlg.h"
+#include "../egammaTopoIsoAlg.h"
+#include "../ElectronRedoOQAlg.h"
+#include "../PhotonRedoOQAlg.h"
+#include "../egammaCalcOQAlg.h"
+#include "../egammaTruthAlg.h"
+#include "../TileGapSelectionAlg.h"
+#include "../TileGapSumAlg.h"
+#include "../PhotonTruthTool.h"
+
+#include "../egammaMaxECellAlg.h"
+#include "../egammaSumCellsGainAlg.h" 
+#include "../egammaNbCellsGainAlg.h"
+#include "../egammaTimeCorrAlg.h"
+
+
+#include "GaudiKernel/DeclareFactoryEntries.h"
+
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY      (D3PD, egammaDeltaEmax2Alg)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY      (D3PD, egammaShowerDepthAlg)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY      (D3PD, PhotonTruthAlg)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY      (D3PD, egammaTopoIsoAlg)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY      (D3PD, ElectronRedoOQAlg)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY      (D3PD, PhotonRedoOQAlg)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY      (D3PD, egammaCalcOQAlg)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY      (D3PD, egammaTruthAlg)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY      (D3PD, TileGapSelectionAlg)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY      (D3PD, TileGapSumAlg)
+
+DECLARE_NAMESPACE_TOOL_FACTORY           (D3PD, PhotonTruthTool)
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY      (D3PD, egammaMaxECellAlg)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY      (D3PD, egammaSumCellsGainAlg)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY      (D3PD, egammaNbCellsGainAlg)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY      (D3PD, egammaTimeCorrAlg)
+
+
+
+DECLARE_FACTORY_ENTRIES(egammaD3PDAnalysis) {
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, egammaDeltaEmax2Alg)
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, egammaShowerDepthAlg)
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, PhotonTruthAlg)
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, egammaTopoIsoAlg)
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, ElectronRedoOQAlg)
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, PhotonRedoOQAlg)
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, egammaCalcOQAlg)
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, egammaTruthAlg)
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, TileGapSelectionAlg)
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, TileGapSumAlg)
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, ClusterCalculatorAlg)
+  DECLARE_NAMESPACE_TOOL      (D3PD, PhotonTruthTool)
+  
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, egammaMaxECellAlg )
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, egammaSumCellsGainAlg )
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, egammaNbCellsGainAlg )
+  DECLARE_NAMESPACE_ALGORITHM (D3PD, egammaTimeCorrAlg)
+  
+}
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/components/egammaD3PDAnalysis_load.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/components/egammaD3PDAnalysis_load.cxx
new file mode 100644
index 00000000000..e392cb8b7b3
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/components/egammaD3PDAnalysis_load.cxx
@@ -0,0 +1,13 @@
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/components/egammaD3PDAnalysis_load.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov, 2009
+ * @brief Gaudi boilerplate.
+ */
+
+
+#include "GaudiKernel/LoadFactoryEntries.h"
+
+LOAD_FACTORY_ENTRIES(egammaD3PDAnalysis)
+
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaCalcOQAlg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaCalcOQAlg.cxx
new file mode 100644
index 00000000000..784a6674cdc
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaCalcOQAlg.cxx
@@ -0,0 +1,111 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/egammaCalcOQAlg.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Dec, 2010
+ * @brief Calculate egamma OQ flags and store as UserData.
+ */
+
+
+#include "egammaCalcOQAlg.h"
+#include "clusterHasCells.h"
+#include "D3PDMakerInterfaces/ICollectionGetterTool.h"
+#include "egammaInterfaces/IegammaBaseTool.h"
+#include "xAODEgamma/Egamma.h"
+#include "xAODEgamma/Electron.h"
+#include "egammaEvent/egamma.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace {
+
+
+class EgammaTmp
+  : public xAOD::Egamma
+{
+public:
+  EgammaTmp() {}
+  virtual xAOD::Type::ObjectType type() const { return xAOD::Type::Electron; }
+  EgammaTmp& operator= (const xAOD::Egamma& other)
+  {
+    if (this != &other) {
+      xAOD::Egamma::operator= (other);
+    }
+    return *this;
+  }
+};
+
+
+} // anonymous namespace
+
+
+namespace D3PD {
+
+
+/**
+ * @brief Standard Gaudi algorithm constructor.
+ * @param name The algorithm name.
+ * @param svcloc The service locator.
+ */
+egammaCalcOQAlg::egammaCalcOQAlg (const std::string& name,
+                                  ISvcLocator* svcloc)
+  : UDAlgBase (name, svcloc),
+    m_getter (this),
+    m_egammaOQFlagsBuilder( "egammaOQFlagsBuilder" )
+{
+  declareProperty ("Getter", m_getter,
+                   "Getter instance for the input egamma objects.");
+  declareProperty ("AllowMissing", m_allowMissing = false,
+                   "If true, don't complain if input objects are missing.");
+
+  declareProperty ("egammaOQFlagsBuilder",
+                   m_egammaOQFlagsBuilder,
+                   "Tool for calculating the OQ flag");
+}
+
+
+/**
+ * @brief Standard Gaudi @c initialize method.
+ */
+StatusCode egammaCalcOQAlg::initialize()
+{
+  CHECK( UDAlgBase::initialize() );
+  CHECK( m_getter.retrieve() );
+  CHECK( m_getter->configureD3PD<xAOD::Egamma>() );
+  CHECK( m_egammaOQFlagsBuilder.retrieve() );
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Standard Gaudi @c execute method.
+ */
+StatusCode egammaCalcOQAlg::execute()
+{
+  CHECK (m_getter->reset (m_allowMissing) );
+  while (const xAOD::Egamma* eg = m_getter->next<xAOD::Egamma>()) {
+    unsigned int oq = 0;
+    // This only works if the cluster has cells available.
+    if (clusterHasCells (eg->caloCluster())) {
+      EgammaTmp neweg;
+      neweg.makePrivateStore();
+      neweg = *eg;
+      CHECK( m_egammaOQFlagsBuilder->execute (&neweg) );
+      static SG::AuxElement::Accessor<unsigned int> var_oq ("OQ");
+      oq = var_oq(neweg);
+    }
+
+    static SG::AuxElement::Decorator<unsigned int> var_oq ("OQ");
+    var_oq(*eg) = oq;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaCalcOQAlg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaCalcOQAlg.h
new file mode 100644
index 00000000000..71e30ea94e7
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaCalcOQAlg.h
@@ -0,0 +1,72 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/egammaCalcOQAlg.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Dec, 2010
+ * @brief Calculate egamma OQ flags and store as UserData.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_EGAMMACALCOQALG_H
+#define EGAMMAD3PDANALYSIS_EGAMMACALCOQALG_H
+
+
+#include "D3PDMakerUtils/UDAlgBase.h"
+#include "GaudiKernel/ToolHandle.h"
+
+
+class IegammaBaseTool;
+
+
+namespace D3PD {
+
+
+class ICollectionGetterTool;
+
+
+/**
+ * @brief Calculate egamma OQ flags and store as UserData.
+ */
+class egammaCalcOQAlg
+  : public UDAlgBase
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  egammaCalcOQAlg (const std::string& name,
+                   ISvcLocator* svcloc);
+
+
+  /// Standard Gaudi @c initialize method.
+  virtual StatusCode initialize();
+
+
+  /// Standard Gaudi @c execute method.
+  virtual StatusCode execute();
+
+
+private:
+  /// Property: Getter for input egamma objects.
+  ToolHandle<ICollectionGetterTool> m_getter;
+
+  /// Property: If true, don't complain if input objects are missing.
+  bool m_allowMissing;
+
+  /// Property: Tool to recalculate OQ flags.
+  ToolHandle<IegammaBaseTool> m_egammaOQFlagsBuilder;
+};
+
+
+} // namespace D3PD
+
+
+#endif // not EGAMMAD3PDANALYSIS_EGAMMACALCOQALG_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaDeltaEmax2Alg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaDeltaEmax2Alg.cxx
new file mode 100644
index 00000000000..19d1df8eac6
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaDeltaEmax2Alg.cxx
@@ -0,0 +1,87 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/egammaDeltaEmax2.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov, 2009
+ * @brief Calculate deltaEmax2 for egamma objects and store as UD.
+ */
+
+
+#include "egammaDeltaEmax2Alg.h"
+#include "D3PDMakerInterfaces/ICollectionGetterTool.h"
+#include "xAODCaloEvent/CaloCluster.h"
+#include "AthenaKernel/errorcheck.h"
+#include <cmath>
+
+
+namespace D3PD {
+
+
+egammaDeltaEmax2Alg::egammaDeltaEmax2Alg (const std::string& name,
+                                          ISvcLocator* svcloc)
+  : AthAlgorithm (name, svcloc),
+    m_getter (this)
+{
+  declareProperty ("AuxPrefix", m_auxPrefix,
+                   "Prefix to add to aux data items.");
+  declareProperty ("Getter", m_getter,
+                   "Getter instance for the input egamma objects.");
+  declareProperty ("AllowMissing", m_allowMissing = false,
+                   "If true, don't complain if input objects are missing.");
+  declareProperty ("HighLum", m_highLum = false,
+                   "True if we should use the high-lum definition "
+                   "of deltaEmax2.");
+}
+
+
+/**
+ * @brief Standard Gaudi @c initialize method.
+ */
+StatusCode egammaDeltaEmax2Alg::initialize()
+{
+  CHECK( AthAlgorithm::initialize() );
+  CHECK( m_getter.retrieve() );
+  CHECK( m_getter->configureD3PD<xAOD::Egamma>() );
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Standard Gaudi @c execute method.
+ */
+StatusCode egammaDeltaEmax2Alg::execute()
+{
+  xAOD::Egamma::Decorator<float> deltaemax2 (m_auxPrefix + "deltaEmax2");
+
+  CHECK( m_getter->reset (m_allowMissing) );
+  while (const xAOD::Egamma* g = m_getter->next<xAOD::Egamma>())
+  {
+    deltaemax2(*g) = -999;
+    const xAOD::CaloCluster*   cluster  = g->caloCluster(); 
+    if (cluster) {
+      double eta2   = std::fabs(cluster->etaBE(2));
+      // Protect against soft E topo clusters that don't have samp info.
+      if (eta2 > 900)
+        eta2   = std::fabs(cluster->eta());
+      double et     = cluster->e()/std::cosh(eta2);
+      float emax2 = 0;
+      g->showerShapeValue (emax2, xAOD::EgammaParameters::e2tsts1);
+
+      if (m_highLum)
+        deltaemax2(*g) = emax2/(1000.+0.0049*et);
+      else
+        deltaemax2(*g) = emax2/(1000.+0.009*et);
+    }
+
+    m_getter->releaseElement (g);
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaDeltaEmax2Alg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaDeltaEmax2Alg.h
new file mode 100644
index 00000000000..550ab0ea70d
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaDeltaEmax2Alg.h
@@ -0,0 +1,73 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/egammaDeltaEmax2.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov, 2009
+ * @brief Calculate deltaEmax2 for egamma objects and store as UD.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_EGAMMADELTAEMAX2_H
+#define EGAMMAD3PDANALYSIS_EGAMMADELTAEMAX2_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "xAODEgamma/Egamma.h"
+#include "GaudiKernel/ToolHandle.h"
+
+
+namespace D3PD {
+
+
+class ICollectionGetterTool;
+
+
+/**
+ * @brief Calculate deltaEmax2 for egamma objects and store as UD.
+ */
+class egammaDeltaEmax2Alg
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  egammaDeltaEmax2Alg (const std::string& name,
+                       ISvcLocator* svcloc);
+
+
+  /// Standard Gaudi @c initialize method.
+  virtual StatusCode initialize() override;
+
+
+  /// Standard Gaudi @c execute method.
+  virtual StatusCode execute() override;
+
+
+private:
+  /// Property: Prefix to add to aux data items.
+  std::string m_auxPrefix;
+
+  /// Property: Getter for input photon objects.
+  ToolHandle<ICollectionGetterTool> m_getter;
+
+  /// Property: If true, don't complain if input objects are missing.
+  bool m_allowMissing;
+
+  /// Property: True if we should use the high-lum definition of deltaEmax2.
+  bool m_highLum;
+};
+
+
+} // namespace D3PD
+
+
+#endif // EGAMMAD3PDANALYSIS_EGAMMADELTAEMAX2_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaMaxECellAlg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaMaxECellAlg.cxx
new file mode 100644
index 00000000000..351279b01c4
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaMaxECellAlg.cxx
@@ -0,0 +1,127 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: egammaMaxECellAlg.cxx 605541 2014-07-09 04:46:56Z ssnyder $
+/**
+ * @file SUSYD3PDMAker/src/egammaMaxECellAlg.cxx
+ * @author Nikiforos K. Nikiforou <nikiforo@cern.ch> adapted from various tools by Scott Snyder and others
+ * @date Apr, 2012
+ * @brief Find max E cell in middle layer for an egamma object EM Cluster and store in UserData.
+ */
+
+
+#include "egammaMaxECellAlg.h"
+#include "D3PDMakerInterfaces/ICollectionGetterTool.h"
+#include "xAODEgamma/Egamma.h"
+#include "xAODCaloEvent/CaloCluster.h"
+#include "LArTools/LArCablingService.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace D3PD {
+
+
+egammaMaxECellAlg::egammaMaxECellAlg (const std::string& name,
+                                      ISvcLocator* svcloc)
+  : AthAlgorithm (name, svcloc),
+    m_getter (this),
+    m_larCablingSvc("LArCablingService",this)
+{
+  declareProperty ("AuxPrefix", m_auxPrefix,
+                   "Prefix to add to aux data items.");
+  declareProperty ("AllowMissing", m_allowMissing = false,
+                   "If true, don't complain if input objects are missing.");
+  declareProperty ("Getter", m_getter,
+                   "Getter instance for the input egamma objects.");
+}
+
+
+/**
+ * @brief Standard Gaudi @c initialize method.
+ */
+StatusCode egammaMaxECellAlg::initialize()
+{
+  msg() << MSG::INFO <<" Starting egammaMaxECellAlg" << endreq;
+    
+  CHECK( AthAlgorithm::initialize() );
+  CHECK( m_getter.retrieve() );
+  CHECK( m_getter->configureD3PD<xAOD::Egamma>() ); 
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Standard Gaudi @c execute method.
+ */
+StatusCode egammaMaxECellAlg::execute()
+{
+  StatusCode sc = StatusCode::SUCCESS;
+
+#define DECOR(TYPE,N) xAOD::Egamma::Decorator<TYPE> N (m_auxPrefix + #N)
+  DECOR(float,        maxEcell_time);
+  DECOR(float,        maxEcell_energy);
+  DECOR(int,          maxEcell_gain);
+  DECOR(unsigned int, maxEcell_onlId);
+  DECOR(float,        maxEcell_x);
+  DECOR(float,        maxEcell_y);
+  DECOR(float,        maxEcell_z);
+#undef DECOR
+
+  CHECK( m_getter->reset (m_allowMissing) );
+  while (const xAOD::Egamma* eg = m_getter->next<xAOD::Egamma>())
+  {
+    const xAOD::CaloCluster *cluster = eg->caloCluster();
+        
+    maxEcell_time(*eg)   = -9898.9;
+    maxEcell_energy(*eg) = -9898.9;
+    maxEcell_gain(*eg)   = -1;
+    maxEcell_onlId(*eg)  = 0;
+        
+    maxEcell_x(*eg) = -9898.9;
+    maxEcell_y(*eg) = -9898.9;
+    maxEcell_z(*eg) = -9898.9;
+        
+    if(cluster){
+      if(cluster->getCellLinks()){
+                
+        float emax=-9999.;
+
+        const CaloCell* cell_maxE=0;
+        for (const CaloCell* cell : *cluster) {
+          int sampling = cell->caloDDE()->getSampling();
+          if (sampling== CaloCell_ID::EMB2 || sampling== CaloCell_ID::EME2) {
+            if ( (cell->provenance() & 0x2000) ) {
+              if (cell->energy() > emax) {
+                emax=cell->energy();
+                cell_maxE=cell;
+              }
+            }
+          }
+        }
+                
+        if(cell_maxE){
+          const CaloDetDescrElement* caloDDEl = cell_maxE->caloDDE();
+                    
+          maxEcell_time(*eg)   = cell_maxE->time();
+          maxEcell_energy(*eg) = cell_maxE->energy();
+          maxEcell_gain(*eg)   = (int) cell_maxE->gain();
+          maxEcell_onlId(*eg)  = (unsigned int) (m_larCablingSvc->createSignalChannelID(caloDDEl->identify())).get_compact();
+          
+          maxEcell_x(*eg) = caloDDEl->x();
+          maxEcell_y(*eg) = caloDDEl->y();
+          maxEcell_z(*eg) = caloDDEl->z();
+        }
+                
+                
+      }
+    }
+
+    m_getter->releaseElement (eg);
+  }
+
+  return sc;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaMaxECellAlg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaMaxECellAlg.h
new file mode 100644
index 00000000000..6cd1dba0896
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaMaxECellAlg.h
@@ -0,0 +1,75 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: egammaMaxECellAlg.h 604352 2014-07-01 04:52:11Z ssnyder $
+/**
+ * @file egammaD3PDAnalysis/src/egammaMaxECellAlg.h
+ * @author Nikiforos K. Nikiforou <nikiforo@cern.ch> adapted from various tools by Scott Snyder and others
+ * @date Apr, 2012
+ * @brief Find max E cell in middle layer for an egamma object EM Cluster and store in UserData.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_EGAMMAMAXECELLALG_H
+#define EGAMMAD3PDANALYSIS_EGAMMAMAXECELLALG_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+#include <vector>
+#include <string>
+
+class LArCablingService;
+
+
+namespace D3PD {
+
+
+class ICollectionGetterTool;
+
+
+/**
+ * @brief Find most energetic cell in the middle layer for an egamma object and store in UserData.
+ */
+class egammaMaxECellAlg
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  egammaMaxECellAlg (const std::string& name,
+                     ISvcLocator* svcloc);
+
+
+  /// Standard Gaudi @c initialize method.
+  virtual StatusCode initialize();
+
+
+  /// Standard Gaudi @c execute method.
+  virtual StatusCode execute();
+
+
+private:
+  /// Property: Prefix to add to aux data items.
+  std::string m_auxPrefix;
+
+  /// Property: Getter for input egamma objects.
+  ToolHandle<ICollectionGetterTool> m_getter;
+
+  /// Property: If true, don't complain if input objects are missing.
+  bool m_allowMissing;
+
+  ToolHandle<LArCablingService>  m_larCablingSvc;
+};
+
+
+} // namespace D3PD
+
+
+#endif // not EGAMMAD3PDANALYSIS_EGAMMAMAXECELLALG_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaNbCellsGainAlg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaNbCellsGainAlg.cxx
new file mode 100644
index 00000000000..9599347aaf9
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaNbCellsGainAlg.cxx
@@ -0,0 +1,155 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: egammaNbCellsGainAlg.cxx 605541 2014-07-09 04:46:56Z ssnyder $
+/**
+ * @file egammaD3PDAnalysis/src/egammaNbCellsGainAlg.cxx
+ * @date Aug. 2013
+ * @brief Number of cells in a given gain
+ */
+
+
+#include "egammaNbCellsGainAlg.h"
+#include "D3PDMakerInterfaces/ICollectionGetterTool.h"
+#include "xAODEgamma/Egamma.h"
+#include "xAODCaloEvent/CaloCluster.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+
+namespace D3PD {
+
+
+egammaNbCellsGainAlg::egammaNbCellsGainAlg (const std::string& name,
+                                            ISvcLocator* svcloc)
+  : AthAlgorithm (name, svcloc),
+    m_getter (this)
+{
+  declareProperty ("AuxPrefix", m_auxPrefix,
+                   "Prefix to add to aux data items.");
+  declareProperty ("AllowMissing", m_allowMissing = false,
+		     "If true, don't complain if input objects are missing.");
+  declareProperty ("Getter", m_getter,
+		     "Getter instance for the input egamma objects.");
+}
+
+
+/**
+ * @brief Standard Gaudi @c initialize method.
+ */
+StatusCode egammaNbCellsGainAlg::initialize()
+{
+  msg() << MSG::INFO <<" Starting egammaNbCellsGainAlg" << endreq;
+  
+  CHECK( AthAlgorithm::initialize() );
+  CHECK( m_getter.retrieve() );
+  CHECK( m_getter->configureD3PD<xAOD::Egamma>() ); 
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Standard Gaudi @c execute method.
+ */
+StatusCode egammaNbCellsGainAlg::execute()
+{
+  StatusCode sc = StatusCode::SUCCESS;
+
+  msg()<<MSG::DEBUG << " In execute: Getting egamma Objects  " << endreq;
+  
+#define DECOR(TYPE,N) xAOD::Egamma::Decorator<TYPE> N (m_auxPrefix + #N)
+  DECOR(int, nbCells_s0LowGain);
+  DECOR(int, nbCells_s0MedGain);
+  DECOR(int, nbCells_s0HighGain);
+
+  DECOR(int, nbCells_s1LowGain);
+  DECOR(int, nbCells_s1MedGain);
+  DECOR(int, nbCells_s1HighGain);
+
+  DECOR(int, nbCells_s2LowGain);
+  DECOR(int, nbCells_s2MedGain);
+  DECOR(int, nbCells_s2HighGain);
+
+  DECOR(int, nbCells_s3LowGain);
+  DECOR(int, nbCells_s3MedGain);
+  DECOR(int, nbCells_s3HighGain);
+#undef DECOR
+
+  CHECK( m_getter->reset (m_allowMissing) );
+  while (const xAOD::Egamma* eg = m_getter->next<xAOD::Egamma>()){
+    const xAOD::CaloCluster *cluster = eg->caloCluster();
+
+    int cell_nbcells_gainlow[4];
+    int cell_nbcells_gainmed[4];
+    int cell_nbcells_gainhgh[4];
+
+    for(int i=0; i<4; i++){
+      cell_nbcells_gainlow[i]=0;
+      cell_nbcells_gainmed[i]=0;
+      cell_nbcells_gainhgh[i]=0;
+    }
+
+    msg()<<MSG::DEBUG <<" Checking Cluster  " << endreq;
+    
+    if(cluster){
+      if(cluster->getCellLinks()){
+
+        for (const CaloCell* cell : *cluster) {
+	  int sampling = cell->caloDDE()->getSampling();
+	  int layer = -1;
+	  switch(sampling){
+	  case CaloCell_ID::PreSamplerB: 
+	  case CaloCell_ID::PreSamplerE:
+	    layer=0;
+	    break;
+	  case CaloCell_ID::EMB1: 
+	  case CaloCell_ID::EME1:
+	    layer=1;
+	    break;
+	  case CaloCell_ID::EMB2: 
+	  case CaloCell_ID::EME2:
+	    layer=2;
+	    break;
+	  case CaloCell_ID::EMB3: 
+	  case CaloCell_ID::EME3:
+	    layer=3;
+	    break;
+	  default:
+	    break;
+	  }
+
+	  if(layer < 0) continue;
+
+	  switch(cell->gain()){
+	  case 0: cell_nbcells_gainhgh[layer]++; break;
+	  case 1: cell_nbcells_gainmed[layer]++; break;
+	  case 2: cell_nbcells_gainlow[layer]++; break;
+	  default: break;
+	  }
+	}
+      }
+    }
+
+    nbCells_s0LowGain(*eg)  = cell_nbcells_gainlow[0];
+    nbCells_s0MedGain(*eg)  = cell_nbcells_gainmed[0];
+    nbCells_s0HighGain(*eg) = cell_nbcells_gainhgh[0];
+
+    nbCells_s1LowGain(*eg)  = cell_nbcells_gainlow[1];
+    nbCells_s1MedGain(*eg)  = cell_nbcells_gainmed[1];
+    nbCells_s1HighGain(*eg) = cell_nbcells_gainhgh[1];
+
+    nbCells_s2LowGain(*eg)  = cell_nbcells_gainlow[2];
+    nbCells_s2MedGain(*eg)  = cell_nbcells_gainmed[2];
+    nbCells_s2HighGain(*eg) = cell_nbcells_gainhgh[2];
+
+    nbCells_s3LowGain(*eg)  = cell_nbcells_gainlow[3];
+    nbCells_s3MedGain(*eg)  = cell_nbcells_gainmed[3];
+    nbCells_s3HighGain(*eg) = cell_nbcells_gainhgh[3];
+
+    m_getter->releaseElement (eg);
+  }
+  
+  return sc;
+}
+}
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaNbCellsGainAlg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaNbCellsGainAlg.h
new file mode 100644
index 00000000000..8b2e532c252
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaNbCellsGainAlg.h
@@ -0,0 +1,70 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: egammaNbCellsGainAlg.h 604352 2014-07-01 04:52:11Z ssnyder $
+/**
+ * @file egammaD3PDAnalysis/src/egammaNbCellsGainAlg.h
+ * @date Aug. 2013
+ * @brief Number of cells with given gain by layer
+ */
+
+
+#ifndef EGAMMANBCELLSGAINALG_H
+#define EGAMMANBCELLSGAINALG_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+#include <string>
+
+
+namespace D3PD {
+
+
+class ICollectionGetterTool;
+
+
+/**
+ * @brief Count the number of cells in each gain, layer by layer
+ */
+class egammaNbCellsGainAlg
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  egammaNbCellsGainAlg (const std::string& name,
+			 ISvcLocator* svcloc);
+
+
+  /// Standard Gaudi @c initialize method.
+  virtual StatusCode initialize();
+
+
+  /// Standard Gaudi @c execute method.
+  virtual StatusCode execute();
+
+
+private:
+  /// Property: Prefix to add to aux data items.
+  std::string m_auxPrefix;
+
+  /// Property: Getter for input egamma objects.
+  ToolHandle<ICollectionGetterTool> m_getter;
+
+  /// Property: If true, don't complain if input objects are missing.
+  bool m_allowMissing;
+
+};
+
+
+} // namespace D3PD
+
+
+#endif // not EGAMMANBCELLSGAINALG_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaRedoOQAlg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaRedoOQAlg.cxx
new file mode 100644
index 00000000000..8bc05f9b41f
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaRedoOQAlg.cxx
@@ -0,0 +1,82 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/egammaRedoOQAlg.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Dec, 2010
+ * @brief Recalculate OQ flags for Electron objects.
+ *        This is a template class, and can't be used directly as an Algorithm.
+ *        Derive a non-templated class from this to actually use.
+ */
+
+
+#include "egammaRedoOQAlg.h"
+#include "clusterHasCells.h"
+#include "D3PDMakerInterfaces/ICollectionGetterTool.h"
+#include "egammaInterfaces/IegammaBaseTool.h"
+#include "xAODEgamma/Egamma.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace D3PD {
+
+
+/**
+ * @brief Standard Gaudi algorithm constructor.
+ * @param name The algorithm name.
+ * @param svcloc The service locator.
+ */
+egammaRedoOQAlgBase::egammaRedoOQAlgBase (const std::string& name,
+                                          ISvcLocator* svcloc)
+  : AthAlgorithm (name, svcloc),
+    m_getter (this),
+    m_egammaOQFlagsBuilder( "egammaOQFlagsBuilder" )
+{
+  declareProperty ("OutputKey", m_outputkey,
+                   "SG key for output container.");
+
+  declareProperty ("Getter", m_getter,
+                   "Getter instance for the input egamma objects.");
+
+  declareProperty ("egammaOQFlagsBuilder",
+                   m_egammaOQFlagsBuilder,
+                   "Tool for calculating the OQ flag");
+}
+
+
+/**
+ * @brief Standard Gaudi @c initialize method.
+ */
+StatusCode egammaRedoOQAlgBase::initialize()
+{
+  CHECK( AthAlgorithm::initialize() );
+  CHECK( m_getter.retrieve() );
+  CHECK( m_getter->configureD3PD<xAOD::Egamma>() );
+  CHECK( m_egammaOQFlagsBuilder.retrieve() );
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Standard Gaudi execute method.
+ */
+StatusCode egammaRedoOQAlgBase::execute()
+{
+  CHECK (m_getter->reset() );
+  while (const xAOD::Egamma* eg = m_getter->next<xAOD::Egamma>()) {
+    xAOD::Egamma* neweg = this->cloneEG(eg);
+    // This only works if the cluster has cells available.
+    if (clusterHasCells (neweg->caloCluster()))
+      CHECK( m_egammaOQFlagsBuilder->execute (neweg) );
+  }
+  CHECK (this->commit());
+
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaRedoOQAlg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaRedoOQAlg.h
new file mode 100644
index 00000000000..e905e264344
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaRedoOQAlg.h
@@ -0,0 +1,129 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/egammaRedoOQAlg.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Dec, 2010
+ * @brief Recalculate OQ flags for Electron objects.
+ *        This is a template class, and can't be used directly as an Algorithm.
+ *        Derive a non-templated class from this to actually use.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_EGAMMAREDOOQALG_H
+#define EGAMMAD3PDANALYSIS_EGAMMAREDOOQALG_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "D3PDMakerInterfaces/ICollectionGetterTool.h"
+#include "egammaInterfaces/IegammaBaseTool.h"
+#include "xAODEgamma/Egamma.h"
+#include "GaudiKernel/ToolHandle.h"
+#include <string>
+
+
+namespace D3PD {
+
+
+class ICollectionGetterTool;
+
+
+/**
+ * @brief Helper, to factor out non-template dependent code.
+ *        Don't use this directly.
+ */
+class egammaRedoOQAlgBase
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  egammaRedoOQAlgBase (const std::string& name,
+                       ISvcLocator* svcloc);
+
+
+  /// Standard Gaudi initialize method.
+  StatusCode initialize();
+
+
+  /// Standard Gaudi execute method.
+  StatusCode execute();
+
+
+protected:
+  /// Clone EG and add it to the output list.
+  virtual xAOD::Egamma* cloneEG (const xAOD::Egamma* eg) = 0;
+
+  /// Store the output list in SG.
+  virtual StatusCode commit () = 0;
+
+
+  /// Property: SG key for output container.
+  std::string m_outputkey;
+
+
+private:
+  /// Property: Getter for input egamma objects.
+  ToolHandle<ICollectionGetterTool> m_getter;
+
+  /// Property: Tool to recalculate OQ flags.
+  ToolHandle<IegammaBaseTool> m_egammaOQFlagsBuilder;
+};
+
+
+/**
+ * @brief Recalculate OQ flags for Electron objects.
+ *        This is a template class, and can't be used directly as an Algorithm.
+ *        Derive a non-templated class from this to actually use.
+ */
+template <typename CONT, typename AUXSTORE>
+class egammaRedoOQAlg
+  : public egammaRedoOQAlgBase
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  egammaRedoOQAlg (const std::string& name,
+                   ISvcLocator* svcloc);
+
+
+protected:
+  typedef typename CONT::base_value_type Element;
+
+  /// Create the container if we haven't done so yet.
+  void checkCont();
+
+  /// Clone EG and add it to the output list.
+  virtual xAOD::Egamma* cloneEG (const xAOD::Egamma* eg);
+
+  /// Store the output list in SG.
+  virtual StatusCode commit ();
+
+
+private:
+  /// The output list being accumulated.
+  CONT* m_outlist;
+
+  /// The corresponding aux store.
+  AUXSTORE* m_auxstore;
+};
+
+
+} // namespace D3PD
+
+
+#include "egammaRedoOQAlg.icc"
+
+
+#endif // not EGAMMAD3PDANALYSIS_EGAMMAREDOOQALG_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaRedoOQAlg.icc b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaRedoOQAlg.icc
new file mode 100644
index 00000000000..28b5198160b
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaRedoOQAlg.icc
@@ -0,0 +1,82 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/egammaRedoOQAlg.icc
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Dec, 2010
+ * @brief Recalculate OQ flags for Electron objects.
+ *        This is a template class, and can't be used directly as an Algorithm.
+ *        Derive a non-templated class from this to actually use.
+ */
+
+
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace D3PD {
+
+
+/**
+ * @brief Standard Gaudi algorithm constructor.
+ * @param name The algorithm name.
+ * @param svcloc The service locator.
+ */
+template <typename CONT, typename AUXSTORE>
+egammaRedoOQAlg<CONT, AUXSTORE>::egammaRedoOQAlg (const std::string& name,
+                                                  ISvcLocator* svcloc)
+  : egammaRedoOQAlgBase (name, svcloc),
+    m_outlist (0),
+    m_auxstore (0)
+{
+}
+
+
+/**
+ * @brief Create the container if we haven't done so yet.
+ */
+template <typename CONT, typename AUXSTORE>
+void egammaRedoOQAlg<CONT, AUXSTORE>::checkCont()
+{
+  if (!m_outlist) {
+    m_outlist = new CONT;
+    m_auxstore = new AUXSTORE;
+    m_outlist->setStore (m_auxstore);
+  }
+}
+
+
+/**
+ * @brief Clone EG and add it to the output list.
+ */
+template <typename CONT, typename AUXSTORE>
+xAOD::Egamma* egammaRedoOQAlg<CONT, AUXSTORE>::cloneEG (const xAOD::Egamma* eg)
+{
+  Element* elt = new Element;
+  checkCont();
+  m_outlist->push_back (elt);
+  *elt = *static_cast<const Element*>(eg);
+  return elt;
+}
+
+
+/**
+ * @brief Store the output list in SG.
+ */
+template <typename CONT, typename AUXSTORE>
+StatusCode egammaRedoOQAlg<CONT, AUXSTORE>::commit ()
+{
+  checkCont();
+
+  CHECK( evtStore()->record (m_outlist, m_outputkey) );
+  CHECK( evtStore()->record (m_auxstore, m_outputkey + "Aux.") );
+  
+  m_outlist = 0;
+  m_auxstore = 0;
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaShowerDepthAlg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaShowerDepthAlg.cxx
new file mode 100644
index 00000000000..5de19739111
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaShowerDepthAlg.cxx
@@ -0,0 +1,112 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/egammaShowerDepthAlg.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jul, 2010
+ * @brief Store in UserData the shower depth for an egamma object.
+ */
+
+
+#include "egammaShowerDepthAlg.h"
+#include "D3PDMakerInterfaces/ICollectionGetterTool.h"
+#include "xAODEgamma/Egamma.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace D3PD {
+
+
+/**
+ * @brief Standard Gaudi algorithm constructor.
+ * @param name The algorithm name.
+ * @param svcloc The service locator.
+ */
+egammaShowerDepthAlg::egammaShowerDepthAlg (const std::string& name,
+                                            ISvcLocator* svcloc)
+  : AthAlgorithm (name, svcloc),
+    m_getter (this),
+    m_depthCalc (m_sampling_depth, m_eta_start_crack, m_eta_end_crack, m_etamax)
+{
+  declareProperty ("AuxPrefix", m_auxPrefix,
+                   "Prefix to add to aux data items.");
+  declareProperty ("Getter", m_getter,
+                   "Getter instance for the input egamma objects.");
+  declareProperty ("AllowMissing", m_allowMissing = false,
+                   "If true, don't complain if input objects are missing.");
+
+  declareConstant ("sampling_depth"  , m_sampling_depth);
+  declareConstant ("eta_start_crack" , m_eta_start_crack);
+  declareConstant ("eta_end_crack"   , m_eta_end_crack);
+  declareConstant ("etamax"          , m_etamax);
+  declareConstant ("use_raw_eta"     , m_use_raw_eta);
+
+  finish_ctor ("D3PD::egammaShowerDepthAlg");
+}
+
+
+/**
+ * @brief Standard Gaudi @c initialize method.
+ */
+StatusCode egammaShowerDepthAlg::initialize()
+{
+  CHECK( AthAlgorithm::initialize() );
+  CHECK( CaloRec::ToolWithConstantsMixin::initialize() );
+  CHECK( m_getter.retrieve() );
+  CHECK( m_getter->configureD3PD<xAOD::Egamma>() );
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Method to set a property value.
+ * @param p The property name/value to set.
+ * @return Gaudi status code.
+ *
+ * Required by @c ToolWithConstantsMixin.
+ */
+StatusCode egammaShowerDepthAlg::setProperty (const Property& p)
+{
+  CHECK (AthAlgorithm::setProperty (p));
+  CHECK (CaloRec::ToolWithConstantsMixin::setProperty (p));
+  return StatusCode::SUCCESS;
+}
+StatusCode egammaShowerDepthAlg::setProperty (const std::string& propname,
+                                              const std::string& value)
+{
+  CHECK (AthAlgorithm::setProperty (propname, value));
+  CHECK (CaloRec::ToolWithConstantsMixin::setProperty (propname, value));
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Standard Gaudi @c execute method.
+ */
+StatusCode egammaShowerDepthAlg::execute()
+{
+  xAOD::Egamma::Decorator<float> depth (m_auxPrefix + "calibHitsShowerDepth");
+
+  // FIXME: Using the adjusted eta value isn't implemented.
+  if (!m_use_raw_eta) {
+    REPORT_MESSAGE (MSG::WARNING) << "use_raw_eta==false is not implemented.";
+  }
+
+  CHECK( m_getter->reset (m_allowMissing) );
+  while (const xAOD::Egamma* eg = m_getter->next<xAOD::Egamma>())
+  {
+    const xAOD::CaloCluster* cl = eg->caloCluster();
+    depth(*eg) = -999;
+    if (cl)
+      depth(*eg) = m_depthCalc.depth (std::abs (cl->etaBE(2)), cl, msg());
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaShowerDepthAlg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaShowerDepthAlg.h
new file mode 100644
index 00000000000..a927a6d2cc4
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaShowerDepthAlg.h
@@ -0,0 +1,104 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/egammaShowerDepthAlg.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jul, 2010
+ * @brief Store in UserData the shower depth for an egamma object.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_EGAMMASHOWERDEPTHALG_H
+#define EGAMMAD3PDANALYSIS_EGAMMASHOWERDEPTHALG_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "CaloClusterCorrection/CaloSwCalibHitsShowerDepth.h"
+#include "CaloRec/ToolWithConstantsMixin.h"
+#include "GaudiKernel/ToolHandle.h"
+
+
+namespace D3PD {
+
+
+class ICollectionGetterTool;
+
+
+/**
+ * @brief Store in UserData the shower depth for an egamma object.
+ */
+class egammaShowerDepthAlg
+  : public AthAlgorithm,
+    public CaloRec::ToolWithConstantsMixin
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  egammaShowerDepthAlg (const std::string& name,
+                        ISvcLocator* svcloc);
+
+
+  /// Standard Gaudi @c initialize method.
+  virtual StatusCode initialize();
+
+
+  /**
+   * @brief Method to set a property value.
+   * @param p The property name/value to set.
+   * @return Gaudi status code.
+   *
+   * Required by @c ToolWithConstantsMixin.
+   */
+  using AthAlgorithm::setProperty;
+  StatusCode setProperty (const Property& p);
+  StatusCode setProperty (const std::string& propname,
+                          const std::string& value);
+
+
+  /// Standard Gaudi @c execute method.
+  virtual StatusCode execute();
+
+
+private:
+  /// Property: Prefix to add to aux data items.
+  std::string m_auxPrefix;
+
+  /// Property: Getter for input egamma objects.
+  ToolHandle<ICollectionGetterTool> m_getter;
+
+  /// Property: If true, don't complain if input objects are missing.
+  bool m_allowMissing;
+
+  /// Property: Table of sampling depth weights.
+  CaloRec::Array<2> m_sampling_depth;
+
+  /// Property: Eta of the start of the crack.
+  float m_eta_start_crack;
+
+  /// Property: Eta of the end of the crack.
+  float m_eta_end_crack;
+
+  /// Property: Maximum eta range of the depth weight table.
+  float m_etamax;
+
+  /// Property: Use raw eta value for region comparisons?
+  // FIXME: The false setting of this is not implemented.
+  bool m_use_raw_eta;
+
+  /// Depth calculator.
+  CaloClusterCorr::CaloSwCalibHitsShowerDepth m_depthCalc;
+};
+
+
+} // namespace D3PD
+
+
+#endif // not EGAMMAD3PDANALYSIS_EGAMMASHOWERDEPTHALG_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaSumCellsGainAlg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaSumCellsGainAlg.cxx
new file mode 100644
index 00000000000..c188cfbe667
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaSumCellsGainAlg.cxx
@@ -0,0 +1,156 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: egammaSumCellsGainAlg.cxx 605541 2014-07-09 04:46:56Z ssnyder $
+/**
+ * @file egammaD3PDAnalysis/src/egammaMaxECellAlg.cxx
+ * @author Mike Hance
+ * @date Aug. 2013
+ * @brief Sum cell energies with given gain
+ */
+
+
+#include "egammaSumCellsGainAlg.h"
+#include "D3PDMakerInterfaces/ICollectionGetterTool.h"
+#include "xAODEgamma/Egamma.h"
+#include "xAODCaloEvent/CaloCluster.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace D3PD {
+
+
+egammaSumCellsGainAlg::egammaSumCellsGainAlg (const std::string& name,
+					      ISvcLocator* svcloc)
+  : AthAlgorithm (name, svcloc),
+    m_getter (this)
+{
+  declareProperty ("AuxPrefix", m_auxPrefix,
+                   "Prefix to add to aux data items.");
+  declareProperty ("AllowMissing", m_allowMissing = false,
+		     "If true, don't complain if input objects are missing.");
+  declareProperty ("Getter", m_getter,
+		     "Getter instance for the input egamma objects.");
+}
+
+
+/**
+ * @brief Standard Gaudi @c initialize method.
+ */
+StatusCode egammaSumCellsGainAlg::initialize()
+{
+  msg() << MSG::INFO <<" Starting egammaSumCellsGainAlg" << endreq;
+  
+  CHECK( AthAlgorithm::initialize() );
+  CHECK( m_getter.retrieve() );
+  CHECK( m_getter->configureD3PD<xAOD::Egamma>() ); 
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Standard Gaudi @c execute method.
+ */
+StatusCode egammaSumCellsGainAlg::execute()
+{
+  StatusCode sc = StatusCode::SUCCESS;
+
+  msg()<<MSG::DEBUG << " In execute: Getting egamma Objects  " << endreq;
+  
+#define DECOR(TYPE,N) xAOD::Egamma::Decorator<TYPE> N (m_auxPrefix + #N)
+  DECOR (float, Es0LowGain);
+  DECOR (float, Es0MedGain);
+  DECOR (float, Es0HighGain);
+
+  DECOR (float, Es1LowGain);
+  DECOR (float, Es1MedGain);
+  DECOR (float, Es1HighGain);
+
+  DECOR (float, Es2LowGain);
+  DECOR (float, Es2MedGain);
+  DECOR (float, Es2HighGain);
+
+  DECOR (float, Es3LowGain);
+  DECOR (float, Es3MedGain);
+  DECOR (float, Es3HighGain);
+#undef DECOR 
+
+  CHECK( m_getter->reset (m_allowMissing) );
+  while (const xAOD::Egamma* eg = m_getter->next<xAOD::Egamma>()){
+    const xAOD::CaloCluster *cluster = eg->caloCluster();
+    
+    float cell_sum_energy_gainlow[4];
+    float cell_sum_energy_gainmed[4];
+    float cell_sum_energy_gainhgh[4];
+    for(int i=0; i<4; i++){
+      cell_sum_energy_gainlow[i]=0;
+      cell_sum_energy_gainmed[i]=0;
+      cell_sum_energy_gainhgh[i]=0;
+    }
+    
+    msg()<<MSG::DEBUG <<" Checking Cluster  " << endreq;
+    
+    if(cluster) {
+      if(cluster->getCellLinks()) {
+	
+        for (const CaloCell* cell : *cluster) {
+	  int sampling = cell->caloDDE()->getSampling();
+	  int layer = -1;
+	  switch(sampling){
+	  case CaloCell_ID::PreSamplerB: 
+	  case CaloCell_ID::PreSamplerE:
+	    layer=0;
+	    break;
+	  case CaloCell_ID::EMB1: 
+	  case CaloCell_ID::EME1:
+	    layer=1;
+	    break;
+	  case CaloCell_ID::EMB2: 
+	  case CaloCell_ID::EME2:
+	    layer=2;
+	    break;
+	  case CaloCell_ID::EMB3: 
+	  case CaloCell_ID::EME3:
+	    layer=3;
+	    break;
+	  default:
+	    break;
+	  }
+
+	  if(layer < 0) continue;
+
+	  switch(cell->gain()){
+	  case 0: cell_sum_energy_gainhgh[layer] += cell->energy(); break;
+	  case 1: cell_sum_energy_gainmed[layer] += cell->energy(); break;
+	  case 2: cell_sum_energy_gainlow[layer] += cell->energy(); break;
+	  default: break;
+	  }
+	}
+      }
+    }
+
+    Es0LowGain(*eg)  = cell_sum_energy_gainlow[0];
+    Es0MedGain(*eg)  = cell_sum_energy_gainmed[0];
+    Es0HighGain(*eg) = cell_sum_energy_gainhgh[0];
+
+    Es1LowGain(*eg)  = cell_sum_energy_gainlow[1];
+    Es1MedGain(*eg)  = cell_sum_energy_gainmed[1];
+    Es1HighGain(*eg) = cell_sum_energy_gainhgh[1];
+
+    Es2LowGain(*eg)  = cell_sum_energy_gainlow[2];
+    Es2MedGain(*eg)  = cell_sum_energy_gainmed[2];
+    Es2HighGain(*eg) = cell_sum_energy_gainhgh[2];
+
+    Es3LowGain(*eg)  = cell_sum_energy_gainlow[3];
+    Es3MedGain(*eg)  = cell_sum_energy_gainmed[3];
+    Es3HighGain(*eg) = cell_sum_energy_gainhgh[3];
+
+    m_getter->releaseElement (eg);
+  }
+  
+  return sc;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaSumCellsGainAlg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaSumCellsGainAlg.h
new file mode 100644
index 00000000000..f5de6c25176
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaSumCellsGainAlg.h
@@ -0,0 +1,70 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: egammaSumCellsGainAlg.h 604352 2014-07-01 04:52:11Z ssnyder $
+/**
+ * @file egammaD3PDAnalysis/src/egammaSumCellsGainAlg.h
+ * @author Mike Hance
+ * @date Aug. 2013
+ * @brief Sum cell energies with given gain
+ */
+
+
+#ifndef EGAMMASUMCELLSGAINALG_H
+#define EGAMMASUMCELLSGAINALG_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+#include <string>
+
+
+namespace D3PD {
+
+
+class ICollectionGetterTool;
+
+
+/**
+ * @brief Find most energetic cell in the middle layer for an egamma object and store in UserData.
+ */
+class egammaSumCellsGainAlg
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  egammaSumCellsGainAlg (const std::string& name,
+			 ISvcLocator* svcloc);
+
+
+  /// Standard Gaudi @c initialize method.
+  virtual StatusCode initialize();
+
+
+  /// Standard Gaudi @c execute method.
+  virtual StatusCode execute();
+
+
+private:
+  /// Property: Prefix to add to aux data items.
+  std::string m_auxPrefix;
+
+  /// Property: Getter for input egamma objects.
+  ToolHandle<ICollectionGetterTool> m_getter;
+
+  /// Property: If true, don't complain if input objects are missing.
+  bool m_allowMissing;
+};
+
+
+} // namespace D3PD
+
+
+#endif // not EGAMMAMAXECELLALG_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTimeCorrAlg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTimeCorrAlg.cxx
new file mode 100644
index 00000000000..f917ea241a2
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTimeCorrAlg.cxx
@@ -0,0 +1,109 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: egammaTimeCorrAlg.cxx 605541 2014-07-09 04:46:56Z ssnyder $
+/**
+* @file egammaD3PDAnalysis/src/egammaTimeCorrAlg.cxx
+* @author Nikiforos K. Nikiforou <nikiforo@cern.ch> adapted from various tools by Scott Snyder
+* @date Apr, 2012
+* @brief Calculate corrected time for an egamma object and store in UserData.
+*/
+
+
+#include "egammaTimeCorrAlg.h"
+#include "D3PDMakerInterfaces/ICollectionGetterTool.h"
+#include "xAODEgamma/Egamma.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace D3PD {
+
+
+egammaTimeCorrAlg::egammaTimeCorrAlg (const std::string& name,
+                                      ISvcLocator* svcloc): 
+  AthAlgorithm (name, svcloc), 
+  m_getter (this),
+  m_caloClusterTimeTool("",this)
+{
+  declareProperty ("AuxPrefix", m_auxPrefix,
+                   "Prefix to add to aux data items.");
+  declareProperty ("AllowMissing", m_allowMissing = false,
+                   "If true, don't complain if input objects are missing.");
+  declareProperty ("Getter", m_getter,
+                   "Getter instance for the input egamma objects.");
+  declareProperty("VertexContainerName", m_vertexContainerName="VxPrimaryCandidate");
+  declareProperty("CaloClusterTimeTool", m_caloClusterTimeTool, "a private tool for caloTime correction");
+}
+
+
+/**
+* @brief Standard Gaudi @c initialize method.
+*/
+StatusCode egammaTimeCorrAlg::initialize()
+{
+    msg() << MSG::INFO <<" Starting egammaTimeCorrAlg" << endreq;
+    
+    CHECK( AthAlgorithm::initialize() );
+    CHECK( m_caloClusterTimeTool.retrieve() );
+    CHECK( m_getter.retrieve() );
+    CHECK( m_getter->configureD3PD<xAOD::Egamma>() );
+    return StatusCode::SUCCESS;
+}
+
+
+/**
+* @brief Standard Gaudi @c execute method.
+*/
+StatusCode egammaTimeCorrAlg::execute()
+{
+  StatusCode sc = StatusCode::SUCCESS;
+
+  float vtx_z=0.0;
+
+  const VxContainer* vertexCont(0);
+  sc = evtStore()->retrieve(vertexCont,m_vertexContainerName);
+  if (sc.isFailure() || !vertexCont || vertexCont->size()<1) {
+    msg() << MSG::ERROR <<" Can't retrieve VertexContainer!" << endreq;
+    return sc;
+  }
+    
+  const Trk::VxCandidate* Vtx = *(vertexCont->begin());
+  vtx_z = Vtx->recVertex().position().z();
+
+#define DECOR(TYPE,N) xAOD::Egamma::Decorator<TYPE> N (m_auxPrefix + #N)
+  DECOR(float,        raw_cl_time);
+  DECOR(float,        corr_cl_time);
+  DECOR(float,        corr_cl_time_err);
+  DECOR(unsigned int, corr_cl_time_flags);
+#undef DECOR
+
+  CHECK( m_getter->reset (m_allowMissing) );
+  while (const xAOD::Egamma* eg = m_getter->next<xAOD::Egamma>())
+  {
+    raw_cl_time(*eg) = -9898.9;
+    corr_cl_time(*eg) = -9898.9;
+    corr_cl_time_err(*eg) = 9898.9;
+    corr_cl_time_flags(*eg) = ~0U;
+        
+    const xAOD::CaloCluster *cluster = eg->caloCluster();
+    if(cluster) {
+      raw_cl_time(*eg) = cluster->time();
+        
+      if(cluster->getCellLinks() && !m_caloClusterTimeTool.empty()) {
+        m_caloClusterTimeTool->makeClusterTimeCorrection
+          (vtx_z, cluster,
+           corr_cl_time(*eg),
+           corr_cl_time_err(*eg),
+           corr_cl_time_flags(*eg));
+        
+      }
+    }
+    m_getter->releaseElement (eg);
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTimeCorrAlg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTimeCorrAlg.h
new file mode 100644
index 00000000000..811f3ff631a
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTimeCorrAlg.h
@@ -0,0 +1,86 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: egammaTimeCorrAlg.h 604352 2014-07-01 04:52:11Z ssnyder $
+/**
+ * @file egammaD3PDAnalysis/src/egammaTimeCorrAlg.h
+ * @author Nikiforos K. Nikiforou <nikiforo@cern.ch> adapted from various tools by Scott Snyder
+ * @date Apr, 2012
+ * @brief Calculate corrected time for an egamma object and store in UserData.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_EGAMMATIMECORRALG_H
+#define EGAMMAD3PDANALYSIS_EGAMMATIMECORRALG_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+
+#include "VxVertex/VxContainer.h"   
+#include "VxVertex/RecVertex.h"
+
+#include "EventInfo/EventInfo.h"
+#include "EventInfo/EventID.h"
+
+#include "CaloInterface/ICaloClusterTimeTool.h"
+
+#include <vector>
+#include <string>
+
+
+namespace D3PD {
+
+
+class ICollectionGetterTool;
+
+
+/**
+ * @brief Calculate corrected time for an egamma object and store in UserData.
+ */
+class egammaTimeCorrAlg
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  egammaTimeCorrAlg (const std::string& name,
+                     ISvcLocator* svcloc);
+
+
+  /// Standard Gaudi @c initialize method.
+  virtual StatusCode initialize();
+
+
+  /// Standard Gaudi @c execute method.
+  virtual StatusCode execute();
+
+
+private:
+  /// Property: Prefix to add to aux data items.
+  std::string m_auxPrefix;
+
+  /// Property: Vertex container name (to correct for TOF difference).
+  std::string m_vertexContainerName;
+
+  /// Property: Getter for input egamma objects.
+  ToolHandle<ICollectionGetterTool> m_getter;
+
+  /// Property: If true, don't complain if input objects are missing.
+  bool m_allowMissing;
+
+  /// Property: Cluster Time corrector tool
+  ToolHandle<ICaloClusterTimeTool> m_caloClusterTimeTool; 
+};
+
+
+} // namespace D3PD
+
+
+#endif // not EGAMMAD3PDANALYSIS_EGAMMATIMECORRALG_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTopoIsoAlg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTopoIsoAlg.cxx
new file mode 100644
index 00000000000..cb33c4512f2
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTopoIsoAlg.cxx
@@ -0,0 +1,137 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/egammaTopoIsoAlg.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov, 2009
+ * @brief Calculate isolation cones of topo clusters for egamma objects.
+ *        Save as aux data.
+ */
+
+
+#include "egammaTopoIsoAlg.h"
+#include "D3PDMakerInterfaces/ICollectionGetterTool.h"
+#include "xAODEgamma/Egamma.h"
+#include "egammaInterfaces/IegammaTopoIso.h"
+#include "xAODCaloEvent/CaloCluster.h"
+#include "FourMomUtils/P4Helpers.h"
+#include "AthContainers/ConstDataVector.h"
+#include "AthenaKernel/errorcheck.h"
+#include "boost/foreach.hpp"
+#include "boost/format.hpp"
+#include <vector>
+
+
+namespace D3PD {
+
+
+egammaTopoIsoAlg::egammaTopoIsoAlg (const std::string& name,
+                                    ISvcLocator* svcloc)
+  : AthAlgorithm (name, svcloc),
+    m_egammaGetter (this),
+    m_clusterGetter (this)
+{ 
+  declareProperty ("AuxPrefix", m_auxPrefix,
+                   "Prefix to add to aux data items.");
+ declareProperty ("EgammaGetter", m_egammaGetter,
+                   "Getter instance for the input egamma objects.");
+  declareProperty ("ClusterGetter", m_clusterGetter,
+                   "Getter instance for the input topo cluster objects.");
+  declareProperty ("TopoIsoTool", m_topoIsoTool,
+		   "egamma tool for calculating topo isolation.");
+  declareProperty ("AllowMissing", m_allowMissing = false,
+                   "If true, don't complain if input objects are missing.");
+  declareProperty ("ConeSizes", m_coneSizes,
+                   "Cone sizes for which to calculate isolation.");
+  declareProperty ("UseEMScale", m_useEMScale = true,
+                   "Use TopoClusters at the EM scale.");
+  declareProperty ("PositiveEnergyClusters", m_positiveClusters = false,
+		   "Use only positive-energy clusters.");
+
+  for (int i=2; i<=6; i++)
+    m_coneSizes.push_back (i / 10.);
+}
+
+
+/**
+ * @brief Standard Gaudi @c initialize method.
+ */
+StatusCode egammaTopoIsoAlg::initialize()
+{
+  CHECK( AthAlgorithm::initialize() );
+  CHECK( m_topoIsoTool.retrieve() );
+  CHECK( m_egammaGetter.retrieve() );
+  CHECK( m_clusterGetter.retrieve() );
+  CHECK( m_egammaGetter->configureD3PD<xAOD::Egamma>() );
+  CHECK( m_clusterGetter->configureD3PD<xAOD::CaloCluster>() );
+  
+  m_names.resize (m_coneSizes.size());
+  boost::format fmt ("topo%sEtcone%02d");
+  const char* em = m_positiveClusters ? (m_useEMScale ? "Pos" : "PosCal"):(m_useEMScale ? "" : "Cal");
+  for (size_t i = 0; i < m_coneSizes.size(); i++) {
+    m_names[i] = (fmt % em % static_cast<int>(m_coneSizes[i]*100 + 0.5)).str();
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Standard Gaudi @c execute method.
+ */
+StatusCode egammaTopoIsoAlg::execute()
+{
+  // Photon and topo cluster lists may be long.
+  // So make a local copy of the cluster list.
+  ConstDataVector<xAOD::CaloClusterContainer> clusts (SG::VIEW_ELEMENTS);
+  CHECK( m_clusterGetter->reset (m_allowMissing) );
+  clusts.reserve (m_clusterGetter->sizeHint (m_allowMissing) );
+  while (const xAOD::CaloCluster* cl = m_clusterGetter->next<xAOD::CaloCluster>()){
+    if(m_useEMScale){
+      if(!(m_positiveClusters && cl->p4(xAOD::CaloCluster::UNCALIBRATED).Et()<0))
+	clusts.push_back (cl);
+    }
+    else{
+      if(!(m_positiveClusters && cl->et()<0))
+	clusts.push_back (cl);
+    }
+  }
+
+  std::vector<float> cones (m_coneSizes.size());
+
+  CHECK( m_egammaGetter->reset (m_allowMissing) );
+  while (const xAOD::Egamma* eg = m_egammaGetter->next<xAOD::Egamma>())
+  {
+    CHECK( topoClustCones (*eg, *clusts.asDataVector(), cones) );
+    m_egammaGetter->releaseElement (eg);
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Calculate isolation cones in topo clusters around @a eg.
+ */
+StatusCode
+egammaTopoIsoAlg::topoClustCones (const xAOD::Egamma& eg,
+                                  const xAOD::CaloClusterContainer& clusts,
+                                  std::vector<float>& cones) const
+{
+  size_t ncones = m_coneSizes.size();
+  
+  CHECK( m_topoIsoTool->execute(&eg, &clusts, m_coneSizes) );
+  for (size_t i = 0; i < ncones; i++){
+    cones[i] = m_topoIsoTool->topoetcone(i);
+    SG::AuxElement::Decorator<float> var (m_auxPrefix + m_names[i]);
+    var(eg) = cones[i];
+  }    
+
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTopoIsoAlg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTopoIsoAlg.h
new file mode 100644
index 00000000000..e3d9eae5c05
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTopoIsoAlg.h
@@ -0,0 +1,99 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/PhotonTopoIsoAlg.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov, 2009
+ * @brief Calculate isolation cones of topo clusters for egamma objects.
+ *        Save as aux data.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_EGAMMATOPOISOALG_H
+#define EGAMMAD3PDANALYSIS_EGAMMATOPOISOALG_H
+
+
+#include "xAODEgamma/Egamma.h"
+#include "xAODCaloEvent/CaloClusterContainer.h"
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+#include <vector>
+class IegammaTopoIso;
+
+namespace D3PD {
+
+
+class ICollectionGetterTool;
+
+
+/**
+ * @brief Calculate isolation cones of topo clusters for egamma objects.
+ *        Save as UD.
+ */
+class egammaTopoIsoAlg
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  egammaTopoIsoAlg (const std::string& name,
+                    ISvcLocator* svcloc);
+
+
+  /// Standard Gaudi @c initialize method.
+  virtual StatusCode initialize() override;
+
+
+  /// Standard Gaudi @c execute method.
+  virtual StatusCode execute() override;
+
+
+private:
+  /// Property: Prefix to add to aux data items.
+  std::string m_auxPrefix;
+
+  /// Calculate isolation cones in topo clusters around @a eg.
+  StatusCode topoClustCones (const xAOD::Egamma& g,
+                             const xAOD::CaloClusterContainer& clusts,
+                             std::vector<float>& cones)
+    const;
+
+
+  /// Property: Getter for input photons.
+  ToolHandle<ICollectionGetterTool> m_egammaGetter;
+
+  /// Property: Getter for topo clusters.
+  ToolHandle<ICollectionGetterTool> m_clusterGetter;
+
+  /// Property: TopoIso calculator tool.
+  ToolHandle<IegammaTopoIso > m_topoIsoTool;
+
+  /// Property: If true, don't complain if input objects are missing.
+  bool m_allowMissing;
+
+  /// Property: List of cone sizes to process.
+  std::vector<float> m_coneSizes;
+
+  /// Property: Use TopoClusters at the EM scale.
+  bool m_useEMScale;
+
+  /// Property: Use only positive-energy TopoClusters.
+  bool m_positiveClusters;
+
+  /// List of UD variable names corresponding to each cone size.
+  std::vector<std::string> m_names;
+};
+
+
+} // namespace D3PD
+
+
+#endif // EGAMMAD3PDANALYSIS_EGAMMATOPOISOALG_H
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTruthAlg.cxx b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTruthAlg.cxx
new file mode 100644
index 00000000000..a167ece47b9
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTruthAlg.cxx
@@ -0,0 +1,304 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/egammaTruthAlg.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jul, 2014
+ * @brief Select egtruth particles.
+ */
+
+
+#include "egammaTruthAlg.h"
+#include "xAODTruth/TruthParticleContainer.h"
+#include "xAODTruth/TruthParticleAuxContainer.h"
+#include "RecoToolInterfaces/IExtrapolateToCaloTool.h"
+#include "TrackToCalo/ImpactInCalo.h"
+#include "EventKernel/PdtPdg.h"
+#include "CxxUtils/make_unique.h"
+#include "GaudiKernel/IPartPropSvc.h"
+#include "GaudiKernel/SystemOfUnits.h"
+#include "HepPDT/ParticleData.hh"
+#include "HepPDT/ParticleDataTable.hh"
+
+
+using Gaudi::Units::GeV;
+using Gaudi::Units::MeV;
+
+
+namespace {
+
+
+bool isGenStable (const xAOD::TruthParticle& tp)
+{
+  // get generator id 
+  int p_id = tp.pdgId();
+
+  const xAOD::TruthVertex* vertex = tp.hasDecayVtx() ? tp.decayVtx() : 0;
+  // we want to keep primary particle with status==2 but without vertex in HepMC
+  int vertex_barcode=-999999;
+  if (vertex) vertex_barcode=vertex->barcode();
+
+  return (
+          ( ( tp.status()%1000 == 1) ||  
+            (tp.status()==2 && vertex_barcode<-200000) || 
+            (tp.status()%1000 == 2 && tp.status() > 1000) 
+            ) && (tp.barcode()<200000) 
+          && !(abs(p_id) == 21 && tp.e()==0)
+          ) ? true:false;    
+}
+
+
+bool isGenInteracting (const xAOD::TruthParticle& tp)
+{
+  int status = tp.status();
+  int barcode = tp.barcode();
+  int pdg_id = abs(tp.pdgId());
+  const xAOD::TruthVertex* vertex = tp.hasDecayVtx() ? tp.decayVtx() : 0;
+  // we want to keep primary particle with status==2 but without vertex in HepMC
+  int vertex_barcode=-999999;
+  if (vertex) vertex_barcode=vertex->barcode();
+
+  return
+    (
+
+     (((status%1000 == 1) ||
+       (status%1000 == 2 && status > 1000) ||
+       (status==2 && vertex_barcode<-200000)) && (barcode<200000)) &&
+
+     !(pdg_id==12 || pdg_id==14 || pdg_id==16 ||
+       (pdg_id==1000022 &&  status%1000==1 ) ||
+       (pdg_id==5100022 &&  status%1000==1 ) ||
+       (pdg_id==1000024 &&  status%1000==1 ) ||
+       (pdg_id==39 &&  status%1000==1 ) ||
+       (pdg_id==1000039 &&  status%1000==1 ) ||
+       (pdg_id==5000039 &&  status%1000==1 ))
+
+     )
+    ? true:false;
+}
+
+
+}
+
+
+namespace D3PD {
+
+
+/**
+ * @brief Standard Gaudi algorithm constructor.
+ * @param name The algorithm name.
+ * @param svcloc The service locator.
+ */
+egammaTruthAlg::egammaTruthAlg (const std::string& name,
+                                ISvcLocator* svcloc)
+  : AthAlgorithm (name, svcloc),
+    m_ppsvc ("PartPropSvc", name)
+{
+  declareProperty ("AuxPrefix", m_auxPrefix,
+                   "Prefix to add to aux data items.");
+
+  declareProperty ("InputKey", m_inputKey,
+                   "SG key for the input container.");
+  declareProperty ("OutputKey", m_outputKey,
+                   "SG key for the output container.");
+  
+  declareProperty ("ElectronPtMin", m_electronPtMin = 2*GeV,
+                   "Minimum pt for electrons.");
+  declareProperty ("PhotonPtMin",   m_photonPtMin = 2*GeV,
+                   "Minimum pt for photons.");
+  declareProperty ("EtaMax",    m_etaMax = 2.5,
+                   "Maximum eta.");
+  declareProperty ("IsoCone",    m_isoCone = 0.2,
+                   "Isolation cone width.");
+  declareProperty ("PhotonEtIsoMax", m_photonEtIsoMax = 2*MeV,
+                   "Maximum isolation cone energy allowed to keep a photon.");
+
+  declareProperty("ExtrapolTrackToCaloTool", m_extrap,
+                  "Extrapolator to calorimeter.");
+  declareProperty("PartPropSvc", m_ppsvc,
+                  "Particle property service.");
+}
+
+
+/**
+ * @brief Standard Gaudi @c initialize method.
+ */
+StatusCode egammaTruthAlg::initialize()
+{
+  CHECK( AthAlgorithm::initialize() );
+  CHECK( m_extrap.retrieve() );
+  CHECK( m_ppsvc.retrieve() );
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Standard Gaudi @c execute method.
+ */
+StatusCode egammaTruthAlg::execute()
+{
+  const xAOD::TruthParticleContainer* pin = 0;
+  CHECK( evtStore()->retrieve (pin, m_inputKey) );
+
+  auto pout = CxxUtils::make_unique<xAOD::TruthParticleContainer>();
+  auto pout_aux = CxxUtils::make_unique<xAOD::TruthParticleAuxContainer>();
+  pout->setStore (pout_aux.get());
+
+#define DECOR(TYPE,N) xAOD::TruthParticle::Decorator<TYPE> N (m_auxPrefix + #N)
+  DECOR(float,        etaCalo);
+  DECOR(float,        phiCalo);
+  DECOR(float,        Etcone20);
+#undef DECOR
+
+  for (const xAOD::TruthParticle* tp : *pin) {
+    float iso = -999;
+    if (isAccepted (*tp, *pin, iso)) {
+      pout->push_back (CxxUtils::make_unique<xAOD::TruthParticle>());
+      *pout->back() = *tp;
+
+      CHECK( findImpact (*tp, etaCalo(*pout->back()), phiCalo(*pout->back())) );
+      Etcone20(*pout->back()) = iso;
+    }
+  }
+
+  CHECK( evtStore()->record (std::move(pout), m_outputKey) );
+  CHECK( evtStore()->record (std::move(pout_aux), m_outputKey + "Aux.") );
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Test to see if we accept a particle.
+ * @param tp The particle to test.
+ * @param cont The container of particles.
+ * @param iso[out] The isolation energy for this particle.
+ */
+bool egammaTruthAlg::isAccepted (const xAOD::TruthParticle& tp,
+                                 const xAOD::TruthParticleContainer& cont,
+                                 float& iso)
+{
+  iso = -999;
+
+  int id = tp.pdgId();
+  int aid = abs(id);
+  int barcode = tp.barcode();
+
+  if (aid == abs(PDG::e_minus)) {
+    if (tp.pt() < m_electronPtMin) return false;
+  }
+  else if (aid == abs(PDG::gamma)) {
+    if (tp.pt() < m_photonPtMin) return false;
+  }
+  else
+    return false;
+
+  if (fabs(tp.eta()) > m_etaMax) return false;
+
+  if (!isGenStable (tp)) return false;
+  if (!isGenInteracting (tp)) return false;
+
+  // Remove electrons/gammas decaying into themselves
+  if( tp.hasDecayVtx() ) {
+    const xAOD::TruthVertex* v = tp.decayVtx();
+    size_t sz = v->nOutgoingParticles();
+    for (size_t i = 0; i < sz; i++) {
+      const xAOD::TruthParticle* child = v->outgoingParticle(i);
+      if( child->pdgId()==id && child->barcode()!=barcode
+          && (child->barcode() <100000 ))
+      {
+        return false;
+      }
+    }
+  } // end decays into themselves
+
+  // Isolation selection for photons.
+  iso = computeIso (tp, cont);
+  if (aid == abs(PDG::gamma)) {
+    if (iso > m_photonEtIsoMax)
+      return false;
+  }
+
+  return true;
+}
+
+
+/**
+ * @brief Compute isolation around a particle.
+ * @param tp The particle for which we want isolation.
+ * @param cont The container of particles.
+ */
+float egammaTruthAlg::computeIso (const xAOD::TruthParticle& tp,
+                                  const xAOD::TruthParticleContainer& cont)
+{
+  TLorentzVector sum;
+  for (const xAOD::TruthParticle* p : cont) {
+    if (p == &tp || p->barcode() == tp.barcode()) continue;
+    if (!isGenStable (*p)) continue;
+    if (!isGenInteracting (*p)) continue;
+    if (tp.p4().DeltaR (p->p4()) < m_isoCone)
+      sum += p->p4();
+  }
+
+  return sum.Pt();
+}
+
+
+/**
+ * @brief Find the impact of a particle in the calorimeter.
+ * @param p The particle to analyze.
+ * @param etaCalo[out] Eta of the particle's impact with the calorimeter.
+ * @param phiCalo[out] Phi of the particle's impact with the calorimeter.
+ */
+StatusCode egammaTruthAlg::findImpact (const xAOD::TruthParticle& tp,
+                                       float& etaCalo,
+                                       float& phiCalo)
+{
+  etaCalo = -999;
+  phiCalo = -999;
+
+  const xAOD::TruthVertex* pvtx = tp.hasProdVtx() ? tp.prodVtx() : 0;
+  if (pvtx) {
+    //create the perigee here
+
+    Amg::Vector3D pos (pvtx->x(),
+                       pvtx->y(),
+                       pvtx->z());
+    Amg::Vector3D mom (tp.px(),
+                       tp.py(),
+                       tp.pz());
+    
+    ImpactInCalo* imp = 0;
+
+    const HepPDT::ParticleDataTable* pdt = m_ppsvc->PDT();
+    const HepPDT::ParticleData* pd = pdt->particle (std::abs(tp.pdgId()));
+    float charge = pd ? pd->charge() : 0;
+    if (tp.pdgId() < 0)
+      charge = - charge;
+    if ( abs(tp.pdgId()) == abs(PDG::e_minus) ) {
+      Trk::Perigee candidatePerigee (pos, mom, charge, pos);
+      imp = m_extrap->getImpactInCalo (candidatePerigee,
+                                       Trk::nonInteracting);
+    }
+    else {
+      Trk::NeutralPerigee candidatePerigee (pos, mom, charge, pos);
+      imp = m_extrap->getImpactInCalo (candidatePerigee,
+                                       Trk::nonInteracting);
+    }
+
+    if (imp) {
+      etaCalo = imp->etaCaloLocal_2();
+      phiCalo = imp->phiCaloLocal_2();
+      delete imp;
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace D3PD
diff --git a/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTruthAlg.h b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTruthAlg.h
new file mode 100644
index 00000000000..865e6afbba7
--- /dev/null
+++ b/PhysicsAnalysis/D3PDMaker/egammaD3PDAnalysis/src/egammaTruthAlg.h
@@ -0,0 +1,124 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file egammaD3PDAnalysis/src/egammaTruthAlg.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jul, 2014
+ * @brief Select egtruth particles.
+ */
+
+
+#ifndef EGAMMAD3PDANALYSIS_EGAMMATRUTHALG_H
+#define EGAMMAD3PDANALYSIS_EGAMMATRUTHALG_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "xAODTruth/TruthParticle.h"
+#include "xAODTruth/TruthParticleContainer.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include <string>
+class IPartPropSvc;
+class IExtrapolateToCaloTool;
+
+
+namespace D3PD {
+
+
+/**
+ * @brief Select egtruth particles.
+ */
+class egammaTruthAlg
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Standard Gaudi algorithm constructor.
+   * @param name The algorithm name.
+   * @param svcloc The service locator.
+   */
+  egammaTruthAlg (const std::string& name,
+                  ISvcLocator* svcloc);
+
+
+  /// Standard Gaudi @c initialize method.
+  virtual StatusCode initialize() override;
+
+
+  /// Standard Gaudi @c execute method.
+  virtual StatusCode execute() override;
+
+
+private:
+  /**
+   * @brief Test to see if we accept a particle.
+   * @param tp The particle to test.
+   * @param cont The container of particles.
+   * @param iso[out] The isolation energy for this particle.
+   */
+  bool isAccepted (const xAOD::TruthParticle& tp,
+                   const xAOD::TruthParticleContainer& cont,
+                   float& iso);
+
+
+  /**
+   * @brief Compute isolation around a particle.
+   * @param tp The particle for which we want isolation.
+   * @param cont The container of particles.
+   */
+  float computeIso (const xAOD::TruthParticle& tp,
+                    const xAOD::TruthParticleContainer& cont);
+
+
+  /**
+   * @brief Find the impact of a particle in the calorimeter.
+   * @param p The particle to analyze.
+   * @param etaCalo[out] Eta of the particle's impact with the calorimeter.
+   * @param phiCalo[out] Phi of the particle's impact with the calorimeter.
+   */
+  StatusCode findImpact (const xAOD::TruthParticle& tp,
+                         float& etaCalo,
+                         float& phiCalo);
+
+
+  /// Property: Prefix to add to aux data items.
+  std::string m_auxPrefix;
+
+  /// Property: Name of the input container.
+  std::string m_inputKey;
+
+  /// Property: Name of the output container.
+  std::string m_outputKey;
+
+  /// Property: Minimum pt for electrons.
+  float m_electronPtMin;
+
+  /// Property: Minimum pt for photons.
+  float m_photonPtMin;
+
+  /// Property: Maximum eta.
+  float m_etaMax;
+
+  /// Property: Isolation cone width.
+  float m_isoCone;
+
+  /// Property: Maximum isolation cone energy allowed to keep a photon.
+  float m_photonEtIsoMax;
+
+  /// Property: Extrapolation tool to calorimeter.
+  ToolHandle<IExtrapolateToCaloTool> m_extrap;
+
+  /// Property: Particle property service.
+  ServiceHandle<IPartPropSvc> m_ppsvc;
+};
+
+
+} // namespace D3PD
+
+
+#endif // not EGAMMAD3PDANALYSIS_EGAMMATRUTHALG_H
-- 
GitLab