From 3b07c06ef9a299af8a1ec2dd9c1ce9214e340639 Mon Sep 17 00:00:00 2001 From: Shinya Ito Date: Wed, 8 Nov 2023 13:05:29 -0800 Subject: [PATCH] Fixing FilterNet bug (ON/OFF offset, issue #339) (#340) Before the fix, spatial filters for ON and OFF receptive fields were pointing to the same object. Resolved by creating filter objects separately. --- .../filternet/default_setters/cell_loaders.py | 15 +++++++++------ .../simulator/filternet/test_default_setters.py | 6 ++++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/bmtk/simulator/filternet/default_setters/cell_loaders.py b/bmtk/simulator/filternet/default_setters/cell_loaders.py index b1c56131c..171eed790 100644 --- a/bmtk/simulator/filternet/default_setters/cell_loaders.py +++ b/bmtk/simulator/filternet/default_setters/cell_loaders.py @@ -96,8 +96,6 @@ def default_cell_loader(node, template_name, dynamics_params): else: rotation = 0.0 - spatial_filter = GaussianSpatialFilter(translate=translate, sigma=sigma, origin=origin, rotation=rotation) - t_weights, t_kpeaks, t_delays = get_tf_params(node, dynamics_params) if template_name: @@ -118,10 +116,12 @@ def default_cell_loader(node, template_name, dynamics_params): amp_off = -(max_roff/max_ron)*(sON_sum/sOFF_sum)*amp_on - (spont*(max_roff - max_ron))/(max_ron*sOFF_sum) # Create sON subunit: - linear_filter_son = SpatioTemporalFilter(spatial_filter, sON_filt_new, amplitude=amp_on) + spatial_filter_on = GaussianSpatialFilter(translate=translate, sigma=sigma, origin=origin, rotation=rotation) + linear_filter_son = SpatioTemporalFilter(spatial_filter_on, sON_filt_new, amplitude=amp_on) # Create sOFF subunit: - linear_filter_soff = SpatioTemporalFilter(spatial_filter, sOFF_filt_new, amplitude=amp_off) + spatial_filter_off = GaussianSpatialFilter(translate=translate, sigma=sigma, origin=origin, rotation=rotation) + linear_filter_soff = SpatioTemporalFilter(spatial_filter_off, sOFF_filt_new, amplitude=amp_off) sf_sep = node.sf_sep if node.predefined_jitter: @@ -144,10 +144,12 @@ def default_cell_loader(node, template_name, dynamics_params): amp_off = -0.7*(max_roff/max_ron)*(sON_sum/tOFF_sum)*amp_on - (spont*(max_roff - max_ron))/(max_ron*tOFF_sum) # Create sON subunit: - linear_filter_son = SpatioTemporalFilter(spatial_filter, sON_filt_new, amplitude=amp_on) + spatial_filter_on = GaussianSpatialFilter(translate=translate, sigma=sigma, origin=origin, rotation=rotation) + linear_filter_son = SpatioTemporalFilter(spatial_filter_on, sON_filt_new, amplitude=amp_on) # Create tOFF subunit: - linear_filter_toff = SpatioTemporalFilter(spatial_filter, tOFF_filt_new, amplitude=amp_off) + spatial_filter_off = GaussianSpatialFilter(translate=translate, sigma=sigma, origin=origin, rotation=rotation) + linear_filter_toff = SpatioTemporalFilter(spatial_filter_off, tOFF_filt_new, amplitude=amp_off) sf_sep = node.sf_sep if node.predefined_jitter: @@ -193,6 +195,7 @@ def default_cell_loader(node, template_name, dynamics_params): transfer_function = ScalarTransferFunction('Heaviside(s+{})*(s+{})'.format(spont_fr, spont_fr)) temporal_filter = TemporalFilterCosineBump(t_weights, t_kpeaks, t_delays) + spatial_filter = GaussianSpatialFilter(translate=translate, sigma=sigma, origin=origin, rotation=rotation) if cell_type.find('ON') >= 0: amplitude = 1.0 linear_filter = SpatioTemporalFilter(spatial_filter, temporal_filter, amplitude=amplitude) diff --git a/bmtk/tests/simulator/filternet/test_default_setters.py b/bmtk/tests/simulator/filternet/test_default_setters.py index ec8f1964e..ac29f013d 100644 --- a/bmtk/tests/simulator/filternet/test_default_setters.py +++ b/bmtk/tests/simulator/filternet/test_default_setters.py @@ -109,7 +109,8 @@ def test_offunit(cell_type, expected_val): @pytest.mark.parametrize("cell_type,expected_val", [ - ('sONsOFF_001', [4.0, 3.5654, 2.2956, 2.7437, 4.4480]) + # ('sONsOFF_001', [4.0, 3.5654, 2.2956, 2.7437, 4.4480]) + ('sONsOFF_001', [4.0, 3.0136, 3.335, 4.3349, 4.9999]) # updated value after OS bug fix. (issue, #339) ]) def test_sONsOFF(cell_type, expected_val): gm = movie.GratingMovie(row_size=120, col_size=240, frame_rate=24.0) @@ -128,7 +129,8 @@ def test_sONsOFF(cell_type, expected_val): @pytest.mark.parametrize("cell_type,expected_val", [ - ('sONsOFF_001', [4.0, 3.5654, 2.2957, 2.7437, 4.4481]) + # ('sONsOFF_001', [4.0, 3.5654, 2.2957, 2.7437, 4.4481]) + ('sONsOFF_001', [4.0, 3.0136, 3.335, 4.3349, 4.9999]) # updated value after OS bug fix. (issue, #339) ]) def test_sONtOFF(cell_type, expected_val): gm = movie.GratingMovie(row_size=120, col_size=240, frame_rate=24.0)