openstudio-analysis 0.3.7 → 0.4.0

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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -6
  3. data/README.md +55 -7
  4. data/Rakefile +10 -0
  5. data/lib/openstudio/analysis/algorithm_attributes.rb +22 -0
  6. data/lib/openstudio/analysis/formulation.rb +174 -0
  7. data/lib/openstudio/analysis/translator/excel.rb +65 -48
  8. data/lib/openstudio/analysis/version.rb +1 -1
  9. data/lib/openstudio/analysis/workflow.rb +197 -0
  10. data/lib/openstudio/analysis/workflow_step.rb +312 -0
  11. data/lib/openstudio/analysis.rb +8 -0
  12. data/lib/openstudio/helpers/string.rb +22 -22
  13. data/lib/openstudio/templates/analysis.json.erb +0 -1
  14. data/lib/openstudio-analysis.rb +9 -0
  15. data/spec/files/0_1_09_small_list_incomplete.xlsx +0 -0
  16. data/spec/files/0_2_0_template_simpletest.xlsx +0 -0
  17. data/spec/files/0_4_0_lhs_discrete_continuous.xlsx +0 -0
  18. data/spec/files/analysis/example_analysis_api.json +656 -0
  19. data/spec/files/analysis/examples/discrete_lhs_example.json +809 -0
  20. data/spec/files/analysis/examples/medium_office_example.json +1673 -0
  21. data/spec/files/analysis/lhs_discrete_and_continuous_variables_api.json +1230 -0
  22. data/spec/files/analysis/medium_office.json +91 -92
  23. data/spec/files/analysis/medium_office.zip +0 -0
  24. data/spec/files/analysis/name_goes_here_api.json +1681 -0
  25. data/spec/files/analysis/output_vars_api.json +632 -0
  26. data/spec/files/analysis/preflight_api.json +1518 -0
  27. data/spec/files/analysis/simple_test_api.json +519 -0
  28. data/spec/files/analysis/test_model_api.json +493 -0
  29. data/spec/files/export/analysis/0_1_09_outputvars.json +38 -39
  30. data/spec/files/export/analysis/0_1_09_outputvars.zip +0 -0
  31. data/spec/files/export/analysis/0_1_11_discrete_variables.json +46 -47
  32. data/spec/files/export/analysis/0_1_11_discrete_variables.zip +0 -0
  33. data/spec/files/export/analysis/0_1_12_discrete_dynamic_columns.json +8 -9
  34. data/spec/files/export/analysis/0_1_12_discrete_dynamic_columns.zip +0 -0
  35. data/spec/files/export/analysis/0_2_0_template_simpletest.json +19 -14
  36. data/spec/files/export/analysis/0_2_0_template_simpletest.zip +0 -0
  37. data/spec/files/export/analysis/0_3_0_outputs.json +99 -100
  38. data/spec/files/export/analysis/0_3_0_outputs.zip +0 -0
  39. data/spec/files/export/analysis/{6d6a08db-fdf8-4bb5-8ad3-18c471418c72.json → 276ccf51-ed22-4604-a380-8985cec5efe8.json} +103 -104
  40. data/spec/files/export/analysis/{6d6a08db-fdf8-4bb5-8ad3-18c471418c72.zip → 276ccf51-ed22-4604-a380-8985cec5efe8.zip} +0 -0
  41. data/spec/files/export/analysis/{55086845-70cf-487f-87f6-7a147cbf1e72.json → 639cb8a5-cdbb-4b69-955a-cbb650f6872b.json} +107 -108
  42. data/spec/files/export/analysis/{55086845-70cf-487f-87f6-7a147cbf1e72.zip → 639cb8a5-cdbb-4b69-955a-cbb650f6872b.zip} +0 -0
  43. data/spec/files/export/analysis/{10c791ce-cba7-4506-a863-3fb15703889b.json → 9560f95b-5730-4038-a95b-328c825c596b.json} +99 -100
  44. data/spec/files/export/analysis/{10c791ce-cba7-4506-a863-3fb15703889b.zip → 9560f95b-5730-4038-a95b-328c825c596b.zip} +0 -0
  45. data/spec/files/export/analysis/{f028bfbe-e30e-488d-adad-a60a62bbf7e0.json → c50f0062-cdfb-4dec-bc02-215f6c29af3c.json} +107 -108
  46. data/spec/files/export/analysis/{f028bfbe-e30e-488d-adad-a60a62bbf7e0.zip → c50f0062-cdfb-4dec-bc02-215f6c29af3c.zip} +0 -0
  47. data/spec/files/export/analysis/discrete_lhs_example.json +1185 -0
  48. data/spec/files/export/analysis/discrete_lhs_example.zip +0 -0
  49. data/spec/files/export/analysis/small_seed.json +38 -39
  50. data/spec/files/export/analysis/small_seed.zip +0 -0
  51. data/spec/files/export/workflow/analysis.json +23 -0
  52. data/spec/files/measures/ActualMeasureNoJson/measure.json +25 -0
  53. data/spec/files/measures/ActualMeasureNoJson/measure.rb +80 -0
  54. data/spec/files/measures/ActualMeasureNoJson/measure.xml +2 -0
  55. data/spec/files/measures/SetThermostatSchedules/measure.json +63 -0
  56. data/spec/files/measures/SetThermostatSchedules/measure.rb +254 -0
  57. data/spec/files/measures/SetThermostatSchedules/measure.xml +2 -0
  58. data/spec/openstudio/excel_spec.rb +11 -11
  59. data/spec/openstudio/formulation_spec.rb +107 -0
  60. data/spec/openstudio/workflow_spec.rb +90 -0
  61. data/spec/openstudio/workflow_step_spec.rb +116 -0
  62. data/spec/reports/SPEC-OpenStudio-Analysis-Formulation.xml +28 -0
  63. data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi-create-a-new-object-instance.xml +2 -2
  64. data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi-test-not-localhost.xml +2 -2
  65. data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi.xml +1 -1
  66. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-discrete-variables.xml +30 -4
  67. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-discrete-with-dynamic-columns.xml +11 -3
  68. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-no-variables-defined.xml +6 -6
  69. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-proxy-setup-with-user.xml +2 -2
  70. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-proxy-setup.xml +2 -2
  71. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-setup-output-variables.xml +52 -8
  72. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-setup-version-0-1-9.xml +22 -5
  73. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-incomplete-variables.xml +2 -2
  74. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-variables-should-not-validate.xml +2 -2
  75. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-variables.xml +28 -5
  76. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-with-with-repeated-variable-names.xml +2 -2
  77. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-1-10.xml +3 -3
  78. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-2-0-simple.xml +13 -6
  79. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-2-0.xml +55 -5
  80. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-0-dynamic-uuid-assignments.xml +9 -4
  81. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-0-measure-existence-checks.xml +8 -3
  82. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-0-objective-functions.xml +13 -5
  83. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-3-and-short-display-names.xml +9 -4
  84. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-5-and-measure-paths.xml +9 -4
  85. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-7-and-worker-init-final-scripts.0.xml +40 -2
  86. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-7-and-worker-init-final-scripts.xml +9 -4
  87. data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel.xml +1 -1
  88. data/spec/reports/SPEC-OpenStudio-Analysis-Workflow.xml +31 -0
  89. data/spec/reports/SPEC-OpenStudio-Analysis-WorkflowStep.xml +29 -0
  90. data/spec/spec_helper.rb +1 -1
  91. metadata +87 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9d66a0d90f0f410e7db18fbdc523c191991d5d20
4
- data.tar.gz: da6f448c4902518e932ad8a17dd183be1d6ff8d7
3
+ metadata.gz: 8716110e6823303d2e72cbcf6b2ddb1a4284776c
4
+ data.tar.gz: 7a7a80b05caa4e9c9ab2172b1b65965ce8f3cd77
5
5
  SHA512:
6
- metadata.gz: d5440d40d0d9bcaf5d0d07e4f8a88471df0d8063b88c2fd2da335b5d48fd3900fe39c72045b398d8929f594ee5fb40fb3038c96bb9896bfef83e0c55f8c489cb
7
- data.tar.gz: 22f2c7ab4cc3bae5e0bccda01921f95c22c7ee3b6bd221e0e75950cc79b760e5ccda9aaf1d660c6d5a249f16fbaf159c3c04e76cbc2fd43285d114353ad871b4
6
+ metadata.gz: bc00fe5e63398aeace567d74799dbfb677446a33edd9586c770488133028fcfc328a4285782a72d1ba2f414e6133327a26de4c3d3a069c5d6aac19bf2676ea75
7
+ data.tar.gz: 543aa0bbc534055de801d433dd5446c05cc4e9fbff5d1c8134605c0f6d9414800cc27266924f3ce0d9113c86ff0c792c71dc9f479c57ab2f4d6eb1c3376eec0b
data/CHANGELOG.md CHANGED
@@ -1,10 +1,14 @@
1
1
  OpenStudio Analysis Gem Change Log
2
2
  ==================================
3
3
 
4
- Version 0.3.7 (Unreleased)
4
+ Version 0.4.0
5
5
  -------------
6
- * Worker initilization and finalization scripts
7
- * Do not allow the file to proccess if the Measure Display Names are not unique
6
+ * Add programmatic interface. This is now used when translating the Excel file into the JSON.
7
+
8
+ Version 0.3.7
9
+ -------------
10
+ * Worker initialization and finalization scripts
11
+ * Do not allow the file to process if the Measure Display Names are not unique
8
12
 
9
13
  Version 0.3.6
10
14
  -------------
@@ -96,7 +100,7 @@ Version 0.1.7
96
100
  Version 0.1.6
97
101
  -------------
98
102
  * Small fixes
99
-
103
+
100
104
  Version 0.1.5
101
105
  -------------
102
106
  * Now depends on json_pure for window users
@@ -119,5 +123,3 @@ Version 0.1.1
119
123
  * Convert argument values to the right variable types
120
124
 
121
125
  * Add measure type parsing by reading the inherited class
122
-
123
-
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
- OpenStudio Analysis Gem
2
- =======================
1
+ # OpenStudio Analysis Gem
2
+
3
3
  [![Build Status](https://travis-ci.org/NREL/OpenStudio-analysis-gem.svg?branch=develop)](https://travis-ci.org/NREL/OpenStudio-analysis-gem) [![Dependency Status](https://www.versioneye.com/user/projects/540a2fe5ccc023dd23000002/badge.svg?style=flat)](https://www.versioneye.com/user/projects/540a2fe5ccc023dd23000002)
4
4
 
5
5
  The OpenStudio Analysis Gem is used to communicate files to the OpenStudio Distributed Analysis.
@@ -7,13 +7,61 @@ The OpenStudio Analysis Gem is used to communicate files to the OpenStudio Distr
7
7
  The purpose of this gem is to generate the analysis.json file, analysis.zip, and communicate with the server to upload
8
8
  the simulations.
9
9
 
10
- The gem does not create the cluster. Currently the only supported Cloud platform is
10
+ This gem does not create the cluster. Currently the only supported Cloud platform is
11
11
  Amazon AWS using either [OpenStudio's PAT](https://openstudio.nrel.gov) the [openstudio-aws gem](https://rubygems.org/gems/openstudio-aws) or using [vagrant](http://www.vagrantup.com/).
12
12
 
13
- Instructions
14
- ------------
13
+ ## Instructions
14
+
15
+ There are two ways to create an OpenStudio Analysis description:
16
+ * Use the Excel Translator
17
+
18
+
19
+ * Programmatically
20
+
21
+ ```
22
+ analysis = OpenStudio::Analysis.create
23
+ analysis.seed_model = "local/dir/seed.osm"
24
+ analysis.name = "Analysis Name"
25
+
26
+ # override existing workflow from a file by
27
+ analysis.workflow = OpenStudio::Analysis::Workflow.load_from_file(...)
28
+
29
+ # add measures to the workflow
30
+ wf = analysis.workflow
31
+ wf.add_measure_from_path("path_to_measure")
32
+ wf.add_measure_from_path("path_to_measure_2")
33
+
34
+ # or allow the system to search for the measure based on default_measure_paths
35
+ OpenStudio::Analysis.measure_paths = ['measures', '../project_specific_measures']
36
+ wf.add_measure_by_name('measure_name')
37
+
38
+ # make a measure's argument a variable
39
+ m = wf.add_measure("path_to_measure_3")
40
+ m.make_variable('variable_argument_name', 'discrete')
41
+
42
+ m = wf.add_measure('path_to_measure_4')
43
+ m.make_variable('variable_argument_name', 'pivot')
44
+ m.argument_static_value('variable_argument_name', value)
45
+
46
+ ```
47
+
48
+
49
+ ## Testing
15
50
 
16
- Testing
17
- -------
18
51
 
19
52
  This gem used RSpec for testing. To test simply run `rspec` at the command line.
53
+
54
+ # Todos
55
+
56
+ In the programmatic interface there are still several items that need to be checked
57
+
58
+ * verify that the measure.xml file exists
59
+ * Check the type of measure being added and make sure that it is in the right workflow (e.g. no energyplus measures before rubymeasures)
60
+ * add reverse translator from existing analysis.jsons
61
+ * more explicit run workflows. For example, add workflow steps for running energyplus, openstudio translator, radiance, etc
62
+ * more explicit assignment of the analyses that can run. This would be nice:
63
+ ```
64
+ a = OpenStudio::Analysis.create("new analysis")
65
+ a.analysis_type('single_run')
66
+ ```
67
+
data/Rakefile CHANGED
@@ -23,3 +23,13 @@ task 'spec:unit' => 'ci:setup:rspec'
23
23
  task 'spec:integration' => 'ci:setup:rspec'
24
24
 
25
25
  task default: 'spec:unit'
26
+
27
+ require 'rubocop/rake_task'
28
+ desc 'Run RuboCop on the lib directory'
29
+ RuboCop::RakeTask.new(:rubocop) do |task|
30
+ task.options = ['--no-color', '--out=rubocop-results.xml']
31
+ task.formatters = ['RuboCop::Formatter::CheckstyleFormatter']
32
+ task.requires = ['rubocop/formatter/checkstyle_formatter']
33
+ # don't abort rake on failure
34
+ task.fail_on_error = false
35
+ end
@@ -0,0 +1,22 @@
1
+ # OpenStudio::Analysis::Algorithm to define the algorithm parameters. The module and class names start to conflict
2
+ # with OpenStudio's namespace. Be careful adding new classes without first making sure that the namespace conflict
3
+ # is clear.
4
+ module OpenStudio
5
+ module Analysis
6
+ class AlgorithmAttributes
7
+ # Create a new instance of an algorithm
8
+ #
9
+ def initialize
10
+ @attributes = {}
11
+ end
12
+
13
+ def set_attribute(attribute_name, attribute_value)
14
+ @attributes[attribute_name] = attribute_value
15
+ end
16
+
17
+ def to_hash(_version = 1)
18
+ @attributes
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,174 @@
1
+ # OpenStudio formulation class handles the generation of the OpenStudio Analysis format.
2
+ module OpenStudio
3
+ module Analysis
4
+ SeedModel = Struct.new(:path)
5
+ WeatherFile = Struct.new(:path)
6
+
7
+ class Formulation
8
+ attr_reader :seed_model
9
+ attr_reader :weather_file
10
+ attr_accessor :display_name
11
+ attr_accessor :workflow
12
+ attr_accessor :algorithm
13
+
14
+ attr_reader :analysis_type
15
+
16
+ # Create an instance of the OpenStudio::Analysis::Formulation
17
+ #
18
+ # @param display_name [String] Display name of the project.
19
+ # @return [Object] An OpenStudio::Analysis::Formulation object
20
+ def initialize(display_name)
21
+ @display_name = display_name
22
+ @analysis_type = nil
23
+ @outputs = []
24
+
25
+ # Initialize child objects (expect workflow)
26
+ @weather_file = WeatherFile.new
27
+ @seed_model = SeedModel.new
28
+ @algorithm = OpenStudio::Analysis::AlgorithmAttributes.new
29
+ end
30
+
31
+ # Initialize or return the current workflow object
32
+ #
33
+ # @return [Object] An OpenStudio::Analysis::Workflow object
34
+ def workflow
35
+ @workflow ||= OpenStudio::Analysis::Workflow.new
36
+ end
37
+
38
+ # Define the type of analysis that this is going to be running
39
+ #
40
+ # @param name [String] Name of the algorithm/analysis. (e.g. rgenoud, lhs, single_run)
41
+ attr_writer :analysis_type
42
+
43
+ # Path to the seed model
44
+ #
45
+ # @param path [String] Path to the seed model. This should be relative.
46
+ def seed_model(path)
47
+ @seed_model = SeedModel.new(path: path)
48
+ end
49
+
50
+ # Path to the weather file (or folder). If it is a folder, then the measures will look for the weather file
51
+ # by name in that folder.
52
+ #
53
+ # @param path [String] Path to the weather file or folder.
54
+ def weather_file(path)
55
+ @weather_file = WeatherFile.new(path: path)
56
+ end
57
+
58
+ # Add an output of interest to the problem formulation
59
+ #
60
+ # @param output_hash [Hash] Hash of the output variable in the legacy format
61
+ # @option output_hash [String] :display_name Name to display
62
+ # @option output_hash [String] :display_name_short A shorter display name
63
+ # @option output_hash [String] :metadata_id Link to DEnCity ID in which this output corresponds
64
+ # @option output_hash [String] :name Unique machine name of the variable. Typically this is measure.attribute
65
+ # @option output_hash [String] :export Export the variable to CSV and dataframes from OpenStudio-server
66
+ # @option output_hash [String] :visualize Visualize the variable in the plots on OpenStudio-server
67
+ # @option output_hash [String] :units Units of the variable as a string
68
+ # @option output_hash [String] :variable_type Data type of the variable
69
+ # @option output_hash [Boolean] :objective_function Whether or not this output is an objective function. Default: false
70
+ # @option output_hash [Integer] :objective_function_index Index of the objective function. Default: nil
71
+ # @option output_hash [Float] :objective_function_target Target for the objective function to reach (if defined). Default: nil
72
+ # @option output_hash [Float] :scaling_factor How to scale the objective function(s). Default: nil
73
+ # @option output_hash [Integer] :objective_function_group If grouping objective functions, then group ID. Default: nil
74
+ def add_output(output_hash)
75
+ output_hash = {
76
+ units: '',
77
+ objective_function: false,
78
+ objective_function_index: nil,
79
+ objective_function_target: nil,
80
+ objective_function_group: nil,
81
+ scaling_factor: nil
82
+ }.merge(output_hash)
83
+
84
+ # if the objective_function index is nil and the variable is an objective function, then increment and
85
+ # assign and objective function index
86
+ unless output_hash[:objective_function_index]
87
+ values = @outputs.map { |o| o[:objective_function_index] }
88
+ output_hash[:objective_function_index] = values.empty? ? 0 : values.max + 1
89
+ end
90
+
91
+ @outputs << output_hash
92
+ end
93
+
94
+ # return a hash.
95
+ #
96
+ # @param version [Integer] Version of the format to return
97
+ # @return [Hash]
98
+ def to_hash(version = 1)
99
+ # fail 'Must define an analysis type' unless @analysis_type
100
+ if version == 1
101
+ h = {
102
+ analysis: {
103
+ display_name: @display_name,
104
+ name: @display_name.snake_case,
105
+ output_variables: @outputs,
106
+ problem: {
107
+ analysis_type: @analysis_type,
108
+ algorithm: algorithm.to_hash(version),
109
+ workflow: workflow.to_hash(version)
110
+ },
111
+ seed: @seed_model[:path],
112
+ weather_file: @weather_file[:path],
113
+ file_format_version: version
114
+ }
115
+ }
116
+
117
+ # This is a hack right now, but after the initial hash is created go back and add in the objective functions
118
+ # to the the algorithm as defined in the output_variables list
119
+ ofs = @outputs.map { |i| i[:name] if i[:objective_function] }.compact
120
+ if h[:analysis][:problem][:algorithm]
121
+ h[:analysis][:problem][:algorithm][:objective_functions] = ofs
122
+ end
123
+
124
+ h
125
+ else
126
+ fail "Version #{version} not defined for #{self.class} and #{__method__}"
127
+ end
128
+ end
129
+
130
+ # return a hash of the data point with the static variables set
131
+ #
132
+ # @param version [Integer] Version of the format to return
133
+ # @return [Hash]
134
+ def to_static_data_point_hash(version = 1)
135
+ if version == 1
136
+ static_hash = {}
137
+ # TODO: this method should be on the workflow step and bubbled up to this interface
138
+ @workflow.items.map do |item|
139
+ item.variables.map { |v| static_hash[v[:uuid]] = v[:static_value] }
140
+ end
141
+
142
+ h = {
143
+ data_point: {
144
+ set_variable_values: static_hash,
145
+ status: 'na',
146
+ uuid: SecureRandom.uuid
147
+ }
148
+ }
149
+ h
150
+ end
151
+ end
152
+
153
+ # save the file to JSON. Will overwrite the file if it already exists
154
+ #
155
+ # @param version [Integer] Version of the format to return
156
+ # @return [Boolean]
157
+ def save(filename, version = 1)
158
+ File.open(filename, 'w') { |f| f << JSON.pretty_generate(to_hash(version)) }
159
+
160
+ true
161
+ end
162
+
163
+ # save the data point JSON with the variables set to the static values. Will overwrite the file if it already exists
164
+ #
165
+ # @param version [Integer] Version of the format to return
166
+ # @return [Boolean]
167
+ def save_static_data_point(filename, version = 1)
168
+ File.open(filename, 'w') { |f| f << JSON.pretty_generate(to_static_data_point_hash(version)) }
169
+
170
+ true
171
+ end
172
+ end
173
+ end
174
+ end
@@ -139,12 +139,11 @@ module OpenStudio
139
139
  fail "Measure Display Names are not unique for '#{measure_display_names_mult.join('\', \'')}'"
140
140
  end
141
141
 
142
- # verify that all continuous variables have all the data needed and create a name maps
142
+ # verify that all continuous variables have all the data needed and create a name map
143
143
  variable_names = []
144
144
  @variables['data'].each do |measure|
145
145
  if measure['enabled']
146
146
  measure['variables'].each do |variable|
147
-
148
147
  # Determine if row is suppose to be an argument or a variable to be perturbed.
149
148
  if variable['variable_type'] == 'variable'
150
149
  variable_names << variable['display_name']
@@ -179,7 +178,7 @@ module OpenStudio
179
178
  if variable['distribution']['max'].nil? || variable['distribution']['max'] == ''
180
179
  fail "Variable #{measure['name']}:#{variable['name']} must have a maximum"
181
180
  end
182
- unless variable['type'] == 'string'
181
+ unless variable['type'] == 'string' || variable['type'] =~ /bool/
183
182
  if variable['distribution']['min'] > variable['distribution']['max']
184
183
  fail "Variable min is greater than variable max for #{measure['name']}:#{variable['name']}"
185
184
  end
@@ -205,6 +204,9 @@ module OpenStudio
205
204
  # the correct weather files or models
206
205
  @template_json = translate_to_analysis_json_template
207
206
 
207
+ # save the other format for now
208
+ translate_to_analysis
209
+
208
210
  @template_json
209
211
  end
210
212
 
@@ -223,7 +225,31 @@ module OpenStudio
223
225
  end
224
226
  end
225
227
 
226
- # TODO: move this into a new class that helps construct this file
228
+ # New method that uses the objects to hold the analysis
229
+ def translate_to_analysis
230
+ # Use the programmatic interface to make the analysis json now
231
+ analysis = OpenStudio::Analysis.create(@analysis_name)
232
+
233
+ @variables['data'].each do |measure|
234
+ next unless measure['enabled']
235
+
236
+ # TODO: make this read the measure.rb file, then override any of the differences. That is call workflow.add_from_measure_path
237
+ analysis.workflow.add_measure_from_excel(measure)
238
+ end
239
+
240
+ # Add in the outputs
241
+
242
+ @outputs['output_variables'].each do |o|
243
+ o = Hash[o.map { |k, v| [k.to_sym, v] }]
244
+ analysis.add_output(o)
245
+ end
246
+
247
+ # Temp save of the json file
248
+ analysis.save("spec/files/analysis/#{analysis.display_name}_api.json")
249
+
250
+ analysis
251
+ end
252
+
227
253
  def translate_to_analysis_json_template
228
254
  # Load in the templates for constructing the JSON file
229
255
  template_root = File.join(File.dirname(__FILE__), '../../templates')
@@ -267,21 +293,10 @@ module OpenStudio
267
293
 
268
294
  # add this as an argument
269
295
  case @variable['type'].downcase
270
- when 'double'
271
- @static_value = @variable['distribution']['static_value'].to_f
272
- when 'integer'
273
- @static_value = @variable['distribution']['static_value'].to_i
274
- # TODO: update openstudio export to write only Strings
275
296
  when 'string', 'choice'
276
297
  @static_value = @variable['distribution']['static_value'].inspect
277
- when 'bool'
278
- if @variable['distribution']['static_value'].downcase == 'true'
279
- @static_value = true
280
- else
281
- @static_value = false
282
- end
283
298
  else
284
- fail "Unknown variable type of '#{@variable['type']}'"
299
+ @static_value = @variable['distribution']['static_value']
285
300
  end
286
301
  ag = JSON.parse(argument_template.result(get_binding))
287
302
  fail "Argument '#{@variable['name']}' did not process. Most likely it did not have all parameters defined." if ag.nil?
@@ -290,21 +305,10 @@ module OpenStudio
290
305
  vr = nil
291
306
  # add this as an argument
292
307
  case @variable['type'].downcase
293
- when 'double'
294
- @static_value = @variable['distribution']['static_value'].to_f
295
- when 'integer'
296
- @static_value = @variable['distribution']['static_value'].to_i
297
- # TODO: update openstudio export to write only Strings
298
308
  when 'string', 'choice'
299
309
  @static_value = @variable['distribution']['static_value'].inspect
300
- when 'bool'
301
- if @variable['distribution']['static_value'].downcase == 'true'
302
- @static_value = true
303
- else
304
- @static_value = false
305
- end
306
310
  else
307
- fail "Unknown variable type of '#{@variable['type']}'"
311
+ @static_value = @variable['distribution']['static_value']
308
312
  end
309
313
 
310
314
  # TODO: remove enum and choice as this is not the variable type
@@ -313,24 +317,11 @@ module OpenStudio
313
317
  vr = JSON.parse(discrete_uncertain_variable_template.result(get_binding))
314
318
  elsif @variable['distribution']['type'] == 'discrete_uncertain'
315
319
  # puts @variable.inspect
316
- weights = nil
317
- if @variable['distribution']['discrete_weights'] && @variable['distribution']['discrete_weights'] != ''
318
- weights = eval(@variable['distribution']['discrete_weights'])
319
- end
320
-
321
- values = nil
322
- if variable['type'].downcase == 'bool'
323
- values = eval(@variable['distribution']['discrete_values'])
324
- values.map! { |v| v.to_s == 'true' }
325
- else
326
- values = eval(@variable['distribution']['discrete_values'])
327
- end
328
-
329
- if weights
330
- fail "Discrete variable '#{@variable['name']}' does not have equal length of values and weights" if values.size != weights.size
331
- @values_and_weights = values.zip(weights).map { |v, w| { value: v, weight: w } }.to_json
320
+ if @variable['distribution']['discrete_weights']
321
+ fail "Discrete variable '#{@variable['name']}' does not have equal length of values and weights" if @variable['distribution']['discrete_values'].size != @variable['distribution']['discrete_weights'].size
322
+ @values_and_weights = @variable['distribution']['discrete_values'].zip(@variable['distribution']['discrete_weights']).map { |v, w| { value: v, weight: w } }.to_json
332
323
  else
333
- @values_and_weights = values.map { |v| { value: v } }.to_json
324
+ @values_and_weights = @variable['distribution']['discrete_values'].map { |v| { value: v } }.to_json
334
325
  end
335
326
 
336
327
  if @variable['variable_type'] == 'pivot'
@@ -903,7 +894,7 @@ module OpenStudio
903
894
 
904
895
  # check if we are a measure - nil means that the cell was blank
905
896
  if row[:enabled].nil?
906
- unless measure_name.nil?
897
+ if measure_name && data['data'][measure_index]['enabled']
907
898
  variable_index += 1
908
899
 
909
900
  var = {}
@@ -912,7 +903,7 @@ module OpenStudio
912
903
  var['display_name_short'] = row[:display_name_short] ? row[:display_name_short] : var['display_name']
913
904
  var['name'] = row[:measure_type_or_parameter_name_in_measure]
914
905
  var['index'] = variable_index # order of the variable (not sure of its need)
915
- var['type'] = row[:variable_type] ? row[:variable_type].downcase : row[:variable_type]
906
+ var['type'] = row[:variable_type].downcase
916
907
  var['units'] = row[:units]
917
908
  var['distribution'] = {}
918
909
 
@@ -933,6 +924,32 @@ module OpenStudio
933
924
  var['distribution']['discrete_weights'] = row[:discrete_weights]
934
925
  var['distribution']['type'] = row[:distribution]
935
926
  var['distribution']['static_value'] = row[:default_value]
927
+ var['distribution']['delta_x'] = row[:delta_x]
928
+
929
+ # type various values correctly
930
+ var['distribution']['min'] = typecast_value(var['type'], var['distribution']['min'])
931
+ var['distribution']['max'] = typecast_value(var['type'], var['distribution']['max'])
932
+ var['distribution']['mean'] = typecast_value(var['type'], var['distribution']['mean'])
933
+ var['distribution']['stddev'] = typecast_value(var['type'], var['distribution']['stddev'])
934
+ var['distribution']['static_value'] = typecast_value(var['type'], var['distribution']['static_value'])
935
+
936
+ # eval the discrete value and weight arrays
937
+ case var['type']
938
+ when 'bool', 'boolean'
939
+ if var['distribution']['discrete_values']
940
+ var['distribution']['discrete_values'] = eval(var['distribution']['discrete_values']).map { |v| v.to_s == 'true' }
941
+ end
942
+ if var['distribution']['discrete_weights'] && var['distribution']['discrete_weights'] != ''
943
+ var['distribution']['discrete_weights'] = eval(var['distribution']['discrete_weights'])
944
+ end
945
+ else
946
+ if var['distribution']['discrete_values']
947
+ var['distribution']['discrete_values'] = eval(var['distribution']['discrete_values'])
948
+ end
949
+ if var['distribution']['discrete_weights'] && var['distribution']['discrete_weights'] != ''
950
+ var['distribution']['discrete_weights'] = eval(var['distribution']['discrete_weights'])
951
+ end
952
+ end
936
953
 
937
954
  var['distribution']['source'] = row[:source]
938
955
  var['notes'] = row[:notes]
@@ -1028,7 +1045,7 @@ module OpenStudio
1028
1045
  var['units'] = row[:units]
1029
1046
  var['visualize'] = row[:visualize].downcase == 'true' ? true : false if row[:visualize]
1030
1047
  var['export'] = row[:export].downcase == 'true' ? true : false if row[:export]
1031
- var['variable_type'] = row[:variable_type] if row[:variable_type]
1048
+ var['variable_type'] = row[:variable_type].downcase if row[:variable_type]
1032
1049
  var['objective_function'] = row[:objective_function].downcase == 'true' ? true : false
1033
1050
  if var['objective_function']
1034
1051
  @algorithm['objective_functions'] << var['name']
@@ -1,5 +1,5 @@
1
1
  module OpenStudio
2
2
  module Analysis
3
- VERSION = '0.3.7'
3
+ VERSION = '0.4.0'
4
4
  end
5
5
  end