示例#1
0
    def __init__(self, guiParent):
        '''Init. args: guiParent'''

        self.chain = None
        self.useAssignments = True
        self.useTentative = True
        self.reTypeSpinSystems = False
        self.typeSpinSystems = True
        self.useDimensionalAssignments = True
        self.selectedSpectra = None
        self.amountOfSteps = 0
        self.amountOfRepeats = 0
        self.minTypeScore = 0.01
        self.leavePeaksOutFraction = 0.0
        self.nmrProject = None
        self.project = None
        self.minIsoFrac = None
        self.acceptanceConstantList = []
        self.sourceName = None
        self.ranAnnealling = False
        self.ranPreCalculations = False
        self.results = None
        self.GUI = ViewAssignmentPopup(guiParent, self)
        self.auto = Malandro()

        #self.addEnergyPoint = self.GUI.annealingSettingsTab.addEnergyPoint

        self.auto.registerTextObserver(self.updateInfoText)
        self.auto.registerEnergyObserver(
            self.GUI.annealingSettingsTab.addEnergyPoint)
示例#2
0
class Connector(object):

    '''This is just a little class that contains all
       settings the user configures in the GUI.
       It acts as a connector between the real logic
       of the monte carlo procedure and the GUI.
    '''

    def __init__(self, guiParent):
        '''Init. args: guiParent'''

        self.chain = None
        self.useAssignments = True
        self.useTentative = True
        self.reTypeSpinSystems = False
        self.typeSpinSystems = True
        self.useDimensionalAssignments = True
        self.selectedSpectra = None
        self.amountOfSteps = 0
        self.amountOfRepeats = 0
        self.minTypeScore = 0.01
        self.leavePeaksOutFraction = 0.0
        self.nmrProject = None
        self.project = None
        self.minIsoFrac = None
        self.acceptanceConstantList = []
        self.sourceName = None
        self.ranAnnealling = False
        self.ranPreCalculations = False
        self.results = None
        self.GUI = ViewAssignmentPopup(guiParent, self)
        self.auto = Malandro()

        #self.addEnergyPoint = self.GUI.annealingSettingsTab.addEnergyPoint

        self.auto.registerTextObserver(self.updateInfoText)
        self.auto.registerEnergyObserver(
            self.GUI.annealingSettingsTab.addEnergyPoint)

    def update(self):
        '''Pulls all settings out of the GUI and gives
           them to the assignment algorithm written in Cython.
        '''

        self.chain = self.GUI.annealingSettingsTab.chain
        self.useAssignments = self.GUI.annealingSettingsTab.useAssignmentsCheck.get()
        self.useTentative = self.GUI.annealingSettingsTab.useTentativeCheck.get()
        self.reTypeSpinSystems = not self.GUI.annealingSettingsTab.useTypeCheck.get()
        self.typeSpinSystems = self.GUI.annealingSettingsTab.useAlsoUntypedSpinSystemsCheck.get()
        self.useDimensionalAssignments = self.GUI.annealingSettingsTab.useDimensionalAssignmentsCheck.get()
        self.amountOfRepeats = self.GUI.annealingSettingsTab.amountOfRepeats
        self.amountOfSteps = self.GUI.annealingSettingsTab.amountOfSteps
        self.minTypeScore = self.GUI.annealingSettingsTab.minTypeScore
        self.leavePeaksOutFraction = self.GUI.annealingSettingsTab.leavePeaksOutFraction
        self.nmrProject = self.GUI.nmrProject
        self.project = self.GUI.project
        self.minIsoFrac = self.GUI.annealingSettingsTab.minIsoFrac

        #self.sourceName = self.GUI.sourceName

        self.selectedSpectra = []

        for spec in self.GUI.spectrumSelectionTab.specConfigList:

            if spec.used:

                self.selectedSpectra.append(spec)

        self.GUI.annealingSettingsTab.updateAcceptanceConstantList()
        self.acceptanceConstantList = self.GUI.annealingSettingsTab.acceptanceConstantList
        self.residuesInRange = self.GUI.annealingSettingsTab.residues
        self.auto.updateSettings(self)

    def runAllCalculations(self):
        '''Run all calculations. This includes all
           calculations that have to be carried out
           before the annealing starts and the annealing
           itself.
        '''

        if not self.ranPreCalculations:
            self.update()
            self.GUI.annealingSettingsTab.disableIllegalButtonsAfterPrecalculations()
            self.preCalculateDataModel()
        self.startAnnealing()

    def preCalculateDataModel(self):
        '''Run all calculations that have to be carried
           out before the annealing can run. This is mainly
           setting up a data model, simulating spectra and
           matching those simulated spectra with the real
           spectra.
        '''

        print 'updating'

        self.update()

        if self.checkPoint1():

            print 'precalculate data model'
            self.auto.preCalculateDataModel()
            self.ranPreCalculations = True

    def startAnnealing(self):
        '''Run the annealing.'''

        if self.checkPoint2():

            self.auto.startMonteCarlo(amountOfRuns=self.amountOfRepeats,
                                      stepsPerTemperature=self.amountOfSteps,
                                      acceptanceConstants=self.acceptanceConstantList,
                                      fractionOfPeaksLeftOut=self.leavePeaksOutFraction)

            self.ranAnnealling = True

            self.getResults()

            # createBenchmark(self.results)

            # TODO: this is not very nice
            self.GUI.resultsTab.dataModel = self.results
            self.GUI.resultsTab.update()
            self.GUI.assignTab.update()

    def checkPoint1(self):
        '''First of two checkpoints, is run before the precalculations.
           Here the labelling scheme and the chain information is checked.
           Returns True if it is safe to proceed. Returns False otherwise.
        '''

        if self.checkSpectraAndLabelling() and self.checkChain():

            return True

        else:

            return False

    def checkPoint2(self):
        '''Second of two checkpoints, is run before the annealing starts.
           It is checked whether the precalculations already ran and whether
           the list with acceptance constants is valid.
           Returns True if it is safe to proceed. Returns False otherwise.
        '''

        if self.ranPreCalculations:

            if self.GUI.annealingSettingsTab.updateAcceptanceConstantList():
                return True
        else:

            string = '''Without running the pre-calculations,
                        the annealing can not run.
                     '''

            showWarning('Run pre-calculations first', string, parent=self.GUI)

        return False

    def checkSpectraAndLabelling(self):
        '''Check whether some spectra are selected by the user
           and whether a reference experiment has been set
           for this experiment (needed to simulate the spectra)
           and if the user said the labelling scheme should
           come automatically from the labelled sample,
           the labelled mixture should be set.
        '''

        if not self.selectedSpectra:

            string = 'Select one or more spectra.'

            showWarning('No Spectra Selected', string, parent=self.GUI)

            return False

        for spec in self.selectedSpectra:

            name = spec.ccpnSpectrum.experiment.name

            if not spec.ccpnSpectrum.experiment.refExperiment:

                string = name + (''' has no reference experiment, '''
                                 '''go to Experiment --> Experiments --> '''
                                 '''Experiment Types and select '''
                                 '''a experiment type.''')

                showWarning('No Reference Experiment',
                            string, parent=self.GUI)

                return False

            mixtures = spec.ccpnSpectrum.experiment.labeledMixtures

            if spec.labellingScheme is True and not mixtures:

                string = name + (''' is not connected to any labelled'''
                                 ''' sample.In order to determine the'''
                                 ''' labelling scheme automatically'''
                                 ''' from the experiment, this has to'''
                                 ''' be set. Go to'''
                                 ''' Menu-Modecule-Isotope Labelling'''
                                 ''' to do so.''')

                showWarning('No Labelled Sample', string, parent=self.GUI)

                return False

            elif len(mixtures) > 1:

                string = name + (''' is connected to more than one labelled'''
                                 ''' sample. This is physically impossible.'''
                                 ''' Go to Menu-Modecule-Isotope Labelling'''
                                 ''' if you want to change this.''')

                showWarning('Multiple Labelled Samples for Spectrum',
                            string, parent=self.GUI)

                return False

        return True

    def checkChain(self):
        '''Checks whether a chain is configured
           and whether this chain has residues.
        '''

        if not self.chain:

            string = 'Setup a molecular chain in Molecule --> Molecules'
            showWarning('No chain selected', string, parent=self.GUI)
            return False

        if not self.chain.residues:

            string = '''The selected chain does not have residues,
                        set up the residues in
                        Molecule --> Molecules --> Sequences
                     '''
            showWarning('No Residues', string, parent=self.GUI)
            return False

        return True

    def getResults(self):
        '''Gets the results from the assignment algorithm.
        '''

        if self.ranAnnealling:

            self.results = self.auto.getResults()

    def updateInfoText(self, text):
        '''Update the string with information that is
           displayed to the used in the GUI and the terminal.
        '''

        print text

        self.GUI.updateInfoText(text)

    def saveDataToPyc(self, fileName):
        '''Pickle the data model and save it to file to
           be use later. Since this storage method relies
           on pickle, it is not guaranteed that the data
           can be loaded in future versions of this macro.
        '''

        if self.results:

            if not fileName[-4:] == '.pyc':

                fileName = fileName + '.pyc'

            if os.path.exists(fileName):
                if not showYesNo('File exists',
                                 'File "%s" exists, overwrite?' % fileName,
                                 parent=self.GUI):

                    return

            self.updateInfoText('Saving results...')
            writeFile = open(fileName, 'wb')
            cPickle.dump(self.results, writeFile, protocol=2)
            writeFile.close()
            self.updateInfoText('Results succesfully saved.')

        else:

            string = 'There are no results to save at the moment.'
            showWarning('No results to save', string, parent=self.GUI)

    def loadDataFromPyc(self, fileName):
        '''Load previously pickled data.
               args: fileName: name of the file
        '''

        self.updateInfoText('Loading file...')

        # TODO : fix this, getting these values from the GUI is ridiculous
        self.project = self.GUI.project
        self.nmrProject = self.GUI.nmrProject

        results = None

        fileExists = False

        if os.path.exists(fileName):

            fileExists = True

        elif os.path.exists(fileName + '.pyc'):

            fileName = fileName + '.pyc'

            fileExists = True

        if fileExists:

            try:
                with open(fileName, 'rb') as readFile:

                    results = cPickle.load(readFile)

            except:

                string = ('''Something went wrong when trying to '''
                          '''load the previously produced results. '''
                          '''Probably the file you try to '''
                          '''open is not of the correct type.''')

                print string

                showWarning('Can not open file', string, parent=self.GUI)
                raise

            if results:

                if isinstance(results, DataModel):

                    self.results = results
                    self.updateInfoText('File loaded succesfully.')
                    self.updateInfoText(('''Re-connecting to object in '''
                                         '''the ccpn analysis project...'''))
                    self.results.connectToProject(self.project,
                                                  self.nmrProject)
                    # TODO: this is not very nice
                    self.GUI.resultsTab.dataModel = self.results
                    self.updateInfoText('Done')
                    return

                else:

                    string = (('''You are trying to open a file that '''
                               '''was not created using this macro.'''))

                    showWarning('Can not open file', string, parent=self.GUI)

        else:

            string = 'The file you selected does not exist.'

            showWarning('No Such File', string, parent=self.GUI)

        self.updateInfoText(' ')