Ejemplo n.º 1
0
 def _selfShielding(self, mainWS):
     """Return the self shielding corrections."""
     wavelengthWSName = self._names.withSuffix('input_in_wavelength')
     wavelengthWS = ConvertUnits(InputWorkspace=mainWS,
                                 OutputWorkspace=wavelengthWSName,
                                 Target='Wavelength',
                                 EMode='Direct',
                                 EnableLogging=self._subalgLogging)
     eventsPerPoint = self.getProperty(
         common.PROP_EVENTS_PER_WAVELENGTH).value
     correctionWSName = self._names.withSuffix('correction')
     useFullInstrument = self.getProperty(
         common.PROP_SIMULATION_INSTRUMENT
     ).value == common.SIMULATION_INSTRUMENT_FULL
     if useFullInstrument:
         correctionWS = MonteCarloAbsorption(
             InputWorkspace=wavelengthWS,
             OutputWorkspace=correctionWSName,
             SparseInstrument=False,
             Interpolation='CSpline',
             EnableLogging=self._subalgLogging,
             EventsPerPoint=eventsPerPoint,
             SeedValue=common.SIMULATION_SEED)
     else:
         rows = self.getProperty(common.PROP_SPARSE_INSTRUMENT_ROWS).value
         columns = self.getProperty(
             common.PROP_SPARSE_INSTRUMENT_COLUMNS).value
         correctionWS = MonteCarloAbsorption(
             InputWorkspace=wavelengthWS,
             OutputWorkspace=correctionWSName,
             SparseInstrument=True,
             NumberOfDetectorRows=rows,
             NumberOfDetectorColumns=columns,
             Interpolation='CSpline',
             EnableLogging=self._subalgLogging,
             EventsPerPoint=eventsPerPoint,
             SeedValue=common.SIMULATION_SEED)
     self._cleanup.cleanup(wavelengthWS)
     correctionWS = ConvertUnits(InputWorkspace=correctionWS,
                                 OutputWorkspace=correctionWSName,
                                 Target='TOF',
                                 EMode='Direct',
                                 EnableLogging=self._subalgLogging)
     return correctionWS
    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)
    def PyExec(self):
        # setup progress reporting
        prog = Progress(self, 0.0, 1.0, 3)

        prog.report('Setting up sample environment')

        # set the beam shape
        SetBeam(self._input_ws_name,
                Geometry={
                    'Shape': 'Slit',
                    'Width': self._beam_width,
                    'Height': self._beam_height
                })

        # set the sample geometry
        sample_geometry = dict()
        sample_geometry['Height'] = self._height

        if self._shape == 'FlatPlate':
            sample_geometry['Shape'] = 'FlatPlate'
            sample_geometry['Width'] = self._width
            sample_geometry['Thick'] = self._thickness
            sample_geometry['Center'] = [0.0, 0.0, self._center]
            sample_geometry['Angle'] = self._angle

        if self._shape == 'Cylinder':
            sample_geometry['Shape'] = 'Cylinder'
            sample_geometry['Radius'] = self._radius
            sample_geometry['Center'] = [0.0, 0.0, 0.0]

        if self._shape == 'Annulus':
            sample_geometry['Shape'] = 'HollowCylinder'
            sample_geometry['InnerRadius'] = self._inner_radius
            sample_geometry['OuterRadius'] = self._outer_radius
            sample_geometry['Center'] = [0.0, 0.0, 0.0]
            sample_geometry['Axis'] = 1

        # set sample
        if self._material_defined:
            # set sample without sample material
            SetSample(InputWorkspace=self._input_ws_name,
                      Geometry=sample_geometry)

        else:
            # set the sample material
            sample_material = dict()
            sample_material['ChemicalFormula'] = self._chemical_formula

            if self._density_type == 'Mass Density':
                sample_material['SampleMassDensity'] = self._density
            if self._density_type == 'Number Density':
                sample_material['SampleNumberDensity'] = self._density

            SetSample(InputWorkspace=self._input_ws_name,
                      Geometry=sample_geometry,
                      Material=sample_material)

        prog.report('Calculating sample corrections')

        MonteCarloAbsorption(InputWorkspace=self._input_ws_name,
                             OutputWorkspace=self._output_ws,
                             EventsPerPoint=self._events,
                             NumberOfWavelengthPoints=self._number_wavelengths,
                             Interpolation=self._interpolation)

        prog.report('Recording Sample Logs')

        log_names = ['beam_height', 'beam_width']
        log_values = [self._beam_height, self._beam_width]

        # add sample geometry to sample logs
        for key, value in sample_geometry.items():
            log_names.append('sample_' + key.lower())
            log_values.append(value)

        add_sample_log_alg = self.createChildAlgorithm('AddSampleLogMultiple',
                                                       enableLogging=False)
        add_sample_log_alg.setProperty('Workspace', self._output_ws)
        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)