Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ JSON3 = "^1.11"
Logging = "1"
Mustache = "1"
Pkg = "1"
PrettyTables = "1.3 - 3"
PrettyTables = "2.1, 3.1"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jd-lara is this how I should implement the PrettyTables version for all the repos, or is this a special case for IS?

Printf = "1"
Random = "1"
SHA = "0.7"
Expand Down
10 changes: 9 additions & 1 deletion src/InfrastructureSystems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Optional interface functions:
- get_available()
The default function is a no-op.
- set_available!()

Subtypes may contain time series and be associated with supplemental attributes.
Those behaviors can be modified with these methods:
- supports_supplemental_attributes()
Expand Down Expand Up @@ -184,6 +184,14 @@ include("validation.jl")
include("component_selector.jl")
include("results.jl")
include("utils/print.jl")
@static if pkgversion(PrettyTables).major == 2
# When PrettyTables v2 is more widely adopted in the ecosystem, we can remove this file.
# In this case, we should also update the compat bounds in Project.toml to list only
# PrettyTables v3.
include("utils/print_pt_v2.jl")
else
include("utils/print_pt_v3.jl")
end
include("utils/test.jl")
include("units.jl")
include("value_curve.jl")
Expand Down
185 changes: 0 additions & 185 deletions src/utils/print.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,44 +77,6 @@ function Base.show(io::IO, ::MIME"text/html", data::SystemData)
show_supplemental_attributes_data(io, data; backend = :html, stand_alone = false)
end

function show_time_series_data(io::IO, data::SystemData; kwargs...)
table = get_static_time_series_summary_table(data)
if !isempty(table)
PrettyTables.pretty_table(
io,
table;
title = "StaticTimeSeries Summary",
alignment = :l,
kwargs...,
)
end
table = get_forecast_summary_table(data)
if !isempty(table)
PrettyTables.pretty_table(
io,
table;
title = "Forecast Summary",
alignment = :l,
kwargs...,
)
end
return
end

function show_supplemental_attributes_data(io::IO, data::SystemData; kwargs...)
table = get_supplemental_attribute_summary_table(data)
if !isempty(table)
PrettyTables.pretty_table(
io,
table;
title = "Supplemental Attribute Summary",
alignment = :l,
kwargs...,
)
end
return
end

function Base.show(io::IO, ::MIME"text/plain", system_units::SystemUnitsSettings)
print(io, summary(system_units), ":")
for name in fieldnames(typeof(system_units))
Expand Down Expand Up @@ -191,167 +153,20 @@ function _get_type_counts(it::FlattenIteratorWrapper)
return data
end

function show_container_table(io::IO, container::InfrastructureSystemsContainer; kwargs...)
column_labels = ["Type", "Count", "Has Static Time Series", "Has Forecasts"]
data = Array{Any, 2}(undef, length(container.data), length(column_labels))

type_names = [(strip_module_name(x), x) for x in keys(container.data)]
sort!(type_names; by = x -> x[1])
for (i, (type_name, type)) in enumerate(type_names)
vals = container.data[type]
has_sts = false
has_forecasts = false
for val in values(vals)
if has_time_series(val, StaticTimeSeries)
has_sts = true
end
if has_time_series(val, Forecast)
has_forecasts = true
end
if has_sts && has_forecasts
break
end
end
data[i, 1] = type_name
data[i, 2] = length(vals)
data[i, 3] = has_sts
data[i, 4] = has_forecasts
end

PrettyTables.pretty_table(io, data; column_labels = column_labels, alignment = :l, kwargs...)
return
end

function show_components(
io::IO,
components::Components,
component_type::Type{<:InfrastructureSystemsComponent},
additional_columns::Union{Dict, Vector} = [];
kwargs...,
)
if !isconcretetype(component_type)
error("$component_type must be a concrete type")
end

title = strip_module_name(component_type)
column_labels = ["name"]
has_available = false
if :available in fieldnames(component_type)
push!(column_labels, "available")
has_available = true
end

if additional_columns isa Dict
columns = sort!(collect(keys(additional_columns)))
else
columns = additional_columns
end

for column in columns
push!(column_labels, string(column))
end

comps = get_components(component_type, components)
data = Array{Any, 2}(undef, length(comps), length(column_labels))
for (i, component) in enumerate(comps)
data[i, 1] = get_name(component)
j = 2
if has_available
data[i, 2] = Base.getproperty(component, :available)
j += 1
end

if additional_columns isa Dict
for column in columns
data[i, j] = additional_columns[column](component)
j += 1
end
else
for column in additional_columns
getter_name = Symbol("get_$column")
parent = parentmodule(component_type)
# This logic enables application of system units in PowerSystems through
# its getter functions.
val = Base.getproperty(component, column)
if val isa InfrastructureSystemsType ||
val isa Vector{<:InfrastructureSystemsComponent}
val = summary(val)
elseif hasproperty(parent, getter_name)
getter_func = Base.getproperty(parent, getter_name)
val = getter_func(component)
end
data[i, j] = val
j += 1
end
end
end

PrettyTables.pretty_table(
io,
data;
column_labels = column_labels,
title = title,
alignment = :l,
kwargs...,
)
return
end

"""
Show a table with supplemental attributes attached to the component.
"""
function show_supplemental_attributes(component::InfrastructureSystemsComponent)
show_supplemental_attributes(stdout, component)
end

function show_supplemental_attributes(io::IO, component::InfrastructureSystemsComponent)
data_by_type = Dict{Any, Vector{OrderedDict{String, Any}}}()
for attribute in get_supplemental_attributes(component)
if !haskey(data_by_type, typeof(attribute))
data_by_type[typeof(attribute)] = Vector{OrderedDict{String, Any}}()
end
data = OrderedDict{String, Any}()
for field in fieldnames(typeof(attribute))
if field != :internal
data[string(field)] = Base.getproperty(attribute, field)
end
end
push!(data_by_type[typeof(attribute)], data)
end
for (type, rows) in data_by_type
PrettyTables.pretty_table(io, DataFrame(rows); title = string(nameof(type)))
end
end

"""
Show a table with time series data attached to the component.
"""
function show_time_series(owner::TimeSeriesOwners)
show_time_series(stdout, owner)
end

function show_time_series(io::IO, owner::TimeSeriesOwners)
data_by_type = Dict{Any, Vector{OrderedDict{String, Any}}}()
for key in get_time_series_keys(owner)
ts_type = get_time_series_type(key)
if !haskey(data_by_type, ts_type)
data_by_type[ts_type] = Vector{OrderedDict{String, Any}}()
end
data = OrderedDict{String, Any}()
for (fname, ftype) in zip(fieldnames(typeof(key)), fieldtypes(typeof(key)))
if ftype <: Type{<:TimeSeriesData}
data[string(fname)] = string(nameof(Base.getproperty(key, fname)))
else
data[string(fname)] = Base.getproperty(key, fname)
end
end
push!(data_by_type[ts_type], data)
end
for rows in values(data_by_type)
PrettyTables.pretty_table(io, DataFrame(rows))
end
end

## This function takes in a time period or date period and returns a compound period
function convert_compound_period(period::Union{Dates.TimePeriod, Dates.DatePeriod})
period = time_period_conversion(period)
Expand Down
Loading
Loading