Skip to content

Commit

Permalink
Merge branch 'main' into feature/beta2b_and_warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
aronsho committed Jun 5, 2024
2 parents 043f72f + 008d7d6 commit a2f0dd9
Show file tree
Hide file tree
Showing 12 changed files with 193 additions and 59 deletions.
10 changes: 0 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,3 @@ pip install git+https://github.com/swiss-seismological-service/SeismoStats.git@f
# update it once the repo has changed:
pip install --force-reinstall git+https://github.com/swiss-seismological-service/SeismoStats.git
```

## Problems with geos

```
1. geos_c.h not found
Solutions (Mac):
brew install geos
Solutions:
sudo apt-get libgeos-dev
```
4 changes: 2 additions & 2 deletions docs/source/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ User Guide <user/index>
API reference <reference/index>
```

# Seismo Stats
# SeismoStats

Measure your seismicity with **SeismoStats**, a Python package for seismicity analysis.
Analyse your seismic catalogues with **SeismoStats**, a Python package for seismicity analysis.

Check out the {doc}`user/usage` section for further information, or the {doc}`reference/index` for a technical reference.

Expand Down
1 change: 1 addition & 0 deletions docs/source/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ catalog
config
plots
analysis
utils
```
54 changes: 54 additions & 0 deletions docs/source/reference/utils.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Utils

```{eval-rst}
.. currentmodule:: seismostats
```

## Binning

```{eval-rst}
.. autosummary::
:toctree: api/
bin_to_precision
utils.get_fmd
utils.get_cum_fmd
```

## Synthetic Magnitude Distributions

```{eval-rst}
.. autosummary::
:toctree: api/
utils.simulate_magnitudes
utils.simulated_magnitudes_binned
```

## Coordinates

```{eval-rst}
.. autosummary::
:toctree: api/
utils.CoordinateTransformer
[//]: <> utils.CoordinateTransformer.to_local_coords
[//]: <> utils.CoordinateTransformer.from_local_coords
[//]: <> utils.CoordinateTransformer.polygon_from_local_coords
[//]: <> utils.CoordinateTransformer.polygon_to_local_coords
utils.bounding_box_to_polygon
utils.polygon_to_bounding_box
```

## Spatial Filtering

```{eval-rst}
.. autosummary::
:toctree: api/
utils.cat_intersect_polygon
```
35 changes: 35 additions & 0 deletions docs/source/user/getting_started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Getting started

`Seismostats` is a Python library but doesn't require extensive knowledge of Python. The statistical analysis of a catalog can be achieved easily without any coding expertise by following the step by step guide ({doc}`examples`).

## Required packages and libraries

We didn't reinvent the wheel and rely on existing libraries and packages to perform basic routines.

### GEOS
The plotting of the seismicity requires [GEOS](https://libgeos.org/), a C/C++ library for computational geometry. If `GEOS` is not installed on your machine, you will need to get it, for example on a linux machine with
```terminal
sudo apt-get libgeos-dev
```
or on a mac with
```terminal
brew install geos
```

## Using SeismoStats in another code

### Install from source
This way of installing `SeismoStats` in another environement allows you to use the static version.
```terminal
pip install git+https://github.com/swiss-seismological-service/SeismoStats.git
```

If you want to install a specific branch:
```terminal
pip install git+https://github.com/swiss-seismological-service/SeismoStats.git@feature/branch
```

To update your environment to the latest version of `SeismoStats`:
```terminal
pip install --force-reinstall git+https://github.com/swiss-seismological-service/SeismoStats.git
```
2 changes: 2 additions & 0 deletions docs/source/user/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
```{toctree}
:maxdepth: 2
what_is_seismostats
getting_started
usage
docs
```
5 changes: 5 additions & 0 deletions docs/source/user/what_is_seismostats.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# What is SeismoStats?

SeismoStats is a python library for statistical analysis of seismicity. The library provides a {doc}`../reference/catalog` object, as well as routines to compute the statistical parameters as well as plot the seismicity catalogs and their statistical features.

This library aims to provide a user friendly way to analyse seismic catalogs, with reliable and documented methods.
9 changes: 9 additions & 0 deletions seismostats/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

import pandas as pd
from jinja2 import Template, select_autoescape
from seismostats.utils.binning import (bin_to_precision, # noqa
get_cum_fmd,
get_fmd)
from seismostats.utils.simulate_distributions import ( # noqa
simulate_magnitudes, simulated_magnitudes_binned)
from seismostats.utils.filtering import cat_intersect_polygon # noqa
from seismostats.utils.coordinates import (CoordinateTransformer, # noqa
bounding_box_to_polygon,
polygon_to_bounding_box)


def _check_required_cols(df: pd.DataFrame,
Expand Down
28 changes: 15 additions & 13 deletions seismostats/utils/binning.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def normal_round_to_int(x: float) -> int:

def normal_round(x: float, n: int = 0) -> float:
"""
Rounds a float number x to n number of decimals. If the number
Rounds a float number ``x`` to n number of decimals. If the number
of decimals is not given, we round to an integer.
Args:
Expand All @@ -40,11 +40,11 @@ def normal_round(x: float, n: int = 0) -> float:

def bin_to_precision(x: np.ndarray | list, delta_x: float = 0.1) -> np.ndarray:
"""
Rounds a float number x to a given precision. If precision not given,
assumes 0.1 bin size
Rounds float numbers within the array ``x`` to a given precision. If
precision not given, assumes ``delta_x = 0.1``.
Args:
x: decimal number that needs to be rounded
x: list of decimal numbers that needs to be rounded
delta_x: size of the bin, optional
Returns:
Expand All @@ -63,9 +63,10 @@ def bin_to_precision(x: np.ndarray | list, delta_x: float = 0.1) -> np.ndarray:
def get_fmd(
mags: np.ndarray, delta_m: float, bin_position: str = "center"
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
"""Calculates event counts per magnitude bin. Note that the returned bins
array contains the center point of each bin unless bin_position is
'left'.
"""
Calculates event counts per magnitude bin. Note that the returned bins
array contains the center point of each bin unless
``bin_position = 'left'``.
Args:
mags : array of magnitudes
Expand All @@ -75,8 +76,8 @@ def get_fmd(
returned.
Returns:
bins : array of bin centers (left to right)
counts : counts for each bin ("")
mags : array of magnitudes binned to delta_m
counts : counts for each bin
mags : array of magnitudes binned to ``delta_m``
"""
mags = bin_to_precision(mags, delta_m)
mags_i = bin_to_precision(mags / delta_m - np.min(mags / delta_m), 1)
Expand Down Expand Up @@ -105,9 +106,10 @@ def get_fmd(
def get_cum_fmd(
mags: np.ndarray, delta_m: float, bin_position: str = "center"
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
"""Calculates cumulative event counts across all magnitude units
"""
Calculates cumulative event counts across all magnitude units
(summed from the right). Note that the returned bins array contains
the center point of each bin unless left is True.
the center point of each bin unless ``bin_position = 'left'``.
Args:
mags : array of magnitudes
Expand All @@ -118,8 +120,8 @@ def get_cum_fmd(
Returns:
bins : array of bin centers (left to right)
c_counts: cumulative counts for each bin ("")
mags : array of magnitudes binned to delta_m
c_counts: cumulative counts for each bin
mags : array of magnitudes binned to ``delta_m``
"""

if delta_m == 0:
Expand Down
71 changes: 54 additions & 17 deletions seismostats/utils/coordinates.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class CoordinateTransformer:
Class to transform between a external geographic (default ESPG:4326,
also known as WGS84), and a local cartesian CRS.
Any EPSG code or proj4 string can be used for the local_proj input,
Any EPSG code or proj4 string can be used for the ``local_proj`` input,
for instance 2056 to represent the swiss coordinate system, or
"+proj=utm +zone=32 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"
to represent a UTM coordinate system.
Expand All @@ -30,12 +30,12 @@ def __init__(
external_proj: int | str = 4326):
"""
Constructor of CoordinateTransformer object.
:param local_proj: int (epsg) or string (proj) of local CRS.
:param ref_easting: reference easting for local coordinates.
:param ref_northing: reference northing for local coordinates.
:param ref_altitude: reference altitude for local coordinates.
:param external_proj: int or string of geographic coordinates.
Args:
local_proj: int (epsg) or string (proj) of local CRS.
ref_easting: reference easting for local coordinates.
ref_northing: reference northing for local coordinates.
ref_altitude: reference altitude for local coordinates.
external_proj: int or string of geographic coordinates.
"""
self.ref_easting = ref_easting
self.ref_northing = ref_northing
Expand All @@ -55,10 +55,13 @@ def to_local_coords(self,
"""
Transform geographic coordinates to local coordinates.
:param lon: longitude
:param lat: latitude
:param altitude: altitude
:returns: Easting, northing and altitude in local CRS relative to ref.
Args:
lon: longitude
lat: latitude
altitude: altitude
Returns:
Easting, northing and altitude in local CRS relative to ref.
"""
enu = \
self.transformer_to_local.transform(lon, lat, altitude)
Expand All @@ -80,10 +83,13 @@ def from_local_coords(
"""
Transform local coordinates to geographic coordinates.
:param easting: easting
:param northing: northing
:param altitude: altitude
:returns: longitude, latitude, altitude in local CRS relative to ref.
Args:
easting: easting
northing: northing
altitude: altitude
Returns:
longitude, latitude, altitude in local CRS relative to ref.
"""
easting_0 = np.array(easting) + self.ref_easting
northing_0 = np.array(northing) + self.ref_northing
Expand All @@ -103,7 +109,13 @@ def from_local_coords(

def polygon_to_local_coords(self, polygon: Polygon) -> Polygon:
"""
Transform polygon to local coordinates.
Transform polygon from geographic coordinates to local coordinates.
Args:
polygon: shapely polygon
Returns:
shapely polygon in local coordinates
"""
new_polygon = transform(
self.transformer_to_local.transform, polygon)
Expand All @@ -114,7 +126,13 @@ def polygon_to_local_coords(self, polygon: Polygon) -> Polygon:

def polygon_from_local_coords(self, polygon: Polygon) -> Polygon:
"""
Transform polygon to local coordinates.
Transform polygon from local coordinates to geographic coordinates.
Args:
polygon: shapely polygon
Returns:
shapely polygon in geographic coordinates
"""
translated_polygon = translate(
polygon, xoff=self.ref_easting,
Expand All @@ -125,12 +143,31 @@ def polygon_from_local_coords(self, polygon: Polygon) -> Polygon:


def bounding_box_to_polygon(x_min, x_max, y_min, y_max, srid=None) -> Polygon:
"""
Create a shapely Polygon from a bounding box.
Args:
x_min: minimum x coordinate
x_max: maximum x coordinate
y_min: minimum y coordinate
y_max: maximum y coordinate
srid: spatial reference system identifier
"""
bbox = (x_min, y_min,
x_max, y_max)
return geometry.box(*bbox, ccw=True)


def polygon_to_bounding_box(polygon: Polygon) -> \
tuple[float, float, float, float]:
"""
Get the bounding box of a Polygon.
Args:
polygon: shapely Polygon
Returns:
tuple: The corner coordinates of the Polygon
"""
(minx, miny, maxx, maxy) = polygon.bounds
return (minx, miny, maxx, maxy)
18 changes: 7 additions & 11 deletions seismostats/utils/filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,17 @@

def cat_intersect_polygon(cat: pd.DataFrame, polygon_vertices: list[tuple]
) -> pd.DataFrame:
"""Returns a DataFrame containing
only the rows with points inside a given polygon.
"""
Returns a DataFrame containing only the rows with points inside a given
polygon.
Args:
-----------
cat : pandas.DataFrame
DataFrame with columns 'latitude' and 'longitude'
containing the points to be checked.
polygon_vertices : list of tuples
List of (x, y) tuples representing
the vertices of the polygon to be checked against.
cat : DataFrame with columns 'latitude' and 'longitude' containing the
points to be checked.
polygon_vertices : List of (x, y) tuples representing
the vertices of the polygon to be checked against.
Returns:
--------
pandas.DataFrame
DataFrame containing only the rows with points inside the polygon.
"""
Expand Down
Loading

0 comments on commit a2f0dd9

Please sign in to comment.