Source code for opal.parser.H5Parser

# Copyright (c) 2018, Matthias Frey, Paul Scherrer Institut, Villigen PSI, Switzerland
# All rights reserved
#
# Implemented as part of the PhD thesis
# "Precise Simulations of Multibunches in High Intensity Cyclotrons"
#
# This file is part of pyOPALTools.
#
# pyOPALTools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# You should have received a copy of the GNU General Public License
# along with pyOPALTools. If not, see <https://www.gnu.org/licenses/>.

import h5py
import numpy as np
from .H5Error import H5ParseError, H5DatasetError, H5OverflowError
from .BaseParser import BaseParser

[docs]class H5Parser(BaseParser):
[docs] def __init__(self): """Constructor. """ self.__filename = '' self.__h5f = '' self.__nsteps = 0
[docs] def parse(self, fname, info = False): """Read a H5 file generated by OPAL Parameters ---------- fname : str H5 filename info : bool, optional Print H5 file summary """ self.__filename = fname self.__h5f = h5py.File(fname, 'r') self.__step_prefix = 'Step#' if self.__h5f: self.__nsteps = len(self.__h5f.keys()) if 'Attachment' in self.__h5f.keys(): self.__nsteps -= 1 if info: print ( self.__str__() ) else: raise H5ParseError("Cannot read '" + fname + "'")
[docs] def clear(self): """Clear data. """ self.close()
[docs] def close(self): """Closes h5 file. """ if self.__h5f: del self.__h5f self.__h5f = '' self.__filename = '' self.__nsteps = 0
[docs] def getNSteps(self): """Number of steps in file. Returns ------- int The number of steps """ return self.__nsteps
[docs] def getStepAttributes(self, step = 0): """Attributes names of a step. Parameters ---------- step : int, optional Steps of file Returns ------- list [str] All attribute names of a step """ self._check_step(step) path = self.__step_prefix + str(step) return list(self.__h5f[path].attrs.keys())
[docs] def getStepDatasets(self, step = 0): """All step dataset names. Parameters ---------- step : int, optional Steps of file Returns ------- list [str] All attribute names of a step """ self._check_step(step) path = self.__step_prefix + str(step) return list(self.__h5f[path].keys())
[docs] def getStepDataset(self, dsetName, step=0): """Obtain the data of a step. Parameters ---------- dsetName : str Name of dataset step : int, optional Steps of file Returns ------- numpy.ndarray, (N,) Array of a dataset of a step (check with getStepDatasets()) """ self._check_step(step) if not dsetName in self.getStepDatasets(step): raise H5DatasetError("'" + dsetName + "' is not a dataset of this step") data = [] path = self.__step_prefix + str(step) + '/' + dsetName return np.asarray(self.__h5f[path])
[docs] def getStepAttribute(self, attrName, step=0): """Obtain the attribute data of a step. Parameters ---------- attrName : str Name of attribute step : int, optional Steps of file """ self._check_step(step) data = [] path = self.__step_prefix + str(step) data = self.__h5f[path].attrs[attrName] return data[:]
[docs] def getGlobalAttributes(self): """All attributes of root. Returns ------- list A list of strings of all root attributes """ return list(self.__h5f.attrs.keys())
[docs] def getGlobalAttribute(self, attrName): """Obtain value of global attribute. Parameters ---------- attrName : str Name of global attribute Returns ------- str Value as string. """ value = self.__h5f.attrs[attrName] # 7. March 2018 # https://stackoverflow.com/questions/37016946/remove-b-character-do-in-front-of-a-string-literal-in-python-3 return value.decode("utf-8")
[docs] def _check_step(self, step): if step > self.__nsteps - 1: raise H5OverflowError('Only ' + str(self.__nsteps - 1) + ' steps.') elif step < 0: raise H5OverflowError("Negative step number: '" + str(step) + "'")
def __str__(self): """Print file summary. Returns ------- str A summary of the file. """ info = '\nNumber of steps: ' + str(self.__nsteps) + '\n\n' info += 'Global attributes:\n' info += '------------------\n' for i, attr in enumerate(sorted(self.getGlobalAttributes())): info += ' {:20}'.format(attr) if (i+1) % 5 == 0: info += '\n' info += '\n\nStep attributes:\n' info += '----------------\n' for i, attr in enumerate(sorted(self.getStepAttributes())): info += ' {:20}'.format(attr) if (i+1) % 5 == 0: info += '\n' info += '\n\nStep datasets:\n' info += '--------------\n' for i, attr, in enumerate(sorted(self.getStepDatasets())): info += ' {:20}'.format(attr) if (i+1) % 5 == 0: info += '\n' return info + '\n'