lib/openstudio/analysis/translator/excel.rb in openstudio-analysis-0.1.3 vs lib/openstudio/analysis/translator/excel.rb in openstudio-analysis-0.1.4
- old
+ new
@@ -3,15 +3,21 @@
module Translator
class Excel
attr_reader :variables
attr_reader :models
attr_reader :weather_files
-
+ attr_reader :measure_path
+ attr_reader :export_path
+ attr_reader :variables
+
# remove these once we have classes to construct the JSON file
attr_reader :name
attr_reader :number_of_samples
+ attr_reader :template_json
+ # methods to override instance variables
+
# pass in the filename to read
def initialize(xls_filename)
@root_path = File.expand_path(File.dirname(xls_filename))
@xls = nil
@@ -27,11 +33,14 @@
@models = []
@other_files = []
@export_path = "./export"
@measure_path = "./measures"
@number_of_samples = 0
-
+ @template_json = nil
+ end
+
+ def process
@setup = parse_setup()
@variables = parse_variables()
# call validate to make sure everything that is needed exists (i.e. directories)
validate_analysis()
@@ -41,11 +50,10 @@
def save_variable_json(filename)
FileUtils.rm_f(filename) if File.exists?(filename)
File.open(filename, 'w') { |f| f << JSON.pretty_generate(@variables) }
end
-
def validate_analysis
# Setup the paths and do some error checking
raise "Measures directory '#{@measure_path}' does not exist" unless Dir.exists?(@measure_path)
@models.uniq!
@@ -66,32 +74,75 @@
@other_files.each do |of|
raise "Other files do not exist for: #{of[:path]}" unless File.exists?(of[:path])
end
FileUtils.mkdir_p(@export_path)
+
+ # verify that all continuous variables have all the data needed and create a name maps
+ variable_names = []
+ @variables['data'].each do |measure|
+ if measure['enabled'] && measure['name'] != 'baseline'
+ measure['variables'].each do |variable|
+ # Determine if row is suppose to be an argument or a variable to be perturbed.
+ if variable['variable_type'] == 'variable'
+ variable_names << variable['display_name']
+ if variable['method'] == 'static'
+ # add this as an argument
+ # check something
+ elsif variable['method'] == 'lhs'
+ if variable['type'] == 'enum'
+ # check something
+ else # must be an integer or double
+ if variable['distribution']['min'].nil? || variable['distribution']['min'] == ""
+ raise "Variable #{measure['name']}:#{variable['name']} must have a minimum"
+ end
+ if variable['distribution']['max'].nil? || variable['distribution']['max'] == ""
+ raise "Variable #{measure['name']}:#{variable['name']} must have a maximum"
+ end
+ if variable['distribution']['mean'].nil? || variable['distribution']['mean'] == ""
+ raise "Variable #{measure['name']}:#{variable['name']} must have a mean"
+ end
+ if variable['distribution']['stddev'].nil? || variable['distribution']['stddev'] == ""
+ raise "Variable #{measure['name']}:#{variable['name']} must have a stddev"
+ end
+ if variable['distribution']['min'] > variable['distribution']['max']
+ raise "Variable min is greater than variable max for #{measure['name']}:#{variable['name']}"
+ end
+ end
+ elsif variable['method'] == 'pivot'
+ # check something
+ end
+ end
+ end
+ end
+ end
+
+ dupes = variable_names.find_all { |e| variable_names.count(e) > 1 }.uniq
+ if dupes.count > 0
+ raise "duplicate variable names found in list #{dupes.inspect}"
+ end
+
+ # most of the checks will raise a runtime exception, so this true will never be called
+ true
end
def save_analysis
- # save the format in the OpenStudio analysis json format
- new_json = translate_to_analysis_json()
+ # save the format in the OpenStudio analysis json format template without
+ # the correct weather files or models
+ @template_json = translate_to_analysis_json_template()
+
+ #validate_template_json
# iterate over each model and save the zip and json
@models.each do |model|
save_analysis_zip(model)
- save_analysis_json(new_json, model)
+ analysis_json = create_analysis_json(@template_json, model)
end
end
- protected
-
- # helper method for ERB
- def get_binding
- binding
- end
-
# TODO: move this into a new class that helps construct this file
- def translate_to_analysis_json
+ def translate_to_analysis_json_template
# Load in the templates for constructing the JSON file
template_root = File.join(File.dirname(__FILE__), "../../templates")
analysis_template = ERB.new(File.open("#{template_root}/analysis.json.erb", 'r').read)
workflow_template = ERB.new(File.open("#{template_root}/workflow_item.json.erb", 'r').read)
uncertain_variable_template = ERB.new(File.open("#{template_root}/uncertain_variable.json.erb", 'r').read)
@@ -146,12 +197,13 @@
else
raise "Unknown variable type of #{@variable['type']}"
end
ag = JSON.parse(argument_template.result(get_binding))
end
+ raise "Argument '#{@variable['name']}' did not process. Most likely it did not have all parameters defined." if ag.nil?
wf['arguments'] << ag
- else # must be a vriable
+ else # must be a variable
vr = nil
if @variable['method'] == 'static'
# add this as an argument
vr = JSON.parse(static_variable_template.result(get_binding))
elsif @variable['method'] == 'lhs'
@@ -163,10 +215,11 @@
end
elsif @variable['method'] == 'pivot'
@values_and_weights = @variable['distribution']['enumerations'].map { |v| {value: v} }.to_json
vr =JSON.parse(pivot_variable_template.result(get_binding))
end
+ raise "variable was nil after processing" if vr.nil?
wf['variables'] << vr
end
end
openstudio_analysis_json['analysis']['problem']['workflow'] << wf
@@ -174,10 +227,18 @@
end
openstudio_analysis_json
end
+ protected
+
+ # helper method for ERB
+ def get_binding
+ binding
+ end
+
+
# Package up the seed, weather files, and measures
def save_analysis_zip(model)
zipfile_name = "#{@export_path}/#{model[:name]}.zip"
FileUtils.rm_f(zipfile_name) if File.exists?(zipfile_name)
@@ -204,11 +265,11 @@
end
end
end
end
- def save_analysis_json(analysis_json, model)
+ def create_analysis_json(analysis_json, model)
# Set the seed model in the analysis_json
analysis_json['analysis']['seed']['file_type'] = model[:type]
# This is the path that will be seen on the server when this runs
analysis_json['analysis']['seed']['path'] = "./seed/#{File.basename(model[:path])}"
@@ -225,12 +286,11 @@
json_file_name = "#{@export_path}/#{model[:name]}.json"
FileUtils.rm_f(json_file_name) if File.exists?(json_file_name)
File.open("#{@export_path}/#{model[:name]}.json", "w") { |f| f << JSON.pretty_generate(analysis_json) }
end
-
-
+
# parse_setup will pull out the data on the "setup" tab and store it in memory for later use
def parse_setup()
rows = @xls.sheet('Setup').parse()
b_run_setup = false
b_problem_setup = false
@@ -300,9 +360,14 @@
# parse_variables will parse the XLS spreadsheet and save the data into
# a higher level JSON file. The JSON file is historic and it should really
# be omitted as an intermediate step
def parse_variables()
rows = @xls.sheet('Variables').parse()
+
+ if !rows
+ raise "Could not find the sheet name 'Variables' in excel file #{@root_path}"
+ end
+
data = {}
data['data'] = []
icnt = 0
measure_index = -1