OSBModelValidation 0.2.18__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. OSBModelValidation-0.2.18.dist-info/METADATA +184 -0
  2. OSBModelValidation-0.2.18.dist-info/RECORD +98 -0
  3. OSBModelValidation-0.2.18.dist-info/WHEEL +5 -0
  4. OSBModelValidation-0.2.18.dist-info/entry_points.txt +2 -0
  5. OSBModelValidation-0.2.18.dist-info/top_level.txt +1 -0
  6. omv/__init__.py +8 -0
  7. omv/analyzers/__init__.py +21 -0
  8. omv/analyzers/activation.py +24 -0
  9. omv/analyzers/analyzer.py +80 -0
  10. omv/analyzers/dryrun.py +13 -0
  11. omv/analyzers/input_resistance.py +47 -0
  12. omv/analyzers/morphology.py +16 -0
  13. omv/analyzers/rates.py +97 -0
  14. omv/analyzers/resting.py +37 -0
  15. omv/analyzers/spikes.py +113 -0
  16. omv/analyzers/temperature.py +12 -0
  17. omv/analyzers/timeseries.py +57 -0
  18. omv/analyzers/utils/__init__.py +0 -0
  19. omv/analyzers/utils/filenode.py +73 -0
  20. omv/analyzers/utils/timeseries.py +293 -0
  21. omv/autogen.py +106 -0
  22. omv/common/__init__.py +0 -0
  23. omv/common/inout.py +154 -0
  24. omv/engines/__init__.py +53 -0
  25. omv/engines/arbor_.py +57 -0
  26. omv/engines/brian1.py +59 -0
  27. omv/engines/brian2_.py +57 -0
  28. omv/engines/eden_.py +63 -0
  29. omv/engines/engine.py +111 -0
  30. omv/engines/genesis.py +86 -0
  31. omv/engines/getarbor.py +15 -0
  32. omv/engines/getbrian1.py +42 -0
  33. omv/engines/getbrian2.py +17 -0
  34. omv/engines/geteden.py +17 -0
  35. omv/engines/getgenesis.py +56 -0
  36. omv/engines/getjlems.py +20 -0
  37. omv/engines/getjnml.py +48 -0
  38. omv/engines/getlibsbml.py +13 -0
  39. omv/engines/getmoose.py +15 -0
  40. omv/engines/getnest.py +62 -0
  41. omv/engines/getnetpyne.py +52 -0
  42. omv/engines/getneuroconstruct.py +31 -0
  43. omv/engines/getnml2.py +26 -0
  44. omv/engines/getnrn.py +60 -0
  45. omv/engines/getoctave.py +11 -0
  46. omv/engines/getpylems.py +13 -0
  47. omv/engines/getpyneuroml.py +14 -0
  48. omv/engines/getpynn.py +40 -0
  49. omv/engines/jlems.py +48 -0
  50. omv/engines/jneuroml.py +101 -0
  51. omv/engines/jneuromlbrian.py +65 -0
  52. omv/engines/jneuromlbrian2.py +61 -0
  53. omv/engines/jneuromleden.py +61 -0
  54. omv/engines/jneuromlmoose.py +63 -0
  55. omv/engines/jneuromlnetpyne.py +73 -0
  56. omv/engines/jneuromlnetpyne_np2.py +45 -0
  57. omv/engines/jneuromlnetpyne_np4.py +45 -0
  58. omv/engines/jneuromlnrn.py +78 -0
  59. omv/engines/jneuromlpynnnrn.py +75 -0
  60. omv/engines/jneuromlvalidate.py +62 -0
  61. omv/engines/jneuromlvalidatev1.py +58 -0
  62. omv/engines/moose_.py +86 -0
  63. omv/engines/nestsli.py +84 -0
  64. omv/engines/netpyne_.py +120 -0
  65. omv/engines/netpyne__np2.py +47 -0
  66. omv/engines/netpyne__np4.py +47 -0
  67. omv/engines/neuron_.py +205 -0
  68. omv/engines/octave.py +51 -0
  69. omv/engines/pylems.py +57 -0
  70. omv/engines/pylemsnml2.py +59 -0
  71. omv/engines/pynest.py +111 -0
  72. omv/engines/pyneuroconstruct.py +67 -0
  73. omv/engines/pyneuroml_.py +55 -0
  74. omv/engines/pyneuromlvalidatesbml.py +83 -0
  75. omv/engines/pyneuron.py +94 -0
  76. omv/engines/pynn.py +63 -0
  77. omv/engines/pynnbrian1.py +59 -0
  78. omv/engines/pynnbrian2.py +60 -0
  79. omv/engines/pynnnest.py +56 -0
  80. omv/engines/pynnneuroml.py +57 -0
  81. omv/engines/pynnneuron.py +94 -0
  82. omv/engines/utils/__init__.py +21 -0
  83. omv/engines/utils/genesis_utils.g +26 -0
  84. omv/engines/utils/wdir.py +15 -0
  85. omv/experiment.py +18 -0
  86. omv/find_tests.py +126 -0
  87. omv/omt_mep_parser.py +59 -0
  88. omv/omv_util.py +439 -0
  89. omv/parse_omt.py +118 -0
  90. omv/tally.py +112 -0
  91. omv/test/__init__.py +0 -0
  92. omv/test/test_rates.py +38 -0
  93. omv/test/test_types.py +29 -0
  94. omv/validation/__init__.py +0 -0
  95. omv/validation/rx_validator.py +35 -0
  96. omv/validation/utils.py +51 -0
  97. omv/validation/validate.py +53 -0
  98. omv/validation/validate_mep.py +15 -0
@@ -0,0 +1,113 @@
1
+ from omv.analyzers.analyzer import OMVAnalyzer
2
+ from omv.analyzers.utils import timeseries as ts
3
+ from omv.analyzers.utils import filenode as fn
4
+ from omv.common.inout import inform
5
+ from os import getcwd
6
+
7
+
8
+ class SpikeAnalyzer(OMVAnalyzer):
9
+ def before_running(self):
10
+ if "file" in self.observable:
11
+ self.f = fn.FileNodeHelper(self.observable["file"], self.omt_root)
12
+ if self.f.tstamp:
13
+ inform(
14
+ "Attention! Preexistent datafile: ",
15
+ self.f.filename,
16
+ indent=2,
17
+ verbosity=1,
18
+ )
19
+ if "spiketimes file" in self.observable:
20
+ self.f = fn.SpikeFileNodeHelper(
21
+ self.observable["spiketimes file"], self.omt_root
22
+ )
23
+ if self.f.tstamp:
24
+ inform(
25
+ "Attention! Preexistent datafile: ",
26
+ self.f.filename,
27
+ indent=2,
28
+ verbosity=1,
29
+ )
30
+
31
+ def parse_spikes(self, to_parse):
32
+ spikes = []
33
+ if isinstance(to_parse, list):
34
+ spikes = to_parse
35
+ elif "file" in to_parse or "spiketimes file" in to_parse:
36
+ if not self.f.exists():
37
+ inform(
38
+ "ERROR! Datafile %s does not exist (relative to %s)!"
39
+ % (self.f.filename, getcwd()),
40
+ indent=2,
41
+ verbosity=0,
42
+ underline="-",
43
+ )
44
+ spikes = None
45
+ elif not self.f.has_changed():
46
+ inform(
47
+ "ERROR! Datafile %s has not changed!" % self.f.filename,
48
+ indent=2,
49
+ verbosity=0,
50
+ underline="-",
51
+ )
52
+ spikes = None
53
+ elif self.f.has_changed():
54
+ if "file" in to_parse:
55
+ try:
56
+ tv = self.f.get_timeseries()
57
+ except Exception as e:
58
+ inform(
59
+ "ERROR! Could not read spikes from datafile %s (%s)!"
60
+ % (self.f.filename, e),
61
+ indent=2,
62
+ verbosity=0,
63
+ underline="-",
64
+ )
65
+ spikes = []
66
+ return spikes
67
+ inform("Reading timeseries from: ", self.f, indent=1, verbosity=1)
68
+ if "spike detection" in to_parse:
69
+ sd = to_parse["spike detection"]
70
+ method = sd.get("method", "threshold")
71
+ threshold = float(sd.get("threshold", 0))
72
+ inform(
73
+ "Detecting spikes with method: ",
74
+ method,
75
+ indent=2,
76
+ verbosity=1,
77
+ )
78
+ spikes = ts.spikes_from_timeseries(
79
+ tv, method=method, threshold=threshold
80
+ )
81
+ else: # file contains spike times
82
+ spikes = tv
83
+
84
+ elif "spiketimes file" in to_parse:
85
+ inform("Reading spiketimes from: ", self.f, indent=1, verbosity=1)
86
+ all_spikes = self.f.get_spike_times()
87
+ if len(all_spikes) != 1:
88
+ inform(
89
+ "ERROR! Spike times file %s should contain only spikes for one cell!"
90
+ % (self.f.filename),
91
+ indent=2,
92
+ verbosity=0,
93
+ underline="-",
94
+ )
95
+ return None
96
+
97
+ spikes = list(all_spikes.values())[0]
98
+ else:
99
+ inform(
100
+ "ERROR! Preexistent datafile %s has not been updated!"
101
+ % self.f.filename,
102
+ indent=2,
103
+ verbosity=0,
104
+ underline="-",
105
+ )
106
+ spikes = []
107
+ return spikes
108
+
109
+ def parse_expected(self):
110
+ return self.parse_spikes(self.expected)
111
+
112
+ def parse_observable(self):
113
+ return self.parse_spikes(self.observable)
@@ -0,0 +1,12 @@
1
+ from omv.analyzers.analyzer import OMVAnalyzer
2
+
3
+
4
+ class TemperatureAnalyzer(OMVAnalyzer):
5
+ def before_running(self):
6
+ self.query = self.engine.query_temperature()
7
+
8
+ def parse_expected(self):
9
+ return float(self.expected)
10
+
11
+ def parse_observable(self):
12
+ return float(self.engine.fetch_query(self.query))
@@ -0,0 +1,57 @@
1
+ from omv.analyzers.analyzer import OMVAnalyzer
2
+ from omv.analyzers.utils import timeseries as ts
3
+ from omv.analyzers.utils import filenode as fn
4
+ from omv.common.inout import inform
5
+
6
+
7
+ class TimeSeriesAnalyzer(OMVAnalyzer):
8
+ def before_running(self):
9
+ if "file" in self.observable:
10
+ self.fo = fn.FileNodeHelper(self.observable["file"], self.omt_root)
11
+ if self.fo.tstamp:
12
+ inform(
13
+ "Attention! Preexistent datafile: ",
14
+ self.fo.filename,
15
+ indent=2,
16
+ verbosity=1,
17
+ )
18
+
19
+ def parse_ts(self, to_parse):
20
+ return ts
21
+
22
+ def parse_expected(self):
23
+ to_parse = self.expected
24
+ if isinstance(to_parse, list):
25
+ ts = to_parse
26
+ elif "file" in to_parse:
27
+ f = fn.FileNodeHelper(to_parse["file"], self.mep_root)
28
+ ts = f.get_timeseries()
29
+ inform("Reading timeseries from: ", f, indent=1, verbosity=1)
30
+ return ts
31
+
32
+ def parse_observable(self):
33
+ to_parse = self.observable
34
+ if isinstance(to_parse, list):
35
+ ts = to_parse
36
+ elif "file" in to_parse:
37
+ if not self.fo.has_changed():
38
+ inform(
39
+ "ERROR! Datafile %s does not exist!" % self.fo.filename,
40
+ indent=2,
41
+ verbosity=0,
42
+ underline="-",
43
+ )
44
+ ts = []
45
+ elif self.fo.has_changed():
46
+ ts = self.fo.get_timeseries()
47
+ inform("Reading timeseries from: ", self.fo, indent=1, verbosity=1)
48
+ else:
49
+ inform(
50
+ "ERROR! Preexistent datafile %s has not been updated!"
51
+ % self.fo.filename,
52
+ indent=2,
53
+ verbosity=0,
54
+ underline="-",
55
+ )
56
+ ts = []
57
+ return ts
File without changes
@@ -0,0 +1,73 @@
1
+ from omv.analyzers.utils.timeseries import load_data_file, load_spike_file
2
+ from os.path import join, getmtime
3
+ from os.path import exists as os_exists
4
+
5
+
6
+ class FileNode(object):
7
+ def get_timestamp(self):
8
+ try:
9
+ return getmtime(self.filename)
10
+ except OSError:
11
+ # No preexisting file
12
+ return None
13
+
14
+ def exists(self):
15
+ return os_exists(self.filename)
16
+
17
+ def has_changed(self):
18
+ return self.get_timestamp() != self.tstamp
19
+
20
+
21
+ class FileNodeHelper(FileNode):
22
+ def __init__(self, fn, root_dir):
23
+ self.filename = join(root_dir, fn["path"])
24
+ self.columns = fn.get("columns", (0, 1))
25
+ self.header = fn.get("header", 0)
26
+ self.scaling = fn.get("scaling", [1.0] * len(self.columns))
27
+ self.tstamp = self.get_timestamp()
28
+
29
+ def get_timestamp(self):
30
+ try:
31
+ return getmtime(self.filename)
32
+ except OSError:
33
+ # No preexisting file
34
+ return None
35
+
36
+ def exists(self):
37
+ return os_exists(self.filename)
38
+
39
+ def has_changed(self):
40
+ return self.get_timestamp() != self.tstamp
41
+
42
+ def __str__(self):
43
+ return str(
44
+ {
45
+ "file name": str(self.filename),
46
+ "columns(time, voltage)": str(self.columns),
47
+ "initial rows to disregard": str(self.header),
48
+ }
49
+ )
50
+
51
+ def get_timeseries(self):
52
+ return load_data_file(self.filename, self.columns, self.header, self.scaling)
53
+
54
+
55
+ class SpikeFileNodeHelper(FileNode):
56
+ def __init__(self, fn, root_dir):
57
+ self.filename = join(root_dir, fn["path"])
58
+ self.tstamp = self.get_timestamp()
59
+ self.format = fn.get("format", 0)
60
+ self.ids = fn.get("ids", 0)
61
+ self.scaling = fn.get("scaling", 1)
62
+
63
+ def __str__(self):
64
+ return str(
65
+ {
66
+ "spike file name": str(self.filename),
67
+ "format": str(self.format),
68
+ "ids": str(self.ids),
69
+ }
70
+ )
71
+
72
+ def get_spike_times(self):
73
+ return load_spike_file(self.filename, self.format, self.ids, self.scaling)
@@ -0,0 +1,293 @@
1
+ from omv.common.inout import inform
2
+
3
+
4
+ def detect_spikes(v, method="threshold", threshold=0.0):
5
+ from numpy import flatnonzero, bitwise_and, roll, diff, array
6
+
7
+ extrema = array([])
8
+ if method == "threshold":
9
+ extrema = 1 + flatnonzero(
10
+ bitwise_and((v[:-1] <= threshold), (roll(v, -1)[:-1] > threshold))
11
+ )
12
+ elif method == "derivative":
13
+ # This should only work for noiseless cases!
14
+ dx = diff(v)
15
+ extrema = 1 + flatnonzero(bitwise_and((dx[:-1] >= 0), (roll(dx, -1)[:-1] < 0)))
16
+ else:
17
+ print("still need to implement fancier spike detectors...")
18
+ # see for example scipy.signal.find_peaks_cwt
19
+ return extrema
20
+
21
+
22
+ def load_data_file(fname, columns=(0, 1), header_lines=0, scaling=1):
23
+ from numpy import loadtxt
24
+
25
+ ts = loadtxt(fname, usecols=columns, skiprows=header_lines)
26
+ return ts * scaling
27
+
28
+
29
+ def load_spike_file(fname, format="ID_TIME", ids=0, scaling=1.0):
30
+ from numpy import loadtxt
31
+
32
+ ts = loadtxt(fname, skiprows=3) if format == "ID_TIME_NEST_DAT" else loadtxt(fname)
33
+ spike_map = {}
34
+ for l in ts:
35
+ # print('Interpreting: %s'%l)
36
+ if format == "ID_TIME" or format == "ID_TIME_NEST_DAT":
37
+ t = l[1] * scaling
38
+ id = l[0]
39
+ elif format == "TIME_ID":
40
+ t = l[0] * scaling
41
+ id = l[1]
42
+ if ids == id or ids == "*":
43
+ if not id in spike_map:
44
+ spike_map[id] = []
45
+ spike_map[id].append(t)
46
+ return spike_map
47
+
48
+
49
+ def compare_arrays(arrays, tolerance):
50
+ from numpy import allclose, array, max, abs, atleast_1d
51
+
52
+ # if array conversion fails, also fail test
53
+ try:
54
+ a1, a2 = array(arrays)
55
+ except ValueError as e:
56
+ print(e)
57
+ return (False, 0)
58
+
59
+ if (hasattr(a1, "__len__") or hasattr(a2, "__len__")) and len(a1) != len(
60
+ a2
61
+ ): # Different lengths!!
62
+ return (False, 0)
63
+
64
+ best_tol = None
65
+ try:
66
+ comp = allclose(a1, a2, tolerance)
67
+ if len(atleast_1d(a1)) > 0:
68
+ best_tol = max(abs((a1 - a2) / a2))
69
+ except ValueError:
70
+ comp = False
71
+ return (comp, best_tol)
72
+
73
+
74
+ def compare_dictionaries(d1, d2, tolerance=0.1):
75
+ from numpy import allclose, array
76
+
77
+ ks = d1.keys() if len(d1) < len(d2) else d2.keys()
78
+ a1 = array([d1[k] for k in ks if k in d1])
79
+ a2 = array([d2[k] for k in ks if k in d2])
80
+ return allclose(a1, a2, tolerance)
81
+
82
+
83
+ def load_spike_times(spiketime):
84
+ if isinstance(spiketime, list):
85
+ return spiketime
86
+ else:
87
+ return load_data_file(spiketime, [0])
88
+
89
+
90
+ def spikes_from_timeseries(ts, **kwargs):
91
+ method = kwargs.get("method", "threshold")
92
+ threshold = kwargs.get("threshold", 0)
93
+ t, v = ts.T
94
+ spk_idx = detect_spikes(v, method, threshold)
95
+ return t[spk_idx]
96
+
97
+
98
+ def spikes_from_datafile(
99
+ path, columns=(0, 1), header=0, method="threshold", threshold=0
100
+ ):
101
+ t, v = load_data_file(path, columns, header)
102
+ spk_idx = detect_spikes(v, method, threshold)
103
+ return t[spk_idx]
104
+
105
+
106
+ def average_resting(tv, window, col=1):
107
+ from numpy import mean
108
+
109
+ return mean(tv[-window:, col])
110
+
111
+
112
+ def input_resistance(tv, ti, h_window, cmd_window, voltages, col=1):
113
+ from numpy import mean, where
114
+
115
+ t = ti[:, 0]
116
+ # print(cmd_window
117
+ t_holding = where((t >= h_window[0]) & (t <= h_window[1]))
118
+ t_cmd = where((t >= cmd_window[0]) & (t <= cmd_window[1]))
119
+ holding_i = mean(ti[t_holding, col])
120
+ command_i = mean(ti[t_cmd, col])
121
+ holding_v = mean(tv[t_holding, col])
122
+ command_v = mean(tv[t_cmd, col])
123
+ i_step = command_i - holding_i
124
+ v_step = command_v - holding_v # voltages[0]-voltages[1]
125
+ # print(v_step, i_step, holding_i, command_i
126
+ input_resistance = v_step / i_step
127
+ return input_resistance
128
+
129
+
130
+ def all_within_bounds(ts, bounds=(0, 1)):
131
+ from numpy import all
132
+
133
+ # print(type(bounds[0]),bounds[0],bounds[1], ts.size
134
+ return all((ts[:, 1:] >= bounds[0]) & (ts[:, 1:] <= bounds[1]))
135
+
136
+
137
+ def all_nonzero(ts):
138
+ from numpy import all
139
+
140
+ return all(ts[:, 1:])
141
+
142
+
143
+ def pretty_print_copypaste(obs, exp):
144
+ from numpy import atleast_1d
145
+
146
+ ob = atleast_1d(obs)
147
+ ex = atleast_1d(exp)
148
+ suggest_tol = False
149
+ try: # making it easier to copy/paste lists
150
+ pretty_obs = [float(el) for el in ob]
151
+ pretty_exp = [float(el) for el in ex]
152
+ suggest_tol = len(ob) == len(ex)
153
+
154
+ except (
155
+ Exception
156
+ ) as e: # obs, exp can be rank > 1. Not sure if we would ever c&p those
157
+ pretty_obs, pretty_exp = (str(ob), str(ex))
158
+
159
+ return pretty_obs, pretty_exp
160
+
161
+
162
+ def test_detect_spikes():
163
+ from numpy import array, all, arange
164
+
165
+ x = array([-1, 0, 1, 0] * 10)
166
+
167
+ spk_idx = detect_spikes(x, method="derivative")
168
+ assert all(spk_idx == arange(2, len(x), 4))
169
+
170
+ spk_idx = detect_spikes(x, method="threshold", threshold=0.1)
171
+ assert all(spk_idx == arange(2, len(x), 4))
172
+
173
+ xx = -x # edge case: first point > threshold
174
+ spk_idx = detect_spikes(xx, method="derivative")
175
+ assert all(spk_idx == arange(4, len(xx), 4))
176
+
177
+ spk_idx = detect_spikes(xx, method="threshold", threshold=0.1)
178
+ assert all(spk_idx == arange(4, len(xx), 4))
179
+
180
+
181
+ def _get_single_spike_rate(spiketimes, method, start_time, end_time):
182
+ if method == ISI_BASED_SPIKERATE_CALC:
183
+ isis = []
184
+ tot_isi = 0
185
+ for si in range(len(spiketimes) - 1):
186
+ if (
187
+ spiketimes[si + 1] >= start_time
188
+ and spiketimes[si + 1] <= end_time
189
+ and spiketimes[si] >= start_time
190
+ and spiketimes[si] <= end_time
191
+ ):
192
+ isi = spiketimes[si + 1] - spiketimes[si]
193
+ isis.append(isi)
194
+ tot_isi += isi
195
+ if len(isis) > 0:
196
+ rate = len(isis) / float(tot_isi)
197
+ else:
198
+ rate = 0
199
+ inform(
200
+ "Spikes (%i): %s, qualifying ISIs: %s, rate: %s"
201
+ % (len(spiketimes), spiketimes, isis, rate),
202
+ verbosity=2,
203
+ indent=2,
204
+ )
205
+
206
+ elif method == DURATION_BASED_SPIKERATE_CALC:
207
+ dur = float(end_time - start_time)
208
+ spikes_in = 0
209
+ for s in spiketimes:
210
+ if s >= start_time and s <= end_time:
211
+ spikes_in += 1
212
+ rate = spikes_in / dur
213
+ inform(
214
+ "Spikes %i of %i inside range %s->%s, so rate %s"
215
+ % (spikes_in, len(spiketimes), start_time, end_time, rate),
216
+ verbosity=2,
217
+ indent=2,
218
+ )
219
+ return rate
220
+
221
+ else:
222
+ raise Exception("Unknown method for calculating rates: %s" % method)
223
+
224
+ return rate
225
+
226
+
227
+ ISI_BASED_SPIKERATE_CALC = "isi based"
228
+ DURATION_BASED_SPIKERATE_CALC = "duration based"
229
+
230
+
231
+ def get_spike_rate(
232
+ spikes, method=ISI_BASED_SPIKERATE_CALC, start_time=0, end_time=float("inf")
233
+ ):
234
+ inform(
235
+ 'Calculating average of %i spike rate(s) with method "%s" from %s->%s'
236
+ % (len(spikes), method, start_time, end_time),
237
+ verbosity=1,
238
+ indent=2,
239
+ )
240
+
241
+ if isinstance(spikes, list):
242
+ return _get_single_spike_rate(spikes, method, start_time, end_time)
243
+
244
+ if isinstance(spikes, dict):
245
+ tot_rates = 0
246
+ all_rates = []
247
+ if len(spikes) == 0:
248
+ avg_rate = 0
249
+ else:
250
+ for s in spikes.values():
251
+ r = _get_single_spike_rate(s, method, start_time, end_time)
252
+ all_rates.append(r)
253
+ tot_rates += r
254
+ avg_rate = float(tot_rates) / len(spikes)
255
+ inform(
256
+ 'Calculated average of %i spike rate(s) with method "%s": %s %s'
257
+ % (len(spikes), method, avg_rate, all_rates),
258
+ verbosity=1,
259
+ indent=2,
260
+ )
261
+ return avg_rate
262
+
263
+
264
+ if __name__ == "__main__":
265
+ from omv.common.inout import set_verbosity
266
+
267
+ set_verbosity(2)
268
+
269
+ tsNone = []
270
+ tsA = [0.1]
271
+ tsB = [0.1, 0.2]
272
+
273
+ ts1 = [0.1, 0.2, 0.3, 0.40]
274
+ ts2 = [0.1, 0.3, 0.50]
275
+
276
+ methods = [ISI_BASED_SPIKERATE_CALC, DURATION_BASED_SPIKERATE_CALC]
277
+
278
+ for method in methods:
279
+ opts = [tsNone, tsA, tsB, ts1, ts2, {"0": ts1}, {"0": ts1, "1": ts2}]
280
+ for opt in opts:
281
+ start_time = 0
282
+ end_time = 0.25
283
+ inform(
284
+ " > Rate in %s->%s (%s) for %s: %s\n"
285
+ % (
286
+ start_time,
287
+ end_time,
288
+ method,
289
+ opt,
290
+ get_spike_rate(opt, method, start_time, end_time),
291
+ ),
292
+ indent=2,
293
+ )
omv/autogen.py ADDED
@@ -0,0 +1,106 @@
1
+ from os.path import isdir, join, split
2
+ from glob import glob
3
+ import yaml
4
+
5
+ # ugly hack to get .travis.yaml closer to manual version
6
+ from collections import OrderedDict
7
+
8
+
9
+ class UnsortableList(list):
10
+ def sort(self, *args, **kwargs):
11
+ pass
12
+
13
+
14
+ class UnsortableOrderedDict(OrderedDict):
15
+ def items(self, *args, **kwargs):
16
+ return UnsortableList(OrderedDict.items(self, *args, **kwargs))
17
+
18
+
19
+ yaml.add_representer(
20
+ UnsortableOrderedDict, yaml.representer.SafeRepresenter.represent_dict
21
+ )
22
+
23
+
24
+ def read_option(options, default=0):
25
+ for i, opt in enumerate(options):
26
+ print("\t\t", i, opt)
27
+ opt = None
28
+ while opt is None:
29
+ try:
30
+ sel = int(raw_input("Select option number [default: %s]: " % default))
31
+ opt = options[sel]
32
+ except IndexError:
33
+ print("invalid index!")
34
+ except ValueError:
35
+ print("selecting default: " + default)
36
+ opt = options[default]
37
+ return opt
38
+
39
+
40
+ def find_targets(auto=False):
41
+ # TODO: should belong to engine
42
+ dirs_to_engines_exts = {
43
+ "NEURON": {"engine": "NEURON", "extension": ".hoc"},
44
+ "NeuroML2": {"engine": "jNeuroML", "extension": ".nml"},
45
+ }
46
+ targets = []
47
+ for d, eng_ext in dirs_to_engines_exts.items():
48
+ if isdir(d):
49
+ engine = dirs_to_engines_exts[d]["engine"]
50
+ ext = dirs_to_engines_exts[d]["extension"]
51
+ print("Default directory for {0} engine found.".format(engine))
52
+ print(" Will look for scripts with {0} extension".format(ext))
53
+ scripts = glob(join(d, "*" + ext))
54
+ if scripts:
55
+ if auto:
56
+ print("selecting default: ", scripts[0])
57
+ script = scripts[0]
58
+ else:
59
+ script = read_option(scripts)
60
+ targets.append((engine, script))
61
+ return targets
62
+
63
+
64
+ def create_dryrun(engine, target):
65
+ print(
66
+ " ".join(("Generating dry run test for file", target, ", using engine", engine))
67
+ )
68
+ dirname, fname = split(target)
69
+ omt = {"target": fname, "engine": engine}
70
+ with open(target + ".dry.omt", "w") as fh:
71
+ yaml.dump(omt, fh, default_flow_style=False)
72
+
73
+
74
+ def generate_dottravis(targets):
75
+ engines = [t[0] for t in targets]
76
+ engines = ["OMV_ENGINE=" + be for be in engines]
77
+ # TODO: softcode
78
+ repo = "git+https://github.com/borismarin/osb-model-validation.git"
79
+
80
+ travis = UnsortableOrderedDict(
81
+ [
82
+ ("language", "python"),
83
+ ("python", 2.7),
84
+ ("env", engines),
85
+ ("install", ["pip install " + repo]),
86
+ ("script", ["omv all"]),
87
+ ]
88
+ )
89
+
90
+ with open(".travis.yml", "w") as fh:
91
+ fh.write(yaml.dump(travis, default_flow_style=False))
92
+
93
+
94
+ def autogen(auto=False, dry=True):
95
+ targets = find_targets(auto)
96
+ if targets:
97
+ for engine, target in targets:
98
+ if dry:
99
+ create_dryrun(engine, target)
100
+ generate_dottravis(targets)
101
+ else:
102
+ print("No target scripts found!")
103
+
104
+
105
+ if __name__ == "__main__":
106
+ autogen()
omv/common/__init__.py ADDED
File without changes