Example #1
0
def window_sele_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.GCMS.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

    @return: The number of points in the window
    @rtype: IntType

    @author: Vladimir Likic
    """

    if not is_int(window_sele) and not is_str(window_sele):
        error("'window' must be 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
Example #2
0
def window_sele_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.GCMS.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

    @return: The number of points in the window
    @rtype: IntType

    @author: Vladimir Likic
    """

    if not is_int(window_sele) and not is_str(window_sele):
        error("'window' must be 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
Example #3
0
    def get_ic_at_index(self, ix):

        """
        @summary: Returns the ion chromatogram at the specified index

        @param ix: Index of an ion chromatogram in the intensity data
            matrix
        @type ix: IntType

        @return: Ion chromatogram at given index
        @rtype: IonChromatogram

        @author: Qiao Wang
        @author: Andrew Isaac
        @author: Vladimir Likic
        """

        if not is_int(ix):
            error("index not an integer")
        try:
            ia = []
            for i in range(len(self.__intensity_matrix)):
                ia.append(self.__intensity_matrix[i][ix])
        except IndexError:
            error("index out of bounds.")

        ic_ia = numpy.array(ia)
        mass = self.get_mass_at_index(ix)
        rt = copy.copy(self.__time_list) #JT: changed to copy form deep copy

        return IonChromatogram(ic_ia, rt, mass)
Example #4
0
    def get_ic_at_index(self, ix):

        """
        @summary: Returns the ion chromatogram at the specified index

        @param ix: Index of an ion chromatogram in the intensity data
            matrix
        @type ix: IntType

        @return: Ion chromatogram at given index
        @rtype: IonChromatogram

        @author: Qiao Wang
        @author: Andrew Isaac
        @author: Vladimir Likic
        """

        if not is_int(ix):
            error("index not an integer")
        try:
            ia = []
            for i in range(len(self.__intensity_matrix)):
                ia.append(self.__intensity_matrix[i][ix])
        except IndexError:
            error("index out of bounds.")

        ic_ia = numpy.array(ia)
        mass = self.get_mass_at_index(ix)
        rt = copy.deepcopy(self.__time_list)

        return IonChromatogram(ic_ia, rt, mass)
Example #5
0
def savitzky_golay(ic, window=__DEFAULT_WINDOW, \
        degree=__DEFAULT_POLYNOMIAL_DEGREE):

    """
    @summary: Applies Savitzky-Golay filter on ion chromatogram

    @param ic: The input ion chromatogram
    @type ic: pyms.GCMS.Class.IonChromatogram
    @param window: 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: IntType or StringType
    @param degree: degree of the fitting polynomial for the Savitzky-Golay
        filter
    @type degree: IntType

    @return: Smoothed ion chromatogram
    @rtype: pyms.GCMS.Class.IonChromatogram

    @author: Uwe Schmitt
    @author: Vladimir Likic
    """

    if not is_ionchromatogram(ic):
        error("'ic' not an IonChromatogram object")

    if not is_int(degree):
        error("'degree' not an integer")

    ia = ic.get_intensity_array()

    wing_length = ic_window_points(ic, window, half_window=True)

    #print " -> Applying Savitzky-Golay filter"
    #print "      Window width (points): %d" % ( 2*wing_length+1 )
    #print "      Polynomial degree: %d" % ( degree )

    coeff = __calc_coeff(wing_length, degree)
    ia_denoise = __smooth(ia, coeff)

    ic_denoise = copy.deepcopy(ic)
    ic_denoise.set_intensity_array(ia_denoise)

    return ic_denoise
Example #6
0
    def get_mass_at_index(self, ix):
        """
        @summary: Returns binned mass at index

        @param ix: Index of binned mass
        @type ix: IntType

        @return: Binned mass
        @rtype: IntType

        @author: Andrew Isaac
        """

        if not is_int(ix):
            error("index not an integer")

        if ix < 0 or ix >= len(self.__mass_list):
            error("index out of range")

        return self.__mass_list[ix]
Example #7
0
    def get_scan_at_index(self, ix):
        """
        @summary: Returns the spectral intensities for scan index

        @param ix: The index of the scan
        @type ix: IntType

        @return: Intensity values of scan spectra
        @rtype: ListType

        @author: Andrew Isaac
        """

        if not is_int(ix):
            error("index not an integer")

        if ix < 0 or ix >= len(self.__intensity_matrix):
            error("index out of range")

        return copy.deepcopy(self.__intensity_matrix[ix])
Example #8
0
    def get_ms_at_index(self, ix):
        """
        @summary: Returns a mass spectrum for a given scan index

        @param ix: The index of the scan
        @type ix: IntType

        @return: Mass spectrum
        @rtype: pyms.GCMS.Class.MassSpectrum

        @author: Andrew Isaac
        """

        # TODO: should a deepcopy be returned?

        if not is_int(ix):
            error("index not an integer")

        scan = self.get_scan_at_index(ix)

        return MassSpectrum(self.__mass_list, scan)
Example #9
0
    def get_time_at_index(self, ix):
        """
        @summary: Returns time at given index

        @param ix: An index
        @type ix: IntType

        @return: Time value
        @rtype: FloatType

        @author: Lewis Lee
        @author: Vladimir Likic
        """

        if not is_int(ix):
            error("index not an integer")

        if ix < 0 or ix > len(self.__time_list) - 1:
            error("index out of bounds")

        return self.__time_list[ix]
Example #10
0
    def get_intensity_at_index(self, ix):
        """
        @summary: Returns intensity at given index

        @param ix: An index
        @type ix: IntType

        @return: Intensity value
        @rtype: FloatType

        @author: Lewis Lee
        @author: Vladimir Likic
        """

        if not is_int(ix):
            error("index not an integer")

        if ix < 0 or ix > self.__ia.size - 1:
            error("index out of bounds")

        return self.__ia[ix]
Example #11
0
    def get_mass_at_index(self, ix):

        """
        @summary: Returns binned mass at index

        @param ix: Index of binned mass
        @type ix: IntType

        @return: Binned mass
        @rtype: IntType

        @author: Andrew Isaac
        """

        if not is_int(ix):
            error("index not an integer")

        if ix < 0 or ix >= len(self.__mass_list):
            error("index out of range")

        return self.__mass_list[ix]
Example #12
0
    def get_scan_at_index(self, ix):

        """
        @summary: Returns the spectral intensities for scan index

        @param ix: The index of the scan
        @type ix: IntType

        @return: Intensity values of scan spectra
        @rtype: ListType

        @author: Andrew Isaac
        """

        if not is_int(ix):
            error("index not an integer")

        if ix < 0 or ix >= len(self.__intensity_matrix):
            error("index out of range")

        return copy.deepcopy(self.__intensity_matrix[ix])
Example #13
0
    def set_ic_at_index(self, ix, ic):

        """
        @summary: Sets the ion chromatogram specified by index to a new
            value

        @param ix: Index of an ion chromatogram in the intensity data
            matrix to be set
        @type ix: IntType
        @param ic: Ion chromatogram that will be copied at position 'ix'
            in the data matrix
        @type: IonChromatogram

        The length of the ion chromatogram must match the appropriate
        dimension of the intensity matrix.

        @author: Vladimir Likic
        """

        if not is_int(ix):
            error("index not an integer")

        # this returns an numpy.array object
        ia = ic.get_intensity_array()

        # check if the dimension is ok
        if len(ia) != len(self.__intensity_matrix):
            error("ion chromatogram incompatible with the intensity matrix")
        else:
           N = len(ia)

        # Convert 'ia' to a list. By convention, the attribute
        # __intensity_matrix of the class IntensityMatrix is a list
        # of lists. This makes pickling instances of IntensityMatrix
        # practically possible, since pickling numpy.array objects
        # produces ten times larger files compared to pickling python
        #lists.
        ial = ia.tolist()
        for i in range(N):
            self.__intensity_matrix[i][ix] = ial[i]
Example #14
0
    def set_ic_at_index(self, ix, ic):

        """
        @summary: Sets the ion chromatogram specified by index to a new
            value

        @param ix: Index of an ion chromatogram in the intensity data
            matrix to be set
        @type ix: IntType
        @param ic: Ion chromatogram that will be copied at position 'ix'
            in the data matrix
        @type: IonChromatogram

        The length of the ion chromatogram must match the appropriate
        dimension of the intensity matrix.

        @author: Vladimir Likic
        """

        if not is_int(ix):
            error("index not an integer")

        # this returns an numpy.array object
        ia = ic.get_intensity_array()

        # check if the dimension is ok
        if len(ia) != len(self.__intensity_matrix):
            error("ion chromatogram incompatible with the intensity matrix")
        else:
           N = len(ia)

        # Convert 'ia' to a list. By convention, the attribute
        # __intensity_matrix of the class IntensityMatrix is a list
        # of lists. This makes pickling instances of IntensityMatrix
        # practically possible, since pickling numpy.array objects
        # produces ten times larger files compared to pickling python
        #lists.
        ial = ia.tolist()
        for i in range(N):
            self.__intensity_matrix[i][ix] = ial[i]
Example #15
0
    def get_time_at_index(self, ix):

        """
        @summary: Returns time at given index

        @param ix: An index
        @type ix: IntType

        @return: Time value
        @rtype: FloatType

        @author: Lewis Lee
        @author: Vladimir Likic
        """

        if not is_int(ix):
            error("index not an integer")

        if ix < 0 or ix > len(self.__time_list) - 1:
            error("index out of bounds")

        return self.__time_list[ix]
Example #16
0
    def get_ms_at_index(self, ix):

        """
        @summary: Returns a mass spectrum for a given scan index

        @param ix: The index of the scan
        @type ix: IntType

        @return: Mass spectrum
        @rtype: pyms.GCMS.Class.MassSpectrum

        @author: Andrew Isaac
        """

        # TODO: should a deepcopy be returned?

        if not is_int(ix):
            error("index not an integer")

        scan = self.get_scan_at_index(ix)

        return MassSpectrum(self.__mass_list, scan)
Example #17
0
    def get_intensity_at_index(self, ix):

        """
        @summary: Returns intensity at given index

        @param ix: An index
        @type ix: IntType

        @return: Intensity value
        @rtype: FloatType

        @author: Lewis Lee
        @author: Vladimir Likic
        """

        if not is_int(ix):
            error("index not an integer")

        if ix < 0 or ix > self.__ia.size - 1:
            error("index out of bounds")

        return self.__ia[ix]
Example #18
0
    def set_pt_bounds(self, pt_bounds):
        """
        @summary: Sets peak boundaries in points

        @param pt_bounds: A list containing left, apex, and right
            peak boundaries in points, left and right are offsets
        @type pt_bounds: ListType

        @return: none
        @rtype: NoneType
        """

        if not is_list(pt_bounds):
            error("'pt_bounds' must be a list")

        if not len(pt_bounds) == 3:
            error("'pt_bounds' must have exactly 3 elements")
        else:
            for item in pt_bounds:
                if not is_int(item):
                    error("'pt_bounds' element not an integer")

        self.__pt_bounds = pt_bounds
Example #19
0
    def set_pt_bounds(self, pt_bounds):

        """
        @summary: Sets peak boundaries in points

        @param pt_bounds: A list containing left, apex, and right
            peak boundaries in points, left and right are offsets
        @type pt_bounds: ListType

        @return: none
        @rtype: NoneType
        """

        if not is_list(pt_bounds):
            error("'pt_bounds' must be a list")

        if not len(pt_bounds) == 3:
            error("'pt_bounds' must have exactly 3 elements")
        else:
            for item in pt_bounds:
                if not is_int(item):
                    error("'pt_bounds' element not an integer")

        self.__pt_bounds = pt_bounds
Example #20
0
    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()
Example #21
0
    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()