structure modules.
Workbook and identifiers
MarketPropensityID comprises region, sector, segment, type and sub_type. Forecast rows also carry scenario.name, potential, impact_type, savings_reporting_level, additional declared IDs and variable. Duplicate combinations can fail the importer’s pivot. Every forecast market ID must resolve to a propensity configuration, and every subregion must resolve to a parent region.
Propensity text is parsed as comma-separated key/value entries into float weights; blanks and textual none/nan yield no weight mapping. The declared column attribute.partition_type is stored on subregions; the partition loop does not independently filter on that field.
Year and unit conventions
The importer takes unique years from the forecast, pivots each disaggregated variable to annual columns and retains metadata. Supply sorted, consecutive integer years. Diffusion advances one unit per array position regardless of gaps in calendar-year labels. All allocation weights are dimensionless. Market numerator and denominator must have matching units; each propensity numerator/denominator pair must also match. Output forecast units equal input forecast units. No energy, currency or customer-count conversion is performed. Percentages or intensive metrics should not be disaggregated as though they were additive quantities without an explicit interpretation.Relative propensity
For subregion , regional parameter and configured coefficient : Withadoption_propensity_parameters equal to None or textual none, . Weights are neither normalized nor constrained to be positive by this function. A parameter with a negative behavioural relationship must be transformed or weighted appropriately in inputs. Zero denominators, missing keys and nonnumeric values are not repaired here.
Starting adoption
Forstarting_point_method="sales_and_barriers", read market using <market_share_parameter>.<sector>.<segment> and starting sales using starting_sales_parameter:
When market is zero but starting sales are nonzero, the function sets zero and emits a warning. The cap is upper-only: negative starts remain negative and fail later diffusion validation. Literal "none" produces no starting point. The conditional written starting_point_method == "none" or None does not accept Python None as an additional alternative; Python None reaches the invalid-method error.
Raw partition methods
market_size uses , constant across study years for fixed market inputs.
barriers_and_market_size uses .
diffusion uses , with the starting point derived above. The only accepted partition_method strings are market_size, barriers_and_market_size and diffusion; other values raise ValueError.
For Bass parameters :
The equivalent starting time is:
For the first forecast position, evaluate at , then increment by one for subsequent positions and relabel the sequence with the supplied study years. Starting fractions and calculated diffusion fractions are checked against . Exact one is allowed by the initial range check but is singular in the inverse logarithm; the normal starting-point calculation avoids it with the 0.999 cap. Require valid positive , a nonzero and finite inputs.
Normalization and multiplication
For every market-propensity configuration, the partition routine constructs a row for every supplied subregion, then normalizes each year column across those rows: The implementation’s normalization set is the supplied subregion list, not an additional grouping byattribute.partition_type or parent region. A configuration can therefore include unrelated subregions unless the caller restricts inputs. Use one coherent partition for a regional forecast and reconcile separately by parent region.
For finite weights with nonzero column sums, . This equality does not establish geographic correctness. Negative weights, overlapping areas or inconsistent market denominators can still create invalid allocations. There is no general zero-sum fallback, nonnegative clipping or rounding to integer customers.
Output and execution
get_disaggregated_forecasts multiplies partitions by each forecast series and appends market attributes, subregion, scenario, potential, impact type, reporting level, additional IDs and variable. Annual columns follow the forecast’s study-year list. Combined output is a concatenated dataframe; the CLI writes a timestamped CSV under ./results/ with the dataframe index included.
The CLI’s --input-data-xlsx default is ./data/DERP_input.xlsx; --log-file defaults to ./logs/ldm.log. These are filenames, not restrictions on which model’s forecasts can be supplied. Empty forecast lists or missing matches can fail in concatenation or next(...); no general empty-output recovery is implemented.