22from pathlib import Path
33import pydicom
44import sys
5+ from collections import Counter
56from fileformats .core import SampleFileGenerator
67from medimages4tests .dummy .raw .pet .siemens .biograph_vision .vr20b .pet_listmode import (
78 get_data as get_pet_listmode_data ,
89)
910from medimages4tests .dummy .raw .pet .siemens .biograph_vision .vr20b .pet_countrate import (
1011 get_data as get_pet_countrate_data ,
1112)
13+ from medimages4tests .dummy .raw .pet .siemens .biograph_vision .vr20b .pet_em_sino import (
14+ get_data as get_pet_sinogram_data ,
15+ )
16+ from medimages4tests .dummy .raw .pet .siemens .biograph_vision .vr20b .pet_calibration import (
17+ get_data as get_pet_calibration_data ,
18+ )
19+ from medimages4tests .dummy .raw .pet .siemens .biograph_vision .vr20b .pet_dynamics_sino import (
20+ get_data as get_pet_dynamics_sino_data ,
21+ )
22+ from medimages4tests .dummy .raw .pet .siemens .biograph_vision .vr20b .pet_replay_param import (
23+ get_data as get_pet_replay_param_data ,
24+ )
25+ from medimages4tests .dummy .raw .pet .siemens .biograph_vision .vr20b .petct_spl import (
26+ get_data as get_petct_spl_data ,
27+ )
1228from fileformats .core import extra_implementation , FileSet
1329from fileformats .medimage .dicom import DicomImage
1430from fileformats .medimage .raw import (
31+ Vnd_Siemens_Biograph128Vision_Vr20b_PetRawData ,
1532 Vnd_Siemens_Biograph128Vision_Vr20b_LargePetRawData ,
16- Vnd_Siemens_Biograph128Vision_Vr20b_PetCountRate ,
1733 Vnd_Siemens_Biograph128Vision_Vr20b_PetListMode ,
18- Vnd_Siemens_Biograph128Vision_Vr20b_PetCtRawData ,
34+ Vnd_Siemens_Biograph128Vision_Vr20b_PetSinogram ,
35+ Vnd_Siemens_Biograph128Vision_Vr20b_PetDynamicSinogramSeries ,
36+ Vnd_Siemens_Biograph128Vision_Vr20b_PetCountRate ,
37+ Vnd_Siemens_Biograph128Vision_Vr20b_PetNormalisation ,
38+ Vnd_Siemens_Biograph128Vision_Vr20b_PetParameterisation ,
39+ Vnd_Siemens_Biograph128Vision_Vr20b_PetCtSplRawData ,
1940)
2041from fileformats .core .io import BinaryIOWindow
2142
@@ -49,9 +70,26 @@ def siemens_pet_raw_data_read_metadata(
4970 return DicomImage .pydicom_to_dict (dcm )
5071
5172
73+ @extra_implementation (Vnd_Siemens_Biograph128Vision_Vr20b_PetRawData .load_pydicom )
74+ def siemens_pet_raw_data_load_pydicom (
75+ pet_raw_data : Vnd_Siemens_Biograph128Vision_Vr20b_LargePetRawData ,
76+ specific_tags : ty .Optional [TagListType ] = None ,
77+ ** kwargs : ty .Any ,
78+ ) -> pydicom .Dataset :
79+
80+ with pet_raw_data .open () as f :
81+ window = BinaryIOWindow (
82+ f , # type: ignore[arg-type]
83+ pet_raw_data .dicom_header_offset ,
84+ pet_raw_data .dcm_hdr_size_int_offset ,
85+ )
86+ dcm = pydicom .dcmread (window , specific_tags = specific_tags )
87+ return dcm
88+
89+
5290@extra_implementation (FileSet .read_metadata )
5391def siemens_petct_raw_data_read_metadata (
54- pet_raw_data : Vnd_Siemens_Biograph128Vision_Vr20b_PetCtRawData ,
92+ pet_raw_data : Vnd_Siemens_Biograph128Vision_Vr20b_PetCtSplRawData ,
5593 specific_tags : ty .Optional [TagListType ] = None ,
5694 ** kwargs : ty .Any ,
5795) -> ty .Mapping [str , ty .Any ]:
@@ -65,6 +103,59 @@ def siemens_petct_raw_data_read_metadata(
65103 return DicomImage .pydicom_to_dict (dcm )
66104
67105
106+ @extra_implementation (Vnd_Siemens_Biograph128Vision_Vr20b_PetRawData .load_pydicom )
107+ def siemens_petct_raw_data_load_pydicom (
108+ pet_raw_data : Vnd_Siemens_Biograph128Vision_Vr20b_PetCtSplRawData ,
109+ specific_tags : ty .Optional [TagListType ] = None ,
110+ ** kwargs : ty .Any ,
111+ ) -> pydicom .Dataset :
112+
113+ with pet_raw_data .open () as f :
114+ window = BinaryIOWindow (
115+ f , # type: ignore[arg-type]
116+ * pet_raw_data .dicom_header_limits ,
117+ )
118+ dcm = pydicom .dcmread (window , specific_tags = specific_tags )
119+ return dcm
120+
121+
122+ @extra_implementation (FileSet .read_metadata )
123+ def siemens_pet_dynamic_sinogram_series_read_metadata (
124+ pet_raw_data : Vnd_Siemens_Biograph128Vision_Vr20b_PetDynamicSinogramSeries ,
125+ specific_tags : ty .Optional [TagListType ] = None ,
126+ ** kwargs : ty .Any ,
127+ ) -> ty .Mapping [str , ty .Any ]:
128+
129+ # Collated DICOM headers across series
130+ collated : ty .Dict [str , ty .Any ] = {}
131+ key_repeats : ty .Counter [str ] = Counter ()
132+ varying_keys = set ()
133+ # We use the "contents" property implementation in TypeSet instead of the overload
134+ # in DicomCollection because we don't want the metadata to be read ahead of the
135+ # the `select_metadata` call below
136+
137+ for ptd in pet_raw_data .contents :
138+ for key , val in ptd .metadata .items ():
139+ try :
140+ prev_val = collated [key ]
141+ except KeyError :
142+ collated [
143+ key
144+ ] = val # Insert initial value (should only happen on first iter)
145+ key_repeats .update ([key ])
146+ else :
147+ if key in varying_keys :
148+ collated [key ].append (val )
149+ # Check whether the value is the same as the values in the previous
150+ # images in the series
151+ elif val != prev_val :
152+ collated [key ] = [prev_val ] * key_repeats [key ] + [val ]
153+ varying_keys .add (key )
154+ else :
155+ key_repeats .update ([key ])
156+ return collated
157+
158+
68159@extra_implementation (FileSet .generate_sample_data )
69160def siemens_pet_listmode_generate_sample_data (
70161 pet_raw_data : Vnd_Siemens_Biograph128Vision_Vr20b_PetListMode ,
@@ -79,3 +170,43 @@ def siemens_pet_countrate_generate_sample_data(
79170 generator : SampleFileGenerator ,
80171) -> ty .List [Path ]:
81172 return get_pet_countrate_data (out_dir = generator .dest_dir ) # type: ignore[no-any-return]
173+
174+
175+ @extra_implementation (FileSet .generate_sample_data )
176+ def siemens_pet_sinogram_generate_sample_data (
177+ pet_raw_data : Vnd_Siemens_Biograph128Vision_Vr20b_PetSinogram ,
178+ generator : SampleFileGenerator ,
179+ ) -> ty .List [Path ]:
180+ return get_pet_sinogram_data (out_dir = generator .dest_dir ) # type: ignore[no-any-return]
181+
182+
183+ @extra_implementation (FileSet .generate_sample_data )
184+ def siemens_pet_dynamics_sino_generate_sample_data (
185+ pet_raw_data : Vnd_Siemens_Biograph128Vision_Vr20b_PetDynamicSinogramSeries ,
186+ generator : SampleFileGenerator ,
187+ ) -> ty .List [Path ]:
188+ return get_pet_dynamics_sino_data (out_dir = generator .dest_dir ) # type: ignore[no-any-return]
189+
190+
191+ @extra_implementation (FileSet .generate_sample_data )
192+ def siemens_pet_normalisation_generate_sample_data (
193+ pet_raw_data : Vnd_Siemens_Biograph128Vision_Vr20b_PetNormalisation ,
194+ generator : SampleFileGenerator ,
195+ ) -> ty .List [Path ]:
196+ return get_pet_calibration_data (out_dir = generator .dest_dir ) # type: ignore[no-any-return]
197+
198+
199+ @extra_implementation (FileSet .generate_sample_data )
200+ def siemens_petct_spl_generate_sample_data (
201+ pet_raw_data : Vnd_Siemens_Biograph128Vision_Vr20b_PetCtSplRawData ,
202+ generator : SampleFileGenerator ,
203+ ) -> ty .List [Path ]:
204+ return get_petct_spl_data (out_dir = generator .dest_dir ) # type: ignore[no-any-return]
205+
206+
207+ @extra_implementation (FileSet .generate_sample_data )
208+ def siemens_pet_parameterisation_generate_sample_data (
209+ pet_raw_data : Vnd_Siemens_Biograph128Vision_Vr20b_PetParameterisation ,
210+ generator : SampleFileGenerator ,
211+ ) -> ty .List [Path ]:
212+ return get_pet_replay_param_data (out_dir = generator .dest_dir ) # type: ignore[no-any-return]
0 commit comments