From 0cc1e13d0f1c3ab7f2a23688d7569cd7b485876b Mon Sep 17 00:00:00 2001 From: Daniel Nachbaur Date: Thu, 31 Mar 2016 16:30:19 +0200 Subject: [PATCH] Add basic provenance metadata for written HDF5 compartment reports --- brion/CMakeLists.txt | 1 + brion/detail/utilsHDF5.h | 41 ++++++++++++++++++++++++++++++++ brion/plugin/compartmentReportHDF5.cpp | 43 ++++++++++++++++++++++------------ brion/plugin/compartmentReportHDF5.h | 1 + brion/plugin/morphologyHDF5.cpp | 12 ++++------ doc/Changelog.md | 2 ++ 6 files changed, 78 insertions(+), 22 deletions(-) create mode 100644 brion/detail/utilsHDF5.h diff --git a/brion/CMakeLists.txt b/brion/CMakeLists.txt index 3eb35b6..15bd651 100644 --- a/brion/CMakeLists.txt +++ b/brion/CMakeLists.txt @@ -43,6 +43,7 @@ set(BRION_HEADERS detail/meshHDF5.h detail/lockHDF5.h detail/silenceHDF5.h + detail/utilsHDF5.h ) set(BRION_SOURCES diff --git a/brion/detail/utilsHDF5.h b/brion/detail/utilsHDF5.h new file mode 100644 index 0000000..fa9bb7a --- /dev/null +++ b/brion/detail/utilsHDF5.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2016, EPFL/Blue Brain Project + * Daniel Nachbaur + * + * This file is part of Brion + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3.0 as published + * by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef BRION_DETAIL_UTILSHDF5 +#define BRION_DETAIL_UTILSHDF5 + +#include + +namespace brion +{ +namespace detail +{ + +/** Add a string attribute to the given H5 object. */ +inline void addStringAttribute( H5::H5Object& object, const std::string& name, + const std::string& value ) +{ + const H5::StrType strType( H5::PredType::C_S1, value.length( )); + object.createAttribute( name, strType, H5S_SCALAR ).write( strType, value ); +} + +} +} + +#endif diff --git a/brion/plugin/compartmentReportHDF5.cpp b/brion/plugin/compartmentReportHDF5.cpp index 3cd7039..3a96829 100644 --- a/brion/plugin/compartmentReportHDF5.cpp +++ b/brion/plugin/compartmentReportHDF5.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, EPFL/Blue Brain Project +/* Copyright (c) 2013-2016, EPFL/Blue Brain Project * Daniel Nachbaur * * This file is part of Brion @@ -20,6 +20,8 @@ #include "compartmentReportHDF5.h" #include "../detail/lockHDF5.h" #include "../detail/silenceHDF5.h" +#include "../detail/utilsHDF5.h" +#include #include #include @@ -425,6 +427,8 @@ void CompartmentReportHDF5::writeHeader( const float startTime, _timestep = timestep; _dunit = dunit; _tunit = tunit; + + _createMetaData(); } bool CompartmentReportHDF5::writeCompartments( const uint32_t gid, @@ -595,15 +599,32 @@ H5::DataSet& CompartmentReportHDF5::_getDataset( const uint32_t gid ) return it->second; } +void CompartmentReportHDF5::_createMetaData() +{ + H5::Group root = _file.openGroup( "/" ); + + detail::addStringAttribute( root, "creator", "Brion" ); + detail::addStringAttribute( root, "software_version", + brion::Version::getRevString( )); + + const time_t now = ::time(0); +#ifdef _WIN32 + char* gmtString = ::ctime( &now ); +#else + char gmtString[32]; + ::ctime_r( &now, gmtString ); +#endif + std::string creationTimeName = gmtString; + creationTimeName.pop_back(); // ctime_r ends with \n + detail::addStringAttribute( root, "creation_time", creationTimeName ); +} + void CompartmentReportHDF5::_createMappingAttributes( H5::DataSet& dataset ) { // const std::string type = // boost::lexical_cast< std::string >( _spec.type( )); const std::string type = "1"; // COMPARTMENT_REPORT - H5::StrType stringType( H5::PredType::C_S1, type.length( )); - - H5::Attribute typeAttr = dataset.createAttribute( mappingAttributes[0], - stringType, H5S_SCALAR ); + detail::addStringAttribute( dataset, mappingAttributes[0], type ); dataset.createAttribute( mappingAttributes[1], H5::PredType::NATIVE_INT, H5S_SCALAR ); dataset.createAttribute( mappingAttributes[2], H5::PredType::NATIVE_INT, @@ -614,8 +635,6 @@ void CompartmentReportHDF5::_createMappingAttributes( H5::DataSet& dataset ) H5S_SCALAR ); dataset.createAttribute( mappingAttributes[5], H5::PredType::NATIVE_INT, H5S_SCALAR ); - - typeAttr.write( stringType, type ); } void CompartmentReportHDF5::_createDataAttributes( H5::DataSet& dataset ) @@ -624,8 +643,6 @@ void CompartmentReportHDF5::_createDataAttributes( H5::DataSet& dataset ) const double startTime = getStartTime(); const double endTime = getEndTime(); const double timestep = getTimestep(); - H5::StrType string2Type( H5::PredType::C_S1, _tunit.length( )); - H5::StrType stringType( H5::PredType::C_S1, _dunit.length( )); H5::Attribute rankAttr = dataset.createAttribute( dataAttributes[0], H5::PredType::NATIVE_INT, H5S_SCALAR ); @@ -635,17 +652,13 @@ void CompartmentReportHDF5::_createDataAttributes( H5::DataSet& dataset ) H5::PredType::NATIVE_DOUBLE, H5S_SCALAR ); H5::Attribute dtAttr = dataset.createAttribute( dataAttributes[3], H5::PredType::NATIVE_DOUBLE, H5S_SCALAR ); - H5::Attribute dunitAttr = dataset.createAttribute( dataAttributes[4], - stringType, H5S_SCALAR ); - H5::Attribute tunitAttr = dataset.createAttribute( dataAttributes[5], - string2Type, H5S_SCALAR ); rankAttr.write( H5::PredType::NATIVE_INT, &rank ); tstartAttr.write( H5::PredType::NATIVE_DOUBLE, &startTime ); tstopAttr.write( H5::PredType::NATIVE_DOUBLE, &endTime ); dtAttr.write( H5::PredType::NATIVE_DOUBLE, ×tep ); - dunitAttr.write( stringType, _dunit ); - tunitAttr.write( string2Type, _tunit ); + detail::addStringAttribute( dataset, dataAttributes[4], _dunit ); + detail::addStringAttribute( dataset, dataAttributes[5], _tunit ); } } diff --git a/brion/plugin/compartmentReportHDF5.h b/brion/plugin/compartmentReportHDF5.h index f4cbeab..ff18d23 100644 --- a/brion/plugin/compartmentReportHDF5.h +++ b/brion/plugin/compartmentReportHDF5.h @@ -71,6 +71,7 @@ class CompartmentReportHDF5 : public CompartmentReportCommon H5::DataSet _createDataset( const uint32_t gid, const size_t compCount ); H5::DataSet& _getDataset( const uint32_t gid ); + void _createMetaData(); void _createMappingAttributes( H5::DataSet& dataset ); void _createDataAttributes( H5::DataSet& dataset ); diff --git a/brion/plugin/morphologyHDF5.cpp b/brion/plugin/morphologyHDF5.cpp index 094f709..78349d6 100644 --- a/brion/plugin/morphologyHDF5.cpp +++ b/brion/plugin/morphologyHDF5.cpp @@ -22,6 +22,7 @@ #include "../detail/lockHDF5.h" #include "../detail/silenceHDF5.h" +#include "../detail/utilsHDF5.h" #include @@ -583,13 +584,10 @@ void MorphologyHDF5::_writeV2Header() char gmtString[32]; ::ctime_r( &now, gmtString ); #endif - const std::string creator = "Brion " + Version::getString() + - " brion::Morphology " + gmtString; - H5::DataSpace creatorDS( H5S_SCALAR ); - H5::StrType stringDT( H5::PredType::C_S1, creator.length( )); - H5::Attribute creatorAttr = root.createAttribute( _a_creator, stringDT, - creatorDS ); - creatorAttr.write( stringDT, creator ); + std::string creator = "Brion " + Version::getString() + + " brion::Morphology " + gmtString; + creator.pop_back(); // ctime_r ends with \n + detail::addStringAttribute( root, _a_creator, creator ); H5::DataSpace versionDS( H5S_SCALAR ); H5::Attribute versionAttr = root.createAttribute( _a_version, diff --git a/doc/Changelog.md b/doc/Changelog.md index 4a9fc9e..de36aae 100644 --- a/doc/Changelog.md +++ b/doc/Changelog.md @@ -3,6 +3,8 @@ Changelog {#Changelog} # Release 1.7.0 (24-Mar-2016) +* [55](https://github.com/BlueBrain/Brion/pull/55): + Add basic provenance metadata for written HDF5 compartment reports * [51](https://github.com/BlueBrain/Brion/pull/51): Empty target does not rise an exeption anymore * [49](https://github.com/BlueBrain/Brion/pull/49):