Merge branch '1977-provenance-report' of git.clinicalfuture.com:arvados into 1977...
[arvados.git] / apps / workbench / app / helpers / provenance_helper.rb
index 9d9f44b335919dc2e1b698c4984b543cb2f47cfe..ef165e86e9eb8be210fcbbf80d93501812d5fb88 100644 (file)
@@ -24,17 +24,38 @@ module ProvenanceHelper
       end
     end
 
+    def determine_fillcolor(n)
+      bgcolor = ""
+      case n
+      when 1
+        bgcolor = "style=filled,fillcolor=\"#88ff88\""
+      when 2
+        bgcolor = "style=filled,fillcolor=\"#8888ff\""
+      when 3
+        bgcolor = "style=filled,fillcolor=\"#88ffff\""
+      end
+      bgcolor
+    end
+
     def describe_node(uuid)
+      bgcolor = determine_fillcolor @opts[:pips][uuid] if @opts[:pips]
+
       rsc = ArvadosBase::resource_class_for_uuid uuid.to_s
       if rsc
         href = "/#{rsc.to_s.underscore.pluralize rsc}/#{uuid}"
-
+      
         #"\"#{uuid}\" [label=\"#{rsc}\\n#{uuid}\",href=\"#{href}\"];\n"
         if rsc == Collection
+          puts uuid
+          if uuid == :"d41d8cd98f00b204e9800998ecf8427e+0"
+            # special case
+            puts "empty!"
+            return "\"#{uuid}\" [label=\"(empty collection)\"];\n"
+          end
           if @pdata[uuid] 
             #puts @pdata[uuid]
             if @pdata[uuid][:name]
-              return "\"#{uuid}\" [label=\"#{@pdata[uuid][:name]}\",href=\"#{href}\",shape=oval];\n"
+              return "\"#{uuid}\" [label=\"#{@pdata[uuid][:name]}\",href=\"#{href}\",shape=oval,#{bgcolor}];\n"
             else
               files = nil
               if @pdata[uuid].respond_to? :files
@@ -54,19 +75,21 @@ module ProvenanceHelper
                 if i < files.length
                   label += "\\n&vellip;"
                 end
-                return "\"#{uuid}\" [label=\"#{label}\",href=\"#{href}\",shape=oval];\n"
+                return "\"#{uuid}\" [label=\"#{label}\",href=\"#{href}\",shape=oval,#{bgcolor}];\n"
               end
             end  
           end
-          return "\"#{uuid}\" [label=\"#{rsc}\",href=\"#{href}\"];\n"
+          return "\"#{uuid}\" [label=\"#{rsc}\",href=\"#{href}\",#{bgcolor}];\n"
         end
       end
-      return ""
+      "\"#{uuid}\" [#{bgcolor}];\n"
     end
 
     def job_uuid(job)
-      if @opts[:combine_jobs]
+      if @opts[:combine_jobs] == :script_only
         uuid = "#{job[:script]}"
+      elsif @opts[:combine_jobs] == :script_and_version
+        uuid = "#{job[:script]}_#{job[:script_version]}"
       else
         uuid = "#{job[:uuid]}"
       end
@@ -111,7 +134,7 @@ module ProvenanceHelper
           sp.each do |v|
             if GenerateGraph::collection_uuid(v)
               gr += script_param_edges(job, "#{prefix}[#{i}]", v)
-            else
+            elsif @opts[:all_script_parameters]
               node += "', '" unless node == ""
               node = "['" if node == ""
               node += "#{v}"
@@ -127,7 +150,8 @@ module ProvenanceHelper
           end
         else
           m = GenerateGraph::collection_uuid(sp)
-          if m
+          #puts "#{m} pdata is #{@pdata[m.intern]}"
+          if m and (@pdata[m.intern] or (not @opts[:pdata_only]))
             gr += edge(job_uuid(job), m, {:label => prefix})
             gr += generate_provenance_edges(m)
           elsif @opts[:all_script_parameters]
@@ -165,6 +189,11 @@ module ProvenanceHelper
         # uuid is a collection
         gr += describe_node(uuid)
 
+        if m == :"d41d8cd98f00b204e9800998ecf8427e+0"
+          # empty collection, don't follow any further
+          return gr
+        end
+
         @pdata.each do |k, job|
           if job[:output] == uuid.to_s
             gr += edge(uuid, job_uuid(job), {:label => "output"})
@@ -185,6 +214,7 @@ module ProvenanceHelper
             gr += script_param_edges(job, "", job[:script_parameters])
 
             if @opts[:script_version_nodes]
+              gr += describe_node(job[:script_version])
               gr += edge(job_uuid(job), job[:script_version], {:label => "script_version"})
             end
           end
@@ -206,25 +236,34 @@ module ProvenanceHelper
       gr
     end
 
-    def add_jobs_href
+    def describe_jobs
       gr = ""
       @jobs.each do |k, v|
         gr += "\"#{k}\" [href=\"/jobs?"
-        script = ""
+        
+        n = 0
         v.each do |u|
           gr += "uuid%5b%5d=#{u[:uuid]}&"
-          script = u[:script]
+          n |= @opts[:pips][u[:uuid].intern] if @opts[:pips] and @opts[:pips][u[:uuid].intern]
         end
+
         gr += "\",label=\""
-        gr += if @opts[:combine_jobs] then "#{script}" else "#{script}\\n#{v[0][:finished_at]}" end
-        gr += "\"];\n"
+        
+        if @opts[:combine_jobs] == :script_only
+          gr += uuid = "#{v[0][:script]}"
+        elsif @opts[:combine_jobs] == :script_and_version
+          gr += uuid = "#{v[0][:script]}"
+        else
+          gr += uuid = "#{v[0][:script]}\\n#{v[0][:finished_at]}"
+        end
+        gr += "\",#{determine_fillcolor n}];\n"
       end
       gr
     end
 
   end
 
-  def self.create_provenance_graph(pdata, opts={})
+  def self.create_provenance_graph(pdata, svgId, opts={})
     if pdata.is_a? Array or pdata.is_a? ArvadosResourceList
       p2 = {}
       pdata.each do |k|
@@ -238,8 +277,8 @@ module ProvenanceHelper
     end
     
     gr = """strict digraph {
-node [fontsize=8,shape=box];
-edge [fontsize=8];
+node [fontsize=10,shape=box];
+edge [fontsize=10];
 """
 
     if opts[:direction] == :bottom_up
@@ -254,7 +293,7 @@ edge [fontsize=8];
       gr += g.generate_provenance_edges(k)
     end
 
-    gr += g.add_jobs_href
+    gr += g.describe_jobs
 
     gr += "}"
     svg = ""
@@ -273,6 +312,7 @@ edge [fontsize=8];
 
     svg = svg.sub(/<\?xml.*?\?>/m, "")
     svg = svg.sub(/<!DOCTYPE.*?>/m, "")
+    svg = svg.sub(/<svg /, "<svg id=\"#{svgId}\" ")
   end
 
   def self.find_collections(sp)