Skip to content

Commit

Permalink
Merge pull request #243 from hybsearch/configurable-jml-and-mrbayes
Browse files Browse the repository at this point in the history
Expose JML and MrBayes config to the UI
  • Loading branch information
hawkrives committed Apr 27, 2019
2 parents 96b5cf7 + f26a43c commit 763adba
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 25 deletions.
35 changes: 33 additions & 2 deletions server/pipeline/pipelines/mbnb.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,33 @@ let options = {
label: "BEAST's 'chainLength' parameter",
description: 'another desc',
},
mrBayesConfig: {
default: `
set autoclose=yes nowarn=yes;
lset nst=6 rates=invgamma;
prset topologypr = uniform;
prset brlenspr = clock:uniform;
mcmc ngen=20000 samplefreq=100;
sumt;`.trim(),
type: 'textarea',
label: 'MrBayes Config',
description: '',
},
jmlConfig: {
default: `
# species and seqperspecies are automatically set,
# but can be overridden here if needed
locusrate = 1.0
heredityscalar = 0.25
seqgencommand = -mHKY -f0.2678,0.1604,0.2031,0.3687 -t1.5161 -i0 -a0.2195 -l810
significancelevel = 0.9999
burnin = 0
thinning = 1
seed = -1`.trim(),
type: 'textarea',
label: 'JML Config',
description: '',
},
}

let steps = [
Expand Down Expand Up @@ -64,7 +91,7 @@ let steps = [
{
// does whatever mrbayes does
input: ['aligned-nexus'],
transform: ([data]) => [mrBayes(data)],
transform: ([data], { mrBayesConfig }) => [mrBayes(data, mrBayesConfig)],
output: ['consensus-tree'],
},
{
Expand Down Expand Up @@ -149,11 +176,15 @@ let steps = [
{
// run JML
input: ['phylipified-trees', 'aligned-phylip', 'phylip-identifier-map'],
transform: ([phylipifiedTrees, alignedPhylip, phylipIdentMap]) => [
transform: (
[phylipifiedTrees, alignedPhylip, phylipIdentMap],
{ jmlConfig }
) => [
jml({
phylipData: alignedPhylip,
trees: phylipifiedTrees,
phylipMapping: phylipIdentMap,
config: jmlConfig,
}),
],
output: ['jml-output'],
Expand Down
8 changes: 7 additions & 1 deletion server/ui/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,15 @@ const handleNewSteps = payload => {
([key, val]) =>
// prettier-ignore
`<div class="option-row">
<label>${val.label}: <input name="${key}" type="${val.type}" value="${val.default}" placeholder="${val.description}"></label>
<label>
${val.label}:
${val.type === 'textarea'
? `<textarea name="${key}" placeholder="${val.description}">${val.default}</textarea>`
: `<input name="${key}" type="${val.type}" value="${val.default}" placeholder="${val.description}">`}
</label>
</div>`
)

if (options.length) {
optionsEl.removeAttribute('hidden')
optionsContainer.innerHTML = options.join('')
Expand Down
8 changes: 6 additions & 2 deletions server/wrappers/jml/__tests__/__snapshots__/ctl.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,27 @@
exports[`emydura-short.phy 1`] = `
"species = tQwNDLi oTYwLH vwAqcZ CXTpAGBdz
seqperspecies = 3 2 2 1
locusrate = 1.0
heredityscalar = 0.25
seqgencommand = -mHKY -f0.2678,0.1604,0.2031,0.3687 -t1.5161 -i0 -a0.2195 -l810
significancelevel = 0.9999
burnin = 0
thinning = 1
seed = -1"
seed = -1
"
`;

exports[`smallerlepus.phy 1`] = `
"species = igcfean abbdbkga cbcidpnh bkaabphc
seqperspecies = 15 2 8 4
locusrate = 1.0
heredityscalar = 0.25
seqgencommand = -mHKY -f0.2678,0.1604,0.2031,0.3687 -t1.5161 -i0 -a0.2195 -l810
significancelevel = 0.9999
burnin = 0
thinning = 1
seed = -1"
seed = -1
"
`;
14 changes: 9 additions & 5 deletions server/wrappers/jml/ctl.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@
const mapValues = require('lodash/mapValues')
const groupBy = require('lodash/groupBy')

function makeControlData(speciesCounts) {
return `species = ${Object.keys(speciesCounts).join(' ')}
seqperspecies = ${Object.values(speciesCounts).join(' ')}
let defaultConfig = `
locusrate = 1.0
heredityscalar = 0.25
seqgencommand = -mHKY -f0.2678,0.1604,0.2031,0.3687 -t1.5161 -i0 -a0.2195 -l810
significancelevel = 0.9999
burnin = 0
thinning = 1
seed = -1`

function makeControlData(speciesCounts, config) {
return `species = ${Object.keys(speciesCounts).join(' ')}
seqperspecies = ${Object.values(speciesCounts).join(' ')}
${config || defaultConfig}
`
}

function getSpeciesFromPhylip(phylipData) {
Expand All @@ -26,12 +30,12 @@ function getSpeciesFromPhylip(phylipData) {
}

module.exports = computeSpecies
function computeSpecies(phylip) {
function computeSpecies(phylip, config) {
let allSpecies = [...getSpeciesFromPhylip(phylip)]
let speciesCounts = mapValues(
groupBy(allSpecies, speciesName => speciesName.split('x')[0]),
speciesInstances => speciesInstances.length
)

return makeControlData(speciesCounts)
return makeControlData(speciesCounts, config)
}
4 changes: 2 additions & 2 deletions server/wrappers/jml/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const readJmlOutputFile = filepath => {
}

module.exports = jml
async function jml({ phylipData, trees, phylipMapping }) {
async function jml({ phylipData, trees, phylipMapping, config }) {
let workDir = tempy.directory()

let phylipFile = path.join(workDir, 'input.phy')
Expand All @@ -38,7 +38,7 @@ async function jml({ phylipData, trees, phylipMapping }) {
fs.writeFileSync(treesFile, trees, 'utf-8')

let controlFile = path.join(workDir, 'jml.input.ctl')
let controlData = generateControlFile(phylipData)
let controlData = generateControlFile(phylipData, config)
fs.writeFileSync(controlFile, controlData, 'utf-8')

// find binary via `which`
Expand Down
30 changes: 17 additions & 13 deletions server/wrappers/mrbayes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,30 @@ $ mb
# Created consensus tree file: {ORIG_FILENAME}.con.tre
*/

function insertCommandBlock(data) {
let cmdBlock = dedent`
begin mrbayes;
set autoclose=yes nowarn=yes;
lset nst=6 rates=invgamma;
prset topologypr = uniform;
prset brlenspr = clock:uniform;
mcmc ngen=20000 samplefreq=100;
sumt;
end;`
return data.replace('end;', `end;\n${cmdBlock}\n`)
let cmdBlock = `
set autoclose=yes nowarn=yes;
lset nst=6 rates=invgamma;
prset topologypr = uniform;
prset brlenspr = clock:uniform;
mcmc ngen=20000 samplefreq=100;
sumt;
`

function insertCommandBlock(data, config) {
config = dedent`
begin mrbayes;
${config || cmdBlock}
end;`
return data.replace('end;', `end;\n${config}\n`)
}

module.exports = mrbayes
async function mrbayes(data) {
async function mrbayes(data, config) {
const inputFile = tempy.file()
const outputFile = inputFile + '.con.tre'

// we can control mrbayes with a "command block"
data = insertCommandBlock(data)
data = insertCommandBlock(data, config)

fs.writeFileSync(inputFile, data, 'utf-8')

Expand Down

0 comments on commit 763adba

Please sign in to comment.