-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcomplexity_metrics_analysis.py
More file actions
63 lines (51 loc) · 2.16 KB
/
Copy pathcomplexity_metrics_analysis.py
File metadata and controls
63 lines (51 loc) · 2.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import argparse
import pydicom
from analysis_batch import process_batch
from analysis_exports import DUAL_MLC_CSV_HEADER, build_dual_mlc_row
from analysis_logging import configure_logging
from DicomParse.utilities import retrieve_dcm_filenames
from ucomx_models import AnalysisMode
def build_parser():
parser = argparse.ArgumentParser(description="Batch export complexity metrics for dual-MLC plans.")
parser.add_argument("--input-dir", required=True, help="Directory containing RT Plan DICOM files.")
parser.add_argument("--output-csv", required=True, help="Output CSV file path.")
parser.add_argument(
"--recursive",
action="store_true",
help="Recursively search for DICOM files under the input directory.",
)
parser.add_argument("--verbose", action="store_true", help="Enable debug logging.")
return parser
def main():
args = build_parser().parse_args()
logger = configure_logging(args.verbose)
filepaths = retrieve_dcm_filenames(args.input_dir, recursive=args.recursive)
def precheck(logger, pfile):
try:
ds = pydicom.dcmread(pfile, force=True)
except Exception as exc:
logger.exception("Skipping file due to DICOM read failure %s: %s", pfile, exc)
return False
if 'Modality' not in ds or 'RTPlanName' not in ds:
logger.warning("Skipping file missing Modality/RTPlanName: %s", pfile)
return False
if str(ds.Modality).upper() != 'RTPLAN' or 'reconstructed' in str(ds.RTPlanName).lower():
logger.warning("Skipping non-target RT Plan file: %s", pfile)
return False
return True
def metadata_filter(metadata):
if metadata["beam_type"] not in ["STATIC", "DYNAMIC"]:
return f"unsupported beam type {metadata['beam_type']}"
return None
process_batch(
logger=logger,
filepaths=filepaths,
output_csv=args.output_csv,
header=DUAL_MLC_CSV_HEADER,
build_row=build_dual_mlc_row,
metadata_filter=metadata_filter,
precheck=precheck,
requested_mode=AnalysisMode.VMAT_IMRT,
)
if __name__ == '__main__':
main()