Here is a macro that will automatically assign your i and i-1 Ca/Cb/C atoms when you do the Pick & Assign step of a backbone assignment.
Simply do your Pick & Assign as usual (https://www.ccpn.ac.uk/manual/v3/PickAndAssign.html), but after you`ve done the `Pick and Assign Selected` for each NmrResidue, run this macro to assign your carbon NmrAtoms rather than using the NmrAtom Assigner. Makes for much less clicking, and if you have little overlap it should work really nicely and not need much in the way of manual corrections.
It`s probably easiest to link the macro with a shortcut so you can repeatedly run it quickly and easily (see https://www.ccpn.ac.uk/manual/v3/RunningMacros.html for more info).
Have a read through the information to check on requirements (e.g. you`ll have to set your experiment types).
- """
- Macro to assign the Ca/Cb/C NmrAtoms when doing the Pick & Assign step of a
- backbone assignment.
-
- This should work with any combination of HNCACB/HNCOCACB, HNCA/HNCOCA, HNCO/HNCACO spectra.
-
- REQUIREMENTS:
- 1. Make sure your spectra have the correct Experiment Types associated with them (shortcut
- ET to set these).
- 2. The macro assumes that all 3D carbon AxisCodes are `C`. For HNCO/HNcaCO experiments you
- may find that these are `CO`. We recommend setting these to `C` by going to
- Spectrum Properties (double-click on the spectrum in the sidebar), then the Dimensions tab
- and here you can check/change the AxisCode.
- 3. Pick and Assign the peaks for an NmrResidue using the Pick and Assign module (PA), then
- run the macro before moving to the next residue. This is easiest if you associate the
- macro with a keyboard shortcut (you can do this with shortcut DU).
- 4. The Macro assumes that you always have the CO-based experiment (e.g. HNcoCACB, HNcoCA or HNCO)
- as well as the CA-based one (e.g. HNCACB, HNCA or HNcoCA) , i.e. it assigns the i-1 NmrResidues
- based on the peaks in the CO-based experiments rather than on peak intensities.
-
- OPTIONS:
- - The macro currently uses a tolerance of 0.2 ppm. Peaks closer than this are assumed to belong to
- the same NmrAtom, i.e. if a peak in the HNCA is within 0.2 ppm of a peak in the HNcoCA, it is
- assumed that this is the i-1 and not the i peak. You can change this tolerance at the top of
- the Settings section.
-
- NOTE:
- The macro assumes you have a relatively straight forward pattern of peaks. If you have
- picked lots of noise peaks you may not get correct behaviour (make sure you adjust your
- contour level before doing the `Pick & Assign Selected` step). You may also have to make manual
- corrections if there is peak overlap, e.g. between the i and i-1 atoms.
-
- """
-
- ############################## Settings #################################
-
- tolerance = 0.2 # peaks closer than this value in ppm are assumed to belong to the same NmrAtom
- assignAxCde = `C` # Carbon AxisCode to be assigned, may need changing for HNCO/HNcoCA expts
- assignDim = 2 # Spectrum dimension to be assigned (0,1,2 for 3Ds)
- rootDim = 0 # One of the root dimensions which has already been assigned (0,1,2 for 3Ds)
- coSpectra = [`H[N[co[{CA|ca[C]}]]]`, `H[N[co[CA]]]`, `H[N[CO]]`]
- # Possible experiment types for `through-CO`/i-1 type spectra
- nonCoSpectra = [`H[N[{CA|ca[Cali]}]]`, `H[N[CA]]`, `H[N[ca[CO]]]`]
- # Possible experiment types for `through-CA`/i,i-1 type spectra
- gstCheckDict = {`CA-1`:{`shifts`:[], `peaks`:[]},
- `CB-1`:{`shifts`:[], `peaks`:[]},
- `CA0`:{`shifts`:[], `peaks`:[]},
- `CB0`:{`shifts`:[], `peaks`:[]}}
- # Data storage for Gly/Ser/Thr check and re-assignment if necessary
-
-
- ############################## Start of the code #################################
-
- import sys
- from statistics import mean
- from ccpn.core.lib.ContextManagers import undoBlock
- from ccpn.ui.gui.widgets.MessageDialog import showWarning
-
-
- def assignNmrAtom(seqCode, atomName, offset):
- if offset == -1:
- newsc = ``.join((seqCode, `-1`))
- newnr = nc.fetchNmrResidue(sequenceCode=newsc, residueType=None)
- newna = newnr.fetchNmrAtom(name=atomName)
- elif offset == 0:
- newna = peakNmrRes.fetchNmrAtom(name=atomName)
- peak.assignDimension(axisCode=assignAxCde, value=newna)
-
-
- def storeDataForGSTCheck(peakShift, peak, atomType):
- gstCheckDict[atomType][`shifts`].append(peakShift)
- gstCheckDict[atomType][`peaks`].append(peak)
-
-
- def checkForGST(gstDict):
- cas1 = gstDict[`CA-1`][`shifts`]
- cbs1 = gstDict[`CB-1`][`shifts`]
- peaks1 = gstDict[`CA-1`][`peaks`] + gstDict[`CB-1`][`peaks`]
- identifyAndAssignGST(cas1, cbs1, peaks1)
- cas2 = gstDict[`CA0`][`shifts`]
- cbs2 = gstDict[`CB0`][`shifts`]
- peaks2 = gstDict[`CA0`][`peaks`] + gstDict[`CB0`][`peaks`]
- identifyAndAssignGST(cas2, cbs2, peaks2)
-
-
- def identifyAndAssignGST(cas, cbs, peaks):
- if len(cas) == 0 and len(cbs) != 0:
- if 50.0 > mean(cbs) > 40.0:
- for pk in peaks:
- nr = pk.assignmentsByDimensions[assignDim][0].nmrResidue
- na = nr.fetchNmrAtom(name=`CA`)
- pk.assignDimension(axisCode=assignAxCde, value=na)
- elif len(cbs) == 0 and len(cas) >= 2:
- for pk in peaks:
- if pk.ppmPositions[assignDim] > mean(cas):
- nr = pk.assignmentsByDimensions[assignDim][0].nmrResidue
- na = nr.fetchNmrAtom(name=`CB`)
- pk.assignDimension(axisCode=assignAxCde, value=na)
-
-
- if current.peak.assignmentsByDimensions[rootDim]:
- nc = current.peak.assignmentsByDimensions[rootDim][0].nmrResidue.nmrChain
- else:
- showWarning(`Missing Root Assignment`, `Please make sure all your peaks have `
- `their root NH NmrAtoms assigned`)
- sys.exit()
-
- with undoBlock():
- for peak in current.peaks:
- peakSpectrum = peak.peakList.spectrum
- peakSpectrumName = peakSpectrum.name
- peakExptType = peakSpectrum.experimentType
- if peak.assignmentsByDimensions[rootDim]:
- peakNmrRes = peak.assignmentsByDimensions[rootDim][0].nmrResidue
- else:
- showWarning(`Missing Root Assignment`, `Please make sure all your peaks have `
- `their root NH NmrAtoms assigned`)
- sys.exit()
- peakSeqCode = peakNmrRes.sequenceCode
- peakShift = peak.ppmPositions[assignDim]
- # Assign CO-based i-1 spectra
- if peakExptType in coSpectra:
- if 80.0 >= peakShift >= 47.0:
- assignNmrAtom(peakSeqCode, atomName=`CA`, offset=-1)
- storeDataForGSTCheck(peakShift, peak, atomType=`CA-1`)
- elif peakShift < 47.0:
- assignNmrAtom(peakSeqCode, atomName=`CB`, offset=-1)
- storeDataForGSTCheck(peakShift, peak, atomType=`CB-1`)
- elif peakShift >= 160.0:
- assignNmrAtom(peakSeqCode, atomName=`C`, offset=-1)
- # Assign CA-based i/i-1 spectra
- elif peakExptType in nonCoSpectra:
- if 80.0 >= peakShift >= 47.0:
- for peak2 in current.peaks:
- if peak2.peakList.spectrum.experimentType in coSpectra:
- if abs(peakShift - peak2.ppmPositions[assignDim]) <= tolerance:
- assignNmrAtom(peakSeqCode, atomName=`CA`, offset=-1)
- storeDataForGSTCheck(peakShift, peak, atomType=`CA-1`)
- if not peak.assignmentsByDimensions[assignDim]:
- assignNmrAtom(peakSeqCode, atomName=`CA`, offset=0)
- storeDataForGSTCheck(peakShift, peak, atomType=`CA0`)
- elif peakShift < 47.0:
- for peak2 in current.peaks:
- if peak2.peakList.spectrum.experimentType in coSpectra:
- if abs(peakShift - peak2.ppmPositions[assignDim]) <= tolerance:
- assignNmrAtom(peakSeqCode, `CB`, offset=-1)
- storeDataForGSTCheck(peakShift, peak, atomType=`CB-1`)
- if not peak.assignmentsByDimensions[assignDim]:
- assignNmrAtom(peakSeqCode, atomName=`CB`, offset=0)
- storeDataForGSTCheck(peakShift, peak, atomType=`CB0`)
- elif peakShift >= 160.0:
- for peak2 in current.peaks:
- if peak2.peakList.spectrum.experimentType in coSpectra:
- if abs(peakShift - peak2.ppmPositions[assignDim]) <= tolerance:
- assignNmrAtom(peakSeqCode, `C`, offset=-1)
- if not peak.assignmentsByDimensions[assignDim]:
- assignNmrAtom(peakSeqCode, atomName=`C`, offset=0)
- elif peakExptType is None:
- showWarning(`Missing Experiment Type`, `Please make sure all `
- `your spectra have an Experiment Type `
- `associated with them (use shortcut ET `
- `to set these)`)
- sys.exit()
-
- checkForGST(gstCheckDict)