1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
require_relative "error"
#
# Methods for the RGFA class, which allow to handle paths in the graph.
#
module RGFA::Paths
def add_path(gfa_line)
gfa_line = gfa_line.to_rgfa_line(validate: @validate)
if @segments.has_key?(gfa_line.path_name)
raise RGFA::DuplicatedLabelError,
"Error when adding line: #{gfa_line}\n"+
"a segment already exists with the name: #{gfa_line.path_name}\n"+
"Segment: #{@segments[gfa_line.path_name]}"
elsif @paths.has_key?(gfa_line.path_name)
raise RGFA::DuplicatedLabelError,
"Error when adding line: #{gfa_line}\n"+
"a path already exists with the name: #{gfa_line.path_name}\n"+
"Path: #{@paths[gfa_line.path_name]}"
else
@paths[gfa_line.path_name] = gfa_line
gfa_line.required_links.each do |from,to,cigar|
l = nil
if segment(from.segment) and segment(to.segment)
l = link_from_to(from, to, cigar)
end
if l.nil?
v = RGFA::Line::Link.new({:from => from.segment,
:from_orient => from.orient,
:to => to.segment,
:to_orient => to.orient,
:overlap => cigar},
virtual: true)
if @segments_first_order
raise RGFA::LineMissingError, "Path: #{gfa_line}\n"+
"requires a non-existing link:\n"+
"#{v}"
end
add_link(v)
l = v
end
direct = l.compatible_direct?(from, to, cigar)
gfa_line.links << [l, direct]
l.paths << [gfa_line, direct]
end
gfa_line.segment_names.each do |sn_with_o|
sn_with_o[0] = segment(sn_with_o[0])
sn_with_o[0].paths[sn_with_o[1]] << gfa_line
end
end
end
protected :add_path
# Delete a path from the RGFA graph
# @return [RGFA] self
# @param pt [String, RGFA::Line::Path] path name or instance
def delete_path(pt)
pt = path!(pt)
pt.segment_names.each {|sn, o| segment!(sn).paths[o].delete(pt)}
pt.links.each {|l, dir| l.paths.delete([pt, dir])}
@paths.delete(pt.path_name)
return self
end
# All path lines of the graph
# @return [Array<RGFA::Line::Path>]
def paths
@paths.values
end
# @!macro [new] path
# Searches the path with name equal to +pt+.
# @param pt [String, RGFA::Line::Path] a path or path name
# @return [RGFA::Line::Path] if a path is found
# @return [nil] if no such path exists in the RGFA instance
#
def path(pt)
return pt if pt.kind_of?(RGFA::Line)
@paths[pt.to_sym]
end
# @!macro path
# @raise [RGFA::LineMissingError] if no such path exists in the RGFA instance
def path!(pt)
pt = path(pt)
raise RGFA::LineMissingError, "No path has name #{pt}" if pt.nil?
pt
end
# @return [Array<RGFA::Line::Path>] paths whose +segment_names+ include the
# specified segment.
# @!macro [new] segment_or_name
# @param s [RGFA::Line::Segment, Symbol] a segment instance or name
def paths_with(s)
segment!(s).all_paths
end
end
|