openstudio-analysis 1.3.6 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/openstudio-analysis.yml +40 -40
- data/.gitignore +21 -21
- data/.rubocop.yml +9 -9
- data/CHANGELOG.md +274 -269
- data/Gemfile +14 -14
- data/README.md +102 -102
- data/Rakefile +40 -40
- data/lib/openstudio/analysis/algorithm_attributes.rb +47 -47
- data/lib/openstudio/analysis/formulation.rb +881 -857
- data/lib/openstudio/analysis/server_api.rb +862 -862
- data/lib/openstudio/analysis/server_scripts.rb +108 -108
- data/lib/openstudio/analysis/support_files.rb +104 -104
- data/lib/openstudio/analysis/translator/datapoints.rb +454 -454
- data/lib/openstudio/analysis/translator/excel.rb +893 -893
- data/lib/openstudio/analysis/translator/workflow.rb +143 -143
- data/lib/openstudio/analysis/version.rb +12 -12
- data/lib/openstudio/analysis/workflow.rb +302 -279
- data/lib/openstudio/analysis/workflow_step.rb +523 -523
- data/lib/openstudio/analysis.rb +144 -144
- data/lib/openstudio/helpers/hash.rb +10 -10
- data/lib/openstudio/helpers/string.rb +36 -36
- data/lib/openstudio/helpers/utils.rb +36 -36
- data/lib/openstudio/weather/epw.rb +178 -178
- data/lib/openstudio-analysis.rb +47 -47
- data/openstudio-analysis.gemspec +38 -38
- data/update_license.rb +60 -60
- metadata +2 -2
@@ -1,279 +1,302 @@
|
|
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
|
-
#
|
188
|
-
#
|
189
|
-
#
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
if
|
198
|
-
|
199
|
-
@items.
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
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
|
+
# Move a measure by its name to after another measure by its name,
|
188
|
+
# error if there is no measure with the name. If no after measure
|
189
|
+
# name is passed, then it will be at the beginning
|
190
|
+
#
|
191
|
+
# @params measure_name [String] instance name of the measure
|
192
|
+
# @params after_measure_name [String] instance name of the measure to move after
|
193
|
+
def move_measure_after(measure_name, after_measure_name=nil)
|
194
|
+
measure = self.find_measure(measure_name)
|
195
|
+
raise "Could not find measure with name #{measure_name}" unless measure
|
196
|
+
|
197
|
+
if after_measure_name.nil?
|
198
|
+
# put the measure at the beginning
|
199
|
+
@items.insert(0, @items.delete(measure))
|
200
|
+
else
|
201
|
+
after_measure = self.find_measure(after_measure_name)
|
202
|
+
raise "Could not find measure with name #{after_measure_name}" unless after_measure
|
203
|
+
|
204
|
+
# the index will be the index of the after measure plus 1 or the len of the list
|
205
|
+
idx = [@items.index(after_measure)+1, @items.length-1].min
|
206
|
+
@items.insert(idx, @items.delete(measure))
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# Return all the variables in the analysis as an array. The list that is returned is read only.
|
211
|
+
#
|
212
|
+
# @return [Array] All variables in the workflow
|
213
|
+
def all_variables
|
214
|
+
@items.map(&:variables).flatten
|
215
|
+
end
|
216
|
+
|
217
|
+
# Save the workflow to a hash object
|
218
|
+
def to_hash(version = 1)
|
219
|
+
h = nil
|
220
|
+
if version == 1
|
221
|
+
arr = []
|
222
|
+
@items.each_with_index do |item, index|
|
223
|
+
temp_h = item.to_hash(version)
|
224
|
+
temp_h[:workflow_index] = index
|
225
|
+
|
226
|
+
arr << temp_h
|
227
|
+
end
|
228
|
+
|
229
|
+
h = arr
|
230
|
+
else
|
231
|
+
raise "Version #{version} not yet implemented for to_hash"
|
232
|
+
end
|
233
|
+
|
234
|
+
h
|
235
|
+
end
|
236
|
+
|
237
|
+
# Save the workflow to a JSON string
|
238
|
+
#
|
239
|
+
# @return [String] JSON formatted string
|
240
|
+
def to_json(version = 1)
|
241
|
+
if version == 1
|
242
|
+
JSON.pretty_generate(to_hash(version))
|
243
|
+
else
|
244
|
+
raise "Version #{version} not yet implemented for to_json"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
# Load from a from a hash
|
249
|
+
#
|
250
|
+
# @param h [Hash or String] Path to file or hash
|
251
|
+
def self.load(h)
|
252
|
+
# get the version of the file
|
253
|
+
file_format_version = h[:file_format_version] ? h[:file_format_version] : 1
|
254
|
+
puts "Parsing file version #{file_format_version}"
|
255
|
+
|
256
|
+
o = OpenStudio::Analysis::Workflow.new
|
257
|
+
|
258
|
+
if h[:workflow]
|
259
|
+
h[:workflow].each do |wf|
|
260
|
+
puts "Adding measure #{wf[:name]}"
|
261
|
+
|
262
|
+
# Go though the defined measure paths and try and find the local measure
|
263
|
+
local_measure_dir = nil
|
264
|
+
if wf[:measure_definition_directory_local] && Dir.exist?(wf[:measure_definition_directory_local])
|
265
|
+
local_measure_dir = wf[:measure_definition_directory_local]
|
266
|
+
else
|
267
|
+
# search in the measure paths for the measure
|
268
|
+
OpenStudio::Analysis.measure_paths.each do |p|
|
269
|
+
test_dir = File.join(p, File.basename(wf[:measure_definition_directory]))
|
270
|
+
if Dir.exist?(test_dir)
|
271
|
+
local_measure_dir = test_dir
|
272
|
+
break
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
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
|
278
|
+
|
279
|
+
o.add_measure_from_analysis_hash(wf[:name], wf[:display_name], local_measure_dir, wf)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
o
|
283
|
+
end
|
284
|
+
|
285
|
+
# Read the Workflow description from a persisted file. The format at the moment is the current analysis.json
|
286
|
+
#
|
287
|
+
# @params filename [String] Path to file with the analysis.json to load
|
288
|
+
# @return [Object] Return an instance of the workflow object
|
289
|
+
def self.from_file(filename)
|
290
|
+
o = nil
|
291
|
+
if File.exist? filename
|
292
|
+
j = JSON.parse(File.read(filename), symbolize_names: true)
|
293
|
+
o = OpenStudio::Analysis::Workflow.load(j)
|
294
|
+
else
|
295
|
+
raise "Could not find workflow file #{filename}"
|
296
|
+
end
|
297
|
+
|
298
|
+
o
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|