urbanopt-scenario 0.2.0.pre2 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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