openstudio-analysis 0.4.5 → 1.0.0.pat1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +7 -3
- data/Gemfile +1 -0
- data/README.md +53 -47
- data/lib/openstudio/analysis/formulation.rb +1 -1
- data/lib/openstudio/analysis/server_api.rb +143 -246
- data/lib/openstudio/analysis/translator/datapoints.rb +8 -3
- data/lib/openstudio/analysis/translator/excel.rb +16 -4
- data/lib/openstudio/analysis/translator/workflow.rb +106 -0
- data/lib/openstudio/analysis/version.rb +1 -1
- data/lib/openstudio/analysis/workflow_step.rb +5 -2
- data/lib/openstudio/analysis.rb +85 -0
- data/lib/openstudio-analysis.rb +1 -0
- data/openstudio-analysis.gemspec +4 -3
- data/spec/files/workflow/analysis.osa +1334 -0
- data/spec/files/workflow/datapoint_0.osd +63 -0
- data/spec/files/workflow/datapoint_1.osd +63 -0
- data/spec/files/workflow/datapoint_2.osd +63 -0
- data/spec/files/workflow/datapoint_wrong_osa_id.osd +65 -0
- data/spec/openstudio/excel_spec.rb +0 -5
- data/spec/openstudio/osw_spec.rb +618 -0
- metadata +36 -9
@@ -0,0 +1,106 @@
|
|
1
|
+
module OpenStudio
|
2
|
+
module Analysis
|
3
|
+
module Translator
|
4
|
+
|
5
|
+
require 'json'
|
6
|
+
require 'securerandom'
|
7
|
+
|
8
|
+
class Workflow
|
9
|
+
attr_reader :osa_filename
|
10
|
+
attr_reader :root_path
|
11
|
+
attr_reader :analysis
|
12
|
+
attr_reader :osa
|
13
|
+
attr_reader :osw_version
|
14
|
+
attr_reader :options
|
15
|
+
attr_reader :file_paths
|
16
|
+
attr_reader :measure_paths
|
17
|
+
attr_reader :seed_file
|
18
|
+
attr_reader :weather_file
|
19
|
+
attr_reader :osa_id
|
20
|
+
attr_reader :steps
|
21
|
+
|
22
|
+
def initialize(osa_filename, options = {})
|
23
|
+
@osa_filename = osa_filename
|
24
|
+
@root_path = File.expand_path(File.dirname(@osa_filename))
|
25
|
+
|
26
|
+
# try to read the osa json file
|
27
|
+
if File.exist?(@osa_filename)
|
28
|
+
@osa = ::JSON.parse(File.read(@osa_filename), {symbolize_names: true})[:analysis]
|
29
|
+
else
|
30
|
+
fail "File #{@osa_filename} does not exist"
|
31
|
+
end
|
32
|
+
|
33
|
+
# Initialize some other instance variables
|
34
|
+
@osw_version = '0.0.1'
|
35
|
+
@options = options
|
36
|
+
@file_paths = options[:file_paths] ? options[:file_paths] : []
|
37
|
+
@measure_paths = options[:measure_paths] ? options[:measure_paths] : []
|
38
|
+
|
39
|
+
# Initialize static inputs from the OSA
|
40
|
+
@seed_file = File.basename @osa[:seed][:path]
|
41
|
+
@weather_file = File.basename @osa[:weather_file][:path]
|
42
|
+
@osa_id = @osa[:_id]
|
43
|
+
@steps = []
|
44
|
+
@osa[:problem][:workflow].each_with_index do |step, i|
|
45
|
+
step_hash = {}
|
46
|
+
step_hash[:measure_dir_name] = File.basename(step[:measure_definition_directory])
|
47
|
+
step_hash[:arguments] = {}
|
48
|
+
@osa[:problem][:workflow][i][:arguments].each do |arg|
|
49
|
+
step_hash[:arguments][arg[:name].to_sym] = arg[:value]
|
50
|
+
end
|
51
|
+
@steps << step_hash
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def process_datapoint(osd_filename)
|
56
|
+
# Try to read the osd json file
|
57
|
+
if File.exist?(osd_filename)
|
58
|
+
warn('data_point selector in ods will be changed to datapoint in version 1.0')
|
59
|
+
osd = ::JSON.parse(File.read(osd_filename), {symbolize_names: true})[:data_point]
|
60
|
+
else
|
61
|
+
fail "File #{osd_filename} does not exist"
|
62
|
+
end
|
63
|
+
|
64
|
+
# Parse the osd hash based off of the osa hash. First check that the analysis id matches
|
65
|
+
fail "File #{osd_filename} does not reference #{@osa_id}." unless @osa_id == osd[:analysis_id]
|
66
|
+
# @todo (rhorsey) Fix the spec so this line can be uncommented
|
67
|
+
osw_steps_instance = @steps
|
68
|
+
osw_steps_instance.each_with_index do |step, i|
|
69
|
+
@osa[:problem][:workflow][i][:variables].each do |var|
|
70
|
+
var_name = var[:argument][:name]
|
71
|
+
var_value_uuid = var[:uuid]
|
72
|
+
var_value = osd[:set_variable_values][var_value_uuid.to_sym]
|
73
|
+
step[:arguments][var_name.to_sym] = var_value
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Save the OSW hash
|
78
|
+
osw = {}
|
79
|
+
created_at = ::Time.now
|
80
|
+
osw[:seed_model] = @seed_file
|
81
|
+
osw[:weather_file] = @weather_file
|
82
|
+
osw[:file_format_version] = @osw_version
|
83
|
+
osw[:osa_id] = @osa_id
|
84
|
+
osw[:osd_id] = osd[:_id]
|
85
|
+
osw[:created_at] = created_at
|
86
|
+
osw[:measure_paths] = @measure_paths
|
87
|
+
osw[:file_paths] = @file_paths
|
88
|
+
osw[:run_directory] = './'
|
89
|
+
osw[:steps] = osw_steps_instance
|
90
|
+
return osw
|
91
|
+
end
|
92
|
+
|
93
|
+
# Runs an array of OSD files
|
94
|
+
def process_datapoints(osd_filename_array)
|
95
|
+
osd_filename_array.each do |osd_file|
|
96
|
+
begin
|
97
|
+
yield process_datapoint(osd_file)
|
98
|
+
rescue => e
|
99
|
+
puts "Warning: Failed to processes datapoint #{osd_file} with error #{e.message} in #{e.backtrace.join('\n')}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -179,8 +179,11 @@ module OpenStudio
|
|
179
179
|
v[:static_value] = v[:argument][:default_value] unless v[:static_value]
|
180
180
|
|
181
181
|
v[:uncertainty_description] = {}
|
182
|
-
|
183
|
-
|
182
|
+
# In Version 0.5 the _uncertain text will be removed from distribution
|
183
|
+
if v[:type] =~ /uncertain/
|
184
|
+
v[:type].delete!('_uncertain')
|
185
|
+
end
|
186
|
+
v[:uncertainty_description][:type] = v[:type]
|
184
187
|
|
185
188
|
# This is not neatly coded. This should be a new object that knows how to write itself out.
|
186
189
|
v[:uncertainty_description][:attributes] = []
|
data/lib/openstudio/analysis.rb
CHANGED
@@ -29,6 +29,12 @@ module OpenStudio
|
|
29
29
|
csv.analysis
|
30
30
|
end
|
31
31
|
|
32
|
+
# Process an OSA with a set of OSDs into OSWs
|
33
|
+
def self.make_osws(osa_filename, osd_array)
|
34
|
+
translator = OpenStudio::Analysis::Translator::Workflow.new(osa_filename)
|
35
|
+
osd_array.each {|osd| translator.process_datapoints osd}
|
36
|
+
end
|
37
|
+
|
32
38
|
# Retrieve aws instance options from a project. This will return a hash
|
33
39
|
def self.aws_instance_options(filename)
|
34
40
|
if File.extname(filename) == '.xlsx'
|
@@ -54,5 +60,84 @@ module OpenStudio
|
|
54
60
|
|
55
61
|
return options
|
56
62
|
end
|
63
|
+
|
64
|
+
# Generate a DEnCity complient hash for uploading from the analysis hash
|
65
|
+
#TODO make this work off of the analysis object, not the hash.
|
66
|
+
def self.to_dencity_analysis(analysis_hash, analysis_uuid)
|
67
|
+
dencity_hash = {}
|
68
|
+
a = analysis_hash[:analysis]
|
69
|
+
provenance = {}
|
70
|
+
provenance[:user_defined_id] = analysis_uuid
|
71
|
+
provenance[:user_created_date] = ::Time.now
|
72
|
+
provenance[:analysis_types] = [a[:problem][:analysis_type]]
|
73
|
+
provenance[:name] = a[:name]
|
74
|
+
provenance[:display_name] = a[:display_name]
|
75
|
+
provenance[:description] = 'Auto-generated DEnCity analysis hash using the OpenStudio Analysis Gem'
|
76
|
+
measure_metadata = []
|
77
|
+
if a[:problem]
|
78
|
+
if a[:problem][:algorithm]
|
79
|
+
provenance[:analysis_information] = a[:problem][:algorithm]
|
80
|
+
else
|
81
|
+
fail 'No algorithm found in the analysis.json.'
|
82
|
+
end
|
83
|
+
|
84
|
+
if a[:problem][:workflow]
|
85
|
+
a[:problem][:workflow].each do |wf|
|
86
|
+
new_wfi = {}
|
87
|
+
new_wfi[:id] = wf[:measure_definition_uuid]
|
88
|
+
new_wfi[:version_id] = wf[:measure_definition_version_uuid]
|
89
|
+
|
90
|
+
# Eventually all of this could be pulled directly from BCL
|
91
|
+
new_wfi[:name] = wf[:measure_definition_class_name] if wf[:measure_definition_class_name]
|
92
|
+
new_wfi[:display_name] = wf[:measure_definition_display_name] if wf[:measure_definition_display_name]
|
93
|
+
new_wfi[:type] = wf[:measure_type] if wf[:measure_type]
|
94
|
+
new_wfi[:modeler_description] = wf[:modeler_description] if wf[:modeler_description]
|
95
|
+
new_wfi[:description] = wf[:description] if wf[:description]
|
96
|
+
new_wfi[:arguments] = []
|
97
|
+
|
98
|
+
if wf[:arguments]
|
99
|
+
wf[:arguments].each do |arg|
|
100
|
+
wfi_arg = {}
|
101
|
+
wfi_arg[:display_name] = arg[:display_name] if arg[:display_name]
|
102
|
+
wfi_arg[:display_name_short] = arg[:display_name_short] if arg[:display_name_short]
|
103
|
+
wfi_arg[:name] = arg[:name] if arg[:name]
|
104
|
+
wfi_arg[:data_type] = arg[:value_type] if arg[:value_type]
|
105
|
+
wfi_arg[:default_value] = nil
|
106
|
+
wfi_arg[:description] = ''
|
107
|
+
wfi_arg[:display_units] = '' # should be haystack compatible unit strings
|
108
|
+
wfi_arg[:units] = '' # should be haystack compatible unit strings
|
109
|
+
|
110
|
+
new_wfi[:arguments] << wfi_arg
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
if wf[:variables]
|
115
|
+
wf[:variables].each do |arg|
|
116
|
+
wfi_var = {}
|
117
|
+
wfi_var[:display_name] = arg[:argument][:display_name] if arg[:argument][:display_name]
|
118
|
+
wfi_var[:display_name_short] = arg[:argument][:display_name_short] if arg[:argument][:display_name_short]
|
119
|
+
wfi_var[:name] = arg[:argument][:name] if arg[:argument][:name]
|
120
|
+
wfi_var[:default_value] = nil
|
121
|
+
wfi_var[:data_type] = arg[:argument][:value_type] if arg[:argument][:value_type]
|
122
|
+
wfi_var[:description] = ''
|
123
|
+
wfi_var[:display_units] = arg[:units] if arg[:units]
|
124
|
+
wfi_var[:units] = '' # should be haystack compatible unit strings
|
125
|
+
new_wfi[:arguments] << wfi_var
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
measure_metadata << new_wfi
|
130
|
+
end
|
131
|
+
else
|
132
|
+
fail 'No workflow found in the analysis.json'
|
133
|
+
end
|
134
|
+
|
135
|
+
dencity_hash[:analysis] = provenance
|
136
|
+
dencity_hash[:measure_definitions] = measure_metadata
|
137
|
+
else
|
138
|
+
fail 'No problem found in the analysis.json'
|
139
|
+
end
|
140
|
+
return dencity_hash
|
141
|
+
end
|
57
142
|
end
|
58
143
|
end
|
data/lib/openstudio-analysis.rb
CHANGED
@@ -30,6 +30,7 @@ require 'openstudio/analysis/algorithm_attributes'
|
|
30
30
|
# translators
|
31
31
|
require 'openstudio/analysis/translator/excel'
|
32
32
|
require 'openstudio/analysis/translator/datapoints'
|
33
|
+
require 'openstudio/analysis/translator/workflow'
|
33
34
|
|
34
35
|
# helpers / core_ext
|
35
36
|
require 'openstudio/helpers/string'
|
data/openstudio-analysis.gemspec
CHANGED
@@ -24,11 +24,12 @@ Gem::Specification.new do |s|
|
|
24
24
|
|
25
25
|
s.add_dependency 'faraday', '~> 0.8'
|
26
26
|
s.add_dependency 'nokogiri', '~> 1.6'
|
27
|
-
s.add_dependency 'roo', '~>
|
28
|
-
s.add_dependency 'rubyzip', '~> 1.
|
27
|
+
s.add_dependency 'roo', '~> 2.3'
|
28
|
+
s.add_dependency 'rubyzip', '~> 1.2' # Should be at 1.0 because of jruby
|
29
29
|
s.add_dependency 'semantic', '~> 1.4'
|
30
30
|
s.add_dependency 'bcl', '~> 0.5.5'
|
31
|
+
s.add_dependency 'dencity', '~> 0.1.0'
|
31
32
|
|
32
33
|
s.add_development_dependency 'bundler', '~> 1.7'
|
33
|
-
s.add_development_dependency 'rake', '~>
|
34
|
+
s.add_development_dependency 'rake', '~> 11.1'
|
34
35
|
end
|