Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate warning #175

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@
- <https://playwright.dev/python/docs/auth>
- Unfortunately, we can't use live_server fixture inside session fixtures
- example <https://github.com/automationneemo/PlaywrightDemoYt>
- Get rid of dicom_connector.download_study/move_study. Do everything at the series level. That way filtering series (e.g. exlcude modalities) is much easier.
- Evaluate if services should be better restarted with pywatchman instead of watchdog and watchmedo
- pywatchman is used by Django autoreload
- See <https://github.com/django/django/blob/main/django/utils/autoreload.py>
Expand Down
15 changes: 4 additions & 11 deletions adit/batch_query/processors.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from django.conf import settings
from django.template.defaultfilters import pluralize

from adit.core.errors import DicomError
Expand Down Expand Up @@ -97,15 +96,7 @@ def _find_studies(self, patient_id: str) -> list[ResultDataset]:
end_date = self.query_task.study_date_end
study_date = (start_date, end_date)

modalities_query: list[str] = []
if self.query_task.modalities:
modalities_query = [
modality
for modality in self.query_task.modalities
if modality not in settings.EXCLUDED_MODALITIES
]

if not modalities_query:
if not self.query_task.modalities:
study_results = list(
self.operator.find_studies(
QueryDataset.create(
Expand All @@ -121,7 +112,9 @@ def _find_studies(self, patient_id: str) -> list[ResultDataset]:
else:
seen: set[str] = set()
study_results: list[ResultDataset] = []
for modality in modalities_query:
for modality in self.query_task.modalities:
# ModalitiesInStudy does not support to query multiple modalities at once,
# so we have to query them one by one.
studies = list(
self.operator.find_studies(
QueryDataset.create(
Expand Down
59 changes: 55 additions & 4 deletions adit/core/processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ def _download_to_folder(
download_folder: Path,
) -> Path:
pseudonym = self.transfer_task.pseudonym

if pseudonym:
patient_folder = download_folder / sanitize_filename(pseudonym)
else:
Expand All @@ -160,9 +161,11 @@ def _download_to_folder(
study = self._find_study()
modalities = study.ModalitiesInStudy

modalities = [
modality for modality in modalities if modality not in settings.EXCLUDED_MODALITIES
]
exclude_modalities = settings.EXCLUDE_MODALITIES
if pseudonym and exclude_modalities:
# When we download the study we will exclude the specified modalities, but only
# if we are pseudonymizing the study, see also _download_study().
modalities = [modality for modality in modalities if modality not in exclude_modalities]

# If some series are explicitly chosen then check if their Series Instance UIDs
# are correct and only use those modalities for the name of the study folder.
Expand Down Expand Up @@ -310,16 +313,64 @@ def callback(ds: Dataset | None) -> None:
file_path = final_folder / file_name
write_dataset(ds, file_path)

pseudonymize = bool(self.transfer_task.pseudonym)
exclude_modalities = settings.EXCLUDE_MODALITIES

if series_uids:
# If specific series are selected we transfer only those series. When pseudonymizing
# we have to check if a modality should be excluded.
if pseudonymize and exclude_modalities:
filtered_series = []
for series_uid in series_uids:
series_list = list(
self.source_operator.find_series(
QueryDataset.create(
PatientID=patient_id,
StudyInstanceUID=study_uid,
SeriesInstanceUID=series_uid,
)
)
)
if not series_list:
logger.warning(f"Series with UID {series_uid} not found.")
continue

assert len(series_list) == 1
series = series_list[0]

if series.Modality in exclude_modalities:
continue

filtered_series.append(series)

series_uids = [series.SeriesInstanceUID for series in filtered_series]

for series_uid in series_uids:
self.source_operator.fetch_series(
patient_id=patient_id,
study_uid=study_uid,
series_uid=series_uid,
callback=callback,
)

elif pseudonymize:
# If the whole study should be transferred and pseudonymized, we transfer on the
# series level to exclude the specified modalities.
series_list = list(
self.source_operator.find_series(
QueryDataset.create(PatientID=patient_id, StudyInstanceUID=study_uid)
)
)
for series in series_list:
series_uid = series.SeriesInstanceUID
modality = series.Modality
if modality in settings.EXCLUDE_MODALITIES:
continue

self.source_operator.fetch_series(patient_id, study_uid, series_uid, callback)

else:
# If no series are explicitly chosen then download all series of the study
# Without pseudonymization we transfer the whole study as it is.
self.source_operator.fetch_study(
patient_id=patient_id,
study_uid=study_uid,
Expand Down
7 changes: 0 additions & 7 deletions adit/core/templatetags/core_extras.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import logging

from django.conf import settings
from django.template import Library

from ..models import DicomJob, DicomTask
Expand All @@ -19,12 +18,6 @@ def person_name_from_dicom(value: str) -> str:
return value.replace("^", ", ")


@register.simple_tag
def filter_modalities(modalities: list[str]) -> list[str]:
exclude_modalities = settings.EXCLUDED_MODALITIES
return [modality for modality in modalities if modality not in exclude_modalities]


@register.filter
def dicom_job_status_css_class(status: DicomJob.Status) -> str:
css_classes = {
Expand Down
1 change: 1 addition & 0 deletions adit/core/utils/dicom_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ def create(
SeriesDescription: str | type[_NoValue] = _NoValue,
SeriesNumber: int | str | type[_NoValue] = _NoValue,
Modality: str | type[_NoValue] = _NoValue,
SOPInstanceUID: str | type[_NoValue] = _NoValue,
) -> "QueryDataset":
"""A helper factory method for type hinting query parameters."""
ds = Dataset()
Expand Down
Loading