| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- import { spawn } from 'child_process';
- import { cpus } from 'os';
- import fs from 'fs'
- import path from 'path';
- const async_exec = (prog: string, args: string[], onData: Function) => {
- return new Promise((resolve, reject) => {
- const child = 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 asyncBwaMem = (
- refPath : string,
- R1 : string | Array<string>,
- R2 : string | Array<string>,
- runName : string,
- libName : string,
- output_dir: string,
- onData : Function,
- options? : any,
- ) => {
- if (typeof options === 'undefined') options = {}
- const refName = path.parse(refPath).name
-
- const bwa = 'bwa'
- const samblaster = 'samblaster'
- const samtools = 'samtools'
- const sambamba = 'sambamba'
-
- 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}'`
-
- const discordantFile = path.join(output_dir, `bwa_mem_discordants_on_${refName}.sam`)
- const splitterFile = path.join(output_dir, `bwa_mem_splitters_on_${refName}.sam`)
- const unmappedFile = path.join(output_dir, `bwa_mem_unmapped_on_${refName}.fq`)
- const bam = path.join(output_dir, `bwa_mem_properly_on_${refName}.bam`)
- const bamSorted = path.join(output_dir, `bwa_mem_properly_on_${refName}.sorted.bam`)
-
- return new Promise<string[]>(async (resolve, reject) => {
- try {
- const code = await async_exec(
- bwa, ['mem',
- '-t', String(cpus().length),
- '-R', `"@RG\\tPL:Illumina\\tID:${+(new Date)}\\tSM:${runName}\\tLB:${libName}"`,
- refPath, R1_in, R2_in,
- '|',
- 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,
- '|',
- samtools,
- 'view',
- '-b',
- '-',
- '>',
- bam
- ], (message: string) => onData('[BWA-MEM] ' + message))
- onData('[BWA-MEM][EXIT CODE] ' + code)
-
- const code_sort = await async_exec(
- sambamba, ['sort',
- '-t', String(require('os').cpus().length),
- bam
- ], (message: string) => onData('[SAMBAMBA-SORT] ' + message))
- onData('[SAMBAMBA-SORT][EXIT CODE] ' + code_sort)
-
- fs.unlinkSync(bam)
-
- resolve([bamSorted, discordantFile, splitterFile, unmappedFile])
- } catch (err) {
- reject(err)
- }
- })
- }
- export { asyncBwaMem }
|