示例#1
0
    def PyExec(self):
        # Check congruence of workspaces
        workspaces = self.getProperty('Workspaces').value
        fvalues = self.getProperty('ParameterValues').value
        if len(workspaces) != len(fvalues):
            mesg = 'Number of Workspaces and ParameterValues should be the same'
            #logger.error(mesg)
            raise IndexError(mesg)
        for workspace in workspaces[1:]:
            if not self.areWorkspacesCompatible(mantid.mtd[workspaces[0]],
                                                mantid.mtd[workspace]):
                mesg = 'Workspace {0} incompatible with {1}'.format(
                    workspace, workspaces[0])
                logger.error(mesg)
                raise ValueError(mesg)
    # Load the workspaces into a group of dynamic structure factors
        from dsfinterp.dsf import Dsf
        from dsfinterp.dsfgroup import DsfGroup
        from dsfinterp.channelgroup import ChannelGroup
        dsfgroup = DsfGroup()
        for idsf in range(len(workspaces)):
            dsf = Dsf()
            dsf.Load(mantid.mtd[workspaces[idsf]])
            if not self.getProperty('LoadErrors').value:
                dsf.errors = None  # do not incorporate error data
            dsf.SetFvalue(fvalues[idsf])
            dsfgroup.InsertDsf(dsf)
    # Create the intepolator if not instantiated before
        if not self.channelgroup:
            self.channelgroup = ChannelGroup()
            self.channelgroup.InitFromDsfGroup(dsfgroup)
            localregression = self.getProperty('LocalRegression').value
            if localregression:
                regressiontype = self.getProperty('RegressionType').value
                windowlength = self.getProperty('RegressionWindow').value
                self.channelgroup.InitializeInterpolator(
                    running_regr_type=regressiontype,
                    windowlength=windowlength)
            else:
                self.channelgroup.InitializeInterpolator(windowlength=0)

    # Invoke the interpolator and generate the output workspaces
        targetfvalues = self.getProperty('TargetParameters').value
        for targetfvalue in targetfvalues:
            if targetfvalue < min(fvalues) or targetfvalue > max(fvalues):
                mesg = 'Target parameters should lie in [{0}, {1}]'.format(
                    min(fvalues), max(fvalues))
                logger.error(mesg)
                raise ValueError(mesg)
        outworkspaces = self.getProperty('OutputWorkspaces').value
        if len(targetfvalues) != len(outworkspaces):
            mesg = 'Number of OutputWorkspaces and TargetParameters should be the same'
            logger.error(mesg)
            raise IndexError(mesg)
        for i in range(len(targetfvalues)):
            dsf = self.channelgroup(targetfvalues[i])
            outws = mantid.simpleapi.CloneWorkspace(
                mantid.mtd[workspaces[0]], OutputWorkspace=outworkspaces[i])
            dsf.Save(outws)  # overwrite dataY and dataE
示例#2
0
 def function1D(self, xvals):
     ''' Fit using the interpolated structure factor '''
     p = self.validateParams()
     if not p:
         return numpy.zeros(
             len(xvals),
             dtype=float)  # return zeros if parameters not valid
     # The first time the function is called requires initialization of the interpolator
     if self._channelgroup is None:
         # Check consistency of the input
         # check InputWorkspaces have at least the workspace index
         for w in self._InputWorkspaces:
             if mtd[w].getNumberHistograms() <= self._WorkspaceIndex:
                 message = 'Numer of histograms in Workspace {0} does not allow for workspace index {1}'.format(
                     w, self._WorkspaceIndex)
                 logger.error(message)
                 raise IndexError(message)
         # check number of input workspaces and parameters is the same
         if len(self._ParameterValues) != len(self._InputWorkspaces):
             message = 'Number of InputWorkspaces and ParameterValues should be the same.'+\
                       ' Found {0} and {1}, respectively'.format(len(self._InputWorkspaces), len(self._ParameterValues))
             logger.error(message)
             raise ValueError(message)
         # check the regression type is valid
         if self._RegressionType not in self._RegressionTypes:
             message = 'Regression type {0} not implemented. choose one of {1}'.format(
                 self._RegressionType, ', '.join(self._RegressionTypes))
             logger.error(message)
             raise NotImplementedError(message)
         # check the regression window is appropriate for the regression type selected
         if self._RegressionWindow < self._minWindow[self._RegressionType]:
             message = 'RegressionWindow must be equal or bigger than '+\
                       '{0} for regression type {1}'.format(self._minWindow[self._RegressionType], self._RegressionType)
             logger.error(message)
             raise ValueError(message)
         # Initialize the energies of the channels with the first of the input workspaces
         self._xvalues = numpy.copy(mtd[self._InputWorkspaces[0]].dataX(
             self._WorkspaceIndex))
         if len(self._xvalues) == 1 + len(
                 mtd[self._InputWorkspaces[0]].dataY(self._WorkspaceIndex)):
             self._xvalues = (self._xvalues[1:] + self._xvalues[:-1]
                              ) / 2.0  # Deal with histogram data
         # Initialize the channel group
         nf = len(self._ParameterValues)
         # Load the InputWorkspaces into a group of dynamic structure factors
         from dsfinterp.dsf import Dsf
         from dsfinterp.dsfgroup import DsfGroup
         dsfgroup = DsfGroup()
         for idsf in range(nf):
             dsf = Dsf()
             dsf.SetIntensities(mtd[self._InputWorkspaces[idsf]].dataY(
                 self._WorkspaceIndex))
             dsf.errors = None  # do not incorporate error data
             if self._LoadErrors:
                 dsf.SetErrors(mtd[self._InputWorkspaces[idsf]].dataE(
                     self._WorkspaceIndex))
             dsf.SetFvalue(self._ParameterValues[idsf])
             dsfgroup.InsertDsf(dsf)
         # Create the interpolator
         from dsfinterp.channelgroup import ChannelGroup
         self._channelgroup = ChannelGroup()
         self._channelgroup.InitFromDsfGroup(dsfgroup)
         if self._LocalRegression:
             self._channelgroup.InitializeInterpolator(
                 running_regr_type=self._RegressionType,
                 windowlength=self._RegressionWindow)
         else:
             self._channelgroup.InitializeInterpolator(windowlength=0)
     # channel group has been initialized, so evaluate the interpolator
     dsf = self._channelgroup(p['TargetParameter'])
     # Linear interpolation between the energies of the channels and the xvalues we require
     # NOTE: interpolator evaluates to zero for any of the xvals outside of the domain defined by self._xvalues
     intensities_interpolator = scipy.interpolate.interp1d(self._xvalues,
                                                           p['Intensity'] *
                                                           dsf.intensities,
                                                           kind='linear')
     return intensities_interpolator(xvals)  # can we pass by reference?