GeneticWFM / src /utils /demand_processing.py
GaetanoParente's picture
first commit
9e62f55
import numpy as np
def align_demand_to_grid(raw_demand_row, current_config):
"""
Allinea la time-series della demand giornaliera alla griglia oraria di configurazione.
Gestisce dinamicamente truncation e padding in base a shift operativi di start/end.
"""
# Estrazione parametri di quantizzazione temporale
start_h = current_config['client_settings']['day_start_hour']
end_h = current_config['client_settings']['day_end_hour']
slot_min = current_config['client_settings']['planning_slot_minutes']
slots_per_day = int((end_h - start_h) * 60 / slot_min)
# Fallback strutturale per payload mancanti o corrotti
if not raw_demand_row:
return np.ones(slots_per_day, dtype=int)
# Early exit se la dimensionalità è già coerente con il setup
if len(raw_demand_row) == slots_per_day:
return np.array(raw_demand_row, dtype=int)
# --- RESHAPING PIPELINE ---
# Inizializzazione target array con baseline di staff (safety net = 1)
adjusted_demand = np.ones(slots_per_day, dtype=int)
# Euristica "Best Effort" per il mapping dei dati storici sulla nuova griglia.
# Assunto: invarianza del delta temporale (slot_min).
# TODO: In caso di mutazione della granularità (es. 15m -> 30m) serve un resampler/interpolatore.
limit = min(len(raw_demand_row), slots_per_day)
adjusted_demand[:limit] = raw_demand_row[:limit]
return adjusted_demand
def sanitize_weekly_demand(weekly_demand, current_config):
"""
Pipeline di sanitizzazione massiva per l'intera matrice settimanale.
Esegue stripping delle label testuali ed enforcing della consistenza dimensionale (7xN).
"""
sanitized = []
# Enforcing del vincolo a 7 giorni operativi
for i in range(7):
if i < len(weekly_demand):
row_data = weekly_demand[i]
# Stripping della label descrittiva se presente (es. "Giorno_0")
if isinstance(row_data[0], str):
row_vals = row_data[1:]
else:
row_vals = row_data
aligned = align_demand_to_grid(row_vals, current_config)
sanitized.append(aligned)
else:
# Imputazione di una curva flat di fallback per le giornate out-of-bounds
dummy = align_demand_to_grid([], current_config)
sanitized.append(dummy)
return sanitized