User defined function to set play vectors

When Python is the interpreter, what is a good
design for the interface to the basic NEURON
concepts.

Moderator: hines

Post Reply
Robert Claar
Posts: 25
Joined: Tue Jun 23, 2020 8:52 am

User defined function to set play vectors

Post by Robert Claar »

I wanted to make this post to get some clarification about the behavior I am observing and also in case anyone else runs into a similar issue.

I am using the Vector.play method to set the values of a parameter inside one of my mod files. I started with a toy example that I found here in the forums viewtopic.php?p=19985&hilit=play+vectors#p19985. I made some minor modifications, mainly using single segment Sections.

For my use case it made sense to have my own function to set the play vectors, so I used the same code but took out the portion setting the play vectors and used it to create a function

Code: Select all


def set_play_vec(cell):
	
    data = h.Vector([0,5,17,2,4,38,22,43,1, 1])
    time = h.Vector([1,2,3,4,5,6,7,8,9,10])

    data.play(cell(0.5).playtest._ref_xx, time, True)
	
# Create NEURON Section
my_cell = h.Section("neurite")

# Set play vector
set_play_vec(my_cell)

t = h.Vector().record(h._ref_t)
xxp1 = h.Vector().record(my_cell(0.1).playtest._ref_xx)
xxp2 = h.Vector().record(my_cell(0.9).playtest._ref_xx)

h.finitialize(-65 * mV)
h.continuerun(10 * ms)

plt.plot(t, xxp1, label="xxp1")
plt.plot(t, xxp2, label="xxp2")
plt.legend()
plt.show()
However, when I did this I saw my recorded variables xxp1 and xxp2 were zero for all time points. After trying a bunch of different things I got it to work once I returned the data and time Vectors that I created inside my set_play_vecs function so they are available outside the scope of the function.

Code: Select all


def set_play_vec(cell):
	
    data = h.Vector([0,5,17,2,4,38,22,43,1, 1])
    time = h.Vector([1,2,3,4,5,6,7,8,9,10])

    data.play(cell(0.5).playtest.xx, time, True)
	
    return data, time
	
# Create NEURON Section	
my_cell = h.Section(name='neurite')

# Set play vector
data, time = set_play_vec(my_cell)

t = h.Vector().record(h._ref_t)
xxp1 = h.Vector().record(my_cell(0.1).playtest._ref_xx)
xxp2 = h.Vector().record(my_cell(0.9).playtest._ref_xx)

h.finitialize(-65 * mV)
h.continuerun(10 * ms)

plt.plot(t, xxp1, label="xxp1")
plt.plot(t, xxp2, label="xxp2")
plt.legend()
plt.show()
I also found that I could get it to work if I first made the time and data Vectors into global variables

Code: Select all

global data
global time
data = h.Vector([ 1,5,17,2,4,38,22,43,1, 1])
time = h.Vector([1,2,3,4,5,6,7,8,9,10])
Can anyone explain why these variables need to be available outside the scope of my function? I'm guessing the data Vector itself is still being referenced to during the simulation.
ted
Site Admin
Posts: 6300
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: User defined function to set play vectors

Post by ted »

Can anyone explain why these variables need to be available outside the scope of my function?
"Can anyone"? Sure--and in particular, you. Create some variable x inside a function and assign it a value. Exit the function without passing the value of x to an external variable. Then try using x after exiting from the function e.g. by printing its value or adding 1 to it and printing the result. What happens and why? Suppose "using that variable after exiting from the function" involves running a simulation--how's that going to work?
Robert Claar
Posts: 25
Joined: Tue Jun 23, 2020 8:52 am

Re: User defined function to set play vectors

Post by Robert Claar »

Sorry, some of my code was incorrect which makes my question seem silly (maybe it still will be when I correct it).

The initial chunk of code in my original post above should have been

Code: Select all

def set_play_vec(cell):
	
    data = h.Vector([0,5,17,2,4,38,22,43,1, 1])
    time = h.Vector([1,2,3,4,5,6,7,8,9,10])

    data.play(cell(0.5).playtest._ref_xx, time, True)
    
    return cell
	
# Create NEURON Section
my_cell = h.Section("neurite")

# Set play vector
my_cell = set_play_vec(my_cell)

t = h.Vector().record(h._ref_t)
xxp1 = h.Vector().record(my_cell(0.1).playtest._ref_xx)
xxp2 = h.Vector().record(my_cell(0.9).playtest._ref_xx)

h.cvode_active(True)
h.finitialize(-65 * mV)
h.continuerun(10 * ms)

plt.plot(t, xxp1, label="xxp1")
plt.plot(t, xxp2, label="xxp2")
plt.legend()
plt.show()
My initial instinct was to return the Section containing the mechanism that I am playing values into, but when I did this, my recording vectors xxp1 and xxp2 contained all zeros. However, when I did not return my Section but returned the data and time Vectors that contain my values I want played in, things worked as I expected.

Code: Select all

def set_play_vecs(cell):

    # Create some toy data
    data = h.Vector([4, 1, 5, 17, 2, 4, 38, 22, 43, 1, 1])
    time = h.Vector([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

    # Play the data vector values into the variable xx inside the mode file
    data.play(cell(0.5).playtest._ref_xx, time, True)

    # These vectors need to be returned so they are available outside the scope of this function
    # else no error will be raised but the variable will only take the value stated in the mod file
    return data, time

# Create a section
my_cell = h.Section("neurite")
my_cell.insert("playtest")

# Set play vectors
data, time = set_play_vecs(my_cell)

t = h.Vector().record(h._ref_t)
xxp1 = h.Vector().record(my_cell(0.1).playtest._ref_xx)
xxp2 = h.Vector().record(my_cell(0.9).playtest._ref_xx)

h.cvode_active(True)
h.finitialize(-65 * mV)
h.continuerun(10 * ms)

plt.plot(t, xxp1, label="xxp1")
plt.plot(t, xxp2, label="xxp2")
plt.legend()
plt.show()
This seemed odd to me since I am just returning, to my knowledge, two Vectors and not the Section containing the mechanism I am playing values into. However, now after a week or so of not looking at this, I notice that play is a method of Vector so I'm guessing that the data Vector contains the instructions to play into the xx variable inside the playtest mechanism inside my_cell, so it makes sense that I would need to return the vector being played instead of my Section.
Post Reply