lib/openstudio/analysis/translator/datapoints.rb in openstudio-analysis-1.0.0.rc9 vs lib/openstudio/analysis/translator/datapoints.rb in openstudio-analysis-1.0.0.rc10
- old
+ new
@@ -33,11 +33,11 @@
@csv = nil
# Try to read the spreadsheet as a roo object
if File.exist?(@csv_filename)
@csv = CSV.read(@csv_filename)
else
- fail "File #{@csv_filename} does not exist"
+ raise "File #{@csv_filename} does not exist"
end
# Remove nil rows and check row length
@csv.delete_if { |row| row.uniq.length == 1 && row.uniq[0].nil? }
@@ -64,22 +64,22 @@
def process
# Seperate CSV into meta and measure groups
measure_tag_index = nil
@csv.each_with_index { |row, index| measure_tag_index = index if row[0] == 'BEGIN-MEASURES' }
- fail "ERROR: No 'BEGIN-MEASURES' tag found in input csv file." unless measure_tag_index
+ raise "ERROR: No 'BEGIN-MEASURES' tag found in input csv file." unless measure_tag_index
meta_rows = []
measure_rows = []
@csv.each_with_index do |_, index|
meta_rows << @csv[index] if index < measure_tag_index
measure_rows << @csv[index] if index > measure_tag_index
end
@setup = parse_csv_meta(meta_rows)
@version = Semantic::Version.new @version
- fail "CSV interface version #{@version} is no longer supported. Please upgrade your csv interface to at least 0.0.1" if @version < '0.0.0'
+ raise "CSV interface version #{@version} is no longer supported. Please upgrade your csv interface to at least 0.0.1" if @version < '0.0.0'
@variables = parse_csv_measures(measure_rows)
# call validate to make sure everything that is needed exists (i.e. directories)
validate_analysis
@@ -101,64 +101,64 @@
end
def validate_analysis
# Setup the paths and do some error checking
@measure_paths.each do |mp|
- fail "Measures directory '#{mp}' does not exist" unless Dir.exist?(mp)
+ raise "Measures directory '#{mp}' does not exist" unless Dir.exist?(mp)
end
@models.uniq!
- fail 'No seed models defined in spreadsheet' if @models.empty?
+ raise 'No seed models defined in spreadsheet' if @models.empty?
@models.each do |model|
- fail "Seed model does not exist: #{model[:path]}" unless File.exist?(model[:path])
+ raise "Seed model does not exist: #{model[:path]}" unless File.exist?(model[:path])
end
@weather_paths.uniq!
- fail 'No weather files found based on what is in the spreadsheet' if @weather_paths.empty?
+ raise 'No weather files found based on what is in the spreadsheet' if @weather_paths.empty?
@weather_paths.each do |wf|
- fail "Weather file does not exist: #{wf}" unless File.exist?(wf)
+ raise "Weather file does not exist: #{wf}" unless File.exist?(wf)
end
# This can be a directory as well
@other_files.each do |f|
- fail "Other files do not exist for: #{f[:path]}" unless File.exist?(f[:path])
+ raise "Other files do not exist for: #{f[:path]}" unless File.exist?(f[:path])
end
@worker_inits.each do |f|
- fail "Worker initialization file does not exist for: #{f[:path]}" unless File.exist?(f[:path])
+ raise "Worker initialization file does not exist for: #{f[:path]}" unless File.exist?(f[:path])
end
@worker_finals.each do |f|
- fail "Worker finalization file does not exist for: #{f[:path]}" unless File.exist?(f[:path])
+ raise "Worker finalization file does not exist for: #{f[:path]}" unless File.exist?(f[:path])
end
FileUtils.mkdir_p(@export_path)
# verify that the measure display names are unique
# puts @variables.inspect
measure_display_names = @variables.map { |m| m[:measure_data][:display_name] }.compact
measure_display_names_mult = measure_display_names.select { |m| measure_display_names.count(m) > 1 }.uniq
if measure_display_names_mult && !measure_display_names_mult.empty?
- fail "Measure Display Names are not unique for '#{measure_display_names_mult.join('\', \'')}'"
+ raise "Measure Display Names are not unique for '#{measure_display_names_mult.join('\', \'')}'"
end
variable_names = @variables.map { |v| v[:vars].map { |hash| hash[:display_name] } }.flatten
dupes = variable_names.select { |e| variable_names.count(e) > 1 }.uniq
if dupes.count > 0
- fail "duplicate variable names found in list #{dupes.inspect}"
+ raise "duplicate variable names found in list #{dupes.inspect}"
end
end
# convert the data in excel's parsed data into an OpenStudio Analysis Object
# @seed_model [Hash] Seed model to set the new analysis to
# @append_model_name [Boolean] Append the name of the seed model to the display name
# @return [Object] An OpenStudio::Analysis
def analysis(seed_model = nil, append_model_name = false)
- fail 'There are no seed models defined in the excel file. Please add one.' if @models.size == 0
- fail 'There are more than one seed models defined in the excel file. This is not supported by the CSV Translator.' if @models.size > 1 && seed_model.nil?
+ raise 'There are no seed models defined in the excel file. Please add one.' if @models.size == 0
+ raise 'There are more than one seed models defined in the excel file. This is not supported by the CSV Translator.' if @models.size > 1 && seed_model.nil?
seed_model = @models.first if seed_model.nil?
# Use the programmatic interface to make the analysis
# append the model name to the analysis name if requested (normally if there are more than 1 models in the spreadsheet)
@@ -172,16 +172,16 @@
if Dir.exist? measure_dir_to_add
if File.exist? "#{measure_dir_to_add}/measure.rb"
measure[:measure_data][:local_path_to_measure] = "#{measure_dir_to_add}/measure.rb"
break
else
- fail "Measure in directory '#{measure_dir_to_add}' did not contain a measure.rb file"
+ raise "Measure in directory '#{measure_dir_to_add}' did not contain a measure.rb file"
end
end
end
- fail "Could not find measure '#{measure['name']}' in directory named '#{measure['measure_file_name_directory']}' in the measure paths '#{@measure_paths.join(', ')}'" unless measure[:measure_data][:local_path_to_measure]
+ raise "Could not find measure '#{measure['name']}' in directory named '#{measure['measure_file_name_directory']}' in the measure paths '#{@measure_paths.join(', ')}'" unless measure[:measure_data][:local_path_to_measure]
a.workflow.add_measure_from_csv(measure)
end
@other_files.each do |library|
@@ -224,41 +224,41 @@
meta_rows.each do |row|
config_hash[row[0].to_sym] = row[1]
end
# Assign required attributes
- fail 'Require setting not found: version' unless config_hash[:version]
+ raise 'Require setting not found: version' unless config_hash[:version]
@version = config_hash[:version]
if config_hash[:analysis_name]
@name = config_hash[:analysis_name]
else
@name = SecureRandom.uuid
end
@analysis_name = @name.to_underscore
- fail 'Require setting not found: measure_path' unless config_hash[:measure_paths]
+ raise 'Require setting not found: measure_path' unless config_hash[:measure_paths]
config_hash[:measure_paths] = [config_hash[:measure_paths]] unless config_hash[:measure_paths].respond_to?(:each)
config_hash[:measure_paths].each do |path|
if (Pathname.new path).absolute?
@measure_paths << path
else
@measure_paths << File.expand_path(File.join(@root_path, path))
end
end
- fail 'Required setting not found: weather_paths' unless config_hash[:weather_paths]
+ raise 'Required setting not found: weather_paths' unless config_hash[:weather_paths]
config_hash[:weather_paths] = config_hash[:weather_paths].split(',')
config_hash[:weather_paths].each do |path|
if (Pathname.new path).absolute?
@weather_paths << path
else
@weather_paths << File.expand_path(File.join(@root_path, path))
end
end
- fail 'Required setting not found: models' unless config_hash[:models]
+ raise 'Required setting not found: models' unless config_hash[:models]
config_hash[:models] = [config_hash[:models]] unless config_hash[:models].respond_to?(:each)
config_hash[:models].each do |path|
model_name = File.basename(path).split('.')[0]
model_name = SecureRandom.uuid if model_name == ''
type = File.basename(path).split('.')[1].upcase
@@ -272,11 +272,11 @@
if config_hash[:output_json]
path = File.expand_path(File.join(@root_path, config_hash[:output_json].to_s))
if File.exist? path
@outputs = MultiJson.load(File.read(path))
else
- fail "Could not find output json: #{config_hash[:output_json]}"
+ raise "Could not find output json: #{config_hash[:output_json]}"
end
end
if config_hash[:export_path]
if (Pathname.new config_hash[:export_path]).absolute?
@@ -293,14 +293,14 @@
end
@other_files << { lib_zip_name: library_name, path: config_hash[:library_path] }
end
if config_hash[:allow_multiple_jobs]
- fail "allow_multiple_jobs is no longer a valid option in the CSV, please delete and rerun"
+ raise 'allow_multiple_jobs is no longer a valid option in the CSV, please delete and rerun'
end
if config_hash[:use_server_as_worker]
- fail "use_server_as_worker is no longer a valid option in the CSV, please delete and rerun"
+ raise 'use_server_as_worker is no longer a valid option in the CSV, please delete and rerun'
end
# Assign AWS settings
@settings[:proxy_port] = config_hash[:proxy_port] if config_hash[:proxy_port]
@settings[:cluster_name] = config_hash[:cluster_name] if config_hash[:cluster_name]
@@ -321,65 +321,71 @@
measures.each do |measure|
measure_map[measure] = {}
col_ind = (0..(measure_rows[0].length - 1)).to_a.select { |i| measure_rows[0][i] == measure.to_s }
col_ind.each do |var_ind|
tuple = measure.to_s + measure_rows[1][var_ind]
- fail "Multiple measure_variable tuples found for '#{measure}_#{measure_rows[1][var_ind]}'. These tuples must be unique." if measure_var_list.include? tuple
+ raise "Multiple measure_variable tuples found for '#{measure}_#{measure_rows[1][var_ind]}'. These tuples must be unique." if measure_var_list.include? tuple
measure_var_list << tuple
measure_map[measure][measure_rows[1][var_ind].to_sym] = var_ind
end
end
# For each measure load measure json and parse out critical variable requirements
data = []
measures.each_with_index do |measure, measure_index|
data[measure_index] = {}
- measure_xml = ''
- for i in 0..(@measure_paths.length - 1)
- if File.exist? File.join(@measure_paths[i], measure.to_s, 'measure.xml')
- measure_xml = Nokogiri::XML File.read(File.join(@measure_paths[i], measure.to_s, 'measure.xml'))
- break
- end
- end
- fail "Could not find measure #{measure} xml in measure_paths: '#{@measure_paths.join("\n")}'" if measure_xml == ''
+ measure_xml, measure_type = find_measure(measure.to_s)
+
+ raise "Could not find measure #{measure} xml in measure_paths: '#{@measure_paths.join("\n")}'" unless measure_xml
measure_data = {}
measure_data[:classname] = measure_xml.xpath('/measure/class_name').text
measure_data[:name] = measure_xml.xpath('/measure/name').text
measure_data[:display_name] = measure_xml.xpath('/measure/display_name').text
- measure_data[:measure_type] = parse_measure_type(File.join(@measure_paths[i], measure.to_s, 'measure.rb'))
+ measure_data[:measure_type] = measure_type
measure_data[:uid] = measure_xml.xpath('/measure/uid').text
measure_data[:version_id] = measure_xml.xpath('/measure/version_id').text
data[measure_index][:measure_data] = measure_data
data[measure_index][:vars] = []
vars = measure_map[measure]
# construct the list of variables
vars.each do |var|
+ # var looks like [:cooling_adjustment, 0]
var = var[0]
- next if var.to_s == "None"
+ next if var.to_s == 'None'
var_hash = {}
found_arg = nil
measure_xml.xpath('/measure/arguments/argument').each do |arg|
- if arg.xpath('name').text == var.to_s
+ if var.to_s == '__SKIP__' || arg.xpath('name').text == var.to_s
found_arg = arg
break
end
end
# var_json = measure_json['arguments'].select { |hash| hash['local_variable'] == var.to_s }[0]
- fail "measure.xml for measure #{measure} does not have an argument with argument == #{var}" unless found_arg
+ raise "measure.xml for measure #{measure} does not have an argument with argument == #{var}" unless found_arg
+ var_type = nil
+ var_units = ''
+ if var.to_s == '__SKIP__'
+ var_type = 'boolean'
+ var_units = ''
+ else
+ var_type = found_arg.xpath('type').text.downcase
+ var_units = found_arg.xpath('units')
+ end
+
var_hash[:name] = var.to_s
var_hash[:variable_type] = 'variable'
var_hash[:display_name] = measure_rows[2][measure_map[measure][var]]
var_hash[:display_name_short] = var_hash[:display_name]
# var_hash[:name] = var_json['local_variable']
- var_hash[:type] = found_arg.xpath('type').text.downcase
- var_hash[:units] = found_arg.xpath('units')
+ var_hash[:type] = var_type
+ var_hash[:units] = var_units
var_hash[:distribution] = {}
case var_hash[:type].downcase
- when 'bool', 'boolean' # is 'boolean' necessary? it's not in the enum catch
- var_hash[:distribution][:values] = (3..(measure_rows.length - 1)).map { |value| measure_rows[value.to_i][measure_map[measure][var]].to_s == 'true' }
+ when 'bool', 'boolean'
+ var_hash[:distribution][:values] = (3..(measure_rows.length - 1)).map { |value| measure_rows[value.to_i][measure_map[measure][var]].to_s.downcase == 'true' }
var_hash[:distribution][:maximum] = true
var_hash[:distribution][:minimum] = false
var_hash[:distribution][:mode] = var_hash[:distribution][:values].group_by { |i| i }.max { |x, y| x[1].length <=> y[1].length }[0]
when 'choice', 'string'
var_hash[:distribution][:values] = (3..(measure_rows.length) - 1).map { |value| measure_rows[value.to_i][measure_map[measure][var]].to_s }
@@ -421,10 +427,23 @@
data
end
private
+ # Find the measure in the measure path
+ def find_measure(measure_name)
+ @measure_paths.each do |mp|
+ measure_xml = File.join(mp, measure_name, 'measure.xml')
+ measure_rb = File.join(mp, measure_name, 'measure.rb')
+ if File.exist?(measure_xml) && File.exist?(measure_rb)
+ return Nokogiri::XML File.read(measure_xml), parse_measure_type(measure_rb)
+ end
+ end
+
+ return nil, nil
+ end
+
def parse_measure_type(measure_filename)
measure_string = File.read(measure_filename)
if measure_string =~ /OpenStudio::Ruleset::WorkspaceUserScript/
return 'EnergyPlusMeasure'
@@ -433,10 +452,10 @@
elsif measure_string =~ /OpenStudio::Ruleset::ReportingUserScript/
return 'ReportingMeasure'
elsif measure_string =~ /OpenStudio::Ruleset::UtilityUserScript/
return 'UtilityUserScript'
else
- fail "measure type is unknown with an inherited class in #{measure_filename}"
+ raise "measure type is unknown with an inherited class in #{measure_filename}"
end
end
end
end
end