Thomas 3 年 前
コミット
f0b04afbeb
9 ファイル変更352 行追加77 行削除
  1. 2 0
      .gitignore
  2. 64 19
      cli.js
  3. 67 28
      cli.ts
  4. 74 16
      index.js
  5. 88 14
      index.ts
  6. 2 0
      package.json
  7. 25 0
      test.js
  8. 20 0
      test.ts
  9. 10 0
      yarn.lock

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+node_modules
+test

+ 64 - 19
cli.js

@@ -15,6 +15,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
 const chalk_1 = __importDefault(require("chalk"));
 const _1 = require(".");
 const blessed_1 = __importDefault(require("blessed"));
+const figlet_1 = __importDefault(require("figlet"));
+const fs_1 = __importDefault(require("fs"));
 const formatSeq = (seq) => {
     return seq.split('').map(c => {
         let r;
@@ -57,23 +59,25 @@ const combineSTr = (strings, lineN) => {
     return firstLines.map((e, i) => formatSeq(e.toUpperCase()) + formatSeq(splittedSts.map(ee => ee[i]).join(''))).join('');
 };
 (() => __awaiter(void 0, void 0, void 0, function* () {
+    var _a;
     const arg = process.argv.slice(2);
     console.log(chalk_1.default.blue('Welcome to gbffParser!'));
     if (arg.length === 0 || arg.length > 1) {
         console.log(chalk_1.default.red('Usage : cli.js <Accession>'));
     }
     else {
-        var screen = blessed_1.default.screen({
-            smartCSR: true
+        const screen = blessed_1.default.screen({
+            smartCSR: true,
+            dockBorders: true,
+            autoPadding: true
         });
         screen.title = 'gbffParser';
-        //blessed.text({})
-        var box = blessed_1.default.box({
-            top: 'center',
-            left: 'center',
-            width: '95%',
-            height: '95%',
-            content: 'Hello {bold}world{/bold}!',
+        const mainBox = blessed_1.default.box({
+            top: '15%',
+            left: '10%',
+            width: '90%',
+            height: '85%',
+            content: '',
             tags: true,
             border: {
                 type: 'line'
@@ -86,24 +90,65 @@ const combineSTr = (strings, lineN) => {
             mouse: false,
             style: {
                 fg: 'white',
-                bg: 'black',
                 border: {
                     fg: '#f0f0f0'
                 }
             }
         });
-        screen.append(box);
-        screen.key(['escape', 'q', 'C-c'], (ch, key) => {
-            return process.exit(0);
+        const topBox = blessed_1.default.box({
+            top: 0,
+            left: 0,
+            width: '100%',
+            height: '15%',
+            content: 'top',
+            tags: true,
+            border: {
+                type: 'line'
+            },
+            scrollable: false,
+            keys: true,
+            mouse: false,
+            style: {
+                fg: 'white',
+                border: {
+                    fg: '#f0f0f0'
+                }
+            }
+        });
+        const leftBox = blessed_1.default.box({
+            top: '15%',
+            left: 0,
+            width: '10%',
+            height: '85%',
+            content: 'left',
+            tags: true,
+            border: {
+                type: 'line'
+            },
+            scrollable: false,
+            keys: true,
+            mouse: false,
+            style: {
+                fg: 'white',
+                border: {
+                    fg: '#f0f0f0'
+                }
+            }
         });
-        const dbPath = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => '/home/thomas/NGS/ref/RNA/human.' + n + '.rna.gbff');
+        screen.append(topBox);
+        screen.append(leftBox);
+        screen.append(mainBox);
+        screen.key(['escape', 'q', 'C-c'], (ch, key) => process.exit(0));
+        const dbPath = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => '/home/thomas/NGS/ref/ncbi/RNA/human.' + n + '.rna.gbff');
         const result = yield (0, _1.getFromAcc)(arg[0], dbPath);
-        // console.log(result)
         if (result) {
-            box.setContent(result.sequence);
-            box.focus();
-            const lineN = box.getScreenLines()[0].length;
-            box.setContent(combineSTr([result.sequence, result.sequence.split('').map(e => '.').join('')], lineN));
+            yield fs_1.default.promises.writeFile('tmp.json', JSON.stringify(result));
+            const title = ((_a = result.features.filter(feature => feature.type === 'gene')[0]) === null || _a === void 0 ? void 0 : _a.name) || arg[0];
+            topBox.setContent(figlet_1.default.textSync(title));
+            mainBox.setContent(result.sequence);
+            mainBox.focus();
+            const lineN = mainBox.getScreenLines()[0].length;
+            mainBox.setContent(combineSTr([result.sequence, result.sequence.split('').map(e => '.').join('')], lineN));
             screen.render();
         }
     }

+ 67 - 28
cli.ts

@@ -1,7 +1,8 @@
 import chalk from 'chalk';
 import { getFromAcc } from '.'
 import blessed from 'blessed'
-
+import figlet from 'figlet'
+import fs from 'fs'
 const formatSeq = (seq:string) => {
     return seq.split('').map(c => {
         let r
@@ -50,18 +51,19 @@ const combineSTr = (strings: string[], lineN:number) => {
     if (arg.length === 0 || arg.length > 1) {
         console.log(chalk.red('Usage : cli.js <Accession>'))
     } else {
-        var screen = blessed.screen({
-            smartCSR: true
+        const screen = blessed.screen({
+            smartCSR: true,
+            dockBorders: true,
+            autoPadding: true
         })
         screen.title = 'gbffParser'
-        //blessed.text({})
      
-        var box = blessed.box({
-            top: 'center',
-            left: 'center',
-            width: '95%',
-            height: '95%',
-            content: 'Hello {bold}world{/bold}!',
+        const mainBox = blessed.box({
+            top: '15%',
+            left: '10%',
+            width: '90%',
+            height: '85%',
+            content: '',
             tags: true,
             border: {
               type: 'line'
@@ -74,35 +76,72 @@ const combineSTr = (strings: string[], lineN:number) => {
             mouse: false,
             style: {
               fg: 'white',
-              bg: 'black',
               border: {
                 fg: '#f0f0f0'
               }
             }
         })
-        
-        
-        screen.append(box)
-        screen.key(['escape', 'q', 'C-c'], (ch, key) => {
-            return process.exit(0);
+        const topBox = blessed.box({
+            top: 0,
+            left: 0,
+            width: '100%',
+            height: '15%',
+            content: 'top',
+            tags: true,
+            border: {
+              type: 'line'
+            },
+            scrollable: false,      
+            keys: true,
+            mouse: false,
+            style: {
+              fg: 'white',
+              border: {
+                fg: '#f0f0f0'
+              }
+            }
+        })
+        const leftBox = blessed.box({
+            top: '15%',
+            left: 0,
+            width: '10%',
+            height: '85%',
+            content: 'left',
+            tags: true,
+            border: {
+              type: 'line'
+            },
+            scrollable: false,      
+            keys: true,
+            mouse: false,
+            style: {
+              fg: 'white',
+              border: {
+                fg: '#f0f0f0'
+              }
+            }
         })
+        
+        screen.append(topBox)
+        screen.append(leftBox)
+        screen.append(mainBox)
+
+        screen.key(['escape', 'q', 'C-c'], (ch, key) => process.exit(0))
           
-        const dbPath = [1,2,3,4,5,6,7,8,9,10].map(n => '/home/thomas/NGS/ref/RNA/human.' + n + '.rna.gbff')
+        const dbPath = [1,2,3,4,5,6,7,8,9,10].map(n => '/home/thomas/NGS/ref/ncbi/RNA/human.' + n + '.rna.gbff')
         const result = await getFromAcc(arg[0], dbPath)
-        // console.log(result)
+        
         if (result) {
-            
-            box.setContent(result.sequence)
-            box.focus();
-            
-            const lineN = box.getScreenLines()[0].length
-            box.setContent(combineSTr([result.sequence, result.sequence.split('').map(e => '.').join('')], lineN))
-            
+            await fs.promises.writeFile('tmp.json', JSON.stringify(result))
+            const title = result.features.filter(feature => feature.type === 'gene')[0]?.name || arg[0]
+            topBox.setContent(figlet.textSync(title))
 
-            screen.render();
-            
-            
+            mainBox.setContent(result.sequence)
+            mainBox.focus();
             
+            const lineN = mainBox.getScreenLines()[0].length
+            mainBox.setContent(combineSTr([result.sequence, result.sequence.split('').map(e => '.').join('')], lineN))
+            screen.render();
         }
         
 

+ 74 - 16
index.js

@@ -1,5 +1,11 @@
 "use strict";
-// wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/mRNA_Prot/human.6.rna.gbff.gz
+// wget https://ftp.ncbi.nlm.nih.gov/genomes/all/annotation_releases/9606/109.20211119/GCF_000001405.39_GRCh38.p13/GCF_000001405.39_GRCh38.p13_feature_table.txt.gz
+// wget https://ftp.ncbi.nlm.nih.gov/genomes/all/annotation_releases/9606/109.20211119/GCF_000001405.39_GRCh38.p13/GCF_000001405.39_GRCh38.p13_assembly_structure/Primary_Assembly/assembled_chromosomes/chr2acc
+// wget https://ftp.ncbi.nlm.nih.gov/genomes/all/annotation_releases/9606/109.20211119/GCF_000001405.39_GRCh38.p13/GCF_000001405.39_GRCh38.p13_genomic.gbff.gz
+// wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/RefSeqGene/LRG_RefSeqGene
+// wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/RefSeqGene/refseqgene.1.genomic.gbff.gz
+// wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/biological_region/human.biological_region.gbff.gz
+// wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/mRNA_Prot/human.[1-10].rna.gbff.gz
 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
     return new (P || (P = Promise))(function (resolve, reject) {
@@ -20,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
     return (mod && mod.__esModule) ? mod : { "default": mod };
 };
 Object.defineProperty(exports, "__esModule", { value: true });
-exports.getFromAcc = void 0;
+exports.getSymbol = exports.getFromAcc = void 0;
 const fs_1 = __importDefault(require("fs"));
 const readline_1 = __importDefault(require("readline"));
 const buffer_1 = require("buffer");
@@ -50,7 +56,7 @@ const readOffset = (path, from, to) => {
  * strings -a -t d human.1.rna.gbff | grep LOCUS | awk '{print $1"\t"$3}' > human.1.rna.gbff.index
  *
  */
-const makeGbffIndex = (filePath, lineSize = 80, indexPath) => __awaiter(void 0, void 0, void 0, function* () {
+const makeGbffIndex = (filePath, indexPath) => __awaiter(void 0, void 0, void 0, function* () {
     var e_1, _a;
     indexPath = indexPath || filePath + '.jsi';
     let entries = [];
@@ -116,7 +122,7 @@ const getOffset = (indexPath, acc) => __awaiter(void 0, void 0, void 0, function
     }
     return res;
 });
-const getFromAcc = (acc, dbPath, indexPath) => __awaiter(void 0, void 0, void 0, function* () {
+const getFromAcc = (accession, dbPath, indexPath) => __awaiter(void 0, void 0, void 0, function* () {
     dbPath = Array.isArray(dbPath) ? dbPath : [dbPath];
     if (!indexPath) {
         indexPath = [];
@@ -134,18 +140,70 @@ const getFromAcc = (acc, dbPath, indexPath) => __awaiter(void 0, void 0, void 0,
         if (indexPath.length !== dbPath.length)
             throw 'Error';
     }
-    let i = 0;
-    let res;
-    for (const p of dbPath) {
-        res = yield getOffset(indexPath[i], acc);
-        if (res)
-            break;
-        i++;
-    }
-    if (res) {
-        const rr = yield readOffset(res[0], Number(res[1]), Number(res[2]));
-        res = (0, genbank_parser_1.default)(rr)[0];
+    for (const iP of indexPath) {
+        const [filePath, from, to] = (yield getOffset(iP, accession)) || [undefined, undefined, undefined];
+        if (filePath) {
+            const txt = yield readOffset(filePath, Number(from), Number(to));
+            return (0, genbank_parser_1.default)(txt)[0];
+        }
     }
-    return res;
+    return undefined;
 });
 exports.getFromAcc = getFromAcc;
+const getPos = (selector, tablePath, headerTablePath) => __awaiter(void 0, void 0, void 0, function* () {
+    const results = [];
+    (yield fs_1.default.promises.readFile(tablePath)).toString().split('\n')
+        .map((line) => {
+        const lineObj = line.split('\t').reduce((p, c, i) => (Object.assign(Object.assign({}, p), { [headerTablePath[i]]: isFinite(Number(c)) ? Number(c) : c })), {});
+        if (lineObj[Object.keys(selector)[0]] === selector[Object.keys(selector)[0]])
+            results.push(lineObj);
+    });
+    return results;
+});
+const getIndex = (symbol, LRGPath) => __awaiter(void 0, void 0, void 0, function* () {
+    return (yield fs_1.default.promises.readFile(LRGPath)).toString()
+        .split('\n')
+        .filter((line) => line.match(new RegExp(symbol, 'g')))
+        .reduce((p, c) => {
+        const [TaxID, GeneID, GeneName, GeneAcc, TranscriptsAcc, ProteinAcc, _] = c.split('\t').filter((e) => e !== '');
+        return { GeneID, GeneAcc, TranscriptsAcc: [...(new Set([...p.TranscriptsAcc, TranscriptsAcc]))], ProteinAcc: [...(new Set([...p.ProteinAcc, ProteinAcc]))] };
+    }, { GeneID: '', GeneAcc: '', TranscriptsAcc: [], ProteinAcc: [] });
+});
+const getSymbol = (symbol, LRGPath, // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/RefSeqGene/LRG_RefSeqGene
+tablePath, // wget https://ftp.ncbi.nlm.nih.gov/genomes/all/annotation_releases/9606/109.20211119/GCF_000001405.39_GRCh38.p13/GCF_000001405.39_GRCh38.p13_feature_table.txt.gz
+// regionDBPath: string | string[], // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/biological_region/human.biological_region.gbff.gz
+geneDBPath, // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/RefSeqGene/refseqgene.[1-7].genomic.gbff.gz
+rnaDBPath // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/mRNA_Prot/human.[1-10].rna.gbff.gz
+) => __awaiter(void 0, void 0, void 0, function* () {
+    const geneIndex = yield getIndex(symbol, LRGPath);
+    // const regionData = await getFromAcc(geneIndex.GeneAcc.split('.')[0], regionDBPath)
+    // if (regionData) await fs.promises.writeFile('test-region.json', JSON.stringify(regionData, null, 4))
+    const headerTablePath = [
+        'feature', 'class', 'assembly', 'assembly_unit', 'seq_type', 'chromosome',
+        'genomic_accession', 'start', 'end', 'strand', 'product_accession', 'non_redundant_refseq',
+        'related_accession', 'name', 'symbol', 'GeneID', 'locus_tag', 'feature_interval_length',
+        'product_length', 'attributes'
+    ];
+    const allFeatures = yield getPos({ symbol }, tablePath, headerTablePath);
+    for (let index = 0; index < allFeatures.length; index++) {
+        const { feature, product_accession } = allFeatures[index];
+        let tmp;
+        switch (feature) {
+            case 'gene':
+                allFeatures[index].product_accession = geneIndex.GeneAcc;
+                tmp = yield getFromAcc(geneIndex.GeneAcc.split('.')[0], geneDBPath);
+                yield fs_1.default.promises.writeFile('test/test-gene.json', JSON.stringify(tmp, null, 4));
+                allFeatures[index].data = tmp;
+                break;
+            case 'mRNA':
+                tmp = yield getFromAcc(product_accession.split('.')[0], rnaDBPath);
+                yield fs_1.default.promises.writeFile('test/test-rna-' + index + '.json', JSON.stringify(tmp, null, 4));
+                allFeatures[index].data = tmp;
+                break;
+            default:
+                break;
+        }
+    }
+    return allFeatures;
+});
+exports.getSymbol = getSymbol;

+ 88 - 14
index.ts

@@ -1,4 +1,10 @@
-// wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/mRNA_Prot/human.6.rna.gbff.gz
+// wget https://ftp.ncbi.nlm.nih.gov/genomes/all/annotation_releases/9606/109.20211119/GCF_000001405.39_GRCh38.p13/GCF_000001405.39_GRCh38.p13_feature_table.txt.gz
+// wget https://ftp.ncbi.nlm.nih.gov/genomes/all/annotation_releases/9606/109.20211119/GCF_000001405.39_GRCh38.p13/GCF_000001405.39_GRCh38.p13_assembly_structure/Primary_Assembly/assembled_chromosomes/chr2acc
+// wget https://ftp.ncbi.nlm.nih.gov/genomes/all/annotation_releases/9606/109.20211119/GCF_000001405.39_GRCh38.p13/GCF_000001405.39_GRCh38.p13_genomic.gbff.gz
+// wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/RefSeqGene/LRG_RefSeqGene
+// wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/RefSeqGene/refseqgene.1.genomic.gbff.gz
+// wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/biological_region/human.biological_region.gbff.gz
+// wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/mRNA_Prot/human.[1-10].rna.gbff.gz
 
 import fs from 'fs'
 import readline from 'readline'
@@ -31,7 +37,7 @@ const readOffset = (path: string, from:number, to:number) => {
  * strings -a -t d human.1.rna.gbff | grep LOCUS | awk '{print $1"\t"$3}' > human.1.rna.gbff.index
  * 
  */
-const makeGbffIndex = async (filePath: string, lineSize = 80, indexPath?: string) => {
+const makeGbffIndex = async (filePath: string, indexPath?: string) => {
     interface entry {
         filePath: string;
         value   : string;
@@ -82,7 +88,7 @@ const getOffset = async (indexPath: string, acc: string) => {
     return res
 }
 
-const getFromAcc = async (acc: string, dbPath: string | string[], indexPath?: string | string[]) => {
+const getFromAcc = async (accession: string, dbPath: string | string[], indexPath?: string | string[]) => {
     dbPath = Array.isArray(dbPath) ? dbPath : [dbPath]
     if (!indexPath) {
         indexPath = []
@@ -98,18 +104,86 @@ const getFromAcc = async (acc: string, dbPath: string | string[], indexPath?: st
         indexPath = Array.isArray(indexPath) ? indexPath : [indexPath]
         if (indexPath.length !== dbPath.length) throw 'Error'
     }
-    let i = 0
-    let res
-    for (const p of dbPath) {
-        res = await getOffset(indexPath[i], acc)
-        if (res) break
-        i++
+
+    for (const iP of indexPath) {
+        const [filePath, from, to] = await getOffset(iP, accession) || [undefined,undefined,undefined]
+        if (filePath) {
+            const txt = await readOffset(filePath, Number(from), Number(to))
+            return genbankParser(txt)[0]
+        }
+    }
+    return undefined
+}
+
+interface selector {[key: string]: string}
+const getPos = async (selector: selector, tablePath: string, headerTablePath:string[]) => {
+    const results:any = [];
+    (await fs.promises.readFile(tablePath)).toString().split('\n')
+    .map((line:string) => {
+        const lineObj = line.split('\t').reduce((p,c,i) => ({...p, [headerTablePath[i]]: isFinite(Number(c)) ? Number(c) : c}), {} as any)
+        if(lineObj[Object.keys(selector)[0]] === selector[Object.keys(selector)[0]]) results.push(lineObj)
+    })
+    return results
+}
+
+const getIndex = async (symbol:string, LRGPath:string) => {
+    interface geneIndex  {
+        GeneID        : string;
+        GeneAcc       : string;
+        TranscriptsAcc: string[];
+        ProteinAcc    : string[]
     }
-    if (res) {
-        const rr = await readOffset(res[0], Number(res[1]), Number(res[2]))
-        res = genbankParser(rr)[0]
+    return (await fs.promises.readFile(LRGPath)).toString()
+    .split('\n')
+    .filter((line:string) => line.match(new RegExp(symbol, 'g')))
+    .reduce((p:any,c:any) => {
+        const [TaxID, GeneID, GeneName, GeneAcc, TranscriptsAcc, ProteinAcc, _] = c.split('\t').filter((e:any)=>e!=='')
+        return {GeneID, GeneAcc, TranscriptsAcc: [...(new Set([...p.TranscriptsAcc, TranscriptsAcc]))], ProteinAcc: [...(new Set([...p.ProteinAcc, ProteinAcc]))]}
+    }, {GeneID: '', GeneAcc: '', TranscriptsAcc: [], ProteinAcc: []} as geneIndex)
+}
+
+const getSymbol = async (
+    symbol:string,
+    LRGPath:string, // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/RefSeqGene/LRG_RefSeqGene
+    tablePath:string, // wget https://ftp.ncbi.nlm.nih.gov/genomes/all/annotation_releases/9606/109.20211119/GCF_000001405.39_GRCh38.p13/GCF_000001405.39_GRCh38.p13_feature_table.txt.gz
+    // regionDBPath: string | string[], // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/biological_region/human.biological_region.gbff.gz
+    geneDBPath: string | string[], // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/RefSeqGene/refseqgene.[1-7].genomic.gbff.gz
+    rnaDBPath: string | string[] // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/mRNA_Prot/human.[1-10].rna.gbff.gz
+) => {
+    const geneIndex = await getIndex(symbol, LRGPath)
+
+    // const regionData = await getFromAcc(geneIndex.GeneAcc.split('.')[0], regionDBPath)
+    // if (regionData) await fs.promises.writeFile('test-region.json', JSON.stringify(regionData, null, 4))
+
+    const headerTablePath = [
+        'feature', 'class', 'assembly', 'assembly_unit', 'seq_type', 'chromosome',
+        'genomic_accession', 'start', 'end', 'strand', 'product_accession', 'non_redundant_refseq',
+        'related_accession', 'name', 'symbol', 'GeneID', 'locus_tag', 'feature_interval_length',
+        'product_length','attributes'
+    ]
+    const allFeatures = await getPos({symbol}, tablePath, headerTablePath)
+
+    for (let index = 0; index < allFeatures.length; index++) {
+        const {feature, product_accession} = allFeatures[index]
+        let tmp
+        switch (feature) {
+            case 'gene':
+                allFeatures[index].product_accession = geneIndex.GeneAcc
+                tmp = await getFromAcc(geneIndex.GeneAcc.split('.')[0], geneDBPath)
+                await fs.promises.writeFile('test/test-gene.json', JSON.stringify(tmp, null, 4))
+                allFeatures[index].data = tmp
+                break;
+            case 'mRNA':
+                tmp = await getFromAcc(product_accession.split('.')[0], rnaDBPath)
+                await fs.promises.writeFile('test/test-rna-'+index+'.json', JSON.stringify(tmp, null, 4))
+                allFeatures[index].data = tmp
+                break;
+            default:
+                break;
+        }
+        
     }
-    return res
+    return allFeatures
 }
 
-export { getFromAcc }
+export { getFromAcc, getSymbol }

+ 2 - 0
package.json

@@ -12,6 +12,7 @@
   "license": "ISC",
   "devDependencies": {
     "@types/blessed": "^0.1.19",
+    "@types/figlet": "^1.5.4",
     "@types/node": "^17.0.19",
     "typescript": "^4.5.5"
   },
@@ -19,6 +20,7 @@
     "@gmod/bgzf-filehandle": "^1.4.2",
     "blessed": "^0.1.81",
     "chalk": "^4.1.2",
+    "figlet": "^1.5.2",
     "genbank-parser": "^1.2.4"
   }
 }

+ 25 - 0
test.js

@@ -0,0 +1,25 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+    return new (P || (P = Promise))(function (resolve, reject) {
+        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+        step((generator = generator.apply(thisArg, _arguments || [])).next());
+    });
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+const _1 = require(".");
+(() => __awaiter(void 0, void 0, void 0, function* () {
+    // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/RefSeqGene/LRG_RefSeqGene
+    const LRGPath = '/home/thomas/NGS/ref/ncbi/LRG_RefSeqGene';
+    // wget https://ftp.ncbi.nlm.nih.gov/genomes/all/annotation_releases/9606/109.20211119/GCF_000001405.39_GRCh38.p13/GCF_000001405.39_GRCh38.p13_feature_table.txt.gz
+    const tablePath = '/home/thomas/NGS/ref/ncbi/GCF_000001405.39_GRCh38.p13_feature_table.txt';
+    // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/biological_region/human.biological_region.gbff.gz
+    const regionDBPath = '/home/thomas/NGS/ref/ncbi/REGIONS/human.biological_region.gbff';
+    // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/RefSeqGene/refseqgene.[1-7].genomic.gbff.gz
+    const geneDBPath = [1, 2, 3, 4, 5, 6, 7].map(n => '/home/thomas/NGS/ref/ncbi/GENES/refseqgene.' + n + '.genomic.gbff');
+    // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/mRNA_Prot/human.[1-10].rna.gbff.gz
+    const rnaDBPath = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => '/home/thomas/NGS/ref/ncbi/RNA/human.' + n + '.rna.gbff');
+    yield (0, _1.getSymbol)('NOTCH1', LRGPath, tablePath, geneDBPath, rnaDBPath);
+}))();

+ 20 - 0
test.ts

@@ -0,0 +1,20 @@
+import { getSymbol } from '.'
+
+( async () => {
+    // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/RefSeqGene/LRG_RefSeqGene
+    const LRGPath = '/home/thomas/NGS/ref/ncbi/LRG_RefSeqGene'
+
+    // wget https://ftp.ncbi.nlm.nih.gov/genomes/all/annotation_releases/9606/109.20211119/GCF_000001405.39_GRCh38.p13/GCF_000001405.39_GRCh38.p13_feature_table.txt.gz
+    const tablePath = '/home/thomas/NGS/ref/ncbi/GCF_000001405.39_GRCh38.p13_feature_table.txt'
+    
+    
+    // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/biological_region/human.biological_region.gbff.gz
+    const regionDBPath = '/home/thomas/NGS/ref/ncbi/REGIONS/human.biological_region.gbff'
+    // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/RefSeqGene/refseqgene.[1-7].genomic.gbff.gz
+    const geneDBPath = [1,2,3,4,5,6,7].map(n => '/home/thomas/NGS/ref/ncbi/GENES/refseqgene.' + n + '.genomic.gbff')
+    // wget ftp://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/mRNA_Prot/human.[1-10].rna.gbff.gz
+    const rnaDBPath  = [1,2,3,4,5,6,7,8,9,10].map(n => '/home/thomas/NGS/ref/ncbi/RNA/human.' + n + '.rna.gbff')
+
+    await getSymbol('NOTCH1', LRGPath, tablePath, geneDBPath, rnaDBPath)
+})()
+

+ 10 - 0
yarn.lock

@@ -19,6 +19,11 @@
   dependencies:
     "@types/node" "*"
 
+"@types/figlet@^1.5.4":
+  version "1.5.4"
+  resolved "https://registry.yarnpkg.com/@types/figlet/-/figlet-1.5.4.tgz#54a426d63e921a9bca44102c5b1b1f206fa56d93"
+  integrity sha512-cskPTju7glYgzvkJy/hftqw7Fen3fsd0yrPOqcbBLJu+YdDQuA438akS1g+2XVKGzsQOnXGV2I9ePv6xUBnKMQ==
+
 "@types/node@*":
   version "17.0.21"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.21.tgz#864b987c0c68d07b4345845c3e63b75edd143644"
@@ -71,6 +76,11 @@ es6-promisify@^7.0.0:
   resolved "https://registry.npmjs.org/es6-promisify/-/es6-promisify-7.0.0.tgz"
   integrity sha512-ginqzK3J90Rd4/Yz7qRrqUeIpe3TwSXTPPZtPne7tGBPeAaQiU8qt4fpKApnxHcq1AwtUdHVg5P77x/yrggG8Q==
 
+figlet@^1.5.2:
+  version "1.5.2"
+  resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.5.2.tgz#dda34ff233c9a48e36fcff6741aeb5bafe49b634"
+  integrity sha512-WOn21V8AhyE1QqVfPIVxe3tupJacq1xGkPTB4iagT6o+P2cAgEOOwIxMftr4+ZCTI6d551ij9j61DFr0nsP2uQ==
+
 file-uri-to-path@^2.0.0:
   version "2.0.0"
   resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz"