Skip to content

solution_surfaces_builder

solution_surfaces_builder

Provide functions & classes supporting surfaces in inversion solutions geometries.

log = logging.getLogger(__name__) module-attribute

SolutionSurfacesBuilder

A class to build solution surfaces.

Source code in solvis/solution/solution_surfaces_builder.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
class SolutionSurfacesBuilder:
    """A class to build solution surfaces."""

    def __init__(self, solution: Union['InversionSolution', 'FaultSystemSolution']) -> None:
        self._solution = solution

    def fault_surfaces(self) -> gpd.GeoDataFrame:
        """Calculate the geometry of the solution fault surfaces projected onto the earth surface.

        Returns:
            a gpd.GeoDataFrame
        """
        tic = time.perf_counter()
        new_geometry_df: gpd.GeoDataFrame = self._solution.solution_file.fault_sections.copy()
        toc = time.perf_counter()
        log.debug('time to load fault_sections: %2.3f seconds' % (toc - tic))
        if self._solution.fault_regime == 'SUBDUCTION':
            return new_geometry_df.set_geometry(
                [create_subduction_section_surface(section) for i, section in new_geometry_df.iterrows()]
            )
        elif self._solution.fault_regime == 'CRUSTAL':
            return new_geometry_df.set_geometry(
                [create_crustal_section_surface(section) for i, section in new_geometry_df.iterrows()]
            )
        else:  # pragma: no cover
            raise RuntimeError(f'Unable to render fault_surfaces for fault regime {self._solution.fault_regime}')

    def rupture_surface(self, rupture_id: int) -> gpd.GeoDataFrame:
        """Calculate the geometry of the rupture surfaces projected onto the earth surface.

        Args:
            rupture_id: ID of the rupture

        Returns:
            a gpd.GeoDataFrame
        """
        tic = time.perf_counter()
        df0 = self._solution.model.fault_sections_with_rupture_rates.copy()
        toc = time.perf_counter()
        log.debug('time to load fault_sections_with_rupture_rates: %2.3f seconds' % (toc - tic))
        rupt: gpd.DataFrame = df0[df0["Rupture Index"] == rupture_id]
        if self._solution.fault_regime == 'SUBDUCTION':
            return rupt.set_geometry([create_subduction_section_surface(section) for i, section in rupt.iterrows()])
        elif self._solution.fault_regime == 'CRUSTAL':
            return rupt.set_geometry([create_crustal_section_surface(section) for i, section in rupt.iterrows()])
        else:  # pragma: no cover
            raise RuntimeError(f'Unable to render rupture_surface for fault regime {self._solution.fault_regime}')

__init__(solution: Union[InversionSolution, FaultSystemSolution]) -> None

Source code in solvis/solution/solution_surfaces_builder.py
46
47
def __init__(self, solution: Union['InversionSolution', 'FaultSystemSolution']) -> None:
    self._solution = solution

fault_surfaces() -> gpd.GeoDataFrame

Calculate the geometry of the solution fault surfaces projected onto the earth surface.

Returns:

Type Description
gpd.GeoDataFrame

a gpd.GeoDataFrame

Source code in solvis/solution/solution_surfaces_builder.py
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
def fault_surfaces(self) -> gpd.GeoDataFrame:
    """Calculate the geometry of the solution fault surfaces projected onto the earth surface.

    Returns:
        a gpd.GeoDataFrame
    """
    tic = time.perf_counter()
    new_geometry_df: gpd.GeoDataFrame = self._solution.solution_file.fault_sections.copy()
    toc = time.perf_counter()
    log.debug('time to load fault_sections: %2.3f seconds' % (toc - tic))
    if self._solution.fault_regime == 'SUBDUCTION':
        return new_geometry_df.set_geometry(
            [create_subduction_section_surface(section) for i, section in new_geometry_df.iterrows()]
        )
    elif self._solution.fault_regime == 'CRUSTAL':
        return new_geometry_df.set_geometry(
            [create_crustal_section_surface(section) for i, section in new_geometry_df.iterrows()]
        )
    else:  # pragma: no cover
        raise RuntimeError(f'Unable to render fault_surfaces for fault regime {self._solution.fault_regime}')

rupture_surface(rupture_id: int) -> gpd.GeoDataFrame

Calculate the geometry of the rupture surfaces projected onto the earth surface.

Parameters:

Name Type Description Default
rupture_id int

ID of the rupture

required

Returns:

Type Description
gpd.GeoDataFrame

a gpd.GeoDataFrame

Source code in solvis/solution/solution_surfaces_builder.py
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
def rupture_surface(self, rupture_id: int) -> gpd.GeoDataFrame:
    """Calculate the geometry of the rupture surfaces projected onto the earth surface.

    Args:
        rupture_id: ID of the rupture

    Returns:
        a gpd.GeoDataFrame
    """
    tic = time.perf_counter()
    df0 = self._solution.model.fault_sections_with_rupture_rates.copy()
    toc = time.perf_counter()
    log.debug('time to load fault_sections_with_rupture_rates: %2.3f seconds' % (toc - tic))
    rupt: gpd.DataFrame = df0[df0["Rupture Index"] == rupture_id]
    if self._solution.fault_regime == 'SUBDUCTION':
        return rupt.set_geometry([create_subduction_section_surface(section) for i, section in rupt.iterrows()])
    elif self._solution.fault_regime == 'CRUSTAL':
        return rupt.set_geometry([create_crustal_section_surface(section) for i, section in rupt.iterrows()])
    else:  # pragma: no cover
        raise RuntimeError(f'Unable to render rupture_surface for fault regime {self._solution.fault_regime}')

create_crustal_section_surface(section: gpd.GeoDataFrame) -> gpd.GeoDataFrame

Source code in solvis/solution/solution_surfaces_builder.py
37
38
39
40
def create_crustal_section_surface(section: gpd.GeoDataFrame) -> gpd.GeoDataFrame:
    return fault_surface_3d(
        section["geometry"], section["DipDir"], section["DipDeg"], section["UpDepth"], section["LowDepth"]
    )

create_subduction_section_surface(section: gpd.GeoDataFrame) -> gpd.GeoDataFrame

Source code in solvis/solution/solution_surfaces_builder.py
22
23
24
25
26
27
28
29
30
31
32
33
34
def create_subduction_section_surface(section: gpd.GeoDataFrame) -> gpd.GeoDataFrame:
    def calc_dip_dir(section: gpd.GeoDataFrame) -> float:
        assert isinstance(section.geometry, LineString), "Got an unhandled geometry type."
        flat_geom = LineString(get_coordinates(section.geometry))

        point_a = Point(reversed(flat_geom.coords[0]))
        point_b = Point(reversed(flat_geom.coords[-1]))

        return dip_direction(point_a, point_b)

    return create_surface(
        section["geometry"], calc_dip_dir(section), section["DipDeg"], section["UpDepth"], section["LowDepth"]
    )