Ejemplo n.º 1
0
    def create_fit_function_str(self, param_vals=None, param_prefix=""):
        """Creates a string used by the Fit algorithm for this profile

        :param param_vals: A table of values for the parameters that override those set
        on the object already. Default=None
        :param param_prefix: A string prefix for the parameter as seen by the Mantid Fit algorithm
        """
        vals_provided = (param_vals is not None)

        if vals_provided:
            def_width = param_vals[param_prefix + "Width"]
        else:
            def_width = self.width
            if isinstance(def_width, list):
                def_width = def_width[1]

        fitting_str = "name={0},Mass={1:f},Width={2:f}".format(self.cfunction, self.mass, def_width)
        if vals_provided:
            param_name = "Intensity"
            intensity_str = "{0}={1:f}".format(param_name, param_vals[param_prefix + param_name])
            fitting_str += "," + intensity_str
        elif self.intensity is not None:
            fitting_str += ",Intensity={0:f}".format(self.intensity)

        logger.debug("Gaussian profile fit function string: {0}".format(fitting_str))
        return fitting_str + ";"
Ejemplo n.º 2
0
def unwrap_monitor(workspace_name):
    """
    Unwrap monitor if required based on value of Workflow.UnwrapMonitor parameter

    @param workspace_name Name of workspace
    @return True if the monitor was unwrapped
    """
    from mantid.simpleapi import (UnwrapMonitor, RemoveBins, FFTSmooth)

    monitor_workspace_name = workspace_name + '_mon'
    instrument = mtd[monitor_workspace_name].getInstrument()

    # Determine if the monitor should be unwrapped
    try:
        unwrap = instrument.getStringParameter('Workflow.UnwrapMonitor')[0]

        if unwrap == 'Always':
            should_unwrap = True
        elif unwrap == 'BaseOnTimeRegime':
            mon_time = mtd[monitor_workspace_name].readX(0)[0]
            det_time = mtd[workspace_name].readX(0)[0]
            should_unwrap = mon_time == det_time
        else:
            should_unwrap = False

    except IndexError:
        should_unwrap = False

    logger.debug('Need to unwrap monitor for %s: %s' %
                 (workspace_name, str(should_unwrap)))

    if should_unwrap:
        sample = instrument.getSample()
        sample_to_source = sample.getPos() - instrument.getSource().getPos()
        radius = mtd[workspace_name].getDetector(0).getDistance(sample)
        z_dist = sample_to_source.getZ()
        l_ref = z_dist + radius

        logger.debug('For workspace %s: radius=%d, z_dist=%d, l_ref=%d' %
                     (workspace_name, radius, z_dist, l_ref))

        _, join = UnwrapMonitor(InputWorkspace=monitor_workspace_name,
                                OutputWorkspace=monitor_workspace_name,
                                LRef=l_ref)

        RemoveBins(InputWorkspace=monitor_workspace_name,
                   OutputWorkspace=monitor_workspace_name,
                   XMin=join - 0.001,
                   XMax=join + 0.001,
                   Interpolation='Linear')

        try:
            FFTSmooth(InputWorkspace=monitor_workspace_name,
                      OutputWorkspace=monitor_workspace_name,
                      WorkspaceIndex=0,
                      IgnoreXBins=True)
        except ValueError:
            raise ValueError('Uneven bin widths are not supported.')

    return should_unwrap
Ejemplo n.º 3
0
    def write_out(self):
        """
        Write out the project file that contains workspace names, interfaces information, plot preferences etc.
        """
        # Get the JSON string versions
        to_save_dict = {
            "workspaces": self.workspace_names,
            "plots": self.plots_to_save,
            "interfaces": self.interfaces_to_save
        }

        # Open file and save the string to it alongside the workspace_names
        if self.project_file_ext not in os.path.basename(self.file_name):
            self.file_name = self.file_name + self.project_file_ext
        try:
            with open(self.file_name, "w+") as f:
                dump(obj=to_save_dict, fp=f)
        except KeyboardInterrupt:
            # Catch any exception and log it
            raise
        except (IOError, OSError, WindowsError) as e:
            logger.warning("JSON project file unable to be opened/written to.")
            logger.debug("Full error: {}".format(e))
        except Exception as e:
            logger.warning("Unknown error occurred. Full detail: {}".format(e))
Ejemplo n.º 4
0
    def get_dict_from_fig(self, fig):
        axes_list = []
        create_list = []
        for ax in fig.axes:
            try:
                creation_args = deepcopy(ax.creation_args)
                # convert the normalise object (if present) into a dict so that it can be json serialised
                for args_dict in creation_args:
                    if 'axis' in args_dict and type(args_dict['axis']) is MantidAxType:
                        args_dict['axis'] = args_dict['axis'].value
                    if 'norm' in args_dict.keys() and isinstance(args_dict['norm'], Normalize):
                        norm_dict = self._convert_normalise_obj_to_dict(args_dict['norm'])
                        args_dict['norm'] = norm_dict
                    if 'axis' in args_dict.keys():
                        args_dict['axis'] = args_dict['axis'].value
                create_list.append(creation_args)
                self.figure_creation_args = creation_args
            except AttributeError:
                logger.debug("Axis had an axis without creation_args - Common with a Colorfill plot")
                continue
            axes_list.append(self.get_dict_for_axes(ax))

        if create_list and axes_list:
            self._add_normalisation_kwargs(create_list, axes_list)
        fig_dict = {"creationArguments": create_list,
                    "axes": axes_list,
                    "label": fig._label,
                    "properties": self.get_dict_from_fig_properties(fig)}
        return fig_dict
Ejemplo n.º 5
0
def identify_bad_detectors(workspace_name):
    """
    Identify detectors which should be masked

    @param workspace_name Name of workspace to use to get masking detectors
    @return List of masked spectra
    """
    from mantid.simpleapi import (IdentifyNoisyDetectors, DeleteWorkspace)

    instrument = mtd[workspace_name].getInstrument()

    try:
        masking_type = instrument.getStringParameter('Workflow.Masking')[0]
    except IndexError:
        masking_type = 'None'

    logger.information('Masking type: %s' % masking_type)

    masked_spec = list()

    if masking_type == 'IdentifyNoisyDetectors':
        ws_mask = '__workspace_mask'
        IdentifyNoisyDetectors(InputWorkspace=workspace_name,
                               OutputWorkspace=ws_mask)

        # Convert workspace to a list of spectra
        num_spec = mtd[ws_mask].getNumberHistograms()
        masked_spec = [spec for spec in range(0, num_spec) if mtd[ws_mask].readY(spec)[0] == 0.0]

        # Remove the temporary masking workspace
        DeleteWorkspace(ws_mask)

    logger.debug('Masked spectra for workspace %s: %s' % (workspace_name, str(masked_spec)))

    return masked_spec
Ejemplo n.º 6
0
    def create_fit_function_str(self, param_vals=None, param_prefix=""):
        """Creates a string used by the Fit algorithm for this profile

        :param param_vals: A table of values for the parameters that override those set
        on the object already. Default=None
        :param param_prefix: A string prefix for the parameter as seen by the Mantid Fit algorithm
        """
        vals_provided = (param_vals is not None)

        intensity = None

        if vals_provided:
            intensity = param_vals[param_prefix + "Intensity"]
            sig_x = param_vals[param_prefix + "SigmaX"]
            sig_y = param_vals[param_prefix + "SigmaY"]
            sig_z = param_vals[param_prefix + "SigmaZ"]
        else:
            intensity = self.intensity
            sig_x = self._sigma_x
            sig_y = self._sigma_y
            sig_z = self._sigma_z

        fitting_str = "name={0},IntegrationSteps={1},Mass={2:f},SigmaX={3:f},SigmaY={4:f},SigmaZ={5:f}"
        fitting_str = fitting_str.format(self.cfunction, self.integration_steps, self.mass, sig_x, sig_y, sig_z)

        if intensity is not None:
            fitting_str += ",Intensity={0:f}".format(intensity)

        logger.debug("Multivariate Gaussian profile fit function string: {0}".format(fitting_str))
        return fitting_str + ";"
Ejemplo n.º 7
0
def identify_bad_detectors(workspace_name):
    """
    Identify detectors which should be masked

    @param workspace_name Name of workspace to use to get masking detectors
    @return List of masked spectra
    """
    from mantid.simpleapi import (IdentifyNoisyDetectors, DeleteWorkspace)

    instrument = mtd[workspace_name].getInstrument()

    try:
        masking_type = instrument.getStringParameter('Workflow.Masking')[0]
    except IndexError:
        masking_type = 'None'

    logger.information('Masking type: %s' % masking_type)

    masked_spec = list()

    if masking_type == 'IdentifyNoisyDetectors':
        ws_mask = '__workspace_mask'
        IdentifyNoisyDetectors(InputWorkspace=workspace_name,
                               OutputWorkspace=ws_mask)

        # Convert workspace to a list of spectra
        num_spec = mtd[ws_mask].getNumberHistograms()
        masked_spec = [spec for spec in range(0, num_spec) if mtd[ws_mask].readY(spec)[0] == 0.0]

        # Remove the temporary masking workspace
        DeleteWorkspace(ws_mask)

    logger.debug('Masked spectra for workspace %s: %s' % (workspace_name, str(masked_spec)))

    return masked_spec
Ejemplo n.º 8
0
def unwrap_monitor(workspace_name):
    """
    Unwrap monitor if required based on value of Workflow.UnwrapMonitor parameter

    @param workspace_name Name of workspace
    @return True if the monitor was unwrapped
    """
    from mantid.simpleapi import (UnwrapMonitor, RemoveBins, FFTSmooth)

    monitor_workspace_name = workspace_name + '_mon'
    instrument = mtd[monitor_workspace_name].getInstrument()

    # Determine if the monitor should be unwrapped
    try:
        unwrap = instrument.getStringParameter('Workflow.UnwrapMonitor')[0]

        if unwrap == 'Always':
            should_unwrap = True
        elif unwrap == 'BaseOnTimeRegime':
            mon_time = mtd[monitor_workspace_name].readX(0)[0]
            det_time = mtd[workspace_name].readX(0)[0]
            logger.notice(str(mon_time) + " " + str(det_time))
            should_unwrap = mon_time == det_time
        else:
            should_unwrap = False

    except IndexError:
        should_unwrap = False

    logger.debug('Need to unwrap monitor for %s: %s' % (workspace_name, str(should_unwrap)))

    if should_unwrap:
        sample = instrument.getSample()
        sample_to_source = sample.getPos() - instrument.getSource().getPos()
        radius = mtd[workspace_name].getDetector(0).getDistance(sample)
        z_dist = sample_to_source.getZ()
        l_ref = z_dist + radius

        logger.debug('For workspace %s: radius=%d, z_dist=%d, l_ref=%d' %
                     (workspace_name, radius, z_dist, l_ref))

        _, join = UnwrapMonitor(InputWorkspace=monitor_workspace_name,
                                OutputWorkspace=monitor_workspace_name,
                                LRef=l_ref)

        RemoveBins(InputWorkspace=monitor_workspace_name,
                   OutputWorkspace=monitor_workspace_name,
                   XMin=join - 0.001, XMax=join + 0.001,
                   Interpolation='Linear')

        try:
            FFTSmooth(InputWorkspace=monitor_workspace_name,
                      OutputWorkspace=monitor_workspace_name,
                      WorkspaceIndex=0,
                      IgnoreXBins=True)
        except ValueError:
            raise ValueError('Uneven bin widths are not supported.')

    return should_unwrap
Ejemplo n.º 9
0
 def _convolution(self, signal):
     from astropy.convolution import convolve, convolve_fft, Gaussian1DKernel
     G1D = Gaussian1DKernel(self.getProperty("ConvolutionWidth").value).array
     G3D = G1D * G1D.reshape((-1,1)) * G1D.reshape((-1,1,1))
     try:
         logger.debug('Trying astropy.convolution.convolve_fft for convolution')
         return convolve_fft(signal, G3D)  # Faster but will fail with large signal and kernel arrays
     except ValueError:
         logger.debug('Using astropy.convolution.convolve for convolution')
         return convolve(signal, G3D)
Ejemplo n.º 10
0
def _load_files(file_specifiers, ipf_filename, spec_min, spec_max, load_logs=True, load_opts=None):
    """
    Loads a set of files and extracts just the spectra we care about (i.e. detector range and monitor).

    @param file_specifiers List of data file specifiers
    @param ipf_filename File path/name for the instrument parameter file to load
    @param spec_min Minimum spectra ID to load
    @param spec_max Maximum spectra ID to load
    @param load_logs Load log files when loading runs
    @param load_opts Additional options to be passed to load algorithm

    @return List of loaded workspace names and flag indicating chopped data
    """
    delete_monitors = False

    if load_opts is None:
        load_opts = {}

    if "DeleteMonitors" in load_opts:
        delete_monitors = load_opts["DeleteMonitors"]
        load_opts.pop("DeleteMonitors")

    workspace_names = []
    chopped_data = False

    for file_specifier in file_specifiers:
        # The filename without path and extension will be the workspace name
        ws_name = os.path.splitext(os.path.basename(str(file_specifier)))[0]
        logger.debug('Loading file %s as workspace %s' % (file_specifier, ws_name))
        do_load(file_specifier, ws_name, ipf_filename, load_logs, load_opts)
        workspace = mtd[ws_name]

        # Add the workspace to the list of workspaces
        workspace_names.append(ws_name)

        # Get the spectrum number for the monitor
        instrument = workspace.getInstrument()
        monitor_param = instrument.getNumberParameter('Workflow.Monitor1-SpectrumNumber')

        if monitor_param:
            monitor_index = int(monitor_param[0])
            logger.debug('Workspace %s monitor 1 spectrum number :%d' % (ws_name, monitor_index))

            workspaces, chopped_data = chop_workspace(workspace, monitor_index)
            crop_workspaces(workspaces, spec_min, spec_max, not delete_monitors, monitor_index)

    logger.information('Loaded workspace names: %s' % (str(workspace_names)))
    logger.information('Chopped data: %s' % (str(chopped_data)))

    if delete_monitors:
        load_opts['DeleteMonitors'] = True

    return workspace_names, chopped_data
Ejemplo n.º 11
0
def _load_files(file_specifiers, ipf_filename, spec_min, spec_max, load_logs=True, load_opts=None):
    """
    Loads a set of files and extracts just the spectra we care about (i.e. detector range and monitor).

    @param file_specifiers List of data file specifiers
    @param ipf_filename File path/name for the instrument parameter file to load
    @param spec_min Minimum spectra ID to load
    @param spec_max Maximum spectra ID to load
    @param load_logs Load log files when loading runs
    @param load_opts Additional options to be passed to load algorithm

    @return List of loaded workspace names and flag indicating chopped data
    """
    delete_monitors = False

    if load_opts is None:
        load_opts = {}

    if "DeleteMonitors" in load_opts:
        delete_monitors = load_opts["DeleteMonitors"]
        load_opts.pop("DeleteMonitors")

    workspace_names = []
    chopped_data = False

    for file_specifier in file_specifiers:
        # The filename without path and extension will be the workspace name
        ws_name = os.path.splitext(os.path.basename(str(file_specifier)))[0]
        logger.debug('Loading file %s as workspace %s' % (file_specifier, ws_name))
        do_load(file_specifier, ws_name, ipf_filename, load_logs, load_opts)
        workspace = mtd[ws_name]

        # Add the workspace to the list of workspaces
        workspace_names.append(ws_name)

        # Get the spectrum number for the monitor
        instrument = workspace.getInstrument()
        monitor_param = instrument.getNumberParameter('Workflow.Monitor1-SpectrumNumber')

        if monitor_param:
            monitor_index = int(monitor_param[0])
            logger.debug('Workspace %s monitor 1 spectrum number :%d' % (ws_name, monitor_index))

            workspaces, chopped_data = chop_workspace(workspace, monitor_index)
            crop_workspaces(workspaces, spec_min, spec_max, not delete_monitors, monitor_index)

    logger.information('Loaded workspace names: %s' % (str(workspace_names)))
    logger.information('Chopped data: %s' % (str(chopped_data)))

    if delete_monitors:
        load_opts['DeleteMonitors'] = True

    return workspace_names, chopped_data
Ejemplo n.º 12
0
def create_from_str(func_str, mass):
    """Try and parse the function string to give the required profile function

        :param func_str: A string of the form 'function=Name,attr1=val1,attr2=val2'
        :param mass: The value of the mass for the profile
    """
    known_types = [GaussianMassProfile, MultivariateGaussianMassProfile, GramCharlierMassProfile]
    logger.debug("Profile factory string: {0}".format(func_str))
    errors = dict()
    for cls in known_types:
        try:
            return cls.from_str(func_str, mass)
        except TypeError, exc:
            errors[str(cls)] = str(exc)
Ejemplo n.º 13
0
    def update_colorbar_from_dict(image, dic):
        # colorbar = image.colorbar
        image.set_clim(*sorted([dic["min"], dic["max"]]))
        image.set_label(dic["label"])
        image.set_cmap(cm.get_cmap(dic["cmap"]))
        image.set_interpolation(dic["interpolation"])
        #Try and make the cmap line up but sometimes it wont
        try:
            image.axes.set_cmap(cm.get_cmap(dic["cmap"]))
        except AttributeError as e:
            logger.debug("PlotsLoader - The Image accessed did not have an axes with the ability to set the cmap: "
                         + str(e))

        # Redraw
        image.axes.figure.canvas.draw()
    def _mask(self, ws, xstart, xend):
        """
        Masks the first and last bins
        @param   ws           :: input workspace name
        @param   xstart       :: MaskBins between x[0] and x[xstart]
        @param   xend         :: MaskBins between x[xend] and x[-1]
        """
        x_values = mtd[ws].readX(0)

        if xstart > 0:
            logger.debug('Mask bins smaller than {0}'.format(xstart))
            MaskBins(InputWorkspace=ws, OutputWorkspace=ws, XMin=x_values[0], XMax=x_values[xstart])

        if xend < len(x_values) - 1:
            logger.debug('Mask bins larger than {0}'.format(xend))
            MaskBins(InputWorkspace=ws, OutputWorkspace=ws, XMin=x_values[xend + 1], XMax=x_values[-1])
Ejemplo n.º 15
0
    def restore_normalise_obj_from_dict(self, norm_dict):
        supported_norm_types = {
            # matplotlib norms that are supported.
            'Normalize': matplotlib.colors.Normalize,
            'LogNorm': matplotlib.colors.LogNorm,
        }
        # If there is a norm dict, but the type is not specified, default to base Normalize class.
        type = norm_dict['type'] if 'type' in norm_dict.keys() else 'Normalize'

        if type not in supported_norm_types.keys():
            logger.debug(
                f"Color normalisation of type {norm_dict['type']} is not supported. Normalisation will not be set on this plot")
            return None

        norm = supported_norm_types[type]
        return norm(vmin=norm_dict['vmin'], vmax=norm_dict['vmax'], clip=norm_dict['clip'])
Ejemplo n.º 16
0
    def get_dict_from_fig(self, fig):
        axes_list = []
        create_list = []
        for ax in fig.axes:
            try:
                create_list.append(ax.creation_args)
                self.figure_creation_args = ax.creation_args
            except AttributeError:
                logger.debug("Axis had a axis without creation_args - Common with colorfill")
                continue
            axes_list.append(self.get_dict_for_axes(ax))

        fig_dict = {"creationArguments": create_list,
                    "axes": axes_list,
                    "label": fig._label,
                    "properties": self.get_dict_from_fig_properties(fig)}
        return fig_dict
Ejemplo n.º 17
0
    def create_fit_function_str(self, param_vals=None, param_prefix=""):
        """Creates a string used by the Fit algorithm for this profile

        :param param_vals: A table of values for the parameters that override those set
        on the object already. Default=None
        :param param_prefix: A string prefix for the parameter as seen by the Mantid Fit algorithm
        """
        vals_provided = (param_vals is not None)

        if vals_provided:
            def_width = param_vals[param_prefix + "Width"]
        else:
            def_width = self.width
            if isinstance(def_width, list):
                def_width = def_width[1]

        def to_space_sep_str(collection):
            _str = ""
            for item in collection:
                _str += " " + str(item)
            return _str.lstrip()

        hermite_str = to_space_sep_str(self.hermite_co)

        fitting_str = "name={0},Mass={1:f},HermiteCoeffs={2},Width={3:f}".format(
            self.cfunction, self.mass, hermite_str, def_width)
        if vals_provided:
            par_names = ["FSECoeff"]
            for i, coeff in enumerate(self.hermite_co):
                if coeff > 0:
                    par_names.append("C_{0}".format(2 * i))
            for par_name in par_names:
                fitting_str += ",{0}={1:f}".format(
                    par_name, param_vals[param_prefix + par_name])
        else:
            if self.fsecoeff is not None:
                fitting_str += "FSECoeff={0}".format(self.fsecoeff)
            if self.hermite_coeff_vals is not None:
                for i, coeff in list(self.hermite_coeff_vals.items()):
                    if coeff > 0:
                        fitting_str += ",C_{0}={1:f}".format(i, coeff)

        logger.debug("Gram Charlier profile fit function string: {0}".format(
            fitting_str))
        return fitting_str + ";"
Ejemplo n.º 18
0
def create_from_str(func_str, mass):
    """Try and parse the function string to give the required profile function

        :param func_str: A string of the form 'function=Name,attr1=val1,attr2=val2'
        :param mass: The value of the mass for the profile
    """
    known_types = [GaussianMassProfile, MultivariateGaussianMassProfile, GramCharlierMassProfile]
    logger.debug("Profile factory string: {0}".format(func_str))
    errors = dict()
    for cls in known_types:
        try:
            return cls.from_str(func_str, mass)
        except TypeError as exc:
            errors[str(cls)] = str(exc)

    # if we get here we were unable to parse anything acceptable
    msgs = ["{0}: {1}".format(name, error) for name, error in iteritems(errors)]
    raise ValueError("\n".join(msgs))
Ejemplo n.º 19
0
    def create_fit_function_str(self, param_vals=None, param_prefix=""):
        """Creates a string used by the Fit algorithm for this profile

        :param param_vals: A table of values for the parameters that override those set
        on the object already. Default=None
        :param param_prefix: A string prefix for the parameter as seen by the Mantid Fit algorithm
        """
        vals_provided = (param_vals is not None)

        if vals_provided:
            def_width = param_vals[param_prefix + "Width"]
        else:
            def_width = self.width
            if isinstance(def_width, list):
                def_width = def_width[1]

        def to_space_sep_str(collection):
            _str = ""
            for item in collection:
                _str += " " + str(item)
            return _str.lstrip()
        hermite_str = to_space_sep_str(self.hermite_co)

        fitting_str = "name={0},Mass={1:f},HermiteCoeffs={2},Width={3:f}".format(self.cfunction,
                                                                                 self.mass, hermite_str,
                                                                                 def_width)
        if vals_provided:
            par_names = ["FSECoeff"]
            for i, coeff in enumerate(self.hermite_co):
                if coeff > 0:
                    par_names.append("C_{0}".format(2*i))
            for par_name in par_names:
                fitting_str += ",{0}={1:f}".format(par_name, param_vals[param_prefix + par_name])
        else:
            if self.fsecoeff is not None:
                fitting_str += "FSECoeff={0}".format(self.fsecoeff)
            if self.hermite_coeff_vals is not None:
                for i, coeff in self.hermite_coeff_vals.items():
                    if coeff > 0:
                        fitting_str += ",C_{0}={1:f}".format(i, coeff)

        logger.debug("Gram Charlier profile fit function string: {0}".format(fitting_str))
        return fitting_str + ";"
Ejemplo n.º 20
0
    def save_plots(self, plot_dict, is_project_recovery=False):
        # if argument is none return empty dictionary
        if plot_dict is None:
            return []

        plot_list = []
        for index in plot_dict:
            try:
                plot_list.append(self.get_dict_from_fig(plot_dict[index].canvas.figure))
            except BaseException as e:
                # Catch all errors in here so it can fail silently-ish, if this is happening on all plots make sure you
                # have built your project.
                if isinstance(e, KeyboardInterrupt):
                    raise KeyboardInterrupt

                error_string = "Plot: " + str(index) + " was not saved. Error: " + str(e)
                if not is_project_recovery:
                    logger.warning(error_string)
                else:
                    logger.debug(error_string)
        return plot_list
Ejemplo n.º 21
0
    def get_dict_from_fig(self, fig):
        axes_list = []
        create_list = []
        for ax in fig.axes:
            try:
                create_list.append(ax.creation_args)
                self.figure_creation_args = ax.creation_args
            except AttributeError:
                logger.debug(
                    "Axis had a axis without creation_args - Common with colorfill"
                )
                continue
            axes_list.append(self.get_dict_for_axes(ax))

        fig_dict = {
            "creationArguments": create_list,
            "axes": axes_list,
            "label": fig._label,
            "properties": self.get_dict_from_fig_properties(fig)
        }
        return fig_dict
Ejemplo n.º 22
0
def create_from_str(func_str, mass):
    """Try and parse the function string to give the required profile function

        :param func_str: A string of the form 'function=Name,attr1=val1,attr2=val2'
        :param mass: The value of the mass for the profile
    """
    known_types = [
        GaussianMassProfile, MultivariateGaussianMassProfile,
        GramCharlierMassProfile
    ]
    logger.debug("Profile factory string: {0}".format(func_str))
    errors = dict()
    for cls in known_types:
        try:
            return cls.from_str(func_str, mass)
        except TypeError as exc:
            errors[str(cls)] = str(exc)

    # if we get here we were unable to parse anything acceptable
    msgs = ["{0}: {1}".format(name, error) for name, error in errors.items()]
    raise ValueError("\n".join(msgs))
Ejemplo n.º 23
0
    def PyExec(self):
        from mantid import config, logger
        from IndirectCommon import StartTime, EndTime
        import inelastic_indirect_reducer

        self._setup()

        StartTime('InelasticIndirectReduction')

        # Setup reducer
        reducer = inelastic_indirect_reducer.IndirectReducer()

        reducer.set_rename(True)

        reducer.set_instrument_name(self._instrument)
        reducer.set_parameter_file(self._param_file)
        try:
            reducer.set_output_path(config["defaultsave.directory"])
        except RuntimeError:
            pass # Use default

        for data_file in self._data_files:
            reducer.append_data_file(data_file)

        reducer.set_sum_files(self._sum_files)

        reducer.set_detector_range(int(self._detector_range[0]) - 1, int(self._detector_range[1]) - 1)

        self._use_calib_ws = self._calib_ws_name != ''
        if self._use_calib_ws:
            logger.information('Using calibration workspace: %s' % self._calib_ws_name)
            reducer.set_calibration_workspace(self._calib_ws_name)

        if len(self._background_range) == 2:
            logger.debug('Using background range: ' + str(self._background_range))
            reducer.set_background(float(self._background_range[0]), float(self._background_range[1]))

        # TODO: There should be a better way to do this
        self._use_detailed_balance = self._detailed_balance != -1.0
        if self._use_detailed_balance:
            logger.debug('Using detailed balance: ' + str(self._detailed_balance))
            reducer.set_detailed_balance(self._detailed_balance)

        if self._rebin_string != '':
            logger.debug('Using rebin string: ' + self._rebin_string)
            reducer.set_rebin_string(self._rebin_string)

        self._use_scale_factor = self._scale_factor != 1.0
        if self._use_scale_factor:
            logger.debug('Using scale factor: ' + str(self._scale_factor))
            reducer.set_scale_factor(self._scale_factor)

        if self._map_file != '':
            logger.debug('Using mapping file: ' + str(self._map_file))
            reducer.set_grouping_policy(self._map_file)

        reducer.set_fold_multiple_frames(self.getProperty('Fold').value)
        reducer.set_save_to_cm_1(self.getProperty('SaveCM1').value)
        reducer.set_save_formats(self._save_formats)

        # Do reduction and get result workspaces
        reducer.reduce()
        ws_list = reducer.get_result_workspaces()

        self._plot_ws = ws_list[0]

        if len(ws_list) < 1:
            logger.error('Failed to complete reduction')
            return

        # Add sample logs to output workspace(s)
        for workspace in ws_list:
            self._add_ws_logs(workspace)

        # Group output workspaces
        GroupWorkspaces(InputWorkspaces=ws_list, OutputWorkspace=self._out_ws_group)
        self.setProperty('OutputWorkspace', self._out_ws_group)

        # Do plotting
        if self._plot_type != 'none':
            self._plot()

        EndTime('InelasticIndirectReduction')
Ejemplo n.º 24
0
def load_files(data_files, ipf_filename, spec_min, spec_max, sum_files=False, load_logs=True, load_opts=None):
    """
    Loads a set of files and extracts just the spectra we care about (i.e. detector range and monitor).

    @param data_files List of data file names
    @param ipf_filename FIle path/name for the instrument parameter file to load
    @param spec_min Minimum spectra ID to load
    @param spec_max Maximum spectra ID to load
    @param sum_files Sum loaded files
    @param load_logs Load log files when loading runs
    @param load_opts Additional options to be passed to load algorithm

    @return List of loaded workspace names and flag indicating chopped data
    """
    from mantid.simpleapi import (Load, LoadVesuvio, LoadParameterFile,
                                  ChopData, ExtractSingleSpectrum,
                                  CropWorkspace)

    if load_opts is None:
        load_opts = {}

    workspace_names = []

    for filename in data_files:
        # The filename without path and extension will be the workspace name
        ws_name = os.path.splitext(os.path.basename(filename))[0]
        logger.debug('Loading file %s as workspace %s' % (filename, ws_name))

        if 'VESUVIO' in ipf_filename:
            evs_filename = os.path.basename(filename).replace('EVS', '')
            LoadVesuvio(Filename=evs_filename,
                        OutputWorkspace=ws_name,
                        SpectrumList='1-198',
                        **load_opts)
        else:
            Load(Filename=filename,
                 OutputWorkspace=ws_name,
                 LoadLogFiles=load_logs,
                 **load_opts)

        # Load the instrument parameters
        LoadParameterFile(Workspace=ws_name,
                          Filename=ipf_filename)

        # Add the workspace to the list of workspaces
        workspace_names.append(ws_name)

        # Get the spectrum number for the monitor
        instrument = mtd[ws_name].getInstrument()
        monitor_index = int(instrument.getNumberParameter('Workflow.Monitor1-SpectrumNumber')[0])
        logger.debug('Workspace %s monitor 1 spectrum number :%d' % (ws_name, monitor_index))

        # Chop data if required
        try:
            chop_threshold = mtd[ws_name].getInstrument().getNumberParameter('Workflow.ChopDataIfGreaterThan')[0]
            x_max = mtd[ws_name].readX(0)[-1]
            chopped_data =  x_max > chop_threshold
        except IndexError:
            chopped_data = False
        logger.information('Workspace %s need data chop: %s' % (ws_name, str(chopped_data)))

        workspaces = [ws_name]
        if chopped_data:
            ChopData(InputWorkspace=ws_name,
                     OutputWorkspace=ws_name,
                     MonitorWorkspaceIndex=monitor_index,
                     IntegrationRangeLower=5000.0,
                     IntegrationRangeUpper=10000.0,
                     NChops=5)
            workspaces = mtd[ws_name].getNames()

        for chop_ws_name in workspaces:
            # Get the monitor spectrum
            monitor_ws_name = chop_ws_name + '_mon'
            ExtractSingleSpectrum(InputWorkspace=chop_ws_name,
                                  OutputWorkspace=monitor_ws_name,
                                  WorkspaceIndex=monitor_index)

            # Crop to the detectors required
            CropWorkspace(InputWorkspace=chop_ws_name, OutputWorkspace=chop_ws_name,
                          StartWorkspaceIndex=int(spec_min) - 1,
                          EndWorkspaceIndex=int(spec_max) - 1)

    logger.information('Loaded workspace names: %s' % (str(workspace_names)))
    logger.information('Chopped data: %s' % (str(chopped_data)))

    # Sum files if needed
    if sum_files:
        if chopped_data:
            workspace_names = sum_chopped_runs(workspace_names)
        else:
            workspace_names = sum_regular_runs(workspace_names)

    logger.information('Summed workspace names: %s' % (str(workspace_names)))

    return workspace_names, chopped_data
Ejemplo n.º 25
0
                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?

# Required to have Mantid recognize the new function
#pylint: disable=unused-import
try:
    import dsfinterp
    FunctionFactory.subscribe(DSFinterp1DFit)
except ImportError:
    logger.debug('Failed to subscribe fit function DSFinterp1DFit. '+\
                 'Python package dsfinterp may be missing (https://pypi.python.org/pypi/dsfinterp)')
def load_files(data_files, ipf_filename, spec_min, spec_max, sum_files=False, load_logs=True, load_opts=None):
    """
    Loads a set of files and extracts just the spectra we care about (i.e. detector range and monitor).

    @param data_files List of data file names
    @param ipf_filename File path/name for the instrument parameter file to load
    @param spec_min Minimum spectra ID to load
    @param spec_max Maximum spectra ID to load
    @param sum_files Sum loaded files
    @param load_logs Load log files when loading runs
    @param load_opts Additional options to be passed to load algorithm

    @return List of loaded workspace names and flag indicating chopped data
    """
    from mantid.simpleapi import (Load, LoadVesuvio, LoadParameterFile,
                                  ChopData, ExtractSingleSpectrum,
                                  CropWorkspace)

    if load_opts is None:
        load_opts = {}

    workspace_names = []

    for filename in data_files:
        # The filename without path and extension will be the workspace name
        ws_name = os.path.splitext(os.path.basename(str(filename)))[0]
        logger.debug('Loading file %s as workspace %s' % (filename, ws_name))

        if 'VESUVIO' in ipf_filename:
            # Load all spectra. They are cropped later
            LoadVesuvio(Filename=str(filename),
                        OutputWorkspace=ws_name,
                        SpectrumList='1-198',
                        **load_opts)
        else:
            Load(Filename=filename,
                 OutputWorkspace=ws_name,
                 LoadLogFiles=load_logs,
                 **load_opts)

        # Load the instrument parameters
        LoadParameterFile(Workspace=ws_name,
                          Filename=ipf_filename)

        # Add the workspace to the list of workspaces
        workspace_names.append(ws_name)

        # Get the spectrum number for the monitor
        instrument = mtd[ws_name].getInstrument()
        monitor_index = int(instrument.getNumberParameter('Workflow.Monitor1-SpectrumNumber')[0])
        logger.debug('Workspace %s monitor 1 spectrum number :%d' % (ws_name, monitor_index))

        # Chop data if required
        try:
            chop_threshold = mtd[ws_name].getInstrument().getNumberParameter('Workflow.ChopDataIfGreaterThan')[0]
            x_max = mtd[ws_name].readX(0)[-1]
            chopped_data = x_max > chop_threshold
        except IndexError:
            chopped_data = False
        logger.information('Workspace {0} need data chop: {1}'.format(ws_name, str(chopped_data)))

        workspaces = [ws_name]
        if chopped_data:
            ChopData(InputWorkspace=ws_name,
                     OutputWorkspace=ws_name,
                     MonitorWorkspaceIndex=monitor_index,
                     IntegrationRangeLower=5000.0,
                     IntegrationRangeUpper=10000.0,
                     NChops=5)
            workspaces = mtd[ws_name].getNames()

        for chop_ws_name in workspaces:
            # Get the monitor spectrum
            monitor_ws_name = chop_ws_name + '_mon'
            ExtractSingleSpectrum(InputWorkspace=chop_ws_name,
                                  OutputWorkspace=monitor_ws_name,
                                  WorkspaceIndex=monitor_index)

            # Crop to the detectors required
            chop_ws = mtd[chop_ws_name]
            CropWorkspace(InputWorkspace=chop_ws_name,
                          OutputWorkspace=chop_ws_name,
                          StartWorkspaceIndex=chop_ws.getIndexFromSpectrumNumber(int(spec_min)),
                          EndWorkspaceIndex=chop_ws.getIndexFromSpectrumNumber(int(spec_max)))

    logger.information('Loaded workspace names: %s' % (str(workspace_names)))
    logger.information('Chopped data: %s' % (str(chopped_data)))

    # Sum files if needed
    if sum_files and len(data_files) > 1:
        if chopped_data:
            workspace_names = sum_chopped_runs(workspace_names)
        else:
            workspace_names = sum_regular_runs(workspace_names)

    logger.information('Summed workspace names: %s' % (str(workspace_names)))

    return workspace_names, chopped_data
Ejemplo n.º 27
0
            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?


# Required to have Mantid recognize the new function
#pylint: disable=unused-import
try:
    import dsfinterp  # noqa
    FunctionFactory.subscribe(DSFinterp1DFit)
except ImportError:
    logger.debug(
        'Failed to subscribe fit function DSFinterp1DFit. ' +
        'Python package dsfinterp may be missing (https://pypi.python.org/pypi/dsfinterp)'
    )