def notebook_interaction(self, display=True): from ipywidgets import Checkbox from traitlets import TraitError as TraitletError from IPython.display import display as ip_display try: container = super(ScalableFixedPattern, self).notebook_interaction(display=False) interpolate = Checkbox(description='interpolate', value=self.interpolate) def on_interpolate_change(change): self.interpolate = change['new'] interpolate.observe(on_interpolate_change, names='value') container.children = (container.children[0], interpolate) + \ container.children[1:] if not display: return container ip_display(container) except TraitletError: if display: print('This function is only avialable when running in a' ' notebook') else: raise
def notebook_interaction(self, display=True): """Creates interactive notebook widgets for all component parameters, if available. Requires `ipywidgets` to be installed. Parameters ---------- display : bool if True (default), attempts to display the widgets. Otherwise returns the formatted widget object. """ from ipywidgets import (Checkbox, VBox) from traitlets import TraitError as TraitletError from IPython.display import display as ip_display try: active = Checkbox(description='active', value=self.active) def on_active_change(change): self.active = change['new'] active.observe(on_active_change, names='value') container = VBox([active]) for parameter in self.parameters: container.children += parameter.notebook_interaction(False), if not display: return container ip_display(container) except TraitletError: if display: _logger.info('This function is only avialable when running in' ' a notebook') else: raise
def notebook_interaction(self, display=True): from ipywidgets import (Checkbox, FloatSlider, VBox) from traitlets import TraitError as TraitletError from IPython.display import display as ip_display try: active = Checkbox(description='active', value=self.active) def on_active_change(change): self.active = change['new'] active.observe(on_active_change, names='value') fine_structure = Checkbox(description='Fine structure', value=self.fine_structure_active) def on_fine_structure_active_change(change): self.fine_structure_active = change['new'] fine_structure.observe(on_fine_structure_active_change, names='value') fs_smoothing = FloatSlider(description='Fine structure smoothing', min=0, max=1, step=0.001, value=self.fine_structure_smoothing) def on_fs_smoothing_change(change): self.fine_structure_smoothing = change['new'] fs_smoothing.observe(on_fs_smoothing_change, names='value') container = VBox([active, fine_structure, fs_smoothing]) for parameter in [self.intensity, self.effective_angle, self.onset_energy]: container.children += parameter.notebook_interaction(False), if not display: return container ip_display(container) except TraitletError: if display: print('This function is only avialable when running in a' ' notebook') else: raise
class SVGTab(object): # myplot = None def __init__(self): tab_height = '520px' tab_height = '550px' tab_layout = Layout( width='900px', # border='2px solid black', height=tab_height) #, overflow_y='scroll') self.output_dir = '.' # self.output_dir = 'tmpdir' max_frames = 1 self.svg_plot = interactive(self.plot_svg, frame=(0, max_frames), continuous_update=False) svg_plot_size = '500px' self.svg_plot.layout.width = svg_plot_size self.svg_plot.layout.height = svg_plot_size self.use_defaults = True self.show_nucleus = 0 # 0->False, 1->True in Checkbox! self.show_edge = 1 # 0->False, 1->True in Checkbox! self.scale_radius = 1.0 self.axes_min = 0.0 self.axes_max = 2000 # hmm, this can change (TODO?) self.fig = plt.figure(figsize=(6, 6)) # self.tab = HBox([svg_plot], layout=tab_layout) self.max_frames = BoundedIntText( min=0, max=99999, value=max_frames, description='Max', # layout=Layout(flex='0 1 auto', width='auto'), #Layout(width='160px'), ) self.max_frames.observe(self.update_max_frames) self.show_nucleus_checkbox = Checkbox( description='nucleus', value=False, disabled=False, # layout=Layout(flex='1 1 auto', width='auto'), #Layout(width='160px'), ) self.show_nucleus_checkbox.observe(self.show_nucleus_cb) self.show_edge_checkbox = Checkbox( description='edge', value=True, disabled=False, # layout=Layout(flex='1 1 auto', width='auto'), #Layout(width='160px'), ) self.show_edge_checkbox.observe(self.show_edge_cb) # row1 = HBox([Label('(select slider: drag or left/right arrows)'), # self.max_frames, VBox([self.show_nucleus_checkbox, self.show_edge_checkbox])]) # self.max_frames, self.show_nucleus_checkbox], layout=Layout(width='500px')) # self.tab = VBox([row1,self.svg_plot], layout=tab_layout) self.help_label = Label('select slider: drag or left/right arrows', layout=Layout(flex='0 1 auto', width='auto')) # layout=Layout(flex='3 1 auto', width='auto')) items_auto = [ self.help_label, self.max_frames, self.show_nucleus_checkbox, self.show_edge_checkbox, ] #row1 = HBox([Label('(select slider: drag or left/right arrows)'), # max_frames, show_nucleus_checkbox, show_edge_checkbox], # layout=Layout(width='800px')) box_layout = Layout(display='flex', flex_flow='row', align_items='stretch', width='90%') # row1 = Box(children=items_auto, layout=box_layout) #row1 = Box(children=items_auto) row1 = Box([ self.help_label, Box([ self.max_frames, self.show_nucleus_checkbox, self.show_edge_checkbox ], layout=Layout(border='0px solid black', width='60%', height='', align_items='stretch', flex_direction='row', display='flex')) ]) # self.download_button = Download('svg.zip', style='warning', icon='cloud-download', tooltip='Download results', cb=self.download_cb) #self.download_button = Download('svg.zip', style='warning', icon='cloud-download', tooltip='Download results') # self.tab = VBox([row1, self.svg_plot], layout=tab_layout) # self.tab = VBox([row1, self.svg_plot, self.download_button.w], layout=tab_layout) self.tab = VBox([row1, self.svg_plot], layout=tab_layout) # self.output_dir_str = os.getenv('RESULTSDIR') + "/pc4nanobio/" def update_max_frames_expected( self, value): # called when beginning an interactive Run # with debug_view: # print("update_max_frames_expected: SVG UPDATE", rdir) self.max_frames.value = value # assumes naming scheme: "snapshot%08d.svg" self.svg_plot.children[0].max = self.max_frames.value # self.svg_plot.update() def update(self, rdir): # with debug_view: # print("svg.py: update(): rdir (->self.output_dir)=", rdir) self.output_dir = rdir if rdir == '': # self.max_frames.value = 0 tmpdir = os.path.abspath('tmpdir') # with debug_view: # print("svg.py: update(): tmpdir=", tmpdir) self.output_dir = tmpdir all_files = sorted(glob.glob(os.path.join(tmpdir, 'snapshot*.svg'))) # with debug_view: # print("svg.py: update(): len(all_files)=", len(all_files)) 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" self.svg_plot.update() return all_files = sorted(glob.glob(os.path.join(rdir, 'snapshot*.svg'))) # with debug_view: # print("svg.py: update(): rdir != blank; len(all_files)=", len(all_files)) 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" self.svg_plot.update() def download_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 show_nucleus_cb(self, b): global current_frame if (self.show_nucleus_checkbox.value): self.show_nucleus = 1 else: self.show_nucleus = 0 # self.plot_svg(self,current_frame) self.svg_plot.update() def show_edge_cb(self, b): if (self.show_edge_checkbox.value): self.show_edge = 1 else: self.show_edge = 0 self.svg_plot.update() def update_max_frames(self, _b): self.svg_plot.children[0].max = self.max_frames.value def plot_svg(self, frame): # global current_idx, axes_max global current_frame current_frame = frame fname = "snapshot%08d.svg" % frame # fullname = self.output_dir_str + fname # fullname = fname # do this for nanoHUB! (data appears in root dir?) full_fname = os.path.join(self.output_dir, fname) if not os.path.isfile(full_fname): # print("File does not exist: ", fname) # print("File does not exist: ", full_fname) #print("No: ", full_fname) print("Missing output file") # No: snapshot00000000.svg return xlist = deque() ylist = deque() rlist = deque() rgb_list = deque() # print('\n---- ' + fname + ':') # tree = ET.parse(fname) tree = ET.parse(full_fname) root = tree.getroot() # print('--- root.tag ---') # print(root.tag) # print('--- root.attrib ---') # print(root.attrib) # print('--- child.tag, child.attrib ---') numChildren = 0 for child in root: # print(child.tag, child.attrib) # print("keys=",child.attrib.keys()) if self.use_defaults and ('width' in child.attrib.keys()): self.axes_max = float(child.attrib['width']) # print("debug> found width --> axes_max =", axes_max) if child.text and "Current time" in child.text: svals = child.text.split() # title_str = "(" + str(current_idx) + ") Current time: " + svals[2] + "d, " + svals[4] + "h, " + svals[7] + "m" # title_str = "Current time: " + svals[2] + "d, " + svals[4] + "h, " + svals[7] + "m" title_str = svals[2] + "d, " + svals[4] + "h, " + svals[7] + "m" # print("width ",child.attrib['width']) # print('attrib=',child.attrib) # if (child.attrib['id'] == 'tissue'): if ('id' in child.attrib.keys()): # print('-------- found tissue!!') tissue_parent = child break # print('------ search tissue') cells_parent = None for child in tissue_parent: # print('attrib=',child.attrib) if (child.attrib['id'] == 'cells'): # print('-------- found cells, setting cells_parent') cells_parent = child break numChildren += 1 num_cells = 0 # print('------ search cells') for child in cells_parent: # print(child.tag, child.attrib) # print('attrib=',child.attrib) for circle in child: # two circles in each child: outer + nucleus # circle.attrib={'cx': '1085.59','cy': '1225.24','fill': 'rgb(159,159,96)','r': '6.67717','stroke': 'rgb(159,159,96)','stroke-width': '0.5'} # print(' --- cx,cy=',circle.attrib['cx'],circle.attrib['cy']) xval = float(circle.attrib['cx']) s = circle.attrib['fill'] # print("s=",s) # print("type(s)=",type(s)) if (s[0:3] == "rgb" ): # if an rgb string, e.g. "rgb(175,175,80)" rgb = list(map(int, s[4:-1].split(","))) rgb[:] = [x / 255. for x in rgb] else: # otherwise, must be a color name rgb_tuple = mplc.to_rgb(mplc.cnames[s]) # a tuple rgb = [x for x in rgb_tuple] # test for bogus x,y locations (rwh TODO: use max of domain?) too_large_val = 10000. if (np.fabs(xval) > too_large_val): print("bogus xval=", xval) break yval = float(circle.attrib['cy']) if (np.fabs(yval) > too_large_val): print("bogus xval=", xval) break rval = float(circle.attrib['r']) # if (rgb[0] > rgb[1]): # print(num_cells,rgb, rval) xlist.append(xval) ylist.append(yval) rlist.append(rval) rgb_list.append(rgb) # For .svg files with cells that *have* a nucleus, there will be a 2nd if (self.show_nucleus == 0): #if (not self.show_nucleus): break num_cells += 1 # if num_cells > 3: # for debugging # print(fname,': num_cells= ',num_cells," --- debug exit.") # sys.exit(1) # break # print(fname,': num_cells= ',num_cells) xvals = np.array(xlist) yvals = np.array(ylist) rvals = np.array(rlist) rgbs = np.array(rgb_list) # print("xvals[0:5]=",xvals[0:5]) # print("rvals[0:5]=",rvals[0:5]) # print("rvals.min, max=",rvals.min(),rvals.max()) # rwh - is this where I change size of render window?? (YES - yipeee!) # plt.figure(figsize=(6, 6)) # plt.cla() title_str += " (" + str(num_cells) + " agents)" # plt.title(title_str) # plt.xlim(axes_min,axes_max) # plt.ylim(axes_min,axes_max) # plt.scatter(xvals,yvals, s=rvals*scale_radius, c=rgbs) # plt.axes().set_aspect('equal', 'datalim') self.fig = plt.figure(figsize=(6, 6)) #rwh: move to __init__ # plt.figure(figsize=(7, 7)) # axx = plt.axes([0, 0.05, 0.9, 0.9]) # left, bottom, width, height # axx = fig.gca() # print('fig.dpi=',fig.dpi) # = 72 # im = ax.imshow(f.reshape(100,100), interpolation='nearest', cmap=cmap, extent=[0,20, 0,20]) # ax.xlim(axes_min,axes_max) # ax.ylim(axes_min,axes_max) # convert radii to radii in pixels # ax2 = fig.gca() ax2 = self.fig.gca() N = len(xvals) rr_pix = (ax2.transData.transform(np.vstack([rvals, rvals]).T) - ax2.transData.transform( np.vstack([np.zeros(N), np.zeros(N)]).T)) rpix, _ = rr_pix.T # markers_size = (144. * rpix / fig.dpi)**2 # = (2*rpix / fig.dpi * 72)**2 markers_size = (144. * rpix / self.fig.dpi)**2 # = (2*rpix / fig.dpi * 72)**2 # markers_size = (2*rpix / fig.dpi * 72)**2 markers_size = markers_size / 4000000. #print('markers_size.max()=',markers_size.max()) # ax.scatter(xvals,yvals, s=rvals*self.scale_radius, c=rgbs) # axx.scatter(xvals,yvals, s=markers_size, c=rgbs) #rwh - temp fix - Ah, error only occurs when "edges" is toggled on if (self.show_edge): plt.scatter(xvals, yvals, s=markers_size, c=rgbs, edgecolor='black', linewidth=0.5) else: plt.scatter(xvals, yvals, s=markers_size, c=rgbs) plt.xlim(self.axes_min, self.axes_max) plt.ylim(self.axes_min, self.axes_max) # ax.grid(False) # axx.set_title(title_str) plt.title(title_str)
def build_options(self): grid = GridspecLayout(4, 2) options_map = {} style = {'description_width': '60%', 'width': 'auto'} # num features num_features = BoundedIntText( value=10, min=0, max=999999, step=1, description='Number of features:', style=style, description_tooltip= 'Maximum number of features present in explanation') options_map['num_features'] = num_features # num samples num_samples = BoundedIntText( value=5000, min=0, max=999999, step=1, description='Number of samples:', style=style, description_tooltip= 'Size of the neighborhood to learn the linear model') options_map['num_samples'] = num_samples # kernel_width kernel_width = BoundedFloatText( value=0.75, min=0, max=999999, step=0.05, description='Kernel width:', style=style, description_tooltip= 'Kernel width for the exponential kernel. Actual value used will be ' 'value * sqrt(num_of_cols_in_train_data)') options_map['kernel_width'] = kernel_width # feature_selection feature_selection = Dropdown( description='Feature selection:', style=style, description_tooltip='Feature selection method\n' ' - forward_selection: iteratively add features to the model, ' 'costly when num_features is high\n' ' - highest_weights: selects the features that have the highest' 'product of absolute weight * original data point when learning with all the features\n' ' - lasso_path: chooses features based on the lasso regularization path\n' ' - none: use all features, ignore Number of features option\n' ' - auto: use forward_selection if num_features <= 6, and highest_weights otherwise', options=[ 'forward_selection', 'highest_weights', 'lasso_path', 'none', 'auto' ], value='auto') options_map['feature_selection'] = feature_selection # discretize_continuous discretize_continuous = Checkbox( description='Discretize continuous', # style=style, value=True, title= 'Whether to discretize all non-categorical features' # This doesn't work... # I don't know how to get a tooltip to checkbox ) options_map['discretize_continuous'] = discretize_continuous # discretizer discretizer = Dropdown( description='Discretizer:', style=style, options=[ 'quartile', 'decile' ], # not supporting entropy, because we don't have training labels :/ value='quartile', description_tooltip= 'Which discretizer to use. Only matters if discretize continuous is True' ) options_map['discretizer'] = discretizer # set up disabling of discretizer dropdown if discretize_continuous is not checked def disable_discretizer(change): discretizer.disabled = not change['new'] discretize_continuous.observe(disable_discretizer, names=['value']) # distance_metric distance_metric = Text( description='Distance metric:', style=style, value='euclidean', description_tooltip= 'What distance metric to use (for calculating weights). ' 'Used as an "distance_metric" argument for sklearn.metrics.pairwise_distances' ) options_map['distance_metric'] = distance_metric # model_regressor model_regressor = UpdatingCombobox( options_keys=self.globals_options, description='Variable with model regressor:', style=style, value='None', description_tooltip= 'sklearn regressor to use in explanation. Defaults to Ridge regression if None. ' 'Must have model_regressor.coef_ and "sample_weight" as a parameter ' 'to model_regressor.fit()\n\n' '(specify the name of the variable with regressor that you have in the notebook)' ) model_regressor.lookup_in_kernel = True options_map['model_regressor'] = model_regressor grid[0, 0] = num_features grid[0, 1] = num_samples grid[1, 0] = kernel_width grid[1, 1] = feature_selection grid[2, 0] = discretize_continuous grid[2, 1] = discretizer grid[3, 0] = distance_metric grid[3, 1] = model_regressor return options_map, grid
class SubstrateTab(object): def __init__(self): self.output_dir = '.' # self.output_dir = 'tmpdir' self.fig = plt.figure(figsize=( 7.2, 6)) # this strange figsize results in a ~square contour plot # initial value self.field_index = 4 # self.field_index = self.mcds_field.value + 4 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) svg_plot_size = '700px' self.mcds_plot.layout.width = svg_plot_size self.mcds_plot.layout.height = svg_plot_size self.max_frames = BoundedIntText( min=0, max=99999, value=max_frames, description='Max', layout=Layout(width='160px'), ) self.max_frames.observe(self.update_max_frames) self.field_min_max = {'oxygen': [0., 38.], 'glucose': [0.8, 1.]} # hacky I know, but make a dict that's got (key,value) reversed from the dict in the Dropdown below self.field_dict = {0: 'oxygen', 1: 'glucose'} self.mcds_field = Dropdown( options={ 'oxygen': 0, 'glucose': 1 }, value=0, # description='Field', layout=Layout(width=constWidth)) # self.mcds_field.observe(self.mcds_field_cb) self.mcds_field.observe(self.mcds_field_changed_cb) # self.field_cmap = Text( # value='viridis', # description='Colormap', # disabled=True, # layout=Layout(width=constWidth), # ) self.field_cmap = Dropdown( options=['viridis', 'jet', 'YlOrRd'], value='viridis', # description='Field', layout=Layout(width=constWidth)) #self.field_cmap.observe(self.plot_substrate) # self.field_cmap.observe(self.plot_substrate) self.field_cmap.observe(self.mcds_field_cb) self.cmap_fixed = Checkbox( description='Fix', disabled=False, # layout=Layout(width=constWidth2), ) 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_cb(b): if (self.cmap_fixed.value): self.cmap_min.disabled = False self.cmap_max.disabled = False self.save_min_max.disabled = False else: self.cmap_min.disabled = True self.cmap_max.disabled = True self.save_min_max.disabled = True # self.mcds_field_cb() self.cmap_fixed.observe(cmap_fixed_cb) field_cmap_row2 = HBox([self.field_cmap, self.cmap_fixed]) # 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) # 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) # self.tab = HBox([mcds_params, self.mcds_plot]) 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', width='50%', height='', align_items='stretch', flex_direction='row', display='flex')) ]) row2 = Box([self.cmap_fixed, self.cmap_min, self.cmap_max], layout=Layout(border='0px solid black', width='50%', height='', align_items='stretch', flex_direction='row', display='flex')) self.tab = VBox([row1, row2, self.mcds_plot]) 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(self, rdir): self.output_dir = rdir if rdir == '': # self.max_frames.value = 0 tmpdir = os.path.abspath('tmpdir') self.output_dir = tmpdir all_files = sorted(glob.glob(os.path.join(tmpdir, 'output*.xml'))) if len(all_files) > 0: last_file = all_files[-1] self.max_frames.value = int( last_file[-12:-4] ) # assumes naming scheme: "output%08d.xml" self.mcds_plot.update() return all_files = sorted(glob.glob(os.path.join(rdir, 'output*.xml'))) if len(all_files) > 0: last_file = all_files[-1] self.max_frames.value = int( last_file[-12:-4]) # assumes naming scheme: "output%08d.xml" self.mcds_plot.update() def update_max_frames(self, _b): self.mcds_plot.children[0].max = self.max_frames.value def mcds_field_changed_cb(self, b): self.field_index = self.mcds_field.value + 4 field_name = self.field_dict[self.mcds_field.value] # print('mcds_field_cb: '+field_name) self.cmap_min.value = self.field_min_max[field_name][0] self.cmap_max.value = self.field_min_max[field_name][1] self.mcds_plot.update() def mcds_field_cb(self, b): #self.field_index = self.mcds_field.value # self.field_index = self.mcds_field.options.index(self.mcds_field.value) + 4 # self.field_index = self.mcds_field.options[self.mcds_field.value] self.field_index = self.mcds_field.value + 4 # field_name = self.mcds_field.options[self.mcds_field.value] # self.cmap_min.value = self.field_min_max[field_name][0] # oxygen, etc # self.cmap_max.value = self.field_min_max[field_name][1] # oxygen, etc # self.field_index = self.mcds_field.value + 4 # print('field_index=',self.field_index) self.mcds_plot.update() def plot_substrate(self, frame): # global current_idx, axes_max, gFileId, field_index fname = "output%08d_microenvironment0.mat" % frame xml_fname = "output%08d.xml" % frame # fullname = output_dir_str + fname # fullname = fname full_fname = os.path.join(self.output_dir, fname) full_xml_fname = os.path.join(self.output_dir, xml_fname) # self.output_dir = '.' # if not os.path.isfile(fullname): if not os.path.isfile(full_fname): # print("File does not exist: ", full_fname) # print("No: ", full_fname) print("Missing output file" ) # No: output00000000_microenvironment0.mat return # tree = ET.parse(xml_fname) tree = ET.parse(full_xml_fname) xml_root = tree.getroot() mins = round(int(float(xml_root.find( ".//current_time").text))) # TODO: check units = mins hrs = mins / 60. days = hrs / 24. title_str = '%dd, %dh, %dm' % (int(days), (hrs % 24), mins - (hrs * 60)) info_dict = {} # scipy.io.loadmat(fullname, info_dict) scipy.io.loadmat(full_fname, info_dict) M = info_dict['multiscale_microenvironment'] # global_field_index = int(mcds_field.value) # print('plot_substrate: field_index =',field_index) f = M[ self. field_index, :] # 4=tumor cells field, 5=blood vessel density, 6=growth substrate # plt.clf() # my_plot = plt.imshow(f.reshape(400,400), cmap='jet', extent=[0,20, 0,20]) self.fig = plt.figure(figsize=( 7.2, 6)) # this strange figsize results in a ~square contour plot # fig.set_tight_layout(True) # ax = plt.axes([0, 0.05, 0.9, 0.9 ]) #left, bottom, width, height # ax = plt.axes([0, 0.0, 1, 1 ]) # cmap = plt.cm.viridis # Blues, YlOrBr, ... # im = ax.imshow(f.reshape(100,100), interpolation='nearest', cmap=cmap, extent=[0,20, 0,20]) # ax.grid(False) N = int(math.sqrt(len(M[0, :]))) grid2D = M[0, :].reshape(N, N) xvec = grid2D[0, :] num_contours = 15 # levels = MaxNLocator(nbins=10).tick_values(vmin, vmax) levels = MaxNLocator(nbins=num_contours).tick_values( self.cmap_min.value, self.cmap_max.value) if (self.cmap_fixed.value): my_plot = plt.contourf(xvec, xvec, M[self.field_index, :].reshape(N, N), levels=levels, extend='both', cmap=self.field_cmap.value) else: # my_plot = plt.contourf(xvec, xvec, M[self.field_index, :].reshape(N,N), num_contours, cmap=self.field_cmap.value) my_plot = plt.contourf(xvec, xvec, M[self.field_index, :].reshape(N, N), num_contours, cmap=self.field_cmap.value) plt.title(title_str) plt.colorbar(my_plot) axes_min = 0 axes_max = 2000
def make_config(self): layout = Layout() style = {"description_width": "initial"} checkbox1 = Checkbox(description="Show Targets", value=self.net.config["show_targets"], layout=layout, style=style) checkbox1.observe(lambda change: self.set_attr( self.net.config, "show_targets", change["new"]), names='value') checkbox2 = Checkbox(description="Errors", value=self.net.config["show_errors"], layout=layout, style=style) checkbox2.observe(lambda change: self.set_attr( self.net.config, "show_errors", change["new"]), names='value') hspace = IntText(value=self.net.config["hspace"], description="Horizontal space between banks:", style=style, layout=layout) hspace.observe(lambda change: self.set_attr(self.net.config, "hspace", change["new"]), names='value') vspace = IntText(value=self.net.config["vspace"], description="Vertical space between layers:", style=style, layout=layout) vspace.observe(lambda change: self.set_attr(self.net.config, "vspace", change["new"]), names='value') self.feature_bank = Select( description="Features:", value="", options=[""] + [ layer.name for layer in self.net.layers if self.net._layer_has_features(layer.name) ], rows=1) self.feature_bank.observe(self.regenerate, names='value') self.control_select = Select(options=['Test', 'Train'], value='Train', description='Dataset:', rows=1) self.control_select.observe(self.update_control_slider, names='value') column1 = [ self.control_select, self.zoom_slider, hspace, vspace, HBox([checkbox1, checkbox2]), self.feature_bank, self.feature_columns, self.feature_scale ] ## Make layer selectable, and update-able: column2 = [] layer = self.net.layers[-1] self.layer_select = Select( description="Layer:", value=layer.name, options=[layer.name for layer in self.net.layers], rows=1) self.layer_select.observe(self.update_layer_selection, names='value') column2.append(self.layer_select) self.layer_visible_checkbox = Checkbox(description="Visible", value=layer.visible, layout=layout) self.layer_visible_checkbox.observe(self.update_layer, names='value') column2.append(self.layer_visible_checkbox) self.layer_colormap = Select( description="Colormap:", options=[""] + AVAILABLE_COLORMAPS, value=layer.colormap if layer.colormap is not None else "", layout=layout, rows=1) self.layer_colormap_image = HTML( value="""<img src="%s"/>""" % self.net._image_to_uri(self.make_colormap_image(layer.colormap))) self.layer_colormap.observe(self.update_layer, names='value') column2.append(self.layer_colormap) column2.append(self.layer_colormap_image) self.layer_mindim = FloatText(description="Leftmost color maps to:", value=layer.minmax[0], style=style) self.layer_maxdim = FloatText(description="Rightmost color maps to:", value=layer.minmax[1], style=style) self.layer_mindim.observe(self.update_layer, names='value') self.layer_maxdim.observe(self.update_layer, names='value') column2.append(self.layer_mindim) column2.append(self.layer_maxdim) output_shape = layer.get_output_shape() self.layer_feature = IntText(value=layer.feature, description="Feature to show:", style=style) self.layer_feature.observe(self.update_layer, names='value') column2.append(self.layer_feature) config_children = HBox([ VBox(column1, layout=Layout(width="100%")), VBox(column2, layout=Layout(width="100%")) ]) accordion = Accordion(children=[config_children]) accordion.set_title(0, self.net.name) accordion.selected_index = None return accordion
class Dashboard(VBox): """ Build the dashboard for Jupyter widgets. Requires running in a notebook/jupyterlab. """ def __init__(self, net, width="95%", height="550px", play_rate=0.5): self._ignore_layer_updates = False self.player = _Player(self, play_rate) self.player.start() self.net = net r = random.randint(1, 1000000) self.class_id = "picture-dashboard-%s-%s" % (self.net.name, r) self._width = width self._height = height ## Global widgets: style = {"description_width": "initial"} self.feature_columns = IntText(description="Detail columns:", value=self.net.config["dashboard.features.columns"], min=0, max=1024, style=style) self.feature_scale = FloatText(description="Detail scale:", value=self.net.config["dashboard.features.scale"], min=0.1, max=10, style=style) self.feature_columns.observe(self.regenerate, names='value') self.feature_scale.observe(self.regenerate, names='value') ## Hack to center SVG as justify-content is broken: self.net_svg = HTML(value="""<p style="text-align:center">%s</p>""" % ("",), layout=Layout( width=self._width, overflow_x='auto', overflow_y="auto", justify_content="center")) # Make controls first: self.output = Output() controls = self.make_controls() config = self.make_config() super().__init__([config, controls, self.net_svg, self.output]) def propagate(self, inputs): """ Propagate inputs through the dashboard view of the network. """ if dynamic_pictures_check(): return self.net.propagate(inputs, class_id=self.class_id, update_pictures=True) else: self.regenerate(inputs=input) def goto(self, position): if len(self.net.dataset.inputs) == 0 or len(self.net.dataset.targets) == 0: return if self.control_select.value == "Train": length = len(self.net.dataset.train_inputs) elif self.control_select.value == "Test": length = len(self.net.dataset.test_inputs) #### Position it: if position == "begin": self.control_slider.value = 0 elif position == "end": self.control_slider.value = length - 1 elif position == "prev": if self.control_slider.value - 1 < 0: self.control_slider.value = length - 1 # wrap around else: self.control_slider.value = max(self.control_slider.value - 1, 0) elif position == "next": if self.control_slider.value + 1 > length - 1: self.control_slider.value = 0 # wrap around else: self.control_slider.value = min(self.control_slider.value + 1, length - 1) self.position_text.value = self.control_slider.value def change_select(self, change=None): """ """ self.update_control_slider(change) self.regenerate() def update_control_slider(self, change=None): self.net.config["dashboard.dataset"] = self.control_select.value if len(self.net.dataset.inputs) == 0 or len(self.net.dataset.targets) == 0: self.total_text.value = "of 0" self.control_slider.value = 0 self.position_text.value = 0 self.control_slider.disabled = True self.position_text.disabled = True for child in self.control_buttons.children: if not hasattr(child, "icon") or child.icon != "refresh": child.disabled = True return if self.control_select.value == "Test": self.total_text.value = "of %s" % len(self.net.dataset.test_inputs) minmax = (0, max(len(self.net.dataset.test_inputs) - 1, 0)) if minmax[0] <= self.control_slider.value <= minmax[1]: pass # ok else: self.control_slider.value = 0 self.control_slider.min = minmax[0] self.control_slider.max = minmax[1] if len(self.net.dataset.test_inputs) == 0: disabled = True else: disabled = False elif self.control_select.value == "Train": self.total_text.value = "of %s" % len(self.net.dataset.train_inputs) minmax = (0, max(len(self.net.dataset.train_inputs) - 1, 0)) if minmax[0] <= self.control_slider.value <= minmax[1]: pass # ok else: self.control_slider.value = 0 self.control_slider.min = minmax[0] self.control_slider.max = minmax[1] if len(self.net.dataset.train_inputs) == 0: disabled = True else: disabled = False self.control_slider.disabled = disabled self.position_text.disbaled = disabled self.position_text.value = self.control_slider.value for child in self.control_buttons.children: if not hasattr(child, "icon") or child.icon != "refresh": child.disabled = disabled def update_zoom_slider(self, change): if change["name"] == "value": self.net.config["svg_scale"] = self.zoom_slider.value self.regenerate() def update_position_text(self, change): # {'name': 'value', 'old': 2, 'new': 3, 'owner': IntText(value=3, layout=Layout(width='100%')), 'type': 'change'} self.control_slider.value = change["new"] def get_current_input(self): if self.control_select.value == "Train" and len(self.net.dataset.train_targets) > 0: return self.net.dataset.train_inputs[self.control_slider.value] elif self.control_select.value == "Test" and len(self.net.dataset.test_targets) > 0: return self.net.dataset.test_inputs[self.control_slider.value] def get_current_targets(self): if self.control_select.value == "Train" and len(self.net.dataset.train_targets) > 0: return self.net.dataset.train_targets[self.control_slider.value] elif self.control_select.value == "Test" and len(self.net.dataset.test_targets) > 0: return self.net.dataset.test_targets[self.control_slider.value] def update_slider_control(self, change): if len(self.net.dataset.inputs) == 0 or len(self.net.dataset.targets) == 0: self.total_text.value = "of 0" return if change["name"] == "value": self.position_text.value = self.control_slider.value if self.control_select.value == "Train" and len(self.net.dataset.train_targets) > 0: self.total_text.value = "of %s" % len(self.net.dataset.train_inputs) if self.net.model is None: return if not dynamic_pictures_check(): self.regenerate(inputs=self.net.dataset.train_inputs[self.control_slider.value], targets=self.net.dataset.train_targets[self.control_slider.value]) return output = self.net.propagate(self.net.dataset.train_inputs[self.control_slider.value], class_id=self.class_id, update_pictures=True) if self.feature_bank.value in self.net.layer_dict.keys(): self.net.propagate_to_features(self.feature_bank.value, self.net.dataset.train_inputs[self.control_slider.value], cols=self.feature_columns.value, scale=self.feature_scale.value, html=False) if self.net.config["show_targets"]: if len(self.net.output_bank_order) == 1: ## FIXME: use minmax of output bank self.net.display_component([self.net.dataset.train_targets[self.control_slider.value]], "targets", class_id=self.class_id, minmax=(-1, 1)) else: self.net.display_component(self.net.dataset.train_targets[self.control_slider.value], "targets", class_id=self.class_id, minmax=(-1, 1)) if self.net.config["show_errors"]: ## minmax is error if len(self.net.output_bank_order) == 1: errors = np.array(output) - np.array(self.net.dataset.train_targets[self.control_slider.value]) self.net.display_component([errors.tolist()], "errors", class_id=self.class_id, minmax=(-1, 1)) else: errors = [] for bank in range(len(self.net.output_bank_order)): errors.append( np.array(output[bank]) - np.array(self.net.dataset.train_targets[self.control_slider.value][bank])) self.net.display_component(errors, "errors", class_id=self.class_id, minmax=(-1, 1)) elif self.control_select.value == "Test" and len(self.net.dataset.test_targets) > 0: self.total_text.value = "of %s" % len(self.net.dataset.test_inputs) if self.net.model is None: return if not dynamic_pictures_check(): self.regenerate(inputs=self.net.dataset.test_inputs[self.control_slider.value], targets=self.net.dataset.test_targets[self.control_slider.value]) return output = self.net.propagate(self.net.dataset.test_inputs[self.control_slider.value], class_id=self.class_id, update_pictures=True) if self.feature_bank.value in self.net.layer_dict.keys(): self.net.propagate_to_features(self.feature_bank.value, self.net.dataset.test_inputs[self.control_slider.value], cols=self.feature_columns.value, scale=self.feature_scale.value, html=False) if self.net.config["show_targets"]: ## FIXME: use minmax of output bank self.net.display_component([self.net.dataset.test_targets[self.control_slider.value]], "targets", class_id=self.class_id, minmax=(-1, 1)) if self.net.config["show_errors"]: ## minmax is error if len(self.net.output_bank_order) == 1: errors = np.array(output) - np.array(self.net.dataset.test_targets[self.control_slider.value]) self.net.display_component([errors.tolist()], "errors", class_id=self.class_id, minmax=(-1, 1)) else: errors = [] for bank in range(len(self.net.output_bank_order)): errors.append( np.array(output[bank]) - np.array(self.net.dataset.test_targets[self.control_slider.value][bank])) self.net.display_component(errors, "errors", class_id=self.class_id, minmax=(-1, 1)) def toggle_play(self, button): ## toggle if self.button_play.description == "Play": self.button_play.description = "Stop" self.button_play.icon = "pause" self.player.resume() else: self.button_play.description = "Play" self.button_play.icon = "play" self.player.pause() def prop_one(self, button=None): self.update_slider_control({"name": "value"}) def regenerate(self, button=None, inputs=None, targets=None): ## Protection when deleting object on shutdown: if isinstance(button, dict) and 'new' in button and button['new'] is None: return ## Update the config: self.net.config["dashboard.features.bank"] = self.feature_bank.value self.net.config["dashboard.features.columns"] = self.feature_columns.value self.net.config["dashboard.features.scale"] = self.feature_scale.value inputs = inputs if inputs is not None else self.get_current_input() targets = targets if targets is not None else self.get_current_targets() features = None if self.feature_bank.value in self.net.layer_dict.keys() and inputs is not None: if self.net.model is not None: features = self.net.propagate_to_features(self.feature_bank.value, inputs, cols=self.feature_columns.value, scale=self.feature_scale.value, display=False) svg = """<p style="text-align:center">%s</p>""" % (self.net.to_svg( inputs=inputs, targets=targets, class_id=self.class_id, highlights={self.feature_bank.value: { "border_color": "orange", "border_width": 30, }})) if inputs is not None and features is not None: html_horizontal = """ <table align="center" style="width: 100%%;"> <tr> <td valign="top" style="width: 50%%;">%s</td> <td valign="top" align="center" style="width: 50%%;"><p style="text-align:center"><b>%s</b></p>%s</td> </tr> </table>""" html_vertical = """ <table align="center" style="width: 100%%;"> <tr> <td valign="top">%s</td> </tr> <tr> <td valign="top" align="center"><p style="text-align:center"><b>%s</b></p>%s</td> </tr> </table>""" self.net_svg.value = (html_vertical if self.net.config["svg_rotate"] else html_horizontal) % ( svg, "%s details" % self.feature_bank.value, features) else: self.net_svg.value = svg def make_colormap_image(self, colormap_name): from .layers import Layer if not colormap_name: colormap_name = get_colormap() layer = Layer("Colormap", 100) minmax = layer.get_act_minmax() image = layer.make_image(np.arange(minmax[0], minmax[1], .01), colormap_name, {"pixels_per_unit": 1, "svg_rotate": self.net.config["svg_rotate"]}).resize((300, 25)) return image def set_attr(self, obj, attr, value): if value not in [{}, None]: ## value is None when shutting down if isinstance(value, dict): value = value["value"] if isinstance(obj, dict): obj[attr] = value else: setattr(obj, attr, value) ## was crashing on Widgets.__del__, if get_ipython() no longer existed self.regenerate() def make_controls(self): layout = Layout(width='100%', height="100%") button_begin = Button(icon="fast-backward", layout=layout) button_prev = Button(icon="backward", layout=layout) button_next = Button(icon="forward", layout=layout) button_end = Button(icon="fast-forward", layout=layout) #button_prop = Button(description="Propagate", layout=Layout(width='100%')) #button_train = Button(description="Train", layout=Layout(width='100%')) self.button_play = Button(icon="play", description="Play", layout=layout) step_down = Button(icon="sort-down", layout=Layout(width="95%", height="100%")) step_up = Button(icon="sort-up", layout=Layout(width="95%", height="100%")) up_down = HBox([step_down, step_up], layout=Layout(width="100%", height="100%")) refresh_button = Button(icon="refresh", layout=Layout(width="25%", height="100%")) self.position_text = IntText(value=0, layout=layout) self.control_buttons = HBox([ button_begin, button_prev, #button_train, self.position_text, button_next, button_end, self.button_play, up_down, refresh_button ], layout=Layout(width='100%', height="100%")) length = (len(self.net.dataset.train_inputs) - 1) if len(self.net.dataset.train_inputs) > 0 else 0 self.control_slider = IntSlider(description="Dataset index", continuous_update=False, min=0, max=max(length, 0), value=0, layout=Layout(width='100%')) if self.net.config["dashboard.dataset"] == "Train": length = len(self.net.dataset.train_inputs) else: length = len(self.net.dataset.test_inputs) self.total_text = Label(value="of %s" % length, layout=Layout(width="100px")) self.zoom_slider = FloatSlider(description="Zoom", continuous_update=False, min=0, max=1.0, style={"description_width": 'initial'}, layout=Layout(width="65%"), value=self.net.config["svg_scale"] if self.net.config["svg_scale"] is not None else 0.5) ## Hook them up: button_begin.on_click(lambda button: self.goto("begin")) button_end.on_click(lambda button: self.goto("end")) button_next.on_click(lambda button: self.goto("next")) button_prev.on_click(lambda button: self.goto("prev")) self.button_play.on_click(self.toggle_play) self.control_slider.observe(self.update_slider_control, names='value') refresh_button.on_click(lambda widget: (self.update_control_slider(), self.output.clear_output(), self.regenerate())) step_down.on_click(lambda widget: self.move_step("down")) step_up.on_click(lambda widget: self.move_step("up")) self.zoom_slider.observe(self.update_zoom_slider, names='value') self.position_text.observe(self.update_position_text, names='value') # Put them together: controls = VBox([HBox([self.control_slider, self.total_text], layout=Layout(height="40px")), self.control_buttons], layout=Layout(width='100%')) #net_page = VBox([control, self.net_svg], layout=Layout(width='95%')) controls.on_displayed(lambda widget: self.regenerate()) return controls def move_step(self, direction): """ Move the layer stepper up/down through network """ options = [""] + [layer.name for layer in self.net.layers] index = options.index(self.feature_bank.value) if direction == "up": new_index = (index + 1) % len(options) else: ## down new_index = (index - 1) % len(options) self.feature_bank.value = options[new_index] self.regenerate() def make_config(self): layout = Layout() style = {"description_width": "initial"} checkbox1 = Checkbox(description="Show Targets", value=self.net.config["show_targets"], layout=layout, style=style) checkbox1.observe(lambda change: self.set_attr(self.net.config, "show_targets", change["new"]), names='value') checkbox2 = Checkbox(description="Errors", value=self.net.config["show_errors"], layout=layout, style=style) checkbox2.observe(lambda change: self.set_attr(self.net.config, "show_errors", change["new"]), names='value') hspace = IntText(value=self.net.config["hspace"], description="Horizontal space between banks:", style=style, layout=layout) hspace.observe(lambda change: self.set_attr(self.net.config, "hspace", change["new"]), names='value') vspace = IntText(value=self.net.config["vspace"], description="Vertical space between layers:", style=style, layout=layout) vspace.observe(lambda change: self.set_attr(self.net.config, "vspace", change["new"]), names='value') self.feature_bank = Select(description="Details:", value=self.net.config["dashboard.features.bank"], options=[""] + [layer.name for layer in self.net.layers], rows=1) self.feature_bank.observe(self.regenerate, names='value') self.control_select = Select( options=['Test', 'Train'], value=self.net.config["dashboard.dataset"], description='Dataset:', rows=1 ) self.control_select.observe(self.change_select, names='value') column1 = [self.control_select, self.zoom_slider, hspace, vspace, HBox([checkbox1, checkbox2]), self.feature_bank, self.feature_columns, self.feature_scale ] ## Make layer selectable, and update-able: column2 = [] layer = self.net.layers[-1] self.layer_select = Select(description="Layer:", value=layer.name, options=[layer.name for layer in self.net.layers], rows=1) self.layer_select.observe(self.update_layer_selection, names='value') column2.append(self.layer_select) self.layer_visible_checkbox = Checkbox(description="Visible", value=layer.visible, layout=layout) self.layer_visible_checkbox.observe(self.update_layer, names='value') column2.append(self.layer_visible_checkbox) self.layer_colormap = Select(description="Colormap:", options=[""] + AVAILABLE_COLORMAPS, value=layer.colormap if layer.colormap is not None else "", layout=layout, rows=1) self.layer_colormap_image = HTML(value="""<img src="%s"/>""" % self.net._image_to_uri(self.make_colormap_image(layer.colormap))) self.layer_colormap.observe(self.update_layer, names='value') column2.append(self.layer_colormap) column2.append(self.layer_colormap_image) ## get dynamic minmax; if you change it it will set it in layer as override: minmax = layer.get_act_minmax() self.layer_mindim = FloatText(description="Leftmost color maps to:", value=minmax[0], style=style) self.layer_maxdim = FloatText(description="Rightmost color maps to:", value=minmax[1], style=style) self.layer_mindim.observe(self.update_layer, names='value') self.layer_maxdim.observe(self.update_layer, names='value') column2.append(self.layer_mindim) column2.append(self.layer_maxdim) output_shape = layer.get_output_shape() self.layer_feature = IntText(value=layer.feature, description="Feature to show:", style=style) self.svg_rotate = Checkbox(description="Rotate", value=layer.visible, layout=layout) self.layer_feature.observe(self.update_layer, names='value') column2.append(self.layer_feature) self.svg_rotate = Checkbox(description="Rotate network", value=self.net.config["svg_rotate"], style={"description_width": 'initial'}, layout=Layout(width="52%")) self.svg_rotate.observe(lambda change: self.set_attr(self.net.config, "svg_rotate", change["new"]), names='value') self.save_config_button = Button(icon="save", layout=Layout(width="10%")) self.save_config_button.on_click(self.save_config) column2.append(HBox([self.svg_rotate, self.save_config_button])) config_children = HBox([VBox(column1, layout=Layout(width="100%")), VBox(column2, layout=Layout(width="100%"))]) accordion = Accordion(children=[config_children]) accordion.set_title(0, self.net.name) accordion.selected_index = None return accordion def save_config(self, widget=None): self.net.save_config() def update_layer(self, change): """ Update the layer object, and redisplay. """ if self._ignore_layer_updates: return ## The rest indicates a change to a display variable. ## We need to save the value in the layer, and regenerate ## the display. # Get the layer: layer = self.net[self.layer_select.value] # Save the changed value in the layer: layer.feature = self.layer_feature.value layer.visible = self.layer_visible_checkbox.value ## These three, dealing with colors of activations, ## can be done with a prop_one(): if "color" in change["owner"].description.lower(): ## Matches: Colormap, lefmost color, rightmost color ## overriding dynamic minmax! layer.minmax = (self.layer_mindim.value, self.layer_maxdim.value) layer.minmax = (self.layer_mindim.value, self.layer_maxdim.value) layer.colormap = self.layer_colormap.value if self.layer_colormap.value else None self.layer_colormap_image.value = """<img src="%s"/>""" % self.net._image_to_uri(self.make_colormap_image(layer.colormap)) self.prop_one() else: self.regenerate() def update_layer_selection(self, change): """ Just update the widgets; don't redraw anything. """ ## No need to redisplay anything self._ignore_layer_updates = True ## First, get the new layer selected: layer = self.net[self.layer_select.value] ## Now, let's update all of the values without updating: self.layer_visible_checkbox.value = layer.visible self.layer_colormap.value = layer.colormap if layer.colormap != "" else "" self.layer_colormap_image.value = """<img src="%s"/>""" % self.net._image_to_uri(self.make_colormap_image(layer.colormap)) minmax = layer.get_act_minmax() self.layer_mindim.value = minmax[0] self.layer_maxdim.value = minmax[1] self.layer_feature.value = layer.feature self._ignore_layer_updates = False
def _make_widget_repr(self): self.widget_repr_name = Text(value='', description='representation') self.widget_repr_name._ngl_name = 'repr_name_text' repr_selection = Text(value=' ', description='selection') repr_selection._ngl_name = 'repr_selection' repr_selection.width = self.widget_repr_name.width = default.DEFAULT_TEXT_WIDTH max_n_components = max(self._view.n_components-1, 0) self.widget_component_slider = IntSlider(value=0, max=max_n_components, min=0, description='component') self.widget_component_slider._ngl_name = 'component_slider' cvalue = ' ' self.widget_component_dropdown = Dropdown(value=cvalue, options=[cvalue,], description='component') self.widget_component_dropdown._ngl_name = 'component_dropdown' self.widget_repr_slider = IntSlider(value=0, description='representation', width=default.DEFAULT_SLIDER_WIDTH) self.widget_repr_slider._ngl_name = 'repr_slider' self.widget_repr_slider.visible = True self.widget_component_slider.layout.width = default.DEFAULT_SLIDER_WIDTH self.widget_repr_slider.layout.width = default.DEFAULT_SLIDER_WIDTH self.widget_component_dropdown.layout.width = self.widget_component_dropdown.max_width = default.DEFAULT_TEXT_WIDTH # turn off for now self.widget_component_dropdown.layout.display = 'none' self.widget_component_dropdown.description = '' # self.widget_accordion_repr_parameters = Accordion() self.widget_accordion_repr_parameters = Tab() self.widget_repr_parameters = self._make_widget_repr_parameters(self.widget_component_slider, self.widget_repr_slider, self.widget_repr_name) self.widget_accordion_repr_parameters.children = [self.widget_repr_parameters, Box()] self.widget_accordion_repr_parameters.set_title(0, 'Parameters') self.widget_accordion_repr_parameters.set_title(1, 'Hide') self.widget_accordion_repr_parameters.selected_index = 1 checkbox_reprlist = Checkbox(value=False, description='reprlist') checkbox_reprlist._ngl_name = 'checkbox_reprlist' self.widget_repr_choices = self._make_repr_name_choices(self.widget_component_slider, self.widget_repr_slider) self.widget_repr_choices._ngl_name = 'reprlist_choices' self.widget_repr_add = self._make_add_widget_repr(self.widget_component_slider) def on_update_checkbox_reprlist(change): self.widget_repr_choices.visible= change['new'] checkbox_reprlist.observe(on_update_checkbox_reprlist, names='value') def on_repr_name_text_value_changed(change): name = change['new'].strip() old = change['old'].strip() should_update = (self._real_time_update and old and name and name in REPRESENTATION_NAMES and name != change['old'].strip()) if should_update: component=self.widget_component_slider.value repr_index=self.widget_repr_slider.value self._view._remote_call('setRepresentation', target='Widget', args=[change['new'], {}, component, repr_index]) self._view._request_repr_parameters(component, repr_index) def on_component_or_repr_slider_value_changed(change): self._view._request_repr_parameters(component=self.widget_component_slider.value, repr_index=self.widget_repr_slider.value) self.widget_component_dropdown.options = tuple(self._view._ngl_component_names) if self.widget_accordion_repr_parameters.selected_index >= 0: self.widget_repr_parameters.name = self.widget_repr_name.value self.widget_repr_parameters.repr_index = self.widget_repr_slider.value self.widget_repr_parameters.component_index = self.widget_component_slider.value def on_repr_selection_value_changed(change): if self._real_time_update: component = self.widget_component_slider.value repr_index = self.widget_repr_slider.value self._view._set_selection(change['new'], component=component, repr_index=repr_index) def on_change_component_dropdown(change): choice = change['new'] if choice: self.widget_component_slider.value = self._view._ngl_component_names.index(choice) self.widget_component_dropdown.observe(on_change_component_dropdown, names='value') self.widget_repr_slider.observe(on_component_or_repr_slider_value_changed, names='value') self.widget_component_slider.observe(on_component_or_repr_slider_value_changed, names='value') self.widget_repr_name.observe(on_repr_name_text_value_changed, names='value') repr_selection.observe(on_repr_selection_value_changed, names='value') self.widget_repr_control_buttons = self._make_button_repr_control(self.widget_component_slider, self.widget_repr_slider, repr_selection) blank_box = Box([Label("")]) all_kids = [self.widget_repr_control_buttons, blank_box, self.widget_repr_add, self.widget_component_dropdown, self.widget_repr_name, repr_selection, self.widget_component_slider, self.widget_repr_slider, self.widget_repr_choices, self.widget_accordion_repr_parameters ] vbox = VBox(all_kids) self._view._request_repr_parameters(component=self.widget_component_slider.value, repr_index=self.widget_repr_slider.value) self.widget_repr = _relayout_master(vbox, width='100%') self._refresh(self.widget_component_slider, self.widget_repr_slider) setattr(self.widget_repr, "_saved_widgets", []) for _box in self.widget_repr.children: if hasattr(_box, 'children'): for kid in _box.children: self.widget_repr._saved_widgets.append(kid) return self.widget_repr
class VariableSelector(VBox): """ Combo widget based on a Select box with a search panel above to live filter variables to Select. When a variable is selected the long name attribute is displayed under the select box. There are also two checkboxes which hide coordinates and restart variables. Note that a dict is used to populate the Select widget, so the visible value is the variable name and is accessed via the label attribute, and the long name via the value attribute. """ variables = None def __init__(self, variables, rows=10, **kwargs): """ variables is a pandas dataframe. kwargs are passed through to child widgets which, theoretically, allows for layout information to be specified """ self._make_widgets(rows) super().__init__(children=[ self.model, self.search, self.selector, self.info, self.filter_coords, self.filter_restarts, ], **kwargs) self.set_variables(variables) self._set_info() self._set_observes() def _make_widgets(self, rows): """ Instantiate all widgets """ # Experiment selector element self.model = Dropdown( options=(), layout={ "padding": "0px 5px", "width": "initial" }, description="", ) # Variable search self.search = Text( placeholder="Search: start typing", layout={ "padding": "0px 5px", "width": "auto", "overflow-x": "scroll" }, ) # Variable selection box self.selector = Select( options=(), # sorted(self.variables.name, key=str.casefold), rows=rows, layout=self.search.layout, ) # Variable info self.info = HTML(layout=self.search.layout) # Variable filtering elements self.filter_coords = Checkbox( value=True, indent=False, description="Hide coordinates", ) self.filter_restarts = Checkbox( value=True, indent=False, description="Hide restarts", ) def _set_observes(self): """ Set event handlers """ self.filter_coords.observe(self._filter_eventhandler, names="value") self.filter_restarts.observe(self._filter_eventhandler, names="value") self.model.observe(self._model_eventhandler, names="value") self.search.observe(self._search_eventhandler, names="value") self.selector.observe(self._selector_eventhandler, names="value") def set_variables(self, variables): """ Change variables """ # Add a new column to keep track of visibility in widget self.variables = variables.assign(visible=True) # Set default filtering self._filter_variables() # Update selector self._update_selector(self.variables[self.variables.visible]) def _update_selector(self, variables): """ Update the variables in the selector. The variable are passed as an argument, so can differ from the internal variable list. This allows for easy filtering """ # Populate model selector. Note label and value differ options = {"All models": ""} for model in variables.model.cat.categories.values: if len(model) > 0 and model != "none": options["{} only".format(model.capitalize())] = model self.model.options = options options = dict() firstvar = None for vals in variables.sort_values(["name" ])[["name", "long_name", "units"]].values: var, name, units = map(str, vals) if firstvar is None: firstvar = var if name.lower() == "none" or name == "": name = var # Add units string if suitable value exists if (units.lower() == "none" or units.lower() == "nounits" or units.lower() == "no units" or units.lower() == "dimensionless" or units.lower() == "1" or units == ""): options[var] = "{}".format(name) else: options[var] = "{} ({})".format(name, units) # Populate variable selector self.selector.options = options # Highlight first value, otherwise accessors like .value are not # immediately accessible if firstvar is not None: self.selector.value = options[firstvar] def _reset_filters(self): """ Reset filters to default values """ self.filter_coords.value = True self.filter_restarts.value = True def _model_eventhandler(self, event=None): """ Filter by model """ model = self.model.value # Reset the coord and restart filters when a model changed self._reset_filters() self._filter_variables(model=model) def _filter_eventhandler(self, event=None): """ Called when filter button pushed """ self._filter_variables(self.filter_coords.value, self.filter_restarts.value, self.model.value) def _filter_variables(self, coords=True, restarts=True, model=""): """ Optionally hide some variables """ # Set up a mask with all true values mask = self.variables["name"] != "" # Filter for matching models if model != "": mask = mask & (self.variables["model"] == model) # Conditionally filter out restarts and coordinates if coords: mask = mask & ~self.variables["coordinate"] if restarts: mask = mask & ~self.variables["restart"] # Mask out hidden variables self.variables["visible"] = mask # Update the variable selector self._update_selector(self.variables[self.variables.visible]) # Reset the search self.search.value = "" self.selector.value = None def _search_eventhandler(self, event=None): """ Live search bar, updates the selector options dynamically, does not alter visible mask in variables """ search_term = self.search.value variables = self.variables[self.variables.visible] if search_term is not None or search_term != "": try: variables = variables[variables.name.str.contains( search_term, case=False, na=False) | variables.long_name.str.contains( search_term, case=False, na=False)] except: warnings.warn("Illegal character in search!", UserWarning) search_term = self.search.value self._update_selector(variables) def _selector_eventhandler(self, event=None): """ Update variable info when variable selected """ self._set_info(self.selector.value) def _set_info(self, long_name=None): """ Set long name info widget """ if long_name is None or long_name == "": long_name = " " style = "<style>.breakword { word-wrap: break-word; font-size: 90%; line-height: 1.1;}</style>" self.info.value = style + '<p class="breakword">{long_name}</p>'.format( long_name=long_name) def delete(self, variable_names=None): """ Remove variables """ # If no variable specified just delete the currently selected one if variable_names is None: if self.selector.label is None: return None else: variable_names = [ self.selector.label, ] if isinstance(variable_names, str): variable_names = [ variable_names, ] mask = self.variables["name"].isin(variable_names) deleted = self.variables[mask] # Delete variables self.variables = self.variables[~mask] # Update selector. Use search eventhandler so the selector preserves any # current search term. It is annoying to have that reset and type in again # if multiple variables are to be added self._search_eventhandler() return deleted def add(self, variables): """ Add variables """ # Concatenate existing and new variables self.variables = pd.concat([self.variables, variables]) # Need to recalculate the visible flag as new variables have been added self._filter_eventhandler(None) def get_selected(self): """ Return currently selected variable name """ return self.selector.label
def show_m(): multipoly = [] multycent = [] geom = view_spatial.trasform_geometry(info_data) poly = geom['coordinates'][0][0] # poly = view_spatial.swap_xy(geom['coordinates'][0])[0] multipoly.append(poly) cent = view_spatial.centroid(poly) multycent.append(cent) cent = view_spatial.centroid(multycent) m = Map(center=cent, zoom=16, basemap=basemaps.OpenStreetMap.Mapnik) polygon = Polygon(locations=multipoly, name='Parcel polygon', color="yellow", fill_color=None) m.add_layer(polygon) basemap2 = basemap_to_tiles(basemaps.Esri.WorldImagery) poly_text = HTML() poly_text.value = f"""Parcel ID: {pid}<br> Crop name: {crop_name}<br> Area: {area:.2f} sqm<br> Coordinates: {cent} """ poly_text.placeholder = "HTML" poly_text.description = "" # Popup with a given location on the map: poly_popup = Popup(child=poly_text, close_button=False, auto_close=False, close_on_escape_key=False) m.add_layer(poly_popup) # Popup associated to a layer polygon.popup = poly_popup # Layers control show_poly = Checkbox(value=True, description='Polygon', disabled=False, indent=False, layout=Layout(width='140px')) show_sat = Checkbox(value=False, description='High res basemap', disabled=False, indent=False, layout=Layout(width='140px')) def polygon_changed(b): try: if show_poly.value is True: m.add_layer(polygon) else: m.remove_layer(polygon) except Exception: pass show_poly.observe(polygon_changed) def show_sat_changed(b): try: if show_sat.value is True: m.add_layer(basemap2) else: m.remove_layer(basemap2) except Exception: pass show_sat.observe(show_sat_changed) try: csv_list = f"{ci_path}{pid}_images_list.{ci_band.value[0]}.csv" df = view_images.create_df(ci_path, pid, ci_band.value) geotiff = f"{ci_path}{df['imgs'][0]}.{ci_band.value[0]}.tif" bounds = view_spatial.bounds(geotiff) images = {} for i, row in df.iterrows(): str_date = str(row['date'].date()).replace('-', '') workdir = os.getcwd().split('/')[-1] img_tc = f"{ci_path}{('').join(ci_band.value)}_{str_date}.png" # Create false color image if it does not exist # Merge bands (images path, export image path, bands list) if not os.path.isfile(img_tc): imgs_path = f"{ci_path}{row['imgs']}" view_images.merge_bands(imgs_path, img_tc, ci_band.value) values = config.read() # Set the current environment if eval(values['set']['jupyterlab']) is True: image_path = f'files/{workdir}/{img_tc}' else: image_path = img_tc images[i] = ImageOverlay(url=image_path, name=str_date, bounds=(bounds)) # Time slider slider = IntSlider(value=1, min=1, max=len(images), step=1, description=str(df['date'][0].date()), disabled=False, continuous_update=False, orientation='horizontal', readout=True, readout_format='d') show_chip = Checkbox(value=True, description='Chip image', disabled=False, indent=False, layout=Layout(width='140px')) def on_ci_band_change(change): pass ci_band.observe(on_ci_band_change, 'value') def show_chip_changed(b): try: if show_chip.value is True: m.add_layer(images[slider.value - 1]) else: m.remove_layer(images[slider.value - 1]) except Exception: pass show_chip.observe(show_chip_changed) # Slider control play = Play(value=1, min=1, max=len(images), step=1, interval=1000, description="Press play", disabled=False) def slider_changed(b): if show_chip.value is True: try: m.substitute_layer(images[b['old'] - 1], images[b['new'] - 1]) except Exception: pass slider.description = str(df['date'][slider.value - 1].date()) slider.observe(slider_changed) jslink((play, 'value'), (slider, 'value')) time_box = HBox([slider, play]) time_control = WidgetControl(widget=time_box, position='bottomleft') m.add_control(time_control) m.add_layer(images[0]) map_options = VBox([show_poly, show_chip, show_sat]) except Exception as err: map_options = VBox([show_poly, show_sat]) print(err) layers_control = WidgetControl(widget=map_options, position='topright', max_width=150) m.add_control(layers_control) return m
class SubstrateTab(object): def __init__(self): self.output_dir = '.' # self.output_dir = 'tmpdir' # self.fig = plt.figure(figsize=(7.2,6)) # this strange figsize results in a ~square contour plot # initial value self.field_index = 4 # self.field_index = self.mcds_field.value + 4 # define dummy size of mesh (set in the tool's primary module) self.numx = 0 self.numy = 0 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) # "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' self.mcds_plot.layout.width = svg_plot_size self.mcds_plot.layout.height = svg_plot_size self.fontsize = 20 self.max_frames = BoundedIntText( min=0, max=99999, value=max_frames, description='Max', layout=Layout(width='160px'), ) self.max_frames.observe(self.update_max_frames) self.field_min_max = {'dummy': [0., 1.]} # 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.mcds_field = Dropdown( options={'dummy': 0}, 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 = Text( # value='viridis', # description='Colormap', # disabled=True, # layout=Layout(width=constWidth), # ) self.field_cmap = Dropdown( options=['viridis', 'jet', 'YlOrRd'], value='viridis', # description='Field', layout=Layout(width=constWidth)) #self.field_cmap.observe(self.plot_substrate) # self.field_cmap.observe(self.plot_substrate) self.field_cmap.observe(self.mcds_field_cb) self.cmap_fixed = Checkbox( description='Fix', disabled=False, # layout=Layout(width=constWidth2), ) 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_cb(b): if (self.cmap_fixed.value): self.cmap_min.disabled = False self.cmap_max.disabled = False self.save_min_max.disabled = False else: self.cmap_min.disabled = True self.cmap_max.disabled = True self.save_min_max.disabled = True # self.mcds_field_cb() self.cmap_fixed.observe(cmap_fixed_cb) field_cmap_row2 = HBox([self.field_cmap, self.cmap_fixed]) # 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) # 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) # self.tab = HBox([mcds_params, self.mcds_plot]) 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', width='50%', height='', align_items='stretch', flex_direction='row', display='flex')) ]) row2 = Box([self.cmap_fixed, self.cmap_min, self.cmap_max], layout=Layout(border='0px solid black', width='50%', height='', align_items='stretch', flex_direction='row', display='flex')) if (hublib_flag): self.download_button = Download('mcds.zip', style='warning', icon='cloud-download', tooltip='Download data', cb=self.download_cb) download_row = HBox([ self.download_button.w, Label( "Download all substrate data (browser must allow pop-ups)." ) ]) # self.tab = VBox([row1, row2, self.mcds_plot]) self.tab = VBox([row1, row2, self.mcds_plot, download_row]) else: # self.tab = VBox([row1, row2]) self.tab = VBox([row1, row2, self.mcds_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']) self.field_min_max[elm.attrib['name']] = [0., 1.] self.field_dict[field_idx] = elm.attrib['name'] dropdown_options[elm.attrib['name']] = field_idx field_idx += 1 # constWidth = '180px' # print('options=',dropdown_options) 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(self, rdir): def update(self, rdir=''): # with debug_view: # print("substrates: update rdir=", rdir) if rdir: self.output_dir = rdir all_files = sorted( glob.glob(os.path.join(self.output_dir, 'output*.xml'))) 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" # with debug_view: # print("substrates: added %s files" % len(all_files)) # self.output_dir = rdir # if rdir == '': # # self.max_frames.value = 0 # tmpdir = os.path.abspath('tmpdir') # self.output_dir = tmpdir # all_files = sorted(glob.glob(os.path.join(tmpdir, 'output*.xml'))) # if len(all_files) > 0: # last_file = all_files[-1] # self.max_frames.value = int(last_file[-12:-4]) # assumes naming scheme: "output%08d.xml" # self.mcds_plot.update() # return # all_files = sorted(glob.glob(os.path.join(rdir, 'output*.xml'))) # if len(all_files) > 0: # last_file = all_files[-1] # self.max_frames.value = int(last_file[-12:-4]) # assumes naming scheme: "output%08d.xml" # self.mcds_plot.update() 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.mcds_plot.children[0].max = self.max_frames.value 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_cb: '+field_name) self.cmap_min.value = self.field_min_max[field_name][0] self.cmap_max.value = self.field_min_max[field_name][1] self.mcds_plot.update() def mcds_field_cb(self, b): #self.field_index = self.mcds_field.value # self.field_index = self.mcds_field.options.index(self.mcds_field.value) + 4 # self.field_index = self.mcds_field.options[self.mcds_field.value] self.field_index = self.mcds_field.value + 4 # field_name = self.mcds_field.options[self.mcds_field.value] # self.cmap_min.value = self.field_min_max[field_name][0] # oxygen, etc # self.cmap_max.value = self.field_min_max[field_name][1] # oxygen, etc # self.field_index = self.mcds_field.value + 4 # print('field_index=',self.field_index) self.mcds_plot.update() def plot_substrate(self, frame): # global current_idx, axes_max, gFileId, field_index fname = "output%08d_microenvironment0.mat" % frame xml_fname = "output%08d.xml" % frame # print("--- plot_substrate") # fullname = output_dir_str + fname # fullname = fname full_fname = os.path.join(self.output_dir, fname) full_xml_fname = os.path.join(self.output_dir, xml_fname) # self.output_dir = '.' # if not os.path.isfile(fullname): if not os.path.isfile(full_fname): print("Once output files are generated, click the slider." ) # No: output00000000_microenvironment0.mat return # tree = ET.parse(xml_fname) tree = ET.parse(full_xml_fname) xml_root = tree.getroot() mins = round(int(float(xml_root.find( ".//current_time").text))) # TODO: check units = mins hrs = int(mins / 60) days = int(hrs / 24) title_str = '%dd, %dh, %dm' % (int(days), (hrs % 24), mins - (hrs * 60)) info_dict = {} # scipy.io.loadmat(fullname, info_dict) scipy.io.loadmat(full_fname, info_dict) M = info_dict['multiscale_microenvironment'] # global_field_index = int(mcds_field.value) # print('plot_substrate: field_index =',field_index) f = M[ self. field_index, :] # 4=tumor cells field, 5=blood vessel density, 6=growth substrate # plt.clf() # my_plot = plt.imshow(f.reshape(400,400), cmap='jet', extent=[0,20, 0,20]) # self.fig = plt.figure(figsize=(7.2,6)) # this strange figsize results in a ~square contour plot # self.fig = plt.figure(figsize=(24.0,20)) # this strange figsize results in a ~square contour plot self.fig = plt.figure(figsize=( 18.0, 15)) # this strange figsize results in a ~square contour plot # plt.rc('font', size=10) # TODO: does this affect the Cell plots fonts too? YES. Not what we want. # fig.set_tight_layout(True) # ax = plt.axes([0, 0.05, 0.9, 0.9 ]) #left, bottom, width, height # ax = plt.axes([0, 0.0, 1, 1 ]) # cmap = plt.cm.viridis # Blues, YlOrBr, ... # im = ax.imshow(f.reshape(100,100), interpolation='nearest', cmap=cmap, extent=[0,20, 0,20]) # ax.grid(False) # print("substrates.py: ------- numx, numy = ", self.numx, self.numy ) if (self.numx == 0): # need to parse vals from the config.xml fname = os.path.join(self.output_dir, "config.xml") tree = ET.parse(fname) xml_root = tree.getroot() xmin = float(xml_root.find(".//x_min").text) xmax = float(xml_root.find(".//x_max").text) dx = float(xml_root.find(".//dx").text) ymin = float(xml_root.find(".//y_min").text) ymax = float(xml_root.find(".//y_max").text) dy = float(xml_root.find(".//dy").text) self.numx = math.ceil((xmax - xmin) / dx) self.numy = math.ceil((ymax - ymin) / dy) xgrid = M[0, :].reshape(self.numy, self.numx) ygrid = M[1, :].reshape(self.numy, self.numx) num_contours = 15 levels = MaxNLocator(nbins=num_contours).tick_values( self.cmap_min.value, self.cmap_max.value) contour_ok = True if (self.cmap_fixed.value): try: my_plot = plt.contourf(xgrid, ygrid, M[self.field_index, :].reshape( self.numy, self.numx), levels=levels, extend='both', cmap=self.field_cmap.value, fontsize=self.fontsize) except: contour_ok = False # print('got error on contourf 1.') else: try: my_plot = plt.contourf(xgrid, ygrid, M[self.field_index, :].reshape( self.numy, self.numx), num_contours, cmap=self.field_cmap.value) except: contour_ok = False # print('got error on contourf 2.') if (contour_ok): plt.title(title_str, fontsize=self.fontsize) plt.tick_params(labelsize=self.fontsize) cbar = plt.colorbar(my_plot) cbar.ax.tick_params(labelsize=self.fontsize) axes_min = 0 axes_max = 2000
def create_checkbox(self, kind, description, value, handler): checkbox = Checkbox(value=value, description=description, indent=False) checkbox.observe(handler, "value") checkbox.add_class("view_%s" % kind) return checkbox
class PapayaConfigWidget(VBox): """A widget that displays widgets to adjust NLPapayaViewer image parameters.""" lut_options = [ "Grayscale", "Red Overlay", "Green Overlay", "Blue Overlay", "Gold", "Spectrum", "Overlay (Positives)", "Overlay (Negatives)", ] def __init__(self, viewer, *args, **kwargs): """ Parameters ---------- viewer: NlPapayaViewer associated viewer. """ super().__init__(*args, **kwargs) self._viewer = viewer self._init_widgets() self.children = [ VBox([ VBox( [self._hist], layout=Layout( height="auto", margin="0px 0px 0px 0px", padding="5px 5px 5px 5px", ), ), VBox( [ self._alpha, self._lut, self._nlut, self._min, self._minp, self._max, self._maxp, self._sym, ], layout=Layout(width="230px"), ), ]) ] def _init_widgets(self): """Initializes all configuration widgets. Possible image config parameters are:""" layout = Layout(width="200px", max_width="200px") self._alpha = FloatSlider( value=1, min=0, max=1.0, step=0.1, description="alpha:", description_tooltip="Overlay image alpha level (0 to 1).", disabled=False, continuous_update=True, orientation="horizontal", readout=True, readout_format=".1f", layout=layout, ) self._lut = Dropdown( options=PapayaConfigWidget.lut_options, value="Red Overlay", description="lut:", description_tooltip="The color table name.", layout=layout, ) self._nlut = Dropdown( options=PapayaConfigWidget.lut_options, value="Red Overlay", description="negative-lut:", description_tooltip= "The color table name used by the negative side of the parametric pair.", layout=layout, ) self._min = FloatText( value=None, description="min:", description_tooltip="The display range minimum.", step=0.01, continuous_update=True, disabled=False, layout=layout, ) self._minp = BoundedFloatText( value=None, min=0, max=100, step=1, continuous_update=True, description="min %:", description_tooltip= "The display range minimum as a percentage of image max.", disabled=False, layout=layout, ) self._max = FloatText( value=None, description="max:", description_tooltip="The display range maximum.", step=0.01, continuous_update=True, disabled=False, layout=layout, ) self._maxp = BoundedFloatText( value=None, min=0, max=100, step=1, continuous_update=True, description="max %:", description_tooltip= "The display range minimum as a percentage of image max.", disabled=False, layout=layout, ) self._sym = Checkbox( value=False, description="symmetric", description_tooltip= "When selected, sets the negative range of a parametric pair to the same size as the positive range.", disabled=False, layout=layout, ) # figure to display histogram of image data fig = Figure() fig.update_layout( height=300, margin=dict(l=15, t=15, b=15, r=15, pad=4), showlegend=True, legend_orientation="h", ) self._hist = FigureWidget(fig) self._hist.add_trace( Histogram(x=[], name="All image data", visible="legendonly")) self._hist.add_trace(Histogram(x=[], name="Image data without 0s")) self._handlers = defaultdict() def _set_values(self, config, range, data): """Sets config values from the specified `config` and creates histogram for `data`. Parameters ---------- config : dict configuration parameters for the image. Possible keywords are: alpha : int the overlay image alpha level (0 to 1). lut : str the color table name. negative_lut : str the color table name used by the negative side of the parametric pair. max : int the display range maximum. maxPercent : int the display range maximum as a percentage of image max. min : int the display range minimum. minPercent : int the display range minimum as a percentage of image min. symmetric : bool if true, sets the negative range of a parametric pair to the same size as the positive range. range: float range of image values. data: [] flattened image data. """ self._alpha.value = config.get("alpha", 1) self._lut.value = config.get("lut", PapayaConfigWidget.lut_options[1]) self._nlut.value = config.get("negative_lut", PapayaConfigWidget.lut_options[1]) self._min.value = config.get("min", 0) self._minp.value = self._get_per_from_value(range, config.get("min", 0)) self._max.value = config.get("max", 0.1) self._maxp.value = self._get_per_from_value(range, config.get("max", 0.1)) self._sym.value = config.get("symmetric", "false") == "true" # set histogram data self._hist.data[0].x = data # leave out 0 values self._hist.data[1].x = [] if (data == [] or data is None) else data[data != 0] def _add_handlers(self, image): """Add config widget event handlers to change the config values for the specified `image`. Parameters ---------- image: neurolang_ipywidgets.PapayaImage image whose config values will be viewed/modified using this config widget. """ # Dropdown does not support resetting event handlers after Dropdown.unobserve_all is called # So handlers are stored to be removed individually # github issue https://github.com/jupyter-widgets/ipywidgets/issues/1868 self._handlers["alpha"] = partial(self._config_changed, image=image, name="alpha") self._handlers["lut"] = partial(self._config_changed, image=image, name="lut") self._handlers["nlut"] = partial(self._config_changed, image=image, name="negative_lut") self._handlers["min"] = partial(self._config_changed, image=image, name="min") self._handlers["minp"] = partial(self._set_min_max, image=image, name="minPercent") self._handlers["max"] = partial(self._config_changed, image=image, name="max") self._handlers["maxp"] = partial(self._set_min_max, image=image, name="maxPercent") self._handlers["sym"] = partial(self._config_bool_changed, image=image, name="symmetric") self._alpha.observe(self._handlers["alpha"], names="value") self._lut.observe(self._handlers["lut"], names="value") self._nlut.observe(self._handlers["nlut"], names="value") self._min.observe(self._handlers["min"], names="value") self._minp.observe(self._handlers["minp"], names="value") self._max.observe(self._handlers["max"], names="value") self._maxp.observe(self._handlers["maxp"], names="value") self._sym.observe(self._handlers["sym"], names="value") def _remove_handlers(self): """Removes all event handlers set for the config widgets.""" if len(self._handlers): self._alpha.unobserve(self._handlers["alpha"], names="value") self._lut.unobserve(self._handlers["lut"], names="value") self._nlut.unobserve(self._handlers["nlut"], names="value") self._min.unobserve(self._handlers["min"], names="value") self._minp.unobserve(self._handlers["minp"], names="value") self._max.unobserve(self._handlers["max"], names="value") self._maxp.unobserve(self._handlers["maxp"], names="value") self._sym.unobserve(self._handlers["sym"], names="value") self._handlers = defaultdict() @debounce(0.5) def _config_changed(self, change, image, name): if name == "min": self._minp.unobserve(self._handlers["minp"], names="value") self._minp.value = self._get_per_from_value( image.range, change.new) self._minp.observe(self._handlers["minp"], names="value") elif name == "max": self._maxp.unobserve(self._handlers["maxp"], names="value") self._maxp.value = self._get_per_from_value( image.range, change.new) self._maxp.observe(self._handlers["maxp"], names="value") self._set_config(image, name, change.new) @debounce(0.5) def _set_min_max(self, change, image, name): if name == "minPercent": self._min.unobserve(self._handlers["min"], names="value") self._min.value = self._get_value_from_per(image.range, change.new) self._set_config(image, "min", self._min.value) self._min.observe(self._handlers["min"], names="value") elif name == "maxPercent": self._max.unobserve(self._handlers["max"], names="value") self._max.value = self._get_value_from_per(image.range, change.new) self._set_config(image, "max", self._max.value) self._max.observe(self._handlers["max"], names="value") def _config_bool_changed(self, change, image, name): value = "false" if change.new: value = "true" self._set_config(image, name, value) def _set_config(self, image, key, value): image.config[key] = value self._viewer.set_images() def _get_per_from_value(self, range, value): return round(value * 100 / range, 0) def _get_value_from_per(self, range, per): return round(per * range / 100, 2) def set_image(self, image): """Sets the image whose config values will be viewed/modified using this config widget. If image is `None`, all config values are reset. Parameters ---------- image: neurolang_ipywidgets.PapayaImage image whose config values will be viewed/modified using this config widget. """ if image: self._remove_handlers() self._set_values(image.config, image.range, image.image.get_fdata().flatten()) self._add_handlers(image) else: self.reset() def reset(self): """Resets values for all config widgets.""" self._remove_handlers() self._set_values({}, 100, []) self.layout.visibility = "hidden"
class NanoParticle(object): def __init__(self, border_color, xml_uep): # uep = unique entry point # self.xml_root = None # for debugging self.xml_uep = xml_uep tab_height = '500px' width_cell_params_units = '270px' np_tab_layout = Layout( width='800px', # border='2px solid black', height='350px', overflow_y='scroll') tab_layout = Layout( width='800px', # border='2px solid black', height=tab_height, overflow_y='scroll') # PK # half_conc_desc = '$T_{0.5}$' desc_style = {'description_width': '150px'} # vs. 'initial' # ec_50_desc = '$EC_{50}$' label_PK = Label('Pharmacokinetics:') pk_param_width = '270px' pd_param_width = '270px' constWidth = '180px' # box_layout=Layout(display='flex',flex_flow='column',align_items='stretch',border='1px solid black',width='30%') box_layout = Layout(border='1px solid ' + border_color) # ------------ disabled_flag = False self.diffusion_coefficient = HBox( [ BoundedFloatText( min=0, step=0.1, description='diffusion coefficient', layout=Layout(width=constWidth), ), Label('micron^2/min') ], layout=Layout(width=width_cell_params_units)) # option-m µm self.survival_lifetime = HBox( [ BoundedFloatText( min=0, max=1.e6, step=0.1, description='survival lifetime', layout=Layout(width=constWidth), ), Label('min') ], layout=Layout(width=width_cell_params_units)) self.ECM_binding_rate = HBox( [ BoundedFloatText( min=0, step=0.1, description='ECM binding rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units)) self.ECM_unbinding_rate = HBox( [ BoundedFloatText( min=0, step=0.1, description='ECM unbinding rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units)) self.ECM_saturation_concentration = HBox( [ BoundedFloatText( min=0, step=0.1, description='ECM saturation concentration', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) pk_widgets_width = '350px' self.PK_params = VBox( [ label_PK, self.diffusion_coefficient, self.survival_lifetime, # self.ECM_binding_rate, # self.ECM_unbinding_rate, # self.ECM_saturation_concentration, ], layout=box_layout) # -------------------------------------------- label_PD = Label('Pharmacodynamics:') self.effect_model_choice = Dropdown( # options=['1', '2', '3','4','5','6'], options={ 'Simple (conc)': 0, 'Intermed (AUC)': 1, 'Details (act/deact)': 2 }, value=0, disabled=True, # description='Field', layout=Layout(width=constWidth)) self.EC_50 = HBox([ BoundedFloatText( min=0, step=0.1, description='EC_50', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) self.Hill_power = HBox([ BoundedIntText( min=0, step=0.1, description='Hill power', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) self.mechanistic_response_rate = HBox( [ BoundedFloatText( min=0, step=0.1, description='mech resp rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units)) self.mechanistic_deactivation_rate = HBox( [ BoundedFloatText( min=0, step=0.1, description='mech deact rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units)) #------------------------------- self.enable_active_influx = Checkbox( description='Active Influx', layout=Layout(width=constWidth), ) self.enable_active_influx.observe(self.enable_active_influx_cb) self.relative_max_internal_concentration = HBox( [ BoundedFloatText( min=0, step=0.1, description='rel max int conc', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) self.internalization_rate = HBox( [ BoundedFloatText( min=0, step=0.1, description='intern rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units)) self.reference_external_concentration = HBox( [ BoundedFloatText( min=0, step=0.1, description='ref ext conc', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) #------------------------------- # label_cycle = Label('Cycle:') self.cycle_response = Checkbox( description='Cycle', disabled=False, layout=Layout(width=constWidth), ) self.cycle_response.observe(self.cycle_response_cb) self.max_birth_rate = HBox( [ BoundedFloatText( min=0, step=0.0001, disabled=disabled_flag, description='max birth rate', style={'description_width': 'initial'}, layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units)) self.o2_proliferation_saturation = HBox( [ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='o2: prolif sat', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) self.o2_proliferation_threshold = HBox( [ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='prolif thresh', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) self.o2_reference = HBox([ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='ref', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) self.glucose_proliferation_reference = HBox( [ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='Glc: prolif ref', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) self.glucose_proliferation_saturation = HBox( [ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='prolif sat', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) self.glucose_proliferation_threshold = HBox( [ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='prolif thresh', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) #------------------------------- self.necrosis_response = Label('Necrosis:') # self.necrosis_response= Checkbox( # description='Necrosis',disabled=disabled_flag, # layout=Layout(width=constWidth), # ='180px' # ) # self.necrosis_response.observe(self.necrosis_response_cb) self.max_necrosis_rate = HBox( [ BoundedFloatText( min=0, step=0.001, disabled=disabled_flag, description='max rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units)) self.o2_necrosis_threshold = HBox( [ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='o2: thresh', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) self.o2_necrosis_max = HBox( [ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='max', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) #------------------------------- self.apoptosis_response = Checkbox( description='Apoptosis', disabled=disabled_flag, layout=Layout(width=constWidth), ) self.apoptosis_response.observe(self.apoptosis_response_cb) self.apoptosis_rate = HBox( [ BoundedFloatText( min=0, step=0.001, disabled=disabled_flag, description='rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units)) #------------------------------- # TODO: enforce sum=1 # label_metabolism = Label('Metabolism (must sum to 1):') self.metabolism_response = Checkbox( description='Metabolism', disabled=True, layout=Layout(width=constWidth), ) self.metabolism_response.observe(self.metabolism_response_cb) # TODO: assert these next 2 values sum to 1.0 self.metab_aero = HBox( [ BoundedFloatText( min=0, max=1, step=0.1, description='Aerobic', disabled=True, #style={'description_width': 'initial'}, layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) self.metab_glyco = HBox( [ BoundedFloatText( min=0, max=1, step=0.1, description='Glycolytic', disabled=True, #style={'description_width': 'initial'}, layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) # metabolism_stuff = VBox([label_metabolism, HBox([self.metab_aero,self.metab_glyco])]) #------------------------------- # label_motility = Label('Motility:') self.motility_response = Checkbox( description='Motility', disabled=True, layout=Layout(width='200px'), ) self.motility_response.observe(self.motility_response_cb) self.is_motile = Checkbox( description='motile', disabled=True, layout=Layout(width='200px'), ) self.is_motile.observe(self.is_motile_cb) self.bias = HBox( [ BoundedFloatText( max=1, step=0.01, description= 'bias', # style={'description_width': 'initial'}, layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) # speed_units = HTMLMath(value=r"$\frac{\mu M^2}{min}$") speed_units = Label( 'micron/min') # use "option m" µ (Mac, for micro symbol) self.speed = HBox( [ BoundedFloatText( min=0, step=0.1, description='speed', layout=Layout(width=constWidth), ), speed_units ], layout=Layout(width='290px')) # width_cell_params_units = '270px' self.persistence_time = HBox( [ BoundedFloatText( min=0, step=0.1, description='persistence time', layout=Layout(width=constWidth), ), Label('min') ], layout=Layout(width=width_cell_params_units)) # taxis_gradient = u"\u2207" self.gradient_substrate_index = BoundedIntText( min=0, description='substrate index', style={'description_width': 'initial'}, layout=Layout(width='200px'), ) self.negative_taxis = RadioButtons( # options={u"\u2207" : 0, "-" + u"\u2207" : 1}, options={ "grad": 0, "-grad": 1 }, # {u"\u2207" : 0, "-" + u"\u2207" : 1}, value=0, description='', disabled=False) #------------------------------- self.mechanics_response = Checkbox( description='Mechanics', disabled=disabled_flag, layout=Layout(width=constWidth), ) self.mechanics_response.observe(self.mechanics_response_cb) self.max_relative_adhesion_distance = HBox( [ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description= 'Max adhesion distance', # style={'description_width': 'initial'}, layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) self.adhesion_strength = HBox( [ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description= 'Adhesion strength', # style={'description_width': 'initial'}, layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) self.repulsion_strength = HBox( [ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description= 'Repulsion strength', # style={'description_width': 'initial'}, layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) #------------------------------- label_hypoxia = Label('Hypoxia:') self.o2_hypoxic_threshold = HBox( [ BoundedFloatText( min=0, step=0.1, description='o2: threshold', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) self.o2_hypoxic_response = HBox( [ BoundedFloatText( min=0, step=0.1, description='response', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) self.o2_hypoxic_saturation = HBox( [ BoundedFloatText( min=0, step=0.1, description='saturation', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) #------------------------------- self.secretion_response = Checkbox( description='Secretion', disabled=disabled_flag, layout=Layout(width=constWidth), ) self.secretion_response.observe(self.secretion_response_cb) self.uptake_rate = [] self.secretion_rate = [] self.saturation_density = [] self.uptake_rate.append( HBox([ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='o2: uptake rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) self.uptake_rate.append( HBox([ BoundedFloatText( min=0, step=0.001, disabled=disabled_flag, description='Glc: uptake rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) self.uptake_rate.append( HBox([ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='H+: uptake rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) self.uptake_rate.append( HBox([ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='ECM: uptake rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) self.uptake_rate.append( HBox([ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='NP1: uptake rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) self.uptake_rate.append( HBox([ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='NP2: uptake rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) for idx in range(6): self.secretion_rate.append( HBox([ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='secretion rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) self.saturation_density.append( HBox([ BoundedFloatText( min=0, step=0.1, disabled=disabled_flag, description='saturation', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units))) row_secretion = [] for idx in range(2): row_secretion.append( HBox([ self.uptake_rate[idx], self.secretion_rate[idx], self.saturation_density[idx] ])) #---------------------------------------------------------- pd_box = VBox([ label_PD, self.effect_model_choice, self.EC_50, self.Hill_power, self.mechanistic_response_rate, self.mechanistic_deactivation_rate, ], layout=box_layout) influx_box = VBox([ self.enable_active_influx, self.relative_max_internal_concentration, self.internalization_rate, self.reference_external_concentration, ], layout=box_layout) cycle_box = VBox([ self.cycle_response, self.max_birth_rate, HBox([ self.o2_proliferation_saturation, self.o2_proliferation_threshold, self.o2_reference ]), HBox([ self.glucose_proliferation_reference, self.glucose_proliferation_saturation, self.glucose_proliferation_threshold ]), ], layout=box_layout) necrosis_box = VBox([ self.necrosis_response, self.max_necrosis_rate, self.o2_necrosis_threshold, self.o2_necrosis_max ], layout=box_layout) apoptosis_box = VBox([ self.apoptosis_response, HBox([self.apoptosis_rate]), ], layout=box_layout) metabolism_box = VBox([ self.metabolism_response, HBox([self.metab_aero, self.metab_glyco]), ], layout=box_layout) motility_box = VBox([ HBox([ self.motility_response, self.is_motile, self.gradient_substrate_index, self.negative_taxis ]), HBox([self.bias, self.speed, self.persistence_time]), ], layout=box_layout) mechanics_box = VBox([ self.mechanics_response, HBox([ self.max_relative_adhesion_distance, self.adhesion_strength, self.repulsion_strength ]), ], layout=box_layout) hypoxia_box = VBox([ label_hypoxia, HBox([ self.o2_hypoxic_threshold, self.o2_hypoxic_response, self.o2_hypoxic_saturation ]), ], layout=box_layout) secretion_box = VBox([ self.secretion_response, HBox([ self.uptake_rate[0], self.secretion_rate[0], self.saturation_density[0] ]), HBox([ self.uptake_rate[1], self.secretion_rate[1], self.saturation_density[1] ]), HBox([ self.uptake_rate[2], self.secretion_rate[2], self.saturation_density[2] ]), HBox([ self.uptake_rate[3], self.secretion_rate[3], self.saturation_density[3] ]), HBox([ self.uptake_rate[4], self.secretion_rate[4], self.saturation_density[4] ]), HBox([ self.uptake_rate[5], self.secretion_rate[5], self.saturation_density[5] ]) ], layout=box_layout) #----------- returns our tab contents at last --------------- self.tab = VBox([ self.PK_params, pd_box, influx_box, cycle_box, necrosis_box, apoptosis_box, metabolism_box, motility_box, mechanics_box, hypoxia_box, secretion_box ]) def is_motile_cb(self, b): if (self.is_motile.value): self.bias.children[0].disabled = False self.speed.children[0].disabled = False self.persistence_time.children[0].disabled = False self.negative_taxis.disabled = False else: self.bias.children[0].disabled = True self.speed.children[0].disabled = True self.persistence_time.children[0].disabled = True self.negative_taxis.disabled = True def enable_active_influx_cb(self, b): if (self.enable_active_influx.value): self.relative_max_internal_concentration.children[ 0].disabled = False self.internalization_rate.children[0].disabled = False self.reference_external_concentration.children[0].disabled = False else: self.relative_max_internal_concentration.children[ 0].disabled = True self.internalization_rate.children[0].disabled = True self.reference_external_concentration.children[0].disabled = True def cycle_response_cb(self, b): disabled_flag = True if (self.cycle_response.value): disabled_flag = False self.max_birth_rate.children[0].disabled = disabled_flag self.o2_proliferation_saturation.children[0].disabled = disabled_flag self.o2_proliferation_threshold.children[0].disabled = disabled_flag self.o2_reference.children[0].disabled = disabled_flag self.glucose_proliferation_reference.children[ 0].disabled = disabled_flag self.glucose_proliferation_saturation.children[ 0].disabled = disabled_flag self.glucose_proliferation_threshold.children[ 0].disabled = disabled_flag def apoptosis_response_cb(self, b): disabled_flag = True if (self.apoptosis_response.value): disabled_flag = False self.apoptosis_rate.children[0].disabled = disabled_flag def metabolism_response_cb(self, b): disabled_flag = True if (self.metabolism_response.value): disabled_flag = False def motility_response_cb(self, b): disabled_flag = True if (self.motility_response.value): disabled_flag = False self.is_motile.disabled = disabled_flag self.bias.children[0].disabled = disabled_flag self.gradient_substrate_index.disabled = disabled_flag self.negative_taxis.disabled = disabled_flag self.speed.children[0].disabled = disabled_flag self.persistence_time.children[0].disabled = disabled_flag def mechanics_response_cb(self, b): disabled_flag = True if (self.mechanics_response.value): disabled_flag = False self.max_relative_adhesion_distance.children[ 0].disabled = disabled_flag self.adhesion_strength.children[0].value = disabled_flag self.repulsion_strength.children[0].value = disabled_flag def secretion_response_cb(self, b): disabled_flag = True if (self.secretion_response.value): disabled_flag = False for idx in range(6): self.uptake_rate[idx].children[0].disabled = disabled_flag self.secretion_rate[idx].children[0].disabled = disabled_flag self.saturation_density[idx].children[0].disabled = disabled_flag #---------------------------------------- def fill_gui(self): # for NanoParticles - both Type1 and Type2 # self.xml_root = xml_root # for debugging # uep = xml_root.find('.//nanoparticle') # find unique entry point into XML uep = self.xml_uep # PK self.diffusion_coefficient.children[0].value = float( uep.find('.//diffusion_coefficient').text) self.survival_lifetime.children[0].value = float( uep.find('.//survival_lifetime').text) # PD self.ECM_binding_rate.children[0].value = float( uep.find('.//ECM_binding_rate').text) self.ECM_unbinding_rate.children[0].value = float( uep.find('.//ECM_unbinding_rate').text) self.ECM_saturation_concentration.children[0].value = float( uep.find('.//ECM_saturation_concentration').text) self.EC_50.children[0].value = float(uep.find('.//EC_50').text) self.Hill_power.children[0].value = float( uep.find('.//Hill_power').text) self.mechanistic_response_rate.children[0].value = float( uep.find('.//mechanistic_response_rate').text) self.mechanistic_deactivation_rate.children[0].value = float( uep.find('.//mechanistic_deactivation_rate').text) # active influx self.enable_active_influx.value = False if ((uep.find('.//enable_active_influx').text).lower() == 'true'): self.enable_active_influx.value = True self.enable_active_influx_cb(None) self.relative_max_internal_concentration.children[0].value = float( uep.find('.//relative_max_internal_concentration').text) self.internalization_rate.children[0].value = float( uep.find('.//internalization_rate').text) self.reference_external_concentration.children[0].value = float( uep.find('.//reference_external_concentration').text) # cycle self.cycle_response.value = False if ((uep.find('.//cycle').text).lower() == 'true'): self.cycle_response.value = True self.cycle_response_cb(None) self.max_birth_rate.children[0].value = float( uep.find('.//max_birth_rate').text) self.o2_proliferation_saturation.children[0].value = float( uep.find('.//o2_proliferation_saturation').text) self.o2_proliferation_threshold.children[0].value = float( uep.find('.//o2_proliferation_threshold').text) self.o2_reference.children[0].value = float( uep.find('.//o2_reference').text) self.glucose_proliferation_reference.children[0].value = float( uep.find('.//glucose_proliferation_reference').text) self.glucose_proliferation_saturation.children[0].value = float( uep.find('.//glucose_proliferation_saturation').text) self.glucose_proliferation_threshold.children[0].value = float( uep.find('.//glucose_proliferation_threshold').text) # necrosis self.max_necrosis_rate.children[0].value = float( uep.find('.//max_necrosis_rate').text) self.o2_necrosis_threshold.children[0].value = float( uep.find('.//o2_necrosis_threshold').text) self.o2_necrosis_max.children[0].value = float( uep.find('.//o2_necrosis_max').text) # apoptosis self.apoptosis_response.value = False if ((uep.find('.//apoptosis').text).lower() == 'true'): self.apoptosis_response.value = True self.apoptosis_response_cb(None) self.apoptosis_rate.children[0].value = float( uep.find('.//apoptosis_rate').text) # metabolism self.metabolism_response.value = False if ((uep.find('.//metabolism').text).lower() == 'true'): self.metabolism_response.value = True self.metabolism_response_cb(None) # motility self.motility_response.value = False if ((uep.find('.//motility').text).lower() == 'true'): self.motility_response.value = True self.motility_response_cb(None) self.is_motile.value = False if ((uep.find('.//is_motile').text).lower() == 'true'): self.is_motile.value = True self.is_motile_cb(None) self.gradient_substrate_index.value = int( uep.find('.//gradient_substrate_index').text) self.bias.children[0].value = float(uep.find('.//bias').text) # self.negative_taxis.value = bool(uep.find('.//negative_taxis').text) self.negative_taxis.value = 0 if ((uep.find('.//negative_taxis').text).lower() == "true"): self.negative_taxis.value = 1 self.speed.children[0].value = float(uep.find('.//speed').text) self.persistence_time.children[0].value = float( uep.find('.//persistence_time').text) # mechanics self.mechanics_response.value = False if ((uep.find('.//mechanics').text).lower() == 'true'): self.mechanics_response.value = True self.mechanics_response_cb(None) self.max_relative_adhesion_distance.children[0].value = float( uep.find('.//max_relative_adhesion_distance').text) self.adhesion_strength.children[0].value = float( uep.find('.//adhesion_strength').text) self.repulsion_strength.children[0].value = float( uep.find('.//repulsion_strength').text) # hypoxia self.o2_hypoxic_threshold.children[0].value = float( uep.find('.//o2_hypoxic_threshold').text) self.o2_hypoxic_response.children[0].value = float( uep.find('.//o2_hypoxic_response').text) self.o2_hypoxic_saturation.children[0].value = float( uep.find('.//o2_hypoxic_saturation').text) # secretion self.secretion_response.value = False if ((uep.find('.//secretion').text).lower() == 'true'): self.secretion_response.value = True self.secretion_response_cb(None) sep = uep.find('.//basic_phenotype').find( './/secretion' ) # secretion entry point (beware of same in previous "enabled_responses") idx = 0 for el in sep.findall( 'substrate'): # currently 6 substrates - find all of them kids = el.getchildren() # assume 3, which follow: self.uptake_rate[idx].children[0].value = float(kids[0].text) self.secretion_rate[idx].children[0].value = float(kids[1].text) self.saturation_density[idx].children[0].value = float( kids[2].text) idx += 1 # if idx == 2: # break def fill_xml(self, uep): # for NanoParticles - both Type1 and Type2 # uep = xml_root.find('.//nanoparticle') # find unique entry point into XML # uep = self.xml_uep # PK uep.find('.//diffusion_coefficient').text = str( self.diffusion_coefficient.children[0].value) uep.find('.//survival_lifetime').text = str( self.survival_lifetime.children[0].value) uep.find('.//ECM_binding_rate').text = str( self.ECM_binding_rate.children[0].value) uep.find('.//ECM_unbinding_rate').text = str( self.ECM_unbinding_rate.children[0].value) uep.find('.//ECM_saturation_concentration').text = str( self.ECM_saturation_concentration.children[0].value) # PD uep.find('.//EC_50').text = str(self.EC_50.children[0].value) uep.find('.//Hill_power').text = str(self.Hill_power.children[0].value) uep.find('.//mechanistic_response_rate').text = str( self.mechanistic_response_rate.children[0].value) uep.find('.//mechanistic_deactivation_rate').text = str( self.mechanistic_deactivation_rate.children[0].value) uep.find('.//enable_active_influx').text = "false" # active influx if (self.enable_active_influx.value): uep.find('.//enable_active_influx').text = "true" uep.find('.//relative_max_internal_concentration').text = str( self.relative_max_internal_concentration.children[0].value) uep.find('.//internalization_rate').text = str( self.internalization_rate.children[0].value) uep.find('.//reference_external_concentration').text = str( self.reference_external_concentration.children[0].value) # cycle uep.find('.//cycle').text = "false" if (self.cycle_response.value): uep.find('.//cycle').text = "true" uep.find('.//max_birth_rate').text = str( self.max_birth_rate.children[0].value) uep.find('.//o2_proliferation_saturation').text = str( self.o2_proliferation_saturation.children[0].value) uep.find('.//o2_proliferation_threshold').text = str( self.o2_proliferation_threshold.children[0].value) uep.find('.//o2_reference').text = str( self.o2_reference.children[0].value) uep.find('.//glucose_proliferation_reference').text = str( self.glucose_proliferation_reference.children[0].value) uep.find('.//glucose_proliferation_saturation').text = str( self.glucose_proliferation_saturation.children[0].value) uep.find('.//glucose_proliferation_threshold').text = str( self.glucose_proliferation_threshold.children[0].value) # necrosis uep.find('.//max_necrosis_rate').text = str( self.max_necrosis_rate.children[0].value) uep.find('.//o2_necrosis_threshold').text = str( self.o2_necrosis_threshold.children[0].value) uep.find('.//o2_necrosis_max').text = str( self.o2_necrosis_max.children[0].value) # apoptosis uep.find('.//apoptosis').text = "false" if (self.apoptosis_response.value): uep.find('.//apoptosis').text = "true" uep.find('.//apoptosis_rate').text = str( self.apoptosis_rate.children[0].value) # metabolism # motility uep.find('.//motility').text = "false" if (self.motility_response.value): uep.find('.//motility').text = "true" uep.find('.//is_motile').text = "false" if (self.is_motile.value): uep.find('.//is_motile').text = "true" uep.find('.//bias').text = str(self.bias.children[0].value) uep.find('.//negative_taxis').text = 'false' if (self.negative_taxis.value > 0): uep.find('.//negative_taxis').text = 'true' uep.find('.//speed').text = str(self.speed.children[0].value) uep.find('.//persistence_time').text = str( self.persistence_time.children[0].value) # mechanics uep.find('.//mechanics').text = "false" if (self.mechanics_response.value): uep.find('.//mechanics').text = "true" # hypoxia uep.find('.//o2_hypoxic_threshold').text = str( self.o2_hypoxic_threshold.children[0].value) uep.find('.//o2_hypoxic_response').text = str( self.o2_hypoxic_response.children[0].value) uep.find('.//o2_hypoxic_saturation').text = str( self.o2_hypoxic_saturation.children[0].value) # secretion uep.find('.//secretion').text = "false" if (self.secretion_response.value): uep.find('.//secretion').text = "true" sep = uep.find('.//basic_phenotype').find( './/secretion' ) # secretion entry point (beware of same in previous "enabled_responses") idx = 0 for el in sep.findall( 'substrate'): # currently 6 substrates - find all of them kids = el.getchildren() # assume 3, which follow: kids[0].text = str(self.uptake_rate[idx].children[0].value) kids[1].text = str(self.secretion_rate[idx].children[0].value) kids[2].text = str(self.saturation_density[idx].children[0].value) idx += 1
def _create_controls( self, time: types_timeindex, show_data_labels: bool, show_labels: bool, show_origins: bool, show_traces: bool, show_vectors: bool, show_wireframe: bool, ): """Create the control panel. Parameters ---------- time : pandas.DatetimeIndex, pandas.TimedeltaIndex, List[pandas.Timestamp], or \ LocalCoordinateSystem The time steps that should be plotted initially show_data_labels : bool If `True`, the data labels will be shown initially show_labels : bool If `True`, the coordinate system labels will be shown initially show_origins : bool If `True`, the coordinate systems' origins will be shown initially show_traces : bool If `True`, the coordinate systems' traces will be shown initially show_vectors : bool If `True`, the coordinate systems' axis vectors will be shown initially show_wireframe : bool If `True`, spatial data containing mesh data will be drawn as wireframe """ num_times = 1 disable_time_widgets = True lo = Layout(width="200px") # create widgets if time is not None: num_times = len(time) disable_time_widgets = False play = Play( min=0, max=num_times - 1, value=self._current_time_index, step=1, ) time_slider = IntSlider( min=0, max=num_times - 1, value=self._current_time_index, description="Time:", ) reference_dropdown = Dropdown( options=self._csm.coordinate_system_names, value=self._current_reference_system, description="Reference:", disabled=False, ) data_dropdown = Dropdown( options=SpatialDataVisualizer.visualization_methods, value="auto", description="data repr.:", disabled=False, layout=lo, ) lo = Layout(width="200px") vectors_cb = Checkbox(value=show_vectors, description="show vectors", layout=lo) origin_cb = Checkbox(value=show_origins, description="show origins", layout=lo) traces_cb = Checkbox(value=show_traces, description="show traces", layout=lo) labels_cb = Checkbox(value=show_labels, description="show labels", layout=lo) wf_cb = Checkbox(value=show_wireframe, description="show wireframe", layout=lo) data_labels_cb = Checkbox(value=show_data_labels, description="show data labels", layout=lo) jslink((play, "value"), (time_slider, "value")) play.disabled = disable_time_widgets time_slider.disabled = disable_time_widgets # callback functions def _reference_callback(change): self.update_reference_system(change["new"]) def _time_callback(change): self.update_time_index(change["new"]) def _vectors_callback(change): self.show_vectors(change["new"]) def _origins_callback(change): self.show_origins(change["new"]) def _traces_callback(change): self.show_traces(change["new"]) def _labels_callback(change): self.show_labels(change["new"]) def _data_callback(change): self.set_data_visualization_method(change["new"]) def _data_labels_callback(change): self.show_data_labels(change["new"]) def _wireframe_callback(change): self.show_wireframes(change["new"]) # register callbacks time_slider.observe(_time_callback, names="value") reference_dropdown.observe(_reference_callback, names="value") vectors_cb.observe(_vectors_callback, names="value") origin_cb.observe(_origins_callback, names="value") traces_cb.observe(_traces_callback, names="value") labels_cb.observe(_labels_callback, names="value") data_dropdown.observe(_data_callback, names="value") data_labels_cb.observe(_data_labels_callback, names="value") wf_cb.observe(_wireframe_callback, names="value") # create control panel row_1 = HBox([time_slider, play, reference_dropdown]) row_2 = HBox([vectors_cb, origin_cb, traces_cb, labels_cb]) if len(self._data_vis) > 0: row_3 = HBox([data_dropdown, wf_cb, data_labels_cb]) return VBox([row_1, row_2, row_3]) return VBox([row_1, row_2])
class ConfigTab(object): # def __init__(self): def __init__(self, xml_root): # micron_units = HTMLMath(value=r"$\mu M$") micron_units = Label( 'micron') # use "option m" (Mac, for micro symbol) # micron_units = Label('microns') # use "option m" (Mac, for micro symbol) constWidth = '180px' # tab_height = '400px' tab_height = '500px' # tab_layout = Layout(width='900px', # border='2px solid black', # tab_layout = Layout(width='850px', # border='2px solid black', # height=tab_height, overflow_y='scroll',) # np_tab_layout = Layout(width='800px', # border='2px solid black', # height='350px', overflow_y='scroll',) # my_domain = [0,0,-10, 2000,2000,10, 20,20,20] # [x,y,zmin, x,y,zmax, x,y,zdelta] # label_domain = Label('Domain ($\mu M$):') label_domain = Label('Domain (micron):') stepsize = 10 disable_domain = False self.xmin = FloatText( step=stepsize, # description='$X_{min}$', description='Xmin', disabled=disable_domain, layout=Layout(width=constWidth), ) self.ymin = FloatText( step=stepsize, description='Ymin', disabled=disable_domain, layout=Layout(width=constWidth), ) self.zmin = FloatText( step=stepsize, description='Zmin', disabled=disable_domain, layout=Layout(width=constWidth), ) self.xmax = FloatText( step=stepsize, description='Xmax', disabled=disable_domain, layout=Layout(width=constWidth), ) self.ymax = FloatText( step=stepsize, description='Ymax', disabled=disable_domain, layout=Layout(width=constWidth), ) self.zmax = FloatText( step=stepsize, description='Zmax', disabled=disable_domain, layout=Layout(width=constWidth), ) self.toggle_virtual_walls = Checkbox(description='Virtual walls', layout=Layout(width='350px')) # description='$Time_{max}$', self.tmax = BoundedFloatText( min=0., max=100000000, step=stepsize, description='Max Time', layout=Layout(width=constWidth), ) self.xdelta = BoundedFloatText( min=1., description='dx', # '∆x', # Mac: opt-j for delta disabled=disable_domain, layout=Layout(width=constWidth), ) self.ydelta = BoundedFloatText( min=1., description='dy', disabled=disable_domain, layout=Layout(width=constWidth), ) self.zdelta = BoundedFloatText( min=1., description='dz', disabled=disable_domain, layout=Layout(width=constWidth), ) """ self.tdelta = BoundedFloatText( min=0.01, description='$Time_{delta}$', layout=Layout(width=constWidth), ) """ """ self.toggle2D = Checkbox( description='2-D', layout=Layout(width=constWidth), ) def toggle2D_cb(b): if (self.toggle2D.value): #zmin.disabled = zmax.disabled = zdelta.disabled = True zmin.disabled = True zmax.disabled = True zdelta.disabled = True else: zmin.disabled = False zmax.disabled = False zdelta.disabled = False self.toggle2D.observe(toggle2D_cb) """ x_row = HBox([self.xmin, self.xmax, self.xdelta]) y_row = HBox([self.ymin, self.ymax, self.ydelta]) z_row = HBox([self.zmin, self.zmax, self.zdelta]) self.omp_threads = BoundedIntText( min=1, max=4, description='# threads', layout=Layout(width=constWidth), ) # self.toggle_prng = Checkbox( # description='Seed PRNG', style={'description_width': 'initial'}, # e.g. 'initial' '120px' # layout=Layout(width=constWidth), # ) # self.prng_seed = BoundedIntText( # min = 1, # description='Seed', # disabled=True, # layout=Layout(width=constWidth), # ) # def toggle_prng_cb(b): # if (toggle_prng.value): # self.prng_seed.disabled = False # else: # self.prng_seed.disabled = True # self.toggle_prng.observe(toggle_prng_cb) #prng_row = HBox([toggle_prng, prng_seed]) self.toggle_svg = Checkbox( description='Cells', # SVG layout=Layout(width='150px')) # constWidth = '180px' # self.svg_t0 = BoundedFloatText ( # min=0, # description='$T_0$', # layout=Layout(width=constWidth), # ) self.svg_interval = BoundedFloatText( min=0.001, max= 99999999, # TODO: set max on all Bounded to avoid unwanted default description='every', layout=Layout(width='160px'), ) self.mcds_interval = BoundedFloatText( min=0.001, max=99999999, description='every', # disabled=True, layout=Layout(width='160px'), ) # don't let this be > mcds interval def svg_interval_cb(b): if (self.svg_interval.value > self.mcds_interval.value): self.svg_interval.value = self.mcds_interval.value self.svg_interval.observe( svg_interval_cb) # BEWARE: when fill_gui, this sets value = 1 ! # don't let this be < svg interval def mcds_interval_cb(b): if (self.mcds_interval.value < self.svg_interval.value): self.mcds_interval.value = self.svg_interval.value self.mcds_interval.observe( mcds_interval_cb) # BEWARE: see warning above def toggle_svg_cb(b): if (self.toggle_svg.value): # self.svg_t0.disabled = False self.svg_interval.disabled = False else: # self.svg_t0.disabled = True self.svg_interval.disabled = True self.toggle_svg.observe(toggle_svg_cb) self.toggle_mcds = Checkbox( # value=False, description='Subtrates', # Full layout=Layout(width='180px'), ) # self.mcds_t0 = FloatText( # description='$T_0$', # disabled=True, # layout=Layout(width=constWidth), # ) def toggle_mcds_cb(b): if (self.toggle_mcds.value): # self.mcds_t0.disabled = False #False self.mcds_interval.disabled = False else: # self.mcds_t0.disabled = True self.mcds_interval.disabled = True self.toggle_mcds.observe(toggle_mcds_cb) svg_mat_output_row = HBox([ Label('Plots:'), self.toggle_svg, HBox([self.svg_interval, Label('min')]), self.toggle_mcds, HBox([self.mcds_interval, Label('min')]) ]) # to sync, do this # svg_mat_output_row = HBox( [Label('Plots:'), self.svg_interval, Label('min')]) #write_config_row = HBox([write_config_button, write_config_file]) #run_sim_row = HBox([run_button, run_command_str, kill_button]) # run_sim_row = HBox([run_button, run_command_str]) # run_sim_row = HBox([run_button.w]) # need ".w" for the custom RunCommand widget label_blankline = Label('') # toggle_2D_seed_row = HBox([toggle_prng, prng_seed]) # toggle2D def upload_done_cb(w, name): # Do something with the files here... # We just print their names print("%s uploaded" % name) # reset clears and re-enables the widget for more uploads # You may want to do this somewhere else, depending on your GUI w.reset() if (hublib_flag): self.csv_upload = FileUpload( '', 'Upload cells positions (.csv) from your local machine', dir='data', cb=upload_done_cb, maxsize='1M', # layout=Layout(width='350px') ) self.toggle_cells_csv = Checkbox(description='Enable .csv', layout=Layout(width='280px')) # layout=Layout(width='350px') ) def toggle_cells_csv_cb(b): # why can't I disable this widget?! # print('---- toggle_cells_csv_cb') if (hublib_flag): if (self.toggle_cells_csv.value): # self.csv_upload.w.disabled = False self.csv_upload.visible = True else: self.csv_upload.visible = False self.toggle_cells_csv.observe(toggle_cells_csv_cb) box_layout = Layout(border='1px solid') if (hublib_flag): upload_cells_hbox = HBox( [self.csv_upload.w, self.toggle_cells_csv], layout=Layout(border='1px solid', width='420px')) else: upload_cells_hbox = HBox([self.toggle_cells_csv], layout=Layout(border='1px solid', width='420px')) # domain_box = VBox([label_domain,x_row,y_row,z_row], layout=box_layout) uep = xml_root.find(".//options//virtual_wall_at_domain_edge") if uep: domain_box = VBox( [label_domain, x_row, y_row, self.toggle_virtual_walls], layout=box_layout) else: domain_box = VBox([label_domain, x_row, y_row], layout=box_layout) uep = xml_root.find(".//options//virtual_wall_at_domain_edge") if uep: self.tab = VBox([ domain_box, HBox([self.tmax, Label('min')]), self.omp_threads, svg_mat_output_row, label_blankline, # HBox([self.csv_upload.w, self.toggle_cells_csv]), upload_cells_hbox, # HBox([self.substrate[3], self.diffusion_coef[3], self.decay_rate[3] ]), # ], layout=tab_layout) # output_dir, toggle_2D_seed_ ]) else: self.tab = VBox([ domain_box, HBox([self.tmax, Label('min')]), self.omp_threads, svg_mat_output_row, ]) # Populate the GUI widgets with values from the XML def fill_gui(self, xml_root): self.xmin.value = float(xml_root.find(".//x_min").text) self.xmax.value = float(xml_root.find(".//x_max").text) self.xdelta.value = float(xml_root.find(".//dx").text) self.ymin.value = float(xml_root.find(".//y_min").text) self.ymax.value = float(xml_root.find(".//y_max").text) self.ydelta.value = float(xml_root.find(".//dy").text) self.zmin.value = float(xml_root.find(".//z_min").text) self.zmax.value = float(xml_root.find(".//z_max").text) self.zdelta.value = float(xml_root.find(".//dz").text) uep = xml_root.find(".//options//virtual_wall_at_domain_edge") if uep and (uep.text.lower() == 'true'): self.toggle_virtual_walls.value = True else: self.toggle_virtual_walls.value = False self.tmax.value = float(xml_root.find(".//max_time").text) self.omp_threads.value = int(xml_root.find(".//omp_num_threads").text) if xml_root.find(".//full_data//enable").text.lower() == 'true': self.toggle_mcds.value = True else: self.toggle_mcds.value = False self.mcds_interval.value = float( xml_root.find(".//full_data//interval").text) # NOTE: do this *after* filling the mcds_interval, directly above, due to the callback/constraints on them if xml_root.find(".//SVG//enable").text.lower() == 'true': self.toggle_svg.value = True else: self.toggle_svg.value = False self.svg_interval.value = float(xml_root.find(".//SVG//interval").text) # if xml_root.find(".//initial_conditions//cell_positions").attrib["enabled"].lower() == 'true': uep = xml_root.find(".//initial_conditions//cell_positions") if uep: if uep.attrib["enabled"].lower() == 'true': self.toggle_cells_csv.value = True else: self.toggle_cells_csv.value = False self.toggle_cells_csv.description = xml_root.find( ".//initial_conditions//cell_positions//filename").text # Read values from the GUI widgets and generate/write a new XML def fill_xml(self, xml_root): # print('config.py fill_xml() !!!!!') # TODO: verify template .xml file exists! # TODO: verify valid type (numeric) and range? 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) if xml_root.find(".//options//virtual_wall_at_domain_edge"): xml_root.find( ".//options//virtual_wall_at_domain_edge").text = str( self.toggle_virtual_walls.value).lower() xml_root.find(".//max_time").text = str(self.tmax.value) xml_root.find(".//omp_num_threads").text = str(self.omp_threads.value) xml_root.find(".//SVG").find(".//enable").text = str( self.toggle_svg.value) xml_root.find(".//SVG").find(".//interval").text = str( self.svg_interval.value) xml_root.find(".//full_data").find(".//enable").text = str( self.toggle_mcds.value) xml_root.find(".//full_data").find(".//interval").text = str( self.mcds_interval.value) # uep.find('.//cell_definition[1]//phenotype//mechanics//options//set_absolute_equilibrium_distance').attrib['enabled'] = str(self.bool1.value) # xml_root.find(".//initial_conditions//cell_positions").attrib["enabled"] = str(self.toggle_cells_csv.value) uep = xml_root.find(".//initial_conditions//cell_positions") if uep: uep.attrib["enabled"] = str(self.toggle_cells_csv.value) # user_details = ET.SubElement(root, "user_details") # ET.SubElement(user_details, "PhysiCell_settings", name="version").text = "devel-version" # ET.SubElement(user_details, "domain") # ET.SubElement(user_details, "xmin").text = "-100" # tree = ET.ElementTree(root) # tree.write(write_config_file.value) # tree.write("test.xml") # TODO: verify can write to this filename # tree.write(write_config_file.value) def get_num_svg_frames(self): if (self.toggle_svg.value): return int(self.tmax.value / self.svg_interval.value) else: return 0 def get_num_substrate_frames(self): if (self.toggle_mcds.value): return int(self.tmax.value / self.mcds_interval.value) else: return 0
def widget_box(): """Update the repository. Args: None Returns: update_widget : A widget for general settings. Raises: Error: Example: """ # User settings user_info = Label("General settings.") values = config.read() user_name = Text(value=values['set']['user'], placeholder='user name', description='User:'******'set']['email'], placeholder='[email protected]', description='email:', disabled=False) user_institution = Text(value=values['set']['institution'], placeholder='EU-', description='Institution:', disabled=False) ms_list = data_options.eu_ms() ms = Dropdown( options=[(ms_list[m], m) for m in ms_list] + [('', '')], value=values['set']['member_state'], description='Member state:', disabled=False, ) wbox_user = VBox([user_info, user_name, user_email, user_institution, ms], layout=Layout(border='1px solid black')) # System settings sys_info = Label("System settings.") paths_info = Label( "Select the personal data folder and the temporary folder.") jupyterlab = Checkbox( value=eval(values['set']['jupyterlab']), description= 'Workin in Jupyter Lab (Uncheck for Voila and classical jupyter environment)', disabled=False, indent=False) def on_jupyterlab_change(change): config.update(['set', 'jupyterlab'], str(jupyterlab.value)) jupyterlab.observe(on_jupyterlab_change, 'value') path_data = Text(value=values['paths']['data'], description='Data path:') path_temp = Text(value=values['paths']['temp'], description='Temp path:') files_info = Label("Select where to store the parcel IDs list file from:") file_pids_poly = Text(value=values['files']['pids_poly'], description='Polygon:') file_pids_dist = Text(value=values['files']['pids_dist'], description='Distance:') plimit_info = Label( "Warning: No more than 25 parcels are tested, unexpected results may occur." ) plimit = BoundedIntText(value=int(values['set']['plimit']), max=100_000_000, min=1, step=1, description='Max parcels that can be downloaded:', disabled=False) wbox_sys = VBox([ sys_info, jupyterlab, plimit_info, plimit, paths_info, path_data, path_temp, files_info, file_pids_poly, file_pids_dist ], layout=Layout(border='1px solid black')) # Git settings git_info = Label( "Git Settings. (To easily get the latest version of notebooks and scripts.)" ) git_url, git_user, git_pass = config.credentials('git') git_url = Text(value=git_url, description='Url:') git_user = Text(value=git_user, description='User name:') git_pass = Password(value=git_pass, placeholder='******', description='Password:'******'1px solid black')) btn_save = Button(description='Save', disabled=False, icon='save') progress = Output() def outlog(*text): with progress: print(*text) @btn_save.on_click def btn_save_on_click(b): progress.clear_output() config.update(['set', 'user'], str(user_name.value)) config.update(['set', 'email'], str(user_email.value)) config.update(['set', 'institution'], str(user_institution.value)) config.update(['set', 'member_state'], str(user_email.value)) config.update(['set', 'plimit'], str(plimit.value)) config.update(['git', 'url'], str(git_url.value)) config.update(['git', 'user'], str(git_user.value)) config.update(['paths', 'data'], str(path_data.value)) config.update(['paths', 'temp'], str(path_temp.value)) config.update(['files', 'pids_poly'], str(file_pids_poly.value)) config.update(['files', 'pids_dist'], str(file_pids_dist.value)) if git_pass.value != '': config.update(['git', 'pass'], str(git_pass.value)) outlog("The new settings are saved.") wbox = VBox([ config.clean_temp(), wbox_user, wbox_sys, wbox_git, HBox([btn_save, update.btn_update()]), progress ]) return wbox
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}, disabled=True, 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', disabled=True, # 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=True, # 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=True, value=False, # 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(str(full_xml_filename)) # this file cannot be overwritten; part of tool distro xml_root = tree.getroot() self.svg_delta_t = float(xml_root.find(".//SVG//interval").text) self.substrate_delta_t = float(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 # 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 # self.cmap_max.value = self.field_min_max[field_name][1] # oxygen, etc # self.field_index = self.mcds_field.value + 4 # print('field_index=',self.field_index) self.i_plot.update() #--------------------------------------------------------------------------- def circles(self, x, y, s, c='b', vmin=None, vmax=None, **kwargs): """ See https://gist.github.com/syrte/592a062c562cd2a98a83 Make a scatter plot of circles. Similar to plt.scatter, but the size of circles are in data scale. Parameters ---------- x, y : scalar or array_like, shape (n, ) Input data s : scalar or array_like, shape (n, ) Radius of circles. c : color or sequence of color, optional, default : 'b' `c` can be a single color format string, or a sequence of color specifications of length `N`, or a sequence of `N` numbers to be mapped to colors using the `cmap` and `norm` specified via kwargs. Note that `c` should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped. (If you insist, use `color` instead.) `c` can be a 2-D array in which the rows are RGB or RGBA, however. vmin, vmax : scalar, optional, default: None `vmin` and `vmax` are used in conjunction with `norm` to normalize luminance data. If either are `None`, the min and max of the color array is used. kwargs : `~matplotlib.collections.Collection` properties Eg. alpha, edgecolor(ec), facecolor(fc), linewidth(lw), linestyle(ls), norm, cmap, transform, etc. Returns ------- paths : `~matplotlib.collections.PathCollection` Examples -------- a = np.arange(11) circles(a, a, s=a*0.2, c=a, alpha=0.5, ec='none') plt.colorbar() License -------- This code is under [The BSD 3-Clause License] (http://opensource.org/licenses/BSD-3-Clause) """ if np.isscalar(c): kwargs.setdefault('color', c) c = None if 'fc' in kwargs: kwargs.setdefault('facecolor', kwargs.pop('fc')) if 'ec' in kwargs: kwargs.setdefault('edgecolor', kwargs.pop('ec')) if 'ls' in kwargs: kwargs.setdefault('linestyle', kwargs.pop('ls')) if 'lw' in kwargs: kwargs.setdefault('linewidth', kwargs.pop('lw')) # You can set `facecolor` with an array for each patch, # while you can only set `facecolors` with a value for all. zipped = np.broadcast(x, y, s) patches = [Circle((x_, y_), s_) for x_, y_, s_ in zipped] collection = PatchCollection(patches, **kwargs) if c is not None: c = np.broadcast_to(c, zipped.shape).ravel() collection.set_array(c) collection.set_clim(vmin, vmax) ax = plt.gca() ax.add_collection(collection) ax.autoscale_view() # plt.draw_if_interactive() if c is not None: plt.sci(collection) # return collection #------------------------------------------------------------ # def plot_svg(self, frame, rdel=''): def plot_svg(self, frame): # global current_idx, axes_max global current_frame current_frame = frame fname = "snapshot%08d.svg" % frame full_fname = os.path.join(self.output_dir, fname) # with debug_view: # print("plot_svg:", full_fname) # print("-- plot_svg:", full_fname) if not os.path.isfile(full_fname): print("Once output files are generated, click the slider.") return xlist = deque() ylist = deque() rlist = deque() rgb_list = deque() # print('\n---- ' + fname + ':') # tree = ET.parse(fname) tree = ET.parse(full_fname) root = tree.getroot() # print('--- root.tag ---') # print(root.tag) # print('--- root.attrib ---') # print(root.attrib) # print('--- child.tag, child.attrib ---') numChildren = 0 for child in root: # print(child.tag, child.attrib) # print("keys=",child.attrib.keys()) if self.use_defaults and ('width' in child.attrib.keys()): self.axes_max = float(child.attrib['width']) # print("debug> found width --> axes_max =", axes_max) if child.text and "Current time" in child.text: svals = child.text.split() # remove the ".00" on minutes self.title_str += " cells: " + svals[2] + "d, " + svals[4] + "h, " + svals[7][:-3] + "m" # self.cell_time_mins = int(svals[2])*1440 + int(svals[4])*60 + int(svals[7][:-3]) # self.title_str += " cells: " + str(self.cell_time_mins) + "m" # rwh # print("width ",child.attrib['width']) # print('attrib=',child.attrib) # if (child.attrib['id'] == 'tissue'): if ('id' in child.attrib.keys()): # print('-------- found tissue!!') tissue_parent = child break # print('------ search tissue') cells_parent = None for child in tissue_parent: # print('attrib=',child.attrib) if (child.attrib['id'] == 'cells'): # print('-------- found cells, setting cells_parent') cells_parent = child break numChildren += 1 num_cells = 0 # print('------ search cells') for child in cells_parent: # print(child.tag, child.attrib) # print('attrib=',child.attrib) for circle in child: # two circles in each child: outer + nucleus # circle.attrib={'cx': '1085.59','cy': '1225.24','fill': 'rgb(159,159,96)','r': '6.67717','stroke': 'rgb(159,159,96)','stroke-width': '0.5'} # print(' --- cx,cy=',circle.attrib['cx'],circle.attrib['cy']) xval = float(circle.attrib['cx']) # map SVG coords into comp domain # xval = (xval-self.svg_xmin)/self.svg_xrange * self.x_range + self.xmin xval = xval/self.x_range * self.x_range + self.xmin s = circle.attrib['fill'] # print("s=",s) # print("type(s)=",type(s)) if (s[0:3] == "rgb"): # if an rgb string, e.g. "rgb(175,175,80)" rgb = list(map(int, s[4:-1].split(","))) rgb[:] = [x / 255. for x in rgb] else: # otherwise, must be a color name rgb_tuple = mplc.to_rgb(mplc.cnames[s]) # a tuple rgb = [x for x in rgb_tuple] # test for bogus x,y locations (rwh TODO: use max of domain?) too_large_val = 10000. if (np.fabs(xval) > too_large_val): print("bogus xval=", xval) break yval = float(circle.attrib['cy']) # yval = (yval - self.svg_xmin)/self.svg_xrange * self.y_range + self.ymin yval = yval/self.y_range * self.y_range + self.ymin if (np.fabs(yval) > too_large_val): print("bogus xval=", xval) break rval = float(circle.attrib['r']) # if (rgb[0] > rgb[1]): # print(num_cells,rgb, rval) xlist.append(xval) ylist.append(yval) rlist.append(rval) rgb_list.append(rgb) # For .svg files with cells that *have* a nucleus, there will be a 2nd if (not self.show_nucleus): #if (not self.show_nucleus): break num_cells += 1 # if num_cells > 3: # for debugging # print(fname,': num_cells= ',num_cells," --- debug exit.") # sys.exit(1) # break # print(fname,': num_cells= ',num_cells) xvals = np.array(xlist) yvals = np.array(ylist) rvals = np.array(rlist) rgbs = np.array(rgb_list) # print("xvals[0:5]=",xvals[0:5]) # print("rvals[0:5]=",rvals[0:5]) # print("rvals.min, max=",rvals.min(),rvals.max()) # rwh - is this where I change size of render window?? (YES - yipeee!) # plt.figure(figsize=(6, 6)) # plt.cla() # if (self.substrates_toggle.value): self.title_str += " (" + str(num_cells) + " agents)" # title_str = " (" + str(num_cells) + " agents)" # else: # mins= round(int(float(root.find(".//current_time").text))) # TODO: check units = mins # hrs = int(mins/60) # days = int(hrs/24) # title_str = '%dd, %dh, %dm' % (int(days),(hrs%24), mins - (hrs*60)) plt.title(self.title_str) plt.xlim(self.xmin, self.xmax) plt.ylim(self.ymin, self.ymax) # plt.xlim(axes_min,axes_max) # plt.ylim(axes_min,axes_max) # plt.scatter(xvals,yvals, s=rvals*scale_radius, c=rgbs) # TODO: make figsize a function of plot_size? What about non-square plots? # self.fig = plt.figure(figsize=(9, 9)) # axx = plt.axes([0, 0.05, 0.9, 0.9]) # left, bottom, width, height # axx = fig.gca() # print('fig.dpi=',fig.dpi) # = 72 # im = ax.imshow(f.reshape(100,100), interpolation='nearest', cmap=cmap, extent=[0,20, 0,20]) # ax.xlim(axes_min,axes_max) # ax.ylim(axes_min,axes_max) # convert radii to radii in pixels # ax2 = self.fig.gca() # N = len(xvals) # rr_pix = (ax2.transData.transform(np.vstack([rvals, rvals]).T) - # ax2.transData.transform(np.vstack([np.zeros(N), np.zeros(N)]).T)) # rpix, _ = rr_pix.T # markers_size = (144. * rpix / self.fig.dpi)**2 # = (2*rpix / fig.dpi * 72)**2 # markers_size = markers_size/4000000. # print('max=',markers_size.max()) #rwh - temp fix - Ah, error only occurs when "edges" is toggled on if (self.show_edge): try: # plt.scatter(xvals,yvals, s=markers_size, c=rgbs, edgecolor='black', linewidth=0.5) self.circles(xvals,yvals, s=rvals, color=rgbs, edgecolor='black', linewidth=0.5) # cell_circles = self.circles(xvals,yvals, s=rvals, color=rgbs, edgecolor='black', linewidth=0.5) # plt.sci(cell_circles) except (ValueError): pass else: # plt.scatter(xvals,yvals, s=markers_size, c=rgbs) self.circles(xvals,yvals, s=rvals, color=rgbs) # if (self.show_tracks): # for key in self.trackd.keys(): # xtracks = self.trackd[key][:,0] # ytracks = self.trackd[key][:,1] # plt.plot(xtracks[0:frame],ytracks[0:frame], linewidth=5) # plt.xlim(self.axes_min, self.axes_max) # plt.ylim(self.axes_min, self.axes_max) # ax.grid(False) # axx.set_title(title_str) # plt.title(title_str) #--------------------------------------------------------------------------- # assume "frame" is cell frame #, unless Cells is togggled off, then it's the substrate frame # # def plot_substrate(self, frame, grid): def plot_substrate(self, frame): # global current_idx, axes_max, gFileId, field_index # print("plot_substrate(): frame*self.substrate_delta_t = ",frame*self.substrate_delta_t) # print("plot_substrate(): frame*self.svg_delta_t = ",frame*self.svg_delta_t) self.title_str = '' # Recall: # 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) # self.therapy_activation_time = user_params_tab.therapy_activation_time.value # print("plot_substrate(): pre_therapy: max svg, substrate frames = ",max_svg_frame_pre_therapy, max_substrate_frame_pre_therapy) # Assume: # .svg files >= # substrate files # if (self.cells_toggle.value): # if (self.substrates_toggle.value and frame*self.substrate_delta_t <= self.svg_frame*self.svg_delta_t): # if (self.substrates_toggle.value and (frame % self.modulo == 0)): if (self.substrates_toggle.value): # self.fig = plt.figure(figsize=(14, 15.6)) # self.fig = plt.figure(figsize=(15.0, 12.5)) self.fig = plt.figure(figsize=(self.figsize_width_substrate, self.figsize_height_substrate)) # rwh - funky way to figure out substrate frame for pc4cancerbots (due to user-defined "save_interval*") # self.cell_time_mins # self.substrate_frame = int(frame / self.modulo) if (self.customized_output_freq and (frame > self.max_svg_frame_pre_therapy)): # max_svg_frame_pre_therapy = int(self.therapy_activation_time/self.svg_delta_t) # max_substrate_frame_pre_therapy = int(self.therapy_activation_time/self.substrate_delta_t) self.substrate_frame = self.max_substrate_frame_pre_therapy + (frame - self.max_svg_frame_pre_therapy) else: self.substrate_frame = int(frame / self.modulo) # print("plot_substrate(): self.substrate_frame=",self.substrate_frame) # if (self.substrate_frame > (self.num_substrates-1)): # self.substrate_frame = self.num_substrates-1 # print('self.substrate_frame = ',self.substrate_frame) # if (self.cells_toggle.value): # self.modulo = int((self.num_svgs - 1) / (self.num_substrates - 1)) # self.substrate_frame = frame % self.modulo # else: # self.substrate_frame = frame fname = "output%08d_microenvironment0.mat" % self.substrate_frame xml_fname = "output%08d.xml" % self.substrate_frame # fullname = output_dir_str + fname # fullname = fname full_fname = os.path.join(self.output_dir, fname) # print("--- plot_substrate(): full_fname=",full_fname) full_xml_fname = os.path.join(self.output_dir, xml_fname) # self.output_dir = '.' # if not os.path.isfile(fullname): if not os.path.isfile(full_fname): print("Once output files are generated, click the slider.") # No: output00000000_microenvironment0.mat return # tree = ET.parse(xml_fname) tree = ET.parse(full_xml_fname) xml_root = tree.getroot() mins = round(int(float(xml_root.find(".//current_time").text))) # TODO: check units = mins self.substrate_mins= round(int(float(xml_root.find(".//current_time").text))) # TODO: check units = mins hrs = int(mins/60) days = int(hrs/24) self.title_str = 'substrate: %dd, %dh, %dm' % (int(days),(hrs%24), mins - (hrs*60)) # self.title_str = 'substrate: %dm' % (mins ) # rwh info_dict = {} # scipy.io.loadmat(fullname, info_dict) scipy.io.loadmat(full_fname, info_dict) M = info_dict['multiscale_microenvironment'] # global_field_index = int(mcds_field.value) # print('plot_substrate: field_index =',field_index) f = M[self.field_index, :] # 4=tumor cells field, 5=blood vessel density, 6=growth substrate # plt.clf() # my_plot = plt.imshow(f.reshape(400,400), cmap='jet', extent=[0,20, 0,20]) # self.fig = plt.figure(figsize=(18.0,15)) # this strange figsize results in a ~square contour plot # plt.subplot(grid[0:1, 0:1]) # main_ax = self.fig.add_subplot(grid[0:1, 0:1]) # works, but tiny upper-left region #main_ax = self.fig.add_subplot(grid[0:2, 0:2]) # main_ax = self.fig.add_subplot(grid[0:, 0:2]) #main_ax = self.fig.add_subplot(grid[:-1, 0:]) # nrows, ncols #main_ax = self.fig.add_subplot(grid[0:, 0:]) # nrows, ncols #main_ax = self.fig.add_subplot(grid[0:4, 0:]) # nrows, ncols # main_ax = self.fig.add_subplot(grid[0:3, 0:]) # nrows, ncols # main_ax = self.fig.add_subplot(111) # nrows, ncols # plt.rc('font', size=10) # TODO: does this affect the Cell plots fonts too? YES. Not what we want. # fig.set_tight_layout(True) # ax = plt.axes([0, 0.05, 0.9, 0.9 ]) #left, bottom, width, height # ax = plt.axes([0, 0.0, 1, 1 ]) # cmap = plt.cm.viridis # Blues, YlOrBr, ... # im = ax.imshow(f.reshape(100,100), interpolation='nearest', cmap=cmap, extent=[0,20, 0,20]) # ax.grid(False) # print("substrates.py: ------- numx, numy = ", self.numx, self.numy ) # if (self.numx == 0): # need to parse vals from the config.xml # # print("--- plot_substrate(): full_fname=",full_fname) # fname = os.path.join(self.output_dir, "config.xml") # tree = ET.parse(fname) # xml_root = tree.getroot() # self.xmin = float(xml_root.find(".//x_min").text) # self.xmax = float(xml_root.find(".//x_max").text) # dx = float(xml_root.find(".//dx").text) # self.ymin = float(xml_root.find(".//y_min").text) # self.ymax = float(xml_root.find(".//y_max").text) # dy = float(xml_root.find(".//dy").text) # self.numx = math.ceil( (self.xmax - self.xmin) / dx) # self.numy = math.ceil( (self.ymax - self.ymin) / dy) try: xgrid = M[0, :].reshape(self.numy, self.numx) ygrid = M[1, :].reshape(self.numy, self.numx) except: print("substrates.py: mismatched mesh size for reshape: numx,numy=",self.numx, self.numy) pass # xgrid = M[0, :].reshape(self.numy, self.numx) # ygrid = M[1, :].reshape(self.numy, self.numx) num_contours = 15 levels = MaxNLocator(nbins=num_contours).tick_values(self.cmap_min.value, self.cmap_max.value) contour_ok = True if (self.cmap_fixed_toggle.value): try: # substrate_plot = main_ax.contourf(xgrid, ygrid, M[self.field_index, :].reshape(self.numy, self.numx), levels=levels, extend='both', cmap=self.field_cmap.value, fontsize=self.fontsize) substrate_plot = plt.contourf(xgrid, ygrid, M[self.field_index, :].reshape(self.numy, self.numx), levels=levels, extend='both', cmap=self.field_cmap.value, fontsize=self.fontsize) except: contour_ok = False # print('got error on contourf 1.') else: try: # substrate_plot = main_ax.contourf(xgrid, ygrid, M[self.field_index, :].reshape(self.numy,self.numx), num_contours, cmap=self.field_cmap.value) substrate_plot = plt.contourf(xgrid, ygrid, M[self.field_index, :].reshape(self.numy,self.numx), num_contours, cmap=self.field_cmap.value) except: contour_ok = False # print('got error on contourf 2.') if (contour_ok): # main_ax.set_title(self.title_str, fontsize=self.fontsize) plt.title(self.title_str, fontsize=self.fontsize) # main_ax.tick_params(labelsize=self.fontsize) # cbar = plt.colorbar(my_plot) # cbar = self.fig.colorbar(substrate_plot, ax=main_ax) cbar = self.fig.colorbar(substrate_plot) cbar.ax.tick_params(labelsize=self.fontsize) # cbar = main_ax.colorbar(my_plot) # cbar.ax.tick_params(labelsize=self.fontsize) # axes_min = 0 # axes_max = 2000 # main_ax.set_xlim([self.xmin, self.xmax]) # main_ax.set_ylim([self.ymin, self.ymax]) plt.xlim(self.xmin, self.xmax) plt.ylim(self.ymin, self.ymax) # if (frame == 0): # maybe allow substrate grid display later # xs = np.linspace(self.xmin,self.xmax,self.numx) # ys = np.linspace(self.ymin,self.ymax,self.numy) # hlines = np.column_stack(np.broadcast_arrays(xs[0], ys, xs[-1], ys)) # vlines = np.column_stack(np.broadcast_arrays(xs, ys[0], xs, ys[-1])) # grid_lines = np.concatenate([hlines, vlines]).reshape(-1, 2, 2) # line_collection = LineCollection(grid_lines, color="gray", linewidths=0.5) # # ax = main_ax.gca() # main_ax.add_collection(line_collection) # # ax.set_xlim(xs[0], xs[-1]) # # ax.set_ylim(ys[0], ys[-1]) # Now plot the cells (possibly on top of the substrate) if (self.cells_toggle.value): if (not self.substrates_toggle.value): # self.fig = plt.figure(figsize=(12, 12)) self.fig = plt.figure(figsize=(self.figsize_width_svg, self.figsize_height_svg)) # self.plot_svg(frame) self.svg_frame = frame # print('plot_svg with frame=',self.svg_frame) self.plot_svg(self.svg_frame)
class ConfigTab(object): def __init__(self): # micron_units = HTMLMath(value=r"$\mu M$") micron_units = Label( 'micron') # use "option m" (Mac, for micro symbol) # micron_units = Label('microns') # use "option m" (Mac, for micro symbol) constWidth = '180px' # tab_height = '400px' tab_height = '500px' # tab_layout = Layout(width='900px', # border='2px solid black', # tab_layout = Layout(width='850px', # border='2px solid black', # height=tab_height, overflow_y='scroll',) # np_tab_layout = Layout(width='800px', # border='2px solid black', # height='350px', overflow_y='scroll',) # my_domain = [0,0,-10, 2000,2000,10, 20,20,20] # [x,y,zmin, x,y,zmax, x,y,zdelta] # label_domain = Label('Domain ($\mu M$):') label_domain = Label('Domain (micron):') stepsize = 10 self.xmin = FloatText( step=stepsize, # description='$X_{min}$', description='Xmin', layout=Layout(width=constWidth), ) self.ymin = FloatText( step=stepsize, description='Ymin', layout=Layout(width=constWidth), ) self.zmin = FloatText( step=stepsize, description='Zmin', layout=Layout(width=constWidth), ) self.xmax = FloatText( step=stepsize, description='Xmax', layout=Layout(width=constWidth), ) self.ymax = FloatText( step=stepsize, description='Ymax', layout=Layout(width=constWidth), ) self.zmax = FloatText( step=stepsize, description='Zmax', layout=Layout(width=constWidth), ) # description='$Time_{max}$', self.tmax = BoundedFloatText( min=0., max=100000000, step=stepsize, description='Max Time', layout=Layout(width=constWidth), ) self.xdelta = BoundedFloatText( min=1., description='dx', # '∆x', # Mac: opt-j for delta layout=Layout(width=constWidth), ) self.ydelta = BoundedFloatText( min=1., description='dy', layout=Layout(width=constWidth), ) self.zdelta = BoundedFloatText( min=1., description='dz', layout=Layout(width=constWidth), ) """ self.tdelta = BoundedFloatText( min=0.01, description='$Time_{delta}$', layout=Layout(width=constWidth), ) """ """ self.toggle2D = Checkbox( description='2-D', layout=Layout(width=constWidth), ) def toggle2D_cb(b): if (self.toggle2D.value): #zmin.disabled = zmax.disabled = zdelta.disabled = True zmin.disabled = True zmax.disabled = True zdelta.disabled = True else: zmin.disabled = False zmax.disabled = False zdelta.disabled = False self.toggle2D.observe(toggle2D_cb) """ x_row = HBox([self.xmin, self.xmax, self.xdelta]) y_row = HBox([self.ymin, self.ymax, self.ydelta]) z_row = HBox([self.zmin, self.zmax, self.zdelta]) self.tumor_radius = BoundedFloatText( min=0, max=99999, # TODO - wth, defaults to 100? step=1, description='Tumor Radius', style={'description_width': 'initial'}, layout=Layout(width=constWidth), ) self.omp_threads = BoundedIntText( min=1, description='# threads', layout=Layout(width=constWidth), ) # self.toggle_prng = Checkbox( # description='Seed PRNG', style={'description_width': 'initial'}, # e.g. 'initial' '120px' # layout=Layout(width=constWidth), # ) # self.prng_seed = BoundedIntText( # min = 1, # description='Seed', # disabled=True, # layout=Layout(width=constWidth), # ) # def toggle_prng_cb(b): # if (toggle_prng.value): # self.prng_seed.disabled = False # else: # self.prng_seed.disabled = True # self.toggle_prng.observe(toggle_prng_cb) #prng_row = HBox([toggle_prng, prng_seed]) self.toggle_svg = Checkbox( description='Cells', # SVG layout=Layout(width='150px')) # constWidth = '180px' # self.svg_t0 = BoundedFloatText ( # min=0, # description='$T_0$', # layout=Layout(width=constWidth), # ) self.svg_interval = BoundedIntText( min=1, max= 99999999, # TODO: set max on all Bounded to avoid unwanted default description='every', layout=Layout(width='160px'), ) def toggle_svg_cb(b): if (self.toggle_svg.value): # self.svg_t0.disabled = False self.svg_interval.disabled = False else: # self.svg_t0.disabled = True self.svg_interval.disabled = True self.toggle_svg.observe(toggle_svg_cb) self.toggle_mcds = Checkbox( # value=False, description='Subtrates', # Full layout=Layout(width='180px'), ) # self.mcds_t0 = FloatText( # description='$T_0$', # disabled=True, # layout=Layout(width=constWidth), # ) self.mcds_interval = BoundedIntText( min=0, max=99999999, description='every', # disabled=True, layout=Layout(width='160px'), ) def toggle_mcds_cb(b): if (self.toggle_mcds.value): # self.mcds_t0.disabled = False #False self.mcds_interval.disabled = False else: # self.mcds_t0.disabled = True self.mcds_interval.disabled = True self.toggle_mcds.observe(toggle_mcds_cb) #svg_output_row = HBox([toggle_svg, svg_t0, svg_interval]) #mat_output_row = HBox([toggle_mcds, mcds_t0, mcds_interval]) # svg_mat_output_row = HBox([self.toggle_svg, self.svg_interval, self.toggle_mcds, self.mcds_interval]) svg_mat_output_row = HBox([ Label('Plots:'), self.toggle_svg, HBox([self.svg_interval, Label('min')]), self.toggle_mcds, HBox([self.mcds_interval, Label('min')]) ]) #write_config_row = HBox([write_config_button, write_config_file]) #run_sim_row = HBox([run_button, run_command_str, kill_button]) # run_sim_row = HBox([run_button, run_command_str]) # run_sim_row = HBox([run_button.w]) # need ".w" for the custom RunCommand widget label_blankline = Label('') tumor_radius2 = HBox([self.tumor_radius, micron_units]) # toggle_2D_seed_row = HBox([toggle_prng, prng_seed]) # toggle2D label_substrates = Label('Substrates:') self.substrate = [] self.diffusion_coef = [] self.decay_rate = [] width_cell_params_units = '510px' width_cell_params_units = '380px' disable_substrates_flag = False self.substrate.append( HBox([ BoundedFloatText( min=0, step=0.1, disabled=True, value=38, description='o2: ', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units))) self.substrate.append( HBox([ BoundedFloatText( min=0, step=0.1, disabled=True, value=1, description='Glc: ', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units))) self.substrate.append( HBox([ BoundedFloatText( min=0, step=0.1, disabled=True, value=7.25, description='H+: ', layout=Layout(width=constWidth), ), Label('pH') ], layout=Layout(width=width_cell_params_units))) self.substrate.append( HBox([ BoundedFloatText( min=0, step=0.1, disabled=True, value=1.0, description='ECM: ', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units))) # self.substrate.append( HBox([BoundedFloatText(min=0, step=0.1, # description='NP1: ', layout=Layout(width=constWidth), ), ], # layout=Layout(width=width_cell_params_units)) ) # self.substrate.append( HBox([BoundedFloatText(min=0, step=0.1, # description='NP2: ', layout=Layout(width=constWidth), ), ], # layout=Layout(width=width_cell_params_units)) ) width_cell_params_units = '450px' width_cell_params_units = '400px' # for idx in range(4): self.diffusion_coef.append( HBox([ BoundedFloatText( min=0, max=999999, step=10.0, description='diffusion coef', disabled=disable_substrates_flag, layout=Layout(width=constWidth), ), Label('micron^2/min') ], layout=Layout(width=width_cell_params_units))) self.diffusion_coef.append( HBox([ BoundedFloatText( min=0, max=999999, step=10.0, description='diffusion coef', disabled=disable_substrates_flag, layout=Layout(width=constWidth), ), Label('micron^2/min') ], layout=Layout(width=width_cell_params_units))) self.diffusion_coef.append( HBox([ BoundedFloatText( min=0, max=999999, step=10.0, description='diffusion coef', disabled=disable_substrates_flag, layout=Layout(width=constWidth), ), Label('micron^2/min') ], layout=Layout(width=width_cell_params_units))) width_cell_params_units = '400px' width_cell_params_units = '380px' self.decay_rate.append( HBox([ BoundedFloatText( min=0, step=0.01, description='decay rate', disabled=disable_substrates_flag, layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) self.decay_rate.append( HBox([ BoundedFloatText( min=0, step=0.00001, description='decay rate', disabled=disable_substrates_flag, layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) self.decay_rate.append( HBox([ BoundedFloatText( min=0, step=0.01, description='decay rate', disabled=disable_substrates_flag, layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) box_layout = Layout(border='1px solid') domain_box = VBox([label_domain, x_row, y_row, z_row], layout=box_layout) substrates_box = VBox([ label_substrates, HBox([ self.substrate[0], self.diffusion_coef[0], self.decay_rate[0] ]), HBox([ self.substrate[1], self.diffusion_coef[1], self.decay_rate[1] ]), HBox([ self.substrate[2], self.diffusion_coef[2], self.decay_rate[2] ]) ], layout=box_layout) self.tab = VBox([ domain_box, # label_blankline, HBox([self.tmax, Label('min')]), self.omp_threads, tumor_radius2, svg_mat_output_row, substrates_box, # HBox([self.substrate[3], self.diffusion_coef[3], self.decay_rate[3] ]), ]) # output_dir, toggle_2D_seed_ # ], layout=tab_layout) # output_dir, toggle_2D_seed_ # Populate the GUI widgets with values from the XML def fill_gui(self, xml_root): self.xmin.value = float(xml_root.find(".//x_min").text) self.xmax.value = float(xml_root.find(".//x_max").text) self.xdelta.value = float(xml_root.find(".//dx").text) self.ymin.value = float(xml_root.find(".//y_min").text) self.ymax.value = float(xml_root.find(".//y_max").text) self.ydelta.value = float(xml_root.find(".//dy").text) self.zmin.value = float(xml_root.find(".//z_min").text) self.zmax.value = float(xml_root.find(".//z_max").text) self.zdelta.value = float(xml_root.find(".//dz").text) self.tmax.value = float(xml_root.find(".//max_time").text) self.tumor_radius.value = float(xml_root.find(".//radius").text) self.omp_threads.value = int(xml_root.find(".//omp_num_threads").text) self.toggle_svg.value = bool( xml_root.find(".//SVG").find(".//enable").text) self.svg_interval.value = int( xml_root.find(".//SVG").find(".//interval").text) self.toggle_mcds.value = bool( xml_root.find(".//full_data").find(".//enable").text) self.mcds_interval.value = int( xml_root.find(".//full_data").find(".//interval").text) # TODO: don't hardwire these values, i.e. don't assume ordered elms in xml child = xml_root.find('substrates').getchildren() # self.substrate[idx].children[0].value = float(kids[0].text) # oxygen self.diffusion_coef[0].children[0].value = float(child[0][0][0].text) self.decay_rate[0].children[0].value = float(child[0][0][1].text) # glucose self.diffusion_coef[1].children[0].value = float(child[1][0][0].text) self.decay_rate[1].children[0].value = float(child[1][0][1].text) # H+ self.diffusion_coef[2].children[0].value = float(child[2][0][0].text) self.decay_rate[2].children[0].value = float(child[2][0][1].text) # Read values from the GUI widgets and generate/write a new XML def fill_xml(self, xml_root): # TODO: verify template .xml file exists! # tree = ET.parse('nanobio_settings.xml') # tree = ET.parse('nanobio_settings2.xml') # root = tree.getroot() # TODO: verify valid type (numeric) and range? 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) xml_root.find(".//max_time").text = str(self.tmax.value) xml_root.find(".//omp_num_threads").text = str(self.omp_threads.value) xml_root.find(".//radius").text = str(self.tumor_radius.value) xml_root.find(".//SVG").find(".//enable").text = str( self.toggle_svg.value) xml_root.find(".//SVG").find(".//interval").text = str( self.svg_interval.value) xml_root.find(".//full_data").find(".//enable").text = str( self.toggle_mcds.value) xml_root.find(".//full_data").find(".//interval").text = str( self.mcds_interval.value) # TODO: don't hardwire child = xml_root.find('substrates').getchildren() child[0][0][0].text = str(self.diffusion_coef[0].children[0].value) child[1][0][0].text = str(self.diffusion_coef[1].children[0].value) child[2][0][0].text = str(self.diffusion_coef[2].children[0].value) child[0][0][1].text = str(self.decay_rate[0].children[0].value) child[1][0][1].text = str(self.decay_rate[1].children[0].value) child[2][0][1].text = str(self.decay_rate[2].children[0].value) # user_details = ET.SubElement(root, "user_details") # ET.SubElement(user_details, "PhysiCell_settings", name="version").text = "devel-version" # ET.SubElement(user_details, "domain") # ET.SubElement(user_details, "xmin").text = "-100" # tree = ET.ElementTree(root) # tree.write(write_config_file.value) # tree.write("test.xml") # TODO: verify can write to this filename # tree.write(write_config_file.value) def get_num_svg_frames(self): if (self.toggle_svg.value): return int(self.tmax.value / self.svg_interval.value) else: return 0 def get_num_substrate_frames(self): if (self.toggle_mcds.value): return int(self.tmax.value / self.mcds_interval.value) else: return 0
class ConfigTab(object): def __init__(self): # micron_units = HTMLMath(value=r"$\mu M$") micron_units = Label('micron') # use "option m" (Mac, for micro symbol) # micron_units = Label('microns') # use "option m" (Mac, for micro symbol) constWidth = '180px' # tab_height = '400px' tab_height = '500px' # tab_layout = Layout(width='900px', # border='2px solid black', # tab_layout = Layout(width='850px', # border='2px solid black', # height=tab_height, overflow_y='scroll',) # np_tab_layout = Layout(width='800px', # border='2px solid black', # height='350px', overflow_y='scroll',) # my_domain = [0,0,-10, 2000,2000,10, 20,20,20] # [x,y,zmin, x,y,zmax, x,y,zdelta] # label_domain = Label('Domain ($\mu M$):') label_domain = Label('Domain (micron):') stepsize = 10 self.xmin = FloatText(step=stepsize, # description='$X_{min}$', description='Xmin', layout=Layout(width=constWidth), ) self.ymin = FloatText(step=stepsize, description='Ymin', layout=Layout(width=constWidth), ) self.zmin = FloatText(step=stepsize, description='Zmin', layout=Layout(width=constWidth), ) self.xmax = FloatText(step=stepsize, description='Xmax', layout=Layout(width=constWidth), ) self.ymax = FloatText(step=stepsize, description='Ymax', layout=Layout(width=constWidth), ) self.zmax = FloatText(step=stepsize, description='Zmax', layout=Layout(width=constWidth), ) # description='$Time_{max}$', self.tmax = BoundedFloatText( min=0., max=100000000, step=stepsize, description='Max Time', layout=Layout(width=constWidth), ) self.xdelta = BoundedFloatText( min=1., description='dx', # '∆x', # Mac: opt-j for delta layout=Layout(width=constWidth), ) self.ydelta = BoundedFloatText( min=1., description='dy', layout=Layout(width=constWidth), ) self.zdelta = BoundedFloatText( min=1., description='dz', layout=Layout(width=constWidth), ) """ self.tdelta = BoundedFloatText( min=0.01, description='$Time_{delta}$', layout=Layout(width=constWidth), ) """ """ self.toggle2D = Checkbox( description='2-D', layout=Layout(width=constWidth), ) def toggle2D_cb(b): if (self.toggle2D.value): #zmin.disabled = zmax.disabled = zdelta.disabled = True zmin.disabled = True zmax.disabled = True zdelta.disabled = True else: zmin.disabled = False zmax.disabled = False zdelta.disabled = False self.toggle2D.observe(toggle2D_cb) """ x_row = HBox([self.xmin, self.xmax, self.xdelta]) y_row = HBox([self.ymin, self.ymax, self.ydelta]) z_row = HBox([self.zmin, self.zmax, self.zdelta]) self.omp_threads = BoundedIntText( min=1, description='# threads', layout=Layout(width=constWidth), ) # self.toggle_prng = Checkbox( # description='Seed PRNG', style={'description_width': 'initial'}, # e.g. 'initial' '120px' # layout=Layout(width=constWidth), # ) # self.prng_seed = BoundedIntText( # min = 1, # description='Seed', # disabled=True, # layout=Layout(width=constWidth), # ) # def toggle_prng_cb(b): # if (toggle_prng.value): # self.prng_seed.disabled = False # else: # self.prng_seed.disabled = True # self.toggle_prng.observe(toggle_prng_cb) #prng_row = HBox([toggle_prng, prng_seed]) self.toggle_svg = Checkbox( description='Cells', # SVG layout=Layout(width='150px') ) # constWidth = '180px' # self.svg_t0 = BoundedFloatText ( # min=0, # description='$T_0$', # layout=Layout(width=constWidth), # ) self.svg_interval = BoundedIntText( min=1, max=99999999, # TODO: set max on all Bounded to avoid unwanted default description='every', layout=Layout(width='160px'), ) def toggle_svg_cb(b): if (self.toggle_svg.value): # self.svg_t0.disabled = False self.svg_interval.disabled = False else: # self.svg_t0.disabled = True self.svg_interval.disabled = True self.toggle_svg.observe(toggle_svg_cb) self.toggle_mcds = Checkbox( # value=False, description='Subtrates', # Full layout=Layout(width='180px'), ) # self.mcds_t0 = FloatText( # description='$T_0$', # disabled=True, # layout=Layout(width=constWidth), # ) self.mcds_interval = BoundedIntText( min=0, max=99999999, description='every', # disabled=True, layout=Layout(width='160px'), ) def toggle_mcds_cb(b): if (self.toggle_mcds.value): # self.mcds_t0.disabled = False #False self.mcds_interval.disabled = False else: # self.mcds_t0.disabled = True self.mcds_interval.disabled = True self.toggle_mcds.observe(toggle_mcds_cb) #svg_output_row = HBox([toggle_svg, svg_t0, svg_interval]) #mat_output_row = HBox([toggle_mcds, mcds_t0, mcds_interval]) # svg_mat_output_row = HBox([self.toggle_svg, self.svg_interval, self.toggle_mcds, self.mcds_interval]) svg_mat_output_row = HBox([Label('Plots:'),self.toggle_svg, HBox([self.svg_interval,Label('min')]), self.toggle_mcds, HBox([self.mcds_interval,Label('min')]) ]) #write_config_row = HBox([write_config_button, write_config_file]) #run_sim_row = HBox([run_button, run_command_str, kill_button]) # run_sim_row = HBox([run_button, run_command_str]) # run_sim_row = HBox([run_button.w]) # need ".w" for the custom RunCommand widget label_blankline = Label('') # toggle_2D_seed_row = HBox([toggle_prng, prng_seed]) # toggle2D box_layout = Layout(border='1px solid') # domain_box = VBox([label_domain,x_row,y_row,z_row], layout=box_layout) domain_box = VBox([label_domain,x_row,y_row], layout=box_layout) self.tab = VBox([domain_box, # label_blankline, HBox([self.tmax, Label('min')]), self.omp_threads, svg_mat_output_row, # HBox([self.substrate[3], self.diffusion_coef[3], self.decay_rate[3] ]), ]) # output_dir, toggle_2D_seed_ # ], layout=tab_layout) # output_dir, toggle_2D_seed_ # Populate the GUI widgets with values from the XML def fill_gui(self, xml_root): self.xmin.value = float(xml_root.find(".//x_min").text) self.xmax.value = float(xml_root.find(".//x_max").text) self.xdelta.value = float(xml_root.find(".//dx").text) self.ymin.value = float(xml_root.find(".//y_min").text) self.ymax.value = float(xml_root.find(".//y_max").text) self.ydelta.value = float(xml_root.find(".//dy").text) self.zmin.value = float(xml_root.find(".//z_min").text) self.zmax.value = float(xml_root.find(".//z_max").text) self.zdelta.value = float(xml_root.find(".//dz").text) self.tmax.value = float(xml_root.find(".//max_time").text) self.omp_threads.value = int(xml_root.find(".//omp_num_threads").text) self.toggle_svg.value = bool(xml_root.find(".//SVG").find(".//enable").text) self.svg_interval.value = int(xml_root.find(".//SVG").find(".//interval").text) self.toggle_mcds.value = bool(xml_root.find(".//full_data").find(".//enable").text) self.mcds_interval.value = int(xml_root.find(".//full_data").find(".//interval").text) # Read values from the GUI widgets and generate/write a new XML def fill_xml(self, xml_root): # TODO: verify template .xml file exists! # TODO: verify valid type (numeric) and range? 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) xml_root.find(".//max_time").text = str(self.tmax.value) xml_root.find(".//omp_num_threads").text = str(self.omp_threads.value) xml_root.find(".//SVG").find(".//enable").text = str(self.toggle_svg.value) xml_root.find(".//SVG").find(".//interval").text = str(self.svg_interval.value) xml_root.find(".//full_data").find(".//enable").text = str(self.toggle_mcds.value) xml_root.find(".//full_data").find(".//interval").text = str(self.mcds_interval.value) # user_details = ET.SubElement(root, "user_details") # ET.SubElement(user_details, "PhysiCell_settings", name="version").text = "devel-version" # ET.SubElement(user_details, "domain") # ET.SubElement(user_details, "xmin").text = "-100" # tree = ET.ElementTree(root) # tree.write(write_config_file.value) # tree.write("test.xml") # TODO: verify can write to this filename # tree.write(write_config_file.value) def get_num_svg_frames(self): if (self.toggle_svg.value): return int(self.tmax.value/self.svg_interval.value) else: return 0 def get_num_substrate_frames(self): if (self.toggle_mcds.value): return int(self.tmax.value/self.mcds_interval.value) else: return 0
class CellsTab(object): def __init__(self): constWidth = '180px' #width_cell_params_units = '240px' width_cell_params_units = '270px' self.cell_name = Text( value='untreated cancer', disabled=False, description='Cell line name', style={'description_width': 'initial'}, ) #------------------------------- label_cycle = Label('Cycle:') self.max_birth_rate = HBox( [ BoundedFloatText( min=0, step=0.0001, description='max birth rate', style={'description_width': 'initial'}, layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units)) self.o2_proliferation_saturation = HBox( [ BoundedFloatText( min=0, step=0.1, description='O2: prolif sat', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) self.o2_proliferation_threshold = HBox( [ BoundedFloatText( min=0, step=0.1, description='prolif thresh', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) self.o2_reference = HBox([ BoundedFloatText( min=0, step=0.1, description='ref', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) self.glucose_proliferation_reference = HBox( [ BoundedFloatText( min=0, step=0.1, description='Glc: prolif ref', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) self.glucose_proliferation_saturation = HBox( [ BoundedFloatText( min=0, step=0.1, description='prolif sat', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) self.glucose_proliferation_threshold = HBox( [ BoundedFloatText( min=0, step=0.1, description='prolif thresh', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) #------------------------------- label_necrosis = Label('Necrosis:') self.max_necrosis_rate = HBox( [ BoundedFloatText( min=0, step=0.001, description='max rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units)) self.o2_necrosis_threshold = HBox( [ BoundedFloatText( min=0, step=0.1, description='O2: thresh', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) self.o2_necrosis_max = HBox( [ BoundedFloatText( min=0, step=0.1, description='max', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) #------------------------------- label_apoptosis = Label('Apoptosis:') self.apoptosis_rate = HBox( [ BoundedFloatText( min=0, step=0.00001, description='rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units)) #------------------------------- # TODO: enforce sum=1 label_metabolism = Label('Metabolism (must sum to 1):') # TODO: assert these next 2 values sum to 1.0 self.relative_aerobic_effects = HBox( [ BoundedFloatText( min=0, max=1, step=0.1, disabled=True, description= 'Aerobic', #style={'description_width': 'initial'}, layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) self.relative_glycolytic_effects = HBox( [ BoundedFloatText( min=0, max=1, step=0.1, disabled=True, description= 'Glycolytic', #style={'description_width': 'initial'}, layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) #------------------------------- label_motility = Label('Motility:') self.is_motile = Checkbox( description='motile', disabled=False, layout=Layout(width=constWidth), ) self.bias = HBox( [ BoundedFloatText( max=1, step=0.01, description= 'bias', # style={'description_width': 'initial'}, layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) # speed_units = HTMLMath(value=r"$\frac{\mu M^2}{min}$") speed_units = Label( 'micron/min') # use "option m" (Mac, for micro symbol) self.speed = HBox([ BoundedFloatText( min=0, step=0.1, description='speed', layout=Layout(width=constWidth), ), speed_units ], layout=Layout(width=width_cell_params_units)) self.persistence_time = HBox( [ BoundedFloatText( min=0, step=0.1, description='persistence time', layout=Layout(width=constWidth), ), Label('min') ], layout=Layout(width=width_cell_params_units)) # constWidt = '180px' self.gradient_substrate_index = BoundedIntText( min=0, value=0, disabled=False, description='substrate index', style={'description_width': 'initial'}, layout=Layout(width='160px'), ) self.negative_taxis = RadioButtons( options={ "grad": 0, "-grad": 1 }, # {u"\u2207" : 0, "-" + u"\u2207" : 1}, value=0, disabled=True, description='', ) self.is_motile.observe(self.is_motile_cb) #------------------------------- label_mechanics = Label('Mechanics:') self.max_relative_adhesion_distance = HBox( [ BoundedFloatText( min=0, step=0.1, #max=1, description= 'Max adhesion distance', # style={'description_width': 'initial'}, layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) self.adhesion_strength = HBox( [ BoundedFloatText( min=0, step=0.1, #max=1, description= 'Adhesion strength', # style={'description_width': 'initial'}, layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) self.repulsion_strength = HBox( [ BoundedFloatText( min=0, step=0.1, #max=1, description= 'Repulsion strength', # style={'description_width': 'initial'}, layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units)) #------------------------------- label_hypoxia = Label('Hypoxia:') self.o2_hypoxic_threshold = HBox( [ BoundedFloatText( min=0, step=0.1, description='O2: threshold', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) self.o2_hypoxic_response = HBox( [ BoundedFloatText( min=0, step=0.1, description='response', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) self.o2_hypoxic_saturation = HBox( [ BoundedFloatText( min=0, step=0.1, description='saturation', layout=Layout(width=constWidth), ), Label('mmHg') ], layout=Layout(width=width_cell_params_units)) #------------------------------- label_secretion = Label('Secretion:') self.uptake_rate = [] self.secretion_rate = [] self.saturation_density = [] self.uptake_rate.append( HBox([ BoundedFloatText( min=0, step=0.1, description='O2: uptake rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) self.uptake_rate.append( HBox([ BoundedFloatText( min=0, step=0.01, description='Glc: uptake rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) self.uptake_rate.append( HBox([ BoundedFloatText( min=0, step=0.1, description='pH: uptake rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) self.uptake_rate.append( HBox([ BoundedFloatText( min=0, step=0.1, description='ECM: uptake rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) self.uptake_rate.append( HBox([ BoundedFloatText( min=0, step=0.1, description='NP1: uptake rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) # self.uptake_rate.append( HBox([BoundedFloatText(min=0, step=0.1, # description='NP2: uptake rate', layout=Layout(width=constWidth), ), Label('1/min')], # layout=Layout(width=width_cell_params_units)) ) for idx in range(6): self.secretion_rate.append( HBox([ BoundedFloatText( min=0, step=0.1, description='secretion rate', layout=Layout(width=constWidth), ), Label('1/min') ], layout=Layout(width=width_cell_params_units))) self.saturation_density.append( HBox([ BoundedFloatText( min=0, step=0.1, description='saturation', layout=Layout(width=constWidth), ), ], layout=Layout(width=width_cell_params_units))) row1 = HBox([self.max_birth_rate]) row2 = HBox([ self.o2_proliferation_saturation, self.o2_proliferation_threshold, self.o2_reference ]) row2b = HBox([ self.glucose_proliferation_reference, self.glucose_proliferation_saturation, self.glucose_proliferation_threshold ]) row3 = HBox([self.max_necrosis_rate]) row4 = HBox([self.o2_necrosis_threshold, self.o2_necrosis_max]) row_secretion = [] for idx in range(2): row_secretion.append( HBox([ self.uptake_rate[idx], self.secretion_rate[idx], self.saturation_density[idx] ])) # row12 = HBox([self.uptake_rate[1], self.secretion_rate[1], self.saturation_density[1] ]) # row13 = HBox([self.uptake_rate3, self.secretion_rate3, self.saturation_density3 ]) # row14 = HBox([self.uptake_rate4, self.secretion_rate4, self.saturation_density4 ]) # row15 = HBox([self.uptake_rate5, self.secretion_rate5, self.saturation_density5 ]) # row16 = HBox([self.uptake_rate6, self.secretion_rate6, self.saturation_density6 ]) box_layout = Layout(border='1px solid') cycle_box = VBox([label_cycle, row1, row2, row2b], layout=box_layout) necrosis_box = VBox([label_necrosis, row3, row4], layout=box_layout) apoptosis_box = VBox( [label_apoptosis, HBox([self.apoptosis_rate])], layout=box_layout) metabolism_box = VBox([ label_metabolism, HBox([ self.relative_aerobic_effects, self.relative_glycolytic_effects ]) ], layout=box_layout) motility_box = VBox([ HBox([ label_motility, self.is_motile, self.gradient_substrate_index, self.negative_taxis, ]), HBox([self.bias, self.speed, self.persistence_time]), ], layout=box_layout) mechanics_box = VBox([ label_mechanics, HBox([ self.max_relative_adhesion_distance, self.adhesion_strength, self.repulsion_strength ]) ], layout=box_layout) hypoxia_box = VBox([ label_hypoxia, HBox([ self.o2_hypoxic_threshold, self.o2_hypoxic_response, self.o2_hypoxic_saturation ]) ], layout=box_layout) secretion_box = VBox( [ label_secretion, HBox([ self.uptake_rate[0], self.secretion_rate[0], self.saturation_density[0] ]), HBox([ self.uptake_rate[1], self.secretion_rate[1], self.saturation_density[1] ]), HBox([ self.uptake_rate[2], self.secretion_rate[2], self.saturation_density[2] ]), HBox([ self.uptake_rate[3], self.secretion_rate[3], self.saturation_density[3] ]), HBox([ self.uptake_rate[4], self.secretion_rate[4], self.saturation_density[4] ]), ], # HBox([self.uptake_rate[5], self.secretion_rate[5], self.saturation_density[5] ]) ], layout=box_layout) self.tab = VBox([ self.cell_name, cycle_box, necrosis_box, apoptosis_box, metabolism_box, motility_box, mechanics_box, hypoxia_box, secretion_box, ]) #,row13,row14,row15,row16]) def is_motile_cb(self, b): if (self.is_motile.value): self.bias.children[0].disabled = False self.speed.children[0].disabled = False self.persistence_time.children[0].disabled = False self.negative_taxis.disabled = False else: self.bias.children[0].disabled = True self.speed.children[0].disabled = True self.persistence_time.children[0].disabled = True self.negative_taxis.disabled = True def fill_gui(self, xml_root): uep = xml_root.find( './/cell_definition') # find unique entry point into XML self.cell_name.value = uep.attrib['name'] self.max_birth_rate.children[0].value = float( uep.find('.//max_birth_rate').text) self.o2_proliferation_saturation.children[0].value = float( uep.find('.//o2_proliferation_saturation').text) self.o2_proliferation_threshold.children[0].value = float( uep.find('.//o2_proliferation_threshold').text) self.o2_reference.children[0].value = float( uep.find('.//o2_reference').text) self.glucose_proliferation_reference.children[0].value = float( uep.find('.//glucose_proliferation_reference').text) self.glucose_proliferation_saturation.children[0].value = float( uep.find('.//glucose_proliferation_saturation').text) self.glucose_proliferation_threshold.children[0].value = float( uep.find('.//glucose_proliferation_threshold').text) self.max_necrosis_rate.children[0].value = float( uep.find('.//max_necrosis_rate').text) self.o2_necrosis_threshold.children[0].value = float( uep.find('.//o2_necrosis_threshold').text) self.o2_necrosis_max.children[0].value = float( uep.find('.//o2_necrosis_max').text) self.apoptosis_rate.children[0].value = float( uep.find('.//apoptosis_rate').text) # metabolism self.relative_aerobic_effects.children[0].value = float( uep.find('.//relative_aerobic_effects').text) self.relative_glycolytic_effects.children[0].value = float( uep.find('.//relative_glycolytic_effects').text) # motility self.is_motile.value = False if ((uep.find('.//is_motile').text).lower() == 'true'): self.is_motile.value = True self.is_motile_cb(None) self.gradient_substrate_index.value = int( uep.find('.//gradient_substrate_index').text) self.bias.children[0].value = float(uep.find('.//bias').text) # self.negative_taxis.value = bool(uep.find('.//negative_taxis').text) self.negative_taxis.value = 0 if ((uep.find('.//negative_taxis').text).lower() == "true"): self.negative_taxis.value = 1 self.speed.children[0].value = float(uep.find('.//speed').text) self.persistence_time.children[0].value = float( uep.find('.//persistence_time').text) # mechanics self.max_relative_adhesion_distance.children[0].value = float( uep.find('.//max_relative_adhesion_distance').text) self.adhesion_strength.children[0].value = float( uep.find('.//adhesion_strength').text) self.repulsion_strength.children[0].value = float( uep.find('.//repulsion_strength').text) # hypoxia self.o2_hypoxic_threshold.children[0].value = float( uep.find('.//o2_hypoxic_threshold').text) self.o2_hypoxic_response.children[0].value = float( uep.find('.//o2_hypoxic_response').text) self.o2_hypoxic_saturation.children[0].value = float( uep.find('.//o2_hypoxic_saturation').text) # wow, this actually works :-) # sep = uep.find('.//secretion') # secretion entry point # idx = 0 # for el in sep.findall('substrate'): # currently 6 substrates - find all of them # kids = el.getchildren() # assume 3, which follow: # self.uptake_rate[idx].children[0].value = float(kids[0].text) # self.secretion_rate[idx].children[0].value = float(kids[1].text) # self.saturation_density[idx].children[0].value = float(kids[2].text) # idx += 1 # # if idx == 2: # break # Read values from the GUI widgets and generate/write a new XML def fill_xml(self, xml_root): # TODO: verify template .xml file exists! # tree = ET.parse('nanobio_settings.xml') # tree = ET.parse('nanobio_settings2.xml') # root = tree.getroot() uep = xml_root.find( './/cell_definition') # find unique entry point into XML uep.attrib['name'] = self.cell_name.value # TODO: verify valid type (numeric) and range? uep.find(".//max_birth_rate").text = str( self.max_birth_rate.children[0].value) uep.find('.//o2_proliferation_saturation').text = str( self.o2_proliferation_saturation.children[0].value) uep.find('.//o2_proliferation_threshold').text = str( self.o2_proliferation_threshold.children[0].value) uep.find('.//o2_reference').text = str( self.o2_reference.children[0].value) uep.find('.//glucose_proliferation_reference').text = str( self.glucose_proliferation_reference.children[0].value) uep.find('.//glucose_proliferation_saturation').text = str( self.glucose_proliferation_saturation.children[0].value) uep.find('.//glucose_proliferation_threshold').text = str( self.glucose_proliferation_threshold.children[0].value) uep.find('.//max_necrosis_rate').text = str( self.max_necrosis_rate.children[0].value) uep.find('.//o2_necrosis_threshold').text = str( self.o2_necrosis_threshold.children[0].value) uep.find('.//o2_necrosis_max').text = str( self.o2_necrosis_max.children[0].value) uep.find('.//apoptosis_rate').text = str( self.apoptosis_rate.children[0].value) # motility uep.find('.//is_motile').text = "false" if (self.is_motile.value): uep.find('.//is_motile').text = "true" uep.find('.//gradient_substrate_index').text = str( self.gradient_substrate_index.value) uep.find('.//bias').text = str(self.bias.children[0].value) # uep.find('.//negative_taxis').text = bool(self.negative_taxis.value) uep.find('.//negative_taxis').text = 'false' if (self.negative_taxis.value > 0): uep.find('.//negative_taxis').text = 'true' uep.find('.//speed').text = str(self.speed.children[0].value) uep.find('.//persistence_time').text = str( self.persistence_time.children[0].value) # mechanics uep.find('.//max_relative_adhesion_distance').text = str( self.max_relative_adhesion_distance.children[0].value) uep.find('.//adhesion_strength').text = str( self.adhesion_strength.children[0].value) uep.find('.//repulsion_strength').text = str( self.repulsion_strength.children[0].value) # hypoxia uep.find('.//o2_hypoxic_threshold').text = str( self.o2_hypoxic_threshold.children[0].value) uep.find('.//o2_hypoxic_response').text = str( self.o2_hypoxic_response.children[0].value) uep.find('.//o2_hypoxic_saturation').text = str( self.o2_hypoxic_saturation.children[0].value)
def make_config(self): layout = Layout() style = {"description_width": "initial"} checkbox1 = Checkbox(description="Show Targets", value=self.net.config["show_targets"], layout=layout, style=style) checkbox1.observe(lambda change: self.set_attr(self.net.config, "show_targets", change["new"]), names='value') checkbox2 = Checkbox(description="Errors", value=self.net.config["show_errors"], layout=layout, style=style) checkbox2.observe(lambda change: self.set_attr(self.net.config, "show_errors", change["new"]), names='value') hspace = IntText(value=self.net.config["hspace"], description="Horizontal space between banks:", style=style, layout=layout) hspace.observe(lambda change: self.set_attr(self.net.config, "hspace", change["new"]), names='value') vspace = IntText(value=self.net.config["vspace"], description="Vertical space between layers:", style=style, layout=layout) vspace.observe(lambda change: self.set_attr(self.net.config, "vspace", change["new"]), names='value') self.feature_bank = Select(description="Details:", value=self.net.config["dashboard.features.bank"], options=[""] + [layer.name for layer in self.net.layers], rows=1) self.feature_bank.observe(self.regenerate, names='value') self.control_select = Select( options=['Test', 'Train'], value=self.net.config["dashboard.dataset"], description='Dataset:', rows=1 ) self.control_select.observe(self.change_select, names='value') column1 = [self.control_select, self.zoom_slider, hspace, vspace, HBox([checkbox1, checkbox2]), self.feature_bank, self.feature_columns, self.feature_scale ] ## Make layer selectable, and update-able: column2 = [] layer = self.net.layers[-1] self.layer_select = Select(description="Layer:", value=layer.name, options=[layer.name for layer in self.net.layers], rows=1) self.layer_select.observe(self.update_layer_selection, names='value') column2.append(self.layer_select) self.layer_visible_checkbox = Checkbox(description="Visible", value=layer.visible, layout=layout) self.layer_visible_checkbox.observe(self.update_layer, names='value') column2.append(self.layer_visible_checkbox) self.layer_colormap = Select(description="Colormap:", options=[""] + AVAILABLE_COLORMAPS, value=layer.colormap if layer.colormap is not None else "", layout=layout, rows=1) self.layer_colormap_image = HTML(value="""<img src="%s"/>""" % self.net._image_to_uri(self.make_colormap_image(layer.colormap))) self.layer_colormap.observe(self.update_layer, names='value') column2.append(self.layer_colormap) column2.append(self.layer_colormap_image) ## get dynamic minmax; if you change it it will set it in layer as override: minmax = layer.get_act_minmax() self.layer_mindim = FloatText(description="Leftmost color maps to:", value=minmax[0], style=style) self.layer_maxdim = FloatText(description="Rightmost color maps to:", value=minmax[1], style=style) self.layer_mindim.observe(self.update_layer, names='value') self.layer_maxdim.observe(self.update_layer, names='value') column2.append(self.layer_mindim) column2.append(self.layer_maxdim) output_shape = layer.get_output_shape() self.layer_feature = IntText(value=layer.feature, description="Feature to show:", style=style) self.svg_rotate = Checkbox(description="Rotate", value=layer.visible, layout=layout) self.layer_feature.observe(self.update_layer, names='value') column2.append(self.layer_feature) self.svg_rotate = Checkbox(description="Rotate network", value=self.net.config["svg_rotate"], style={"description_width": 'initial'}, layout=Layout(width="52%")) self.svg_rotate.observe(lambda change: self.set_attr(self.net.config, "svg_rotate", change["new"]), names='value') self.save_config_button = Button(icon="save", layout=Layout(width="10%")) self.save_config_button.on_click(self.save_config) column2.append(HBox([self.svg_rotate, self.save_config_button])) config_children = HBox([VBox(column1, layout=Layout(width="100%")), VBox(column2, layout=Layout(width="100%"))]) accordion = Accordion(children=[config_children]) accordion.set_title(0, self.net.name) accordion.selected_index = None return accordion
def updateinputboxes(obj=None): lst_name = list(dict_settings['security'].keys()) lst_ticker = list(dict_settings['security'].values()) for n in range(num_avail_ticker): if list_sec_input[n + 1].children[0].value.strip( ) != '' and list_sec_input[n + 1].children[1].value.strip() == '': list_sec_input[n + 1].children[1].value = lst_name[n] if check_usemktcap.value: list_sec_input[n + 1].children[2].disabled = True list_sec_input[n + 1].children[2].layout.visibility = 'hidden' else: list_sec_input[n + 1].children[2].disabled = False list_sec_input[n + 1].children[2].layout.visibility = 'visible' check_usemktcap.observe(updateinputboxes, 'value') button_applysettings = Button(description='Apply Settings') #button_reset=Button(description = 'Reset to No Views') def onclickapplysettings(obj=None): save_settings() updateinputboxes() solve_intial_opt_weight() updateviewcontrol() updatecontrolinui() run_viewmodel({'new': 0.}) #display(button_reset)
def general(): """General settings. Args: None Returns: update_widget : A widget for general settings. Raises: Error: Example: """ # User settings user_info = Label("General settings.") values = config.read() user_name = Text(value=values['set']['user'], placeholder='user name', description='User:'******'set']['email'], placeholder='[email protected]', description='email:', disabled=False) user_institution = Text(value=values['set']['institution'], placeholder='EU-', description='Institution:', disabled=False) ms_list = data_options.eu_ms() ms = Dropdown( options=[(ms_list[m], m) for m in ms_list] + [('', '')], value=values['set']['member_state'], description='Member state:', disabled=False, ) wbox_user = VBox([user_info, user_name, user_email, user_institution, ms], layout=Layout(border='1px solid black')) # System settings sys_info = Label("System settings.") paths_info = Label("Select the personal data folder.") jupyterlab = Checkbox( value=eval(values['set']['jupyterlab']), description= 'Workin in Jupyter Lab (Uncheck for Voila and classical jupyter environment)', disabled=False, indent=False) def on_jupyterlab_change(change): config.set_value(['set', 'jupyterlab'], str(jupyterlab.value)) jupyterlab.observe(on_jupyterlab_change, 'value') path_data = Text(value=values['paths']['data'], description='Data path:') path_temp = Text(value=values['paths']['temp'], description='Temp path:', disabled=True) files_info = Label("Select where to store the parcel IDs list file from:") plimit_info = Label( "Warning: No more than 25 parcels are tested, unexpected results may occur." ) plimit = BoundedIntText(value=int(values['set']['plimit']), max=100_000_000, min=1, step=1, description='Max parcels that can be downloaded:', disabled=False) wbox_sys = VBox([ sys_info, jupyterlab, plimit_info, plimit, paths_info, path_data, path_temp, files_info ], layout=Layout(border='1px solid black')) btn_save = Button(description='Save', icon='save') progress = Output() def outlog(*text): with progress: print(*text) @btn_save.on_click def btn_save_on_click(b): progress.clear_output() config.set_value(['set', 'user'], str(user_name.value)) config.set_value(['set', 'email'], str(user_email.value)) config.set_value(['set', 'institution'], str(user_institution.value)) config.set_value(['set', 'member_state'], str(user_email.value)) config.set_value(['set', 'plimit'], str(plimit.value)) config.set_value(['paths', 'data'], str(path_data.value)) config.set_value(['paths', 'temp'], str(path_temp.value)) outlog("The new settings are saved.") wbox = VBox( [clean_temp(), wbox_user, wbox_sys, HBox([btn_save]), progress]) return wbox
def _make_widget_repr(self): self.widget_repr_name = Text(value='', description='representation') self.widget_repr_name._ngl_name = 'repr_name_text' repr_selection = Text(value=' ', description='selection') repr_selection._ngl_name = 'repr_selection' repr_selection.width = self.widget_repr_name.width = default.DEFAULT_TEXT_WIDTH max_n_components = max(self._view.n_components - 1, 0) self.widget_component_slider = IntSlider(value=0, max=max_n_components, min=0, description='component') self.widget_component_slider._ngl_name = 'component_slider' cvalue = ' ' self.widget_component_dropdown = Dropdown(value=cvalue, options=[ cvalue, ], description='component') self.widget_component_dropdown._ngl_name = 'component_dropdown' self.widget_repr_slider = IntSlider(value=0, description='representation', width=default.DEFAULT_SLIDER_WIDTH) self.widget_repr_slider._ngl_name = 'repr_slider' self.widget_repr_slider.visible = True self.widget_component_slider.layout.width = default.DEFAULT_SLIDER_WIDTH self.widget_repr_slider.layout.width = default.DEFAULT_SLIDER_WIDTH self.widget_component_dropdown.layout.width = self.widget_component_dropdown.max_width = default.DEFAULT_TEXT_WIDTH # turn off for now self.widget_component_dropdown.layout.display = 'none' self.widget_component_dropdown.description = '' # self.widget_accordion_repr_parameters = Accordion() self.widget_accordion_repr_parameters = Tab() self.widget_repr_parameters = self._make_widget_repr_parameters( self.widget_component_slider, self.widget_repr_slider, self.widget_repr_name) self.widget_accordion_repr_parameters.children = [ self.widget_repr_parameters, Box() ] self.widget_accordion_repr_parameters.set_title(0, 'Parameters') self.widget_accordion_repr_parameters.set_title(1, 'Hide') self.widget_accordion_repr_parameters.selected_index = 1 checkbox_reprlist = Checkbox(value=False, description='reprlist') checkbox_reprlist._ngl_name = 'checkbox_reprlist' self.widget_repr_choices = self._make_repr_name_choices( self.widget_component_slider, self.widget_repr_slider) self.widget_repr_choices._ngl_name = 'reprlist_choices' self.widget_repr_add = self._make_add_widget_repr( self.widget_component_slider) def on_update_checkbox_reprlist(change): self.widget_repr_choices.visible = change['new'] checkbox_reprlist.observe(on_update_checkbox_reprlist, names='value') def on_repr_name_text_value_changed(change): name = change['new'].strip() old = change['old'].strip() should_update = (self._real_time_update and old and name and name in REPRESENTATION_NAMES and name != change['old'].strip()) if should_update: component = self.widget_component_slider.value repr_index = self.widget_repr_slider.value self._view._remote_call( 'setRepresentation', target='Widget', args=[change['new'], {}, component, repr_index]) self._view._request_repr_parameters(component, repr_index) def on_component_or_repr_slider_value_changed(change): self._view._request_repr_parameters( component=self.widget_component_slider.value, repr_index=self.widget_repr_slider.value) self.widget_component_dropdown.options = tuple( self._view._ngl_component_names) if self.widget_accordion_repr_parameters.selected_index >= 0: self.widget_repr_parameters.name = self.widget_repr_name.value self.widget_repr_parameters.repr_index = self.widget_repr_slider.value self.widget_repr_parameters.component_index = self.widget_component_slider.value def on_repr_selection_value_changed(change): if self._real_time_update: component = self.widget_component_slider.value repr_index = self.widget_repr_slider.value self._view._set_selection(change['new'], component=component, repr_index=repr_index) def on_change_component_dropdown(change): choice = change['new'] if choice and choice.strip(): # bool(" ") is True self.widget_component_slider.value = self._view._ngl_component_names.index( choice) self.widget_component_dropdown.observe(on_change_component_dropdown, names='value') self.widget_repr_slider.observe( on_component_or_repr_slider_value_changed, names='value') self.widget_component_slider.observe( on_component_or_repr_slider_value_changed, names='value') self.widget_repr_name.observe(on_repr_name_text_value_changed, names='value') repr_selection.observe(on_repr_selection_value_changed, names='value') self.widget_repr_control_buttons = self._make_button_repr_control( self.widget_component_slider, self.widget_repr_slider, repr_selection) blank_box = Box([Label("")]) all_kids = [ self.widget_repr_control_buttons, blank_box, self.widget_repr_add, self.widget_component_dropdown, self.widget_repr_name, repr_selection, self.widget_component_slider, self.widget_repr_slider, self.widget_repr_choices, self.widget_accordion_repr_parameters ] vbox = VBox(all_kids) self._view._request_repr_parameters( component=self.widget_component_slider.value, repr_index=self.widget_repr_slider.value) self.widget_repr = _relayout_master(vbox, width='100%') self._refresh(self.widget_component_slider, self.widget_repr_slider) setattr(self.widget_repr, "_saved_widgets", []) for _box in self.widget_repr.children: if hasattr(_box, 'children'): for kid in _box.children: self.widget_repr._saved_widgets.append(kid) return self.widget_repr
class Dashboard(VBox): """ Build the dashboard for Jupyter widgets. Requires running in a notebook/jupyterlab. """ def __init__(self, net, width="95%", height="550px", play_rate=0.5): self._ignore_layer_updates = False self.player = _Player(self, play_rate) self.player.start() self.net = net self.dataset = net.dataset self._width = width self._height = height ## Global widgets: style = {"description_width": "initial"} self.feature_columns = IntText(description="Feature columns:", value=3, style=style) self.feature_scale = FloatText(description="Feature scale:", value=2.0, style=style) self.feature_columns.observe(self.regenerate, names='value') self.feature_scale.observe(self.regenerate, names='value') ## Hack to center SVG as justify-content is broken: self.net_svg = HTML(value="""<p style="text-align:center">%s</p>""" % ("", ), layout=Layout(width=self._width, overflow_x='auto', overflow_y="auto", justify_content="center")) # Make controls first: self.output = Output() controls = self.make_controls() config = self.make_config() super().__init__([config, controls, self.net_svg, self.output]) def goto(self, position): if len(self.dataset.inputs) == 0 or len(self.dataset.targets) == 0: return if self.control_select.value == "Train": length = len(self.dataset.train_inputs) elif self.control_select.value == "Test": length = len(self.dataset.test_inputs) #### Position it: if position == "begin": self.control_slider.value = 0 elif position == "end": self.control_slider.value = length - 1 elif position == "prev": if self.control_slider.value - 1 < 0: self.control_slider.value = length - 1 # wrap around else: self.control_slider.value = max(self.control_slider.value - 1, 0) elif position == "next": if self.control_slider.value + 1 > length - 1: self.control_slider.value = 0 # wrap around else: self.control_slider.value = min(self.control_slider.value + 1, length - 1) self.position_text.value = self.control_slider.value def update_control_slider(self, change=None): if len(self.dataset.inputs) == 0 or len(self.dataset.targets) == 0: self.total_text.value = "of 0" self.control_slider.value = 0 self.position_text.value = 0 self.control_slider.disabled = True self.position_text.disabled = True for child in self.control_buttons.children: if not hasattr(child, "icon") or child.icon != "refresh": child.disabled = True return if self.control_select.value == "Test": self.total_text.value = "of %s" % len(self.dataset.test_inputs) minmax = (0, max(len(self.dataset.test_inputs) - 1, 0)) if minmax[0] <= self.control_slider.value <= minmax[1]: pass # ok else: self.control_slider.value = 0 self.control_slider.min = minmax[0] self.control_slider.max = minmax[1] if len(self.dataset.test_inputs) == 0: disabled = True else: disabled = False elif self.control_select.value == "Train": self.total_text.value = "of %s" % len(self.dataset.train_inputs) minmax = (0, max(len(self.dataset.train_inputs) - 1, 0)) if minmax[0] <= self.control_slider.value <= minmax[1]: pass # ok else: self.control_slider.value = 0 self.control_slider.min = minmax[0] self.control_slider.max = minmax[1] if len(self.dataset.train_inputs) == 0: disabled = True else: disabled = False self.control_slider.disabled = disabled self.position_text.disbaled = disabled self.position_text.value = self.control_slider.value for child in self.control_buttons.children: if not hasattr(child, "icon") or child.icon != "refresh": child.disabled = disabled def update_zoom_slider(self, change): if change["name"] == "value": self.net.config["svg_height"] = self.zoom_slider.value * 780 self.regenerate() def update_position_text(self, change): if (change["name"] == "_property_lock" and isinstance(change["new"], dict) and "value" in change["new"]): self.control_slider.value = change["new"]["value"] def get_current_input(self): if self.control_select.value == "Train" and len( self.dataset.train_targets) > 0: return self.dataset.train_inputs[self.control_slider.value] elif self.control_select.value == "Test" and len( self.dataset.test_targets) > 0: return self.dataset.test_inputs[self.control_slider.value] def update_slider_control(self, change): if len(self.dataset.inputs) == 0 or len(self.dataset.targets) == 0: self.total_text.value = "of 0" return if change["name"] == "value": self.position_text.value = self.control_slider.value if self.control_select.value == "Train" and len( self.dataset.train_targets) > 0: self.total_text.value = "of %s" % len( self.dataset.train_inputs) output = self.net.propagate( self.dataset.train_inputs[self.control_slider.value]) if self.feature_bank.value in self.net.layer_dict.keys(): self.net.propagate_to_features( self.feature_bank.value, self.dataset.train_inputs[self.control_slider.value], cols=self.feature_columns.value, scale=self.feature_scale.value, html=False) if self.net.config["show_targets"]: self.net.display_component([ self.dataset.train_targets[self.control_slider.value] ], "targets", minmax=(-1, 1)) if self.net.config["show_errors"]: errors = np.array(output) - np.array( self.dataset.train_targets[self.control_slider.value]) self.net.display_component([errors.tolist()], "errors", minmax=(-1, 1)) elif self.control_select.value == "Test" and len( self.dataset.test_targets) > 0: self.total_text.value = "of %s" % len(self.dataset.test_inputs) output = self.net.propagate( self.dataset.test_inputs[self.control_slider.value]) if self.feature_bank.value in self.net.layer_dict.keys(): self.net.propagate_to_features( self.feature_bank.value, self.dataset.test_inputs[self.control_slider.value], cols=self.feature_columns.value, scale=self.feature_scale.value, html=False) if self.net.config["show_targets"]: self.net.display_component( [self.dataset.test_targets[self.control_slider.value]], "targets", minmax=(-1, 1)) if self.net.config["show_errors"]: errors = np.array(output) - np.array( self.dataset.test_targets[self.control_slider.value]) self.net.display_component([errors.tolist()], "errors", minmax=(-1, 1)) def train_one(self, button): if len(self.dataset.inputs) == 0 or len(self.dataset.targets) == 0: return if self.control_select.value == "Train" and len( self.dataset.train_targets) > 0: outputs = self.train_one( self.dataset.train_inputs[self.control_slider.value], self.dataset.train_targets[self.control_slider.value]) elif self.control_select.value == "Test" and len( self.dataset.test_targets) > 0: outputs = self.train_one( self.dataset.test_inputs[self.control_slider.value], self.dataset.test_targets[self.control_slider.value]) def toggle_play(self, button): ## toggle if self.button_play.description == "Play": self.button_play.description = "Stop" self.button_play.icon = "pause" self.player.resume() else: self.button_play.description = "Play" self.button_play.icon = "play" self.player.pause() def prop_one(self, button=None): self.update_slider_control({"name": "value"}) def regenerate(self, button=None): ## Protection when deleting object on shutdown: if isinstance(button, dict) and 'new' in button and button['new'] is None: return #with self.output: # print("regenerate called!", button) inputs = self.get_current_input() features = None if self.feature_bank.value in self.net.layer_dict.keys(): features = self.net.propagate_to_features( self.feature_bank.value, inputs, cols=self.feature_columns.value, scale=self.feature_scale.value, display=False) svg = """<p style="text-align:center">%s</p>""" % (self.net.build_svg( inputs=inputs), ) if inputs is not None and features is not None: self.net_svg.value = """ <table align="center" style="width: 100%%;"> <tr> <td valign="top">%s</td> <td valign="top" align="center"><p style="text-align:center"><b>%s</b></p>%s</td> </tr> </table>""" % (svg, "%s features" % self.feature_bank.value, features) else: self.net_svg.value = svg def make_colormap_image(self, colormap_name): from .layers import Layer if not colormap_name: colormap_name = get_colormap() layer = Layer("Colormap", 100) image = layer.make_image(np.arange(-1, 1, .01), colormap_name, { "pixels_per_unit": 1 }).resize((300, 25)) return image def set_attr(self, obj, attr, value): if value not in [{}, None]: ## value is None when shutting down if isinstance(value, dict): value = value["value"] if isinstance(obj, dict): obj[attr] = value else: setattr(obj, attr, value) ## was crashing on Widgets.__del__, if get_ipython() no longer existed self.regenerate() def make_controls(self): button_begin = Button(icon="fast-backward", layout=Layout(width='100%')) button_prev = Button(icon="backward", layout=Layout(width='100%')) button_next = Button(icon="forward", layout=Layout(width='100%')) button_end = Button(icon="fast-forward", layout=Layout(width='100%')) #button_prop = Button(description="Propagate", layout=Layout(width='100%')) #button_train = Button(description="Train", layout=Layout(width='100%')) self.button_play = Button(icon="play", description="Play", layout=Layout(width="100%")) refresh_button = Button(icon="refresh", layout=Layout(width="25%")) self.position_text = IntText(value=0, layout=Layout(width="100%")) self.control_buttons = HBox( [ button_begin, button_prev, #button_train, self.position_text, button_next, button_end, self.button_play, refresh_button ], layout=Layout(width='100%', height="50px")) length = (len(self.dataset.train_inputs) - 1) if len(self.dataset.train_inputs) > 0 else 0 self.control_slider = IntSlider(description="Dataset index", continuous_update=False, min=0, max=max(length, 0), value=0, layout=Layout(width='100%')) self.total_text = Label(value="of 0", layout=Layout(width="100px")) self.zoom_slider = FloatSlider(description="Zoom", continuous_update=False, min=.5, max=3, value=self.net.config["svg_height"] / 780.0) ## Hook them up: button_begin.on_click(lambda button: self.goto("begin")) button_end.on_click(lambda button: self.goto("end")) button_next.on_click(lambda button: self.goto("next")) button_prev.on_click(lambda button: self.goto("prev")) self.button_play.on_click(self.toggle_play) self.control_slider.observe(self.update_slider_control, names='value') refresh_button.on_click(lambda widget: (self.update_control_slider( ), self.output.clear_output(), self.regenerate())) self.zoom_slider.observe(self.update_zoom_slider, names='value') self.position_text.observe(self.update_position_text, names='value') # Put them together: controls = VBox([ HBox([self.control_slider, self.total_text], layout=Layout(height="40px")), self.control_buttons ], layout=Layout(width='100%')) #net_page = VBox([control, self.net_svg], layout=Layout(width='95%')) controls.on_displayed(lambda widget: self.regenerate()) return controls def make_config(self): layout = Layout() style = {"description_width": "initial"} checkbox1 = Checkbox(description="Show Targets", value=self.net.config["show_targets"], layout=layout, style=style) checkbox1.observe(lambda change: self.set_attr( self.net.config, "show_targets", change["new"]), names='value') checkbox2 = Checkbox(description="Errors", value=self.net.config["show_errors"], layout=layout, style=style) checkbox2.observe(lambda change: self.set_attr( self.net.config, "show_errors", change["new"]), names='value') hspace = IntText(value=self.net.config["hspace"], description="Horizontal space between banks:", style=style, layout=layout) hspace.observe(lambda change: self.set_attr(self.net.config, "hspace", change["new"]), names='value') vspace = IntText(value=self.net.config["vspace"], description="Vertical space between layers:", style=style, layout=layout) vspace.observe(lambda change: self.set_attr(self.net.config, "vspace", change["new"]), names='value') self.feature_bank = Select( description="Features:", value="", options=[""] + [ layer.name for layer in self.net.layers if self.net._layer_has_features(layer.name) ], rows=1) self.feature_bank.observe(self.regenerate, names='value') self.control_select = Select(options=['Test', 'Train'], value='Train', description='Dataset:', rows=1) self.control_select.observe(self.update_control_slider, names='value') column1 = [ self.control_select, self.zoom_slider, hspace, vspace, HBox([checkbox1, checkbox2]), self.feature_bank, self.feature_columns, self.feature_scale ] ## Make layer selectable, and update-able: column2 = [] layer = self.net.layers[-1] self.layer_select = Select( description="Layer:", value=layer.name, options=[layer.name for layer in self.net.layers], rows=1) self.layer_select.observe(self.update_layer_selection, names='value') column2.append(self.layer_select) self.layer_visible_checkbox = Checkbox(description="Visible", value=layer.visible, layout=layout) self.layer_visible_checkbox.observe(self.update_layer, names='value') column2.append(self.layer_visible_checkbox) self.layer_colormap = Select( description="Colormap:", options=[""] + AVAILABLE_COLORMAPS, value=layer.colormap if layer.colormap is not None else "", layout=layout, rows=1) self.layer_colormap_image = HTML( value="""<img src="%s"/>""" % self.net._image_to_uri(self.make_colormap_image(layer.colormap))) self.layer_colormap.observe(self.update_layer, names='value') column2.append(self.layer_colormap) column2.append(self.layer_colormap_image) self.layer_mindim = FloatText(description="Leftmost color maps to:", value=layer.minmax[0], style=style) self.layer_maxdim = FloatText(description="Rightmost color maps to:", value=layer.minmax[1], style=style) self.layer_mindim.observe(self.update_layer, names='value') self.layer_maxdim.observe(self.update_layer, names='value') column2.append(self.layer_mindim) column2.append(self.layer_maxdim) output_shape = layer.get_output_shape() self.layer_feature = IntText(value=layer.feature, description="Feature to show:", style=style) self.layer_feature.observe(self.update_layer, names='value') column2.append(self.layer_feature) config_children = HBox([ VBox(column1, layout=Layout(width="100%")), VBox(column2, layout=Layout(width="100%")) ]) accordion = Accordion(children=[config_children]) accordion.set_title(0, self.net.name) accordion.selected_index = None return accordion def update_layer(self, change): """ Update the layer object, and redisplay. """ if self._ignore_layer_updates: return ## The rest indicates a change to a display variable. ## We need to save the value in the layer, and regenerate ## the display. # Get the layer: layer = self.net[self.layer_select.value] # Save the changed value in the layer: layer.feature = self.layer_feature.value layer.visible = self.layer_visible_checkbox.value ## These three, dealing with colors of activations, ## can be done with a prop_one(): if "color" in change["owner"].description.lower(): ## Matches: Colormap, lefmost color, rightmost color layer.minmax = (self.layer_mindim.value, self.layer_maxdim.value) layer.minmax = (self.layer_mindim.value, self.layer_maxdim.value) layer.colormap = self.layer_colormap.value if self.layer_colormap.value else None self.layer_colormap_image.value = """<img src="%s"/>""" % self.net._image_to_uri( self.make_colormap_image(layer.colormap)) self.prop_one() else: self.regenerate() def update_layer_selection(self, change): """ Just update the widgets; don't redraw anything. """ ## No need to redisplay anything self._ignore_layer_updates = True ## First, get the new layer selected: layer = self.net[self.layer_select.value] ## Now, let's update all of the values without updating: self.layer_visible_checkbox.value = layer.visible self.layer_colormap.value = layer.colormap if layer.colormap != "" else "" self.layer_colormap_image.value = """<img src="%s"/>""" % self.net._image_to_uri( self.make_colormap_image(layer.colormap)) self.layer_mindim.value = layer.minmax[0] self.layer_maxdim.value = layer.minmax[1] self.layer_feature.value = layer.feature self._ignore_layer_updates = False
class CellsTab(object): def __init__(self): # tab_height = '520px' # tab_layout = Layout(width='900px', # border='2px solid black', # height=tab_height, overflow_y='scroll') self.output_dir = '.' constWidth = '180px' # self.fig = plt.figure(figsize=(6, 6)) # self.fig = plt.figure(figsize=(7, 7)) max_frames = 1 self.cells_plot = interactive(self.plot_cells, frame=(0, max_frames), continuous_update=False) # https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20List.html#Play-(Animation)-widget # play = widgets.Play( # # interval=10, # value=50, # min=0, # max=100, # step=1, # description="Press play", # disabled=False # ) # slider = widgets.IntSlider() # widgets.jslink((play, 'value'), (slider, 'value')) # widgets.HBox([play, slider]) # "plot_size" controls the size of the tab height, not the plot (rf. figsize for that) plot_size = '500px' # small: plot_size = '750px' # medium plot_size = '700px' # medium plot_size = '600px' # medium self.cells_plot.layout.width = plot_size self.cells_plot.layout.height = plot_size self.use_defaults = True self.show_nucleus = 1 # 0->False, 1->True in Checkbox! self.show_edge = 1 # 0->False, 1->True in Checkbox! self.show_tracks = 0 # 0->False, 1->True in Checkbox! self.trackd = { } # dictionary to hold cell IDs and their tracks: (x,y) pairs # self.scale_radius = 1.0 # self.axes_min = 0 # self.axes_max = 2000 self.axes_min = -1000.0 self.axes_max = 1000. # TODO: get from input file self.axes_min = -500.0 self.axes_max = 500. # TODO: get from input file self.max_frames = BoundedIntText( min=0, max=99999, value=max_frames, description='Max', layout=Layout(width='160px'), # layout=Layout(flex='1 1 auto', width='auto'), #Layout(width='160px'), ) self.max_frames.observe(self.update_max_frames) self.show_nucleus_checkbox = Checkbox( description='nucleus', value=True, disabled=False, layout=Layout(width=constWidth), # layout=Layout(flex='1 1 auto', width='auto'), #Layout(width='160px'), ) self.show_nucleus_checkbox.observe(self.show_nucleus_cb) self.show_edge_checkbox = Checkbox( description='edge', value=True, disabled=False, layout=Layout(width=constWidth), # layout=Layout(flex='1 1 auto', width='auto'), #Layout(width='160px'), ) self.show_edge_checkbox.observe(self.show_edge_cb) self.show_tracks_checkbox = Checkbox( description='tracks', value=True, disabled=False, layout=Layout(width=constWidth), # layout=Layout(flex='1 1 auto', width='auto'), #Layout(width='160px'), ) # self.show_tracks_checkbox.observe(self.show_tracks_cb) # row1 = HBox([Label('(select slider: drag or left/right arrows)'), # self.max_frames, VBox([self.show_nucleus_checkbox, self.show_edge_checkbox])]) # self.max_frames, self.show_nucleus_checkbox], layout=Layout(width='500px')) # self.tab = VBox([row1,self.cells_plot], layout=tab_layout) items_auto = [ Label('select slider: drag or left/right arrows'), self.max_frames, # self.show_nucleus_checkbox, # self.show_edge_checkbox, # self.show_tracks_checkbox, ] #row1 = HBox([Label('(select slider: drag or left/right arrows)'), # max_frames, show_nucleus_checkbox, show_edge_checkbox], # layout=Layout(width='800px')) box_layout = Layout(display='flex', flex_flow='row', align_items='stretch', width='70%') row1 = Box(children=items_auto, layout=box_layout) # if (hublib_flag): # self.download_button = Download('svg.zip', style='warning', icon='cloud-download', # tooltip='You need to allow pop-ups in your browser', cb=self.download_cb) # download_row = HBox([self.download_button.w, Label("Download all cell plots (browser must allow pop-ups).")]) # # self.tab = VBox([row1, self.cells_plot, self.download_button.w], layout=tab_layout) # # self.tab = VBox([row1, self.cells_plot, self.download_button.w]) # self.tab = VBox([row1, self.cells_plot, download_row]) # else: # self.tab = VBox([row1, self.cells_plot]) self.tab = VBox([row1, self.cells_plot]) # def update(self, rdir=''): def update(self, rdir=''): # with debug_view: # print("mcds_cells:update(): rdir=", rdir) if rdir: self.output_dir = rdir all_files = sorted( glob.glob(os.path.join(self.output_dir, 'output*.xml'))) if len(all_files) > 0: last_file = all_files[-1] # Note! the following will trigger: self.max_frames.observe(self.update_max_frames) self.max_frames.value = int( last_file[-12:-4]) # assumes naming scheme: "snapshot%08d.svg" # with debug_view: # print("mcds_cells": added %s files" % len(all_files)) # def download_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 show_nucleus_cb(self, b): global current_frame if (self.show_nucleus_checkbox.value): self.show_nucleus = 1 else: self.show_nucleus = 0 # self.plot_cells(self,current_frame) self.cells_plot.update() def show_edge_cb(self, b): if (self.show_edge_checkbox.value): self.show_edge = 1 else: self.show_edge = 0 self.cells_plot.update() # def show_tracks_cb(self, b): # if (self.show_tracks_checkbox.value): # self.show_tracks = 1 # else: # self.show_tracks = 0 # # print('--- show_tracks_cb: calling cells_plot.update()') # # if (not self.show_tracks): # # self.cells_plot.update() # # else: # if (self.show_tracks): # self.create_all_tracks() # self.cells_plot.update() # Note! this is called for EACH change to "Max" frames, which is with every new .svg file created! def update_max_frames(self, _b): self.cells_plot.children[0].max = self.max_frames.value # if (self.show_tracks): # print('--- update_max_frames: calling create_all_tracks') # self.create_all_tracks() #----------------------------------------------------- def circles(self, x, y, s, c='b', vmin=None, vmax=None, **kwargs): """ See https://gist.github.com/syrte/592a062c562cd2a98a83 Make a scatter plot of circles. Similar to plt.scatter, but the size of circles are in data scale. Parameters ---------- x, y : scalar or array_like, shape (n, ) Input data s : scalar or array_like, shape (n, ) Radius of circles. c : color or sequence of color, optional, default : 'b' `c` can be a single color format string, or a sequence of color specifications of length `N`, or a sequence of `N` numbers to be mapped to colors using the `cmap` and `norm` specified via kwargs. Note that `c` should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped. (If you insist, use `color` instead.) `c` can be a 2-D array in which the rows are RGB or RGBA, however. vmin, vmax : scalar, optional, default: None `vmin` and `vmax` are used in conjunction with `norm` to normalize luminance data. If either are `None`, the min and max of the color array is used. kwargs : `~matplotlib.collections.Collection` properties Eg. alpha, edgecolor(ec), facecolor(fc), linewidth(lw), linestyle(ls), norm, cmap, transform, etc. Returns ------- paths : `~matplotlib.collections.PathCollection` Examples -------- a = np.arange(11) circles(a, a, s=a*0.2, c=a, alpha=0.5, ec='none') plt.colorbar() License -------- This code is under [The BSD 3-Clause License] (http://opensource.org/licenses/BSD-3-Clause) """ if np.isscalar(c): kwargs.setdefault('color', c) c = None if 'fc' in kwargs: kwargs.setdefault('facecolor', kwargs.pop('fc')) if 'ec' in kwargs: kwargs.setdefault('edgecolor', kwargs.pop('ec')) if 'ls' in kwargs: kwargs.setdefault('linestyle', kwargs.pop('ls')) if 'lw' in kwargs: kwargs.setdefault('linewidth', kwargs.pop('lw')) # You can set `facecolor` with an array for each patch, # while you can only set `facecolors` with a value for all. zipped = np.broadcast(x, y, s) patches = [Circle((x_, y_), s_) for x_, y_, s_ in zipped] collection = PatchCollection(patches, **kwargs) if c is not None: c = np.broadcast_to(c, zipped.shape).ravel() collection.set_array(c) collection.set_clim(vmin, vmax) ax = plt.gca() ax.add_collection(collection) ax.autoscale_view() # plt.draw_if_interactive() if c is not None: plt.sci(collection) # return collection #------------------------- # def plot_cells(self, frame, rdel=''): def plot_cells(self, frame): # global current_idx, axes_max global current_frame current_frame = frame fname = "output%08d.xml" % frame full_fname = os.path.join(self.output_dir, fname) # with debug_view: # print("plot_cells:", full_fname) # print("-- plot_cells:", full_fname) if not os.path.isfile(full_fname): print("Once output files are generated, click the slider.") return mcds = pyMCDS(fname, self.output_dir) # print(mcds.get_time()) cell_ids = mcds.data['discrete_cells']['ID'] # print(cell_ids.shape) # print(cell_ids[:4]) #cell_vec = np.zeros((cell_ids.shape, 3)) num_cells = cell_ids.shape[0] cell_vec = np.zeros((cell_ids.shape[0], 3)) vec_list = ['position_x', 'position_y', 'position_z'] for i, lab in enumerate(vec_list): cell_vec[:, i] = mcds.data['discrete_cells'][lab] xvals = cell_vec[:, 0] yvals = cell_vec[:, 1] # print('x range: ',xvals.min(), xvals.max()) # print('y range: ',yvals.min(), yvals.max()) # xvals = np.array(xlist) # yvals = np.array(ylist) # rvals = np.array(rlist) # rgbs = np.array(rgb_list) # print("xvals[0:5]=",xvals[0:5]) # print("rvals[0:5]=",rvals[0:5]) # print("rvals.min, max=",rvals.min(),rvals.max()) # rwh - is this where I change size of render window?? (YES - yipeee!) # plt.figure(figsize=(6, 6)) # plt.cla() # title_str = svals[2] + "d, " + svals[4] + "h, " + svals[7] + "m" title_str = str( mcds.get_time()) + " min (" + str(num_cells) + " agents)" # plt.title(title_str) # plt.xlim(axes_min,axes_max) # plt.ylim(axes_min,axes_max) # plt.scatter(xvals,yvals, s=rvals*scale_radius, c=rgbs) # TODO: make figsize a function of plot_size? What about non-square plots? # self.fig = plt.figure(figsize=(9, 9)) # self.fig = plt.figure(figsize=(18, 18)) # self.fig = plt.figure(figsize=(15, 15)) # self.fig = plt.figure(figsize=(9, 9)) # #rwh - temp fix - Ah, error only occurs when "edges" is toggled on # cell_size = 5 cell_vols = mcds.data['discrete_cells']['total_volume'] cell_radii = (cell_vols * 0.75 / 3.14159)**0.3333 # if (self.show_edge): # try: # # self.circles(xvals,yvals, s=rvals, color=rgbs, edgecolor='black', linewidth=0.5) # # self.circles(xvals,yvals, s=cell_radii, edgecolor='black', linewidth=0.1) # # self.circles(xvals,yvals, s=cell_radii, c='red', edgecolor='black', linewidth=0.5, fc='none') # self.circles(xvals,yvals, s=cell_radii, c='red', fc='none') # # cell_circles = self.circles(xvals,yvals, s=rvals, color=rgbs, edgecolor='black', linewidth=0.5) # # plt.sci(cell_circles) # except (ValueError): # pass # else: # # self.circles(xvals,yvals, s=rvals, color=rgbs) # self.circles(xvals,yvals, s=cell_radii, fc='none') self.circles(xvals, yvals, s=cell_radii, fc='none') plt.xlim(self.axes_min, self.axes_max) plt.ylim(self.axes_min, self.axes_max) # ax.grid(False) # axx.set_title(title_str) plt.title(title_str)