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

NeuroMLDBModel current amplitudes that are multiple of rheobase #222

Open
rgerkin opened this issue Jul 1, 2019 · 7 comments
Open

NeuroMLDBModel current amplitudes that are multiple of rheobase #222

rgerkin opened this issue Jul 1, 2019 · 7 comments
Assignees
Labels
Milestone

Comments

@rgerkin
Copy link
Contributor

rgerkin commented Jul 1, 2019

@JustasB
The code for loading waveforms by current amplitude has the following problem:

import quantities as pq
from neuronunit.neuromldb import NeuroMLDBModel
model = NeuroMLDBModel(model_id='NMLCL000086')
model.fetch_waveform_list();
model.get_waveform_by_current(100*pq.pA)

leads to:

    136     def get_waveform_current_amplitude(self, waveform):
--> 137         return float(waveform["Waveform_Label"].replace(" nA", "")) * pq.nA
    138 
    139 

ValueError: could not convert string to float: '0.75xRB'

Currents that are expressed as a multiple of rheobase will need their own handling. Is the rheobase stored somewhere in the class or elsewhere in the database? If so, I can add a conversion from "NUMxRB" to the true value.

@rgerkin rgerkin added the bug label Jul 1, 2019
@rgerkin rgerkin modified the milestones: 0.3 release, 0.2 release Jul 1, 2019
@russelljjarvis
Copy link
Contributor

@rgerkin

I think you are using the wrong type of waveform/protocol combination.

If you use the logic below you can query the NML-DB server to get appropriate waveforms that are amenable to

def get_waveform_current_amplitude(waveform):
    long_squares = [ w for w in wlist if w['Protocol_ID'] == 'LONG_SQUARE' ]

    #variable_names = [  w["Variable_Name"] for w in wlist if w["Protocol_ID"] == "LONG_SQUARE" ]
    applied_current_injections = [ w for w in wlist if w["Protocol_ID"] == "LONG_SQUARE" and w["Variable_Name"] == "Current" ]

    #import pdb; pdb.set_trace()
    currents = [ w for w in wlist if w["Protocol_ID"] == "LONG_SQUARE" and w["Variable_Name"] == "Voltage" ]

    in_current_filter = [ w for w in wlist if w["Protocol_ID"] == "SQUARE" and w["Variable_Name"] == "Voltage" ]
    rheobases = []
    for wl in long_squares:
        wid = wl['ID']
        url = str("https://neuroml-db.org/api/waveform?id=")+str(wid)
        waves = requests.get(url)
        temp = json.loads(waves.text)
        if temp['Spikes'] >= 1:
            rheobases.append(temp)
    if len(rheobases) == 0:
        return None

    in_current = []
    for check in in_current_filter:
        amp = get_waveform_current_amplitude(check)
        if amp < 0 * pq.nA:
            in_current.append(amp)
    rheobase_current = get_waveform_current_amplitude(rheobases[0])
    druckmann2013_standard_current = get_waveform_current_amplitude(currents[-2])
druckmann2013_strong_current = get_waveform_current_amplitude(currents[-1])

https://github.com/russelljjarvis/neuronunit/blob/barcelona/get_allen_features_from_nml_db.py#L153-L169

@rgerkin
Copy link
Contributor Author

rgerkin commented Jul 2, 2019

@russelljjarvis Justas had pointed me specifically to get_waveform_by_current so I was trying to produce a minimal example using that method.

@russelljjarvis
Copy link
Contributor

The code I am proposing uses get_waveform_by_current under the hood too.

@rgerkin
Copy link
Contributor Author

rgerkin commented Jul 2, 2019

@russelljjarvis It does? I see that get_waveform_by_current calls get_waveform_current_amplitude but not the other way around. Is there somewhere else in your code where something that calls get_waveform_by_current is used?

@russelljjarvis
Copy link
Contributor

russelljjarvis commented Jul 2, 2019

Sorry no, you are right, I used to call those methods indirectly with the three lines below but then I realized that they would re-download waveforms every time a waveform was needed which would slow down the batch process I was designing. Therefore I get the waveforms myself once using code that is very similar, but then I hard assign those waveforms to the model.

The functionality is there by I bypassed it, because I needed it to work with a different pre-existing code for querying the NML-DB waveforms.

get_waveform_by_current is more like a private method that only works under particular circumstances. Its better if the object calls this method itself, by calling these three methods from the object:

self.standard = self.model.nmldb_model.get_druckmann2013_standard_current()
self.strong = self.model.nmldb_model.get_druckmann2013_strong_current()
self.ir_currents = self.model.nmldb_model.get_druckmann2013_input_resistance_currents()

These lines https://github.com/russelljjarvis/AllenDruckmannData/blob/master/dm_test_interoperable.py#L126-#L128

The code below is acting on a neuroml-db static backend model. Since I am supplying a pre-made model, and models type is not None.

        if type(model) is type(None):
            self.model = model_dict[model_id]
            self.model_id = model_id
            if self.model_id not in self.predicted:
                self.predicted[self.model_id] = [None for i in range(38)] # There are 38 tests
            self.standard = self.model.nmldb_model.get_druckmann2013_standard_current()
            self.strong = self.model.nmldb_model.get_druckmann2013_strong_current()
            self.ir_currents = self.model.nmldb_model.get_druckmann2013_input_resistance_currents()

        else:
            self.model = model
            self.standard = model.druckmann2013_standard_current
            self.strong = model.druckmann2013_strong_current
            self.ir_currents = model.druckmann2013_input_resistance_currents

https://github.com/russelljjarvis/AllenEFELDruckmanData/blob/master/neuromldb.py#L109

What I should have said instead is if these lines of code are executed instead:

            self.standard = self.model.nmldb_model.get_druckmann2013_standard_current()
            self.strong = self.model.nmldb_model.get_druckmann2013_strong_current()
            self.ir_currents = self.model.nmldb_model.get_druckmann2013_input_resistance_currents()

They properly set up the neuroml-db static model class in a way, that makes it able to call get_waveform_by_current itself without syntactic errors.

It's a bit complicated to understand, but when I call get_waveform_by_current. I am still adding currents to the models lookup table, because the last thing that happens is that method is this call:

 return self.fetch_waveform_as_AnalogSignal(w["ID"])

@russelljjarvis
Copy link
Contributor

https://github.com/russelljjarvis/AllenEFELDruckmanData/blob/master/get_allen_features_from_nml_db.py#L441-L446

    def not_necessary_for_program_completion(DMTNMLO):
        current = DMTNMLO.model.nmldb_model.get_druckmann2013_standard_current()
        DMTNMLO.model.nmldb_model.get_waveform_by_current(current)
        temp0 = np.mean(DMTNMLO.model.nmldb_model.get_waveform_by_current(DMTNMLO.model.nmldb_model.get_druckmann2013_strong_current()))
        temp1 = np.mean(DMTNMLO.model.nmldb_model.get_waveform_by_current(DMTNMLO.model.nmldb_model.get_druckmann2013_standard_current()))
        assert temp0 != temp1
        return
    _ = not_necessary_for_program_completion(DMTNMLO)    

This code works as an example.

@JustasB
Copy link
Collaborator

JustasB commented Jul 2, 2019

It looks like I really need to add more documentation on the API. I'll work on that when I find spare moments.

For the question:

Is the rheobase stored somewhere in the class or elsewhere in the database?

In this line:

data = self.read_api_url(self.api_url + "model?id=" + str(self.model_id))

the data variable will contain the contents of the model API call results e.g.
https://neuroml-db.org/api/model?id=NMLCL001129

For cell models, that data variable will have a Rheobase_High key, which stores the value of the rheobase current.

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

No branches or pull requests

3 participants