Published
Edited
Feb 4, 2019
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
handleQuery = queryString => {
const doc = nlp(queryString).normalize()
const nouns = doc.nouns().toSingular();
const genes = nouns.match('#Gene');
const tissueOrCellTypes = matchMultiWordNounPhrase('TissueOrCellType')(nouns);
const diseases = matchMultiWordNounPhrase('Disease')(nouns);
const entityGene = matchMultiWordNounPhrase('EntityGene')(nouns);
const entityDisease = matchMultiWordNounPhrase('EntityDisease')(nouns);
const entityTissueOrCellType = matchMultiWordNounPhrase('EntityTissueOrCellType')(nouns);

return {
// entities: [...entityGene, ...entityDisease, ...entityTissueOrCellType],
entityGene,
entityDisease,
entityTissueOrCellType,
genes: genes.out('array'),
diseases,
tissueOrCellTypes,
};
}
Insert cell
handleTaggedEntities = taggedEntities => {
// suggest urls based on tag combinations
// TODO: lookup step (mapping eg. gene symbol to ensembl id)
const suggestions = [];

// single gene page
taggedEntities.genes.forEach(gene => {
suggestions.push({
question: `Tell me about ${gene.toUpperCase()}`,
url: `/search/gene/${gene}`,
});
});
// single disease page
taggedEntities.diseases.forEach(disease => {
suggestions.push({
question: `Tell me about ${disease}`,
url: `/search/disease/${disease}`,
});
});
// single tissue/celltype page
taggedEntities.tissueOrCellTypes.forEach(tissueOrCellType => {
suggestions.push({
question: `Tell me about ${tissueOrCellType}`,
url: `/search/tissueOrCellType/${tissueOrCellType}`,
});
});
// gene+disease page
taggedEntities.genes.forEach(gene => {
taggedEntities.diseases.forEach(disease => {
suggestions.push({
question: `Show me the evidence associating ${gene.toUpperCase()} and ${disease}`,
url: `/search/evidence/${gene}/${disease}`,
});
});
});
// gene+entityDisease page
taggedEntities.genes.forEach(gene => {
if (taggedEntities.entityDisease.length > 0) {
suggestions.push({
question: `Show me diseases associated with ${gene.toUpperCase()}`,
url: `/search/association/gene/${gene}`,
});
}
});
// disease+entityGene page
taggedEntities.diseases.forEach(disease => {
if (taggedEntities.entityGene.length > 0) {
suggestions.push({
question: `Show me genes associated with ${disease}`,
url: `/search/association/disease/${disease}`,
});
}
});
// gene+entityTissueOrCellType page
taggedEntities.genes.forEach(gene => {
if (taggedEntities.entityTissueOrCellType.length > 0) {
suggestions.push({
question: `Show me where ${gene.toUpperCase()} is expressed in the body`,
url: `/search/expression/${gene}`,
});
}
});
return suggestions;
}
Insert cell
Insert cell
setupPlugin = {
const plugin = {
name:'compromise-opentargets',
words: {
// diseases
melanoma: 'Disease',
'breast carcinoma': 'Disease',
carcinoma: 'Disease',
'acute leukemia': 'Disease',
'psoriasis vulgaris': 'Disease',
'acute lymphoblastic leukemia': 'Disease',
// genes
braf: 'Gene',
'brafp': 'Gene',
brap: 'Gene',
pten: 'Gene',

// body parts
blood: 'TissueOrCellType',
brain: 'TissueOrCellType',
'left ventricle': 'TissueOrCellType',
// entities
gene: 'EntityGene',
protein: 'EntityGene',
target: 'EntityGene',
disease: 'EntityDisease',
phenotype: 'EntityDisease',
trait: 'EntityDisease',
organ: 'EntityTissueOrCellType',
tissue: 'EntityTissueOrCellType',
'cell type': 'EntityTissueOrCellType',
},
regex: {
'^ENSG\\d+$': 'Gene',
'^(P|Q)\\d+$': 'Gene',
'^EFO_\\d+$': 'Disease',
'^Orphanet_\\d+$': 'Disease',
},
tags: {
Entity: {
isA: 'Noun'
},
SpecificEntity: {
isA: 'Entity'
},
EntityGene: {
isA: 'Entity'
},
EntityDisease: {
isA: 'Entity'
},
EntityTissueOrCellType: {
isA: 'Entity'
},
Disease: {
isA: 'SpecificEntity'
},
Gene: {
isA: 'SpecificEntity'
},
TissueOrCellType: {
isA: 'SpecificEntity'
},
},
};
const packedPlugin = nlpPlugin.pack(plugin);
nlp.plugin(packedPlugin);
// nlp.verbose('tagger'); // outputs lots of detail to the console
return plugin;
}
Insert cell
Insert cell
matchMultiWordNounPhrase = tag => nouns => {
const tagRuns = nouns.match(`#${tag}+`)
const words = nouns.world().words;
const multiWordNouns = [];
tagRuns.forEach(tagRun => {
const tags = tagRun.match(`#${tag}`);
const tagsArray = tags.out('array');
let i, j;
for (i = 0; i < tagsArray.length; i++) {
for (j = i + 1; j < tagsArray.length + 1; j++) {
const tagSubrun = tagsArray.slice(i, j);
const tagSubrunWord = tagSubrun.join(' ');
if (words[tagSubrunWord] === tag) {
multiWordNouns.push(tagSubrunWord);
}
}
}
});
return multiWordNouns;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more