lib/mspire/ident/search.rb
module Mspire
module Ident
module SearchLike
attr_accessor :id
attr_accessor :peptide_hits
alias_method :hits, :peptide_hits
alias_method :hits=, :peptide_hits=
# returns an array of peptide_hits and protein_hits that are linked to
# one another. NOTE: this will update peptide and protein
# hits :proteins and :peptide_hits attributes respectively). Assumes that each search
# responds to :peptide_hits, each peptide responds to :proteins and each protein to
# :peptide_hits. Can be done on a single file to restore protein/peptide
# linkages to their original single-file state.
# Assumes the protein is initialized with (reference, peptide_ar)
#
# yields the protein that will become the template for a new protein
# and expects a new protein hit
#def merge!(ar_of_peptide_hit_arrays)
# all_peptide_hits = []
# reference_hash = {}
# ar_of_peptide_hit_arrays.each do |peptide_hits|
# all_peptide_hits.push(*peptide_hits)
# peptide_hits.each do |peptide|
# peptide.proteins.each do |protein|
# id = protein.id
# if reference_hash.key?(id)
# reference_hash[id].peptide_hits << peptide
# reference_hash[id]
# else
# reference_hash[id] = yield(protein, [peptide])
# end
# end
# end
# end
# [all_peptide_hits, reference_hash.values]
#end
end
class Search
include SearchLike
def initialize(id=nil, peptide_hits=[])
@id = id
@peptide_hits = peptide_hits
end
end
module SearchGroup
# an array of search objects
attr_accessor :searches
# the group's file extension (with no leading period)
def extension
'grp'
end
def search_class
Search
end
# a simple formatted file with paths to the search files
def to_paths(file)
IO.readlines(file).grep(/\w/).reject {|v| v =~ /^#/}.map {|v| v.chomp }
end
def from_file(file)
from_filenames(to_paths(file))
end
def from_filenames(filenames)
filenames.each do |file|
if !File.exist? file
message = "File: #{file} does not exist!\n"
message << "perhaps you need to modify the file with file paths"
abort message
end
@searches << search_class.new(file)
end
end
# takes an array of filenames or a single search filename (with
# extension defined by 'extendsion') or an array of objects passes any
# arguments to the initializer for each search
# the optional block yields the object for further processing
def initialize(arg=nil, opts={})
@peptide_hits = []
@reference_hash = {}
@searches = []
if arg
if arg.is_a?(String) && arg =~ /\.#{Regexp.escap(extension)}$/
from_file(arg)
elsif arg.is_a?(Array) && arg.first.is_a?(String)
from_filenames(arg)
elsif arg.is_a?(Array)
@searches = array
else
raise ArgumentError, "must be file, array of filenames, or array of objs"
end
@searches << search_class.new(file, opts)
end
yield(self) if block_given?
end
end
end
end