openstudio-workflow 1.3.3 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +77 -72
  3. data/README.md +93 -93
  4. data/Rakefile +36 -36
  5. data/lib/openstudio-workflow.rb +65 -49
  6. data/lib/openstudio/workflow/adapters/input/local.rb +324 -301
  7. data/lib/openstudio/workflow/adapters/output/local.rb +161 -97
  8. data/lib/openstudio/workflow/adapters/output/socket.rb +107 -91
  9. data/lib/openstudio/workflow/adapters/output/web.rb +82 -66
  10. data/lib/openstudio/workflow/adapters/output_adapter.rb +163 -147
  11. data/lib/openstudio/workflow/job.rb +57 -22
  12. data/lib/openstudio/workflow/jobs/resources/monthly_report.idf +222 -222
  13. data/lib/openstudio/workflow/jobs/run_energyplus.rb +70 -54
  14. data/lib/openstudio/workflow/jobs/run_ep_measures.rb +73 -57
  15. data/lib/openstudio/workflow/jobs/run_initialization.rb +203 -171
  16. data/lib/openstudio/workflow/jobs/run_os_measures.rb +89 -73
  17. data/lib/openstudio/workflow/jobs/run_postprocess.rb +73 -57
  18. data/lib/openstudio/workflow/jobs/run_preprocess.rb +104 -80
  19. data/lib/openstudio/workflow/jobs/run_reporting_measures.rb +118 -102
  20. data/lib/openstudio/workflow/jobs/run_translation.rb +84 -68
  21. data/lib/openstudio/workflow/multi_delegator.rb +62 -46
  22. data/lib/openstudio/workflow/registry.rb +172 -137
  23. data/lib/openstudio/workflow/run.rb +328 -312
  24. data/lib/openstudio/workflow/time_logger.rb +96 -53
  25. data/lib/openstudio/workflow/util.rb +49 -14
  26. data/lib/openstudio/workflow/util/energyplus.rb +605 -570
  27. data/lib/openstudio/workflow/util/io.rb +68 -33
  28. data/lib/openstudio/workflow/util/measure.rb +650 -615
  29. data/lib/openstudio/workflow/util/model.rb +151 -100
  30. data/lib/openstudio/workflow/util/post_process.rb +238 -187
  31. data/lib/openstudio/workflow/util/weather_file.rb +143 -108
  32. data/lib/openstudio/workflow/version.rb +40 -24
  33. data/lib/openstudio/workflow_json.rb +476 -443
  34. data/lib/openstudio/workflow_runner.rb +268 -252
  35. metadata +23 -23
@@ -1,301 +1,324 @@
1
- ######################################################################
2
- # Copyright (c) 2008-2014, Alliance for Sustainable Energy.
3
- # All rights reserved.
4
- #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation; either
8
- # version 2.1 of the License, or (at your option) any later version.
9
- #
10
- # This library is distributed in the hope that it will be useful,
11
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- # Lesser General Public License for more details.
14
- #
15
- # You should have received a copy of the GNU Lesser General Public
16
- # License along with this library; if not, write to the Free Software
17
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
- ######################################################################
19
-
20
- require 'openstudio/workflow_json'
21
-
22
- # Local file based workflow
23
- module OpenStudio
24
- module Workflow
25
- module InputAdapter
26
- class Local
27
- def initialize(osw_path = './workflow.osw')
28
- @osw_abs_path = File.absolute_path(osw_path, Dir.pwd)
29
-
30
- @workflow = nil
31
- if File.exist? @osw_abs_path
32
- @workflow = ::JSON.parse(File.read(@osw_abs_path), symbolize_names: true)
33
- end
34
-
35
- @workflow_json = nil
36
- @run_options = nil
37
- if @workflow
38
- begin
39
- # Create a temporary WorkflowJSON, will not be same one used in registry during simulation
40
- @workflow_json = OpenStudio::WorkflowJSON.new(JSON.fast_generate(workflow))
41
- @workflow_json.setOswDir(osw_dir)
42
- rescue NameError => e
43
- @workflow_json = WorkflowJSON_Shim.new(workflow, osw_dir)
44
- end
45
-
46
- begin
47
- @run_options = @workflow_json.runOptions
48
- rescue
49
- end
50
- end
51
- end
52
-
53
- # Get the OSW file from the local filesystem
54
- #
55
- def workflow
56
- raise "Could not read workflow from #{@osw_abs_path}" if @workflow.nil?
57
- @workflow
58
- end
59
-
60
- # Get the OSW path
61
- #
62
- def osw_path
63
- @osw_abs_path
64
- end
65
-
66
- # Get the OSW dir
67
- #
68
- def osw_dir
69
- File.dirname(@osw_abs_path)
70
- end
71
-
72
- # Get the run dir
73
- #
74
- def run_dir
75
- result = File.join(osw_dir, 'run')
76
- if @workflow_json
77
- begin
78
- result = @workflow_json.absoluteRunDir.to_s
79
- rescue
80
- end
81
- end
82
- result
83
- end
84
-
85
- def output_adapter(user_options, default, logger)
86
-
87
- # user option trumps all others
88
- return user_options[:output_adapter] if user_options[:output_adapter]
89
-
90
- # try to read from OSW
91
- if @run_options && !@run_options.empty?
92
- custom_adapter = @run_options.get.customOutputAdapter
93
- if !custom_adapter.empty?
94
- begin
95
- custom_file_name = custom_adapter.get.customFileName
96
- class_name = custom_adapter.get.className
97
- options = ::JSON.parse(custom_adapter.get.options, :symbolize_names => true)
98
-
99
- # merge with user options, user options will replace options loaded from OSW
100
- options.merge!(user_options)
101
-
102
- # stick output_directory in options
103
- options[:output_directory] = run_dir
104
-
105
- p = @workflow_json.findFile(custom_file_name)
106
- if !p.empty?
107
- load(p.get.to_s)
108
- output_adapter = eval("#{class_name}.new(options)")
109
- return output_adapter
110
- else
111
- log_message = "Failed to load custom adapter file '#{custom_file_name}'"
112
- logger.error log_message
113
- raise log_message
114
- end
115
- rescue
116
- log_message = "Failed to load custom adapter '#{class_name}' from file '#{custom_file_name}'"
117
- logger.error log_message
118
- raise log_message
119
- end
120
- end
121
- end
122
-
123
- return default
124
- end
125
-
126
- def jobs(user_options, default, logger)
127
-
128
- # user option trumps all others
129
- return user_options[:jobs] if user_options[:jobs]
130
-
131
- # try to read from OSW
132
- begin
133
- #log_message = "Reading custom job states from OSW is not currently supported'"
134
- #logger.info log_message
135
- rescue
136
- end
137
-
138
- return default
139
- end
140
-
141
- def debug(user_options, default)
142
-
143
- # user option trumps all others
144
- return user_options[:debug] if user_options[:debug]
145
-
146
- # try to read from OSW
147
- if @run_options && !@run_options.empty?
148
- return @run_options.get.debug
149
- end
150
-
151
- return default
152
- end
153
-
154
- def fast(user_options, default)
155
-
156
- # user option trumps all others
157
- return user_options[:fast] if user_options[:fast]
158
-
159
- # try to read from OSW
160
- if @run_options && !@run_options.empty?
161
- if @run_options.get.respond_to?(:fast)
162
- return @run_options.get.fast
163
- else
164
- if @workflow[:run_options]
165
- return @workflow[:run_options][:fast]
166
- end
167
- end
168
- end
169
-
170
- return default
171
- end
172
-
173
- def preserve_run_dir(user_options, default)
174
-
175
- # user option trumps all others
176
- return user_options[:preserve_run_dir] if user_options[:preserve_run_dir]
177
-
178
- # try to read from OSW
179
- if @run_options && !@run_options.empty?
180
- return @run_options.get.preserveRunDir
181
- end
182
-
183
- return default
184
- end
185
-
186
- def skip_expand_objects(user_options, default)
187
-
188
- # user option trumps all others
189
- return user_options[:skip_expand_objects] if user_options[:skip_expand_objects]
190
-
191
- # try to read from OSW
192
- if @run_options && !@run_options.empty?
193
- if @run_options.get.respond_to?(:skipExpandObjects)
194
- return @run_options.get.skipExpandObjects
195
- else
196
- if @workflow[:run_options]
197
- return @workflow[:run_options][:skip_expand_objects]
198
- end
199
- end
200
- end
201
-
202
- return default
203
- end
204
-
205
- def skip_energyplus_preprocess(user_options, default)
206
-
207
- # user option trumps all others
208
- return user_options[:skip_energyplus_preprocess] if user_options[:skip_energyplus_preprocess]
209
-
210
- # try to read from OSW
211
- if @run_options && !@run_options.empty?
212
- if @run_options.get.respond_to?(:skipEnergyPlusPreprocess)
213
- return @run_options.get.skipEnergyPlusPreprocess
214
- else
215
- if @workflow[:run_options]
216
- return @workflow[:run_options][:skip_energyplus_preprocess]
217
- end
218
- end
219
- end
220
-
221
- return default
222
- end
223
-
224
- def cleanup(user_options, default)
225
-
226
- # user option trumps all others
227
- return user_options[:cleanup] if user_options[:cleanup]
228
-
229
- # try to read from OSW
230
- if @run_options && !@run_options.empty?
231
- return @run_options.get.cleanup
232
- end
233
-
234
- return default
235
- end
236
-
237
- def energyplus_path(user_options, default)
238
-
239
- # user option trumps all others
240
- return user_options[:energyplus_path] if user_options[:energyplus_path]
241
-
242
- return default
243
- end
244
-
245
- def profile(user_options, default)
246
-
247
- # user option trumps all others
248
- return user_options[:profile] if user_options[:profile]
249
-
250
- return default
251
- end
252
-
253
- def verify_osw(user_options, default)
254
-
255
- # user option trumps all others
256
- return user_options[:verify_osw] if user_options[:verify_osw]
257
-
258
- return default
259
- end
260
-
261
- def weather_file(user_options, default)
262
-
263
- # user option trumps all others
264
- return user_options[:weather_file] if user_options[:weather_file]
265
-
266
- # try to read from OSW
267
- if !@workflow_json.weatherFile.empty?
268
- return @workflow_json.weatherFile.get.to_s
269
- end
270
-
271
- return default
272
- end
273
-
274
- # Get the associated OSD (datapoint) file from the local filesystem
275
- #
276
- def datapoint
277
- # DLM: should this come from the OSW? the osd id and checksum are specified there.
278
- osd_abs_path = File.join(osw_dir, 'datapoint.osd')
279
- result = nil
280
- if File.exist? osd_abs_path
281
- result = ::JSON.parse(File.read(osd_abs_path), symbolize_names: true)
282
- end
283
- return result
284
- end
285
-
286
- # Get the associated OSA (analysis) definition from the local filesystem
287
- #
288
- def analysis
289
- # DLM: should this come from the OSW? the osd id and checksum are specified there.
290
- osa_abs_path = File.join(osw_dir, '../analysis.json')
291
- result = nil
292
- if File.exist? osa_abs_path
293
- result = ::JSON.parse(File.read(osa_abs_path), symbolize_names: true)
294
- end
295
- return result
296
- end
297
-
298
- end
299
- end
300
- end
301
- end
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) 2008-2018, Alliance for Sustainable Energy, LLC.
3
+ # All rights reserved.
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ #
7
+ # (1) Redistributions of source code must retain the above copyright notice,
8
+ # this list of conditions and the following disclaimer.
9
+ #
10
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ #
14
+ # (3) Neither the name of the copyright holder nor the names of any contributors
15
+ # may be used to endorse or promote products derived from this software without
16
+ # specific prior written permission from the respective party.
17
+ #
18
+ # (4) Other than as required in clauses (1) and (2), distributions in any form
19
+ # of modifications or other derivative works may not use the "OpenStudio"
20
+ # trademark, "OS", "os", or any other confusingly similar designation without
21
+ # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
+ #
23
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER, THE UNITED STATES
27
+ # GOVERNMENT, OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
33
+ # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ # *******************************************************************************
35
+
36
+ require 'openstudio/workflow_json'
37
+
38
+ # Local file based workflow
39
+ module OpenStudio
40
+ module Workflow
41
+ module InputAdapter
42
+ class Local
43
+ def initialize(osw_path = './workflow.osw')
44
+ @osw_abs_path = File.absolute_path(osw_path, Dir.pwd)
45
+
46
+ @workflow = nil
47
+ if File.exist? @osw_abs_path
48
+ @workflow = ::JSON.parse(File.read(@osw_abs_path), symbolize_names: true)
49
+ end
50
+
51
+ begin
52
+ # configure the OSW with paths for loaded extension gems
53
+ # Bundler.require is called in the CLI to load extension gems
54
+ @workflow = OpenStudio::Extension::configure_osw(@workflow)
55
+ rescue NameError => e
56
+ end
57
+
58
+ @workflow_json = nil
59
+ @run_options = nil
60
+ if @workflow
61
+ begin
62
+ # Create a temporary WorkflowJSON, will not be same one used in registry during simulation
63
+ @workflow_json = OpenStudio::WorkflowJSON.new(JSON.fast_generate(workflow))
64
+ @workflow_json.setOswDir(osw_dir)
65
+ rescue NameError => e
66
+ @workflow_json = WorkflowJSON_Shim.new(workflow, osw_dir)
67
+ end
68
+
69
+ begin
70
+ @run_options = @workflow_json.runOptions
71
+ rescue
72
+ end
73
+ end
74
+ end
75
+
76
+ # Get the OSW file from the local filesystem
77
+ #
78
+ def workflow
79
+ raise "Could not read workflow from #{@osw_abs_path}" if @workflow.nil?
80
+ @workflow
81
+ end
82
+
83
+ # Get the OSW path
84
+ #
85
+ def osw_path
86
+ @osw_abs_path
87
+ end
88
+
89
+ # Get the OSW dir
90
+ #
91
+ def osw_dir
92
+ File.dirname(@osw_abs_path)
93
+ end
94
+
95
+ # Get the run dir
96
+ #
97
+ def run_dir
98
+ result = File.join(osw_dir, 'run')
99
+ if @workflow_json
100
+ begin
101
+ result = @workflow_json.absoluteRunDir.to_s
102
+ rescue
103
+ end
104
+ end
105
+ result
106
+ end
107
+
108
+ def output_adapter(user_options, default, logger)
109
+
110
+ # user option trumps all others
111
+ return user_options[:output_adapter] if user_options[:output_adapter]
112
+
113
+ # try to read from OSW
114
+ if @run_options && !@run_options.empty?
115
+ custom_adapter = @run_options.get.customOutputAdapter
116
+ if !custom_adapter.empty?
117
+ begin
118
+ custom_file_name = custom_adapter.get.customFileName
119
+ class_name = custom_adapter.get.className
120
+ options = ::JSON.parse(custom_adapter.get.options, :symbolize_names => true)
121
+
122
+ # merge with user options, user options will replace options loaded from OSW
123
+ options.merge!(user_options)
124
+
125
+ # stick output_directory in options
126
+ options[:output_directory] = run_dir
127
+
128
+ p = @workflow_json.findFile(custom_file_name)
129
+ if !p.empty?
130
+ load(p.get.to_s)
131
+ output_adapter = eval("#{class_name}.new(options)")
132
+ return output_adapter
133
+ else
134
+ log_message = "Failed to load custom adapter file '#{custom_file_name}'"
135
+ logger.error log_message
136
+ raise log_message
137
+ end
138
+ rescue
139
+ log_message = "Failed to load custom adapter '#{class_name}' from file '#{custom_file_name}'"
140
+ logger.error log_message
141
+ raise log_message
142
+ end
143
+ end
144
+ end
145
+
146
+ return default
147
+ end
148
+
149
+ def jobs(user_options, default, logger)
150
+
151
+ # user option trumps all others
152
+ return user_options[:jobs] if user_options[:jobs]
153
+
154
+ # try to read from OSW
155
+ begin
156
+ #log_message = "Reading custom job states from OSW is not currently supported'"
157
+ #logger.info log_message
158
+ rescue
159
+ end
160
+
161
+ return default
162
+ end
163
+
164
+ def debug(user_options, default)
165
+
166
+ # user option trumps all others
167
+ return user_options[:debug] if user_options[:debug]
168
+
169
+ # try to read from OSW
170
+ if @run_options && !@run_options.empty?
171
+ return @run_options.get.debug
172
+ end
173
+
174
+ return default
175
+ end
176
+
177
+ def fast(user_options, default)
178
+
179
+ # user option trumps all others
180
+ return user_options[:fast] if user_options[:fast]
181
+
182
+ # try to read from OSW
183
+ if @run_options && !@run_options.empty?
184
+ if @run_options.get.respond_to?(:fast)
185
+ return @run_options.get.fast
186
+ else
187
+ if @workflow[:run_options]
188
+ return @workflow[:run_options][:fast]
189
+ end
190
+ end
191
+ end
192
+
193
+ return default
194
+ end
195
+
196
+ def preserve_run_dir(user_options, default)
197
+
198
+ # user option trumps all others
199
+ return user_options[:preserve_run_dir] if user_options[:preserve_run_dir]
200
+
201
+ # try to read from OSW
202
+ if @run_options && !@run_options.empty?
203
+ return @run_options.get.preserveRunDir
204
+ end
205
+
206
+ return default
207
+ end
208
+
209
+ def skip_expand_objects(user_options, default)
210
+
211
+ # user option trumps all others
212
+ return user_options[:skip_expand_objects] if user_options[:skip_expand_objects]
213
+
214
+ # try to read from OSW
215
+ if @run_options && !@run_options.empty?
216
+ if @run_options.get.respond_to?(:skipExpandObjects)
217
+ return @run_options.get.skipExpandObjects
218
+ else
219
+ if @workflow[:run_options]
220
+ return @workflow[:run_options][:skip_expand_objects]
221
+ end
222
+ end
223
+ end
224
+
225
+ return default
226
+ end
227
+
228
+ def skip_energyplus_preprocess(user_options, default)
229
+
230
+ # user option trumps all others
231
+ return user_options[:skip_energyplus_preprocess] if user_options[:skip_energyplus_preprocess]
232
+
233
+ # try to read from OSW
234
+ if @run_options && !@run_options.empty?
235
+ if @run_options.get.respond_to?(:skipEnergyPlusPreprocess)
236
+ return @run_options.get.skipEnergyPlusPreprocess
237
+ else
238
+ if @workflow[:run_options]
239
+ return @workflow[:run_options][:skip_energyplus_preprocess]
240
+ end
241
+ end
242
+ end
243
+
244
+ return default
245
+ end
246
+
247
+ def cleanup(user_options, default)
248
+
249
+ # user option trumps all others
250
+ return user_options[:cleanup] if user_options[:cleanup]
251
+
252
+ # try to read from OSW
253
+ if @run_options && !@run_options.empty?
254
+ return @run_options.get.cleanup
255
+ end
256
+
257
+ return default
258
+ end
259
+
260
+ def energyplus_path(user_options, default)
261
+
262
+ # user option trumps all others
263
+ return user_options[:energyplus_path] if user_options[:energyplus_path]
264
+
265
+ return default
266
+ end
267
+
268
+ def profile(user_options, default)
269
+
270
+ # user option trumps all others
271
+ return user_options[:profile] if user_options[:profile]
272
+
273
+ return default
274
+ end
275
+
276
+ def verify_osw(user_options, default)
277
+
278
+ # user option trumps all others
279
+ return user_options[:verify_osw] if user_options[:verify_osw]
280
+
281
+ return default
282
+ end
283
+
284
+ def weather_file(user_options, default)
285
+
286
+ # user option trumps all others
287
+ return user_options[:weather_file] if user_options[:weather_file]
288
+
289
+ # try to read from OSW
290
+ if !@workflow_json.weatherFile.empty?
291
+ return @workflow_json.weatherFile.get.to_s
292
+ end
293
+
294
+ return default
295
+ end
296
+
297
+ # Get the associated OSD (datapoint) file from the local filesystem
298
+ #
299
+ def datapoint
300
+ # DLM: should this come from the OSW? the osd id and checksum are specified there.
301
+ osd_abs_path = File.join(osw_dir, 'datapoint.osd')
302
+ result = nil
303
+ if File.exist? osd_abs_path
304
+ result = ::JSON.parse(File.read(osd_abs_path), symbolize_names: true)
305
+ end
306
+ return result
307
+ end
308
+
309
+ # Get the associated OSA (analysis) definition from the local filesystem
310
+ #
311
+ def analysis
312
+ # DLM: should this come from the OSW? the osd id and checksum are specified there.
313
+ osa_abs_path = File.join(osw_dir, '../analysis.json')
314
+ result = nil
315
+ if File.exist? osa_abs_path
316
+ result = ::JSON.parse(File.read(osa_abs_path), symbolize_names: true)
317
+ end
318
+ return result
319
+ end
320
+
321
+ end
322
+ end
323
+ end
324
+ end