Class: RGFA::Line::Link

Inherits:
RGFA::Line show all
Defined in:
lib/rgfa/line/link.rb

Overview

A link connects two segments, or a segment to itself.

Constant Summary collapse

RECORD_TYPE =
:L
REQFIELDS =
[:from, :from_orient, :to, :to_orient, :overlap]
PREDEFINED_OPTFIELDS =
[:MQ, :NM, :RC, :FC, :KC]
DATATYPE =
{
   :from => :lbl,
   :from_orient => :orn,
   :to => :lbl,
   :to_orient => :orn,
   :overlap => :cig,
   :MQ => :i,
   :NM => :i,
   :RC => :i,
   :FC => :i,
   :KC => :i,
}

Constants inherited from RGFA::Line

DELAYED_PARSING_DATATYPES, DIRECTION, FIELD_DATATYPE, OPTFIELD_DATATYPE, ORIENTATION, RECORD_TYPES, RECORD_TYPE_LABELS, REQFIELD_DATATYPE, SEPARATOR

Instance Method Summary collapse

Methods inherited from RGFA::Line

#==, #clone, #delete, #field_to_s, #fieldnames, #get, #get!, #get_datatype, #initialize, #method_missing, #optional_fieldnames, #real!, #record_type, #required_fieldnames, #respond_to?, #set, #set_datatype, subclass, #tags, #to_a, #to_rgfa_line, #to_s, #validate!, #validate_field!, #virtual?

Constructor Details

This class inherits a constructor from RGFA::Line

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class RGFA::Line

Instance Method Details

#canonical?Boolean

Returns true if the link is canonical, false otherwise

A link if canonical if:

  • from != to and from < to (lexicographically); or

  • from == to and at least one of from_orient or to_orient is +

Details

In the special case in which from == to (== s) we have the following equivalences:

s + s + == s - s -
s - s - == s + s + (same as previous case)
s + s - == s + s - (equivalent to itself)
s - s + == s - s + (equivalent to itself)

Considering the values on the left, the first one can be taken as canonical, the second not, because it can be transformed in the first one; the other two values are canonical, as they are only equivalent to themselves.

Returns:

  • (Boolean)


140
141
142
143
144
145
146
147
148
# File 'lib/rgfa/line/link.rb', line 140

def canonical?
  if from_name < to_name
    return true
  elsif from_name > to_name
    return false
  else
    return [from_orient, to_orient].include?(:+)
  end
end

#canonicize!RGFA::Line::Link

Note:

The path references are not corrected by this method; therefore the method shall be used before the link is embedded in a graph.

Returns the unchanged link if the link is canonical, otherwise complements the link and returns it.

Returns:



157
158
159
# File 'lib/rgfa/line/link.rb', line 157

def canonicize!
  complement! if !canonical?
end

#circular?Boolean

Returns is the from and to segments are equal.

Returns:

  • (Boolean)

    is the from and to segments are equal



43
44
45
# File 'lib/rgfa/line/link.rb', line 43

def circular?
  from.to_sym == to.to_sym
end

#circular_same_end?Boolean

Returns is the from and to segments are equal.

Returns:

  • (Boolean)

    is the from and to segments are equal



48
49
50
# File 'lib/rgfa/line/link.rb', line 48

def circular_same_end?
  from_end == to_end
end

#compatible?(other_oriented_from, other_oriented_to, other_overlap = [], equivalent = true) ⇒ Boolean

Compares a link and optionally the complement link, with two oriented_segments and optionally an overlap.

Parameters:

Returns:

  • (Boolean)

    does the link or, if equivalent, the complement link go from the first oriented segment to the second with an overlap equal to the provided one (if not empty)?



326
327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/rgfa/line/link.rb', line 326

def compatible?(other_oriented_from, other_oriented_to, other_overlap = [],
                equivalent = true)
  other_overlap = other_overlap.to_cigar
  is_direct = compatible_direct?(other_oriented_from, other_oriented_to,
                                 other_overlap)
  if is_direct
    return true
  elsif equivalent
    return compatible_complement?(other_oriented_from, other_oriented_to,
                        other_overlap)
  else
    return false
  end
end

#compatible_complement?(other_oriented_from, other_oriented_to, other_overlap = []) ⇒ Boolean

Compares the complement link with two oriented segments and optionally an overlap.

Parameters:

Returns:

  • (Boolean)

    does the complement link go from the first oriented segment to the second with an overlap equal to the provided one (if not empty)?



363
364
365
366
367
368
# File 'lib/rgfa/line/link.rb', line 363

def compatible_complement?(other_oriented_from, other_oriented_to,
                        other_overlap = [])
  (oriented_to == other_oriented_from.invert_orient and
   oriented_from == other_oriented_to.invert_orient) and
   (overlap.empty? or other_overlap.empty? or (overlap == other_overlap))
end

#compatible_direct?(other_oriented_from, other_oriented_to, other_overlap = []) ⇒ Boolean

Compares a link with two oriented segments and optionally an overlap.

Parameters:

Returns:

  • (Boolean)

    does the link go from the first oriented segment to the second with an overlap equal to the provided one (if not empty)?



348
349
350
351
352
353
# File 'lib/rgfa/line/link.rb', line 348

def compatible_direct?(other_oriented_from, other_oriented_to,
                       other_overlap = [])
  (oriented_from == other_oriented_from and
   oriented_to == other_oriented_to) and
   (overlap.empty? or other_overlap.empty? or (overlap == other_overlap))
end

#complementRGFA::Line::Link

Note:

The path references are not copied to the complement link.

Note:

This method shall be overridden if custom optional fields are defined, which have a “complementation” operation which determines their value in the equivalent complement link.

Creates the equivalent link with from/to inverted.

The CIGAR operations (order/type) are inverted as well. Optional fields are left unchanged.

Returns:



173
174
175
176
177
178
179
180
181
# File 'lib/rgfa/line/link.rb', line 173

def complement
  l = self.clone
  l.from = to
  l.from_orient = (to_orient == :+ ? :- : :+)
  l.to = from
  l.to_orient = (from_orient == :+ ? :- : :+)
  l.overlap = complement_overlap
  l
end

#complement!RGFA::Line::Link

Note:

The path references are not complemented by this method; therefore the method shall be used before the link is embedded in a graph.

Note:

This method shall be overridden if custom optional fields are defined, which have a “complementation” operation which determines their value in the complement link.

Complements the link inplace, i.e. sets:

from = to
from_orient = other_orient(to_orient)
to = from
to_orient = other_orient(from_orient)
overlap = complement_overlap.

The optional fields are left unchanged.

Returns:



200
201
202
203
204
205
206
207
208
209
# File 'lib/rgfa/line/link.rb', line 200

def complement!
  tmp = self.from
  self.from = self.to
  self.to = tmp
  tmp = self.from_orient
  self.from_orient = (self.to_orient == :+) ? :- : :+
  self.to_orient = (tmp == :+) ? :- : :+
  self.overlap = self.complement_overlap
  return self
end

#complement?(other) ⇒ Boolean

Compares the link to the complement of another link and determine their equivalence. Thereby, optional fields are not considered.

Parameters:

Returns:

  • (Boolean)

    are self and the complement of other equivalent?

See Also:



302
303
304
305
306
# File 'lib/rgfa/line/link.rb', line 302

def complement?(other)
  (from_end == other.to_end and
    to_end == other.from_end and
    overlap == other.complement_overlap)
end

#complement_overlapRGFA::CIGAR

Compute the overlap when the strand of both sequences is inverted.

Returns:



229
230
231
# File 'lib/rgfa/line/link.rb', line 229

def complement_overlap
  self.overlap.to_cigar.complement
end

#eql?(other) ⇒ Boolean

Note:

Inverting the strand of both links and reversing the CIGAR operations (order/type), one obtains an equivalent complement link.

Compares two links and determine their equivalence. Thereby, optional fields are not considered.

Parameters:

Returns:

  • (Boolean)

    are self and other equivalent?

See Also:



246
247
248
# File 'lib/rgfa/line/link.rb', line 246

def eql?(other)
  same?(other) or complement?(other)
end

#eql_optional?(other) ⇒ Boolean

Note:

This method shall be overridden if custom optional fields are defined, which have a “complementation” operation which determines their value in the equivalent but complement link.

Compares the optional fields of two links.

Parameters:

Returns:

  • (Boolean)

    are self and other equivalent?

See Also:



259
260
261
262
# File 'lib/rgfa/line/link.rb', line 259

def eql_optional?(other)
  (self.optional_fieldnames.sort == other.optional_fieldnames.sort) and
    optional_fieldnames.each {|fn| self.get(fn) == other.get(fn)}
end

#from_endRGFA::SegmentEnd

Returns the segment end represented by the from/from_orient fields.

Returns:

  • (RGFA::SegmentEnd)

    the segment end represented by the from/from_orient fields



66
67
68
# File 'lib/rgfa/line/link.rb', line 66

def from_end
  [from, from_orient == :+ ? :E : :B].to_segment_end
end

#from_nameSymbol

The from segment name, in both cases where from is a segment name (Symbol) or a segment (RGFA::Line::Segment)

Returns:



104
105
106
# File 'lib/rgfa/line/link.rb', line 104

def from_name
  from.to_sym
end

#hashObject

Computes an hash for including a link in an Hash tables, so that the hash of a link and its complement is the same. Thereby, optional fields are not considered.

See Also:



312
313
314
# File 'lib/rgfa/line/link.rb', line 312

def hash
  from_end.hash + to_end.hash + overlap.hash + complement_overlap.to_s.hash
end

#oriented_fromRGFA::OrientedSegment

Returns the oriented segment represented by the from/from_orient fields.

Returns:



54
55
56
# File 'lib/rgfa/line/link.rb', line 54

def oriented_from
  [from, from_orient].to_oriented_segment
end

#oriented_toRGFA::OrientedSegment

Returns the oriented segment represented by the to/to_orient fields.

Returns:



60
61
62
# File 'lib/rgfa/line/link.rb', line 60

def oriented_to
  [to, to_orient].to_oriented_segment
end

#other(segment) ⇒ Symbol

The other segment of a link

Parameters:

Returns:

  • (Symbol)

    the name of the other segment of the link if circular, then segment

Raises:



29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/rgfa/line/link.rb', line 29

def other(segment)
  segment_name =
    (segment.kind_of?(RGFA::Line::Segment) ? segment.name : segment.to_sym)
  if segment_name == from.to_sym
    to
  elsif segment_name == to.to_sym
    from
  else
    raise RGFA::LineMissingError,
      "Link #{self} does not involve segment #{segment_name}"
  end
end

#other_end(segment_end) ⇒ RGFA::SegmentEnd

Returns the other segment end.

Parameters:

Returns:

Raises:

  • (ArgumentError)

    if segment_end is not a valid segment end representation

  • (RuntimeError)

    if segment_end is not a segment end of the link



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/rgfa/line/link.rb', line 89

def other_end(segment_end)
  segment_end = segment_end.to_segment_end
  if (from_end == segment_end)
    return to_end
  elsif (to_end == segment_end)
    return from_end
  else
    raise "Segment end '#{segment_end.inspect}' not found\n"+
          "(from=#{from_end.inspect};to=#{to_end.inspect})"
  end
end

#pathsArray<Array<(RGFA::Line::Path, Boolean)>>

Paths for which the link is required.

The return value is an empty array if the link is not embedded in a graph.

Otherwise, an array of tuples path/boolean is returned. The boolean value tells if the link is used (true) or its complement (false) in the path.

Returns:



221
222
223
224
# File 'lib/rgfa/line/link.rb', line 221

def paths
  @paths ||= []
  @paths
end

#same?(other) ⇒ Boolean

Compares two links and determine their equivalence. Thereby, optional fields are not considered.

Parameters:

Returns:

  • (Boolean)

    are self and other equivalent?

See Also:



287
288
289
290
291
# File 'lib/rgfa/line/link.rb', line 287

def same?(other)
  (from_end == other.from_end and
    to_end == other.to_end and
    overlap == other.overlap)
end

#segment_ends_sObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Signature of the segment ends, for debugging



78
79
80
# File 'lib/rgfa/line/link.rb', line 78

def segment_ends_s
  [from_end.to_s, to_end.to_s].join("---")
end

#to_endRGFA::SegmentEnd

Returns the segment end represented by the to/to_orient fields.

Returns:



72
73
74
# File 'lib/rgfa/line/link.rb', line 72

def to_end
  [to, to_orient == :+ ? :B : :E].to_segment_end
end

#to_nameSymbol

The to segment name, in both cases where to is a segment name (Symbol) or a segment (RGFA::Line::Segment)

Returns:



111
112
113
# File 'lib/rgfa/line/link.rb', line 111

def to_name
  to.to_sym
end