class SequenceWithAction

Author

Almudena Bocinos Rioboo

This class create the structure to storage the actions associated to a sequence. It allows to add action, and to write at file the actions for every sequence

Inherit

Sequence

Constants

SHOW_FINAL_INSERTS
SHOW_QUAL

Attributes

actions[RW]
insert_end[RW]
insert_end_last[RW]
insert_start[RW]
insert_start_last[RW]
order_in_tuple[RW]
seq_fasta_orig[RW]
seq_qual_orig[RW]
stats[RW]
tuple_id[RW]
tuple_size[RW]

Public Class Methods

new(seq_name,seq_fasta,seq_qual, seq_comment = '') click to toggle source

Creates an instance with the structure to storage the actions associated to a sequence

Calls superclass method Sequence::new
# File lib/seqtrimnext/classes/sequence_with_action.rb, line 21
def initialize(seq_name,seq_fasta,seq_qual, seq_comment = '')
  super

  @actions = []
  @seq_fasta_orig = seq_fasta
  @seq_fasta = seq_fasta
  
  @seq_qual_orig = seq_qual
  @seq_qual = seq_qual     
  
  @insert_start = 0
  @insert_end = seq_fasta.length-1 
  
  @stats={}
  @comments=[]
  
  @file_tags=[]
  
  # for paired ends
  @order_in_tuple=0
  @tuple_id=0
  @tuple_size=0
  @file_tag_tuple_priority=0
  
end

Public Instance Methods

action_right(a,p_beg,p_end) click to toggle source
# File lib/seqtrimnext/classes/sequence_with_action.rb, line 431
def action_right(a,p_beg,p_end) 
  
    # $LOG.debug " is right action" if ((a.start_pos-p_beg)>(p_end-a.end_pos-1))
    # $LOG.debug " is left action " if !((a.start_pos-p_beg)>(p_end-a.end_pos-1))
    return ((a.start_pos-p_beg)>(p_end-a.end_pos-1))
  
end
add_action(a) click to toggle source

Adds a new action to the sequence

# File lib/seqtrimnext/classes/sequence_with_action.rb, line 91
def add_action(a)
  $LOG.debug("Adding action #{a.type} to #{seq_name}")
        
  @actions.push a
  
  a.apply_to(self)
  
  return a
  
end
add_actions(actions) click to toggle source

TODO - Nuevo algoritmo de corte de seqs. 1 - Ordenar seqs con cut=true en izq y der y por posición de ends o begs 2 - Obtener izq.ends.max y der.begs.min 3 - El corte lo definen esos min y max

# File lib/seqtrimnext/classes/sequence_with_action.rb, line 128
def add_actions(actions)
              
  if !actions.empty?             
     start_pos=0
     end_pos = 0
     cut = false              

     max_end_pos = 0 
     
         
     
     p_beg = @insert_start
     p_end = @seq_fasta.length-1+@insert_start   
     # p_end = @seq_fasta.length-1
     # puts "ADDING ACTIONS"
     # puts "=" * 50
     # puts 'actions ' + actions.inspect
     # para cada accion ordenada por start_pos
     actions.sort{|e,f| e.start_pos<=>f.start_pos}.each do |action| 
       # puts ' current ' + action.inspect
       # puts " UUUUUUUUUU1 "
       # puts "vect in pos #{action.start_pos} #{action.end_pos}" if (action.type=='ActionVectors')
       # puts " UUUUUUUUUU2 "
                      
       # puts "ADD ACTION:",action.to_json
                       
       # añadir el inicio del inserto si es necesario
       if action.start_pos !=0 or action.end_pos != 0
          action.start_pos+=@insert_start    
          action.end_pos+=@insert_start            
       end       
       
       # guardar accion
       a = add_action(action)
       
       start_pos= a.start_pos                     
       end_pos=a.end_pos             
                                  
                     
       # si hay que cortar y es accion izquierda
       # if (a.cut && ( left_action(@seq_fasta,start_pos-p_beg,end_pos) ||   # action is left in insert
       if (a.cut && a.left_action?(@seq_fasta.length))
       # if (a.cut && ( a.left_action==true ||
       #                       ( a.right_action==false && (left_action(@seq_fasta,start_pos-p_beg,end_pos-p_beg) ||   # action is left in insert
       #                        (start_pos==p_beg)) )))     # action is right in insert but it's continous to the before action
       #
           # puts "in seq w action left act  #{start_pos} #{end_pos} pbeg #{p_beg} p_end #{p_end}"
            # puts "Cut left: #{a.inspect}"
           if (end_pos+1) > p_beg
             p_beg=end_pos+1
           end
           a.left_action=true
           cut=true     
           # puts "in seq w action left act  #{start_pos} #{end_pos} pbeg #{p_beg} p_end #{p_end}"
           
        # elsif (a.cut && right_action(@seq_fasta,start_pos-p_beg,end_pos)) # action is rigth  in insert
       elsif (a.cut && a.right_action?(@seq_fasta.length))
         # puts "Cut right: #{a.inspect}"
        # elsif (a.cut && (a.right_action==true || right_action(@seq_fasta,start_pos-p_beg,end_pos-p_beg))) # action is rigth  in insert
           # puts "in seq w action right act  #{start_pos} #{end_pos} pbeg #{p_beg} p_end #{p_end}"
           if (start_pos-1) < p_end
             p_end = start_pos-1   
           end
           a.right_action=true
           cut=true  
           # puts "in seq w action right act  #{start_pos} #{end_pos} pbeg #{p_beg} p_end #{p_end}"
       elsif !a.cut
           # puts "NO cut action"
           if a.right_action?(@seq_fasta.length)
             a.right_action=true
           else
             a.left_action = true
           end

       end  
        
       # puts "p_beg: #{p_beg} , p_end: #{p_end}"
      
    end
    
 
    if cut then 
             
      @seq_fasta = @seq_fasta_orig[p_beg..p_end] 
      # puts @seq_fasta
      @seq_qual = @seq_qual_orig[p_beg..p_end] if !@seq_qual_orig.nil?
                  
      # puts "in seq w action1 #{@insert_start} #{@insert_end}"
      @insert_start = p_beg
      size_cut_right = @insert_end - p_end
      @insert_end -= size_cut_right
      # puts "in seq w action2 #{@insert_start} #{@insert_end}"
      
      
    end    
   end
 end
add_actions_no_left_rigth_parameters(actions) click to toggle source

Adds a set of actions to the sequence, update the positon of the cut sequence. # Version without the parameters left_action and rigth action #

# File lib/seqtrimnext/classes/sequence_with_action.rb, line 230
def add_actions_no_left_rigth_parameters(actions)
              
  if !actions.empty?
     start_pos=0
     end_pos = 0
     cut = false              

     max_end_pos = 0 
     
         
     
     p_beg = @insert_start
     p_end = @seq_fasta.length-1+@insert_start   
     # p_end = @seq_fasta.length-1
           
     # puts 'actions ' + actions.inspect
     # para cada accion ordenada por start_pos
     actions.sort!{|e,f| e.start_pos<=>f.start_pos}.each do |action| 
       # puts ' current ' + action.inspect
       # puts " UUUUUUUUUU1 "
       # puts "vect in pos #{action.start_pos} #{action.end_pos}" if (action.type=='ActionVectors')
       # puts " UUUUUUUUUU2 "
                      
       # puts "ADD ACTION:",action.to_json
                       
       # añadir el inicio del inserto si es necesario
       if action.start_pos !=0 or action.end_pos != 0
          action.start_pos+=@insert_start    
          action.end_pos+=@insert_start            
       end       
       
       # guardar accion
       a = add_action(action)
       
       start_pos= a.start_pos                     
       end_pos=a.end_pos             
                                  
                      
       # si hay que cortar y es accion izquierda
       # if (a.cut && ( left_action(@seq_fasta,start_pos-p_beg,end_pos) ||   # action is left in insert
       if (a.cut && ( left_action(@seq_fasta,start_pos-p_beg,end_pos-p_beg) ||   # action is left in insert
                     (start_pos==p_beg)) )     # action is right in insert but it's continous to the before action
           
           puts "in seq w action left act  #{start_pos} #{end_pos} pbeg #{p_beg} p_end #{p_end}"                                                                        
           
           p_beg=end_pos+1
           cut=true     
           a.left_action=true
           # puts "in seq w action left act  #{start_pos} #{end_pos} pbeg #{p_beg} p_end #{p_end}"
           
        # elsif (a.cut && right_action(@seq_fasta,start_pos-p_beg,end_pos)) # action is rigth  in insert
        elsif (a.cut && right_action(@seq_fasta,start_pos-p_beg,end_pos-p_beg)) # action is rigth  in insert
           puts "in seq w action right act  #{start_pos} #{end_pos} pbeg #{p_beg} p_end #{p_end}"  
           p_end = start_pos-1   
           a.right_action=true
           cut=true  
           # puts "in seq w action right act  #{start_pos} #{end_pos} pbeg #{p_beg} p_end #{p_end}"
        elsif !a.cut
          puts "NO cut action"
          if right_action(@seq_fasta,start_pos-p_beg,end_pos-p_beg)
            a.right_action=true
          end
          
        end  
        
 
      
    end
    
 
    if cut then 
             
      @seq_fasta = @seq_fasta_orig[p_beg..p_end] 
      @seq_qual = @seq_qual_orig[p_beg..p_end] if !@seq_qual_orig.nil?
                  
      # puts "in seq w action1 #{@insert_start} #{@insert_end}"
      @insert_start = p_beg
      size_cut_right = @insert_end - p_end
      @insert_end -= size_cut_right   
      # puts "in seq w action2 #{@insert_start} #{@insert_end}"
      
 
      
    end    
   end
 end
add_comment(comment) click to toggle source
# File lib/seqtrimnext/classes/sequence_with_action.rb, line 47
def add_comment(comment)
  @comments.push comment
end
add_file_tag(tag_level, tag_value, tag_type, priority=0) click to toggle source

add a file tag to sequence

# File lib/seqtrimnext/classes/sequence_with_action.rb, line 56
def add_file_tag(tag_level, tag_value, tag_type, priority=0)
  @file_tags<< {:level => tag_level, :name => tag_value, :type=> tag_type}
  @file_tag_tuple_priority=priority
end
get_actions(type=nil) click to toggle source

Receive a type of action. Be carefull, type is not a string . Return an array of actions of this type

# File lib/seqtrimnext/classes/sequence_with_action.rb, line 446
def get_actions(type=nil)
   res = []
             
   @actions.each do |a|
      if a.is_a?(type) or type.nil?
        res.push a
      end
   end
   
   return res
end
get_comment_line() click to toggle source
# File lib/seqtrimnext/classes/sequence_with_action.rb, line 51
def get_comment_line
  return ([@seq_rejected_by_message]+@comments).compact.join(';')
end
get_file_tag_path() click to toggle source

join file tags into a path

# File lib/seqtrimnext/classes/sequence_with_action.rb, line 62
def get_file_tag_path
  levels=@file_tags.map{|e| e[:level]}.uniq

  dirpath = []
  levels.sort.each do |level|
    # select names from all that are not files
    level_path = @file_tags.select{|e| ((e[:level]==level) && (e[:type]!=:file))}.map{|tag| tag[:name]}
    dirpath << level_path.join('_') if !level_path.empty?
  end
  
  filepath = []
  levels.sort.each do |level|
    # select names from all that are not files
    level_path = @file_tags.select{|e| ((e[:level]==level) && (e[:type]!=:dir))}.map{|tag| tag[:name]}
    filepath << level_path.join('_') if !level_path.empty?
  end
  
  
  filename=filepath.join('_')
  dirname=File.join(dirpath)
  
  
  # puts "#{dirname}, #{filename}"
  
  return [dirname,filename,@file_tag_tuple_priority]
  
end
get_inserts() click to toggle source
# File lib/seqtrimnext/classes/sequence_with_action.rb, line 461
def get_inserts
   
  inserts = get_actions(ActionInsert)
  
  res =[]         
  inserts.each do |insert|
    res.push @seq_fasta_orig[insert.start_pos..insert.end_pos]
  end

  return res 

end
get_qual_inserts() click to toggle source
# File lib/seqtrimnext/classes/sequence_with_action.rb, line 474
def get_qual_inserts
   
  inserts = get_actions(ActionInsert)
  
  res =[]
  
  if @seq_qual_orig
    inserts.each do |insert|
      res.push @seq_qual_orig[insert.start_pos..insert.end_pos]
    end
  end
  
  return res 

end
insert_bounds() click to toggle source
# File lib/seqtrimnext/classes/sequence_with_action.rb, line 490
def insert_bounds
  return [@insert_start,@insert_end]
end
new_action(start_pos,end_pos,action_type) click to toggle source

Adds a new action to the sequence

# File lib/seqtrimnext/classes/sequence_with_action.rb, line 103
def new_action(start_pos,end_pos,action_type)
  
  a = ActionManager.new_action(start_pos,end_pos,action_type)
  
  return a
  
end
range_inside_action_type?(q_beg,q_end,action_type) click to toggle source

check if range defined by q_beg and q_end is inside some action of the type indicated by action_type

# File lib/seqtrimnext/classes/sequence_with_action.rb, line 318
def range_inside_action_type?(q_beg,q_end,action_type)
              res = false

              action_list = get_actions(action_type)
              
              action_list.each do |action|
                      
                      if action.contains_action?(q_beg+@insert_start,q_end+@insert_start,10)
                              res = true
                              break
                      end
              end
              
              return res

end
save_to_file() click to toggle source

Saves a sequence with its actions to a file

# File lib/seqtrimnext/classes/sequence_with_action.rb, line 418
def save_to_file
  File.open("results/#{seq_name}"+".txt", 'w') { |file|
   
    n=1
    
    @actions.each do |a|
      file.puts a.description
      n +=1   
    end
  } 
  
end
to_json() click to toggle source
# File lib/seqtrimnext/classes/sequence_with_action.rb, line 494
def to_json
   s={}
   s[:seq_name]=@seq_name
   s[:seq_fasta]=@seq_fasta_orig
   s[:seq_qual]=''
   if @seq_qual_orig
     s[:seq_qual]=@seq_qual_orig.join(' ')
   end
   s[:rejected]=@rejected
   

   s[:fasta_inserts]= get_inserts
   s[:qual_inserts]=get_qual_inserts.map { |e| e.join(' ') }
   s[:actions]=[]
   
   @actions.each { |a| s[:actions].push a.to_hash }
   # puts "YAML",s.to_yaml
   return JSON.pretty_generate(s)
end
to_text() click to toggle source

Prints a sequence with its actions to a file

# File lib/seqtrimnext/classes/sequence_with_action.rb, line 338
def to_text
  
    output_res=[]
    
    if @seq_rejected
      output_res<< "[#{@tuple_id},#{@order_in_tuple}] Sequence #{seq_name} had the next actions: ".bold.underline + " REJECTED:  #{@seq_rejected_by_message}".red    
      # puts  @seq_name.bold + bold + ' REJECTED BECAUSE ' +@seq_rejected_by_message.bold if @seq_rejected
    else
      output_res<< "[#{@tuple_id},#{@order_in_tuple}] Sequence #{seq_name} had the next actions: ".bold.underline  
      
    end
    
    n=1
    withMessage = ["ActionIsContaminated","ActionVectors","ActionBadAdapter","ActionLeftAdapter","ActionRightAdapter"]  
    color = red
    
    @actions.sort!{|e,f| e.start_pos<=>f.start_pos}.each do |a|     
      a_type=a.action_type
      color = a.apply_decoration(" EXAMPLE ") 
      color2 =a.apply_decoration(" #{a_type.center(8)} ") 
         
      reversed_str = ''    
      
      if a.reversed
        reversed_str = "   REVERSED  ".bold 
      end
      
      output_res<< " [#{n}] ".bold + color2+ " #{a.title} ".ljust(24).reset  +  " [ " + " #{a.start_pos+1}".center(6) + " , " + "#{a.end_pos+1}".center(6) + " ]" +  clear.to_s + "#{a.message}".rjust(a.message.size+8) + reversed_str
      
      n +=1   
    end
    
    pos = 0
    res = '' 
    
    @seq_fasta_orig.each_char do |c|
      
      @actions.each do |a|
        c= a.decorate(c,pos) 
        
      end 
      
      res += c
      
      pos += 1
    end       
            
    output_res<< res
    
    if SHOW_QUAL and @seq_qual_orig
       res = '' 
       pos=0               
       output_res<< ''
      @seq_fasta_orig.each_char do |c2|
        c=@seq_qual_orig[pos].to_s+' '
        @actions.each do |a|
          c= a.decorate(c,pos) 

        end 
        res += c
        pos += 1
      end
             
      output_res<< res
    end
    
    if SHOW_FINAL_INSERTS                      
       output_res<<  "INSERT ==>"+get_inserts.join("\nINSERT ==>")
       output_res<< "="*80
    end
    # puts  @seq_name.bold + bold + ' rejected because ' +@seq_rejected_by_message.bold if @seq_rejected

    return output_res
end
to_text_seq_fasta() click to toggle source
# File lib/seqtrimnext/classes/sequence_with_action.rb, line 413
def to_text_seq_fasta
   return " "*@insert_start +@seq_fasta
end