openstudio-analysis 0.4.5 → 1.0.0.pat1

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.
@@ -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