Creating a fiber

In this tutorial we create a mammalian myelinated fiber model (i.e., MRG) with a diameter of 10 µm using an instance of the Fiber class. We can control the length of the fiber by specifying one (and only one) of the following:

  • total number of sections (n_sections)

  • total number of nodes (n_nodes, where nodes are excitable sections that represent nodes of Ranvier)

  • length of the fiber in µm (length)

We can see the available fiber models using the code below. This will include any plugins that have been installed. If you wish to create your own fiber model, see the documentation on custom fiber models. Additionally, the implementation of our built-in fiber models are described in implementations of fiber models.

from pyfibers import FiberModel

[FM.name for FM in FiberModel]
['MRG_DISCRETE',
 'MRG_INTERPOLATION',
 'RATTAY',
 'SCHILD94',
 'SCHILD97',
 'SMALL_MRG_INTERPOLATION',
 'SUNDT',
 'THIO_AUTONOMIC',
 'THIO_CUTANEOUS',
 'TIGERHOLM']

We will select the MRG_INTERPOLATION model, and specify the number of nodes as 25.

from pyfibers import build_fiber

n_nodes = 25
fiber = build_fiber(FiberModel.MRG_INTERPOLATION, diameter=10, n_nodes=n_nodes)

This produces a fiber object that can be used to run simulations. See the fiber api documentation for additional parameters for fiber creation (e.g., fiber temperature).

print(fiber)
MRG_INTERPOLATION fiber of diameter 10 µm and length 26936.20 µm 
	node count: 25, section count: 265. 
	Fiber is not 3d.

The spatial position of the fiber may or may not be of interest, depending on if/how you intend to apply extracellular potentials to the fiber (See Extracellular potentials). If the spatial position is of interest, it can be ascertained with the Fiber.coordinates attribute, which returns the x, y, z coordinates of the center of each section in the fiber. By default, the fiber is positioned with one end at x=0, y=0, z=0 and extends in the positive z direction.

import numpy as np

np.set_printoptions(precision=2, suppress=True, threshold=50)
print(fiber.coordinates)
[[    0.       0.       0.5 ]
 [    0.       0.       2.5 ]
 [    0.       0.      27.37]
 ...
 [    0.       0.   26908.83]
 [    0.       0.   26933.7 ]
 [    0.       0.   26935.7 ]]

Note that this is distinct from Fiber.longitudinal_coordinates, which is the arc length along the fiber at the center of each section. For a straight fiber, this is equal to the z coordinate. For 3D fibers (See The 3D fiber tutorial), this is not the case. The fiber position for straight fibers can be changed using set_xyz(), which sets an x position, y position, and shifts the z coordinates by a given amount.

fiber.set_xyz(5, 10, -100)
print(fiber.coordinates)
[[    5.      10.     -99.5 ]
 [    5.      10.     -97.5 ]
 [    5.      10.     -72.63]
 ...
 [    5.      10.   26808.83]
 [    5.      10.   26833.7 ]
 [    5.      10.   26835.7 ]]

Below we outline some additional methods which may be helpful in using a fiber.

Magic Methods

Our fiber object has a number of special methods that simplify code usage.

Indexing

We can index into the fiber to access a particular node/section. Note that “nodes” refer to excitable sections, and not every section comprising the fiber. For more information, see Fiber Implementations.

node = fiber[2]  # Accesses the node at index 2
print(node)  # the number in the node name refers to the section index along the fiber
active node 22

NEURON style indexing

We can index to a node in NEURON style by calling the fiber object. We can also use the loc_index() method to get the index of a node using the same convention. Remember, the indexing uses the node index, but the name of the node object refers to its number in the list of sections comprising the fiber. To search among all sections, use the target="sections" arguments.

# indexing among nodes
node = fiber(0.9)
print('Node at 90% fiber length:', node)
ind = fiber.loc_index(0.9)
print('Index of node at 90% fiber length:', ind)
print('fiber[ind] is the same node?', fiber[ind] is node)

# now indexing to sections (which includes all nodes)
print()
section = fiber(0.9, target='sections')
print('Section at 90% along section list:', section)
sec_ind = fiber.loc_index(0.9, target='sections')
print('Index of section at 90% along section list:', sec_ind)
print(
    'fiber.sections[sec_ind] is the same section?', fiber.sections[sec_ind] is section
)
Node at 90% fiber length: active node 231
Index of node at 90% fiber length: 21
fiber[ind] is the same node? True

Section at 90% along section list: stin 237
Index of section at 90% along section list: 237
fiber.sections[sec_ind] is the same section? True

Iteration

The fiber’s nodes can be iterated over using a loop.

for node in fiber:
    print(node)
passive node 0
active node 11
active node 22
active node 33
active node 44
active node 55
active node 66
active node 77
active node 88
active node 99
active node 110
active node 121
active node 132
active node 143
active node 154
active node 165
active node 176
active node 187
active node 198
active node 209
active node 220
active node 231
active node 242
active node 253
passive node 264

Membership

We can check if a specific section object is part of the fiber. Note that nodes are part of the fiber’s sections.

node = fiber.nodes[0]
section = fiber.sections[0]
print(node in fiber)
print(section in fiber)
print(node in fiber.sections)
print(section in fiber.sections)
True
True
True
True

For an example of using this fiber in PyFibers’ simulation code, see the next tutorial on running a simulation and searching for activation threshold. Additionally, you can use this fiber object in your own custom simulation code.