示例#1
0
def handle_compressed_frame(allmz, allint, allim, mslevel, rtime, center,
                            width):
    mz = np.concatenate(allmz)
    intens = np.concatenate(allint)
    ims = np.concatenate(allim)

    fda = pyopenms.FloatDataArray()
    fda.setName("Ion Mobility")
    fda.resize(len(mz))
    for k, val in enumerate(ims):
        fda[k] = val

    sframe = pyopenms.MSSpectrum()
    sframe.setMSLevel(mslevel)
    sframe.setRT(rtime)
    sframe.setFloatDataArrays([fda])
    p = pyopenms.Precursor()
    if mslevel == 2:
        p.setMZ(center)
        p.setIsolationWindowUpperOffset(width / 2.0)
        p.setIsolationWindowLowerOffset(width / 2.0)
    sframe.setPrecursors([p])
    sframe.set_peaks((mz, intens))
    sframe.sortByPosition()
    return sframe
示例#2
0
def four_d_spectrum_to_experiment(spec):
    """Function that converts a 4D spectrum object which contains retention
    time, ion mobility, mass to charge, and intensity data, into a new
    experiment where the ion mobility becomes the retention time of
    each of its new spectra and vice versa.

    Args:
        spec (MSSpectrum): An OpenMS MSSpectrum object.

    Returns:
        MSExperiment: A new MSExperiment where each MSSpectrum object is a 3D
        spectrum from the original where the retention time and ion mobility
        has been swapped.
    """
    ion_mobility_to_peaks = zip(spec.getFloatDataArrays()[0],
                                *spec.get_peaks())

    new_exp = ms.MSExperiment()
    new_mz, new_int = [], []
    curr_im = None

    for im, mz, intensity in sorted(ion_mobility_to_peaks,
                                    key=lambda x: (x[0], x[1], x[2])):
        if im != curr_im:
            if curr_im:
                new_spec = ms.MSSpectrum()
                new_spec.setRT(curr_im)
                new_spec.set_peaks((new_mz, new_int))

                rt_fda = ms.FloatDataArray()
                for i in new_mz:
                    rt_fda.push_back(spec.getRT())

                new_spec.setFloatDataArrays([rt_fda])
                new_exp.addSpectrum(new_spec)
                new_mz, new_int = [], []

            curr_im = im

        new_mz.append(mz)
        new_int.append(intensity)

    return new_exp
示例#3
0
    def bin_spectrum(self, spec: ms.MSSpectrum) -> None:
        """Bins a single spectrum in two passes.

        Keyword arguments:
        spec: the spectrum to bin
        """
        points = util.get_spectrum_points(spec)
        points.sort(key=itemgetter(3))  # Ascending IM

        temp_bins = [[], [[]]]  # 2D spectra
        new_bins = [[], [[]]]  # Final 1D spectra

        for i in range(self.num_bins):
            for j in range(2):
                temp_bins[j].append([])
                new_bins[j].append([])

        for i in range(len(points)):  # Assign points to bins
            bin_idx = int((points[i][3] - self.im_start) / self.bin_size)
            if bin_idx >= self.num_bins:
                bin_idx = self.num_bins - 1
            temp_bins[0][bin_idx].append(points[i])

            bin_idx = int((points[i][3] - self.im_offset) / self.bin_size) + 1
            if points[i][3] < self.im_offset:
                bin_idx = 0
            elif bin_idx > self.num_bins:
                bin_idx = self.num_bins
            temp_bins[1][bin_idx].append(points[i])

        for i in range(self.num_bins):  # First pass
            if len(temp_bins[0][i]) == 0:
                continue

            temp_bins[0][i].sort(key=itemgetter(1))  # Ascending m/z
            mz_start, curr_mz = 0, temp_bins[0][i][0][1]
            running_intensity = 0

            for j in range(len(temp_bins[0][i])):
                if self.within_epsilon(curr_mz, temp_bins[0][i][j][1]):
                    running_intensity += temp_bins[0][i][j][2]
                else:  # Reached a new m/z slice
                    point = list(
                        temp_bins[0][i][mz_start])  # Prevents aliasing
                    point[2] = running_intensity
                    new_bins[0][i].append(point)
                    mz_start, curr_mz = j, temp_bins[0][i][j][1]
                    running_intensity = temp_bins[0][i][j][2]

            point = list(
                temp_bins[0][i][mz_start])  # Take care of the last slice
            point[2] = running_intensity
            new_bins[0][i].append(point)

            transpose = list(zip(*new_bins[0][i]))
            new_spec = ms.MSSpectrum()  # The final binned spectrum
            im_fda = ms.FloatDataArray()
            for im in transpose[3]:
                im_fda.push_back(im)

            new_spec.setRT(spec.getRT())
            new_spec.set_peaks((list(transpose[1]), list(transpose[2])))
            new_spec.setFloatDataArrays([im_fda])
            self.exps[0][i].addSpectrum(new_spec)

        for i in range(self.num_bins + 1):  # Second pass
            if len(temp_bins[1][i]) == 0:
                continue

            temp_bins[1][i].sort(key=itemgetter(1))
            mz_start, curr_mz = 0, temp_bins[1][i][0][1]
            running_intensity = 0

            for j in range(len(temp_bins[1][i])):
                if self.within_epsilon(curr_mz, temp_bins[1][i][j][1]):
                    running_intensity += temp_bins[1][i][j][2]
                else:
                    point = list(temp_bins[1][i][mz_start])
                    point[2] = running_intensity
                    new_bins[1][i].append(point)
                    mz_start, curr_mz = j, temp_bins[1][i][j][1]
                    running_intensity = temp_bins[1][i][j][2]

            point = list(temp_bins[1][i][mz_start])
            point[2] = running_intensity
            new_bins[1][i].append(point)

            transpose = list(zip(*new_bins[1][i]))
            new_spec = ms.MSSpectrum()
            im_fda = ms.FloatDataArray()
            for im in transpose[3]:
                im_fda.push_back(im)

            new_spec.setRT(spec.getRT())
            new_spec.set_peaks((list(transpose[1]), list(transpose[2])))
            new_spec.setFloatDataArrays([im_fda])
            self.exps[1][i].addSpectrum(new_spec)
示例#4
0
def store_frame(frame_id, td, conn, exp, verbose=False, compressFrame=True):
    """
    Store a single frame as an individual mzML file

    Note that there are two ways to store the data:
      (i) Multiple spectra per frame (for visualization), compressFrame is False. This is the
      easiest way to visualize and process the data but involves a few hacks,
      namely storing the IM axis as the RT of each spectrum.

      (ii) One spectrum per frame, compressFrame is True. This puts all peaks
      into a single spectrum (while storing the IM data in an extra array).
      This is more efficient for storage and allows analysis that is ignorant
      of the IM dimension.
    """
    # Get a projected mass spectrum:
    q = conn.execute("SELECT NumScans, Time, Polarity, MsMsType FROM Frames WHERE Id={0}".format(frame_id))
    tmp = q.fetchone()
    num_scans = tmp[0]
    time = tmp[1]
    pol = tmp[2]
    msms = int(tmp[3])

    center = -1
    width = -1
    mslevel = 1
    if msms == 2:
        q = conn.execute("SELECT TriggerMass, IsolationWidth, PrecursorCharge, CollisionEnergy FROM FrameMsMsInfo WHERE Frame={0}".format(frame_id))
        tmp = q.fetchone()
        center = float(tmp[0])
        width = float(tmp[1])
        mslevel = 2

    if verbose:
        print "mslevel", mslevel, msms

    # Get the mapping of the ion mobility axis
    scan_number_axis = np.arange(num_scans, dtype=np.float64)
    ook0_axis = td.scanNumToOneOverK0(frame_id, scan_number_axis)

    allmz = []
    allint = []
    allim = []

    # Traverse in reversed order to get low ion mobilities first
    for k, scan in reversed(list(enumerate(td.readScans(frame_id, 0, num_scans)))):
        index = np.array(scan[0], dtype=np.float64)
        mz = td.indexToMz(frame_id, index)
        intens = scan[1]
        drift_time = ook0_axis [k] 
        if compressFrame:
            allmz.append(mz)
            allint.append(intens)
            allim.append([drift_time for k in mz])
            continue

        # Store data in OpenMS Spectrum file -> each TOF push is an individual
        # spectrum and we store the ion mobility in the precursor. The frame
        # can be reconstructed by grouping all spectra with the same RT.
        s = pyopenms.MSSpectrum()
        s.setMSLevel(mslevel)
        s.set_peaks( (mz, intens) ) 
        s.setRT(time)
        p = pyopenms.Precursor()
        p.setDriftTime(drift_time)
        if msms == 2:
            p.setMZ(center)
            p.setIsolationWindowUpperOffset(width / 2.0)
            p.setIsolationWindowLowerOffset(width / 2.0)
        s.setPrecursors([p])
        exp.consumeSpectrum(s)


    if compressFrame:
        mz = np.concatenate(allmz)
        intens = np.concatenate(allint)
        ims = np.concatenate(allim)
        # print "   leeen", len(mz), len(intens)

        fda = pyopenms.FloatDataArray()
        fda.setName("Ion Mobility")
        fda.resize(len(mz))
        for k,val in enumerate(ims):
            fda[k] = val

        sframe = pyopenms.MSSpectrum()
        sframe.setMSLevel(mslevel)
        sframe.setRT(time)
        sframe.setFloatDataArrays([fda])
        p = pyopenms.Precursor()
        if msms == 2:
            p.setMZ(center)
            p.setIsolationWindowUpperOffset(width / 2.0)
            p.setIsolationWindowLowerOffset(width / 2.0)
        sframe.setPrecursors([p])
        sframe.set_peaks( (mz, intens) )
        sframe.sortByPosition()
        exp.consumeSpectrum(sframe)