Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Enable searching genes by Ensembl ID #376

Merged
merged 4 commits into from
Dec 6, 2024
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
Binary file modified examples/vanilla/img/gene_leads_ideogram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 37 additions & 24 deletions src/js/kit/related-genes.js
Original file line number Diff line number Diff line change
Expand Up @@ -473,36 +473,48 @@ function fetchGenesFromCache(names, type, ideo) {
const locusMap = isSymbol ? cache.lociByName : cache.lociById;
const nameMap = isSymbol ? cache.idsByName : cache.namesById;

const ensemblGeneIdRegex = /ENS[A-Z]{0,3}G\d{11}/;

const hits = names.map(name => {

const nameLc = name.toLowerCase();
let isSynonym = false;
let synonym = null;

if (
!locusMap[name] &&
!cache.nameCaseMap[nameLc] &&
!getGeneBySynonym(name, ideo)
) {
if (isSymbol) {
throwGeneNotFound(name, ideo);
} else {
return;
}
if (ensemblGeneIdRegex.test(name)) {
// Omit version if given Ensembl gene ID + version, e.g.
// ENSG00000010404.11 -> ENSG00000010404
name = name.split('.')[0];
}
const isIdentifier = name in cache.namesById;
if (isIdentifier && isSymbol) {
name = cache.namesById[name];
} else {
const nameLc = name.toLowerCase();

let isSynonym = false;
let synonym = null;
if (
!locusMap[name] &&
!cache.nameCaseMap[nameLc] &&
!getGeneBySynonym(name, ideo)
) {
if (isSymbol) {
throwGeneNotFound(name, ideo);
} else {
return;
}
}

// Canonicalize name if it is mistaken in upstream data source.
// This can sometimes happen in WikiPathways, e.g. when searching
// interactions for rat Pten, it includes a result for "PIK3CA".
// In that case, this would correct PIK3CA to be Pik3ca.
if (isSymbol && !locusMap[name]) {
if (cache.nameCaseMap[nameLc]) {
name = cache.nameCaseMap[nameLc];
} else {
synonym = name;
name = getGeneBySynonym(synonym, ideo);
isSynonym = true;
// Canonicalize name if it is mistaken in upstream data source.
// This can sometimes happen in WikiPathways, e.g. when searching
// interactions for rat Pten, it includes a result for "PIK3CA".
// In that case, this would correct PIK3CA to be Pik3ca.
if (isSymbol && !locusMap[name]) {
if (cache.nameCaseMap[nameLc]) {
name = cache.nameCaseMap[nameLc];
} else {
synonym = name;
name = getGeneBySynonym(synonym, ideo);
isSynonym = true;
}
}
}

Expand All @@ -522,6 +534,7 @@ function fetchGenesFromCache(names, type, ideo) {
ensemblgene: ensemblId
},
isSynonym,
isIdentifier,
synonym
};

Expand Down
21 changes: 9 additions & 12 deletions test/online/related-genes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,20 +269,16 @@ describe('Ideogram related genes kit', function() {
const ideogram = Ideogram.initRelatedGenes(config);
});

it('handles gene with no interacting genes and no paralogs', done => {
it('handles search by Ensembl ID', done => {

async function callback() {
const ideo = this;

await ideogram.plotRelatedGenes('BRCA1');
// Ensembl ID for gene "LPL"
await ideo.plotRelatedGenes('ENSG00000175445');

const related = ideo.getRelatedGenesByType();

const numParalogs = related.paralogous.length;
const numInteractingGenes = related.interacting.length;

assert.equal(numInteractingGenes, 0);
assert.equal(numParalogs, 0);
const chr10ParalogNeighborhoods = ideo.annotsOther['9'].annots;
assert.equal(chr10ParalogNeighborhoods.length, 1);

done();
}
Expand All @@ -292,7 +288,7 @@ describe('Ideogram related genes kit', function() {
}

var config = {
organism: 'Macaca mulatta', // Also tests standard, non-slugged name
organism: 'Homo sapiens', // Also tests standard, non-slugged name
onLoad: callback,
dataDir: '/dist/data/bands/native/',
cacheDir: '/dist/data/cache/',
Expand All @@ -303,6 +299,7 @@ describe('Ideogram related genes kit', function() {
});

it('handles gene with no interacting genes and no paralogs', done => {

async function callback() {
const ideo = this;

Expand All @@ -324,16 +321,16 @@ describe('Ideogram related genes kit', function() {
}

var config = {
organism: 'Macaca mulatta',
organism: 'Macaca mulatta', // Also tests standard, non-slugged name
onLoad: callback,
dataDir: '/dist/data/bands/native/',
cacheDir: '/dist/data/cache/',
onClickAnnot
};

const ideogram = Ideogram.initRelatedGenes(config);
});


it('handles gene that is unknown', done => {

async function callback() {
Expand Down