openstudio-analysis 1.3.5 → 1.3.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,144 +1,144 @@
1
- # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
- # See also https://openstudio.net/license
4
- # *******************************************************************************
5
-
6
- # OpenStudio::Analysis Module instantiates versions of formulations
7
- module OpenStudio
8
- module Analysis
9
- # Create a new analysis
10
- def self.create(display_name)
11
- OpenStudio::Analysis::Formulation.new(display_name)
12
- end
13
-
14
- # Load the analysis json or from a file. If this is a json then it must have
15
- # symbolized keys
16
- def self.load(h)
17
- h = MultiJson.load(h, symbolize_keys: true) unless h.is_a? Hash
18
- OpenStudio::Analysis::Formulation.from_hash h
19
- end
20
-
21
- # Load an analysis from excel. This will create an array of analyses because
22
- # excel can create more than one analyses
23
- def self.from_excel(filename)
24
- excel = OpenStudio::Analysis::Translator::Excel.new(filename)
25
- excel.process
26
- excel.analyses
27
- end
28
-
29
- # Load an set of batch datapoints from a csv. This will create a analysis
30
- # of type 'batch_datapoints' which requires 'batch_run'
31
- def self.from_csv(filename)
32
- csv = OpenStudio::Analysis::Translator::Datapoints.new(filename)
33
- csv.process
34
- csv.analysis
35
- end
36
-
37
- # Process an OSA with a set of OSDs into OSWs
38
- def self.make_osws(osa_filename, osd_array)
39
- translator = OpenStudio::Analysis::Translator::Workflow.new(osa_filename)
40
- osd_array.each { |osd| translator.process_datapoints osd }
41
- end
42
-
43
- # Retrieve aws instance options from a project. This will return a hash
44
- def self.aws_instance_options(filename)
45
- if File.extname(filename) == '.xlsx'
46
- excel = OpenStudio::Analysis::Translator::Excel.new(filename)
47
- excel.process
48
- options = {
49
- os_server_version: excel.settings['openstudio_server_version'],
50
- server_instance_type: excel.settings['server_instance_type'],
51
- worker_instance_type: excel.settings['worker_instance_type'],
52
- worker_node_number: excel.settings['worker_nodes'].to_i,
53
- user_id: excel.settings['user_id'],
54
- aws_tags: excel.aws_tags,
55
- analysis_type: excel.analyses.first.analysis_type,
56
- cluster_name: excel.cluster_name
57
- }
58
- elsif File.extname(filename) == '.csv'
59
- csv = OpenStudio::Analysis::Translator::Datapoints.new(filename)
60
- csv.process
61
- options = csv.settings
62
- else
63
- raise 'Invalid file extension'
64
- end
65
-
66
- return options
67
- end
68
-
69
- # Generate a DEnCity complient hash for uploading from the analysis hash
70
- # TODO make this work off of the analysis object, not the hash.
71
- def self.to_dencity_analysis(analysis_hash, analysis_uuid)
72
- dencity_hash = {}
73
- a = analysis_hash[:analysis]
74
- provenance = {}
75
- provenance[:user_defined_id] = analysis_uuid
76
- provenance[:user_created_date] = ::Time.now
77
- provenance[:analysis_types] = [a[:problem][:analysis_type]]
78
- provenance[:name] = a[:name]
79
- provenance[:display_name] = a[:display_name]
80
- provenance[:description] = 'Auto-generated DEnCity analysis hash using the OpenStudio Analysis Gem'
81
- measure_metadata = []
82
- if a[:problem]
83
- if a[:problem][:algorithm]
84
- provenance[:analysis_information] = a[:problem][:algorithm]
85
- else
86
- raise 'No algorithm found in the analysis.json.'
87
- end
88
-
89
- if a[:problem][:workflow]
90
- a[:problem][:workflow].each do |wf|
91
- new_wfi = {}
92
- new_wfi[:id] = wf[:measure_definition_uuid]
93
- new_wfi[:version_id] = wf[:measure_definition_version_uuid]
94
-
95
- # Eventually all of this could be pulled directly from BCL
96
- new_wfi[:name] = wf[:measure_definition_class_name] if wf[:measure_definition_class_name]
97
- new_wfi[:display_name] = wf[:measure_definition_display_name] if wf[:measure_definition_display_name]
98
- new_wfi[:type] = wf[:measure_type] if wf[:measure_type]
99
- new_wfi[:modeler_description] = wf[:modeler_description] if wf[:modeler_description]
100
- new_wfi[:description] = wf[:description] if wf[:description]
101
- new_wfi[:arguments] = []
102
-
103
- wf[:arguments]&.each do |arg|
104
- wfi_arg = {}
105
- wfi_arg[:display_name] = arg[:display_name] if arg[:display_name]
106
- wfi_arg[:display_name_short] = arg[:display_name_short] if arg[:display_name_short]
107
- wfi_arg[:name] = arg[:name] if arg[:name]
108
- wfi_arg[:data_type] = arg[:value_type] if arg[:value_type]
109
- wfi_arg[:default_value] = nil
110
- wfi_arg[:description] = ''
111
- wfi_arg[:display_units] = '' # should be haystack compatible unit strings
112
- wfi_arg[:units] = '' # should be haystack compatible unit strings
113
-
114
- new_wfi[:arguments] << wfi_arg
115
- end
116
-
117
- wf[:variables]&.each do |arg|
118
- wfi_var = {}
119
- wfi_var[:display_name] = arg[:argument][:display_name] if arg[:argument][:display_name]
120
- wfi_var[:display_name_short] = arg[:argument][:display_name_short] if arg[:argument][:display_name_short]
121
- wfi_var[:name] = arg[:argument][:name] if arg[:argument][:name]
122
- wfi_var[:default_value] = nil
123
- wfi_var[:data_type] = arg[:argument][:value_type] if arg[:argument][:value_type]
124
- wfi_var[:description] = ''
125
- wfi_var[:display_units] = arg[:units] if arg[:units]
126
- wfi_var[:units] = '' # should be haystack compatible unit strings
127
- new_wfi[:arguments] << wfi_var
128
- end
129
-
130
- measure_metadata << new_wfi
131
- end
132
- else
133
- raise 'No workflow found in the analysis.json'
134
- end
135
-
136
- dencity_hash[:analysis] = provenance
137
- dencity_hash[:measure_definitions] = measure_metadata
138
- else
139
- raise 'No problem found in the analysis.json'
140
- end
141
- return dencity_hash
142
- end
143
- end
144
- end
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://openstudio.net/license
4
+ # *******************************************************************************
5
+
6
+ # OpenStudio::Analysis Module instantiates versions of formulations
7
+ module OpenStudio
8
+ module Analysis
9
+ # Create a new analysis
10
+ def self.create(display_name)
11
+ OpenStudio::Analysis::Formulation.new(display_name)
12
+ end
13
+
14
+ # Load the analysis json or from a file. If this is a json then it must have
15
+ # symbolized keys
16
+ def self.load(h)
17
+ h = MultiJson.load(h, symbolize_keys: true) unless h.is_a? Hash
18
+ OpenStudio::Analysis::Formulation.from_hash h
19
+ end
20
+
21
+ # Load an analysis from excel. This will create an array of analyses because
22
+ # excel can create more than one analyses
23
+ def self.from_excel(filename)
24
+ excel = OpenStudio::Analysis::Translator::Excel.new(filename)
25
+ excel.process
26
+ excel.analyses
27
+ end
28
+
29
+ # Load an set of batch datapoints from a csv. This will create a analysis
30
+ # of type 'batch_datapoints' which requires 'batch_run'
31
+ def self.from_csv(filename)
32
+ csv = OpenStudio::Analysis::Translator::Datapoints.new(filename)
33
+ csv.process
34
+ csv.analysis
35
+ end
36
+
37
+ # Process an OSA with a set of OSDs into OSWs
38
+ def self.make_osws(osa_filename, osd_array)
39
+ translator = OpenStudio::Analysis::Translator::Workflow.new(osa_filename)
40
+ osd_array.each { |osd| translator.process_datapoints osd }
41
+ end
42
+
43
+ # Retrieve aws instance options from a project. This will return a hash
44
+ def self.aws_instance_options(filename)
45
+ if File.extname(filename) == '.xlsx'
46
+ excel = OpenStudio::Analysis::Translator::Excel.new(filename)
47
+ excel.process
48
+ options = {
49
+ os_server_version: excel.settings['openstudio_server_version'],
50
+ server_instance_type: excel.settings['server_instance_type'],
51
+ worker_instance_type: excel.settings['worker_instance_type'],
52
+ worker_node_number: excel.settings['worker_nodes'].to_i,
53
+ user_id: excel.settings['user_id'],
54
+ aws_tags: excel.aws_tags,
55
+ analysis_type: excel.analyses.first.analysis_type,
56
+ cluster_name: excel.cluster_name
57
+ }
58
+ elsif File.extname(filename) == '.csv'
59
+ csv = OpenStudio::Analysis::Translator::Datapoints.new(filename)
60
+ csv.process
61
+ options = csv.settings
62
+ else
63
+ raise 'Invalid file extension'
64
+ end
65
+
66
+ return options
67
+ end
68
+
69
+ # Generate a DEnCity complient hash for uploading from the analysis hash
70
+ # TODO make this work off of the analysis object, not the hash.
71
+ def self.to_dencity_analysis(analysis_hash, analysis_uuid)
72
+ dencity_hash = {}
73
+ a = analysis_hash[:analysis]
74
+ provenance = {}
75
+ provenance[:user_defined_id] = analysis_uuid
76
+ provenance[:user_created_date] = ::Time.now
77
+ provenance[:analysis_types] = [a[:problem][:analysis_type]]
78
+ provenance[:name] = a[:name]
79
+ provenance[:display_name] = a[:display_name]
80
+ provenance[:description] = 'Auto-generated DEnCity analysis hash using the OpenStudio Analysis Gem'
81
+ measure_metadata = []
82
+ if a[:problem]
83
+ if a[:problem][:algorithm]
84
+ provenance[:analysis_information] = a[:problem][:algorithm]
85
+ else
86
+ raise 'No algorithm found in the analysis.json.'
87
+ end
88
+
89
+ if a[:problem][:workflow]
90
+ a[:problem][:workflow].each do |wf|
91
+ new_wfi = {}
92
+ new_wfi[:id] = wf[:measure_definition_uuid]
93
+ new_wfi[:version_id] = wf[:measure_definition_version_uuid]
94
+
95
+ # Eventually all of this could be pulled directly from BCL
96
+ new_wfi[:name] = wf[:measure_definition_class_name] if wf[:measure_definition_class_name]
97
+ new_wfi[:display_name] = wf[:measure_definition_display_name] if wf[:measure_definition_display_name]
98
+ new_wfi[:type] = wf[:measure_type] if wf[:measure_type]
99
+ new_wfi[:modeler_description] = wf[:modeler_description] if wf[:modeler_description]
100
+ new_wfi[:description] = wf[:description] if wf[:description]
101
+ new_wfi[:arguments] = []
102
+
103
+ wf[:arguments]&.each do |arg|
104
+ wfi_arg = {}
105
+ wfi_arg[:display_name] = arg[:display_name] if arg[:display_name]
106
+ wfi_arg[:display_name_short] = arg[:display_name_short] if arg[:display_name_short]
107
+ wfi_arg[:name] = arg[:name] if arg[:name]
108
+ wfi_arg[:data_type] = arg[:value_type] if arg[:value_type]
109
+ wfi_arg[:default_value] = nil
110
+ wfi_arg[:description] = ''
111
+ wfi_arg[:display_units] = '' # should be haystack compatible unit strings
112
+ wfi_arg[:units] = '' # should be haystack compatible unit strings
113
+
114
+ new_wfi[:arguments] << wfi_arg
115
+ end
116
+
117
+ wf[:variables]&.each do |arg|
118
+ wfi_var = {}
119
+ wfi_var[:display_name] = arg[:argument][:display_name] if arg[:argument][:display_name]
120
+ wfi_var[:display_name_short] = arg[:argument][:display_name_short] if arg[:argument][:display_name_short]
121
+ wfi_var[:name] = arg[:argument][:name] if arg[:argument][:name]
122
+ wfi_var[:default_value] = nil
123
+ wfi_var[:data_type] = arg[:argument][:value_type] if arg[:argument][:value_type]
124
+ wfi_var[:description] = ''
125
+ wfi_var[:display_units] = arg[:units] if arg[:units]
126
+ wfi_var[:units] = '' # should be haystack compatible unit strings
127
+ new_wfi[:arguments] << wfi_var
128
+ end
129
+
130
+ measure_metadata << new_wfi
131
+ end
132
+ else
133
+ raise 'No workflow found in the analysis.json'
134
+ end
135
+
136
+ dencity_hash[:analysis] = provenance
137
+ dencity_hash[:measure_definitions] = measure_metadata
138
+ else
139
+ raise 'No problem found in the analysis.json'
140
+ end
141
+ return dencity_hash
142
+ end
143
+ end
144
+ end
@@ -1,10 +1,10 @@
1
- # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
- # See also https://openstudio.net/license
4
- # *******************************************************************************
5
-
6
- class Hash
7
- def deep_find(key)
8
- key?(key) ? self[key] : values.reduce(nil) { |memo, v| memo ||= v.deep_find(key) if v.respond_to?(:deep_find) }
9
- end
10
- end
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://openstudio.net/license
4
+ # *******************************************************************************
5
+
6
+ class Hash
7
+ def deep_find(key)
8
+ key?(key) ? self[key] : values.reduce(nil) { |memo, v| memo ||= v.deep_find(key) if v.respond_to?(:deep_find) }
9
+ end
10
+ end
@@ -1,36 +1,36 @@
1
- # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
- # See also https://openstudio.net/license
4
- # *******************************************************************************
5
-
6
- # Typecast Variable Values by a string.
7
- def typecast_value(variable_type, value, inspect_string = false)
8
- out_value = nil
9
- unless value.nil?
10
- case variable_type.downcase
11
- when 'double'
12
- out_value = value.to_f
13
- when 'integer'
14
- out_value = value.to_i
15
- when 'string', 'choice'
16
- out_value = inspect_string ? value.inspect : value.to_s
17
- when 'bool', 'boolean'
18
- # Check if the value is already a boolean
19
- if !!value == value
20
- out_value = value
21
- else
22
- if value.casecmp('true').zero?
23
- out_value = true
24
- elsif value.casecmp('false').zero?
25
- out_value = false
26
- else
27
- raise "Can't cast to a bool from a value of '#{value}' of class '#{value.class}'"
28
- end
29
- end
30
- else
31
- raise "Unknown variable type of '#{@variable['type']}'"
32
- end
33
- end
34
-
35
- out_value
36
- end
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://openstudio.net/license
4
+ # *******************************************************************************
5
+
6
+ # Typecast Variable Values by a string.
7
+ def typecast_value(variable_type, value, inspect_string = false)
8
+ out_value = nil
9
+ unless value.nil?
10
+ case variable_type.downcase
11
+ when 'double'
12
+ out_value = value.to_f
13
+ when 'integer'
14
+ out_value = value.to_i
15
+ when 'string', 'choice'
16
+ out_value = inspect_string ? value.inspect : value.to_s
17
+ when 'bool', 'boolean'
18
+ # Check if the value is already a boolean
19
+ if !!value == value
20
+ out_value = value
21
+ else
22
+ if value.casecmp('true').zero?
23
+ out_value = true
24
+ elsif value.casecmp('false').zero?
25
+ out_value = false
26
+ else
27
+ raise "Can't cast to a bool from a value of '#{value}' of class '#{value.class}'"
28
+ end
29
+ end
30
+ else
31
+ raise "Unknown variable type of '#{@variable['type']}'"
32
+ end
33
+ end
34
+
35
+ out_value
36
+ end
@@ -1,36 +1,36 @@
1
- # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
- # See also https://openstudio.net/license
4
- # *******************************************************************************
5
-
6
- require 'rexml/document'
7
-
8
- def parse_measure_xml(measure_xml_filename)
9
- measure_hash = {}
10
- xml_to_parse = File.open(measure_xml_filename)
11
- xml_root = REXML::Document.new(xml_to_parse).root
12
-
13
- # pull out some information
14
- measure_hash[:classname] = xml_root.elements['//measure/class_name'].text
15
- measure_hash[:name] = xml_root.elements['//measure/name'].text
16
- measure_hash[:display_name] = xml_root.elements['//measure/display_name'].text
17
- measure_hash[:display_name_titleized] = measure_hash[:name].titleize
18
- measure_hash[:measure_type] = xml_root.elements['//measure/attributes/attribute[name="Measure Type"]/value'].text
19
- measure_hash[:description] = xml_root.elements['//measure/description'].text
20
- measure_hash[:modeler_description] = xml_root.elements['//measure/modeler_description'].text
21
- measure_hash[:uid] = xml_root.elements['//measure/uid'].text
22
- measure_hash[:version_id] = xml_root.elements['//measure/version_id'].text
23
- measure_hash[:arguments] = []
24
-
25
- REXML::XPath.each(xml_root, '//measure/arguments/argument') do |arg|
26
- measure_hash[:arguments] << {
27
- name: arg.elements['name']&.text,
28
- display_name: arg.elements['display_name']&.text,
29
- variable_type: arg.elements['type']&.text.downcase,
30
- default_value: arg.elements['default_value']&.text,
31
- units: arg.elements['units']&.text || ''
32
- }
33
- end
34
-
35
- measure_hash
36
- end
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://openstudio.net/license
4
+ # *******************************************************************************
5
+
6
+ require 'rexml/document'
7
+
8
+ def parse_measure_xml(measure_xml_filename)
9
+ measure_hash = {}
10
+ xml_to_parse = File.open(measure_xml_filename)
11
+ xml_root = REXML::Document.new(xml_to_parse).root
12
+
13
+ # pull out some information
14
+ measure_hash[:classname] = xml_root.elements['//measure/class_name'].text
15
+ measure_hash[:name] = xml_root.elements['//measure/name'].text
16
+ measure_hash[:display_name] = xml_root.elements['//measure/display_name'].text
17
+ measure_hash[:display_name_titleized] = measure_hash[:name].titleize
18
+ measure_hash[:measure_type] = xml_root.elements['//measure/attributes/attribute[name="Measure Type"]/value'].text
19
+ measure_hash[:description] = xml_root.elements['//measure/description'].text
20
+ measure_hash[:modeler_description] = xml_root.elements['//measure/modeler_description'].text
21
+ measure_hash[:uid] = xml_root.elements['//measure/uid'].text
22
+ measure_hash[:version_id] = xml_root.elements['//measure/version_id'].text
23
+ measure_hash[:arguments] = []
24
+
25
+ REXML::XPath.each(xml_root, '//measure/arguments/argument') do |arg|
26
+ measure_hash[:arguments] << {
27
+ name: arg.elements['name']&.text,
28
+ display_name: arg.elements['display_name']&.text,
29
+ variable_type: arg.elements['type']&.text.downcase,
30
+ default_value: arg.elements['default_value']&.text,
31
+ units: arg.elements['units']&.text || ''
32
+ }
33
+ end
34
+
35
+ measure_hash
36
+ end