diff --git a/Makefile b/Makefile index 7fd85a87f..bb126b986 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,4 @@ -all: R/service.R SCSSC - -R/service.R: R/measurements.R R/smaa.R R/macbethSolve.R - cat $^ > $@ +all: SCSSC SCSSC: compass compile diff --git a/Dockerfile b/R/Dockerfile similarity index 73% rename from Dockerfile rename to R/Dockerfile index 87e1420cc..44a993bc0 100644 --- a/Dockerfile +++ b/R/Dockerfile @@ -9,8 +9,11 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install -y -q libgmp-dev RUN R -e 'install.packages("hitandrun", repos="http://cran.rstudio.com/"); if (!require("hitandrun")) quit(save="no", status=8)' RUN R -e 'install.packages("smaa", repos="http://cran.rstudio.com/"); if (!require("smaa")) quit(save="no", status=8)' -ADD R/service.R /var/lib/patavi/smaa_service.R +ADD measurements.R /tmp/ +ADD macbethSolve.R /tmp/ +ADD smaa.R /tmp/ +RUN cat /tmp/*.R > /var/lib/patavi/smaa_service.R USER patavi ENV HOME /var/lib/patavi -ENTRYPOINT ["/var/lib/patavi/bin/patavi-worker", "--method", "smaa", "-n", "1", "--file", "/var/lib/patavi/smaa_service.R", "--rserve", "--packages", "MASS,rcdd,hitandrun,smaa"] +ENTRYPOINT ["/var/lib/patavi/bin/patavi-worker", "--method", "smaa_v2", "-n", "1", "--file", "/var/lib/patavi/smaa_service.R", "--rserve", "--packages", "MASS,rcdd,hitandrun,smaa"] diff --git a/R/smaa.R b/R/smaa.R index 9752bc992..7cfbb6f7a 100644 --- a/R/smaa.R +++ b/R/smaa.R @@ -8,7 +8,7 @@ wrap.matrix <- function(m) { l } -smaa <- function(params) { +smaa_v2 <- function(params) { allowed <- c('scales', 'smaa', 'macbeth') if(params$method %in% allowed) { do.call(paste("run", params$method, sep="_"), list(params)) @@ -22,7 +22,8 @@ run_scales <- function(params) { crit <- names(params$criteria) alts <- names(params$alternatives) meas <- sample(alts, crit, params$performanceTable, N) - list(wrap.matrix(t(apply(meas, 3, function(e) { quantile(e, c(0.025, 0.975)) })))) + scales <- apply(meas, c(2, 3), function(e) { quantile(e, c(0.025, 0.5, 0.975)) }) + apply(aperm(scales, c(3,2,1)), 1, wrap.matrix) } ratioConstraint <- function(n, i1, i2, x) { diff --git a/R/test/thrombo.R b/R/test/thrombo.R index 2204ee9d9..69a018681 100644 --- a/R/test/thrombo.R +++ b/R/test/thrombo.R @@ -11,20 +11,18 @@ params <- fromJSON('../../examples/thrombolytics.json') print("=== CI hulls ===") -expected <- list(structure( - list( - `Prox DVT` = structure( - c(0.0312317469487807, 0.202267162805509), - .Names = c("2.5%", "97.5%")), - `Dist DVT` = structure( - c(0.189206533230964, 0.359563082546533), - .Names = c("2.5%", "97.5%")), - Bleed = structure( - c(0.000383785658019692, 0.0704173191411898), - .Names = c("2.5%", "97.5%"))), - .Names = c("Prox DVT", "Dist DVT", "Bleed"))) - -actual <- run_scales(params) +expected <- structure(list( + `Prox DVT` = structure(c(0.0273829683645853, 0.211008623949751), .Names = c("2.5%", "97.5%")), + `Dist DVT` = structure(c(0.179207896860712, 0.372992144610352), .Names = c("2.5%", "97.5%")), + Bleed = structure(c(0.000174242898524121, 0.0774123400973682), .Names = c("2.5%", "97.5%"))), + .Names = c("Prox DVT", "Dist DVT", "Bleed")) + +scales <- run_scales(params) +actual <- lapply(scales, function(y) { + lower <- min(unlist(lapply(y, function(z) { z["2.5%"] }))) + upper <- max(unlist(lapply(y, function(z) { z["97.5%"] }))) + c("2.5%"=lower, "97.5%"=upper) +}) print(all.equal(expected, actual, tolerance=0.05)) print("=== Preference Free ===") diff --git a/app/js/config.js b/app/js/config.js index b649a2443..a13a0afc0 100644 --- a/app/js/config.js +++ b/app/js/config.js @@ -50,6 +50,7 @@ define([], function() { return { tasks: tasks, - defaultView: defaultView + defaultView: defaultView, + pataviService: 'smaa_v2' }; }); diff --git a/app/js/controllers/helpers/wizard.js b/app/js/controllers/helpers/wizard.js index ceb4936c9..b9c143b3c 100644 --- a/app/js/controllers/helpers/wizard.js +++ b/app/js/controllers/helpers/wizard.js @@ -1,12 +1,12 @@ 'use strict'; -define(['angular', 'underscore', 'mcda/lib/patavi', 'NProgress'], function(angular, _, patavi, NProgress) { +define(['mcda/config', 'angular', 'underscore', 'mcda/lib/patavi', 'NProgress'], function(Config, angular, _, patavi, NProgress) { return ['$rootScope', '$scope', 'handler', function($rootScope, $scope, handler) { $rootScope.noProgress = true; var calculateIntermediateResults = function(state, standardizeFn) { var prefs = standardizeFn(state.prefs); var data = _.extend(state.problem, { "preferences": prefs, "method": "smaa" }); - var task = patavi.submit('smaa', data); + var task = patavi.submit(Config.pataviService, data); var successHandler = function(results) { $scope.$root.$safeApply($scope, function() { diff --git a/app/js/controllers/partialValueFunction.js b/app/js/controllers/partialValueFunction.js index f1854b6dd..06bdab6fa 100644 --- a/app/js/controllers/partialValueFunction.js +++ b/app/js/controllers/partialValueFunction.js @@ -1,5 +1,5 @@ 'use strict'; -define(['mcda/controllers/helpers/wizard', 'angular', 'mcda/lib/patavi', 'underscore'], function(Wizard, angular, patavi, _) { +define(['mcda/config', 'mcda/controllers/helpers/wizard', 'angular', 'mcda/lib/patavi', 'underscore'], function(Config, Wizard, angular, patavi, _) { return function($scope, $injector, currentScenario, taskDefinition, PartialValueFunction) { var standardize = function(state) { // Copy choices to problem @@ -35,7 +35,7 @@ define(['mcda/controllers/helpers/wizard', 'angular', 'mcda/lib/patavi', 'unders } var preferences = rewritePreferences(choice.data[choice.criterion].preferences); - var task = patavi.submit("smaa", { method: "macbeth", preferences: preferences }); + var task = patavi.submit(Config.pataviService, { method: "macbeth", preferences: preferences }); task.results.then(function(results) { $scope.$root.$safeApply($scope, function() { currentState.results = results.results; diff --git a/app/js/controllers/results.js b/app/js/controllers/results.js index 7cff6e162..10587db2c 100644 --- a/app/js/controllers/results.js +++ b/app/js/controllers/results.js @@ -1,5 +1,5 @@ 'use strict'; -define(['angular', 'mcda/lib/patavi', 'underscore', 'NProgress'], function(angular, patavi, _, NProgress) { +define(['mcda/config', 'angular', 'mcda/lib/patavi', 'underscore', 'NProgress'], function(Config, angular, patavi, _, NProgress) { return function($rootScope, $scope, currentScenario, taskDefinition) { var alternatives; var criteria; @@ -9,7 +9,7 @@ define(['angular', 'mcda/lib/patavi', 'underscore', 'NProgress'], function(angul var run = function(state) { state = angular.copy(state); var data = _.extend(state.problem, { "preferences": state.prefs, "method": "smaa" }); - var task = patavi.submit('smaa', data); + var task = patavi.submit(Config.pataviService, data); var successHandler = function(results) { $scope.$root.$safeApply($scope, function() { diff --git a/app/js/controllers/scaleRange.js b/app/js/controllers/scaleRange.js index 6b0c9b867..835d47ddb 100644 --- a/app/js/controllers/scaleRange.js +++ b/app/js/controllers/scaleRange.js @@ -1,5 +1,5 @@ 'use strict'; -define(['angular', 'mcda/lib/patavi', 'underscore'], function(angular, patavi, _) { +define(['mcda/config', 'angular', 'mcda/lib/patavi', 'underscore'], function(Config, angular, patavi, _) { return function($scope, currentScenario, taskDefinition) { $scope.title = taskDefinition.title; @@ -22,20 +22,26 @@ define(['angular', 'mcda/lib/patavi', 'underscore'], function(angular, patavi, _ code: (code && code.desc) ? code.desc : code, cause: error }; - $scope.$root.$broadcast('error', message); + $scope.$root.$broadcast('patavi.error', message); }; var successHandler = function(state, results) { var scales = {}; var choices = {}; $scope.$root.$safeApply($scope, function() { - _.map(_.pairs(results.results[0]), function(criterion) { + _.map(_.pairs(results.results), function(criterion) { + + // Calculate interval hulls + var criterionRange = [ + Math.min.apply(null, _.map(_.values(criterion[1]), function(alt) { return alt["2.5%"] })), + Math.max.apply(null, _.map(_.values(criterion[1]), function(alt) { return alt["97.5%"] })) + ]; // Set inital model value var pvf = state.problem.criteria[criterion[0]].pvf; var problemRange = pvf ? pvf.range : null; - var from = problemRange ? problemRange[0] : criterion[1]['2.5%']; - var to = problemRange ? problemRange[1] : criterion[1]['97.5%']; + var from = problemRange ? problemRange[0] : criterionRange[0]; + var to = problemRange ? problemRange[1] : criterionRange[1]; choices[criterion[0]] = { lower: from, @@ -55,8 +61,8 @@ define(['angular', 'mcda/lib/patavi', 'underscore'], function(angular, patavi, _ return val > scale[1] ? scale[1] : val; }; scales[criterion[0]] = { - restrictFrom: criterion[1]['2.5%'], - restrictTo: criterion[1]['97.5%'], + restrictFrom: criterionRange[0], + restrictTo: criterionRange[1], from: boundFrom(nice(from) - margin), to: boundTo(nice(to) + margin), increaseFrom: function() { @@ -78,7 +84,7 @@ define(['angular', 'mcda/lib/patavi', 'underscore'], function(angular, patavi, _ var scenario = currentScenario; var state = taskDefinition.clean(scenario.state); - var calculateScales = patavi.submit('smaa', _.extend(state.problem, { + var calculateScales = patavi.submit(Config.pataviService, _.extend(state.problem, { 'method': 'scales' })); calculateScales.results.then(_.partial(successHandler, state), errorHandler); @@ -112,4 +118,4 @@ define(['angular', 'mcda/lib/patavi', 'underscore'], function(angular, patavi, _ scenario.redirectToDefaultView(); }; }; -}); \ No newline at end of file +});