diff --git a/docs/src/how-to-use.md b/docs/src/how-to-use.md index f368a5ec..5ae8f4e7 100644 --- a/docs/src/how-to-use.md +++ b/docs/src/how-to-use.md @@ -82,18 +82,30 @@ These files contain information about assets and their associated profiles. Each This file contains information about flows and their representative period profiles for intra-temporal constraints. Each flow is defined as a pair of assets. -#### `profiles-timeframe.csv` and `profiles-rep-periods.csv` +#### [`rep-periods-data.csv`](@id rep-periods-data) -Define all the profiles for the `rep-periods` and `timeframe`. -The `profile_name` is a unique identifier, the `period` and `value` define the profile. -For the `rep-periods` case, the `rep_period` field informs the representative period. +Describes the [representative periods](@ref representative-periods) by their unique ID, the number of timesteps per representative period, and the resolution per timestep. Note that in the test files the resolution units are given as hours for understandability, but the resolution is technically unitless. + +#### [`rep-periods-mapping.csv`](@id rep-periods-mapping) + +Describes the periods of the [timeframe](@ref timeframe) that map into a [representative period](@ref representative-periods) and the weight of the representative periods that construct a period. Note that each weight is a decimal between 0 and 1, and that the sum of weights for a given period must also be between 0 and 1 (but do not have to sum to 1). + +#### `profiles-rep-periods.csv` + +Define all the profiles for the `rep-periods`. +The `profile_name` is a unique identifier, the `period` and `value` define the profile, and the `rep_period` field informs the representative period. The profiles are linked to assets and flows in the files [`assets-profiles`](@ref assets-profiles-definition), [`assets-timeframe-profiles`](@ref assets-profiles-definition), and [`flows-profiles`](@ref flows-profiles-definition). -#### [`assets-rep-periods-partitions.csv`](@id assets-rep-periods-partitions-definition) +#### `profiles-timeframe.csv` (optional) + +Define all the profiles for the `timeframe`. +This is similar to the [`profiles-rep-periods.csv`](@ref) except that it doesn't have a `rep-period` field and if this is not passed, default values are used in the timeframe constraints. + +#### [`assets-rep-periods-partitions.csv` (optional)](@id assets-rep-periods-partitions-definition) Contains a description of the [partition](@ref Partition) for each asset with respect to representative periods. -If not specified, each asset will have the exact time resolution as the representative period. +If not specified, each asset will have the same time resolution as the representative period, which is hourly by default. There are currently three ways to specify the desired resolution, indicated in the column `specification`. The column `partition` serves to define the partitions in the specified style. @@ -113,24 +125,16 @@ The table below shows various results for different formats for a representative Note: If an asset is not specified in this file, the balance equation will be written in the lowest resolution of both the incoming and outgoing flows to the asset. -#### [`flows-rep-periods-partitions.csv`](@id flow-rep-periods-partitions-definition) +#### [`flows-rep-periods-partitions.csv` (optional)](@id flow-rep-periods-partitions-definition) The same as [`assets-rep-periods-partitions.csv`](@ref assets-rep-periods-partitions-definition), but for flows. If a flow is not specified in this file, the flow time resolution will be for each timestep by default (e.g., hourly). -#### [`assets-timeframe-partitions.csv`](@id assets-timeframe-partitions) +#### [`assets-timeframe-partitions.csv` (optional)](@id assets-timeframe-partitions) The same as their [`assets-rep-periods-partitions.csv`](@ref assets-rep-periods-partitions-definition) counterpart, but for the periods in the [timeframe](@ref timeframe) of the model. -#### [`rep-periods-data.csv`](@id rep-periods-data) - -Describes the [representative periods](@ref representative-periods) by their unique ID, the number of timesteps per representative period, and the resolution per timestep. Note that in the test files the resolution units are given as hours for understandability, but the resolution is technically unitless. - -#### [`rep-periods-mapping.csv`](@id rep-periods-mapping) - -Describes the periods of the [timeframe](@ref timeframe) that map into a [representative period](@ref representative-periods) and the weight of the representative periods that construct a period. Note that each weight is a decimal between 0 and 1, and that the sum of weights for a given period must also be between 0 and 1 (but do not have to sum to 1). - #### [Schemas](@id schemas) ```@eval diff --git a/src/io.jl b/src/io.jl index 54b87bb9..d8d2437d 100644 --- a/src/io.jl +++ b/src/io.jl @@ -89,8 +89,17 @@ The following tables are expected to exist in the DB. _ `rep_periods_mapping`: Following the schema `schemas.rep_periods.mapping`. """ function create_input_dataframes(connection::DuckDB.DB; strict = false) - function read_table(table_name) + function read_table(table_name; allow_missing_table = false) schema = get_schema(table_name) + if allow_missing_table + existence_query = DBInterface.execute( + connection, + "SELECT table_name FROM information_schema.tables WHERE table_name = '$table_name'", + ) + if length(collect(existence_query)) == 0 + return DataFrame([key => value[] for (key, value) in schema]...) + end + end df = DataFrame(DBInterface.execute(connection, "SELECT * FROM $table_name")) # enforcing schema to match what Tulipa expects; DuckDB string -> symbol, int -> string for (key, value) in schema @@ -110,11 +119,12 @@ function create_input_dataframes(connection::DuckDB.DB; strict = false) dfs_assets_profiles = Dict( :rep_periods => read_table("assets_profiles"), - :timeframe => read_table("assets_timeframe_profiles"), + :timeframe => read_table("assets_timeframe_profiles"; allow_missing_table = true), ) df_flows_profiles = read_table("flows_profiles") dfs_assets_partitions = Dict( - period_type => read_table("assets_$(period_type)_partitions") for + period_type => + read_table("assets_$(period_type)_partitions"; allow_missing_table = true) for period_type in PERIOD_TYPES ) df_flows_partitions = read_table("flows_rep_periods_partitions") diff --git a/test/inputs/Tiny/assets-timeframe-partitions.csv b/test/inputs/Tiny/assets-timeframe-partitions.csv deleted file mode 100644 index 2a566fbe..00000000 --- a/test/inputs/Tiny/assets-timeframe-partitions.csv +++ /dev/null @@ -1,2 +0,0 @@ -,{uniform;explicit;math}, -asset,specification,partition diff --git a/test/inputs/Tiny/assets-timeframe-profiles.csv b/test/inputs/Tiny/assets-timeframe-profiles.csv deleted file mode 100644 index 182346ca..00000000 --- a/test/inputs/Tiny/assets-timeframe-profiles.csv +++ /dev/null @@ -1,2 +0,0 @@ -,type,name -asset,profile_type,profile_name diff --git a/test/inputs/Tiny/flows-timeframe-partitions.csv b/test/inputs/Tiny/flows-timeframe-partitions.csv deleted file mode 100644 index 05e8bbd2..00000000 --- a/test/inputs/Tiny/flows-timeframe-partitions.csv +++ /dev/null @@ -1,2 +0,0 @@ -,,{uniform;explicit;math}, -from_asset,to_asset,specification,partition diff --git a/test/inputs/Tiny/flows-timeframe-profiles.csv b/test/inputs/Tiny/flows-timeframe-profiles.csv deleted file mode 100644 index a253abe2..00000000 --- a/test/inputs/Tiny/flows-timeframe-profiles.csv +++ /dev/null @@ -1,2 +0,0 @@ -,,type,name -from_asset,to_asset,profile_type,profile_name