Write your own corrections¶
Custom corrections can be registered with the correction factory when you need to test a site-specific or experimental correction without changing the built-in method list.
Built a correction that works well? Share it
The approach below registers a correction at runtime in your own analysis code. If your correction could be useful to others, consider contributing it to Neptoon so it can become part of the standard pipeline. See Develop with Neptoon.
Creating a custom correction¶
Extend the Correction base class, call super().__init__(), and implement apply():
import pandas as pd
from neptoon.corrections import Correction, CorrectionType
class NewIdeaForBiomass(Correction):
"""Example biomass correction that also uses relative humidity."""
def __init__(
self,
correction_type: CorrectionType = CorrectionType.CUSTOM,
correction_factor_column_name: str = "new_biomass_correction",
) -> None:
super().__init__(
correction_type=correction_type,
correction_factor_column_name=correction_factor_column_name,
)
self.humidity_column_name = "air_relative_humidity"
self.biomass_column_name = "site_biomass"
@staticmethod
def new_func(biomass: float, humidity: float) -> float:
if biomass == 0:
return 1.0
return 1 - ((biomass / humidity) / 1000)
def apply(
self,
data_frame: pd.DataFrame,
invalid_data_policy: str | None = None,
) -> pd.DataFrame:
data_frame[self.correction_factor_column_name] = data_frame.apply(
lambda row: self.new_func(
row[self.biomass_column_name],
row[self.humidity_column_name],
),
axis=1,
)
return data_frame
The older apply(self, data_frame) signature remains supported. New corrections should accept the optional invalid_data_policy argument so they can follow the same row-level error policy as built-in corrections.
Registration¶
Register the class, not an instance:
data_hub.correction_factory.register_custom_correction(
correction_type=CorrectionType.CUSTOM,
theory="my_new_idea",
correction_class=NewIdeaForBiomass,
)
data_hub.select_correction(
correction_type=CorrectionType.CUSTOM,
correction_theory="my_new_idea",
)
data_hub.correct_neutrons()
Theory names are stable lookup keys and must use lowercase snake_case.
What is validated¶
Registration fails immediately with an actionable error and hint when:
correction_typeis not aCorrectionTypemember;theoryis empty or is not lowercasesnake_case;- the supplied value is not a
Correctionsubclass; - the class is still abstract because
apply()is missing; - the constructor cannot be called as
MyCorrection(correction_type=...); - construction raises an exception;
- the instance reports a different
correction_typefrom the registered type; correction_factor_column_nameis missing, empty, non-string, or contains unsafe whitespace;apply()cannot be called with a pandasDataFrame.
Some checks require real data and therefore happen when the correction is first applied. Neptoon then verifies that apply() returns a pandas DataFrame and that it creates the declared correction-factor column.
For example, returning None produces an error that explains that the input DataFrame must be returned. Declaring correction_factor_column_name = "my_factor" without creating data_frame["my_factor"] produces an error pointing to the missing assignment.
Replacing a registration¶
Accidental replacement is rejected by default. Explicitly opt in when replacing a previously registered class is intentional: