Exemple #1
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 #2
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
Exemple #3
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 #4
0
def autoBackboneNexus(chain,
                      spinSystems,
                      shiftList,
                      peakLists,
                      iterations=25,
                      varianceC=0.09,
                      varianceH=0.04,
                      keepExisting=False,
                      progressBar=None):

    #ss2 = [(ss.residue.seqCode, ss) for ss in spinSystems if ss.residue]
    #ss2.sort()
    #spinSystems = [x[1] for x in ss2]

    A, R, spinSystems, residues = getInitialAssignMatrix(
        chain, spinSystems, peakLists, shiftList, keepExisting, progressBar)
    if not iterations:
        return

    matrixIter = 400

    m, n = A.shape

    cMatrix = getConnectivityMatrix(spinSystems, peakLists, sqrt(varianceC),
                                    sqrt(varianceH), progressBar)

    C = matrix(cMatrix)
    C /= C.sum()

    #root = Tkinter.Tk()
    #availHeight = int(root.winfo_screenheight())
    #root.geometry('%dx%d' % (availHeight,availHeight))
    #root.grid_columnconfigure(0, weight=1)
    #root.grid_rowconfigure(0, weight=1)

    #xLabels = [(i+1) for i in range(m)]
    #yLabels = ['%3d %s' % (r.seqCode, r.chemCompVar.chemComp.code1Letter) for r in residues]
    #title = 'Assignment Matrix Refinement'
    #boxSize = (availHeight - 100.0)/len(yLabels)
    #graph = ScrolledDensityMatrix(root, matrix=M.tolist(), boxSize=boxSize, maxVal=None,
    #                              xLabels=xLabels, yLabels=yLabels, borderWidth=1,
    #                              borderColor='grey', zoom=1.0, title=title,
    #                              xAxisLabel='Spin Systems', yAxisLabel='Residues')

    #graph.grid(row=0, column=0, sticky='nsew')

    #return {}

    # Nexus matrix method

    B = matrixRefine(C, A, R, matrixIter, progressBar)

    # Resolve

    maxS = B.max()
    assign = {}
    scores = []
    for s in xrange(m):
        for r in xrange(n):
            scores.append((A[s, r] * B[s, r], s, r))

    scores.sort()
    scores2 = []

    assign = {}
    while scores:
        v, s, r = scores.pop()
        assign[r] = s
        i = 0
        scores2 = scores[:]
        scores2.reverse()
        for v2, s2, r2 in scores2:
            if i > 1:
                break
            if v2 / maxS < 0.001:
                break

            if r2 == r:
                i += 1

        scores = [x for x in scores if (x[1] != s) and (x[2] != r)]

    # Monte carlo

    A /= A.max()
    B /= B.max()
    C /= C.max()

    m, n = A.shape
    for r in xrange(n):
        if r not in assign:
            assign[r] = None

    sc = 0.0
    for r in assign:
        s = assign[r]
        if s is None:
            continue

        sc += A[s, r]
        r2 = r - 1
        s2 = assign.get(r2)

        if s2 is not None:
            sc += C[s2, s]

    e = 10
    ensemble = []
    for i in xrange(e):
        ensemble.append((sc, assign.copy()))

    if progressBar:
        progressBar.setText('Refinement')
        progressBar.total = iterations
        progressBar.set(0)
        progressBar.open()
        progressBar.parent.update_idletasks()

    n2 = n - 1
    nR = range(n)
    scBest = sc
    assignBest = assign.copy()

    multi = 1000
    i = multi * iterations
    I = float(i)
    t = i / e
    w = 5
    indices = range(n)

    if nR > w:
        for r in nR[:-w]:
            for r1 in range(r, r + w):
                s = assignBest[r1]
                if s is None:
                    break

                sc3 = 0.0

                s2 = assignBest.get(r1 - 1)
                if s2 is None:
                    break

                s3 = assignBest.get(r1 + 1)
                if s3 is None:
                    break

                sc3 = C[s2, s] + C[s, s3]
                if sc3 <= 1.0:
                    break

            else:
                for r1 in range(r, r + w):
                    if r1 in indices:
                        indices.remove(r1)
                        n2 -= 1

    while i:
        ensemble.sort()

        if i and (i % t == 0) and (len(ensemble) > 2):
            ensemble.pop(0)

        if i and (i % multi == 0):
            if i < I / 2:
                indices = range(n)
                n2 = n - 1

            if progressBar:
                progressBar.increment()

        if ensemble[-1][0] > scBest:
            scBest = ensemble[-1][0]
            assignBest = ensemble[-1][1].copy()
            print 'Best Score:', scBest

        randint(1, len(ensemble))
        scW, assignW = ensemble[0]
        sc, assign = ensemble[randint(1, len(ensemble) - 1)]

        rA = indices[randint(0, n2)]
        rB = rA
        while rA == rB:
            rB = indices[randint(0, n2)]

        assignB = assign.copy()
        sB = assignB[rB]
        assignB[rB] = assignB[rA]
        assignB[rA] = sB

        sc2 = 0.0
        for r in nR:
            s = assignB[r]
            if s is None:
                continue

            sc2 += A[s, r]

            r2 = r - 1
            s2 = assignB.get(r2)

            if s2 is not None:
                sc2 += C[s2, s]

        accept = scW - sc2
        if accept <= 0:
            ensemble[0] = (sc2, assignB)

        elif random() < (0.00001 / (accept * accept)):
            ensemble[0] = (sc2, assignB)

        else:
            ensemble[0] = (sc, assign.copy())
            i -= 1

    rAssign = {}

    if progressBar:
        progressBar.close()

    for r in assignBest:
        s = assignBest[r]

        if s is not None:
            ss = set([
                s,
            ])
            residue = residues[r]
            rAssign[residue] = [1.0, [
                spinSystems[s],
            ]]

            for sc2, assign2 in ensemble:
                s3 = assign2[r]

                if (s3 is not None) and (s3 not in ss):
                    ss.add(s3)

                    if len(ss) < 3:
                        rAssign[residue][1].append(spinSystems[s3])

            #rAssign[residue][0] /= len(ss)

    # Scale by connectivity score
    conns = [1.0] * n
    for i in range(n):
        residue = residues[i]
        prev = getLinkedResidue(residue, 'prev')
        next = getLinkedResidue(residue, 'next')

        connPrev = 0.5
        connNext = 0.5

        if prev and (prev.ccpCode in PROLYL):
            connPrev = 0.8

        else:
            spinSystemsA = rAssign.get(prev)
            spinSystemsB = rAssign.get(residue)

            if spinSystemsA and spinSystemsB:
                spinSystemA = spinSystemsA[1][0]
                spinSystemB = spinSystemsB[1][0]
                connPrev = getSpinSystemLikelihood(spinSystemA, spinSystemB,
                                                   peakLists)

        if next and (next.ccpCode in PROLYL):
            connNext = 0.8

        else:
            spinSystemsB = rAssign.get(residue)
            spinSystemsC = rAssign.get(next)

            if spinSystemsB and spinSystemsC:
                spinSystemB = spinSystemsB[1][0]
                spinSystemC = spinSystemsC[1][0]
                connNext = getSpinSystemLikelihood(spinSystemB, spinSystemC,
                                                   peakLists)

        conns[i] = connPrev * connNext

    for i, residue in enumerate(residues):
        if rAssign.get(residue):
            #rAssign[residue][0] = conns[i]
            rAssign[residue][0] *= conns[i]

    return rAssign
Exemple #5
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