Morphology Usage¶
Morphology usage can be split into two APIs: mutable and immutable. Mutable is for creating or editing morphologies. Immutable is for read-only operations. Both are represented in C++ and Python.
Immutable API¶
This read-only API aims at providing better performances as its internal data representation is contiguous in memory. All accessors return immutable objects.
Internally, in this API the morphology object is in fact where all is are stored. The Soma and Section classes are lightweight classes that provide views on the Morphology data.
To access it in C++:
#include <morphio/morphology.h>
#include <morphio/section.h>
#include <morphio/soma.h>
To access it in Python:
from morphio import Morphology, Section, Soma
Example of morphology analysis with Immutable API:¶
C++:
#include <morphio/morphology.h>
#include <morphio/section.h>
int main()
{
auto m = morphio::Morphology("sample.asc");
auto roots = m.rootSections();
auto first_root = roots[0];
// iterate on sections starting at first_root
for (auto it = first_root.depth_begin(); it != first_root.depth_end(); ++it) {
const morphio::Section §ion = *it;
std::cout << "Section type: " << section.type()
<< "\nSection id: " << section.id()
<< "\nParent section id: " << section.parent().id()
<< "\nNumber of child sections: " << section.children().size()
<< "\nX - Y - Z - Diameter";
for (auto i = 0u; i < section.points().size(); ++i) {
const auto& point = section.points()[i];
std::copy(point.begin(), point.end(), std::ostream_iterator<float>(std::cout, " "));
std::cout << '\n' << section.diameters()[i] << '\n';
}
std::cout << '\n';
}
}
Python:
from morphio import Morphology
m = Morphology("sample.asc")
roots = m.root_sections
first_root = roots[0]
# iterate on sections starting at first_root
for section in first_root.iter():
print("Section type: {}".format(section.type))
print("Section id: {}".format(section.id))
if not section.is_root:
print("Parent section id: {}".format(section.parent.id))
print("Number of child sections: {}".format(len(section.children)))
print("X - Y - Z - Diameter")
for point, diameter in zip(section.points, section.diameters):
print('{} - {}'.format(point, diameter))
Mutable API¶
This API can be as well used for reading morphologies but the main usage of it is creating morphologies or editing them.
Example of creating morphologies¶
C++:
#include <morphio/mut/morphology.h>
int main()
{
morphio::mut::Morphology morpho;
morpho.soma()->points() = {{0, 0, 0}, {1, 1, 1}};
morpho.soma()->diameters() = {1, 1};
auto section = morpho.appendRootSection(
morphio::Property::PointLevel(
{{2, 2, 2}, {3, 3, 3}}, // x,y,z coordinates of each point
{4, 4}), // diameter of each point
morphio::SectionType::SECTION_AXON); // (optional) perimeter of each point
auto childSection = section->appendSection(
morphio::Property::PointLevel(
{{3, 3, 3}, {4, 4, 4}},
{4, 4}),
morphio::SectionType::SECTION_AXON);
// Writing the file in the 3 formats
morpho.write("outfile.asc");
morpho.write("outfile.swc");
morpho.write("outfile.h5");
}
Python:
from morphio import PointLevel, SectionType
from morphio.mut import Morphology
morpho = Morphology()
morpho.soma.points = [[0, 0, 0], [1, 1, 1]]
morpho.soma.diameters = [1, 1]
section = morpho.append_root_section(
PointLevel(
[[2, 2, 2], [3, 3, 3]], # x, y, z coordinates of each point
[4, 4]), # diameter of each point
SectionType.axon) # (optional) perimeter of each point
child_section0 = section.append_section(
PointLevel(
[[3, 3, 3], [4, 4, 4]],
[4, 4])) # section type is omitted -> parent section type will be used
child_section1 = section.append_section(
PointLevel(
[[3, 3, 3], [5, 5, 5]],
[5, 5])) # section type is omitted -> parent section type will be used
morpho.write("outfile.asc")
morpho.write("outfile.swc")
morpho.write("outfile.h5")
Opening flags¶
In both types of API when opening the file, modifier flags can be passed to alter the morphology representation. The following flags are supported:
morphio::NO_MODIFIER
: This is the default flag, it will do nothing.morphio::TWO_POINTS_SECTIONS
: Each section gets reduce to a line made of the first and lastpoint.
morphio::SOMA_SPHERE
: The soma is reduced to a sphere which is the center of gravity of thereal soma.
morphio::NO_DUPLICATES
: The duplicate point are not present. It means the first point ofeach section is no longer the last point of the parent section.
morphio::NRN_ORDER
: Neurite are reordered according to the
morphio::UNIFURCATED_SECTION_CHANGE
: Allow section type to change without bifurcation, emits warning
Multiple flags can be passed by using the standard bit flag manipulation (works the same way in C++ and Python):
C++:
#include <morphio/Morphology.h>
Morphology("myfile.asc", options=morphio::NO_DUPLICATES|morphio::NRN_ORDER)
Python:
from morphio import Morphology, Option
Morphology("myfile.asc", options=Option.no_duplicates|Option.nrn_order)