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

Feature/expand models running #197

Merged
merged 2 commits into from
Sep 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -709,10 +709,10 @@ There are few things that can be setup from outside:
- **`algorithms`** (attr. `data-algorithms`): Whether to list available algorithms, rather than available models. Default: _false_.
- **`maxStars`** (attr. `data-max-stars`): How many stars are considered maximum, when building the long version of ratings. Default: _10_.
- **`shortStars`** (attr. `data-short-stars`): Whether to show show star rating notation, i.e. - one star and the number of stars next to it, opposed to the long (default) version - always showing the maximum number of stars, with given number of them - highlighted. Default is _false_.
- **`loadOnInit`** (attr. `data-load-on-init`): Whether to make an initial query even when _modelUri_ or _algorithmNeedle_ are not specified. Default is _false_.
- **`loadOnInit`** (attr. `data-load-on-init`): Whether to make an initial query even when _modelUri_ or _algorithmFilter_ are not specified. Default is _false_.
- **`sDom`** (attr. `data-s-dom`): The redefinition of _sDom_ attribute for the table. Default _"\<Fif\>rt"_.
- **`modelUri`** (attr. `data-model-uri`): The address to query for list of models. If none is passed, the standard `<baseURL>/model` is used.
- **`algorithmNeedle`** (attr. `data-algorithms-needle`): If algorithms listing mode is selected (`algorithms` = _true_) - this is the needle to be used when listing them. Default: _null_.
- **`algorithmFilter`** (attr. `data-algorithm-filter`): If algorithms listing mode is selected (`algorithms` = _true_) - this is the needle to be used when listing them. Default: _null_.
- **`forceCreate`** (attr. `data-force-create`): When creating a model from an algorithm, the kit usually tries to obtain one from the server, and only if that fails it makes a _create model_ query, unless this option is specified, which instructs the kit to directly try to create a new one. Default _false_.


Expand Down
2 changes: 1 addition & 1 deletion scripts/toxcompound.js
Original file line number Diff line number Diff line change
Expand Up @@ -1034,7 +1034,7 @@ cls.prototype.init = function () {
var feat = jT.$.extend({}, features[fId]);
feat.value = entry.values[fId];
if (!!feat.title) {
if (ccLib.fireCallback(callback, null, feat, fId) !== false) {
if (ccLib.fireCallback(callback, null, feat, fId, data.length) !== false) {
if (!feat.value)
feat.value = '-';
data.push(feat);
Expand Down
6 changes: 3 additions & 3 deletions scripts/toxmodel.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var jToxModel = (function () {
sDom: "<Fif>rt", // merged to dataTable's settings, when created
loadOnInit: false, // whether to make a (blank) request upon loading
oLanguage: null, // merged to dataTable's settings, when created
/* algorithmNeedle */
/* algorithmFilter */
/* modelUri */
configuration: {
columns : {
Expand Down Expand Up @@ -64,7 +64,7 @@ var jToxModel = (function () {
}

// finally, wait a bit for everyone to get initialized and make a call, if asked to
if (self.settings.modelUri != null || self.settings.algorithmNeedle != null || self.settings.loadOnInit)
if (self.settings.modelUri != null || self.settings.algorithmFilter != null || self.settings.loadOnInit)
self.query();
};

Expand Down Expand Up @@ -222,7 +222,7 @@ var jToxModel = (function () {

cls.prototype.query = function (uri) {
if (this.settings.algorithms)
this.listAlgorithms(this.settings.algorithmNeedle = (uri || this.settings.algorithmNeedle));
this.listAlgorithms(this.settings.algorithmFilter = (uri || this.settings.algorithmFilter));
else
this.listModels(this.settings.modelUri = (uri || this.settings.modelUri));
};
Expand Down
2 changes: 1 addition & 1 deletion toxmodel.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

</head>
<body>
<div class="jtox-toolkit" data-kit="model" data-algorithm-link="true" data-algorithm-needle="ToxTree" data-algorithms="true" data-load-on-init="true" data-base-url="http://apps.ideaconsult.net:8080/ambit2"></div>
<div class="jtox-toolkit" data-kit="model" data-algorithm-link="true" data-algorithm-filter="ToxTree" data-algorithms="true" data-load-on-init="true" data-base-url="http://apps.ideaconsult.net:8080/ambit2"></div>
<div class="jtox-template">
<!--[[ jT.templates['all-model'] -->
<div id="jtox-model" class="jtox-model">
Expand Down
1 change: 1 addition & 0 deletions uses/ui-toxtree.css → uses/ui-prediction.css
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ body>div.jtox-toolkit {

#tt-models-panel .content .tt-explanation {
margin: 5px;
padding: 5px;
background: #fefefe;
border: 1px solid #aaa;
border-radius: 5px;
Expand Down
19 changes: 8 additions & 11 deletions uses/ui-toxtree.html → uses/ui-prediction.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" >

<title>ToxTree web interface</title>
<title>Model Prediction</title>
<link rel="stylesheet" href="../tests/base.css"/>
<link rel="stylesheet" href="../tests/skeleton-fluid.css"/>
<link rel="stylesheet" href="../tests/layout.css"/>
Expand All @@ -18,7 +18,7 @@

<link rel="stylesheet" href="../www/jtoxkit.css"/>
<link rel="stylesheet" href="../www/ketcher.css"/>
<link rel="stylesheet" href="ui-toxtree.css"/>
<link rel="stylesheet" href="ui-prediction.css"/>

<script src="oecdcategories.js"></script>

Expand All @@ -32,12 +32,12 @@

<script src="../www/jtoxkit.js"></script>
<script src="../www/ketcher.js"></script>
<script src="ui-toxtree.js"></script>
<script src="ui-prediction.js"></script>
</head>
<body>
<div id="logger" class="jtox-toolkit jtox-widget hidden" data-kit="log" data-resend-events="false" data-right-side="true"></div>

<div class="jtox-toolkit" data-kit="query" data-configuration="config_toxtree" data-base-url="https://apps.ideaconsult.net/data">
<div class="jtox-toolkit" data-kit="query" data-configuration="config_model" data-base-url="https://apps.ideaconsult.net/data">
<div class="jtox-toolkit jtox-widget cc-fixed" data-kit="search"></div>
<div id="tt-bigpane" class="cc-flex">
<div>
Expand All @@ -59,9 +59,9 @@
<div class="title jtox-inline"><span class="counter-field">Toxicity prediction modules (0/0)</span></div>
<div class="jtox-inline selections"><a href="#" class="select-unselect" title="(Un)select all algorithms" data-other="unselect">select</a>&nbsp;<a href="#" class="expand-collapse" title="Expand/collapse all algorithm panes" data-other="collapse">expand</a>&nbsp;<a href="#" class="run-selected" title="Run predictions for all selected algorithms">run</a>&nbsp;<a href="#" class="show-hide" data-other="show" title="Hide/show unselected algorithms">hide</a></div>
</div>
<div class="jtox-toolkit jtox-widget cc-flex size-full" data-kit="model" data-algorithms="true" data-no-interface="true" data-on-loaded="onAlgoLoaded" data-algorithm-needle="ToxTree"></div>
<div class="jtox-toolkit jtox-widget cc-flex size-full" data-kit="model" data-algorithms="true" data-no-interface="true" data-on-loaded="onAlgoLoaded"></div>
</div>
<div id="tt-table" class="jtox-toolkit jtox-panel" data-kit="compound" data-configuration="config_toxtree" data-manual-init="true" data-pre-details="onTableDetails" data-show-tabs="false" data-on-loaded="onDataLoaded" data-selection-handler="checked"></div>
<div id="tt-table" class="jtox-toolkit jtox-panel" data-kit="compound" data-configuration="config_model" data-manual-init="true" data-pre-details="onTableDetails" data-show-tabs="false" data-on-loaded="onDataLoaded" data-selection-handler="checked"></div>
</div>
</div>
<div id="sidebar">
Expand All @@ -88,12 +88,9 @@
<button class="jt-toggle jtox-handler model" data-handler="makeModel" title="Prepare the model for this algorithm">M</button>
<button class="jt-toggle jtox-handler auto" data-handler="markAuto" title="Run automatically on new queries">A</button>
</div>
<div class="tt-classification">
</div>
</div>
<div class="content">
<div class="tt-explanation"></div>
<div class="tt-classification"></div>
</div>
<div class="content"></div>
</div>
</div>
</body>
Expand Down
185 changes: 120 additions & 65 deletions uses/ui-toxtree.js → uses/ui-prediction.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var tt = {
]
};

var config_toxtree = {
var config_model = {
"baseFeatures": {}, // to be expanded upon algorithm loading
"handlers": {
"query": function (e, query) {
Expand All @@ -42,7 +42,7 @@ var config_toxtree = {
"http://www.opentox.org/api/1.1#EINECS",
"http://www.opentox.org/api/1.1#IUCLID5_UUID"
],
"ToxTree": [] // to be expanded upon algorithm loading
"Models": [] // to be expanded upon algorithm loading
}
};

Expand Down Expand Up @@ -121,50 +121,36 @@ function runSelected() {
}

function formatAlgoName(val) {
return (val.indexOf('ToxTree: ') == 0) ? val = val.substr(9) : val;
return val.replace(/^\w+:\s+/, "");
}

function buildCategories(features, values) {
var cats = [];
var regex = /\^\^(\S+)Category/i;
var multi = false;

for (var fId in values) {
if (features[fId].title.indexOf('#explanation') > -1 || features[fId].source.type.toLowerCase() != 'model')
continue;
var val = values[fId];
var anot = features[fId].annotation;
if (anot.length > 0) {
if (cats.length > 0)
multi = true;
for (var i = 0;i < anot.length; ++i) {
cats.push({
name: features[fId].title.replace(/\s/g, '&nbsp;'),
title: anot[i].o.replace(/\s/g, '&nbsp;'),
toxicity: anot[i].type.replace(regex, '$1').toLowerCase(),
active: anot[i].o == val
});
}
}
else
cats.push({
name: features[fId].title.replace(/\s/g, '&nbsp;'),
title: val,
toxicity: 'unknown',
active: true
});
};

if (multi) {
var old = cats;
cats = [];
$.map(old, function (o) {
function mergeCategories(features, indices) {
var cats = [];
for (var i = 0; i < indices.length; ++i) {
$.map(features[indices[i]].categories, function (o) {
if (o.active) {
o.title = o.name + ':&nbsp;' + o.title;
cats.push(o);
}
});
});
}

return cats;
}

function buildCategories(feature) {
anot = feature.annotation;
if (!anot || anot.length == 0)
return null;
var cats = [],
regex = /\^\^(\S+)Category/i;
for (var i = 0;i < anot.length; ++i) {
cats.push({
name: feature.title.replace(/\s/g, '&nbsp;'),
title: anot[i].o.replace(/\s/g, '&nbsp;'),
toxicity: anot[i].type.replace(regex, '$1').toLowerCase(),
active: anot[i].o == feature.value
});
}

return cats;
Expand Down Expand Up @@ -204,8 +190,8 @@ function onAlgoLoaded(result) {
};

$(this).data('algoId', data.id);
config_toxtree.groups.ToxTree.push(data.uri);
config_toxtree.baseFeatures[data.uri] = {
config_model.groups.Models.push(data.uri);
config_model.baseFeatures[data.uri] = {
title: formatAlgoName(data.name),
search: false,
data: "index",
Expand Down Expand Up @@ -244,7 +230,7 @@ function addFeatures(data, className) {
enumFn = function () { $(this).addClass(className); };
$('.' + className, tt.featuresList).remove();
}
ccLib.populateData(tt.featuresList, '#tt-feature', data, enumFn);
ccLib.populateData(tt.featuresList, '#tt-feature', data.filter(function (e) { return e.explanation == null; }), enumFn);
var sep = $('#tt-feature')[0].cloneNode(true);
sep.removeAttribute('id');
$(sep).addClass('separator').empty();
Expand Down Expand Up @@ -307,51 +293,120 @@ function showCompound() {
}

function showPrediction(algoId) {
var map = tt.algoMap[algoId];
var mapRes = map.results[tt.compoundIdx];
var map = tt.algoMap[algoId],
mapRes = map.results[tt.compoundIdx];

// check if we have results for this guy at all...
if (mapRes == null || mapRes.data == null)
return;

addFeatures(mapRes.data, algoId);
var aEl = map.dom;
if (mapRes.explanation != null)
$('.tt-explanation', aEl).html(mapRes.explanation.replace(/(Yes|No)/g, '<span class="answer $1">$1</span>'));
var aEl = map.dom,
$expEl = $('.content', aEl).empty();

if (mapRes.submodels && mapRes.submodels.length) {
mapRes.submodels.forEach(function (el, subIdx) {
addFeatures(el.data, algoId + "-" + subIdx);
if (!el.explanation) {
el.explanation = "";
el.data.forEach(function (feature) {
if (!feature.annotation || !feature.annotation.length)
el.explanation += feature.title + "&nbsp;:&nbsp;<strong>" + jT.ui.valueWithUnits(feature.value, feature.units) + "</strong><br/>";
});
}

if (!!el.explanation)
$expEl.append('<div class="tt-explanation">' + el.explanation + '</div>');
});
}
else { // Singe model mode
addFeatures(mapRes.data, algoId);
if (mapRes.explanation != null)
$expEl.append('<div class="tt-explanation">' + mapRes.explanation + '</div>');
}

$('.tt-classification', aEl).empty();


fillClassification($('.tt-classification', aEl)[0], mapRes.categories);
$(aEl).removeClass('folded');
}

function splitFeatures(features) {
var lastURI = features[0].source.URI,
subs = [],
catFeatures = [],
descIndex = null;

for (var e, i = 0;; ++i) {
if (i >= features.length || features[i].source.URI != lastURI) {
e = { data: features.splice(0, i) };
if (catFeatures.length > 1)
e.categories = mergeCategories(e.data, catFeatures);
else if (catFeatures.length == 1)
e.categories = e.data[catFeatures[0]].categories;

if (descIndex != null)
e.explanation = e.data[descIndex].explanation;

subs.push(e);

i = 0;
descIndex = null;
catFeatures = [];
}

if (i >= features.length)
break;
else if (features[i].explanation != null)
descIndex = i;
else if (features[i].categories != null)
catFeatures.push(i);
lastURI = i < features.length ? features[i].source.URI : null;
}

return subs;
}

function parsePrediction(result, algoId, index) {
var map = tt.algoMap[algoId];

var cells = $('#tt-table table td.' + algoId);
for (var i = 0, rl = result.dataEntry.length; i < rl; ++i) {
var idx = i + (index || 0);
var mapRes = map.results[idx];
if (mapRes == null){
var idx = i + (index || 0),
mapRes = map.results[idx],
catFeatures = [];

if (mapRes == null)
map.results[idx] = mapRes = {};
}
mapRes.explanation = '';
mapRes.data = jToxCompound.extractFeatures(result.dataEntry[i], result.feature, function (feature, fId) {
if (feature.title.indexOf("#explanation") > -1) {
mapRes.explanation = feature.value;

mapRes.data = jToxCompound.extractFeatures(result.dataEntry[i], result.feature, function (feature, fId, fIdx) {
if (feature.source.type.toLowerCase() != 'model' || !feature.value)
return false;

if (feature.title.endsWith("#explanation"))
feature.explanation = feature.value.replace(/\W(Yes|No)\W/g, '<span class="answer $1">$&</span>');
else {
feature.categories = buildCategories(feature);
if (feature.categories != null)
catFeatures.push(fIdx)
}
else if (feature.source.type.toLowerCase() == 'model' && !!feature.value)
return true;
else
return false;
return true;
});

mapRes.categories = buildCategories(result.feature, result.dataEntry[i].values);
// Make the combined categories in any case for the table mode
if (catFeatures.length > 1)
mapRes.categories = mergeCategories(mapRes.data, catFeatures);
else if (catFeatures.length == 1)
mapRes.categories = mapRes.data[catFeatures[0]].categories;

if (mapRes.categories.length == 0 && index == null){
runPredict ($('button', cells[idx]), algoId);
if (tt.modelKit.settings.multiModels && mapRes.data.length > 1) {
mapRes.data.sort(function (a, b) { return a.title < b.title ? -1 : (a.title > b.title ? 1 : 0); });
mapRes.submodels = splitFeatures(mapRes.data);
}
else // !multiModels
mapRes.explanation = mapRes.data.find(function (e) { return e.explanation != null; }).explanation;

// Finally, fill the table cell.
if (mapRes.categories.length == 0 && index == null)
runPredict ($('button', cells[idx]), algoId);
else {
$('.tt-class', cells[idx]).remove();
$(cells[idx]).addClass('calculated');
Expand Down
Loading