Exemple #1
0
    def updateSpinSystems(self):

        textMatrix = []
        objectList = []
        colorMatrix = []
        headingList = self.getHeadings()

        for spinSystem in self.getTentativeSpinSystems():

            residueText = None
            residue, probability = self.getProbableResidue(spinSystem)
            if residue:
                residueText = '%d%s' % (residue.seqCode,
                                        getResidueCode(residue))

            links = []
            color = '#D04040'

            if findConnectedSpinSystem(spinSystem, delta=-1):
                links.append('-1')

            if findConnectedSpinSystem(spinSystem, delta=1):
                links.append('+1')

            if len(links) == 2:
                color = '#40B040'
            elif len(links) == 1:
                color = '#B0B040'

            datum = []
            datum.append(spinSystem.serial)
            datum.append(residueText)
            datum.append(probability)
            datum.append(' '.join(links))

            self.addShiftData(spinSystem, datum)

            colors = [None] * len(headingList)
            colors[3] = color

            objectList.append(spinSystem)
            textMatrix.append(datum)
            colorMatrix.append(colors)

        if self.spinSystem not in objectList:
            self.spinSystem = None

        self.spinSystemMatrix.update(headingList=headingList,
                                     objectList=objectList,
                                     textMatrix=textMatrix,
                                     colorMatrix=colorMatrix)
        self.updateButtons()
        self.waiting = False
Exemple #2
0
    def getConnectedSpinSystems(self, spinSystem):

        if self.link == '-1':
            prevSS = findConnectedSpinSystem(spinSystem, delta=-1)
            nextSS = None
        elif self.link == '+1':
            prevSS = None
            nextSS = findConnectedSpinSystem(spinSystem, delta=1)
        else:
            prevSS = findConnectedSpinSystem(spinSystem, delta=-1)
            nextSS = findConnectedSpinSystem(spinSystem, delta=1)

        return prevSS, nextSS
Exemple #3
0
    def makeInterConstraints(self, resonances, constraintSet):

        from ccpnmr.analysis.core.ConstraintBasic import getFixedResonance
        from ccpnmr.analysis.core.AssignmentBasic import findConnectedSpinSystem

        project = constraintSet.root
        constraintList = constraintSet.newDistanceConstraintList()
        constraintList.name = 'Seq connections'

        resDict = {}
        spinSystemDict = {}
        for resonance in resonances:
            resDict[resonance] = True
            spinSystem = resonance.resonanceGroup
            if spinSystem:
                spinSystemDict[spinSystem] = None

        spinSystems = spinSystemDict.keys()

        for spinSystem in spinSystems:
            nextSpinSystem = findConnectedSpinSystem(spinSystem, delta=1)
            if nextSpinSystem:
                ca = spinSystem.newAtoms.get('CA')
                c = spinSystem.newAtoms.get('C')
                n = nextSpinSystem.newAtoms.get('N')

                if ca and c and n:
                    if resDict.get(ca) is None:
                        resonances.append(ca)
                    if resDict.get(c) is None:
                        resonances.append(c)
                    if resDict.get(n) is None:
                        resonances.append(n)

                    c_n = constraintList.newDistanceConstraint(
                        weight=1.0,
                        origData=1.0,
                        targetValue=1.32,
                        upperLimit=1.35,
                        lowerLimit=1.29,
                        error=0.06)

                    # below based on angle constraints
                    ca_n = constraintList.newDistanceConstraint(
                        weight=1.0,
                        origData=1.0,
                        targetValue=2.415,
                        upperLimit=2.513,
                        lowerLimit=2.316,
                        error=0.197)

                    frCa = getFixedResonance(constraintSet, ca)
                    frC = getFixedResonance(constraintSet, c)
                    frN = getFixedResonance(constraintSet, n)

                    item = ca_n.newDistanceConstraintItem(
                        resonances=[frCa, frN])
                    item = c_n.newDistanceConstraintItem(resonances=[frC, frN])

        return resonances, constraintList
Exemple #4
0
    def linkSpinSystems(self, spinSystems):

        data = []

        for spinSystem in spinSystems:
            residue, p = self.getProbableResidue(spinSystem)
            key = '%s%s%4.4d' % (residue.chain.molSystem.code,
                                 residue.chain.code, residue.seqCode)
            data.append([key, residue.seqCode, residue, spinSystem])

        data.sort()
        seqCodes = [x[1] for x in data]
        residues = [x[2] for x in data]
        spinSystems = [x[3] for x in data]

        N = len(data)
        for i in range(N):

            if i > 0:
                delta = seqCodes[i] - seqCodes[i - 1]
                if delta == 1 and (residues[i].chain is residues[i - 1].chain):
                    ss = findConnectedSpinSystem(spinSystems[i], delta=-1)
                    if ss:
                        mergeSpinSystems(
                            ss,
                            spinSystems[i -
                                        1])  # copy resonances across & delete

                    makeSeqSpinSystemLink(spinSystems[i - 1],
                                          spinSystems[i],
                                          delta=1)

            if i < N - 1:
                delta = seqCodes[i + 1] - seqCodes[i]
                if delta == 1 and (residues[i].chain is residues[i + 1].chain):
                    ss = findConnectedSpinSystem(spinSystems[i], delta=1)
                    if ss:
                        mergeSpinSystems(
                            ss,
                            spinSystems[i +
                                        1])  # copy resonances across & delete

                    makeSeqSpinSystemLink(spinSystems[i],
                                          spinSystems[i + 1],
                                          delta=1)

        self.updateSpinSystemsAfter()
Exemple #5
0
def networkAnchorAssign(peakLists,
                        intensityType='height',
                        strictness=2,
                        threshold=1.0,
                        isotopeTolerances=None,
                        assignPeakList=True,
                        constraintSet=None,
                        labelling=None,
                        minLabelFraction=0.1,
                        scale=None,
                        distParams=None,
                        structure=None,
                        progressBar=None,
                        nexus=None):

    if not peakLists:
        return

    if isotopeTolerances:
        TOLERANCE_DICT = isotopeTolerances

    distanceFunction = None
    if distParams:
        distanceFunction = lambda val: getNoeDistance(val, distParams)

    project = peakLists[0].root
    nmrProject = peakLists[0].topObject
    molSystem = project.findFirstMolSystem()
    shiftList = peakLists[0].dataSource.experiment.shiftList
    isotopes = set([])

    # Get known network of connectivities inc covalent and NOE
    network = {}
    covalent = {}

    # Assign some peaks with uniquely matching shifts
    for peakList in peakLists:
        if labelling is True:
            expLabelling = peakList.dataSource.experiment
        else:
            expLabelling = labelling

        network, covalent = getCloseSingleShiftMatches(
            peakList,
            network,
            covalent,
            labelling=expLabelling,
            minLabelFraction=minLabelFraction,
            intensityType=intensityType,
            progressBar=progressBar)

    # Get existing assigned NOE network
    totalPeaks = 0
    for peakList in peakLists:
        if not peakList.peaks:
            continue

        meanIntensity = getMeanPeakIntensity(peakList.peaks,
                                             intensityType=intensityType)
        if scale:
            meanIntensity = scale

        spectrum = peakList.dataSource
        distDims = getThroughSpaceDataDims(spectrum)
        for dataDim in distDims:
            isotopes.update(getDataDimIsotopes(dataDim))

        hDims = [dd.dim - 1 for dd in distDims]

        numPeaks = len(peakList.peaks)
        totalPeaks += numPeaks
        info = (spectrum.experiment.name, spectrum.name, peakList.serial,
                numPeaks)

        if progressBar:
            progressBar.setText(
                'Get existing NOE network\nfor %s:%s:%d - %d peaks' % info)
            progressBar.set(0)
            progressBar.total = numPeaks
            progressBar.open()
            progressBar.update_idletasks()

        else:
            print 'Get existing NOE network for %s:%s:%d - %d peaks' % info

        if len(hDims) != 2:
            continue

        for peak in peakList.peaks:
            if progressBar:
                progressBar.increment()

            peakDims = peak.sortedPeakDims()
            peakDim1 = peakDims[hDims[0]]
            contribs1 = peakDim1.peakDimContribs
            if contribs1:
                peakDim2 = peakDims[hDims[1]]
                contribs2 = peakDim2.peakDimContribs
                if contribs2:
                    peakIntensity = peak.findFirstPeakIntensity(
                        intensityType=intensityType)
                    if peakIntensity:
                        intensity = peakIntensity.value
                        intensity /= float(len(contribs1))
                        intensity /= float(len(contribs2))
                        #intensity /= meanIntensity

                        for contrib1 in contribs1:
                            resonance1 = contrib1.resonance
                            if network.get(resonance1) is None:
                                covalent[resonance1] = {}
                                network[resonance1] = {}

                            intensity2 = intensity
                            if resonance1.resonanceSet:
                                intensity2 /= float(
                                    len(resonance1.resonanceSet.
                                        findFirstAtomSet().atoms))

                            for contrib2 in contribs2:
                                resonance2 = contrib2.resonance
                                if network.get(resonance2) is None:
                                    network[resonance2] = {}
                                    covalent[resonance2] = {}

                                if resonance2.resonanceSet:
                                    intensity2 /= float(
                                        len(resonance2.resonanceSet.
                                            findFirstAtomSet().atoms))

                                if not contrib2.peakContribs:
                                    if not contrib1.peakContribs:
                                        network[resonance1][resonance2] = [
                                            intensity2, peak
                                        ]
                                        network[resonance2][resonance1] = [
                                            intensity2, peak
                                        ]

                                else:
                                    for peakContrib in contrib2.peakContribs:
                                        if peakContrib in contrib1.peakContribs:
                                            network[resonance1][resonance2] = [
                                                intensity2, peak
                                            ]
                                            network[resonance2][resonance1] = [
                                                intensity2, peak
                                            ]
                                            break

                    else:
                        pass  # Should warn

    covalentIntensity = 5.0  # Need to optimise this

    # Get covalent network
    if progressBar:
        progressBar.setText('Getting covalent network')
        progressBar.set(0)
        progressBar.total = len(nmrProject.resonances)
        progressBar.open()
        progressBar.update_idletasks()

    else:
        print 'Getting covalent network - %d resonances' % len(
            nmrProject.resonances)

    neighbours = {}
    chemAtomToAtom = {}

    c = 0
    for resonance in nmrProject.resonances:
        if progressBar:
            progressBar.increment()

        if resonance.isotopeCode not in isotopes:
            continue

        resonanceSet = resonance.resonanceSet
        if not resonanceSet:
            continue

        if network.get(resonance) is None:
            network[resonance] = {}
            covalent[resonance] = {}

        for atomSet in resonanceSet.atomSets:
            for atom in atomSet.atoms:
                residue = atom.residue

                if chemAtomToAtom.get(residue) is None:
                    chemAtomToAtom[residue] = {}
                    for atom2 in residue.atoms:
                        chemAtomToAtom[residue][atom2.chemAtom] = atom2

                chemAtom = atom.chemAtom
                if chemAtom.waterExchangeable:
                    continue

                chemAtoms = neighbours.get(chemAtom)

                if chemAtoms is None:
                    chemAtoms = []
                    for atom2 in residue.atoms:
                        if atom2 is atom:
                            continue

                        chemAtom2 = atom2.chemAtom
                        if DEFAULT_ISOTOPES.get(
                                chemAtom2.elementSymbol) not in isotopes:
                            continue

                        numBonds = getNumConnectingBonds(atom, atom2, limit=6)
                        if numBonds < 5:
                            chemAtoms.append(chemAtom2)

                    neighbours[chemAtom] = chemAtoms

                atoms = []
                for chemAtomB in chemAtoms:
                    atom2 = chemAtomToAtom[residue].get(chemAtomB)
                    if atom2 is not None:
                        atoms.append(atom2)

                residue2 = getLinkedResidue(residue, 'prev')
                if residue2:
                    for atom2 in residue2.atoms:
                        chemAtom2 = atom2.chemAtom
                        if DEFAULT_ISOTOPES.get(
                                chemAtom2.elementSymbol) not in isotopes:
                            continue

                        numBonds = getNumConnectingBonds(atom, atom2, limit=6)
                        if numBonds < 5:
                            atoms.append(atom2)

                residue2 = getLinkedResidue(residue, 'next')
                if residue2:
                    for atom2 in residue2.atoms:
                        chemAtom2 = atom2.chemAtom
                        if DEFAULT_ISOTOPES.get(
                                chemAtom2.elementSymbol) not in isotopes:
                            continue

                        numBonds = getNumConnectingBonds(atom, atom2, limit=6)
                        if numBonds < 5:
                            atoms.append(atom2)

                for atom2 in atoms:
                    atomSet2 = atom2.atomSet
                    if atomSet2 and (atomSet2 is not atomSet):
                        for resonanceSet2 in atomSet2.resonanceSets:
                            for resonance2 in resonanceSet2.resonances:
                                if network.get(resonance2) is None:
                                    network[resonance2] = {}
                                    covalent[resonance2] = {}

                                if network[resonance].get(
                                        resonance2
                                ) is None:  # Not already in network
                                    network[resonance][resonance2] = [
                                        covalentIntensity, None
                                    ]
                                    network[resonance2][resonance] = [
                                        covalentIntensity, None
                                    ]
                                    covalent[resonance][resonance2] = True
                                    covalent[resonance2][resonance] = True
                                    c += 1

    #print 'Atom pair network connections %d' % c

    c = 0
    for ss in nmrProject.resonanceGroups:
        ss2 = findConnectedSpinSystem(ss, delta=-1)
        if ss2:
            for r1 in ss.resonances:
                if r1.isotopeCode not in isotopes:
                    continue

                for r2 in ss.resonances:
                    if r2.isotopeCode not in isotopes:
                        continue

                    if network.get(r1) is None:
                        network[r1] = {}
                        covalent[r1] = {}
                    if network.get(r2) is None:
                        network[r2] = {}
                        covalent[r2] = {}

                    if network[r1].get(r2) is None:
                        network[r1][r2] = [covalentIntensity, None]
                        network[r2][r1] = [covalentIntensity, None]
                        covalent[r1][r2] = True
                        covalent[r2][r1] = True
                        c += 1

    #print 'Anonymous intra residue connections %d' % c

    done = {}
    iter = 0
    nAssign = 1
    k = 0
    dataSets = []
    while nAssign > 0:
        #while iter < 1:
        data = []

        nAssign = 0
        iter += 1

        if progressBar:
            progressBar.setText('Anchoring iteration %d' % iter)
            progressBar.set(0)
            progressBar.total = totalPeaks
            progressBar.open()
            progressBar.update_idletasks()
        else:
            print 'Anchoring iteration %d' % iter

        closeResonancesDict = {}

        for peakList in peakLists:
            if not peakList.peaks:
                continue

            spectrum = peakList.dataSource
            distDims = getThroughSpaceDataDims(spectrum)
            hDims = [dd.dim - 1 for dd in distDims]
            tolerances = getDimTolerances(spectrum)
            bondedDims = getBondedDimsDict(spectrum)
            #meanIntensity = getMeanPeakIntensity(peakList.peaks, intensityType=intensityType)

            info = (spectrum.experiment.name, spectrum.name, peakList.serial,
                    len(peakList.peaks))
            #print '  Using %s:%s:%d - %d peaks' % info
            if len(hDims) != 2:
                continue

            for peak in peakList.peaks:
                if progressBar:
                    progressBar.increment()

                if done.get(peak):
                    continue

                peakDims = peak.sortedPeakDims()

                if peakDims[hDims[0]].peakDimContribs:
                    if peakDims[hDims[1]].peakDimContribs:
                        continue

                boundResonances = {}

                if closeResonancesDict.get(peak) is None:
                    possibles = []
                    for dim in hDims:
                        peakDim = peakDims[dim]
                        if peakDim.peakDimContribs:
                            possibles.append([
                                contrib.resonance
                                for contrib in peakDim.peakDimContribs
                            ])
                            continue

                        resonances = []
                        shifts = findMatchingPeakDimShifts(
                            peakDim,
                            shiftRanges=None,
                            tolerance=tolerances[dim],
                            aliasing=True,
                            findAssigned=False)
                        dim2 = bondedDims.get(dim)
                        peakDim2 = None
                        if dim2 is not None:
                            peakDim2 = peakDims[dim2]
                            shifts2 = findMatchingPeakDimShifts(
                                peakDim2,
                                shiftRanges=None,
                                tolerance=tolerances[dim2],
                                aliasing=True,
                                findAssigned=False)

                            for shift in shifts:
                                resonance1 = shift.resonance
                                for shift2 in shifts2:
                                    resonance2 = shift2.resonance
                                    if areResonancesBound(
                                            resonance1, resonance2):
                                        if labelling:
                                            fraction = getResonancePairLabellingFraction(
                                                resonance1, resonance2,
                                                expLabelling)
                                            if fraction < minLabelFraction:
                                                continue

                                        resonances.append(resonance1)
                                        boundResonances[
                                            resonance1] = resonance2
                                        break

                        else:
                            for shift in shifts:
                                resonance = shift.resonance

                                if labelling:
                                    fraction = getResonanceLabellingFraction(
                                        resonance, expLabelling)

                                    if fraction < minLabelFraction:
                                        continue

                                resonances.append(resonance)

                        possibles.append(resonances)
                    closeResonancesDict[peak] = possibles

                else:
                    possibles = closeResonancesDict[peak]

                if not possibles[0]:
                    continue  # warn

                if not possibles[1]:
                    continue  # warn

                peakIntensity = peak.findFirstPeakIntensity(
                    intensityType=intensityType)
                if not peakIntensity:
                    print 'Peak missing intensity', peak
                    continue

                else:
                    intensity = peakIntensity.value  #/meanIntensity

                scores = {}
                numbers = {}

                bestScore = None
                bestPair = None
                for resonance1 in possibles[0]:
                    if not resonance1.resonanceGroup:
                        continue

                    if network.get(resonance1) is None:
                        continue

                    anchors1 = network[resonance1].keys()
                    spinSystem1 = resonance1.resonanceGroup

                    for resonance2 in possibles[1]:
                        if not resonance2.resonanceGroup:
                            continue

                        if network.get(resonance2) is None:
                            continue

                        anchors2 = network[resonance2].keys()
                        pair = (resonance1, resonance2)
                        spinSystem2 = resonance2.resonanceGroup

                        for resonance3 in anchors1:

                            spinSystem3 = resonance3.resonanceGroup
                            if (strictness > 0) and spinSystem3:
                                check = False
                                if (spinSystem3 is spinSystem1) or (
                                        spinSystem3 is spinSystem2):
                                    check = True

                                if (strictness > 1) and spinSystem3.residue:
                                    if spinSystem1.residue:
                                        if abs(spinSystem1.residue.seqCode -
                                               spinSystem3.residue.seqCode
                                               ) < 2:
                                            check = True

                                    if spinSystem2.residue:
                                        if abs(spinSystem2.residue.seqCode -
                                               spinSystem3.residue.seqCode
                                               ) < 2:
                                            check = True

                            else:
                                check = True

                            if check and (resonance3 in anchors2):
                                intensityA, peakA = network[resonance1][
                                    resonance3]
                                intensityB, peakB = network[resonance2][
                                    resonance3]

                                if scores.get(pair) is None:
                                    scores[pair] = 0.0
                                    numbers[pair] = 0.0

                                shift1 = resonance1.findFirstShift(
                                    parentList=shiftList)
                                shift2 = resonance2.findFirstShift(
                                    parentList=shiftList)

                                if shift1 and shift2:

                                    delta1 = abs(peakDims[hDims[0]].realValue -
                                                 shift1.value)
                                    delta2 = abs(peakDims[hDims[1]].realValue -
                                                 shift2.value)

                                    tol1 = TOLERANCE_DICT[
                                        resonance1.isotopeCode]
                                    tol2 = TOLERANCE_DICT[
                                        resonance2.isotopeCode]

                                    match1 = (tol1 - delta1) / tol1
                                    match2 = (tol2 - delta2) / tol2

                                    scores[
                                        pair] += intensityA * intensityB * match1 * match2
                                    numbers[pair] += 1

                nGood = 0
                for pair in scores.keys():
                    resonance1, resonance2 = pair

                    score = scores[pair]

                    if score > threshold:
                        nGood += 1

                    if (bestScore is None) or (score > bestScore):
                        bestScore = score
                        bestPair = pair

                #if bestScore and (nGood < 2):
                for pair in scores.keys():
                    resonance1, resonance2 = pair

                    if scores[pair] < threshold:
                        #if len(scores.keys()) > 1:
                        continue
                    else:
                        intensity2 = intensity / nGood

                    bestPair = pair
                    bestScore = scores[pair]

                    for i in (0, 1):
                        resonance = bestPair[i]

                        if assignPeakList:
                            assignResToDim(peakDims[hDims[i]],
                                           resonance,
                                           doWarning=False)

                            bound = boundResonances.get(resonance)
                            if bound:
                                dim2 = bondedDims.get(hDims[i])
                                if dim2 is not None:
                                    assignResToDim(peakDims[dim2],
                                                   bound,
                                                   doWarning=False)

                        if network.get(resonance) is None:
                            network[resonance] = {}

                    #name1 = makeResonanceGuiName(bestPair[0])
                    #name2 = makeResonanceGuiName(bestPair[1])

                    if resonance1.resonanceSet:
                        intensity2 /= float(
                            len(resonance1.resonanceSet.findFirstAtomSet().
                                atoms))
                    if resonance2.resonanceSet:
                        intensity2 /= float(
                            len(resonance2.resonanceSet.findFirstAtomSet().
                                atoms))

                    if labelling:
                        intensity2 /= getResonanceLabellingFraction(
                            resonance1, expLabelling)
                        intensity2 /= getResonanceLabellingFraction(
                            resonance2, expLabelling)

                    nAssign += 1

                    covalent[bestPair[0]][bestPair[1]] = None
                    covalent[bestPair[1]][bestPair[0]] = None
                    network[bestPair[0]][bestPair[1]] = [intensity2, peak]
                    network[bestPair[1]][bestPair[0]] = [intensity2, peak]
                    done[peak] = True

        #print '  Assigned:', nAssign
        dataSets.append(data)

    from ccpnmr.analysis.core.ConstraintBasic import getDistancesFromIntensity, getIntensityDistanceTable
    from ccpnmr.analysis.core.ConstraintBasic import makeNmrConstraintStore, getFixedResonance

    if constraintSet is None:
        constraintSet = makeNmrConstraintStore(nmrProject)

    if not constraintSet:
        return

    constraintList = constraintSet.newDistanceConstraintList()

    peakConstraints = {}
    doneResonances = {}
    for resonance1 in network.keys():
        fixedResonance1 = getFixedResonance(constraintSet, resonance1)

        for resonance2 in network[resonance1].keys():
            if resonance1 is resonance2:
                continue

            key = [resonance1.serial, resonance2.serial]
            key.sort()
            key = tuple(key)

            if doneResonances.get(key):
                continue
            else:
                doneResonances[key] = True

            if covalent.get(resonance1):
                if covalent[resonance1].get(resonance2):
                    # J connected are close so what do we do...?
                    #print "Skip", makeResonanceGuiName(resonance1), makeResonanceGuiName(resonance2)
                    continue

            fixedResonance2 = getFixedResonance(constraintSet, resonance2)
            intensity, peak = network[resonance1][resonance2]

            if peak:
                peakList = peak.peakList
                spectrum = peakList.dataSource
                experiment = spectrum.experiment

                if not distanceFunction:
                    noeDistClasses = getIntensityDistanceTable(spectrum)
                    distanceFunction = lambda val: getDistancesFromIntensity(
                        noeDistClasses, val)

                constraint = peakConstraints.get(peak)
                if not constraint:
                    constraint = constraintList.newDistanceConstraint(
                        weight=1.0, origData=intensity)
                    peakContrib = constraint.newConstraintPeakContrib(
                        experimentSerial=experiment.serial,
                        dataSourceSerial=spectrum.serial,
                        peakListSerial=peakList.serial,
                        peakSerial=peak.serial)
                    peakConstraints[peak] = constraint
                else:
                    intensity += constraint.origData

                dist, minDist, maxDist = distanceFunction(intensity /
                                                          meanIntensity)
                error = abs(maxDist - minDist)

                constraint.origData = intensity
                constraint.targetValue = dist
                constraint.upperLimit = maxDist
                constraint.lowerLimit = minDist
                constraint.error = error

                item = constraint.newDistanceConstraintItem(
                    resonances=[fixedResonance1, fixedResonance2])

    return constraintList
Exemple #6
0
def getInitialAssignMatrix(chain,
                           spinSystems,
                           peakLists,
                           shiftList,
                           keepExisting=False,
                           progressBar=None):

    if progressBar:
        progressBar.setText('Preparing Spin System Typing')
        progressBar.total = len(spinSystems)
        progressBar.set(0)
        progressBar.open()
        progressBar.parent.update_idletasks()

    peakListDict = {}
    for peakList in peakLists:
        peakListDict[peakList] = True

    allResidues = chain.sortedResidues()
    nResidues = len(allResidues)

    prolyl = []
    residues = []
    prevResidueDict = {}

    rMatrix = []
    for i, residue in enumerate(allResidues):
        row = [0.0] * nResidues

        if i + 1 < nResidues:
            row[i + 1] = 1.0

        rMatrix.append(row)

        prevResidueDict[residue] = getLinkedResidue(residue, 'prev')

        if residue.ccpCode in PROLYL:
            prolyl.append(i)
        else:
            residues.append(residue)

    prolyl.reverse()
    for row in rMatrix:
        for i in prolyl:
            del row[i]

    for i in prolyl:
        del rMatrix[i]

    nResidues = len(residues)
    nSpinSystems = len(spinSystems)

    #t0 = time.time()

    aMatrix = [[0] * nResidues for x in range(nSpinSystems)]

    for i, spinSystem in enumerate(spinSystems):
        #if hasattr(spinSystem, 'codeScoreDict'):
        #  del spinSystem.codeScoreDict

        if keepExisting:
            residueA = spinSystem.residue
            ccpCodeA = spinSystem.ccpCode

            if residueA and (residueA.chain is chain):
                for j, residue in enumerate(residues):
                    if residue is residueA:
                        score = 1.0
                    else:
                        score = 0.0

                    aMatrix[i][j] = score
                continue

            elif ccpCodeA:
                for j, residue in enumerate(residues):
                    if residue.ccpCode == ccpCodeA:
                        score = 1.0
                    else:
                        score = 0.0

                    aMatrix[i][j] = score
                continue

        shifts = []
        for resonance in spinSystem.resonances:
            for contrib in resonance.peakDimContribs:
                peak = contrib.peakDim.peak

                if peakListDict.get(peak.peakList):
                    shift = resonance.findFirstShift(parentList=shiftList)

                    if shift:
                        shifts.append(shift)
                        break

        scores = getShiftsChainProbabilities(shifts, chain)

        prevSpinSystem = findConnectedSpinSystem(spinSystem, delta=-1)
        if spinSystem.residue and not prevSpinSystem:
            residueB = getLinkedResidue(spinSystem.residue, linkCode='prev')
            nmrProject = spinSystem.topObject
            prevSpinSystem = nmrProject.findFirstResonanceGroup(
                residue=residueB)

        prevScores = None
        if prevSpinSystem:
            prevShifts = []
            for resonance in prevSpinSystem.resonances:
                for contrib in resonance.peakDimContribs:
                    peak = contrib.peakDim.peak

                    if peakListDict.get(peak.peakList):
                        shift = resonance.findFirstShift(parentList=shiftList)

                        if shift:
                            prevShifts.append(shift)
                            break

            prevSpinSystem.shifts = prevShifts
            prevScores = getShiftsChainProbabilities(prevShifts, chain)

        for j, residue in enumerate(residues):
            aMatrix[i][j] = scores[residue.ccpCode] or 1e-150
            prevResidue = prevResidueDict.get(residue)
            if prevResidue and prevScores:
                aMatrix[i][j] *= prevScores[prevResidue.ccpCode] or 1e-150
            else:
                aMatrix[i][j] *= aMatrix[i][j]

        if progressBar:
            progressBar.increment()

    #print "Time", time.time() - t0

    A = matrix(aMatrix)
    R = matrix(rMatrix)

    # Normalise per Spin System
    for s in xrange(A.shape[0]):
        A[s] /= A[s].max()

    # Normalise per Residue
    A = A.T
    for s in xrange(A.shape[0]):
        A[s] /= A[s].max()
    A = A.T

    A /= A.max()

    if progressBar:
        progressBar.close()

    return A, R, spinSystems, residues
def assignSpecNonRootResonances(rootPeaks,
                                targetPeakList,
                                tolerances=None,
                                diagTolerance=0.5,
                                waterMinPpm=4.88,
                                waterMaxPpm=4.92,
                                progressBar=None,
                                assignType=False,
                                refExpsCO=None):
    """Descrn: 
     Inputs: 
     Output: 
  """
    peaks, dimMapping = pickAssignSpecFromRoot(rootPeaks,
                                               targetPeakList,
                                               tolerances=tolerances,
                                               progressBar=progressBar,
                                               pickNew=False)

    spectrum = targetPeakList.dataSource
    targetDataDim = None
    rootDataDims = set()
    for dataDim in spectrum.dataDims:
        if dataDim.dim in dimMapping.values():
            rootDataDims.add(dataDim.dim)
        else:
            targetDataDim = dataDim

    if targetDataDim is None:
        msg = 'No non-root dimension found for %s:%s'
        showWarning('Failure', msg % (spectrum.experiment.name, spectrum.name))

    resonances = assignDimNewResonances(peaks,
                                        targetDataDim.dim,
                                        diagTolerance=diagTolerance,
                                        waterMinPpm=waterMinPpm,
                                        waterMaxPpm=waterMaxPpm,
                                        assignType=assignType)
    if not refExpsCO:
        refExps, refExpsCO = ExperimentBasic.getSeqAssignRefExperiments(
            targetPeakList.root)

    refExperiment = targetPeakList.dataSource.experiment.refExperiment

    if refExperiment in refExpsCO:
        resonances2 = set([r for r in resonances if not r.resonanceGroup])

        rootSpinSystems = set()
        for peak in peaks:
            for peakDim in peak.peakDims:
                if peakDim.dim in rootDataDims:
                    for contrib in peakDim.peakDimContribs:
                        spinSystem = contrib.resonance.resonanceGroup

                        if spinSystem:
                            rootSpinSystems.add(spinSystem)

        if len(rootSpinSystems) == 1:
            rootSpinSystem = rootSpinSystems.pop()
            prevSpinSystem = findConnectedSpinSystem(rootSpinSystem, delta=-1)

            if not prevSpinSystem:
                prevSpinSystem = rootSpinSystem.nmrProject.newResonanceGroup()
                makeSeqSpinSystemLink(prevSpinSystem, rootSpinSystem, delta=1)

            resonances2.update(prevSpinSystem.resonances)
            prevSpinSystem.setResonances(resonances2)
Exemple #8
0
def assignSpinSystemstoResidues(spinSystems,
                                residues,
                                strategy=None,
                                guiParent=None):
    ''' This method is somewhat different than multiple calls
        to assignmentBasic.assignSpinSystemResidue does.
        If you want to assign more spin systems in one go,
        you should prevent merging 2 spin systems A and B if
        B possibly needs to be assigned in a next iteration
        to another residue.
        Also multiple calls to assignmentBasic.assignSpinSystem
        would cause unnescesarry breaking of sequential links,
        because they don't fit the assignment temporarely.
        In this funtion, non-valid sequential links are only
        corrected after all assignments have been made.
        Also, present sequential links are ignored in this
        function, in the sense that linked spin systems are not
        automatically assigned to neighboring residues because
        they might conflict with the answer the annealing presented.
        Also no new sequential links are made.
        args:    spinSystems: list of spin systems
                 residues:    list of corrsponding residues
        kwargs:  strategy: what to do when if a spin systems
                           should be assigned to a residue that
                           already has a spin system assignment.
                           five possibilities:
                               1) None, in this case the user is
                                        asked every single time
                                        this happens.
                               2) 'skip', leave the old spin
                                          system assignment.
                               3) 'noMerge', assign but do not
                                   merge.
                               4) 'remove', remove old spin
                                            system assignment
                               4) 'merge', assign and merge.
                 guiParent: nescesarry to raise a popup to
                            ask for a merging strategy, only
                            important when strategy=None


        output: None
    '''

    #proposedSRdict = {}
    proposedRSdict = {}
    visitedSpinSystems = set()
    visitedResidues = set()
    deAssignedSpinSystems = set()

    # Determine the proposed mapping between spin systems and residues and
    # the other way around. Only a unique mapping between residues and
    # spin systems is used, because it is impossible to assign one spin
    # system to different residues.
    # Although it is technically possible to assign two spin systems
    # to one residue that is not what I want to do (unless there is already a
    # spin system assigned to the residue, in which case I'll ask what to do
    # with it.).

    for spinSystem, residue in set(zip(spinSystems, residues)):

        if not spinSystem or not residue:
            continue

        if spinSystem in visitedSpinSystems or residue in visitedResidues:

            proposedRSdict.pop(residue, None)
            continue

        proposedRSdict[residue] = spinSystem
        visitedSpinSystems.add(spinSystem)
        visitedResidues.add(residue)

    # Figuring out which of the spin systems assigned to the targetted
    #residues are not going to be shuffled around, they potentially have to get
    # merged or correct assignment might already be present
    assignSpinSystems = set(proposedRSdict.values())

    for residue, spinSystem in proposedRSdict.items():

        nonMovingSpinSystems = []
        placeHolderSpinSystems = []

        oldSpinSystems = residue.getResonanceGroups()

        for oldSpinSystem in oldSpinSystems:

            if oldSpinSystem is spinSystem or oldSpinSystem not in assignSpinSystems:

                if oldSpinSystem.resonances:

                    nonMovingSpinSystems.append(oldSpinSystem)

                else:

                    placeHolderSpinSystems.append(oldSpinSystem)

        if nonMovingSpinSystems:

            # The spin system is already assigned to the residue
            if spinSystem in nonMovingSpinSystems:

                continue

            else:

                tempStrategy = strategy or askToMergeSpinSystems(
                    residue,
                    spinSystem,
                    nonMovingSpinSystems + placeHolderSpinSystems,
                    guiParent=guiParent)
                # options are: 'merge','remove','noMerge','skip'

                if tempStrategy == 'skip':

                    continue

                elif tempStrategy == 'noMerge':

                    assignSpinSystemResidueMinimal(spinSystem, residue)

                elif tempStrategy == 'remove':

                    for oldSpinSystem in nonMovingSpinSystems:

                        assignSpinSystemResidueMinimal(oldSpinSystem, None)
                        deAssignedSpinSystems.add(oldSpinSystem)

                    assignSpinSystemResidueMinimal(spinSystem, residue)

                    for placeHolderSpinSystem in placeHolderSpinSystems:

                        mergeSpinSystems(placeHolderSpinSystem, spinSystem)

                elif tempStrategy == 'merge':

                    assignSpinSystemResidueMinimal(spinSystem, residue)

                    for oldSpinSystem in placeHolderSpinSystems + nonMovingSpinSystems:

                        mergeSpinSystems(oldSpinSystem, spinSystem)

        else:

            assignSpinSystemResidueMinimal(spinSystem, residue)

            for placeHolderSpinSystem in placeHolderSpinSystems:

                mergeSpinSystems(placeHolderSpinSystem, spinSystem)

    # Removing sequentials links that do not make sense any longer
    for spinSystem in assignSpinSystems.union(deAssignedSpinSystems):

        connectedSpinSystems = [
            findConnectedSpinSystem(spinSystem, delta=i) for i in (-1, 1)
        ]

        residue = spinSystem.getResidue()

        if residue:

            connectedResidues = [
                residue.chain.findFirstResidue(seqId=residue.seqId + i)
                for i in (-1, 1)
            ]

            for connectedResidue, connectedSpinSystem, i in zip(
                    connectedResidues, connectedSpinSystems, [-1, 1]):

                if connectedResidue:

                    assignedSpinSystems = connectedResidue.getResonanceGroups()

                    if connectedSpinSystem not in assignedSpinSystems:

                        clearSeqSpinSystemLinks(spinSystem, delta=i)

        else:

            for connectedSpinSystem, i in zip(connectedSpinSystems, [-1, 1]):

                if connectedSpinSystem:

                    connectedResidue = connectedSpinSystem.getResidue()

                    if connectedResidue:

                        residue = connectedResidue.chain.findFirstResidue(
                            seqId=residue.seqId + (i * -1))

                        if residue and residue.getResonanceGroups():

                            clearSeqSpinSystemLinks(spinSystem, delta=i)
Exemple #9
0
def linkSpinSystemInterIntraResonances(spinSystem,
                                       activeLists,
                                       tolerances=None):

    nmrProject = spinSystem.topObject
    prevSpinSystem = findConnectedSpinSystem(spinSystem)
    allowedRefExps, coRefExps = getSeqAssignRefExperiments(nmrProject.root)

    if not prevSpinSystem:
        if spinSystem.residue:
            residueB = getLinkedResidue(spinSystem.residue, linkCode='prev')
            prevSpinSystem = nmrProject.findFirstResonanceGroup(
                residue=residueB)

    if not prevSpinSystem:
        prevSpinSystem = nmrProject.newResonanceGroup()
        makeSeqSpinSystemLink(prevSpinSystem, spinSystem)

    peaks = []
    found = {}
    expTypes = {}
    linkDims = {}

    # go though the peaks associated with this spin system
    # within the selected peak lists
    # find the indirect, linking dimension
    for resonance in spinSystem.resonances:
        if resonance.isotopeCode != '15N':
            continue

        if not isResonanceAmide(resonance):
            continue

        for contrib in resonance.peakDimContribs:
            peakDim = contrib.peakDim
            peak = peakDim.peak

            if found.get(peak):
                continue

            peakList = peak.peakList
            if peakList not in activeLists:
                continue

            setupPeakHeight(peak)
            intensity = peak.findFirstPeakIntensity(intensityType='height')
            if not intensity:
                continue

            spectrum = peakList.dataSource
            expType = expTypes.get(peakList, spectrum.experiment.refExperiment)
            expTypes[peakList] = expType

            linkDim = linkDims.get(peakList)
            if linkDim is None:
                boundDict = {}
                for dataDimA, dataDimB in getOnebondDataDims(spectrum):
                    boundDict[dataDimA] = dataDimB
                    boundDict[dataDimB] = dataDimA

                dims = []
                for dataDim in spectrum.dataDims:
                    dataDimRef = getPrimaryDataDimRef(dataDim)

                    if not dataDimRef:
                        continue

                    isotopes = '/'.join(dataDimRef.expDimRef.isotopeCodes)
                    dims.append((isotopes, dataDim))

                dims.sort()
                for isotopes, dataDim in dims:
                    if '13C' == isotopes:
                        linkDim = (dataDim.dim, isotopes)
                        break

                    elif '1H' == isotopes:
                        dataDimB = boundDict.get(dataDim)

                        if dataDimB:
                            dataDimRefB = getPrimaryDataDimRef(dataDimB)

                            if '15N' in dataDimRefB.expDimRef.isotopeCodes:
                                continue

                        linkDim = (dataDim.dim, isotopes)
                        break

                linkDims[peakList] = linkDim

            if linkDim is None:
                continue

            if peakDim.dim is linkDim[0]:
                continue

            found[peak] = True
            peakDimL = peak.findFirstPeakDim(dim=linkDim[0])
            isotope = linkDim[1]

            peaks.append((peak, expType, peakDimL, isotope, intensity.value))

    peakTypes = []
    interResonances = {}
    intraResonances = {}
    for peak, expType, peakDim, isotope, height in peaks:

        ppm = peakDim.value
        atomType = None

        if expType in coRefExps:
            isInter = True
        elif 'N[coca]' in expType.name:
            isInter = False
        elif 'N_' in expType.name:
            isInter = False
        else:
            isInter = None

        resonance = None
        contrib = peakDim.findFirstPeakDimContrib()
        if contrib:
            resonance = contrib.resonance

            if isInter and resonance.assignNames:
                atomType = resonance.assignNames[0]
                interResonances[atomType] = (resonance, ppm, prevSpinSystem)

            if (isInter is False) and resonance.assignNames:
                atomType = resonance.assignNames[0]
                intraResonances[atomType] = (resonance, ppm, spinSystem)

        if not atomType:
            atomType = guessAtomType(expType, ppm, height)

        peakTypes.append((peakDim, atomType, contrib, isotope, isInter, ppm))

    # Get known inter/intra resonance assignments
    # for each atom type
    for peakDim, atomType, contrib, isotope, isInter, ppm in peakTypes:
        if isInter is None:
            continue
        elif isInter:
            resDict = interResonances
            uniqSpinSystem = prevSpinSystem
        else:
            resDict = intraResonances
            uniqSpinSystem = spinSystem

        if atomType:
            resonance, ppm2, ss = resDict.get(atomType, (None, None, None))

            if (resonance is None) and contrib:
                resDict[atomType] = (contrib.resonance, ppm, uniqSpinSystem)

    # Make any new assignments for the unambig peaks
    untypedIntra = []
    untypedInter = []
    for i, data in enumerate(peakTypes):
        (peakDim, atomType, contrib, isotope, isInter, ppm) = data

        if isInter is None:
            continue

        elif isInter:
            untyped = untypedInter
            resDict = interResonances
            uniqSpinSystem = prevSpinSystem

        else:
            resDict = intraResonances
            untyped = untypedIntra
            uniqSpinSystem = spinSystem

        if atomType:
            # Get any previously used resonances for this atom type
            resonance, ppm2, ss = resDict.get(atomType, (None, None, None))

            # If no prev resonance, look at the peak assignment
            if (not resonance) and contrib:
                resonance = contrib.resonance

            # Check to ensure that any existing resonance
            # is from the correct, this/prev spin system
            if resonance:
                spinSystem2 = resonance.resonanceGroup
                if spinSystem2 and (spinSystem2 is not uniqSpinSystem):
                    resonance = None

            # If no valid reasonance yet, check named ones
            # in the required spin system
            if not resonance:
                for resonance2 in uniqSpinSystem.resonances:
                    if atomType in resonance2.assignNames:
                        resonance = resonance2
                        break

            # If no valid resonance yet, make a new one
            if not resonance:
                resonance = nmrProject.newResonance(isotopeCode=isotope)

            # If peak dim is assigned to the wrong resonance
            # clear the assignment
            if contrib and contrib.resonance is not resonance:
                clearPeakDim(peakDim)
                contrib = None

            # Ensure the peak dim is assigned correctly
            if not contrib:
                assignResToDim(peakDim, resonance)

            # Check type of resonance set correctly
            if not resonance.assignNames:
                assignResonanceType(resonance, assignNames=(atomType, ))

            # Check spin system set correctly
            if resonance.resonanceGroup is not uniqSpinSystem:
                addSpinSystemResonance(uniqSpinSystem, resonance)

            # Store resonance by atom type, so that it can
            # be picked up later
            resDict[atomType] = (resonance, ppm, uniqSpinSystem)

        else:
            untyped.append((peakDim, contrib, isotope, isInter, ppm, i))

    uniqResonances = interResonances.values() + intraResonances.values()

    # Cluster untyped peaks
    interCluster = {}
    intraCluster = ()

    interData = (untypedInter, interCluster, prevSpinSystem)
    intraData = (untypedIntra, intraCluster, spinSystem)

    for untyped, clusters, uniqSpinSystem in (interData, intraData):

        for peakDim, contrib, isotope, isInter, ppm, i in untyped:

            if peakDim in clusters:
                continue

            if tolerances:
                tolerance = tolerances[isotope]
            else:
                tolerance = getAnalysisDataDim(peakDim.dataDim).assignTolerance

            if contrib:
                resonance = contrib.resonance
            else:
                resonance = None

            cluster = [peakDim]
            interCluster[peakDim] = True
            for peakDimB, contribB, isotopeB, isInterB, ppmB, i in untyped:
                if isotope != isotopeB:
                    continue

                if abs(ppmB - ppm) > tolerance:
                    continue

                if peakDim.peak.peakList == peakDimB.peak.peakList:
                    continue

                if contribB:
                    if not resonance:
                        resonance = contribB.resonance
                    if resonance is not contribB.resonance:
                        clearPeakDim(peakDimB)
                        assignResToDim(peakDimB,
                                       resonance,
                                       tolerance=tolerance)

                cluster.append(peakDimB)
                clusters[peakDimB] = True

            if not resonance:
                # Try to macth to any typed peaks
                for peakDimB, atomType, contribB, isotopeB, isInterB, ppmB in peakTypes:
                    if not contribB:
                        continue

                    if not atomType:
                        continue

                    if isotope != isotopeB:
                        continue

                    if abs(ppmB - ppm) > tolerance:
                        continue

                    if peakDim.peak.peakList == peakDimB.peak.peakList:
                        continue

                    resonance = contribB.resonance

                    # Set type for this peak
                    peakTypes[i] = (peakDim, atomType, contrib, isotope,
                                    isInter, ppm)
                    break

            if not resonance:
                resonance = nmrProject.newResonance(isotopeCode=isotope)

            for peakDimC in cluster:
                clearPeakDim(peakDimC)
                assignResToDim(peakDimC, resonance, tolerance=tolerance)

            uniqResonances.append((resonance, ppm, uniqSpinSystem))

            if resonance.resonanceGroup is not uniqSpinSystem:
                addSpinSystemResonance(uniqSpinSystem, resonance)

    # E.g. Find the HNCA peaks which best match the HNcoCA/iHNCA resonances
    matchDict = {}
    closestDict = {}
    for peakDim, atomType, contrib, isotope, isInter, ppm in peakTypes:
        if isInter is not None:
            # Not through HNcoCA or iHNCA
            continue

        if tolerances:
            tolerance = tolerances[isotope]
        else:
            tolerance = getAnalysisDataDim(peakDim.dataDim).assignTolerance

        matches = []
        shiftList = peakDim.peak.peakList.dataSource.experiment.shiftList
        for resonanceB, ppm2, uniqSpinSystem in uniqResonances:

            if resonanceB.isotopeCode != isotope:
                continue

            assignNames = resonanceB.assignNames
            if assignNames and (atomType not in assignNames):
                continue

            if not ppm2:
                shift = resonanceB.findFirstShift(parentList=shiftList)
                if not shift:
                    continue
                ppm2 = shift.value

            delta = abs(ppm - ppm2)
            prevDelta = closestDict.get(peakDim)
            if (prevDelta is None) or (delta < prevDelta):
                closestDict[peakDim] = delta

            if delta > tolerance:
                continue

            matches.append((delta, resonanceB, uniqSpinSystem))

        # Best match has smallest delta
        if matches:
            matches.sort()
            delta, resonance, uniqSpinSystem = matches[0]

            prevDelta, peakDimB, ss = matchDict.get(resonance,
                                                    (None, None, None))
            if not peakDimB or (delta < prevDelta):
                matchDict[resonance] = (delta, peakDim, uniqSpinSystem)

    uniqResonanceDict = {}
    for resonance in matchDict.keys():
        delta, peakDim, uniqSpinSystem = matchDict[resonance]
        uniqResonanceDict[peakDim] = resonance, uniqSpinSystem

    # E.g. go through HNCA peaks and assign to
    # HNcoCA or iHNCA resonances if required
    nonMatched = {}
    for peakDim, atomType, contrib, isotope, isInter, ppm in peakTypes:
        if isInter is not None:
            continue

        if closestDict.get(peakDim) is None:
            # No inter residue peaks at all
            intensity = peak.findFirstPeakIntensity(intensityType='height')

            if intensity:
                if not nonMatched.has_key(atomType):
                    nonMatched[atomType] = []
                nonMatched[atomType].append(
                    (-abs(intensity.value), peakDim, contrib, isotope))

            continue

        match = uniqResonanceDict.get(peakDim)
        if match:
            resonance, uniqSpinSystem = match

            if tolerances:
                tolerance = tolerances[isotope]
            else:
                tolerance = getAnalysisDataDim(peakDim.dataDim).assignTolerance

            # untyped through-carbonyl resonance can interit type
            # by matching typed peaks

            if atomType and not resonance.assignNames:
                resonance.addAssignName(atomType)

            # e.g. the HNcoCA resonance is the one to put on this HNCA peak
            if contrib:
                if contrib.resonance is not resonance:
                    clearPeakDim(peakDim)
                    assignResToDim(peakDim, resonance, tolerance=tolerance)
            else:
                assignResToDim(peakDim, resonance, tolerance=tolerance)

        else:
            # No match to an unambig peak
            # store to work out which is best for each atom type
            # e.g. just in case we have two intra residue CA possibilites
            if not nonMatched.has_key(atomType):
                nonMatched[atomType] = []

            nonMatched[atomType].append(
                (closestDict[peakDim], peakDim, contrib, isotope))

    for atomType in nonMatched.keys():

        if (atomType in intraResonances) and (atomType in interResonances):
            # Both resonances already found, peak is spurious
            continue

        if (atomType in intraResonances) and (atomType not in interResonances):
            # E.g. there was iHNCA but no HNcoCA
            otherSpinSystem = prevSpinSystem

        elif (atomType not in intraResonances) and (atomType
                                                    in interResonances):
            # E.g. there was HNcoCA but no iHNCA
            otherSpinSystem = spinSystem

        else:
            # No info
            continue

        peakDimList = nonMatched[atomType]
        peakDimList.sort()
        # Assume that if we have two possible ambiguous peaks
        # for any given atom type, then the one furthest from an
        # unambigous peak is the best to take
        deltaPpm, peakDim, contrib, isotope = peakDimList[-1]

        if tolerances:
            tolerance = tolerances[isotope]
        else:
            tolerance = getAnalysisDataDim(peakDim.dataDim).assignTolerance

        # E.g. this HNCA peak matches no HNcoCA/iHNCA resonances
        resonance = None
        if contrib:
            resonance = contrib.resonance

        if resonance:
            # Already have an assignment
            spinSystem2 = resonance.resonanceGroup
            if spinSystem2 is None:
                addSpinSystemResonance(otherSpinSystem, resonance)

            elif spinSystem2 is not otherSpinSystem:
                resonance = nmrProject.newResonance(isotopeCode=isotope)
                addSpinSystemResonance(otherSpinSystem, resonance)
                clearPeakDim(peakDim)
                contrib = assignResToDim(peakDim,
                                         resonance,
                                         tolerance=tolerance)

        else:
            # Needs a new assignment
            for resonance2 in otherSpinSystem.resonances:
                if atomType in resonance2.assignNames:
                    resonance = resonance2
                    break

            if not resonance:
                resonance = nmrProject.newResonance(isotopeCode=isotope)
                contrib = assignResToDim(peakDim,
                                         resonance,
                                         tolerance=tolerance)
                addSpinSystemResonance(otherSpinSystem, resonance)

        if not contrib:
            # Resonance has come from the spin system due to its atomTypes
            contrib = assignResToDim(peakDim,
                                     resonance,
                                     tolerance=2 * tolerance)

        if not contrib:
            # Existing resonance on spin system was too far away
            resonance = nmrProject.newResonance(isotopeCode=isotope)
            contrib = assignResToDim(peakDim, resonance, tolerance=tolerance)
            addSpinSystemResonance(otherSpinSystem, resonance)

        if atomType:
            assignNames = (atomType, )
        else:
            assignNames = []

        if not resonance.assignNames:
            assignResonanceType(resonance, assignNames=assignNames)
Exemple #10
0
def getSpinSystemInterIntraResonances(spinSystem, peakLists):

    nmrProject = spinSystem.nmrProject
    shiftLists = []

    for peakList in peakLists:
        spectrum = peakList.dataSource
        experiment = spectrum.experiment
        shiftLists.append(experiment.shiftList)

    interResonances = []
    intraResonances = []
    interPpms = []
    intraPpms = []
    interTypes = []
    intraTypes = []

    for resonance in spinSystem.resonances:
        if isResonanceAmide(resonance):
            continue

        if resonance.shifts:
            for contrib in resonance.peakDimContribs:
                peakList2 = contrib.peakDim.peak.peakList

                if peakList2 in peakLists:
                    assignName = '/'.join(resonance.assignNames)
                    intraResonances.append(resonance)
                    intraTypes.append(assignName)
                    break

    prevSpinSystem = findConnectedSpinSystem(spinSystem)
    if not prevSpinSystem:
        if spinSystem.residue:
            residueB = getLinkedResidue(spinSystem.residue, linkCode='prev')
            prevSpinSystem = nmrProject.findFirstResonanceGroup(
                residue=residueB)

    if prevSpinSystem:
        for resonance in prevSpinSystem.resonances:
            if isResonanceAmide(resonance):
                continue

            if resonance.shifts:
                for contrib in resonance.peakDimContribs:
                    peakList2 = contrib.peakDim.peak.peakList

                    if peakList2 in peakLists:
                        assignName = '/'.join(resonance.assignNames)
                        interResonances.append(resonance)
                        interTypes.append(assignName)
                        break

    inter = [interResonances, interPpms]
    intra = [intraResonances, intraPpms]

    for resonances, ppms in (inter, intra):
        for resonance in resonances:
            ppmSum = {}
            counts = {}

            for shiftList in shiftLists:
                ppmSum[shiftList] = 0.0
                counts[shiftList] = 0.0

            for shiftList in shiftLists:
                shift = resonance.findFirstShift(parentList=shiftList)

                if shift:
                    ppmSum[shiftList] += shift.value
                    counts[shiftList] += 1.0

            ppm = None
            if shiftLists:
                ppm = 0.0
                for shiftList in shiftLists:
                    n = counts[shiftList]

                    if n:
                        ppm += ppmSum[shiftList] / n

                ppm /= len(shiftLists)

            ppms.append(ppm)

    return interResonances, intraResonances, interPpms, intraPpms, interTypes, intraTypes
def assignSpinSystemstoResidues(spinSystems, residues,
                                strategy=None, guiParent=None):
    ''' This method is somewhat different than multiple calls
        to assignmentBasic.assignSpinSystemResidue does.
        If you want to assign more spin systems in one go,
        you should prevent merging 2 spin systems A and B if
        B possibly needs to be assigned in a next iteration
        to another residue.
        Also multiple calls to assignmentBasic.assignSpinSystem
        would cause unnescesarry breaking of sequential links,
        because they don't fit the assignment temporarely.
        In this funtion, non-valid sequential links are only
        corrected after all assignments have been made.
        Also, present sequential links are ignored in this
        function, in the sense that linked spin systems are not
        automatically assigned to neighboring residues because
        they might conflict with the answer the annealing presented.
        Also no new sequential links are made.
        args:    spinSystems: list of spin systems
                 residues:    list of corrsponding residues
        kwargs:  strategy: what to do when if a spin systems
                           should be assigned to a residue that
                           already has a spin system assignment.
                           five possibilities:
                               1) None, in this case the user is
                                        asked every single time
                                        this happens.
                               2) 'skip', leave the old spin
                                          system assignment.
                               3) 'noMerge', assign but do not
                                   merge.
                               4) 'remove', remove old spin
                                            system assignment
                               4) 'merge', assign and merge.
                 guiParent: nescesarry to raise a popup to
                            ask for a merging strategy, only
                            important when strategy=None


        output: None
    '''

    #proposedSRdict = {}
    proposedRSdict = {}
    visitedSpinSystems = set()
    visitedResidues = set()
    deAssignedSpinSystems = set()

    # Determine the proposed mapping between spin systems and residues and
    # the other way around. Only a unique mapping between residues and
    # spin systems is used, because it is impossible to assign one spin
    # system to different residues.
    # Although it is technically possible to assign two spin systems
    # to one residue that is not what I want to do (unless there is already a
    # spin system assigned to the residue, in which case I'll ask what to do
    # with it.).

    for spinSystem, residue in set(zip(spinSystems, residues)):

        if not spinSystem or not residue:
            continue

        if spinSystem in visitedSpinSystems or residue in visitedResidues:

            proposedRSdict.pop(residue, None)
            continue

        proposedRSdict[residue] = spinSystem
        visitedSpinSystems.add(spinSystem)
        visitedResidues.add(residue)

    # Figuring out which of the spin systems assigned to the targetted
    #residues are not going to be shuffled around, they potentially have to get
    # merged or correct assignment might already be present
    assignSpinSystems = set(proposedRSdict.values())

    for residue, spinSystem in proposedRSdict.items():

        nonMovingSpinSystems = []
        placeHolderSpinSystems = []

        oldSpinSystems = residue.getResonanceGroups()

        for oldSpinSystem in oldSpinSystems:

            if oldSpinSystem is spinSystem or oldSpinSystem not in assignSpinSystems:

                if oldSpinSystem.resonances:

                    nonMovingSpinSystems.append(oldSpinSystem)

                else:

                    placeHolderSpinSystems.append(oldSpinSystem)

        if nonMovingSpinSystems:

            # The spin system is already assigned to the residue
            if spinSystem in nonMovingSpinSystems:

                continue

            else:

                tempStrategy = strategy or askToMergeSpinSystems(residue,
                                spinSystem,
                                nonMovingSpinSystems + placeHolderSpinSystems,
                                guiParent=guiParent)
                # options are: 'merge','remove','noMerge','skip'

                if tempStrategy == 'skip':

                    continue

                elif tempStrategy == 'noMerge':

                    assignSpinSystemResidueMinimal(spinSystem, residue)

                elif tempStrategy == 'remove':

                    for oldSpinSystem in nonMovingSpinSystems:

                        assignSpinSystemResidueMinimal(oldSpinSystem, None)
                        deAssignedSpinSystems.add(oldSpinSystem)

                    assignSpinSystemResidueMinimal(spinSystem, residue)

                    for placeHolderSpinSystem in placeHolderSpinSystems:

                        mergeSpinSystems(placeHolderSpinSystem, spinSystem)

                elif tempStrategy == 'merge':

                    assignSpinSystemResidueMinimal(spinSystem, residue)

                    for oldSpinSystem in placeHolderSpinSystems + nonMovingSpinSystems:

                        mergeSpinSystems(oldSpinSystem, spinSystem)

        else:

            assignSpinSystemResidueMinimal(spinSystem, residue)

            for placeHolderSpinSystem in placeHolderSpinSystems:

                mergeSpinSystems(placeHolderSpinSystem, spinSystem)

    # Removing sequentials links that do not make sense any longer
    for spinSystem in assignSpinSystems.union(deAssignedSpinSystems):

        connectedSpinSystems = [
            findConnectedSpinSystem(spinSystem, delta=i) for i in (-1, 1)]

        residue = spinSystem.getResidue()

        if residue:

            connectedResidues = [
                residue.chain.findFirstResidue(seqId=residue.seqId + i) for i in (-1, 1)]

            for connectedResidue, connectedSpinSystem, i in zip(connectedResidues, connectedSpinSystems, [-1, 1]):

                if connectedResidue:

                    assignedSpinSystems = connectedResidue.getResonanceGroups()

                    if connectedSpinSystem not in assignedSpinSystems:

                        clearSeqSpinSystemLinks(spinSystem, delta=i)

        else:

            for connectedSpinSystem, i in zip(connectedSpinSystems, [-1, 1]):

                if connectedSpinSystem:

                    connectedResidue = connectedSpinSystem.getResidue()

                    if connectedResidue:

                        residue = connectedResidue.chain.findFirstResidue(
                            seqId=residue.seqId + (i * -1))

                        if residue and residue.getResonanceGroups():

                            clearSeqSpinSystemLinks(spinSystem, delta=i)