Skip to content

Commit

Permalink
run anon pipeline in the plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
Sandip117 committed Dec 12, 2024
1 parent a6d35c0 commit b5a22d6
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 3 deletions.
22 changes: 22 additions & 0 deletions base_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from abc import ABC, abstractmethod

class BaseClient(ABC):
@abstractmethod
def create_con(self, params: dict):
pass

@abstractmethod
def pacs_pull(self):
pass

@abstractmethod
def anonymize(self, dicom_dir: str, params: str, pv_id: int):
pass

@abstractmethod
def pacs_push(self):
pass

@abstractmethod
def health_check(self):
pass
80 changes: 80 additions & 0 deletions chrisClient.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
### Python Chris Client Implementation ###

from base_client import BaseClient
from chrisclient import client
from chris_pacs_service import PACSClient
import json
import time
from loguru import logger
import sys

LOG = logger.debug

logger_format = (
"<green>{time:YYYY-MM-DD HH:mm:ss}</green> │ "
"<level>{level: <5}</level> │ "
"<yellow>{name: >28}</yellow>::"
"<cyan>{function: <30}</cyan> @"
"<cyan>{line: <4}</cyan> ║ "
"<level>{message}</level>"
)
logger.remove()
logger.add(sys.stderr, format=logger_format)

class ChrisClient(BaseClient):
def __init__(self, url: str, username: str, password: str):
self.cl = client.Client(url, username, password)
self.cl.pacs_series_url = f"{url}pacs/series/"
self.req = PACSClient(self.cl.pacs_series_url,username,password)

def create_con(self,params:dict):
return self.cl

def health_check(self):
return self.cl.get_chris_instance()

def pacs_pull(self):
pass
def pacs_push(self):
pass

def anonymize(self, dicom_dir: str, tag_struct: str, pv_id: int):

pl_id = self.__get_plugin_id({"name": "pl-dsdircopy", "version": "1.0.2"})
pl_sub_id = self.__get_plugin_id({"name": "pl-pfdicom_tagsub", "version": "3.3.4"})
pl_dcm_id = self.__get_plugin_id({"name": "pl-orthanc_push", "version": "1.2.7"})

# 1) Run dircopy
# empty directory check
if len(dicom_dir) == 0:
LOG(f"No directory found in CUBE containing files for search : {tag_struct}")
return
pv_in_id = self.__create_feed(pl_id, {"previous_id": pv_id, 'dir': dicom_dir})

# 2) Run anonymization
data = {"previous_id": pv_in_id, "tagStruct": tag_struct, 'fileFilter': '.dcm'}
tag_sub_id = self.__create_feed(pl_sub_id, data)

# 3) Push results
dir_send_data = {
"previous_id": tag_sub_id,
'inputFileFilter': "**/*dcm",
"orthancUrl": params["push"]["url"],
"username":params["push"]["username"],
"password": params["push"]["password"],
"pushToRemote": params["push"]["aec"]
}
pl_inst_id = self.__create_feed(pl_dcm_id, dir_send_data)

def __create_feed(self, plugin_id: str,params: dict):
response = self.cl.create_plugin_instance(plugin_id, params)
return response['id']

def __get_plugin_id(self, params: dict):
response = self.cl.get_plugins(params)
if response['total'] > 0:
return response['data'][0]['id']
raise Exception(f"No plugin found with matching search criteria {params}")



33 changes: 32 additions & 1 deletion chris_pacs_service.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
from chrisclient import client
import requests
from chrisclient import client, request
from loguru import logger
import sys

LOG = logger.debug

logger_format = (
"<green>{time:YYYY-MM-DD HH:mm:ss}</green> │ "
"<level>{level: <5}</level> │ "
"<yellow>{name: >28}</yellow>::"
"<cyan>{function: <30}</cyan> @"
"<cyan>{line: <4}</cyan> ║ "
"<level>{message}</level>"
)
logger.remove()
logger.add(sys.stderr, format=logger_format)


class PACSClient(object):
def __init__(self, url: str, username: str, password: str):
self.cl = client.Client(url, username, password)
self.cl.pacs_series_url = f"{url}pacs/series/"
self.req = request.Request(username, password)

def get_pacs_registered(self, params: dict):
"""
Expand All @@ -15,3 +32,17 @@ def get_pacs_registered(self, params: dict):
if response:
return response['total']
raise Exception(f"No PACS details with matching search criteria {params}")

def get_pacs_files(self, params: dict):
"""
Get PACS folder path
"""
l_dir_path = set()
resp = self.req.get(f"{self.cl.pacs_series_url}search", params)
for item in resp.items:
for link in item.links:
folder = self.req.get(link.href)
for item_folder in folder.items:
path = item_folder.data.path.value
l_dir_path.add(path)
return ','.join(l_dir_path)
38 changes: 37 additions & 1 deletion reg_chxr.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from chris_pacs_service import PACSClient
from loguru import logger
from chris_plugin import chris_plugin, PathMapper
from chrisClient import ChrisClient
import time
import json
import copy
Expand Down Expand Up @@ -44,6 +45,11 @@
default="http://localhost:8000/api/v1/",
help="CUBE URL"
)
parser.add_argument(
"--pluginInstanceID",
default="",
help="plugin instance ID from which to start analysis",
)
parser.add_argument(
"--CUBEuser",
default="chris",
Expand All @@ -60,7 +66,12 @@
type=str,
help='JSON file containing DICOM data to be retrieved'
)

parser.add_argument(
'--tagStruct',
default='',
type=str,
help='directive to use to anonymize DICOMs'
)
parser.add_argument('-V', '--version', action='version',
version=f'%(prog)s {__version__}')

Expand Down Expand Up @@ -97,10 +108,12 @@ def main(options: Namespace, inputdir: Path, outputdir: Path):
#
# Refer to the documentation for more options, examples, and advanced uses e.g.
# adding a progress bar and parallelism.
if not health_check(options): return

cube_cl = PACSClient(options.CUBEurl, options.CUBEuser, options.CUBEpassword)
mapper = PathMapper.file_mapper(inputdir, outputdir, glob=options.inputJSONfile)
for input_file, output_file in mapper:

# Open and read the JSON file
with open(input_file, 'r') as file:
data = json.load(file)
Expand Down Expand Up @@ -128,6 +141,11 @@ def main(options: Namespace, inputdir: Path, outputdir: Path):
if registered_file_count == 0:
raise Exception(f"PACS file registration unsuccessful. Please try again.")
LOG(f"{registered_file_count} files were successfully registered to CUBE.")
dicom_dir = cube_cl.get_pacs_files(pacs_search_params)

# create connection object
cube_con = ChrisClient(options.CUBEurl, options.CUBEuser, options.CUBEpassword)
cube_con.anonymize(dicom_dir, options.tagStruct, options.pluginInstanceID)


def sanitize_for_cube(series: dict) -> dict:
Expand All @@ -139,6 +157,24 @@ def sanitize_for_cube(series: dict) -> dict:
params["StudyInstanceUID"] = series["StudyInstanceUID"]
return params

def health_check(options) -> bool:
"""
check if connections to pfdcm, orthanc, and CUBE is valid
"""
try:
if not options.pluginInstanceID:
options.pluginInstanceID = os.environ['CHRIS_PREV_PLG_INST_ID']
except Exception as ex:
LOG(ex)
return False
try:
# create connection object
cube_con = ChrisClient(options.CUBEurl, options.CUBEuser, options.CUBEpassword)
cube_con.health_check()
except Exception as ex:
LOG(ex)
return False
return True


if __name__ == '__main__':
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def get_version(rel_path: str) -> str:
author='FNNDSC',
author_email='[email protected]',
url='https://github.com/FNNDSC/pl-reg_',
py_modules=['reg_chxr','chris_pacs_service'],
py_modules=['reg_chxr','chris_pacs_service','base_client','chrisClient'],
install_requires=['chris_plugin'],
license='MIT',
entry_points={
Expand Down

0 comments on commit b5a22d6

Please sign in to comment.