Class: Diadem::Calculator

Inherits:
Object
  • Object
show all
Defined in:
lib/diadem/calculator.rb

Defined Under Namespace

Classes: Info, Modification, Polynomial

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(element = :H, mass_number = 2, penetration_table = Enrichment::AA_TABLE, isotope_table = Mspire::Isotope::BY_ELEMENT, round = false) ⇒ Calculator

returns spectra objects. The isotope_table handed in will not be altered



83
84
85
86
87
# File 'lib/diadem/calculator.rb', line 83

def initialize(element=:H, mass_number=2, penetration_table=Enrichment::AA_TABLE, isotope_table=Mspire::Isotope::BY_ELEMENT, round=false)
  @round = round
  @penetration_table, @element, @mass_number = penetration_table, element, mass_number
  @isotope_table = dup_isotope_table(isotope_table)
end

Class Method Details

.distributions_to_polynomials(enrichments, distributions, num = 5, degree = 2) ⇒ Object

related intensities



75
76
77
78
79
# File 'lib/diadem/calculator.rb', line 75

def distributions_to_polynomials(enrichments, distributions, num=5, degree=2)
  distributions.map {|dist| dist.intensities[0,num] }.transpose.each_with_index.map do |ar, m|
    polyfit(enrichments, ar, degree)
  end
end

.enrich_isotope(isotopes, mass_number, fraction = 1.0) ⇒ Object

returns new isotopes, properly enriched.



65
66
67
68
69
70
71
72
# File 'lib/diadem/calculator.rb', line 65

def enrich_isotope(isotopes, mass_number, fraction=1.0)
  new_isotopes = isotopes.map(&:dup)
  leftover_fraction = 1.0 - fraction
  new_isotopes.each {|isot| isot.relative_abundance *= leftover_fraction }
  isot_to_enrich = new_isotopes.find {|isot| isot.mass_number == mass_number }
  isot_to_enrich.relative_abundance += fraction
  new_isotopes
end

.polyfit(x, y, degree) ⇒ Object

from rosettacode.org/wiki/Polynomial_regression#Ruby. Returns a Polynomial object



55
56
57
58
59
60
61
62
# File 'lib/diadem/calculator.rb', line 55

def polyfit(x, y, degree)
  x_data = x.map {|xi| (0..degree).map { |pow| (xi**pow).to_f } }

  mx = Matrix[*x_data]
  my = Matrix.column_vector(y)

  Diadem::Calculator::Polynomial.new( ((mx.t * mx).inv * mx.t * my).transpose.to_a[0] )
end

Instance Method Details

#calculate_formula(aaseq_with_mods, mods) ⇒ Object

returns [formula_adjusted_for_mods, aaseq_with_no_mods]



105
106
107
108
109
110
111
112
113
114
115
# File 'lib/diadem/calculator.rb', line 105

def calculate_formula(aaseq_with_mods, mods)
  mods.group_by(&:char).each do |modchar, mod|
    aaseq_with_mods.each_char do |char|
      if char == modchar
      end
    end
  end


  Mspire::MolecularFormula.from_aaseq(aaseq)
end

#calculate_isotope_distributions(aaseq, enrichments, normalize_type: :total, mods: Diadem::Calculator::Modification::DEFAULT_MODS) ⇒ Object

Returns [distributions, info]. Interprets lowercase m as singly oxidized methionine.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/diadem/calculator.rb', line 118

def calculate_isotope_distributions(aaseq, enrichments, normalize_type: :total, mods: Diadem::Calculator::Modification::DEFAULT_MODS)
  @info = Info.new
  pct_cutoff = nil

  mf = Mspire::MolecularFormula
  aaseq_up = aaseq
  subtract_formula = mf.new
  add_formula = mf.new
  matched_mods = []
  mods.each do |mod|
    delta_formula = mod.gain ? add_formula : subtract_formula
    aaseq_up = aaseq_up.gsub(mod.match) do |match|
      matched_mods << [match, mod]
      delta_formula.add!(mod.diff_formula)
      mod.match_block.call(match)
    end
  end
  @info.mods = matched_mods

  formula = mf.from_aaseq(aaseq_up)
  formula += add_formula
  formula -= subtract_formula
  @info.formula = formula

  max_pen_frac = max_penetration_fraction(aaseq_up, formula)

  orig_isotopes = @isotope_table[@element]

  distributions = enrichments.map do |enrich_frac|
    effective_fraction = max_pen_frac * enrich_frac
    @isotope_table[@element] = Diadem::Calculator.enrich_isotope(orig_isotopes, @mass_number, effective_fraction)
    spectrum = formula.isotope_distribution_spectrum(normalize_type, pct_cutoff, @isotope_table)
    @isotope_table[@element] = orig_isotopes
    @info.masses = spectrum.mzs unless @info.masses
    Diadem::Distribution.new( spectrum.intensities )
  end
  [distributions, @info]
end

#dup_isotope_table(table) ⇒ Object



89
90
91
92
93
# File 'lib/diadem/calculator.rb', line 89

def dup_isotope_table(table)
  table.each.with_object({}) do |(key,val), new_table|
    new_table[key] = val.map {|obj| obj.dup }
  end
end

#max_penetration_fraction(aaseq, formula) ⇒ Object



95
96
97
98
99
100
101
102
# File 'lib/diadem/calculator.rb', line 95

def max_penetration_fraction(aaseq, formula)
  penetration = aaseq.each_char.inject(0.0) do |sum, aa|
    sum + ( @penetration_table[aa] || 0.0 )
  end
  penetration = penetration.round if @round
  @info.penetration = penetration
  penetration.to_f / formula[@element]
end