AllenInstitute / AllenInstitute/bmtk

FilterNet: Changing the location of nondominant filter also changes the location of dominant filter in class "TwoSubfieldLinearCell" of "cellmodel.py" in bmtk

Open
#339 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
335
Forks
102
Avg merge
1d 5h
Merged PRs (30d)
6

Description

Overview

In function default_cell_loader() of "bmtk/simulator/filternet/default_setters/cell_loaders.py", variable linear_filter_son (line 121) and linear_filter_soff (line 124) take the same variable spatial_filter as input. This causes the two former variables to store the same spatial_filter object.

Then, linear_filter_son and linear_filter_soff are passed into the __init__() function of "bmtk/simulator/filternet/lgnmodel/cellmodel.py" as argument dominant_filterand nondominant_filter. However, in line 65-69 of this file:

self.dominant_filter.spatial_filter.translate = self.dominant_subfield_location
hor_offset = np.cos(self.onoff_axis_angle*np.pi/180.)*self.subfield_separation + self.dominant_subfield_location[0]
vert_offset = np.sin(self.onoff_axis_angle*np.pi/180.)*self.subfield_separation + self.dominant_subfield_location[1]
rel_translation = (hor_offset, vert_offset)
self.nondominant_filter.spatial_filter.translate = rel_translation

the intention is to set a different location for the nondominant_filter. But since self.dominant_filter.spatial_filter and self.nondominant_filter.spatial_filter is actually the same object, changing self.nondominant_filter.spatial_filter.translate will also change self.dominant_filter.spatial_filter.translate.

Therefore, when running the LGN filternet, the dominant and nondominant spatial filter will be placed at exactly the same location. This can be verified by checking the lnunit_cursor_list in class SeparableMultiLNUnitCursor of "bmtk/simulator/filternet/lgnmodel/cursor.py".

Steps to reproduce

  1. Download and extract the attachment (1 MB) in this issue. The files are selected from the source code of the mouse V1 model in Billeh et al., Neuron, 2020 (mostly unmodified).
  2. Set a breakpoint at line 69 of "bmtk/simulator/filternet/lgnmodel/cellmodel.py". This file runs when establishing the network.
  3. Run and debug "run_filternet.py", wait until it stops at the above breakpoint.
  4. Print self.dominant_filter.spatial_filter.translate, the result should be: (8.07545259102928, 10.021859654121696)
  5. Run line 69 of "bmtk/simulator/filternet/lgnmodel/cellmodel.py".
  6. Print self.dominant_filter.spatial_filter.translate and self.nondominant_filter.spatial_filter.translate, the outputs will both be (3.6379139789913113, 6.169332828582764). THIS IS THE BUG
  7. Print self.dominant_filter.spatial_filter.translate is self.nondominant_filter.spatial_filter.translate, the output will be True.
  8. Remove the breakpoint in line 69 of "bmtk/simulator/filternet/lgnmodel/cellmodel.py", set a new breakpoint in line 210 of "bmtk/simulator/filternet/lgnmodel/cursor.py". This file runs when actually simulating the network.
  9. Continue running the code until it stops at the new breakpoint (make take several minutes).
  10. Print self.lnunit_cursor_list[0].spatial_filter.translate, self.lnunit_cursor_list[1].spatial_filter.translate. The output is ((3.6379139789913113, 6.169332828582764), (3.6379139789913113, 6.169332828582764)).
  11. Print np.abs(self.lnunit_cursor_list[0].spatial_filter.get_kernel(np.arange(120), np.arange(240)).full()).argmax(), np.abs(self.lnunit_cursor_list[1].spatial_filter.get_kernel(np.arange(120), np.arange(240)).full()).argmax(). The output is (1444, 1444), which shows that the two spatial kernels peak at the same location.

Suggested fix

Use copy.deepcopy to isolate the two spatial_filter in function default_cell_loader() of "bmtk/simulator/filternet/default_setters/cell_loaders.py".

Attached code

attached_code.zip

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in bmtk/simulator/filternet/default_setters/cell_loaders.py at default_cell_loader(), then trace the filters into cellmodel.py and the lnunit_cursor_list in cursor.py. Reproduce the shared spatial_filter behavior with the supplied debugging steps; done means the dominant and nondominant filters retain distinct translations and their cursor kernels no longer peak at the same location.

Written by the indexing model from the issue text.

Assessment

Tech stack
numpy, python
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.