Skip to content

Commit

Permalink
Merge pull request #252 from RobokopU24/update/ui-tweaks
Browse files Browse the repository at this point in the history
Update/UI tweaks
  • Loading branch information
Woozl authored Apr 18, 2023
2 parents 8caabab + 120ab6c commit a97675c
Show file tree
Hide file tree
Showing 13 changed files with 439 additions and 514 deletions.
11 changes: 4 additions & 7 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { useState, useEffect } from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import {
BrowserRouter, Switch, Route, Redirect,
} from 'react-router-dom';
import { ThemeProvider, StylesProvider } from '@material-ui/core/styles';
import { Auth0Provider } from '@auth0/auth0-react';

import Landing from '~/pages/Landing';
import Logout from '~/pages/Logout';
import About from '~/pages/About';
import Help from '~/pages/Help';
import Guide from '~/pages/Guide';
import TermsofService from '~/pages/TermsofService';
import QueryBuilder from '~/pages/queryBuilder/QueryBuilder';
Expand Down Expand Up @@ -71,9 +71,6 @@ export default function App() {
<Route path="/about">
<About />
</Route>
<Route path="/help">
<Help />
</Route>
<Route path="/guide">
<Guide />
</Route>
Expand All @@ -93,7 +90,7 @@ export default function App() {
<QueryBuilder />
</Route>
<Route path="/">
<Landing />
<Redirect to="/question" />
</Route>
</Switch>
</div>
Expand Down
7 changes: 3 additions & 4 deletions src/components/header/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, {
useState,
} from 'react';
import { Link } from 'react-router-dom';
import { Link as MuiLink } from '@material-ui/core';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Button from '@material-ui/core/Button';
Expand All @@ -24,13 +25,11 @@ export default function Header() {
return (
<AppBar position="relative" className="header">
<Toolbar id="headerToolbar">
<Link to="/" id="robokopBrand">ROBOKOP</Link>
<Link to="/questions">Question Library</Link>
<Link to="/answer">Answer Viewer</Link>
<MuiLink href="https://robokop.renci.org" id="robokopBrand">ROBOKOP</MuiLink>
<div className="grow" />
<Link to="/about">About</Link>
<Link to="/help">Help</Link>
<Link to="/guide">Guide</Link>
<a href="https://robokop.renci.org/#contact" target="_blank" rel="noreferrer">Help</a>
<Divider orientation="vertical" variant="middle" flexItem />
<IconButton
onClick={(e) => (
Expand Down
79 changes: 14 additions & 65 deletions src/pages/About.jsx
Original file line number Diff line number Diff line change
@@ -1,85 +1,34 @@
import React, { useState, useEffect } from 'react';
import React from 'react';

import {
Grid, Row, Col, Panel,
Grid, Row, Col,
} from 'react-bootstrap';

export default function About() {
const [licenses, updateLicenses] = useState([]);

useEffect(() => {
// this.appConfig.licenses(
// licenses => this.setState({ licenses }),
// err => console.log('Failed to retrieve license information. This may indicate a connection issue.', err),
// );
updateLicenses([]);
}, []);

return (
<Grid style={{ marginBottom: '50px' }}>
<Row>
<Col md={8}>
<h2>About Robokop</h2>
<hr />
<h3>Overview</h3>
<p>Knowledge graphs (KGs) are becoming more and more popular to store data from which higher-level analysis can be implemented. KGs typically get stored as graph-databases, and queries on those databases can be used to answer questions of interest posed by users, in our case, biomedical researchers. For queries containing just a few data points, the number of connections in the knowledge graph and the storage and analysis of the results are simple. However, for more complex queries, the analysis of the results gets exponentially harder. For instance, a relatively complex query can return a knowledge graph with hundreds of thousands of results. We created ROBOKOP (Reasoning Over Biomedical Objects linked in Knowledge Oriented Pathways) as a way for users to more easily query knowledge graphs and store, rank, and explore query results.</p>
<p>Knowledge graphs (KGs) are becoming more and more popular as an approach for storing data, integrating data, and implementing high-level reasoning algorithms to derive insights from the integrated and harmonized knowledge sources. KGs typically are stored as graph databases, and queries on those databases can be used to answer user questions. ROBOKOP has been developed specifically to support biomedical questions such as <em>“what diseases are associated with dioxins?”</em>. As such, nodes represent biomedical entities, and edges represent predicates that define the relationship between nodes. Statements or assertions in a graph are structured as subject-predicate-object relationships or triples, for example, <em>“dioxins (subject) - associated_with (predicate) - cancer (object)”</em> or <em>“dioxins are associated with cancer”</em>.</p>
<p>The ROBOKOP KG can be queried through the ROBOKOP user interface (UI) or by direct Cypher query. Most users will find that the ROBOKOP UI provides a more convenient query tool than Cypher query and also allows users to more readily explore knowledge subgraphs or answers and associated provenance and publication support.</p>
<hr />
<h3>Questions and Answers</h3>
<p>Queries (read as Questions) are JSON templates that have been abstracted into a more friendly user interface (UI). Each node in the question subgraph signifies an entity with a category and specified properties, and edges with predicate categories can be specified to limit the allowable relationships between nodes. If multiple predicates are given, then edges that match any predicates will be included, and if no predicates are given, then edges are not limited. Results of the query (read as Answers) are subgraphs that match the categories and desired properties of the nodes and edges. Answers are stored using bindings of the nodes and edges in the question as references in the local knowledge graph. This format is efficient in that nodes and edges that are used in multiple answers do not require duplication. Additionally, the nodes and edges within each answer are bound to the nodes and edges of the question. This makes the analysis of complex questions containing repeated node categories, or even repeats of the same node, transparent.</p>
<p>Questions or queries are represented in ROBOKOP as JSON templates that have been abstracted into a more friendly UI. Each node in the query graph denotes a biomedical entity with a defined category (e.g., disease) and defined properties (e.g., breast cancer versus cancer); likewise, each edge denotes a predicate that can be specified to limit the allowable relationships between nodes (e.g., associated_with). Nodes and edges can be specified by way of text description, using the autocomplete drop-down menu, or, for nodes, by directly entering a CURIE (Compact Uniform Resource Identifier) (e.g., MONDO:0004989 for breast cancer).
</p>
<p>The node categories and edge categories are defined by Biolink Model, which is an open-source data model and upper-level ontology that formalizes the relationships between biomedical entities such as gene, disease, chemical, and phenotype as a set of hierarchical interconnected categories and relationships between them or predicates, e.g., <em>“chemical entity X causes disease Y”</em> or <em>“drug X treats disease Y”</em>. Biolink serves as the “semantic glue” for the ROBOKOP application by enabling integration and harmonization across ROBOKOP KG’s diverse underlying knowledge sources. For more information on Biolink Model, please refer to <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC9372416/" target="_blank" rel="noreferrer">Unni et al. 2022</a> and the <a href="https://biolink.github.io/biolink-model/" target="_blank" rel="noreferrer">Biolink GitHub website</a>.</p>
<p>Query results are in the form of knowledge subgraphs or answers that match the categories and desired properties of the nodes and edges.</p>
<hr />
<h3>Answer Ranking</h3>
<p>Questions that are asked with very few node and edge properties or with many nodes and edges typically result in a lot of answers. As such, the ranking of answer subgraphs by relevance is critical for user analysis. The ROBOKOP answer-ranking algorithm weights each edge within each subgraph based on the number of PubMed article abstracts that cite both the source and target nodes. The publication support is provided by an additional ROBOKOP service, OmniCorp, that contains a graph of PubMed identifiers linked to node categories referenced within abstracts. A weighted score for each answer is calculated based on the distance from one node to another given the nodes and edges between them and from the publication counts provided by curated data sources and Omnicorp.</p>
<h3>Answer Scoring and Ranking</h3>
<p>Questions or queries that include very few nodes and edges or that include many specified nodes and edges typically result in numerous knowledge subgraphs or answers. As such, the scoring and ranking of answers by relevance is critical for user analysis. ROBOKOP scores and ranks each answer within an answer set using a complex scoring algorithm. In brief, the ROBOKOP answer scoring-and-ranking algorithm weights each edge within each knowledge subgraph based on the number of supporting PubMed publications. The publication support is provided by either the curated knowledge source from which a particular edge was derived or by an additional ROBOKOP service, termed OmniCorp, which contains a graph of PubMed identifiers linked to node categories or biomedical entities co-occurring within PubMed abstracts. The ROBOKOP answer scoring-and-ranking algorithm treats publications derived from curated knowledge sources with greater importance than those derived from OmniCorp.</p>
<hr />
<h3>APIs, Knowledge Sources, and Automated Workflows and Modules</h3>
<p>
{'An extensive list of Robokop resources can be found at '}
<a target="_blank" rel="noopener noreferrer" href="https://researchsoftwareinstitute.github.io/data-translator/apis">RSI Data Translator</a>
{' or users can view all publicly available APIs by going to the '}
<a href="/apidocs/">APIDocs</a>
{' page.'}
</p>
<h3>ROBOKOP Knowledge Sources</h3>
<p>Information on ROBOKOP’s knowledge sources, including URLs, their publicly available application programming interfaces (APIs), and other resources, can be found on the <a href="https://robokop.renci.org/api-docs/docs/category/automat" target="_blank" rel="noreferrer">Automat page</a>.</p>
<hr />
<h3>Open Source</h3>
<p>
{'This project is open source. All the code can be found on GitHub: '}
<a href="https://github.com/NCATS-Gamma">Robokop</a>
</p>
<Panel style={{ marginTop: 30 }}>
<Panel.Heading style={{ padding: 0 }}>
<Panel.Title toggle>
<h3 style={{ margin: 0, padding: 20 }}>Source Licenses</h3>
</Panel.Title>
</Panel.Heading>
<Panel.Collapse>
<Panel.Body>
{licenses.map((license) => (
<div key={license.name}>
<hr />
<h3>{license.name}</h3>
<p>
{'Home: '}
<a href={license.url}>{license.url}</a>
</p>
<p>
{'Type: '}
{license.license}
</p>
<p>
{'License: '}
<a href={license.license_url}>{license.license_url}</a>
</p>
<p>
{'Citation: '}
<a href={license.citation_url}>{license.citation_url}</a>
</p>
</div>
))}
{licenses.length === 0 && (
<p>Loading licenses...</p>
)}
</Panel.Body>
</Panel.Collapse>
</Panel>
<h3>Open-source Licensing</h3>
<p>ROBOKOP is an open-source software application licensed under the <a href="https://opensource.org/license/mit/" target="_blank" rel="noreferrer">MIT license</a>. All software code can be found on the <a href="https://github.com/RobokopU24" target="_blank" rel="noreferrer">ROBOKOP GitHub repository</a>.</p>
</Col>
</Row>
</Grid>
Expand Down
Loading

0 comments on commit a97675c

Please sign in to comment.