bsb-test 7.2.2__tar.gz → 7.3.0__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 (41) hide show
  1. {bsb_test-7.2.2 → bsb_test-7.3.0}/PKG-INFO +1 -1
  2. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/engines.py +173 -3
  3. {bsb_test-7.2.2 → bsb_test-7.3.0}/pyproject.toml +6 -1
  4. {bsb_test-7.2.2 → bsb_test-7.3.0}/LICENSE +0 -0
  5. {bsb_test-7.2.2 → bsb_test-7.3.0}/README.md +0 -0
  6. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/__init__.py +0 -0
  7. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/__init__.py +0 -0
  8. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/brunel.py +0 -0
  9. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/brunel_wbsb.py +0 -0
  10. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/chunked.py +0 -0
  11. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/complete.py +0 -0
  12. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/double_neuron.py +0 -0
  13. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/full_compile.py +0 -0
  14. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/gif_pop_psc_exp.py +0 -0
  15. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/indegree.py +0 -0
  16. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/minimal.py +0 -0
  17. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/multi.py +0 -0
  18. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/nest_minimal.py +0 -0
  19. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/neuron_miniature_sim.py +0 -0
  20. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/neuron_minimal.py +0 -0
  21. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/outdegree.py +0 -0
  22. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/configs/single.py +0 -0
  23. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/.gitignore +0 -0
  24. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/morphologies/2branch.swc +0 -0
  25. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/morphologies/2comp.swc +0 -0
  26. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/morphologies/2root.swc +0 -0
  27. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/morphologies/3branch.swc +0 -0
  28. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/morphologies/AA0048.swc +0 -0
  29. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/morphologies/BasketCell.swc +0 -0
  30. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/morphologies/GolgiCell.asc +0 -0
  31. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/morphologies/GolgiCell.swc +0 -0
  32. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/morphologies/GranuleCell.swc +0 -0
  33. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/morphologies/PurkinjeCell.swc +0 -0
  34. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/morphologies/StellateCell.swc +0 -0
  35. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/morphologies/soma_boundary.swc +0 -0
  36. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/morphologies/test_morphometry.swc +0 -0
  37. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/orientations/toy_annotations.nrrd +0 -0
  38. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/data/orientations/toy_orientations.nrrd +0 -0
  39. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/debug.py +0 -0
  40. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/exceptions.py +0 -0
  41. {bsb_test-7.2.2 → bsb_test-7.3.0}/bsb_test/parallel.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bsb-test
3
- Version: 7.2.2
3
+ Version: 7.3.0
4
4
  Summary: Helpers for better and more complete tests for component developers of the BSB framework.
5
5
  Author-email: Robin De Schepper <robin@alexandria.sc>, Dimitri Rodarie <dimitri.rodarie@unipv.it>
6
6
  Requires-Python: >=3.10,<4
@@ -25,6 +25,7 @@ from bsb import (
25
25
  Configuration,
26
26
  DatasetExistsError,
27
27
  DatasetNotFoundError,
28
+ LabellingError,
28
29
  MorphologySet,
29
30
  Scaffold,
30
31
  Storage,
@@ -241,12 +242,20 @@ class TestPlacementSet(
241
242
  self.assertEqual(int, arr.dtype, "Expected ints")
242
243
  self.assertClose(np.arange(100), arr, "Expected ids 0 to 99")
243
244
 
245
+ labels = ["test_label"]
246
+ ps.label(labels=labels, cells=np.linspace(0, 100, 20, endpoint=False, dtype=int))
244
247
  # Load one chunk (the `FixedPosConfigFixture` places 25 cells in 4 chunks).
245
248
  ps.set_chunk_filter([(1, 0, 0)])
246
249
  arr = ps.load_ids()
247
250
  self.assertEqual((25,), arr.shape, "Expected 25 ids")
248
251
  self.assertClose(np.arange(25, 50), arr, "Expected ids 25 to 49")
249
252
 
253
+ ps.set_label_filter(labels)
254
+ self.assertEqual(ps.get_label_filter(), labels)
255
+ arr = ps.load_ids()
256
+ self.assertEqual((5,), arr.shape, "Expected 5 ids")
257
+ self.assertClose(np.arange(25, 50, 5), arr, "Expected ids 25 to 45")
258
+
250
259
  def test_load_positions(self):
251
260
  self.network.compile()
252
261
  ps = self.network.get_placement_set("test_cell")
@@ -403,6 +412,13 @@ class TestPlacementSet(
403
412
  ps = self.network.get_placement_set("test_cell")
404
413
  cells_to_label = [33, 12, 0, 3, 77]
405
414
  labels = ["label1", "label2"]
415
+ # Test empty labeling
416
+ ps.label(labels, np.full(len(ps), False))
417
+ self.assertAll(
418
+ np.asarray(ps.get_unique_labels()) == np.asarray([set()]),
419
+ "No cells should have been labelled.",
420
+ )
421
+
406
422
  ps.label(labels, cells_to_label)
407
423
  self.assertAll(
408
424
  np.asarray(ps.get_unique_labels()) == np.asarray([set(), set(labels)])
@@ -414,8 +430,8 @@ class TestPlacementSet(
414
430
  )
415
431
  self.assertClose(
416
432
  np.delete(np.arange(len(ps)), cells_to_label),
417
- ps.get_labelled(),
418
- "Empty set should return all non labelled cells",
433
+ ps.get_labelled([]),
434
+ "Empty list should return all non labelled cells",
419
435
  )
420
436
 
421
437
  def test_label_filter(self):
@@ -446,7 +462,123 @@ class TestPlacementSet(
446
462
  self.assertEqual(7, len(ps), "overlapping labels, incorrectly counted")
447
463
  self.assertEqual(7, len(ps.load_positions()), "pos not filtered")
448
464
  self.assertEqual(7, len(ps.load_morphologies()), "morpho not filtered")
449
- self.assertEqual(7, len(ps.load_morphologies()), "rot not filtered")
465
+ self.assertEqual(7, len(ps.load_rotations()), "rot not filtered")
466
+
467
+ @skip_parallel
468
+ def test_overwrite_labels(self):
469
+ # overwriting labels does not work in this unit test
470
+ # in parallel because of how we use the label_filter
471
+ self.network.compile()
472
+ ps = self.network.get_placement_set("test_cell")
473
+ cells_to_label = np.full(len(ps), False, dtype=bool)
474
+ ids_selected = np.array([4, 76, 15, 99, 33])
475
+ cells_to_label[ids_selected] = True
476
+ labels = ["label1", "label2"]
477
+ # Label first with both label1 and label2
478
+ ps.label_by_mask(labels, cells_to_label)
479
+ ps.set_label_filter(labels)
480
+ self.assertClose(ps.load_ids(), np.sort(ids_selected))
481
+ self.assertAll(
482
+ np.asarray(ps.get_unique_labels()) == np.asarray([set(), set(labels)])
483
+ )
484
+ # Overwrite the labels of the same cells with only label1
485
+ ps.remove_labels_by_mask(
486
+ [labels[1]],
487
+ np.full(ids_selected.size, True, dtype=bool),
488
+ )
489
+ # label filters return any matching
490
+ self.assertClose(ps.load_ids(), np.sort(ids_selected))
491
+ # no more cells should be labelled with label2
492
+ ps.set_label_filter([labels[1]])
493
+ self.assertEqual(ps.load_ids().size, 0)
494
+ # unique labels does not take into account label filters
495
+ self.assertAll(
496
+ np.asarray(ps.get_unique_labels()) == np.asarray([set(), set([labels[0]])])
497
+ )
498
+ # remove the labels
499
+ ps.set_label_filter([labels[0]])
500
+ cells = np.full(ids_selected.size, True, dtype=bool)
501
+ ps.remove_labels_by_mask(
502
+ labels,
503
+ cells,
504
+ )
505
+ # no more cells should be labelled with label1
506
+ self.assertEqual(ps.load_ids().size, 0)
507
+ ps.set_label_filter(None)
508
+ self.assertClose(ps.load_ids(), np.arange(100, dtype=int))
509
+ self.assertAll(np.asarray(ps.get_unique_labels()) == np.asarray([set()]))
510
+
511
+ @skip_parallel
512
+ def test_example_labels(self):
513
+ # Unit test of the example given on the PlacementSet documentation
514
+ # overwriting labels does not work in this unit test
515
+ # in parallel because of how we use the label_filter
516
+ self.network.compile()
517
+ ps = self.network.get_placement_set("test_cell")
518
+ self.assertAll(ps.load_ids() == np.arange(100, dtype=int))
519
+ # you can put as many labels onto one cell
520
+ ps.label(["labelA", "labelB"], [1, 5, 6])
521
+ filter_ = np.zeros(len(ps), dtype=bool)
522
+ filter_[np.array([0, 1, 3, 5])] = True
523
+ ps.label_by_mask(["labelC"], filter_)
524
+ ps.remove_labels(["labelA", "labelB", "labelC"], [1])
525
+ ps.label(["labelD"], [1])
526
+ self.assertAll(ps.get_labelled(["labelA"]) == np.array([5, 6]))
527
+ filter_[1] = False
528
+ self.assertAll(ps.get_label_mask(["labelC"]) == filter_)
529
+ self.assertAll(ps.get_labelled(["labelB", "labelC"]) == np.array([0, 3, 5, 6]))
530
+ self.assertAll(ps.get_labelled(["labelD"]) == np.array([1]))
531
+ self.assertAll(ps.get_label_mask() == np.ones(len(ps), dtype=bool))
532
+ self.assertAll(np.isin([2, 4], ps.get_labelled([])))
533
+ self.assertAll(
534
+ ps.get_unique_labels()
535
+ == np.array(
536
+ [
537
+ set(),
538
+ {"labelA", "labelB"},
539
+ {"labelC"},
540
+ {"labelA", "labelB", "labelC"},
541
+ {"labelD"},
542
+ ]
543
+ )
544
+ )
545
+ ps.set_label_filter(["labelA"])
546
+ self.assertAll(ps.load_ids() == np.array([5, 6]))
547
+ self.assertEqual(len(ps), 2)
548
+ ps.set_label_filter(["labelB", "labelC"])
549
+ self.assertAll(ps.load_ids() == np.array([0, 3, 5, 6]))
550
+ ps.set_label_filter([])
551
+ self.assertAll(np.isin([2, 4], ps.load_ids()))
552
+ ps.set_label_filter(None)
553
+ self.assertAll(ps.load_ids() == np.arange(100, dtype=int))
554
+ ps.set_label_filter(["labelA"])
555
+ ps.label(["labelE"], [1])
556
+ self.assertAll(ps.get_labelled(["labelE"]) == np.array([6]))
557
+
558
+ def test_label_errors(self):
559
+ self.network.compile()
560
+ ps = self.network.get_placement_set("test_cell")
561
+ labels = ["test_label"]
562
+ with self.assertRaises(LabellingError, msg="Negative ids should raise exception"):
563
+ ps.label(labels, np.arange(-1, 50))
564
+
565
+ with self.assertRaises(
566
+ LabellingError, msg="Ids out of range should raise exception"
567
+ ):
568
+ ps.label(labels, np.arange(50, len(ps) + 1))
569
+
570
+ def test_label_by_mask_errors(self):
571
+ self.network.compile()
572
+ ps = self.network.get_placement_set("test_cell")
573
+ labels = ["test_label"]
574
+ with self.assertRaises(
575
+ LabellingError, msg="Array with wrong length should raise exception"
576
+ ):
577
+ ps.label_by_mask(labels, np.full(len(ps) + 1, True))
578
+ with self.assertRaises(
579
+ LabellingError, msg="Array with wrong length should raise exception"
580
+ ):
581
+ ps.remove_labels_by_mask(labels, np.full(len(ps) + 1, True))
450
582
 
451
583
 
452
584
  class TestMorphologyRepository(NumpyTestCase, RandomStorageFixture, engine_name=None):
@@ -759,3 +891,41 @@ class TestConnectivitySet(
759
891
  [len(block[1]) for block in spies["block_data"]],
760
892
  "expected each block to have 625 global locs",
761
893
  )
894
+
895
+ def test_labelled_cells(self):
896
+ # setting seed necessary for parallel testing
897
+ np.random.seed(0)
898
+ ps = self.network.get_placement_set("test_cell")
899
+ labelled_a = np.asarray(np.random.choice(2, len(ps)), dtype=bool)
900
+ ps.label_by_mask(["labelA"], labelled_a)
901
+ ps.label_by_mask(["labelB"], ~labelled_a)
902
+ self.network.configuration.connectivity.add(
903
+ "a_to_b",
904
+ dict(
905
+ strategy="bsb.connectivity.AllToAll",
906
+ presynaptic=dict(cell_types=["test_cell"], labels=["labelA"]),
907
+ postsynaptic=dict(cell_types=["test_cell"], labels=["labelB"]),
908
+ ),
909
+ )
910
+ self.network.configuration.connectivity.add(
911
+ "b_to_a",
912
+ dict(
913
+ strategy="bsb.connectivity.AllToAll",
914
+ presynaptic=dict(cell_types=["test_cell"], labels=["labelB"]),
915
+ postsynaptic=dict(cell_types=["test_cell"], labels=["labelA"]),
916
+ ),
917
+ )
918
+ self.network.compile(
919
+ skip_after_placement=True,
920
+ skip_after_connectivity=True,
921
+ redo=True,
922
+ only=["a_to_b", "b_to_a"],
923
+ )
924
+ a_to_b = self.network.get_connectivity_set("a_to_b").load_connections().all()
925
+ b_to_a = self.network.get_connectivity_set("b_to_a").load_connections().all()
926
+ ids_a = np.where(labelled_a)[0]
927
+ ids_b = np.where(~labelled_a)[0]
928
+ self.assertAll(ids_a == np.unique(a_to_b[0][:, 0]))
929
+ self.assertAll(ids_a == np.unique(b_to_a[1][:, 0]))
930
+ self.assertAll(ids_b == np.unique(a_to_b[1][:, 0]))
931
+ self.assertAll(ids_b == np.unique(b_to_a[0][:, 0]))
@@ -6,7 +6,7 @@ build-backend = "flit_core.buildapi"
6
6
 
7
7
  [project]
8
8
  name = "bsb-test"
9
- version = "7.2.2"
9
+ version = "7.3.0"
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.10,<4"
12
12
  dynamic = [ "description" ]
@@ -36,6 +36,11 @@ name = "bsb_test"
36
36
  [tool.coverage.run]
37
37
  branch = true
38
38
  source = [ "bsb_test" ]
39
+ omit = [
40
+ "bsb_test/engines.py",
41
+ "bsb_test/configs/*",
42
+ "bsb_test/data/*"
43
+ ]
39
44
 
40
45
  [tool.coverage.report]
41
46
  exclude_lines = [ "if typing.TYPE_CHECKING:", "pragma: nocover" ]
File without changes
File without changes
File without changes
File without changes
File without changes