docs: def calcPeptideMass(peptide, **kwargs):
      """Calculate the mass of a peptide.
  
      :param aaMass: A dictionary with the monoisotopic masses of amino acid
          residues, by default :attr:`maspy.constants.aaMass`
      :param aaModMass: A dictionary with the monoisotopic mass changes of
          modications, by default :attr:`maspy.constants.aaModMass`
      :param elementMass: A dictionary with the masses of chemical elements, by
          default ``pyteomics.mass.nist_mass``
      :param peptide: peptide sequence, modifications have to be written in the
          format "[modificationId]" and "modificationId" has to be present in
          :attr:`maspy.constants.aaModMass`
  
      #TODO: change to a more efficient way of calculating the modified mass, by
      first extracting all present modifications and then looking up their masses.
      """
      aaMass = kwargs.get('aaMass', maspy.constants.aaMass)
      aaModMass = kwargs.get('aaModMass', maspy.constants.aaModMass)
      elementMass = kwargs.get('elementMass', pyteomics.mass.nist_mass)
  
      addModMass = float()
      unmodPeptide = peptide
      for modId, modMass in viewitems(aaModMass):
          modSymbol = '[' + modId + ']'
          numMod = peptide.count(modSymbol)
          if numMod > 0:
              unmodPeptide = unmodPeptide.replace(modSymbol, '')
              addModMass += modMass * numMod
  
      if unmodPeptide.find('[') != -1:
          print(unmodPeptide)
          raise Exception('The peptide contains modification, ' +
                          'not present in maspy.constants.aaModMass'
                          )
  
      unmodPeptideMass = sum(aaMass[i] for i in unmodPeptide)
      unmodPeptideMass += elementMass['H'][0][0]*2 + elementMass['O'][0][0]
      modPeptideMass = unmodPeptideMass + addModMass
      return modPeptideMass