Exemplo n.º 1
0
 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
Exemplo n.º 2
0
 def setGenerator(selforcls, newGenerator):
     if isinstance(newGenerator, type):
         testfor(issubclass(newGenerator, NumberGenerator),
                 ParameterGeneratorError, "NumberGenerator type expected!")
     else:
         newGenerator = RandomUniform
     selforcls._generator = newGenerator
Exemplo n.º 3
0
 def setValue(selforcls, newValue):
     testfor(newValue is not None, DefaultValueError,
             "Default value is mandatory!")
     if selforcls._value == newValue:
         return  # no update necessary
     selforcls._value = newValue
     if isCallable(selforcls.onValueUpdate()):
         selforcls.onValueUpdate()()
Exemplo n.º 4
0
 def setValue(selforcls, newValue, clip=True):
     if newValue is None:
         return  # ignore
     testfor(isNumber(newValue), DefaultValueError,
             u"A value has to be numerical! ({})".format(newValue))
     if clip:
         # clip to min/max values:
         newValue = selforcls.clip(newValue)
     super(ParameterNumerical, selforcls).setValue(newValue)
Exemplo n.º 5
0
 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])
Exemplo n.º 6
0
    def __call__(self, dataset):
        if self.model is None:
            logging.warning("No model set!")
            return
        # start log file writing
        testfor(isinstance(dataset, DataSet), Exception,
                "{cls} requires a DataSet!".format(cls=type(self)))
        self._outFn = OutputFilename(dataset)
        fn = self._outFn.filenameVerbose("log", "this log")
        logFile = logging.FileHandler(fn, encoding="utf8")
        widgetHandler = log.getWidgetHandlers()[0]
        log.replaceHandler(widgetHandler)  # remove everything else
        log.addHandler(logFile)
        try:
            # show last lines about pdf output from separate thread
            widgetHandler.widget.addWatchDir(self._outFn.outDir)
        except AttributeError:
            pass

        self._writeSettings(dict(), dataset)
        if self.nolog:  # refers to the widgethandler
            log.removeHandler(widgetHandler)
        #set data in the algorithm
        self._algo.data = dataset

        # write HDF5, show exceptions traceback, if any
        try:
            self.hdfStore(self._outFn.filenameVerbose(
                "hdf5archive",
                "Complete state of the calculation",
                extension='.hdf5'),
                          rootLocation="mcsasentry")
        except Exception as e:
            import traceback
            print(traceback.format_exc())

        self._algo.calc()
        if self.nolog:
            log.addHandler(widgetHandler)

        if isList(self._algo.result) and len(self._algo.result):
            res = self._algo.result[0]
            # quick hack for now, will get fixed with Parameter design
            for p in self.model.activeParams():
                self._writeDistrib(p)
                self._writeStatistics(p)
            self._updateSeries(dataset, self.model)
            # plotting last so stats were already calculated
            if res is not None:
                self._writeFit(res)
                self._writeContribs(res)
                self._algo.plot(outputFilename=self._outFn,
                                autoClose=self._algo.autoClose())
        else:
            logging.info("No results available!")

        log.removeHandler(logFile)
Exemplo n.º 7
0
 def setDecimals(selforcls, newDecimals):
     if newDecimals is not None:
         testfor(
             isNumber(newDecimals) and newDecimals >= 0, DecimalsError,
             "Parameter decimals has to be a positive number!")
     else:
         start, end = selforcls._valueRange
         newDecimals = round(math_log10(math_fabs(end - start)))
     newDecimals = max(newDecimals, 0)
     newDecimals = min(newDecimals, sys.float_info.max_10_exp)
     selforcls._decimals = int(newDecimals)
Exemplo n.º 8
0
 def setParams(cls, *parameters):
     """Expects a list of ParameterBase classes/types and sets them as
     class attributes to this class. They will become instances later,
     please see __init__()"""
     cls._parameters = []
     for i, p in enumerate(parameters):
         testfor(
             isinstance(p, type) and issubclass(p, ParameterBase),
             AlgorithmParameterError, "{name}: Expected a "
             "ParameterBase type for parameter {index}, got {type}!".format(
                 name=cls.__name__, index=i, type=p))
         cls.setParam(p)
Exemplo n.º 9
0
 def __init__(self):
     """Creates instances from defined parameters and replaces the class
     attributes accordingly."""
     testfor(
         self._name is not None, AlgorithmNameError, "No name provided! "
         "Set up {name} by calling factory() first.".format(
             name=type(self).__name__))
     testfor(
         self._parameters is not None, AlgorithmParameterError,
         "Parameters not configured! "
         "Set up {name} by calling factory() first.".format(
             name=type(self).__name__))
     paramTypes = self.params()
     self._parameters = None
     for ptype in paramTypes:
         self.setParam(ptype())
Exemplo n.º 10
0
    def test(cls, filename):
        """Regression test of a scattering model. File names are expected
        to contain the parameter values which produce the provided intensity.
        Otherwise implement fixTestParams() for the particular model.

        - *filename*: Name of the file in cls.testDataDir to test against.
        - *cls.testRelErr*: Acceptable mean of relative error against reference
                            intensity. Default: 1e-5
        - *cls.testVolExp*: Volume compensation exponent, sets the amount of
                            volume contribution the intensity is scaled by.
        - *cls.testDataDir*: Directory of test data relative to program dir.
                             Default: "testdata"
        """
        return # this does not work anymore
        relerr = getattr(cls, "testRelErr", 1e-5)
        datadir = getattr(cls, "testDataDir", "testdata")
        volumeExponent = getattr(cls, "testVolExp", 1.0)
        filename = os.path.abspath(os.path.join(datadir, filename))
        #dataset = SASData.load(filename)
        if dataset is None:
            return
        model = cls()
        testParams = model.getParametersFromFilename(dataset.filename)
        model.update(testParams)
        # intensity how it's calculated in SASfit
        intensity = (model.vol(None,
                               compensationExponent = volumeExponent)
                     * model._formfactor(dataset, None))**2.
        # computing the relative error to reference data
        delta = abs((dataset.f.binnedData - intensity) / dataset.f.binnedData)
        dmax = argmax(delta)
        testfor(delta.mean() < relerr, AssertionError,
                "Could not verify {model} intensity against\n'{fn}',"
                "\nmean(delta): {mean} >= relErr: {relerr}"
                "\nQ, Int_ref, Int_calc, Delta around dmax({dmax}):"
                "\n{data}"
                .format(model = cls.name(), fn = filename,
                        mean = delta.mean(), relerr = relerr,
                        dmax = dmax, data = hstack((
                            dataset.x0.binnedData.reshape(-1, 1),
                            dataset.f.binnedData.reshape(-1, 1),
                            intensity.reshape(-1, 1),
                            delta.reshape(-1, 1)))[max(0, dmax-4):dmax+5]
                        )
                )
Exemplo n.º 11
0
 def getParametersFromFilename(cls, filename):
     """Derives model parameters for testing from reference data file."""
     pnames = os.path.splitext(os.path.basename(filename))[0]
     pnames = pnames.split("-")
     errorMsg = ("Could not infer {model} parameters from '{fn}'!"
                 .format(model = cls.name(), fn = filename))
     testfor(len(pnames) > cls.paramCount(), NameError, errorMsg)
     # exclude the base name at front
     pnames = tuple(enumerate(pnames[1:]))
     # store all values by index for reference in fixTestParams()
     result = dict(pnames)
     # map values to parameter names beginning at front
     for i, valueStr in pnames:
         try:
             p = cls.param(i) # raises IndexError eventually
             result[p.name()] = p.dtype(valueStr)
         except IndexError: continue
     return result
Exemplo n.º 12
0
 def _makeEntry(self,
                name,
                dtype,
                value,
                minmax=None,
                widgetType=None,
                parent=None,
                decimals=None,
                **kwargs):
     testfor(
         name not in self.keys, KeyError,
         "Input widget '{w}' exists already in '{s}'".format(
             w=name, s=self.objectName()))
     if widgetType is None:
         if dtype is float:
             widgetType = SciEntryBox
         else:
             widgetType = self.getInputWidget(dtype)
     if parent is None:
         parent = self
     widget = widgetType(parent, **kwargs)
     widget.setObjectName(name)
     if decimals is not None:  # set precision before the value is set
         widget.setDecimals(decimals)
     if dtype is bool:
         widget.setCheckable(True)
         widget.setChecked(value)
     else:
         widget.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
         if isList(minmax) and len(minmax):
             widget.setMinimum(min(minmax))
             widget.setMaximum(max(minmax))
         widget.setValue(value)
     # update tooltip with help text about valid input values
     decimals = getattr(widget, "decimals", None)
     if decimals is not None:
         decimals = decimals()
     try:
         SciEntryBox.updateToolTip(widget, decimals)
     except:
         pass  # for non-float input widgets
     self.connectInputWidgets(widget)
     return widget
Exemplo n.º 13
0
 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
Exemplo n.º 14
0
 def setValueRange(selforcls, newRange):
     testfor(isList(newRange), ValueRangeError,
             "A value range is mandatory for a numerical parameter!")
     testfor(
         len(newRange) == 2, ValueRangeError,
         "A value range has to consist of two values!")
     testfor(all([isNumber(v) for v in newRange]), ValueRangeError,
             "A value range has to consist of numbers only!")
     minVal, maxVal = min(newRange), max(newRange)
     # minVal = max(minVal, -sys.float_info.max)
     # maxVal = min(maxVal,  sys.float_info.max)
     # avoid inf/nan showing up somewhere
     # otherwise, inf might be ok if UI elements support it (going in&out)
     minVal = max(minVal, -1e200)  # as good as -inf?...
     maxVal = min(maxVal, 1e200)  # as good as inf?...
     selforcls._valueRange = minVal, maxVal
     # apply limits to value:
     selforcls.setValue(selforcls.clip())
Exemplo n.º 15
0
 def setStepping(selforcls, newStepping):
     if newStepping is None:
         return
     testfor(isNumber(newStepping), SteppingError,
             "Parameter has to be a number!")
     selforcls._stepping = newStepping
Exemplo n.º 16
0
 def __init__(self):
     self._path = self._getPath()
     testfor(
         self._path is not None and os.path.isfile(self._path), OSError,
         "{name}: '{path}' not found!".format(name=self._name,
                                              path=self._path))