diff --git a/Reconstruction/Jet/JetRecConfig/CMakeLists.txt b/Reconstruction/Jet/JetRecConfig/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..18ea0632da48d38e9122f7c94643599a28416584
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/CMakeLists.txt
@@ -0,0 +1,16 @@
+################################################################################
+# Package: JetRecConfig
+################################################################################
+
+# Declare the package name:
+atlas_subdir( JetRecConfig )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs( PUBLIC
+                          GaudiKernel )
+
+# Install files from the package:
+atlas_install_python_modules( python/*.py )
+atlas_install_joboptions( share/*.py )
+atlas_install_joboptions( share/JetRec_jobOptions.py )
+
diff --git a/Reconstruction/Jet/JetRecConfig/cmt/requirements b/Reconstruction/Jet/JetRecConfig/cmt/requirements
new file mode 100644
index 0000000000000000000000000000000000000000..ef08a2e5541b14c0ea65d3144c92958c06a91ec4
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/cmt/requirements
@@ -0,0 +1,23 @@
+## automatically generated CMT requirements file
+package JetRecConfig
+author  elmsheus
+
+## for athena policies: this has to be the first use statement
+use AtlasPolicy 	AtlasPolicy-*
+
+## for gaudi tools, services and objects
+use GaudiInterface 	GaudiInterface-* 	External
+
+## put here your package dependencies...
+
+##
+branches src src/components doc python share
+
+## default is to make component library. See: https://twiki.cern.ch/twiki/bin/view/Main/LearningAthena#Libraries_in_CMT for alternatives
+#library JetRecConfig *.cxx components/*.cxx
+#apply_pattern component_library
+
+apply_pattern declare_joboptions files="*.py"
+apply_pattern declare_python_modules files="*.py"
+apply_pattern declare_joboptions files="JetRec_jobOptions.py"
+
diff --git a/Reconstruction/Jet/JetRecConfig/python/FastJetInterfaceConfig.py b/Reconstruction/Jet/JetRecConfig/python/FastJetInterfaceConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..d9641147035eca31a06e7ddc30c70eb43925bc47
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/python/FastJetInterfaceConfig.py
@@ -0,0 +1,174 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+
+from AthenaCommon.SystemOfUnits import *
+from AthenaCommon.Logging import logging
+
+from JetRec.JetRecConf import FastJetInterfaceTool
+
+_fastjetLog = logging.getLogger("FastJetInterfaceConfiguration")
+
+# set up some enumerator values
+def enums(name='Enum',**enums):
+    return type( name, (), enums)
+
+# recognized keys
+fastjet_conf_tags = enums('FastJetConfTags',
+                          Strategy=[ 'default', 'Best', 
+                                     'N2MinHeapTiled','N2Tiled', 'N2PoorTiled', 'N2Plain',
+                                     'N3Dumb', 
+                                     'NlnN', 'NlnN3pi', 'NlnN4pi', 'NlnNCam4pi', 'NlnNCam2pi2R', 'NlNCam',
+                                     'plugin_strategy' ],
+                          RecombScheme = [ 'default', 'E', 'pt', 'pt2', 'Et', 'Et2', 'BIpt', 'BIpt2' ],
+                          Algorithm   = [ 'default', 'kt', 'Kt', 'anti-kt', 'AntiKt', 'cambridge', 'CamKt',
+                                          'genkt', 'passive cambridge', 'passive genkt',
+                                          'CMSCone', 'SISCone'],
+                          JetAreaMethod = [ 'default', 'VoronoiArea', 'ActiveArea', 
+                                            'ActiveAreaExplicitGhost', 'PassiveArea', '1GhostPassiveArea' ],
+                          SISSplitMergeScale = [ 'default', 'pttilde', 'PtTilde', 'Pt', 'Et', 'mt' ], 
+                          )
+
+# Ghosted area parameters
+fastjet_gas = enums('FastJetGhostAreaSettings',
+                    def_ghost_maxrap  = 6.0,   #fastjet::gas::def_ghost_maxrap
+                    def_repeat        = 1,     #fastjet::gas::def_repeat
+                    def_ghost_area    = 0.01,  #fastjet::gas::def_ghost_area
+                    def_grid_scatter  = 1.0,   #fastjet::gas::def_grid_scatter
+                    def_kt_scatter    = 0.1,   #fastjet::gas::def_kt_scatter
+                    def_mean_ghost_kt = 1e-100,#fastjet::gas::def_mean_ghost_kt
+    )
+
+# ignored keys
+config_ignored_keys = enums('SetupIgnoredKeys',
+                            ControlKeys = ["_alreadyChecked_","_locked_","_ignoreUnknown_" ])
+
+# Default FastJet configuration dictionary: 
+#
+# Most keys are the same as the corresponding FastJet tags or enumerator names.
+# In addition, for backward compatibility, the following tags are recognized:
+#
+#  
+defFastJetInterfaceConfigDict = {
+    # -- overall setup and process control
+    'Algorithm'               : "anti-kt",
+    'JetAreaMethod'           : "VoronoiArea",
+    'CalculateJetArea'        : False,
+    # -- kt-style parameters
+    'Strategy'                : "Best",
+    'RecombScheme'            : "E",
+    # -- CMS cone parameters
+    'CMS_SeedThreshold'       : 15.*GeV,
+    # -- SIS cone parameters
+    'SIS_OverlapThreshold'    : 0.75,
+    'SIS_NumPassMax'          : 0,
+    'SIS_ProtojetPtMin'       : 0.0,
+    'SIS_DoCaching'           : False,
+    'SIS_SplitMergeScale'     : 'PtTilde',
+    'SIS_SplitMergeStopScale' : 0.0,
+    # -- jet algorithm parameters
+    'Radius'                  : 0.4,       # ATLAS default
+    'Inclusive'               : True,      # ATLAS default
+    'InclusivePtMin'          : 0.*GeV,
+    'ExclusiveDcut'           : 0.5,       
+    'ExclusiveNjets'          : 3,
+    # -- jet area calculation directives and parameters
+    'VoronoiEffectiveRfact'   : 1.0,   # Voronoi
+    'GhostMaxRapidity'        : fastjet_gas.def_ghost_maxrap,   
+    'GhostMinRapidity'        : -fastjet_gas.def_ghost_maxrap,   
+    'GhostRepeats'            : fastjet_gas.def_repeat,
+    'GhostAreaSize'           : fastjet_gas.def_ghost_area,
+    'GhostGridScatter'        : fastjet_gas.def_grid_scatter,
+    'GhostKtScatter'          : fastjet_gas.def_kt_scatter,
+    'GhostMeanKt'             : fastjet_gas.def_mean_ghost_kt
+    }
+
+# Check whole dictionary or key/value assigments and return dictionary with
+# invalid options stripped (if allowed) or exception thrown for invalid options
+def checkAndUpdate(**options):
+    # already checked
+    if options.get("_alreadyChecked_",False) or options.get("_locked_",False):
+        return options
+
+    # check what to do with unknowns
+    ignoreUnknown = options.pop("_ignoreUnknown_",False)
+
+    # check every entry
+    for k in options.keys():
+        if k not in defFastJetInterfaceConfigDict :
+            if ignoreUnknown :
+                _fastjetLog.warning("Option %s unknown - ignoring it!"%(k))
+                options.pop(k)
+            else :
+                _fastjetLog.error("Option %s unknown - abort configuration!"%(k))
+                raise Exception
+
+    checkedOptions = dict(defFastJetInterfaceConfigDict)
+    for k,v in defFastJetInterfaceConfigDict.iteritems():
+        t = type(v)
+        if t in ( list, set, dict ) :
+            checkedOptions[k] = t(v)
+
+    checkedOptions['_alreadyChecked_'] = True
+    checkedOptions.update(options)
+
+    # check settings for Strategy
+    key = "Strategy"
+    #    print checkedOptions
+    tag = checkedOptions[key]
+    _fastjetLog.info("Test option %s",key)
+    if checkedOptions[key] not in fastjet_conf_tags.Strategy :
+        _fastjetLog.error("Strategy \042%s\042 not recognized - fatal! Allowed values are: ",checkedOptions['Strategy'])
+        for s in fastjet_conf_tags.Strategy :
+            _fastjetLog.error("\042%s\042",s)
+        raise Exception
+    
+    # check settings for RecombScheme
+    if checkedOptions['RecombScheme'] not in fastjet_conf_tags.RecombScheme :
+        _fastjetLog.error("RecombScheme \042%s\042 not recognized - fatal! Allowed values are: ",checkedOptions['RecombScheme'])
+        for s in fastjet_conf_tags.RecombScheme :
+            _fastjetLog.error("\042%s\042",s)
+        raise Exception
+    
+    # check settings for Algorithm
+    if checkedOptions['Algorithm'] not in fastjet_conf_tags.Algorithm :
+        _fastjetLog.error("Algorithm \042%s\042 not recognized - fatal! Allowed values are: ",checkedOptions['Algorithm'])
+        for s in fastjet_conf_tags.Algorithm :
+            _fastjetLog.error("\042%%s\042",s)
+        raise Exception
+
+    # check settings for JetAreaMethod
+    if checkedOptions['JetAreaMethod'] not in fastjet_conf_tags.JetAreaMethod :
+        _fastjetLog.error("JetAreaMethod \042%s\042 not recognized - fatal! Allowed values are: ",checkedOptions['JetAreaMethod'])
+        for s in fastjet_conf_tags.JetAreaMethod :
+            _fastjetLog.error("\042%s\042",s)
+        raise Exception
+
+    # check settings for SIS split merge scale
+    if checkedOptions['SIS_SplitMergeScale'] not in fastjet_conf_tags.SISSplitMergeScale :
+      _fastjetLog.error("SIS_SplitMergeScale \042%2\042 not recognized - fatal! Allowed values are: ",checkedOptions['SIS_SplitMergeScale'])
+      for s in fastjet_conf_tags.SISSplitMergeScale :
+        _fastjetLog.error("\042%s\042",s)
+      raise Exception
+
+    return checkedOptions
+            
+
+def getFastJetInterfaceConfig(name,**options):
+    # get tool configuration 
+    fjTool = FastJetInterfaceTool(name)
+    from AthenaCommon.AppMgr import ToolSvc
+    ToolSvc += fjTool
+    # check job options
+    options = checkAndUpdate(**options)    
+    # set tool properties
+    for k,v in options.iteritems():
+        if k not in config_ignored_keys.ControlKeys :
+            setattr(fjTool,k,v)
+    # return tool configuration object
+    return fjTool
+
+#def dumpFastJetInterfaceConfig(**options=**defFastJetInterfaceConfigDict):
+#    # write out all attributes
+#    for k,v in options.iteritems():
+#        _fastjetLog.message("Config::%s value %s",%(k),%(v))
+    
diff --git a/Reconstruction/Jet/JetRecConfig/python/JetAlgorithm.py b/Reconstruction/Jet/JetRecConfig/python/JetAlgorithm.py
new file mode 100644
index 0000000000000000000000000000000000000000..125c929be32e3f8746f535138a8134925803d42f
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/python/JetAlgorithm.py
@@ -0,0 +1,129 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# JetAlgorithm.py
+#
+# David Adams
+# March 2014
+# October 2014: Update to provide a fn that allow specification of alg sequence.
+#
+# Configure the jet algorithm after the tool manager has been configured.
+
+# Record the jet algorithm here.
+# Retrieve this with "from JetRecConfig.JetAlgorithm import jetalg" *after*
+# calling addJetRecoToAlgSequence().
+jetalg = None
+
+# Function to add jet reconstruction to an algorithm sequence
+#               job: algorithm sequence
+#          useTruth: Flag to schedule building of selected-truth containers
+#   eventShapeTools: Keys for the event shape tools to be run
+#   separateJetAlgs: Run JetRecTools in separate algs (experts only)
+#             debug: Debug level (0 for quiet). See below.
+def addJetRecoToAlgSequence(job =None, useTruth =None, eventShapeTools =None,
+                            separateJetAlgs= None, debug =None):
+
+  myname = "JetAlgorithm: "
+
+  # We need this to modify the global variable.
+  global jetalg
+
+  # Import message level flags.
+  from GaudiKernel.Constants import DEBUG
+
+  # Import the jet reconstruction control flags.
+  from JetRecFlags import jetFlags
+
+  # Import the standard jet tool manager.
+  from JetRecStandardToolManager import jtm
+
+  # Set sequence and flags as needed.
+  if job == None:
+    from AthenaCommon.AlgSequence import AlgSequence
+    job = AlgSequence()
+  if useTruth == None:
+    useTruth = jetFlags.useTruth()
+  if eventShapeTools == None:
+    eventShapeTools = jetFlags.eventShapeTools()
+    if eventShapeTools == None:
+      eventShapeTools = []
+  if separateJetAlgs == None:
+    separateJetAlgs = jetFlags.separateJetAlgs()
+
+
+  # Event shape tools.
+  evstools = []
+  evsDict = {
+    "emtopo"   : ("EMTopoEventShape",   jtm.emget),
+    "lctopo"   : ("LCTopoEventShape",   jtm.lcget),
+    "empflow"  : ("EMPFlowEventShape",  jtm.empflowget),
+    "emcpflow" : ("EMCPFlowEventShape", jtm.emcpflowget),
+    "lcpflow"  : ("LCPFlowEventShape",  jtm.lcpflowget),
+  }
+  print myname + "Event shape tools: " + str(eventShapeTools)
+  for evskey in eventShapeTools:
+    from EventShapeTools.EventDensityConfig import configEventDensityTool
+    if evskey in evsDict:
+      (toolname, getter) = evsDict[evskey]
+      if toolname in jtm.tools:
+        print myname + "Skipping duplicate event shape: " + toolname
+      else:
+        print myname + "Adding event shape " + evskey
+        jtm += configEventDensityTool(toolname, getter, 0.4)
+        evstools += [jtm.tools[toolname]]
+    else:
+      print myname + "Invalid event shape key: " + evskey
+      raise Exception
+
+  # Add the tool runner. It runs the jetrec tools.
+  rtools = []
+  # Add the truth tools.
+  if useTruth:    
+    from JetFlavorAlgs import scheduleCopyTruthParticles
+    rtools += scheduleCopyTruthParticles()
+    
+    # build truth jet input :
+    rtools += [ jtm.truthpartcopy, jtm.truthpartcopywz ]
+
+  ## if jetFlags.useCells():
+  ##   rtools += [jtm.missingcells] commented out : incompatible with trigger : ATR-9696
+  if jetFlags.useTracks:
+    rtools += [jtm.tracksel]
+    rtools += [jtm.tvassoc]
+    rtools += [jtm.trackselloose_trackjets]
+  rtools += jtm.jetrecs
+  from JetRec.JetRecConf import JetToolRunner
+  jtm += JetToolRunner("jetrun",
+           EventShapeTools=evstools,
+           Tools=rtools,
+           Timer=jetFlags.timeJetToolRunner()
+         )
+  jetrun = jtm.jetrun
+
+  # Add the algorithm. It runs the jetrec tools.
+  from JetRec.JetRecConf import JetAlgorithm
+
+  if jetFlags.separateJetAlgs():
+    job += JetAlgorithm("jetalg")
+    jetalg = job.jetalg
+    jetalg.Tools = [jtm.jetrun]
+    for t in rtools:
+      jalg = JetAlgorithm("jetalg"+t.name())
+      jalg.Tools = [t]
+      job+= jalg
+
+  else:
+    job += JetAlgorithm("jetalg")
+    jetalg = job.jetalg
+    jetalg.Tools = [jtm.jetrun]
+    if jetFlags.debug > 0:
+      jtm.setOutputLevel(jtm.jetrun, DEBUG)
+      jetalg.OutputLevel = DEBUG
+    if jetFlags.debug > 1:
+      for tool in jtm.jetrecs:
+        jtm.setOutputLevel(tool, DEBUG)
+    if jetFlags.debug > 2:
+      for tool in jtm.finders:
+        jtm.setOutputLevel(tool, DEBUG)
+    if jetFlags.debug > 3:
+      jtm.setOutputLevel(jtm.jetBuilderWithArea, DEBUG)
+      jtm.setOutputLevel(jtm.jetBuilderWithoutArea, DEBUG)
diff --git a/Reconstruction/Jet/JetRecConfig/python/JetFlavorAlgs.py b/Reconstruction/Jet/JetRecConfig/python/JetFlavorAlgs.py
new file mode 100644
index 0000000000000000000000000000000000000000..750d9c8844bee303c3d041a662e6954f3d6fc2fb
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/python/JetFlavorAlgs.py
@@ -0,0 +1,46 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# JetFlavorAlgs.py
+#
+# David Adams
+# September 2014
+
+# Import the jet reconstruction control flags.
+from JetRecFlags import jetFlags
+
+print str(jetFlags.truthFlavorTags())
+
+def scheduleCopyTruthParticles():
+  myname = "scheduleCopyTruthParticles: "
+  from JetRecStandardToolManager import jtm
+  if not jtm.haveParticleJetTools: return
+  from ParticleJetTools.ParticleJetToolsConf import CopyFlavorLabelTruthParticles
+  from ParticleJetTools.ParticleJetToolsConf import CopyBosonTopLabelTruthParticles
+  from ParticleJetTools.ParticleJetToolsConf import CopyTruthPartons
+  from ParticleJetTools.CopyTruthParticlesAlg import CopyTruthParticlesAlg
+
+  tools = []
+  for ptype in jetFlags.truthFlavorTags():
+    toolname = "CopyTruthTag" + ptype
+    if toolname in jtm.tools:
+      print myname + "Skipping previously-defined tool: " + toolname
+      print jtm.tools[toolname]
+    else:
+      print myname + "Scheduling " + toolname
+      ptmin = 5000
+      if ptype == "Partons":
+        ctp = CopyTruthPartons(toolname)
+      elif ptype in ["WBosons", "ZBosons", "HBosons", "TQuarksFinal"]:
+        ctp = CopyBosonTopLabelTruthParticles(toolname)
+        ctp.ParticleType = ptype
+        ptmin = 100000
+      else:
+        ctp = CopyFlavorLabelTruthParticles(toolname)
+        ctp.ParticleType = ptype
+      ctp.OutputName = "TruthLabel" + ptype
+      ctp.PtMin = ptmin
+      jtm += ctp
+      #theJob += CopyTruthParticlesAlg(ctp, toolname + "Alg")
+      print ctp
+      tools.append( ctp )
+  return tools
diff --git a/Reconstruction/Jet/JetRecConfig/python/JetRecCalibrationFinder.py b/Reconstruction/Jet/JetRecConfig/python/JetRecCalibrationFinder.py
new file mode 100644
index 0000000000000000000000000000000000000000..7577fc1706fa142e9fabcc374325b166106d0a5c
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/python/JetRecCalibrationFinder.py
@@ -0,0 +1,114 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# JetRecCalibrationFinder.py
+
+# David Adams
+# September 2014
+#
+# Class to retrieve the calibration tool for a given jet definition
+# and calibration sequence.  The calibration tool is created if it
+# does not already exist.
+#
+# Usage:
+#   from JetRec.JetRecCalibrationFinder import jrcf
+#   tool = jrcf.find(alg, rad, inp, seq, con)
+#
+# Arguments:
+#   alg - Algorithm name: AntiKt, CamKt or Kt
+#   rad - Jet size parameter, e.g. 0.4
+#   inp - Input type: EMTopo or LCTopo
+#   seq - Calibration sequence as one letter for each step, e.g. "ar"
+#            a = Active area correction (rho*A)
+#            r = Pileup residual correction (i.e. using mu and NPV)
+#            j = JES correction (from MC)
+#            g = GSC correction (from MC)
+#            i = Insitu correction (data only)
+#   con - Configuration file name or entry in jrcf.configDict
+#
+# To add to the confid dictionary:
+#   jrcf.configDict["myname"] = "someConfigFile.config"
+
+class JetRecCalibrationFinder:
+    
+  # Dictionary of calibrations steps.
+  calibStep = {
+    "a":"JetArea",
+    "r":"Residual",
+    "o":"Origin",
+    "j":"AbsoluteEtaJES",
+    "g":"GSC",
+    "i":"Insitu"
+  }
+    
+  # Dictionary for calibration configurations.
+  configDict = {
+    "reco"            : "JES_Full2012dataset_Preliminary_Jan13.config",
+    "trigger"         : "JES_Full2012dataset_Preliminary_Trigger.config",
+    "triggerNoPileup" : "JES_Full2012dataset_Preliminary_Trigger_NoPileup.config",
+    "pflow"           : "PFlowJES_September2014.config"
+  }
+
+  def find(self, alg, rad, inpin, seq, configkeyin, evsprefix):
+    from JetCalibTools.JetCalibToolsConf import JetCalibrationTool
+    from JetRecStandardToolManager import jtm
+    inp = inpin
+    # Find the configuration file.
+    configkey = configkeyin
+    if configkey == "": configkey = "reco"
+    if configkey in self.configDict:
+      configfile = self.configDict[configkey]
+    else:
+      configfile = configkey
+    # Assign name for tool
+    jetdefn = alg + str(int(10*rad+0.1)) + inp
+    tname = "calib_" + jetdefn + "_" + configkey.replace(".","_") + "_" + seq
+    # Display configuration.
+    myname = "JetRecCalibrationFinder:find: "
+    print myname + "Building jet calibration tool."
+    print myname + "  Arguments:"
+    print myname + "    alg: " + str(alg)
+    print myname + "    rad: " + str(rad)
+    print myname + "    inp: " + str(inp)
+    print myname + "    seq: " + str(seq)
+    print myname + "  Jet definition: " + jetdefn
+    print myname + "  Configuration file: " + configfile
+
+    if tname in jtm.tools:
+      print myname + "  Skipping previously-defined tool: " + tname
+    else:
+      # build calib tool
+      print myname + "  Creating " + tname
+      # ...define calbration sequence
+      try:
+        fullseq = [self.calibStep[l] for l in seq] # translate letters
+      except KeyError as err:
+        print myname + "  ERROR Invalid sequence: " + seq
+        print myname + "  ERROR Unknown sequence key: " + err.message
+        raise err
+      fullseq = '_'.join(fullseq)  # join seq names with a '_'
+      print myname + "  Calibration sequence: " + fullseq
+      # ...define the key for the event shape container
+      if   inpin == "EMTopo":
+        evssuf="EMTopoEventShape"
+      elif inpin == "LCTopo":
+        evssuf="LCTopoEventShape"
+      elif inpin == "EMPFlow":
+        evssuf="EMPFlowEventShape"
+      elif inpin == "EMCPFlow":
+        evssuf="EMCPFlowEventShape"
+      elif inpin == "LCPFlow":
+        evssuf="LCPFlowEventShape"
+      else:
+        evssuf="INVALID"
+        print myname + "  ERROR: Invalid input specifier: " + inp
+        raise KeyError
+      evskey = evsprefix + evssuf
+      print myname + "  Event shape key: " + evskey
+      # ...create the tool.
+      jtm += JetCalibrationTool(tname, JetCollection=jetdefn, ConfigFile=configfile, CalibSequence=fullseq, RhoKey=evskey)
+
+    return jtm.tools[tname]
+
+# This is the only instance of the above class that should be used to
+# that should be used to fetch calibration tools.
+jrcf = JetRecCalibrationFinder()
diff --git a/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py b/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..ec6c44ccb85e7184aaa9f454c731f7e850d10291
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py
@@ -0,0 +1,712 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# JetRecStandardTools.py
+#
+# David Adams
+# March 2014
+#
+# Define the low-level tools used in jet reconstruction.
+#
+# Tools are configured and put in the global jet tool manager so
+# they can be accessed when configuring JetRec tools.
+#
+# Execute this file to add the definitions to
+# JetRecStandardToolManager.jtm, e.g.
+#   import JetRecConfig.JetRecStandardTools
+
+# Import the jet flags.
+# from JetRecFlags import jetFlags
+
+# if not "UseTriggerStore " in locals():
+#   UseTriggerStore = False
+
+# # get levels defined VERBOSE=1 etc.
+# from GaudiKernel.Constants import *
+
+# from eflowRec.eflowRecFlags import jobproperties
+
+# from JetRecStandardToolManager import jtm
+# from InDetTrackSelectionTool.InDetTrackSelectionToolConf import InDet__InDetTrackSelectionTool
+# from MCTruthClassifier.MCTruthClassifierConf import MCTruthClassifier
+
+# from PFlowUtils.PFlowUtilsConf import CP__RetrievePFOTool as RetrievePFOTool
+# from JetRecTools.JetRecToolsConf import TrackPseudoJetGetter
+# from JetRecTools.JetRecToolsConf import JetTrackSelectionTool
+# from JetRecTools.JetRecToolsConf import SimpleJetTrackSelectionTool
+# from JetRecTools.JetRecToolsConf import TrackVertexAssociationTool
+# try:
+#   from JetRecCalo.JetRecCaloConf import MissingCellListTool
+#   jtm.haveJetRecCalo = True
+# except ImportError:
+#   jtm.haveJetRecCalo = False
+# from JetRecTools.JetRecToolsConf import PFlowPseudoJetGetter
+# from JetRec.JetRecConf import JetPseudojetRetriever
+# from JetRec.JetRecConf import JetConstituentsRetriever
+# from JetRec.JetRecConf import JetRecTool
+# from JetRec.JetRecConf import PseudoJetGetter
+# from JetRec.JetRecConf import MuonSegmentPseudoJetGetter
+# from JetRec.JetRecConf import JetFromPseudojet
+# from JetRec.JetRecConf import JetConstitRemover
+# from JetRec.JetRecConf import JetSorter
+# from JetMomentTools.JetMomentToolsConf import JetCaloQualityTool
+# try:
+#   from JetMomentTools.JetMomentToolsConf import JetCaloCellQualityTool
+#   jtm.haveJetCaloCellQualityTool = True
+# except ImportError:
+#   jtm.haveJetCaloCellQualityTool = False
+# from JetMomentTools.JetMomentToolsConf import JetWidthTool
+# from JetMomentTools.JetMomentToolsConf import JetCaloEnergies
+# try:
+#   from JetMomentTools.JetMomentToolsConf import JetJetBadChanCorrTool
+#   jtm.haveJetBadChanCorrTool = True
+# except ImportError:
+#   jtm.haveJetBadChanCorrTool = False
+# from JetMomentTools.JetMomentToolsConf import JetECPSFractionTool
+# from JetMomentTools.JetMomentToolsConf import JetVertexFractionTool
+# from JetMomentTools.JetMomentToolsConf import JetVertexTaggerTool
+# from JetMomentTools.JetMomentToolsConf import JetTrackMomentsTool
+# from JetMomentTools.JetMomentToolsConf import JetTrackSumMomentsTool
+# from JetMomentTools.JetMomentToolsConf import JetClusterMomentsTool
+# from JetMomentTools.JetMomentToolsConf import JetVoronoiMomentsTool
+# from JetMomentTools.JetMomentToolsConf import JetIsolationTool
+# from JetMomentTools.JetMomentToolsConf import JetLArHVTool
+# from JetMomentTools.JetMomentToolsConf import JetOriginCorrectionTool
+# from JetSubStructureMomentTools.JetSubStructureMomentToolsConf import KtDeltaRTool
+# from JetSubStructureMomentTools.JetSubStructureMomentToolsConf import NSubjettinessTool
+# from JetSubStructureMomentTools.JetSubStructureMomentToolsConf import KTSplittingScaleTool
+# from JetSubStructureMomentTools.JetSubStructureMomentToolsConf import AngularityTool
+# from JetSubStructureMomentTools.JetSubStructureMomentToolsConf import DipolarityTool
+# from JetSubStructureMomentTools.JetSubStructureMomentToolsConf import PlanarFlowTool
+# from JetSubStructureMomentTools.JetSubStructureMomentToolsConf import KtMassDropTool
+# from JetSubStructureMomentTools.JetSubStructureMomentToolsConf import EnergyCorrelatorTool
+# from JetSubStructureMomentTools.JetSubStructureMomentToolsConf import CenterOfMassShapesTool
+# from JetSubStructureMomentTools.JetSubStructureMomentToolsConf import JetPullTool
+# from JetSubStructureMomentTools.JetSubStructureMomentToolsConf import JetChargeTool
+# try:
+#   from JetSubStructureMomentTools.JetSubStructureMomentToolsConf import ShowerDeconstructionTool
+#   jtm.haveShowerDeconstructionTool = True
+# except ImportError:
+#   jtm.haveShowerDeconstructionTool = False
+# try:
+#   from ParticleJetTools.ParticleJetToolsConf import Analysis__JetQuarkLabel
+#   jtm.haveParticleJetTools = True
+# except:
+#   jtm.haveParticleJetTools = False
+# if jtm.haveParticleJetTools:
+#   from ParticleJetTools.ParticleJetToolsConf import Analysis__JetConeLabeling
+#   from ParticleJetTools.ParticleJetToolsConf import Analysis__JetPartonTruthLabel
+#   from ParticleJetTools.ParticleJetToolsConf import CopyTruthJetParticles
+#   from ParticleJetTools.ParticleJetToolsConf import ParticleJetDeltaRLabelTool
+
+# #--------------------------------------------------------------
+# # Track selection.
+# #--------------------------------------------------------------
+
+# # This is the InDet loose selection from
+# # https://twiki.cern.ch/twiki/bin/view/AtlasProtected/InDetTrackingPerformanceGuidelines
+# # October 28, 2014
+# #jtm += InDet__InDetDetailedTrackSelectionTool(
+# jtm += InDet__InDetTrackSelectionTool(
+#   "trk_trackselloose",
+#   minPt                = 400.0,
+#   maxAbsEta            = 2.5,
+#   minNSiHits           = 7,
+#   maxNPixelSharedHits  = 1,
+#   maxOneSharedModule   = True,
+#   maxNSiHoles          = 2,
+#   maxNPixelHoles       = 1,
+# )
+
+# jtm += JetTrackSelectionTool(
+#   "trackselloose",
+#   InputContainer  = jtm.trackContainer,
+#   OutputContainer = "JetSelectedTracks",
+#   Selector        = jtm.trk_trackselloose
+# )
+
+# jtm += InDet__InDetTrackSelectionTool(
+#   "trk_trackselloose_trackjets",
+#   CutLevel                = "Loose"
+# )
+
+# jtm += JetTrackSelectionTool(
+#    "trackselloose_trackjets",
+#   InputContainer  = jtm.trackContainer,
+#   OutputContainer = "JetSelectedTracks_LooseTrackJets",
+#   Selector        = jtm.trk_trackselloose_trackjets
+# )
+
+# if jetFlags.useInDetTrackSelection():
+#   jtm += JetTrackSelectionTool(
+#     "tracksel",
+#     InputContainer  = jtm.trackContainer,
+#     OutputContainer = "JetSelectedTracks",
+#     Selector        = jtm.trk_trackselloose
+#   )
+# else:
+#   jtm += SimpleJetTrackSelectionTool(
+#     "tracksel",
+#     PtMin = 500.0,
+#     InputContainer  = jtm.trackContainer,
+#     OutputContainer = "JetSelectedTracks",
+#   )
+
+# #--------------------------------------------------------------
+# # Track-vertex association.
+# #--------------------------------------------------------------
+# from TrackVertexAssociationTool.TrackVertexAssociationToolConf import CP__TightTrackVertexAssociationTool
+# jtm += CP__TightTrackVertexAssociationTool("jetTighTVAtool", dzSinTheta_cut=3, doPV=True)
+
+# jtm += TrackVertexAssociationTool(
+#   "tvassoc",
+#   TrackParticleContainer  = jtm.trackContainer,
+#   TrackVertexAssociation  = "JetTrackVtxAssoc",
+#   VertexContainer         = jtm.vertexContainer,
+#   TrackVertexAssoTool     = jtm.jetTighTVAtool,
+# )
+
+# jtm += TrackVertexAssociationTool(
+#   "tvassoc_old",
+#   TrackParticleContainer  = jtm.trackContainer,
+#   TrackVertexAssociation  = "JetTrackVtxAssoc_old",
+#   VertexContainer         = jtm.vertexContainer,
+#   MaxTransverseDistance   = 1.5,
+#   MaxLongitudinalDistance = 1.0e7,
+#   MaxZ0SinTheta = 1.5
+# )
+
+# #--------------------------------------------------------------
+# # Truth selection.
+# #--------------------------------------------------------------
+
+# if jetFlags.useTruth:
+#     truthClassifier = MCTruthClassifier(name = "JetMCTruthClassifier",
+#                                        ParticleCaloExtensionTool="")
+#     jtm += truthClassifier
+
+#     jtm += CopyTruthJetParticles("truthpartcopy", OutputName="JetInputTruthParticles",
+#                                  MCTruthClassifier=truthClassifier)
+#     jtm += CopyTruthJetParticles("truthpartcopywz", OutputName="JetInputTruthParticlesNoWZ",
+#                                  MCTruthClassifier=truthClassifier,
+#                                  IncludeWZLeptons=False, #IncludeTauLeptons=False,
+#                                  IncludeMuons=True,IncludeNeutrinos=True)
+
+
+# #--------------------------------------------------------------
+# # Jet reco infrastructure.
+# #--------------------------------------------------------------
+
+# # Jet pseudojet retriever.
+# jtm += JetPseudojetRetriever("jpjretriever")
+
+# # Jet constituent retriever.
+# labs = []
+# if jetFlags.useTracks():
+#   labs += ["Track"]
+#   labs += ["AntiKt3TrackJet", "AntiKt3TrackJet"]
+# if jetFlags.useMuonSegments():
+#   labs += ["MuonSegment",]
+# if jetFlags.useTruth():
+#   labs += ["Truth"]
+#   for lab in jetFlags.truthFlavorTags():
+#     labs += [lab]
+# jtm += JetConstituentsRetriever(
+#   "jconretriever",
+#   UsePseudojet = True,
+#   UseJetConstituents = True,
+#   PseudojetRetriever = jtm.jpjretriever,
+#   GhostLabels = labs,
+#   GhostScale = 1.e-20
+# )
+
+# #--------------------------------------------------------------
+# # Pseudojet builders.
+# #--------------------------------------------------------------
+
+# # Clusters.
+# jtm += PseudoJetGetter(
+#   "lcget",
+#   InputContainer = "CaloCalTopoClusters",
+#   Label = "LCTopo",
+#   OutputContainer = "PseudoJetLCTopo",
+#   SkipNegativeEnergy = True,
+#   GhostScale = 0.0
+# )
+
+# # EM clusters.
+# jtm += PseudoJetGetter(
+#   "emget",
+#   InputContainer = "CaloCalTopoClusters",
+#   Label = "EMTopo",
+#   OutputContainer = "PseudoJetEMTopo",
+#   SkipNegativeEnergy = True,
+#   GhostScale = 0.0
+# )
+
+# # Tracks.
+# jtm += TrackPseudoJetGetter(
+#   "trackget",
+#   InputContainer = jtm.trackselloose_trackjets.OutputContainer,
+#   Label = "Track",
+#   OutputContainer = "PseudoJetTracks",
+#   TrackVertexAssociation = jtm.tvassoc.TrackVertexAssociation,
+#   SkipNegativeEnergy = True,
+#   GhostScale = 0.0
+# )
+
+# # Ghost tracks.
+# jtm += TrackPseudoJetGetter(
+#   "gtrackget",
+#   InputContainer = jtm.tracksel.OutputContainer,
+#   Label = "GhostTrack",
+#   OutputContainer = "PseudoJetGhostTracks",
+#   TrackVertexAssociation = jtm.tvassoc.TrackVertexAssociation,
+#   SkipNegativeEnergy = True,
+#   GhostScale = 1e-20
+# )
+
+# # Muon segments
+# jtm += MuonSegmentPseudoJetGetter(
+#   "gmusegget",
+#   InputContainer = "MuonSegments",
+#   Label = "GhostMuonSegment",
+#   OutputContainer = "PseudoJetGhostMuonSegment",
+#   Pt = 1.e-20
+# )
+
+# # Retriever for pflow objects.
+# jtm += RetrievePFOTool("pflowretriever")
+
+# useVertices = True
+# if False == jetFlags.useVertices:
+#   useVertices = False
+
+# if True == jobproperties.eflowRecFlags.useUpdated2015ChargedShowerSubtraction:
+#   useChargedWeights = True
+# else:
+#   useChargedWeights = False
+
+# useTrackVertexTool = False
+# if True == jetFlags.useTrackVertexTool:
+#   useTrackVertexTool = True
+
+# # EM-scale pflow.
+# jtm += PFlowPseudoJetGetter(
+#   "empflowget",
+#   Label = "EMPFlow",
+#   OutputContainer = "PseudoJetEMPFlow",
+#   RetrievePFOTool = jtm.pflowretriever,
+#   InputIsEM = True,
+#   CalibratePFO = False,
+#   SkipNegativeEnergy = True,
+#   UseChargedWeights = useChargedWeights,
+#   UseVertices = useVertices,
+#   UseTrackToVertexTool = useTrackVertexTool
+# )
+
+# # Calibrated EM-scale pflow.
+# jtm += PFlowPseudoJetGetter(
+#   "emcpflowget",
+#   Label = "EMCPFlow",
+#   OutputContainer = "PseudoJetEMCPFlow",
+#   RetrievePFOTool = jtm.pflowretriever,
+#   InputIsEM = True,
+#   CalibratePFO = True,
+#   SkipNegativeEnergy = True,
+#   UseChargedWeights = useChargedWeights,
+#   UseVertices = useVertices,
+#   UseTrackToVertexTool = useTrackVertexTool
+# )
+
+# # LC-scale pflow.
+# jtm += PFlowPseudoJetGetter(
+#   "lcpflowget",
+#   Label = "LCPFlow",
+#   OutputContainer = "PseudoJetLCPFlow",
+#   RetrievePFOTool = jtm.pflowretriever,
+#   InputIsEM = False,
+#   CalibratePFO = False,
+#   SkipNegativeEnergy = True,
+#   UseChargedWeights = useChargedWeights,
+#   UseVertices = useVertices,
+#   UseTrackToVertexTool = useTrackVertexTool
+# )
+
+# # AntiKt2 track jets.
+# jtm += PseudoJetGetter(
+#   "gakt2trackget", # give a unique name
+#   InputContainer = jetFlags.containerNamePrefix() + "AntiKt2PV0TrackJets", # SG key
+#   Label = "GhostAntiKt2TrackJet",   # this is the name you'll use to retrieve associated ghosts
+#   OutputContainer = "PseudoJetGhostAntiKt2TrackJet",
+#   SkipNegativeEnergy = True,
+#   GhostScale = 1.e-20,   # This makes the PseudoJet Ghosts, and thus the reco flow will treat them as so.
+# )
+
+# # AntiKt3 track jets.
+# jtm += PseudoJetGetter(
+#   "gakt3trackget", # give a unique name
+#   InputContainer = jetFlags.containerNamePrefix() + "AntiKt3PV0TrackJets", # SG key
+#   Label = "GhostAntiKt3TrackJet",   # this is the name you'll use to retrieve associated ghosts
+#   OutputContainer = "PseudoJetGhostAntiKt3TrackJet",
+#   SkipNegativeEnergy = True,
+#   GhostScale = 1.e-20,   # This makes the PseudoJet Ghosts, and thus the reco flow will treat them as so.
+# )
+
+# # AntiKt4 track jets.
+# jtm += PseudoJetGetter(
+#   "gakt4trackget", # give a unique name
+#   InputContainer = jetFlags.containerNamePrefix() + "AntiKt4PV0TrackJets", # SG key
+#   Label = "GhostAntiKt4TrackJet",   # this is the name you'll use to retrieve associated ghosts
+#   OutputContainer = "PseudoJetGhostAntiKt4TrackJet",
+#   SkipNegativeEnergy = True,
+#   GhostScale = 1.e-20,   # This makes the PseudoJet Ghosts, and thus the reco flow will treat them as so.
+# )
+
+# # Truth.
+# if jetFlags.useTruth and jtm.haveParticleJetTools:
+#   jtm += PseudoJetGetter(
+#     "truthget",
+#     Label = "Truth",
+#     InputContainer = jtm.truthpartcopy.OutputName,
+#     OutputContainer = "PseudoJetTruth",
+#     GhostScale = 0.0,
+#     SkipNegativeEnergy = True,
+
+#   )
+#   jtm += PseudoJetGetter(
+#     "truthwzget",
+#     Label = "TruthWZ",
+#     InputContainer = jtm.truthpartcopywz.OutputName,
+#     OutputContainer = "PseudoJetTruthWZ",
+#     GhostScale = 0.0,
+#     SkipNegativeEnergy = True,
+    
+#   )
+#   jtm += PseudoJetGetter(
+#     "gtruthget",
+#     Label = "GhostTruth",
+#     InputContainer = jtm.truthpartcopy.OutputName,
+#     OutputContainer = "PseudoJetGhostTruth",
+#     GhostScale = 1.e-20,
+#     SkipNegativeEnergy = True,
+#   )
+
+#   # Truth flavor tags.
+#   for ptype in jetFlags.truthFlavorTags():
+#     jtm += PseudoJetGetter(
+#       "gtruthget_" + ptype,
+#       InputContainer = "TruthLabel" + ptype,
+#       Label = "Ghost" + ptype,
+#       OutputContainer = "PseudoJetGhost" + ptype,
+#       SkipNegativeEnergy = True,
+#       GhostScale = 1e-20
+#     )
+
+#   # ParticleJetTools tools may be omitted in analysi releases.
+#   #ift jtm.haveParticleJetTools:
+#   # Delta-R truth parton label: truthpartondr.
+#   jtm += Analysis__JetQuarkLabel(
+#       "jetquarklabel",
+#       McEventCollection = "TruthEvents"
+#     )
+#   jtm += Analysis__JetConeLabeling(
+#       "truthpartondr",
+#       JetTruthMatchTool = jtm.jetquarklabel
+#       )
+  
+#   # Parton truth label.
+#   jtm += Analysis__JetPartonTruthLabel("partontruthlabel")
+
+#   # Cone matching for B, C and tau truth for all but track jets.
+#   jtm += ParticleJetDeltaRLabelTool(
+#     "jetdrlabeler",
+#     LabelName = "HadronConeExclTruthLabelID",
+#     BLabelName = "ConeExclBHadronsFinal",
+#     CLabelName = "ConeExclCHadronsFinal",
+#     TauLabelName = "ConeExclTausFinal",
+#     BParticleCollection = "TruthLabelBHadronsFinal",
+#     CParticleCollection = "TruthLabelCHadronsFinal",
+#     TauParticleCollection = "TruthLabelTausFinal",
+#     PartPtMin = 5000.0,
+#     JetPtMin =     0.0,
+#     DRMax = 0.3,
+#     MatchMode = "MinDR"
+#   )
+
+#   # Cone matching for B, C and tau truth for track jets.
+#   jtm += ParticleJetDeltaRLabelTool(
+#     "trackjetdrlabeler",
+#     LabelName = "HadronConeExclTruthLabelID",
+#     BLabelName = "ConeExclBHadronsFinal",
+#     CLabelName = "ConeExclCHadronsFinal",
+#     TauLabelName = "ConeExclTausFinal",
+#     BParticleCollection = "TruthLabelBHadronsFinal",
+#     CParticleCollection = "TruthLabelCHadronsFinal",
+#     TauParticleCollection = "TruthLabelTausFinal",
+#     PartPtMin = 5000.0,
+#     JetPtMin = 4500.0,
+#     DRMax = 0.3,
+#     MatchMode = "MinDR"
+#   )
+
+# #--------------------------------------------------------------
+# # Jet builder.
+# # The tool manager must have one jet builder.
+# #--------------------------------------------------------------
+
+# jtm.addJetBuilderWithArea(JetFromPseudojet(
+#   "jblda",
+#   Attributes = ["ActiveArea", "ActiveArea4vec"]
+# ))
+
+# jtm.addJetBuilderWithoutArea(JetFromPseudojet(
+#   "jbldna",
+#   Attributes = []
+# ))
+
+# #--------------------------------------------------------------
+# # Non-substructure moment builders.
+# #--------------------------------------------------------------
+
+# # Quality from clusters.
+# jtm += JetCaloQualityTool(
+#   "caloqual_cluster",
+#   TimingCuts = [5, 10],
+#   Calculations = ["LArQuality", "N90Constituents", "FracSamplingMax",  "NegativeE", "Timing", "HECQuality", "Centroid", "AverageLArQF", "BchCorrCell"],
+# )
+
+# # Quality from cells.
+# if jtm.haveJetCaloCellQualityTool:
+#   jtm += JetCaloCellQualityTool(
+#     "caloqual_cell",
+#     LArQualityCut = 4000,
+#     TileQualityCut = 254,
+#     TimingCuts = [5, 10],
+#     Calculations = ["LArQuality", "N90Cells", "FracSamplingMax",  "NegativeE", "Timing", "HECQuality", "Centroid", "AverageLArQF"]
+#   )
+
+# # Jet width.
+# jtm += JetWidthTool("width")
+
+# # Calo layer energies.
+# jtm += JetCaloEnergies("jetens")
+
+# # Read in missing cell map (needed for the following)
+# # commented out : incompatible with trigger : ATR-9696
+# ## if jtm.haveJetRecCalo:
+# ##     def missingCellFileReader(): 
+# ##       import os
+# ##       dataPathList = os.environ[ 'DATAPATH' ].split(os.pathsep)
+# ##       dataPathList.insert(0, os.curdir)
+# ##       from AthenaCommon.Utils.unixtools import FindFile
+# ##       RefFileName = FindFile( "JetBadChanCorrTool.root" ,dataPathList, os.R_OK )
+# ##       from AthenaCommon.AppMgr import ServiceMgr
+# ##       if not hasattr(ServiceMgr, 'THistSvc'):
+# ##         from GaudiSvc.GaudiSvcConf import THistSvc
+# ##         ServiceMgr += THistSvc()
+# ##       ServiceMgr.THistSvc.Input += ["JetBadChanCorrTool DATAFILE=\'%s\' OPT=\'READ\'" % RefFileName]
+# ##       missingCellFileReader.called = True 
+
+# ##     missingCellFileReader()
+
+# ##     jtm += MissingCellListTool(
+# ##       "missingcells",
+# ##       AddCellList = [],
+# ##       RemoveCellList = [],
+# ##       AddBadCells = True,
+# ##       DeltaRmax = 1.0,
+# ##       AddCellFromTool = False,
+# ##       LArMaskBit = 608517,
+# ##       TileMaskBit = 1,
+# ##       MissingCellMapName = "MissingCaloCellsMap"
+# ## )
+
+# ## # Bad channel corrections from cells
+# ## if jtm.haveJetBadChanCorrTool:
+# ##   jtm += JetBadChanCorrTool(
+# ##     "bchcorrcell",
+# ##     NBadCellLimit = 10000,
+# ##     StreamName = "/JetBadChanCorrTool/",
+# ##     ProfileName = "JetBadChanCorrTool.root",
+# ##     ProfileTag = "",
+# ##     UseCone = True,
+# ##     UseCalibScale = False,
+# ##     MissingCellMap = "MissingCaloCellsMap",
+# ##     ForceMissingCellCheck = False,
+# ##     UseClusters = False,
+# ##   )
+  
+# ##   # Bad channel corrections from clusters
+# ##   jtm += JetBadChanCorrTool(
+# ##     "bchcorrclus",
+# ##     NBadCellLimit = 0,
+# ##     StreamName = "",
+# ##     ProfileName = "",
+# ##     ProfileTag = "",
+# ##     UseCone = True,
+# ##     UseCalibScale = False,
+# ##     MissingCellMap = "",
+# ##     ForceMissingCellCheck = False,
+# ##     UseClusters = True
+# ##   )
+
+# # Jet vertex fraction.
+# jtm += JetVertexFractionTool(
+#   "jvfold",
+#   VertexContainer = jtm.vertexContainer,
+#   AssociatedTracks = "GhostTrack",
+#   TrackVertexAssociation = jtm.tvassoc.TrackVertexAssociation,
+#   JVFName = "JVFOld"
+# )
+
+# # Jet vertex fraction with selection.
+# jtm += JetVertexFractionTool(
+#   "jvf",
+#   VertexContainer = jtm.vertexContainer,
+#   AssociatedTracks = "GhostTrack",
+#   TrackVertexAssociation = jtm.tvassoc.TrackVertexAssociation,
+#   TrackSelector = jtm.trackselloose,
+#   JVFName = "JVF"
+# )
+
+# # Jet vertex tagger.
+# jtm += JetVertexTaggerTool(
+#   "jvt",
+#   VertexContainer = jtm.vertexContainer,
+#   TrackParticleContainer  = jtm.trackContainer,
+#   AssociatedTracks = "GhostTrack",
+#   TrackVertexAssociation = jtm.tvassoc.TrackVertexAssociation,
+#   TrackSelector = jtm.trackselloose,
+#   JVTName = "Jvt",
+#   K_JVFCorrScale = 0.01,
+#   Z0Cut = 3.0,
+#   PUTrkPtCut = 30000.0
+# )
+
+# # Jet track info.
+# jtm += JetTrackMomentsTool(
+#   "trkmoms",
+#   VertexContainer = jtm.vertexContainer,
+#   AssociatedTracks = "GhostTrack",
+#   TrackVertexAssociation = jtm.tvassoc.TrackVertexAssociation,
+#   TrackMinPtCuts = [500, 1000],
+#   TrackSelector = jtm.trackselloose
+# )
+
+# # Jet track vector sum info
+# jtm += JetTrackSumMomentsTool(
+#   "trksummoms",
+#   VertexContainer = jtm.vertexContainer,
+#   AssociatedTracks = "GhostTrack",
+#   TrackVertexAssociation = jtm.tvassoc.TrackVertexAssociation,
+#   RequireTrackPV = True,
+#   TrackSelector = jtm.trackselloose
+# )
+
+# # Jet cluster info.
+# jtm += JetClusterMomentsTool(
+#   "clsmoms",
+#   DoClsPt = True,
+#   DoClsSecondLambda = True,
+#   DoClsCenterLambda = True,
+#   DoClsSecondR = True
+# )
+
+# jtm += JetVoronoiMomentsTool(
+#   "voromoms",
+#   AreaXmin= -5.,
+#   AreaXmax=  5.,
+#   AreaYmin= -3.141592,
+#   AreaYmax=  3.141592
+# )
+
+# # Number of associated muon segments.
+# #jtm += JetMuonSegmentMomentsTool("muonsegs")
+
+# # Isolations.
+# # Note absence of PseudoJetGetter property means the jet inputs
+# # are obtained according to the InputType property of the jet.
+# jtm += JetIsolationTool(
+#   "jetisol",
+#   IsolationCalculations = ["IsoDelta:2:SumPt", "IsoDelta:3:SumPt"],
+# )
+# jtm += JetIsolationTool(
+#   "run1jetisol",
+#   IsolationCalculations = ["IsoKR:11:Perp", "IsoKR:11:Par", "IsoFixedCone:6:SumPt",],
+# )
+
+# # Bad LAr fractions.
+# jtm += JetLArHVTool("larhvcorr")
+
+# # Bad LAr fractions.
+# jtm += JetECPSFractionTool(
+#   "ecpsfrac",
+#   ECPSFractionThreshold = 0.80
+# )
+
+# # Jet origin correction.
+# jtm += JetOriginCorrectionTool(
+#   "jetorigincorr",
+#   VertexContainer = jtm.vertexContainer,
+#   OriginCorrectedName = "JetOriginConstitScaleMomentum"
+# )
+
+# #--------------------------------------------------------------
+# # Substructure moment builders.
+# #--------------------------------------------------------------
+
+# # Nsubjettiness
+# jtm += NSubjettinessTool(
+#   "nsubjettiness",
+#   Alpha = 1.0
+# )
+
+# # KtDR
+# jtm += KtDeltaRTool(
+#   "ktdr",
+#   JetRadius = 0.4
+# )
+
+# # Kt-splitter
+# jtm += KTSplittingScaleTool("ktsplitter")
+
+# # Angularity.
+# jtm += AngularityTool("angularity")
+
+# # Dipolarity.
+# jtm += DipolarityTool("dipolarity", SubJetRadius = 0.3)
+
+# # Planar flow.
+# jtm += PlanarFlowTool("planarflow")
+
+# # Kt mass drop.
+# jtm += KtMassDropTool("ktmassdrop")
+
+# # Energy correlations.
+# jtm += EnergyCorrelatorTool("encorr", Beta = 1.0)
+
+# # COM shapes.
+# jtm += CenterOfMassShapesTool("comshapes")
+
+# # Jet pull
+# jtm += JetPullTool(
+#   "pull",
+#   UseEtaInsteadOfY = False,
+#   IncludeTensorMoments = True
+# )
+
+# # Jet charge
+# jtm += JetChargeTool("charge", K=1.0)
+
+# # Shower deconstruction.
+# if jtm.haveShowerDeconstructionTool:
+#   jtm += ShowerDeconstructionTool("showerdec")
+
+# # Remove constituents (useful for truth jets in evgen pile-up file)
+# jtm += JetConstitRemover("removeconstit")
+
+# # Sort jets by pT
+# # May be deisred after calibration or grooming.
+# jtm += JetSorter("jetsorter")
+
+# #  LocalWords:  JetRecStandardTools
diff --git a/Reconstruction/Jet/JetRecConfig/python/JetRecFlags.py b/Reconstruction/Jet/JetRecConfig/python/JetRecFlags.py
new file mode 100644
index 0000000000000000000000000000000000000000..43d10118bba21cfe4efcf8d71f4bc3ba66b2f718
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/python/JetRecFlags.py
@@ -0,0 +1,238 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# JetRecFlags.py
+#
+# David Adams
+# Updated March 2015
+#
+# These are flags for controlling the behavior of jet reconstruction
+# in RecExCommon (which includes JetRec/JetRec_jobOptions.py) and in
+# the example jet reconstruction options RunJetRec.py.
+#
+# Typical usage is
+#   from JetRec.JetRecFlags import jetFlags
+#   if jetFlags.UseTruth:
+#     doSomethingWithTruth()
+#
+# Properties:
+#   Enabled - Skip all jet reco if false (drop whe rec.doJets is added)
+#   debug - JetRecTools are run a DEBUG level
+#   useTruth - Truth jets and association are enabled (for MC)
+#   useTopo  - Topocluster jets are enabled
+#   useTracks - Track jets and association are enabled
+#   useVertices - Toggles whether PFlow jet reconstruction makes use of vertex information.
+#   useMuonSegmentss - Muon segemnt association is enabled
+#   usePFlow - PFlow jets and associations are enabled
+#   useInDetTrackSelection - The inner detector track selection
+#     tool is used. This requires track propagator exist.
+#   jetAODList - The list of jet collections to be written out
+#   And much more--see below.
+
+from AthenaCommon.JobProperties import JobProperty, JobPropertyContainer
+from AthenaCommon.JobProperties import jobproperties
+
+class JetRecFlags(JobPropertyContainer):
+  """ The Jet making flag property container
+  """
+  pass
+
+class Enabled(JobProperty):
+  """ If false will prevent run of any Jet Alg
+  """
+  statusOn     = True     
+  allowedTypes = ['bool']  # type
+  StoredValue  = True      # default value
+
+class debug(JobProperty):
+  """ If > 0, debug (or higher) messages are written by jet tools.
+  """
+  statusOn     = True     
+  allowedTypes = ['int']  # type
+  StoredValue  = 0        # default value
+
+class useTruth(JobProperty):
+  """ If true, truth is present and used in jet reconstruction.
+      The status is set on in JetRecStandardToolManager.
+  """
+  statusOn     = False    
+  allowedTypes = ['bool']  # type
+  StoredValue  = True      # default value
+
+class truthFlavorTags(JobProperty):
+  """ List of flavor tags for truth tagging jets.
+  """
+  statusOn     = True     
+  allowedTypes = ['array']  # type
+  StoredValue  = ["BHadronsInitial", "BHadronsFinal", "BQuarksFinal",
+                  "CHadronsInitial", "CHadronsFinal", "CQuarksFinal",
+                  "TausFinal",
+                  "WBosons", "ZBosons", "HBosons", "TQuarksFinal",
+                  "Partons",
+                 ]
+  
+class useTopo(JobProperty):
+  """ If true, topoclusters are present and used in jet reconstruction.
+      The status is set on in JetRecStandardToolManager.
+  """
+  statusOn     = False    
+  allowedTypes = ['bool']  # type
+  StoredValue  = True      # default value
+
+class useTracks(JobProperty):
+  """ If true, tracks and vertices are present and used in jet reconstruction.
+      The status is set on in JetRecStandardToolManager.
+  """
+  statusOn     = False    
+  allowedTypes = ['bool']  # type
+  StoredValue  = True      # default value
+
+class useVertices(JobProperty):
+  """ If true, vertices are present and used in pflow jet reconstruction.
+  """
+  statusOn     = True     
+  allowedTypes = ['bool']  # type
+  StoredValue  = True      # default value
+
+class useMuonSegments(JobProperty):
+  """ If true, muon segments are present and used in jet reconstruction.
+      The status is set on in JetRecStandardToolManager.
+  """
+  statusOn     = False    
+  allowedTypes = ['bool']  # type
+  StoredValue  = True      # default value
+
+class usePFlow(JobProperty):
+  """ If true, pflow objects are present and used in jet reconstruction.
+      The status is set in JetRecStandardToolManager.
+  """
+  statusOn     = False    
+  allowedTypes = ['bool']  # type
+  StoredValue  = True      # default value
+
+class eventShapeTools(JobProperty):
+  """ List of event shape tools that should be called to calculate rho.
+      Allowed values are "emtopo", "lctopo", "empflow", "emcpflow", "lcpflow".
+  """
+  statusOn     = True     
+  allowedTypes = ['None', 'list']  # type
+  StoredValue  = None              # default value
+
+class useInDetTrackSelection(JobProperty):
+  """ If true, the InDet track selection tool is used.
+  """
+  statusOn     = True     
+  allowedTypes = ['bool']  # type
+  StoredValue  = False     # default value
+
+class useCells(JobProperty):
+  """ If true, calo cells are accesible
+  """
+  statusOn     = True     
+  allowedTypes = ['bool']  # type
+  StoredValue  = False     # default value
+
+class useCaloQualityTool(JobProperty):
+  """ If true, the (slow) CaloQuality tool is used
+  """
+  statusOn     = True     
+  allowedTypes = ['bool']  # type
+  StoredValue  = True      # default value
+
+class useBTagging(JobProperty):
+  """ If true, then btagging is done when requested
+  """
+  statusOn     = True     
+  allowedTypes = ['bool']  # type
+  StoredValue  = False     # default value
+
+class skipTools(JobProperty):
+  """ List of modifier tools to exclude
+  """
+  statusOn     = True     
+  allowedTypes = ['list']  # type
+  StoredValue  = []        # default value
+
+class additionalTopoGetters(JobProperty):
+  """ List of PseudoJet getters to add for Topo jets.
+      E.g. to tag jets with track jets
+  """
+  statusOn     = True     
+  allowedTypes = ['list']  # type
+  StoredValue  = []        # default value
+
+class defaultCalibOpt(JobProperty):
+  """ Calibration applied to topo jets during jet building. See JetRecCalibrationFinder.
+  """
+  statusOn     = True     
+  allowedTypes = ['str']    # type
+  StoredValue  = ""   # default value
+
+class containerNamePrefix(JobProperty):
+  """ Prefix for jet collection names
+  """
+  statusOn     = True     
+  allowedTypes = ['str']    # type
+  StoredValue  = ""         # default value
+
+class separateJetAlgs(JobProperty):
+  """ If true, find and build jet containers in separate alg. Used for debugging.
+  """
+  statusOn     = True     
+  allowedTypes = ['bool']  # type
+  StoredValue  = False      # default value
+
+class timeJetToolRunner(JobProperty):
+  """ Timing flag for JetToolRunner: 0 for no timing, 1 for some, 2 for detailed
+  """
+  statusOn     = True     
+  allowedTypes = ['int']  # type
+  StoredValue  = 0        # default value
+
+class timeJetRecTool(JobProperty):
+  """ Timing flag for JetRecTool: 0 for no timing, 1 for some, 2 for detailed
+  """
+  statusOn     = True     
+  allowedTypes = ['int']  # type
+  StoredValue  = 0        # default value
+
+class jetAODList(JobProperty):
+  """ The collections to be saved in (x)AOD files
+  """
+  statusOn = True
+  allowedTypes = ['list']  
+  StoredValue  = []   
+
+class useTrackVertexTool(JobProperty):
+  """ Toggles whether to use track-vertex tool (only known client is currently pflow jet finding)
+  """
+  statusOn = True
+  allowedTypes = ['bool']
+  StoredValue = False
+
+jobproperties.add_Container(JetRecFlags)
+
+jobproperties.JetRecFlags.add_JobProperty(Enabled)
+jobproperties.JetRecFlags.add_JobProperty(debug)
+jobproperties.JetRecFlags.add_JobProperty(useTruth)
+jobproperties.JetRecFlags.add_JobProperty(truthFlavorTags)
+jobproperties.JetRecFlags.add_JobProperty(useTopo)
+jobproperties.JetRecFlags.add_JobProperty(useTracks)
+jobproperties.JetRecFlags.add_JobProperty(useVertices)
+jobproperties.JetRecFlags.add_JobProperty(useInDetTrackSelection)
+jobproperties.JetRecFlags.add_JobProperty(useMuonSegments)
+jobproperties.JetRecFlags.add_JobProperty(usePFlow)
+jobproperties.JetRecFlags.add_JobProperty(eventShapeTools)
+jobproperties.JetRecFlags.add_JobProperty(jetAODList)
+jobproperties.JetRecFlags.add_JobProperty(useCells)
+jobproperties.JetRecFlags.add_JobProperty(useCaloQualityTool)
+jobproperties.JetRecFlags.add_JobProperty(useBTagging)
+jobproperties.JetRecFlags.add_JobProperty(skipTools)
+jobproperties.JetRecFlags.add_JobProperty(additionalTopoGetters)
+jobproperties.JetRecFlags.add_JobProperty(defaultCalibOpt)
+jobproperties.JetRecFlags.add_JobProperty(containerNamePrefix)
+jobproperties.JetRecFlags.add_JobProperty(separateJetAlgs)
+jobproperties.JetRecFlags.add_JobProperty(timeJetToolRunner)
+jobproperties.JetRecFlags.add_JobProperty(timeJetRecTool)
+jobproperties.JetRecFlags.add_JobProperty(useTrackVertexTool)
+
+jetFlags = jobproperties.JetRecFlags
diff --git a/Reconstruction/Jet/JetRecConfig/python/JetRecStandard.py b/Reconstruction/Jet/JetRecConfig/python/JetRecStandard.py
new file mode 100644
index 0000000000000000000000000000000000000000..286f4c2df8da1c06b99702c0a75fc4faac5eff76
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/python/JetRecStandard.py
@@ -0,0 +1,110 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# JetRecStandard.py
+#
+# David Adams
+# October 2014
+# Updated March 2015
+#
+# Wrapper for JetRecStandardToolManager.py that first uses RecExCommon to set flags.
+# High-level RecExCommon scripts should use this in place or JetRecStandardToolManager.
+#
+# Call with
+#   from JetRecConfig.JetRecStandard import jtm
+#
+# Jet flags should be set before making this call. Those for truth, clusters, tracks
+# and muon segments will be set here iff they are not already set.
+
+myname = "JetRecStandard: "
+print myname + "Begin."
+
+from RecExConfig.RecFlags import rec 
+from InDetRecExample.InDetJobProperties import InDetFlags
+from JetRecFlags import jetFlags
+
+# Function to display flag value and status.
+def sflagstat(flag):
+  return str(flag()) + " (status=" + str(flag.statusOn) + ")"
+
+# Import the jet reconstruction control flags.
+from JetRecFlags import jetFlags
+from RecExConfig.ObjKeyStore import cfgKeyStore
+from AthenaCommon import Logging
+jetlog = Logging.logging.getLogger('JetRec_jobOptions')
+
+# Disable usage of vertices in pflow jets, if we are using cosmic data.
+from AthenaCommon.BeamFlags import jobproperties
+if jobproperties.Beam.beamType == 'cosmics':
+  jetFlags.useVertices = False
+
+# Skip truth if rec says it is absent.
+# No action if someone has already set the flag.
+print myname + "Initial useTruth: " + sflagstat(jetFlags.useTruth)
+print myname + "     rec.doTruth: " + str(rec.doTruth())
+if not jetFlags.useTruth.statusOn:
+  jetFlags.useTruth = rec.doTruth()
+print myname + "  Final useTruth: " + sflagstat(jetFlags.useTruth)
+
+# Skip use of topoclusters if not built
+# No action if someone has already set the flag.
+print myname + "Initial use topoclusters: " + str(jetFlags.useTopo())
+if not jetFlags.useTopo.statusOn:
+  jetFlags.useTopo = rec.doCalo()
+print myname + "  Final use topoclusters: " + str(jetFlags.useTopo())
+
+# Skip tracks if tracks or vertices are not present in the job.
+# No action if someone has already set the flag.
+haveTracks = cfgKeyStore.isInTransient('xAOD::TrackParticleContainer','InDetTrackParticles')
+haveVertices = cfgKeyStore.isInTransient("xAOD::VertexContainer","PrimaryVertices")
+recTracks = rec.doInDet()
+recVertices = bool(InDetFlags.doVertexFinding)
+print myname + "Initial useTracks: " + sflagstat(jetFlags.useTracks)
+print myname + "      rec doInDet: " + str(recTracks)
+print myname + "  doVertexFinding: " + str(recVertices)
+print myname + "      have tracks: " + str(haveTracks)
+print myname + "    have vertices: " + str(haveVertices)
+if not jetFlags.useTracks.statusOn:
+  jetFlags.useTracks = (recTracks or haveTracks) and (recVertices or haveVertices)
+print myname + "  Final useTracks: " + sflagstat(jetFlags.useTracks)
+
+# Skip pflow if we are not using tracks.
+print myname + "Initial usePFlow: " + sflagstat(jetFlags.usePFlow)
+if not jetFlags.usePFlow.statusOn:
+  jetFlags.usePFlow = jetFlags.useTracks()
+print myname + "Final usePFlow: " + sflagstat(jetFlags.usePFlow)
+
+# Skip use of muon segments if not built.
+# No action if someone has already set the flag.
+print myname + "Initial use muon segments: " + sflagstat(jetFlags.useMuonSegments)
+if not jetFlags.useMuonSegments.statusOn:
+  jetFlags.useMuonSegments = rec.doMuon() and rec.doMuonCombined()
+print myname + "  Final use muon segments: " + sflagstat(jetFlags.useMuonSegments)
+
+# Use rec flag to control BTagging.
+# No. Disable this unit we get support from Btagging to do this.
+# No action if someone has already set the flag.
+print myname + "Initial use Btagging: " + str(jetFlags.useBTagging)
+print myname + "     rec do BTagging: " + str(rec.doBTagging())
+if not jetFlags.useBTagging.statusOn:
+  #jetFlags.useBTagging = rec.doBTagging()
+  jetFlags.useBTagging = False
+print myname + "  Final use Btagging: " + str(jetFlags.useBTagging)
+
+# The following can be used to exclude tools from reconstruction.
+if 0:
+  jetFlags.skipTools = ["comshapes"]
+jetlog.info( "Skipped tools: %s", jetFlags.skipTools())
+
+# Set the list of rho calculations.
+# If caller has set jetFlags.eventShapeTools(), then we use those values.
+if jetFlags.eventShapeTools() == None:
+  jetFlags.eventShapeTools = []
+  if jetFlags.useTopo():
+    jetFlags.eventShapeTools += ['emtopo', 'lctopo']
+  if jetFlags.usePFlow():
+    jetFlags.eventShapeTools += ['empflow']
+
+# Import the jet tool manager.
+from JetRecStandardToolManager import jtm
+
+print myname + "End."
diff --git a/Reconstruction/Jet/JetRecConfig/python/JetRecStandardToolManager.py b/Reconstruction/Jet/JetRecConfig/python/JetRecStandardToolManager.py
new file mode 100644
index 0000000000000000000000000000000000000000..096e8ae110bc16311988c3e50fa87c708a85fac1
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/python/JetRecStandardToolManager.py
@@ -0,0 +1,316 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# JetRecStandardToolManager.py
+#
+# David Adams
+# March 2014
+#
+# Constructs an instance jtm of the JetToolManager with
+# standard definitions for jet tools.
+#
+# Usage:
+#   from JetRecConfig.JetRecStandardToolManager import jtm
+#   jtm.addJetFinder("AntiKt4EMTopoJets", "AntiKt", 0.4, "em", "calib_topo_ungroomed")
+#
+
+import copy
+
+myname = "JetRecStandardToolManager.py: "
+
+print myname + "Defining standard tools"
+
+#########################################################
+# Set and lock flags.
+#########################################################
+
+from JetRecFlags import jetFlags
+
+# Set status on for flags that are initialized with status off.
+jetFlags.useTruth.set_On()
+jetFlags.useTopo.set_On()
+jetFlags.useTracks.set_On()
+jetFlags.usePFlow.set_On()
+jetFlags.useMuonSegments.set_On()
+jetFlags.useBTagging.set_On()
+
+# Lock all the flags used here so that later attempts to change
+# the value will fail with an error message.
+jetFlags.useTruth.lock()
+jetFlags.useTopo.lock()
+jetFlags.useTracks.lock()
+jetFlags.useMuonSegments.lock()
+jetFlags.useBTagging.lock()
+jetFlags.useCaloQualityTool.lock()
+jetFlags.additionalTopoGetters.lock()
+jetFlags.truthFlavorTags.lock()
+jetFlags.skipTools.lock()
+
+# Display all flags used here.
+print myname + "jetFlags.useTruth: " + str(jetFlags.useTruth())
+print myname + "jetFlags.useTopo: " + str(jetFlags.useTopo())
+print myname + "jetFlags.useTracks: " + str(jetFlags.useTracks())
+print myname + "jetFlags.useMuonSegments: " + str(jetFlags.useMuonSegments())
+print myname + "jetFlags.useBTagging: " + str(jetFlags.useBTagging())
+print myname + "jetFlags.useCaloQualityTool: " + str(jetFlags.useCaloQualityTool())
+print myname + "jetFlags.additionalTopoGetters: " + str(jetFlags.additionalTopoGetters())
+print myname + "jetFlags.truthFlavorTags: " + str(jetFlags.truthFlavorTags())
+print myname + "jetFlags.skipTools: " + str(jetFlags.skipTools())
+
+#########################################################
+# Create standard tool manager.
+#########################################################
+
+# Import the jet tool manager.
+from JetToolSupport import JetToolManager
+
+# Global jet tool manager with standard definitions
+jtm = JetToolManager()
+
+# Pt thresholds in MeV
+jtm.ptminFinder = 2000
+jtm.ptminFilter =    0
+
+# Add standard tool definitions to the tool manager.
+import JetRecStandardTools
+
+if 0:
+  print "First call to JetRecStandardToolManager.py:"
+  from traceback import format_exc
+  print format_exc()
+  print "Exception"
+  raise Exception
+  from traceback import print_stack
+  print_stack()
+
+#########################################################
+# Getters
+#########################################################
+
+# Pseudojet getters
+empfgetters =  [jtm.empflowget]
+emcpfgetters = [jtm.emcpflowget]
+lcpfgetters =  [jtm.lcpflowget]
+emgetters = [jtm.emget]
+lcgetters = [jtm.lcget]
+trackgetters = [jtm.trackget]
+# Add track ghosts
+if jetFlags.useTracks():
+  emgetters += [jtm.gtrackget]
+  lcgetters += [jtm.gtrackget]
+  empfgetters += [jtm.gtrackget]
+  emcpfgetters += [jtm.gtrackget]
+  lcpfgetters += [jtm.gtrackget]
+if jetFlags.useMuonSegments():
+  emgetters += [jtm.gmusegget]
+  lcgetters += [jtm.gmusegget]
+  empfgetters  += [jtm.gmusegget]
+  emcpfgetters += [jtm.gmusegget]
+  lcpfgetters += [jtm.gmusegget]
+# Add jet ghosts.
+if 1:
+  for gettername in jetFlags.additionalTopoGetters():
+    getter = jtm[gettername]
+    emgetters += [getter]
+    lcgetters += [getter]
+# Add truth getter and truth ghosts.
+if jetFlags.useTruth():
+  truthgetters = [jtm.truthget]
+  truthwzgetters = [jtm.truthwzget]
+  trackgetters += [jtm.gtruthget]
+  emgetters += [jtm.gtruthget]
+  lcgetters += [jtm.gtruthget]
+  empfgetters += [jtm.gtruthget]
+  emcpfgetters += [jtm.gtruthget]
+  lcpfgetters += [jtm.gtruthget]
+  # Add truth cone matching and truth flavor ghosts.
+  flavorgetters = []
+  for ptype in jetFlags.truthFlavorTags():
+    flavorgetters += [getattr(jtm, "gtruthget_" + ptype)]
+  emgetters      += flavorgetters
+  lcgetters      += flavorgetters
+  truthgetters   += flavorgetters
+  truthwzgetters += flavorgetters
+  trackgetters   += flavorgetters
+  empfgetters    += flavorgetters
+  emcpfgetters   += flavorgetters
+  lcpfgetters    += flavorgetters
+# Add track jet ghosts.
+if jetFlags.useTracks():
+  trackjetgetters = []
+  trackjetgetters += [jtm.gakt2trackget]
+  trackjetgetters += [jtm.gakt3trackget]
+  trackjetgetters += [jtm.gakt4trackget]
+  emgetters += trackjetgetters
+  lcgetters += trackjetgetters
+  empfgetters += trackjetgetters
+  emcpfgetters += trackjetgetters
+  lcpfgetters += trackjetgetters
+
+# Add getter lists to jtm indexed by input type name.
+jtm.gettersMap["emtopo"]    = list(emgetters)
+jtm.gettersMap["lctopo"]    = list(lcgetters)
+jtm.gettersMap["empflow"]   = list(empfgetters)
+jtm.gettersMap["emcpflow"]  = list(emcpfgetters)
+jtm.gettersMap["lcpflow"]   = list(lcpfgetters)
+jtm.gettersMap["track"]     = list(trackgetters)
+jtm.gettersMap["ztrack"]    = list(trackgetters)
+jtm.gettersMap["pv0track"]  = list(trackgetters)
+if jetFlags.useTruth():
+  jtm.gettersMap["truth"]   = list(truthgetters)
+  jtm.gettersMap["truthwz"] = list(truthwzgetters)
+
+#########################################################
+# Modifiers
+#########################################################
+
+# Modifiers for ungroomed jets from all input types.
+common_ungroomed_modifiers = [
+  jtm.width,
+  jtm.jetisol,
+  jtm.ktdr,
+  jtm.nsubjettiness,
+  jtm.ktsplitter,
+  jtm.angularity,
+  jtm.dipolarity,
+  jtm.planarflow,
+  jtm.ktmassdrop,
+  jtm.encorr,
+  jtm.comshapes
+]
+
+# Add parton truth labels and truth jet modifiers.
+if jetFlags.useTruth():
+  if jtm.haveParticleJetTools:
+    common_ungroomed_modifiers += [jtm.partontruthlabel]
+    common_ungroomed_modifiers += [jtm.truthpartondr]
+
+  # Modifiers for truth jets.
+  truth_ungroomed_modifiers = list(common_ungroomed_modifiers)
+  if jtm.haveParticleJetTools:
+    truth_ungroomed_modifiers += [jtm.jetdrlabeler]
+
+# Modifiers for track jets.
+track_ungroomed_modifiers = list(common_ungroomed_modifiers)
+if jetFlags.useTruth() and jtm.haveParticleJetTools:
+  track_ungroomed_modifiers += [jtm.trackjetdrlabeler]
+
+# Modifiers for topo (and pflow) jets.
+topo_ungroomed_modifiers = ["jetfilter"]
+topo_ungroomed_modifiers += common_ungroomed_modifiers
+topo_ungroomed_modifiers += [jtm.jetens]
+topo_ungroomed_modifiers += [jtm.larhvcorr]
+topo_ungroomed_modifiers += [jtm.ecpsfrac]
+if jetFlags.useCaloQualityTool():
+  topo_ungroomed_modifiers += [jtm.caloqual_cluster]
+if jetFlags.useTracks():
+  topo_ungroomed_modifiers += [jtm.jvf]
+  topo_ungroomed_modifiers += [jtm.jvt]
+  topo_ungroomed_modifiers += [jtm.trkmoms]
+  topo_ungroomed_modifiers += [jtm.trksummoms]
+  topo_ungroomed_modifiers += [jtm.charge]
+  topo_ungroomed_modifiers += ["trackassoc"]
+if jetFlags.useTruth():
+  topo_ungroomed_modifiers += ["truthassoc"]
+  if jtm.haveParticleJetTools:
+    topo_ungroomed_modifiers += [jtm.jetdrlabeler]
+
+# Modifiers for groomed jets.
+groomed_modifiers = [ ]
+
+# Modifiers for groomed topo jets.
+topo_groomed_modifiers = list(groomed_modifiers)
+if jetFlags.useTracks():
+  topo_groomed_modifiers += [jtm.jetorigincorr]
+groomed_modifiers += [jtm.jetsorter]
+topo_groomed_modifiers += [jtm.jetsorter]
+
+# Function to filter out skipped tools.
+def filterout(skiptoolnames, tools):
+  outtools = []
+  remtoolnames = []
+  nrem = 0
+  for tool in tools:
+    keep = True
+    for toolname in skiptoolnames:
+      skiptool = jtm[toolname]
+      same = tool == skiptool
+      if same:
+        keep = False
+        remtoolnames += [toolname]
+    if keep:
+      outtools += [tool]
+  print myname + "Removed tools: " + str(remtoolnames)
+  return outtools
+
+# Modifiers for pflow jets.
+# Same as topo jets.
+pflow_ungroomed_modifiers = []
+pflow_ungroomed_modifiers += ["calib"]
+pflow_ungroomed_modifiers += topo_ungroomed_modifiers
+
+# 28may2015 - ecpsfrac is not yet working for pflow in xAOD.
+pflow_ungroomed_modifiers = filterout(["ecpsfrac"], pflow_ungroomed_modifiers)
+
+# Here add tools to be run for topo jets and NOT for pflow.
+
+# Cluster moments.
+topo_ungroomed_modifiers += [jtm.clsmoms]
+
+# Voronoi moments.
+#topo_ungroomed_modifiers += [jtm.voromoms]
+
+# Modifiers for calibrated topo jets.
+calib_topo_ungroomed_modifiers = []
+if jetFlags.useTracks():
+  tmp_topo_ungroomed_modifiers = filterout(["jetens"], topo_ungroomed_modifiers)
+  calib_topo_ungroomed_modifiers += [jtm.jetorigincorr, jtm.jetens, "calib", jtm.jetsorter]
+  calib_topo_ungroomed_modifiers += tmp_topo_ungroomed_modifiers
+else:
+  calib_topo_ungroomed_modifiers += topo_ungroomed_modifiers
+
+# Add origin corrn for uncalibrated, ungroomed topo jets.
+if jetFlags.useTracks():
+  topo_ungroomed_modifiers += [jtm.jetorigincorr]
+
+# Add Btagging.
+btags = ["btag"]
+if jetFlags.useBTagging():
+  topo_ungroomed_modifiers += btags
+  calib_topo_ungroomed_modifiers += btags
+
+# Filter out skipped tools.
+if len(jetFlags.skipTools()):
+  print myname + "Tools to be skipped: " + str(jetFlags.skipTools())
+  topo_ungroomed_modifiers        = filterout(jetFlags.skipTools(), topo_ungroomed_modifiers)
+  calib_topo_ungroomed_modifiers  = filterout(jetFlags.skipTools(), calib_topo_ungroomed_modifiers)
+  if jetFlags.useTruth():
+    truth_ungroomed_modifiers     = filterout(jetFlags.skipTools(), truth_ungroomed_modifiers)
+  track_ungroomed_modifiers       = filterout(jetFlags.skipTools(), track_ungroomed_modifiers)
+  topo_groomed_modifiers          = filterout(jetFlags.skipTools(), topo_groomed_modifiers)
+  groomed_modifiers               = filterout(jetFlags.skipTools(), groomed_modifiers)
+  pflow_ungroomed_modifiers       = filterout(jetFlags.skipTools(), pflow_ungroomed_modifiers)
+
+# Add modifier lists to jtm indexed by modifier type name.
+jtm.modifiersMap["none"]                  = []
+jtm.modifiersMap["topo_ungroomed"]        =       list(topo_ungroomed_modifiers)
+jtm.modifiersMap["calib_topo_ungroomed"]  = list(calib_topo_ungroomed_modifiers)
+jtm.modifiersMap["calib"]                 = list(calib_topo_ungroomed_modifiers)
+jtm.modifiersMap["pflow"]                 =      list(pflow_ungroomed_modifiers)
+if jetFlags.useTruth():
+  jtm.modifiersMap["truth_ungroomed"]     =      list(truth_ungroomed_modifiers)
+jtm.modifiersMap["track_ungroomed"]       =      list(track_ungroomed_modifiers)
+jtm.modifiersMap["topo_groomed"]          =         list(topo_groomed_modifiers)
+jtm.modifiersMap["groomed"]               =              list(groomed_modifiers)
+
+# Also index modifier type names by input type name.
+# These are used when the modifier list is omitted.
+jtm.modifiersMap["emtopo"]    =  list(topo_ungroomed_modifiers)
+jtm.modifiersMap["lctopo"]    =  list(topo_ungroomed_modifiers)
+jtm.modifiersMap["track"]     = list(track_ungroomed_modifiers)
+jtm.modifiersMap["ztrack"]    = list(track_ungroomed_modifiers)
+jtm.modifiersMap["pv0track"]  = list(track_ungroomed_modifiers)
+if jetFlags.useTruth():
+  jtm.modifiersMap["truth"]   = list(truth_ungroomed_modifiers)
+  jtm.modifiersMap["truthwz"] = list(truth_ungroomed_modifiers)
+
+print myname + "End."
diff --git a/Reconstruction/Jet/JetRecConfig/python/JetRecStandardTools.py b/Reconstruction/Jet/JetRecConfig/python/JetRecStandardTools.py
new file mode 100644
index 0000000000000000000000000000000000000000..98108a29ef388b998b4dfa23d172f16e9e4b71e8
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/python/JetRecStandardTools.py
@@ -0,0 +1,45 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# JetRecStandardTools.py
+#
+# David Adams
+# March 2014
+#
+# Define the low-level tools used in jet reconstruction.
+#
+# Tools are configured and put in the global jet tool manager so
+# they can be accessed when configuring JetRec tools.
+#
+# Execute this file to add the definitions to
+# JetRecStandardToolManager.jtm, e.g.
+#   import JetRecStandardTools
+
+# Import the jet flags.
+from JetRecFlags import jetFlags
+
+from JetRecStandardToolManager import jtm
+
+if not "UseTriggerStore " in locals():
+  UseTriggerStore = False
+
+# get levels defined VERBOSE=1 etc.
+from GaudiKernel.Constants import *
+
+try:
+  from JetRecCalo.JetRecCaloConf import MissingCellListTool
+  jtm.haveJetRecCalo = True
+except ImportError:
+  jtm.haveJetRecCalo = False
+
+# Import configurations from jet packages
+import JetMomentTools.DefaultTools
+import JetSubStructureMomentTools.DefaultTools
+import ParticleJetTools.DefaultTools
+import JetRec.DefaultTools 
+import PFlowUtils.DefaultTools
+
+JetMomentTools.DefaultTools.declareDefaultTools()
+JetSubStructureMomentTools.DefaultTools.declareDefaultTools()
+ParticleJetTools.DefaultTools.declareDefaultTools()
+JetRec.DefaultTools.declareDefaultTools()
+PFlowUtils.DefaultTools.declareDefaultTools()
diff --git a/Reconstruction/Jet/JetRecConfig/python/JetRecUtils.py b/Reconstruction/Jet/JetRecConfig/python/JetRecUtils.py
new file mode 100644
index 0000000000000000000000000000000000000000..15075e90ca672b36791fe4e706a9df0f2fb1553f
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/python/JetRecUtils.py
@@ -0,0 +1,70 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+from AthenaCommon.AppMgr import ToolSvc
+
+def retrieveAODList():
+    from JetRecFlags import jetFlags
+    from RecExConfig.RecFlags import rec
+
+    if rec.doESD():
+        return jetFlags.jetAODList()
+
+    # else : just copy what's in input.
+    from RecExConfig.ObjKeyStore import objKeyStore
+
+    inputcontent = objKeyStore['inputFile'].list()
+    typeToSave = [ 'xAOD::JetContainer', 'xAOD::JetAuxContainer', 'xAOD::JetTrigAuxContainer' , 'xAOD::EventShape', 'xAOD::EventShapeAuxInfo' ]
+
+    def saveThisObject(o):
+        # we must not write out any HLT jet containers - writing of those is controlled from trigger software, not offline jet software
+        if  "HLT_" in o:
+            return False
+        # return True if o is of a desired type    
+        return any( o.startswith( typ ) for typ in typeToSave )
+
+    esdjets = [ o for o in inputcontent if saveThisObject(o) ]
+
+    return esdjets
+
+def buildJetAlgName(finder, mainParam):
+    return finder + str(int(mainParam*10))
+
+def buildJetContName(finder, mainParam, input):
+    return buildJetAlgName(finder, mainParam) +input+"Jets" # could be more elaborated...
+
+def interpretJetName(jetcollName,  finder = None,input=None, mainParam=None):
+    # first step : guess the finder, input , mainParam, if needed
+    if finder is None:
+        for a in [ 'AntiKt','CamKt','Kt', 'Cone','SISCone','CMSCone']:
+            if jetcollName.startswith(a):
+                finder = a
+                break
+        if finder is None:
+            print "Error could not guess jet finder type in ",jetcollName
+            return 
+
+    if input is None:
+        for i in ['LCTopo','Tower','EMTopo', "Truth", "ZTrack", 'PV0Track']:
+            if i in jetcollName:
+                input = i
+                if i== "Tower":
+                    if 'Ghost' in jetcollName:
+                        input = 'Tower'
+                    else:
+                        input = "TopoTower"
+                break
+        if input is None:
+            print "Error could not guess input type in ",jetcollName            
+            return
+        
+    if mainParam is None:
+        # get the 2 chars following finder :
+        mp = jetcollName[len(finder):len(finder)+2]
+        mp = mp[0] if not mp[1] in '0123456789' else mp
+        try :
+            mainParam = float(mp)/10.
+        except ValueError :
+            print "Error could not guess main parameter in ",jetcollName
+            return
+
+    return finder, mainParam, input
diff --git a/Reconstruction/Jet/JetRecConfig/python/JetToolSupport.py b/Reconstruction/Jet/JetRecConfig/python/JetToolSupport.py
new file mode 100644
index 0000000000000000000000000000000000000000..7114441934ea076c35c2dd88daff3ee04bd7c276
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/python/JetToolSupport.py
@@ -0,0 +1,617 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# JetToolSupport.py
+#
+# David Adams
+# March 2014
+#
+# Defines the jet tool manager (class JetToolManager, JTM for short)
+# which can be used to configure jet reconstruction tools.
+#
+# Use add or "+=" to register a tool both with this an instance of this
+# class and with ToolSvc. The advantage of doing it here is there is a
+# check to make sure the same name is not used more than once.
+#
+# Tools are locked when registered. The method setOutputLevel may
+# be used to override this lock to change the tool's output level.
+#
+# Methods are provide to configure a jetrec tool along with its
+# associated finder or groomer. The member "jetrecs" holds the full
+# list of offline jetrec tools and can be used to configure the tool or
+# algorithm that loops over such tools. The member trigjetrecs holds
+# the same for the trigger.  The members "finders" and
+# "groomers" hold the finding and grooming tools used by the jetrec
+# tools.
+#
+# The prefix for messages from this tool is held by the member "prefix"
+# and the member "debug" may be set to 1 to obtain more messages.
+#
+# The members "jetBuilderWithArea" and "jetBuilderWithoutArea" hold the
+# jet builders used by all jetrec tools.
+#
+# The member "ghostArea" specifies the area to use for the ghosts
+# generated for jet finding.
+
+# import the jet flags.
+from JetRecFlags import jetFlags
+
+# The tool manager
+class JetToolManager:
+  prefix = "JetToolManager: "
+  debug = 0
+  m_jetBuilder = None
+  jetBuilderWithArea = None
+  jetBuilderWithoutArea = None
+  tools = { }
+  finders = []
+  groomers = []
+  jetrecs = []
+  trigjetrecs = []
+  # Jet container names. Add input containers to this list:
+  # jetcons += ["SomeExistingJetContainer"]
+  jetcons = []
+  # pT thresholds in MeV (for finding and filtering after calibration)
+  ptminFinder = 2000
+  ptminFilter = 10000
+  # Map of getter lists.
+  gettersMap = {}
+  # Map of modifier lists
+  modifiersMap = {}
+  # Timer for JetRecTool
+  timer = jetFlags.timeJetRecTool()
+
+  vertexContainer = "PrimaryVertices"
+  trackContainer = "InDetTrackParticles"
+
+  # Print a message to the log.
+  def msg(self, lvl, mymsg):
+    if lvl <= self.debug: print self.prefix + str(mymsg)
+
+  # Add a tool.
+  def add(self, mytool):
+    myname = mytool.name()
+    self.msg(1, "Adding tool " + myname)
+    if myname in self.tools:
+      self.msg(0, "Tool " + myname + " is already registered")
+      raise LookupError
+    else:
+      print type(mytool)
+      self.tools[myname] = mytool
+      from AthenaCommon.AppMgr import ToolSvc 
+      ToolSvc += mytool
+      mytool.lock()
+      setattr(self, myname, mytool)
+      return mytool
+
+  # Add a tool with a local name (alias).
+  # Used to provide alternative names for tools with long names.
+  def addNamed(self, myname, mytool):
+    if myname in self.tools:
+      self.msg( "Name " + myname + " is already registered")
+      raise LookupError
+    self.tools[myname] = self.add(mytool)
+    setattr(self, myname, mytool)
+    return mytool
+
+  # Ad op+= as alternative syntax to add.
+  def __iadd__(self, mytool):
+    self.add(mytool)
+    return self
+
+  # Add for a jet builder.
+  # The jet builder is used by by all finders an groomers and
+  # must be added with one of these methods.
+  def addJetBuilderWithArea(self, mytool):
+    if self.add(mytool):
+      self.jetBuilderWithArea = mytool
+      self.msg(1, "Jet builder with area added: " + mytool.name())
+      return mytool
+    else:
+      self.msg(0, "Error adding jet builder with area.")
+      raise LookupError
+  def addJetBuilderWithoutArea(self, mytool):
+    if self.add(mytool):
+      self.jetBuilderWithoutArea = mytool
+      self.msg(1, "Jet builder without area added: " + mytool.name())
+      return mytool
+    else:
+      self.msg(0, "Error adding jet builder without area.")
+      raise LookupError
+
+  # Return the list of modifiers associated with a name.
+  # If the argument is a list, it is returned directly.
+  def getModifiers(self, modifiersin, altname =None):
+    if modifiersin == None:
+      return self.modifiersMap[altname]
+    if type(modifiersin) == str:
+      return self.modifiersMap[modifiersin]
+    return modifiersin
+
+  # Build the list of modifiers, replacing the string "calib:XXX:CALIB" with
+  # the appropriate calibration tool.
+  def buildModifiers(self, modifiersin, finder, getters, altname, output, calibOpt):
+    from GaudiKernel.Proxy.Configurable import ConfigurableAlgTool
+    from JetRec.JetRecConf import JetFinder
+    outmods = []
+    inmods = self.getModifiers(modifiersin, altname)
+    ncalib = 0
+    for mod in inmods:
+      print self.prefix + "Adding modifier " + str(mod)
+      mod0 = ""
+      # Split mod = a:b:c... into mod0="a" and modarr = [a, b, c, ...]
+      if type(mod) == str:
+        if len(mod) == 0: continue
+        modarr = mod.split(":")
+        mod0 = modarr[0]
+      # Fully configured tool.
+      if isinstance(mod, ConfigurableAlgTool):
+        self.msg(2, "  Adding modifier " + mod.name())
+        outmods += [mod]
+      # Add jet calibration:
+      #   calib:XXX:CALIB - Applies calibration sequence XXX (see JetRecCalibrationFinder)
+      #                     using JetCalibrationTool with configuration (or key) CONFIG.
+      elif mod0 == "calib":
+        ncalib += 1
+        alg = finder.JetAlgorithm
+        rad = finder.JetRadius
+        get = getters[0]
+        inp = get.Label
+        copt = calibOpt
+        if type(calibOpt)==str and len(calibOpt):
+          calargs = calibOpt.split(":")
+        else:
+          calargs = modarr[1:]
+        if len(calargs) == 0:
+          copt = jetFlags.defaultCalibOpt
+          if type(copt)==str and len(copt):
+            calargs = copt.split(":")
+          else:
+            print self.prefix + 'ERROR: If the modifier "calib" is used, then calibOpt or jetFlags.CalibOpt must be a non-blank string.'
+            print self.prefix + 'ERROR: Another alternative is to use the modifier string format "calib:<OPT>", e.g. "calib:a"'
+            raise Exception
+        if len(calargs) == 0 or calargs[0]=="":
+          print self.prefix + "ERROR: Calibration requested without option."
+          print self.prefix + "       Add calibOpt to tool string, jet build command or to jetFlags.defaultCalibOpt"
+          raise Exception
+        seq = calargs[0]
+        if seq == "none":
+          print self.prefix + "Skipping calibration."
+          continue
+        config = ""
+        evsprefix = "Kt4"
+        if len(calargs) > 1:
+          config = calargs[1]
+        if len(calargs) > 2:
+          evsprefix = calargs[2]
+        self.msg(0, "  Adding " + seq + " calibration for " + alg + " R=" + str(rad) + " " + inp)
+        self.msg(0, "  Configuration key/file: " + config)
+        self.msg(0, "  Event shape prefix: " + evsprefix)
+        from JetRecCalibrationFinder import jrcf
+        calmod = jrcf.find(alg, rad, inp, seq, config, evsprefix)
+        print self.prefix + "Adding calib modifier " + str(calmod)
+        outmods += [calmod]
+      # truthassoc - Does truth jet association replacing the input anme with "Truth"
+      elif mod == "truthassoc":
+        sinp = getters[0].Label
+        salg = finder.JetAlgorithm
+        srad = str(int(10*finder.JetRadius))
+        cname = output.replace(sinp, "Truth")
+        if cname == output:
+          raise TypeError
+        # Check that the building of the association tool has been scheduled.
+        if not cname in self.jetcons:
+          print self.prefix + "Truth association skipped because container is missing: " + cname
+          print self.prefix + "Add to jetcons if input stream is expected to have this."
+        tname = mod + "_" + salg + srad
+        if not tname in self.tools:
+          from JetMomentTools.JetMomentToolsConf import JetPtAssociationTool
+          self += JetPtAssociationTool(tname, InputContainer=cname, AssociationName="GhostTruth")
+        outmods += [self.tools[tname]]
+      # trackassoc - Does truth jet association replacing the input name with "Track"
+      elif mod == "trackassoc":
+        sinp = getters[0].Label
+        salg = finder.JetAlgorithm
+        srad = str(int(10*finder.JetRadius))
+        cname = output.replace(sinp, "Track")
+        if cname == output:
+          raise TypeError
+        # Check that the building of the association tool has been scheduled.
+        if not cname in self.jetcons:
+          print self.prefix + "Track association skipped because container is missing: " + cname
+          print self.prefix + "Add to jetcons if input stream is expected to have this."
+        else:
+          tname = mod + "_" + salg + srad
+          if not tname in self.tools:
+            from JetMomentTools.JetMomentToolsConf import JetPtAssociationTool
+            self += JetPtAssociationTool(tname, InputContainer=cname, AssociationName="GhostTrack")
+          outmods += [self.tools[tname]]
+      # jetfilter - Filter to remove jets with pT < self.ptminFilter
+      elif mod == "jetfilter":
+        if self.ptminFilter <= 0:
+          print self.prefix + "Jet filter requested without a threshold."
+          raise Exception
+        tname = "jetpt" + str(self.ptminFilter)
+        if not tname in self.tools:
+          from JetRec.JetRecConf import JetFilterTool
+          self.add( JetFilterTool(tname, PtMin=self.ptminFilter) ) 
+        outmods += [self.tools[tname]]
+      # btag - btagging
+      elif mod == "btag":
+        from BTagging.BTaggingConfiguration import getConfiguration
+        ConfInstance = getConfiguration()
+        from AthenaCommon.AppMgr import ToolSvc 
+        sinp = getters[0].Label
+        salg = finder.JetAlgorithm
+        srad = str(int(10*finder.JetRadius))
+        bspec = salg + srad + sinp
+        print self.prefix + "Scheduling btagging for " + bspec
+        btagger = ConfInstance.setupJetBTaggerTool(ToolSvc, bspec)
+        print btagger
+        self.add(btagger)
+        outmods += [btagger]
+      else:
+        raise TypeError
+    # Check calibration.
+    if calibOpt != "":
+      if ncalib==0:
+        print self.prefix + "Calibration option (" + calibOpt + ") provided without any calibration modifiers."
+      elif ncalib > 1:
+        print self.prefix + "Calibration option (" + calibOpt + ") provided with multiple calibration modifiers."
+        raise Exception
+
+        
+    return outmods
+
+  # Create a jet finder without a JetRecToosl.
+  #   alg = akgorithm name (Kt, CamKt, AntiKt)
+  #   radius = size parameter
+  #   rndseed: RandomOption for the finder
+  #   gettersin = array of input pseudojet builders (or name in gettersMap)
+  #   modifiersin = list of modifier tools (or name of such in modifiersMap)
+  #                 If absent, the gettersin name is used.
+  #   consumers = sequence of jet consumers to run after reco
+  #   ivtx = None: ordinary jet finding
+  #            -1: Separate finding for each vertex
+  #           >=0: Finding only for vertex ivtx.
+  #   ghostArea: if > 0, then ghosts are found with this inverse density
+  #   rndseed: RandomOption for the finder
+  #   variableRMinRadius: Min radius for variable-R finding
+  #   variableRMassScale: Mass scale for variable-R finding
+  #   calibOpt: Calibration option, e.g. "ar". See JetRecCalibrationFinder.py.
+  # returns lofinder, hifinder where finder is the lowest-level finder and hifinder
+  #         is the highest.
+  def addJetFinderTool(self, toolname, alg, radius, ivtx =None,
+                       ghostArea =0.0, ptmin =0.0, rndseed =1,
+                       variableRMinRadius =-1.0, variableRMassScale =-1.0):
+    myname = "JetToolManager:addJetFinderTool: "
+    if toolname in self.tools:
+      self.msg(0, "Tool " + myname + " is already registered")
+      raise LookupError
+    self.msg(2, "Adding finder tool")
+    if ghostArea == 0.0:
+      self.m_jetBuilder = self.jetBuilderWithoutArea
+    else:
+      self.m_jetBuilder = self.jetBuilderWithArea
+    if self.m_jetBuilder == None:
+      self.msg(0, "Jet builder must be specified")
+      raise Error
+    from JetRec.JetRecConf import JetFinder
+    areaSuffix= "Area" if ghostArea>0.0 else ""
+    finder = JetFinder(toolname);
+    finder.JetAlgorithm = alg
+    finder.JetRadius = radius
+    finder.VariableRMinRadius = variableRMinRadius
+    finder.VariableRMassScale = variableRMassScale
+    finder.RandomOption = rndseed
+    finder.GhostArea = ghostArea
+    if ptmin > 0.0:
+      finder.PtMin = ptmin
+    else:
+      finder.PtMin = self.ptminFinder
+    finder.JetBuilder = self.m_jetBuilder
+    self += finder
+    self.finders += [finder]
+    hifinder = finder;
+    if type(ivtx) is int:
+      from JetRec.JetRecConf import JetByVertexFinder
+      vfinder = JetByVertexFinder(
+        toolname + "ByVertex",
+        JetFinder = finder,
+        Vertex = ivtx
+      )
+      self += vfinder
+      self.finders += [vfinder]
+      hifinder = vfinder;
+    return (finder, hifinder)
+
+  # Create a jet finder and rectool.
+  #   output = name for output container (and JetRecTool)
+  #   alg = akgorithm name (Kt, CamKt, AntiKt)
+  #   radius = size parameter
+  #   rndseed: RandomOption for the finder
+  #   isTrigger: If true, the trigger store is used and the tools is added to
+  #              trigjetrecs instead of jetrecs
+  #   useTriggerStore: If true, the trigger store is used.
+  #   gettersin = array of input pseudojet builders (or name in gettersMap)
+  #   modifiersin = list of modifier tools (or name of such in modifiersMap)
+  #                 If absent, the gettersin name is used.
+  #   consumers = sequence of jet consumers to run after reco
+  #   ivtx = None: ordinary jet finding (unless gettersin = ztrack or pv0track)
+  #            -1: Separate finding fore each vertex
+  #           >=0: Finding only for vertex ivtx.
+  #   ghostArea: if > 0, then ghosts are found with this inverse density
+  #   ptminFilter: If > 0, then this is used as the pT threhold for filtering jets.
+  #   rndseed: RandomOption for the finder
+  #   isTrigger: If true, the trigger store is used and the tools is added to
+  #              trigjetrecs instead of jetrecs
+  #   useTriggerStore: If true, the trigger store is used (only for testing)
+  #   variableRMinRadius: Min radius for variable-R finding
+  #   variableRMassScale: Mass scale for variable-R finding
+  #   calibOpt: Calibration option, e.g. "ar". See JetRecCalibrationFinder.py.
+  def addJetFinder(self, output, alg, radius, gettersin, modifiersin =None,
+                   consumers =None, ivtxin =None,
+                   ghostArea =0.0, ptmin =0.0, ptminFilter =0.0, rndseed =1,
+                   isTrigger =False, useTriggerStore =False,
+                   variableRMinRadius =-1.0, variableRMassScale =-1.0,
+                   calibOpt ="", jetPseudojetCopier =""):
+    self.msg(2, "Adding finder")
+    from JetRec.JetRecConf import JetRecTool
+    if type(gettersin) == str:
+      getters = self.gettersMap[gettersin]
+    else:
+      getters = gettersin
+    # If jet finding by vertex is not specified, check for special input type names
+    ivtx = ivtxin
+    if ivtx == None:
+      if gettersin == "ztrack": ivtx = -1        # Find tracs separatesly for each vertex
+      elif gettersin == "pv0track": ivtx = 0     # Find tracks only for 1st vertex
+    # Retrieve/build the jet finder.
+    lofinder,hifinder = self.addJetFinderTool(output+"Finder", alg, radius, ivtx, ghostArea, ptmin, rndseed, 
+                                            variableRMinRadius, variableRMassScale)
+    jetrec = JetRecTool(output)
+    jetrec.PseudoJetGetters = getters
+    jetrec.JetFinder = hifinder
+    jetrec.OutputContainer = output
+    ptminSave = self.ptminFilter
+    if ptminFilter > 0.0: self.ptminFilter = ptminFilter
+    jetrec.JetModifiers = self.buildModifiers(modifiersin, lofinder, getters, gettersin, output, calibOpt)
+    if consumers != None:
+      jetrec.JetConsumers = consumers
+    self.ptminFilter = ptminSave
+    jetrec.Trigger = isTrigger or useTriggerStore
+    jetrec.Timer = self.timer
+    self += jetrec
+    if isTrigger:
+      self.trigjetrecs += [jetrec]
+    else:
+      self.jetrecs += [jetrec]
+    self.jetcons += [output]
+    return jetrec
+
+  # Create a mass-drop filter and rectool.
+  #   output = name for output container (and JetRecTool)
+  #   mumax = MuMax used in the filter
+  #   ymin = YMin used in the filter
+  #   input = name of the input jet container
+  #   modifiersin = list of modifier tools (or name of such in modifiersMap)
+  #   doArea = whether to write jet areas (default false because work is needed to 
+  #            recover this for reclustered jets).
+  def addJetSplitter(self, output, mumax, ymin, input, modifiersin ="groomed",
+                     isTrigger =False, useTriggerStore =False, doArea =True):
+    from JetRec.JetRecConf import JetSplitter
+    from JetRec.JetRecConf import JetRecTool
+    groomer = JetSplitter(output + "Groomer")
+    groomer.MuMax = mumax
+    groomer.YMin = ymin
+    groomer.BDRS = False
+    groomer.NSubjetMax = 3
+    if doArea:
+      groomer.JetBuilder = self.jetBuilderWithArea
+    else:
+      groomer.JetBuilder = self.jetBuilderWithoutArea
+    self += groomer
+    jetrec = JetRecTool(output)
+    jetrec.JetGroomer = groomer
+    jetrec.InputContainer = input
+    jetrec.OutputContainer = output
+    jetrec.JetModifiers = self.getModifiers(modifiersin)
+    jetrec.Trigger = isTrigger or useTriggerStore
+    jetrec.Timer = self.timer
+    self += jetrec
+    if isTrigger:
+      self.trigjetrecs += [jetrec]
+    else:
+      self.jetrecs += [jetrec]
+    self.jetcons += [output]
+    return jetrec
+
+  # Create a Trimmer and rectool.
+  #   output = name for output container (and JetRecTool)
+  #   rclus = RClus used in the trimming
+  #   ptfrac = PtFrac used in the trimming
+  #   input = name of the input jet container
+  #   modifiersin = list of modifier tools (or name of such in modifiersMap)
+  def addJetTrimmer(self, output, rclus, ptfrac, input, modifiersin ="groomed",
+                    pseudojetRetriever ="jpjretriever",
+                    isTrigger =False, useTriggerStore =False, doArea =True):
+    from JetRec.JetRecConf import JetTrimmer
+    from JetRec.JetRecConf import JetRecTool
+    groomer = JetTrimmer(output + "Groomer")
+    groomer.RClus = rclus
+    groomer.PtFrac = ptfrac
+    if doArea:
+      groomer.JetBuilder = self.jetBuilderWithArea
+    else:
+      groomer.JetBuilder = self.jetBuilderWithoutArea
+    self += groomer
+    jetrec = JetRecTool(output)
+    jetrec.JetGroomer = groomer
+    jetrec.InputContainer = input
+    jetrec.OutputContainer = output
+    jetrec.JetModifiers = self.getModifiers(modifiersin)
+    jetrec.Trigger = isTrigger or useTriggerStore
+    jetrec.Timer = self.timer
+    if pseudojetRetriever in self.tools:
+      jetrec.JetPseudojetRetriever = self.tools[pseudojetRetriever]
+    else:
+      print "Requested jet pseudojet retriever is not a registered tool: " \
+            + pseudojetRetriever
+      raise KeyError
+    self += jetrec
+    if isTrigger:
+      self.trigjetrecs += [jetrec]
+    else:
+      self.jetrecs += [jetrec]
+    self.jetcons += [output]
+    return jetrec
+
+  # Create a Pruner and rectool.
+  #   output = name for output container (and JetRecTool)
+  #   rcut = RCut used in the pruning
+  #   zcut = ZCut used in the pruning
+  #   input = name of the input jet container
+  #   modifiersin = list of modifier tools (or name of such in modifiersMap)
+  def addJetPruner(self, output, rcut, zcut, input, modifiersin ="groomed",
+                   isTrigger =False, useTriggerStore =False, doArea =True):
+    from JetRec.JetRecConf import JetPruner
+    from JetRec.JetRecConf import JetRecTool
+    groomer = JetPruner(output + "Groomer")
+    groomer.RCut = rcut
+    groomer.ZCut = zcut
+    if doArea:
+      groomer.JetBuilder = self.jetBuilderWithArea
+    else:
+      groomer.JetBuilder = self.jetBuilderWithoutArea
+    self += groomer
+    jetrec = JetRecTool(output)
+    jetrec.JetGroomer = groomer
+    jetrec.InputContainer = input
+    jetrec.OutputContainer = output
+    jetrec.JetModifiers = self.getModifiers(modifiersin)
+    jetrec.Trigger = isTrigger or useTriggerStore
+    jetrec.Timer = self.timer
+    self += jetrec
+    if isTrigger:
+      self.trigjetrecs += [jetrec]
+    else:
+      self.jetrecs += [jetrec]
+    self.jetcons += [output]
+    return jetrec
+
+  # Create a jet reclusterer and rectool.
+  #   output = name for output container (and JetRecTool)
+  #   alg = akgorithm name (Kt, CamKt, AntiKt)
+  #   radius = size parameter
+  #   input = name for the input jet collection
+  #   rndseed: RandomOption for the finder
+  #   isTrigger: If true, the trigger store is used and the tools is added to
+  #              trigjetrecs instead of jetrecs
+  #   useTriggerStore: If true, the trigger store is used.
+  #   modifiersin = list of modifier tools (or name of such in modifiersMap)
+  #                 If absent, the gettersin name is used.
+  #   consumers = sequence of jet consumers to run after reco
+  #   ivtx = None: ordinary jet finding (unless gettersin = ztrack or pv0track)
+  #            -1: Separate finding fore each vertex
+  #           >=0: Finding only for vertex ivtx.
+  #   ghostArea: if > 0, then ghosts are found with this inverse density
+  #   ptminFilter: If > 0, then this is used as the pT threhold for filtering jets.
+  #   rndseed: RandomOption for the finder
+  #   isTrigger: If true, the trigger store is used and the tools is added to
+  #              trigjetrecs instead of jetrecs
+  #   useTriggerStore: If true, the trigger store is used (only for testing)
+  #   variableRMinRadius: Min radius for variable-R finding
+  #   variableRMassScale: Mass scale for variable-R finding
+  #   calibOpt: Calibration option, e.g. "ar". See JetRecCalibrationFinder.py.
+  def addJetReclusterer(self, output, alg, radius, input, modifiersin =None,
+                        consumers =None, ivtx =None,
+                        ghostArea =0.0, ptmin =0.0, ptminFilter =0.0, rndseed =1,
+                        isTrigger =False, useTriggerStore =False,
+                        variableRMinRadius =-1.0, variableRMassScale =-1.0,
+                        calibOpt ="", jetPseudojetCopier =""):
+    self.msg(2, "Adding reclusterer")
+    from JetRec.JetRecConf import JetRecTool
+    from JetRec.JetRecConf import JetReclusterer
+    # Retrieve/build the jet finder.
+    lofinder,hifinder = self.addJetFinderTool(output+"Finder", alg, radius, ivtx, ghostArea, ptmin, rndseed, 
+                                              variableRMinRadius, variableRMassScale)
+    reclname = output + "Reclusterer"
+    groomer = JetReclusterer(
+      reclname,
+      JetConstituentsRetriever = self.tools["jconretriever"],
+      JetFinder = hifinder
+    )
+    self += groomer
+    jetrec = JetRecTool(output)
+    jetrec.InputContainer = input
+    jetrec.OutputContainer = output
+    jetrec.JetGroomer = groomer
+    jetrec.JetModifiers = self.getModifiers(modifiersin)
+    if consumers != None:
+      jetrec.JetConsumers = consumers
+    jetrec.Trigger = isTrigger or useTriggerStore
+    jetrec.Timer = self.timer
+    self += jetrec
+    if isTrigger:
+      self.trigjetrecs += [jetrec]
+    else:
+      self.jetrecs += [jetrec]
+    self.jetcons += [output]
+    return jetrec
+
+  # Create a copying rectool.
+  #   output = name for output container (and JetRecTool)
+  #   output = name for input container
+  #   modifiersin = list of modifier tools (or name of such in modifiersMap)
+  def addJetCopier(self, output, input, modifiersin, ptminFilter =0.0, radius =0.0, alg ="", inp ="",
+                   isTrigger=False, useTriggerStore=False, calibOpt ="", shallow =True):
+    from JetRec.JetRecConf import JetRecTool
+    jetrec = JetRecTool(output)
+    jetrec.InputContainer = input
+    jetrec.OutputContainer = output
+    ptminSave = self.ptminFilter
+    if ptminFilter > 0.0: self.ptminFilter = ptminFilter
+    class finder:
+      JetRadius = radius
+      JetAlgorithm = alg
+    class get:
+      Label = inp
+    getters = [get]
+    jetrec.JetModifiers = self.buildModifiers(modifiersin, finder, getters, None, output, calibOpt)
+    self.ptminFilter = ptminSave
+    jetrec.Trigger = isTrigger or useTriggerStore
+    jetrec.Timer = self.timer
+    jetrec.ShallowCopy = shallow
+    self += jetrec
+    self.jetrecs += [jetrec]
+    self.jetcons += [output]
+    return jetrec
+
+  # Ad op[] to return a tool.
+  def __getitem__(self, toolname):
+    return self.tools[toolname]
+
+  # Change the output level of a tool.
+  def setOutputLevel(self, toolid, level):
+    from GaudiKernel.Proxy.Configurable import ConfigurableAlgTool
+    if type(toolid) == str:
+      tool = self[toolid]
+    else:
+      tool = toolid
+    locked = tool.isLocked()
+    oldlevel = "undefined"
+    if locked:
+      dbglvl = 0
+      slock = "locked"
+      tool.unlock()
+    else:
+      dbglvl = 1
+      slock = "unlocked"
+    aname = "OutputLevel"
+    if hasattr(tool, aname):
+      oldlevel = getattr(tool, aname)
+    setattr(tool, aname, level)
+    if locked:
+      tool.lock()
+    self.msg(0, "Changed output level of " + slock + " tool " + tool.name() + \
+             " from " + str(oldlevel) + " to " + str(level) + ".")
+
diff --git a/Reconstruction/Jet/JetRecConfig/python/__init__.py b/Reconstruction/Jet/JetRecConfig/python/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..74583d364ec2ca794156596c7254d9b234a940c6
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/python/__init__.py
@@ -0,0 +1,2 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
diff --git a/Reconstruction/Jet/JetRecConfig/share/JetRec_jobOptions.py b/Reconstruction/Jet/JetRecConfig/share/JetRec_jobOptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..297bbfd593f6e3a01c1f0a203334091da92fec34
--- /dev/null
+++ b/Reconstruction/Jet/JetRecConfig/share/JetRec_jobOptions.py
@@ -0,0 +1,85 @@
+# JetRec_jobOptions.py
+#
+# David Adams
+# February 2014
+#
+# RecExCommon job options for running jet reconstruction.
+#
+# Run with
+# > athena.py test_RunJetRec.py
+#
+
+myname = "JetRec_jobOptions: "
+print myname + "Begin."
+
+# Import the jet tool manager.
+from JetRecConfig.JetRecStandard import jtm
+
+#--------------------------------------------------------------
+# Define the finders and groomers.
+# Each line configures a finder or groomer and its associated jetrec tool.
+# The first argument is the name of the output collection and the jetrec tool.
+# The fifth argument is the list of modifiers.
+# Non-zero ghostArea enables calculation of active area.
+#--------------------------------------------------------------
+
+# Finders.
+from JetRecConfig.JetRecFlags import jetFlags
+if jetFlags.useTruth():
+  jtm.addJetFinder("AntiKt4TruthJets",    "AntiKt", 0.4,    "truth", ptmin= 5000)
+  jtm.addJetFinder("AntiKt4TruthWZJets",  "AntiKt", 0.4,  "truthwz", ptmin= 5000)
+  jtm.addJetFinder("AntiKt10TruthJets",   "AntiKt", 1.0,    "truth", ptmin=40000)
+  jtm.addJetFinder("AntiKt10TruthWZJets", "AntiKt", 1.0,  "truthwz", ptmin=40000)
+  jtm.addJetFinder("CamKt12TruthJets",     "CamKt", 1.2,    "truth", ptmin=40000)
+  jtm.addJetFinder("CamKt12TruthWZJets",   "CamKt", 1.2,  "truthwz", ptmin=40000)
+if jetFlags.useTracks():
+  jtm.addJetFinder("AntiKt2PV0TrackJets", "AntiKt", 0.2, "pv0track", ptmin= 2000)
+  jtm.addJetFinder("AntiKt3PV0TrackJets", "AntiKt", 0.3, "pv0track", ptmin= 2000)
+  jtm.addJetFinder("AntiKt4PV0TrackJets", "AntiKt", 0.4, "pv0track", ptmin= 2000)
+if jetFlags.useTopo():
+  jtm.addJetFinder("AntiKt4EMTopoJets",   "AntiKt", 0.4,   "emtopo", "calib", ghostArea=0.01, ptmin= 2000, ptminFilter= 5000, calibOpt="aro")
+  jtm.addJetFinder("AntiKt4LCTopoJets",   "AntiKt", 0.4,   "lctopo", "calib", ghostArea=0.01, ptmin= 2000, ptminFilter= 7000, calibOpt="aro")
+  jtm.addJetFinder("AntiKt10LCTopoJets",  "AntiKt", 1.0,   "lctopo", "calib", ghostArea=0.01, ptmin= 2000, ptminFilter=50000, calibOpt="none")
+  jtm.addJetFinder("CamKt12LCTopoJets",    "CamKt", 1.2,   "lctopo", "calib", ghostArea=0.01, ptmin= 2000, ptminFilter=50000, calibOpt="none")
+if jetFlags.usePFlow():
+  jtm.addJetFinder("AntiKt4EMPFlowJets",  "AntiKt", 0.4,  "empflow", "pflow", ghostArea=0.01, ptmin= 2000, ptminFilter= 5000, calibOpt="a:pflow")
+
+#--------------------------------------------------------------
+# Build output container list.
+#--------------------------------------------------------------
+
+# Both standard and aux container must be listed explicitly.
+# For release 19, the container version must be explicit.
+
+for jetrec in jtm.jetrecs:
+  jetFlags.jetAODList += [ "xAOD::JetContainer#" + jetrec.name() ]
+  auxprefix = ""
+  if jetrec.Trigger:
+    auxprefix = "Trig"
+  jetFlags.jetAODList += [ "xAOD::Jet" + auxprefix + "AuxContainer#" + jetrec.name() + "Aux." ]
+
+
+# For testing. These blocks should not be enabled in production.
+if jetFlags.debug > 0:
+  jetlog.info( "JetRec_jobOptions.py: Requested output stream: ")
+  jetlog.info( "%s", jetFlags.jetAODList )
+if jetFlags.debug > 1:
+  jetlog.info( "JetRec_jobOptions.py: Setting output level to DEBUG for all jetrecs")
+  for jetrec in jtm.jetrecs:
+    jtm.setOutputLevel(jetrec, DEBUG)
+
+#--------------------------------------------------------------
+# Add jet reco to algorithm sequence.
+#--------------------------------------------------------------
+from JetRecConfig.JetAlgorithm import addJetRecoToAlgSequence
+addJetRecoToAlgSequence()
+
+#--------------------------------------------------------------
+# save event shapes set with the JetAlgorithm
+#--------------------------------------------------------------
+for esTool in jtm.jetrun.EventShapeTools :
+    t = getattr(ToolSvc, esTool.getName() )
+    jetFlags.jetAODList += [ "xAOD::EventShape#"+t.OutputContainer,
+                             "xAOD::EventShapeAuxInfo#"+t.OutputContainer+'Aux.' ]
+
+print myname + "Begin."