Skip to content

Commit

Permalink
refactor!(settlement_measurement_rod): refator status and add status …
Browse files Browse the repository at this point in the history
…messages to SettlementRodMeasurement
  • Loading branch information
Pablo Vasconez committed Jul 3, 2024
1 parent 272888f commit 5f8fb22
Show file tree
Hide file tree
Showing 12 changed files with 849 additions and 630 deletions.
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Welcome to BAEC Model Generator SDK documentation!
=======================================
==================================================

The `baec` library is created by `CEMS BV <https://cemsbv.nl/>`_ .

Expand Down
17 changes: 16 additions & 1 deletion docs/tree/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,22 @@ Measured Settlement Series
:member-order: bysource

.. automethod:: __init__


.. _statusMessage:

Status Message
--------------

.. autoclass:: baec.measurements.settlement_rod_measurement.StatusMessage
:members:
:inherited-members:
:member-order: bysource

.. automethod:: __init__

.. autoenum:: baec.measurements.settlement_rod_measurement.StatusMessageLevel
:members:

.. _measurementDevice:

Measurement Device
Expand Down
71 changes: 56 additions & 15 deletions src/baec/measurements/io/zbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,68 @@
from baec.measurements.measurement_device import MeasurementDevice
from baec.measurements.settlement_rod_measurement import (
SettlementRodMeasurement,
SettlementRodMeasurementStatus,
StatusMessage,
StatusMessageLevel,
)
from baec.measurements.settlement_rod_measurement_series import (
SettlementRodMeasurementSeries,
)
from baec.project import Project

_STATUS_MAP = {
0: "ok",
1: "ok",
2: "disturbed",
3: "expired",
4: "relocated",
5: "rod_is_extended",
6: "crooked",
7: "deselected",
8: "deselected",
9: "fictional",
10: "unknown",
0: StatusMessage(code=0, description="OK", level=StatusMessageLevel.OK),
1: StatusMessage(code=1, description="OK", level=StatusMessageLevel.OK),
2: StatusMessage(code=2, description="Disturbed", level=StatusMessageLevel.WARNING),
3: StatusMessage(code=3, description="Expired", level=StatusMessageLevel.WARNING),
4: StatusMessage(code=4, description="Relocated", level=StatusMessageLevel.WARNING),
5: StatusMessage(
code=5, description="Rod is extended", level=StatusMessageLevel.INFO
),
6: StatusMessage(code=6, description="Crooked", level=StatusMessageLevel.WARNING),
7: StatusMessage(
code=7, description="Deselected", level=StatusMessageLevel.WARNING
),
8: StatusMessage(
code=8, description="Deselected", level=StatusMessageLevel.WARNING
),
9: StatusMessage(code=9, description="Fictional", level=StatusMessageLevel.WARNING),
}


def _zbase_status_to_message(status: int) -> StatusMessage:
"""
Convert a ZBase status code to a StatusMessage object.
If the status code is not recognized, a default StatusMessage object is returned
with level set to StatusMessageLevel.ERROR.
Parameters
----------
status : int
The ZBase status code.
Returns
-------
status_message : StatusMessage
The corresponding StatusMessage object.
Raises
------
TypeError
If status is not of type int.
"""
if not isinstance(status, int):
raise TypeError(f"status must be of type `int`, but got {type(status)}.")

status_message = _STATUS_MAP.get(status)
if status_message is None:
status_message = StatusMessage(
code=status,
description="Unrecognized status code",
level=StatusMessageLevel.ERROR,
)
return status_message


def measurements_from_zbase(
filepath_or_buffer: str | PathLike[str] | ReadCsvBuffer[bytes] | ReadCsvBuffer[str],
project_name: str,
Expand Down Expand Up @@ -98,6 +138,7 @@ def measurements_from_zbase(
# create SettlementRodMeasurement objects
measurements = []
for _, row in df.iterrows():
status = row.get("status")
measurements.append(
SettlementRodMeasurement(
project=Project(id_=id_, name=project_name),
Expand All @@ -113,9 +154,9 @@ def measurements_from_zbase(
rod_length=row.get("rod_top_z", 0) - row.get("rod_bottom_z", 0),
rod_bottom_z=row.get("rod_bottom_z", 0),
ground_surface_z=row.get("ground_surface_z", 0),
status=SettlementRodMeasurementStatus(
_STATUS_MAP.get(row.get("status", 10), "unknown")
),
status_messages=[]
if status is None
else [_zbase_status_to_message(status)],
)
)

Expand Down
32 changes: 32 additions & 0 deletions src/baec/measurements/measured_settlement.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import datetime
from functools import cache, cached_property
from typing import List

from baec.measurements.settlement_rod_measurement import (
SettlementRodMeasurement,
SettlementRodMeasurementStatus,
StatusMessage,
)
from baec.project import Project

Expand All @@ -29,6 +31,7 @@ def __init__(
horizontal_units: str,
vertical_units: str,
status: SettlementRodMeasurementStatus,
status_messages: List[StatusMessage],
) -> None:
"""
Initializes a MeasuredSettlement object.
Expand Down Expand Up @@ -63,6 +66,9 @@ def __init__(
status: SettlementRodMeasurementStatus
The status of the settlement rod measurement from which the measured settlement
is derived.
status_messages: List[StatusMessage]
The list of status messages about the settlement rod measurement from which the
measured settlement is derived.
Raises
------
Expand All @@ -86,6 +92,7 @@ def __init__(
self._set_horizontal_units(horizontal_units)
self._set_vertical_units(vertical_units)
self._set_status(status)
self._set_status_messages(status_messages)

@classmethod
def from_settlement_rod_measurement(
Expand Down Expand Up @@ -156,6 +163,7 @@ def from_settlement_rod_measurement(
horizontal_units=measurement.coordinate_reference_systems.horizontal_units,
vertical_units=measurement.coordinate_reference_systems.vertical_units,
status=measurement.status,
status_messages=measurement.status_messages,
)

def _set_project(self, value: Project) -> None:
Expand Down Expand Up @@ -274,6 +282,21 @@ def _set_status(self, value: SettlementRodMeasurementStatus) -> None:
)
self._status = value

def _set_status_messages(self, value: List[StatusMessage]) -> None:
"""
Private setter for status attribute.
"""
if not isinstance(value, list):
raise TypeError(
"Expected 'List[StatusMessage]' type for 'status_messages' attribute."
)
# Check if the input is a list of StatusMessage objects.
if not all(isinstance(item, StatusMessage) for item in value):
raise TypeError(
"Expected 'List[StatusMessage]' type for 'status_messages' attribute."
)
self._status_messages = value

@property
def project(self) -> Project:
"""
Expand Down Expand Up @@ -364,6 +387,14 @@ def status(self) -> SettlementRodMeasurementStatus:
"""
return self._status

@property
def status_messages(self) -> List[StatusMessage]:
"""
The list of status messages about the settlement rod measurement from which the
measured settlement is derived.
"""
return self._status_messages

@cache
def to_dict(self) -> dict:
"""
Expand All @@ -383,4 +414,5 @@ def to_dict(self) -> dict:
"horizontal_units": self.horizontal_units,
"vertical_units": self.vertical_units,
"status": self.status.value,
"status_messages": "\n".join([m.to_string() for m in self.status_messages]),
}
18 changes: 10 additions & 8 deletions src/baec/measurements/measured_settlement_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,18 +139,20 @@ def __init__(
If the `start_index` is out of range for the series.
"""

# Check the types of the input parameters.
if not isinstance(series, SettlementRodMeasurementSeries):
raise TypeError(
"Expected 'SettlementRodMeasurementSeries' type for 'series' parameter."
)

# set SettlementRodMeasurementSeries
self._series = series
self._set_series(series)

# set start of settlement
self._set_start_index_or_start_date_time(start_index, start_date_time)

def _set_series(self, value: SettlementRodMeasurementSeries) -> None:
"""Private setter for series attribute."""
if not isinstance(value, SettlementRodMeasurementSeries):
raise TypeError(
"Expected 'SettlementRodMeasurementSeries' type for 'series' attribute."
)
self._series = value

def _set_start_index_or_start_date_time(
self,
start_index: int | None = None,
Expand Down Expand Up @@ -438,7 +440,7 @@ def to_dataframe(self) -> pd.DataFrame:
A pandas DataFrame with the measured settlements. The columns of the DataFrame are:
project_id, project_name, object_id, start_date_time
date_time, days, fill_thickness, settlement, x_displacement, y_displacement
horizontal_units, vertical_units, status
horizontal_units, vertical_units, status, status_messages
"""
return pd.DataFrame.from_records(
[measurement.to_dict() for measurement in self.items]
Expand Down
Loading

0 comments on commit 5f8fb22

Please sign in to comment.