def getCouplingTolerance(component, dataDimRef): """ Get the coupling assignment tolerance (usually Hz) for a given data dim. .. describe:: Input ccp.nmr.Nmr.FreqDataDim .. describe:: Output Float """ freqDataDim = dataDimRef.dataDim delta = getAnalysisDataDim(dataDimRef.dataDim).assignTolerance unit = dataDimRef.expDimRef.unit if unit != 'point': delta /= dataDimRef.valuePerPoint tolerance = component.dataDimRef.pointToValue(delta) return tolerance
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
def updateConditions(self): self.updateButtons() objectList = [] textMatrix = [] colorMatrix = [] nCols = len(self.conditionPointsMatrix.headingList) defaultColors = [None] * nCols if self.expSeries: if self.expSeries.className == 'Experiment': dataDim = getExperimentSampledDim(self.expSeries) analysisDataDim = getAnalysisDataDim(dataDim) conditionVaried = dataDim.conditionVaried expName = self.expSeries.name unit = dataDim.unit pointValues = dataDim.pointValues pointErrors = dataDim.pointErrors refPlane = analysisDataDim.refSamplePlane for i in range(dataDim.numPoints): if i < len(pointErrors): error = pointErrors[i] else: error = None pointText = ':%3d' % (i+1) if i == refPlane: datum = ['* Ref Plane *', expName+pointText, None, None, None] colorMatrix.append(['#f08080'] * nCols) else: datum = [conditionVaried , expName+pointText, pointValues[i], error, unit] colorMatrix.append(defaultColors) textMatrix.append(datum) objectList.append((dataDim, i)) else: condDict = getNmrExpSeriesSampleConditions(self.expSeries) conditionNames = self.expSeries.conditionNames for conditionName in conditionNames: for sampleCondition in condDict.get(conditionName, []): datum = [sampleCondition.condition, ' '.join([e.name for e in sampleCondition.parent.experiments]), sampleCondition.value, sampleCondition.error, sampleCondition.unit] textMatrix.append(datum) objectList.append(sampleCondition) colorMatrix.append(defaultColors) self.conditionPointsMatrix.update(objectList=objectList, colorMatrix=colorMatrix, textMatrix=textMatrix) self.waitingConditions = 0
def setPeakFindBoxwidth(dataDim, boxwidth): getAnalysisDataDim(dataDim).peakFindBoxWidth = boxwidth
def getPeakFindBoxwidth(dataDim): return getAnalysisDataDim(dataDim).peakFindBoxWidth
def setPeakFindMinLinewidth(dataDim, min_lw): getAnalysisDataDim(dataDim).peakFindMinLineWidth = min_lw
def getPeakFindMinLinewidth(dataDim): return getAnalysisDataDim(dataDim).peakFindMinLineWidth
def pickAssignSpecFromRoot(rootPeaks, targetPeakList, tolerances=None, progressBar=None, pickNew=True, diagTolerance=None, waterExclusion=None): """Descrn: Pick peaks in a spectrum based upon a root peak list and assign picked peaks to root resonances. Inputs: List of Nmr.Peaks, Nmr.PeakList, List of Floats (target dim order), memops.gui.ProgressBar, Boolean, Float or None, 2-Tuple of Floats (min, max) or None Output: Nmr.Peaks, Dict of Int:Int (dim mapping root:target) """ # TBD: perhaps a list of peaks rather than a set should be passed in rootPeakList = tuple(rootPeaks)[0].peakList project = rootPeakList.root spectrum0 = rootPeakList.dataSource spectrum1 = targetPeakList.dataSource if not tolerances: tolerances = [] for dataDim in spectrum1.sortedDataDims(): tolerances.append(getAnalysisDataDim(dataDim).assignTolerance) expDimRefs0 = ExperimentBasic.getOnebondExpDimRefs(spectrum0.experiment) expDimRefs1 = ExperimentBasic.getOnebondExpDimRefs(spectrum1.experiment) if not expDimRefs0: msg = 'Spectrum %s:%s has no directly bonded dims.' showWarning('Failure', msg % (spectrum0.experiment.name, spectrum0.name)) return if not expDimRefs1: msg = 'Spectrum %s:%s has no directly bonded dims.' showWarning('Failure', msg % (spectrum1.experiment.name, spectrum1.name)) return # could really do with a generic get matching dataDims function # TBD try PeakBasic.getDataDimMapping() dimMapping = {} for expDimRef0, expDimRef1 in expDimRefs0: dataDim0 = spectrum0.findFirstDataDim(expDim=expDimRef0.expDim) dataDim1 = spectrum0.findFirstDataDim(expDim=expDimRef1.expDim) isotopes0 = expDimRef0.isotopeCodes isotopes1 = expDimRef1.isotopeCodes if '1H' in isotopes0 or '1H' in isotopes1: break boundDims = set([dataDim0.dim, dataDim1.dim]) for expDimRef2, expDimRef3 in expDimRefs1: isotopes2 = expDimRef2.isotopeCodes isotopes3 = expDimRef3.isotopeCodes dataDim2 = spectrum1.findFirstDataDim(expDim=expDimRef2.expDim) dataDim3 = spectrum1.findFirstDataDim(expDim=expDimRef3.expDim) if not (dataDim2 and dataDim3): continue if (isotopes0 == isotopes2) and (isotopes1 == isotopes3): dimMapping[dataDim0.dim] = dataDim2.dim dimMapping[dataDim1.dim] = dataDim3.dim break elif (isotopes0 == isotopes3) and (isotopes1 == isotopes2): dimMapping[dataDim0.dim] = dataDim3.dim dimMapping[dataDim1.dim] = dataDim2.dim break if not dimMapping: msg = 'Could not find equivalent dims in spectra %s:%s & %s:%s' data = (spectrum0.experiment.name, spectrum0.name, spectrum1.experiment.name, spectrum1.name) showWarning('Failure', msg % data) return if progressBar: progressBar.total = len(rootPeaks) progressBar.set(0) progressBar.open() fullRegion = [] getDimRef = ExperimentBasic.getPrimaryDataDimRef targetDims = targetPeakList.dataSource.sortedDataDims() targetDims = [(getDimRef(dd), dd) for dd in targetDims] targetIsotopes = [ ','.join(ddr.expDimRef.isotopeCodes) for (ddr, dd) in targetDims ] for dataDimRef, dataDim in targetDims: valueMax = pnt2ppm(1, dataDimRef) valueMin = pnt2ppm(dataDim.numPoints, dataDimRef) fullRegion.append([valueMin, valueMax]) foundPeaks = [] for peak in rootPeaks: peakRegion = list(fullRegion) rootIsotopes = [] rootMapDims = set() values = [] boundPeakDims = [ pd for pd in peak.sortedPeakDims() if pd.dim in boundDims ] for i, peakDim in enumerate(boundPeakDims): error = tolerances[i] value = peakDim.value j = dimMapping[peakDim.dim] - 1 peakRegion[j] = (value - error, value + error) rootIsotopes.append(targetIsotopes[j]) rootMapDims.add(j) values.append(value) regions = [ peakRegion, ] if diagTolerance: for i, isotopes in enumerate(targetIsotopes): if (i not in rootMapDims) and (isotopes in rootIsotopes): value = values[rootIsotopes.index(isotopes)] # Chop in two at diagonal regions2 = [] for region in regions: regionA = list(region) regionB = list(region) valueMin, valueMax = region[i] regionA[i] = (valueMin, value - diagTolerance) regionB[i] = (value + diagTolerance, valueMax) regions2.append(regionA) regions2.append(regionB) regions = regions2 if waterExclusion: waterMin, waterMax = waterExclusion for i, isotopes in enumerate(targetIsotopes): if (i not in rootMapDims) and (isotopes in rootIsotopes): regions2 = [] # Chop at water for region in regions: valueMin, valueMax = region[i] if valueMin < waterMin < valueMax: regionA = list(region) regionA[i] = (valueMin, waterMin) regions2.append(regionA) if valueMin < waterMax < valueMax: regionB = list(region) regionB[i] = (waterMax, valueMax) regions2.append(regionB) elif valueMin < waterMax < valueMax: regionB = list(region) regionB[i] = (waterMax, valueMax) regions2.append(regionB) else: regions2.append(region) regions = regions2 peaks = [] for region in regions: peaks.extend(searchPeaks([ targetPeakList, ], region)) if pickNew: peaks.extend(findPeaks(targetPeakList, region)) # possible to grow the region here if no peaks are found for peak2 in peaks: for intens in peak.peakIntensities: if str(intens.value) == 'inf': peaks.remove(peak2) peak2.delete() break foundPeaks.extend(peaks) for i, peakDim in enumerate(boundPeakDims): dim2 = dimMapping[peakDim.dim] resonances = [c.resonance for c in peakDim.peakDimContribs] tolerance = tolerances[i] for peak2 in peaks: peakDim2 = peak2.findFirstPeakDim(dim=dim2) if not peakDim2.peakDimContribs: for resonance in resonances: assignResToDim(peakDim2, resonance, tolerance=10 * tolerance, doWarning=False) if progressBar: progressBar.increment() if progressBar: progressBar.close() return foundPeaks, dimMapping
def update(self, contrib, peakDim, aliasing=False, structure=None, limitedResonances=None, molSystems=None, component=None, noDisplay=False, doubleTol=False, resetScrollbars=True, showMolSystem=False): self.aliasing = aliasing self.contrib = contrib self.resonances = [] self.jCouplings = [] self.structure = structure self.component = component atomSets1 = [] if peakDim: self.peakDim = peakDim elif contrib: self.peakDim = None peakDim = contrib.peakDim else: self.scrolledMatrix.update(objectList=[], textMatrix=[ [], ]) return if component and (component.dataDimRef.expDimRef.unit != 'ppm'): headingList = ['#', 'Names', 'Delta', 'Coupling', 'SD'] tipTexts = TIP_TEXTS2 isCoupling = True else: tipTexts = TIP_TEXTS headingList = ['#', 'Name', 'Delta', 'Shift', 'SD', 'Dist'] isCoupling = False if showMolSystem: tipTexts = tipTexts[:] tipText = 'Mol System of resonance' if isCoupling: tipText += 's' tipTexts.append(tipText) headingList.append('MS') dataDimRef = peakDim.dataDimRef expDimRef = dataDimRef.expDimRef dataDim = dataDimRef.dataDim textMatrix = [] colorMatrix = [] if isCoupling: ppm = getAnalysisDataDim(peakDim.dataDim).assignTolerance points = peakDim.dataDimRef.valueToPoint(ppm) tolerance = component.dataDimRef.pointToValue(points) if doubleTol: tolerance *= 2 # get couplings that might match the splitting for delta, coupling in findMatchingCouplings(component, tolerance): resonanceA, resonanceB = coupling.resonances nameA = makeResonanceGuiName(resonanceA) nameB = makeResonanceGuiName(resonanceB) self.jCouplings.append(coupling) colors = [None, None, None, None, None] if coupling.error >= tolerance: colors[4] = '#d0a0a0' textMatrix.append([ '%d,%d' % (resonanceA.serial, resonanceB.serial), '%s-%s' % (nameA, nameB), '%5.3f' % round(delta, 3), coupling.value, '%5.3f' % round(coupling.error, 3) ]) colorMatrix.append(colors) if showMolSystem: molSystemA = getResonanceMolSystem(resonanceA) or '' molSystemB = getResonanceMolSystem(resonanceB) or '' if molSystemA == molSystemB: texts.append(molSystemA and molSystemA.code) else: texts.append('%s,%s' % (molSystemA and molSystemA.code, molSystemB and molSystemB.code)) colors.append(None) objectList = self.jCouplings else: # set up atomSets for distance calculations where possible if self.structure: for expTransfer in expDimRef.expTransfers: if expTransfer.transferType in longRangeTransfers: expDimRefs = list(expTransfer.expDimRefs) expDimRefs.remove(expDimRef) for peakDim1 in peakDim.peak.sortedPeakDims(): if peakDim1.dataDimRef.expDimRef is expDimRefs[0]: for contrib1 in peakDim1.peakDimContribs: resonance1 = contrib1.resonance if resonance1 and resonance1.resonanceSet: for atomSet in resonance1.resonanceSet.atomSets: atomSets1.append(atomSet) if component: # E.g. MQ or reduced dimensionality dataDimRef2 = component.dataDimRef if dataDimRef is dataDimRef2: ppm = abs(peakDim.value - peakDim.realValue) else: realPoint = ppm2pnt(peakDim.realValue, dataDimRef) deltaPoints = abs(peakDim.position - realPoint) ppm = abs(component.scalingFactor * dataDimRef2.pointToValue(deltaPoints)) peakUnit = dataDimRef2.expDimRef.unit or 'point' else: ppm = peakDim.realValue peakUnit = expDimRef.unit or 'point' shiftList = peakDim.peak.peakList.dataSource.experiment.shiftList shiftUnit = shiftList.unit tolerance = getAnalysisDataDim(dataDim).assignTolerance if doubleTol: tolerance *= 2 shifts = self.givePossAssignments(peakDim, tolerance, ppm) if len(shifts) > 0: # resonance matches temp = [] for shift in shifts: resonance = shift.resonance if limitedResonances is not None: if resonance not in limitedResonances: continue if molSystems: molSystem = getResonanceMolSystem(resonance) if molSystem and (molSystem not in molSystems): continue # Kludge until chain states if ( not molSystem ) and resonance.resonanceGroup and resonance.resonanceGroup.chains: molSystems2 = set([ ch.molSystem for ch in resonance.resonanceGroup.chains ]) if not molSystems2.intersection(molSystems): continue if peakUnit != shiftUnit: shiftValue = unit_converter[(shiftUnit, peakUnit)](shift.value, dataDimRef) else: shiftValue = shift.value points = unit_converter[(peakUnit, 'point')](shiftValue, dataDimRef) numAliasing = findNumAliasing(dataDimRef, points) deltaAliasing = numAliasing - peakDim.numAliasing if deltaAliasing: points -= dataDim.numPointsOrig * deltaAliasing shiftValue = unit_converter[('point', peakUnit)](points, dataDimRef) shift.isDiffAliasing = 1 else: shift.isDiffAliasing = 0 delta = abs(ppm - shiftValue) temp.append((delta, shift)) shift.delta = delta temp.sort() shifts = [x[1] for x in temp] textMatrix = [] colorMatrix = [] for shift in shifts: resonance = shift.resonance if limitedResonances is not None: if resonance not in limitedResonances: continue # wb104, 13 Apr 2016, added below (could check this instead in if statement # but the problem is that shift.delta also needs to exist further down # and also both attributes get deleted at bottom of the loop) if not hasattr(shift, 'isDiffAliasing'): continue if shift.isDiffAliasing: colors = [None, None, '#d0d0a0', None, None, None] else: colors = [None, None, None, None, None, None] name = makeResonanceGuiName(resonance) self.resonances.append(resonance) if shift.error >= tolerance: colors[4] = '#d0a0a0' if self.structure and atomSets1: if resonance.resonanceSet: atomSets2 = list(resonance.resonanceSet.atomSets) dist = getAtomSetsDistance(atomSets1, atomSets2, self.structure, method='noe') else: dist = None else: dist = None texts = [ resonance.serial, name, '%5.3f' % round(shift.delta, 3), shift.value, '%5.3f' % round(shift.error, 3), dist or ' ' ] if showMolSystem: molSystem = getResonanceMolSystem(resonance) texts.append(molSystem and molSystem.code) colors.append(None) textMatrix.append(texts) colorMatrix.append(colors) del shift.isDiffAliasing del shift.delta objectList = self.resonances if not noDisplay: self.scrolledMatrix.update(headingList=headingList, tipTexts=tipTexts, objectList=objectList, textMatrix=textMatrix, colorMatrix=colorMatrix, resetScrollbars=resetScrollbars)
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)
def assignPeakDimComponentResonance(component, resonance, tolerance=None): """ Assign a chemical shift to a peakDim component (e.g. reduced dimensionality) .. describe:: Input ccp.nmr.Nmr.PeakDimComponent, ccp.nmr.Nmr.Resonance, Float .. describe:: Output ccp.nmr.Nmr.PeakDimContrib """ # TBD version to cope with multiple resonances if resonance: dataDimRef = component.dataDimRef expDimRef = dataDimRef.expDimRef if resonance.isotopeCode not in expDimRef.isotopeCodes: return peakDimContrib = component.findFirstPeakDimContrib(resonance=resonance) if not peakDimContrib: experiment = expDimRef.expDim.experiment shiftList = experiment.shiftList if not tolerance: tolerance = getAnalysisDataDim( dataDimRef.dataDim).assignTolerance if not shiftList: nmrProject = experiment.nmrProject shiftList = nmrProject.findFirstMeasurementList( className='ShiftList') if not shiftList: shiftList = nmrProject.newShiftList( name='ShiftList 1', details='Assignment Default', unit='ppm') experiment.shiftList = shiftList shift = resonance.findFirstShift(parentList=shiftList) if shift: value = getPeakDimComponentSplitting(component) if abs(shift.value - value) > tolerance: return peakDim = component.peakDim peakDimContrib = peakDim.newPeakDimContrib( resonance=resonance, peakDimComponent=component) else: for contrib in component.peakDimContribs: contrib.delete() return return peakDimContrib
def averageJCouplingValue(jCoupling): """ Recalculate a J-coupling value based upon the peakDimComponents to which it may be assigned via resonances. Sets any peak and peakDim links. .. describe:: Input ccp.nmr.Nmr.JCoupling .. describe:: Output Float """ hasApp = hasattr(jCoupling.root, 'application') sum1 = 0.0 sum2 = 0.0 N = 0.0 sigma2 = 0.0 sigma = 0.0 mean = None peakDims = set() peakDimsAdd = peakDims.add resonances = jCoupling.resonances for resonance in resonances: for contrib in resonance.peakDimContribNs: component = contrib.peakDimComponent if not component: continue if not isinstance(contrib, Nmr.PeakDimContribN): continue if hasApp: weight = getAnalysisDataDim( component.dataDimRef.dataDim).chemShiftWeight else: weight = 1.0 value = getPeakDimComponentSplitting(component) vw = value * weight sum1 += vw sum2 += value * vw N += weight peakDimsAdd(contrib.peakDim) if N > 0.0: mean = sum1 / N mean2 = sum2 / N sigma2 = abs(mean2 - (mean * mean)) sigma = sqrt(sigma2) jCoupling.setValue(mean) jCoupling.setError(sigma) jCoupling.setPeakDims(peakDims) jCoupling.setPeaks(set([pd.peak for pd in peakDims])) else: jCoupling.setError(0.0) jCoupling.setPeakDims([]) jCoupling.setPeaks([]) return mean