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
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?