Commit ce7f34fb authored by jhoogenboom's avatar jhoogenboom

Various bug fixes and additions

Fixed:
* Fixed crash that would occur when an empty sequence (primer dimer) is converted from raw to TSSV-style (or allelename) format.
* Fixed bug in BGHomRaw that caused incorrect sample tags in the output.
* Fixed bug that caused allele names with negative CE numbers and names of primer dimers to be regarded as 'invalid allele names' even though FDSTools generated those names itself.
* Fixed crash when reading sample data while looking for an annotation column.
* Fixed bug in Allelefinder resulting in the complete absence of output that occurred when a column name with Stuttermark output was specified.

Changed:
* Restyled the Options box on HTML visualisations. It is now less transparent and oriented more vertically to reduce overlap with the visualisation. Options are now presented in groups.
* Updated Vega to version 2.2.1.

New:
* Added *_corrected columns to BGCorrect output for convenience. E.g., the total_corrected column contains the value of total-total_noise+total_add.
* Added -L/--log-scale option to the Vis tool.
parent 8213ec14
......@@ -10,7 +10,7 @@ from StringIO import StringIO
PAT_SEQ_RAW = re.compile("^[ACGT]*$")
PAT_SEQ_TSSV = re.compile("^(?:[ACGT]+\(\d+\))*$")
PAT_SEQ_ALLELENAME = re.compile( # First line: n_ACT[m] or alias.
"^(?:(?:(?:CE)?\d+(?:\.\d+)?_(?:[ACGT]+\[\d+\])+)|((?!_).+?))"
"^(?:(?:(?:CE)?-?\d+(?:\.\d+)?_(?:[ACGT]+\[\d+\])*)|((?!_).+?))"
"(?:_[-+]\d+(?:\.1)?(?P<a>(?:(?<=\.1)-)|(?<!\.1)[ACGT]+)>" # _+3A>
"(?!(?P=a))(?:[ACTG]+|-))*$") # Portion of variants after '>'.
......@@ -603,8 +603,8 @@ def convert_sequence_raw_tssv(seq, library, marker, return_alias=False):
if match is None and marker in library["regex"]:
match = library["regex"][marker].match(seq)
if match is not None:
parts = ((match.group(i), match.end(i))
for i in range(1, match.lastindex+1) if match.group(i))
parts = ((match.group(i), match.end(i)) for i in range(1, 1 if
match.lastindex is None else match.lastindex+1) if match.group(i))
# Use heuristics if the sequence does not match the pattern.
else:
......@@ -727,11 +727,11 @@ def convert_sequence_raw_allelename(seq, library, marker):
remaining_blocks = len(blocks)
if "prefix" in library and marker in library["prefix"]:
prefix = library["prefix"][marker][0]
if prefix and blocks[0][1] == "1":
if prefix and remaining_blocks > 0 and blocks[0][1] == "1":
remaining_blocks -= 1
if "suffix" in library and marker in library["suffix"]:
suffix = library["suffix"][marker][0]
if suffix and blocks[-1][1] == "1":
if suffix and remaining_blocks > 0 and blocks[-1][1] == "1":
remaining_blocks -= 1
if remaining_blocks > 0 and prefix and blocks[0][1] == "1":
this_prefix = blocks[0][0]
......@@ -932,7 +932,7 @@ def read_sample_data_file(infile, data, annotation_column=None, seqformat=None,
library=library, marker=marker)
if (annotation_column is not None and
line[colid_annotation].startswith("ALLELE")):
found_alleles.append(marker, allele)
found_alleles.append((marker, allele))
data[marker, allele] = map(int,
(line[colid_forward], line[colid_reverse]))
......
......@@ -53,7 +53,8 @@ def find_alleles(samples_in, outfile, reportfile, min_reads, min_allele_pct,
samples_in,
lambda tag, data: find_alleles_sample(
data if stuttermark_column is None
else {key: data[key] for key in allelelist[tag]},
else {key: data[key] for key in data if key[0] in
allelelist[tag]},
outfile, reportfile, tag, min_reads, min_allele_pct, max_noise_pct,
max_alleles, max_noisy, seqformat, library),
allelelist,
......
......@@ -3,10 +3,11 @@
Match background noise profiles (obtained from e.g., bgestimate) to
samples.
Six new columns are added to the output giving, for each sequence, the
Nine new columns are added to the output giving, for each sequence, the
number of reads attributable to noise from other sequences (_noise
columns) and the number of noise reads caused by the prescense of this
sequence (_add columns).
sequence (_add columns), as well as the resulting number of reads after
correction (_corrected columns: original minus _noise plus _add).
"""
import argparse
#import numpy as np # Only imported when actually running this tool.
......@@ -30,6 +31,9 @@ def get_sample_data(infile, convert_to_raw=False, library=None):
column_names.append("forward_add")
column_names.append("reverse_add")
column_names.append("total_add")
column_names.append("forward_corrected")
column_names.append("reverse_corrected")
column_names.append("total_corrected")
colid_name, colid_allele, colid_forward, colid_reverse = get_column_ids(
column_names, "name", "allele", "forward", "reverse")
data = {}
......@@ -47,6 +51,9 @@ def get_sample_data(infile, convert_to_raw=False, library=None):
cols.append(0)
cols.append(0)
cols.append(0)
cols.append(int(cols[colid_forward]))
cols.append(int(cols[colid_reverse]))
cols.append(int(cols[colid_forward]) + int(cols[colid_reverse]))
if marker not in data:
data[marker] = []
data[marker].append(cols)
......@@ -58,10 +65,13 @@ def match_profile(column_names, data, profile, convert_to_raw, library,
marker):
(colid_name, colid_allele, colid_forward, colid_reverse, colid_total,
colid_forward_noise, colid_reverse_noise, colid_total_noise,
colid_forward_add, colid_reverse_add, colid_total_add) = get_column_ids(
colid_forward_add, colid_reverse_add, colid_total_add,
colid_forward_corrected, colid_reverse_corrected,
colid_total_corrected) = get_column_ids(
column_names, "name", "allele", "forward", "reverse", "total",
"forward_noise", "reverse_noise", "total_noise", "forward_add",
"reverse_add", "total_add")
"reverse_add", "total_add", "forward_corrected", "reverse_corrected",
"total_corrected")
# Enter profiles into P.
P1 = np.matrix(profile["forward"])
......@@ -106,10 +116,16 @@ def match_profile(column_names, data, profile, convert_to_raw, library,
line[colid_forward_noise] = forward_noise[0, i]
line[colid_reverse_noise] = reverse_noise[0, i]
line[colid_total_noise] = forward_noise[0, i] + reverse_noise[0, i]
line[colid_forward_corrected] -= line[colid_forward_noise]
line[colid_reverse_corrected] -= line[colid_reverse_noise]
line[colid_total_corrected] -= line[colid_total_noise]
if i < profile["n"]:
line[colid_forward_add] = forward_add[0, i]
line[colid_reverse_add] = reverse_add[0, i]
line[colid_total_add] = forward_add[0, i] + reverse_add[0, i]
line[colid_forward_corrected] += line[colid_forward_add]
line[colid_reverse_corrected] += line[colid_reverse_add]
line[colid_total_corrected] += line[colid_total_add]
# Add sequences that are in the profile but not in the sample.
for i in range(profile["m"]):
......@@ -128,10 +144,16 @@ def match_profile(column_names, data, profile, convert_to_raw, library,
line[colid_forward_noise] = forward_noise[0, i]
line[colid_reverse_noise] = reverse_noise[0, i]
line[colid_total_noise] = forward_noise[0, i] + reverse_noise[0, i]
line[colid_forward_corrected] = -line[colid_forward_noise]
line[colid_reverse_corrected] = -line[colid_reverse_noise]
line[colid_total_corrected] = -line[colid_total_noise]
if i < profile["n"]:
line[colid_forward_add] = forward_add[0, i]
line[colid_reverse_add] = reverse_add[0, i]
line[colid_total_add] = forward_add[0, i] + reverse_add[0, i]
line[colid_forward_corrected] += line[colid_forward_add]
line[colid_reverse_corrected] += line[colid_reverse_add]
line[colid_total_corrected] += line[colid_total_add]
else:
line[colid_forward_add] = 0
line[colid_reverse_add] = 0
......
......@@ -505,7 +505,8 @@ def add_arguments(parser):
filtergroup.add_argument('-n', '--min-abs', metavar="N", type=pos_int_arg,
default=_DEF_THRESHOLD_ABS,
help="minimum amount of background to consider, as an absolute "
"number of reads (default: %(default)s)")
"number of reads for at least one orientation (default: "
"%(default)s)")
filtergroup.add_argument('-s', '--min-samples', metavar="N",
type=pos_int_arg, default=_DEF_MIN_SAMPLES,
help="require this minimum number of samples for each true allele "
......
......@@ -131,7 +131,7 @@ def compute_ratios(samples_in, outfile, allelefile, annotation_column, min_pct,
for sequence in data[marker, allele]:
for i in range(len(data[marker, allele][sequence]["tag"])):
outfile.write("\t".join([
data[marker, allele][sequence]["tag"][0], marker, allele,
data[marker, allele][sequence]["tag"][i], marker, allele,
sequence] + [
str(x) if abs(x) > 0.0000000001 else "0" for x in (
data[marker, allele][sequence]["forward"][i],
......
......@@ -98,8 +98,23 @@ def set_data_formula_transform_value(spec, dataname, fieldname, value):
#set_data_formula_transform_value
def create_visualisation(vistype, infile, outfile, vega, online, tidy,
min_abs, min_pct, bar_width, padding, marker, width):
def set_axis_scale(spec, scalename, value):
success = False
for marks in spec["marks"]:
if "scales" not in marks:
continue
for scale in marks["scales"]:
if scale["name"] != scalename:
continue
scale["type"] = value;
success = True
return success
#set_axis_scale
def create_visualisation(vistype, infile, outfile, vega, online, tidy, min_abs,
min_pct, bar_width, padding, marker, width,
log_scale):
# Get graph spec.
spec = json.load(resource_stream(
"fdstools", "vis/%svis/%svis.json" % (vistype, vistype)))
......@@ -125,6 +140,14 @@ def create_visualisation(vistype, infile, outfile, vega, online, tidy,
elif vistype == "profile":
set_data_formula_transform_value(
spec, "table", "filter_threshold", min_pct)
set_data_formula_transform_value(
spec, "table", "low", "0.001" if log_scale else "0")
if not log_scale:
set_axis_scale(spec, "x", "linear")
elif vistype == "sample":
set_axis_scale(spec, "x", "sqrt")
else:
set_axis_scale(spec, "x", "log")
# Stringify spec.
if tidy:
......@@ -215,6 +238,9 @@ def add_arguments(parser):
help="[sample, profile, bgraw] only show graphs for the markers that "
"match the given regular expression; the default value "
"'%(default)s' matches any marker name")
visgroup.add_argument('-L', '--log-scale', action="store_true",
help="[sample, profile, bgraw] use logarithmic scale (for sample: "
"square root scale) instead of linear scale")
visgroup.add_argument('-b', '--bar-width', metavar="N", type=pos_int_arg,
default=_DEF_BAR_WIDTH,
help="[sample, profile, bgraw] width of the bars in pixels (default: "
......@@ -251,7 +277,8 @@ def run(args):
create_visualisation(args.type, args.infile, args.outfile, args.vega,
args.online, args.tidy, args.min_abs, args.min_pct,
args.bar_width, args.padding, args.marker, args.width)
args.bar_width, args.padding, args.marker, args.width,
args.log_scale)
#run
......
......@@ -32,8 +32,7 @@
"expr": "0.5"
},
{
"type":
"formula",
"type": "formula",
"field": "maxnoise",
"expr": "max(datum.fnoise, datum.rnoise, datum.tnoise)"
},
......@@ -90,20 +89,20 @@
"type": "filter",
"test": "datum.b.name < datum.a.name"
},
{
"type": "aggregate",
"groupby": ["a.name"],
"summarize": [{"field": "b.name", "ops": ["distinct"], "as": ["cumulpadding"]}]
},
{
"type": "formula",
"field": "name",
"expr": "datum['a.name']"
"expr": "datum.a.name"
},
{
"type": "aggregate",
"groupby": ["name"],
"summarize": [{"field": "b.name", "ops": ["distinct"], "as": ["cumulpadding"]}]
}
]
},
{
"name": "subgraphoffsets",
"name": "workaround for https://github.com/vega/vega/issues/341",
"source": "barcounts",
"transform": [
{
......@@ -119,15 +118,21 @@
"field": "namesequence",
"expr": "datum.b.name + datum.b.sequence"
},
{
"type": "aggregate",
"groupby": ["a.name"],
"summarize": [{"field": "namesequence", "ops": ["distinct"], "as": ["cumulcount"]}]
},
{
"type": "formula",
"field": "name",
"expr": "datum['a.name']"
"expr": "datum.a.name"
}
]
},
{
"name": "subgraphoffsets",
"source": "workaround for https://github.com/vega/vega/issues/341",
"transform": [
{
"type": "aggregate",
"groupby": ["name"],
"summarize": [{"field": "namesequence", "ops": ["distinct"], "as": ["cumulcount"]}]
}
]
},
......@@ -248,7 +253,6 @@
{
"type": "x",
"scale": "x",
"format": "g",
"grid": true,
"layer": "back",
"title": "Noise ratio (%)",
......
......@@ -10,20 +10,34 @@
<style>
* {
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
font-size: 10pt;
}
body {
margin: 0px
margin: 0px;
}
div.options {
position: absolute;
margin: 5px;
background-color: rgba(128, 128, 255, 0.5);
padding: 5px;
background-color: rgba(255, 255, 255, 0.8);
z-index: 10;
}
#optionsheader{
cursor: pointer;
table.optiongroup {
padding: 10px 0px 0px 0px;
margin: 0px;
border-spacing: 0px;
border: none;
}
table.optiongroup td {
padding-right: 10px;
}
#optionsheader:hover{
table.optiongroup th {
text-align: left;
font-weight: bold;
padding-top: 5px;
}
#optionsheader {
cursor: pointer;
font-variant: small-caps;
border-bottom: 1px dashed black;
}
div#vis {
......@@ -41,19 +55,65 @@
<div class="options">
<strong id="optionsheader">Options</strong><br>
<div id="options">
<span id="fileselectspan" style="display: none">
Open raw background noise data file (or drag a file onto this page): <input id="fileselect" type="file"><br>
</span>
Display options: graph width <input type="text" value="600" id="graphwidth" size="3">px;
sequence spacing <input type="text" value="15" id="barwidth" size="2">px;
subgraph spacing <input type="text" value="70" id="subgraphoffset" size="3">px<br>
Filtering: require at least <input type="text" value="15" id="minN" size="3"> reads and at least <input type="text" value="0.5" id="minP" size="3">% of highest allele per marker<br>
Filtering: marker <input type="text" id="markerFilter" size="10" title="Supports regular expression syntax: e.g., use '.*' to match anything."><br>
Axis scale: <input type="radio" name="scale" value="linear" id="scaleLinear" checked> Linear
<input type="radio" name="scale" value="log" id="scaleLog"> Logarithmic<br>
Render as: <input type="radio" name="renderer" value="canvas" id="renderCanvas"> Canvas
<input type="radio" name="renderer" value="svg" id="renderSVG" checked> SVG
<br>
<table class="optiongroup" id="fileselectgroup" style="display: none">
<tr>
<th>Input file</th>
</tr>
<tr>
<td>Raw background noise data file:</td>
</tr>
<tr>
<td><input id="fileselect" type="file"></td>
</tr>
<tr>
<td>(or drag a file onto this page)</td>
</tr>
</table>
<table class="optiongroup">
<tr>
<th colspan="2">Filtering options</th>
</tr>
<tr>
<td>Require at least</td>
<td><input type="text" value="15" id="minN" size="3"> reads</td>
</tr>
<tr>
<td>Require at least</td>
<td><input type="text" value="0.5" id="minP" size="3">% of highest allele per marker</td>
</tr>
<tr>
<td>Marker name</td>
<td><input type="text" id="markerFilter" size="10" title="Supports regular expression syntax: e.g., use '.*' to match anything."></td>
</tr>
</table>
<table class="optiongroup">
<tr>
<th colspan="3">Display options</th>
</tr>
<tr>
<td>Graph width</td>
<td colspan="2"><input type="text" value="600" id="graphwidth" size="3"> px</td>
</tr>
<tr>
<td>Sequence spacing</td>
<td colspan="2"><input type="text" value="15" id="barwidth" size="3"> px</td>
</tr>
<tr>
<td>Subgraph spacing</td>
<td colspan="2"><input type="text" value="70" id="subgraphoffset" size="3"> px</td>
</tr>
<tr>
<td>Axis scale</td>
<td><input type="radio" name="scale" value="linear" id="scaleLinear" checked> Linear</td>
<td><input type="radio" name="scale" value="log" id="scaleLog"> Logarithmic
</td>
</tr>
<tr>
<td>Render as:</td>
<td><input type="radio" name="renderer" value="svg" id="renderSVG" checked> SVG</td>
<td><input type="radio" name="renderer" value="canvas" id="renderCanvas"> Canvas</td>
</tr>
</table>
<a id="saveLink" href="javascript:void(saveImage())" style="display: none">Save image</a>
</div>
</div>
......@@ -81,15 +141,24 @@
for(i in graph_spec["marks"])
if(graph_spec["marks"][i]["scales"])
for(j in graph_spec["marks"][i]["scales"])
if(graph_spec["marks"][i]["scales"][j]["name"] == "x"){
if(graph_spec["marks"][i]["scales"][j]["name"] == "x")
graph_spec["marks"][i]["scales"][j]["type"] = value;
graph_spec["marks"][i]["scales"][j]["format"] = (value == "log"? ".1r" : "g");
}
if(graph)
parse();
}
function getScale(){
if(!graph_spec)
return "linear";
for(i in graph_spec["marks"])
if(graph_spec["marks"][i]["scales"])
for(j in graph_spec["marks"][i]["scales"])
if(graph_spec["marks"][i]["scales"][j]["name"] == "x")
return graph_spec["marks"][i]["scales"][j]["type"];
return "linear";
}
function setDataFormulaTransformValue(dataname, fieldname, value){
if(!graph_spec)
return false;
......@@ -157,8 +226,8 @@
}
function onLoadSpec(has_data){
//Allow files to be dragged onto the page.
if(!has_data){
//Allow files to be dragged onto the page.
document.addEventListener('dragover', function(evt){
evt.stopPropagation();
evt.preventDefault();
......@@ -173,7 +242,7 @@
document.getElementById("fileselect").addEventListener('change', function(){
loadDataset(document.getElementById("fileselect").files);
}, false);
document.getElementById("fileselectspan").style.display = "inline";
document.getElementById("fileselectgroup").style.display = "table";
}
//Update graph when rendering mode or axis scale is changed.
......@@ -240,10 +309,14 @@
}, false);
//Sync graph_spec and display.
if(document.getElementById("scaleLinear").checked)
setScale(document.getElementById("scaleLinear").value);
else
setScale(document.getElementById("scaleLog").value);
if(getScale() == "linear"){
document.getElementById("scaleLinear").checked = true;
document.getElementById("scaleLog").checked = false;
}
else{
document.getElementById("scaleLinear").checked = false;
document.getElementById("scaleLog").checked = true;
}
document.getElementById("markerFilter").value = getDataFormulaTransformValue("table", "filter_marker").replace(/^(['"]?)(.*(?=\1$))\1$/, '$2');
document.getElementById("graphwidth").value = graph_spec["width"];
document.getElementById("barwidth").value = getDataFormulaTransformValue("yscale", "barwidth");
......
......@@ -10,20 +10,34 @@
<style>
* {
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
font-size: 10pt;
}
body {
margin: 0px
margin: 0px;
}
div.options {
position: absolute;
margin: 5px;
background-color: rgba(128, 128, 255, 0.5);
padding: 5px;
background-color: rgba(255, 255, 255, 0.8);
z-index: 10;
}
#optionsheader{
cursor: pointer;
table.optiongroup {
padding: 10px 0px 0px 0px;
margin: 0px;
border-spacing: 0px;
border: none;
}
table.optiongroup td {
padding-right: 10px;
}
#optionsheader:hover{
table.optiongroup th {
text-align: left;
font-weight: bold;
padding-top: 5px;
}
#optionsheader {
cursor: pointer;
font-variant: small-caps;
border-bottom: 1px dashed black;
}
div#vis {
......@@ -41,18 +55,61 @@
<div class="options">
<strong id="optionsheader">Options</strong><br>
<div id="options">
<span id="fileselectspan" style="display: none">
Open background noise profiles file (or drag a file onto this page): <input id="fileselect" type="file"><br>
</span>
Display options: graph width <input type="text" value="600" id="graphwidth" size="3">px;
bar width <input type="text" value="15" id="barwidth" size="2">px;
subgraph spacing <input type="text" value="70" id="subgraphoffset" size="3">px<br>
Filtering: minimum noise ratio <input type="text" value="0.5" id="minP" size="3">%; marker <input type="text" id="markerFilter" size="10" title="Supports regular expression syntax: e.g., use '.*' to match anything."><br>
Axis scale: <input type="radio" name="scale" value="linear" id="scaleLinear" checked> Linear
<input type="radio" name="scale" value="log" id="scaleLog"> Logarithmic<br>
Render as: <input type="radio" name="renderer" value="canvas" id="renderCanvas"> Canvas
<input type="radio" name="renderer" value="svg" id="renderSVG" checked> SVG
<br>
<table class="optiongroup" id="fileselectgroup" style="display: none">
<tr>
<th>Input file</th>
</tr>
<tr>
<td>Background noise profiles file:</td>
</tr>
<tr>
<td><input id="fileselect" type="file"></td>
</tr>
<tr>
<td>(or drag a file onto this page)</td>
</tr>
</table>
<table class="optiongroup">
<tr>
<th colspan="2">Filtering options</th>
</tr>
<tr>
<td>Minimum noise ratio</td>
<td><input type="text" value="0.5" id="minP" size="3">%</td>
</tr>
<tr>
<td>Marker name</td>
<td><input type="text" id="markerFilter" size="10" title="Supports regular expression syntax: e.g., use '.*' to match anything."></td>
</tr>
</table>
<table class="optiongroup">
<tr>
<th colspan="3">Display options</th>
</tr>
<tr>
<td>Graph width</td>
<td colspan="2"><input type="text" value="600" id="graphwidth" size="3"> px</td>
</tr>
<tr>
<td>Bar width</td>
<td colspan="2"><input type="text" value="15" id="barwidth" size="3"> px</td>
</tr>
<tr>
<td>Subgraph spacing</td>
<td colspan="2"><input type="text" value="70" id="subgraphoffset" size="3"> px</td>
</tr>
<tr>
<td>Axis scale</td>
<td><input type="radio" name="scale" value="linear" id="scaleLinear" checked> Linear</td>
<td><input type="radio" name="scale" value="log" id="scaleLog"> Logarithmic
</td>
</tr>
<tr>
<td>Render as:</td>
<td><input type="radio" name="renderer" value="svg" id="renderSVG" checked> SVG</td>
<td><input type="radio" name="renderer" value="canvas" id="renderCanvas"> Canvas</td>
</tr>
</table>
<a id="saveLink" href="javascript:void(saveImage())" style="display: none">Save image</a>
</div>
</div>
......@@ -80,16 +137,25 @@
for(i in graph_spec["marks"])
if(graph_spec["marks"][i]["scales"])
for(j in graph_spec["marks"][i]["scales"])
if(graph_spec["marks"][i]["scales"][j]["name"] == "x"){
graph_spec["marks"][i]["scales"][j]["format"] = (value == "log"? ".1r" : "g");
if(graph_spec["marks"][i]["scales"][j]["name"] == "x")
graph_spec["marks"][i]["scales"][j]["type"] = value;
}
setDataFormulaTransformValue("table", "low", value == "log"? "0.001" : "0");
if(graph)
parse();
}
function getScale(){
if(!graph_spec)
return "linear";
for(i in graph_spec["marks"])
if(graph_spec["marks"][i]["scales"])
for(j in graph_spec["marks"][i]["scales"])
if(graph_spec["marks"][i]["scales"][j]["name"] == "x")
return graph_spec["marks"][i]["scales"][j]["type"];
return "linear";
}
function setDataFormulaTransformValue(dataname, fieldname, value){
if(!graph_spec)
return false;
......@@ -173,7 +239,7 @@
document.getElementById("fileselect").addEventListener('change', function(){
loadDataset(document.getElementById("fileselect").files);
}, false);
document.getElementById("fileselectspan").style.display = "inline";
document.getElementById("fileselectgroup").style.display = "table";
}
//Update graph when rendering mode or axis scale is changed.
......@@ -233,10 +299,14 @@
}, false);
//Sync graph_spec and display.
if(document.getElementById("scaleLinear").checked)
setScale(document.getElementById("scaleLinear").value);
else
setScale(document.getElementById("scaleLog").value);
if(getScale() == "linear"){
document.getElementById("scaleLinear").checked = true;
document.getElementById("scaleLog").checked = false;
}
else{
document.getElementById("scaleLinear").checked = false;
document.getElementById("scaleLog").checked = true;
}
document.getElementById("markerFilter").value = getDataFormulaTransformValue("table", "filter_marker").replace(/^(['"]?)(.*(?=\1$))\1$/, '$2');
document.getElementById("graphwidth").value = graph_spec["width"];
document.getElementById("barwidth").value = getDataFormulaTransformValue("yscale", "barwidth");
......
......@@ -3,7 +3,7 @@
"height": 10,
"data": [
{
"name": "raw",
"name": "table",
"values": "VALUES HERE",
"format": {
"type": "tsv",
......@@ -11,12 +11,12 @@
"fmean": "number",
"rmean": "number"
}
}
},
{
"name": "table",
"source": "raw",
},
"transform": [
{
"type": "filter",
"test": "datum.allele != datum.sequence"
},
{
"type": "formula",
"field": "filter_threshold",
......@@ -24,7 +24,7 @@
},
{
"type": "filter",
"test": "datum.fmean+datum.rmean < 200 && max(datum.fmean, datum.rmean) >= datum.filter_threshold"
"test": "max(datum.fmean, datum.rmean) >= datum.filter_threshold"
},
{
"type": "formula",
......@@ -94,15 +94,15 @@
"type": "filter",
"test": "datum.b.name < datum.a.name"
},
{
"type": "aggregate",
"groupby": ["a.name"],
"summarize": [{"field": "*", "ops": ["count"], "as": ["cumulpadding"]}]
},
{
"type": "formula",
"field": "name",
"expr": "datum['a.name']"
"expr": "datum.a.name"
},
{
"type": "aggregate",
"groupby": ["name"],
"summarize": [{"field": "*", "ops": ["count"], "as": ["cumulpadding"]}]
}
]
},
......@@ -118,15 +118,15 @@
"type": "filter",