Exemple #1
0
    def __init__(self, io):

        # create the widgets
        connectivity = v.Select(label=cm.acc.connectivity,
                                items=cp.connectivity,
                                v_model=cp.connectivity[0]['value'])
        edge_width = v.Slider(label=cm.mspa.edge_width,
                              min=1,
                              max=30,
                              v_model=1)
        transition = v.Switch(label=cm.mspa.transition,
                              false_value=0,
                              true_value=1,
                              v_model=1)
        int_ext = v.Switch(label=cm.mspa.int_ext,
                           false_value=0,
                           true_value=1,
                           v_model=1)

        # bind to the io
        self.output = sw.Alert() \
            .bind(connectivity, io, 'connectivity') \
            .bind(edge_width, io, 'edge_width') \
            .bind(transition, io, 'transition') \
            .bind(int_ext, io, 'int_ext')

        super().__init__(
            io=io,
            inputs=[connectivity, edge_width, transition, int_ext],
            output=self.output)
Exemple #2
0
def download_tile(obj, w_selection):
    def bind_change(change, obj, attr):
        setattr(obj, attr, change['new'])

    w_overwrite = v.Switch(v_model=obj.overwrite,
                           inset=True,
                           label="Overwrite SEPAL images")
    w_overwrite.observe(partial(bind_change, obj=obj, attr='overwrite'),
                        'v_model')

    w_remove = v.Switch(v_model=obj.rmdrive,
                        inset=True,
                        label="Remove Google Drive Images")
    w_remove.observe(partial(bind_change, obj=obj, attr='rmdrive'), 'v_model')

    out = widgets.Output()
    btn = s.Btn(text="Download", icon='download')

    # Create an alert element for the process
    process_alert = s.Alert()

    on_download(obj, w_selection, btn, out, process_alert)

    html_header = """
    <style>
    .widget-html span {
        color:black!important;
    }
    div.output_stderr{
        color:none;
    }
    </style>
    <p>With this module you can track and download the images processed into your Google Earth Engine account 
    by providing the 'tasks' text file, the results will be stored directly into your SEPAL account.</br>
    <b>Note that if you check the overwrite and remove options, the result can't be undone.</b>
    </p>
    """

    download_content = v.Layout(
        class_="pa-5",
        row=True,
        align_center=True,
        children=[
            v.Flex(xs12=True,
                   children=[
                       v.Sheet(class_="pa-5",
                               children=[
                                   widgets.HTML(html_header),
                                   w_selection,
                                   w_overwrite,
                                   w_remove,
                                   btn,
                                   process_alert,
                                   out,
                               ])
                   ])
        ])

    return download_content
    def __init__(self, aoi_model, model, viz_tile, export_tile, **kwargs):

        # gather the model
        self.aoi_model = aoi_model
        self.model = model
        self.viz_tile = viz_tile
        self.export_tile = export_tile

        # widgets
        w_time_title = v.Html(tag="H3",
                              class_="mt-3",
                              children=[ms.selection.time_range])
        self.start_picker = sw.DatePicker(label=ms.selection.start)
        self.end_picker = sw.DatePicker(label=ms.selection.end)
        w_time_range = v.Layout(row=True,
                                children=[self.start_picker, self.end_picker])

        w_collection_title = v.Html(tag="H3",
                                    class_="mt-3",
                                    children=[ms.selection.collection])
        self.sensors = v.Select(
            label=ms.selection.sensor,
            items=pm.sensors,
            v_model=None,
            chips=True,
            multiple=True,
        )
        self.t2 = v.Switch(class_="ml-5", label=ms.selection.t2, v_model=False)
        self.sr = v.Switch(class_="ml-5", label=ms.selection.sr, v_model=False)

        self.model.bind(self.start_picker,
                        "start").bind(self.end_picker, "end").bind(
                            self.sensors,
                            "sensors").bind(self.t2, "t2").bind(self.sr, "sr")

        # construct the Tile with the widget we have initialized
        super().__init__(
            id_=
            "selection_widget",  # the id will be used to make the Tile appear and disapear
            title=ms.selection.
            title,  # the Title will be displayed on the top of the tile
            inputs=[
                w_time_title,
                w_time_range,
                w_collection_title,
                self.sensors,
                self.t2,
                self.sr,
            ],
            btn=sw.Btn(ms.selection.btn),
            alert=sw.Alert(),
        )

        # now that the Tile is created we can link it to a specific function
        self.btn.on_event("click", self._on_run)
Exemple #4
0
    def __init__(self, model):

        # create the widgets
        connectivity = v.Select(
            label=cm.acc.connectivity,
            items=cp.connectivity,
            v_model=cp.connectivity[0]["value"],
        )
        res = v.TextField(
            label=cm.acc.res, type="number", v_model=None, hint=cm.acc.res_hint
        )
        thresholds = cw.Thresholds(label=cm.acc.thresholds)
        options = v.Select(
            label=cm.acc.options,
            items=cp.acc_options,
            v_model=cp.acc_options[0]["value"],
        )
        big_3_pink = v.Switch(label=cm.acc.big3pink, v_model=True)

        # bind to the
        (
            model.bind(connectivity, "connectivity")
            .bind(res, "res")
            .bind(thresholds.save, "thresholds")
            .bind(options, "options")
            .bind(big_3_pink, "big_3_pink")
        )

        # extra js behaviour
        res.on_event("focusout", self._on_focus_out)

        super().__init__(
            model=model, inputs=[connectivity, res, thresholds, options, big_3_pink]
        )
    def __init__(self, aoi_model, model, **kwargs):

        # gather the model
        self.aoi_model = aoi_model
        self.model = model

        # widgets
        self.measure = v.Select(label=ms.selection.measure,
                                v_model=None,
                                items=pm.measures)
        self.annual = v.Switch(class_="ml-5",
                               label=ms.selection.annual,
                               v_model=False)

        # add the map
        self.m = sm.SepalMap()

        # create an output alert
        self.model.bind(self.measure, "measure").bind(self.annual, "annual")

        # construct the Tile with the widget we have initialized
        super().__init__(
            id_=
            "visualization_widget",  # the id will be used to make the Tile appear and disapear
            title=ms.visualization.
            title,  # the Title will be displayed on the top of the tile
            inputs=[self.measure, self.annual, self.m],
            alert=sw.Alert(),
        )

        self.measure.observe(self._on_change, "v_model")
        self.annual.observe(self._on_change, "v_model")
Exemple #6
0
    def __init__(self, test_case_widget, lb_scheme_widget, discret_widget,
                 **kwargs):
        self.test_case_widget = test_case_widget
        self.lb_scheme_widget = lb_scheme_widget
        self.discret_widget = discret_widget
        self.params, self.relax_params = None, None

        self.select_param = v.Select(label='Parameters',
                                     v_model=None,
                                     items=[])
        self.select_relax = v.Select(label='relaxation rates',
                                     v_model=[],
                                     items=[],
                                     multiple=True,
                                     class_='d-none')
        self.srt_relax = v.Switch(label='Single relaxation time',
                                  v_model=True,
                                  class_='d-none')
        self.sigma = v.Switch(label='Using sigma',
                              v_model=False,
                              class_='d-none')
        self.in_log = v.Switch(label='Using log10',
                               v_model=False,
                               class_='d-none')
        self.minmax = v.Layout()

        self.update_select_fields(None)

        test_case_widget.select_case.observe(self.update_select_fields,
                                             'v_model')
        lb_scheme_widget.select_case.observe(self.update_select_fields,
                                             'v_model')
        discret_widget['dx'].observe(self.update_select_fields, 'v_model')

        self.fields = [
            self.select_param, self.select_relax, self.srt_relax, self.sigma,
            self.in_log, self.minmax
        ]

        super().__init__(v_model='valid', children=self.fields)

        self.select_param.observe(self.select_param_changed, 'v_model')
        self.select_relax.observe(self.select_relax_all, 'v_model')
        self.select_relax.observe(self.check_changes, 'v_model')
        self.in_log.observe(self.check_changes, 'v_model')
        self.sigma.observe(self.check_changes, 'v_model')
Exemple #7
0
    def __init__(self, model, aoi_model, viz_tile, export_tile, **kwargs):

        # Define the model and the aoi_model as class attribute so that they can be manipulated in its custom methods
        self.model = model
        self.aoi_model = aoi_model

        # Link to the result tile
        self.viz_tile = viz_tile
        self.export_tile = export_tile

        # widgets
        self.year = v.Select(label=ms.process.slider,
                             v_model=None,
                             items=pm.years[::-1])

        self.filter = v.Select(label=ms.process.filter,
                               v_model=None,
                               items=pm.speckle_filters)

        self.ls_mask = v.Switch(class_="ml-5",
                                label=ms.process.ls_mask,
                                v_model=True)

        self.dB = v.Switch(class_="ml-5", label=ms.process.dB, v_model=True)

        # it also has the embeded `bind` method that link mutable variable to component v_model
        # bind return self so it can be chained to bind everything in one statement.
        # args are (widget, model, model_attribute_name)
        self.model.bind(self.year, "year").bind(self.filter, "filter").bind(
            self.ls_mask, "ls_mask").bind(self.dB, "dB")

        # construct the Tile with the widget we have initialized
        super().__init__(
            id_=
            "process_widget",  # the id will be used to make the Tile appear and disapear
            title=ms.process.
            title,  # the Title will be displayed on the top of the tile
            inputs=[self.year, self.filter, self.ls_mask,
                    self.dB],  # self.asset,
            btn=sw.Btn(ms.process.process),
            alert=sw.Alert(),
        )

        # now that the Tile is created we can link it to a specific function
        self.btn.on_event("click", self._on_run)
Exemple #8
0
def switch(v_model=False,
                  label=None,
                  hint=None,
                  persistent_hint=False,
                  class_=None,
                  style_=None,
                  **kwargs):
    """
    Switch input

    Function to generate an ipyvuetify Switch input widget. Essentially a checkbox. With style.

    The value of the widget can be accessed or modified by the `v_model` property of the return value.

    See the vuetify documention for other arguments that can be passed as keyword arguments: https://vuetifyjs.com/en/components/selection-controls/

    Parameters:
    v_model : bool (optional, default None)
        Value of the time input, must be an element of choices

    label : str (optional, default False)
        Default value of the checkbox input

    hint : str (optional, default None)
        Hint text

    persistent_hint : bool (optional, default False)
        Set to True to display the hint when widget is not focused

    class_ : str (optional, default None)
        ipyvuetify HTML class string

    style_ : str (optional, default None)
        ipyvuetify HTML CSS string

    **kwargs
        Other arguments supported by ipyvuetify.TextField

    Returns:
    ipyvuetify.TextInput
        An ipyvuetify time input widget
    """
    ret = ipyvuetify.Switch(
        class_=class_,
        style_=style_,
        v_model=v_model,
        label=label,
        hint=hint,
        persistent_hint=persistent_hint)

    # Set other keyword arguments
    for arg in kwargs:
        setattr(ret, arg, kwargs[arg])

    # Return widget
    return ret
Exemple #9
0
    def __init__(self, model):

        # create the widgets
        connectivity = v.Select(
            label=cm.acc.connectivity,
            items=cp.connectivity,
            v_model=cp.connectivity[0]["value"],
        )
        edge_width = v.Slider(label=cm.mspa.edge_width,
                              min=1,
                              max=30,
                              v_model=1,
                              thumb_label=True)
        transition = v.Switch(label=cm.mspa.transition,
                              false_value=0,
                              true_value=1,
                              v_model=1)
        int_ext = v.Switch(label=cm.mspa.int_ext,
                           false_value=0,
                           true_value=1,
                           v_model=1)
        disk = v.Switch(label=cm.mspa.disk,
                        false_value=0,
                        true_value=1,
                        v_model=0)
        stats = v.Switch(label=cm.mspa.stats,
                         fals_value=0,
                         true_value=1,
                         v_model=0)

        # bind to the io
        (model.bind(connectivity, "connectivity").bind(
            edge_width, "edge_width").bind(transition, "transition").bind(
                int_ext, "int_ext").bind(disk,
                                         "disk").bind(stats, "statistics"))

        super().__init__(
            model=model,
            inputs=[
                connectivity, edge_width, transition, int_ext, disk, stats
            ],
        )
Exemple #10
0
    def __init__(self, name, header, id_, **kwargs):

        widget = v.Switch(
            # readonly = True,
            persistent_hint=True,
            v_model=True,
            label=name,
            **kwargs,
        )

        super().__init__(widget, name=name, header=header, id_=id_)
Exemple #11
0
            def run_parametric_study():
                from pathos.multiprocessing import ProcessingPool
                pool = pp.ProcessPool()
                output = pool.map(run_simulation, args)

                dimensions = [
                    dict(values=np.asarray([o[0] for o in output],
                                           dtype=np.float64),
                         label='stability')
                ]

                dimensions.extend([
                    dict(values=sampling[:, ik], label=f'{k}')
                    for ik, k in enumerate(design_space.keys())
                ])

                for i, r in enumerate(self.responses.widget.v_model):
                    if output[0][i + 1] is not None:
                        dimensions.append(
                            dict(values=np.asarray([o[i + 1] for o in output],
                                                   dtype=np.float64),
                                 label=r))

                for isamp in range(len(sampling)):
                    tmp_design = {
                        f'{k}': sampling[isamp, ik]
                        for ik, k in enumerate(design_space.keys())
                    }
                    tmp_responses = {
                        r: output[isamp][ir + 1]
                        for ir, r in enumerate(self.responses.widget.v_model)
                    }
                    tmp_responses['stability'] = output[isamp][0]
                    simu_path = os.path.join(path, f'simu_{isamp}')
                    save_param_study_for_simu(simu_path, 'param_study.json',
                                              tmp_design, tmp_responses)

                fig = v.Row(children=[
                    go.FigureWidget(data=go.Parcoords(
                        line=dict(color=dimensions[0]['values']),
                        dimensions=dimensions,
                    )),
                ],
                            align='center',
                            justify='center')

                def change_plot(change):
                    if only_stable.v_model:
                        mask = dimensions[0]['values'] == 1
                    else:
                        mask = slice(dimensions[0]['values'].size)

                    new_data = []
                    for i in items.v_model:
                        d = dimensions[i]
                        new_data.append(
                            dict(values=d['values'][mask], label=d['label']))

                    fig.children = [
                        go.FigureWidget(
                            go.Parcoords(
                                line=dict(color=dimensions[color.v_model]
                                          ['values'][mask]),
                                dimensions=new_data,
                            ))
                    ]

                color = v.Select(label='color',
                                 items=[{
                                     'text': v['label'],
                                     'value': i
                                 } for i, v in enumerate(dimensions)],
                                 v_model=0)
                items = v.Select(label='Show items',
                                 items=[{
                                     'text': v['label'],
                                     'value': i
                                 } for i, v in enumerate(dimensions)],
                                 v_model=[i for i in range(len(dimensions))],
                                 multiple=True)
                only_stable = v.Switch(label='Show only stable results',
                                       v_model=False)

                color.observe(change_plot, 'v_model')
                items.observe(change_plot, 'v_model')
                only_stable.observe(change_plot, 'v_model')

                self.plotly_plot.children = [color, items, only_stable, fig]
                self.stop_simulation(None)
Exemple #12
0
    def __init__(self, aoi_model, model, **kwargs):

        # gather the model
        self.aoi_model = aoi_model
        self.model = model

        # create an output alert
        self.output = sw.Alert()

        #
        self.backscatter = v.Switch(class_="ml-5",
                                    label=ms.export.backscatter,
                                    v_model=True)

        self.rfdi = v.Switch(class_="ml-5", label=ms.export.rfdi, v_model=True)

        self.texture = v.Switch(class_="ml-5",
                                label=ms.export.texture,
                                v_model=False)

        self.aux = v.Switch(class_="ml-5", label=ms.export.aux, v_model=False)

        self.fnf = v.Switch(class_="ml-5", label=ms.export.fnf, v_model=False)

        self.scale = v.TextField(label=ms.export.scale, v_model=25)

        # create buttons
        self.asset_btn = sw.Btn(ms.export.asset_btn,
                                "mdi-download",
                                disabled=True,
                                class_="ma-5")
        self.sepal_btn = sw.Btn(ms.export.sepal_btn,
                                "mdi-download",
                                disabled=True,
                                class_="ma-5")

        # bindings
        self.model.bind(self.backscatter, "backscatter").bind(
            self.rfdi, "rfdi").bind(self.texture, "texture").bind(
                self.aux, "aux").bind(self.fnf,
                                      "fnf").bind(self.scale, "scale")

        # note that btn and output are not a madatory attributes
        super().__init__(
            id_="export_widget",
            title=ms.export.title,
            inputs=[
                self.backscatter,
                self.rfdi,
                self.texture,
                self.aux,
                self.fnf,
                self.scale,
            ],
            alert=sw.Alert(),
            btn=v.Layout(row=True, children=[self.asset_btn, self.sepal_btn]),
        )

        # decorate each function as we are using multiple btns
        self._on_asset_click = su.loading_button(self.alert,
                                                 self.asset_btn,
                                                 debug=False)(
                                                     self._on_asset_click)
        self._on_sepal_click = su.loading_button(self.alert,
                                                 self.sepal_btn,
                                                 debug=False)(
                                                     self._on_sepal_click)

        # link the btn
        self.asset_btn.on_event("click", self._on_asset_click)
        self.sepal_btn.on_event("click", self._on_sepal_click)
Exemple #13
0
    def __init__(self):

        # create the different widgets
        # I will not use Io as the information doesn't need to be communicated to any other tile
        self.folder = cw.FolderSelect()
        self.out_dir = cw.OutDirSelect()
        self.tiles = cw.TilesSelect()
        self.poly = v.Select(label=cm.widget.harmonic.label,
                             v_model=3,
                             items=[i for i in range(3, 11)])
        self.freq = v.Slider(label=cm.widget.freq.label,
                             v_model=365,
                             min=1,
                             max=365,
                             thumb_label="always",
                             class_='mt-5')
        self.trend = v.Switch(v_model=False, label=cm.widget.trend.label)
        self.hfrac = v.Select(label=cm.widget.hfrac.label,
                              v_model=.25,
                              items=[.25, .5, 1.])
        self.level = v.Slider(label=cm.widget.level.label,
                              v_model=.95,
                              step=.001,
                              min=.95,
                              max=1,
                              thumb_label="always",
                              class_='mt-5')
        self.backend = cw.BackendSelect()
        self.monitoring = cw.DateRangeSlider(label=cm.widget.monitoring.label)
        self.history = cw.DateSlider(label=cm.widget.history.label)

        # stack the advance parameters in a expandpanel
        advance_params = v.ExpansionPanels(
            class_='mb-5',
            popout=True,
            children=[
                v.ExpansionPanel(children=[
                    v.ExpansionPanelHeader(
                        children=[cm.widget.advance_params]),
                    v.ExpansionPanelContent(children=[
                        v.Flex(xs12=True, children=[self.hfrac]),
                        v.Flex(xs12=True, children=[self.level]),
                        v.Flex(xs12=True, children=[self.backend])
                    ])
                ])
            ])

        # create the tile
        super().__init__(
            "bfast_tile",
            cm.bfast.
            folder,  # the title is used to describe the first section 
            inputs=[
                self.folder, self.out_dir, self.tiles,
                v.Html(tag="h2", children=[cm.bfast.process]), self.poly,
                self.freq, self.trend, advance_params,
                v.Html(tag="h2", children=[cm.bfast.periods]), self.history,
                self.monitoring
            ],
            output=cw.CustomAlert(),
            btn=sw.Btn(cm.bfast.btn))

        # add js behaviour
        self.folder.observe(self._on_folder_change, 'v_model')
        self.btn.on_event('click', self._start_process)
        self.monitoring.observe(self._check_periods, 'v_model')
        self.history.observe(self._check_periods, 'v_model')
Exemple #14
0
    def __init__(self, test_case_widget, lb_scheme_widget, discret_widget,
                 codegen_widget):
        """
        Widget definition for parametric study of lattice Boltzmann methods.

        Parameters
        ==========

        - test_case_widget:
            widget of the test case (see test_case.py).

        - lb_scheme_widget:
            widget of the lattice Boltzmann scheme (see lb_scheme.py).

        This widget is composed by a menu where you can define the design space of the parametric study,
        the responses computed on each sample and the method used to generate the sampling as well as
        the number of points.

        This widget is also composed by a main widget where the result of the parametric study is
        represented by a parallel coordinates plot using plotly.

        """
        self.test_case_widget = test_case_widget
        self.lb_scheme_widget = lb_scheme_widget
        self.discret_widget = discret_widget
        self.codegen = codegen_widget
        self.tmp_dir = tempfile.TemporaryDirectory()
        self.results = []

        ##
        ## The menu
        ##
        self.study_name = v.TextField(label='Study name', v_model='PS_0')

        self.param_cfg = v.Select(label='Load parametric study',
                                  items=[],
                                  v_model=None)
        self.update_param_cfg_list()

        self.design = DesignWidget(test_case_widget, lb_scheme_widget,
                                   discret_widget)
        self.responses = ResponsesWidget(test_case_widget, lb_scheme_widget)

        self.sampling_method = v.Select(label='Method',
                                        items=list(skopt_method.keys()),
                                        v_model=list(skopt_method.keys())[0])
        self.sample_size = NbPointsField(label='Number of samples', v_model=10)

        self.run = v.Btn(v_model=True,
                         children=['Run parametric study'],
                         class_="ma-5",
                         color='success')

        self.menu = [
            self.study_name,
            self.param_cfg,
            v.ExpansionPanels(children=[
                v.ExpansionPanel(children=[
                    v.ExpansionPanelHeader(children=['Design space']),
                    v.ExpansionPanelContent(children=[self.design.widget]),
                ]),
                v.ExpansionPanel(children=[
                    v.ExpansionPanelHeader(children=['Responses']),
                    v.ExpansionPanelContent(children=[self.responses.widget]),
                ]),
                v.ExpansionPanel(children=[
                    v.ExpansionPanelHeader(children=['Sampling method']),
                    v.ExpansionPanelContent(
                        children=[self.sampling_method, self.sample_size]),
                ]),
            ],
                              multiple=True),
        ]

        ##
        ## The main
        ##
        self.color = v.Select(label='color', v_model=0)
        self.items = v.Select(label='Show items', multiple=True)
        self.only_stable = v.Switch(label='Show only stable results',
                                    v_model=False)
        self.fig = v.Row(children=[], align='center', justify='center')
        self.plotly_plot = v.Container(align_content_center=True)

        self.dialog = DialogPath()

        self.main = [
            v.Row(children=[self.run], align='center', justify='center'),
            v.Row(children=[self.plotly_plot]), self.dialog
        ]

        ##
        ## Widget events
        ##
        self.run.on_event('click', self.start_PS)
        self.test_case_widget.select_case.observe(self.purge, 'v_model')
        self.lb_scheme_widget.select_case.observe(self.purge, 'v_model')
        self.param_cfg.observe(self.load_param_cfg, 'v_model')

        self.color.observe(self.change_plot, 'v_model')
        self.items.observe(self.change_plot, 'v_model')
        self.only_stable.observe(self.change_plot, 'v_model')
Exemple #15
0
              children=[
                  v.Select(label='Fruits',
                           items=['Apple', 'Pear', 'Cherry'],
                           v_model='Pear')
              ]),
        v.Col(cols=4,
              children=[
                  v.Select(label='Fruits',
                           items=['Apple', 'Pear', 'Cherry'],
                           chips=True,
                           multiple=True,
                           v_model=['Pear', 'Cherry'])
              ]),
        v.Col(cols=4,
              children=[
                  v.Select(label='Fruits',
                           items=['Apple', 'Pear', 'Cherry'],
                           outlined=True)
              ]),
    ]),
    v.Row(children=[
        v.Col(cols=4, children=[v.Slider()]),
        v.Col(cols=4, children=[v.Slider(thumb_label='always')]),
        v.Col(cols=4, children=[v.RangeSlider(value=[20, 80])]),
    ]),
    v.Row(children=[
        v.Col(cols=4, children=[v.Switch(label='switch', margin_top='0')]),
        v.Col(cols=4, children=[menu]),
        v.Col(cols=4, children=[dialog]),
    ]),
])
Exemple #16
0
    def __init__(self):

        self.select_dim = v.Select(label='Dimension', items=[1, 2], v_model=1)
        self.previous_dim = 1

        headers = [
            {
                'text': 'Id',
                'value': 'id'
            },
            {
                'text': 'Iteration',
                'value': 'iteration'
            },
            {
                'text': 'Time',
                'value': 'time'
            },
            {
                'text': 'Field',
                'value': 'field'
            },
            {
                'text': 'Model',
                'value': 'model'
            },
            {
                'text': 'Test case',
                'value': 'test case'
            },
            {
                'text': 'LB scheme',
                'value': 'lb scheme'
            },
            {
                'text': 'Filename',
                'value': 'file'
            },
            {
                'text': 'Directory',
                'value': 'directory'
            },
        ]

        headers_select = v.Select(label='Show columns',
                                  items=[{
                                      'text': v['text'],
                                      'value': i + 1
                                  } for i, v in enumerate(headers[1:])],
                                  v_model=list(range(1, 7)),
                                  multiple=True)

        search = v.TextField(
            v_model=None,
            append_icon="mdi-magnify",
            label="Search",
            single_line=True,
            hide_details=True,
        )

        self.table = v.DataTable(
            v_model=[],
            headers=[headers[i] for i in headers_select.v_model],
            items=[],
            item_key="id",
            single_select=False,
            show_select=True,
            search='',
        )

        self.selected_cache = [[]] * 3
        self.select_item_cache = [[]] * 3
        self.properties_cache = [[]] * 3
        self.select_table = SelectedDataTable(
            self.table,
            headers=[headers[i]
                     for i in headers_select.v_model] + [{
                         'text': 'Action',
                         'value': 'action'
                     }],
        )

        self.plot = Plot()

        def select(change):
            with out:
                for e in list(self.table.v_model):
                    self.select_table.items.append(e)
                    if e['dim'] == 1:
                        self.select_table.properties.append({
                            'label':
                            e['field'],
                            'color':
                            plot_config['colors'][0],
                            'alpha':
                            plot_config['alpha'],
                            'linewidth':
                            plot_config['linewidth'],
                            'linestyle':
                            plot_config['linestyle'],
                            'marker':
                            plot_config['marker'],
                            'markersize':
                            plot_config['markersize']
                        })
                    elif e['dim'] == 2:
                        h5 = os.path.join(e['directory'], e['file'])
                        h5_data = h5py.File(h5)
                        data = h5_data[e['field']][:]
                        self.select_table.properties.append({
                            'label':
                            e['field'],
                            'min_value':
                            np.nanmin(data),
                            'max_value':
                            np.nanmax(data),
                            'cmap':
                            plt.colormaps().index(plot_config['cmap'])
                        })
                    self.table.items.remove(e)
                self.table.v_model = []
                self.select_table.notify_change({
                    'name': 'items',
                    'type': 'change'
                })
                self.table.notify_change({'name': 'items', 'type': 'change'})

        def search_text(change):
            self.table.search = search.v_model

        # self.update(None)

        self.select_table.observe(self.plot_result, 'items')
        self.select_table.observe(self.plot_result, 'properties')
        self.select_table.observe(self.plot_result, 'selected')
        search.observe(search_text, 'v_model')
        self.table.observe(select, 'v_model')
        self.select_dim.observe(self.cache, 'v_model')

        def update_headers(change):
            with out:
                self.table.headers = [
                    headers[i] for i in headers_select.v_model
                ]
                self.select_table.headers = [
                    headers[i] for i in headers_select.v_model
                ] + [{
                    'text': 'Action',
                    'value': 'action'
                }]
                self.select_table.notify_change({
                    'name': 'items',
                    'type': 'change'
                })
                self.table.notify_change({'name': 'items', 'type': 'change'})

        headers_select.observe(update_headers, 'v_model')

        download_zip = v.Btn(children=['Download results'])

        def create_zip(widget, event, data):
            from zipfile import ZipFile

            zipfilename = os.path.join(voila_notebook, 'results.zip')
            with ZipFile(zipfilename, 'w') as zipObj:
                for folderName, subfolders, filenames in os.walk(default_path):
                    for filename in filenames:
                        #create complete filepath of file in directory
                        filePath = os.path.join(folderName, filename)

                        # Add file to zip
                        zipObj.write(filePath,
                                     filePath.replace(default_path, ''))

            dialog.children = [
                v.Card(children=[
                    v.CardTitle(children=[
                        widgets.HTML(
                            f'<a href="./results.zip" download="results.zip">Download the archive</a>'
                        )
                    ])
                ])
            ]
            dialog.v_model = True

        self.title = v.TextField(label='Plot title', v_model='')
        self.xlabel = v.TextField(label='x label', v_model='')
        self.ylabel = v.TextField(label='y label', v_model='')
        self.legend = v.Switch(label='Add legend', v_model=False)

        self.title.observe(self.set_plot_properties, 'v_model')
        self.xlabel.observe(self.set_plot_properties, 'v_model')
        self.ylabel.observe(self.set_plot_properties, 'v_model')
        self.legend.observe(self.set_plot_properties, 'v_model')

        dialog = v.Dialog()
        dialog.v_model = False
        dialog.width = '200'
        download_zip.on_event('click', create_zip)

        self.menu = [
            self.select_dim, headers_select, self.title, self.xlabel,
            self.ylabel, self.legend, download_zip, dialog
        ]
        self.main = [
            v.Card(
                children=[
                    v.CardTitle(
                        children=['Available results',
                                  v.Spacer(), search]),
                    self.table,
                ],
                class_='ma-2',
            ),
            v.Card(
                children=[
                    v.CardTitle(children=[
                        'Selected results',
                    ]),
                    self.select_table,
                    self.select_table.dialog,
                ],
                class_='ma-2',
            ),
            v.Row(children=[self.plot.fig.canvas], justify='center'),
        ]