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

Landmark edits #340

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
516879a
Update vtk.js version to use new classes
annehaley Sep 18, 2023
1322d0f
Use new vtk.js classes to make landmarks moveable
annehaley Sep 18, 2023
63afbab
Fix landmark cube sizing
annehaley Sep 18, 2023
05acb61
clear cached widgets on project change
annehaley Sep 18, 2023
afa601f
Change vtk.js version specification
annehaley Oct 2, 2023
4ed3e71
Allow user to change landmarkInfo client-side
annehaley Oct 2, 2023
4ac49e6
Save landmark changes to server
annehaley Oct 2, 2023
4d3b420
Add landmarkSize input
annehaley Oct 10, 2023
fdca295
Update yarn.lock
annehaley Oct 10, 2023
6a68839
Update table interface for adding and deleting landmarks (still needs…
annehaley Oct 11, 2023
4abde70
Allow user to place new landmarks
annehaley Oct 12, 2023
9e72320
Save landmark changes to project swproj file
annehaley Oct 12, 2023
77f5fbd
Fix infinite loop in DataList update
annehaley Oct 16, 2023
830219c
Fixes for creating landmarks on multidomain
annehaley Oct 16, 2023
9d33a33
Update landmark position on drag
annehaley Oct 16, 2023
fe11e68
Use allSetLandmarks as source of truth for positions
annehaley Oct 17, 2023
425fa8e
Copy vtk.js SeedWidget and modifiy handleMouseMove
annehaley Oct 17, 2023
250a5dc
Assign landmark IDs upon fetch
annehaley Oct 20, 2023
0cd5736
Minor usability changes
annehaley Oct 25, 2023
db6a467
Add check to find world coords in landmark widget
annehaley Nov 6, 2023
522e996
Refactoring and simplifying logic to fix strange behavior
annehaley Nov 10, 2023
343dc1c
Fix landmark deletions
annehaley Nov 10, 2023
d9de19d
Minor behavior fixes
annehaley Nov 13, 2023
b73f37b
Remove console log
annehaley Nov 13, 2023
9afd883
Lint fix
annehaley Nov 13, 2023
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
62 changes: 62 additions & 0 deletions shapeworks_cloud/core/rest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import base64
import json
import os
from pathlib import Path
from tempfile import TemporaryDirectory, gettempdir
from typing import Dict, Type

from django.contrib.auth import logout
from django.core.files.base import ContentFile
from django.db.models import Q
from django.utils import timezone
from django_filters.rest_framework import DjangoFilterBackend
Expand Down Expand Up @@ -302,6 +304,66 @@ def download(self, request, **kwargs):
project = self.get_object()
return Response(serializers.ProjectDownloadSerializer(project).data)

@action(
detail=True,
url_path='landmarks',
url_name='landmarks',
methods=['POST'],
)
def set_landmarks(self, request, **kwargs):
project = self.get_object()
form_data = request.data
landmarks_info = form_data.get('info')
landmarks_locations = form_data.get('locations')

project.landmarks_info = landmarks_info
project_file_contents = json.loads(project.file.read())
project_file_contents['landmarks'] = landmarks_info
project.file.save(
project.file.name.split('/')[-1],
ContentFile(json.dumps(project_file_contents).encode()),
)
project.save()

ids_existing_with_coords = []
for subject_id, data in landmarks_locations.items():
for anatomy_type, locations in data.items():
target_subject = models.Subject.objects.get(id=subject_id)
landmarks_object, created = models.Landmarks.objects.get_or_create(
project=project, subject=target_subject, anatomy_type=anatomy_type
)
file_content = ''
if (
locations is not None
and len(locations) > 0
and locations[0] is not None
and len(locations[0]) == 3
):
file_content = '\n'.join(
' '.join(str(n) for n in (loc.values() if isinstance(loc, dict) else loc))
for loc in locations
)
file_name = 'landmarks.csv'
if landmarks_object.file:
file_name = landmarks_object.file.name.split('/')[-1]
landmarks_object.file.save(
file_name,
ContentFile(file_content.encode()),
)
ids_existing_with_coords.append(landmarks_object.id)

models.Landmarks.objects.filter(project=project).exclude(
id__in=ids_existing_with_coords
).delete()

log_write_access(
timezone.now(),
self.request.user.username,
'Set Project Landmarks',
project.id,
)
return Response(serializers.ProjectReadSerializer(project).data)

@action(
detail=True,
url_path='groom',
Expand Down
1 change: 1 addition & 0 deletions swcc/swcc/models/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
'groomed',
'local',
'world',
'landmarks',
'constraints',
]
2 changes: 1 addition & 1 deletion web/shapeworks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"json-schema-defaults": "^0.4.0",
"lodash": "^4.17.21",
"shader-loader": "^1.3.1",
"vtk.js": "*",
"vtk.js": ">=28.11.0",
"vue": "^2.7.14",
"vue-echarts": "^6.2.4",
"vue-router": "^3.2.0",
Expand Down
13 changes: 12 additions & 1 deletion web/shapeworks/src/api/rest.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AnalysisParams, DataObject, Dataset, Project, Subject } from "@/types";
import { AnalysisParams, DataObject, Dataset, LandmarkInfo, Project, Subject } from "@/types";
import { apiClient } from "./auth";
import { loadGroomedShapeForObject, loadParticlesForObject } from "@/store";

Expand Down Expand Up @@ -154,3 +154,14 @@ export async function deleteTaskProgress(taskId: number){
export async function abortTask(taskId: number) {
return (await apiClient.post(`/task-progress/${taskId}/abort/`)).data
}

export async function saveLandmarkData(
projectId: number,
landmarkInfo: LandmarkInfo[],
landmarkLocations: Record<number, Record<number, number[][]>>
) {
return (await apiClient.post(`/projects/${projectId}/landmarks/`, {
info: landmarkInfo,
locations: landmarkLocations,
})).data
}
15 changes: 14 additions & 1 deletion web/shapeworks/src/components/DataList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
selectedDataset,
allSubjectsForDataset,
allDataObjectsInDataset,
anatomies,
selectedDataObjects,
loadingState,
loadReconstructedSamplesForProject,
Expand All @@ -30,7 +31,7 @@ export default {
}
},
setup(props) {
const anatomies = ref<string[]>([]);

const selectedAnatomies = ref<string[]>([]);
const selectedSubjects = ref<number[]>([])
const headers = [
Expand Down Expand Up @@ -85,6 +86,17 @@ export default {
)
}

function selectedObjectsUpdated() {
const uniqueAnatomies = [...new Set(selectedDataObjects.value.map(item => item.anatomy_type))]
const uniqueSubjects = [...new Set(selectedDataObjects.value.map(item => item.subject))]
if (JSON.stringify(uniqueAnatomies) !== JSON.stringify(selectedAnatomies.value)) {
selectedAnatomies.value = uniqueAnatomies
}
if (JSON.stringify(uniqueSubjects) !== JSON.stringify(selectedSubjects.value)) {
selectedSubjects.value = uniqueSubjects
}
}

onMounted(async () => {
if(!selectedDataset.value) {
await fetchData(props.dataset)
Expand All @@ -95,6 +107,7 @@ export default {

watch(selectedAnatomies, updateSelectedObjects)
watch(selectedSubjects, updateSelectedObjects)
watch(selectedDataObjects, selectedObjectsUpdated)

return {
anatomies,
Expand Down
80 changes: 0 additions & 80 deletions web/shapeworks/src/components/InfoTab.vue

This file was deleted.

Loading
Loading