<commit_before>require 'molecules/empirical_formula'

module Molecules
  module Calc
    
    # :manifest: a mass calculator
    # Calculates the mass of a molecule or empirical formula.  The
    # options can be used to alter the output (precision, mass
    # calculation method etc.)
    #
    # You may enter compound formulae, as well as a list of formulae.
    #
    #   % tap -- molecules/calc/mass H2O
    #     I[17:09:00]      18.0105646863 H2O
    #
    #   % tap -- molecules/calc/mass 'C3H5NO + H2O' C50H73N15O11 --precision=2
    #     I[17:08:21]              89.05 C3H5NO + H2O
    #     I[17:08:21]            1059.56 C50H73N15O11
    #
    class Mass < Tap::Task
    
      config :type, :monoisotopic
      config :precision, nil
      #config :units, :Da

      def process(*formulae)
        formulae.collect do |formula|
          mass = EmpiricalFormula.mass(formula) do |element|
            case type
            when :monoisotopic then element.mass
            when :average then element.std_atomic_weight.value
            end
          end
          
          mass = (precision == nil ? mass : Utils.round(mass, precision))
          
          log mass, formula
          mass
        end
      end
      
    end
  end
end<commit_msg>added unit reporting and conversion to calc/mass<commit_after>require 'molecules/empirical_formula'

# patch for ruby units
class Unit < Numeric
  UNIT_DEFINITIONS['<AMU>'] = [%w{u AMU amu}, 1/6.0221415e26, :mass, %w{<kilogram>}]
  UNIT_DEFINITIONS['<dalton>'] = [%w{Da Dalton Daltons dalton daltons}, 1/6.0221415e26, :mass, %w{<kilogram>}]
end
Unit.setup

module Molecules
  module Calc
    
    # :manifest: a mass calculator
    # Calculates the mass of a molecule or empirical formula.  The
    # options can be used to alter the output (precision, mass
    # calculation method etc.)
    #
    # You may enter compound formulae, as well as a list of formulae.
    #
    #   % tap -- molecules/calc/mass H2O
    #     I[17:09:00]      18.0105646863 H2O
    #
    #   % tap -- molecules/calc/mass 'C3H5NO + H2O' C50H73N15O11 --precision=2
    #     I[17:08:21]              89.05 C3H5NO + H2O
    #     I[17:08:21]            1059.56 C50H73N15O11
    #
    class Mass < Tap::Task
    
      config :type, :monoisotopic    # the mass type calculated
      config :precision, nil              # the precision of the mass
      config :units, "Da"                 # the mass unit reported

      def process(*formulae)
        formulae.collect do |formula|
          mass = EmpiricalFormula.mass(formula) do |element|
            case type
            when :monoisotopic then element.mass
            when :average then element.std_atomic_weight.value
            else raise "unknown mass type: #{type}"
            end
          end
          
          mass = Unit.new(mass, "Da").convert_to(units)
          unless precision == nil
            mass = Unit.new( Utils.round(mass.scalar, precision), units) 
          end
          
          log mass, formula
          mass
        end
      end
      
    end
  end
end
{'fraction_non_alphanumeric': 0.08875931324910917, 'fraction_numerical': 0.049238743116294136, 'mean_word_length': 1.8779123951537744, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3189753', 'n_tokens_mistral': 1075, 'n_tokens_neox': 962, 'n_words': 279}