Skip to content

Commit

Permalink
Feature/multiple coruptures (#37)
Browse files Browse the repository at this point in the history
* added list support for corupture queries;
* update changelog;
* detox;
  • Loading branch information
chrisbc authored Jul 4, 2023
1 parent e273859 commit 55e69b9
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 132 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## [0.8.2] - 2023-07-04

### Changed
- added list support for corupture queries

## [0.8.1] - 2023-07-03

### Changed
Expand Down
216 changes: 102 additions & 114 deletions poetry.lock

Large diffs are not rendered by default.

54 changes: 42 additions & 12 deletions solvis_graphql_api/composite_solution/cached.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import time
from functools import lru_cache
from pathlib import Path
from typing import Callable, Iterable, Iterator, List, Tuple, Union
from typing import Callable, Iterable, Iterator, List, Set, Tuple, Union

import geopandas as gpd
import nzshm_model
Expand Down Expand Up @@ -93,6 +93,11 @@ def get_fss(slt, fault_system):
return get_rupture_ids(rupture_set_id=rupture_set_id, locations=location_ids, radius=radius_km, union=union)


@lru_cache
def get_rupture_ids_for_parent_fault(fault_system_solution: InversionSolutionProtocol, fault_name: str) -> Set[int]:
return set(fault_system_solution.get_ruptures_for_parent_fault(fault_name))


@lru_cache
def matched_rupture_sections_gdf(
model_id: str,
Expand All @@ -104,17 +109,20 @@ def matched_rupture_sections_gdf(
min_mag: float,
max_mag: float,
union: bool = False,
corupture_parent_fault_name: str = "",
corupture_fault_names: Union[None, Tuple[str]] = None,
) -> gpd.GeoDataFrame:
"""
Query the solvis.CompositeSolution instance identified by model ID.
return a dataframe of the matched ruptures.
"""

tic0 = time.perf_counter()
composite_solution = get_composite_solution(model_id)

fss = composite_solution._solutions[fault_system]
tic1 = time.perf_counter()
log.debug('matched_rupture_sections_gdf(): time to load fault system solution: %2.3f seconds' % (tic1 - tic0))

df0 = fss.ruptures_with_rates

# attribute filters
Expand All @@ -123,21 +131,43 @@ def matched_rupture_sections_gdf(
df0 = df0 if not max_rate else df0[df0.rate_weighted_mean <= max_rate]
df0 = df0 if not min_rate else df0[df0.rate_weighted_mean > min_rate]

tic2 = time.perf_counter()
log.debug('matched_rupture_sections_gdf(): time apply attribute filters: %2.3f seconds' % (tic2 - tic1))

# co-rupture filter
if corupture_parent_fault_name and len(corupture_parent_fault_name):
rupture_ids = list(fss.get_ruptures_for_parent_fault(corupture_parent_fault_name))
df0 = df0[df0["Rupture Index"].isin(rupture_ids)]
if corupture_fault_names and len(corupture_fault_names):
first = True
rupture_ids: Set[int]
for fault_name in corupture_fault_names:
if fault_name not in parent_fault_names(fss):
raise ValueError("Invalid fault name: %s" % fault_name)
tic22 = time.perf_counter()
fault_rupture_ids = get_rupture_ids_for_parent_fault(fss, fault_name)
tic23 = time.perf_counter()
log.debug('fss.get_ruptures_for_parent_fault %s: %2.3f seconds' % (fault_name, (tic23 - tic22)))

if first:
rupture_ids = fault_rupture_ids
first = False
else:
rupture_ids = rupture_ids.intersection(fault_rupture_ids)

df0 = df0[df0["Rupture Index"].isin(list(rupture_ids))]

tic3 = time.perf_counter()
log.debug('matched_rupture_sections_gdf(): time apply co-rupture filter: %2.3f seconds' % (tic3 - tic2))

# location filters
if location_ids is not None and len(location_ids):
if RESOLVE_LOCATIONS_INTERNALLY:
df0 = filter_dataframe_by_radius(fss, df0, location_ids, radius_km)
else:
rupture_ids = list(
filter_dataframe_by_radius_stored(model_id, fault_system, df0, location_ids, radius_km, union)
)
rupture_ids = set(filter_dataframe_by_radius_stored(model_id, fault_system, df0, location_ids, radius_km, union))
df0 = df0[df0["Rupture Index"].isin(rupture_ids)]

tic4 = time.perf_counter()
log.debug('matched_rupture_sections_gdf(): time apply location filters: %2.3f seconds' % (tic4 - tic3))

return df0


Expand All @@ -153,7 +183,7 @@ def fault_section_aggregates_gdf(
max_mag: float,
union: bool = False,
trace_only: bool = False,
corupture_parent_fault_name: str = "",
corupture_fault_names: Union[None, Tuple[str]] = None,
) -> gpd.GeoDataFrame:

tic0 = time.perf_counter()
Expand All @@ -173,11 +203,11 @@ def fault_section_aggregates_gdf(
min_mag,
max_mag,
union,
corupture_parent_fault_name,
corupture_fault_names,
)

tic2 = time.perf_counter()
log.debug('fault_section_aggregates_gdf(): time to filter rutpure sections: %2.3f seconds' % (tic2 - tic1))
log.debug('fault_section_aggregates_gdf(): time to filter rupture sections: %2.3f seconds' % (tic2 - tic1))

fsr = fss.fault_sections_with_rates
fsr = fsr[fsr['Rupture Index'].isin(df0['Rupture Index'].unique())]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def get_fault_section_aggregates(filter_args, trace_only=False):
max_mag=filter_args.maximum_mag,
union=False,
trace_only=trace_only,
corupture_parent_fault_name=filter_args.corupture_parent_fault_name,
corupture_fault_names=tuple(filter_args.corupture_fault_names),
)


Expand Down Expand Up @@ -132,7 +132,8 @@ def resolve_mfd_histogram(root, info, *args, **kwargs):
min_mag=filter_args.minimum_mag,
max_mag=filter_args.maximum_mag,
union=False,
corupture_parent_fault_name=filter_args.corupture_parent_fault_name,
corupture_fault_names=tuple(filter_args.corupture_fault_names),
# corupture_parent_fault_name=filter_args.corupture_parent_fault_name,
)

# TODO - move this function into solvis (see solvis.mfd_hist)
Expand Down
6 changes: 4 additions & 2 deletions solvis_graphql_api/composite_solution/composite_solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ class FilterRupturesArgsBase:
description="The fault systems [`HIK`, `PUY`, `CRU`]",
)

corupture_parent_fault_name = graphene.String(
corupture_fault_names = graphene.List(
graphene.String,
required=False,
description="The name of parent fault may be supplied to restrict to ruptures that include parent "
default_value=[],
description="Optional list of parent fault names. Result will only include ruptures that include parent "
"fault sections",
)

Expand Down
2 changes: 1 addition & 1 deletion solvis_graphql_api/composite_solution/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def paginated_filtered_ruptures(filter_args, sortby_args, **kwargs) -> RuptureDe
min_mag=filter_args.get('minimum_mag'),
max_mag=filter_args.get('maximum_mag'),
union=False,
corupture_parent_fault_name=filter_args.corupture_parent_fault_name,
corupture_fault_names=tuple(filter_args.corupture_fault_names),
)

if sortby_args:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_composite_corupture_sections.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
filter_rupture_sections(
filter:{
model_id: "NSHM_v1.0.4",
corupture_parent_fault_name: "Masterton",
corupture_fault_names: ["Masterton"],
location_ids: [],
fault_system: "CRU",
radius_km: 100
Expand Down

0 comments on commit 55e69b9

Please sign in to comment.