Custom Simulation Code

This section provides examples of how to run custom simulations using fibers. These examples demonstrate different methods, including directly using NEURON’s :class:IClamp <neuron:IClamp> and h.continuerun(), leveraging the Stimulation class with a custom run_sim() function, and using the pre_run_setup() method with manual assignment of extracellular potentials.

Before running any simulations, we must create a model fiber. See the Fiber Tutorial for information on how to do so. The tutorials assume that you have already created a model fiber called fiber.

Custom Simulation with a Custom run_sim() Function

In this example, we demonstrate how to set up a custom simulation by providing a custom run_sim function to the Stimulation class. You could also achieve this by creating a subclass and overriding the run_sim() method.

Note

Note, to use custom run_sim() methods with threshold searches, the custom method should take stimulation amplitude as the first argument, and return the number of action potentials generated and the time of the last action potential.

  1. Define the custom run_sim() function:

def custom_run_sim(self, stimamp, fiber):
    print("Running custom simulation.")

    # Set up the simulation using Stimulation.pre_run_setup
    stimulation.pre_run_setup(fiber)

    # Example of a custom simulation loop
    for i in range(int(stimulation.tstop / stimulation.dt)):
        # Custom simulation logic here

        # Advance to the next time step
        h.fadvance()

    return n_aps, last_ap_time
  1. Set up the Stimulation instance with the custom run_sim() function:

from pyfibers import Stimulation

stimulation = Stimulation(dt=0.001, tstop=20, custom_run_sim=custom_run_sim)

stimulation.run_sim(fiber)

Custom run_sim in a Subclass of Stimulation

In this example, we demonstrate how to create a subclass of Stimulation and override the run_sim() method to provide custom simulation logic. See pyfibers.stimulation.ScaledStim.run_sim() and pyfibers.stimulation.IntraStim.run_sim() for examples.

  1. Create a subclass of Stimulation:

from pyfibers import Stimulation


class CustomStimulation(Stimulation):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
  1. Override the run_sim() method:

def run_sim(self, stimamp, fiber):  # defined as a method of CustomStimulation
    print("Running custom simulation:")

    self.pre_run_setup(fiber)

    # Example of a custom simulation loop
    for i in range(int(self.tstop / self.dt)):
        # Custom simulation logic here

        # Advance to next time step
        h.fadvance()

    return n_aps, last_ap_time
  1. Set up the CustomStimulation instance and run the simulation:

stimulation = CustomStimulation(dt=0.001, tstop=20)
stimulation.run_sim(fiber)

Custom Simulation Using NEURON IClamp and h.continuerun()

In this example, we demonstrate how to set up a custom simulation using NEURON’s :class:IClamp <neuron:IClamp> and h.continuerun() without using the simulation classes included in PyFibers.

  1. Set up and configure intracellular stimulation:

from neuron import h

# Apply stimulation to the 10th section of the fiber
stim = h.IClamp(fiber.sections[10](0.5))
stim.amp = 0.1  # nA
stim.delay = 1  # ms
stim.dur = 5  # ms
  1. Run the simulation:

# Initialize membrane potential using h.finitialize
h.finitialize(fiber.v_rest)
# Run the simulation for 20 ms using h.continuerun
h.continuerun(20)

Custom Simulation Using pre_run_setup() and Manual Extracellular Potentials

In this example, we demonstrate how to set up a custom simulation by using the pre_run_setup() method and then manually assigning extracellular potentials in a loop.

  1. Set up the Stimulation instance:

from pyfibers import Stimulation

stimulation = Stimulation(dt=0.001, tstop=20)

# Pre-run setup using Stimulation.pre_run_setup
stimulation.pre_run_setup(fiber)
  1. Manually assign extracellular potentials in the simulation loop:

stimamp = 0.1  # Example stimulation amplitude

for i in range(int(stimulation.tstop / stimulation.dt)):
    # Manually assign extracellular potentials using Stimulation._update_extracellular
    e_stims = [stimamp * pot for pot in fiber.potentials]
    stimulation._update_extracellular(fiber, e_stims)

    # Advance the simulation using h.fadvance
    h.fadvance()

These examples demonstrate different ways to set up and run custom simulations using fibers—with or without the Stimulation class. Each method allows for flexibility in how the simulations are defined and executed.