Example #1
0
    def setRawDistanceConstraintItemMembers(self):

        itemResonances = getResonancesFromPairwiseConstraintItem(self.item)

        atomSerialList = []

        for i in range(2):

            resonance = itemResonances[i]

            if resonance in self.resonanceToAtomSerial.keys():
                atomSerials = self.resonanceToAtomSerial[resonance]

            else:

                atomSerials = []
                resonanceToAtoms = self.resonanceToAtoms[resonance]

                for resonanceToAtom in resonanceToAtoms:

                    atom = resonanceToAtom.getAtom()
                    atomSerial = self.getAtomSerial(atom)

                    if atomSerial == None:
                        print "  Error: no atom serial for atom '{}.{}.{}, aborting this constraint.'".format(
                            atom.residue.chain.code, atom.residue.seqCode,
                            atom.name)
                        atomSerials = []
                        break

                    atomSerials.append(atomSerial)

            atomSerialList.append(atomSerials)
            atomSerialList[-1].sort()

        #
        # Now make all combinations...
        #

        for atomSerial1 in atomSerialList[0]:
            for atomSerial2 in atomSerialList[1]:

                atomSerialComb = (atomSerial1, atomSerial2)

                if atomSerialComb in self.atomSerialCombs:
                    continue
                else:
                    self.atomSerialCombs.append(atomSerialComb)

                self.rawConstraint.items.append(self.rawConstraintItemClass())
                self.rawConstraint.items[-1].members.append(
                    self.rawConstraintItemMemberClass(atomSerial1))
                self.rawConstraint.items[-1].members.append(
                    self.rawConstraintItemMemberClass(atomSerial2))
Example #2
0
def setLocalSumContribs(resIndex,sideCodes,item,resAtomDict,swap,resAtomSwapDict,atomCoordDict,prochiralResonancesDict,prochiralAvgSum,avgSum):

  sideCode = sideCodes[resIndex]

  itemResonances = getResonancesFromPairwiseConstraintItem(item)
  
  resonance = itemResonances[resIndex]
  atomList = resAtomDict[resonance]

  if swap and resAtomSwapDict.has_key(resonance):
    atomList = resAtomSwapDict[resonance]

  for atom in atomList:

    if atomCoordDict.has_key(atom):

      otherResonance = itemResonances[not resIndex]
      otherAtomLists = [resAtomDict[otherResonance]]

      if resAtomSwapDict.has_key(otherResonance):
        otherAtomLists.append(resAtomSwapDict[otherResonance])

      avgLocalSums = [0.0,0.0]

      for i in range(0,len(otherAtomLists)):       

        otherAtomList = otherAtomLists[i]

        for otherAtom in otherAtomList:
          if atom != otherAtom and atomCoordDict.has_key(otherAtom) and atomCoordDict[atom] and atomCoordDict[otherAtom]:

            avgSumContrib = 1.0 / math.pow(getDistanceFromCoordinates(atomCoordDict[atom],atomCoordDict[otherAtom]),6)
            avgLocalSums[i] += avgSumContrib
      
      #
      # Pick the largest average local sum: is the smallest distance!!
      #
      
      if avgLocalSums[0] < avgLocalSums[1]:
        avgLocalSum = avgLocalSums[1]
      else:
        avgLocalSum = avgLocalSums[0]

      avgSum[sideCode] += avgLocalSum

      if avgLocalSum:
        if resonance in prochiralResonancesDict.keys():
          prochiralKey = prochiralResonancesDict[resonance]             

          if not prochiralAvgSum[sideCode].has_key(prochiralKey):
            prochiralAvgSum[sideCode][prochiralKey] = [0.00,[]]
          prochiralAvgSum[sideCode][prochiralKey][0] += avgLocalSum
          prochiralAvgSum[sideCode][prochiralKey][1].append(item)
Example #3
0
    def setRawRdcConstraintItemMembers(self):

        itemResonances = getResonancesFromPairwiseConstraintItem(self.item)

        for i in range(0, 2):

            (chainCode, seqCode, spinSystemId, seqInsertCode,
             atomName) = getNameInfo(self.resSetNames[i])
            resLabel = self.getResonanceResLabel(itemResonances[i])

            self.rawConstraintItem.members.append(
                self.rawConstraintItemMemberClass(chainCode, seqCode, resLabel,
                                                  atomName))
Example #4
0
    def setRawDistanceConstraintItemMembers(self):

        itemResonances = getResonancesFromPairwiseConstraintItem(self.item)

        for i in range(0, 2):

            resonance = itemResonances[i]

            resLabel = self.getResonanceResLabel(resonance)

            (chainCode, seqCode, spinSystemId, seqInsertCode,
             atomName) = getNameInfo(self.resSetNames[i])

            if atomName == allResidueAtoms_kw:
                print "  Error: not handling residue level constraints for %s." % self.format
                continue

            self.rawConstraintItem.members.append(
                self.rawConstraintItemMemberClass(chainCode, seqCode, resLabel,
                                                  atomName))
Example #5
0
    def getPseudoCorrection(self, constraint, pseudoCorrections):

        constraintItems = constraint.sortedItems()

        #
        # Can only really do pseudocorrection on unambiguous item,
        # or on multiple items that designate an atom set...
        #

        resonanceList = []

        for consItem in constraintItems:
            resonanceList.append(
                getResonancesFromPairwiseConstraintItem(consItem))

        atomsForPseudoCorrection = []

        residueList = []

        #print constraint.serial

        for i in range(2):

            chemAtomSets = []
            deepChemAtomSets = []
            atomNames = []

            useAtomSetName = None

            if len(resonanceList) > 1:
                checkForSets = True
            else:
                checkForSets = False

            for resonances in resonanceList:
                resonance = resonances[i]

                if self.resObjectMapping.has_key(resonance):
                    (residue, atomList) = self.resObjectMapping[resonance]
                else:
                    useAtomSetName = checkForSets = False
                    atomNames = []
                    break

                if len(atomList) > 1:
                    checkForSets = True

                residueList.append(residue)

                atomNames.append(atomList[0].name)

                chemAtomSet = deepChemAtomSet = None

                chemAtom = atomList[0].chemAtom
                if chemAtom.chemAtomSet:
                    chemAtomSet = chemAtom.chemAtomSet.name

                    if chemAtom.chemAtomSet.chemAtomSet:
                        deepChemAtomSet = chemAtom.chemAtomSet.chemAtomSet.name

                chemAtomSets.append(chemAtomSet)
                deepChemAtomSets.append(deepChemAtomSet)

            # First check if got multiple 'deep' chemAtomSets
            if not deepChemAtomSets.count(None) and checkForSets:
                if deepChemAtomSets.count(
                        deepChemAtomSets[0]) == len(deepChemAtomSets):
                    useAtomSetName = deepChemAtomSets[0]
            if not chemAtomSets.count(None) and checkForSets:
                if chemAtomSets.count(chemAtomSets[0]) == len(chemAtomSets):
                    # Note that this will reset HG* to HG1*, for example, if this is the only
                    # one that occurs!
                    useAtomSetName = chemAtomSets[0]
            if (not checkForSets
                    or not useAtomSetName) and atomNames and atomNames.count(
                        atomNames[0]) == len(atomNames):
                useAtomSetName = atomNames[0]

            #print "    %d" % i, chemAtomSets, deepChemAtomSets, atomNames

            atomsForPseudoCorrection.append(useAtomSetName)

        #print "  ",atomsForPseudoCorrection

        if residueList and len(residueList) == residueList.count(
                residueList[0]):
            intraResidue = True
            #print "  intrares, %s" % residueList[0].ccpCode
        else:
            intraResidue = False
            #print "  interres, %s-%s" % (residueList[0].ccpCode,residueList[-1].ccpCode)

        #
        # Now check if have to apply correction...
        #

        pseudoCorrection = 0.0

        if None not in atomsForPseudoCorrection and len(resonanceList) == 2:

            for i in range(2):
                resonance = resonanceList[0][i]
                if pseudoCorrections.has_key(resonance):

                    if type(pseudoCorrections[resonance]) == type(0.0):
                        pseudoCorrection += pseudoCorrections[resonance]

                    # Now handle Wuthich exceptions...
                    elif pseudoCorrections[resonance].has_key(
                            atomsForPseudoCorrection[i]):
                        corrInfo = pseudoCorrections[resonance][
                            atomsForPseudoCorrection[i]]

                        if intraResidue and corrInfo[1].has_key(
                                atomsForPseudoCorrection[not i]):
                            pseudoCorrection += corrInfo[1][
                                atomsForPseudoCorrection[not i]]
                        else:
                            pseudoCorrection += corrInfo[0]

        return pseudoCorrection
Example #6
0
    def recalibrateConstraints(
            self,
            nmrConstraintStore,
            structures,
            pseudo='Wuthrich',
            saveResults=True,
            ensembleAverage='median',  # Can be 'median', 'average', or 'NOE'. Last one is r-6 average
            classify=[],
            fout=sys.stdout,
            correlationMethod='spearman'):
        """
    
    Recalibrates a set of distance constraint lists based on a set of coordinates.
    
    Input:
    
     args:
      nmrConstraintStore: A CCPN Nmr.NmrConstraintStore (NOTE THIS WILL BE MODIFIED IF SAVERESULTS IS TRUE!)
      structures:         A list of CCPN MolSystem.Models
     
     keywds:
      pseudo:       'Wuthrich' to use Wuthrich pseudo atom corrections
                    'Generic' to use generic pseudo atom corrections (based on CONCOORD ones)
      saveResults:  Boolean. Write out the results (or not)
      classify:     Set to ['atomType'] for using bb,sc atom classifications in calibration.
      fout:         File handle to write result information to.
  
    Output:
    
      None (except for writing outFile and possibly new data to CCPN project)
        
    """

        from pdbe.analysis.Stats import getCorrelation

        #
        # Initialise some stuff
        #

        invSixth = -1.0 / 6.0
        fixedResonances = nmrConstraintStore.sortedFixedResonances()

        #
        # Check if pseudo correction info OK
        #

        if pseudo == 'Wuthrich':
            pseudoCorrections = getPseudoCorrectionsWuthrich(fixedResonances)
        elif pseudo == 'Generic':
            pseudoCorrections = getPseudoCorrections(fixedResonances)
        else:
            print "  ERROR: Unrecognized pseudo correction system '%s' - aborting."
            return

        #
        # Write header
        #

        if classify:
            classifyString = ", classification by '%s'" % str(classify)
        else:
            classifyString = ""

        headerLine = " # Recalibrating constraints, based on '%s', ensemble averaging '%s'%s. #\n" % (
            pseudo, ensembleAverage, classifyString)
        headerFrameLine = " %s\n" % ("#" * (len(headerLine) - 1))

        fout.write("\n")
        fout.write(headerFrameLine)
        fout.write(headerLine)
        fout.write(headerFrameLine)
        fout.write("\n")

        #
        # Set up dict for resonance->atom links
        #

        self.setAssignedAtomsAndResidues(
            fixedResonances)  # From ResonanceCoordinateHandler class!

        #
        # Set up reference info for structure coords
        #

        self.structureList = list(structures)

        numStructures = len(self.structureList)
        if numStructures == 1:
            fout.write("  Warning: only one structure used in analysis!\n")

        self.createCoordAtomInfoDict(
        )  # From ResonanceCoordinateHandler class!

        #
        # Now go over the constraint lists, handle 1 by 1...
        #

        allDistanceConstraintLists = []

        for constraintList in nmrConstraintStore.sortedConstraintLists():
            if constraintList.className == 'DistanceConstraintList':
                allDistanceConstraintLists.append(constraintList)

        for dcl in allDistanceConstraintLists:

            dclConstraints = dcl.sortedConstraints()
            constraintKeys = []

            distances = []
            targetDistances = []
            targetCorrected = []
            upperDistances = []
            upperCorrected = []

            distanceClasses = []
            pseudoDistances = []
            pseudoTargetDistances = []
            pseudoTargetCorrectedDistances = []
            pseudoUpperDistances = []
            pseudoUpperCorrectedDistances = []

            if not classify:
                coordinateVolumeSum = {'all': 0.0}
            else:
                coordinateVolumeSum = {}

            for constraint in dclConstraints:

                distPerStruc = []
                atomCombs = []
                atomTypes = []

                for strucIndex in range(numStructures):
                    distPerStruc.append([])

                hasDistance = False
                pseudoCorrection = self.getPseudoCorrection(
                    constraint, pseudoCorrections)
                """           
        if dcl.serial == 9 and constraint.serial in [6,7,8,9]:
          print "  ", constraint.serial
          #print "    ",constraint.sortedItems()
          #print "    ", distPerStruc
          #print "    ", ["%s.%d.%s-%s.%d.%s" % (atomComb[0].residue.ccpCode,atomComb[0].residue.seqId,atomComb[0].name,atomComb[1].residue.ccpCode,atomComb[1].residue.seqId,atomComb[1].name)  for atomComb in atomCombs]
        """

                for item in constraint.sortedItems():
                    (resonance, otherResonance
                     ) = getResonancesFromPairwiseConstraintItem(item)

                    if self.resObjectMapping.has_key(
                            resonance) and self.resObjectMapping.has_key(
                                otherResonance):
                        (residue, atomList) = self.resObjectMapping[resonance]
                        (otherResidue,
                         otherAtomList) = self.resObjectMapping[otherResonance]
                        """           
            if dcl.serial == 9 and constraint.serial in [6,7,8,9]:
              print "    ", residue, atomList
              print "    ", otherResidue,otherAtomList
            """

                        # Set the atom type
                        if 'atomType' in classify:
                            atomContactType = []

                            for atomRefName in (atomList[0].name,
                                                otherAtomList[0].name):
                                atomType = getAtomPositionType(atomRefName)
                                atomContactType.append(atomType)

                            atomContactType.sort()
                            atomContactType = tuple(atomContactType)
                            if not atomContactType in atomTypes:
                                atomTypes.append(atomContactType)

                        # Get distance info...
                        for atom in atomList:
                            if self.coordAtomInfo.has_key(atom):
                                for otherAtom in otherAtomList:
                                    if atom == otherAtom:
                                        continue

                                    atomComb = (atom, otherAtom)

                                    # Only count each contribution once!!
                                    if atomComb in atomCombs or (
                                            atomComb[1],
                                            atomComb[0]) in atomCombs:
                                        continue

                                    atomCombs.append(atomComb)

                                    if self.coordAtomInfo.has_key(otherAtom):
                                        hasDistance = True
                                        for strucIndex in range(numStructures):
                                            coord = self.coordAtomInfo[atom][
                                                strucIndex]
                                            otherCoord = self.coordAtomInfo[
                                                otherAtom][strucIndex]

                                            if coord and otherCoord:
                                                distance = getDistanceFromCoordinates(
                                                    coord, otherCoord)
                                                distPerStruc[
                                                    strucIndex].append(
                                                        distance)

                if not hasDistance:
                    continue

                #
                # Take average based on median, straight average or NOE average (r-6)
                #

                overallDistSum = 0.0
                tempDistTotal = 0.0
                numDistZero = 0
                tempDistanceList = []

                for strucIndex in range(numStructures):
                    distSum = 0.0
                    for distance in distPerStruc[strucIndex]:
                        distSum += math.pow(distance, -6)

                    if distSum:
                        if ensembleAverage == 'NOE':
                            # This is correct
                            overallDistSum += distSum
                        else:
                            tempDist = math.pow(distSum, invSixth)
                            tempDistanceList.append(tempDist)
                            tempDistTotal += tempDist
                    else:
                        numDistZero += 1

                # TODO: here aim 'lower' than actual target distance? Aymeric can do this himself though...
                # Not implemented currently
                numDistances = numStructures - numDistZero

                if not numDistances:
                    continue

                if ensembleAverage == 'NOE':
                    overallDistSum = overallDistSum / numDistances
                    avgDist = math.pow(overallDistSum, invSixth)

                else:
                    numDistances = len(tempDistanceList)
                    # TODO ARE THERE GOOD BUILTIN PYTHON FUNCIONS FOR THIS?
                    if ensembleAverage == 'median':
                        tempDistanceList.sort()
                        middleIndex = int(numDistances / 2)
                        if numDistances % 2 == 0:
                            avgDist = (tempDistanceList[middleIndex - 1] +
                                       tempDistanceList[middleIndex]) / 2
                        else:
                            avgDist = tempDistanceList[middleIndex]
                    elif ensembleAverage == 'average':
                        avgDist = tempDistTotal / numDistances
                    else:
                        avgDist = 0.0

                    overallDistSum = math.pow(avgDist, -6)
                """           
        if dcl.serial == 9 and constraint.serial in [6,7,8,9]:
          print "  ", avgDist
          print
        """

                #
                # Now set the information
                #

                if not classify:
                    classType = 'all'
                elif 'atomType' in classify:
                    atomTypes.sort()
                    atomTypes = tuple(atomTypes)
                    classType = atomTypes
                    # TODO Need to add other types if necessary, also combine info...
                    if not coordinateVolumeSum.has_key(classType):
                        coordinateVolumeSum[classType] = 0.0

                coordinateVolumeSum[classType] += overallDistSum

                distances.append(avgDist)
                constraintKeys.append(constraint.getFullKey())

                if pseudoCorrection:
                    pseudoDistances.append(avgDist)

                #
                # Get the restraint distance info
                #

                if constraint.targetValue:
                    targetValue = constraint.targetValue
                else:
                    targetValue = 0.0

                distanceClasses.append(classType)
                targetDistances.append(targetValue)
                targetCorrected.append(targetValue - pseudoCorrection)

                if constraint.upperLimit:
                    upperLimit = constraint.upperLimit
                else:
                    upperLimit = 0.0

                upperDistances.append(upperLimit)
                upperCorrected.append(upperLimit - pseudoCorrection)

                if pseudoCorrection:
                    pseudoTargetDistances.append(targetValue)
                    pseudoTargetCorrectedDistances.append(targetValue -
                                                          pseudoCorrection)
                    pseudoUpperDistances.append(upperLimit)
                    pseudoUpperCorrectedDistances.append(upperLimit -
                                                         pseudoCorrection)

                    #print residue.ccpCode, atomList[0].name, otherResidue.ccpCode, otherAtomList[0].name, avgDist, upperLimit, pseudoCorrection

            #
            # TODO: also check number of values that are available? If only a couple (out of 1000s), then don't use that one!
            #

            fout.write("Constraint list %s, with %d distances.\n" %
                       (dcl.serial, len(distances)))
            if not distances:
                fout.write("  No distances - ignored.\n")
                continue

            fout.write("  Correlations by %s method:\n" % correlationMethod)

            targetCorr = getCorrelation(distances,
                                        targetDistances,
                                        correlationMethod=correlationMethod)
            fout.write("    All target distances, as is: %.4f.\n" % targetCorr)
            upperCorr = getCorrelation(distances,
                                       upperDistances,
                                       correlationMethod=correlationMethod)
            """           
      print distances[0], distances[-1], upperDistances[0], upperDistances[-1]
      if dcl.serial == 9:
        print
        print distances
        print
      """

            fout.write("    All upper distances, as is:  %.4f.\n" % upperCorr)

            if targetCorr > upperCorr:
                selectText = "Selecting target distances as best option"
                useDistances = targetDistances
                distType = 'target'

            elif 0 < upperCorr < 1:

                pseudoUpperCorr = 0.0

                if pseudoDistances:
                    pseudoUpperCorr = getCorrelation(
                        distances,
                        upperCorrected,
                        correlationMethod=correlationMethod)
                    fout.write(
                        "    All upper distances, pseudo corrected:  %.4f\n" %
                        pseudoUpperCorr)

                if not pseudoUpperCorr or pseudoUpperCorr < upperCorr:
                    selectText = "Selecting upper bounds as best option"
                    useDistances = upperDistances
                    distType = 'upper'
                else:
                    selectText = "Selecting pseudo corrected upper bounds as best option"
                    useDistances = upperCorrected
                    distType = 'pseudo'

            else:

                # TODO THIS IS NOT GOOD - just copy over original list as is? Or what?!?!?
                # Info will now go missing - check where this happens!

                fout.write("  Ignoring list - no valid distances.\n\n")
                continue

            fout.write("%s\n\n\n" % selectText)

            newConstraintList = NmrConstraint.DistanceConstraintList.getByKey(
                nmrConstraintStore, (dcl.serial, ))
            newConstraintList.details = selectText

            newConstraintList.addApplicationData(
                Implementation.AppDataString(application='ConstraintsHandler',
                                             keyword='distType',
                                             value=distType))

            #
            # Now create a new list, with recalculated target distances
            #

            volumes = []
            volumeSum = {}
            for classType in coordinateVolumeSum.keys():
                volumeSum[classType] = 0.0

            for distIndex in range(len(useDistances)):
                useDistance = useDistances[distIndex]
                classType = distanceClasses[distIndex]
                if useDistance:
                    volume = math.pow(useDistance, -6)
                else:
                    volume = 0.0
                volumeSum[classType] += volume
                volumes.append((volume, classType))

            correctionFactor = {}
            for classType in volumeSum.keys():
                correctionFactor[classType] = coordinateVolumeSum[
                    classType] / volumeSum[classType]

                if type(classType) == type(""):
                    classTypeString = classType
                else:
                    classTypeString = ','.join([
                        "%s-%s" % classTypeItem for classTypeItem in classType
                    ])

                newConstraintList.addApplicationData(
                    Implementation.AppDataFloat(
                        application='ConstraintsHandler',
                        keyword='correctionFactor_%s' % classTypeString,
                        value=correctionFactor[classType]))

            for i in range(0, len(volumes)):
                (volume, classType) = volumes[i]

                if volume:
                    newDistance = math.pow(
                        volume * correctionFactor[classType], invSixth)
                else:
                    # This is the default value
                    newDistance = 1.8

                # Consistency check
                if newDistance < 1.8:
                    newDistance = 1.8

                #
                # Change the relevant constraint...
                #

                constraintKey = constraintKeys[i][1:]
                newConstraint = NmrConstraint.DistanceConstraint.getByKey(
                    nmrConstraintStore, constraintKey)

                newConstraint.targetValue = newDistance

                # Do some consistency checks...
                if not newConstraint.weight:
                    newConstraint.weight = 1.0

                if not newConstraint.lowerLimit or not newConstraint.upperLimit:
                    correction = 0.125 * (newConstraint.targetValue**2)

                    if not newConstraint.lowerLimit:
                        lowerLimit = newConstraint.targetValue - correction
                        if lowerLimit < 1.8:
                            lowerLimit = 1.8
                        newConstraint.lowerLimit = lowerLimit

                    if not newConstraint.upperLimit:
                        newConstraint.upperLimit = newConstraint.targetValue + correction

        if saveResults:
            # TODO will this take care of everything?
            nmrConstraintStore.root.saveModified()

        return nmrConstraintStore
Example #7
0
    for distConstr in ccpnConstraintList.sortedConstraints():

        print "Constraint %d: %.1f-%.1f" % (
            distConstr.serial, distConstr.lowerLimit, distConstr.upperLimit)

        for constrItem in distConstr.sortedItems():

            #
            # Now list the atoms linked to each of the two resonances associated with
            # this item.
            #

            atomList = []

            resonanceList = getResonancesFromPairwiseConstraintItem(constrItem)

            for resonance in resonanceList:
                atomList.append([])
                if resonance.resonanceSet:
                    for atomSet in resonance.resonanceSet.atomSets:
                        for atom in atomSet.atoms:
                            atomList[-1].append(
                                "%d.%s" % (atom.residue.seqCode, atom.name))

                atomList[-1].sort()
                atomList[-1] = ','.join(atomList[-1])

            print "   (%s) - (%s)" % (atomList[0], atomList[1])

        print
Example #8
0
    def setRawDistanceConstraintItemMembers(self):

        #
        # Expand the information... is necessary for Concoord (only handles individual atoms)
        #

        atomNameLists = []

        for i in range(0, 2):

            atomNameLists.append([])

            resonanceToAtom = self.ccpInfo[i][3]
            chemAtomOrigName = self.ccpInfo[i][2]

            if resonanceToAtom.chemAtomSet:
                chemAtomOrSet = resonanceToAtom.chemAtomSet
            else:
                chemAtomOrSet = resonanceToAtom.chemAtom

            if chemAtomOrSet:

                chemCompVar = resonanceToAtom.getResidue().chemCompVar
                namingSystem = chemCompVar.chemComp.findFirstNamingSystem(
                    name=self.namingSystemName)
                if namingSystem:
                    chemAtomSysName = findChemAtomSysName(
                        namingSystem, {'sysName': chemAtomOrigName})
                else:
                    chemAtomSysName = None

                if chemAtomSysName:
                    chemAtom = chemCompVar.findFirstChemAtom(
                        name=chemAtomSysName.atomName,
                        subType=chemAtomSysName.atomSubType)
                else:
                    chemAtom = chemCompVar.findFirstChemAtom(
                        name=chemAtomOrigName)

                if not chemAtom:

                    chemAtomSetSysName = findChemAtomSetSysName(
                        namingSystem, {'sysName': chemAtomOrigName})

                    if chemAtomSetSysName:
                        chemAtomSet = chemCompVar.findFirstChemAtomSet(
                            name=chemAtomSetSysName.atomName,
                            subType=chemAtomSetSysName.atomSubType)
                    else:
                        chemAtomSet = chemCompVar.findFirstChemAtomSet(
                            name=chemAtomOrigName)

                    if chemAtomSet:

                        (chainCode, seqCode, spinSystemId, seqInsertCode,
                         atomName) = getNameInfo(self.resSetNames[i])

                        if chemAtomSet.chemAtomSets:
                            chemAtomSets = list(chemAtomSet.chemAtomSets)
                        else:
                            chemAtomSets = [chemAtomSet]

                        for chemAtomSet in chemAtomSets:

                            chemAtomSysNames = self.getChemAtomSysNamesFromSet(
                                chemAtomSet, chemCompVar, findIupac=1)

                            for chemAtomSysName in chemAtomSysNames:

                                if chemAtomSysName:
                                    atomNameLists[-1].append(
                                        getResName(
                                            chainCode,
                                            seqCode,
                                            chemAtomSysName,
                                            seqInsertCode=seqInsertCode))
                                else:
                                    print "  Error: problems with decompressing Concoord name %s - sysNames missing for %s" % (
                                        self.resSetNames[i], chemAtomSet.name)

                    else:
                        print "  Error: can't decompress Concoord name %s" % self.resSetNames[
                            i]

            #
            # If no names use default
            #

            if not atomNameLists[-1]:
                atomNameLists[-1].append(self.resSetNames[i])

        #
        # Now write them one by one...
        #

        itemResonances = getResonancesFromPairwiseConstraintItem(self.item)

        for resSetName0 in atomNameLists[0]:

            # TODO: bit risky this one! What if original names (eg GLU-) are being used?!
            resonance = itemResonances[0]
            resLabel0 = resonance.resonanceSet.findFirstAtomSet(
            ).findFirstAtom().residue.molResidue.chemComp.ccpCode.upper()

            (chainCode0, seqCode0, spinSystemId0, seqInsertCode0,
             atomName0) = getNameInfo(resSetName0)

            if atomName0 == allResidueAtoms_kw:
                print "  Error: not handling residue level constraints for %s." % self.format
                continue

            for resSetName1 in atomNameLists[1]:

                # TODO: bit risky this one! What if original names (eg GLU-) are being used?!
                resonance = itemResonances[1]
                resLabel1 = resonance.resonanceSet.findFirstAtomSet(
                ).findFirstAtom().residue.molResidue.chemComp.ccpCode.upper()

                (chainCode1, seqCode1, spinSystemId1, seqInsertCode1,
                 atomName1) = getNameInfo(resSetName1)

                if atomName1 == allResidueAtoms_kw:
                    print "  Error: not handling residue level constraints for %s." % self.format
                    continue

                #
                # Now set all items and members...
                #

                self.rawConstraint.items.append(self.rawConstraintItemClass())
                self.rawConstraintItem = self.rawConstraint.items[-1]

                self.rawConstraintItem.members.append(
                    self.rawConstraintItemMemberClass())
                self.rawConstraintItem.members[-1].setInfo(
                    chainCode0, seqCode0, resLabel0, atomName0)
                self.rawConstraintItem.members.append(
                    self.rawConstraintItemMemberClass())
                self.rawConstraintItem.members[-1].setInfo(
                    chainCode1, seqCode1, resLabel1, atomName1)
Example #9
0
    def cleanDistanceConstraintList(self, constraintList):

        print "Cleaning distance constraint list '%s'." % constraintList.name

        constraints = []
        constraintRefs = []

        #
        # Set up some reference data and do initial checking
        #

        for constraint in constraintList.constraints:

            constraints.append([])
            constraintRefs.append(constraint)

            for item in constraint.sortedItems():

                resonances = getResonancesFromPairwiseConstraintItem(item)

                #
                # Check for items between the same resonance (or resonanceSet)
                # Remove if present.
                #

                if resonances[0] == resonances[1]:
                    print "  Deleting constraint item (between same resonance)"
                    item.delete()
                    continue

                elif resonances[0].resonanceSet and resonances[
                        0].resonanceSet == resonances[1].resonanceSet:
                    print "  Deleting constraint item (between same resonanceSets)"
                    # This item can be deleted because ambiguity present on resonanceSet level -
                    # need not be repeated on constraint level!
                    item.delete()
                    continue

                #
                # Check if restraint between directly covalently linked atoms
                #

                if resonances[0].resonanceSet and len(
                        resonances[0].resonanceSet.atomSets) == 1:

                    if resonances[1].resonanceSet and len(
                            resonances[1].resonanceSet.atomSets) == 1:

                        #
                        # Need direct link to atomSet for both resonances...
                        #

                        nmrAtoms0 = list(resonances[0].resonanceSet.
                                         findFirstAtomSet().atoms)

                        refChemAtom0 = self.getRefChemAtom(nmrAtoms0)

                        if refChemAtom0:

                            nmrAtoms1 = list(resonances[1].resonanceSet.
                                             findFirstAtomSet().atoms)

                            refChemAtom1 = self.getRefChemAtom(nmrAtoms1)

                            if refChemAtom1 and nmrAtoms0[
                                    0].residue == nmrAtoms1[0].residue:

                                itemDeleted = 0

                                if refChemAtom1 == refChemAtom0:

                                    print "  Deleting constraint item (connected via atom %s)" % (
                                        refChemAtom0.name)

                                    item.delete()
                                    itemDeleted = 1

                                #else:

                                #  for chemBond in refChemAtom0.chemBonds:

                                #    if refChemAtom1 == getOtherAtom(refChemAtom0,chemBond):

                                #      print "  Deleting constraint item (between atoms %s, %s directly connected via two covalent bonds)" % (refChemAtom0.name,refChemAtom1.name)

                                #      item.delete()
                                #      itemDeleted = 1
                                #      break

                                if itemDeleted:

                                    continue

                #
                # Keep track of valid items
                #

                constraints[-1].append(resonances)

            #
            # Check if there are any items left
            #

            if not constraint.items:
                print "  Deleting constraint %d (no items left)" % constraint.serial
                constraint.delete()
                constraints.pop(-1)
                constraintRefs.pop(-1)

            else:

                constraints[-1].sort()

        #
        # Now check whether there are any duplicates
        #

        i = 0

        while (i < len(constraints)):

            refConstraint = constraints[i]

            j = i + 1

            while (j < len(constraints)):

                if refConstraint == constraints[j]:
                    items = ""
                    for (res1, res2) in constraints[j]:
                        items += "[%s,%s]," % (res1.name, res2.name)
                    items = items[:-1]

                    #
                    # Always keep tightest value if available
                    #

                    for attribute in [
                            'upperLimit', 'targetValue', 'lowerLimit'
                    ]:
                        if getattr(constraintRefs[i], attribute) and getattr(
                                constraintRefs[j], attribute):
                            setattr(
                                constraintRefs[i], attribute,
                                min(getattr(constraintRefs[i], attribute),
                                    getattr(constraintRefs[j], attribute)))

                    print "  Constraint %s (items %s) is duplicate of %s - deleted" % (
                        constraintRefs[j].serial, items,
                        constraintRefs[i].serial)
                    constraintRefs[j].delete()
                    constraints.pop(j)
                    constraintRefs.pop(j)

                else:
                    j += 1

            i += 1
Example #10
0
  def checkSwapsAndClean(self,method = 'SUM_AVERAGING', violationCodes = None, swapFraction = 0.75):
  
    if not self.distanceConstraintLists or not self.structureEnsemble or not self.structureEnsemble.models:
      print "Error: no constraint lists or no structures available! Aborting..."
      return
  
    print
    print "Checking swap status and cleaning prochiral groups in constraint lists..."
    print
    
    #
    # Initialize... see parameters above for swapFraction
    #
    # Set a dictionary with violationCodes (what is a large violation?)
    #
    
    if violationCodes:
      self.violationCodes = violationCodes
      
    else:
      self.violationCodes = {}
      self.violationCodes['xl'] = {'violation': 2.0, 'fraction': 0.00001}
      self.violationCodes['l'] = {'violation': 1.0, 'fraction': 0.5}
  
    #
    # Set up a dict of resonances
    # TODO: Should this be done in cleanStereoAssignments?!?
    #       Should I make this a 'violationHandler' class??!?!
    #

    (self.resAtomDict,self.resAtomSetDict) = createResonanceAtomAndAtomSetDict(self.distanceConstraintLists[0].parent.fixedResonances)    
    if self.verbose:
      print "Made resAtomDict, resAtomSetDict"
  
    (self.resAtomSwapDict,self.prochiralResonancesDict) = createResAtomSwapDict(self.resAtomSetDict)
    if self.verbose:
      print "Made resAtomSwapDict,prochiralResonancesDict"
  
    structureViolations = []
  
    """
    infoStrings = []
    for resonance in resAtomSwapDict.keys():
      atoms = resAtomDict[resonance]
      infoString = "%3d.%s" % (atoms[0].residue.seqId, atoms[0].atomSet.name)
      atoms = resAtomSwapDict[resonance]
      infoString += "-> swap is %3d.%s" % (atoms[0].residue.seqId, atoms[0].name)
      infoStrings.append(infoString)
    infoStrings.sort()
    for infoString in infoStrings:
      print infoString
    """

    #
    # Set the factor for calculating violations
    #

    if method == 'SUM_AVERAGING':
      factor = 1.0/6.0
    
    #
    # Loop over the structures
    #
    
    self.models = self.structureEnsemble.sortedModels()
    #self.models = self.models[:3]
    for model in self.models:

      self.prochiralViolationDict = self.createProchiralViolationDict()
    
      #violationList = Nmr.ViolationList(distanceConstraintLists[0].structureGeneration,molStructures = [model])
    
      totalViols = 0
    
      #
      # Set up dict for coordinates
      #
    
      self.atomCoordDict = {}
      
      # No need for sorting here...
      for cChain in self.structureEnsemble.coordChains:
        for cRes in cChain.residues:
          for cAtom in cRes.atoms:
            if cAtom.atom:
          
              #
              # TODO: cannot handle multiple coords for one atom!!
              #
            
              self.atomCoordDict[cAtom.atom] = model.findFirstCoord(atom = cAtom)
              
      if self.verbose:
        print "Made atomCoordDict for model %d" % model.serial
    
      #
      # Go over the distance constraints
      #
    
      for distanceConstraintList in self.distanceConstraintLists:
    
        for distConstr in distanceConstraintList.sortedConstraints():
        
          # TODO: extend to other methods?

          if method == 'SUM_AVERAGING':

            #
            # Calculate sum averaged distance (Nilges et al., Proteins 17, 297-309, 1993)
            #

            (avgDist,prochiralContribs) = getDistConstrSumAvg(distConstr,self.resAtomDict,self.atomCoordDict,factor,self.resAtomSwapDict,self.prochiralResonancesDict)
            totalViols += self.setViolationDict(avgDist,prochiralContribs,distConstr,'orig')

            #
            # Now do the same but for the swap...
            #

            if prochiralContribs:
              (avgDist,prochiralContribs) = getDistConstrSumAvg(distConstr,self.resAtomDict,self.atomCoordDict,factor,self.resAtomSwapDict,self.prochiralResonancesDict,swap = True)
              self.setViolationDict(avgDist,prochiralContribs,distConstr,'swap')
            
      structureViolations.append(self.prochiralViolationDict)
      
      if self.verbose:
        print "Total violations %d" % totalViols

    #
    # Check if whether original or swap state was the best...
    #

    prochiralSwaps = {}

    for i in range(0,len(structureViolations)):
      prochiralViolationDict = structureViolations[i]

      for prochiralKey in prochiralViolationDict['orig']['total']:

        #
        # Calculate total violation over all structures for swapping...
        #

        if prochiralViolationDict['orig']['total'][prochiralKey] > prochiralViolationDict['swap']['total'][prochiralKey]:
          if not prochiralSwaps.has_key(prochiralKey):
            prochiralSwaps[prochiralKey] = 0
          prochiralSwaps[prochiralKey] += 1
      
  
    #
    # Finally make the changes in the data model where appropriate
    #

    cutoff = swapFraction * len(structureViolations)
    infoText = []
    
    totalStructures = len(self.models)

    for prochiralKey in prochiralViolationDict['orig']['total']:
      
      #
      # Set the swapstatus
      #
      
      if prochiralSwaps.has_key(prochiralKey) and prochiralSwaps[prochiralKey] > cutoff:
        swapStatus = 'swap'
        percent = prochiralSwaps[prochiralKey] * 100 / len(structureViolations)
        infoText.append("Swapping stereo assignment status chain %s, residue %3d group %s: %.3f%%" % (prochiralKey[0],prochiralKey[1],prochiralKey[2].name,percent))

      else:
        swapStatus = 'orig'

      #
      # Check for constraints with large violations based on the swap state...
      #
      
      constraintItemsReset = []

      for violationCode in self.violationCodes.keys():
      
        constraintsViolated = {}
        cutoffFraction = self.violationCodes[violationCode]['fraction']
        
        #
        # Again look over all structures
        #
        
        for prochiralViolationDict in structureViolations:
          for distConstr in prochiralViolationDict[swapStatus][violationCode][prochiralKey].keys():
            if not constraintsViolated.has_key(distConstr):
              constraintsViolated[distConstr] = [0.0,[]]         
            constraintsViolated[distConstr][0] += 1.0
            
            for constrItem in prochiralViolationDict[swapStatus][violationCode][prochiralKey][distConstr][1]:
              if constrItem not in constraintsViolated[distConstr][1]:
                constraintsViolated[distConstr][1].append(constrItem)
        
        #
        # Then recalculate and add a constraint item if necessary
        #
        
        distConstraints = constraintsViolated.keys()
        distConstraints.sort()
        
        for distConstr in distConstraints:

          fractionViolated = constraintsViolated[distConstr][0] / totalStructures
          #print prochiralKey, violationCode, fractionViolated 
          if fractionViolated >= cutoffFraction:

            prochiralResonances = []
            for resonance in self.prochiralResonancesDict.keys():
              if self.prochiralResonancesDict[resonance] == prochiralKey:
                prochiralResonances.append(resonance)
            
            #
            # Have to make a new prochiral resonance if there's only one!!
            #
            
            if len(prochiralResonances) == 1:
            
              otherProchiralResonance = NmrConstraint.FixedResonance(self.nmrConstraintStore, isotopeCode = prochiralResonances[0].isotopeCode)
              otherAtoms = self.resAtomSwapDict[prochiralResonances[0]]
              if otherAtoms[0].atomSet:
                otherAtomSet = otherAtoms[0].atomSet
              else:
                otherAtomSet = NmrConstraint.FixedAtomSet(self.nmrConstraintStore,atoms = otherAtoms)

              otherProchiralResonanceSet = NmrConstraint.FixedResonanceSet(self.nmrConstraintStore, resonances = [otherProchiralResonance], atomSets = [otherAtomSet])

              prochiralResonances.append(otherProchiralResonance)
              self.prochiralResonancesDict[otherProchiralResonance] = prochiralKey
            
            violatedItems = constraintsViolated[distConstr][1]
            
            for violatedItem in violatedItems:
              
              #
              # Don't redo the item if it was already reset..
              #
              
              if (prochiralKey,violatedItem) in constraintItemsReset:
                continue
                
              violatedResonances = getResonancesFromPairwiseConstraintItem(violatedItem)
              
              for resonance in prochiralResonances:
                if resonance in violatedResonances:
                  otherResonanceIndex = not violatedResonances.index(resonance)
                  otherResonance = violatedResonances[otherResonanceIndex]
                  
                  otherProchiralResonance = prochiralResonances[not prochiralResonances.index(resonance)]
                  
                  # Put these the wrong way around on purpose!
                  if otherResonanceIndex == 1:
                    newResonances = [otherResonance,otherProchiralResonance]
                  else:
                    newResonances = [otherProchiralResonance,otherResonance]
                    
                  break
                  
              constraintExists = distConstr.findFirstItem(resonances = tuple(newResonances))
              
              if not constraintExists:
                newResonances.reverse()
                
                constraintExists = distConstr.findFirstItem(resonances = tuple(newResonances))
                
                if not constraintExists and newResonances[0] != newResonances[1]:
                  
                  NmrConstraint.DistanceConstraintItem(distConstr,resonances = newResonances)
                  
                  prochiralText = "%s.%d.%s" % (prochiralKey[0],prochiralKey[1],prochiralKey[2].name)
                  infoLine = "Deassigned constraint %d to prochiral %s: violation > %.1f in %.1f%% of structures.\n" % (distConstr.serial,prochiralText,self.violationCodes[violationCode]['violation'],fractionViolated * 100)
                  infoLine += "   --> added new item for '%s' to '%s'" % (getResNameText(newResonances[0]),getResNameText(newResonances[1]))
                  infoText.append(infoLine)
                  
                  constraintItemsReset.append((prochiralKey,violatedItem))
      
      #
      # Reset based on swapStatus
      #

      if swapStatus == 'swap':

        #
        # Switch the assignments...
        #

        prochiralResonances = []
        for resonance in self.prochiralResonancesDict.keys():
          if self.prochiralResonancesDict[resonance] == prochiralKey:
            prochiralResonances.append(resonance)

        if len(prochiralResonances) == 2:
        
          resSet1 = prochiralResonances[0].resonanceSet
          atomSet1 = resSet1.sortedAtomSets()[0]
          resSet2 = prochiralResonances[1].resonanceSet
          atomSet2 = resSet2.sortedAtomSets()[0]

          resSet1.addAtomSet(atomSet2)
          resSet1.removeAtomSet(atomSet1)
          resSet2.addAtomSet(atomSet1)
          resSet2.removeAtomSet(atomSet2)

        else:
          resSet = prochiralResonances[0].resonanceSet
          atomSet1 = resSet.sortedAtomSets()[0]

          otherAtoms = self.resAtomSwapDict[prochiralResonances[0]]
          if otherAtoms[0].atomSet:
            otherAtomSet = otherAtoms[0].atomSet
          else:
            otherAtomSet = NmrConstraint.FixedAtomSet(self.nmrConstraintStore,atoms = otherAtoms)

          resSet.addAtomSet(otherAtomSet)
          resSet.removeAtomSet(atomSet1)

    infoText.sort()
    for line in infoText:
      print line
Example #11
0
  #

  for distConstr in ccpnConstraintList.sortedConstraints():

    print "Constraint %d: %.1f-%.1f" % (distConstr.serial, distConstr.lowerLimit, distConstr.upperLimit)

    for constrItem in distConstr.sortedItems():

      #
      # Now list the atoms linked to each of the two resonances associated with
      # this item.
      #

      atomList = []

      resonanceList = getResonancesFromPairwiseConstraintItem(constrItem)

      for resonance in resonanceList:
        atomList.append([])
        if resonance.resonanceSet:
          for atomSet in resonance.resonanceSet.atomSets:
            for atom in atomSet.atoms:
              atomList[-1].append("%d.%s" % (atom.residue.seqCode,atom.name))

        atomList[-1].sort()
        atomList[-1] = ','.join(atomList[-1])

      print "   (%s) - (%s)" % (atomList[0],atomList[1])

    print