Skip to content

Commit afe436b

Browse files
authored
Merge pull request #300 from ModellingWebLab/276-list-of-fitting-results
Lists of fitting results
2 parents 196d39e + b24356d commit afe436b

18 files changed

Lines changed: 937 additions & 100 deletions

File tree

weblab/datasets/tests/test_views.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,3 +637,134 @@ def test_nonexistent_dataset_redirects_anonymous_to_login(self, client, helpers,
637637
def test_nonexistent_dataset_generates_404_for_user(self, client, logged_in_user, helpers, recipe, url):
638638
response = client.get(url % 10000)
639639
assert response.status_code == 404
640+
641+
642+
@pytest.mark.django_db
643+
class TestDatasetCompareFittingResultsView:
644+
def test_shows_fittings_related_to_dataset(self, client, fittingresult_version):
645+
fit = fittingresult_version.fittingresult
646+
647+
# should not be included, as it uses a different dataset
648+
recipes.fittingresult_version.make()
649+
650+
response = client.get('/datasets/%d/fittings' % fit.dataset.pk)
651+
652+
assert response.status_code == 200
653+
assert response.context['comparisons'] == [(fit.model, [fit])]
654+
655+
def test_groups_by_model(self, client, helpers, public_dataset):
656+
m1, m2 = recipes.model.make(_quantity=2)
657+
m1v = helpers.add_cached_version(m1, visibility='public')
658+
m2v = helpers.add_cached_version(m2, visibility='public')
659+
660+
# Create publicly visible fitting result versions
661+
fit1_m1 = recipes.fittingresult_version.make(
662+
fittingresult__dataset=public_dataset,
663+
fittingresult__model=m1,
664+
fittingresult__model_version=m1v,
665+
fittingresult__fittingspec_version__visibility='public',
666+
fittingresult__protocol_version__visibility='public',
667+
).fittingresult
668+
669+
fit2_m1 = recipes.fittingresult_version.make(
670+
fittingresult__dataset=public_dataset,
671+
fittingresult__model=m1,
672+
fittingresult__model_version=m1v,
673+
fittingresult__fittingspec_version__visibility='public',
674+
fittingresult__protocol_version__visibility='public',
675+
).fittingresult
676+
677+
fit3_m2 = recipes.fittingresult_version.make(
678+
fittingresult__dataset=public_dataset,
679+
fittingresult__model=m2,
680+
fittingresult__model_version=m2v,
681+
fittingresult__fittingspec_version__visibility='public',
682+
fittingresult__protocol_version__visibility='public',
683+
).fittingresult
684+
685+
response = client.get('/datasets/%d/fittings' % public_dataset.id)
686+
687+
assert response.status_code == 200
688+
assert response.context['comparisons'] == [
689+
(m1, [fit2_m1, fit1_m1]),
690+
(m2, [fit3_m2]),
691+
]
692+
693+
def test_multiple_model_versions_for_dataset(self, client, helpers, public_dataset):
694+
m1, m2 = recipes.model.make(_quantity=2)
695+
m1v1 = helpers.add_cached_version(m1, visibility='public')
696+
m1v2 = helpers.add_cached_version(m1, visibility='public')
697+
m2v = helpers.add_cached_version(m2, visibility='public')
698+
699+
# Create publicly visible fitting result versions
700+
fit1_m1v1 = recipes.fittingresult_version.make(
701+
fittingresult__dataset=public_dataset,
702+
fittingresult__model=m1,
703+
fittingresult__model_version=m1v1,
704+
fittingresult__fittingspec_version__visibility='public',
705+
fittingresult__protocol_version__visibility='public',
706+
).fittingresult
707+
708+
fit2_m1v2 = recipes.fittingresult_version.make(
709+
fittingresult__dataset=public_dataset,
710+
fittingresult__model=m1,
711+
fittingresult__model_version=m1v2,
712+
fittingresult__fittingspec_version__visibility='public',
713+
fittingresult__protocol_version__visibility='public',
714+
).fittingresult
715+
716+
fit3_m2v = recipes.fittingresult_version.make(
717+
fittingresult__dataset=public_dataset,
718+
fittingresult__model=m2,
719+
fittingresult__model_version=m2v,
720+
fittingresult__fittingspec_version__visibility='public',
721+
fittingresult__protocol_version__visibility='public',
722+
).fittingresult
723+
724+
response = client.get(
725+
'/datasets/%d/fittings' % public_dataset.id
726+
)
727+
728+
assert response.status_code == 200
729+
assert response.context['comparisons'] == [
730+
(m1, [fit2_m1v2, fit1_m1v1]),
731+
(m2, [fit3_m2v]),
732+
]
733+
734+
def test_ensure_private_results_are_not_shown(self, client, public_dataset):
735+
recipes.fittingresult_version.make(
736+
fittingresult__dataset=public_dataset,
737+
fittingresult__model_version__visibility='private',
738+
fittingresult__protocol_version__visibility='public',
739+
fittingresult__fittingspec_version__visibility='public',
740+
)
741+
742+
recipes.fittingresult_version.make(
743+
fittingresult__dataset=public_dataset,
744+
fittingresult__model_version__visibility='public',
745+
fittingresult__protocol_version__visibility='private',
746+
fittingresult__fittingspec_version__visibility='public',
747+
)
748+
749+
recipes.fittingresult_version.make(
750+
fittingresult__dataset=public_dataset,
751+
fittingresult__model_version__visibility='public',
752+
fittingresult__protocol_version__visibility='public',
753+
fittingresult__fittingspec_version__visibility='private',
754+
)
755+
756+
fit = recipes.fittingresult_version.make(
757+
fittingresult__dataset=public_dataset,
758+
fittingresult__model_version__visibility='public',
759+
fittingresult__protocol_version__visibility='public',
760+
fittingresult__fittingspec_version__visibility='public',
761+
).fittingresult
762+
763+
response = client.get(
764+
'/datasets/%d/fittings' % public_dataset.id
765+
)
766+
767+
assert response.status_code == 200
768+
assert response.context['comparisons'] == [
769+
(fit.model, [fit]),
770+
]

weblab/datasets/urls.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,10 @@
7474
views.DatasetRenameView.as_view(),
7575
name='rename',
7676
),
77+
78+
url(
79+
r'^(?P<pk>\d+)/fittings$',
80+
views.DatasetCompareFittingResultsView.as_view(),
81+
name='compare_fittings',
82+
),
7783
]

weblab/datasets/views.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import mimetypes
22
import os.path
33
import shutil
4+
from itertools import groupby
45
from zipfile import ZipFile
56

67
from braces.views import UserFormKwargsMixin
@@ -25,6 +26,7 @@
2526
from accounts.forms import OwnershipTransferForm
2627
from core.combine import ManifestWriter
2728
from core.visibility import VisibilityMixin
29+
from fitting.models import FittingResult
2830

2931
from .forms import (
3032
DatasetAddFilesForm,
@@ -332,3 +334,39 @@ def post(self, request, *args, **kwargs):
332334
def get_success_url(self, *args, **kwargs):
333335
ns = self.request.resolver_match.namespace
334336
return reverse(ns + ':detail', args=[self._get_object().id])
337+
338+
339+
class DatasetCompareFittingResultsView(DetailView):
340+
"""
341+
List fitting results for this dataset, with selection boxes for comparison
342+
"""
343+
model = Dataset
344+
template_name = 'datasets/compare_fittings.html'
345+
346+
def _get_object(self):
347+
if not hasattr(self, 'object'):
348+
self.object = self.get_object()
349+
return self.object
350+
351+
def get_context_data(self, **kwargs):
352+
dataset = self._get_object()
353+
354+
fittings = FittingResult.objects.filter(
355+
dataset=dataset.pk,
356+
).select_related(
357+
'model',
358+
).order_by('model', '-model_version__timestamp', '-protocol_version__timestamp')
359+
360+
# Ensure all are visible to user
361+
fittings = [
362+
fit for fit in fittings
363+
if fit.is_visible_to_user(self.request.user)
364+
]
365+
366+
# Group fittings by model
367+
kwargs['comparisons'] = [
368+
(obj, list(fits))
369+
for (obj, fits) in groupby(fittings, lambda fit: fit.model)
370+
]
371+
372+
return super().get_context_data(**kwargs)

weblab/entities/templatetags/entities.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ def name_of_protocol(experiment):
123123
return '%s @ %s' % (experiment.protocol.name, experiment.protocol_version.get_name())
124124

125125

126+
@register.filter
127+
def name_of_fittingspec(experiment):
128+
return '%s @ %s' % (experiment.fittingspec.name, experiment.fittingspec_version.get_name())
129+
130+
126131
def _url_friendly_label(entity, version):
127132
"""
128133
Get URL-friendly version label for a commit

0 commit comments

Comments
 (0)