Example #1
0
    def __init__(self, **params):
        super(LoadModel, self).__init__(**params)
        self.dat_files = []

        self.model = None

        self.adh_mod = AdhModel()
Example #2
0
class ConceptualModelEditor(param.Parameterized):
    adh_mod = param.ClassSelector(default=AdhModel(
        path_type=gv.Polygons,
        poly_columns=['node_spacing'],
        point_columns=['node_spacing']),
                                  class_=AdhModel)

    polys = param.ClassSelector(class_=hv.Path)

    def __init__(self, polys, **params):
        super(ConceptualModelEditor, self).__init__(polys=polys, **params)

        self.adh_mod = AdhModel(path_type=gv.Polygons,
                                polys=polys,
                                point_columns=['node_spacing'],
                                poly_columns=['node_spacing'],
                                crs=polys.crs)
        self.adh_mod.projection.set_crs(polys.crs)
        self.adh_mod.wmts.source = gv.tile_sources.EsriImagery

        self.adh_mod.height = 600
        self.adh_mod.width = 600

    @param.output(adh_mod=AdhModel)
    def output(self):
        return self.adh_mod

    def panel(self):
        return self.adh_mod.panel()
Example #3
0
def test_adhmodel_read_mesh():
    # set test project name
    project_name = 'SanDiego'
    # set project directory
    path = os.path.join(TESTDIR, 'test_files', project_name)
    # instantiate empty adh model object
    adhmod = AdhModel()
    # read the mesh file
    adhmod.read_mesh(path=path, project_name=project_name, crs=None, fmt='nc')
Example #4
0
 def test_read_result(self):
     file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                              'test_files/SanDiego', 'SanDiego_dep.dat')
     model = AdhModel()
     model.read_result(file_path)
     results = model.simulation.results
     self.assertEqual(len(results), 1)
     self.assertIn('Depth', results)
     self.assertEqual(results.Depth.shape, (49, 9140))
Example #5
0
def test_adhmodel_fromnnetcdf():
    # set test project name
    project_name = 'SanDiego'
    # set project directory
    path = os.path.join(TESTDIR, 'test_files', project_name)
    # instantiate empty adh model object
    adhmod = AdhModel()
    # read model files
    adhmod.from_netcdf(path=path, project_name=project_name, crs=None)
Example #6
0
 def test_bad_format_e3t(self):
     path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'test_files')
     fname = os.path.join(path, 'bad_mesh_e3t.3dm')
     model = AdhModel()
     with self.assertRaises(ValueError) as context:
         model.read_mesh(fname, fmt='3dm')
     # self.assertTrue('Error reading element (E3T) record from file on line 3.' in str(context.exception))
     self.assertTrue(
         "list.remove(x): x not in list" in str(context.exception))
Example #7
0
def test_adhmodel_read_bc():
    # set test project name
    project_name = 'SanDiego'
    # set project directory
    path = os.path.join(TESTDIR, 'test_files', project_name,
                        f'{project_name}.bc')
    # instantiate empty adh model object
    adhmod = AdhModel()
    # read the mesh file
    adhmod.read_bc(file_name=path, fmt='bc')
Example #8
0
 def test_bad_format_nds(self):
     path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'test_files')
     fname = os.path.join(path, 'bad_mesh_nds.3dm')
     model = AdhModel()
     with self.assertRaises(UnboundLocalError) as context:
         model.read_mesh(fname, fmt='3dm')
     # self.assertTrue('Error reading node (ND) record from file on line 2.' in str(context.exception))
     self.assertTrue(
         "local variable 'extra_cols' referenced before assignment" in str(
             context.exception))
Example #9
0
 def test_read_hot_start(self):
     path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'test_files')
     fname = os.path.join(path, 'angle_bt.hot')
     out_file = os.path.join(path, 'out_files', 'out_angle_bt.hot')
     base_file = os.path.join(path, 'base_angle_bt.hot')
     model = AdhModel()
     model.read_hotstart(fname, fmt='ascii')
     hotstart = model.simulation.hotstart
     self.assertEqual(1, len(hotstart))
     self.assertEqual(250, hotstart.ioh.size)
     model.simulation.write_hotstart(out_file)
     self.assertTrue(filecmp.cmp(base_file, out_file, shallow=False))
Example #10
0
    def __init__(self, polys, **params):
        super(ConceptualModelEditor, self).__init__(polys=polys, **params)

        self.adh_mod = AdhModel(path_type=gv.Polygons,
                                polys=polys,
                                point_columns=['node_spacing'],
                                poly_columns=['node_spacing'],
                                crs=polys.crs)
        self.adh_mod.projection.set_crs(polys.crs)
        self.adh_mod.wmts.source = gv.tile_sources.EsriImagery

        self.adh_mod.height = 600
        self.adh_mod.width = 600
Example #11
0
 def test_read_results(self):
     path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'test_files/SanDiego')
     project_name = 'SanDiego'
     model = AdhModel()
     model.read_results(path=path, project_name=project_name, fmt='ascii')
     results = model.simulation.results
     self.assertEqual(len(results), 3)
     self.assertIn('Depth', results)
     self.assertIn('Error', results)
     self.assertIn('Depth-Averaged Velocity', results)
     self.assertEqual(results.Depth.shape, (49, 9140))
     self.assertEqual(results['Depth-Averaged Velocity'].shape,
                      (49, 9140, 3))
Example #12
0
 def test_read_bc_2d_coriolis_x(self):
     path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'test_files')
     fname = os.path.join(path, '2D-coriolis_X.bc')
     base_file = os.path.join(path, 'base_2D-coriolis_X.bc')
     out_file = os.path.join(path, 'out_files', 'out_2D-coriolis_X.bc')
     model = AdhModel()
     model.read_bc(fname, fmt='bc')
     model.write_bc(out_file, fmt='bc', validate=False)
     self.assertTrue(filecmp.cmp(base_file, out_file))
Example #13
0
 def test_read_bc_east_ll_coarse(self):
     path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'test_files')
     fname = os.path.join(path, 'east_LL_coarse.bc')
     base_file = os.path.join(path, 'base_east_LL_coarse.bc')
     out_file = os.path.join(path, 'out_files', 'out_east_LL_coarse.bc')
     model = AdhModel()
     model.read_bc(fname, fmt='bc')
     model.write_bc(out_file, fmt='bc', validate=False)
     self.assertTrue(filecmp.cmp(base_file, out_file))
Example #14
0
 def test_read_bc_red_river(self):
     path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'test_files')
     fname = os.path.join(path, 'RedRiver.bc')
     base_file = os.path.join(path, 'base_RedRiver.bc')
     out_file = os.path.join(path, 'out_files', 'out_RedRiver.bc')
     model = AdhModel()
     model.read_bc(fname, fmt='bc')
     model.write_bc(out_file, fmt='bc', validate=False)
     self.assertTrue(filecmp.cmp(base_file, out_file))
Example #15
0
 def test_read_mesh_file(self):
     path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'test_files')
     fname = os.path.join(path, 'angle_bt.3dm')
     out_file = os.path.join(path, 'out_files', 'out_angle_bt.3dm')
     base_file = os.path.join(path, 'base_angle_bt2.3dm')
     model = AdhModel()
     model.read_mesh(fname, fmt='3dm')
     model.write_mesh(out_file, fmt='3dm')
     self.assertTrue(filecmp.cmp(base_file, out_file))
Example #16
0
    def test_read_bc_file(self):
        path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                            'test_files')
        fname = os.path.join(path, 'ka_mult_sed.bc')
        base_file = os.path.join(path, 'base_ka_mult_sed.bc')
        out_file = os.path.join(path, 'out_files', 'out_ka_mult_sed.bc')
        out_file2 = os.path.join(path, 'out_files', 'out2_ka_mult_sed.bc')
        model = AdhModel()
        model.read_bc(fname, fmt='bc')
        model.write_bc(out_file, fmt='bc', validate=False)
        self.assertTrue(filecmp.cmp(base_file, out_file))

        bc_class2 = BoundaryConditions()
        read_bc_file(out_file, bc_class2)
        write_bc_file(out_file2, bc_class2)
        self.assertTrue(filecmp.cmp(out_file, out_file2))
Example #17
0
def test_adhmodel_initialize():
    adhmod = AdhModel(version=5.0)
    assert adhmod.version == 5
Example #18
0
class CreateMesh(param.Parameterized):
    """
    We need a UUID for each polygon created (https://github.com/pyviz/EarthSim/issues/292)
    and then we need to apply attirbutes to the UUID.
    This is an issue right now since polygons are currently not being deleted properly. So they
    will always be in poly_stream (either as empty list or a single node - I cant remember)
    """

    create = param.Action(lambda self: self.param.trigger('create'),
                          label='Generate Mesh',
                          precedence=0.2)
    status_bar = param.ClassSelector(default=StatusBar(), class_=StatusBar)

    # import data
    point_file = param.String(default=os.path.join(ROOTDIR, 'tests',
                                                   'test_files',
                                                   'vicksburg_pts.geojson'),
                              label='Point file (*.geojson)',
                              precedence=3)
    poly_file = param.String(default=os.path.join(ROOTDIR, 'tests',
                                                  'test_files',
                                                  'vicksburg_polys.geojson'),
                             label='Polygon file (*geojson)',
                             precedence=4)
    import_projection = param.ClassSelector(default=Projection(),
                                            class_=Projection,
                                            precedence=5)
    load_data = param.Action(lambda self: self.param.trigger('load_data'),
                             label='Load',
                             precedence=6)

    map_height = param.Number(default=600, bounds=(0, None), precedence=-1)
    map_width = param.Number(default=600, bounds=(0, None), precedence=-1)

    default_point_spacing = param.Number(default=1000,
                                         bounds=(0, None),
                                         precedence=-1)
    default_poly_spacing = param.Number(default=1000,
                                        bounds=(0, None),
                                        precedence=-1)

    adh_mod = param.ClassSelector(default=AdhModel(
        path_type=gv.Polygons,
        poly_columns=['node_spacing'],
        point_columns=['node_spacing'],
        crs=ccrs.GOOGLE_MERCATOR),
                                  class_=AdhModel)

    def __init__(self, **params):
        super(CreateMesh, self).__init__(**params)

        # self.map.opts.get('style') # merged but not released. (https://github.com/pyviz/holoviews/pull/3440)
        self.mesh_io = None
        self.adh_mod.wmts.source = gv.tile_sources.EsriImagery
        self.import_projection.set_crs(ccrs.GOOGLE_MERCATOR)

    @param.depends('load_data', watch=True)
    def _load_data(self):
        polys = geopandas.read_file(self.poly_file)
        pts = geopandas.read_file(self.point_file)

        self.adh_mod.points = geodframe_to_geoviews(
            pts, 'point', crs=self.import_projection.get_crs())
        self.adh_mod.polys = geodframe_to_geoviews(
            polys, 'polygon', crs=self.import_projection.get_crs())

    @param.depends('create', watch=True)
    def _create(self):
        # print('create clicked')
        # todo modify to always reproject to mercator before creating the mesh
        self.status_bar.busy()

        refine_points = []

        if self.adh_mod.point_stream.data and 'node_spacing' in self.adh_mod.point_stream.element.columns(
        ):
            # for item in zip(element['Longitude'], element['Latitude'], element['node_spacing']):
            for idx in range(len(self.adh_mod.point_stream.data['Longitude'])):

                refine_points.append(
                    xmsmesh.meshing.RefinePoint(
                        create_mesh_point=True,
                        point=(
                            self.adh_mod.point_stream.element['Longitude']
                            [idx],
                            self.adh_mod.point_stream.element['Latitude'][idx],
                            0),
                        size=float(self.adh_mod.point_stream.
                                   element['node_spacing'])))

        # ==============
        input_polygon = []
        if self.adh_mod.poly_stream.data:
            for idx in range(len(self.adh_mod.poly_stream.data['xs'])):
                poly_arr = np.fromiter(zip(
                    self.adh_mod.poly_stream.data['xs'][idx],
                    self.adh_mod.poly_stream.data['ys'][idx],
                    [0] * len(self.adh_mod.poly_stream.data['ys'][idx])),
                                       dtype=('float,float,float'))

                # if no spacing value is given, use only the existing polygon vertices
                # if self.adh_mod.poly_stream.data['node_spacing'][idx] == self.adh_mod.default_value:
                # if self.adh_mod.poly_stream.data['node_spacing'][idx] == '':
                #     input_polygon.append(xmsmesh.meshing.PolyInput(outside_polygon=poly_arr))

                # redistribute vertices based on spacing from user
                # else:
                # instantiate the redistribution class
                rdp = xmsmesh.meshing.PolyRedistributePts()
                # set the node distance

                node_spacing = float(
                    self.adh_mod.poly_stream.element.dimension_values(
                        'node_spacing', expanded=False)[idx])
                # print(node_spacing, type(node_spacing))
                # rdp.set_constant_size_func(float(self.adh_mod.poly_stream.data['node_spacing'][idx]))  # create_constant_size_function
                rdp.set_constant_size_func(node_spacing)
                # run the redistribution function
                outdata = rdp.redistribute(poly_arr)
                # AML CHANGE redistribute with the closed loop and then remove the duplicates
                # and reverse the order because the mesher expects clockwise polygons
                # ensure start and end node are different
                # if len(poly_arr) != 0:  # todo - waiting on fix for moving poly edges that leave a single node poly behind
                #     outdata = check_polygon(outdata)[::-1] # todo pretty sure this is fixed so I'm commenting it out
                # convert the polygon to an 'input polygon'
                input_polygon.append(
                    xmsmesh.meshing.PolyInput(outside_polygon=outdata))

        # add the input polygons as polygons to the mesher class
        self.mesh_io = xmsmesh.meshing.MultiPolyMesherIo(
            poly_inputs=input_polygon, refine_points=refine_points)

        # Generate Mesh
        succeded, errors = xmsmesh.meshing.mesh_utils.generate_mesh(
            mesh_io=self.mesh_io)
        if succeded:
            self.status_bar.set_msg('Meshing was successful')
        else:
            self.status_bar.set_msg('Meshing errors found: {}'.format(errors))

        # poly_stream and point_stream are always mercator because they come from bokeh
        proj = Projection(crs_label='Mercator')
        self.adh_mod.mesh = AdhMesh(projection=proj)
        self.adh_mod.mesh.verts, self.adh_mod.mesh.tris = xmsmesh_to_dataframe(
            self.mesh_io.points, self.mesh_io.cells)
        self.adh_mod.mesh.reproject_points()
        self.adh_mod.mesh.tri_mesh = gv.TriMesh(
            (self.adh_mod.mesh.tris[['v0', 'v1', 'v2']],
             self.adh_mod.mesh.mesh_points)).opts(
                 opts.TriMesh(edge_cmap='yellow', edge_color='yellow'))

    # @param.depends('adh_mod.mesh', 'adh_mod.viewable_points', 'adh_mod.viewable_polys', 'load_data', 'adh_mod.wmts.source', watch=True)
    @param.depends('create', 'load_data', watch=True)
    def view_map(self):
        map = hv.DynamicMap(
            self.adh_mod.wmts.view) * self.adh_mod.polys * self.adh_mod.points
        if not self.adh_mod.mesh.verts.empty:
            # map *= self.adh_mod.mesh.view_elements(line_color='black')
            map *= self.adh_mod.mesh.view_mesh(line_color='blue')

        return map.opts(width=self.map_width, height=self.map_height)

    @param.depends('create', 'load_data', watch=True)
    def _data_tab(self):
        return pn.Tabs(('Polygons', self.adh_mod.poly_table),
                       ('Points', self.adh_mod.point_table),
                       name='View Data')

    @param.output(adh_mod=AdhModel)
    def output(self):
        return self.adh_mod

    # @param.depends('load_data')
    def panel(self):
        map_panel = pn.Column(
            self.view_map,
            pn.panel(self.param, parameters=['create'], show_name=False))
        # display_tab = pn.Column(
        #                         pn.panel(self.adh_mod.wmts.param, parameters=['source'], expand_button=False),
        #                         pn.pane.Markdown('Visibility', style={'font-family':'Arial'}),
        #                         pn.panel(self.adh_mod.param, parameters=['viewable_points'], show_name=False),
        #                         self.adh_mod.param.viewable_polys
        #                         )

        display_tab = pn.Column(
            pn.panel(self.adh_mod.wmts.param,
                     parameters=['source'],
                     expand_button=False,
                     show_name=False))

        # data_tab = pn.Tabs(('Polygons', self.adh_mod.poly_table), ('Points', self.adh_mod.point_table), name='View Data')

        import_tab = pn.Column(
            pn.panel(self.param,
                     parameters=['point_file', 'poly_file'],
                     show_name=False),
            pn.panel(self.import_projection, show_name=False),
            pn.panel(self.param, parameters=['load_data'], show_name=False))

        logo_box = pn.Spacer()

        tool_panel = pn.Column(
            pn.Tabs(('Conceptual Model', self._data_tab),
                    ('Display', display_tab)), logo_box)

        main = pn.Column(pn.Row(map_panel, tool_panel), self.status_bar.panel)

        return main
Example #19
0
class AdhView(param.Parameterized):
    """

    """
    # projection options
    projection = param.ClassSelector(default=Projection(name=''),
                                     class_=Projection)
    # generic display options
    cmap_opts = param.ClassSelector(default=ColormapOpts(),
                                    class_=ColormapOpts)
    display_range = param.ClassSelector(default=DisplayRangeOpts(),
                                        class_=DisplayRangeOpts)

    adh_mod = param.ClassSelector(
        default=AdhModel(),
        class_=AdhModel,
        precedence=-1,
        doc="""AdhModel object containing all the model data""")

    # todo view analysis is currently hidden until it receives more work
    view_analysis = param.Boolean(
        default=False,
        precedence=-1,
    )
    resolution = param.Number(default=1000,
                              bounds=(10, 2000),
                              softbounds=(10, 2000),
                              doc="""
            Distance between samples in meters. Used for interpolation
            of the cross-section paths.""")

    selected_result = param.ObjectSelector()

    selected_times = param.ObjectSelector()

    bc_ui = param.ClassSelector(class_=BoundaryConditionsUI)

    def __init__(self, **params):
        super(AdhView, self).__init__(**params)
        # initialize the boundary condition ui
        self.bc_ui = BoundaryConditionsUI(
            bound_cond=self.adh_mod.simulation.boundary_conditions)

        self.meshes = None

        if len(self.adh_mod.simulation.results.data_vars) != 0:
            # set default values
            self.param.selected_result.objects = self.adh_mod.simulation.results.data_vars
            try:
                self.selected_result = 'Depth'
            except:
                self.selected_result = set(
                    self.adh_mod.simulation.results.data_vars).pop()

            self.param.selected_times.objects = self.adh_mod.mesh.current_sim.results[
                self.selected_result].times.data
            self.selected_times = set(self.adh_mod.mesh.current_sim.results[
                self.selected_result].times.data).pop()

        # set default colormap
        self.cmap_opts.colormap = process_cmap('rainbow_r')
        # set default wmts
        self.adh_mod.wmts.source = gvts.tile_sources['EsriImagery']

    # function for dynamic map call
    @param.depends('selected_times')
    def time_mesh_scalar(self):
        # add this time step's data as a vdim under the provided label
        data_points = self.adh_mod.mesh.mesh_points.add_dimension(
            self.selected_result,
            0,
            self.adh_mod.mesh.current_sim.results[self.selected_result].sel(
                times=self.selected_times).data,
            vdim=True)

        # return a trimesh with this data
        return gv.TriMesh(
            (self.adh_mod.mesh.tris[['v0', 'v1', 'v2']], data_points),
            label=self.selected_result,
            crs=ccrs.GOOGLE_MERCATOR)

    @param.depends('selected_times')
    def time_mesh_vector(self):
        vx = self.adh_mod.mesh.current_sim.results[self.selected_result].sel(
            times=self.selected_times).data[:, 0]
        vy = self.adh_mod.mesh.current_sim.results[self.selected_result].sel(
            times=self.selected_times).data[:, 1]
        xs = self.adh_mod.mesh.mesh_points.data['x']
        ys = self.adh_mod.mesh.mesh_points.data['y']
        with np.errstate(divide='ignore', invalid='ignore'):
            angle = np.arctan2(vy, vx)
        mag = np.sqrt(vx**2 + vy**2)
        return gv.VectorField((xs, ys, angle, mag),
                              vdims=['Angle', 'Magnitude'],
                              crs=ccrs.GOOGLE_MERCATOR)

    @param.depends('selected_result')
    def create_animation(self):
        """ Method to create holoviews dynamic map meshes for vector or scalar datasets"""
        # check to make sure the mesh points have been set.
        if self.adh_mod.mesh.mesh_points.data.empty:
            self.adh_mod.mesh.reproject_points()

        if 'BEGSCL' in self.adh_mod.mesh.current_sim.results[
                self.selected_result].attrs.keys():
            meshes = hv.DynamicMap(self.time_mesh_scalar, label='scalar')
            # meshes = hv.DynamicMap(self.time_mesh_scalar, kdims='times', label='scalar').redim.values(
            #     times=sorted(self.adh_mod.mesh.current_sim.results['Depth'].times.values))

            return meshes

        elif 'BEGVEC' in self.adh_mod.mesh.current_sim.results[
                self.selected_result].attrs.keys():
            meshes = hv.DynamicMap(self.time_mesh_vector, label='vector')
            return meshes

        else:
            log.error('Data type not recognized. Must be BEGSCL or BEGVEC.')

    @property
    def tabs(self):
        # if the annotator has no mesh
        if self.adh_mod.mesh.verts.empty:
            disp_tab = pn.Column(
                pn.panel(self.adh_mod.wmts.param,
                         parameters=['source'],
                         expand_button=False,
                         show_name=False))
        # otherwise display all mesh options
        else:
            disp_tab = pn.Column(
                pn.panel(self.adh_mod.wmts.param,
                         parameters=['source'],
                         expand_button=False,
                         show_name=False),
                pn.panel(self.cmap_opts, show_name=False),
                pn.panel(self.display_range, show_name=False),
                pn.panel(self.adh_mod.mesh.param,
                         parameters=['elements_toggle'],
                         show_name=False),
                pn.panel(self.param,
                         parameters=['selected_result'],
                         show_name=False),
                pn.panel(self, parameters=['view_analysis'], show_name=False))

        return [('Display', disp_tab)]

    # what to pass out of this page (for pipeline)
    @param.output()
    def output(self):
        pass

    # how to build this page
    def panel(self):
        return pn.panel(self.run)

    @param.depends('selected_result',
                   'view_analysis',
                   'adh_mod.mesh.elements_toggle',
                   watch=True)
    def run(self):
        self.build_map_pane()
        self.build_tool_pane()
        self.build_analysis_pane()

        return pn.Row(self.map_pane, self.analysis_pane, self.tool_pane)

    def build_tool_pane(self, logo=None):
        if logo:
            logo_box = pn.panel(logo, width=300)
        else:
            logo_box = pn.Spacer()
        # self.tool_pane = pn.Column(pn.Tabs(*self.tabs, *self.bc_ui.tabs), logo_box)
        self.tool_pane = pn.Column(pn.Tabs(*self.tabs), logo_box)
        # self.tool_pane = pn.Column(pn.Tabs(*self.tabs), self.bc_ui.panel(), logo_box)

    # @param.depends('annotator.result_label')
    # @param.depends('adh_mod.mesh.elements_toggle', watch=True) # todo I don't know why this won't work
    def build_map_pane(self):
        if self.adh_mod.mesh.verts.empty:
            self.map_pane = self.adh_mod.map_view
            self.analysis_pane = pn.Spacer()
        else:
            # create the meshes for the dynamic map
            meshes = self.create_animation()

            edgepaths_overlay = self.adh_mod.mesh.view_elements()

            # Define dynamic options
            opts = dict(clipping_colors={
                'NaN': 'transparent',
                'min': 'transparent'
            },
                        cmap=self.cmap_opts.param.colormap,
                        clim=self.display_range.param.color_range,
                        height=600,
                        width=600)
            if meshes.label == 'scalar':

                # todo THIS IS GOING TO LOSE ALL ANNOTATIONS EVERY TIME THE MAP IS REDRAWN

                rasterized = rasterize(meshes).apply.opts(**opts)
                # Apply the colormap and color range dynamically
                dynamic = (rasterized * hv.DynamicMap(self.adh_mod.wmts.view) *
                           self.adh_mod.polys * self.adh_mod.points *
                           edgepaths_overlay)
            elif meshes.label == 'vector':
                # Apply the colormap and color range dynamically
                paths = vectorfield_to_paths(meshes,
                                             color='Magnitude',
                                             magnitude='Magnitude',
                                             scale=0.005)
                rasterized = rasterize(paths,
                                       aggregator='mean',
                                       precompute=True).apply.opts(**opts)
                dynamic = (rasterized * hv.DynamicMap(self.adh_mod.wmts.view) *
                           self.adh_mod.polys * self.adh_mod.points *
                           edgepaths_overlay)

            # time = pn.panel(self.adh_mod, parameters=['time'], widgets={'time': pn.widgets.DiscretePlayer}, show_name=False, width=400)
            # time = pn.panel(self.adh_mod.mesh.simulations[self.sim_selector], parameters=['time'], widgets={'time': pn.widgets.DiscretePlayer}, show_name=False, width=400)
            # time = pn.panel(self.adh_mod.mesh.current_sim, parameters=['time'],
            #                 widgets={'time': pn.widgets.DiscretePlayer}, show_name=False, width=400)
            time = pn.panel(
                self.param,
                parameters=['selected_times'],
                widgets={'selected_times': pn.widgets.DiscretePlayer},
                show_name=False,
                width=600)

            hv_panel = pn.panel(dynamic)

            if self.view_analysis:
                # todo going to have to combine the dynamic maps for meshes/vectorization/moving_points
                # self.map_pane = pn.Column(hv_panel[0] * self.annotator.moving_points, pn.Row(pn.Spacer(width=100), time))

                # create the sections of the trimesh
                self.sections = meshes.apply(
                    self.adh_mod._sample, streams=[self.adh_mod.poly_stream])
                point_x = PointerX(source=self.sections, x=0)
                self.vline = hv.DynamicMap(hv.VLine, streams=[point_x])
                self.moving_points = self.sections.apply(
                    self.adh_mod._pos_indicator, streams=[point_x])
                self.analysis_pane = pn.Column(
                    (self.sections * self.vline).redim.range(
                        Depth=(0, 100),
                        Distance=(0, 20000)).opts(framewise=True))
                self.map_pane = pn.Column(hv_panel[0],
                                          pn.Row(pn.Spacer(width=80), time))
            else:
                self.map_pane = pn.Column(hv_panel[0],
                                          pn.Row(pn.Spacer(width=80), time))
                self.analysis_pane = pn.Spacer()

    def build_analysis_pane(self):
        # if self.view_analysis:
        #     self.analysis_pane = pn.Column(self.sections * self.vline)
        pass
Example #20
0
class LoadModel(param.Parameterized):
    """
    Parameterized class to load model information

    Formatted for Panel and Pipeline Page
    """
    load_sim_widget = param.ClassSelector(default=LoadSimulation(),
                                          class_=LoadSimulation)
    att_widget = param.ClassSelector(default=Attributes(), class_=Attributes)
    projection = param.ClassSelector(default=Projection(), class_=Projection)

    load_data = param.Action(lambda self: self.param.trigger('load_data'),
                             label='Load Data',
                             precedence=0.2)

    label = param.String(default='Basic Input', precedence=-1)

    def __init__(self, **params):
        super(LoadModel, self).__init__(**params)
        self.dat_files = []

        self.model = None

        self.adh_mod = AdhModel()

    # output the adh_viz object
    # @param.output(annot=AdhAnnotator)
    @param.output(adh_mod=AdhModel)
    def output(self):
        return self._load_data()

    @param.depends('load_sim_widget.load_netcdf',
                   'load_sim_widget.adh_root_filename',
                   'load_sim_widget.adh_directory',
                   watch=True)
    def available_attributes(self):
        # todo this needs a 'no files found' check
        att_list = []
        # enable the projections
        self.projection.set_constant(value=False)

        # if netcdf is selected
        if self.load_sim_widget.load_netcdf:
            filename = os.path.join(
                self.load_sim_widget.adh_directory,
                self.load_sim_widget.adh_root_filename + '.nc')

            try:
                # open the xarray dataset (does not load into memory)
                ncdf = xr.open_dataset(filename)

            except FileNotFoundError:
                print('File Not Found: {}'.format(filename))
            else:
                # look for crs in the file
                if 'crs' in ncdf.attrs.keys():
                    # set the projection in the widget
                    self.projection.set_crs(get_crs(ncdf))
                    # disable the widget
                    self.projection.set_constant(value=True)

                with ncdf:
                    # enable and add all variables in the netcdf file
                    for var in ncdf.data_vars:
                        att_name = var.lower().replace(" ", "_")

                        # if the variable has results dimensions
                        if 'times' in ncdf[var].dims and 'nodes_ids' in ncdf[
                                var].dims:
                            if att_name == 'depth-averaged_velocity':
                                att_list.append('velocity')
                            elif att_name == 'error':
                                att_list.append('error_hydro')
                            else:
                                # add to the list
                                att_list.append(att_name)
                # close the dataset
                ncdf.close()

        # otherwise read from available *.dat files
        else:
            # get the list of filenames  # todo this isn't foolproof e.g. `SanDieg` finds files
            file_names = glob.glob(
                os.path.join(self.load_sim_widget.adh_directory,
                             self.load_sim_widget.adh_root_filename +
                             '_*.dat'))

            # convert file suffixes to a list of widgets
            att_list = [
                self.att_widget.suffix_to_widget[get_variable_from_file_name(
                    x)] for x in file_names
            ]

        # # dictionary for naming inconsistencies # todo add complexity for err_con in future
        # label_to_widget = {'error': 'error_hydro',
        #                    'depth-averaged_velocity': 'velocity'}
        #
        # # loop over the inconsistencies
        # for key in label_to_widget.keys():
        #     # if this is found in the list
        #     if key in att_list:
        #         # remove the key
        #         att_list.remove(key)
        #         # add back in the corrected value
        #         att_list.append(label_to_widget[key])

        # adjust available attribute widgets based on available data
        for p in self.att_widget.param:
            # if this attribute wasn't in the list
            pobj = self.att_widget.param[p]
            if p in att_list:
                # ensure the widget is enabled
                pobj.constant = False
                # set the widget value
                setattr(self.att_widget, p, True)
            elif p != 'name':
                # ensure the widget is enabled
                pobj.constant = False
                # uncheck the attribute
                setattr(self.att_widget, p, False)
                # disable attribute
                pobj.constant = True

    @param.depends('load_data', watch=True)
    def _load_data(self):
        # if file is netcdf
        if self.load_sim_widget.load_netcdf:

            self.adh_mod.from_netcdf(
                path=self.load_sim_widget.adh_directory,
                project_name=self.load_sim_widget.adh_root_filename,
                crs=self.projection.get_crs())
        # request to load data from *dat files:
        else:
            # get a list of requested suffix strings
            slist = self.att_widget.suffix_list(value=True)

            # construct list of filenames
            fnames = []
            [
                fnames.append(
                    os.path.join(
                        self.load_sim_widget.adh_directory,
                        self.load_sim_widget.adh_root_filename + '_' + x +
                        '.dat')) for x in slist
            ]
            # read the requested files
            self.adh_mod.from_ascii(
                path=self.load_sim_widget.adh_directory,
                project_name=self.load_sim_widget.adh_root_filename,
                crs=self.projection.get_crs(),
                file_names=fnames)

        return self.adh_mod

    # visualize the page
    def panel(self):
        self.available_attributes()  # for the initial load
        return pn.Column(
            pn.Row(pn.Param(self.load_sim_widget, show_name=False),
                   pn.Param(self.att_widget, show_name=False),
                   pn.Param(self.projection, show_name=False),
                   name=self.label),
            pn.Pane(self.param, parameters=['load_data'], show_name=False))