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.
@@ -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
@@ -1,5 +1,5 @@
1
1
  module OpenStudio
2
2
  module Analysis
3
- VERSION = '0.4.5'
3
+ VERSION = '1.0.0.pat1'
4
4
  end
5
5
  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
- v[:uncertainty_description][:type] = v[:type] =~ /uncertain/ ? "#{v[:type]}" : "#{v[:type]}_uncertain"
183
- warn "Deprecation Warning. In Version 0.5 the _uncertain text will be removed from distribution types: #{v[:uncertainty_description][:type]}"
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] = []
@@ -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
@@ -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'
@@ -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', '~> 1.12'
28
- s.add_dependency 'rubyzip', '~> 1.0' # don't update because of jruby
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', '~> 10.0'
34
+ s.add_development_dependency 'rake', '~> 11.1'
34
35
  end