Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/examples/attribute_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@
print(attr.name)

#access directly via name
print(r.attributes["NeXus_version"].name)
print(r.attributes["HDF5_Version"].name)

52 changes: 25 additions & 27 deletions doc/sphinx/nexus_attributes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@ Working with attributes
=======================

Fields and groups can have attributes attached which provide additional
metadata. In fact Nexus makes heavy use of attributes to store additional
information about a field or group. It is thus not recommended to use
metadata. In fact Nexus makes heavy use of attributes to store additional
information about a field or group. It is thus not recommended to use
attributes too excessively as one may runs into name conflicts with future Nexus
development.
development.
Attributes can be accessed from fields and groups via their :py:attr:`attributes`
member. Attributes behave basically like fields with some restrictions

* they cannot grow
* one cannot apply compression to attributes.

Due to this restrictions one should not use attributes to store large amounts of
data.
data.

To create attributes use the :py:meth:`create` method of the
:py:obj:`attributes` member

.. code-block:: python

import pninexus.nexus as nx

field = ....
Expand All @@ -35,7 +35,7 @@ optional ``shape`` keyword argument
a = field.attributes.create("temperature",type="float32",shape=(4,4))

If an attribute already exists it can be overwritten using the ``overwrite``
keyword argument (:py:const:`False` by default).
keyword argument (:py:const:`False` by default).

.. code-block:: python

Expand All @@ -53,30 +53,29 @@ queried to obtain metadata for a particular attribute instance
=================== =====================================================
property description
=================== =====================================================
:py:attr:`shape` a tuple with the number of elements along each
dimension of the attribute
:py:attr:`dtype` the string representation of the attributes data type
:py:attr:`is_valid` true if the attribute is a valid object
:py:attr:`name` the name of the attribute (the key which can be used
to retrieve the attribute from its parent)
:py:attr:`value` provides access to the attributes data
:py:attr:`shape` a tuple with the number of elements along each
dimension of the attribute
:py:attr:`dtype` the string representation of the attributes data type
:py:attr:`is_valid` true if the attribute is a valid object
:py:attr:`name` the name of the attribute (the key which can be used
to retrieve the attribute from its parent)
:py:attr:`value` provides access to the attributes data
:py:attr:`path` returns the path of the attribute
=================== =====================================================

The following code
The following code

.. literalinclude:: ../examples/attributes_properties.py

will produce
will produce

.. code-block:: bash
.. code-block:: bash

HDF5_version : /@HDF5_version type=string size=1
NX_class : /@NX_class type=string size=1
NeXus_version : /@NeXus_version type=string size=1
file_name : /@file_name type=string size=1
file_time : /@file_time type=string size=1
file_update_time : /@file_update_time type=string size=1
HDF5_Version : /@HDF5_Version type=string size=1
NX_class : /@NX_class type=string size=1
file_name : /@file_name type=string size=1
file_time : /@file_time type=string size=1
file_update_time : /@file_update_time type=string size=1



Expand All @@ -86,12 +85,12 @@ Attribute retrieval and iteration
There are basically three ways to to access the attributes attached to a group
or a field

* by name via :py:meth:`__getitem__` (using `[]`)
* by the attributes index
* by name via :py:meth:`__getitem__` (using `[]`)
* by the attributes index
* by an iterator.

The :py:attr:`attributes` attribute of groups and fields exposes an iterable
interface. The following example shows all three ways how to access the
interface. The following example shows all three ways how to access the
attributes of a files root group

.. literalinclude:: ../examples/attribute_access.py
Expand All @@ -108,12 +107,11 @@ the next example
.. literalinclude:: ../examples/attribute_io.py

.. code-block:: bash

r= [-1. 0. 0.]
x= -1.0
y= 0.0
z= 0.0

There is not too much more to day about that. When reading and writing
multidimensional data numpy arrays must be used in any case (also for strings).

4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

cmdclass = {'build_sphinx': BuildDoc}
name = "pninexus"
version = "1.3.3"
release = "1.3.3"
version = "1.3.4"
release = "1.3.4"


def get_build_dir():
Expand Down
8 changes: 8 additions & 0 deletions src/cpp/h5cpp/_h5cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ void print_hdf5_errors(bool value)
hdf5::error::Singleton::instance().auto_print(value);
}

std::string current_library_version()
{

hdf5::Version ver = hdf5::current_library_version();
return hdf5::Version::to_string(ver);
}


//=================implementation of the python extension======================
BOOST_PYTHON_MODULE(_h5cpp)
Expand Down Expand Up @@ -128,6 +135,7 @@ BOOST_PYTHON_MODULE(_h5cpp)
;

def("print_hdf5_errors",print_hdf5_errors);
def("current_library_version",current_library_version);

exception_registration();
}
3 changes: 2 additions & 1 deletion src/pninexus/h5cpp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
from pninexus.h5cpp._h5cpp import IterationIndex
from pninexus.h5cpp._h5cpp import Path
from pninexus.h5cpp._h5cpp import print_hdf5_errors
from pninexus.h5cpp._h5cpp import current_library_version

__all__ = ["IteratorConfig", "IterationOrder", "IterationIndex", "Path",
"print_hdf5_errors",
"print_hdf5_errors", "current_library_version",
"attribute", "dataspace", "datatype", "file", "filter", "node",
"property", "_h5cpp"]
2 changes: 1 addition & 1 deletion test/debug/attributes_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
f = nexus.create_file("attributes_all.nxs", True)
r = f.root()

print(r.attributes["HDF5_version"].read())
print(r.attributes["HDF5_Version"].read())

a = r.attributes.create("temp", "uint32", shape=(2, 3))
a.write(numpy.array([[1, 2, 3], [4, 5, 6]]))
Expand Down
12 changes: 6 additions & 6 deletions test/h5cpp_tests/file_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def test_image_from_buffer(self):
hdf5_version = "1.0.4"
f1 = create(self.filename, AccessFlags.TRUNCATE)
r1 = f1.root()
a1 = r1.attributes.create("HDF5_version", kVariableString)
a1 = r1.attributes.create("HDF5_Version", kVariableString)
a1.write(hdf5_version)
a1.close()
r1.close()
Expand All @@ -71,7 +71,7 @@ def test_image_from_buffer(self):
ibuffer = np.fromfile(self.filename, dtype='uint8')
f2 = from_buffer(ibuffer)
r2 = f2.root()
a2 = r2.attributes["HDF5_version"]
a2 = r2.attributes["HDF5_Version"]
self.assertTrue(a2.read(), hdf5_version)
a2.close()
r2.close()
Expand All @@ -84,7 +84,7 @@ def test_image_to_buffer(self):
hdf5_version = "1.0.3"
f1 = create(self.filename, AccessFlags.TRUNCATE)
r1 = f1.root()
a1 = r1.attributes.create("HDF5_version", kVariableString)
a1 = r1.attributes.create("HDF5_Version", kVariableString)
a1.write(hdf5_version)
size = f1.buffer_size
obuffer = np.zeros(shape=[size], dtype='uint8')
Expand All @@ -97,7 +97,7 @@ def test_image_to_buffer(self):

f2 = h5open(self.filename2)
r2 = f2.root()
a2 = r2.attributes["HDF5_version"]
a2 = r2.attributes["HDF5_Version"]
self.assertTrue(a2.read(), hdf5_version)
a2.close()
r2.close()
Expand All @@ -110,7 +110,7 @@ def test_image_buffer(self):
hdf5_version = "1.0.2"
f1 = create(self.filename, AccessFlags.TRUNCATE)
r1 = f1.root()
a1 = r1.attributes.create("HDF5_version", kVariableString)
a1 = r1.attributes.create("HDF5_Version", kVariableString)
a1.write(hdf5_version)

size = f1.buffer_size
Expand All @@ -123,7 +123,7 @@ def test_image_buffer(self):

f2 = from_buffer(obuffer, ImageFlags.READWRITE)
r2 = f2.root()
a2 = r2.attributes["HDF5_version"]
a2 = r2.attributes["HDF5_Version"]
self.assertTrue(a2.read(), hdf5_version)
a2.close()
r2.close()
Expand Down
11 changes: 11 additions & 0 deletions test/h5cpp_tests/path_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ def setUp(self):
def tearDown(self):
pass

def test_hdf5_version(self):

hdf5ver = h5cpp.current_library_version()
mj, mn, pa = hdf5ver.split(".")
imj = int(mj)
imn = int(mn)
ipa = int(pa)
self.assertTrue(imj > 0)
self.assertTrue(imn > -1)
self.assertTrue(ipa > -1)

def test_default_contruction(self):

p = h5cpp.Path()
Expand Down
1 change: 0 additions & 1 deletion test/nexus_tests/file_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ def test(self):
self.assertTrue(root.attributes.exists("file_time"))
self.assertTrue(root.attributes.exists("file_update_time"))
self.assertTrue(root.attributes.exists("file_name"))
self.assertTrue(root.attributes.exists("NeXus_version"))

self.assertEqual(root.attributes["NX_class"].read(), "NXroot")

Expand Down