Skip to content

Commit

Permalink
added visualizations and some more bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Vishwesh4 committed Dec 10, 2021
1 parent 90732d8 commit 735b26c
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 21 deletions.
9 changes: 7 additions & 2 deletions imgtools/autopipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def __init__(self,
modalities="CT",
spacing=(1., 1., 0.),
n_jobs=-1,
visualize=False,
missing_strategy="drop",
show_progress=False,
warn_on_error=False):
Expand All @@ -50,7 +51,7 @@ def __init__(self,
self.existing = [None] #self.existing_patients()

#input operations
self.input = ImageAutoInput(input_directory, modalities, n_jobs)
self.input = ImageAutoInput(input_directory, modalities, n_jobs, visualize)

self.output_df_path = os.path.join(self.output_directory, "dataset.csv")
#Output component table
Expand Down Expand Up @@ -220,7 +221,10 @@ def run(self):

parser.add_argument("--modalities", type=str, default="CT",
help="List of desired modalities. Type as string for ex: RTSTRUCT,CT,RTDOSE")


parser.add_argument("--visualize", type=bool, default=False,
help="Whether to visualize the data graph")

parser.add_argument("--spacing", nargs=3, type=float, default=(1., 1., 0.),
help="The resampled voxel spacing in (x, y, z) directions.")

Expand All @@ -236,6 +240,7 @@ def run(self):
modalities=args.modalities,
spacing=args.spacing,
n_jobs=args.n_jobs,
visualize=args.visualize,
show_progress=args.show_progress)

print(f'starting Pipeline...')
Expand Down
42 changes: 40 additions & 2 deletions imgtools/modules/datagraph.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import os, time
from typing import List
from functools import reduce

import numpy as np
import pandas as pd
from tqdm import tqdm
from pyvis.network import Network


class DataGraph:
'''
Expand All @@ -24,7 +25,8 @@ class DataGraph:
'''
def __init__(self,
path_crawl: str,
edge_path: str = "./patient_id_full_edges.csv") -> None:
edge_path: str = "./patient_id_full_edges.csv",
visualize: bool = False) -> None:
'''
Parameters
----------
Expand All @@ -43,6 +45,8 @@ def __init__(self,
else:
print("Edge table not present. Forming the edge table based on the crawl data...")
self.form_graph()
if visualize:
self.visualize_graph()

def form_graph(self):
'''
Expand Down Expand Up @@ -82,6 +86,40 @@ def form_graph(self):
print(f"Saving edge table in {self.edge_path}")
self.df_edges.to_csv(self.edge_path, index=False)

def visualize_graph(self):
"""
Generates visualization using Pyviz, a wrapper around visJS. The visualization can be found at datanet.html
"""
print("Generating visualizations...")
data_net = Network(height='100%', width='100%', bgcolor='#222222', font_color='white')

sources = self.df_edges["series_y"]
targets = self.df_edges["series_x"]
name_src = self.df_edges["modality_y"]
name_tar = self.df_edges["modality_x"]
patient_id = self.df_edges["patient_ID_x"]
reference_ct = self.df_edges["reference_ct_y"]
reference_rs = self.df_edges["reference_rs_y"]

data_zip = zip(sources,targets,name_src,name_tar,patient_id,reference_ct,reference_rs)

for i in data_zip:
data_net.add_node(i[0],i[2],title=i[2],group=i[4])
data_net.add_node(i[1],i[3],title=i[3],group=i[4])
data_net.add_edge(i[0],i[1])
node = data_net.get_node(i[0])
node["title"] = "<br>Patient_id: {}<br>Series: {}<br>reference_ct: {}<br>reference_rs: {}".format(i[4],i[0],i[5],i[6])
node = data_net.get_node(i[1])
node["title"] = "<br>Patient_id: {}<br>Series: {}<br>reference_ct: {}<br>reference_rs: {}".format(i[4],i[1],i[5],i[6])

neigbour_map = data_net.get_adj_list()
for node in data_net.nodes:
node["title"] += "<br>Number of connections: {}".format(len(neigbour_map[node['id']]))
node["value"] = len(neigbour_map[node['id']])

vis_path = os.path.join(("/").join(self.edge_path.split("/")[:-1]),"datanet.html")
data_net.show(vis_path)

def _form_edge_study(self, df, all_study, study_id):
'''
For a given study id forms edge table
Expand Down
4 changes: 2 additions & 2 deletions imgtools/modules/dose.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ def get_metadata(self):
# DVH specifc properties
doses_bin = np.cumsum(raw_data[0:n:2])
vol = raw_data[1:n:2]
self.dvh[ROI_reference]["dose_bins"] = doses_bin
self.dvh[ROI_reference]["vol"] = vol
self.dvh[ROI_reference]["dose_bins"] = doses_bin.tolist()
self.dvh[ROI_reference]["vol"] = vol.tolist()

# ROI specific properties
tot_vol = np.sum(vol)
Expand Down
4 changes: 2 additions & 2 deletions imgtools/modules/pet.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ def get_metadata(self):
except:
pass
try:
self.metadata["scan_time"] = datetime.datetime.strptime(self.df.AcquisitionTime, '%H%M%S.%f')
self.metadata["injection_time"] = datetime.datetime.strptime(self.df.RadiopharmaceuticalInformationSequence[0].RadiopharmaceuticalStartTime, '%H%M%S.%f')
self.metadata["scan_time"] = datetime.datetime.strptime(self.df.AcquisitionTime, '%H%M%S.%f').__str__()
self.metadata["injection_time"] = datetime.datetime.strptime(self.df.RadiopharmaceuticalInformationSequence[0].RadiopharmaceuticalStartTime, '%H%M%S.%f').__str__()
self.metadata["half_life"] = float(self.df.RadiopharmaceuticalInformationSequence[0].RadionuclideHalfLife)
self.metadata["injected_dose"] = float(self.df.RadiopharmaceuticalInformationSequence[0].RadionuclideTotalDose)
except:
Expand Down
18 changes: 5 additions & 13 deletions imgtools/ops/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,14 @@ class ImageAutoInput(BaseInput):
modalities: str
List of modalities to process. Only samples with ALL modalities will be processed. Make sure there are no space between list elements as it is parsed as a string.
visualize: bool
Whether to return visualization of the data graph
"""
def __init__(self,
dir_path: str,
modalities: str,
n_jobs: int = -1):
n_jobs: int = -1,
visualize: bool = False):
self.dir_path = dir_path
self.modalities = modalities
self.dataset_name = self.dir_path.split("/")[-1]
Expand All @@ -93,24 +96,13 @@ def __init__(self,
####### GRAPH ##########
# Form the graph
edge_path = os.path.join(self.parent,f"imgtools_{self.dataset_name}_edges.csv")
graph = DataGraph(path_crawl=path_crawl,edge_path=edge_path)
graph = DataGraph(path_crawl=path_crawl,edge_path=edge_path,visualize=visualize)
print(f"Forming the graph based on the given modalities: {self.modalities}")
self.df_combined = graph.parser(self.modalities)
self.output_streams = [("_").join(cols.split("_")[1:]) for cols in self.df_combined.columns if cols.split("_")[0]=="folder"]
self.column_names = [cols for cols in self.df_combined.columns if cols.split("_")[0]=="folder"]
self.series_names = [cols for cols in self.df_combined.columns if cols.split("_")[0]=="series"]

#Initilizations for the pipeline
for colnames in self.output_streams:
output_stream = ("_").join([items for items in colnames.split("_") if items!="1"])
modality = colnames.split("_")[0]
if modality in ["PT","CT","RTDOSE"]:
self.df_combined["size_{}".format(output_stream)] = None
if modality!="CT":
self.df_combined["metadata_{}".format(output_stream)] = None
elif modality=="RTSTRUCT":
self.df_combined["roi_names_{}".format(output_stream)] = None

print(f"There are {len(self.df_combined)} cases containing all {modalities} modalities.")

self.readers = [read_dicom_auto for i in range(len(self.output_streams))]
Expand Down

0 comments on commit 735b26c

Please sign in to comment.