diff --git a/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/PyAnalysisCore/PyAnalysisCoreDict.h b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/PyAnalysisCore/PyAnalysisCoreDict.h
new file mode 100755
index 0000000000000000000000000000000000000000..a6764f0a3ab1f159438cee7a772be4d3cbef0366
--- /dev/null
+++ b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/PyAnalysisCore/PyAnalysisCoreDict.h
@@ -0,0 +1,11 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef PYANALYSISCORE_PYKERNELDICT_H
+#define PYANALYSISCORE_PYKERNELDICT_H
+
+#include "PyAnalysisCore/PyClassIDSvc.h"
+#include "PyAnalysisCore/PyDataHeader.h"
+
+#endif
diff --git a/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/PyAnalysisCore/PyClassIDSvc.h b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/PyAnalysisCore/PyClassIDSvc.h
new file mode 100755
index 0000000000000000000000000000000000000000..cb7bce84e695d9543f97b10b84ef330878776bf2
--- /dev/null
+++ b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/PyAnalysisCore/PyClassIDSvc.h
@@ -0,0 +1,47 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef PYANALYSISCORE_PYCLASSIDSVC_H
+#define PYANALYSISCORE_PYCLASSIDSVC_H
+
+/**
+   A wrapper for ClassIDSvc
+
+    @author Tadashi Maeno
+*/
+ 
+#include "AthenaKernel/IClassIDSvc.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/MsgStream.h"
+#include "AthenaKernel/getMessageSvc.h"
+
+struct PyClassIDSvc
+{
+  /// get type name associated with clID (if any)
+  static std::string getTypeNameOfID (const unsigned int id)
+  {
+    IClassIDSvc *pSvc = 0;
+    Gaudi::svcLocator()->service("ClassIDSvc", pSvc);
+    if (!pSvc)
+      {
+	MsgStream log(Athena::getMessageSvc(), "PyClassIDSvc");
+	log << MSG::ERROR << "could not get ClassIDSvc" << endreq;
+	return "";
+      }
+    
+    std::string name;
+    StatusCode sc = pSvc->getTypeNameOfID (id, name);
+    if (sc.isFailure())
+      {
+	MsgStream log(Athena::getMessageSvc(), "PyClassIDSvc");
+	log << MSG::ERROR << "could not get TypeName for " << id << endreq;
+      }
+    return name;
+  }
+};
+
+#endif
+
+  
diff --git a/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/PyAnalysisCore/PyDataHeader.h b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/PyAnalysisCore/PyDataHeader.h
new file mode 100755
index 0000000000000000000000000000000000000000..94bc51323512737c51c100b991b797d581118707
--- /dev/null
+++ b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/PyAnalysisCore/PyDataHeader.h
@@ -0,0 +1,118 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef PYANALYSISCORE_PYDATAHEADER_H
+#define PYANALYSISCORE_PYDATAHEADER_H
+
+/**
+   A wrapper for DataHeader
+
+    @author Tadashi Maeno
+*/
+ 
+#include "PersistentDataModel/DataHeader.h"
+#include "StoreGate/StoreGateSvc.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/MsgStream.h"
+#include "AthenaKernel/getMessageSvc.h"
+
+#include <vector>
+
+class PyDataHeader
+{
+public:
+  PyDataHeader () : m_DataHeaderElementV(0)
+  {
+    MsgStream log(Athena::getMessageSvc(), "PyDataHeader");
+
+    // get StoreGate
+    StoreGateSvc *pSvc = 0;
+    StatusCode sc = Gaudi::svcLocator()->service("StoreGateSvc", pSvc);
+    if (sc.isFailure())
+      log << MSG::ERROR << "could not get StoreGateSvc" << endreq;
+    else
+      {
+	// retrieve DataHeader
+	const DataHandle<DataHeader> beg; 
+	const DataHandle<DataHeader> ending; 
+	sc = pSvc->retrieve(beg,ending);
+	if (sc.isFailure() || beg==ending)
+	  log << MSG::ERROR << "could not get DataHeader" << endreq;
+	else
+	  {
+	    // cache DataHeaderElement
+	    for (; beg != ending; ++beg)
+	      {
+		DataHeader &dh = const_cast<DataHeader &>(*beg);
+		std::vector<DataHeaderElement>::const_iterator it = dh.begin();
+		for (; it != dh.end(); ++it)
+		  m_DataHeaderElementV.push_back(const_cast<DataHeaderElement *>(&*it));
+	      }
+	  }
+      }
+
+    m_classIDSvc = 0;
+    sc = Gaudi::svcLocator()->service("ClassIDSvc", m_classIDSvc);
+    if (sc.isFailure())
+      log << MSG::ERROR << "could not get ClassIDSvc" << endreq;
+  }
+
+  virtual ~PyDataHeader () {}
+
+  //! get number of elements
+  int size() { return m_DataHeaderElementV.size(); }
+
+  //! get class name of Nth element
+  std::string getName (int index)
+  {
+    if (index >= size()) return "";
+    std::vector<DataHeaderElement *>::iterator it = m_DataHeaderElementV.begin();
+    it += index;
+
+    // look for non-symlink name
+    std::string name="";
+    std::set<CLID>::iterator itCLID  = ((*it)->getClassIDs()).begin();
+    std::set<CLID>::iterator itCLIDe = ((*it)->getClassIDs()).end();
+    for (; itCLID != itCLIDe; ++itCLID)
+      {
+	// convert CLID to class name
+	std::string localName;
+	StatusCode sc = m_classIDSvc->getTypeNameOfID (*itCLID, localName);
+	if (sc.isFailure()) 
+	  {
+	    MsgStream log(Athena::getMessageSvc(), "PyDataHeader");
+	    log << MSG::ERROR << "could not get TypeName for " << *itCLID << endreq;
+	    return "";
+	  }
+	// select non-symlink
+	if ((name == "") || 
+	    ((localName != "ParticleBaseContainer") && 
+	     (localName != "IParticleContainer") &&
+	     (localName != "INavigable4MomentumCollection")))
+	  name = localName;
+      }
+    return name;
+  }
+
+  //! get key of Nth element
+  std::string getKey (int index)
+  {
+    if (index >= size()) return "";
+    std::vector<DataHeaderElement *>::iterator it = m_DataHeaderElementV.begin();
+    it += index;
+    return (*it)->getKey();
+  }
+
+private:
+  //! cash for DataHeaderElements
+  std::vector<DataHeaderElement *> m_DataHeaderElementV;
+
+  //!  class ID service
+  IClassIDSvc *m_classIDSvc;
+};
+
+#endif
+
+  
diff --git a/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/PyAnalysisCore/selection.xml b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/PyAnalysisCore/selection.xml
new file mode 100755
index 0000000000000000000000000000000000000000..57a4d3ab595e42137e98d48763f19f7be4c1c218
--- /dev/null
+++ b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/PyAnalysisCore/selection.xml
@@ -0,0 +1,6 @@
+<lcgdict>
+
+  <class name="PyClassIDSvc" />
+  <class name="PyDataHeader" />
+  
+</lcgdict>
\ No newline at end of file
diff --git a/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/cmt/requirements b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/cmt/requirements
new file mode 100755
index 0000000000000000000000000000000000000000..af5a75a3c49cb62b8f59b6dbe3cc3fe1576c3d1f
--- /dev/null
+++ b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/cmt/requirements
@@ -0,0 +1,19 @@
+package PyAnalysisCore
+
+author Tadashi Maeno <Tadashi.Maeno@cern.ch>
+
+use AtlasPolicy		AtlasPolicy-*
+use GaudiInterface      GaudiInterface-*        External
+use AthenaKernel	AthenaKernel-*	        Control
+use StoreGate		StoreGate-*		Control
+use PersistentDataModel	PersistentDataModel-*	Database
+
+apply_pattern declare_joboptions     files="*.py"
+apply_pattern declare_python_modules files="*.py"
+
+private
+
+use AtlasReflex  AtlasReflex-*  External -no_auto_imports
+
+apply_pattern lcgdict dict=PyAnalysisCore selectionfile=selection.xml \
+        headerfiles="../PyAnalysisCore/PyAnalysisCoreDict.h"
\ No newline at end of file
diff --git a/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/python/PyEventTools.py b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/python/PyEventTools.py
new file mode 100755
index 0000000000000000000000000000000000000000..a2397a5e7965cb0cbe2fb400e38f727e7ea8cc88
--- /dev/null
+++ b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/python/PyEventTools.py
@@ -0,0 +1,24 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+"""module to access Event objects interactively
+
+:author: Tadashi Maeno
+:contact: Tadashi.Maeno@cern.ch
+
+"""
+__docformat__ = "restructuredtext en"
+
+from PyKernel import PyKernel as PyK
+
+def getEventInfo (aKey):
+    """Retrieve EventInfo object from SG
+
+    :param aKey: key of the object
+
+    **examples**::
+
+      athena> e = PyEventTools.getEventInfo('McEventInfo')
+      athena> print e.event_ID().event_number()
+    
+    """
+    return PyK.retrieve(PyK.GNS.EventInfo,aKey)
diff --git a/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/python/PyTruthTools.py b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/python/PyTruthTools.py
new file mode 100755
index 0000000000000000000000000000000000000000..b1b09da2af8bbc46ebde386902ad53a58526cb46
--- /dev/null
+++ b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/python/PyTruthTools.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+"""module to access truth objects interactively
+
+Example is in `PyAnalysisExamples/TruthTest.py`_
+
+.. _PyAnalysisExamples/TruthTest.py: http://atlas-sw.cern.ch/cgi-bin/viewcvs-atlas.cgi/offline/PhysicsAnalysis/PyAnalysis/PyAnalysisExamples/share/TruthTest.py?rev=HEAD&content-type=text/vnd.viewcvs-markup
+
+
+:author: Tadashi Maeno
+:contact: Tadashi.Maeno@cern.ch
+
+"""
+__docformat__ = "restructuredtext en"
+
+from PyKernel import PyKernel as PyK
+
+def getMcEvents (aKey):
+    """Retrieve McEventCollection object from SG
+
+    :param aKey: key of the object
+
+    **examples**::
+
+      athena> mcc = PyTruthTools.getMcEvents('GEN_EVENT')
+      athena> len(mcc)
+      athena> mc = mcc[0]
+      athena> mc.alphaQCD()
+      athena> it  = mc.particles_begin()       # GenEvent::particles_begin() and _end() give ietrators
+      athena> itE = mc.particles_end()  
+      athena> while (it != itE):               # loop over all particles
+      ...  p = it.next()                       # dereference and increment the ietrator
+      ...  print p.pdg_id()
+      ...                                      # just hit return key
+
+
+    **Note:** Some methods of GenEvent_/GenVertex_, e.g., particles_begin(), give an iterator. One may use it like as a python iterator. But don't try 'for i in iterator:'. It should cause a crash since an iterator of C++ doesn't know it's boundary.
+
+    .. _GenEvent: http://reserve02.usatlas.bnl.gov/lxr/source/atlas/Simulation/HepMC/HepMC/GenEvent.h
+    .. _GenVertex: http://reserve02.usatlas.bnl.gov/lxr/source/atlas/Simulation/HepMC/HepMC/GenVertex.h
+    
+    """
+    return PyK.retrieve(PyK.GNS.McEventCollection,aKey)
diff --git a/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/python/__init__.py b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/python/__init__.py
new file mode 100755
index 0000000000000000000000000000000000000000..74583d364ec2ca794156596c7254d9b234a940c6
--- /dev/null
+++ b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/python/__init__.py
@@ -0,0 +1,2 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
diff --git a/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/share/InitPyAnalysisCore.py b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/share/InitPyAnalysisCore.py
new file mode 100755
index 0000000000000000000000000000000000000000..17d39619958209a38d86d0ed4e522033b11a6c6f
--- /dev/null
+++ b/PhysicsAnalysis/PyAnalysis/PyAnalysisCore/share/InitPyAnalysisCore.py
@@ -0,0 +1,13 @@
+import PyCintex
+
+# load Dictionaries and Tools
+from PyAnalysisCore  import PyEventTools
+from PyAnalysisCore  import PyTruthTools
+from PyParticleTools import PyParticleTools
+from PyTriggerTools  import PyTriggerTools
+
+# seek
+include ('AthenaServices/ReadAthenaPoolSeek_jobOptions.py')
+
+# this must be the last one, since proxy classes are patched by this
+include ('PyKernel/InitPyKernel.py')