seqeyes-python 0.3.6__tar.gz → 0.3.7__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 (20) hide show
  1. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/PKG-INFO +1 -1
  2. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/pyproject.toml +1 -1
  3. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/src/seqeyes/__init__.py +1 -1
  4. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/src/seqeyes/resources/pulseq-bundle.js +47 -22
  5. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/.gitignore +0 -0
  6. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/README.md +0 -0
  7. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/examples/demo.ipynb +0 -0
  8. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/examples/demo.py +0 -0
  9. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/src/seqeyes/_plot.py +0 -0
  10. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/src/seqeyes/_renderer.py +0 -0
  11. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/src/seqeyes/resources/viewer.html +0 -0
  12. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/src/seqeyes/resources/webview-bundle.js +0 -0
  13. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/tests/conftest.py +0 -0
  14. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/tests/debug_full.html +0 -0
  15. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/tests/debug_minimal.html +0 -0
  16. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/tests/debug_viewer.html +0 -0
  17. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/tests/debug_viewer.py +0 -0
  18. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/tests/integration_test.py +0 -0
  19. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/tests/test_plot.py +0 -0
  20. {seqeyes_python-0.3.6 → seqeyes_python-0.3.7}/tests/test_renderer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: seqeyes-python
3
- Version: 0.3.6
3
+ Version: 0.3.7
4
4
  Summary: Interactive Pulseq MRI sequence viewer for Jupyter — lightweight, beautiful, replaces seq.plot() in pypulseq.
5
5
  Project-URL: Homepage, https://github.com/bughht/seqeyes_plugin
6
6
  Project-URL: Repository, https://github.com/bughht/seqeyes_plugin
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "seqeyes-python"
7
- version = "0.3.6"
7
+ version = "0.3.7"
8
8
  description = "Interactive Pulseq MRI sequence viewer for Jupyter — lightweight, beautiful, replaces seq.plot() in pypulseq."
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -29,4 +29,4 @@ from seqeyes._plot import set, reset
29
29
  from seqeyes._renderer import SeqEyesViewer
30
30
 
31
31
  __all__ = ["set", "reset", "SeqEyesViewer"]
32
- __version__ = "0.3.6"
32
+ __version__ = "0.3.7"
@@ -23,31 +23,24 @@ var Pulseq = (() => {
23
23
  // web/pulseq-browser.ts
24
24
  var pulseq_browser_exports = {};
25
25
  __export(pulseq_browser_exports, {
26
- BAND_DETAIL_SAMPLES: () => BAND_DETAIL_SAMPLES,
27
- EXACT_DETAIL_SAMPLES: () => EXACT_DETAIL_SAMPLES,
28
26
  INTERACTIVE_COMPUTE_LIMITS: () => INTERACTIVE_COMPUTE_LIMITS,
29
- MAX_DETAIL_PTS: () => MAX_DETAIL_PTS,
30
- MAX_DISPLAY_PTS: () => MAX_DISPLAY_PTS,
31
- MAX_ENVELOPE_COLUMNS: () => MAX_ENVELOPE_COLUMNS,
32
27
  MAX_RF_RESPONSE_BANDS: () => MAX_RF_RESPONSE_BANDS,
33
28
  MAX_RF_RESPONSE_FFT_POINTS: () => MAX_RF_RESPONSE_FFT_POINTS,
34
29
  MAX_RF_RESPONSE_SAMPLES: () => MAX_RF_RESPONSE_SAMPLES,
35
30
  PACKAGE_VERSION: () => PACKAGE_VERSION,
36
31
  analyzeRfResponse: () => analyzeRfResponse,
37
32
  audioBudgetRefusal: () => audioBudgetRefusal,
33
+ buildWaveformDetailReply: () => buildWaveformDetailReply,
38
34
  calculateKspace: () => calculateKspace,
39
35
  calculateM1: () => calculateM1,
40
36
  calculateM1Coarse: () => calculateM1Coarse,
41
37
  calculatePns: () => calculatePns,
42
38
  calculatePnsCoarse: () => calculatePnsCoarse,
43
39
  computeGradSpectrumParity: () => computeGradSpectrumParity,
44
- computeGradientEnvelope: () => computeGradientEnvelope,
45
40
  computeGradientSpectrogram: () => computeGradientSpectrogram,
46
41
  computeGradientSpectrumAverage: () => computeGradientSpectrumAverage,
47
42
  computeGradientSpectrumSlice: () => computeGradientSpectrumSlice,
48
43
  countBandsOutsideRange: () => countBandsOutsideRange,
49
- countExactDetailSamples: () => countExactDetailSamples,
50
- countGradientSamples: () => countGradientSamples,
51
44
  createSequenceDecodeContext: () => createSequenceDecodeContext,
52
45
  decodeAllBlocks: () => decodeAllBlocks,
53
46
  decodeBlockRange: () => decodeBlockRange,
@@ -72,8 +65,6 @@ var Pulseq = (() => {
72
65
  hasPulseqBinaryMagic: () => hasPulseqBinaryMagic,
73
66
  isEmptyAscProfile: () => isEmptyAscProfile,
74
67
  kspaceExceedsInteractiveBudget: () => kspaceExceedsInteractiveBudget,
75
- packGradientEnvelope: () => packGradientEnvelope,
76
- packSequenceBlockRange: () => packSequenceBlockRange,
77
68
  packSequenceBlocks: () => packSequenceBlocks,
78
69
  parseAcousticResonancesAsc: () => parseAcousticResonancesAsc,
79
70
  parseAscProfile: () => parseAscProfile,
@@ -84,7 +75,6 @@ var Pulseq = (() => {
84
75
  parseSequenceText: () => parseSequenceText,
85
76
  physicalGradientValueAt: () => physicalGradientValueAt,
86
77
  resamplePhysicalGradients: () => resamplePhysicalGradients,
87
- resolveDetailBlockRange: () => resolveDetailBlockRange,
88
78
  resolveSpectrogramParams: () => resolveSpectrogramParams,
89
79
  rotateGradient: () => rotateGradient,
90
80
  safePnsModel: () => safePnsModel,
@@ -97,7 +87,7 @@ var Pulseq = (() => {
97
87
  });
98
88
 
99
89
  // package.json
100
- var version = "0.3.6";
90
+ var version = "0.3.7";
101
91
 
102
92
  // src/pulseq/decompressor.ts
103
93
  function decompressShape(compressed, numSamples) {
@@ -2862,16 +2852,6 @@ var Pulseq = (() => {
2862
2852
  }
2863
2853
  return { startSec, endSec, columns: width, channels };
2864
2854
  }
2865
- function countGradientSamples(blocks) {
2866
- let total = 0;
2867
- for (const block of blocks) {
2868
- for (const key of GRADIENT_CHANNELS) {
2869
- const grad = block[key];
2870
- if (grad && grad.type !== "none") total += grad.timePoints.length;
2871
- }
2872
- }
2873
- return total;
2874
- }
2875
2855
  function packGradientEnvelope(envelope) {
2876
2856
  const { columns } = envelope;
2877
2857
  const out = new Float32Array(columns * 6);
@@ -2886,6 +2866,51 @@ var Pulseq = (() => {
2886
2866
  return { startSec: envelope.startSec, endSec: envelope.endSec, columns, values: out.buffer };
2887
2867
  }
2888
2868
 
2869
+ // src/editor/waveformDetailReply.ts
2870
+ var WINDOW_DETAIL_BLOCK_LIMIT = 2e4;
2871
+ function buildWaveformDetailReply(seq, context, request, generation = 0, lookup, blockLimit = WINDOW_DETAIL_BLOCK_LIMIT) {
2872
+ const startSec = Number(request.startSec);
2873
+ const endSec = Number(request.endSec);
2874
+ const { start, end } = resolveDetailBlockRange(
2875
+ context.blockStartTimes,
2876
+ seq.blocks.length,
2877
+ startSec,
2878
+ endSec
2879
+ );
2880
+ if (!(endSec > startSec)) {
2881
+ return { kind: "error", message: "This waveform detail window is empty." };
2882
+ }
2883
+ const columns = Math.max(1, Math.min(
2884
+ MAX_ENVELOPE_COLUMNS,
2885
+ Math.floor(Number(request.columns) || 0) || 1
2886
+ ));
2887
+ const cacheKey = `${generation}:${start}:${end}:${startSec}:${endSec}`;
2888
+ const cached = lookup?.(cacheKey);
2889
+ if (cached && end - start <= blockLimit) {
2890
+ return { kind: "samples", startBlock: start, endBlock: end, startSec, endSec, packed: cached, cacheKey };
2891
+ }
2892
+ const decoded = decodeBlockRange(seq, start, end, context);
2893
+ const windowSamples = countExactDetailSamples(decoded, { startSec, endSec });
2894
+ if (windowSamples > EXACT_DETAIL_SAMPLES) {
2895
+ if (windowSamples > BAND_DETAIL_SAMPLES) return { kind: "unavailable", startSec, endSec };
2896
+ const band = packGradientEnvelope(computeGradientEnvelope(decoded, startSec, endSec, columns));
2897
+ return { kind: "band", startSec: band.startSec, endSec: band.endSec, columns: band.columns, values: band.values };
2898
+ }
2899
+ if (end - start > blockLimit) {
2900
+ return { kind: "error", message: "This waveform detail window is too large. Zoom in further." };
2901
+ }
2902
+ const packed = packSequenceBlockRange(
2903
+ seq,
2904
+ start,
2905
+ end,
2906
+ context,
2907
+ MAX_DETAIL_PTS,
2908
+ void 0,
2909
+ { startSec, endSec }
2910
+ );
2911
+ return { kind: "samples", startBlock: start, endBlock: end, startSec, endSec, packed, cacheKey };
2912
+ }
2913
+
2889
2914
  // src/pulseq/physicalGradients.ts
2890
2915
  var GRADIENT_ENDPOINT_TOLERANCE_SEC = 1e-12;
2891
2916
  function rotateGradient(block, gx, gy, gz) {
File without changes