Skip to content

Commit

Permalink
Merge pull request #208 from HFragnaud/master
Browse files Browse the repository at this point in the history
#207,#172,#152,#193 and fix on datahandler
  • Loading branch information
HFragnaud committed Jun 19, 2018
2 parents 8b4e454 + 97e44c7 commit b59c61c
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 44 deletions.
108 changes: 87 additions & 21 deletions model_validation_api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,105 @@
ScientificModel, ScientificModelInstance, ScientificModelImage,
CollabParameters,
Param_DataModalities, Param_TestType, Param_Species,
Param_BrainRegion, Param_CellType, Param_ModelType)
Param_BrainRegion, Param_CellType, Param_ModelType, Param_ScoreType,Param_organizations,
Tickets, Comments)

admin.site.site_header = "HBP Validation Service administration"

@admin.register(ValidationTestDefinition)
class ValidationTestDefinitionAdmin(admin.ModelAdmin):
list_display = ('name', 'brain_region', 'cell_type',
list_display = ('id','name','alias', 'species', 'brain_region', 'cell_type',
'data_type', 'data_modality', 'test_type',
'publication', 'author', 'score_type')
list_filter = ('brain_region', 'cell_type', 'test_type', 'score_type')
search_fields = ('name', 'protocol')
'publication', 'author', 'score_type', 'age', 'data_location', 'protocol', 'creation_date')
list_filter = ('brain_region', 'cell_type', 'test_type', 'score_type', 'species', 'data_modality',)
search_fields = ('id','name','alias', 'species', 'brain_region', 'cell_type',
'data_type', 'data_modality', 'test_type',
'publication', 'author', 'score_type', 'age', 'data_location', 'protocol', 'creation_date')


@admin.register(ValidationTestCode)
class ValidationTestCodeAdmin(admin.ModelAdmin):
pass
list_display = ('id', 'repository', 'version', 'description', 'parameters', 'path', 'timestamp', 'test_definition')
# list_filter = ()
search_fields = ('id', 'repository', 'version', 'description', 'parameters', 'path', 'timestamp', 'test_definition')


@admin.register(ValidationTestResult)
class ValidationTestResultAdmin(admin.ModelAdmin):
list_display = ('model_version', 'test_code',
list_display = ('id','model_version', 'test_code',
'score', 'passed', 'timestamp',
'normalized_score', 'platform', 'project')
search_fields = ('id','model_version', 'test_code',
'score', 'passed', 'timestamp',
'normalized_score', 'platform')
search_fields = ('model_version', 'test_code')


admin.site.register(ScientificModel)
admin.site.register(ScientificModelInstance)
admin.site.register(ScientificModelImage)
admin.site.register(CollabParameters)
admin.site.register(Param_DataModalities)
admin.site.register(Param_TestType)
admin.site.register(Param_Species)
admin.site.register(Param_BrainRegion)
admin.site.register(Param_CellType)
admin.site.register(Param_ModelType)
'normalized_score', 'platform', 'project')

@admin.register(ScientificModel)
class ScientificModelAdmin(admin.ModelAdmin):
list_display = ('id','name', 'alias', 'author', 'owner', 'description', 'species', 'brain_region', 'cell_type', 'model_type', 'private', 'app', 'code_format', 'creation_date', 'organization', 'project', 'license')
search_fields = ('id','name', 'alias', 'author', 'owner', 'description', 'species', 'brain_region', 'cell_type', 'model_type', 'private', 'app', 'code_format', 'creation_date', 'organization', 'project', 'license')
list_filter = ('species', 'brain_region', 'cell_type', 'model_type', 'private', 'code_format', 'organization')

@admin.register(ScientificModelInstance)
class ScientificModelInstanceAdmin(admin.ModelAdmin):
list_display = ('id','version', 'model', 'description', 'parameters', 'code_format', 'source', 'timestamp', 'hash')
search_fields = ('id','version', 'model', 'description', 'parameters', 'code_format', 'source', 'timestamp', 'hash')

@admin.register(ScientificModelImage)
class ScientificModelImageAdmin(admin.ModelAdmin):
list_display = ('id', 'model', 'url', 'caption')
search_fields = ('id', 'model', 'url', 'caption')

@admin.register(CollabParameters)
class CollabParametersAdmin(admin.ModelAdmin):
list_display = ('id', 'app_type', 'data_modalities', 'test_type', 'species', 'brain_region', 'cell_type', 'model_type', 'organization', 'collab_id')
search_fields = ('id', 'app_type', 'data_modalities', 'test_type', 'species', 'brain_region', 'cell_type', 'model_type', 'organization', 'collab_id')

@admin.register(Param_DataModalities)
class Param_DataModalitiesAdmin(admin.ModelAdmin):
list_display = ('id', 'authorized_value')
search_fields = ('id', 'authorized_value')

@admin.register(Param_TestType)
class Param_TestTypeAdmin(admin.ModelAdmin):
list_display = ('id', 'authorized_value')
search_fields = ('id', 'authorized_value')

@admin.register(Param_Species)
class Param_SpeciesAdmin(admin.ModelAdmin):
list_display = ('id', 'authorized_value')
search_fields = ('id', 'authorized_value')

@admin.register(Param_BrainRegion)
class Param_BrainRegionAdmin(admin.ModelAdmin):
list_display = ('id', 'authorized_value')
search_fields = ('id', 'authorized_value')

@admin.register(Param_CellType)
class Param_CellTypeAdmin(admin.ModelAdmin):
list_display = ('id', 'authorized_value')
search_fields = ('id', 'authorized_value')

@admin.register(Param_ModelType)
class Param_ModelTypeAdmin(admin.ModelAdmin):
list_display = ('id', 'authorized_value')
search_fields = ('id', 'authorized_value')

@admin.register(Param_ScoreType)
class Param_ScoreTypeAdmin(admin.ModelAdmin):
list_display = ('id', 'authorized_value')
search_fields = ('id', 'authorized_value')

@admin.register(Param_organizations)
class Param_organizationsAdmin(admin.ModelAdmin):
list_display = ('id', 'authorized_value')
search_fields = ('id', 'authorized_value')

@admin.register(Comments)
class CommentsAdmin(admin.ModelAdmin):
list_display = ('id', 'Ticket', 'author', 'text', 'creation_date')
search_fields = ('id', 'Ticket', 'author', 'text', 'creation_date')

@admin.register(Tickets)
class TicketsAdmin(admin.ModelAdmin):
list_display = ('id', 'test', 'author', 'title', 'text', 'creation_date')
search_fields = ('id', 'test', 'author', 'title', 'text', 'creation_date')
2 changes: 1 addition & 1 deletion model_validation_api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class ValidationTestResult(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, )
model_version = models.ForeignKey(ScientificModelInstance)
test_code = models.ForeignKey(ValidationTestCode)
results_storage = models.TextField(help_text="Location of data files produced by the test run") # or store locations of individual files?
results_storage = models.TextField(blank=True, help_text="Location of data files produced by the test run") # or store locations of individual files?
score = models.FloatField(help_text="A numerical measure of the difference between model and experiment") # name this 'score'? like sciunit
# should result be a Quantity?
passed = models.NullBooleanField(help_text="Whether the test passed or failed")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,10 @@ def is_authorised(request, collab_id):
if request.META.get("HTTP_AUTHORIZATION", None) == None :
return False
else:
if not (_is_collaborator_token(request, collab_id) or _is_collaborator_token(request, collab_id)):
return False
else:
return True
auth = _is_collaborator_token(request, collab_id)
if auth == False:
auth = _is_collaborator_token(request, admin_id)
return auth

else :
if not (_is_collaborator(request, collab_id) or _is_collaborator(request,admin_id)):
Expand Down
27 changes: 22 additions & 5 deletions model_validation_api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,10 @@ def get(self, request, format=None, **kwargs):
:type timestamp: datetime
:param model_alias: alias of the model name
:type model_alias: str
:param code_format: format of the code
:type code_format: str
:param hash: hash
:type hash: str
:return: list of instances
:rtype: dictionnary
"""
Expand All @@ -505,6 +509,8 @@ def get(self, request, format=None, **kwargs):
param_source = request.GET.getlist('source')
param_timestamp = request.GET.getlist('timestamp')
param_model_alias = request.GET.getlist('model_alias')
param_code_format = request.GET.getlist('code_format')
param_hash = request.GET.getlist('hash')

if check_list_uuid_validity(param_id) is False :
return Response("Badly formed uuid in : id", status=status.HTTP_400_BAD_REQUEST)
Expand All @@ -529,6 +535,10 @@ def get(self, request, format=None, **kwargs):
q = q.filter(source__in = param_source )
if len(param_timestamp) > 0 :
q = q.filter(timestamp__in = param_timestamp )
if len(param_code_format) > 0 :
q = q.filter(code_format__in = param_code_format )
if len(param_hash) > 0 :
q = q.filter(hash__in = param_hash )

instances = q

Expand Down Expand Up @@ -749,7 +759,6 @@ def get(self, request, format=None, **kwargs):
image_serializer = ScientificModelImageSerializer(data=images, context=serializer_context, many=True)
image_serializer.is_valid() # needed....


return Response({
'images': image_serializer.data,
})
Expand All @@ -771,7 +780,10 @@ def post(self, request, format=None):
serializer = ScientificModelImageSerializer(data=image, context=serializer_context)
if serializer.is_valid():
#security
app_id = ScientificModel.objects.get(id=image['model_id']).app_id
try:
app_id = ScientificModel.objects.get(id=image['model_id']).app_id
except:
app_id = ScientificModel.objects.get(alias=image['model_alias']).app_id
collab_id = get_collab_id_from_app_id(app_id)
if not is_authorised(request, collab_id):
return HttpResponseForbidden()
Expand All @@ -783,7 +795,12 @@ def post(self, request, format=None):
serializer = ScientificModelImageSerializer(data=image, context=serializer_context)

if serializer.is_valid():
im = serializer.save(model_id=image['model_id'])
if image['model_id']:
im = serializer.save(model_id=image['model_id'])
else:
if image['model_alias']:
model_id = ScientificModel.objects.get(alias=image['model_alias']).id
im = serializer.save(model_id=model_id)
list_id.append(im.id)


Expand Down Expand Up @@ -1087,12 +1104,12 @@ def get(self, request, format=None, **kwargs):
try:
web_app = request.GET.getlist('web_app')
except:
web_app = False
web_app = False
id =id[0]
models = ScientificModel.objects.filter(id=id)

if len(models) > 0 :

#check if private
if models.values("private")[0]["private"] == 1 :
#if private check if collab member
Expand Down
32 changes: 27 additions & 5 deletions validation_service/app/js/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ testApp.controller('HomeCtrl', ['$scope', '$rootScope', '$http', '$location', "S

var status = DataHandler.getCurrentStatus();
if (status != "up_to_date") {
console.log("status")
DataHandler.loadModelsByPage($scope.app_id, $scope.nb_pages);
}
});
Expand All @@ -72,12 +73,14 @@ testApp.controller('HomeCtrl', ['$scope', '$rootScope', '$http', '$location', "S

if (state_type == "model") {
Context.validation_goToModelDetailView(element);
$scope.$apply();
} else if (state_type == "test") {
Context.validation_goToTestDetailView(element);
$scope.$apply();
} else if (state_type == "result") {
Context.validation_goToResultDetailView(element);
$scope.$apply();
}

}
});
}
Expand Down Expand Up @@ -1040,6 +1043,7 @@ ModelCatalogApp.filter('filterMultiple', ['$parse', '$filter', function($parse,
if (!angular.isArray(items)) {
return items;
}

var filterObj = {
data: items,
filteredData: [],
Expand All @@ -1059,9 +1063,15 @@ ModelCatalogApp.filter('filterMultiple', ['$parse', '$filter', function($parse,
if (angular.isDefined(obj[i]['value'])) {
fObj[key] = obj[i]['value'];
} else {
fObj[key] = obj[i];
if (key == 'collab_id') { //specific for Model Catalog home: to allow filter by collab (deep filter)
fObj['app'] = {}
fObj['app'][key] = obj[i];
} else {
fObj[key] = obj[i];
}
}
fData = fData.concat($filter('filter')(this.filteredData, fObj));

}
}
}
Expand All @@ -1084,7 +1094,6 @@ ModelCatalogApp.filter('filterMultiple', ['$parse', '$filter', function($parse,
filterObj.applyFilter(obj, key);
});
}

return filterObj.filteredData;
}
}]);
Expand Down Expand Up @@ -1118,8 +1127,20 @@ ModelCatalogApp.controller('ModelCatalogCtrl', [
return models
}

$scope._get_collab_and_app_ids_from_models = function() {
for (var i in $scope.models.models) {
if ($scope.models.models[i].app != null) {
if ($scope.collab_ids_to_select.indexOf($scope.models.models[i].app.collab_id.toString()) == -1) {
$scope.collab_ids_to_select.push($scope.models.models[i].app.collab_id.toString());
}
}
}
$scope.$apply();
}

$scope.$on('models_updated', function(event, models) {
$scope.models = $scope._change_empty_organization_string(models);
$scope.collab_ids_to_select = $scope._get_collab_and_app_ids_from_models();
});

Context.setService().then(function() {
Expand Down Expand Up @@ -1164,8 +1185,9 @@ ModelCatalogApp.controller('ModelCatalogCtrl', [
$scope.collab_cell_type = CollabParameters.getParametersOrDefaultByType("cell_type");
$scope.collab_model_type = CollabParameters.getParametersOrDefaultByType("model_type");
$scope.collab_organization = CollabParameters.getParametersOrDefaultByType("organization");


$scope.collab_ids_to_select = new Array();
$scope._get_collab_and_app_ids_from_models();
// $scope.selected_collab = $scope.collab_ids_to_select //initialize


$scope.is_collab_member = false;
Expand Down
4 changes: 2 additions & 2 deletions validation_service/app/js/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ DataHandlerServices.service('DataHandler', ['$rootScope', 'ScientificModelRest',
} else {
var temp_models = ScientificModelRest.get(dict_params);
temp_models.$promise.then(function() {
models = { date_last_load: new Date(), status: "up_to_date", data: temp_models };
models = { date_last_load: new Date(), status: "loading", data: temp_models };
resolve(models.data, models.status);
});
}
Expand All @@ -474,7 +474,7 @@ DataHandlerServices.service('DataHandler', ['$rootScope', 'ScientificModelRest',
$rootScope.$broadcast('models_updated', models.data);

//change status if last load is done
if (pages_loaded.length == nb_pages.length) {
if (pages_loaded.length == nb_pages) {
models.date_last_load = new Date();
models.status = "up_to_date";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ <h1 align=center> Model Catalog</h1>
<nav>
<table>
<tr>
<td>
<label> Search : <input id="search_model" ng-model='search.$'> </label>
</td>


<td>
<multiselect ng-model="selected_species" placeholder="Select species" options="collab_species"></multiselect>
Expand All @@ -30,15 +28,27 @@ <h1 align=center> Model Catalog</h1>
<td>
<multiselect ng-model="selected_privacy" placeholder="Select privacy" options="model_privacy" id-prop="value" display-prop="name"></multiselect>
</td>
<td>
<multiselect ng-model="selected_collab" placeholder="Select collab" options="collab_ids_to_select"></multiselect>
</td>
<td>
<select id="sorting_option" placeholder="Sorting options" class="form-control" ng-model="selected_sorting_option">
<option value="">Sorting options</option>
<option value="-creation_date ">Sorting: Newest first</option>
<option value="creation_date ">Sorting: Oldest first</option>
</select>
</td>
</td>
<td><a class="button-MC " ng-href="#/model-catalog/create " ng-if="is_collab_member==true " class="btn btn-primary ">New model </a></td>
</tr>

</table>
<table>
<tr>
<td width="90%">
<label> Search : <input id="search_model" ng-model='search.$' size=30> </label>

</tr>
</table>
<br>
</nav>
Expand All @@ -58,8 +68,9 @@ <h1 align=center> Model Catalog</h1>
</tr>
</thead>
<tbody>
<tr ng-mousedown="Context.goToModelDetailView($event, model.id)" oncontextmenu="return false" class="tr-clickable " dir-paginate="model in models.models | filter:search | filterMultiple:{ organization:selected_organization, species:selected_species, brain_region:selected_brain_region , cell_type:selected_cell_type, model_type:selected_model_type, private: selected_privacy}
<tr ng-mousedown="Context.goToModelDetailView($event, model.id)" oncontextmenu="return false" class="tr-clickable " dir-paginate="model in models.models | filter:search | filterMultiple:{ organization:selected_organization, species:selected_species, brain_region:selected_brain_region , cell_type:selected_cell_type, model_type:selected_model_type, private: selected_privacy, collab_id: selected_collab}
| orderBy: selected_sorting_option | itemsPerPage: itemsPerPages" pagination-id="models">

<td>{{ model.name}}</td>
<td ng-text-truncate=model.alias ng-tt-chars-threshold="50 " ng-tt-no-toggling>{{ model.alias }}</td>
<td ng-text-truncate=model.species ng-tt-chars-threshold="50 " ng-tt-no-toggling>{{ model.species }}</td>
Expand Down
Loading

0 comments on commit b59c61c

Please sign in to comment.