Advertisement
Pasted

dendroscope_parser

Jan 10th, 2012
389
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 21.35 KB | None | 0 0
  1. # Quick and dirty Dendroscope labeling script. Accepts a Dendroscope format tree and
  2. # a variety of clustering text files such as BAPS, eBURST and Bron-Kerbosch outputs
  3. # from the Allele Profiler java application
  4. # Copyright and all that shizzle:
  5. # Copyright (C) 2010 Garan Jones
  6. #
  7. # Permission is hereby granted, free of charge, to any person obtaining a copy of
  8. # this software and associated documentation files (the "Software"), to deal in
  9. # the Software without restriction, including without limitation the rights to
  10. # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  11. # of the Software, and to permit persons to whom the Software is furnished to do
  12. # so, subject to the following conditions:
  13. #
  14. # The above copyright notice and this permission notice shall be included in all
  15. # copies or substantial portions of the Software.
  16. #
  17. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. # SOFTWARE.
  24. #
  25. class Label
  26.     attr_accessor :lb_id, :lb_st, :lb_baps_cluster, :lb_colour
  27.     def initialize(st, cluster)
  28.         @lb_st = st
  29.         @lb_baps_cluster = cluster
  30.     end
  31. end
  32.  
  33. class Cluster
  34.     attr_accessor :cl_id, :cl_sts  
  35.     def initialize(id, st_array)
  36.         @cl_id = id
  37.         @cl_sts = st_array
  38.     end
  39. end
  40.  
  41.  
  42. class Lookup
  43.     attr_accessor :lk_id, :lk_sts
  44.     def initialize(id, st_array)
  45.         @lk_id = id
  46.         @lk_sts = st_array
  47.     end
  48. end
  49.  
  50. def colour_line(line, node_label, lb)
  51.  
  52.     if ! lb.nil?
  53.          
  54.         case lb.lb_baps_cluster.to_i
  55.             when 1
  56.                 #bright red bk, black font
  57.                 line.sub!(/lb='/, 'lk=255 0 0 lc=0 0 0 lb=\'')
  58.                 #line.sub!(/lb='/, 'nh=8 nw=8 sh=2 bg=255 0 0 fg=0 0 0 lb=\'')
  59.             when 2
  60.                 #bright green bk, black font
  61.                 line.sub!(/lb='/, 'lk=0 255 0 lc=0 0 0 lb=\'')
  62.                 #line.sub!(/lb='/, 'nh=8 nw=8 sh=2 bg=0 255 0 fg=0 0 0 lb=\'')
  63.             when 3
  64.                 #bright cyan bk, black font
  65.                 line.sub!(/lb='/, 'lk=0 255 255 lc=0 0 0 lb=\'')
  66.                 #line.sub!(/lb='/, 'nh=8 nw=8 sh=2 bg=0 255 255 fg=0 0 0 lb=\'')
  67.             when 4
  68.                 #dark red bk, white font
  69.                 line.sub!(/lb='/, 'lk=102 0 0 lc=255 255 255 lb=\'')
  70.                 #line.sub!(/lb='/, 'nh=8 nw=8 sh=2 bg=102 0 0 fg=0 0 0 lb=\'')
  71.             when 5
  72.                 #dark green bk, white font
  73.                 line.sub!(/lb='/, 'lk=0 102 0 lc=255 255 255 lb=\'')
  74.                 #line.sub!(/lb='/, 'nh=8 nw=8 sh=2 bg=0 102 0 fg=0 0 0 lb=\'')
  75.             when 6
  76.                 #dark blue bk, white font
  77.                 line.sub!(/lb='/, 'lk=0 51 204 lc=255 255 255 lb=\'')
  78.                 #line.sub!(/lb='/, 'nh=8 nw=8 sh=2 bg=0 51 204 fg=0 0 0 lb=\'')
  79.             when 7
  80.                 #dark grey bk, white font
  81.                 line.sub!(/lb='/, 'lk=51 51 51 lc=255 255 255 lb=\'')
  82.                 #line.sub!(/lb='/, 'nh=8 nw=8 sh=2 bg=51 51 51 fg=0 0 0 lb=\'')
  83.             when 8
  84.                 #teal bk, white font
  85.                 line.sub!(/lb='/, 'lk=0 102 102 lc=255 255 255 lb=\'')
  86.                 #line.sub!(/lb='/, 'nh=8 nw=8 sh=2 bg=0 102 102 fg=0 0 0 lb=\'')
  87.             when 9
  88.                 #pink bk, black font
  89.                 line.sub!(/lb='/, 'lk=255 51 255 lc=0 0 0 lb=\'')
  90.                 #line.sub!(/lb='/, 'nh=8 nw=8 sh=2 bg=255 51 255 fg=0 0 0 lb=\'')
  91.             when 10
  92.                 #orange bk, black font
  93.                 line.sub!(/lb='/, 'lk=255 153 0 lc=0 0 0 lb=\'')
  94.                 #line.sub!(/lb='/, 'nh=8 nw=8 sh=2 bg=255 153 0 fg=0 0 0 lb=\'')
  95.             when 11
  96.                 #gold bk, black font
  97.                 line.sub!(/lb='/, 'lk=204 204 0 lc=0 0 0 lb=\'')
  98.                 #line.sub!(/lb='/, 'nh=8 nw=8 sh=2 bg=204 204 0 fg=0 0 0 lb=\'')
  99.             when 12
  100.                 #yellow bk, black font
  101.                 line.sub!(/lb='/, 'lk=255 255 0 lc=0 0 0 lb=\'')
  102.                 #line.sub!(/lb='/, 'nh=8 nw=8 sh=2 bg=255 255 0 fg=0 0 0 lb=\'')
  103.             when 13
  104.                 #purple bk, white font
  105.                 line.sub!(/lb='/, 'lk=153 0 204 lc=255 255 255 lb=\'')
  106.             when 14
  107.                 #brown bk, white font
  108.                 line.sub!(/lb='/, 'lk=153 51 0 lc=255 255 255 lb=\'')
  109.             when 15
  110.                 #pale turquoise bk, black font
  111.                 line.sub!(/lb='/, 'lk=141 211 199 lc=0 0 0 lb=\'')
  112.             when 16
  113.                 #pale yellow bk, black font
  114.                 line.sub!(/lb='/, 'lk=255 255 179 lc=0 0 0 lb=\'')
  115.             when 17
  116.                 #pale lilac bk, black font
  117.                 line.sub!(/lb='/, 'lk=190 186 218 lc=0 0 0 lb=\'')
  118.             when 18
  119.                 #salmon bk, black font
  120.                 line.sub!(/lb='/, 'lk=251 128 114 lc=0 0 0 lb=\'')
  121.             when 19
  122.                 #pale blue bk, black font
  123.                 line.sub!(/lb='/, 'lk=128 177 211 lc=0 0 0 lb=\'')
  124.             when 20
  125.                 #flesh bk, black font
  126.                 line.sub!(/lb='/, 'lk=253 180 98 lc=0 0 0 lb=\'')
  127.             when 21
  128.                 #pale green bk, black font
  129.                 line.sub!(/lb='/, 'lk=179 222 105 lc=0 0 0 lb=\'')
  130.             when 22
  131.                 #pale pink bk, black font
  132.                 line.sub!(/lb='/, 'lk=252 205 229 lc=0 0 0 lb=\'')
  133.             when 23
  134.                 #pale grey, black font
  135.                 line.sub!(/lb='/, 'lk=217 217 217 lc=0 0 0 lb=\'')
  136.             when 24
  137.                 #puce bk, black font
  138.                 line.sub!(/lb='/, 'lk=188 128 189 lc=0 0 0 lb=\'')
  139.             when 25
  140.                 #pale celadon bk, black font
  141.                 line.sub!(/lb='/, 'lk=204 236 197 lc=0 0 0 lb=\'')
  142.             when 26
  143.                 #pale tan bk, black font
  144.                 line.sub!(/lb='/, 'lk=255 237 111 lc=0 0 0 lb=\'')
  145.             else
  146.                   #line.sub!(/lb='/, 'lk=null ll=11 lb=\'')
  147.                   line.sub!(/lb='/, 'nh=0 nw=0 sh=0 bg=null fg=null lb=\'')
  148.             end
  149.            
  150.     else
  151.         #line.sub!(/lb='/, 'lk=null ll=11 lb=\'')
  152.         line.sub!(/lb='/, 'nh=0 nw=0 sh=0 bg=null fg=null lb=\'')
  153.     end
  154.    node_label.sub!(/\//, '\/')
  155.   # line.sub!(/#{node_label}/, '') # remove label
  156. end
  157.  
  158. def options(param)
  159.    
  160.     i = 0
  161.     ARGV.each{|arg|
  162.    
  163.         if (arg == '-' + param.to_s)
  164.             return ARGV[i+1]
  165.         else
  166.             return false
  167.         end
  168.         i = i + 1
  169.     }
  170.    
  171. end
  172.  
  173. def print_help()
  174.         puts "-- ARGVS --"
  175.         puts " -m baps|baps_m|eburst|bk"
  176.         puts " If -m baps"
  177.         puts "  -it intree.dendro"
  178.         puts "  -ot baps_outtree.dendro"
  179.         puts "  -baps_in baps.txt"
  180.         puts " If -m baps_m"
  181.         puts "  -it intree.dendro"
  182.         puts "  -ot baps_outtree.dendro"
  183.         puts "  -baps_in baps.txt"
  184.         puts "  -baps_lk *filename needs to be specified, no default"
  185.         puts " If -m eburst"
  186.         puts "  -it intree.dendro"
  187.         puts "  -ot eburst_outtree.dendro"
  188.         puts "  -eburst_in eburst.txt"
  189.         puts " If -m bk"
  190.         puts "  -it intree.dendro"
  191.         puts "  -ot bk_outtree.dendro"
  192.         puts "  -bk_in bk.txt"
  193.         puts "  -m argument with either baps, baps_m, eburst or bk required. Additional arguments available are given below each mode option."
  194.         puts "  Default file names shown after each flag. Lookup tables only required if a merged profile is being used ie the input file has less loci compared to the profiles used to produce the tree."
  195. end
  196.  
  197. if options('m')
  198.     #return the mode to run
  199.     mode = options('m')
  200.     puts "Mode : " << mode
  201.     if mode == 'baps_m'
  202.         if options('it')
  203.             path = options('it')
  204.         else
  205.             path = "intree.dendro"
  206.         end
  207.        
  208.         if options('ot')
  209.             out_path = options('ot')
  210.         else
  211.             out_path = "baps_outtree.dendro"
  212.         end
  213.        
  214.         if options('baps_in')
  215.             baps_path = options('baps_in')
  216.         else
  217.             baps_path = "baps.txt"
  218.         end
  219.        
  220.         if options('baps_lk')
  221.             baps_lkup = options('baps_lk')
  222.         else
  223.             baps_lkup = "baps_lkup.txt"
  224.         end
  225.     elsif mode == 'baps'
  226.         if options('it')
  227.             path = options('it')
  228.         else
  229.             path = "intree.dendro"
  230.         end
  231.        
  232.         if options('ot')
  233.             out_path = options('ot')
  234.         else
  235.             out_path = "baps_outtree.dendro"
  236.         end
  237.        
  238.         if options('baps_in')
  239.             baps_path = options('baps_in')
  240.         else
  241.             baps_path = "baps.txt"
  242.         end
  243.     elsif mode == 'admix'
  244.         if options('it')
  245.             path = options('it')
  246.         else
  247.             path = "intree.dendro"
  248.         end
  249.        
  250.         if options('ot')
  251.             out_path = options('ot')
  252.         else
  253.             out_path = "admix_outtree.dendro"
  254.         end
  255.        
  256.         if options('admix_in')
  257.             admix_path = options('admix_in')
  258.         else
  259.             admix_path = "admix.txt"
  260.         end
  261.        
  262.     elsif mode == 'eburst'
  263.         if options('it')
  264.             path = options('it')
  265.         else
  266.             path = "intree.dendro"
  267.         end
  268.        
  269.         if options('ot')
  270.             out_path = options('ot')
  271.         else
  272.             out_path = "eburst_outtree.dendro"
  273.         end
  274.        
  275.         if options('eburst_in')
  276.             eburst_path = options('eburst_in')
  277.         else
  278.             eburst_path = "eburst.txt"
  279.         end
  280.        
  281.         if options('eburst_lk')
  282.             eburst_lkup = options('eburst_lk')
  283.         else
  284.             eburst_lkup = "eburst_lkup.txt"
  285.         end
  286.     elsif mode == 'bk'
  287.         if options('it')
  288.             path = options('it')
  289.         else
  290.             path = "intree.dendro"
  291.         end
  292.        
  293.         if options('ot')
  294.             out_path = options('ot')
  295.         else
  296.             out_path = "bk_outtree.dendro"
  297.         end
  298.        
  299.         if options('bk_in')
  300.             bk_path = options('bk_in')
  301.         else
  302.             bk_path = "bk.txt"
  303.         end
  304.        
  305.         if options('bk_lk')
  306.             bk_lkup = options('bk_lk')
  307.         else
  308.             bk_lkup = "bk_lkup.txt"
  309.         end
  310.     end
  311.    
  312.     if mode == 'baps_m'
  313.         #Merged BAPS clusters with lookup table
  314.         clusters = Array.new
  315.         lookups = Array.new
  316.         #import the baps clusters
  317.         baps_file = File.open(baps_path)
  318.         baps_file.each do |line|
  319.             if line =~ /Cluster/
  320.                 line_array = line.split(':')
  321.                
  322.                 cluster = line_array[0].to_s.slice(/\d.|\d/)
  323.                 sequence_types_baps = line_array[1].split(',')
  324.                 sequence_types_baps.each{|st| st.strip!}
  325.                 sequence_types_baps.collect!{|st| st.to_i}
  326.                 sequence_types_baps.sort!
  327.                
  328.                 this_cluster = Cluster.new(cluster, sequence_types_baps)
  329.                 clusters[cluster.to_i] = this_cluster
  330.             end
  331.         end
  332.         baps_file.close
  333.        
  334.         #import the lookup table
  335.         lkup_file = File.open(baps_lkup)
  336.         lkup_file.each do |line|
  337.            
  338.                 line_array = line.split(';')
  339.                
  340.                 id = line_array[0].to_s.strip
  341.                 sequence_types_lkup = line_array[2].split(',')
  342.                 sequence_types_lkup.each{|st| st.strip!}
  343.                 sequence_types_lkup.collect!{|st| st.to_i}
  344.                 sequence_types_lkup.sort!
  345.                
  346.                 this_lookup = Lookup.new(id, sequence_types_lkup)
  347.                 lookups[id.to_i] = this_lookup
  348.            
  349.         end
  350.         lkup_file.close
  351.        
  352.         #remove any nil fields
  353.         clusters.compact!
  354.         lookups.compact!
  355.        
  356.         #Array of labels
  357.         lb_array = Hash.new
  358.        
  359.         clusters.each do |clust|
  360.             if clust != nil
  361.                 clust.cl_sts.each do |st|
  362.                     lookups.each do |lk|
  363.                         if lk != nil
  364.                             if lk.lk_sts.include?(st)
  365.                                 lb = Label.new(st, clust.cl_id)
  366.                                 lb.lb_id = lk.lk_id
  367.                                 lb_array[lb.lb_id] = lb
  368.                             end
  369.                         end
  370.                     end
  371.                 end
  372.             end
  373.         end
  374.        
  375.        
  376.         #build the label class
  377.        
  378.         tree_file = File.open(path)
  379.         out_tree = File.open(out_path, 'w')
  380.         finished_merged_ids = Array.new
  381.         tree_file.each do |line|
  382.           if line =~ /lb='(.+)';/ # line contains a label
  383.             node_label = $1
  384.             node_label.strip!
  385.             if node_label != nil && !lb_array.key?(node_label)
  386.                 line.sub!(/lb='/, 'lk=null lc=0 0 0 lb=\'')
  387.             end
  388.             lb_array.each_value do |lb|
  389.                
  390.                 if lb.lb_id == node_label
  391.                     if !finished_merged_ids.include?(lb.lb_id)
  392.                         colour_line(line, node_label, lb)
  393.                         finished_merged_ids.push(lb.lb_id)
  394.                     else
  395.                         puts "Merged id : " << lb.lb_id.to_s << "    ST : " << lb.lb_st.to_s
  396.                     end
  397.                 end
  398.        
  399.             end
  400.        
  401.           end
  402.           out_tree.write(line)
  403.         end
  404.         tree_file.close
  405.         out_tree.close
  406.     elsif mode == 'baps'
  407.         #normal BAPS mode - no merged profiles or lookup tables
  408.         clusters = Array.new
  409.        
  410.         #import the baps clusters
  411.         baps_file = File.open(baps_path)
  412.         baps_file.each do |line|
  413.             if line =~ /Cluster/
  414.                 line_array = line.split(':')
  415.                
  416.                 cluster = line_array[0].to_s.slice(/\d.|\d/)
  417.                 sequence_types_baps = line_array[1].split(',')
  418.                 sequence_types_baps.each{|st| st.strip!}
  419.                 sequence_types_baps.collect!{|st| st.to_i}
  420.                 sequence_types_baps.sort!
  421.                
  422.                 this_cluster = Cluster.new(cluster, sequence_types_baps)
  423.                 clusters[cluster.to_i] = this_cluster
  424.             end
  425.         end
  426.         baps_file.close
  427.         #remove any nil fields
  428.         clusters.compact!
  429.        
  430.         #Array of labels
  431.         lb_array = Hash.new
  432.        
  433.         clusters.each do |clust|
  434.             if clust != nil
  435.                 clust.cl_sts.each do |st|
  436.                     lb = Label.new(st, clust.cl_id)
  437.                     lb.lb_id = st.to_s
  438.                     lb_array[lb.lb_id] = lb
  439.  
  440.                 end
  441.             end
  442.         end
  443.        
  444.        
  445.         #build the label class
  446.        
  447.         tree_file = File.open(path)
  448.         out_tree = File.open(out_path, 'w')
  449.         tree_file.each do |line|
  450.           if line =~ /lb='(.+)';/ # line contains a label
  451.             node_label = $1
  452.             node_label.strip!
  453.            
  454.             if node_label != nil && !lb_array.key?(node_label)
  455.                 #line.sub!(/lb='/, 'lk=null lc=0 0 0 lb=\'')
  456.                
  457.                 if node_label =~ /\./
  458.                         #line.sub!(/lb='/, 'lk=null lb=\'')
  459.                         split_line = line.split("lb=")
  460.                         line = split_line[0].strip! << ";"
  461.                         puts node_label.to_s
  462.                         puts line.to_s
  463.                     end
  464.             end
  465.             lb_array.each_value do |lb|
  466.  
  467.                 if lb.lb_id.to_s == node_label.to_s
  468.                     colour_line(line, node_label, lb)
  469.                 end
  470.             end
  471.        
  472.           end
  473.           out_tree.write(line)
  474.         end
  475.         tree_file.close
  476.         out_tree.close
  477.     elsif mode == "eburst"
  478.         #Eburst takes standard eburst output file as input along with tree
  479.         #normal BAPS mode - no merged profiles or lookup tables
  480.         clusters = Array.new
  481.         new_eburst_group = false
  482.         #import the baps clusters
  483.         eburst_file = File.open(eburst_path)
  484.         #start a new st array
  485.         st_array = Array.new
  486.         #declare cluster variable outside of loop so it can pass between the if statements
  487.         cluster = ""
  488.         eburst_file.each do |line|
  489.             if line =~ /Group/
  490.                 #start of new eburst group
  491.                 line_array = line.split(':')
  492.                 cluster = line_array[0].to_s.slice(/\d.|\d/)
  493.                
  494.                 if cluster == nil
  495.                     puts line
  496.                    
  497.                 end
  498.                 new_eburst_group = true
  499.                 #skip headers
  500.                 eburst_file.readline()
  501.                 eburst_file.readline()
  502.  
  503.             end
  504.             if new_eburst_group == true
  505.                
  506.                 if line =~ /^\d/
  507.                     #line starts with a digit must include the ST
  508.                     line_array = line.split('\t')
  509.                     #make sure that the slice method has a regex in this order from largest expected number of digits to smallest, otherwise it
  510.                     #will just return the first instance of the regex that matches (only the first digit on each line)
  511.                     this_st = line_array[0].to_s.slice(/\d..|\d.|\d/)
  512.                     this_st.strip!
  513.                     st_array << this_st.to_i
  514.                    
  515.                 elsif line =~ /^\s*$/
  516.                     #empty line end of eburst group - reset new_eburst_group boolean to false
  517.                     new_eburst_group = false
  518.                     #build cluster
  519.                     st_array.compact!
  520.                     st_array.sort!
  521.                     puts cluster
  522.                     this_cluster = Cluster.new(cluster, st_array)
  523.                     clusters[cluster.to_i] = this_cluster
  524.                    
  525.                     st_array = Array.new
  526.                 end
  527.                
  528.             end
  529.         end
  530.        
  531.         eburst_file.close
  532.         #remove any nil fields
  533.         clusters.compact!
  534.         #Array of labels
  535.         lb_array = Hash.new
  536.        
  537.         clusters.each do |clust|
  538.             if clust != nil
  539.                 clust.cl_sts.each do |st|
  540.                     lb = Label.new(st, clust.cl_id)
  541.                     lb.lb_id = st.to_s
  542.                     lb_array[lb.lb_id] = lb
  543.                 end
  544.             end
  545.         end
  546.  
  547.         #build the label class
  548.        
  549.         tree_file = File.open(path)
  550.         out_tree = File.open(out_path, 'w')
  551.         tree_file.each do |line|
  552.           if line =~ /lb='(.+)';/ # line contains a label
  553.             node_label = $1
  554.             node_label.strip!
  555.            
  556.             if node_label != nil && !lb_array.key?(node_label)
  557.                 line.sub!(/lb='/, 'lk=null lc=0 0 0 lb=\'')
  558.             end
  559.             lb_array.each_value do |lb|
  560.  
  561.                 if lb.lb_id.to_s == node_label.to_s
  562.                     colour_line(line, node_label, lb)
  563.                 end
  564.             end
  565.        
  566.           end
  567.           out_tree.write(line)
  568.         end
  569.         tree_file.close
  570.         out_tree.close
  571.  
  572.     elsif mode == "bk"
  573.         #BK input file starts with number of nucleotides threshold on the first line (usually 7 or 9 depending on the number of loci in the profile)
  574.         #The start of each BK cluster is then marked with '>' followed by the cluster id number and the number of constituent profiles (seperated by a colon)
  575.         #the following lines are the constituent ST / profile ID number followed by the profile (seperated by a colon)
  576.         #E.g.
  577.         #9
  578.         #>1 : 220
  579.         #2 : 6,10,19,3,19,4,9
  580.         #4 : 1,10,19,1,9,4,1
  581.  
  582.         #normal BAPS mode - no merged profiles or lookup tables
  583.         clusters = Array.new
  584.         new_bk_group = false
  585.         #import the baps clusters
  586.         bk_file = File.open(bk_path)
  587.         #start a new st array
  588.         st_array = Array.new
  589.         #declare cluster variable outside of loop so it can pass between the if statements
  590.         cluster = ""
  591.         bk_file.each do |line|     
  592.                
  593.                 if (line =~ /^\d/) && !(line =~ />/)
  594.                     if new_bk_group == true
  595.                         #line starts with a digit and doesnt include '>' must include the ST
  596.                         line_array = line.split(':')
  597.                         #make sure that the slice method has a regex in this order from largest expected number of digits to smallest, otherwise it
  598.                         #will just return the first instance of the regex that matches (only the first digit on each line)
  599.                         this_st = line_array[0].to_s.slice(/\d..|\d.|\d/)
  600.                         this_st.strip!
  601.                         st_array << this_st.to_i
  602.                     end
  603.                 elsif line =~ />/
  604.                     if st_array.length > 0
  605.                         #st_array is full so make the last cluster before starting this new one
  606.                         st_array.compact!
  607.                         st_array.sort!
  608.                         this_cluster = Cluster.new(cluster, st_array)
  609.                         clusters[cluster.to_i] = this_cluster
  610.                         #remake st_array
  611.                         st_array = Array.new
  612.                     end
  613.                     #start of new BK group
  614.                     line_array = line.split(':')
  615.                     cluster = line_array[0].to_s.slice(/\d.|\d/)
  616.                    
  617.                     if cluster == nil
  618.                         puts line
  619.                     end
  620.                     new_bk_group = true
  621.                 end
  622.         end
  623.        
  624.         bk_file.close
  625.         #remove any nil fields
  626.         clusters.compact!
  627.         #Array of labels
  628.         lb_array = Hash.new
  629.        
  630.         clusters.each do |clust|
  631.             if clust != nil
  632.                 clust.cl_sts.each do |st|
  633.                     lb = Label.new(st, clust.cl_id)
  634.                     lb.lb_id = st.to_s
  635.                     lb_array[lb.lb_id] = lb
  636.                 end
  637.             end
  638.         end
  639.  
  640.         #build the label class
  641.        
  642.         tree_file = File.open(path)
  643.         out_tree = File.open(out_path, 'w')
  644.         tree_file.each do |line|
  645.           if line =~ /lb='(.+)';/ # line contains a label
  646.             node_label = $1
  647.             node_label.strip!
  648.            
  649.             if node_label != nil && !lb_array.key?(node_label)
  650.                 line.sub!(/lb='/, 'lk=null lc=0 0 0 lb=\'')
  651.             end
  652.             lb_array.each_value do |lb|
  653.  
  654.                 if lb.lb_id.to_s == node_label.to_s
  655.                     colour_line(line, node_label, lb)
  656.                 end
  657.             end
  658.        
  659.           end
  660.           out_tree.write(line)
  661.         end
  662.         puts "--- Summary ---"
  663.         puts clusters.length.to_s << " Clusters labelled."
  664.         puts lb_array.length.to_s << " Labels processed."
  665.         puts "Output file : " << out_path
  666.         tree_file.close
  667.         out_tree.close
  668.        
  669.     elsif mode == "admix"
  670.         #normal BAPS mode - no merged profiles or lookup tables
  671.         clusters = Array.new
  672.        
  673.         #import the baps clusters
  674.         admix_file = File.open(admix_path)
  675.         header_array = Array.new
  676.         pop_array = Array.new
  677.         admix_file.each do |line|      
  678.  
  679.             if line =~ /^Index/
  680.                     #start of the admix clustering table
  681.                     #read in header line and find number of populations
  682.                     header_array = line.split(" ")
  683.                     #extract population id numbers from headers
  684.                    
  685.                     pop_array = header_array[2..-2]
  686.                    
  687.                     puts pop_array.inspect
  688.                     #skip blank lines, read in cluster info for each ST
  689.                     admix_file.each do |table_line|
  690.                         if !(table_line =~ /^\s*$/)
  691.                             #not a blank line
  692.                             this_line = table_line.split(" ")
  693.                            
  694.                             this_pop_array = this_line[2..-2]
  695.                             #find the highest value out of the populations - this should be the one that the ST is assigned to
  696.                             pop_val = this_pop_array[0].to_f
  697.                             pop_id = pop_array[0].to_i
  698.                             pop_count = pop_id
  699.                             this_pop_array.each do |this_val|
  700.                                 if this_val.to_f > pop_val.to_f
  701.                                     pop_val = this_val
  702.                                     pop_id = pop_count
  703.                                 end
  704.                                 pop_count = pop_count + 1
  705.                             end
  706.                             #get the P value
  707.                             p_val = this_line[-1].to_f
  708.                             #get the ST
  709.                             st_val = this_line[1]
  710.                             if (p_val.to_f > 0.05) && (pop_val.to_f > 0.5)
  711.                                 #if p_val is greater than the cutoff and highest pop_val is greater than 0.5
  712.                                 #ie the ST can be assigned to one definite population
  713.                                 #construct label
  714.                                 if clusters[pop_id.to_i] != nil
  715.                                     #if the population exists, get cluster object and push new st onto the st array
  716.                                     this_cluster = clusters[pop_id.to_i]
  717.                                     this_cluster.cl_sts.push(st_val)
  718.                                     clusters[pop_id.to_i] = this_cluster
  719.                                 else
  720.                                     #else make a new population
  721.                                     new_st_array = Array[st_val]
  722.                                     this_cluster = Cluster.new(pop_id.to_i, new_st_array)
  723.                                     clusters[pop_id.to_i] = this_cluster
  724.                                 end
  725.  
  726.                             end
  727.                            
  728.  
  729.                         end
  730.                    
  731.                     end
  732.  
  733.             end
  734.         end
  735.         clusters.compact!
  736.        
  737.         admix_file.close
  738.         #Array of labels
  739.         lb_array = Hash.new
  740.        
  741.         clusters.each do |clust|
  742.             if clust != nil
  743.                 clust.cl_sts.each do |st|
  744.                     lb = Label.new(st, clust.cl_id)
  745.                     lb.lb_id = st.to_s
  746.                     lb_array[lb.lb_id] = lb
  747.                 end
  748.             end
  749.         end
  750.  
  751.         #build the label class
  752.        
  753.         tree_file = File.open(path)
  754.         out_tree = File.open(out_path, 'w')
  755.         tree_file.each do |line|
  756.           if line =~ /lb='(.+)';/ # line contains a label
  757.             node_label = $1
  758.             node_label.strip!
  759.            
  760.             if node_label != nil && !lb_array.key?(node_label)
  761.                 # line.sub!(/lb='/, 'nh=1 nw=1 sh=2 bg=0 0 0 fg=0 0 0 lb=\'')
  762.                 line.sub!(/lb='/, 'lk=null lc=0 0 0 lb=\'')
  763.             end
  764.             lb_array.each_value do |lb|
  765.  
  766.                 if lb.lb_id.to_s == node_label.to_s
  767.                     colour_line(line, node_label, lb)
  768.                 end
  769.             end
  770.        
  771.           end
  772.           out_tree.write(line)
  773.         end
  774.         puts "--- Summary ---"
  775.         puts clusters.length.to_s << " Clusters labelled."
  776.         puts lb_array.length.to_s << " Labels processed."
  777.         puts "Output file : " << out_path
  778.         tree_file.close
  779.         out_tree.close
  780.        
  781.     else
  782.         #print help file
  783.         print_help()
  784.     end
  785. else
  786.     #print help file
  787.     print_help()
  788. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement