Merge branch 'master' into 1977-provenance-report
authorTom Clegg <tom@curoverse.com>
Mon, 3 Feb 2014 22:44:19 +0000 (14:44 -0800)
committerTom Clegg <tom@curoverse.com>
Mon, 3 Feb 2014 22:44:19 +0000 (14:44 -0800)
Conflicts:
apps/workbench/app/controllers/pipeline_instances_controller.rb
apps/workbench/app/views/jobs/show.html.erb

1  2 
apps/workbench/app/controllers/pipeline_instances_controller.rb
apps/workbench/app/views/jobs/index.html.erb
apps/workbench/app/views/jobs/show.html.erb
apps/workbench/app/views/pipeline_instances/show.html.erb

index 55ee02bc450cf8e11a1abb0dfff5f4200f13498b,d77694172bda87242ccd0a6108bcc3315c17e187..1bb95e091afcabb043dc1336d25eea197fd9664f
  class PipelineInstancesController < ApplicationController
+   skip_before_filter :find_object_by_uuid, only: :compare
+   before_filter :find_objects_by_uuid, only: :compare
+   include PipelineInstancesHelper
  
-       PipelineInstance.where(uuid: params[:compare]).each do |p| pipelines << p end
 +  def show
 +    pipelines = [@object]
 +
 +    if params[:compare]
-     #puts pips
++      PipelineInstance.where(uuid: params[:compare]).each do |p|
++        pipelines << p
++      end
 +    end
 +
 +    count = {}    
 +    provenance = {}
 +    pips = {}
 +    n = 1
 +
 +    pipelines.each do |p|
 +      collections = []
 +
 +      p.components.each do |k, v|
 +        j = v[:job]
 +
 +        uuid = j[:uuid].intern
 +        provenance[uuid] = j
 +        pips[uuid] = 0 unless pips[uuid] != nil
 +        pips[uuid] |= n
 +
 +        collections << j[:output]
 +        ProvenanceHelper::find_collections(j[:script_parameters]).each do |k|
 +          collections << k
 +        end
 +
 +        uuid = j[:script_version].intern
 +        provenance[uuid] = {:uuid => uuid}
 +        pips[uuid] = 0 unless pips[uuid] != nil
 +        pips[uuid] |= n
 +      end
 +
 +      Collection.where(uuid: collections).each do |c|
 +        uuid = c.uuid.intern
 +        provenance[uuid] = c
 +        pips[uuid] = 0 unless pips[uuid] != nil
 +        pips[uuid] |= n
 +      end
 +      
 +      n = n << 1
 +    end
 +
 +    @prov_svg = ProvenanceHelper::create_provenance_graph provenance, "provenance_svg", {
 +      :all_script_parameters => true, 
 +      :combine_jobs => :script_and_version,
 +      :script_version_nodes => true,
 +      :pips => pips }
 +  end
 +
+   def compare
+     @breadcrumb_page_name = 'compare'
+     @rows = []          # each is {name: S, components: [...]}
+     # Build a table: x=pipeline y=component
+     @objects.each_with_index do |pi, pi_index|
+       pipeline_jobs(pi).each do |component|
+         # Find a cell with the same name as this component but no
+         # entry for this pipeline
+         target_row = nil
+         @rows.each_with_index do |row, row_index|
+           if row[:name] == component[:name] and !row[:components][pi_index]
+             target_row = row
+           end
+         end
+         if !target_row
+           target_row = {name: component[:name], components: []}
+           @rows << target_row
+         end
+         target_row[:components][pi_index] = component
+       end
+     end
+     @rows.each do |row|
+       # Build a "normal" pseudo-component for this row by picking the
+       # most common value for each attribute. If all values are
+       # equally common, there is no "normal".
+       normal = {}              # attr => most common value
+       highscore = {}           # attr => how common "normal" is
+       score = {}               # attr => { value => how common }
+       row[:components].each do |pj|
+         pj.each do |k,v|
+           vstr = for_comparison v
+           score[k] ||= {}
+           score[k][vstr] = (score[k][vstr.to_s] || 0) + 1
+           highscore[k] ||= 0
+           if score[k][vstr] == highscore[k]
+             # tie for first place = no "normal"
+             normal.delete k
+           elsif score[k][vstr] == highscore[k] + 1
+             # more pipelines have v than anything else
+             highscore[k] = score[k][vstr]
+             normal[k] = vstr
+           end
+         end
+       end
+       # Add a hash in component[:is_normal]: { attr => is_the_value_normal? }
+       row[:components].each do |pj|
+         pj[:is_normal] = {}
+         pj.each do |k,v|
+           pj[:is_normal][k] = (normal.has_key?(k) && normal[k] == for_comparison(v))
+         end
+       end
+     end
+   end
+   protected
+   def for_comparison v
+     if v.is_a? Hash or v.is_a? Array
+       v.to_json
+     else
+       v.to_s
+     end
+   end
+   def find_objects_by_uuid
+     @objects = model_class.where(uuid: params[:uuids])
+   end
  end
index 5022b8b45435045f965e4bbb1d764f0f0e428f85,0000000000000000000000000000000000000000..2bc74ca00e3475d2818b7d94b80776fee2994b81
mode 100644,000000..100644
--- /dev/null
@@@ -1,6 -1,0 +1,6 @@@
- <%= render :partial => 'application/arvados_object' %>
++<%= render partial: 'arvados_object' %>
 +
 +<%= render partial: 'application/svg_div', locals: {
 +      divId: "provenance_graph", 
 +      svgId: "provenance_svg", 
 +      svg: @svg } %>