Beispiel #1
0
 def PyInit(self):
     int_validator = IntArrayOrderedPairsValidator()
     self.declareProperty(
         IntArrayProperty("IntInput", int_validator))
     float_validator = FloatArrayOrderedPairsValidator()
     self.declareProperty(
         FloatArrayProperty("FloatInput", float_validator))
Beispiel #2
0
    def PyInit(self):

        self.declareProperty(MultipleFileProperty('Run', extensions=['nxs']),
                             doc='File path of run(s).')

        self.declareProperty(name='NormaliseTo',
                             defaultValue='Monitor',
                             validator=StringListValidator(['None', 'Monitor']),
                             doc='Normalise to monitor, or skip normalisation.')

        self.declareProperty(FileProperty('CalibrationFile', '', action=FileAction.OptionalLoad, extensions=['nxs']),
                             doc='File containing the detector efficiencies.')

        self.declareProperty(name='UseCalibratedData',
                             defaultValue=True,
                             doc='Whether or not to use the calibrated data in the NeXus files.')

        self.declareProperty(name='Output2DTubes',
                             defaultValue=False,
                             doc='Output a 2D workspace of height along tube against tube scattering angle.')

        self.declareProperty(name='Output2D',
                             defaultValue=False,
                             doc='Output a 2D workspace of height along tube against the real scattering angle.')

        self.declareProperty(name='Output1D',
                             defaultValue=True,
                             doc='Output a 1D workspace with counts against scattering angle.')

        self.declareProperty(name='CropNegativeScatteringAngles', defaultValue=True,
                             doc='Whether or not to crop the negative scattering angles.')

        self.declareProperty(FloatArrayProperty(name='HeightRange', values=[],
                                                validator=CompositeValidator([FloatArrayOrderedPairsValidator(),
                                                                              FloatArrayLengthValidator(0, 2)])),
                             doc='A pair of values, comma separated, to give the minimum and maximum height range (in m). If not specified '
                                 'the full height range is used.')

        self.declareProperty(WorkspaceGroupProperty('OutputWorkspace', '',
                                                    direction=Direction.Output),
                             doc='Output workspace containing the reduced data.')

        self.declareProperty(name='InitialMask', defaultValue=20, validator=IntBoundedValidator(lower=0, upper=64),
                             doc='Number of pixels to mask from the bottom and the top of each tube before superposition.')

        self.declareProperty(name='FinalMask', defaultValue=30, validator=IntBoundedValidator(lower=0, upper=70),
                             doc='Number of spectra to mask from the bottom and the top of the result of 2D options.')

        self.declareProperty(name='ComponentsToMask', defaultValue='',
                             doc='Comma separated list of component names to mask, for instance: tube_1, tube_2')

        self.declareProperty(name='ComponentsToReduce', defaultValue='',
                             doc='Comma separated list of component names to output the reduced data for; for example tube_1')

        self.declareProperty(name='AlignTubes', defaultValue=True,
                             doc='Align the tubes vertically and horizontally according to IPF.')
Beispiel #3
0
    def PyInit(self):

        self.declareProperty(MultipleFileProperty('Run', extensions=['nxs']),
                             doc='File path of run(s).')

        self.declareProperty(
            name='NormaliseTo',
            defaultValue='Monitor',
            validator=StringListValidator(['None', 'Monitor']),
            doc='Normalise to monitor, or skip normalisation.')

        self.declareProperty(
            name='UseCalibratedData',
            defaultValue=True,
            doc='Whether or not to use the calibrated data in the NeXus files.'
        )

        self.declareProperty(
            name='Output2DTubes',
            defaultValue=False,
            doc=
            'Output a 2D workspace of height along tube against tube scattering angle.'
        )

        self.declareProperty(
            name='Output2D',
            defaultValue=False,
            doc=
            'Output a 2D workspace of height along tube against the real scattering angle.'
        )

        self.declareProperty(
            name='Output1D',
            defaultValue=True,
            doc='Output a 1D workspace with counts against scattering angle.')

        self.declareProperty(
            FloatArrayProperty(name='HeightRange',
                               values=[],
                               validator=CompositeValidator([
                                   FloatArrayOrderedPairsValidator(),
                                   FloatArrayLengthValidator(0, 2)
                               ])),
            doc=
            'A pair of values, comma separated, to give the minimum and maximum height range (in m). If not specified '
            'the full height range is used.')

        self.declareProperty(
            WorkspaceGroupProperty('OutputWorkspace',
                                   '',
                                   direction=Direction.Output),
            doc='Output workspace containing the reduced data.')
    def PyInit(self):

        self.declareProperty(MultipleFileProperty('Run', extensions=['nxs']),
                             doc='File path of run(s).')

        self.declareProperty(FileProperty('CalibrationFile', '',
                                          action=FileAction.OptionalLoad, extensions=['nxs']),
                             doc='File containing the detector efficiencies.')

        self.declareProperty(FileProperty('ROCCorrectionFile', '',
                                          action=FileAction.OptionalLoad, extensions=['nxs']),
                             doc='File containing the radial oscillating collimator (ROC) corrections.')

        self.declareProperty(name='NormaliseTo',
                             defaultValue='None',
                             validator=StringListValidator(['None', 'Time', 'Monitor', 'ROI']),
                             doc='Normalise to time, monitor or ROI counts.')

        thetaRangeValidator = FloatArrayOrderedPairsValidator()

        self.declareProperty(FloatArrayProperty(name='ROI', values=[0, 153.6], validator=thetaRangeValidator),
                             doc='Regions of interest for normalisation [in scattering angle in degrees].')

        normaliseToROI = VisibleWhenProperty('NormaliseTo', PropertyCriterion.IsEqualTo, 'ROI')
        self.setPropertySettings('ROI', normaliseToROI)

        self.declareProperty(name='Observable',
                             defaultValue='sample.temperature',
                             doc='Scanning observable, a Sample Log entry.')

        self.declareProperty(name='SortObservableAxis',
                             defaultValue=False,
                             doc='Whether or not to sort the scanning observable axis.')

        self.declareProperty(name='ScanAxisBinWidth', defaultValue=0., validator=FloatBoundedValidator(lower=0.),
                             doc='Rebin the observable axis to this width. Default is to not rebin.')

        self.declareProperty(name='CropNegative2Theta', defaultValue=True,
                             doc='Whether or not to crop out the bins corresponding to negative scattering angle.')

        self.declareProperty(name='ZeroCountingCells', defaultValue='Interpolate',
                             validator=StringListValidator(['Crop','Interpolate','Leave']),
                             doc='Crop out the zero counting cells or interpolate the counts from the neighbours.')

        self.declareProperty(name='Unit',
                             defaultValue='ScatteringAngle',
                             validator=StringListValidator(['ScatteringAngle', 'MomentumTransfer', 'dSpacing']),
                             doc='The unit of the reduced diffractogram.')

        self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '',
                                                     direction=Direction.Output),
                             doc='Output workspace containing the reduced data.')
Beispiel #5
0
    def PyInit(self):

        positiveFloat = FloatBoundedValidator(0., exclusive=False)
        validRebinParams = RebinParamsValidator(AllowEmpty=True)
        orderedPairsValidator = FloatArrayOrderedPairsValidator()

        self.declareProperty(
            WorkspaceGroupProperty('OutputWorkspace',
                                   '',
                                   direction=Direction.Output),
            doc='The output workspace group containing reduced data.')

        self.declareProperty(MultipleFileProperty('Runs',
                                                  action=FileAction.Load,
                                                  extensions=['nxs']),
                             doc='Run(s) to be processed.')

        processes = ['Cadmium', 'Empty', 'Vanadium', 'Sample']
        self.declareProperty(name='ProcessAs',
                             defaultValue='Sample',
                             validator=StringListValidator(processes),
                             doc='Choose the process type.')

        reduction_options = ['Powder', 'SingleCrystal']
        self.declareProperty(
            name='ReductionType',
            defaultValue='Powder',
            validator=StringListValidator(reduction_options),
            doc='Choose the appropriate reduction type for the data to process.'
        )

        self.declareProperty(
            'VanadiumWorkspace',
            '',
            doc='File(s) or workspaces containing vanadium data.')

        self.declareProperty('EmptyContainerWorkspace',
                             '',
                             doc='Empty container workspace.')

        self.declareProperty('EmptyContainerScaling',
                             1.0,
                             doc='Scaling factor for the empty container.')

        self.declareProperty(WorkspaceGroupProperty(
            'CadmiumWorkspace',
            '',
            direction=Direction.Input,
            optional=PropertyMode.Optional),
                             doc='Cadmium absorber workspace.')

        self.copyProperties(
            'DirectILLCollectData',
            [common.PROP_FLAT_BKG, common.PROP_FLAT_BKG_WINDOW])

        self.declareProperty(
            'FlatBackgroundSource',
            "",
            doc=
            'File(s) or workspaces containing the source to calculate flat background.'
        )

        self.copyProperties(
            'DirectILLCollectData',
            [common.PROP_FLAT_BKG_SCALING, common.PROP_OUTPUT_FLAT_BKG_WS])

        self.copyProperties('DirectILLReduction', common.PROP_ABSOLUTE_UNITS)

        additional_inputs_group = 'Corrections'
        self.setPropertyGroup('VanadiumWorkspace', additional_inputs_group)
        self.setPropertyGroup('EmptyContainerWorkspace',
                              additional_inputs_group)
        self.setPropertyGroup('EmptyContainerScaling', additional_inputs_group)
        self.setPropertyGroup('CadmiumWorkspace', additional_inputs_group)
        self.setPropertyGroup(common.PROP_FLAT_BKG, additional_inputs_group)
        self.setPropertyGroup(common.PROP_FLAT_BKG_WINDOW,
                              additional_inputs_group)
        self.setPropertyGroup('FlatBackgroundSource', additional_inputs_group)
        self.setPropertyGroup(common.PROP_FLAT_BKG_SCALING,
                              additional_inputs_group)
        self.setPropertyGroup(common.PROP_OUTPUT_FLAT_BKG_WS,
                              additional_inputs_group)
        self.setPropertyGroup(common.PROP_ABSOLUTE_UNITS,
                              additional_inputs_group)

        self.copyProperties(
            'DirectILLCollectData',
            [common.PROP_NORMALISATION, common.PROP_MON_PEAK_SIGMA_MULTIPLIER])

        self.copyProperties('DirectILLCollectData',
                            common.PROP_INCIDENT_ENERGY_CALIBRATION)

        self.declareProperty(
            name='IncidentEnergy',
            defaultValue=0.0,
            validator=positiveFloat,
            doc='Value for the calibrated incident energy (meV).')

        self.copyProperties(
            'DirectILLCollectData',
            [common.PROP_ELASTIC_CHANNEL_MODE, common.PROP_EPP_METHOD])

        self.declareProperty(
            name='ElasticChannelIndex',
            defaultValue=0.0,
            validator=positiveFloat,
            doc=
            'Bin index value for the centre of the elastic peak. Can be a float.'
        )

        self.declareProperty(
            'SampleAngleOffset',
            0.0,
            doc='Value for the offset parameter in omega scan (degrees).')

        calibration_group = 'Calibration'
        self.setPropertyGroup(common.PROP_INCIDENT_ENERGY_CALIBRATION,
                              calibration_group)
        self.setPropertyGroup('IncidentEnergy', calibration_group)
        self.setPropertyGroup('ElasticChannelIndex', calibration_group)
        self.setPropertyGroup(common.PROP_ELASTIC_CHANNEL_MODE,
                              calibration_group)
        self.setPropertyGroup(common.PROP_EPP_METHOD, calibration_group)
        self.setPropertyGroup('SampleAngleOffset', calibration_group)

        # The mask workspace replaces MaskWorkspace parameter from PantherSingle and DiagnosticsWorkspace from directred
        self.declareProperty('MaskWorkspace',
                             '',
                             doc='File(s) or workspaces containing the mask.')

        self.declareProperty(IntArrayProperty(name='MaskedTubes',
                                              values=[],
                                              direction=Direction.Input),
                             doc='List of tubes to be masked.')

        self.declareProperty(
            'MaskThresholdMin',
            0.0,
            doc='Threshold level below which bins will be masked'
            ' to remove empty / background pixels.')

        self.declareProperty(
            'MaskThresholdMax',
            0.0,
            doc='Threshold level above which bins will be masked'
            ' to remove noisy pixels.')

        self.declareProperty(FloatArrayProperty(
            name='MaskedAngles', values=[], validator=orderedPairsValidator),
                             doc='Mask detectors in the given angular range.')

        self.declareProperty(
            'MaskWithVanadium',
            True,
            doc='Whether to mask using vanadium diagnostics workspace.')

        masking_group_name = 'Masking'
        self.setPropertyGroup('MaskWorkspace', masking_group_name)
        self.setPropertyGroup('MaskedTubes', masking_group_name)
        self.setPropertyGroup('MaskThresholdMin', masking_group_name)
        self.setPropertyGroup('MaskThresholdMax', masking_group_name)
        self.setPropertyGroup('MaskedAngles', masking_group_name)
        self.setPropertyGroup('MaskWithVanadium', masking_group_name)

        self.copyProperties(
            'DirectILLReduction',
            [common.PROP_REBINNING_W, common.PROP_REBINNING_PARAMS_W])

        self.declareProperty(FloatArrayProperty(name='MomentumTransferBinning',
                                                validator=validRebinParams),
                             doc='Momentum transfer binning parameters.')

        rebinning_group = 'Binning parameters'
        self.setPropertyGroup(common.PROP_REBINNING_W, rebinning_group)
        self.setPropertyGroup(common.PROP_REBINNING_PARAMS_W, rebinning_group)
        self.setPropertyGroup('MomentumTransferBinning', rebinning_group)

        self.declareProperty(
            name='AbsorptionCorrection',
            defaultValue='None',
            validator=StringListValidator(['None', 'Fast', 'Full']),
            doc='Choice of approach to absorption correction.')

        self.declareProperty(
            name='SelfAttenuationMethod',
            defaultValue='MonteCarlo',
            validator=StringListValidator(['Numerical', 'MonteCarlo']),
            doc='Choice of calculation method for the attenuation calculation.'
        )

        self.declareProperty(PropertyManagerProperty('SampleMaterial'),
                             doc='Sample material definitions.')

        self.declareProperty(PropertyManagerProperty('SampleGeometry'),
                             doc="Dictionary for the sample geometry.")

        self.declareProperty(PropertyManagerProperty('ContainerMaterial'),
                             doc='Container material definitions.')

        self.declareProperty(PropertyManagerProperty('ContainerGeometry'),
                             doc="Dictionary for the container geometry.")

        attenuation_group = 'Sample attenuation'
        self.setPropertyGroup('AbsorptionCorrection', attenuation_group)
        self.setPropertyGroup('SelfAttenuationMethod', attenuation_group)
        self.setPropertyGroup('SampleMaterial', attenuation_group)
        self.setPropertyGroup('SampleGeometry', attenuation_group)
        self.setPropertyGroup('ContainerMaterial', attenuation_group)
        self.setPropertyGroup('ContainerGeometry', attenuation_group)

        self.declareProperty(
            name=common.PROP_DET_GROUPING,
            defaultValue="",
            doc='Grouping pattern to reduce the granularity of the output.')

        self.declareProperty(
            name=common.PROP_DET_GROUPING_BY,
            defaultValue=1,
            doc=
            'Step to use when grouping detectors to reduce the granularity of the output.'
        )

        self.copyProperties(
            'DirectILLCollectData',
            [common.PROP_DET_HOR_GROUPING, common.PROP_DET_VER_GROUPING])

        self.declareProperty(
            name="ApplyGroupingBy",
            defaultValue=False,
            doc=
            'Whether to apply the pixel grouping horizontally or vertically to the data, and not'
            ' only to increase the statistics of the flat background calculation.'
        )

        self.declareProperty(
            name=common.PROP_GROUPING_ANGLE_STEP,
            defaultValue=0.0,
            validator=positiveFloat,
            doc=
            'A scattering angle step to which to group detectors, in degrees.')

        self.declareProperty(
            name='GroupingBehaviour',
            defaultValue="Sum",
            validator=StringListValidator(['Sum', 'Average']),
            doc='Defines which behaviour should be used when grouping pixels.')

        grouping_options_group = 'Grouping options'
        self.setPropertyGroup(common.PROP_DET_GROUPING, grouping_options_group)
        self.setPropertyGroup(common.PROP_DET_GROUPING_BY,
                              grouping_options_group)
        self.setPropertyGroup(common.PROP_DET_HOR_GROUPING,
                              grouping_options_group)
        self.setPropertyGroup(common.PROP_DET_VER_GROUPING,
                              grouping_options_group)
        self.setPropertyGroup('ApplyGroupingBy', grouping_options_group)
        self.setPropertyGroup(common.PROP_GROUPING_ANGLE_STEP,
                              grouping_options_group)
        self.setPropertyGroup('GroupingBehaviour', grouping_options_group)

        self.declareProperty(
            name="SaveOutput",
            defaultValue=True,
            doc="Whether to save the output directly after processing.")

        self.declareProperty(name='ClearCache',
                             defaultValue=False,
                             doc='Whether to clear intermediate workspaces.')
    def PyInit(self):
        self.declareProperty(
            MultipleFileProperty('CalibrationRun',
                                 action=FileAction.Load,
                                 extensions=['nxs']),
            doc=
            'File path of calibration runs (numors). Must be detector scans.')

        self.declareProperty(
            FileProperty('CalibrationFile',
                         '',
                         action=FileAction.OptionalLoad,
                         extensions=['nxs']),
            doc='Optional file containing previous calibration constants.')

        self.declareProperty(
            name='CalibrationMethod',
            defaultValue='Median',
            validator=StringListValidator(['Median', 'Mean',
                                           'MostLikelyMean']),
            doc='The method of how the calibration constant of a pixel '
            'is derived from the distribution of ratios.')

        self.declareProperty(
            name='DerivationMethod',
            defaultValue='SequentialSummedReference1D',
            validator=StringListValidator(
                ['SequentialSummedReference1D', 'GlobalSummedReference2D']),
            doc=
            'Choose sequential for D20 (1D detector), global for D2B (2D detector).'
        )

        self.declareProperty(
            name='InterpolateOverlappingAngles',
            defaultValue=False,
            doc=
            'Whether to interpolate scattering angle values in overlapping regions (D20 only).'
        )

        self.declareProperty(
            name='NormaliseTo',
            defaultValue='None',
            validator=StringListValidator(['None', 'Monitor', 'ROI']),
            doc=
            'Normalise to monitor or ROI counts before deriving the calibration.'
        )

        thetaRangeValidator = FloatArrayOrderedPairsValidator()

        self.declareProperty(
            FloatArrayProperty(name='ROI',
                               values=[0, 100.],
                               validator=thetaRangeValidator),
            doc=
            'Scattering angle regions of interest for normalisation [degrees].'
        )

        normaliseToROI = VisibleWhenProperty('NormaliseTo',
                                             PropertyCriterion.IsEqualTo,
                                             'ROI')
        self.setPropertySettings('ROI', normaliseToROI)

        self.declareProperty(
            FloatArrayProperty(name='ExcludedRange',
                               values=[],
                               validator=thetaRangeValidator),
            doc='Scattering angle regions to exclude from the computation of '
            'relative calibration constants; for example, the beam stop [degrees]. '
        )

        pixelRangeValidator = CompositeValidator()
        greaterThanOne = IntArrayBoundedValidator(lower=1)
        lengthTwo = IntArrayLengthValidator()
        lengthTwo.setLength(2)
        orderedPairsValidator = IntArrayOrderedPairsValidator()
        pixelRangeValidator.add(greaterThanOne)
        pixelRangeValidator.add(lengthTwo)
        pixelRangeValidator.add(orderedPairsValidator)

        self.declareProperty(
            IntArrayProperty(name='PixelRange',
                             values=[1, 3072],
                             validator=pixelRangeValidator),
            doc=
            'Range of the pixel numbers to compute the calibration factors for (D20 only); '
            'for the other pixels outside the range, the factor will be set to 1.'
        )

        self.declareProperty(
            MatrixWorkspaceProperty('OutputResponseWorkspace',
                                    '',
                                    optional=PropertyMode.Optional,
                                    direction=Direction.Output),
            doc=
            'Output workspace containing the summed diffraction patterns of all the overlapping pixels.'
        )

        self.declareProperty(
            MatrixWorkspaceProperty('OutputWorkspace',
                                    '',
                                    direction=Direction.Output),
            doc=
            'Output workspace containing the calibration constants (inverse of efficiency) for each pixel.'
        )

        self.declareProperty(
            name='NumberOfIterations',
            defaultValue=1,
            validator=IntBoundedValidator(lower=0, upper=10),
            doc=
            'Number of iterations to perform (D2B only): 0 means auto; that is, the '
            'iterations will terminate after reaching some Chi2/NdoF.')

        maskCriterionValidator = CompositeValidator()
        arrayLengthTwo = FloatArrayLengthValidator()
        arrayLengthTwo.setLengthMax(2)
        orderedPairs = FloatArrayOrderedPairsValidator()
        maskCriterionValidator.add(arrayLengthTwo)
        maskCriterionValidator.add(orderedPairs)

        self.declareProperty(
            FloatArrayProperty(name='MaskCriterion',
                               values=[],
                               validator=maskCriterionValidator),
            doc='Efficiency constants outside this range will be set to zero.')

        self.declareProperty(
            name='UseCalibratedData',
            defaultValue=False,
            doc=
            'Whether or not to use the calibrated data in the NeXus files (D2B only).'
        )
Beispiel #7
0
    def PyInit(self):
        self.declareProperty(MatrixWorkspaceProperty(
            'InputWorkspace', '', direction=Direction.Input),
                             doc='The input workspace.')

        self.declareProperty(MatrixWorkspaceProperty(
            'OutputWorkspace', '', direction=Direction.Output),
                             doc='The output workspace.')

        self.declareProperty(name='OutputType',
                             defaultValue='I(Q)',
                             validator=StringListValidator(
                                 ['I(Q)', 'I(Qx,Qy)', 'I(Phi,Q)']),
                             doc='Choose the output type.')

        self.declareProperty(name='CalculateResolution',
                             defaultValue='None',
                             validator=StringListValidator(
                                 ['MildnerCarpenter', 'DirectBeam', 'None']),
                             doc='Choose to calculate the Q resolution.')

        output_iq = EnabledWhenProperty('OutputType',
                                        PropertyCriterion.IsEqualTo, 'I(Q)')
        output_iphiq = EnabledWhenProperty('OutputType',
                                           PropertyCriterion.IsEqualTo,
                                           'I(Phi,Q)')
        output_iqxy = EnabledWhenProperty('OutputType',
                                          PropertyCriterion.IsEqualTo,
                                          'I(Qx,Qy)')

        self.declareProperty(
            name='DefaultQBinning',
            defaultValue='PixelSizeBased',
            validator=StringListValidator(
                ['PixelSizeBased', 'ResolutionBased']),
            doc='Choose how to calculate the default Q binning.')
        self.setPropertySettings(
            'DefaultQBinning',
            EnabledWhenProperty(output_iq, output_iphiq, LogicOperator.Or))

        self.declareProperty(
            name='BinningFactor',
            defaultValue=1.,
            validator=FloatBoundedValidator(lower=0.),
            doc=
            'Specify a multiplicative factor for default Q binning (pixel or resolution based).'
        )
        self.setPropertySettings(
            'BinningFactor',
            EnabledWhenProperty(output_iq, output_iphiq, LogicOperator.Or))

        self.declareProperty(FloatArrayProperty('OutputBinning'),
                             doc='The manual Q binning of the output')
        self.setPropertySettings(
            'OutputBinning',
            EnabledWhenProperty(output_iq, output_iphiq, LogicOperator.Or))

        self.declareProperty('NPixelDivision', 1, IntBoundedValidator(lower=1),
                             'Number of subpixels to split the pixel (NxN)')
        self.setPropertySettings(
            'NPixelDivision',
            EnabledWhenProperty(output_iq, output_iphiq, LogicOperator.Or))

        iq_without_shapes = EnabledWhenProperty(
            EnabledWhenProperty("ShapeTable", PropertyCriterion.IsDefault),
            EnabledWhenProperty(output_iq, output_iphiq, LogicOperator.Or),
            LogicOperator.And)

        self.declareProperty(name='NumberOfWedges',
                             defaultValue=0,
                             validator=IntBoundedValidator(lower=0),
                             doc='Number of wedges to integrate separately.')
        self.setPropertySettings('NumberOfWedges', iq_without_shapes)

        iq_with_wedges = EnabledWhenProperty(
            output_iq,
            EnabledWhenProperty('NumberOfWedges',
                                PropertyCriterion.IsNotDefault),
            LogicOperator.And)
        iq_with_wedges_or_shapes = EnabledWhenProperty(
            iq_with_wedges,
            EnabledWhenProperty("ShapeTable", PropertyCriterion.IsNotDefault),
            LogicOperator.Or)
        iq_with_wedges_but_no_shapes = EnabledWhenProperty(
            iq_with_wedges,
            EnabledWhenProperty("ShapeTable", PropertyCriterion.IsDefault),
            LogicOperator.And)

        self.declareProperty(
            WorkspaceGroupProperty('WedgeWorkspace',
                                   '',
                                   direction=Direction.Output,
                                   optional=PropertyMode.Optional),
            doc='WorkspaceGroup containing I(Q) for each azimuthal wedge.')
        self.setPropertySettings('WedgeWorkspace', iq_with_wedges_or_shapes)

        self.declareProperty(name='WedgeAngle',
                             defaultValue=30.,
                             validator=FloatBoundedValidator(lower=0.),
                             doc='Wedge opening angle [degrees].')
        self.setPropertySettings('WedgeAngle', iq_with_wedges_but_no_shapes)

        self.declareProperty(name='WedgeOffset',
                             defaultValue=0.,
                             validator=FloatBoundedValidator(lower=0.),
                             doc='Wedge offset angle from x+ axis.')
        self.setPropertySettings('WedgeOffset', iq_with_wedges_but_no_shapes)

        self.declareProperty(name='AsymmetricWedges',
                             defaultValue=False,
                             doc='Whether to have asymmetric wedges.')
        self.setPropertySettings('AsymmetricWedges', iq_with_wedges_or_shapes)

        self.setPropertyGroup('DefaultQBinning', 'I(Q) Options')
        self.setPropertyGroup('BinningFactor', 'I(Q) Options')
        self.setPropertyGroup('OutputBinning', 'I(Q) Options')
        self.setPropertyGroup('NPixelDivision', 'I(Q) Options')
        self.setPropertyGroup('NumberOfWedges', 'I(Q) Options')
        self.setPropertyGroup('WedgeWorkspace', 'I(Q) Options')
        self.setPropertyGroup('WedgeAngle', 'I(Q) Options')
        self.setPropertyGroup('WedgeOffset', 'I(Q) Options')
        self.setPropertyGroup('AsymmetricWedges', 'I(Q) Options')

        self.declareProperty(name='MaxQxy',
                             defaultValue=-1.0,
                             validator=FloatBoundedValidator(lower=-1.0),
                             doc='Maximum of absolute Qx and Qy.')
        self.setPropertySettings('MaxQxy', output_iqxy)

        self.declareProperty(name='DeltaQ',
                             defaultValue=-1.0,
                             validator=FloatBoundedValidator(lower=-1.0),
                             doc='The dimension of a Qx-Qy cell.')
        self.setPropertySettings('DeltaQ', output_iqxy)

        self.declareProperty(
            name='IQxQyLogBinning',
            defaultValue=False,
            doc='I(Qx, Qy) log binning when binning is not specified.')
        self.setPropertySettings('IQxQyLogBinning', output_iqxy)

        self.setPropertyGroup('MaxQxy', 'I(Qx,Qy) Options')
        self.setPropertyGroup('DeltaQ', 'I(Qx,Qy) Options')
        self.setPropertyGroup('IQxQyLogBinning', 'I(Qx,Qy) Options')
        self.declareProperty(
            WorkspaceGroupProperty('PanelOutputWorkspaces',
                                   '',
                                   direction=Direction.Output,
                                   optional=PropertyMode.Optional),
            doc='The name of the output workspace group for detector panels.')
        self.declareProperty(
            ITableWorkspaceProperty('ShapeTable',
                                    '',
                                    direction=Direction.Input,
                                    optional=PropertyMode.Optional),
            doc=
            'The name of the table workspace containing drawn shapes on which to integrate. '
            'If provided, NumberOfWedges, WedgeOffset and WedgeAngle arguments are ignored. '
        )

        self.setPropertyGroup('PanelOutputWorkspaces', 'I(Q) Options')
        self.setPropertyGroup('ShapeTable', 'I(Q) Options')

        lambda_range_validator = CompositeValidator()
        lambda_range_validator.add(FloatArrayOrderedPairsValidator())
        lambda_range_validator.add(FloatArrayLengthValidator(2))
        self.declareProperty(
            FloatArrayProperty('WavelengthRange', [1., 10.],
                               validator=lambda_range_validator),
            doc=
            'Wavelength range [Angstrom] to be used in integration (TOF only).'
        )