diff --git a/python/EventStore.py b/python/EventStore.py deleted file mode 100644 index 5607f2da0..000000000 --- a/python/EventStore.py +++ /dev/null @@ -1,6 +0,0 @@ -"""Legacy import wrapper for EventStore.""" - -import warnings -warnings.warn("You are using the legacy EventStore import. Switch to 'from podio import EventStore'", FutureWarning) - -from podio import EventStore # noqa: F401 # pylint: disable=wrong-import-position, unused-import diff --git a/python/podio/EventStore.py b/python/podio/EventStore.py deleted file mode 100644 index d2df33cbe..000000000 --- a/python/podio/EventStore.py +++ /dev/null @@ -1,140 +0,0 @@ -"""Python EventStore for reading files with podio generated datamodels""" - -import warnings -warnings.warn("The EventStore based I/O model is deprecated and will be removed. Switch to the Frame based model.", - FutureWarning) - -from ROOT import gSystem # pylint: disable=wrong-import-position -gSystem.Load("libpodioPythonStore") # noqa: E402 -from ROOT import podio # noqa: E402 # pylint: disable=wrong-import-position - - -def size(self): - """Override size function that can be attached as __len__ method to - collections""" - return self.size() - - -def getitem(self, key): - """Override getitem function that can be attached as __getitem__ method to - collections (see below why this is necessary sometimes)""" - return self.at(key) - - -class EventStore: - '''Interface to events in an podio root file. - Example of use: - events = EventStore(["example.root", "example1.root"]) - for iev, store in islice(enumerate(events), 0, 2): - particles = store.get("GenParticle"); - for i, p in islice(enumerate(particles), 0, 5): - print "particle ", i, p.ID(), p.P4().Pt - ''' - - def __init__(self, filenames): - '''Create an event list from the podio root file. - Parameters: - filenames: list of root files - you can of course provide a list containing a single - root file. you could use the glob module to get all - files matching a wildcard pattern. - ''' - if isinstance(filenames, str): - filenames = (filenames,) - self.files = filenames - self.stores = [] - self.current_store = None - for fname in self.files: - store = podio.PythonEventStore(fname) - if store.isZombie(): - raise ValueError(fname + ' does not exist.') - store.name = fname - if self.current_store is None: - self.current_store = store - self.stores.append((store.getEntries(), store)) - - def __str__(self): - result = "Content:" - for item in self.current_store.getCollectionNames(): - result += f"\n\t{item}" - return result - - def get(self, name): - '''Returns a collection. - Parameters: - name: name of the collection in the podio root file. - ''' - coll = self.current_store.get(name) - # adding length function - coll.__len__ = size - # enabling the use of [] notation on the collection - # cppyy defines the __getitem__ method if the underlying c++ class has an operator[] - # method. For some reason they do not conform to the usual signature and only - # pass one argument to the function they call. Here we simply check if we have to - # define the __getitem__ for the collection. - if not hasattr(coll, '__getitem__'): - coll.__getitem__ = getitem - return coll - - def collections(self): - """Return list of all collection names.""" - return [str(c) for c in self.current_store.getCollectionNames()] - - def metadata(self): - """Get the metadata of the current event as GenericParameters""" - return self.current_store.getEventMetaData() - - def isValid(self): - """Check if the EventStore is in a valid state""" - return self.current_store is not None and self.current_store.isValid() - - # def __getattr__(self, name): - # '''missing attributes are taken from self.current_store''' - # if name != 'current_store': - # return getattr(self.current_store, name) - # else: - # return None - - def current_filename(self): - '''Returns the name of the current file.''' - if self.current_store is None: - return None - return self.current_store.fname - - def __enter__(self): - return self - - def __exit__(self, exception_type, exception_val, trace): - for store in self.stores: - store[1].close() - - def __iter__(self): - '''iterate on events in the tree. - ''' - for _, store in self.stores: - self.current_store = store - for _ in range(store.getEntries()): - yield store - store.endOfEvent() - - def __getitem__(self, evnum): - '''Get event number evnum''' - current_store = None - rel_evnum = evnum - for nev, store in self.stores: - if rel_evnum < nev: - current_store = store - break - rel_evnum -= nev - if current_store is None: - raise ValueError('event number too large: ' + str(evnum)) - self.current_store = current_store - self.current_store.goToEvent(rel_evnum) - return self - - def __len__(self): - '''Returns the total number of events in all files.''' - nevts_all_files = 0 - for nev, _ in self.stores: - nevts_all_files += nev - return nevts_all_files diff --git a/python/podio/test_EventStore.py b/python/podio/test_EventStore.py deleted file mode 100644 index a8e4fb965..000000000 --- a/python/podio/test_EventStore.py +++ /dev/null @@ -1,95 +0,0 @@ -"""Unit tests for the EventStore class""" - -from podio.EventStore import EventStore - - -class EventStoreBaseTestCaseMixin: - """EventStore unit tests - - These define some tests that should work regardless of the backend that is - used. In order to not have to duplicate this functionality for each backend, - this base class defines the common tests and inheriting classes define a - corresponding setUp method that sets up the correct EventStore and potentially - additional backend specific functionality - """ - def test_eventloop(self): - self.assertTrue(len(self.store) >= 0) - self.assertEqual(self.store.current_store.getEntries(), - len(self.store)) - for iev, event in enumerate(self.store): - self.assertTrue(event is not None) - if iev > 5: - break - - def test_navigation(self): - event0 = self.store[0] - self.assertEqual(event0.__class__, self.store.__class__) - - def test_collections(self): - evinfo = self.store.get("info") - self.assertTrue(len(evinfo) > 0) - particles = self.store.get("CollectionNotThere") - self.assertFalse(particles) - - def test_read_only(self): - hits = self.store.get("hits") - # testing that one can't modify attributes in - # read-only pods - self.assertEqual(hits[0].energy(), 23.) - hits[0].energy(10) - self.assertEqual(hits[0].energy(), 10) # oops - - def test_one_to_many(self): - clusters = self.store.get("clusters") - ref_hits = [] - # testing that cluster hits can be accessed and make sense - for cluster in clusters: - sume = 0 - for ihit in range(cluster.Hits_size()): - hit = cluster.Hits(ihit) - ref_hits.append(hit) - sume += hit.energy() - self.assertEqual(cluster.energy(), sume) - hits = self.store.get("hits") - # testing that the hits stored as a one to many relation - # in the cluster can be found in the hit collection - for hit in ref_hits: - self.assertTrue(hit in hits) - - def test_relation_range(self): - """Test that the RelationRange functionality is also accessible in python""" - clusters = self.store.get("clusters") - hits = self.store.get("hits") - - for cluster in clusters: - sume = 0 - for hit in cluster.Hits(): - self.assertTrue(hit in hits) - sume += hit.energy() - self.assertEqual(cluster.energy(), sume) - - def test_hash(self): - clusters = self.store.get("clusters") - ref_hits = [] - # testing that cluster hits can be accessed and make sense - for cluster in clusters: - sume = 0 - for ihit in range(cluster.Hits_size()): - hit = cluster.Hits(ihit) - ref_hits.append(hit) - sume += hit.energy() - self.assertEqual(cluster.energy(), sume) - hits = self.store.get("hits") - if hits[0] == ref_hits[0]: - self.assertEqual(hits[0].getObjectID().index, - ref_hits[0].getObjectID().index) - self.assertEqual(hits[0].getObjectID().collectionID, - ref_hits[0].getObjectID().collectionID) - self.assertEqual(hits[0].getObjectID(), ref_hits[0].getObjectID()) - # testing that the hits stored as a one to many relation - # import pdb; pdb.set_trace() - - def test_context_managers(self): - with EventStore([self.filename]) as store: - self.assertTrue(len(store) >= 0) - self.assertTrue(store.isValid()) diff --git a/python/podio/test_EventStoreRoot.py b/python/podio/test_EventStoreRoot.py deleted file mode 100644 index b9f3830dd..000000000 --- a/python/podio/test_EventStoreRoot.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 -"""Python unit tests for the ROOT backend""" - -import unittest -import os - -from ROOT import TFile - -from podio.EventStore import EventStore -from podio.test_EventStore import EventStoreBaseTestCaseMixin - - -class EventStoreRootTestCase(EventStoreBaseTestCaseMixin, unittest.TestCase): - """Test cases for root input files""" - def setUp(self): - """Setup an EventStore reading from a ROOT file""" - self.filename = 'root_io/example.root' - self.assertTrue(os.path.isfile(self.filename)) - self.store = EventStore([self.filename]) - - def test_chain(self): - self.store = EventStore([self.filename, - self.filename]) - rootfile = TFile(self.filename) - events = rootfile.Get(str('events')) - numbers = [] - for iev, _ in enumerate(self.store): - evinfo = self.store.get("info") - numbers.append(evinfo[0].Number()) - self.assertEqual(iev + 1, 2 * events.GetEntries()) # pylint: disable=undefined-loop-variable - # testing that numbers is [0, .. 1999, 0, .. 1999] - self.assertEqual(numbers, list(range(events.GetEntries())) * 2) - # trying to go to an event beyond the last one - self.assertRaises(ValueError, self.store.__getitem__, 4001) - # this is in the first event in the second file, - # so its event number should be 0. - self.assertEqual(self.store[2000].get("info")[0].Number(), 0) - - def test_no_file(self): - '''Test that non-accessible files are gracefully handled.''' - with self.assertRaises(ValueError): - self.store = EventStore('foo.root') - - -if __name__ == '__main__': - # NOTE: These tests are really not intended to be run directly as they depend - # on quite some environment setup as well as externally produced inputs. - # See the CMakeLists.txt file in the tests folder for the specifics of that - # environment and the inputs - unittest.main() diff --git a/python/podio/test_EventStoreSio.py b/python/podio/test_EventStoreSio.py deleted file mode 100644 index 511da07d8..000000000 --- a/python/podio/test_EventStoreSio.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python3 -"""Python unit tests for the SIO backend""" - -import unittest -import os - -from podio.EventStore import EventStore -from podio.test_EventStore import EventStoreBaseTestCaseMixin -from podio.test_utils import SKIP_SIO_TESTS - - -@unittest.skipIf(SKIP_SIO_TESTS, "no SIO support") -class EventStoreSioTestCase(EventStoreBaseTestCaseMixin, unittest.TestCase): - """Test cases for root input files""" - def setUp(self): - """setup an EventStore reading an SIO file""" - self.filename = 'sio_io/example.sio' - self.assertTrue(os.path.isfile(self.filename)) - self.store = EventStore([self.filename]) - - def test_no_file(self): - '''Test that non-accessible files are gracefully handled.''' - with self.assertRaises(ValueError): - self.store = EventStore('foo.sio') - - -if __name__ == '__main__': - # NOTE: These tests are really not intended to be run directly as they depend - # on quite some environment setup as well as externally produced inputs. - # See the CMakeLists.txt file in the tests folder for the specifics of that - # environment and the inputs - unittest.main()