def writeMember(self, obj, memberName): if isString(obj): logging.warning(u"String as object provided! " + self._warningPrefix(obj, memberName)) if isInteger(memberName) and isList(obj): member = obj[memberName] memberName = str(memberName) else: member = getattr(obj, memberName, None) if member is None: self.log(u"skipped " + self._warningPrefix(obj, memberName) + u"It is empty or does not exist (=None).") return if isCallable(member) and not hasattr(member, "hdfWrite"): member = member() if hasattr(member, "hdfWrite"): # support instances and types # store the member in a group of its own oldLocation = self.location self._location = "/".join((oldLocation.rstrip('/'), memberName)) member.hdfWrite(self) # recursion entry, mind the loops! self._location = oldLocation elif isList(member): self.writeDataset(memberName, member) elif isString(member) or isNumber(member): self.writeAttribute(memberName, member) else: self.log(u"skipped " + self._warningPrefix(obj, memberName) + "(={}) It is not a compatible value type!".format( classname(member)))
def __init__(self, dataset, createDir=True): self._outDir = LastPath.get() if not os.path.isdir(self._outDir): logging.warning("Output path '{}' does not exist!".format( self._outDir)) self._outDir = "" self._timestamp = log.timestamp() self._basename = u"{title} {ts}".format(title=dataset.title, ts=log.timestampFormatted( self.timestamp)) anglesStr = getattr(dataset, "anglesToStr", "") if isString(anglesStr) and len(anglesStr): self._basename += u" [{}]".format(anglesStr) indicesStr = getattr(dataset, "measIndicesStr", "") if isString(indicesStr) and len(indicesStr): self._basename += u" ({})".format(indicesStr) if not createDir: return # create a directory for all output files newDir = os.path.join(self._outDir, self._basename) try: os.mkdir(newDir) self._outDir = newDir except OSError: logging.warning("Failed to create directory '{}'!".format(newDir)) pass # on failure: no subdirectory
def filename(self, kind=None, extension='.txt'): """Creates a file name from data base name, its directory and the current timestamp. It's created once so that all output files have the same base name and timestamp.""" fn = [self._basename] if isString(kind) and len(kind): fn += ["_", kind] if isString(extension): fn += extension fn = os.path.join(self._outDir, "".join(fn)) return fixFilename(fn)
def update(self): """Updates this item according to eventually changed data object""" data = self.data() # forced to be DataSet in __init__ columnCount = len(data.displayData) for column in range(0, columnCount): columnData = data.displayData[column] if not isList(columnData): # columnData is supposed to be tuple columnData = (columnData, ) for attrname in columnData: # set attributes of columns if avail if not isString(attrname): continue value = getattr(data, attrname, None) if value is None: continue getProperty, setProperty, value = self.getItemProperty(value) # set it always, regardless if needed setProperty(column, value) # adjust #table columns treeWidget = self.treeWidget() if treeWidget is not None and treeWidget.columnCount() < columnCount: treeWidget.setColumnCount(columnCount) # update children for item in self.takeChildren(): # remove all children item.remove() del item
def setSuffix(selforcls, newSuffix): if newSuffix is None: return testfor( isString(newSuffix) and len(newSuffix) > 0, SuffixError, "Parameter suffix has to be some text!") selforcls._suffix = newSuffix
def addMenuEntry(self, name = None, text = None, toolTip = None, shortCut = None, checkable = False, checked = False, callbacks = None, menuStates = None): """ Argument 'callbacks' is supposed to be a list of methods which will be connected to the QAction.triggered signal. """ a = QAction(self) assert isString(name) a.setObjectName("action{0}".format(name.title())) assert text is not None a.setText(self._updateTitle(escapeAmp(text))) if toolTip is not None: a.setToolTip(self._updateTitle(toolTip)) if shortCut is not None: a.setShortcut(shortCut) a.setShortcutContext(Qt.WidgetShortcut) a.setCheckable(bool(checkable)) a.setChecked(bool(checked)) if not isList(callbacks): callbacks = (callbacks, ) for callback in callbacks: if callback is None: continue assert callable(callback), tr("Specified callbacks have to be " "a method or a function!") a.triggered.connect(callback) self.addMenuEntryAction(name, a, menuStates) return a
def launch(cmd: str) -> None: """ Executes command """ assert(utils.isString(cmd)) if cmd == 'sd': #resets settings to default if _generateSettingsFile(): print("Settings were set to default.") elif cmd in ['se','sv']: #print settings list slist = _getSettingsList() if slist == None: print("Could not print settings list.\n") return _printSettings(slist) if cmd == 'se': print() lbl = input("Label: ") curr_value = _getSettingValueFromLabel(slist,lbl) if curr_value == None: print("Label not recognized.\n") return print("Current value for '"+lbl+"': "+curr_value) new_value = input("Setting new value: ") if _editSetting(slist,lbl,new_value): print("New value set successfully.") else: print("Command '"+cmd+"' not recognized.") print()
def update(self, obj): title = obj if not isString(title): return TitleMixin.title.fset(self, title) for func in self._updateFunc: func(title)
def setValue(self, widget, value): if None in (widget, value): return setter, dtype = None, None for attr in "checked", "value", "text": setterName = "set" + attr.title() try: setter = getattr(widget, setterName) try: oldValue = getattr(widget, attr)() except: oldValue = widget.property(attr) dtype = type(oldValue) except AttributeError: continue else: if dtype is not None: break try: if (issubclass(dtype, bool) and isString(value) and value.lower() == "false"): value = "" setter(dtype(value)) except (TypeError, ValueError) as e: raise IndexError( "Could not set widget '{0}' to '{1}'!: ".format(key, value) + str(e).title()) else: self.getEditingFinishedSignal(widget).emit() widget.update()
def _getSettingValueFromLabel( settings_list , label ): assert(utils.isList(settings_list)) assert(utils.isString(label)) for s in settings_list: if _getSettingLabel(s) == label: return _getSettingValue(s) return None
def _editSetting( settings_list , label , new_value ): # saves the new value in the cfg file assert(utils.isList(settings_list)) assert(utils.isString(label)) assert(utils.isString(new_value)) if len(new_value) == 0 or not _validateString(new_value): print("\nInvalid string for new value.") return False lbl_list = [ _getSettingLabel(s) for s in settings_list ] if not label in lbl_list: print("\nUnexpected error occurred. Label not in list.") return False if not _validateEdit(label,new_value): print("\nNew value does not meet label requirementes. Check README.") return False idx = lbl_list.index(label) settings_list[idx] = _formatSetting(label,new_value) return _writeSettings(settings_list)
def setValueRange(self, newRange): testfor(isList(newRange), ValueRangeError, "A value range for a string type parameter has to be a list!") testfor(all([isString(v) for v in newRange]), ValueRangeError, "A value range for a string has to be a list of strings!") self._valueRange = newRange if not (self.value() in self.valueRange()): # where are the default values? self.setValue(self.valueRange()[0])
def _setApplicationMetaData(self): for func, data in ((coreApp.setApplicationName, self.name()), (coreApp.setApplicationVersion, self.number()), (coreApp.setOrganizationName, self.organizationName()), (coreApp.setOrganizationDomain, self.organizationDomain())): if isString(data): func(data)
def addToMenuState(self, stateName, *entryNames): assert isString(stateName) if stateName != self.allMenuStates: # default state assert hasattr(self, stateName) assert isList(entryNames) entryList = self._states.get(stateName, []) for name in entryNames: if name in self._actions: entryList.append(name) self._states[stateName] = entryList
def writeAttribute(self, key, value): if value is None: return if isString(value): value = HDFString(value) elif type(value) == type(True): # filter boolean value = np.int8(value) self.log("attribute '{loc}/{k}': '{v}'".format( loc=self.location.rstrip('/'), k=key, v=value)) self._writeLocation().attrs[key] = value
def __init__(self, paramDefFile=None): """initialise the defaults and populate the database with values where appropriate default parameter file can be provided using kwarg: paramDefFile = 'path/to/file' relative to application root dir """ # instantiate defaults: if not isString(paramDefFile) or not os.path.exists(paramDefFile): paramDefFile = self.paramDefFile self.loadParameters(paramDefFile)
def factory(name, value, paramTypes=None, **kwargs): """ Generates a new Parameter type derived from one of the predefined base classes choosen by the supplied value: Providing a string value results in a type derived from ParameterBase, providing an integer value produces a ParameterNumerical type and a float value results in a ParameterFloat type. Alternatively, a class type cls can be provided which is used as base class for the resulting Parameter class type. Make sure in this case, all attributes mandatory for this base type are provided too. - *name*: short name of the new parameter without spaces - *value*: default value from which the type is derived if cls is not given Optional arguments: - *paramTypes*: tuple of available parameter types instead of the default - *cls*: forces a certain Parameter type. - *description*: Updates the __doc__ attribute. May be displayed in the UI somewhere. """ kwargs.update(name=name, value=value) name = kwargs.get("name", None) assertName(name, ParameterNameError) value = kwargs.get("value", None) cls = kwargs.pop("cls", None) # remove 'cls' keyword before forwarding if paramTypes is None: paramTypes = (ParameterBoolean, ParameterFloat, ParameterNumerical, ParameterBase) if not (cls is not None and ((isinstance(cls, super) and issubclass(cls.__thisclass__, ParameterBase)) or issubclass(cls, ParameterBase))): for cls in paramTypes[:-1]: if cls.isDataType(value): break else: cls = paramTypes[-1] # ParameterBase usually # embed description as class documentation clsdict = dict() description = kwargs.get("description", None) if isString(description) and len(description) > 0: clsdict['__doc__'] = description # create a new class/type with given name and base class # translate works different for unicode strings: typeName = (str(name.title()).translate(str.maketrans("", "", ' \t\n\r')) + "Parameter") NewType = None try: NewType = type(typeName, (cls, ), clsdict) except TypeError: # Python 2: type() argument 1 must be string, not unicode NewType = type(typeName.encode('ascii', 'ignore'), (cls, ), clsdict) # set up the new class before return return NewType.setAttributes(**kwargs)
def setDisplayValues(selforcls, newDisplayValues): if newDisplayValues is None: return testfor(isMap(newDisplayValues), DisplayValuesError, "Expected a display value mapping of numbers to text!") testfor(all([isNumber(v) for v in newDisplayValues.keys()]), DisplayValuesError, "Display value keys have to be numbers!") testfor(all([isString(s) for s in newDisplayValues.values()]), DisplayValuesError, "Display values have to be text!") # TODO: also add reverse lookup selforcls._displayValues = newDisplayValues
def figInit(self, nHists, figureTitle, nR=1): """initialize figure and initialise axes using GridSpec. Each rangeinfo (nR) contains two rows and nHists + 1 columns. the top row axes are for placing text objects: settings and stats. The bottom row axes are for plotting the fits and the histograms TODO: add settings to window title? (next to figure_xy)""" ahl = list() #list of axes handles from top left to bottom right. cellWidth, cellHeight = 7, 7 numCols, numRows = nHists + 1, nR self._figWidth = cellWidth * numCols self._figHeight = cellHeight * numRows fig = figure(figsize=(self._figWidth, self._figHeight), dpi=80, facecolor='w', edgecolor='k') if isString(figureTitle): fig.canvas.set_window_title(figureTitle) charWidth, charHeight = getTextSize(fig, self._textfont) charWidth, charHeight = (charWidth / (cellWidth * fig.dpi), charHeight / (cellHeight * fig.dpi)) self._charHeight = charHeight self._charWidth = charWidth gs = gridspec.GridSpec(2 * numRows, numCols, height_ratios=np.tile([1, 6], numRows)) # update margins self._subPlotPars = dict(left=charWidth * 11. / numCols, bottom=charHeight * 4., right=1. - charWidth * 7. / numCols, top=1. - charHeight * 1.5, wspace=charWidth * 20., hspace=charHeight * 12.) gs.update(**self._subPlotPars) textAxDict = { 'frame_on': False, 'yticks': [], 'xticks': [], 'ylim': [0., 1.], 'xlim': [0., 1.], } for ai in range(numCols * numRows * 2): # initialise axes ah = subplot(gs[ai]) # disable mouse coordinates while avoiding Tkinter error # about None not being callable ah.format_coord = lambda x, y: "" if ai % (numCols * 2) < numCols: ah.update(textAxDict) # text box settings: ahl.append(ah) return fig, ahl
def set(cls, lastpath): """Accepts a directory path or a file path. Determines the directory itself in the latter case.""" if not isString(lastpath): lastpath = str(lastpath) # get path of possible unwritten files (previously selected) path = lastpath while not os.path.isdir(path) and len(path) > 0: path = os.path.dirname(path) if len(path) > 0: cls._path = path else: logging.warning("Could not set last path '{0}'!".format(lastpath))
def selectModel(self, model): """*model*: string containing the name of the model to select. Calls _selectModelSlot() via signal.""" if not isString(model): return index = 0 # search the model with the provided name for i in range(0, self.modelBox.count()): if self.modelBox.itemText(i).lower() == model.lower().strip(): index = i break # set the index found or the first one otherwise self.modelBox.setCurrentIndex(index)
def __init__(self, dataCount, description = None): object.__init__(self) if any([not hasattr(self, key) for key in self._entries.keys()]): self._setup() # init header with default values if not isString(description): description = "" self.setDescription(description) self.setKeywords(["SAXS", "BOX"]) assert isInteger(dataCount) self.setDataCount(dataCount) self.setWaveLength(0) # setting spare lines self.setDummy(0)
def _validateSettingFormat( s ): if not utils.isList(s): print("Setting isn't table.") return False if len(s) != 2: print("Setting table size is wrong.") return False if True in [ not utils.isString(x) for x in s]: print("Settings variables aren't string.") return False if False in [ _validateString(x) for x in s]: print("Settings variables are invalid.") return False return True
def getSetting(label: str): """ Returns setting value if it exists """ assert(utils.isString(label)) slist = _getSettingsList() if slist == None: return None value = _getSettingValueFromLabel(slist,label) if label in ["tknlistpath", "tokenpath", "psalmspath","dictpath"] : return value elif label in ["quotmarks","upperfirst"]: return value == "true" elif label == "wordlimit": return int(value) elif label == "endchars": return [ c for c in value ] else: return None
def HDFCleanup(infile): """Unused space is reclaimed by making a copy of the contents in the current hdf 5 file object, and moves the copy in place of the original. if the input argument supplied is a file name instead of an HDF5 object, the method returns nothing. Else, the method returns the new HDF5 object""" inputIsFilename = False if isString(infile): # a filename was supplied infile = h5py.File(infile) inputIsFilename = True def hdfDeepCopy(infile, outfilename): """Copies the internals of an open HDF5 file object (infile) to a second file.""" infile.flush() outfile = h5py.File(outfilename, "w") # create file, truncate if exists for item in infile: outfile.copy(infile[item], item) for attr_name in infile.attrs: outfile.attrs[attr_name] = infile.attrs[attr_name] outfile.close() # shutil.move is more flexible than os.rename, and can move across disks. origfname = infile.filename # generate a temporary file for the original backup tempfname = "{}.hdf5".format(str(uuid.uuid4().hex)) # temporary output filename tempofname = "{}.hdf5".format(str(uuid.uuid4().hex)) shutil.copy(origfname, tempfname) # backup copy try: hdfDeepCopy(infile, tempofname) # copy internals infile.close() # close old file shutil.move(tempofname, origfname) # replace with new except: # move back the backup shutil.move(tempfname, origfname) infile = h5py.File(origfname) # reopen new file # cleanup: for filename in [tempfname, tempofname]: try: os.remove(filename) except OSError: pass if not inputIsFilename: return infile
def loaddatafile(filename): """Creates a DataFile instance from the given file name by selecting the appropriate specialised file object based on the file name extension or parts of the file contents.""" if not isString(filename) or not os.path.isfile(filename): logging.warning( u"File '{0}' is not a file or does not exist!".format(filename)) return logging.info(u"Loading '{0}' ...".format(filename)) path, ext = os.path.splitext(filename) ext = ext[1:].lower() datafile = None if ext in PDHFile.extensions: datafile = PDHFile(filename) else: datafile = ArrayFile(filename) # works for CSV too return datafile
def restoreSession(self, model=None): """Load last known user settings from persistent app settings.""" if self.appSettings is None: return if model is None: # get the last model used and select it self.appSettings.beginGroup(self.objectName()) model = self.appSettings.value("model") self.appSettings.endGroup() # calls restoreSession(model) and storeSession() # mind the QSettings.group() if not isString(model): # default model if none set model = "Sphere" self.selectModel(model) else: self.appSettings.beginGroup(self.objectName()) super(ModelWidget, self).restoreSession(model) self.appSettings.endGroup() self._statsWidget.restoreSession()
def title(self, title): assert (title is not None and isString(title) and len(title) > 0), \ "Expected a meaningful title!" self._title = title
def isDataType(cls, value): return isString(value)
def setDisplayName(selforcls, newName): if (not isString(newName) or len(newName) <= 0): newName = selforcls.name() if newName is not None: selforcls._displayName = str(newName)