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.
- checksums.yaml +4 -4
- data/.github/workflows/openstudio-analysis.yml +40 -40
- data/.gitignore +21 -21
- data/.rubocop.yml +9 -9
- data/CHANGELOG.md +269 -265
- 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 +857 -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 +279 -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 +9 -9
@@ -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
|