Skip to content
Merged

v0.27.0 #1256

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
3c82d53
Merge pull request #1245 from PathwayCommons/v0.26.0
jvwong Feb 2, 2024
1cbdeee
Merge branch 'master' into diff-master
jvwong Mar 20, 2024
cc5f6fa
Lint
jvwong Mar 20, 2024
45e3bda
lint
jvwong Mar 20, 2024
c17c0e1
Merge pull request #1246 from PathwayCommons/diff-master
jvwong Mar 20, 2024
ca71b5b
Capture PubMedArticle attribute CommentsCorrectionsList storing relat…
jvwong Apr 18, 2024
71afaf4
Merge pull request #1247 from PathwayCommons/iss1203_paper-relations-…
jvwong Apr 18, 2024
ae66fd7
Map a subset of Crossref relations to the PubMed schema for CommentsC…
jvwong Apr 18, 2024
8aecb5b
More intuitive names for relation type variables.
jvwong Apr 22, 2024
ad740b9
Merge pull request #1248 from PathwayCommons/iss1203_paper-relations-…
jvwong Apr 22, 2024
722e0bc
Min width of related paper to accommodate no abstract.
jvwong Apr 24, 2024
ced69ee
Merge pull request #1250 from PathwayCommons/iss1249_compressed-relPa…
jvwong Apr 24, 2024
e6cff8f
Prettify the relations and present subset in the UI.
jvwong Apr 23, 2024
41547de
Improve the formatting of paper relations.
jvwong Apr 24, 2024
f695b14
Present all relations
jvwong Apr 24, 2024
f297c99
Include fetch response in HTTPStatusError; Log HTTP errors in resourc…
jvwong Apr 25, 2024
f46e478
ArticleIDError logged at info-level.
jvwong Apr 25, 2024
3ca56e9
Revert update changes.
jvwong Apr 25, 2024
ff496b5
Merge pull request #1253 from PathwayCommons/iss1251_more-informative…
jvwong Apr 25, 2024
1aa547c
Merge pull request #1252 from PathwayCommons/iss1203_citation-relation
jvwong Apr 25, 2024
045ff6b
Accordion component; FAQ start
jvwong May 1, 2024
28232f7
Optional title
jvwong May 2, 2024
3adb083
Adding in text from FAQ.
jvwong May 2, 2024
71ee68c
Accommodate small screen sizes
jvwong May 2, 2024
c60b336
Toggle when header is clicked (not entire content)
jvwong May 2, 2024
67869ab
Accommodate large content.
jvwong May 2, 2024
0bcdde5
Merge pull request #1254 from PathwayCommons/iss1216_faq
jvwong May 3, 2024
efa2412
Minor lint warn.
jvwong May 7, 2024
9a48a67
0.27.0
jvwong May 7, 2024
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 package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,5 @@
"engines": {
"node": ">=16.19.0"
},
"version": "0.26.0"
"version": "0.27.0"
}
63 changes: 63 additions & 0 deletions src/client/components/accordion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import h from 'react-hyperscript';
import { Component } from 'react';
import { makeClassList } from '../dom';
import _ from 'lodash';


export const ACCORDION_ITEM_FIELDS = {
TITLE: 'title',
DESCRIPTION: 'description'
};


export class AccordionItem extends Component {
constructor(props){
super(props);

this.state = {
isOpen: false
};
}

toggleItem(){
this.setState({ isOpen: !this.state.isOpen });
}

render(){
const { title, description } = this.props.item;
const { isOpen } = this.state;
const content = _.isString( description ) ? [ h('p', description) ] : description;
return h('div.accordion-item', [
h('div.accordion-item-header', {
className: makeClassList({
'open': isOpen
}),
onClick: () => this.toggleItem()
}, [
h( 'p.accordion-item-header-title', title ),
isOpen ? h('i.material-icons.accordion-item-header-icon', 'expand_less') :
h('i.material-icons.accordion-item-header-icon', 'expand_more')
]),
h('div.accordion-item-content', content )
]);
}
}

export class Accordion extends Component {
constructor(props){
super(props);

this.state = {
};
}

render(){
const { title, items } = this.props;
return h('div.accordion', [
title ? h('h3.accordion-title', title ) : null,
h('div.accordion-items', items.map( (item, key) => h( AccordionItem, { key, item } ) ) )
]);
}
}

export default Accordion;
11 changes: 10 additions & 1 deletion src/client/components/editor/info-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,16 @@ export class InfoPanel extends Component {
const citation = document.citation();
// authorProfiles may not be existing for the older documents
const authorProfiles = document.authorProfiles() || citation.authors.authorList;
const { pmid, title = 'Untitled article', reference, doi, abstract } = citation;
const { pmid, title = 'Untitled article', reference, doi, abstract, relations } = citation;

const retractedPubType = _.find( citation.pubTypes, ['UI', 'D016441'] );
const retractFlag = retractedPubType ? h('span.editor-info-flag.super-salient-button.danger', retractedPubType.value) : null;

const hasArticleId = pmid != null || doi != null;
const hasRelatedPapers = !_.isEmpty( document.relatedPapers() );

const hasRelations = !_.isEmpty( relations );

return h('div.editor-info-panel', [
h('div.editor-info-flags', [ retractFlag ]),

Expand Down Expand Up @@ -103,6 +105,13 @@ export class InfoPanel extends Component {
pmid ? h('a.editor-info-link.plain-link', { target: '_blank', href: `${PUBMED_LINK_BASE_URL}${pmid}` }, 'PubMed') : null,
h('a.editor-info-link.plain-link', { target: '_blank', href: `${GOOGLE_SCHOLAR_BASE_URL}${( "\u0022" + title + "\u0022") }`}, 'Google Scholar')
]),
hasRelations ?
h('div.editor-info-relations', relations.map( ({ type, links }, i) => [
h('div.editor-info-relation', { key: i.toString() }, [
h('span.editor-info-relation-type', `${type} `),
h('span.editor-info-links', links.map( ({ url, reference }, j ) => h('a.editor-info-link.plain-link', { key: j.toString(), target: '_blank', href: url }, reference ) ) )
])
])): null,
h('div.editor-info-main-sections', [
abstract ? h('div.editor-info-abstract-section.editor-info-main-section', [
h('div.editor-info-section-title', abstract ? 'Abstract': 'Summary'),
Expand Down
6 changes: 1 addition & 5 deletions src/client/components/element-info/entity-info.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,11 +365,6 @@ class EntityInfo extends DataComponent {
let doc = p.document;
let children = [];

const citation = doc.citation();
const { pmid } = citation;

const hasPubmedMetadata = pmid != null;

let Loader = ({ loading = true }) => h('div.entity-info-matches-loading' + (loading ? '.entity-info-matches-loading-active' : ''), [
loading ? h('i.icon.icon-spinner') : h('i.material-icons', 'remove')
]);
Expand Down Expand Up @@ -612,6 +607,7 @@ class EntityInfo extends DataComponent {
if( isComplex(s.element.type()) ){
const entityNames = s.element.participants().map(ppt => ppt.name());
children.push( h('div.entity-info-assoc', targetFromAssoc({ type, name, entityNames }, true )) );

if (hasRelatedPapers) {
children.push( h('div.entity-info-reld-papers-title', `Recommended articles`) );

Expand Down
134 changes: 133 additions & 1 deletion src/client/components/home.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Carousel, CAROUSEL_CONTENT } from './carousel';
import { tryPromise } from '../../util';
import { formatDistanceToNow } from 'date-fns';
import DocumentSearch from '../document-search';
import Accordion from './accordion.js';

import { TWITTER_ACCOUNT_NAME, SAMPLE_DOC_ID, EMAIL_ADDRESS_INFO } from '../../config';
import _ from 'lodash';
Expand Down Expand Up @@ -377,7 +378,8 @@ class Home extends Component {
h('a.home-nav-link', [
h(ContactPopover)
]),
h('a.home-nav-link', { href: `https://twitter.com/${TWITTER_ACCOUNT_NAME}`, target: '_blank' }, 'Twitter')
h('a.home-nav-link', { href: `https://twitter.com/${TWITTER_ACCOUNT_NAME}`, target: '_blank' }, 'Twitter'),
h('a.home-nav-link', { href: '#faq' }, 'FAQ')
])
]),
h('div.home-intro', [
Expand Down Expand Up @@ -557,6 +559,136 @@ class Home extends Component {
])
])
]),
h('div.home-section.home-fluid-section.home-fluid-section-no-figure', [
h('div.home-fluid-section-copy', [
h( Accordion, {
title: [ h('span', { id: 'faq' }, 'Frequently Asked Questions')],
items: [
{ title: 'What is Biofactoid?', description: [
h('p', [
'A tool to map ',
h('a.plain-link', { href: 'https://en.wikipedia.org/wiki/Biological_pathway', target: '_blank' }, 'biological pathways'),
' assembled from author-curated results in papers.'
])
]},
{ title: 'What problem does Biofactoid help solve?', description: [
h('p', 'Think about the last time you snapped a photo of your friends or family (or your pet). Your phone automatically identified and focused on all the faces, but, whether you were aware of it or not, it also labelled those faces (and cars, food, cute babies) so that it could organise your album by the places, people, pets and things within the images.'),
h('p', 'Wouldn’t it be great if all of the scientific details in a paper were readily identifiable by computers so that information across the literature could be precisely related and combined?'),
h('p', [
'Despite the fact that scientific papers are distributed digitally, the content itself -- plain text and images -- remains rooted in the print era. Unfortunately, knowledge in the text and figures in papers is extremely challenging for computers to accurately extract and use. We traditionally rely on expert curators at biological resources (e.g., ',
h('a.plain-link', { href: 'https://www.uniprot.org/', target: '_blank' }, 'UniProt'),
') to read papers and enter the information in a format that a computer can work with. However, this is expensive and there are too many papers for expert curators to handle at the same time.'
]),
h('p', 'Biofactoid rethinks the way information in papers is captured by enabling curation by authors of scientific articles, which is accurate, since authors are authoritative experts on their studies, and scales to support comprehensive, up-to-the-minute coverage of the literature.')
]},
{ title: 'What kind of information does Biofactoid contain?', description: 'Functional relationships (e.g., binding, transcription) between molecules and chemicals. For instance, "NAD+ binds to mouse PARP1".'},
{ title: 'Which species does Biofactoid support?', description: [
h('p', [
'Humans and major model organisms including: ',
h('em', 'M. musculus'), ', ',
h('em', 'R. norvegicus'), ', ',
h('em', 'S. cerevisiae'), ', ',
h('em', 'D. melanogaster'), ', ',
h('em', 'E. coli'), ', ',
h('em', 'C. elegans'), ', ',
h('em', 'D. rerio'), ', ',
h('em', 'A. thaliana'), ', as well as ',
h('em', 'SARS-CoV-2.')
])
]},
{ title: 'Can anyone submit an article?', description: [
h('p', [
h('span', 'Any author of a primary research article is welcome to submit content to Biofactoid. Authors access the curation tool via a private web link. Author names and emails are associated with Biofactoid records and matched against corresponding author and '),
h('a.plain-link', { href: 'https://orcid.org/', target: '_blank' }, 'Open Researcher and Contributor ID (ORCID)'),
h('span', ' information (when available) for each article. The Biofactoid website displays the name of the author who created the record, linked to their ORCID.')
])
]},
{ title: 'How long does it take?', description: 'A typical author spends a total of 6 minutes to add information from a paper; this usually involves 3 interactions. More than a quarter of users finish in less than 3 minutes.' },
{ title: 'Do I need to create an account?', description: 'No. All Biofactoid data is freely and openly available for all to use, download and redistribute without restriction. Authors curate their paper by following a private web link. Email addresses remain private and are never shared.' },
{ title: 'How does Biofactoid compare to other pathway databases like Reactome or STRING?', description: [
h('p', 'Biofactoid collects pathway and network data and makes it available as a resource to support many different uses. Biofactoid data can be searched as is, as a knowledge resource. It can also provide input data for pathway and network analyses, such as the following:'),
h('ul', [
h('li', [
'STRING collects data from other sources, such as Biocarta, BioCyc, Gene Ontology, KEGG, and Reactome; ',
h('u', 'Biofactoid is a primary source of curated data')
]),
h('li', 'Reactome curates a defined set of human pathways from select papers, focusing on a consensus (i.e. "textbook") interpretation of biological processes; Biofactoid supports author-curation of all papers with pathway results')
])
]},
{ title: 'How is Biofactoid data is used?', description: [
h('p', 'Biofactoid collects pathway and network data and makes it available as a resource to support many different uses. Biofactoid data can be searched as is, as a knowledge resource. It can also provide input data for pathway and network analyses, such as the following:'),
h('ul', [
h('li', [
h('b', 'Interpreting long lists of genes from large-scale experiments'),
h('ul', [
h('p', 'Comprehensive quantification of DNA, RNA and proteins in biological samples yields long lists of measured entities (e.g. differentially expressed genes) which are difficult to interpret. Pathway enrichment analysis summarises gene lists as a smaller, more easily interpretable list of affected pathways. Pathway data is obtained from manually curated resources.'),
h('li', [
h('a.plain-link', { href: 'https://www.science.org/doi/full/10.1126/scisignal.aan3580', target: '_blank' }, 'Integrated in vivo multiomics analysis identifies p21-activated kinase signaling as a driver of colitis.'),
' Sci. Signal 11 (2018)'
]),
h('li', [
h('a.plain-link', { href: 'https://www.nature.com/articles/nature13108', target: '_blank' }, 'Epigenomic alterations define lethal CIMP-positive ependymomas of infancy.'),
' Nature 506 (2014)'
]),
h('li', [
h('a.plain-link', { href: 'https://www.nature.com/articles/nature13483', target: '_blank' }, 'DNA-damage-induced differentiation of leukaemic cells as an anti-cancer barrier.'),
' Nature 514 (2014)'
])
])
]),
h('li', [
h('b', 'Exploring the mechanistic neighbourhood of a gene or drug'),
h('ul', [
h('p', 'Functional screens (e.g., RNAi) and genetic screens can implicate one or a few genes in a phenotype. However, complex cellular networks of gene products and chemicals underlie most genotype-to-phenotype relationships. An integrated resource of curated biological relationships enables researchers to explore a neighbourhood of direct and indirect mechanistic interactions for a protein (or drug) of interest.'),
h('li', [
'Search engines: ',
h('a.plain-link', { href: 'https://string-db.org/', target: '_blank' }, 'STRING'),
h('span', ', '),
h('a.plain-link', { href: 'https://genemania.org/', target: '_blank' }, 'GeneMANIA'),
h('span', ', '),
h('a.plain-link', { href: 'https://apps.pathwaycommons.org/', target: '_blank' }, 'Pathway Commons Search')
])
]),
]),
h('li', [
h('b', 'Network analysis'),
h('ul', [
h('p', 'The research community has used pathway and interaction data in a wide variety of computational analyses:'),
h('li', [
h('em', 'Constructing quantitative dynamical models from curated pathways'),
h('ul', [
h('li', [
h('a.plain-link', { href: 'https://pubmed.ncbi.nlm.nih.gov/24273241/', target: '_blank' }, 'Pathway Commons at virtual cell: use of pathway data for mathematical.'),
' Bioinformatics 15:30 (2014)'
])
]),
]),
h('li', [
h('em', 'Using curated pathways to assemble a kinase signalling network that explains kinase data'),
h('ul', [
h('li', [
h('a.plain-link', { href: 'https://www.nature.com/articles/nmeth.3773', target: '_blank' }, 'DREAM Challenge: Hill, S. M. et al. Inferring causal molecular networks: empirical assessment through a community-based effort.'),
' Nat. Methods 13 (2016)'
])
]),
]),
h('li', [
h('em', 'Using curated pathways to explain mutually exclusive mutations in cancer'),
h('ul', [
h('li', [
h('a.plain-link', { href: 'https://genomebiology.biomedcentral.com/articles/10.1186/s13059-015-0612-6', target: '_blank' }, 'Systematic identification of cancer driving signaling pathways based on mutual exclusivity of genomic alterations.'),
' Genome Biology 16:45 (2015)'
])
]),
])
])
])
])
]}
]
})
])
]),
h('div.home-section.home-search-results', [
this.state.searchMode ? (
this.state.searching ? (
Expand Down
49 changes: 47 additions & 2 deletions src/server/routes/api/document/crossref/map.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import _ from 'lodash';
import { format } from 'date-fns';
import { createPubmedArticle } from '../../../../../util/pubmed';
import { COMMENTSCORRECTIONS_REFTYPE, createPubmedArticle } from '../../../../../util/pubmed';

/**
* getAbstract
Expand Down Expand Up @@ -169,14 +169,59 @@ const getPublicationTypeList = record => {
return PublicationTypeList;
};

const getCommentsCorrectionsList = record => {
const CommentsCorrectionsList = [];
const CRRELATION_REFTYPE_MAP = new Map([
['is-preprint-of', COMMENTSCORRECTIONS_REFTYPE.UpdateIn],
['has-preprint', COMMENTSCORRECTIONS_REFTYPE.UpdateOf],
['is-comment-on', COMMENTSCORRECTIONS_REFTYPE.CommentOn],
['has-comment', COMMENTSCORRECTIONS_REFTYPE.CommentIn],
['isSupplementedBy', COMMENTSCORRECTIONS_REFTYPE.AssociatedDataset]
]);
const CRRELATION_IDTYPES = new Set([
'doi',
'pmid'
]);
const { relation } = record;
if( relation ){
for (let crRelationType of Object.keys(relation)) {
if( CRRELATION_REFTYPE_MAP.has( crRelationType ) ){
const RefType = CRRELATION_REFTYPE_MAP.get( crRelationType );
const relations = relation[crRelationType];
for (let rel of relations) {
const { id, 'id-type': idType } = rel;
if( CRRELATION_IDTYPES.has( idType ) ){
const CommentsCorrections = {
RefType,
PMID: null,
DOI: null,
RefSource: ''
};
if( idType === 'doi' ){
_.set(CommentsCorrections, 'DOI', id);
_.set(CommentsCorrections, 'RefSource', `doi: ${id}`);
} else if( idType === 'pmid' ){
_.set(CommentsCorrections, 'PMID', id);
_.set(CommentsCorrections, 'RefSource', `pmid: ${id}`);
}
CommentsCorrectionsList.push(CommentsCorrections);
}
}
}
}
}
return CommentsCorrectionsList;
};

const getMedlineCitation = record => {
const { abstract, title, author } = record;
const Abstract = getAbstract( abstract );
const ArticleTitle = _.head ( title );
const AuthorList = asAuthorList( author );
const Journal = getJournal( record );
const PublicationTypeList = getPublicationTypeList( record );
const MedlineCitation = { Article: { Abstract, ArticleTitle, AuthorList, Journal, PublicationTypeList } };
const CommentsCorrectionsList = getCommentsCorrectionsList( record );
const MedlineCitation = { Article: { Abstract, ArticleTitle, AuthorList, Journal, PublicationTypeList }, CommentsCorrectionsList };
return MedlineCitation;
};

Expand Down
Loading