From 75bbbb83e531484a92aa9d14dd7c27fc5aab5196 Mon Sep 17 00:00:00 2001 From: Nicolas Schmid Date: Tue, 3 Sep 2024 11:35:42 +0200 Subject: [PATCH] fix: catalog serialization-deserialization handling NaNs --- seismostats/catalogs/catalog.py | 2 +- .../catalogs/catalog_templates/quakeml.j2 | 20 +++++----- seismostats/utils/__init__.py | 39 +++++++++++-------- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/seismostats/catalogs/catalog.py b/seismostats/catalogs/catalog.py index 30d4a16..0d6e4a1 100644 --- a/seismostats/catalogs/catalog.py +++ b/seismostats/catalogs/catalog.py @@ -187,7 +187,7 @@ def from_dict(cls, for num in numeric_cols: if num in df.columns: - df[num] = pd.to_numeric(df[num]) + df[num] = pd.to_numeric(df[num], errors='coerce') if 'time' in df.columns: df['time'] = pd.to_datetime(df['time']).dt.tz_localize(None) diff --git a/seismostats/catalogs/catalog_templates/quakeml.j2 b/seismostats/catalogs/catalog_templates/quakeml.j2 index 21a1e91..6f96a63 100644 --- a/seismostats/catalogs/catalog_templates/quakeml.j2 +++ b/seismostats/catalogs/catalog_templates/quakeml.j2 @@ -14,8 +14,8 @@ {{ author }} - {{ event.magnitude }} - {{ event.magnitude_uncertainty }} + {{ event.magnitude if not event.magnitude is nan else ''}} + {{ event.magnitude_uncertainty if not event.magnitude_uncertainty is nan else '' }} {{ event.magnitude_type }} {{ event.originid }} @@ -28,8 +28,8 @@ {{ author }} - {{ magnitude.magnitude }} - {{ magnitude.magnitude_uncertainty }} + {{ magnitude.magnitude if not magnitude.magnitude is nan else ''}} + {{ magnitude.magnitude_uncertainty if not magnitude.magnitude_uncertainty is nan else ''}} {{ type }} {{ event.originid }} @@ -41,12 +41,12 @@ {{ event.time.strftime('%Y-%m-%dT%H:%M:%S.%fZ') }} - {{ event.longitude }} - {{ event.longitude_uncertainty }} + {{ event.longitude if not event.longitude is nan else ''}} + {{ event.longitude_uncertainty if not event.longitude_uncertainty is nan else ''}} - {{ event.latitude }} - {{ event.latitude_uncertainty }} + {{ event.latitude if not event.latitude is nan else ''}} + {{ event.latitude_uncertainty if not event.latitude_uncertainty is nan else '' }} {{ event.evaluationmode }} @@ -54,8 +54,8 @@ {{ author }} - {{ event.depth }} - {{ event.depth_uncertainty }} + {{ event.depth if not event.depth is nan else ''}} + {{ event.depth_uncertainty if not event.depth_uncertainty is nan else '' }} diff --git a/seismostats/utils/__init__.py b/seismostats/utils/__init__.py index 8a9e24c..761d832 100644 --- a/seismostats/utils/__init__.py +++ b/seismostats/utils/__init__.py @@ -1,22 +1,17 @@ import functools +import math import pandas as pd -from jinja2 import Template, select_autoescape -from seismostats.utils.binning import ( # noqa - bin_to_precision, - get_cum_fmd, - get_fmd, -) -from seismostats.utils.simulate_distributions import ( # noqa - simulate_magnitudes, - simulate_magnitudes_binned, -) +from jinja2 import Environment, FileSystemLoader, select_autoescape + +from seismostats.utils.binning import (bin_to_precision, get_cum_fmd, # noqa + get_fmd) +from seismostats.utils.coordinates import CoordinateTransformer # noqa +from seismostats.utils.coordinates import (bounding_box_to_polygon, # noqa + polygon_to_bounding_box) from seismostats.utils.filtering import cat_intersect_polygon # noqa -from seismostats.utils.coordinates import ( # noqa - CoordinateTransformer, - bounding_box_to_polygon, - polygon_to_bounding_box, -) +from seismostats.utils.simulate_distributions import ( # noqa + simulate_magnitudes, simulate_magnitudes_binned) def _check_required_cols(df: pd.DataFrame, required_cols: list[str]): @@ -75,9 +70,19 @@ def wrapper_require(self, *args, **kwargs): return decorator_require(_func) +def is_nan(value): + return isinstance(value, float) and math.isnan(value) + + def _render_template(data: dict, template_path: str) -> str: - with open(template_path) as t: - template = Template(t.read(), autoescape=select_autoescape()) + + env = Environment( + loader=FileSystemLoader('/'), # Base directory for templates + autoescape=select_autoescape() + ) + env.tests['nan'] = is_nan + + template = env.get_template(template_path) qml = template.render(**data) return qml