arrayview 0.50.1__tar.gz → 0.51.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 (89) hide show
  1. {arrayview-0.50.1 → arrayview-0.51.0}/PKG-INFO +1 -1
  2. {arrayview-0.50.1 → arrayview-0.51.0}/pyproject.toml +1 -1
  3. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_io.py +6 -4
  4. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_launcher.py +25 -2
  5. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_viewer.html +287 -73
  6. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_browser.py +113 -0
  7. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_cli.py +21 -6
  8. {arrayview-0.50.1 → arrayview-0.51.0}/.gitignore +0 -0
  9. {arrayview-0.50.1 → arrayview-0.51.0}/LICENSE +0 -0
  10. {arrayview-0.50.1 → arrayview-0.51.0}/README.md +0 -0
  11. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/ARCHITECTURE.md +0 -0
  12. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/__init__.py +0 -0
  13. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/__main__.py +0 -0
  14. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_analysis.py +0 -0
  15. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_app.py +0 -0
  16. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_bootstrap_app.py +0 -0
  17. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_config.py +0 -0
  18. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_diagnostics.py +0 -0
  19. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_dicom.py +0 -0
  20. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_diff.py +0 -0
  21. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_extra_ports.py +0 -0
  22. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_icon.png +0 -0
  23. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_imaging.py +0 -0
  24. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_instance_registry.py +0 -0
  25. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_launch_plan.py +0 -0
  26. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_launch_trace.py +0 -0
  27. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_lifecycle.py +0 -0
  28. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_overlays.py +0 -0
  29. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_platform.py +0 -0
  30. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_render.py +0 -0
  31. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_routes_analysis.py +0 -0
  32. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_routes_drop.py +0 -0
  33. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_routes_export.py +0 -0
  34. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_routes_loading.py +0 -0
  35. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_routes_persistence.py +0 -0
  36. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_routes_preferences.py +0 -0
  37. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_routes_preload.py +0 -0
  38. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_routes_query.py +0 -0
  39. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_routes_rendering.py +0 -0
  40. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_routes_segmentation.py +0 -0
  41. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_routes_state.py +0 -0
  42. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_routes_vectorfield.py +0 -0
  43. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_routes_websocket.py +0 -0
  44. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_segmentation.py +0 -0
  45. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_server.py +0 -0
  46. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_session.py +0 -0
  47. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_session_spec.py +0 -0
  48. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_shell.html +0 -0
  49. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_source_safety.py +0 -0
  50. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_synthetic_mri.py +0 -0
  51. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_torch.py +0 -0
  52. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_tutorial.py +0 -0
  53. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_vectorfield.py +0 -0
  54. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_view_memory.py +0 -0
  55. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_vscode.py +0 -0
  56. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_vscode_browser.py +0 -0
  57. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_vscode_extension.py +0 -0
  58. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_vscode_signal.py +0 -0
  59. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/_watch.py +0 -0
  60. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/arrayview-opener.vsix +0 -0
  61. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/gsap.min.js +0 -0
  62. {arrayview-0.50.1 → arrayview-0.51.0}/src/arrayview/todo.md +0 -0
  63. {arrayview-0.50.1 → arrayview-0.51.0}/tests/capture_patient_loading.py +0 -0
  64. {arrayview-0.50.1 → arrayview-0.51.0}/tests/capture_v_animation.py +0 -0
  65. {arrayview-0.50.1 → arrayview-0.51.0}/tests/conftest.py +0 -0
  66. {arrayview-0.50.1 → arrayview-0.51.0}/tests/make_vectorfield_test_arrays.py +0 -0
  67. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_1d_arrays.py +0 -0
  68. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_api.py +0 -0
  69. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_backend_shared.py +0 -0
  70. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_config.py +0 -0
  71. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_dicom.py +0 -0
  72. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_drop_import.py +0 -0
  73. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_instance_registry.py +0 -0
  74. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_io.py +0 -0
  75. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_large_arrays.py +0 -0
  76. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_launch_blackbox.py +0 -0
  77. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_mode_roundtrip.py +0 -0
  78. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_nifti_meta.py +0 -0
  79. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_nifti_series.py +0 -0
  80. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_rgb_pixel_art.py +0 -0
  81. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_safe_server_stop.py +0 -0
  82. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_source_safety.py +0 -0
  83. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_torch.py +0 -0
  84. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_tutorial.py +0 -0
  85. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_view_memory.py +0 -0
  86. {arrayview-0.50.1 → arrayview-0.51.0}/tests/test_vsix_bundle.py +0 -0
  87. {arrayview-0.50.1 → arrayview-0.51.0}/tests/ui_audit.py +0 -0
  88. {arrayview-0.50.1 → arrayview-0.51.0}/tests/v_anim_frames/.gitkeep +0 -0
  89. {arrayview-0.50.1 → arrayview-0.51.0}/tests/visual_smoke.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: arrayview
3
- Version: 0.50.1
3
+ Version: 0.51.0
4
4
  Summary: Fast multi-dimensional array viewer
5
5
  Project-URL: Home, https://github.com/oscarvanderheide/arrayview
6
6
  Project-URL: Source, https://github.com/oscarvanderheide/arrayview
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "arrayview"
7
- version = "0.50.1"
7
+ version = "0.51.0"
8
8
  description = "Fast multi-dimensional array viewer"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  requires-python = ">=3.12"
@@ -1452,7 +1452,7 @@ def _collection_pattern_paths(pattern):
1452
1452
  return paths
1453
1453
 
1454
1454
 
1455
- def _explicit_case_files(patterns):
1455
+ def _explicit_case_files(patterns, keep_order=False):
1456
1456
  """Plain file paths given as several patterns, or None.
1457
1457
 
1458
1458
  An unquoted ``--match dir/*/maps.nii`` reaches us already expanded by the
@@ -1467,7 +1467,7 @@ def _explicit_case_files(patterns):
1467
1467
  paths = [os.path.abspath(p) for p in patterns if _is_supported_collection_path(p)]
1468
1468
  if len(paths) != len(patterns) or len(set(paths)) != len(paths):
1469
1469
  return None
1470
- return sorted(paths)
1470
+ return paths if keep_order else sorted(paths)
1471
1471
 
1472
1472
 
1473
1473
  def _distinguishing_path_parts(paths):
@@ -1720,6 +1720,7 @@ def load_dir_collection(
1720
1720
  stack="auto",
1721
1721
  scan_progress=None,
1722
1722
  exclude_cases=None,
1723
+ keep_order=False,
1723
1724
  ):
1724
1725
  """Load recursive collection patterns as aligned lazy image/overlay stacks.
1725
1726
 
@@ -1730,7 +1731,8 @@ def load_dir_collection(
1730
1731
  *case_regex*, files are paired by the regex's named ``case`` group instead.
1731
1732
  *exclude_cases* removes known case ids before any image or overlay data is
1732
1733
  opened. It is used by the interactive CLI after the user accepts a partial
1733
- overlay match.
1734
+ overlay match. *keep_order* stacks an explicit file list in the order
1735
+ given instead of sorted.
1734
1736
  """
1735
1737
  if not base_patterns:
1736
1738
  raise ValueError("--match requires at least one positional image pattern.")
@@ -1753,7 +1755,7 @@ def load_dir_collection(
1753
1755
  raise ValueError("; ".join(missing))
1754
1756
  base_matrix = [[by_case[case] for by_case in base_maps] for case in case_ids]
1755
1757
  else:
1756
- explicit_cases = _explicit_case_files(base_patterns)
1758
+ explicit_cases = _explicit_case_files(base_patterns, keep_order=keep_order)
1757
1759
  base_lists = (
1758
1760
  [explicit_cases]
1759
1761
  if explicit_cases is not None
@@ -6052,6 +6052,27 @@ def arrayview():
6052
6052
  "stacking: a directory of arrays is stacked either way. It selects "
6053
6053
  "which files form the collection."
6054
6054
  )
6055
+ if (
6056
+ args.files
6057
+ and len(args.files) > 4
6058
+ and not args.stack_mode
6059
+ and not (
6060
+ args.compare
6061
+ or args.overlay
6062
+ or args.vectorfield
6063
+ or args.watch
6064
+ or args.rgb
6065
+ or args.relay
6066
+ )
6067
+ ):
6068
+ # Too many for a side-by-side compare: stack them along a new last
6069
+ # axis, one case per file, as --match does for explicit file lists.
6070
+ args.stack_mode = True
6071
+ args.keep_file_order = True
6072
+ print(
6073
+ f"[ArrayView] {len(args.files)} files: opened as one stack; "
6074
+ "step through the last dimension to switch files."
6075
+ )
6055
6076
  if args.dry_run and not args.stack_mode:
6056
6077
  parser.error("--dry-run requires --match.")
6057
6078
  excluded_cases = set()
@@ -6098,9 +6119,10 @@ def arrayview():
6098
6119
  dims_override = (0, 1)
6099
6120
  if not args.serve and not args.kill and not args.files:
6100
6121
  _configure_tutorial_args(args)
6101
- if args.files and len(args.files) > 6 and not args.stack_mode:
6122
+ if args.files and len(args.files) > 4 and not args.stack_mode:
6102
6123
  parser.error(
6103
- "At most six FILE arguments are supported; concat arrays first for larger compare sets."
6124
+ "More than four FILE arguments open as one stack, which does not "
6125
+ "support --compare, --overlay, --vectorfield, --watch, --rgb, or --relay."
6104
6126
  )
6105
6127
  if args.compare and len(args.files) > 1 and not args.stack_mode:
6106
6128
  parser.error("Use either positional compare files or --compare, not both.")
@@ -6310,6 +6332,7 @@ def arrayview():
6310
6332
  stack=args.stack_policy or "auto",
6311
6333
  scan_progress=scan_progress.update,
6312
6334
  exclude_cases=excluded_cases,
6335
+ keep_order=getattr(args, "keep_file_order", False),
6313
6336
  )
6314
6337
  finally:
6315
6338
  scan_progress.finish()