Source code for bmtk.utils.sonata.utils

# Copyright 2017. Allen Institute. All rights reserved
#
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
# following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
# products derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
import os
import sys

import h5py
import pandas as pd
import numpy as np

MAGIC_ATTR = 'magic'
MAGIC_VAL = 0x0A7A
VERSION_ATTR = 'version'
VERSION_NA = 'NA'
VERSION_CURRENT = '0.1'

try:
    ver_split = VERSION_CURRENT.split('.')
    VERSION_MAJOR = ver_split[0]
    VERSION_MINOR = ver_split[1]
except (IndexError, AttributeError) as err:
    VERSION_MAJOR = 0
    VERSION_MINOR = 1


[docs]def listify(files): # TODO: change this to include any iterable datastructures (sets, panda sequences, etc) if not isinstance(files, (list, tuple)): return [files] else: return files
[docs]def load_h5(h5file, mode='r'): # TODO: Allow for h5py.Group also if isinstance(h5file, h5py.File): return h5file return h5py.File(h5file, mode)
[docs]def load_csv(csvfile): # TODO: make the separator more flexible if isinstance(csvfile, pd.DataFrame): return csvfile # TODO: check if it is csv object and convert to a pd dataframe return pd.read_csv(csvfile, sep=' ', na_values='NONE')
[docs]def get_attribute_h5(h5obj, attribut_name, default=None): val = h5obj.attrs.get(attribut_name, default) if using_py3 and isinstance(val, bytes): # There is an but with h5py returning unicode/str based attributes as bytes val = val.decode() return val
[docs]def check_magic(hdf5_file): """Check the magic attribute exists according to the sonata format""" h5_file_obj = load_h5(hdf5_file) if MAGIC_ATTR not in h5_file_obj.attrs: raise Exception('File {} missing top-level \"{}\" attribute.'.format(h5_file_obj.filename, MAGIC_ATTR)) elif np.uint32(get_attribute_h5(hdf5_file, MAGIC_ATTR)) != MAGIC_VAL: raise Exception('File {} has unexpected magic value (expected {})'.format(h5_file_obj.filename, MAGIC_VAL)) return True
[docs]def get_version(hdf5_file): h5_file_obj = load_h5(hdf5_file) if VERSION_ATTR not in h5_file_obj.attrs: return VERSION_NA else: version_val = get_attribute_h5(h5_file_obj, VERSION_ATTR) version_str = str(version_val[0]) for ver_sub in version_val[1:]: version_str += '.{}'.format(ver_sub) return version_str
[docs]def add_hdf5_magic(hdf5_handle): hdf5_handle['/'].attrs['magic'] = np.uint32(0x0A7A)
[docs]def add_hdf5_version(hdf5_handle): hdf5_handle['/'].attrs['version'] = [np.uint32(VERSION_MAJOR), np.uint32(VERSION_MINOR)]
[docs]def get_node_ids(nodes_path, population): # Used by PoissonSpikesGenerator with h5py.File(nodes_path, 'r') as h5: node_ids = h5['/nodes'][population]['node_id'][()] return node_ids
if sys.version_info[0] == 3: using_py3 = True range_itr = range else: using_py3 = False range_itr = xrange