コード例 #1
0
    def setup_time_range(self, current_file, sam_file):
        StartTime = current_file["StartTime"]
        EndTime = current_file["EndTime"]
        # Errors: if trying to reduce time slice larger than the total time of the measurement:
        # Error message & Stop - to add

        if ((not StartTime) and (EndTime)) or ((StartTime) and (not EndTime)):
            raise ValueError(
                "Check StartTime and EndTime values; either both or none shall be intered."
            )

        if (not StartTime) and (not EndTime):
            ws_sam = mantid_api.LoadBBY(sam_file)
            time_range = ''
        elif (float(StartTime)) > (float(EndTime)):
            raise ValueError(
                "Check StartTime and EndTime values; EndTime cannot be smaller than StartTime."
            )
        else:
            ws_sam = mantid_api.LoadBBY(
                sam_file
            )  # test loader: to check if given StartTime and EndTime are reasonable
            Real_EndTime_max = float(
                ws_sam.run().getProperty('bm_counts').value)
            if (float(EndTime) > Real_EndTime_max * 1.1):
                raise ValueError(
                    'EndTime value is wrong, it is more than 10%% larger than the data collection time: %7.2f'
                    % Real_EndTime_max)
            ws_sam = mantid_api.LoadBBY(
                sam_file,
                FilterByTimeStart=StartTime,
                FilterByTimeStop=EndTime
            )  # now to load file within requested time slice if values are feasible
            time_range = '_' + StartTime + '_' + EndTime

        return ws_sam, time_range
コード例 #2
0
    def run_bilby_reduction(self):
        # Read input csv file and define / create a folder for the output data
        csv_files_to_reduce_list = mantid_api.FileFinder.getFullPath(
            self.current_reduction_settings[0]["csv_file_name"])
        reduced_files_path = self.setup_save_out_path(csv_files_to_reduce_list)

        # Wavelength binning
        binning_wavelength_ini_str = self.retrieve_reduction_settings(
            "binning_wavelength_ini",
            raise_exception=True,
            message="binning_wavelength_ini cannot be empty")

        binning_wavelength_ini = BilbyCustomFunctions_Reduction.read_convert_to_float(
            binning_wavelength_ini_str)
        binning_wavelength_ini_original = binning_wavelength_ini

        # WAVELENGTH RANGE FOR TRANSMISSION: the aim is to fit transmission on the whole range, and take only part for the data reduction
        # must  be equal or longer than binning_wavelength_ini
        binning_wavelength_transmission_str = self.current_reduction_settings[
            0]["binning_wavelength_transmission"]
        binning_wavelength_transmission = BilbyCustomFunctions_Reduction.read_convert_to_float(
            binning_wavelength_transmission_str)
        binning_wavelength_transmission_original = binning_wavelength_transmission

        # Check of wavelength range: transmission range must be equal or longer than the wavelength binning range for data reduction
        if (binning_wavelength_ini[0] < binning_wavelength_transmission[0]
            ) or (binning_wavelength_ini[2] >
                  binning_wavelength_transmission[2]):
            raise ValueError(
                "Range for transmission binning shall be equal or wider than the range for the"
                " sample wavelength binning (refer to line 94)")

        # Binning for Q
        binning_q_str = self.current_reduction_settings[0]["binning_q"]
        binning_q = BilbyCustomFunctions_Reduction.read_convert_to_float(
            binning_q_str)

        RadiusCut = self.retrieve_reduction_settings("RadiusCut", default=0.0)
        WaveCut = self.retrieve_reduction_settings("WaveCut", default=0.0)

        # Transmission fit parameters
        transmission_fit_ini = self.current_reduction_settings[0][
            "transmission_fit"]
        if (transmission_fit_ini != "Linear") and (
                transmission_fit_ini != "Log") and (transmission_fit_ini !=
                                                    "Polynomial"):
            raise ValueError("Check value of transmission_fit; it can be only"
                             " \"Linear\", \"Log\" or \"Polynomial\","
                             " first letter is mandatory capital")

        PolynomialOrder = self.current_reduction_settings[0]["PolynomialOrder"]

        # Wavelength interval: if reduction on wavelength intervals is needed
        wavelength_interval_input = self.current_reduction_settings[0][
            "wavelength_intervals"].lower()
        wavelength_intervals = BilbyCustomFunctions_Reduction.string_boolean(
            wavelength_interval_input)
        wavelength_intervals_original = wavelength_intervals
        wav_delta = 0.0  # set the value, needed for the "wavelengh_slices" function

        if self.reduce_2D:
            print(
                "2D reduction is performing. Q interval and number of points are taking into account;"
                " Q-binning intervals are ignored.")
            number_data_points_2D = float(
                self.retrieve_reduction_settings(
                    "2D_number_data_points",
                    raise_exception=True,
                    message="Number of points shall be given"))

            plot_2D = self.current_reduction_settings[0]["plot_2D"].lower()
            plot_2D = BilbyCustomFunctions_Reduction.string_boolean(plot_2D)
            binning_q[1] = (
                binning_q[0] + binning_q[2]
            ) / number_data_points_2D  # To replace deltaQ from the input file
        else:
            plot_2D = None

        ######################################
        # Calling function to read given csv file
        parameters = BilbyCustomFunctions_Reduction.files_list_reduce(
            csv_files_to_reduce_list)
        files_to_reduce = BilbyCustomFunctions_Reduction.files_to_reduce(
            parameters, self.index_files_to_reduce)
        if len(files_to_reduce) == 0:
            raise ValueError(
                'Please check index_files_to_reduce; chosen one does not exist'
            )

        # reduce requested files one by one
        for current_file in files_to_reduce:
            sam_file = current_file["Sample"] + '.tar'

            ws_sam, time_range = self.setup_time_range(current_file, sam_file)

            # To read the mode value: True - ToF; False - NVS; this will define some steps inside SANSDataProcessor
            try:
                external_mode = (ws_sam.run().getProperty("is_tof").value)
            except:
                external_mode = True  # This is needed for old files, where the ToF/mono mode value has not been recorded

            # Internal frame source has been used during data collection; it is not always NVS only,
            # one can have both, NVS and choppers running for this mode
            if (not external_mode):
                print(
                    "Internal frame source. Binning range is taken from the sample scattering data."
                )
                binning_wavelength_ini = (ws_sam.readX(0)[0],
                                          ws_sam.readX(0)[ws_sam.blocksize()] -
                                          ws_sam.readX(0)[0],
                                          ws_sam.readX(0)[ws_sam.blocksize()])
                binning_wavelength_transmission = binning_wavelength_ini
                if wavelength_intervals:
                    wavelength_intervals = False
                    print("NVS: monochromatic mode")
                    print(
                        "There is no sense to reduce monochromatic data on multiple wavelength;"
                        " \"wavelength_intervals\" value changed to False.")
            else:
                # important for the case when NVS data is being analysed first,
                # ie to be able to come back to the whole range & wavelength slices, if needed
                binning_wavelength_ini = binning_wavelength_ini_original
                binning_wavelength_transmission = binning_wavelength_transmission_original
                wavelength_intervals = wavelength_intervals_original
                if wavelength_intervals:
                    wav_delta = float(
                        self.current_reduction_settings[0]["wav_delta"]
                    )  # no need to read if the previous is false

            # empty beam scattering in transmission mode
            ws_emp_file = current_file["T_EmptyBeam"] + '.tar'
            mantid_api.LoadBBY(
                ws_emp_file, OutputWorkspace='ws_emp'
            )  # Note that this is of course a transmission measurement - shall be long

            # transmission workspaces and masks
            transm_file = current_file["T_Sample"] + '.tar'
            ws_tranSam = mantid_api.LoadBBY(transm_file)
            ws_tranEmp = mantid_api.LoadBBY(
                ws_emp_file)  # empty beam for transmission
            transm_mask = current_file["mask_transmission"] + '.xml'
            ws_tranMsk = mantid_api.LoadMask('Bilby', transm_mask)

            sam_mask_file = current_file["mask"] + '.xml'
            ws_samMsk = mantid_api.LoadMask('Bilby', sam_mask_file)

            # scaling: attenuation
            att_pos = float(ws_tranSam.run().getProperty("att_pos").value)

            scale = BilbyCustomFunctions_Reduction.attenuation_correction(
                att_pos, self.data_before_May_2016)
            print("scale, aka attenuation factor {}".format(scale))

            thickness = current_file["thickness [cm]"]

            # Cd / Al masks shift
            if self.correct_tubes_shift:
                BilbyCustomFunctions_Reduction.correction_tubes_shift(
                    ws_sam, self.path_tube_shift_correction)

            if self.data_before_2016:
                BilbyCustomFunctions_Reduction.det_shift_before_2016(ws_sam)

                # Blocked beam
            if self.blocked_beam:
                ws_blocked_beam = current_file["BlockedBeam"] + '.tar'
                ws_blk = mantid_api.LoadBBY(ws_blocked_beam)
                if self.correct_tubes_shift:
                    BilbyCustomFunctions_Reduction.correction_tubes_shift(
                        ws_blk, self.path_tube_shift_correction)
            else:
                ws_blk = None

            # Detector sensitivity
            ws_sen = None

            # empty beam normalisation
            mantid_api.MaskDetectors(
                "ws_emp", MaskedWorkspace=ws_tranMsk
            )  # does not have to be ws_tranMsk, can be a specific mask
            mantid_api.ConvertUnits("ws_emp",
                                    Target="Wavelength",
                                    OutputWorkspace='ws_emp')

            # wavelenth intervals: building  binning_wavelength list
            binning_wavelength, n = BilbyCustomFunctions_Reduction.wavelengh_slices(
                wavelength_intervals, binning_wavelength_ini, wav_delta)

            # By now we know how many wavelengths bins we have, so shall run Q1D n times
            # -- Processing --
            suffix = '_' + current_file[
                "suffix"]  # is the same for all wavelength intervals
            suffix_2 = current_file["additional_description"]
            if suffix_2 != '':
                suffix += '_' + suffix_2

            plot1Dgraph = None

            for i in range(n):
                ws_emp_partial = mantid_api.Rebin("ws_emp",
                                                  Params=binning_wavelength[i])
                ws_emp_partial = mantid_api.SumSpectra(ws_emp_partial,
                                                       IncludeMonitors=False)

                base_output_name = self.get_base_output_name(
                    i, sam_file, binning_wavelength, time_range, suffix)

                # needed here, otherwise SANSDataProcessor replaced it with "transmission_fit" string
                transmission_fit = transmission_fit_ini

                output_workspace, transmission_fit = mantid_api.BilbySANSDataProcessor(
                    InputWorkspace=ws_sam,
                    InputMaskingWorkspace=ws_samMsk,
                    BlockedBeamWorkspace=ws_blk,
                    EmptyBeamSpectrumShapeWorkspace=ws_emp_partial,
                    SensitivityCorrectionMatrix=ws_sen,
                    TransmissionWorkspace=ws_tranSam,
                    TransmissionEmptyBeamWorkspace=ws_tranEmp,
                    TransmissionMaskingWorkspace=ws_tranMsk,
                    ScalingFactor=scale,
                    SampleThickness=thickness,
                    FitMethod=transmission_fit,
                    PolynomialOrder=PolynomialOrder,
                    BinningWavelength=binning_wavelength[i],
                    BinningWavelengthTransm=binning_wavelength_transmission,
                    BinningQ=binning_q,
                    TimeMode=external_mode,
                    AccountForGravity=self.account_for_gravity,
                    SolidAngleWeighting=self.solid_angle_weighting,
                    RadiusCut=RadiusCut,
                    WaveCut=WaveCut,
                    WideAngleCorrection=self.wide_angle_correction,
                    Reduce2D=self.reduce_2D,
                    OutputWorkspace=base_output_name)

                if not self.reduce_2D:
                    BilbyCustomFunctions_Reduction.strip_NaNs(
                        output_workspace, base_output_name)

                self.plot_graphs(i, reduced_files_path, base_output_name,
                                 output_workspace, plot_2D, plot1Dgraph)
                self.save_out_files(reduced_files_path, base_output_name,
                                    output_workspace)

                return output_workspace, transmission_fit