Exemple #1
0
    def _report_progress(msg: str,
                         reporter: Union[None, Progress] = None,
                         notice: bool = False) -> None:
        """
        :param msg:  message to print out
        :param reporter:  Progress object for visual feedback in Workbench
        :param notice:  Log at "notice" level (i.e. visible by default)

        """
        # In order to avoid
        #
        # RuntimeError: Pickling of "mantid.kernel._kernel.Logger"
        # instances is not enabled (http://www.boost.org/libs/python/doc/v2/pickle.html)
        #
        # logger has to be imported locally

        from mantid.kernel import logger

        if reporter:
            reporter.report(msg)

        if notice:
            logger.notice(msg)
        else:
            logger.information(msg)
Exemple #2
0
    def PyExec(self):
        self._setup()

        self._calculate_parameters()

        if not self._dry_run:
            self._fury()

            self._add_logs()

            if self._save:
                workdir = config['defaultsave.directory']
                opath = os.path.join(workdir, self._output_workspace + '.nxs')
                SaveNexusProcessed(InputWorkspace=self._output_workspace,
                                   Filename=opath)
                if self._verbose:
                    logger.notice('Output file : ' + opath)

            if self._plot:
                self._plot_output()
        else:
            if self._verbose:
                logger.notice('Dry run, will not run Fury')

        self.setProperty('ParameterWorkspace', self._parameter_table)
        self.setProperty('OutputWorkspace', self._output_workspace)
 def run_algorithm(self,
                   name: str,
                   start_progress: float,
                   end_progress: float,
                   soft_crash=True,
                   **kwargs):
     r"""
     @param soft_crash : log an error but do not raise an exception
     """
     algorithm_align = self.createChildAlgorithm(
         name=name,
         startProgress=start_progress,
         endProgress=end_progress,
         enableLogging=True)
     [
         algorithm_align.setProperty(name, value)
         for name, value in kwargs.items()
     ]
     try:
         algorithm_align.execute()
     except Exception as err:
         if soft_crash is True:
             logger.error('Execution continues')
         else:
             raise err.__class__(err)
     logger.notice(f'{name} has executed')
    def live_monitor(self, input_ws, output_ws):
        """

        :return:
        """
        # Now get the data, read the first spectra
        spectra = input_ws.readY(0)
        # extract the first value from the array
        count = spectra[0]
        print(f'Total count: {count}')

        count = input_ws.getNumberEvents()

        # output it as a log message
        logger.notice("Total counts so far " + str(count))

        # if my ouput workspace has not been created yet, create it.
        if not mtd.doesExist(output_ws):
            table = CreateEmptyTableWorkspace(OutputWorkspace=output_ws)
            table.setTitle("Event Rate History")
            table.addColumn("str", "Time")
            table.addColumn('str', 'EventsS')
            table.addColumn("int", "Events")

        table = mtd[output_ws]
        assert table
    def action_show_in_explorer(self):
        widget = self.view.widget(self.view.last_tab_clicked)
        if not widget:
            # the widget has been deleted without updating the last tab clicked
            return

        filepath = widget.editor.fileName()
        if "" != filepath:
            ShowInExplorer.open_directory(os.path.dirname(filepath))
        else:
            logger.notice("Selected tab is not saved to a file, and cannot be shown in explorer.")
    def _report_progress(self, msg):
        """
        :param msg:  message to print out
        """
        # In order to avoid
        #
        # RuntimeError: Pickling of "mantid.kernel._kernel.Logger"
        # instances is not enabled (http://www.boost.org/libs/python/doc/v2/pickle.html)
        #
        # logger has to be imported locally

        from mantid.kernel import logger
        logger.notice(msg)
    def action_show_in_explorer(self):
        widget = self.view.widget(self.view.last_tab_clicked)
        if not widget:
            # the widget has been deleted without updating the last tab clicked
            return

        filepath = widget.editor.fileName()
        if "" != filepath:
            ShowInExplorer.open_directory(os.path.dirname(filepath))
        else:
            logger.notice(
                "Selected tab is not saved to a file, and cannot be shown in explorer."
            )
Exemple #8
0
    def _report_progress(self, msg):
        """
        :param msg:  message to print out
        """
        # In order to avoid
        #
        # RuntimeError: Pickling of "mantid.kernel._kernel.Logger"
        # instances is not enabled (http://www.boost.org/libs/python/doc/v2/pickle.html)
        #
        # logger has to be imported locally

        from mantid.kernel import logger
        logger.notice(msg)
Exemple #9
0
    def _logSuccessExport(self, wsName):
        """
        Log all the successful exports.

        Args:
            wsName (str): name of the concerned workspace
        """
        if wsName not in self._successExports:
            return
        filenames = ", ".join(self._successExports[wsName])
        logger.notice("Successful export of workspace {} to {}"
                      .format(wsName, filenames))
        del self._successExports[wsName]
Exemple #10
0
    def read_vibrational_or_phonon_data(self):
        """
        Reads vibrational or phonon data from CRYSTAL output files. Saves frequencies, weights of k-point vectors,
        k-point vectors, amplitudes of atomic displacements, hash of the vibrational or phonon data file (hash) to
        <>.hdf5.
        :return  object of type AbinsData.
        """

        # determine system (molecule or crystal?)
        system = self._determine_system()

        # check if one or more k-points to parse
        phonon_dispersion = self._determine_dispersion()

        # read data from output CRYSTAL file
        filename = self._clerk.get_input_filename()
        with io.open(filename, "rb") as crystal_file:
            logger.notice("Reading from " + filename)

            if system is AbinsModules.AbinsConstants.CRYSTAL:
                lattice_vectors = self._read_lattice_vectors(
                    file_obj=crystal_file)
            else:
                lattice_vectors = [[0, 0, 0]] * 3

            coord_lines = self._read_atomic_coordinates(file_obj=crystal_file)
            masses = self._read_masses_from_file(file_obj=crystal_file)

            freq, coordinates, weights, k_coordinates = self._read_modes(
                file_obj=crystal_file, phonon_dispersion=phonon_dispersion)

        # put data into Abins data structure
        data = {}
        self._create_atoms_data(data=data,
                                coord_lines=coord_lines[:self._num_atoms],
                                atoms_masses=masses[:self._num_atoms])
        self._create_kpoints_data(
            data=data,
            freq=freq,
            atomic_displacements=coordinates,
            atomic_coordinates=coord_lines[:self._num_atoms],
            weights=weights,
            k_coordinates=k_coordinates,
            unit_cell=lattice_vectors)

        # save data to hdf file
        self.save_ab_initio_data(data=data)

        # return AbinsData object
        return self._rearrange_data(data=data)
Exemple #11
0
def polCorr(polcorr, IvsLam, crho, calpha, cAp, cPp):
    '''
    Perform polynomial correction
    '''
    # Treat False like a polarization correction of None.
    if polcorr == PolarisationCorrection.PNR:
        IvsLam = nrPNRCorrection(IvsLam.name(), crho[0],calpha[0],cAp[0],cPp[0])
    elif polcorr == PolarisationCorrection.PA:
        IvsLam = nrPACorrection(IvsLam.name(), crho[0],calpha[0],cAp[0],cPp[0])
    else:
        message = "No Polarisation Correction Requested."
        logger.notice(message)
        print message
    return IvsLam
Exemple #12
0
def _normalize_one_spectrum(single_spectrum_ws, spline, instrument):
    rebinned_spline = mantid.RebinToWorkspace(
        WorkspaceToRebin=spline,
        WorkspaceToMatch=single_spectrum_ws,
        StoreInADS=False)
    divided = mantid.Divide(LHSWorkspace=single_spectrum_ws,
                            RHSWorkspace=rebinned_spline,
                            StoreInADS=False)
    if instrument.get_instrument_prefix() == "GEM":
        values_replaced = mantid.ReplaceSpecialValues(InputWorkspace=divided,
                                                      NaNValue=0,
                                                      StoreInADS=False)
        # crop based off max between 1000 and 2000 tof as the vanadium peak on Gem will always occur here
        complete = _crop_spline_to_percent_of_max(rebinned_spline,
                                                  values_replaced,
                                                  single_spectrum_ws, 1000,
                                                  2000)
    else:
        complete = mantid.ReplaceSpecialValues(
            InputWorkspace=divided,
            NaNValue=0,
            OutputWorkspace=single_spectrum_ws)

    if instrument.perform_abs_vanadium_norm():
        vanadium_material = spline.sample().getMaterial()
        v_number_density = vanadium_material.numberDensityEffective
        v_cross_section = vanadium_material.totalScatterXSection()
        vanadium_shape = spline.sample().getShape()
        # number density in Angstroms-3, volume in m3. Don't bother with 1E30 factor because will cancel
        num_v_atoms = vanadium_shape.volume() * v_number_density

        sample_material = single_spectrum_ws.sample().getMaterial()
        sample_number_density = sample_material.numberDensityEffective
        sample_shape = spline.sample().getShape()
        num_sample_atoms = sample_shape.volume() * sample_number_density

        abs_norm_factor = v_cross_section * num_v_atoms / \
                          (num_sample_atoms * 4 * math.pi)
        logger.notice(
            "Performing absolute normalisation, multiplying by factor=" +
            str(abs_norm_factor))
        # avoid "Variable invalidated, data has been deleted" error when debugging
        output_ws_name = single_spectrum_ws.name()
        abs_norm_factor_ws = mantid.CreateSingleValuedWorkspace(
            DataValue=abs_norm_factor, OutputWorkspace="__abs_norm_factor_ws")
        complete = mantid.Multiply(LHSWorkspace=complete,
                                   RHSWorkspace=abs_norm_factor_ws,
                                   OutputWorkspace=output_ws_name)

    return complete
Exemple #13
0
def polCorr(polcorr, IvsLam, crho, calpha, cAp, cPp):
    '''
    Perform polynomial correction
    '''
    # Treat False like a polarization correction of None.
    if polcorr == PolarisationCorrection.PNR:
        IvsLam = nrPNRCorrection(IvsLam.name(), crho[0],calpha[0],cAp[0],cPp[0])
    elif polcorr == PolarisationCorrection.PA:
        IvsLam = nrPACorrection(IvsLam.name(), crho[0],calpha[0],cAp[0],cPp[0])
    else:
        message = "No Polarisation Correction Requested."
        logger.notice(message)
        print message
    return IvsLam
Exemple #14
0
    def create_output_files(self, calibration_dir, difa, difc, tzero, sample_path, vanadium_path,
                            instrument, bank, spectrum_numbers):
        """
        Create output files from the algorithms in the specified directory
        :param calibration_dir: The directory to save the files into.
        :param difa: DIFA values from calibration algorithm
        :param difc: DIFC values from the calibration algorithm.
        :param tzero: TZERO values from the calibration algorithm.
        :param sample_path: The path to the sample data file.
        :param vanadium_path: The path to the vanadium data file.
        :param instrument: The instrument (ENGINX or IMAT)
        :param bank: Optional parameter to crop by bank
        :param spectrum_numbers: Optional parameter to crop using spectrum numbers.
        """
        kwargs = {"ceria_run": path_handling.get_run_number_from_path(sample_path, instrument),
                  "vanadium_run": path_handling.get_run_number_from_path(vanadium_path, instrument)}

        def south_kwargs():
            kwargs["template_file"] = SOUTH_BANK_TEMPLATE_FILE
            kwargs["bank_names"] = ["South"]

        def north_kwargs():
            kwargs["template_file"] = NORTH_BANK_TEMPLATE_FILE
            kwargs["bank_names"] = ["North"]

        def generate_output_file(difa_list, difc_list, tzero_list, bank_name, kwargs_to_pass):
            file_path = calibration_dir + self._generate_output_file_name(vanadium_path, sample_path, instrument,
                                                                          bank=bank_name)
            write_ENGINX_GSAS_iparam_file(file_path, difa_list, difc_list, tzero_list, **kwargs_to_pass)

        if not path.exists(calibration_dir):
            makedirs(calibration_dir)

        if bank is None and spectrum_numbers is None:
            generate_output_file(difa, difc, tzero, "all", kwargs)
            north_kwargs()
            generate_output_file([difa[0]], [difc[0]], [tzero[0]], "north", kwargs)
            south_kwargs()
            generate_output_file([difa[1]], [difc[1]], [tzero[1]], "south", kwargs)
        elif bank == "1":
            north_kwargs()
            generate_output_file([difa[0]], [difc[0]], [tzero[0]], "north", kwargs)
        elif bank == "2":
            south_kwargs()
            generate_output_file([difa[0]], [difc[0]], [tzero[0]], "south", kwargs)
        elif bank is None:  # Custom cropped files use the north bank template.
            north_kwargs()
            generate_output_file([difa[0]], [difc[0]], [tzero[0]], "cropped", kwargs)
        logger.notice(f"\n\nCalibration files saved to: \"{calibration_dir}\"\n\n")
Exemple #15
0
 def _create_and_save_configuration(self):
     logger.notice('Reduction will not be carried out')
     #
     # configuration file name and save location
     #
     basename = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
     dir_name = self.getProperty('ConfigSaveDir').value
     if len(dir_name) <= 0:  # default directory
         run_number = self.getProperty('RunNumbers').value[
             0]  # first run number
         dir_name = Path(self.get_IPTS_Local(
             run_number)) / 'shared' / 'autoreduce' / 'configurations'
         dir_name.mkdir(
             parents=True,
             exist_ok=True)  # in case it has not yet been created
     filename = str(Path(dir_name) / f'{basename}.json')
     #
     # Selected algorithm properties as a dictionary
     #
     dict_repr = json.loads(str(self)).get(
         'properties'
     )  # representation of the algorithm's properties in a dict
     # Remove not wanted properties
     for not_wanted in ('RunNumbers', 'OutputDirectory',
                        'EnableConfigurator', 'ConfigSaveDir'):
         if not_wanted in dict_repr:
             del dict_repr[not_wanted]
     """
     hack to fix the entry for the default JSON represenation of property DetCalFilename, which is saved as a list of lists
     Example: "DetCalFilename": [ ["/SNS/SNAP/IPTS-26217/shared/E76p2_W65p3.detcal"],
                                  ["/SNS/SNAP/IPTS-26217/shared/E76p2_W65p5.detcal"]]
              must become:
              "DetCalFilename": "/SNS/SNAP/IPTS-26217/shared/E76p2_W65p3.detcal,/SNS/SNAP/IPTS-26217/shared/E76p2_W65p5.detcal"
     """
     if 'DetCalFilename' in dict_repr:
         dict_repr['DetCalFilename'] = ','.join(
             [entry[0] for entry in dict_repr.get('DetCalFilename')])
     #
     # Save to file in JSON format
     #
     formatted_pretty = json.dumps(dict_repr, sort_keys=True, indent=4)
     with open(filename, 'w') as f:
         f.write(formatted_pretty)
         logger.information(f'Saving configuration to {filename}')
         logger.debug(f'Configuration contents:\n{formatted_pretty}')
    def PyExec(self):
        """ Main execution body
        """
        #get parameters
        w = self.getProperty("Workspace").value
        logNames = self.getProperty("LogNames").value
        resultString = ''
        #check for parameters and build the result string
        for value in logNames.split(','):
            value = value.strip()
            if len(value) > 0:
                if not w.run().hasProperty(value):
                    resultString += 'Property ' + value + ' not found\n'

        #return the result
        logger.notice(resultString)
        self.setProperty("Result", resultString)
        return
Exemple #17
0
 def open_directory(path):
     try:
         if sys.platform == "win32":
             os.startfile(path)
         elif sys.platform == 'darwin':
             subprocess.check_call(['open', '--', path])
         elif sys.platform == 'linux2':
             call_params = ['xdg-open', path]
             subprocess.check_call(call_params)
     except Exception as ex:
         # it is hard to narrow down the type of exception, as too many things can go wrong:
         # - subprocess.CalledProcessError if the process has an error
         # - OSError if the command cannot be found (on Linux)
         # - WindowsError is the directory does not exist
         # However, catching this general exception makes sure that there will not be a crash
         # regardless of what the error is
         logger.notice("Could not open the folder in explorer.")
         logger.debug("Error encountered: {}".format(ex))
    def PyExec(self):
        """ Main execution body
        """
	#get parameters
	w = self.getProperty("Workspace").value
	logNames = self.getProperty("LogNames").value
	resultString=''
	#check for parameters and build the result string
	for value in logNames.split(','):
		value=value.strip()
		if len(value)>0:
			if not w.run().hasProperty(value):
				resultString+='Property '+value+' not found\n'
	
	#return the result
	logger.notice(resultString)
	self.setProperty("Result",resultString)
        return 
Exemple #19
0
def euphonic_calculate_modes(filename: str, cutoff: float = 20.,
                             gamma: bool = True,
                             acoustic_sum_rule: Optional[str] = 'reciprocal'):
    """
    Read force constants file with Euphonic and sample frequencies/modes

    :param filename: Input data
    :param cutoff:
        Sampling density of Brillouin-zone. Specified as real-space length
        cutoff in Angstrom.
    :param gamma:
        Shift sampling grid to include the Gamma-point.
    :param acoustic_sum_rule:
        Apply acoustic sum rule correction to force constants: options are
        'realspace' and 'reciprocal', specifying different implementations of
        the correction. If None, no correction is applied. This option is
        referred to as "asr" in the Euphonic python API and command-line tools.

    :returns: euphonic.QpointPhononModes

    """

    from math import ceil
    from euphonic.cli.utils import force_constants_from_file
    from euphonic.util import mp_grid

    fc = force_constants_from_file(filename)
    recip_lattice_lengths = np.linalg.norm(
        fc.crystal.reciprocal_cell().to('1/angstrom').magnitude, axis=1)
    mp_sampling = [ceil(x)
                   for x in (cutoff * recip_lattice_lengths / (2 * np.pi))]
    qpts = mp_grid(mp_sampling)

    if gamma:
        mp_sampling = np.array(mp_sampling, dtype=int)
        # Shift directions with even number of samples by half the grid spacing
        offsets = ((mp_sampling + 1) % 2) * (0.5 / mp_sampling)
        qpts += offsets

    logger.notice('Calculating phonon modes on {} grid'.format(
        'x'.join(map(str, mp_sampling))))
    modes = fc.calculate_qpoint_phonon_modes(qpts, asr=acoustic_sum_rule)

    return modes
Exemple #20
0
    def read_vibrational_or_phonon_data(self):
        """
        Reads vibrational or phonon data from CRYSTAL output files. Saves frequencies, weights of k-point vectors,
        k-point vectors, amplitudes of atomic displacements, hash of the vibrational or phonon data file (hash) to
        <>.hdf5.
        :return  object of type AbinsData.
        """

        # determine system (molecule or crystal?)
        system = self._determine_system()

        # check if one or more k-points to parse
        phonon_dispersion = self._determine_dispersion()

        # read data from output CRYSTAL file
        filename = self._clerk.get_input_filename()
        with io.open(filename, "rb") as crystal_file:
            logger.notice("Reading from " + filename)

            if system is AbinsModules.AbinsConstants.CRYSTAL:
                lattice_vectors = self._read_lattice_vectors(file_obj=crystal_file)
            else:
                lattice_vectors = [[0, 0, 0]] * 3

            coord_lines = self._read_atomic_coordinates(file_obj=crystal_file)
            masses = self._read_masses_from_file(file_obj=crystal_file)

            freq, coordinates, weights, k_coordinates = self._read_modes(file_obj=crystal_file,
                                                                         phonon_dispersion=phonon_dispersion)

        # put data into Abins data structure
        data = {}
        self._create_atoms_data(data=data, coord_lines=coord_lines[:self._num_atoms],
                                atoms_masses=masses[:self._num_atoms])
        self._create_kpoints_data(data=data, freq=freq, atomic_displacements=coordinates,
                                  atomic_coordinates=coord_lines[:self._num_atoms], weights=weights,
                                  k_coordinates=k_coordinates, unit_cell=lattice_vectors)

        # save data to hdf file
        self.save_ab_initio_data(data=data)

        # return AbinsData object
        return self._rearrange_data(data=data)
Exemple #21
0
def get_bank_grouping_workspace(bank: int, sample_raw):  # -> GroupingWorkspace
    """
    Retrieve the grouping workspace for the North/South bank from the user directories, or create a new one from the
    sample workspace instrument data if not found
    :param bank: integer denoting the bank, 1 or 2 for North/South respectively
    :param sample_raw: Workspace containing the instrument data that can be used to create a new grouping workspace
    :return: The loaded or created grouping workspace
    """
    if bank == 1:
        try:
            if ADS.doesExist("NorthBank_grouping"):
                return ADS.retrieve("NorthBank_grouping")
            grp_ws = mantid.LoadDetectorsGroupingFile(
                InputFile="ENGINX_North_grouping.xml",
                OutputWorkspace="NorthBank_grouping")
            return grp_ws
        except ValueError:
            logger.notice(
                "NorthBank grouping file not found in user directories - creating one"
            )
        bank_name = "NorthBank"
    elif bank == 2:
        try:
            if ADS.doesExist("SouthBank_grouping"):
                return ADS.retrieve("SouthBank_grouping")
            grp_ws = mantid.LoadDetectorsGroupingFile(
                InputFile="ENGINX_South_grouping.xml",
                OutputWorkspace="SouthBank_grouping")
            return grp_ws
        except ValueError:
            logger.notice(
                "SouthBank grouping file not found in user directories - creating one"
            )
        bank_name = "SouthBank"
    else:
        raise ValueError("Invalid bank number given")
    ws_name = bank_name + "_grouping"
    grp_ws, _, _ = mantid.CreateGroupingWorkspace(InputWorkspace=sample_raw,
                                                  GroupNames=bank_name,
                                                  OutputWorkspace=ws_name)
    return grp_ws
Exemple #22
0
    def _determine_system(self):
        """
        Determines whether the system is a molecule or a crystal.
        :returns: True if calculation for molecule otherwise False
        """
        with io.open(self._clerk.get_input_filename(), "rb") as crystal_file:
            lines = crystal_file.read()

        if b"MOLECULAR CALCULATION" in lines or b"0D - MOLECULE" in lines:
            molecular = True
        elif b"CRYSTAL CALCULATION" in lines or b"3D - CRYSTAL" in lines:
            molecular = False
        else:
            raise ValueError("Only molecular or 3D CRYSTAL systems can be processed")

        if molecular:
            logger.notice("This run is for a MOLECULAR system")
        else:
            logger.notice("This run is for a 3D CRYSTAL system")

        return molecular
    def _determine_system(self):
        """
        Determines whether the system is a molecule or a crystal.
        :returns: True if calculation for molecule otherwise False
        """
        with io.open(self._clerk.get_input_filename(), "rb") as crystal_file:
            lines = crystal_file.read()

        if b"MOLECULAR CALCULATION" in lines or b"0D - MOLECULE" in lines:
            molecular = True
        elif b"CRYSTAL CALCULATION" in lines or b"3D - CRYSTAL" in lines:
            molecular = False
        else:
            raise ValueError("Only molecular or 3D CRYSTAL systems can be processed")

        if molecular:
            logger.notice("This run is for a MOLECULAR system")
        else:
            logger.notice("This run is for a 3D CRYSTAL system")

        return molecular
Exemple #24
0
def create_output_files(calibration_dir, calibration, ws_foc):
    """
    Create output files (.prm for GSAS and .nxs of calibration table) from the algorithms in the specified directory
    :param calibration_dir: The directory to save the files into.
    :param calibration: CalibrationInfo object with details of calibration and grouping
    :param ws_foc: focused ceria workspace
    """
    # create calibration dir of not exist
    if not path.exists(calibration_dir):
        makedirs(calibration_dir)

    # save grouping ws if custom or cropped
    if not calibration.group.banks:
        calibration.save_grouping_workspace(calibration_dir)

    # save prm file(s)
    prm_filepath = path.join(calibration_dir,
                             calibration.generate_output_file_name())
    write_prm_file(ws_foc, prm_filepath)
    calibration.set_prm_filepath(prm_filepath)
    # save pdcal output as nexus
    filepath, ext = path.splitext(prm_filepath)
    nxs_filepath = filepath + '.nxs'
    mantid.SaveNexus(InputWorkspace=calibration.get_calibration_table(),
                     Filename=nxs_filepath)

    # if both banks calibrated save individual banks separately as well
    if calibration.group == GROUP.BOTH:
        # output a separate prm for North and South when both banks included
        for ibank, bank in enumerate(calibration.group.banks):
            # get prm filename for individual banks by passing group enum as argument to generate_output_file_name
            prm_filepath_bank = path.join(
                calibration_dir,
                calibration.generate_output_file_name(GROUP(str(ibank + 1))))
            write_prm_file(ws_foc, prm_filepath_bank, spec_nums=[ibank])
            # copy pdcal output nxs for both banks
            filepath, ext = path.splitext(prm_filepath_bank)
            nxs_filepath_bank = filepath + '.nxs'
            copy2(nxs_filepath, nxs_filepath_bank)
    logger.notice(f"\n\nCalibration files saved to: \"{calibration_dir}\"\n\n")
Exemple #25
0
    def get_formatted_data(self):

        # try to load DFT data from *.hdf5 file
        try:
            if self._dft_program != self._clerk.get_previous_dft_program():
                raise ValueError(
                    "Different DFT program was used in the previous calculation. Data in the hdf file "
                    "will be erased.")

            self._clerk.check_previous_data()

            dft_data = self.load_formatted_data()
            logger.notice(
                str(dft_data) + " has been loaded from the HDF file.")

        # if loading from *.hdf5 file failed than read data directly from input DFT file and erase hdf file
        except (IOError, ValueError) as err:

            logger.notice(str(err))
            self._clerk.erase_hdf_file()
            dft_data = self.read_phonon_file()
            logger.notice(
                str(dft_data) + " from DFT input file has been loaded.")

        return dft_data
    def get_formatted_data(self):

        # try to load ab initio data from *.hdf5 file
        try:
            if self._ab_initio_program != self._clerk.get_previous_ab_initio_program(
            ):
                raise ValueError(
                    "Different ab initio program was used in the previous calculation. Data in the hdf "
                    "file will be erased.")

            self._clerk.check_previous_data()

            ab_initio_data = self.load_formatted_data()
            logger.notice(
                str(ab_initio_data) + " has been loaded from the HDF file.")

        # if loading from *.hdf5 file failed than read data directly from input ab initio file and erase hdf file
        except (IOError, ValueError) as err:

            logger.notice(str(err))
            self._clerk.erase_hdf_file()
            ab_initio_data = self.read_vibrational_or_phonon_data()
            logger.notice(
                str(ab_initio_data) +
                " from ab initio input file has been loaded.")

        return ab_initio_data
Exemple #27
0
 def create_bank_grouping_workspace(self):
     """
     Create grouping workspace for ROI corresponding to one or more banks
     """
     ws_name = GROUP_WS_NAMES[self.group]
     grp_ws = None
     try:
         grp_ws = LoadDetectorsGroupingFile(InputFile=path.join(
             CALIB_DIR, GROUP_FILES[self.group]),
                                            OutputWorkspace=ws_name)
     except ValueError:
         logger.notice(
             "Grouping file not found in user directories - creating one")
         if self.group.banks and self.group != GROUP.TEXTURE20 and self.group != GROUP.TEXTURE30:
             grp_ws, _, _ = CreateGroupingWorkspace(
                 InstrumentName=self.instrument,
                 OutputWorkspace=ws_name,
                 GroupNames=GROUP_BANK_ARGS[self.group])
     if grp_ws:
         self.group_ws = grp_ws
     else:
         raise ValueError(
             "Could not find or create grouping requested - make sure the directory of the grouping.xml"
             " files is on the path")
Exemple #28
0
def load_bank_table(bank_id: int,
                    database_path: str,
                    date: str,
                    table_type: str = 'calibration') -> TableWorkspace:
    """
    Function that loads the latest bank calibrated TableWorkspace from a single HDF5 file
    using corelli format:
    database_path/bank0ID/type_corelli_bank0ID_YYYYMMDD.nxs
    :param bank_id bank number that is calibrated
    :param database_path location of the corelli database (absolute or relative)
           Example: database/corelli/ for
                    database/corelli/bank001/
                    database/corelli/bank002/
    :param date current day in YYYYMMDD format
    :param table_type 'calibration', 'mask' or 'fit'
    :return TableWorkspace with corresponding data
    """
    TableType.assert_valid_type(table_type)
    verify_date_format('load_bank_table', date)
    filename: str = filename_bank_table(bank_id, database_path, date,
                                        table_type)
    logger.notice(f'Loading bank{bank_id} {table_type} file from database')
    outputWS = LoadNexusProcessed(filename)
    return outputWS
    def get_formatted_data(self):

        # try to load ab initio data from *.hdf5 file
        try:
            self._clerk.check_previous_data()

            ab_initio_data = self.load_formatted_data()
            logger.notice(str(ab_initio_data) + " has been loaded from the HDF file.")

        # if loading from *.hdf5 file failed than read data directly from input ab initio file and erase hdf file
        except (IOError, ValueError) as err:

            logger.notice(str(err))
            self._clerk.erase_hdf_file()
            ab_initio_data = self.read_vibrational_or_phonon_data()
            logger.notice(str(ab_initio_data) + " from ab initio input file has been loaded.")

        return ab_initio_data
    def get_formatted_data(self):

        # try to load ab initio data from *.hdf5 file
        try:
            if self._ab_initio_program != self._clerk.get_previous_ab_initio_program():
                raise ValueError("Different ab initio program was used in the previous calculation. Data in the hdf "
                                 "file will be erased.")

            self._clerk.check_previous_data()

            ab_initio_data = self.load_formatted_data()
            logger.notice(str(ab_initio_data) + " has been loaded from the HDF file.")

        # if loading from *.hdf5 file failed than read data directly from input ab initio file and erase hdf file
        except (IOError, ValueError) as err:

            logger.notice(str(err))
            self._clerk.erase_hdf_file()
            ab_initio_data = self.read_vibrational_or_phonon_data()
            logger.notice(str(ab_initio_data) + " from ab initio input file has been loaded.")

        return ab_initio_data
Exemple #31
0
def make_trans_corr(transrun, stitch_start_overlap, stitch_end_overlap, stitch_params,
                    lambda_min=None, lambda_max=None, background_min=None,
                    background_max=None, int_min=None, int_max=None, detector_index_ranges=None,
                    i0_monitor_index=None):
    '''
    Make the transmission correction workspace.
    '''

    '''
    Check to see whether all optional inputs have been provide. If not we have to get them from the IDF.
    '''
    if not all((lambda_min, lambda_max, background_min, background_max, int_min, int_max, detector_index_ranges, i0_monitor_index)):
        logger.notice("make_trans_corr: Fetching missing arguments from the IDF")
        instrument_source = transrun
        if isinstance(transrun, str):
            instrument_source = transrun.split(',')[0]
        trans_ws = ConvertToWavelength.to_workspace(instrument_source)
        idf_defaults = get_defaults(trans_ws)

        # Fetch defaults for anything not specified
        if not i0_monitor_index:
            i0_monitor_index = idf_defaults['I0MonitorIndex']
        if not lambda_min:
            lambda_min = idf_defaults['LambdaMin']
        if not lambda_max:
            lambda_max = idf_defaults['LambdaMax']
        if not detector_index_ranges:
            point_detector_start = idf_defaults['PointDetectorStart']
            point_detector_stop =  idf_defaults['PointDetectorStop']
            detector_index_ranges = (point_detector_start, point_detector_stop)
        if not background_min:
            background_min = idf_defaults['MonitorBackgroundMin']
        if not background_max:
            background_max = idf_defaults['MonitorBackgroundMax']
        if not int_min:
            int_min = idf_defaults['MonitorIntegralMin']
        if not int_max:
            int_max = idf_defaults['MonitorIntegralMax']


    transWS = None
    if isinstance(transrun, str) and (',' in transrun):
        slam = transrun.split(',')[0]
        llam = transrun.split(',')[1]
        print "Transmission runs: ", transrun

        to_lam = ConvertToWavelength(slam)
        _monitor_ws_slam, _detector_ws_slam = to_lam.convert(wavelength_min=lambda_min, wavelength_max=lambda_max, detector_workspace_indexes=detector_index_ranges, monitor_workspace_index=i0_monitor_index, correct_monitor=True, bg_min=background_min, bg_max=background_max )

        _i0p_slam = RebinToWorkspace(WorkspaceToRebin=_monitor_ws_slam, WorkspaceToMatch=_detector_ws_slam)
        _mon_int_trans = Integration(InputWorkspace=_i0p_slam, RangeLower=int_min, RangeUpper=int_max)
        _detector_ws_slam = Divide(LHSWorkspace=_detector_ws_slam, RHSWorkspace=_mon_int_trans)

        to_lam = ConvertToWavelength(llam)
        _monitor_ws_llam, _detector_ws_llam = to_lam.convert(wavelength_min=lambda_min, wavelength_max=lambda_max, detector_workspace_indexes=detector_index_ranges, monitor_workspace_index=i0_monitor_index, correct_monitor=True, bg_min=background_min, bg_max=background_max )

        _i0p_llam = RebinToWorkspace(WorkspaceToRebin=_monitor_ws_llam, WorkspaceToMatch=_detector_ws_llam)
        _mon_int_trans = Integration(InputWorkspace=_i0p_llam, RangeLower=int_min,RangeUpper=int_max)
        _detector_ws_llam = Divide(LHSWorkspace=_detector_ws_llam, RHSWorkspace=_mon_int_trans)

        print stitch_start_overlap, stitch_end_overlap, stitch_params
        transWS, outputScaling = Stitch1D(LHSWorkspace=_detector_ws_slam, RHSWorkspace=_detector_ws_llam, StartOverlap=stitch_start_overlap,
                                           EndOverlap=stitch_end_overlap,  Params=stitch_params)

        transWS = RenameWorkspace(InputWorkspace=transWS, OutputWorkspace="TRANS_" + slam + "_" + llam)
    else:

        to_lam = ConvertToWavelength(transrun)
        _monitor_ws_trans, _detector_ws_trans = to_lam.convert(wavelength_min=lambda_min, wavelength_max=lambda_max, detector_workspace_indexes=detector_index_ranges, monitor_workspace_index=i0_monitor_index, correct_monitor=True, bg_min=background_min, bg_max=background_max )
        _i0p_trans = RebinToWorkspace(WorkspaceToRebin=_monitor_ws_trans, WorkspaceToMatch=_detector_ws_trans)

        _mon_int_trans = Integration( InputWorkspace=_i0p_trans, RangeLower=int_min, RangeUpper=int_max )
        transWS = Divide( LHSWorkspace=_detector_ws_trans, RHSWorkspace=_mon_int_trans )

        transWS = RenameWorkspace(InputWorkspace=transWS, OutputWorkspace="TRANS_" + transrun)
    return transWS
Exemple #32
0
def nrPNRCorrection(Wksp,crho,calpha,cAp,cPp):

    # Constants Based on Runs 18350+18355 and 18351+18356 analyser theta at -0.1deg
    # 2 RF Flippers as the polarising system
    # crho=[1.006831,-0.011467,0.002244,-0.000095]
    # calpha=[1.017526,-0.017183,0.003136,-0.000140]
    # cAp=[0.917940,0.038265,-0.006645,0.000282]
    # cPp=[0.972762,0.001828,-0.000261,0.0]
    message = "Performing PNR correction"
    logger.notice(message)
    print message
    CloneWorkspace(Wksp,OutputWorkspace='_'+Wksp+'_uncorrected')
    if ( (not isinstance(mtd[Wksp], WorkspaceGroup))  or (not  mtd[Wksp].size()==2) ):
        print "PNR correction works only with exactly 2 periods!"
        return mtd[Wksp]
    else:
        Ip = mtd[Wksp][0]
        Ia = mtd[Wksp][1]

        CloneWorkspace(Ip,OutputWorkspace="PCalpha")
        CropWorkspace(InputWorkspace="PCalpha",OutputWorkspace="PCalpha",StartWorkspaceIndex="0",EndWorkspaceIndex="0")
        PCalpha=(mtd['PCalpha']*0.0)+1.0
        alpha=mtd['PCalpha']
        # a1=alpha.readY(0)
        # for i in range(0,len(a1)):
            # alpha.dataY(0)[i]=0.0
            # alpha.dataE(0)[i]=0.0
        CloneWorkspace("PCalpha",OutputWorkspace="PCrho")
        CloneWorkspace("PCalpha",OutputWorkspace="PCAp")
        CloneWorkspace("PCalpha",OutputWorkspace="PCPp")
        rho=mtd['PCrho']
        Ap=mtd['PCAp']
        Pp=mtd['PCPp']
        # for i in range(0,len(a1)):
            # x=(alpha.dataX(0)[i]+alpha.dataX(0)[i])/2.0
            # for j in range(0,4):
                # alpha.dataY(0)[i]=alpha.dataY(0)[i]+calpha[j]*x**j
                # rho.dataY(0)[i]=rho.dataY(0)[i]+crho[j]*x**j
                # Ap.dataY(0)[i]=Ap.dataY(0)[i]+cAp[j]*x**j
                # Pp.dataY(0)[i]=Pp.dataY(0)[i]+cPp[j]*x**j
        PolynomialCorrection(InputWorkspace="PCalpha",OutputWorkspace="PCalpha",Coefficients=calpha,Operation="Multiply")
        PolynomialCorrection(InputWorkspace="PCrho",OutputWorkspace="PCrho",Coefficients=crho,Operation="Multiply")
        PolynomialCorrection(InputWorkspace="PCAp",OutputWorkspace="PCAp",Coefficients=cAp,Operation="Multiply")
        PolynomialCorrection(InputWorkspace="PCPp",OutputWorkspace="PCPp",Coefficients=cPp,Operation="Multiply")
        D=Pp*(1.0+rho)
        nIp=(Ip*(rho*Pp+1.0)+Ia*(Pp-1.0))/D
        nIa=(Ip*(rho*Pp-1.0)+Ia*(Pp+1.0))/D
        RenameWorkspace(nIp,OutputWorkspace=str(Ip)+"corr")
        RenameWorkspace(nIa,OutputWorkspace=str(Ia)+"corr")

        out = GroupWorkspaces(str(Ip)+"corr"+','+str(Ia)+"corr",OutputWorkspace=Wksp)

        #CloneWorkspace=(InputWorkspace="gr",OutputWorkspace=Wksp)
        iwksp = mtd.getObjectNames()
        list=[str(Ip),str(Ia),"PCalpha","PCrho","PCAp","PCPp","1_p"]
        for i in range(len(iwksp)):
            for j in list:
                lname=len(j)
                if iwksp[i] [0:lname+1] == j+"_":

                    DeleteWorkspace(iwksp[i])

        DeleteWorkspace("PCalpha")
        DeleteWorkspace("PCrho")
        DeleteWorkspace("PCAp")
        DeleteWorkspace("PCPp")
        DeleteWorkspace("D")

        return out
Exemple #33
0
def nrPACorrection(Wksp,crho,calpha,cAp,cPp):#UpUpWksp,UpDownWksp,DownUpWksp,DownDownWksp):
#    crho=[0.941893,0.0234006,-0.00210536,0.0]
#    calpha=[0.945088,0.0242861,-0.00213624,0.0]
#    cAp=[1.00079,-0.0186778,0.00131546,0.0]
#    cPp=[1.01649,-0.0228172,0.00214626,0.0]
    # Constants Based on Runs 18350+18355 and 18351+18356 analyser theta at -0.1deg
    # 2 RF Flippers as the polarising system
    # Ipa and Iap appear to be swapped in the sequence on CRISP 4 perido data!
    message = "Performing PA correction"
    logger.notice(message)
    print message
    CloneWorkspace(Wksp,OutputWorkspace='_'+Wksp+'_uncorrected')
    if  (not isinstance(mtd[Wksp], WorkspaceGroup)) or (not mtd[Wksp].size()==4) :
        print "PNR correction works only with exactly 4 periods (uu,ud,du,dd)!"
        return mtd[Wksp]
    else:
        Ipp = mtd[Wksp][0]
        Ipa = mtd[Wksp][1]
        Iap = mtd[Wksp][2]
        Iaa = mtd[Wksp][3]

        CloneWorkspace(Ipp,OutputWorkspace="PCalpha")
        CropWorkspace(InputWorkspace="PCalpha",OutputWorkspace="PCalpha",StartWorkspaceIndex=0,EndWorkspaceIndex=0)
        PCalpha=(mtd['PCalpha']*0.0)+1.0
        alpha=mtd['PCalpha']
        CloneWorkspace("PCalpha",OutputWorkspace="PCrho")
        CloneWorkspace("PCalpha",OutputWorkspace="PCAp")
        CloneWorkspace("PCalpha",OutputWorkspace="PCPp")
        rho=mtd['PCrho']
        Ap=mtd['PCAp']
        Pp=mtd['PCPp']

        # Use the polynomial corretion fn instead
        PolynomialCorrection(InputWorkspace="PCalpha",OutputWorkspace="PCalpha",Coefficients=calpha,Operation="Multiply")
        PolynomialCorrection(InputWorkspace="PCrho",OutputWorkspace="PCrho",Coefficients=crho,Operation="Multiply")
        PolynomialCorrection(InputWorkspace="PCAp",OutputWorkspace="PCAp",Coefficients=cAp,Operation="Multiply")
        PolynomialCorrection(InputWorkspace="PCPp",OutputWorkspace="PCPp",Coefficients=cPp,Operation="Multiply")

        A0 = (Iaa * Pp * Ap) + (Ap * Ipa * rho * Pp) + (Ap * Iap * Pp * alpha) + (Ipp * Ap * alpha * rho * Pp)
        A1 = Pp * Iaa
        A2 = Pp * Iap
        A3 = Ap * Iaa
        A4 = Ap * Ipa
        A5 = Ap * alpha * Ipp
        A6 = Ap * alpha * Iap
        A7 = Pp * rho  * Ipp
        A8 = Pp * rho  * Ipa
        D = Pp * Ap *( 1.0 + rho + alpha + (rho * alpha) )
        nIpp = (A0 - A1 + A2 - A3 + A4 + A5 - A6 + A7 - A8 + Ipp + Iaa - Ipa - Iap) / D
        nIaa = (A0 + A1 - A2 + A3 - A4 - A5 + A6 - A7 + A8 + Ipp + Iaa - Ipa - Iap) / D
        nIpa = (A0 - A1 + A2 + A3 - A4 - A5 + A6 + A7 - A8 - Ipp - Iaa + Ipa + Iap) / D
        nIap = (A0 + A1 - A2 - A3 + A4 + A5 - A6 - A7 + A8 - Ipp - Iaa + Ipa + Iap) / D
        ipp_corr = RenameWorkspace(nIpp,OutputWorkspace=str(Ipp)+"corr")
        ipa_corr = RenameWorkspace(nIpa,OutputWorkspace=str(Ipa)+"corr")
        iap_corr = RenameWorkspace(nIap,OutputWorkspace=str(Iap)+"corr")
        iaa_corr = RenameWorkspace(nIaa,OutputWorkspace=str(Iaa)+"corr")
        ReplaceSpecialValues(str(Ipp)+"corr",OutputWorkspace=str(Ipp)+"corr",NaNValue="0.0",NaNError="0.0",InfinityValue="0.0",InfinityError="0.0")
        ReplaceSpecialValues(str(Ipp)+"corr",OutputWorkspace=str(Ipp)+"corr",NaNValue="0.0",NaNError="0.0",InfinityValue="0.0",InfinityError="0.0")
        ReplaceSpecialValues(str(Ipp)+"corr",OutputWorkspace=str(Ipp)+"corr",NaNValue="0.0",NaNError="0.0",InfinityValue="0.0",InfinityError="0.0")
        ReplaceSpecialValues(str(Ipp)+"corr",OutputWorkspace=str(Ipp)+"corr",NaNValue="0.0",NaNError="0.0",InfinityValue="0.0",InfinityError="0.0")
        iwksp=mtd.getObjectNames()
        list=[str(Ipp),str(Ipa),str(Iap),str(Iaa),"PCalpha","PCrho","PCAp","PCPp","1_p"]
        for i in range(len(iwksp)):
            for j in list:
                lname=len(j)
                if iwksp[i] [0:lname+1] == j+"_":
                    DeleteWorkspace(iwksp[i])
        DeleteWorkspace("PCalpha")
        DeleteWorkspace("PCrho")
        DeleteWorkspace("PCAp")
        DeleteWorkspace("PCPp")
        DeleteWorkspace('A0')
        DeleteWorkspace('A1')
        DeleteWorkspace('A2')
        DeleteWorkspace('A3')
        DeleteWorkspace('A4')
        DeleteWorkspace('A5')
        DeleteWorkspace('A6')
        DeleteWorkspace('A7')
        DeleteWorkspace('A8')
        DeleteWorkspace('D')
        out = GroupWorkspaces("%s, %s, %s, %s" % (ipp_corr.name(), ipa_corr.name(), iap_corr.name(), iaa_corr.name()))

        return out
Exemple #34
0
def nrPNRCorrection(Wksp,crho,calpha,cAp,cPp):

    # Constants Based on Runs 18350+18355 and 18351+18356 analyser theta at -0.1deg
    # 2 RF Flippers as the polarising system
    # crho=[1.006831,-0.011467,0.002244,-0.000095]
    # calpha=[1.017526,-0.017183,0.003136,-0.000140]
    # cAp=[0.917940,0.038265,-0.006645,0.000282]
    # cPp=[0.972762,0.001828,-0.000261,0.0]
    message = "Performing PNR correction"
    logger.notice(message)
    print message
    CloneWorkspace(Wksp,OutputWorkspace='_'+Wksp+'_uncorrected')
    if ( (not isinstance(mtd[Wksp], WorkspaceGroup))  or (not  mtd[Wksp].size()==2) ):
        print "PNR correction works only with exactly 2 periods!"
        return mtd[Wksp]
    else:
        Ip = mtd[Wksp][0]
        Ia = mtd[Wksp][1]

        CloneWorkspace(Ip,OutputWorkspace="PCalpha")
        CropWorkspace(InputWorkspace="PCalpha",OutputWorkspace="PCalpha",StartWorkspaceIndex="0",EndWorkspaceIndex="0")
        PCalpha=(mtd['PCalpha']*0.0)+1.0
        alpha=mtd['PCalpha']
        # a1=alpha.readY(0)
        # for i in range(0,len(a1)):
            # alpha.dataY(0)[i]=0.0
            # alpha.dataE(0)[i]=0.0
        CloneWorkspace("PCalpha",OutputWorkspace="PCrho")
        CloneWorkspace("PCalpha",OutputWorkspace="PCAp")
        CloneWorkspace("PCalpha",OutputWorkspace="PCPp")
        rho=mtd['PCrho']
        Ap=mtd['PCAp']
        Pp=mtd['PCPp']
        # for i in range(0,len(a1)):
            # x=(alpha.dataX(0)[i]+alpha.dataX(0)[i])/2.0
            # for j in range(0,4):
                # alpha.dataY(0)[i]=alpha.dataY(0)[i]+calpha[j]*x**j
                # rho.dataY(0)[i]=rho.dataY(0)[i]+crho[j]*x**j
                # Ap.dataY(0)[i]=Ap.dataY(0)[i]+cAp[j]*x**j
                # Pp.dataY(0)[i]=Pp.dataY(0)[i]+cPp[j]*x**j
        PolynomialCorrection(InputWorkspace="PCalpha",OutputWorkspace="PCalpha",Coefficients=calpha,Operation="Multiply")
        PolynomialCorrection(InputWorkspace="PCrho",OutputWorkspace="PCrho",Coefficients=crho,Operation="Multiply")
        PolynomialCorrection(InputWorkspace="PCAp",OutputWorkspace="PCAp",Coefficients=cAp,Operation="Multiply")
        PolynomialCorrection(InputWorkspace="PCPp",OutputWorkspace="PCPp",Coefficients=cPp,Operation="Multiply")
        D=Pp*(1.0+rho)
        nIp=(Ip*(rho*Pp+1.0)+Ia*(Pp-1.0))/D
        nIa=(Ip*(rho*Pp-1.0)+Ia*(Pp+1.0))/D
        RenameWorkspace(nIp,OutputWorkspace=str(Ip)+"corr")
        RenameWorkspace(nIa,OutputWorkspace=str(Ia)+"corr")

        out = GroupWorkspaces(str(Ip)+"corr"+','+str(Ia)+"corr",OutputWorkspace=Wksp)

        #CloneWorkspace=(InputWorkspace="gr",OutputWorkspace=Wksp)
        iwksp = mtd.getObjectNames()
        list=[str(Ip),str(Ia),"PCalpha","PCrho","PCAp","PCPp","1_p"]
        for i in range(len(iwksp)):
            for j in list:
                lname=len(j)
                if iwksp[i] [0:lname+1] == j+"_":

                    DeleteWorkspace(iwksp[i])

        DeleteWorkspace("PCalpha")
        DeleteWorkspace("PCrho")
        DeleteWorkspace("PCAp")
        DeleteWorkspace("PCPp")
        DeleteWorkspace("D")

        return out
Exemple #35
0
def make_trans_corr(transrun, stitch_start_overlap, stitch_end_overlap, stitch_params,
                    lambda_min=None, lambda_max=None, background_min=None,
                    background_max=None, int_min=None, int_max=None, detector_index_ranges=None,
                    i0_monitor_index=None):
    '''
    Make the transmission correction workspace.
    '''

    '''
    Check to see whether all optional inputs have been provide. If not we have to get them from the IDF.
    '''
    if not all((lambda_min, lambda_max, background_min, background_max, int_min, int_max, detector_index_ranges, i0_monitor_index)):
        logger.notice("make_trans_corr: Fetching missing arguments from the IDF")
        instrument_source = transrun
        if isinstance(transrun, str):
            instrument_source = transrun.split(',')[0]
        trans_ws = ConvertToWavelength.to_workspace(instrument_source)
        idf_defaults = get_defaults(trans_ws)

        # Fetch defaults for anything not specified
        if not i0_monitor_index:
            i0_monitor_index = idf_defaults['I0MonitorIndex']
        if not lambda_min:
            lambda_min = idf_defaults['LambdaMin']
        if not lambda_max:
            lambda_max = idf_defaults['LambdaMax']
        if not detector_index_ranges:
            point_detector_start = idf_defaults['PointDetectorStart']
            point_detector_stop =  idf_defaults['PointDetectorStop']
            detector_index_ranges = (point_detector_start, point_detector_stop)
        if not background_min:
            background_min = idf_defaults['MonitorBackgroundMin']
        if not background_max:
            background_max = idf_defaults['MonitorBackgroundMax']
        if not int_min:
            int_min = idf_defaults['MonitorIntegralMin']
        if not int_max:
            int_max = idf_defaults['MonitorIntegralMax']


    transWS = None
    if isinstance(transrun, str) and (',' in transrun):
        slam = transrun.split(',')[0]
        llam = transrun.split(',')[1]
        print "Transmission runs: ", transrun

        to_lam = ConvertToWavelength(slam)
        _monitor_ws_slam, _detector_ws_slam = to_lam.convert(wavelength_min=lambda_min, wavelength_max=lambda_max, detector_workspace_indexes=detector_index_ranges, monitor_workspace_index=i0_monitor_index, correct_monitor=True, bg_min=background_min, bg_max=background_max )

        _i0p_slam = RebinToWorkspace(WorkspaceToRebin=_monitor_ws_slam, WorkspaceToMatch=_detector_ws_slam)
        _mon_int_trans = Integration(InputWorkspace=_i0p_slam, RangeLower=int_min, RangeUpper=int_max)
        _detector_ws_slam = Divide(LHSWorkspace=_detector_ws_slam, RHSWorkspace=_mon_int_trans)

        to_lam = ConvertToWavelength(llam)
        _monitor_ws_llam, _detector_ws_llam = to_lam.convert(wavelength_min=lambda_min, wavelength_max=lambda_max, detector_workspace_indexes=detector_index_ranges, monitor_workspace_index=i0_monitor_index, correct_monitor=True, bg_min=background_min, bg_max=background_max )

        _i0p_llam = RebinToWorkspace(WorkspaceToRebin=_monitor_ws_llam, WorkspaceToMatch=_detector_ws_llam)
        _mon_int_trans = Integration(InputWorkspace=_i0p_llam, RangeLower=int_min,RangeUpper=int_max)
        _detector_ws_llam = Divide(LHSWorkspace=_detector_ws_llam, RHSWorkspace=_mon_int_trans)

        print stitch_start_overlap, stitch_end_overlap, stitch_params
        transWS, outputScaling = Stitch1D(LHSWorkspace=_detector_ws_slam, RHSWorkspace=_detector_ws_llam, StartOverlap=stitch_start_overlap,
                                           EndOverlap=stitch_end_overlap,  Params=stitch_params)

        transWS = RenameWorkspace(InputWorkspace=transWS, OutputWorkspace="TRANS_" + slam + "_" + llam)
    else:

        to_lam = ConvertToWavelength(transrun)
        _monitor_ws_trans, _detector_ws_trans = to_lam.convert(wavelength_min=lambda_min, wavelength_max=lambda_max, detector_workspace_indexes=detector_index_ranges, monitor_workspace_index=i0_monitor_index, correct_monitor=True, bg_min=background_min, bg_max=background_max )
        _i0p_trans = RebinToWorkspace(WorkspaceToRebin=_monitor_ws_trans, WorkspaceToMatch=_detector_ws_trans)

        _mon_int_trans = Integration( InputWorkspace=_i0p_trans, RangeLower=int_min, RangeUpper=int_max )
        transWS = Divide( LHSWorkspace=_detector_ws_trans, RHSWorkspace=_mon_int_trans )

        transWS = RenameWorkspace(InputWorkspace=transWS, OutputWorkspace="TRANS_" + transrun)
    return transWS
Exemple #36
0
def nrPACorrection(Wksp,crho,calpha,cAp,cPp):#UpUpWksp,UpDownWksp,DownUpWksp,DownDownWksp):
#    crho=[0.941893,0.0234006,-0.00210536,0.0]
#    calpha=[0.945088,0.0242861,-0.00213624,0.0]
#    cAp=[1.00079,-0.0186778,0.00131546,0.0]
#    cPp=[1.01649,-0.0228172,0.00214626,0.0]
    # Constants Based on Runs 18350+18355 and 18351+18356 analyser theta at -0.1deg
    # 2 RF Flippers as the polarising system
    # Ipa and Iap appear to be swapped in the sequence on CRISP 4 perido data!
    message = "Performing PA correction"
    logger.notice(message)
    print message
    CloneWorkspace(Wksp,OutputWorkspace='_'+Wksp+'_uncorrected')
    if  (not isinstance(mtd[Wksp], WorkspaceGroup)) or (not mtd[Wksp].size()==4) :
        print "PNR correction works only with exactly 4 periods (uu,ud,du,dd)!"
        return mtd[Wksp]
    else:
        Ipp = mtd[Wksp][0]
        Ipa = mtd[Wksp][1]
        Iap = mtd[Wksp][2]
        Iaa = mtd[Wksp][3]

        CloneWorkspace(Ipp,OutputWorkspace="PCalpha")
        CropWorkspace(InputWorkspace="PCalpha",OutputWorkspace="PCalpha",StartWorkspaceIndex=0,EndWorkspaceIndex=0)
        PCalpha=(mtd['PCalpha']*0.0)+1.0
        alpha=mtd['PCalpha']
        CloneWorkspace("PCalpha",OutputWorkspace="PCrho")
        CloneWorkspace("PCalpha",OutputWorkspace="PCAp")
        CloneWorkspace("PCalpha",OutputWorkspace="PCPp")
        rho=mtd['PCrho']
        Ap=mtd['PCAp']
        Pp=mtd['PCPp']

        # Use the polynomial corretion fn instead
        PolynomialCorrection(InputWorkspace="PCalpha",OutputWorkspace="PCalpha",Coefficients=calpha,Operation="Multiply")
        PolynomialCorrection(InputWorkspace="PCrho",OutputWorkspace="PCrho",Coefficients=crho,Operation="Multiply")
        PolynomialCorrection(InputWorkspace="PCAp",OutputWorkspace="PCAp",Coefficients=cAp,Operation="Multiply")
        PolynomialCorrection(InputWorkspace="PCPp",OutputWorkspace="PCPp",Coefficients=cPp,Operation="Multiply")

        A0 = (Iaa * Pp * Ap) + (Ap * Ipa * rho * Pp) + (Ap * Iap * Pp * alpha) + (Ipp * Ap * alpha * rho * Pp)
        A1 = Pp * Iaa
        A2 = Pp * Iap
        A3 = Ap * Iaa
        A4 = Ap * Ipa
        A5 = Ap * alpha * Ipp
        A6 = Ap * alpha * Iap
        A7 = Pp * rho  * Ipp
        A8 = Pp * rho  * Ipa
        D = Pp * Ap *( 1.0 + rho + alpha + (rho * alpha) )
        nIpp = (A0 - A1 + A2 - A3 + A4 + A5 - A6 + A7 - A8 + Ipp + Iaa - Ipa - Iap) / D
        nIaa = (A0 + A1 - A2 + A3 - A4 - A5 + A6 - A7 + A8 + Ipp + Iaa - Ipa - Iap) / D
        nIpa = (A0 - A1 + A2 + A3 - A4 - A5 + A6 + A7 - A8 - Ipp - Iaa + Ipa + Iap) / D
        nIap = (A0 + A1 - A2 - A3 + A4 + A5 - A6 - A7 + A8 - Ipp - Iaa + Ipa + Iap) / D
        ipp_corr = RenameWorkspace(nIpp,OutputWorkspace=str(Ipp)+"corr")
        ipa_corr = RenameWorkspace(nIpa,OutputWorkspace=str(Ipa)+"corr")
        iap_corr = RenameWorkspace(nIap,OutputWorkspace=str(Iap)+"corr")
        iaa_corr = RenameWorkspace(nIaa,OutputWorkspace=str(Iaa)+"corr")
        ReplaceSpecialValues(str(Ipp)+"corr",OutputWorkspace=str(Ipp)+"corr",NaNValue="0.0",NaNError="0.0",InfinityValue="0.0",InfinityError="0.0")
        ReplaceSpecialValues(str(Ipp)+"corr",OutputWorkspace=str(Ipp)+"corr",NaNValue="0.0",NaNError="0.0",InfinityValue="0.0",InfinityError="0.0")
        ReplaceSpecialValues(str(Ipp)+"corr",OutputWorkspace=str(Ipp)+"corr",NaNValue="0.0",NaNError="0.0",InfinityValue="0.0",InfinityError="0.0")
        ReplaceSpecialValues(str(Ipp)+"corr",OutputWorkspace=str(Ipp)+"corr",NaNValue="0.0",NaNError="0.0",InfinityValue="0.0",InfinityError="0.0")
        iwksp=mtd.getObjectNames()
        list=[str(Ipp),str(Ipa),str(Iap),str(Iaa),"PCalpha","PCrho","PCAp","PCPp","1_p"]
        for i in range(len(iwksp)):
            for j in list:
                lname=len(j)
                if iwksp[i] [0:lname+1] == j+"_":
                    DeleteWorkspace(iwksp[i])
        DeleteWorkspace("PCalpha")
        DeleteWorkspace("PCrho")
        DeleteWorkspace("PCAp")
        DeleteWorkspace("PCPp")
        DeleteWorkspace('A0')
        DeleteWorkspace('A1')
        DeleteWorkspace('A2')
        DeleteWorkspace('A3')
        DeleteWorkspace('A4')
        DeleteWorkspace('A5')
        DeleteWorkspace('A6')
        DeleteWorkspace('A7')
        DeleteWorkspace('A8')
        DeleteWorkspace('D')
        out = GroupWorkspaces("%s, %s, %s, %s" % (ipp_corr.name(), ipa_corr.name(), iap_corr.name(), iaa_corr.name()))

        return out
Exemple #37
0
 def generate_plot_script_clipboard(self):
     script = generate_script(self.canvas.figure, exclude_headers=True)
     QApplication.clipboard().setText(script)
     logger.notice("Plotting script copied to clipboard.")
    def PyExec(self):
        self._eulerConvention = self.getProperty('EulerConvention').value
        calWS = self.getProperty('CalibrationTable').value
        calWS = api.SortTableWorkspace(calWS, Columns='detid')
        maskWS = self.getProperty("MaskWorkspace").value

        difc = calWS.column('difc')
        if maskWS is not None:
            self._masking = True
            mask = maskWS.extractY().flatten()
            difc = np.ma.masked_array(difc, mask)

        detID = calWS.column('detid')

        if self.getProperty("Workspace").value is not None:
            wks_name = self.getProperty("Workspace").value.name()
        else:
            wks_name = "alignedWorkspace"
            api.LoadEmptyInstrument(
                Filename=self.getProperty("InstrumentFilename").value,
                OutputWorkspace=wks_name)

        # Make a dictionary of what options are being refined for sample/source. No rotation.
        for opt in self._optionsList[:3]:
            self._optionsDict[opt] = self.getProperty(opt).value
        for opt in self._optionsList[3:]:
            self._optionsDict[opt] = False

        # First fit L1 if selected for Source and/or Sample
        for component in "Source", "Sample":
            if self.getProperty("Fit" + component + "Position").value:
                self._move = True
                if component == "Sample":
                    comp = api.mtd[wks_name].getInstrument().getSample()
                else:
                    comp = api.mtd[wks_name].getInstrument().getSource()
                componentName = comp.getFullName()
                logger.notice("Working on " + componentName +
                              " Starting position is " + str(comp.getPos()))
                firstIndex = 0
                lastIndex = len(difc)
                if self._masking:
                    mask_out = mask[firstIndex:lastIndex + 1]
                else:
                    mask_out = None

                self._initialPos = [
                    comp.getPos().getX(),
                    comp.getPos().getY(),
                    comp.getPos().getZ(), 0, 0, 0
                ]

                # Set up x0 and bounds lists
                x0List = []
                boundsList = []
                for iopt, opt in enumerate(self._optionsList[:3]):
                    if self._optionsDict[opt]:
                        x0List.append(self._initialPos[iopt])
                        boundsList.append(
                            (self._initialPos[iopt] +
                             self.getProperty("Min" + opt).value,
                             self._initialPos[iopt] +
                             self.getProperty("Max" + opt).value))

                results = minimize(self._minimisation_func,
                                   x0=x0List,
                                   method='L-BFGS-B',
                                   args=(wks_name, componentName, firstIndex,
                                         lastIndex, difc[firstIndex:lastIndex +
                                                         1], mask_out),
                                   bounds=boundsList)

                # Apply the results to the output workspace
                xmap = self._mapOptions(results.x)

                # Need to grab the component again, as things have changed
                api.MoveInstrumentComponent(wks_name,
                                            componentName,
                                            X=xmap[0],
                                            Y=xmap[1],
                                            Z=xmap[2],
                                            RelativePosition=False)
                comp = api.mtd[wks_name].getInstrument().getComponentByName(
                    componentName)
                logger.notice("Finished " + componentName +
                              " Final position is " + str(comp.getPos()))
                self._move = False

        # Now fit all the components if any
        components = self.getProperty("ComponentList").value

        # Make a dictionary of what options are being refined.
        for opt in self._optionsList:
            self._optionsDict[opt] = self.getProperty(opt).value

        self._move = (self._optionsDict["Xposition"]
                      or self._optionsDict["Yposition"]
                      or self._optionsDict["Zposition"])

        self._rotate = (self._optionsDict["AlphaRotation"]
                        or self._optionsDict["BetaRotation"]
                        or self._optionsDict["GammaRotation"])

        prog = Progress(self, start=0, end=1, nreports=len(components))
        for component in components:
            comp = api.mtd[wks_name].getInstrument().getComponentByName(
                component)
            firstDetID = self._getFirstDetID(comp)
            firstIndex = detID.index(firstDetID)
            lastDetID = self._getLastDetID(comp)
            lastIndex = detID.index(lastDetID)
            if lastDetID - firstDetID != lastIndex - firstIndex:
                raise RuntimeError(
                    "Calibration detid doesn't match instrument")

            eulerAngles = comp.getRotation().getEulerAngles(
                self._eulerConvention)

            logger.notice("Working on " + comp.getFullName() +
                          " Starting position is " + str(comp.getPos()) +
                          " Starting rotation is " + str(eulerAngles))

            x0List = []
            self._initialPos = [
                comp.getPos().getX(),
                comp.getPos().getY(),
                comp.getPos().getZ(), eulerAngles[0], eulerAngles[1],
                eulerAngles[2]
            ]

            boundsList = []

            if self._masking:
                mask_out = mask[firstIndex:lastIndex + 1]
                if mask_out.sum() == mask_out.size:
                    self.log().warning(
                        "All pixels in '%s' are masked. Skipping calibration."
                        % component)
                    continue
            else:
                mask_out = None

            for iopt, opt in enumerate(self._optionsList):
                if self._optionsDict[opt]:
                    x0List.append(self._initialPos[iopt])
                    boundsList.append((self._initialPos[iopt] +
                                       self.getProperty("Min" + opt).value,
                                       self._initialPos[iopt] +
                                       self.getProperty("Max" + opt).value))

            results = minimize(self._minimisation_func,
                               x0=x0List,
                               method='L-BFGS-B',
                               args=(wks_name, component, firstIndex,
                                     lastIndex, difc[firstIndex:lastIndex + 1],
                                     mask_out),
                               bounds=boundsList)

            # Apply the results to the output workspace
            xmap = self._mapOptions(results.x)

            if self._move:
                api.MoveInstrumentComponent(wks_name,
                                            component,
                                            X=xmap[0],
                                            Y=xmap[1],
                                            Z=xmap[2],
                                            RelativePosition=False)

            if self._rotate:
                (rotw, rotx, roty,
                 rotz) = self._eulerToAngleAxis(xmap[3], xmap[4], xmap[5],
                                                self._eulerConvention)
                api.RotateInstrumentComponent(wks_name,
                                              component,
                                              X=rotx,
                                              Y=roty,
                                              Z=rotz,
                                              Angle=rotw,
                                              RelativeRotation=False)

            # Need to grab the component again, as things have changed
            comp = api.mtd[wks_name].getInstrument().getComponentByName(
                component)
            logger.notice(
                "Finshed " + comp.getFullName() + " Final position is " +
                str(comp.getPos()) + " Final rotation is " +
                str(comp.getRotation().getEulerAngles(self._eulerConvention)))

            prog.report()
        logger.notice("Results applied to workspace " + wks_name)
Exemple #39
0
    def create_output_files(self, calibration_dir, difa, difc, tzero,
                            bk2bk_params, ceria_path, instrument, bank,
                            spectrum_numbers, calfile):
        """
        Create output files from the algorithms in the specified directory
        :param calibration_dir: The directory to save the files into.
        :param difa: DIFA values from calibration algorithm.
        :param difc: DIFC values from the calibration algorithm.
        :param tzero: TZERO values from the calibration algorithm.
        :param bk2bk_params: BackToBackExponential parameters from Parameters.xml file.
        :param ceria_path: The path to the ceria data file.
        :param instrument: The instrument (ENGINX or IMAT).
        :param bank: Optional parameter to crop by bank.
        :param spectrum_numbers: Optional parameter to crop using spectrum numbers.
        :param calfile: Optional parameter to crop with a custom calfile
        """
        kwargs = {
            "ceria_run":
            path_handling.get_run_number_from_path(ceria_path, instrument)
        }

        def south_kwargs():
            kwargs["template_file"] = SOUTH_BANK_TEMPLATE_FILE
            kwargs["bank_names"] = ["South"]

        def north_kwargs():
            kwargs["template_file"] = NORTH_BANK_TEMPLATE_FILE
            kwargs["bank_names"] = ["North"]

        def generate_prm_output_file(difa_list, difc_list, tzero_list,
                                     bank_name, kwargs_to_pass):
            file_path = calibration_dir + EnggUtils.generate_output_file_name(
                ceria_path, instrument, bank=bank_name)
            EnggUtils.write_ENGINX_GSAS_iparam_file(file_path, difa_list,
                                                    difc_list, tzero_list,
                                                    bk2bk_params,
                                                    **kwargs_to_pass)
            set_setting(output_settings.INTERFACES_SETTINGS_GROUP,
                        output_settings.ENGINEERING_PREFIX,
                        "last_calibration_path", file_path)

        def save_pdcal_output_file(ws_name_suffix, bank_name):
            file_path = calibration_dir + EnggUtils.generate_output_file_name(
                ceria_path, instrument, bank=bank_name, ext=".nxs")
            ws_name = "engggui_calibration_" + ws_name_suffix
            SaveNexus(InputWorkspace=ws_name, Filename=file_path)

        if not path.exists(calibration_dir):
            makedirs(calibration_dir)

        if not (bank or spectrum_numbers or calfile):
            # both banks
            generate_prm_output_file(difa, difc, tzero, "all", kwargs)
            north_kwargs()
            generate_prm_output_file([difa[0]], [difc[0]], [tzero[0]], "north",
                                     kwargs)
            save_pdcal_output_file("bank_1", "north")
            south_kwargs()
            generate_prm_output_file([difa[1]], [difc[1]], [tzero[1]], "south",
                                     kwargs)
            save_pdcal_output_file("bank_2", "south")
        elif bank == "1":
            north_kwargs()
            generate_prm_output_file([difa[0]], [difc[0]], [tzero[0]], "north",
                                     kwargs)
            save_pdcal_output_file("bank_1", "north")
        elif bank == "2":
            south_kwargs()
            generate_prm_output_file([difa[0]], [difc[0]], [tzero[0]], "south",
                                     kwargs)
            save_pdcal_output_file("bank_2", "south")
        elif spectrum_numbers:  # Custom crops use the north bank template
            north_kwargs()
            generate_prm_output_file([difa[0]], [difc[0]], [tzero[0]],
                                     "Cropped", kwargs)
            save_pdcal_output_file("Cropped", "Cropped")
        else:  # custom calfile
            north_kwargs()
            generate_prm_output_file([difa[0]], [difc[0]], [tzero[0]],
                                     "Custom", kwargs)
            save_pdcal_output_file("Custom", "Custom")
        logger.notice(
            f"\n\nCalibration files saved to: \"{calibration_dir}\"\n\n")
def export_masks(ws,fileName='',returnMasksOnly=False):
    """Exports masks applied to Mantid workspace
       (e.g. drawn using the instrument view) and write these masks
       into the old fashioned ASCII .msk file containing masked spectra numbers.

       The file is Libisis/Mantid old ISIS format compatible and can be read by Libisis
       or Mantid LoadMasks algorithm

       If optional parameter fileName is present, the masks are saved
       in the file with this name
       Otherwise, the file with the name equal to the workspace
       name and the extension .msk is used.

       If returnMasks is set to True, the function does not write to file but returns
       list of masks instead.
    """
   # get pointer to the workspace
    if isinstance(ws, str):
        pws = mtd[ws]
    else:
        pws = ws

    ws_name=pws.getName()
    nhist = pws.getNumberHistograms()

    no_detectors = 0
    masks = []
    for i in range(nhist):
        # set provisional spectra ID
        ms = i+1
        try:
            sp = pws.getSpectrum(i)
            # got real spectra ID, which would correspond real spectra num to spectra ID map
            ms = sp.getSpectrumNo()
#pylint: disable=W0703
        except Exception:
            logger.notice("Can not retrieve spectra No: " + str(i) + ". Have masked it")
            masks.append(ms)
            continue
        try:
            det = pws.getDetector(i)
#pylint: disable=W0703
        except Exception:
            no_detectors = no_detectors +1
            masks.append(ms)
            continue
        if det.isMasked():
            masks.append(ms)

    filename=''
    if len(fileName)==0 :
        filename = os.path.join(config.getString('defaultsave.directory'),ws_name+'.msk')
    else:
        filename = fileName

    nMasks = len(masks)
    if nMasks == 0:
        if returnMasksOnly:
            logger.warning("Workspace {0} have no masked spectra. File {1} have not been created".format(ws_name,filename))
        else:
            logger.notice("Workspace "+ws_name+" have no masked spectra")
        return masks

    logger.notice("Workspace {0} has {1} masked spectra, including {2} spectra without detectors".format(ws_name,nMasks,no_detectors))

    if not returnMasksOnly :
        writeISISmasks(filename,masks,8)
    return masks
    def PyExec(self):
        self._eulerConvention=self.getProperty('EulerConvention').value
        calWS = self.getProperty('CalibrationTable').value
        calWS = api.SortTableWorkspace(calWS, Columns='detid')
        maskWS = self.getProperty("MaskWorkspace").value

        difc = calWS.column('difc')
        if maskWS is not None:
            self._masking = True
            mask = maskWS.extractY().flatten()
            difc = np.ma.masked_array(difc, mask)

        detID = calWS.column('detid')

        if self.getProperty("Workspace").value is not None:
            wks_name = self.getProperty("Workspace").value.name()
        else:
            wks_name = "alignedWorkspace"
            api.LoadEmptyInstrument(Filename=self.getProperty("InstrumentFilename").value,
                                    OutputWorkspace=wks_name)

        # Make a dictionary of what options are being refined for sample/source. No rotation.
        for opt in self._optionsList[:3]:
            self._optionsDict[opt] = self.getProperty(opt).value
        for opt in self._optionsList[3:]:
            self._optionsDict[opt] = False

        # First fit L1 if selected for Source and/or Sample
        for component in "Source", "Sample":
            if self.getProperty("Fit"+component+"Position").value:
                self._move = True
                if component == "Sample":
                    comp = api.mtd[wks_name].getInstrument().getSample()
                else:
                    comp = api.mtd[wks_name].getInstrument().getSource()
                componentName = comp.getFullName()
                logger.notice("Working on " + componentName +
                              " Starting position is " + str(comp.getPos()))
                firstIndex = 0
                lastIndex = len(difc)
                if self._masking:
                    mask_out = mask[firstIndex:lastIndex + 1]
                else:
                    mask_out = None

                self._initialPos = [comp.getPos().getX(),
                                    comp.getPos().getY(),
                                    comp.getPos().getZ(),
                                    0, 0, 0]

                # Set up x0 and bounds lists
                x0List = []
                boundsList = []
                for iopt,opt in enumerate(self._optionsList[:3]):
                    if self._optionsDict[opt]:
                        x0List.append(self._initialPos[iopt])
                        boundsList.append((self._initialPos[iopt] + self.getProperty("Min"+opt).value,
                                           self._initialPos[iopt] + self.getProperty("Max"+opt).value))

                results = minimize(self._minimisation_func, x0=x0List,
                                   method='L-BFGS-B',
                                   args=(wks_name,
                                         componentName,
                                         firstIndex,
                                         lastIndex,
                                         difc[firstIndex:lastIndex + 1],
                                         mask_out),
                                   bounds=boundsList)

                # Apply the results to the output workspace
                xmap = self._mapOptions(results.x)

                # Need to grab the component again, as things have changed
                api.MoveInstrumentComponent(wks_name, componentName,
                                            X=xmap[0],
                                            Y=xmap[1],
                                            Z=xmap[2],
                                            RelativePosition=False)
                comp = api.mtd[wks_name].getInstrument().getComponentByName(componentName)
                logger.notice("Finished " + componentName +
                              " Final position is " + str(comp.getPos()))
                self._move = False

        # Now fit all the components if any
        components = self.getProperty("ComponentList").value

        # Make a dictionary of what options are being refined.
        for opt in self._optionsList:
            self._optionsDict[opt] = self.getProperty(opt).value

        self._move = (self._optionsDict["Xposition"] or self._optionsDict["Yposition"] or self._optionsDict["Zposition"])

        self._rotate = (self._optionsDict["AlphaRotation"] or self._optionsDict["BetaRotation"] or self._optionsDict["GammaRotation"])

        prog = Progress(self, start=0, end=1, nreports=len(components))
        for component in components:
            comp = api.mtd[wks_name].getInstrument().getComponentByName(component)
            firstDetID = self._getFirstDetID(comp)
            firstIndex = detID.index(firstDetID)
            lastDetID = self._getLastDetID(comp)
            lastIndex = detID.index(lastDetID)
            if lastDetID - firstDetID != lastIndex - firstIndex:
                raise RuntimeError("Calibration detid doesn't match instrument")

            eulerAngles = comp.getRotation().getEulerAngles(self._eulerConvention)

            logger.notice("Working on " + comp.getFullName() +
                          " Starting position is " + str(comp.getPos()) +
                          " Starting rotation is " + str(eulerAngles))

            x0List = []
            self._initialPos = [comp.getPos().getX(), comp.getPos().getY(), comp.getPos().getZ(),
                                eulerAngles[0], eulerAngles[1], eulerAngles[2]]

            boundsList = []

            if self._masking:
                mask_out = mask[firstIndex:lastIndex + 1]
                if mask_out.sum() == mask_out.size:
                    self.log().warning("All pixels in '%s' are masked. Skipping calibration." % component)
                    continue
            else:
                mask_out = None

            for iopt,opt in enumerate(self._optionsList):
                if self._optionsDict[opt]:
                    x0List.append(self._initialPos[iopt])
                    boundsList.append((self._initialPos[iopt] + self.getProperty("Min"+opt).value,
                                       self._initialPos[iopt] + self.getProperty("Max"+opt).value))

            results = minimize(self._minimisation_func, x0=x0List,
                               method='L-BFGS-B',
                               args=(wks_name,
                                     component,
                                     firstIndex,
                                     lastIndex,
                                     difc[firstIndex:lastIndex + 1],
                                     mask_out),
                               bounds=boundsList)

            # Apply the results to the output workspace
            xmap = self._mapOptions(results.x)

            if self._move:
                api.MoveInstrumentComponent(wks_name, component, X=xmap[0], Y=xmap[1], Z=xmap[2],
                                            RelativePosition=False)

            if self._rotate:
                (rotw, rotx, roty, rotz) = self._eulerToAngleAxis(xmap[3], xmap[4], xmap[5], self._eulerConvention)
                api.RotateInstrumentComponent(wks_name, component, X=rotx, Y=roty, Z=rotz, Angle=rotw,
                                              RelativeRotation=False)

            # Need to grab the component again, as things have changed
            comp = api.mtd[wks_name].getInstrument().getComponentByName(component)
            logger.notice("Finshed " + comp.getFullName() +
                          " Final position is " + str(comp.getPos()) +
                          " Final rotation is " + str(comp.getRotation().getEulerAngles(self._eulerConvention)))

            prog.report()
        logger.notice("Results applied to workspace "+wks_name)