Skip to content

Commit

Permalink
Fix/add logging (#141)
Browse files Browse the repository at this point in the history
* Adding utils to get logger for file name and set logging levels

* adding logging calls to project/map_data for debugging

* fix: fault topology merge was using incorrect lookups

* adding logging to def history and m2l wrapper

* fix: run map2model for user defined stratigraphic column

* removing logger from this pr

* fix: use fault id not Fault_{id}

* adding more logging for config and mapdata

* logging for m2m inputs

* linting

* fix: missing label in structurepoint thickness calculator

* updating so tests pass

* only run builds on master

* remove Fault_ from table
  • Loading branch information
lachlangrose authored Nov 19, 2024
1 parent 5ebc07b commit e6aa3e9
Show file tree
Hide file tree
Showing 13 changed files with 279 additions and 76 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/CD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,6 @@ jobs:
release_created: ${{ steps.release-please.outputs.release_created }}
#if a release is created then run the deploy scripts for github.io, conda, pypi and docker



conda-upload:
needs: [release-please, conda-build]
runs-on: ${{matrix.os}}
Expand Down
2 changes: 1 addition & 1 deletion dependencies.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ beartype
gdal==3.8.4
hjson
pytest
scikit-learn
scikit-learn
7 changes: 7 additions & 0 deletions map2loop/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@

import logging
loggers = {}
ch = logging.StreamHandler()
formatter = logging.Formatter("%(levelname)s: %(asctime)s: %(filename)s:%(lineno)d -- %(message)s")
ch.setFormatter(formatter)
ch.setLevel(logging.WARNING)
from .project import Project
from .version import __version__
15 changes: 9 additions & 6 deletions map2loop/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import pathlib
from typing import Union

from .logging import getLogger

logger = getLogger(__name__)

class Config:
"""
Expand Down Expand Up @@ -97,28 +100,28 @@ def update_from_dictionary(self, dictionary: dict, lower: bool = False):
self.structure_config.update(dictionary["structure"])
for key in dictionary["structure"].keys():
if key not in self.structure_config:
print(f"Config dictionary structure segment contained {key} which is not used")
logger.warning(f"Config dictionary structure segment contained {key} which is not used")
dictionary.pop("structure")
if "geology" in dictionary:
self.geology_config.update(dictionary["geology"])
for key in dictionary["geology"].keys():
if key not in self.geology_config:
print(f"Config dictionary geology segment contained {key} which is not used")
logger.warning(f"Config dictionary geology segment contained {key} which is not used")
dictionary.pop("geology")
if "fault" in dictionary:
self.fault_config.update(dictionary["fault"])
for key in dictionary["fault"].keys():
if key not in self.fault_config:
print(f"Config dictionary fault segment contained {key} which is not used")
logger.warning(f"Config dictionary fault segment contained {key} which is not used")
dictionary.pop("fault")
if "fold" in dictionary:
self.fold_config.update(dictionary["fold"])
for key in dictionary["fold"].keys():
if key not in self.fold_config:
print(f"Config dictionary fold segment contained {key} which is not used")
logger.warning(f"Config dictionary fold segment contained {key} which is not used")
dictionary.pop("fold")
if len(dictionary):
print(f"Unused keys from config format {list(dictionary.keys())}")
logger.warning(f"Unused keys from config format {list(dictionary.keys())}")

@beartype.beartype
def update_from_legacy_file(self, file_map: dict, lower: bool = False):
Expand Down Expand Up @@ -178,7 +181,7 @@ def update_from_legacy_file(self, file_map: dict, lower: bool = False):
file_map.pop("o")

if len(file_map) > 0:
print(f"Unused keys from legacy format {list(file_map.keys())}")
logger.warning(f"Unused keys from legacy format {list(file_map.keys())}")

@beartype.beartype
def update_from_file(
Expand Down
41 changes: 30 additions & 11 deletions map2loop/deformation_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import geopandas
import math

from .logging import getLogger

logger = getLogger(__name__)

class DeformationHistory:
"""
Expand Down Expand Up @@ -90,6 +93,7 @@ def set_minimum_fault_length(self, length):
length (float or int):
The fault length cutoff
"""
logger.info(f"Setting minimum fault length to {length}")
self.minimum_fault_length_to_export = length

def get_minimum_fault_length(self):
Expand All @@ -113,11 +117,13 @@ def findfault(self, id):
pandas.DataFrame: The sliced data frame containing the requested fault
"""
if issubclass(type(id), int):
logger.info(f"Finding fault with eventId {id}")
return self.faults[self.faults["eventId"] == id]
elif issubclass(type(id), str):
logger.info(f"Finding fault with name {id}")
return self.faults[self.faults["name"] == id]
else:
print("ERROR: Unknown identifier type used to find fault")
logger.error("ERROR: Unknown identifier type used to find fault")

def findfold(self, id):
"""
Expand All @@ -131,11 +137,13 @@ def findfold(self, id):
pandas.DataFrame: The sliced data frame containing the requested fold
"""
if issubclass(type(id), int):
logger.info(f"Finding fold with eventId {id}")
return self.folds[self.folds["foldId"] == id]
elif issubclass(type(id), str):
logger.info(f"Finding fold with name {id}")
return self.folds[self.folds["name"] == id]
else:
print("ERROR: Unknown identifier type used to find fold")
logger.error("ERROR: Unknown identifier type used to find fold")

def addFault(self, fault):
"""
Expand All @@ -148,12 +156,13 @@ def addFault(self, fault):
if issubclass(type(fault), pandas.DataFrame) or issubclass(type(fault), dict):
if "name" in fault.keys():
if fault["name"] in self.faults.index:
print("Replacing fault", fault["name"])
logger.warning("Replacing fault", fault["name"])
self.faults[fault["name"]] = fault
logger.info("Adding fault", fault["name"])
else:
print("No name field in fault", fault)
logger.error("No name field in fault", fault)
else:
print("Cannot add fault to dataframe with type", type(fault))
logger.error("Cannot add fault to dataframe with type", type(fault))

def removeFaultByName(self, name: str):
"""
Expand All @@ -163,7 +172,8 @@ def removeFaultByName(self, name: str):
name (str):
The name of the fault(s) to remove
"""
self.faults = self.faults[self.faults["name"] != name].copy()
logger.info(f"Removing fault with name {name}")
self.faults = self.faults.drop[self.faults.index[self.faults["name"] != name]]

def removeFaultByEventId(self, eventId: int):
"""
Expand All @@ -173,6 +183,7 @@ def removeFaultByEventId(self, eventId: int):
eventId (int):
The eventId of the fault to remove
"""
logger.info(f"Removing fault with eventId {eventId}")
self.faults = self.faults[self.faults["eventId"] != eventId].copy()

def addFold(self, fold):
Expand All @@ -186,12 +197,13 @@ def addFold(self, fold):
if issubclass(type(fold), pandas.DataFrame) or issubclass(type(fold), dict):
if "name" in fold.keys():
if fold["name"] in self.folds.index:
print("Replacing fold", fold["name"])
logger.warning("Replacing fold", fold["name"])
logger.info("Adding fold", fold["name"])
self.folds[fold["name"]] = fold
else:
print("No name field in fold", fold)
logger.error("No name field in fold", fold)
else:
print("Cannot add fold to dataframe with type", type(fold))
logger.error("Cannot add fold to dataframe with type", type(fold))

@beartype.beartype
def populate(self, faults_map_data: geopandas.GeoDataFrame):
Expand All @@ -202,6 +214,7 @@ def populate(self, faults_map_data: geopandas.GeoDataFrame):
faults_map_data (geopandas.GeoDataFrame):
The parsed data frame from the map
"""
logger.info("Populating fault/fold summary")
if faults_map_data.shape[0] == 0:
return
faults_data = faults_map_data.copy()
Expand Down Expand Up @@ -251,6 +264,7 @@ def summarise_data(self, fault_observations: pandas.DataFrame):
fault_observations (pandas.DataFrame):
The fault observations data
"""
logger.info("Summarising fault data")
id_list = self.faults["eventId"].unique()
for id in id_list:
observations = fault_observations[fault_observations["ID"] == id]
Expand All @@ -272,6 +286,7 @@ def get_faults_for_export(self):
Returns:
pandas.DataFrame: The filtered fault summary
"""
logger.info("Getting faults for export")
return self.faults[self.faults["length"] >= self.minimum_fault_length_to_export].copy()

@beartype.beartype
Expand All @@ -285,12 +300,16 @@ def get_fault_relationships_with_ids(self, fault_fault_relationships: pandas.Dat
Returns:
pandas.DataFrame: The fault_relationships with the correct eventIds
"""
logger.info("Getting fault relationships with eventIds")
faultIds = self.get_faults_for_export()[["eventId", "name"]].copy()
rel = fault_fault_relationships.copy()
rel = rel.merge(faultIds, left_on="Fault1", right_on="name")
rel['Fault1'] = rel['Fault1'].astype(str)
rel['Fault2'] = rel['Fault2'].astype(str)
faultIds['eventId'] = faultIds['eventId'].astype(str)
rel = rel.merge(faultIds, left_on="Fault1", right_on="eventId")
rel.rename(columns={"eventId": "eventId1"}, inplace=True)
rel.drop(columns=["name"], inplace=True)
rel = rel.merge(faultIds, left_on="Fault2", right_on="name")
rel = rel.merge(faultIds, left_on="Fault2", right_on="eventId")
rel.rename(columns={"eventId": "eventId2"}, inplace=True)
rel.drop(columns=["name"], inplace=True)
return rel
5 changes: 5 additions & 0 deletions map2loop/fault_orientation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
from .mapdata import MapData
import numpy as np

from .logging import getLogger

logger = getLogger(__name__)
class FaultOrientation(ABC):
"""
Base Class of Fault Orientation assigner to force structure of FaultOrientation
Expand Down Expand Up @@ -80,7 +82,10 @@ def calculate(
Returns:
pandas.DataFrame: fault orientations assigned to a fault label
"""
logger.info("Assigning fault orientations to fault traces from nearest orientation")
orientations = fault_orientations.copy()
logger.info(f'There are {len(orientations)} fault orientations to assign')

orientations["ID"] = -1

for i in orientations.index:
Expand Down
57 changes: 57 additions & 0 deletions map2loop/logging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import logging
import map2loop
def get_levels():
"""dict for converting to logger levels from string
Returns
-------
dict
contains all strings with corresponding logging levels.
"""
return {
"info": logging.INFO,
"warning": logging.WARNING,
"error": logging.ERROR,
"debug": logging.DEBUG,
}

def getLogger(name:str):
"""Get a logger object with a specific name
Parameters
----------
name : str
name of the logger object
Returns
-------
logging.Logger
logger object
"""
if name in map2loop.loggers:
return map2loop.loggers[name]
logger = logging.getLogger(name)
logger.addHandler(map2loop.ch)
logger.propagate = False
map2loop.loggers[name] = logger
return logger
logger = getLogger(__name__)
def set_level(level:str):
"""Set the level of the logging object
Parameters
----------
level : str
level of the logging object
"""
levels = get_levels()
level = levels.get(level, logging.WARNING)
map2loop.ch.setLevel(level)

for name in map2loop.loggers:
logger = logging.getLogger(name)
logger.setLevel(level)
logger.info(f"Logging level set to {level}")
Loading

0 comments on commit e6aa3e9

Please sign in to comment.