Skip to content

Instantly share code, notes, and snippets.

@romgrk
Created October 16, 2017 21:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save romgrk/73027f78b51ad0ea4bb45d1de96d6fe1 to your computer and use it in GitHub Desktop.
Save romgrk/73027f78b51ad0ea4bb45d1de96d6fe1 to your computer and use it in GitHub Desktop.
Slices and merges bigWig files into a single bedGraph file
#!/usr/bin/env node
/*
* slice-and-merge - slices and merges bigWig files into a single bedGraph
*
* Usage:
* slice-and-merge [OPTIONS] file1.bw file2.bw .. fileN.bw
*
* Options:
* -o, --output <FILE> output file (default: out.bedGraph)
* -b, --bin <DIR> defines the bin directory for utils (default: ./bin)
* -p, --position <CHROM>:<START>-<END> position to slice, e.g. chr1:1-100000
* -v, --verbose print more details
* -h, --help print this message
*/
const fs = require('fs')
const path = require('path')
const child_process = require('child_process')
const { promisify } = require('util')
const exec = promisify(child_process.exec)
const writeFile = promisify(fs.writeFile)
const basename = filename => path.basename(filename, path.extname(filename))
const changeExtname = (filename, ext) => path.join(path.dirname(filename), basename(filename) + ext)
const args = process.argv.slice(2)
const options = {
verbose: false,
bin: './bin',
output: 'out.bedGraph'
}
const files = []
if (args.length === 0)
printUsage()
// Parse arguments
for (let i = 0; i < args.length; i++) {
const arg = args[i]
const next = args[i + 1]
if (['-p', '--position'].some(o => o === arg)) {
const [ chromosome, position ] = next.split(':')
const [ start, end ] = position ? position.split('-') : []
options.chromosome = chromosome
options.start = start
options.end = end
i += 1
} else if (['-o', '--output'].some(o => o === arg)) {
options.output = next
i += 1
} else if (['-b', '--bin'].some(o => o === arg)) {
options.bin = next
i += 1
} else if (['-v', '--verbose'].some(o => o === arg)) {
options.verbose = true
} else if (['-h', '--help'].some(o => o === arg)) {
printUsage()
} else {
files.push(arg)
}
}
// Command generation
const toWigCommand = file => ({
output: changeExtname(file, '.wig'),
command: [
path.join(options.bin, `bigWigToWig`),
`${ options.chromosome ? '-chrom=' + options.chromosome : '' }`,
`${ options.start ? '-start=' + options.start : '' }`,
`${ options.end ? '-end=' + options.end : '' }`,
file,
changeExtname(file, '.wig')
].join(' ')
})
const toBigWigCommand = file => ({
output: changeExtname(file, '.out.bw'),
command: [
path.join(options.bin, `wigToBigWig`),
file,
'chrom.sizes',
changeExtname(file, '.out.bw')
].join(' ')
})
const mergeCommand = files => ({
output: options.output,
command: [
path.join(options.bin, `bigWigMerge`),
files.join(' '),
options.output
].join(' ')
})
log(options, '\n')
log('bigWigToWig -------------------------------------------------------')
Promise.all( // bigWigToWig
files.map(file => {
const to = toWigCommand(file)
log(' Running:', to.command)
return exec(to.command).then(() => to.output)
})
.concat(writeFile('chrom.sizes', [options.chromosome, options.end].join(' ')))
)
.then((files) => { // wigToBigWig
log('wigToBigWig -----------------------------------------------------')
return Promise.all(
files.filter(f => f !== undefined).map(file => {
const to = toBigWigCommand(file)
log(' Running:', to.command)
return exec(to.command).then(() => to.output)
})
)
})
.then((files) => { // bigWigMerge
log('bigWigMerge -----------------------------------------------------')
const merge = mergeCommand(files)
log(' Running:', merge.command)
return exec(merge.command).then(() => merge.output)
})
.then((output) => {
log('Done ------------------------------------------------------------')
console.log(' Output written at', output)
})
.catch(err =>
console.error('Error:', err))
function log(...args) {
if (!options.verbose)
return
console.log(...args)
}
function printUsage() {
console.log('slice-and-merge - slices and merges bigWig files into a single bedGraph')
console.log('')
console.log('Usage:')
console.log('\tslice-and-merge [OPTIONS] file1.bw file2.bw .. fileN.bw')
console.log('')
console.log('Options:')
console.log('\t-o, --output <FILE> output file (default: out.bedGraph)')
console.log('\t-b, --bin <DIR> defines the bin directory for utils (default: ./bin)')
console.log('\t-p, --position <CHROM>:<START>-<END> position to slice, e.g. chr1:1-100000')
console.log('\t-v, --verbose print more details')
console.log('\t-h, --help print this message')
process.exit(0)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment