Source code for ccpn.AnalysisStructure.gui.ProcessXplorStructureCalculationPopup

"""
Alpha version of a popup for processing a structure calculation using Xplor-NIH calculations.
"""
#=========================================================================================
# Licence, Reference and Credits
#=========================================================================================
__copyright__ = "Copyright (C) CCPN project (https://www.ccpn.ac.uk) 2014 - 2022"
__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 https://ccpn.ac.uk/software/licensing/")
__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: 2022-03-09 21:13:06 +0000 (Wed, March 09, 2022) $"
__version__ = "$Revision: 3.1.0 $"
#=========================================================================================
# Created
#=========================================================================================
__author__ = "$Author: CCPN $"
__date__ = "$Date: 2021-04-27 16:04:57 +0100 (Tue, April 27, 2021) $"
#=========================================================================================
# Start of code
#=========================================================================================

import os
from PyQt5 import QtCore, QtGui, QtWidgets

from ccpn.ui.gui.widgets.PulldownListsForObjects import PeakListPulldown, ChemicalShiftListPulldown, ChainPulldown
from ccpn.ui.gui.popups.Dialog import CcpnDialogMainWidget
from ccpn.ui.gui.widgets.ListWidget import ListWidgetPair
from ccpn.ui.gui.widgets.Button import Button
from ccpn.ui.gui.lib.GuiPath import PathEdit
from ccpn.ui.gui.widgets.Label import Label
from ccpn.ui.gui.widgets import MessageDialog
from ccpn.ui.gui.widgets import CheckBox
from ccpn.ui.gui.widgets import Entry
from ccpn.ui.gui.widgets.HLine import LabeledHLine
from ccpn.ui.gui.widgets.FileDialog import OtherFileDialog, ProjectFileDialog
from ccpn.ui.gui.widgets.MessageDialog import showWarning, progressManager
from ccpn.ui.gui.widgets.Frame import Frame

from ccpn.framework.Application import getApplication
from ccpn.framework.Version import applicationVersion
from ccpn.framework.Preferences import getPreferences, XPLOR_NIH_PATH, TALOS_PATH

from ccpn.core.lib.ContextManagers import undoBlockWithoutSideBar, notificationEchoBlocking

from ccpn.AnalysisStructure.lib.runManagers.XplorNihRunManager import XplorNihRunManager

from ccpn.util.Path import aPath


if '3.1' in applicationVersion:
    ccpnVersion310 = True
else:
    ccpnVersion310 = False


[docs]class ProcessXplorCalculationFolderPopup(CcpnDialogMainWidget): """ Process the Xplor-NIH Structure calculation run by - performing a cleanup - creating an structure ensemble - (optionally) generating the violations nef file """ FIXEDWIDTH = True FIXEDHEIGHT = False _GREY = '#888888' title = 'Process Xplor-NIH Structure Calculation (Alpha)' def __init__(self, parent=None, mainWindow=None, title=title, **kwds): super().__init__(parent, setLayout=True, windowTitle=title, size=(500, 10), minimumSize=None, **kwds) if mainWindow: self.mainWindow = mainWindow self.application = mainWindow.application self.current = self.application.current self.project = mainWindow.project else: self.mainWindow = None self.application = None self.current = None self.project = None self._createWidgets() # enable the buttons # self.tipText = '' # self.setOkButton(callback=self._okCallback, tipText =self.tipText, text='Clean up', enabled=True) self.setCloseButton(callback=self.reject, tipText='Close') self.setDefaultButton(CcpnDialogMainWidget.CLOSEBUTTON) self.__postInit__() # self._okButton = self.dialogButtons.button(self.OKBUTTON) def _createWidgets(self): """Make the widgets """ _height = 30 row = -1 row += 1 self.pathLabel = Label(self.mainWidget, text="Xplor-NIH Run Directory", grid=(row, 0), hAlign='right') self.pathData = PathEdit(self.mainWidget, grid=(row, 1), vAlign='t', editable=False) self.pathData.setMinimumWidth(400) _b = Button(self.mainWidget, grid=(row, 2), callback=self._getPathFromDialog, icon='icons/directory', hPolicy='fixed') _b.setFixedHeight(_height) row += 1 Label(self.mainWidget, text="Run name", grid=(row, 0), hAlign='right' ) self.runName = Entry.Entry(self.mainWidget, grid=(row, 1), editable=False) row += 1 Label(self.mainWidget, text="Run number", grid=(row, 0), hAlign='right') self.runId = Entry.IntEntry(self.mainWidget, grid=(row, 1), editable=False) row += 1 Label(self.mainWidget, text="State", grid=(row, 0), hAlign='right') doneFrame = Frame(self.mainWidget, grid=(row, 1), gridSpan=(1,2), setLayout=True) self.setupDone = CheckBox.CheckBox(doneFrame, grid=(0, 0), text='setup done', checked=False) self.setupDone.setEnabled(False) self.calculationDone = CheckBox.CheckBox(doneFrame, grid=(0, 1), text='calculated', checked=False) self.calculationDone.setEnabled(False) self.processDone = CheckBox.CheckBox(doneFrame, grid=(0, 2), text='processed', checked=False) self.processDone.setEnabled(False) self.importDone = CheckBox.CheckBox(doneFrame, grid=(0, 3), text='imported', checked=False) self.importDone.setEnabled(False) # settings row += 1 LabeledHLine(self.mainWidget, text='Settings', grid=(row,0), gridSpan=(1,2), style='DashLine', colour=self._GREY) _preferences = getPreferences() row += 1 Label(self.mainWidget, text="xplor_nih path", grid=(row, 0), hAlign='right') self.xplorPath = Entry.Entry(self.mainWidget, grid=(row, 1), editable=False) # self.xplorPath.set(_preferences.get(XPLOR_NIH_PATH)) row += 1 Label(self.mainWidget, text="talosN path", grid=(row, 0), hAlign='right') self.talosnPath = Entry.Entry(self.mainWidget, grid=(row, 1), editable=False) # self.talosnPath.set(_preferences.get(TALOS_PATH)) row += 1 self.checkLabel = Label(self.mainWidget, text="Use multicore CPU", grid=(row, 0), hAlign='right') self.useParallel = CheckBox.CheckBox(self.mainWidget, grid=(row, 1)) self.useParallel.setEnabled(False) row += 1 self.entryLabel = Label(self.mainWidget, text="Number of CPU Cores", grid=(row, 0), hAlign='right') self.numberOfCores = Entry.IntEntry(self.mainWidget, grid=(row, 1), editable=False) # Actions row += 1 LabeledHLine(self.mainWidget, text='Actions', grid=(row,0), gridSpan=(1,2), style='DashLine', colour=self._GREY) # row += 1 # _b = Button(self.mainWidget, grid=(row, 1), text='Load Run Data', callback=self._loadRunData, # hPolicy='expanding') # _b.setFixedHeight(_height) # row += 1 # Label(self.mainWidget, text="setup done", grid=(row, 0), hAlign='right') # self.setupDone = CheckBox.CheckBox(self.mainWidget, grid=(row, 1), checked=False) # self.setupDone.setEnabled(False) # # row += 1 # Label(self.mainWidget, text="calculation done", grid=(row, 0), hAlign='right') # self.calculationDone = CheckBox.CheckBox(self.mainWidget, grid=(row, 1), checked=False) # self.calculationDone.setEnabled(False) row += 1 Label(self.mainWidget, text="Processed", grid=(row, 0), hAlign='right') processDoneFrame = Frame(self.mainWidget, grid=(row, 1), gridSpan=(1,2), setLayout=True) self.cleanupDone = CheckBox.CheckBox(processDoneFrame, grid=(0, 0), text='cleanup', checked=False) self.cleanupDone.setEnabled(False) self.violationDone = CheckBox.CheckBox(processDoneFrame, grid=(0, 1), text='violations', checked=False) self.violationDone.setEnabled(False) self.ensembleDone = CheckBox.CheckBox(processDoneFrame, grid=(0, 2), text='ensemble', checked=False) self.ensembleDone.setEnabled(False) # row += 1 # Label(self.mainWidget, text="cleanup done", grid=(row, 0), hAlign='right') # self.cleanupDone = CheckBox.CheckBox(self.mainWidget, grid=(row, 1), checked=False) # self.cleanupDone.setEnabled(False) # # row += 1 # Label(self.mainWidget, text="violations done", grid=(row, 0), hAlign='right') # self.violationDone = CheckBox.CheckBox(self.mainWidget, grid=(row, 1), checked=False) # self.violationDone.setEnabled(False) # # row += 1 # Label(self.mainWidget, text="ensemble done", grid=(row, 0), hAlign='right') # self.ensembleDone = CheckBox.CheckBox(self.mainWidget, grid=(row, 1), checked=False) # self.ensembleDone.setEnabled(False) row += 1 Label(self.mainWidget, text="Generate violations.nef", grid=(row, 0), hAlign='right') self.generateViolations = CheckBox.CheckBox(self.mainWidget,grid=(row,1), checked=True) row += 1 self.processButton = Button(self.mainWidget, grid=(row, 1), text='Process', callback=self._processXplorCalculation, hPolicy='expanding') self.processButton.setFixedHeight(_height) # Try to set a sensible initial path by finding the most recent xplor run _path = self.project.application.dataPath / XplorNihRunManager._RUN_TYPE _runs = [str(p) for p in _path.glob('*') \ if p.is_dir() and (p / XplorNihRunManager._JSON_FILE).exists()] _runs.sort() if len(_runs) > 0: self.pathData.setText(str(_runs[-1])) self._loadRunData() def _getPathFromDialog(self): """Select a new path from using a dialog """ _path = self.project.application.dataPath / XplorNihRunManager._RUN_TYPE dialog = ProjectFileDialog(parent=self.mainWindow, directory=str(_path)) dialog._show() if (path := dialog.selectedFile()) is not None: self.pathData.setText(str(path)) self._loadRunData() def _loadRunData(self): """Load the data from json file in pathData """ _path = self.pathData.get() if _path is None or len(_path) == 0: showWarning(self.title, f'Path is undefined') return _path = aPath(_path) if not _path.exists(): showWarning(self.title, f'Path {_path} not found') return _jsonPath = _path / XplorNihRunManager._JSON_FILE if not _jsonPath.exists(): showWarning(self.title, f'Json file {_jsonPath} not found') return myRun = XplorNihRunManager(project=self.project) myRun.restoreState(runPath=_path) self.runName.set(myRun.runName) self.runId.set(myRun.runId) self.xplorPath.set(str(myRun._xplorPath)) self.talosnPath.set(str(myRun._talosnPath)) self.useParallel.set(myRun.useParallel) self.numberOfCores.set(myRun.numberOfCores) self.setupDone.set(myRun.setupDone) self.calculationDone.set(myRun.calculationDone) self.cleanupDone.set(myRun.cleanupDone) self.violationDone.set(myRun.violationDone) self.ensembleDone.set(myRun.ensembleDone) self.processDone.set(myRun.cleanupDone and myRun.ensembleDone) if (not myRun.setupDone) or \ (not myRun.calculationDone) or \ (myRun.cleanupDone and myRun.ensembleDone): self.processButton.setEnabled(False) else: self.processButton.setEnabled(True) def _processXplorCalculation(self): """Clicked 'Process': process the calculation files """ if not self.project: raise RuntimeError('Project is not defined') pathRun = self.pathData.get() if not pathRun: MessageDialog.showWarning(self.title, 'First define the path to Xplor-nih run data directory') return # process the calculation myRun = XplorNihRunManager(project=self.project) myRun.restoreState(runPath=self.pathData.get()) # Process the directory with progressManager(self, f'Processing {myRun.runPath}'): myRun.processCalculation() if self.generateViolations.isChecked(): myRun._runViolationAnalysis() myRun.saveState() self._loadRunData() MessageDialog.showInfo(self.title, f'Processed directory {myRun.runPath}' )
if __name__ == '__main__': from ccpn.ui.gui.widgets.Application import TestApplication app = TestApplication() popup = ProcessXplorCalculationFolderPopup() popup.show() popup.raise_() # app.start()