Source code for ccpn.ui.gui.widgets.GLWidgets

"""
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: Geerten Vuister $"
__dateModified__ = "$dateModified: 2021-12-23 11:27:19 +0000 (Thu, December 23, 2021) $"
__version__ = "$Revision: 3.0.4 $"
#=========================================================================================
# Created
#=========================================================================================
__author__ = "$Author: CCPN $"
__date__ = "$Date: 2018-12-20 15:44:35 +0000 (Thu, December 20, 2018) $"
#=========================================================================================
# Start of code
#=========================================================================================

import numpy as np
from itertools import zip_longest
from ccpn.ui.gui.lib.OpenGL.CcpnOpenGL import CcpnGLWidget, GLVertexArray, GLRENDERMODE_DRAW, \
    GLRENDERMODE_RESCALE
from ccpn.ui.gui.lib.OpenGL.CcpnOpenGLDefs import YAXISUNITS1D, SPECTRUM_VALUEPERPOINT
import ccpn.util.Phasing as Phasing
from ccpn.core.lib.AxisCodeLib import getAxisCodeMatchIndices
from ccpn.ui.gui.lib.OpenGL import CcpnOpenGLDefs as GLDefs
from ccpn.util.Logging import getLogger
from ccpn.core.lib.peakUtils import movePeak

from ccpn.ui.gui.lib.OpenGL import GL


[docs]class GuiNdWidget(CcpnGLWidget): is1D = False INVERTXAXIS = True INVERTYAXIS = True SPECTRUMPOSCOLOUR = 'positiveContourColour' SPECTRUMNEGCOLOUR = 'negativeContourColour' AXIS_INSIDE = False def __init__(self, strip=None, mainWindow=None, stripIDLabel=None): super().__init__(strip=strip, mainWindow=mainWindow, stripIDLabel=stripIDLabel) def _mouseInPeak(self, xPosition, yPosition, firstOnly=False): """Find the peaks under the mouse. If firstOnly is true, return only the first item, else an empty list """ xPositions = [xPosition - self.symbolX, xPosition + self.symbolX] yPositions = [yPosition - self.symbolY, yPosition + self.symbolY] if len(self._orderedAxes) > 2: zPositions = self._orderedAxes[2].region else: zPositions = None peaks = [] for spectrumView in self.strip.spectrumViews: for peakListView in spectrumView.peakListViews: if spectrumView.isDisplayed and peakListView.isDisplayed: peakList = peakListView.peakList spectrumIndices = spectrumView.dimensionIndices xAxis = spectrumIndices[0] yAxis = spectrumIndices[1] for peak in peakList.peaks: if len(peak.axisCodes) > 2 and zPositions is not None: zAxis = spectrumIndices[2] if (xPositions[0] < float(peak.position[xAxis]) < xPositions[1] and yPositions[0] < float(peak.position[yAxis]) < yPositions[1]): # within the XY bounds so check whether inPlane _isInPlane, _isInFlankingPlane, planeIndex, fade = self._GLPeaks.objIsInVisiblePlanes(spectrumView, peak) # if zPositions[0] < float(peak.position[zAxis]) < zPositions[1]: if _isInPlane: peaks.append(peak) if firstOnly: return peaks else: if (xPositions[0] < float(peak.position[xAxis]) < xPositions[1] and yPositions[0] < float(peak.position[yAxis]) < yPositions[1]): peaks.append(peak) if firstOnly: return peaks if peak in self.current.peaks else [] return peaks def _mouseInMultiplet(self, xPosition, yPosition, firstOnly=False): """Find the multiplets under the mouse. If firstOnly is true, return only the first item, else an empty list """ xPositions = [xPosition - self.symbolX, xPosition + self.symbolX] yPositions = [yPosition - self.symbolY, yPosition + self.symbolY] if len(self._orderedAxes) > 2: zPositions = self._orderedAxes[2].region else: zPositions = None multiplets = [] for spectrumView in self.strip.spectrumViews: for multipletListView in spectrumView.multipletListViews: if spectrumView.isDisplayed and multipletListView.isDisplayed: multipletList = multipletListView.multipletList spectrumIndices = spectrumView.dimensionIndices xAxis = spectrumIndices[0] yAxis = spectrumIndices[1] for multiplet in multipletList.multiplets: if not multiplet.position: continue if len(multiplet.axisCodes) > 2 and zPositions is not None: zAxis = spectrumIndices[2] if (xPositions[0] < float(multiplet.position[xAxis]) < xPositions[1] and yPositions[0] < float(multiplet.position[yAxis]) < yPositions[1]): # within the XY bounds so check whether inPlane _isInPlane, _isInFlankingPlane, planeIndex, fade = self._GLMultiplets.objIsInVisiblePlanes(spectrumView, multiplet) # if zPositions[0] < float(multiplet.position[zAxis]) < zPositions[1]: if _isInPlane: multiplets.append(multiplet) if firstOnly: return multiplets else: if (xPositions[0] < float(multiplet.position[xAxis]) < xPositions[1] and yPositions[0] < float(multiplet.position[yAxis]) < yPositions[1]): multiplets.append(multiplet) if firstOnly: return multiplets if multiplet in self.current.multiplets else [] return multiplets def _mouseInIntegral(self, xPosition, yPosition, firstOnly=False): """Find the integrals under the mouse. If firstOnly is true, return only the first item, else an empty list Currently not-defined for Nd integrals """ return [] def _updateVisibleSpectrumViews(self): """Update the list of visible spectrumViews when change occurs """ # make the list of ordered spectrumViews self._ordering = self.strip.getSpectrumViews() # GWV: removed as new data reader returns zeros; blank spectra can be displayed # self._ordering = [specView for specView in self._ordering if specView.spectrum.hasValidPath()] for specView in tuple(self._spectrumSettings.keys()): if specView not in self._ordering: del self._spectrumSettings[specView] # delete the 1d string relating to the spectrumView self._spectrumLabelling.removeString(specView) # make a list of the visible and not-deleted spectrumViews # visibleSpectra = [specView.spectrum for specView in self._ordering if not specView.isDeleted and specView.isDisplayed] visibleSpectrumViews = [specView for specView in self._ordering if not specView.isDeleted and specView.isDisplayed] self._visibleOrdering = visibleSpectrumViews # set the first visible, or the first in the ordered list self._firstVisible = visibleSpectrumViews[0] if visibleSpectrumViews else self._ordering[0] if self._ordering and not self._ordering[ 0].isDeleted else None self.visiblePlaneList = {} self.visiblePlaneListPointValues = {} self.visiblePlaneDimIndices = {} # generate the new axis labels based on the visible spectrum axisCodes self._buildAxisCodesWithWildCards() minList = [self._spectrumSettings[sp][SPECTRUM_VALUEPERPOINT] if SPECTRUM_VALUEPERPOINT in self._spectrumSettings[sp] else None for sp in self._ordering if sp in self._spectrumSettings] minimumValuePerPoint = None # check the length of the min values, may have lower dimension spectra overlaid for val in minList: if minimumValuePerPoint and val is not None: minimumValuePerPoint = [min(ii, jj) for ii, jj in zip_longest(minimumValuePerPoint, val, fillvalue=0.0)] elif minimumValuePerPoint: # val is None so ignore pass else: # set the first value minimumValuePerPoint = val for visibleSpecView in self._ordering: visValues = visibleSpecView._getVisiblePlaneList( firstVisible=self._firstVisible, minimumValuePerPoint=minimumValuePerPoint) self.visiblePlaneList[visibleSpecView], \ self.visiblePlaneListPointValues[visibleSpecView], \ self.visiblePlaneDimIndices[visibleSpecView] = visValues # update the labelling lists self._GLPeaks.setListViews(self._ordering) self._GLIntegrals.setListViews(self._ordering) self._GLMultiplets.setListViews(self._ordering)
[docs] def getPeakPositionFromMouse(self, peak, lastStartCoordinate, cursorPosition=None): """Get the centre position of the clicked peak """ indices = getAxisCodeMatchIndices(self._axisCodes, peak.axisCodes) for ii, ind in enumerate(indices[:2]): if ind is not None: lastStartCoordinate[ii] = peak.position[ind] else: lastStartCoordinate[ii] = cursorPosition[ii]
def _movePeak(self, peak, deltaPosition): """Move the peak to new position """ indices = getAxisCodeMatchIndices(self.axisCodes, peak.axisCodes) # get the correct coordinates based on the axisCodes p0 = list(peak.position) for ii, ind in enumerate(indices[:2]): if ind is not None: # update the peak position p0[ind] += deltaPosition[ii] aliasInds = peak.spectrum.aliasingIndexes lims = peak.spectrum.spectrumLimits widths = peak.spectrum.spectralWidths for dim, pos in enumerate(p0): # update the aliasing so that the peak stays within the bounds of the spectrumLimits/aliasingLimits minSpectrumFrequency, maxSpectrumFrequency = sorted(lims[dim]) regionBounds = (minSpectrumFrequency + aliasInds[dim][0] * widths[dim], maxSpectrumFrequency + aliasInds[dim][1] * widths[dim]) p0[dim] = (pos - regionBounds[0]) % (regionBounds[1] - regionBounds[0]) + regionBounds[0] movePeak(peak, p0, updateHeight=True) def _tracesNeedUpdating(self, spectrumView=None): """Check if traces need updating on _lastTracePoint, use spectrumView to see if cursor has moved sufficiently far to warrant an update of the traces """ cursorCoordinate = self.getCurrentCursorCoordinate() if spectrumView not in self._lastTracePoint: numDim = len(spectrumView.strip.axes) self._lastTracePoint[spectrumView] = [-1] * numDim lastTrace = self._lastTracePoint[spectrumView] ppm2point = spectrumView.spectrum.ppm2point # get the correct ordering for horizontal/vertical planeDims = self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_POINTINDEX] point = [0] * len(cursorCoordinate) for n in range(2): point[planeDims[n]] = ppm2point(cursorCoordinate[n], dimension=planeDims[n] + 1) - 1 point = [round(p) for p in point] if None in planeDims: getLogger().warning(f'bad planeDims {planeDims}') return if None in point: getLogger().warning(f'bad point {point}') return # numPoints = spectrumView.spectrum.pointCounts # xNumPoints, yNumPoints = numPoints[planeDims[0]], numPoints[planeDims[1]] # if point[planeDims[0]] >= xNumPoints or point[planeDims[1]] >= yNumPoints: # # Extra check whether the new point is out of range if numLimits # return False if self._updateHTrace and not self._updateVTrace and point[planeDims[1]] == lastTrace[planeDims[1]]: # Only HTrace, an y-point has not changed return False elif not self._updateHTrace and self._updateVTrace and point[planeDims[0]] == lastTrace[planeDims[0]]: # Only VTrace and x-point has not changed return False elif self._updateHTrace and self._updateVTrace and point[planeDims[0]] == lastTrace[planeDims[0]] \ and point[planeDims[1]] == lastTrace[planeDims[1]]: # both HTrace and Vtrace, both x-point an y-point have not changed return False # We need to update; save this point as the last point self._lastTracePoint[spectrumView] = point return True
[docs] def drawAliasedLabels(self): """Draw all the labels that require aliasing to multiple regions """ _shader = self.globalGL._shaderProgramTexAlias.makeCurrent() # set the scale to the axis limits, needs addressing correctly, possibly same as grid _shader.setProjectionAxes(self._uPMatrix, self.axisL, self.axisR, self.axisB, self.axisT, -1.0, 1.0) _shader.setPTexMatrix(self._uPMatrix) self._axisScale[0:4] = [self.pixelX, self.pixelY, 0.0, 1.0] _shader.setAxisScale(self._axisScale) _shader.setStackOffset(np.array((0.0, 0.0), dtype=np.float32)) _shader.setAliasEnabled(self._aliasEnabled and self._aliasLabelsEnabled) # change to correct value for shader _shader.setAliasShade(self._aliasShade / 100.0) for specView in self._ordering: if specView.isDeleted: continue if specView.isDisplayed and specView in self._spectrumSettings.keys(): # set correct transform when drawing this contour specSettings = self._spectrumSettings[specView] # pIndex = specSettings[GLDefs.SPECTRUM_POINTINDEX] # if None in pIndex: # continue # should move this to buildSpectrumSettings # and emit a signal when visibleAliasingRange or foldingModes are changed # fx0 = specSettings[GLDefs.SPECTRUM_MAXXALIAS] # # fx1 = specSettings[GLDefs.SPECTRUM_MINXALIAS] # fy0 = specSettings[GLDefs.SPECTRUM_MAXYALIAS] # # fy1 = specSettings[GLDefs.SPECTRUM_MINYALIAS] # dxAF = specSettings[GLDefs.SPECTRUM_DXAF] # dyAF = specSettings[GLDefs.SPECTRUM_DYAF] # xScale = specSettings[GLDefs.SPECTRUM_XSCALE] # yScale = specSettings[GLDefs.SPECTRUM_YSCALE] specMatrix = np.array(specSettings[GLDefs.SPECTRUM_MATRIX], dtype=np.float32) # alias = specView.spectrum.visibleAliasingRange # folding = specView.spectrum.foldingModes _, fxMax = specSettings[GLDefs.SPECTRUM_XLIMITS] _, fyMax = specSettings[GLDefs.SPECTRUM_YLIMITS] dxAF, dyAF = specSettings[GLDefs.SPECTRUM_AF] xScale, yScale = specSettings[GLDefs.SPECTRUM_SCALE] alias = specSettings[GLDefs.SPECTRUM_ALIASINGINDEX] folding = specSettings[GLDefs.SPECTRUM_FOLDINGMODE] for ii in range(alias[0][0], alias[0][1] + 1, 1): for jj in range(alias[1][0], alias[1][1] + 1, 1): foldX = foldY = 1.0 foldXOffset = foldYOffset = 0 if folding[0] == 'mirror': foldX = pow(-1, ii) foldXOffset = -dxAF if foldX < 0 else 0 if folding[1] == 'mirror': foldY = pow(-1, jj) foldYOffset = -dyAF if foldY < 0 else 0 self._axisScale[0:4] = [foldX * self.pixelX / xScale, foldY * self.pixelY / yScale, 0.0, 1.0] _shader.setAxisScale(self._axisScale) specMatrix[0:16] = [xScale * foldX, 0.0, 0.0, 0.0, 0.0, yScale * foldY, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, fxMax + (ii * dxAF) + foldXOffset, fyMax + (jj * dyAF) + foldYOffset, 0.0, 1.0] # flipping in the same GL region - xScale = -xScale # offset = fx0-dxAF # circular - offset = fx0 + dxAF*alias, alias = min->max _shader.setMVMatrix(specMatrix) _shader.setAliasPosition(ii, jj) if self._peakLabelsEnabled: self._GLPeaks.drawLabels(specView) if self._multipletLabelsEnabled: self._GLMultiplets.drawLabels(specView)
[docs] def drawAliasedSymbols(self): """Draw all the symbols that require aliasing to multiple regions """ _shader = self.globalGL._shaderProgramAlias.makeCurrent() # set the scale to the axis limits, needs addressing correctly, possibly same as grid _shader.setProjectionAxes(self._uPMatrix, self.axisL, self.axisR, self.axisB, self.axisT, -1.0, 1.0) _shader.setPMatrix(self._uPMatrix) lineThickness = self._symbolThickness GL.glLineWidth(lineThickness * self.viewports.devicePixelRatio) _shader.setAliasEnabled(self._aliasEnabled) # change to correct value for shader _shader.setAliasShade(self._aliasShade / 100.0) for specView in self._ordering: if specView.isDeleted: continue if specView.isDisplayed and specView in self._spectrumSettings.keys(): specSettings = self._spectrumSettings[specView] # pIndex = specSettings[GLDefs.SPECTRUM_POINTINDEX] # if None in pIndex: # continue # should move this to buildSpectrumSettings # and emit a signal when visibleAliasingRange or foldingModes are changed # fx0 = specSettings[GLDefs.SPECTRUM_MAXXALIAS] # # fx1 = specSettings[GLDefs.SPECTRUM_MINXALIAS] # fy0 = specSettings[GLDefs.SPECTRUM_MAXYALIAS] # # fy1 = specSettings[GLDefs.SPECTRUM_MINYALIAS] # dxAF = specSettings[GLDefs.SPECTRUM_DXAF] # dyAF = specSettings[GLDefs.SPECTRUM_DYAF] # xScale = specSettings[GLDefs.SPECTRUM_XSCALE] # yScale = specSettings[GLDefs.SPECTRUM_YSCALE] specMatrix = np.array(specSettings[GLDefs.SPECTRUM_MATRIX], dtype=np.float32) # alias = specView.spectrum.visibleAliasingRange # folding = specView.spectrum.foldingModes _, fxMax = specSettings[GLDefs.SPECTRUM_XLIMITS] _, fyMax = specSettings[GLDefs.SPECTRUM_YLIMITS] dxAF, dyAF = specSettings[GLDefs.SPECTRUM_AF] xScale, yScale = specSettings[GLDefs.SPECTRUM_SCALE] alias = specSettings[GLDefs.SPECTRUM_ALIASINGINDEX] folding = specSettings[GLDefs.SPECTRUM_FOLDINGMODE] for ii in range(alias[0][0], alias[0][1] + 1, 1): for jj in range(alias[1][0], alias[1][1] + 1, 1): foldX = foldY = 1.0 foldXOffset = foldYOffset = 0 if folding[0] == 'mirror': foldX = pow(-1, ii) foldXOffset = -dxAF if foldX < 0 else 0 if folding[1] == 'mirror': foldY = pow(-1, jj) foldYOffset = -dyAF if foldY < 0 else 0 specMatrix[0:16] = [xScale * foldX, 0.0, 0.0, 0.0, 0.0, yScale * foldY, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, fxMax + (ii * dxAF) + foldXOffset, fyMax + (jj * dyAF) + foldYOffset, 0.0, 1.0] # flipping in the same GL region - xScale = -xScale # offset = fx0-dxAF # circular - offset = fx0 + dxAF*alias, alias = min->max _shader.setMVMatrix(specMatrix) _shader.setAliasPosition(ii, jj) self._GLPeaks.drawSymbols(specView) self._GLMultiplets.drawSymbols(specView) GL.glLineWidth(GLDefs.GLDEFAULTLINETHICKNESS * self.viewports.devicePixelRatio)
[docs] def drawIntegralLabels(self): """Draw all the integral labels """ pass
[docs] def drawBoundingBoxes(self): if self.strip.isDeleted: return currentShader = self.globalGL._shaderProgram1 # set transform to identity - ensures only the pMatrix is applied currentShader.setMVMatrix(self._IMatrix) # build the bounding boxes index = 0 drawList = self.boundingBoxes # NOTE:ED - shouldn't need to build this every time :| drawList.clearArrays() # if self._preferences.showSpectrumBorder: if self.strip.spectrumBordersVisible: for spectrumView in self._ordering: if spectrumView.isDeleted: continue if spectrumView.isDisplayed and spectrumView.spectrum.dimensionCount > 1 and spectrumView in self._spectrumSettings.keys(): specSettings = self._spectrumSettings[spectrumView] fxMin, _ = specSettings[GLDefs.SPECTRUM_XFOLDLIMITS] fyMin, _ = specSettings[GLDefs.SPECTRUM_YFOLDLIMITS] dxAF, dyAF = specSettings[GLDefs.SPECTRUM_AF] alias = specSettings[GLDefs.SPECTRUM_ALIASINGINDEX] try: _posColour = spectrumView.posColours[0] col = (*_posColour[0:3], 0.5) except Exception as es: col = (0.9, 0.1, 0.2, 0.5) for ii in range(alias[0][0], alias[0][1] + 2, 1): # draw the vertical lines x0 = fxMin + (ii * dxAF) y0 = fyMin + (alias[1][0] * dyAF) y1 = fyMin + ((alias[1][1] + 1) * dyAF) drawList.indices = np.append(drawList.indices, np.array((index, index + 1), dtype=np.uint32)) drawList.vertices = np.append(drawList.vertices, np.array((x0, y0, x0, y1), dtype=np.float32)) drawList.colors = np.append(drawList.colors, np.array(col * 2, dtype=np.float32)) drawList.numVertices += 2 index += 2 for jj in range(alias[1][0], alias[1][1] + 2, 1): # draw the horizontal lines y0 = fyMin + (jj * dyAF) x0 = fxMin + (alias[0][0] * dxAF) x1 = fxMin + ((alias[0][1] + 1) * dxAF) drawList.indices = np.append(drawList.indices, np.array((index, index + 1), dtype=np.uint32)) drawList.vertices = np.append(drawList.vertices, np.array((x0, y0, x1, y0), dtype=np.float32)) drawList.colors = np.append(drawList.colors, np.array(col * 2, dtype=np.float32)) drawList.numVertices += 2 index += 2 # define and draw the boundaries drawList.defineIndexVBO() with self._disableGLAliasing(): GL.glEnable(GL.GL_BLEND) # use the viewports.devicePixelRatio for retina displays GL.glLineWidth(self._contourThickness * self.viewports.devicePixelRatio) drawList.drawIndexVBO() # reset lineWidth GL.glLineWidth(GLDefs.GLDEFAULTLINETHICKNESS * self.viewports.devicePixelRatio)
[docs] def drawSpectra(self): if self.strip.isDeleted: return currentShader = self.globalGL._shaderProgram1 GL.glLineWidth(self._contourThickness * self.viewports.devicePixelRatio) GL.glDisable(GL.GL_BLEND) for spectrumView in self._ordering: if spectrumView.isDeleted or not spectrumView._showContours: continue if spectrumView.spectrum is None or (spectrumView.spectrum and spectrumView.spectrum.isDeleted): continue if spectrumView.isDisplayed and spectrumView in self._spectrumSettings.keys(): # set correct transform when drawing this contour if spectrumView.spectrum.displayFoldedContours: specSettings = self._spectrumSettings[spectrumView] pIndex = specSettings[GLDefs.SPECTRUM_POINTINDEX] if None in pIndex: continue # should move this to buildSpectrumSettings # and emit a signal when visibleAliasingRange or foldingModes are changed _, fxMax = specSettings[GLDefs.SPECTRUM_XLIMITS] _, fyMax = specSettings[GLDefs.SPECTRUM_YLIMITS] dxAF, dyAF = specSettings[GLDefs.SPECTRUM_AF] xScale, yScale = specSettings[GLDefs.SPECTRUM_SCALE] alias = specSettings[GLDefs.SPECTRUM_ALIASINGINDEX] folding = specSettings[GLDefs.SPECTRUM_FOLDINGMODE] specMatrix = np.array(specSettings[GLDefs.SPECTRUM_MATRIX], dtype=np.float32) for ii in range(alias[0][0], alias[0][1] + 1, 1): for jj in range(alias[1][0], alias[1][1] + 1, 1): foldX = foldY = 1.0 foldXOffset = foldYOffset = 0 if folding[0] == 'mirror': foldX = pow(-1, ii) foldXOffset = -dxAF if foldX < 0 else 0 if folding[1] == 'mirror': foldY = pow(-1, jj) foldYOffset = -dyAF if foldY < 0 else 0 specMatrix[0:16] = [xScale * foldX, 0.0, 0.0, 0.0, 0.0, yScale * foldY, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, fxMax + (ii * dxAF) + foldXOffset, fyMax + (jj * dyAF) + foldYOffset, 0.0, 1.0] # flipping in the same GL region - xScale = -xScale # offset = fxMax-dxAF # circular - offset = fxMax + dxAF*alias, alias = min->max currentShader.setMVMatrix(specMatrix) self._contourList[spectrumView].drawIndexVBO() else: # set the scaling/offset for a single spectrum GL contour currentShader.setMVMatrix(self._spectrumSettings[spectrumView][ GLDefs.SPECTRUM_MATRIX]) self._contourList[spectrumView].drawIndexVBO() # reset lineWidth GL.glLineWidth(GLDefs.GLDEFAULTLINETHICKNESS * self.viewports.devicePixelRatio)
def _drawDiagonalLineV2(self, x0, x1, y0, y1): """Generate a simple diagonal mapped to (0..1/0..1) """ yy0 = float(x0 - y0) / (y1 - y0) yy1 = float(x1 - y0) / (y1 - y0) return (0, yy0, 1, yy1) def _addDiagonalLine(self, drawList, x0, x1, y0, y1, col): """Add a diagonal line to the drawList """ index = len(drawList.indices) drawList.indices = np.append(drawList.indices, np.array((index, index + 1), dtype=np.uint32)) drawList.vertices = np.append(drawList.vertices, np.array(self._drawDiagonalLineV2(x0, x1, y0, y1), dtype=np.float32)) drawList.colors = np.append(drawList.colors, np.array(col * 2, dtype=np.float32)) drawList.numVertices += 2 def _buildDiagonalList(self): """Build a list containing the diagonal and the spinningRate lines for the sidebands """ # get spectral width in X and Y # get max number of diagonal lines to draw in each axis # map to the valueToRatio screen # zoom should take care in bounding to the viewport # draw the diagonals for the visible spectra if self.strip.isDeleted: return # build the bounding boxes drawList = self.diagonalGLList drawList.clearArrays() drawListSideBands = self.diagonalSideBandsGLList drawListSideBands.clearArrays() x0 = self.axisL x1 = self.axisR y0 = self.axisB y1 = self.axisT col = (0.5, 0.5, 0.5, 0.5) diagonalCount = 0 for spectrumView in self._ordering: #self._ordering: # strip.spectrumViews: if spectrumView.isDeleted: continue if spectrumView.isDisplayed and spectrumView in self._spectrumSettings.keys(): specSettings = self._spectrumSettings[spectrumView] pIndex = specSettings[GLDefs.SPECTRUM_POINTINDEX] if not diagonalCount: # add lines to drawList if self._matchingIsotopeCodes: mTypes = spectrumView.spectrum.measurementTypes xaxisType = mTypes[pIndex[0]] yaxisType = mTypes[pIndex[1]] # extra multiple-quantum diagonals if xaxisType == 'MQShift' and yaxisType == 'Shift': self._addDiagonalLine(drawList, x0, x1, 2 * y0, 2 * y1, col) elif xaxisType == 'Shift' and yaxisType == 'MQShift': self._addDiagonalLine(drawList, 2 * x0, 2 * x1, y0, y1, col) else: # add the standard diagonal self._addDiagonalLine(drawList, x0, x1, y0, y1, col) diagonalCount += 1 spinningRate = spectrumView.spectrum.spinningRate if spinningRate: sFreqs = spectrumView.spectrum.spectrometerFrequencies spinningRate /= sFreqs[pIndex[0]] # might need to pick the correct axis here nmin = -int(self._preferences.numSideBands) nmax = int(self._preferences.numSideBands) for n in range(nmin, nmax + 1): if n: # add lines to drawList self._addDiagonalLine(drawListSideBands, x0 + n * spinningRate, x1 + n * spinningRate, y0, y1, col) drawList.defineIndexVBO() drawListSideBands.defineIndexVBO()
[docs] def buildDiagonals(self): # determine whether the isotopeCodes of the first two visible axes are matching self._matchingIsotopeCodes = False for specView in self._ordering: # check whether the spectrumView is still active if specView.isDeleted or specView._flaggedForDelete: continue spec = specView.spectrum # inside the paint event, so sometimes specView may not exist if specView in self._spectrumSettings: pIndex = self._spectrumSettings[specView][GLDefs.SPECTRUM_POINTINDEX] if pIndex and None not in pIndex: if spec.isotopeCodes[pIndex[0]] == spec.isotopeCodes[pIndex[1]]: self._matchingIsotopeCodes = True # build the diagonal list here from the visible spectra - each may have a different spinning rate # remove from _build axe - not needed there self._buildDiagonalList() break
def _buildSpectrumSetting(self, spectrumView, stackCount=0): # if spectrumView.spectrum.headerSize == 0: # return self._spectrumSettings[spectrumView] = {} self._spectrumValues = spectrumView.getVisibleState() # set defaults for undefined spectra if not self._spectrumValues[0].pointCount: dx = -1.0 if self.INVERTXAXIS else -1.0 fxMax, fxMin = 1.0, -1.0 fxFoldMax, fxFoldMin = 1.0, -1.0 dxAF = fxMax - fxMin xScale = dx * dxAF dy = -1.0 if self.INVERTYAXIS else -1.0 fyMax, fyMin = 1.0, -1.0 fyFoldMax, fyFoldMin = 1.0, -1.0 dyAF = fyMax - fyMin yScale = dy * dyAF xAliasingIndex = (0, 0) yAliasingIndex = (0, 0) xFoldingMode = yFoldingMode = None self._minXRange = min(self._minXRange, GLDefs.RANGEMINSCALE * dxAF) self._maxXRange = max(self._maxXRange, dxAF) self._minYRange = min(self._minYRange, GLDefs.RANGEMINSCALE * dyAF) self._maxYRange = max(self._maxYRange, dyAF) else: # get the bounding box of the spectra dx = -1.0 if self.INVERTXAXIS else -1.0 # self.sign(self.axisR - self.axisL) fxMax, fxMin = self._spectrumValues[0].maxSpectrumFrequency, self._spectrumValues[0].minSpectrumFrequency xAliasingIndex = self._spectrumValues[0].aliasingIndex xFoldingMode = self._spectrumValues[0].foldingMode fxFoldMax, fxFoldMin = self._spectrumValues[0].maxFoldingFrequency, self._spectrumValues[0].minFoldingFrequency # check tolerances if not self._widthsChangedEnough((fxMax, 0.0), (fxMin, 0.0), tol=1e-10): fxMax, fxMin = 1.0, -1.0 dxAF = fxFoldMax - fxFoldMin # fxMax - fxMin xScale = dx * dxAF / self._spectrumValues[0].pointCount dy = -1.0 if self.INVERTYAXIS else -1.0 # self.sign(self.axisT - self.axisB) fyMax, fyMin = self._spectrumValues[1].maxSpectrumFrequency, self._spectrumValues[1].minSpectrumFrequency yAliasingIndex = self._spectrumValues[1].aliasingIndex yFoldingMode = self._spectrumValues[1].foldingMode fyFoldMax, fyFoldMin = self._spectrumValues[1].maxFoldingFrequency, self._spectrumValues[1].minFoldingFrequency # check tolerances if not self._widthsChangedEnough((fyMax, 0.0), (fyMin, 0.0), tol=1e-10): fyMax, fyMin = 1.0, -1.0 dyAF = fyFoldMax - fyFoldMin # fyMax - fyMin yScale = dy * dyAF / self._spectrumValues[1].pointCount # set to nD limits to twice the width of the spectrum and a few data points self._minXRange = min(self._minXRange, GLDefs.RANGEMINSCALE * dxAF / self._spectrumValues[0].pointCount) self._maxXRange = max(self._maxXRange, dxAF) self._minYRange = min(self._minYRange, GLDefs.RANGEMINSCALE * dyAF / self._spectrumValues[1].pointCount) self._maxYRange = max(self._maxYRange, dyAF) self._rangeXDefined = True self._rangeYDefined = True # create modelview matrix for the spectrum to be drawn self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_MATRIX] = np.zeros((16,), dtype=np.float32) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_MATRIX][0:16] = [xScale, 0.0, 0.0, 0.0, 0.0, yScale, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, fxMax, fyMax, 0.0, 1.0] # setup information for the horizontal/vertical traces self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_XLIMITS] = (fxMin, fxMax) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_YLIMITS] = (fyMin, fyMax) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_AF] = (dxAF, dyAF) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_SCALE] = (xScale, yScale) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_SPINNINGRATE] = spectrumView.spectrum.spinningRate self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_ALIASINGINDEX] = (xAliasingIndex, yAliasingIndex) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_FOLDINGMODE] = (xFoldingMode, yFoldingMode) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_XFOLDLIMITS] = (fxFoldMin, fxFoldMax) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_YFOLDLIMITS] = (fyFoldMin, fyFoldMax) indices = getAxisCodeMatchIndices(self.strip.axisCodes, spectrumView.spectrum.axisCodes) # only need the axes for this spectrum indices = indices[:spectrumView.spectrum.dimensionCount] self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_POINTINDEX] = indices self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_REGIONBOUNDS] = (self._spectrumValues[0].regionBounds, self._spectrumValues[1].regionBounds) if len(self._spectrumValues) > 2: # store a list for the extra dimensions - should only be one per spectrumDisplay really # needed so that the planeDepth is calculated correctly for visible spectra vPP = () for dim in range(2, len(self._spectrumValues)): specVal = self._spectrumValues[dim] vPP = vPP + (specVal.valuePerPoint,) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_VALUEPERPOINT] = vPP else: self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_VALUEPERPOINT] = None self._maxX = max(self._maxX, fxMax) self._minX = min(self._minX, fxMin) self._maxY = max(self._maxY, fyMax) self._minY = min(self._minY, fyMin) self._buildAxisCodesWithWildCards()
[docs] def initialiseTraces(self): # set up the arrays and dimension for showing the horizontal/vertical traces for spectrumView in self._ordering: # strip.spectrumViews: if spectrumView.isDeleted: continue self._spectrumSettings[spectrumView] = {} self._spectrumValues = spectrumView.getVisibleState(dimensionCount=2) # get the bounding box of the spectra dx = self.sign(self.axisR - self.axisL) fxMax, fxMin = self._spectrumValues[0].maxSpectrumFrequency, self._spectrumValues[0].minSpectrumFrequency # check tolerances if not self._widthsChangedEnough((fxMax, 0.0), (fxMin, 0.0), tol=1e-10): fxMax, fxMin = 1.0, -1.0 dxAF = fxMax - fxMin xScale = dx * dxAF / self._spectrumValues[0].pointCount dy = self.sign(self.axisT - self.axisB) fyMax, fyMin = self._spectrumValues[1].maxSpectrumFrequency, self._spectrumValues[1].minSpectrumFrequency # check tolerances if not self._widthsChangedEnough((fyMax, 0.0), (fyMin, 0.0), tol=1e-10): fyMax, fyMin = 1.0, -1.0 dyAF = fyMax - fyMin yScale = dy * dyAF / self._spectrumValues[1].pointCount # create modelview matrix for the spectrum to be drawn self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_MATRIX] = np.zeros((16,), dtype=np.float32) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_MATRIX][0:16] = [xScale, 0.0, 0.0, 0.0, 0.0, yScale, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, fxMax, fyMax, 0.0, 1.0] # setup information for the horizontal/vertical traces self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_XLIMITS] = (fxMin, fxMax) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_YLIMITS] = (fyMin, fyMax) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_AF] = (dxAF, dyAF) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_SCALE] = (xScale, yScale) indices = getAxisCodeMatchIndices(self.strip.axisCodes, spectrumView.spectrum.axisCodes) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_POINTINDEX] = indices
[docs]class Gui1dWidget(CcpnGLWidget): AXIS_MARGINRIGHT = 80 YAXISUSEEFORMAT = True INVERTXAXIS = True INVERTYAXIS = False AXISLOCKEDBUTTON = True AXISLOCKEDBUTTONALLSTRIPS = True is1D = True SPECTRUMPOSCOLOUR = 'sliceColour' SPECTRUMNEGCOLOUR = 'sliceColour' SPECTRUMXZOOM = 1.0e2 SPECTRUMYZOOM = 1.0e6 SHOWSPECTRUMONPHASING = False YAXES = YAXISUNITS1D def __init__(self, strip=None, mainWindow=None, stripIDLabel=None): super(Gui1dWidget, self).__init__(strip=strip, mainWindow=mainWindow, stripIDLabel=stripIDLabel) def _mouseInPeak(self, xPosition, yPosition, firstOnly=False): """Find the peaks under the mouse. If firstOnly is true, return only the first item, else an empty list """ xPositions = [xPosition - self.symbolX, xPosition + self.symbolX] yPositions = [yPosition - self.symbolY, yPosition + self.symbolY] originalxPositions = xPositions originalyPositions = yPositions peaks = [] for spectrumView in self.strip.spectrumViews: for peakListView in spectrumView.peakListViews: xOffset, yOffset = self._spectrumSettings[spectrumView].get(GLDefs.SPECTRUM_STACKEDMATRIXOFFSET) xPositions = np.array(originalxPositions) - xOffset yPositions = np.array(originalyPositions) - yOffset if spectrumView.isDisplayed and peakListView.isDisplayed: peakList = peakListView.peakList for peak in peakList.peaks: if (xPositions[0] < float(peak.position[0]) < xPositions[1] and yPositions[0] < float(peak.height) < yPositions[1]): peaks.append(peak) if firstOnly: return peaks if peak in self.current.peaks else [] return peaks def _mouseInIntegral(self, xPosition, yPosition, firstOnly=False): """Find the integrals under the mouse. If firstOnly is true, return only the first item, else an empty list """ integrals = [] if not self._stackingMode and not (self.is1D and self.strip._isPhasingOn): for reg in self._GLIntegrals._GLSymbols.values(): if not reg.integralListView.isDisplayed or not reg.spectrumView.isDisplayed: continue integralPressed = self.mousePressIn1DArea(reg._regions) if integralPressed: for ilp in integralPressed: obj = ilp[0]._object integrals.append(obj) if firstOnly: return integrals if obj in self.current.integrals else [] return integrals def _mouseInMultiplet(self, xPosition, yPosition, firstOnly=False): """Find the multiplets under the mouse. If firstOnly is true, return only the first item, else an empty list """ xPositions = [xPosition - self.symbolX, xPosition + self.symbolX] yPositions = [yPosition - self.symbolY, yPosition + self.symbolY] multiplets = [] for spectrumView in self.strip.spectrumViews: for multipletListView in spectrumView.multipletListViews: if spectrumView.isDisplayed and multipletListView.isDisplayed: multipletList = multipletListView.multipletList for multiplet in multipletList.multiplets: if not multiplet.position: continue if (xPositions[0] < float(multiplet.position[0]) < xPositions[1] and yPositions[0] < float(multiplet.height) < yPositions[1]): multiplets.append(multiplet) if firstOnly: return multiplets if multiplet in self.current.multiplets else [] return multiplets def _newStatic1DTraceData(self, spectrumView, tracesDict, positionPixel, ph0=None, ph1=None, pivot=None): """Create a new static 1D phase trace """ try: # ignore for 1D if already in the traces list for thisTrace in tracesDict: if spectrumView == thisTrace.spectrumView: return data = spectrumView.spectrum.intensities if ph0 is not None and ph1 is not None and pivot is not None: preData = Phasing.phaseRealData(data, ph0, ph1, pivot) else: preData = data x = spectrumView.spectrum.positions colour = spectrumView._getColour(self.SPECTRUMPOSCOLOUR, '#aaaaaa') colR = int(colour.strip('# ')[0:2], 16) / 255.0 colG = int(colour.strip('# ')[2:4], 16) / 255.0 colB = int(colour.strip('# ')[4:6], 16) / 255.0 tracesDict.append(GLVertexArray(numLists=1, renderMode=GLRENDERMODE_RESCALE, blendMode=False, drawMode=GL.GL_LINE_STRIP, dimension=2, GLContext=self)) numVertices = len(x) hSpectrum = tracesDict[-1] hSpectrum.indices = numVertices hSpectrum.numVertices = numVertices hSpectrum.indices = np.arange(numVertices, dtype=np.uint32) if self._showSpectraOnPhasing: hSpectrum.colors = np.array(self._phasingTraceColour * numVertices, dtype=np.float32) else: hSpectrum.colors = np.array((colR, colG, colB, 1.0) * numVertices, dtype=np.float32) hSpectrum.vertices = np.empty(hSpectrum.numVertices * 2, dtype=np.float32) hSpectrum.vertices[::2] = x hSpectrum.vertices[1::2] = preData # store the pre-phase data hSpectrum.data = data hSpectrum.positionPixel = positionPixel hSpectrum.spectrumView = spectrumView except Exception as es: tracesDict = [] @property def showSpectraOnPhasing(self): return self._showSpectraOnPhasing @showSpectraOnPhasing.setter def showSpectraOnPhasing(self, visible): self._showSpectraOnPhasing = visible self._updatePhasingColour() self.update()
[docs] def toggleShowSpectraOnPhasing(self): self._showSpectraOnPhasing = not self._showSpectraOnPhasing self._updatePhasingColour() self.update()
def _updatePhasingColour(self): for trace in self._staticHTraces: colour = trace.spectrumView._getColour(self.SPECTRUMPOSCOLOUR, '#aaaaaa') colR = int(colour.strip('# ')[0:2], 16) / 255.0 colG = int(colour.strip('# ')[2:4], 16) / 255.0 colB = int(colour.strip('# ')[4:6], 16) / 255.0 numVertices = trace.numVertices if self._showSpectraOnPhasing: trace.colors = np.array(self._phasingTraceColour * numVertices, dtype=np.float32) else: trace.colors = np.array((colR, colG, colB, 1.0) * numVertices, dtype=np.float32) trace.renderMode = GLRENDERMODE_RESCALE
[docs] def buildSpectra(self): """set the GL flags to build spectrum contour lists """ if self.strip.isDeleted: return stackCount = 0 # self._spectrumSettings = {} rebuildFlag = False for stackCount, spectrumView in enumerate(self._ordering): # .strip.spectrumViews: if spectrumView.isDeleted: continue if spectrumView.buildContours or spectrumView.buildContoursOnly: # flag the peaks for rebuilding if not spectrumView.buildContoursOnly: for peakListView in spectrumView.peakListViews: peakListView.buildSymbols = True peakListView.buildLabels = True for integralListView in spectrumView.integralListViews: integralListView.buildSymbols = True integralListView.buildLabels = True for multipletListView in spectrumView.multipletListViews: multipletListView.buildSymbols = True multipletListView.buildLabels = True spectrumView.buildContours = False spectrumView.buildContoursOnly = False # rebuild the contours if spectrumView not in self._contourList.keys(): self._contourList[spectrumView] = GLVertexArray(numLists=1, renderMode=GLRENDERMODE_DRAW, blendMode=False, drawMode=GL.GL_LINE_STRIP, dimension=2, GLContext=self) spectrumView._buildGLContours(self._contourList[spectrumView]) self._buildSpectrumSetting(spectrumView=spectrumView, stackCount=stackCount) # if self._stackingMode: # stackCount += 1 rebuildFlag = True # define the VBOs to pass to the graphics card self._contourList[spectrumView].defineIndexVBO() # rebuild the traces as the spectrum/plane may have changed if rebuildFlag: self.rebuildTraces()
def _updateVisibleSpectrumViews(self): """Update the list of visible spectrumViews when change occurs """ # make the list of ordered spectrumViews self._ordering = self.strip.getSpectrumViews() self._ordering = [specView for specView in self._ordering] for specView in tuple(self._spectrumSettings.keys()): if specView not in self._ordering: # print('>>>_updateVisibleSpectrumViews delete', specView, id(specView)) # print('>>>', [id(spec) for spec in self._ordering]) del self._spectrumSettings[specView] # delete the 1d string relating to the spectrumView self._spectrumLabelling.removeString(specView) # make a list of the visible and not-deleted spectrumViews # visibleSpectra = [specView.spectrum for specView in self._ordering if not specView.isDeleted and specView.isDisplayed] visibleSpectrumViews = [specView for specView in self._ordering if not specView.isDeleted and specView.isDisplayed] self._visibleOrdering = visibleSpectrumViews # set the first visible, or the first in the ordered list self._firstVisible = visibleSpectrumViews[0] if visibleSpectrumViews else self._ordering[0] if self._ordering and not self._ordering[ 0].isDeleted else None # generate the new axis labels based on the visible spectrum axisCodes self._buildAxisCodesWithWildCards() # update the labelling lists self._GLPeaks.setListViews(self._ordering) self._GLIntegrals.setListViews(self._ordering) self._GLMultiplets.setListViews(self._ordering)
[docs] def getPeakPositionFromMouse(self, peak, lastStartCoordinate, cursorPosition=None): """Get the centre position of the clicked 1d peak """ indices = getAxisCodeMatchIndices(self._axisCodes, peak.axisCodes) # check that the mappings are okay for ii, ind in enumerate(indices[:2]): if ind is not None: lastStartCoordinate[ii] = peak.position[ind] else: lastStartCoordinate[ii] = peak.height
def _movePeak(self, peak, deltaPosition): """Move the peak to new position """ peak.height += deltaPosition[1] position = peak.position[0] position += deltaPosition[0] peak.position = [position] def _tracesNeedUpdating(self, spectrumView=None): """Check if traces need updating on _lastTracePoint, use spectrumView to see if cursor has moved sufficiently far to warrant an update of the traces """ # for 1d spectra, traces never need updating, they never move with the cursor return False
[docs] def drawAliasedLabels(self): """Draw all the labels that require aliasing to multiple regions """ _shader = self.globalGL._shaderProgramTexAlias.makeCurrent() # set the scale to the axis limits, needs addressing correctly, possibly same as grid _shader.setProjectionAxes(self._uPMatrix, self.axisL, self.axisR, self.axisB, self.axisT, -1.0, 1.0) _shader.setPTexMatrix(self._uPMatrix) self._axisScale[0:4] = [self.pixelX, self.pixelY, 0.0, 1.0] _shader.setAxisScale(self._axisScale) _shader.setStackOffset(np.array((0.0, 0.0), dtype=np.float32)) _shader.setAliasEnabled(self._aliasEnabled and self._aliasLabelsEnabled) # change to correct value for shader _shader.setAliasShade(self._aliasShade / 100.0) for specView in self._ordering: if specView.isDeleted: continue if specView.isDisplayed and specView in self._spectrumSettings.keys(): specSettings = self._spectrumSettings[specView] # should move this to buildSpectrumSettings # and emit a signal when visibleAliasingRange or foldingModes are changed # fx0 = specSettings[GLDefs.SPECTRUM_MAXXALIAS] # xScale = specSettings[GLDefs.SPECTRUM_XSCALE] _, fxMax = specSettings[GLDefs.SPECTRUM_XLIMITS] dxAF, _ = specSettings[GLDefs.SPECTRUM_AF] xScale, _ = specSettings[GLDefs.SPECTRUM_SCALE] alias = specSettings[GLDefs.SPECTRUM_ALIASINGINDEX] folding = specSettings[GLDefs.SPECTRUM_FOLDINGMODE] for ii in range(alias[0][0], alias[0][1] + 1, 1): foldX = 1.0 foldXOffset = 0 if folding[0] == 'mirror': foldX = pow(-1, ii) foldXOffset = -dxAF if foldX < 0 else 0 if self._stackingMode: _matrix = np.array(specSettings[GLDefs.SPECTRUM_STACKEDMATRIX]) else: _matrix = np.array(self._IMatrix) # take the stacking matrix and insert the correct x-scaling to map the pointPositions to the screen _matrix[0] = xScale * foldX _matrix[12] += (fxMax + (ii * dxAF) + foldXOffset) _shader.setMVMatrix(_matrix) self._axisScale[0:4] = [foldX * self.pixelX / xScale, self.pixelY, 0.0, 1.0] _shader.setAxisScale(self._axisScale) _shader.setAliasPosition(ii, 0) if self._peakLabelsEnabled: self._GLPeaks.drawLabels(specView) if self._multipletLabelsEnabled: self._GLMultiplets.drawLabels(specView)
[docs] def drawAliasedSymbols(self): """Draw all the symbols that require aliasing to multiple regions """ _shader = self.globalGL._shaderProgramAlias.makeCurrent() # set the scale to the axis limits, needs addressing correctly, possibly same as grid _shader.setProjectionAxes(self._uPMatrix, self.axisL, self.axisR, self.axisB, self.axisT, -1.0, 1.0) _shader.setPMatrix(self._uPMatrix) lineThickness = self._symbolThickness GL.glLineWidth(lineThickness * self.viewports.devicePixelRatio) _shader.setAliasEnabled(self._aliasEnabled) # change to correct value for shader _shader.setAliasShade(self._aliasShade / 100.0) for specView in self._ordering: if specView.isDeleted: continue if specView.isDisplayed and specView in self._spectrumSettings.keys(): specSettings = self._spectrumSettings[specView] # should move this to buildSpectrumSettings # and emit a signal when visibleAliasingRange or foldingModes are changed # fx0 = specSettings[GLDefs.SPECTRUM_MAXXALIAS] # xScale = specSettings[GLDefs.SPECTRUM_XSCALE] _, fxMax = specSettings[GLDefs.SPECTRUM_XLIMITS] dxAF, _ = specSettings[GLDefs.SPECTRUM_AF] xScale, _ = specSettings[GLDefs.SPECTRUM_SCALE] alias = specSettings[GLDefs.SPECTRUM_ALIASINGINDEX] folding = specSettings[GLDefs.SPECTRUM_FOLDINGMODE] for ii in range(alias[0][0], alias[0][1] + 1, 1): foldX = 1.0 foldXOffset = 0 if folding[0] == 'mirror': foldX = pow(-1, ii) foldXOffset = -dxAF if foldX < 0 else 0 if self._stackingMode: _matrix = np.array(specSettings[GLDefs.SPECTRUM_STACKEDMATRIX]) else: _matrix = np.array(self._IMatrix) # take the stacking matrix and insert the correct x-scaling to map the pointPositions to the screen _matrix[0] = xScale * foldX _matrix[12] += (fxMax + (ii * dxAF) + foldXOffset) _shader.setMVMatrix(_matrix) _shader.setAliasPosition(ii, 0) # draw the symbols self._GLPeaks.drawSymbols(specView) self._GLMultiplets.drawSymbols(specView) GL.glLineWidth(GLDefs.GLDEFAULTLINETHICKNESS * self.viewports.devicePixelRatio)
[docs] def drawIntegralLabels(self): """Draw all the integral labels """ for specView in self._ordering: if specView.isDeleted: continue if specView.isDisplayed: self._GLIntegrals.drawLabels(specView)
[docs] def drawBoundingBoxes(self): """Draw all the bounding boxes """ pass
[docs] def KEEPdrawSpectra(self): if self.strip.isDeleted: return currentShader = self.globalGL._shaderProgram1 # self.buildSpectra() GL.glLineWidth(self._contourThickness * self.viewports.devicePixelRatio) GL.glDisable(GL.GL_BLEND) # only draw the traces for the spectra that are visible specTraces = [trace.spectrumView for trace in self._staticHTraces] _visibleSpecs = [specView for specView in self._ordering if not specView.isDeleted and specView.isDisplayed and specView._showContours and specView in self._spectrumSettings.keys() and specView in self._contourList.keys() and (specView not in specTraces or self.showSpectraOnPhasing)] # for spectrumView in self._ordering: # # if spectrumView.isDeleted: # continue # if not spectrumView._showContours: # continue # # if spectrumView.isDisplayed and spectrumView in self._spectrumSettings.keys(): # # set correct transform when drawing this contour # # if spectrumView in self._contourList.keys() and \ # (spectrumView not in specTraces or self.showSpectraOnPhasing): for spectrumView in _visibleSpecs: if self._stackingMode: # use the stacking matrix to offset the 1D spectra currentShader.setMVMatrix(self._spectrumSettings[spectrumView][ GLDefs.SPECTRUM_STACKEDMATRIX]) # draw contours self._contourList[spectrumView].drawVertexColorVBO() # reset lineWidth GL.glLineWidth(GLDefs.GLDEFAULTLINETHICKNESS * self.viewports.devicePixelRatio)
[docs] def drawSpectra(self): if self.strip.isDeleted: return currentShader = self.globalGL._shaderProgram1 GL.glLineWidth(self._contourThickness * self.viewports.devicePixelRatio) GL.glDisable(GL.GL_BLEND) for spectrumView in self._ordering: if spectrumView.isDeleted: continue if spectrumView.spectrum is None or (spectrumView.spectrum and spectrumView.spectrum.isDeleted): continue if not spectrumView._showContours: continue # only draw the traces for the spectra that are visible specTraces = [trace.spectrumView for trace in self._staticHTraces] if spectrumView.isDisplayed and spectrumView in self._spectrumSettings.keys(): # set correct transform when drawing this contour if spectrumView.spectrum.displayFoldedContours: specSettings = self._spectrumSettings[spectrumView] # should move this to buildSpectrumSettings # and emit a signal when visibleAliasingRange or foldingModes are changed _, fxMax = specSettings[GLDefs.SPECTRUM_XLIMITS] dxAF, _ = specSettings[GLDefs.SPECTRUM_AF] alias = specSettings[GLDefs.SPECTRUM_ALIASINGINDEX] folding = specSettings[GLDefs.SPECTRUM_FOLDINGMODE] for ii in range(alias[0][0], alias[0][1] + 1, 1): if self._stackingMode: _matrix = np.array(specSettings[GLDefs.SPECTRUM_STACKEDMATRIX]) else: _matrix = np.array(self._IMatrix) # # take the stacking matrix and insert the correct x-scaling to map the pointPositions to the screen # _matrix[0] = xScale # _matrix[12] += fx0 foldX = 1.0 foldXOffset = foldYOffset = 0 if folding[0] == 'mirror': foldX = pow(-1, ii) foldXOffset = (2 * fxMax - dxAF) if foldX < 0 else 0 # foldYOffset = ii * 1e8 #if foldX < 0 else 0 # specMatrix[0:16] = [xScale * foldX, 0.0, 0.0, 0.0, # 0.0, 1.0, 0.0, 0.0, # 0.0, 0.0, 1.0, 0.0, # fx0 + (ii * dxAF) + foldXOffset, 0.0, 0.0, 1.0] # take the stacking matrix and insert the correct x-scaling to map the pointPositions to the screen _matrix[0] = foldX _matrix[12] += (ii * dxAF) + foldXOffset # _matrix[12] += foldXOffset # _matrix[13] += foldYOffset # flipping in the same GL region - xScale = -xScale # offset = fx0-dxAF # circular - offset = fx0 + dxAF*alias, alias = min->max currentShader.setMVMatrix(_matrix) if spectrumView in self._contourList: self._contourList[spectrumView].drawVertexColorVBO() else: if spectrumView in self._contourList.keys() and \ (spectrumView not in specTraces or self.showSpectraOnPhasing): if self._stackingMode: # use the stacking matrix to offset the 1D spectra currentShader.setMVMatrix(self._spectrumSettings[spectrumView][ GLDefs.SPECTRUM_STACKEDMATRIX]) # draw contours if spectrumView in self._contourList: self._contourList[spectrumView].drawVertexColorVBO() # reset lineWidth GL.glLineWidth(GLDefs.GLDEFAULTLINETHICKNESS * self.viewports.devicePixelRatio)
[docs] def buildDiagonals(self): """Build a list containing the diagonal and the spinningRate lines for the sidebands """ pass
def _buildSpectrumSetting(self, spectrumView, stackCount=0): # if spectrumView.spectrum.headerSize == 0: # return self._spectrumSettings[spectrumView] = {} self._spectrumValues = spectrumView.getVisibleState() # set defaults for undefined spectra if not self._spectrumValues[0].pointCount: dx = -1.0 if self.INVERTXAXIS else -1.0 fxMax, fxMin = 1.0, -1.0 fxFoldMax, fxFoldMin = 1.0, -1.0 dxAF = fxMax - fxMin xScale = dx * dxAF dy = -1.0 if self.INVERTYAXIS else -1.0 fyMax, fyMin = 1.0, -1.0 fyFoldMax, fyFoldMin = 1.0, -1.0 dyAF = fyMax - fyMin yScale = dy * dyAF xAliasingIndex = (0, 0) yAliasingIndex = (0, 0) xFoldingMode = yFoldingMode = None self._minXRange = min(self._minXRange, GLDefs.RANGEMINSCALE * dxAF) self._maxXRange = max(self._maxXRange, dxAF) self._minYRange = min(self._minYRange, GLDefs.RANGEMINSCALE * dyAF) self._maxYRange = max(self._maxYRange, dyAF) else: # get the bounding box of the spectra dx = -1.0 if self.INVERTXAXIS else -1.0 # self.sign(self.axisR - self.axisL) fxMax, fxMin = self._spectrumValues[0].maxSpectrumFrequency, self._spectrumValues[0].minSpectrumFrequency xAliasingIndex = self._spectrumValues[0].aliasingIndex xFoldingMode = self._spectrumValues[0].foldingMode fxFoldMax, fxFoldMin = self._spectrumValues[0].maxFoldingFrequency, self._spectrumValues[0].minFoldingFrequency # check tolerances if not self._widthsChangedEnough((fxMax, 0.0), (fxMin, 0.0), tol=1e-10): fxMax, fxMin = 1.0, -1.0 dxAF = fxFoldMax - fxFoldMin # fxMax - fxMin xScale = dx * dxAF / self._spectrumValues[0].pointCount dy = -1.0 if self.INVERTYAXIS else -1.0 # dy = self.sign(self.axisT - self.axisB) if spectrumView.spectrum.intensities is not None and spectrumView.spectrum.intensities.size != 0: fyMax = float(np.max(spectrumView.spectrum.intensities)) fyMin = float(np.min(spectrumView.spectrum.intensities)) else: fyMax, fyMin = 0.0, 0.0 yAliasingIndex = (0, 0) yFoldingMode = None # check tolerances if not self._widthsChangedEnough((fyMax, 0.0), (fyMin, 0.0), tol=1e-10): fyMax, fyMin = 1.0, -1.0 dyAF = fyMax - fyMin yScale = dy * dyAF / 1.0 # set to 1D limits to twice the width of the spectrum and the intensity limit self._minXRange = min(self._minXRange, GLDefs.RANGEMINSCALE * dxAF / max(self._spectrumValues[0].pointCount, self.SPECTRUMXZOOM)) self._maxXRange = max(self._maxXRange, dxAF) # self._minYRange = min(self._minYRange, 3.0 * dyAF / self.SPECTRUMYZOOM) self._minYRange = min(self._minYRange, self._intensityLimit) self._maxYRange = max(self._maxYRange, dyAF) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_STACKEDMATRIX] = np.zeros((16,), dtype=np.float32) # if self._stackingMode: stX = stackCount * self._stackingValue[0] stY = stackCount * self._stackingValue[1] # stackCount += 1 self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_STACKEDMATRIX][0:16] = [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, stX, stY, 0.0, 1.0] self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_STACKEDMATRIXOFFSET] = np.array((stX, stY), dtype=np.float32) self._rangeXDefined = True self._rangeYDefined = True # create modelview matrix for the spectrum to be drawn self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_MATRIX] = np.zeros((16,), dtype=np.float32) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_MATRIX][0:16] = [xScale, 0.0, 0.0, 0.0, 0.0, yScale, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, fxMax, fyMax, 0.0, 1.0] # setup information for the horizontal/vertical traces self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_XLIMITS] = (fxMin, fxMax) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_YLIMITS] = (fyMin, fyMax) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_AF] = (dxAF, dyAF) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_SCALE] = (xScale, yScale) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_SPINNINGRATE] = spectrumView.spectrum.spinningRate self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_ALIASINGINDEX] = (xAliasingIndex, yAliasingIndex) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_FOLDINGMODE] = (xFoldingMode, yFoldingMode) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_XFOLDLIMITS] = (fxFoldMin, fxFoldMax) indices = getAxisCodeMatchIndices(self.strip.axisCodes, spectrumView.spectrum.axisCodes) # only need the axes for this spectrum indices = indices[:spectrumView.spectrum.dimensionCount] self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_POINTINDEX] = indices self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_VALUEPERPOINT] = None self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_REGIONBOUNDS] = (self._spectrumValues[0].regionBounds, 0) self._maxX = max(self._maxX, fxMax) self._minX = min(self._minX, fxMin) self._maxY = max(self._maxY, fyMax) self._minY = min(self._minY, fyMin) self._buildAxisCodesWithWildCards()
[docs] def initialiseTraces(self): # set up the arrays and dimension for showing the horizontal/vertical traces for spectrumView in self._ordering: # strip.spectrumViews: if spectrumView.isDeleted: continue self._spectrumSettings[spectrumView] = {} self._spectrumValues = spectrumView.getVisibleState(dimensionCount=2) # get the bounding box of the spectra dx = self.sign(self.axisR - self.axisL) fxMax, fxMin = self._spectrumValues[0].maxSpectrumFrequency, self._spectrumValues[0].minSpectrumFrequency # check tolerances if not self._widthsChangedEnough((fxMax, 0.0), (fxMin, 0.0), tol=1e-10): fxMax, fxMin = 1.0, -1.0 dxAF = fxMax - fxMin xScale = dx * dxAF / self._spectrumValues[0].pointCount dy = self.sign(self.axisT - self.axisB) if spectrumView.spectrum.intensities is not None and spectrumView.spectrum.intensities.size != 0: fyMax = float(np.max(spectrumView.spectrum.intensities)) fyMin = float(np.min(spectrumView.spectrum.intensities)) else: fyMax, fyMin = 0.0, 0.0 # check tolerances if not self._widthsChangedEnough((fyMax, 0.0), (fyMin, 0.0), tol=1e-10): fyMax, fyMin = 1.0, -1.0 dyAF = fyMax - fyMin yScale = dy * dyAF / 1.0 # create modelview matrix for the spectrum to be drawn self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_MATRIX] = np.zeros((16,), dtype=np.float32) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_MATRIX][0:16] = [xScale, 0.0, 0.0, 0.0, 0.0, yScale, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, fxMax, fyMax, 0.0, 1.0] # setup information for the horizontal/vertical traces self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_XLIMITS] = (fxMin, fxMax) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_YLIMITS] = (fyMin, fyMax) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_AF] = (dxAF, dyAF) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_SCALE] = (xScale, yScale) indices = getAxisCodeMatchIndices(self.strip.axisCodes, spectrumView.spectrum.axisCodes) self._spectrumSettings[spectrumView][GLDefs.SPECTRUM_POINTINDEX] = indices