urbanopt-scenario 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/.github/CONTRIBUTING.md +58 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
  5. data/.github/pull_request_template.md +23 -0
  6. data/.gitignore +26 -0
  7. data/.rdoc_options +36 -0
  8. data/.rspec +3 -0
  9. data/.rubocop.yml +10 -0
  10. data/.travis.yml +23 -0
  11. data/CHANGELOG.md +19 -0
  12. data/Gemfile +43 -0
  13. data/Jenkinsfile +10 -0
  14. data/LICENSE.md +27 -0
  15. data/RDOC_MAIN.md +39 -0
  16. data/README.md +39 -0
  17. data/Rakefile +51 -0
  18. data/deploy_docs.sh +5 -0
  19. data/doc_templates/LICENSE.md +27 -0
  20. data/doc_templates/README.md.erb +42 -0
  21. data/doc_templates/copyright_erb.txt +31 -0
  22. data/doc_templates/copyright_js.txt +4 -0
  23. data/doc_templates/copyright_ruby.txt +29 -0
  24. data/docs/.gitignore +3 -0
  25. data/docs/.vuepress/components/InnerJsonSchema.vue +84 -0
  26. data/docs/.vuepress/components/JsonSchema.vue +12 -0
  27. data/docs/.vuepress/components/ScenarioSchema.vue +12 -0
  28. data/docs/.vuepress/components/StaticLink.vue +8 -0
  29. data/docs/.vuepress/config.js +15 -0
  30. data/docs/.vuepress/highlight.js +8 -0
  31. data/docs/.vuepress/public/custom_rdoc_styles.css +74 -0
  32. data/docs/.vuepress/utils.js +17 -0
  33. data/docs/README.md +39 -0
  34. data/docs/package-lock.json +11817 -0
  35. data/docs/package.json +26 -0
  36. data/docs/schemas/scenario-schema.md +3 -0
  37. data/lib/change_log.rb +147 -0
  38. data/lib/measures/.rubocop.yml +5 -0
  39. data/lib/measures/default_feature_reports/LICENSE.md +27 -0
  40. data/lib/measures/default_feature_reports/README.md +56 -0
  41. data/lib/measures/default_feature_reports/README.md.erb +42 -0
  42. data/lib/measures/default_feature_reports/measure.rb +742 -0
  43. data/lib/measures/default_feature_reports/measure.xml +139 -0
  44. data/lib/measures/default_feature_reports/tests/USA_CO_Golden-NREL.724666_TMY3.epw +8768 -0
  45. data/lib/measures/default_feature_reports/tests/default_feature_reports_test.rb +238 -0
  46. data/lib/measures/default_feature_reports/tests/example_model.osm +4378 -0
  47. data/lib/urbanopt-scenario.rb +31 -0
  48. data/lib/urbanopt/scenario.rb +45 -0
  49. data/lib/urbanopt/scenario/default_reports.rb +40 -0
  50. data/lib/urbanopt/scenario/default_reports/construction_cost.rb +169 -0
  51. data/lib/urbanopt/scenario/default_reports/date.rb +97 -0
  52. data/lib/urbanopt/scenario/default_reports/distributed_generation.rb +187 -0
  53. data/lib/urbanopt/scenario/default_reports/end_use.rb +159 -0
  54. data/lib/urbanopt/scenario/default_reports/end_uses.rb +140 -0
  55. data/lib/urbanopt/scenario/default_reports/feature_report.rb +213 -0
  56. data/lib/urbanopt/scenario/default_reports/generator.rb +92 -0
  57. data/lib/urbanopt/scenario/default_reports/location.rb +99 -0
  58. data/lib/urbanopt/scenario/default_reports/logger.rb +44 -0
  59. data/lib/urbanopt/scenario/default_reports/program.rb +261 -0
  60. data/lib/urbanopt/scenario/default_reports/reporting_period.rb +298 -0
  61. data/lib/urbanopt/scenario/default_reports/scenario_report.rb +300 -0
  62. data/lib/urbanopt/scenario/default_reports/schema/README.md +34 -0
  63. data/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt +13 -0
  64. data/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json +830 -0
  65. data/lib/urbanopt/scenario/default_reports/solar_pv.rb +92 -0
  66. data/lib/urbanopt/scenario/default_reports/storage.rb +105 -0
  67. data/lib/urbanopt/scenario/default_reports/timeseries_csv.rb +258 -0
  68. data/lib/urbanopt/scenario/default_reports/validator.rb +97 -0
  69. data/lib/urbanopt/scenario/default_reports/wind.rb +92 -0
  70. data/lib/urbanopt/scenario/extension.rb +63 -0
  71. data/lib/urbanopt/scenario/logger.rb +42 -0
  72. data/lib/urbanopt/scenario/scenario_base.rb +79 -0
  73. data/lib/urbanopt/scenario/scenario_csv.rb +122 -0
  74. data/lib/urbanopt/scenario/scenario_datapoint_base.rb +162 -0
  75. data/lib/urbanopt/scenario/scenario_post_processor_base.rb +69 -0
  76. data/lib/urbanopt/scenario/scenario_post_processor_default.rb +98 -0
  77. data/lib/urbanopt/scenario/scenario_runner_base.rb +63 -0
  78. data/lib/urbanopt/scenario/scenario_runner_osw.rb +158 -0
  79. data/lib/urbanopt/scenario/simulation_dir_base.rb +90 -0
  80. data/lib/urbanopt/scenario/simulation_dir_osw.rb +261 -0
  81. data/lib/urbanopt/scenario/simulation_mapper_base.rb +47 -0
  82. data/lib/urbanopt/scenario/version.rb +35 -0
  83. data/urbanopt-scenario-gem.gemspec +38 -0
  84. metadata +251 -0
@@ -0,0 +1,92 @@
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
+
58
+ # initialize class variables @@validator and @@schema
59
+ @@validator ||= Validator.new
60
+ @@schema ||= @@validator.schema
61
+
62
+ # initialize @@logger
63
+ @@logger ||= URBANopt::Scenario::DefaultReports.logger
64
+ end
65
+
66
+ ##
67
+ # Convert to a Hash equivalent for JSON serialization
68
+ ##
69
+ def to_hash
70
+ result = {}
71
+
72
+ result[:size_kw] = @size_kw if @size_kw
73
+
74
+ return result
75
+ end
76
+
77
+ ##
78
+ # Merge PV systems
79
+ ##
80
+ def self.add_pv(existing_pv, new_pv)
81
+ if existing_pv.size_kw.nil? && new_pv.size_kw.nil?
82
+ existing_pv.size_kw = nil
83
+ else
84
+ existing_pv.size_kw = (existing_pv.size_kw || 0) + (new_pv.size_kw || 0)
85
+ end
86
+
87
+ return existing_pv
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,105 @@
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
@@ -0,0 +1,258 @@
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
+ @column_names = hash[:column_names]
60
+
61
+ # hash of column_name to array of values, does not get serialized to hash
62
+ @mutex = Mutex.new
63
+ @data = nil
64
+
65
+ # initialize class variables @@validator and @@schema
66
+ @@validator ||= Validator.new
67
+ @@schema ||= @@validator.schema
68
+
69
+ # initialize @@logger
70
+ @@logger ||= URBANopt::Scenario::DefaultReports.logger
71
+ end
72
+
73
+ ##
74
+ # Assigns default values if values does not exist.
75
+ ##
76
+ def defaults
77
+ hash = {}
78
+ hash[:path] = nil
79
+ hash[:column_names] = []
80
+ return hash
81
+ end
82
+
83
+ ##
84
+ # Gets run directory.
85
+ ##
86
+ # [parameters:]
87
+ # +name+ - _String_ - The name of the scenario (+directory_name+).
88
+ ##
89
+ def run_dir_name(name)
90
+ @run_dir = name
91
+ end
92
+
93
+ ##
94
+ # Converts to a Hash equivalent for JSON serialization.
95
+ ##
96
+ # - Exclude attributes with nil values.
97
+ # - Validate reporting_period hash properties against schema.
98
+ ##
99
+ def to_hash
100
+ result = {}
101
+ directory_path = Pathname.new File.expand_path(@run_dir.to_s, File.dirname(__FILE__)) if @run_dir
102
+ csv_path = Pathname.new @path if @path
103
+
104
+ relative_path = csv_path.to_s.sub(directory_path.to_s, '')
105
+
106
+ result[:path] = relative_path if @path
107
+ result[:first_report_datetime] = @first_report_datetime if @first_report_datetime
108
+ result[:column_names] = @column_names if @column_names
109
+
110
+ # validate timeseries_csv properties against schema
111
+ if @@validator.validate(@@schema[:definitions][:TimeseriesCSV][:properties], result).any?
112
+ raise "scenario_report properties does not match schema: #{@@validator.validate(@@schema[:definitions][:TimeseriesCSV][:properties], result)}"
113
+ end
114
+
115
+ return result
116
+ end
117
+
118
+ ##
119
+ # Reloads data from the CSV file.
120
+ ##
121
+ def reload_data(new_data)
122
+ @mutex.synchronize do
123
+ @data = {}
124
+ @column_names = []
125
+ new_data.each do |row|
126
+ if @column_names.empty?
127
+ @column_names = row
128
+ @column_names.each do |column_name|
129
+ @data[column_name] = []
130
+ end
131
+ else
132
+ row.each_with_index do |value, i|
133
+ @data[@column_names[i]] << value.to_f
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ ##
141
+ # Loads data from the CSV file.
142
+ ##
143
+ def load_data
144
+ @mutex.synchronize do
145
+ if @data.nil?
146
+ @data = {}
147
+ @column_names = []
148
+ CSV.foreach(@path) do |row|
149
+ if @column_names.empty?
150
+ @column_names = row
151
+ @column_names.each do |column_name|
152
+ @data[column_name] = []
153
+ end
154
+ else
155
+ row.each_with_index do |value, i|
156
+ @data[@column_names[i]] << value.to_f
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+
164
+ ##
165
+ # Gets data for each column name in the CSV file.
166
+ ##
167
+ # [parameters:]
168
+ # +column_name+ - _String_ - The header of each column in the CSV file.
169
+ ##
170
+ def get_data(column_name)
171
+ load_data
172
+ return @data[column_name]
173
+ end
174
+
175
+ ##
176
+ # Saves data to the the scenario report CSV file.
177
+ ##
178
+ # [parameters:]
179
+ # +path+ - _String_ - The path of the scenario report CSV (default_scenario_report.csv).
180
+ ##
181
+ def save_data(path = nil)
182
+ if path.nil?
183
+ path = @path
184
+ end
185
+ File.open(path, 'w') do |f|
186
+ f.puts @column_names.join(',')
187
+ n = @data[@column_names[0]].size - 1
188
+
189
+ (0..n).each do |i|
190
+ line = []
191
+ @column_names.each do |column_name|
192
+ line << @data[column_name][i]
193
+ end
194
+ f.puts line.join(',')
195
+ end
196
+ begin
197
+ f.fsync
198
+ rescue StandardError
199
+ f.flush
200
+ end
201
+ end
202
+ end
203
+
204
+ ##
205
+ # Merges timeseries csv to each other.
206
+ ##
207
+ # - initialize first_report_datetime with the incoming first_report_datetime if its nil.
208
+ # - checks if first_report_datetime are identical.
209
+ # - merge the column names
210
+ # - merge the column data
211
+ ##
212
+ # [parameters:]
213
+ # +other+ - _TimeseriesCSV_ - An object of TimeseriesCSV class.
214
+ ##
215
+ def add_timeseries_csv(other)
216
+ # initialize first_report_datetime with the incoming first_report_datetime if its nil.
217
+ if @first_report_datetime.nil?
218
+ @first_report_datetime = other.first_report_datetime
219
+ end
220
+
221
+ # checks if first_report_datetime are identical.
222
+ if @first_report_datetime != other.first_report_datetime
223
+ raise "first_report_datetime '#{@first_report_datetime}' does not match other.first_report_datetime '#{other.first_report_datetime}'"
224
+ end
225
+
226
+ # merge the column names
227
+ @column_names = @column_names.concat(other.column_names).uniq
228
+
229
+ # merge the column data
230
+ other.column_names.each do |column_name|
231
+ if !@column_names.include? column_name
232
+ @column_names.push column_name
233
+ end
234
+
235
+ new_values = other.get_data(column_name)
236
+
237
+ if @data.nil?
238
+ @data = {}
239
+ end
240
+
241
+ current_values = @data[column_name]
242
+ if current_values
243
+ if current_values.size != new_values.size
244
+ raise 'Values of different sizes in add_timeseries_csv'
245
+ end
246
+ new_values.each_with_index do |value, i|
247
+ new_values[i] = value + current_values[i]
248
+ end
249
+ @data[column_name] = new_values
250
+ else
251
+ @data[column_name] = new_values
252
+ end
253
+ end
254
+ end
255
+ end
256
+ end
257
+ end
258
+ end