@@ -617,6 +617,58 @@ def fuel_spending_litre_proxy_uprating(
617617 )
618618
619619
620+ def _fuel_litre_proxy_mlitres (
621+ household : pd .DataFrame ,
622+ fiscal_year : int ,
623+ parameters = None ,
624+ ) -> float :
625+ """Return weighted petrol + diesel litres represented by spending proxies."""
626+ from policyengine_uk .system import system
627+
628+ if parameters is None :
629+ parameters = system .parameters
630+
631+ total_litres = 0.0
632+ for variable , price_parameter_name in FUEL_PRICE_PARAMETER_NAME .items ():
633+ price = getattr (
634+ parameters .household .consumption .fuel .prices ,
635+ price_parameter_name ,
636+ )(fiscal_year )
637+ total_litres += household [variable ] / price
638+ return (total_litres * household ["household_weight" ]).sum () / 1_000_000
639+
640+
641+ def calibrate_fuel_litre_proxies_to_road_fuel (
642+ household : pd .DataFrame ,
643+ fiscal_year : int ,
644+ parameters = None ,
645+ ) -> float :
646+ """Scale imputed fuel proxies to HMRC/OBR road-fuel litre controls.
647+
648+ PolicyEngine UK derives petrol and diesel litres from spending divided by
649+ pump prices. Applying one multiplicative factor to petrol and diesel
650+ spending preserves the household distribution while making the resulting
651+ litres reconcile to the external fuel-duty volume benchmark.
652+ """
653+ from policyengine_uk_data .sources .road_fuel_volume import (
654+ road_fuel_clearances_mlitres ,
655+ )
656+
657+ actual_mlitres = _fuel_litre_proxy_mlitres (
658+ household ,
659+ fiscal_year ,
660+ parameters = parameters ,
661+ )
662+ if actual_mlitres <= 0 :
663+ return 1.0
664+
665+ target_mlitres = road_fuel_clearances_mlitres (end_year = fiscal_year )[fiscal_year ]
666+ scale = target_mlitres / actual_mlitres
667+ for variable in FUEL_PRICE_PARAMETER_NAME :
668+ household [variable ] *= scale
669+ return scale
670+
671+
620672def save_imputation_models ():
621673 from policyengine_uk_data .utils .qrf import QRF
622674
@@ -739,5 +791,10 @@ def _wmean(arr, mask):
739791 dataset .household ["petrol_spending" ][no_fuel ] = 0
740792 dataset .household ["diesel_spending" ][no_fuel ] = 0
741793
794+ calibrate_fuel_litre_proxies_to_road_fuel (
795+ dataset .household ,
796+ int (dataset .time_period ),
797+ )
798+
742799 dataset .validate ()
743800 return dataset
0 commit comments