From aaf2dac4e2c6ff875ffef67a17c731462e24f1fe Mon Sep 17 00:00:00 2001 From: Stefan Eilemann Date: Tue, 27 Oct 2015 09:15:07 +0100 Subject: [PATCH 1/4] Convenience methods needed for Fivox --- brion/blueConfig.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++++-------- brion/blueConfig.h | 13 ++++++++ tests/blueConfig.cpp | 38 ++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 12 deletions(-) diff --git a/brion/blueConfig.cpp b/brion/blueConfig.cpp index 9cdf376..bdad3f2 100644 --- a/brion/blueConfig.cpp +++ b/brion/blueConfig.cpp @@ -19,12 +19,15 @@ #include "blueConfig.h" +#include +#include +#include +#include #include #include #include -#include -#include +namespace fs = boost::filesystem; namespace boost { template<> @@ -115,7 +118,7 @@ class BlueConfig continue; } - _names[type].push_back( name ); + names[type].push_back( name ); Strings lines; boost::split( lines, content, boost::is_any_of( "\n" ), @@ -137,18 +140,34 @@ class BlueConfig std::string value = line.substr( pos+1 ); boost::trim( value ); - _table[type][name].insert( std::make_pair( line.substr( 0, pos), + table[type][name].insert( std::make_pair( line.substr( 0, pos), value )); } } - if( _table[CONFIGSECTION_RUN].empty( )) + if( table[CONFIGSECTION_RUN].empty( )) LBTHROW( std::runtime_error( source + " not a valid BlueConfig file" )); } - Strings _names[CONFIGSECTION_ALL]; - ValueTable _table[CONFIGSECTION_ALL]; + std::string getRun() + { + const brion::Strings& runs = names[ brion::CONFIGSECTION_RUN ]; + return runs.empty() ? std::string() : runs.front(); + } + + std::string getOutputRoot() + { + return table[ brion::CONFIGSECTION_RUN ][ getRun() ][ "OutputRoot" ]; + } + + std::string getCircuitTarget() + { + return table[ brion::CONFIGSECTION_RUN ][ getRun() ][ "CircuitTarget" ]; + } + + Strings names[CONFIGSECTION_ALL]; + ValueTable table[CONFIGSECTION_ALL]; }; } @@ -162,17 +181,57 @@ BlueConfig::~BlueConfig() delete _impl; } -const Strings& -BlueConfig::getSectionNames( const BlueConfigSection section ) const +const Strings& BlueConfig::getSectionNames( const BlueConfigSection section ) + const { - return _impl->_names[section]; + return _impl->names[section]; } const std::string& BlueConfig::get( const BlueConfigSection section, const std::string& sectionName, const std::string& key ) const { - return _impl->_table[section][sectionName][key]; + return _impl->table[section][sectionName][key]; +} + +std::string BlueConfig::getCircuitSource() +{ + return get( CONFIGSECTION_RUN, _impl->getRun(), "CircuitPath" ) + + "/circuit.mvd2"; +} + +brion::URI BlueConfig::getReportSource( const std::string& report ) +{ + std::string format = get( CONFIGSECTION_REPORT, report, "Format" ); + boost::algorithm::to_lower( format ); + + if( format == "binary" || format == "bin" ) + return URI( std::string( "file://" ) + _impl->getOutputRoot() + "/" + + report + ".bbp" ); + + if( format == "hdf5" || format.empty() || fs::is_directory( format )) + return URI( std::string( "file://" ) + _impl->getOutputRoot() + "/" + + report + ".h5" ); + + if( format == "stream" || format == "leveldb" || format == "skv" ) + return URI( _impl->getOutputRoot( )); + + LBWARN << "Unknown report format " << format << std::endl; + return URI(); +} + +brion::GIDSet BlueConfig::parseTarget( std::string target ) +{ + if( target.empty( )) + target = _impl->getCircuitTarget(); + + const std::string& run = _impl->getRun(); + brion::Targets targets; + targets.push_back( brion::Target( + get( brion::CONFIGSECTION_RUN, run, "nrnPath" ) + "/start.target" )); + targets.push_back( brion::Target( + get( brion::CONFIGSECTION_RUN, run, "TargetFile" ))); + return brion::Target::parse( targets, target ); } std::ostream& operator << ( std::ostream& os, const BlueConfig& config ) @@ -180,7 +239,7 @@ std::ostream& operator << ( std::ostream& os, const BlueConfig& config ) for( size_t i = 0; i < CONFIGSECTION_ALL; ++i ) { BOOST_FOREACH( const ValueTable::value_type& entry, - config._impl->_table[i] ) + config._impl->table[i] ) { os << boost::lexical_cast< std::string >( BlueConfigSection( i )) << " " << entry.first << std::endl; diff --git a/brion/blueConfig.h b/brion/blueConfig.h index fce737e..108d5ae 100644 --- a/brion/blueConfig.h +++ b/brion/blueConfig.h @@ -92,6 +92,19 @@ class BlueConfig : public boost::noncopyable } //@} + /** @name Semantic read API */ + //@{ + /** @return the full path to the circuit.mvd2 file. @sa Circuit */ + BRION_API std::string getCircuitSource(); + + /** @return the URI to the named report. @sa CompartmentReport */ + BRION_API brion::URI getReportSource( const std::string& report ); + + /** @return the set of GIDs for the given target, or the circuit target if + * the given target is empty. */ + BRION_API brion::GIDSet parseTarget( std::string target ); + //@} + private: friend std::ostream& operator << ( std::ostream&, const BlueConfig& ); diff --git a/tests/blueConfig.cpp b/tests/blueConfig.cpp index f1f5f82..181bbb8 100644 --- a/tests/blueConfig.cpp +++ b/tests/blueConfig.cpp @@ -152,3 +152,41 @@ BOOST_AUTO_TEST_CASE( test_verify_loaded_data ) BOOST_CHECK_EQUAL( config.get( brion::CONFIGSECTION_REPORT, "voltage", "EndTime" ), 99.f ); } + +BOOST_AUTO_TEST_CASE( semantic_api ) +{ + const std::string prefix( BBP_TESTDATA ); + const brion::BlueConfig config( bbp::test::getBlueconfig( )); + BOOST_CHECK_EQUAL( config.getCircuitSource(), + prefix + "/local/circuits/18.10.10_600cell/circuit.mvd2" ); + + BOOST_CHECK_EQUAL( config.getReportSource( "unknown"), brion::URI( )); + const std::string root = config.get( brion::CONFIGSECTION_RUN, "Demo", + "OutputRoot" ); + const brion::URI allCompartments = + config.getReportSource( "allCompartments" ); + BOOST_CHECK_EQUAL( allCompartments.getScheme(), "file" ); + BOOST_CHECK_EQUAL( allCompartments.getPath(), + root + "/allCompartments.bbp" ); +} + +BOOST_AUTO_TEST_CASE( parse_target ) +{ + const brion::BlueConfig config( bbp::test::getBlueconfig( )); + const brion::GIDSet defaultTarget = config.parseTarget( "" ); + BOOST_CHECK( defaultTarget.size( )); + const brion::GIDSet columnTarget = config.parseTarget( "Column" ); + BOOST_CHECK( columnTarget.size( )); + // Can't use BOOST_CHECK_EQUAL because GIDSet lacks operator<< + BOOST_CHECK( defaultTarget == columnTarget ); + + const brion::GIDSet fromUserTarget = config.parseTarget( "AllL5CSPC" ); + BOOST_CHECK( fromUserTarget.size( )); + const brion::GIDSet fromStartTarget = config.parseTarget( "L5CSPC" ); + BOOST_CHECK( fromStartTarget.size( )); + BOOST_CHECK( fromStartTarget == fromUserTarget ); + + // Shouldn't this throw instead? + const brion::GIDSet empty = config.parseTarget( "unexistent" ); + BOOST_CHECK( empty.empty( )); +} From f40f905e00e789c39c0d48805fbb588d2974abf0 Mon Sep 17 00:00:00 2001 From: Juan Hernando Date: Wed, 28 Oct 2015 23:11:30 +0100 Subject: [PATCH 2/4] Convenience methods needed for Fivox spike loader. Change-Id: I0f40cfd19907c3535fccb36fb484e27587c2eaa5 --- brion/blueConfig.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++++++----- brion/blueConfig.h | 16 ++++++++-- tests/blueConfig.cpp | 12 ++++++-- 3 files changed, 99 insertions(+), 13 deletions(-) diff --git a/brion/blueConfig.cpp b/brion/blueConfig.cpp index bdad3f2..dfdeddf 100644 --- a/brion/blueConfig.cpp +++ b/brion/blueConfig.cpp @@ -68,6 +68,11 @@ inline std::string lexical_cast( const brion::BlueConfigSection& b ) } } +namespace +{ + const char* const SPIKE_FILE = "/out.dat"; +} + namespace brion { @@ -76,6 +81,7 @@ typedef stde::hash_map< std::string, KVStore > ValueTable; namespace detail { + class BlueConfig { public: @@ -156,16 +162,51 @@ class BlueConfig return runs.empty() ? std::string() : runs.front(); } - std::string getOutputRoot() + const std::string& get( const BlueConfigSection section, + const std::string& sectionName, + const std::string& key ) const { - return table[ brion::CONFIGSECTION_RUN ][ getRun() ][ "OutputRoot" ]; + // This function doesn't create entries in the tables in case they + // doesn't exist. + static std::string empty; + const ValueTable::const_iterator tableIt = + table[section].find( sectionName ); + if( tableIt == table[section].end( )) + return empty; + const KVStore& store = tableIt->second; + const KVStore::const_iterator kv = store.find( key ); + if( kv == store.end( )) + return empty; + return kv->second; } - std::string getCircuitTarget() + const std::string& getCircuitTarget() { - return table[ brion::CONFIGSECTION_RUN ][ getRun() ][ "CircuitTarget" ]; + return get( brion::CONFIGSECTION_RUN, getRun(), "CircuitTarget" ); + } + + const std::string& getOutputRoot() + { + return get( brion::CONFIGSECTION_RUN, getRun(), "OutputRoot" ); + } + + + template + bool get( const BlueConfigSection section, const std::string& sectionName, + const std::string& key, T& value ) const + { + try + { + value = boost::lexical_cast< T >( get( section, sectionName, key )); + } + catch( const boost::bad_lexical_cast& ) + { + return false; + } + return true; } + Strings names[CONFIGSECTION_ALL]; ValueTable table[CONFIGSECTION_ALL]; }; @@ -191,18 +232,24 @@ const std::string& BlueConfig::get( const BlueConfigSection section, const std::string& sectionName, const std::string& key ) const { - return _impl->table[section][sectionName][key]; + return _impl->get( section, sectionName, key ); } -std::string BlueConfig::getCircuitSource() +std::string BlueConfig::getCircuitSource() const { return get( CONFIGSECTION_RUN, _impl->getRun(), "CircuitPath" ) + "/circuit.mvd2"; } -brion::URI BlueConfig::getReportSource( const std::string& report ) +URI BlueConfig::getReportSource( const std::string& report ) const { std::string format = get( CONFIGSECTION_REPORT, report, "Format" ); + if( format.empty( )) + { + LBWARN << "Invalid or missing report " << report << std::endl; + return URI(); + } + boost::algorithm::to_lower( format ); if( format == "binary" || format == "bin" ) @@ -220,7 +267,20 @@ brion::URI BlueConfig::getReportSource( const std::string& report ) return URI(); } -brion::GIDSet BlueConfig::parseTarget( std::string target ) +URI BlueConfig::getSpikeSource() const +{ + std::string path = get( CONFIGSECTION_RUN, _impl->getRun(), "SpikesPath" ); + if( path.empty( )) + path = _impl->getOutputRoot() + SPIKE_FILE; + return URI( std::string( "file://" ) + path ); +} + +std::string BlueConfig::getCircuitTarget() const +{ + return _impl->getCircuitTarget(); +} + +GIDSet BlueConfig::parseTarget( std::string target ) const { if( target.empty( )) target = _impl->getCircuitTarget(); @@ -234,6 +294,14 @@ brion::GIDSet BlueConfig::parseTarget( std::string target ) return brion::Target::parse( targets, target ); } +float BlueConfig::getTimestep() const +{ + const std::string& run = _impl->getRun(); + float timestep = std::numeric_limits::quiet_NaN(); + _impl->get< float >( brion::CONFIGSECTION_RUN, run, "Dt", timestep ); + return timestep; +} + std::ostream& operator << ( std::ostream& os, const BlueConfig& config ) { for( size_t i = 0; i < CONFIGSECTION_ALL; ++i ) diff --git a/brion/blueConfig.h b/brion/blueConfig.h index 108d5ae..50d2cad 100644 --- a/brion/blueConfig.h +++ b/brion/blueConfig.h @@ -95,14 +95,24 @@ class BlueConfig : public boost::noncopyable /** @name Semantic read API */ //@{ /** @return the full path to the circuit.mvd2 file. @sa Circuit */ - BRION_API std::string getCircuitSource(); + BRION_API std::string getCircuitSource() const; /** @return the URI to the named report. @sa CompartmentReport */ - BRION_API brion::URI getReportSource( const std::string& report ); + BRION_API brion::URI getReportSource( const std::string& report ) const; + + /** @return the URI to the default spike data source. @sa SpikeReport */ + BRION_API brion::URI getSpikeSource() const; + + /** @return the name of the circuit target + @version 1.7 */ + std::string getCircuitTarget() const; /** @return the set of GIDs for the given target, or the circuit target if * the given target is empty. */ - BRION_API brion::GIDSet parseTarget( std::string target ); + BRION_API brion::GIDSet parseTarget( std::string target ) const; + + /** @return the simulation timestep or NaN if undefined. */ + BRION_API float getTimestep() const; //@} private: diff --git a/tests/blueConfig.cpp b/tests/blueConfig.cpp index 181bbb8..a568662 100644 --- a/tests/blueConfig.cpp +++ b/tests/blueConfig.cpp @@ -157,17 +157,25 @@ BOOST_AUTO_TEST_CASE( semantic_api ) { const std::string prefix( BBP_TESTDATA ); const brion::BlueConfig config( bbp::test::getBlueconfig( )); + const std::string root = config.get( brion::CONFIGSECTION_RUN, "Demo", + "OutputRoot" ); + BOOST_CHECK_EQUAL( config.getCircuitSource(), prefix + "/local/circuits/18.10.10_600cell/circuit.mvd2" ); BOOST_CHECK_EQUAL( config.getReportSource( "unknown"), brion::URI( )); - const std::string root = config.get( brion::CONFIGSECTION_RUN, "Demo", - "OutputRoot" ); const brion::URI allCompartments = config.getReportSource( "allCompartments" ); BOOST_CHECK_EQUAL( allCompartments.getScheme(), "file" ); BOOST_CHECK_EQUAL( allCompartments.getPath(), root + "/allCompartments.bbp" ); + + const brion::URI spikes = config.getSpikeSource(); + BOOST_CHECK_EQUAL( spikes.getScheme(), "file" ); + BOOST_CHECK_EQUAL( spikes.getPath(), root + "/out.dat" ); + + BOOST_CHECK_EQUAL( config.getCircuitTarget(), "Column" ); + BOOST_CHECK_EQUAL( config.getTimestep( ), 0.025f ); } BOOST_AUTO_TEST_CASE( parse_target ) From 7909c3262e986a463683d292322948a8f1caad8d Mon Sep 17 00:00:00 2001 From: Juan Hernando Date: Mon, 16 Nov 2015 18:07:01 +0100 Subject: [PATCH 3/4] Convenience method for the brion-only synapse loader in Fivox. Change-Id: If7c943c106849fadd703facf31f18b92c392cfce --- brion/blueConfig.cpp | 5 +++++ brion/blueConfig.h | 3 +++ tests/blueConfig.cpp | 2 ++ 3 files changed, 10 insertions(+) diff --git a/brion/blueConfig.cpp b/brion/blueConfig.cpp index dfdeddf..bfbb531 100644 --- a/brion/blueConfig.cpp +++ b/brion/blueConfig.cpp @@ -241,6 +241,11 @@ std::string BlueConfig::getCircuitSource() const "/circuit.mvd2"; } +std::string BlueConfig::getSynapseSource() const +{ + return get( CONFIGSECTION_RUN, _impl->getRun(), "nrnPath" ); +} + URI BlueConfig::getReportSource( const std::string& report ) const { std::string format = get( CONFIGSECTION_REPORT, report, "Format" ); diff --git a/brion/blueConfig.h b/brion/blueConfig.h index 50d2cad..6ae4904 100644 --- a/brion/blueConfig.h +++ b/brion/blueConfig.h @@ -97,6 +97,9 @@ class BlueConfig : public boost::noncopyable /** @return the full path to the circuit.mvd2 file. @sa Circuit */ BRION_API std::string getCircuitSource() const; + /** @return the path to the location of synapse nrn files. */ + BRION_API std::string getSynapseSource() const; + /** @return the URI to the named report. @sa CompartmentReport */ BRION_API brion::URI getReportSource( const std::string& report ) const; diff --git a/tests/blueConfig.cpp b/tests/blueConfig.cpp index a568662..043f9b6 100644 --- a/tests/blueConfig.cpp +++ b/tests/blueConfig.cpp @@ -162,6 +162,8 @@ BOOST_AUTO_TEST_CASE( semantic_api ) BOOST_CHECK_EQUAL( config.getCircuitSource(), prefix + "/local/circuits/18.10.10_600cell/circuit.mvd2" ); + BOOST_CHECK_EQUAL( config.getSynapseSource(), + prefix + "/local/circuits/18.10.10_600cell/ncsFunctionalCompare" ); BOOST_CHECK_EQUAL( config.getReportSource( "unknown"), brion::URI( )); const brion::URI allCompartments = From 17b8a5752b4799722cce9840eff98d928d1b52a1 Mon Sep 17 00:00:00 2001 From: Juan Hernando Date: Wed, 25 Nov 2015 12:49:54 +0100 Subject: [PATCH 4/4] More convenience methods for Fivox. Minor refactorings. Change-Id: Ia6c61370cecbe76bc4958a2b5549dee2718cd8a4 --- CMakeLists.txt | 2 +- brion/blueConfig.cpp | 67 +++++++++++++++++++++++++++++++++-------------- brion/blueConfig.h | 41 +++++++++++++++++++++-------- brion/circuit.cpp | 18 ++++++------- brion/circuit.h | 17 ++++++++---- brion/constants.h | 45 +++++++++++++++++++++++++++++++ brion/spikeReportPlugin.h | 2 +- brion/types.h | 13 ++++----- doc/Changelog.md | 2 ++ tests/blueConfig.cpp | 6 +++-- 10 files changed, 158 insertions(+), 55 deletions(-) create mode 100644 brion/constants.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 840e1db..e845ec0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake include(GitExternal) set(VERSION_MAJOR "1") -set(VERSION_MINOR "6") +set(VERSION_MINOR "7") set(VERSION_PATCH "0") set(VERSION_ABI 5) diff --git a/brion/blueConfig.cpp b/brion/blueConfig.cpp index bfbb531..fcc55d5 100644 --- a/brion/blueConfig.cpp +++ b/brion/blueConfig.cpp @@ -19,6 +19,7 @@ #include "blueConfig.h" +#include #include #include #include @@ -68,11 +69,6 @@ inline std::string lexical_cast( const brion::BlueConfigSection& b ) } } -namespace -{ - const char* const SPIKE_FILE = "/out.dat"; -} - namespace brion { @@ -167,7 +163,7 @@ class BlueConfig const std::string& key ) const { // This function doesn't create entries in the tables in case they - // doesn't exist. + // don't exist. static std::string empty; const ValueTable::const_iterator tableIt = table[section].find( sectionName ); @@ -182,12 +178,14 @@ class BlueConfig const std::string& getCircuitTarget() { - return get( brion::CONFIGSECTION_RUN, getRun(), "CircuitTarget" ); + return get( brion::CONFIGSECTION_RUN, getRun(), + BLUECONFIG_CIRCUIT_TARGET_KEY ); } const std::string& getOutputRoot() { - return get( brion::CONFIGSECTION_RUN, getRun(), "OutputRoot" ); + return get( brion::CONFIGSECTION_RUN, getRun(), + BLUECONFIG_OUTPUT_PATH_KEY ); } @@ -235,20 +233,45 @@ const std::string& BlueConfig::get( const BlueConfigSection section, return _impl->get( section, sectionName, key ); } -std::string BlueConfig::getCircuitSource() const +URI BlueConfig::getCircuitSource() const +{ + URI uri; + uri.setScheme("file"); + uri.setPath( get( CONFIGSECTION_RUN, _impl->getRun(), + BLUECONFIG_CIRCUIT_PATH_KEY ) + CIRCUIT_FILE ); + return uri; +} + + +URI BlueConfig::getSynapseSource() const { - return get( CONFIGSECTION_RUN, _impl->getRun(), "CircuitPath" ) + - "/circuit.mvd2"; + URI uri; + uri.setScheme("file"); + uri.setPath( get( CONFIGSECTION_RUN, _impl->getRun(), + BLUECONFIG_NRN_PATH_KEY )); + return uri; } -std::string BlueConfig::getSynapseSource() const +URI BlueConfig::getMorphologySource() const { - return get( CONFIGSECTION_RUN, _impl->getRun(), "nrnPath" ); + URI uri; + uri.setScheme("file"); + std::string bare = get( CONFIGSECTION_RUN, _impl->getRun(), + BLUECONFIG_MORPHOLOGY_PATH_KEY ); + const fs::path barePath( bare ); + const fs::path guessedPath = barePath / MORPHOLOGY_HDF5_FILES_SUBDIRECTORY; + if( fs::exists( guessedPath ) && fs::is_directory( guessedPath )) + uri.setPath( guessedPath.string( )); + else + uri.setPath( bare ); + + return uri; } URI BlueConfig::getReportSource( const std::string& report ) const { - std::string format = get( CONFIGSECTION_REPORT, report, "Format" ); + std::string format = get( CONFIGSECTION_REPORT, report, + BLUECONFIG_REPORT_FORMAT_KEY ); if( format.empty( )) { LBWARN << "Invalid or missing report " << report << std::endl; @@ -274,10 +297,14 @@ URI BlueConfig::getReportSource( const std::string& report ) const URI BlueConfig::getSpikeSource() const { - std::string path = get( CONFIGSECTION_RUN, _impl->getRun(), "SpikesPath" ); + std::string path = get( CONFIGSECTION_RUN, _impl->getRun(), + BLUECONFIG_SPIKES_PATH_KEY ); if( path.empty( )) path = _impl->getOutputRoot() + SPIKE_FILE; - return URI( std::string( "file://" ) + path ); + URI uri; + uri.setScheme( "file" ); + uri.setPath( path ); + return uri; } std::string BlueConfig::getCircuitTarget() const @@ -293,9 +320,10 @@ GIDSet BlueConfig::parseTarget( std::string target ) const const std::string& run = _impl->getRun(); brion::Targets targets; targets.push_back( brion::Target( - get( brion::CONFIGSECTION_RUN, run, "nrnPath" ) + "/start.target" )); + get( brion::CONFIGSECTION_RUN, run, BLUECONFIG_NRN_PATH_KEY ) + + CIRCUIT_TARGET_FILE )); targets.push_back( brion::Target( - get( brion::CONFIGSECTION_RUN, run, "TargetFile" ))); + get( brion::CONFIGSECTION_RUN, run, BLUECONFIG_TARGET_FILE_KEY ))); return brion::Target::parse( targets, target ); } @@ -303,7 +331,8 @@ float BlueConfig::getTimestep() const { const std::string& run = _impl->getRun(); float timestep = std::numeric_limits::quiet_NaN(); - _impl->get< float >( brion::CONFIGSECTION_RUN, run, "Dt", timestep ); + _impl->get< float >( brion::CONFIGSECTION_RUN, run, BLUECONFIG_DT_KEY, + timestep ); return timestep; } diff --git a/brion/blueConfig.h b/brion/blueConfig.h index 6ae4904..bbb1695 100644 --- a/brion/blueConfig.h +++ b/brion/blueConfig.h @@ -94,27 +94,46 @@ class BlueConfig : public boost::noncopyable /** @name Semantic read API */ //@{ - /** @return the full path to the circuit.mvd2 file. @sa Circuit */ - BRION_API std::string getCircuitSource() const; + /** @return the URI to the circuit information. @sa Circuit + * @version 1.7 + */ + BRION_API URI getCircuitSource() const; - /** @return the path to the location of synapse nrn files. */ - BRION_API std::string getSynapseSource() const; + /** @return the URI to the location of synapse nrn files. + * @version 1.7 + */ + BRION_API URI getSynapseSource() const; - /** @return the URI to the named report. @sa CompartmentReport */ - BRION_API brion::URI getReportSource( const std::string& report ) const; + /** @return the full path to the morphology database. A suffix may be + * prepended to the to the bare path from the BlueConfig. + * @version 1.7 + */ + BRION_API URI getMorphologySource() const; - /** @return the URI to the default spike data source. @sa SpikeReport */ - BRION_API brion::URI getSpikeSource() const; + /** @return the URI to the named report. @sa CompartmentReport + * @version 1.7 + */ + BRION_API URI getReportSource( const std::string& report ) const; + + /** @return the URI to the default spike data source. @sa SpikeReport + * @version 1.7 + */ + BRION_API URI getSpikeSource() const; /** @return the name of the circuit target - @version 1.7 */ + * @version 1.7 + */ std::string getCircuitTarget() const; /** @return the set of GIDs for the given target, or the circuit target if - * the given target is empty. */ + * the given target is empty. + * @version 1.7 + */ BRION_API brion::GIDSet parseTarget( std::string target ) const; - /** @return the simulation timestep or NaN if undefined. */ + /** @return the simulation timestep in ms or NaN if undefined. + * @version 1.7 + */ BRION_API float getTimestep() const; //@} diff --git a/brion/circuit.cpp b/brion/circuit.cpp index e3cbe34..3889590 100644 --- a/brion/circuit.cpp +++ b/brion/circuit.cpp @@ -28,8 +28,6 @@ namespace brion { -namespace detail -{ enum Section { @@ -44,10 +42,10 @@ enum Section SECTION_UNKNOWN }; -class Circuit +class Circuit::Impl { public: - explicit Circuit( const std::string& source ) + explicit Impl( const std::string& source ) { namespace fs = boost::filesystem; fs::path path = source; @@ -88,10 +86,6 @@ class Circuit } } - ~Circuit() - { - } - NeuronMatrix get( const GIDSet& gids, const uint32_t attributes ) const { const std::bitset< NEURON_ALL > bits( attributes ); @@ -207,10 +201,14 @@ class Circuit typedef stde::hash_map< uint32_t, Strings > CircuitTable; CircuitTable _table; }; -} Circuit::Circuit( const std::string& source ) - : _impl( new detail::Circuit( source )) + : _impl( new Impl( source )) +{ +} + +Circuit::Circuit( const URI& source ) + : _impl( new Impl( source.getPath( ))) { } diff --git a/brion/circuit.h b/brion/circuit.h index 6ba04e1..b165302 100644 --- a/brion/circuit.h +++ b/brion/circuit.h @@ -26,12 +26,10 @@ namespace brion { -namespace detail { class Circuit; } - /** Read access to a Circuit file. * - * Following RAII, this class is ready to use after the creation and will ensure - * release of resources upon destruction. + * This class loads the circuit data at creation and will ensure release of + * resources upon destruction. */ class Circuit : public boost::noncopyable { @@ -49,6 +47,14 @@ class Circuit : public boost::noncopyable */ BRION_API explicit Circuit( const std::string& source ); + /** Open given filepath to a circuit file for reading. + * + * @param source filepath to circuit file + * @throw std::runtime_error if file is not a valid circuit file + * @version 1.7 + */ + BRION_API explicit Circuit( const URI& source ); + /** Retrieve neuron attributes for set of neurons. * * @param gids set of neurons of interest; if empty, all neurons in the @@ -76,7 +82,8 @@ class Circuit : public boost::noncopyable //@} private: - detail::Circuit* const _impl; + class Impl; + Impl* const _impl; }; } diff --git a/brion/constants.h b/brion/constants.h new file mode 100644 index 0000000..2f42d35 --- /dev/null +++ b/brion/constants.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2013-2015, EPFL/Blue Brain Project + * Juan Hernando + * + * 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_CONSTANTS +#define BRION_CONSTANTS + +namespace brion +{ + +const char* const SPIKE_FILE = "/out.dat"; +const char* const CIRCUIT_FILE = "/circuit.mvd2"; +const char* const CIRCUIT_TARGET_FILE = "/start.target"; + +const char* const MORPHOLOGY_HDF5_FILES_SUBDIRECTORY = "h5"; + +const char* const BLUECONFIG_CIRCUIT_PATH_KEY = "CircuitPath"; +const char* const BLUECONFIG_NRN_PATH_KEY = "nrnPath"; +const char* const BLUECONFIG_MORPHOLOGY_PATH_KEY = "MorphologyPath"; +const char* const BLUECONFIG_OUTPUT_PATH_KEY = "OutputRoot"; +const char* const BLUECONFIG_TARGET_FILE_KEY = "TargetFile"; +const char* const BLUECONFIG_SPIKES_PATH_KEY = "SpikesPath"; + +const char* const BLUECONFIG_CIRCUIT_TARGET_KEY = "CircuitTarget"; +const char* const BLUECONFIG_REPORT_FORMAT_KEY = "Format"; +const char* const BLUECONFIG_DT_KEY = "Dt"; + +} + +#endif diff --git a/brion/spikeReportPlugin.h b/brion/spikeReportPlugin.h index b60ee5f..e21e777 100644 --- a/brion/spikeReportPlugin.h +++ b/brion/spikeReportPlugin.h @@ -70,7 +70,7 @@ typedef PluginInitData SpikeReportInitData; * * Plugin libraries in the LD_LIBRARY_PATH will be automatically registered if * they provide the abovementioned C functions and follow the naming convention: - * BrionSpikeReport. + * \Brion\SpikeReport.\ * * @version 1.4 */ diff --git a/brion/types.h b/brion/types.h index f1b5b25..db4e1da 100644 --- a/brion/types.h +++ b/brion/types.h @@ -58,11 +58,11 @@ class Synapse; class SynapseSummary; class Target; -typedef vmml::vector< 2, int32_t > Vector2i; //!< A two-component int32 vector -typedef vmml::vector< 3, float > Vector3f; //!< A three-component float vector -typedef vmml::vector< 4, float > Vector4f; //!< A four-component float vector -typedef vmml::vector< 3, double > Vector3d; //!< A three-component double vector -typedef vmml::vector< 4, double > Vector4d; //!< A four-component double vector +using vmml::Vector2i; +using vmml::Vector3f; +using vmml::Vector4f; +using vmml::Vector3d; +using vmml::Vector4d; typedef std::vector< size_t > size_ts; typedef std::vector< int32_t > int32_ts; @@ -124,7 +124,8 @@ const float RESTING_VOLTAGE = -67.; //!< Resting voltage in mV const float MINIMUM_VOLTAGE = -80.; //!< Lowest voltage after hyperpolarisation using lunchbox::Strings; -using lunchbox::URI; + +using servus::URI; } // if you have a type T in namespace N, the operator << for T needs to be in diff --git a/doc/Changelog.md b/doc/Changelog.md index a66cbd3..d0106bf 100644 --- a/doc/Changelog.md +++ b/doc/Changelog.md @@ -3,6 +3,8 @@ Changelog {#Changelog} # git master {#master) +* [29](https://github.com/BlueBrain/Brion/pull/29): + New member functions in brion::BlueConfig to provide a semantic API. * [28](https://github.com/BlueBrain/Brion/pull/28): SpikeReport continues parsing files that have broken lines diff --git a/tests/blueConfig.cpp b/tests/blueConfig.cpp index 043f9b6..6b18e14 100644 --- a/tests/blueConfig.cpp +++ b/tests/blueConfig.cpp @@ -161,9 +161,11 @@ BOOST_AUTO_TEST_CASE( semantic_api ) "OutputRoot" ); BOOST_CHECK_EQUAL( config.getCircuitSource(), - prefix + "/local/circuits/18.10.10_600cell/circuit.mvd2" ); + brion::URI( prefix + "/local/circuits/18.10.10_600cell/circuit.mvd2" )); BOOST_CHECK_EQUAL( config.getSynapseSource(), - prefix + "/local/circuits/18.10.10_600cell/ncsFunctionalCompare" ); + brion::URI( prefix + "/local/circuits/18.10.10_600cell/ncsFunctionalCompare" )); + BOOST_CHECK_EQUAL( config.getMorphologySource(), + brion::URI( prefix + "/local/morphologies/01.07.08/h5" )); BOOST_CHECK_EQUAL( config.getReportSource( "unknown"), brion::URI( )); const brion::URI allCompartments =