def interactive_plot(model_name):
    def _to_png(x):
        if hasattr(x, 'numpy'):
            x = x.numpy()
        x = np.rot90(x.squeeze(), n_rot90)
        x = np.clip(x, 0., 255.)
        x = x.astype(np.uint8)
        x = Image.fromarray(x)
        x = x.resize(resize, resample=Image.BILINEAR)
        return x

    def plot_intervention(intervention,
                          idx,
                          num_samples=32,
                          save_image_dir='',
                          save=False):
        fig, ax = plt.subplots(1,
                               4,
                               figsize=(10, 2.5),
                               gridspec_kw=dict(wspace=0, hspace=0))
        orig_data = prep_data(calabresi_test[idx])
        ms_type = orig_data['type']
        del orig_data['type']
        x_test = orig_data['x']
        og = {k: v.to(device) for k, v in orig_data.items()}
        pyro.clear_param_store()
        cond = {
            k: torch.tensor([[v]]).to(device)
            for k, v in intervention.items()
        }
        counterfactual = loaded_models[model_name].counterfactual(
            og, cond, num_samples)
        counterfactual = {
            k: v.detach().cpu()
            for k, v in counterfactual.items()
        }
        x = counterfactual['x'].squeeze()
        x_test = x_test.squeeze()
        diff = (x - x_test).squeeze()
        if x.ndim == 3:
            if x.shape[0] == 3:
                x = x[1]
                x_test = x_test[1]
                diff = diff[1]
            else:
                raise ValueError(f'Invalid channel size: {x.shape[0]}.')
        lim = diff.abs().max()
        ax[1].set_title('Original')
        ax[1].imshow(np.rot90(x_test, n_rot90), img_cm, **imshow_kwargs)
        ax[2].set_title(fmt_intervention(intervention))
        ax[2].imshow(np.rot90(x, n_rot90), img_cm, **imshow_kwargs)
        ax[3].set_title('Difference')
        im = ax[3].imshow(np.rot90(diff, n_rot90), diff_cm, clim=[-lim, lim])
        plt.colorbar(im)
        for axi in ax:
            axi.axis('off')
            axi.xaxis.set_major_locator(plt.NullLocator())
            axi.yaxis.set_major_locator(plt.NullLocator())

        if 'cuda' in str(device):
            del og, cond
            torch.cuda.empty_cache()

        orig_data['type'] = ms_type
        att_str = (
            '$s={sex}$\n$a={age}$\n$b={brain_volume}$\n$v={ventricle_volume}$\n$l={lesion_volume}$\n'
            '$d={duration}$\n$e={edss}$\n$t={type}$').format(
                **{
                    att: value_fmt[att](orig_data[att].item())
                    for att in variables + ('type', )
                })

        ax[0].text(0.5,
                   0.5,
                   att_str,
                   horizontalalignment='center',
                   verticalalignment='center',
                   transform=ax[0].transAxes,
                   fontsize=mpl.rcParams['axes.titlesize'])
        fig.tight_layout()
        if save_image_dir and save:
            x = _to_png(x)
            x_test = _to_png(x_test)
            intervention_str = fmt_save(intervention)
            x.save(os.path.join(save_image_dir, intervention_str + '_cf.png'))
            x_test.save(
                os.path.join(save_image_dir, intervention_str + '_orig.png'))
            plt.savefig(intervention_str + '_full.pdf')
        plt.show()

    from ipywidgets import (interactive, IntSlider, FloatSlider, HBox, VBox,
                            Checkbox, Dropdown, Text, Button, BoundedIntText)
    from IPython.display import display

    def plot(image, age, sex, brain_volume, ventricle_volume, lesion_volume,
             duration, edss, do_age, do_sex, do_brain_volume,
             do_ventricle_volume, do_lesion_volume, do_duration, do_edss,
             save_image_dir, save):
        intervention = {}
        if do_age:
            intervention['age'] = age
        if do_sex:
            intervention['sex'] = sex
        if do_brain_volume:
            intervention['brain_volume'] = brain_volume * 1000.
        if do_ventricle_volume:
            intervention['ventricle_volume'] = ventricle_volume * 1000.
        if do_lesion_volume:
            intervention['lesion_volume'] = lesion_volume * 1000.
        if do_duration:
            intervention['duration'] = duration
        if do_edss:
            intervention['edss'] = edss

        plot_intervention(intervention,
                          image,
                          save_image_dir=save_image_dir,
                          save=save)

    w = interactive(
        plot,
        image=BoundedIntText(min=0,
                             max=len(calabresi_test) - 1,
                             description='Image #'),
        age=FloatSlider(min=20.,
                        max=80.,
                        step=1.,
                        continuous_update=False,
                        description='Age'),
        do_age=Checkbox(description='do(age)'),
        sex=Dropdown(options=[('female', 0.), ('male', 1.)],
                     description='Sex'),
        do_sex=Checkbox(description='do(sex)'),
        brain_volume=FloatSlider(min=600.,
                                 max=1800.,
                                 step=0.5,
                                 continuous_update=False,
                                 description='Brain Volume (ml):',
                                 style={'description_width': 'initial'}),
        do_brain_volume=Checkbox(description='do(brain_volume)'),
        ventricle_volume=FloatSlider(min=1e-5,
                                     max=88.,
                                     step=0.1,
                                     continuous_update=False,
                                     description='Ventricle Volume (ml):',
                                     style={'description_width': 'initial'}),
        do_ventricle_volume=Checkbox(description='do(ventricle_volume)'),
        lesion_volume=FloatSlider(min=1e-5,
                                  max=66.,
                                  step=0.1,
                                  continuous_update=False,
                                  description='Lesion Volume (ml):',
                                  style={'description_width': 'initial'}),
        do_lesion_volume=Checkbox(description='do(lesion_volume)'),
        duration=FloatSlider(min=1e-5,
                             max=24.,
                             step=1.,
                             continuous_update=False,
                             description='Duration (y):',
                             style={'description_width': 'initial'}),
        do_duration=Checkbox(description='do(duration)'),
        edss=FloatSlider(min=1e-5,
                         max=10.,
                         step=1.,
                         continuous_update=False,
                         description='EDSS:',
                         style={'description_width': 'initial'}),
        do_edss=Checkbox(description='do(edss)'),
        save_image_dir=Text(value='',
                            placeholder='Full path',
                            description='Save Image Directory:',
                            style={'description_width': 'initial'}),
        save=Checkbox(description='Save'))

    n = len(variables)
    ui = VBox([
        HBox([w.children[0], w.children[-3],
              w.children[-2]]),  # image # and save_image_dir
        VBox([
            HBox([w.children[i], w.children[i + n]]) for i in range(1, n + 1)
        ]),  # vars and intervention checkboxes
        w.children[-1]
    ])  # show image
    display(ui)
    w.update()
Ejemplo n.º 2
0
    def dsc_config(dsc_value):
        values = config.read()
        ds_db = Dropdown(
            options=["1"],
            value="1",
            description='Database:',
            disabled=False,
            layout=Layout(width='140px')
        )

        try:
            with open(f"{config.get_value(['paths','temp'])}tb_prefix", 'r') as f:
                code_value = f.read()
        except Exception:
            code_value = dsc_value

        ds_code = Combobox(
            value=code_value,
            placeholder='abc',
            options=[m for m in data_options.eu_ms()]+[''],
            description='AOI code:',
            ensure_option=False,
            disabled=False,
            layout=Layout(width='200px'),
            tooltip='Lowercase AOI code name for the dataset (5chr max).'
        )
        ds_year = BoundedIntText(
            value=int(dsy.value),
            min=1980,
            max=2100,
            step=1,
            description='Dataset year:',
            disabled=False,
            layout=Layout(width='180px')

        )
        ds_desc = Text(
            value=values['ds_conf'][dsc_value]['desc'],
            description='Description:',
            disabled=False
        )

        info_map_text = ["Set default map view options. ",
                         "You can get automatically the dataset ",
                         "center coordinates."]

        lat, lon = values['ds_conf'][dsc_value]['center'].split(",")
        map_cent_lat = FloatText(
            value=float(lat),
            description='Lat:',
            disabled=False,
            layout=Layout(width='160px')
        )
        map_cent_lon = FloatText(
            value=float(lon),
            description='Lon:',
            disabled=False,
            layout=Layout(width='160px')
        )
        map_zoom = BoundedIntText(
            value=values['ds_conf'][dsc_value]['zoom'],
            min=0,
            max=20,
            step=1,
            description='Zoom:',
            disabled=False,
            layout=Layout(width='140px')
        )
        bt_get_center = Button(
            layout=Layout(width='40px'),
            icon='bullseye',
            tooltip='Get center point from database.'
        )

        ds_box = HBox([ds_code, ds_year, ds_desc])
        map_box = HBox([Label("Map center: "), map_cent_lat,
                        map_cent_lon, bt_get_center, map_zoom])

        info_config = Label(
            """Change 'AOI code' value to create a new configuration set or 
            leave the same 'AOI code' value to configure the selected one.""")

        db = int(values['ds_conf'][dsc_value]['db'])

        def get_tb_list():
            tbls = database.tables(db, None, False)
            if tbls is None:
                return []
            else:
                return tbls

        tb_dc = Dropdown(
            options=get_tb_list(),
            value=config.autoselect(
                values['ds_conf'][dsc_value]['years'][
                    str(ds_year.value)]['tables']['dias_catalog'],
                get_tb_list(), False),
            description='DIAS catalog:',
            disabled=False
        )
        tb_pr = Dropdown(
            options=get_tb_list(),
            value=config.autoselect(
                values['ds_conf'][dsc_value]['years'][
                    str(ds_year.value)]['tables']['parcels'],
                get_tb_list(), False),
            description='Parcels:',
            disabled=False
        )

        def get_pr_columns():
            try:
                colms = database.table_columns(tb_pr.value, 1, None)
                if colms is None:
                    return []
                else:
                    return colms
            except Exception:
                return []

        tc_id = Dropdown(
            options=get_pr_columns(),
            value=config.autoselect(
                values['ds_conf'][dsc_value]['years'][
                    str(ds_year.value)]['columns']['parcels_id'],
                get_pr_columns(), False),
            description='Parcels ID:',
            disabled=False,
            layout=Layout(width='180px')
        )
        tc_cn = Dropdown(
            options=get_pr_columns(),
            value=config.autoselect(
                values['ds_conf'][dsc_value]['years'][
                    str(ds_year.value)]['columns']['crop_names'],
                get_pr_columns(), False),
            description='Crop names:',
            disabled=False,
            layout=Layout(width='180px')
        )
        tc_cc = Dropdown(
            options=get_pr_columns(),
            value=config.autoselect(
                values['ds_conf'][dsc_value]['years'][
                    str(ds_year.value)]['columns']['crop_codes'],
                get_pr_columns(), False),
            description='Crop codes:',
            disabled=False,
            layout=Layout(width='180px')
        )

        def on_tb_pr_change(change):
            tc_id.options = get_pr_columns()
            tc_cn.options = get_pr_columns()
            tc_cc.options = get_pr_columns()
        tb_pr.observe(on_tb_pr_change, 'value')

        parcel_box = HBox([tb_pr, tc_id, tc_cn, tc_cc])

        tb_s2 = Dropdown(
            options=get_tb_list(),
            value=config.autoselect(
                values['ds_conf'][dsc_value]['years'][
                    str(ds_year.value)]['tables']['s2'],
                get_tb_list(), False),
            description='S2 signatures:',
            disabled=False
        )
        tb_bs = Dropdown(
            options=get_tb_list(),
            value=config.autoselect(
                values['ds_conf'][dsc_value]['years'][
                    str(ds_year.value)]['tables']['bs'],
                get_tb_list(), False),
            description='Backscattering:',
            disabled=False
        )
        tb_6c = Dropdown(
            options=get_tb_list(),
            value=config.autoselect(
                values['ds_conf'][dsc_value]['years'][
                    str(ds_year.value)]['tables']['c6'],
                get_tb_list(), False),
            description='6 day coherence:',
            disabled=False
        )

        wb_save = Button(
            description='Save',
            disabled=False,
            icon='save'
        )

        @bt_get_center.on_click
        def bt_get_center_on_click(b):
            import json
            center_json = json.loads(
                database.getTableCentroid(tb_pr.value)['center'][0])
            map_cent_lat.value = round(center_json['coordinates'][1], 2)
            map_cent_lon.value = round(center_json['coordinates'][0], 2)
            map_zoom.value = 10

        @wb_save.on_click
        def wb_save_on_click(b):
            progress.clear_output()
            dscode = ds_code.value
            config.update(['ds_conf', dscode, 'years', str(ds_year.value),
                           'tables', 'dias_catalog'], str(tb_dc.value))
            config.update(['ds_conf', dscode, 'years', str(ds_year.value),
                           'tables', 'parcels'], str(tb_pr.value))
            config.update(['ds_conf', dscode, 'years', str(ds_year.value),
                           'columns', 'parcels_id'], str(tc_id.value))
            config.update(['ds_conf', dscode, 'years', str(ds_year.value),
                           'columns', 'crop_names'], str(tc_cn.value))
            config.update(['ds_conf', dscode, 'years', str(ds_year.value),
                           'columns', 'crop_codes'], str(tc_cc.value))
            config.update(['ds_conf', dscode, 'years', str(ds_year.value),
                           'tables', 's2'], str(tb_s2.value))
            config.update(['ds_conf', dscode, 'years', str(ds_year.value),
                           'tables', 'bs'], str(tb_bs.value))
            config.update(['ds_conf', dscode, 'years', str(ds_year.value),
                           'tables', 'c6'], str(tb_6c.value))
            config.update(['ds_conf', dscode,
                           'db'], str(ds_db.value))
            config.update(['ds_conf', dscode,
                           'desc'], str(ds_desc.value))
            config.update(['ds_conf', dscode, 'center'],
                          f"{map_cent_lat.value},{map_cent_lon.value}")
            config.update(['ds_conf', dscode,
                           'zoom'], str(map_zoom.value))
            config.update(['set', 'ds_conf'], str(dscode))
            config.update(['set', 'ds_year'], str(ds_year.value))
            values = config.read()
            ds_c = values['set']['ds_conf']
            ds_y = values['set']['ds_year']
            dsc.options = [d for d in values['ds_conf']]
            dsy.options = [int(y) for y in values['ds_conf'][ds_c]['years']]
            dsc.value = ds_c
            dsy.value = int(ds_y)
            outlog("The configurations are saved.")

        return VBox([info_config, ds_box, parcel_box,
                     tb_dc, tb_s2, tb_bs, tb_6c,
                     Label(''.join(info_map_text)), map_box, wb_save])
Ejemplo n.º 3
0
    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
        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),
        )
        #            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=True,
            layout=Layout(width=constWidth),
        )
        self.zdelta = BoundedFloatText(
            min=1.,
            description='dz',
            disabled=disable_domain,
            layout=Layout(width=constWidth),
        )

        def xdelta_cb(b):
            self.ydelta.value = self.xdelta.value
            self.zdelta.value = 0.5 * (self.xdelta.value + self.ydelta.value)
            self.zmin.value = -0.5 * self.zdelta.value
            self.zmax.value = 0.5 * self.zdelta.value

        self.xdelta.observe(xdelta_cb)
        """
        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 = BoundedIntText(
            min=1,
            max=
            99999999,  # TODO: set max on all Bounded to avoid unwanted default
            description='every',
            layout=Layout(width='160px'),
        )
        self.mcds_interval = BoundedIntText(
            min=1,
            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

        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_
Ejemplo n.º 4
0
    def __init__(self,
                 df: pd.DataFrame,
                 box_col: str = 'box',
                 img_col: str = 'image',
                 text_cols: Union[str, List[str]] = None,
                 text_fmts: Union[Callable, List[Callable]] = None,
                 style_col: str = None):
        """
        :param pd.DataFrame df: `DataFrame` with images and boxes
        :param str box_col: column in the dataframe that contains boxes
        :param str img_col: column in the dataframe that contains image paths
        :param Union[str, List[str]] text_cols: (optional) the column(s) in the
        dataframe to use for creating the text that is shown on top of a box.
        When multiple columns are give, the text will be created by a
        comma-separated list of the contents of the given columns.
        :param Unions[Callable, List[Callable]] text_fmts: (optional) a
        callable, or list of callables, that takes the corresponding value from
        the `text_cols` column(s) as an input and returns the string to print
        for that value.
        :param str style_col: the column containing a dict of style attributes.
        Available attributes are:
            - `stroke_width`: the stroke width of a box (default 2)
            - `stroke_color`: the stroke color of a box (default 'red')
            - `fill_color`: the fill color of a box (default  '#00000000')
            - `hover_fill`: the fill color of a box when it is hovered on
              (default '#00000088')
            - `hover_stroke`: the stroke color of a box when it is hovered on
              (default 'blue')
            - `active_fill`: the fill color of a box when it is clicked on
              (default '#ffffff22')
            - `active_stroke`: the stroke color of a box when it is clicked on
              (default 'green')
            - `font_family`: the font family to use for box text (default
            'arial'). NOTE: exported text will always be Arial.
            - `font_size`: the font size in points (default 10)
        """
        if text_cols is None:
            text_cols = []
        if isinstance(text_cols, str):
            text_cols = [text_cols]
        if text_fmts is None:
            text_fmts = [None] * len(text_cols)
        if isinstance(text_fmts, Callable):
            text_fmts = [text_fmts]
        self.text_cols = text_cols
        self.text_fmts = text_fmts

        df2 = df.copy()

        def row2text(row):
            txts = row[text_cols]
            return ', '.join([
                fmt(txt) if fmt is not None else str(txt)
                for txt, fmt in zip(txts, self.text_fmts)
            ])

        if style_col is None:
            style_col = '_dfim_style'
            df2[style_col] = [DEFAULT_STYLE] * len(df2)
        else:
            df2[style_col] = df2[style_col].apply(lambda s: {
                k: s[k] if k in s else DEFAULT_STYLE[k]
                for k in DEFAULT_STYLE
            })

        df2['box_text'] = df2.apply(lambda row: row2text(row), axis=1)
        df2['box_dict'] = df2.apply(
            lambda row: dict(index=row.name,
                             box=row[box_col],
                             text=row['box_text'],
                             style=row[style_col])
            if (box_col in row.index and row[box_col] is not None) else None,
            axis=1)

        self.df_img = df2.groupby(img_col).agg(list).reset_index()
        self.df = df
        self.img_col = img_col
        self.box_col = box_col

        # SELECTION widget
        self.idx_wgt = BoundedIntText(value=0,
                                      min=0,
                                      max=len(self.df_img) - 1,
                                      step=1,
                                      description='Choose index',
                                      disabled=False)
        self.drop_wgt = Dropdown(options=self.df_img[img_col],
                                 description='or image',
                                 value=None,
                                 disabled=False)
        self.drop_wgt.observe(self.drop_changed, names='value')
        self.idx_wgt.observe(self.idx_changed, names='value')
        self.imsel_wgt = VBox([self.idx_wgt, self.drop_wgt])
        self.imsel_wgt.layout = Layout(margin='auto')

        # IMAGE PANE
        self.img_title = HTML(placeholder='(Image path)')
        self.img_title.layout = Layout(margin='auto')
        self.imbox_wgt = ImBoxWidget()
        self.imbox_wgt.layout = Layout(margin='1em auto')
        self.imbox_wgt.observe(self.box_changed, names='active_box')
        self.imbox_wgt.observe(self.img_changed, names='img')

        # DETAILS PANE
        self.crop_wgt = CropBoxWidget()
        self.crop_wgt.layout = Layout(margin='0 1em')
        self.detail_wgt = DetailsWidget()
        self.detail_wgt.layout = Layout(margin='auto')
        self.detail_pane = HBox([self.crop_wgt, self.detail_wgt])
        self.detail_pane.layout = Layout(margin='1em auto')

        # PLAY widget
        self.play_btns = Play(interval=100,
                              value=0,
                              min=0,
                              max=len(self.df_img) - 1,
                              step=1,
                              description="Play",
                              disabled=False)
        self.play_slider = widgets.IntSlider(value=0,
                                             min=0,
                                             max=len(self.df_img) - 1,
                                             step=1)
        widgets.jslink((self.play_btns, 'value'), (self.idx_wgt, 'value'))
        widgets.jslink((self.play_btns, 'value'), (self.play_slider, 'value'))

        self.play_wgt = widgets.HBox([self.play_btns, self.play_slider])
        self.play_wgt.layout = Layout(margin='auto')

        # IMAGE EXPORT widget
        self.imexp_dest = Text(description='Output file',
                               value='output/output.png')
        self.imexp_btn = Button(description='Export')
        self.imexp_btn.on_click(self.export_img)
        self.imexp_wgt = HBox([self.imexp_dest, self.imexp_btn])

        # VIDEO EXPORT widget
        self.videxp_dest = Text(description='Output file',
                                value='output/output.mp4')
        self.videxp_start = BoundedIntText(value=0,
                                           min=0,
                                           max=len(self.df_img) - 1,
                                           step=1,
                                           description='From index',
                                           disabled=False)
        self.videxp_start.observe(self.vididx_changed, names='value')
        self.videxp_end = BoundedIntText(value=0,
                                         min=0,
                                         max=len(self.df_img) - 1,
                                         step=1,
                                         description='Until index',
                                         disabled=False)
        self.videxp_end.observe(self.vididx_changed, names='value')
        self.videxp_fps = FloatText(value=30, description='FPS')
        self.videxp_btn = Button(description='Export')
        self.videxp_btn.on_click(self.export_vid)

        self.videxp_wgt = VBox([
            HBox([self.videxp_start, self.videxp_end]),
            HBox([self.videxp_dest, self.videxp_fps]), self.videxp_btn
        ])
        self.exp_wgt = Tab(children=[self.imexp_wgt, self.videxp_wgt])
        self.exp_wgt.set_title(0, 'Export image')
        self.exp_wgt.set_title(1, 'Export video')
        self.exp_wgt.layout = Layout(margin='0 1em')

        super().__init__([
            self.imsel_wgt,
            VBox([
                self.img_title, self.imbox_wgt, self.play_wgt, self.detail_pane
            ]), self.exp_wgt
        ])
        self.idx_changed({'new': 0})
Ejemplo n.º 5
0
class SVGTab(object):

    #    myplot = None

    def __init__(self):
        tab_height = '520px'
        tab_layout = Layout(
            width='800px',  # border='2px solid black',
            height=tab_height,
            overflow_y='scroll')

        self.output_dir = '.'

        max_frames = 505  # first time + 30240 / 60
        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.tab = HBox([svg_plot], layout=tab_layout)

        self.max_frames = BoundedIntText(
            min=0,
            max=99999,
            value=max_frames,
            description='Max',
            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=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)

        items_auto = [
            Label('(select slider: drag or left/right arrows)'),
            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)
        self.tab = VBox([row1, self.svg_plot], layout=tab_layout)

#       self.output_dir_str = os.getenv('RESULTSDIR') + "/pc4nanobio/"

    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
        # print('plot_svg: SVG=', SVG)
        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)
            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)

        fig = plt.figure(figsize=(6, 6))
        #        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()
        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 = (2*rpix / fig.dpi * 72)**2
        markers_size = markers_size / 4000000.
        #        print('max=',markers_size.max())

        #        ax.scatter(xvals,yvals, s=rvals*self.scale_radius, c=rgbs)
        #        axx.scatter(xvals,yvals, s=markers_size, c=rgbs)
        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)
Ejemplo n.º 6
0
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"
                # mins= round(int(float(xml_root.find(".//current_time").text)))  # TODO: check units = mins
                mins = round(int(float(svals[7])))  # TODO: check units = mins
                hrs = int(mins / 60)
                days = int(hrs / 24)
                title_str = '%dd, %dh, %dm' % (int(days),
                                               (hrs % 24), mins - (hrs * 60))

            # 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)
Ejemplo n.º 7
0
    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=(self.figsize_width_substrate, self.figsize_height_substrate))
        # self.fig = plt.figure()
        self.fig = None

        # 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

        # 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 = 2
        # 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_substrate0, frame=(0, max_frames), continuous_update=False)
        self.i_plot = interactive(self.plot_substrate,
                                  frame=(0, max_frames),
                                  continuous_update=False)

        self.frame_slider = IntSlider(
            min=0,
            max=10,
            step=1,
            description='Test:',
            disabled=False,
            continuous_update=False,
            orientation='horizontal',
            readout=True,
            readout_format='d',
        )
        # self.frame_slider.observe(self.frame_slider_cb)
        self.frame_slider.observe(self.plot_substrate)

        # "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.]}
        # NOTE: manually setting these for now (vs. parsing them out of data/initial.xml)
        self.field_min_max = {
            'director signal': [0., 1.],
            'cargo signal': [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.field_dict = {0: 'director signal', 1: 'cargo signal'}

        self.mcds_field = Dropdown(
            options={
                'director signal': 0,
                'cargo signal': 1
            },
            value=0,
            #     description='Field',
            layout=Layout(width=constWidth))
        # print("substrate __init__: self.mcds_field.value=",self.mcds_field.value)
        #        self.mcds_field.observe(self.mcds_field_cb)
        self.mcds_field.observe(self.mcds_field_changed_cb)

        # self.field_cmap = Text(
        #     value='viridis',
        #     description='Colormap',
        #     disabled=True,
        #     layout=Layout(width=constWidth),
        # )
        self.field_cmap = Dropdown(
            options=['viridis', 'jet', 'YlOrRd'],
            value='YlOrRd',
            #     description='Field',
            layout=Layout(width=constWidth))
        #        self.field_cmap.observe(self.plot_substrate)
        self.field_cmap.observe(self.mcds_field_cb)

        self.cmap_fixed = 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)

        #---------------------
        self.cell_nucleus_toggle = Checkbox(
            description='nuclei',
            disabled=False,
            value=self.show_nucleus,
            #           layout=Layout(width=constWidth2),
        )

        def cell_nucleus_toggle_cb(b):
            # self.update()
            if (self.cell_nucleus_toggle.value):
                self.show_nucleus = True
            else:
                self.show_nucleus = False
            self.i_plot.update()

        self.cell_nucleus_toggle.observe(cell_nucleus_toggle_cb)

        #----
        self.cell_edges_toggle = Checkbox(
            description='edges',
            disabled=False,
            value=self.show_edge,
            #           layout=Layout(width=constWidth2),
        )

        def cell_edges_toggle_cb(b):
            # self.update()
            if (self.cell_edges_toggle.value):
                self.show_edge = True
            else:
                self.show_edge = False
            self.i_plot.update()

        self.cell_edges_toggle.observe(cell_edges_toggle_cb)

        self.cells_toggle = Checkbox(
            description='Cells',
            disabled=False,
            value=True,
            #           layout=Layout(width=constWidth2),
        )

        def cells_toggle_cb(b):
            # self.update()
            self.i_plot.update()
            if (self.cells_toggle.value):
                self.cell_edges_toggle.disabled = False
                self.cell_nucleus_toggle.disabled = False
            else:
                self.cell_edges_toggle.disabled = True
                self.cell_nucleus_toggle.disabled = True

        self.cells_toggle.observe(cells_toggle_cb)

        #---------------------
        self.substrates_toggle = Checkbox(
            description='Substrates',
            disabled=False,
            value=True,
            #           layout=Layout(width=constWidth2),
        )

        def substrates_toggle_cb(b):
            if (self.substrates_toggle.value):  # seems bass-ackwards
                self.cmap_fixed.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.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, 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])

        row3 = HBox([
            self.frame_slider,
        ])

        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)
            controls_box = VBox([row1, row2,
                                 row3])  # ,width='50%', layout=box_layout)

            # self.tab = VBox([controls_box, self.i_plot, download_row])

            #            graph = GraphWidget()
            # iplot([{"x": [1, 2, 3], "y": [3, 1, 6]}])
            # self.fig = go.FigureWidget(data=go.Bar(y=[2, 3, 1]))

            # x = np.random.randn(2000)
            # y = np.random.randn(2000)
            self.x = np.random.randn(2)
            self.y = np.random.randn(2)
            # iplot([go.Histogram2dContour(x=x, y=y, contours=dict(coloring='heatmap')),
            # self.fig = go.FigureWidget(data=go.Histogram2dContour(x=x, y=y, contours_showlines=False, contours=dict(coloring='heatmap')))
            self.fig = go.FigureWidget(data=go.Histogram2dContour(
                x=self.x, y=self.y, contours=dict(coloring='heatmap')))

            # self.fig = go.FigureWidget( data = [
            #     {
            #     'type' : 'Histogram2dContour',
            #     'x' : self.x,
            #     'y' : self.y,
            #     'contours' : {
            #         'coloring': 'heatmap'
            #     }
            #     },
            #     {
            #     'type' : 'scatter',
            #     'x' : self.x,
            #     'y' : self.y,
            #     'line' : {
            #         'color': 'red',
            #         'width': 3
            #     }
            #     }
            #     ], layout={})
            # self.fig = go.FigureWidget(data=go.Contour(x=x, y=y, contours=dict(coloring='heatmap')))

            # x = np.linspace(-10, 10, 400)
            # y = np.linspace(-5, 5, 400)
            # x, y = np.meshgrid(x, y)
            # a = 1
            # b = 2
            # z = x**2/a**2 - y**2/b**2
            # contour = go.Contour(
            #     z=z
            # )
            # contour.contours.type = 'constraint'
            # contour.contours.value = 8
            # data = [contour]
            # # self.fig = go.Figure(data=data)
            # self.fig = go.FigureWidget(data=data)

            #                go.Scatter(x=x, y=y, mode='markers', marker=dict(color='white', size=3, opacity=0.3)), show_link=False)
            self.fig.update_layout(  # square figure layout for plotly?
                autosize=True,
                margin=dict(l=20, r=20, t=30, b=20),
                width=800,
                height=800,
                # margin=dict(
                #     l=50,
                #     r=50,
                #     b=100,
                #     t=100,
                #     pad=4
                # ),
                # paper_bgcolor="White",
                # paper_bgcolor="LightSteelBlue",
            )

            self.tab = VBox([controls_box, self.fig,
                             download_row])  # plotly approach

            # app_layout = AppLayout(
            #     center= self.fig.canvas,
            #     # footer= self.frame_slider,
            #     pane_heights=[0, 6, 1]
            # )
            # self.tab = app_layout

            # self.tab = VBox([controls_box, self.fig.canvas, download_row])

#        self.fig = plt.figure(figsize=(self.figsize_width_substrate, self.figsize_height_substrate))

        else:
            # self.tab = VBox([row1, row2])
            self.tab = VBox([row1, row2, self.i_plot])
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
    def _create_input_widgets(self):
        self._input["smiles"] = Text(description="SMILES",
                                     continuous_update=False)
        self._input["smiles"].observe(self._show_mol, names="value")
        display(self._input["smiles"])
        self._output["smiles"] = Output(layout={
            "border": "1px solid silver",
            "width": "50%",
            "height": "180px"
        })
        display(self._output["smiles"])

        self._input["stocks"] = [
            Checkbox(value=True, description=key, layout={"justify": "left"})
            for key in self.finder.stock.items
        ]
        box_stocks = VBox(
            [Label("Stocks")] + self._input["stocks"],
            layout={"border": "1px solid silver"},
        )

        self._input["policy"] = widgets.Dropdown(
            options=self.finder.expansion_policy.items,
            description="Expansion Policy:",
            style={"description_width": "initial"},
        )

        self._input["filter"] = widgets.Dropdown(
            options=["None"] + self.finder.filter_policy.items,
            description="Filter Policy:",
            style={"description_width": "initial"},
        )

        max_time_box = self._make_slider_input("time_limit", "Time (min)", 1,
                                               120)
        self._input["time_limit"].value = self.finder.config.time_limit / 60
        max_iter_box = self._make_slider_input("iteration_limit",
                                               "Max Iterations", 100, 2000)
        self._input[
            "iteration_limit"].value = self.finder.config.iteration_limit
        self._input["return_first"] = widgets.Checkbox(
            value=self.finder.config.return_first,
            description="Return first solved route",
        )
        vbox = VBox([
            self._input["policy"],
            self._input["filter"],
            max_time_box,
            max_iter_box,
            self._input["return_first"],
        ])
        box_options = HBox([box_stocks, vbox])

        self._input["C"] = FloatText(description="C",
                                     value=self.finder.config.C)
        self._input["max_transforms"] = BoundedIntText(
            description="Max steps for substrates",
            min=1,
            max=6,
            value=self.finder.config.max_transforms,
            style={"description_width": "initial"},
        )
        self._input["cutoff_cumulative"] = BoundedFloatText(
            description="Policy cutoff cumulative",
            min=0,
            max=1,
            value=self.finder.config.cutoff_cumulative,
            style={"description_width": "initial"},
        )
        self._input["cutoff_number"] = BoundedIntText(
            description="Policy cutoff number",
            min=1,
            max=1000,
            value=self.finder.config.cutoff_number,
            style={"description_width": "initial"},
        )
        self._input["filter_cutoff"] = BoundedFloatText(
            description="Filter cutoff",
            min=0,
            max=1,
            value=self.finder.config.filter_cutoff,
            style={"description_width": "initial"},
        )
        self._input["exclude_target_from_stock"] = widgets.Checkbox(
            value=self.finder.config.exclude_target_from_stock,
            description="Exclude target from stock",
        )
        box_advanced = VBox([
            self._input["C"],
            self._input["max_transforms"],
            self._input["cutoff_cumulative"],
            self._input["cutoff_number"],
            self._input["filter_cutoff"],
            self._input["exclude_target_from_stock"],
        ])

        children = [box_options, box_advanced]
        tab = widgets.Tab()
        tab.children = children
        tab.set_title(0, "Options")
        tab.set_title(1, "Advanced")
        display(tab)
Ejemplo n.º 10
0
    def __init__(self,
                 task_type,
                 observations,
                 output_path,
                 name,
                 classes,
                 show_name=True,
                 show_axis=False,
                 fig_size=(10, 10),
                 buttons_vertical=False,
                 custom_display_function=None,
                 is_image=True):

        if task_type not in self.supported_types:
            raise Exception(labels_str.warn_task_not_supported)

        if len(observations) == 0:
            raise Exception(labels_str.warn_no_images)

        num_classes = len(classes)
        if num_classes <= 1:
            raise Exception(labels_str.warn_little_classes)

        elif len(
                classes
        ) > 2 and task_type.value == TaskType.CLASSIFICATION_BINARY.value:
            raise Exception(labels_str.warn_binary_only_two)

        self.is_image = is_image
        self.key = "path" if self.is_image else "observation"
        if not self.is_image and custom_display_function is None:
            raise Exception(labels_str.warn_display_function_needed)

        self.task_type = task_type
        self.show_axis = show_axis
        self.name = name
        self.show_name = show_name
        self.output_path = output_path
        self.file_path = os.path.join(self.output_path, self.name + ".json")
        print(labels_str.info_ds_output + self.file_path)
        self.mapping, self.dataset = self.__create_results_dict(
            self.file_path, classes)

        self.classes = list(self.mapping["categories_id"].values())

        if len(
                self.classes
        ) > 2 and task_type.value == TaskType.CLASSIFICATION_BINARY.value:
            raise Exception(labels_str.warn_binary_only_two +
                            " ".join(self.classes))

        self.observations = observations
        self.max_pos = len(self.observations) - 1
        self.pos = 0
        self.fig_size = fig_size
        self.buttons_vertical = buttons_vertical

        if custom_display_function is None:
            self.image_display_function = self.__show_image
        else:
            self.image_display_function = custom_display_function

        self.previous_button = self.__create_button(labels_str.str_btn_prev,
                                                    (self.pos == 0),
                                                    self.__on_previous_clicked)
        self.next_button = self.__create_button(labels_str.str_btn_next,
                                                (self.pos == self.max_pos),
                                                self.__on_next_clicked)
        self.save_button = self.__create_button(labels_str.str_btn_download,
                                                False, self.__on_save_clicked)
        self.save_function = self.__save_function  # save_function

        buttons = [self.previous_button, self.next_button, self.save_button]

        label_total = Label(value='/ {}'.format(len(self.observations)))
        self.text_index = BoundedIntText(value=1,
                                         min=1,
                                         max=len(self.observations))
        self.text_index.layout.width = '80px'
        self.text_index.layout.height = '35px'
        self.text_index.observe(self.__selected_index)
        self.out = Output()
        self.out.add_class(name)

        if self.__is_multilabel():
            self.checkboxes = [
                Checkbox(False,
                         description='{}'.format(self.classes[i]),
                         indent=False) for i in range(len(self.classes))
            ]
            for cb in self.checkboxes:
                cb.layout.width = '180px'
                cb.observe(self.__checkbox_changed)
            self.checkboxes_layout = VBox(
                children=[cb for cb in self.checkboxes])
        else:
            self.checkboxes = RadioButtons(options=self.classes,
                                           disabled=False,
                                           indent=False)
            self.checkboxes.layout.width = '180px'
            self.checkboxes.observe(self.__checkbox_changed)
            self.checkboxes_layout = VBox(children=[self.checkboxes])

        output_layout = HBox(children=[self.out, self.checkboxes_layout])
        if self.buttons_vertical:
            self.all_widgets = HBox(children=[
                VBox(children=[HBox([self.text_index, label_total])] +
                     buttons), output_layout
            ])
        else:
            self.all_widgets = VBox(children=[
                HBox([self.text_index, label_total]),
                HBox(children=buttons), output_layout
            ])

        ## loading js library to perform html screenshots
        j_code = """
                require.config({
                    paths: {
                        html2canvas: "https://html2canvas.hertzen.com/dist/html2canvas.min"
                    }
                });
            """
        display(Javascript(j_code))
Ejemplo n.º 11
0
    def __init__(self):
        self.mp4_zip_file = "cells_mp4.zip"
        self.mp4_file = "cells.mp4"

        self.instructions = Label(
            "After a simulation completes, generate a video of cells (from SVG files). Does not work for cached results yet."
        )
        self.feedback = Label("                            ")
        # self.feedback.value = "Converting all svg to jpg..."

        self.gen_button = Button(
            description='Generate video',
            button_style=
            'success',  # 'success', 'info', 'warning', 'danger' or ''
            tooltip='Generate a MP4 video of cells',
        )
        self.gen_button.disabled = True
        self.gen_button.on_click(self.gen_button_cb)

        fps_style = {'description_width': '35%'}
        fps_layout = {'width': '85px'}
        # tooltip='frames per sec',  -- tooltip not available for *Text !
        self.fps = BoundedIntText(description="fps=",
                                  value=5,
                                  min=1,
                                  max=30,
                                  step=1,
                                  style=fps_style,
                                  layout=fps_layout)

        size_style = {'description_width': '50%'}
        size_layout = {'width': '150px'}
        self.size = BoundedIntText(description="w,h(pixels)=",
                                   value=500,
                                   min=250,
                                   max=1500,
                                   step=10,
                                   disabled=False,
                                   tooltip='width, height of video',
                                   style=size_style,
                                   layout=size_layout)

        self.video = HTML(value="",
                          placeholder='',
                          description='',
                          layout=Layout(visibility='hidden'))

        if (hublib_flag):
            self.download_mp4_button = Download(
                self.mp4_zip_file,
                style='success',
                icon='cloud-download',
                tooltip=
                'Download mp4 (you need to allow pop-ups in your browser)')
            self.download_mp4_button.w.disabled = True

            self.tab = VBox([
                self.instructions,
                HBox([
                    self.gen_button, self.fps, self.size, self.feedback,
                    self.download_mp4_button.w
                ]), self.video
            ])
        else:
            self.tab = VBox([
                self.instructions,
                HBox([self.gen_button, self.fps, self.size, self.feedback]),
                self.video
            ])
Ejemplo n.º 12
0
class DatasetAnnotatorClassification:
    supported_types = [
        TaskType.CLASSIFICATION_BINARY, TaskType.CLASSIFICATION_SINGLE_LABEL,
        TaskType.CLASSIFICATION_MULTI_LABEL
    ]

    def __init__(self,
                 task_type,
                 observations,
                 output_path,
                 name,
                 classes,
                 show_name=True,
                 show_axis=False,
                 fig_size=(10, 10),
                 buttons_vertical=False,
                 custom_display_function=None,
                 is_image=True):

        if task_type not in self.supported_types:
            raise Exception(labels_str.warn_task_not_supported)

        if len(observations) == 0:
            raise Exception(labels_str.warn_no_images)

        num_classes = len(classes)
        if num_classes <= 1:
            raise Exception(labels_str.warn_little_classes)

        elif len(
                classes
        ) > 2 and task_type.value == TaskType.CLASSIFICATION_BINARY.value:
            raise Exception(labels_str.warn_binary_only_two)

        self.is_image = is_image
        self.key = "path" if self.is_image else "observation"
        if not self.is_image and custom_display_function is None:
            raise Exception(labels_str.warn_display_function_needed)

        self.task_type = task_type
        self.show_axis = show_axis
        self.name = name
        self.show_name = show_name
        self.output_path = output_path
        self.file_path = os.path.join(self.output_path, self.name + ".json")
        print(labels_str.info_ds_output + self.file_path)
        self.mapping, self.dataset = self.__create_results_dict(
            self.file_path, classes)

        self.classes = list(self.mapping["categories_id"].values())

        if len(
                self.classes
        ) > 2 and task_type.value == TaskType.CLASSIFICATION_BINARY.value:
            raise Exception(labels_str.warn_binary_only_two +
                            " ".join(self.classes))

        self.observations = observations
        self.max_pos = len(self.observations) - 1
        self.pos = 0
        self.fig_size = fig_size
        self.buttons_vertical = buttons_vertical

        if custom_display_function is None:
            self.image_display_function = self.__show_image
        else:
            self.image_display_function = custom_display_function

        self.previous_button = self.__create_button(labels_str.str_btn_prev,
                                                    (self.pos == 0),
                                                    self.__on_previous_clicked)
        self.next_button = self.__create_button(labels_str.str_btn_next,
                                                (self.pos == self.max_pos),
                                                self.__on_next_clicked)
        self.save_button = self.__create_button(labels_str.str_btn_download,
                                                False, self.__on_save_clicked)
        self.save_function = self.__save_function  # save_function

        buttons = [self.previous_button, self.next_button, self.save_button]

        label_total = Label(value='/ {}'.format(len(self.observations)))
        self.text_index = BoundedIntText(value=1,
                                         min=1,
                                         max=len(self.observations))
        self.text_index.layout.width = '80px'
        self.text_index.layout.height = '35px'
        self.text_index.observe(self.__selected_index)
        self.out = Output()
        self.out.add_class(name)

        if self.__is_multilabel():
            self.checkboxes = [
                Checkbox(False,
                         description='{}'.format(self.classes[i]),
                         indent=False) for i in range(len(self.classes))
            ]
            for cb in self.checkboxes:
                cb.layout.width = '180px'
                cb.observe(self.__checkbox_changed)
            self.checkboxes_layout = VBox(
                children=[cb for cb in self.checkboxes])
        else:
            self.checkboxes = RadioButtons(options=self.classes,
                                           disabled=False,
                                           indent=False)
            self.checkboxes.layout.width = '180px'
            self.checkboxes.observe(self.__checkbox_changed)
            self.checkboxes_layout = VBox(children=[self.checkboxes])

        output_layout = HBox(children=[self.out, self.checkboxes_layout])
        if self.buttons_vertical:
            self.all_widgets = HBox(children=[
                VBox(children=[HBox([self.text_index, label_total])] +
                     buttons), output_layout
            ])
        else:
            self.all_widgets = VBox(children=[
                HBox([self.text_index, label_total]),
                HBox(children=buttons), output_layout
            ])

        ## loading js library to perform html screenshots
        j_code = """
                require.config({
                    paths: {
                        html2canvas: "https://html2canvas.hertzen.com/dist/html2canvas.min"
                    }
                });
            """
        display(Javascript(j_code))

    def __create_results_dict(self, file_path, cc):
        mapping = {
            "categories_id": {},
            "categories_name": {},
            "observations": {}
        }

        if not os.path.exists(file_path):
            dataset = {'categories': [], "observations": []}
            for index, c in enumerate(cc):
                category = {"supercategory": c, "name": c, "id": index + 1}
                dataset["categories"].append(category)
        else:
            with open(file_path, 'r') as classification_file:
                dataset = json.load(classification_file)
            for index, img in enumerate(dataset['observations']):
                mapping['observations'][img[self.key]] = index

        for c in dataset['categories']:
            mapping['categories_id'][c["id"]] = c["name"]
            mapping['categories_name'][c["name"]] = c["id"]
        index_categories = len(dataset['categories']) + 1

        for c in cc:
            if not c in mapping['categories_name'].keys():
                mapping['categories_id'][index_categories] = c
                mapping['categories_name'][c] = index_categories
                category = {
                    "supercategory": c,
                    "name": c,
                    "id": index_categories
                }
                dataset["categories"].append(category)
                index_categories += 1

        return mapping, dataset

    def __checkbox_changed(self, b):

        if b['owner'].value is None or b['name'] != 'value':
            return

        class_name = b['owner'].description
        value = b['owner'].value
        current_index = self.mapping["observations"][self.observations[
            self.pos]]

        if self.__is_multilabel():
            class_index = self.mapping["categories_name"][class_name]
            if not class_index in self.dataset["observations"][current_index][
                    "categories"] and value:
                self.dataset["observations"][current_index][
                    "categories"].append(class_index)
            if class_index in self.dataset["observations"][current_index][
                    "categories"] and not value:
                self.dataset["observations"][current_index][
                    "categories"].remove(class_index)
        else:
            class_index = self.mapping["categories_name"][value]
            self.dataset["observations"][current_index][
                "category"] = class_index

        if self.pos == self.max_pos:
            self.save_state()

    def __is_multilabel(self):
        return TaskType.CLASSIFICATION_MULTI_LABEL.value == self.task_type.value

    def __create_button(self, description, disabled, function):
        button = Button(description=description)
        button.disabled = disabled
        button.on_click(function)
        return button

    def __show_image(self, image_record):
        if not 'path' in image_record:
            print("missing path")
        if not os.path.exists(image_record['path']):
            print("Image cannot be load" + image_record['path'])

        img = Image.open(image_record['path'])
        if self.show_name:
            print(os.path.basename(image_record['path']))
        plt.figure(figsize=self.fig_size)
        if not self.show_axis:
            plt.axis('off')
        plt.imshow(img)
        plt.show()

    def save_state(self):
        with open(self.file_path, 'w') as output_file:
            json.dump(self.dataset, output_file, indent=4)

    def __save_function(self, image_path, index):
        img_name = os.path.basename(image_path).split('.')[0]
        j_code = """
            require(["html2canvas"], function(html2canvas) {
                var element = $(".p-Widget.jupyter-widgets-output-area.output_wrapper.$it_name$")[0];
                console.log(element);
                 html2canvas(element).then(function (canvas) { 
                    var myImage = canvas.toDataURL(); 
                    var a = document.createElement("a"); 
                    a.href = myImage; 
                    a.download = "$img_name$.png"; 
                    a.click(); 
                    a.remove(); 
                });
            });
            """
        j_code = j_code.replace('$it_name$', self.name)
        j_code = j_code.replace('$img_name$', img_name)
        tmp_out = Output()
        with tmp_out:
            display(Javascript(j_code))
            tmp_out.clear_output()

    def __perform_action(self):

        if not self.observations[
                self.pos] in self.mapping["observations"].keys():
            observation = {self.key: self.observations[self.pos]}
            if self.is_image:
                observation["file_name"] = os.path.basename(
                    self.observations[self.pos])

            observation["id"] = len(self.mapping["observations"]) + 1
            if self.__is_multilabel():
                observation["categories"] = []
            self.dataset["observations"].append(observation)

            self.mapping["observations"][observation[self.key]] = len(
                self.dataset["observations"]) - 1

        current_index = self.mapping["observations"][self.observations[
            self.pos]]
        self.next_button.disabled = (self.pos == self.max_pos)
        self.previous_button.disabled = (self.pos == 0)

        if self.__is_multilabel():
            for cb in self.checkboxes:
                cb.unobserve(self.__checkbox_changed)
                if not "categories" in self.dataset["observations"][
                        current_index]:
                    self.dataset["observations"][current_index][
                        "categories"] = []
                categories = self.dataset["observations"][current_index][
                    "categories"]
                cb.value = self.mapping["categories_name"][
                    cb.description] in categories
                cb.observe(self.__checkbox_changed)
        else:
            self.checkboxes.unobserve(self.__checkbox_changed)
            obs = self.dataset["observations"][current_index]
            category = obs["category"] if "category" in obs else None

            if category:
                for k in self.mapping["categories_name"]:
                    if self.mapping["categories_name"][k] == category:
                        category = k
                        break
            self.checkboxes.value = category
            self.checkboxes.observe(self.__checkbox_changed)

        with self.out:
            self.out.clear_output()
            self.image_display_function(
                self.dataset["observations"][current_index])

        self.text_index.unobserve(self.__selected_index)
        self.text_index.value = self.pos + 1
        self.text_index.observe(self.__selected_index)

    def __on_previous_clicked(self, b):
        self.save_state()
        self.pos -= 1
        self.__perform_action()

    def __on_next_clicked(self, b):
        self.save_state()
        self.pos += 1
        self.__perform_action()

    def __on_save_clicked(self, b):
        self.save_state()
        self.save_function(self.observations[self.pos], self.pos)

    def __selected_index(self, t):
        if t['owner'].value is None or t['name'] != 'value':
            return
        self.pos = t['new'] - 1
        self.__perform_action()

    def start_classification(self):
        if self.max_pos < self.pos:
            print("No available observation")
            return
        display(self.all_widgets)
        self.__perform_action()

    def print_statistics(self):
        counter = dict()
        for c in self.mapping["categories_id"]:
            counter[c] = 0

        for record in self.dataset["observations"]:

            if self.__is_multilabel():
                if "categories" in record:
                    for c in record["categories"]:
                        counter[c] += 1
            elif "category" in record:
                counter[record["category"]] += 1

        table = []
        for c in counter:
            table.append([self.mapping["categories_id"][c], counter[c]])
        table = sorted(table, key=lambda x: x[0])

        print(
            tabulate(table,
                     headers=[
                         labels_str.info_class_name, labels_str.info_ann_images
                     ]))
    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))

        config_file = "data/PhysiCell_settings.xml"

        self.cell_lines = {}
        self.cell_lines_by_name = {}
        self.cell_lines_array = ["All"]

        if os.path.isfile(config_file):

            try:
                tree = ET.parse(config_file)
            except:
                print("Cannot parse", config_file, "- check it's XML syntax.")
                return

            root = tree.getroot()
            uep = root.find(
                './/cell_definitions')  # find unique entry point (uep)
            for child in uep.findall('cell_definition'):
                self.cell_lines[int(child.attrib["ID"])] = child.attrib["name"]
                self.cell_lines_by_name[child.attrib["name"]] = int(
                    child.attrib["ID"])
                self.cell_lines_array.append(child.attrib["name"])
                # print(child.attrib['name'])
        else:
            print("config.xml does not exist")

        max_frames = 0
        self.svg_plot = interactive(self.create_area_chart,
                                    frame=(0, max_frames),
                                    percentage=(0.0, 10.0),
                                    total=False,
                                    cell_line=self.cell_lines_array,
                                    continuous_update=False)
        plot_size = '500px'  # small: controls the size of the tab height, not the plot (rf. figsize for that)
        plot_size = '700px'  # medium
        plot_size = '750px'  # medium
        self.svg_plot.layout.width = '1000px'
        self.svg_plot.layout.height = '700px'
        self.use_defaults = True

        self.axes_min = 0.0
        self.axes_max = 2000  # hmm, this can change (TODO?)

        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)

        items_auto = [
            Label('select slider: drag or left/right arrows'),
            self.max_frames,
        ]

        box_layout = Layout(display='flex',
                            flex_flow='row',
                            align_items='stretch',
                            width='70%')
        row1 = Box(children=items_auto, layout=box_layout)

        self.tab = VBox([row1, self.svg_plot])
        self.count_dict = {}
        self.file_dict = {}
class PhysiBoSSTab(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))

        config_file = "data/PhysiCell_settings.xml"

        self.cell_lines = {}
        self.cell_lines_by_name = {}
        self.cell_lines_array = ["All"]

        if os.path.isfile(config_file):

            try:
                tree = ET.parse(config_file)
            except:
                print("Cannot parse", config_file, "- check it's XML syntax.")
                return

            root = tree.getroot()
            uep = root.find(
                './/cell_definitions')  # find unique entry point (uep)
            for child in uep.findall('cell_definition'):
                self.cell_lines[int(child.attrib["ID"])] = child.attrib["name"]
                self.cell_lines_by_name[child.attrib["name"]] = int(
                    child.attrib["ID"])
                self.cell_lines_array.append(child.attrib["name"])
                # print(child.attrib['name'])
        else:
            print("config.xml does not exist")

        max_frames = 0
        self.svg_plot = interactive(self.create_area_chart,
                                    frame=(0, max_frames),
                                    percentage=(0.0, 10.0),
                                    total=False,
                                    cell_line=self.cell_lines_array,
                                    continuous_update=False)
        plot_size = '500px'  # small: controls the size of the tab height, not the plot (rf. figsize for that)
        plot_size = '700px'  # medium
        plot_size = '750px'  # medium
        self.svg_plot.layout.width = '1000px'
        self.svg_plot.layout.height = '700px'
        self.use_defaults = True

        self.axes_min = 0.0
        self.axes_max = 2000  # hmm, this can change (TODO?)

        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)

        items_auto = [
            Label('select slider: drag or left/right arrows'),
            self.max_frames,
        ]

        box_layout = Layout(display='flex',
                            flex_flow='row',
                            align_items='stretch',
                            width='70%')
        row1 = Box(children=items_auto, layout=box_layout)

        self.tab = VBox([row1, self.svg_plot])
        self.count_dict = {}
        self.file_dict = {}

    def update(self, rdir=''):
        # with debug_view:
        #     print("SVG: update rdir=", rdir)

        if rdir:
            self.output_dir = rdir

        all_files = sorted(
            glob.glob(os.path.join(self.output_dir, 'snapshot*.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"

        # self.create_dict(self.max_frames.value, self.output_dir)
        # self.state_counter(self.max_frames.value)

        # with debug_view:
        #     print("SVG: added %s files" % len(all_files))

    def update_max_frames(self, _b):
        self.svg_plot.children[0].max = self.max_frames.value

    #-------------------------
    def plot_states(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)

        if not os.path.isfile(full_fname):
            print("Once output files are generated, click the slider.")
            return

        tree = ET.parse(full_fname)
        root = tree.getroot()

        numChildren = 0
        for child in root:

            if self.use_defaults and ('width' in child.attrib.keys()):
                self.axes_max = float(child.attrib['width'])

            if child.text and "Current time" in child.text:
                svals = child.text.split()
                title_str = svals[2] + "d, " + svals[4] + "h, " + svals[7] + "m"

        title_str += " (" + str(num_cells) + " agents)"
        self.fig = plt.figure(figsize=(15, 15))

        plt.xlim(self.axes_min, self.axes_max)
        plt.ylim(self.axes_min, self.axes_max)

        plt.title(title_str)

    def create_dict(self, number_of_files, folder, cells_indexes):
        "create a dictionary with the states file in the folder 'output', half of the dict is used to calculate the percentage of the node, the other half is for the states"
        # if not os.path.isfile("%sstates_00000000.csv" % folder):
        #     return

        self.file_dict = {}
        if number_of_files > 0:
            for i in range(0, number_of_files):
                nodes_dict = {}
                states_dict = {}
                with open('%s//states_%08u.csv' % (folder, i),
                          newline='') as csvfile:
                    states_reader = csv.reader(csvfile, delimiter=',')

                    for row in states_reader:
                        if row[0] != 'ID' and (cells_indexes is None or int(
                                row[0]) in cells_indexes):
                            states_dict[row[0]] = row[1]
                            nodes_dict[row[0]] = row[1].replace("--",
                                                                "").split()
                self.file_dict["node_step{0}".format(i)] = nodes_dict
                self.file_dict["state_step{0}".format(i)] = states_dict

                # print(self.file_dict)
            # return file_dict

    def state_counter(self, number_of_files, percentage):
        "create a dict with the states of the network, it can be used to print states pie chart"
        self.count_dict = {}
        temp_dict = {}
        max_cell = 0
        if number_of_files > 0:
            for i in range(0, number_of_files):
                state_list = []
                for key in self.file_dict["state_step{0}".format(i)]:
                    state_list.append(
                        self.file_dict["state_step{0}".format(i)][key])
                state_counts = Counter(state_list)
                max_cell = max_cell + sum(state_counts.values())
                #fix_count_dict = {}
                #for key, group in itertools.groupby(state_counts, lambda k: 'others' if (state_counts[k]<(0.01* (len(self.file_dict["state_step%s" %(i)])))) else k):
                #fix_count_dict[key] = sum([state_counts[k] for k in list(group)])
                temp_dict["state_count{0}".format(i)] = state_counts
            self.count_dict = self.filter_states(max_cell, temp_dict,
                                                 percentage)
            # return self.count_dict

    def create_area_chart(self,
                          frame=None,
                          total=False,
                          percentage=(0.0, 100.0),
                          cell_line="All"):
        "plot an area chart with the evolution of the network states during the simulation"

        cells_indexes = None
        if cell_line != "All":
            cells_indexes = set()
            for i in range(0, frame):
                fname = "output%08d_cells_physicell.mat" % i
                full_fname = os.path.join(self.output_dir, fname)

                if not os.path.isfile(full_fname):
                    print("Once output files are generated, click the slider."
                          )  # No:  output00000000_microenvironment0.mat
                    return

                info_dict = {}
                scipy.io.loadmat(full_fname, info_dict)

                M = info_dict['cells'][[0, 5], :].astype(int)

                cell_line_index = self.cell_lines_by_name[cell_line]
                indexes = np.where(M[1, :] == cell_line_index)
                cells_indexes = cells_indexes.union(set(M[0, indexes][0]))

            cells_indexes = list(cells_indexes)

            if len(cells_indexes) == 0:
                print("There are no %s cells." % cell_line)
                return

        self.create_dict(frame, self.output_dir, cells_indexes)
        self.state_counter(frame, percentage)

        state_list = []
        all_state = []
        a = []
        for k in self.count_dict:
            state_list.append(list(self.count_dict[k].keys()))
            for l in state_list:
                for state in l:
                    all_state.append(state)
        all_state = list(dict.fromkeys(all_state))

        for state_count in self.count_dict:
            b = []
            for states in all_state:
                try:
                    b.append(self.count_dict[state_count][states])
                except:
                    b.append(0)
            a.append(b)
        a = np.array(a)
        #print(a)
        a = np.transpose(a)
        if not total:
            percent = a / a.sum(axis=0).astype(float) * 100
        else:
            percent = a
        x = np.arange(len(self.count_dict))
        self.fig = plt.figure(figsize=(10, 5), dpi=200)
        ax = self.fig.add_subplot(111)
        ax.stackplot(x, percent, labels=all_state)
        ax.legend(labels=all_state,
                  loc='upper center',
                  bbox_to_anchor=(0.5, -0.05),
                  shadow=True,
                  ncol=2)
        # ax.legend(labels=all_state, bbox_to_anchor=(1.05, 1), loc='lower center', borderaxespad=0.)
        ax.set_title('100 % stacked area chart')
        if not total:
            ax.set_ylabel('Percent (%)')
        else:
            ax.set_ylabel("Total")
        ax.margins(0, 0)  # Set margins to avoid "whitespace"

        # plt.show()

    def filter_states(self, max_cell, all_counts, percentage):
        """max_cell = 0
        all_counts = {}
        for i in range (0, number_of_files):
            state_list = []
            for key in file_dict["state_step{0}".format(i)]:
                state_list.append(file_dict["state_step{0}".format(i)][key])
            state_counts = Counter(state_list)
            max_cell = max_cell + sum(state_counts.values())
            all_counts[i] = state_counts"""

        copy_all_counts = copy.deepcopy(all_counts)

        state_list = []
        all_state = []
        for k in all_counts:
            state_list.append(list(all_counts[k].keys()))
            for l in state_list:
                for state in l:
                    all_state.append(state)
        all_state = list(dict.fromkeys(all_state))

        banned_list = []
        for state in all_state:
            a = 0
            for i in all_counts.keys():
                try:
                    a = a + all_counts[i][state]
                except:
                    a = a + 0
            if (a < (percentage / 100) * max_cell):
                banned_list.append(state)
                for i in all_counts.keys():
                    del all_counts[i][state]

        for i in all_counts.keys():
            b = 0
            for state in banned_list:
                try:
                    b = b + copy_all_counts[i][state]
                except:
                    b = b + 0
            all_counts[i]["others"] = b

        return all_counts
Ejemplo n.º 15
0
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 = {'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'))
        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])

    #---------------------------------------------------
    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)
#            return
        except:
            print("Cannot open ",fname," to get 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
        # 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("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
        #     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
Ejemplo n.º 16
0
    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,
            ])
Ejemplo n.º 17
0
    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 = {'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'))
        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])
Ejemplo n.º 18
0
def plot_interactive_multiple_slicing(array,
                                      axes,
                                      slice_indexes,
                                      model_array=None,
                                      cmap='viridis',
                                      update_colorbar=False,
                                      vmin=0.,
                                      vmax=1.,
                                      extent=None,
                                      clabel='',
                                      xlabel='',
                                      ylabel='',
                                      figsize=None):
    '''
    Plot 2D slices of a ND NumPy array, with the possibility to loop through and
    visualize the slices
    
    @param array: A ND NumPy array
    @param axes: A list of N - 2 elements that contains the indexes of the axes 
                 to slice
    @param slice_indexes: A list of N - 2 elements that contains the initial 
                          slice to show for each axis
    @param model_array: A 2D NumPy array to compare to the slices
    @param cmap: A colormap for the array
    @param update_colorbar: True if the colorbar must be updated between each 
                            slice, false otherwise
    @param v_min: The minimal value of the colorbar if update_colorbar if false 
                  and no model is used
    @param v_max: The maximal value of the colorbar if update_colorbar if false 
                  and no model is used
    @param extent: The spatial extent of the slice
    @param clabel: A label for the colorbar
    @param xlabel: A label for the x axis
    @param ylabel: A label for the y axis
    @param figsize: A 2D tuple for the figure size
    '''
    assert len(set(axes)) == len(axes), "Axes must be unique"
    assert len(slice_indexes) == len(
        axes), "Slice indexes and axes should have the same length"
    assert array.ndim - len(
        axes) == 2, "The plotted array should be two-dimensional"

    s = [slice(None) for i in range(array.ndim)]
    for axis, slice_index in zip(axes, slice_indexes):
        s[axis] = slice(slice_index, slice_index + 1)
    sliced_array = array[s].squeeze()

    if update_colorbar == False:
        if model_array is not None:
            vmin = np.nanmin(model_array)
            vmax = np.nanmax(model_array)
    else:
        vmin = np.nanmin(sliced_array)
        vmax = np.nanmax(sliced_array)

    number_plots = 1
    if model_array is not None:
        number_plots = 2

    figure, subplots = plt.subplots(1,
                                    number_plots,
                                    sharex=True,
                                    sharey=True,
                                    figsize=figsize)

    subplot = subplots
    if model_array is not None:
        subplot = subplots[1]

        model_raster_map = subplots[0].imshow(
            np.ma.masked_invalid(model_array),
            extent=extent,
            cmap=cmap,
            interpolation='None',
            rasterized=True,
            vmin=vmin,
            vmax=vmax,
            zorder=0)
        subplots[0].set_xlabel(xlabel)
        subplots[0].set_ylabel(ylabel)

    raster_map = subplot.imshow(np.ma.masked_invalid(sliced_array),
                                extent=extent,
                                cmap=cmap,
                                interpolation='None',
                                rasterized=True,
                                vmin=vmin,
                                vmax=vmax,
                                zorder=0)
    raster_map_colorbar = plt.colorbar(raster_map, ax=subplots)
    raster_map_colorbar.set_label(clabel)
    if model_array is None:
        subplot.set_ylabel(ylabel)
    subplot.set_xlabel(xlabel)

    plt.show()

    def update_imshow(new_axis, new_slice_index):
        s[new_axis] = slice(new_slice_index, new_slice_index + 1)
        sliced_array = array[s].squeeze()
        raster_map.set_data(sliced_array)
        if update_colorbar == True:
            raster_map.set_clim(vmin=np.nanmin(sliced_array),
                                vmax=np.nanmax(sliced_array))
            if model_array is not None:
                model_raster_map.set_clim(vmin=np.nanmin(sliced_array),
                                          vmax=np.nanmax(sliced_array))

    for axis, slice_index in zip(axes, slice_indexes):
        axis_widget = Dropdown(options=[axis],
                               value=axis,
                               description='Axis',
                               disabled=False)
        slice_widget = BoundedIntText(value=slice_index,
                                      min=0,
                                      max=array.shape[axis] - 1,
                                      step=1,
                                      description='Slice',
                                      continuous_update=False)
        widget = interactive(update_imshow,
                             new_axis=axis_widget,
                             new_slice_index=slice_widget)
        box = HBox(widget.children)
        display(box)
Ejemplo n.º 19
0
    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)
Ejemplo n.º 20
0
def plot_interactive_slicing(array,
                             slice_index,
                             model_array=None,
                             axis=0,
                             cmap='viridis',
                             extent=None,
                             clabel='',
                             xlabel='',
                             ylabel='',
                             figsize=None,
                             update_colorbar=False):
    '''
    Plot 2D slices of a 3D NumPy array, with the possibility to loop through and
    visualize the slices
    
    @param array: A 3D NumPy array
    @param slice_index: The initial slice to show
    @param model_array: A 2D NumPy array to compare to the realizations
    @param axis: The axis perpendicular to the slices
    @param cmap: A colormap for the array
    @param extent: The spatial extent of the slice
    @param clabel: A label for the colorbar
    @param xlabel: A label for the x axis
    @param ylabel: A label for the y axis
    @param figsize: A 2D tuple for the figure size
    @param update_colorbar: True if the colorbar must be updated between each
                            slice, false otherwise
    '''
    s = [
        slice(slice_index, slice_index + 1) if i == axis else slice(None)
        for i in range(3)
    ]
    sliced_array = array[s].squeeze()

    min_value = 0.
    max_value = 1.
    if update_colorbar == False:
        if model_array is None:
            min_value, max_value = average_minmax_slices(array, axis=axis)
        else:
            min_value = np.nanmin(model_array)
            max_value = np.nanmax(model_array)
    else:
        min_value = np.nanmin(sliced_array)
        max_value = np.nanmax(sliced_array)

    number_plots = 1
    if model_array is not None:
        number_plots = 2

    figure, subplots = plt.subplots(1,
                                    number_plots,
                                    sharex=True,
                                    sharey=True,
                                    figsize=figsize)

    subplot = subplots
    if model_array is not None:
        subplot = subplots[1]

        model_raster_map = subplots[0].imshow(
            np.ma.masked_invalid(model_array),
            extent=extent,
            cmap=cmap,
            interpolation='None',
            rasterized=True,
            vmin=min_value,
            vmax=max_value,
            zorder=0)
        subplots[0].set_xlabel(xlabel)
        subplots[0].set_ylabel(ylabel)

    raster_map = subplot.imshow(np.ma.masked_invalid(sliced_array),
                                extent=extent,
                                cmap=cmap,
                                interpolation='None',
                                rasterized=True,
                                vmin=min_value,
                                vmax=max_value,
                                zorder=0)
    raster_map_colorbar = plt.colorbar(raster_map, ax=subplots)
    raster_map_colorbar.set_label(clabel)
    if model_array is None:
        subplot.set_ylabel(ylabel)
    subplot.set_xlabel(xlabel)

    plt.show()

    def update_imshow(new_slice_index):
        s = [
            slice(new_slice_index, new_slice_index +
                  1) if i == axis else slice(None) for i in range(3)
        ]
        sliced_array = array[s].squeeze()
        raster_map.set_data(sliced_array)
        if update_colorbar == True:
            raster_map.set_clim(vmin=np.nanmin(sliced_array),
                                vmax=np.nanmax(sliced_array))
            if model_array is not None:
                model_raster_map.set_clim(vmin=np.nanmin(sliced_array),
                                          vmax=np.nanmax(sliced_array))

    interactive_plot = interact(update_imshow,
                                new_slice_index=BoundedIntText(
                                    value=slice_index,
                                    min=0,
                                    max=array.shape[axis] - 1,
                                    step=1,
                                    description='Slice',
                                    continuous_update=False))

    plt.draw()
Ejemplo n.º 21
0
class ImBox(VBox):
    """Widget for inspecting images that contain bounding boxes."""
    def __init__(self,
                 df: pd.DataFrame,
                 box_col: str = 'box',
                 img_col: str = 'image',
                 text_cols: Union[str, List[str]] = None,
                 text_fmts: Union[Callable, List[Callable]] = None,
                 style_col: str = None):
        """
        :param pd.DataFrame df: `DataFrame` with images and boxes
        :param str box_col: column in the dataframe that contains boxes
        :param str img_col: column in the dataframe that contains image paths
        :param Union[str, List[str]] text_cols: (optional) the column(s) in the
        dataframe to use for creating the text that is shown on top of a box.
        When multiple columns are give, the text will be created by a
        comma-separated list of the contents of the given columns.
        :param Unions[Callable, List[Callable]] text_fmts: (optional) a
        callable, or list of callables, that takes the corresponding value from
        the `text_cols` column(s) as an input and returns the string to print
        for that value.
        :param str style_col: the column containing a dict of style attributes.
        Available attributes are:
            - `stroke_width`: the stroke width of a box (default 2)
            - `stroke_color`: the stroke color of a box (default 'red')
            - `fill_color`: the fill color of a box (default  '#00000000')
            - `hover_fill`: the fill color of a box when it is hovered on
              (default '#00000088')
            - `hover_stroke`: the stroke color of a box when it is hovered on
              (default 'blue')
            - `active_fill`: the fill color of a box when it is clicked on
              (default '#ffffff22')
            - `active_stroke`: the stroke color of a box when it is clicked on
              (default 'green')
            - `font_family`: the font family to use for box text (default
            'arial'). NOTE: exported text will always be Arial.
            - `font_size`: the font size in points (default 10)
        """
        if text_cols is None:
            text_cols = []
        if isinstance(text_cols, str):
            text_cols = [text_cols]
        if text_fmts is None:
            text_fmts = [None] * len(text_cols)
        if isinstance(text_fmts, Callable):
            text_fmts = [text_fmts]
        self.text_cols = text_cols
        self.text_fmts = text_fmts

        df2 = df.copy()

        def row2text(row):
            txts = row[text_cols]
            return ', '.join([
                fmt(txt) if fmt is not None else str(txt)
                for txt, fmt in zip(txts, self.text_fmts)
            ])

        if style_col is None:
            style_col = '_dfim_style'
            df2[style_col] = [DEFAULT_STYLE] * len(df2)
        else:
            df2[style_col] = df2[style_col].apply(lambda s: {
                k: s[k] if k in s else DEFAULT_STYLE[k]
                for k in DEFAULT_STYLE
            })

        df2['box_text'] = df2.apply(lambda row: row2text(row), axis=1)
        df2['box_dict'] = df2.apply(
            lambda row: dict(index=row.name,
                             box=row[box_col],
                             text=row['box_text'],
                             style=row[style_col])
            if (box_col in row.index and row[box_col] is not None) else None,
            axis=1)

        self.df_img = df2.groupby(img_col).agg(list).reset_index()
        self.df = df
        self.img_col = img_col
        self.box_col = box_col

        # SELECTION widget
        self.idx_wgt = BoundedIntText(value=0,
                                      min=0,
                                      max=len(self.df_img) - 1,
                                      step=1,
                                      description='Choose index',
                                      disabled=False)
        self.drop_wgt = Dropdown(options=self.df_img[img_col],
                                 description='or image',
                                 value=None,
                                 disabled=False)
        self.drop_wgt.observe(self.drop_changed, names='value')
        self.idx_wgt.observe(self.idx_changed, names='value')
        self.imsel_wgt = VBox([self.idx_wgt, self.drop_wgt])
        self.imsel_wgt.layout = Layout(margin='auto')

        # IMAGE PANE
        self.img_title = HTML(placeholder='(Image path)')
        self.img_title.layout = Layout(margin='auto')
        self.imbox_wgt = ImBoxWidget()
        self.imbox_wgt.layout = Layout(margin='1em auto')
        self.imbox_wgt.observe(self.box_changed, names='active_box')
        self.imbox_wgt.observe(self.img_changed, names='img')

        # DETAILS PANE
        self.crop_wgt = CropBoxWidget()
        self.crop_wgt.layout = Layout(margin='0 1em')
        self.detail_wgt = DetailsWidget()
        self.detail_wgt.layout = Layout(margin='auto')
        self.detail_pane = HBox([self.crop_wgt, self.detail_wgt])
        self.detail_pane.layout = Layout(margin='1em auto')

        # PLAY widget
        self.play_btns = Play(interval=100,
                              value=0,
                              min=0,
                              max=len(self.df_img) - 1,
                              step=1,
                              description="Play",
                              disabled=False)
        self.play_slider = widgets.IntSlider(value=0,
                                             min=0,
                                             max=len(self.df_img) - 1,
                                             step=1)
        widgets.jslink((self.play_btns, 'value'), (self.idx_wgt, 'value'))
        widgets.jslink((self.play_btns, 'value'), (self.play_slider, 'value'))

        self.play_wgt = widgets.HBox([self.play_btns, self.play_slider])
        self.play_wgt.layout = Layout(margin='auto')

        # IMAGE EXPORT widget
        self.imexp_dest = Text(description='Output file',
                               value='output/output.png')
        self.imexp_btn = Button(description='Export')
        self.imexp_btn.on_click(self.export_img)
        self.imexp_wgt = HBox([self.imexp_dest, self.imexp_btn])

        # VIDEO EXPORT widget
        self.videxp_dest = Text(description='Output file',
                                value='output/output.mp4')
        self.videxp_start = BoundedIntText(value=0,
                                           min=0,
                                           max=len(self.df_img) - 1,
                                           step=1,
                                           description='From index',
                                           disabled=False)
        self.videxp_start.observe(self.vididx_changed, names='value')
        self.videxp_end = BoundedIntText(value=0,
                                         min=0,
                                         max=len(self.df_img) - 1,
                                         step=1,
                                         description='Until index',
                                         disabled=False)
        self.videxp_end.observe(self.vididx_changed, names='value')
        self.videxp_fps = FloatText(value=30, description='FPS')
        self.videxp_btn = Button(description='Export')
        self.videxp_btn.on_click(self.export_vid)

        self.videxp_wgt = VBox([
            HBox([self.videxp_start, self.videxp_end]),
            HBox([self.videxp_dest, self.videxp_fps]), self.videxp_btn
        ])
        self.exp_wgt = Tab(children=[self.imexp_wgt, self.videxp_wgt])
        self.exp_wgt.set_title(0, 'Export image')
        self.exp_wgt.set_title(1, 'Export video')
        self.exp_wgt.layout = Layout(margin='0 1em')

        super().__init__([
            self.imsel_wgt,
            VBox([
                self.img_title, self.imbox_wgt, self.play_wgt, self.detail_pane
            ]), self.exp_wgt
        ])
        self.idx_changed({'new': 0})

    def box_changed(self, change):
        if change['new'] is None:
            self.detail_wgt.data = {}
            self.crop_wgt.box = None
        else:
            new_idx = change['new']['index']
            self.detail_wgt.data = dict(self.df.loc[new_idx])
            self.crop_wgt.box = change['new']['box']

    def img_changed(self, change):
        new_img = change['new']
        self.detail_wgt.data = {}
        self.crop_wgt.img = new_img
        self.img_title.value = f'Image path: <a href="{new_img}">{new_img}</a>'
        self.imexp_dest.value = f'output/{Path(new_img).stem}.png'
        self.imexp_btn.button_style = ''
        self.imexp_btn.description = 'Export'
        self.imexp_btn.disabled = False

    def drop_changed(self, change):
        idx = self.df_img[self.df_img[self.img_col] == change['new']].index[0]
        self.idx = idx
        self.imbox_wgt.img = self.df_img.loc[idx, self.img_col]
        self.imbox_wgt.boxes = self.df_img.loc[idx, 'box_dict']
        self.idx_wgt.value = idx

    def idx_changed(self, change):
        self.idx = change['new']
        self.imbox_wgt.img = self.df_img.loc[self.idx, self.img_col]
        self.imbox_wgt.boxes = self.df_img.loc[self.idx, 'box_dict']
        self.drop_wgt.value = self.imbox_wgt.img

    def vididx_changed(self, change):
        start = self.videxp_start.value
        end = self.videxp_end.value
        self.videxp_dest.value = f'output/{start}_{end}.mp4'
        self.videxp_btn.button_style = ''
        self.videxp_btn.description = 'Export'
        self.videxp_btn.disabled = False

    def get_pilim_from_idx(self, idx):
        """Return the processed PIL image that belongs to an image index.
        """
        im = Image.open(self.df_img.loc[idx, self.img_col])
        draw = ImageDraw.Draw(im, mode='RGBA')

        box_dicts = self.df_img.loc[idx, 'box_dict']
        for bd in box_dicts:
            box = bd['box']
            draw.rectangle([(box.x_min, box.y_min), (box.x_max, box.y_max)],
                           fill=bd['style']['fill_color'],
                           outline=bd['style']['stroke_color'],
                           width=bd['style']['stroke_width'])

            fontfile = str(Path(__file__).parent / 'etc/Arial.ttf')

            # size*4 to make it look more similar to example in widget
            fontsize = bd['style']['font_size'] * 4
            font = ImageFont.truetype(fontfile, size=fontsize)
            w, h = draw.textsize(bd['text'], font=font)
            draw.text((box.x_min, box.y_min - h),
                      text=bd['text'],
                      fill=bd['style']['stroke_color'],
                      font=font)
        return im

    def export_img(self, button):
        self.imexp_btn.disabled = True
        self.imexp_btn.description = 'Exporting...'
        im = self.get_pilim_from_idx(self.idx)
        try:
            im.save(self.imexp_dest.value)
            self.imexp_btn.button_style = 'success'
            self.imexp_btn.description = 'Export Successful'
        except (IOError, KeyError) as e:
            self.imexp_btn.button_style = 'danger'
            self.imexp_btn.description = 'Export Failed'
            logging.exception('Export Failed')

    def export_vid(self, button):
        self.videxp_btn.disabled = True
        self.videxp_btn.description = 'Exporting...'
        fps = str(self.videxp_fps.value)
        writer = FFmpegWriter(self.videxp_dest.value,
                              inputdict={'-framerate': fps})

        for idx in tqdm(range(self.videxp_start.value, self.videxp_end.value)):
            im = self.get_pilim_from_idx(idx)
            writer.writeFrame(np.array(im))

        try:
            writer.close()
            self.videxp_btn.button_style = 'success'
            self.videxp_btn.description = 'Export successful'
        except OSError as e:
            self.videxp_btn.button_style = 'danger'
            self.videxp_btn.description = 'Export failed'
            logging.exception('Export Failed')
Ejemplo n.º 22
0
class AnnotatorInterface(metaclass=abc.ABCMeta):

    def __init__(self,
                 dataset,
                 properties_and_values,  # properties { name: (MetaPropType, [possible values], optional label)}
                 output_path=None,
                 show_name=False,
                 show_axis=False,
                 fig_size=(10, 10),
                 buttons_vertical=False,
                 ds_name=None,
                 custom_display_function=None,
                 classes_to_annotate=None,
                 validate_function=None,
                 show_reset=True
                 ):

        for k, v in properties_and_values.items():
            if v[0] not in [MetaPropertiesType.UNIQUE, MetaPropertiesType.TEXT]:
                raise NotImplementedError(f"Cannot use {v[0]}!")

        self.dataset_orig = dataset
        self.properties_and_values = properties_and_values
        self.show_axis = show_axis
        self.show_reset = show_reset
        self.show_name = show_name

        if classes_to_annotate is None:  # if classes_to_annotate is None, all the classes would be annotated
            self.classes_to_annotate = self.dataset_orig.get_categories_names()  # otherwise, the only the classes in the list

        if ds_name is None:
            self.name = (self.dataset_orig.dataset_root_param.split('/')[-1]).split('.')[0]  # get_original_file_name
        else:
            self.name = ds_name

        self.set_output(output_path)

        print("{} {}".format(labels_str.info_new_ds, self.file_path_for_json))

        self.current_pos = 0
        self.mapping, self.dataset_annotated = self.create_results_dict(self.file_path_for_json)
        self.set_objects()

        self.fig_size = fig_size
        self.buttons_vertical = buttons_vertical

        self.current_image = {}

        label_total = self.create_label_total()

        # create buttons
        buttons = self.create_buttons()

        self.updated = False

        self.validation_show = HTML(value="")
        self.out = Output()
        self.out.add_class("my_canvas_class")

        self.checkboxes = {}
        self.radiobuttons = {}
        self.bounded_text = {}
        self.box_text = {}

        labels = self.create_check_radio_boxes()

        self.validate = not validate_function is None
        if self.validate:
            self.validate_function = validate_function

        self.set_display_function(custom_display_function)

        output_layout = self.set_check_radio_boxes_layout(labels)

        self.all_widgets = VBox(children=
                                [HBox([self.text_index, label_total]),
                                 HBox(buttons),
                                 self.validation_show,
                                 HBox([self.out,
                                       VBox(output_layout)])])

        self.load_js()

    @abc.abstractmethod
    def set_objects(self):
        pass

    @abc.abstractmethod
    def set_display_function(self, custom_display_function):
        pass

    def set_output(self, output_path):
        if output_path is None:
            name = self.dataset_orig.dataset_root_param
            self.output_directory = name.replace(os.path.basename(name), "")
        else:
            self.output_directory = output_path

        self.file_path_for_json = os.path.join(self.output_directory, self.name + "_ANNOTATED.json")

    def create_label_total(self):
        label_total = Label(value='/ {}'.format(len(self.objects)))
        self.text_index = BoundedIntText(value=1, min=1, max=len(self.objects))
        self.text_index.layout.width = '80px'
        self.text_index.layout.height = '35px'
        self.text_index.observe(self.selected_index)
        return label_total

    def create_buttons(self):
        # create buttons
        self.previous_button = self.create_button(labels_str.str_btn_prev, (self.current_pos == 0),
                                                  self.on_previous_clicked)
        self.next_button = self.create_button(labels_str.str_btn_next, (self.current_pos == self.max_pos),
                                              self.on_next_clicked)
        self.save_button = self.create_button(labels_str.str_btn_download, False, self.on_save_clicked)
        self.save_function = self.save_function  # save_function

        if self.show_reset:
            self.reset_button = self.create_button(labels_str.str_btn_reset, False, self.on_reset_clicked)
            buttons = [self.previous_button, self.next_button, self.reset_button, self.save_button]
        else:
            buttons = [self.previous_button, self.next_button, self.save_button]
        return buttons

    def create_check_radio_boxes(self):
        labels = dict()
        for k_name, v in self.properties_and_values.items():

            if len(v) == 3:
                label = v[2]
            elif MetaPropertiesType.TEXT.value == v[0].value and len(v) == 2:
                label = v[1]
            else:
                label = k_name

            labels[k_name] = label

            if MetaPropertiesType.UNIQUE.value == v[0].value:  # radiobutton
                self.radiobuttons[k_name] = RadioButtons(name=k_name, options=v[1],
                                                         disabled=False,
                                                         indent=False)
            elif MetaPropertiesType.COMPOUND.value == v[0].value:  # checkbox
                self.checkboxes[k_name] = [Checkbox(False, indent=False, name=k_name,
                                                    description=prop_name) for prop_name in v[1]]
            elif MetaPropertiesType.CONTINUE.value == v[0].value:
                self.bounded_text[k_name] = BoundedFloatText(value=v[1][0], min=v[1][0], max=v[1][1])

            elif MetaPropertiesType.TEXT.value == v[0].value:
                self.box_text[k_name] = Textarea(disabled=False)

        return labels

    def set_check_radio_boxes_layout(self, labels):
        output_layout = []
        self.check_radio_boxes_layout = {}
        for rb_k, rb_v in self.radiobuttons.items():
            rb_v.layout.width = '180px'
            rb_v.observe(self.checkbox_changed)
            rb_v.add_class(rb_k)
            html_title = HTML(value="<b>" + labels[rb_k] + "</b>")
            self.check_radio_boxes_layout[rb_k] = VBox([rb_v])
            output_layout.append(VBox([html_title, self.check_radio_boxes_layout[rb_k]]))

        for cb_k, cb_i in self.checkboxes.items():
            for cb in cb_i:
                cb.layout.width = '180px'
                cb.observe(self.checkbox_changed)
                cb.add_class(cb_k)
            html_title = HTML(value="<b>" + labels[cb_k] + "</b>")
            self.check_radio_boxes_layout[cb_k] = VBox(children=[cb for cb in cb_i])
            output_layout.append(VBox([html_title, self.check_radio_boxes_layout[cb_k]]))

        for bf_k, bf in self.bounded_text.items():
            bf.layout.width = '80px'
            bf.layout.height = '35px'
            bf.observe(self.checkbox_changed)
            bf.add_class(bf_k)
            html_title = HTML(value="<b>" + labels[bf_k] + "</b>")
            self.check_radio_boxes_layout[bf_k] = VBox([bf])
            output_layout.append(VBox([html_title, self.check_radio_boxes_layout[bf_k]]))

        for tb_k, tb_i in self.box_text.items():
            tb_i.layout.width = '500px'
            tb_i.observe(self.checkbox_changed)
            tb_i.add_class(tb_k)
            html_title = HTML(value="<b>" + labels[tb_k] + "</b>")
            self.check_radio_boxes_layout[tb_k] = VBox([tb_i])
            output_layout.append(VBox([html_title, self.check_radio_boxes_layout[tb_k]]))

        return output_layout

    def load_js(self):
        ## loading js library to perform html screenshots
        j_code = """
                        require.config({
                            paths: {
                                html2canvas: "https://html2canvas.hertzen.com/dist/html2canvas.min"
                            }
                        });
                    """
        display(Javascript(j_code))

    def change_check_radio_boxes_value(self, current_ann):
        for m_k, m_v in self.properties_and_values.items():
            if m_v[0].value == MetaPropertiesType.UNIQUE.value:  # radiobutton
                self.radiobuttons[m_k].unobserve(self.checkbox_changed)
                self.radiobuttons[m_k].value = current_ann[m_k] if m_k in current_ann.keys() else None
                self.radiobuttons[m_k].observe(self.checkbox_changed)
            elif m_v[0].value == MetaPropertiesType.COMPOUND.value:  # checkbox
                for cb_i, cb_v in enumerate(self.checkboxes[m_k]):
                    cb_v.unobserve(self.checkbox_changed)
                    if m_k in current_ann.keys():
                        if cb_v.description in current_ann[m_k].keys():
                            cb_v.value = current_ann[m_k][cb_v.description]
                        else:
                            cb_v.value = False
                    else:
                        cb_v.value = False
                    cb_v.observe(self.checkbox_changed)
            elif m_v[0].value == MetaPropertiesType.CONTINUE.value:  # textbound
                self.bounded_text[m_k].unobserve(self.checkbox_changed)
                self.bounded_text[m_k].value = float(current_ann[m_k]) if m_k in current_ann.keys() else \
                    self.bounded_text[m_k].min
                self.bounded_text[m_k].observe(self.checkbox_changed)
            elif m_v[0].value == MetaPropertiesType.TEXT.value:  # text
                self.box_text[m_k].unobserve(self.checkbox_changed)
                self.box_text[m_k].value = current_ann[m_k] if m_k in current_ann.keys() else ""
                self.box_text[m_k].observe(self.checkbox_changed)

    def create_results_dict(self, file_path):
        mapping = {}
        mapping["annotated_ids"] = set()  # key: object_id from dataset, values=[(annotations done)]
        mapping["categories_counter"] = dict.fromkeys([c for c in self.dataset_orig.get_categories_names()], 0)
        self.mapping = mapping

        if not os.path.exists(file_path):  # it does exist __ANNOTATED in the output directory
            with open(self.dataset_orig.dataset_root_param, 'r') as input_json_file:
                dataset_annotated = json.load(input_json_file)
                input_json_file.close()

            # take the same metaproperties already in file if it's not empty (like a new file)
            meta_prop = dataset_annotated['meta_properties'] if 'meta_properties' in dataset_annotated.keys() else []

            # adds the new annotations categories to dataset if it doesn't exist
            for k_name, v in self.properties_and_values.items():

                new_mp_to_append = {
                    "name": k_name,
                    "type": v[0].value,
                }

                if len(v) > 1:
                    new_mp_to_append["values"] = sorted([p for p in v[1]])

                names_prop_in_file = {m_p['name']: m_p for m_i, m_p in enumerate(dataset_annotated[
                                                                                     'meta_properties'])} if 'meta_properties' in dataset_annotated.keys() else None

                if 'meta_properties' not in dataset_annotated.keys():  # it is a new file
                    meta_prop.append(new_mp_to_append)
                    dataset_annotated['meta_properties'] = []

                elif names_prop_in_file is not None and k_name not in names_prop_in_file.keys():
                    # if there is a property with the same in meta_properties, it must be the same structure as the one proposed
                    meta_prop.append(new_mp_to_append)
                    self.update_annotation_counter_and_current_pos(dataset_annotated)

                elif names_prop_in_file is not None and k_name in names_prop_in_file.keys() and \
                        names_prop_in_file[k_name] == new_mp_to_append:
                    # we don't append because it's already there
                    self.update_annotation_counter_and_current_pos(dataset_annotated)

                else:
                    raise NameError("An annotation with the same name {} "
                                    "already exist in dataset {}, and it has different structure. Check properties.".format(
                        k_name, self.dataset_orig.dataset_root_param))

                # if k_name is in name_props_in_file and it's the same structure. No update is done.
            dataset_annotated['meta_properties'] = dataset_annotated['meta_properties'] + meta_prop
        else:
            with open(file_path, 'r') as classification_file:
                dataset_annotated = json.load(classification_file)
                classification_file.close()

            self.update_annotation_counter_and_current_pos(dataset_annotated)
        return mapping, dataset_annotated

    @abc.abstractmethod
    def add_annotation_to_mapping(self, ann):
        pass

    @abc.abstractmethod
    def update_mapping_from_whole_dataset(self):
        pass

    @abc.abstractmethod
    def update_annotation_counter_and_current_pos(self, dataset_annotated):
        pass

    def execute_validation(self, ann):
        if self.validate:
            if self.validate_function(ann):
                self.validation_show.value = labels_str.srt_validation_not_ok
            else:
                self.validation_show.value = labels_str.srt_validation_ok

    @abc.abstractmethod
    def show_name_func(self, image_record, path_img):
        pass

    @abc.abstractmethod
    def checkbox_changed(self, b):
        pass

    def create_button(self, description, disabled, function):
        button = Button(description=description)
        button.disabled = disabled
        button.on_click(function)
        return button

    @abc.abstractmethod
    def show_image(self, image_record, ann_key):
        pass

    @abc.abstractmethod
    def save_state(self):
        pass

    def save_function(self, image_path):
        img_name = os.path.basename(image_path).split('.')[0]
        j_code = """
            require(["html2canvas"], function(html2canvas) {
                var element = $(".p-Widget.jupyter-widgets-output-area.output_wrapper.$it_name$")[0];
                console.log(element);
                 html2canvas(element).then(function (canvas) { 
                    var myImage = canvas.toDataURL(); 
                    var a = document.createElement("a"); 
                    a.href = myImage; 
                    a.download = "$img_name$.png"; 
                    a.click(); 
                    a.remove(); 
                });
            });
            """
        j_code = j_code.replace('$it_name$', "my_canvas_class")
        j_code = j_code.replace('$img_name$', img_name)
        tmp_out = Output()
        with tmp_out:
            display(Javascript(j_code))
            tmp_out.clear_output()

    @abc.abstractmethod
    def perform_action(self):
        pass

    @abc.abstractmethod
    def get_image_record(self):
        pass

    @abc.abstractmethod
    def on_reset_clicked(self, b):
        pass

    def on_previous_clicked(self, b):
        self.save_state()
        self.current_pos -= 1
        self.perform_action()

    def on_next_clicked(self, b):
        self.save_state()
        self.current_pos += 1
        self.perform_action()

    @abc.abstractmethod
    def on_save_clicked(self, b):
        pass

    def selected_index(self, t):
        if t['owner'].value is None or t['name'] != 'value':
            return
        self.current_pos = t['new'] - 1
        self.perform_action()

    def start_annotation(self):
        if self.max_pos < self.current_pos:
            print(labels_str.info_no_more_images)
            return
        display(self.all_widgets)
        self.perform_action()

    @abc.abstractmethod
    def print_statistics(self):
        pass

    @abc.abstractmethod
    def print_results(self):
        pass
Ejemplo n.º 23
0
    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

        self.use_defaults = True

        self.svg_xmin = 0
        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 = 0
        self.show_edge = False

        # 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 = '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.mcds_plot = interactive(self.plot_plots,
                                     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.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='YlOrRd',
            #     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)

        #---------------------
        self.cell_edges_toggle = Checkbox(
            description='edges',
            disabled=False,
            value=False,
            #           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.mcds_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.mcds_plot.update()
            if (self.cells_toggle.value):
                self.cell_edges_toggle.disabled = False
            else:
                self.cell_edges_toggle.disabled = True

        self.cells_toggle.observe(cells_toggle_cb)

        #---------------------
        self.substrates_toggle = Checkbox(
            description='Substrates',
            disabled=False,
            value=True,
            #           layout=Layout(width=constWidth2),
        )

        def substrates_toggle_cb(b):
            if (self.substrates_toggle.value):  # seems bass-ackwards
                self.cmap_fixed.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.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.mcds_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)
        #        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',
        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_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, 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).")
            ])

            #        self.tab = VBox([row1, row2, self.mcds_plot])
            # self.tab = VBox([row1, row2, self.mcds_plot, download_row])
            # box_layout = Layout(border='0px solid')
            controls_box = VBox([row1,
                                 row2])  # ,width='50%', layout=box_layout)
            self.tab = VBox([controls_box, self.mcds_plot, download_row])
        else:
            # self.tab = VBox([row1, row2])
            self.tab = VBox([row1, row2, self.mcds_plot])
Ejemplo n.º 24
0
class Iterator:
    def __init__(self,
                 images,
                 name="iterator",
                 show_name=True,
                 show_axis=False,
                 show_random=True,
                 fig_size=(10, 10),
                 buttons_vertical=False,
                 image_display_function=None):
        if len(images) == 0:
            raise Exception("No images provided")

        self.show_axis = show_axis
        self.name = name
        self.show_name = show_name
        self.show_random = show_random
        self.images = images
        self.max_pos = len(self.images) - 1
        self.pos = 0
        self.fig_size = fig_size
        self.buttons_vertical = buttons_vertical

        if image_display_function is None:
            self.image_display_function = self.__show_image
        else:
            self.image_display_function = image_display_function

        self.previous_button = self.__create_button("Previous",
                                                    (self.pos == 0),
                                                    self.__on_previous_clicked)
        self.next_button = self.__create_button("Next",
                                                (self.pos == self.max_pos),
                                                self.__on_next_clicked)
        self.save_button = self.__create_button("Save", False,
                                                self.__on_save_clicked)
        self.save_function = self.__save_function  # save_function

        buttons = [self.previous_button, self.next_button]

        if self.show_random:
            self.random_button = self.__create_button("Random", False,
                                                      self.__on_random_clicked)
            buttons.append(self.random_button)

        buttons.append(self.save_button)

        label_total = Label(value='/ {}'.format(len(self.images)))
        self.text_index = BoundedIntText(value=1, min=1, max=len(self.images))
        self.text_index.layout.width = '80px'
        self.text_index.layout.height = '35px'
        self.text_index.observe(self.__selected_index)
        self.out = Output()
        self.out.add_class(name)

        if self.buttons_vertical:
            self.all_widgets = HBox(children=[
                VBox(children=[HBox([self.text_index, label_total])] +
                     buttons), self.out
            ])
        else:
            self.all_widgets = VBox(children=[
                HBox([self.text_index, label_total]),
                HBox(children=buttons), self.out
            ])
        ## loading js library to perform html screenshots
        j_code = """
                require.config({
                    paths: {
                        html2canvas: "https://html2canvas.hertzen.com/dist/html2canvas.min"
                    }
                });
            """
        display(Javascript(j_code))

    def __create_button(self, description, disabled, function):
        button = Button(description=description)
        button.disabled = disabled
        button.on_click(function)
        return button

    def __show_image(self, image_path, index):
        img = Image.open(image_path)
        if self.show_name:
            print(os.path.basename(image_path))
        plt.figure(figsize=self.fig_size)
        if not self.show_axis:
            plt.axis('off')
        plt.imshow(img)
        plt.show()

    def __save_function(self, image_path, index):
        img_name = os.path.basename(image_path).split('.')[0]
        j_code = """
            require(["html2canvas"], function(html2canvas) {
                var element = $(".p-Widget.jupyter-widgets-output-area.output_wrapper.$it_name$")[0];
                console.log(element);
                 html2canvas(element).then(function (canvas) { 
                    var myImage = canvas.toDataURL(); 
                    var a = document.createElement("a"); 
                    a.href = myImage; 
                    a.download = "$img_name$.png"; 
                    a.click(); 
                    a.remove(); 
                });
            });
            """
        j_code = j_code.replace('$it_name$', self.name)
        j_code = j_code.replace('$img_name$', img_name)
        tmp_out = Output()
        with tmp_out:
            display(Javascript(j_code))
            tmp_out.clear_output()

    def __on_next_clicked(self, b):
        self.pos += 1
        self.__perform_action(self.pos, self.max_pos)

    def __on_save_clicked(self, b):
        self.save_function(self.images[self.pos], self.pos)

    def __perform_action(self, index, max_pos):
        self.next_button.disabled = (index == max_pos)
        self.previous_button.disabled = (index == 0)

        with self.out:
            self.out.clear_output()
        with self.out:
            self.image_display_function(self.images[index], index)

        self.text_index.unobserve(self.__selected_index)
        self.text_index.value = index + 1
        self.text_index.observe(self.__selected_index)

    def __on_previous_clicked(self, b):
        self.pos -= 1
        self.__perform_action(self.pos, self.max_pos)

    def __on_random_clicked(self, b):
        self.pos = random.randint(0, self.max_pos)
        self.__perform_action(self.pos, self.max_pos)

    def __selected_index(self, t):
        if t['owner'].value is None or t['name'] != 'value':
            return
        self.pos = t['new'] - 1
        self.__perform_action(self.pos, self.max_pos)

    def start_iteration(self):
        if self.max_pos < self.pos:
            print("No available images")
            return

        display(self.all_widgets)
        self.__perform_action(self.pos, self.max_pos)
Ejemplo n.º 25
0
    def __init__(self):
        tab_height = '520px'
        tab_layout = Layout(
            width='800px',  # border='2px solid black',
            height=tab_height,
            overflow_y='scroll')

        self.output_dir = '.'

        max_frames = 505  # first time + 30240 / 60
        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.tab = HBox([svg_plot], layout=tab_layout)

        self.max_frames = BoundedIntText(
            min=0,
            max=99999,
            value=max_frames,
            description='Max',
            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=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)

        items_auto = [
            Label('(select slider: drag or left/right arrows)'),
            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)
        self.tab = VBox([row1, self.svg_plot], layout=tab_layout)
Ejemplo n.º 26
0
    def __init__(self,
                 images,
                 name="iterator",
                 show_name=True,
                 show_axis=False,
                 show_random=True,
                 fig_size=(10, 10),
                 buttons_vertical=False,
                 image_display_function=None):
        if len(images) == 0:
            raise Exception("No images provided")

        self.show_axis = show_axis
        self.name = name
        self.show_name = show_name
        self.show_random = show_random
        self.images = images
        self.max_pos = len(self.images) - 1
        self.pos = 0
        self.fig_size = fig_size
        self.buttons_vertical = buttons_vertical

        if image_display_function is None:
            self.image_display_function = self.__show_image
        else:
            self.image_display_function = image_display_function

        self.previous_button = self.__create_button("Previous",
                                                    (self.pos == 0),
                                                    self.__on_previous_clicked)
        self.next_button = self.__create_button("Next",
                                                (self.pos == self.max_pos),
                                                self.__on_next_clicked)
        self.save_button = self.__create_button("Save", False,
                                                self.__on_save_clicked)
        self.save_function = self.__save_function  # save_function

        buttons = [self.previous_button, self.next_button]

        if self.show_random:
            self.random_button = self.__create_button("Random", False,
                                                      self.__on_random_clicked)
            buttons.append(self.random_button)

        buttons.append(self.save_button)

        label_total = Label(value='/ {}'.format(len(self.images)))
        self.text_index = BoundedIntText(value=1, min=1, max=len(self.images))
        self.text_index.layout.width = '80px'
        self.text_index.layout.height = '35px'
        self.text_index.observe(self.__selected_index)
        self.out = Output()
        self.out.add_class(name)

        if self.buttons_vertical:
            self.all_widgets = HBox(children=[
                VBox(children=[HBox([self.text_index, label_total])] +
                     buttons), self.out
            ])
        else:
            self.all_widgets = VBox(children=[
                HBox([self.text_index, label_total]),
                HBox(children=buttons), self.out
            ])
        ## loading js library to perform html screenshots
        j_code = """
                require.config({
                    paths: {
                        html2canvas: "https://html2canvas.hertzen.com/dist/html2canvas.min"
                    }
                });
            """
        display(Javascript(j_code))
Ejemplo n.º 27
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
        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),
        )
        #            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=True,
            layout=Layout(width=constWidth),
        )
        self.zdelta = BoundedFloatText(
            min=1.,
            description='dz',
            disabled=disable_domain,
            layout=Layout(width=constWidth),
        )

        def xdelta_cb(b):
            self.ydelta.value = self.xdelta.value
            self.zdelta.value = 0.5 * (self.xdelta.value + self.ydelta.value)
            self.zmin.value = -0.5 * self.zdelta.value
            self.zmax.value = 0.5 * self.zdelta.value

        self.xdelta.observe(xdelta_cb)
        """
        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 = BoundedIntText(
            min=1,
            max=
            99999999,  # TODO: set max on all Bounded to avoid unwanted default
            description='every',
            layout=Layout(width='160px'),
        )
        self.mcds_interval = BoundedIntText(
            min=1,
            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

        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)

        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 = int(
            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 = int(xml_root.find(".//SVG//interval").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)

        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
Ejemplo n.º 28
0
    def build_options(self):
        grid = GridspecLayout(4, 2)
        options_map = {}
        style = {'description_width': '60%'}

        # plot_type
        plot_type = Dropdown(
            description='Plot:',
            options=['force', 'decision', 'both'],
            description_tooltip='Which plot to draw decision, force or both',
            style=style)
        options_map['plot_type'] = plot_type

        # background_data
        background_data = Dropdown(
            description='Background data:',
            options={
                'KMeans': 'kmeans',
                'Custom variable': 'custom'
            },
            value='kmeans',
            description_tooltip=
            'What background data will be used to sample from, when simulating "missing" feature\n'
            ' - KMeans: use KMeans to sample from provided dataset\n'
            ' - Custom variable: provide variable with instances to use',
            style=style)
        options_map['background_data'] = background_data

        # kmeans_count (only show when KMeans is chosen)
        kmeans_count = BoundedIntText(
            value=100,
            min=1,
            max=len(self.X_train),
            description='Count of KMeans centers:',
            description_tooltip=
            'Number of means to use when creating background data',
            style=style)
        options_map['kmeans_count'] = kmeans_count

        # data (only show when Custom variable is chosen)
        data = UpdatingCombobox(
            options_keys=self.globals_options,
            description='Background data variable:',
            options=list(self.globals_options),
            description_tooltip=
            'Variable with background data from which the "missing" features will be sampled',
            style=style)
        options_map['data'] = data

        # set up swap of options
        def swap_kmeans(change):
            if change['new'] == 'kmeans':
                data.lookup_in_kernel = False
                grid[1, 1] = kmeans_count
            else:
                data.lookup_in_kernel = True
                grid[1, 1] = data

        background_data.observe(swap_kmeans, names=['value'])

        # link
        link = Dropdown(
            description='Link:',
            options=['identity', 'logit'],
            value='identity',
            description_tooltip=
            'A generalized linear model link to connect the feature importance values '
            'to the model output.\n'
            'Since the feature importance values, phi, sum up to the model output, '
            'it often makes sense to connect them to the ouput with a link function '
            'where link(outout) = sum(phi).\n '
            'If the model output is a probability then the LogitLink link function makes '
            'the feature importance values have log-odds units.',
            style=style)
        options_map['link'] = link

        # nsamples
        nsamples = BoundedIntText(
            min=1,
            max=999999,
            value=2048,
            disabled=True,
            description='Model sample size:',
            description_tooltip=
            'Number of times to re-evaluate the model when explaining each prediction.\n'
            'More samples lead to lower variance estimates of the SHAP values.\n'
            'The "auto" setting uses nsamples = 2 * X.shape[1] + 2048.',
            style=style)
        options_map['nsamples'] = nsamples

        # auto_nsamples
        auto_nsamples = Checkbox(description='Auto choose model sample size',
                                 value=True,
                                 style={'description_width': 'auto'})
        options_map['auto_nsamples'] = auto_nsamples

        def disable_nsamples(change):
            nsamples.disabled = change['new']

        auto_nsamples.observe(disable_nsamples, names=['value'])

        # l1_reg
        l1_reg = Combobox(
            description='L1 regularization:',
            options=['auto', 'aic', 'bic'],
            value='auto',
            description_tooltip=
            'The l1 regularization to use for feature selection '
            '(the estimation procedure is based on a debiased lasso).\n'
            ' - The auto option currently uses "aic" when less that 20% '
            'of the possible sample space is enumerated, otherwise it uses no regularization.\n'
            ' - The "aic" and "bic" options use the AIC and BIC rules for regularization.\n'
            ' - Integer selects a fix number of top features.\n'
            ' - float directly sets the "alpha" parameter of the sklearn.linear_model.Lasso model '
            'used for feature selection',
            style=style)
        options_map['l1_reg'] = l1_reg

        # class_to_explain (only if classification)
        if self.is_classification:
            class_to_explain = Dropdown(
                description='Class to plot:',
                options={val: e
                         for e, val in enumerate(self.class_names)},
                description_tooltip=
                'For classification select a class for which the prediction will be explained',
                style=style)
            options_map['class_to_explain'] = class_to_explain
            grid[3, 1] = class_to_explain

        grid[0, 0] = plot_type
        grid[1, 0] = background_data
        grid[1, 1] = kmeans_count
        grid[0, 1] = link
        grid[2, 0] = nsamples
        grid[2, 1] = auto_nsamples
        grid[3, 0] = l1_reg

        return options_map, grid
Ejemplo n.º 29
0
class SubstrateTab(object):

    def __init__(self):
        
        self.output_dir = '.'
        # self.output_dir = 'tmpdir'

        self.figsize_width_substrate = 15.0  # allow extra for colormap
        self.figsize_height_substrate = 12.5
        self.figsize_width_svg = 12.0
        self.figsize_height_svg = 12.0

        # self.fig = plt.figure(figsize=(7.2,6))  # this strange figsize results in a ~square contour plot

        self.first_time = True
        self.modulo = 1

        self.use_defaults = True

        self.svg_delta_t = 1
        self.substrate_delta_t = 1
        self.svg_frame = 1
        self.substrate_frame = 1

        self.customized_output_freq = False
        self.therapy_activation_time = 1000000
        self.max_svg_frame_pre_therapy = 1000000
        self.max_substrate_frame_pre_therapy = 1000000

        self.svg_xmin = 0

        # Probably don't want to hardwire these if we allow changing the domain size
        # self.svg_xrange = 2000
        # self.xmin = -1000.
        # self.xmax = 1000.
        # self.ymin = -1000.
        # self.ymax = 1000.
        # self.x_range = 2000.
        # self.y_range = 2000.

        self.show_nucleus = False
        self.show_edge = True

        # initial value
        self.field_index = 4
        # self.field_index = self.mcds_field.value + 4

        self.skip_cb = False

        # define dummy size of mesh (set in the tool's primary module)
        self.numx = 0
        self.numy = 0

        self.title_str = ''

        tab_height = '600px'
        tab_height = '500px'
        constWidth = '180px'
        constWidth2 = '150px'
        tab_layout = Layout(width='900px',   # border='2px solid black',
                            height=tab_height, ) #overflow_y='scroll')

        max_frames = 1   
        # self.mcds_plot = interactive(self.plot_substrate, frame=(0, max_frames), continuous_update=False)  
        # self.i_plot = interactive(self.plot_plots, frame=(0, max_frames), continuous_update=False)  
        self.i_plot = interactive(self.plot_substrate, frame=(0, max_frames), continuous_update=False)  

        # "plot_size" controls the size of the tab height, not the plot (rf. figsize for that)
        # NOTE: the Substrates Plot tab has an extra row of widgets at the top of it (cf. Cell Plots tab)
        svg_plot_size = '700px'
        svg_plot_size = '600px'
        svg_plot_size = '700px'
        svg_plot_size = '900px'
        self.i_plot.layout.width = svg_plot_size
        self.i_plot.layout.height = svg_plot_size

        self.fontsize = 20

            # description='# cell frames',
        self.max_frames = BoundedIntText(
            min=0, max=99999, value=max_frames,
            description='# frames',
           layout=Layout(width='160px'),
        )
        self.max_frames.observe(self.update_max_frames)

        # self.field_min_max = {'dummy': [0., 1., False]}
        # NOTE: manually setting these for now (vs. parsing them out of data/initial.xml)
        self.field_min_max = {'director signal':[0.,1.,False], 'cargo signal':[0.,1.,False] }
        # hacky I know, but make a dict that's got (key,value) reversed from the dict in the Dropdown below
        # self.field_dict = {0:'dummy'}
        self.field_dict = {0:'director signal', 1:'cargo signal'}

        self.mcds_field = Dropdown(
            options={'director signal': 0, 'cargo signal':1},
            value=0,
            #     description='Field',
           layout=Layout(width=constWidth)
        )
        # print("substrate __init__: self.mcds_field.value=",self.mcds_field.value)
#        self.mcds_field.observe(self.mcds_field_cb)
        self.mcds_field.observe(self.mcds_field_changed_cb)

        self.field_cmap = Dropdown(
            options=['viridis', 'jet', 'YlOrRd'],
            value='YlOrRd',
            #     description='Field',
           layout=Layout(width=constWidth)
        )
#        self.field_cmap.observe(self.plot_substrate)
        self.field_cmap.observe(self.mcds_field_cb)

        self.cmap_fixed_toggle = Checkbox(
            description='Fix',
            disabled=False,
#           layout=Layout(width=constWidth2),
        )
        self.cmap_fixed_toggle.observe(self.mcds_field_cb)

#         def cmap_fixed_toggle_cb(b):
#             # self.update()
# #            self.field_min_max = {'oxygen': [0., 30.,True], 'glucose': [0., 1.,False]}
#             field_name = self.field_dict[self.mcds_field.value]
#             if (self.cmap_fixed_toggle.value):  
#                 self.field_min_max[field_name][0] = self.cmap_min.value
#                 self.field_min_max[field_name][1] = self.cmap_max.value
#                 self.field_min_max[field_name][2] = True
#             else:
#                 # self.field_min_max[field_name][0] = self.cmap_min.value
#                 # self.field_min_max[field_name][1] = self.cmap_max.value
#                 self.field_min_max[field_name][2] = False
#             self.i_plot.update()

        # self.cmap_fixed_toggle.observe(cmap_fixed_toggle_cb)

#         self.save_min_max= Button(
#             description='Save', #style={'description_width': 'initial'},
#             button_style='success',  # 'success', 'info', 'warning', 'danger' or ''
#             tooltip='Save min/max for this substrate',
#             disabled=True,
#            layout=Layout(width='90px')
#         )

#         def save_min_max_cb(b):
# #            field_name = self.mcds_field.options[]
# #            field_name = next(key for key, value in self.mcds_field.options.items() if value == self.mcds_field.value)
#             field_name = self.field_dict[self.mcds_field.value]
# #            print(field_name)
# #            self.field_min_max = {'oxygen': [0., 30.], 'glucose': [0., 1.], 'H+ ions': [0., 1.], 'ECM': [0., 1.], 'NP1': [0., 1.], 'NP2': [0., 1.]}
#             self.field_min_max[field_name][0] = self.cmap_min.value
#             self.field_min_max[field_name][1] = self.cmap_max.value
# #            print(self.field_min_max)

#         self.save_min_max.on_click(save_min_max_cb)


        self.cmap_min = FloatText(
            description='Min',
            value=0,
            step = 0.1,
            disabled=True,
            layout=Layout(width=constWidth2),
        )
        self.cmap_min.observe(self.mcds_field_cb)

        self.cmap_max = FloatText(
            description='Max',
            value=38,
            step = 0.1,
            disabled=True,
            layout=Layout(width=constWidth2),
        )
        self.cmap_max.observe(self.mcds_field_cb)

        def cmap_fixed_toggle_cb(b):
            field_name = self.field_dict[self.mcds_field.value]
            # print(self.cmap_fixed_toggle.value)
            if (self.cmap_fixed_toggle.value):  # toggle on fixed range
                self.cmap_min.disabled = False
                self.cmap_max.disabled = False
                self.field_min_max[field_name][0] = self.cmap_min.value
                self.field_min_max[field_name][1] = self.cmap_max.value
                self.field_min_max[field_name][2] = True
                # self.save_min_max.disabled = False
            else:  # toggle off fixed range
                self.cmap_min.disabled = True
                self.cmap_max.disabled = True
                self.field_min_max[field_name][2] = False
                # self.save_min_max.disabled = True
#            self.mcds_field_cb()
            self.i_plot.update()

        self.cmap_fixed_toggle.observe(cmap_fixed_toggle_cb)

        field_cmap_row2 = HBox([self.field_cmap, self.cmap_fixed_toggle])

#        field_cmap_row3 = HBox([self.save_min_max, self.cmap_min, self.cmap_max])
        items_auto = [
            # self.save_min_max, #layout=Layout(flex='3 1 auto', width='auto'),
            self.cmap_min, 
            self.cmap_max,  
         ]
        box_layout = Layout(display='flex',
                    flex_flow='row',
                    align_items='stretch',
                    width='80%')
        field_cmap_row3 = Box(children=items_auto, layout=box_layout)

        # self.debug_str = Text(
        #     value='debug info',
        #     description='Debug:',
        #     disabled=True,
        #     layout=Layout(width='600px'),  #constWidth = '180px'
        # )

        #---------------------
        self.cell_nucleus_toggle = Checkbox(
            description='nuclei',
            disabled=False,
            value = self.show_nucleus,
#           layout=Layout(width=constWidth2),
        )
        def cell_nucleus_toggle_cb(b):
            # self.update()
            if (self.cell_nucleus_toggle.value):  
                self.show_nucleus = True
            else:
                self.show_nucleus = False
            self.i_plot.update()

        self.cell_nucleus_toggle.observe(cell_nucleus_toggle_cb)

        #----
        self.cell_edges_toggle = Checkbox(
            description='edges',
            disabled=False,
            value=self.show_edge,
#           layout=Layout(width=constWidth2),
        )
        def cell_edges_toggle_cb(b):
            # self.update()
            if (self.cell_edges_toggle.value):  
                self.show_edge = True
            else:
                self.show_edge = False
            self.i_plot.update()

        self.cell_edges_toggle.observe(cell_edges_toggle_cb)

        self.cells_toggle = Checkbox(
            description='Cells',
            disabled=False,
            value=True,
#           layout=Layout(width=constWidth2),
        )
        def cells_toggle_cb(b):
            # self.update()
            self.i_plot.update()
            if (self.cells_toggle.value):
                self.cell_edges_toggle.disabled = False
                self.cell_nucleus_toggle.disabled = False
            else:
                self.cell_edges_toggle.disabled = True
                self.cell_nucleus_toggle.disabled = True

        self.cells_toggle.observe(cells_toggle_cb)

        #---------------------
        self.substrates_toggle = Checkbox(
            description='Substrates',
            disabled=False,
            value=True,
#           layout=Layout(width=constWidth2),
        )
        def substrates_toggle_cb(b):
            if (self.substrates_toggle.value):  # seems bass-ackwards
                self.cmap_fixed_toggle.disabled = False
                self.cmap_min.disabled = False
                self.cmap_max.disabled = False
                self.mcds_field.disabled = False
                self.field_cmap.disabled = False
            else:
                self.cmap_fixed_toggle.disabled = True
                self.cmap_min.disabled = True
                self.cmap_max.disabled = True
                self.mcds_field.disabled = True
                self.field_cmap.disabled = True

        self.substrates_toggle.observe(substrates_toggle_cb)

        self.grid_toggle = Checkbox(
            description='grid',
            disabled=False,
            value=True,
#           layout=Layout(width=constWidth2),
        )
        def grid_toggle_cb(b):
            # self.update()
            self.i_plot.update()

        self.grid_toggle.observe(grid_toggle_cb)

#        field_cmap_row3 = Box([self.save_min_max, self.cmap_min, self.cmap_max])

        # mcds_tab = widgets.VBox([mcds_dir, mcds_plot, mcds_play], layout=tab_layout)
        # mcds_params = VBox([self.mcds_field, field_cmap_row2, field_cmap_row3, self.max_frames])  # mcds_dir
#        mcds_params = VBox([self.mcds_field, field_cmap_row2, field_cmap_row3,])  # mcds_dir

#        self.tab = HBox([mcds_params, self.mcds_plot], layout=tab_layout)

        help_label = Label('select slider: drag or left/right arrows')
        # row1 = Box([help_label, Box( [self.max_frames, self.mcds_field, self.field_cmap], layout=Layout(border='0px solid black',
        row1a = Box( [self.max_frames, self.mcds_field, self.field_cmap], layout=Layout(border='1px solid black',
                            width='50%',
                            height='',
                            align_items='stretch',
                            flex_direction='row',
                            display='flex')) 
        row1b = Box( [self.cells_toggle, self.cell_nucleus_toggle, self.cell_edges_toggle], layout=Layout(border='1px solid black',
                            width='50%',
                            height='',
                            align_items='stretch',
                            flex_direction='row',
                            display='flex')) 
        row1 = HBox( [row1a, Label('.....'), row1b])

        row2a = Box([self.cmap_fixed_toggle, self.cmap_min, self.cmap_max], layout=Layout(border='1px solid black',
                            width='50%',
                            height='',
                            align_items='stretch',
                            flex_direction='row',
                            display='flex'))
        # row2b = Box( [self.substrates_toggle, self.grid_toggle], layout=Layout(border='1px solid black',
        row2b = Box( [self.substrates_toggle, ], layout=Layout(border='1px solid black',
                            width='50%',
                            height='',
                            align_items='stretch',
                            flex_direction='row',
                            display='flex')) 
        # row2 = HBox( [row2a, self.substrates_toggle, self.grid_toggle])
        row2 = HBox( [row2a, Label('.....'), row2b])

        if (hublib_flag):
            self.download_button = Download('mcds.zip', style='warning', icon='cloud-download', 
                                                tooltip='Download data', cb=self.download_cb)

            self.download_svg_button = Download('svg.zip', style='warning', icon='cloud-download', 
                                            tooltip='You need to allow pop-ups in your browser', cb=self.download_svg_cb)
            download_row = HBox([self.download_button.w, self.download_svg_button.w, Label("Download all cell plots (browser must allow pop-ups).")])

            # box_layout = Layout(border='0px solid')
            controls_box = VBox([row1, row2])  # ,width='50%', layout=box_layout)
            self.tab = VBox([controls_box, self.i_plot, download_row])
            # self.tab = VBox([controls_box, self.debug_str, self.i_plot, download_row])
        else:
            # self.tab = VBox([row1, row2])
            self.tab = VBox([row1, row2, self.i_plot])

    #---------------------------------------------------
    def update_dropdown_fields(self, data_dir):
        # print('update_dropdown_fields called --------')
        self.output_dir = data_dir
        tree = None
        try:
            fname = os.path.join(self.output_dir, "initial.xml")
            tree = ET.parse(fname)
            xml_root = tree.getroot()
        except:
            print("Cannot open ",fname," to read info, e.g., names of substrate fields.")
            return

        xml_root = tree.getroot()
        self.field_min_max = {}
        self.field_dict = {}
        dropdown_options = {}
        uep = xml_root.find('.//variables')
        comment_str = ""
        field_idx = 0
        if (uep):
            for elm in uep.findall('variable'):
                # print("-----> ",elm.attrib['name'])
                field_name = elm.attrib['name']
                self.field_min_max[field_name] = [0., 1., False]
                self.field_dict[field_idx] = field_name
                dropdown_options[field_name] = field_idx

                self.field_min_max[field_name][0] = 0   
                self.field_min_max[field_name][1] = 1

                # self.field_min_max[field_name][0] = field_idx   #rwh: helps debug
                # self.field_min_max[field_name][1] = field_idx+1   
                self.field_min_max[field_name][2] = False
                field_idx += 1

#        constWidth = '180px'
        # print('options=',dropdown_options)
        # print(self.field_min_max)  # debug
        self.mcds_field.value = 0
        self.mcds_field.options = dropdown_options
#         self.mcds_field = Dropdown(
# #            options={'oxygen': 0, 'glucose': 1},
#             options=dropdown_options,
#             value=0,
#             #     description='Field',
#            layout=Layout(width=constWidth)
#         )

    # def update_max_frames_expected(self, value):  # called when beginning an interactive Run
    #     self.max_frames.value = value  # assumes naming scheme: "snapshot%08d.svg"
    #     self.mcds_plot.children[0].max = self.max_frames.value

#------------------------------------------------------------------------------
    def update_params(self, config_tab, user_params_tab):
        # xml_root.find(".//x_min").text = str(self.xmin.value)
        # xml_root.find(".//x_max").text = str(self.xmax.value)
        # xml_root.find(".//dx").text = str(self.xdelta.value)
        # xml_root.find(".//y_min").text = str(self.ymin.value)
        # xml_root.find(".//y_max").text = str(self.ymax.value)
        # xml_root.find(".//dy").text = str(self.ydelta.value)
        # xml_root.find(".//z_min").text = str(self.zmin.value)
        # xml_root.find(".//z_max").text = str(self.zmax.value)
        # xml_root.find(".//dz").text = str(self.zdelta.value)

        self.xmin = config_tab.xmin.value 
        self.xmax = config_tab.xmax.value 
        self.x_range = self.xmax - self.xmin
        self.svg_xrange = self.xmax - self.xmin
        self.ymin = config_tab.ymin.value
        self.ymax = config_tab.ymax.value 
        self.y_range = self.ymax - self.ymin

        self.numx =  math.ceil( (self.xmax - self.xmin) / config_tab.xdelta.value)
        self.numy =  math.ceil( (self.ymax - self.ymin) / config_tab.ydelta.value)

        if (self.x_range > self.y_range):  
            ratio = self.y_range / self.x_range
            self.figsize_width_substrate = 15.0  # allow extra for colormap
            self.figsize_height_substrate = 12.5 * ratio
            self.figsize_width_svg = 12.0
            self.figsize_height_svg = 12.0 * ratio
        else:   # x < y
            ratio = self.x_range / self.y_range
            self.figsize_width_substrate = 15.0 * ratio 
            self.figsize_height_substrate = 12.5
            self.figsize_width_svg = 12.0 * ratio
            self.figsize_height_svg = 12.0 

        self.svg_flag = config_tab.toggle_svg.value
        self.substrates_flag = config_tab.toggle_mcds.value
        # print("substrates: update_params(): svg_flag, toggle=",self.svg_flag,config_tab.toggle_svg.value)        
        # print("substrates: update_params(): self.substrates_flag = ",self.substrates_flag)
        self.svg_delta_t = config_tab.svg_interval.value
        self.substrate_delta_t = config_tab.mcds_interval.value
        self.modulo = int(self.substrate_delta_t / self.svg_delta_t)
        # print("substrates: update_params(): modulo=",self.modulo)        

        if self.customized_output_freq:
#            self.therapy_activation_time = user_params_tab.therapy_activation_time.value   # NOTE: edit for user param name
            # print("substrates: update_params(): therapy_activation_time=",self.therapy_activation_time)
            self.max_svg_frame_pre_therapy = int(self.therapy_activation_time/self.svg_delta_t)
            self.max_substrate_frame_pre_therapy = int(self.therapy_activation_time/self.substrate_delta_t)

#------------------------------------------------------------------------------
#    def update(self, rdir):
#   Called from driver module (e.g., pc4*.py) (among other places?)
    def update(self, rdir=''):
        # with debug_view:
        #     print("substrates: update rdir=", rdir)        
        # print("substrates: update rdir=", rdir)        

        if rdir:
            self.output_dir = rdir

        # print('update(): self.output_dir = ', self.output_dir)

        if self.first_time:
        # if True:
            self.first_time = False
            full_xml_filename = Path(os.path.join(self.output_dir, 'config.xml'))
            # print("substrates: update(), config.xml = ",full_xml_filename)        
            # self.num_svgs = len(glob.glob(os.path.join(self.output_dir, 'snap*.svg')))
            # self.num_substrates = len(glob.glob(os.path.join(self.output_dir, 'output*.xml')))
            # print("substrates: num_svgs,num_substrates =",self.num_svgs,self.num_substrates)        
            # argh - no! If no files created, then denom = -1
            # self.modulo = int((self.num_svgs - 1) / (self.num_substrates - 1))
            # print("substrates: update(): modulo=",self.modulo)        
            if full_xml_filename.is_file():
                tree = ET.parse(full_xml_filename)  # this file cannot be overwritten; part of tool distro
                xml_root = tree.getroot()
                self.svg_delta_t = int(xml_root.find(".//SVG//interval").text)
                self.substrate_delta_t = int(xml_root.find(".//full_data//interval").text)
                # print("substrates: svg,substrate delta_t values=",self.svg_delta_t,self.substrate_delta_t)        
                self.modulo = int(self.substrate_delta_t / self.svg_delta_t)
                # print("substrates: update(): modulo=",self.modulo)        


        # all_files = sorted(glob.glob(os.path.join(self.output_dir, 'output*.xml')))  # if the substrates/MCDS

        all_files = sorted(glob.glob(os.path.join(self.output_dir, 'snap*.svg')))   # if .svg
        if len(all_files) > 0:
            last_file = all_files[-1]
            self.max_frames.value = int(last_file[-12:-4])  # assumes naming scheme: "snapshot%08d.svg"
        else:
            substrate_files = sorted(glob.glob(os.path.join(self.output_dir, 'output*.xml')))
            if len(substrate_files) > 0:
                last_file = substrate_files[-1]
                self.max_frames.value = int(last_file[-12:-4])

    def download_svg_cb(self):
        file_str = os.path.join(self.output_dir, '*.svg')
        # print('zip up all ',file_str)
        with zipfile.ZipFile('svg.zip', 'w') as myzip:
            for f in glob.glob(file_str):
                myzip.write(f, os.path.basename(f))   # 2nd arg avoids full filename path in the archive

    def download_cb(self):
        file_xml = os.path.join(self.output_dir, '*.xml')
        file_mat = os.path.join(self.output_dir, '*.mat')
        # print('zip up all ',file_str)
        with zipfile.ZipFile('mcds.zip', 'w') as myzip:
            for f in glob.glob(file_xml):
                myzip.write(f, os.path.basename(f)) # 2nd arg avoids full filename path in the archive
            for f in glob.glob(file_mat):
                myzip.write(f, os.path.basename(f))

    def update_max_frames(self,_b):
        self.i_plot.children[0].max = self.max_frames.value

    def dummy_cb(self, b):
        return

    # called if user selected different substrate in dropdown
    def mcds_field_changed_cb(self, b):
        # print("mcds_field_changed_cb: self.mcds_field.value=",self.mcds_field.value)
        if (self.mcds_field.value == None):
            return
        self.field_index = self.mcds_field.value + 4

        field_name = self.field_dict[self.mcds_field.value]
        # print('mcds_field_changed_cb: field_name='+ field_name)
        # print(self.field_min_max[field_name])
        # self.debug_str.value = 'mcds_field_changed_cb: '+ field_name  + str(self.field_min_max[field_name])
        # self.debug_str.value = 'cb1: '+ str(self.field_min_max)

        # BEWARE of these triggering the mcds_field_cb() callback! Hence, the "skip_cb"
        self.skip_cb = True
        self.cmap_min.value = self.field_min_max[field_name][0]
        self.cmap_max.value = self.field_min_max[field_name][1]
        self.cmap_fixed_toggle.value = bool(self.field_min_max[field_name][2])
        self.skip_cb = False

        self.i_plot.update()

    # called if user provided different min/max values for colormap, or a different colormap
    def mcds_field_cb(self, b):
        if self.skip_cb:
            return

        self.field_index = self.mcds_field.value + 4

        field_name = self.field_dict[self.mcds_field.value]
        # print('mcds_field_cb: field_name='+ field_name)

        # print('mcds_field_cb: '+ field_name)
        self.field_min_max[field_name][0] = self.cmap_min.value 
        self.field_min_max[field_name][1] = self.cmap_max.value
        self.field_min_max[field_name][2] = self.cmap_fixed_toggle.value
        # print(self.field_min_max[field_name])
        # self.debug_str.value = 'mcds_field_cb: ' + field_name + str(self.field_min_max[field_name])
        # self.debug_str.value = 'cb2: '+ str(self.field_min_max)
        # print('--- cb2: '+ str(self.field_min_max))  #rwh2
        # self.cmap_fixed_toggle.value = self.field_min_max[field_name][2]

        # field_name = self.mcds_field.options[self.mcds_field.value]
        # self.cmap_min.value = self.field_min_max[field_name][0]  # oxygen, etc
        # 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)
Ejemplo n.º 30
0
    def __init__(self, nb_rows, limit=50, *args, **kwargs):
        """
        Parameters
        ----------
        nb_rows: int
            total number of rows in the result set.
        limit: int
            number of rows to display in a page.

        """
        super().__init__(*args, **kwargs)

        self.__nb_rows = nb_rows if nb_rows else 1
        self.page = 1
        self.limit = (limit if limit and limit > 0
                      and limit < PaginationWidget.MAX_LIMIT else
                      PaginationWidget.DEFAULT_LIMIT)

        self.layout.width = "400px"

        if nb_rows <= limit:
            self.layout.visibility = "hidden"
        else:
            self.layout.visibility = "visible"

            nb_pages = self._get_nb_pages(self.limit)

            # widget to set page number
            self.__page_widget = BoundedIntText(
                value=self.page,
                min=1,
                max=nb_pages,
                step=1,
                continuous_update=True,
                description="page",
                description_tooltip="Current page",
                disabled=False,
                style={"description_width": "30px"},
                layout=Layout(width="90px", max_width="90px"),
            )

            # widget to display total number of pages.
            self.__label_slash = Label(value=f"/ {nb_pages}",
                                       layout=Layout(width="60px"))

            # widget to set limit
            self.__limit_widget = BoundedIntText(
                value=self.limit,
                min=1,
                max=PaginationWidget.MAX_LIMIT,
                step=1,
                continuous_update=True,
                description="rows",
                description_tooltip=
                f"Number of rows per page. Max. possible: {PaginationWidget.MAX_LIMIT}",
                disabled=False,
                style={"description_width": "30px"},
                layout=Layout(width="90px", max_width="90px"),
            )

            self.__page_widget.observe(self._page_widget_changed,
                                       names="value")
            self.__limit_widget.observe(self._limit_widget_changed,
                                        names="value")

            self.children = [
                self.__page_widget,
                self.__label_slash,
                self.__limit_widget,
            ]