Unverified Commit fb0f2889 authored by Randy Heiland's avatar Randy Heiland Committed by GitHub
Browse files

Delete substrates-2.py

parent 2843490a
# substrates Tab
import os, math
from pathlib import Path
from ipywidgets import Layout, Label, Text, Checkbox, Button, BoundedIntText, HBox, VBox, Box, \
FloatText, Dropdown, interactive
import matplotlib.pyplot as plt
from matplotlib.colors import BoundaryNorm
from matplotlib.ticker import MaxNLocator
from matplotlib.collections import LineCollection
from matplotlib.patches import Circle, Ellipse, Rectangle
from matplotlib.collections import PatchCollection
import matplotlib.colors as mplc
from collections import deque
import numpy as np
import scipy.io
import xml.etree.ElementTree as ET # https://docs.python.org/2/library/xml.etree.elementtree.html
import glob
import platform
import zipfile
from debug import debug_view
import warnings
hublib_flag = True
if platform.system() != 'Windows':
try:
# print("Trying to import hublib.ui")
from hublib.ui import Download
except:
hublib_flag = False
else:
hublib_flag = False
#warnings.warn(message, mplDeprecation, stacklevel=1)
warnings.filterwarnings("ignore")
class SubstrateTab(object):
def __init__(self):
self.output_dir = '.'
# self.output_dir = 'tmpdir'
self.figsize_width_substrate = 15.0 # allow extra for colormap
self.figsize_height_substrate = 12.5
self.figsize_width_svg = 12.0
self.figsize_height_svg = 12.0
# self.fig = plt.figure(figsize=(7.2,6)) # this strange figsize results in a ~square contour plot
self.first_time = True
self.modulo = 1
self.use_defaults = True
self.svg_delta_t = 1
self.substrate_delta_t = 1
self.svg_frame = 1
self.substrate_frame = 1
self.customized_output_freq = False
self.therapy_activation_time = 1000000
self.max_svg_frame_pre_therapy = 1000000
self.max_substrate_frame_pre_therapy = 1000000
self.svg_xmin = 0
# Probably don't want to hardwire these if we allow changing the domain size
# self.svg_xrange = 2000
# self.xmin = -1000.
# self.xmax = 1000.
# self.ymin = -1000.
# self.ymax = 1000.
# self.x_range = 2000.
# self.y_range = 2000.
self.show_nucleus = False
self.show_edge = True
# initial value
self.field_index = 4
# self.field_index = self.mcds_field.value + 4
self.skip_cb = False
# define dummy size of mesh (set in the tool's primary module)
self.numx = 0
self.numy = 0
self.title_str = ''
tab_height = '600px'
tab_height = '500px'
constWidth = '180px'
constWidth2 = '150px'
tab_layout = Layout(width='900px', # border='2px solid black',
height=tab_height, ) #overflow_y='scroll')
max_frames = 1
# self.mcds_plot = interactive(self.plot_substrate, frame=(0, max_frames), continuous_update=False)
# self.i_plot = interactive(self.plot_plots, frame=(0, max_frames), continuous_update=False)
self.i_plot = interactive(self.plot_substrate, frame=(0, max_frames), continuous_update=False)
# "plot_size" controls the size of the tab height, not the plot (rf. figsize for that)
# NOTE: the Substrates Plot tab has an extra row of widgets at the top of it (cf. Cell Plots tab)
svg_plot_size = '700px'
svg_plot_size = '600px'
svg_plot_size = '700px'
svg_plot_size = '900px'
self.i_plot.layout.width = svg_plot_size
self.i_plot.layout.height = svg_plot_size
self.fontsize = 20
# description='# cell frames',
self.max_frames = BoundedIntText(
min=0, max=99999, value=max_frames,
description='# frames',
layout=Layout(width='160px'),
)
self.max_frames.observe(self.update_max_frames)
# self.field_min_max = {'dummy': [0., 1., False]}
# NOTE: manually setting these for now (vs. parsing them out of data/initial.xml)
self.field_min_max = {'director signal':[0.,1.,False], 'cargo signal':[0.,1.,False] }
# hacky I know, but make a dict that's got (key,value) reversed from the dict in the Dropdown below
# self.field_dict = {0:'dummy'}
self.field_dict = {0:'director signal', 1:'cargo signal'}
self.mcds_field = Dropdown(
options={'director signal': 0, 'cargo signal':1},
value=0,
# description='Field',
layout=Layout(width=constWidth)
)
# print("substrate __init__: self.mcds_field.value=",self.mcds_field.value)
# self.mcds_field.observe(self.mcds_field_cb)
self.mcds_field.observe(self.mcds_field_changed_cb)
self.field_cmap = Dropdown(
options=['viridis', 'jet', 'YlOrRd'],
value='YlOrRd',
# description='Field',
layout=Layout(width=constWidth)
)
# self.field_cmap.observe(self.plot_substrate)
self.field_cmap.observe(self.mcds_field_cb)
self.cmap_fixed_toggle = Checkbox(
description='Fix',
disabled=False,
# layout=Layout(width=constWidth2),
)
self.cmap_fixed_toggle.observe(self.mcds_field_cb)
# def cmap_fixed_toggle_cb(b):
# # self.update()
# # self.field_min_max = {'oxygen': [0., 30.,True], 'glucose': [0., 1.,False]}
# field_name = self.field_dict[self.mcds_field.value]
# if (self.cmap_fixed_toggle.value):
# self.field_min_max[field_name][0] = self.cmap_min.value
# self.field_min_max[field_name][1] = self.cmap_max.value
# self.field_min_max[field_name][2] = True
# else:
# # self.field_min_max[field_name][0] = self.cmap_min.value
# # self.field_min_max[field_name][1] = self.cmap_max.value
# self.field_min_max[field_name][2] = False
# self.i_plot.update()
# self.cmap_fixed_toggle.observe(cmap_fixed_toggle_cb)
# self.save_min_max= Button(
# description='Save', #style={'description_width': 'initial'},
# button_style='success', # 'success', 'info', 'warning', 'danger' or ''
# tooltip='Save min/max for this substrate',
# disabled=True,
# layout=Layout(width='90px')
# )
# def save_min_max_cb(b):
# # field_name = self.mcds_field.options[]
# # field_name = next(key for key, value in self.mcds_field.options.items() if value == self.mcds_field.value)
# field_name = self.field_dict[self.mcds_field.value]
# # print(field_name)
# # self.field_min_max = {'oxygen': [0., 30.], 'glucose': [0., 1.], 'H+ ions': [0., 1.], 'ECM': [0., 1.], 'NP1': [0., 1.], 'NP2': [0., 1.]}
# self.field_min_max[field_name][0] = self.cmap_min.value
# self.field_min_max[field_name][1] = self.cmap_max.value
# # print(self.field_min_max)
# self.save_min_max.on_click(save_min_max_cb)
self.cmap_min = FloatText(
description='Min',
value=0,
step = 0.1,
disabled=True,
layout=Layout(width=constWidth2),
)
self.cmap_min.observe(self.mcds_field_cb)
self.cmap_max = FloatText(
description='Max',
value=38,
step = 0.1,
disabled=True,
layout=Layout(width=constWidth2),
)
self.cmap_max.observe(self.mcds_field_cb)
def cmap_fixed_toggle_cb(b):
field_name = self.field_dict[self.mcds_field.value]
# print(self.cmap_fixed_toggle.value)
if (self.cmap_fixed_toggle.value): # toggle on fixed range
self.cmap_min.disabled = False
self.cmap_max.disabled = False
self.field_min_max[field_name][0] = self.cmap_min.value
self.field_min_max[field_name][1] = self.cmap_max.value
self.field_min_max[field_name][2] = True
# self.save_min_max.disabled = False
else: # toggle off fixed range
self.cmap_min.disabled = True
self.cmap_max.disabled = True
self.field_min_max[field_name][2] = False
# self.save_min_max.disabled = True
# self.mcds_field_cb()
self.i_plot.update()
self.cmap_fixed_toggle.observe(cmap_fixed_toggle_cb)
field_cmap_row2 = HBox([self.field_cmap, self.cmap_fixed_toggle])
# field_cmap_row3 = HBox([self.save_min_max, self.cmap_min, self.cmap_max])
items_auto = [
# self.save_min_max, #layout=Layout(flex='3 1 auto', width='auto'),
self.cmap_min,
self.cmap_max,
]
box_layout = Layout(display='flex',
flex_flow='row',
align_items='stretch',
width='80%')
field_cmap_row3 = Box(children=items_auto, layout=box_layout)
# self.debug_str = Text(
# value='debug info',
# description='Debug:',
# disabled=True,
# layout=Layout(width='600px'), #constWidth = '180px'
# )
#---------------------
self.cell_nucleus_toggle = Checkbox(
description='nuclei',
disabled=False,
value = self.show_nucleus,
# layout=Layout(width=constWidth2),
)
def cell_nucleus_toggle_cb(b):
# self.update()
if (self.cell_nucleus_toggle.value):
self.show_nucleus = True
else:
self.show_nucleus = False
self.i_plot.update()
self.cell_nucleus_toggle.observe(cell_nucleus_toggle_cb)
#----
self.cell_edges_toggle = Checkbox(
description='edges',
disabled=False,
value=self.show_edge,
# layout=Layout(width=constWidth2),
)
def cell_edges_toggle_cb(b):
# self.update()
if (self.cell_edges_toggle.value):
self.show_edge = True
else:
self.show_edge = False
self.i_plot.update()
self.cell_edges_toggle.observe(cell_edges_toggle_cb)
self.cells_toggle = Checkbox(
description='Cells',
disabled=False,
value=True,
# layout=Layout(width=constWidth2),
)
def cells_toggle_cb(b):
# self.update()
self.i_plot.update()
if (self.cells_toggle.value):
self.cell_edges_toggle.disabled = False
self.cell_nucleus_toggle.disabled = False
else:
self.cell_edges_toggle.disabled = True
self.cell_nucleus_toggle.disabled = True
self.cells_toggle.observe(cells_toggle_cb)
#---------------------
self.substrates_toggle = Checkbox(
description='Substrates',
disabled=False,
value=True,
# layout=Layout(width=constWidth2),
)
def substrates_toggle_cb(b):
if (self.substrates_toggle.value): # seems bass-ackwards
self.cmap_fixed_toggle.disabled = False
self.cmap_min.disabled = False
self.cmap_max.disabled = False
self.mcds_field.disabled = False
self.field_cmap.disabled = False
else:
self.cmap_fixed_toggle.disabled = True
self.cmap_min.disabled = True
self.cmap_max.disabled = True
self.mcds_field.disabled = True
self.field_cmap.disabled = True
self.substrates_toggle.observe(substrates_toggle_cb)
self.grid_toggle = Checkbox(
description='grid',
disabled=False,
value=True,
# layout=Layout(width=constWidth2),
)
def grid_toggle_cb(b):
# self.update()
self.i_plot.update()
self.grid_toggle.observe(grid_toggle_cb)
# field_cmap_row3 = Box([self.save_min_max, self.cmap_min, self.cmap_max])
# mcds_tab = widgets.VBox([mcds_dir, mcds_plot, mcds_play], layout=tab_layout)
# mcds_params = VBox([self.mcds_field, field_cmap_row2, field_cmap_row3, self.max_frames]) # mcds_dir
# mcds_params = VBox([self.mcds_field, field_cmap_row2, field_cmap_row3,]) # mcds_dir
# self.tab = HBox([mcds_params, self.mcds_plot], layout=tab_layout)
help_label = Label('select slider: drag or left/right arrows')
# row1 = Box([help_label, Box( [self.max_frames, self.mcds_field, self.field_cmap], layout=Layout(border='0px solid black',
row1a = Box( [self.max_frames, self.mcds_field, self.field_cmap], layout=Layout(border='1px solid black',
width='50%',
height='',
align_items='stretch',
flex_direction='row',
display='flex'))
row1b = Box( [self.cells_toggle, self.cell_nucleus_toggle, self.cell_edges_toggle], layout=Layout(border='1px solid black',
width='50%',
height='',
align_items='stretch',
flex_direction='row',
display='flex'))
row1 = HBox( [row1a, Label('.....'), row1b])
row2a = Box([self.cmap_fixed_toggle, self.cmap_min, self.cmap_max], layout=Layout(border='1px solid black',
width='50%',
height='',
align_items='stretch',
flex_direction='row',
display='flex'))
# row2b = Box( [self.substrates_toggle, self.grid_toggle], layout=Layout(border='1px solid black',
row2b = Box( [self.substrates_toggle, ], layout=Layout(border='1px solid black',
width='50%',
height='',
align_items='stretch',
flex_direction='row',
display='flex'))
# row2 = HBox( [row2a, self.substrates_toggle, self.grid_toggle])
row2 = HBox( [row2a, Label('.....'), row2b])
if (hublib_flag):
self.download_button = Download('mcds.zip', style='warning', icon='cloud-download',
tooltip='Download data', cb=self.download_cb)
self.download_svg_button = Download('svg.zip', style='warning', icon='cloud-download',
tooltip='You need to allow pop-ups in your browser', cb=self.download_svg_cb)
download_row = HBox([self.download_button.w, self.download_svg_button.w, Label("Download all cell plots (browser must allow pop-ups).")])
# box_layout = Layout(border='0px solid')
controls_box = VBox([row1, row2]) # ,width='50%', layout=box_layout)
self.tab = VBox([controls_box, self.i_plot, download_row])
# self.tab = VBox([controls_box, self.debug_str, self.i_plot, download_row])
else:
# self.tab = VBox([row1, row2])
self.tab = VBox([row1, row2, self.i_plot])
#---------------------------------------------------
def update_dropdown_fields(self, data_dir):
# print('update_dropdown_fields called --------')
self.output_dir = data_dir
tree = None
try:
fname = os.path.join(self.output_dir, "initial.xml")
tree = ET.parse(fname)
xml_root = tree.getroot()
except:
print("Cannot open ",fname," to read info, e.g., names of substrate fields.")
return
xml_root = tree.getroot()
self.field_min_max = {}
self.field_dict = {}
dropdown_options = {}
uep = xml_root.find('.//variables')
comment_str = ""
field_idx = 0
if (uep):
for elm in uep.findall('variable'):
# print("-----> ",elm.attrib['name'])
field_name = elm.attrib['name']
self.field_min_max[field_name] = [0., 1., False]
self.field_dict[field_idx] = field_name
dropdown_options[field_name] = field_idx
self.field_min_max[field_name][0] = 0
self.field_min_max[field_name][1] = 1
# self.field_min_max[field_name][0] = field_idx #rwh: helps debug
# self.field_min_max[field_name][1] = field_idx+1
self.field_min_max[field_name][2] = False
field_idx += 1
# constWidth = '180px'
# print('options=',dropdown_options)
# print(self.field_min_max) # debug
self.mcds_field.value = 0
self.mcds_field.options = dropdown_options
# self.mcds_field = Dropdown(
# # options={'oxygen': 0, 'glucose': 1},
# options=dropdown_options,
# value=0,
# # description='Field',
# layout=Layout(width=constWidth)
# )
# def update_max_frames_expected(self, value): # called when beginning an interactive Run
# self.max_frames.value = value # assumes naming scheme: "snapshot%08d.svg"
# self.mcds_plot.children[0].max = self.max_frames.value
#------------------------------------------------------------------------------
def update_params(self, config_tab, user_params_tab):
# xml_root.find(".//x_min").text = str(self.xmin.value)
# xml_root.find(".//x_max").text = str(self.xmax.value)
# xml_root.find(".//dx").text = str(self.xdelta.value)
# xml_root.find(".//y_min").text = str(self.ymin.value)
# xml_root.find(".//y_max").text = str(self.ymax.value)
# xml_root.find(".//dy").text = str(self.ydelta.value)
# xml_root.find(".//z_min").text = str(self.zmin.value)
# xml_root.find(".//z_max").text = str(self.zmax.value)
# xml_root.find(".//dz").text = str(self.zdelta.value)
self.xmin = config_tab.xmin.value
self.xmax = config_tab.xmax.value
self.x_range = self.xmax - self.xmin
self.svg_xrange = self.xmax - self.xmin
self.ymin = config_tab.ymin.value
self.ymax = config_tab.ymax.value
self.y_range = self.ymax - self.ymin
self.numx = math.ceil( (self.xmax - self.xmin) / config_tab.xdelta.value)
self.numy = math.ceil( (self.ymax - self.ymin) / config_tab.ydelta.value)
if (self.x_range > self.y_range):
ratio = self.y_range / self.x_range
self.figsize_width_substrate = 15.0 # allow extra for colormap
self.figsize_height_substrate = 12.5 * ratio
self.figsize_width_svg = 12.0
self.figsize_height_svg = 12.0 * ratio
else: # x < y
ratio = self.x_range / self.y_range
self.figsize_width_substrate = 15.0 * ratio
self.figsize_height_substrate = 12.5
self.figsize_width_svg = 12.0 * ratio
self.figsize_height_svg = 12.0
self.svg_flag = config_tab.toggle_svg.value
self.substrates_flag = config_tab.toggle_mcds.value
# print("substrates: update_params(): svg_flag, toggle=",self.svg_flag,config_tab.toggle_svg.value)
# print("substrates: update_params(): self.substrates_flag = ",self.substrates_flag)
self.svg_delta_t = config_tab.svg_interval.value
self.substrate_delta_t = config_tab.mcds_interval.value
self.modulo = int(self.substrate_delta_t / self.svg_delta_t)
# print("substrates: update_params(): modulo=",self.modulo)
if self.customized_output_freq:
# self.therapy_activation_time = user_params_tab.therapy_activation_time.value # NOTE: edit for user param name
# print("substrates: update_params(): therapy_activation_time=",self.therapy_activation_time)
self.max_svg_frame_pre_therapy = int(self.therapy_activation_time/self.svg_delta_t)
self.max_substrate_frame_pre_therapy = int(self.therapy_activation_time/self.substrate_delta_t)
#------------------------------------------------------------------------------
# def update(self, rdir):
# Called from driver module (e.g., pc4*.py) (among other places?)
def update(self, rdir=''):
# with debug_view:
# print("substrates: update rdir=", rdir)
# print("substrates: update rdir=", rdir)
if rdir:
self.output_dir = rdir
# print('update(): self.output_dir = ', self.output_dir)
if self.first_time:
# if True:
self.first_time = False
full_xml_filename = Path(os.path.join(self.output_dir, 'config.xml'))
# print("substrates: update(), config.xml = ",full_xml_filename)
# self.num_svgs = len(glob.glob(os.path.join(self.output_dir, 'snap*.svg')))
# self.num_substrates = len(glob.glob(os.path.join(self.output_dir, 'output*.xml')))
# print("substrates: num_svgs,num_substrates =",self.num_svgs,self.num_substrates)
# argh - no! If no files created, then denom = -1
# self.modulo = int((self.num_svgs - 1) / (self.num_substrates - 1))
# print("substrates: update(): modulo=",self.modulo)
if full_xml_filename.is_file():
tree = ET.parse(full_xml_filename) # this file cannot be overwritten; part of tool distro
xml_root = tree.getroot()
self.svg_delta_t = int(xml_root.find(".//SVG//interval").text)
self.substrate_delta_t = int(xml_root.find(".//full_data//interval").text)
# print("substrates: svg,substrate delta_t values=",self.svg_delta_t,self.substrate_delta_t)
self.modulo = int(self.substrate_delta_t / self.svg_delta_t)
# print("substrates: update(): modulo=",self.modulo)
# all_files = sorted(glob.glob(os.path.join(self.output_dir, 'output*.xml'))) # if the substrates/MCDS
all_files = sorted(glob.glob(os.path.join(self.output_dir, 'snap*.svg'))) # if .svg
if len(all_files) > 0:
last_file = all_files[-1]
self.max_frames.value = int(last_file[-12:-4]) # assumes naming scheme: "snapshot%08d.svg"
else:
substrate_files = sorted(glob.glob(os.path.join(self.output_dir, 'output*.xml')))
if len(substrate_files) > 0:
last_file = substrate_files[-1]
self.max_frames.value = int(last_file[-12:-4])
def download_svg_cb(self):
file_str = os.path.join(self.output_dir, '*.svg')
# print('zip up all ',file_str)
with zipfile.ZipFile('svg.zip', 'w') as myzip:
for f in glob.glob(file_str):
myzip.write(f, os.path.basename(f)) # 2nd arg avoids full filename path in the archive
def download_cb(self):
file_xml = os.path.join(self.output_dir, '*.xml')
file_mat = os.path.join(self.output_dir, '*.mat')
# print('zip up all ',file_str)
with zipfile.ZipFile('mcds.zip', 'w') as myzip:
for f in glob.glob(file_xml):
myzip.write(f, os.path.basename(f)) # 2nd arg avoids full filename path in the archive
for f in glob.glob(file_mat):
myzip.write(f, os.path.basename(f))
def update_max_frames(self,_b):
self.i_plot.children[0].max = self.max_frames.value
def dummy_cb(self, b):
return
# called if user selected different substrate in dropdown
def mcds_field_changed_cb(self, b):
# print("mcds_field_changed_cb: self.mcds_field.value=",self.mcds_field.value)
if (self.mcds_field.value == None):
return
self.field_index = self.mcds_field.value + 4
field_name = self.field_dict[self.mcds_field.value]
# print('mcds_field_changed_cb: field_name='+ field_name)
# print(self.field_min_max[field_name])
# self.debug_str.value = 'mcds_field_changed_cb: '+ field_name + str(self.field_min_max[field_name])
# self.debug_str.value = 'cb1: '+ str(self.field_min_max)
# BEWARE of these triggering the mcds_field_cb() callback! Hence, the "skip_cb"
self.skip_cb = True
self.cmap_min.value = self.field_min_max[field_name][0]
self.cmap_max.value = self.field_min_max[field_name][1]
self.cmap_fixed_toggle.value = bool(self.field_min_max[field_name][2])
self.skip_cb = False
self.i_plot.update()
# called if user provided different min/max values for colormap, or a different colormap
def mcds_field_cb(self, b):
if self.skip_cb:
return
self.field_index = self.mcds_field.value + 4
field_name = self.field_dict[self.mcds_field.value]
# print('mcds_field_cb: field_name='+ field_name)
# print('mcds_field_cb: '+ field_name)
self.field_min_max[field_name][0] = self.cmap_min.value
self.field_min_max[field_name][1] = self.cmap_max.value
self.field_min_max[field_name][2] = self.cmap_fixed_toggle.value
# print(self.field_min_max[field_name])
# self.debug_str.value = 'mcds_field_cb: ' + field_name + str(self.field_min_max[field_name])
# self.debug_str.value = 'cb2: '+ str(self.field_min_max)
# print('--- cb2: '+ str(self.field_min_max)) #rwh2
# self.cmap_fixed_toggle.value = self.field_min_max[field_name][2]
# field_name = self.mcds_field.options[self.mcds_field.value]
# self.cmap_min.value = self.field_min_max[field_name][0] # oxygen, etc