Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
js/*

**/.DS_Store

!.gitignore
!python
python/sample_composites/composite_average.out
/python/sample_composites
/python/__pycache__
1 change: 0 additions & 1 deletion js/parse_composite.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,5 @@ let parse_multiple_composite = function(text, prefix) {
if (save_comp) {
composites[id] = {xmin: xmin, xmax: xmax, sense: sense, anti: anti}
};

return composites
}
13 changes: 8 additions & 5 deletions js/widgets/main_plot.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ $(function() {
d3.select("#main-plot-div").on("mousemove", function(e) {
$("#main-plot").main_plot("move_tooltip", e)
});
main_plot.on("mouseleave", function() {
// $("#main-plot").main_plot("hide_tooltip")
d3.select("#main-plot-div").on("mouseleave", function() {
$("#main-plot").main_plot("hide_tooltip")
});

this.enable_tooltip = true;
Expand Down Expand Up @@ -737,8 +737,10 @@ $(function() {
if (color_trace) {
this._elements.composite_group.selectAll(".composite .color-line-top")
.style("display", null);
this._elements.composite_group.selectAll(".composite .color-line-bottom")
.style("display", null);
if (!this.combined){
this._elements.composite_group.selectAll(".composite .color-line-bottom")
.style("display", null);
}
this._elements.composite_group.selectAll(".composite .white-line")
.style("display", "none");
this._elements.composite_group.selectAll(".composite .black-line")
Expand Down Expand Up @@ -820,12 +822,13 @@ $(function() {
.style("left", ev.clientX - (w - 80) / 1.4)
} else {
this._elements.tooltip.style("display", "none")
d3.selectAll("#composite-plot-tooltip").remove();
}
}
},

hide_tooltip: function() {
this._elements.tooltip.style("display", "none")
d3.selectAll("#composite-plot-tooltip").remove();
},

download_as_svg: function() {
Expand Down
87 changes: 87 additions & 0 deletions python/composite.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import csv
import xml.dom.minidom as dom
import argparse
import math
import parseComposite

# Objected to store bare-bones composite data, can be used with plot_composite function
class SimpleComposite:
def __init__(self, xmin=None, xmax=None, sense=[], anti=[], id=""):
self.xmin = xmin
self.xmax = xmax
self.sense = sense
self.anti = anti
self.id = id

# Object to store composite data with options for plotting, similar to a settings row
class Composite:
def __init__(self, scale=1, color=None, secondary_color=None, i=None, opacity=None, smoothing=None, bp_shift=None, hide_sense=False, hide_anti=False, baseline=0, name=None, sense=None, anti=None, xmin=None, xmax=None):
# Sets default values
self.scale = scale if scale is not None else 1
self.color = color if color is not None else "#0000FF"
self.secondary_color = secondary_color if secondary_color is not None else color
self.baseline = baseline if baseline is not None else 0
self.xmin = xmin if xmin is not None else 0
self.xmax = xmax if xmax is not None else 0
self.sense = sense if sense is not None else []
self.anti = anti if anti is not None else []
# Don't assign defaults to opacity, smoothing, and bp_shift so plot can apply plot defaults
self.opacity = opacity
self.smoothing = smoothing
self.bp_shift = bp_shift
self.hide_anti = hide_anti
self.hide_sense = hide_sense
self.individual_files = {}
self.files_loaded = len(self.individual_files)
self.name = name
# Adds a simple composite to the 'row'
def load_simple_composite(self,composite: SimpleComposite):
# If no files, initialize sense and anti arrays; otherwise, pad sense and anti arrays to new xdomain
self.xmin = min(composite.xmin, self.xmin)
self.xmax = max(composite.xmax, self.xmax)
if len(self.individual_files) == 0:
self.sense = [0] * (composite.xmax - composite.xmin + 1)
self.anti = [0] * (composite.xmax - composite.xmin + 1)
else:
xmin = min([int(self.individual_files[c].xmin) for c in self.individual_files])
xmax = max([int(self.individual_files[c].xmax) for c in self.individual_files])
prefix = [0] * (xmin - self.xmin)
suffix = [0] * (self.xmax - xmax)
self.sense = prefix + self.sense + suffix
self.anti = prefix + self.anti + suffix
# Update sense and anti arrays
j = composite.xmin - self.xmin
while j <= composite.xmax - composite.xmin:
idx = composite.xmin - self.xmin + j
self.sense[idx] += composite.sense[j]
self.anti[idx] += composite.anti[j]
j += 1
self.individual_files[composite.id] = composite
# Loads dictionary from parse_multiple_composites
def load_composite_dict(self,composite_dict: dict):
for key in composite_dict:
composite = composite_dict[key]
# If no files, initialize sense and anti arrays; otherwise, pad sense and anti arrays to new xdomain
self.xmin = min(composite.xmin, self.xmin)
self.xmax = max(composite.xmax, self.xmax)
if len(self.individual_files) == 0:
self.sense = [0] * (composite.xmax - composite.xmin + 1)
self.anti = [0] * (composite.xmax - composite.xmin + 1)
else:
xmin = min([c.xmin for c in self.individual_files])
xmax = max([c.xmax for c in self.individual_files])
prefix = [0] * (xmin - self.xmin)
suffix = [0] * (self.xmax - xmax)
self.sense = prefix + self.sense + suffix
self.anti = prefix + self.anti + suffix
# Update sense and anti arrays
j = composite.xmin - self.xmin
while j <= composite.xmax - composite.xmin:
idx = composite.xmin - self.xmin + j
self.sense[idx] += composite.sense[j]
self.anti[idx] += composite.anti[j]
j += 1
self.individual_files[composite.id] = composite

def __str__(self):
return str(self.individual_files)
123 changes: 123 additions & 0 deletions python/out.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
144 changes: 144 additions & 0 deletions python/parseComposite.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import csv
import xml.dom.minidom as dom
import argparse
import math
import composite
import os

# Returns a simple composite from a single file
def parse_simple(file):
fileArr = open(file, "r").read().split("\n")
xmin = None
xmax = None
sense = []
anti = []
xmin_curr = 0
xmax_curr = 0
offset = 0
for line in fileArr:
# Skip empty
if len(line.strip()) == 0 :
continue
# Separate fields
fields = line.split("\t")
if not fields[0].strip() or fields[0] == "NAME":
xmin_curr = int(float(fields[1]))
xmax_curr = int(float(fields[-1]))
# If the x domain starts at 0 shift it to the left
if xmin_curr == 0:
xmin_curr -= math.floor(xmax_curr / 2)
xmax_curr -= math.floor(xmax_curr / 2)
# If the x domain is not defined yet, define it
if xmin == None or xmax == None:
xmin = xmin_curr
xmax = xmax_curr
# Redefine min and max if necessary
xmax = max(xmax_curr, xmax)
xmin = min(xmin_curr, xmin)
sense = [0] * (xmax - xmin + 1)
anti = [0] * (xmax - xmin + 1)
# Add the values to sense and anti arrays
if "sense" in fields[0].lower():
i = 1
while i < len(fields):
sense[offset + i - 1] += float(fields[i])
i += 1
elif "anti" in fields[0].lower():
i = 1
while i < len(fields):
anti[offset + i - 1] += float(fields[i])
i += 1
# If the first field is not empty or "NAME" and does not contain "sense" or "anti" parse as combined or midpoint data
elif not (fields[0] == "" or fields[0] == "NAME"):
i = 1
while i < len(fields):
sense[offset + i - 1] += float(fields[i]) / 2
anti[offset + i - 1] += float(fields[i]) / 2
return composite.SimpleComposite(xmin, xmax, sense, anti, os.path.basename(file).split('_')[0])

# Returns list of prefixes from multi-composite file, mimics the plotter method
def get_prefixes_from_multiple_composites(file):
lines = open(file, "r").read().split("\n")
names_list = []
i = 0
while i < len(lines):
line = lines[i]
# Skip empty
if line.strip() == "":
i += 1
continue
# Get the first field
col0 = line.split("\t")[0]
if col0 == "" or col0[0] == "NAME":
# Get the names of the composites for lines immediately following the xdomain
i += 1
names_list.append(lines[i].split("\t")[0])
i += 1
# Take the first name and split it by "_"
split_name = names_list[0].split("_")
idx = None
# Iterate over each possible prefix-suffix split
for i in range(1, len(split_name) - 1):
prefix = "_".join(split_name[:i])
suffix = "_".join(split_name[i:])
n_prefix = sum(1 for n in names_list if n.startswith(prefix))
n_suffix = sum(1 for n in names_list if n.endswith(suffix))
if n_prefix * n_suffix == len(names_list):
if n_suffix == len(names_list):
idx = i if idx is None else idx
break
idx = i
suffix = "_".join(split_name[idx:])
# Get the prefixes by removing the suffix from the names
return [n[:-len(suffix)] for n in names_list if n.endswith(suffix)]

# Returns dictionary with composite from multi-composite file, mimics the plotter method
def parse_multiple_composite(file, prefix):
lines = open(file, "r").read().split("\n")
composites = {}
xmin = None
xmax = None
sense = []
anti = []
i = 0
id = 0
save_comp = False
while i < len(lines):
line = lines[i]
# Skip empty
if line.strip() == "":
i += 1
continue
# Get the first field
fields = line.split("\t")
col0 = fields[0]
if not col0.strip() or col0 == "NAME":
# If the x domain is defined, save the composite
if save_comp:
composites[id] = composite.SimpleComposite(xmin, xmax, sense, anti, id)
save_comp = False
# Get the nex x domain
fields = [field for field in fields if field.strip()]
xmin = int(float(fields[0]))
xmax = int(float(fields[-1]))
# If the x domain starts at 0 shift it to the left
if xmin == 0:
xmin -= math.floor(xmax / 2)
xmin -= math.floor(xmax / 2)
elif col0.startswith(prefix):
id = col0[len(prefix):].split("_")[0]
save_comp = True
# Add the values to sense and anti arrays
fields = [field for field in fields if field.strip()]
if "sense" in fields[0].lower():
sense = [float(val) for val in fields[1:]]
elif "anti" in fields[0].lower():
anti = [float(val) for val in fields[1:]]
else:
sense = [float(val) / 2 for val in fields[1:]]
anti = [float(val) / 2 for val in fields[1:]]
i += 1
# Save the last composite
if save_comp:
composites[id] = composite.SimpleComposite(xmin, xmax, sense, anti, id)
return composites
Loading