diff --git a/brukerapi/config/properties_2dseq_custom.json b/brukerapi/config/properties_2dseq_custom.json index 4ffc0ed..068f8b4 100644 --- a/brukerapi/config/properties_2dseq_custom.json +++ b/brukerapi/config/properties_2dseq_custom.json @@ -1,7 +1,7 @@ { "subj_id": [ { - "cmd": "#VisuSubjectName", + "cmd": "#VisuSubjectId", "conditions": [ ] }, @@ -13,7 +13,19 @@ ], "study_id": [ { - "cmd": "str(#VisuStudyNumber)", + "cmd": "#VisuStudyId", + "conditions": [ + ] + }, + { + "cmd": "''", + "conditions": [ + ] + } + ], + "study_nr": [ + { + "cmd": "#VisuStudyNumber", "conditions": [ ] }, @@ -49,7 +61,7 @@ ], "id": [ { - "cmd": "'2DSEQ_{}_{}_{}_{}'.format(@exp_id, @proc_id, @subj_id, @study_id)", + "cmd": "'2DSEQ_{}_{}_{}_{}'.format(@exp_id, @proc_id, @subj_id, @study_nr)", "conditions": [ ] } diff --git a/brukerapi/config/properties_fid_custom.json b/brukerapi/config/properties_fid_custom.json index cd32ce5..13a1158 100644 --- a/brukerapi/config/properties_fid_custom.json +++ b/brukerapi/config/properties_fid_custom.json @@ -15,7 +15,21 @@ ], "study_id": [ { - "cmd": "str(#SUBJECT_study_nr)", + "cmd": "#SUBJECT_study_name", + "conditions": [ + + ] + }, + { + "cmd": "''", + "conditions": [ + + ] + } + ], + "study_nr": [ + { + "cmd": "#SUBJECT_study_nr", "conditions": [ ] @@ -43,7 +57,7 @@ ], "id": [ { - "cmd": "'FID_{}_{}_{}'.format(@exp_id, @subj_id, @study_id)", + "cmd": "'FID_{}_{}_{}'.format(@exp_id, @subj_id, @study_nr)", "conditions": [ ] } diff --git a/brukerapi/config/properties_fid_proc_custom.json b/brukerapi/config/properties_fid_proc_custom.json index bbff1e1..5ae0f8b 100644 --- a/brukerapi/config/properties_fid_proc_custom.json +++ b/brukerapi/config/properties_fid_proc_custom.json @@ -11,7 +11,17 @@ ], "study_id": [ { - "cmd": "str(#SUBJECT_study_nr)", + "cmd": "#SUBJECT_study_name", + "conditions": [] + }, + { + "cmd": "''", + "conditions": [] + } + ], + "study_nr": [ + { + "cmd": "#SUBJECT_study_nr", "conditions": [] }, { @@ -41,7 +51,7 @@ ], "id": [ { - "cmd": "'{}_{}_{}_{}_{}'.format(@type.upper(), @exp_id, @proc_id, @subj_id, @study_id)", + "cmd": "'{}_{}_{}_{}_{}'.format(@type.upper(), @exp_id, @proc_id, @subj_id, @study_nr)", "conditions": [], "comment": "spec 3.5: these live in the PROCNO, so the id names the reconstruction as a 2dseq id does" } diff --git a/brukerapi/config/properties_rawdata_custom.json b/brukerapi/config/properties_rawdata_custom.json index 36d64f9..3476ffb 100644 --- a/brukerapi/config/properties_rawdata_custom.json +++ b/brukerapi/config/properties_rawdata_custom.json @@ -15,7 +15,21 @@ ], "study_id": [ { - "cmd": "str(#SUBJECT_study_nr)", + "cmd": "#SUBJECT_study_name", + "conditions": [ + + ] + }, + { + "cmd": "''", + "conditions": [ + + ] + } + ], + "study_nr": [ + { + "cmd": "#SUBJECT_study_nr", "conditions": [ ] @@ -43,7 +57,7 @@ ], "id": [ { - "cmd": "f'RawData_{@subtype}_{@exp_id}_{@subj_id}_{@study_id}'", + "cmd": "f'RawData_{@subtype}_{@exp_id}_{@subj_id}_{@study_nr}'", "conditions": [ ] } diff --git a/brukerapi/config/properties_traj_custom.json b/brukerapi/config/properties_traj_custom.json index 55724b3..4291136 100644 --- a/brukerapi/config/properties_traj_custom.json +++ b/brukerapi/config/properties_traj_custom.json @@ -11,7 +11,17 @@ ], "study_id": [ { - "cmd": "str(#SUBJECT_study_nr)", + "cmd": "#SUBJECT_study_name", + "conditions": [] + }, + { + "cmd": "''", + "conditions": [] + } + ], + "study_nr": [ + { + "cmd": "#SUBJECT_study_nr", "conditions": [] }, { @@ -31,7 +41,7 @@ ], "id": [ { - "cmd": "'Traj_{}*{}*{}'.format(@exp_id, @subj_id, @study_id)", + "cmd": "'Traj_{}*{}*{}'.format(@exp_id, @subj_id, @study_nr)", "conditions": [] } ] diff --git a/brukerapi/dataset.py b/brukerapi/dataset.py index 0232022..0e1a282 100644 --- a/brukerapi/dataset.py +++ b/brukerapi/dataset.py @@ -1252,6 +1252,7 @@ def to_dict(self, props=None): "_schema", "random_access", "study_id", + "study_nr", "exp_id", "proc_id", "subj_id", diff --git a/test/config/properties_0.2H2.json b/test/config/properties_0.2H2.json index f823a6c..beaf2db 100644 --- a/test/config/properties_0.2H2.json +++ b/test/config/properties_0.2H2.json @@ -1,5 +1,5 @@ { - "2DSEQ_10_1_LEGO_PHANTOM_2": { + "2DSEQ_10_1_0_2": { "TE": 2, "TR": 4, "affine": [ @@ -42,7 +42,7 @@ 50, 50 ], - "id": "2DSEQ_10_1_LEGO_PHANTOM_2", + "id": "2DSEQ_10_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -86,7 +86,7 @@ 182.269660998766 ] }, - "2DSEQ_11_1_LEGO_PHANTOM_2": { + "2DSEQ_11_1_0_2": { "TE": 6, "TR": 20, "affine": [ @@ -129,7 +129,7 @@ 50, 1 ], - "id": "2DSEQ_11_1_LEGO_PHANTOM_2", + "id": "2DSEQ_11_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": true, "num_slice_packages": 1, @@ -174,7 +174,7 @@ 0.000915569254904989 ] }, - "2DSEQ_12_1_LEGO_PHANTOM_2": { + "2DSEQ_12_1_0_2": { "TE": 20, "TR": 1500, "affine": [ @@ -217,7 +217,7 @@ 50.0, 10.0 ], - "id": "2DSEQ_12_1_LEGO_PHANTOM_2", + "id": "2DSEQ_12_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -286,7 +286,7 @@ 151.31449775852 ] }, - "2DSEQ_13_1_LEGO_PHANTOM_2": { + "2DSEQ_13_1_0_2": { "TE": 24.818, "TR": 1000, "affine": [ @@ -328,7 +328,7 @@ 50.0, 20.0 ], - "id": "2DSEQ_13_1_LEGO_PHANTOM_2", + "id": "2DSEQ_13_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -375,7 +375,7 @@ 565.46586457527 ] }, - "2DSEQ_14_1_LEGO_PHANTOM_2": { + "2DSEQ_14_1_0_2": { "TE": 24.279, "TR": 4000, "affine": [ @@ -419,7 +419,7 @@ 50.0, 1.5 ], - "id": "2DSEQ_14_1_LEGO_PHANTOM_2", + "id": "2DSEQ_14_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": true, "num_slice_packages": 1, @@ -482,7 +482,7 @@ 52.6828980096941 ] }, - "2DSEQ_15_1_LEGO_PHANTOM_2": { + "2DSEQ_15_1_0_2": { "TE": 49.0008, "TR": 1500.001, "affine": [ @@ -525,7 +525,7 @@ 50.0, 15.0 ], - "id": "2DSEQ_15_1_LEGO_PHANTOM_2", + "id": "2DSEQ_15_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -620,7 +620,7 @@ 53.6282571882034 ] }, - "2DSEQ_16_1_LEGO_PHANTOM_2": { + "2DSEQ_16_1_0_2": { "TE": 45.788, "TR": 10000, "affine": [ @@ -663,7 +663,7 @@ 50, 2 ], - "id": "2DSEQ_16_1_LEGO_PHANTOM_2", + "id": "2DSEQ_16_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": true, "num_slice_packages": 1, @@ -736,7 +736,7 @@ 65.0506197119759 ] }, - "2DSEQ_17_1_LEGO_PHANTOM_2": { + "2DSEQ_17_1_0_2": { "TE": [ 90.362, 180.724, @@ -788,7 +788,7 @@ 50.0, 30.0 ], - "id": "2DSEQ_17_1_LEGO_PHANTOM_2", + "id": "2DSEQ_17_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -1069,7 +1069,7 @@ 257.301041366432 ] }, - "2DSEQ_18_1_LEGO_PHANTOM_2": { + "2DSEQ_18_1_0_2": { "TE": [ 17.438, 39.93, @@ -1117,7 +1117,7 @@ 50, 2 ], - "id": "2DSEQ_18_1_LEGO_PHANTOM_2", + "id": "2DSEQ_18_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": true, "num_slice_packages": 1, @@ -1166,7 +1166,7 @@ 61.0842873359424 ] }, - "2DSEQ_1_1_LEGO_PHANTOM_2": { + "2DSEQ_1_1_0_2": { "TE": 3, "TR": 200, "affine": [ @@ -1208,7 +1208,7 @@ 60.0, 30.0 ], - "id": "2DSEQ_1_1_LEGO_PHANTOM_2", + "id": "2DSEQ_1_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 3, @@ -1279,7 +1279,7 @@ 68.0388746198903 ] }, - "2DSEQ_21_1_LEGO_PHANTOM_2": { + "2DSEQ_21_1_0_2": { "TE": 0.316319272829721, "TR": 30, "affine": [ @@ -1321,7 +1321,7 @@ 50.0, 6.0 ], - "id": "2DSEQ_21_1_LEGO_PHANTOM_2", + "id": "2DSEQ_21_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -1368,7 +1368,7 @@ 2.49152751238897 ] }, - "2DSEQ_22_1_LEGO_PHANTOM_2": { + "2DSEQ_22_1_0_2": { "TE": 0.02, "TR": 8, "affine": [ @@ -1411,7 +1411,7 @@ 50, 50 ], - "id": "2DSEQ_22_1_LEGO_PHANTOM_2", + "id": "2DSEQ_22_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -1455,7 +1455,7 @@ 1.37425787550869 ] }, - "2DSEQ_23_1_LEGO_PHANTOM_2": { + "2DSEQ_23_1_0_2": { "TE": 0, "TR": 4, "affine": [ @@ -1498,7 +1498,7 @@ 50, 50 ], - "id": "2DSEQ_23_1_LEGO_PHANTOM_2", + "id": "2DSEQ_23_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -1542,7 +1542,7 @@ 1.41252549223342 ] }, - "2DSEQ_24_1_LEGO_PHANTOM_2": { + "2DSEQ_24_1_0_2": { "TR": 1200, "date": "2020-06-16 15:13:18", "dim_type": [ @@ -1553,7 +1553,7 @@ ], "dwell_s": 0.00012480000000000002, "encoded_dim": 3, - "id": "2DSEQ_24_1_LEGO_PHANTOM_2", + "id": "2DSEQ_24_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -1592,7 +1592,7 @@ 0.610878945064932 ] }, - "2DSEQ_25_1_LEGO_PHANTOM_2": { + "2DSEQ_25_1_0_2": { "TE": [ 1.537, 5.537 @@ -1638,7 +1638,7 @@ 50, 50 ], - "id": "2DSEQ_25_1_LEGO_PHANTOM_2", + "id": "2DSEQ_25_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -1684,7 +1684,7 @@ 0.0015559824536877 ] }, - "2DSEQ_26_1_LEGO_PHANTOM_2": { + "2DSEQ_26_1_0_2": { "TE": 0, "TR": 800, "date": "2020-06-16 15:13:18", @@ -1694,7 +1694,7 @@ ], "dwell_s": null, "encoded_dim": 1, - "id": "2DSEQ_26_1_LEGO_PHANTOM_2", + "id": "2DSEQ_26_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -1728,7 +1728,7 @@ 32031.3476742137 ] }, - "2DSEQ_27_1_LEGO_PHANTOM_2": { + "2DSEQ_27_1_0_2": { "TE": 0, "date": "2020-06-16 15:13:18", "dim_type": [ @@ -1737,7 +1737,7 @@ ], "dwell_s": 0.00012480000000000002, "encoded_dim": 1, - "id": "2DSEQ_27_1_LEGO_PHANTOM_2", + "id": "2DSEQ_27_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -1767,7 +1767,7 @@ 0.0783475008622457 ] }, - "2DSEQ_28_1_LEGO_PHANTOM_2": { + "2DSEQ_28_1_0_2": { "TE": 0, "date": "2020-06-16 15:13:18", "dim_type": [ @@ -1776,7 +1776,7 @@ ], "dwell_s": 8.320000000000002e-05, "encoded_dim": 1, - "id": "2DSEQ_28_1_LEGO_PHANTOM_2", + "id": "2DSEQ_28_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -1806,7 +1806,7 @@ 0.0188149760445386 ] }, - "2DSEQ_2_1_LEGO_PHANTOM_2": { + "2DSEQ_2_1_0_2": { "TE": 6, "TR": 100, "affine": [ @@ -1848,7 +1848,7 @@ 50.0, 12.0 ], - "id": "2DSEQ_2_1_LEGO_PHANTOM_2", + "id": "2DSEQ_2_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -1893,7 +1893,7 @@ 153.274237284458 ] }, - "2DSEQ_31_1_LEGO_PHANTOM_2": { + "2DSEQ_31_1_0_2": { "TE": [ 10, 30, @@ -1950,7 +1950,7 @@ 50, 1 ], - "id": "2DSEQ_31_1_LEGO_PHANTOM_2", + "id": "2DSEQ_31_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": true, "num_slice_packages": 1, @@ -2053,7 +2053,7 @@ 98.9442691872253 ] }, - "2DSEQ_31_2_LEGO_PHANTOM_2": { + "2DSEQ_31_2_0_2": { "TR": [ 5500, 3000, @@ -2103,7 +2103,7 @@ 50, 1 ], - "id": "2DSEQ_31_2_LEGO_PHANTOM_2", + "id": "2DSEQ_31_2_0_2", "is_single_slice": true, "num_slice_packages": 1, "numpy_dtype": "int32", @@ -2205,7 +2205,7 @@ 0.000244140625 ] }, - "2DSEQ_31_3_LEGO_PHANTOM_2": { + "2DSEQ_31_3_0_2": { "TE": [ 10, 30, @@ -2254,7 +2254,7 @@ 50, 1 ], - "id": "2DSEQ_31_3_LEGO_PHANTOM_2", + "id": "2DSEQ_31_3_0_2", "is_single_slice": true, "num_slice_packages": 1, "numpy_dtype": "int32", @@ -2346,7 +2346,7 @@ 3.0517578125e-05 ] }, - "2DSEQ_32_1_LEGO_PHANTOM_2": { + "2DSEQ_32_1_0_2": { "TE": 23.5, "TR": 3800, "affine": [ @@ -2389,7 +2389,7 @@ 40.0, 22.5 ], - "id": "2DSEQ_32_1_LEGO_PHANTOM_2", + "id": "2DSEQ_32_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -3480,7 +3480,7 @@ 0.00396825760804928 ] }, - "2DSEQ_32_2_LEGO_PHANTOM_2": { + "2DSEQ_32_2_0_2": { "affine": [ [ 0.3125, @@ -3521,7 +3521,7 @@ 40.0, 22.5 ], - "id": "2DSEQ_32_2_LEGO_PHANTOM_2", + "id": "2DSEQ_32_2_0_2", "is_single_slice": false, "num_slice_packages": 1, "numpy_dtype": "int32", @@ -4221,7 +4221,7 @@ 1e-06 ] }, - "2DSEQ_33_1_LEGO_PHANTOM_2": { + "2DSEQ_33_1_0_2": { "TE": [ 11, 22, @@ -4281,7 +4281,7 @@ 50, 1 ], - "id": "2DSEQ_33_1_LEGO_PHANTOM_2", + "id": "2DSEQ_33_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": true, "num_slice_packages": 1, @@ -4354,7 +4354,7 @@ 0.00166073135632915 ] }, - "2DSEQ_33_2_LEGO_PHANTOM_2": { + "2DSEQ_33_2_0_2": { "affine": [ [ 0.390625, @@ -4395,7 +4395,7 @@ 50, 1 ], - "id": "2DSEQ_33_2_LEGO_PHANTOM_2", + "id": "2DSEQ_33_2_0_2", "is_single_slice": true, "num_slice_packages": 1, "numpy_dtype": "int32", @@ -4445,7 +4445,7 @@ 0.0009765625 ] }, - "2DSEQ_33_3_LEGO_PHANTOM_2": { + "2DSEQ_33_3_0_2": { "affine": [ [ 0.390625, @@ -4486,7 +4486,7 @@ 50, 1 ], - "id": "2DSEQ_33_3_LEGO_PHANTOM_2", + "id": "2DSEQ_33_3_0_2", "is_single_slice": true, "num_slice_packages": 1, "numpy_dtype": "int32", @@ -4536,7 +4536,7 @@ 0.0009765625 ] }, - "2DSEQ_35_1_LEGO_PHANTOM_2": { + "2DSEQ_35_1_0_2": { "TE": 2.90666666666667, "TR": 8, "affine": [ @@ -4580,7 +4580,7 @@ 50, 1 ], - "id": "2DSEQ_35_1_LEGO_PHANTOM_2", + "id": "2DSEQ_35_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": true, "num_slice_packages": 1, @@ -4643,7 +4643,7 @@ 0.000189802173865093 ] }, - "2DSEQ_3_1_LEGO_PHANTOM_2": { + "2DSEQ_3_1_0_2": { "TE": [ 4, 10, @@ -4696,7 +4696,7 @@ 60.0, 16.0 ], - "id": "2DSEQ_3_1_LEGO_PHANTOM_2", + "id": "2DSEQ_3_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -4881,7 +4881,7 @@ 76.6238619262818 ] }, - "2DSEQ_4_1_LEGO_PHANTOM_2": { + "2DSEQ_4_1_0_2": { "TE": [ 15.8175, 36.9075 @@ -4927,7 +4927,7 @@ 50.0, 16.0 ], - "id": "2DSEQ_4_1_LEGO_PHANTOM_2", + "id": "2DSEQ_4_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -4984,7 +4984,7 @@ 295.909058565224 ] }, - "2DSEQ_5_1_LEGO_PHANTOM_2": { + "2DSEQ_5_1_0_2": { "TE": [ 56, 168 @@ -5031,7 +5031,7 @@ 50.0, 9.0 ], - "id": "2DSEQ_5_1_LEGO_PHANTOM_2", + "id": "2DSEQ_5_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -5110,7 +5110,7 @@ 76.2645359359099 ] }, - "2DSEQ_6_1_LEGO_PHANTOM_2": { + "2DSEQ_6_1_0_2": { "TE": 15, "TR": 3000, "affine": [ @@ -5155,7 +5155,7 @@ 50, 1 ], - "id": "2DSEQ_6_1_LEGO_PHANTOM_2", + "id": "2DSEQ_6_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": true, "num_slice_packages": 1, @@ -5240,7 +5240,7 @@ 116.699247196268 ] }, - "2DSEQ_7_1_LEGO_PHANTOM_2": { + "2DSEQ_7_1_0_2": { "TE": [ 14, 42, @@ -5289,7 +5289,7 @@ 50.0, 12.5 ], - "id": "2DSEQ_7_1_LEGO_PHANTOM_2", + "id": "2DSEQ_7_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, @@ -5372,7 +5372,7 @@ 161.012696069596 ] }, - "2DSEQ_8_1_LEGO_PHANTOM_2": { + "2DSEQ_8_1_0_2": { "TE": 19, "TR": 3000, "affine": [ @@ -5415,7 +5415,7 @@ 50, 1 ], - "id": "2DSEQ_8_1_LEGO_PHANTOM_2", + "id": "2DSEQ_8_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": true, "num_slice_packages": 1, @@ -5460,7 +5460,7 @@ 396.459816812455 ] }, - "2DSEQ_9_1_LEGO_PHANTOM_2": { + "2DSEQ_9_1_0_2": { "TE": 5, "TR": 4000, "affine": [ @@ -5503,7 +5503,7 @@ 50, 5 ], - "id": "2DSEQ_9_1_LEGO_PHANTOM_2", + "id": "2DSEQ_9_1_0_2", "imaging_frequency": 400.322522538113, "is_single_slice": false, "num_slice_packages": 1, diff --git a/test/config/properties_PV360_StdData.json b/test/config/properties_PV360_StdData.json index b1e54eb..790943f 100644 --- a/test/config/properties_PV360_StdData.json +++ b/test/config/properties_PV360_StdData.json @@ -1,5 +1,5 @@ { - "2DSEQ_DTI_EPI_seg_30dir_sat_1_std_PV360_3.6^^^^_1": { + "2DSEQ_DTI_EPI_seg_30dir_sat_1_std_PV360_3.6_1": { "TE": 36, "TR": 2000, "affine": [ @@ -42,7 +42,7 @@ 15.0, 5.249999999999999 ], - "id": "2DSEQ_DTI_EPI_seg_30dir_sat_1_std_PV360_3.6^^^^_1", + "id": "2DSEQ_DTI_EPI_seg_30dir_sat_1_std_PV360_3.6_1", "imaging_frequency": 400.38072797888503, "is_single_slice": false, "num_slice_packages": 1, @@ -433,7 +433,7 @@ 41.818209641992354 ] }, - "2DSEQ_DTI_EPI_seg_30dir_sat_2_std_PV360_3.6^^^^_1": { + "2DSEQ_DTI_EPI_seg_30dir_sat_2_std_PV360_3.6_1": { "TE": 36, "TR": 2000, "affine": [ @@ -476,7 +476,7 @@ 15.0, 5.249999999999999 ], - "id": "2DSEQ_DTI_EPI_seg_30dir_sat_2_std_PV360_3.6^^^^_1", + "id": "2DSEQ_DTI_EPI_seg_30dir_sat_2_std_PV360_3.6_1", "imaging_frequency": 400.38072797888503, "is_single_slice": false, "num_slice_packages": 1, @@ -747,7 +747,7 @@ 4.656612876329999e-10 ] }, - "2DSEQ_DTI_EPI_seg_30dir_sat_multi_1_std_PV360_3.6^^^^_1": { + "2DSEQ_DTI_EPI_seg_30dir_sat_multi_1_std_PV360_3.6_1": { "TE": 36, "TR": 2000, "affine": [ @@ -790,7 +790,7 @@ 15.0, 5.249999999999999 ], - "id": "2DSEQ_DTI_EPI_seg_30dir_sat_multi_1_std_PV360_3.6^^^^_1", + "id": "2DSEQ_DTI_EPI_seg_30dir_sat_multi_1_std_PV360_3.6_1", "imaging_frequency": 400.38072797888503, "is_single_slice": false, "num_slice_packages": 1, @@ -1481,7 +1481,7 @@ 42.265919849004014 ] }, - "2DSEQ_DTI_EPI_seg_30dir_sat_multi_2_std_PV360_3.6^^^^_1": { + "2DSEQ_DTI_EPI_seg_30dir_sat_multi_2_std_PV360_3.6_1": { "TE": 36, "TR": 2000, "affine": [ @@ -1524,7 +1524,7 @@ 15.0, 5.249999999999999 ], - "id": "2DSEQ_DTI_EPI_seg_30dir_sat_multi_2_std_PV360_3.6^^^^_1", + "id": "2DSEQ_DTI_EPI_seg_30dir_sat_multi_2_std_PV360_3.6_1", "imaging_frequency": 400.38072797888503, "is_single_slice": false, "num_slice_packages": 1, @@ -1795,7 +1795,7 @@ 4.656612876329999e-10 ] }, - "2DSEQ_PRESS_1H_1_std_PV360_3.6^^^^_1": { + "2DSEQ_PRESS_1H_1_std_PV360_3.6_1": { "TE": 0, "date": "2024-07-25 09:02:12.259000+02:00", "dim_type": [ @@ -1804,7 +1804,7 @@ ], "dwell_s": 6.25e-07, "encoded_dim": 1, - "id": "2DSEQ_PRESS_1H_1_std_PV360_3.6^^^^_1", + "id": "2DSEQ_PRESS_1H_1_std_PV360_3.6_1", "imaging_frequency": 400.3807277403667, "is_single_slice": false, "num_slice_packages": 1, @@ -1834,7 +1834,7 @@ 8.380509974458529e-06 ] }, - "2DSEQ_T1_FLASH_1_std_PV360_3.6^^^^_1": { + "2DSEQ_T1_FLASH_1_std_PV360_3.6_1": { "TE": 4, "TR": 200, "affine": [ @@ -1876,7 +1876,7 @@ 20.0, 8.999999999999993 ], - "id": "2DSEQ_T1_FLASH_1_std_PV360_3.6^^^^_1", + "id": "2DSEQ_T1_FLASH_1_std_PV360_3.6_1", "imaging_frequency": 400.3807239646813, "is_single_slice": false, "num_slice_packages": 1, @@ -1933,7 +1933,7 @@ 1.0110652119312826 ] }, - "2DSEQ_T1_FLASH_3D_iso_1_std_PV360_3.6^^^^_1": { + "2DSEQ_T1_FLASH_3D_iso_1_std_PV360_3.6_1": { "TE": 8, "TR": 50, "affine": [ @@ -1976,7 +1976,7 @@ 20, 12 ], - "id": "2DSEQ_T1_FLASH_3D_iso_1_std_PV360_3.6^^^^_1", + "id": "2DSEQ_T1_FLASH_3D_iso_1_std_PV360_3.6_1", "imaging_frequency": 400.3807239646813, "is_single_slice": false, "num_slice_packages": 1, @@ -2020,7 +2020,7 @@ 0.2549454820972602 ] }, - "2DSEQ_T1_RARE_1_std_PV360_3.6^^^^_1": { + "2DSEQ_T1_RARE_1_std_PV360_3.6_1": { "TE": 7.5, "TR": 800, "affine": [ @@ -2062,7 +2062,7 @@ 20.0, 9.0 ], - "id": "2DSEQ_T1_RARE_1_std_PV360_3.6^^^^_1", + "id": "2DSEQ_T1_RARE_1_std_PV360_3.6_1", "imaging_frequency": 400.3807239646813, "is_single_slice": false, "num_slice_packages": 1, @@ -2119,7 +2119,7 @@ 3.3552416637796436 ] }, - "2DSEQ_T2_TurboRARE_1_std_PV360_3.6^^^^_1": { + "2DSEQ_T2_TurboRARE_1_std_PV360_3.6_1": { "TE": 33, "TR": 2500, "affine": [ @@ -2161,7 +2161,7 @@ 20.0, 8.999999999999993 ], - "id": "2DSEQ_T2_TurboRARE_1_std_PV360_3.6^^^^_1", + "id": "2DSEQ_T2_TurboRARE_1_std_PV360_3.6_1", "imaging_frequency": 400.3807239646813, "is_single_slice": false, "num_slice_packages": 1, @@ -2218,7 +2218,7 @@ 3.7060712879070272 ] }, - "2DSEQ_T2map_MSME_1_std_PV360_3.6^^^^_1": { + "2DSEQ_T2map_MSME_1_std_PV360_3.6_1": { "TE": [ 8, 16, @@ -2273,7 +2273,7 @@ 20.0, 6.500000000000002 ], - "id": "2DSEQ_T2map_MSME_1_std_PV360_3.6^^^^_1", + "id": "2DSEQ_T2map_MSME_1_std_PV360_3.6_1", "imaging_frequency": 400.3807239646813, "is_single_slice": false, "num_slice_packages": 1, @@ -2424,7 +2424,7 @@ 9.175818853906016 ] }, - "2DSEQ_T2map_MSME_2_std_PV360_3.6^^^^_1": { + "2DSEQ_T2map_MSME_2_std_PV360_3.6_1": { "TE": 8, "TR": 2200, "affine": [ @@ -2467,7 +2467,7 @@ 20.0, 6.500000000000002 ], - "id": "2DSEQ_T2map_MSME_2_std_PV360_3.6^^^^_1", + "id": "2DSEQ_T2map_MSME_2_std_PV360_3.6_1", "imaging_frequency": 400.3807239646813, "is_single_slice": false, "num_slice_packages": 1, @@ -2568,7 +2568,7 @@ 1 ] }, - "2DSEQ_T2star_FID_EPI_1_std_PV360_3.6^^^^_1": { + "2DSEQ_T2star_FID_EPI_1_std_PV360_3.6_1": { "TE": 24.5, "TR": 2000, "affine": [ @@ -2610,7 +2610,7 @@ 20.0, 6.25 ], - "id": "2DSEQ_T2star_FID_EPI_1_std_PV360_3.6^^^^_1", + "id": "2DSEQ_T2star_FID_EPI_1_std_PV360_3.6_1", "imaging_frequency": 400.38072797888503, "is_single_slice": false, "num_slice_packages": 1, @@ -2659,7 +2659,7 @@ 44.029659425184775 ] }, - "2DSEQ_T2star_map_MGE_1_std_PV360_3.6^^^^_1": { + "2DSEQ_T2star_map_MGE_1_std_PV360_3.6_1": { "TE": [ 4.5, 10.0, @@ -2711,7 +2711,7 @@ 20, 1 ], - "id": "2DSEQ_T2star_map_MGE_1_std_PV360_3.6^^^^_1", + "id": "2DSEQ_T2star_map_MGE_1_std_PV360_3.6_1", "imaging_frequency": 400.38072797888503, "is_single_slice": true, "num_slice_packages": 1, @@ -2768,7 +2768,7 @@ 3.4421158749619405 ] }, - "2DSEQ_T2star_map_MGE_2_std_PV360_3.6^^^^_1": { + "2DSEQ_T2star_map_MGE_2_std_PV360_3.6_1": { "TE": [ 4.5, 4.5, @@ -2825,7 +2825,7 @@ 20, 1 ], - "id": "2DSEQ_T2star_map_MGE_2_std_PV360_3.6^^^^_1", + "id": "2DSEQ_T2star_map_MGE_2_std_PV360_3.6_1", "imaging_frequency": 400.38072797888503, "is_single_slice": true, "num_slice_packages": 1, @@ -2878,7 +2878,7 @@ 1 ] }, - "2DSEQ_T2star_map_MGE_mod_all_1_std_PV360_3.6^^^^_3": { + "2DSEQ_T2star_map_MGE_mod_all_1_std_PV360_3.6_3": { "TE": [ 3.5, 8.5, @@ -2930,7 +2930,7 @@ 20.0, 0.8 ], - "id": "2DSEQ_T2star_map_MGE_mod_all_1_std_PV360_3.6^^^^_3", + "id": "2DSEQ_T2star_map_MGE_mod_all_1_std_PV360_3.6_3", "imaging_frequency": 400.3322244201979, "is_single_slice": true, "num_slice_packages": 1, @@ -2987,7 +2987,7 @@ 0.9648777393544125 ] }, - "2DSEQ_T2star_map_MGE_mod_all_2_std_PV360_3.6^^^^_3": { + "2DSEQ_T2star_map_MGE_mod_all_2_std_PV360_3.6_3": { "TE": [ 3.5, 3.5, @@ -3044,7 +3044,7 @@ 20.0, 0.8 ], - "id": "2DSEQ_T2star_map_MGE_mod_all_2_std_PV360_3.6^^^^_3", + "id": "2DSEQ_T2star_map_MGE_mod_all_2_std_PV360_3.6_3", "imaging_frequency": 400.3322244201979, "is_single_slice": true, "num_slice_packages": 1, @@ -3097,7 +3097,7 @@ 1 ] }, - "2DSEQ_T2star_map_MGE_mod_pos_1_std_PV360_3.6^^^^_3": { + "2DSEQ_T2star_map_MGE_mod_pos_1_std_PV360_3.6_3": { "TE": [ 3.5, 8.5, @@ -3149,7 +3149,7 @@ 20.0, 0.8 ], - "id": "2DSEQ_T2star_map_MGE_mod_pos_1_std_PV360_3.6^^^^_3", + "id": "2DSEQ_T2star_map_MGE_mod_pos_1_std_PV360_3.6_3", "imaging_frequency": 400.3322244201979, "is_single_slice": true, "num_slice_packages": 1, @@ -3206,7 +3206,7 @@ 0.9597664168090889 ] }, - "2DSEQ_T2star_map_MGE_mod_pos_2_std_PV360_3.6^^^^_3": { + "2DSEQ_T2star_map_MGE_mod_pos_2_std_PV360_3.6_3": { "TE": [ 3.5, 3.5, @@ -3263,7 +3263,7 @@ 20.0, 0.8 ], - "id": "2DSEQ_T2star_map_MGE_mod_pos_2_std_PV360_3.6^^^^_3", + "id": "2DSEQ_T2star_map_MGE_mod_pos_2_std_PV360_3.6_3", "imaging_frequency": 400.3322244201979, "is_single_slice": true, "num_slice_packages": 1, @@ -3316,7 +3316,7 @@ 1 ] }, - "2DSEQ_UTE3D_1_std_PV360_3.6^^^^_1": { + "2DSEQ_UTE3D_1_std_PV360_3.6_1": { "TE": 0.006883333333333333, "TR": 2.3, "affine": [ @@ -3359,7 +3359,7 @@ 25, 25 ], - "id": "2DSEQ_UTE3D_1_std_PV360_3.6^^^^_1", + "id": "2DSEQ_UTE3D_1_std_PV360_3.6_1", "imaging_frequency": 400.38072797888503, "is_single_slice": false, "num_slice_packages": 1, diff --git a/test/synthetic.py b/test/synthetic.py index 3046e28..b852aa2 100644 --- a/test/synthetic.py +++ b/test/synthetic.py @@ -153,6 +153,7 @@ def visu_pars_records( "VisuCoreByteOrder": "littleEndian", "VisuSubjectPosition": subject_position, "VisuSubjectName": [""], + "VisuSubjectId": [""], "VisuStudyNumber": 1, } diff --git a/test/test_api.py b/test/test_api.py index 4d52c4e..dd4cd76 100644 --- a/test/test_api.py +++ b/test/test_api.py @@ -15,7 +15,7 @@ from brukerapi.exceptions import UnsupportedDatasetType from brukerapi.folders import Folder from brukerapi.splitters import SlicePackageSplitter -from test.synthetic import stacked_positions, write_2dseq, write_jcampdx +from test.synthetic import Verbatim, stacked_positions, write_2dseq, write_fid, write_jcampdx def study(tmp_path, **kwargs): @@ -70,7 +70,7 @@ def test_metadata_groups_follow_the_specification(tmp_path): def test_metadata_reports_the_same_string_as_the_property_that_reads_it(tmp_path): - """`subj_id` and `metadata` read VisuSubjectName; they must agree. + """`subj_id` and `metadata` read VisuSubjectId; they must agree. `subj_id` stripped the `<...>` delimiters in its recipe, `metadata` -- the newer surface -- did not, so the two APIs reported different values for one @@ -78,8 +78,58 @@ def test_metadata_reports_the_same_string_as_the_property_that_reads_it(tmp_path """ dataset = Dataset(study(tmp_path), load=LOAD_STAGES["properties"]) + assert dataset.metadata["visu_subject"]["id"] == "phantom" + assert dataset.subj_id == dataset.metadata["visu_subject"]["id"] + + +def test_subj_id_is_the_subject_identifier_not_the_subject_name(tmp_path): + """A 2dseq read VisuSubjectName while fid/rawdata/traj read SUBJECT_id (#216). + + ParaVision keeps the two apart -- VisuSubjectName is the DICOM patient + name, `family^given^middle^prefix^suffix` on PV360 -- and VisuSubjectId is + the Visu copy of SUBJECT_id. `subj_id`, and the `id` built from it, must + mean the same thing for every dataset type. + """ + dataset = Dataset(study(tmp_path), add_parameters=["subject"], load=LOAD_STAGES["properties"]) + assert dataset.metadata["visu_subject"]["name"] == "synthetic" - assert dataset.subj_id == dataset.metadata["visu_subject"]["name"] + assert dataset.subj_id == dataset["SUBJECT_id"].value == "phantom" + assert dataset.id == "2DSEQ_8_1_phantom_1" + + +def test_study_id_is_the_study_identifier_and_study_nr_the_number(tmp_path): + """`study_id` read the study *number* for every dataset type (#216). + + ParaVision's study identifier is a different parameter -- VisuStudyId / + SUBJECT_study_name, the user-given string set at study registration -- and + the number is VisuStudyNumber / SUBJECT_study_nr. `id` keeps using the + number, which is what makes it unique within a subject. + """ + root = tmp_path / "20200612_094625_study_1_1" + write_jcampdx(root / "subject", {"SUBJECT_id": [""], "SUBJECT_study_nr": 1, "SUBJECT_study_name": [""]}) + image = Dataset(write_2dseq(root / "8" / "pdata" / "1", extra={"VisuStudyId": [""]}), add_parameters=["subject"], load=LOAD_STAGES["properties"]) + acqp = { + "ACQ_sw_version": [""], + "GO_raw_data_format": "GO_32BIT_SGN_INT", + "GO_block_size": "continuous", + "BYTORDA": "little", + "ACQ_dim": 2, + "ACQ_dim_desc": Verbatim("( 2 )\nSpatial Spatial"), + "ACQ_size": np.array([8, 2]), + "NI": 1, + "NR": 1, + "ACQ_phase_factor": 1, + "PULPROG": [""], + } + method = {"PVM_EncNReceivers": 1, "PVM_EncMatrix": np.array([4, 2]), "PVM_DigNp": 4} + raw = Dataset(write_fid(root / "8", acqp, method), add_parameters=["subject"], load=LOAD_STAGES["properties"]) + + for dataset in (image, raw): + assert dataset.study_id == "TEST_IO" + assert dataset.study_nr == 1 + assert dataset.subj_id == "phantom" + assert image.id == "2DSEQ_8_1_phantom_1" + assert raw.id == "FID_8_phantom_1" def test_get_returns_a_default_where_a_property_does_not_resolve(tmp_path): diff --git a/test/test_property_configs.py b/test/test_property_configs.py index 84293d3..7a3556a 100644 --- a/test/test_property_configs.py +++ b/test/test_property_configs.py @@ -105,8 +105,8 @@ def test_traj_scheme_detection_is_not_version_gated(): def test_traj_custom_properties_define_a_stable_id(): traj = _load_config("properties_traj_custom.json") - assert [*traj] == ["subj_id", "study_id", "exp_id", "id"] - assert traj["id"][0]["cmd"] == "'Traj_{}*{}*{}'.format(@exp_id, @subj_id, @study_id)" + assert [*traj] == ["subj_id", "study_id", "study_nr", "exp_id", "id"] + assert traj["id"][0]["cmd"] == "'Traj_{}*{}*{}'.format(@exp_id, @subj_id, @study_nr)" def test_fid_scheme_config_keeps_exact_matches_before_code_fallback():