@sh.add_function(
dsp, inputs_kwargs=True, outputs=['kco2_wltp_correction_factor']
)
def identify_kco2_wltp_correction_factor(
drive_battery_electric_powers, service_battery_electric_powers,
co2_emissions, times, force_on_engine, after_treatment_warm_up_phases,
velocities, is_hybrid=True):
"""
Identifies the kco2 correction factor [g/Wh].
:param drive_battery_electric_powers:
Drive battery electric power [kW].
:type drive_battery_electric_powers: numpy.array
:param service_battery_electric_powers:
Service battery electric power [kW].
:type service_battery_electric_powers: numpy.array
:param force_on_engine:
Phases when engine is on because parallel mode is forced [-].
:type force_on_engine: numpy.array
:param after_treatment_warm_up_phases:
Phases when engine speed is affected by the after treatment warm up [-].
:type after_treatment_warm_up_phases: numpy.array
:param velocities:
Vehicle velocity [km/h].
:type velocities: numpy.array
:param co2_emissions:
CO2 instantaneous emissions vector [CO2g/s].
:type co2_emissions: numpy.array
:param times:
Time vector.
:type times: numpy.array
:param is_hybrid:
Is the vehicle hybrid?
:type is_hybrid: bool
:return:
kco2 correction factor [g/Wh].
:rtype: float
"""
if not is_hybrid:
return sh.NONE
from scipy.integrate import cumtrapz
from sklearn.linear_model import RANSACRegressor, Lasso
b = ~(force_on_engine | after_treatment_warm_up_phases)
e = np.where(
b, drive_battery_electric_powers + service_battery_electric_powers, 0
)
e = cumtrapz(e, times, initial=0) / 3.6
co2 = cumtrapz(np.where(b, co2_emissions, 0), times, initial=0)
km = cumtrapz(np.where(b, velocities / 3.6, 0), times, initial=0) / 1000
# noinspection PyTypeChecker
it = co2_utl.sliding_window(list(zip(km, zip(km, e, co2))), 5)
d = np.diff(np.array([(v[0][1], v[-1][1]) for v in it]), axis=1)[:, 0, :].T
e, co2 = d[1:] / d[0]
d0 = t0 = -float('inf')
b, dkm = [], .5
dt = dkm / np.mean(velocities) * 3600
for i, (d, t) in enumerate(zip(km, times)):
if d > d0 and t > t0:
d0, t0 = d + dkm, t + dt
b.append(i)
b = np.array(b)
m = RANSACRegressor(
random_state=0,
base_estimator=Lasso(random_state=0, positive=True)
).fit(e[b, None], co2[b])
return float(m.estimator_.coef_)