bmtool 0.8.3__tar.gz → 0.8.4__tar.gz

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 (45) hide show
  1. {bmtool-0.8.3 → bmtool-0.8.4}/PKG-INFO +1 -1
  2. bmtool-0.8.4/bmtool/__init__.py +37 -0
  3. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/connectors.py +115 -30
  4. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool.egg-info/PKG-INFO +1 -1
  5. {bmtool-0.8.3 → bmtool-0.8.4}/setup.py +1 -1
  6. bmtool-0.8.3/bmtool/__init__.py +0 -6
  7. {bmtool-0.8.3 → bmtool-0.8.4}/LICENSE +0 -0
  8. {bmtool-0.8.3 → bmtool-0.8.4}/README.md +0 -0
  9. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/SLURM.py +0 -0
  10. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/__main__.py +0 -0
  11. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/analysis/__init__.py +0 -0
  12. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/analysis/entrainment.py +0 -0
  13. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/analysis/lfp.py +0 -0
  14. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/analysis/netcon_reports.py +0 -0
  15. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/analysis/spikes.py +0 -0
  16. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/bmplot/__init__.py +0 -0
  17. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/bmplot/connections.py +0 -0
  18. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/bmplot/entrainment.py +0 -0
  19. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/bmplot/lfp.py +0 -0
  20. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/bmplot/netcon_reports.py +0 -0
  21. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/bmplot/spikes.py +0 -0
  22. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/debug/__init__.py +0 -0
  23. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/debug/commands.py +0 -0
  24. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/debug/debug.py +0 -0
  25. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/graphs.py +0 -0
  26. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/manage.py +0 -0
  27. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/plot_commands.py +0 -0
  28. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/singlecell.py +0 -0
  29. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/stimulus/__init__.py +0 -0
  30. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/stimulus/assemblies.py +0 -0
  31. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/stimulus/core.py +0 -0
  32. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/stimulus/generators.py +0 -0
  33. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/synapses.py +0 -0
  34. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/util/__init__.py +0 -0
  35. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/util/commands.py +0 -0
  36. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/util/neuron/__init__.py +0 -0
  37. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/util/neuron/celltuner.py +0 -0
  38. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool/util/util.py +0 -0
  39. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool.egg-info/SOURCES.txt +0 -0
  40. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool.egg-info/dependency_links.txt +0 -0
  41. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool.egg-info/entry_points.txt +0 -0
  42. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool.egg-info/requires.txt +0 -0
  43. {bmtool-0.8.3 → bmtool-0.8.4}/bmtool.egg-info/top_level.txt +0 -0
  44. {bmtool-0.8.3 → bmtool-0.8.4}/pyproject.toml +0 -0
  45. {bmtool-0.8.3 → bmtool-0.8.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bmtool
3
- Version: 0.8.3
3
+ Version: 0.8.4
4
4
  Summary: BMTool
5
5
  Home-page: https://github.com/cyneuro/bmtool
6
6
  Download-URL:
@@ -0,0 +1,37 @@
1
+ """ I dont love this solution but seems good enough for now might look into this more later"""
2
+
3
+ try:
4
+ from importlib.metadata import PackageNotFoundError, version
5
+ except ImportError: # Python < 3.8
6
+ try:
7
+ from importlib_metadata import PackageNotFoundError, version
8
+ except ImportError:
9
+ PackageNotFoundError = Exception
10
+ version = None
11
+
12
+ from pathlib import Path
13
+ import re
14
+ import warnings
15
+
16
+
17
+ def _version_from_setup_py():
18
+ """Read package version from setup.py as a source-tree fallback."""
19
+ setup_py = Path(__file__).resolve().parents[1] / "setup.py"
20
+ try:
21
+ content = setup_py.read_text(encoding="utf-8")
22
+ except OSError:
23
+ return "0+unknown"
24
+ match = re.search(r"version\s*=\s*['\"]([^'\"]+)['\"]", content)
25
+ return match.group(1) if match else "0+unknown"
26
+
27
+
28
+ if version is None:
29
+ __version__ = _version_from_setup_py()
30
+ else:
31
+ try:
32
+ __version__ = version("bmtool")
33
+ except PackageNotFoundError:
34
+ __version__ = _version_from_setup_py()
35
+
36
+ with warnings.catch_warnings():
37
+ warnings.filterwarnings("ignore", category=FutureWarning)
@@ -10,6 +10,14 @@ from scipy.special import erf
10
10
 
11
11
  rng = np.random.default_rng()
12
12
 
13
+
14
+ def _get_default_rng():
15
+ """Return the current module-level default RNG.
16
+ Using a getter ensures that if the user sets `connectors.rng = seeded_rng`,
17
+ all internal functions that fall back to the default will pick up the new value."""
18
+ return rng
19
+
20
+
13
21
  report_name = "conn.csv"
14
22
 
15
23
  ##############################################################################
@@ -38,7 +46,7 @@ def num_prop(ratio, N):
38
46
  return np.diff(np.round(N / p[-1] * p).astype(int)).reshape(ratio.shape)
39
47
 
40
48
 
41
- def decision(prob, size=None):
49
+ def decision(prob, size=None, rng=None):
42
50
  """
43
51
  Make random decision(s) based on input probability.
44
52
 
@@ -48,6 +56,8 @@ def decision(prob, size=None):
48
56
  Probability threshold between 0 and 1.
49
57
  size : int or tuple, optional
50
58
  Size of the output array. If None, a single decision is returned.
59
+ rng : numpy.random.Generator, optional
60
+ Random number generator. If None, uses the default generator.
51
61
 
52
62
  Returns:
53
63
  --------
@@ -55,10 +65,11 @@ def decision(prob, size=None):
55
65
  Boolean result(s) of the random decision(s). True if the random number
56
66
  is less than prob, False otherwise.
57
67
  """
68
+ rng = _get_default_rng() if rng is None else rng
58
69
  return rng.random(size) < prob
59
70
 
60
71
 
61
- def decisions(prob):
72
+ def decisions(prob, rng=None):
62
73
  """
63
74
  Make multiple random decisions based on input probabilities.
64
75
 
@@ -66,6 +77,8 @@ def decisions(prob):
66
77
  -----------
67
78
  prob : array-like
68
79
  Array of probability thresholds between 0 and 1.
80
+ rng : numpy.random.Generator, optional
81
+ Random number generator. If None, uses the default generator.
69
82
 
70
83
  Returns:
71
84
  --------
@@ -74,6 +87,7 @@ def decisions(prob):
74
87
  the random decisions.
75
88
  """
76
89
  prob = np.asarray(prob)
90
+ rng = _get_default_rng() if rng is None else rng
77
91
  return rng.random(prob.shape) < prob
78
92
 
79
93
 
@@ -130,7 +144,7 @@ class DistantDependentProbability(ProbabilityFunction):
130
144
  else:
131
145
  return 0.0
132
146
 
133
- def decisions(self, dist):
147
+ def decisions(self, dist, rng=None):
134
148
  """Return bool array of decisions given distance array"""
135
149
  dist = np.asarray(dist)
136
150
  dec = np.zeros(dist.shape, dtype=bool)
@@ -138,7 +152,7 @@ class DistantDependentProbability(ProbabilityFunction):
138
152
  dist = dist[mask]
139
153
  prob = np.empty(dist.shape)
140
154
  prob[:] = self.probability(dist)
141
- dec[mask] = decisions(prob)
155
+ dec[mask] = decisions(prob, rng=rng)
142
156
  return dec
143
157
 
144
158
 
@@ -371,7 +385,7 @@ class NormalizedReciprocalRate(ProbabilityFunction):
371
385
  """Return probability for single distance input"""
372
386
  return self.probability(dist, p0, p1)
373
387
 
374
- def decisions(self, dist, p0, p1, cond=None):
388
+ def decisions(self, dist, p0, p1, cond=None, rng=None):
375
389
  """Return bool array of decisions
376
390
  dist: distance (scalar or array). Will be ignored if NRR is constant.
377
391
  p0, p1: forward and backward probability (scalar or array)
@@ -379,6 +393,8 @@ class NormalizedReciprocalRate(ProbabilityFunction):
379
393
  Conditional probability will be returned if specified. The condition
380
394
  event is determined by connection direction (0 for forward, or 1 for
381
395
  backward) and outcomes (bool array of whether connection exists).
396
+ rng : numpy.random.Generator, optional
397
+ Random number generator. If None, uses the default generator.
382
398
  """
383
399
  dist, p0, p1 = map(np.asarray, (dist, p0, p1))
384
400
  pr = np.empty(dist.shape)
@@ -388,7 +404,7 @@ class NormalizedReciprocalRate(ProbabilityFunction):
388
404
  mask = np.asarray(cond[1])
389
405
  pr[mask] /= p1 if cond[0] else p0
390
406
  pr[~mask] = 0.0
391
- return decisions(pr)
407
+ return decisions(pr, rng=rng)
392
408
 
393
409
 
394
410
  # Connector Classes
@@ -625,6 +641,14 @@ class ReciprocalConnector(AbstractConnector):
625
641
  the opposite case. However, it requires large memory allocation
626
642
  as the population size grows. Set it to False if there is a memory
627
643
  issue.
644
+ rng: Random number generator (`numpy.random.Generator`) used for
645
+ stochastic connection decisions in both forward and backward
646
+ directions. Provide a seeded generator for reproducible
647
+ connectivity. If None (default), fall back to the module-level
648
+ default RNG returned by _get_default_rng().
649
+ save_report: Whether to save connection report to CSV file.
650
+ report_name: Filename for connection report. If None, uses the
651
+ module-level report_name.
628
652
  verbose: Whether show verbose information in console.
629
653
 
630
654
  Returns:
@@ -676,6 +700,7 @@ class ReciprocalConnector(AbstractConnector):
676
700
  verbose=True,
677
701
  save_report=True,
678
702
  report_name=None,
703
+ rng = None
679
704
  ):
680
705
  args = locals()
681
706
  var_set = ("p0", "p0_arg", "p1", "p1_arg", "pr", "pr_arg", "n_syn0", "n_syn1")
@@ -703,6 +728,8 @@ class ReciprocalConnector(AbstractConnector):
703
728
  self.stage = 0
704
729
  self.iter_count = 0
705
730
 
731
+ self.rng = _get_default_rng() if rng is None else rng
732
+
706
733
  # *** Two methods executed during bmtk edge creation net.add_edges() ***
707
734
  def setup_nodes(self, source=None, target=None):
708
735
  """Must run this before building connections"""
@@ -1106,10 +1133,10 @@ class ReciprocalConnector(AbstractConnector):
1106
1133
 
1107
1134
  # Make random decision
1108
1135
  if forward:
1109
- forward = decision(p0)
1136
+ forward = decision(p0, rng=self.rng)
1110
1137
  if backward:
1111
1138
  pr = self.pr(self._pr_arg(i, j), p0, p1)
1112
- backward = decision(self.cond_backward(forward, p0, p1, pr))
1139
+ backward = decision(self.cond_backward(forward, p0, p1, pr), rng=self.rng)
1113
1140
 
1114
1141
  # Make connection
1115
1142
  if forward:
@@ -1276,6 +1303,13 @@ class UnidirectionConnector(AbstractConnector):
1276
1303
  n_syn: Number of synapses in the forward connection if connected. It
1277
1304
  can be a constant or a (deterministic or random) function whose
1278
1305
  input arguments are two node objects in BMTK like p_arg.
1306
+ rng: Random number generator (`numpy.random.Generator`) used for
1307
+ stochastic connection decisions. Provide a seeded generator for
1308
+ reproducible connectivity. If None (default), fall back to the
1309
+ module-level default RNG returned by _get_default_rng().
1310
+ save_report: Whether to save connection report to CSV file.
1311
+ report_name: Filename for connection report. If None, uses the
1312
+ module-level report_name.
1279
1313
  verbose: Whether show verbose information in console.
1280
1314
 
1281
1315
  Returns:
@@ -1294,7 +1328,7 @@ class UnidirectionConnector(AbstractConnector):
1294
1328
  """
1295
1329
 
1296
1330
  def __init__(
1297
- self, p=1.0, p_arg=None, n_syn=1, verbose=True, save_report=True, report_name=None
1331
+ self, p=1.0, p_arg=None, n_syn=1, verbose=True, save_report=True, report_name=None, rng=None
1298
1332
  ):
1299
1333
  args = locals()
1300
1334
  var_set = ("p", "p_arg", "n_syn")
@@ -1309,6 +1343,8 @@ class UnidirectionConnector(AbstractConnector):
1309
1343
  self.conn_prop = {}
1310
1344
  self.iter_count = 0
1311
1345
 
1346
+ self.rng = _get_default_rng() if rng is None else rng
1347
+
1312
1348
  # *** Two methods executed during bmtk edge creation net.add_edges() ***
1313
1349
  def setup_nodes(self, source=None, target=None):
1314
1350
  """Must run this before building connections"""
@@ -1377,7 +1413,7 @@ class UnidirectionConnector(AbstractConnector):
1377
1413
  p = self.p(p_arg)
1378
1414
  possible = p > 0
1379
1415
  self.n_poss += possible
1380
- if possible and decision(p):
1416
+ if possible and decision(p, rng=self.rng):
1381
1417
  nsyns = self.n_syn(source, target)
1382
1418
  self.add_conn_prop(source.node_id, target.node_id, p_arg)
1383
1419
  self.n_conn += 1
@@ -1697,6 +1733,13 @@ class GapJunction(UnidirectionConnector):
1697
1733
  can be a constant or a deterministic function whose value must be
1698
1734
  within range [0, 1]. When p is constant, the connection is
1699
1735
  homogenous.
1736
+ rng: Random number generator (`numpy.random.Generator`) used for
1737
+ stochastic gap-junction decisions. Provide a seeded generator for
1738
+ reproducible connectivity. If None (default), fall back to the
1739
+ module-level default RNG returned by _get_default_rng().
1740
+ save_report: Whether to save connection report to CSV file.
1741
+ report_name: Filename for connection report. If None, uses the
1742
+ module-level report_name.
1700
1743
  verbose: Whether show verbose information in console.
1701
1744
 
1702
1745
  Returns:
@@ -1706,9 +1749,9 @@ class GapJunction(UnidirectionConnector):
1706
1749
  Similar to `UnidirectionConnector`.
1707
1750
  """
1708
1751
 
1709
- def __init__(self, p=1.0, p_arg=None, verbose=True, save_report=True, report_name=None):
1752
+ def __init__(self, p=1.0, p_arg=None, verbose=True, save_report=True, report_name=None, rng=None):
1710
1753
  super().__init__(
1711
- p=p, p_arg=p_arg, verbose=verbose, save_report=save_report, report_name=None
1754
+ p=p, p_arg=p_arg, verbose=verbose, save_report=save_report, report_name=report_name, rng=rng
1712
1755
  )
1713
1756
 
1714
1757
  def setup_nodes(self, source=None, target=None):
@@ -1738,7 +1781,7 @@ class GapJunction(UnidirectionConnector):
1738
1781
  p = self.p(p_arg)
1739
1782
  possible = p > 0
1740
1783
  self.n_poss += possible
1741
- if possible and decision(p):
1784
+ if possible and decision(p, rng=self.rng):
1742
1785
  nsyns = 1
1743
1786
  sid, tid = source.node_id, target.node_id
1744
1787
  self.add_conn_prop(sid, tid, p_arg)
@@ -1807,6 +1850,13 @@ class CorrelatedGapJunction(GapJunction):
1807
1850
  within this population, which contains the connection information
1808
1851
  in its attribute `conn_prop`. So this connector should have
1809
1852
  generated the chemical synapses before generating the gap junction.
1853
+ rng: Random number generator (`numpy.random.Generator`) used for
1854
+ stochastic gap-junction decisions. Provide a seeded generator for
1855
+ reproducible connectivity. If None (default), fall back to the
1856
+ module-level default RNG returned by _get_default_rng().
1857
+ save_report: Whether to save connection report to CSV file.
1858
+ report_name: Filename for connection report. If None, uses the
1859
+ module-level report_name.
1810
1860
  verbose: Whether show verbose information in console.
1811
1861
 
1812
1862
  Returns:
@@ -1826,9 +1876,10 @@ class CorrelatedGapJunction(GapJunction):
1826
1876
  verbose=True,
1827
1877
  save_report=True,
1828
1878
  report_name=None,
1879
+ rng=None,
1829
1880
  ):
1830
1881
  super().__init__(
1831
- p=p_non, p_arg=p_arg, verbose=verbose, save_report=save_report, report_name=None
1882
+ p=p_non, p_arg=p_arg, verbose=verbose, save_report=save_report, report_name=None, rng=rng
1832
1883
  )
1833
1884
  self.vars["p_non"] = self.vars.pop("p")
1834
1885
  self.vars["p_uni"] = p_uni
@@ -1879,7 +1930,7 @@ class CorrelatedGapJunction(GapJunction):
1879
1930
  p = self.ps[conn_type](p_arg)
1880
1931
  possible = p > 0
1881
1932
  self.n_poss += possible
1882
- if possible and decision(p):
1933
+ if possible and decision(p, rng=self.rng):
1883
1934
  nsyns = 1
1884
1935
  self.add_conn_prop(sid, tid, p_arg)
1885
1936
  self.add_conn_prop(tid, sid, p_arg)
@@ -1965,6 +2016,11 @@ class GapJunctionConditionalReciprocalConnector(AbstractConnector):
1965
2016
  n_syn0, n_syn1: Number of synapses for forward/backward connections if
1966
2017
  established. Can be constants or functions of node properties.
1967
2018
  Limited to 255 due to uint8 storage.
2019
+ rng: Random number generator (`numpy.random.Generator`) used for
2020
+ stochastic forward/backward chemical connection decisions.
2021
+ Provide a seeded generator for reproducible connectivity.
2022
+ If None (default), fall back to the module-level default RNG
2023
+ returned by _get_default_rng().
1968
2024
  verbose: Whether to print detailed connection statistics and progress.
1969
2025
  save_report: Whether to save connection report to CSV file.
1970
2026
  report_name: Filename for connection report (default: "conn.csv").
@@ -1990,7 +2046,7 @@ class GapJunctionConditionalReciprocalConnector(AbstractConnector):
1990
2046
  def __init__(self, gap_connector, p0_elec, p1_elec, pr_elec, p0_nonelec, p1_nonelec, pr_nonelec,
1991
2047
  p0_elec_arg=None, p1_elec_arg=None, pr_elec_arg=None,
1992
2048
  p0_nonelec_arg=None, p1_nonelec_arg=None, pr_nonelec_arg=None,
1993
- n_syn0=1, n_syn1=1, verbose=True, save_report=True, report_name=None):
2049
+ n_syn0=1, n_syn1=1, verbose=True, save_report=True, report_name=None, rng=None):
1994
2050
  # Store original parameters like ReciprocalConnector
1995
2051
  args = locals()
1996
2052
  var_set = ("p0_elec", "p0_elec_arg", "p1_elec", "p1_elec_arg", "pr_elec", "pr_elec_arg",
@@ -2004,6 +2060,7 @@ class GapJunctionConditionalReciprocalConnector(AbstractConnector):
2004
2060
  self.report_name = report_name or "conn.csv"
2005
2061
  self.conn_prop = [{}, {}]
2006
2062
  self.stage = 0
2063
+ self.rng = _get_default_rng() if rng is None else rng
2007
2064
  # Track gap junction decisions and connections for detailed reporting
2008
2065
  self.gap_decisions = {}
2009
2066
  self.connection_stats = {'elec': {'pairs': 0, 'uni': 0, 'recp': 0},
@@ -2177,11 +2234,11 @@ class GapJunctionConditionalReciprocalConnector(AbstractConnector):
2177
2234
  p0, p1, pr = self.calc_pair(i, j, False)
2178
2235
 
2179
2236
  # First decide forward connection
2180
- forward = decision(p0)
2237
+ forward = decision(p0, rng=self.rng)
2181
2238
 
2182
2239
  # Then decide backward connection based on forward result
2183
2240
  backward_prob = self.cond_backward_prob(forward, p0, p1, pr)
2184
- backward = decision(backward_prob)
2241
+ backward = decision(backward_prob, rng=self.rng)
2185
2242
 
2186
2243
  # Track connection statistics
2187
2244
  if forward and backward:
@@ -2461,11 +2518,32 @@ def syn_const_delay(
2461
2518
  fluc_stdev=FLUC_STDEV,
2462
2519
  delay_bound=(DELAY_LOWBOUND, DELAY_UPBOUND),
2463
2520
  connector=None,
2521
+ rng=None, **kwargs
2464
2522
  ):
2465
- """Synapse delay constant with some random fluctuation."""
2523
+ """Synapse delay approximately constant with some random fluctuation.
2524
+ Parameters
2525
+ ----------
2526
+ source, target : optional
2527
+ Included for API consistency; not used in this implementation.
2528
+ dist : float, optional
2529
+ Distance between source and target (micron).
2530
+ min_delay : float, optional
2531
+ Minimum delay (ms).
2532
+ velocity : float, optional
2533
+ Synapse conduction velocity (micron/ms).
2534
+ fluc_stdev : float, optional
2535
+ Standard deviation of random Gaussian fluctuation (ms).
2536
+ delay_bound : tuple of (float, float), optional
2537
+ Lower and upper bounds for the delay (ms).
2538
+ connector : optional
2539
+ Included for API consistency; not used in this implementation.
2540
+ rng : numpy.random.Generator, optional
2541
+ Random number generator. If None, uses the default generator.
2542
+ """
2543
+ rng = _get_default_rng() if rng is None else rng
2466
2544
  del_fluc = fluc_stdev * rng.normal()
2467
- delay = dist / SYN_VELOCITY + SYN_MIN_DELAY + del_fluc
2468
- delay = min(max(delay, DELAY_LOWBOUND), DELAY_UPBOUND)
2545
+ delay = dist / velocity + min_delay + del_fluc
2546
+ delay = min(max(delay, delay_bound[0]), delay_bound[1])
2469
2547
  return delay
2470
2548
 
2471
2549
 
@@ -2477,6 +2555,8 @@ def syn_dist_delay_feng(
2477
2555
  fluc_stdev=FLUC_STDEV,
2478
2556
  delay_bound=(DELAY_LOWBOUND, DELAY_UPBOUND),
2479
2557
  connector=None,
2558
+ rng=None,
2559
+ **kwargs
2480
2560
  ):
2481
2561
  """Synpase delay linearly dependent on distance.
2482
2562
  min_delay: minimum delay (ms)
@@ -2484,7 +2564,10 @@ def syn_dist_delay_feng(
2484
2564
  fluc_stdev: standard deviation of random Gaussian fluctuation (ms)
2485
2565
  delay_bound: (lower, upper) bounds of delay (ms)
2486
2566
  connector: connector object from which to read distance
2567
+ rng : numpy.random.Generator, optional
2568
+ Random number generator. If None, uses the default generator.
2487
2569
  """
2570
+ rng = _get_default_rng() if rng is None else rng
2488
2571
  if connector is None:
2489
2572
  dist = euclid_dist(target["positions"], source["positions"])
2490
2573
  else:
@@ -2495,30 +2578,32 @@ def syn_dist_delay_feng(
2495
2578
  return delay
2496
2579
 
2497
2580
 
2498
- def syn_section_PN(source, target, p=0.9, sec_id=(1, 2), sec_x=(0.4, 0.6), **kwargs):
2581
+ def syn_section_PN(source, target, p=0.9, sec_id=(1, 2), sec_x=(0.4, 0.6), rng=None, **kwargs):
2499
2582
  """Synapse location follows a Bernoulli distribution, with probability p
2500
2583
  to obtain the former in sec_id and sec_x"""
2501
- syn_loc = int(not decision(p))
2584
+ rng = _get_default_rng() if rng is None else rng
2585
+ syn_loc = int(not decision(p, rng=rng))
2502
2586
  return sec_id[syn_loc], sec_x[syn_loc]
2503
2587
 
2504
2588
 
2505
2589
  def syn_const_delay_feng_section_PN(
2506
- source, target, p=0.9, sec_id=(1, 2), sec_x=(0.4, 0.6), **kwargs
2590
+ source, target, p=0.9, sec_id=(1, 2), sec_x=(0.4, 0.6), rng=None, **kwargs
2507
2591
  ):
2508
2592
  """Assign both synapse delay and location with constant distance assumed"""
2509
- delay = syn_const_delay(source, target, **kwargs)
2510
- s_id, s_x = syn_section_PN(source, target, p=p, sec_id=sec_id, sec_x=sec_x)
2593
+ delay = syn_const_delay(source, target, rng=rng, **kwargs)
2594
+ s_id, s_x = syn_section_PN(source, target, p=p, sec_id=sec_id, sec_x=sec_x, rng=rng)
2511
2595
  return delay, s_id, s_x
2512
2596
 
2513
2597
 
2514
2598
  def syn_dist_delay_feng_section_PN(
2515
- source, target, p=0.9, sec_id=(1, 2), sec_x=(0.4, 0.6), **kwargs
2599
+ source, target, p=0.9, sec_id=(1, 2), sec_x=(0.4, 0.6), rng=None, **kwargs
2516
2600
  ):
2517
2601
  """Assign both synapse delay and location"""
2518
- delay = syn_dist_delay_feng(source, target, **kwargs)
2519
- s_id, s_x = syn_section_PN(source, target, p=p, sec_id=sec_id, sec_x=sec_x)
2602
+ delay = syn_dist_delay_feng(source, target, rng=rng, **kwargs)
2603
+ s_id, s_x = syn_section_PN(source, target, p=p, sec_id=sec_id, sec_x=sec_x, rng=rng)
2520
2604
  return delay, s_id, s_x
2521
2605
 
2522
2606
 
2523
- def syn_uniform_delay_section(source, target, low=DELAY_LOWBOUND, high=DELAY_UPBOUND, **kwargs):
2607
+ def syn_uniform_delay_section(source, target, low=DELAY_LOWBOUND, high=DELAY_UPBOUND, rng=None, **kwargs):
2608
+ rng = _get_default_rng() if rng is None else rng
2524
2609
  return rng.uniform(low, high)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bmtool
3
- Version: 0.8.3
3
+ Version: 0.8.4
4
4
  Summary: BMTool
5
5
  Home-page: https://github.com/cyneuro/bmtool
6
6
  Download-URL:
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setup(
7
7
  name="bmtool",
8
- version="0.8.3",
8
+ version="0.8.4",
9
9
  author="Neural Engineering Laboratory at the University of Missouri",
10
10
  author_email="gregglickert@mail.missouri.edu",
11
11
  description="BMTool",
@@ -1,6 +0,0 @@
1
- __version__ = "0.0.1"
2
-
3
- import warnings
4
-
5
- with warnings.catch_warnings():
6
- warnings.filterwarnings("ignore", category=FutureWarning)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes