Calculates the mass difference for alternative possible label states of a
    given peptide. See also :class:`LabelDescriptor`, :func:`returnLabelState()`


    :param peptide: Peptide to calculate alternative label states
    :param labelDescriptor: :class:`LabelDescriptor` describes the label setup
        of an experiment
    :param labelState: label state of the peptide, if None it is calculated by
        :func:`returnLabelState()`
    :param sequence: unmodified amino acid sequence of the "peptide", if None
        it is generated by :func:`maspy.peptidemethods.removeModifications()`

    :returns: {alternativeLabelSate: massDifference, ...} or {} if the peptide
        label state is -1.

    .. note:: The massDifference plus the peptide mass is the expected mass of
        an alternatively labeled peptide

def returnLabelStateMassDifferences(peptide, labelDescriptor, labelState=None,
                                    sequence=None):
    """Calculates the mass difference for alternative possible label states of a
    given peptide. See also :class:`LabelDescriptor`, :func:`returnLabelState()`


    :param peptide: Peptide to calculate alternative label states
    :param labelDescriptor: :class:`LabelDescriptor` describes the label setup
        of an experiment
    :param labelState: label state of the peptide, if None it is calculated by
        :func:`returnLabelState()`
    :param sequence: unmodified amino acid sequence of the "peptide", if None
        it is generated by :func:`maspy.peptidemethods.removeModifications()`

    :returns: {alternativeLabelSate: massDifference, ...} or {} if the peptide
        label state is -1.

    .. note:: The massDifference plus the peptide mass is the expected mass of
        an alternatively labeled peptide
    """
    if labelState is None:
        labelState = returnLabelState(peptide, labelDescriptor)
    if sequence is None:
        sequence = maspy.peptidemethods.removeModifications(peptide)

    if labelState < 0:
        # special case for mixed label... #
        return dict()

    # define type and number of labels of the peptide
    labelModNumbers = dict()
    _positions = expectedLabelPosition(peptide,
                                       labelDescriptor.labels[labelState],
                                       sequence=sequence)
    for labelStateModList in viewvalues(_positions):
        for labelMod in labelStateModList:
            labelModNumbers.setdefault(labelMod, int())
            labelModNumbers[labelMod] += 1

    # calculate the combined labels mass of the peptide
    labelMass = int()
    for labelMod, modCounts in viewitems(labelModNumbers):
        labelMass += maspy.constants.aaModMass[labelMod] * modCounts

    # calculate mass differences to all other possible label states
    labelStateMassDifferences = dict()
    for possibleLabelState in viewkeys(labelDescriptor.labels):
        if possibleLabelState == labelState:
            continue

        labelModNumbers = dict()
        _positions = expectedLabelPosition(peptide,
                                           labelDescriptor.labels[possibleLabelState],
                                           sequence=sequence)
        for labelStateModList in viewvalues(_positions):
            for labelMod in labelStateModList:
                labelModNumbers.setdefault(labelMod, int())
                labelModNumbers[labelMod] += 1

        possibleLabelMass = int()
        for labelMod, modCounts in viewitems(labelModNumbers):
            possibleLabelMass += maspy.constants.aaModMass[labelMod] * modCounts

        possibleLabelMassDifference = possibleLabelMass - labelMass
        labelStateMassDifferences[possibleLabelState] = possibleLabelMassDifference
    return labelStateMassDifferences