Beispiel #1
0
    def _get_dda_scan_param(self, mz, intensity, isolation_width, mz_tol,
                            rt_tol, collision_energy):
        dda_scan_params = ScanParameters()
        dda_scan_params.set(ScanParameters.MS_LEVEL, 2)

        # create precursor object, assume it's all singly charged
        precursor_charge = +1 if (self.environment.mass_spec.ionisation_mode
                                  == POSITIVE) else -1
        precursor = Precursor(precursor_mz=mz,
                              precursor_intensity=intensity,
                              precursor_charge=precursor_charge,
                              precursor_scan_id=self.last_ms1_scan.scan_id)
        dda_scan_params.set(ScanParameters.PRECURSOR_MZ, precursor)

        # set the full-width isolation width, in Da
        dda_scan_params.set(ScanParameters.ISOLATION_WIDTH, isolation_width)

        # define dynamic exclusion parameters
        dda_scan_params.set(ScanParameters.DYNAMIC_EXCLUSION_MZ_TOL, mz_tol)
        dda_scan_params.set(ScanParameters.DYNAMIC_EXCLUSION_RT_TOL, rt_tol)

        # define other fragmentation parameters
        dda_scan_params.set(ScanParameters.COLLISION_ENERGY, collision_energy)
        dda_scan_params.set(ScanParameters.POLARITY,
                            self.environment.mass_spec.ionisation_mode)
        dda_scan_params.set(ScanParameters.FIRST_MASS,
                            DEFAULT_MSN_SCAN_WINDOW[0])
        dda_scan_params.set(ScanParameters.LAST_MASS,
                            DEFAULT_MSN_SCAN_WINDOW[1])
        return dda_scan_params
Beispiel #2
0
    def _process_scan(self, scan, queue_size):
        # if there's a previous ms1 scan to process
        new_tasks = []
        if self.last_ms1_scan is not None:

            rt = self.last_ms1_scan.rt

            # then get the last ms1 scan, select bin walls and create scan locations
            mzs = self.last_ms1_scan.mzs
            default_range = [
                DEFAULT_MS1_SCAN_WINDOW
            ]  # TODO: this should maybe come from somewhere else?
            locations = DiaWindows(mzs, default_range, self.dia_design,
                                   self.window_type, self.kaufmann_design,
                                   self.extra_bins, self.num_windows).locations
            logger.debug('Window locations {}'.format(locations))
            for i in range(
                    len(locations)
            ):  # define isolation window around the selected precursor ions
                isolation_windows = locations[i]
                dda_scan_params = ScanParameters()
                dda_scan_params.set(ScanParameters.MS_LEVEL, 2)
                dda_scan_params.set(ScanParameters.ISOLATION_WINDOWS,
                                    isolation_windows)
                new_tasks.append(dda_scan_params
                                 )  # push this dda scan to the mass spec queue

            # set this ms1 scan as has been processed
            self.last_ms1_scan = None
        return new_tasks
Beispiel #3
0
    def __init__(self,
                 mass_spec,
                 N,
                 scan_param_changepoints,
                 isolation_window,
                 mz_tol,
                 rt_tol,
                 min_ms1_intensity,
                 n_purity_scans=None,
                 purity_shift=None,
                 purity_threshold=0):
        super().__init__(mass_spec)
        self.last_ms1_scan = None
        self.N = np.array(N)
        if scan_param_changepoints is not None:
            self.scan_param_changepoints = np.array([0] +
                                                    scan_param_changepoints)
        else:
            self.scan_param_changepoints = np.array([0])
        self.isolation_window = np.array(
            isolation_window
        )  # the isolation window (in Dalton) to select a precursor ion
        self.mz_tol = np.array(
            mz_tol
        )  # the m/z window (ppm) to prevent the same precursor ion to be fragmented again
        self.rt_tol = np.array(
            rt_tol
        )  # the rt window to prevent the same precursor ion to be fragmented again
        self.min_ms1_intensity = min_ms1_intensity  # minimum ms1 intensity to fragment

        self.n_purity_scans = n_purity_scans
        self.purity_shift = purity_shift
        self.purity_threshold = purity_threshold

        # make sure the input are all correct
        assert len(self.N) == len(self.scan_param_changepoints) == len(
            self.isolation_window) == len(self.mz_tol) == len(self.rt_tol)
        if self.purity_threshold != 0:
            assert all(self.n_purity_scans < np.array(self.N))

        mass_spec.reset()
        current_N, current_rt_tol, idx = self._get_current_N_DEW()
        mass_spec.current_N = current_N
        mass_spec.current_DEW = current_rt_tol

        default_scan = ScanParameters()
        default_scan.set(ScanParameters.MS_LEVEL, 1)
        default_scan.set(ScanParameters.ISOLATION_WINDOWS,
                         [[DEFAULT_MS1_SCAN_WINDOW]])
        mass_spec.set_repeating_scan(default_scan)

        # register new event handlers under this controller
        mass_spec.register(IndependentMassSpectrometer.MS_SCAN_ARRIVED,
                           self.handle_scan)
        mass_spec.register(
            IndependentMassSpectrometer.ACQUISITION_STREAM_OPENING,
            self.handle_acquisition_open)
        mass_spec.register(
            IndependentMassSpectrometer.ACQUISITION_STREAM_CLOSING,
            self.handle_acquisition_closing)
Beispiel #4
0
    def __init__(self,
                 mass_spec,
                 dia_design,
                 window_type,
                 kaufmann_design,
                 extra_bins,
                 num_windows=None):
        super().__init__(mass_spec)
        self.last_ms1_scan = None
        self.dia_design = dia_design
        self.window_type = window_type
        self.kaufmann_design = kaufmann_design
        self.extra_bins = extra_bins
        self.num_windows = num_windows

        mass_spec.reset()
        default_scan = ScanParameters()
        default_scan.set(ScanParameters.MS_LEVEL, 1)
        default_scan.set(ScanParameters.ISOLATION_WINDOWS,
                         [[DEFAULT_MS1_SCAN_WINDOW]])
        mass_spec.set_repeating_scan(default_scan)

        mass_spec.register(IndependentMassSpectrometer.MS_SCAN_ARRIVED,
                           self.handle_scan)
        mass_spec.register(
            IndependentMassSpectrometer.ACQUISITION_STREAM_OPENING,
            self.handle_acquisition_open)
        mass_spec.register(
            IndependentMassSpectrometer.ACQUISITION_STREAM_CLOSING,
            self.handle_acquisition_closing)
Beispiel #5
0
    def __init__(self, mass_spec, N, isolation_window, mz_tol, rt_tol,
                 min_ms1_intensity):
        super().__init__(mass_spec)
        self.last_ms1_scan = None
        self.N = N
        self.isolation_window = isolation_window  # the isolation window (in Dalton) to select a precursor ion
        self.mz_tol = mz_tol  # the m/z window (ppm) to prevent the same precursor ion to be fragmented again
        self.rt_tol = rt_tol  # the rt window to prevent the same precursor ion to be fragmented again
        self.min_ms1_intensity = min_ms1_intensity  # minimum ms1 intensity to fragment

        mass_spec.reset()
        mass_spec.current_N = N
        mass_spec.current_DEW = rt_tol

        default_scan = ScanParameters()
        default_scan.set(ScanParameters.MS_LEVEL, 1)
        default_scan.set(ScanParameters.ISOLATION_WINDOWS,
                         [[DEFAULT_MS1_SCAN_WINDOW]])
        mass_spec.set_repeating_scan(default_scan)

        # register new event handlers under this controller
        mass_spec.register(IndependentMassSpectrometer.MS_SCAN_ARRIVED,
                           self.handle_scan)
        mass_spec.register(
            IndependentMassSpectrometer.ACQUISITION_STREAM_OPENING,
            self.handle_acquisition_open)
        mass_spec.register(
            IndependentMassSpectrometer.ACQUISITION_STREAM_CLOSING,
            self.handle_acquisition_closing)
Beispiel #6
0
    def __init__(self,
                 mass_spec,
                 isolation_window,
                 mz_tol,
                 min_ms1_intensity,
                 min_roi_intensity,
                 min_roi_length,
                 score_method,
                 N=None,
                 rt_tol=math.inf,
                 score_params=None):
        super().__init__(mass_spec)
        self.last_ms1_scan = None
        self.N = N
        self.isolation_window = isolation_window  # the isolation window (in Dalton) to select a precursor ion
        self.mz_tol = mz_tol  # the m/z window (ppm) to prevent the same precursor ion to be fragmented again
        self.rt_tol = rt_tol  # the rt window to prevent the same precursor ion to be fragmented again
        self.min_ms1_intensity = min_ms1_intensity  # minimum ms1 intensity to fragment

        # ROI stuff
        self.min_roi_intensity = min_roi_intensity
        self.mz_units = 'Da'
        self.min_roi_length = min_roi_length

        # Score stuff
        self.score_params = score_params
        self.score_method = score_method

        # Create ROI
        self.live_roi = []
        self.dead_roi = []
        self.junk_roi = []
        self.live_roi_fragmented = []
        self.live_roi_last_rt = []  # last fragmentation time of ROI

        mass_spec.reset()
        mass_spec.current_N = N
        mass_spec.current_DEW = rt_tol
        mass_spec.use_exclusion_list = False

        default_scan = ScanParameters()
        default_scan.set(ScanParameters.MS_LEVEL, 1)
        default_scan.set(ScanParameters.ISOLATION_WINDOWS,
                         [[DEFAULT_MS1_SCAN_WINDOW]])
        mass_spec.set_repeating_scan(default_scan)

        # register new event handlers under this controller
        mass_spec.register(IndependentMassSpectrometer.MS_SCAN_ARRIVED,
                           self.handle_scan)
        mass_spec.register(
            IndependentMassSpectrometer.ACQUISITION_STREAM_OPENING,
            self.handle_acquisition_open)
        mass_spec.register(
            IndependentMassSpectrometer.ACQUISITION_STREAM_CLOSING,
            self.handle_acquisition_closing)
Beispiel #7
0
    def __init__(self, mass_spec):
        super().__init__(mass_spec)
        default_scan = ScanParameters()
        default_scan.set(ScanParameters.MS_LEVEL, 1)
        default_scan.set(ScanParameters.ISOLATION_WINDOWS,
                         [[DEFAULT_MS1_SCAN_WINDOW]])

        mass_spec.reset()
        mass_spec.current_N = 0
        mass_spec.current_DEW = 0

        mass_spec.set_repeating_scan(default_scan)
        mass_spec.register(IndependentMassSpectrometer.MS_SCAN_ARRIVED,
                           self.handle_scan)
        mass_spec.register(
            IndependentMassSpectrometer.ACQUISITION_STREAM_OPENING,
            self.handle_acquisition_open)
        mass_spec.register(
            IndependentMassSpectrometer.ACQUISITION_STREAM_CLOSING,
            self.handle_acquisition_closing)
Beispiel #8
0
 def __init__(self,
              mass_spec,
              controller,
              min_time,
              max_time,
              progress_bar=True,
              out_dir=None,
              out_file=None):
     """
     Initialises a synchronous environment to run the mass spec and controller
     :param mass_spec: An instance of Mass Spec object
     :param controller: An instance of Controller object
     :param min_time: start time
     :param max_time: end time
     :param progress_bar: True if a progress bar is to be shown
     """
     self.scan_channel = []
     self.task_channel = []
     self.mass_spec = mass_spec
     self.controller = controller
     self.min_time = min_time
     self.max_time = max_time
     self.progress_bar = progress_bar
     self.default_scan_params = ScanParameters()
     self.default_scan_params.set(ScanParameters.MS_LEVEL, 1)
     self.default_scan_params.set(ScanParameters.ISOLATION_WINDOWS,
                                  [[DEFAULT_MS1_SCAN_WINDOW]])
     self.default_scan_params.set(ScanParameters.ISOLATION_WIDTH,
                                  DEFAULT_ISOLATION_WIDTH)
     self.default_scan_params.set(ScanParameters.COLLISION_ENERGY,
                                  DEFAULT_COLLISION_ENERGY)
     self.default_scan_params.set(ScanParameters.POLARITY,
                                  self.mass_spec.ionisation_mode)
     self.default_scan_params.set(ScanParameters.FIRST_MASS,
                                  DEFAULT_MS1_SCAN_WINDOW[0])
     self.default_scan_params.set(ScanParameters.LAST_MASS,
                                  DEFAULT_MS1_SCAN_WINDOW[1])
     self.out_dir = out_dir
     self.out_file = out_file
Beispiel #9
0
    def run(self, schedule_file, progress_bar=True):
        self.schedule = pd.read_csv(schedule_file)
        for idx, row in self.schedule.iterrows():
            target_mass = row.targetMass
            target_time = row.targetTime

            if np.isnan(target_mass):
                ms_level = 1
                isolation_windows = [[(0, 1000)]]
                precursor = None
            else:
                ms_level = 2
                mz_lower = target_mass - self.isolation_window
                mz_upper = target_mass + self.isolation_window
                isolation_windows = [[(mz_lower, mz_upper)]]
                precursor_charge = +1 if (self.mass_spec.ionisation_mode
                                          == POSITIVE) else -1
                scan_id = 0
                precursor = Precursor(precursor_mz=target_mass,
                                      precursor_intensity=0,
                                      precursor_charge=precursor_charge,
                                      precursor_scan_id=scan_id)

            dda_scan_params = ScanParameters()
            dda_scan_params.set(ScanParameters.MS_LEVEL, ms_level)
            dda_scan_params.set(ScanParameters.ISOLATION_WINDOWS,
                                isolation_windows)
            dda_scan_params.set(ScanParameters.TIME, target_time)
            if precursor:
                dda_scan_params.set(ScanParameters.PRECURSOR, precursor)
            self.mass_spec.add_task(
                dda_scan_params)  # push this scan to the mass spec queue

        if progress_bar:
            with tqdm(total=target_time, initial=0) as pbar:
                self.mass_spec.run(self.schedule, pbar=pbar)
        else:
            self.mass_spec.run(self.schedule)
Beispiel #10
0
    def _update_parameters(self, scan):

        # if there's a previous ms1 scan to process
        if self.last_ms1_scan is not None:

            self.current_roi_mzs = [roi.get_mean_mz() for roi in self.live_roi]
            self.current_roi_intensities = [
                roi.get_max_intensity() for roi in self.live_roi
            ]
            rt = self.last_ms1_scan.rt

            # loop over points in decreasing score
            scores = self.get_scores(self.score_method, self.score_params)
            idx = np.argsort(scores)[::-1]
            for i in idx:
                mz = self.current_roi_mzs[i]
                intensity = self.current_roi_intensities[i]

                # stopping criteria is done based on the scores
                if scores[i] <= 0:
                    self.logger.debug(
                        'Time %f Top-%d ions have been selected' %
                        (self.mass_spec.time, self.N))
                    break

                # updated fragmented list and times
                if self.live_roi_fragmented[i]:
                    continue
                self.live_roi_fragmented[i] = True
                self.live_roi_last_rt[
                    i] = rt  # TODO: May want to update this to use the time of the MS2 scan

                # send a new ms2 scan parameter to the mass spec
                dda_scan_params = ScanParameters()
                dda_scan_params.set(ScanParameters.MS_LEVEL, 2)

                # create precursor object, assume it's all singly charged
                precursor_charge = +1 if (self.mass_spec.ionisation_mode
                                          == POSITIVE) else -1
                precursor = Precursor(
                    precursor_mz=mz,
                    precursor_intensity=intensity,
                    precursor_charge=precursor_charge,
                    precursor_scan_id=self.last_ms1_scan.scan_id)
                mz_lower = mz - self.isolation_window  # Da
                mz_upper = mz + self.isolation_window  # Da
                isolation_windows = [[(mz_lower, mz_upper)]]
                dda_scan_params.set(ScanParameters.ISOLATION_WINDOWS,
                                    isolation_windows)
                dda_scan_params.set(ScanParameters.PRECURSOR, precursor)

                # save dynamic exclusion parameters too
                dda_scan_params.set(ScanParameters.DYNAMIC_EXCLUSION_MZ_TOL,
                                    self.mz_tol)
                dda_scan_params.set(ScanParameters.DYNAMIC_EXCLUSION_RT_TOL,
                                    self.rt_tol)

                # push this dda scan parameter to the mass spec queue
                self.mass_spec.add_task(dda_scan_params)

            for param in self.mass_spec.get_task_queue():
                precursor = param.get(ScanParameters.PRECURSOR)
                if precursor is not None:
                    self.logger.debug('- %s' % str(precursor))

                # set this ms1 scan as has been processed
            self.last_ms1_scan = None
Beispiel #11
0
    def _update_parameters(self, scan):

        # if there's a previous ms1 scan to process
        if self.last_ms1_scan is not None:

            mzs = self.last_ms1_scan.mzs
            intensities = self.last_ms1_scan.intensities
            rt = self.last_ms1_scan.rt

            # set up current scan parameters
            current_N, current_rt_tol, idx = self._get_current_N_DEW()
            current_isolation_window = self.isolation_window[idx]
            current_mz_tol = self.mz_tol[idx]

            # calculate purities
            purities = []
            for mz_idx in range(len(self.last_ms1_scan.mzs)):
                nearby_mzs_idx = np.where(
                    abs(self.last_ms1_scan.mzs - self.last_ms1_scan.mzs[mz_idx]
                        ) < current_isolation_window)
                if len(nearby_mzs_idx[0]) == 1:
                    purities.append(1)
                else:
                    total_intensity = sum(
                        self.last_ms1_scan.intensities[nearby_mzs_idx])
                    purities.append(self.last_ms1_scan.intensities[mz_idx] /
                                    total_intensity)

            # loop over points in decreasing intensity
            fragmented_count = 0
            idx = np.argsort(intensities)[::-1]
            for i in idx:
                mz = mzs[i]
                intensity = intensities[i]
                purity = purities[i]

                # stopping criteria is after we've fragmented N ions or we found ion < min_intensity
                if fragmented_count >= current_N:
                    self.logger.debug(
                        'Time %f Top-%d ions have been selected' %
                        (self.mass_spec.time, current_N))
                    break

                if intensity < self.min_ms1_intensity:
                    self.logger.debug(
                        'Time %f Minimum intensity threshold %f reached at %f, %d'
                        % (self.mass_spec.time, self.min_ms1_intensity,
                           intensity, fragmented_count))
                    break

                # skip ion in the dynamic exclusion list of the mass spec
                if self.mass_spec.is_excluded(mz, rt):
                    continue

                if purity < self.purity_threshold:
                    purity_shift_amounts = [
                        self.purity_shift * (i - (self.n_purity_scans - 1) / 2)
                        for i in range(self.n_purity_scans)
                    ]
                    for purity_idx in range(self.n_purity_scans):
                        # send a new ms2 scan parameter to the mass spec
                        dda_scan_params = ScanParameters()
                        dda_scan_params.set(ScanParameters.MS_LEVEL, 2)
                        dda_scan_params.set(ScanParameters.N, current_N)

                        # create precursor object, assume it's all singly charged
                        precursor_charge = +1 if (
                            self.mass_spec.ionisation_mode == POSITIVE) else -1
                        precursor = Precursor(
                            precursor_mz=mz,
                            precursor_intensity=intensity,
                            precursor_charge=precursor_charge,
                            precursor_scan_id=self.last_ms1_scan.scan_id)
                        mz_lower = mz + purity_shift_amounts[
                            purity_idx] - current_isolation_window  # Da
                        mz_upper = mz + purity_shift_amounts[
                            purity_idx] + current_isolation_window  # Da
                        isolation_windows = [[(mz_lower, mz_upper)]]
                        dda_scan_params.set(ScanParameters.ISOLATION_WINDOWS,
                                            isolation_windows)
                        dda_scan_params.set(ScanParameters.PRECURSOR,
                                            precursor)

                        # save dynamic exclusion parameters too
                        dda_scan_params.set(
                            ScanParameters.DYNAMIC_EXCLUSION_MZ_TOL,
                            current_mz_tol)
                        dda_scan_params.set(
                            ScanParameters.DYNAMIC_EXCLUSION_RT_TOL,
                            current_rt_tol)

                        # push this dda scan parameter to the mass spec queue
                        self.mass_spec.add_task(dda_scan_params)
                        fragmented_count += 1
                        # need to work out what we want to do here
                else:
                    # send a new ms2 scan parameter to the mass spec
                    dda_scan_params = ScanParameters()
                    dda_scan_params.set(ScanParameters.MS_LEVEL, 2)
                    dda_scan_params.set(ScanParameters.N, current_N)

                    # create precursor object, assume it's all singly charged
                    precursor_charge = +1 if (self.mass_spec.ionisation_mode
                                              == POSITIVE) else -1
                    precursor = Precursor(
                        precursor_mz=mz,
                        precursor_intensity=intensity,
                        precursor_charge=precursor_charge,
                        precursor_scan_id=self.last_ms1_scan.scan_id)
                    mz_lower = mz - current_isolation_window  # Da
                    mz_upper = mz + current_isolation_window  # Da
                    isolation_windows = [[(mz_lower, mz_upper)]]
                    dda_scan_params.set(ScanParameters.ISOLATION_WINDOWS,
                                        isolation_windows)
                    dda_scan_params.set(ScanParameters.PRECURSOR, precursor)

                    # save dynamic exclusion parameters too
                    dda_scan_params.set(
                        ScanParameters.DYNAMIC_EXCLUSION_MZ_TOL,
                        current_mz_tol)
                    dda_scan_params.set(
                        ScanParameters.DYNAMIC_EXCLUSION_RT_TOL,
                        current_rt_tol)

                    # push this dda scan parameter to the mass spec queue
                    self.mass_spec.add_task(dda_scan_params)
                    fragmented_count += 1

            for param in self.mass_spec.get_task_queue():
                precursor = param.get(ScanParameters.PRECURSOR)
                if precursor is not None:
                    self.logger.debug('- %s' % str(precursor))

                # set this ms1 scan as has been processed
            self.last_ms1_scan = None
Beispiel #12
0
    def _update_parameters(self, scan):

        # if there's a previous ms1 scan to process
        if self.last_ms1_scan is not None:

            mzs = self.last_ms1_scan.mzs
            intensities = self.last_ms1_scan.intensities
            rt = self.last_ms1_scan.rt

            # loop over points in decreasing intensity
            fragmented_count = 0
            idx = np.argsort(intensities)[::-1]
            for i in idx:
                mz = mzs[i]
                intensity = intensities[i]

                # stopping criteria is after we've fragmented N ions or we found ion < min_intensity
                if fragmented_count >= self.N:
                    self.logger.debug(
                        'Time %f Top-%d ions have been selected' %
                        (self.mass_spec.time, self.N))
                    break

                if intensity < self.min_ms1_intensity:
                    self.logger.debug(
                        'Time %f Minimum intensity threshold %f reached at %f, %d'
                        % (self.mass_spec.time, self.min_ms1_intensity,
                           intensity, fragmented_count))
                    break

                # skip ion in the dynamic exclusion list of the mass spec
                if self.mass_spec.is_excluded(mz, rt):
                    continue

                # send a new ms2 scan parameter to the mass spec
                dda_scan_params = ScanParameters()
                dda_scan_params.set(ScanParameters.MS_LEVEL, 2)

                # create precursor object, assume it's all singly charged
                precursor_charge = +1 if (self.mass_spec.ionisation_mode
                                          == POSITIVE) else -1
                precursor = Precursor(
                    precursor_mz=mz,
                    precursor_intensity=intensity,
                    precursor_charge=precursor_charge,
                    precursor_scan_id=self.last_ms1_scan.scan_id)
                mz_lower = mz - self.isolation_window  # Da
                mz_upper = mz + self.isolation_window  # Da
                isolation_windows = [[(mz_lower, mz_upper)]]
                dda_scan_params.set(ScanParameters.ISOLATION_WINDOWS,
                                    isolation_windows)
                dda_scan_params.set(ScanParameters.PRECURSOR, precursor)

                # save dynamic exclusion parameters too
                dda_scan_params.set(ScanParameters.DYNAMIC_EXCLUSION_MZ_TOL,
                                    self.mz_tol)
                dda_scan_params.set(ScanParameters.DYNAMIC_EXCLUSION_RT_TOL,
                                    self.rt_tol)

                # push this dda scan parameter to the mass spec queue
                self.mass_spec.add_task(dda_scan_params)
                fragmented_count += 1

            for param in self.mass_spec.get_task_queue():
                precursor = param.get(ScanParameters.PRECURSOR)
                if precursor is not None:
                    self.logger.debug('- %s' % str(precursor))

                # set this ms1 scan as has been processed
            self.last_ms1_scan = None