lib/openstudio/analysis/workflow.rb in openstudio-analysis-0.4.2 vs lib/openstudio/analysis/workflow.rb in openstudio-analysis-0.4.3

- old
+ new

@@ -19,58 +19,72 @@ end # Add a measure to the workflow from a path. Inside the path it is expecting to have a measure.json file # if not, the BCL gem is used to create the measure.json file. # - # @params instance_name [String] The name of the instance. This allows for multiple measures to be added to the worklow with unique names - # @params instance_display_name [String] The display name of the instance. This allows for multiple measures to be added to the worklow with unique names - # @param path_to_measure [String] This is the local path to the measure directory, relative or absolute. It is used when zipping up all the measures. + # @params instance_name [String] The name of the instance. This allows for multiple measures to be added to the workflow with uni que names + # @params instance_display_name [String] The display name of the instance. This allows for multiple measures to be added to the workflow with unique names + # @param local_path_to_measure [String] This is the local path to the measure directory, relative or absolute. It is used when zipping up all the measures. # @return [Object] Returns the measure that was added as an OpenStudio::AnalysisWorkflowStep object - def add_measure_from_path(instance_name, instance_display_name, path_to_measure) + def add_measure_from_path(instance_name, instance_display_name, local_path_to_measure) measure_filename = 'measure.rb' - if File.exist?(path_to_measure) && File.file?(path_to_measure) - measure_filename = File.basename(path_to_measure) - path_to_measure = File.dirname(path_to_measure) + + if File.exist?(local_path_to_measure) && File.file?(local_path_to_measure) + measure_filename = File.basename(local_path_to_measure) + local_path_to_measure = File.dirname(local_path_to_measure) end - if Dir.exist?(path_to_measure) && File.directory?(path_to_measure) + if Dir.exist?(local_path_to_measure) && File.directory?(local_path_to_measure) # Watch out for namespace conflicts (use ::BCL) b = ::BCL::ComponentMethods.new measure_hash = nil - unless File.exist?(File.join(path_to_measure, 'measure.json')) - measure_hash = b.parse_measure_file(nil, File.join(path_to_measure, measure_filename)) - File.open(File.join(path_to_measure, 'measure.json'), 'w') { |f| f << JSON.pretty_generate(measure_hash) } - warn("measure.json not found in #{path_to_measure}, will parse measure file using BCL gem") + unless File.exist?(File.join(local_path_to_measure, 'measure.json')) + measure_hash = b.parse_measure_file(nil, File.join(local_path_to_measure, measure_filename)) + File.open(File.join(local_path_to_measure, 'measure.json'), 'w') { |f| f << JSON.pretty_generate(measure_hash) } + warn("measure.json not found in #{local_path_to_measure}, will parse measure file using BCL gem") end - if measure_hash.nil? && File.exist?(File.join(path_to_measure, 'measure.json')) - measure_hash = JSON.parse(File.read(File.join(path_to_measure, 'measure.json')), symbolize_names: true) + if measure_hash.nil? && File.exist?(File.join(local_path_to_measure, 'measure.json')) + measure_hash = JSON.parse(File.read(File.join(local_path_to_measure, 'measure.json')), symbolize_names: true) elsif measure_hash.nil? fail 'measure.json was not found and was not automatically created' end - add_measure(instance_name, instance_display_name, path_to_measure, measure_hash) + add_measure(instance_name, instance_display_name, local_path_to_measure, measure_hash) else - fail "could not find measure to add to workflow #{path_to_measure}" + fail "could not find measure to add to workflow #{local_path_to_measure}" end @items.last end # Add a measure from the custom hash format without reading the measure.rb or measure.json file # - # @params instance_name [String] The name of the instance. This allows for multiple measures to be added to the worklow with unique names - # @params instance_display_name [String] The display name of the instance. This allows for multiple measures to be added to the worklow with unique names - # @param path_to_measure [String] This is the local path to the measure directory, relative or absolute. It is used when zipping up all the measures. + # @params instance_name [String] The name of the instance. This allows for multiple measures to be added to the workflow with unique names + # @params instance_display_name [String] The display name of the instance. This allows for multiple measures to be added to the workflow with unique names + # @param local_path_to_measure [String] This is the local path to the measure directory, relative or absolute. It is used when zipping up all the measures. # @param measure_metadata [Hash] Format of the measure.json # @return [Object] Returns the measure that was added as an OpenStudio::AnalysisWorkflowStep object - def add_measure(instance_name, instance_display_name, path_to_measure, measure_metadata) - @items << OpenStudio::Analysis::WorkflowStep.from_measure_hash(instance_name, instance_display_name, path_to_measure, measure_metadata) + def add_measure(instance_name, instance_display_name, local_path_to_measure, measure_metadata) + @items << OpenStudio::Analysis::WorkflowStep.from_measure_hash(instance_name, instance_display_name, local_path_to_measure, measure_metadata) @items.last end + # Add a measure from the analysis hash format + # + # @params instance_name [String] The name of the instance. This allows for multiple measures to be added to the workflow with unique names + # @params instance_display_name [String] The display name of the instance. This allows for multiple measures to be added to the workflow with unique names + # @param local_path_to_measure [String] This is the local path to the measure directory, relative or absolute. It is used when zipping up all the measures. + # @param measure_metadata [Hash] Format of the measure.json + # @return [Object] Returns the measure that was added as an OpenStudio::AnalysisWorkflowStep object + def add_measure_from_analysis_hash(instance_name, instance_display_name, local_path_to_measure, measure_metadata) + @items << OpenStudio::Analysis::WorkflowStep.from_analysis_hash(instance_name, instance_display_name, local_path_to_measure, measure_metadata) + + @items.last + end + # Add a measure from the format that Excel parses into. This is a helper method to map the excel data to the new # programmatic interface format # # @params measure [Hash] The measure in the format of the Excel translator # @return [Object] Returns the measure that was added as an OpenStudio::AnalysisWorkflowStep object @@ -81,12 +95,14 @@ hash[:display_name] = measure['display_name'] hash[:measure_type] = measure['measure_type'] hash[:uid] = measure['uid'] ? measure['uid'] : SecureRandom.uuid hash[:version_id] = measure['version_id'] ? measure['version_id'] : SecureRandom.uuid - # map the arguments - this can be a variable or argument, add them all as arguments first + # map the arguments - this can be a variable or argument, add them all as arguments first, + # the make_variable will remove from arg and place into variables args = [] + measure['variables'].each do |variable| args << { local_variable: variable['name'], variable_type: variable['type'], name: variable['name'], @@ -97,14 +113,14 @@ value: variable['distribution']['static_value'] } end hash[:arguments] = args - m = add_measure(measure['name'], measure['display_name'], measure['measure_file_name_directory'], hash) + m = add_measure(measure['name'], measure['display_name'], measure['local_path_to_measure'], hash) measure['variables'].each do |variable| - next unless variable['variable_type'] == 'variable' + next unless %w(variable pivot).include? variable['variable_type'] dist = { type: variable['distribution']['type'], minimum: variable['distribution']['min'], maximum: variable['distribution']['max'], @@ -118,11 +134,11 @@ variable_type: variable['variable_type'], variable_display_name_short: variable['display_name_short'], static_value: variable['distribution']['static_value'] } - m.make_variable(variable['name'], variable['display_name'], dist) + m.make_variable(variable['name'], variable['display_name'], dist, opt) end end # Iterate over all the WorkflowItems def each @@ -173,28 +189,58 @@ else fail "Version #{version} not yet implemented for to_json" end end + # Load from a from a hash + # + # @param h [Hash or String] Path to file or hash + def self.load(h) + # get the version of the file + file_format_version = h[:file_format_version] ? h[:file_format_version] : 1 + puts "Parsing file version #{file_format_version}" + + o = OpenStudio::Analysis::Workflow.new + + h[:workflow].each do |wf| + puts "Adding measure #{wf[:name]}" + + # Go though the defined measure paths and try and find the local measure + local_measure_dir = nil + if wf[:measure_definition_directory_local] && Dir.exist?(wf[:measure_definition_directory_local]) + local_measure_dir = wf[:measure_definition_directory_local] + else + # search in the measure paths for the measure + OpenStudio::Analysis.measure_paths.each do |p| + test_dir = File.join(p, File.basename(wf[:measure_definition_directory])) + if Dir.exist?(test_dir) + local_measure_dir = test_dir + break + end + end + end + + fail "Could not find local measure when loading workflow for #{wf[:measure_definition_class_name]} in #{File.basename(wf[:measure_definition_directory])}. You may have to add measure paths to OpenStudio::Analysis.measure_paths" unless local_measure_dir + + o.add_measure_from_analysis_hash(wf[:name], wf[:display_name], local_measure_dir, wf) + end + + o + end + # Read the Workflow description from a persisted file. The format at the moment is the current analysis.json # # @params filename [String] Path to file with the analysis.json to load # @return [Object] Return an instance of the workflow object def self.from_file(filename) + o = nil if File.exist? filename j = JSON.parse(File.read(filename), symbolize_names: true) - - # get the version of the file - file_format_version = j[:file_format_version] ? j[:file_format_version] : 1 - - puts "Parsing file version #{file_format_version}" - + o = OpenStudio::Analysis::Workflow.load(j) else fail "Could not find workflow file #{filename}" end - o = OpenStudio::Analysis::Workflow.new - # put the JSON into the right format o end end end end