Skip to content

Commit

Permalink
Merge pull request #266 from RobokopU24/update/trapi-1-4
Browse files Browse the repository at this point in the history
Parse TRAPI 1.4
  • Loading branch information
Woozl authored Oct 23, 2023
2 parents ed3b3ea + bc9a0b6 commit e1cec4c
Show file tree
Hide file tree
Showing 7 changed files with 3,266 additions and 3,844 deletions.
6,975 changes: 3,169 additions & 3,806 deletions api_routes/sample-query-cache.json

Large diffs are not rendered by default.

28 changes: 27 additions & 1 deletion src/pages/answer/resultsTable/AttributesTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const PublicationLinkCell = ({ value }) => {
);
};

const AttributesTable = ({ attributes }) => (
const AttributesTable = ({ attributes, sources }) => (
<Box style={{ maxHeight: 500, overflow: 'auto' }}>
<Table size="small" aria-label="edge attributes table">
<TableHead style={{ position: 'sticky', top: 0 }}>
Expand All @@ -96,6 +96,32 @@ const AttributesTable = ({ attributes }) => (
}
</TableRow>
))}
<TableRow>
<TableCell>
Sources
</TableCell>
<TableCell>
{Array.isArray(sources) && sources.map((source, i) => (
<section key={i}>
<p style={{ marginBottom: '0px', fontStyle: 'italic' }}>{source.resource_id}</p>
<p style={{ filter: 'opacity(0.75)', fontSize: '0.8em' }}>{source.resource_role}</p>
{Boolean(source.upstream_resource_ids) && Array.isArray(source.upstream_resource_ids) && (
<>
<p style={{ marginBottom: '0px' }}>Upstream resource ids:</p>
<ul>
{source.upstream_resource_ids.map((urid, j) => (
<li key={j}>
{urid}
</li>
))}
</ul>
</>
)}
{i === sources.length - 1 ? null : <hr />}
</section>
))}
</TableCell>
</TableRow>
</StyledTableBody>
</Table>
</Box>
Expand Down
9 changes: 5 additions & 4 deletions src/pages/answer/resultsTable/ResultExplorer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ export default function ResultExplorer({ answerStore }) {
.map((key) => ({
...answerStore.selectedResult.edges[key],
attributes: answerStore.resultJSON.knowledge_graph.edges[key].attributes,
sources: answerStore.resultJSON.knowledge_graph.edges[key].sources,
}));
// this is weird, but stops the simulation from throwing a
// `d3 cannot create property 'vx' on string` error when trying to move edges
Expand Down Expand Up @@ -262,7 +263,7 @@ export default function ResultExplorer({ answerStore }) {
.attr('stroke', '#999');
})
.on('click', function (e) {
handleClickEdge(e, d3.select(this).datum().attributes);
handleClickEdge(e, d3.select(this).datum());
}),
(update) => update
.call((e) => e.select('title')
Expand Down Expand Up @@ -313,10 +314,10 @@ export default function ResultExplorer({ answerStore }) {
}
}

const handleClickEdge = (event, attributes) => {
const handleClickEdge = (event, data) => {
setPopoverPosition({ x: event.clientX, y: event.clientY });

setPopoverData(attributes);
setPopoverData(data);
setPopoverOpen('edge');
};

Expand Down Expand Up @@ -378,7 +379,7 @@ export default function ResultExplorer({ answerStore }) {
anchorPosition={{ top: popoverPosition.y, left: popoverPosition.x }}
above
>
<AttributesTable attributes={popoverData} />
<AttributesTable attributes={popoverData.attributes} sources={popoverData.sources} />
</Popover>

<Popover
Expand Down
74 changes: 49 additions & 25 deletions src/pages/answer/useAnswerStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,28 @@ export default function useAnswerStore() {
setResultJSON({});
}

/**
* Takes a TRAPI message and average the analysis scores for each
* result, and places that average in a new key called `score` on
* each result object.
* @param {object} msg - TRAPI message
*/
function averageAnalysesScores(msg) {
const resultsWithScore = msg.results.map((result) => {
// get average score of all analyses
const score = result.analyses.reduce((sum, analysis) => sum + analysis.score, 0) / result.analyses.length;
return {
...result,
score,
};
});

return {
...msg,
results: resultsWithScore,
};
}

/**
* Initialize the answer store with a message
*
Expand All @@ -37,7 +59,7 @@ export default function useAnswerStore() {
* @param {object} msg - TRAPI message
*/
function initialize(msg, updateDisplayState) {
setMessage(msg);
setMessage(averageAnalysesScores(msg));
if (msg.knowledge_graph && msg.results) {
setKgNodes(kgUtils.makeDisplayNodes(msg, hierarchies));
updateDisplayState({ type: 'toggle', payload: { component: 'kg', show: true } });
Expand Down Expand Up @@ -94,35 +116,37 @@ export default function useAnswerStore() {
}
});
});

const edges = {};
const edgesJSON = {};
Object.values(row.edge_bindings).forEach((value) => {
value.forEach((kgObject) => {
const kgEdge = message.knowledge_graph.edges[kgObject.id];
edgesJSON[kgObject.id] = kgEdge || 'Unknown';
if (kgEdge) {
const graphEdge = {
id: kgObject.id,
source: kgEdge.subject,
target: kgEdge.object,
predicate: kgEdge.predicate,
};
edges[kgObject.id] = graphEdge;
if (kgEdge.subject in nodes) {
nodes[kgEdge.subject].score += 1;
row.analyses.forEach((analysis) => {
Object.values(analysis.edge_bindings).forEach((edgeBindings) => {
edgeBindings.forEach((binding) => {
const kgEdge = message.knowledge_graph.edges[binding.id];
edgesJSON[binding.id] = kgEdge || 'Unknown';
if (kgEdge) {
const graphEdge = {
id: binding.id,
source: kgEdge.subject,
target: kgEdge.object,
predicate: kgEdge.predicate,
};
edges[binding.id] = graphEdge;
if (kgEdge.subject in nodes) {
nodes[kgEdge.subject].score += 1;
}
if (kgEdge.object in nodes) {
nodes[kgEdge.object].score += 1;
}
const subjectNode = message.knowledge_graph.nodes[kgEdge.subject];
const objectNode = message.knowledge_graph.nodes[kgEdge.object];
const edgeKey = `${subjectNode.name || kgEdge.subject} ${stringUtils.displayPredicate(kgEdge.predicate)} ${objectNode.name || kgEdge.object}`;
publications[edgeKey] = resultsUtils.getPublications(kgEdge);
}
if (kgEdge.object in nodes) {
nodes[kgEdge.object].score += 1;
}

const subjectNode = message.knowledge_graph.nodes[kgEdge.subject];
const objectNode = message.knowledge_graph.nodes[kgEdge.object];
const edgeKey = `${subjectNode.name || kgEdge.subject} ${stringUtils.displayPredicate(kgEdge.predicate)} ${objectNode.name || kgEdge.object}`;

publications[edgeKey] = resultsUtils.getPublications(kgEdge);
}
});
});
});

setSelectedResult({ nodes, edges });
setSelectedRowId(rowId);
setMetaData(publications);
Expand Down
6 changes: 5 additions & 1 deletion src/utils/fetchCuries.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ export default async function fetchCuries(entity, displayAlert, cancel) {
'Failed to contact name resolver to search curies. Please try again later.');
return [];
}
const curieResponse = Object.keys(response);

if (!Array.isArray(response)) {
return [];
}
const curieResponse = response.map((node) => node.curie);
if (!curieResponse.length) {
return [];
}
Expand Down
8 changes: 4 additions & 4 deletions src/utils/trapi.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ function validateResults(results) {
errors.push('Results node_bindings is not a valid JSON object');
}

if (!('edge_bindings' in results[i])) {
errors.push('No edge_bindings in result object');
} else if (results[i].edge_bindings.constructor !== Object) {
errors.push('Results edge_bindings is not a valid JSON object');
if (!('analyses' in results[i])) {
errors.push('No analyses in result object');
} else if (!Array.isArray(results[i].analyses)) {
errors.push('Results analyses is not an array');
}
if (errors.length) {
break;
Expand Down
10 changes: 7 additions & 3 deletions tests/common/test_message.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,13 @@
"n0": [{ "id": "1" }],
"n1": [{ "id": "2" }]
},
"edge_bindings": {
"e0": [{ "id": "1" }]
}
"analyses": [
{
"edge_bindings": {
"e0": [{ "id": "1" }]
}
}
]
}
]
}
Expand Down

0 comments on commit e1cec4c

Please sign in to comment.