lib/mspire/ident/pepxml/search_hit.rb
require 'set'
require 'merge'
require 'nokogiri'
module Mspire ; end
module Mspire::Ident ; end
class Mspire::Ident::Pepxml
class Mspire::Ident::Pepxml::SearchHit
include Merge
DEFAULT_MEMBERS = [:hit_rank, :peptide, :peptide_prev_aa, :peptide_next_aa, :num_matched_ions, :tot_num_ions, :calc_neutral_pep_mass, :massdiff, :num_tol_term, :num_missed_cleavages, :is_rejected, :protein, :num_tot_proteins, :protein_desc, :calc_pI, :protein_mw, :modification_info, :search_scores, :spectrum_query]
Required = Set.new([:hit_rank, :peptide, :protein, :num_tot_proteins, :calc_neutral_pep_mass, :massdiff])
class << self
attr_writer :members
def members
@members || DEFAULT_MEMBERS
end
end
members.each {|memb| attr_accessor memb }
# rank of the peptide hit (required)
attr_accessor :hit_rank
# Peptide aminoacid sequence (with no indicated modifications) (required)
attr_accessor :peptide
# Aminoacid preceding peptide ('-' if none)
attr_accessor :peptide_prev_aa
# Aminoacid following peptide (- if none)
attr_accessor :peptide_next_aa
# Number of peptide fragment ions found in spectrum (Integer)
attr_accessor :num_matched_ions
# Number of peptide fragment ions predicted for peptide (Integer)
attr_accessor :tot_num_ions
# (required)
attr_accessor :calc_neutral_pep_mass
# Mass(precursor ion) - Mass(peptide) (required)
attr_accessor :massdiff
# Number of peptide termini consistent with cleavage by sample enzyme
attr_accessor :num_tol_term
# Number of sample enzyme cleavage sites internal to peptide<
attr_accessor :num_missed_cleavages
# Potential use in future for user manual validation (true/false)
# by default, this will be set to false
# (the xml is expressed as a 0 or 1)
attr_accessor :is_rejected
# a protein identifier string (required)
attr_accessor :protein
# Number of unique proteins in search database containing peptide
# (required)
attr_accessor :num_tot_proteins
# Extracted from search database
attr_accessor :protein_desc
attr_accessor :calc_pI
attr_accessor :protein_mw
# a ModificationInfo object
attr_accessor :modification_info
# a Hash with keys (the score type) and values
# (to_xml calls each_pair to generate the xml, so a Struct would also
# work)
attr_accessor :search_scores
# a link back to the spectrum_query object
attr_accessor :spectrum_query
Non_standard_amino_acid_char_re = %r{[^A-Z\.\-]}
alias_method :aaseq, :peptide
alias_method :aaseq=, :peptide=
# takes either a hash or an ordered list of values to set.
# yeilds an empty search_scores hash if given a block.
# mind that you set the ModificationInfo object as needed.
def initialize(*args, &block)
@search_scores = {}
if args.first.is_a?(Hash)
merge!(args.first)
else
self.class.members.zip(args) do |k,v|
send("#{k}=", v)
end
end
block.call(@search_scores) if block
end
def members
self.class.members
end
def to_xml(builder=nil)
xmlb = builder || Nokogiri::XML::Builder.new
attrs = members[0,14].map {|k| v=send(k) ; [k, v] if v }.compact
hash_attrs = Hash[attrs]
hash_attrs[:massdiff] = hash_attrs[:massdiff].to_plus_minus_string
xmlb.search_hit(hash_attrs) do |xmlb|
@modification_info.to_xml(xmlb) if @modification_info
@search_scores.each_pair {|k,v| xmlb.search_score(:name => k, :value => v) }
end
builder || xmlb.doc.root.to_xml
end
def from_pepxml_node(node)
node.attributes
self[0] = node['hit_rank'].to_i
self[1] = node['peptide']
self[2] = node['peptide_prev_aa']
self[3] = node['peptide_next_aa']
self[4] = node['protein'] ## will this be the string?? (yes, for now)
self[5] = node['num_tot_proteins'].to_i
self[6] = node['num_matched_ions'].to_i
self[7] = node['tot_num_ions'].to_i
self[8] = node['calc_neutral_pep_mass'].to_f
self[9] = node['massdiff'].to_f
self[10] = node['num_tol_term'].to_i
self[11] = node['num_missed_cleavages'].to_i
self[12] = node['is_rejected'].to_i
self
end
Simple = Struct.new(:id, :search, :aaseq, :charge, :search_scores, :analysis_results)
end
end