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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -6
- data/README.md +55 -7
- data/Rakefile +10 -0
- data/lib/openstudio/analysis/algorithm_attributes.rb +22 -0
- data/lib/openstudio/analysis/formulation.rb +174 -0
- data/lib/openstudio/analysis/translator/excel.rb +65 -48
- data/lib/openstudio/analysis/version.rb +1 -1
- data/lib/openstudio/analysis/workflow.rb +197 -0
- data/lib/openstudio/analysis/workflow_step.rb +312 -0
- data/lib/openstudio/analysis.rb +8 -0
- data/lib/openstudio/helpers/string.rb +22 -22
- data/lib/openstudio/templates/analysis.json.erb +0 -1
- data/lib/openstudio-analysis.rb +9 -0
- data/spec/files/0_1_09_small_list_incomplete.xlsx +0 -0
- data/spec/files/0_2_0_template_simpletest.xlsx +0 -0
- data/spec/files/0_4_0_lhs_discrete_continuous.xlsx +0 -0
- data/spec/files/analysis/example_analysis_api.json +656 -0
- data/spec/files/analysis/examples/discrete_lhs_example.json +809 -0
- data/spec/files/analysis/examples/medium_office_example.json +1673 -0
- data/spec/files/analysis/lhs_discrete_and_continuous_variables_api.json +1230 -0
- data/spec/files/analysis/medium_office.json +91 -92
- data/spec/files/analysis/medium_office.zip +0 -0
- data/spec/files/analysis/name_goes_here_api.json +1681 -0
- data/spec/files/analysis/output_vars_api.json +632 -0
- data/spec/files/analysis/preflight_api.json +1518 -0
- data/spec/files/analysis/simple_test_api.json +519 -0
- data/spec/files/analysis/test_model_api.json +493 -0
- data/spec/files/export/analysis/0_1_09_outputvars.json +38 -39
- data/spec/files/export/analysis/0_1_09_outputvars.zip +0 -0
- data/spec/files/export/analysis/0_1_11_discrete_variables.json +46 -47
- data/spec/files/export/analysis/0_1_11_discrete_variables.zip +0 -0
- data/spec/files/export/analysis/0_1_12_discrete_dynamic_columns.json +8 -9
- data/spec/files/export/analysis/0_1_12_discrete_dynamic_columns.zip +0 -0
- data/spec/files/export/analysis/0_2_0_template_simpletest.json +19 -14
- data/spec/files/export/analysis/0_2_0_template_simpletest.zip +0 -0
- data/spec/files/export/analysis/0_3_0_outputs.json +99 -100
- data/spec/files/export/analysis/0_3_0_outputs.zip +0 -0
- data/spec/files/export/analysis/{6d6a08db-fdf8-4bb5-8ad3-18c471418c72.json → 276ccf51-ed22-4604-a380-8985cec5efe8.json} +103 -104
- data/spec/files/export/analysis/{6d6a08db-fdf8-4bb5-8ad3-18c471418c72.zip → 276ccf51-ed22-4604-a380-8985cec5efe8.zip} +0 -0
- data/spec/files/export/analysis/{55086845-70cf-487f-87f6-7a147cbf1e72.json → 639cb8a5-cdbb-4b69-955a-cbb650f6872b.json} +107 -108
- data/spec/files/export/analysis/{55086845-70cf-487f-87f6-7a147cbf1e72.zip → 639cb8a5-cdbb-4b69-955a-cbb650f6872b.zip} +0 -0
- data/spec/files/export/analysis/{10c791ce-cba7-4506-a863-3fb15703889b.json → 9560f95b-5730-4038-a95b-328c825c596b.json} +99 -100
- data/spec/files/export/analysis/{10c791ce-cba7-4506-a863-3fb15703889b.zip → 9560f95b-5730-4038-a95b-328c825c596b.zip} +0 -0
- data/spec/files/export/analysis/{f028bfbe-e30e-488d-adad-a60a62bbf7e0.json → c50f0062-cdfb-4dec-bc02-215f6c29af3c.json} +107 -108
- data/spec/files/export/analysis/{f028bfbe-e30e-488d-adad-a60a62bbf7e0.zip → c50f0062-cdfb-4dec-bc02-215f6c29af3c.zip} +0 -0
- data/spec/files/export/analysis/discrete_lhs_example.json +1185 -0
- data/spec/files/export/analysis/discrete_lhs_example.zip +0 -0
- data/spec/files/export/analysis/small_seed.json +38 -39
- data/spec/files/export/analysis/small_seed.zip +0 -0
- data/spec/files/export/workflow/analysis.json +23 -0
- data/spec/files/measures/ActualMeasureNoJson/measure.json +25 -0
- data/spec/files/measures/ActualMeasureNoJson/measure.rb +80 -0
- data/spec/files/measures/ActualMeasureNoJson/measure.xml +2 -0
- data/spec/files/measures/SetThermostatSchedules/measure.json +63 -0
- data/spec/files/measures/SetThermostatSchedules/measure.rb +254 -0
- data/spec/files/measures/SetThermostatSchedules/measure.xml +2 -0
- data/spec/openstudio/excel_spec.rb +11 -11
- data/spec/openstudio/formulation_spec.rb +107 -0
- data/spec/openstudio/workflow_spec.rb +90 -0
- data/spec/openstudio/workflow_step_spec.rb +116 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-Formulation.xml +28 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi-create-a-new-object-instance.xml +2 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi-test-not-localhost.xml +2 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-ServerApi.xml +1 -1
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-discrete-variables.xml +30 -4
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-discrete-with-dynamic-columns.xml +11 -3
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-no-variables-defined.xml +6 -6
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-proxy-setup-with-user.xml +2 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-proxy-setup.xml +2 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-setup-output-variables.xml +52 -8
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-setup-version-0-1-9.xml +22 -5
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-incomplete-variables.xml +2 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-variables-should-not-validate.xml +2 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-of-variables.xml +28 -5
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-small-list-with-with-repeated-variable-names.xml +2 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-1-10.xml +3 -3
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-2-0-simple.xml +13 -6
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-2-0.xml +55 -5
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-0-dynamic-uuid-assignments.xml +9 -4
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-0-measure-existence-checks.xml +8 -3
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-0-objective-functions.xml +13 -5
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-3-and-short-display-names.xml +9 -4
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-5-and-measure-paths.xml +9 -4
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-7-and-worker-init-final-scripts.0.xml +40 -2
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel-version-0-3-7-and-worker-init-final-scripts.xml +9 -4
- data/spec/reports/SPEC-OpenStudio-Analysis-Translator-Excel.xml +1 -1
- data/spec/reports/SPEC-OpenStudio-Analysis-Workflow.xml +31 -0
- data/spec/reports/SPEC-OpenStudio-Analysis-WorkflowStep.xml +29 -0
- data/spec/spec_helper.rb +1 -1
- metadata +87 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8716110e6823303d2e72cbcf6b2ddb1a4284776c
|
|
4
|
+
data.tar.gz: 7a7a80b05caa4e9c9ab2172b1b65965ce8f3cd77
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
4
|
+
Version 0.4.0
|
|
5
5
|
-------------
|
|
6
|
-
*
|
|
7
|
-
|
|
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
|
[](https://travis-ci.org/NREL/OpenStudio-analysis-gem) [](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
|
-
|
|
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
|
|
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
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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 =
|
|
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
|
-
|
|
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]
|
|
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']
|