Ticket #11413: IndirectFlatPlateAbsorption.py

File IndirectFlatPlateAbsorption.py, 10.1 KB (added by Dan Nixon, 6 years ago)
Line 
1from mantid.simpleapi import *
2from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, PropertyMode
3from mantid.kernel import StringMandatoryValidator, Direction, logger
4
5
6class IndirectFlatPlateAbsorption(DataProcessorAlgorithm):
7
8    def category(self):
9        return "Workflow\\Inelastic;PythonAlgorithms;CorrectionFunctions\\AbsorptionCorrections;Workflow\\MIDAS"
10
11
12    def summary(self):
13        return "Calculates indirect absorption corrections for a flat sample shape."
14
15
16    def PyInit(self):
17        self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '', direction=Direction.Input),
18                             doc='Sample workspace.')
19        self.declareProperty(name='SampleChemicalFormula', defaultValue='', validator=StringMandatoryValidator(),
20                             doc='Chemical formula for the sample')
21        self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, doc='Sample number density')
22        self.declareProperty(name='SampleHeight', defaultValue=0.0, doc='Sample height')
23        self.declareProperty(name='SampleWidth', defaultValue=0.0, doc='Sample width')
24        self.declareProperty(name='SampleThickness', defaultValue=0.0, doc='Sample thickness')
25
26        self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '', optional=PropertyMode.Optional,
27                                                     direction=Direction.Input),
28                             doc='Container workspace.')
29        self.declareProperty(name='UseCanCorrections', defaultValue=False, doc='Use can corrections in subtraction')
30        self.declareProperty(name='CanChemicalFormula', defaultValue='', validator=StringMandatoryValidator(),
31                             doc='Chemical formula for the Container')
32        self.declareProperty(name='CanNumberDensity', defaultValue=0.1, doc='Container number density')
33        self.declareProperty(name='CanThickness1', defaultValue=0.0, doc='Can thickness1 - front')
34        self.declareProperty(name='CanThickness2', defaultValue=0.0, doc='Can thickness2 - back')
35        self.declareProperty(name='CanScaleFactor', defaultValue=1.0, doc='Scale factor to multiply can data')
36
37        self.declareProperty(name='ElementSize', defaultValue=0.1, doc='Element size in mm')
38        self.declareProperty(name='Plot', defaultValue=False, doc='Plot options')
39
40        self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '', direction=Direction.Output),
41                             doc='The output corrected workspace.')
42
43        self.declareProperty(MatrixWorkspaceProperty('CorrectionsWorkspace', '', direction=Direction.Output,
44                                                     optional=PropertyMode.Optional),
45                             doc='The corrections workspace for scattering and absorptions in sample.')
46
47    def PyExec(self):
48        from IndirectCommon import getEfixed, addSampleLogs
49
50        self._setup()
51        efixed = getEfixed(self._sample_ws)
52
53        sample_wave_ws = '__sam_wave'
54        ConvertUnits(InputWorkspace=self._sample_ws, OutputWorkspace=sample_wave_ws,
55                     Target='Wavelength', EMode='Indirect', EFixed=efixed)
56
57        SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_number_density)
58
59        FlatPlateAbsorption(InputWorkspace=sample_wave_ws,
60                            OutputWorkspace=self._ass_ws,
61                            SampleHeight=self._sample_height,
62                            SampleWidth=self._sample_width,
63                            SampleThickness=self._sample_thickness,
64                            ElementSize=self._element_size,
65                            EMode='Indirect',
66                            EFixed=efixed,
67                            NumberOfWavelengthPoints=10)
68
69        plot_data = [self._output_ws, self._sample_ws]
70        plot_corr = [self._ass_ws]
71        group = self._ass_ws
72
73        if self._can_ws_name is not None:
74            can_wave_ws = '__can_wave'
75            ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can_wave_ws,
76                         Target='Wavelength', EMode='Indirect', EFixed=efixed)
77            if self._can_scale != 1.0:
78                logger.information('Scaling can by: ' + str(self._can_scale))
79                Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply')
80
81            if self._use_can_corrections:
82                Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)
83
84                SetSampleMaterial(can_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_number_density)
85                FlatPlateAbsorption(InputWorkspace=can_wave_ws,
86                                OutputWorkspace=self._acc_ws,
87                                SampleHeight=self._sample_height,
88                                SampleWidth=self._sample_width,
89                                SampleThickness=self._can_thickness1 + self._can_thickness2,
90                                ElementSize=self._element_size,
91                                EMode='Indirect',
92                                EFixed=efixed,
93                                NumberOfWavelengthPoints=10)
94
95                Divide(LHSWorkspace=can_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can_wave_ws)
96                Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws)
97                plot_corr.append(self._acc_ws)
98                group += ',' + self._acc_ws
99
100            else:
101                Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws)
102                Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)
103
104            DeleteWorkspace(can_wave_ws)
105            plot_data.append(self._can_ws_name)
106
107        else:
108            Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)
109
110        ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws,
111                     Target='DeltaE', EMode='Indirect', EFixed=efixed)
112        DeleteWorkspace(sample_wave_ws)
113
114        sample_logs = {'sample_shape': 'flatplate',
115                       'sample_filename': self._sample_ws,
116                       'sample_height': self._sample_height,
117                       'sample_width': self._sample_width,
118                       'sample_thickness': self._sample_thickness,
119                       'element_size': self._element_size}
120        addSampleLogs(self._ass_ws, sample_logs)
121        addSampleLogs(self._output_ws, sample_logs)
122
123        if self._can_ws_name is not None:
124            AddSampleLog(Workspace=self._output_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name))
125            AddSampleLog(Workspace=self._output_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale))
126            if self._use_can_corrections:
127                addSampleLogs(self._acc_ws, sample_logs)
128                AddSampleLog(Workspace=self._acc_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name))
129                AddSampleLog(Workspace=self._acc_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale))
130                AddSampleLog(Workspace=self._output_ws, LogName='can_thickness1', LogType='String', LogText=str(self._can_thickness1))
131                AddSampleLog(Workspace=self._output_ws, LogName='can_thickness2', LogType='String', LogText=str(self._can_thickness2))
132
133        self.setProperty('OutputWorkspace', self._output_ws)
134
135        # Output the Ass workspace if it is wanted, delete if not
136        if self._abs_ws == '':
137            DeleteWorkspace(self._ass_ws)
138            if self._can_ws_name is not None:
139                if self._use_can_corrections:
140                    DeleteWorkspace(self._acc_ws)
141        else:
142            group_name = self._abs_ws + '_abs'
143            GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=group_name)
144            self.setProperty('CorrectionsWorkspace', group_name)
145
146        if self._plot:
147            from IndirectImport import import_mantidplot
148            mantid_plot = import_mantidplot()
149            mantid_plot.plotSpectrum(plot_data, 0)
150            mantid_plot.plotSpectrum(plot_corr, 0)
151
152    def _setup(self):
153        """
154        Get algorithm properties.
155        """
156
157        self._sample_ws = self.getPropertyValue('SampleWorkspace')
158        self._sample_chemical_formula = self.getPropertyValue('SampleChemicalFormula')
159        self._sample_number_density = self.getProperty('SampleNumberDensity').value
160        self._sample_height = self.getProperty('SampleHeight').value
161        self._sample_width = self.getProperty('SampleWidth').value
162        self._sample_thickness = self.getProperty('SampleThickness').value
163
164        self._can_ws_name = self.getPropertyValue('CanWorkspace')
165        if self._can_ws_name == '':
166            self._can_ws_name = None
167        self._use_can_corrections = self.getProperty('UseCanCorrections').value
168        self._can_chemical_formula = self.getPropertyValue('CanChemicalFormula')
169        self._can_number_density = self.getProperty('CanNumberDensity').value
170        self._can_thickness1 = self.getProperty('CanThickness1').value
171        self._can_thickness2 = self.getProperty('CanThickness2').value
172        self._can_scale = self.getProperty('CanScaleFactor').value
173
174        self._element_size = self.getProperty('ElementSize').value
175        self._plot = self.getProperty('Plot').value
176        self._output_ws = self.getPropertyValue('OutputWorkspace')
177
178        self._abs_ws = self.getPropertyValue('CorrectionsWorkspace')
179        if self._abs_ws == '':
180            self._ass_ws = '__ass'
181            self._acc_ws = '__acc'
182        else:
183            self._ass_ws = self._abs_ws + '_ass'
184            self._acc_ws = self._abs_ws + '_acc'
185
186# Register algorithm with Mantid
187AlgorithmFactory.subscribe(IndirectFlatPlateAbsorption)