Thomas 3 ani în urmă
părinte
comite
939b4e43a2
2 a modificat fișierele cu 124 adăugiri și 40 ștergeri
  1. 70 22
      dist/index.js
  2. 54 18
      index.ts

+ 70 - 22
dist/index.js

@@ -1,4 +1,15 @@
 "use strict";
+var __assign = (this && this.__assign) || function () {
+    __assign = Object.assign || function(t) {
+        for (var s, i = 1, n = arguments.length; i < n; i++) {
+            s = arguments[i];
+            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+                t[p] = s[p];
+        }
+        return t;
+    };
+    return __assign.apply(this, arguments);
+};
 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) {
@@ -35,6 +46,15 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
         if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
     }
 };
+var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
+    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
+        if (ar || !(i in from)) {
+            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
+            ar[i] = from[i];
+        }
+    }
+    return to.concat(ar || Array.prototype.slice.call(from));
+};
 var __importDefault = (this && this.__importDefault) || function (mod) {
     return (mod && mod.__esModule) ? mod : { "default": mod };
 };
@@ -57,18 +77,27 @@ var asyncBwaMem = function (refPath, reads,
 // R1        : string | Array<string>,
 // R2        : string | Array<string>,
 runName, libName, outputDir, onData, options) {
-    if (typeof options === 'undefined')
-        options = {
-            discordants: true,
-            splitted: true
-        };
+    var defaultOptions = {
+        output_discordant: true,
+        output_splitted: true,
+        output_unmapped: true
+    };
+    if (typeof options === 'undefined') {
+        options = defaultOptions;
+    }
+    else {
+        options = __assign(__assign({}, defaultOptions), options);
+    }
     var refName = path_1.default.parse(refPath).name;
     var bwa = 'bwa';
     var samblaster = 'samblaster';
     var samtools = 'samtools';
     var sambamba = 'sambamba';
     var readsIn;
+    var isPairedEnd = false;
     if (Array.isArray(reads)) {
+        isPairedEnd = true;
+        console.log('Assuming paired end reads');
         var R1 = reads[0], R2 = reads[1];
         var R1_arr = Array.isArray(R1) ? R1.join(' ') : R1;
         var R2_arr = Array.isArray(R2) ? R2.join(' ') : R2;
@@ -81,37 +110,56 @@ runName, libName, outputDir, onData, options) {
     else {
         readsIn = reads;
     }
-    var discordantFile = path_1.default.join(outputDir, "bwa_mem_discordants_on_".concat(refName, ".sam"));
-    var splitterFile = path_1.default.join(outputDir, "bwa_mem_splitters_on_".concat(refName, ".sam"));
-    var unmappedFile = path_1.default.join(outputDir, "bwa_mem_unmapped_on_".concat(refName, ".fq"));
     var bam = path_1.default.join(outputDir, "bwa_mem_properly_on_".concat(refName, ".bam"));
     var bamSorted = path_1.default.join(outputDir, "bwa_mem_properly_on_".concat(refName, ".sorted.bam"));
+    var retObj = { bamSorted: bamSorted };
     var threads = String((0, os_1.cpus)().length);
+    var samblasterCmd = [];
+    if ((options === null || options === void 0 ? void 0 : options.output_discordant) || (options === null || options === void 0 ? void 0 : options.output_splitted)) {
+        console.log('Using samblaster');
+        // https://github.com/GregoryFaust/samblaster
+        samblasterCmd = ['|', samblaster,
+            '--addMateTags',
+            '-a',
+            '-e', // Exclude reads marked as duplicates from discordant, splitter, and/or unmapped
+        ];
+        if (options === null || options === void 0 ? void 0 : options.output_discordant) {
+            if (!isPairedEnd)
+                throw 'Error discordant reads can be found only in paired reads';
+            var discordantFile = path_1.default.join(outputDir, "bwa_mem_discordants_on_".concat(refName, ".sam"));
+            console.log('Discordant reads file path: ', discordantFile);
+            samblasterCmd = __spreadArray(__spreadArray([], samblasterCmd, true), ['-d', discordantFile], false);
+            retObj = __assign(__assign({}, retObj), { discordantFile: discordantFile });
+        }
+        if (options === null || options === void 0 ? void 0 : options.output_splitted) {
+            var splitterFile = path_1.default.join(outputDir, "bwa_mem_splitters_on_".concat(refName, ".sam"));
+            console.log('Splitted reads file path: ', splitterFile);
+            samblasterCmd = __spreadArray(__spreadArray([], samblasterCmd, true), ['-s', splitterFile], false);
+            retObj = __assign(__assign({}, retObj), { splitterFile: splitterFile });
+        }
+        if (options === null || options === void 0 ? void 0 : options.output_unmapped) {
+            var unmappedFile = path_1.default.join(outputDir, "bwa_mem_unmapped_on_".concat(refName, ".fq"));
+            console.log('Unmapped reads file path: ', unmappedFile);
+            samblasterCmd = __spreadArray(__spreadArray([], samblasterCmd, true), ['-u', unmappedFile], false);
+            retObj = __assign(__assign({}, retObj), { unmappedFile: unmappedFile });
+        }
+    }
     return new Promise(function (resolve, reject) { return __awaiter(void 0, void 0, void 0, function () {
         var code, code_sort, err_1;
         return __generator(this, function (_a) {
             switch (_a.label) {
                 case 0:
                     _a.trys.push([0, 3, , 4]);
-                    return [4 /*yield*/, async_exec(bwa, ['mem',
+                    return [4 /*yield*/, async_exec(bwa, __spreadArray(__spreadArray(['mem',
                             '-t', threads,
                             '-R', "\"@RG\\tPL:Illumina\\tID:".concat(+(new Date), "\\tSM:").concat(runName, "\\tLB:").concat(libName, "\""), refPath,
-                            readsIn,
-                            '|',
-                            samblaster,
-                            '--addMateTags',
-                            '-a',
-                            '-e',
-                            '-d', discordantFile,
-                            '-s', splitterFile,
-                            '-u', unmappedFile,
-                            '|',
+                            readsIn], samblasterCmd, true), ['|',
                             samtools,
                             'view',
-                            '-b',
+                            '-Sb',
                             '-',
                             '>',
-                            bam], function (message) { return onData('[BWA-MEM] ' + message); })];
+                            bam], false), function (message) { return onData('[BWA-MEM] ' + message); })];
                 case 1:
                     code = _a.sent();
                     onData('[BWA-MEM][EXIT CODE] ' + code);
@@ -123,7 +171,7 @@ runName, libName, outputDir, onData, options) {
                     code_sort = _a.sent();
                     onData('[SAMBAMBA-SORT][EXIT CODE] ' + code_sort);
                     fs_1.default.unlinkSync(bam);
-                    resolve([bamSorted, discordantFile, splitterFile, unmappedFile]);
+                    resolve(retObj);
                     return [3 /*break*/, 4];
                 case 3:
                     err_1 = _a.sent();

+ 54 - 18
index.ts

@@ -27,9 +27,16 @@ const asyncBwaMem = (
     options?  : any,
     ) => {
 
-    if (typeof options === 'undefined') options = {
-      discordants: true,
-      splitted: true
+    const defaultOptions = {
+      output_discordant: true,
+      output_splitted: true,
+      output_unmapped: true
+    }
+
+    if (typeof options === 'undefined') {
+      options = defaultOptions
+    } else {
+      options = {...defaultOptions, ...options}
     }
 
     const refName = path.parse(refPath).name
@@ -40,8 +47,12 @@ const asyncBwaMem = (
     const sambamba   = 'sambamba'
 
     let readsIn: string
+    let isPairedEnd = false
 
     if (Array.isArray(reads) ) {
+      isPairedEnd = true
+      console.log('Assuming paired end reads');
+      
       const [R1, R2] = reads
       const R1_arr = Array.isArray(R1) ? R1.join(' ') : R1
       const R2_arr = Array.isArray(R2) ? R2.join(' ') : R2
@@ -55,14 +66,46 @@ const asyncBwaMem = (
     } else {
       readsIn = reads
     }
-  
-    const discordantFile = path.join(outputDir, `bwa_mem_discordants_on_${refName}.sam`)
-    const splitterFile   = path.join(outputDir, `bwa_mem_splitters_on_${refName}.sam`)
-    const unmappedFile   = path.join(outputDir, `bwa_mem_unmapped_on_${refName}.fq`)
     const bam            = path.join(outputDir, `bwa_mem_properly_on_${refName}.bam`)
     const bamSorted      = path.join(outputDir, `bwa_mem_properly_on_${refName}.sorted.bam`)
 
+    let retObj: any = { bamSorted } 
+
     const threads = String(cpus().length)
+
+    let samblasterCmd: Array<string> = []
+    if (options?.output_discordant || options?.output_splitted) {
+      console.log('Using samblaster');
+
+      // https://github.com/GregoryFaust/samblaster
+      samblasterCmd = ['|', samblaster, 
+        '--addMateTags',
+        '-a', // Accept duplicate marks already in input file
+        '-e', // Exclude reads marked as duplicates from discordant, splitter, and/or unmapped
+      ]
+
+      if(options?.output_discordant) {
+        if(!isPairedEnd) throw 'Error discordant reads can be found only in paired reads'
+        const discordantFile = path.join(outputDir, `bwa_mem_discordants_on_${refName}.sam`)
+        console.log('Discordant reads file path: ', discordantFile);
+        samblasterCmd = [...samblasterCmd, '-d', discordantFile]
+        retObj = {...retObj, discordantFile}
+      }
+
+      if(options?.output_splitted) {
+        const splitterFile   = path.join(outputDir, `bwa_mem_splitters_on_${refName}.sam`)
+        console.log('Splitted reads file path: ', splitterFile);
+        samblasterCmd = [...samblasterCmd, '-s', splitterFile]
+        retObj = {...retObj, splitterFile}
+      }
+
+      if(options?.output_unmapped) {
+        const unmappedFile   = path.join(outputDir, `bwa_mem_unmapped_on_${refName}.fq`)
+        console.log('Unmapped reads file path: ', unmappedFile);
+        samblasterCmd = [...samblasterCmd, '-u', unmappedFile]
+        retObj = {...retObj, unmappedFile}
+      }
+    }
   
     return new Promise<string[]>(async (resolve, reject) => {
       try {
@@ -72,18 +115,11 @@ const asyncBwaMem = (
           '-R', `"@RG\\tPL:Illumina\\tID:${+(new Date)}\\tSM:${runName}\\tLB:${libName}"`,
           refPath, 
           readsIn,
-        '|',
-        samblaster,
-          '--addMateTags', // https://github.com/GregoryFaust/samblaster
-          '-a', // Accept duplicate marks already in input file
-          '-e', // Exclude reads marked as duplicates from discordant, splitter, and/or unmapped
-          '-d', discordantFile,
-          '-s', splitterFile,
-          '-u', unmappedFile,
+        ...samblasterCmd,
         '|',
         samtools,
           'view',
-          '-b',
+          '-Sb',
           '-',
         '>',
         bam
@@ -98,8 +134,8 @@ const asyncBwaMem = (
         onData('[SAMBAMBA-SORT][EXIT CODE] ' + code_sort)
   
         fs.unlinkSync(bam)
-  
-        resolve([bamSorted, discordantFile, splitterFile, unmappedFile])
+        
+        resolve(retObj)
       } catch (err) {
         reject(err)
       }