openstudio-analysis 0.1.16 → 0.1.17
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.
- checksums.yaml +4 -4
- data/lib/openstudio/analysis/server_api.rb +59 -62
- data/lib/openstudio/analysis/translator/excel.rb +186 -189
- data/lib/openstudio/analysis/version.rb +1 -1
- data/lib/openstudio/helpers/string.rb +4 -5
- data/spec/files/analysis/medium_office.json +192 -192
- data/spec/files/analysis/medium_office.zip +0 -0
- data/spec/files/export/analysis/Kats model v2.json +16 -16
- data/spec/files/export/analysis/Kats model v2.zip +0 -0
- data/spec/files/export/analysis/discrete_dynamic_seed.json +16 -16
- data/spec/files/export/analysis/discrete_dynamic_seed.zip +0 -0
- data/spec/files/export/analysis/discrete_seed.json +91 -91
- data/spec/files/export/analysis/discrete_seed.zip +0 -0
- data/spec/files/export/analysis/output_vars.json +83 -83
- data/spec/files/export/analysis/output_vars.zip +0 -0
- data/spec/files/export/analysis/small_seed.json +83 -83
- data/spec/files/export/analysis/small_seed.zip +0 -0
- data/spec/files/measures/IncreaseInsulationRValueForRoofs/measure.rb +372 -375
- data/spec/openstudio/analysis/server_api_spec.rb +6 -6
- data/spec/openstudio/analysis/translator/excel_spec.rb +182 -188
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi-create-a-new-localhost-instance.65.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi-create-a-new-localhost-instance.66.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi-create-a-new-localhost-instance.67.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi-test-not-localhost.65.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi-test-not-localhost.66.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi-test-not-localhost.67.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi.65.xml +7 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi.66.xml +7 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi.67.xml +7 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-discrete-variables.23.xml +18 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-discrete-variables.24.xml +18 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-discrete-variables.25.xml +18 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-discrete-with-dynamic-columns.7.xml +17 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-discrete-with-dynamic-columns.8.xml +17 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-discrete-with-dynamic-columns.9.xml +17 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-no-variables-defined.65.xml +20 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-no-variables-defined.66.xml +20 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-no-variables-defined.67.xml +20 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-proxy-setup-with-user.31.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-proxy-setup-with-user.32.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-proxy-setup-with-user.33.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-proxy-setup.37.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-proxy-setup.38.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-proxy-setup.39.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-setup-output-variables.17.xml +36 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-setup-output-variables.18.xml +36 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-setup-output-variables.19.xml +36 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-setup-version-0-1-9.14.xml +21 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-setup-version-0-1-9.15.xml +21 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-setup-version-0-1-9.16.xml +21 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-incomplete-variables.65.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-incomplete-variables.66.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-incomplete-variables.67.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-variables-should-not-validate.65.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-variables-should-not-validate.66.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-variables-should-not-validate.67.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-variables.65.xml +23 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-variables.66.xml +23 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-variables.67.xml +23 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-with-with-repeated-variable-names.65.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-with-with-repeated-variable-names.66.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-with-with-repeated-variable-names.67.xml +9 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-1-10.14.xml +13 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-1-10.15.xml +13 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-1-10.16.xml +13 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-2-0-simple.0.xml +19 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-2-0-simple.1.xml +19 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-2-0-simple.xml +19 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-2-0.0.xml +32 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-2-0.1.xml +32 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-2-0.2.xml +32 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel.65.xml +7 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel.66.xml +7 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel.67.xml +7 -0
- data/spec/spec_helper.rb +1 -3
- metadata +127 -19
|
@@ -30,10 +30,10 @@ module OpenStudio
|
|
|
30
30
|
|
|
31
31
|
@xls = nil
|
|
32
32
|
# try to read the spreadsheet as a roo object
|
|
33
|
-
if File.
|
|
33
|
+
if File.exist?(@xls_filename)
|
|
34
34
|
@xls = Roo::Spreadsheet.open(@xls_filename)
|
|
35
35
|
else
|
|
36
|
-
|
|
36
|
+
fail "File #{@xls_filename} does not exist"
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
# Initialize some other instance variables
|
|
@@ -45,8 +45,8 @@ module OpenStudio
|
|
|
45
45
|
@weather_files = []
|
|
46
46
|
@models = []
|
|
47
47
|
@other_files = []
|
|
48
|
-
@export_path =
|
|
49
|
-
@measure_path =
|
|
48
|
+
@export_path = './export'
|
|
49
|
+
@measure_path = './measures'
|
|
50
50
|
@number_of_samples = 0 # todo: remove this
|
|
51
51
|
@problem = {}
|
|
52
52
|
@algorithm = {}
|
|
@@ -56,46 +56,46 @@ module OpenStudio
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def process
|
|
59
|
-
@setup = parse_setup
|
|
59
|
+
@setup = parse_setup
|
|
60
60
|
|
|
61
61
|
@version = Semantic::Version.new @version
|
|
62
|
-
|
|
62
|
+
fail "Spreadsheet version #{@version} is no longer supported. Please upgrade your spreadsheet to at least 0.1.9" if @version < '0.1.9'
|
|
63
63
|
|
|
64
|
-
@variables = parse_variables
|
|
64
|
+
@variables = parse_variables
|
|
65
65
|
|
|
66
|
-
@outputs = parse_outputs
|
|
66
|
+
@outputs = parse_outputs
|
|
67
67
|
|
|
68
|
-
# call validate to make sure everything that is needed exists (i.e. directories)
|
|
69
|
-
validate_analysis
|
|
68
|
+
# call validate to make sure everything that is needed exists (i.e. directories)
|
|
69
|
+
validate_analysis
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
# Save off the legacy format of the JSON file
|
|
73
73
|
def save_variable_json(filename)
|
|
74
|
-
FileUtils.rm_f(filename) if File.
|
|
74
|
+
FileUtils.rm_f(filename) if File.exist?(filename)
|
|
75
75
|
File.open(filename, 'w') { |f| f << JSON.pretty_generate(@variables) }
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
def validate_analysis
|
|
79
79
|
# Setup the paths and do some error checking
|
|
80
|
-
|
|
80
|
+
fail "Measures directory '#{@measure_path}' does not exist" unless Dir.exist?(@measure_path)
|
|
81
81
|
|
|
82
82
|
@models.uniq!
|
|
83
|
-
|
|
83
|
+
fail 'No seed models defined in spreadsheet' if @models.empty?
|
|
84
84
|
|
|
85
85
|
@models.each do |model|
|
|
86
|
-
|
|
86
|
+
fail "Seed model does not exist: #{model[:path]}" unless File.exist?(model[:path])
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
@weather_files.uniq!
|
|
90
|
-
|
|
90
|
+
fail 'No weather files found based on what is in the spreadsheet' if @weather_files.empty?
|
|
91
91
|
|
|
92
92
|
@weather_files.each do |wf|
|
|
93
|
-
|
|
93
|
+
fail "Weather file does not exist: #{wf}" unless File.exist?(wf)
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
# This can be a directory as well
|
|
97
97
|
@other_files.each do |of|
|
|
98
|
-
|
|
98
|
+
fail "Other files do not exist for: #{of[:path]}" unless File.exist?(of[:path])
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
FileUtils.mkdir_p(@export_path)
|
|
@@ -116,31 +116,30 @@ module OpenStudio
|
|
|
116
116
|
# check something
|
|
117
117
|
else # must be an integer or double
|
|
118
118
|
if variable['distribution']['type'] == 'discrete_uncertain'
|
|
119
|
-
if variable['distribution']['discrete_values'].nil? || variable['distribution']['discrete_values'] ==
|
|
120
|
-
|
|
119
|
+
if variable['distribution']['discrete_values'].nil? || variable['distribution']['discrete_values'] == ''
|
|
120
|
+
fail "Variable #{measure['name']}:#{variable['name']} needs discrete values"
|
|
121
121
|
end
|
|
122
122
|
else
|
|
123
|
-
if variable['distribution']['mean'].nil? || variable['distribution']['mean'] ==
|
|
124
|
-
|
|
123
|
+
if variable['distribution']['mean'].nil? || variable['distribution']['mean'] == ''
|
|
124
|
+
fail "Variable #{measure['name']}:#{variable['name']} must have a mean"
|
|
125
125
|
end
|
|
126
|
-
if variable['distribution']['stddev'].nil? || variable['distribution']['stddev'] ==
|
|
127
|
-
|
|
126
|
+
if variable['distribution']['stddev'].nil? || variable['distribution']['stddev'] == ''
|
|
127
|
+
fail "Variable #{measure['name']}:#{variable['name']} must have a stddev"
|
|
128
128
|
end
|
|
129
129
|
end
|
|
130
130
|
|
|
131
|
-
if variable['distribution']['mean'].nil? || variable['distribution']['mean'] ==
|
|
132
|
-
|
|
131
|
+
if variable['distribution']['mean'].nil? || variable['distribution']['mean'] == ''
|
|
132
|
+
fail "Variable #{measure['name']}:#{variable['name']} must have a mean/mode"
|
|
133
133
|
end
|
|
134
|
-
if variable['distribution']['min'].nil? || variable['distribution']['min'] ==
|
|
135
|
-
|
|
134
|
+
if variable['distribution']['min'].nil? || variable['distribution']['min'] == ''
|
|
135
|
+
fail "Variable #{measure['name']}:#{variable['name']} must have a minimum"
|
|
136
136
|
end
|
|
137
|
-
if variable['distribution']['max'].nil? || variable['distribution']['max'] ==
|
|
138
|
-
|
|
137
|
+
if variable['distribution']['max'].nil? || variable['distribution']['max'] == ''
|
|
138
|
+
fail "Variable #{measure['name']}:#{variable['name']} must have a maximum"
|
|
139
139
|
end
|
|
140
140
|
if variable['distribution']['min'] > variable['distribution']['max']
|
|
141
|
-
|
|
141
|
+
fail "Variable min is greater than variable max for #{measure['name']}:#{variable['name']}"
|
|
142
142
|
end
|
|
143
|
-
|
|
144
143
|
|
|
145
144
|
end
|
|
146
145
|
elsif variable['method'] == 'pivot'
|
|
@@ -151,9 +150,9 @@ module OpenStudio
|
|
|
151
150
|
end
|
|
152
151
|
end
|
|
153
152
|
|
|
154
|
-
dupes = variable_names.
|
|
153
|
+
dupes = variable_names.select { |e| variable_names.count(e) > 1 }.uniq
|
|
155
154
|
if dupes.count > 0
|
|
156
|
-
|
|
155
|
+
fail "duplicate variable names found in list #{dupes.inspect}"
|
|
157
156
|
end
|
|
158
157
|
|
|
159
158
|
# most of the checks will raise a runtime exception, so this true will never be called
|
|
@@ -163,7 +162,7 @@ module OpenStudio
|
|
|
163
162
|
def create_analysis_hash
|
|
164
163
|
# save the format in the OpenStudio analysis json format template without
|
|
165
164
|
# the correct weather files or models
|
|
166
|
-
@template_json = translate_to_analysis_json_template
|
|
165
|
+
@template_json = translate_to_analysis_json_template
|
|
167
166
|
|
|
168
167
|
@template_json
|
|
169
168
|
end
|
|
@@ -171,7 +170,7 @@ module OpenStudio
|
|
|
171
170
|
def save_analysis
|
|
172
171
|
@template_json = create_analysis_hash
|
|
173
172
|
|
|
174
|
-
#validate_template_json
|
|
173
|
+
# validate_template_json
|
|
175
174
|
|
|
176
175
|
# iterate over each model and save the zip and json
|
|
177
176
|
@models.each do |model|
|
|
@@ -183,7 +182,7 @@ module OpenStudio
|
|
|
183
182
|
# TODO: move this into a new class that helps construct this file
|
|
184
183
|
def translate_to_analysis_json_template
|
|
185
184
|
# Load in the templates for constructing the JSON file
|
|
186
|
-
template_root = File.join(File.dirname(__FILE__),
|
|
185
|
+
template_root = File.join(File.dirname(__FILE__), '../../templates')
|
|
187
186
|
analysis_template = ERB.new(File.open("#{template_root}/analysis.json.erb", 'r').read)
|
|
188
187
|
workflow_template = ERB.new(File.open("#{template_root}/workflow_item.json.erb", 'r').read)
|
|
189
188
|
uncertain_variable_template = ERB.new(File.open("#{template_root}/uncertain_variable.json.erb", 'r').read)
|
|
@@ -221,30 +220,30 @@ module OpenStudio
|
|
|
221
220
|
if @variable['variable_type'] == 'argument'
|
|
222
221
|
ag = nil
|
|
223
222
|
if @variable['method'] == 'static'
|
|
224
|
-
|
|
225
|
-
|
|
223
|
+
unless @variable['distribution']['static_value']
|
|
224
|
+
fail 'can not have an argument that is not a static value defined in which to set the argument'
|
|
226
225
|
end
|
|
227
226
|
|
|
228
227
|
# add this as an argument
|
|
229
228
|
case @variable['type'].downcase
|
|
230
|
-
when
|
|
229
|
+
when 'double'
|
|
231
230
|
@static_value = @variable['distribution']['static_value'].to_f
|
|
232
|
-
when
|
|
231
|
+
when 'integer'
|
|
233
232
|
@static_value = @variable['distribution']['static_value'].to_i
|
|
234
|
-
when
|
|
233
|
+
when 'string', 'choice'
|
|
235
234
|
@static_value = @variable['distribution']['static_value'].inspect
|
|
236
|
-
when
|
|
237
|
-
if @variable['distribution']['static_value'].downcase ==
|
|
235
|
+
when 'bool'
|
|
236
|
+
if @variable['distribution']['static_value'].downcase == 'true'
|
|
238
237
|
@static_value = true
|
|
239
238
|
else
|
|
240
239
|
@static_value = false
|
|
241
240
|
end
|
|
242
241
|
else
|
|
243
|
-
|
|
242
|
+
fail "Unknown variable type of #{@variable['type']}"
|
|
244
243
|
end
|
|
245
244
|
ag = JSON.parse(argument_template.result(get_binding))
|
|
246
245
|
end
|
|
247
|
-
|
|
246
|
+
fail "Argument '#{@variable['name']}' did not process. Most likely it did not have all parameters defined." if ag.nil?
|
|
248
247
|
wf['arguments'] << ag
|
|
249
248
|
else # must be a variable [either pivot or normal variable]
|
|
250
249
|
vr = nil
|
|
@@ -254,10 +253,10 @@ module OpenStudio
|
|
|
254
253
|
elsif @variable['method'] == 'lhs'
|
|
255
254
|
# TODO: remove enum and choice as this is not the variable type
|
|
256
255
|
if @variable['type'] == 'enum' || @variable['type'].downcase == 'choice'
|
|
257
|
-
@values_and_weights = @variable['distribution']['enumerations'].map { |v| {value: v} }.to_json
|
|
256
|
+
@values_and_weights = @variable['distribution']['enumerations'].map { |v| { value: v } }.to_json
|
|
258
257
|
vr = JSON.parse(discrete_uncertain_variable_template.result(get_binding))
|
|
259
258
|
elsif @variable['distribution']['type'] == 'discrete_uncertain'
|
|
260
|
-
#puts @variable.inspect
|
|
259
|
+
# puts @variable.inspect
|
|
261
260
|
weights = nil
|
|
262
261
|
if @variable['distribution']['discrete_weights'] && @variable['distribution']['discrete_weights'] != ''
|
|
263
262
|
weights = eval(@variable['distribution']['discrete_weights'])
|
|
@@ -272,10 +271,10 @@ module OpenStudio
|
|
|
272
271
|
end
|
|
273
272
|
|
|
274
273
|
if weights
|
|
275
|
-
|
|
276
|
-
@values_and_weights = values.zip(weights).map { |v, w| {value: v, weight: w} }.to_json
|
|
274
|
+
fail "Discrete variable #{@variable['name']} does not have equal length of values and weights" if values.size != weights.size
|
|
275
|
+
@values_and_weights = values.zip(weights).map { |v, w| { value: v, weight: w } }.to_json
|
|
277
276
|
else
|
|
278
|
-
@values_and_weights = values.map { |v| {value: v} }.to_json
|
|
277
|
+
@values_and_weights = values.map { |v| { value: v } }.to_json
|
|
279
278
|
end
|
|
280
279
|
|
|
281
280
|
if @variable['variable_type'] == 'pivot'
|
|
@@ -285,13 +284,13 @@ module OpenStudio
|
|
|
285
284
|
end
|
|
286
285
|
else
|
|
287
286
|
if @variable['variable_type'] == 'pivot'
|
|
288
|
-
|
|
287
|
+
fail 'Currently unable to pivot on continuous variables... stay tuned.'
|
|
289
288
|
else
|
|
290
289
|
vr = JSON.parse(uncertain_variable_template.result(get_binding))
|
|
291
290
|
end
|
|
292
291
|
end
|
|
293
292
|
end
|
|
294
|
-
|
|
293
|
+
fail 'variable was nil after processing' if vr.nil?
|
|
295
294
|
wf['variables'] << vr
|
|
296
295
|
end
|
|
297
296
|
end
|
|
@@ -310,29 +309,28 @@ module OpenStudio
|
|
|
310
309
|
binding
|
|
311
310
|
end
|
|
312
311
|
|
|
313
|
-
|
|
314
312
|
# Package up the seed, weather files, and measures
|
|
315
313
|
def save_analysis_zip(model)
|
|
316
314
|
zipfile_name = "#{@export_path}/#{model[:name]}.zip"
|
|
317
|
-
FileUtils.rm_f(zipfile_name) if File.
|
|
315
|
+
FileUtils.rm_f(zipfile_name) if File.exist?(zipfile_name)
|
|
318
316
|
|
|
319
317
|
Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
|
|
320
318
|
@weather_files.each do |filename|
|
|
321
|
-
#puts " Adding #{filename}"
|
|
319
|
+
# puts " Adding #{filename}"
|
|
322
320
|
zipfile.add("./weather/#{File.basename(filename)}", filename)
|
|
323
321
|
end
|
|
324
322
|
|
|
325
323
|
Dir.glob("#{@measure_path}/**/*.rb").each do |measure|
|
|
326
|
-
next if measure.include?(
|
|
324
|
+
next if measure.include?('spec') # don't include the spec folders nor files
|
|
327
325
|
measure_name = measure.split(File::SEPARATOR).last(2).first
|
|
328
|
-
#puts " Adding ./measures/#{measure_name}/#{File.basename(measure)}"
|
|
326
|
+
# puts " Adding ./measures/#{measure_name}/#{File.basename(measure)}"
|
|
329
327
|
zipfile.add("./measures/#{measure_name}/#{File.basename(measure)}", measure)
|
|
330
328
|
end
|
|
331
329
|
|
|
332
|
-
#puts "Adding #{model[:path]}"
|
|
330
|
+
# puts "Adding #{model[:path]}"
|
|
333
331
|
zipfile.add("./seed/#{File.basename(model[:path])}", model[:path])
|
|
334
332
|
|
|
335
|
-
#puts "Adding in other files #{@other_files.inspect}"
|
|
333
|
+
# puts "Adding in other files #{@other_files.inspect}"
|
|
336
334
|
@other_files.each do |others|
|
|
337
335
|
Dir[File.join(others[:path], '**', '**')].each do |file|
|
|
338
336
|
zipfile.add(file.sub(others[:path], "./lib/#{others[:lib_zip_name]}/"), file)
|
|
@@ -356,14 +354,14 @@ module OpenStudio
|
|
|
356
354
|
end
|
|
357
355
|
|
|
358
356
|
json_file_name = "#{@export_path}/#{model[:name]}.json"
|
|
359
|
-
FileUtils.rm_f(json_file_name) if File.
|
|
357
|
+
FileUtils.rm_f(json_file_name) if File.exist?(json_file_name)
|
|
360
358
|
|
|
361
|
-
File.open("#{@export_path}/#{model[:name]}.json",
|
|
359
|
+
File.open("#{@export_path}/#{model[:name]}.json", 'w') { |f| f << JSON.pretty_generate(analysis_json) }
|
|
362
360
|
end
|
|
363
361
|
|
|
364
362
|
# parse_setup will pull out the data on the "setup" tab and store it in memory for later use
|
|
365
|
-
def parse_setup
|
|
366
|
-
rows = @xls.sheet('Setup').parse
|
|
363
|
+
def parse_setup
|
|
364
|
+
rows = @xls.sheet('Setup').parse
|
|
367
365
|
b_settings = false
|
|
368
366
|
b_run_setup = false
|
|
369
367
|
b_problem_setup = false
|
|
@@ -373,7 +371,7 @@ module OpenStudio
|
|
|
373
371
|
b_other_libs = false
|
|
374
372
|
|
|
375
373
|
rows.each do |row|
|
|
376
|
-
if row[0] ==
|
|
374
|
+
if row[0] == 'Settings'
|
|
377
375
|
b_settings = true
|
|
378
376
|
b_run_setup = false
|
|
379
377
|
b_problem_setup = false
|
|
@@ -382,7 +380,7 @@ module OpenStudio
|
|
|
382
380
|
b_models = false
|
|
383
381
|
b_other_libs = false
|
|
384
382
|
next
|
|
385
|
-
elsif row[0] ==
|
|
383
|
+
elsif row[0] == 'Running Setup'
|
|
386
384
|
b_settings = false
|
|
387
385
|
b_run_setup = true
|
|
388
386
|
b_problem_setup = false
|
|
@@ -391,7 +389,7 @@ module OpenStudio
|
|
|
391
389
|
b_models = false
|
|
392
390
|
b_other_libs = false
|
|
393
391
|
next
|
|
394
|
-
elsif row[0] ==
|
|
392
|
+
elsif row[0] == 'Problem Definition'
|
|
395
393
|
b_settings = false
|
|
396
394
|
b_run_setup = false
|
|
397
395
|
b_problem_setup = true
|
|
@@ -400,7 +398,7 @@ module OpenStudio
|
|
|
400
398
|
b_models = false
|
|
401
399
|
b_other_libs = false
|
|
402
400
|
next
|
|
403
|
-
elsif row[0] ==
|
|
401
|
+
elsif row[0] == 'Algorithm Setup'
|
|
404
402
|
b_settings = false
|
|
405
403
|
b_run_setup = false
|
|
406
404
|
b_problem_setup = false
|
|
@@ -409,7 +407,7 @@ module OpenStudio
|
|
|
409
407
|
b_models = false
|
|
410
408
|
b_other_libs = false
|
|
411
409
|
next
|
|
412
|
-
elsif row[0] ==
|
|
410
|
+
elsif row[0] == 'Weather Files'
|
|
413
411
|
b_settings = false
|
|
414
412
|
b_run_setup = false
|
|
415
413
|
b_problem_setup = false
|
|
@@ -418,7 +416,7 @@ module OpenStudio
|
|
|
418
416
|
b_models = false
|
|
419
417
|
b_other_libs = false
|
|
420
418
|
next
|
|
421
|
-
elsif row[0] ==
|
|
419
|
+
elsif row[0] == 'Models'
|
|
422
420
|
b_settings = false
|
|
423
421
|
b_run_setup = false
|
|
424
422
|
b_problem_setup = false
|
|
@@ -427,7 +425,7 @@ module OpenStudio
|
|
|
427
425
|
b_models = true
|
|
428
426
|
b_other_libs = false
|
|
429
427
|
next
|
|
430
|
-
elsif row[0] ==
|
|
428
|
+
elsif row[0] == 'Other Library Files'
|
|
431
429
|
b_settings = false
|
|
432
430
|
b_run_setup = false
|
|
433
431
|
b_problem_setup = false
|
|
@@ -441,23 +439,23 @@ module OpenStudio
|
|
|
441
439
|
next if row[0].nil?
|
|
442
440
|
|
|
443
441
|
if b_settings
|
|
444
|
-
@version = row[1].chomp if row[0] ==
|
|
442
|
+
@version = row[1].chomp if row[0] == 'Spreadsheet Version'
|
|
445
443
|
@settings["#{row[0].snake_case}"] = row[1] if row[0]
|
|
446
|
-
@cluster_name = @settings[
|
|
444
|
+
@cluster_name = @settings['cluster_name'].snake_case if @settings['cluster_name']
|
|
447
445
|
|
|
448
446
|
# type some of the values that we know
|
|
449
|
-
@settings[
|
|
447
|
+
@settings['proxy_port'] = @settings['proxy_port'].to_i if @settings['proxy_port']
|
|
450
448
|
elsif b_run_setup
|
|
451
|
-
@name = row[1].chomp if row[0] ==
|
|
449
|
+
@name = row[1].chomp if row[0] == 'Analysis Name'
|
|
452
450
|
@machine_name = @name.snake_case
|
|
453
|
-
@export_path = File.expand_path(File.join(@root_path, row[1])) if row[0] ==
|
|
454
|
-
@measure_path = File.expand_path(File.join(@root_path, row[1])) if row[0] ==
|
|
451
|
+
@export_path = File.expand_path(File.join(@root_path, row[1])) if row[0] == 'Export Directory'
|
|
452
|
+
@measure_path = File.expand_path(File.join(@root_path, row[1])) if row[0] == 'Measure Directory'
|
|
455
453
|
|
|
456
454
|
@run_setup["#{row[0].snake_case}"] = row[1] if row[0]
|
|
457
455
|
|
|
458
456
|
# type cast
|
|
459
|
-
@run_setup[
|
|
460
|
-
@run_setup[
|
|
457
|
+
@run_setup['allow_multiple_jobs'] = @run_setup['allow_multiple_jobs'].to_s.to_bool if @run_setup['allow_multiple_jobs']
|
|
458
|
+
@run_setup['use_server_as_worker'] = @run_setup['use_server_as_worker'].to_s.to_bool if @run_setup['use_server_as_worker']
|
|
461
459
|
|
|
462
460
|
elsif b_problem_setup
|
|
463
461
|
if row[0]
|
|
@@ -473,124 +471,123 @@ module OpenStudio
|
|
|
473
471
|
@algorithm["#{row[0].snake_case}"] = v
|
|
474
472
|
end
|
|
475
473
|
elsif b_weather_files
|
|
476
|
-
if row[0] ==
|
|
474
|
+
if row[0] == 'Weather File'
|
|
477
475
|
@weather_files += Dir.glob(File.expand_path(File.join(@root_path, row[1])))
|
|
478
476
|
end
|
|
479
477
|
elsif b_models
|
|
480
|
-
@models << {name: row[1], type: row[2], path: File.expand_path(File.join(@root_path, row[3]))}
|
|
478
|
+
@models << { name: row[1], type: row[2], path: File.expand_path(File.join(@root_path, row[3])) }
|
|
481
479
|
elsif b_other_libs
|
|
482
|
-
@other_files << {lib_zip_name: row[1], path: row[2]}
|
|
480
|
+
@other_files << { lib_zip_name: row[1], path: row[2] }
|
|
483
481
|
end
|
|
484
482
|
end
|
|
485
483
|
end
|
|
486
484
|
|
|
487
485
|
# parse_variables will parse the XLS spreadsheet and save the data into
|
|
488
|
-
# a higher level JSON file. The JSON file is historic and it should really
|
|
486
|
+
# a higher level JSON file. The JSON file is historic and it should really
|
|
489
487
|
# be omitted as an intermediate step
|
|
490
|
-
def parse_variables
|
|
491
|
-
|
|
488
|
+
def parse_variables
|
|
492
489
|
# clean remove whitespace and unicode chars
|
|
493
|
-
# The parse is a unique format (https://github.com/Empact/roo/blob/master/lib/roo/base.rb#L444)
|
|
490
|
+
# The parse is a unique format (https://github.com/Empact/roo/blob/master/lib/roo/base.rb#L444)
|
|
494
491
|
# If you add a new column and you want that variable in the hash, then you must add it here.
|
|
495
|
-
#rows = @xls.sheet('Variables').parse(:enabled => "# variable")
|
|
496
|
-
#puts rows.inspect
|
|
492
|
+
# rows = @xls.sheet('Variables').parse(:enabled => "# variable")
|
|
493
|
+
# puts rows.inspect
|
|
497
494
|
rows = nil
|
|
498
495
|
begin
|
|
499
|
-
if @version >=
|
|
500
|
-
rows = @xls.sheet('Variables').parse(:
|
|
501
|
-
:
|
|
502
|
-
:
|
|
503
|
-
:
|
|
504
|
-
:
|
|
505
|
-
:
|
|
506
|
-
:
|
|
507
|
-
:
|
|
508
|
-
:
|
|
509
|
-
:
|
|
510
|
-
:
|
|
511
|
-
:
|
|
512
|
-
:
|
|
513
|
-
:
|
|
514
|
-
:
|
|
515
|
-
:
|
|
516
|
-
:
|
|
517
|
-
:
|
|
518
|
-
:
|
|
519
|
-
:
|
|
520
|
-
:
|
|
521
|
-
:
|
|
522
|
-
elsif @version >=
|
|
523
|
-
rows = @xls.sheet('Variables').parse(:
|
|
524
|
-
:
|
|
525
|
-
:
|
|
526
|
-
:
|
|
527
|
-
:
|
|
528
|
-
:
|
|
529
|
-
:
|
|
530
|
-
:
|
|
531
|
-
:
|
|
532
|
-
:
|
|
533
|
-
:
|
|
534
|
-
:
|
|
535
|
-
:
|
|
536
|
-
:
|
|
537
|
-
:
|
|
538
|
-
:
|
|
539
|
-
:
|
|
540
|
-
:
|
|
541
|
-
:
|
|
542
|
-
:
|
|
543
|
-
:
|
|
544
|
-
elsif @version >=
|
|
545
|
-
rows = @xls.sheet('Variables').parse(:
|
|
546
|
-
:
|
|
547
|
-
:
|
|
548
|
-
:
|
|
549
|
-
:
|
|
550
|
-
:
|
|
551
|
-
:
|
|
552
|
-
:
|
|
553
|
-
:
|
|
554
|
-
:
|
|
555
|
-
:
|
|
556
|
-
:
|
|
557
|
-
:
|
|
496
|
+
if @version >= '0.2.0'
|
|
497
|
+
rows = @xls.sheet('Variables').parse(enabled: '# variable',
|
|
498
|
+
measure_name_or_var_type: 'type',
|
|
499
|
+
measure_file_name_or_var_display_name: 'parameter display name.*',
|
|
500
|
+
measure_file_name_directory: 'measure directory',
|
|
501
|
+
measure_type_or_parameter_name_in_measure: 'parameter name in measure',
|
|
502
|
+
sampling_method: 'sampling method',
|
|
503
|
+
variable_type: 'Variable Type',
|
|
504
|
+
units: 'units',
|
|
505
|
+
default_value: 'static.default value',
|
|
506
|
+
enums: 'enumerations',
|
|
507
|
+
min: 'min',
|
|
508
|
+
max: 'max',
|
|
509
|
+
mode: 'mean|mode',
|
|
510
|
+
stddev: 'std dev',
|
|
511
|
+
delta_x: 'delta.x',
|
|
512
|
+
discrete_values: 'discrete values',
|
|
513
|
+
discrete_weights: 'discrete weights',
|
|
514
|
+
distribution: 'distribution',
|
|
515
|
+
source: 'data source',
|
|
516
|
+
notes: 'notes',
|
|
517
|
+
relation_to_eui: 'typical var to eui relationship',
|
|
518
|
+
clean: true)
|
|
519
|
+
elsif @version >= '0.1.12' # add delta x
|
|
520
|
+
rows = @xls.sheet('Variables').parse(enabled: '# variable',
|
|
521
|
+
measure_name_or_var_type: 'type',
|
|
522
|
+
measure_file_name_or_var_display_name: 'parameter display name.*',
|
|
523
|
+
measure_type_or_parameter_name_in_measure: 'parameter name in measure',
|
|
524
|
+
sampling_method: 'sampling method',
|
|
525
|
+
variable_type: 'Variable Type',
|
|
526
|
+
units: 'units',
|
|
527
|
+
default_value: 'static.default value',
|
|
528
|
+
enums: 'enumerations',
|
|
529
|
+
min: 'min',
|
|
530
|
+
max: 'max',
|
|
531
|
+
mode: 'mean|mode',
|
|
532
|
+
stddev: 'std dev',
|
|
533
|
+
delta_x: 'delta.x',
|
|
534
|
+
discrete_values: 'discrete values',
|
|
535
|
+
discrete_weights: 'discrete weights',
|
|
536
|
+
distribution: 'distribution',
|
|
537
|
+
source: 'data source',
|
|
538
|
+
notes: 'notes',
|
|
539
|
+
relation_to_eui: 'typical var to eui relationship',
|
|
540
|
+
clean: true)
|
|
541
|
+
elsif @version >= '0.1.11' # add discrete variables
|
|
542
|
+
rows = @xls.sheet('Variables').parse(enabled: '# variable',
|
|
543
|
+
measure_name_or_var_type: 'type',
|
|
544
|
+
measure_file_name_or_var_display_name: 'parameter display name.*',
|
|
545
|
+
measure_type_or_parameter_name_in_measure: 'parameter name in measure',
|
|
546
|
+
sampling_method: 'sampling method',
|
|
547
|
+
variable_type: 'Variable Type',
|
|
548
|
+
units: 'units',
|
|
549
|
+
default_value: 'static.default value',
|
|
550
|
+
enums: 'enumerations',
|
|
551
|
+
min: 'min',
|
|
552
|
+
max: 'max',
|
|
553
|
+
mode: 'mean|mode',
|
|
554
|
+
stddev: 'std dev',
|
|
558
555
|
#:delta_x => 'delta.x',
|
|
559
|
-
:
|
|
560
|
-
:
|
|
561
|
-
:
|
|
562
|
-
:
|
|
563
|
-
:
|
|
564
|
-
:
|
|
565
|
-
:
|
|
556
|
+
discrete_values: 'discrete values',
|
|
557
|
+
discrete_weights: 'discrete weights',
|
|
558
|
+
distribution: 'distribution',
|
|
559
|
+
source: 'data source',
|
|
560
|
+
notes: 'notes',
|
|
561
|
+
relation_to_eui: 'typical var to eui relationship',
|
|
562
|
+
clean: true)
|
|
566
563
|
else
|
|
567
|
-
rows = @xls.sheet('Variables').parse(:
|
|
568
|
-
:
|
|
569
|
-
:
|
|
570
|
-
:
|
|
571
|
-
:
|
|
572
|
-
:
|
|
573
|
-
:
|
|
574
|
-
:
|
|
575
|
-
:
|
|
576
|
-
:
|
|
577
|
-
:
|
|
578
|
-
:
|
|
579
|
-
:
|
|
564
|
+
rows = @xls.sheet('Variables').parse(enabled: '# variable',
|
|
565
|
+
measure_name_or_var_type: 'type',
|
|
566
|
+
measure_file_name_or_var_display_name: 'parameter display name.*',
|
|
567
|
+
measure_type_or_parameter_name_in_measure: 'parameter name in measure',
|
|
568
|
+
sampling_method: 'sampling method',
|
|
569
|
+
variable_type: 'Variable Type',
|
|
570
|
+
units: 'units',
|
|
571
|
+
default_value: 'static.default value',
|
|
572
|
+
enums: 'enumerations',
|
|
573
|
+
min: 'min',
|
|
574
|
+
max: 'max',
|
|
575
|
+
mode: 'mean|mode',
|
|
576
|
+
stddev: 'std dev',
|
|
580
577
|
#:delta_x => 'delta.x',
|
|
581
578
|
#:discrete_values => 'discrete values',
|
|
582
579
|
#:discrete_weights => 'discrete weights',
|
|
583
|
-
:
|
|
584
|
-
:
|
|
585
|
-
:
|
|
586
|
-
:
|
|
587
|
-
:
|
|
580
|
+
distribution: 'distribution',
|
|
581
|
+
source: 'data source',
|
|
582
|
+
notes: 'notes',
|
|
583
|
+
relation_to_eui: 'typical var to eui relationship',
|
|
584
|
+
clean: true)
|
|
588
585
|
end
|
|
589
586
|
rescue Exception => e
|
|
590
587
|
raise "#{e.message} with Spreadsheet #{@xls_filename} with Version #{@version} "
|
|
591
588
|
end
|
|
592
589
|
|
|
593
|
-
|
|
590
|
+
fail "Could not find the sheet name 'Variables' in excel file #{@root_path}" unless rows
|
|
594
591
|
|
|
595
592
|
# map the data to another hash that is more easily processed
|
|
596
593
|
data = {}
|
|
@@ -603,7 +600,7 @@ module OpenStudio
|
|
|
603
600
|
rows.each do |row|
|
|
604
601
|
icnt += 1
|
|
605
602
|
next if icnt <= 1 # skip the first line after the header
|
|
606
|
-
#puts "Parsing line: #{icnt}:#{row}"
|
|
603
|
+
# puts "Parsing line: #{icnt}:#{row}"
|
|
607
604
|
|
|
608
605
|
# check if we are a measure - nil means that the cell was blank
|
|
609
606
|
if row[:enabled].nil?
|
|
@@ -613,9 +610,9 @@ module OpenStudio
|
|
|
613
610
|
var = {}
|
|
614
611
|
var['variable_type'] = row[:measure_name_or_var_type]
|
|
615
612
|
var['display_name'] = row[:measure_file_name_or_var_display_name]
|
|
616
|
-
var['machine_name'] = row[:measure_file_name_or_var_display_name].downcase.strip.gsub(
|
|
613
|
+
var['machine_name'] = row[:measure_file_name_or_var_display_name].downcase.strip.gsub('-', '_').gsub(' ', '_').strip
|
|
617
614
|
var['name'] = row[:measure_type_or_parameter_name_in_measure]
|
|
618
|
-
var['index'] = variable_index #order of the variable (not sure of its need)
|
|
615
|
+
var['index'] = variable_index # order of the variable (not sure of its need)
|
|
619
616
|
|
|
620
617
|
var['method'] = row[:sampling_method]
|
|
621
618
|
var['type'] = row[:variable_type] ? row[:variable_type].downcase : row[:variable_type]
|
|
@@ -623,12 +620,12 @@ module OpenStudio
|
|
|
623
620
|
|
|
624
621
|
var['distribution'] = {}
|
|
625
622
|
|
|
626
|
-
#parse the choices/enums
|
|
623
|
+
# parse the choices/enums
|
|
627
624
|
if var['type'] == 'enum' || var['type'] == 'choice' # this is now a choice
|
|
628
|
-
var['distribution']['enumerations'] = row[:enums].gsub(
|
|
625
|
+
var['distribution']['enumerations'] = row[:enums].gsub('|', '').split(',').map { |v| v.strip }
|
|
629
626
|
elsif var['type'] == 'bool'
|
|
630
627
|
var['distribution']['enumerations'] = []
|
|
631
|
-
var['distribution']['enumerations'] << 'true' #todo: should this be a real bool?
|
|
628
|
+
var['distribution']['enumerations'] << 'true' # todo: should this be a real bool?
|
|
632
629
|
var['distribution']['enumerations'] << 'false'
|
|
633
630
|
end
|
|
634
631
|
|
|
@@ -655,15 +652,15 @@ module OpenStudio
|
|
|
655
652
|
variable_index = 0
|
|
656
653
|
data['data'][measure_index] = {}
|
|
657
654
|
|
|
658
|
-
#generate name id
|
|
659
|
-
#todo: put this into a logger. puts "Parsing measure #{row[1]}"
|
|
655
|
+
# generate name id
|
|
656
|
+
# todo: put this into a logger. puts "Parsing measure #{row[1]}"
|
|
660
657
|
display_name = row[:measure_name_or_var_type]
|
|
661
|
-
measure_name = display_name.downcase.strip.gsub(
|
|
658
|
+
measure_name = display_name.downcase.strip.gsub('-', '_').gsub(' ', '_')
|
|
662
659
|
data['data'][measure_index]['display_name'] = display_name
|
|
663
660
|
data['data'][measure_index]['name'] = measure_name
|
|
664
|
-
data['data'][measure_index]['enabled'] = row[:enabled] ==
|
|
661
|
+
data['data'][measure_index]['enabled'] = row[:enabled] == 'TRUE' ? true : false
|
|
665
662
|
data['data'][measure_index]['measure_file_name'] = row[:measure_file_name_or_var_display_name]
|
|
666
|
-
data['data'][measure_index]['measure_file_name_directory'] = row[:measure_file_name_directory] ?
|
|
663
|
+
data['data'][measure_index]['measure_file_name_directory'] = row[:measure_file_name_directory] ?
|
|
667
664
|
row[:measure_file_name_directory] : row[:measure_file_name_or_var_display_name].underscore
|
|
668
665
|
data['data'][measure_index]['measure_type'] = row[:measure_type_or_parameter_name_in_measure]
|
|
669
666
|
data['data'][measure_index]['version'] = @version_id
|
|
@@ -672,15 +669,15 @@ module OpenStudio
|
|
|
672
669
|
end
|
|
673
670
|
end
|
|
674
671
|
|
|
675
|
-
#puts data.inspect
|
|
672
|
+
# puts data.inspect
|
|
676
673
|
data
|
|
677
674
|
end
|
|
678
675
|
|
|
679
|
-
def parse_outputs
|
|
680
|
-
rows = @xls.sheet('Outputs').parse
|
|
676
|
+
def parse_outputs
|
|
677
|
+
rows = @xls.sheet('Outputs').parse
|
|
681
678
|
|
|
682
|
-
|
|
683
|
-
|
|
679
|
+
unless rows
|
|
680
|
+
fail "Could not find the sheet name 'Outputs' in excel file #{@root_path}"
|
|
684
681
|
end
|
|
685
682
|
|
|
686
683
|
data = {}
|
|
@@ -700,7 +697,7 @@ module OpenStudio
|
|
|
700
697
|
var['display_name'] = row[0].strip
|
|
701
698
|
var['name'] = row[1]
|
|
702
699
|
var['units'] = row[2]
|
|
703
|
-
var['objective_function'] = row[3].downcase ==
|
|
700
|
+
var['objective_function'] = row[3].downcase == 'true' ? true : false
|
|
704
701
|
if var['objective_function'] == true
|
|
705
702
|
@algorithm['objective_functions'] << var['name']
|
|
706
703
|
variable_index += 1
|