-
Notifications
You must be signed in to change notification settings - Fork 53
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
[ENH] Fixed bug in clear_connectivity and improved tests for deleting drives #613
base: master
Are you sure you want to change the base?
Conversation
hnn_core/network.py
Outdated
""" | ||
connectivity = list() | ||
def clear_connectivity(self, src_types=None): | ||
"""Remove connections with src_type in Network.connectivity.""" |
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 document src_types
?
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.
also is clear_connectivity
tested?
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 will add the documentation for src_types.
Yes it is tested in all three tests. First test checks the base conditions where no arguments are passed. Here it successfully deletes all cell connections apart from those originating from external drives
The other two tests it tests for deletion of connections from specific source types.
hnn_core/network.py
Outdated
del self.external_drives[drive_name] | ||
self.clear_connectivity(src_types=drive_names) | ||
|
||
def get_external_drive_names(self): |
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.
How about?
def get_external_drive_names(self): | |
@property | |
def drive_names(self): |
It feels more Pythonic.
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 will make this change
Codecov Report
📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more @@ Coverage Diff @@
## master #613 +/- ##
==========================================
- Coverage 92.15% 91.87% -0.28%
==========================================
Files 22 22
Lines 4219 4333 +114
==========================================
+ Hits 3888 3981 +93
- Misses 331 352 +21
|
@jasmainak Is the short description for src_types enough or should I elaborate it more? |
hnn_core/network.py
Outdated
The drive_names to remove | ||
""" | ||
if drive_names == 'all': | ||
drive_names = list(self.external_drives.keys()) |
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.
drive_names = list(self.external_drives.keys()) | |
drive_names = self.drive_names |
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 will do
examples/howto/plot_connectivity.py
Outdated
@@ -71,7 +71,7 @@ | |||
# directly. | |||
def get_network(probability=1.0): | |||
net = jones_2009_model(add_drives_from_params=True) | |||
net.clear_connectivity() | |||
net.connectivity = list() |
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.
undo this since you have clear_connectivity
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.
Sure will do
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.
Here net.connectivity needs to be completely cleared.
So both clear_connectivity() and clear_drives() will need to be called one by one.
- clear_connectivity() will leave connections of external drives open. For deleting them clear_drives will need to be called.
- But if there are existing external drive connections only clear_connectivity needs to be called....
Which direction is better?
hnn_core/tests/test_network.py
Outdated
net.clear_drives() | ||
assert len(net.connectivity) == 0 | ||
assert len(net.connectivity) == 0 # All connections are deleted |
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.
clear_drives
should still leave the connections within the cortical column ... were there no connections within the cell populations?
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.
Earlier clear_connectivity() was called which deleted all connections other than the ones involving external drives. That was pushed by the previous pull request i think, the one I got merge conflict with so I kept that change
I'm guessing you merged master with your |
Yes I merged master in clear_drive because of which I got external commits |
you almost never want to do a merge or pull (fetch + merge) when working on public repos. Just fetch the latest master and rebase: $ git fetch upstream master:master
$ git rebase master |
Yes will remember this in future. Thanks!! |
Hey @rythorpe @jasmainak what changes need to be made in this? |
hnn_core/network.py
Outdated
src_types : list | None | ||
Source types of connections to be removed | ||
None - Remove all connections other than those which have an | ||
external drive as a source type |
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.
@raj1701 I think you have been struggling with the logic because you are trying to preserve the old behavior and logic without fully understanding the purpose of that behavior. You need to clarify the behavior before writing the logic. To me, what makes the most sense is:
net.clear_connectivity() # clear all connections
net.clear_connectivity(src_types='drives') # clear connections from drives to cells
net.clear_connectivity(src_types='local') # clear connections within cells
net.clear_connectivity(src_types=['L2_Pyramidal', 'L5_basket']) # clear connection starting with cell populations L2_pyramidal and L5_basket
To do this, you should use pick_connection and avoid rewriting the logic of finding the appropriate connections. Once you have the indices of the connections, you can write a simple for loop to delete the items:
for conn_idx in conn_idxs:
del net.connectivity[conn_idx]
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.
Yes @jasmainak I was trying to preserve the old logic. If no argument is passed to clear_connectivity
then the default value of src_types should be called "All" instead of "None". Will refactor the code accordingly and make the required changes.
Hey @jasmainak I redesigned the code. It passed all the tests in my local system but here the tests are failing for a file I didn't even change... |
Looks like an MPI error... I'm going to rerun the tests because sometimes running |
hnn_core/network.py
Outdated
src_types = list() | ||
for conn in self.connectivity: | ||
if conn['src_type'] not in src_types: | ||
src_types.append(conn['src_type']) |
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 seems pretty convoluted ... could you use self.gid_ranges.keys()
?
hnn_core/network.py
Outdated
src_types = list() | ||
external_drives = self.drive_names | ||
for conn in self.connectivity: | ||
if (conn['src_type'] not in src_types and | ||
conn['src_type'] not in external_drives): | ||
src_types.append(conn['src_type']) |
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.
same here ... I think you just need to do a list comprehension to leave out the external drives from all the cell populations
hnn_core/tests/test_network.py
Outdated
|
||
Parameters | ||
---------- | ||
net - The network instance |
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 follow the numpy docstring conventions: https://numpydoc.readthedocs.io/en/latest/format.html#parameters
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.
Hey @jasmainak I have simplified the loops and followed the numpy docstring conventions
hnn_core/network.py
Outdated
src_types = list() | ||
for src_type in self.gid_ranges.keys(): | ||
src_types.append(src_type) |
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.
src_types = list() | |
for src_type in self.gid_ranges.keys(): | |
src_types.append(src_type) | |
src_types = list(self.gid_ranges.keys()) |
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 constructor of list
can take an iterable
hnn_core/network.py
Outdated
src_types = list() | ||
all_src_types = self.gid_ranges.keys() | ||
local_src_types = all_src_types - self.drive_names | ||
for src_type in local_src_types: | ||
src_types.append(src_type) |
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.
src_types = list() | |
all_src_types = self.gid_ranges.keys() | |
local_src_types = all_src_types - self.drive_names | |
for src_type in local_src_types: | |
src_types.append(src_type) | |
src_types = [src_type for src_type in list(self.gid_ranges.keys()) if src_type not in self.drive_names] |
hnn_core/network.py
Outdated
|
||
Parameters | ||
---------- | ||
src_types : list | all | drives | local |
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.
src_types : list | all | drives | local | |
src_types : list | 'all' | 'drives' | 'local' |
to be clear that these are strings ... also fix below
@jasmainak I made these changes. Sorry for the extra commit. I pushed by mistake before changing one thing. |
Hey @jasmainak can you suggest any changes required for this PR? |
hnn_core/network.py
Outdated
'drives' - Clear connections originating from external drives | ||
'local' - Clear connections within 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.
'drives' - Clear connections originating from external drives | |
'local' - Clear connections within cells | |
'drives' - Clear connections from the external drives to the local network | |
'local' - Clear connections between cells of the local network |
How about 'external'
or 'exogenous'
instead of 'drives'
, and 'internal'
or 'endogenous'
instead of 'local'
? I've gotten the impression our documentation is already a little hazy on how we delineate between these two distinct categories of connections.
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 will rename instances of drives
as exogenous
and instances of local
as endogenous
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 @ntolley wdyt?
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 like 'external' and 'internal' ... very explicit, clear and I prefer it over exogenous/endogenous which is a bit too academic.
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.
That's fair!
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 will rename accordingly
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.
Looks like I never posted the comments from my review ... here goes
hnn_core/network.py
Outdated
'drives' - Clear connections originating from external drives | ||
'local' - Clear connections within 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.
I like 'external' and 'internal' ... very explicit, clear and I prefer it over exogenous/endogenous which is a bit too academic.
hnn_core/tests/test_network.py
Outdated
@@ -510,6 +510,30 @@ def test_network_drives_legacy(): | |||
n_bursty_sources) | |||
|
|||
|
|||
def get_expected_connectivities(net, src_types='all'): |
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.
just make this a private function ... it's not user facing
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 will do
hnn_core/network.py
Outdated
@@ -1253,23 +1253,77 @@ def add_connection(self, src_gids, target_gids, loc, receptor, | |||
|
|||
self.connectivity.append(deepcopy(conn)) | |||
|
|||
def clear_connectivity(self): | |||
"""Remove all connections defined in Network.connectivity | |||
def _get_expected_connectivities(self, src_types='all'): |
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.
Since this is solely for testing purposes, should this function be moved to test_network.py
?
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 wanted this function as private because it was not user facing, that is why I shifted it here. But yes it is used only for testing purposes, if required I can move it to test_network.py
. @jasmainak @rythorpe wdyt?
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.
yes, let's move this to test_network.py
hnn_core/network.py
Outdated
def clear_connectivity(self): | ||
"""Remove all connections defined in Network.connectivity | ||
def _get_expected_connectivities(self, src_types='all'): | ||
"""Return expected connectivities left after clearng connections. |
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.
"""Return expected connectivities left after clearng connections. | |
"""Return expected connectivities left after clearing connections. |
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
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 looks like there are two ways to modify drive connectivity: net.clear_connectivity(src_types='internal')
and net.clear_drives(drive_names='all')
. The first method, however, doesn't clear net.external_drives
, which could be misleading to users. I'm not sure why we need two different ways to clear drive connections, so my recommendation would be to consolidate.
Zen of Python: There should be one-- and preferably only one --obvious way to do it.
Just to clarify, I understand the utility of having Alternatively, you could just separate the functionality of the two existing functions s.t. one takes care of drives + external connectivity while the other takes care of internal connectivity. Apologies if this contradicts some of your previous conversations @raj1701 and @jasmainak - LMK if you disagree. |
Can we have a private function |
hnn_core/network.py
Outdated
self.external_drives = dict() | ||
self.connectivity = connectivity | ||
if src_types == 'all': | ||
return 0 |
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.
instead of hard coding this, it might be better to do:
return 0 | |
src_types = self.gid_ranges().keys() |
or something similar (please check what it should be).
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.
Just to clarify, I understand the utility of having
net.clear_drives
callnet.clear_connectivity
: the first is clearsnet.external_drives
and then outsources clearing the drive connectivity to the second. My only issue is that we should encourage users to only usenet.clear_drives
when touching drive connectivity. The simplest solution would be to makeclear_connectivity
private, and then make a public wrapper method with the same name that users can call to clear internal network connectivity but doesn't give them access to external drive connectivity.
Alternatively, you could just separate the functionality of the two existing functions s.t. one takes care of drives + external connectivity while the other takes care of internal connectivity.
Apologies if this contradicts some of your previous conversations @raj1701 and @jasmainak - LMK if you disagree.Can we have a private function
_clear_connectivity()
to clear connections. A functionclear_internal_connectivity()
for deleting internal connections with a check to make sure the inputsrc_types
do not have an external drive and then just call the private method to clear connections(internal)? Similarlyclear_drives()
can have a check to ensuresrc_types
only has drive names.
This line of code may not be required if the above behavior is used.
hnn_core/network.py
Outdated
src_gids=src_type)) | ||
return len(self.connectivity) - deleted_connectivities | ||
|
||
def clear_connectivity(self, src_types="all"): |
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 is a bit of a nitpick. But for stylistic consistency, I suggest using single quotes everywhere unless you need to escape certain characters. You can also check what the PEP 8 document says.
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.
https://peps.python.org/pep-0008/#string-quotes
Ok, it makes no recommendation but I personally prefer single quotes :)
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 will use single quotes
def clear_connectivity(self, src_types='all'): | ||
"""Clear connections between cells of the local network |
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 is this what you intended? A "dangling" cell population will be problematic even with local network connectivity ... I'm wondering if we should make clear_connectivity
private altogether until it has clarified in our minds how to do it right
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.
Yep! I don't see how this could be problematic. If you think we should prevent users from selectively removing local network connections, perhaps we can just get rid of the src_types
arg and make this function clear all local network connections (which I guess is more consistent with the name of this method anyway).
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.
but clear_drives
needs the src_types
argument ...
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.
but
clear_drives
needs thesrc_types
argument ...
why?
connectivity.append(conn) | ||
self.external_drives = dict() | ||
self.connectivity = connectivity | ||
_validate_type(src_types, list, 'src_types', 'list, drives, local') |
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.
Does this need to be updated? I think it should say something like this for the last arg: 'list of drive names or local network connections'
.
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 we can remove this check as types are already validated in the public functions - clear_connectivity()
and clear_drives()
. Should I remove this check or update it?
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, go ahead and remove it!
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 will do
Closes #549
Fixed all bugs in clear_drives and clear_connectivity functions
Wrote tests for the following