def deconvolute(peaklist, massType=0): """Recalculate peaklist to singly charged. peaklist (mspy.peaklist) - peak list to deconvolute massType (0 or 1) - mass type used for m/z re-calculation, 0 = monoisotopic, 1 = average """ # recalculate peaks buff = [] for peak in copy.deepcopy(peaklist): CHECK_FORCE_QUIT() # uncharged peak if not peak.charge: continue # charge is correct elif abs(peak.charge) == 1: buff.append(peak) # recalculate peak else: # set fwhm if peak.fwhm: newFwhm = abs(peak.fwhm*peak.charge) peak.setfwhm(newFwhm) # set m/z and charge if peak.charge < 0: newMz = mod_basics.mz(mass=peak.mz, charge=-1, currentCharge=peak.charge, massType=massType) peak.setmz(newMz) peak.setcharge(-1) else: newMz = mod_basics.mz(mass=peak.mz, charge=1, currentCharge=peak.charge, massType=massType) peak.setmz(newMz) peak.setcharge(1) # store peak buff.append(peak) # remove baseline if buff: for peak in buff: peak.setsn(None) peak.setai(peak.intensity) peak.setbase(0.) # update peaklist peaklist = obj_peaklist.peaklist(buff) return peaklist
def mz(self, charge, agentFormula='H', agentCharge=1): """Get ion m/z""" return mod_basics.mz(mass=self.mass(), charge=charge, agentFormula=agentFormula, agentCharge=agentCharge)
def averagine(mz, charge=0, composition=AVERAGE_AMINO): """Calculate average formula for given mass and building block composition. mz (float) - peak m/z charge (int) - peak charge composition (dict) - building block composition """ # get average mass of block blockMass = 0. for element in composition: blockMass += blocks.elements[element].mass[1] * composition[element] # get block count neutralMass = mod_basics.mz(mz, charge=0, currentCharge=charge, massType=1) count = max(1, neutralMass / blockMass) # make formula formula = '' for element in composition: formula += '%s%d' % (element, int(composition[element]*count)) formula = obj_compound.compound(formula) # add some hydrogens to reach the mass hydrogens = int(round((neutralMass - formula.mass(1)) / blocks.elements['H'].mass[1])) hydrogens = max(hydrogens, -1*formula.count('H')) formula += 'H%d' % hydrogens return formula
def mz(self, charge, agentFormula='H', agentCharge=1): """Get ion m/z.""" return mod_basics.mz(self.mass(), charge = charge, agentFormula = agentFormula, agentCharge = agentCharge )
def mass(self): """Get neutral peak mass.""" # check charge if self.charge == None: return None # check mass buffer if self._mass != None: return self._mass # calculate neutral mass self._mass = mod_basics.mz(self.mz, 0, self.charge, agentFormula='H', agentCharge=1) return self._mass
def formulator(mz, charge=0, tolerance=1., units='ppm', composition={}, agentFormula='H', agentCharge=1, limit=1000): """Generate formulae for given mass, tolerance and composition limits. mz (float) - searched m/z value charge (int) - current charge tolerance (float) - mass tolerance units (ppm or Da) - mass tolerance units composition (dict of 'element':[min count, max count]) - composition limits agentFormula (str) - charging agent formula agentCharge (int) - charging agent unit charge limit (int) - maximum formulae allowed to be calculated """ # get neutral mass if charge != 0 and agentFormula: mass = mod_basics.mz(mz, 0, currentCharge=charge, agentFormula=agentFormula, agentCharge=agentCharge) else: mass = mz # check neutral mass if mass <= 0: return [] # get mass limits if units == 'ppm': loMass = mass - (mass / 1e6) * tolerance hiMass = mass + (mass / 1e6) * tolerance elif charge != 0: loMass = mass - abs(charge) * tolerance hiMass = mass + abs(charge) * tolerance else: loMass = mass - tolerance hiMass = mass + tolerance # sort elements by masses to speed up processing buff = [] for el in composition: elMass = obj_compound.compound(el).mass(0) buff.append([elMass, el]) buff.sort(reverse=True) # compile elements and counts elementMasses = [] elements = [] minComposition = [] maxComposition = [] for el in buff: elementMasses.append(el[0]) elements.append(el[1]) minComposition.append(composition[el[1]][0]) maxComposition.append(composition[el[1]][1]) # check max composition for i in range(len(maxComposition)): maxComposition[i] = min(maxComposition[i], int(hiMass / elementMasses[i])) # generate compositions formulae = [] comps = _compositions(minComposition, maxComposition, elementMasses, loMass, hiMass, limit) for comp in comps: CHECK_FORCE_QUIT() formula = '' for i in range(len(comp)): formula += '%s%d' % (elements[i], comp[i]) formulae.append(formula) return formulae
def deisotope(peaklist, maxCharge=1, mzTolerance=0.15, intTolerance=0.5, isotopeShift=0.0): """Isotopes determination and calculation of peaks charge. peaklist (mspy.peaklist) - peaklist to process maxCharge (float) - max charge to be searched mzTolerance (float) - absolute m/z tolerance for isotopes distance intTolerance (float) - relative intensity tolerance for isotopes and model (in %/100) isotopeShift (float) - isotope distance correction (neutral mass) (for HDX etc.) """ # check peaklist if not isinstance(peaklist, obj_peaklist.peaklist): raise TypeError, "Peak list must be mspy.peaklist object!" # clear previous results for peak in peaklist: peak.setcharge(None) peak.setisotope(None) # get charges if maxCharge < 0: charges = [-x for x in range(1, abs(maxCharge)+1)] else: charges = [x for x in range(1, maxCharge+1)] charges.reverse() # walk in a peaklist maxIndex = len(peaklist) for x, parent in enumerate(peaklist): CHECK_FORCE_QUIT() # skip assigned peaks if parent.isotope != None: continue # try all charge states for z in charges: cluster = [parent] # search for next isotope within m/z tolerance difference = (ISOTOPE_DISTANCE + isotopeShift)/abs(z) y = 1 while x+y < maxIndex: mzError = (peaklist[x+y].mz - cluster[-1].mz - difference) if abs(mzError) <= mzTolerance: cluster.append(peaklist[x+y]) elif mzError > mzTolerance: break y += 1 # no isotope found if len(cluster) == 1: continue # get theoretical isotopic pattern mass = min(15000, int( mod_basics.mz( parent.mz, 0, z))) / 200 pattern = patternLookupTable[mass] # check minimal number of isotopes in the cluster limit = 0 for p in pattern: if p >= 0.33: limit += 1 if len(cluster) < limit and abs(z) > 1: continue # check peak intensities in cluster valid = True isotope = 1 limit = min(len(pattern), len(cluster)) while (isotope < limit): # calc theoretical intensity from previous peak and current error intTheoretical = (cluster[isotope-1].intensity / pattern[isotope-1]) * pattern[isotope] intError = cluster[isotope].intensity - intTheoretical # intensity in tolerance if abs(intError) <= (intTheoretical * intTolerance): cluster[isotope].setisotope(isotope) cluster[isotope].setcharge(z) # intensity is higher (overlap) elif intError > 0: pass # intensity is lower and first isotope is checked (nonsense) elif (intError < 0 and isotope == 1): valid = False break # try next peak isotope += 1 # cluster is OK, set parent peak and skip other charges if valid: parent.setisotope(0) parent.setcharge(z) break
def formulator(mz, charge=0, tolerance=1., units='ppm', composition={}, agentFormula='H', agentCharge=1, limit=1000): """Generate formulae for given mass, tolerance and composition limits. mz (float) - searched m/z value charge (int) - current charge tolerance (float) - mass tolerance units (ppm or Da) - mass tolerance units composition (dict of 'element':[min count, max count]) - composition limits agentFormula (str) - charging agent formula agentCharge (int) - charging agent unit charge limit (int) - maximum formulae allowed to be calculated """ # get neutral mass if charge != 0 and agentFormula: mass = mod_basics.mz(mz, 0, currentCharge=charge, agentFormula=agentFormula, agentCharge=agentCharge) else: mass = mz # check neutral mass if mass <= 0: return [] # get mass limits if units == 'ppm': loMass = mass - (mass/1e6) * tolerance hiMass = mass + (mass/1e6) * tolerance elif charge != 0: loMass = mass - abs(charge)*tolerance hiMass = mass + abs(charge)*tolerance else: loMass = mass - tolerance hiMass = mass + tolerance # sort elements by masses to speed up processing buff = [] for el in composition: elMass = obj_compound.compound(el).mass(0) buff.append([elMass, el]) buff.sort(reverse=True) # compile elements and counts elementMasses = [] elements = [] minComposition = [] maxComposition = [] for el in buff: elementMasses.append(el[0]) elements.append(el[1]) minComposition.append(composition[el[1]][0]) maxComposition.append(composition[el[1]][1]) # check max composition for i in range(len(maxComposition)): maxComposition[i] = min(maxComposition[i], int(hiMass/elementMasses[i])) # generate compositions formulae = [] comps = _compositions(minComposition, maxComposition, elementMasses, loMass, hiMass, limit) for comp in comps: CHECK_FORCE_QUIT() formula = '' for i in range(len(comp)): formula += '%s%d' % (elements[i], comp[i]) formulae.append(formula) return formulae