Source code for ccpn.ui.gui.popups.PeakFind

"""Module Documentation here

"""
#=========================================================================================
# Licence, Reference and Credits
#=========================================================================================
__copyright__ = "Copyright (C) CCPN project (http://www.ccpn.ac.uk) 2014 - 2021"
__credits__ = ("Ed Brooksbank, Joanna Fox, Victoria A Higman, Luca Mureddu, Eliza Płoskoń",
               "Timothy J Ragan, Brian O Smith, Gary S Thompson & Geerten W Vuister")
__licence__ = ("CCPN licence. See http://www.ccpn.ac.uk/v3-software/downloads/license")
__reference__ = ("Skinner, S.P., Fogh, R.H., Boucher, W., Ragan, T.J., Mureddu, L.G., & Vuister, G.W.",
                 "CcpNmr AnalysisAssign: a flexible platform for integrated NMR analysis",
                 "J.Biomol.Nmr (2016), 66, 111-124, http://doi.org/10.1007/s10858-016-0060-y")
#=========================================================================================
# Last code modification
#=========================================================================================
__modifiedBy__ = "$modifiedBy: Ed Brooksbank $"
__dateModified__ = "$dateModified: 2021-06-28 11:41:02 +0100 (Mon, June 28, 2021) $"
__version__ = "$Revision: 3.0.4 $"
#=========================================================================================
# Created
#=========================================================================================
__author__ = "$Author: CCPN $"
__date__ = "$Date: 2017-04-07 10:28:41 +0000 (Fri, April 07, 2017) $"
#=========================================================================================
# Start of code
#=========================================================================================

from PyQt5 import QtWidgets, QtCore
from ccpn.ui.gui.widgets.Base import Base
from ccpn.ui.gui.widgets.Button import Button
from ccpn.ui.gui.widgets.ButtonList import ButtonList
from ccpn.ui.gui.widgets.RadioButtons import RadioButtons
from ccpn.ui.gui.widgets.DoubleSpinbox import DoubleSpinbox
from ccpn.ui.gui.widgets.Label import Label
from ccpn.ui.gui.widgets.Frame import Frame
from ccpn.ui.gui.widgets.PulldownList import PulldownList
from ccpn.ui.gui.popups.Dialog import CcpnDialog
from ccpn.ui.gui.widgets.MessageDialog import showInfo
from ccpn.ui.gui.widgets.CompoundWidgets import CheckBoxCompoundWidget


COLWIDTH = 140


[docs]class PeakFindPopup(CcpnDialog): """ PeakFind for nD spectra This popup works only for nDs. (Should be renamed?) """ def __init__(self, parent=None, mainWindow=None, **kwds): CcpnDialog.__init__(self, parent, setLayout=True, windowTitle='Pick ND peaks', **kwds) self.mainWindow = mainWindow self.project = self.mainWindow.project self.application = self.mainWindow.application self.current = self.application.current # if self.current.strip and not self.current.strip.isDeleted: # if not self.current.strip.spectra[-1].peakLists: # # # if there is no peaklist then create a new one # self.current.strip.spectra[0].newPeakList() # showInfo(str(self.windowTitle()), "Current selected spectrum '%s' has no peakList:" # "New peakList '%s' inserted" # % (str(self.current.strip.spectra[0].pid), # str(self.current.strip.spectra[0].peakLists[0].pid))) self.peakListLabel = Label(self, text="PeakList ", grid=(0, 0)) self.peakListPulldown = PulldownList(self, grid=(0, 1), gridSpan=(1, 2), hAlign='l', callback=self._selectPeakList) self.checkBoxWidget = Frame(self, setLayout=True, grid=(1,0), gridSpan=(1,6)) Label(self.checkBoxWidget, 'Pick', grid=(0, 0)) self.spectrumContourSelect = RadioButtons(self.checkBoxWidget, grid=(0, 1), texts=['Positive only', 'Negative only', 'Both'], selectedInd=2, callback=None, direction='h', hAlign='l', tipTexts=['Only pick positive peaks', 'Only pick negative peaks', 'Pick all peaks'], ) self.checkBox1, self.checkBox2, self.checkBox3 = self.spectrumContourSelect.radioButtons self.limitsFrame = Frame(parent=self, setLayout=True, spacing=(5, 0), showBorder=False, fShape='noFrame', grid=(2, 0), gridSpan=(1,6)) self.estimateFrame = Frame(parent=self, setLayout=True, spacing=(5, 0), showBorder=False, fShape='noFrame', grid=(3, 0), gridSpan=(1,6)) self.estimateLineWidths = CheckBoxCompoundWidget(self.estimateFrame, grid=(0, 0), vAlign='top', stretch=(0, 0), hAlign='left', # fixedWidths=(COLWIDTH, 30), orientation='right', labelText='Estimate Line Widths', checked=True ) self.estimateVolumes = CheckBoxCompoundWidget(self.estimateFrame, grid=(0, 1), vAlign='top', stretch=(0, 0), hAlign='left', # fixedWidths=(COLWIDTH, 30), orientation='right', labelText='Estimate Peak Volumes', checked=True ) self.addSpacer(5, 5, expandX=True, expandY=True, grid=(4,5)) self.buttonBox = ButtonList(self, grid=(5, 3), gridSpan=(1, 3), texts=['Cancel', 'Find Peaks'], callbacks=[self.reject, self._pickPeaks]) self.peakListPulldown.setData([peakList.pid for peakList in self.project.peakLists if peakList.spectrum.dimensionCount != 1]) if self.current is not None and self.current.strip is not None and len(self.current.strip.spectra) > 0: self.peakListPulldown.select(self.current.strip.spectra[-1].peakLists[-1].pid) self.peakList = self.project.getByPid(self.peakListPulldown.currentText()) # populate the estimateFrame self._updateContents() self.setFixedSize(self.sizeHint()) # else: # self.close() def _selectPeakList(self, item): self.peakList = self.project.getByPid(item) self._updateContents() def _pickPeaks(self): peakList = self.peakList positions = [[x.value(), y.value()] for x, y in zip(self.minPositionBoxes, self.maxPositionBoxes)] doPos = True doNeg = True if self.checkBox1.isChecked(): # Positive only doNeg = False elif self.checkBox2.isChecked(): # negative only doPos = False doLineWidths = self.estimateLineWidths.isChecked() doVolumes = self.estimateVolumes.isChecked() # Checking the third box turns the others off and sets both. Hence default # peakList.pickPeaksNd(positions, doPos=doPos, doNeg=doNeg, fitMethod='gaussian') axisCodeDict = dict((code, positions[ii]) for ii, code in enumerate(self.peakList.spectrum.axisCodes)) _spectrum = peakList.spectrum # may create a peakPicker instance if not defined, subject to settings in preferences _peakPicker = _spectrum.peakPicker if _peakPicker: _peakPicker.dropFactor = self.application.preferences.general.peakDropFactor _peakPicker.setLineWidths = doLineWidths _spectrum.pickPeaks(peakList, _spectrum.positiveContourBase if doPos else None, _spectrum.negativeContourBase if doNeg else None, **axisCodeDict) # estimate the peak volumes if doVolumes and doLineWidths: peakList.estimateVolumes(volumeIntegralLimit=self.application.preferences.general.volumeIntegralLimit) self.accept() def _updateContents(self): # updat the contents of the limits frame to the new spectrum layout = self.limitsFrame.getLayout() rowCount = layout.rowCount() colCount = layout.columnCount() for r in range(2, 7): for m in range(0, colCount): item = layout.itemAtPosition(r, m) if item: if item.widget(): item.widget().hide() layout.removeItem(item) self.minPositionBoxes = [] self.maxPositionBoxes = [] if self.peakList is not None: for ii in range(self.peakList.spectrum.dimensionCount): dim1MinLabel = Label(self.limitsFrame, text='F%s ' % str(ii + 1) + self.peakList.spectrum.axisCodes[ii] + ' min', grid=(2 + ii, 0), vAlign='t') dim1MinDoubleSpinBox = DoubleSpinbox(self.limitsFrame, grid=(2 + ii, 1), vAlign='t') dim1MinDoubleSpinBox.setMinimum(self.peakList.spectrum.aliasingLimits[ii][0]) dim1MinDoubleSpinBox.setMaximum(self.peakList.spectrum.aliasingLimits[ii][1]) dim1MinDoubleSpinBox.setValue(self.peakList.spectrum.aliasingLimits[ii][0]) dim1MaxLabel = Label(self.limitsFrame, text='F%s ' % str(ii + 1) + self.peakList.spectrum.axisCodes[ii] + ' max', grid=(2 + ii, 2), vAlign='t') dim1MaxDoubleSpinBox = DoubleSpinbox(self.limitsFrame, grid=(2 + ii, 3)) dim1MaxDoubleSpinBox.setMinimum(self.peakList.spectrum.aliasingLimits[ii][0]) dim1MaxDoubleSpinBox.setMaximum(self.peakList.spectrum.aliasingLimits[ii][1]) dim1MaxDoubleSpinBox.setValue(self.peakList.spectrum.aliasingLimits[ii][1]) self.minPositionBoxes.append(dim1MinDoubleSpinBox) self.maxPositionBoxes.append(dim1MaxDoubleSpinBox) # self.excludedRegionsButton = Button(self, grid=(self.peakList.spectrum.dimensionCount+3, 0), text='Exclude Regions') # self.excludedRegionsButton.setCheckable(True) # self.excludedRegionsButton.toggled.connect(self.toggleExcludedRegionsPopup) def _toggleExcludedRegionsPopup(self): if not hasattr(self, 'excludedRegionsPopup'): self.raiseExcludedRegionsPopup() else: if self.excludedRegionsButton.isChecked(): self.excludedRegionsPopup.show() else: self.excludedRegionsPopup.hide()
[docs] def raiseExcludedRegionsPopup(self): self.excludedRegionsPopup = ExcludeRegions(self, self.peakList) self.layout().addWidget(self.excludedRegionsPopup, 5, 0, 1, 4)
[docs]class ExcludeRegions(QtWidgets.QWidget, Base): def __init__(self, parent, peakList): super(ExcludeRegions, self).__init__(parent) self.regionCount = 0 self.peakList = peakList self.addRegionButton = Button(self, text='Add Region', callback=self._addRegion, grid=(20, 0), gridSpan=(1, 3)) self.removeRegionButton = Button(self, text='Remove Region', callback=self._removeRegion, grid=(20, 3), gridSpan=(1, 3)) self.excludedRegions = [] def _addRegion(self): self.regionCount += 1 minRegion = [] maxRegion = [] for ii in range(self.peakList.spectrum.dimensionCount): print(self.peakList.spectrum.dimensionCount) dim1MinLabel = Label(self, text='F%s ' % str(1 + ii) + self.peakList.spectrum.axisCodes[ii] + ' min', grid=(1 + ii * self.regionCount, 0), vAlign='t') dim1MinDoubleSpinBox = DoubleSpinbox(self, grid=(1 + ii * self.regionCount, 1), vAlign='t') dim1MinDoubleSpinBox.setMinimum(self.peakList.spectrum.aliasingLimits[ii][0]) dim1MinDoubleSpinBox.setMaximum(self.peakList.spectrum.aliasingLimits[ii][1]) dim1MinDoubleSpinBox.setValue(self.peakList.spectrum.aliasingLimits[ii][0]) minRegion.append(dim1MinDoubleSpinBox) dim1MaxLabel = Label(self, text='F%s ' % str(1 + ii) + self.peakList.spectrum.axisCodes[ii] + ' max', grid=(1 + ii * self.regionCount, 2), vAlign='t') dim1MaxDoubleSpinBox = DoubleSpinbox(self, grid=(1 + ii * self.regionCount, 3)) dim1MaxDoubleSpinBox.setMinimum(self.peakList.spectrum.aliasingLimits[ii][0]) dim1MaxDoubleSpinBox.setMaximum(self.peakList.spectrum.aliasingLimits[ii][1]) dim1MaxDoubleSpinBox.setValue(self.peakList.spectrum.aliasingLimits[ii][1]) maxRegion.append(dim1MaxDoubleSpinBox) # self.minPositionBoxes.append(dim1MinDoubleSpinBox) # self.maxPositionBoxes.append(dim1MaxDoubleSpinBox) self.excludedRegions.append([minRegion, maxRegion]) self.regionCount += 1 def _removeRegion(self): for i in range(5): item = self.layout().itemAtPosition(self.regionCount, i)
# print(item, i, self.regionCount) # self.regionCount-=1