diff --git a/src/PowerSystems.jl b/src/PowerSystems.jl index b377f4dd26..e632550aed 100644 --- a/src/PowerSystems.jl +++ b/src/PowerSystems.jl @@ -189,6 +189,7 @@ export IEEETurbineGov1 export SteamTurbineGov1 export DEGOV export DEGOV1 +export PIDGOV # Converter Exports export Converter diff --git a/src/descriptors/power_system_structs.json b/src/descriptors/power_system_structs.json index 7d2e7f1d59..eac4509ad6 100644 --- a/src/descriptors/power_system_structs.json +++ b/src/descriptors/power_system_structs.json @@ -12659,6 +12659,203 @@ ], "supertype": "TurbineGov" }, + { + "struct_name": "PIDGOV", + "docstring": "Hydro Turbine-Governor with PID controller. The GeneralGovModel (GGOV1) model is a general purpose governor model used for a variety of prime movers controlled by proportional-integral-derivative (PID) governors including gas turbines", + "fields": [ + { + "name": "feedback_flag", + "comment": "Feedback signal for governor droop: 0 for electrical power, and 1 for gate position.", + "null_value": 1, + "data_type": "Int", + "valid_range": { + "min": 0, + "max": 1 + }, + "validation_action": "error" + }, + { + "name": "Rperm", + "comment": "Speed permanent droop parameter", + "null_value": 0, + "data_type": "Float64", + "valid_range": { + "min": 0, + "max": null + }, + "validation_action": "warn" + }, + { + "name": "T_reg", + "comment": "Speed detector time constant", + "null_value": 0, + "data_type": "Float64", + "valid_range": { + "min": 0, + "max": null + }, + "validation_action": "warn" + }, + { + "name": "Kp", + "comment": "Governor proportional gain", + "null_value": 0, + "data_type": "Float64", + "valid_range": { + "min": 0, + "max": null + }, + "validation_action": "warn" + }, + { + "name": "Ki", + "comment": "Governor integral gain", + "null_value": 0, + "data_type": "Float64", + "valid_range": { + "min": 0, + "max": null + }, + "validation_action": "warn" + }, + { + "name": "Kd", + "comment": "Governor derivative gain", + "null_value": 0, + "data_type": "Float64", + "valid_range": { + "min": 0, + "max": null + }, + "validation_action": "warn" + }, + { + "name": "Ta", + "comment": "Governor derivative time constant", + "null_value": 0, + "data_type": "Float64", + "valid_range": { + "min": 0, + "max": null + }, + "validation_action": "warn" + }, + { + "name": "Tb", + "comment": "Gate-servo time constant", + "null_value": 0, + "data_type": "Float64", + "valid_range": { + "min": 0, + "max": null + }, + "validation_action": "warn" + }, + { + "name": "D_turb", + "comment": "Turbine damping factor", + "null_value": 0, + "data_type": "Float64", + "valid_range": { + "min": 0, + "max": null + }, + "validation_action": "warn" + }, + { + "name": "gate_openings", + "comment": "Gate-opening speed at different loads", + "null_value": "(0.0, 0.0, 0.0)", + "data_type": "Tuple{Float64, Float64, Float64}" + }, + { + "name": "power_gate_openings", + "comment": "Power at gate_openings", + "null_value": "(0.0, 0.0, 0.0)", + "data_type": "Tuple{Float64, Float64, Float64}" + }, + { + "name": "G_lim", + "comment": "Minimum/Maximum Gate openings `(G_min, G_max)`.", + "null_value": "(min=0.0, max=0.0)", + "data_type": "MinMax" + }, + { + "name": "A_tw", + "comment": "Factor multiplying Tw", + "null_value": 0, + "data_type": "Float64", + "valid_range": { + "min": "eps()", + "max": null + }, + "validation_action": "warn" + }, + { + "name": "Tw", + "comment": "Water inertia time constant, sec", + "null_value": 0, + "data_type": "Float64", + "valid_range": { + "min": "eps()", + "max": null + }, + "validation_action": "warn" + }, + { + "name": "V_lim", + "comment": "Gate opening velocity limits `(G_min, G_max)`.", + "null_value": "(min=0.0, max=0.0)", + "data_type": "MinMax" + }, + { + "name": "P_ref", + "comment": "Reference Power Set-point (pu)", + "null_value": 0, + "default": "1.0", + "data_type": "Float64", + "valid_range": { + "min": 0, + "max": null + } + }, + { + "name": "ext", + "comment": "An *ext*ra dictionary for users to add metadata that are not used in simulation, such as latitude and longitude. See [Adding additional fields](@ref)", + "data_type": "Dict{String, Any}", + "null_value": "Dict{String, Any}()", + "default": "Dict{String, Any}()" + }, + { + "name": "states", + "exclude_setter": true, + "comment": "(**Do not modify.**) The [states](@ref S) of the PIDGOV model are:\n\tx_g1: Filtered input measurement,\n\tx_g2: PI block internal state,\n\tx_g3: First regulator state, \n\tx_g4: Derivative block internal state, \n\tx_g5: Second regulator state, \n\tx_g6: Gate position state, \n\tx_g7: Water inertia state", + "internal_default": "[:x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6, :x_g7]", + "data_type": "Vector{Symbol}" + }, + { + "name": "n_states", + "exclude_setter": true, + "comment": "(**Do not modify.**) PIDGOV has 7 states", + "internal_default": 7, + "data_type": "Int" + }, + { + "name": "states_types", + "comment": "(**Do not modify.**) PIDGOV has 7 [differential](@ref states_list) [states](@ref S)", + "internal_default": "[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid]", + "data_type": "Vector{StateTypes}" + }, + { + "name": "internal", + "comment": "(**Do not modify.**) PowerSystems.jl internal reference", + "data_type": "InfrastructureSystemsInternal", + "internal_default": "InfrastructureSystemsInternal()", + "exclude_setter": true + } + ], + "supertype": "TurbineGov" + }, { "struct_name": "SteamTurbineGov1", "docstring": "Steam Turbine-Governor. This model considers both TGOV1 or TGOV1DU in PSS/E", diff --git a/src/models/generated/PIDGOV.jl b/src/models/generated/PIDGOV.jl new file mode 100644 index 0000000000..edaed063c9 --- /dev/null +++ b/src/models/generated/PIDGOV.jl @@ -0,0 +1,225 @@ +#= +This file is auto-generated. Do not edit. +=# + +#! format: off + +""" + mutable struct PIDGOV <: TurbineGov + feedback_flag::Int + Rperm::Float64 + T_reg::Float64 + Kp::Float64 + Ki::Float64 + Kd::Float64 + Ta::Float64 + Tb::Float64 + D_turb::Float64 + gate_openings::Tuple{Float64, Float64, Float64} + power_gate_openings::Tuple{Float64, Float64, Float64} + G_lim::MinMax + A_tw::Float64 + Tw::Float64 + V_lim::MinMax + P_ref::Float64 + ext::Dict{String, Any} + states::Vector{Symbol} + n_states::Int + states_types::Vector{StateTypes} + internal::InfrastructureSystemsInternal + end + +Hydro Turbine-Governor with PID controller. The GeneralGovModel (GGOV1) model is a general purpose governor model used for a variety of prime movers controlled by proportional-integral-derivative (PID) governors including gas turbines + +# Arguments +- `feedback_flag::Int`: Feedback signal for governor droop: 0 for electrical power, and 1 for gate position., validation range: `(0, 1)` +- `Rperm::Float64`: Speed permanent droop parameter, validation range: `(0, nothing)` +- `T_reg::Float64`: Speed detector time constant, validation range: `(0, nothing)` +- `Kp::Float64`: Governor proportional gain, validation range: `(0, nothing)` +- `Ki::Float64`: Governor integral gain, validation range: `(0, nothing)` +- `Kd::Float64`: Governor derivative gain, validation range: `(0, nothing)` +- `Ta::Float64`: Governor derivative time constant, validation range: `(0, nothing)` +- `Tb::Float64`: Gate-servo time constant, validation range: `(0, nothing)` +- `D_turb::Float64`: Turbine damping factor, validation range: `(0, nothing)` +- `gate_openings::Tuple{Float64, Float64, Float64}`: Gate-opening speed at different loads +- `power_gate_openings::Tuple{Float64, Float64, Float64}`: Power at gate_openings +- `G_lim::MinMax`: Minimum/Maximum Gate openings `(G_min, G_max)`. +- `A_tw::Float64`: Factor multiplying Tw, validation range: `(eps(), nothing)` +- `Tw::Float64`: Water inertia time constant, sec, validation range: `(eps(), nothing)` +- `V_lim::MinMax`: Gate opening velocity limits `(G_min, G_max)`. +- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)` +- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An *ext*ra dictionary for users to add metadata that are not used in simulation, such as latitude and longitude. See [Adding additional fields](@ref) +- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the PIDGOV model are: + x_g1: Filtered input measurement, + x_g2: PI block internal state, + x_g3: First regulator state, + x_g4: Derivative block internal state, + x_g5: Second regulator state, + x_g6: Gate position state, + x_g7: Water inertia state +- `n_states::Int`: (**Do not modify.**) PIDGOV has 7 states +- `states_types::Vector{StateTypes}`: (**Do not modify.**) PIDGOV has 7 [differential](@ref states_list) [states](@ref S) +- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference +""" +mutable struct PIDGOV <: TurbineGov + "Feedback signal for governor droop: 0 for electrical power, and 1 for gate position." + feedback_flag::Int + "Speed permanent droop parameter" + Rperm::Float64 + "Speed detector time constant" + T_reg::Float64 + "Governor proportional gain" + Kp::Float64 + "Governor integral gain" + Ki::Float64 + "Governor derivative gain" + Kd::Float64 + "Governor derivative time constant" + Ta::Float64 + "Gate-servo time constant" + Tb::Float64 + "Turbine damping factor" + D_turb::Float64 + "Gate-opening speed at different loads" + gate_openings::Tuple{Float64, Float64, Float64} + "Power at gate_openings" + power_gate_openings::Tuple{Float64, Float64, Float64} + "Minimum/Maximum Gate openings `(G_min, G_max)`." + G_lim::MinMax + "Factor multiplying Tw" + A_tw::Float64 + "Water inertia time constant, sec" + Tw::Float64 + "Gate opening velocity limits `(G_min, G_max)`." + V_lim::MinMax + "Reference Power Set-point (pu)" + P_ref::Float64 + "An *ext*ra dictionary for users to add metadata that are not used in simulation, such as latitude and longitude. See [Adding additional fields](@ref)" + ext::Dict{String, Any} + "(**Do not modify.**) The [states](@ref S) of the PIDGOV model are: + x_g1: Filtered input measurement, + x_g2: PI block internal state, + x_g3: First regulator state, + x_g4: Derivative block internal state, + x_g5: Second regulator state, + x_g6: Gate position state, + x_g7: Water inertia state" + states::Vector{Symbol} + "(**Do not modify.**) PIDGOV has 7 states" + n_states::Int + "(**Do not modify.**) PIDGOV has 7 [differential](@ref states_list) [states](@ref S)" + states_types::Vector{StateTypes} + "(**Do not modify.**) PowerSystems.jl internal reference" + internal::InfrastructureSystemsInternal +end + +function PIDGOV(feedback_flag, Rperm, T_reg, Kp, Ki, Kd, Ta, Tb, D_turb, gate_openings, power_gate_openings, G_lim, A_tw, Tw, V_lim, P_ref=1.0, ext=Dict{String, Any}(), ) + PIDGOV(feedback_flag, Rperm, T_reg, Kp, Ki, Kd, Ta, Tb, D_turb, gate_openings, power_gate_openings, G_lim, A_tw, Tw, V_lim, P_ref, ext, [:x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6, :x_g7], 7, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid], InfrastructureSystemsInternal(), ) +end + +function PIDGOV(; feedback_flag, Rperm, T_reg, Kp, Ki, Kd, Ta, Tb, D_turb, gate_openings, power_gate_openings, G_lim, A_tw, Tw, V_lim, P_ref=1.0, ext=Dict{String, Any}(), states=[:x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6, :x_g7], n_states=7, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid], internal=InfrastructureSystemsInternal(), ) + PIDGOV(feedback_flag, Rperm, T_reg, Kp, Ki, Kd, Ta, Tb, D_turb, gate_openings, power_gate_openings, G_lim, A_tw, Tw, V_lim, P_ref, ext, states, n_states, states_types, internal, ) +end + +# Constructor for demo purposes; non-functional. +function PIDGOV(::Nothing) + PIDGOV(; + feedback_flag=1, + Rperm=0, + T_reg=0, + Kp=0, + Ki=0, + Kd=0, + Ta=0, + Tb=0, + D_turb=0, + gate_openings=(0.0, 0.0, 0.0), + power_gate_openings=(0.0, 0.0, 0.0), + G_lim=(min=0.0, max=0.0), + A_tw=0, + Tw=0, + V_lim=(min=0.0, max=0.0), + P_ref=0, + ext=Dict{String, Any}(), + ) +end + +"""Get [`PIDGOV`](@ref) `feedback_flag`.""" +get_feedback_flag(value::PIDGOV) = value.feedback_flag +"""Get [`PIDGOV`](@ref) `Rperm`.""" +get_Rperm(value::PIDGOV) = value.Rperm +"""Get [`PIDGOV`](@ref) `T_reg`.""" +get_T_reg(value::PIDGOV) = value.T_reg +"""Get [`PIDGOV`](@ref) `Kp`.""" +get_Kp(value::PIDGOV) = value.Kp +"""Get [`PIDGOV`](@ref) `Ki`.""" +get_Ki(value::PIDGOV) = value.Ki +"""Get [`PIDGOV`](@ref) `Kd`.""" +get_Kd(value::PIDGOV) = value.Kd +"""Get [`PIDGOV`](@ref) `Ta`.""" +get_Ta(value::PIDGOV) = value.Ta +"""Get [`PIDGOV`](@ref) `Tb`.""" +get_Tb(value::PIDGOV) = value.Tb +"""Get [`PIDGOV`](@ref) `D_turb`.""" +get_D_turb(value::PIDGOV) = value.D_turb +"""Get [`PIDGOV`](@ref) `gate_openings`.""" +get_gate_openings(value::PIDGOV) = value.gate_openings +"""Get [`PIDGOV`](@ref) `power_gate_openings`.""" +get_power_gate_openings(value::PIDGOV) = value.power_gate_openings +"""Get [`PIDGOV`](@ref) `G_lim`.""" +get_G_lim(value::PIDGOV) = value.G_lim +"""Get [`PIDGOV`](@ref) `A_tw`.""" +get_A_tw(value::PIDGOV) = value.A_tw +"""Get [`PIDGOV`](@ref) `Tw`.""" +get_Tw(value::PIDGOV) = value.Tw +"""Get [`PIDGOV`](@ref) `V_lim`.""" +get_V_lim(value::PIDGOV) = value.V_lim +"""Get [`PIDGOV`](@ref) `P_ref`.""" +get_P_ref(value::PIDGOV) = value.P_ref +"""Get [`PIDGOV`](@ref) `ext`.""" +get_ext(value::PIDGOV) = value.ext +"""Get [`PIDGOV`](@ref) `states`.""" +get_states(value::PIDGOV) = value.states +"""Get [`PIDGOV`](@ref) `n_states`.""" +get_n_states(value::PIDGOV) = value.n_states +"""Get [`PIDGOV`](@ref) `states_types`.""" +get_states_types(value::PIDGOV) = value.states_types +"""Get [`PIDGOV`](@ref) `internal`.""" +get_internal(value::PIDGOV) = value.internal + +"""Set [`PIDGOV`](@ref) `feedback_flag`.""" +set_feedback_flag!(value::PIDGOV, val) = value.feedback_flag = val +"""Set [`PIDGOV`](@ref) `Rperm`.""" +set_Rperm!(value::PIDGOV, val) = value.Rperm = val +"""Set [`PIDGOV`](@ref) `T_reg`.""" +set_T_reg!(value::PIDGOV, val) = value.T_reg = val +"""Set [`PIDGOV`](@ref) `Kp`.""" +set_Kp!(value::PIDGOV, val) = value.Kp = val +"""Set [`PIDGOV`](@ref) `Ki`.""" +set_Ki!(value::PIDGOV, val) = value.Ki = val +"""Set [`PIDGOV`](@ref) `Kd`.""" +set_Kd!(value::PIDGOV, val) = value.Kd = val +"""Set [`PIDGOV`](@ref) `Ta`.""" +set_Ta!(value::PIDGOV, val) = value.Ta = val +"""Set [`PIDGOV`](@ref) `Tb`.""" +set_Tb!(value::PIDGOV, val) = value.Tb = val +"""Set [`PIDGOV`](@ref) `D_turb`.""" +set_D_turb!(value::PIDGOV, val) = value.D_turb = val +"""Set [`PIDGOV`](@ref) `gate_openings`.""" +set_gate_openings!(value::PIDGOV, val) = value.gate_openings = val +"""Set [`PIDGOV`](@ref) `power_gate_openings`.""" +set_power_gate_openings!(value::PIDGOV, val) = value.power_gate_openings = val +"""Set [`PIDGOV`](@ref) `G_lim`.""" +set_G_lim!(value::PIDGOV, val) = value.G_lim = val +"""Set [`PIDGOV`](@ref) `A_tw`.""" +set_A_tw!(value::PIDGOV, val) = value.A_tw = val +"""Set [`PIDGOV`](@ref) `Tw`.""" +set_Tw!(value::PIDGOV, val) = value.Tw = val +"""Set [`PIDGOV`](@ref) `V_lim`.""" +set_V_lim!(value::PIDGOV, val) = value.V_lim = val +"""Set [`PIDGOV`](@ref) `P_ref`.""" +set_P_ref!(value::PIDGOV, val) = value.P_ref = val +"""Set [`PIDGOV`](@ref) `ext`.""" +set_ext!(value::PIDGOV, val) = value.ext = val +"""Set [`PIDGOV`](@ref) `states_types`.""" +set_states_types!(value::PIDGOV, val) = value.states_types = val diff --git a/src/models/generated/includes.jl b/src/models/generated/includes.jl index 98beba8adf..0c2648349d 100644 --- a/src/models/generated/includes.jl +++ b/src/models/generated/includes.jl @@ -86,6 +86,7 @@ include("GasTG.jl") include("DEGOV.jl") include("DEGOV1.jl") include("GeneralGovModel.jl") +include("PIDGOV.jl") include("SteamTurbineGov1.jl") include("HydroTurbineGov.jl") include("IEEETurbineGov1.jl") @@ -133,6 +134,7 @@ export get_A5 export get_A6 export get_AT export get_A_set +export get_A_tw export get_Accel export get_Ae export get_At @@ -166,6 +168,7 @@ export get_FRT_pnts export get_Freq_Flag export get_Ftrip_Flag export get_G +export get_G_lim export get_Gen_Flag export get_H export get_H_ex @@ -304,6 +307,7 @@ export get_Recon_Flag export get_Ref_Flag export get_Rmin export get_Rp +export get_Rperm export get_Rrpwr export get_Rselect export get_SOC_ini @@ -342,6 +346,7 @@ export get_T_p export get_T_pord export get_T_q export get_T_rate +export get_T_reg export get_T_rv export get_Ta export get_Ta_2 @@ -494,6 +499,7 @@ export get_ext export get_f export get_fdbd_pnts export get_fe_lim +export get_feedback_flag export get_fh export get_fl export get_flow_limits @@ -504,6 +510,7 @@ export get_from_branch_control export get_fs export get_fuel export get_fuel_flag +export get_gate_openings export get_gate_position_limits export get_hysteresis_binary_logic export get_impedance_active_power @@ -579,6 +586,7 @@ export get_peak_active_power export get_peak_reactive_power export get_phase_angle_limits export get_power_factor +export get_power_gate_openings export get_power_trajectory export get_primary_shunt export get_prime_mover_type @@ -673,6 +681,7 @@ export set_A5! export set_A6! export set_AT! export set_A_set! +export set_A_tw! export set_Accel! export set_Ae! export set_At! @@ -706,6 +715,7 @@ export set_FRT_pnts! export set_Freq_Flag! export set_Ftrip_Flag! export set_G! +export set_G_lim! export set_Gen_Flag! export set_H! export set_H_ex! @@ -844,6 +854,7 @@ export set_Recon_Flag! export set_Ref_Flag! export set_Rmin! export set_Rp! +export set_Rperm! export set_Rrpwr! export set_Rselect! export set_SOC_ini! @@ -882,6 +893,7 @@ export set_T_p! export set_T_pord! export set_T_q! export set_T_rate! +export set_T_reg! export set_T_rv! export set_Ta! export set_Ta_2! @@ -1034,6 +1046,7 @@ export set_ext! export set_f! export set_fdbd_pnts! export set_fe_lim! +export set_feedback_flag! export set_fh! export set_fl! export set_flow_limits! @@ -1044,6 +1057,7 @@ export set_from_branch_control! export set_fs! export set_fuel! export set_fuel_flag! +export set_gate_openings! export set_gate_position_limits! export set_hysteresis_binary_logic! export set_impedance_active_power! @@ -1119,6 +1133,7 @@ export set_peak_active_power! export set_peak_reactive_power! export set_phase_angle_limits! export set_power_factor! +export set_power_gate_openings! export set_power_trajectory! export set_primary_shunt! export set_prime_mover_type! diff --git a/src/parsers/psse_dynamic_data.jl b/src/parsers/psse_dynamic_data.jl index 2737ec95dd..99433a8ea5 100644 --- a/src/parsers/psse_dynamic_data.jl +++ b/src/parsers/psse_dynamic_data.jl @@ -61,10 +61,15 @@ function _parse_input_types(_v, val) return NaN # If the parameter is a tuple (as a string), then construct the tuple directly. elseif isa(_v, String) + #TODO: Generalize n-length tuple m = match(r"^\((\d+)\s*,\s*(\d+)\)$", _v) + m2 = match(r"^\((\d+)\s*,\s*(\d+),\s*(\d+)\)$", _v) if m !== nothing _tuple_ix = parse.(Int, m.captures) return Tuple(val[_tuple_ix]) + elseif m2 !== nothing + _tuple_ix = parse.(Int, m2.captures) + return Tuple(val[_tuple_ix]) else error("String $(_v) not recognized for parsing") end @@ -466,7 +471,7 @@ specific generator components """ function _convert_argument_types_for_gen!(str::AbstractString, struct_args::Vector) - if str == "DEGOV1" + if (str == "DEGOV1") || (str == "PIDGOV") struct_args[1] = Int(struct_args[1]) end return diff --git a/src/parsers/psse_dynamic_mapping.yaml b/src/parsers/psse_dynamic_mapping.yaml index 626933948b..ee0596d759 100644 --- a/src/parsers/psse_dynamic_mapping.yaml +++ b/src/parsers/psse_dynamic_mapping.yaml @@ -135,6 +135,10 @@ DEGOV1: { TurbineGov: DEGOV1 }, +PIDGOV: +{ + TurbineGov: PIDGOV +}, ###################################### ###### Power System Stabilizers ###### @@ -257,6 +261,7 @@ parameter_mapping: SteamTurbineGov1: [1, 2, '(4, 3)', 5, 6, 7, 0.0, 0.0, 0.0], TGOV1DU: [1, 2, '(4, 3)', 5, 6, 7, 8, 9, 10], DEGOV1: [1, 2, 3, 4, 5, 6, 7, 8, 9, '(11, 10)', 12, 13], + PIDGOV: [1, 2, 3, 4, 5, 6, 7, 8, 9, '(10, 11, 13)', '(12, 14, 15)', '(17, 16)', 18, 19, '(21, 20)'], #PSSs: IEEEST: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, '(17, 16)', 18, 19], STAB1: [1, 2, 3, 4, 5, 6, 7],