Пример #1
0
 def testDetectorGrouping(self):
     ws = illhelpers.create_poor_mans_in5_workspace(0.0,
                                                    _groupingTestDetectors)
     originalNDetectors = ws.getNumberHistograms()
     detectorIds = list()
     for i in range(originalNDetectors):
         detectorIds.append(ws.getDetector(i).getID())
     _add_natural_angle_step_parameter(ws)
     mtd.addOrReplace('inWS', ws)
     outWSName = 'outWS'
     algProperties = {
         'InputWorkspace': ws,
         'OutputWorkspace': outWSName,
         'Cleanup': 'Cleanup OFF',
         'Transposing': 'Transposing OFF',
         'rethrow': True
     }
     run_algorithm('DirectILLReduction', **algProperties)
     groupedWSName = outWSName + '_grouped_detectors_'
     self.assertTrue(groupedWSName in mtd)
     groupedWS = mtd[groupedWSName]
     self.assertEqual(groupedWS.getNumberHistograms(), 2)
     groupIds = list(groupedWS.getDetector(0).getDetectorIDs())
     groupIds += groupedWS.getDetector(1).getDetectorIDs()
     self.assertEqual(collections.Counter(detectorIds),
                      collections.Counter(groupIds))
Пример #2
0
 def testDetectorGroupingWithUserGivenAngleStep(self):
     ws = illhelpers.create_poor_mans_in5_workspace(0.0,
                                                    _groupingTestDetectors)
     nhisto = ws.getNumberHistograms()
     spectrumInfo = ws.spectrumInfo()
     minAngle = 180.
     maxAngle = 0.
     for i in range(nhisto):
         angle = numpy.rad2deg(spectrumInfo.twoTheta(i))
         minAngle = min(minAngle, angle)
         maxAngle = max(maxAngle, angle)
     mtd.addOrReplace('inWS', ws)
     outWSName = 'unused'
     outSThetaWName = 'SofThetaW'
     angleStep = 0.2
     algProperties = {
         'InputWorkspace': ws,
         'OutputWorkspace': outWSName,
         'GroupingAngleStep': angleStep,
         'OutputSofThetaEnergyWorkspace': outSThetaWName,
         'Transposing': 'Transposing OFF',
         'rethrow': True
     }
     run_algorithm('DirectILLReduction', **algProperties)
     self.assertTrue(outSThetaWName in mtd)
     SThetaWWS = mtd[outSThetaWName]
     spectrumInfo = SThetaWWS.spectrumInfo()
     firstAngleBin = int(minAngle / angleStep)
     lastAngleBin = int(maxAngle / angleStep) + 1
     expected = lastAngleBin - firstAngleBin
     self.assertEqual(spectrumInfo.size(), expected)
 def testDetectorGroupingWithUserGivenAngleStep(self):
     ws = illhelpers.create_poor_mans_in5_workspace(0.0, _groupingTestDetectors)
     nhisto = ws.getNumberHistograms()
     spectrumInfo = ws.spectrumInfo()
     minAngle = 180.
     maxAngle = 0.
     for i in range(nhisto):
         angle = numpy.rad2deg(spectrumInfo.twoTheta(i))
         minAngle = min(minAngle, angle)
         maxAngle = max(maxAngle, angle)
     mtd.addOrReplace('inWS', ws)
     outWSName = 'unused'
     outSThetaWName = 'SofThetaW'
     angleStep = 0.2
     algProperties = {
         'InputWorkspace': ws,
         'OutputWorkspace': outWSName,
         'GroupingAngleStep': angleStep,
         'OutputSofThetaEnergyWorkspace': outSThetaWName,
         'Transposing': 'Transposing OFF',
         'rethrow': True
     }
     run_algorithm('DirectILLReduction', **algProperties)
     self.assertTrue(outSThetaWName in mtd)
     SThetaWWS = mtd[outSThetaWName]
     spectrumInfo = SThetaWWS.spectrumInfo()
     firstAngleBin = int(minAngle / angleStep)
     lastAngleBin = int(maxAngle / angleStep) + 1
     expected = lastAngleBin - firstAngleBin
     self.assertEqual(spectrumInfo.size(), expected)
 def test_TotScatCalculateSelfScattering_executes(self):
     raw_ws = WorkspaceCreationHelper.create2DWorkspaceWithFullInstrument(6, 100, True)
     mtd.addOrReplace("tot_scat_test", raw_ws)
     correction_ws = TotScatCalculateSelfScattering(InputWorkspace="tot_scat_test",
                                                    CalFileName=self.cal_file_path,
                                                    SampleGeometry=self.geometry,
                                                    SampleMaterial=self.material)
     self.assertEqual(correction_ws.getNumberHistograms(), 2)
Пример #5
0
 def _cloneTestWorkspace(self, wsName=None):
     if not wsName:
         # Cannot use as default parameter as 'self' is not know in argument list.
         wsName = self._TEST_WS_NAME
     tempName = 'temp_testWS_'
     mtd.addOrReplace(tempName, self._testIN5WS)
     ws = CloneWorkspace(InputWorkspace=tempName, OutputWorkspace=wsName)
     mtd.remove(tempName)
     return ws
 def _cloneTestWorkspace(self, wsName=None):
     if not wsName:
         # Cannot use as default parameter as 'self' is not know in argument list.
         wsName = self._TEST_WS_NAME
     tempName = 'temp_testWS_'
     mtd.addOrReplace(tempName, self._testIN5WS)
     ws = CloneWorkspace(InputWorkspace=tempName,
                         OutputWorkspace=wsName)
     mtd.remove(tempName)
     return ws
 def setUp(self):
     if DirectILLDiagnosticsTest._TEST_WS is None:
         DirectILLDiagnosticsTest._TEST_WS = illhelpers.create_poor_mans_in5_workspace(self._BKG_LEVEL,
                                                                                       illhelpers.default_test_detectors)
     inWSName = 'inputWS'
     mtd.addOrReplace(inWSName, DirectILLDiagnosticsTest._TEST_WS)
     kwargs = {
         'InputWorkspace': DirectILLDiagnosticsTest._TEST_WS,
         'OutputWorkspace': self._TEST_WS_NAME,
         'EPPCreationMethod': 'Fit EPP',
         'FlatBkg': 'Flat Bkg ON',
         'OutputEPPWorkspace': self._EPP_WS_NAME,
         'OutputRawWorkspace': self._RAW_WS_NAME
     }
     run_algorithm('DirectILLCollectData', **kwargs)
     mtd.remove(inWSName)
 def setUp(self):
     if DirectILLDiagnosticsTest._TEST_WS is None:
         DirectILLDiagnosticsTest._TEST_WS = illhelpers.create_poor_mans_in5_workspace(
             self._BKG_LEVEL, illhelpers.default_test_detectors)
     inWSName = 'inputWS'
     mtd.addOrReplace(inWSName, DirectILLDiagnosticsTest._TEST_WS)
     kwargs = {
         'InputWorkspace': DirectILLDiagnosticsTest._TEST_WS,
         'OutputWorkspace': self._TEST_WS_NAME,
         'EPPCreationMethod': 'Fit EPP',
         'FlatBkg': 'Flat Bkg ON',
         'OutputEPPWorkspace': self._EPP_WS_NAME,
         'OutputRawWorkspace': self._RAW_WS_NAME
     }
     run_algorithm('DirectILLCollectData', **kwargs)
     mtd.remove(inWSName)
Пример #9
0
 def testDetectorGrouping(self):
     ws = illhelpers.create_poor_mans_in5_workspace(0.0, _groupingTestDetectors)
     originalNDetectors = ws.getNumberHistograms()
     detectorIds = list()
     for i in range(originalNDetectors):
         detectorIds.append(ws.getDetector(i).getID())
     mtd.addOrReplace('inWS', ws)
     outWSName = 'outWS'
     algProperties = {
         'InputWorkspace': ws,
         'OutputWorkspace': outWSName,
         'Cleanup': 'Cleanup OFF',
         'Transposing': 'Transposing OFF',
         'rethrow': True
     }
     run_algorithm('DirectILLReduction', **algProperties)
     groupedWSName = outWSName + '_grouped_detectors_'
     self.assertTrue(groupedWSName in mtd)
     groupedWS = mtd[groupedWSName]
     self.assertEqual(groupedWS.getNumberHistograms(), 1)
     groupIds = groupedWS.getDetector(0).getDetectorIDs()
     self.assertEqual(collections.Counter(detectorIds), collections.Counter(groupIds))
Пример #10
0
 def setUp(self):
     if not self._testIN5WS:
         self._testIN5WS = illhelpers.create_poor_mans_in5_workspace(self._BKG_LEVEL,
                                                                     illhelpers.default_test_detectors)
     inWSName = 'inputWS'
     mtd.addOrReplace(inWSName, self._testIN5WS)
     kwargs = {
         'InputWorkspace': self._testIN5WS,
         'OutputWorkspace': self._TEST_WS_NAME,
         'OutputEPPWorkspace': self._EPP_WS_NAME
     }
     run_algorithm('DirectILLCollectData', **kwargs)
     kwargs = {
         'InputWorkspace': self._TEST_WS_NAME,
         'OutputWorkspace': self._VANADIUM_WS_NAME,
         'EPPWorkspace': self._EPP_WS_NAME
     }
     run_algorithm('DirectILLIntegrateVanadium', **kwargs)
     vanadiumWS = mtd[self._VANADIUM_WS_NAME]
     for i in range(vanadiumWS.getNumberHistograms()):
         vanadiumYs = vanadiumWS.dataY(i)
         vanadiumYs.fill(1.0)
     mtd.remove(inWSName)
Пример #11
0
 def setUp(self):
     if not self._testIN5WS:
         self._testIN5WS = illhelpers.create_poor_mans_in5_workspace(
             self._BKG_LEVEL, illhelpers.default_test_detectors)
     inWSName = 'inputWS'
     mtd.addOrReplace(inWSName, self._testIN5WS)
     kwargs = {
         'InputWorkspace': self._testIN5WS,
         'OutputWorkspace': self._TEST_WS_NAME,
         'OutputEPPWorkspace': self._EPP_WS_NAME
     }
     run_algorithm('DirectILLCollectData', **kwargs)
     kwargs = {
         'InputWorkspace': self._TEST_WS_NAME,
         'OutputWorkspace': self._VANADIUM_WS_NAME,
         'EPPWorkspace': self._EPP_WS_NAME
     }
     run_algorithm('DirectILLIntegrateVanadium', **kwargs)
     vanadiumWS = mtd[self._VANADIUM_WS_NAME]
     for i in range(vanadiumWS.getNumberHistograms()):
         vanadiumYs = vanadiumWS.dataY(i)
         vanadiumYs.fill(1.0)
     mtd.remove(inWSName)
    def PyExec(self):

        # set up progress reporting
        prog = Progress(self, 0, 1, 10)

        prog.report('Converting to wavelength')
        sample_wave_ws = self._convert_to_wavelength(self._sample_ws)

        prog.report('Calculating sample absorption factors')

        sample_kwargs = dict()
        sample_kwargs.update(self._general_kwargs)
        if self._set_sample_method == 'Chemical Formula':
            sample_kwargs['ChemicalFormula'] = self._sample_chemical_formula
        else:
            sample_kwargs[
                'CoherentXSection'] = self._sample_coherent_cross_section
            sample_kwargs[
                'IncoherentXSection'] = self._sample_incoherent_cross_section
            sample_kwargs[
                'AttenuationXSection'] = self._sample_attenuation_cross_section

        sample_kwargs['DensityType'] = self._sample_density_type
        sample_kwargs['Density'] = self._sample_density

        if self._sample_density_type == 'Number Density':
            sample_kwargs[
                'NumberDensityUnit'] = self._sample_number_density_unit

        sample_kwargs['Height'] = self._height
        sample_kwargs['Shape'] = self._shape

        if self._shape == 'FlatPlate':
            sample_kwargs['Width'] = self._sample_width
            sample_kwargs['Thickness'] = self._sample_thickness
            sample_kwargs['Angle'] = self._sample_angle
            sample_kwargs['Center'] = self._sample_center

        if self._shape == 'Cylinder':
            sample_kwargs['Radius'] = self._sample_radius

        if self._shape == 'Annulus':
            sample_kwargs['InnerRadius'] = self._sample_inner_radius
            sample_kwargs['OuterRadius'] = self._sample_outer_radius

        ss_monte_carlo_alg = self.createChildAlgorithm(
            "SimpleShapeMonteCarloAbsorption", enableLogging=True)
        ss_monte_carlo_alg.setProperty("InputWorkspace", sample_wave_ws)
        self._set_algorithm_properties(ss_monte_carlo_alg, sample_kwargs)
        ss_monte_carlo_alg.execute()
        ass_ws = ss_monte_carlo_alg.getProperty("OutputWorkspace").value

        sample_log_names = []
        sample_log_values = []

        for log_name, log_value in sample_kwargs.items():
            sample_log_names.append("sample_" + log_name.lower())
            sample_log_values.append(log_value)

        ass_ws = self._convert_from_wavelength(ass_ws)
        self._add_sample_log_multiple(ass_ws, sample_log_names,
                                      sample_log_values)

        if not self.isChild():
            mtd.addOrReplace(self._ass_ws_name, ass_ws)

        if self._container_ws:
            prog.report('Calculating container absorption factors')

            container_wave_1 = self._convert_to_wavelength(self._container_ws)
            container_wave_2 = self._clone_ws(container_wave_1)

            container_kwargs = dict()
            container_kwargs.update(self._general_kwargs)
            if self._set_can_method == 'Chemical Formula':
                container_kwargs[
                    'ChemicalFormula'] = self._container_chemical_formula
            else:
                container_kwargs[
                    'CoherentXSection'] = self._container_coherent_cross_section
                container_kwargs[
                    'IncoherentXSection'] = self._container_incoherent_cross_section
                container_kwargs[
                    'AttenuationXSection'] = self._container_attenuation_cross_section

            container_kwargs['DensityType'] = self._container_density_type
            container_kwargs['Density'] = self._container_density
            if self._container_density_type == 'Number Density':
                container_kwargs[
                    'NumberDensityUnit'] = self._container_number_density_unit

            container_kwargs['Height'] = self._height
            container_kwargs['Shape'] = self._shape
            self._set_algorithm_properties(ss_monte_carlo_alg,
                                           container_kwargs)

            if self._shape == 'FlatPlate':
                offset_front = 0.5 * (self._container_front_thickness +
                                      self._sample_thickness)
                ss_monte_carlo_alg.setProperty("InputWorkspace",
                                               container_wave_1)
                ss_monte_carlo_alg.setProperty("Width", self._sample_width)
                ss_monte_carlo_alg.setProperty("Angle", self._sample_angle)
                ss_monte_carlo_alg.setProperty("Thickness",
                                               self._container_front_thickness)
                ss_monte_carlo_alg.setProperty("Center", -offset_front)
                ss_monte_carlo_alg.execute()
                acc_1 = ss_monte_carlo_alg.getProperty("OutputWorkspace").value

                offset_back = 0.5 * (self._container_back_thickness +
                                     self._sample_thickness)
                ss_monte_carlo_alg.setProperty("InputWorkspace",
                                               container_wave_2)
                ss_monte_carlo_alg.setProperty("Thickness",
                                               self._container_back_thickness)
                ss_monte_carlo_alg.setProperty("Center", offset_back)
                ss_monte_carlo_alg.execute()
                acc_2 = ss_monte_carlo_alg.getProperty("OutputWorkspace").value

                acc_ws = self._multiply(acc_1, acc_2)

            elif self._shape == 'Cylinder':
                ss_monte_carlo_alg.setProperty("InputWorkspace",
                                               container_wave_1)
                ss_monte_carlo_alg.setProperty("InnerRadius",
                                               self._container_inner_radius)
                ss_monte_carlo_alg.setProperty("OuterRadius",
                                               self._container_outer_radius)
                ss_monte_carlo_alg.setProperty("Shape", "Annulus")
                ss_monte_carlo_alg.execute()
                acc_ws = ss_monte_carlo_alg.getProperty(
                    "OutputWorkspace").value

            elif self._shape == 'Annulus':
                ss_monte_carlo_alg.setProperty("InputWorkspace",
                                               container_wave_1)
                ss_monte_carlo_alg.setProperty("InnerRadius",
                                               self._container_inner_radius)
                ss_monte_carlo_alg.setProperty("OuterRadius",
                                               self._container_outer_radius)
                ss_monte_carlo_alg.execute()
                acc_1 = ss_monte_carlo_alg.getProperty("OutputWorkspace").value

                ss_monte_carlo_alg.setProperty("InputWorkspace",
                                               container_wave_2)
                ss_monte_carlo_alg.execute()
                acc_2 = ss_monte_carlo_alg.getProperty("OutputWorkspace").value

                acc_ws = self._multiply(acc_1, acc_2)

            for log_name, log_value in container_kwargs.items():
                sample_log_names.append("container_" + log_name.lower())
                sample_log_values.append(log_value)

            acc_ws = self._convert_from_wavelength(acc_ws)

            self._add_sample_log_multiple(acc_ws, sample_log_names,
                                          sample_log_values)

            if not self.isChild():
                mtd.addOrReplace(self._acc_ws_name, acc_ws)

            self._output_ws = self._group_ws([ass_ws, acc_ws])
        else:
            self._output_ws = self._group_ws([ass_ws])

        self.setProperty('CorrectionsWorkspace', self._output_ws)
Пример #13
0
 def setUp(self):
     if not DirectILLCollectDataTest._TEST_WS:
         DirectILLCollectDataTest._TEST_WS = illhelpers.create_poor_mans_in5_workspace(
             self._BKG_LEVEL, illhelpers.default_test_detectors)
     mtd.addOrReplace(self._TEST_WS_NAME, DirectILLCollectDataTest._TEST_WS)
    def PyExec(self):

        # set up progress reporting
        prog = Progress(self, 0, 1, 10)

        prog.report('Converting to wavelength')
        sample_wave_ws = self._convert_to_wavelength(self._sample_ws)

        prog.report('Calculating sample absorption factors')

        sample_kwargs = dict()
        sample_kwargs.update(self._general_kwargs)
        sample_kwargs['ChemicalFormula'] = self._sample_chemical_formula
        sample_kwargs['DensityType'] = self._sample_density_type
        sample_kwargs['Density'] = self._sample_density
        sample_kwargs['Height'] = self._height
        sample_kwargs['Shape'] = self._shape

        if self._shape == 'FlatPlate':
            sample_kwargs['Width'] = self._sample_width
            sample_kwargs['Thickness'] = self._sample_thickness
            sample_kwargs['Angle'] = self._sample_angle
            sample_kwargs['Center'] = self._sample_center

        if self._shape == 'Cylinder':
            sample_kwargs['Radius'] = self._sample_radius

        if self._shape == 'Annulus':
            sample_kwargs['InnerRadius'] = self._sample_inner_radius
            sample_kwargs['OuterRadius'] = self._sample_outer_radius

        ss_monte_carlo_alg = self.createChildAlgorithm("SimpleShapeMonteCarloAbsorption", enableLogging=True)
        ss_monte_carlo_alg.setProperty("InputWorkspace", sample_wave_ws)
        self._set_algorithm_properties(ss_monte_carlo_alg, sample_kwargs)
        ss_monte_carlo_alg.execute()
        ass_ws = ss_monte_carlo_alg.getProperty("OutputWorkspace").value

        sample_log_names = []
        sample_log_values = []

        for log_name, log_value in sample_kwargs.items():
            sample_log_names.append("sample_" + log_name.lower())
            sample_log_values.append(log_value)

        ass_ws = self._convert_from_wavelength(ass_ws)
        self._add_sample_log_multiple(ass_ws, sample_log_names, sample_log_values)

        if not self.isChild():
            mtd.addOrReplace(self._ass_ws_name, ass_ws)

        if self._container_ws:
            prog.report('Calculating container absorption factors')

            container_wave_1 = self._convert_to_wavelength(self._container_ws)
            container_wave_2 = self._clone_ws(container_wave_1)

            container_kwargs = dict()
            container_kwargs.update(self._general_kwargs)
            container_kwargs['ChemicalFormula'] = self._container_chemical_formula
            container_kwargs['DensityType'] = self._container_density_type
            container_kwargs['Density'] = self._container_density
            container_kwargs['Height'] = self._height
            container_kwargs['Shape'] = self._shape
            self._set_algorithm_properties(ss_monte_carlo_alg, container_kwargs)

            if self._shape == 'FlatPlate':
                offset_front = 0.5 * (self._container_front_thickness + self._sample_thickness)
                ss_monte_carlo_alg.setProperty("InputWorkspace", container_wave_1)
                ss_monte_carlo_alg.setProperty("Width", self._sample_width)
                ss_monte_carlo_alg.setProperty("Angle", self._sample_angle)
                ss_monte_carlo_alg.setProperty("Thickness", self._container_front_thickness)
                ss_monte_carlo_alg.setProperty("Center", -offset_front)
                ss_monte_carlo_alg.execute()
                acc_1 = ss_monte_carlo_alg.getProperty("OutputWorkspace").value

                offset_back = 0.5 * (self._container_back_thickness + self._sample_thickness)
                ss_monte_carlo_alg.setProperty("InputWorkspace", container_wave_2)
                ss_monte_carlo_alg.setProperty("Thickness", self._container_back_thickness)
                ss_monte_carlo_alg.setProperty("Center", offset_back)
                ss_monte_carlo_alg.execute()
                acc_2 = ss_monte_carlo_alg.getProperty("OutputWorkspace").value

                acc_ws = self._multiply(acc_1, acc_2)

            elif self._shape == 'Cylinder':
                ss_monte_carlo_alg.setProperty("InputWorkspace", container_wave_1)
                ss_monte_carlo_alg.setProperty("InnerRadius", self._container_inner_radius)
                ss_monte_carlo_alg.setProperty("OuterRadius", self._container_outer_radius)
                ss_monte_carlo_alg.setProperty("Shape", "Annulus")
                ss_monte_carlo_alg.execute()
                acc_ws = ss_monte_carlo_alg.getProperty("OutputWorkspace").value

            elif self._shape == 'Annulus':
                ss_monte_carlo_alg.setProperty("InputWorkspace", container_wave_1)
                ss_monte_carlo_alg.setProperty("InnerRadius", self._container_inner_radius)
                ss_monte_carlo_alg.setProperty("OuterRadius", self._container_outer_radius)
                ss_monte_carlo_alg.execute()
                acc_1 = ss_monte_carlo_alg.getProperty("OutputWorkspace").value

                ss_monte_carlo_alg.setProperty("InputWorkspace", container_wave_2)
                ss_monte_carlo_alg.execute()
                acc_2 = ss_monte_carlo_alg.getProperty("OutputWorkspace").value

                acc_ws = self._multiply(acc_1, acc_2)

            for log_name, log_value in container_kwargs.items():
                sample_log_names.append("container_" + log_name.lower())
                sample_log_values.append(log_value)

            acc_ws = self._convert_from_wavelength(acc_ws)

            self._add_sample_log_multiple(acc_ws, sample_log_names, sample_log_values)

            if not self.isChild():
                mtd.addOrReplace(self._acc_ws_name, acc_ws)

            self._output_ws = self._group_ws([ass_ws, acc_ws])
        else:
            self._output_ws = self._group_ws([ass_ws])

        self.setProperty('CorrectionsWorkspace', self._output_ws)
    def PyExec(self):

        # Set up progress reporting
        n_prog_reports = 2
        if self._can_ws_name is not None:
            n_prog_reports += 1
        prog = Progress(self, 0.0, 1.0, n_prog_reports)

        sample_wave_ws = '__sam_wave'
        convert_unit_alg = self.createChildAlgorithm("ConvertUnits",
                                                     enableLogging=False)
        convert_unit_alg.setProperty("InputWorkspace", self._sample_ws_name)
        convert_unit_alg.setProperty("OutputWorkspace", sample_wave_ws)
        convert_unit_alg.setProperty("Target", 'Wavelength')
        convert_unit_alg.setProperty("EMode", self._emode)
        convert_unit_alg.setProperty("EFixed", self._efixed)
        convert_unit_alg.execute()
        mtd.addOrReplace(sample_wave_ws,
                         convert_unit_alg.getProperty("OutputWorkspace").value)

        prog.report('Calculating sample corrections')
        SetBeam(sample_wave_ws,
                Geometry={
                    'Shape': 'Slit',
                    'Width': self._beam_width,
                    'Height': self._beam_height
                })

        if self._sample_density_type == 'Mass Density':
            sample_mat_list = {
                'ChemicalFormula': self._sample_chemical_formula,
                'SampleMassDensity': self._sample_density
            }
        if self._sample_density_type == 'Number Density':
            sample_mat_list = {
                'ChemicalFormula': self._sample_chemical_formula,
                'SampleNumberDensity': self._sample_density
            }

        SetSample(sample_wave_ws,
                  Geometry={
                      'Shape': 'Cylinder',
                      'Height': self._sample_height,
                      'Radius': self._sample_radius,
                      'Center': [0., 0., 0.]
                  },
                  Material=sample_mat_list)

        prog.report('Calculating sample corrections')
        MonteCarloAbsorption(InputWorkspace=sample_wave_ws,
                             OutputWorkspace=self._ass_ws,
                             EventsPerPoint=self._events,
                             NumberOfWavelengthPoints=self._number_wavelengths,
                             Interpolation='CSpline')

        group = self._ass_ws

        delete_alg = self.createChildAlgorithm("DeleteWorkspace",
                                               enableLogging=False)
        divide_alg = self.createChildAlgorithm("Divide", enableLogging=False)
        minus_alg = self.createChildAlgorithm("Minus", enableLogging=False)

        if self._can_ws_name is not None:
            can_wave_ws = '__can_wave'
            convert_unit_alg.setProperty("InputWorkspace", self._can_ws_name)
            convert_unit_alg.setProperty("OutputWorkspace", can_wave_ws)
            convert_unit_alg.setProperty("Target", 'Wavelength')
            convert_unit_alg.setProperty("EMode", self._emode)
            convert_unit_alg.setProperty("EFixed", self._efixed)
            convert_unit_alg.execute()
            mtd.addOrReplace(
                can_wave_ws,
                convert_unit_alg.getProperty("OutputWorkspace").value)

            if self._can_scale != 1.0:
                logger.information('Scaling can by: %s' % self._can_scale)
                scale_alg = self.createChildAlgorithm("Scale",
                                                      enableLogging=False)
                scale_alg.setProperty("InputWorkspace", can_wave_ws)
                scale_alg.setProperty("OutputWorkspace", can_wave_ws)
                scale_alg.setProperty("Factor", self._can_scale)
                scale_alg.setProperty("Operation", 'Multiply')
                scale_alg.execute()

            can_thickness = self._can_radius - self._sample_radius
            logger.information('Container thickness: ' + str(can_thickness))

            if self._use_can_corrections:
                # Doing can corrections
                prog.report('Calculating container corrections')
                divide_alg.setProperty("LHSWorkspace", sample_wave_ws)
                divide_alg.setProperty("RHSWorkspace", self._ass_ws)
                divide_alg.setProperty("OutputWorkspace", sample_wave_ws)
                divide_alg.execute()

                if self._sample_density_type == 'Mass Density':
                    container_mat_list = {
                        'ChemicalFormula': self._can_chemical_formula,
                        'SampleMassDensity': self._can_density
                    }
                if self._sample_density_type == 'Number Density':
                    container_mat_list = {
                        'ChemicalFormula': self._can_chemical_formula,
                        'SampleNumberDensity': self._can_density
                    }

                SetSample(can_wave_ws,
                          Geometry={
                              'Shape': 'HollowCylinder',
                              'Height': self._sample_height,
                              'InnerRadius': self._sample_radius,
                              'OuterRadius': self._can_radius,
                              'Center': [0., 0., 0.]
                          },
                          Material=container_mat_list)

                MonteCarloAbsorption(
                    InputWorkspace=can_wave_ws,
                    OutputWorkspace=self._acc_ws,
                    EventsPerPoint=self._events,
                    NumberOfWavelengthPoints=self._number_wavelengths,
                    Interpolation='CSpline')

                divide_alg.setProperty("LHSWorkspace", can_wave_ws)
                divide_alg.setProperty("RHSWorkspace", self._acc_ws)
                divide_alg.setProperty("OutputWorkspace", can_wave_ws)
                divide_alg.execute()
                minus_alg.setProperty("LHSWorkspace", sample_wave_ws)
                minus_alg.setProperty("RHSWorkspace", can_wave_ws)
                minus_alg.setProperty("OutputWorkspace", sample_wave_ws)
                minus_alg.execute()
                group += ',' + self._acc_ws

            else:
                # Doing simple can subtraction
                prog.report('Calculating container scaling')
                minus_alg.setProperty("LHSWorkspace", sample_wave_ws)
                minus_alg.setProperty("RHSWorkspace", can_wave_ws)
                minus_alg.setProperty("OutputWorkspace", sample_wave_ws)
                minus_alg.execute()
                divide_alg.setProperty("LHSWorkspace", sample_wave_ws)
                divide_alg.setProperty("RHSWorkspace", self._ass_ws)
                divide_alg.setProperty("OutputWorkspace", sample_wave_ws)
                divide_alg.execute()

            delete_alg.setProperty("Workspace", can_wave_ws)
            delete_alg.execute()

        else:
            divide_alg.setProperty("LHSWorkspace", sample_wave_ws)
            divide_alg.setProperty("RHSWorkspace", self._ass_ws)
            divide_alg.setProperty("OutputWorkspace", sample_wave_ws)
            divide_alg.execute()

        convert_unit_alg.setProperty("InputWorkspace", sample_wave_ws)
        convert_unit_alg.setProperty("OutputWorkspace", self._output_ws)
        convert_unit_alg.setProperty("Target", 'DeltaE')
        convert_unit_alg.setProperty("EMode", self._emode)
        convert_unit_alg.setProperty("EFixed", self._efixed)
        convert_unit_alg.execute()
        mtd.addOrReplace(self._output_ws,
                         convert_unit_alg.getProperty("OutputWorkspace").value)
        delete_alg.setProperty("Workspace", sample_wave_ws)
        delete_alg.execute()

        # Record sample logs
        prog.report('Recording sample logs')
        sample_log_workspaces = [self._output_ws, self._ass_ws]
        sample_logs = [('sample_shape', 'cylinder'),
                       ('sample_filename', self._sample_ws_name),
                       ('sample_radius', self._sample_radius)]

        if self._can_ws_name is not None:
            sample_logs.append(('container_filename', self._can_ws_name))
            sample_logs.append(('container_scale', self._can_scale))
            if self._use_can_corrections:
                sample_log_workspaces.append(self._acc_ws)
                sample_logs.append(('container_thickness', can_thickness))

        log_names = [item[0] for item in sample_logs]
        log_values = [item[1] for item in sample_logs]

        add_sample_log_alg = self.createChildAlgorithm("AddSampleLogMultiple",
                                                       enableLogging=False)
        for ws_name in sample_log_workspaces:
            add_sample_log_alg.setProperty("Workspace", ws_name)
            add_sample_log_alg.setProperty("LogNames", log_names)
            add_sample_log_alg.setProperty("LogValues", log_values)
            add_sample_log_alg.execute()

        self.setProperty('OutputWorkspace', self._output_ws)

        # Output the Abs group workspace if it is wanted, delete if not
        if self._abs_ws == '':
            delete_alg.setProperty("Workspace", self._ass_ws)
            delete_alg.execute()
            if self._can_ws_name is not None and self._use_can_corrections:
                delete_alg.setProperty("Workspace", self._acc_ws)
                delete_alg.execute()

        else:
            GroupWorkspaces(InputWorkspaces=group,
                            OutputWorkspace=self._abs_ws,
                            EnableLogging=False)
            self.setProperty('CorrectionsWorkspace', self._abs_ws)
Пример #16
0
    def PyExec(self):  # noqa C901
        inWS = self.getProperty("InputWorkspace").value
        normWS = self.getProperty("NormalisationWorkspace").value
        _norm = bool(normWS)

        instrument = inWS.getExperimentInfo(0).getInstrument().getName()

        dim0_min, dim0_max, dim0_bins = self.getProperty('BinningDim0').value
        dim1_min, dim1_max, dim1_bins = self.getProperty('BinningDim1').value
        dim2_min, dim2_max, dim2_bins = self.getProperty('BinningDim2').value
        dim0_bins = int(dim0_bins)
        dim1_bins = int(dim1_bins)
        dim2_bins = int(dim2_bins)
        dim0_bin_size = (dim0_max - dim0_min) / dim0_bins
        dim1_bin_size = (dim1_max - dim1_min) / dim1_bins
        dim2_bin_size = (dim2_max - dim2_min) / dim2_bins

        data_array = inWS.getSignalArray(
        )  # getSignalArray returns a F_CONTIGUOUS view of the signal array

        number_of_runs = data_array.shape[2]

        progress = Progress(self, 0.0, 1.0, number_of_runs + 4)

        # Get rotation array
        if instrument == "HB3A":
            omega = np.deg2rad(
                inWS.getExperimentInfo(0).run().getProperty('omega').value)
            chi = np.deg2rad(
                inWS.getExperimentInfo(0).run().getProperty('chi').value)
            phi = np.deg2rad(
                inWS.getExperimentInfo(0).run().getProperty('phi').value)
        else:
            s1 = np.deg2rad(
                inWS.getExperimentInfo(0).run().getProperty('s1').value
            ) + np.deg2rad(self.getProperty("S1Offset").value)

        normaliseBy = self.getProperty("NormaliseBy").value
        if normaliseBy == "Monitor":
            if instrument == "HB3A":
                scale = np.asarray(
                    inWS.getExperimentInfo(0).run().getProperty(
                        'monitor').value)
            else:
                scale = np.asarray(
                    inWS.getExperimentInfo(0).run().getProperty(
                        'monitor_count').value)
        elif normaliseBy == "Time":
            if instrument == "HB3A":
                scale = np.asarray(
                    inWS.getExperimentInfo(0).run().getProperty('time').value)
            else:
                scale = np.asarray(
                    inWS.getExperimentInfo(0).run().getProperty(
                        'duration').value)
        else:
            scale = np.ones(number_of_runs)

        if _norm:
            if normaliseBy == "Monitor":
                if instrument == "HB3A":
                    norm_scale = np.sum(
                        normWS.getExperimentInfo(0).run().getProperty(
                            'monitor').value)
                else:
                    norm_scale = np.sum(
                        normWS.getExperimentInfo(0).run().getProperty(
                            'monitor_count').value)
            elif normaliseBy == "Time":
                if instrument == "HB3A":
                    norm_scale = np.sum(
                        normWS.getExperimentInfo(0).run().getProperty(
                            'time').value)
                else:
                    norm_scale = np.sum(
                        normWS.getExperimentInfo(0).run().getProperty(
                            'duration').value)
            else:
                norm_scale = 1.
            norm_array = normWS.getSignalArray().sum(axis=2)

        W = np.eye(3)
        UBW = np.eye(3)
        if self.getProperty("Frame").value == 'HKL':
            W[:, 0] = self.getProperty('Uproj').value
            W[:, 1] = self.getProperty('Vproj').value
            W[:, 2] = self.getProperty('Wproj').value
            ubWS = self.getProperty("UBWorkspace").value
            if ubWS:
                try:
                    ol = ubWS.sample().getOrientedLattice()
                except AttributeError:
                    ol = ubWS.getExperimentInfo(
                        0).sample().getOrientedLattice()
                logger.notice("Using UB matrix from {} with {}".format(
                    ubWS.name(), ol))
            else:
                ol = inWS.getExperimentInfo(0).sample().getOrientedLattice()
                logger.notice("Using UB matrix from {} with {}".format(
                    inWS.name(), ol))
            UB = ol.getUB()
            UBW = np.dot(UB, W)
            char_dict = {0: '0', 1: '{1}', -1: '-{1}'}
            chars = ['H', 'K', 'L']
            names = [
                '[' + ','.join(
                    char_dict.get(j, '{0}{1}').format(
                        j, chars[np.argmax(np.abs(W[:, i]))])
                    for j in W[:, i]) + ']' for i in range(3)
            ]
            units = 'in {:.3f} A^-1,in {:.3f} A^-1,in {:.3f} A^-1'.format(
                ol.qFromHKL(W[0]).norm(),
                ol.qFromHKL(W[1]).norm(),
                ol.qFromHKL(W[2]).norm())
            frames = 'HKL,HKL,HKL'
            k = 1 / self.getProperty(
                "Wavelength"
            ).value  # Not 2pi/wavelength to save dividing by 2pi later
        else:
            names = 'Q_sample_x,Q_sample_y,Q_sample_z'
            units = 'Angstrom^-1,Angstrom^-1,Angstrom^-1'
            frames = 'QSample,QSample,QSample'
            k = 2 * np.pi / self.getProperty("Wavelength").value

        progress.report('Calculating Qlab for each pixel')
        if inWS.getExperimentInfo(0).run().hasProperty('twotheta'):
            polar = np.array(
                inWS.getExperimentInfo(0).run().getProperty('twotheta').value)
        else:
            di = inWS.getExperimentInfo(0).detectorInfo()
            polar = np.array([
                di.twoTheta(i) for i in range(di.size()) if not di.isMonitor(i)
            ])
            if inWS.getExperimentInfo(0).getInstrument().getName() == 'HB3A':
                polar = polar.reshape(512 * 3, 512).T.flatten()

        if inWS.getExperimentInfo(0).run().hasProperty('twotheta'):
            azim = np.array(
                inWS.getExperimentInfo(0).run().getProperty('azimuthal').value)
        else:
            di = inWS.getExperimentInfo(0).detectorInfo()
            azim = np.array([
                di.azimuthal(i) for i in range(di.size())
                if not di.isMonitor(i)
            ])
            if inWS.getExperimentInfo(0).getInstrument().getName() == 'HB3A':
                azim = azim.reshape(512 * 3, 512).T.flatten()

        qlab = np.vstack(
            (np.sin(polar) * np.cos(azim), np.sin(polar) * np.sin(azim),
             np.cos(polar) - 1)).T * -k  # Kf - Ki(0,0,1)

        progress.report('Calculating Q volume')

        output = np.zeros((dim0_bins + 2, dim1_bins + 2, dim2_bins + 2))
        outputr = output.ravel()

        output_scale = np.zeros_like(output)
        output_scaler = output_scale.ravel()

        if _norm:
            output_norm = np.zeros_like(output)
            output_normr = output_norm.ravel()
            output_norm_scale = np.zeros_like(output)
            output_norm_scaler = output_norm_scale.ravel()

        bin_size = np.array([[dim0_bin_size], [dim1_bin_size],
                             [dim2_bin_size]])

        offset = np.array([[dim0_min / dim0_bin_size],
                           [dim1_min / dim1_bin_size],
                           [dim2_min / dim2_bin_size]]) - 0.5

        assert not data_array[:, :, 0].flags.owndata
        assert not data_array[:, :, 0].ravel('F').flags.owndata
        assert data_array[:, :, 0].flags.fnc

        for n in range(number_of_runs):
            if instrument == "HB3A":
                R1 = np.array([
                    [np.cos(omega[n]), 0, -np.sin(omega[n])],  # omega 0,1,0,-1
                    [0, 1, 0],
                    [np.sin(omega[n]), 0,
                     np.cos(omega[n])]
                ])
                R2 = np.array([
                    [np.cos(chi[n]), np.sin(chi[n]), 0],  # chi 0,0,1,-1
                    [-np.sin(chi[n]), np.cos(chi[n]), 0],
                    [0, 0, 1]
                ])
                R3 = np.array([
                    [np.cos(phi[n]), 0, -np.sin(phi[n])],  # phi 0,1,0,-1
                    [0, 1, 0],
                    [np.sin(phi[n]), 0, np.cos(phi[n])]
                ])
                R = np.dot(np.dot(R1, R2), R3)
            else:
                R = np.array([
                    [np.cos(s1[n]), 0, np.sin(s1[n])],  # s1 0,1,0,1
                    [0, 1, 0],
                    [-np.sin(s1[n]), 0, np.cos(s1[n])]
                ])
            RUBW = np.dot(R, UBW)
            q = np.round(
                np.dot(np.linalg.inv(RUBW), qlab.T) / bin_size -
                offset).astype(np.int)
            q_index = np.ravel_multi_index(
                q, (dim0_bins + 2, dim1_bins + 2, dim2_bins + 2), mode='clip')
            q_uniq, inverse = np.unique(q_index, return_inverse=True)
            outputr[q_uniq] += np.bincount(inverse, data_array[:, :,
                                                               n].ravel('F'))
            output_scaler[q_uniq] += np.bincount(inverse) * scale[n]
            if _norm:
                output_normr[q_uniq] += np.bincount(inverse,
                                                    norm_array.ravel('F'))
                output_norm_scaler[q_uniq] += np.bincount(inverse)

            progress.report()

        if _norm:
            output *= output_norm_scale * norm_scale
            output_norm *= output_scale
        else:
            output_norm = output_scale

        if self.getProperty('KeepTemporaryWorkspaces').value:
            # Create data workspace
            progress.report('Creating data MDHistoWorkspace')
            createWS_alg = self.createChildAlgorithm("CreateMDHistoWorkspace",
                                                     enableLogging=False)
            createWS_alg.setProperty("SignalInput", output[1:-1, 1:-1,
                                                           1:-1].ravel('F'))
            createWS_alg.setProperty(
                "ErrorInput", np.sqrt(output[1:-1, 1:-1, 1:-1].ravel('F')))
            createWS_alg.setProperty("Dimensionality", 3)
            createWS_alg.setProperty(
                "Extents",
                '{},{},{},{},{},{}'.format(dim0_min, dim0_max, dim1_min,
                                           dim1_max, dim2_min, dim2_max))
            createWS_alg.setProperty(
                "NumberOfBins", '{},{},{}'.format(dim0_bins, dim1_bins,
                                                  dim2_bins))
            createWS_alg.setProperty("Names", names)
            createWS_alg.setProperty("Units", units)
            createWS_alg.setProperty("Frames", frames)
            createWS_alg.execute()
            outWS_data = createWS_alg.getProperty("OutputWorkspace").value
            mtd.addOrReplace(
                self.getPropertyValue("OutputWorkspace") + '_data', outWS_data)

            # Create normalisation workspace
            progress.report('Creating norm MDHistoWorkspace')
            createWS_alg = self.createChildAlgorithm("CreateMDHistoWorkspace",
                                                     enableLogging=False)
            createWS_alg.setProperty("SignalInput",
                                     output_norm[1:-1, 1:-1, 1:-1].ravel('F'))
            createWS_alg.setProperty(
                "ErrorInput", np.sqrt(output_norm[1:-1, 1:-1,
                                                  1:-1].ravel('F')))
            createWS_alg.setProperty("Dimensionality", 3)
            createWS_alg.setProperty(
                "Extents",
                '{},{},{},{},{},{}'.format(dim0_min, dim0_max, dim1_min,
                                           dim1_max, dim2_min, dim2_max))
            createWS_alg.setProperty(
                "NumberOfBins", '{},{},{}'.format(dim0_bins, dim1_bins,
                                                  dim2_bins))
            createWS_alg.setProperty("Names", names)
            createWS_alg.setProperty("Units", units)
            createWS_alg.setProperty("Frames", frames)
            createWS_alg.execute()
            mtd.addOrReplace(
                self.getPropertyValue("OutputWorkspace") + '_normalization',
                createWS_alg.getProperty("OutputWorkspace").value)

        old_settings = np.seterr(
            divide='ignore', invalid='ignore'
        )  # Ignore RuntimeWarning: invalid value encountered in true_divide
        output /= output_norm  # We often divide by zero here and we get NaN's, this is desired behaviour
        np.seterr(**old_settings)

        progress.report('Creating MDHistoWorkspace')
        createWS_alg = self.createChildAlgorithm("CreateMDHistoWorkspace",
                                                 enableLogging=False)
        createWS_alg.setProperty("SignalInput", output[1:-1, 1:-1,
                                                       1:-1].ravel('F'))
        createWS_alg.setProperty("ErrorInput",
                                 np.sqrt(output[1:-1, 1:-1, 1:-1].ravel('F')))
        createWS_alg.setProperty("Dimensionality", 3)
        createWS_alg.setProperty(
            "Extents",
            '{},{},{},{},{},{}'.format(dim0_min, dim0_max, dim1_min, dim1_max,
                                       dim2_min, dim2_max))
        createWS_alg.setProperty(
            "NumberOfBins", '{},{},{}'.format(dim0_bins, dim1_bins, dim2_bins))
        createWS_alg.setProperty("Names", names)
        createWS_alg.setProperty("Units", units)
        createWS_alg.setProperty("Frames", frames)
        createWS_alg.execute()
        outWS = createWS_alg.getProperty("OutputWorkspace").value

        # Copy experiment infos
        if inWS.getNumExperimentInfo() > 0:
            outWS.copyExperimentInfos(inWS)

        outWS.getExperimentInfo(0).run().addProperty('RUBW_MATRIX',
                                                     list(UBW.flatten()), True)
        outWS.getExperimentInfo(0).run().addProperty('W_MATRIX',
                                                     list(W.flatten()), True)
        try:
            if outWS.getExperimentInfo(0).sample().hasOrientedLattice():
                outWS.getExperimentInfo(0).sample().getOrientedLattice().setUB(
                    UB)
        except NameError:
            pass

        if self.getProperty('KeepTemporaryWorkspaces').value:
            outWS_data.copyExperimentInfos(outWS)

        progress.report()
        self.setProperty("OutputWorkspace", outWS)
Пример #17
0
    def PyExec(self):
        inWS = self.getProperty("InputWorkspace").value
        normWS = self.getProperty("NormalisationWorkspace").value
        _norm = bool(normWS)

        dim0_min, dim0_max, dim0_bins = self.getProperty('BinningDim0').value
        dim1_min, dim1_max, dim1_bins = self.getProperty('BinningDim1').value
        dim2_min, dim2_max, dim2_bins = self.getProperty('BinningDim2').value
        dim0_bins = int(dim0_bins)
        dim1_bins = int(dim1_bins)
        dim2_bins = int(dim2_bins)
        dim0_bin_size = (dim0_max-dim0_min)/dim0_bins
        dim1_bin_size = (dim1_max-dim1_min)/dim1_bins
        dim2_bin_size = (dim2_max-dim2_min)/dim2_bins

        data_array = inWS.getSignalArray() # getSignalArray returns a F_CONTIGUOUS view of the signal array

        number_of_runs = data_array.shape[2]

        progress = Progress(self, 0.0, 1.0, number_of_runs+4)

        # Get rotation array
        s1 = np.deg2rad(inWS.getExperimentInfo(0).run().getProperty('s1').value) + np.deg2rad(self.getProperty("S1Offset").value)

        normaliseBy = self.getProperty("NormaliseBy").value
        if normaliseBy == "Monitor":
            scale = np.asarray(inWS.getExperimentInfo(0).run().getProperty('monitor_count').value)
        elif normaliseBy == "Time":
            scale = np.asarray(inWS.getExperimentInfo(0).run().getProperty('duration').value)
        else:
            scale = np.ones(number_of_runs)

        if _norm:
            if normaliseBy == "Monitor":
                norm_scale = np.sum(normWS.getExperimentInfo(0).run().getProperty('monitor_count').value)
            elif normaliseBy == "Time":
                norm_scale = np.sum(normWS.getExperimentInfo(0).run().getProperty('duration').value)
            else:
                norm_scale = 1.
            norm_array = normWS.getSignalArray().sum(axis=2)

        W = np.eye(3)
        UBW = np.eye(3)
        if self.getProperty("Frame").value == 'HKL':
            W[:,0] = self.getProperty('Uproj').value
            W[:,1] = self.getProperty('Vproj').value
            W[:,2] = self.getProperty('Wproj').value
            ubWS = self.getProperty("UBWorkspace").value
            if ubWS:
                try:
                    ol = ubWS.sample().getOrientedLattice()
                except AttributeError:
                    ol = ubWS.getExperimentInfo(0).sample().getOrientedLattice()
                logger.notice("Using UB matrix from {} with {}".format(ubWS.name(), ol))
            else:
                ol = inWS.getExperimentInfo(0).sample().getOrientedLattice()
                logger.notice("Using UB matrix from {} with {}".format(inWS.name(), ol))
            UB = ol.getUB()
            UBW = np.dot(UB, W)
            char_dict = {0:'0', 1:'{1}', -1:'-{1}'}
            chars=['H','K','L']
            names = ['['+','.join(char_dict.get(j, '{0}{1}')
                                  .format(j,chars[np.argmax(np.abs(W[:,i]))]) for j in W[:,i])+']' for i in range(3)]
            units = 'in {:.3f} A^-1,in {:.3f} A^-1,in {:.3f} A^-1'.format(ol.qFromHKL(W[0]).norm(),
                                                                          ol.qFromHKL(W[1]).norm(),
                                                                          ol.qFromHKL(W[2]).norm())
            frames = 'HKL,HKL,HKL'
            k = 1/self.getProperty("Wavelength").value # Not 2pi/wavelength to save dividing by 2pi later
        else:
            names = 'Q_sample_x,Q_sample_y,Q_sample_z'
            units = 'Angstrom^-1,Angstrom^-1,Angstrom^-1'
            frames = 'QSample,QSample,QSample'
            k = 2*np.pi/self.getProperty("Wavelength").value

        progress.report('Calculating Qlab for each pixel')
        polar = np.array(inWS.getExperimentInfo(0).run().getProperty('twotheta').value)
        azim = np.array(inWS.getExperimentInfo(0).run().getProperty('azimuthal').value)
        qlab = np.vstack((np.sin(polar)*np.cos(azim),
                          np.sin(polar)*np.sin(azim),
                          np.cos(polar) - 1)).T * -k # Kf - Ki(0,0,1)

        progress.report('Calculating Q volume')

        output = np.zeros((dim0_bins+2, dim1_bins+2, dim2_bins+2))
        outputr = output.ravel()

        output_scale = np.zeros_like(output)
        output_scaler = output_scale.ravel()

        if _norm:
            output_norm = np.zeros_like(output)
            output_normr = output_norm.ravel()
            output_norm_scale = np.zeros_like(output)
            output_norm_scaler = output_norm_scale.ravel()

        bin_size = np.array([[dim0_bin_size],
                             [dim1_bin_size],
                             [dim2_bin_size]])

        offset = np.array([[dim0_min/dim0_bin_size],
                           [dim1_min/dim1_bin_size],
                           [dim2_min/dim2_bin_size]])-0.5

        assert not data_array[:,:,0].flags.owndata
        assert not data_array[:,:,0].ravel('F').flags.owndata
        assert data_array[:,:,0].flags.fnc

        for n in range(number_of_runs):
            R = np.array([[ np.cos(s1[n]), 0, np.sin(s1[n])],
                          [             0, 1,             0],
                          [-np.sin(s1[n]), 0, np.cos(s1[n])]])
            RUBW = np.dot(R,UBW)
            q = np.round(np.dot(np.linalg.inv(RUBW),qlab.T)/bin_size-offset).astype(np.int)
            q_index = np.ravel_multi_index(q, (dim0_bins+2, dim1_bins+2, dim2_bins+2), mode='clip')
            q_uniq, inverse = np.unique(q_index, return_inverse=True)
            outputr[q_uniq] += np.bincount(inverse, data_array[:,:,n].ravel('F'))
            output_scaler[q_uniq] += np.bincount(inverse)*scale[n]
            if _norm:
                output_normr[q_uniq] += np.bincount(inverse, norm_array.ravel('F'))
                output_norm_scaler[q_uniq] += np.bincount(inverse)

            progress.report()

        if _norm:
            output *= output_norm_scale*norm_scale
            output_norm *= output_scale
        else:
            output_norm = output_scale

        if self.getProperty('KeepTemporaryWorkspaces').value:
            # Create data workspace
            progress.report('Creating data MDHistoWorkspace')
            createWS_alg = self.createChildAlgorithm("CreateMDHistoWorkspace", enableLogging=False)
            createWS_alg.setProperty("SignalInput", output[1:-1,1:-1,1:-1].ravel('F'))
            createWS_alg.setProperty("ErrorInput", np.sqrt(output[1:-1,1:-1,1:-1].ravel('F')))
            createWS_alg.setProperty("Dimensionality", 3)
            createWS_alg.setProperty("Extents", '{},{},{},{},{},{}'.format(dim0_min,dim0_max,dim1_min,dim1_max,dim2_min,dim2_max))
            createWS_alg.setProperty("NumberOfBins", '{},{},{}'.format(dim0_bins,dim1_bins,dim2_bins))
            createWS_alg.setProperty("Names", names)
            createWS_alg.setProperty("Units", units)
            createWS_alg.setProperty("Frames", frames)
            createWS_alg.execute()
            outWS_data = createWS_alg.getProperty("OutputWorkspace").value
            mtd.addOrReplace(self.getPropertyValue("OutputWorkspace")+'_data', outWS_data)

            # Create normalisation workspace
            progress.report('Creating norm MDHistoWorkspace')
            createWS_alg = self.createChildAlgorithm("CreateMDHistoWorkspace", enableLogging=False)
            createWS_alg.setProperty("SignalInput", output_norm[1:-1,1:-1,1:-1].ravel('F'))
            createWS_alg.setProperty("ErrorInput", np.sqrt(output_norm[1:-1,1:-1,1:-1].ravel('F')))
            createWS_alg.setProperty("Dimensionality", 3)
            createWS_alg.setProperty("Extents", '{},{},{},{},{},{}'.format(dim0_min,dim0_max,dim1_min,dim1_max,dim2_min,dim2_max))
            createWS_alg.setProperty("NumberOfBins", '{},{},{}'.format(dim0_bins,dim1_bins,dim2_bins))
            createWS_alg.setProperty("Names", names)
            createWS_alg.setProperty("Units", units)
            createWS_alg.setProperty("Frames", frames)
            createWS_alg.execute()
            mtd.addOrReplace(self.getPropertyValue("OutputWorkspace")+'_normalization', createWS_alg.getProperty("OutputWorkspace").value)

        old_settings = np.seterr(divide='ignore', invalid='ignore') # Ignore RuntimeWarning: invalid value encountered in true_divide
        output /= output_norm # We often divide by zero here and we get NaN's, this is desired behaviour
        np.seterr(**old_settings)

        progress.report('Creating MDHistoWorkspace')
        createWS_alg = self.createChildAlgorithm("CreateMDHistoWorkspace", enableLogging=False)
        createWS_alg.setProperty("SignalInput", output[1:-1,1:-1,1:-1].ravel('F'))
        createWS_alg.setProperty("ErrorInput", np.sqrt(output[1:-1,1:-1,1:-1].ravel('F')))
        createWS_alg.setProperty("Dimensionality", 3)
        createWS_alg.setProperty("Extents", '{},{},{},{},{},{}'.format(dim0_min,dim0_max,dim1_min,dim1_max,dim2_min,dim2_max))
        createWS_alg.setProperty("NumberOfBins", '{},{},{}'.format(dim0_bins,dim1_bins,dim2_bins))
        createWS_alg.setProperty("Names", names)
        createWS_alg.setProperty("Units", units)
        createWS_alg.setProperty("Frames", frames)
        createWS_alg.execute()
        outWS = createWS_alg.getProperty("OutputWorkspace").value

        # Copy experiment infos
        if inWS.getNumExperimentInfo() > 0:
            outWS.copyExperimentInfos(inWS)

        outWS.getExperimentInfo(0).run().addProperty('RUBW_MATRIX', list(UBW.flatten()), True)
        outWS.getExperimentInfo(0).run().addProperty('W_MATRIX', list(W.flatten()), True)
        try:
            if outWS.getExperimentInfo(0).sample().hasOrientedLattice():
                outWS.getExperimentInfo(0).sample().getOrientedLattice().setUB(UB)
        except NameError:
            pass

        if self.getProperty('KeepTemporaryWorkspaces').value:
            outWS_data.copyExperimentInfos(outWS)

        progress.report()
        self.setProperty("OutputWorkspace", outWS)
Пример #18
0
    def PyExec(self):

        # Set up progress reporting
        n_prog_reports = 2
        if self._can_ws_name is not None:
            n_prog_reports += 1
        prog = Progress(self, 0.0, 1.0, n_prog_reports)

        sample_wave_ws = '__sam_wave'
        convert_unit_alg = self.createChildAlgorithm("ConvertUnits", enableLogging=False)
        convert_unit_alg.setProperty("InputWorkspace", self._sample_ws_name)
        convert_unit_alg.setProperty("OutputWorkspace", sample_wave_ws)
        convert_unit_alg.setProperty("Target", 'Wavelength')
        convert_unit_alg.setProperty("EMode", self._emode)
        convert_unit_alg.setProperty("EFixed", self._efixed)
        convert_unit_alg.execute()
        mtd.addOrReplace(sample_wave_ws, convert_unit_alg.getProperty("OutputWorkspace").value)

        prog.report('Calculating sample corrections')
        SetBeam(sample_wave_ws,
                Geometry={'Shape': 'Slit',
                          'Width': self._beam_width,
                          'Height': self._beam_height})

        if self._sample_density_type == 'Mass Density':
            sample_mat_list = {'ChemicalFormula': self._sample_chemical_formula,
                               'SampleMassDensity': self._sample_density}
        if self._sample_density_type == 'Number Density':
            sample_mat_list = {'ChemicalFormula': self._sample_chemical_formula,
                               'SampleNumberDensity': self._sample_density}

        SetSample(sample_wave_ws,
                  Geometry={'Shape': 'Cylinder',
                            'Height': self._sample_height,
                            'Radius': self._sample_radius,
                            'Center': [0., 0., 0.]},
                  Material=sample_mat_list)

        prog.report('Calculating sample corrections')
        MonteCarloAbsorption(InputWorkspace=sample_wave_ws,
                             OutputWorkspace=self._ass_ws,
                             EventsPerPoint=self._events,
                             NumberOfWavelengthPoints=self._number_wavelengths,
                             Interpolation='CSpline')

        group = self._ass_ws

        delete_alg = self.createChildAlgorithm("DeleteWorkspace", enableLogging=False)
        divide_alg = self.createChildAlgorithm("Divide", enableLogging=False)
        minus_alg = self.createChildAlgorithm("Minus", enableLogging=False)

        if self._can_ws_name is not None:
            can_wave_ws = '__can_wave'
            convert_unit_alg.setProperty("InputWorkspace", self._can_ws_name)
            convert_unit_alg.setProperty("OutputWorkspace", can_wave_ws)
            convert_unit_alg.setProperty("Target", 'Wavelength')
            convert_unit_alg.setProperty("EMode", self._emode)
            convert_unit_alg.setProperty("EFixed", self._efixed)
            convert_unit_alg.execute()
            mtd.addOrReplace(can_wave_ws, convert_unit_alg.getProperty("OutputWorkspace").value)

            if self._can_scale != 1.0:
                logger.information('Scaling can by: %s' % self._can_scale)
                scale_alg = self.createChildAlgorithm("Scale", enableLogging=False)
                scale_alg.setProperty("InputWorkspace", can_wave_ws)
                scale_alg.setProperty("OutputWorkspace", can_wave_ws)
                scale_alg.setProperty("Factor", self._can_scale)
                scale_alg.setProperty("Operation", 'Multiply')
                scale_alg.execute()

            can_thickness = self._can_radius - self._sample_radius
            logger.information('Container thickness: ' + str(can_thickness))

            if self._use_can_corrections:
                # Doing can corrections
                prog.report('Calculating container corrections')
                divide_alg.setProperty("LHSWorkspace", sample_wave_ws)
                divide_alg.setProperty("RHSWorkspace", self._ass_ws)
                divide_alg.setProperty("OutputWorkspace", sample_wave_ws)
                divide_alg.execute()

                if self._sample_density_type == 'Mass Density':
                    container_mat_list = {'ChemicalFormula': self._can_chemical_formula,
                                          'SampleMassDensity': self._can_density}
                if self._sample_density_type == 'Number Density':
                    container_mat_list = {'ChemicalFormula': self._can_chemical_formula,
                                          'SampleNumberDensity': self._can_density}

                SetSample(can_wave_ws,
                          Geometry={'Shape': 'HollowCylinder',
                                    'Height': self._sample_height,
                                    'InnerRadius': self._sample_radius,
                                    'OuterRadius': self._can_radius,
                                    'Center': [0., 0., 0.]},
                          Material=container_mat_list)

                MonteCarloAbsorption(InputWorkspace=can_wave_ws,
                                     OutputWorkspace=self._acc_ws,
                                     EventsPerPoint=self._events,
                                     NumberOfWavelengthPoints=self._number_wavelengths,
                                     Interpolation='CSpline')

                divide_alg.setProperty("LHSWorkspace", can_wave_ws)
                divide_alg.setProperty("RHSWorkspace", self._acc_ws)
                divide_alg.setProperty("OutputWorkspace", can_wave_ws)
                divide_alg.execute()
                minus_alg.setProperty("LHSWorkspace", sample_wave_ws)
                minus_alg.setProperty("RHSWorkspace", can_wave_ws)
                minus_alg.setProperty("OutputWorkspace", sample_wave_ws)
                minus_alg.execute()
                group += ',' + self._acc_ws

            else:
                # Doing simple can subtraction
                prog.report('Calculating container scaling')
                minus_alg.setProperty("LHSWorkspace", sample_wave_ws)
                minus_alg.setProperty("RHSWorkspace", can_wave_ws)
                minus_alg.setProperty("OutputWorkspace", sample_wave_ws)
                minus_alg.execute()
                divide_alg.setProperty("LHSWorkspace", sample_wave_ws)
                divide_alg.setProperty("RHSWorkspace", self._ass_ws)
                divide_alg.setProperty("OutputWorkspace", sample_wave_ws)
                divide_alg.execute()

            delete_alg.setProperty("Workspace", can_wave_ws)
            delete_alg.execute()

        else:
            divide_alg.setProperty("LHSWorkspace", sample_wave_ws)
            divide_alg.setProperty("RHSWorkspace", self._ass_ws)
            divide_alg.setProperty("OutputWorkspace", sample_wave_ws)
            divide_alg.execute()

        convert_unit_alg.setProperty("InputWorkspace", sample_wave_ws)
        convert_unit_alg.setProperty("OutputWorkspace", self._output_ws)
        convert_unit_alg.setProperty("Target", 'DeltaE')
        convert_unit_alg.setProperty("EMode", self._emode)
        convert_unit_alg.setProperty("EFixed", self._efixed)
        convert_unit_alg.execute()
        mtd.addOrReplace(self._output_ws, convert_unit_alg.getProperty("OutputWorkspace").value)
        delete_alg.setProperty("Workspace", sample_wave_ws)
        delete_alg.execute()

        # Record sample logs
        prog.report('Recording sample logs')
        sample_log_workspaces = [self._output_ws, self._ass_ws]
        sample_logs = [('sample_shape', 'cylinder'),
                       ('sample_filename', self._sample_ws_name),
                       ('sample_radius', self._sample_radius)]

        if self._can_ws_name is not None:
            sample_logs.append(('container_filename', self._can_ws_name))
            sample_logs.append(('container_scale', self._can_scale))
            if self._use_can_corrections:
                sample_log_workspaces.append(self._acc_ws)
                sample_logs.append(('container_thickness', can_thickness))

        log_names = [item[0] for item in sample_logs]
        log_values = [item[1] for item in sample_logs]

        add_sample_log_alg = self.createChildAlgorithm("AddSampleLogMultiple", enableLogging=False)
        for ws_name in sample_log_workspaces:
            add_sample_log_alg.setProperty("Workspace", ws_name)
            add_sample_log_alg.setProperty("LogNames", log_names)
            add_sample_log_alg.setProperty("LogValues", log_values)
            add_sample_log_alg.execute()

        self.setProperty('OutputWorkspace', self._output_ws)

        # Output the Abs group workspace if it is wanted, delete if not
        if self._abs_ws == '':
            delete_alg.setProperty("Workspace", self._ass_ws)
            delete_alg.execute()
            if self._can_ws_name is not None and self._use_can_corrections:
                delete_alg.setProperty("Workspace", self._acc_ws)
                delete_alg.execute()

        else:
            GroupWorkspaces(InputWorkspaces=group,
                            OutputWorkspace=self._abs_ws,
                            EnableLogging=False)
            self.setProperty('CorrectionsWorkspace', self._abs_ws)
Пример #19
0
 def setUp(self):
     if not DirectILLCollectDataTest._TEST_WS:
         DirectILLCollectDataTest._TEST_WS = illhelpers.create_poor_mans_in5_workspace(self._BKG_LEVEL,
                                                                                       illhelpers.default_test_detectors)
     mtd.addOrReplace(self._TEST_WS_NAME, DirectILLCollectDataTest._TEST_WS)