openstudio-workflow 1.2.0 → 1.2.1

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 +72 -72
  3. data/README.md +48 -48
  4. data/Rakefile +36 -36
  5. data/lib/openstudio/workflow/adapters/input/local.rb +240 -240
  6. data/lib/openstudio/workflow/adapters/output/local.rb +95 -95
  7. data/lib/openstudio/workflow/adapters/output/socket.rb +91 -91
  8. data/lib/openstudio/workflow/adapters/output/web.rb +66 -66
  9. data/lib/openstudio/workflow/adapters/output_adapter.rb +147 -147
  10. data/lib/openstudio/workflow/job.rb +22 -22
  11. data/lib/openstudio/workflow/jobs/resources/monthly_report.idf +222 -222
  12. data/lib/openstudio/workflow/jobs/run_energyplus.rb +49 -49
  13. data/lib/openstudio/workflow/jobs/run_ep_measures.rb +55 -55
  14. data/lib/openstudio/workflow/jobs/run_initialization.rb +167 -167
  15. data/lib/openstudio/workflow/jobs/run_os_measures.rb +69 -69
  16. data/lib/openstudio/workflow/jobs/run_postprocess.rb +53 -53
  17. data/lib/openstudio/workflow/jobs/run_preprocess.rb +69 -69
  18. data/lib/openstudio/workflow/jobs/run_reporting_measures.rb +98 -98
  19. data/lib/openstudio/workflow/jobs/run_translation.rb +61 -61
  20. data/lib/openstudio/workflow/multi_delegator.rb +46 -46
  21. data/lib/openstudio/workflow/registry.rb +137 -137
  22. data/lib/openstudio/workflow/run.rb +299 -299
  23. data/lib/openstudio/workflow/time_logger.rb +53 -53
  24. data/lib/openstudio/workflow/util/energyplus.rb +564 -564
  25. data/lib/openstudio/workflow/util/io.rb +33 -33
  26. data/lib/openstudio/workflow/util/measure.rb +588 -586
  27. data/lib/openstudio/workflow/util/model.rb +100 -100
  28. data/lib/openstudio/workflow/util/post_process.rb +187 -187
  29. data/lib/openstudio/workflow/util/weather_file.rb +108 -108
  30. data/lib/openstudio/workflow/util.rb +14 -14
  31. data/lib/openstudio/workflow/version.rb +24 -24
  32. data/lib/openstudio/workflow_json.rb +426 -426
  33. data/lib/openstudio/workflow_runner.rb +215 -215
  34. data/lib/openstudio-workflow.rb +49 -49
  35. metadata +3 -3
@@ -1,61 +1,61 @@
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 validate the directory and initialize the adapters.
21
- class RunTranslation < OpenStudio::Workflow::Job
22
- require 'openstudio/workflow/util/model'
23
- include OpenStudio::Workflow::Util::Model
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
- # Ensure that the run directory is created
33
- FileUtils.mkdir_p(@registry[:run_dir])
34
-
35
- # Copy in the weather file defined in the registry, or alternately in the options
36
- if @registry[:wf]
37
- @logger.info "Weather file for EnergyPlus simulation is #{@registry[:wf]}"
38
- FileUtils.copy(@registry[:wf], "#{@registry[:run_dir]}/in.epw")
39
- @registry.register(:wf) { "#{@registry[:run_dir]}/in.epw" }
40
- else
41
- @logger.warn "EPW file not found or not sent to #{self.class}"
42
- end
43
-
44
- # Translate the OSM to an IDF
45
- @logger.info 'Beginning the translation to IDF'
46
- @registry[:time_logger].start('Translating to EnergyPlus') if @registry[:time_logger]
47
- model_idf = translate_to_energyplus @registry[:model], @logger
48
- @registry[:time_logger].stop('Translating to EnergyPlus') if @registry[:time_logger]
49
- @registry.register(:model_idf) { model_idf }
50
- @logger.info 'Successfully translated to IDF'
51
-
52
- # Save the generated IDF file if the :debug option is true
53
- return nil unless @options[:debug]
54
- @registry[:time_logger].start('Saving IDF') if @registry[:time_logger]
55
- idf_name = save_idf(@registry[:model_idf], @registry[:root_dir])
56
- @registry[:time_logger].stop('Saving IDF') if @registry[:time_logger]
57
- @logger.debug "Saved IDF as #{idf_name}"
58
-
59
- nil
60
- end
61
- end
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 validate the directory and initialize the adapters.
21
+ class RunTranslation < OpenStudio::Workflow::Job
22
+ require 'openstudio/workflow/util/model'
23
+ include OpenStudio::Workflow::Util::Model
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
+ # Ensure that the run directory is created
33
+ FileUtils.mkdir_p(@registry[:run_dir])
34
+
35
+ # Copy in the weather file defined in the registry, or alternately in the options
36
+ if @registry[:wf]
37
+ @logger.info "Weather file for EnergyPlus simulation is #{@registry[:wf]}"
38
+ FileUtils.copy(@registry[:wf], "#{@registry[:run_dir]}/in.epw")
39
+ @registry.register(:wf) { "#{@registry[:run_dir]}/in.epw" }
40
+ else
41
+ @logger.warn "EPW file not found or not sent to #{self.class}"
42
+ end
43
+
44
+ # Translate the OSM to an IDF
45
+ @logger.info 'Beginning the translation to IDF'
46
+ @registry[:time_logger].start('Translating to EnergyPlus') if @registry[:time_logger]
47
+ model_idf = translate_to_energyplus @registry[:model], @logger
48
+ @registry[:time_logger].stop('Translating to EnergyPlus') if @registry[:time_logger]
49
+ @registry.register(:model_idf) { model_idf }
50
+ @logger.info 'Successfully translated to IDF'
51
+
52
+ # Save the generated IDF file if the :debug option is true
53
+ return nil unless @options[:debug]
54
+ @registry[:time_logger].start('Saving IDF') if @registry[:time_logger]
55
+ idf_name = save_idf(@registry[:model_idf], @registry[:root_dir])
56
+ @registry[:time_logger].stop('Saving IDF') if @registry[:time_logger]
57
+ @logger.debug "Saved IDF as #{idf_name}"
58
+
59
+ nil
60
+ end
61
+ end
@@ -1,46 +1,46 @@
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 'logger'
21
-
22
- class Logger
23
- def format_message(severity, datetime, _progname, msg)
24
- "[%s %s] %s\n" % [datetime.strftime('%H:%M:%S.%6N'), severity, msg]
25
- end
26
- end
27
-
28
- # Class to allow multiple logging paths
29
- class MultiDelegator
30
- def initialize(*targets)
31
- @targets = targets
32
- end
33
-
34
- def self.delegate(*methods)
35
- methods.each do |m|
36
- define_method(m) do |*args|
37
- @targets.map { |t| t.send(m, *args) }
38
- end
39
- end
40
- self
41
- end
42
-
43
- class <<self
44
- alias to new
45
- end
46
- end
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 'logger'
21
+
22
+ class Logger
23
+ def format_message(severity, datetime, _progname, msg)
24
+ "[%s %s] %s\n" % [datetime.strftime('%H:%M:%S.%6N'), severity, msg]
25
+ end
26
+ end
27
+
28
+ # Class to allow multiple logging paths
29
+ class MultiDelegator
30
+ def initialize(*targets)
31
+ @targets = targets
32
+ end
33
+
34
+ def self.delegate(*methods)
35
+ methods.each do |m|
36
+ define_method(m) do |*args|
37
+ @targets.map { |t| t.send(m, *args) }
38
+ end
39
+ end
40
+ self
41
+ end
42
+
43
+ class <<self
44
+ alias to new
45
+ end
46
+ end
@@ -1,137 +1,137 @@
1
- module OpenStudio
2
- module Workflow
3
- # Registers objects in a single place. Based on Hashicorps's Vagrant Registry class
4
- #
5
- # This allows certain components (such as models, weather files, proxy settings, etc.) to be registered as blocks
6
- # and lazily updated. This allows for the state of various objects to be updated through evaluation of or
7
- # overwriting the key. An instance of this class is passed between jobs to allow for highly flexible workflow
8
- # definitions. Note that hashes can be passed into the registry as follows: hash = {...};
9
- # Registry.new.register(:hash) { hash } or Registry.new.register(:hash) { {...} }. This class will likely absorb
10
- # un-abstracted elements of the adapter class, see Workflow#Adapter
11
-
12
- # @todo (rhorsey) registry should be a member of WorkflowRunner - DLM
13
- # @todo (rhorsey) how is this different than a regular hash? why is it important to be able to register keys with blocks that return values instead of values, looks like the block is called on insert anyway? let's not go crazy on performance optimizations until we have to - DLM
14
- class Registry
15
- def initialize
16
- @items = {}
17
- @results_cache = {}
18
- end
19
-
20
- # Register a key and cache it's value. Note that if a key with the given name already exists it is overwritten
21
- #
22
- # @param [] key The key for the passed in block. Symbols are highly recommended
23
- # @param [Proc] block The block (Proc) which contains the registered information
24
- # @return [] Returns block.call from the registries cache
25
- #
26
- def register(key, &block)
27
- raise ArgumentError, 'block required' unless block_given?
28
- @items[key] = block
29
- @results_cache[key] = @items[key].call
30
- end
31
-
32
- # Get the cached value of the given key
33
- #
34
- # @param [] key The key defining the block
35
- # @return [] Returns the registries cached value for the key or nil if the key was not found
36
- #
37
- def get(key)
38
- return nil unless @items.key?(key)
39
- @results_cache[key]
40
- end
41
- alias [] get
42
-
43
- # Re-evaluate the proc of a key and update the cache
44
- #
45
- # @param [Sym or String] key This will evaluate the item assigned to the key and update the cache if possible
46
- # @return [] If successful the method returns the new value, and if it cannot find or cannot update the key it
47
- # returns nil
48
- #
49
- def eval(key)
50
- return nil unless @items.key?(key)
51
- begin
52
- @items[key].call
53
- rescue
54
- return nil
55
- end
56
- @results_cache[key] = @items[key].call
57
- end
58
-
59
- # Checks if the given key is registered with the registry
60
- #
61
- # @return [Boolean]
62
- #
63
- def key?(key)
64
- @items.key?(key)
65
- end
66
- alias has_key? key?
67
-
68
- # Returns an array populated with the keys of this object
69
- #
70
- # @return [Array]
71
- #
72
- def keys
73
- @items.keys
74
- end
75
-
76
- # Return the number of elements in this registry
77
- #
78
- # @return [Fixnum]
79
- #
80
- def length
81
- @items.keys.length
82
- end
83
- alias size length
84
-
85
- # Checks if this registry has any items
86
- #
87
- # @return [Boolean]
88
- #
89
- def empty?
90
- @items.keys.empty?
91
- end
92
-
93
- # Merge one registry with another and return a completely new registry. Note that the result cache is completely
94
- # busted, so any gets on the new registry will result in a cache miss
95
- #
96
- # @param [Registry] other The other #Registry to merge onto of self
97
- # @return [Registry] A merged #Registry
98
- #
99
- def merge(other)
100
- self.class.new.tap do |result|
101
- result.merge!(self)
102
- result.merge!(other)
103
- end
104
- end
105
-
106
- # Like #merge but updates self
107
- #
108
- # @param [Registry] other The other #Registry to merge onto of self
109
- # @return [Void]
110
- #
111
- def merge!(other)
112
- @items.merge!(other.__internal_state[:items])
113
- self
114
- end
115
-
116
- # Converts the registry to a hash
117
- #
118
- # @return [Hash] The registry as a hash
119
- #
120
- def to_hash
121
- result = {}
122
- @results_cache.each_pair do |key, value|
123
- result[key] = value
124
- end
125
-
126
- result
127
- end
128
-
129
- def __internal_state
130
- {
131
- items: @items,
132
- results_cache: @results_cache
133
- }
134
- end
135
- end
136
- end
137
- end
1
+ module OpenStudio
2
+ module Workflow
3
+ # Registers objects in a single place. Based on Hashicorps's Vagrant Registry class
4
+ #
5
+ # This allows certain components (such as models, weather files, proxy settings, etc.) to be registered as blocks
6
+ # and lazily updated. This allows for the state of various objects to be updated through evaluation of or
7
+ # overwriting the key. An instance of this class is passed between jobs to allow for highly flexible workflow
8
+ # definitions. Note that hashes can be passed into the registry as follows: hash = {...};
9
+ # Registry.new.register(:hash) { hash } or Registry.new.register(:hash) { {...} }. This class will likely absorb
10
+ # un-abstracted elements of the adapter class, see Workflow#Adapter
11
+
12
+ # @todo (rhorsey) registry should be a member of WorkflowRunner - DLM
13
+ # @todo (rhorsey) how is this different than a regular hash? why is it important to be able to register keys with blocks that return values instead of values, looks like the block is called on insert anyway? let's not go crazy on performance optimizations until we have to - DLM
14
+ class Registry
15
+ def initialize
16
+ @items = {}
17
+ @results_cache = {}
18
+ end
19
+
20
+ # Register a key and cache it's value. Note that if a key with the given name already exists it is overwritten
21
+ #
22
+ # @param [] key The key for the passed in block. Symbols are highly recommended
23
+ # @param [Proc] block The block (Proc) which contains the registered information
24
+ # @return [] Returns block.call from the registries cache
25
+ #
26
+ def register(key, &block)
27
+ raise ArgumentError, 'block required' unless block_given?
28
+ @items[key] = block
29
+ @results_cache[key] = @items[key].call
30
+ end
31
+
32
+ # Get the cached value of the given key
33
+ #
34
+ # @param [] key The key defining the block
35
+ # @return [] Returns the registries cached value for the key or nil if the key was not found
36
+ #
37
+ def get(key)
38
+ return nil unless @items.key?(key)
39
+ @results_cache[key]
40
+ end
41
+ alias [] get
42
+
43
+ # Re-evaluate the proc of a key and update the cache
44
+ #
45
+ # @param [Sym or String] key This will evaluate the item assigned to the key and update the cache if possible
46
+ # @return [] If successful the method returns the new value, and if it cannot find or cannot update the key it
47
+ # returns nil
48
+ #
49
+ def eval(key)
50
+ return nil unless @items.key?(key)
51
+ begin
52
+ @items[key].call
53
+ rescue
54
+ return nil
55
+ end
56
+ @results_cache[key] = @items[key].call
57
+ end
58
+
59
+ # Checks if the given key is registered with the registry
60
+ #
61
+ # @return [Boolean]
62
+ #
63
+ def key?(key)
64
+ @items.key?(key)
65
+ end
66
+ alias has_key? key?
67
+
68
+ # Returns an array populated with the keys of this object
69
+ #
70
+ # @return [Array]
71
+ #
72
+ def keys
73
+ @items.keys
74
+ end
75
+
76
+ # Return the number of elements in this registry
77
+ #
78
+ # @return [Fixnum]
79
+ #
80
+ def length
81
+ @items.keys.length
82
+ end
83
+ alias size length
84
+
85
+ # Checks if this registry has any items
86
+ #
87
+ # @return [Boolean]
88
+ #
89
+ def empty?
90
+ @items.keys.empty?
91
+ end
92
+
93
+ # Merge one registry with another and return a completely new registry. Note that the result cache is completely
94
+ # busted, so any gets on the new registry will result in a cache miss
95
+ #
96
+ # @param [Registry] other The other #Registry to merge onto of self
97
+ # @return [Registry] A merged #Registry
98
+ #
99
+ def merge(other)
100
+ self.class.new.tap do |result|
101
+ result.merge!(self)
102
+ result.merge!(other)
103
+ end
104
+ end
105
+
106
+ # Like #merge but updates self
107
+ #
108
+ # @param [Registry] other The other #Registry to merge onto of self
109
+ # @return [Void]
110
+ #
111
+ def merge!(other)
112
+ @items.merge!(other.__internal_state[:items])
113
+ self
114
+ end
115
+
116
+ # Converts the registry to a hash
117
+ #
118
+ # @return [Hash] The registry as a hash
119
+ #
120
+ def to_hash
121
+ result = {}
122
+ @results_cache.each_pair do |key, value|
123
+ result[key] = value
124
+ end
125
+
126
+ result
127
+ end
128
+
129
+ def __internal_state
130
+ {
131
+ items: @items,
132
+ results_cache: @results_cache
133
+ }
134
+ end
135
+ end
136
+ end
137
+ end