openstudio-analysis 1.3.5 → 1.3.6

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.
@@ -1,279 +1,279 @@
1
- # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
- # See also https://openstudio.net/license
4
- # *******************************************************************************
5
-
6
- # OpenStudio::Analysis::Workflow configured the list of measures to run and in what order
7
- module OpenStudio
8
- module Analysis
9
- class Workflow
10
- attr_reader :items
11
- # allow users to access the items via the measures attribute accessor
12
- alias measures items
13
-
14
- # Create an instance of the OpenStudio::Analysis::Workflow
15
- #
16
- # @return [Object] An OpenStudio::Analysis::Workflow object
17
- def initialize
18
- @items = []
19
- end
20
-
21
- # Remove all the items in the workflow
22
- def clear
23
- @items.clear
24
- end
25
-
26
- # Add a measure to the workflow from a path. This will parse the measure.xml which must exist.
27
- #
28
- # @params instance_name [String] The name of the instance. This allows for multiple measures to be added to the workflow with uni que names
29
- # @params instance_display_name [String] The display name of the instance. This allows for multiple measures to be added to the workflow with unique names
30
- # @param local_path_to_measure [String] This is the local path to the measure directory, relative or absolute. It is used when zipping up all the measures.
31
- # @return [Object] Returns the measure that was added as an OpenStudio::AnalysisWorkflowStep object
32
- def add_measure_from_path(instance_name, instance_display_name, local_path_to_measure)
33
- measure_filename = 'measure.rb'
34
-
35
- if File.exist?(local_path_to_measure) && File.file?(local_path_to_measure)
36
- measure_filename = File.basename(local_path_to_measure)
37
- local_path_to_measure = File.dirname(local_path_to_measure)
38
- end
39
-
40
- if Dir.exist?(local_path_to_measure) && File.directory?(local_path_to_measure)
41
- measure_hash = nil
42
- if File.exist?(File.join(local_path_to_measure, 'measure.xml'))
43
- measure_hash = parse_measure_xml(File.join(local_path_to_measure, 'measure.xml'))
44
- else
45
- raise 'Could not find measure.xml'
46
- end
47
-
48
- add_measure(instance_name, instance_display_name, local_path_to_measure, measure_hash)
49
- else
50
- raise "could not find measure to add to workflow #{local_path_to_measure}"
51
- end
52
-
53
- @items.last
54
- end
55
-
56
- # Add a measure from the custom hash format without reading the measure.rb or measure.xml file
57
- #
58
- # @params instance_name [String] The name of the instance. This allows for multiple measures to be added to the workflow with unique names
59
- # @params instance_display_name [String] The display name of the instance. This allows for multiple measures to be added to the workflow with unique names
60
- # @param local_path_to_measure [String] This is the local path to the measure directory, relative or absolute. It is used when zipping up all the measures.
61
- # @param measure_metadata [Hash] Format of the measure.xml in JSON format
62
- # @return [Object] Returns the measure that was added as an OpenStudio::AnalysisWorkflowStep object
63
- def add_measure(instance_name, instance_display_name, local_path_to_measure, measure_metadata)
64
- @items << OpenStudio::Analysis::WorkflowStep.from_measure_hash(instance_name, instance_display_name, local_path_to_measure, measure_metadata)
65
-
66
- @items.last
67
- end
68
-
69
- # Add a measure from the analysis hash format
70
- #
71
- # @params instance_name [String] The name of the instance. This allows for multiple measures to be added to the workflow with unique names
72
- # @params instance_display_name [String] The display name of the instance. This allows for multiple measures to be added to the workflow with unique names
73
- # @param local_path_to_measure [String] This is the local path to the measure directory, relative or absolute. It is used when zipping up all the measures.
74
- # @param measure_metadata [Hash] Format of the measure.xml in JSON format
75
- # @return [Object] Returns the measure that was added as an OpenStudio::AnalysisWorkflowStep object
76
- def add_measure_from_analysis_hash(instance_name, instance_display_name, local_path_to_measure, measure_metadata)
77
- @items << OpenStudio::Analysis::WorkflowStep.from_analysis_hash(instance_name, instance_display_name, local_path_to_measure, measure_metadata)
78
-
79
- @items.last
80
- end
81
-
82
- # Add a measure from the format that Excel parses into. This is a helper method to map the excel data to the new
83
- # programmatic interface format
84
- #
85
- # @params measure [Hash] The measure in the format of the Excel translator
86
- # @return [Object] Returns the measure that was added as an OpenStudio::AnalysisWorkflowStep object
87
- def add_measure_from_excel(measure)
88
- hash = {}
89
- hash[:classname] = measure['measure_file_name']
90
- hash[:name] = measure['name']
91
- hash[:display_name] = measure['display_name']
92
- hash[:measure_type] = measure['measure_type']
93
- hash[:uid] = measure['uid'] ? measure['uid'] : SecureRandom.uuid
94
- hash[:version_id] = measure['version_id'] ? measure['version_id'] : SecureRandom.uuid
95
-
96
- # map the arguments - this can be a variable or argument, add them all as arguments first,
97
- # the make_variable will remove from arg and place into variables
98
- args = []
99
-
100
- measure['variables'].each do |variable|
101
- args << {
102
- local_variable: variable['name'],
103
- variable_type: variable['type'],
104
- name: variable['name'],
105
- display_name: variable['display_name'],
106
- display_name_short: variable['display_name_short'],
107
- units: variable['units'],
108
- default_value: variable['distribution']['static_value'],
109
- value: variable['distribution']['static_value']
110
- }
111
- end
112
- hash[:arguments] = args
113
-
114
- m = add_measure(measure['name'], measure['display_name'], measure['local_path_to_measure'], hash)
115
-
116
- measure['variables'].each do |variable|
117
- next unless ['variable', 'pivot'].include? variable['variable_type']
118
-
119
- dist = {
120
- type: variable['distribution']['type'],
121
- minimum: variable['distribution']['min'],
122
- maximum: variable['distribution']['max'],
123
- mean: variable['distribution']['mean'],
124
- standard_deviation: variable['distribution']['stddev'],
125
- values: variable['distribution']['discrete_values'],
126
- weights: variable['distribution']['discrete_weights'],
127
- step_size: variable['distribution']['delta_x']
128
- }
129
- opt = {
130
- variable_type: variable['variable_type'],
131
- variable_display_name_short: variable['display_name_short'],
132
- static_value: variable['distribution']['static_value']
133
- }
134
-
135
- m.make_variable(variable['name'], variable['display_name'], dist, opt)
136
- end
137
- end
138
-
139
- # Add a measure from the format that CSV parses into. This is a helper method to map the csv data to the new
140
- # programmatic interface format
141
- #
142
- # @params measure [Hash] The measure in the format of the CSV translator
143
- # @return [Object] Returns the measure that was added as an OpenStudio::AnalysisWorkflowStep object
144
- def add_measure_from_csv(measure)
145
- hash = {}
146
- hash[:classname] = measure[:measure_data][:classname]
147
- hash[:name] = measure[:measure_data][:name]
148
- hash[:display_name] = measure[:measure_data][:display_name]
149
- hash[:measure_type] = measure[:measure_data][:measure_type]
150
- hash[:uid] = measure[:measure_data][:uid] ? measure[:measure_data][:uid] : SecureRandom.uuid
151
- hash[:version_id] = measure[:measure_data][:version_id] ? measure[:measure_data][:version_id] : SecureRandom.uuid
152
-
153
- # map the arguments - this can be a variable or argument, add them all as arguments first,
154
- # the make_variable will remove from arg and place into variables
155
- hash[:arguments] = measure[:args]
156
-
157
- m = add_measure(measure[:measure_data][:name], measure[:measure_data][:display_name], measure[:measure_data][:local_path_to_measure], hash)
158
-
159
- measure[:vars].each do |variable|
160
- next unless ['variable', 'pivot'].include? variable[:variable_type]
161
-
162
- dist = variable[:distribution]
163
- opt = {
164
- variable_type: variable[:variable_type],
165
- variable_display_name_short: variable[:display_name_short],
166
- static_value: variable[:distribution][:mode]
167
- }
168
-
169
- m.make_variable(variable[:name], variable[:display_name], dist, opt)
170
- end
171
- end
172
-
173
- # Iterate over all the WorkflowItems
174
- def each
175
- @items.each { |i| yield i }
176
- end
177
-
178
- # Find the measure by its instance name
179
- #
180
- # @params instance_name [String] instance name of the measure
181
- # @return [Object] The WorkflowStep with the instance_name
182
- def find_measure(instance_name)
183
- @items.find { |i| i.name == instance_name }
184
- end
185
- alias find_workflow_step find_measure
186
-
187
- # Return all the variables in the analysis as an array. The list that is returned is read only.
188
- #
189
- # @return [Array] All variables in the workflow
190
- def all_variables
191
- @items.map(&:variables).flatten
192
- end
193
-
194
- # Save the workflow to a hash object
195
- def to_hash(version = 1)
196
- h = nil
197
- if version == 1
198
- arr = []
199
- @items.each_with_index do |item, index|
200
- temp_h = item.to_hash(version)
201
- temp_h[:workflow_index] = index
202
-
203
- arr << temp_h
204
- end
205
-
206
- h = arr
207
- else
208
- raise "Version #{version} not yet implemented for to_hash"
209
- end
210
-
211
- h
212
- end
213
-
214
- # Save the workflow to a JSON string
215
- #
216
- # @return [String] JSON formatted string
217
- def to_json(version = 1)
218
- if version == 1
219
- JSON.pretty_generate(to_hash(version))
220
- else
221
- raise "Version #{version} not yet implemented for to_json"
222
- end
223
- end
224
-
225
- # Load from a from a hash
226
- #
227
- # @param h [Hash or String] Path to file or hash
228
- def self.load(h)
229
- # get the version of the file
230
- file_format_version = h[:file_format_version] ? h[:file_format_version] : 1
231
- puts "Parsing file version #{file_format_version}"
232
-
233
- o = OpenStudio::Analysis::Workflow.new
234
-
235
- if h[:workflow]
236
- h[:workflow].each do |wf|
237
- puts "Adding measure #{wf[:name]}"
238
-
239
- # Go though the defined measure paths and try and find the local measure
240
- local_measure_dir = nil
241
- if wf[:measure_definition_directory_local] && Dir.exist?(wf[:measure_definition_directory_local])
242
- local_measure_dir = wf[:measure_definition_directory_local]
243
- else
244
- # search in the measure paths for the measure
245
- OpenStudio::Analysis.measure_paths.each do |p|
246
- test_dir = File.join(p, File.basename(wf[:measure_definition_directory]))
247
- if Dir.exist?(test_dir)
248
- local_measure_dir = test_dir
249
- break
250
- end
251
- end
252
- end
253
-
254
- raise "Could not find local measure when loading workflow for #{wf[:measure_definition_class_name]} in #{File.basename(wf[:measure_definition_directory])}. You may have to add measure paths to OpenStudio::Analysis.measure_paths" unless local_measure_dir
255
-
256
- o.add_measure_from_analysis_hash(wf[:name], wf[:display_name], local_measure_dir, wf)
257
- end
258
- end
259
- o
260
- end
261
-
262
- # Read the Workflow description from a persisted file. The format at the moment is the current analysis.json
263
- #
264
- # @params filename [String] Path to file with the analysis.json to load
265
- # @return [Object] Return an instance of the workflow object
266
- def self.from_file(filename)
267
- o = nil
268
- if File.exist? filename
269
- j = JSON.parse(File.read(filename), symbolize_names: true)
270
- o = OpenStudio::Analysis::Workflow.load(j)
271
- else
272
- raise "Could not find workflow file #{filename}"
273
- end
274
-
275
- o
276
- end
277
- end
278
- end
279
- end
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://openstudio.net/license
4
+ # *******************************************************************************
5
+
6
+ # OpenStudio::Analysis::Workflow configured the list of measures to run and in what order
7
+ module OpenStudio
8
+ module Analysis
9
+ class Workflow
10
+ attr_reader :items
11
+ # allow users to access the items via the measures attribute accessor
12
+ alias measures items
13
+
14
+ # Create an instance of the OpenStudio::Analysis::Workflow
15
+ #
16
+ # @return [Object] An OpenStudio::Analysis::Workflow object
17
+ def initialize
18
+ @items = []
19
+ end
20
+
21
+ # Remove all the items in the workflow
22
+ def clear
23
+ @items.clear
24
+ end
25
+
26
+ # Add a measure to the workflow from a path. This will parse the measure.xml which must exist.
27
+ #
28
+ # @params instance_name [String] The name of the instance. This allows for multiple measures to be added to the workflow with uni que names
29
+ # @params instance_display_name [String] The display name of the instance. This allows for multiple measures to be added to the workflow with unique names
30
+ # @param local_path_to_measure [String] This is the local path to the measure directory, relative or absolute. It is used when zipping up all the measures.
31
+ # @return [Object] Returns the measure that was added as an OpenStudio::AnalysisWorkflowStep object
32
+ def add_measure_from_path(instance_name, instance_display_name, local_path_to_measure)
33
+ measure_filename = 'measure.rb'
34
+
35
+ if File.exist?(local_path_to_measure) && File.file?(local_path_to_measure)
36
+ measure_filename = File.basename(local_path_to_measure)
37
+ local_path_to_measure = File.dirname(local_path_to_measure)
38
+ end
39
+
40
+ if Dir.exist?(local_path_to_measure) && File.directory?(local_path_to_measure)
41
+ measure_hash = nil
42
+ if File.exist?(File.join(local_path_to_measure, 'measure.xml'))
43
+ measure_hash = parse_measure_xml(File.join(local_path_to_measure, 'measure.xml'))
44
+ else
45
+ raise 'Could not find measure.xml'
46
+ end
47
+
48
+ add_measure(instance_name, instance_display_name, local_path_to_measure, measure_hash)
49
+ else
50
+ raise "could not find measure to add to workflow #{local_path_to_measure}"
51
+ end
52
+
53
+ @items.last
54
+ end
55
+
56
+ # Add a measure from the custom hash format without reading the measure.rb or measure.xml file
57
+ #
58
+ # @params instance_name [String] The name of the instance. This allows for multiple measures to be added to the workflow with unique names
59
+ # @params instance_display_name [String] The display name of the instance. This allows for multiple measures to be added to the workflow with unique names
60
+ # @param local_path_to_measure [String] This is the local path to the measure directory, relative or absolute. It is used when zipping up all the measures.
61
+ # @param measure_metadata [Hash] Format of the measure.xml in JSON format
62
+ # @return [Object] Returns the measure that was added as an OpenStudio::AnalysisWorkflowStep object
63
+ def add_measure(instance_name, instance_display_name, local_path_to_measure, measure_metadata)
64
+ @items << OpenStudio::Analysis::WorkflowStep.from_measure_hash(instance_name, instance_display_name, local_path_to_measure, measure_metadata)
65
+
66
+ @items.last
67
+ end
68
+
69
+ # Add a measure from the analysis hash format
70
+ #
71
+ # @params instance_name [String] The name of the instance. This allows for multiple measures to be added to the workflow with unique names
72
+ # @params instance_display_name [String] The display name of the instance. This allows for multiple measures to be added to the workflow with unique names
73
+ # @param local_path_to_measure [String] This is the local path to the measure directory, relative or absolute. It is used when zipping up all the measures.
74
+ # @param measure_metadata [Hash] Format of the measure.xml in JSON format
75
+ # @return [Object] Returns the measure that was added as an OpenStudio::AnalysisWorkflowStep object
76
+ def add_measure_from_analysis_hash(instance_name, instance_display_name, local_path_to_measure, measure_metadata)
77
+ @items << OpenStudio::Analysis::WorkflowStep.from_analysis_hash(instance_name, instance_display_name, local_path_to_measure, measure_metadata)
78
+
79
+ @items.last
80
+ end
81
+
82
+ # Add a measure from the format that Excel parses into. This is a helper method to map the excel data to the new
83
+ # programmatic interface format
84
+ #
85
+ # @params measure [Hash] The measure in the format of the Excel translator
86
+ # @return [Object] Returns the measure that was added as an OpenStudio::AnalysisWorkflowStep object
87
+ def add_measure_from_excel(measure)
88
+ hash = {}
89
+ hash[:classname] = measure['measure_file_name']
90
+ hash[:name] = measure['name']
91
+ hash[:display_name] = measure['display_name']
92
+ hash[:measure_type] = measure['measure_type']
93
+ hash[:uid] = measure['uid'] ? measure['uid'] : SecureRandom.uuid
94
+ hash[:version_id] = measure['version_id'] ? measure['version_id'] : SecureRandom.uuid
95
+
96
+ # map the arguments - this can be a variable or argument, add them all as arguments first,
97
+ # the make_variable will remove from arg and place into variables
98
+ args = []
99
+
100
+ measure['variables'].each do |variable|
101
+ args << {
102
+ local_variable: variable['name'],
103
+ variable_type: variable['type'],
104
+ name: variable['name'],
105
+ display_name: variable['display_name'],
106
+ display_name_short: variable['display_name_short'],
107
+ units: variable['units'],
108
+ default_value: variable['distribution']['static_value'],
109
+ value: variable['distribution']['static_value']
110
+ }
111
+ end
112
+ hash[:arguments] = args
113
+
114
+ m = add_measure(measure['name'], measure['display_name'], measure['local_path_to_measure'], hash)
115
+
116
+ measure['variables'].each do |variable|
117
+ next unless ['variable', 'pivot'].include? variable['variable_type']
118
+
119
+ dist = {
120
+ type: variable['distribution']['type'],
121
+ minimum: variable['distribution']['min'],
122
+ maximum: variable['distribution']['max'],
123
+ mean: variable['distribution']['mean'],
124
+ standard_deviation: variable['distribution']['stddev'],
125
+ values: variable['distribution']['discrete_values'],
126
+ weights: variable['distribution']['discrete_weights'],
127
+ step_size: variable['distribution']['delta_x']
128
+ }
129
+ opt = {
130
+ variable_type: variable['variable_type'],
131
+ variable_display_name_short: variable['display_name_short'],
132
+ static_value: variable['distribution']['static_value']
133
+ }
134
+
135
+ m.make_variable(variable['name'], variable['display_name'], dist, opt)
136
+ end
137
+ end
138
+
139
+ # Add a measure from the format that CSV parses into. This is a helper method to map the csv data to the new
140
+ # programmatic interface format
141
+ #
142
+ # @params measure [Hash] The measure in the format of the CSV translator
143
+ # @return [Object] Returns the measure that was added as an OpenStudio::AnalysisWorkflowStep object
144
+ def add_measure_from_csv(measure)
145
+ hash = {}
146
+ hash[:classname] = measure[:measure_data][:classname]
147
+ hash[:name] = measure[:measure_data][:name]
148
+ hash[:display_name] = measure[:measure_data][:display_name]
149
+ hash[:measure_type] = measure[:measure_data][:measure_type]
150
+ hash[:uid] = measure[:measure_data][:uid] ? measure[:measure_data][:uid] : SecureRandom.uuid
151
+ hash[:version_id] = measure[:measure_data][:version_id] ? measure[:measure_data][:version_id] : SecureRandom.uuid
152
+
153
+ # map the arguments - this can be a variable or argument, add them all as arguments first,
154
+ # the make_variable will remove from arg and place into variables
155
+ hash[:arguments] = measure[:args]
156
+
157
+ m = add_measure(measure[:measure_data][:name], measure[:measure_data][:display_name], measure[:measure_data][:local_path_to_measure], hash)
158
+
159
+ measure[:vars].each do |variable|
160
+ next unless ['variable', 'pivot'].include? variable[:variable_type]
161
+
162
+ dist = variable[:distribution]
163
+ opt = {
164
+ variable_type: variable[:variable_type],
165
+ variable_display_name_short: variable[:display_name_short],
166
+ static_value: variable[:distribution][:mode]
167
+ }
168
+
169
+ m.make_variable(variable[:name], variable[:display_name], dist, opt)
170
+ end
171
+ end
172
+
173
+ # Iterate over all the WorkflowItems
174
+ def each
175
+ @items.each { |i| yield i }
176
+ end
177
+
178
+ # Find the measure by its instance name
179
+ #
180
+ # @params instance_name [String] instance name of the measure
181
+ # @return [Object] The WorkflowStep with the instance_name
182
+ def find_measure(instance_name)
183
+ @items.find { |i| i.name == instance_name }
184
+ end
185
+ alias find_workflow_step find_measure
186
+
187
+ # Return all the variables in the analysis as an array. The list that is returned is read only.
188
+ #
189
+ # @return [Array] All variables in the workflow
190
+ def all_variables
191
+ @items.map(&:variables).flatten
192
+ end
193
+
194
+ # Save the workflow to a hash object
195
+ def to_hash(version = 1)
196
+ h = nil
197
+ if version == 1
198
+ arr = []
199
+ @items.each_with_index do |item, index|
200
+ temp_h = item.to_hash(version)
201
+ temp_h[:workflow_index] = index
202
+
203
+ arr << temp_h
204
+ end
205
+
206
+ h = arr
207
+ else
208
+ raise "Version #{version} not yet implemented for to_hash"
209
+ end
210
+
211
+ h
212
+ end
213
+
214
+ # Save the workflow to a JSON string
215
+ #
216
+ # @return [String] JSON formatted string
217
+ def to_json(version = 1)
218
+ if version == 1
219
+ JSON.pretty_generate(to_hash(version))
220
+ else
221
+ raise "Version #{version} not yet implemented for to_json"
222
+ end
223
+ end
224
+
225
+ # Load from a from a hash
226
+ #
227
+ # @param h [Hash or String] Path to file or hash
228
+ def self.load(h)
229
+ # get the version of the file
230
+ file_format_version = h[:file_format_version] ? h[:file_format_version] : 1
231
+ puts "Parsing file version #{file_format_version}"
232
+
233
+ o = OpenStudio::Analysis::Workflow.new
234
+
235
+ if h[:workflow]
236
+ h[:workflow].each do |wf|
237
+ puts "Adding measure #{wf[:name]}"
238
+
239
+ # Go though the defined measure paths and try and find the local measure
240
+ local_measure_dir = nil
241
+ if wf[:measure_definition_directory_local] && Dir.exist?(wf[:measure_definition_directory_local])
242
+ local_measure_dir = wf[:measure_definition_directory_local]
243
+ else
244
+ # search in the measure paths for the measure
245
+ OpenStudio::Analysis.measure_paths.each do |p|
246
+ test_dir = File.join(p, File.basename(wf[:measure_definition_directory]))
247
+ if Dir.exist?(test_dir)
248
+ local_measure_dir = test_dir
249
+ break
250
+ end
251
+ end
252
+ end
253
+
254
+ raise "Could not find local measure when loading workflow for #{wf[:measure_definition_class_name]} in #{File.basename(wf[:measure_definition_directory])}. You may have to add measure paths to OpenStudio::Analysis.measure_paths" unless local_measure_dir
255
+
256
+ o.add_measure_from_analysis_hash(wf[:name], wf[:display_name], local_measure_dir, wf)
257
+ end
258
+ end
259
+ o
260
+ end
261
+
262
+ # Read the Workflow description from a persisted file. The format at the moment is the current analysis.json
263
+ #
264
+ # @params filename [String] Path to file with the analysis.json to load
265
+ # @return [Object] Return an instance of the workflow object
266
+ def self.from_file(filename)
267
+ o = nil
268
+ if File.exist? filename
269
+ j = JSON.parse(File.read(filename), symbolize_names: true)
270
+ o = OpenStudio::Analysis::Workflow.load(j)
271
+ else
272
+ raise "Could not find workflow file #{filename}"
273
+ end
274
+
275
+ o
276
+ end
277
+ end
278
+ end
279
+ end