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] Add warnings for invalid connections #419
[MRG] Add warnings for invalid connections #419
Conversation
Also @rythorpe adding these warnings makes the legacy mode drives API to fail. Specifically, hnn-core/hnn_core/cells_default.py Line 190 in 4fde7c6
Line 741 in 4fde7c6
Any thoughts on a workaround? |
hnn_core/network.py
Outdated
@@ -11,6 +11,7 @@ | |||
from copy import deepcopy | |||
|
|||
import numpy as np | |||
from numpy.testing._private.utils import raises |
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.
VSCode is getting too big for its britches, this was added automatically 😬
I'll remove it later.
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.
github autopilot? :)
Is the problem that legacy mode doesn't currently add an NMDA weight for a non-specified target cell type? If so, you could just copy and paste |
hnn_core/network.py
Outdated
valid_loc.extend(item) | ||
|
||
valid_loc = list(set(valid_loc)) | ||
# Separation ecessary to identify valid receptors |
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.
# Separation ecessary to identify valid receptors | |
# Separation necessary to identify valid receptors |
hnn_core/network.py
Outdated
valid_loc = list(set(valid_loc)) | ||
# Separation ecessary to identify valid receptors | ||
if loc in self.cell_types[target_type].sect_loc and \ | ||
self.cell_types[target_type].sect_loc[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.
can you be more explicit with the second condition? what exactly is it checking?
hnn_core/network.py
Outdated
conn['loc'] = loc | ||
|
||
valid_receptor = ['ampa', 'nmda', 'gabaa', 'gabab'] | ||
_check_option('receptor', receptor, valid_receptor) | ||
valid_receptors = set(np.concatenate([ |
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.
valid_receptors = set(np.concatenate([ | |
valid_receptors = set(sum([ |
does this work?
should some of the checks go to |
Is there a real use case? Otherwise, I'd suggest just documenting it better. E.g., by saying: "loc must be either in cell.sect_loc or 'soma'" Let's not open a can of worms if not necessary |
@ntolley this PR seems pretty easy to bring to MRG. Could be a nice one to tackle to get back into the groove? |
41f2e7b
to
82cf21c
Compare
82cf21c
to
9db8532
Compare
While it may have taken me some time to "get back into the grove" 😄 , it may be for the better that I came back to this with fresh eyes. @jasmainak @rythorpe I've implemented a fairly clean system to allow connections to be added through Since everything goes through Let me know what you think so far. If you like the idea of targeting specific sections with drives, I'll go ahead and remove the hard coded checks for proximal and distal. |
Can you have "proximal" or "distal" defined across cell types instead of just a group of sections in one cell? Will your code be able to handle that? @chenghuzi this a PR you might want to review :) |
Can you elaborate on what you are thinking? With the way the API for drives is designed, as well as the structure of the When you define a proximal/distal drive, the weights and delays for each cell need to be specified, so there's no way to avoid thinking in terms of the specific cells that compose the proximal/distal drive. |
Isn't it so that currently the distal drive doesn't target L5 basket cells? I suppose the logic for that would have to be outside |
Ah I understand now. So that logic is handled here: Line 41 in b66742d
and here: hnn-core/hnn_core/cells_default.py Line 339 in b66742d
I think I see why specifying proximal/distal at the cell level could be useful to break away these hard coded dependencies. Perhaps this is getting at @rythorpe's idea of a "constraints" file. Perhaps the larger issue is simply moving the hard-coded specifications from |
Maybe one could iterate over the cell types in |
9db8532
to
f34157b
Compare
Codecov Report
@@ Coverage Diff @@
## master #419 +/- ##
==========================================
+ Coverage 89.93% 90.03% +0.10%
==========================================
Files 20 20
Lines 3883 3893 +10
==========================================
+ Hits 3492 3505 +13
+ Misses 391 388 -3
Continue to review full report at Codecov.
|
b675784
to
1248e83
Compare
I like this a lot actually @ntolley. I'm definitely in favor of moving away from hardcoded definitions for "proximal" and "distal". These properties are and should be network-specific. Perhaps we could start (probably in a separate PR) by adding a new attribute to Network.connectivity_constraints = {
'exogenous_drive_targets': {
'proximal': ['L5_pyr_soma', 'L2_pyr_soma', 'L5_bask_soma', 'L5_bask_soma'],
'distal': [...]
},
'local_net_conn_restrictions': {
'L5_bask': ['L2_bask', 'L2_pyr'],
'L2_bask': [...],
...
} By default, |
hnn_core/network.py
Outdated
Target location of synapses. Must be an element of | ||
`Cell.sect_loc` such as 'proximal' or 'distal', which defines a | ||
group of sections, or an existing section such as 'soma' or | ||
'apical_tuft' (defined in `Cell.sections` for all targeted cells) |
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.
+1 for this. Eventually, it'd be nice to allow users to specify which cell sections apply to a given sect_loc
. I can imagine a few different network changes I'd like to implement for my own project where the location (i.e., 'proximal' or 'distal') isn't necessarily intuitive.
@@ -11,7 +11,8 @@ | |||
from .externals.mne import _validate_type | |||
|
|||
|
|||
def jones_2009_model(params=None, add_drives_from_params=False): | |||
def jones_2009_model(params=None, add_drives_from_params=False, | |||
legacy_mode=True): |
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.
why did you add this here? We need to set ourselves free of the legacy ...
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 promise it's actually towards that goal! legacy_mode=True
by default in the Network
. But the old interface for jones_2009_model()
didn't have the option to turn it on or off.
The reason I added it is because legacy_mode
needs to be False
to add a drive that targets a specific section. This is because legacy_mode=True
creates a connection for all cells, even if they aren't specified in the weights dict (they just have a weight of zero). Therefore if you try to target 'apical_trunk'
for example, it'll throw an error because it tries to create a connection to the basket cells when they don't have a section named 'apical_trunk'
.
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.
Would a good fix be to just make that clearer in the docstring?
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.
If you plan to deprecate it in the future, the default should be False
and it should raise a deprecation warning if someone sets it to True
.
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.
It sounds like the examples are secretly using legacy_mode=True
? I think the "right" thing to do is to start a separate PR that fixes this problem, then rebase this PR after that is merged.
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.
If we set default to False
here, then we'll need to explicitly set legacy_mode=True
for all of our examples + tests that use this network model in order to maintain consistency. Either that or we just rip the bandaid off and change the outcome of our examples + tests now.
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.
Btw, I noticed that the new GUI currently loads the "ghost" drives ... probably because of the implicit legacy_mode=True
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.
Ugh. Legacy mode is going to be the death of us.
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 that's exactly what's happening. Considering this change doesn't require changes to the current code, can we deal with legacy_mode
in a separate PR?
0a34276
to
e1007ce
Compare
Just rebased this PR. Everything is good on my end if you guys are happy with the changes! |
Thanks @ntolley ! 🥳 🥳 🥳 |
This PR adds checks inside
net.add_connection
to ensure the validloc
,receptor
,target_type
combinations are specified. Depending on the definition of the cell, certain combinations will break duringsimulate_dipole
. For example, pyramidal cells do not haveampa
synapses so if the user accidentally defines one withnet.add_connection
, then the simulation will break.While writing this I am realizing there are some issues with how things are organized internally. At the moment we support
proximal
,distal
, andsoma
as valid location arguments. However,soma
is handled a bit strangely since it is not defined in thesect_loc
attribute but still passes as a valid location because it has defined synapses:hnn-core/hnn_core/cells_default.py
Line 289 in 4fde7c6
This brings up an important question, should we allow targeting of locations with more precision? For example
loc='apical_1'
. It would be fairly easy to allow, and may make adding tonetwork_models.py
easier with that sort of flexibility.