start removing lots of print
This commit is contained in:
@@ -113,8 +113,6 @@ def get_exam_user_status_cid_user(request, exam_id: int, cid: int):
|
|||||||
if not exam.check_user_can_edit(request.user):
|
if not exam.check_user_can_edit(request.user):
|
||||||
raise HttpError(HTTPStatus.UNAUTHORIZED,"Exam author required")
|
raise HttpError(HTTPStatus.UNAUTHORIZED,"Exam author required")
|
||||||
|
|
||||||
print(exam_id, cid)
|
|
||||||
|
|
||||||
return exam.exam_user_status.filter(cid_user_exam__cid_user__cid=cid)
|
return exam.exam_user_status.filter(cid_user_exam__cid_user__cid=cid)
|
||||||
|
|
||||||
@router.get('/exam/{exam_id}/user_status/{user_id}/user', response=List[ExamStatusSchema])
|
@router.get('/exam/{exam_id}/user_status/{user_id}/user', response=List[ExamStatusSchema])
|
||||||
|
|||||||
@@ -492,7 +492,6 @@ class Exam(ExamBase):
|
|||||||
return answer
|
return answer
|
||||||
|
|
||||||
def get_question_user_user_answer(self, question_index, user):
|
def get_question_user_user_answer(self, question_index, user):
|
||||||
print(user)
|
|
||||||
question = self.get_question_by_index(question_index)
|
question = self.get_question_by_index(question_index)
|
||||||
answer = UserAnswer.objects.filter(question=question, user=user.pk, exam=self)
|
answer = UserAnswer.objects.filter(question=question, user=user.pk, exam=self)
|
||||||
|
|
||||||
|
|||||||
@@ -194,8 +194,6 @@ def test_exams(db, client):
|
|||||||
exam.save()
|
exam.save()
|
||||||
|
|
||||||
res = client.get(exam_metadata["url"])
|
res = client.get(exam_metadata["url"])
|
||||||
print("PRE ERRER", exam_metadata["url"])
|
|
||||||
print(res.content)
|
|
||||||
assert res.status_code == 404
|
assert res.status_code == 404
|
||||||
|
|
||||||
exam.active = True
|
exam.active = True
|
||||||
|
|||||||
@@ -646,22 +646,6 @@ class AnatomyQuestionUpdate(UpdateQuestionMixin):
|
|||||||
context = self.get_context_data(form=form)
|
context = self.get_context_data(form=form)
|
||||||
#formset = context["answer_formset"]
|
#formset = context["answer_formset"]
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
## logger.debug(formset.is_valid())
|
|
||||||
#if formset.is_valid():
|
|
||||||
# response = super().form_valid(form)
|
|
||||||
# formset.instance = self.object
|
|
||||||
# formset.save()
|
|
||||||
|
|
||||||
# # restore exam orders
|
|
||||||
# #for exam in self.object.exams.all():
|
|
||||||
# # if exam in exam_orders and self.object in exam_orders[exam]:
|
|
||||||
# # print(exam_orders[exam])
|
|
||||||
# # exam.exam_questions.set(exam_orders[exam])
|
|
||||||
# # exam.save()
|
|
||||||
|
|
||||||
# return response
|
|
||||||
#else:
|
|
||||||
# return super().form_invalid(form)
|
|
||||||
|
|
||||||
|
|
||||||
class QuestionClone(AnatomyQuestionCreateBase):
|
class QuestionClone(AnatomyQuestionCreateBase):
|
||||||
@@ -797,7 +781,6 @@ def question_save_annotation(request, pk):
|
|||||||
question = get_object_or_404(AnatomyQuestion, pk=pk)
|
question = get_object_or_404(AnatomyQuestion, pk=pk)
|
||||||
|
|
||||||
question.image_annotations = request.POST.get("annotation")
|
question.image_annotations = request.POST.get("annotation")
|
||||||
print(question.image_annotations)
|
|
||||||
|
|
||||||
question.save()
|
question.save()
|
||||||
data = {"status": "success"}
|
data = {"status": "success"}
|
||||||
|
|||||||
+23
-37
@@ -128,15 +128,10 @@ def uncategorised_dicoms(request):
|
|||||||
|
|
||||||
|
|
||||||
def import_dicoms_helper(request, case_id: int | None = None):
|
def import_dicoms_helper(request, case_id: int | None = None):
|
||||||
# TODO: move this out of the api (would be better with HTMX)
|
|
||||||
|
|
||||||
|
|
||||||
# dicoms = UncategorisedDicom.objects.filter(user=request.user)
|
|
||||||
if "selection" in request.POST:
|
if "selection" in request.POST:
|
||||||
dicoms = UncategorisedDicom.objects.filter(
|
dicoms = UncategorisedDicom.objects.filter(
|
||||||
series_instance_uid__in=request.POST.getlist("selection")
|
series_instance_uid__in=request.POST.getlist("selection")
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
dicoms = UncategorisedDicom.objects.filter(user=request.user)
|
dicoms = UncategorisedDicom.objects.filter(user=request.user)
|
||||||
|
|
||||||
@@ -145,33 +140,30 @@ def import_dicoms_helper(request, case_id: int | None = None):
|
|||||||
else:
|
else:
|
||||||
order = None
|
order = None
|
||||||
|
|
||||||
data = defaultdict(list)
|
# Group dicoms by SeriesInstanceUID, but don't keep all tags in memory
|
||||||
for d in dicoms:
|
series_map = {}
|
||||||
|
for d in dicoms.iterator(): # Use iterator() to avoid loading all at once
|
||||||
tags = d.basic_dicom_tags
|
tags = d.basic_dicom_tags
|
||||||
|
series_uid = tags["SeriesInstanceUID"]
|
||||||
|
|
||||||
data[tags["SeriesInstanceUID"]].append((d, tags))
|
if series_uid not in series_map:
|
||||||
|
# Get or create Series and related objects as needed
|
||||||
series_list = []
|
|
||||||
for series_uid in data:
|
|
||||||
# Hmm probably not a good idea to blinding create a modality...
|
|
||||||
try:
|
try:
|
||||||
modality = Modality.objects.get(short_code=tags["Modality"])
|
modality = Modality.objects.get(short_code=tags["Modality"])
|
||||||
except Modality.DoesNotExist:
|
except Modality.DoesNotExist:
|
||||||
modality = Modality.objects.create(short_code=tags["Modality"], modality=tags["Modality"])
|
modality = Modality.objects.create(short_code=tags["Modality"], modality=tags["Modality"])
|
||||||
|
|
||||||
|
series_tags = tags # Save the first tag for this series
|
||||||
tags = data[series_uid][0][1]
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
series, created = Series.objects.get_or_create(
|
series, created = Series.objects.get_or_create(
|
||||||
series_instance_uid=tags["SeriesInstanceUID"],
|
series_instance_uid=series_uid,
|
||||||
defaults={
|
defaults={
|
||||||
"modality": modality,
|
"modality": modality,
|
||||||
"description": tags["SeriesDescription"],
|
"description": tags.get("SeriesDescription", ""),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if created and tags["StudyDescription"]:
|
if created and tags.get("StudyDescription"):
|
||||||
examination, created_exam = Examination.objects.get_or_create(
|
examination, created_exam = Examination.objects.get_or_create(
|
||||||
examination=tags["StudyDescription"]
|
examination=tags["StudyDescription"]
|
||||||
)
|
)
|
||||||
@@ -181,37 +173,33 @@ def import_dicoms_helper(request, case_id: int | None = None):
|
|||||||
series.examination = examination
|
series.examination = examination
|
||||||
series.save()
|
series.save()
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
# If a race condition still occurs, fetch the existing series
|
series = Series.objects.get(series_instance_uid=series_uid)
|
||||||
pass
|
|
||||||
|
|
||||||
|
# Add author and case if needed
|
||||||
if 'series' not in locals():
|
|
||||||
series = Series.objects.get(series_instance_uid=tags["SeriesInstanceUID"])
|
|
||||||
|
|
||||||
|
|
||||||
# We might only want to add the author during creation....
|
|
||||||
series.author.add(request.user)
|
series.author.add(request.user)
|
||||||
|
|
||||||
if case_id is not None:
|
if case_id is not None:
|
||||||
case_object = get_object_or_404(Case, pk=case_id)
|
case_object = get_object_or_404(Case, pk=case_id)
|
||||||
try:
|
try:
|
||||||
series.case.add(case_object)
|
series.case.add(case_object)
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
# The relation already exists, safe to ignore
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
for dicom, dicom_tags in data[series_uid]:
|
series_map[series_uid] = series
|
||||||
|
else:
|
||||||
|
series = series_map[series_uid]
|
||||||
|
|
||||||
|
# Create and save SeriesImage immediately
|
||||||
series_image = SeriesImage(
|
series_image = SeriesImage(
|
||||||
image=dicom.image,
|
image=d.image,
|
||||||
series=series,
|
series=series,
|
||||||
is_dicom=True,
|
is_dicom=True,
|
||||||
image_blake3_hash=dicom.image_blake3_hash,
|
image_blake3_hash=d.image_blake3_hash,
|
||||||
)
|
)
|
||||||
series_image.save()
|
series_image.save()
|
||||||
# dicom.image.delete()
|
d.delete() # Remove UncategorisedDicom immediately
|
||||||
|
|
||||||
dicom.delete()
|
|
||||||
|
|
||||||
|
# Optionally, re-order series if needed
|
||||||
|
for series in series_map.values():
|
||||||
match order:
|
match order:
|
||||||
case "order-series-instance-number":
|
case "order-series-instance-number":
|
||||||
series.order_by_dicom("InstanceNumber")
|
series.order_by_dicom("InstanceNumber")
|
||||||
@@ -220,9 +208,7 @@ def import_dicoms_helper(request, case_id: int | None = None):
|
|||||||
case _:
|
case _:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
series_list.append((series, series.get_link()))
|
return [(series, series.get_link()) for series in series_map.values()]
|
||||||
|
|
||||||
return series_list
|
|
||||||
|
|
||||||
|
|
||||||
@router.post(
|
@router.post(
|
||||||
|
|||||||
@@ -84,9 +84,6 @@ class CaseSelect(Select):
|
|||||||
def create_option(self, *args, **kwargs):
|
def create_option(self, *args, **kwargs):
|
||||||
option = super().create_option(*args, **kwargs)
|
option = super().create_option(*args, **kwargs)
|
||||||
|
|
||||||
print(option)
|
|
||||||
|
|
||||||
|
|
||||||
return option
|
return option
|
||||||
|
|
||||||
def get_context(self, name: str, value, attrs) -> dict[str, Any]:
|
def get_context(self, name: str, value, attrs) -> dict[str, Any]:
|
||||||
@@ -694,7 +691,6 @@ class CidReportAnswerMarkForm(ModelForm):
|
|||||||
#
|
#
|
||||||
# def __init__(self, *args, user, **kwargs):
|
# def __init__(self, *args, user, **kwargs):
|
||||||
# super(AddCollectionToCaseForm, self).__init__(*args, **kwargs)
|
# super(AddCollectionToCaseForm, self).__init__(*args, **kwargs)
|
||||||
# print("INIT", args, kwargs)
|
|
||||||
#
|
#
|
||||||
# if not user.groups.filter(name="atlas_editor").exists():
|
# if not user.groups.filter(name="atlas_editor").exists():
|
||||||
# queryset = CaseCollection.objects.filter(author__id=user.id)
|
# queryset = CaseCollection.objects.filter(author__id=user.id)
|
||||||
@@ -736,7 +732,6 @@ class AddCollectionToCaseForm(Form):
|
|||||||
|
|
||||||
def __init__(self, *args, user, **kwargs):
|
def __init__(self, *args, user, **kwargs):
|
||||||
super(AddCollectionToCaseForm, self).__init__(*args, **kwargs)
|
super(AddCollectionToCaseForm, self).__init__(*args, **kwargs)
|
||||||
print("INIT", args, kwargs)
|
|
||||||
|
|
||||||
if not user.groups.filter(name="atlas_editor").exists():
|
if not user.groups.filter(name="atlas_editor").exists():
|
||||||
queryset = CaseCollection.objects.filter(author__id=user.id)
|
queryset = CaseCollection.objects.filter(author__id=user.id)
|
||||||
@@ -752,21 +747,16 @@ class AddCollectionToCaseForm(Form):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
print("SAVE", args, kwargs)
|
|
||||||
instance = super(AddCollectionToCaseForm, self).save(*args, **kwargs)
|
instance = super(AddCollectionToCaseForm, self).save(*args, **kwargs)
|
||||||
|
|
||||||
# Here we save the modified project selection back into the database
|
# Here we save the modified project selection back into the database
|
||||||
instance.casecollection_set.set(self.cleaned_data['casecollection'])
|
instance.casecollection_set.set(self.cleaned_data['casecollection'])
|
||||||
|
|
||||||
print(f"{instance=}")
|
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def clean_casecollection(self):
|
def clean_casecollection(self):
|
||||||
collection_set = self.cleaned_data["casecollection"]
|
collection_set = self.cleaned_data["casecollection"]
|
||||||
|
|
||||||
print(f"{collection_set=}")
|
|
||||||
|
|
||||||
for col in collection_set:
|
for col in collection_set:
|
||||||
if col not in self.valid_collections:
|
if col not in self.valid_collections:
|
||||||
raise ValidationError("Invalid collection")
|
raise ValidationError("Invalid collection")
|
||||||
|
|||||||
@@ -1215,10 +1215,7 @@ class BaseReportAnswer(models.Model):
|
|||||||
if self.question.question_schema is None or not "properties" in self.question.question_schema:
|
if self.question.question_schema is None or not "properties" in self.question.question_schema:
|
||||||
return []
|
return []
|
||||||
answers = []
|
answers = []
|
||||||
print("1", self.json_answer)
|
|
||||||
print("2", self.question.question_answers)
|
|
||||||
for name, value in self.question.question_schema["properties"].items():
|
for name, value in self.question.question_schema["properties"].items():
|
||||||
print(name, value)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user_answer = self.json_answer[name]
|
user_answer = self.json_answer[name]
|
||||||
@@ -1229,11 +1226,8 @@ class BaseReportAnswer(models.Model):
|
|||||||
except KeyError: # If the schema has changed?
|
except KeyError: # If the schema has changed?
|
||||||
correct_answer = ""
|
correct_answer = ""
|
||||||
|
|
||||||
print(correct_answer)
|
|
||||||
|
|
||||||
match value:
|
match value:
|
||||||
case {"type": "string", "enum": _}:
|
case {"type": "string", "enum": _}:
|
||||||
print("YES", value)
|
|
||||||
automark = True
|
automark = True
|
||||||
answer_is_correct = user_answer == correct_answer
|
answer_is_correct = user_answer == correct_answer
|
||||||
case {"type": "string"}:
|
case {"type": "string"}:
|
||||||
@@ -1366,8 +1360,6 @@ class UncategorisedDicom(models.Model):
|
|||||||
# duplicate = obj
|
# duplicate = obj
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
print(image_hash)
|
|
||||||
|
|
||||||
if obj := SeriesImage.objects.filter(image_blake3_hash=image_hash).first():
|
if obj := SeriesImage.objects.filter(image_blake3_hash=image_hash).first():
|
||||||
duplicate = obj
|
duplicate = obj
|
||||||
|
|
||||||
@@ -1409,8 +1401,6 @@ class UncategorisedDicom(models.Model):
|
|||||||
ds = pydicom.dcmread(self.image)
|
ds = pydicom.dcmread(self.image)
|
||||||
return ds
|
return ds
|
||||||
except pydicom.errors.InvalidDicomError:
|
except pydicom.errors.InvalidDicomError:
|
||||||
print("Error getting dicom dataset")
|
|
||||||
print(self.image)
|
|
||||||
return {"SeriesInstanceUID": "1234"}
|
return {"SeriesInstanceUID": "1234"}
|
||||||
|
|
||||||
def get_basic_dicom_tags(self, dataset=None):
|
def get_basic_dicom_tags(self, dataset=None):
|
||||||
|
|||||||
@@ -196,11 +196,6 @@ class PopupLinkColumn(tables.Column):
|
|||||||
return obj.get_thumbnail()[0]
|
return obj.get_thumbnail()[0]
|
||||||
|
|
||||||
|
|
||||||
def create_link(test):
|
|
||||||
print(test)
|
|
||||||
return "Hello"
|
|
||||||
|
|
||||||
|
|
||||||
class SeriesTable(tables.Table):
|
class SeriesTable(tables.Table):
|
||||||
edit = tables.LinkColumn(
|
edit = tables.LinkColumn(
|
||||||
"atlas:series_update", text="Edit", args=[A("pk")], orderable=False
|
"atlas:series_update", text="Edit", args=[A("pk")], orderable=False
|
||||||
|
|||||||
@@ -69,12 +69,12 @@
|
|||||||
title="Deleted selected uploads"
|
title="Deleted selected uploads"
|
||||||
>Delete Uploads</button>
|
>Delete Uploads</button>
|
||||||
|
|
||||||
<button id="import-dicoms-sequential-button"
|
<button id="import-dicoms-sequential-button"
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-primary"
|
class="btn btn-primary"
|
||||||
>Import {% if case %}into case{% endif %} (one at a time)</button>
|
>Import {% if case %}into case{% endif %} (one at a time)</button>
|
||||||
|
|
||||||
<div id="import-status"></div>
|
<div id="import-status"></div>
|
||||||
|
|
||||||
<div class="indicator"><div class="loader"></div>Loading...</div>
|
<div class="indicator"><div class="loader"></div>Loading...</div>
|
||||||
<div id="import-status"></div>
|
<div id="import-status"></div>
|
||||||
@@ -89,8 +89,10 @@
|
|||||||
|
|
||||||
<p><a href="{% url 'atlas:series_view' %}?case=null&sort=-modified_date">View orphan series</a></p>
|
<p><a href="{% url 'atlas:series_view' %}?case=null&sort=-modified_date">View orphan series</a></p>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.getElementById('import-dicoms-sequential-button').addEventListener('click', async function() {
|
const importButton = document.getElementById('import-dicoms-sequential-button');
|
||||||
|
if (importButton) {
|
||||||
|
document.getElementById('import-dicoms-sequential-button').addEventListener('click', async function() {
|
||||||
const checkboxes = Array.from(document.querySelectorAll('input[name="selection"]:checked'));
|
const checkboxes = Array.from(document.querySelectorAll('input[name="selection"]:checked'));
|
||||||
const allCheckboxes = Array.from(document.querySelectorAll('input[name="selection"]'));
|
const allCheckboxes = Array.from(document.querySelectorAll('input[name="selection"]'));
|
||||||
// Only include checkboxes that are not disabled (i.e., not already imported)
|
// Only include checkboxes that are not disabled (i.e., not already imported)
|
||||||
@@ -152,29 +154,30 @@ document.getElementById('import-dicoms-sequential-button').addEventListener('cli
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
statusDiv.innerHTML += "<div>All done.</div>";
|
statusDiv.innerHTML += "<div>All done.</div>";
|
||||||
});
|
});
|
||||||
</script>
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
<style>
|
<style>
|
||||||
.indicator {
|
.indicator {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.indicator.htmx-request {
|
.indicator.htmx-request {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loader {
|
.loader {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
aspect-ratio: 1;
|
aspect-ratio: 1;
|
||||||
display: grid;
|
display: grid;
|
||||||
}
|
}
|
||||||
.loader::before,
|
.loader::before,
|
||||||
.loader::after {
|
.loader::after {
|
||||||
content:"";
|
content:"";
|
||||||
grid-area: 1/1;
|
grid-area: 1/1;
|
||||||
--c:no-repeat radial-gradient(farthest-side,#25b09b 92%,#0000);
|
--c:no-repeat radial-gradient(farthest-side,#25b09b 92%,#0000);
|
||||||
@@ -185,40 +188,39 @@ document.getElementById('import-dicoms-sequential-button').addEventListener('cli
|
|||||||
var(--c) 0 50%;
|
var(--c) 0 50%;
|
||||||
background-size: 12px 12px;
|
background-size: 12px 12px;
|
||||||
animation: l12 1s infinite;
|
animation: l12 1s infinite;
|
||||||
}
|
}
|
||||||
.loader::before {
|
.loader::before {
|
||||||
margin: 4px;
|
margin: 4px;
|
||||||
filter: hue-rotate(45deg);
|
filter: hue-rotate(45deg);
|
||||||
background-size: 8px 8px;
|
background-size: 8px 8px;
|
||||||
animation-timing-function: linear
|
animation-timing-function: linear
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes l12 {
|
@keyframes l12 {
|
||||||
100%{transform: rotate(.5turn)}
|
100%{transform: rotate(.5turn)}
|
||||||
}
|
}
|
||||||
|
|
||||||
#series-list {
|
#series-list {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#series-list li {
|
#series-list li {
|
||||||
}
|
}
|
||||||
#series-list .selected {
|
#series-list .selected {
|
||||||
color: white;
|
color: white;
|
||||||
border: 1px solid #52057b;
|
border: 1px solid #52057b;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
margin: -1px;
|
margin: -1px;
|
||||||
|
|
||||||
}
|
}
|
||||||
.series-block-popup-link {
|
.series-block-popup-link {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
#series-list li.imported {
|
#series-list li.imported {
|
||||||
border-color: #e6ffe6;
|
border-color: #e6ffe6;
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
{% endblock css %}
|
{% endblock css %}
|
||||||
|
|
||||||
@@ -37,7 +37,6 @@ def test_condition_tree_structure(db):
|
|||||||
assert len(child2.get_parents()) == 1
|
assert len(child2.get_parents()) == 1
|
||||||
assert parent in child2.get_parents()
|
assert parent in child2.get_parents()
|
||||||
|
|
||||||
print(parent.get_descendents())
|
|
||||||
|
|
||||||
#@pytest.fixture
|
#@pytest.fixture
|
||||||
#def create_basic_user(db, django_user_model):
|
#def create_basic_user(db, django_user_model):
|
||||||
|
|||||||
@@ -568,7 +568,6 @@ class SeriesBase(models.Model):
|
|||||||
n = n + 1
|
n = n + 1
|
||||||
|
|
||||||
def order_by_dicom(self, field="SliceLocation"):
|
def order_by_dicom(self, field="SliceLocation"):
|
||||||
print(f"Ordering by dicom field {field}")
|
|
||||||
images = self.images.filter(removed=False)
|
images = self.images.filter(removed=False)
|
||||||
|
|
||||||
|
|
||||||
@@ -577,9 +576,6 @@ class SeriesBase(models.Model):
|
|||||||
for i in images:
|
for i in images:
|
||||||
files.append((i, pydicom.dcmread(i.image.path)))
|
files.append((i, pydicom.dcmread(i.image.path)))
|
||||||
|
|
||||||
print("images to order")
|
|
||||||
print(files)
|
|
||||||
|
|
||||||
# print("file count: {}".format(len(files)))
|
# print("file count: {}".format(len(files)))
|
||||||
|
|
||||||
# skip files with no SliceLocation (eg scout views)
|
# skip files with no SliceLocation (eg scout views)
|
||||||
@@ -594,8 +590,6 @@ class SeriesBase(models.Model):
|
|||||||
else:
|
else:
|
||||||
skipcount = skipcount + 1
|
skipcount = skipcount + 1
|
||||||
|
|
||||||
print("skipped, no {}: {}".format(field, skipcount))
|
|
||||||
|
|
||||||
if not slices:
|
if not slices:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -607,7 +601,6 @@ class SeriesBase(models.Model):
|
|||||||
for f in slices:
|
for f in slices:
|
||||||
i = map[f[field].value]
|
i = map[f[field].value]
|
||||||
i.position = n
|
i.position = n
|
||||||
print(f"Setting position {n} for {i}")
|
|
||||||
i.save()
|
i.save()
|
||||||
n = n + 1
|
n = n + 1
|
||||||
|
|
||||||
|
|||||||
+1
-11
@@ -93,38 +93,29 @@ def get_dicom_order(path):
|
|||||||
files = []
|
files = []
|
||||||
|
|
||||||
for fname in glob.glob(path, recursive=False):
|
for fname in glob.glob(path, recursive=False):
|
||||||
print("loading: {}".format(fname))
|
|
||||||
files.append((fname, pydicom.dcmread(fname)))
|
files.append((fname, pydicom.dcmread(fname)))
|
||||||
|
|
||||||
print("file count: {}".format(len(files)))
|
|
||||||
|
|
||||||
# skip files with no SliceLocation (eg scout views)
|
# skip files with no SliceLocation (eg scout views)
|
||||||
slices = []
|
slices = []
|
||||||
map = {}
|
map = {}
|
||||||
skipcount = 0
|
skipcount = 0
|
||||||
for fname, f in files:
|
for fname, f in files:
|
||||||
print(dir(f))
|
|
||||||
print(fname)
|
|
||||||
if hasattr(f, 'SliceLocation'):
|
if hasattr(f, 'SliceLocation'):
|
||||||
slices.append(f)
|
slices.append(f)
|
||||||
map[f.SliceLocation] = fname
|
map[f.SliceLocation] = fname
|
||||||
else:
|
else:
|
||||||
skipcount = skipcount + 1
|
skipcount = skipcount + 1
|
||||||
|
|
||||||
print("skipped, no SliceLocation: {}".format(skipcount))
|
|
||||||
|
|
||||||
# ensure they are in the correct order
|
# ensure they are in the correct order
|
||||||
slices = sorted(slices, key=lambda s: s.SliceLocation)
|
slices = sorted(slices, key=lambda s: s.SliceLocation)
|
||||||
|
|
||||||
#print(slices)
|
return slices
|
||||||
for i in slices:
|
|
||||||
print(map[i.SliceLocation])
|
|
||||||
|
|
||||||
#get_dicom_order("/home/ross/Downloads/DICOM HEAD/STD4/SER1/*.dcm")
|
#get_dicom_order("/home/ross/Downloads/DICOM HEAD/STD4/SER1/*.dcm")
|
||||||
|
|
||||||
def pretty_print_dicom(dataset, indent=0):
|
def pretty_print_dicom(dataset, indent=0):
|
||||||
l = print_dicom(dataset, indent)
|
l = print_dicom(dataset, indent)
|
||||||
print(l)
|
|
||||||
return "".join(l)
|
return "".join(l)
|
||||||
|
|
||||||
|
|
||||||
@@ -183,7 +174,6 @@ def get_image_dicom_hash(img, dataset=None, hash_type="md5", direct_pixel_data=T
|
|||||||
hasher.update(dataset.PixelData)
|
hasher.update(dataset.PixelData)
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
print("Error getting pixel data hash from dataset")
|
print("Error getting pixel data hash from dataset")
|
||||||
print(dataset)
|
|
||||||
raise InvalidDicomError("Error getting pixel data hash from dataset")
|
raise InvalidDicomError("Error getting pixel data hash from dataset")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ if __name__ == "__main__":
|
|||||||
if os.environ.get('RUN_MAIN'):
|
if os.environ.get('RUN_MAIN'):
|
||||||
if settings.DEBUG_CONTAINER:
|
if settings.DEBUG_CONTAINER:
|
||||||
import debugpy
|
import debugpy
|
||||||
print("DEBUG LISTEN")
|
|
||||||
debugpy.listen(("0.0.0.0", 3459))
|
debugpy.listen(("0.0.0.0", 3459))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
+146
-146
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user