Exemplo n.º 1
0
def areResonancesBound(resonance1, resonance2):
    """
  Determine whether two resonances are assigned to directly bonded atoms
  
  .. describe:: Input
  
  Nmr.Resonance, Nmr.Resonance

  .. describe:: Output
  
  Boolean
  """

    if resonance1 is resonance2:
        return False

    resonanceSet1 = resonance1.resonanceSet
    resonanceSet2 = resonance2.resonanceSet

    if resonanceSet1 and resonanceSet2:

        atomSets1 = resonanceSet1.atomSets
        atomSets2 = resonanceSet2.atomSets

        bound1 = resonance1.covalentlyBound
        bound2 = resonance2.covalentlyBound

        # Have to look through everything to get the right equiv
        # & prochiral pair - Val CGa HGb: check both atomSets for each
        # Phe Ce* He*: check both atoms (only one atomSet each)
        for atomSet1 in atomSets1:
            for atom1 in atomSet1.atoms:
                for atomSet2 in atomSets2:
                    for atom2 in atomSet2.atoms:
                        if areAtomsBound(atom1, atom2):
                            # Val Cgb - Hgb* can appear bound,
                            # so check resonance links
                            if (resonance1.isotopeCode
                                    == '1H') and (len(atomSets2) > 1):
                                if bound1 and resonance2 not in bound1:
                                    continue

                            elif (resonance2.isotopeCode
                                  == '1H') and (len(atomSets1) > 1):
                                if bound2 and resonance1 not in bound2:
                                    continue

                            return True

        return False

    from ccpnmr.analysis.core.AssignmentBasic import getBoundResonances

    resonances = getBoundResonances(resonance1)
    if resonance2 in resonances:
        return True

    else:
        return False
Exemplo n.º 2
0
def getAmideSpinSystems(peakLists, minNitrogenPpm=93.0):

    #

    spinSystems = set()

    for peakList in peakLists:
        shiftList = peakList.dataSource.experiment.shiftList

        for peak in peakList.peaks:
            for peakDim in peak.peakDims:
                ppm = peakDim.value

                # Check ppm range

                if ppm < minNitrogenPpm:  # Also removes 1H and most 1C
                    continue

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

                    # Check isotope

                    if resonance.isotopeCode != '15N':
                        continue

                    # Check we have an amide

                    if not isResonanceAmide(resonance):
                        continue

                    # Check not side chain bound

                    numH = 0
                    for bound in getBoundResonances(resonance):
                        if bound.isotopeCode == '1H':
                            numH += 1

                    if numH > 1:
                        continue

                    spinSystem = resonance.resonanceGroup

                    if spinSystem:
                        spinSystems.add(spinSystem)

    ss = [(s.serial, s) for s in spinSystems]
    ss.sort()

    return [x[1] for x in ss]
Exemplo n.º 3
0
def findBoundResonances(resonance):
    """Find any resonances which are assigned to atoms covalently bound
             to the assigned atoms of the input resonance
  .. describe:: Input
  
  Nmr.Resonance

  .. describe:: Output
  
  List of Nmr.Resonances
  """

    from ccpnmr.analysis.core.AssignmentBasic import getBoundResonances

    return getBoundResonances(resonance)
def get_bound_resonances_of_isotope(resonance, isotope):
    '''For a resonance, get all resonances of an
       isotope type bound to this resonance.

    '''

    isotopeCode = '{}{}'.format(isotope.massNumber, isotope.chemElement.symbol)

    # Use getBoundResonance to get from e.g. Cga to Hga* and not Hgb*
    resonancesA = set(x for x in getBoundResonances(resonance, recalculate=True)
                      if x.isotopeCode == isotopeCode
                      and x.resonanceSet)

    # get covalently bound atomSts
    atoms = set()
    for atomSet in resonance.resonanceSet.atomSets:
        atoms.update(getBoundAtoms(atomSet.findFirstAtom()))

    atomSets = set(a.atomSet for a in atoms if a.atomSet and \
                   a.chemAtom.chemElement is isotope.chemElement)


    if resonancesA:
        # remove covalently impossible resonances
        resonanceSets = set(y for x in atomSets for y in x.resonanceSets)
        resonancesA = set(x for x in resonancesA
                          if x.resonanceSet in resonanceSets)

    if not resonancesA:
        nmrProject = resonance.parent
        # make new resonances for covanlently bound atoms
        for atomSet in atomSets:
            resonanceB = nmrProject.newResonance(isotopeCode=isotopeCode)
            assignAtomsToRes([atomSet,], resonanceB)
            resonancesA.add(resonanceB)

    return resonancesA
Exemplo n.º 5
0
def analysePeaks(peakList):


  # Row per peak - Cols: height vs PL mean, vol vs PL mean,
  # sign check, F1 shift delta, F2 shift delta ++

  meanVolume = 0.0
  meanHeight = 0.0
  meanVolume2 = 0.0
  meanHeight2 = 0.0
  nVolume = 0
  nHeight = 0

  pos = 0
  tot = 0

  data0 = []
  for peak in peakList.sortedPeaks():
    
    volume = getPeakVolume(peak)
    height = getPeakHeight(peak)
    logVolume = None
    logHeight = None
        
    if volume:
      logVolume = log(abs(volume))
      meanVolume += logVolume
      meanVolume2 += logVolume * logVolume
      nVolume += 1
    else:
      volume = 0.0
    
    if height:
      logHeight = log(abs(height))
      meanHeight += logHeight
      meanHeight2 += logHeight * logHeight
      nHeight += 1
  
      tot += 1
      if height > 0:
        pos += 1
        
    else:
      height = 0.0
  
    data0.append([peak, volume,logVolume, height, logHeight])
  
  
  if nVolume:
    meanVolume /= float(nVolume)
    meanVolume2 /= float(nVolume)
  
  if nHeight:
    meanHeight /= float(nHeight)
    meanHeight2 /= float(nHeight)
  
  heightSd =  sqrt(abs(meanHeight2 - (meanHeight * meanHeight)))
  # abs() due to float point error - v small negs rather than zero 
  volumeSd =  sqrt(abs(meanVolume2 - (meanVolume * meanVolume)))
    
  shiftList = peakList.dataSource.experiment.shiftList
  
  boundDataDims = {}
  for dataDim1, dataDim2 in getOnebondDataDims(peakList.dataSource):
    boundDataDims[dataDim1] = dataDim2
    boundDataDims[dataDim2] = dataDim1

  data = []
  for peak, volume, logVolume, height, logHeight in data0:
  
    deltaLogVolume = None
    deltaLogHeight = None
    
    if volume:
      deltaLogVolume = abs(logVolume - meanVolume)

    if height:
      deltaLogHeight = abs(logHeight - meanHeight)

    maxDeltas = []
    assignErrors = {}
    # Row per peak: - Cols: Causes muli 1bond,
    # causes atom impossible 1bond, Partly assigned onebond,
    # missing/extra assign
    for peakDim in peak.sortedPeakDims():
      
      maxDelta = None
      isotopeCode  = None
      
      if shiftList:
        for contrib in peakDim.peakDimContribs:
          resonance = contrib.resonance
          isotopeCode = resonance.isotopeCode
          shift = resonance.findFirstShift(parentList=shiftList)
          if shift:
            delta = abs(peakDim.realValue - shift.value)
            
            if (maxDelta is None) or (delta > maxDelta):
              maxDelta = delta
      
      maxDeltas.append([maxDelta,isotopeCode])  
      
      for contrib in peakDim.peakDimContribs:
        resonance = contrib.resonance
        # Warn the user if prochirals have similar shifts
        # but only one is linked to the peak.
        resonanceSet = resonance.resonanceSet
        if resonanceSet:
          if len(resonanceSet.atomSets) > 1:
            resonances2 = list(resonanceSet.resonances)
            resonances2.remove(resonance)
            
            for resonance2 in resonances2:
              if peakDim.findFirstPeakDimContrib(resonance=resonance2):
                continue
              
              for contrib2 in resonance2.peakDimContribs:
                if contrib2.peakDim.peak.peakList is peakList:
                  break
              
              else:
                shift = resonance.findFirstShift(parentList=shiftList)
                shift2 = resonance2.findFirstShift(parentList=shiftList)
                if shift and shift2:
                  delta = abs(shift.value-shift2.value)
                  analysisDataDim = getAnalysisDataDim(peakDim.dataDim)
 
                  if analysisDataDim and (delta < analysisDataDim.assignTolerance/5.0):
                    name = makeResonanceGuiName(resonance2, fullName=False)
                    msg = 'Also expected dim %d %s assignment' % (peakDim.dim,name)
                    assignErrors[msg] = True

      boundDataDim = boundDataDims.get(peakDim.dataDim)
      if boundDataDim:
        peakDim2 = peak.findFirstPeakDim(dataDim=boundDataDim)
    
        if peakDim.peakDimContribs:
          if peakDim2.peakDimContribs:
            
            # Count number of atomSets to see if result makes sense
            atomSets1 = set()
            atomSets2 = set()
            for contrib2 in peakDim2.peakDimContribs:
              resonanceSet = contrib2.resonance.resonanceSet
              if resonanceSet:
                for atomSet in resonanceSet.atomSets:
                  atomSets2.add(atomSet)
          
            for contrib in peakDim.peakDimContribs:
              resonance = contrib.resonance
              resonanceSet = resonance.resonanceSet
              name = makeResonanceGuiName(resonance)
              bound = getBoundResonances(resonance, recalculate=True)
              impossibles  = []
              
              if resonanceSet:
                for atomSet in resonanceSet.atomSets:
                  atomSets1.add(atomSet)

              if bound:
        
                nBound = len(bound)
                
                for reson in bound:
                  # Correct for multiatom atomSets (CH3 resonances e,g,)
                  resSet = reson.resonanceSet
                  if resSet:
                    ll = [1]
                    for atomSet in resSet.atomSets:
                      length = len(atomSet.atoms)
                      cas = atomSet.findFirstAtom().chemAtom.chemAtomSet
                      if not cas or cas.isEquivalent is not None:
                        # Test excludes e.g. Tyr and Phe side chains
                        # that otherwise give spurious errors
                        ll.append(length)
                    # Add additional number of atoms for each bound resonance
                    nBound += min(ll) - 1
                    
                if isotopeCode in ('1H','2H','19F'):
                  if nBound > 1:
                    assignErrors['%s mutiple %s bonds' % (name,isotopeCode)] = True
 
                elif resonanceSet:
                  chemAtom = resonance.resonanceSet.findFirstAtomSet().findFirstAtom().chemAtom
                  if nBound > len(chemAtom.chemBonds):
                    assignErrors['%s excessive bonds' % name] = True
                    
                okAtoms = False
                foundBound = False
                for contrib2 in peakDim2.peakDimContribs:
                  resonance2 = contrib2.resonance
                  
                  if resonance2 in bound:
                    resonanceSet2 = resonance2.resonanceSet
                    foundBound = True
                    if resonanceSet and resonanceSet2:
                      if not areResonanceSetAtomsBound(resonanceSet, resonanceSet2):
                        names = [name,makeResonanceGuiName(resonance2)]
                        names.sort()
                        impossibles.append(names)
                        
                      else:
                        okAtoms = True
                        
                if not okAtoms:
                  for names in impossibles:
                    assignErrors['Impossible bond %s-%s' % tuple(names)] = True
                
                if not foundBound:
                  assignErrors['%s no bound partner' % name] = True
            
            if isotopeCode in ('1H','2H','19F'):
              if len(atomSets2) > len(atomSets1):
                assignErrors['Only %s H to bind %s Non-H' % (len(atomSets1), len(atomSets2))] = True
                
          else:
            assignErrors['Dim %d empty' % peakDim2.dataDim.dim] = True
        
        elif peakDim2.peakDimContribs:
          assignErrors['Dim %d empty' % peakDim.dataDim.dim] = True
      

    sortedPeakDims = peak.sortedPeakDims()
    annotation = ' '.join([pd.annotation or '-' for pd in sortedPeakDims])
    
    locations = []
    for pd in sortedPeakDims:
      if pd.value is None:
        if pd.position is None:
          locations.append('Error')
        else:
          locations.append('%.2f' % pd.position)
          
      else:
        locations.append('%.2f' % pd.value)
    
    location   = ' '.join(locations)

    nearestPeak, nearestDistance = findClosestOtherPeak(peak, scale=2.0)
    symmetryPeaks = findSymmetryPeaks(peak)

    datum = [peak.serial,annotation,assignErrors.keys(),location,
             volume,deltaLogVolume,
             height,deltaLogHeight,maxDeltas,
             nearestPeak, nearestDistance, symmetryPeaks]
    data.append([peak, datum])

  posProp = 1.0
  if tot:
    posProp = pos/float(tot)

  return posProp, volumeSd, heightSd, data
Exemplo n.º 6
0
def analyseChemicalShifts(shiftList):
    
    updateAllShifts(shiftList)
    
    # T1, shifts -  Row per resonance - Cols: shift, shiftSD,
    # maxPeak delta, SD per spectrum ++
    data = []
    
    duplicateAssign = {}
    data2 = []
    if shiftList:
      project = shiftList.root
    
      for shift in shiftList.measurements:
        resonance = shift.resonance
        assignTuple = getResonanceAtomTuple(resonance)
        data2.append(['%s%s%8.8s%s' % assignTuple,shift])
        duplicateAssign[assignTuple] = duplicateAssign.get(assignTuple, 0) + 1
    
    data2.sort()
    for name, shift in data2:
      resonance  = shift.resonance
      deltaMax   = None
      nContribs  = 0
      bmrbMean   = None
      randomCoil = None
      typeScore  = None
      
      resonanceSet = resonance.resonanceSet
      if resonanceSet:
        atomSet = resonanceSet.findFirstAtomSet()
        residue = atomSet.findFirstAtom().residue
        ccpCode = residue.ccpCode
        molType = residue.molResidue.molType
        atomName = atomSet.name
        chemAtomNmrRef = getChemAtomNmrRef(project, atomName, ccpCode, molType=molType)
        if chemAtomNmrRef is None:
          atomName = atomSet.findFirstAtom().name
          chemAtomNmrRef = getChemAtomNmrRef(project, atomName, ccpCode, molType=molType)
         
        if chemAtomNmrRef:
        
          # Horrid kludge until we have chem shift ref info per var
          if (ccpCode == 'Cys') and ('link:SG' in residue.chemCompVar.descriptor):
            ccpCode = 'Cyss'
                
          typeScore  = lookupAtomProbability(project, ccpCode, atomName, shift.value, molType)
          bmrbMean   = chemAtomNmrRef.meanValue
          randomCoil = chemAtomNmrRef.randomCoilValue
      
      for contrib in resonance.peakDimContribs:
        peakDim = contrib.peakDim
        shiftList1 = peakDim.peak.peakList.dataSource.experiment.shiftList
        if shiftList1 and (shiftList1 is shiftList):
          nContribs +=1
          delta = abs(peakDim.realValue-shift.value)
          if (deltaMax is None) or (delta > deltaMax):
            deltaMax = delta
            
      boundWarn = False      
      bound = getBoundResonances(resonance, recalculate=True)
      if bound:
        
        nBound = len(bound)
        
        for reson in bound:
          # Correct for multiatom atomSets (CH3 resonances e,g,)
          resSet = reson.resonanceSet
          if resSet:
            ll = [1]
            for atomSet in resSet.atomSets:
              length = len(atomSet.atoms)
              cas = atomSet.findFirstAtom().chemAtom.chemAtomSet
              if not cas or cas.isEquivalent is not None:
                # Test excludes e.g. Tyr and Phe side chains 
                # that otherwise give spurious errors
                ll.append(length)
            # Add additional number of atoms for each bound resonance
            nBound += min(ll) - 1
          
        if resonance.isotopeCode in ('1H','2H','19F'):
          if nBound > 1:
            boundWarn = True
 
        elif resonanceSet:
          chemAtom = resonance.resonanceSet.findFirstAtomSet().findFirstAtom().chemAtom
          if nBound > len(chemAtom.chemBonds):
            boundWarn = True
    
        if resonanceSet and not boundWarn:
          atom = resonanceSet.findFirstAtomSet().findFirstAtom()
          
          for resonance1 in bound:
            resonanceSet1 = resonance1.resonanceSet
            
            if resonanceSet1:
              for atomSet1 in resonanceSet1.atomSets:
                for atom1 in atomSet1.atoms:
                  if areAtomsBound(atom, atom1):
                    break
                    
                else:
                  continue
                break   
              
              else:
                boundWarn = True
    
      assignTuple = getResonanceAtomTuple(resonance)
      sameResBound = []
      otherBound   = []
      residue = getResonanceResidue(resonance)
      for resonance1 in bound:
        residue1 = getResonanceResidue(resonance1)
        if residue1 is residue:
          sameResBound.append(makeResonanceGuiName(resonance1,fullName=False))
        else:
          otherBound.append(makeResonanceGuiName(resonance1))
      
      boundResonances = ''
      if residue:
        ccpCode = getResidueCode(residue)
        resName1 = '%d%s' % (residue.seqCode,ccpCode)
        
        if len(sameResBound) > 1:
          boundResonances += '%s[%s] ' % (resName1,','.join([x for x in sameResBound]))
        elif sameResBound:
          boundResonances += '%s%s ' % (resName1,sameResBound[0])
      
      else:
         boundResonances += ','.join([x for x in sameResBound])
         
      boundResonances += ','.join([x for x in otherBound])
     
      isDuplicate = False
      if duplicateAssign.get(assignTuple, 0) > 1:
        isDuplicate = True
        
      resName = makeResonanceGuiName(resonance)
      datum = [resonance.serial,resonance.isotopeCode,resName,boundResonances,
               bmrbMean,randomCoil,typeScore,shift.value,shift.error,
               deltaMax,nContribs,isDuplicate,boundWarn]
      
      data.append([shift, datum])
      
    return data