Skip to content

Commit

Permalink
BRAYNS 578 - Use libsonata endfeet mesh path (#1201)
Browse files Browse the repository at this point in the history
  • Loading branch information
NadirRoGue committed Sep 20, 2023
1 parent 92b87d6 commit 8345359
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 134 deletions.
34 changes: 30 additions & 4 deletions plugins/CircuitExplorer/io/sonataloader/ParameterCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include <io/sonataloader/data/Names.h>
#include <io/sonataloader/data/PopulationType.h>

#include <spdlog/fmt/fmt.h>

#include <filesystem>
#include <unordered_set>

Expand Down Expand Up @@ -141,7 +143,9 @@ class EdgeChecker
for (auto &edgeParams : params.edge_populations)
{
_checkPopulation(params.node_population, edgeParams);
_checkSynapseAstrocyte(edgeParams);
auto properties = _config.getEdgesProperties(edgeParams.edge_population);
_checkSynapseAstrocyte(edgeParams, properties);
_checkEndfeet(edgeParams, properties);
_checkReport(edgeParams);
}
}
Expand All @@ -163,12 +167,34 @@ class EdgeChecker
}
}

void _checkSynapseAstrocyte(const SonataEdgePopulationParameters &params)
void _checkSynapseAstrocyte(
const SonataEdgePopulationParameters &params,
const bbp::sonata::EdgePopulationProperties &edgeProperties)
{
auto edgeProperties = _config.getEdgesProperties(params.edge_population);
if (edgeProperties.type == sonataloader::EdgeNames::synapseAstrocyte && params.load_afferent)
{
throw std::invalid_argument("synapse_astrocyte edge populations are not allowed in afferent mode");
throw std::invalid_argument(fmt::format("{} edges are not allowed in afferent mode", edgeProperties.type));
}
}

void _checkEndfeet(
const SonataEdgePopulationParameters &params,
const bbp::sonata::EdgePopulationProperties &edgeProperties)
{
if (edgeProperties.type != sonataloader::EdgeNames::endfoot)
{
return;
}

if (params.load_afferent)
{
throw std::invalid_argument(fmt::format("{} edges are not allowed in afferent mode", edgeProperties.type));
}

if (!edgeProperties.endfeetMeshesFile || (*edgeProperties.endfeetMeshesFile).empty())
{
throw std::invalid_argument(
fmt::format("No endfeet meshes file path defined for {}", params.edge_population));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,138 +20,12 @@

#include "common/EdgeMetadataFactory.h"

#include <brayns/json/Json.h>

#include <api/circuit/EndfeetCircuitBuilder.h>
#include <io/sonataloader/colordata/ColorDataFactory.h>
#include <io/sonataloader/data/EndFeetReader.h>
#include <io/sonataloader/data/Names.h>
#include <io/sonataloader/data/Synapses.h>

#include <filesystem>

namespace
{
class EndFeetAreasPath
{
public:
explicit EndFeetAreasPath(const sonataloader::EdgeLoadContext &context):
_json(_parseConfig(context)),
_rootPath(_getConfigRootPath(context)),
_edgeName(context.edgePopulation.name())
{
}

std::string resolve()
{
auto resultPath = _findEndfeetPath();
if (resultPath.empty())
{
resultPath = _getDefaultPath();
}

if (resultPath.empty())
{
throw std::runtime_error("EndFootPopulationLoader: Cannot locate endfeet areas H5 file");
}

if (!std::filesystem::path(resultPath).is_absolute())
{
auto fullPath = _rootPath / std::filesystem::path(resultPath);
resultPath = fullPath.lexically_normal().string();
}

return resultPath;
}

private:
Poco::JSON::Object::Ptr _parseConfig(const sonataloader::EdgeLoadContext &context)
{
auto &config = context.config;
auto parsedJson = brayns::Json::parse(config.getConfigAsJson());
return parsedJson.extract<brayns::JsonObject::Ptr>();
}

std::filesystem::path _getConfigRootPath(const sonataloader::EdgeLoadContext &context)
{
auto &config = context.config;
return std::filesystem::path(config.getBasePath());
}

std::string _getDefaultPath()
{
// First fetch default one, if any
if (const auto components = _json->getObject("components"))
{
if (components->has("end_feet_area"))
{
return components->get("end_feet_area").extract<std::string>();
}
}
return {};
}

Poco::JSON::Object::Ptr _findPopulationObject()
{
auto edgeNetworks = _json->getObject("networks")->getArray("edges");
for (auto &entry : *edgeNetworks)
{
auto &entryObject = entry.extract<Poco::JSON::Object::Ptr>();
auto edgeFile = _getPathToEdgeFile(entryObject);

auto populationStorage = bbp::sonata::EdgeStorage(edgeFile);
for (auto &population : populationStorage.populationNames())
{
if (population != _edgeName)
{
continue;
}
auto popObject = entryObject->getObject("populations");
if (!popObject)
{
return nullptr;
}
return popObject->getObject(_edgeName);
}
}
return nullptr;
}

std::string _findEndfeetPath()
{
auto json = _findPopulationObject();

if (json->has("endfeet_meshes"))
{
return json->get("endfeet_meshes").extract<std::string>();
}
if (json->has("endfeet_meshes_file"))
{
return json->get("endfeet_meshes_file").extract<std::string>();
}
return {};
}

std::string _getPathToEdgeFile(const Poco::JSON::Object::Ptr &json)
{
auto edgeFile = json->get("edges_file").extract<std::string>();
auto edgeFilePath = std::filesystem::path(edgeFile);
if (!edgeFilePath.is_absolute())
{
auto edgeFileFullPath = _rootPath / edgeFilePath;
edgeFile = edgeFileFullPath.string();
}
return edgeFile;
}

private:
Poco::JSON::Object::Ptr _json;
std::filesystem::path _rootPath;
std::string _edgeName;
};

} // namespace

namespace sonataloader
{
std::string_view EndFootPopulationLoader::getPopulationType() const noexcept
Expand All @@ -161,17 +35,17 @@ std::string_view EndFootPopulationLoader::getPopulationType() const noexcept

void EndFootPopulationLoader::load(EdgeLoadContext &context) const
{
auto path = EndFeetAreasPath(context).resolve();

auto &nodeSelection = context.nodeSelection;
auto nodes = nodeSelection.flatten();
auto &population = context.edgePopulation;
auto populationProperties = context.config.getEdgesProperties(population.name());
auto &endfeetMeshPath = populationProperties.endfeetMeshesFile;
auto &edgeSelection = context.edgeSelection;
auto flatEdges = edgeSelection.flatten();
auto astrocyteIds = Synapses::getTargetNodes(population, edgeSelection);
auto endFeetIds = Synapses::getEndFeetIds(population, edgeSelection);

auto meshes = EndFeetReader::read(path, endFeetIds);
auto meshes = EndFeetReader::read(*endfeetMeshPath, endFeetIds);

std::map<uint64_t, std::vector<brayns::TriangleMesh>> endfeetGeometry;
for (size_t i = 0; i < astrocyteIds.size(); ++i)
Expand Down
2 changes: 1 addition & 1 deletion plugins/deps/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ if(BRAYNS_CIRCUITEXPLORER_ENABLED AND NOT sonata_FOUND AND NOT TARGET sonata::so
FetchContent_Declare(
libsonata
GIT_REPOSITORY https://github.com/BlueBrain/libsonata.git
GIT_TAG v0.1.22
GIT_TAG v0.1.23
GIT_SHALLOW ON
GIT_SUBMODULES_RECURSE ON
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libsonata
Expand Down

0 comments on commit 8345359

Please sign in to comment.