Source code for djura.slf.utilities
# SPDX-License-Identifier: AGPL-3.0-or-later
# Copyright (C) 2025-2026 Djura | Risk - Data - Engineering S.r.l.
import pandas as pd
from scipy.interpolate import interp1d
from ..utilities import ( # noqa: F401 (re-exported)
to_json_serializable, filter_args)
[docs]
def aggregate_values(row, columns, key):
return [row[col] for col in columns if key in col and
not pd.isnull(row[col])]
[docs]
def convert_inv(df: pd.DataFrame):
out = []
for _, row in df.iterrows():
median = aggregate_values(row, df.columns, "median-demand")
dispersion = aggregate_values(row, df.columns, "total-dispersion")
cost = aggregate_values(row, df.columns, "repair-cost")
cost_disp = aggregate_values(row, df.columns, "cost-dispersion")
best_fit = [row[col] for col in df.columns if "best-fit" in col]
out.append({
"id": row["id"],
"EDP": row["EDP"],
"Component": row["Component"],
"Group": row["Group"],
"Quantity": row["Quantity"],
"damage-states": row["damage-states"],
"median-demand": median,
"total-dispersion": dispersion,
"repair-cost": cost,
"cost-dispersion": cost_disp,
"best-fit": best_fit,
})
return out
[docs]
def convert_corr(df: pd.DataFrame):
out = []
for _, row in df.iterrows():
min_ds = aggregate_values(row, df.columns, "MIN DS")
out.append({
"ITEM": row["ITEM"],
"DEPENDANT ON ITEM": row["DEPENDANT ON ITEM"],
"MIN DS": min_ds,
})
return out
[docs]
def slf_aggregator(*args) -> list:
"""Aggregates input SLFs into a list supported by the loss assessment
module and creates interpolation functions for the EDP vs Loss
relationships
Each argument must have a specific structure::
{
'group name': {
'Directionality': null,
'Storey': null,
'edp': 'edp_name',
'edp_range': list(),
'slf': list()
}
}
"""
slfs = list()
for arg in args:
for group in arg.keys():
edp = arg[group]["edp"]
loss = arg[group]["slfs"]["mean"]
loss[loss < 0] = 0.0
interpolator = interp1d(edp, loss)
arg[group]["interpolator"] = interpolator
slfs.append(arg)
return slfs