Skip to content

Commit

Permalink
ENH: Added feature to load single .csv files from the gui
Browse files Browse the repository at this point in the history
STY: Fixed edge case on dropdown width. Fixed flake8 errors

MAINT: Moving save simulation button initialization logic to a private funciton. Adding upload csv file test

DOC: Added entry in whats_new.rst

DOC: Update doc/whats_new.rst

Co-authored-by: George Dang <53052793+gtdang@users.noreply.github.com>

TEST: Fixed  csv file upload test on windows

MAINT: Removed commented code

STY: Fixed docustring of the  public funciton serialize_simulation

STY: Applied changes in docustirng of serialize_simulation

TST: Added new test cases on test_gui_upload_csv_simulation. Fixed flake8 errors
  • Loading branch information
kmilo9999 authored and ntolley committed May 8, 2024
1 parent abd6ee4 commit 5e04b17
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 50 deletions.
3 changes: 3 additions & 0 deletions doc/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ Changelog
- Added gui widget to enable/disable synchronous input in simulations,
by `Camilo Diaz`_ in :gh:`750`

- Added gui widgets to save simulation as csv and updated the file upload to support csv data,
by `Camilo Diaz`_ in :gh:`753`

Bug
~~~
- Fix inconsistent connection mapping from drive gids to cell gids, by
Expand Down
2 changes: 1 addition & 1 deletion hnn_core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .dipole import simulate_dipole, read_dipole, average_dipoles, Dipole
from .dipole import simulate_dipole, read_dipole, average_dipoles, Dipole,_read_dipole_txt
from .params import Params, read_params, convert_to_hdf5
from .network import Network, pick_connection
from .network_models import jones_2009_model, law_2021_model, calcium_model
Expand Down
19 changes: 10 additions & 9 deletions hnn_core/dipole.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,20 +106,25 @@ def simulate_dipole(net, tstop, dt=0.025, n_trials=None, record_vsec=False,
return dpls


def _read_dipole_txt(fname):
def _read_dipole_txt(fname, extension='.txt'):
"""Read dipole values from a txt file and create a Dipole instance.
Parameters
----------
fname : str
Full path to the input file (.txt)
fname : str or io.StringIO
Full path to the input file (.txt or .csv) or
Content of file in memory as a StringIO
Returns
-------
dpl : Dipole
The instance of Dipole class
"""
dpl_data = np.loadtxt(fname, dtype=float)
if extension == '.csv':
# read from a csv file ignoring the headers
dpl_data = np.genfromtxt(fname, delimiter=',',
skip_header=1, dtype=float)
else:
dpl_data = np.loadtxt(fname, dtype=float)
ncols = dpl_data.shape[1]
if ncols not in (2, 4):
raise ValueError(
Expand Down Expand Up @@ -174,10 +179,6 @@ def read_dipole(fname):
The instance of Dipole class
"""

# For supporting tests in test_gui.py
if isinstance(fname, StringIO):
return _read_dipole_txt(fname)

fname = str(fname)
if not os.path.exists(fname):
raise FileNotFoundError('File not found at path %s.' % (fname,))
Expand Down
75 changes: 35 additions & 40 deletions hnn_core/gui/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,35 +234,18 @@ def __init__(self, theme_color="#8A2BE2",
description='Cores:',
disabled=False)
self.load_data_button = FileUpload(
accept='.txt', multiple=False,
accept='.txt,.csv', multiple=False,
style={'button_color': self.layout['theme_color']},
description='Load data',
button_style='success')

b64 = base64.b64encode("".encode())
payload = b64.decode()
# Initialliting HTML code for download button
self.html_download_button = '''
<a download="{filename}" href="data:text/csv;base64,{payload}"
download>
<button style="background:{color_theme}; height:{btn_height}"
class=" jupyter-button
mod-warning" {is_disabled} >Save Simulation</button>
</a>
'''
# Create widget wrapper
self.save_simuation_button = (
HTML(self.html_download_button.
format(payload=payload,
filename={""},
is_disabled="disabled",
btn_height=self.layout['run_btn'].height,
color_theme=self.layout['theme_color'])))
# Create save simulation widget wrapper
self.save_simuation_button = self._init_html_download_button()

self.simulation_list_widget = Dropdown(options=[],
value=None,
description='',
layout={'width': 'max-content'})
layout={'width': '15%'})
# Drive selection
self.widget_drive_type_selection = RadioButtons(
options=['Evoked', 'Poisson', 'Rhythmic'],
Expand Down Expand Up @@ -315,6 +298,27 @@ def __init__(self, theme_color="#8A2BE2",
self._init_ui_components()
self.add_logging_window_logger()

def _init_html_download_button(self):
b64 = base64.b64encode("".encode())
payload = b64.decode()
# Initialliting HTML code for download button
self.html_download_button = '''
<a download="{filename}" href="data:text/csv;base64,{payload}"
download>
<button style="background:{color_theme}; height:{btn_height}"
class=" jupyter-button
mod-warning" {is_disabled} >Save Simulation</button>
</a>
'''
# Create widget wrapper
return (
HTML(self.html_download_button.
format(payload=payload,
filename={""},
is_disabled="disabled",
btn_height=self.layout['run_btn'].height,
color_theme=self.layout['theme_color'])))

def add_logging_window_logger(self):
handler = _OutputWidgetHandler(self._log_out)
handler.setFormatter(
Expand Down Expand Up @@ -1211,7 +1215,10 @@ def on_upload_data_change(change, data, viz_manager, log_out):

data_dict = change['new'][0]

data_fname = data_dict['name'].rstrip('.txt')
dict_name = data_dict['name'].rsplit('.', 1)
data_fname = dict_name[0]
file_extension = f".{dict_name[1]}"

if data_fname in data['simulation_data'].keys():
logger.error(f"Found existing data: {data_fname}.")
return
Expand All @@ -1220,7 +1227,7 @@ def on_upload_data_change(change, data, viz_manager, log_out):
ext_content = codecs.decode(ext_content, encoding="utf-8")
with log_out:
data['simulation_data'][data_fname] = {'net': None, 'dpls': [
hnn_core.read_dipole(io.StringIO(ext_content))
hnn_core._read_dipole_txt(io.StringIO(ext_content), file_extension)
]}
logger.info(f'External data {data_fname} loaded.')
_template_name = "[Blank] single figure"
Expand Down Expand Up @@ -1444,23 +1451,11 @@ def _serialize_simulation(log_out, sim_data, simulation_list_widget):


def serialize_simulation(simulations_data, simulation_name):
"""
Serializes the simulation data for a given simulation name
into either a single CSV file
or a ZIP file containing multiple CSVs, depending on the number
of trials in the simulation.
Parameters:
- simulation_name (str): The name of the simulation to serialize.
This name is used to access the corresponding
data in the 'simulations' dictionary
of the instance.
Returns:
- tuple: A tuple where the first element is either
the CSV content (str) of a single trial
or the binary data of a ZIP file (bytes)
containing multiple CSV files, and the
second element is the file extension (either ".csv" or ".zip").
"""Serializes simulation data to CSV.
Creates a single CSV file or a ZIP file containing multiple CSVs,
depending on the number of trials in the simulation.
"""
simulation_data = simulations_data["simulation_data"]
csv_trials_output = []
Expand Down
202 changes: 202 additions & 0 deletions hnn_core/tests/assets/test_default.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
# times,agg,L2,L5
0.000000, 0.004901, -0.000004, 0.004905
0.850000, -0.001031, -0.000002, -0.001028
1.700000, -0.000821, -0.000001, -0.000820
2.550000, -0.000643, -0.000000, -0.000642
3.400000, -0.000500, -0.000000, -0.000500
4.250000, -0.000389, 0.000000, -0.000389
5.100000, -0.000304, 0.000000, -0.000305
5.950000, -0.000240, 0.000000, -0.000240
6.800000, -0.000190, 0.000000, -0.000191
7.650000, -0.000153, 0.000000, -0.000153
8.500000, -0.000125, 0.000000, -0.000125
9.350000, -0.000105, 0.000000, -0.000105
10.200000, -0.000091, 0.000000, -0.000091
11.050000, -0.000081, 0.000000, -0.000082
11.900000, -0.000076, 0.000000, -0.000077
12.750000, -0.000074, 0.000000, -0.000075
13.600000, -0.000075, 0.000000, -0.000076
14.450000, -0.000078, 0.000000, -0.000078
15.300000, -0.000083, 0.000000, -0.000083
16.150000, -0.000089, 0.000000, -0.000089
17.000000, -0.000095, 0.000000, -0.000096
17.850000, -0.000103, 0.000000, -0.000103
18.700000, -0.000111, 0.000000, -0.000111
19.550000, -0.000119, 0.000000, -0.000119
20.400000, -0.000036, 0.000091, -0.000127
21.250000, 0.000111, 0.000246, -0.000135
22.100000, 0.000440, 0.000583, -0.000143
22.950000, 0.000023, 0.000100, -0.000076
23.800000, 0.000069, -0.000005, 0.000074
24.650000, 0.001068, 0.000864, 0.000204
25.500000, 0.002378, 0.002052, 0.000326
26.350000, 0.003182, 0.002578, 0.000604
27.200000, 0.003840, 0.002685, 0.001155
28.050000, 0.007157, 0.003880, 0.003277
28.900000, 0.010487, 0.005213, 0.005274
29.750000, 0.011173, 0.006169, 0.005004
30.600000, 0.011241, 0.006422, 0.004819
31.450000, 0.009575, 0.006133, 0.003442
32.300000, 0.009335, 0.005203, 0.004132
33.150000, 0.006574, 0.003111, 0.003463
34.000000, 0.002448, 0.000363, 0.002086
34.850000, -0.000186, -0.001311, 0.001125
35.700000, -0.003248, -0.000321, -0.002928
36.550000, -0.005199, 0.001513, -0.006712
37.400000, -0.005465, 0.002522, -0.007986
38.250000, -0.004499, 0.003356, -0.007855
39.100000, -0.003944, 0.002935, -0.006879
39.950000, -0.003525, 0.001841, -0.005365
40.800000, -0.003617, 0.000354, -0.003971
41.650000, -0.003927, -0.000611, -0.003316
42.500000, -0.004465, -0.001302, -0.003162
43.350000, -0.004995, -0.001412, -0.003584
44.200000, -0.005744, -0.000842, -0.004902
45.050000, -0.007144, -0.000433, -0.006711
45.900000, -0.008093, -0.000461, -0.007633
46.750000, -0.008008, 0.000093, -0.008101
47.600000, -0.007503, 0.000971, -0.008474
48.450000, -0.005630, 0.001635, -0.007265
49.300000, -0.003517, 0.001869, -0.005386
50.150000, -0.002863, 0.001902, -0.004765
51.000000, -0.005328, 0.001636, -0.006964
51.850000, -0.007813, 0.001029, -0.008842
52.700000, -0.005764, 0.000967, -0.006731
53.550000, -0.001065, 0.001102, -0.002166
54.400000, 0.000317, 0.001231, -0.000914
55.250000, 0.001767, 0.001268, 0.000500
56.100000, 0.004760, 0.001304, 0.003456
56.950000, 0.005124, 0.001289, 0.003835
57.800000, 0.002286, 0.001216, 0.001070
58.650000, -0.000461, 0.001093, -0.001554
59.500000, -0.002546, 0.000963, -0.003508
60.350000, -0.004627, 0.000811, -0.005438
61.200000, -0.006834, 0.000671, -0.007505
62.050000, -0.008932, 0.000516, -0.009449
62.900000, -0.013852, 0.000352, -0.014203
63.750000, -0.018401, 0.000157, -0.018559
64.600000, -0.024898, -0.000071, -0.024827
65.450000, -0.032659, -0.000282, -0.032377
66.300000, -0.039890, -0.000617, -0.039273
67.150000, -0.048405, -0.000906, -0.047499
68.000000, -0.057989, -0.001351, -0.056637
68.850000, -0.059963, -0.001943, -0.058020
69.700000, -0.048681, -0.002180, -0.046500
70.550000, -0.031704, -0.002144, -0.029560
71.400000, -0.017230, -0.002095, -0.015135
72.250000, -0.020491, -0.002083, -0.018408
73.100000, -0.010235, -0.001987, -0.008248
73.950000, -0.000233, -0.001868, 0.001635
74.800000, 0.006187, -0.001794, 0.007981
75.650000, 0.004787, -0.001772, 0.006559
76.500000, -0.000787, -0.001764, 0.000977
77.350000, -0.003187, -0.001749, -0.001437
78.200000, 0.006586, -0.001727, 0.008312
79.050000, 0.004913, -0.001699, 0.006612
79.900000, 0.002309, -0.001669, 0.003978
80.750000, -0.003490, -0.001637, -0.001853
81.600000, -0.002349, -0.001604, -0.000745
82.450000, 0.007867, -0.001597, 0.009465
83.300000, 0.013894, -0.001576, 0.015470
84.150000, 0.009662, -0.001546, 0.011208
85.000000, -0.004782, -0.001515, -0.003267
85.850000, -0.015327, -0.001483, -0.013844
86.700000, -0.019231, -0.001493, -0.017738
87.550000, -0.023699, -0.001479, -0.022220
88.400000, -0.027380, -0.001454, -0.025926
89.250000, -0.029593, -0.001427, -0.028167
90.100000, -0.030457, -0.001399, -0.029058
90.950000, -0.027972, -0.001373, -0.026599
91.800000, -0.023526, -0.001347, -0.022180
92.650000, -0.027878, -0.001320, -0.026558
93.500000, -0.034506, -0.001295, -0.033210
94.350000, -0.037153, -0.001273, -0.035881
95.200000, -0.034914, -0.001253, -0.033661
96.050000, -0.028039, -0.001235, -0.026804
96.900000, -0.020244, -0.001218, -0.019026
97.750000, -0.009078, -0.001202, -0.007876
98.600000, -0.002269, -0.001186, -0.001083
99.450000, 0.002204, -0.001170, 0.003374
100.300000, 0.005398, -0.001155, 0.006553
101.150000, 0.005492, -0.001140, 0.006632
102.000000, 0.003259, -0.001125, 0.004384
102.850000, 0.015135, -0.001110, 0.016245
103.700000, 0.017619, -0.001096, 0.018715
104.550000, 0.018101, -0.001082, 0.019183
105.400000, 0.018124, -0.001155, 0.019280
106.250000, 0.020798, -0.001170, 0.021968
107.100000, 0.023153, -0.001178, 0.024331
107.950000, 0.022969, -0.001165, 0.024134
108.800000, 0.020145, -0.001160, 0.021305
109.650000, 0.018732, -0.001146, 0.019877
110.500000, 0.016862, -0.001128, 0.017990
111.350000, 0.011694, -0.000813, 0.012507
112.200000, 0.007697, -0.000498, 0.008195
113.050000, 0.003436, -0.000598, 0.004034
113.900000, 0.001065, -0.001218, 0.002283
114.750000, 0.001018, -0.001386, 0.002405
115.600000, 0.001123, -0.001332, 0.002455
116.450000, 0.000912, -0.001187, 0.002099
117.300000, 0.001343, -0.000987, 0.002330
118.150000, 0.003930, -0.000771, 0.004701
119.000000, 0.007365, -0.000556, 0.007921
119.850000, 0.008765, -0.000453, 0.009217
120.700000, 0.010135, -0.000404, 0.010539
121.550000, 0.012114, -0.000089, 0.012203
122.400000, 0.014030, 0.000210, 0.013820
123.250000, 0.012956, 0.000012, 0.012944
124.100000, 0.009596, -0.000030, 0.009625
124.950000, 0.009737, 0.001321, 0.008416
125.800000, 0.011428, 0.002215, 0.009213
126.650000, 0.009874, 0.001135, 0.008738
127.500000, 0.007932, 0.000147, 0.007785
128.350000, 0.008005, 0.000672, 0.007333
129.200000, 0.008103, 0.000770, 0.007334
130.050000, 0.007523, -0.000085, 0.007608
130.900000, 0.011667, 0.001946, 0.009721
131.750000, 0.016976, 0.004917, 0.012059
132.600000, 0.018978, 0.004972, 0.014007
133.450000, 0.018376, 0.003383, 0.014993
134.300000, 0.018065, 0.004381, 0.013683
135.150000, 0.018451, 0.005940, 0.012511
136.000000, 0.017998, 0.006308, 0.011690
136.850000, 0.016924, 0.005754, 0.011170
137.700000, 0.022504, 0.008672, 0.013832
138.550000, 0.025043, 0.011590, 0.013453
139.400000, 0.029372, 0.011424, 0.017948
140.250000, 0.032035, 0.009205, 0.022830
141.100000, 0.034229, 0.009407, 0.024822
141.950000, 0.033103, 0.011782, 0.021321
142.800000, 0.030434, 0.012227, 0.018208
143.650000, 0.027193, 0.009627, 0.017566
144.500000, 0.018579, 0.006458, 0.012121
145.350000, 0.006030, 0.001837, 0.004193
146.200000, 0.000821, -0.000384, 0.001204
147.050000, 0.003639, 0.001047, 0.002592
147.900000, 0.010721, 0.004641, 0.006080
148.750000, 0.020417, 0.009757, 0.010660
149.600000, 0.024747, 0.013637, 0.011110
150.450000, 0.026965, 0.014998, 0.011967
151.300000, 0.030735, 0.014423, 0.016312
152.150000, 0.035009, 0.014149, 0.020860
153.000000, 0.036671, 0.011801, 0.024870
153.850000, 0.035689, 0.009358, 0.026331
154.700000, 0.031327, 0.008404, 0.022923
155.550000, 0.026491, 0.008488, 0.018003
156.400000, 0.024704, 0.007879, 0.016825
157.250000, 0.023513, 0.006935, 0.016578
158.100000, 0.021296, 0.005790, 0.015506
158.950000, 0.022641, 0.005599, 0.017042
159.800000, 0.022466, 0.006542, 0.015924
160.650000, 0.018331, 0.007326, 0.011005
161.500000, 0.014261, 0.007754, 0.006507
162.350000, 0.013925, 0.007803, 0.006122
163.200000, 0.013594, 0.007289, 0.006305
164.050000, 0.010272, 0.006451, 0.003822
164.900000, 0.007026, 0.005557, 0.001468
165.750000, 0.002971, 0.005171, -0.002201
166.600000, 0.002061, 0.005246, -0.003184
167.450000, 0.003700, 0.005597, -0.001897
168.300000, 0.007350, 0.005701, 0.001649
169.150000, 0.010697, 0.005525, 0.005172
170.000000, 0.013794, 0.005309, 0.008485
Loading

0 comments on commit 5e04b17

Please sign in to comment.