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

"""
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-08-12 19:29:19 +0100 (Thu, August 12, 2021) $"
__version__ = "$Revision: 3.0.4 $"
#=========================================================================================
# Created
#=========================================================================================
__author__ = "$Author: CCPN $"
__date__ = "$Date: 2016-09-07 12:42:52 +0100 (Wed, 07 Sep 2016) $"
#=========================================================================================
# Start of code
#=========================================================================================

import os
import datetime

import pandas as pd

from PyQt5 import QtGui, QtWidgets, QtCore, QtPrintSupport

from ccpn.core.lib import Summary
from ccpn.util import Logging
from ccpn.util import Path

from ccpn.ui.gui.widgets.Button import Button
from ccpn.ui.gui.widgets.Frame import Frame
from ccpn.ui.gui.widgets.Label import Label
# from ccpn.ui.gui.widgets.Table import ObjectTable, Column
from ccpn.ui.gui.popups.Dialog import CcpnDialog  # ejb
from ccpn.ui.gui.widgets.GuiTable import GuiTable
from ccpn.ui.gui.widgets.Column import Column, ColumnClass


MINHEIGHT = 100

[docs]class ProjectSummaryPopup(CcpnDialog): def __init__(self, parent=None, mainWindow=None, title='Project Summary', modal=False, **kwds): CcpnDialog.__init__(self, parent, setLayout=True, windowTitle=title, **kwds) self.mainWindow = mainWindow self.application = mainWindow.application self.project = mainWindow.application.project # self.setContentsMargins(15,15,15,15) # QtWidgets.QDialog.__init__(self, parent=parent) if modal: # Set before visible modality = QtCore.Qt.ApplicationModal self.setWindowModality(modality) self.setWindowTitle(title) self.resize(700, self.height()) self._setupData() self.mainFrame = frame = Frame(self, grid=(0, 0), setLayout=True) row = 0 self.pathFrame = Frame(self.mainFrame, grid=(row, 0), setLayout=True) self.pathLabel = Label(self.pathFrame, text='Path', grid=(row, 0), hAlign='l', bold=True) self.pathPathLabel = Label(self.pathFrame, text=self.project.path, grid=(row, 1), hAlign='l', bold=False) self.pathPathButton = Button(self.pathFrame, text='Copy', grid=(row, 2), hAlign='r', callback=self._pathToClipboard) row += 1 # SPECTRA self.spectrumFrame = Frame(self.mainFrame, grid=(row, 0), setLayout=True) self.spectrumLabel = Label(self.spectrumFrame, text='Spectra', grid=(0, 0), hAlign='l', bold=True) row += 1 columnsSpectrum = ColumnClass([ ('#', lambda spectrum: self.spectrumNumberDict[spectrum], 'Number', None, None), ('Pid', lambda spectrum: spectrum.pid, 'Pid of NmrResidue', None, None), ('_object', lambda spectrum: spectrum, 'Object', None, None), ('Id', lambda spectrum: spectrum.id, 'Spectrum id', None, None), ('Dimension count', lambda spectrum: spectrum.dimensionCount, 'Spectrum dimension count', None, None), ('Chemical shiftList', lambda spectrum: spectrum.chemicalShiftList.id, 'Spectrum chemical shiftList', None, None), ('File path', lambda spectrum: spectrum.filePath, 'Spectrum data file path', None, None), ]) self._hiddenColumnsSpectrum = ['Pid'] self.dataFrameSpectrum = None # initialise the table self.spectrumTable = GuiTable(parent=self.spectrumFrame, mainWindow=self.mainWindow, dataFrameObject=None, setLayout=True, autoResize=True, enableDelete=False, grid=(1, 0), gridSpan=(1, 1) ) self.spectrumTable.setMinimumHeight(MINHEIGHT) # self.spectrumTable = ObjectTable(self.spectrumFrame, columns=columns, objects=self.spectra, grid=(1, 0)) row += 1 # PEAKLISTS self.peakListFrame = Frame(self.mainFrame, grid=(row, 0), setLayout=True) self.peakListLabel = Label(self.peakListFrame, text='PeakLists', grid=(0, 0), hAlign='l', bold=True) row += 1 columnsPeakList = ColumnClass([ ('#', lambda peakList: self.peakListNumberDict[peakList], 'Number', None, None), ('Pid', lambda peakList: peakList.pid, 'Pid of NmrResidue', None, None), ('_object', lambda peakList: peakList, 'Object', None, None), ('Id', lambda peakList: peakList.id, 'PeakList id', None, None), ('Peak count', lambda peakList: len(peakList.peaks), 'Number of peaks in peakList', None, None), ('Partly assigned count', Summary.partlyAssignedPeakCount, 'Number of peaks in peakList at least partially assigned', None, None), ('Partly assigned %', Summary.partlyAssignedPeakPercentage, 'Percentage of peaks in peakList at least partially assigned', None, None), ('Fully assigned count', Summary.fullyAssignedPeakCount, 'Number of peaks in peakList fully assigned', None, None), ('Fully assigned %', Summary.fullyAssignedPeakPercentage, 'Percentage of peaks in peakList fully assigned', None, None), ]) self._hiddenColumnsPeakList = ['Pid'] self.dataFramePeakList = None # initialise the table self.peakListTable = GuiTable(parent=self.peakListFrame, mainWindow=self.mainWindow, dataFrameObject=None, setLayout=True, autoResize=True, enableDelete=False, grid=(1, 0), gridSpan=(1, 1) ) self.peakListTable.setMinimumHeight(MINHEIGHT) # self.peakListTable = ObjectTable(self.peakListFrame, columns=columns, objects=self.peakLists, grid=(1, 0)) row += 1 # CHAINS self.chainFrame = Frame(self.mainFrame, grid=(row, 0), setLayout=True) self.chainLabel = Label(self.chainFrame, text='Chains', grid=(0, 0), hAlign='l', bold=True) row += 1 columnsChain = ColumnClass([ ('#', lambda chain: self.chainNumberDict[chain], 'Number', None, None), ('Pid', lambda chain: chain.pid, 'Pid of NmrResidue', None, None), ('_object', lambda chain: chain, 'Object', None, None), ('Id', lambda chain: chain.id, 'Chain id', None, None), ('Residue count', lambda chain: len(chain.residues), 'Number of residues in chain', None, None), ('Assignable atom count', Summary.assignableAtomCount, 'Number of atoms in chain which are assignable to', None, None), ('Assigned atom count', Summary.assignedAtomCount, 'Number of atoms in chain which are assigned to', None, None), ('Assigned atom %', Summary.assignedAtomPercentage, 'Percentage of atoms in chain which are assigned to', None, None), ]) self._hiddenColumnsChains = ['Pid'] self.dataFrameChains = None # initialise the table self.chainTable = GuiTable(parent=self.chainFrame, mainWindow=self.mainWindow, dataFrameObject=None, setLayout=True, autoResize=True, enableDelete=False, grid=(1, 0), gridSpan=(1, 1) ) self.chainTable.setMinimumHeight(MINHEIGHT) # self.chainTable = ObjectTable(self.chainFrame, columns=columns, objects=self.chains, grid=(1, 0)) row += 1 self.mainFrame.addSpacer(10, 10, grid=(row,0)) row += 1 # Buttons buttonFrame = Frame(self, grid=(1, 0), setLayout=True) button = Button(buttonFrame, 'Save to Excel', callback=self._saveToExcel, grid=(0, 0)) # button = Button(buttonFrame, 'Save to PDF', callback=self._saveToPdf, grid=(0, 1)) button = Button(buttonFrame, 'Close', callback=self.accept, grid=(0, 2)) row += 1 self.dataFrameSpectrum = self.spectrumTable.getDataFrameFromList(table=self.spectrumTable, buildList=self.spectra, colDefs=columnsSpectrum) self.spectrumTable.setTableFromDataFrameObject(dataFrameObject=self.dataFrameSpectrum) self.dataFramePeakList = self.peakListTable.getDataFrameFromList(table=self.peakListTable, buildList=self.peakLists, colDefs=columnsPeakList) self.peakListTable.setTableFromDataFrameObject(dataFrameObject=self.dataFramePeakList) self.dataFrameChains = self.chainTable.getDataFrameFromList(table=self.chainTable, buildList=self.chains, colDefs=columnsChain) self.chainTable.setTableFromDataFrameObject(dataFrameObject=self.dataFrameChains) def _setupData(self): # SPECTRA self.spectra = self.project.spectra self.spectrumNumberDict = {} for n, spectrum in enumerate(self.spectra): self.spectrumNumberDict[spectrum] = n + 1 # PEAKLISTS self.peakLists = [] self.peakListNumberDict = {} n = 1 for spectrum in self.spectra: self.peakLists.extend(spectrum.peakLists) for peakList in spectrum.peakLists: self.peakListNumberDict[peakList] = n n += 1 # CHAINS self.chains = self.project.chains self.chainNumberDict = {} for n, chain in enumerate(self.chains): self.chainNumberDict[chain] = n + 1 def _pathToClipboard(self, *args): from ccpn.util.Common import copyToClipboard copyToClipboard([self.pathPathLabel.get()]) def _getPathPrefix(self): directory = os.path.join(self.project.path, Path.CCPN_SUMMARIES_DIRECTORY) if not os.path.exists(directory): os.mkdir(directory) now = datetime.datetime.now() filePrefix = 'summary_%s_%02d%02d%02d_%02d%02d%02d' % \ (self.project.name, now.year, now.month, now.day, now.hour, now.minute, now.second) return os.path.join(directory, filePrefix) def _showMessage(self, path): message = 'Project summary written to file %s' % path logger = Logging.getLogger() logger.info(message) self.getParent().statusBar().showMessage(message) def _saveToPdf(self): path = self._getPathPrefix() + '.pdf' printer = QtPrintSupport.QPrinter(QtPrintSupport.QPrinter.ScreenResolution) printer.setPaperSize(QtPrintSupport.QPrinter.A4) printer.setOrientation(QtPrintSupport.QPrinter.Landscape) printer.setOutputFormat(QtPrintSupport.QPrinter.PdfFormat) printer.setOutputFileName(path) painter = QtGui.QPainter(printer) self.spectrumFrame.render(painter) printer.newPage() self.peakListFrame.render(painter) printer.newPage() self.chainFrame.render(painter) painter.end() self._showMessage(path) def _saveToExcel(self): path = self._getPathPrefix() + '.xlsx' writer = pd.ExcelWriter(path, engine='xlsxwriter') for (table, name) in ((self.spectrumTable, 'spectrum'), (self.peakListTable, 'peakList'), (self.chainTable, 'chain')): dataFrame = table.tableToDataFrame() if not dataFrame.empty: dataFrame.to_excel(writer, sheet_name=name, index=False) # table.findExportFormats(path, sheet_name=name) writer.save() self._showMessage(path)