def sele_peaks_by_rt(peaks: Union[Sequence, numpy.ndarray], rt_range: Sequence[str]) -> Peak: """ Selects peaks from a retention time range :param peaks: A list of peak objects :type peaks: list or tuple or numpy.ndarray :param rt_range: A list of two time strings, specifying lower and upper retention times :type rt_range: ~collections.abc.Sequence[str] :return: A list of peak objects :rtype: :class:`list` of :class:`pyms.Peak.Class.Peak` """ if not is_peak_list(peaks): raise TypeError("'peaks' must be a Sequence of Peak objects") if not is_sequence(rt_range): raise TypeError("'rt_range' must be a Sequence") else: if len(rt_range) != 2: raise ValueError("'rt_range' must have exactly two elements") if not isinstance(rt_range[0], str) or not isinstance( rt_range[1], str): raise TypeError( "lower/upper retention time limits must be strings") rt_lo = time_str_secs(rt_range[0]) rt_hi = time_str_secs(rt_range[1]) if rt_lo >= rt_hi: raise ValueError("lower retention time limit must be less than upper") peaks_sele = [] for peak in peaks: rt = peak.rt if rt_lo < rt < rt_hi: peaks_sele.append(peak) # print("%d peaks selected" % (len(peaks_sele))) return peaks_sele
def sele_peaks_by_rt(peaks, rt_range): """ @summary: Selects peaks from a retention time range @param peaks: A list of peak objects @type peaks: ListType @param rt_range: A list of two time strings, specifying lower and upper retention times @type rt_range: ListType @return: A list of peak objects @rtype: ListType """ if not is_peak_list(peaks): error("'peaks' not a peak list") if not is_list(rt_range): error("'rt_range' not a list") else: if len(rt_range) != 2: error("'rt_range' must have exactly two elements") if not is_str(rt_range[0]) or not is_str(rt_range[1]): error("lower/upper retention time limits must be strings") rt_lo = time_str_secs(rt_range[0]) rt_hi = time_str_secs(rt_range[1]) if not rt_lo < rt_hi: error("lower retention time limit must be less than upper") peaks_sele = [] for peak in peaks: rt = peak.get_rt() if rt > rt_lo and rt < rt_hi: peaks_sele.append(peak) # print "%d peaks selected" % (len(peaks_sele)) return peaks_sele
def ic_window_points(ic: IonChromatogram, window_sele: Union[int, str], half_window: bool = False): """ Converts the window selection parameter into points based on the time step in an ion chromatogram. :param ic: ion chromatogram object relevant for the conversion :type ic: pyms.IO.Class.IonChromatogram :param window_sele: The window selection parameter. This can be an integer or time string. If integer, taken as the number of points. If a string, must of the form "<NUMBER>s" or "<NUMBER>m", specifying a time in seconds or minutes, respectively :type window_sele: int or str :param half_window: Specifies whether to return half-window :type half_window: bool, optional :author: Vladimir Likic """ if not isinstance(window_sele, (int, str)): raise TypeError("'window_sele' must be either an integer or a string") if isinstance(window_sele, int): if half_window: if window_sele % 2 == 0: raise ValueError("window must be an odd number of points") else: points = int(math.floor(window_sele * 0.5)) else: points = window_sele else: time = time_str_secs(window_sele) time_step = ic.time_step if half_window: time = time * 0.5 points = int(math.floor(time / time_step)) if half_window: if points < 1: raise ValueError(f"window too small (half window={points:d})") else: if points < 2: raise ValueError(f"window too small (window={points})") return points
def ic_window_points(ic, window_sele, half_window=False): """ @summary: Converts window selection parameter into points based on the time step in an ion chromatogram @param ic: ion chromatogram object relevant for the conversion @type ic: pyms.IO.Class.IonChromatogram @param window_sele: The window selection parameter. This can be an integer or time string. If integer, taken as the number of points. If a string, must of the form "<NUMBER>s" or "<NUMBER>m", specifying a time in seconds or minutes, respectively @type window_sele: IntType or StringType @param half_window: Specifies whether to return half-window @type half_window: Booleantype @author: Vladimir Likic """ if not is_int(window_sele) and not is_str(window_sele): error("'window' must be either an integer or a string") if is_int(window_sele): if half_window: if window_sele % 2 == 0: error("window must be an odd number of points") else: points = int(math.floor(window_sele*0.5)) else: points = window_sele else: time = time_str_secs(window_sele) time_step = ic.get_time_step() if half_window: time = time*0.5 points = int(math.floor(time/time_step)) if half_window: if points < 1: error("window too small (half window=%d)" % (points)) else: if points < 2: error("window too small (window=%d)" % (points)) return points
def ic_window_points(ic, window_sele, half_window=False): """ @summary: Converts window selection parameter into points based on the time step in an ion chromatogram @param ic: ion chromatogram object relevant for the conversion @type ic: pyms.IO.Class.IonChromatogram @param window_sele: The window selection parameter. This can be an integer or time string. If integer, taken as the number of points. If a string, must of the form "<NUMBER>s" or "<NUMBER>m", specifying a time in seconds or minutes, respectively @type window_sele: IntType or StringType @param half_window: Specifies whether to return half-window @type half_window: Booleantype @author: Vladimir Likic """ if not is_int(window_sele) and not is_str(window_sele): error("'window' must be either an integer or a string") if is_int(window_sele): if half_window: if window_sele % 2 == 0: error("window must be an odd number of points") else: points = int(math.floor(window_sele * 0.5)) else: points = window_sele else: time = time_str_secs(window_sele) time_step = ic.get_time_step() if half_window: time = time * 0.5 points = int(math.floor(time / time_step)) if half_window: if points < 1: error("window too small (half window=%d)" % (points)) else: if points < 2: error("window too small (window=%d)" % (points)) return points
def trim(self, begin=None, end=None): """ @summary: trims data in the time domain @param begin: begin parameter designating start time or scan number @type begin: IntType or StrType @param end: end parameter designating start time or scan number @type end: IntType or StrType The arguments 'begin' and 'end' can be either integers (in which case they are taken as the first/last scan number for trimming) or strings in which case they are treated as time strings and converted to scan numbers. At present both 'begin' and 'end' must be of the same type, either both scan numbers or time strings. @author: Vladimir Likic """ # trim called with defaults, or silly arguments if begin == None and end == None: print "Nothing to do." return # exit immediately N = len(self.__scan_list) # process 'begin' and 'end' if begin == None: first_scan = 0 elif is_int(begin): first_scan = begin-1 elif is_str(begin): time = time_str_secs(begin) first_scan = self.get_index_at_time(time) + 1 else: error("invalid 'begin' argument") if end == None: last_scan = N-1 elif is_int(end): last_scan = end elif is_str(end): time = time_str_secs(end) last_scan = self.get_index_at_time(time) + 1 else: error("invalid 'end' argument") # sanity checks if not last_scan > first_scan: error("last scan=%d, first scan=%d" % (last_scan, first_scan)) elif first_scan < 0: error("scan number must be greater than one") elif last_scan > N-1: error("last scan=%d, total number of scans=%d" % (last_scan, N)) print "Trimming data to between %d and %d scans" % \ (first_scan+1, last_scan+1) scan_list_new = [] time_list_new = [] for ii in range(len(self.__scan_list)): if ii >= first_scan and ii <= last_scan: scan = self.__scan_list[ii] time = self.__time_list[ii] scan_list_new.append(scan) time_list_new.append(time) # update info self.__scan_list = scan_list_new self.__set_time(time_list_new) self.__set_min_max_mass() self.__calc_tic()
def trim( self, begin: Optional[IntStr] = None, end: Optional[IntStr] = None, ): """ Trims data in the time domain. The arguments ``begin`` and ``end`` can be either integers (in which case they are taken as the first/last scan number for trimming) or strings in which case they are treated as time strings and converted to scan numbers. At present both ``begin`` and ``end`` must be of the same type, either both scan numbers or time strings. At least one of ``begin`` and ``end`` is required. :param begin: The start time or scan number :param end: The end time or scan number :author: Vladimir Likic """ # trim called with defaults, or silly arguments if begin is None and end is None: raise SyntaxError("At least one of 'begin' and 'end' is required") N = len(self._scan_list) # process 'begin' and 'end' if begin is None: first_scan = 0 elif isinstance(begin, (int, signedinteger)): first_scan = cast(int, begin) - 1 elif isinstance(begin, str): time = time_str_secs(begin) scan_ = self.get_index_at_time(time) if scan_ is None: raise TypeError("invalid 'begin' argument") first_scan = scan_ + 1 else: raise TypeError("invalid 'begin' argument") if end is None: last_scan = N - 1 elif isinstance(end, (int, signedinteger)): last_scan = cast(int, end) elif isinstance(end, str): time = time_str_secs(end) scan_ = self.get_index_at_time(time) if scan_ is None: raise TypeError("invalid 'end' argument") last_scan = scan_ + 1 else: raise TypeError("invalid 'end' argument") # sanity checks if not last_scan > first_scan: raise ValueError( f"last scan={last_scan:d}, first scan={first_scan:d}") elif first_scan < 0: raise ValueError("scan number must be greater than one") elif last_scan > N - 1: raise ValueError( f"last scan={last_scan:d}, total number of scans={N:d}") print( f"Trimming data to between {first_scan + 1:d} and {last_scan + 1:d} scans" ) scan_list_new = [] time_list_new = [] for ii in range(len(self._scan_list)): if first_scan <= ii <= last_scan: scan = self._scan_list[ii] time = self._time_list[ii] scan_list_new.append(scan) time_list_new.append(time) # update info self._scan_list = scan_list_new self._time_list = time_list_new self._set_time() self._set_min_max_mass() self._calc_tic()