def envmono(isotopes, charge, intensity='maximum'): """Calculate envelope centroid for given isotopes. isotopes (mspy.peaklist or list of mspy.peak) - envelope isotopes charge (int) - peak charge intensity (maximum | sum | average) - envelope intensity type """ # check isotopes if len(isotopes) == 0: return None # check peaklist object if not isinstance(isotopes, obj_peaklist.peaklist): isotopes = obj_peaklist.peaklist(isotopes) # calc averagine avFormula = averagine(isotopes.basepeak.mz, charge=charge, composition=AVERAGE_AMINO) avPattern = avFormula.pattern(fwhm=0.1, threshold=0.001, charge=charge) avPattern = obj_peaklist.peaklist(avPattern) # get envelope centroid points = numpy.array([(p.mz, p.intensity) for p in isotopes]) centroid = labelpeak(points, mz=isotopes.basepeak.mz, pickingHeight=0.8) if not centroid: centroid = isotopes.basepeak # get averagine centroid points = numpy.array([(p.mz, p.intensity) for p in avPattern]) avCentroid = labelpeak(points, mz=avPattern.basepeak.mz, pickingHeight=0.8) if not avCentroid: avCentroid = avPattern.basepeak # align profiles and get monoisotopic mass shift = centroid.mz - avCentroid.mz errors = [(abs(p.mz - avPattern.basepeak.mz - shift), p.mz) for p in isotopes] mz = min(errors)[1] - (avPattern.basepeak.mz - avFormula.mz(charge)[0]) # sum intensities sumIntensity = 0 for isotope in isotopes: sumIntensity += isotope.intensity # get ai, base and sn base = isotopes.basepeak.base sn = isotopes.basepeak.sn fwhm = isotopes.basepeak.fwhm if intensity == 'sum': ai = base + sumIntensity elif intensity == 'average': ai = base + sumIntensity / len(isotopes) else: ai = isotopes.basepeak.ai if isotopes.basepeak.sn: sn = (ai - base) * isotopes.basepeak.sn / (isotopes.basepeak.ai - base) # make peak peak = obj_peak.peak(mz=mz, ai=ai, base=base, sn=sn, fwhm=fwhm, isotope=0) return peak
def _makeScan(self, scanData): """Make scan object from raw data.""" # parse peaks points = self._parsePoints(scanData) if scanData['spectrumType'] == 'discrete': for x, p in enumerate(points): points[x] = obj_peak.peak(p[0], p[1]) scan = obj_scan.scan(peaklist=obj_peaklist.peaklist(points)) else: scan = obj_scan.scan(profile=points) # set metadata scan.title = scanData['title'] scan.scanNumber = scanData['scanNumber'] scan.parentScanNumber = scanData['parentScanNumber'] scan.msLevel = scanData['msLevel'] scan.polarity = scanData['polarity'] scan.retentionTime = scanData['retentionTime'] scan.totIonCurrent = scanData['totIonCurrent'] scan.basePeakMZ = scanData['basePeakMZ'] scan.basePeakIntensity = scanData['basePeakIntensity'] scan.precursorMZ = scanData['precursorMZ'] scan.precursorIntensity = scanData['precursorIntensity'] scan.precursorCharge = scanData['precursorCharge'] return scan
def __init__(self, profile=[], peaklist=[], **attr): self.title = '' self.scanNumber = None self.parentScanNumber = None self.polarity = None self.msLevel = None self.retentionTime = None self.totIonCurrent = None self.basePeakMZ = None self.basePeakIntensity = None self.precursorMZ = None self.precursorIntensity = None self.precursorCharge = None # buffers self._baseline = None self._baselineParams = {'window': None, 'offset': None} # convert profile to numPy array if not isinstance(profile, numpy.ndarray): profile = numpy.array(profile) self.profile = profile # convert peaks to peaklist if not isinstance(peaklist, obj_peaklist.peaklist): peaklist = obj_peaklist.peaklist(peaklist) self.peaklist = peaklist # get additional attributes self.attributes = {} for name, value in attr.items(): self.attributes[name] = value
def topeaklist(self, peaklist, fwhm=0.1, forceFwhm=True, autoAlign=True, iterLimit=None, relThreshold=0.): """Fit modeled profiles to peaklist. peaklist (mspy.peaklist) - peak list fwhm (float) - defaut fwhm forceFwhm (bool) - use default fwhm autoAlign (bool) - automatic m/z shift iterLimit (int) - maximum number of iterations """ # check peaklist object if not isinstance(peaklist, obj_peaklist.peaklist): peaklist = obj_peaklist.peaklist(peaklist) # crop peaklist to relevant m/z range peaklist = peaklist.duplicate() peaklist.crop(self.mzrange[0], self.mzrange[1]) # remove peaks below threshold peaklist.remthreshold(relThreshold=relThreshold) # get fwhm from basepeak if not forceFwhm and peaklist.basepeak and peaklist.basepeak.fwhm: fwhm = peaklist.basepeak.fwhm # make data to fit points = numpy.array([(p.mz, p.intensity) for p in peaklist]) # fit return self.topoints( points = points, fwhm = fwhm, autoAlign = autoAlign, iterLimit = iterLimit, )
def __init__(self, profile=[], peaklist=[], **attr): self.title = "" self.scanNumber = None self.parentScanNumber = None self.polarity = None self.msLevel = None self.retentionTime = None self.totIonCurrent = None self.basePeakMZ = None self.basePeakIntensity = None self.precursorMZ = None self.precursorIntensity = None self.precursorCharge = None # buffers self._baseline = None self._baselineParams = {"window": None, "offset": None} # convert profile to numPy array if not isinstance(profile, numpy.ndarray): profile = numpy.array(profile) self.profile = profile # convert peaks to peaklist if not isinstance(peaklist, obj_peaklist.peaklist): peaklist = obj_peaklist.peaklist(peaklist) self.peaklist = peaklist # get additional attributes self.attributes = {} for name, value in attr.items(): self.attributes[name] = value
def _makeScan(self, scanData, dataType): """Make scan object from raw data.""" # parse data as peaklist (discrete points) if dataType == 'peaklist' or (dataType==None and len(scanData['data'])<3000): buff = [] for point in scanData['data']: buff.append(obj_peak.peak(point[0], point[1])) scan = obj_scan.scan(peaklist=obj_peaklist.peaklist(buff)) # parse data as spectrum (continuous line) else: scan = obj_scan.scan(profile=scanData['data']) # set metadata scan.title = scanData['title'] scan.scanNumber = scanData['scanNumber'] scan.parentScanNumber = scanData['parentScanNumber'] scan.msLevel = scanData['msLevel'] scan.polarity = scanData['polarity'] scan.retentionTime = scanData['retentionTime'] scan.totIonCurrent = scanData['totIonCurrent'] scan.basePeakMZ = scanData['basePeakMZ'] scan.basePeakIntensity = scanData['basePeakIntensity'] scan.precursorMZ = scanData['precursorMZ'] scan.precursorIntensity = scanData['precursorIntensity'] scan.precursorCharge = scanData['precursorCharge'] return scan
def _makeScan(self, scanData, dataType): """Make scan object from raw data.""" # parse data as peaklist (discrete points) if dataType == 'peaklist' or (dataType == None and len(scanData['data']) < 3000): buff = [] for point in scanData['data']: buff.append(obj_peak.peak(point[0], point[1])) scan = obj_scan.scan(peaklist=obj_peaklist.peaklist(buff)) # parse data as spectrum (continuous line) else: scan = obj_scan.scan(profile=scanData['data']) # set metadata scan.title = scanData['title'] scan.scanNumber = scanData['scanNumber'] scan.parentScanNumber = scanData['parentScanNumber'] scan.msLevel = scanData['msLevel'] scan.polarity = scanData['polarity'] scan.retentionTime = scanData['retentionTime'] scan.totIonCurrent = scanData['totIonCurrent'] scan.basePeakMZ = scanData['basePeakMZ'] scan.basePeakIntensity = scanData['basePeakIntensity'] scan.precursorMZ = scanData['precursorMZ'] scan.precursorIntensity = scanData['precursorIntensity'] scan.precursorCharge = scanData['precursorCharge'] return scan
def profile(peaklist, fwhm=0.1, points=10, noise=0, raster=None, forceFwhm=False, model='gaussian'): """Make profile spectrum for given peaklist. peaklist (mspy.peaklist) - peaklist fwhm (float) - default peak fwhm points (int) - default number of points per peak width (not used if raster is given) noise (float) - random noise width raster (1D numpy.array) - m/z raster forceFwhm (bool) - use default fwhm for all peaks model (gaussian, lorentzian, gausslorentzian) - peak shape function """ # check peaklist type if not isinstance(peaklist, obj_peaklist.peaklist): peaklist = obj_peaklist.peaklist(peaklist) # check raster type if raster != None and not isinstance(raster, numpy.ndarray): raster = numpy.array(raster) # get peaks peaks = [] for peak in peaklist: peaks.append([peak.mz, peak.intensity, peak.fwhm]) if forceFwhm or not peak.fwhm: peaks[-1][2] = fwhm # get model shape = 0 if model == 'gaussian': shape = 0 elif model == 'lorentzian': shape = 1 elif model == 'gausslorentzian': shape = 2 # make profile if raster != None: data = calculations.signal_profile_to_raster(numpy.array(peaks), raster, float(noise), shape) else: data = calculations.signal_profile(numpy.array(peaks), int(points), float(noise), shape) # make baseline baseline = [] for peak in peaklist: if not baseline or baseline[-1][0] != peak.mz: baseline.append([peak.mz, -peak.base]) # apply baseline data = mod_signal.subbase(data, numpy.array(baseline)) return data
def setpeaklist(self, peaks): """Set new peaklist.""" # convert peaks to peaklist if isinstance(peaks, obj_peaklist.peaklist): self.peaklist = peaks else: self.peaklist = obj_peaklist.peaklist(peaks)
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 _makeScan(self, scanData, dataType): """Make scan object from raw data.""" # parse data as peaklist (discrete points) if dataType == 'discrete': buff = [] for point in scanData: buff.append(obj_peak.peak(point[0], point[1])) scan = obj_scan.scan(peaklist=obj_peaklist.peaklist(buff)) # parse data as spectrum (continuous line) else: scan = obj_scan.scan(profile=scanData) return scan
def swap(self): """Swap data between profile and peaklist.""" # make new profile profile = [[i.mz, i.ai] for i in self.peaklist] profile = numpy.array(profile) # make new peaklist peaks = [obj_peak.peak(i[0], i[1]) for i in self.profile] peaks = obj_peaklist.peaklist(peaks) # update scan self.profile = profile self.peaklist = peaks # clear buffers self.reset()
def topeaklist(self, peaklist, fwhm=0.1, forceFwhm=True, autoAlign=True, iterLimit=None, relThreshold=0.): """Fit modeled profiles to peaklist. peaklist (mspy.peaklist) - peak list fwhm (float) - defaut fwhm forceFwhm (bool) - use default fwhm autoAlign (bool) - automatic m/z shift iterLimit (int) - maximum number of iterations """ # check peaklist object if not isinstance(peaklist, obj_peaklist.peaklist): peaklist = obj_peaklist.peaklist(peaklist) # crop peaklist to relevant m/z range peaklist = peaklist.duplicate() peaklist.crop(self.mzrange[0], self.mzrange[1]) # remove peaks below threshold peaklist.remthreshold(relThreshold=relThreshold) # get fwhm from basepeak if not forceFwhm and peaklist.basepeak and peaklist.basepeak.fwhm: fwhm = peaklist.basepeak.fwhm # make data to fit points = numpy.array([(p.mz, p.intensity) for p in peaklist]) # fit return self.topoints( points=points, fwhm=fwhm, autoAlign=autoAlign, iterLimit=iterLimit, )
def labelscan(signal, minX=None, maxX=None, pickingHeight=0.75, absThreshold=0., relThreshold=0., snThreshold=0., baseline=None): """Return centroided peaklist for given data points. signal (numpy array) - signal data points minX (float) - x-range start maxX (float) - x-range end pickingHeight (float) - centroiding height absThreshold (float) - absolute intensity threshold relThreshold (float) - relative intensity threshold snThreshold (float) - signal to noise threshold baseline (numpy array) - signal baseline """ # check signal type if not isinstance(signal, numpy.ndarray): raise TypeError, "Signal must be NumPy array!" # check baseline type if baseline != None and not isinstance(baseline, numpy.ndarray): raise TypeError, "Baseline must be NumPy array!" # crop data if minX != None and maxX != None: i1 = mod_signal.locate(signal, minX) i2 = mod_signal.locate(signal, maxX) signal = signal[i1:i2] # check data points if len(signal) == 0: return obj_peaklist.peaklist([]) # get local maxima buff = [] basepeak = mod_signal.basepeak(signal) threshold = max(signal[basepeak][1] * relThreshold, absThreshold) for peak in mod_signal.maxima(signal): if peak[1] >= threshold: buff.append( [peak[0], peak[1], 0., None, None] ) # mz, ai, base, sn, fwhm CHECK_FORCE_QUIT() # get peaks baseline and s/n basepeak = 0.0 if baseline != None: for peak in buff: idx = mod_signal.locate(baseline, peak[0]) if (idx > 0) and (idx < len(baseline)): p1 = baseline[idx-1] p2 = baseline[idx] peak[2] = mod_signal.interpolate( (p1[0], p1[1]), (p2[0], p2[1]), x=peak[0]) noise = mod_signal.interpolate( (p1[0], p1[2]), (p2[0], p2[2]), x=peak[0]) intens = peak[1] - peak[2] if noise: peak[3] = intens / noise if intens > basepeak: basepeak = intens CHECK_FORCE_QUIT() # remove peaks bellow threshold threshold = max(basepeak * relThreshold, absThreshold) candidates = [] for peak in buff: if peak[0] > 0 and (peak[1] - peak[2]) >= threshold and (not peak[3] or peak[3] >= snThreshold): candidates.append(peak) # make centroides if pickingHeight < 1.: buff = [] previous = None for peak in candidates: CHECK_FORCE_QUIT() # calc peak height h = ((peak[1]-peak[2]) * pickingHeight) + peak[2] # get centroid indexes idx = mod_signal.locate(signal, peak[0]) if (idx == 0) or (idx == len(signal)): continue ileft = idx-1 while (ileft > 0) and (signal[ileft][1] > h): ileft -= 1 iright = idx while (iright < len(signal)-1) and (signal[iright][1] > h): iright += 1 # calculate peak mz leftMZ = mod_signal.interpolate(signal[ileft], signal[ileft+1], y=h) rightMZ = mod_signal.interpolate(signal[iright-1], signal[iright], y=h) peak[0] = (leftMZ + rightMZ)/2. # get peak intensity intens = mod_signal.intensity(signal, peak[0]) if intens and intens <= peak[1]: peak[1] = intens else: continue # try to group with previous peak if previous != None and leftMZ < previous: if peak[1] > buff[-1][1]: buff[-1] = peak previous = rightMZ else: buff.append(peak) previous = rightMZ # store as candidates candidates = buff CHECK_FORCE_QUIT() # get peaks baseline and s/n basepeak = 0.0 if baseline != None: for peak in candidates: idx = mod_signal.locate(baseline, peak[0]) if (idx > 0) and (idx < len(baseline)): p1 = baseline[idx-1] p2 = baseline[idx] peak[2] = mod_signal.interpolate( (p1[0], p1[1]), (p2[0], p2[1]), x=peak[0]) noise = mod_signal.interpolate( (p1[0], p1[2]), (p2[0], p2[2]), x=peak[0]) intens = peak[1] - peak[2] if noise: peak[3] = intens / noise if intens > basepeak: basepeak = intens CHECK_FORCE_QUIT() # remove peaks bellow threshold and calculate fwhm threshold = max(basepeak * relThreshold, absThreshold) centroides = [] for peak in candidates: if peak[0] > 0 and (peak[1] - peak[2]) >= threshold and (not peak[3] or peak[3] >= snThreshold): peak[4] = mod_signal.width(signal, peak[0], (peak[2] + ((peak[1] - peak[2]) * 0.5))) centroides.append(obj_peak.peak(mz=peak[0], ai=peak[1], base=peak[2], sn=peak[3], fwhm=peak[4])) # return peaklist object return obj_peaklist.peaklist(centroides)
def envcentroid(isotopes, pickingHeight=0.5, intensity='maximum'): """Calculate envelope centroid for given isotopes. isotopes (mspy.peaklist or list of mspy.peak) envelope isotopes pickingHeight (float) - centroiding height intensity (maximum | sum | average) envelope intensity type """ # check isotopes if len(isotopes) == 0: return None elif len(isotopes) == 1: return isotopes[0] # check peaklist object if not isinstance(isotopes, obj_peaklist.peaklist): isotopes = obj_peaklist.peaklist(isotopes) # get sums sumMZ = 0. sumIntensity = 0. for isotope in isotopes: sumMZ += isotope.mz * isotope.intensity sumIntensity += isotope.intensity # get average m/z mz = sumMZ / sumIntensity # get ai, base and sn base = isotopes.basepeak.base sn = isotopes.basepeak.sn fwhm = isotopes.basepeak.fwhm if intensity == 'sum': ai = base + sumIntensity elif intensity == 'average': ai = base + sumIntensity / len(isotopes) else: ai = isotopes.basepeak.ai if isotopes.basepeak.sn: sn = (ai - base) * isotopes.basepeak.sn / (isotopes.basepeak.ai - base) # get envelope width minInt = isotopes.basepeak.intensity * pickingHeight i1 = None i2 = None for x, isotope in enumerate(isotopes): if isotope.intensity >= minInt: i2 = x if i1 == None: i1 = x mz1 = isotopes[i1].mz mz2 = isotopes[i2].mz if i1 != 0: mz1 = mod_signal.interpolate((isotopes[i1-1].mz, isotopes[i1-1].ai), (isotopes[i1].mz, isotopes[i1].ai), y=minInt) if i2 < len(isotopes)-1: mz2 = mod_signal.interpolate((isotopes[i2].mz, isotopes[i2].ai), (isotopes[i2+1].mz, isotopes[i2+1].ai), y=minInt) if mz1 != mz2: fwhm = abs(mz2 - mz1) # make peak peak = obj_peak.peak(mz=mz, ai=ai, base=base, sn=sn, fwhm=fwhm) return peak