diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderILLDetectorScan.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderILLDetectorScan.py
index 929586d9c9b3a907fcac21080456df303d590498..7ff56f0de7ab377883be56492fc11534b4a96b40 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderILLDetectorScan.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderILLDetectorScan.py
@@ -8,8 +8,7 @@ from __future__ import (absolute_import, division, print_function)
 
 from mantid.kernel import CompositeValidator, Direction, FloatArrayLengthValidator, FloatArrayOrderedPairsValidator, \
     FloatArrayProperty, StringListValidator, IntBoundedValidator
-from mantid.api import DataProcessorAlgorithm, MultipleFileProperty, Progress, WorkspaceGroupProperty, FileProperty, \
-    FileAction
+from mantid.api import DataProcessorAlgorithm, MultipleFileProperty, Progress, WorkspaceGroupProperty, FileProperty, FileAction
 from mantid.simpleapi import *
 
 
@@ -28,7 +27,7 @@ class PowderILLDetectorScan(DataProcessorAlgorithm):
         return 'Performs powder diffraction data reduction for D2B and D20 (when doing a detector scan).'
 
     def seeAlso(self):
-        return ["PowderILLParameterScan", "PowderILLEfficiency"]
+        return [ "PowderILLParameterScan", "PowderILLEfficiency" ]
 
     def name(self):
         return "PowderILLDetectorScan"
@@ -123,9 +122,9 @@ class PowderILLDetectorScan(DataProcessorAlgorithm):
             end_bottom = start_bottom + n_pix - 1
             start_top = (tube + 1) * n_pixels - n_pix + 1
             end_top = start_top + n_pix - 1
-            mask += str(start_bottom) + '-' + str(end_bottom) + ','
-            mask += str(start_top) + '-' + str(end_top) + ','
-        self.log().debug('Preparing to mask with DetectorList=' + mask[:-1])
+            mask += str(start_bottom)+'-'+str(end_bottom)+','
+            mask += str(start_top)+'-'+str(end_top)+','
+        self.log().debug('Preparing to mask with DetectorList='+mask[:-1])
         return mask[:-1]
 
     def _reduce_1D(self, input_group):
@@ -147,8 +146,8 @@ class PowderILLDetectorScan(DataProcessorAlgorithm):
                                             OutputWorkspace=output2DtubesName)
         if self._final_mask != 0:
             nSpec = mtd[output2DtubesName].getNumberHistograms()
-            mask_list = '0-{0},{1}-{2}'.format(self._final_mask, nSpec - self._final_mask, nSpec - 1)
-            MaskDetectors(Workspace=output2DtubesName, WorkspaceIndexList=mask_list)
+            mask_list = '0-{0},{1}-{2}'.format(self._final_mask,nSpec-self._final_mask,nSpec-1)
+            MaskDetectors(Workspace=output2DtubesName,WorkspaceIndexList=mask_list)
 
         return output2DTubes
 
@@ -159,26 +158,32 @@ class PowderILLDetectorScan(DataProcessorAlgorithm):
                                        HeightAxis=self._height_range,
                                        MirrorScatteringAngles=self._mirror,
                                        CropNegativeScatteringAngles=self._crop_negative,
-                                       OutputWorkspace=output2DName)
+                                       OutputWorkspace = output2DName)
         if self._final_mask != 0:
             nSpec = mtd[output2DName].getNumberHistograms()
-            mask_list = '0-{0},{1}-{2}'.format(self._final_mask, nSpec - self._final_mask, nSpec - 1)
-            MaskDetectors(Workspace=output2DName, WorkspaceIndexList=mask_list)
+            mask_list = '0-{0},{1}-{2}'.format(self._final_mask,nSpec-self._final_mask,nSpec-1)
+            MaskDetectors(Workspace=output2DName,WorkspaceIndexList=mask_list)
 
         return output2D
 
-    def _apply_calibration(self, input_group):
-        calib_file = self.getPropertyValue('CalibrationFile')
-        if calib_file:
-            self._progress.report('Applying detector efficiencies')
-            LoadNexusProcessed(Filename=calib_file, OutputWorkspace='__det_eff')
-            for ws in input_group:
-                name = ws.name()
-                ExtractMonitors(InputWorkspace=name, DetectorWorkspace=name)
-                ApplyDetectorScanEffCorr(InputWorkspace=name, DetectorEfficiencyWorkspace='__det_eff',
-                                         OutputWorkspace=name)
+    def PyExec(self): # noqa C901
+        data_type = 'Raw'
+        if self.getProperty('UseCalibratedData').value:
+            data_type = 'Calibrated'
+        align_tubes = self.getProperty('AlignTubes').value
 
-    def _check_instrument(self, instrument):
+        self._progress = Progress(self, start=0.0, end=1.0, nreports=6)
+        self._progress.report('Loading data')
+        # Do not merge the runs yet, since it will break the calibration
+        # Load and calibrate separately, then SumOverlappingTubes will merge correctly
+        # Besides + here does not make sense, and it will also slow down D2B a lot
+        input_workspace = LoadAndMerge(Filename=self.getPropertyValue('Run').replace('+', ','),
+                                       LoaderName='LoadILLDiffraction',
+                                       LoaderOptions={'DataType': data_type, 'AlignTubes': align_tubes})
+        # We might already have a group, but group just in case
+        input_group = GroupWorkspaces(InputWorkspaces=input_workspace)
+
+        instrument = input_group[0].getInstrument()
         supported_instruments = ['D2B', 'D20']
         if instrument.getName() not in supported_instruments:
             self.log.warning('Running for unsupported instrument, use with caution. Supported instruments are: '
@@ -189,14 +194,21 @@ class PowderILLDetectorScan(DataProcessorAlgorithm):
             if self.getProperty('Output2D').value:
                 raise RuntimeError('Output2D is not supported for D20 (1D detector)')
 
-    def _component_cropping(self, input_group):
-        components = self.getPropertyValue('ComponentsToReduce')
-        if components:
+        self._progress.report('Normalising to monitor')
+        if self.getPropertyValue('NormaliseTo') == 'Monitor':
+            input_group = NormaliseToMonitor(InputWorkspace=input_group, MonitorID=0)
+            if instrument.getName() == 'D2B':
+                input_group = Scale(InputWorkspace=input_group, Factor=1e+6)
+
+        calib_file = self.getPropertyValue('CalibrationFile')
+        if calib_file:
+            self._progress.report('Applying detector efficiencies')
+            LoadNexusProcessed(Filename=calib_file, OutputWorkspace='__det_eff')
             for ws in input_group:
-                CropToComponent(InputWorkspace=ws.getName(), OutputWorkspace=ws.getName(),
-                                ComponentNames=components)
+                name = ws.getName()
+                ExtractMonitors(InputWorkspace=name, DetectorWorkspace=name)
+                ApplyDetectorScanEffCorr(InputWorkspace=name,DetectorEfficiencyWorkspace='__det_eff',OutputWorkspace=name)
 
-    def _do_masking(self, input_group):
         pixels_to_mask = self.getProperty('InitialMask').value
         if pixels_to_mask != 0:
             mask = self._generate_mask(pixels_to_mask, input_group[0].getInstrument())
@@ -207,21 +219,6 @@ class PowderILLDetectorScan(DataProcessorAlgorithm):
             for ws in input_group:
                 MaskDetectors(Workspace=ws, ComponentList=components_to_mask)
 
-    def _do_reduction(self, input_group, output_workspaces):
-        self._progress.report('Doing Output2DTubes Option')
-        if self.getProperty('Output2DTubes').value:
-            output2DTubes = self._reduce_2DTubes(input_group)
-            output_workspaces.append(output2DTubes)
-        self._progress.report('Doing Output2D Option')
-        if self.getProperty('Output2D').value:
-            output2D = self._reduce_2D(input_group)
-            output_workspaces.append(output2D)
-        self._progress.report('Doing Output1D Option')
-        if self.getProperty('Output1D').value:
-            output1D = self._reduce_1D(input_group)
-            output_workspaces.append(output1D)
-
-    def _get_height_range(self):
         height_range_prop = self.getProperty('HeightRange').value
         if len(height_range_prop) == 0:
             run = mtd["input_group"].getItem(0).getRun()
@@ -231,40 +228,6 @@ class PowderILLDetectorScan(DataProcessorAlgorithm):
                 self._height_range = str(-maxHeight) + ',' + str(pixelHeight) + ',' + str(maxHeight)
         elif len(height_range_prop) == 2:
             self._height_range = str(height_range_prop[0]) + ', ' + str(height_range_prop[1])
-
-    def _normalise_input(self, input_group, instrument):
-        self._progress.report('Normalising to monitor')
-        if self.getPropertyValue('NormaliseTo') == 'Monitor':
-            input_group = NormaliseToMonitor(InputWorkspace=input_group, MonitorID=0)
-            if instrument.getName() == 'D2B':
-                input_group = Scale(InputWorkspace=input_group, Factor=1e+6)
-        return input_group
-
-    def PyExec(self):
-        data_type = 'Raw'
-        if self.getProperty('UseCalibratedData').value:
-            data_type = 'Calibrated'
-        align_tubes = self.getProperty('AlignTubes').value
-
-        self._progress = Progress(self, start=0.0, end=1.0, nreports=6)
-        self._progress.report('Loading data')
-        # Do not merge the runs yet, since it will break the calibration
-        # Load and calibrate separately, then SumOverlappingTubes will merge correctly
-        # Besides + here does not make sense, and it will also slow down D2B a lot
-        input_workspace = LoadAndMerge(Filename=self.getPropertyValue('Run').replace('+', ','),
-                                       LoaderName='LoadILLDiffraction',
-                                       LoaderOptions={'DataType': data_type, 'AlignTubes': align_tubes})
-        # We might already have a group, but group just in case
-        input_group = GroupWorkspaces(InputWorkspaces=input_workspace)
-
-        instrument = input_group[0].getInstrument()
-        self._check_instrument(instrument)
-
-        input_group = self._normalise_input(input_group, instrument)
-        self._apply_calibration(input_group)
-        self._do_masking(input_group)
-        self._get_height_range()
-
         output_workspaces = []
         self._out_ws_name = self.getPropertyValue('OutputWorkspace')
         self._mirror = False
@@ -272,15 +235,32 @@ class PowderILLDetectorScan(DataProcessorAlgorithm):
         if instrument.hasParameter("mirror_scattering_angles"):
             self._mirror = instrument.getBoolParameter("mirror_scattering_angles")[0]
         self._final_mask = self.getProperty('FinalMask').value
-        self._component_cropping(input_group)
 
-        self._do_reduction(input_group, output_workspaces)
+        components = self.getPropertyValue('ComponentsToReduce')
+        if components:
+            for ws in input_group:
+                CropToComponent(InputWorkspace=ws.getName(), OutputWorkspace=ws.getName(),
+                                ComponentNames=components)
+
+        self._progress.report('Doing Output2DTubes Option')
+        if self.getProperty('Output2DTubes').value:
+            output2DTubes = self._reduce_2DTubes(input_group)
+            output_workspaces.append(output2DTubes)
+
+        self._progress.report('Doing Output2D Option')
+        if self.getProperty('Output2D').value:
+            output2D = self._reduce_2D(input_group)
+            output_workspaces.append(output2D)
+
+        self._progress.report('Doing Output1D Option')
+        if self.getProperty('Output1D').value:
+            output1D = self._reduce_1D(input_group)
+            output_workspaces.append(output1D)
 
         self._progress.report('Finishing up...')
         DeleteWorkspace('input_group')
         GroupWorkspaces(InputWorkspaces=output_workspaces, OutputWorkspace=self._out_ws_name)
         self.setProperty('OutputWorkspace', self._out_ws_name)
 
-
 # Register the algorithm with Mantid
 AlgorithmFactory.subscribe(PowderILLDetectorScan)
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSILLReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSILLReduction.py
index 551e95ab012988d5cd1448a16bb82a292e9eec42..f0b2ff9239d4c27f4a604a488049f53992a68616 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSILLReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSILLReduction.py
@@ -7,14 +7,14 @@
 from __future__ import (absolute_import, division, print_function)
 
 from mantid.api import PythonAlgorithm, MatrixWorkspaceProperty, MultipleFileProperty, PropertyMode, Progress
-from mantid.kernel import Direction, EnabledWhenProperty, FloatBoundedValidator, LogicOperator, PropertyCriterion, \
-    StringListValidator
+from mantid.kernel import Direction, EnabledWhenProperty, FloatBoundedValidator, LogicOperator, PropertyCriterion, StringListValidator
 from mantid.simpleapi import *
 from math import fabs
 import numpy as np
 
 
 class SANSILLReduction(PythonAlgorithm):
+
     _mode = 'Monochromatic'
     _instrument = None
 
@@ -45,7 +45,7 @@ class SANSILLReduction(PythonAlgorithm):
             @param ws2 : workspace 2
             @return true if the detector distance difference is less than 1 cm
         """
-        tolerance = 0.01  # m
+        tolerance = 0.01 #m
         l2_1 = ws1.getRun().getLogData('L2').value
         l2_2 = ws2.getRun().getLogData('L2').value
         return fabs(l2_1 - l2_2) < tolerance
@@ -100,8 +100,7 @@ class SANSILLReduction(PythonAlgorithm):
 
         self.setPropertySettings('BeamFinderMethod', beam)
 
-        self.declareProperty('SampleThickness', 0.1, validator=FloatBoundedValidator(lower=0.),
-                             doc='Sample thickness [cm]')
+        self.declareProperty('SampleThickness', 0.1, validator=FloatBoundedValidator(lower=0.), doc='Sample thickness [cm]')
 
         self.setPropertySettings('SampleThickness', EnabledWhenProperty(sample, reference, LogicOperator.Or))
 
@@ -214,7 +213,7 @@ class SANSILLReduction(PythonAlgorithm):
             if mtd[ws].getRun().hasProperty('timer'):
                 duration = mtd[ws].getRun().getLogData('timer').value
                 if duration != 0.:
-                    Scale(InputWorkspace=ws, Factor=1. / duration, OutputWorkspace=ws)
+                    Scale(InputWorkspace=ws, Factor=1./duration, OutputWorkspace=ws)
                     self._dead_time_correction(ws)
                 else:
                     raise RuntimeError('Unable to normalise to time; duration found is 0 seconds.')
@@ -239,112 +238,6 @@ class SANSILLReduction(PythonAlgorithm):
         else:
             self.log().information('No tau available in IPF, skipping dead time correction.')
 
-    def _check_absorber_workspace_processing(self, ws):
-        absorber_ws = self.getProperty('AbsorberInputWorkspace').value
-        if absorber_ws:
-            if not self._check_processed_flag(absorber_ws, 'Absorber'):
-                self.log().warning('Absorber input workspace is not processed as absorber.')
-            Minus(LHSWorkspace=ws, RHSWorkspace=absorber_ws, OutputWorkspace=ws)
-
-    def _check_beam_workspace_processing(self, ws):
-        beam_ws = self.getProperty('BeamInputWorkspace').value
-        if beam_ws:
-            if not self._check_processed_flag(beam_ws, 'Beam'):
-                self.log().warning('Beam input workspace is not processed as beam.')
-            if self._mode != 'TOF':
-                beam_x = beam_ws.getRun().getLogData('BeamCenterX').value
-                beam_y = beam_ws.getRun().getLogData('BeamCenterY').value
-                AddSampleLog(Workspace=ws, LogName='BeamCenterX', LogText=str(beam_x), LogType='Number')
-                AddSampleLog(Workspace=ws, LogName='BeamCenterY', LogText=str(beam_y), LogType='Number')
-                MoveInstrumentComponent(Workspace=ws, X=-beam_x, Y=-beam_y, ComponentName='detector')
-            if not self._check_distances_match(mtd[ws], beam_ws):
-                self.log().warning('Different detector distances found for empty beam and sample runs!')
-        return beam_ws
-
-    def _check_container_workspace_processing(self, container_ws, ws):
-        if container_ws:
-            if not self._check_processed_flag(container_ws, 'Container'):
-                self.log().warning('Container input workspace is not processed as container.')
-            if not self._check_distances_match(mtd[ws], container_ws):
-                self.log().warning(
-                    'Different detector distances found for container and sample runs!')
-            Minus(LHSWorkspace=ws, RHSWorkspace=container_ws, OutputWorkspace=ws)
-
-    def _check_reference_workspace_processing(self, beam_ws, ws):
-        reference_ws = self.getProperty('ReferenceInputWorkspace').value
-        coll_ws = None
-        if reference_ws:
-            if not self._check_processed_flag(reference_ws, 'Reference'):
-                self.log().warning('Reference input workspace is not processed as reference.')
-            Divide(LHSWorkspace=ws, RHSWorkspace=reference_ws, OutputWorkspace=ws)
-            coll_ws = reference_ws
-        else:
-            self._check_sensitivity_workspace_processing(ws)
-            flux_in = self.getProperty('FluxInputWorkspace').value
-            if flux_in:
-                coll_ws = beam_ws
-                flux_ws = ws + '_flux'
-                if self._mode == 'TOF':
-                    RebinToWorkspace(WorkspaceToRebin=flux_in, WorkspaceToMatch=ws, OutputWorkspace=flux_ws)
-                    Divide(LHSWorkspace=ws, RHSWorkspace=flux_ws, OutputWorkspace=ws)
-                    DeleteWorkspace(flux_ws)
-                else:
-                    Divide(LHSWorkspace=ws, RHSWorkspace=flux_in, OutputWorkspace=ws)
-        return coll_ws
-
-    def _check_sensitivity_workspace_processing(self, ws):
-        sensitivity_in = self.getProperty('SensitivityInputWorkspace').value
-        if sensitivity_in:
-            if not self._check_processed_flag(sensitivity_in, 'Sensitivity'):
-                self.log().warning('Sensitivity input workspace is not processed as sensitivity.')
-            Divide(LHSWorkspace=ws, RHSWorkspace=sensitivity_in, OutputWorkspace=ws)
-
-    def _check_transmission_workspace_processing(self, ws):
-        transmission_ws = self.getProperty('TransmissionInputWorkspace').value
-        if transmission_ws:
-            if not self._check_processed_flag(transmission_ws, 'Transmission'):
-                self.log().warning('Transmission input workspace is not processed as transmission.')
-            if transmission_ws.blocksize() == 1:
-                # monochromatic mode, scalar transmission
-                transmission = transmission_ws.readY(0)[0]
-                transmission_err = transmission_ws.readE(0)[0]
-                ApplyTransmissionCorrection(InputWorkspace=ws, TransmissionValue=transmission,
-                                            TransmissionError=transmission_err, OutputWorkspace=ws)
-            else:
-                # wavelenght dependent transmission, need to rebin
-                transmission_rebinned = ws + '_tr_rebinned'
-                RebinToWorkspace(WorkspaceToRebin=transmission_ws, WorkspaceToMatch=ws,
-                                 OutputWorkspace=transmission_rebinned)
-                ApplyTransmissionCorrection(InputWorkspace=ws, TransmissionWorkspace=transmission_rebinned,
-                                            OutputWorkspace=ws)
-                DeleteWorkspace(transmission_rebinned)
-
-    def _create_sensitivity_out(self, ws):
-        sensitivity_out = self.getPropertyValue('SensitivityOutputWorkspace')
-        if sensitivity_out:
-            CalculateEfficiency(InputWorkspace=ws, OutputWorkspace=sensitivity_out)
-            mtd[sensitivity_out].getRun().addProperty('ProcessedAs', 'Sensitivity', True)
-            self.setProperty('SensitivityOutputWorkspace', mtd[sensitivity_out])
-
-    def _do_masking(self, ws):
-        mask_ws = self.getProperty('MaskedInputWorkspace').value
-        if mask_ws:
-            masked_ws = ws + '_mask'
-            CloneWorkspace(InputWorkspace=mask_ws, OutputWorkspace=masked_ws)
-            ExtractMonitors(InputWorkspace=masked_ws, DetectorWorkspace=masked_ws)
-            MaskDetectors(Workspace=ws, MaskedWorkspace=masked_ws)
-            DeleteWorkspace(masked_ws)
-
-    def _parallax_correction(self, ws):
-        if self._instrument in ['D22', 'D22lr', 'D33']:
-            self.log().information('Performing parallax correction')
-            if self._instrument == 'D33':
-                components = ['back_detector', 'front_detector_top', 'front_detector_bottom',
-                              'front_detector_left', 'front_detector_right']
-            else:
-                components = ['detector']
-            ParallaxCorrection(InputWorkspace=ws, OutputWorkspace=ws, ComponentNames=components)
-
     def _process_beam(self, ws):
         """
             Calculates the beam center's x,y coordinates, and the beam flux
@@ -353,10 +246,9 @@ class SANSILLReduction(PythonAlgorithm):
         centers = ws + '_centers'
         method = self.getPropertyValue('BeamFinderMethod')
         radius = self.getProperty('BeamRadius').value
-        FindCenterOfMassPosition(InputWorkspace=ws, DirectBeam=(method == 'DirectBeam'), BeamRadius=radius,
-                                 Output=centers)
-        beam_x = mtd[centers].cell(0, 1)
-        beam_y = mtd[centers].cell(1, 1)
+        FindCenterOfMassPosition(InputWorkspace=ws, DirectBeam=(method == 'DirectBeam'), BeamRadius=radius, Output=centers)
+        beam_x = mtd[centers].cell(0,1)
+        beam_y = mtd[centers].cell(1,1)
         AddSampleLog(Workspace=ws, LogName='BeamCenterX', LogText=str(beam_x), LogType='Number')
         AddSampleLog(Workspace=ws, LogName='BeamCenterY', LogText=str(beam_y), LogType='Number')
         DeleteWorkspace(centers)
@@ -369,12 +261,11 @@ class SANSILLReduction(PythonAlgorithm):
             att_value = run.getLogData('attenuator.attenuation_value').value
             if float(att_value) < 10. and self._instrument == 'D33':
                 instrument = mtd[ws].getInstrument()
-                param = 'att' + str(int(att_value))
+                param = 'att'+str(int(att_value))
                 if instrument.hasParameter(param):
                     att_coeff = instrument.getNumberParameter(param)[0]
                 else:
-                    raise RuntimeError(
-                        'Unable to find the attenuation coefficient for D33 attenuator #' + str(int(att_value)))
+                    raise RuntimeError('Unable to find the attenuation coefficient for D33 attenuator #'+str(int(att_value)))
             else:
                 att_coeff = att_value
         else:
@@ -395,45 +286,12 @@ class SANSILLReduction(PythonAlgorithm):
             RenameWorkspace(InputWorkspace=flux, OutputWorkspace=flux_out)
             self.setProperty('FluxOutputWorkspace', mtd[flux_out])
 
-    def _process_sample(self, beam_ws, ws):
-        coll_ws = self._check_reference_workspace_processing(beam_ws, ws)
-        if coll_ws:
-            if not self._check_distances_match(mtd[ws], coll_ws):
-                self.log().warning(
-                    'Different detector distances found for the reference/flux and sample runs!')
-            sample_coll = mtd[ws].getRun().getLogData('collimation.actual_position').value
-            ref_coll = coll_ws.getRun().getLogData('collimation.actual_position').value
-            flux_factor = (sample_coll ** 2) / (ref_coll ** 2)
-            self.log().notice('Flux factor is: ' + str(flux_factor))
-            Scale(InputWorkspace=ws, Factor=flux_factor, OutputWorkspace=ws)
-            ReplaceSpecialValues(InputWorkspace=ws, OutputWorkspace=ws,
-                                 NaNValue=0., NaNError=0., InfinityValue=0., InfinityError=0.)
-
-    def _process_transmission(self, beam_ws, ws):
-        if not self._check_distances_match(mtd[ws], beam_ws):
-            self.log().warning('Different detector distances found for empty beam and transmission runs!')
-        RebinToWorkspace(WorkspaceToRebin=ws, WorkspaceToMatch=beam_ws, OutputWorkspace=ws)
-        radius = self.getProperty('BeamRadius').value
-        shapeXML = self._cylinder(radius)
-        det_list = FindDetectorsInShape(Workspace=ws, ShapeXML=shapeXML)
-        lambdas = mtd[ws].extractX()
-        min_lambda = np.min(lambdas)
-        max_lambda = np.max(lambdas)
-        width_lambda = lambdas[0][1] - lambdas[0][0]
-        lambda_binning = [min_lambda, width_lambda, max_lambda]
-        self.log().information('Rebinning for transmission calculation to: ' + str(lambda_binning))
-        Rebin(InputWorkspace=ws, Params=lambda_binning, OutputWorkspace=ws)
-        beam_rebinned = Rebin(InputWorkspace=beam_ws, Params=lambda_binning, StoreInADS=False)
-        CalculateTransmission(SampleRunWorkspace=ws, DirectRunWorkspace=beam_rebinned,
-                              TransmissionROI=det_list, OutputWorkspace=ws, RebinParams=lambda_binning)
-
-    def PyExec(self):
+    def PyExec(self): # noqa: C901
         process = self.getPropertyValue('ProcessAs')
         processes = ['Absorber', 'Beam', 'Transmission', 'Container', 'Reference', 'Sample']
         progress = Progress(self, start=0.0, end=1.0, nreports=processes.index(process) + 1)
         ws = '__' + self.getPropertyValue('OutputWorkspace')
-        LoadAndMerge(Filename=self.getPropertyValue('Run').replace(',', '+'), LoaderName='LoadILLSANS',
-                     OutputWorkspace=ws)
+        LoadAndMerge(Filename=self.getPropertyValue('Run').replace(',','+'), LoaderName='LoadILLSANS', OutputWorkspace=ws)
         self._normalise(ws)
         ExtractMonitors(InputWorkspace=ws, DetectorWorkspace=ws)
         self._instrument = mtd[ws].getInstrument().getName()
@@ -443,17 +301,62 @@ class SANSILLReduction(PythonAlgorithm):
                 self._mode = 'TOF'
         progress.report()
         if process in ['Beam', 'Transmission', 'Container', 'Reference', 'Sample']:
-            self._check_absorber_workspace_processing(ws)
+            absorber_ws = self.getProperty('AbsorberInputWorkspace').value
+            if absorber_ws:
+                if not self._check_processed_flag(absorber_ws, 'Absorber'):
+                    self.log().warning('Absorber input workspace is not processed as absorber.')
+                Minus(LHSWorkspace=ws, RHSWorkspace=absorber_ws, OutputWorkspace=ws)
             if process == 'Beam':
                 progress.report()
                 self._process_beam(ws)
             else:
-                beam_ws = self._check_beam_workspace_processing(ws)
+                beam_ws = self.getProperty('BeamInputWorkspace').value
+                if beam_ws:
+                    if not self._check_processed_flag(beam_ws, 'Beam'):
+                        self.log().warning('Beam input workspace is not processed as beam.')
+                    if self._mode != 'TOF':
+                        beam_x = beam_ws.getRun().getLogData('BeamCenterX').value
+                        beam_y = beam_ws.getRun().getLogData('BeamCenterY').value
+                        AddSampleLog(Workspace=ws, LogName='BeamCenterX', LogText=str(beam_x), LogType='Number')
+                        AddSampleLog(Workspace=ws, LogName='BeamCenterY', LogText=str(beam_y), LogType='Number')
+                        MoveInstrumentComponent(Workspace=ws, X=-beam_x, Y=-beam_y, ComponentName='detector')
+                    if not self._check_distances_match(mtd[ws], beam_ws):
+                        self.log().warning('Different detector distances found for empty beam and sample runs!')
                 progress.report()
                 if process == 'Transmission':
-                    self._process_transmission(beam_ws, ws)
+                    if not self._check_distances_match(mtd[ws], beam_ws):
+                        self.log().warning('Different detector distances found for empty beam and transmission runs!')
+                    RebinToWorkspace(WorkspaceToRebin=ws, WorkspaceToMatch=beam_ws, OutputWorkspace=ws)
+                    radius = self.getProperty('BeamRadius').value
+                    shapeXML = self._cylinder(radius)
+                    det_list = FindDetectorsInShape(Workspace=ws, ShapeXML=shapeXML)
+                    lambdas = mtd[ws].extractX()
+                    min_lambda = np.min(lambdas)
+                    max_lambda = np.max(lambdas)
+                    width_lambda = lambdas[0][1]-lambdas[0][0]
+                    lambda_binning = [min_lambda, width_lambda, max_lambda]
+                    self.log().information('Rebinning for transmission calculation to: '+str(lambda_binning))
+                    Rebin(InputWorkspace=ws, Params=lambda_binning, OutputWorkspace=ws)
+                    beam_rebinned = Rebin(InputWorkspace=beam_ws, Params=lambda_binning, StoreInADS=False)
+                    CalculateTransmission(SampleRunWorkspace=ws, DirectRunWorkspace=beam_rebinned,
+                                          TransmissionROI=det_list, OutputWorkspace=ws, RebinParams=lambda_binning)
                 else:
-                    self._check_transmission_workspace_processing(ws)
+                    transmission_ws = self.getProperty('TransmissionInputWorkspace').value
+                    if transmission_ws:
+                        if not self._check_processed_flag(transmission_ws, 'Transmission'):
+                            self.log().warning('Transmission input workspace is not processed as transmission.')
+                        if transmission_ws.blocksize() == 1:
+                            # monochromatic mode, scalar transmission
+                            transmission = transmission_ws.readY(0)[0]
+                            transmission_err = transmission_ws.readE(0)[0]
+                            ApplyTransmissionCorrection(InputWorkspace=ws, TransmissionValue=transmission,
+                                                        TransmissionError=transmission_err, OutputWorkspace=ws)
+                        else:
+                            # wavelenght dependent transmission, need to rebin
+                            transmission_rebinned = ws + '_tr_rebinned'
+                            RebinToWorkspace(WorkspaceToRebin=transmission_ws, WorkspaceToMatch=ws, OutputWorkspace=transmission_rebinned)
+                            ApplyTransmissionCorrection(InputWorkspace=ws, TransmissionWorkspace=transmission_rebinned, OutputWorkspace=ws)
+                            DeleteWorkspace(transmission_rebinned)
                     solid_angle = ws + '_sa'
                     SolidAngle(InputWorkspace=ws, OutputWorkspace=solid_angle)
                     Divide(LHSWorkspace=ws, RHSWorkspace=solid_angle, OutputWorkspace=ws)
@@ -461,17 +364,74 @@ class SANSILLReduction(PythonAlgorithm):
                     progress.report()
                     if process in ['Reference', 'Sample']:
                         container_ws = self.getProperty('ContainerInputWorkspace').value
-                        self._check_container_workspace_processing(container_ws, ws)
-                        self._do_masking(ws)
+                        if container_ws:
+                            if not self._check_processed_flag(container_ws, 'Container'):
+                                self.log().warning('Container input workspace is not processed as container.')
+                            if not self._check_distances_match(mtd[ws], container_ws):
+                                self.log().warning(
+                                    'Different detector distances found for container and sample runs!')
+                            Minus(LHSWorkspace=ws, RHSWorkspace=container_ws, OutputWorkspace=ws)
+                        mask_ws = self.getProperty('MaskedInputWorkspace').value
+                        if mask_ws:
+                            masked_ws = ws + '_mask'
+                            CloneWorkspace(InputWorkspace=mask_ws, OutputWorkspace=masked_ws)
+                            ExtractMonitors(InputWorkspace=masked_ws, DetectorWorkspace=masked_ws)
+                            MaskDetectors(Workspace=ws, MaskedWorkspace=masked_ws)
+                            DeleteWorkspace(masked_ws)
                         thickness = self.getProperty('SampleThickness').value
                         NormaliseByThickness(InputWorkspace=ws, OutputWorkspace=ws, SampleThickness=thickness)
                         # parallax (gondola) effect
-                        self._parallax_correction(ws)
+                        if self._instrument in ['D22', 'D22lr', 'D33']:
+                            self.log().information('Performing parallax correction')
+                            if self._instrument == 'D33':
+                                components = ['back_detector', 'front_detector_top', 'front_detector_bottom',
+                                              'front_detector_left', 'front_detector_right']
+                            else:
+                                components = ['detector']
+                            ParallaxCorrection(InputWorkspace=ws, OutputWorkspace=ws, ComponentNames=components)
                         progress.report()
                         if process == 'Reference':
-                            self._create_sensitivity_out(ws)
+                            sensitivity_out = self.getPropertyValue('SensitivityOutputWorkspace')
+                            if sensitivity_out:
+                                CalculateEfficiency(InputWorkspace=ws, OutputWorkspace=sensitivity_out)
+                                mtd[sensitivity_out].getRun().addProperty('ProcessedAs', 'Sensitivity', True)
+                                self.setProperty('SensitivityOutputWorkspace', mtd[sensitivity_out])
                         elif process == 'Sample':
-                            self._process_sample(beam_ws, ws)
+                            reference_ws = self.getProperty('ReferenceInputWorkspace').value
+                            coll_ws = None
+                            if reference_ws:
+                                if not self._check_processed_flag(reference_ws, 'Reference'):
+                                    self.log().warning('Reference input workspace is not processed as reference.')
+                                Divide(LHSWorkspace=ws, RHSWorkspace=reference_ws, OutputWorkspace=ws)
+                                coll_ws = reference_ws
+                            else:
+                                sensitivity_in = self.getProperty('SensitivityInputWorkspace').value
+                                if sensitivity_in:
+                                    if not self._check_processed_flag(sensitivity_in, 'Sensitivity'):
+                                        self.log().warning('Sensitivity input workspace is not processed as sensitivity.')
+                                    Divide(LHSWorkspace=ws, RHSWorkspace=sensitivity_in, OutputWorkspace=ws)
+                                flux_in = self.getProperty('FluxInputWorkspace').value
+                                if flux_in:
+                                    coll_ws = beam_ws
+                                    flux_ws = ws + '_flux'
+                                    if self._mode == 'TOF':
+                                        RebinToWorkspace(WorkspaceToRebin=flux_in, WorkspaceToMatch=ws, OutputWorkspace=flux_ws)
+                                        Divide(LHSWorkspace=ws, RHSWorkspace=flux_ws, OutputWorkspace=ws)
+                                        DeleteWorkspace(flux_ws)
+                                    else:
+                                        Divide(LHSWorkspace=ws, RHSWorkspace=flux_in, OutputWorkspace=ws)
+
+                            if coll_ws:
+                                if not self._check_distances_match(mtd[ws], coll_ws):
+                                    self.log().warning(
+                                        'Different detector distances found for the reference/flux and sample runs!')
+                                sample_coll = mtd[ws].getRun().getLogData('collimation.actual_position').value
+                                ref_coll = coll_ws.getRun().getLogData('collimation.actual_position').value
+                                flux_factor = (sample_coll ** 2) / (ref_coll ** 2)
+                                self.log().notice('Flux factor is: ' + str(flux_factor))
+                                Scale(InputWorkspace=ws, Factor=flux_factor, OutputWorkspace=ws)
+                                ReplaceSpecialValues(InputWorkspace=ws, OutputWorkspace=ws,
+                                                     NaNValue=0., NaNError=0., InfinityValue=0., InfinityError=0.)
                             progress.report()
         if process != 'Transmission':
             if self._instrument == 'D33':
@@ -482,6 +442,5 @@ class SANSILLReduction(PythonAlgorithm):
         RenameWorkspace(InputWorkspace=ws, OutputWorkspace=ws[2:])
         self.setProperty('OutputWorkspace', mtd[ws[2:]])
 
-
 # Register algorithm with Mantid
 AlgorithmFactory.subscribe(SANSILLReduction)
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSILLReductionTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSILLReductionTest.py
index c9116dcb0f9e0aca681e9faa6a7966e05fa0e4fe..a27ce13af21656b4897a746007b87d47d38e94dc 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSILLReductionTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/WorkflowAlgorithms/SANSILLReductionTest.py
@@ -7,8 +7,9 @@
 from __future__ import (absolute_import, division, print_function)
 
 import unittest
-from mantid.api import MatrixWorkspace
+from mantid.api import MatrixWorkspace, Run
 from mantid.simpleapi import SANSILLReduction, config, mtd
+from mantid.geometry import Instrument
 
 
 class SANSILLReductionTest(unittest.TestCase):
@@ -92,13 +93,13 @@ class SANSILLReductionTest(unittest.TestCase):
         self._check_output(mtd['flux'], False, 30, 256*256)
         self._check_process_flag(mtd['flux'], 'Beam')
 
-    def xtest_transmission_tof(self):
+    def test_transmission_tof(self):
         # D33 VTOF
         SANSILLReduction(Run='093406', ProcessAs='Beam', OutputWorkspace='beam')
         SANSILLReduction(Run='093407', ProcessAs='Transmission', BeamInputWorkspace='beam', OutputWorkspace='ctr')
         self._check_output(mtd['ctr'], False, 75, 1)
 
-    def test_container_tof(self):
+    def test_reference_tof(self):
         # D33 VTOF
         # this is actually a sample run, not water, but is fine for this test
         SANSILLReduction(Run='093410', ProcessAs='Reference', OutputWorkspace='ref')
@@ -122,8 +123,8 @@ class SANSILLReductionTest(unittest.TestCase):
         self.assertEqual(ws.getAxis(0).getUnit().unitID(), "Wavelength")
         self.assertEqual(ws.blocksize(), blocksize)
         self.assertEqual(ws.getNumberHistograms(), spectra)
-        self.assertTrue(ws.getInstrument())
-        self.assertTrue(ws.getRun())
+        self.assertTrue(isinstance(ws.getInstrument(), Instrument))
+        self.assertTrue(isinstance(ws.getRun(), Run))
         self.assertTrue(ws.getHistory())
         if logs:
             self.assertTrue(ws.getRun().hasProperty('qmin'))