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,54 +1,70 @@
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
- # This class runs the EnergyPlus simulation
21
- class RunEnergyPlus < OpenStudio::Workflow::Job
22
- require 'openstudio/workflow/util/energyplus'
23
- include OpenStudio::Workflow::Util::EnergyPlus
24
-
25
- def initialize(input_adapter, output_adapter, registry, options = {})
26
- super
27
- end
28
-
29
- def perform
30
- @logger.debug "Calling #{__method__} in the #{self.class} class"
31
-
32
- # skip if halted
33
- halted = @registry[:runner].halted
34
- @logger.info 'Workflow halted, skipping the EnergyPlus simulation' if halted
35
- return nil if halted
36
-
37
- # Checks and configuration
38
- raise 'No run_dir specified in the registry' unless @registry[:run_dir]
39
- ep_path = @options[:energyplus_path] ? @options[:energyplus_path] : nil
40
- @logger.warn "Using EnergyPlus path specified in options #{ep_path}" if ep_path
41
-
42
- @logger.info 'Starting the EnergyPlus simulation'
43
- @registry[:time_logger].start('Running EnergyPlus') if @registry[:time_logger]
44
- call_energyplus(@registry[:run_dir], ep_path, @output_adapter, @logger, @registry[:workflow_json])
45
- @registry[:time_logger].stop('Running EnergyPlus') if @registry[:time_logger]
46
- @logger.info 'Completed the EnergyPlus simulation'
47
-
48
- sql_path = File.join(@registry[:run_dir], 'eplusout.sql')
49
- @registry.register(:sql) { sql_path } if File.exist? sql_path
50
- @logger.warn "Unable to find sql file at #{sql_path}" unless @registry[:sql]
51
-
52
- nil
53
- end
54
- 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
+ # This class runs the EnergyPlus simulation
37
+ class RunEnergyPlus < OpenStudio::Workflow::Job
38
+ require 'openstudio/workflow/util/energyplus'
39
+ include OpenStudio::Workflow::Util::EnergyPlus
40
+
41
+ def initialize(input_adapter, output_adapter, registry, options = {})
42
+ super
43
+ end
44
+
45
+ def perform
46
+ @logger.debug "Calling #{__method__} in the #{self.class} class"
47
+
48
+ # skip if halted
49
+ halted = @registry[:runner].halted
50
+ @logger.info 'Workflow halted, skipping the EnergyPlus simulation' if halted
51
+ return nil if halted
52
+
53
+ # Checks and configuration
54
+ raise 'No run_dir specified in the registry' unless @registry[:run_dir]
55
+ ep_path = @options[:energyplus_path] ? @options[:energyplus_path] : nil
56
+ @logger.warn "Using EnergyPlus path specified in options #{ep_path}" if ep_path
57
+
58
+ @logger.info 'Starting the EnergyPlus simulation'
59
+ @registry[:time_logger].start('Running EnergyPlus') if @registry[:time_logger]
60
+ call_energyplus(@registry[:run_dir], ep_path, @output_adapter, @logger, @registry[:workflow_json])
61
+ @registry[:time_logger].stop('Running EnergyPlus') if @registry[:time_logger]
62
+ @logger.info 'Completed the EnergyPlus simulation'
63
+
64
+ sql_path = File.join(@registry[:run_dir], 'eplusout.sql')
65
+ @registry.register(:sql) { sql_path } if File.exist? sql_path
66
+ @logger.warn "Unable to find sql file at #{sql_path}" unless @registry[:sql]
67
+
68
+ nil
69
+ end
70
+ end
@@ -1,57 +1,73 @@
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
- # This class runs all EnergyPlus measures defined in the OSW
21
- class RunEnergyPlusMeasures < OpenStudio::Workflow::Job
22
- require 'openstudio/workflow/util'
23
- include OpenStudio::Workflow::Util::Measure
24
- include OpenStudio::Workflow::Util::Model
25
-
26
- def initialize(input_adapter, output_adapter, registry, options = {})
27
- super
28
- end
29
-
30
- def perform
31
- @logger.debug "Calling #{__method__} in the #{self.class} class"
32
-
33
- # halted workflow is handled in apply_measures
34
-
35
- # Ensure output_attributes is initialized in the registry
36
- @registry.register(:output_attributes) { {} } unless @registry[:output_attributes]
37
-
38
- # Apply the EnergyPlus measures
39
- @options[:output_adapter] = @output_adapter
40
- @logger.info 'Beginning to execute EnergyPlus measures.'
41
- apply_measures('EnergyPlusMeasure'.to_MeasureType, @registry, @options)
42
- @logger.info('Finished applying EnergyPlus measures.')
43
-
44
- # Send the measure output attributes to the output adapter
45
- @logger.debug 'Communicating measure output attributes to the output adapter'
46
- @output_adapter.communicate_measure_attributes @registry[:output_attributes]
47
-
48
- # Save both the OSM and IDF if the :debug option is true
49
- return nil unless @options[:debug]
50
- @registry[:time_logger].start('Saving IDF') if @registry[:time_logger]
51
- idf_name = save_idf(@registry[:model_idf], @registry[:root_dir])
52
- @registry[:time_logger].stop('Saving IDF') if @registry[:time_logger]
53
- @logger.debug "Saved IDF as #{idf_name}"
54
-
55
- nil
56
- end
57
- 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
+ # This class runs all EnergyPlus measures defined in the OSW
37
+ class RunEnergyPlusMeasures < OpenStudio::Workflow::Job
38
+ require 'openstudio/workflow/util'
39
+ include OpenStudio::Workflow::Util::Measure
40
+ include OpenStudio::Workflow::Util::Model
41
+
42
+ def initialize(input_adapter, output_adapter, registry, options = {})
43
+ super
44
+ end
45
+
46
+ def perform
47
+ @logger.debug "Calling #{__method__} in the #{self.class} class"
48
+
49
+ # halted workflow is handled in apply_measures
50
+
51
+ # Ensure output_attributes is initialized in the registry
52
+ @registry.register(:output_attributes) { {} } unless @registry[:output_attributes]
53
+
54
+ # Apply the EnergyPlus measures
55
+ @options[:output_adapter] = @output_adapter
56
+ @logger.info 'Beginning to execute EnergyPlus measures.'
57
+ apply_measures('EnergyPlusMeasure'.to_MeasureType, @registry, @options)
58
+ @logger.info('Finished applying EnergyPlus measures.')
59
+
60
+ # Send the measure output attributes to the output adapter
61
+ @logger.debug 'Communicating measure output attributes to the output adapter'
62
+ @output_adapter.communicate_measure_attributes @registry[:output_attributes]
63
+
64
+ # Save both the OSM and IDF if the :debug option is true
65
+ return nil unless @options[:debug]
66
+ @registry[:time_logger].start('Saving IDF') if @registry[:time_logger]
67
+ idf_name = save_idf(@registry[:model_idf], @registry[:root_dir])
68
+ @registry[:time_logger].stop('Saving IDF') if @registry[:time_logger]
69
+ @logger.debug "Saved IDF as #{idf_name}"
70
+
71
+ nil
72
+ end
73
+ end
@@ -1,171 +1,203 @@
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
- # Run the initialization job to run validations and initializations
21
- class RunInitialization < OpenStudio::Workflow::Job
22
- require 'openstudio/workflow/util'
23
- include OpenStudio::Workflow::Util::WeatherFile
24
- include OpenStudio::Workflow::Util::Model
25
- include OpenStudio::Workflow::Util::Measure
26
-
27
- def initialize(input_adapter, output_adapter, registry, options = {})
28
- defaults = {
29
- verify_osw: true
30
- }
31
- options = defaults.merge(options)
32
- super
33
- end
34
-
35
- def perform
36
- # DLM: why are there multiple loggers running around? there is one in the registry can we just use that?
37
- @logger.info "Calling #{__method__} in the #{self.class} class"
38
-
39
- # do not skip initialization if halted
40
-
41
- # Communicate that the workflow has been started
42
- @logger.debug 'Registering that the workflow has started with the adapter'
43
- @output_adapter.communicate_started
44
-
45
- # Load various files and set basic directories for the registry
46
- # DLM: this key is the raw JSON object, it is deprecated and should not be used, use :workflow_json instead
47
- @registry.register(:workflow) { @input_adapter.workflow }
48
- raise 'Specified workflow was nil' unless @registry[:workflow]
49
- @logger.debug 'Retrieved the workflow from the adapter'
50
-
51
- @registry.register(:osw_dir) { @input_adapter.osw_dir }
52
- @logger.debug "osw_dir is #{@registry[:osw_dir]}"
53
-
54
- @registry.register(:datapoint) { @input_adapter.datapoint }
55
- @logger.debug 'Found associated OSD file' if @registry[:datapoint]
56
-
57
- @registry.register(:analysis) { @input_adapter.analysis }
58
- @logger.debug 'Found associated OSA file' if @registry[:analysis]
59
-
60
- # create the real WorkflowJSON here, we will be able to edit this during the run
61
- if @registry[:openstudio_2]
62
- workflow_json = OpenStudio::WorkflowJSON.new(JSON.fast_generate(@registry[:workflow]))
63
- workflow_json.setOswDir(@registry[:osw_dir])
64
- else
65
- workflow_json = WorkflowJSON_Shim.new(@registry[:workflow], @registry[:osw_dir])
66
- end
67
- @registry.register(:workflow_json) { workflow_json }
68
-
69
- @registry.register(:root_dir) { workflow_json.absoluteRootDir }
70
- @logger.debug "The root_dir for the datapoint is #{@registry[:root_dir]}"
71
-
72
- reports_dir = "#{@registry[:root_dir]}/reports"
73
- if File.exist?(reports_dir)
74
- @logger.debug "Removing existing reports directory: #{reports_dir}"
75
- FileUtils.rm_rf(reports_dir)
76
- end
77
-
78
- # create the runner with our WorkflowJSON
79
- @registry.register(:runner) { WorkflowRunner.new(@registry[:logger], @registry[:workflow_json], @registry[:openstudio_2]) }
80
- @registry[:runner].setDatapoint(@registry[:datapoint])
81
- @registry[:runner].setAnalysis(@registry[:analysis])
82
- @logger.debug 'Initialized runner'
83
-
84
- # Validate the OSW measures if the flag is set to true, (the default state)
85
- if @options[:verify_osw]
86
- @logger.info 'Attempting to validate the measure workflow'
87
- validate_measures(@registry, @logger)
88
- @logger.info 'Validated the measure workflow'
89
- end
90
-
91
- # Load or create the seed OSM object
92
- @logger.debug 'Finding and loading the seed file'
93
- model_path = workflow_json.seedFile
94
- if !model_path.empty?
95
-
96
- model_full_path = workflow_json.findFile(model_path.get)
97
- if model_full_path.empty?
98
- raise "Seed model #{model_path.get} specified in OSW cannot be found"
99
- end
100
- model_full_path = model_full_path.get
101
-
102
- if File.extname(model_full_path.to_s) == '.idf'
103
- @registry.register(:model_idf) { load_idf(model_full_path, @logger) }
104
- @registry.register(:model) { nil }
105
- else
106
- @registry.register(:model) { load_osm(model_full_path, @logger) }
107
- end
108
- else
109
- @registry.register(:model) { OpenStudio::Model::Model.new }
110
-
111
- # add default objects to the model
112
- begin
113
- OpenStudio::Model::initializeModelObjects(@registry[:model])
114
- rescue NameError
115
- @registry[:model].getBuilding
116
- @registry[:model].getFacility
117
- @registry[:model].getSimulationControl
118
- @registry[:model].getSizingParameters
119
- @registry[:model].getTimestep
120
- @registry[:model].getShadowCalculation
121
- @registry[:model].getHeatBalanceAlgorithm
122
- @registry[:model].getRunPeriod
123
- @registry[:model].getLifeCycleCostParameters
124
- end
125
- end
126
-
127
- if @registry[:openstudio_2]
128
- if @registry[:model]
129
- @registry[:model].setWorkflowJSON(workflow_json.clone)
130
- end
131
- end
132
-
133
- # DLM: TODO, load weather_file from options so it can be overriden by user_options
134
-
135
- # Find the weather file, should it exist and be findable
136
- @logger.debug 'Getting the initial weather file'
137
- weather_path = workflow_json.weatherFile
138
- if weather_path.empty?
139
- @logger.debug 'No weather file specified in OSW, looking in model'
140
- if @registry[:model]
141
- model = @registry[:model]
142
- unless model.weatherFile.empty?
143
- weather_path = model.weatherFile.get.path
144
- end
145
- end
146
- end
147
-
148
- unless weather_path.empty?
149
- weather_path = weather_path.get
150
- @logger.debug 'Searching for weather file #{weather_path}'
151
-
152
- weather_full_path = workflow_json.findFile(weather_path)
153
- if weather_full_path.empty?
154
- weather_full_path = workflow_json.findFile(File.basename(weather_path.to_s))
155
- end
156
-
157
- if weather_full_path.empty?
158
- raise "Weather file '#{weather_path}' specified but cannot be found"
159
- end
160
- weather_full_path = weather_full_path.get
161
-
162
- @registry.register(:wf) { weather_full_path.to_s }
163
-
164
- end
165
- @logger.warn 'No valid weather file defined in either the osm or osw.' unless @registry[:wf]
166
-
167
- workflow_json.start
168
-
169
- nil
170
- end
171
- 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
+ # Run the initialization job to run validations and initializations
37
+ class RunInitialization < OpenStudio::Workflow::Job
38
+ require 'openstudio/workflow/util'
39
+ include OpenStudio::Workflow::Util::WeatherFile
40
+ include OpenStudio::Workflow::Util::Model
41
+ include OpenStudio::Workflow::Util::Measure
42
+
43
+ def initialize(input_adapter, output_adapter, registry, options = {})
44
+ defaults = {
45
+ verify_osw: true
46
+ }
47
+ options = defaults.merge(options)
48
+ super
49
+ end
50
+
51
+ def perform
52
+ # DLM: why are there multiple loggers running around? there is one in the registry can we just use that?
53
+ @logger.info "Calling #{__method__} in the #{self.class} class"
54
+
55
+ # do not skip initialization if halted
56
+
57
+ # Communicate that the workflow has been started
58
+ @logger.debug 'Registering that the workflow has started with the adapter'
59
+ @output_adapter.communicate_started
60
+
61
+ # Load various files and set basic directories for the registry
62
+ # DLM: this key is the raw JSON object, it is deprecated and should not be used, use :workflow_json instead
63
+ @registry.register(:workflow) { @input_adapter.workflow }
64
+ raise 'Specified workflow was nil' unless @registry[:workflow]
65
+ @logger.debug 'Retrieved the workflow from the adapter'
66
+
67
+ @registry.register(:osw_dir) { @input_adapter.osw_dir }
68
+ @logger.debug "osw_dir is #{@registry[:osw_dir]}"
69
+
70
+ @registry.register(:datapoint) { @input_adapter.datapoint }
71
+ @logger.debug 'Found associated OSD file' if @registry[:datapoint]
72
+
73
+ @registry.register(:analysis) { @input_adapter.analysis }
74
+ @logger.debug 'Found associated OSA file' if @registry[:analysis]
75
+
76
+ # create the real WorkflowJSON here, we will be able to edit this during the run
77
+ if @registry[:openstudio_2]
78
+ workflow_json = OpenStudio::WorkflowJSON.new(JSON.fast_generate(@registry[:workflow]))
79
+ workflow_json.setOswDir(@registry[:osw_dir])
80
+ else
81
+ workflow_json = WorkflowJSON_Shim.new(@registry[:workflow], @registry[:osw_dir])
82
+ end
83
+ @registry.register(:workflow_json) { workflow_json }
84
+
85
+ @registry.register(:root_dir) { workflow_json.absoluteRootDir }
86
+ @logger.debug "The root_dir for the datapoint is #{@registry[:root_dir]}"
87
+
88
+ generated_files_dir = "#{@registry[:root_dir]}/generated_files"
89
+ if File.exist?(generated_files_dir)
90
+ @logger.debug "Removing existing generated files directory: #{generated_files_dir}"
91
+ FileUtils.rm_rf(generated_files_dir)
92
+ end
93
+ @logger.debug "Creating generated files directory: #{generated_files_dir}"
94
+ FileUtils.mkdir_p(generated_files_dir)
95
+
96
+ # insert the generated files directory in the first spot so all generated ExternalFiles go here
97
+ file_paths = @registry[:workflow_json].filePaths
98
+ @registry[:workflow_json].resetFilePaths
99
+ @registry[:workflow_json].addFilePath(generated_files_dir)
100
+ file_paths.each do |file_path|
101
+ @registry[:workflow_json].addFilePath(file_path)
102
+ end
103
+
104
+ reports_dir = "#{@registry[:root_dir]}/reports"
105
+ if File.exist?(reports_dir)
106
+ @logger.debug "Removing existing reports directory: #{reports_dir}"
107
+ FileUtils.rm_rf(reports_dir)
108
+ end
109
+
110
+ # create the runner with our WorkflowJSON
111
+ @registry.register(:runner) { WorkflowRunner.new(@registry[:logger], @registry[:workflow_json], @registry[:openstudio_2]) }
112
+ @registry[:runner].setDatapoint(@registry[:datapoint])
113
+ @registry[:runner].setAnalysis(@registry[:analysis])
114
+ @logger.debug 'Initialized runner'
115
+
116
+ # Validate the OSW measures if the flag is set to true, (the default state)
117
+ if @options[:verify_osw]
118
+ @logger.info 'Attempting to validate the measure workflow'
119
+ validate_measures(@registry, @logger)
120
+ @logger.info 'Validated the measure workflow'
121
+ end
122
+
123
+ # Load or create the seed OSM object
124
+ @logger.debug 'Finding and loading the seed file'
125
+ model_path = workflow_json.seedFile
126
+ if !model_path.empty?
127
+
128
+ model_full_path = workflow_json.findFile(model_path.get)
129
+ if model_full_path.empty?
130
+ raise "Seed model #{model_path.get} specified in OSW cannot be found"
131
+ end
132
+ model_full_path = model_full_path.get
133
+
134
+ if File.extname(model_full_path.to_s) == '.idf'
135
+ @registry.register(:model_idf) { load_idf(model_full_path, @logger) }
136
+ @registry.register(:model) { nil }
137
+ else
138
+ @registry.register(:model) { load_osm(model_full_path, @logger) }
139
+ end
140
+ else
141
+ @registry.register(:model) { OpenStudio::Model::Model.new }
142
+
143
+ # add default objects to the model
144
+ begin
145
+ OpenStudio::Model::initializeModelObjects(@registry[:model])
146
+ rescue NameError
147
+ @registry[:model].getBuilding
148
+ @registry[:model].getFacility
149
+ @registry[:model].getSimulationControl
150
+ @registry[:model].getSizingParameters
151
+ @registry[:model].getTimestep
152
+ @registry[:model].getShadowCalculation
153
+ @registry[:model].getHeatBalanceAlgorithm
154
+ @registry[:model].getRunPeriod
155
+ @registry[:model].getLifeCycleCostParameters
156
+ end
157
+ end
158
+
159
+ if @registry[:openstudio_2]
160
+ if @registry[:model]
161
+ @registry[:model].setWorkflowJSON(workflow_json.clone)
162
+ end
163
+ end
164
+
165
+ # DLM: TODO, load weather_file from options so it can be overriden by user_options
166
+
167
+ # Find the weather file, should it exist and be findable
168
+ @logger.debug 'Getting the initial weather file'
169
+ weather_path = workflow_json.weatherFile
170
+ if weather_path.empty?
171
+ @logger.debug 'No weather file specified in OSW, looking in model'
172
+ if @registry[:model]
173
+ model = @registry[:model]
174
+ unless model.weatherFile.empty?
175
+ weather_path = model.weatherFile.get.path
176
+ end
177
+ end
178
+ end
179
+
180
+ unless weather_path.empty?
181
+ weather_path = weather_path.get
182
+ @logger.debug 'Searching for weather file #{weather_path}'
183
+
184
+ weather_full_path = workflow_json.findFile(weather_path)
185
+ if weather_full_path.empty?
186
+ weather_full_path = workflow_json.findFile(File.basename(weather_path.to_s))
187
+ end
188
+
189
+ if weather_full_path.empty?
190
+ raise "Weather file '#{weather_path}' specified but cannot be found"
191
+ end
192
+ weather_full_path = weather_full_path.get
193
+
194
+ @registry.register(:wf) { weather_full_path.to_s }
195
+
196
+ end
197
+ @logger.warn 'No valid weather file defined in either the osm or osw.' unless @registry[:wf]
198
+
199
+ workflow_json.start
200
+
201
+ nil
202
+ end
203
+ end