From 2fdd6e0de0b1fdf1d4214e36f40cbfc28511c245 Mon Sep 17 00:00:00 2001
From: "E. Joshua Rigler" <erigler@usgs.gov>
Date: Mon, 17 Mar 2025 15:59:42 -0600
Subject: [PATCH] Minor future-proofing fixes:

Create and use default Absolute class/module values, rather than hard-coding `shift` or `valid` values
---
 geomagio/residual/Absolute.py    |  7 +++++--
 geomagio/residual/Calculation.py | 26 +++++++++++++++++++-------
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/geomagio/residual/Absolute.py b/geomagio/residual/Absolute.py
index 1339ad5f..ebdf59da 100644
--- a/geomagio/residual/Absolute.py
+++ b/geomagio/residual/Absolute.py
@@ -4,6 +4,9 @@ from obspy import UTCDateTime
 from pydantic import BaseModel
 from ..pydantic_utcdatetime import CustomUTCDateTimeType
 
+AbsoluteShiftDefault = 0
+AbsoluteValidDefault = True
+
 
 class Absolute(BaseModel):
     """Computed absolute and baseline measurement.
@@ -27,8 +30,8 @@ class Absolute(BaseModel):
     starttime: Optional[CustomUTCDateTimeType] = None
     endtime: Optional[CustomUTCDateTimeType] = None
 
-    shift: float = 0
-    valid: bool = True
+    shift: float = AbsoluteShiftDefault
+    valid: bool = AbsoluteValidDefault
 
     def is_valid(self) -> bool:
         return (
diff --git a/geomagio/residual/Calculation.py b/geomagio/residual/Calculation.py
index 6c415f0b..d74225c3 100644
--- a/geomagio/residual/Calculation.py
+++ b/geomagio/residual/Calculation.py
@@ -2,7 +2,7 @@ from typing import List, Literal, Tuple
 
 import numpy as np
 
-from .Absolute import Absolute
+from .Absolute import Absolute, AbsoluteShiftDefault, AbsoluteValidDefault
 from .MeasurementType import (
     MeasurementType as mt,
     DECLINATION_TYPES,
@@ -59,7 +59,7 @@ def calculate(reading: Reading, adjust_reference: bool = True) -> Reading:
         h_baseline=absoluteH.baseline,
         measurements=reading.measurements,
         reference=reference,
-        shift=reading.absolutes[0].shift if reading.absolutes else 0,
+        shift=reading.absolutes[0].shift if reading.absolutes else AbsoluteShiftDefault,
     )
 
     d_computed = calculate_D_computed(
@@ -130,10 +130,22 @@ def calculate(reading: Reading, adjust_reference: bool = True) -> Reading:
     )
 
     # just persist Absolute.valid if passed to calculate
-    if reading.absolutes:
-        absoluteD.valid = reading.absolutes[0].valid
-        absoluteH.valid = reading.absolutes[1].valid
-        absoluteZ.valid = reading.absolutes[2].valid
+    if hasattr(reading.absolutes, "__iter__") and len(reading.absolutes) == 3:
+        absoluteD.valid = (
+            reading.absolutes[0].valid
+            if hasattr(reading.absolutes[0], "valid")
+            else AbsoluteValidDefault
+        )
+        absoluteH.valid = (
+            reading.absolutes[1].valid
+            if hasattr(reading.absolutes[1], "valid")
+            else AbsoluteValidDefault
+        )
+        absoluteZ.valid = (
+            reading.absolutes[2].valid
+            if hasattr(reading.absolutes[2], "valid")
+            else AbsoluteValidDefault
+        )
 
     # create new reading object
     calculated = Reading(
@@ -152,7 +164,7 @@ def calculate_D_absolute(
     azimuth: float,
     h_baseline: float,
     reference: Measurement,
-    shift: float = 0,
+    shift: float = AbsoluteShiftDefault,
 ) -> Tuple[Absolute, Diagnostics]:
     """Calculate D absolute.
 
-- 
GitLab