Skip to content

Commit d131c4c

Browse files
committed
ENH: added additional json output flag
ENH: invalid volume flag added to make empty dict for invalid series/volumes
1 parent e0230de commit d131c4c

File tree

1 file changed

+123
-7
lines changed

1 file changed

+123
-7
lines changed

scripts/classify_study.py

Lines changed: 123 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python3
22

33
import argparse
4+
import json
45
import shutil
56
import sys
67
from typing import Any
@@ -12,6 +13,7 @@
1213
try:
1314
from dcm_classifier.study_processing import ProcessOneDicomStudyToVolumesMappingBase
1415
from dcm_classifier.image_type_inference import ImageTypeClassifierBase
16+
from dcm_classifier.dicom_config import required_DICOM_fields, optional_DICOM_fields
1517
except Exception as e:
1618
print(f"Missing module import {e}")
1719
print(
@@ -61,6 +63,13 @@ def main():
6163
default=None,
6264
help="Path to the output the newly organized dicom data",
6365
)
66+
parser.add_argument(
67+
"-j",
68+
"--json",
69+
required=False,
70+
default=None,
71+
help="Path to the output json file",
72+
)
6473

6574
args = parser.parse_args()
6675

@@ -88,45 +97,141 @@ def main():
8897
list_of_inputs: list[dict[str, Any]] = []
8998
list_of_probabilities: list[pd.DataFrame] = []
9099
list_of_dictionaries: list[dict[str, str]] = []
100+
session_dictionary: dict[str, Any] = {}
91101

92102
for series_number, series in study.series_dictionary.items():
93103
for index, volume in enumerate(series.get_volume_list()):
104+
invalid_volume: bool = False
94105
current_dict: dict[str, str] = ordered_dict()
95106
current_dict["Series#"] = str(series_number)
107+
dict_entry_name: str | None = None
108+
dictionary = {}
109+
110+
# Volume Index
96111
try:
97-
current_dict["Vol.#"] = str(volume.get_volume_index())
112+
vol_index: str = str(volume.get_volume_index())
113+
current_dict["Vol.#"] = vol_index
114+
dict_entry_name: str = f"{series_number}_{vol_index}"
98115
except AttributeError:
99116
current_dict["Vol.#"] = "None"
117+
118+
# Volume Modality
100119
try:
101-
current_dict["Volume Modality"] = str(volume.get_volume_modality())
120+
vol_modality: str = str(volume.get_volume_modality())
121+
current_dict["Volume Modality"] = vol_modality
122+
if vol_modality != "INVALID":
123+
dictionary["VolumeModality"] = vol_modality
124+
else:
125+
invalid_volume = True
102126
except AttributeError:
103127
current_dict["Volume Modality"] = "None"
128+
dictionary = {}
129+
130+
# Series Modality
104131
try:
105-
current_dict["Series Modality"] = str(series.get_series_modality())
132+
series_modality: str = str(series.get_series_modality())
133+
current_dict["Series Modality"] = series_modality
134+
dictionary["SeriesModality"] = series_modality if dictionary else {}
106135
except AttributeError:
107136
current_dict["Series Modality"] = "None"
137+
dictionary = {}
138+
139+
# Acquisition Plane
108140
try:
109-
current_dict["Acq.Plane"] = str(volume.get_acquisition_plane())
141+
acq_plane: str = str(volume.get_acquisition_plane())
142+
current_dict["Acq.Plane"] = acq_plane
143+
dictionary["AcqPlane"] = acq_plane if dictionary else {}
110144
except AttributeError:
111145
current_dict["Acq.Plane"] = "None"
146+
dictionary = {}
147+
148+
# Isotropic
112149
try:
113-
current_dict["Isotropic"] = str(volume.get_is_isotropic())
150+
isotropic: str = str(volume.get_is_isotropic())
151+
current_dict["Isotropic"] = isotropic
152+
dictionary["Isotropic"] = isotropic if dictionary else {}
114153
except AttributeError:
115154
current_dict["Isotropic"] = "None"
155+
dictionary["Isotropic"] = "None"
156+
157+
# Modality Probabilities
116158
vol_probabilities = volume.get_modality_probabilities()
159+
for col in vol_probabilities.columns:
160+
# current_dict[col] = str(vol_probabilities[col].values[0])
161+
if "SeriesNumber" in col or "CODE" in col:
162+
continue
163+
dictionary[col] = (
164+
str(vol_probabilities[col].values[0]) if dictionary else {}
165+
)
117166
print(vol_probabilities.to_string(index=False))
167+
168+
# Bvalue
118169
try:
119-
current_dict["Bvalue"] = str(volume.get_volume_bvalue())
170+
bval = str(volume.get_volume_bvalue())
171+
current_dict["Bvalue"] = bval
172+
dictionary["Bvalue"] = bval if dictionary else {}
120173
except AttributeError:
121174
current_dict["Bvalue"] = "None"
175+
dictionary["Bvalue"] = "None"
176+
177+
# Series Description
122178
try:
123-
current_dict["SeriesDesc"] = volume.get_dicom_field_by_name(
179+
series_description: str = volume.get_dicom_field_by_name(
124180
"SeriesDescription"
125181
)
182+
current_dict["SeriesDesc"] = series_description
183+
dictionary["SeriesDescription"] = (
184+
series_description if dictionary else {}
185+
)
126186
except AttributeError:
127187
current_dict["SeriesDesc"] = "None"
188+
dictionary["SeriesDescription"] = "None"
189+
190+
# Contrast Agent
191+
try:
192+
contrast = volume.get_has_contrast()
193+
dictionary["Contrast"] = str(contrast) if dictionary else {}
194+
195+
if contrast:
196+
contrast_agent = volume.get_contrast_agent()
197+
# current_dict["ContrastAgent"] = contrast_agent
198+
dictionary["ContrastAgent"] = contrast_agent if dictionary else {}
199+
else:
200+
# current_dict["Contrast"] = "None"
201+
dictionary["Contrast"] = "None"
202+
except AttributeError:
203+
# current_dict["Contrast"] = "None"
204+
dictionary["Contrast"] = "None"
205+
206+
# Pixel Spacing
207+
try:
208+
pixel_spacing = volume.get_dicom_field_by_name("PixelSpacing")
209+
# current_dict["PixelSpacing"] = pixel_spacing
210+
dictionary["PixelSpacing_0"] = (
211+
str(pixel_spacing[0]) if dictionary else {}
212+
)
213+
dictionary["PixelSpacing_1"] = (
214+
str(pixel_spacing[1]) if dictionary else {}
215+
)
216+
except AttributeError:
217+
# current_dict["PixelSpacing"] = "None"
218+
dictionary["PixelSpacing_0"] = "None"
219+
dictionary["PixelSpacing_1"] = "None"
220+
221+
for field in required_DICOM_fields:
222+
if field in ["PixelSpacing", "ImageType"]:
223+
continue
224+
try:
225+
value = volume.get_dicom_field_by_name(field)
226+
# current_dict[field] = str(value)
227+
dictionary[field] = str(value) if dictionary else {}
228+
except AttributeError:
229+
# current_dict[field] = "None"
230+
dictionary[field] = "None"
231+
128232
inputs_df: dict[str, Any] = volume.get_volume_dictionary()
129233
current_dict["ImageType"] = str(inputs_df.get("ImageType", "Unknown"))
234+
dictionary["ImageType"] = str(inputs_df.get("ImageType", "Unknown"))
130235
for unwanted in [
131236
"FileName",
132237
"StudyInstanceUID",
@@ -170,6 +275,17 @@ def main():
170275
print(f"Copying {dcm_file} to {output_file_path}")
171276
shutil.copy(dcm_file, output_file_path, follow_symlinks=True)
172277
# shutil.move(dcm_file, output_file_path)
278+
if dict_entry_name is not None:
279+
session_dictionary[dict_entry_name] = (
280+
dictionary if not invalid_volume else {} # set to empty if invalid
281+
)
282+
283+
json_output_dict: dict[str, Any] = {str(args.session_directory): session_dictionary}
284+
285+
# save the dictionary to a file
286+
if args.json is not None:
287+
with open(args.json, "w") as f:
288+
json.dump(json_output_dict, f, indent=4)
173289

174290
df: pd.DataFrame = pd.DataFrame(list_of_dictionaries)
175291
df.sort_values(by=["Series#", "Vol.#"], inplace=True)

0 commit comments

Comments
 (0)