Skip to content

Commit

Permalink
Merge pull request #138 from molgenis/feat/fasta
Browse files Browse the repository at this point in the history
genome browser: use embedded reference sequence data
  • Loading branch information
marikaris authored Apr 22, 2021
2 parents 3d0552d + 5d3f8ee commit 7004b97
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 111 deletions.
18 changes: 9 additions & 9 deletions package-lock.json

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

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@molgenis/vip-report-template",
"version": "2.0.0",
"version": "2.1.0",
"description": "Report Template for Variant Call Format (VCF) Report Generator",
"scripts": {
"serve": "vue-cli-service serve",
Expand All @@ -10,7 +10,7 @@
"i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'"
},
"dependencies": {
"@molgenis/vip-report-api": "^2.0.0",
"@molgenis/vip-report-api": "^2.1.0",
"bootstrap-vue": "^2.21.2",
"core-js": "^3.9.1",
"file-saver": "^2.0.5",
Expand Down
88 changes: 59 additions & 29 deletions src/components/GenomeBrowser.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,80 @@
import Vue from 'vue';
import igv from 'igv';
import { mapActions, mapGetters, mapState } from 'vuex';
import { GenomeBrowserDb } from '@/types/GenomeBrowserDb';
import { Vcf } from '@molgenis/vip-report-api';
export default Vue.extend({
computed: {
...mapGetters(['genomeBrowserDb']),
...mapState(['selectedRecord'])
},
mounted() {
if (this.genomeBrowserDb !== GenomeBrowserDb.hg19 && this.genomeBrowserDb !== GenomeBrowserDb.hg38) {
return;
}
const options = {
genome: this.genomeBrowserDb
};
// store browser in prototype instead of data to prevent very slow report
igv.createBrowser(this.$refs.igv, options).then((browser: never) => {
Vue.prototype.$browser = browser;
this.loadVariantTrack();
});
},
methods: {
...mapActions(['getVcfGz']),
async loadVariantTrack() {
const data = await this.getVcfGz();
Vue.prototype.$browser.loadTrack({
...mapActions(['getFastaGz', 'getVcfGz']),
hasGenomeBrowser() {
return Vue.prototype.$browser !== undefined;
},
async createGenomeBrowser(config: unknown) {
Vue.prototype.$browser = await igv.createBrowser(this.$refs.igv, config);
},
async updateGenomeBrowser(record: Vcf.Record | null) {
const config = record !== null ? await this.createBrowserConfig(record) : null;
if (config === null) {
if (this.hasGenomeBrowser()) {
await this.deleteGenomeBrowser();
}
} else {
if (this.hasGenomeBrowser()) {
Vue.prototype.$browser.loadSessionObject(config);
} else {
await this.createGenomeBrowser(config);
}
}
},
async deleteGenomeBrowser() {
igv.removeBrowser(Vue.prototype.$browser);
Vue.prototype.$browser = undefined;
},
async createBrowserConfig(record: Vcf.Record): Promise<unknown | null> {
const data = await Promise.all([this.getFastaGz({ contig: record.c, pos: record.p }), this.getVcfGz()]);
const fastaGz = data[0];
const vcfGz = data[1];
if (fastaGz === null) {
return null;
}
let tracks = [];
tracks.push({
type: 'variant',
format: 'vcf',
name: 'Variants',
url: 'data:application/gzip;base64,' + data.toString('base64')
url: 'data:application/gzip;base64,' + vcfGz.toString('base64')
});
},
selectRecord(record?: Vcf.Record) {
const locus = record ? `chr${record.c}:${record.p}` : 'all';
Vue.prototype.$browser.search(locus);
return {
reference: {
id: this.genomeBrowserDb !== null ? this.genomeBrowserDb : 'reference_unknown',
name: this.genomeBrowserDb !== null ? this.genomeBrowserDb : 'Reference',
fastaURL: 'data:application/gzip;base64,' + fastaGz.toString('base64'),
tracks: tracks
},
locus: record.c + ':' + record.p,
showChromosomeWidget: false,
loadDefaultGenomes: false,
nucleotideColors: {
A: 'rgb(144, 238, 144)',
C: 'rgb(176, 196, 222)',
T: 'rgb(238, 162, 173)',
G: 'rgb(255, 236, 139)',
N: 'rgb(80,80,80)'
}
// bug in igv?
// showCenterGuide: true
};
}
},
watch: {
selectedRecord(newRecord?: Vcf.Record) {
if (Vue.prototype.$browser !== undefined) {
this.selectRecord(newRecord);
}
selectedRecord(newRecord: Vcf.Record | null) {
this.updateGenomeBrowser(newRecord);
}
}
});
Expand Down
58 changes: 57 additions & 1 deletion src/mocks/apiDataMock.ts

Large diffs are not rendered by default.

13 changes: 11 additions & 2 deletions src/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ declare global {
}

const inputData = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test' ? apiData : window.api;
let api = new ApiClient(inputData);
let api: ApiClient = new ApiClient(inputData);

export type Locus = {
contig: string;
pos: number;
};

export default {
async loadMetadata({ commit }: ActionContext<State, State>): Promise<void> {
Expand Down Expand Up @@ -96,8 +101,12 @@ export default {
setFilterRecordsByDepth({ commit }: ActionContext<State, State>, value: boolean): void {
commit('setFilterRecordsByDepth', value);
},
async getVcfGz(): Promise<Buffer> {
getVcfGz(): Promise<Buffer> {
return api.getVcfGz();
},
// eslint-disable-next-line @typescript-eslint/no-unused-vars
getFastaGz({ commit }: ActionContext<State, State>, locus: Locus): Promise<Buffer | null> {
return api.getFastaGz(locus.contig, locus.pos);
}
};

Expand Down
67 changes: 0 additions & 67 deletions tests/unit/components/GenomeBrowser.spec.ts

This file was deleted.

10 changes: 9 additions & 1 deletion tests/unit/store/actions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,15 @@ test('set filter records by read depth', async (done) => {
done();
});

test('set filter records by read depth', async (done) => {
test('get vcf gz', async (done) => {
expect(await actions.getVcfGz()).not.toBe(null);
done();
});

test('get fasta gz', async (done) => {
const commit = jest.fn() as Commit;
expect(await actions.getFastaGz({ commit } as ActionContext<State, State>, { contig: '1', pos: 17350500 })).not.toBe(
null
);
done();
});

0 comments on commit 7004b97

Please sign in to comment.