brukerapi 0.3.0__tar.gz → 0.4.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 (45) hide show
  1. {brukerapi-0.3.0/brukerapi.egg-info → brukerapi-0.4.0}/PKG-INFO +47 -2
  2. {brukerapi-0.3.0 → brukerapi-0.4.0}/README.rst +45 -0
  3. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/config/properties_2dseq_core.json +21 -1
  4. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/config/properties_fid_core.json +83 -45
  5. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/config/properties_rawdata_core.json +10 -25
  6. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/config/properties_traj_core.json +6 -0
  7. brukerapi-0.4.0/brukerapi/config/properties_traj_custom.json +38 -0
  8. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/dataset.py +177 -13
  9. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/jcampdx.py +7 -3
  10. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/schemas.py +397 -40
  11. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/splitters.py +15 -8
  12. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/utils.py +5 -9
  13. {brukerapi-0.3.0 → brukerapi-0.4.0/brukerapi.egg-info}/PKG-INFO +47 -2
  14. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi.egg-info/SOURCES.txt +2 -1
  15. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi.egg-info/requires.txt +1 -1
  16. {brukerapi-0.3.0 → brukerapi-0.4.0}/pyproject.toml +3 -2
  17. {brukerapi-0.3.0 → brukerapi-0.4.0}/test/test_dataset.py +314 -14
  18. {brukerapi-0.3.0 → brukerapi-0.4.0}/test/test_jcampdx.py +27 -0
  19. {brukerapi-0.3.0 → brukerapi-0.4.0}/test/test_property_configs.py +50 -28
  20. brukerapi-0.4.0/test/test_random_access.py +41 -0
  21. brukerapi-0.4.0/test/test_rawdata.py +102 -0
  22. {brukerapi-0.3.0 → brukerapi-0.4.0}/test/test_split.py +12 -0
  23. brukerapi-0.4.0/test/test_utils.py +22 -0
  24. brukerapi-0.3.0/brukerapi/config/properties_traj_custom.json +0 -3
  25. brukerapi-0.3.0/test/test_random_access.py +0 -20
  26. brukerapi-0.3.0/test/test_rawdata.py +0 -17
  27. {brukerapi-0.3.0 → brukerapi-0.4.0}/LICENSE +0 -0
  28. {brukerapi-0.3.0 → brukerapi-0.4.0}/MANIFEST.in +0 -0
  29. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/__init__.py +0 -0
  30. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/cli.py +0 -0
  31. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/config/properties_2dseq_custom.json +0 -0
  32. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/config/properties_fid_custom.json +0 -0
  33. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/config/properties_rawdata_custom.json +0 -0
  34. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/data.py +0 -0
  35. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/exceptions.py +0 -0
  36. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/folders.py +0 -0
  37. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi/mergers.py +0 -0
  38. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi.egg-info/dependency_links.txt +0 -0
  39. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi.egg-info/entry_points.txt +0 -0
  40. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi.egg-info/not-zip-safe +0 -0
  41. {brukerapi-0.3.0 → brukerapi-0.4.0}/brukerapi.egg-info/top_level.txt +0 -0
  42. {brukerapi-0.3.0 → brukerapi-0.4.0}/setup.cfg +0 -0
  43. {brukerapi-0.3.0 → brukerapi-0.4.0}/test/test_exceptions.py +0 -0
  44. {brukerapi-0.3.0 → brukerapi-0.4.0}/test/test_folders.py +0 -0
  45. {brukerapi-0.3.0 → brukerapi-0.4.0}/test/test_trajectory.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: brukerapi
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Bruker API
5
5
  Author-email: Tomas Psorn <tomaspsorn@isibrno.cz>, Jiri Vitous <vitous@isibrno.cz>
6
6
  Maintainer-email: Jiri Vitous <vitous@isibrno.cz>
@@ -16,7 +16,7 @@ Requires-Dist: pyyaml
16
16
  Provides-Extra: dev
17
17
  Requires-Dist: pytest; extra == "dev"
18
18
  Requires-Dist: zenodo_get; extra == "dev"
19
- Requires-Dist: ruff; extra == "dev"
19
+ Requires-Dist: ruff==0.16.0; extra == "dev"
20
20
  Requires-Dist: pytest-cov; extra == "dev"
21
21
  Dynamic: license-file
22
22
 
@@ -54,6 +54,51 @@ Load any **data set**:
54
54
  dataset.data # access data array
55
55
  dataset.get_value('VisuCoreSize') # get a parameter value
56
56
 
57
+ Raw acquisitions and k-space
58
+ ==============================
59
+
60
+ Raw Bruker acquisitions have format-dependent historical ``.data`` semantics.
61
+ For explicit code, use the representation that matches the task:
62
+
63
+ .. code-block:: python
64
+
65
+ fid = Dataset('{path}/fid')
66
+ fid.raw # decoded (sample, shot, receiver) acquisitions
67
+ fid.kspace # ordered FID k-space
68
+
69
+ job = Dataset('{path}/rawdata.job0')
70
+ job.raw # decoded (sample, shot, receiver) acquisitions
71
+ job.kspace # ordered Cartesian PV360 k-space, when metadata proves the layout
72
+ job.to_kspace(bart=True) # optional 16-axis BART layout
73
+
74
+ ``Dataset.data`` remains backward compatible: FIDs expose their historical
75
+ ordered k-space view, whereas PV360 ``rawdata.jobN`` exposes its historical
76
+ decoded stream and emits a ``FutureWarning``. ``.kspace`` is not a
77
+ reconstruction API; EPI and non-Cartesian jobs require acquisition-specific
78
+ handling.
79
+
80
+ Frame-group metadata
81
+ ====================
82
+
83
+ For 2dseq data, ``frame_group_values`` aligns values named by
84
+ ``VisuGroupDepVals`` to the corresponding array axes. Returned arrays use
85
+ singleton dimensions where needed and therefore broadcast directly against
86
+ ``dataset.data``:
87
+
88
+ .. code-block:: python
89
+
90
+ echoes = dataset.frame_group_values['VisuAcqEchoTime']
91
+ b_matrices = dataset.frame_group_values['VisuAcqDiffusionBMatrix']
92
+
93
+ ``metadata`` provides normalized, grouped access to parsed subject, study,
94
+ series, equipment, and acquisition fields:
95
+
96
+ .. code-block:: python
97
+
98
+ dataset.metadata['visu_study']['uid']
99
+ dataset.metadata['visu_acq']['sequence_name']
100
+ dataset.metadata['subject']['id']
101
+
57
102
  Load an entire **study**:
58
103
 
59
104
  .. code-block:: python
@@ -32,6 +32,51 @@ Load any **data set**:
32
32
  dataset.data # access data array
33
33
  dataset.get_value('VisuCoreSize') # get a parameter value
34
34
 
35
+ Raw acquisitions and k-space
36
+ ==============================
37
+
38
+ Raw Bruker acquisitions have format-dependent historical ``.data`` semantics.
39
+ For explicit code, use the representation that matches the task:
40
+
41
+ .. code-block:: python
42
+
43
+ fid = Dataset('{path}/fid')
44
+ fid.raw # decoded (sample, shot, receiver) acquisitions
45
+ fid.kspace # ordered FID k-space
46
+
47
+ job = Dataset('{path}/rawdata.job0')
48
+ job.raw # decoded (sample, shot, receiver) acquisitions
49
+ job.kspace # ordered Cartesian PV360 k-space, when metadata proves the layout
50
+ job.to_kspace(bart=True) # optional 16-axis BART layout
51
+
52
+ ``Dataset.data`` remains backward compatible: FIDs expose their historical
53
+ ordered k-space view, whereas PV360 ``rawdata.jobN`` exposes its historical
54
+ decoded stream and emits a ``FutureWarning``. ``.kspace`` is not a
55
+ reconstruction API; EPI and non-Cartesian jobs require acquisition-specific
56
+ handling.
57
+
58
+ Frame-group metadata
59
+ ====================
60
+
61
+ For 2dseq data, ``frame_group_values`` aligns values named by
62
+ ``VisuGroupDepVals`` to the corresponding array axes. Returned arrays use
63
+ singleton dimensions where needed and therefore broadcast directly against
64
+ ``dataset.data``:
65
+
66
+ .. code-block:: python
67
+
68
+ echoes = dataset.frame_group_values['VisuAcqEchoTime']
69
+ b_matrices = dataset.frame_group_values['VisuAcqDiffusionBMatrix']
70
+
71
+ ``metadata`` provides normalized, grouped access to parsed subject, study,
72
+ series, equipment, and acquisition fields:
73
+
74
+ .. code-block:: python
75
+
76
+ dataset.metadata['visu_study']['uid']
77
+ dataset.metadata['visu_acq']['sequence_name']
78
+ dataset.metadata['subject']['id']
79
+
35
80
  Load an entire **study**:
36
81
 
37
82
  .. code-block:: python
@@ -61,6 +61,14 @@
61
61
  ["#VisuCoreWordType",["_8BIT_UNSGN_INT"]],
62
62
  ["#VisuCoreByteOrder",["bigEndian"]]
63
63
  ]
64
+ },
65
+ {
66
+ "cmd": "np.dtype({'_32BIT_SGN_INT':'int32','_16BIT_SGN_INT':'int16','_32BIT_FLOAT':'float32','_8BIT_UNSGN_INT':'uint8'}[#RECO_wordtype]).newbyteorder('<' if #RECO_byte_order=='littleEndian' else '>')",
67
+ "conditions": ["#RECO_wordtype in ['_32BIT_SGN_INT','_16BIT_SGN_INT','_32BIT_FLOAT','_8BIT_UNSGN_INT']", "#RECO_byte_order in ['littleEndian','bigEndian']"]
68
+ },
69
+ {
70
+ "cmd": "np.dtype({'ip_int':'int32','ip_short':'int16','ip_float':'float32'}[#DATTYPE]).newbyteorder('<')",
71
+ "conditions": ["#DATTYPE in ['ip_int','ip_short','ip_float']"]
64
72
  }
65
73
  ],
66
74
  "shape_frames": [
@@ -108,12 +116,24 @@
108
116
  {
109
117
  "cmd": "#VisuCoreSize.tuple",
110
118
  "conditions": []
119
+ },
120
+ {
121
+ "cmd": "#RECO_size.tuple",
122
+ "conditions": []
123
+ },
124
+ {
125
+ "cmd": "tuple(size for size in (int(#IM_SIX), int(#IM_SIY), int(#IM_SIZ)) if size > 1)",
126
+ "conditions": []
111
127
  }
112
128
  ],
113
129
  "encoded_dim": [
114
130
  {
115
131
  "cmd": "len(#VisuCoreSize.tuple)",
116
132
  "conditions": []
133
+ },
134
+ {
135
+ "cmd": "len(@shape_block)",
136
+ "conditions": []
117
137
  }
118
138
  ],
119
139
  "shape_storage":[
@@ -173,7 +193,7 @@
173
193
  "conditions": ["@is_single_slice==False"]
174
194
  },
175
195
  {
176
- "cmd": "#VisuCoreDimDesc.list",
196
+ "cmd": "#VisuCoreDimDesc.list + ['frame']",
177
197
  "conditions": ["@is_single_slice==False"]
178
198
  }
179
199
  ]
@@ -73,48 +73,6 @@
73
73
  "#BYTORDA=='big'",
74
74
  "#ACQ_sw_version=='<PV-360.1.1>' or #ACQ_sw_version.value.startswith('<PV-360.3.')"
75
75
  ]
76
- },
77
- {
78
- "cmd": "np.dtype('i4').newbyteorder('<')",
79
- "conditions": [
80
- "#DTYPA in [0, 'Integer']",
81
- "#BYTORDA=='little'"
82
- ]
83
- },
84
- {
85
- "cmd": "np.dtype('i4').newbyteorder('>')",
86
- "conditions": [
87
- "#DTYPA in [0, 'Integer']",
88
- "#BYTORDA=='big'"
89
- ]
90
- },
91
- {
92
- "cmd": "np.dtype('f4').newbyteorder('<')",
93
- "conditions": [
94
- "#DTYPA in [1, 'Float']",
95
- "#BYTORDA=='little'"
96
- ]
97
- },
98
- {
99
- "cmd": "np.dtype('f4').newbyteorder('>')",
100
- "conditions": [
101
- "#DTYPA in [1, 'Float']",
102
- "#BYTORDA=='big'"
103
- ]
104
- },
105
- {
106
- "cmd": "np.dtype('f8').newbyteorder('<')",
107
- "conditions": [
108
- "#DTYPA in [2, 'Double']",
109
- "#BYTORDA=='little'"
110
- ]
111
- },
112
- {
113
- "cmd": "np.dtype('f8').newbyteorder('>')",
114
- "conditions": [
115
- "#DTYPA in [2, 'Double']",
116
- "#BYTORDA=='big'"
117
- ]
118
76
  }
119
77
  ],
120
78
  "channels": [
@@ -346,6 +304,15 @@
346
304
  }
347
305
  ],
348
306
  "block_count": [
307
+ {
308
+ "cmd": "#NPro*#PVM_EncMatrix[2]*#NI*#NR",
309
+ "conditions": [
310
+ "@scheme_id=='RADIAL'",
311
+ "#ACQ_dim==3",
312
+ "np.atleast_1d(#PVM_EncMatrix).size>2",
313
+ "#ACQ_size[1]==#NPro*#PVM_EncMatrix[2]"
314
+ ]
315
+ },
349
316
  {
350
317
  "cmd": "#NI*#NR*#PVM_EncMatrix[1]",
351
318
  "conditions": [
@@ -428,6 +395,23 @@
428
395
  }
429
396
  ],
430
397
  "encoding_space": [
398
+ {
399
+ "cmd": [
400
+ "#ACQ_size[0]//2",
401
+ "#PVM_EncNReceivers",
402
+ "#ACQ_phase_factor",
403
+ "#NI",
404
+ "#NPro // #ACQ_phase_factor",
405
+ "#PVM_EncMatrix[2]",
406
+ "#NR"
407
+ ],
408
+ "conditions": [
409
+ "@scheme_id=='RADIAL'",
410
+ "#ACQ_dim==3",
411
+ "np.atleast_1d(#PVM_EncMatrix).size>2",
412
+ "#ACQ_size[1]==#NPro*#PVM_EncMatrix[2]"
413
+ ]
414
+ },
431
415
  {
432
416
  "cmd": [
433
417
  "#PVM_EncMatrix[0]",
@@ -581,6 +565,15 @@
581
565
  }
582
566
  ],
583
567
  "permute": [
568
+ {
569
+ "cmd": [0,2,4,3,5,6,1],
570
+ "conditions": [
571
+ "@scheme_id=='RADIAL'",
572
+ "#ACQ_dim==3",
573
+ "np.atleast_1d(#PVM_EncMatrix).size>2",
574
+ "#ACQ_size[1]==#NPro*#PVM_EncMatrix[2]"
575
+ ]
576
+ },
584
577
  {
585
578
  "cmd": [0,2,4,3,5,1],
586
579
  "conditions": [
@@ -632,6 +625,22 @@
632
625
  }
633
626
  ],
634
627
  "k_space": [
628
+ {
629
+ "cmd": [
630
+ "#ACQ_size[0]//2",
631
+ "#NPro",
632
+ "#PVM_EncMatrix[2]",
633
+ "#NI",
634
+ "#NR",
635
+ "#PVM_EncNReceivers"
636
+ ],
637
+ "conditions": [
638
+ "@scheme_id=='RADIAL'",
639
+ "#ACQ_dim==3",
640
+ "np.atleast_1d(#PVM_EncMatrix).size>2",
641
+ "#ACQ_size[1]==#NPro*#PVM_EncMatrix[2]"
642
+ ]
643
+ },
635
644
  {
636
645
  "cmd": [
637
646
  "#PVM_EncMatrix[0]",
@@ -794,7 +803,35 @@
794
803
  }
795
804
  ],
796
805
  "dim_type": [
797
- {
806
+ {
807
+ "cmd": [
808
+ "'k_space_encode_step_0'",
809
+ "'k_space_encode_step_1'",
810
+ "'k_space_encode_step_2'",
811
+ "'repetition'",
812
+ "'channel'"
813
+ ],
814
+ "conditions": [
815
+ "@scheme_id=='RADIAL'",
816
+ "#ACQ_dim==3",
817
+ "np.atleast_1d(#PVM_EncMatrix).size>2",
818
+ "#ACQ_size[1]==#NPro*#PVM_EncMatrix[2]"
819
+ ]
820
+ },
821
+ {
822
+ "cmd": [
823
+ "'k_space_encode_step_0'",
824
+ "'k_space_encode_step_1'",
825
+ "'slice'",
826
+ "'repetition'",
827
+ "'channel'",
828
+ "'k_space_encode_step_2'"
829
+ ],
830
+ "conditions": [
831
+ "@scheme_id=='dEPI'"
832
+ ]
833
+ },
834
+ {
798
835
  "cmd": [
799
836
  "'k_space_encode_step_0'",
800
837
  "'k_space_encode_step_1'",
@@ -803,7 +840,7 @@
803
840
  "'channel'"
804
841
  ],
805
842
  "conditions": [
806
- ["@scheme_id",["CART_2D","RADIAL","EPI","dEPI","SPIRAL","ZTE"]]
843
+ ["@scheme_id",["CART_2D","RADIAL","EPI","SPIRAL","ZTE"]]
807
844
  ]
808
845
  },
809
846
  {
@@ -821,7 +858,8 @@
821
858
  {
822
859
  "cmd": [
823
860
  "'k_space_encode_step_0'",
824
- "'repetition'"
861
+ "'repetition'",
862
+ "'average'"
825
863
  ],
826
864
  "conditions": [
827
865
  "@scheme_id=='SPECTROSCOPY'"
@@ -76,31 +76,16 @@
76
76
  }
77
77
  ],
78
78
  "job_desc": [
79
- {
80
- "cmd": "#ACQ_jobs.primed_dict(-1)['<{}>'.format(@subtype)]",
81
- "conditions": [
82
- ["#ACQ_sw_version",["<PV-360.1.1>"]]
83
- ]
84
- },
85
79
  {
86
80
  "cmd": "[v for v in #ACQ_jobs.nested if v[-1] == '<{}>'.format(@subtype)][0]",
87
81
  "conditions": [
88
- "#ACQ_sw_version.value.startswith('<PV-360.3.')"
89
- ]
90
- },
91
-
92
- {
93
- "cmd": "#ACQ_jobs.nested[0]",
94
- "conditions": [
95
- "#ACQ_sw_version in ['<PV 5.1>', '<PV 6.0>', '<PV 6.0.1>', '<PV-7.0.0>']",
96
- "@subtype == 'job0'"
82
+ "len(#ACQ_jobs.nested[0])==9"
97
83
  ]
98
84
  },
99
85
  {
100
- "cmd": "#ACQ_jobs.nested[1]",
86
+ "cmd": "#ACQ_jobs.nested[int(@subtype[3:])]",
101
87
  "conditions": [
102
- "#ACQ_sw_version in ['<PV 5.1>', '<PV 6.0>', '<PV 6.0.1>', '<PV-7.0.0>']",
103
- "@subtype == 'job1'"
88
+ "len(#ACQ_jobs.nested[0])==8"
104
89
  ]
105
90
  }
106
91
  ],
@@ -111,15 +96,15 @@
111
96
  ]
112
97
  }
113
98
  ],
114
- "shape_storage": [
99
+ "dim_type": [
115
100
  {
116
- "cmd": "(@job_desc[0],) + (#PVM_EncNReceivers,) + (@job_desc[6],)",
117
- "conditions": [
118
- "#ACQ_sw_version.value.startswith('<PV-360.3.')"
119
- ]
120
- },
101
+ "cmd": ["'sample'", "'channel'", "'scan'"],
102
+ "conditions": []
103
+ }
104
+ ],
105
+ "shape_storage": [
121
106
  {
122
- "cmd": "(@job_desc[0],) + (#PVM_EncNReceivers,) + (@job_desc[3],)",
107
+ "cmd": "(@job_desc[0],) + (#PVM_EncNReceivers,) + (@job_desc[6] if len(@job_desc)==9 else @job_desc[3],)",
123
108
  "conditions": []
124
109
  }
125
110
  ]
@@ -68,6 +68,12 @@
68
68
  ]
69
69
  }
70
70
  ],
71
+ "dim_type": [
72
+ {
73
+ "cmd": ["'axis'", "'sample'", "'projection'"],
74
+ "conditions": []
75
+ }
76
+ ],
71
77
  "shape_storage": [
72
78
  {
73
79
  "cmd": "(#ACQ_dim, int(os.stat(self.path).st_size // @numpy_dtype.itemsize // #ACQ_dim // #NPro), #NPro)",
@@ -0,0 +1,38 @@
1
+ {
2
+ "subj_id": [
3
+ {
4
+ "cmd": "#SUBJECT_id[1:-1]",
5
+ "conditions": []
6
+ },
7
+ {
8
+ "cmd": "''",
9
+ "conditions": []
10
+ }
11
+ ],
12
+ "study_id": [
13
+ {
14
+ "cmd": "str(#SUBJECT_study_nr)",
15
+ "conditions": []
16
+ },
17
+ {
18
+ "cmd": "''",
19
+ "conditions": []
20
+ }
21
+ ],
22
+ "exp_id": [
23
+ {
24
+ "cmd": "@path.parent.name",
25
+ "conditions": []
26
+ },
27
+ {
28
+ "cmd": "''",
29
+ "conditions": []
30
+ }
31
+ ],
32
+ "id": [
33
+ {
34
+ "cmd": "'Traj_{}*{}*{}'.format(@exp_id, @subj_id, @study_id)",
35
+ "conditions": []
36
+ }
37
+ ]
38
+ }