def visualize(self, obj, **args): """Open the Protocol GUI Form given a Protocol instance""" from gui.form import FormWindow self.setProtocol(obj) self.windows = args.get('windows', None) self.formWindow = FormWindow("Protocol Viewer: " + self.getClassName(), self, self._viewAll, self.windows, visualizeDict=self.__getVisualizeWrapperDict(), visualizeMode=True) self.formWindow.visualizeMode = True self.showInfo = self.formWindow.showInfo self.showError = self.formWindow.showError self._tkRoot = self.formWindow.root self.formWindow.show(center=True)
class ProtocolViewer(Protocol, Viewer): """ Special kind of viewer that have a Form to organize better complex visualization associated with protocol results. If should provide a mapping between form params and the corresponding functions that will return the corresponding Views. """ def __init__(self, **kwargs): # Here we are going to intercept the original _defineParams function # and replace by an empty one, this is to postpone the definition of # params until the protocol is set and then self.protocol can be used # for a more dynamic definition object.__setattr__(self, '_defineParamsBackup', self._defineParams) object.__setattr__(self, '_defineParams', self._defineParamsEmpty) Protocol.__init__(self, **kwargs) Viewer.__init__(self, **kwargs) self.allowHeader.set(False) # This flag will be used to display a plot or return the plotter self.showPlot = True self._tkRoot = None self.formWindow = None self.setWorkingDir(self.getProject().getTmpPath()) def getWindow(self): return self.formWindow def getTkRoot(self): return self._tkRoot def _defineParamsEmpty(self, form): """ Just do nothing and postpone the real definition. """ pass def setProtocol(self, protocol): """ Set the protocol instance to the viewer and call the definition of the parameters. """ self.protocol = protocol self._defineParamsBackup(self._definition) self._createVarsFromDefinition() def visualize(self, obj, **args): """Open the Protocol GUI Form given a Protocol instance""" from gui.form import FormWindow self.setProtocol(obj) self.windows = args.get('windows', None) self.formWindow = FormWindow( "Protocol Viewer: " + self.getClassName(), self, self._viewAll, self.windows, visualizeDict=self.__getVisualizeWrapperDict(), visualizeMode=True) self.formWindow.visualizeMode = True self.showInfo = self.formWindow.showInfo self.showError = self.formWindow.showError self._tkRoot = self.formWindow.root self.formWindow.show(center=True) def _visualizeParam(self, paramName=None): """ Call handler to get viewers and visualize each one. """ errors = self.validate() if errors: errorMsg = '\n'.join(errors) self.showError(errorMsg, "Validation errors") else: views = self._getVisualizeDict()[paramName](paramName) if views: for v in views: v.show() def __getVisualizeWrapperDict(self): """ Replace the True attributes handler by the generic one. """ d = {} for k in self._getVisualizeDict(): d[k] = self._visualizeParam return d def _getVisualizeDict(self): """ Create the visualization dict for view individual params. """ return {} def _viewAll(self, *args): """ Visualize all data give the parameters. """ for k, v in self._getVisualizeDict().iteritems(): print "k: %s, v: %s" % (k, v) if self.getAttributeValue(k, False): print " calling v..." v(k) def _citations(self): return self.protocol._citations() #TODO: This method should not be necessary, instead NumericListParam should # return a list and not a String def _getListFromRangeString(self, rangeStr): ''' Create a list of integer from a string with range definitions Examples: "1,5-8,10" -> [1,5,6,7,8,10] "2,6,9-11" -> [2,6,9,10,11] "2 5, 6-8" -> [2,5,6,7,8] ''' elements = rangeStr.split(',') values = [] for e in elements: if '-' in e: limits = e.split('-') values += range(int(limits[0]), int(limits[1]) + 1) else: # If values are separated by comma also splitted values += map(int, e.split()) return values def createVolumesSqlite(self, files, path, samplingRate, updateItemCallback=None): from em import SetOfVolumes, Volume cleanPath(path) volSet = SetOfVolumes(filename=path) volSet.setSamplingRate(samplingRate) for volFn in files: vol = Volume() vol.setFileName(volFn) if updateItemCallback: updateItemCallback(vol) volSet.append(vol) volSet.write() volSet.close() return volSet def createAngDistributionSqlite(self, sqliteFn, numberOfParticles, itemDataIterator): import pyworkflow.em.metadata as md if not os.path.exists(sqliteFn): # List of list of 3 elements containing angleTilt, anglePsi, weight projectionList = [] def getCloseProjection(angleRot, angleTilt): """ Get an existing projection close to angleRot, angleTilt. Return None if not found close enough. """ for projection in projectionList: if (abs(projection[0] - angleRot) <= 0.5 and abs(projection[1] - angleTilt) <= 0.5): return projection return None weight = 1. / numberOfParticles for angleRot, angleTilt in itemDataIterator: projection = getCloseProjection(angleRot, angleTilt) if projection is None: projectionList.append([angleRot, angleTilt, weight]) else: projection[2] = projection[2] + weight mdProj = md.MetaData() for projection in projectionList: mdRow = md.Row() mdRow.setValue(md.MDL_ANGLE_ROT, projection[0]) mdRow.setValue(md.MDL_ANGLE_TILT, projection[1]) mdRow.setValue(md.MDL_WEIGHT, projection[2]) mdRow.writeToMd(mdProj, mdProj.addObject()) mdProj.write(sqliteFn)
class ProtocolViewer(Protocol, Viewer): """ Special kind of viewer that have a Form to organize better complex visualization associated with protocol results. If should provide a mapping between form params and the corresponding functions that will return the corresponding Views. """ def __init__(self, **kwargs): # Here we are going to intercept the original _defineParams function # and replace by an empty one, this is to postpone the definition of # params until the protocol is set and then self.protocol can be used # for a more dynamic definition object.__setattr__(self, '_defineParamsBackup', self._defineParams) object.__setattr__(self, '_defineParams', self._defineParamsEmpty) Protocol.__init__(self, **kwargs) Viewer.__init__(self, **kwargs) self.allowHeader.set(False) # This flag will be used to display a plot or return the plotter self.showPlot = True self._tkRoot = None self.formWindow = None self.setWorkingDir(self.getProject().getTmpPath()) def getWindow(self): return self.formWindow def getTkRoot(self): return self._tkRoot def _defineParamsEmpty(self, form): """ Just do nothing and postpone the real definition. """ pass def setProtocol(self, protocol): """ Set the protocol instance to the viewer and call the definition of the parameters. """ self.protocol = protocol self._defineParamsBackup(self._definition) self._createVarsFromDefinition() def visualize(self, obj, **args): """Open the Protocol GUI Form given a Protocol instance""" from gui.form import FormWindow self.setProtocol(obj) self.windows = args.get('windows', None) self.formWindow = FormWindow("Protocol Viewer: " + self.getClassName(), self, self._viewAll, self.windows, visualizeDict=self.__getVisualizeWrapperDict(), visualizeMode=True) self.formWindow.visualizeMode = True self.showInfo = self.formWindow.showInfo self.showError = self.formWindow.showError self._tkRoot = self.formWindow.root self.formWindow.show(center=True) def _visualizeParam(self, paramName=None): """ Call handler to get viewers and visualize each one. """ errors = self.validate() if errors: errorMsg = '\n'.join(errors) self.showError(errorMsg, "Validation errors") else: views = self._getVisualizeDict()[paramName](paramName) if views: for v in views: v.show() def __getVisualizeWrapperDict(self): """ Replace the True attributes handler by the generic one. """ d = {} for k in self._getVisualizeDict(): d[k] = self._visualizeParam return d def _getVisualizeDict(self): """ Create the visualization dict for view individual params. """ return {} def _viewAll(self, *args): """ Visualize all data give the parameters. """ for k, v in self._getVisualizeDict().iteritems(): print "k: %s, v: %s" % (k, v) if self.getAttributeValue(k, False): print " calling v..." v(k) def _citations(self): return self.protocol._citations() #TODO: This method should not be necessary, instead NumericListParam should # return a list and not a String def _getListFromRangeString(self, rangeStr): ''' Create a list of integer from a string with range definitions Examples: "1,5-8,10" -> [1,5,6,7,8,10] "2,6,9-11" -> [2,6,9,10,11] "2 5, 6-8" -> [2,5,6,7,8] ''' elements = rangeStr.split(',') values = [] for e in elements: if '-' in e: limits = e.split('-') values += range(int(limits[0]), int(limits[1])+1) else: # If values are separated by comma also splitted values += map(int, e.split()) return values def createVolumesSqlite(self, files, path, samplingRate, updateItemCallback=None): from em import SetOfVolumes, Volume cleanPath(path) volSet = SetOfVolumes(filename=path) volSet.setSamplingRate(samplingRate) for volFn in files: vol = Volume() vol.setFileName(volFn) if updateItemCallback: updateItemCallback(vol) volSet.append(vol) volSet.write() volSet.close() return volSet def createAngDistributionSqlite(self, sqliteFn, numberOfParticles, itemDataIterator): import pyworkflow.em.metadata as md if not os.path.exists(sqliteFn): # List of list of 3 elements containing angleTilt, anglePsi, weight projectionList = [] def getCloseProjection(angleRot, angleTilt): """ Get an existing projection close to angleRot, angleTilt. Return None if not found close enough. """ for projection in projectionList: if (abs(projection[0] - angleRot) <= 0.5 and abs(projection[1] - angleTilt) <= 0.5): return projection return None weight = 1./numberOfParticles for angleRot, angleTilt in itemDataIterator: projection = getCloseProjection(angleRot, angleTilt) if projection is None: projectionList.append([angleRot, angleTilt, weight]) else: projection[2] = projection[2] + weight mdProj = md.MetaData() for projection in projectionList: mdRow = md.Row() mdRow.setValue(md.MDL_ANGLE_ROT, projection[0]) mdRow.setValue(md.MDL_ANGLE_TILT, projection[1]) mdRow.setValue(md.MDL_WEIGHT, projection[2]) mdRow.writeToMd(mdProj, mdProj.addObject()) mdProj.write(sqliteFn)