| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- "use strict";
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
- }) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
- }));
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
- }) : function(o, v) {
- o["default"] = v;
- });
- var __importStar = (this && this.__importStar) || function (mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
- };
- 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());
- });
- };
- var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.scheduleAsyncBwaMem = exports.makeReference = exports.writeSequence = exports.asyncBwaMem = void 0;
- const child_process_1 = require("child_process");
- const os_1 = require("os");
- const fs_1 = __importDefault(require("fs"));
- const path_1 = __importDefault(require("path"));
- const fastq = __importStar(require("fastq"));
- const async_exec = (prog, args, onData) => {
- return new Promise((resolve, reject) => {
- const child = (0, child_process_1.spawn)(prog, args, { shell: true });
- child.stdout.on('data', data => onData(data.toString().trim()));
- child.stderr.on('data', data => onData(data.toString().trim()));
- child.on('error', err => reject(err));
- child.on('exit', code => resolve(code));
- });
- };
- const invReplace = (regex, string, by = '_') => string.split('').map(letter => letter.match(regex) ? letter : by).join('');
- const writeSequence = (sequenceName, sequence, filePath, lineN = 80) => __awaiter(void 0, void 0, void 0, function* () {
- return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
- var _a;
- try {
- const r = new RegExp(".{1," + lineN + "}", "g");
- const regex_sam_restriction = /[>0-9A-Za-z!#$%&+\./:;?@^_|~-]|[\n\t]/g;
- const nSeqName = invReplace(regex_sam_restriction, sequenceName);
- yield fs_1.default.promises.writeFile(filePath, '>' + nSeqName + '\n' + ((_a = sequence.match(r)) === null || _a === void 0 ? void 0 : _a.join('\n').toUpperCase()));
- resolve(true);
- }
- catch (error) {
- console.log(error);
- reject(false);
- }
- }));
- });
- exports.writeSequence = writeSequence;
- const makeReference = (sequenceName, sequence, filePath, lineN = 80) => __awaiter(void 0, void 0, void 0, function* () {
- if (yield writeSequence(sequenceName, sequence, filePath, lineN))
- yield async_exec('bwa', ['index', filePath], () => console.log);
- });
- exports.makeReference = makeReference;
- const asyncBwaMem = (refPath, reads,
- // R1 : string | Array<string>,
- // R2 : string | Array<string>,
- runName, libName, outputDir, onData, options) => {
- return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
- try {
- const defaultOptions = {
- output_discordant: true,
- output_splitted: true,
- output_unmapped: true
- };
- if (typeof options === 'undefined') {
- options = defaultOptions;
- }
- else {
- options = Object.assign(Object.assign({}, defaultOptions), options);
- }
- const refName = path_1.default.parse(refPath).name;
- const bwa = 'bwa';
- const samblaster = 'samblaster';
- const samtools = 'samtools';
- const sambamba = 'sambamba';
- let readsIn;
- 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;
- const R1_kitty = R1_arr.slice(-2) === 'gz' ? 'zcat' : 'cat';
- const R2_kitty = R2_arr.slice(-2) === 'gz' ? 'zcat' : 'cat';
- const R1_in = `'< ${R1_kitty} ${R1_arr}'`;
- const R2_in = `'< ${R2_kitty} ${R2_arr}'`;
- readsIn = R1_in + ' ' + R2_in;
- }
- else {
- readsIn = reads;
- }
- let bam = path_1.default.join(outputDir, `bwa_mem_properly_on_${refName}.bam`);
- let bamSorted = path_1.default.join(outputDir, `bwa_mem_properly_on_${refName}.sorted.bam`);
- let retObj = { bamSorted };
- if (options === null || options === void 0 ? void 0 : options.remove_mapped) {
- bam = '/dev/null';
- delete retObj.bamSorted;
- }
- const threads = String((0, os_1.cpus)().length);
- let samblasterCmd = [];
- // 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) || (options === null || options === void 0 ? void 0 : options.output_splitted)) {
- console.log('Using samblaster');
- if (options === null || options === void 0 ? void 0 : options.output_discordant) {
- if (!isPairedEnd) {
- console.log('Discordant reads can be found only in paired reads, skipping');
- }
- else {
- const discordantFile = path_1.default.join(outputDir, `bwa_mem_discordants_on_${refName}.sam`);
- console.log('Discordant reads file path: ', discordantFile);
- samblasterCmd = [...samblasterCmd, '-d', discordantFile];
- retObj = Object.assign(Object.assign({}, retObj), { discordantFile });
- }
- }
- if (!isPairedEnd) {
- samblasterCmd = [...samblasterCmd, '--ignoreUnmated'];
- }
- if (options === null || options === void 0 ? void 0 : options.output_splitted) {
- const splitterFile = path_1.default.join(outputDir, `bwa_mem_splitters_on_${refName}.sam`);
- console.log('Splitted reads file path: ', splitterFile);
- samblasterCmd = [...samblasterCmd, '-s', splitterFile];
- retObj = Object.assign(Object.assign({}, retObj), { splitterFile });
- }
- }
- if (options === null || options === void 0 ? void 0 : options.output_unmapped) {
- const unmappedFile = path_1.default.join(outputDir, `bwa_mem_unmapped_on_${refName}.fq`);
- console.log('Unmapped reads file path: ', unmappedFile);
- samblasterCmd = [...samblasterCmd, '-u', unmappedFile];
- retObj = Object.assign(Object.assign({}, retObj), { unmappedFile });
- }
- if (!fs_1.default.existsSync(refPath + '.amb')) {
- yield async_exec(bwa, ['index', refPath], (message) => onData('[BWA-INDEX] ' + message));
- }
- console.log(options, samblasterCmd);
- const code = yield async_exec(bwa, ['mem',
- '-t', threads,
- '-R', `"@RG\\tPL:Illumina\\tID:${+(new Date)}\\tSM:${runName}\\tLB:${libName}"`,
- refPath,
- readsIn,
- ...samblasterCmd,
- '|',
- samtools,
- 'view',
- '-Sb',
- '-',
- '>',
- bam
- ], (message) => onData('[BWA-MEM] ' + message));
- onData('[BWA-MEM][EXIT CODE] ' + code);
- if (retObj.bamSorted) {
- const code_sort = yield async_exec(sambamba, ['sort',
- '-t', threads,
- bam
- ], (message) => onData('[SAMBAMBA-SORT] ' + message));
- onData('[SAMBAMBA-SORT][EXIT CODE] ' + code_sort);
- fs_1.default.unlinkSync(bam);
- }
- resolve(retObj);
- }
- catch (err) {
- reject(err);
- }
- }));
- };
- exports.asyncBwaMem = asyncBwaMem;
- const asyncBwaMemWorker = (args) => __awaiter(void 0, void 0, void 0, function* () {
- const { refPath, reads, runName, libName, outputDir, onData } = args;
- yield asyncBwaMem(refPath, reads, runName, libName, outputDir, onData);
- });
- const scheduleAsyncBwaMem = (allReads, refPath, runName, libName, allOutputDir, onData) => __awaiter(void 0, void 0, void 0, function* () {
- const q = fastq.promise(asyncBwaMemWorker, 1);
- yield Promise.all(allReads.map((reads, i) => q.push({ refPath, reads, runName, libName, outputDir: allOutputDir[i], onData })));
- });
- exports.scheduleAsyncBwaMem = scheduleAsyncBwaMem;
|