Skip to content

Commit

Permalink
Feature/add plots to result (#255)
Browse files Browse the repository at this point in the history
* add mock plot data to result file

* solution 1: using binary

* add histogram

* Co-authored-by: Megan Riel-Mehan <meganrm@gmail.com>

* remove unused flag and call

* wip: comment out saveResult in pack_one_seed to avoid packing twice

* save each seed

* merge add_histogram into histogram()

* remove unused code

* set save_png to true for pairwise distances

* avoid early return in saving histogram
  • Loading branch information
rugeli authored Jun 11, 2024
1 parent a506867 commit acea1ee
Showing 5 changed files with 103 additions and 35 deletions.
85 changes: 53 additions & 32 deletions cellpack/autopack/Analysis.py
Original file line number Diff line number Diff line change
@@ -54,6 +54,7 @@ def __init__(
self.figures_path = self.output_path / "figures"
self.figures_path.mkdir(parents=True, exist_ok=True)
self.seed_to_results = {}
self.helper = autopack.helper

@staticmethod
def cartesian_to_sph(xyz, center=None):
@@ -153,6 +154,7 @@ def plot_distance_distribution(self, all_ingredient_distances):
title_str=ingr_key,
x_label="pairwise distance",
y_label="count",
save_png=True,
)

def get_obj_dict(self, packing_results_path):
@@ -586,33 +588,53 @@ def run_analysis_workflow(
**analysis_config["create_report"],
)

def histogram(self, distances, filename, title_str="", x_label="", y_label=""):
plt.clf()
# calculate histogram
nbins = int(numpy.sqrt(len(distances)))
if nbins < 2:
return
y, bin_edges = numpy.histogram(distances, bins=nbins)
bincenters = 0.5 * (bin_edges[1:] + bin_edges[:-1])

# calculate standard error for values in each bin
bin_inds = numpy.digitize(distances, bin_edges)
x_err_vals = numpy.zeros(y.shape)
for bc in range(nbins):
dist_vals = distances[bin_inds == (bc + 1)]
if len(dist_vals) > 1:
x_err_vals[bc] = numpy.std(dist_vals)
else:
x_err_vals[bc] = 0
y_err_vals = numpy.sqrt(y * (1 - y / numpy.sum(y)))
# set bin width
dbin = 0.9 * (bincenters[1] - bincenters[0])
plt.bar(bincenters, y, width=dbin, color="r", xerr=x_err_vals, yerr=y_err_vals)
plt.title(title_str)
plt.xlabel(x_label)
plt.ylabel(y_label)
plt.savefig(filename)
plt.close()
def histogram(
self,
distances,
filename,
title_str="",
x_label="",
y_label="",
add_to_result=True,
save_png=False,
):
if add_to_result:
# add histogrm to result file and display on the web page
self.helper.plot_data.add_histogram(
title=f"{title_str}: {x_label}",
xaxis_title=x_label,
traces={y_label: numpy.array(distances)},
)
if save_png:
# use matplotlib to create histogram and save as png
plt.clf()
# calculate histogram
nbins = int(numpy.sqrt(len(distances)))
if nbins < 2:
return
y, bin_edges = numpy.histogram(distances, bins=nbins)
bincenters = 0.5 * (bin_edges[1:] + bin_edges[:-1])

# calculate standard error for values in each bin
bin_inds = numpy.digitize(distances, bin_edges)
x_err_vals = numpy.zeros(y.shape)
for bc in range(nbins):
dist_vals = distances[bin_inds == (bc + 1)]
if len(dist_vals) > 1:
x_err_vals[bc] = numpy.std(dist_vals)
else:
x_err_vals[bc] = 0
y_err_vals = numpy.sqrt(y * (1 - y / numpy.sum(y)))
# set bin width
dbin = 0.9 * (bincenters[1] - bincenters[0])
plt.bar(
bincenters, y, width=dbin, color="r", xerr=x_err_vals, yerr=y_err_vals
)
plt.title(title_str)
plt.xlabel(x_label)
plt.ylabel(y_label)
plt.savefig(filename)
plt.close()

def plot(self, rdf, radii, file_name):
plt.clf()
@@ -979,7 +1001,6 @@ def pack_one_seed(
seed = int(seed_list[seed_index])
seed_basename = self.env.add_seed_number_to_base_name(seed)
self.env.reset()
self.env.saveResult = True
numpy.random.seed(seed)
self.build_grid()
two_d = self.env.is_two_d()
@@ -1123,7 +1144,6 @@ def pack_one_seed(
)
grid_image_writer = gradient.create_voxelization(grid_image_writer)
grid_image_writer.export_image()

return (
center_distance_dict,
pairwise_distance_dict,
@@ -1291,9 +1311,6 @@ def doloop(
self.writeJSON(ingredient_occurences_file, ingredient_occurence_dict)
self.writeJSON(ingredient_key_file, ingredient_key_dict)

if number_of_packings > 1:
Writer().save_as_simularium(self.env, self.seed_to_results)

all_ingredient_positions = self.combine_results_from_seeds(
ingredient_position_dict
)
@@ -1386,3 +1403,7 @@ def doloop(
x_label="angles Z",
y_label="count",
)
if number_of_packings > 1:
for seed, result in self.seed_to_results.items():
Writer().save_as_simularium(self.env, {seed: result})
Writer().save_as_simularium(self.env, self.seed_to_results)
7 changes: 5 additions & 2 deletions cellpack/autopack/Environment.py
Original file line number Diff line number Diff line change
@@ -143,7 +143,11 @@ def __init__(self, config=None, recipe=None):
self.name = name
self.version = recipe.get("version", "default")
# saving/pickle option
self.saveResult = "out" in config
self.saveResult = (
"out" in config
and not config["save_analyze_result"]
and not config["number_of_packings"] > 1
)
self.out_folder = create_output_dir(config["out"], name, config["place_method"])
self.base_name = f"{self.name}_{config['name']}_{self.version}"
self.grid_file_out = (
@@ -2174,7 +2178,6 @@ def pack_grid(
pbar.close()
self.log.info("time to fill %d", t2 - t1)
all_objects = self.prep_molecules_for_save(distances, free_points, nbFreePoints)

if self.saveResult:
self.save_result(
free_points,
36 changes: 36 additions & 0 deletions cellpack/autopack/upy/simularium/plots.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import numpy as np
from simulariumio import ScatterPlotData, HistogramPlotData


class PlotData:
def __init__(self):
self.plot_list = [] # list of tuples

def _add_plot(self, plot):
self.plot_list.append(plot)

def add_scatter(self, title, xaxis_title, yaxis_title, xtrace, ytraces):
self._add_plot(
(
"scatter",
ScatterPlotData(
title=title,
xaxis_title=xaxis_title,
yaxis_title=yaxis_title,
xtrace=np.array(xtrace),
ytraces={key: np.array(value) for key, value in ytraces.items()},
),
)
)

def add_histogram(self, title, xaxis_title, traces):
self._add_plot(
(
"histogram",
HistogramPlotData(
title=title,
xaxis_title=xaxis_title,
traces={key: np.array(value) for key, value in traces.items()},
),
)
)
8 changes: 7 additions & 1 deletion cellpack/autopack/upy/simularium/simularium_helper.py
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@
from simulariumio.constants import DISPLAY_TYPE, VIZ_TYPE

from cellpack.autopack.upy import hostHelper
from cellpack.autopack.upy.simularium.plots import PlotData
from cellpack.autopack.DBRecipeHandler import DBUploader, DBMaintenance
from cellpack.autopack.interface_objects.database_ids import DATABASE_IDS
import collada
@@ -112,6 +113,7 @@ def __init__(self, master=None, vi=None):
self.nogui = True
self.hext = "dae"
self.max_fiber_length = 0
self.plot_data = PlotData()

@staticmethod
def format_rgb_color(color):
@@ -1370,7 +1372,11 @@ def writeToFile(self, file_name, bb, recipe_name, version):
time_units=UnitData("ns"), # nanoseconds
spatial_units=UnitData("nm"), # nanometers
)
TrajectoryConverter(converted_data).save(file_name, False)
converter = TrajectoryConverter(converted_data)
plot_list = self.plot_data.plot_list
for type, plot in plot_list:
converter.add_plot(plot, type)
converter.save(file_name, False)
return file_name

def raycast(self, **kw):
2 changes: 2 additions & 0 deletions cellpack/autopack/writers/__init__.py
Original file line number Diff line number Diff line change
@@ -188,6 +188,8 @@ def save_as_simularium(self, env, seed_to_results_map):
is_aggregate = len(seed_to_results_map) > 1
if is_aggregate:
result_file_name = f"{env.result_file.split('_seed')[0]}_all"
else:
result_file_name = f"{env.result_file.split('_seed')[0]}_seed_{list(seed_to_results_map.keys())[0]}"
file_name = env.helper.writeToFile(
result_file_name, env.boundingBox, env.name, env.version
)

0 comments on commit acea1ee

Please sign in to comment.