Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pynest microcircuit #451

Merged
merged 16 commits into from
Dec 14, 2016
Merged

Pynest microcircuit #451

merged 16 commits into from
Dec 14, 2016

Conversation

hendrikrth
Copy link
Contributor

The example files of NEST are lacking a PyNEST version of the microcircuit #450. To compensate this I would like you to include my branch. As reviewers I suggest @jhnnsnk and @mschmidt87.

May 2016

## Description ##
This is a PyNEST implementation of the SLI cortical microcircuit from the microcircuit model by Potjans and Diesmann (2014): The cell-type specific
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a PyNEST implementation of the microcircuit model ...
(no need to mention SLI)

@mschmidt87
Copy link

👍 from me.

'Seeds for random number generators of virtual processes: %r'
% rng_seeds
)
print('Global random number generator seed:%i' % grng_seed)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a space in front of %i for being consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


def connect_devices(self):
""" Connects the recording devices to the microcircuit."""
print('%s of 2 Devices connected' % (len(self.net_dict['rec_dev'])))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It prints "1 of 2 Devices connected" if only a spike detector is used which sounds as if something was missing. I suggest to be specific and print "Spike Detector connected" or/and "Voltmeter connected".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed



# Initialize the network and pass parameters to it.
net = network.Network(sim_dict, net_dict, stim_dict)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to time also the network initialization.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

t1 = time.time()
net.setup()
time_con = time.time()-t1
print("Time to create the connections: %.2f seconds" % time_con)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the units ms and Hz are printed as well, why not just writing s instead of seconds?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


How to use the example:

To run the microcircuit on a local machine, adjust the variables `N_scaling` and `K_scaling` in `network_params.py` to 0.1 and create an output directory called `data`. `N_scaling` adjusts the number of neurons and `K_scaling` the number of connections to be simulated. The full network can be run by adjusting these values to 1. If this is done, the option to print the time progress should be set to False in the file `sim_params.py`. For running, use `python example.py`. The output will be saved in the directory `data`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove

and create an output directory called data.

since this is now done automatically.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

""" This function simulates the microcircuit."""
nest.Simulate(self.sim_dict['t_sim'])

def evaluate(self, raster_plot_time_idx, fire_rate_time_idx):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could save the generated plots directly in the output directory together with the raw data.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

# Standard deviation of the postsynaptic potential (in relative units).
'PSP_sd': 0.1,
# Start of the thalamic input (in ms).
'th_start': 700.0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to set the default stimulus intervals somewhere into the default plotting interval so that their effect is directly visible by eye.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept the thalamus stimulus interval, since this is the stimulus interval of the sli version. I therefore changed the interval of the spike raster plot.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Please update the comment on the plotting interval accordingly.

else:
os.mkdir(self.sim_dict['data_path'])
print('data directory created')
print('Data will be written to %s' % self.data_path)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If used with MPI such statements are currently printed once per process. Please print them only on Rank 0 unless you want to print something specific to a process.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

'0 << /model /%s >> GetLocalNodes' % self.net_dict['neuron_model']
)
local_nodes = nest.sli_pop()
vp = nest.GetStatus(local_nodes)[0]['vp']
Copy link
Contributor

@jhnnsnk jhnnsnk Nov 8, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If run with both MPI and threads, taking the vp of the first local node is not correct. For example, with 2 MPI processes and 2 threads, one gets the MPI ranks 0 and 1, but the vps 0,1,2 and 3. For accessing the right pyrngs, I think we cannot avoid to extract all vps correponding to the local nodes. I will give a suggestion soon.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be a possible solution to the problem:

for thread in np.arange(nest.GetKernelStatus('local_num_threads')):
    local_nodes = nest.GetNodes([0], {'model': self.net_dict['neuron_model'], 'thread': thread}, local_only=True)[0]
    vp = nest.GetStatus(local_nodes)[0]['vp'] # same thread on MPI proc -> same vp
    nest.SetStatus(
        local_nodes, 'V_m', self.pyrngs[vp].normal(
        self.net_dict['neuron_params']['V0_mean'],
        self.net_dict['neuron_params']['V0_sd'],
            len(local_nodes)))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed this, using your solution.

self.DC_amp_e = compute_DC(self.net_dict, self.w_ext)

print(
'The Number of neurons is scaled by a factor of: %.2f'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Number -> number

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@jhnnsnk
Copy link
Contributor

jhnnsnk commented Nov 9, 2016

Hi, during testing with both MPI and threads, I noticed that the initialization of membrane voltages did not work correctly. I made a suggestion inline how this could be solved. Apart from this, I made some other minor comments for improvement.

@terhorstd terhorstd added ZC: PyNEST DO NOT USE THIS LABEL I: No breaking change Previously written code will work as before, no one should note anything changing (aside the fix) ZP: PR Created DO NOT USE THIS LABEL S: Normal Handle this with default priority T: Enhancement New functionality, model or documentation labels Nov 17, 2016
fixed initialization of membrane potentials, with provided solution
@heplesser heplesser added ZC: Documentation DO NOT USE THIS LABEL and removed ZC: PyNEST DO NOT USE THIS LABEL labels Nov 17, 2016
Copy link

@mschmidt87 mschmidt87 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thanks to @albada , I took another look at the code and discovered some typos. Please fix them.

# along with NEST. If not, see <http://www.gnu.org/licenses/>.

'''
pynest microcicuit example

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please correct to microcircuit. Also in All other files that have this typo.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed this and all other typos



def get_weight(PSP_val, net_dict):
""" Function computes weight to elicit a change in the membrane potential.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change to "Computes" in accordance to the documentation of other functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes this and adapted this style in all other functions

)
# If the network is scaled the indegrees are calculated in the same
# fashion as in the original version of the circuit, which is
# written in sli

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

insert '.' at the end.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

def adj_w_ext_to_K(K_full, K_scaling, w, w_from_PSP, DC, net_dict, stim_dict):
""" Adjustment of weights to scaling is dine in this function.

With this funtion the recurrent and external weights are adjusted

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done



def load_spike_times(path, name, begin, end):
""" This function loads spike times of each spike detector.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to "Loads..."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

# along with NEST. If not, see <http://www.gnu.org/licenses/>.

'''
microcicuit simulation parameters

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

microcircuit

microcicuit simulation parameters
---------------------------------

Simulation Parameters for the microcircuit.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simulation parameters

'local_num_threads': 1,
# Recording interval of the membrane potential (in ms).
'rec_V_int': 1.0,
# If True data will be overwritten,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If True, data...

# Recording interval of the membrane potential (in ms).
'rec_V_int': 1.0,
# If True data will be overwritten,
# if False a NESTError is raised if the files already exist.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If False, ...

# along with NEST. If not, see <http://www.gnu.org/licenses/>.

'''
microcicuit stimulus parameters

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

microcircuit

some typos were fixed and a comment about the initialization
of the membrane potentials was changed
@jhnnsnk
Copy link
Contributor

jhnnsnk commented Dec 14, 2016

👍

@heplesser
Copy link
Contributor

@hendrikrth Thank you for porting this important model to PyNEST! @jhnnsnk @mschmidt87 Thank you for your thorough review!

@heplesser heplesser merged commit 102e338 into nest:master Dec 14, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I: No breaking change Previously written code will work as before, no one should note anything changing (aside the fix) S: Normal Handle this with default priority T: Enhancement New functionality, model or documentation ZC: Documentation DO NOT USE THIS LABEL ZP: PR Created DO NOT USE THIS LABEL
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants