urbanopt-scenario 0.2.0.pre2 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. checksums.yaml +5 -5
  2. data/.github/pull_request_template.md +2 -2
  3. data/.gitignore +2 -0
  4. data/.rubocop.yml +1 -1
  5. data/CHANGELOG.md +82 -1
  6. data/CONTRIBUTING.md +1 -1
  7. data/Gemfile +28 -18
  8. data/Jenkinsfile +1 -1
  9. data/LICENSE.md +1 -1
  10. data/RDOC_MAIN.md +1 -1
  11. data/README.md +1 -1
  12. data/Rakefile +2 -2
  13. data/docs/README.md +1 -1
  14. data/docs/package-lock.json +2499 -2322
  15. data/docs/package.json +13 -9
  16. data/lib/urbanopt-scenario.rb +1 -1
  17. data/lib/urbanopt/scenario.rb +3 -1
  18. data/lib/urbanopt/scenario/default_reports.rb +3 -8
  19. data/lib/urbanopt/scenario/extension.rb +1 -1
  20. data/lib/urbanopt/scenario/logger.rb +1 -1
  21. data/lib/urbanopt/scenario/scenario_base.rb +1 -1
  22. data/lib/urbanopt/scenario/scenario_csv.rb +22 -9
  23. data/lib/urbanopt/scenario/scenario_datapoint_base.rb +8 -1
  24. data/lib/urbanopt/scenario/scenario_post_processor_base.rb +1 -1
  25. data/lib/urbanopt/scenario/scenario_post_processor_default.rb +99 -8
  26. data/lib/urbanopt/scenario/scenario_post_processor_opendss.rb +275 -0
  27. data/lib/urbanopt/scenario/scenario_runner_base.rb +2 -2
  28. data/lib/urbanopt/scenario/scenario_runner_osw.rb +23 -9
  29. data/lib/urbanopt/scenario/scenario_visualization.rb +236 -0
  30. data/lib/urbanopt/scenario/simulation_dir_base.rb +1 -1
  31. data/lib/urbanopt/scenario/simulation_dir_osw.rb +2 -9
  32. data/lib/urbanopt/scenario/simulation_mapper_base.rb +1 -1
  33. data/lib/urbanopt/scenario/version.rb +2 -2
  34. data/package-lock.json +3 -0
  35. data/urbanopt-scenario-gem.gemspec +15 -15
  36. metadata +78 -82
  37. data/doc_templates/LICENSE.md +0 -27
  38. data/doc_templates/README.md.erb +0 -42
  39. data/doc_templates/copyright_erb.txt +0 -31
  40. data/doc_templates/copyright_js.txt +0 -4
  41. data/doc_templates/copyright_ruby.txt +0 -29
  42. data/lib/change_log.rb +0 -147
  43. data/lib/measures/.rubocop.yml +0 -5
  44. data/lib/measures/default_feature_reports/LICENSE.md +0 -27
  45. data/lib/measures/default_feature_reports/README.md +0 -56
  46. data/lib/measures/default_feature_reports/README.md.erb +0 -42
  47. data/lib/measures/default_feature_reports/measure.rb +0 -957
  48. data/lib/measures/default_feature_reports/measure.xml +0 -143
  49. data/lib/measures/default_feature_reports/tests/USA_CO_Golden-NREL.724666_TMY3.epw +0 -8768
  50. data/lib/measures/default_feature_reports/tests/default_feature_reports_test.rb +0 -238
  51. data/lib/measures/default_feature_reports/tests/example_model.osm +0 -4378
  52. data/lib/urbanopt/scenario/default_reports/construction_cost.rb +0 -169
  53. data/lib/urbanopt/scenario/default_reports/date.rb +0 -97
  54. data/lib/urbanopt/scenario/default_reports/distributed_generation.rb +0 -374
  55. data/lib/urbanopt/scenario/default_reports/end_use.rb +0 -159
  56. data/lib/urbanopt/scenario/default_reports/end_uses.rb +0 -140
  57. data/lib/urbanopt/scenario/default_reports/feature_report.rb +0 -260
  58. data/lib/urbanopt/scenario/default_reports/generator.rb +0 -92
  59. data/lib/urbanopt/scenario/default_reports/location.rb +0 -99
  60. data/lib/urbanopt/scenario/default_reports/logger.rb +0 -44
  61. data/lib/urbanopt/scenario/default_reports/program.rb +0 -266
  62. data/lib/urbanopt/scenario/default_reports/reporting_period.rb +0 -301
  63. data/lib/urbanopt/scenario/default_reports/scenario_report.rb +0 -311
  64. data/lib/urbanopt/scenario/default_reports/schema/README.md +0 -33
  65. data/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt +0 -21
  66. data/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json +0 -839
  67. data/lib/urbanopt/scenario/default_reports/solar_pv.rb +0 -93
  68. data/lib/urbanopt/scenario/default_reports/storage.rb +0 -105
  69. data/lib/urbanopt/scenario/default_reports/timeseries_csv.rb +0 -284
  70. data/lib/urbanopt/scenario/default_reports/validator.rb +0 -97
  71. data/lib/urbanopt/scenario/default_reports/wind.rb +0 -92
@@ -1,93 +0,0 @@
1
- # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
- # contributors. All rights reserved.
4
- #
5
- # Redistribution and use in source and binary forms, with or without modification,
6
- # are permitted provided that the following conditions are met:
7
- #
8
- # Redistributions of source code must retain the above copyright notice, this list
9
- # of conditions and the following disclaimer.
10
- #
11
- # Redistributions in binary form must reproduce the above copyright notice, this
12
- # list of conditions and the following disclaimer in the documentation and/or other
13
- # materials provided with the distribution.
14
- #
15
- # Neither the name of the copyright holder nor the names of its contributors may be
16
- # used to endorse or promote products derived from this software without specific
17
- # prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
- # OF THE POSSIBILITY OF SUCH DAMAGE.
29
- # *********************************************************************************
30
-
31
- require 'json'
32
- require 'json-schema'
33
-
34
- module URBANopt
35
- module Scenario
36
- module DefaultReports
37
- ##
38
- # Onsite solar PV system attributes
39
- ##
40
- class SolarPV
41
- ##
42
- # _Float_ - power capacity in kilowatts
43
- #
44
- attr_accessor :size_kw
45
-
46
- ##
47
- # Initialize SolarPV attributes from a hash. Solar PV attributes currently are limited to power capacity.
48
- ##
49
- # [parameters:]
50
- #
51
- # * +hash+ - _Hash_ - A hash containting a +:size_kw+ key/value pair which represents the nameplate capacity in kilowatts (kW)
52
- #
53
- def initialize(hash = {})
54
- hash.delete_if { |k, v| v.nil? }
55
-
56
- @size_kw = hash[:size_kw]
57
- @id = hash[:id]
58
-
59
- # initialize class variables @@validator and @@schema
60
- @@validator ||= Validator.new
61
- @@schema ||= @@validator.schema
62
-
63
- # initialize @@logger
64
- @@logger ||= URBANopt::Scenario::DefaultReports.logger
65
- end
66
-
67
- ##
68
- # Convert to a Hash equivalent for JSON serialization
69
- ##
70
- def to_hash
71
- result = {}
72
-
73
- result[:size_kw] = @size_kw if @size_kw
74
-
75
- return result
76
- end
77
-
78
- ##
79
- # Merge PV systems
80
- ##
81
- def self.add_pv(existing_pv, new_pv)
82
- if existing_pv.size_kw.nil? && new_pv.size_kw.nil?
83
- existing_pv.size_kw = nil
84
- else
85
- existing_pv.size_kw = (existing_pv.size_kw || 0) + (new_pv.size_kw || 0)
86
- end
87
-
88
- return existing_pv
89
- end
90
- end
91
- end
92
- end
93
- end
@@ -1,105 +0,0 @@
1
- # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
- # contributors. All rights reserved.
4
- #
5
- # Redistribution and use in source and binary forms, with or without modification,
6
- # are permitted provided that the following conditions are met:
7
- #
8
- # Redistributions of source code must retain the above copyright notice, this list
9
- # of conditions and the following disclaimer.
10
- #
11
- # Redistributions in binary form must reproduce the above copyright notice, this
12
- # list of conditions and the following disclaimer in the documentation and/or other
13
- # materials provided with the distribution.
14
- #
15
- # Neither the name of the copyright holder nor the names of its contributors may be
16
- # used to endorse or promote products derived from this software without specific
17
- # prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
- # OF THE POSSIBILITY OF SUCH DAMAGE.
29
- # *********************************************************************************
30
-
31
- require 'json'
32
- require 'json-schema'
33
-
34
- module URBANopt
35
- module Scenario
36
- module DefaultReports
37
- ##
38
- # Onsite storage system attributes
39
- ##
40
- class Storage
41
- ##
42
- # _Float_ - power capacity in kilowatts
43
- #
44
- attr_accessor :size_kw
45
-
46
- ##
47
- # _Float_ - storage capacity in kilowatt-hours
48
- #
49
- attr_accessor :size_kwh
50
-
51
- ##
52
- # Initialize Storage attributes from a hash. Storage attributes currently are limited to power and storage capacity.
53
- ##
54
- # [parameters:]
55
- #
56
- # * +hash+ - _Hash_ - A hash containting +:size_kw+ and +:size_kwh+ key/value pair which represents the power and storage capacity in kilowatts (kW) and kilowatt-hours respectively.
57
- #
58
- def initialize(hash = {})
59
- hash.delete_if { |k, v| v.nil? }
60
-
61
- @size_kw = hash[:size_kw]
62
- @size_kwh = hash[:size_kwh]
63
-
64
- # initialize class variables @@validator and @@schema
65
- @@validator ||= Validator.new
66
- @@schema ||= @@validator.schema
67
-
68
- # initialize @@logger
69
- @@logger ||= URBANopt::Scenario::DefaultReports.logger
70
- end
71
-
72
- ##
73
- # Convert to a Hash equivalent for JSON serialization
74
- ##
75
- def to_hash
76
- result = {}
77
-
78
- result[:size_kw] = @size_kw if @size_kw
79
- result[:size_kwh] = @size_kwh if @size_kwh
80
-
81
- return result
82
- end
83
-
84
- ##
85
- # Merge Storage systems
86
- ##
87
- def self.add_storage(existing_storage, new_storage)
88
- if existing_storage.size_kw.nil?
89
- existing_storage.size_kw = new_storage.size_kw
90
- else
91
- existing_storage.size_kw = (existing_storage.size_kw || 0) + (new_storage.size_kw || 0)
92
- end
93
-
94
- if existing_storage.size_kw.nil?
95
- existing_storage.size_kwh = new_storage.size_kwh
96
- else
97
- existing_storage.size_kwh = (existing_storage.size_kwh || 0) + (new_storage.size_kwh || 0)
98
- end
99
-
100
- return existing_storage
101
- end
102
- end
103
- end
104
- end
105
- end
@@ -1,284 +0,0 @@
1
- # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
- # contributors. All rights reserved.
4
- #
5
- # Redistribution and use in source and binary forms, with or without modification,
6
- # are permitted provided that the following conditions are met:
7
- #
8
- # Redistributions of source code must retain the above copyright notice, this list
9
- # of conditions and the following disclaimer.
10
- #
11
- # Redistributions in binary form must reproduce the above copyright notice, this
12
- # list of conditions and the following disclaimer in the documentation and/or other
13
- # materials provided with the distribution.
14
- #
15
- # Neither the name of the copyright holder nor the names of its contributors may be
16
- # used to endorse or promote products derived from this software without specific
17
- # prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
- # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
- # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
- # OF THE POSSIBILITY OF SUCH DAMAGE.
29
- # *********************************************************************************
30
-
31
- require 'csv'
32
- require 'pathname'
33
- require 'json-schema'
34
- require 'urbanopt/scenario/default_reports/validator'
35
- require 'urbanopt/scenario/default_reports/logger'
36
-
37
- module URBANopt
38
- module Scenario
39
- module DefaultReports
40
- ##
41
- # TimeseriesCSV include timesries reults reported in a CSV file.
42
- ##
43
- class TimeseriesCSV
44
- attr_accessor :path, :first_report_datetime, :column_names #:nodoc:
45
-
46
- ##
47
- # TimeseriesCSV class initializes timeseries csv attributes: +:path+ , +:first_report_datetime+ , +:column_names+
48
- ##
49
- # +hash+ - _Hash_ - A hash which may contain a deserialized timeseries_csv.
50
- ##
51
- def initialize(hash = {})
52
- hash.delete_if { |k, v| v.nil? }
53
- hash = defaults.merge(hash)
54
-
55
- @run_dir = ''
56
-
57
- @path = hash[:path]
58
- @first_report_datetime = hash[:first_report_datetime]
59
-
60
- # from scenario csv shema get required reults to be aggregated
61
- @required_column_names = load_scenario_csv_schema_headers
62
-
63
- @column_names = hash[:column_names]
64
- @column_names.delete_if { |x| !@required_column_names.include? x.split('(')[0] }
65
-
66
- # hash of column_name to array of values, does not get serialized to hash
67
- @mutex = Mutex.new
68
- @data = nil
69
-
70
- # initialize class variables @@validator and @@schema
71
- @@validator ||= Validator.new
72
- @@schema ||= @@validator.schema
73
-
74
- # initialize @@logger
75
- @@logger ||= URBANopt::Scenario::DefaultReports.logger
76
- end
77
-
78
- ##
79
- # load required scenario report csv headers from reports schema
80
- ##
81
- def load_scenario_csv_schema_headers
82
- # rubocop: disable Security/Open
83
- scenario_csv_schema = open(File.expand_path('../default_reports/schema/scenario_csv_columns.txt', File.dirname(__FILE__)))
84
- # rubocop: enable Security/Open
85
-
86
- scenario_csv_schema_headers = []
87
- File.readlines(scenario_csv_schema).each do |line|
88
- l = line.delete("\n")
89
- a = l.delete("\t")
90
- scenario_csv_schema_headers << a
91
- end
92
- return scenario_csv_schema_headers
93
- end
94
-
95
- ##
96
- # Assigns default values if values does not exist.
97
- ##
98
- def defaults
99
- hash = {}
100
- hash[:path] = nil
101
- hash[:column_names] = []
102
- return hash
103
- end
104
-
105
- ##
106
- # Gets run directory.
107
- ##
108
- # [parameters:]
109
- # +name+ - _String_ - The name of the scenario (+directory_name+).
110
- ##
111
- def run_dir_name(name)
112
- @run_dir = name
113
- end
114
-
115
- ##
116
- # Converts to a Hash equivalent for JSON serialization.
117
- ##
118
- # - Exclude attributes with nil values.
119
- # - Validate reporting_period hash properties against schema.
120
- ##
121
- def to_hash
122
- result = {}
123
- directory_path = Pathname.new File.expand_path(@run_dir.to_s, File.dirname(__FILE__)) if @run_dir
124
- csv_path = Pathname.new @path if @path
125
-
126
- relative_path = csv_path.to_s.sub(directory_path.to_s, '')
127
-
128
- result[:path] = relative_path if @path
129
- result[:first_report_datetime] = @first_report_datetime if @first_report_datetime
130
- result[:column_names] = @column_names if @column_names
131
-
132
- # validate timeseries_csv properties against schema
133
- if @@validator.validate(@@schema[:definitions][:TimeseriesCSV][:properties], result).any?
134
- raise "scenario_report properties does not match schema: #{@@validator.validate(@@schema[:definitions][:TimeseriesCSV][:properties], result)}"
135
- end
136
-
137
- return result
138
- end
139
-
140
- ##
141
- # Reloads data from the CSV file.
142
- ##
143
- def reload_data(new_data)
144
- @mutex.synchronize do
145
- @data = {}
146
- @column_names = []
147
- new_data.each do |row|
148
- if @column_names.empty?
149
- @column_names = row
150
- @column_names.each do |column_name|
151
- @data[column_name] = []
152
- end
153
- else
154
- row.each_with_index do |value, i|
155
- @data[@column_names[i]] << value.to_f
156
- end
157
- end
158
- end
159
- end
160
- end
161
-
162
- ##
163
- # Loads data from the CSV file.
164
- ##
165
- def load_data
166
- @mutex.synchronize do
167
- if @data.nil?
168
- @data = {}
169
- @column_names = []
170
- CSV.foreach(@path) do |row|
171
- if @column_names.empty?
172
- @column_names = row
173
- @column_names.each do |column_name|
174
- @data[column_name] = []
175
- end
176
- else
177
- row.each_with_index do |value, i|
178
- @data[@column_names[i]] << value
179
- end
180
- end
181
- end
182
- end
183
- end
184
- end
185
-
186
- ##
187
- # Gets data for each column name in the CSV file.
188
- ##
189
- # [parameters:]
190
- # +column_name+ - _String_ - The header of each column in the CSV file.
191
- ##
192
- def get_data(column_name)
193
- load_data
194
- return @data[column_name]
195
- end
196
-
197
- ##
198
- # Saves data to the the scenario report CSV file.
199
- ##
200
- # [parameters:]
201
- # +path+ - _String_ - The path of the scenario report CSV (default_scenario_report.csv).
202
- ##
203
- def save_data(path = nil)
204
- if path.nil?
205
- path = @path
206
- end
207
- File.open(path, 'w') do |f|
208
- f.puts @column_names.join(',')
209
- n = @data[@column_names[0]].size - 1
210
-
211
- (0..n).each do |i|
212
- line = []
213
- @column_names.each do |column_name|
214
- line << @data[column_name][i]
215
- end
216
- f.puts line.join(',')
217
- end
218
- begin
219
- f.fsync
220
- rescue StandardError
221
- f.flush
222
- end
223
- end
224
- end
225
-
226
- ##
227
- # Merges timeseries csv to each other.
228
- ##
229
- # - initialize first_report_datetime with the incoming first_report_datetime if its nil.
230
- # - checks if first_report_datetime are identical.
231
- # - merge the column names
232
- # - merge the column data
233
- ##
234
- # [parameters:]
235
- # +other+ - _TimeseriesCSV_ - An object of TimeseriesCSV class.
236
- ##
237
- def add_timeseries_csv(other)
238
- # initialize first_report_datetime with the incoming first_report_datetime if its nil.
239
- if @first_report_datetime.nil? || @first_report_datetime == ''
240
- @first_report_datetime = other.first_report_datetime
241
- end
242
-
243
- # checks if first_report_datetime are identical.
244
- if @first_report_datetime != other.first_report_datetime
245
- raise "first_report_datetime '#{@first_report_datetime}' does not match other.first_report_datetime '#{other.first_report_datetime}'"
246
- end
247
-
248
- # merge the column names
249
- @column_names = @column_names.concat(other.column_names).uniq
250
-
251
- # merge the column data
252
- other.column_names.each do |column_name|
253
- if !@column_names.include? column_name
254
- @column_names.push column_name
255
- end
256
-
257
- new_values = other.get_data(column_name)
258
-
259
- if @data.nil?
260
- @data = {}
261
- end
262
-
263
- current_values = @data[column_name]
264
-
265
- if current_values
266
- if current_values.size != new_values.size
267
- raise 'Values of different sizes in add_timeseries_csv'
268
- end
269
- new_values.each_with_index do |value, i|
270
- # aggregate all columns except Datime column
271
- if column_name != 'Datetime'
272
- new_values[i] = value.to_f + current_values[i].to_f
273
- end
274
- end
275
- @data[column_name] = new_values
276
- else
277
- @data[column_name] = new_values
278
- end
279
- end
280
- end
281
- end
282
- end
283
- end
284
- end