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

report for computing population-resolved ecp and average membrane potentials #312

Open
nicolomeneghetti opened this issue Jun 30, 2023 · 4 comments

Comments

@nicolomeneghetti
Copy link

Dear all,

I am writing for three issues (the first two really related one another).

  1. How can I modify the "config.json" report section in order to tell bmtk to compute the 'population_name' resolved ecp? My goal is indeed to optimize disk space usage: I would like therefore to tell bmtk to calculate the extracellular potentials estimate for each "population_name" (rather than for each cell) separately.

For example: I have a network composed of two populations: 'e5' and 'i5' (each one composed of 1000 and 500 neurons respectively). Is there a way to tell bmtk to provide as output two files containg the ecps generated by the two neuronal families separately?


  1. Is there a way to specify in the "config.json" report section to compute (for each 'population_name') the average membrane potential trace among cells belonging to the same 'population_name'?

Using the same example as point 1): is there a way to tell bmtk to produce as output two files (one containing the average membrane potentials between all the neurons belonging to 'e5' and the other one for the 'i5' family)?


  1. In the "v1_v1_edge_types.csv" of the Billeh et al. network (available here: https://www.dropbox.com/sh/w5u31m3hq6u2x5m/AAD9BfM5ndSCZOYslh1zWokga/simulations/v1_biophysical/network?dl=0&subfolder_nav_tracking=1) there's something that seems odd (at least to me).

In some istances of the .csv files, it is indeed possible to read in the target_query column: node_type_id=='478110866'&pop_name=='i6Htr3a'

Yet, in the very same file, it is also possible to find a target_query that reads:

node_type_id=='478110866'&pop_name=='i5Htr3a'

I don't understand how is it possible that two edges have the same "node_type_id" attribure, but different "pop_name" (please note that I have reported just an example but there are multiple istances in which this apparent contradiction seems to appear).

Thanks in advance for any help,

Best regards,

Nicolò

@shixnya
Copy link
Collaborator

shixnya commented Jun 30, 2023

Hi Nicolò,

1 and 2:
Please check these working examples to see if you can do what you want to do.
In one file I'm specifying multiple conditions for selecting a population. You should be able to use any cell property defined in the node_types file.
In the other file, I'm saving voltage and current in separate files by having multiple items in 'reports' section. Similarly, you should be able to save voltages for multiple populations in separate files.

config_multimeter.json.txt
config_lgn_multimeter.json.txt

I am not aware of a way to calculate an average for the population in BMTK, so please do so once the file is generated.

3:
I don't have a concrete answer for this right now, so let us get back to this a little later.

@kaeldai
Copy link
Collaborator

kaeldai commented Jun 30, 2023

Hi @nicolomeneghetti

1

It is possible to have multiple "ecp" module reports that record from a different subset of cells. In the below I split the ecp module into two but notice that in the "cells" option instead of a value of "all", on filters for only those cells with population_name=e5 and the other filters only cells with population_name=i5. Also I changed the "file_name" and "contributions_dir" so the two ecp modules don't overwrite each other:

"reports" : {
    "ecp_e5": {
        "module": "extracellular",
        "variable_name": "v",
        "electrode_channels": "all",
        "electrode_positions": "$COMPONENTS_DIR/recXelectrodes/linear_electrode.csv",
        "file_name": "ecp_e5.h5",
        "cells": {"population_name": "e5"},
        "contributions_dir": "ecp_contributions_e5"
    },
    "ecp_i5": {
        "module": "extracellular",
        "variable_name": "v",
        "cells": {"population_name": "i5"},
        "electrode_positions": "$COMPONENTS_DIR/recXelectrodes/linear_electrode.csv",
        "file_name": "ecp_i5.h5",
        "electrode_channels": "all",
        "contributions_dir": "ecp_contributions_i5"
    },

Also, if you want to save space you can get rid of the "contriubtions_dir"; it will still create a ecp_e5 and ecp_i5 ecp file but not store the individual cell contribution.

note: you may need to update bmtk as there is could be potential bug depending on your system.

2

Similar to above, it is possible to split the Vm report into multiple reports, and modify the "cell" option to filter out only a specific subset of cells:

  "vm_e5": {
    "cells": {"population_name": "e5"},
    "variable_name": "v",
    "module": "membrane_report",
    "sections": "soma"
  },
  "vm_i5": {
    "cells": {"population_name": "i5"},
    "variable_name": "v",
    "module": "membrane_report",
    "sections": "soma"
  }

This will produce two separate files, vm_e5.h5 and vm_i5.h5, containing only e5 cells and i5 cells voltage traces respectively. However, at the moment we don't have a direct way to store the mean voltage traces. However the following python script can be used to read both h5 files, find the mean voltage traces over all cells, and save them to a csv file:

import h5py
import numpy as np
import pandas as pd

pop_names = ['i5', 'e5']
for pname in pop_names:
    with h5py.File(f'output/vm_{pname}.h5', 'r') as h5:
        for node_pop_name, node_pop_grp in h5['report'].items():
            tstart, tstop, dt = node_pop_grp['mapping/time'][()]
            times = np.arange(tstart, tstop, step=dt)
            vm_means = np.mean(node_pop_grp['data'][()], axis=1)
            pd.DataFrame({
                'node_population': node_pop_name,
                'population_name': pname,
                'times': times,
                'vm_means': vm_means
            }).to_csv(f'{pname}_vm_means.csv', index=False, sep=' ')

3

Taking a brief look at the v1_v1_edges files, it looks like there are some "edge_types" specified in the csv that don't actually exists. So it looks like at some point someone tried to create a set of connection onto cells with node_type_id==478110866 & pop_name=='i5Htr3a', but there are none. It's like trying to find all excitatory GABA neurons; in BMTK/SONATA it's a valid query even if the results don't exists.

I will need to do some more digging to see how this happened and hopefully fix this issue. Thanks for bringing it to our attention!

@nicolomeneghetti
Copy link
Author

Dear all,

thanks for the reply. I totally got the response concerning the ecp reports (thanks a lot: it works just like I wanted to).

It's a pity that there is no similar approach to save disk space by storing only the summed or averaged trace of membrane potentials for cells belonging to a specific population label, instead of individual traces for each cell with that label. If I may, I would like to suggest considering this for future developments.

While I await the response regarding the Billeh et al. model, I would like to add a related comment and a question.

  1. [the comment to @kaeldai reply] Based on the "v1_node_models.json" (available at https://www.dropbox.com/sh/w5u31m3hq6u2x5m/AACkYaimuHqLpjBvaGpNfL0fa/simulations/v1_biophysical/build_files/biophys_props?dl=0&preview=v1_node_models.json&subfolder_nav_tracking=1), it appears that the model_type_id = 478110866 is associated with the i5Htr3a label. Therefore, I assume that the query referring to non-existent edges is the one related to node_type_id == 478110866 & pop_name == 'i6Htr3a'. Am I overlooking something?

  2. [the question] The somatic positions of cells along the depth axis are constrained between -50 and -850 micrometers, as evident from the network .csv and .h5 files. However, when I examined the "build_network.py" code, I didn't see how the somatic positions on the y-axis could be negative. In fact, when I ran the "generate_random_positions" function, the y-positions returned as positive. Is there something I am missing?

Thanks again to you all for your constant support.

Best regards,

Nicolò

@kaeldai
Copy link
Collaborator

kaeldai commented Jul 5, 2023

Hi @nicolomeneghetti

I think it should be possible to implement a way of taking the mean across subpopulations of voltage traces. It does sound like a good idea so I think we can go ahead and add it in an upcoming release.

  1. I think are correct in that 478110866 referring to the non-existiant edges - I must have confused the numbers when I was replying.
  2. The depth ranges for each cell-type is specified in biophys_props.json, and the build_network script is suppose to convert the values to negative - but you are correct it doesn't seem too anymore. We'll need to take a look at it in depth but I think there might be bug in the script.

I think the issue is that when the V1 model was being built, there were a lot of "hand-made" adjustments made directly to the network csv/hdf5 files that didn't get put back into the build_network.py script. Hence what the build_network.py script creates and what is in the network/ folder may not exactly match. I'll look into it and try to fix the build_network.py script. But the files that are in the network/ folder is the most optimized and tested version of the V1 model we have.

Thanks,
Kael

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants