Skip to content

Commit

Permalink
Added simulation model (#142)
Browse files Browse the repository at this point in the history

* Added color scheme for layers, e-types and m-types
  • Loading branch information
favreau committed Apr 4, 2017
1 parent 33668d8 commit 13f17df
Show file tree
Hide file tree
Showing 19 changed files with 351 additions and 1,159 deletions.
2 changes: 1 addition & 1 deletion brayns/Brayns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ struct Brayns::Impl
auto& scene = _engine->getScene();

strings filters = {".obj", ".dae", ".fbx", ".ply", ".lwo",
".stl", ".3ds", ".ase", ".ifc"};
".stl", ".3ds", ".ase", ".ifc", ".off"};
strings files = parseFolder(folder, filters);
size_t progress = 0;
for (const auto& file : files)
Expand Down
11 changes: 7 additions & 4 deletions brayns/common/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,13 @@ enum class ColorScheme
neuron_by_id = 1,
neuron_by_type = 2,
neuron_by_segment_type = 3,
protein_by_id = 4,
protein_atoms = 5,
protein_chains = 6,
protein_residues = 7
neuron_by_layer = 4,
neuron_by_mtype = 5,
neuron_by_etype = 6,
protein_by_id = 7,
protein_atoms = 8,
protein_chains = 9,
protein_residues = 10
};

/** Define the environment that is added to the default scene */
Expand Down
12 changes: 8 additions & 4 deletions brayns/common/vocabulary/parameters.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,13 @@ enum ColorScheme: uint {
neuron_by_id = 1,
neuron_by_type = 2,
neuron_by_segment_type = 3,
protein_by_id = 4,
protein_atoms = 5,
protein_chain = 6,
protein_residue = 7
neuron_by_layer = 4,
neuron_by_mtype = 5,
neuron_by_etype = 6,
protein_by_id = 7,
protein_atoms = 8,
protein_chain = 9,
protein_residue = 10
}

enum SceneEnvironment: uint {
Expand Down Expand Up @@ -82,6 +85,7 @@ table DataSource {
end_simulation_time: float;
simulation_values_range: [float:2];
simulation_cache_file: string;
use_simulation_model: bool;
nest_cache_file: string;
morphology_section_types: [SectionType];
morphology_layout: MorphologyLayout;
Expand Down
146 changes: 120 additions & 26 deletions brayns/io/MorphologyLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#ifdef BRAYNS_USE_BRION
#include <brain/brain.h>
#include <brion/brion.h>
typedef std::shared_ptr<brion::Circuit> BrionCircuitPtr;
#endif

namespace brayns
Expand All @@ -59,12 +60,10 @@ brain::neuron::SectionTypes _getSectionTypes(
return sectionTypes;
}

bool MorphologyLoader::_importMorphologyAsMesh(const servus::URI& source,
const size_t morphologyIndex,
const MaterialsMap& materials,
const Matrix4f& transformation,
TrianglesMeshMap& meshes,
Boxf& bounds)
bool MorphologyLoader::_importMorphologyAsMesh(
const servus::URI& source, const size_t morphologyIndex,
const MaterialsMap& materials, const Matrix4f& transformation,
TrianglesMeshMap& meshes, Boxf& bounds, const size_t forcedMaterial)
{
try
{
Expand All @@ -85,7 +84,8 @@ bool MorphologyLoader::_importMorphologyAsMesh(const servus::URI& source,
// Soma
const brain::neuron::Soma& soma = morphology.getSoma();
const size_t material = _getMaterialFromSectionType(
morphologyIndex, size_t(brain::neuron::SectionType::soma));
morphologyIndex, forcedMaterial,
size_t(brain::neuron::SectionType::soma));
const Vector3f center = soma.getCentroid();

const float radius =
Expand All @@ -112,7 +112,7 @@ bool MorphologyLoader::_importMorphologyAsMesh(const servus::URI& source,
}

const auto material =
_getMaterialFromSectionType(morphologyIndex,
_getMaterialFromSectionType(morphologyIndex, forcedMaterial,
size_t(section.getType()));
const auto& samples = section.getSamples();
if (samples.empty())
Expand Down Expand Up @@ -144,8 +144,10 @@ bool MorphologyLoader::_importMorphologyAsMesh(const servus::URI& source,
const size_t gridSize = _geometryParameters.getMetaballsGridSize();
const float threshold = _geometryParameters.getMetaballsThreshold();
MetaballsGenerator metaballsGenerator;
const size_t material = _getMaterialFromSectionType(
morphologyIndex, size_t(brain::neuron::SectionType::soma));
const size_t material =
_getMaterialFromSectionType(morphologyIndex, forcedMaterial,
size_t(
brain::neuron::SectionType::soma));
metaballsGenerator.generateMesh(metaballs, gridSize, threshold,
materials, material, meshes);
}
Expand Down Expand Up @@ -182,7 +184,8 @@ bool MorphologyLoader::_importMorphology(
const Matrix4f& transformation,
const SimulationInformation* simulationInformation, SpheresMap& spheres,
CylindersMap& cylinders, ConesMap& cones, Boxf& bounds,
const size_t simulationOffset, float& maxDistanceToSoma)
const size_t simulationOffset, float& maxDistanceToSoma,
const size_t forcedMaterial)
{
maxDistanceToSoma = 0.f;
try
Expand Down Expand Up @@ -233,24 +236,47 @@ bool MorphologyLoader::_importMorphology(
// Soma
const brain::neuron::Soma& soma = morphology.getSoma();
const size_t material = _getMaterialFromSectionType(
morphologyIndex, size_t(brain::neuron::SectionType::soma));
const Vector3f& center = soma.getCentroid() + translation;
morphologyIndex, forcedMaterial,
size_t(brain::neuron::SectionType::soma));
const Vector3f somaPosition = soma.getCentroid() + translation;

const float radius =
float radius =
(_geometryParameters.getRadiusCorrection() != 0.f
? _geometryParameters.getRadiusCorrection()
: soma.getMeanRadius() *
_geometryParameters.getRadiusMultiplier());
spheres[material].push_back(
SpherePtr(new Sphere(material, center, radius, 0.f, offset)));
bounds.merge(center);

spheres[material].push_back(SpherePtr(
new Sphere(material, somaPosition, radius, 0.f, offset)));
bounds.merge(somaPosition);

if (_geometryParameters.getUseSimulationModel())
{
// When using a simulation model, parametric geometries must
// occupy as much space as possible in the mesh. This code
// inserts a Cone between the soma and the beginning of each
// branch.
const auto& children = soma.getChildren();
for (const auto& child : children)
{
const auto& samples = child.getSamples();
const Vector3f sample = {samples[0].x(), samples[0].y(),
samples[0].z()};
cones[material].push_back(ConePtr(
new Cone(material, somaPosition, sample, radius,
samples[0].w() * 0.5f *
_geometryParameters.getRadiusMultiplier(),
0.f, offset)));
bounds.merge(sample);
}
}
}

// Dendrites and axon
for (const auto& section : sections)
{
const size_t material =
_getMaterialFromSectionType(morphologyIndex,
_getMaterialFromSectionType(morphologyIndex, forcedMaterial,
size_t(section.getType()));
const Vector4fs& samples = section.getSamples();
if (samples.empty())
Expand Down Expand Up @@ -352,6 +378,50 @@ bool MorphologyLoader::_importMorphology(
return true;
}

brion::NeuronAttributes getNeuronAttributes(const ColorScheme& colorScheme)
{
brion::NeuronAttributes neuronAttributes;
switch (colorScheme)
{
case ColorScheme::neuron_by_layer:
neuronAttributes = brion::NEURON_LAYER;
break;
case ColorScheme::neuron_by_mtype:
neuronAttributes = brion::NEURON_MTYPE;
break;
case ColorScheme::neuron_by_etype:
neuronAttributes = brion::NEURON_ETYPE;
break;
default:
neuronAttributes = brion::NEURON_ALL;
break;
}
return neuronAttributes;
}

bool getNeuronMatrix(const brion::BlueConfig& bc, const brain::GIDSet& gids,
const ColorScheme colorScheme, strings& neuronMatrix)
{
brion::NeuronAttributes neuronAttributes = getNeuronAttributes(colorScheme);
if (neuronAttributes == brion::NEURON_ALL)
return false;
try
{
brion::Circuit brionCircuit(bc.getCircuitSource());
for (const auto& a : brionCircuit.get(gids, neuronAttributes))
neuronMatrix.push_back(a[0]);
return true;
}
catch (...)
{
BRAYNS_WARN << "Only MVD2 format is currently supported by Brion "
"circuits. Color scheme by layer, e-type or m-type is "
"not available for this circuit"
<< std::endl;
}
return false;
}

bool MorphologyLoader::importCircuit(const servus::URI& circuitConfig,
const std::string& target, Scene& scene)
{
Expand All @@ -366,13 +436,17 @@ bool MorphologyLoader::importCircuit(const servus::URI& circuitConfig,
return false;
}
const Matrix4fs& transforms = circuit.getTransforms(gids);

const brain::URIs& uris = circuit.getMorphologyURIs(gids);

BRAYNS_INFO << "Loading " << uris.size() << " cells" << std::endl;

std::map<size_t, float> morphologyOffsets;
// Read Brion circuit
strings neuronMatrix;
bool mvd3Support =
getNeuronMatrix(bc, gids, _geometryParameters.getColorScheme(),
neuronMatrix);

std::map<size_t, float> morphologyOffsets;
size_t simulationOffset = 1;
size_t simulatedCells = 0;
size_t progress = 0;
Expand All @@ -387,19 +461,22 @@ bool MorphologyLoader::importCircuit(const servus::URI& circuitConfig,
{
const auto& uri = uris[i];
float maxDistanceToSoma = 0.f;
const size_t material =
mvd3Support ? boost::lexical_cast<size_t>(neuronMatrix[i])
: NO_MATERIAL;

if (_geometryParameters.useMetaballs())
{
_importMorphologyAsMesh(uri, i, scene.getMaterials(),
transforms[i],
scene.getTriangleMeshes(),
scene.getWorldBounds());
scene.getWorldBounds(), material);
}

if (_importMorphology(uri, i, transforms[i], 0, private_spheres,
private_cylinders, private_cones,
private_bounds, simulationOffset,
maxDistanceToSoma))
maxDistanceToSoma, material))
{
morphologyOffsets[simulatedCells] = maxDistanceToSoma;
simulationOffset += maxDistanceToSoma;
Expand Down Expand Up @@ -477,6 +554,12 @@ bool MorphologyLoader::importCircuit(const servus::URI& circuitConfig,
brain::URIs cr_uris;
const brain::GIDSet& cr_gids = compartmentReport.getGIDs();

// Read Brion circuit
strings neuronMatrix;
bool mvd3Support =
getNeuronMatrix(bc, gids, _geometryParameters.getColorScheme(),
neuronMatrix);

BRAYNS_INFO << "Loading " << cr_gids.size() << " simulated cells"
<< std::endl;
for (const auto cr_gid : cr_gids)
Expand All @@ -499,19 +582,22 @@ bool MorphologyLoader::importCircuit(const servus::URI& circuitConfig,
const auto& uri = cr_uris[i];
const SimulationInformation simulationInformation = {
&compartmentCounts[i], &compartmentOffsets[i]};
const size_t material =
mvd3Support ? boost::lexical_cast<size_t>(neuronMatrix[i])
: NO_MATERIAL;

if (_geometryParameters.useMetaballs())
{
_importMorphologyAsMesh(uri, i, scene.getMaterials(),
transforms[i],
scene.getTriangleMeshes(),
scene.getWorldBounds());
scene.getWorldBounds(), material);
}

float maxDistanceToSoma;
_importMorphology(uri, i, transforms[i], &simulationInformation,
private_spheres, private_cylinders, private_cones,
private_bounds, 0, maxDistanceToSoma);
private_bounds, 0, maxDistanceToSoma, material);

BRAYNS_PROGRESS(progress, cr_uris.size());
#pragma omp atomic
Expand Down Expand Up @@ -586,10 +672,15 @@ bool MorphologyLoader::importCircuit(const servus::URI& circuitConfig,
{
float maxDistanceToSoma;
const auto& uri = allUris[i];
const size_t material =
mvd3Support
? boost::lexical_cast<size_t>(neuronMatrix[i][0])
: NO_MATERIAL;

_importMorphology(uri, i, allTransforms[i], 0, private_spheres,
private_cylinders, private_cones,
private_bounds, 0, maxDistanceToSoma);
private_bounds, 0, maxDistanceToSoma,
material);

BRAYNS_PROGRESS(progress, allUris.size());
#pragma omp atomic
Expand Down Expand Up @@ -745,8 +836,11 @@ bool MorphologyLoader::importSimulationData(const servus::URI&,
#endif

size_t MorphologyLoader::_getMaterialFromSectionType(
const size_t morphologyIndex, const size_t sectionType)
const size_t morphologyIndex, const size_t forcedMaterial,
const size_t sectionType)
{
if (forcedMaterial != NO_MATERIAL)
return forcedMaterial;
size_t material;
switch (_geometryParameters.getColorScheme())
{
Expand Down
11 changes: 7 additions & 4 deletions brayns/io/MorphologyLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,19 @@ class MorphologyLoader
SpheresMap& spheres, CylindersMap& cylinders,
ConesMap& cones, Boxf& bounds,
const size_t simulationOffset,
float& maxDistanceToSoma);
float& maxDistanceToSoma,
const size_t forcedMaterial = NO_MATERIAL);

bool _importMorphologyAsMesh(const servus::URI& source,
const size_t morphologyIndex,
const MaterialsMap& materials,
const Matrix4f& transformation,
TrianglesMeshMap& meshes, Boxf& bounds);
TrianglesMeshMap& meshes, Boxf& bounds,
const size_t forcedMaterial = NO_MATERIAL);

size_t _getMaterialFromSectionType(size_t morphologyIndex,
size_t sectionType);
size_t _getMaterialFromSectionType(const size_t morphologyIndex,
const size_t forcedMaterial,
const size_t sectionType);

const GeometryParameters& _geometryParameters;
};
Expand Down
Loading

0 comments on commit 13f17df

Please sign in to comment.