Repository navigation
Identification of sub time structures #78
Description
Problem statement
In the current stage, we do not know what time structures are within the top time structure, even when considering the parametric input.
Consider the following example:
using TimeStruct
# Creation of the time structure
day = SimpleTimes(24, 1);
opscen_summer = OperationalScenarios(2, [day, day], [0.5, 0.5]);
opscen_winter = OperationalScenarios(2, [day, day], [0.5, 0.5])
rep = RepresentativePeriods(2, 8760.0, [25, 25]/50, [opscen_summer, opscen_winter]);
ts = TwoLevel(n_sp, dur_sp, rep, op_per_strat=8760.0);The time structure is in this case of type TwoLevel{Int64, Int64, RepresentativePeriods{Float64, Int64, OperationalScenarios{Int64, SimpleTimes{Int64}}}}. If we change it a bit to
rep = RepresentativePeriods(2, 8760.0, [25, 25]/50, [opscen_summer, day]);
ts = TwoLevel(n_sp, dur_sp, rep, op_per_strat=8760.0);we lost the knowledge as it is not of type TwoLevel{Int64, Int64, RepresentativePeriods{Float64, Int64, TimeStructure{Int64}}}. It can however be beneficial to have an understanding of whether a time structure has representative periods and operational scenarios for only declaring variables when these are required. A current (crude) implementation in EnergyModelsBase is rather limited and does not allow for a TwoLevelTree.
Potential solutions
We can create an iterative procedure which identifies whether operational scenarios are required:
function has_opscenarios(ts::TwoLevelTree, tmp::Bool = false)
for strat_node ∈ ts.nodes
tmp = has_opscenarios(strat_node.operational, tmp)
tmp && break
end
return tmp
end
function has_opscenarios(ts::TwoLevel, tmp::Bool = false)
for sub_ts ∈ ts.operational
tmp = has_opscenarios(sub_ts, tmp)
tmp && break
end
return tmp
end
function has_opscenarios(ts::RepresentativePeriods, tmp::Bool = false)
for sub_ts ∈ ts.rep_periods
tmp = has_opscenarios(sub_ts, tmp)
tmp && break
end
return tmp
end
has_opscenarios(ts::OperationalScenarios, tmp::Bool = false) = true
has_opscenarios(ts::SimpleTimes, tmp::Bool = false) = false
has_opscenarios(ts::CalendarTimes, tmp::Bool = false) = falseA similar procedure could also be declared for RepresentativePeriods. There may still be potential problems in a model if a mixed time structure is created and these implications are not considered, but I think that it would be a good support for external users when creating models.
Note
I would hope that we get this through before 1.0. It should however be included at latest 1.0
Activity
JulStraus commentedon Oct 13, 2026
Given that it is about 1 year old, are there any thoughts regarding the implementation? @trulsf or @hellemo? I do not see any harm in adding it.
trulsf commentedon Oct 16, 2026
I also see no harm in adding it.
I would prefer to leave out the
tmpin the signature and do e.g.and similarly for other functions. Should the functionality also be provided for periods? E.g.
has_opscenarios(sp::StrategicPeriod).JulStraus commentedon Oct 16, 2026
Seems reasonable to me to leave out temp. The reason why I proposed the for loop was to explicitly break once it was detected. I realized now that
anyis doing the same.I would guess so? Then again, for me, the key factor is that I only want to declare variables over operational scenarios or representative periods when these are present. This is not necessarily equally important for, e.g., a
StrategicPeriod.I will implement a version of it.