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
[MRG] refactoring of external feed class #108
Conversation
@jasmainak I'm going to work on adding the args and corresponding parameters to the |
yes go for it! Let me know when you're done |
Done for now! I still need to update the corresponding params but I'll need to save that for later. |
Great! Btw, do you know if the GUI has a provision for 'normal' vs 'uniform' distribution. I am a little puzzled to see it in the code but not in the GUI? |
You're right, I don't see the 'uniform' burst distribution referenced anywhere in the GUI or mentioned in the tutorials. I'm guessing this is due to lack of a use-case. Physiologically speaking, I can't think of a situation where a burst event would ever occur with sharp edges. Even a near-synchronous Poisson process wouldn't contain the edge effects present at the bounds of a uniform (i.e., rectangular) distribution. |
okay sounds good. I ask this because it means we don't have to expose an argument to the functions called |
@rythorpe I'm going to do a pass now. Do you have any commits to push? |
Go for it. I won’t be able to work on it until Monday probably. |
hnn_core/network.py
Outdated
@@ -124,9 +125,7 @@ def __init__(self, params, n_jobs=1): | |||
# Global number of external inputs ... automatic counting | |||
# makes more sense | |||
# p_unique represent ext inputs that are going to go to each cell | |||
self.p_common, self.p_unique = create_pext(self.params, | |||
self.params['tstop']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
most of what is in this function needs to go inside Rhythmic
and Evoked
for backwards compatibility. With the new objects, users should be able to either provide legacy params
to pre-populate these objects, or set them manually.
hnn_core/pyramidal.py
Outdated
def parreceive(self, gid, gid_dict, pos_dict, p_ext): | ||
for gid_src, p_src, pos in zip(gid_dict['common'], | ||
p_ext, pos_dict['common']): | ||
def parreceive(self, gids, pos_dict, feeds, threshold): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gid
was not used anywhere in the function and gid_dict
is very opaque. All it does is provide a range of gids
. This should be passed directly instead of passing the entire gid_dict
.
hnn_core/pyramidal.py
Outdated
|
||
Parameters | ||
---------- | ||
gids : dict |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops, should be a list
hnn_core/feed.py
Outdated
|
||
def set_times(self, tstart, tstop, tstart_dev, burst_freq=10, burst_std=20, | ||
burst_n_spikes=2, n_bursts=10, randomize_tstart=False, | ||
random_state1=None, random_state2=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simplified version of the existing function.
hnn_core/feed.py
Outdated
self.L2_Basket_ampa['g'] = g_basket_ampa | ||
self.L2_Basket_ampa['g'] = delay | ||
self.L2_Basket_ampa['lamtha'] = 100. | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pass |
@rythorpe I have to stop for today and I may not be able to get to this tomorrow. I left some comments. Hopefully it begins to make sense. What we're trying to do is:
|
hnn_core/feed.py
Outdated
burst_freq=params[f'f_input_{loc}'], | ||
burst_std=params[f'f_stdev_{loc}'], | ||
burst_n_spikes=params[f'events_per_cycle_{loc}'], | ||
n_bursts=params[f'repeats_{loc}']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thinking a bit more @rythorpe I think we should just focus on this method / function and do the other methods in another PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jasmainak so just use the new Evoked
and Rhythmic
classes to initialize and store feed attributes and let the Network
class handle setting connections for now?
hnn_core/network.py
Outdated
@@ -391,6 +392,9 @@ def _create_all_spike_sources(self): | |||
pc.cell(gid, self.cells[-1].connect_to_target( | |||
None, self.params['threshold'])) | |||
|
|||
for feed in self.feeds: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So our goal here is to set spike inputs in their own loop (i.e., separate from looping through self._gid_list
)? Why is this necessary?
Also, self.feeds
should be a list of both self.feeds_common
and self.unique_feeds
right?
@jasmainak Can I push something I've been working on? |
Go for it!
…On Mon, Jun 22, 2020 at 6:27 PM Ryan Thorpe ***@***.***> wrote:
@jasmainak <https://github.com/jasmainak> Can I push something I've been
working on?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#108 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ADY6FIX4PJCZXX5VB7GTILTRX7LE5ANCNFSM4OA7C2XA>
.
|
hnn_core/feed.py
Outdated
|
||
def set_times(self, tstart, tstop, tstart_dev, burst_freq=10, burst_std=20, | ||
burst_n_spikes=2, n_bursts=10, randomize_tstart=False, | ||
random_state1=None, random_state2=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure what you were attempting but I think we should keep this method as a function. Let's talk more tomorrow. Maybe I'm overlooking some challenge
hnn_core/network.py
Outdated
@@ -410,9 +410,18 @@ def _create_all_spike_sources(self): | |||
params=self.p_common[p_ind], | |||
gid=gid)) | |||
|
|||
# Convert event times into nrn vector |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be a function:
def artificial_cell(event_times):
# the code below
# should maybe go into cell.py
return nc
event_times = rhythmic_input_times(tstart, tstop, burst_freq, n_burst_spikes, ...)
nc = artificial_cell(event_times)
pc.cell(gid, nc)
hnn_core/network.py
Outdated
self.params['threshold'])) | ||
event_times = get_rhythmic_times(tstart=params['t0'], | ||
tstop=params['T'], | ||
...) # TODO: fill the rest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rythorpe I probably broke your code :) But I think I am getting a clearer and clearer picture now. I made a skeleton/sketch of what we want to accomplish in this PR. Please take a look and we'll discuss tomorrow. We really should explicitly pass parameters to make the code more transparent. If you get the idea already, feel free to pull the latest commit and continue on top of it. Let's catch up tomorrow in any case!
97da41d
to
fc60b7f
Compare
@jasmainak We should be clear to move forward with the PR now. At some point we should work on adding more tests for the |
hnn_core/network.py
Outdated
@@ -155,6 +156,9 @@ def __init__(self, params, n_jobs=1): | |||
self._gid_assign() | |||
# create cells (and create self.origin in create_cells_pyr()) | |||
self.cells = [] | |||
# list of artificial cells for storing external feed sources |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rather than this comment, I would prefer a more informative comment which explains why you need to create the list in the first place and how it needs to be a list so that the netcon doesn't deactivate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point!
hnn_core/cell.py
Outdated
Parameters | ||
---------- | ||
event_times : list | ||
Spike times associated with a given gid |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is the gid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The gid does not need to specified/known within the scope of this instance, however, I thought that the user should be aware that each ArtificialCell
instance is created for a specific gid in the Network
class.
hnn_core/feed.py
Outdated
@@ -5,7 +5,7 @@ | |||
# Christopher Bailey <bailey.cj@gmail.com> | |||
|
|||
import numpy as np | |||
from neuron import h | |||
# from .utils import check_random_state |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this PR was originally meant to clean up ExtFeed object. Do you still want to do this in the PR or should we delegate this to another PR? If we do this in another PR, let's delete the above line and the corresponding function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, let's delegate this to another PR.
@jasmainak I'm considering making the following changes:
Do these sound good to you? If so, do you have any commits to push before I work on this? |
@rythorpe that sounds like the right sequence of steps! |
hnn_core/network.py
Outdated
unique_feed = ExtFeed(feed_type=src_type, | ||
target_cell_type=target_cell_type, | ||
params=self.p_unique[src_type], | ||
gid=gid) | ||
self._artificial_cells.append( | ||
ArtificialCell(unique_feed.event_times, | ||
self.params['threshold'])) | ||
pc.cell(gid, self._artificial_cells[-1].nrn_netcon) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we rename _artificial_cells
to be _feed_cells
to make it clear that these cells relate to the external feed?
Now we have this incongruity that the class ExtFeed
does not really create a "feed" but just gives us event_times. I guess it will be fixed once we separate the class properly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, we can do that. So maybe the feed module will eventually contain a single function, callable by the Network
class, that creates instances of ExtFeed
and ArtificialCell
to be passed into pc.cell()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, but for command-line interface, I think we need to give user the ability to create feed objects outside of the Network
class and then the Network
class will simply create the _feed_cells
from these objects.
hnn_core/tests/test_feed.py
Outdated
assert ei.cell_type is None # artificial cell | ||
assert hasattr(ei, 'nrn_eventvec') | ||
assert hasattr(ei, 'nrn_vecstim') | ||
assert ei.nrn_eventvec.hname().startswith('Vector') | ||
assert hasattr(ei.nrn_vecstim, 'play') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rythorpe I think you can have these tests for the new object now?
@@ -14,6 +14,42 @@ | |||
# Units for gbar: S/cm^2 | |||
|
|||
|
|||
class _ArtificialCell: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need unit tests for the new object!
Otherwise LGTM. Let's try to merge this PR soonish so we can move on with life :) |
@jasmainak check out the test I added for the |
@@ -16,3 +17,16 @@ def test_dipole(): | |||
with Network(params) as net: | |||
net.build() | |||
net.cells[0].plot_voltage() | |||
|
|||
|
|||
def test_artificial_cell(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docstring is missing. It's displayed during test
@rythorpe please set the PR to [MRG] once it's good to go for you |
Codecov Report
@@ Coverage Diff @@
## master #108 +/- ##
==========================================
+ Coverage 89.92% 90.08% +0.15%
==========================================
Files 17 17
Lines 1708 1704 -4
==========================================
- Hits 1536 1535 -1
+ Misses 172 169 -3
Continue to review full report at Codecov.
|
Just for reference, what does MRG stand for? |
[MRG] = merge these are two common titles used for PRs :) In the days when github didn't have the approve button folks would also do [MRG +1] and [MRG +2] and then merge the PR once it's [MRG +2] |
whatever happened to Travis CI? |
@blakecaldwell should we wait for your PR #79 to be merged first before merging this to avoid rebase mess? What do you think? One of the PRs has to do the rebase ... not sure which one is easier |
Thanks for checking. Yeah, that would be nice to push #79 first. After these two, we will have a good handle on the |
@rythorpe we will need to rebase this PR now. Up for the challenge? ;-) |
I need to spend some time wrapping my head around the new structure, so yeah, I'll give it a shot! |
add space create methods for Evoked and Rhythmic classes Expanding more params Network class handles nrn feed objects Try artificial cell move to feed blah create ArtificialCell class for initializing external feed sources add docstring and clean code fix test_feed.py fix docstrings and comments in ArtificialCell and Network classes remove check_random_state() from utils module remove feed list attributes in Network class make artificial cell class private add unit test for _ArtificialCell class remove useless return statements from '_create_feed' functions Update hnn_core/feed.py comment Co-authored-by: Mainak Jas <jasmainak@users.noreply.github.com> update docstrings in feed tests
@rythorpe I did a rebase after squash. Can you check if this was done correctly? If not, can you push fixes? |
Thanks for the rebase @jasmainak! Aside from the TravisCI issue on the MacOS build job, all tests now pass. I'm ready to move forward whenever you and Travis are. |
okay let's move on. The MacOS build needs to be fixed separately. We should probably pin the NEURON version for now. thanks a lot for the effort @rythorpe ! |
No description provided.