From 8072b97d943ddcc1958966b6365af12d3e2d2067 Mon Sep 17 00:00:00 2001 From: Karl Palmen <karl.palmen@stfc.ac.uk> Date: Mon, 9 Apr 2018 16:06:38 +0100 Subject: [PATCH] Merge remote-tracking branch 'origin/master' re #12828 # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit. Merge done to enable documentation be be fixed, because of removal of alias directive and addition of related algorithms directive. Signed-off-by: Karl Palmen <karl.palmen@stfc.ac.uk> --- Framework/API/inc/MantidAPI/Algorithm.h | 3 + Framework/API/inc/MantidAPI/AlgorithmProxy.h | 11 +- .../API/inc/MantidAPI/CompositeDomainMD.h | 4 +- .../API/inc/MantidAPI/FunctionDomainMD.h | 2 +- .../API/inc/MantidAPI/FunctionProperty.h | 2 +- Framework/API/inc/MantidAPI/IAlgorithm.h | 3 + Framework/API/inc/MantidAPI/IMDIterator.h | 26 +- Framework/API/inc/MantidAPI/IMDNode.h | 10 +- Framework/API/inc/MantidAPI/IMDWorkspace.h | 19 +- Framework/API/inc/MantidAPI/IndexProperty.h | 2 +- .../API/inc/MantidAPI/IndexTypeProperty.h | 4 +- Framework/API/inc/MantidAPI/MatrixWorkspace.h | 2 +- .../inc/MantidAPI/MatrixWorkspaceMDIterator.h | 8 +- .../API/inc/MantidAPI/WorkspaceProperty.h | 3 +- .../API/inc/MantidAPI/WorkspaceProperty.tcc | 5 +- Framework/API/src/AlgorithmProxy.cpp | 7 +- Framework/API/src/EqualBinSizesValidator.cpp | 4 +- Framework/API/src/FunctionDomainMD.cpp | 6 +- Framework/API/src/FunctionProperty.cpp | 6 +- Framework/API/src/IMDWorkspace.cpp | 7 +- Framework/API/src/IndexProperty.cpp | 5 +- Framework/API/src/IndexTypeProperty.cpp | 5 +- Framework/API/src/MatrixWorkspace.cpp | 37 +- .../API/src/MatrixWorkspaceMDIterator.cpp | 4 +- Framework/API/test/AlgorithmProxyTest.h | 5 + Framework/API/test/AlgorithmTest.h | 7 + Framework/API/test/ExperimentInfoTest.h | 5 +- Framework/API/test/FakeAlgorithms.h | 3 + Framework/API/test/GroupingLoaderTest.h | 6 +- .../API/test/MatrixWorkspaceMDIteratorTest.h | 20 +- .../inc/MantidAlgorithms/AddLogDerivative.h | 3 + .../Algorithms/inc/MantidAlgorithms/AddNote.h | 3 + .../Algorithms/inc/MantidAlgorithms/AddPeak.h | 3 + .../inc/MantidAlgorithms/AddSampleLog.h | 3 + .../inc/MantidAlgorithms/AddTimeSeriesLog.h | 3 + .../inc/MantidAlgorithms/AlignDetectors.h | 3 + .../MantidAlgorithms/AnnularRingAbsorption.h | 3 + .../inc/MantidAlgorithms/AnyShapeAbsorption.h | 8 + .../inc/MantidAlgorithms/AppendSpectra.h | 3 + .../inc/MantidAlgorithms/ApplyDeadTimeCorr.h | 3 + .../ApplyTransmissionCorrection.h | 3 + .../inc/MantidAlgorithms/AsymmetryCalc.h | 3 + .../MantidAlgorithms/Bin2DPowderDiffraction.h | 3 + .../inc/MantidAlgorithms/BinaryOperateMasks.h | 3 + .../inc/MantidAlgorithms/CalMuonDeadTime.h | 3 + .../inc/MantidAlgorithms/CalculateCountRate.h | 3 + .../inc/MantidAlgorithms/CalculateDIFC.h | 3 + .../MantidAlgorithms/CalculateMuonAsymmetry.h | 3 + .../CalculatePolynomialBackground.h | 3 + .../inc/MantidAlgorithms/CalculateSlits.h | 3 + .../MantidAlgorithms/CalculateTransmission.h | 3 + .../CalculateTransmissionBeamSpreader.h | 3 + .../inc/MantidAlgorithms/ChangeBinOffset.h | 1 + .../inc/MantidAlgorithms/ChangeLogTime.h | 3 + .../inc/MantidAlgorithms/ChangePulsetime.h | 3 + .../MantidAlgorithms/CheckWorkspacesMatch.h | 3 + .../inc/MantidAlgorithms/ChopData.h | 5 + .../inc/MantidAlgorithms/ClearCache.h | 3 + .../ClearInstrumentParameters.h | 3 + .../inc/MantidAlgorithms/ClearMaskFlag.h | 3 + .../inc/MantidAlgorithms/ClearMaskedSpectra.h | 3 + .../inc/MantidAlgorithms/CloneWorkspace.h | 3 + .../Algorithms/inc/MantidAlgorithms/Comment.h | 3 + .../inc/MantidAlgorithms/CompareWorkspaces.h | 3 + .../inc/MantidAlgorithms/ConjoinWorkspaces.h | 3 + .../MantidAlgorithms/ConvertAxesToRealSpace.h | 3 + .../MantidAlgorithms/ConvertAxisByFormula.h | 3 + .../inc/MantidAlgorithms/ConvertDiffCal.h | 3 + .../ConvertFromDistribution.h | 3 + .../MantidAlgorithms/ConvertSpectrumAxis2.h | 3 + .../ConvertTableToMatrixWorkspace.h | 3 + .../MantidAlgorithms/ConvertToConstantL2.h | 3 + .../MantidAlgorithms/ConvertToDistribution.h | 3 + .../ConvertToEventWorkspace.h | 3 + .../inc/MantidAlgorithms/ConvertToHistogram.h | 4 +- .../ConvertToMatrixWorkspace.h | 3 + .../inc/MantidAlgorithms/ConvertToPointData.h | 4 +- .../inc/MantidAlgorithms/ConvertUnits.h | 4 + .../MantidAlgorithms/CopyDetectorMapping.h | 3 + .../CopyInstrumentParameters.h | 3 + .../inc/MantidAlgorithms/CopyLogs.h | 4 + .../inc/MantidAlgorithms/CopySample.h | 3 + .../inc/MantidAlgorithms/CorrectTOFAxis.h | 3 + .../MantidAlgorithms/CreateCalFileByNames.h | 5 + .../inc/MantidAlgorithms/CreateDummyCalFile.h | 5 + .../inc/MantidAlgorithms/CreateEPP.h | 3 + .../CreateGroupingWorkspace.h | 3 + .../MantidAlgorithms/CreateLogPropertyTable.h | 3 + .../CreateLogTimeCorrection.h | 3 + .../inc/MantidAlgorithms/CreatePSDBleedMask.h | 4 +- .../MantidAlgorithms/CreatePeaksWorkspace.h | 3 + .../MantidAlgorithms/CreateSampleWorkspace.h | 3 + .../CreateSingleValuedWorkspace.h | 3 + .../CreateTransmissionWorkspace2.h | 3 + .../CreateTransmissionWorkspaceAuto2.h | 3 + .../CreateUserDefinedBackground.h | 3 + .../inc/MantidAlgorithms/CreateWorkspace.h | 5 +- .../inc/MantidAlgorithms/CropToComponent.h | 3 + .../inc/MantidAlgorithms/CropWorkspace.h | 4 + .../inc/MantidAlgorithms/CrossCorrelate.h | 3 + .../CuboidGaugeVolumeAbsorption.h | 3 + .../inc/MantidAlgorithms/CylinderAbsorption.h | 3 + .../inc/MantidAlgorithms/DeleteLog.h | 3 + .../inc/MantidAlgorithms/DeleteWorkspace.h | 3 + .../inc/MantidAlgorithms/DeleteWorkspaces.h | 3 + .../inc/MantidAlgorithms/DetectorDiagnostic.h | 4 + .../MantidAlgorithms/DetectorEfficiencyCor.h | 3 + .../DetectorEfficiencyCorUser.h | 3 + .../DetectorEfficiencyVariation.h | 3 + .../DiffractionEventCalibrateDetectors.h | 3 + .../MantidAlgorithms/DiffractionFocussing2.h | 3 + .../Algorithms/inc/MantidAlgorithms/Divide.h | 3 + .../inc/MantidAlgorithms/EQSANSResolution.h | 3 + .../inc/MantidAlgorithms/ElasticWindow.h | 3 + .../inc/MantidAlgorithms/EstimateDivergence.h | 3 + .../EstimateResolutionDiffraction.h | 3 + .../inc/MantidAlgorithms/Exponential.h | 3 + .../MantidAlgorithms/ExponentialCorrection.h | 4 + .../MantidAlgorithms/ExportTimeSeriesLog.h | 3 + .../inc/MantidAlgorithms/ExtractFFTSpectrum.h | 4 + .../inc/MantidAlgorithms/ExtractMask.h | 3 + .../inc/MantidAlgorithms/ExtractMaskToTable.h | 3 + .../MantidAlgorithms/ExtractSingleSpectrum.h | 3 + .../inc/MantidAlgorithms/ExtractSpectra.h | 4 + .../MantidAlgorithms/ExtractUnmaskedSpectra.h | 3 + .../Algorithms/inc/MantidAlgorithms/FFT.h | 4 + .../inc/MantidAlgorithms/FFTDerivative.h | 4 + .../inc/MantidAlgorithms/FFTSmooth2.h | 3 + .../inc/MantidAlgorithms/FilterBadPulses.h | 3 + .../inc/MantidAlgorithms/FilterByLogValue.h | 4 + .../inc/MantidAlgorithms/FilterByTime.h | 4 + .../inc/MantidAlgorithms/FilterByXValue.h | 3 + .../inc/MantidAlgorithms/FilterEvents.h | 3 + .../FindCenterOfMassPosition2.h | 1 + .../inc/MantidAlgorithms/FindDeadDetectors.h | 3 + .../FindDetectorsOutsideLimits.h | 3 + .../inc/MantidAlgorithms/FindPeakBackground.h | 1 + .../inc/MantidAlgorithms/FindPeaks.h | 3 + .../Algorithms/inc/MantidAlgorithms/FitPeak.h | 1 + .../MantidAlgorithms/FixGSASInstrumentFile.h | 3 + .../MantidAlgorithms/FlatPlateAbsorption.h | 3 + .../MantidAlgorithms/GenerateEventsFilter.h | 3 + .../GenerateIPythonNotebook.h | 3 + .../inc/MantidAlgorithms/GeneratePeaks.h | 3 + .../MantidAlgorithms/GeneratePythonScript.h | 3 + .../inc/MantidAlgorithms/GetAllEi.h | 1 + .../GetDetOffsetsMultiPeaks.h | 3 + .../inc/MantidAlgorithms/GetDetectorOffsets.h | 4 + .../Algorithms/inc/MantidAlgorithms/GetEi2.h | 3 + .../inc/MantidAlgorithms/GetEiMonDet2.h | 1 + .../GetTimeSeriesLogInformation.h | 3 + .../inc/MantidAlgorithms/GroupWorkspaces.h | 3 + .../MantidAlgorithms/HRPDSlabCanAbsorption.h | 3 + .../inc/MantidAlgorithms/He3TubeEfficiency.h | 3 + .../MantidAlgorithms/IdentifyNoisyDetectors.h | 4 + .../MantidAlgorithms/IntegrateByComponent.h | 3 + .../inc/MantidAlgorithms/Integration.h | 3 + .../inc/MantidAlgorithms/InterpolatingRebin.h | 1 + .../inc/MantidAlgorithms/InvertMask.h | 3 + .../inc/MantidAlgorithms/LineProfile.h | 3 + .../inc/MantidAlgorithms/Logarithm.h | 3 + .../inc/MantidAlgorithms/LorentzCorrection.h | 3 + .../MagFormFactorCorrection.h | 1 + .../inc/MantidAlgorithms/MaskBins.h | 3 + .../inc/MantidAlgorithms/MaskBinsFromTable.h | 3 + .../inc/MantidAlgorithms/MaskDetectorsIf.h | 3 + .../inc/MantidAlgorithms/MaskInstrument.h | 3 + .../Algorithms/inc/MantidAlgorithms/Max.h | 3 + .../Algorithms/inc/MantidAlgorithms/MaxEnt.h | 4 + .../Algorithms/inc/MantidAlgorithms/MaxMin.h | 3 + .../inc/MantidAlgorithms/MedianDetectorTest.h | 3 + .../inc/MantidAlgorithms/MergeRuns.h | 3 + .../Algorithms/inc/MantidAlgorithms/Min.h | 3 + .../Algorithms/inc/MantidAlgorithms/Minus.h | 3 + .../inc/MantidAlgorithms/ModeratorTzero.h | 3 + .../MantidAlgorithms/ModeratorTzeroLinear.h | 3 + .../MonitorEfficiencyCorUser.h | 3 + .../MantidAlgorithms/MonteCarloAbsorption.h | 4 + .../inc/MantidAlgorithms/MostLikelyMean.h | 1 + .../MultipleScatteringCylinderAbsorption.h | 4 + .../inc/MantidAlgorithms/Multiply.h | 3 + .../inc/MantidAlgorithms/MultiplyRange.h | 3 + .../NRCalculateSlitResolution.h | 3 + .../inc/MantidAlgorithms/NormaliseByCurrent.h | 1 + .../MantidAlgorithms/NormaliseByDetector.h | 1 + .../inc/MantidAlgorithms/NormaliseToMonitor.h | 1 + .../inc/MantidAlgorithms/NormaliseToUnity.h | 1 + .../MantidAlgorithms/OneMinusExponentialCor.h | 4 + .../inc/MantidAlgorithms/PDCalibration.h | 3 + .../MantidAlgorithms/PDFFourierTransform.h | 1 + .../MantidAlgorithms/PerformIndexOperations.h | 3 + .../inc/MantidAlgorithms/PhaseQuadMuon.h | 4 +- .../PlotAsymmetryByLogValue.h | 3 + .../Algorithms/inc/MantidAlgorithms/Plus.h | 3 + .../MantidAlgorithms/PolarizationCorrection.h | 3 + .../PolarizationEfficiencyCor.h | 3 + .../MantidAlgorithms/PolynomialCorrection.h | 4 + .../Algorithms/inc/MantidAlgorithms/Power.h | 3 + .../inc/MantidAlgorithms/PowerLawCorrection.h | 4 + .../Algorithms/inc/MantidAlgorithms/Q1D2.h | 3 + .../inc/MantidAlgorithms/Q1DWeighted.h | 1 + .../Algorithms/inc/MantidAlgorithms/Qxy.h | 1 + .../Algorithms/inc/MantidAlgorithms/RRFMuon.h | 3 + .../inc/MantidAlgorithms/RadiusSum.h | 3 + .../inc/MantidAlgorithms/ReadGroupsFromFile.h | 5 + .../Algorithms/inc/MantidAlgorithms/RealFFT.h | 4 + .../Algorithms/inc/MantidAlgorithms/Rebin.h | 5 + .../Algorithms/inc/MantidAlgorithms/Rebin2D.h | 3 + .../inc/MantidAlgorithms/RebinByPulseTimes.h | 5 + .../MantidAlgorithms/RebinByTimeAtSample.h | 5 + .../inc/MantidAlgorithms/RebinToWorkspace.h | 3 + .../Algorithms/inc/MantidAlgorithms/Rebunch.h | 1 + .../inc/MantidAlgorithms/RecordPythonScript.h | 3 + .../ReflectometryReductionOne2.h | 3 + .../ReflectometryReductionOneAuto2.h | 3 + .../Algorithms/inc/MantidAlgorithms/Regroup.h | 1 + .../inc/MantidAlgorithms/RemoveBins.h | 3 + .../inc/MantidAlgorithms/RemoveExpDecay.h | 1 + .../MantidAlgorithms/RemoveMaskedSpectra.h | 3 + .../MantidAlgorithms/RemoveWorkspaceHistory.h | 3 + .../inc/MantidAlgorithms/RenameWorkspace.h | 3 + .../inc/MantidAlgorithms/RenameWorkspaces.h | 3 + .../inc/MantidAlgorithms/ResampleX.h | 4 + .../ResizeRectangularDetector.h | 3 + .../inc/MantidAlgorithms/RingProfile.h | 3 + .../MayersSampleCorrection.h | 3 + .../inc/MantidAlgorithms/SassenaFFT.h | 4 + .../Algorithms/inc/MantidAlgorithms/Scale.h | 1 + .../Algorithms/inc/MantidAlgorithms/ScaleX.h | 3 + .../MantidAlgorithms/SetInstrumentParameter.h | 3 + .../inc/MantidAlgorithms/ShiftLogTime.h | 3 + .../inc/MantidAlgorithms/SmoothData.h | 3 + .../inc/MantidAlgorithms/SmoothNeighbours.h | 3 + .../Algorithms/inc/MantidAlgorithms/SofQW.h | 3 + .../inc/MantidAlgorithms/SofQWCentre.h | 3 + .../MantidAlgorithms/SofQWNormalisedPolygon.h | 3 + .../inc/MantidAlgorithms/SofQWPolygon.h | 3 + .../inc/MantidAlgorithms/SolidAngle.h | 1 + .../inc/MantidAlgorithms/SortEvents.h | 3 + .../inc/MantidAlgorithms/SpatialGrouping.h | 3 + .../SpecularReflectionCalculateTheta2.h | 3 + .../SpecularReflectionPositionCorrect2.h | 3 + .../MantidAlgorithms/SphericalAbsorption.h | 3 + .../inc/MantidAlgorithms/Stitch1D.h | 3 + .../inc/MantidAlgorithms/Stitch1DMany.h | 3 + .../inc/MantidAlgorithms/StripPeaks.h | 3 + .../MantidAlgorithms/StripVanadiumPeaks2.h | 3 + .../MantidAlgorithms/SumEventsByLogValue.h | 3 + .../inc/MantidAlgorithms/SumNeighbours.h | 3 + .../MantidAlgorithms/SumOverlappingTubes.h | 3 + .../inc/MantidAlgorithms/SumRowColumn.h | 3 + .../inc/MantidAlgorithms/SumSpectra.h | 3 + .../inc/MantidAlgorithms/TOFSANSResolution.h | 3 + .../TOFSANSResolutionByPixel.h | 3 + .../inc/MantidAlgorithms/Transpose.h | 4 + .../inc/MantidAlgorithms/UnGroupWorkspace.h | 3 + .../inc/MantidAlgorithms/UnwrapMonitor.h | 3 + .../MantidAlgorithms/UnwrapMonitorsInTOF.h | 3 + .../inc/MantidAlgorithms/UnwrapSNS.h | 1 + .../MantidAlgorithms/UpdateScriptRepository.h | 3 + .../inc/MantidAlgorithms/WeightedMean.h | 1 + .../WeightedMeanOfWorkspace.h | 3 + .../inc/MantidAlgorithms/WienerSmooth.h | 3 + Framework/Algorithms/src/ConjoinXRuns.cpp | 4 +- Framework/Algorithms/src/CreateWorkspace.cpp | 22 +- .../Algorithms/src/DiffractionFocussing.cpp | 6 +- .../src/MagFormFactorCorrection.cpp | 4 +- Framework/Algorithms/src/MaxEnt.cpp | 114 +- Framework/Algorithms/src/RingProfile.cpp | 4 +- .../SampleCorrections/SparseInstrument.cpp | 4 +- .../Algorithms/test/ChangeTimeZeroTest.h | 14 +- .../Algorithms/test/CreateWorkspaceTest.h | 74 +- .../test/DetectorEfficiencyVariationTest.h | 4 +- Framework/Algorithms/test/FilterEventsTest.h | 49 +- .../Algorithms/test/GroupWorkspacesTest.h | 10 +- .../Algorithms/test/MaskBinsFromTableTest.h | 4 +- .../Algorithms/test/MedianDetectorTestTest.h | 4 +- .../test/PDDetermineCharacterizationsTest.h | 4 +- .../Algorithms/test/RebinByTimeAtSampleTest.h | 3 +- Framework/Algorithms/test/RebinTest.h | 10 +- .../Algorithms/test/RemoveBackgroundTest.h | 4 +- Framework/Algorithms/test/SassenaFFTTest.h | 10 +- Framework/Algorithms/test/SofQWCutTest.h | 42 + Framework/Algorithms/test/Stitch1DTest.h | 12 +- .../Algorithms/test/UnGroupWorkspaceTest.h | 10 +- .../inc/MantidBeamline/ComponentInfo.h | 1 + Framework/Beamline/src/ComponentInfo.cpp | 6 + .../Crystal/inc/MantidCrystal/AddPeakHKL.h | 3 + .../inc/MantidCrystal/AnvredCorrection.h | 3 + .../inc/MantidCrystal/CalculatePeaksHKL.h | 3 + .../inc/MantidCrystal/CalculateUMatrix.h | 1 + .../Crystal/inc/MantidCrystal/CentroidPeaks.h | 3 + Framework/Crystal/inc/MantidCrystal/ClearUB.h | 3 + .../MantidCrystal/CombinePeaksWorkspaces.h | 3 + .../inc/MantidCrystal/CountReflections.h | 3 + .../inc/MantidCrystal/DiffPeaksWorkspaces.h | 3 + .../Crystal/inc/MantidCrystal/FilterPeaks.h | 3 + .../inc/MantidCrystal/FindClusterFaces.h | 3 + .../Crystal/inc/MantidCrystal/FindSXPeaks.h | 3 + .../inc/MantidCrystal/FindUBUsingFFT.h | 4 + .../MantidCrystal/FindUBUsingIndexedPeaks.h | 4 + .../FindUBUsingLatticeParameters.h | 4 + .../inc/MantidCrystal/FindUBUsingMinMaxD.h | 4 + .../GoniometerAnglesFromPhiRotation.h | 3 + Framework/Crystal/inc/MantidCrystal/HasUB.h | 3 + .../Crystal/inc/MantidCrystal/IndexPeaks.h | 3 + .../Crystal/inc/MantidCrystal/IndexSXPeaks.h | 3 + .../MantidCrystal/IntegratePeakTimeSlices.h | 3 + .../inc/MantidCrystal/IntegratePeaksHybrid.h | 4 + .../IntegratePeaksUsingClusters.h | 4 + Framework/Crystal/inc/MantidCrystal/LoadHKL.h | 3 + .../Crystal/inc/MantidCrystal/LoadIsawPeaks.h | 3 + .../inc/MantidCrystal/LoadIsawSpectrum.h | 3 + .../Crystal/inc/MantidCrystal/LoadIsawUB.h | 3 + .../inc/MantidCrystal/MaskPeaksWorkspace.h | 3 + .../OptimizeLatticeForCellType.h | 4 + .../inc/MantidCrystal/PeakIntegration.h | 3 + .../inc/MantidCrystal/PeakIntensityVsRadius.h | 3 + .../inc/MantidCrystal/PeakStatisticsTools.h | 24 +- .../Crystal/inc/MantidCrystal/PeaksInRegion.h | 3 + .../inc/MantidCrystal/PeaksOnSurface.h | 3 + .../MantidCrystal/PredictFractionalPeaks.h | 3 + .../Crystal/inc/MantidCrystal/PredictPeaks.h | 6 +- .../inc/MantidCrystal/SCDCalibratePanels.h | 3 + Framework/Crystal/inc/MantidCrystal/SaveHKL.h | 3 + .../Crystal/inc/MantidCrystal/SaveIsawPeaks.h | 3 + .../Crystal/inc/MantidCrystal/SaveIsawUB.h | 3 + .../inc/MantidCrystal/SelectCellOfType.h | 4 + .../inc/MantidCrystal/SelectCellWithForm.h | 4 + .../Crystal/inc/MantidCrystal/SetGoniometer.h | 3 + .../inc/MantidCrystal/SetSpecialCoordinates.h | 3 + Framework/Crystal/inc/MantidCrystal/SetUB.h | 4 + .../inc/MantidCrystal/ShowPeakHKLOffsets.h | 3 + .../inc/MantidCrystal/ShowPossibleCells.h | 4 + Framework/Crystal/inc/MantidCrystal/SortHKL.h | 3 + .../inc/MantidCrystal/SortPeaksWorkspace.h | 3 + .../StatisticsOfPeaksWorkspace.h | 3 + .../Crystal/inc/MantidCrystal/TransformHKL.h | 3 + .../src/ConnectedComponentLabeling.cpp | 14 +- Framework/Crystal/src/FindClusterFaces.cpp | 2 +- Framework/Crystal/src/LoadHKL.cpp | 4 + Framework/Crystal/src/LoadIsawPeaks.cpp | 9 +- Framework/Crystal/src/PeakStatisticsTools.cpp | 40 +- Framework/Crystal/src/PredictPeaks.cpp | 10 +- Framework/Crystal/src/SCDCalibratePanels.cpp | 12 +- Framework/Crystal/src/SaveHKL.cpp | 3 +- Framework/Crystal/src/SaveIsawPeaks.cpp | 10 +- Framework/Crystal/src/SortHKL.cpp | 130 +- .../src/StatisticsOfPeaksWorkspace.cpp | 25 + .../test/ConnectedComponentLabelingTest.h | 5 +- .../test/HardThresholdBackgroundTest.h | 2 +- Framework/Crystal/test/PeakBackgroundTest.h | 8 +- .../Crystal/test/PeakStatisticsToolsTest.h | 24 + Framework/Crystal/test/PredictPeaksTest.h | 4 +- .../Algorithms/CalculateChiSquared.h | 3 + .../Algorithms/CalculateCostFunction.h | 3 + .../Algorithms/EstimateFitParameters.h | 3 + .../Algorithms/EstimatePeakErrors.h | 3 + .../Algorithms/EvaluateFunction.h | 1 + .../inc/MantidCurveFitting/Algorithms/Fit.h | 4 + .../Algorithms/FitPowderDiffPeaks.h | 3 + .../MantidCurveFitting/Algorithms/LeBailFit.h | 3 + .../Algorithms/NormaliseByPeakArea.h | 4 + .../MantidCurveFitting/Algorithms/PawleyFit.h | 3 + .../Algorithms/PlotPeakByLogValue.h | 1 + .../RefinePowderInstrumentParameters3.h | 3 + .../Algorithms/SplineBackground.h | 3 + .../Algorithms/SplineInterpolation.h | 3 + .../Algorithms/SplineSmoothing.h | 3 + .../VesuvioCalculateGammaBackground.h | 3 + .../Algorithms/VesuvioCalculateMS.h | 5 + .../Functions/UserFunction1D.h | 1 + .../MantidCurveFitting/RalNlls/Workspaces.h | 6 +- .../src/Algorithms/EstimateFitParameters.cpp | 4 +- .../FuncMinimizers/TrustRegionMinimizer.cpp | 8 +- .../Functions/CrystalFieldMultiSpectrum.cpp | 14 +- .../test/Algorithms/EvaluateFunctionTest.h | 1 - .../test/Algorithms/LeBailFunctionTest.h | 10 +- .../test/Algorithms/PlotPeakByLogValueTest.h | 4 +- .../RefinePowderInstrumentParametersTest.h | 12 +- .../test/Functions/ChebfunBaseTest.h | 13 +- .../Functions/CrystalFieldMultiSpectrumTest.h | 10 + .../test/Functions/ProcessBackgroundTest.h | 4 +- .../test/Functions/SimpleChebfunTest.h | 4 +- .../IPeakFunctionCentreParameterNameTest.h | 7 +- .../test/IPeakFunctionIntensityTest.h | 19 +- .../inc/MantidDataHandling/CompressEvents.h | 3 + .../MantidDataHandling/CreateSampleShape.h | 3 + .../MantidDataHandling/DefineGaugeVolume.h | 3 + .../inc/MantidDataHandling/DeleteTableRows.h | 3 + .../inc/MantidDataHandling/DownloadFile.h | 3 + .../MantidDataHandling/DownloadInstrument.h | 3 + .../ExtractMonitorWorkspace.h | 3 + .../MantidDataHandling/FindDetectorsInShape.h | 3 + .../inc/MantidDataHandling/GroupDetectors2.h | 3 + .../inc/MantidDataHandling/Load.h | 4 + .../inc/MantidDataHandling/LoadAscii2.h | 3 + .../inc/MantidDataHandling/LoadBBY.h | 3 + .../inc/MantidDataHandling/LoadCalFile.h | 6 + .../inc/MantidDataHandling/LoadCanSAS1D2.h | 3 + .../inc/MantidDataHandling/LoadDaveGrp.h | 3 + .../inc/MantidDataHandling/LoadDetectorInfo.h | 3 + .../LoadDetectorsGroupingFile.h | 3 + .../inc/MantidDataHandling/LoadDiffCal.h | 3 + .../MantidDataHandling/LoadEmptyInstrument.h | 3 + .../inc/MantidDataHandling/LoadEventNexus.h | 3 + .../MantidDataHandling/LoadEventPreNexus2.h | 3 + .../inc/MantidDataHandling/LoadFITS.h | 3 + .../LoadFullprofResolution.h | 3 + .../LoadGSASInstrumentFile.h | 3 + .../inc/MantidDataHandling/LoadGSS.h | 3 + .../MantidDataHandling/LoadILLDiffraction.h | 3 + .../inc/MantidDataHandling/LoadILLIndirect2.h | 3 + .../MantidDataHandling/LoadILLReflectometry.h | 3 + .../inc/MantidDataHandling/LoadILLSANS.h | 3 + .../inc/MantidDataHandling/LoadILLTOF2.h | 3 + .../inc/MantidDataHandling/LoadISISNexus2.h | 3 + .../inc/MantidDataHandling/LoadInstrument.h | 4 + .../LoadInstrumentFromNexus.h | 3 + .../LoadInstrumentFromRaw.h | 3 + .../inc/MantidDataHandling/LoadIsawDetCal.h | 3 + .../inc/MantidDataHandling/LoadLog.h | 3 + .../inc/MantidDataHandling/LoadMask.h | 3 + .../inc/MantidDataHandling/LoadMcStas.h | 3 + .../inc/MantidDataHandling/LoadMcStasNexus.h | 3 + .../inc/MantidDataHandling/LoadMuonLog.h | 3 + .../inc/MantidDataHandling/LoadMuonNexus2.h | 3 + .../inc/MantidDataHandling/LoadNXSPE.h | 3 + .../inc/MantidDataHandling/LoadNXcanSAS.h | 3 + .../inc/MantidDataHandling/LoadNexus.h | 6 + .../inc/MantidDataHandling/LoadNexusLogs.h | 3 + .../MantidDataHandling/LoadNexusMonitors2.h | 3 + .../MantidDataHandling/LoadNexusProcessed.h | 3 + .../inc/MantidDataHandling/LoadPDFgetNFile.h | 3 + .../MantidDataHandling/LoadParameterFile.h | 3 + .../inc/MantidDataHandling/LoadPreNexus.h | 3 + .../MantidDataHandling/LoadPreNexusMonitors.h | 3 + .../inc/MantidDataHandling/LoadQKK.h | 3 + .../inc/MantidDataHandling/LoadRKH.h | 3 + .../inc/MantidDataHandling/LoadRaw3.h | 4 + .../inc/MantidDataHandling/LoadRawBin0.h | 3 + .../inc/MantidDataHandling/LoadRawSpectrum0.h | 3 + .../inc/MantidDataHandling/LoadSESANS.h | 3 + .../inc/MantidDataHandling/LoadSINQFocus.h | 3 + .../inc/MantidDataHandling/LoadSNSspec.h | 3 + .../inc/MantidDataHandling/LoadSPE.h | 3 + .../LoadSampleDetailsFromRaw.h | 3 + .../inc/MantidDataHandling/LoadSpec.h | 3 + .../inc/MantidDataHandling/LoadSpice2D.h | 3 + .../inc/MantidDataHandling/LoadSpiceAscii.h | 3 + .../MantidDataHandling/LoadSpiceXML2DDet.h | 3 + .../inc/MantidDataHandling/LoadTBL.h | 3 + .../inc/MantidDataHandling/LoadTOFRawNexus.h | 3 + .../MantidDataHandling/LoadVulcanCalFile.h | 6 + .../inc/MantidDataHandling/MaskDetectors.h | 4 + .../MantidDataHandling/MaskDetectorsInShape.h | 3 + .../inc/MantidDataHandling/MaskSpectra.h | 3 + .../inc/MantidDataHandling/MergeLogs.h | 3 + .../ModifyDetectorDotDatFile.h | 3 + .../MoveInstrumentComponent.h | 3 + .../inc/MantidDataHandling/PatchBBY.h | 3 + .../inc/MantidDataHandling/RawFileInfo.h | 3 + .../inc/MantidDataHandling/RemoveLogs.h | 3 + .../inc/MantidDataHandling/RenameLog.h | 3 + .../RotateInstrumentComponent.h | 3 + .../inc/MantidDataHandling/RotateSource.h | 3 + .../inc/MantidDataHandling/SaveANSTOAscii.h | 3 + .../inc/MantidDataHandling/SaveAscii2.h | 6 + .../inc/MantidDataHandling/SaveCSV.h | 3 + .../inc/MantidDataHandling/SaveCalFile.h | 6 + .../inc/MantidDataHandling/SaveCanSAS1D2.h | 3 + .../inc/MantidDataHandling/SaveDaveGrp.h | 3 + .../SaveDetectorsGrouping.h | 3 + .../inc/MantidDataHandling/SaveDiffCal.h | 3 + .../MantidDataHandling/SaveDiffFittingAscii.h | 3 + .../inc/MantidDataHandling/SaveFITS.h | 3 + .../inc/MantidDataHandling/SaveFocusedXYE.h | 3 + .../SaveFullprofResolution.h | 3 + .../SaveGSASInstrumentFile.h | 3 + .../inc/MantidDataHandling/SaveGSS.h | 3 + .../MantidDataHandling/SaveILLCosmosAscii.h | 3 + .../inc/MantidDataHandling/SaveISISNexus.h | 3 + .../inc/MantidDataHandling/SaveIsawDetCal.h | 3 + .../inc/MantidDataHandling/SaveMask.h | 3 + .../inc/MantidDataHandling/SaveNXSPE.h | 3 + .../inc/MantidDataHandling/SaveNXTomo.h | 3 + .../inc/MantidDataHandling/SaveNXcanSAS.h | 3 + .../inc/MantidDataHandling/SaveNexus.h | 3 + .../MantidDataHandling/SaveNexusProcessed.h | 3 + .../MantidDataHandling/SaveOpenGenieAscii.h | 3 + .../inc/MantidDataHandling/SavePAR.h | 3 + .../inc/MantidDataHandling/SavePDFGui.h | 3 + .../inc/MantidDataHandling/SavePHX.h | 3 + .../MantidDataHandling/SaveParameterFile.h | 3 + .../inc/MantidDataHandling/SaveRKH.h | 3 + .../MantidDataHandling/SaveReflCustomAscii.h | 3 + .../SaveReflThreeColumnAscii.h | 3 + .../inc/MantidDataHandling/SaveSESANS.h | 3 + .../inc/MantidDataHandling/SaveSPE.h | 3 + .../inc/MantidDataHandling/SaveTBL.h | 3 + .../SaveToSNSHistogramNexus.h | 3 + .../inc/MantidDataHandling/SetBeam.h | 3 + .../inc/MantidDataHandling/SetSample.h | 3 + .../MantidDataHandling/SetSampleMaterial.h | 4 + .../MantidDataHandling/SortTableWorkspace.h | 3 + .../UpdateInstrumentFromFile.h | 3 + Framework/DataHandling/src/LoadMask.cpp | 19 +- .../DataHandling/src/LoadNexusProcessed.cpp | 8 + .../DataHandling/src/LoadSpiceXML2DDet.cpp | 21 +- .../DataHandling/src/ParallelEventLoader.cpp | 4 +- Framework/DataHandling/src/SaveAscii2.cpp | 4 +- Framework/DataHandling/src/SaveGSS.cpp | 5 +- .../DataHandling/test/FindDetectorsParTest.h | 16 +- Framework/DataHandling/test/LoadCalFileTest.h | 4 +- .../DataHandling/test/LoadDetectorInfoTest.h | 17 +- .../DataHandling/test/LoadEventNexusTest.h | 6 +- .../test/LoadEventPreNexus2Test.h | 4 +- Framework/DataHandling/test/LoadMaskTest.h | 8 +- .../DataHandling/test/LoadNexusMonitorsTest.h | 8 +- Framework/DataHandling/test/LoadTest.h | 8 +- Framework/DataHandling/test/SaveAscii2Test.h | 24 +- Framework/DataHandling/test/SavePHXTest.h | 4 +- .../inc/MantidDataObjects/MDBoxBase.h | 8 +- .../inc/MantidDataObjects/MDBoxBase.tcc | 11 +- .../inc/MantidDataObjects/MDBoxIterator.h | 8 +- .../inc/MantidDataObjects/MDBoxIterator.tcc | 4 +- .../inc/MantidDataObjects/MDEventWorkspace.h | 2 +- .../MantidDataObjects/MDEventWorkspace.tcc | 6 +- .../inc/MantidDataObjects/MDHistoWorkspace.h | 5 +- .../MDHistoWorkspaceIterator.h | 8 +- .../DataObjects/inc/MantidDataObjects/Peak.h | 6 + .../DataObjects/src/FractionalRebinning.cpp | 23 +- .../DataObjects/src/MDHistoWorkspace.cpp | 35 +- .../src/MDHistoWorkspaceIterator.cpp | 10 +- Framework/DataObjects/src/Peak.cpp | 43 +- Framework/DataObjects/src/PeakColumn.cpp | 8 +- Framework/DataObjects/src/PeaksWorkspace.cpp | 15 +- Framework/DataObjects/src/Workspace2D.cpp | 4 +- Framework/DataObjects/test/EventListTest.h | 20 +- Framework/DataObjects/test/FakeMDTest.h | 2 - Framework/DataObjects/test/MDBoxBaseTest.h | 26 +- .../DataObjects/test/MDBoxFlatTreeTest.h | 4 +- .../DataObjects/test/MDBoxSaveableTest.h | 3 +- Framework/DataObjects/test/MDBoxTest.h | 12 +- .../DataObjects/test/MDEventWorkspaceTest.h | 23 +- Framework/DataObjects/test/MDGridBoxTest.h | 86 +- .../test/MDHistoWorkspaceIteratorTest.h | 171 +- .../DataObjects/test/MDHistoWorkspaceTest.h | 21 +- Framework/DataObjects/test/PeakTest.h | 3 +- .../DataObjects/test/PeaksWorkspaceTest.h | 2 +- Framework/Geometry/CMakeLists.txt | 4 +- .../inc/MantidGeometry/Crystal/IPeak.h | 4 + .../inc/MantidGeometry/IObjComponent.h | 9 +- .../Instrument/ComponentVisitor.h | 1 + .../Instrument/InstrumentVisitor.h | 3 + .../Instrument/StructuredDetector.h | 4 +- .../inc/MantidGeometry/Objects/CSGObject.h | 1 + .../inc/MantidGeometry/Objects/IObject.h | 1 - .../Rendering/GeometryHandler.h | 12 +- .../Rendering/GeometryTriangulator.h | 4 +- .../Geometry/src/Instrument/ComponentInfo.cpp | 24 +- .../Instrument/InstrumentDefinitionParser.cpp | 4 +- .../src/Instrument/InstrumentVisitor.cpp | 16 +- .../src/Instrument/RectangularDetector.cpp | 2 +- .../src/Instrument/StructuredDetector.cpp | 8 +- Framework/Geometry/src/Objects/CSGObject.cpp | 4 +- .../Geometry/src/Objects/ShapeFactory.cpp | 6 +- .../src/Rendering/GeometryHandler.cpp | 17 +- .../src/Rendering/GeometryTriangulator.cpp | 2 +- .../src/Rendering/RenderingHelpers.cpp | 116 +- .../Geometry/src/Rendering/ShapeInfo.cpp | 1 + .../src/Rendering/vtkGeometryCacheReader.cpp | 8 +- Framework/Geometry/test/CSGObjectTest.h | 11 +- Framework/Geometry/test/CenteringGroupTest.h | 8 +- .../test/CompositeBraggScattererTest.h | 4 +- .../Geometry/test/GroupTransformationTest.h | 4 +- Framework/Geometry/test/IndexingUtilsTest.h | 20 +- Framework/Geometry/test/MockObjects.h | 3 + Framework/Geometry/test/ObjCompAssemblyTest.h | 9 +- .../Geometry/test/ParObjCompAssemblyTest.h | 1 - Framework/Geometry/test/PointGroupTest.h | 12 +- .../Geometry/test/ReflectionConditionTest.h | 8 +- Framework/Geometry/test/ShapeInfoTest.h | 2 +- Framework/Geometry/test/SpaceGroupTest.h | 8 +- .../Geometry/test/StructuredDetectorTest.h | 33 +- .../test/SymmetryOperationFactoryTest.h | 8 +- .../inc/MantidHistogramData/Histogram.h | 2 +- .../MantidHistogramData/HistogramBuilder.h | 5 + .../HistogramData/src/HistogramBuilder.cpp | 2 + .../HistogramData/test/HistogramBuilderTest.h | 27 + .../inc/MantidICat/CatalogDownloadDataFiles.h | 3 + .../ICat/inc/MantidICat/CatalogGetDataFiles.h | 3 + .../ICat/inc/MantidICat/CatalogGetDataSets.h | 3 + .../ICat/inc/MantidICat/CatalogKeepAlive.h | 3 + .../inc/MantidICat/CatalogListInstruments.h | 3 + .../CatalogListInvestigationTypes.h | 3 + Framework/ICat/inc/MantidICat/CatalogLogin.h | 3 + Framework/ICat/inc/MantidICat/CatalogLogout.h | 3 + .../ICat/inc/MantidICat/CatalogMyDataSearch.h | 3 + .../ICat/inc/MantidICat/CatalogPublish.h | 3 + Framework/ICat/inc/MantidICat/CatalogSearch.h | 4 + Framework/Indexing/src/IndexInfo.cpp | 3 +- Framework/Kernel/CMakeLists.txt | 2 +- .../inc/MantidKernel/PropertyWithValue.h | 2 +- .../inc/MantidKernel/PropertyWithValue.tcc | 6 +- .../Kernel/inc/MantidKernel/Statistics.h | 3 + Framework/Kernel/src/ConfigService.cpp | 5 +- Framework/Kernel/src/Statistics.cpp | 40 +- Framework/Kernel/test/ArrayPropertyTest.h | 9 +- Framework/Kernel/test/ConfigServiceTest.h | 6 +- .../Kernel/test/DiskBufferISaveableTest.h | 39 +- Framework/Kernel/test/DiskBufferTest.h | 29 +- Framework/Kernel/test/FileDescriptorTest.h | 8 +- Framework/Kernel/test/GlobTest.h | 10 +- Framework/Kernel/test/InterpolationTest.h | 6 +- Framework/Kernel/test/MutexTest.h | 7 +- .../test/NDPseudoRandomNumberGeneratorTest.h | 4 +- Framework/Kernel/test/NexusDescriptorTest.h | 8 +- Framework/Kernel/test/PropertyManagerTest.h | 6 +- Framework/Kernel/test/PropertyWithValueTest.h | 4 +- Framework/Kernel/test/SobolSequenceTest.h | 4 +- Framework/Kernel/test/ThreadSchedulerTest.h | 4 +- Framework/Kernel/test/UsageServiceTest.h | 10 +- .../MantidLiveData/ISIS/FakeISISEventDAE.h | 3 + .../MantidLiveData/ISIS/FakeISISHistoDAE.h | 3 + .../MantidLiveData/Kafka/KafkaEventListener.h | 16 +- .../MantidLiveData/SNSLiveEventDataListener.h | 2 +- .../LiveData/src/Kafka/KafkaEventListener.cpp | 28 +- .../src/Kafka/KafkaEventStreamDecoder.cpp | 27 +- .../private/Schema/flatbuffers/flatbuffers.h | 6 +- .../LiveData/src/SNSLiveEventDataListener.cpp | 104 +- .../test/KafkaEventStreamDecoderTest.h | 50 +- Framework/LiveData/test/KafkaTesting.h | 78 +- Framework/LiveData/test/LoadLiveDataTest.h | 8 +- .../inc/MantidMDAlgorithms/AccumulateMD.h | 3 + .../inc/MantidMDAlgorithms/AndMD.h | 3 + .../inc/MantidMDAlgorithms/BinMD.h | 3 + .../MantidMDAlgorithms/CalculateCoverageDGS.h | 3 + .../inc/MantidMDAlgorithms/CentroidPeaksMD2.h | 3 + .../ConvertMDHistoToMatrixWorkspace.h | 4 + .../ConvertToDetectorFaceMD.h | 3 + .../ConvertToDiffractionMDWorkspace3.h | 3 + .../inc/MantidMDAlgorithms/ConvertToMD.h | 5 + .../ConvertToMDMinMaxGlobal.h | 3 + .../ConvertToMDMinMaxLocal.h | 3 + .../ConvertToReflectometryQ.h | 3 + .../inc/MantidMDAlgorithms/CreateMD.h | 3 + .../CreateMDHistoWorkspace.h | 3 + .../MantidMDAlgorithms/CreateMDWorkspace.h | 4 + .../inc/MantidMDAlgorithms/CutMD.h | 3 + .../inc/MantidMDAlgorithms/DivideMD.h | 3 + .../inc/MantidMDAlgorithms/EqualToMD.h | 3 + .../MantidMDAlgorithms/EvaluateMDFunction.h | 3 + .../inc/MantidMDAlgorithms/ExponentialMD.h | 3 + .../inc/MantidMDAlgorithms/FakeMDEventData.h | 3 + .../inc/MantidMDAlgorithms/FindPeaksMD.h | 3 + .../inc/MantidMDAlgorithms/GreaterThanMD.h | 3 + .../ImportMDEventWorkspace.h | 3 + .../ImportMDHistoWorkspace.h | 3 + .../MantidMDAlgorithms/IntegrateEllipsoids.h | 3 + .../IntegrateEllipsoidsTwoStep.h | 3 + .../inc/MantidMDAlgorithms/IntegrateFlux.h | 3 + .../IntegrateMDHistoWorkspace.h | 3 + .../MantidMDAlgorithms/IntegratePeaksCWSD.h | 4 + .../MantidMDAlgorithms/IntegratePeaksMD2.h | 4 + .../MantidMDAlgorithms/IntegratePeaksMDHKL.h | 4 + .../inc/MantidMDAlgorithms/LessThanMD.h | 3 + .../inc/MantidMDAlgorithms/LoadMD.h | 1 + .../inc/MantidMDAlgorithms/LoadSQW2.h | 3 + .../inc/MantidMDAlgorithms/LogarithmMD.h | 3 + .../inc/MantidMDAlgorithms/MDNormDirectSC.h | 3 + .../inc/MantidMDAlgorithms/MDNormSCD.h | 3 + .../inc/MantidMDAlgorithms/MaskMD.h | 3 + .../inc/MantidMDAlgorithms/MergeMD.h | 3 + .../inc/MantidMDAlgorithms/MergeMDFiles.h | 3 + .../inc/MantidMDAlgorithms/MinusMD.h | 3 + .../inc/MantidMDAlgorithms/MultiplyMD.h | 3 + .../inc/MantidMDAlgorithms/NotMD.h | 3 + .../inc/MantidMDAlgorithms/OrMD.h | 3 + .../inc/MantidMDAlgorithms/PlusMD.h | 3 + .../inc/MantidMDAlgorithms/PowerMD.h | 4 + .../FitResolutionConvolvedModel.h | 3 + .../SimulateResolutionConvolvedModel.h | 4 +- .../inc/MantidMDAlgorithms/ReplicateMD.h | 3 + .../inc/MantidMDAlgorithms/SaveMD2.h | 3 + .../inc/MantidMDAlgorithms/SaveZODS.h | 1 + .../inc/MantidMDAlgorithms/SliceMD.h | 3 + .../inc/MantidMDAlgorithms/SmoothMD.h | 3 + .../inc/MantidMDAlgorithms/ThresholdMD.h | 3 + .../inc/MantidMDAlgorithms/TransformMD.h | 3 + .../inc/MantidMDAlgorithms/TransposeMD.h | 3 + .../inc/MantidMDAlgorithms/WeightedMeanMD.h | 3 + .../inc/MantidMDAlgorithms/XorMD.h | 3 + Framework/MDAlgorithms/src/BinMD.cpp | 6 +- .../src/ConvertCWPDMDToSpectra.cpp | 2 +- .../MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp | 2 +- Framework/MDAlgorithms/src/FindPeaksMD.cpp | 4 + Framework/MDAlgorithms/src/FitMD.cpp | 3 - .../src/GetSpiceDataRawCountsFromMD.cpp | 4 +- .../src/IntegrateMDHistoWorkspace.cpp | 15 +- .../MDAlgorithms/src/IntegratePeaksCWSD.cpp | 2 +- .../Resolution/TobyFitResolutionModel.cpp | 1 - .../ResolutionConvolvedCrossSection.cpp | 8 +- .../MDAlgorithms/src/QueryMDWorkspace.cpp | 3 +- Framework/MDAlgorithms/src/ReplicateMD.cpp | 6 +- Framework/MDAlgorithms/src/SmoothMD.cpp | 9 +- Framework/MDAlgorithms/src/TransposeMD.cpp | 2 +- Framework/MDAlgorithms/src/WeightedMeanMD.cpp | 11 +- .../test/ConvertCWSDExpToMomentumTest.h | 4 +- .../test/ConvertSpiceDataToRealSpaceTest.h | 4 +- Framework/MDAlgorithms/test/DivideMDTest.h | 2 +- .../MDAlgorithms/test/FakeMDEventDataTest.h | 2 - Framework/MDAlgorithms/test/FitMDTest.h | 17 +- Framework/MDAlgorithms/test/LoadMDTest.h | 4 +- .../MDAlgorithms/test/MDTransfModQTest.h | 4 +- Framework/MDAlgorithms/test/MDTransfQ3DTest.h | 4 +- Framework/MDAlgorithms/test/MaskMDTest.h | 2 +- .../MDAlgorithms/test/MergeMDFilesTest.h | 8 +- Framework/MDAlgorithms/test/MinusMDTest.h | 2 +- Framework/MDAlgorithms/test/MultiplyMDTest.h | 2 +- Framework/MDAlgorithms/test/ReplicateMDTest.h | 4 +- .../ResolutionConvolvedCrossSectionTest.h | 3 +- .../MDAlgorithms/test/TobyFitYVectorTest.h | 4 +- Framework/MDAlgorithms/test/TransformMDTest.h | 3 +- .../api/PythonAlgorithm/AlgorithmAdapter.h | 2 + .../mantid/api/src/Exports/IAlgorithm.cpp | 4 + .../mantid/api/src/Exports/IPeak.cpp | 9 + .../src/PythonAlgorithm/AlgorithmAdapter.cpp | 16 + .../dataobjects/src/Exports/Workspace2D.cpp | 7 +- .../mantid/kernel/CMakeLists.txt | 2 +- Framework/PythonInterface/mantid/simpleapi.py | 4 + .../AlignAndFocusPowderFromFiles.py | 3 + .../plugins/algorithms/AlignComponents.py | 3 + .../algorithms/ApplyDetectorScanEffCorr.py | 3 + .../plugins/algorithms/BASISDiffraction.py | 3 + .../plugins/algorithms/BASISReduction311.py | 3 + .../algorithms/CalculateSampleTransmission.py | 3 + .../CalibrateRectangularDetectors.py | 3 + .../plugins/algorithms/CheckForSampleLogs.py | 3 + .../plugins/algorithms/CleanFileCache.py | 3 + .../plugins/algorithms/CompareSampleLogs.py | 3 + .../plugins/algorithms/ConjoinFiles.py | 3 + .../plugins/algorithms/ConjoinSpectra.py | 3 + .../algorithms/ConvertSnsRoiFileToMask.py | 3 + .../plugins/algorithms/CorrectLogTimes.py | 3 + .../plugins/algorithms/CorrectTOF.py | 3 + .../algorithms/CreateEmptyTableWorkspace.py | 3 + .../algorithms/CreateLeBailFitInput.py | 3 + .../plugins/algorithms/CropWorkspaceRagged.py | 3 + .../algorithms/DNSComputeDetEffCorrCoefs.py | 3 + .../algorithms/DNSFlippingRatioCorr.py | 3 + .../plugins/algorithms/DNSMergeRuns.py | 3 + .../plugins/algorithms/EnggCalibrate.py | 3 + .../plugins/algorithms/EnggCalibrateFull.py | 3 + .../algorithms/EnggFitDIFCFromPeaks.py | 3 + .../plugins/algorithms/EnggFitPeaks.py | 3 + .../plugins/algorithms/EnggFocus.py | 3 + .../plugins/algorithms/ExportExperimentLog.py | 3 + .../plugins/algorithms/ExportGeometry.py | 3 + .../algorithms/ExportSampleLogsToCSVFile.py | 3 + .../plugins/algorithms/ExportSpectraMask.py | 3 + .../plugins/algorithms/ExtractMonitors.py | 3 + .../plugins/algorithms/FilterLogByTime.py | 3 + .../plugins/algorithms/FitGaussian.py | 3 + .../algorithms/GSASIIRefineFitPeaks.py | 3 + .../GenerateGroupingSNSInelastic.py | 3 + .../plugins/algorithms/GetEiT0atSNS.py | 3 + .../plugins/algorithms/LoadAndMerge.py | 3 + .../plugins/algorithms/LoadEmptyVesuvio.py | 4 + .../plugins/algorithms/LoadFullprofFile.py | 3 + .../algorithms/LoadLogPropertyTable.py | 3 + .../plugins/algorithms/LoadMultipleGSS.py | 3 + .../plugins/algorithms/LoadVesuvio.py | 6 + .../plugins/algorithms/LoadVisionElasticBS.py | 3 + .../plugins/algorithms/LoadVisionElasticEQ.py | 3 + .../plugins/algorithms/LoadVisionInelastic.py | 3 + .../MagnetismReflectometryReduction.py | 35 +- .../plugins/algorithms/MaskAngle.py | 3 + .../plugins/algorithms/MaskBTP.py | 3 + .../algorithms/MaskWorkspaceToCalFile.py | 4 + .../plugins/algorithms/Mean.py | 3 + .../plugins/algorithms/MergeCalFiles.py | 4 + .../plugins/algorithms/MuonMaxent.py | 3 + .../plugins/algorithms/PDToGUDRUN.py | 3 + .../plugins/algorithms/PDToPDFgetN.py | 3 + .../plugins/algorithms/PearlMCAbsorption.py | 4 + .../algorithms/PoldiCreatePeaksFromFile.py | 3 + .../plugins/algorithms/RefLReduction.py | 390 ---- .../algorithms/RefinePowderDiffProfileSeq.py | 3 + .../plugins/algorithms/RetrieveRunInfo.py | 3 + .../plugins/algorithms/SANSSubtract.py | 3 + .../plugins/algorithms/SNSPowderReduction.py | 3 + .../plugins/algorithms/SaveNexusPD.py | 3 + .../plugins/algorithms/SavePlot1DAsJson.py | 3 + .../plugins/algorithms/SaveReflections.py | 2 +- .../plugins/algorithms/SortByQVectors.py | 3 + .../plugins/algorithms/SortDetectors.py | 3 + .../plugins/algorithms/SortXAxis.py | 26 +- .../plugins/algorithms/StringToPng.py | 3 + .../plugins/algorithms/SuggestTibCNCS.py | 3 + .../plugins/algorithms/SuggestTibHYSPEC.py | 3 + .../plugins/algorithms/TOFTOFCropWorkspace.py | 3 + .../plugins/algorithms/TOFTOFMergeRuns.py | 3 + .../plugins/algorithms/USANSSimulation.py | 3 + .../AddSampleLogMultiple.py | 3 + .../CalculateMonteCarloAbsorption.py | 3 + .../ConvertMultipleRunsToSingleCrystalMD.py | 3 + .../DirectILLApplySelfShielding.py | 3 + .../DirectILLCollectData.py | 3 + .../DirectILLDiagnostics.py | 3 + .../DirectILLIntegrateVanadium.py | 3 + .../WorkflowAlgorithms/DirectILLReduction.py | 4 + .../DirectILLSelfShielding.py | 3 + .../ISISIndirectDiffractionReduction.py | 5 +- .../IndirectILLEnergyTransfer.py | 3 + .../IndirectILLReductionFWS.py | 3 + .../IndirectILLReductionQENS.py | 3 + .../MDNormSCDPreprocessIncoherent.py | 3 + .../OSIRISDiffractionReduction.py | 3 + .../PowderDiffILLDetEffCorr.py | 3 + .../PowderDiffILLDetScanReduction.py | 3 + .../PowderDiffILLReduction.py | 3 + .../WorkflowAlgorithms/REFLReprocess.py | 229 -- .../ReactorSANSResolution.py | 3 + .../WorkflowAlgorithms/SavePlot1D.py | 3 + .../WorkflowAlgorithms/SaveVulcanGSS.py | 3 + .../SimpleShapeMonteCarloAbsorption.py | 3 + .../SingleCrystalDiffuseReduction.py | 3 + .../WorkflowAlgorithms/TimeSlice.py | 3 + .../WorkflowAlgorithms/USANSReduction.py | 3 + .../VesuvioDiffractionReduction.py | 3 + .../plugins/algorithms/sfCalculator.py | 1441 ------------ .../test/python/mantid/api/AlgorithmTest.py | 1 + .../plugins/algorithms/SaveReflectionsTest.py | 2 +- .../plugins/algorithms/SortXAxisTest.py | 90 +- .../test/AbortRemoteJob2Test.h | 6 +- .../test/AbortRemoteJobTest.h | 6 +- .../RemoteAlgorithms/test/Authenticate2Test.h | 6 +- .../RemoteAlgorithms/test/AuthenticateTest.h | 6 +- .../test/DownloadRemoteFile2Test.h | 6 +- .../test/DownloadRemoteFileTest.h | 6 +- Framework/RemoteAlgorithms/test/Logout2Test.h | 6 +- .../test/QueryAllRemoteJobs2Test.h | 6 +- .../test/QueryAllRemoteJobsTest.h | 6 +- .../test/QueryRemoteFile2Test.h | 6 +- .../test/QueryRemoteFileTest.h | 6 +- .../test/QueryRemoteJob2Test.h | 6 +- .../test/QueryRemoteJobTest.h | 6 +- .../test/StartRemoteTransaction2Test.h | 6 +- .../test/StartRemoteTransactionTest.h | 6 +- .../test/StopRemoteTransaction2Test.h | 6 +- .../test/StopRemoteTransactionTest.h | 6 +- .../test/SubmitRemoteJob2Test.h | 6 +- .../test/SubmitRemoteJobTest.h | 6 +- .../test/UploadRemoteFile2Test.h | 6 +- .../test/UploadRemoteFileTest.h | 6 +- Framework/SINQ/inc/MantidSINQ/InvertMDDim.h | 3 + .../SINQ/inc/MantidSINQ/LoadFlexiNexus.h | 3 + .../inc/MantidSINQ/MDHistoToWorkspace2D.h | 3 + .../inc/MantidSINQ/PoldiCreatePeaksFromCell.h | 3 + .../SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h | 3 + .../SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h | 3 + Framework/SINQ/inc/MantidSINQ/ProjectMD.h | 3 + .../SINQ/inc/MantidSINQ/SINQTranspose3D.h | 4 +- Framework/SINQ/inc/MantidSINQ/SliceMDHisto.h | 3 + Framework/SINQ/test/PoldiFitPeaks1D2Test.h | 4 +- Framework/SINQ/test/PoldiFitPeaks1DTest.h | 4 +- .../SINQ/test/PoldiIndexKnownCompoundsTest.h | 8 +- Framework/SINQ/test/PoldiPeakSearchTest.h | 5 +- .../test/ScriptRepositoryTestImpl.h | 9 +- Framework/WorkflowAlgorithms/CMakeLists.txt | 2 - .../AlignAndFocusPowder.h | 3 + .../LoadEventAndCompress.h | 3 + .../MantidWorkflowAlgorithms/RefReduction.h | 87 - .../inc/MantidWorkflowAlgorithms/RefRoi.h | 1 + .../SANSBeamFluxCorrection.h | 3 + .../SANSSolidAngleCorrection.h | 3 + .../WorkflowAlgorithms/src/RefReduction.cpp | 817 ------- MantidPlot/src/ApplicationWindow.cpp | 5 +- .../tests/analysis/REFLReduction.py | 44 - .../tests/analysis/REFLWithBackground.py | 44 - .../tests/analysis/REFMReduction.py | 36 - .../SystemTests/tests/analysis/SortHKLTest.py | 6 +- .../tests/analysis/VesuvioCommandsTest.py | 2 + .../tests/analysis/VesuvioCorrectionsTest.py | 2 + buildconfig/CMake/DarwinSetup.cmake | 11 +- buildconfig/CMake/GoogleTest.in | 1 + buildconfig/CMake/googletest_msvc_cpp11.patch | 41 + buildconfig/Jenkins/buildscript | 79 +- buildconfig/Jenkins/check_for_changes | 44 +- buildconfig/Jenkins/jenkins-slave.sh | 11 +- buildconfig/class_maker.py | 2 +- dev-docs/source/AutomatedBuildProcess.rst | 70 + dev-docs/source/BuildingOnOSX.rst | 440 ++++ dev-docs/source/BuildingVATES.rst | 121 + dev-docs/source/BuildingWithCMake.rst | 121 + dev-docs/source/DataFilesForTesting.rst | 282 +++ dev-docs/source/DebuggingUnitTests.rst | 101 + dev-docs/source/Dependencies.rst | 41 - dev-docs/source/DesignDocumentGuides.rst | 121 + dev-docs/source/DeveloperAccounts.rst | 63 + .../source/DevelopmentAndReleaseCycle.rst | 27 + dev-docs/source/DoxygenSetup.rst | 83 + dev-docs/source/GUIDesignGuidelines.rst | 10 +- dev-docs/source/GettingStarted.rst | 80 +- dev-docs/source/GitWorkflow.rst | 190 ++ dev-docs/source/IssueTracking.rst | 135 ++ dev-docs/source/JenkinsConfiguration.rst | 460 ++++ dev-docs/source/LoadAlgorithmHook.rst | 63 + dev-docs/source/Logging.rst | 3 +- .../MVPTutorial/CalculatorExample/index.rst | 4 +- dev-docs/source/MVPTutorial/Introduction.rst | 2 +- .../source/MultiThreadingInAlgorithms.rst | 65 + dev-docs/source/PatchReleaseChecklist.rst | 151 ++ ...ythonViews.rst => QtDesignerForPython.rst} | 25 +- dev-docs/source/ReleaseChecklist.rst | 214 ++ dev-docs/source/RemoteJobSubmissionAPI.rst | 390 ++++ dev-docs/source/RunningTheUnitTests.rst | 135 ++ .../AlgorithmDocumentation.rst | 0 .../AlgorithmUsageExamples.rst | 0 dev-docs/source/Standards/CPPStandards.rst | 378 ++++ .../DocumentationGuideForDevs.rst | 0 .../InterfaceDocumentation.rst | 0 dev-docs/source/Standards/Libraries.rst | 53 + dev-docs/source/Standards/MantidStandards.rst | 119 + dev-docs/source/Standards/PythonStandards.rst | 65 + .../source/Standards/UnitTestStandards.rst | 25 + dev-docs/source/Standards/index.rst | 44 + dev-docs/source/SystemTests.rst | 228 ++ dev-docs/source/TSC.rst | 13 + dev-docs/source/TestingUtilities.rst | 50 + .../{UsefulTools.rst => ToolsOverview.rst} | 7 +- dev-docs/source/UnitTestGoodPractice.rst | 191 ++ dev-docs/source/WritingAnAlgorithm.rst | 249 ++ ...WritingCustomConvertToMDTransformation.rst | 197 ++ dev-docs/source/WritingPerformanceTests.rst | 154 ++ dev-docs/source/conf.py | 5 +- dev-docs/source/images/AttachToProcess.png | Bin 0 -> 32164 bytes dev-docs/source/images/BuildStatuses.png | Bin 0 -> 30343 bytes dev-docs/source/images/CodeFreezePR.png | Bin 0 -> 97943 bytes .../source/images/ConvertToMDClassDiagram.gif | Bin 0 -> 19417 bytes .../images/DevelopmentAndReleaseCycle.png | Bin 0 -> 26344 bytes .../source/images/ExternalDataSchematic.png | Bin 0 -> 30206 bytes dev-docs/source/images/Mocking.png | Bin 0 -> 17303 bytes dev-docs/source/images/RestartBuild.png | Bin 0 -> 79478 bytes .../VisualStudioTestDebugProperties.png | Bin 0 -> 96923 bytes dev-docs/source/index.rst | 175 +- docs/source/algorithms/Abins-v1.rst | 2 +- docs/source/algorithms/AbortRemoteJob-v1.rst | 2 +- docs/source/algorithms/AbortRemoteJob-v2.rst | 2 +- .../algorithms/AbsorptionCorrection-v1.rst | 2 +- docs/source/algorithms/AccumulateMD-v1.rst | 2 +- .../source/algorithms/AddLogDerivative-v1.rst | 2 +- docs/source/algorithms/AddNote-v1.rst | 2 +- docs/source/algorithms/AddPeak-v1.rst | 2 +- docs/source/algorithms/AddPeakHKL-v1.rst | 2 +- docs/source/algorithms/AddSampleLog-v1.rst | 2 +- .../algorithms/AddSampleLogMultiple-v1.rst | 2 +- .../source/algorithms/AddTimeSeriesLog-v1.rst | 2 +- .../algorithms/AlignAndFocusPowder-v1.rst | 2 +- .../AlignAndFocusPowderFromFiles-v1.rst | 2 +- docs/source/algorithms/AlignComponents-v1.rst | 2 +- docs/source/algorithms/AlignDetectors-v1.rst | 2 +- docs/source/algorithms/AlphaCalc-v1.rst | 2 +- docs/source/algorithms/AndMD-v1.rst | 2 +- .../AngularAutoCorrelationsSingleAxis-v1.rst | 2 +- .../AngularAutoCorrelationsTwoAxes-v1.rst | 2 +- .../algorithms/AnnularRingAbsorption-v1.rst | 2 +- .../source/algorithms/AnvredCorrection-v1.rst | 2 +- .../AppendGeometryToSNSNexus-v1.rst | 2 +- docs/source/algorithms/AppendSpectra-v1.rst | 2 +- .../source/algorithms/ApplyCalibration-v1.rst | 2 +- .../algorithms/ApplyDeadTimeCorr-v1.rst | 2 +- .../algorithms/ApplyDetailedBalance-v1.rst | 2 +- .../ApplyDetectorScanEffCorr-v1.rst | 2 +- .../ApplyPaalmanPingsCorrection-v1.rst | 2 +- .../ApplyTransmissionCorrection-v1.rst | 2 +- docs/source/algorithms/AsymmetryCalc-v1.rst | 2 +- docs/source/algorithms/Authenticate-v1.rst | 2 +- docs/source/algorithms/Authenticate-v2.rst | 2 +- docs/source/algorithms/AverageLogData-v1.rst | 2 +- .../source/algorithms/BASISDiffraction-v1.rst | 8 +- docs/source/algorithms/BASISReduction-v1.rst | 2 +- .../algorithms/BASISReduction311-v1.rst | 4 +- docs/source/algorithms/BayesQuasi-v1.rst | 2 +- docs/source/algorithms/BayesStretch-v1.rst | 2 +- .../algorithms/Bin2DPowderDiffraction-v1.rst | 2 +- docs/source/algorithms/BinMD-v1.rst | 2 +- docs/source/algorithms/BinWidthAtX-v1.rst | 2 +- .../algorithms/BinaryOperateMasks-v1.rst | 2 +- .../algorithms/BroadcastWorkspace-v1.rst | 2 +- docs/source/algorithms/CalMuonDeadTime-v1.rst | 2 +- .../algorithms/CalMuonDetectorPhases-v1.rst | 2 +- .../algorithms/CalculateChiSquared-v1.rst | 4 +- .../algorithms/CalculateCostFunction-v1.rst | 2 +- .../algorithms/CalculateCountRate-v1.rst | 2 +- .../algorithms/CalculateCoverageDGS-v1.rst | 2 +- docs/source/algorithms/CalculateDIFC-v1.rst | 2 +- .../algorithms/CalculateEfficiency-v1.rst | 2 +- .../algorithms/CalculateFlatBackground-v1.rst | 2 +- .../CalculateMonteCarloAbsorption-v1.rst | 2 +- .../algorithms/CalculateMuonAsymmetry-v1.rst | 2 +- .../algorithms/CalculatePeaksHKL-v1.rst | 2 +- .../CalculatePolynomialBackground-v1.rst | 2 +- .../CalculateSampleTransmission-v1.rst | 2 +- docs/source/algorithms/CalculateSlits-v1.rst | 2 +- .../algorithms/CalculateTransmission-v1.rst | 2 +- .../CalculateTransmissionBeamSpreader-v1.rst | 2 +- .../source/algorithms/CalculateUMatrix-v1.rst | 2 +- docs/source/algorithms/CalculateZscore-v1.rst | 2 +- .../CalibrateRectangularDetectors-v1.rst | 2 +- .../CatalogDownloadDataFiles-v1.rst | 2 +- .../algorithms/CatalogGetDataFiles-v1.rst | 2 +- .../algorithms/CatalogGetDataSets-v1.rst | 2 +- .../source/algorithms/CatalogKeepAlive-v1.rst | 2 +- .../algorithms/CatalogListInstruments-v1.rst | 2 +- .../CatalogListInvestigationTypes-v1.rst | 2 +- docs/source/algorithms/CatalogLogin-v1.rst | 2 +- docs/source/algorithms/CatalogLogout-v1.rst | 2 +- .../algorithms/CatalogMyDataSearch-v1.rst | 2 +- docs/source/algorithms/CatalogPublish-v1.rst | 2 +- docs/source/algorithms/CatalogSearch-v1.rst | 2 +- docs/source/algorithms/CentroidPeaks-v1.rst | 2 +- docs/source/algorithms/CentroidPeaksMD-v1.rst | 2 +- docs/source/algorithms/CentroidPeaksMD-v2.rst | 2 +- docs/source/algorithms/ChangeBinOffset-v1.rst | 2 +- docs/source/algorithms/ChangeLogTime-v1.rst | 2 +- docs/source/algorithms/ChangePulsetime-v1.rst | 2 +- .../algorithms/ChangeQConvention-v1.rst | 2 +- docs/source/algorithms/ChangeTimeZero-v1.rst | 2 +- .../algorithms/CheckForSampleLogs-v1.rst | 2 +- .../algorithms/CheckMantidVersion-v1.rst | 2 +- .../algorithms/CheckWorkspacesMatch-v1.rst | 2 +- docs/source/algorithms/ChopData-v1.rst | 2 +- docs/source/algorithms/CleanFileCache-v1.rst | 2 +- docs/source/algorithms/ClearCache-v1.rst | 2 +- .../ClearInstrumentParameters-v1.rst | 2 +- docs/source/algorithms/ClearMaskFlag-v1.rst | 2 +- .../algorithms/ClearMaskedSpectra-v1.rst | 2 +- docs/source/algorithms/ClearUB-v1.rst | 2 +- .../source/algorithms/CloneMDWorkspace-v1.rst | 2 +- docs/source/algorithms/CloneWorkspace-v1.rst | 2 +- .../CollectHB3AExperimentInfo-v1.rst | 2 +- .../algorithms/CombinePeaksWorkspaces-v1.rst | 2 +- docs/source/algorithms/Comment-v1.rst | 2 +- docs/source/algorithms/CompactMD-v1.rst | 2 +- .../algorithms/CompareMDWorkspaces-v1.rst | 2 +- .../algorithms/CompareSampleLogs-v1.rst | 2 +- .../algorithms/CompareWorkspaces-v1.rst | 2 +- docs/source/algorithms/CompressEvents-v1.rst | 6 +- .../ComputeCalibrationCoefVan-v1.rst | 2 +- .../algorithms/ComputeIncoherentDOS-v1.rst | 2 +- .../algorithms/ComputeSensitivity-v1.rst | 2 +- docs/source/algorithms/ConjoinFiles-v1.rst | 2 +- docs/source/algorithms/ConjoinSpectra-v1.rst | 2 +- .../algorithms/ConjoinWorkspaces-v1.rst | 2 +- docs/source/algorithms/ConjoinXRuns-v1.rst | 2 +- .../algorithms/ConvertAxesToRealSpace-v1.rst | 2 +- .../algorithms/ConvertAxisByFormula-v1.rst | 2 +- .../algorithms/ConvertCWPDMDToSpectra-v1.rst | 2 +- .../ConvertCWSDExpToMomentum-v1.rst | 2 +- .../algorithms/ConvertCWSDMDtoHKL-v1.rst | 2 +- docs/source/algorithms/ConvertDiffCal-v1.rst | 2 +- .../algorithms/ConvertEmptyToTof-v1.rst | 2 +- .../algorithms/ConvertFromDistribution-v1.rst | 2 +- .../ConvertMDHistoToMatrixWorkspace-v1.rst | 2 +- ...onvertMultipleRunsToSingleCrystalMD-v1.rst | 2 +- .../algorithms/ConvertSnsRoiFileToMask-v1.rst | 2 +- .../algorithms/ConvertSpectrumAxis-v1.rst | 2 +- .../algorithms/ConvertSpectrumAxis-v2.rst | 2 +- .../ConvertSpiceDataToRealSpace-v1.rst | 2 +- .../ConvertTableToMatrixWorkspace-v1.rst | 2 +- .../algorithms/ConvertToConstantL2-v1.rst | 2 +- .../algorithms/ConvertToDetectorFaceMD-v1.rst | 2 +- .../ConvertToDiffractionMDWorkspace-v1.rst | 2 +- .../ConvertToDiffractionMDWorkspace-v2.rst | 2 +- .../ConvertToDiffractionMDWorkspace-v3.rst | 2 +- .../algorithms/ConvertToDistribution-v1.rst | 2 +- .../algorithms/ConvertToEventWorkspace-v1.rst | 2 +- .../algorithms/ConvertToHistogram-v1.rst | 2 +- docs/source/algorithms/ConvertToMD-v1.rst | 2 +- .../algorithms/ConvertToMDMinMaxGlobal-v1.rst | 2 +- .../algorithms/ConvertToMDMinMaxLocal-v1.rst | 2 +- .../ConvertToMatrixWorkspace-v1.rst | 2 +- .../algorithms/ConvertToPointData-v1.rst | 2 +- .../algorithms/ConvertToReflectometryQ-v1.rst | 2 +- docs/source/algorithms/ConvertToYSpace-v1.rst | 2 +- docs/source/algorithms/ConvertUnits-v1.rst | 2 +- .../ConvertUnitsUsingDetectorTable-v1.rst | 2 +- .../ConvolutionFitSequential-v1.rst | 2 +- .../algorithms/ConvolveWorkspaces-v1.rst | 2 +- .../algorithms/CopyDetectorMapping-v1.rst | 2 +- .../CopyInstrumentParameters-v1.rst | 2 +- docs/source/algorithms/CopyLogs-v1.rst | 2 +- docs/source/algorithms/CopySample-v1.rst | 2 +- .../algorithms/CorelliCrossCorrelate-v1.rst | 2 +- docs/source/algorithms/CorrectKiKf-v1.rst | 2 +- docs/source/algorithms/CorrectLogTimes-v1.rst | 2 +- docs/source/algorithms/CorrectTOF-v1.rst | 2 +- docs/source/algorithms/CorrectTOFAxis-v1.rst | 2 +- docs/source/algorithms/CorrectToFile-v1.rst | 2 +- .../source/algorithms/CountReflections-v1.rst | 2 +- .../algorithms/CreateCacheFilename-v1.rst | 2 +- .../algorithms/CreateCalFileByNames-v1.rst | 2 +- .../algorithms/CreateChopperModel-v1.rst | 2 +- .../CreateChunkingFromInstrument-v1.rst | 2 +- .../algorithms/CreateDummyCalFile-v1.rst | 2 +- docs/source/algorithms/CreateEPP-v1.rst | 2 +- .../CreateEmptyTableWorkspace-v1.rst | 2 +- .../CreateFlatEventWorkspace-v1.rst | 2 +- .../algorithms/CreateGroupingWorkspace-v1.rst | 2 +- .../algorithms/CreateLeBailFitInput-v1.rst | 2 +- .../algorithms/CreateLogPropertyTable-v1.rst | 2 +- .../algorithms/CreateLogTimeCorrection-v1.rst | 2 +- docs/source/algorithms/CreateMD-v1.rst | 2 +- .../algorithms/CreateMDHistoWorkspace-v1.rst | 2 +- .../algorithms/CreateMDWorkspace-v1.rst | 2 +- .../algorithms/CreateModeratorModel-v1.rst | 2 +- .../algorithms/CreatePSDBleedMask-v1.rst | 2 +- .../algorithms/CreatePeaksWorkspace-v1.rst | 2 +- .../algorithms/CreateSampleShape-v1.rst | 2 +- .../algorithms/CreateSampleWorkspace-v1.rst | 4 +- .../CreateSimulationWorkspace-v1.rst | 2 +- .../CreateSingleValuedWorkspace-v1.rst | 2 +- .../CreateTransmissionWorkspace-v1.rst | 2 +- .../CreateTransmissionWorkspace-v2.rst | 2 +- .../CreateTransmissionWorkspaceAuto-v1.rst | 2 +- .../CreateTransmissionWorkspaceAuto-v2.rst | 2 +- .../CreateUserDefinedBackground-v1.rst | 2 +- docs/source/algorithms/CreateWorkspace-v1.rst | 22 +- docs/source/algorithms/CropToComponent-v1.rst | 2 +- docs/source/algorithms/CropWorkspace-v1.rst | 2 +- .../algorithms/CropWorkspaceRagged-v1.rst | 2 +- docs/source/algorithms/CrossCorrelate-v1.rst | 2 +- .../algorithms/CrystalFieldEnergies-v1.rst | 2 +- .../CuboidGaugeVolumeAbsorption-v1.rst | 2 +- docs/source/algorithms/CutMD-v1.rst | 12 +- .../algorithms/CylinderAbsorption-v1.rst | 2 +- .../CylinderPaalmanPingsCorrection-v2.rst | 2 +- .../DNSComputeDetEffCorrCoefs-v1.rst | 2 +- .../algorithms/DNSFlippingRatioCorr-v1.rst | 2 +- docs/source/algorithms/DNSMergeRuns-v1.rst | 2 +- docs/source/algorithms/DPDFreduction-v1.rst | 2 +- docs/source/algorithms/DSFinterp-v1.rst | 2 +- .../source/algorithms/DakotaChiSquared-v1.rst | 2 +- .../algorithms/DefineGaugeVolume-v1.rst | 2 +- docs/source/algorithms/DeleteLog-v1.rst | 2 +- docs/source/algorithms/DeleteTableRows-v1.rst | 2 +- docs/source/algorithms/DeleteWorkspace-v1.rst | 2 +- .../source/algorithms/DeleteWorkspaces-v1.rst | 2 +- docs/source/algorithms/DeltaPDF3D-v1.rst | 2 +- .../algorithms/DetectorDiagnostic-v1.rst | 2 +- .../algorithms/DetectorEfficiencyCor-v1.rst | 2 +- .../DetectorEfficiencyCorUser-v1.rst | 2 +- .../DetectorEfficiencyVariation-v1.rst | 2 +- .../algorithms/DetectorFloodWeighting-v1.rst | 2 +- .../algorithms/DetermineChunking-v1.rst | 2 +- .../DgsAbsoluteUnitsReduction-v1.rst | 2 +- .../DgsConvertToEnergyTransfer-v1.rst | 2 +- docs/source/algorithms/DgsDiagnose-v1.rst | 2 +- .../algorithms/DgsPreprocessData-v1.rst | 2 +- .../DgsProcessDetectorVanadium-v1.rst | 2 +- docs/source/algorithms/DgsReduction-v1.rst | 2 +- docs/source/algorithms/DgsRemap-v1.rst | 2 +- .../algorithms/DiffPeaksWorkspaces-v1.rst | 2 +- .../DiffractionEventCalibrateDetectors-v1.rst | 2 +- .../algorithms/DiffractionFocussing-v1.rst | 2 +- .../algorithms/DiffractionFocussing-v2.rst | 2 +- .../DirectILLApplySelfShielding-v1.rst | 2 +- .../algorithms/DirectILLCollectData-v1.rst | 2 +- .../algorithms/DirectILLDiagnostics-v1.rst | 2 +- .../DirectILLIntegrateVanadium-v1.rst | 2 +- .../algorithms/DirectILLReduction-v1.rst | 2 +- .../algorithms/DirectILLSelfShielding-v1.rst | 2 +- docs/source/algorithms/Divide-v1.rst | 2 +- docs/source/algorithms/DivideMD-v1.rst | 2 +- docs/source/algorithms/DownloadFile-v1.rst | 2 +- .../algorithms/DownloadInstrument-v1.rst | 2 +- .../algorithms/DownloadRemoteFile-v1.rst | 2 +- .../algorithms/DownloadRemoteFile-v2.rst | 2 +- .../EQSANSAzimuthalAverage1D-v1.rst | 2 +- .../EQSANSDarkCurrentSubtraction-v1.rst | 2 +- .../EQSANSDarkCurrentSubtraction-v2.rst | 2 +- .../EQSANSDirectBeamTransmission-v1.rst | 2 +- docs/source/algorithms/EQSANSLoad-v1.rst | 2 +- .../source/algorithms/EQSANSMonitorTOF-v1.rst | 2 +- docs/source/algorithms/EQSANSNormalise-v1.rst | 2 +- .../algorithms/EQSANSPatchSensitivity-v1.rst | 2 +- docs/source/algorithms/EQSANSQ2D-v1.rst | 2 +- .../source/algorithms/EQSANSResolution-v1.rst | 2 +- .../algorithms/EQSANSTofStructure-v1.rst | 2 +- .../algorithms/EditInstrumentGeometry-v1.rst | 2 +- docs/source/algorithms/ElasticWindow-v1.rst | 2 +- .../algorithms/ElasticWindowMultiple-v1.rst | 2 +- .../source/algorithms/EnergyWindowScan-v1.rst | 2 +- docs/source/algorithms/EnggCalibrate-v1.rst | 2 +- .../algorithms/EnggCalibrateFull-v1.rst | 2 +- .../algorithms/EnggFitDIFCFromPeaks-v1.rst | 2 +- docs/source/algorithms/EnggFitPeaks-v1.rst | 2 +- docs/source/algorithms/EnggFocus-v1.rst | 2 +- .../algorithms/EnggVanadiumCorrections-v1.rst | 2 +- docs/source/algorithms/EqualToMD-v1.rst | 2 +- .../algorithms/EstimateDivergence-v1.rst | 2 +- .../algorithms/EstimateFitParameters-v1.rst | 2 +- .../EstimateMuonAsymmetryFromCounts-v1.rst | 2 +- .../algorithms/EstimatePeakErrors-v1.rst | 2 +- .../EstimateResolutionDiffraction-v1.rst | 2 +- .../source/algorithms/EvaluateFunction-v1.rst | 2 +- .../algorithms/EvaluateMDFunction-v1.rst | 2 +- .../ExaminePowderDiffProfile-v1.rst | 2 +- .../source/algorithms/ExampleSaveAscii-v1.rst | 2 +- docs/source/algorithms/Exponential-v1.rst | 2 +- .../algorithms/ExponentialCorrection-v1.rst | 2 +- docs/source/algorithms/ExponentialMD-v1.rst | 2 +- .../algorithms/ExportExperimentLog-v1.rst | 2 +- docs/source/algorithms/ExportGeometry-v1.rst | 2 +- .../ExportSampleLogsToCSVFile-v1.rst | 8 +- .../algorithms/ExportSpectraMask-v1.rst | 2 +- .../algorithms/ExportTimeSeriesLog-v1.rst | 2 +- .../algorithms/ExtractFFTSpectrum-v1.rst | 2 +- docs/source/algorithms/ExtractMask-v1.rst | 2 +- .../algorithms/ExtractMaskToTable-v1.rst | 2 +- .../algorithms/ExtractMonitorWorkspace-v1.rst | 2 +- docs/source/algorithms/ExtractMonitors-v1.rst | 2 +- .../algorithms/ExtractQENSMembers-v1.rst | 2 +- .../algorithms/ExtractSingleSpectrum-v1.rst | 2 +- docs/source/algorithms/ExtractSpectra-v1.rst | 2 +- .../algorithms/ExtractUnmaskedSpectra-v1.rst | 2 +- docs/source/algorithms/FFT-v1.rst | 2 +- docs/source/algorithms/FFTDerivative-v1.rst | 2 +- docs/source/algorithms/FFTSmooth-v1.rst | 2 +- docs/source/algorithms/FFTSmooth-v2.rst | 2 +- .../source/algorithms/FakeISISEventDAE-v1.rst | 2 +- .../source/algorithms/FakeISISHistoDAE-v1.rst | 2 +- docs/source/algorithms/FakeMDEventData-v1.rst | 2 +- docs/source/algorithms/FilterBadPulses-v1.rst | 2 +- .../source/algorithms/FilterByLogValue-v1.rst | 2 +- docs/source/algorithms/FilterByTime-v1.rst | 2 +- docs/source/algorithms/FilterByXValue-v1.rst | 2 +- docs/source/algorithms/FilterEvents-v1.rst | 2 +- .../FilterEventsByLogValuePreNexus-v2.rst | 2 +- docs/source/algorithms/FilterLogByTime-v1.rst | 2 +- docs/source/algorithms/FilterPeaks-v1.rst | 2 +- .../FindCenterOfMassPosition-v1.rst | 2 +- .../FindCenterOfMassPosition-v2.rst | 2 +- .../source/algorithms/FindClusterFaces-v1.rst | 2 +- .../algorithms/FindDeadDetectors-v1.rst | 2 +- .../algorithms/FindDetectorsInShape-v1.rst | 2 +- .../FindDetectorsOutsideLimits-v1.rst | 2 +- .../source/algorithms/FindDetectorsPar-v1.rst | 2 +- docs/source/algorithms/FindEPP-v1.rst | 2 +- docs/source/algorithms/FindEPP-v2.rst | 2 +- .../algorithms/FindPeakBackground-v1.rst | 2 +- docs/source/algorithms/FindPeaks-v1.rst | 2 +- docs/source/algorithms/FindPeaksMD-v1.rst | 46 +- .../algorithms/FindReflectometryLines-v1.rst | 2 +- docs/source/algorithms/FindSXPeaks-v1.rst | 2 +- docs/source/algorithms/FindUBUsingFFT-v1.rst | 2 +- .../algorithms/FindUBUsingIndexedPeaks-v1.rst | 2 +- .../FindUBUsingLatticeParameters-v1.rst | 2 +- .../algorithms/FindUBUsingMinMaxD-v1.rst | 2 +- docs/source/algorithms/Fit-v1.rst | 2 +- docs/source/algorithms/FitGaussian-v1.rst | 2 +- docs/source/algorithms/FitPeak-v1.rst | 2 +- .../algorithms/FitPowderDiffPeaks-v1.rst | 2 +- .../FitResolutionConvolvedModel-v1.rst | 2 +- .../algorithms/FixGSASInstrumentFile-v1.rst | 2 +- .../algorithms/FlatPlateAbsorption-v1.rst | 2 +- .../FlatPlatePaalmanPingsCorrection-v1.rst | 2 +- .../algorithms/GSASIIRefineFitPeaks-v1.rst | 2 +- .../source/algorithms/GatherWorkspaces-v1.rst | 2 +- .../GeneralisedSecondDifference-v1.rst | 2 +- .../algorithms/GenerateEventsFilter-v1.rst | 2 +- .../algorithms/GenerateGroupingPowder-v1.rst | 2 +- .../GenerateGroupingSNSInelastic-v1.rst | 2 +- .../algorithms/GenerateIPythonNotebook-v1.rst | 2 +- docs/source/algorithms/GeneratePeaks-v1.rst | 2 +- .../algorithms/GeneratePythonScript-v1.rst | 2 +- docs/source/algorithms/GetAllEi-v1.rst | 2 +- .../algorithms/GetDetOffsetsMultiPeaks-v1.rst | 2 +- .../algorithms/GetDetectorOffsets-v1.rst | 2 +- docs/source/algorithms/GetEi-v1.rst | 2 +- docs/source/algorithms/GetEi-v2.rst | 2 +- docs/source/algorithms/GetEiMonDet-v1.rst | 2 +- docs/source/algorithms/GetEiMonDet-v2.rst | 2 +- docs/source/algorithms/GetEiT0atSNS-v1.rst | 2 +- docs/source/algorithms/GetIPTS-v1.rst | 2 +- docs/source/algorithms/GetQsInQENSData-v1.rst | 2 +- .../GetSpiceDataRawCountsFromMD-v1.rst | 2 +- .../GetTimeSeriesLogInformation-v1.rst | 2 +- .../GoniometerAnglesFromPhiRotation-v1.rst | 2 +- docs/source/algorithms/GreaterThanMD-v1.rst | 2 +- docs/source/algorithms/GroupDetectors-v1.rst | 2 +- docs/source/algorithms/GroupDetectors-v2.rst | 2 +- docs/source/algorithms/GroupWorkspaces-v1.rst | 2 +- .../HFIRDarkCurrentSubtraction-v1.rst | 2 +- docs/source/algorithms/HFIRLoad-v1.rst | 2 +- .../algorithms/HFIRSANSNormalise-v1.rst | 2 +- .../algorithms/HFIRSANSReduction-v1.rst | 2 +- .../algorithms/HRPDSlabCanAbsorption-v1.rst | 2 +- docs/source/algorithms/HasUB-v1.rst | 2 +- .../algorithms/He3TubeEfficiency-v1.rst | 2 +- .../algorithms/HyspecScharpfCorrection-v1.rst | 2 +- docs/source/algorithms/IQTransform-v1.rst | 2 +- .../ISISIndirectDiffractionReduction-v1.rst | 2 +- .../ISISIndirectEnergyTransfer-v1.rst | 2 +- .../algorithms/IdentifyNoisyDetectors-v1.rst | 2 +- .../algorithms/ImportMDEventWorkspace-v1.rst | 2 +- .../algorithms/ImportMDHistoWorkspace-v1.rst | 2 +- docs/source/algorithms/IndexPeaks-v1.rst | 2 +- docs/source/algorithms/IndexSXPeaks-v1.rst | 2 +- .../IndirectAnnulusAbsorption-v1.rst | 2 +- .../IndirectAnnulusAbsorption-v2.rst | 2 +- .../algorithms/IndirectCalibration-v1.rst | 2 +- .../IndirectCylinderAbsorption-v1.rst | 2 +- .../IndirectCylinderAbsorption-v2.rst | 2 +- .../source/algorithms/IndirectDiffScan-v1.rst | 2 +- .../IndirectFlatPlateAbsorption-v1.rst | 2 +- .../IndirectFlatPlateAbsorption-v2.rst | 2 +- .../IndirectILLEnergyTransfer-v1.rst | 2 +- .../algorithms/IndirectILLReductionFWS-v1.rst | 2 +- .../IndirectILLReductionQENS-v1.rst | 8 +- .../source/algorithms/IndirectQuickRun-v1.rst | 2 +- .../algorithms/IndirectResolution-v1.rst | 2 +- .../algorithms/IndirectSampleChanger-v1.rst | 2 +- .../algorithms/IndirectTransmission-v1.rst | 2 +- .../IndirectTransmissionMonitor-v1.rst | 2 +- .../algorithms/IntegrateByComponent-v1.rst | 2 +- docs/source/algorithms/IntegrateEPP-v1.rst | 2 +- .../algorithms/IntegrateEllipsoids-v1.rst | 24 +- .../IntegrateEllipsoidsTwoStep-v1.rst | 24 +- docs/source/algorithms/IntegrateFlux-v1.rst | 2 +- .../IntegrateMDHistoWorkspace-v1.rst | 6 +- .../algorithms/IntegratePeakTimeSlices-v1.rst | 2 +- .../algorithms/IntegratePeaksCWSD-v1.rst | 2 +- .../algorithms/IntegratePeaksHybrid-v1.rst | 2 +- .../source/algorithms/IntegratePeaksMD-v1.rst | 2 +- .../source/algorithms/IntegratePeaksMD-v2.rst | 24 +- .../algorithms/IntegratePeaksMDHKL-v1.rst | 2 +- .../IntegratePeaksUsingClusters-v1.rst | 2 +- docs/source/algorithms/Integration-v1.rst | 2 +- .../algorithms/InterpolatingRebin-v1.rst | 2 +- docs/source/algorithms/InvertMDDim-v1.rst | 2 +- docs/source/algorithms/InvertMask-v1.rst | 2 +- docs/source/algorithms/IqtFitMultiple-v1.rst | 2 +- .../source/algorithms/IqtFitSequential-v1.rst | 2 +- docs/source/algorithms/LRAutoReduction-v1.rst | 2 +- .../source/algorithms/LRDirectBeamSort-v1.rst | 2 +- docs/source/algorithms/LRPeakSelection-v1.rst | 2 +- .../algorithms/LRPrimaryFraction-v1.rst | 2 +- .../algorithms/LRReflectivityOutput-v1.rst | 2 +- .../source/algorithms/LRScalingFactors-v1.rst | 2 +- .../LRSubtractAverageBackground-v1.rst | 2 +- docs/source/algorithms/LeBailFit-v1.rst | 2 +- docs/source/algorithms/LessThanMD-v1.rst | 2 +- docs/source/algorithms/LineProfile-v1.rst | 2 +- .../LiquidsReflectometryReduction-v1.rst | 2 +- docs/source/algorithms/Load-v1.rst | 2 +- docs/source/algorithms/LoadAndMerge-v1.rst | 2 +- docs/source/algorithms/LoadAscii-v1.rst | 2 +- docs/source/algorithms/LoadAscii-v2.rst | 2 +- docs/source/algorithms/LoadBBY-v1.rst | 2 +- docs/source/algorithms/LoadCIF-v1.rst | 2 +- docs/source/algorithms/LoadCalFile-v1.rst | 2 +- docs/source/algorithms/LoadCanSAS1D-v1.rst | 2 +- docs/source/algorithms/LoadCanSAS1D-v2.rst | 2 +- docs/source/algorithms/LoadDNSLegacy-v1.rst | 2 +- docs/source/algorithms/LoadDaveGrp-v1.rst | 2 +- .../source/algorithms/LoadDetectorInfo-v1.rst | 2 +- .../LoadDetectorsGroupingFile-v1.rst | 2 +- docs/source/algorithms/LoadDiffCal-v1.rst | 2 +- docs/source/algorithms/LoadDspacemap-v1.rst | 2 +- docs/source/algorithms/LoadEXED-v1.rst | 2 +- .../algorithms/LoadEmptyInstrument-v1.rst | 2 +- .../source/algorithms/LoadEmptyVesuvio-v1.rst | 2 +- .../algorithms/LoadEventAndCompress-v1.rst | 2 +- docs/source/algorithms/LoadEventNexus-v1.rst | 2 +- .../algorithms/LoadEventPreNexus-v2.rst | 2 +- docs/source/algorithms/LoadFITS-v1.rst | 2 +- docs/source/algorithms/LoadFlexiNexus-v1.rst | 2 +- .../source/algorithms/LoadFullprofFile-v1.rst | 2 +- .../algorithms/LoadFullprofResolution-v1.rst | 2 +- .../algorithms/LoadGSASInstrumentFile-v1.rst | 2 +- docs/source/algorithms/LoadGSS-v1.rst | 2 +- docs/source/algorithms/LoadHKL-v1.rst | 4 +- .../source/algorithms/LoadIDFFromNexus-v1.rst | 2 +- .../algorithms/LoadILLDiffraction-v1.rst | 2 +- docs/source/algorithms/LoadILLIndirect-v2.rst | 2 +- .../LoadILLPolarizationFactors-v1.rst | 2 +- .../algorithms/LoadILLReflectometry-v1.rst | 2 +- docs/source/algorithms/LoadILLSANS-v1.rst | 2 +- docs/source/algorithms/LoadILLTOF-v2.rst | 2 +- docs/source/algorithms/LoadISISNexus-v2.rst | 2 +- docs/source/algorithms/LoadInstrument-v1.rst | 2 +- .../algorithms/LoadInstrumentFromNexus-v1.rst | 2 +- .../algorithms/LoadInstrumentFromRaw-v1.rst | 2 +- docs/source/algorithms/LoadIsawDetCal-v1.rst | 2 +- docs/source/algorithms/LoadIsawPeaks-v1.rst | 2 +- .../source/algorithms/LoadIsawSpectrum-v1.rst | 2 +- docs/source/algorithms/LoadIsawUB-v1.rst | 2 +- docs/source/algorithms/LoadLLB-v1.rst | 2 +- docs/source/algorithms/LoadLamp-v1.rst | 2 +- docs/source/algorithms/LoadLiveData-v1.rst | 2 +- docs/source/algorithms/LoadLog-v1.rst | 2 +- .../algorithms/LoadLogPropertyTable-v1.rst | 2 +- docs/source/algorithms/LoadMD-v1.rst | 2 +- docs/source/algorithms/LoadMLZ-v1.rst | 2 +- .../source/algorithms/LoadMappingTable-v1.rst | 2 +- docs/source/algorithms/LoadMask-v1.rst | 2 +- docs/source/algorithms/LoadMcStas-v1.rst | 2 +- docs/source/algorithms/LoadMcStasNexus-v1.rst | 2 +- docs/source/algorithms/LoadMultipleGSS-v1.rst | 2 +- docs/source/algorithms/LoadMuonLog-v1.rst | 2 +- docs/source/algorithms/LoadMuonNexus-v1.rst | 2 +- docs/source/algorithms/LoadMuonNexus-v2.rst | 2 +- .../algorithms/LoadNMoldyn3Ascii-v1.rst | 2 +- .../algorithms/LoadNMoldyn4Ascii-v1.rst | 2 +- .../algorithms/LoadNMoldyn4Ascii1D-v1.rst | 2 +- docs/source/algorithms/LoadNXSPE-v1.rst | 2 +- docs/source/algorithms/LoadNXcanSAS-v1.rst | 2 +- docs/source/algorithms/LoadNexus-v1.rst | 2 +- docs/source/algorithms/LoadNexusLogs-v1.rst | 2 +- .../algorithms/LoadNexusMonitors-v1.rst | 2 +- .../algorithms/LoadNexusMonitors-v2.rst | 8 +- .../algorithms/LoadNexusProcessed-v1.rst | 2 +- docs/source/algorithms/LoadPDFgetNFile-v1.rst | 2 +- .../algorithms/LoadParameterFile-v1.rst | 2 +- docs/source/algorithms/LoadPreNexus-v1.rst | 2 +- .../source/algorithms/LoadPreNexusLive-v1.rst | 2 +- .../algorithms/LoadPreNexusMonitors-v1.rst | 2 +- docs/source/algorithms/LoadQKK-v1.rst | 2 +- docs/source/algorithms/LoadRKH-v1.rst | 2 +- docs/source/algorithms/LoadRaw-v3.rst | 2 +- docs/source/algorithms/LoadRawBin0-v1.rst | 2 +- .../source/algorithms/LoadRawSpectrum0-v1.rst | 2 +- docs/source/algorithms/LoadSESANS-v1.rst | 2 +- docs/source/algorithms/LoadSINQ-v1.rst | 2 +- docs/source/algorithms/LoadSINQFile-v1.rst | 2 +- docs/source/algorithms/LoadSINQFocus-v1.rst | 2 +- docs/source/algorithms/LoadSNSspec-v1.rst | 2 +- docs/source/algorithms/LoadSPE-v1.rst | 2 +- docs/source/algorithms/LoadSQW-v1.rst | 2 +- docs/source/algorithms/LoadSQW-v2.rst | 2 +- .../LoadSampleDetailsFromRaw-v1.rst | 2 +- docs/source/algorithms/LoadSassena-v1.rst | 2 +- docs/source/algorithms/LoadSpec-v1.rst | 2 +- docs/source/algorithms/LoadSpice2D-v1.rst | 2 +- docs/source/algorithms/LoadSpiceAscii-v1.rst | 2 +- .../algorithms/LoadSpiceXML2DDet-v1.rst | 2 +- docs/source/algorithms/LoadSwans-v1.rst | 2 +- docs/source/algorithms/LoadTBL-v1.rst | 2 +- docs/source/algorithms/LoadTOFRawNexus-v1.rst | 2 +- docs/source/algorithms/LoadVTK-v1.rst | 2 +- docs/source/algorithms/LoadVesuvio-v1.rst | 2 +- .../algorithms/LoadVisionElasticBS-v1.rst | 2 +- .../algorithms/LoadVisionElasticEQ-v1.rst | 2 +- .../algorithms/LoadVisionInelastic-v1.rst | 2 +- .../algorithms/LoadVulcanCalFile-v1.rst | 8 +- docs/source/algorithms/LoadWAND-v1.rst | 2 +- docs/source/algorithms/Logarithm-v1.rst | 2 +- docs/source/algorithms/LogarithmMD-v1.rst | 2 +- .../algorithms/LorentzCorrection-v1.rst | 2 +- .../algorithms/MDHistoToWorkspace2D-v1.rst | 2 +- docs/source/algorithms/MDNormDirectSC-v1.rst | 2 +- docs/source/algorithms/MDNormSCD-v1.rst | 2 +- .../MDNormSCDPreprocessIncoherent-v1.rst | 2 +- .../algorithms/MRFilterCrossSections-v1.rst | 2 +- docs/source/algorithms/MRInspectData-v1.rst | 2 +- docs/source/algorithms/MSDFit-v1.rst | 2 +- .../algorithms/MagFormFactorCorrection-v1.rst | 2 +- docs/source/algorithms/MaskAngle-v1.rst | 2 +- docs/source/algorithms/MaskBTP-v1.rst | 2 +- docs/source/algorithms/MaskBins-v1.rst | 2 +- .../algorithms/MaskBinsFromTable-v1.rst | 2 +- docs/source/algorithms/MaskDetectors-v1.rst | 2 +- docs/source/algorithms/MaskDetectorsIf-v1.rst | 2 +- .../algorithms/MaskDetectorsInShape-v1.rst | 2 +- docs/source/algorithms/MaskInstrument-v1.rst | 2 +- docs/source/algorithms/MaskMD-v1.rst | 2 +- .../algorithms/MaskPeaksWorkspace-v1.rst | 2 +- docs/source/algorithms/MaskSpectra-v1.rst | 2 +- .../algorithms/MaskWorkspaceToCalFile-v1.rst | 2 +- docs/source/algorithms/MatchPeaks-v1.rst | 2 +- docs/source/algorithms/Max-v1.rst | 2 +- docs/source/algorithms/MaxEnt-v1.rst | 105 +- docs/source/algorithms/MaxMin-v1.rst | 2 +- .../algorithms/MayersSampleCorrection-v1.rst | 2 +- docs/source/algorithms/Mean-v1.rst | 2 +- docs/source/algorithms/MedianBinWidth-v1.rst | 2 +- .../algorithms/MedianDetectorTest-v1.rst | 2 +- docs/source/algorithms/MergeCalFiles-v1.rst | 2 +- docs/source/algorithms/MergeLogs-v1.rst | 2 +- docs/source/algorithms/MergeMD-v1.rst | 2 +- docs/source/algorithms/MergeMDFiles-v1.rst | 2 +- docs/source/algorithms/MergeRuns-v1.rst | 2 +- docs/source/algorithms/Min-v1.rst | 2 +- docs/source/algorithms/Minus-v1.rst | 2 +- docs/source/algorithms/MinusMD-v1.rst | 2 +- docs/source/algorithms/ModeratorTzero-v1.rst | 2 +- .../algorithms/ModeratorTzeroLinear-v1.rst | 2 +- .../ModifyDetectorDotDatFile-v1.rst | 2 +- docs/source/algorithms/MolDyn-v1.rst | 2 +- .../MonitorEfficiencyCorUser-v1.rst | 2 +- docs/source/algorithms/MonitorLiveData-v1.rst | 2 +- .../algorithms/MonteCarloAbsorption-v1.rst | 2 +- docs/source/algorithms/MostLikelyMean-v1.rst | 2 +- .../algorithms/MoveInstrumentComponent-v1.rst | 2 +- ...ultipleScatteringCylinderAbsorption-v1.rst | 2 +- docs/source/algorithms/Multiply-v1.rst | 2 +- docs/source/algorithms/MultiplyMD-v1.rst | 2 +- docs/source/algorithms/MultiplyRange-v1.rst | 2 +- .../algorithms/MuonGroupDetectors-v1.rst | 2 +- docs/source/algorithms/MuonMaxent-v1.rst | 2 +- docs/source/algorithms/MuonProcess-v1.rst | 2 +- docs/source/algorithms/MuscatData-v1.rst | 2 +- docs/source/algorithms/MuscatFunc-v1.rst | 2 +- docs/source/algorithms/MuscatSofQW-v1.rst | 2 +- .../algorithms/NMoldyn4Interpolation-v1.rst | 2 +- .../NRCalculateSlitResolution-v1.rst | 4 +- docs/source/algorithms/NexusTester-v1.rst | 2 +- .../algorithms/NormaliseByCurrent-v1.rst | 2 +- .../algorithms/NormaliseByDetector-v1.rst | 2 +- .../algorithms/NormaliseByPeakArea-v1.rst | 2 +- .../algorithms/NormaliseByThickness-v1.rst | 2 +- .../source/algorithms/NormaliseSpectra-v1.rst | 2 +- .../algorithms/NormaliseToMonitor-v1.rst | 2 +- .../source/algorithms/NormaliseToUnity-v1.rst | 2 +- .../algorithms/NormaliseVanadium-v1.rst | 2 +- docs/source/algorithms/NotMD-v1.rst | 2 +- .../OSIRISDiffractionReduction-v1.rst | 2 +- .../algorithms/OneMinusExponentialCor-v1.rst | 2 +- docs/source/algorithms/OneStepMDEW-v1.rst | 2 +- .../OptimizeCrystalPlacement-v1.rst | 2 +- .../OptimizeLatticeForCellType-v1.rst | 2 +- docs/source/algorithms/OrMD-v1.rst | 2 +- docs/source/algorithms/PDCalibration-v1.rst | 2 +- .../PDDetermineCharacterizations-v1.rst | 2 +- .../algorithms/PDFFourierTransform-v1.rst | 8 +- .../algorithms/PDLoadCharacterizations-v1.rst | 2 +- docs/source/algorithms/PDToGUDRUN-v1.rst | 2 +- docs/source/algorithms/PDToPDFgetN-v1.rst | 2 +- .../algorithms/PaddingAndApodization-v1.rst | 2 +- docs/source/algorithms/Pause-v1.rst | 2 +- docs/source/algorithms/PawleyFit-v1.rst | 2 +- docs/source/algorithms/PeakIntegration-v1.rst | 2 +- .../algorithms/PeakIntensityVsRadius-v1.rst | 2 +- docs/source/algorithms/PeaksInRegion-v1.rst | 2 +- docs/source/algorithms/PeaksOnSurface-v1.rst | 2 +- .../algorithms/PearlMCAbsorption-v1.rst | 2 +- .../algorithms/PerformIndexOperations-v1.rst | 2 +- docs/source/algorithms/PhaseQuad-v1.rst | 2 +- .../algorithms/PlotAsymmetryByLogValue-v1.rst | 2 +- .../algorithms/PlotPeakByLogValue-v1.rst | 2 +- docs/source/algorithms/Plus-v1.rst | 2 +- docs/source/algorithms/PlusMD-v1.rst | 2 +- .../algorithms/PointByPointVCorrection-v1.rst | 2 +- docs/source/algorithms/PoissonErrors-v1.rst | 2 +- .../algorithms/PolarizationCorrection-v1.rst | 2 +- .../PolarizationEfficiencyCor-v1.rst | 2 +- .../algorithms/PoldiAnalyseResiduals-v1.rst | 2 +- .../algorithms/PoldiAutoCorrelation-v5.rst | 2 +- .../PoldiCreatePeaksFromCell-v1.rst | 2 +- .../PoldiCreatePeaksFromFile-v1.rst | 2 +- .../algorithms/PoldiDataAnalysis-v1.rst | 2 +- docs/source/algorithms/PoldiFitPeaks1D-v1.rst | 2 +- docs/source/algorithms/PoldiFitPeaks1D-v2.rst | 2 +- docs/source/algorithms/PoldiFitPeaks2D-v1.rst | 2 +- .../PoldiIndexKnownCompounds-v1.rst | 2 +- docs/source/algorithms/PoldiLoadRuns-v1.rst | 2 +- docs/source/algorithms/PoldiMerge-v1.rst | 2 +- docs/source/algorithms/PoldiPeakSearch-v1.rst | 2 +- .../source/algorithms/PoldiPeakSummary-v1.rst | 2 +- .../algorithms/PoldiTruncateData-v1.rst | 2 +- .../algorithms/PolynomialCorrection-v1.rst | 2 +- .../algorithms/PowderDiffILLDetEffCorr-v1.rst | 2 +- .../PowderDiffILLDetScanReduction-v1.rst | 2 +- .../algorithms/PowderDiffILLReduction-v1.rst | 2 +- docs/source/algorithms/Power-v1.rst | 2 +- .../algorithms/PowerLawCorrection-v1.rst | 2 +- docs/source/algorithms/PowerMD-v1.rst | 2 +- .../algorithms/PredictFractionalPeaks-v1.rst | 2 +- docs/source/algorithms/PredictPeaks-v1.rst | 2 +- .../algorithms/PreprocessDetectorsToMD-v1.rst | 2 +- .../algorithms/ProcessBackground-v1.rst | 2 +- .../ProcessIndirectFitParameters-v1.rst | 2 +- docs/source/algorithms/ProjectMD-v1.rst | 2 +- docs/source/algorithms/Q1D-v2.rst | 2 +- docs/source/algorithms/Q1DWeighted-v1.rst | 2 +- .../algorithms/QueryAllRemoteJobs-v1.rst | 2 +- .../algorithms/QueryAllRemoteJobs-v2.rst | 2 +- .../source/algorithms/QueryMDWorkspace-v1.rst | 2 +- docs/source/algorithms/QueryRemoteFile-v1.rst | 2 +- docs/source/algorithms/QueryRemoteFile-v2.rst | 2 +- docs/source/algorithms/QueryRemoteJob-v1.rst | 2 +- docs/source/algorithms/QueryRemoteJob-v2.rst | 2 +- docs/source/algorithms/Qxy-v1.rst | 2 +- docs/source/algorithms/REFLReprocess-v1.rst | 16 - docs/source/algorithms/RRFMuon-v1.rst | 2 +- docs/source/algorithms/RadiusSum-v1.rst | 2 +- docs/source/algorithms/RawFileInfo-v1.rst | 2 +- docs/source/algorithms/RayTracerTester-v1.rst | 2 +- .../algorithms/ReactorSANSResolution-v1.rst | 2 +- .../algorithms/ReadGroupsFromFile-v1.rst | 2 +- docs/source/algorithms/RealFFT-v1.rst | 2 +- docs/source/algorithms/Rebin-v1.rst | 8 +- docs/source/algorithms/Rebin2D-v1.rst | 2 +- .../algorithms/RebinByPulseTimes-v1.rst | 2 +- .../algorithms/RebinByTimeAtSample-v1.rst | 2 +- .../source/algorithms/RebinToWorkspace-v1.rst | 4 +- docs/source/algorithms/Rebunch-v1.rst | 2 +- .../algorithms/RecordPythonScript-v1.rst | 2 +- docs/source/algorithms/RefLReduction-v1.rst | 16 - docs/source/algorithms/RefReduction-v1.rst | 18 - docs/source/algorithms/RefRoi-v1.rst | 2 +- .../RefinePowderDiffProfileSeq-v1.rst | 2 +- .../RefinePowderInstrumentParameters-v3.rst | 16 +- .../ReflectometryReductionOne-v2.rst | 2 +- .../ReflectometryReductionOneAuto-v2.rst | 2 +- docs/source/algorithms/Regroup-v1.rst | 2 +- .../source/algorithms/RemoveBackground-v1.rst | 2 +- docs/source/algorithms/RemoveBins-v1.rst | 2 +- docs/source/algorithms/RemoveExpDecay-v1.rst | 2 +- docs/source/algorithms/RemoveLogs-v1.rst | 2 +- docs/source/algorithms/RemoveLowResTOF-v1.rst | 2 +- .../algorithms/RemoveMaskedSpectra-v1.rst | 2 +- .../algorithms/RemovePromptPulse-v1.rst | 2 +- .../algorithms/RemoveWorkspaceHistory-v1.rst | 2 +- docs/source/algorithms/RenameLog-v1.rst | 2 +- docs/source/algorithms/RenameWorkspace-v1.rst | 2 +- .../source/algorithms/RenameWorkspaces-v1.rst | 2 +- .../algorithms/ReplaceSpecialValues-v1.rst | 2 +- docs/source/algorithms/ReplicateMD-v1.rst | 2 +- docs/source/algorithms/ResNorm-v1.rst | 2 +- docs/source/algorithms/ResNorm-v2.rst | 2 +- docs/source/algorithms/ResampleX-v1.rst | 2 +- docs/source/algorithms/ResetNegatives-v1.rst | 2 +- .../ResizeRectangularDetector-v1.rst | 2 +- docs/source/algorithms/RetrieveRunInfo-v1.rst | 2 +- docs/source/algorithms/RingProfile-v1.rst | 2 +- .../RotateInstrumentComponent-v1.rst | 2 +- docs/source/algorithms/RotateSource-v1.rst | 2 +- docs/source/algorithms/RunPythonScript-v1.rst | 2 +- .../algorithms/SANSAbsoluteScale-v1.rst | 2 +- .../algorithms/SANSAzimuthalAverage1D-v1.rst | 2 +- docs/source/algorithms/SANSBeamFinder-v1.rst | 2 +- .../algorithms/SANSBeamFluxCorrection-v1.rst | 2 +- .../SANSBeamSpreaderTransmission-v1.rst | 2 +- .../SANSCalculateTransmission-v1.rst | 2 +- docs/source/algorithms/SANSConvertToQ-v1.rst | 2 +- .../algorithms/SANSConvertToWavelength-v1.rst | 2 +- .../SANSConvertToWavelengthAndRebin-v1.rst | 2 +- .../SANSCreateAdjustmentWorkspaces-v1.rst | 2 +- ...SCreateWavelengthAndPixelAdjustment-v1.rst | 2 +- docs/source/algorithms/SANSCrop-v1.rst | 2 +- .../SANSDarkRunBackgroundCorrection-v1.rst | 2 +- .../SANSDirectBeamTransmission-v1.rst | 2 +- .../algorithms/SANSFitShiftScale-v1.rst | 2 +- docs/source/algorithms/SANSLoad-v1.rst | 2 +- docs/source/algorithms/SANSMask-v1.rst | 2 +- .../algorithms/SANSMaskWorkspace-v1.rst | 2 +- docs/source/algorithms/SANSMove-v1.rst | 2 +- .../algorithms/SANSNormalizeToMonitor-v1.rst | 2 +- docs/source/algorithms/SANSReduction-v1.rst | 2 +- docs/source/algorithms/SANSSave-v1.rst | 2 +- docs/source/algorithms/SANSScale-v1.rst | 2 +- .../SANSSensitivityCorrection-v1.rst | 2 +- docs/source/algorithms/SANSSliceEvent-v1.rst | 2 +- .../SANSSolidAngleCorrection-v1.rst | 2 +- docs/source/algorithms/SANSStitch-v1.rst | 2 +- docs/source/algorithms/SANSSubtract-v1.rst | 2 +- .../algorithms/SANSWideAngleCorrection-v1.rst | 2 +- .../algorithms/SCDCalibratePanels-v1.rst | 4 +- docs/source/algorithms/SNAPReduce-v1.rst | 2 +- .../algorithms/SNSPowderReduction-v1.rst | 2 +- docs/source/algorithms/SassenaFFT-v1.rst | 2 +- docs/source/algorithms/SaveANSTOAscii-v1.rst | 2 +- docs/source/algorithms/SaveAscii-v1.rst | 2 +- docs/source/algorithms/SaveAscii-v2.rst | 2 +- docs/source/algorithms/SaveCSV-v1.rst | 2 +- docs/source/algorithms/SaveCalFile-v1.rst | 2 +- docs/source/algorithms/SaveCanSAS1D-v1.rst | 2 +- docs/source/algorithms/SaveCanSAS1D-v2.rst | 2 +- docs/source/algorithms/SaveDaveGrp-v1.rst | 2 +- .../algorithms/SaveDetectorsGrouping-v1.rst | 2 +- docs/source/algorithms/SaveDiffCal-v1.rst | 2 +- .../algorithms/SaveDiffFittingAscii-v1.rst | 2 +- docs/source/algorithms/SaveDspacemap-v1.rst | 2 +- docs/source/algorithms/SaveFITS-v1.rst | 2 +- docs/source/algorithms/SaveFocusedXYE-v1.rst | 2 +- .../algorithms/SaveFullprofResolution-v1.rst | 2 +- .../algorithms/SaveGSASInstrumentFile-v1.rst | 2 +- docs/source/algorithms/SaveGSS-v1.rst | 2 +- docs/source/algorithms/SaveHKL-v1.rst | 2 +- .../algorithms/SaveILLCosmosAscii-v1.rst | 2 +- docs/source/algorithms/SaveISISNexus-v1.rst | 2 +- docs/source/algorithms/SaveIsawDetCal-v1.rst | 2 +- docs/source/algorithms/SaveIsawPeaks-v1.rst | 4 +- docs/source/algorithms/SaveIsawQvector-v1.rst | 2 +- docs/source/algorithms/SaveIsawUB-v1.rst | 2 +- docs/source/algorithms/SaveLauenorm-v1.rst | 2 +- docs/source/algorithms/SaveMD-v1.rst | 2 +- docs/source/algorithms/SaveMD-v2.rst | 2 +- .../algorithms/SaveMDWorkspaceToVTK-v1.rst | 2 +- docs/source/algorithms/SaveMask-v1.rst | 2 +- docs/source/algorithms/SaveNISTDAT-v1.rst | 2 +- docs/source/algorithms/SaveNXSPE-v1.rst | 2 +- docs/source/algorithms/SaveNXTomo-v1.rst | 2 +- docs/source/algorithms/SaveNXcanSAS-v1.rst | 2 +- docs/source/algorithms/SaveNexus-v1.rst | 2 +- docs/source/algorithms/SaveNexusPD-v1.rst | 2 +- .../algorithms/SaveNexusProcessed-v1.rst | 2 +- .../algorithms/SaveOpenGenieAscii-v1.rst | 2 +- docs/source/algorithms/SavePAR-v1.rst | 2 +- docs/source/algorithms/SavePDFGui-v1.rst | 2 +- docs/source/algorithms/SavePHX-v1.rst | 2 +- .../algorithms/SaveParameterFile-v1.rst | 2 +- docs/source/algorithms/SavePlot1D-v1.rst | 2 +- .../source/algorithms/SavePlot1DAsJson-v1.rst | 2 +- docs/source/algorithms/SaveRKH-v1.rst | 2 +- .../algorithms/SaveReflCustomAscii-v1.rst | 2 +- .../SaveReflThreeColumnAscii-v1.rst | 2 +- docs/source/algorithms/SaveReflections-v1.rst | 2 +- docs/source/algorithms/SaveSESANS-v1.rst | 2 +- docs/source/algorithms/SaveSPE-v1.rst | 2 +- docs/source/algorithms/SaveTBL-v1.rst | 2 +- .../algorithms/SaveToSNSHistogramNexus-v1.rst | 2 +- docs/source/algorithms/SaveVTK-v1.rst | 2 +- docs/source/algorithms/SaveVulcanGSS-v1.rst | 2 +- docs/source/algorithms/SaveYDA-v1.rst | 2 +- docs/source/algorithms/SaveZODS-v1.rst | 2 +- docs/source/algorithms/Scale-v1.rst | 2 +- docs/source/algorithms/ScaleX-v1.rst | 2 +- docs/source/algorithms/Segfault-v1.rst | 2 +- .../source/algorithms/SelectCellOfType-v1.rst | 2 +- .../algorithms/SelectCellWithForm-v1.rst | 2 +- .../SelectNexusFilesByMetadata-v1.rst | 2 +- docs/source/algorithms/SetBeam-v1.rst | 2 +- docs/source/algorithms/SetDetScale-v1.rst | 2 +- docs/source/algorithms/SetGoniometer-v1.rst | 2 +- .../algorithms/SetInstrumentParameter-v1.rst | 2 +- docs/source/algorithms/SetMDFrame-v1.rst | 2 +- docs/source/algorithms/SetMDUsingMask-v1.rst | 2 +- docs/source/algorithms/SetSample-v1.rst | 2 +- .../algorithms/SetSampleMaterial-v1.rst | 2 +- docs/source/algorithms/SetScalingPSD-v1.rst | 2 +- .../algorithms/SetSpecialCoordinates-v1.rst | 2 +- docs/source/algorithms/SetUB-v1.rst | 2 +- .../source/algorithms/SetUncertainties-v1.rst | 2 +- .../algorithms/SetupEQSANSReduction-v1.rst | 2 +- .../algorithms/SetupHFIRReduction-v1.rst | 2 +- .../algorithms/SetupILLD33Reduction-v1.rst | 2 +- docs/source/algorithms/ShiftLogTime-v1.rst | 2 +- .../algorithms/ShowPeakHKLOffsets-v1.rst | 2 +- .../algorithms/ShowPossibleCells-v1.rst | 2 +- docs/source/algorithms/SignalOverError-v1.rst | 2 +- .../SimpleShapeMonteCarloAbsorption-v1.rst | 2 +- .../SimulateResolutionConvolvedModel-v1.rst | 2 +- .../SimulatedDensityOfStates-v1.rst | 2 +- .../SingleCrystalDiffuseReduction-v1.rst | 2 +- docs/source/algorithms/SliceMD-v1.rst | 2 +- docs/source/algorithms/SliceMDHisto-v1.rst | 2 +- docs/source/algorithms/SmoothData-v1.rst | 2 +- docs/source/algorithms/SmoothMD-v1.rst | 2 +- .../source/algorithms/SmoothNeighbours-v1.rst | 2 +- docs/source/algorithms/SofQW-v1.rst | 2 +- docs/source/algorithms/SofQWCentre-v1.rst | 2 +- docs/source/algorithms/SofQWMoments-v1.rst | 2 +- .../source/algorithms/SofQWMomentsScan-v1.rst | 2 +- .../algorithms/SofQWNormalisedPolygon-v1.rst | 2 +- docs/source/algorithms/SofQWPolygon-v1.rst | 2 +- docs/source/algorithms/SolidAngle-v1.rst | 2 +- docs/source/algorithms/SortByQVectors-v1.rst | 2 +- docs/source/algorithms/SortDetectors-v1.rst | 2 +- docs/source/algorithms/SortEvents-v1.rst | 2 +- docs/source/algorithms/SortHKL-v1.rst | 13 +- .../algorithms/SortPeaksWorkspace-v1.rst | 2 +- .../algorithms/SortTableWorkspace-v1.rst | 2 +- docs/source/algorithms/SortXAxis-v1.rst | 10 +- docs/source/algorithms/SpatialGrouping-v1.rst | 2 +- .../SpecularReflectionCalculateTheta-v1.rst | 2 +- .../SpecularReflectionCalculateTheta-v2.rst | 2 +- .../SpecularReflectionPositionCorrect-v1.rst | 2 +- .../SpecularReflectionPositionCorrect-v2.rst | 2 +- .../algorithms/SphericalAbsorption-v1.rst | 2 +- .../source/algorithms/SplineBackground-v1.rst | 2 +- .../algorithms/SplineInterpolation-v1.rst | 2 +- docs/source/algorithms/SplineSmoothing-v1.rst | 2 +- docs/source/algorithms/Squares-v1.rst | 2 +- docs/source/algorithms/StartLiveData-v1.rst | 2 +- .../algorithms/StartRemoteTransaction-v1.rst | 2 +- .../algorithms/StartRemoteTransaction-v2.rst | 2 +- .../StatisticsOfPeaksWorkspace-v1.rst | 4 +- .../StatisticsOfTableWorkspace-v1.rst | 2 +- docs/source/algorithms/StepScan-v1.rst | 2 +- docs/source/algorithms/Stitch1D-v3.rst | 78 +- docs/source/algorithms/Stitch1DMany-v1.rst | 2 +- .../algorithms/StopRemoteTransaction-v1.rst | 2 +- .../algorithms/StopRemoteTransaction-v2.rst | 2 +- docs/source/algorithms/StringToPng-v1.rst | 2 +- docs/source/algorithms/StripPeaks-v1.rst | 2 +- .../algorithms/StripVanadiumPeaks-v1.rst | 2 +- .../algorithms/StripVanadiumPeaks-v2.rst | 2 +- docs/source/algorithms/SubmitRemoteJob-v1.rst | 2 +- docs/source/algorithms/SubmitRemoteJob-v2.rst | 2 +- docs/source/algorithms/SuggestTibCNCS-v1.rst | 2 +- .../source/algorithms/SuggestTibHYSPEC-v1.rst | 2 +- .../algorithms/SumEventsByLogValue-v1.rst | 2 +- docs/source/algorithms/SumNeighbours-v1.rst | 2 +- .../algorithms/SumOverlappingTubes-v1.rst | 2 +- docs/source/algorithms/SumRowColumn-v1.rst | 2 +- docs/source/algorithms/SumSpectra-v1.rst | 2 +- docs/source/algorithms/SwapWidths-v1.rst | 2 +- docs/source/algorithms/Symmetrise-v1.rst | 2 +- .../algorithms/TOFSANSResolution-v1.rst | 2 +- .../TOFSANSResolutionByPixel-v1.rst | 2 +- .../algorithms/TOFTOFCropWorkspace-v1.rst | 2 +- docs/source/algorithms/TOFTOFMergeRuns-v1.rst | 2 +- .../algorithms/TOSCABankCorrection-v1.rst | 2 +- .../TestWorkspaceGroupProperty-v1.rst | 2 +- docs/source/algorithms/ThresholdMD-v1.rst | 2 +- docs/source/algorithms/TimeSlice-v1.rst | 2 +- docs/source/algorithms/TransformHKL-v1.rst | 2 +- docs/source/algorithms/TransformMD-v1.rst | 2 +- docs/source/algorithms/TransformToIqt-v1.rst | 2 +- docs/source/algorithms/Transpose-v1.rst | 2 +- docs/source/algorithms/Transpose3D-v1.rst | 2 +- docs/source/algorithms/TransposeMD-v1.rst | 2 +- docs/source/algorithms/USANSReduction-v1.rst | 2 +- docs/source/algorithms/USANSSimulation-v1.rst | 2 +- .../source/algorithms/UnGroupWorkspace-v1.rst | 2 +- docs/source/algorithms/UnwrapMonitor-v1.rst | 2 +- .../algorithms/UnwrapMonitorsInTOF-v1.rst | 2 +- docs/source/algorithms/UnwrapSNS-v1.rst | 2 +- .../UpdateInstrumentFromFile-v1.rst | 2 +- .../UpdatePeakParameterTableValue-v1.rst | 2 +- .../algorithms/UpdateScriptRepository-v1.rst | 2 +- .../source/algorithms/UploadRemoteFile-v1.rst | 2 +- .../source/algorithms/UploadRemoteFile-v2.rst | 2 +- docs/source/algorithms/UserFunction1D-v1.rst | 2 +- .../VelocityAutoCorrelations-v1.rst | 2 +- .../VelocityCrossCorrelations-v1.rst | 2 +- .../VesuvioCalculateGammaBackground-v1.rst | 2 +- .../algorithms/VesuvioCalculateMS-v1.rst | 2 +- .../algorithms/VesuvioCorrections-v1.rst | 2 +- .../VesuvioDiffractionReduction-v1.rst | 2 +- .../VesuvioL1ThetaResolution-v1.rst | 2 +- .../algorithms/VesuvioPeakPrediction-v1.rst | 2 +- docs/source/algorithms/VesuvioPreFit-v1.rst | 2 +- .../algorithms/VesuvioResolution-v1.rst | 2 +- docs/source/algorithms/VesuvioTOFFit-v1.rst | 2 +- .../source/algorithms/VesuvioThickness-v1.rst | 2 +- docs/source/algorithms/ViewBOA-v1.rst | 2 +- docs/source/algorithms/VisionReduction-v1.rst | 2 +- docs/source/algorithms/WeightedMean-v1.rst | 2 +- docs/source/algorithms/WeightedMeanMD-v1.rst | 2 +- .../algorithms/WeightedMeanOfWorkspace-v1.rst | 2 +- docs/source/algorithms/WienerSmooth-v1.rst | 2 +- .../algorithms/WorkflowAlgorithmRunner-v1.rst | 2 +- docs/source/algorithms/XorMD-v1.rst | 2 +- .../images/EnggDiffExampleGSASOutput.png | Bin 0 -> 19419 bytes docs/source/images/EquivalentIntensities.png | Bin 0 -> 579717 bytes .../Engineering Diffraction Test Guide.rst | 37 + .../interfaces/Engineering Diffraction.rst | 69 + docs/source/release/v3.13.0/diffraction.rst | 10 + docs/source/release/v3.13.0/framework.rst | 24 +- docs/source/release/v3.13.0/index.rst | 1 + .../release/v3.13.0/instrument_view.rst | 36 + .../mantiddoc/directives/__init__.py | 4 +- docs/sphinxext/mantiddoc/directives/alias.py | 34 - docs/sphinxext/mantiddoc/directives/base.py | 35 +- .../mantiddoc/directives/relatedalgorithms.py | 48 + instrument/D2B_2018-03-01_Definition.xml | 324 +++ .../Sources/MDEWSource/vtkMDEWSource.cxx | 2 +- .../inc/MantidVatesAPI/Normalization.h | 4 +- .../VatesAPI/src/Normalization.cpp | 4 +- .../VatesAPI/src/vtkMDHexFactory.cpp | 6 +- .../VatesAPI/src/vtkMDHistoQuadFactory.cpp | 7 +- .../VatesAPI/src/vtkMDLineFactory.cpp | 8 +- .../VatesAPI/src/vtkMDQuadFactory.cpp | 9 +- qt/paraview_ext/VatesAPI/test/MockObjects.h | 2 +- .../mantidqt/utils/qt/testing/__init__.py | 2 + .../widgets/test/test_jupyterconsole.py | 4 +- .../test/FindFilesThreadPoolManagerTest.h | 8 +- qt/widgets/common/test/FindFilesWorkerTest.h | 10 +- qt/widgets/instrumentview/CMakeLists.txt | 4 + .../InstrumentView/BankRenderingHelpers.h | 39 + .../InstrumentView/InstrumentActor.h | 34 +- .../InstrumentView/InstrumentRenderer.h | 74 + .../src/BankRenderingHelpers.cpp | 170 ++ .../instrumentview/src/InstrumentActor.cpp | 226 +- .../instrumentview/src/InstrumentRenderer.cpp | 436 ++++ .../instrumentview/src/Projection3D.cpp | 1 - .../instrumentview/src/ProjectionSurface.cpp | 5 +- .../instrumentview/src/UnwrappedSurface.cpp | 5 +- .../MantidQtWidgets/LegacyQwt/SignalRange.h | 4 +- qt/widgets/legacyqwt/src/SignalRange.cpp | 6 +- .../SliceViewer/QPeaksTableModel.h | 4 + .../sliceviewer/src/QPeaksTableModel.cpp | 9 +- scripts/ExternalInterfaces/CMakeLists.txt | 2 +- scripts/Inelastic/CrystalField/fitting.py | 9 +- scripts/Inelastic/CrystalField/function.py | 4 + .../reflectometer/refl_data_script.py | 163 +- .../reflectometer/refl_data_series.py | 25 +- .../reduction/reflectometer/refl_reduction.py | 51 - .../reflectometer/refl_sf_calculator.py | 179 -- .../refl_sf_calculator_data_script.py | 150 -- .../refl_sf_calculator_data_series.py | 82 - .../reflectometer/refm_data_script.py | 381 ---- .../ScalingFactorCalculation/sfCalculator.py | 952 -------- scripts/REFL_Reduction.py | 10 - scripts/REFL_SF_Calculator.py | 10 - scripts/REFM_Reduction.py | 10 - .../instruments/reflectometer/__init__.py | 0 .../reflectometer/data_manipulation.py | 226 -- .../instruments/reflectometer/wks_utility.py | 1999 ----------------- 1915 files changed, 11840 insertions(+), 10179 deletions(-) delete mode 100644 Framework/PythonInterface/plugins/algorithms/RefLReduction.py delete mode 100644 Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/REFLReprocess.py delete mode 100644 Framework/PythonInterface/plugins/algorithms/sfCalculator.py delete mode 100644 Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefReduction.h delete mode 100644 Framework/WorkflowAlgorithms/src/RefReduction.cpp delete mode 100644 Testing/SystemTests/tests/analysis/REFLReduction.py delete mode 100644 Testing/SystemTests/tests/analysis/REFLWithBackground.py delete mode 100644 Testing/SystemTests/tests/analysis/REFMReduction.py create mode 100644 buildconfig/CMake/googletest_msvc_cpp11.patch create mode 100644 dev-docs/source/AutomatedBuildProcess.rst create mode 100644 dev-docs/source/BuildingOnOSX.rst create mode 100644 dev-docs/source/BuildingVATES.rst create mode 100644 dev-docs/source/BuildingWithCMake.rst create mode 100644 dev-docs/source/DataFilesForTesting.rst create mode 100644 dev-docs/source/DebuggingUnitTests.rst delete mode 100644 dev-docs/source/Dependencies.rst create mode 100644 dev-docs/source/DesignDocumentGuides.rst create mode 100644 dev-docs/source/DeveloperAccounts.rst create mode 100644 dev-docs/source/DevelopmentAndReleaseCycle.rst create mode 100644 dev-docs/source/DoxygenSetup.rst create mode 100644 dev-docs/source/GitWorkflow.rst create mode 100644 dev-docs/source/IssueTracking.rst create mode 100644 dev-docs/source/JenkinsConfiguration.rst create mode 100644 dev-docs/source/LoadAlgorithmHook.rst create mode 100644 dev-docs/source/MultiThreadingInAlgorithms.rst create mode 100644 dev-docs/source/PatchReleaseChecklist.rst rename dev-docs/source/{MVPPythonViews.rst => QtDesignerForPython.rst} (91%) create mode 100644 dev-docs/source/ReleaseChecklist.rst create mode 100644 dev-docs/source/RemoteJobSubmissionAPI.rst create mode 100644 dev-docs/source/RunningTheUnitTests.rst rename dev-docs/source/{ => Standards}/AlgorithmDocumentation.rst (100%) rename dev-docs/source/{ => Standards}/AlgorithmUsageExamples.rst (100%) create mode 100644 dev-docs/source/Standards/CPPStandards.rst rename dev-docs/source/{ => Standards}/DocumentationGuideForDevs.rst (100%) rename dev-docs/source/{ => Standards}/InterfaceDocumentation.rst (100%) create mode 100644 dev-docs/source/Standards/Libraries.rst create mode 100644 dev-docs/source/Standards/MantidStandards.rst create mode 100644 dev-docs/source/Standards/PythonStandards.rst create mode 100644 dev-docs/source/Standards/UnitTestStandards.rst create mode 100644 dev-docs/source/Standards/index.rst create mode 100644 dev-docs/source/SystemTests.rst create mode 100644 dev-docs/source/TSC.rst create mode 100644 dev-docs/source/TestingUtilities.rst rename dev-docs/source/{UsefulTools.rst => ToolsOverview.rst} (98%) create mode 100644 dev-docs/source/UnitTestGoodPractice.rst create mode 100644 dev-docs/source/WritingAnAlgorithm.rst create mode 100644 dev-docs/source/WritingCustomConvertToMDTransformation.rst create mode 100644 dev-docs/source/WritingPerformanceTests.rst create mode 100644 dev-docs/source/images/AttachToProcess.png create mode 100644 dev-docs/source/images/BuildStatuses.png create mode 100644 dev-docs/source/images/CodeFreezePR.png create mode 100644 dev-docs/source/images/ConvertToMDClassDiagram.gif create mode 100644 dev-docs/source/images/DevelopmentAndReleaseCycle.png create mode 100644 dev-docs/source/images/ExternalDataSchematic.png create mode 100644 dev-docs/source/images/Mocking.png create mode 100644 dev-docs/source/images/RestartBuild.png create mode 100644 dev-docs/source/images/VisualStudioTestDebugProperties.png delete mode 100644 docs/source/algorithms/REFLReprocess-v1.rst delete mode 100644 docs/source/algorithms/RefLReduction-v1.rst delete mode 100644 docs/source/algorithms/RefReduction-v1.rst create mode 100644 docs/source/images/EnggDiffExampleGSASOutput.png create mode 100644 docs/source/images/EquivalentIntensities.png create mode 100644 docs/source/release/v3.13.0/instrument_view.rst delete mode 100644 docs/sphinxext/mantiddoc/directives/alias.py create mode 100644 docs/sphinxext/mantiddoc/directives/relatedalgorithms.py create mode 100644 instrument/D2B_2018-03-01_Definition.xml create mode 100644 qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BankRenderingHelpers.h create mode 100644 qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentRenderer.h create mode 100644 qt/widgets/instrumentview/src/BankRenderingHelpers.cpp create mode 100644 qt/widgets/instrumentview/src/InstrumentRenderer.cpp delete mode 100644 scripts/Interface/reduction_gui/reduction/reflectometer/refl_reduction.py delete mode 100644 scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator.py delete mode 100644 scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator_data_script.py delete mode 100644 scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator_data_series.py delete mode 100644 scripts/Interface/reduction_gui/reduction/reflectometer/refm_data_script.py delete mode 100644 scripts/LargeScaleStructures/ScalingFactorCalculation/sfCalculator.py delete mode 100644 scripts/REFL_Reduction.py delete mode 100644 scripts/REFL_SF_Calculator.py delete mode 100644 scripts/REFM_Reduction.py delete mode 100644 scripts/reduction/instruments/reflectometer/__init__.py delete mode 100644 scripts/reduction/instruments/reflectometer/data_manipulation.py delete mode 100644 scripts/reduction/instruments/reflectometer/wks_utility.py diff --git a/Framework/API/inc/MantidAPI/Algorithm.h b/Framework/API/inc/MantidAPI/Algorithm.h index 8115702290f..a86aab57364 100644 --- a/Framework/API/inc/MantidAPI/Algorithm.h +++ b/Framework/API/inc/MantidAPI/Algorithm.h @@ -183,6 +183,9 @@ public: /// Function to return the separator token for the category string. A default /// implementation ';' is provided const std::string categorySeparator() const override { return ";"; } + /// Function to return all of the seeAlso (these are not validated) algorithms + /// related to this algorithm.A default implementation is provided. + const std::vector<std::string> seeAlso() const override { return {}; }; /// function to return any aliases to the algorithm; A default implementation /// is provided const std::string alias() const override { return ""; } diff --git a/Framework/API/inc/MantidAPI/AlgorithmProxy.h b/Framework/API/inc/MantidAPI/AlgorithmProxy.h index 6c2cac0c6ba..08cba70c8aa 100644 --- a/Framework/API/inc/MantidAPI/AlgorithmProxy.h +++ b/Framework/API/inc/MantidAPI/AlgorithmProxy.h @@ -79,11 +79,13 @@ public: const std::string category() const override { return m_category; } /// Function to return all of the categories that contain this algorithm const std::vector<std::string> categories() const override; - /// Function to return the sperator token for the category string. A default + /// Function to return the seperator token for the category string. A default /// implementation ',' is provided const std::string categorySeparator() const override { return m_categorySeparator; } + /// Function to return all of the seeAlso algorithms related to this algorithm + const std::vector<std::string> seeAlso() const override { return m_seeAlso; }; /// Aliases to the algorithm const std::string alias() const override { return m_alias; } /// Optional documentation URL for the real algorithm @@ -183,9 +185,10 @@ private: const std::string m_name; ///< name of the real algorithm const std::string m_category; ///< category of the real algorithm const std::string - m_categorySeparator; ///< category seperator of the real algorithm - const std::string m_alias; ///< alias to the algorithm - const std::string m_helpURL; ///< Optional documentation URL + m_categorySeparator; ///< category seperator of the real algorithm + const std::vector<std::string> m_seeAlso; ///< seeAlso of the real algorithm + const std::string m_alias; ///< alias to the algorithm + const std::string m_helpURL; ///< Optional documentation URL const std::string m_summary; ///<Message to display in GUI and help. const int m_version; ///< version of the real algorithm diff --git a/Framework/API/inc/MantidAPI/CompositeDomainMD.h b/Framework/API/inc/MantidAPI/CompositeDomainMD.h index aadf666d4ec..5fffbaf394f 100644 --- a/Framework/API/inc/MantidAPI/CompositeDomainMD.h +++ b/Framework/API/inc/MantidAPI/CompositeDomainMD.h @@ -53,8 +53,8 @@ public: const FunctionDomain &getDomain(size_t i) const override; protected: - mutable IMDIterator *m_iterator; ///< IMDIterator - size_t m_totalSize; ///< The total size of the domain + mutable std::unique_ptr<IMDIterator> m_iterator; ///< IMDIterator + size_t m_totalSize; ///< The total size of the domain mutable std::vector<FunctionDomainMD *> m_domains; ///< smaller parts of the domain }; diff --git a/Framework/API/inc/MantidAPI/FunctionDomainMD.h b/Framework/API/inc/MantidAPI/FunctionDomainMD.h index fa52a8a3668..adc80e5bed6 100644 --- a/Framework/API/inc/MantidAPI/FunctionDomainMD.h +++ b/Framework/API/inc/MantidAPI/FunctionDomainMD.h @@ -53,7 +53,7 @@ public: protected: /// IMDIterator - mutable IMDIterator *m_iterator; + mutable std::unique_ptr<IMDIterator> m_iterator; /// start of the domain, 0 <= m_startIndex < m_iterator->getDataSize() const size_t m_startIndex; /// track the iterator's index, 0 <= m_currentIndex < m_size. diff --git a/Framework/API/inc/MantidAPI/FunctionProperty.h b/Framework/API/inc/MantidAPI/FunctionProperty.h index 7d254fce7c8..64189b6038e 100644 --- a/Framework/API/inc/MantidAPI/FunctionProperty.h +++ b/Framework/API/inc/MantidAPI/FunctionProperty.h @@ -56,7 +56,7 @@ public: /// Bring in the PropertyWithValue assignment operator explicitly (avoids /// VSC++ warning) - boost::shared_ptr<IFunction> & + FunctionProperty & operator=(const boost::shared_ptr<IFunction> &value) override; /// Add the value of another property diff --git a/Framework/API/inc/MantidAPI/IAlgorithm.h b/Framework/API/inc/MantidAPI/IAlgorithm.h index 376780fda33..5f8888f7643 100644 --- a/Framework/API/inc/MantidAPI/IAlgorithm.h +++ b/Framework/API/inc/MantidAPI/IAlgorithm.h @@ -77,6 +77,9 @@ public: /// Function to return the separator token for the category string virtual const std::string categorySeparator() const = 0; + /// Function to return all of the seeAlso algorithms related to this algorithm + virtual const std::vector<std::string> seeAlso() const = 0; + /// function to return any aliases of the algorithm. virtual const std::string alias() const = 0; diff --git a/Framework/API/inc/MantidAPI/IMDIterator.h b/Framework/API/inc/MantidAPI/IMDIterator.h index 85d50481879..ea8ca2a3ff1 100644 --- a/Framework/API/inc/MantidAPI/IMDIterator.h +++ b/Framework/API/inc/MantidAPI/IMDIterator.h @@ -5,7 +5,6 @@ // Includes //---------------------------------------------------------------------- #include "MantidAPI/DllConfig.h" -#include "MantidAPI/IMDWorkspace.h" #include "MantidGeometry/MDGeometry/IMDDimension.h" #include "MantidGeometry/MDGeometry/MDTypes.h" #include "MantidKernel/VMD.h" @@ -14,10 +13,18 @@ namespace Mantid { namespace API { -//---------------------------------------------------------------------- -// Forward declaration -//---------------------------------------------------------------------- -class IMDWorkspace; + +/** Enum describing different ways to normalize the signal + * in a MDWorkspace. + */ +enum MDNormalization { + /// Don't normalize = return raw counts + NoNormalization = 0, + /// Divide the signal by the volume of the box/bin + VolumeNormalization = 1, + /// Divide the signal by the number of events that contributed to it. + NumEventsNormalization = 2 +}; /** This is an interface to an iterator of an IMDWorkspace @@ -83,13 +90,14 @@ public: virtual signal_t getError() const = 0; /// Return a list of vertexes defining the volume pointed to - virtual coord_t *getVertexesArray(size_t &numVertices) const = 0; + virtual std::unique_ptr<coord_t[]> + getVertexesArray(size_t &numVertices) const = 0; /// Return a list of vertexes defining the volume pointed to, enable masking /// of dimensions. - virtual coord_t *getVertexesArray(size_t &numVertices, - const size_t outDimensions, - const bool *maskDim) const = 0; + virtual std::unique_ptr<coord_t[]> + getVertexesArray(size_t &numVertices, const size_t outDimensions, + const bool *maskDim) const = 0; /// Returns the position of the center of the box pointed to. virtual Mantid::Kernel::VMD getCenter() const = 0; diff --git a/Framework/API/inc/MantidAPI/IMDNode.h b/Framework/API/inc/MantidAPI/IMDNode.h index a7e1a9f8ad4..09678f09d8a 100644 --- a/Framework/API/inc/MantidAPI/IMDNode.h +++ b/Framework/API/inc/MantidAPI/IMDNode.h @@ -3,6 +3,7 @@ #include <algorithm> #include <string> +#include <memory> #include <vector> #include "MantidKernel/VMD.h" #include "MantidGeometry/MDGeometry/MDTypes.h" @@ -277,10 +278,11 @@ public: // -------------------------------- Geometry/vertexes-Related // ------------------------------------------- virtual std::vector<Mantid::Kernel::VMD> getVertexes() const = 0; - virtual coord_t *getVertexesArray(size_t &numVertices) const = 0; - virtual coord_t *getVertexesArray(size_t &numVertices, - const size_t outDimensions, - const bool *maskDim) const = 0; + virtual std::unique_ptr<coord_t[]> + getVertexesArray(size_t &numVertices) const = 0; + virtual std::unique_ptr<coord_t[]> + getVertexesArray(size_t &numVertices, const size_t outDimensions, + const bool *maskDim) const = 0; virtual void transformDimensions(std::vector<double> &scaling, std::vector<double> &offset) = 0; diff --git a/Framework/API/inc/MantidAPI/IMDWorkspace.h b/Framework/API/inc/MantidAPI/IMDWorkspace.h index 6c5441eda94..8e6069d642a 100644 --- a/Framework/API/inc/MantidAPI/IMDWorkspace.h +++ b/Framework/API/inc/MantidAPI/IMDWorkspace.h @@ -1,6 +1,7 @@ #ifndef MANTID_API_IMDWORKSPACE_H_ #define MANTID_API_IMDWORKSPACE_H_ +#include "MantidAPI/IMDIterator.h" #include "MantidAPI/ITableWorkspace_fwd.h" #include "MantidAPI/MDGeometry.h" #include "MantidAPI/Workspace.h" @@ -16,20 +17,6 @@ class MDImplicitFunction; namespace API { -class IMDIterator; - -/** Enum describing different ways to normalize the signal - * in a MDWorkspace. - */ -enum MDNormalization { - /// Don't normalize = return raw counts - NoNormalization = 0, - /// Divide the signal by the volume of the box/bin - VolumeNormalization = 1, - /// Divide the signal by the number of events that contributed to it. - NumEventsNormalization = 2 -}; - static const signal_t MDMaskValue = std::numeric_limits<double>::quiet_NaN(); /** Basic MD Workspace Abstract Class. @@ -106,7 +93,7 @@ public: virtual uint64_t getNEvents() const = 0; /// Creates a new iterator pointing to the first cell in the workspace - virtual std::vector<IMDIterator *> createIterators( + virtual std::vector<std::unique_ptr<IMDIterator>> createIterators( size_t suggestedNumCores = 1, Mantid::Geometry::MDImplicitFunction *function = nullptr) const = 0; @@ -126,7 +113,7 @@ public: const Mantid::Kernel::VMD &end, Mantid::API::MDNormalization normalize) const; - IMDIterator *createIterator( + std::unique_ptr<IMDIterator> createIterator( Mantid::Geometry::MDImplicitFunction *function = nullptr) const; std::string getConvention() const; diff --git a/Framework/API/inc/MantidAPI/IndexProperty.h b/Framework/API/inc/MantidAPI/IndexProperty.h index 1952a88d54c..dad8fdd724c 100644 --- a/Framework/API/inc/MantidAPI/IndexProperty.h +++ b/Framework/API/inc/MantidAPI/IndexProperty.h @@ -57,7 +57,7 @@ public: bool isDefault() const override; std::string isValid() const override; - std::string operator=(const std::string &rhs); + IndexProperty &operator=(const std::string &rhs); operator Indexing::SpectrumIndexSet() const; Indexing::SpectrumIndexSet getIndices() const; Indexing::IndexInfo getFilteredIndexInfo() const; diff --git a/Framework/API/inc/MantidAPI/IndexTypeProperty.h b/Framework/API/inc/MantidAPI/IndexTypeProperty.h index 4ee308d2584..4ad313bfd15 100644 --- a/Framework/API/inc/MantidAPI/IndexTypeProperty.h +++ b/Framework/API/inc/MantidAPI/IndexTypeProperty.h @@ -52,7 +52,7 @@ public: using PropertyWithValue<std::string>::operator=; - std::string &operator=(API::IndexType type); + IndexTypeProperty &operator=(API::IndexType type); static std::string generatePropertyName(const std::string &name = ""); @@ -63,4 +63,4 @@ private: } // namespace API } // namespace Mantid -#endif /* MANTID_API_INDEXTYPEPROPERTY_H_ */ \ No newline at end of file +#endif /* MANTID_API_INDEXTYPEPROPERTY_H_ */ diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspace.h b/Framework/API/inc/MantidAPI/MatrixWorkspace.h index ad3657c215d..3fe921d12c0 100644 --- a/Framework/API/inc/MantidAPI/MatrixWorkspace.h +++ b/Framework/API/inc/MantidAPI/MatrixWorkspace.h @@ -499,7 +499,7 @@ public: const Mantid::API::MDNormalization &normalization) const override; /// Create iterators. Partitions the iterators according to the number of /// cores. - std::vector<IMDIterator *> createIterators( + std::vector<std::unique_ptr<IMDIterator>> createIterators( size_t suggestedNumCores = 1, Mantid::Geometry::MDImplicitFunction *function = nullptr) const override; diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspaceMDIterator.h b/Framework/API/inc/MantidAPI/MatrixWorkspaceMDIterator.h index 7bcde9b2386..0432b6eefd1 100644 --- a/Framework/API/inc/MantidAPI/MatrixWorkspaceMDIterator.h +++ b/Framework/API/inc/MantidAPI/MatrixWorkspaceMDIterator.h @@ -60,10 +60,12 @@ public: signal_t getError() const override; - coord_t *getVertexesArray(size_t &numVertices) const override; + std::unique_ptr<coord_t[]> + getVertexesArray(size_t &numVertices) const override; - coord_t *getVertexesArray(size_t &numVertices, const size_t outDimensions, - const bool *maskDim) const override; + std::unique_ptr<coord_t[]> + getVertexesArray(size_t &numVertices, const size_t outDimensions, + const bool *maskDim) const override; Mantid::Kernel::VMD getCenter() const override; diff --git a/Framework/API/inc/MantidAPI/WorkspaceProperty.h b/Framework/API/inc/MantidAPI/WorkspaceProperty.h index 75a5d27dfe5..fc9a66d00df 100644 --- a/Framework/API/inc/MantidAPI/WorkspaceProperty.h +++ b/Framework/API/inc/MantidAPI/WorkspaceProperty.h @@ -95,8 +95,7 @@ public: WorkspaceProperty &operator=(const WorkspaceProperty &right); - boost::shared_ptr<TYPE> & - operator=(const boost::shared_ptr<TYPE> &value) override; + WorkspaceProperty &operator=(const boost::shared_ptr<TYPE> &value) override; WorkspaceProperty &operator+=(Kernel::Property const *) override; diff --git a/Framework/API/inc/MantidAPI/WorkspaceProperty.tcc b/Framework/API/inc/MantidAPI/WorkspaceProperty.tcc index 1dbcb92a022..1894b6dded1 100644 --- a/Framework/API/inc/MantidAPI/WorkspaceProperty.tcc +++ b/Framework/API/inc/MantidAPI/WorkspaceProperty.tcc @@ -107,13 +107,14 @@ operator=(const WorkspaceProperty &right) { * @return assigned PropertyWithValue */ template <typename TYPE> -boost::shared_ptr<TYPE> &WorkspaceProperty<TYPE>:: +WorkspaceProperty<TYPE> &WorkspaceProperty<TYPE>:: operator=(const boost::shared_ptr<TYPE> &value) { std::string wsName = value->getName(); if (this->direction() == Kernel::Direction::Input && !wsName.empty()) { m_workspaceName = wsName; } - return Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::operator=(value); + Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::operator=(value); + return *this; } //-------------------------------------------------------------------------------------- diff --git a/Framework/API/src/AlgorithmProxy.cpp b/Framework/API/src/AlgorithmProxy.cpp index adf89ce8ac2..94c4df66b0b 100644 --- a/Framework/API/src/AlgorithmProxy.cpp +++ b/Framework/API/src/AlgorithmProxy.cpp @@ -19,9 +19,10 @@ AlgorithmProxy::AlgorithmProxy(Algorithm_sptr alg) m_executeAsync(new Poco::ActiveMethod<bool, Poco::Void, AlgorithmProxy>( this, &AlgorithmProxy::executeAsyncImpl)), m_name(alg->name()), m_category(alg->category()), - m_categorySeparator(alg->categorySeparator()), m_alias(alg->alias()), - m_summary(alg->summary()), m_version(alg->version()), m_alg(alg), - m_isExecuted(), m_isLoggingEnabled(true), m_loggingOffset(0), + m_categorySeparator(alg->categorySeparator()), m_seeAlso(alg->seeAlso()), + m_alias(alg->alias()), m_summary(alg->summary()), + m_version(alg->version()), m_alg(alg), m_isExecuted(), + m_isLoggingEnabled(true), m_loggingOffset(0), m_isAlgStartupLoggingEnabled(true), m_rethrow(false), m_isChild(false), m_setAlwaysStoreInADS(true) { if (!alg) { diff --git a/Framework/API/src/EqualBinSizesValidator.cpp b/Framework/API/src/EqualBinSizesValidator.cpp index 7415acc1b18..034cdc8acca 100644 --- a/Framework/API/src/EqualBinSizesValidator.cpp +++ b/Framework/API/src/EqualBinSizesValidator.cpp @@ -25,10 +25,10 @@ std::string EqualBinSizesValidator::checkValidity(const MatrixWorkspace_sptr &value) const { if (!value) return "Enter an existing workspace"; - if (value->getNumberHistograms() == 0 || value->blocksize() == 0) - return "Enter a workspace with some data in it"; if (!value->isCommonBins()) return "The workspace must have common bin boundaries for all histograms"; + if (value->getNumberHistograms() == 0 || value->blocksize() == 0) + return "Enter a workspace with some data in it"; Kernel::EqualBinsChecker checker(value->readX(0), m_errorLevel, m_warningLevel); diff --git a/Framework/API/src/FunctionDomainMD.cpp b/Framework/API/src/FunctionDomainMD.cpp index 55f26e7bcc0..73652eb0e78 100644 --- a/Framework/API/src/FunctionDomainMD.cpp +++ b/Framework/API/src/FunctionDomainMD.cpp @@ -34,7 +34,7 @@ FunctionDomainMD::FunctionDomainMD(IMDWorkspace_const_sptr ws, size_t start, /** Destructor. */ -FunctionDomainMD::~FunctionDomainMD() { delete m_iterator; } +FunctionDomainMD::~FunctionDomainMD() = default; /// Reset the iterator to point to the start of the domain. void FunctionDomainMD::reset() const { @@ -53,14 +53,14 @@ void FunctionDomainMD::reset() const { const IMDIterator *FunctionDomainMD::getNextIterator() const { if (m_justReset) { m_justReset = false; - return m_iterator; + return m_iterator.get(); } ++m_currentIndex; if (!m_iterator->next() || m_currentIndex >= m_size) { m_currentIndex = m_size; return nullptr; } - return m_iterator; + return m_iterator.get(); } /// Returns the pointer to the original workspace diff --git a/Framework/API/src/FunctionProperty.cpp b/Framework/API/src/FunctionProperty.cpp index 3a51eec8373..a2f62efc1b4 100644 --- a/Framework/API/src/FunctionProperty.cpp +++ b/Framework/API/src/FunctionProperty.cpp @@ -31,10 +31,10 @@ FunctionProperty &FunctionProperty::operator=(const FunctionProperty &right) { * @param value :: The value to set to * @return assigned PropertyWithValue */ -boost::shared_ptr<IFunction> &FunctionProperty:: +FunctionProperty &FunctionProperty:: operator=(const boost::shared_ptr<IFunction> &value) { - return Kernel::PropertyWithValue<boost::shared_ptr<IFunction>>::operator=( - value); + Kernel::PropertyWithValue<boost::shared_ptr<IFunction>>::operator=(value); + return *this; } //-------------------------------------------------------------------------------------- diff --git a/Framework/API/src/IMDWorkspace.cpp b/Framework/API/src/IMDWorkspace.cpp index 033a160b5ba..1285b43072c 100644 --- a/Framework/API/src/IMDWorkspace.cpp +++ b/Framework/API/src/IMDWorkspace.cpp @@ -26,15 +26,16 @@ IMDWorkspace::IMDWorkspace(const Parallel::StorageMode storageMode) * @param function :: Implicit function limiting space to look at * @return a single IMDIterator pointer */ -IMDIterator *IMDWorkspace::createIterator( +std::unique_ptr<IMDIterator> IMDWorkspace::createIterator( Mantid::Geometry::MDImplicitFunction *function) const { - std::vector<IMDIterator *> iterators = this->createIterators(1, function); + std::vector<std::unique_ptr<IMDIterator>> iterators = + this->createIterators(1, function); if (iterators.empty()) throw std::runtime_error("IMDWorkspace::createIterator(): iterator " "creation was not successful. No iterators " "returned by " + this->id()); - return iterators[0]; + return std::move(iterators[0]); } //--------------------------------------------------------------------------------------------- diff --git a/Framework/API/src/IndexProperty.cpp b/Framework/API/src/IndexProperty.cpp index fa8dedb6141..ea0cefaa786 100644 --- a/Framework/API/src/IndexProperty.cpp +++ b/Framework/API/src/IndexProperty.cpp @@ -33,8 +33,9 @@ std::string IndexProperty::isValid() const { return error; } -std::string IndexProperty::operator=(const std::string &rhs) { - return setValue(rhs); +IndexProperty &IndexProperty::operator=(const std::string &rhs) { + setValue(rhs); + return *this; } IndexProperty::operator Indexing::SpectrumIndexSet() const { diff --git a/Framework/API/src/IndexTypeProperty.cpp b/Framework/API/src/IndexTypeProperty.cpp index 26b14da4fa8..8df2a25296a 100644 --- a/Framework/API/src/IndexTypeProperty.cpp +++ b/Framework/API/src/IndexTypeProperty.cpp @@ -50,7 +50,7 @@ std::vector<std::string> IndexTypeProperty::allowedValues() const { bool IndexTypeProperty::isMultipleSelectionAllowed() { return false; } -std::string &IndexTypeProperty::operator=(API::IndexType type) { +IndexTypeProperty &IndexTypeProperty::operator=(API::IndexType type) { std::string val; switch (type) { @@ -62,7 +62,8 @@ std::string &IndexTypeProperty::operator=(API::IndexType type) { break; } - return *this = val; + *this = val; + return *this; } std::string IndexTypeProperty::generatePropertyName(const std::string &name) { diff --git a/Framework/API/src/MatrixWorkspace.cpp b/Framework/API/src/MatrixWorkspace.cpp index 12a2ba68ac4..5cd215f3e50 100644 --- a/Framework/API/src/MatrixWorkspace.cpp +++ b/Framework/API/src/MatrixWorkspace.cpp @@ -1466,7 +1466,7 @@ MatrixWorkspace::getDimensionWithId(std::string id) const { * @param function :: implicit function to limit range * @return MatrixWorkspaceMDIterator vector */ -std::vector<IMDIterator *> MatrixWorkspace::createIterators( +std::vector<std::unique_ptr<IMDIterator>> MatrixWorkspace::createIterators( size_t suggestedNumCores, Mantid::Geometry::MDImplicitFunction *function) const { // Find the right number of cores to use @@ -1480,13 +1480,14 @@ std::vector<IMDIterator *> MatrixWorkspace::createIterators( numCores = 1; // Create one iterator per core, splitting evenly amongst spectra - std::vector<IMDIterator *> out; + std::vector<std::unique_ptr<IMDIterator>> out; for (size_t i = 0; i < numCores; i++) { size_t begin = (i * numElements) / numCores; size_t end = ((i + 1) * numElements) / numCores; if (end > numElements) end = numElements; - out.push_back(new MatrixWorkspaceMDIterator(this, function, begin, end)); + out.push_back(Kernel::make_unique<MatrixWorkspaceMDIterator>(this, function, + begin, end)); } return out; } @@ -2000,8 +2001,8 @@ void MatrixWorkspace::rebuildDetectorIDGroupings() { const auto &allDetIDs = detInfo.detectorIDs(); const auto &specDefs = m_indexInfo->spectrumDefinitions(); const auto size = static_cast<int64_t>(m_indexInfo->size()); - std::atomic<bool> parallelException{false}; - std::string error; + enum class ErrorCode { None, InvalidDetIndex, InvalidTimeIndex }; + std::atomic<ErrorCode> errorValue(ErrorCode::None); #pragma omp parallel for for (int64_t i = 0; i < size; ++i) { auto &spec = getSpectrum(i); @@ -2013,23 +2014,29 @@ void MatrixWorkspace::rebuildDetectorIDGroupings() { const size_t detIndex = index.first; const size_t timeIndex = index.second; if (detIndex >= allDetIDs.size()) { - parallelException = true; - error = "MatrixWorkspace: SpectrumDefinition contains an out-of-range " - "detector index, i.e., the spectrum definition does not match " - "the instrument in the workspace."; + errorValue = ErrorCode::InvalidDetIndex; } else if (timeIndex >= detInfo.scanCount(detIndex)) { - parallelException = true; - error = "MatrixWorkspace: SpectrumDefinition contains an out-of-range " - "time index for a detector, i.e., the spectrum definition does " - "not match the instrument in the workspace."; + errorValue = ErrorCode::InvalidTimeIndex; } else { detIDs.insert(allDetIDs[detIndex]); } } spec.setDetectorIDs(std::move(detIDs)); } - if (parallelException) - throw std::invalid_argument(error); + switch (errorValue) { + case ErrorCode::InvalidDetIndex: + throw std::invalid_argument( + "MatrixWorkspace: SpectrumDefinition contains an out-of-range " + "detector index, i.e., the spectrum definition does not match " + "the instrument in the workspace."); + case ErrorCode::InvalidTimeIndex: + throw std::invalid_argument( + "MatrixWorkspace: SpectrumDefinition contains an out-of-range " + "time index for a detector, i.e., the spectrum definition does " + "not match the instrument in the workspace."); + case ErrorCode::None: + ; // nothing to do + } } } // namespace API diff --git a/Framework/API/src/MatrixWorkspaceMDIterator.cpp b/Framework/API/src/MatrixWorkspaceMDIterator.cpp index 7fd7e4291a4..c08e2759182 100644 --- a/Framework/API/src/MatrixWorkspaceMDIterator.cpp +++ b/Framework/API/src/MatrixWorkspaceMDIterator.cpp @@ -204,13 +204,13 @@ signal_t MatrixWorkspaceMDIterator::getError() const { //---------------------------------------------------------------------------------------------- /// Return a list of vertexes defining the volume pointed to -coord_t * +std::unique_ptr<coord_t[]> MatrixWorkspaceMDIterator::getVertexesArray(size_t & /*numVertices*/) const { throw std::runtime_error( "MatrixWorkspaceMDIterator::getVertexesArray() not implemented yet"); } -coord_t * +std::unique_ptr<coord_t[]> MatrixWorkspaceMDIterator::getVertexesArray(size_t & /*numVertices*/, const size_t /*outDimensions*/, const bool * /*maskDim*/) const { diff --git a/Framework/API/test/AlgorithmProxyTest.h b/Framework/API/test/AlgorithmProxyTest.h index d8d745c15a7..58b97aa90b3 100644 --- a/Framework/API/test/AlgorithmProxyTest.h +++ b/Framework/API/test/AlgorithmProxyTest.h @@ -29,6 +29,9 @@ public: const std::string category() const override { return "ProxyCat"; } ///< Algorithm's category for identification + const std::vector<std::string> seeAlso() const override { + return {"elephant", "seal"}; + } ///< Algorithm's seeAlso const std::string alias() const override { return "Dog"; } ///< Algorithm's alias @@ -134,6 +137,8 @@ public: TS_ASSERT_EQUALS(alg->version(), 1); TS_ASSERT_EQUALS(alg->category(), "ProxyCat"); TS_ASSERT_EQUALS(alg->alias(), "Dog"); + std::vector<std::string> seeAlsoList{"elephant", "seal"}; + TS_ASSERT_EQUALS(alg->seeAlso(), seeAlsoList); TS_ASSERT(alg->isInitialized()); TS_ASSERT(alg->existsProperty("prop1")); TS_ASSERT(alg->existsProperty("prop2")); diff --git a/Framework/API/test/AlgorithmTest.h b/Framework/API/test/AlgorithmTest.h index 9e92250520e..bac48ae042b 100644 --- a/Framework/API/test/AlgorithmTest.h +++ b/Framework/API/test/AlgorithmTest.h @@ -241,6 +241,13 @@ public: TS_ASSERT_EQUALS(algv3.categories(), result); } + void testSeeAlso() { + std::vector<std::string> result{"rabbit"}; + result.emplace_back("goldfish"); + result.emplace_back("Spotted Hyena"); + TS_ASSERT_EQUALS(alg.seeAlso(), result); + } + void testAlias() { TS_ASSERT_EQUALS(alg.alias(), "Dog"); } void testIsChild() { diff --git a/Framework/API/test/ExperimentInfoTest.h b/Framework/API/test/ExperimentInfoTest.h index a9a01510235..71806ba8cc0 100644 --- a/Framework/API/test/ExperimentInfoTest.h +++ b/Framework/API/test/ExperimentInfoTest.h @@ -526,9 +526,8 @@ public: std::pair<std::unordered_multimap<std::string, fromToEntry>::iterator, std::unordered_multimap<std::string, fromToEntry>::iterator> ret; - for (auto setIt = idfIdentifiers.begin(); setIt != idfIdentifiers.end(); - setIt++) { - ret = idfFiles.equal_range(*setIt); + for (const auto &idfIdentifier : idfIdentifiers) { + ret = idfFiles.equal_range(idfIdentifier); for (it1 = ret.first; it1 != ret.second; ++it1) { for (it2 = ret.first; it2 != ret.second; ++it2) { if (it1 != it2) { diff --git a/Framework/API/test/FakeAlgorithms.h b/Framework/API/test/FakeAlgorithms.h index 8c3744aa40f..706ea9e8f5a 100644 --- a/Framework/API/test/FakeAlgorithms.h +++ b/Framework/API/test/FakeAlgorithms.h @@ -23,6 +23,9 @@ public: } ///< Algorithm's category for identification const std::string alias() const override { return "Dog"; } const std::string summary() const override { return "Test summary"; } + const std::vector<std::string> seeAlso() const override { + return {"rabbit", "goldfish", "Spotted Hyena"}; + } void init() override { declareProperty("prop1", "value"); diff --git a/Framework/API/test/GroupingLoaderTest.h b/Framework/API/test/GroupingLoaderTest.h index c6aa0e50d51..4258fb1cbf2 100644 --- a/Framework/API/test/GroupingLoaderTest.h +++ b/Framework/API/test/GroupingLoaderTest.h @@ -25,11 +25,11 @@ public: auto dataPaths = ConfigService::Instance().getDataSearchDirs(); // Find the path of AutoTestData - for (auto it = dataPaths.begin(); it != dataPaths.end(); ++it) { - Poco::Path path(*it); + for (auto &dataPath : dataPaths) { + Poco::Path path(dataPath); if (path.directory(path.depth() - 1) == "UnitTest") { - m_testDataDir = *it; + m_testDataDir = dataPath; break; } } diff --git a/Framework/API/test/MatrixWorkspaceMDIteratorTest.h b/Framework/API/test/MatrixWorkspaceMDIteratorTest.h index 13c44fa5e4a..3a9cdaa5cbf 100644 --- a/Framework/API/test/MatrixWorkspaceMDIteratorTest.h +++ b/Framework/API/test/MatrixWorkspaceMDIteratorTest.h @@ -52,7 +52,7 @@ public: void test_iterating() { boost::shared_ptr<MatrixWorkspace> ws = makeFakeWS(); - IMDIterator *it = nullptr; + std::unique_ptr<IMDIterator> it; TS_ASSERT_THROWS_NOTHING(it = ws->createIterator(nullptr)); TS_ASSERT_EQUALS(it->getDataSize(), 20); TS_ASSERT_DELTA(it->getSignal(), 0.0, 1e-5); @@ -83,24 +83,21 @@ public: TS_ASSERT_DELTA(it->getError(), 22.0, 1e-5); TS_ASSERT_DELTA(it->getCenter()[0], 3.0, 1e-5); TS_ASSERT_DELTA(it->getCenter()[1], 2.0, 1e-5); - delete it; } /** Create a set of iterators that can be applied in parallel */ void test_parallel_iterators() { boost::shared_ptr<MatrixWorkspace> ws = makeFakeWS(); // The number of output cannot be larger than the number of histograms - std::vector<IMDIterator *> it = ws->createIterators(10, nullptr); + auto it = ws->createIterators(10, nullptr); TS_ASSERT_EQUALS(it.size(), 4); - for (size_t i = 0; i < it.size(); ++i) - delete it[i]; // Split in 4 iterators - std::vector<IMDIterator *> iterators = ws->createIterators(4, nullptr); + auto iterators = ws->createIterators(4, nullptr); TS_ASSERT_EQUALS(iterators.size(), 4); for (size_t i = 0; i < iterators.size(); i++) { - IMDIterator *it = iterators[i]; + IMDIterator *it = iterators[i].get(); const double i_d = static_cast<double>(i); // Only 5 elements per each iterator TS_ASSERT_EQUALS(it->getDataSize(), 5); @@ -116,19 +113,17 @@ public: TS_ASSERT(it->next()); TS_ASSERT(it->next()); TS_ASSERT(!it->next()); - delete it; } } void test_get_is_masked() { boost::shared_ptr<MatrixWorkspace> ws = makeFakeWS(); - IMDIterator *it = ws->createIterator(nullptr); + auto it = ws->createIterator(nullptr); const auto &spectrumInfo = ws->spectrumInfo(); for (size_t i = 0; i < ws->getNumberHistograms(); ++i) { TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), it->getIsMasked()); it->next(); } - delete it; } void testUnequalBins() { @@ -141,11 +136,11 @@ public: TS_ASSERT_THROWS(ws->blocksize(), std::logic_error); TS_ASSERT_EQUALS(ws->size(), 17); // Split in 4 iterators - std::vector<IMDIterator *> iterators = ws->createIterators(4, nullptr); + auto iterators = ws->createIterators(4, nullptr); TS_ASSERT_EQUALS(iterators.size(), 4); for (size_t i = 0; i < iterators.size(); i++) { - IMDIterator *it = iterators[i]; + auto it = iterators[i].get(); const double i_d = static_cast<double>(i); if (i == 0) { // Only 5 elements per each iterator @@ -174,7 +169,6 @@ public: TS_ASSERT(it->next()); } TS_ASSERT(!it->next()); - delete it; } } }; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AddLogDerivative.h b/Framework/Algorithms/inc/MantidAlgorithms/AddLogDerivative.h index c8b36aa070b..f582c8c6c1b 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/AddLogDerivative.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/AddLogDerivative.h @@ -47,6 +47,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"AddSampleLog"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Logs"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AddNote.h b/Framework/Algorithms/inc/MantidAlgorithms/AddNote.h index da8a8f5d8f5..c43944616a4 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/AddNote.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/AddNote.h @@ -42,6 +42,9 @@ public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"Comment"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AddPeak.h b/Framework/Algorithms/inc/MantidAlgorithms/AddPeak.h index 7e93f7274f5..ebf67e387d9 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/AddPeak.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/AddPeak.h @@ -43,6 +43,9 @@ public: } /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"AddPeakHKL", "CalculatePeaksHKL"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\Peaks"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AddSampleLog.h b/Framework/Algorithms/inc/MantidAlgorithms/AddSampleLog.h index d9bbd403543..651547a0d1b 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/AddSampleLog.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/AddSampleLog.h @@ -57,6 +57,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"AddSampleLogMultiple", "AddTimeSeriesLog", "DeleteLog", "LoadLog"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Logs"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AddTimeSeriesLog.h b/Framework/Algorithms/inc/MantidAlgorithms/AddTimeSeriesLog.h index 5ac9b054c3e..a5ab0398aed 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/AddTimeSeriesLog.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/AddTimeSeriesLog.h @@ -42,6 +42,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"AddSampleLog", "GetTimeSeriesLogInformation", "MergeLogs"}; + } const std::string category() const override; private: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h b/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h index 6d5dd1fb37c..5e8d7abfde3 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/AlignDetectors.h @@ -67,6 +67,9 @@ public: /// Algorithm's version for identification. @see Algorithm::version int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"DiffractionFocussing", "AlignAndFocusPowder"}; + } /// Algorithm's category for identification. @see Algorithm::category const std::string category() const override; /// Cross-check properties with each other @see IAlgorithm::validateInputs diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AnnularRingAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/AnnularRingAbsorption.h index 8da2489d4b9..63fbee31b02 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/AnnularRingAbsorption.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/AnnularRingAbsorption.h @@ -43,6 +43,9 @@ class DLLExport AnnularRingAbsorption : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"AbsorptionCorrection"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AnyShapeAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/AnyShapeAbsorption.h index 8e387758a60..358ccc76611 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/AnyShapeAbsorption.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/AnyShapeAbsorption.h @@ -88,6 +88,14 @@ public: AnyShapeAbsorption(); /// Algorithm's name const std::string name() const override { return "AbsorptionCorrection"; } + + const std::vector<std::string> seeAlso() const override { + return {"SetSampleMaterial", "CreateSampleShape", + "DefineGaugeVolume", "CylinderAbsorption", + "FlatPlateAbsorption", "AnnularRingAbsorption", + "CuboidGaugeVolumeAbsorption"}; + } + /// Summary of algorithms purpose const std::string summary() const override { return "Calculates an approximation of the attenuation due to absorption " diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AppendSpectra.h b/Framework/Algorithms/inc/MantidAlgorithms/AppendSpectra.h index 0fa090ffc8c..a69fd074bb4 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/AppendSpectra.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/AppendSpectra.h @@ -46,6 +46,9 @@ class DLLExport AppendSpectra : public WorkspaceJoiners { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ConjoinSpectra"}; + } private: // Overridden Algorithm methods diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ApplyDeadTimeCorr.h b/Framework/Algorithms/inc/MantidAlgorithms/ApplyDeadTimeCorr.h index 92565b4245c..d5ab58b031d 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ApplyDeadTimeCorr.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ApplyDeadTimeCorr.h @@ -45,6 +45,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"CalMuonDeadTime"}; + } /// Algorithm's category for identification const std::string category() const override { return "Muon;CorrectionFunctions\\EfficiencyCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ApplyTransmissionCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/ApplyTransmissionCorrection.h index 0e72040355f..8de12765a49 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ApplyTransmissionCorrection.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ApplyTransmissionCorrection.h @@ -55,6 +55,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"CalculateTransmission", "CalculateTransmissionBeamSpreader"}; + } /// Algorithm's category for identification const std::string category() const override { return "SANS;CorrectionFunctions\\TransmissionCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/AsymmetryCalc.h b/Framework/Algorithms/inc/MantidAlgorithms/AsymmetryCalc.h index 66d57249ef5..753103dba02 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/AsymmetryCalc.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/AsymmetryCalc.h @@ -61,6 +61,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CalculateMuonAsymmetry"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Muon"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Bin2DPowderDiffraction.h b/Framework/Algorithms/inc/MantidAlgorithms/Bin2DPowderDiffraction.h index 5ce3d96a863..86a6004356e 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Bin2DPowderDiffraction.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Bin2DPowderDiffraction.h @@ -40,6 +40,9 @@ class MANTID_ALGORITHMS_DLL Bin2DPowderDiffraction : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"Rebin2D"}; + } const std::string category() const override; const std::string summary() const override; /// Cross-check properties with each other @see IAlgorithm::validateInputs diff --git a/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperateMasks.h b/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperateMasks.h index 812134927ad..67d854720a0 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperateMasks.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperateMasks.h @@ -45,6 +45,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"InvertMask"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Masking"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalMuonDeadTime.h b/Framework/Algorithms/inc/MantidAlgorithms/CalMuonDeadTime.h index 32cfe9bfe32..b69e9cb25e1 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CalMuonDeadTime.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CalMuonDeadTime.h @@ -45,6 +45,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"ApplyDeadTimeCorr"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Muon"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculateCountRate.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculateCountRate.h index 0c6a6270046..f0a7e0990b5 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CalculateCountRate.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculateCountRate.h @@ -47,6 +47,9 @@ class DLLExport CalculateCountRate : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ChangePulsetime"}; + } const std::string category() const override; const std::string summary() const override; /// Helper function: true if count rate should be normalized and false diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculateDIFC.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculateDIFC.h index 257cce3dfbf..155ac49fbae 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CalculateDIFC.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculateDIFC.h @@ -38,6 +38,9 @@ public: const std::string name() const override; /// Algorithm's version for identification. @see Algorithm::version int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ConvertDiffCal"}; + } const std::string category() const override; /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculateMuonAsymmetry.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculateMuonAsymmetry.h index 89450631712..86c75f94942 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CalculateMuonAsymmetry.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculateMuonAsymmetry.h @@ -70,6 +70,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"AsymmetryCalc"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Muon"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculatePolynomialBackground.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculatePolynomialBackground.h index f5b5ebf757d..40c82fc53e6 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CalculatePolynomialBackground.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculatePolynomialBackground.h @@ -37,6 +37,9 @@ class MANTID_ALGORITHMS_DLL CalculatePolynomialBackground public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"RemoveBackground", "CreateUserDefinedBackground"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculateSlits.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculateSlits.h index f4654b9b735..7482d0f0294 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CalculateSlits.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculateSlits.h @@ -40,6 +40,9 @@ public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"NRCalculateSlitResolution"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmission.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmission.h index 803747c9ca5..a29fd88d5ea 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmission.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmission.h @@ -76,6 +76,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"CalculateTransmissionBeamSpreader", "ApplyTransmissionCorrection"}; + } /// Algorithm's category for identification const std::string category() const override { return "SANS;CorrectionFunctions\\TransmissionCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmissionBeamSpreader.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmissionBeamSpreader.h index 58f4637c9a0..919bc42fb6d 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmissionBeamSpreader.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculateTransmissionBeamSpreader.h @@ -85,6 +85,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"CalculateTransmission", "ApplyTransmissionCorrection"}; + } /// Algorithm's category for identification const std::string category() const override { return "SANS;CorrectionFunctions\\TransmissionCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ChangeBinOffset.h b/Framework/Algorithms/inc/MantidAlgorithms/ChangeBinOffset.h index c9f8d162a27..60e7c39ce6a 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ChangeBinOffset.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ChangeBinOffset.h @@ -51,6 +51,7 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { return {"ScaleX"}; } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Axes"; } /// Algorithm's Alternate Name diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ChangeLogTime.h b/Framework/Algorithms/inc/MantidAlgorithms/ChangeLogTime.h index 3fbcf270422..4e0d49695fd 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ChangeLogTime.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ChangeLogTime.h @@ -10,6 +10,9 @@ class DLLExport ChangeLogTime : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CreateLogTimeCorrection", "ChangePulsetime", "ShiftLogTime"}; + } const std::string category() const override; /// Algorithm's summary const std::string summary() const override { diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ChangePulsetime.h b/Framework/Algorithms/inc/MantidAlgorithms/ChangePulsetime.h index 0b0e6648194..55cbc9c2fbf 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ChangePulsetime.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ChangePulsetime.h @@ -24,6 +24,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"CreateLogTimeCorrection", "CalculateCountRate"}; + } /// Algorithm's category for identification const std::string category() const override { return "Events;Transforms\\Axes"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CheckWorkspacesMatch.h b/Framework/Algorithms/inc/MantidAlgorithms/CheckWorkspacesMatch.h index 6a8b8a95df0..8a53f4d604d 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CheckWorkspacesMatch.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CheckWorkspacesMatch.h @@ -87,6 +87,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"CompareWorkspaces"}; + } /// Algorithm's category for identification const std::string category() const override { return "Utility\\Workspaces"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ChopData.h b/Framework/Algorithms/inc/MantidAlgorithms/ChopData.h index 29052364139..37a04194b3d 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ChopData.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ChopData.h @@ -44,8 +44,13 @@ public: return "Transforms\\Splitting"; } ///< @return the algorithms category int version() const override { + return (1); } ///< @return version number of algorithm + + const std::vector<std::string> seeAlso() const override { + return {"ExtractSpectra"}; + } /// Algorithm's summary const std::string summary() const override { return "Splits an input workspace into a grouped workspace, where each " diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ClearCache.h b/Framework/Algorithms/inc/MantidAlgorithms/ClearCache.h index c6487ce37ce..c18ef3f0588 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ClearCache.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ClearCache.h @@ -33,6 +33,9 @@ class MANTID_ALGORITHMS_DLL ClearCache final : public API::Algorithm { public: const std::string name() const override final; int version() const override final; + const std::vector<std::string> seeAlso() const override { + return {"CleanFileCache"}; + } const std::string category() const override final; const std::string summary() const override final; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ClearInstrumentParameters.h b/Framework/Algorithms/inc/MantidAlgorithms/ClearInstrumentParameters.h index b39849874d6..d24d9dd115b 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ClearInstrumentParameters.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ClearInstrumentParameters.h @@ -40,6 +40,9 @@ public: const std::string summary() const override; const std::string category() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CopyInstrumentParameters"}; + } private: void init() override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskFlag.h b/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskFlag.h index 99eb3d1fb12..d50afc77ffa 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskFlag.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskFlag.h @@ -34,6 +34,9 @@ class DLLExport ClearMaskFlag : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"MaskDetectors"}; + } const std::string category() const override; /// Algorithm's summary const std::string summary() const override { diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskedSpectra.h b/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskedSpectra.h index fa27e65da22..95dd39b1fb7 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskedSpectra.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ClearMaskedSpectra.h @@ -40,6 +40,9 @@ class MANTID_ALGORITHMS_DLL ClearMaskedSpectra public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"MaskDetectors", "MaskInstrument"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CloneWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CloneWorkspace.h index d22e997dd59..3152a123de2 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CloneWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CloneWorkspace.h @@ -51,6 +51,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"CompareWorkspaces"}; + } /// Algorithm's category for identification const std::string category() const override { return "Utility\\Workspaces"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Comment.h b/Framework/Algorithms/inc/MantidAlgorithms/Comment.h index 6db408913c3..d8e7bb888d3 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Comment.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Comment.h @@ -33,6 +33,9 @@ class DLLExport Comment : public API::DistributedAlgorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"RemoveWorkspaceHistory"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CompareWorkspaces.h b/Framework/Algorithms/inc/MantidAlgorithms/CompareWorkspaces.h index 88b4ec69a72..dd7b806f982 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CompareWorkspaces.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CompareWorkspaces.h @@ -76,6 +76,9 @@ public: /// Algorithm's version for identification. @see Algorithm::version int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CheckWorkspacesMatch", "CompareSampleLogs", "CloneWorkspace"}; + } /// Algorithm's category for identification. @see Algorithm::category const std::string category() const override { return "Utility\\Workspaces"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConjoinWorkspaces.h b/Framework/Algorithms/inc/MantidAlgorithms/ConjoinWorkspaces.h index ff4dfcc488b..ac635cd6b76 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConjoinWorkspaces.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConjoinWorkspaces.h @@ -64,6 +64,9 @@ public: const std::string name() const override { return "ConjoinWorkspaces"; } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"ConjoinSpectra", "ConjoinXRuns", "MergeRuns"}; + } private: // Overridden Algorithm methods diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxesToRealSpace.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxesToRealSpace.h index 082160564d1..87f2f1774bc 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxesToRealSpace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxesToRealSpace.h @@ -39,6 +39,9 @@ class DLLExport ConvertAxesToRealSpace : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ConvertSpectrumAxis", "ConvertUnits"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxisByFormula.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxisByFormula.h index ada468038c9..b6065781996 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxisByFormula.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertAxisByFormula.h @@ -51,6 +51,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ConvertUnits"}; + } const std::string category() const override; protected: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertDiffCal.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertDiffCal.h index 9efc415141b..3244c5f8c1b 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertDiffCal.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertDiffCal.h @@ -33,6 +33,9 @@ class DLLExport ConvertDiffCal : public API::ParallelAlgorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CalculateDIFC"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertFromDistribution.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertFromDistribution.h index 19bfe10f0f9..77212c5bdb6 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertFromDistribution.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertFromDistribution.h @@ -51,6 +51,9 @@ public: } /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"ConvertToDistribution"}; + } /// Algorithm's category for identification const std::string category() const override { return "Transforms\\Distribution"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis2.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis2.h index b104840265f..2184cbfa942 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis2.h @@ -61,6 +61,9 @@ public: /// Algorithm's version int version() const override { return (2); } + const std::vector<std::string> seeAlso() const override { + return {"ConvertAxesToRealSpace", "ConvertUnits"}; + } /// Algorithm's category for identification const std::string category() const override { return "Transforms\\Units;Transforms\\Axes"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertTableToMatrixWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertTableToMatrixWorkspace.h index 1d2071bff6c..96b38bf7aa8 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertTableToMatrixWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertTableToMatrixWorkspace.h @@ -59,6 +59,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"ConvertMDHistoToMatrixWorkspace"}; + } /// Algorithm's category for identification const std::string category() const override { return "Utility\\Workspaces"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToConstantL2.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToConstantL2.h index bc00562a101..115e0ee62a7 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToConstantL2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToConstantL2.h @@ -53,6 +53,9 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CorrectTOFAxis"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Inelastic\\Corrections;CorrectionFunctions\\InstrumentCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToDistribution.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToDistribution.h index 1a73ad98da0..dc2d624acc1 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToDistribution.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToDistribution.h @@ -50,6 +50,9 @@ public: } /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"ConvertFromDistribution"}; + } /// Algorithm's category for identification const std::string category() const override { return "Transforms\\Distribution"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToEventWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToEventWorkspace.h index 002d9a88f34..25fc51d4174 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToEventWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToEventWorkspace.h @@ -47,6 +47,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"ConvertToMatrixWorkspace"}; + } /// Algorithm's category for identification const std::string category() const override { return "Events"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToHistogram.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToHistogram.h index 762f8298b57..54a0e7c7649 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToHistogram.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToHistogram.h @@ -46,7 +46,9 @@ public: return "Converts a workspace containing point data into one containing " "histograms."; } - + const std::vector<std::string> seeAlso() const override { + return {"ConvertToPointData"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Axes"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToMatrixWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToMatrixWorkspace.h index b54ea719a05..b678284d18a 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToMatrixWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToMatrixWorkspace.h @@ -55,6 +55,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"ConvertToEventWorkspace", "Rebin"}; + } /// Algorithm's category for identification const std::string category() const override { return "Events"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToPointData.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToPointData.h index ad628c2de7a..052d24418f4 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToPointData.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToPointData.h @@ -46,7 +46,9 @@ public: return "Converts a workspace containing histogram data into one containing " "point data."; } - + const std::vector<std::string> seeAlso() const override { + return {"ConvertToHistogram"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Axes"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnits.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnits.h index 17b12f37a7c..9d856b2453f 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnits.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnits.h @@ -75,6 +75,10 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"ConvertAxisByFormula", "ConvertAxesToRealSpace", + "ConvertSpectrumAxis", "ConvertToYSpace"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Units"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CopyDetectorMapping.h b/Framework/Algorithms/inc/MantidAlgorithms/CopyDetectorMapping.h index 9dd9c126305..d162e7172f1 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CopyDetectorMapping.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CopyDetectorMapping.h @@ -48,6 +48,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"CopyLogs"}; + } /// Algorithm's category for identification const std::string category() const override { return "Utility\\Workspaces"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CopyInstrumentParameters.h b/Framework/Algorithms/inc/MantidAlgorithms/CopyInstrumentParameters.h index 5740e3cae41..56a41ccf8a8 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CopyInstrumentParameters.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CopyInstrumentParameters.h @@ -67,6 +67,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"ClearInstrumentParameters"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Instrument"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CopyLogs.h b/Framework/Algorithms/inc/MantidAlgorithms/CopyLogs.h index 9ac0cda4991..0bdae1199d3 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CopyLogs.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CopyLogs.h @@ -51,6 +51,10 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CreateLogPropertyTable", "CopyDetectorMapping", + "CheckForSampleLogs", "CopySample"}; + } const std::string category() const override; private: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CopySample.h b/Framework/Algorithms/inc/MantidAlgorithms/CopySample.h index 0fd33a49057..8b2a8cdfd4c 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CopySample.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CopySample.h @@ -57,6 +57,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"CompareSampleLogs", "CopyLogs", "CheckForSampleLogs"}; + } /// Algorithm's category for identification const std::string category() const override { return "Sample;Utility\\Workspaces"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CorrectTOFAxis.h b/Framework/Algorithms/inc/MantidAlgorithms/CorrectTOFAxis.h index 1c0ebc3900a..53d13250b5c 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CorrectTOFAxis.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CorrectTOFAxis.h @@ -43,6 +43,9 @@ class MANTID_ALGORITHMS_DLL CorrectTOFAxis : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ConvertToConstantL2"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateCalFileByNames.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateCalFileByNames.h index 72d23586f7a..2a6b275cbb3 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateCalFileByNames.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateCalFileByNames.h @@ -73,6 +73,11 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"ReadGroupsFromFile", "CreateDummyCalFile", "AlignDetectors", + "DiffractionFocussing", "LoadCalFile", "SaveCalFile", + "MergeCalFiles"}; + } /// Algorithm's category for identification const std::string category() const override { return "Diffraction\\DataHandling\\CalFiles"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateDummyCalFile.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateDummyCalFile.h index 819b5a10844..6b85d258860 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateDummyCalFile.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateDummyCalFile.h @@ -72,6 +72,11 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"ReadGroupsFromFile", "CreateCalFileByNames", "AlignDetectors", + "DiffractionFocussing", "LoadCalFile", "SaveCalFile", + "MergeCalFiles"}; + } /// Algorithm's category for identification const std::string category() const override { return "Diffraction\\DataHandling\\CalFiles"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateEPP.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateEPP.h index 7c830335786..defb4365f0d 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateEPP.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateEPP.h @@ -36,6 +36,9 @@ class MANTID_ALGORITHMS_DLL CreateEPP : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"FindEPP"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateGroupingWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateGroupingWorkspace.h index 3114ba65dc9..3ea99f0c802 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateGroupingWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateGroupingWorkspace.h @@ -27,6 +27,9 @@ public: /// Algorithm's version for identification int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"DiffractionFocussing", "LoadCalFile"}; + } /// Algorithm's category for identification const std::string category() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateLogPropertyTable.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateLogPropertyTable.h index 9e1b2ab1af4..aa1126df4a5 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateLogPropertyTable.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateLogPropertyTable.h @@ -40,6 +40,9 @@ public: const std::string name() const override { return "CreateLogPropertyTable"; }; /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"CopyLogs"}; + } /// Algorithm's category for identification const std::string category() const override { return "Utility\\Workspaces"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateLogTimeCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateLogTimeCorrection.h index a854f532299..69b99c16991 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateLogTimeCorrection.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateLogTimeCorrection.h @@ -54,6 +54,9 @@ public: } int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"ChangePulsetime", "ShiftLogTime"}; + } const std::string category() const override { return "Events\\EventFiltering"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreatePSDBleedMask.h b/Framework/Algorithms/inc/MantidAlgorithms/CreatePSDBleedMask.h index 05a492c9611..1b77bb1653b 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreatePSDBleedMask.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreatePSDBleedMask.h @@ -57,7 +57,9 @@ public: return "Runs a diagnostic test for saturation of PSD tubes and creates a " "MaskWorkspace marking the failed tube spectra."; } - + const std::vector<std::string> seeAlso() const override { + return {"IdentifyNoisyDetectors"}; + } const std::string category() const override; private: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreatePeaksWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CreatePeaksWorkspace.h index c89ea8575bb..b82ffbe83ab 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreatePeaksWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreatePeaksWorkspace.h @@ -23,6 +23,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SortPeaksWorkspace"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\Peaks;Utility\\Workspaces"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h index 097365525c3..c6af3b525d9 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h @@ -43,6 +43,9 @@ public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CreateWorkspace"}; + } const std::string category() const override; /// Algorithm's summary const std::string summary() const override { diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateSingleValuedWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateSingleValuedWorkspace.h index 6f12e8453a5..177f8fcab21 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateSingleValuedWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateSingleValuedWorkspace.h @@ -53,6 +53,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"CreateWorkspace"}; + } /// Algorithm's category for identification const std::string category() const override { return "Utility\\Workspaces"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspace2.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspace2.h index 03d9025360a..c366d823bd5 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspace2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspace2.h @@ -36,6 +36,9 @@ public: const std::string name() const override; const std::string summary() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CreateTransmissionWorkspaceAuto"}; + } const std::string category() const override; private: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspaceAuto2.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspaceAuto2.h index d70bbe6c2c9..ce18cd219a0 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspaceAuto2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateTransmissionWorkspaceAuto2.h @@ -40,6 +40,9 @@ public: } /// Algorithm's version for identification. @see Algorithm::version int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { + return {"CreateTransmissionWorkspace"}; + } /// Algorithm's category for identification. @see Algorithm::category const std::string category() const override { return "Reflectometry\\ISIS"; } /// Algorithm's summary for documentation diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateUserDefinedBackground.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateUserDefinedBackground.h index 1c23eefb957..d69dce91441 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateUserDefinedBackground.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateUserDefinedBackground.h @@ -44,6 +44,9 @@ public: const std::string name() const override; /// Version number int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"RemoveBackground", "CalculatePolynomialBackground"}; + } /// Category algorithm belongs to const std::string category() const override; /// Description of algorithm diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateWorkspace.h index 7e4f3c1169f..fba8eb347f2 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CreateWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateWorkspace.h @@ -9,7 +9,7 @@ namespace Algorithms { * CreateWorkspace Algorithm * * This algorithm constructs a MatrixWorkspace when passed a vector for each of -*the X, Y, and E +*the X, Y, E, and Dx * data values. The unit for the X Axis can optionally be specified as any of *the units in the * Kernel's UnitFactory. @@ -65,6 +65,9 @@ public: return (1); } ///< @return version number of algorithm + const std::vector<std::string> seeAlso() const override { + return {"CreateSingleValuedWorkspace", "CreateSampleWorkspace"}; + } std::map<std::string, std::string> validateInputs() override; protected: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CropToComponent.h b/Framework/Algorithms/inc/MantidAlgorithms/CropToComponent.h index d847fa91c39..330848923df 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CropToComponent.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CropToComponent.h @@ -35,6 +35,9 @@ class MANTID_ALGORITHMS_DLL CropToComponent final public: const std::string name() const override final; int version() const override final; + const std::vector<std::string> seeAlso() const override { + return {"CropWorkspace"}; + } const std::string category() const override final; const std::string summary() const override final; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CropWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CropWorkspace.h index f4917f1b15d..cec199a358a 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CropWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CropWorkspace.h @@ -75,6 +75,10 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"CropWorkspaceRagged", "CropToComponent", "RemoveBins", + "ExtractSingleSpectrum", "ExtractSpectra"}; + } /// Algorithm's category for identification const std::string category() const override { return "Transforms\\Splitting"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CrossCorrelate.h b/Framework/Algorithms/inc/MantidAlgorithms/CrossCorrelate.h index 199d1651a75..64a710667f3 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CrossCorrelate.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CrossCorrelate.h @@ -72,6 +72,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"GetDetectorOffsets"}; + } /// Algorithm's category for identification const std::string category() const override { return "Arithmetic"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CuboidGaugeVolumeAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/CuboidGaugeVolumeAbsorption.h index 9496e24b5db..a9eaaa3fe70 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CuboidGaugeVolumeAbsorption.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CuboidGaugeVolumeAbsorption.h @@ -57,6 +57,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"AbsorptionCorrection"}; + } private: std::string sampleXML() override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CylinderAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/CylinderAbsorption.h index 3f6a68b2fcf..002d5d2ca35 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CylinderAbsorption.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CylinderAbsorption.h @@ -100,6 +100,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"AbsorptionCorrection"}; + } private: void defineProperties() override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DeleteLog.h b/Framework/Algorithms/inc/MantidAlgorithms/DeleteLog.h index 12c5a0dedef..35bf4200a4e 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/DeleteLog.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/DeleteLog.h @@ -37,6 +37,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"AddSampleLog", "RenameLog"}; + } const std::string category() const override; private: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspace.h index 045f2df92cb..406e0a2c29b 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspace.h @@ -47,6 +47,9 @@ public: const std::string category() const override { return "Utility\\Workspaces"; } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"DeleteWorkspaces"}; + } private: /// Overridden init diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspaces.h b/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspaces.h index 5fb03e76290..af374634491 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspaces.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/DeleteWorkspaces.h @@ -48,6 +48,9 @@ public: const std::string category() const override { return "Utility\\Workspaces"; } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"DeleteWorkspace"}; + } private: /// Overridden init diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DetectorDiagnostic.h b/Framework/Algorithms/inc/MantidAlgorithms/DetectorDiagnostic.h index 6c25619a6d3..8f8d42bebc6 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/DetectorDiagnostic.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/DetectorDiagnostic.h @@ -59,6 +59,10 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"FindDetectorsOutsideLimits", "FindDeadDetectors", + "MedianDetectorTest", "DetectorEfficiencyVariation"}; + } private: // Overridden Algorithm methods diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCor.h b/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCor.h index 473265ec925..de8a1a4827b 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCor.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCor.h @@ -97,6 +97,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"He3TubeEfficiency", "DetectorEfficiencyCorUser"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "CorrectionFunctions\\EfficiencyCorrections;Inelastic\\Corrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCorUser.h b/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCorUser.h index d37642568e5..875e3364283 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCorUser.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCorUser.h @@ -62,6 +62,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"DetectorEfficiencyCor"}; + } const std::string category() const override; private: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyVariation.h b/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyVariation.h index ea4732a4284..cb57fadb7df 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyVariation.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyVariation.h @@ -73,6 +73,9 @@ public: const std::string category() const override; /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"DetectorDiagnostic"}; + } protected: // Overridden Algorithm methods diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DiffractionEventCalibrateDetectors.h b/Framework/Algorithms/inc/MantidAlgorithms/DiffractionEventCalibrateDetectors.h index 2f574ba31e8..f6df300325a 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/DiffractionEventCalibrateDetectors.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/DiffractionEventCalibrateDetectors.h @@ -53,6 +53,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"AlignComponents", "GetDetOffsetsMultiPeaks"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Diffraction\\Calibration;" diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h b/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h index bc4b37726ca..93be5a46103 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h @@ -90,6 +90,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { + return {"AlignDetectors", "AlignAndFocusPowder", "LoadCalFile"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Diffraction\\Focussing"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Divide.h b/Framework/Algorithms/inc/MantidAlgorithms/Divide.h index eec9111b43a..58ed5e56097 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Divide.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Divide.h @@ -56,6 +56,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"Plus", "Minus", "Multiply"}; + } private: void init() override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/EQSANSResolution.h b/Framework/Algorithms/inc/MantidAlgorithms/EQSANSResolution.h index 8eca5028f2c..b4a839b7704 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/EQSANSResolution.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/EQSANSResolution.h @@ -44,6 +44,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"ReactorSANSResolution"}; + } /// Algorithm's category for identification const std::string category() const override { return "SANS"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ElasticWindow.h b/Framework/Algorithms/inc/MantidAlgorithms/ElasticWindow.h index 8db8dcae7ec..d7d1ee0e14e 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ElasticWindow.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ElasticWindow.h @@ -50,6 +50,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"Integration"}; + } /// Algorithm's category for identification const std::string category() const override { return "Inelastic\\Indirect"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/EstimateDivergence.h b/Framework/Algorithms/inc/MantidAlgorithms/EstimateDivergence.h index b6f1f75ddce..d8ca4d92550 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/EstimateDivergence.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/EstimateDivergence.h @@ -35,6 +35,9 @@ class MANTID_ALGORITHMS_DLL EstimateDivergence : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"EstimateResolutionDiffraction"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/EstimateResolutionDiffraction.h b/Framework/Algorithms/inc/MantidAlgorithms/EstimateResolutionDiffraction.h index ce8ec2d8d91..dca712bdd1c 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/EstimateResolutionDiffraction.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/EstimateResolutionDiffraction.h @@ -43,6 +43,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"EstimateDivergence"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Exponential.h b/Framework/Algorithms/inc/MantidAlgorithms/Exponential.h index 784a465f256..f68b314d352 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Exponential.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Exponential.h @@ -58,6 +58,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"Power", "Logarithm"}; + } private: // Overridden UnaryOperation methods diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExponentialCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/ExponentialCorrection.h index d0471988b87..426525e90b6 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ExponentialCorrection.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ExponentialCorrection.h @@ -65,6 +65,10 @@ public: } /// Algorithm's version for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"MagFormFactorCorrection", "PowerLawCorrection", + "OneMinusExponentialCor", "PolynomialCorrection"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "CorrectionFunctions"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExportTimeSeriesLog.h b/Framework/Algorithms/inc/MantidAlgorithms/ExportTimeSeriesLog.h index eb102b7b5e1..3c08034cfc1 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ExportTimeSeriesLog.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ExportTimeSeriesLog.h @@ -41,6 +41,9 @@ public: const std::string name() const override { return "ExportTimeSeriesLog"; }; int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"GetTimeSeriesLogInformation"}; + } const std::string category() const override { return "Diffraction\\DataHandling;Events\\EventFiltering"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExtractFFTSpectrum.h b/Framework/Algorithms/inc/MantidAlgorithms/ExtractFFTSpectrum.h index 03273d2ac66..f2c65586655 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ExtractFFTSpectrum.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ExtractFFTSpectrum.h @@ -55,6 +55,10 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"FFT", "FFTDerivative", "MaxEnt", + "RealFFT", "SassenaFFT", "FFTSmooth"}; + } /// Algorithm's category for identification const std::string category() const override { return "Arithmetic\\FFT"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExtractMask.h b/Framework/Algorithms/inc/MantidAlgorithms/ExtractMask.h index 1395599033b..db6ed184f7c 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ExtractMask.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ExtractMask.h @@ -56,6 +56,9 @@ public: /// Algorithm's version int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"ExtractMaskToTable"}; + } /// Algorithm's category for identification const std::string category() const override { return "Transforms\\Masking"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExtractMaskToTable.h b/Framework/Algorithms/inc/MantidAlgorithms/ExtractMaskToTable.h index a2da267a776..a1b87289f1d 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ExtractMaskToTable.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ExtractMaskToTable.h @@ -46,6 +46,9 @@ public: /// Algorithm's version int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"ExtractMask"}; + } /// Algorithm's category for identification const std::string category() const override { return "Transforms\\Masking"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExtractSingleSpectrum.h b/Framework/Algorithms/inc/MantidAlgorithms/ExtractSingleSpectrum.h index 298ca2bf477..2ef1ec06876 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ExtractSingleSpectrum.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ExtractSingleSpectrum.h @@ -52,6 +52,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"CropWorkspace", "ExtractSpectra", "PerformIndexOperations"}; + } /// Algorithm's category for identification const std::string category() const override { return "Transforms\\Splitting"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExtractSpectra.h b/Framework/Algorithms/inc/MantidAlgorithms/ExtractSpectra.h index 39bf1d6753d..e34b54c0b06 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ExtractSpectra.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ExtractSpectra.h @@ -37,6 +37,10 @@ class DLLExport ExtractSpectra : public API::DistributedAlgorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CropWorkspace", "ExtractSingleSpectrum", "ExtractUnmaskedSpectra", + "PerformIndexOperations"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ExtractUnmaskedSpectra.h b/Framework/Algorithms/inc/MantidAlgorithms/ExtractUnmaskedSpectra.h index ca372477cfa..1b52e0c51b1 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ExtractUnmaskedSpectra.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ExtractUnmaskedSpectra.h @@ -34,6 +34,9 @@ class MANTID_ALGORITHMS_DLL ExtractUnmaskedSpectra : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"RemoveMaskedSpectra"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FFT.h b/Framework/Algorithms/inc/MantidAlgorithms/FFT.h index 072ce8cdd3a..82f6aedf00c 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FFT.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FFT.h @@ -60,6 +60,10 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"ExtractFFTSpectrum", "FFTDerivative", "MaxEnt", "RealFFT", + "SassenaFFT", "FFTSmooth"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Arithmetic\\FFT"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FFTDerivative.h b/Framework/Algorithms/inc/MantidAlgorithms/FFTDerivative.h index 00b88117866..6f5b3c06070 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FFTDerivative.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FFTDerivative.h @@ -53,6 +53,10 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"ExtractFFTSpectrum", "FFT", "MaxEnt", "RealFFT", "SassenaFFT", + "FFTSmooth"}; + } /// Algorithm's category for identification const std::string category() const override { return "Arithmetic\\FFT"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FFTSmooth2.h b/Framework/Algorithms/inc/MantidAlgorithms/FFTSmooth2.h index 5706a7006eb..2fc57c42ca5 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FFTSmooth2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FFTSmooth2.h @@ -43,6 +43,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { + return {"FFT", "WienerSmooth"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Arithmetic\\FFT;Transforms\\Smoothing"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FilterBadPulses.h b/Framework/Algorithms/inc/MantidAlgorithms/FilterBadPulses.h index c57eab8d113..a2344de1000 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FilterBadPulses.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FilterBadPulses.h @@ -56,6 +56,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"FilterByTime", "FilterByLogValue"}; + } const std::string category() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FilterByLogValue.h b/Framework/Algorithms/inc/MantidAlgorithms/FilterByLogValue.h index 0e9eb5773ce..adae9416d81 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FilterByLogValue.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FilterByLogValue.h @@ -42,6 +42,10 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"FilterByXValue", "FilterEvents", "FilterLogByTime", + "FilterBadPulses", "FilterByTime"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Events\\EventFiltering"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FilterByTime.h b/Framework/Algorithms/inc/MantidAlgorithms/FilterByTime.h index 8bd8398a9e1..9177dd53f8d 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FilterByTime.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FilterByTime.h @@ -49,6 +49,10 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadEventNexus", "FilterByXValue", "FilterEvents", + "FilterLogByTime", "FilterBadPulses"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Events\\EventFiltering"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FilterByXValue.h b/Framework/Algorithms/inc/MantidAlgorithms/FilterByXValue.h index 95e703d2c46..73648a3f59d 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FilterByXValue.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FilterByXValue.h @@ -43,6 +43,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"FilterByTime", "FilterByLogValue", "FilterBadPulses"}; + } const std::string category() const override; std::map<std::string, std::string> validateInputs() override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FilterEvents.h b/Framework/Algorithms/inc/MantidAlgorithms/FilterEvents.h index f7cb0a4ee73..08d166fdcaa 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FilterEvents.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FilterEvents.h @@ -67,6 +67,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"GenerateEventsFilter", "FilterByTime", "FilterByLogValue"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FindCenterOfMassPosition2.h b/Framework/Algorithms/inc/MantidAlgorithms/FindCenterOfMassPosition2.h index a1cd8654046..f5893103918 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FindCenterOfMassPosition2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FindCenterOfMassPosition2.h @@ -50,6 +50,7 @@ public: /// Algorithm's version int version() const override { return (2); } + /// Algorithm's category for identification const std::string category() const override { return "SANS"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FindDeadDetectors.h b/Framework/Algorithms/inc/MantidAlgorithms/FindDeadDetectors.h index 9581d8fd6d8..cfbbd00da51 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FindDeadDetectors.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FindDeadDetectors.h @@ -75,6 +75,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"FindDetectorsOutsideLimits", "DetectorDiagnostic"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Diagnostics"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FindDetectorsOutsideLimits.h b/Framework/Algorithms/inc/MantidAlgorithms/FindDetectorsOutsideLimits.h index aaca7555e04..ffe28acd94d 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FindDetectorsOutsideLimits.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FindDetectorsOutsideLimits.h @@ -79,6 +79,9 @@ public: const std::string category() const override; /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"FindDeadDetectors", "DetectorDiagnostic"}; + } private: /// Overridden init diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FindPeakBackground.h b/Framework/Algorithms/inc/MantidAlgorithms/FindPeakBackground.h index d2737dc9b99..a7ce1365d6c 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FindPeakBackground.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FindPeakBackground.h @@ -49,6 +49,7 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { return {"Fit"}; } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Utility\\Calculation"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FindPeaks.h b/Framework/Algorithms/inc/MantidAlgorithms/FindPeaks.h index 7cdaf8d08bb..3a5aeafd292 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FindPeaks.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FindPeaks.h @@ -78,6 +78,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"MatchPeaks", "FindPeaksMD", "GeneratePeaks"}; + } /// Algorithm's category for identification const std::string category() const override { return "Optimization\\PeakFinding"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FitPeak.h b/Framework/Algorithms/inc/MantidAlgorithms/FitPeak.h index f89d0d207af..abb09b22a1d 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FitPeak.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FitPeak.h @@ -80,6 +80,7 @@ private: /// Version int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { return {"Fit"}; } /// Init void init() override; /// Exec diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FixGSASInstrumentFile.h b/Framework/Algorithms/inc/MantidAlgorithms/FixGSASInstrumentFile.h index 7376307abd1..7743225df33 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FixGSASInstrumentFile.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FixGSASInstrumentFile.h @@ -41,6 +41,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadGSASInstrumentFile"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FlatPlateAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/FlatPlateAbsorption.h index 4253708e901..e043d49b51f 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/FlatPlateAbsorption.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/FlatPlateAbsorption.h @@ -88,6 +88,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"AbsorptionCorrection"}; + } protected: void initialiseCachedDistances() override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h b/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h index 7c8f6930d78..9e12f0b9e99 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/GenerateEventsFilter.h @@ -73,6 +73,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"FilterEvents", "FilterByTime", "FilterByLogValue"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Events\\EventFiltering"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GenerateIPythonNotebook.h b/Framework/Algorithms/inc/MantidAlgorithms/GenerateIPythonNotebook.h index 882baeea539..93e9b72a6f8 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/GenerateIPythonNotebook.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/GenerateIPythonNotebook.h @@ -51,6 +51,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"RecordPythonScript", "GeneratePythonScript"}; + } /// Algorithm's category for identification const std::string category() const override { return "Utility\\Python"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GeneratePeaks.h b/Framework/Algorithms/inc/MantidAlgorithms/GeneratePeaks.h index a7dbfa73025..0a921362f4c 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/GeneratePeaks.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/GeneratePeaks.h @@ -53,6 +53,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"FindPeaks", "MatchPeaks"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Crystal\\Peaks"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GeneratePythonScript.h b/Framework/Algorithms/inc/MantidAlgorithms/GeneratePythonScript.h index 90db547f684..4e98759a226 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/GeneratePythonScript.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/GeneratePythonScript.h @@ -54,6 +54,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"RecordPythonScript", "GenerateIPythonNotebook"}; + } /// Algorithm's category for identification const std::string category() const override { return "Utility\\Python"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GetAllEi.h b/Framework/Algorithms/inc/MantidAlgorithms/GetAllEi.h index 7cdd5ef79a4..10d97d6341a 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/GetAllEi.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/GetAllEi.h @@ -55,6 +55,7 @@ public: } /// Algorithm's version for identification. @see Algorithm::version int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { return {"GetEi"}; } /// Algorithm's category for identification. @see Algorithm::category const std::string category() const override { return "Inelastic\\Ei"; }; /// Cross-check properties with each other @see IAlgorithm::validateInputs diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GetDetOffsetsMultiPeaks.h b/Framework/Algorithms/inc/MantidAlgorithms/GetDetOffsetsMultiPeaks.h index fe45add3a62..35faf98d455 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/GetDetOffsetsMultiPeaks.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/GetDetOffsetsMultiPeaks.h @@ -70,6 +70,9 @@ public: const std::string name() const override { return "GetDetOffsetsMultiPeaks"; } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"GetDetectorOffsets"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Diffraction\\Calibration"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GetDetectorOffsets.h b/Framework/Algorithms/inc/MantidAlgorithms/GetDetectorOffsets.h index f7b2392926d..0e08637ad9b 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/GetDetectorOffsets.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/GetDetectorOffsets.h @@ -47,6 +47,10 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"GetDetOffsetsMultiPeaks", "CalibrateRectangularDetectors", + "AlignComponents"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Diffraction\\Calibration"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GetEi2.h b/Framework/Algorithms/inc/MantidAlgorithms/GetEi2.h index c717122ebd9..57ac117c791 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/GetEi2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/GetEi2.h @@ -80,6 +80,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { + return {"GetAllEi", "GetEiMonDet", "GetEiT0atSNS"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Inelastic\\Ei"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GetEiMonDet2.h b/Framework/Algorithms/inc/MantidAlgorithms/GetEiMonDet2.h index fc8b693dd75..66e032bb637 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/GetEiMonDet2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/GetEiMonDet2.h @@ -56,6 +56,7 @@ public: /// Returns algorithm's version for identification int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { return {"GetEi"}; } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Inelastic\\Ei"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GetTimeSeriesLogInformation.h b/Framework/Algorithms/inc/MantidAlgorithms/GetTimeSeriesLogInformation.h index 8776e174d15..169b4bbb421 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/GetTimeSeriesLogInformation.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/GetTimeSeriesLogInformation.h @@ -50,6 +50,9 @@ public: } int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"AddSampleLogMultiple"}; + } const std::string category() const override { return "Diffraction\\Utility;Events\\EventFiltering"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GroupWorkspaces.h b/Framework/Algorithms/inc/MantidAlgorithms/GroupWorkspaces.h index 97a25bb314f..b7e5f75380a 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/GroupWorkspaces.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/GroupWorkspaces.h @@ -49,6 +49,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"UnGroupWorkspace"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Grouping;Utility\\Workspaces"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/HRPDSlabCanAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/HRPDSlabCanAbsorption.h index 5496735501c..9aec8352820 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/HRPDSlabCanAbsorption.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/HRPDSlabCanAbsorption.h @@ -79,6 +79,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"AbsorptionCorrection"}; + } /// Algorithm's category for identification const std::string category() const override { return "CorrectionFunctions\\AbsorptionCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h b/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h index 275d5bdce0a..b3372121aa9 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h @@ -73,6 +73,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"DetectorEfficiencyCor"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "CorrectionFunctions\\EfficiencyCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/IdentifyNoisyDetectors.h b/Framework/Algorithms/inc/MantidAlgorithms/IdentifyNoisyDetectors.h index 429d437f954..020a2193d25 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/IdentifyNoisyDetectors.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/IdentifyNoisyDetectors.h @@ -55,6 +55,10 @@ public: return (1); } ///< @return version number of algorithm + const std::vector<std::string> seeAlso() const override { + return {"CreatePSDBleedMask"}; + } + private: void init() override; ///< Initialise the algorithm. Declare properties, etc. void exec() override; ///< Executes the algorithm. diff --git a/Framework/Algorithms/inc/MantidAlgorithms/IntegrateByComponent.h b/Framework/Algorithms/inc/MantidAlgorithms/IntegrateByComponent.h index caa647670c5..4610fa03e45 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/IntegrateByComponent.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/IntegrateByComponent.h @@ -40,6 +40,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"Integration"}; + } const std::string category() const override; private: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Integration.h b/Framework/Algorithms/inc/MantidAlgorithms/Integration.h index 37eae998773..20a1320c1dc 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Integration.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Integration.h @@ -67,6 +67,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"IntegrateByComponent", "Rebin"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Arithmetic;Transforms\\Rebin"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/InterpolatingRebin.h b/Framework/Algorithms/inc/MantidAlgorithms/InterpolatingRebin.h index 458b4b79d75..55adc55e8e0 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/InterpolatingRebin.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/InterpolatingRebin.h @@ -79,6 +79,7 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { return {"Rebin"}; } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Rebin"; } /// Alias for the algorithm. Must override so it doesn't get parent class's diff --git a/Framework/Algorithms/inc/MantidAlgorithms/InvertMask.h b/Framework/Algorithms/inc/MantidAlgorithms/InvertMask.h index 5fbb20ac6df..87903339789 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/InvertMask.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/InvertMask.h @@ -43,6 +43,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"BinaryOperateMasks", "MaskDetectors"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Masking"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/LineProfile.h b/Framework/Algorithms/inc/MantidAlgorithms/LineProfile.h index e2da673079d..d1921f4400f 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/LineProfile.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/LineProfile.h @@ -35,6 +35,9 @@ class MANTID_ALGORITHMS_DLL LineProfile : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"RingProfile"}; + } const std::string category() const override; const std::string summary() const override; std::map<std::string, std::string> validateInputs() override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Logarithm.h b/Framework/Algorithms/inc/MantidAlgorithms/Logarithm.h index 4831106bddb..c5cf955fc3f 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Logarithm.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Logarithm.h @@ -62,6 +62,9 @@ public: /// Algorithm's version for identification int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"Power", "Exponential"}; + } /// Algorithm's category for identification const std::string category() const override { return "Arithmetic"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/LorentzCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/LorentzCorrection.h index ba973bfdf0e..e7f64c86975 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/LorentzCorrection.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/LorentzCorrection.h @@ -35,6 +35,9 @@ class DLLExport LorentzCorrection : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"AnvredCorrection"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MagFormFactorCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/MagFormFactorCorrection.h index 98d2ac575b8..0799f810be7 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MagFormFactorCorrection.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MagFormFactorCorrection.h @@ -56,6 +56,7 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { return {"SofQW"}; } /// Algorithm's category for identification const std::string category() const override { return "CorrectionFunctions"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaskBins.h b/Framework/Algorithms/inc/MantidAlgorithms/MaskBins.h index 743d0a81787..85e5b5b1082 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaskBins.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaskBins.h @@ -64,6 +64,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"MaskBinsFromTable"}; + } /// Algorithm's category for identification const std::string category() const override { return "Transforms\\Masking"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaskBinsFromTable.h b/Framework/Algorithms/inc/MantidAlgorithms/MaskBinsFromTable.h index 740c88c9d8c..c8974c5b7eb 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaskBinsFromTable.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaskBinsFromTable.h @@ -46,6 +46,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"MaskBins"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Masking"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h b/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h index fba8e6c81c1..d4fd299ed3b 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h @@ -57,6 +57,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"MaskDetectors"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Diffraction\\Masking;Transforms\\Masking"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaskInstrument.h b/Framework/Algorithms/inc/MantidAlgorithms/MaskInstrument.h index ef683723228..1c3c0493bee 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaskInstrument.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaskInstrument.h @@ -39,6 +39,9 @@ class MANTID_ALGORITHMS_DLL MaskInstrument : public API::DistributedAlgorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"MaskDetectors", "ClearMaskedSpectra"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Max.h b/Framework/Algorithms/inc/MantidAlgorithms/Max.h index 8f3a089b5b3..ad8c92dcb33 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Max.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Max.h @@ -58,6 +58,9 @@ public: const std::string name() const override { return "Max"; } /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"Min", "MaxMin"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Arithmetic"; } /// Summary of algorithms purpose diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt.h b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt.h index 14582e52674..3980cda6bcf 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaxEnt.h @@ -43,6 +43,10 @@ public: const std::string name() const override; /// Algorithm's version int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ExtractFFTSpectrum", "FFT", "FFTDerivative", "RealFFT", + "SassenaFFT", "FFTSmooth"}; + } /// Algorithm's category const std::string category() const override; /// Algorithm's summary diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaxMin.h b/Framework/Algorithms/inc/MantidAlgorithms/MaxMin.h index f2cb873b2f8..32a59b4c693 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MaxMin.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MaxMin.h @@ -65,6 +65,9 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"Max", "Min"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Arithmetic"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MedianDetectorTest.h b/Framework/Algorithms/inc/MantidAlgorithms/MedianDetectorTest.h index 695b0320bb1..dba48a980ca 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MedianDetectorTest.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MedianDetectorTest.h @@ -77,6 +77,9 @@ public: const std::string category() const override; /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"DetectorDiagnostic"}; + } private: // Overridden Algorithm methods diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h b/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h index d3d22f26abc..8165863d775 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h @@ -74,6 +74,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"ConjoinWorkspaces"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Merging"; } // Overriden MultiPeriodGroupAlgorithm method. diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Min.h b/Framework/Algorithms/inc/MantidAlgorithms/Min.h index 4787828eb9d..f218d65f679 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Min.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Min.h @@ -58,6 +58,9 @@ public: const std::string name() const override { return "Min"; } /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"Max", "MaxMin"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Arithmetic"; } /// Summary of algorithms purpose diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Minus.h b/Framework/Algorithms/inc/MantidAlgorithms/Minus.h index 5e6a402ccb6..bd9acf03cbe 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Minus.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Minus.h @@ -58,6 +58,9 @@ public: const std::string alias() const override; /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"Plus", "Divide", "Multiply"}; + } private: // Overridden BinaryOperation methods diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzero.h b/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzero.h index fd98511d372..97af2302028 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzero.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzero.h @@ -86,6 +86,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"ModeratorTzeroLinear"}; + } /// Algorithm's category for identification const std::string category() const override { return "CorrectionFunctions\\InstrumentCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzeroLinear.h b/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzeroLinear.h index 9a3ead956e7..f0fb409e222 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzeroLinear.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ModeratorTzeroLinear.h @@ -88,6 +88,9 @@ public: const std::string summary() const override; /// Algorithm's version int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ModeratorTzero"}; + } /// Algorithm's category for identification const std::string category() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MonitorEfficiencyCorUser.h b/Framework/Algorithms/inc/MantidAlgorithms/MonitorEfficiencyCorUser.h index 1b9c80ef93b..75ede8e3a45 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MonitorEfficiencyCorUser.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MonitorEfficiencyCorUser.h @@ -26,6 +26,9 @@ public: /// Algorithm's version int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"NormaliseToMonitor"}; + } /// Algorithm's category for identification const std::string category() const override { return "CorrectionFunctions\\NormalisationCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MonteCarloAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/MonteCarloAbsorption.h index 179ca161b01..2d627213fc7 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MonteCarloAbsorption.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MonteCarloAbsorption.h @@ -49,6 +49,10 @@ public: const std::string name() const override { return "MonteCarloAbsorption"; } /// Algorithm's version int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"MayersSampleCorrection", "MultipleScatteringCylinderAbsorption", + "PearlMCAbsorption", "VesuvioCalculateMS"}; + } /// Algorithm's category for identification const std::string category() const override { return "CorrectionFunctions\\AbsorptionCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MostLikelyMean.h b/Framework/Algorithms/inc/MantidAlgorithms/MostLikelyMean.h index f673f021c81..0d71ccd28e6 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MostLikelyMean.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MostLikelyMean.h @@ -35,6 +35,7 @@ class MANTID_ALGORITHMS_DLL MostLikelyMean : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { return {"Mean"}; } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MultipleScatteringCylinderAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/MultipleScatteringCylinderAbsorption.h index ab2190f5bf9..c3bf17eb48b 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MultipleScatteringCylinderAbsorption.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MultipleScatteringCylinderAbsorption.h @@ -49,6 +49,10 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"MonteCarloAbsorption", "MayersSampleCorrection", + "PearlMCAbsorption", "VesuvioCalculateMS"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Multiply.h b/Framework/Algorithms/inc/MantidAlgorithms/Multiply.h index 716a97bb14a..4300b55bbe1 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Multiply.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Multiply.h @@ -56,6 +56,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"Plus", "Minus", "Divide"}; + } private: // Overridden BinaryOperation methods diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MultiplyRange.h b/Framework/Algorithms/inc/MantidAlgorithms/MultiplyRange.h index 3ff7887c9de..a1345d92492 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/MultiplyRange.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/MultiplyRange.h @@ -54,6 +54,9 @@ public: } int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"Multiply"}; + } const std::string category() const override { return "Arithmetic;CorrectionFunctions"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/NRCalculateSlitResolution.h b/Framework/Algorithms/inc/MantidAlgorithms/NRCalculateSlitResolution.h index e8f6eeab26b..8a2a880bd6a 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/NRCalculateSlitResolution.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/NRCalculateSlitResolution.h @@ -37,6 +37,9 @@ class DLLExport NRCalculateSlitResolution : public API::DataProcessorAlgorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CalculateSlits"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByCurrent.h b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByCurrent.h index c41872d84f0..46c22074df6 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByCurrent.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByCurrent.h @@ -58,6 +58,7 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { return {"Divide"}; } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "CorrectionFunctions\\NormalisationCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByDetector.h b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByDetector.h index 70f9574d2b7..802dd0dce9f 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByDetector.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseByDetector.h @@ -55,6 +55,7 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { return {"Divide"}; } const std::string category() const override; private: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h index 0d62e5d949d..c99bc15fc87 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h @@ -88,6 +88,7 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { return {"Divide"}; } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "CorrectionFunctions\\NormalisationCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToUnity.h b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToUnity.h index c3719f59bfc..ca93683fcb2 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToUnity.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToUnity.h @@ -67,6 +67,7 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { return {"Divide"}; } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "CorrectionFunctions\\NormalisationCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/OneMinusExponentialCor.h b/Framework/Algorithms/inc/MantidAlgorithms/OneMinusExponentialCor.h index e6f247584e8..b6dfe1d62ce 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/OneMinusExponentialCor.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/OneMinusExponentialCor.h @@ -65,6 +65,10 @@ public: /// Algorithm's version for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"MagFormFactorCorrection", "ExponentialCorrection", + "PowerLawCorrection"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "CorrectionFunctions"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PDCalibration.h b/Framework/Algorithms/inc/MantidAlgorithms/PDCalibration.h index bacf0c065f8..bb44e769669 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/PDCalibration.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/PDCalibration.h @@ -41,6 +41,9 @@ public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CalibrateRectangularDetectors"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PDFFourierTransform.h b/Framework/Algorithms/inc/MantidAlgorithms/PDFFourierTransform.h index fb7dd244241..4fc13a297bc 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/PDFFourierTransform.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/PDFFourierTransform.h @@ -22,6 +22,7 @@ public: /// Algorithm's version for identification int version() const override; + const std::vector<std::string> seeAlso() const override { return {"FFT"}; } /// Algorithm's category for identification const std::string category() const override; /// @copydoc Algorithm::validateInputs() diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PerformIndexOperations.h b/Framework/Algorithms/inc/MantidAlgorithms/PerformIndexOperations.h index fa32a9e561a..62fe4913a32 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/PerformIndexOperations.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/PerformIndexOperations.h @@ -40,6 +40,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ExtractSpectra"}; + } const std::string category() const override; private: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h b/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h index d47ca50770d..8b9ffafb6b5 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h @@ -44,7 +44,9 @@ public: const std::string summary() const override { return "Generates a quadrature phase signal."; } - + const std::vector<std::string> seeAlso() const override { + return {"MuonMaxent"}; + } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } /// Algorithm's category for identification overriding a virtual method diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PlotAsymmetryByLogValue.h b/Framework/Algorithms/inc/MantidAlgorithms/PlotAsymmetryByLogValue.h index e23fc5a2826..f804ee642d9 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/PlotAsymmetryByLogValue.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/PlotAsymmetryByLogValue.h @@ -69,6 +69,9 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"AsymmetryCalc", "CalculateMuonAsymmetry", "PlotPeakByLogValue"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Muon"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Plus.h b/Framework/Algorithms/inc/MantidAlgorithms/Plus.h index c06e1cbe8ea..1e6239de2bf 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Plus.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Plus.h @@ -58,6 +58,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"Divide", "Minus", "Multiply"}; + } private: // Overridden BinaryOperation methods diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PolarizationCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/PolarizationCorrection.h index 82a9adc2c20..07a29b9ac67 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/PolarizationCorrection.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/PolarizationCorrection.h @@ -41,6 +41,9 @@ class DLLExport PolarizationCorrection : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"PolarizationEfficiencyCor"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PolarizationEfficiencyCor.h b/Framework/Algorithms/inc/MantidAlgorithms/PolarizationEfficiencyCor.h index 53ed3838865..a84f32e031f 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/PolarizationEfficiencyCor.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/PolarizationEfficiencyCor.h @@ -42,6 +42,9 @@ class MANTID_ALGORITHMS_DLL PolarizationEfficiencyCor : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"PolarizationCorrection"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PolynomialCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/PolynomialCorrection.h index 9461f9ba196..b287e7bdf30 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/PolynomialCorrection.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/PolynomialCorrection.h @@ -63,6 +63,10 @@ public: /// Algorithm's version for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"OneMinusExponentialCor", "MagFormFactorCorrection", + "ExponentialCorrection", "PowerLawCorrection"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "CorrectionFunctions"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Power.h b/Framework/Algorithms/inc/MantidAlgorithms/Power.h index 193cb745874..ece61ba23d3 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Power.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Power.h @@ -59,6 +59,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"Exponential", "Logarithm"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Arithmetic"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/PowerLawCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/PowerLawCorrection.h index ae78311091a..970c63de36c 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/PowerLawCorrection.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/PowerLawCorrection.h @@ -63,6 +63,10 @@ public: /// Algorithm's version for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"PolynomialCorrection", "OneMinusExponentialCor", + "MagFormFactorCorrection", "ExponentialCorrection"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "CorrectionFunctions"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Q1D2.h b/Framework/Algorithms/inc/MantidAlgorithms/Q1D2.h index e0779024764..75184ff5b4d 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Q1D2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Q1D2.h @@ -52,6 +52,9 @@ public: /// Algorithm's version int version() const override { return (2); } + const std::vector<std::string> seeAlso() const override { + return {"Q1DWeighted", "Qxy"}; + } /// Algorithm's category for identification const std::string category() const override { return "SANS"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Q1DWeighted.h b/Framework/Algorithms/inc/MantidAlgorithms/Q1DWeighted.h index e0ca710e74c..02dbe13c83f 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Q1DWeighted.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Q1DWeighted.h @@ -56,6 +56,7 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { return {"Q1D"}; } /// Algorithm's category for identification const std::string category() const override { return "SANS"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Qxy.h b/Framework/Algorithms/inc/MantidAlgorithms/Qxy.h index fe36eda1772..f91222a9542 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Qxy.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Qxy.h @@ -58,6 +58,7 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { return {"Q1D"}; } /// Algorithm's category for identification const std::string category() const override { return "SANS"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RRFMuon.h b/Framework/Algorithms/inc/MantidAlgorithms/RRFMuon.h index f23184aafc1..3fe15b988d5 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RRFMuon.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RRFMuon.h @@ -45,6 +45,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CalculateMuonAsymmetry"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Muon"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RadiusSum.h b/Framework/Algorithms/inc/MantidAlgorithms/RadiusSum.h index af0fc0257a7..8f1eba680b5 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RadiusSum.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RadiusSum.h @@ -46,6 +46,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"RingProfile", "RadiusSum"}; + } const std::string category() const override; static bool inputWorkspaceHasInstrumentAssociated(API::MatrixWorkspace_sptr); diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h b/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h index 11505f00e7c..6ba55dde1fe 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h @@ -90,6 +90,11 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"CreateDummyCalFile", "CreateCalFileByNames", "AlignDetectors", + "DiffractionFocussing", "LoadCalFile", "SaveCalFile", + "MergeCalFiles"}; + } /// Algorithm's category for identification const std::string category() const override { return "Diffraction\\DataHandling\\CalFiles"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RealFFT.h b/Framework/Algorithms/inc/MantidAlgorithms/RealFFT.h index bba0209f620..2c6201579c9 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RealFFT.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RealFFT.h @@ -44,6 +44,10 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"ExtractFFTSpectrum", "FFT", "FFTDerivative", "MaxEnt", + "SassenaFFT", "FFTSmooth"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Arithmetic\\FFT"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Rebin.h b/Framework/Algorithms/inc/MantidAlgorithms/Rebin.h index 51240422723..585cc66d279 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Rebin.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Rebin.h @@ -67,6 +67,11 @@ public: const std::string category() const override { return "Transforms\\Rebin"; } /// Algorithm's aliases const std::string alias() const override { return "rebin"; } + /// Algorithm's seeAlso + const std::vector<std::string> seeAlso() const override { + return {"RebinToWorkspace", "Rebin2D", "Rebunch", + "Regroup", "RebinByPulseTimes", "RebinByTimeAtSample"}; + } static std::vector<double> rebinParamsFromInput(const std::vector<double> &inParams, diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Rebin2D.h b/Framework/Algorithms/inc/MantidAlgorithms/Rebin2D.h index d5e0b2c3206..59981e907ce 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Rebin2D.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Rebin2D.h @@ -48,6 +48,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"Rebin", "SofQW"}; + } /// Algorithm's category for identification const std::string category() const override { return "Transforms\\Rebin"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RebinByPulseTimes.h b/Framework/Algorithms/inc/MantidAlgorithms/RebinByPulseTimes.h index 711aabe826f..74a7579fd41 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RebinByPulseTimes.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RebinByPulseTimes.h @@ -41,7 +41,12 @@ public: } int version() const override; + const std::string category() const override; + /// Algorithm's seeAlso + const std::vector<std::string> seeAlso() const override { + return {"Rebin", "RebinByTimeAtSample"}; + } private: /// Do the algorithm specific histogramming. diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RebinByTimeAtSample.h b/Framework/Algorithms/inc/MantidAlgorithms/RebinByTimeAtSample.h index 6bca5d6b0e0..7316a4e2712 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RebinByTimeAtSample.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RebinByTimeAtSample.h @@ -36,8 +36,13 @@ class DLLExport RebinByTimeAtSample : public RebinByTimeBase { public: const std::string name() const override; int version() const override; + const std::string category() const override; const std::string summary() const override; + /// Algorithm's seeAlso + const std::vector<std::string> seeAlso() const override { + return {"Rebin", "RebinByPulseTimes"}; + } private: void doHistogramming(Mantid::API::IEventWorkspace_sptr inWS, diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RebinToWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/RebinToWorkspace.h index 62cf3439e3c..3518bb59c6c 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RebinToWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RebinToWorkspace.h @@ -57,8 +57,11 @@ public: /// Algorithm's version int version() const override { return (1); } + /// Algorithm's category for identification const std::string category() const override { return "Transforms\\Rebin"; } + /// Algorithm's seeAlso + const std::vector<std::string> seeAlso() const override { return {"Rebin"}; } protected: Parallel::ExecutionMode getParallelExecutionMode( diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Rebunch.h b/Framework/Algorithms/inc/MantidAlgorithms/Rebunch.h index 6ab2eec8105..51d1ca1c91c 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Rebunch.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Rebunch.h @@ -67,6 +67,7 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { return {"Rebin"}; } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Rebin"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RecordPythonScript.h b/Framework/Algorithms/inc/MantidAlgorithms/RecordPythonScript.h index f60f3d88c23..5acc3d276ed 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RecordPythonScript.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RecordPythonScript.h @@ -54,6 +54,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"GenerateIPythonNotebook", "GeneratePythonScript"}; + } /// Algorithm's category for identification const std::string category() const override { return "Utility\\Python"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne2.h b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne2.h index 49a8f680da0..d947f14b638 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne2.h @@ -56,6 +56,9 @@ public: } /// Algorithm's version for identification. int version() const override { return 2; }; + const std::vector<std::string> seeAlso() const override { + return {"ReflectometryReductionOneAuto"}; + } /// Algorithm's category for identification. const std::string category() const override { return "Reflectometry"; }; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto2.h b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto2.h index dddab606aea..6cca5e21700 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto2.h @@ -36,6 +36,9 @@ class DLLExport ReflectometryReductionOneAuto2 public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ReflectometryReductionOne"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Regroup.h b/Framework/Algorithms/inc/MantidAlgorithms/Regroup.h index a301f7c678c..9818529a54a 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Regroup.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Regroup.h @@ -60,6 +60,7 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { return {"Rebin"}; } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Rebin"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RemoveBins.h b/Framework/Algorithms/inc/MantidAlgorithms/RemoveBins.h index 79fa181b28f..d208dbfa445 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RemoveBins.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RemoveBins.h @@ -71,6 +71,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CropWorkspace"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Splitting"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RemoveExpDecay.h b/Framework/Algorithms/inc/MantidAlgorithms/RemoveExpDecay.h index 7ab51404be3..21769da0fac 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RemoveExpDecay.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RemoveExpDecay.h @@ -59,6 +59,7 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { return {"Fit"}; } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Muon"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RemoveMaskedSpectra.h b/Framework/Algorithms/inc/MantidAlgorithms/RemoveMaskedSpectra.h index 95d106f840e..2a1f98e0a90 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RemoveMaskedSpectra.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RemoveMaskedSpectra.h @@ -34,6 +34,9 @@ class DLLExport RemoveMaskedSpectra : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ExtractUnmaskedSpectra"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RemoveWorkspaceHistory.h b/Framework/Algorithms/inc/MantidAlgorithms/RemoveWorkspaceHistory.h index 5c2e4ffaa01..cde17cd34f0 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RemoveWorkspaceHistory.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RemoveWorkspaceHistory.h @@ -38,6 +38,9 @@ public: const std::string name() const override; const std::string summary() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"Comment"}; + } const std::string category() const override; private: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspace.h index fcde2879ca7..324819fb3e1 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspace.h @@ -47,6 +47,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"RenameWorkspaces"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Utility\\Workspaces"; } /// Check that input params are valid diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspaces.h b/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspaces.h index 59e5f4f39e0..052e3e01576 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspaces.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RenameWorkspaces.h @@ -57,6 +57,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"RenameWorkspace"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Utility\\Workspaces"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ResampleX.h b/Framework/Algorithms/inc/MantidAlgorithms/ResampleX.h index ec56de62ac3..4a9d517a078 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ResampleX.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ResampleX.h @@ -37,6 +37,10 @@ class DLLExport ResampleX : public Algorithms::Rebin { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"RebinToWorkspace", "Rebin2D", "Rebunch", + "Regroup", "RebinByPulseTimes", "RebinByTimeAtSample"}; + } const std::string category() const override; const std::string alias() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ResizeRectangularDetector.h b/Framework/Algorithms/inc/MantidAlgorithms/ResizeRectangularDetector.h index 1d4e8b3d43f..c3def823b2d 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ResizeRectangularDetector.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ResizeRectangularDetector.h @@ -41,6 +41,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ModifyDetectorDotDatFile"}; + } const std::string category() const override; private: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/RingProfile.h b/Framework/Algorithms/inc/MantidAlgorithms/RingProfile.h index e5a96681c94..7e0be63d542 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/RingProfile.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/RingProfile.h @@ -47,6 +47,9 @@ public: } int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LineProfile"}; + } const std::string category() const override { return "Transforms\\Grouping"; }; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MayersSampleCorrection.h b/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MayersSampleCorrection.h index 9d336dc7886..19719ae48c0 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MayersSampleCorrection.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MayersSampleCorrection.h @@ -39,6 +39,9 @@ public: int version() const override; const std::string category() const override; const std::string summary() const override; + const std::vector<std::string> seeAlso() const override { + return {"MonteCarloAbsorption", "MultipleScatteringCylinderAbsorption"}; + } private: void init() override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SassenaFFT.h b/Framework/Algorithms/inc/MantidAlgorithms/SassenaFFT.h index e1b131edc2c..254c77abb8b 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SassenaFFT.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SassenaFFT.h @@ -47,6 +47,10 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"ExtractFFTSpectrum", "FFT", "FFTDerivative", "MaxEnt", "RealFFT", + "FFTSmooth"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Arithmetic\\FFT"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Scale.h b/Framework/Algorithms/inc/MantidAlgorithms/Scale.h index 5c451b14fcb..f87b8a15d9c 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Scale.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Scale.h @@ -55,6 +55,7 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { return {"ScaleX"}; } /// Algorithm's category for identification const std::string category() const override { return "Arithmetic;CorrectionFunctions"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ScaleX.h b/Framework/Algorithms/inc/MantidAlgorithms/ScaleX.h index f1ea4fa1da5..82c1995077e 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ScaleX.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ScaleX.h @@ -62,6 +62,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"ChangeBinOffset", "Scale"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Arithmetic;CorrectionFunctions"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SetInstrumentParameter.h b/Framework/Algorithms/inc/MantidAlgorithms/SetInstrumentParameter.h index 316649738e8..ec65580bc12 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SetInstrumentParameter.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SetInstrumentParameter.h @@ -46,6 +46,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"RotateInstrumentComponent", "MoveInstrumentComponent"}; + } const std::string category() const override; std::map<std::string, std::string> validateInputs() override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ShiftLogTime.h b/Framework/Algorithms/inc/MantidAlgorithms/ShiftLogTime.h index 8b233e64390..eff5195d540 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/ShiftLogTime.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/ShiftLogTime.h @@ -36,6 +36,9 @@ class DLLExport ShiftLogTime : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CreateLogTimeCorrection", "ChangePulsetime", "ChangeLogTime"}; + } const std::string category() const override; /// Summary of algorithms purpose diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SmoothData.h b/Framework/Algorithms/inc/MantidAlgorithms/SmoothData.h index 6624446363e..851e6550560 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SmoothData.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SmoothData.h @@ -63,6 +63,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SmoothNeighbours"}; + } /// Algorithm's category for identification const std::string category() const override { return "Transforms\\Smoothing"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h b/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h index 5a9375d1842..4c9c7781fb1 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SmoothNeighbours.h @@ -92,6 +92,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SmoothData"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Smoothing"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SofQW.h b/Framework/Algorithms/inc/MantidAlgorithms/SofQW.h index 2326fc7fb2b..c7d91346c7b 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SofQW.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SofQW.h @@ -57,6 +57,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SofQWCentre", "SofQWPolygon", "SofQWNormalisedPolygon", "Rebin2D"}; + } /// Algorithm's category for identification const std::string category() const override { return "Inelastic\\SofQW"; } /// Create the output workspace diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SofQWCentre.h b/Framework/Algorithms/inc/MantidAlgorithms/SofQWCentre.h index f850e0d0329..b63f12fe518 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SofQWCentre.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SofQWCentre.h @@ -62,6 +62,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SofQW", "Rebin2D"}; + } /// Algorithm's category for identification const std::string category() const override { return "Inelastic\\SofQW"; } /// Create the output workspace diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SofQWNormalisedPolygon.h b/Framework/Algorithms/inc/MantidAlgorithms/SofQWNormalisedPolygon.h index e3a4a37bb9a..932e6ecf338 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SofQWNormalisedPolygon.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SofQWNormalisedPolygon.h @@ -71,6 +71,9 @@ public: /// Algorithm's version for identification int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"SofQW", "SofQWPolygon", "Rebin2D"}; + } /// Algorithm's category for identification const std::string category() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SofQWPolygon.h b/Framework/Algorithms/inc/MantidAlgorithms/SofQWPolygon.h index 250dd2cc982..e4124966553 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SofQWPolygon.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SofQWPolygon.h @@ -71,6 +71,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"SofQW", "SofQWNormalisedPolygon", "Rebin2D"}; + } /// Algorithm's category for identification const std::string category() const override { return "Inelastic\\SofQW"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SolidAngle.h b/Framework/Algorithms/inc/MantidAlgorithms/SolidAngle.h index 18553ffd1bd..1538828b148 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SolidAngle.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SolidAngle.h @@ -57,6 +57,7 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { return {"Divide"}; } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "CorrectionFunctions\\InstrumentCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SortEvents.h b/Framework/Algorithms/inc/MantidAlgorithms/SortEvents.h index 9401200dad1..757f1bd48ad 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SortEvents.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SortEvents.h @@ -50,6 +50,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadEventNexus"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Events;Utility\\Sorting"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SpatialGrouping.h b/Framework/Algorithms/inc/MantidAlgorithms/SpatialGrouping.h index 3171b7d784d..298627ace52 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SpatialGrouping.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SpatialGrouping.h @@ -61,6 +61,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"GroupDetectors"}; + } /// Algorithm's category for identification const std::string category() const override { return "Transforms\\Grouping"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionCalculateTheta2.h b/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionCalculateTheta2.h index f42949c5a55..b19f0648858 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionCalculateTheta2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionCalculateTheta2.h @@ -43,6 +43,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"SpecularReflectionPositionCorrect"}; + } const std::string category() const override; private: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionPositionCorrect2.h b/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionPositionCorrect2.h index e015c4d451a..850bcd3b154 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionPositionCorrect2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SpecularReflectionPositionCorrect2.h @@ -38,6 +38,9 @@ public: const std::string summary() const override; /// Version int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"SpecularReflectionCalculateTheta"}; + } /// Category const std::string category() const override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SphericalAbsorption.h b/Framework/Algorithms/inc/MantidAlgorithms/SphericalAbsorption.h index 84431eefc0e..273c57b45b3 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SphericalAbsorption.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SphericalAbsorption.h @@ -96,6 +96,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"AbsorptionCorrection"}; + } protected: API::MatrixWorkspace_sptr m_inputWS; ///< A pointer to the input workspace diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h b/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h index 973bd63c7cc..28d040083b0 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Stitch1D.h @@ -43,6 +43,9 @@ public: const std::string summary() const override { return "Stitches single histogram matrix workspaces together"; } + const std::vector<std::string> seeAlso() const override { + return {"Stitch1DMany"}; + } /// Does the x-axis have non-zero errors bool hasNonzeroErrors(Mantid::API::MatrixWorkspace_sptr ws); diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Stitch1DMany.h b/Framework/Algorithms/inc/MantidAlgorithms/Stitch1DMany.h index 47761af10a6..d0008c838cd 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Stitch1DMany.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Stitch1DMany.h @@ -38,6 +38,9 @@ public: const std::string name() const override { return "Stitch1DMany"; } /// Algorithm's version for identification. @see Algorithm::version int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"Stitch1D"}; + } /// Algorithm's category for identification. @see Algorithm::category const std::string category() const override { return "Reflectometry"; } /// Summary of algorithm's purpose diff --git a/Framework/Algorithms/inc/MantidAlgorithms/StripPeaks.h b/Framework/Algorithms/inc/MantidAlgorithms/StripPeaks.h index aea54a092d9..e1239529cc2 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/StripPeaks.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/StripPeaks.h @@ -63,6 +63,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"FindPeaks", "StripVanadiumPeaks"}; + } /// Algorithm's category for identification const std::string category() const override { return "CorrectionFunctions\\PeakCorrections;Optimization\\PeakFinding"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/StripVanadiumPeaks2.h b/Framework/Algorithms/inc/MantidAlgorithms/StripVanadiumPeaks2.h index da5ac35ef60..b180b29dc92 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/StripVanadiumPeaks2.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/StripVanadiumPeaks2.h @@ -39,6 +39,9 @@ public: const std::string name() const override { return "StripVanadiumPeaks"; } /// Algorithm's version for identification overriding a virtual method int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { + return {"FindPeaks", "StripPeaks"}; + } /// Algorithm's category for identification const std::string category() const override { return "CorrectionFunctions\\PeakCorrections;Optimization\\PeakFinding;" diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SumEventsByLogValue.h b/Framework/Algorithms/inc/MantidAlgorithms/SumEventsByLogValue.h index 12d4de12a8e..dc6aeeb2f98 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SumEventsByLogValue.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SumEventsByLogValue.h @@ -43,6 +43,9 @@ public: const std::string name() const override { return "SumEventsByLogValue"; } /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"FilterByLogValue"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Events"; } /// Summary of algorithms purpose diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SumNeighbours.h b/Framework/Algorithms/inc/MantidAlgorithms/SumNeighbours.h index 2f91f202760..c8686555f23 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SumNeighbours.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SumNeighbours.h @@ -55,6 +55,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SumSpectra", "SumRowColumn"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Grouping"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SumOverlappingTubes.h b/Framework/Algorithms/inc/MantidAlgorithms/SumOverlappingTubes.h index 17115c98e2e..c322de85858 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SumOverlappingTubes.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SumOverlappingTubes.h @@ -45,6 +45,9 @@ public: "supported."; } int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"SumSpectra"}; + } private: void init() override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SumRowColumn.h b/Framework/Algorithms/inc/MantidAlgorithms/SumRowColumn.h index b0f4e1c2a2d..a718e872214 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SumRowColumn.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SumRowColumn.h @@ -74,6 +74,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SumSpectra", "SumNeighbours"}; + } /// Algorithm's category for identification const std::string category() const override { return "SANS;Transforms\\Grouping"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SumSpectra.h b/Framework/Algorithms/inc/MantidAlgorithms/SumSpectra.h index 16d6b3cb000..c9cdefd880a 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/SumSpectra.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/SumSpectra.h @@ -65,6 +65,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SumNeighbours"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Grouping"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolution.h b/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolution.h index 101fda8c0b0..1079f291e9f 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolution.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolution.h @@ -46,6 +46,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"TOFSANSResolutionByPixel"}; + } /// Algorithm's category for identification const std::string category() const override { return "SANS"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolutionByPixel.h b/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolutionByPixel.h index f30e41a307e..107c9e7f2d5 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolutionByPixel.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/TOFSANSResolutionByPixel.h @@ -30,6 +30,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"TOFSANSResolution"}; + } /// Algorithm's category for identification const std::string category() const override { return "SANS"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/Transpose.h b/Framework/Algorithms/inc/MantidAlgorithms/Transpose.h index dd5678552f5..5e9c8f42af9 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/Transpose.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/Transpose.h @@ -57,6 +57,10 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"Transpose3D", "TransposeMD", "ConvertUnits", "ConvertSpectrumAxis", + "ConvertAxesToRealSpace"}; + } /// Algorithm's category for identification const std::string category() const override { return "Transforms\\Axes"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/UnGroupWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/UnGroupWorkspace.h index 1dce4cfb171..756753c1535 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/UnGroupWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/UnGroupWorkspace.h @@ -50,6 +50,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"GroupWorkspaces"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Grouping;Utility\\Workspaces"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitor.h b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitor.h index 15645cf6139..83c3747b8de 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitor.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitor.h @@ -61,6 +61,9 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"UnwrapMonitorsInTOF", "UnwrapSNS"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "CorrectionFunctions\\InstrumentCorrections"; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitorsInTOF.h b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitorsInTOF.h index 25382da7a80..b8ccd3b9533 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitorsInTOF.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitorsInTOF.h @@ -38,6 +38,9 @@ class MANTID_ALGORITHMS_DLL UnwrapMonitorsInTOF : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"UnwrapMonitor", "UnwrapSNS"}; + } const std::string category() const override; const std::string summary() const override; std::map<std::string, std::string> validateInputs() override; diff --git a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapSNS.h b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapSNS.h index a2fa09ad8fd..51d55541823 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapSNS.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapSNS.h @@ -60,6 +60,7 @@ public: } int version() const override { return 1; } + const std::string category() const override { return "CorrectionFunctions\\InstrumentCorrections"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/UpdateScriptRepository.h b/Framework/Algorithms/inc/MantidAlgorithms/UpdateScriptRepository.h index 8fe8749094d..d3cc7742666 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/UpdateScriptRepository.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/UpdateScriptRepository.h @@ -43,6 +43,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"DownloadInstrument"}; + } const std::string category() const override; private: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/WeightedMean.h b/Framework/Algorithms/inc/MantidAlgorithms/WeightedMean.h index fdd1a7a39a1..e3872f59bf2 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/WeightedMean.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/WeightedMean.h @@ -51,6 +51,7 @@ public: } int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { return {"Mean"}; } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Arithmetic"; } diff --git a/Framework/Algorithms/inc/MantidAlgorithms/WeightedMeanOfWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/WeightedMeanOfWorkspace.h index e61de16ed74..21cfe3befca 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/WeightedMeanOfWorkspace.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/WeightedMeanOfWorkspace.h @@ -42,6 +42,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"Mean", "WeightedMean"}; + } const std::string category() const override; private: diff --git a/Framework/Algorithms/inc/MantidAlgorithms/WienerSmooth.h b/Framework/Algorithms/inc/MantidAlgorithms/WienerSmooth.h index 6390c452d1e..d37bcde93b5 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/WienerSmooth.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/WienerSmooth.h @@ -37,6 +37,9 @@ class DLLExport WienerSmooth : public API::Algorithm { public: const std::string name() const override { return "WienerSmooth"; } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"FFTSmooth"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Algorithms/src/ConjoinXRuns.cpp b/Framework/Algorithms/src/ConjoinXRuns.cpp index a19028d9bc8..fa9504834ad 100644 --- a/Framework/Algorithms/src/ConjoinXRuns.cpp +++ b/Framework/Algorithms/src/ConjoinXRuns.cpp @@ -254,8 +254,8 @@ void ConjoinXRuns::fillHistory() { if (!isChild()) { // Loop over the input workspaces, making the call that copies their // history to the output one - for (auto inWS = m_inputWS.begin(); inWS != m_inputWS.end(); ++inWS) { - m_outWS->history().addHistory((*inWS)->getHistory()); + for (auto &inWS : m_inputWS) { + m_outWS->history().addHistory(inWS->getHistory()); } // Add the history for the current algorithm to the output m_outWS->history().addHistory(m_history); diff --git a/Framework/Algorithms/src/CreateWorkspace.cpp b/Framework/Algorithms/src/CreateWorkspace.cpp index 768ebe0b209..ca572b5f910 100644 --- a/Framework/Algorithms/src/CreateWorkspace.cpp +++ b/Framework/Algorithms/src/CreateWorkspace.cpp @@ -17,7 +17,6 @@ #include "MantidIndexing/IndexInfo.h" #include "MantidIndexing/SpectrumIndexSet.h" #include "MantidHistogramData/HistogramBuilder.h" -#include "MantidTypes/SpectrumDefinition.h" namespace Mantid { namespace Algorithms { @@ -47,7 +46,7 @@ void CreateWorkspace::init() { declareProperty(Kernel::make_unique<ArrayProperty<double>>("DataY", required), "Y-axis data values for workspace (measures)."); declareProperty(make_unique<ArrayProperty<double>>("DataE"), - "Error values for workspace. Optional."); + "Error values for workspace."); declareProperty(make_unique<PropertyWithValue<int>>("NSpec", 1), "Number of spectra to divide data into."); declareProperty("UnitX", "", "The unit to assign to the XAxis"); @@ -70,6 +69,8 @@ void CreateWorkspace::init() { Direction::Input, PropertyMode::Optional), "Name of a parent workspace."); + declareProperty(Kernel::make_unique<ArrayProperty<double>>("Dx"), + "X error values for workspace (optional)."); std::vector<std::string> propOptions{ Parallel::toString(Parallel::StorageMode::Cloned), Parallel::toString(Parallel::StorageMode::Distributed), @@ -102,6 +103,7 @@ void CreateWorkspace::exec() { const Property *const dataXprop = getProperty("DataX"); const Property *const dataYprop = getProperty("DataY"); const Property *const dataEprop = getProperty("DataE"); + const Property *const errorDxprop = getProperty("Dx"); const ArrayProperty<double> *pCheck = nullptr; @@ -120,6 +122,11 @@ void CreateWorkspace::exec() { throw std::invalid_argument("DataE cannot be casted to a double vector"); const std::vector<double> &dataE = *pCheck; + pCheck = dynamic_cast<const ArrayProperty<double> *>(errorDxprop); + if (!pCheck) + throw std::invalid_argument("Dx cannot be casted to a double vector"); + const std::vector<double> &dX = *pCheck; + const int nSpec = getProperty("NSpec"); const std::string xUnit = getProperty("UnitX"); const std::string vUnit = getProperty("VerticalAxisUnit"); @@ -159,6 +166,13 @@ void CreateWorkspace::exec() { histogramBuilder.setX(xSize); } histogramBuilder.setY(ySize); + + if (!dX.empty()) { + if (dX.size() != dataY.size()) + throw std::runtime_error("Dx must have the same size as DataY"); + histogramBuilder.setDx(ySize); + } + histogramBuilder.setDistribution(getProperty("Distribution")); auto histogram = histogramBuilder.build(); @@ -212,6 +226,10 @@ void CreateWorkspace::exec() { outputWS->mutableE(local_i) .assign(dataE.begin() + yStart, dataE.begin() + yEnd); + if (!dX.empty()) + outputWS->mutableDx(local_i) + .assign(dX.begin() + yStart, dX.begin() + yEnd); + progress.report(); PARALLEL_END_INTERUPT_REGION } diff --git a/Framework/Algorithms/src/DiffractionFocussing.cpp b/Framework/Algorithms/src/DiffractionFocussing.cpp index b4cac6232c9..354ba051a11 100644 --- a/Framework/Algorithms/src/DiffractionFocussing.cpp +++ b/Framework/Algorithms/src/DiffractionFocussing.cpp @@ -83,12 +83,12 @@ void DiffractionFocussing::exec() { if (iprogress_step == 0) iprogress_step = 1; std::vector<int64_t> resultIndeces; - for (auto g = groupNumbers.cbegin(); g != groupNumbers.end(); ++g) { + for (auto groupNumber : groupNumbers) { if (iprogress++ % iprogress_step == 0) { progress(0.68 + double(iprogress) / iprogress_count / 3); } - auto from = detectorGroups.lower_bound(*g); - auto to = detectorGroups.upper_bound(*g); + auto from = detectorGroups.lower_bound(groupNumber); + auto to = detectorGroups.upper_bound(groupNumber); std::vector<detid_t> detectorList; for (auto d = from; d != to; ++d) detectorList.push_back(static_cast<detid_t>(d->second)); diff --git a/Framework/Algorithms/src/MagFormFactorCorrection.cpp b/Framework/Algorithms/src/MagFormFactorCorrection.cpp index ed5942f1207..cacd1d509d9 100644 --- a/Framework/Algorithms/src/MagFormFactorCorrection.cpp +++ b/Framework/Algorithms/src/MagFormFactorCorrection.cpp @@ -84,8 +84,8 @@ void MagFormFactorCorrection::exec() { // Gets the vector of form factor values std::vector<double> FF; FF.reserve(Qvals.size()); - for (int64_t iQ = 0; iQ < (int64_t)Qvals.size(); iQ++) { - FF.push_back(ion.analyticalFormFactor(Qvals[iQ] * Qvals[iQ])); + for (double Qval : Qvals) { + FF.push_back(ion.analyticalFormFactor(Qval * Qval)); } if (!ffwsStr.empty()) { MatrixWorkspace_sptr ffws = API::WorkspaceFactory::Instance().create( diff --git a/Framework/Algorithms/src/MaxEnt.cpp b/Framework/Algorithms/src/MaxEnt.cpp index a87781e0f0b..c6d708b81a3 100644 --- a/Framework/Algorithms/src/MaxEnt.cpp +++ b/Framework/Algorithms/src/MaxEnt.cpp @@ -53,39 +53,35 @@ const double THRESHOLD = 1E-6; /** removes zeros from converged results * @param ws :: [input] The input workspace with zeros -* @param maxIt :: [input] The max number of iteration this alg used +* @param itCount [input] The number of iterations this alg used for each +* spectrum * @param yLabel :: [input] y-label to use for returned ws * @return : ws cut down in lenght to maxIt */ -MatrixWorkspace_sptr removeZeros(const MatrixWorkspace_sptr &ws, - const size_t maxIt, - const ::std::string yLabel) { +MatrixWorkspace_sptr removeZeros(MatrixWorkspace_sptr &ws, + const std::vector<size_t> &itCount, + const std::string &yLabel) { ws->setYUnitLabel(yLabel); - try { - ws->getAxis(0)->unit() = - UnitFactory::Instance().create("Number of Iterations"); - } catch (Exception::NotFoundError &) { - ws->getAxis(0)->unit() = UnitFactory::Instance().create("Label"); - Unit_sptr unit = ws->getAxis(0)->unit(); - boost::shared_ptr<Units::Label> label = - boost::dynamic_pointer_cast<Units::Label>(unit); - label->setLabel("Number of Iterations", ""); - } + ws->getAxis(0)->unit() = UnitFactory::Instance().create("Label"); + Unit_sptr unit = ws->getAxis(0)->unit(); + boost::shared_ptr<Units::Label> label = + boost::dynamic_pointer_cast<Units::Label>(unit); + label->setLabel("Number of Iterations", ""); - if (maxIt == ws->readY(0).size()) { - return ws; - } const size_t nspec = ws->getNumberHistograms(); - MatrixWorkspace_sptr outWS = - WorkspaceFactory::Instance().create(ws, nspec, maxIt, maxIt); + if (itCount.empty()) { + return ws; // In case, we don't have any spectra + } for (size_t spec = 0; spec < nspec; spec++) { - outWS->setPoints(spec, Points(maxIt, LinearGenerator(0.0, 1.0))); - auto Data = ws->readY(spec); - outWS->setCounts(spec, - std::vector<double>(Data.begin(), Data.begin() + maxIt)); + auto &dataX = ws->dataX(spec); + dataX.resize(itCount[spec]); + auto &dataY = ws->dataY(spec); + dataY.resize(itCount[spec]); + auto &dataE = ws->dataE(spec); + dataE.resize(itCount[spec]); } - return outWS; + return ws; } } @@ -274,14 +270,14 @@ void MaxEnt::exec() { // Distance penalty for current image const double distEps = getProperty("DistancePenalty"); // Maximum number of iterations - const size_t niter = getProperty("MaxIterations"); + const size_t nIter = getProperty("MaxIterations"); // Maximum number of iterations in alpha chop const size_t alphaIter = getProperty("AlphaChopIterations"); // Number of spectra and datapoints // Read input workspace MatrixWorkspace_const_sptr inWS = getProperty("InputWorkspace"); // Number of spectra - size_t nspec = inWS->getNumberHistograms(); + size_t nSpec = inWS->getNumberHistograms(); // Number of data points - assumed to be constant between spectra or // this will throw an exception size_t npoints = inWS->blocksize() * resolutionFactor; @@ -290,7 +286,7 @@ void MaxEnt::exec() { // For now have the requirement that data must have non-zero // (and positive!) errors - for (size_t s = 0; s < nspec; s++) { + for (size_t s = 0; s < nSpec; s++) { auto errors = inWS->e(s).rawData(); size_t npoints = errors.size(); @@ -337,22 +333,24 @@ void MaxEnt::exec() { MatrixWorkspace_sptr outEvolChi; MatrixWorkspace_sptr outEvolTest; - nspec = complexData ? nspec / 2 : nspec; + nSpec = complexData ? nSpec / 2 : nSpec; outImageWS = - WorkspaceFactory::Instance().create(inWS, 2 * nspec, npoints, npoints); + WorkspaceFactory::Instance().create(inWS, 2 * nSpec, npoints, npoints); for (size_t i = 0; i < outImageWS->getNumberHistograms(); ++i) outImageWS->getSpectrum(i).setDetectorID(static_cast<detid_t>(i + 1)); outDataWS = - WorkspaceFactory::Instance().create(inWS, 2 * nspec, npointsX, npoints); + WorkspaceFactory::Instance().create(inWS, 2 * nSpec, npointsX, npoints); for (size_t i = 0; i < outDataWS->getNumberHistograms(); ++i) outDataWS->getSpectrum(i).setDetectorID(static_cast<detid_t>(i + 1)); - outEvolChi = WorkspaceFactory::Instance().create(inWS, nspec, niter, niter); - outEvolTest = WorkspaceFactory::Instance().create(inWS, nspec, niter, niter); + outEvolChi = WorkspaceFactory::Instance().create(inWS, nSpec, nIter, nIter); + outEvolTest = WorkspaceFactory::Instance().create(inWS, nSpec, nIter, nIter); npoints = complexImage ? npoints * 2 : npoints; - size_t maxIt = 0; // used to determine max iterations used by alg - outEvolChi->setPoints(0, Points(niter, LinearGenerator(0.0, 1.0))); - for (size_t s = 0; s < nspec; s++) { + std::vector<size_t> iterationCounts; + iterationCounts.reserve(nSpec); + outEvolChi->setPoints(0, Points(nIter, LinearGenerator(0.0, 1.0))); + + for (size_t spec = 0; spec < nSpec; spec++) { // Start distribution (flat background) std::vector<double> image(npoints, background); @@ -360,22 +358,22 @@ void MaxEnt::exec() { std::vector<double> data; std::vector<double> errors; if (complexData) { - data = toComplex(inWS, s, false); // false -> data - errors = toComplex(inWS, s, true); // true -> errors + data = toComplex(inWS, spec, false); // false -> data + errors = toComplex(inWS, spec, true); // true -> errors } else { - data = inWS->y(s).rawData(); - errors = inWS->e(s).rawData(); + data = inWS->y(spec).rawData(); + errors = inWS->e(spec).rawData(); } // To record the algorithm's progress - std::vector<double> evolChi(niter, 0.); - std::vector<double> evolTest(niter, 0.); + std::vector<double> evolChi(nIter, 0.); + std::vector<double> evolTest(nIter, 0.); // Progress - Progress progress(this, 0.0, 1.0, niter); + Progress progress(this, 0.0, 1.0, nIter); // Run maxent algorithm - for (size_t it = 0; it < niter; it++) { + for (size_t it = 0; it < nIter; it++) { // Iterates one step towards the solution. This means calculating // quadratic coefficients, search directions, angle and chi-sq @@ -397,15 +395,15 @@ void MaxEnt::exec() { double currAngle = maxentCalculator.getAngle(); evolChi[it] = currChisq; evolTest[it] = currAngle; - if (it > maxIt) { - maxIt = it; - } + // Stop condition, solution found if ((std::abs(currChisq / ChiTargetOverN - 1.) < chiEps) && (currAngle < angle)) { - g_log.information() << "Stopped after " << it << " iterations" + // it + 1 iterations have been done because we count from zero + g_log.information() << "Stopped after " << it + 1 << " iterations" << std::endl; + iterationCounts.push_back(it + 1); break; } @@ -416,32 +414,32 @@ void MaxEnt::exec() { progress.report(); - } // iterations + } // Next Iteration // Get calculated data auto solData = maxentCalculator.getReconstructedData(); auto solImage = maxentCalculator.getImage(); // Populate the output workspaces - populateDataWS(inWS, s, nspec, solData, complexData, outDataWS); - populateImageWS(inWS, s, nspec, solImage, complexImage, outImageWS, + populateDataWS(inWS, spec, nSpec, solData, complexData, outDataWS); + populateImageWS(inWS, spec, nSpec, solImage, complexImage, outImageWS, autoShift); // Populate workspaces recording the evolution of Chi and Test // X values - outEvolChi->setSharedX(s, outEvolChi->sharedX(0)); - outEvolTest->setSharedX(s, outEvolChi->sharedX(0)); + outEvolChi->setSharedX(spec, outEvolChi->sharedX(0)); + outEvolTest->setSharedX(spec, outEvolChi->sharedX(0)); // Y values - outEvolChi->setCounts(s, std::move(evolChi)); - outEvolTest->setCounts(s, std::move(evolTest)); + outEvolChi->setCounts(spec, std::move(evolChi)); + outEvolTest->setCounts(spec, std::move(evolTest)); // No errors } // Next spectrum - // add 1 to maxIt to account for starting at 0 - maxIt++; - setProperty("EvolChi", removeZeros(outEvolChi, maxIt, "Chi squared")); - setProperty("EvolAngle", removeZeros(outEvolTest, maxIt, "Maximum Angle")); + setProperty("EvolChi", + removeZeros(outEvolChi, iterationCounts, "Chi squared")); + setProperty("EvolAngle", + removeZeros(outEvolTest, iterationCounts, "Maximum Angle")); setProperty("ReconstructedImage", outImageWS); setProperty("ReconstructedData", outDataWS); } diff --git a/Framework/Algorithms/src/RingProfile.cpp b/Framework/Algorithms/src/RingProfile.cpp index b54b772a09f..8ffb30a6e90 100644 --- a/Framework/Algorithms/src/RingProfile.cpp +++ b/Framework/Algorithms/src/RingProfile.cpp @@ -418,8 +418,8 @@ void RingProfile::processInstrumentRingProfile( const MantidVec &refY = inputWS->getSpectrum(i).dataY(); // accumulate the values of this spectrum inside this bin - for (size_t sp_ind = 0; sp_ind < refY.size(); sp_ind++) - output_bins[bin_n] += refY[sp_ind]; + for (double sp_ind : refY) + output_bins[bin_n] += sp_ind; } } diff --git a/Framework/Algorithms/src/SampleCorrections/SparseInstrument.cpp b/Framework/Algorithms/src/SampleCorrections/SparseInstrument.cpp index 281a0c31ce8..6c2580cd1e8 100644 --- a/Framework/Algorithms/src/SampleCorrections/SparseInstrument.cpp +++ b/Framework/Algorithms/src/SampleCorrections/SparseInstrument.cpp @@ -286,8 +286,8 @@ createSparseWS(const API::MatrixWorkspace &modelWS, } const auto e = modelWS.getEFixed(detIDs[0]); const auto &sparseDetIDs = ws->detectorInfo().detectorIDs(); - for (size_t i = 0; i < sparseDetIDs.size(); ++i) { - ws->setEFixed(sparseDetIDs[i], e); + for (int sparseDetID : sparseDetIDs) { + ws->setEFixed(sparseDetID, e); } } return API::MatrixWorkspace_uptr(ws.release()); diff --git a/Framework/Algorithms/test/ChangeTimeZeroTest.h b/Framework/Algorithms/test/ChangeTimeZeroTest.h index 88520874edf..c0dd81f2f1d 100644 --- a/Framework/Algorithms/test/ChangeTimeZeroTest.h +++ b/Framework/Algorithms/test/ChangeTimeZeroTest.h @@ -487,11 +487,11 @@ private: auto logs = ws->run().getLogData(); // Go over each log and check the times - for (auto iter = logs.begin(); iter != logs.end(); ++iter) { - if (dynamic_cast<Mantid::Kernel::ITimeSeriesProperty *>(*iter)) { - do_check_time_series(*iter, timeShift); - } else if (dynamic_cast<PropertyWithValue<std::string> *>(*iter)) { - do_check_property_with_string_value(*iter, timeShift); + for (auto &log : logs) { + if (dynamic_cast<Mantid::Kernel::ITimeSeriesProperty *>(log)) { + do_check_time_series(log, timeShift); + } else if (dynamic_cast<PropertyWithValue<std::string> *>(log)) { + do_check_property_with_string_value(log, timeShift); } } @@ -509,8 +509,8 @@ private: // Iterator over all entries of the time series and check if they are // altered double secondCounter = timeShift; - for (auto it = times.begin(); it != times.end(); ++it) { - double secs = DateAndTime::secondsFromDuration(*it - m_startTime); + for (auto &time : times) { + double secs = DateAndTime::secondsFromDuration(time - m_startTime); TSM_ASSERT_DELTA("Time series logs should have shifted times.", secs, secondCounter, 1e-5); ++secondCounter; diff --git a/Framework/Algorithms/test/CreateWorkspaceTest.h b/Framework/Algorithms/test/CreateWorkspaceTest.h index 86bdb52c454..823ba7ba664 100644 --- a/Framework/Algorithms/test/CreateWorkspaceTest.h +++ b/Framework/Algorithms/test/CreateWorkspaceTest.h @@ -23,6 +23,7 @@ void run_create(const Parallel::Communicator &comm, alg->setProperty<std::vector<double>>("DataX", dataEYX); alg->setProperty<std::vector<double>>("DataY", dataEYX); alg->setProperty<std::vector<double>>("DataE", dataEYX); + alg->setProperty<std::vector<double>>("Dx", dataEYX); alg->setProperty("ParallelStorageMode", storageMode); alg->execute(); MatrixWorkspace_const_sptr ws = alg->getProperty("OutputWorkspace"); @@ -73,6 +74,8 @@ public: alg.setProperty<std::vector<double>>("DataY", dataEYX)); TS_ASSERT_THROWS_NOTHING( alg.setProperty<std::vector<double>>("DataE", dataEYX)); + TS_ASSERT_THROWS_NOTHING( + alg.setProperty<std::vector<double>>("Dx", dataEYX)); TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("UnitX", "Wavelength")); TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("VerticalAxisUnit", "MomentumTransfer")); @@ -95,17 +98,14 @@ public: // No parent workspace -> no instrument -> no detectors -> no mapping. TS_ASSERT_EQUALS(ws->getSpectrum(0).getDetectorIDs().size(), 0); - TS_ASSERT_EQUALS(ws->x(0)[0], 0); - TS_ASSERT_EQUALS(ws->x(0)[1], 1.234); - TS_ASSERT_EQUALS(ws->x(0)[2], 2.468); - TS_ASSERT_EQUALS(ws->y(0)[0], 0); - TS_ASSERT_EQUALS(ws->y(0)[1], 1.234); - TS_ASSERT_EQUALS(ws->y(0)[2], 2.468); - TS_ASSERT_EQUALS(ws->e(0)[0], 0); - TS_ASSERT_EQUALS(ws->e(0)[1], 1.234); - TS_ASSERT_EQUALS(ws->e(0)[2], 2.468); + for (size_t i = 0; i < dataEYX.size(); ++i) { + TS_ASSERT_EQUALS(ws->x(0)[i], dataEYX[i]); + } + for (size_t i = 0; i < dataEYX.size(); ++i) { + TS_ASSERT_EQUALS(ws->y(0)[i], dataEYX[i]); + TS_ASSERT_EQUALS(ws->e(0)[i], dataEYX[i]); + } TS_ASSERT_EQUALS(ws->getAxis(0)->unit()->caption(), "Wavelength"); - TS_ASSERT_EQUALS(ws->getAxis(1)->unit()->unitID(), "MomentumTransfer"); TS_ASSERT_EQUALS(ws->getAxis(1)->unit()->caption(), "q"); @@ -122,6 +122,54 @@ public: "test_CreateWorkspace")); } + void testCreateBinEdges() { + Mantid::Algorithms::CreateWorkspace createBinEdges; + TS_ASSERT_THROWS_NOTHING(createBinEdges.initialize()); + + std::vector<double> dataX{5.5, 6.8, 9.1, 12.3}; + std::vector<double> dataEYDx{0.0, 1.234, 2.468}; + + TS_ASSERT_THROWS_NOTHING(createBinEdges.setProperty<int>("NSpec", 1)); + TS_ASSERT_THROWS_NOTHING( + createBinEdges.setProperty<std::vector<double>>("DataX", dataX)); + TS_ASSERT_THROWS_NOTHING( + createBinEdges.setProperty<std::vector<double>>("DataY", dataEYDx)); + TS_ASSERT_THROWS_NOTHING( + createBinEdges.setProperty<std::vector<double>>("DataE", dataEYDx)); + TS_ASSERT_THROWS_NOTHING( + createBinEdges.setProperty<std::vector<double>>("Dx", dataEYDx)); + TS_ASSERT_THROWS_NOTHING(createBinEdges.setPropertyValue( + "OutputWorkspace", "test_CreateWorkspace")); + TS_ASSERT_THROWS_NOTHING(createBinEdges.execute()); + + TS_ASSERT(createBinEdges.isExecuted()); + Mantid::API::MatrixWorkspace_const_sptr ws; + + TS_ASSERT_THROWS_NOTHING( + ws = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>( + Mantid::API::AnalysisDataService::Instance().retrieve( + "test_CreateWorkspace"))); + + TS_ASSERT(ws->isHistogramData()); + TS_ASSERT_EQUALS(ws->getNumberHistograms(), 1); + // No parent workspace -> no instrument -> no detectors -> no mapping. + TS_ASSERT_EQUALS(ws->getSpectrum(0).getDetectorIDs().size(), 0); + + for (size_t i = 0; i < dataX.size(); ++i) { + TS_ASSERT_EQUALS(ws->x(0)[i], dataX[i]); + } + for (size_t i = 0; i < dataEYDx.size(); ++i) { + TS_ASSERT_EQUALS(ws->y(0)[i], dataEYDx[i]); + TS_ASSERT_EQUALS(ws->e(0)[i], dataEYDx[i]); + TS_ASSERT_EQUALS(ws->dx(0)[i], dataEYDx[i]); + } + + // Remove the created workspace + TS_ASSERT_THROWS_NOTHING( + Mantid::API::AnalysisDataService::Instance().remove( + "test_CreateWorkspace")); + } + void testCreateTextAxis() { std::vector<std::string> textAxis{"I've Got", "A Lovely", "Bunch Of", "Coconuts"}; @@ -157,11 +205,12 @@ public: alg.setProperty<int>("NSpec", 4); std::vector<double> values{1.0, 2.0, 3.0, 4.0}; + std::vector<double> xVals{1.1, 2.2}; - alg.setProperty<std::vector<double>>("DataX", - std::vector<double>{1.1, 2.2}); + alg.setProperty<std::vector<double>>("DataX", xVals); alg.setProperty<std::vector<double>>("DataY", values); alg.setProperty<std::vector<double>>("DataE", values); + alg.setProperty<std::vector<double>>("Dx", xVals); TS_ASSERT_THROWS(alg.execute(), std::invalid_argument); } @@ -302,6 +351,7 @@ public: creator.setProperty("DataX", *vec); creator.setProperty("DataY", *vec); creator.setProperty("DataE", *vec); + creator.setProperty("Dx", *vec); creator.setProperty("NSpec", 10000); TS_ASSERT(creator.execute()); } diff --git a/Framework/Algorithms/test/DetectorEfficiencyVariationTest.h b/Framework/Algorithms/test/DetectorEfficiencyVariationTest.h index f91e385f02b..cfeac3a09db 100644 --- a/Framework/Algorithms/test/DetectorEfficiencyVariationTest.h +++ b/Framework/Algorithms/test/DetectorEfficiencyVariationTest.h @@ -130,8 +130,8 @@ public: inputB->setBinEdges(j, x); std::vector<double> forInputA, forInputB; // the spectravalues will be multiples of the random numbers above - for (int l = 0; l < ySize; ++l) { - forInputA.push_back(yArray[l]); + for (double y : yArray) { + forInputA.push_back(y); // there is going to be a small difference between the workspaces that // will vary with histogram number forInputB.push_back(forInputA.back() * diff --git a/Framework/Algorithms/test/FilterEventsTest.h b/Framework/Algorithms/test/FilterEventsTest.h index 7cbc4ae3ecc..10c83e09c25 100644 --- a/Framework/Algorithms/test/FilterEventsTest.h +++ b/Framework/Algorithms/test/FilterEventsTest.h @@ -254,8 +254,8 @@ public: AnalysisDataService::Instance().remove("Splitter02"); std::vector<std::string> outputwsnames = filter.getProperty("OutputWorkspaceNames"); - for (size_t i = 0; i < outputwsnames.size(); ++i) { - AnalysisDataService::Instance().remove(outputwsnames[i]); + for (const auto &outputwsname : outputwsnames) { + AnalysisDataService::Instance().remove(outputwsname); } return; @@ -350,9 +350,9 @@ public: AnalysisDataService::Instance().remove("Splitter02"); std::vector<std::string> outputwsnames = filter.getProperty("OutputWorkspaceNames"); - for (size_t i = 0; i < outputwsnames.size(); ++i) { - std::cout << "Delete output workspace name: " << outputwsnames[i] << "\n"; - AnalysisDataService::Instance().remove(outputwsnames[i]); + for (const auto &outputwsname : outputwsnames) { + std::cout << "Delete output workspace name: " << outputwsname << "\n"; + AnalysisDataService::Instance().remove(outputwsname); } return; @@ -435,8 +435,8 @@ public: std::vector<std::string> outputwsnames = filter.getProperty("OutputWorkspaceNames"); - for (size_t i = 0; i < outputwsnames.size(); ++i) { - AnalysisDataService::Instance().remove(outputwsnames[i]); + for (const auto &outputwsname : outputwsnames) { + AnalysisDataService::Instance().remove(outputwsname); } return; @@ -493,8 +493,8 @@ public: // Delete all the workspaces generated here AnalysisDataService::Instance().remove("MockDirectEventWS"); AnalysisDataService::Instance().remove("SplitterTableX"); - for (size_t i = 0; i < vecwsname.size(); ++i) { - AnalysisDataService::Instance().remove(vecwsname[i]); + for (const auto &workspaceName : vecwsname) { + AnalysisDataService::Instance().remove(workspaceName); } return; @@ -544,8 +544,8 @@ public: AnalysisDataService::Instance().remove("SplitterTableX"); std::vector<std::string> outputwsnames = filter.getProperty("OutputWorkspaceNames"); - for (size_t i = 0; i < outputwsnames.size(); ++i) { - AnalysisDataService::Instance().remove(outputwsnames[i]); + for (const auto &outputwsname : outputwsnames) { + AnalysisDataService::Instance().remove(outputwsname); } return; @@ -608,8 +608,8 @@ public: AnalysisDataService::Instance().remove("MockIndirectEventWS"); std::vector<std::string> outputwsnames = filter.getProperty("OutputWorkspaceNames"); - for (size_t i = 0; i < outputwsnames.size(); ++i) { - AnalysisDataService::Instance().remove(outputwsnames[i]); + for (const auto &outputwsname : outputwsnames) { + AnalysisDataService::Instance().remove(outputwsname); } return; @@ -781,10 +781,10 @@ public: // Test the sample logs std::vector<std::string> outputwsnames = filter.getProperty("OutputWorkspaceNames"); - for (size_t i = 0; i < outputwsnames.size(); ++i) { + for (const auto &outputwsname : outputwsnames) { EventWorkspace_sptr filtered_ws = boost::dynamic_pointer_cast<DataObjects::EventWorkspace>( - AnalysisDataService::Instance().retrieve(outputwsnames[i])); + AnalysisDataService::Instance().retrieve(outputwsname)); TS_ASSERT(filtered_ws->run().hasProperty("LogA")); TS_ASSERT(filtered_ws->run().hasProperty("LogB")); @@ -805,8 +805,8 @@ public: // clean up all the workspaces generated AnalysisDataService::Instance().remove("Test10"); AnalysisDataService::Instance().remove("Splitter10"); - for (size_t i = 0; i < outputwsnames.size(); ++i) { - AnalysisDataService::Instance().remove(outputwsnames[i]); + for (const auto &outputwsname : outputwsnames) { + AnalysisDataService::Instance().remove(outputwsname); } return; @@ -977,8 +977,8 @@ public: AnalysisDataService::Instance().remove("TableSplitter1"); std::vector<std::string> outputwsnames = filter.getProperty("OutputWorkspaceNames"); - for (size_t i = 0; i < outputwsnames.size(); ++i) { - AnalysisDataService::Instance().remove(outputwsnames[i]); + for (const auto &outputwsname : outputwsnames) { + AnalysisDataService::Instance().remove(outputwsname); } return; @@ -1033,10 +1033,10 @@ public: std::vector<std::string> outputwsnames = filter.getProperty("OutputWorkspaceNames"); - for (size_t i = 0; i < outputwsnames.size(); ++i) { + for (const auto &outputwsname : outputwsnames) { EventWorkspace_sptr childworkspace = boost::dynamic_pointer_cast<EventWorkspace>( - AnalysisDataService::Instance().retrieve(outputwsnames[i])); + AnalysisDataService::Instance().retrieve(outputwsname)); TS_ASSERT(childworkspace); // there is 1 sample logs that is excluded from propagating to the child // workspaces. LogB is not TSP, so it won't be excluded even if it is @@ -1051,8 +1051,8 @@ public: // clean workspaces AnalysisDataService::Instance().remove("Test12"); AnalysisDataService::Instance().remove("TableSplitter2"); - for (size_t i = 0; i < outputwsnames.size(); ++i) { - AnalysisDataService::Instance().remove(outputwsnames[i]); + for (const auto &outputwsname : outputwsnames) { + AnalysisDataService::Instance().remove(outputwsname); } return; @@ -1587,8 +1587,7 @@ public: // 2. Add rows const auto &detectorInfo = inpws->detectorInfo(); const auto detids = detectorInfo.detectorIDs(); - for (size_t i = 0; i < detids.size(); ++i) { - int detid = detids[i]; + for (int detid : detids) { double factor = 0.75; TableRow newrow = corrtable->appendRow(); newrow << detid << factor; diff --git a/Framework/Algorithms/test/GroupWorkspacesTest.h b/Framework/Algorithms/test/GroupWorkspacesTest.h index 0b9fa7e31c0..bc183339d67 100644 --- a/Framework/Algorithms/test/GroupWorkspacesTest.h +++ b/Framework/Algorithms/test/GroupWorkspacesTest.h @@ -196,8 +196,8 @@ public: private: void addTestMatrixWorkspacesToADS(const std::vector<std::string> &inputs) { - for (auto it = inputs.begin(); it != inputs.end(); ++it) { - addTestMatrixWorkspaceToADS(*it); + for (const auto &input : inputs) { + addTestMatrixWorkspaceToADS(input); } } @@ -258,9 +258,9 @@ private: const std::vector<std::string> &members) { auto &ads = Mantid::API::AnalysisDataService::Instance(); - for (auto it = members.begin(); it != members.end(); ++it) { - if (ads.doesExist(*it)) - ads.remove(*it); + for (const auto &member : members) { + if (ads.doesExist(member)) + ads.remove(member); } if (ads.doesExist(groupName)) ads.remove(groupName); diff --git a/Framework/Algorithms/test/MaskBinsFromTableTest.h b/Framework/Algorithms/test/MaskBinsFromTableTest.h index 4bf775b5486..210d8061e63 100644 --- a/Framework/Algorithms/test/MaskBinsFromTableTest.h +++ b/Framework/Algorithms/test/MaskBinsFromTableTest.h @@ -183,8 +183,8 @@ public: speclist.push_back(6); speclist.push_back(7); speclist.push_back(8); - for (size_t iws = 0; iws < speclist.size(); ++iws) { - auto &yvec = WS->y(speclist[iws]); + for (int spectrum : speclist) { + auto &yvec = WS->y(spectrum); for (size_t bin = 0; bin < yvec.size(); ++bin) { if (bin >= 4 && bin < 7) { TS_ASSERT_EQUALS(yvec[bin], 0.0); diff --git a/Framework/Algorithms/test/MedianDetectorTestTest.h b/Framework/Algorithms/test/MedianDetectorTestTest.h index cfccc53ddd1..81be253a63a 100644 --- a/Framework/Algorithms/test/MedianDetectorTestTest.h +++ b/Framework/Algorithms/test/MedianDetectorTestTest.h @@ -180,8 +180,8 @@ public: 1, 0, 15, 4, 0, 0.001, 2e-10, 0, 8, 0, 1e-4, 1, 7, 11}; m_YSum = 0; - for (int i = 0; i < specLength - 1; i++) { - m_YSum += yArray[i]; + for (double i : yArray) { + m_YSum += i; } // most error values will be small so that they wont affect the tests diff --git a/Framework/Algorithms/test/PDDetermineCharacterizationsTest.h b/Framework/Algorithms/test/PDDetermineCharacterizationsTest.h index 95d3c084391..4da29ea57d1 100644 --- a/Framework/Algorithms/test/PDDetermineCharacterizationsTest.h +++ b/Framework/Algorithms/test/PDDetermineCharacterizationsTest.h @@ -213,8 +213,8 @@ public: const std::vector<Property *> &expectedProps = expected->getProperties(); - for (std::size_t i = 0; i < expectedProps.size(); ++i) { - const std::string name = expectedProps[i]->name(); + for (auto expectedProp : expectedProps) { + const std::string name = expectedProp->name(); TS_ASSERT_EQUALS(expected->getPropertyValue(name), observed->getPropertyValue(name)); } diff --git a/Framework/Algorithms/test/RebinByTimeAtSampleTest.h b/Framework/Algorithms/test/RebinByTimeAtSampleTest.h index aaf90573ec8..481148a9648 100644 --- a/Framework/Algorithms/test/RebinByTimeAtSampleTest.h +++ b/Framework/Algorithms/test/RebinByTimeAtSampleTest.h @@ -31,8 +31,7 @@ createSinglePulseEventWorkspace(const V3D &sourcePosition, // Make fake events for (size_t pix = 0; pix < numberspectra; pix++) { - for (size_t i = 0; i < allSpectraTOF.size(); i++) { - const double tof = allSpectraTOF[i]; + for (double tof : allSpectraTOF) { uint64_t pulseTime(0); // Pulse time is always zero. Same pulse. retVal->getSpectrum(pix) += TofEvent(tof, pulseTime); } diff --git a/Framework/Algorithms/test/RebinTest.h b/Framework/Algorithms/test/RebinTest.h index 00ea719f481..17cb8232c61 100644 --- a/Framework/Algorithms/test/RebinTest.h +++ b/Framework/Algorithms/test/RebinTest.h @@ -424,9 +424,8 @@ public: // turn the mask list into an array like the Y values MantidVec weights(outY.size(), 0); - for (MatrixWorkspace::MaskList::const_iterator it = mask.begin(); - it != mask.end(); ++it) { - weights[it->first] = it->second; + for (auto it : mask) { + weights[it.first] = it.second; } // the degree of masking must be the same as the reduction in the y-value, @@ -484,9 +483,8 @@ public: // turn the mask list into an array like the Y values MantidVec weights(outY.size(), 0); - for (MatrixWorkspace::MaskList::const_iterator it = mask.begin(); - it != mask.end(); ++it) { - weights[it->first] = it->second; + for (auto it : mask) { + weights[it.first] = it.second; } // the degree of masking must be the same as the reduction in the y-value, diff --git a/Framework/Algorithms/test/RemoveBackgroundTest.h b/Framework/Algorithms/test/RemoveBackgroundTest.h index c01c9209a07..8139f055e6f 100644 --- a/Framework/Algorithms/test/RemoveBackgroundTest.h +++ b/Framework/Algorithms/test/RemoveBackgroundTest.h @@ -195,8 +195,8 @@ public: auto clone = cloneSourceWS(); // set negative values to signal auto &Y = clone->dataY(0); - for (size_t i = 0; i < Y.size(); i++) { - Y[i] = -1000; + for (double &i : Y) { + i = -1000; } // Create zero background workspace // Create the workspace diff --git a/Framework/Algorithms/test/SassenaFFTTest.h b/Framework/Algorithms/test/SassenaFFTTest.h index 4c15d0aa2fc..a5736da3014 100644 --- a/Framework/Algorithms/test/SassenaFFTTest.h +++ b/Framework/Algorithms/test/SassenaFFTTest.h @@ -144,10 +144,10 @@ private: double sum = 0.0; double average = 0.0; MantidVec::iterator itx = xv.begin(); - for (MantidVec::iterator it = yv.begin(); it != yv.end(); ++it) { + for (double &y : yv) { factor = exp(exponentFactor * (*itx)); - sum += (*it) * factor; - average += (*it) * (*itx) * factor; + sum += y * factor; + average += y * (*itx) * factor; ++itx; } average /= sum; @@ -186,9 +186,9 @@ private: xv = ws->readX(i); MantidVec::iterator itx = xv.begin(); double sum = 0.0; - for (MantidVec::iterator it = yv.begin(); it != yv.end(); ++it) { + for (double &y : yv) { factor = exp(exponentFactor * (*itx)); - sum += (*it) * factor; + sum += y * factor; ++itx; } sum *= dx / static_cast<double>(nbins); diff --git a/Framework/Algorithms/test/SofQWCutTest.h b/Framework/Algorithms/test/SofQWCutTest.h index ea13b747661..60f86cc05a0 100644 --- a/Framework/Algorithms/test/SofQWCutTest.h +++ b/Framework/Algorithms/test/SofQWCutTest.h @@ -12,6 +12,7 @@ #include "MantidAPI/WorkspaceGroup.h" #include "MantidKernel/Unit.h" #include "MantidDataHandling/LoadNexusProcessed.h" +#include "MantidDataHandling/CreateSimulationWorkspace.h" #include <boost/make_shared.hpp> @@ -221,6 +222,47 @@ public: TS_ASSERT_DELTA(ws_e->readY(0)[119], 0.045373095, delta); TS_ASSERT_DELTA(ws_e->readE(0)[119], 0.005462714, delta); } + + void test_sofqw3_zerobinwidth() { + // This test sets up a workspace which can yield a bin with zero width + // to check the code FractionalRebinning code handles this correctly + const double delta(1e-08); + Mantid::DataHandling::CreateSimulationWorkspace create_ws; + create_ws.initialize(); + create_ws.setChild(true); + create_ws.setPropertyValue("Instrument", "MARI"); + create_ws.setPropertyValue("BinParams", "-5,0.5,24"); + create_ws.setPropertyValue("OutputWorkspace", "__unused"); + create_ws.execute(); + + MatrixWorkspace_sptr createdWS = create_ws.getProperty("OutputWorkspace"); + auto inWS = boost::dynamic_pointer_cast<MatrixWorkspace>(createdWS); + // Sets one spectrum to zero so final value is not unity. + inWS->setCounts(300, std::vector<double>(58, 0.)); + + Mantid::Algorithms::SofQWNormalisedPolygon sqw; + sqw.initialize(); + sqw.setChild(true); + TS_ASSERT_THROWS_NOTHING(sqw.setProperty("InputWorkspace", inWS)); + TS_ASSERT_THROWS_NOTHING( + sqw.setPropertyValue("OutputWorkspace", "__unused")); + TS_ASSERT_THROWS_NOTHING(sqw.setPropertyValue("QAxisBinning", "0,10,10")); + TS_ASSERT_THROWS_NOTHING(sqw.setPropertyValue("EMode", "Direct")); + TS_ASSERT_THROWS_NOTHING(sqw.setPropertyValue("EFixed", "25")); + TS_ASSERT_THROWS_NOTHING( + sqw.setPropertyValue("EAxisBinning", "-1.5,3,1.5")); + TS_ASSERT_THROWS_NOTHING(sqw.execute()); + TS_ASSERT(sqw.isExecuted()); + + MatrixWorkspace_sptr ws = sqw.getProperty("OutputWorkspace"); + TS_ASSERT_EQUALS(ws->getAxis(0)->length(), 2); + TS_ASSERT_EQUALS(ws->getAxis(0)->unit()->unitID(), "DeltaE"); + TS_ASSERT_EQUALS((*(ws->getAxis(0)))(0), -1.5); + TS_ASSERT_EQUALS((*(ws->getAxis(0)))(1), 1.5); + TS_ASSERT_EQUALS(ws->getAxis(1)->length(), 2); + TS_ASSERT_EQUALS(ws->getAxis(1)->unit()->unitID(), "MomentumTransfer"); + TS_ASSERT_DELTA(ws->readY(0)[0], 0.998910675, delta); + } }; #endif /*SOFQWCUTTEST_H_*/ diff --git a/Framework/Algorithms/test/Stitch1DTest.h b/Framework/Algorithms/test/Stitch1DTest.h index 1e787942a34..fab1d86938b 100644 --- a/Framework/Algorithms/test/Stitch1DTest.h +++ b/Framework/Algorithms/test/Stitch1DTest.h @@ -384,8 +384,7 @@ public: } // Check that the output E-Values are correct. Output Error values should // all be zero - for (auto itr = stitched_e.begin(); itr != stitched_e.end(); ++itr) { - double temp = *itr; + for (double temp : stitched_e) { TS_ASSERT_EQUALS(temp, 0); } // Check that the output X-Values are correct. @@ -416,8 +415,7 @@ public: } // Check that the output E-Values are correct. Output Error values should // all be zero - for (auto itr = stitched_e.begin(); itr != stitched_e.end(); ++itr) { - double temp = *itr; + for (double temp : stitched_e) { TS_ASSERT_EQUALS(temp, 0); } // Check that the output X-Values are correct. @@ -449,8 +447,7 @@ public: } // Check that the output E-Values are correct. Output Error values should // all be zero - for (auto itr = stitched_e.begin(); itr != stitched_e.end(); ++itr) { - double temp = *itr; + for (double temp : stitched_e) { TS_ASSERT_EQUALS(temp, 0); } // Check that the output X-Values are correct. @@ -482,8 +479,7 @@ public: } // Check that the output E-Values are correct. Output Error values should // all be zero - for (auto itr = stitched_e.begin(); itr != stitched_e.end(); ++itr) { - double temp = *itr; + for (double temp : stitched_e) { TS_ASSERT_EQUALS(temp, 0); } // Check that the output X-Values are correct. diff --git a/Framework/Algorithms/test/UnGroupWorkspaceTest.h b/Framework/Algorithms/test/UnGroupWorkspaceTest.h index 70a5ea9404c..62e6379b4d4 100644 --- a/Framework/Algorithms/test/UnGroupWorkspaceTest.h +++ b/Framework/Algorithms/test/UnGroupWorkspaceTest.h @@ -102,8 +102,8 @@ private: auto newGroup = boost::make_shared<Mantid::API::WorkspaceGroup>(); auto &ads = Mantid::API::AnalysisDataService::Instance(); - for (auto it = inputs.begin(); it != inputs.end(); ++it) { - auto ws = addTestMatrixWorkspaceToADS(*it); + for (const auto &input : inputs) { + auto ws = addTestMatrixWorkspaceToADS(input); newGroup->addWorkspace(ws); } ads.add(name, newGroup); @@ -120,9 +120,9 @@ private: void removeFromADS(const std::vector<std::string> &members) { auto &ads = Mantid::API::AnalysisDataService::Instance(); - for (auto it = members.begin(); it != members.end(); ++it) { - if (ads.doesExist(*it)) - ads.remove(*it); + for (const auto &member : members) { + if (ads.doesExist(member)) + ads.remove(member); } } }; diff --git a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h index 331b52f1fc0..a8883732d2d 100644 --- a/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h +++ b/Framework/Beamline/inc/MantidBeamline/ComponentInfo.h @@ -116,6 +116,7 @@ public: std::vector<size_t> componentsInSubtree(const size_t componentIndex) const; const std::vector<size_t> &children(const size_t componentIndex) const; size_t size() const; + size_t numberOfDetectorsInSubtree(const size_t componentIndex) const; bool isDetector(const size_t componentIndex) const { return componentIndex < m_assemblySortedDetectorIndices->size(); } diff --git a/Framework/Beamline/src/ComponentInfo.cpp b/Framework/Beamline/src/ComponentInfo.cpp index ffe12a64a97..6baef33046e 100644 --- a/Framework/Beamline/src/ComponentInfo.cpp +++ b/Framework/Beamline/src/ComponentInfo.cpp @@ -167,6 +167,12 @@ ComponentInfo::children(const size_t componentIndex) const { size_t ComponentInfo::size() const { return m_size; } +size_t +ComponentInfo::numberOfDetectorsInSubtree(const size_t componentIndex) const { + auto range = detectorRangeInSubtree(componentIndex); + return std::distance(range.begin(), range.end()); +} + Eigen::Vector3d ComponentInfo::position(const size_t componentIndex) const { checkNoTimeDependence(); if (isDetector(componentIndex)) { diff --git a/Framework/Crystal/inc/MantidCrystal/AddPeakHKL.h b/Framework/Crystal/inc/MantidCrystal/AddPeakHKL.h index 49e3de7345d..4eaf865ad8c 100644 --- a/Framework/Crystal/inc/MantidCrystal/AddPeakHKL.h +++ b/Framework/Crystal/inc/MantidCrystal/AddPeakHKL.h @@ -34,6 +34,9 @@ class DLLExport AddPeakHKL : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"AddPeak"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Crystal/inc/MantidCrystal/AnvredCorrection.h b/Framework/Crystal/inc/MantidCrystal/AnvredCorrection.h index b207795b4ef..684e31e4aee 100644 --- a/Framework/Crystal/inc/MantidCrystal/AnvredCorrection.h +++ b/Framework/Crystal/inc/MantidCrystal/AnvredCorrection.h @@ -87,6 +87,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LorentzCorrection"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Crystal\\Corrections;CorrectionFunctions\\AbsorptionCorrections"; diff --git a/Framework/Crystal/inc/MantidCrystal/CalculatePeaksHKL.h b/Framework/Crystal/inc/MantidCrystal/CalculatePeaksHKL.h index b66b64d5f46..41136356c25 100644 --- a/Framework/Crystal/inc/MantidCrystal/CalculatePeaksHKL.h +++ b/Framework/Crystal/inc/MantidCrystal/CalculatePeaksHKL.h @@ -42,6 +42,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"AddPeak"}; + } const std::string category() const override; private: diff --git a/Framework/Crystal/inc/MantidCrystal/CalculateUMatrix.h b/Framework/Crystal/inc/MantidCrystal/CalculateUMatrix.h index be18c24679b..a95255657f9 100644 --- a/Framework/Crystal/inc/MantidCrystal/CalculateUMatrix.h +++ b/Framework/Crystal/inc/MantidCrystal/CalculateUMatrix.h @@ -46,6 +46,7 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { return {"SetUB"}; } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\UBMatrix"; } diff --git a/Framework/Crystal/inc/MantidCrystal/CentroidPeaks.h b/Framework/Crystal/inc/MantidCrystal/CentroidPeaks.h index f5e0c4fdfaa..73fc4567201 100644 --- a/Framework/Crystal/inc/MantidCrystal/CentroidPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/CentroidPeaks.h @@ -27,6 +27,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"CentroidPeaksMD", "PeakIntegration"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\Peaks"; } diff --git a/Framework/Crystal/inc/MantidCrystal/ClearUB.h b/Framework/Crystal/inc/MantidCrystal/ClearUB.h index 9785a49ec21..04c6c405e88 100644 --- a/Framework/Crystal/inc/MantidCrystal/ClearUB.h +++ b/Framework/Crystal/inc/MantidCrystal/ClearUB.h @@ -45,6 +45,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"SetUB", "HasUB"}; + } const std::string category() const override; protected: diff --git a/Framework/Crystal/inc/MantidCrystal/CombinePeaksWorkspaces.h b/Framework/Crystal/inc/MantidCrystal/CombinePeaksWorkspaces.h index b72fb786fda..150268c2eff 100644 --- a/Framework/Crystal/inc/MantidCrystal/CombinePeaksWorkspaces.h +++ b/Framework/Crystal/inc/MantidCrystal/CombinePeaksWorkspaces.h @@ -43,6 +43,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CreatePeaksWorkspace"}; + } const std::string category() const override; private: diff --git a/Framework/Crystal/inc/MantidCrystal/CountReflections.h b/Framework/Crystal/inc/MantidCrystal/CountReflections.h index bf1a72a7f0a..b06c2af7705 100644 --- a/Framework/Crystal/inc/MantidCrystal/CountReflections.h +++ b/Framework/Crystal/inc/MantidCrystal/CountReflections.h @@ -41,6 +41,9 @@ class DLLExport CountReflections : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"PredictPeaks", "SortHKL"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/Crystal/inc/MantidCrystal/DiffPeaksWorkspaces.h b/Framework/Crystal/inc/MantidCrystal/DiffPeaksWorkspaces.h index ac57e4c18d4..f725a968f44 100644 --- a/Framework/Crystal/inc/MantidCrystal/DiffPeaksWorkspaces.h +++ b/Framework/Crystal/inc/MantidCrystal/DiffPeaksWorkspaces.h @@ -41,6 +41,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CreatePeaksWorkspace", "CombinePeaksWorkspaces"}; + } const std::string category() const override; private: diff --git a/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h b/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h index ca4816edd60..579d3225477 100644 --- a/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/FilterPeaks.h @@ -42,6 +42,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CreatePeaksWorkspace"}; + } const std::string category() const override; private: diff --git a/Framework/Crystal/inc/MantidCrystal/FindClusterFaces.h b/Framework/Crystal/inc/MantidCrystal/FindClusterFaces.h index 6951b5625dc..5431772a914 100644 --- a/Framework/Crystal/inc/MantidCrystal/FindClusterFaces.h +++ b/Framework/Crystal/inc/MantidCrystal/FindClusterFaces.h @@ -40,6 +40,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"IntegratePeaksUsingClusters"}; + } const std::string category() const override; private: diff --git a/Framework/Crystal/inc/MantidCrystal/FindSXPeaks.h b/Framework/Crystal/inc/MantidCrystal/FindSXPeaks.h index f3f4a60123a..6c9e8db9866 100644 --- a/Framework/Crystal/inc/MantidCrystal/FindSXPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/FindSXPeaks.h @@ -64,6 +64,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"IndexSXPeaks"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Crystal\\Peaks;Optimization\\PeakFinding"; diff --git a/Framework/Crystal/inc/MantidCrystal/FindUBUsingFFT.h b/Framework/Crystal/inc/MantidCrystal/FindUBUsingFFT.h index 91351b5cbcf..1850af09c14 100644 --- a/Framework/Crystal/inc/MantidCrystal/FindUBUsingFFT.h +++ b/Framework/Crystal/inc/MantidCrystal/FindUBUsingFFT.h @@ -40,6 +40,10 @@ public: /// Algorithm's version for identification int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"SetUB", "FindUBUsingIndexedPeaks", "FindUBUsingLatticeParameters", + "FindUBUsingMinMaxD"}; + } /// Algorithm's category for identification const std::string category() const override; diff --git a/Framework/Crystal/inc/MantidCrystal/FindUBUsingIndexedPeaks.h b/Framework/Crystal/inc/MantidCrystal/FindUBUsingIndexedPeaks.h index a50d04231a8..4d7456eefd8 100644 --- a/Framework/Crystal/inc/MantidCrystal/FindUBUsingIndexedPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/FindUBUsingIndexedPeaks.h @@ -41,6 +41,10 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SetUB", "FindUBUsingFFT", "FindUBUsingLatticeParameters", + "FindUBUsingMinMaxD"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\UBMatrix"; } diff --git a/Framework/Crystal/inc/MantidCrystal/FindUBUsingLatticeParameters.h b/Framework/Crystal/inc/MantidCrystal/FindUBUsingLatticeParameters.h index dc8eebab330..1cb69eba444 100644 --- a/Framework/Crystal/inc/MantidCrystal/FindUBUsingLatticeParameters.h +++ b/Framework/Crystal/inc/MantidCrystal/FindUBUsingLatticeParameters.h @@ -43,6 +43,10 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SetUB", "FindUBUsingFFT", "FindUBUsingIndexedPeaks", + "FindUBUsingMinMaxD"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\UBMatrix"; } diff --git a/Framework/Crystal/inc/MantidCrystal/FindUBUsingMinMaxD.h b/Framework/Crystal/inc/MantidCrystal/FindUBUsingMinMaxD.h index 49ae0c54355..d62b5093268 100644 --- a/Framework/Crystal/inc/MantidCrystal/FindUBUsingMinMaxD.h +++ b/Framework/Crystal/inc/MantidCrystal/FindUBUsingMinMaxD.h @@ -45,6 +45,10 @@ public: /// Algorithm's version for identification int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"SetUB", "FindUBUsingFFT", "FindUBUsingIndexedPeaks", + "FindUBUsingLatticeParameters"}; + } /// Algorithm's category for identification const std::string category() const override; diff --git a/Framework/Crystal/inc/MantidCrystal/GoniometerAnglesFromPhiRotation.h b/Framework/Crystal/inc/MantidCrystal/GoniometerAnglesFromPhiRotation.h index a15567c4e64..5365e482828 100644 --- a/Framework/Crystal/inc/MantidCrystal/GoniometerAnglesFromPhiRotation.h +++ b/Framework/Crystal/inc/MantidCrystal/GoniometerAnglesFromPhiRotation.h @@ -56,6 +56,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"SetGoniometer"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\Goniometer"; } diff --git a/Framework/Crystal/inc/MantidCrystal/HasUB.h b/Framework/Crystal/inc/MantidCrystal/HasUB.h index 0b4ae3cb02b..4937aebd190 100644 --- a/Framework/Crystal/inc/MantidCrystal/HasUB.h +++ b/Framework/Crystal/inc/MantidCrystal/HasUB.h @@ -42,6 +42,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"SetUB", "ClearUB"}; + } const std::string category() const override; private: diff --git a/Framework/Crystal/inc/MantidCrystal/IndexPeaks.h b/Framework/Crystal/inc/MantidCrystal/IndexPeaks.h index b205ac8cbfe..792114abb63 100644 --- a/Framework/Crystal/inc/MantidCrystal/IndexPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/IndexPeaks.h @@ -45,6 +45,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"IndexSXPeaks"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\Peaks"; } diff --git a/Framework/Crystal/inc/MantidCrystal/IndexSXPeaks.h b/Framework/Crystal/inc/MantidCrystal/IndexSXPeaks.h index bb7a92f68c9..df864e4f7a2 100644 --- a/Framework/Crystal/inc/MantidCrystal/IndexSXPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/IndexSXPeaks.h @@ -163,6 +163,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"IndexPeaks"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Crystal\\Peaks"; } diff --git a/Framework/Crystal/inc/MantidCrystal/IntegratePeakTimeSlices.h b/Framework/Crystal/inc/MantidCrystal/IntegratePeakTimeSlices.h index 837aeff6fe7..da247e5f06c 100644 --- a/Framework/Crystal/inc/MantidCrystal/IntegratePeakTimeSlices.h +++ b/Framework/Crystal/inc/MantidCrystal/IntegratePeakTimeSlices.h @@ -245,6 +245,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"PeakIntegration"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Crystal\\Integration"; } diff --git a/Framework/Crystal/inc/MantidCrystal/IntegratePeaksHybrid.h b/Framework/Crystal/inc/MantidCrystal/IntegratePeaksHybrid.h index cfce138cd8a..0330ce088f6 100644 --- a/Framework/Crystal/inc/MantidCrystal/IntegratePeaksHybrid.h +++ b/Framework/Crystal/inc/MantidCrystal/IntegratePeaksHybrid.h @@ -34,6 +34,10 @@ class DLLExport IntegratePeaksHybrid : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"IntegratePeaksUsingClusters", "IntegratePeaksMDHKL", + "IntegratePeaksMD", "IntegratePeaksCWSD"}; + } const std::string category() const override; private: diff --git a/Framework/Crystal/inc/MantidCrystal/IntegratePeaksUsingClusters.h b/Framework/Crystal/inc/MantidCrystal/IntegratePeaksUsingClusters.h index 1b6615135f2..85bdca7257a 100644 --- a/Framework/Crystal/inc/MantidCrystal/IntegratePeaksUsingClusters.h +++ b/Framework/Crystal/inc/MantidCrystal/IntegratePeaksUsingClusters.h @@ -40,6 +40,10 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"IntegratePeaksHybrid", "IntegratePeaksMDHKL", "IntegratePeaksMD", + "IntegratePeaksCWSD"}; + } const std::string category() const override; private: diff --git a/Framework/Crystal/inc/MantidCrystal/LoadHKL.h b/Framework/Crystal/inc/MantidCrystal/LoadHKL.h index 92842034004..80582648ed9 100644 --- a/Framework/Crystal/inc/MantidCrystal/LoadHKL.h +++ b/Framework/Crystal/inc/MantidCrystal/LoadHKL.h @@ -27,6 +27,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SaveHKL"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\DataHandling;DataHandling\\Text"; diff --git a/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h b/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h index 7352a0a069f..3292dc08c38 100644 --- a/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h @@ -29,6 +29,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"SaveIsawPeaks"}; + } /// Algorithm's category for identification const std::string category() const override { diff --git a/Framework/Crystal/inc/MantidCrystal/LoadIsawSpectrum.h b/Framework/Crystal/inc/MantidCrystal/LoadIsawSpectrum.h index 09c220e8fc7..5e6289b756e 100644 --- a/Framework/Crystal/inc/MantidCrystal/LoadIsawSpectrum.h +++ b/Framework/Crystal/inc/MantidCrystal/LoadIsawSpectrum.h @@ -43,6 +43,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SaveIsawPeaks", "SaveIsawUB"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\DataHandling;DataHandling\\Text"; diff --git a/Framework/Crystal/inc/MantidCrystal/LoadIsawUB.h b/Framework/Crystal/inc/MantidCrystal/LoadIsawUB.h index 6b0835fca4c..00c86fc298c 100644 --- a/Framework/Crystal/inc/MantidCrystal/LoadIsawUB.h +++ b/Framework/Crystal/inc/MantidCrystal/LoadIsawUB.h @@ -26,6 +26,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SaveIsawUB"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\DataHandling;DataHandling\\Isaw"; diff --git a/Framework/Crystal/inc/MantidCrystal/MaskPeaksWorkspace.h b/Framework/Crystal/inc/MantidCrystal/MaskPeaksWorkspace.h index 018fb73a50b..afe832b53da 100644 --- a/Framework/Crystal/inc/MantidCrystal/MaskPeaksWorkspace.h +++ b/Framework/Crystal/inc/MantidCrystal/MaskPeaksWorkspace.h @@ -45,6 +45,9 @@ public: const std::string name() const override { return "MaskPeaksWorkspace"; } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CreatePeaksWorkspace"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Crystal\\Peaks"; } diff --git a/Framework/Crystal/inc/MantidCrystal/OptimizeLatticeForCellType.h b/Framework/Crystal/inc/MantidCrystal/OptimizeLatticeForCellType.h index 5f11c2f9dc6..6a96a5e364c 100644 --- a/Framework/Crystal/inc/MantidCrystal/OptimizeLatticeForCellType.h +++ b/Framework/Crystal/inc/MantidCrystal/OptimizeLatticeForCellType.h @@ -55,6 +55,10 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"FindUBUsingFFT", "FindUBUsingIndexedPeaks", + "FindUBUsingLatticeParameters"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Crystal\\Cell"; } diff --git a/Framework/Crystal/inc/MantidCrystal/PeakIntegration.h b/Framework/Crystal/inc/MantidCrystal/PeakIntegration.h index 548d9238aa0..5801c136b27 100644 --- a/Framework/Crystal/inc/MantidCrystal/PeakIntegration.h +++ b/Framework/Crystal/inc/MantidCrystal/PeakIntegration.h @@ -43,6 +43,9 @@ public: const std::string name() const override { return "PeakIntegration"; } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"IntegratePeakTimeSlices", "CentroidPeaks"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Crystal\\Integration"; } /// Summary of algorithms purpose diff --git a/Framework/Crystal/inc/MantidCrystal/PeakIntensityVsRadius.h b/Framework/Crystal/inc/MantidCrystal/PeakIntensityVsRadius.h index 22526c5a707..5991e2db6c6 100644 --- a/Framework/Crystal/inc/MantidCrystal/PeakIntensityVsRadius.h +++ b/Framework/Crystal/inc/MantidCrystal/PeakIntensityVsRadius.h @@ -41,6 +41,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"PeakIntegration"}; + } const std::string category() const override; private: diff --git a/Framework/Crystal/inc/MantidCrystal/PeakStatisticsTools.h b/Framework/Crystal/inc/MantidCrystal/PeakStatisticsTools.h index 29e46581d4c..f3c42620042 100644 --- a/Framework/Crystal/inc/MantidCrystal/PeakStatisticsTools.h +++ b/Framework/Crystal/inc/MantidCrystal/PeakStatisticsTools.h @@ -34,10 +34,12 @@ public: const std::vector<DataObjects::Peak> &getPeaks() const { return m_peaks; } size_t count() const { return m_peaks.size(); } + std::vector<double> getWavelengths() const; std::vector<double> getIntensities() const; std::vector<double> getSigmas() const; - UniqueReflection removeOutliers(double sigmaCritical = 3.0) const; + UniqueReflection removeOutliers(double sigmaCritical = 3.0, + bool weightedZ = false) const; void setPeaksIntensityAndSigma(double intensity, double sigma); private: @@ -109,7 +111,21 @@ public: m_redundancy(0.0), m_rMerge(0.0), m_rPim(0.0), m_meanIOverSigma(0.0), m_dspacingMin(0.0), m_dspacingMax(0.0), m_chiSquared(0.0), m_peaks() { m_peaks.reserve(reflections.getObservedReflectionCount()); - calculatePeaksStatistics(reflections.getReflections()); + std::string equivalentIntensities = "Mean"; + double sigmaCritical = 3.0; + bool weightedZ = false; + calculatePeaksStatistics(reflections.getReflections(), + equivalentIntensities, sigmaCritical, weightedZ); + } + explicit PeaksStatistics(const UniqueReflectionCollection &reflections, + std::string &equivalentIntensities, + double &sigmaCritical, bool &weightedZ) + : m_measuredReflections(0), m_uniqueReflections(0), m_completeness(0.0), + m_redundancy(0.0), m_rMerge(0.0), m_rPim(0.0), m_meanIOverSigma(0.0), + m_dspacingMin(0.0), m_dspacingMax(0.0), m_chiSquared(0.0), m_peaks() { + m_peaks.reserve(reflections.getObservedReflectionCount()); + calculatePeaksStatistics(reflections.getReflections(), + equivalentIntensities, sigmaCritical, weightedZ); } /// Total number of observed reflections - no symmetry is taken into @@ -152,7 +168,9 @@ public: private: void calculatePeaksStatistics( - const std::map<Kernel::V3D, UniqueReflection> &uniqueReflections); + const std::map<Kernel::V3D, UniqueReflection> &uniqueReflections, + std::string &equivalentIntensities, double &sigmaCritical, + bool &weightedZ); double getIOverSigmaSum(const std::vector<double> &sigmas, const std::vector<double> &intensities) const; diff --git a/Framework/Crystal/inc/MantidCrystal/PeaksInRegion.h b/Framework/Crystal/inc/MantidCrystal/PeaksInRegion.h index 7d703d788f6..59bc599256f 100644 --- a/Framework/Crystal/inc/MantidCrystal/PeaksInRegion.h +++ b/Framework/Crystal/inc/MantidCrystal/PeaksInRegion.h @@ -39,6 +39,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"PeaksOnSurface"}; + } const std::string category() const override; private: diff --git a/Framework/Crystal/inc/MantidCrystal/PeaksOnSurface.h b/Framework/Crystal/inc/MantidCrystal/PeaksOnSurface.h index ecd75678eff..a156efcb55d 100644 --- a/Framework/Crystal/inc/MantidCrystal/PeaksOnSurface.h +++ b/Framework/Crystal/inc/MantidCrystal/PeaksOnSurface.h @@ -41,6 +41,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"PeaksInRegion"}; + } const std::string category() const override; private: diff --git a/Framework/Crystal/inc/MantidCrystal/PredictFractionalPeaks.h b/Framework/Crystal/inc/MantidCrystal/PredictFractionalPeaks.h index 3a2c319f1a4..03142b14714 100644 --- a/Framework/Crystal/inc/MantidCrystal/PredictFractionalPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/PredictFractionalPeaks.h @@ -47,6 +47,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"PredictPeaks"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\Peaks"; } diff --git a/Framework/Crystal/inc/MantidCrystal/PredictPeaks.h b/Framework/Crystal/inc/MantidCrystal/PredictPeaks.h index 922a6ad9ab7..a4a61759f7d 100644 --- a/Framework/Crystal/inc/MantidCrystal/PredictPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/PredictPeaks.h @@ -39,6 +39,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"CountReflections", "PredictFractionalPeaks"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\Peaks"; } @@ -64,7 +67,8 @@ private: void calculateQAndAddToOutput(const Kernel::V3D &hkl, const Kernel::DblMatrix &orientedUB, - const Kernel::DblMatrix &goniometerMatrix); + const Kernel::DblMatrix &goniometerMatrix, + int &seqNum); private: /// Get the predicted detector direction from Q diff --git a/Framework/Crystal/inc/MantidCrystal/SCDCalibratePanels.h b/Framework/Crystal/inc/MantidCrystal/SCDCalibratePanels.h index b95ca3f7276..541fa748f8e 100644 --- a/Framework/Crystal/inc/MantidCrystal/SCDCalibratePanels.h +++ b/Framework/Crystal/inc/MantidCrystal/SCDCalibratePanels.h @@ -54,6 +54,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CalculateUMatrix"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override; diff --git a/Framework/Crystal/inc/MantidCrystal/SaveHKL.h b/Framework/Crystal/inc/MantidCrystal/SaveHKL.h index 392e2d0484d..f258a559c17 100644 --- a/Framework/Crystal/inc/MantidCrystal/SaveHKL.h +++ b/Framework/Crystal/inc/MantidCrystal/SaveHKL.h @@ -25,6 +25,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadHKL"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\DataHandling;DataHandling\\Text"; diff --git a/Framework/Crystal/inc/MantidCrystal/SaveIsawPeaks.h b/Framework/Crystal/inc/MantidCrystal/SaveIsawPeaks.h index df8d19a4f3f..094005a25e2 100644 --- a/Framework/Crystal/inc/MantidCrystal/SaveIsawPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/SaveIsawPeaks.h @@ -30,6 +30,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadIsawPeaks"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\DataHandling;DataHandling\\Isaw"; diff --git a/Framework/Crystal/inc/MantidCrystal/SaveIsawUB.h b/Framework/Crystal/inc/MantidCrystal/SaveIsawUB.h index f80f316859d..a1beabf73d0 100644 --- a/Framework/Crystal/inc/MantidCrystal/SaveIsawUB.h +++ b/Framework/Crystal/inc/MantidCrystal/SaveIsawUB.h @@ -49,6 +49,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadIsawUB"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\DataHandling;DataHandling\\Isaw"; diff --git a/Framework/Crystal/inc/MantidCrystal/SelectCellOfType.h b/Framework/Crystal/inc/MantidCrystal/SelectCellOfType.h index fbe9134f074..1e448ee097b 100644 --- a/Framework/Crystal/inc/MantidCrystal/SelectCellOfType.h +++ b/Framework/Crystal/inc/MantidCrystal/SelectCellOfType.h @@ -43,6 +43,10 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"FindUBUsingFFT", "FindUBUsingIndexedPeaks", + "FindUBUsingLatticeParameters"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\Cell"; } diff --git a/Framework/Crystal/inc/MantidCrystal/SelectCellWithForm.h b/Framework/Crystal/inc/MantidCrystal/SelectCellWithForm.h index a6b4a6f01d6..2254043d5c4 100644 --- a/Framework/Crystal/inc/MantidCrystal/SelectCellWithForm.h +++ b/Framework/Crystal/inc/MantidCrystal/SelectCellWithForm.h @@ -44,6 +44,10 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"FindUBUsingFFT", "FindUBUsingIndexedPeaks", + "FindUBUsingLatticeParameters"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\Cell"; } diff --git a/Framework/Crystal/inc/MantidCrystal/SetGoniometer.h b/Framework/Crystal/inc/MantidCrystal/SetGoniometer.h index 817b2e7af43..c48931dc6b8 100644 --- a/Framework/Crystal/inc/MantidCrystal/SetGoniometer.h +++ b/Framework/Crystal/inc/MantidCrystal/SetGoniometer.h @@ -25,6 +25,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"GoniometerAnglesFromPhiRotation"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\Goniometer"; } diff --git a/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h b/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h index 6104fcc75d2..5a271da941c 100644 --- a/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h +++ b/Framework/Crystal/inc/MantidCrystal/SetSpecialCoordinates.h @@ -48,6 +48,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ConvertToMD", "ConvertToDiffractionMDWorkspace"}; + } const std::string category() const override; private: diff --git a/Framework/Crystal/inc/MantidCrystal/SetUB.h b/Framework/Crystal/inc/MantidCrystal/SetUB.h index 481137668a9..6c105fe4681 100644 --- a/Framework/Crystal/inc/MantidCrystal/SetUB.h +++ b/Framework/Crystal/inc/MantidCrystal/SetUB.h @@ -46,6 +46,10 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"FindUBUsingFFT", "FindUBUsingIndexedPeaks", + "FindUBUsingLatticeParameters", "FindUBUsingMinMaxD"}; + } const std::string category() const override; private: diff --git a/Framework/Crystal/inc/MantidCrystal/ShowPeakHKLOffsets.h b/Framework/Crystal/inc/MantidCrystal/ShowPeakHKLOffsets.h index 1787aa59cfc..368de1c811c 100644 --- a/Framework/Crystal/inc/MantidCrystal/ShowPeakHKLOffsets.h +++ b/Framework/Crystal/inc/MantidCrystal/ShowPeakHKLOffsets.h @@ -53,6 +53,9 @@ public: } int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"StatisticsOfPeaksWorkspace"}; + } const std::string category() const override { return "Crystal\\Peaks"; }; diff --git a/Framework/Crystal/inc/MantidCrystal/ShowPossibleCells.h b/Framework/Crystal/inc/MantidCrystal/ShowPossibleCells.h index d890f6cac20..977cbaa4e2c 100644 --- a/Framework/Crystal/inc/MantidCrystal/ShowPossibleCells.h +++ b/Framework/Crystal/inc/MantidCrystal/ShowPossibleCells.h @@ -43,6 +43,10 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"FindUBUsingFFT", "FindUBUsingIndexedPeaks", + "FindUBUsingLatticeParameters"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\Cell"; } diff --git a/Framework/Crystal/inc/MantidCrystal/SortHKL.h b/Framework/Crystal/inc/MantidCrystal/SortHKL.h index 44a384ad92f..ba95a470fd5 100644 --- a/Framework/Crystal/inc/MantidCrystal/SortHKL.h +++ b/Framework/Crystal/inc/MantidCrystal/SortHKL.h @@ -41,6 +41,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"TransformHKL"}; + } /// Algorithm's category for identification const std::string category() const override { return R"(Crystal\Peaks;DataHandling\Text;Utility\Sorting)"; diff --git a/Framework/Crystal/inc/MantidCrystal/SortPeaksWorkspace.h b/Framework/Crystal/inc/MantidCrystal/SortPeaksWorkspace.h index 27f8e9d5f13..78034d31092 100644 --- a/Framework/Crystal/inc/MantidCrystal/SortPeaksWorkspace.h +++ b/Framework/Crystal/inc/MantidCrystal/SortPeaksWorkspace.h @@ -41,6 +41,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CreatePeaksWorkspace"}; + } const std::string category() const override; private: diff --git a/Framework/Crystal/inc/MantidCrystal/StatisticsOfPeaksWorkspace.h b/Framework/Crystal/inc/MantidCrystal/StatisticsOfPeaksWorkspace.h index dae2543c1f6..baa26ff1549 100644 --- a/Framework/Crystal/inc/MantidCrystal/StatisticsOfPeaksWorkspace.h +++ b/Framework/Crystal/inc/MantidCrystal/StatisticsOfPeaksWorkspace.h @@ -28,6 +28,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"ShowPeakHKLOffsets"}; + } /// Algorithm's category for identification const std::string category() const override { return "Crystal\\Peaks;DataHandling\\Text"; diff --git a/Framework/Crystal/inc/MantidCrystal/TransformHKL.h b/Framework/Crystal/inc/MantidCrystal/TransformHKL.h index 5b8dd122cff..2c174d2fe1f 100644 --- a/Framework/Crystal/inc/MantidCrystal/TransformHKL.h +++ b/Framework/Crystal/inc/MantidCrystal/TransformHKL.h @@ -41,6 +41,9 @@ public: /// Algorithm's version for identification int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"SortHKL"}; + } /// Algorithm's category for identification const std::string category() const override; diff --git a/Framework/Crystal/src/ConnectedComponentLabeling.cpp b/Framework/Crystal/src/ConnectedComponentLabeling.cpp index 327fb52ffb0..e4117ccdf03 100644 --- a/Framework/Crystal/src/ConnectedComponentLabeling.cpp +++ b/Framework/Crystal/src/ConnectedComponentLabeling.cpp @@ -288,9 +288,7 @@ ClusterMap ConnectedComponentLabeling::calculateDisjointTree( const int nThreadsToUse = getNThreads(); if (nThreadsToUse > 1) { - std::vector<API::IMDIterator *> iterators = - ws->createIterators(nThreadsToUse); - + auto iterators = ws->createIterators(nThreadsToUse); const size_t maxClustersPossible = calculateMaxClusters(ws.get(), nThreadsToUse); @@ -303,7 +301,7 @@ ClusterMap ConnectedComponentLabeling::calculateDisjointTree( g_log.debug("Parallel solve local CCL"); // PARALLEL_FOR_NO_WSP_CHECK() for (int i = 0; i < nThreadsToUse; ++i) { - API::IMDIterator *iterator = iterators[i]; + API::IMDIterator *iterator = iterators[i].get(); boost::scoped_ptr<BackgroundStrategy> strategy( baseStrategy->clone()); // local strategy VecEdgeIndexPair &edgeVec = parallelEdgeVec[i]; // local edge indexes @@ -364,12 +362,12 @@ ClusterMap ConnectedComponentLabeling::calculateDisjointTree( clusterMap = clusterRegister.clusters(neighbourElements); } else { - API::IMDIterator *iterator = ws->createIterator(nullptr); + auto iterator = ws->createIterator(nullptr); VecEdgeIndexPair edgeIndexPair; // This should never get filled in a single // threaded situation. size_t endLabelId = doConnectedComponentLabeling( - iterator, baseStrategy, neighbourElements, progress, maxNeighbours, - m_startId, edgeIndexPair); + iterator.get(), baseStrategy, neighbourElements, progress, + maxNeighbours, m_startId, edgeIndexPair); // Create clusters from labels. for (size_t labelId = m_startId; labelId != endLabelId; ++labelId) { @@ -383,7 +381,7 @@ ClusterMap ConnectedComponentLabeling::calculateDisjointTree( iterator->jumpTo(0); // Reset do { const size_t currentIndex = iterator->getLinearIndex(); - if (!baseStrategy->isBackground(iterator)) { + if (!baseStrategy->isBackground(iterator.get())) { const int labelAtIndex = neighbourElements[currentIndex].getRoot(); clusterMap[labelAtIndex]->addIndex(currentIndex); } diff --git a/Framework/Crystal/src/FindClusterFaces.cpp b/Framework/Crystal/src/FindClusterFaces.cpp index c5bad728f4d..0cfe98c93e9 100644 --- a/Framework/Crystal/src/FindClusterFaces.cpp +++ b/Framework/Crystal/src/FindClusterFaces.cpp @@ -331,7 +331,7 @@ void FindClusterFaces::exec() { for (int it = 0; it < nIterators; ++it) { PARALLEL_START_INTERUPT_REGION ClusterFaces &localClusterFaces = clusterFaces[it]; - auto mdIterator = mdIterators[it]; + auto mdIterator = mdIterators[it].get(); if (usingFiltering) { executeFiltered(mdIterator, localClusterFaces, progress, clusterImage, diff --git a/Framework/Crystal/src/LoadHKL.cpp b/Framework/Crystal/src/LoadHKL.cpp index a629fc87948..666562eac9a 100644 --- a/Framework/Crystal/src/LoadHKL.cpp +++ b/Framework/Crystal/src/LoadHKL.cpp @@ -85,16 +85,19 @@ void LoadHKL::exec() { double wl = std::stod(line.substr(32, 8)); double tbar, trans, scattering; int run, bank; + int seqNum; if (cosines) { tbar = std::stod(line.substr(40, 8)); // tbar run = std::stoi(line.substr(102, 6)); trans = std::stod(line.substr(114, 7)); // transmission + seqNum = std::stoi(line.substr(109, 7)); bank = std::stoi(line.substr(121, 4)); scattering = std::stod(line.substr(125, 9)); } else { tbar = std::stod(line.substr(40, 7)); // tbar run = std::stoi(line.substr(47, 7)); trans = std::stod(line.substr(61, 7)); // transmission + seqNum = std::stoi(line.substr(54, 7)); bank = std::stoi(line.substr(68, 4)); scattering = std::stod(line.substr(72, 9)); } @@ -115,6 +118,7 @@ void LoadHKL::exec() { peak.setIntensity(Inti); peak.setSigmaIntensity(SigI); peak.setRunNumber(run); + peak.setPeakNumber(seqNum); std::ostringstream oss; oss << "bank" << bank; std::string bankName = oss.str(); diff --git a/Framework/Crystal/src/LoadIsawPeaks.cpp b/Framework/Crystal/src/LoadIsawPeaks.cpp index 194e3125fea..db2f3a2998b 100644 --- a/Framework/Crystal/src/LoadIsawPeaks.cpp +++ b/Framework/Crystal/src/LoadIsawPeaks.cpp @@ -213,8 +213,8 @@ std::string LoadIsawPeaks::readHeader(PeaksWorkspace_sptr outWS, boost::erase_all(bankName, bankPart); int bank = 0; Strings::convert(bankName, bank); - for (size_t j = 0; j < det.size(); j++) { - if (bank == det[j]) { + for (int j : det) { + if (bank == j) { bank = 0; continue; } @@ -268,8 +268,6 @@ DataObjects::Peak LoadIsawPeaks::readPeak(PeaksWorkspace_sptr outWS, double Inti; double SigI; - seqNum = -1; - std::string s = lastStr; if (s.length() < 1 && in.good()) // blank line @@ -334,6 +332,7 @@ DataObjects::Peak LoadIsawPeaks::readPeak(PeaksWorkspace_sptr outWS, peak.setIntensity(Inti); peak.setSigmaIntensity(SigI); peak.setBinCount(IPK); + peak.setPeakNumber(seqNum); // Return the peak return peak; } @@ -488,7 +487,7 @@ void LoadIsawPeaks::appendFile(PeaksWorkspace_sptr outWS, oss << bankString << bankNum; std::string bankName = oss.str(); - int seqNum = -1; + int seqNum; try { // Read the peak diff --git a/Framework/Crystal/src/PeakStatisticsTools.cpp b/Framework/Crystal/src/PeakStatisticsTools.cpp index bf1d288c6a2..be199079e7e 100644 --- a/Framework/Crystal/src/PeakStatisticsTools.cpp +++ b/Framework/Crystal/src/PeakStatisticsTools.cpp @@ -16,6 +16,19 @@ using namespace Mantid::DataObjects; using namespace Mantid::Geometry; using namespace Mantid::Kernel; +/// Returns a vector with the wavelengths of the Peaks stored in this +/// reflection. +std::vector<double> UniqueReflection::getWavelengths() const { + std::vector<double> wavelengths; + wavelengths.reserve(m_peaks.size()); + + std::transform( + m_peaks.begin(), m_peaks.end(), std::back_inserter(wavelengths), + [](const DataObjects::Peak &peak) { return peak.getWavelength(); }); + + return wavelengths; +} + /// Returns a vector with the intensities of the Peaks stored in this /// reflection. std::vector<double> UniqueReflection::getIntensities() const { @@ -44,7 +57,8 @@ std::vector<double> UniqueReflection::getSigmas() const { /// Removes peaks whose intensity deviates more than sigmaCritical from the /// intensities' mean. -UniqueReflection UniqueReflection::removeOutliers(double sigmaCritical) const { +UniqueReflection UniqueReflection::removeOutliers(double sigmaCritical, + bool weightedZ) const { if (sigmaCritical <= 0.0) { throw std::invalid_argument( "Critical sigma value has to be greater than 0."); @@ -54,7 +68,13 @@ UniqueReflection UniqueReflection::removeOutliers(double sigmaCritical) const { if (m_peaks.size() > 2) { auto intensities = getIntensities(); - auto zScores = Kernel::getZscore(intensities); + std::vector<double> zScores; + if (!weightedZ) { + zScores = Kernel::getZscore(intensities); + } else { + auto sigmas = getSigmas(); + zScores = Kernel::getWeightedZscore(intensities, sigmas); + } for (size_t i = 0; i < zScores.size(); ++i) { if (zScores[i] <= sigmaCritical) { @@ -196,9 +216,15 @@ UniqueReflectionCollection::getReflections() const { * group of equivalent reflections. * * @param uniqueReflections :: Map of unique reflections and peaks. + * @param equivalentIntensities :: Mean or median for statistics of equivalent + *peaks. + * @param sigmaCritical :: Number of standard deviations for outliers. + * @param weightedZ :: True for weighted Zscore */ void PeaksStatistics::calculatePeaksStatistics( - const std::map<V3D, UniqueReflection> &uniqueReflections) { + const std::map<V3D, UniqueReflection> &uniqueReflections, + std::string &equivalentIntensities, double &sigmaCritical, + bool &weightedZ) { double rMergeNumerator = 0.0; double rPimNumerator = 0.0; double intensitySumRValues = 0.0; @@ -212,7 +238,8 @@ void PeaksStatistics::calculatePeaksStatistics( ++m_uniqueReflections; // Possibly remove outliers. - auto outliersRemoved = unique.second.removeOutliers(); + auto outliersRemoved = + unique.second.removeOutliers(sigmaCritical, weightedZ); // I/sigma is calculated for all reflections, even if there is only one // observation. @@ -225,9 +252,12 @@ void PeaksStatistics::calculatePeaksStatistics( if (outliersRemoved.count() > 1) { // Get mean, standard deviation for intensities auto intensityStatistics = Kernel::getStatistics( - intensities, StatOptions::Mean | StatOptions::UncorrectedStdDev); + intensities, StatOptions::Mean | StatOptions::UncorrectedStdDev | + StatOptions::Median); double meanIntensity = intensityStatistics.mean; + if (equivalentIntensities == "Median") + meanIntensity = intensityStatistics.median; /* This was in the original algorithm, not entirely sure where it is * used. It's basically the sum of all relative standard deviations. diff --git a/Framework/Crystal/src/PredictPeaks.cpp b/Framework/Crystal/src/PredictPeaks.cpp index 5dec60e24ce..26a76731256 100644 --- a/Framework/Crystal/src/PredictPeaks.cpp +++ b/Framework/Crystal/src/PredictPeaks.cpp @@ -274,6 +274,7 @@ void PredictPeaks::exec() { HKLFilterWavelength lambdaFilter(orientedUB, lambdaMin, lambdaMax); size_t allowedPeakCount = 0; + int seqNum = 1; bool useExtendedDetectorSpace = getProperty("PredictPeaksOutsideDetectors"); if (useExtendedDetectorSpace && @@ -284,8 +285,9 @@ void PredictPeaks::exec() { for (auto &possibleHKL : possibleHKLs) { if (lambdaFilter.isAllowed(possibleHKL)) { + calculateQAndAddToOutput(possibleHKL, orientedUB, goniometerMatrix, + seqNum); ++allowedPeakCount; - calculateQAndAddToOutput(possibleHKL, orientedUB, goniometerMatrix); } prog.report(); } @@ -471,10 +473,12 @@ void PredictPeaks::setStructureFactorCalculatorFromSample( * @param hkl * @param orientedUB * @param goniometerMatrix + * @param seqNum */ void PredictPeaks::calculateQAndAddToOutput(const V3D &hkl, const DblMatrix &orientedUB, - const DblMatrix &goniometerMatrix) { + const DblMatrix &goniometerMatrix, + int &seqNum) { // The q-vector direction of the peak is = goniometer * ub * hkl_vector // This is in inelastic convention: momentum transfer of the LATTICE! // Also, q does have a 2pi factor = it is equal to 2pi/wavelength. @@ -535,6 +539,8 @@ void PredictPeaks::calculateQAndAddToOutput(const V3D &hkl, // Save the run number found before. peak->setRunNumber(m_runNumber); peak->setHKL(hkl * m_qConventionFactor); + peak->setPeakNumber(seqNum); + seqNum++; if (m_sfCalculator) { peak->setIntensity(m_sfCalculator->getFSquared(hkl)); diff --git a/Framework/Crystal/src/SCDCalibratePanels.cpp b/Framework/Crystal/src/SCDCalibratePanels.cpp index 2fed712d7f9..be3bd66cf02 100644 --- a/Framework/Crystal/src/SCDCalibratePanels.cpp +++ b/Framework/Crystal/src/SCDCalibratePanels.cpp @@ -102,9 +102,9 @@ void SCDCalibratePanels::exec() { std::vector<std::string> parameter_workspaces( MyBankNames.size() + MyPanels.size(), "params_"); int i = 0; - for (auto iBank = MyPanels.begin(); iBank != MyPanels.end(); ++iBank) { - fit_workspaces[i] += *iBank; - parameter_workspaces[i] += *iBank; + for (auto &MyPanel : MyPanels) { + fit_workspaces[i] += MyPanel; + parameter_workspaces[i] += MyPanel; i++; } if (snapPanels) { @@ -122,9 +122,9 @@ void SCDCalibratePanels::exec() { << " degrees\n"; } - for (auto iBank = MyBankNames.begin(); iBank != MyBankNames.end(); ++iBank) { - fit_workspaces[i] += *iBank; - parameter_workspaces[i] += *iBank; + for (auto &MyBankName : MyBankNames) { + fit_workspaces[i] += MyBankName; + parameter_workspaces[i] += MyBankName; i++; } if (bankPanels) { diff --git a/Framework/Crystal/src/SaveHKL.cpp b/Framework/Crystal/src/SaveHKL.cpp index 42043c5f354..c91416f25c3 100644 --- a/Framework/Crystal/src/SaveHKL.cpp +++ b/Framework/Crystal/src/SaveHKL.cpp @@ -345,6 +345,7 @@ void SaveHKL::exec() { continue; } int run = p.getRunNumber(); + int seqNum = p.getPeakNumber(); int bank = 0; std::string bankName = p.getBankName(); int nCols, nRows; @@ -546,7 +547,7 @@ void SaveHKL::exec() { out << std::setw(6) << run; - out << std::setw(6) << wi + 1; + out << std::setw(6) << seqNum; out << std::setw(7) << std::fixed << std::setprecision(4) << transmission; diff --git a/Framework/Crystal/src/SaveIsawPeaks.cpp b/Framework/Crystal/src/SaveIsawPeaks.cpp index a50badfca01..6cda29d7aa2 100644 --- a/Framework/Crystal/src/SaveIsawPeaks.cpp +++ b/Framework/Crystal/src/SaveIsawPeaks.cpp @@ -259,13 +259,14 @@ void SaveIsawPeaks::exec() { qSign = 1.0; // ============================== Save all Peaks // ========================================= - // Sequence number - int seqNum = 1; // Go in order of run numbers + int maxPeakNumb = 0; + int appendPeakNumb = 0; runMap_t::iterator runMap_it; for (runMap_it = runMap.begin(); runMap_it != runMap.end(); ++runMap_it) { // Start of a new run + appendPeakNumb += maxPeakNumb; int run = runMap_it->first; bankMap_t &bankMap = runMap_it->second; @@ -310,7 +311,8 @@ void SaveIsawPeaks::exec() { Peak &p = peaks[wi]; // Sequence (run) number - out << "3" << std::setw(7) << seqNum; + maxPeakNumb = std::max(maxPeakNumb, p.getPeakNumber()); + out << "3" << std::setw(7) << p.getPeakNumber() + appendPeakNumb; // HKL's are flipped by -1 because of the internal Q convention // unless Crystallography convention @@ -383,8 +385,6 @@ void SaveIsawPeaks::exec() { } } } - // Count the sequence - seqNum++; } } } diff --git a/Framework/Crystal/src/SortHKL.cpp b/Framework/Crystal/src/SortHKL.cpp index 976b9208558..f77708bfa28 100644 --- a/Framework/Crystal/src/SortHKL.cpp +++ b/Framework/Crystal/src/SortHKL.cpp @@ -1,16 +1,16 @@ #include "MantidAPI/AnalysisDataService.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/Sample.h" - +#include "MantidDataObjects/Workspace2D.h" #include "MantidCrystal/SortHKL.h" - +#include "MantidAPI/WorkspaceFactory.h" #include "MantidDataObjects/Peak.h" #include "MantidDataObjects/PeaksWorkspace.h" - +#include "MantidAPI/TextAxis.h" #include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidGeometry/Crystal/PointGroupFactory.h" #include "MantidGeometry/Crystal/OrientedLattice.h" - +#include "MantidKernel/UnitFactory.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/Utils.h" @@ -84,6 +84,22 @@ void SortHKL::init() { declareProperty("Append", false, "Append to output table workspace if true.\n" "If false, new output table workspace (default)."); + std::vector<std::string> equivTypes{"Mean", "Median"}; + declareProperty("EquivalentIntensities", equivTypes[0], + boost::make_shared<StringListValidator>(equivTypes), + "Replace intensities by mean(default), " + "or median."); + declareProperty(Kernel::make_unique<PropertyWithValue<double>>( + "SigmaCritical", 3.0, Direction::Input), + "Removes peaks whose intensity deviates more than " + "SigmaCritical from the mean (or median)."); + declareProperty( + make_unique<WorkspaceProperty<MatrixWorkspace>>( + "EquivalentsWorkspace", "EquivalentIntensities", Direction::Output), + "Output Equivalent Intensities"); + declareProperty("WeightedZScore", false, + "Use weighted ZScore if true.\n" + "If false, standard ZScore (default)."); } void SortHKL::exec() { @@ -101,8 +117,112 @@ void SortHKL::exec() { UniqueReflectionCollection uniqueReflections = getUniqueReflections(peaks, cell); + std::string equivalentIntensities = getPropertyValue("EquivalentIntensities"); + double sigmaCritical = getProperty("SigmaCritical"); + bool weightedZ = getProperty("WeightedZScore"); + + MatrixWorkspace_sptr UniqWksp = + Mantid::API::WorkspaceFactory::Instance().create( + "Workspace2D", uniqueReflections.getReflections().size(), 20, 20); + int counter = 0; + size_t maxPeaks = 0; + auto taxis = new TextAxis(uniqueReflections.getReflections().size()); + UniqWksp->getAxis(0)->unit() = UnitFactory::Instance().create("Wavelength"); + for (const auto &unique : uniqueReflections.getReflections()) { + /* Since all possible unique reflections are explored + * there may be 0 observations for some of them. + * In that case, nothing can be done.*/ + + if (unique.second.count() > 2) { + taxis->setLabel(counter, " " + unique.second.getHKL().toString()); + auto &UniqX = UniqWksp->mutableX(counter); + auto &UniqY = UniqWksp->mutableY(counter); + auto &UniqE = UniqWksp->mutableE(counter); + counter++; + auto wavelengths = unique.second.getWavelengths(); + auto intensities = unique.second.getIntensities(); + g_log.debug() << "HKL " << unique.second.getHKL() << "\n"; + g_log.debug() << "Intensities "; + for (const auto &e : intensities) + g_log.debug() << e << " "; + g_log.debug() << "\n"; + std::vector<double> zScores; + if (!weightedZ) { + zScores = Kernel::getZscore(intensities); + } else { + auto sigmas = unique.second.getSigmas(); + zScores = Kernel::getWeightedZscore(intensities, sigmas); + } + + if (zScores.size() > maxPeaks) + maxPeaks = zScores.size(); + // Possibly remove outliers. + auto outliersRemoved = + unique.second.removeOutliers(sigmaCritical, weightedZ); + + auto intensityStatistics = + Kernel::getStatistics(outliersRemoved.getIntensities(), + StatOptions::Mean | StatOptions::Median); + + g_log.debug() << "Mean = " << intensityStatistics.mean + << " Median = " << intensityStatistics.median << "\n"; + // sort wavelengths & intensities + for (size_t i = 0; i < wavelengths.size(); i++) { + size_t i0 = i; + for (size_t j = i + 1; j < wavelengths.size(); j++) { + if (wavelengths[j] < wavelengths[i0]) // Change was here! + { + i0 = j; + } + } + double temp = wavelengths[i0]; + wavelengths[i0] = wavelengths[i]; + wavelengths[i] = temp; + temp = intensities[i0]; + intensities[i0] = intensities[i]; + intensities[i] = temp; + } + g_log.debug() << "Zscores "; + for (size_t i = 0; i < std::min(zScores.size(), static_cast<size_t>(20)); + ++i) { + UniqX[i] = wavelengths[i]; + UniqY[i] = intensities[i]; + if (zScores[i] > sigmaCritical) + UniqE[i] = intensities[i]; + else if (equivalentIntensities == "Mean") + UniqE[i] = intensityStatistics.mean - intensities[i]; + else + UniqE[i] = intensityStatistics.median - intensities[i]; + g_log.debug() << zScores[i] << " "; + } + for (size_t i = zScores.size(); i < 20; ++i) { + UniqX[i] = wavelengths[zScores.size() - 1]; + UniqY[i] = intensities[zScores.size() - 1]; + UniqE[i] = 0.0; + } + g_log.debug() << "\n"; + } + } + + if (counter > 0) { + MatrixWorkspace_sptr UniqWksp2 = + Mantid::API::WorkspaceFactory::Instance().create("Workspace2D", counter, + maxPeaks, maxPeaks); + for (int64_t i = 0; i < counter; ++i) { + auto &outSpec = UniqWksp2->getSpectrum(i); + const auto &inSpec = UniqWksp->getSpectrum(i); + outSpec.setHistogram(inSpec.histogram()); + // Copy the spectrum number/detector IDs + outSpec.copyInfoFrom(inSpec); + } + UniqWksp2->replaceAxis(1, taxis); + setProperty("EquivalentsWorkspace", UniqWksp2); + } else { + setProperty("EquivalentsWorkspace", UniqWksp); + } - PeaksStatistics peaksStatistics(uniqueReflections); + PeaksStatistics peaksStatistics(uniqueReflections, equivalentIntensities, + sigmaCritical, weightedZ); // Store the statistics for output. const std::string tableName = getProperty("StatisticsTable"); diff --git a/Framework/Crystal/src/StatisticsOfPeaksWorkspace.cpp b/Framework/Crystal/src/StatisticsOfPeaksWorkspace.cpp index fc67fa1e3eb..3a1351badd3 100644 --- a/Framework/Crystal/src/StatisticsOfPeaksWorkspace.cpp +++ b/Framework/Crystal/src/StatisticsOfPeaksWorkspace.cpp @@ -6,6 +6,7 @@ #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/UnitFactory.h" #include "MantidKernel/ListValidator.h" +#include "MantidDataObjects/Workspace2D.h" #include <fstream> @@ -75,6 +76,22 @@ void StatisticsOfPeaksWorkspace::init() { boost::make_shared<StringListValidator>(sortTypes), "Sort the peaks by resolution shell in d-Spacing(default), " "bank, run number, or only overall statistics."); + std::vector<std::string> equivTypes{"Mean", "Median"}; + declareProperty("EquivalentIntensities", equivTypes[0], + boost::make_shared<StringListValidator>(equivTypes), + "Replace intensities by mean(default), " + "or median."); + declareProperty(Kernel::make_unique<PropertyWithValue<double>>( + "SigmaCritical", 3.0, Direction::Input), + "Removes peaks whose intensity deviates more than " + "SigmaCritical from the mean (or median)."); + declareProperty( + make_unique<WorkspaceProperty<MatrixWorkspace>>( + "EquivalentsWorkspace", "EquivalentIntensities", Direction::Output), + "Output Equivalent Intensities"); + declareProperty("WeightedZScore", false, + "Use weighted ZScore if true.\n" + "If false, standard ZScore (default)."); } //---------------------------------------------------------------------------------------------- @@ -177,6 +194,9 @@ void StatisticsOfPeaksWorkspace::doSortHKL(Mantid::API::Workspace_sptr ws, std::string latticeCentering = getPropertyValue("LatticeCentering"); std::string wkspName = getPropertyValue("OutputWorkspace"); std::string tableName = getPropertyValue("StatisticsTable"); + std::string equivalentIntensities = getPropertyValue("EquivalentIntensities"); + double sigmaCritical = getProperty("SigmaCritical"); + bool weightedZ = getProperty("WeightedZScore"); API::IAlgorithm_sptr statsAlg = createChildAlgorithm("SortHKL"); statsAlg->setProperty("InputWorkspace", ws); statsAlg->setPropertyValue("OutputWorkspace", wkspName); @@ -186,12 +206,17 @@ void StatisticsOfPeaksWorkspace::doSortHKL(Mantid::API::Workspace_sptr ws, statsAlg->setProperty("RowName", runName); if (runName != "Overall") statsAlg->setProperty("Append", true); + statsAlg->setPropertyValue("EquivalentIntensities", equivalentIntensities); + statsAlg->setProperty("SigmaCritical", sigmaCritical); + statsAlg->setProperty("WeightedZScore", weightedZ); statsAlg->executeAsChildAlg(); PeaksWorkspace_sptr statsWksp = statsAlg->getProperty("OutputWorkspace"); ITableWorkspace_sptr tablews = statsAlg->getProperty("StatisticsTable"); + MatrixWorkspace_sptr equivws = statsAlg->getProperty("EquivalentsWorkspace"); if (runName == "Overall") setProperty("OutputWorkspace", statsWksp); setProperty("StatisticsTable", tablews); + setProperty("EquivalentsWorkspace", equivws); } } // namespace Mantid diff --git a/Framework/Crystal/test/ConnectedComponentLabelingTest.h b/Framework/Crystal/test/ConnectedComponentLabelingTest.h index 81beb4d05b4..dc161cfcc89 100644 --- a/Framework/Crystal/test/ConnectedComponentLabelingTest.h +++ b/Framework/Crystal/test/ConnectedComponentLabelingTest.h @@ -410,9 +410,8 @@ public: clusterThreeIndexes.end()); // Add elevated signal to the workspace at cluster indexes. - for (auto it = allClusterIndexes.begin(); it != allClusterIndexes.end(); - ++it) { - inWS->setSignalAt(*it, raisedSignal); + for (auto &clusterIndex : allClusterIndexes) { + inWS->setSignalAt(clusterIndex, raisedSignal); } // ---------- Run the cluster finding diff --git a/Framework/Crystal/test/HardThresholdBackgroundTest.h b/Framework/Crystal/test/HardThresholdBackgroundTest.h index 5429cc3c3c7..5d9566fcb27 100644 --- a/Framework/Crystal/test/HardThresholdBackgroundTest.h +++ b/Framework/Crystal/test/HardThresholdBackgroundTest.h @@ -27,7 +27,7 @@ public: HardThresholdBackground strategy(threshold, Mantid::API::NoNormalization); - TS_ASSERT(strategy.isBackground(iterator)); + TS_ASSERT(strategy.isBackground(iterator.get())); } }; diff --git a/Framework/Crystal/test/PeakBackgroundTest.h b/Framework/Crystal/test/PeakBackgroundTest.h index 7b21d7d9da0..4605bc16067 100644 --- a/Framework/Crystal/test/PeakBackgroundTest.h +++ b/Framework/Crystal/test/PeakBackgroundTest.h @@ -48,10 +48,12 @@ public: MOCK_CONST_METHOD0(getNormalizedSignalWithMask, signal_t()); MOCK_CONST_METHOD0(getSignal, signal_t()); MOCK_CONST_METHOD0(getError, signal_t()); - MOCK_CONST_METHOD1(getVertexesArray, coord_t *(size_t &numVertices)); + MOCK_CONST_METHOD1(getVertexesArray, + std::unique_ptr<coord_t[]>(size_t &numVertices)); MOCK_CONST_METHOD3(getVertexesArray, - coord_t *(size_t &numVertices, const size_t outDimensions, - const bool *maskDim)); + std::unique_ptr<coord_t[]>(size_t &numVertices, + const size_t outDimensions, + const bool *maskDim)); MOCK_CONST_METHOD0(getCenter, Mantid::Kernel::VMD()); MOCK_CONST_METHOD0(getNumEvents, size_t()); MOCK_CONST_METHOD1(getInnerRunIndex, uint16_t(size_t index)); diff --git a/Framework/Crystal/test/PeakStatisticsToolsTest.h b/Framework/Crystal/test/PeakStatisticsToolsTest.h index 779df462ee0..7f84cfa02c7 100644 --- a/Framework/Crystal/test/PeakStatisticsToolsTest.h +++ b/Framework/Crystal/test/PeakStatisticsToolsTest.h @@ -178,6 +178,30 @@ public: TS_ASSERT_EQUALS(cleanIntensities[1], 31.0); } + void test_UniqueReflectionRemoveOutliersWeighted() { + UniqueReflection reflection = + getReflectionWithPeaks({30.0, 34.0, 32.0, 31.0}, {4.5, 6.5, 10.0, 2.3}); + + // standard deviation is 1.70782512765993 + auto cleanReflection = reflection.removeOutliers(3.0, true); + TSM_ASSERT_EQUALS( + "UniqueReflection removed outlier although it should not.", + cleanReflection.count(), 3); + + cleanReflection = reflection.removeOutliers(2.0, true); + TSM_ASSERT_EQUALS( + "UniqueReflection removed outlier although it should not.", + cleanReflection.count(), 2); + + cleanReflection = reflection.removeOutliers(1.0, true); + TSM_ASSERT_EQUALS( + "UniqueReflection did not remove outliers although it should have.", + cleanReflection.count(), 1); + + std::vector<double> cleanIntensities = cleanReflection.getIntensities(); + TS_ASSERT_EQUALS(cleanIntensities[0], 32.0); + } + void test_UniqueReflectionSetIntensityAndSigma() { UniqueReflection reflection = getReflectionWithPeaks({30.0, 34.0, 32.0, 31.0}, {4.5, 6.5, 10.0, 2.3}); diff --git a/Framework/Crystal/test/PredictPeaksTest.h b/Framework/Crystal/test/PredictPeaksTest.h index ef297ab7108..6778889cdc0 100644 --- a/Framework/Crystal/test/PredictPeaksTest.h +++ b/Framework/Crystal/test/PredictPeaksTest.h @@ -37,9 +37,9 @@ public: PeaksWorkspace_sptr hklPW; if (hkls.size() > 0) { hklPW = PeaksWorkspace_sptr(new PeaksWorkspace()); - for (size_t i = 0; i < hkls.size(); i++) { + for (const auto &hkl : hkls) { Peak p(inst, detid, 1.0); - p.setHKL(hkls[i]); + p.setHKL(hkl); hklPW->addPeak(p); } } diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateChiSquared.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateChiSquared.h index 3a4279938f5..ae69f85c424 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateChiSquared.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateChiSquared.h @@ -39,6 +39,9 @@ class DLLExport CalculateChiSquared : public IFittingAlgorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CalculateCostFunction", "Fit"}; + } const std::string summary() const override; private: diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateCostFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateCostFunction.h index d66640fd091..958ac294066 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateCostFunction.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/CalculateCostFunction.h @@ -42,6 +42,9 @@ class DLLExport CalculateCostFunction : public IFittingAlgorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CalculateChiSquared", "Fit"}; + } const std::string summary() const override; private: diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimateFitParameters.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimateFitParameters.h index 4e7bffa93e4..8366d8e8ccc 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimateFitParameters.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimateFitParameters.h @@ -37,6 +37,9 @@ class DLLExport EstimateFitParameters : public IFittingAlgorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"Fit", "EstimatePeakErrors"}; + } const std::string summary() const override; private: diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimatePeakErrors.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimatePeakErrors.h index 9337aba2706..d7f2c396550 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimatePeakErrors.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EstimatePeakErrors.h @@ -38,6 +38,9 @@ public: const std::string summary() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"Fit", "EstimateFitParameters"}; + } const std::string category() const override; private: diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EvaluateFunction.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EvaluateFunction.h index 915b3285faa..aef157d8558 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EvaluateFunction.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/EvaluateFunction.h @@ -38,6 +38,7 @@ class DLLExport EvaluateFunction : public IFittingAlgorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { return {"Fit"}; } const std::string summary() const override; private: diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/Fit.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/Fit.h index a60b8da6de0..028f6d76fee 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/Fit.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/Fit.h @@ -103,6 +103,10 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"FitGaussian", "UserFunction1D", "PlotPeakByLogValue", + "SplineBackground", "EvaluateFunction"}; + } private: void initConcrete() override; diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/FitPowderDiffPeaks.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/FitPowderDiffPeaks.h index c602e18e0f1..8b99f2e5e91 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/FitPowderDiffPeaks.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/FitPowderDiffPeaks.h @@ -71,6 +71,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LeBailFit"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Diffraction\\Fitting"; } diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFit.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFit.h index 05466c164ed..9c73166259e 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFit.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/LeBailFit.h @@ -91,6 +91,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CreateLeBailFitInput", "FitPowderDiffPeaks"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Diffraction\\Fitting"; } diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/NormaliseByPeakArea.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/NormaliseByPeakArea.h index 36c402f6e09..d7ca221d867 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/NormaliseByPeakArea.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/NormaliseByPeakArea.h @@ -49,6 +49,10 @@ public: "input mass value."; } + const std::vector<std::string> seeAlso() const override { + return {"MonitorEfficiencyCorUser", "Divide"}; + } + int version() const override; const std::string category() const override; diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PawleyFit.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PawleyFit.h index deaad15eca4..9e25bff6a66 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PawleyFit.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PawleyFit.h @@ -69,6 +69,9 @@ public: PawleyFit(); const std::string name() const override { return "PawleyFit"; } int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"PoldiPeakSearch"}; + } const std::string summary() const override; const std::string category() const override { return "Diffraction\\Fitting"; } diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PlotPeakByLogValue.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PlotPeakByLogValue.h index 659bad57095..d7425fe118c 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PlotPeakByLogValue.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/PlotPeakByLogValue.h @@ -88,6 +88,7 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { return {"Fit"}; } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Optimization"; } diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters3.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters3.h index 1c02e46c59e..8e06e79bb4b 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters3.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters3.h @@ -54,6 +54,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 3; } + const std::vector<std::string> seeAlso() const override { + return {"RefinePowderDiffProfileSeq"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Diffraction\\Fitting"; } diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineBackground.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineBackground.h index c154c4c35aa..cb77bfa19f4 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineBackground.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineBackground.h @@ -47,6 +47,9 @@ public: const std::string name() const override { return "SplineBackground"; } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"Fit", "SplineInterpolation", "SplineSmoothing"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Optimization;CorrectionFunctions\\BackgroundCorrections"; diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineInterpolation.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineInterpolation.h index 0d4af58d67a..363fb385aa4 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineInterpolation.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineInterpolation.h @@ -49,6 +49,9 @@ public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"Fit", "SplineBackground", "SplineSmoothing"}; + } const std::string category() const override; const std::string summary() const override; std::map<std::string, std::string> validateInputs() override; diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineSmoothing.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineSmoothing.h index 51ed2dce5c9..1a59ab2510e 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineSmoothing.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineSmoothing.h @@ -45,6 +45,9 @@ public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"Fit", "SplineInterpolation", "SplineBackground"}; + } const std::string category() const override; /// Summary of algorithms purpose const std::string summary() const override { diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateGammaBackground.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateGammaBackground.h index 108ccccdbd7..08972a6f98b 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateGammaBackground.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateGammaBackground.h @@ -57,6 +57,9 @@ public: return "Calculates the background due to gamma rays produced when neutrons " "are absorbed by shielding."; } + const std::vector<std::string> seeAlso() const override { + return {"VesuvioCorrections"}; + } int version() const override; const std::string category() const override; diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateMS.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateMS.h index d3e19adf0d6..7adc0d45e76 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateMS.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/VesuvioCalculateMS.h @@ -95,6 +95,11 @@ public: "on a flat plate sample for VESUVIO"; } + const std::vector<std::string> seeAlso() const override { + return {"MayersSampleCorrection", "MonteCarloAbsorption", + "MultipleScatteringCylinderAbsorption"}; + } + private: void init() override; void exec() override; diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/UserFunction1D.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/UserFunction1D.h index 5274b319fc8..e6478b9b335 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/UserFunction1D.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/UserFunction1D.h @@ -88,6 +88,7 @@ public: const std::string summary() const override { return "Fits a histogram from a workspace to a user defined function."; } + const std::vector<std::string> seeAlso() const override { return {"Fit"}; } protected: /// overwrite base class methods diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/RalNlls/Workspaces.h b/Framework/CurveFitting/inc/MantidCurveFitting/RalNlls/Workspaces.h index 5d13fc72a88..a65b4c92694 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/RalNlls/Workspaces.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/RalNlls/Workspaces.h @@ -183,14 +183,14 @@ struct nlls_inform { /// the value of the objective function at the best estimate of the solution /// determined by NLLS_solve - double obj = HUGE; + double obj = std::numeric_limits<float>::max(); /// the norm of the gradient of the objective function at the best estimate /// of the solution determined by NLLS_solve - double norm_g = HUGE; + double norm_g = std::numeric_limits<float>::max(); /// the norm of the gradient, scaled by the norm of the residual - double scaled_g = HUGE; + double scaled_g = std::numeric_limits<float>::max(); }; // END TYPE nlls_inform diff --git a/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp b/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp index 763a15975a2..aa33da34928 100644 --- a/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp +++ b/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp @@ -429,8 +429,8 @@ void EstimateFitParameters::execConcrete() { if (m_function->isActive(i)) { TableRow row = table->appendRow(); row << m_function->parameterName(i); - for (size_t j = 0; j < output.size(); ++j) { - row << output[j][ia]; + for (auto &j : output) { + row << j[ia]; } ++ia; } diff --git a/Framework/CurveFitting/src/FuncMinimizers/TrustRegionMinimizer.cpp b/Framework/CurveFitting/src/FuncMinimizers/TrustRegionMinimizer.cpp index 2b4c732e712..e2d26ec8947 100644 --- a/Framework/CurveFitting/src/FuncMinimizers/TrustRegionMinimizer.cpp +++ b/Framework/CurveFitting/src/FuncMinimizers/TrustRegionMinimizer.cpp @@ -1274,10 +1274,10 @@ void solveSubproblem(int n, double radius, double f, inform.obj *= pow(scale_c, 2) / scale_h; inform.multiplier *= scale_h; inform.pole *= scale_h; - for (size_t i = 0; i < inform.history.size(); - ++i) { // do i = 1, inform.len_history - inform.history[i].lambda *= scale_h; - inform.history[i].x_norm *= scale_c / scale_h; + for (auto &history_item : + inform.history) { // do i = 1, inform.len_history + history_item.lambda *= scale_h; + history_item.x_norm *= scale_c / scale_h; } } diff --git a/Framework/CurveFitting/src/Functions/CrystalFieldMultiSpectrum.cpp b/Framework/CurveFitting/src/Functions/CrystalFieldMultiSpectrum.cpp index f1af30eea74..70aed84ab03 100644 --- a/Framework/CurveFitting/src/Functions/CrystalFieldMultiSpectrum.cpp +++ b/Framework/CurveFitting/src/Functions/CrystalFieldMultiSpectrum.cpp @@ -192,10 +192,20 @@ void CrystalFieldMultiSpectrum::setAttribute(const std::string &name, } } else if (boost::regex_match(name, match, FWHMX_ATTR_REGEX)) { auto iSpec = std::stoul(match[1]); - m_fwhmX[iSpec].clear(); + if (m_fwhmX.size() > iSpec) { + m_fwhmX[iSpec].clear(); + } else { + throw std::invalid_argument( + "Temperatures must be defined before resolution model"); + } } else if (boost::regex_match(name, match, FWHMY_ATTR_REGEX)) { auto iSpec = std::stoul(match[1]); - m_fwhmY[iSpec].clear(); + if (m_fwhmY.size() > iSpec) { + m_fwhmY[iSpec].clear(); + } else { + throw std::invalid_argument( + "Temperatures must be defined before resolution model"); + } } FunctionGenerator::setAttribute(name, attr); } diff --git a/Framework/CurveFitting/test/Algorithms/EvaluateFunctionTest.h b/Framework/CurveFitting/test/Algorithms/EvaluateFunctionTest.h index d675c5f0de7..9748b7ac889 100644 --- a/Framework/CurveFitting/test/Algorithms/EvaluateFunctionTest.h +++ b/Framework/CurveFitting/test/Algorithms/EvaluateFunctionTest.h @@ -149,7 +149,6 @@ public: TS_ASSERT_DELTA((signal - value) / value, 0.0, 1e-6); } } while (iter->next()); - delete iter; } void test_set_workspace_twice() { diff --git a/Framework/CurveFitting/test/Algorithms/LeBailFunctionTest.h b/Framework/CurveFitting/test/Algorithms/LeBailFunctionTest.h index 0f761eab369..6f560ebd21c 100644 --- a/Framework/CurveFitting/test/Algorithms/LeBailFunctionTest.h +++ b/Framework/CurveFitting/test/Algorithms/LeBailFunctionTest.h @@ -515,10 +515,10 @@ public: 1.950190, 1.613562, 1.335208, 1.104734, 0.914043, 0.756362, 0.000000}; - for (size_t i = 0; i < vecY.size(); ++i) { + for (double y : vecY) { double e = 1.0; - if (vecY[i] > 1.0) - e = sqrt(vecY[i]); + if (y > 1.0) + e = sqrt(y); vecE.push_back(e); } @@ -687,8 +687,8 @@ public: vecy.push_back(0.03096179); vece.push_back(0.00105191); - for (size_t i = 0; i < vecy.size(); ++i) - vecy[i] -= 0.02295189; + for (double &i : vecy) + i -= 0.02295189; return; } diff --git a/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h b/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h index 557a80dc32e..887b222e9af 100644 --- a/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h +++ b/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h @@ -496,10 +496,10 @@ public: TS_ASSERT(fits->getNames().size() == 2); auto wsNames = fits->getNames(); - for (size_t i = 0; i < wsNames.size(); ++i) { + for (const auto &wsName : wsNames) { auto fit = AnalysisDataService::Instance().retrieveWS<const MatrixWorkspace>( - wsNames[i]); + wsName); TS_ASSERT(fit); TS_ASSERT(fit->getNumberHistograms() == 5); } diff --git a/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParametersTest.h b/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParametersTest.h index 233c1a20055..ba013ee91cb 100644 --- a/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParametersTest.h +++ b/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParametersTest.h @@ -308,9 +308,9 @@ public: hkl << hkls[ipk][i]; cout << hkls[ipk][i] << ", "; } - for (size_t ipm = 0; ipm < peakparams[ipk].size(); ++ipm) { - hkl << peakparams[ipk][ipm]; - cout << peakparams[ipk][ipm]; + for (double ipm : peakparams[ipk]) { + hkl << ipm; + cout << ipm; } cout << '\n'; } @@ -416,10 +416,10 @@ public: // 2. Add peak parameters' name and values map<string, vector<double>>::iterator finditer; - for (size_t ipn = 0; ipn < paramnames.size(); ++ipn) { + for (const auto ¶mname : paramnames) { API::TableRow newrow = geomws->appendRow(); - std::string parname = paramnames[ipn]; - double parvalue = parameters[paramnames[ipn]]; + std::string parname = paramname; + double parvalue = parameters[paramname]; newrow << parname << parvalue; double parmin = -DBL_MAX; double parmax = DBL_MAX; diff --git a/Framework/CurveFitting/test/Functions/ChebfunBaseTest.h b/Framework/CurveFitting/test/Functions/ChebfunBaseTest.h index 23331503944..db19d23152d 100644 --- a/Framework/CurveFitting/test/Functions/ChebfunBaseTest.h +++ b/Framework/CurveFitting/test/Functions/ChebfunBaseTest.h @@ -115,8 +115,7 @@ private: ChebfunBase base(n, start, end); auto p = base.fit(fun); auto x = base.linspace(2 * n); - for (size_t i = 0; i < x.size(); ++i) { - double xi = x[i]; + for (double xi : x) { TS_ASSERT_DELTA(base.eval(xi, p), fun(xi), 1e-4); } } @@ -148,8 +147,7 @@ private: std::vector<double> p, a; auto base = ChebfunBase::bestFit(start, end, fun, p, a); auto x = base->linspace(2 * base->size()); - for (size_t i = 0; i < x.size(); ++i) { - double xi = x[i]; + for (double xi : x) { TS_ASSERT_DELTA(base->eval(xi, p), fun(xi), 1e-14); } TS_ASSERT_EQUALS(base->size(), expected_n); @@ -169,8 +167,7 @@ private: base->derivative(a, da); dp = base->calcP(da); auto x = base->linspace(2 * base->size()); - for (size_t i = 0; i < x.size(); ++i) { - double xi = x[i]; + for (double xi : x) { // std::cerr << xi << ' ' << base->eval(xi,dp) - Cos(xi) << '\n'; TS_ASSERT_DELTA(base->eval(xi, dp), deriv(xi), 1e-13); } @@ -182,8 +179,8 @@ private: auto base = ChebfunBase::bestFit(start, end, fun, p, a); auto roots = base->roots(a); TS_ASSERT_EQUALS(n_roots, roots.size()); - for (size_t i = 0; i < roots.size(); ++i) { - TS_ASSERT_DELTA(base->eval(roots[i], p), 0.0, tol); + for (double root : roots) { + TS_ASSERT_DELTA(base->eval(root, p), 0.0, tol); } } }; diff --git a/Framework/CurveFitting/test/Functions/CrystalFieldMultiSpectrumTest.h b/Framework/CurveFitting/test/Functions/CrystalFieldMultiSpectrumTest.h index 4656d63c7a6..dc26a88b3b2 100644 --- a/Framework/CurveFitting/test/Functions/CrystalFieldMultiSpectrumTest.h +++ b/Framework/CurveFitting/test/Functions/CrystalFieldMultiSpectrumTest.h @@ -406,6 +406,16 @@ public: } } + void test_multispectrum_malformed_resmod() { + std::string fun = + "name=CrystalFieldMultiSpectrum,Ion=Ce,FWHMX0=(1,2),FWHMY0=(2,3)," + "FWHMX1=(0,1),FWHMY2=(5,6),Temperatures=(44,50),B20=0.37737"; + auto alg = AlgorithmFactory::Instance().create("EvaluateFunction", -1); + alg->initialize(); + TS_ASSERT_THROWS(alg->setPropertyValue("Function", fun), + std::invalid_argument); + } + void test_underdefinded() { CrystalFieldMultiSpectrum fun; fun.setParameter("B20", 0.37737); diff --git a/Framework/CurveFitting/test/Functions/ProcessBackgroundTest.h b/Framework/CurveFitting/test/Functions/ProcessBackgroundTest.h index acd2ddcd4f0..13ca05b896b 100644 --- a/Framework/CurveFitting/test/Functions/ProcessBackgroundTest.h +++ b/Framework/CurveFitting/test/Functions/ProcessBackgroundTest.h @@ -446,8 +446,8 @@ public: MersenneTwister mt(1234, 0.0, 1000000.0); std::vector<double> bkgdpts(10000); - for (auto it = bkgdpts.begin(); it != bkgdpts.end(); it++) { - *it = mt.nextValue(); + for (double &bkgdpt : bkgdpts) { + bkgdpt = mt.nextValue(); } sbg.initialize(); diff --git a/Framework/CurveFitting/test/Functions/SimpleChebfunTest.h b/Framework/CurveFitting/test/Functions/SimpleChebfunTest.h index f3b4482f107..f2ee2336d68 100644 --- a/Framework/CurveFitting/test/Functions/SimpleChebfunTest.h +++ b/Framework/CurveFitting/test/Functions/SimpleChebfunTest.h @@ -159,9 +159,9 @@ private: } } auto &xp = cheb.xPoints(); - for (size_t i = 0; i < xp.size(); ++i) { + for (double i : xp) { // std::cerr << xp[i] << ' ' << cheb(xp[i]) - fun(xp[i]) << '\n'; - TS_ASSERT_DELTA(cheb(xp[i]), fun(xp[i]), accur2); + TS_ASSERT_DELTA(cheb(i), fun(i), accur2); } } }; diff --git a/Framework/CurveFitting/test/IPeakFunctionCentreParameterNameTest.h b/Framework/CurveFitting/test/IPeakFunctionCentreParameterNameTest.h index 2d19fed5347..843542f9221 100644 --- a/Framework/CurveFitting/test/IPeakFunctionCentreParameterNameTest.h +++ b/Framework/CurveFitting/test/IPeakFunctionCentreParameterNameTest.h @@ -33,10 +33,9 @@ public: /* Test that all functions give the expected result. */ void testAllFunctions() { - for (auto it = m_expectedResults.begin(); it != m_expectedResults.end(); - ++it) { - const std::string &peakFunctionName = it->first; - const std::string ¢reParameterName = it->second; + for (auto &expectedResult : m_expectedResults) { + const std::string &peakFunctionName = expectedResult.first; + const std::string ¢reParameterName = expectedResult.second; IPeakFunction_sptr fn = boost::dynamic_pointer_cast<IPeakFunction>( FunctionFactory::Instance().createFunction(peakFunctionName)); diff --git a/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h b/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h index cec758e09c5..7babcbecbfa 100644 --- a/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h +++ b/Framework/CurveFitting/test/IPeakFunctionIntensityTest.h @@ -91,12 +91,11 @@ private: std::vector<std::string> registeredFunctions = FunctionFactory::Instance().getFunctionNames<IPeakFunction>(); - for (auto it = registeredFunctions.begin(); it != registeredFunctions.end(); - ++it) { - if (blackList.count(*it) == 0) { + for (auto ®isteredFunction : registeredFunctions) { + if (blackList.count(registeredFunction) == 0) { IPeakFunction_sptr peakFunction = boost::dynamic_pointer_cast<IPeakFunction>( - FunctionFactory::Instance().createFunction(*it)); + FunctionFactory::Instance().createFunction(registeredFunction)); if (peakFunction) { peakFunctions.push_back(peakFunction); @@ -110,16 +109,16 @@ private: void initializePeakFunctions(const std::vector<IPeakFunction_sptr> &peaks, const ParameterSet ¶meters) const { - for (auto it = peaks.begin(); it != peaks.end(); ++it) { - (*it)->setCentre(parameters.center); + for (const auto &peak : peaks) { + peak->setCentre(parameters.center); // for Ikeda-Carpenter it's not allowed to set Fwhm try { - (*it)->setFwhm(parameters.fwhm); + peak->setFwhm(parameters.fwhm); } catch (std::invalid_argument) { } - (*it)->setHeight(parameters.height); + peak->setHeight(parameters.height); } } @@ -137,8 +136,8 @@ private: getIntensities(const std::vector<IPeakFunction_sptr> &peaks) const { std::vector<double> intensities; - for (auto it = peaks.begin(); it != peaks.end(); ++it) { - intensities.push_back((*it)->intensity()); + for (const auto &peak : peaks) { + intensities.push_back(peak->intensity()); } return intensities; diff --git a/Framework/DataHandling/inc/MantidDataHandling/CompressEvents.h b/Framework/DataHandling/inc/MantidDataHandling/CompressEvents.h index c3c49b795f8..e787d32ae90 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/CompressEvents.h +++ b/Framework/DataHandling/inc/MantidDataHandling/CompressEvents.h @@ -53,6 +53,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadEventNexus", "LoadEventAndCompress"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Events"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/CreateSampleShape.h b/Framework/DataHandling/inc/MantidDataHandling/CreateSampleShape.h index 24ef28c000c..6151c5b35b1 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/CreateSampleShape.h +++ b/Framework/DataHandling/inc/MantidDataHandling/CreateSampleShape.h @@ -49,6 +49,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"AbsorptionCorrection", "SetSampleMaterial", "CopySample"}; + } /// Algorithm's category for identification const std::string category() const override { return "Sample;"; } /// Algorithm's aliases diff --git a/Framework/DataHandling/inc/MantidDataHandling/DefineGaugeVolume.h b/Framework/DataHandling/inc/MantidDataHandling/DefineGaugeVolume.h index bdddc787c77..6d5d06d7600 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/DefineGaugeVolume.h +++ b/Framework/DataHandling/inc/MantidDataHandling/DefineGaugeVolume.h @@ -50,6 +50,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"AbsorptionCorrection"}; + } /// Algorithm's category for identification const std::string category() const override { return "Sample"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/DeleteTableRows.h b/Framework/DataHandling/inc/MantidDataHandling/DeleteTableRows.h index 93ac211c015..524f0a5fd06 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/DeleteTableRows.h +++ b/Framework/DataHandling/inc/MantidDataHandling/DeleteTableRows.h @@ -49,6 +49,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CreateEmptyTableWorkspace"}; + } /// Category const std::string category() const override { return "Utility\\Workspaces"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/DownloadFile.h b/Framework/DataHandling/inc/MantidDataHandling/DownloadFile.h index dcf95a8715e..900a3632669 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/DownloadFile.h +++ b/Framework/DataHandling/inc/MantidDataHandling/DownloadFile.h @@ -43,6 +43,9 @@ public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"Load", "CatalogDownloadDataFiles"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/DownloadInstrument.h b/Framework/DataHandling/inc/MantidDataHandling/DownloadInstrument.h index 08183f6e02c..69e035ef999 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/DownloadInstrument.h +++ b/Framework/DataHandling/inc/MantidDataHandling/DownloadInstrument.h @@ -40,6 +40,9 @@ public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LoadInstrument", "UpdateScriptRepository"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/ExtractMonitorWorkspace.h b/Framework/DataHandling/inc/MantidDataHandling/ExtractMonitorWorkspace.h index 96a62132aa9..3e57037660b 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/ExtractMonitorWorkspace.h +++ b/Framework/DataHandling/inc/MantidDataHandling/ExtractMonitorWorkspace.h @@ -36,6 +36,9 @@ class DLLExport ExtractMonitorWorkspace : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ExtractMonitors"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/FindDetectorsInShape.h b/Framework/DataHandling/inc/MantidDataHandling/FindDetectorsInShape.h index 492bbdf0e1f..245ce4500cf 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/FindDetectorsInShape.h +++ b/Framework/DataHandling/inc/MantidDataHandling/FindDetectorsInShape.h @@ -64,6 +64,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"MaskDetectorsInShape"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Utility\\Instrument"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h b/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h index 9424a2ce8ea..0a3bbc012da 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h @@ -120,6 +120,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 2; }; + const std::vector<std::string> seeAlso() const override { + return {"SpatialGrouping"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Grouping"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/Load.h b/Framework/DataHandling/inc/MantidDataHandling/Load.h index 7ba6bf16ee6..3645c6b4066 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/Load.h +++ b/Framework/DataHandling/inc/MantidDataHandling/Load.h @@ -47,6 +47,10 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadNexus", "LoadRaw", "LoadBBY"}; + } + /// Category const std::string category() const override { return "DataHandling"; } /// Aliases diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h index db7c394e413..961566c7770 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h @@ -60,6 +60,9 @@ public: /// The version number int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { + return {"SaveAscii"}; + } /// The category const std::string category() const override { return "DataHandling\\Text"; } /// Returns a confidence value that this algorithm can load a file diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h b/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h index 1540b860759..8cbf569c987 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h @@ -91,6 +91,9 @@ class DLLExport LoadBBY : public API::IFileLoader<Kernel::FileDescriptor> { public: // description int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"Load", "LoadQKK"}; + } const std::string name() const override { return "LoadBBY"; } const std::string category() const override { return "DataHandling\\ANSTO"; } const std::string summary() const override { diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadCalFile.h b/Framework/DataHandling/inc/MantidDataHandling/LoadCalFile.h index bb334703fc2..baf78431397 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadCalFile.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadCalFile.h @@ -31,6 +31,12 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"ReadGroupsFromFile", "CreateDummyCalFile", + "CreateCalFileByNames", "AlignDetectors", + "DiffractionFocussing", "SaveCalFile", + "MergeCalFiles"}; + } /// Algorithm's category for identification const std::string category() const override { return R"(DataHandling\Text;Diffraction\DataHandling\CalFiles)"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadCanSAS1D2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadCanSAS1D2.h index fa4a5ec2325..33e161e4fa2 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadCanSAS1D2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadCanSAS1D2.h @@ -72,6 +72,9 @@ class DLLExport LoadCanSAS1D2 : public LoadCanSAS1D { public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { + return {"SaveCanSAS1D"}; + } protected: /// Overwrites Algorithm method. Extend to create the LoadTransmission flag. diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadDaveGrp.h b/Framework/DataHandling/inc/MantidDataHandling/LoadDaveGrp.h index ca1fb205d81..d0e15313261 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadDaveGrp.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadDaveGrp.h @@ -58,6 +58,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SaveDaveGrp"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Text;Inelastic\\DataHandling"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorInfo.h b/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorInfo.h index 6e07009f379..c628cae276c 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorInfo.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorInfo.h @@ -45,6 +45,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadRaw", "LoadNexus"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Raw"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorsGroupingFile.h b/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorsGroupingFile.h index 0e4c1fc1b84..5dbe7b6e3c4 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorsGroupingFile.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadDetectorsGroupingFile.h @@ -62,6 +62,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SaveDetectorsGrouping", "GroupDetectors"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Grouping;Transforms\\Grouping"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadDiffCal.h b/Framework/DataHandling/inc/MantidDataHandling/LoadDiffCal.h index a2a205d2264..a4c87a37ce5 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadDiffCal.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadDiffCal.h @@ -40,6 +40,9 @@ class DLLExport LoadDiffCal : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"SaveDiffCal"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadEmptyInstrument.h b/Framework/DataHandling/inc/MantidDataHandling/LoadEmptyInstrument.h index 2165b49239b..18caec619c9 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadEmptyInstrument.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadEmptyInstrument.h @@ -71,6 +71,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadInstrument"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Instrument"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h index 9d167858e41..fe1e4f16d4f 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h @@ -79,6 +79,9 @@ public: /// Version int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadISISNexus", "LoadEventAndCompress"}; + } /// Category const std::string category() const override { return "DataHandling\\Nexus"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus2.h index 21e12011e36..ed3863be5de 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadEventPreNexus2.h @@ -98,6 +98,9 @@ public: const std::string name() const override { return "LoadEventPreNexus"; } /// Algorithm's version int version() const override { return (2); } + const std::vector<std::string> seeAlso() const override { + return {"LoadPreNexus", "FilterEventsByLogValuePreNexus"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\PreNexus"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h b/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h index a699607c6ea..a7f8ccbde2f 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h @@ -61,6 +61,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"Load", "SaveFITS"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadFullprofResolution.h b/Framework/DataHandling/inc/MantidDataHandling/LoadFullprofResolution.h index 8111a311ed1..0c425dac2b6 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadFullprofResolution.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadFullprofResolution.h @@ -46,6 +46,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadFullprofFile"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadGSASInstrumentFile.h b/Framework/DataHandling/inc/MantidDataHandling/LoadGSASInstrumentFile.h index e6125080801..5cc76649a76 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadGSASInstrumentFile.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadGSASInstrumentFile.h @@ -49,6 +49,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"SaveGSASInstrumentFile", "LoadGSS", "FixGSASInstrumentFile"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadGSS.h b/Framework/DataHandling/inc/MantidDataHandling/LoadGSS.h index 8512e0db397..b19318ba0f9 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadGSS.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadGSS.h @@ -51,6 +51,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"LoadAscii", "SaveGSS", "LoadMultipleGSS"}; + } /// Algorithm's category for identification const std::string category() const override { diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadILLDiffraction.h b/Framework/DataHandling/inc/MantidDataHandling/LoadILLDiffraction.h index 0d741397051..cf96c27b81f 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadILLDiffraction.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadILLDiffraction.h @@ -41,6 +41,9 @@ class MANTID_DATAHANDLING_DLL LoadILLDiffraction public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LoadNexus"}; + } const std::string category() const override; const std::string summary() const override; int confidence(Kernel::NexusDescriptor &descriptor) const override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadILLIndirect2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadILLIndirect2.h index ab552a992cf..cab355c3535 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadILLIndirect2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadILLIndirect2.h @@ -41,6 +41,9 @@ public: /// Algorithm's version for identification. @see Algorithm::version int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { + return {"LoadNexus"}; + } const std::string name() const override; /// Summary of algorithms purpose diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadILLReflectometry.h b/Framework/DataHandling/inc/MantidDataHandling/LoadILLReflectometry.h index 000b92adafa..eab4a74e9e8 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadILLReflectometry.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadILLReflectometry.h @@ -40,6 +40,9 @@ public: const std::string name() const override { return "LoadILLReflectometry"; } /// Algorithm's version for identification. @see Algorithm::version int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadNexus"}; + } /// Algorithm's category for search and find. @see Algorithm::category const std::string category() const override { return "DataHandling\\Nexus;ILL\\Reflectometry"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadILLSANS.h b/Framework/DataHandling/inc/MantidDataHandling/LoadILLSANS.h index cdb68d71b77..1a4f331bd35 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadILLSANS.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadILLSANS.h @@ -68,6 +68,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LoadNexus"}; + } const std::string category() const override; /// Returns a confidence value that this algorithm can load a file int confidence(Kernel::NexusDescriptor &descriptor) const override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadILLTOF2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadILLTOF2.h index 79ce533b723..700a7a9646a 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadILLTOF2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadILLTOF2.h @@ -45,6 +45,9 @@ public: /// Algorithm's version int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { + return {"LoadNexus"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Nexus;ILL\\Direct"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h index 2954b9871a8..85144c3c08a 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h @@ -80,6 +80,9 @@ public: const std::string name() const override { return "LoadISISNexus"; } /// Algorithm's version for identification overriding a virtual method int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { + return {"LoadEventNexus", "SaveISISNexus"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Nexus"; } /// Summary of algorithms purpose diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h b/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h index 8649493fe51..a0ffc22adc4 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h @@ -84,6 +84,10 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadInstrumentFromNexus", "LoadInstrumentFromRaw", + "ExportGeometry", "Load"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Instrument"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromNexus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromNexus.h index 5ae9d79ccad..b00f4d6a148 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromNexus.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromNexus.h @@ -84,6 +84,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadInstrument", "Load"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromRaw.h b/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromRaw.h index 6185daee8cf..6b5e3d9a826 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromRaw.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadInstrumentFromRaw.h @@ -84,6 +84,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadInstrument"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadIsawDetCal.h b/Framework/DataHandling/inc/MantidDataHandling/LoadIsawDetCal.h index 321ed71e527..10a9d244e59 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadIsawDetCal.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadIsawDetCal.h @@ -56,6 +56,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"SaveIsawDetCal"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Diffraction\\DataHandling;DataHandling\\Isaw"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadLog.h b/Framework/DataHandling/inc/MantidDataHandling/LoadLog.h index 94b541b5c63..075cee128ed 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadLog.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadLog.h @@ -85,6 +85,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"AddSampleLog", "LoadNexusLogs"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Logs"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadMask.h b/Framework/DataHandling/inc/MantidDataHandling/LoadMask.h index 3ea1b442157..593063b1954 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadMask.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadMask.h @@ -59,6 +59,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"ExportSpectraMask", "LoadMask"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Masking;Transforms\\Masking"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadMcStas.h b/Framework/DataHandling/inc/MantidDataHandling/LoadMcStas.h index 332df5a22b0..f0511bb6db4 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadMcStas.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadMcStas.h @@ -43,6 +43,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LoadMcStasNexus", "LoadNexus"}; + } const std::string category() const override; /// Returns a confidence value that this algorithm can load a file diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadMcStasNexus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadMcStasNexus.h index 7097dddffa0..5a7d147d6bd 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadMcStasNexus.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadMcStasNexus.h @@ -40,6 +40,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LoadMcStas"}; + } const std::string category() const override; /// Returns a confidence value that this algorithm can load a file diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadMuonLog.h b/Framework/DataHandling/inc/MantidDataHandling/LoadMuonLog.h index 7f10f57d911..4d638a49e27 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadMuonLog.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadMuonLog.h @@ -66,6 +66,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadLog", "LoadLogPropertyTable"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Logs;Muon\\DataHandling"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadMuonNexus2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadMuonNexus2.h index 38f9560f2e9..45189d42715 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadMuonNexus2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadMuonNexus2.h @@ -75,6 +75,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { + return {"LoadNexus"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Nexus;Muon\\DataHandling"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h index a3bb7fbe5c7..ad95de64fc8 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h @@ -52,6 +52,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SaveNXSPE", "LoadSPE"}; + } /// Algorithm's category for identification const std::string category() const override { return R"(DataHandling\Nexus;DataHandling\SPE;Inelastic\DataHandling)"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNXcanSAS.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNXcanSAS.h index 5b0614563bb..f17a4f2c6fa 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadNXcanSAS.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNXcanSAS.h @@ -50,6 +50,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"LoadCanSAS1D", "SaveNXcanSAS"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Nexus"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNexus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNexus.h index 0f99dc22017..5f377952ec8 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadNexus.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNexus.h @@ -70,6 +70,12 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadMcStasNexus", "LoadNexusMonitors", "LoadNexusProcessed", + "LoadTOFRawNexus", "LoadILLDiffraction", "LoadILLTOF", + "LoadILLIndirect", "LoadILLReflectometry", "LoadILLSANS", + "LoadMuonNexus", "LoadFlexiNexus"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Nexus"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusLogs.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusLogs.h index e0bc283b8ee..c23d54cc16e 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusLogs.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusLogs.h @@ -62,6 +62,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadLog", "MergeLogs"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Logs;DataHandling\\Nexus"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors2.h index 3ca91b39b59..7a98ee10fe4 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors2.h @@ -61,6 +61,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { + return {"LoadNexus"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Nexus"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusProcessed.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusProcessed.h index 7aaec5cdb23..5f449616746 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusProcessed.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusProcessed.h @@ -76,6 +76,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadNexus"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Nexus"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadPDFgetNFile.h b/Framework/DataHandling/inc/MantidDataHandling/LoadPDFgetNFile.h index 535770755f2..d74c01e2b0f 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadPDFgetNFile.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadPDFgetNFile.h @@ -43,6 +43,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadAscii"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadParameterFile.h b/Framework/DataHandling/inc/MantidDataHandling/LoadParameterFile.h index 698e991deeb..6843aa500b2 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadParameterFile.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadParameterFile.h @@ -76,6 +76,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SaveParameterFile"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Instrument"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexus.h index 713214413fa..c2ccb22f0e6 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexus.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexus.h @@ -44,6 +44,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LoadEventPreNexus", "LoadPreNexusMonitors", "LoadNexus"}; + } const std::string category() const override; void parseRuninfo(const std::string &runinfo, std::string &dataDir, std::vector<std::string> &eventFilenames); diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexusMonitors.h b/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexusMonitors.h index 664ac56cff3..25c416c6701 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexusMonitors.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadPreNexusMonitors.h @@ -47,6 +47,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"LoadEventPreNexus", "LoadPreNexus"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\PreNexus"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadQKK.h b/Framework/DataHandling/inc/MantidDataHandling/LoadQKK.h index bc9889a5668..406beb41fcb 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadQKK.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadQKK.h @@ -48,6 +48,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"LoadBBY"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Nexus"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadRKH.h b/Framework/DataHandling/inc/MantidDataHandling/LoadRKH.h index 1c2e33f2bf9..7e174ea284f 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadRKH.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadRKH.h @@ -57,6 +57,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SaveRKH"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Text;SANS\\DataHandling"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h b/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h index d72df2b5c52..f2908a5e83b 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h @@ -58,6 +58,10 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 3; } + const std::vector<std::string> seeAlso() const override { + return {"LoadVesuvio", "RawFileInfo", "LoadSampleDetailsFromRaw", + "LoadRawBin0", "LoadRawSpectrum0"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Raw"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadRawBin0.h b/Framework/DataHandling/inc/MantidDataHandling/LoadRawBin0.h index 9fcc52621f6..ec86f240489 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadRawBin0.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadRawBin0.h @@ -78,6 +78,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadRawSpectrum0", "LoadRaw"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Diagnostics\\Raw;DataHandling\\Raw"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadRawSpectrum0.h b/Framework/DataHandling/inc/MantidDataHandling/LoadRawSpectrum0.h index 1be9e313735..fdabf955b69 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadRawSpectrum0.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadRawSpectrum0.h @@ -70,6 +70,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadRawBin0", "LoadRaw"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Diagnostics\\Raw;DataHandling\\Raw"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSESANS.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSESANS.h index d2af4e82ce4..300403b5dc8 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadSESANS.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSESANS.h @@ -51,6 +51,9 @@ public: const std::string name() const override; const std::string summary() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"SaveSESANS"}; + } const std::string category() const override; int confidence(Kernel::FileDescriptor &descriptor) const override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSINQFocus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSINQFocus.h index 14e8c752579..7bed907b117 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadSINQFocus.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSINQFocus.h @@ -55,6 +55,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LoadSINQ", "LoadSINQFile"}; + } const std::string category() const override; /// Returns a confidence value that this algorithm can load a file diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h index 6ded9e3c081..68aa0af8ac9 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSNSspec.h @@ -58,6 +58,9 @@ public: } int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadSpec"}; + } const std::string category() const override { return "DataHandling\\Text"; } /// Returns a confidence value that this algorithm can load a file diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSPE.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSPE.h index 4b7893dcd77..29d269c26ff 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadSPE.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSPE.h @@ -52,6 +52,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SaveSPE"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\SPE;Inelastic\\DataHandling"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSampleDetailsFromRaw.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSampleDetailsFromRaw.h index 99c75422620..c898cb038b8 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadSampleDetailsFromRaw.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSampleDetailsFromRaw.h @@ -54,6 +54,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"LoadRaw"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Raw;Sample"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSpec.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSpec.h index 4fcfdabb54d..5eb20bb45b7 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadSpec.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSpec.h @@ -57,6 +57,9 @@ public: } int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadSNSspec"}; + } const std::string category() const override { return "DataHandling\\Text"; } private: diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h index 2553c519928..4552c15f71b 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h @@ -62,6 +62,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadSpiceAscii", "LoadSpiceXML2DDet"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Text;SANS\\DataHandling"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceAscii.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceAscii.h index ef02ed6e6c6..017f844650d 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceAscii.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceAscii.h @@ -37,6 +37,9 @@ class DLLExport LoadSpiceAscii : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LoadSpice2D", "LoadSpiceXML2DDet"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceXML2DDet.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceXML2DDet.h index 8edc6f39906..3129bdbfc31 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceXML2DDet.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceXML2DDet.h @@ -69,6 +69,9 @@ public: /// Algorithm version int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LoadSpice2D"}; + } /// Category const std::string category() const override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadTBL.h b/Framework/DataHandling/inc/MantidDataHandling/LoadTBL.h index 7ada633b4f1..5f202b0a116 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadTBL.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadTBL.h @@ -48,6 +48,9 @@ public: /// The version number int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"SaveTBL"}; + } /// The category const std::string category() const override { return "DataHandling\\Text"; } /// Returns a confidence value that this algorithm can load a file diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadTOFRawNexus.h b/Framework/DataHandling/inc/MantidDataHandling/LoadTOFRawNexus.h index 83db10f2857..1c104389e45 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadTOFRawNexus.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadTOFRawNexus.h @@ -56,6 +56,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadNexus"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Nexus"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadVulcanCalFile.h b/Framework/DataHandling/inc/MantidDataHandling/LoadVulcanCalFile.h index 18fe35888b7..9614a977eac 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadVulcanCalFile.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadVulcanCalFile.h @@ -36,6 +36,12 @@ public: /// Algorithm's version for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"ReadGroupsFromFile", "CreateDummyCalFile", + "CreateCalFileByNames", "AlignDetectors", + "DiffractionFocussing", "LoadCalFile", + "SaveCalFile", "MergeCalFiles"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Text;Diffraction\\DataHandling"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/MaskDetectors.h b/Framework/DataHandling/inc/MantidDataHandling/MaskDetectors.h index eeb72c9fea0..fd2d0d03475 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/MaskDetectors.h +++ b/Framework/DataHandling/inc/MantidDataHandling/MaskDetectors.h @@ -65,6 +65,10 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"MaskDetectorsInShape", "MaskDetectorsIf", "MaskInstrument", + "MaskSpectra", "MaskBTP", "MaskAngle", "InvertMask"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Masking"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/MaskDetectorsInShape.h b/Framework/DataHandling/inc/MantidDataHandling/MaskDetectorsInShape.h index 533fe235fe9..ea22b9e1b00 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/MaskDetectorsInShape.h +++ b/Framework/DataHandling/inc/MantidDataHandling/MaskDetectorsInShape.h @@ -58,6 +58,9 @@ public: const std::string name() const override { return "MaskDetectorsInShape"; }; /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"MaskDetectors", "FindDetectorsInShape"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "Transforms\\Masking"; } /// Summary of algorithms purpose diff --git a/Framework/DataHandling/inc/MantidDataHandling/MaskSpectra.h b/Framework/DataHandling/inc/MantidDataHandling/MaskSpectra.h index ee0a2df9cfa..9c842bfe1ab 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/MaskSpectra.h +++ b/Framework/DataHandling/inc/MantidDataHandling/MaskSpectra.h @@ -39,6 +39,9 @@ class MANTID_DATAHANDLING_DLL MaskSpectra : public API::DistributedAlgorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"MaskDetectors"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/MergeLogs.h b/Framework/DataHandling/inc/MantidDataHandling/MergeLogs.h index 7489b04a7e8..14b20e692d7 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/MergeLogs.h +++ b/Framework/DataHandling/inc/MantidDataHandling/MergeLogs.h @@ -45,6 +45,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"AddTimeSeriesLog"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Logs"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/ModifyDetectorDotDatFile.h b/Framework/DataHandling/inc/MantidDataHandling/ModifyDetectorDotDatFile.h index 7c0c85e4607..4783666f48c 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/ModifyDetectorDotDatFile.h +++ b/Framework/DataHandling/inc/MantidDataHandling/ModifyDetectorDotDatFile.h @@ -48,6 +48,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"ResizeRectangularDetector"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Instrument"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/MoveInstrumentComponent.h b/Framework/DataHandling/inc/MantidDataHandling/MoveInstrumentComponent.h index d556d560520..3839dc8a3c5 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/MoveInstrumentComponent.h +++ b/Framework/DataHandling/inc/MantidDataHandling/MoveInstrumentComponent.h @@ -71,6 +71,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"RotateInstrumentComponent", "SetInstrumentParameter"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Instrument"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/PatchBBY.h b/Framework/DataHandling/inc/MantidDataHandling/PatchBBY.h index c2001589b99..dc12118760c 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/PatchBBY.h +++ b/Framework/DataHandling/inc/MantidDataHandling/PatchBBY.h @@ -47,6 +47,9 @@ class DLLExport PatchBBY : public API::Algorithm { public: // description int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadBBY"}; + } const std::string name() const override { return "PatchBBY"; } const std::string category() const override { return "DataHandling\\ANSTO"; } const std::string summary() const override { diff --git a/Framework/DataHandling/inc/MantidDataHandling/RawFileInfo.h b/Framework/DataHandling/inc/MantidDataHandling/RawFileInfo.h index f2be39a103e..e73bd721436 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/RawFileInfo.h +++ b/Framework/DataHandling/inc/MantidDataHandling/RawFileInfo.h @@ -71,6 +71,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"LoadRaw"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Raw"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/RemoveLogs.h b/Framework/DataHandling/inc/MantidDataHandling/RemoveLogs.h index 2e2354bd5df..976bccc342f 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/RemoveLogs.h +++ b/Framework/DataHandling/inc/MantidDataHandling/RemoveLogs.h @@ -86,6 +86,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"RenameLog", "DeleteLog"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Logs"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/RenameLog.h b/Framework/DataHandling/inc/MantidDataHandling/RenameLog.h index 936ff1012d7..eeea4eb47e4 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/RenameLog.h +++ b/Framework/DataHandling/inc/MantidDataHandling/RenameLog.h @@ -43,6 +43,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"RemoveLogs", "DeleteLog"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Logs"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/RotateInstrumentComponent.h b/Framework/DataHandling/inc/MantidDataHandling/RotateInstrumentComponent.h index 1b6cb651bd9..0bab2f84414 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/RotateInstrumentComponent.h +++ b/Framework/DataHandling/inc/MantidDataHandling/RotateInstrumentComponent.h @@ -70,6 +70,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"MoveInstrumentComponent", "SetInstrumentParameter"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Instrument"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/RotateSource.h b/Framework/DataHandling/inc/MantidDataHandling/RotateSource.h index 40938148a8f..2eebef20dc0 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/RotateSource.h +++ b/Framework/DataHandling/inc/MantidDataHandling/RotateSource.h @@ -36,6 +36,9 @@ class DLLExport RotateSource : public API::Algorithm { public: const std::string name() const override { return "RotateSource"; }; int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"RotateInstrumentComponent"}; + } const std::string category() const override { return "DataHandling\\Instrument"; }; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveANSTOAscii.h b/Framework/DataHandling/inc/MantidDataHandling/SaveANSTOAscii.h index 5cd322be4f1..c716e3f12ed 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveANSTOAscii.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveANSTOAscii.h @@ -48,6 +48,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"SaveAscii"}; + } private: /// Return the file extension this algorthm should output. diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h b/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h index a78c28d12aa..899e9eb803b 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h @@ -50,6 +50,12 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { + return {"LoadAscii", "SaveANSTOAscii", "SaveCSV", "SaveDiffFittingAscii", + "SaveILLCosmosAscii", "SaveReflCustomAscii", + "SaveReflThreeColumnAscii", "SaveOpenGenieAscii", "SaveGSS", + "SaveFocusedXYE"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Text"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveCSV.h b/Framework/DataHandling/inc/MantidDataHandling/SaveCSV.h index 2e60283a4f5..5fad0d6a2a7 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveCSV.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveCSV.h @@ -93,6 +93,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SaveAscii"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Text"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveCalFile.h b/Framework/DataHandling/inc/MantidDataHandling/SaveCalFile.h index e42f8268571..6e801b78f2f 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveCalFile.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveCalFile.h @@ -29,6 +29,12 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"ReadGroupsFromFile", "CreateDummyCalFile", + "CreateCalFileByNames", "AlignDetectors", + "DiffractionFocussing", "LoadCalFile", + "MergeCalFiles"}; + } /// Algorithm's category for identification const std::string category() const override { return R"(DataHandling\Text;Diffraction\DataHandling\CalFiles)"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveCanSAS1D2.h b/Framework/DataHandling/inc/MantidDataHandling/SaveCanSAS1D2.h index 8763bb1052a..de4678a9dcc 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveCanSAS1D2.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveCanSAS1D2.h @@ -79,6 +79,9 @@ Code Documentation is available at: <http://doxygen.mantidproject.org> class DLLExport SaveCanSAS1D2 : public SaveCanSAS1D { public: int version() const override { return 2; } + const std::vector<std::string> seeAlso() const override { + return {"LoadCanSAS1D"}; + } protected: /// Extends the SaveCanSAS1D init method diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveDaveGrp.h b/Framework/DataHandling/inc/MantidDataHandling/SaveDaveGrp.h index c7f5b5cae24..82380bf8367 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveDaveGrp.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveDaveGrp.h @@ -54,6 +54,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadDaveGrp"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Text;Inelastic\\DataHandling"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveDetectorsGrouping.h b/Framework/DataHandling/inc/MantidDataHandling/SaveDetectorsGrouping.h index 52796fc12a7..fecebb64053 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveDetectorsGrouping.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveDetectorsGrouping.h @@ -44,6 +44,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadDetectorsGroupingFile", "GroupDetectors"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Grouping;Transforms\\Grouping"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveDiffCal.h b/Framework/DataHandling/inc/MantidDataHandling/SaveDiffCal.h index 74c30be7a4a..d1ae5a69a2d 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveDiffCal.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveDiffCal.h @@ -40,6 +40,9 @@ class DLLExport SaveDiffCal : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LoadDiffCal"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveDiffFittingAscii.h b/Framework/DataHandling/inc/MantidDataHandling/SaveDiffFittingAscii.h index 4b0c21dd82f..5b619ca6f59 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveDiffFittingAscii.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveDiffFittingAscii.h @@ -28,6 +28,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"EnggFitPeaks", "SaveAscii"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Text"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveFITS.h b/Framework/DataHandling/inc/MantidDataHandling/SaveFITS.h index ea59057a006..dff9928d773 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveFITS.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveFITS.h @@ -37,6 +37,9 @@ public: const std::string name() const override final; int version() const override final; + const std::vector<std::string> seeAlso() const override { + return {"LoadFITS", "SaveNXTomo"}; + } const std::string category() const override final; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveFocusedXYE.h b/Framework/DataHandling/inc/MantidDataHandling/SaveFocusedXYE.h index 7da884dc5cc..7d71c447173 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveFocusedXYE.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveFocusedXYE.h @@ -69,6 +69,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SaveFullprofResolution", "SaveAscii"}; + } /// Algorithm's category for identification const std::string category() const override { return "Diffraction\\DataHandling;DataHandling\\Text"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveFullprofResolution.h b/Framework/DataHandling/inc/MantidDataHandling/SaveFullprofResolution.h index 5b1fce6e8b8..30dbb51d582 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveFullprofResolution.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveFullprofResolution.h @@ -44,6 +44,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SaveFocusedXYE"}; + } /// Algorithm's category for identification const std::string category() const override { return "Diffraction\\DataHandling;DataHandling\\Text"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveGSASInstrumentFile.h b/Framework/DataHandling/inc/MantidDataHandling/SaveGSASInstrumentFile.h index e4ec6e647f5..6ce5acae91d 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveGSASInstrumentFile.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveGSASInstrumentFile.h @@ -50,6 +50,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"LoadGSASInstrumentFile", "SaveGSS"}; + } /// Algorithm's category for identification const std::string category() const override { return "Diffraction\\DataHandling"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveGSS.h b/Framework/DataHandling/inc/MantidDataHandling/SaveGSS.h index bc4c870cf25..6c1124c070b 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveGSS.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveGSS.h @@ -80,6 +80,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"LoadGSS", "SaveVulcanGSS", "SaveGSASInstrumentFile", "SaveAscii"}; + } /// Algorithm's category for identification const std::string category() const override { return "Diffraction\\DataHandling;DataHandling\\Text"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveILLCosmosAscii.h b/Framework/DataHandling/inc/MantidDataHandling/SaveILLCosmosAscii.h index a21a7709ed4..598759ad8f1 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveILLCosmosAscii.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveILLCosmosAscii.h @@ -49,6 +49,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"SaveAscii"}; + } private: /// Return the file extension this algorthm should output. diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveISISNexus.h b/Framework/DataHandling/inc/MantidDataHandling/SaveISISNexus.h index 4c070da9edc..963c5e96447 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveISISNexus.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveISISNexus.h @@ -58,6 +58,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SaveNexusProcessed", "SaveNexus", "LoadNexus"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Nexus"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveIsawDetCal.h b/Framework/DataHandling/inc/MantidDataHandling/SaveIsawDetCal.h index 68970bb983a..8aab2423c5c 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveIsawDetCal.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveIsawDetCal.h @@ -45,6 +45,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadIsawDetCal"}; + } /// Algorithm's category for identification const std::string category() const override { return "Diffraction\\DataHandling;DataHandling\\Isaw"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveMask.h b/Framework/DataHandling/inc/MantidDataHandling/SaveMask.h index d3c06e9be40..e7ddb70ce27 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveMask.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveMask.h @@ -43,6 +43,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SaveMask", "LoadMask"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Masking;Transforms\\Masking"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveNXSPE.h b/Framework/DataHandling/inc/MantidDataHandling/SaveNXSPE.h index d0864a389fa..4e9a4116f28 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveNXSPE.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveNXSPE.h @@ -45,6 +45,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"LoadNXSPE", "SaveSPE"}; + } /// Algorithm's category for identification const std::string category() const override { return R"(DataHandling\Nexus;DataHandling\SPE;Inelastic\DataHandling)"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveNXTomo.h b/Framework/DataHandling/inc/MantidDataHandling/SaveNXTomo.h index 1884a315586..562a6d86b08 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveNXTomo.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveNXTomo.h @@ -60,6 +60,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SaveNexusProcessed"}; + } /// Algorithm's category for identification const std::string category() const override { diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveNXcanSAS.h b/Framework/DataHandling/inc/MantidDataHandling/SaveNXcanSAS.h index 8c9541ef206..62bbbbe7ce3 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveNXcanSAS.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveNXcanSAS.h @@ -45,6 +45,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SaveCanSAS1D", "LoadNXcanSAS"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Nexus"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveNexus.h b/Framework/DataHandling/inc/MantidDataHandling/SaveNexus.h index 98d7c344d6f..12b09027ad3 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveNexus.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveNexus.h @@ -55,6 +55,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SaveISISNexus", "SaveNexusPD", "SaveNexusProcessed", "LoadNexus"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Nexus"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h b/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h index 5c3a7f73062..c3e23960fae 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h @@ -62,6 +62,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SaveISISNexus", "SaveNexus", "LoadNexusProcessed"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Nexus"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveOpenGenieAscii.h b/Framework/DataHandling/inc/MantidDataHandling/SaveOpenGenieAscii.h index 7b50c4f0141..de5947fd4a8 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveOpenGenieAscii.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveOpenGenieAscii.h @@ -26,6 +26,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SaveAscii"}; + } /// Algorithm's category for identification const std::string category() const override { diff --git a/Framework/DataHandling/inc/MantidDataHandling/SavePAR.h b/Framework/DataHandling/inc/MantidDataHandling/SavePAR.h index 47569287cac..b223398d7dd 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SavePAR.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SavePAR.h @@ -68,6 +68,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SaveSPE"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\SPE;Inelastic\\DataHandling"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SavePDFGui.h b/Framework/DataHandling/inc/MantidDataHandling/SavePDFGui.h index 43f0ee8259d..ef1455272cc 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SavePDFGui.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SavePDFGui.h @@ -34,6 +34,9 @@ class DLLExport SavePDFGui : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"SaveAscii"}; + } const std::string category() const override; const std::string summary() const override; std::map<std::string, std::string> validateInputs() override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SavePHX.h b/Framework/DataHandling/inc/MantidDataHandling/SavePHX.h index 85a87d9784d..4244b99431e 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SavePHX.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SavePHX.h @@ -53,6 +53,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SaveSPE"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\SPE;Inelastic\\DataHandling"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveParameterFile.h b/Framework/DataHandling/inc/MantidDataHandling/SaveParameterFile.h index 780ed0bb1e8..4f2fe27a236 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveParameterFile.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveParameterFile.h @@ -44,6 +44,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LoadParameterFile"}; + } const std::string category() const override; private: diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveRKH.h b/Framework/DataHandling/inc/MantidDataHandling/SaveRKH.h index 846b94d51bd..0dbf4c0197e 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveRKH.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveRKH.h @@ -54,6 +54,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"LoadRKH"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Text"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveReflCustomAscii.h b/Framework/DataHandling/inc/MantidDataHandling/SaveReflCustomAscii.h index ddaa6abdaa7..b4e5d837912 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveReflCustomAscii.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveReflCustomAscii.h @@ -48,6 +48,9 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"SaveReflThreeColumnAscii", "SaveAscii"}; + } /// void data(std::ofstream &file, const std::vector<double> &XData, diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveReflThreeColumnAscii.h b/Framework/DataHandling/inc/MantidDataHandling/SaveReflThreeColumnAscii.h index daa9664c0ee..6bf26dd3880 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveReflThreeColumnAscii.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveReflThreeColumnAscii.h @@ -50,6 +50,9 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"SaveReflCustomAscii", "SaveAscii"}; + } /// Algorithm's version for data output overriding a virtual method void data(std::ofstream &file, const std::vector<double> &XData, bool exportDeltaQ = false) override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveSESANS.h b/Framework/DataHandling/inc/MantidDataHandling/SaveSESANS.h index 185f10b0cbf..13e4b95071d 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveSESANS.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveSESANS.h @@ -54,6 +54,9 @@ public: const std::string name() const override; const std::string summary() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LoadSESANS"}; + } const std::string category() const override; std::map<std::string, std::string> validateInputs() override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveSPE.h b/Framework/DataHandling/inc/MantidDataHandling/SaveSPE.h index 1a1dc408346..c09ae5d2845 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveSPE.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveSPE.h @@ -57,6 +57,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"LoadSPE", "SavePAR", "SavePHX"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\SPE;Inelastic\\DataHandling"; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveTBL.h b/Framework/DataHandling/inc/MantidDataHandling/SaveTBL.h index 5f82e9098f8..b80c6798d0a 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveTBL.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveTBL.h @@ -49,6 +49,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"LoadTBL"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Text"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveToSNSHistogramNexus.h b/Framework/DataHandling/inc/MantidDataHandling/SaveToSNSHistogramNexus.h index dc53024f175..aeed901d4ad 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SaveToSNSHistogramNexus.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SaveToSNSHistogramNexus.h @@ -60,6 +60,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SaveNexus"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Nexus"; } diff --git a/Framework/DataHandling/inc/MantidDataHandling/SetBeam.h b/Framework/DataHandling/inc/MantidDataHandling/SetBeam.h index c947ebbd142..56a10b05966 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SetBeam.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SetBeam.h @@ -34,6 +34,9 @@ class MANTID_DATAHANDLING_DLL SetBeam final : public API::Algorithm { public: const std::string name() const override final; int version() const override final; + const std::vector<std::string> seeAlso() const override { + return {"SetSample"}; + } const std::string category() const override final; const std::string summary() const override final; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SetSample.h b/Framework/DataHandling/inc/MantidDataHandling/SetSample.h index 6769bd955b1..b5a855904dd 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SetSample.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SetSample.h @@ -40,6 +40,9 @@ class MANTID_DATAHANDLING_DLL SetSample final : public API::Algorithm { public: const std::string name() const override final; int version() const override final; + const std::vector<std::string> seeAlso() const override { + return {"SetSampleMaterial", "CopySample", "SetBeam"}; + } const std::string category() const override final; const std::string summary() const override final; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SetSampleMaterial.h b/Framework/DataHandling/inc/MantidDataHandling/SetSampleMaterial.h index a4e0461fdbe..573251000e4 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SetSampleMaterial.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SetSampleMaterial.h @@ -47,6 +47,10 @@ public: /// Algorithm's version int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"AbsorptionCorrection", "CreateSampleShape", + "CalculateSampleTransmission"}; + } /// Algorithm's category for identification const std::string category() const override; std::map<std::string, std::string> validateInputs() override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/SortTableWorkspace.h b/Framework/DataHandling/inc/MantidDataHandling/SortTableWorkspace.h index 22ac676da17..a165dce8bf6 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/SortTableWorkspace.h +++ b/Framework/DataHandling/inc/MantidDataHandling/SortTableWorkspace.h @@ -34,6 +34,9 @@ class DLLExport SortTableWorkspace : public API::ParallelAlgorithm { public: const std::string name() const override { return "SortTableWorkspace"; } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CreateEmptyTableWorkspace"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/DataHandling/inc/MantidDataHandling/UpdateInstrumentFromFile.h b/Framework/DataHandling/inc/MantidDataHandling/UpdateInstrumentFromFile.h index c19f353f5df..13b140d5660 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/UpdateInstrumentFromFile.h +++ b/Framework/DataHandling/inc/MantidDataHandling/UpdateInstrumentFromFile.h @@ -69,6 +69,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadInstrument"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { diff --git a/Framework/DataHandling/src/LoadMask.cpp b/Framework/DataHandling/src/LoadMask.cpp index ebf95f91f86..10661889d02 100644 --- a/Framework/DataHandling/src/LoadMask.cpp +++ b/Framework/DataHandling/src/LoadMask.cpp @@ -531,9 +531,7 @@ void LoadMask::processMaskOnWorkspaceIndex(bool mask, // 3. Set mask auto spec0 = maskedSpecID[0]; auto prev_masks = spec0; - for (size_t i = 0; i < maskedSpecID.size(); i++) { - - auto spec2mask = maskedSpecID[i]; + for (int spec2mask : maskedSpecID) { s2iter = s2imap.find(spec2mask); if (s2iter == s2imap.end()) { @@ -703,19 +701,18 @@ void LoadMask::convertSpMasksToDetIDs(const API::MatrixWorkspace &sourceWS, sourceWS.getDetectorIDToWorkspaceIndexMap(false); std::multimap<size_t, Mantid::detid_t> spectr2index_map; - for (auto it = sourceDetMap.begin(); it != sourceDetMap.end(); it++) { + for (auto &it : sourceDetMap) { spectr2index_map.insert( - std::pair<size_t, Mantid::detid_t>(it->second, it->first)); + std::pair<size_t, Mantid::detid_t>(it.second, it.first)); } spec2index_map new_map; - for (size_t i = 0; i < maskedSpecID.size(); i++) { + for (int i : maskedSpecID) { // find spectra number from spectra ID for the source workspace - const auto itSpec = s2imap.find(maskedSpecID[i]); + const auto itSpec = s2imap.find(i); if (itSpec == s2imap.end()) { - throw std::runtime_error( - "Can not find spectra with ID: " + - boost::lexical_cast<std::string>(maskedSpecID[i]) + - " in the workspace" + sourceWS.getName()); + throw std::runtime_error("Can not find spectra with ID: " + + boost::lexical_cast<std::string>(i) + + " in the workspace" + sourceWS.getName()); } size_t specN = itSpec->second; diff --git a/Framework/DataHandling/src/LoadNexusProcessed.cpp b/Framework/DataHandling/src/LoadNexusProcessed.cpp index 233a1faf072..a8c1164f786 100644 --- a/Framework/DataHandling/src/LoadNexusProcessed.cpp +++ b/Framework/DataHandling/src/LoadNexusProcessed.cpp @@ -1155,6 +1155,14 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) { if (ival != -1) peakWS->getPeak(r).setRunNumber(ival); } + } else if (str == "column_17") { + NXInt nxInt = nx_tw.openNXInt(str); + nxInt.load(); + + for (int r = 0; r < numberPeaks; r++) { + int ival = nxInt[r]; + peakWS->getPeak(r).setPeakNumber(ival); + } } else if (str == "column_15") { NXDouble nxDouble = nx_tw.openNXDouble(str); nxDouble.load(); diff --git a/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp b/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp index 725bcfd9be1..31deaced985 100644 --- a/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp +++ b/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp @@ -669,20 +669,17 @@ MatrixWorkspace_sptr LoadSpiceXML2DDet::createMatrixWorkspaceVersion2( } // END-FOR (xml nodes) // Add the property to output workspace - for (std::map<std::string, std::string>::iterator miter = str_log_map.begin(); - miter != str_log_map.end(); ++miter) { + for (auto &log_entry : str_log_map) { outws->mutableRun().addProperty( - new PropertyWithValue<std::string>(miter->first, miter->second)); + new PropertyWithValue<std::string>(log_entry.first, log_entry.second)); } - for (std::map<std::string, int>::iterator miter = int_log_map.begin(); - miter != int_log_map.end(); ++miter) { + for (auto &log_entry : int_log_map) { outws->mutableRun().addProperty( - new PropertyWithValue<int>(miter->first, miter->second)); + new PropertyWithValue<int>(log_entry.first, log_entry.second)); } - for (std::map<std::string, double>::iterator miter = dbl_log_map.begin(); - miter != dbl_log_map.end(); ++miter) { + for (auto &log_entry : dbl_log_map) { outws->mutableRun().addProperty( - new PropertyWithValue<double>(miter->first, miter->second)); + new PropertyWithValue<double>(log_entry.first, log_entry.second)); } // Raise exception if no detector node is found @@ -713,10 +710,10 @@ LoadSpiceXML2DDet::parseDetectorNode(const std::string &detvaluestr, // file records data in column major) size_t num_empty_line = 0; size_t num_weird_line = 0; - for (size_t iline = 0; iline < vecLines.size(); ++iline) { - if (vecLines[iline].empty()) + for (auto &vecLine : vecLines) { + if (vecLine.empty()) ++num_empty_line; - else if (vecLines[iline].size() < 100) + else if (vecLine.size() < 100) ++num_weird_line; } size_t num_pixel_x = vecLines.size() - num_empty_line - num_weird_line; diff --git a/Framework/DataHandling/src/ParallelEventLoader.cpp b/Framework/DataHandling/src/ParallelEventLoader.cpp index 90a7522fa79..d8c240ba489 100644 --- a/Framework/DataHandling/src/ParallelEventLoader.cpp +++ b/Framework/DataHandling/src/ParallelEventLoader.cpp @@ -59,11 +59,11 @@ std::vector<int32_t> bankOffsetsSpectrumNumbers( const auto &specNums = ws.indexInfo().spectrumNumbers(); int32_t spectrumIndex{0}; // *global* index std::vector<int32_t> bankOffsets(bankNames.size(), 0); - for (size_t i = 0; i < specNums.size(); ++i) { + for (auto i : specNums) { // In contrast to the case of event ID = detector ID we know that any // spectrum number has a corresponding event ID, i.e., we do not need // special handling for monitors. - specnum_t specNum = static_cast<specnum_t>(specNums[i]); + specnum_t specNum = static_cast<specnum_t>(i); // See comment in bankOffsets regarding this offset computation. if (idToBank.count(specNum) == 1) { size_t bank = idToBank.at(specNum); diff --git a/Framework/DataHandling/src/SaveAscii2.cpp b/Framework/DataHandling/src/SaveAscii2.cpp index f254010925e..b8199fa5104 100644 --- a/Framework/DataHandling/src/SaveAscii2.cpp +++ b/Framework/DataHandling/src/SaveAscii2.cpp @@ -268,8 +268,8 @@ void SaveAscii2::exec() { } } else { Progress progress(this, 0.0, 1.0, idx.size()); - for (auto i = idx.begin(); i != idx.end(); ++i) { - writeSpectrum(*i, file); + for (int i : idx) { + writeSpectrum(i, file); progress.report(); } } diff --git a/Framework/DataHandling/src/SaveGSS.cpp b/Framework/DataHandling/src/SaveGSS.cpp index d9873b66173..dd1410209b8 100644 --- a/Framework/DataHandling/src/SaveGSS.cpp +++ b/Framework/DataHandling/src/SaveGSS.cpp @@ -442,9 +442,8 @@ void SaveGSS::generateInstrumentHeader(std::stringstream &out, // write user header first if (m_user_specified_gsas_header.size() > 0) { - for (auto iter = m_user_specified_gsas_header.begin(); - iter != m_user_specified_gsas_header.end(); ++iter) { - out << *iter << "\n"; + for (const auto &iter : m_user_specified_gsas_header) { + out << iter << "\n"; } } diff --git a/Framework/DataHandling/test/FindDetectorsParTest.h b/Framework/DataHandling/test/FindDetectorsParTest.h index a55f1b77af5..5d9785001ad 100644 --- a/Framework/DataHandling/test/FindDetectorsParTest.h +++ b/Framework/DataHandling/test/FindDetectorsParTest.h @@ -490,8 +490,8 @@ private: cont[2] = " 2. 3. -4. 5. 6. 2"; std::ofstream testFile(fileName); - for (size_t i = 0; i < cont.size(); i++) { - testFile << cont[i] << '\n'; + for (const auto &i : cont) { + testFile << i << '\n'; } testFile.close(); } @@ -503,8 +503,8 @@ private: cont[3] = "3. 4. -5. 6. 7. 3"; std::ofstream testFile(fileName); - for (size_t i = 0; i < cont.size(); i++) { - testFile << cont[i] << '\n'; + for (const auto &i : cont) { + testFile << i << '\n'; } testFile.close(); } @@ -516,8 +516,8 @@ private: cont[3] = "10 0 5.000 6.000 7.000 8.0000 3"; std::ofstream testFile(fileName); - for (size_t i = 0; i < cont.size(); i++) { - testFile << cont[i] << '\n'; + for (const auto &i : cont) { + testFile << i << '\n'; } testFile.close(); } @@ -527,8 +527,8 @@ private: cont[1] = "10 0 5.000 6.000 7.000 8.0000 1"; std::ofstream testFile(fileName); - for (size_t i = 0; i < cont.size(); i++) { - testFile << cont[i] << '\n'; + for (const auto &i : cont) { + testFile << i << '\n'; } testFile.close(); } diff --git a/Framework/DataHandling/test/LoadCalFileTest.h b/Framework/DataHandling/test/LoadCalFileTest.h index 2dfcf9897d6..d4724f78271 100644 --- a/Framework/DataHandling/test/LoadCalFileTest.h +++ b/Framework/DataHandling/test/LoadCalFileTest.h @@ -125,8 +125,8 @@ public: } void tearDown() override { - for (size_t i = 0; i < loadAlgPtrArray.size(); i++) { - delete loadAlgPtrArray[i]; + for (auto &i : loadAlgPtrArray) { + delete i; } loadAlgPtrArray.clear(); diff --git a/Framework/DataHandling/test/LoadDetectorInfoTest.h b/Framework/DataHandling/test/LoadDetectorInfoTest.h index d7fe7bcb642..dbdf5437653 100644 --- a/Framework/DataHandling/test/LoadDetectorInfoTest.h +++ b/Framework/DataHandling/test/LoadDetectorInfoTest.h @@ -69,13 +69,14 @@ void writeSmallDatFile(const std::string &filename) { " w_y w_z f_x f_y f_z a_x " " a_y a_z det_1 det_2 det_3 " "det4\n"; - for (int i = 0; i < SmallTestDatFile::NDETECTS; ++i) { - file << i << "\t" << delta[i] << "\t" << det_l2[i] << "\t" << code[i] - << "\t" << det_theta[i] << "\t" << det_phi[i] << "\t" << NOTUSED - << "\t" << NOTUSED << "\t" << NOTUSED << "\t" << NOTUSED << "\t" + for (int detector = 0; detector < SmallTestDatFile::NDETECTS; ++detector) { + file << detector << "\t" << delta[detector] << "\t" << det_l2[detector] + << "\t" << code[detector] << "\t" << det_theta[detector] << "\t" + << det_phi[detector] << "\t" << NOTUSED << "\t" << NOTUSED << "\t" << NOTUSED << "\t" << NOTUSED << "\t" << NOTUSED << "\t" << NOTUSED - << "\t" << NOTUSED << "\t" << NOTUSED << "\t" << pressure[i] << "\t" - << wallThick[i] << "\t" << NOTUSED << '\n'; + << "\t" << NOTUSED << "\t" << NOTUSED << "\t" << NOTUSED << "\t" + << NOTUSED << "\t" << pressure[detector] << "\t" << wallThick[detector] + << "\t" << NOTUSED << '\n'; } file.close(); } @@ -301,8 +302,8 @@ public: // read the parameters from some random detectors, they're parameters are // all set to the same thing - for (int i = 0; i < NUMRANDOM; ++i) { - const size_t detIndex = detInfo.indexOf(DETECTS[i]); + for (int detector : DETECTS) { + const size_t detIndex = detInfo.indexOf(detector); const auto &det = detInfo.detector(detIndex); Parameter_sptr par = pmap.getRecursive(&det, "TubePressure"); diff --git a/Framework/DataHandling/test/LoadEventNexusTest.h b/Framework/DataHandling/test/LoadEventNexusTest.h index 5dc3e8407b3..c49541b5900 100644 --- a/Framework/DataHandling/test/LoadEventNexusTest.h +++ b/Framework/DataHandling/test/LoadEventNexusTest.h @@ -295,9 +295,9 @@ public: double max = events.begin()->tof(); double min = events.begin()->tof(); - for (size_t j = 0; j < events.size(); ++j) { - max = events[j].tof() > max ? events[j].tof() : max; - min = events[j].tof() < min ? events[j].tof() : min; + for (auto &event : events) { + max = event.tof() > max ? event.tof() : max; + min = event.tof() < min ? event.tof() : min; } TSM_ASSERT("The max TOF in the workspace should be equal to or less than " "the filtered cut-off", diff --git a/Framework/DataHandling/test/LoadEventPreNexus2Test.h b/Framework/DataHandling/test/LoadEventPreNexus2Test.h index 35bb8cd208d..9203e17325b 100644 --- a/Framework/DataHandling/test/LoadEventPreNexus2Test.h +++ b/Framework/DataHandling/test/LoadEventPreNexus2Test.h @@ -135,8 +135,8 @@ public: Types::Core::DateAndTime start = it->first; std::vector<TofEvent> events1 = ew->getSpectrum(1000).getEvents(); - for (size_t i = 0; i < events1.size(); i++) { - std::cout << (events1[i].pulseTime() - start) << " sec \n"; + for (auto &event : events1) { + std::cout << (event.pulseTime() - start) << " sec \n"; } } diff --git a/Framework/DataHandling/test/LoadMaskTest.h b/Framework/DataHandling/test/LoadMaskTest.h index dc3f1db1fcf..9e10583d305 100644 --- a/Framework/DataHandling/test/LoadMaskTest.h +++ b/Framework/DataHandling/test/LoadMaskTest.h @@ -532,8 +532,8 @@ public: ss << "</detids>\n"; } - for (size_t i = 0; i < banks.size(); i++) { - ss << "<component>bank" << banks[i] << "</component>\n"; + for (int bank : banks) { + ss << "<component>bank" << bank << "</component>\n"; } // 4. End of file @@ -552,8 +552,8 @@ public: std::stringstream ss; // 1. Single spectra - for (size_t i = 0; i < singlespectra.size(); i++) { - ss << singlespectra[i] << " "; + for (int i : singlespectra) { + ss << i << " "; } ss << '\n'; diff --git a/Framework/DataHandling/test/LoadNexusMonitorsTest.h b/Framework/DataHandling/test/LoadNexusMonitorsTest.h index 7051fab7658..b1a87e19a1e 100644 --- a/Framework/DataHandling/test/LoadNexusMonitorsTest.h +++ b/Framework/DataHandling/test/LoadNexusMonitorsTest.h @@ -167,8 +167,8 @@ public: // Count output workspaces int ws_count = 0; auto props = ld1.getProperties(); - for (auto iter = props.begin(); iter != props.end(); ++iter) - if ((*iter)->type() == "Workspace") + for (auto &prop : props) + if (prop->type() == "Workspace") ws_count++; // Version 1 has an issue that produces additional output workspaces for @@ -191,8 +191,8 @@ public: // Count output workspaces ws_count = 0; props = ld2.getProperties(); - for (auto iter = props.begin(); iter != props.end(); ++iter) - if ((*iter)->type() == "Workspace") + for (auto &prop : props) + if (prop->type() == "Workspace") ws_count++; // Version 2 always produces one OutputWorkspace, which may be a group diff --git a/Framework/DataHandling/test/LoadTest.h b/Framework/DataHandling/test/LoadTest.h index 55305d0dbeb..8ffc38e739f 100644 --- a/Framework/DataHandling/test/LoadTest.h +++ b/Framework/DataHandling/test/LoadTest.h @@ -112,16 +112,16 @@ public: const char *loadraw_props[NUMPROPS] = { "SpectrumMin", "SpectrumMax", "SpectrumList", "Cache", "LoadLogFiles"}; // Basic load has no additional loader properties - for (size_t i = 0; i < NUMPROPS; ++i) { - TS_ASSERT_EQUALS(loader.existsProperty(loadraw_props[i]), false); + for (auto &loadraw_prop : loadraw_props) { + TS_ASSERT_EQUALS(loader.existsProperty(loadraw_prop), false); } // After setting the file property, the algorithm should have aquired the // appropriate properties TS_ASSERT_THROWS_NOTHING( loader.setPropertyValue("Filename", "IRS38633.raw")); // Now - for (size_t i = 0; i < NUMPROPS; ++i) { - TS_ASSERT_EQUALS(loader.existsProperty(loadraw_props[i]), true); + for (auto &loadraw_prop : loadraw_props) { + TS_ASSERT_EQUALS(loader.existsProperty(loadraw_prop), true); } // Did it find the right loader diff --git a/Framework/DataHandling/test/SaveAscii2Test.h b/Framework/DataHandling/test/SaveAscii2Test.h index c3b86dacfdc..26ef97cb2da 100644 --- a/Framework/DataHandling/test/SaveAscii2Test.h +++ b/Framework/DataHandling/test/SaveAscii2Test.h @@ -68,8 +68,8 @@ public: std::getline(in, binlines); boost::split(binstr, binlines, boost::is_any_of(",")); - for (size_t i = 0; i < binstr.size(); i++) { - bins.push_back(boost::lexical_cast<double>(binstr.at(i))); + for (const auto &i : binstr) { + bins.push_back(boost::lexical_cast<double>(i)); } TS_ASSERT_EQUALS(bins[0], 0); TS_ASSERT_EQUALS(bins[1], 2); @@ -78,8 +78,8 @@ public: std::getline(in, binlines); bins.clear(); boost::split(binstr, binlines, boost::is_any_of(",")); - for (size_t i = 0; i < binstr.size(); i++) { - bins.push_back(boost::lexical_cast<double>(binstr.at(i))); + for (const auto &i : binstr) { + bins.push_back(boost::lexical_cast<double>(i)); } TS_ASSERT_EQUALS(bins[0], 1.66667); TS_ASSERT_EQUALS(bins[1], 8.66667); @@ -165,8 +165,8 @@ public: std::getline(in, binlines); boost::split(binstr, binlines, boost::is_any_of(",")); - for (size_t i = 0; i < binstr.size(); i++) { - bins.push_back(boost::lexical_cast<double>(binstr.at(i))); + for (const auto &i : binstr) { + bins.push_back(boost::lexical_cast<double>(i)); } TS_ASSERT_EQUALS(bins[0], 0); TS_ASSERT_EQUALS(bins[1], 2); @@ -175,8 +175,8 @@ public: std::getline(in, binlines); bins.clear(); boost::split(binstr, binlines, boost::is_any_of(",")); - for (size_t i = 0; i < binstr.size(); i++) { - bins.push_back(boost::lexical_cast<double>(binstr.at(i))); + for (const auto &i : binstr) { + bins.push_back(boost::lexical_cast<double>(i)); } TS_ASSERT_EQUALS(bins[0], 1.66667); TS_ASSERT_EQUALS(bins[1], 8.66667); @@ -589,8 +589,8 @@ public: std::getline(in, binlines); boost::split(binstr, binlines, boost::is_any_of(",")); - for (size_t i = 0; i < binstr.size(); i++) { - bins.push_back(boost::lexical_cast<double>(binstr.at(i))); + for (const auto &i : binstr) { + bins.push_back(boost::lexical_cast<double>(i)); } TS_ASSERT_EQUALS(bins[0], 0); TS_ASSERT_EQUALS(bins[1], 4); @@ -599,8 +599,8 @@ public: std::getline(in, binlines); bins.clear(); boost::split(binstr, binlines, boost::is_any_of(",")); - for (size_t i = 0; i < binstr.size(); i++) { - bins.push_back(boost::lexical_cast<double>(binstr.at(i))); + for (const auto &i : binstr) { + bins.push_back(boost::lexical_cast<double>(i)); } TS_ASSERT_EQUALS(bins[0], 1.66667); TS_ASSERT_EQUALS(bins[1], 17.3333); diff --git a/Framework/DataHandling/test/SavePHXTest.h b/Framework/DataHandling/test/SavePHXTest.h index 1bb461aabe3..e64993177da 100644 --- a/Framework/DataHandling/test/SavePHXTest.h +++ b/Framework/DataHandling/test/SavePHXTest.h @@ -139,8 +139,8 @@ public: sample_value[0] = (float)spTW->rowCount(); } else { size_t ii = 0; - for (size_t i = 0; i < column_name.size(); i++) { - sample_value[ii] = (spTW->cell_cast<float>(ic - 1, column_name[i])); + for (const auto &i : column_name) { + sample_value[ii] = (spTW->cell_cast<float>(ic - 1, i)); ii++; if (ii == 1) ii = 2; // scip second column in the file, which contains 0; diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h b/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h index 2617c286f00..37c91d33fba 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.h @@ -158,9 +158,11 @@ public: // ------------------------------------------- std::vector<Mantid::Kernel::VMD> getVertexes() const override; - coord_t *getVertexesArray(size_t &numVertices) const override; - coord_t *getVertexesArray(size_t &numVertices, const size_t outDimensions, - const bool *maskDim) const override; + std::unique_ptr<coord_t[]> + getVertexesArray(size_t &numVertices) const override; + std::unique_ptr<coord_t[]> + getVertexesArray(size_t &numVertices, const size_t outDimensions, + const bool *maskDim) const override; void transformDimensions(std::vector<double> &scaling, std::vector<double> &offset) override; diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.tcc index 99c8f9aab90..fdd9f3d261e 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.tcc +++ b/Framework/DataObjects/inc/MantidDataObjects/MDBoxBase.tcc @@ -1,12 +1,11 @@ #include "MantidDataObjects/MDBoxBase.h" #include "MantidDataObjects/MDEvent.h" +#include "MantidKernel/make_unique.h" #include "MantidKernel/System.h" #include "MantidKernel/VMD.h" #include <boost/make_shared.hpp> #include <limits> -//using NeXus::File; - namespace Mantid { namespace DataObjects { @@ -135,13 +134,13 @@ TMDE(std::vector<Mantid::Kernel::VMD> MDBoxBase)::getVertexes() const { * @param[out] numVertices :: returns the number of vertices in the array. * @return the bare array. This should be deleted by the caller! * */ -TMDE(coord_t *MDBoxBase)::getVertexesArray(size_t &numVertices) const { +TMDE(std::unique_ptr<coord_t[]> MDBoxBase)::getVertexesArray(size_t &numVertices) const { // How many vertices does one box have? 2^nd, or bitwise shift left 1 by nd // bits numVertices = 1 << nd; // Allocate the array of the right size - auto out = new coord_t[nd * numVertices]; + auto out = Kernel::make_unique<coord_t[]>(nd * numVertices); // For each vertex, increase an integeer for (size_t i = 0; i < numVertices; ++i) { @@ -184,7 +183,7 @@ TMDE(coord_t *MDBoxBase)::getVertexesArray(size_t &numVertices) const { *caller! * @throw if outDimensions == 0 * */ -TMDE(coord_t *MDBoxBase)::getVertexesArray(size_t &numVertices, +TMDE(std::unique_ptr<coord_t[]> MDBoxBase)::getVertexesArray(size_t &numVertices, const size_t outDimensions, const bool *maskDim) const { if (outDimensions == 0) @@ -195,7 +194,7 @@ TMDE(coord_t *MDBoxBase)::getVertexesArray(size_t &numVertices, numVertices = (size_t)1 << outDimensions; // Allocate the array of the right size - auto out = new coord_t[outDimensions * numVertices]; + auto out = Kernel::make_unique<coord_t[]>(outDimensions * numVertices); // For each vertex, increase an integeer for (size_t i = 0; i < numVertices; ++i) { diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.h b/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.h index a7627744434..29e4b029043 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.h @@ -54,10 +54,12 @@ public: signal_t getError() const override; - coord_t *getVertexesArray(size_t &numVertices, const size_t outDimensions, - const bool *maskDim) const override; + std::unique_ptr<coord_t[]> + getVertexesArray(size_t &numVertices, const size_t outDimensions, + const bool *maskDim) const override; - coord_t *getVertexesArray(size_t &numVertices) const override; + std::unique_ptr<coord_t[]> + getVertexesArray(size_t &numVertices) const override; Mantid::Kernel::VMD getCenter() const override; diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.tcc index d5df20e7669..c15a92b207a 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.tcc +++ b/Framework/DataObjects/inc/MantidDataObjects/MDBoxIterator.tcc @@ -258,11 +258,11 @@ TMDE(signal_t MDBoxIterator)::getSignal() const { TMDE(signal_t MDBoxIterator)::getError() const { return m_current->getError(); } /// Return a list of vertexes defining the volume pointed to -TMDE(coord_t *MDBoxIterator)::getVertexesArray(size_t &numVertices) const { +TMDE(std::unique_ptr<coord_t[]> MDBoxIterator)::getVertexesArray(size_t &numVertices) const { return m_current->getVertexesArray(numVertices); } -TMDE(coord_t *MDBoxIterator)::getVertexesArray(size_t &numVertices, +TMDE(std::unique_ptr<coord_t[]> MDBoxIterator)::getVertexesArray(size_t &numVertices, const size_t outDimensions, const bool *maskDim) const { return m_current->getVertexesArray(numVertices, outDimensions, maskDim); diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h index d111f289f1d..e29bdc73fd9 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h @@ -73,7 +73,7 @@ public: uint64_t getNEvents() const override { return getNPoints(); } /// Creates a new iterator pointing to the first cell (box) in the workspace - std::vector<Mantid::API::IMDIterator *> createIterators( + std::vector<std::unique_ptr<Mantid::API::IMDIterator>> createIterators( size_t suggestedNumCores = 1, Mantid::Geometry::MDImplicitFunction *function = nullptr) const override; diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc index e1e125b7e90..a67a2f30a59 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc +++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc @@ -239,7 +239,7 @@ TMDE(std::vector<coord_t> MDEventWorkspace)::estimateResolution() const { * @param suggestedNumCores :: split iterator over this many cores. * @param function :: Optional MDImplicitFunction limiting the iterator */ -TMDE(std::vector<Mantid::API::IMDIterator *> MDEventWorkspace)::createIterators( +TMDE(std::vector<std::unique_ptr<Mantid::API::IMDIterator>> MDEventWorkspace)::createIterators( size_t suggestedNumCores, Mantid::Geometry::MDImplicitFunction *function) const { // Get all the boxes in this workspaces @@ -261,13 +261,13 @@ TMDE(std::vector<Mantid::API::IMDIterator *> MDEventWorkspace)::createIterators( numCores = 1; // Create one iterator per core, splitting evenly amongst spectra - std::vector<API::IMDIterator *> out; + std::vector<std::unique_ptr<API::IMDIterator>> out; for (size_t i = 0; i < numCores; i++) { size_t begin = (i * numElements) / numCores; size_t end = ((i + 1) * numElements) / numCores; if (end > numElements) end = numElements; - out.push_back(new MDBoxIterator<MDE, nd>(boxes, begin, end)); + out.push_back(Kernel::make_unique<MDBoxIterator<MDE, nd>>(boxes, begin, end)); } return out; } diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h index 8284af3e4ae..ae75cdc5c36 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h @@ -78,7 +78,7 @@ public: uint64_t getNPoints() const override { return m_length; } /// get number of contributed events uint64_t getNEvents() const override; - std::vector<Mantid::API::IMDIterator *> createIterators( + std::vector<std::unique_ptr<Mantid::API::IMDIterator>> createIterators( size_t suggestedNumCores = 1, Mantid::Geometry::MDImplicitFunction *function = nullptr) const override; @@ -174,7 +174,8 @@ public: void applyImplicitFunction(Mantid::Geometry::MDImplicitFunction *function, signal_t signal, signal_t errorSquared); - coord_t *getVertexesArray(size_t linearIndex, size_t &numVertices) const; + std::unique_ptr<coord_t[]> getVertexesArray(size_t linearIndex, + size_t &numVertices) const; Kernel::VMD getCenter(size_t linearIndex) const override; diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h index 622a532b623..ea83dda0416 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h +++ b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspaceIterator.h @@ -95,10 +95,12 @@ public: signal_t getError() const override; - coord_t *getVertexesArray(size_t &numVertices) const override; + std::unique_ptr<coord_t[]> + getVertexesArray(size_t &numVertices) const override; - coord_t *getVertexesArray(size_t &numVertices, const size_t outDimensions, - const bool *maskDim) const override; + std::unique_ptr<coord_t[]> + getVertexesArray(size_t &numVertices, const size_t outDimensions, + const bool *maskDim) const override; Mantid::Kernel::VMD getCenter() const override; diff --git a/Framework/DataObjects/inc/MantidDataObjects/Peak.h b/Framework/DataObjects/inc/MantidDataObjects/Peak.h index 82b728b8712..40ae08376c4 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/Peak.h +++ b/Framework/DataObjects/inc/MantidDataObjects/Peak.h @@ -121,6 +121,7 @@ public: void setWavelength(double wavelength) override; double getWavelength() const override; double getScattering() const override; + double getAzimuthal() const override; double getDSpacing() const override; double getTOF() const override; @@ -149,6 +150,8 @@ public: int getCol() const override; void setRow(int m_row); void setCol(int m_col); + void setPeakNumber(int m_peakNumber) override; + int getPeakNumber() const override; virtual Mantid::Kernel::V3D getDetPos() const override; double getL1() const override; @@ -242,6 +245,9 @@ private: double m_orig_K; double m_orig_L; + // keep peak number + int m_peakNumber; + /// List of contributing detectors IDs std::set<int> m_detIDs; diff --git a/Framework/DataObjects/src/FractionalRebinning.cpp b/Framework/DataObjects/src/FractionalRebinning.cpp index ff317cc6cce..6e9ee3b1a49 100644 --- a/Framework/DataObjects/src/FractionalRebinning.cpp +++ b/Framework/DataObjects/src/FractionalRebinning.cpp @@ -152,9 +152,9 @@ double polyArea(T &v1, T &v2, Ts &&... vertices) { * @param yAxis The output data vertical axis * @param inputQ The input quadrilateral * @param y_start The starting y-axis index - * @param y_end The starting y-axis index + * @param y_end The ending y-axis index * @param x_start The starting x-axis index - * @param x_end The starting x-axis index + * @param x_end The ending x-axis index * @param areaInfo Output vector of indices and areas of overlapping bins */ void calcTrapezoidYIntersections( @@ -202,8 +202,8 @@ void calcTrapezoidYIntersections( // Step 1 - construct the left/right bin lims on the lines of the y-grid. const double NaN = std::numeric_limits<double>::quiet_NaN(); const double DBL_EPS = std::numeric_limits<double>::epsilon(); - std::vector<double> leftLim(nx * (ny + 1), NaN); - std::vector<double> rightLim(nx * (ny + 1), NaN); + std::vector<double> leftLim((nx + 1) * (ny + 1), NaN); + std::vector<double> rightLim((nx + 1) * (ny + 1), NaN); auto x0_it = xAxis.begin() + x_start; auto x1_it = xAxis.begin() + x_end + 1; auto y0_it = yAxis.begin() + y_start; @@ -239,7 +239,7 @@ void calcTrapezoidYIntersections( auto right_it = std::upper_bound(x0_it, x1_it, right_val); if (right_it != x1_it) { rightLim[right_it - x0_it - 1 + yjx] = right_val; - } else if (yAxis[yj + y_start] < ur_y) { + } else if (yAxis[yj + y_start] < ur_y && nx > 0) { right_it = x1_it - 1; rightLim[nx - 1 + yjx] = lr_x; } @@ -277,12 +277,15 @@ void calcTrapezoidYIntersections( left_it--; if (right_it == x1_it) right_it--; - size_t li = left_it - x0_it - 1; + size_t li = (left_it > x0_it) ? (left_it - x0_it - 1) : 0; + size_t ri = (right_it > x0_it) ? (right_it - x0_it - 1) : 0; leftLim[li + yjx] = (mTop >= 0) ? val : ll_x; - rightLim[right_it - x0_it - 1 + yjx] = (mTop >= 0) ? lr_x : val; - for (auto x_it = left_it; x_it != right_it; x_it++) { - leftLim[li + 1 + yjx] = *x_it; - rightLim[li++ + yjx] = *x_it; + rightLim[ri + yjx] = (mTop >= 0) ? lr_x : val; + if (left_it < right_it && right_it != x1_it) { + for (auto x_it = left_it; x_it != right_it; x_it++) { + leftLim[li + 1 + yjx] = *x_it; + rightLim[li++ + yjx] = *x_it; + } } } } diff --git a/Framework/DataObjects/src/MDHistoWorkspace.cpp b/Framework/DataObjects/src/MDHistoWorkspace.cpp index 0ee1c538168..d93a75a3553 100644 --- a/Framework/DataObjects/src/MDHistoWorkspace.cpp +++ b/Framework/DataObjects/src/MDHistoWorkspace.cpp @@ -1,21 +1,22 @@ +#include "MantidDataObjects/MDHistoWorkspace.h" +#include "MantidAPI/IMDIterator.h" +#include "MantidAPI/IMDWorkspace.h" +#include "MantidDataObjects/MDFramesToSpecialCoordinateSystem.h" +#include "MantidDataObjects/MDHistoWorkspaceIterator.h" #include "MantidGeometry/MDGeometry/IMDDimension.h" +#include "MantidGeometry/MDGeometry/MDDimensionExtents.h" #include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h" +#include "MantidGeometry/MDGeometry/MDHistoDimension.h" #include "MantidKernel/System.h" #include "MantidKernel/Utils.h" #include "MantidKernel/VMD.h" #include "MantidKernel/WarningSuppressions.h" -#include "MantidDataObjects/MDHistoWorkspace.h" -#include "MantidDataObjects/MDHistoWorkspaceIterator.h" -#include "MantidDataObjects/MDFramesToSpecialCoordinateSystem.h" -#include "MantidGeometry/MDGeometry/MDHistoDimension.h" -#include "MantidGeometry/MDGeometry/MDDimensionExtents.h" -#include <map> -#include "MantidAPI/IMDWorkspace.h" -#include "MantidAPI/IMDIterator.h" -#include <boost/scoped_array.hpp> +#include "MantidKernel/make_unique.h" #include <boost/make_shared.hpp> #include <boost/optional.hpp> +#include <boost/scoped_array.hpp> #include <cmath> +#include <map> using namespace Mantid::Kernel; using namespace Mantid::Geometry; @@ -303,8 +304,9 @@ void MDHistoWorkspace::applyImplicitFunction( * @param[out] numVertices :: returns the number of vertices in the array. * @return the bare array. This should be deleted by the caller! * */ -coord_t *MDHistoWorkspace::getVertexesArray(size_t linearIndex, - size_t &numVertices) const { +std::unique_ptr<coord_t[]> +MDHistoWorkspace::getVertexesArray(size_t linearIndex, + size_t &numVertices) const { // How many vertices does one box have? 2^nd, or bitwise shift left 1 by nd // bits numVertices = static_cast<size_t>(1) @@ -319,7 +321,7 @@ coord_t *MDHistoWorkspace::getVertexesArray(size_t linearIndex, numDimensions, linearIndex, m_indexMaker, m_indexMax, dimIndexes); // The output vertexes coordinates - auto out = new coord_t[numDimensions * numVertices]; + auto out = Kernel::make_unique<coord_t[]>(numDimensions * numVertices); for (size_t i = 0; i < numVertices; ++i) { size_t outIndex = i * numDimensions; // Offset the 0th box by the position of this linear index, in each @@ -421,7 +423,8 @@ size_t MDHistoWorkspace::getLinearIndexAtCoord(const coord_t *coords) const { *call. * @return MDHistoWorkspaceIterator vector */ -std::vector<Mantid::API::IMDIterator *> MDHistoWorkspace::createIterators( +std::vector<std::unique_ptr<Mantid::API::IMDIterator>> +MDHistoWorkspace::createIterators( size_t suggestedNumCores, Mantid::Geometry::MDImplicitFunction *function) const { size_t numCores = suggestedNumCores; @@ -434,7 +437,7 @@ std::vector<Mantid::API::IMDIterator *> MDHistoWorkspace::createIterators( numCores = 1; // Create one iterator per core, splitting evenly amongst spectra - std::vector<IMDIterator *> out; + std::vector<std::unique_ptr<IMDIterator>> out; for (size_t i = 0; i < numCores; i++) { size_t begin = (i * numElements) / numCores; size_t end = ((i + 1) * numElements) / numCores; @@ -446,8 +449,8 @@ std::vector<Mantid::API::IMDIterator *> MDHistoWorkspace::createIterators( if (function) clonedFunction = new Mantid::Geometry::MDImplicitFunction(*function); - out.push_back( - new MDHistoWorkspaceIterator(this, clonedFunction, begin, end)); + out.push_back(Kernel::make_unique<MDHistoWorkspaceIterator>( + this, clonedFunction, begin, end)); } return out; } diff --git a/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp b/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp index 03277600b8d..ffc3b2e39ef 100644 --- a/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp +++ b/Framework/DataObjects/src/MDHistoWorkspaceIterator.cpp @@ -384,14 +384,16 @@ signal_t MDHistoWorkspaceIterator::getError() const { } //---------------------------------------------------------------------------------------------- /// Return a list of vertexes defining the volume pointed to -coord_t *MDHistoWorkspaceIterator::getVertexesArray(size_t &numVertices) const { +std::unique_ptr<coord_t[]> +MDHistoWorkspaceIterator::getVertexesArray(size_t &numVertices) const { // The MDHistoWorkspace takes care of this return m_ws->getVertexesArray(m_pos, numVertices); } -coord_t *MDHistoWorkspaceIterator::getVertexesArray(size_t &numVertices, - const size_t outDimensions, - const bool *maskDim) const { +std::unique_ptr<coord_t[]> +MDHistoWorkspaceIterator::getVertexesArray(size_t &numVertices, + const size_t outDimensions, + const bool *maskDim) const { // Do the same thing as is done in the MDBoxBase UNUSED_ARG(numVertices); UNUSED_ARG(outDimensions); diff --git a/Framework/DataObjects/src/Peak.cpp b/Framework/DataObjects/src/Peak.cpp index c99817f9474..a0fbcb21920 100644 --- a/Framework/DataObjects/src/Peak.cpp +++ b/Framework/DataObjects/src/Peak.cpp @@ -29,7 +29,7 @@ Peak::Peak() m_finalEnergy(0.), m_GoniometerMatrix(3, 3, true), m_InverseGoniometerMatrix(3, 3, true), m_runNumber(0), m_monitorCount(0), m_row(-1), m_col(-1), m_orig_H(0), m_orig_K(0), m_orig_L(0), - m_peakShape(boost::make_shared<NoShape>()) { + m_peakNumber(0), m_peakShape(boost::make_shared<NoShape>()) { convention = Kernel::ConfigService::Instance().getString("Q.convention"); } @@ -49,7 +49,7 @@ Peak::Peak(const Geometry::Instrument_const_sptr &m_inst, : m_H(0), m_K(0), m_L(0), m_intensity(0), m_sigmaIntensity(0), m_binCount(0), m_GoniometerMatrix(3, 3, true), m_InverseGoniometerMatrix(3, 3, true), m_runNumber(0), m_monitorCount(0), - m_orig_H(0), m_orig_K(0), m_orig_L(0), + m_orig_H(0), m_orig_K(0), m_orig_L(0), m_peakNumber(0), m_peakShape(boost::make_shared<NoShape>()) { convention = Kernel::ConfigService::Instance().getString("Q.convention"); this->setInstrument(m_inst); @@ -76,7 +76,7 @@ Peak::Peak(const Geometry::Instrument_const_sptr &m_inst, : m_H(0), m_K(0), m_L(0), m_intensity(0), m_sigmaIntensity(0), m_binCount(0), m_GoniometerMatrix(goniometer), m_InverseGoniometerMatrix(goniometer), m_runNumber(0), m_monitorCount(0), - m_orig_H(0), m_orig_K(0), m_orig_L(0), + m_orig_H(0), m_orig_K(0), m_orig_L(0), m_peakNumber(0), m_peakShape(boost::make_shared<NoShape>()) { convention = Kernel::ConfigService::Instance().getString("Q.convention"); if (fabs(m_InverseGoniometerMatrix.Invert()) < 1e-8) @@ -99,7 +99,7 @@ Peak::Peak(const Geometry::Instrument_const_sptr &m_inst, int m_detectorID, : m_H(0), m_K(0), m_L(0), m_intensity(0), m_sigmaIntensity(0), m_binCount(0), m_GoniometerMatrix(3, 3, true), m_InverseGoniometerMatrix(3, 3, true), m_runNumber(0), m_monitorCount(0), - m_orig_H(0), m_orig_K(0), m_orig_L(0), + m_orig_H(0), m_orig_K(0), m_orig_L(0), m_peakNumber(0), m_peakShape(boost::make_shared<NoShape>()) { convention = Kernel::ConfigService::Instance().getString("Q.convention"); this->setInstrument(m_inst); @@ -121,7 +121,7 @@ Peak::Peak(const Geometry::Instrument_const_sptr &m_inst, int m_detectorID, : m_H(HKL[0]), m_K(HKL[1]), m_L(HKL[2]), m_intensity(0), m_sigmaIntensity(0), m_binCount(0), m_GoniometerMatrix(3, 3, true), m_InverseGoniometerMatrix(3, 3, true), m_runNumber(0), m_monitorCount(0), - m_orig_H(0), m_orig_K(0), m_orig_L(0), + m_orig_H(0), m_orig_K(0), m_orig_L(0), m_peakNumber(0), m_peakShape(boost::make_shared<NoShape>()) { convention = Kernel::ConfigService::Instance().getString("Q.convention"); this->setInstrument(m_inst); @@ -145,7 +145,7 @@ Peak::Peak(const Geometry::Instrument_const_sptr &m_inst, int m_detectorID, : m_H(HKL[0]), m_K(HKL[1]), m_L(HKL[2]), m_intensity(0), m_sigmaIntensity(0), m_binCount(0), m_GoniometerMatrix(goniometer), m_InverseGoniometerMatrix(goniometer), m_runNumber(0), m_monitorCount(0), - m_orig_H(0), m_orig_K(0), m_orig_L(0), + m_orig_H(0), m_orig_K(0), m_orig_L(0), m_peakNumber(0), m_peakShape(boost::make_shared<NoShape>()) { convention = Kernel::ConfigService::Instance().getString("Q.convention"); if (fabs(m_InverseGoniometerMatrix.Invert()) < 1e-8) @@ -169,7 +169,7 @@ Peak::Peak(const Geometry::Instrument_const_sptr &m_inst, double scattering, m_binCount(0), m_GoniometerMatrix(3, 3, true), m_InverseGoniometerMatrix(3, 3, true), m_runNumber(0), m_monitorCount(0), m_row(-1), m_col(-1), m_orig_H(0), m_orig_K(0), m_orig_L(0), - m_peakShape(boost::make_shared<NoShape>()) { + m_peakNumber(0), m_peakShape(boost::make_shared<NoShape>()) { convention = Kernel::ConfigService::Instance().getString("Q.convention"); this->setInstrument(m_inst); this->setWavelength(m_Wavelength); @@ -197,8 +197,9 @@ Peak::Peak(const Peak &other) m_row(other.m_row), m_col(other.m_col), sourcePos(other.sourcePos), samplePos(other.samplePos), detPos(other.detPos), m_orig_H(other.m_orig_H), m_orig_K(other.m_orig_K), - m_orig_L(other.m_orig_L), m_detIDs(other.m_detIDs), - m_peakShape(other.m_peakShape->clone()), convention(other.convention) {} + m_orig_L(other.m_orig_L), m_peakNumber(other.m_peakNumber), + m_detIDs(other.m_detIDs), m_peakShape(other.m_peakShape->clone()), + convention(other.convention) {} //---------------------------------------------------------------------------------------------- /** Constructor making a Peak from IPeak interface @@ -218,6 +219,7 @@ Peak::Peak(const Geometry::IPeak &ipeak) m_runNumber(ipeak.getRunNumber()), m_monitorCount(ipeak.getMonitorCount()), m_row(ipeak.getRow()), m_col(ipeak.getCol()), m_orig_H(0.), m_orig_K(0.), m_orig_L(0.), + m_peakNumber(ipeak.getPeakNumber()), m_peakShape(boost::make_shared<NoShape>()) { convention = Kernel::ConfigService::Instance().getString("Q.convention"); if (fabs(m_InverseGoniometerMatrix.Invert()) < 1e-8) @@ -422,6 +424,15 @@ double Peak::getScattering() const { return detDir.angle(beamDir); } +// ------------------------------------------------------------------------------------- +/** Calculate the azimuthal angle of the peak */ +double Peak::getAzimuthal() const { + // The detector is at 2 theta scattering angle + V3D detDir = detPos - samplePos; + + return atan2(detDir.Y(), detDir.X()); +} + // ------------------------------------------------------------------------------------- /** Calculate the d-spacing of the peak, in 1/Angstroms */ double Peak::getDSpacing() const { @@ -878,6 +889,11 @@ int Peak::getRow() const { return m_row; } * Returns -1 if it could not find it. */ int Peak::getCol() const { return m_col; } +// ------------------------------------------------------------------------------------- +/**Returns the unique peak number + * Returns -1 if it could not find it. */ +int Peak::getPeakNumber() const { return m_peakNumber; } + // ------------------------------------------------------------------------------------- /** For RectangularDetectors only, sets the row (y) of the pixel of the * detector. @@ -890,6 +906,13 @@ void Peak::setRow(int m_row) { this->m_row = m_row; } * @param m_col :: col value */ void Peak::setCol(int m_col) { this->m_col = m_col; } +// ------------------------------------------------------------------------------------- +/** Sets the unique peak number + * @param m_peakNumber :: unique peak number value */ +void Peak::setPeakNumber(int m_peakNumber) { + this->m_peakNumber = m_peakNumber; +} + // ------------------------------------------------------------------------------------- /** Return the detector position vector */ Mantid::Kernel::V3D Peak::getDetPos() const { return detPos; } @@ -941,6 +964,8 @@ double Peak::getValueByColName(const std::string &name_in) const { return this->getRow(); else if (name == "col") return this->getCol(); + else if (name == "peaknumber") + return double(this->getPeakNumber()); else throw std::runtime_error( "Peak::getValueByColName() unknown column or column is not a number: " + diff --git a/Framework/DataObjects/src/PeakColumn.cpp b/Framework/DataObjects/src/PeakColumn.cpp index 57a6634f4b2..891e199908a 100644 --- a/Framework/DataObjects/src/PeakColumn.cpp +++ b/Framework/DataObjects/src/PeakColumn.cpp @@ -31,7 +31,7 @@ const std::string typeFromName(const std::string &name) { // We should enter the critical section if the map has not been fully filled. // Be sure to keep the value tested against in sync with the number of inserts // below - if (TYPE_INDEX.size() != 17) { + if (TYPE_INDEX.size() != 18) { PARALLEL_CRITICAL(fill_column_index_map) { if (TYPE_INDEX.empty()) // check again inside the critical block { @@ -53,6 +53,7 @@ const std::string typeFromName(const std::string &name) { TYPE_INDEX.emplace("Col", "double"); TYPE_INDEX.emplace("QLab", "V3D"); TYPE_INDEX.emplace("QSample", "V3D"); + TYPE_INDEX.emplace("PeakNumber", "int"); // If adding an entry, be sure to increment the size comparizon in the // first line } @@ -152,6 +153,8 @@ void PeakColumn::print(size_t index, std::ostream &s) const { s << std::fixed << std::setprecision(m_hklPrec) << peak.getK(); } else if (m_name == "l") { s << std::fixed << std::setprecision(m_hklPrec) << peak.getL(); + } else if (m_name == "PeakNumber") { + s << peak.getPeakNumber(); } else s << peak.getValueByColName(m_name); s.flags(fflags); @@ -291,6 +294,9 @@ const void *PeakColumn::void_pointer(size_t index) const { } else if (m_name == "RunNumber") { value = peak.getRunNumber(); return boost::get<int>(&value); + } else if (m_name == "PeakNumber") { + value = peak.getPeakNumber(); + return boost::get<int>(&value); } else if (m_name == "DetID") { value = peak.getDetectorID(); return boost::get<int>(&value); diff --git a/Framework/DataObjects/src/PeaksWorkspace.cpp b/Framework/DataObjects/src/PeaksWorkspace.cpp index eab92ec1da6..7cbe6aea457 100644 --- a/Framework/DataObjects/src/PeaksWorkspace.cpp +++ b/Framework/DataObjects/src/PeaksWorkspace.cpp @@ -162,8 +162,8 @@ void PeaksWorkspace::removePeaks(std::vector<int> badPeaks) { std::remove_if(peaks.begin(), peaks.end(), [&ip, badPeaks](Peak &pk) { (void)pk; ip++; - for (auto ibp = badPeaks.begin(); ibp != badPeaks.end(); ++ibp) { - if (*ibp == ip) + for (int badPeak : badPeaks) { + if (badPeak == ip) return true; } return false; @@ -630,6 +630,7 @@ void PeaksWorkspace::initColumns() { addPeakColumn("Col"); addPeakColumn("QLab"); addPeakColumn("QSample"); + addPeakColumn("PeakNumber"); } //--------------------------------------------------------------------------------------------- @@ -694,6 +695,7 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const { std::vector<double> dSpacing(np); std::vector<double> TOF(np); std::vector<int> runNumber(np); + std::vector<int> peakNumber(np); std::vector<double> goniometerMatrix(9 * np); std::vector<std::string> shapes(np); @@ -715,6 +717,7 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const { dSpacing[i] = p.getDSpacing(); TOF[i] = p.getTOF(); runNumber[i] = p.getRunNumber(); + peakNumber[i] = p.getPeakNumber(); { Matrix<double> gm = p.getGoniometerMatrix(); goniometerMatrix[9 * i] = gm[0][0]; @@ -861,6 +864,14 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const { file->putAttr("units", "Not known"); // Units may need changing when known file->closeData(); + // Peak Number column + file->writeData("column_17", peakNumber); + file->openData("column_17"); + file->putAttr("name", "Peak Number"); + file->putAttr("interpret_as", specifyInteger); + file->putAttr("units", "Not known"); // Units may need changing when known + file->closeData(); + // Goniometer Matrix Column std::vector<int> array_dims; array_dims.push_back(static_cast<int>(peaks.size())); diff --git a/Framework/DataObjects/src/Workspace2D.cpp b/Framework/DataObjects/src/Workspace2D.cpp index 169ce00da4c..883abc4fd85 100644 --- a/Framework/DataObjects/src/Workspace2D.cpp +++ b/Framework/DataObjects/src/Workspace2D.cpp @@ -107,8 +107,8 @@ void Workspace2D::init(const HistogramData::Histogram &histogram) { Histogram1D spec(initializedHistogram.xMode(), initializedHistogram.yMode()); spec.setHistogram(initializedHistogram); - for (size_t i = 0; i < data.size(); i++) { - data[i] = new Histogram1D(spec); + for (auto &i : data) { + i = new Histogram1D(spec); } // Add axes that reference the data diff --git a/Framework/DataObjects/test/EventListTest.h b/Framework/DataObjects/test/EventListTest.h index 23f979ed5c1..30b5161f111 100644 --- a/Framework/DataObjects/test/EventListTest.h +++ b/Framework/DataObjects/test/EventListTest.h @@ -1826,9 +1826,8 @@ public: } // Clean the pointers - for (std::map<int, EventList *>::iterator im = outputs.begin(); - im != outputs.end(); ++im) { - delete im->second; + for (auto &output : outputs) { + delete output.second; } return; @@ -1874,9 +1873,8 @@ public: } // Clean the pointers - for (std::map<int, EventList *>::iterator im = outputs.begin(); - im != outputs.end(); ++im) { - delete im->second; + for (auto &output : outputs) { + delete output.second; } return; @@ -2312,9 +2310,8 @@ public: TS_ASSERT_EQUALS(e7->getNumberEvents(), 1); // Clean the pointers - for (std::map<int, EventList *>::iterator im = outputs.begin(); - im != outputs.end(); ++im) { - delete im->second; + for (auto &output : outputs) { + delete output.second; } return; @@ -2385,9 +2382,8 @@ public: // TS_ASSERT_EQUALS(e7->getNumberEvents(), 1); // Clean the pointers - for (std::map<int, EventList *>::iterator im = outputs.begin(); - im != outputs.end(); ++im) { - delete im->second; + for (auto &output : outputs) { + delete output.second; } return; diff --git a/Framework/DataObjects/test/FakeMDTest.h b/Framework/DataObjects/test/FakeMDTest.h index aa8ce321bca..e7c5b133b22 100644 --- a/Framework/DataObjects/test/FakeMDTest.h +++ b/Framework/DataObjects/test/FakeMDTest.h @@ -150,8 +150,6 @@ public: it->next(); ++counter; } - - delete it; } }; diff --git a/Framework/DataObjects/test/MDBoxBaseTest.h b/Framework/DataObjects/test/MDBoxBaseTest.h index 046b09bca0a..8af6937d8c1 100644 --- a/Framework/DataObjects/test/MDBoxBaseTest.h +++ b/Framework/DataObjects/test/MDBoxBaseTest.h @@ -326,7 +326,7 @@ public: b.setExtents(0, -10.0, 10.0); b.setExtents(1, -4.0, 6.0); size_t numVertexes = 0; - coord_t *v = b.getVertexesArray(numVertexes); + auto v = b.getVertexesArray(numVertexes); TS_ASSERT_EQUALS(numVertexes, 4); TS_ASSERT_EQUALS(v[0], -10.0); TS_ASSERT_EQUALS(v[0 + 1], -4.0); @@ -336,7 +336,6 @@ public: TS_ASSERT_EQUALS(v[4 + 1], 6.0); TS_ASSERT_EQUALS(v[6], 10.0); TS_ASSERT_EQUALS(v[6 + 1], 6.0); - delete[] v; } /** Get vertexes as a bare array, @@ -346,21 +345,18 @@ public: b.setExtents(0, -10.0, 10.0); b.setExtents(1, -4.0, 6.0); size_t numVertexes = 0; - coord_t *v; bool maskDim[2] = {true, false}; - v = b.getVertexesArray(numVertexes, 1, maskDim); + auto v = b.getVertexesArray(numVertexes, 1, maskDim); TS_ASSERT_EQUALS(numVertexes, 2); TS_ASSERT_EQUALS(v[0], -10.0); TS_ASSERT_EQUALS(v[1], 10.0); - delete[] v; bool maskDim2[2] = {false, true}; v = b.getVertexesArray(numVertexes, 1, maskDim2); TS_ASSERT_EQUALS(numVertexes, 2); TS_ASSERT_EQUALS(v[0], -4.0); TS_ASSERT_EQUALS(v[1], 6.0); - delete[] v; } /** Get vertexes as a bare array, @@ -371,11 +367,10 @@ public: b.setExtents(1, -4.0, 6.0); b.setExtents(2, -2.0, 8.0); size_t numVertexes = 0; - coord_t *v; // 3D projected down to 2D in X/Y bool maskDim[3] = {true, true, false}; - v = b.getVertexesArray(numVertexes, 2, maskDim); + auto v = b.getVertexesArray(numVertexes, 2, maskDim); TS_ASSERT_EQUALS(numVertexes, 4); TS_ASSERT_EQUALS(v[0], -10.0); TS_ASSERT_EQUALS(v[0 + 1], -4.0); @@ -385,7 +380,6 @@ public: TS_ASSERT_EQUALS(v[4 + 1], 6.0); TS_ASSERT_EQUALS(v[6], 10.0); TS_ASSERT_EQUALS(v[6 + 1], 6.0); - delete[] v; // Can't give 0 dimensions. TS_ASSERT_THROWS_ANYTHING(v = b.getVertexesArray(numVertexes, 0, maskDim)); @@ -396,7 +390,6 @@ public: TS_ASSERT_EQUALS(numVertexes, 2); TS_ASSERT_EQUALS(v[0], -4.0); TS_ASSERT_EQUALS(v[1], 6.0); - delete[] v; // 3D projected down to 2D in Y/Z bool maskDim3[3] = {false, true, true}; @@ -410,7 +403,6 @@ public: TS_ASSERT_EQUALS(v[4 + 1], 8.0); TS_ASSERT_EQUALS(v[6], 6.0); TS_ASSERT_EQUALS(v[6 + 1], 8.0); - delete[] v; } void xtest_sortBoxesByFilePos() { @@ -456,8 +448,7 @@ public: b.setExtents(2, -7.0, 7.0); for (size_t i = 0; i < 1000000; i++) { size_t numVertexes; - coord_t *v = b.getVertexesArray(numVertexes); - delete[] v; + auto v = b.getVertexesArray(numVertexes); } } @@ -469,8 +460,7 @@ public: bool maskDim[3] = {true, true, false}; for (size_t i = 0; i < 1000000; i++) { size_t numVertexes; - coord_t *v = b.getVertexesArray(numVertexes, 2, maskDim); - delete[] v; + auto v = b.getVertexesArray(numVertexes, 2, maskDim); } } @@ -482,8 +472,7 @@ public: b.setExtents(3, -6.0, 6.0); for (size_t i = 0; i < 1000000; i++) { size_t numVertexes; - coord_t *v = b.getVertexesArray(numVertexes); - delete[] v; + auto v = b.getVertexesArray(numVertexes); } } void test_getVertexesArray_4D_projected_to_3D() { @@ -495,8 +484,7 @@ public: b.setExtents(3, -6.0, 6.0); for (size_t i = 0; i < 1000000; i++) { size_t numVertexes; - coord_t *v = b.getVertexesArray(numVertexes, 3, maskDim); - delete[] v; + auto v = b.getVertexesArray(numVertexes, 3, maskDim); } } }; diff --git a/Framework/DataObjects/test/MDBoxFlatTreeTest.h b/Framework/DataObjects/test/MDBoxFlatTreeTest.h index 3b3cfc2c991..3fcd866ec46 100644 --- a/Framework/DataObjects/test/MDBoxFlatTreeTest.h +++ b/Framework/DataObjects/test/MDBoxFlatTreeTest.h @@ -93,8 +93,8 @@ public: if (!Boxes[i]->isBox()) gridIndices.push_back(i); } - for (size_t i = 0; i < gridIndices.size(); ++i) { - delete Boxes[gridIndices[i]]; + for (auto gridIndex : gridIndices) { + delete Boxes[gridIndex]; } // Clean up file diff --git a/Framework/DataObjects/test/MDBoxSaveableTest.h b/Framework/DataObjects/test/MDBoxSaveableTest.h index 8408e0f6802..fdf5fb46e9b 100644 --- a/Framework/DataObjects/test/MDBoxSaveableTest.h +++ b/Framework/DataObjects/test/MDBoxSaveableTest.h @@ -840,8 +840,7 @@ public: size_t numOnDisk = 0; uint64_t eventsOnDisk = 0; uint64_t maxFilePos = 0; - for (size_t i = 0; i < boxes.size(); i++) { - API::IMDNode *box = boxes[i]; + for (auto box : boxes) { TS_ASSERT_EQUALS(box->getNPoints(), num_repeat); auto mdbox = dynamic_cast<MDBox<MDE, 2> *>(box); TS_ASSERT(mdbox); diff --git a/Framework/DataObjects/test/MDBoxTest.h b/Framework/DataObjects/test/MDBoxTest.h index 3aa90974421..ab9b56a8a17 100644 --- a/Framework/DataObjects/test/MDBoxTest.h +++ b/Framework/DataObjects/test/MDBoxTest.h @@ -585,8 +585,8 @@ public: coord_t centroid[2] = {0, 0}; signal_t signal = 0.0; b.centroidSphere(sphere, 400., centroid, signal); - for (size_t d = 0; d < 2; d++) - centroid[d] /= static_cast<coord_t>(signal); + for (float &d : centroid) + d /= static_cast<coord_t>(signal); // This should be the weighted centroid TS_ASSERT_DELTA(signal, 6.000, 0.001); @@ -595,11 +595,11 @@ public: // --- Reset and reduce the radius ------ signal = 0; - for (size_t d = 0; d < 2; d++) - centroid[d] = 0.0; + for (float &d : centroid) + d = 0.0; b.centroidSphere(sphere, 16., centroid, signal); - for (size_t d = 0; d < 2; d++) - centroid[d] /= static_cast<coord_t>(signal); + for (float &d : centroid) + d /= static_cast<coord_t>(signal); // Only one event was contained TS_ASSERT_DELTA(signal, 2.000, 0.001); TS_ASSERT_DELTA(centroid[0], 2.000, 0.001); diff --git a/Framework/DataObjects/test/MDEventWorkspaceTest.h b/Framework/DataObjects/test/MDEventWorkspaceTest.h index 2c1cecc5183..f1e0a555200 100644 --- a/Framework/DataObjects/test/MDEventWorkspaceTest.h +++ b/Framework/DataObjects/test/MDEventWorkspaceTest.h @@ -42,7 +42,7 @@ private: /// Helper function to return the number of masked bins in a workspace. TODO: /// move helper into test helpers size_t getNumberMasked(Mantid::API::IMDWorkspace_sptr ws) { - Mantid::API::IMDIterator *it = ws->createIterator(nullptr); + auto it = ws->createIterator(nullptr); size_t numberMasked = 0; size_t counter = 0; for (; counter < it->getDataSize(); ++counter) { @@ -51,7 +51,6 @@ private: } it->next(1); // Doesn't perform skipping on masked, bins, but next() does. } - delete it; return numberMasked; } @@ -238,42 +237,34 @@ public: //------------------------------------------------------------------------------------- /** Create an IMDIterator */ void test_createIterator() { - MDEventWorkspace3 *ew = new MDEventWorkspace3(); + auto ew = boost::make_shared<MDEventWorkspace3>(); BoxController_sptr bc = ew->getBoxController(); bc->setSplitInto(4); ew->splitBox(); - IMDIterator *it = ew->createIterator(); + auto it = ew->createIterator(); TS_ASSERT(it); TS_ASSERT_EQUALS(it->getDataSize(), 4 * 4 * 4); TS_ASSERT(it->next()); - delete it; - auto *mdfunction = new MDImplicitFunction(); - it = ew->createIterator(mdfunction); + MDImplicitFunction mdfunction; + it = ew->createIterator(&mdfunction); TS_ASSERT(it); TS_ASSERT_EQUALS(it->getDataSize(), 4 * 4 * 4); TS_ASSERT(it->next()); - delete mdfunction; - delete it; - delete ew; } //------------------------------------------------------------------------------------- /** Create several IMDIterators to run them in parallel */ void test_createIterators() { - MDEventWorkspace3 *ew = new MDEventWorkspace3(); + auto ew = boost::make_shared<MDEventWorkspace3>(); BoxController_sptr bc = ew->getBoxController(); bc->setSplitInto(4); ew->splitBox(); - std::vector<IMDIterator *> iterators = ew->createIterators(3); + auto iterators = ew->createIterators(3); TS_ASSERT_EQUALS(iterators.size(), 3); TS_ASSERT_EQUALS(iterators[0]->getDataSize(), 21); TS_ASSERT_EQUALS(iterators[1]->getDataSize(), 21); TS_ASSERT_EQUALS(iterators[2]->getDataSize(), 22); - - for (size_t i = 0; i < 3; ++i) - delete iterators[i]; - delete ew; } //------------------------------------------------------------------------------------- diff --git a/Framework/DataObjects/test/MDGridBoxTest.h b/Framework/DataObjects/test/MDGridBoxTest.h index 91442092b7a..ff4538f21b2 100644 --- a/Framework/DataObjects/test/MDGridBoxTest.h +++ b/Framework/DataObjects/test/MDGridBoxTest.h @@ -261,10 +261,10 @@ public: new MDGridBox<MDLeanEvent<1>, 1>(*box, newBoxController); auto boxes = box1->getBoxes(); - for (size_t i = 0; i < boxes.size(); ++i) { + for (auto &box : boxes) { TSM_ASSERT_EQUALS( "All child boxes should have the same box controller as the parent.", - newBoxController, boxes[i]->getBoxController()); + newBoxController, box->getBoxController()); } delete newBoxController; delete box1; @@ -295,11 +295,10 @@ public: TS_ASSERT_EQUALS(g->getChild(i - 2)->getParent(), g); } // MDGridBox will delete the children that it pulled in but the rest need to - // be - // taken care of manually + // be taken care of manually size_t indices[5] = {0, 1, 12, 13, 14}; - for (size_t i = 0; i < 5; ++i) - delete boxes[indices[i]]; + for (auto index : indices) + delete boxes[index]; delete g; delete bcc; } @@ -329,9 +328,9 @@ public: // Check the boxes std::vector<MDBoxBase<MDLeanEvent<3>, 3> *> boxes = g->getBoxes(); TS_ASSERT_EQUALS(boxes.size(), 10 * 5 * 2); - for (size_t i = 0; i < boxes.size(); i++) { + for (auto &boxBase : boxes) { MDBox<MDLeanEvent<3>, 3> *box = - dynamic_cast<MDBox<MDLeanEvent<3>, 3> *>(boxes[i]); + dynamic_cast<MDBox<MDLeanEvent<3>, 3> *>(boxBase); TS_ASSERT(box); } MDBox<MDLeanEvent<3>, 3> *box; @@ -602,8 +601,8 @@ public: parent->getBoxes(boxes, 3, false, function); TS_ASSERT_EQUALS(boxes.size(), 54); // The boxes extents make sense - for (size_t i = 0; i < boxes.size(); i++) { - TS_ASSERT(boxes[i]->getExtents(0).getMax() >= 1.51); + for (auto &box : boxes) { + TS_ASSERT(box->getExtents(0).getMax() >= 1.51); } // --- Now leaf-only --- @@ -611,8 +610,8 @@ public: parent->getBoxes(boxes, 3, true, function); TS_ASSERT_EQUALS(boxes.size(), 40); // The boxes extents make sense - for (size_t i = 0; i < boxes.size(); i++) { - TS_ASSERT(boxes[i]->getExtents(0).getMax() >= 1.51); + for (auto &box : boxes) { + TS_ASSERT(box->getExtents(0).getMax() >= 1.51); } // Limit by another plane @@ -622,18 +621,18 @@ public: boxes.clear(); parent->getBoxes(boxes, 3, false, function); TS_ASSERT_EQUALS(boxes.size(), 33); - for (size_t i = 0; i < boxes.size(); i++) { - TS_ASSERT(boxes[i]->getExtents(0).getMax() >= 1.51); - TS_ASSERT(boxes[i]->getExtents(0).getMin() <= 2.99); + for (auto &box : boxes) { + TS_ASSERT(box->getExtents(0).getMax() >= 1.51); + TS_ASSERT(box->getExtents(0).getMin() <= 2.99); } // Same, leaf only boxes.clear(); parent->getBoxes(boxes, 3, true, function); TS_ASSERT_EQUALS(boxes.size(), 24); - for (size_t i = 0; i < boxes.size(); i++) { - TS_ASSERT(boxes[i]->getExtents(0).getMax() >= 1.51); - TS_ASSERT(boxes[i]->getExtents(0).getMin() <= 2.99); + for (auto &box : boxes) { + TS_ASSERT(box->getExtents(0).getMax() >= 1.51); + TS_ASSERT(box->getExtents(0).getMin() <= 2.99); } // ----- Infinitely thin plane for an implicit function ------------ @@ -675,11 +674,11 @@ public: parent->getBoxes(boxes, 3, false, function); TS_ASSERT_EQUALS(boxes.size(), 46); // The boxes extents make sense - for (size_t i = 0; i < boxes.size(); i++) { - TS_ASSERT(boxes[i]->getExtents(0).getMax() >= 2.00); - TS_ASSERT(boxes[i]->getExtents(0).getMin() <= 3.00); - TS_ASSERT(boxes[i]->getExtents(1).getMax() >= 2.00); - TS_ASSERT(boxes[i]->getExtents(1).getMin() <= 3.00); + for (auto &box : boxes) { + TS_ASSERT(box->getExtents(0).getMax() >= 2.00); + TS_ASSERT(box->getExtents(0).getMin() <= 3.00); + TS_ASSERT(box->getExtents(1).getMax() >= 2.00); + TS_ASSERT(box->getExtents(1).getMin() <= 3.00); } // -- Leaf only --- @@ -690,11 +689,11 @@ public: 16 + 4 * 4 + 4); // 16 in the center one + 4x4 at the 4 edges + 4 at the corners // The boxes extents make sense - for (size_t i = 0; i < boxes.size(); i++) { - TS_ASSERT(boxes[i]->getExtents(0).getMax() >= 2.00); - TS_ASSERT(boxes[i]->getExtents(0).getMin() <= 3.00); - TS_ASSERT(boxes[i]->getExtents(1).getMax() >= 2.00); - TS_ASSERT(boxes[i]->getExtents(1).getMin() <= 3.00); + for (auto &box : boxes) { + TS_ASSERT(box->getExtents(0).getMax() >= 2.00); + TS_ASSERT(box->getExtents(0).getMin() <= 3.00); + TS_ASSERT(box->getExtents(1).getMax() >= 2.00); + TS_ASSERT(box->getExtents(1).getMin() <= 3.00); } // clean up behind @@ -835,12 +834,12 @@ public: // Get all the boxes contained std::vector<MDBoxBase<MDLeanEvent<2>, 2> *> boxes = b->getBoxes(); TS_ASSERT_EQUALS(boxes.size(), 100); - for (size_t i = 0; i < boxes.size(); i++) { - TS_ASSERT_EQUALS(boxes[i]->getNPoints(), 1); - TS_ASSERT_EQUALS(boxes[i]->getSignal(), 2.0); - TS_ASSERT_EQUALS(boxes[i]->getErrorSquared(), 2.0); - TS_ASSERT_EQUALS(boxes[i]->getSignalNormalized(), 2.0); - TS_ASSERT_EQUALS(boxes[i]->getErrorSquaredNormalized(), 2.0); + for (auto &box : boxes) { + TS_ASSERT_EQUALS(box->getNPoints(), 1); + TS_ASSERT_EQUALS(box->getSignal(), 2.0); + TS_ASSERT_EQUALS(box->getErrorSquared(), 2.0); + TS_ASSERT_EQUALS(box->getSignalNormalized(), 2.0); + TS_ASSERT_EQUALS(box->getErrorSquaredNormalized(), 2.0); } // Now try to add bad events (outside bounds) @@ -1083,8 +1082,7 @@ public: // many events std::vector<ibox_t *> boxes = b->getBoxes(); TS_ASSERT_EQUALS(boxes.size(), 100); - for (size_t i = 0; i < boxes.size(); i++) { - ibox_t *box = boxes[i]; + for (auto box : boxes) { TS_ASSERT_EQUALS(box->getNPoints(), num_repeat); TS_ASSERT(dynamic_cast<gbox_t *>(box)); @@ -1405,8 +1403,8 @@ public: signal); // Normalized if (signal != 0.0) { - for (size_t d = 0; d < 2; d++) - centroid[d] /= static_cast<coord_t>(signal); + for (float &d : centroid) + d /= static_cast<coord_t>(signal); } TSM_ASSERT_DELTA(message, signal, 1.0 * numExpected, 1e-5); @@ -1630,8 +1628,8 @@ public: rng, u); for (size_t i = 0; i < num; ++i) { double centers[3]; - for (size_t d = 0; d < 3; d++) - centers[d] = gen(); + for (double ¢er : centers) + center = gen(); // Create and add the event. events.push_back(MDLeanEvent<3>(1.0, 1.0, centers)); } @@ -1730,12 +1728,12 @@ public: coord_t centroid[3]; for (size_t i = 0; i < 100; i++) { signal = 0; - for (size_t d = 0; d < 3; d++) - centroid[d] = 0.0; + for (float &d : centroid) + d = 0.0; box3b->centroidSphere(sphere, radius * radius, centroid, signal); if (signal != 0.0) { - for (size_t d = 0; d < 3; d++) - centroid[d] /= static_cast<coord_t>(signal); + for (float &d : centroid) + d /= static_cast<coord_t>(signal); } } diff --git a/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h b/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h index f1377d70080..6c89feb705d 100644 --- a/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h +++ b/Framework/DataObjects/test/MDHistoWorkspaceIteratorTest.h @@ -79,9 +79,8 @@ public: TS_ASSERT_DELTA(it->getNormalizedSignal(), double(i) / 1.0, 1e-5); TS_ASSERT_DELTA(it->getNormalizedError(), 1.0, 1e-5); size_t numVertices; - coord_t *vertexes = it->getVertexesArray(numVertices); + auto vertexes = it->getVertexesArray(numVertices); TS_ASSERT(vertexes); - delete[] vertexes; TS_ASSERT_EQUALS(it->getNumEvents(), 1); TS_ASSERT_EQUALS(it->getInnerDetectorID(0), 0); TS_ASSERT_EQUALS(it->getInnerRunIndex(0), 0); @@ -126,8 +125,7 @@ public: Mantid::DataObjects::MDHistoWorkspace_sptr ws_sptr(ws); - MDHistoWorkspaceIterator *histoIt = - new MDHistoWorkspaceIterator(ws, function); + auto histoIt = Kernel::make_unique<MDHistoWorkspaceIterator>(ws, function); TSM_ASSERT_EQUALS("The first index hit should be 5 since that is the first " "unmasked and inside function", @@ -136,8 +134,6 @@ public: TSM_ASSERT_EQUALS("The next index hit should be 7 since that is the next " "unmasked and inside function", 7, histoIt->getLinearIndex()); - - delete histoIt; } void test_getNormalizedSignal_with_mask() { @@ -167,8 +163,8 @@ public: Mantid::DataObjects::MDHistoWorkspace_sptr ws_sptr(ws); - MDHistoWorkspaceIterator *histoIt = - dynamic_cast<MDHistoWorkspaceIterator *>(ws->createIterator()); + auto it = ws->createIterator(); + auto histoIt = dynamic_cast<MDHistoWorkspaceIterator *>(it.get()); TSM_ASSERT_EQUALS("Should get the signal value here as data at the iterator" " are unmasked", @@ -180,8 +176,6 @@ public: TSM_ASSERT_EQUALS("Should get the signal value here as data at the iterator" " are unmasked", 3.0, histoIt->getNormalizedSignal()); - - delete histoIt; } void test_iterator_1D() { do_test_iterator(1, 10); } @@ -202,7 +196,7 @@ public: MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2, 10); for (size_t i = 0; i < 100; i++) ws->setSignalAt(i, double(i)); - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws, function); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws, function); TSM_ASSERT("This iterator is valid at the start.", it->valid()); TS_ASSERT_EQUALS(it->getNormalizedSignal(), 0.); @@ -225,8 +219,6 @@ public: it->next(); TS_ASSERT_EQUALS(it->getNormalizedSignal(), 30.); TS_ASSERT(!it->next()); - - delete it; } void test_iterator_2D_implicitFunction_thatExcludesTheStart() { @@ -239,7 +231,7 @@ public: MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2, 10); for (size_t i = 0; i < 100; i++) ws->setSignalAt(i, double(i)); - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws, function); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws, function); TSM_ASSERT("This iterator is valid at the start.", it->valid()); TS_ASSERT_EQUALS(it->getNormalizedSignal(), 4.); @@ -257,8 +249,6 @@ public: TS_ASSERT_EQUALS(it->getNormalizedSignal(), 13.); it->next(); // And so forth.... - - delete it; } void test_iterator_2D_implicitFunction_thatExcludesEverything() { @@ -270,11 +260,9 @@ public: MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2, 10); for (size_t i = 0; i < 100; i++) ws->setSignalAt(i, double(i)); - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws, function); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws, function); TSM_ASSERT("This iterator is not valid at the start.", !it->valid()); - - delete it; } /** Create several parallel iterators */ @@ -286,38 +274,35 @@ public: ws->setSignalAt(i, double(i)); // Make 3 iterators - std::vector<IMDIterator *> iterators = ws->createIterators(3); + auto iterators = ws->createIterators(3); TS_ASSERT_EQUALS(iterators.size(), 3); IMDIterator *it; - it = iterators[0]; + it = iterators[0].get(); TS_ASSERT_DELTA(it->getSignal(), 0.0, 1e-5); TS_ASSERT_EQUALS(it->getDataSize(), 33); TS_ASSERT_DELTA(it->getInnerPosition(0, 0), 0.5, 1e-5); TS_ASSERT_DELTA(it->getInnerPosition(0, 1), 0.5, 1e-5); - it = iterators[1]; + it = iterators[1].get(); TS_ASSERT_DELTA(it->getSignal(), 33.0, 1e-5); TS_ASSERT_EQUALS(it->getDataSize(), 33); TS_ASSERT_DELTA(it->getInnerPosition(0, 0), 3.5, 1e-5); TS_ASSERT_DELTA(it->getInnerPosition(0, 1), 3.5, 1e-5); - it = iterators[2]; + it = iterators[2].get(); TS_ASSERT_DELTA(it->getSignal(), 66.0, 1e-5); TS_ASSERT_EQUALS(it->getDataSize(), 34); TS_ASSERT_DELTA(it->getInnerPosition(0, 0), 6.5, 1e-5); TS_ASSERT_DELTA(it->getInnerPosition(0, 1), 6.5, 1e-5); - - for (size_t i = 0; i < 3; ++i) - delete iterators[i]; } void test_predictable_steps() { MDHistoWorkspace_sptr ws = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2, 10); - MDHistoWorkspaceIterator *histoIt = - dynamic_cast<MDHistoWorkspaceIterator *>(ws->createIterator()); + auto it = ws->createIterator(); + auto histoIt = dynamic_cast<MDHistoWorkspaceIterator *>(it.get()); size_t expected = 0; for (size_t i = 0; i < histoIt->getDataSize(); ++i) { size_t current = histoIt->getLinearIndex(); @@ -326,7 +311,6 @@ public: expected = current + 1; histoIt->next(); } - delete histoIt; } void test_skip_masked_detectors() { @@ -345,8 +329,8 @@ public: Mantid::DataObjects::MDHistoWorkspace_sptr ws_sptr(ws); - MDHistoWorkspaceIterator *histoIt = - dynamic_cast<MDHistoWorkspaceIterator *>(ws_sptr->createIterator()); + auto it = ws_sptr->createIterator(); + auto histoIt = dynamic_cast<MDHistoWorkspaceIterator *>(it.get()); histoIt->next(); TSM_ASSERT_EQUALS( "The first index hit should be 2 since that is the first unmasked one", @@ -355,8 +339,6 @@ public: TSM_ASSERT_EQUALS( "The next index hit should be 5 since that is the next unmasked one", 5, histoIt->getLinearIndex()); - - delete histoIt; } // template<typename ContainerType, typename ElementType> @@ -393,7 +375,7 @@ public: */ - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws); // At first position /* @@ -401,7 +383,8 @@ public: ^ | */ - std::vector<size_t> neighbourIndexes = findNeighbourMemberFunction(it); + std::vector<size_t> neighbourIndexes = + findNeighbourMemberFunction(it.get()); TS_ASSERT_EQUALS(1, neighbourIndexes.size()); // should be on edge TSM_ASSERT("Neighbour at index 0 is 1", @@ -414,7 +397,7 @@ public: | */ it->next(); - neighbourIndexes = findNeighbourMemberFunction(it); + neighbourIndexes = findNeighbourMemberFunction(it.get()); TS_ASSERT_EQUALS(2, neighbourIndexes.size()); // should be on edge TSM_ASSERT("Neighbours at index 1 includes 0", @@ -429,11 +412,9 @@ public: | */ it->jumpTo(9); - neighbourIndexes = findNeighbourMemberFunction(it); + neighbourIndexes = findNeighbourMemberFunction(it.get()); TSM_ASSERT("Neighbour at index 9 is 8", doesContainIndex(neighbourIndexes, 8)); - - delete it; } void test_neighbours_1d_face_touching() { @@ -462,7 +443,7 @@ public: 8 - 9 -10 -11 12-13 -14 -15 */ - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws); // At initial position /* @@ -532,8 +513,6 @@ public: doesContainIndex(neighbourIndexes, 11)); TSM_ASSERT("Neighbour at index 15 is 14", doesContainIndex(neighbourIndexes, 14)); - - delete it; } void test_neighbours_2d_vertex_touching() { @@ -548,7 +527,7 @@ public: 8 - 9 -10 -11 12-13 -14 -15 */ - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws); // At initial position /* @@ -633,8 +612,6 @@ public: doesContainIndex(neighbourIndexes, 11)); TSM_ASSERT("Neighbour at index 15 is 14", doesContainIndex(neighbourIndexes, 14)); - - delete it; } void test_neighbours_3d_face_touching() { @@ -665,7 +642,7 @@ public: [60 61 62 63]]] */ - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws); // Start at Index = 0 std::vector<size_t> neighbourIndexes = @@ -681,9 +658,8 @@ public: neighbourIndexes = it->findNeighbourIndexesFaceTouching(); TS_ASSERT_EQUALS(4, neighbourIndexes.size()); std::vector<size_t> expected_neighbours = {0, 2, 5, 17}; - for (auto i = expected_neighbours.begin(); i != expected_neighbours.end(); - ++i) { - TS_ASSERT(doesContainIndex(neighbourIndexes, *i)); + for (auto &expected_neighbour : expected_neighbours) { + TS_ASSERT(doesContainIndex(neighbourIndexes, expected_neighbour)); } // Move to index 21 @@ -694,9 +670,8 @@ public: // Is completely enclosed expected_neighbours = {17, 20, 22, 25, 5, 37}; - for (auto i = expected_neighbours.begin(); i != expected_neighbours.end(); - ++i) { - TS_ASSERT(doesContainIndex(neighbourIndexes, *i)); + for (auto &expected_neighbour : expected_neighbours) { + TS_ASSERT(doesContainIndex(neighbourIndexes, expected_neighbour)); } // Move to index 63. The last index. @@ -706,12 +681,9 @@ public: // Is on edge expected_neighbours = {47, 59, 62}; - for (auto i = expected_neighbours.begin(); i != expected_neighbours.end(); - ++i) { - TS_ASSERT(doesContainIndex(neighbourIndexes, *i)); + for (auto &expected_neighbour : expected_neighbours) { + TS_ASSERT(doesContainIndex(neighbourIndexes, expected_neighbour)); } - - delete it; } void test_neighbours_3d_vertex_touching() { @@ -742,7 +714,7 @@ public: [60 61 62 63]]] */ - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws); // Start at Index = 0 std::vector<size_t> neighbourIndexes = it->findNeighbourIndexes(); @@ -762,9 +734,8 @@ public: TS_ASSERT_EQUALS(11, neighbourIndexes.size()); std::vector<size_t> expected_neighbours = {0, 2, 4, 5, 6, 16, 17, 18, 20, 21, 22, 22}; - for (auto i = expected_neighbours.begin(); i != expected_neighbours.end(); - ++i) { - TS_ASSERT(doesContainIndex(neighbourIndexes, *i)); + for (auto &expected_neighbour : expected_neighbours) { + TS_ASSERT(doesContainIndex(neighbourIndexes, expected_neighbour)); } // Move to index 21 @@ -776,9 +747,8 @@ public: expected_neighbours = {0, 1, 2, 4, 5, 6, 8, 9, 10, 16, 17, 18, 22, 20, 24, 25, 26, 32, 33, 34, 37, 38, 36, 41, 40, 42}; - for (auto i = expected_neighbours.begin(); i != expected_neighbours.end(); - ++i) { - TS_ASSERT(doesContainIndex(neighbourIndexes, *i)); + for (auto &expected_neighbour : expected_neighbours) { + TS_ASSERT(doesContainIndex(neighbourIndexes, expected_neighbour)); } // Move to index 63. The last index. @@ -788,12 +758,9 @@ public: // Is on edge expected_neighbours = {42, 43, 46, 47, 58, 59, 62}; - for (auto i = expected_neighbours.begin(); i != expected_neighbours.end(); - ++i) { - TS_ASSERT(doesContainIndex(neighbourIndexes, *i)); + for (auto &expected_neighbour : expected_neighbours) { + TS_ASSERT(doesContainIndex(neighbourIndexes, expected_neighbour)); } - - delete it; } void test_neighbours_1d_with_width() { @@ -811,7 +778,7 @@ public: */ - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws); // At first position /* @@ -859,8 +826,6 @@ public: doesContainIndex(neighbourIndexes, 8)); TSM_ASSERT("Neighbours at index 9 includes 7", doesContainIndex(neighbourIndexes, 7)); - - delete it; } void test_neighbours_2d_vertex_touching_by_width() { @@ -876,7 +841,7 @@ public: 8 - 9 -10 -11 12-13 -14 -15 */ - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws); // At initial position /* @@ -953,8 +918,6 @@ public: doesContainIndex(neighbourIndexes, 13)); TSM_ASSERT("Neighbour at index is 14", doesContainIndex(neighbourIndexes, 14)); - - delete it; } void test_neighbours_2d_vertex_touching_by_width_vector() { @@ -973,7 +936,7 @@ public: 8 - 9 -10 -11 12-13 -14 -15 */ - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws); // At initial position /* @@ -1038,8 +1001,6 @@ public: doesContainIndex(neighbourIndexes, 13)); TSM_ASSERT("Neighbour at index is 14", doesContainIndex(neighbourIndexes, 14)); - - delete it; } void test_neighbours_3d_vertex_touching_width() { @@ -1071,7 +1032,7 @@ public: [60 61 62 63]]] */ - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws); // Start at Index = 0 std::vector<size_t> neighbourIndexes = @@ -1095,8 +1056,6 @@ public: TS_ASSERT(doesContainIndex(neighbourIndexes, 24)); TS_ASSERT(doesContainIndex(neighbourIndexes, 25)); TS_ASSERT(doesContainIndex(neighbourIndexes, 26)); - - delete it; } void test_cache() { @@ -1110,7 +1069,7 @@ public: */ - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws); TSM_ASSERT_EQUALS("Empty cache expected", 0, it->permutationCacheSize()); it->findNeighbourIndexesByWidth(3); TSM_ASSERT_EQUALS("One cache item expected", 1, it->permutationCacheSize()); @@ -1121,15 +1080,13 @@ public: it->findNeighbourIndexesByWidth(5); TSM_ASSERT_EQUALS("Two cache entries expected", 2, it->permutationCacheSize()); - - delete it; } void test_getBoxExtents_1d() { const size_t nd = 1; MDHistoWorkspace_sptr ws = MDEventsTestHelper::makeFakeMDHistoWorkspace( 1.0 /*signal*/, nd, 3 /*3 bins*/); // Dimension length defaults to 10 - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws); // At zeroth position VecMDExtents extents = it->getBoxExtents(); @@ -1149,15 +1106,13 @@ public: extents = it->getBoxExtents(); TS_ASSERT_DELTA(extents[0].get<0>(), 10.0 * 2.0 / 3.0, 1e-4); TS_ASSERT_DELTA(extents[0].get<1>(), 10.0 * 3.0 / 3.0, 1e-4); - - delete it; } void test_getBoxExtents_3d() { MDHistoWorkspace_sptr ws = MDEventsTestHelper::makeFakeMDHistoWorkspace( 1.0 /*signal*/, 3 /*nd*/, 4 /*nbins per dim*/, 6 /*max*/, 1.0 /*error sq*/); - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws); // At zeroth position VecMDExtents extents = it->getBoxExtents(); @@ -1181,8 +1136,6 @@ public: TS_ASSERT_DELTA(extents[1].get<1>(), 4.0 / 4 * 6.0, 1e-4); TS_ASSERT_DELTA(extents[2].get<0>(), 3.0 / 4 * 6.0, 1e-4); TS_ASSERT_DELTA(extents[2].get<1>(), 4.0 / 4 * 6.0, 1e-4); - - delete it; } void test_jump_to_nearest_1d() { @@ -1210,8 +1163,8 @@ public: */ - MDHistoWorkspaceIterator *itIn = new MDHistoWorkspaceIterator(wsIn); - MDHistoWorkspaceIterator *itOut = new MDHistoWorkspaceIterator(wsOut); + auto itIn = Kernel::make_unique<MDHistoWorkspaceIterator>(wsIn); + auto itOut = Kernel::make_unique<MDHistoWorkspaceIterator>(wsOut); // First position TS_ASSERT_EQUALS(itIn->getLinearIndex(), 0); @@ -1239,9 +1192,6 @@ public: diff = itOut->jumpToNearest(itIn->getCenter()); TS_ASSERT_EQUALS(itOut->getLinearIndex(), 3); // 10.5 closer to 12 than 8 TS_ASSERT_DELTA(1.5, diff, 1e-4); - - delete itIn; - delete itOut; } void test_neighbours_1d_with_width_including_out_of_bounds() { @@ -1259,7 +1209,7 @@ public: */ - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws); // At first position /* @@ -1348,8 +1298,6 @@ public: doesContainIndex(neighbourIndexes, 10)); // Invalid TSM_ASSERT("Neighbours include 3", doesContainIndex(neighbourIndexes, 11)); // Invalid - - delete it; } void test_neighbours_2d_vertex_touching_by_width_including_out_of_bounds() { @@ -1366,7 +1314,7 @@ public: 8 - 9 -10 -11 12-13 -14 -15 */ - MDHistoWorkspaceIterator *it = new MDHistoWorkspaceIterator(ws); + auto it = Kernel::make_unique<MDHistoWorkspaceIterator>(ws); // At initial position /* @@ -1451,8 +1399,6 @@ public: doesContainIndex(neighbourIndexes, 19)); // Invalid TSM_ASSERT("Neighbour at index is 23", doesContainIndex(neighbourIndexes, 23)); // Invalid - - delete it; } }; @@ -1479,37 +1425,34 @@ public: /** ~Two million iterations */ void test_iterator_3D_signalAndErrorOnly() { - MDHistoWorkspaceIterator *it = - new MDHistoWorkspaceIterator(ws, new SkipNothing); + auto it = + Kernel::make_unique<MDHistoWorkspaceIterator>(ws, new SkipNothing); do { signal_t sig = it->getNormalizedSignal(); signal_t err = it->getNormalizedError(); UNUSED_ARG(sig); UNUSED_ARG(err); } while (it->next()); - delete it; } /** ~Two million iterations */ void test_iterator_3D_withGetVertexes() { - MDHistoWorkspaceIterator *it = - new MDHistoWorkspaceIterator(ws, new SkipNothing); + auto it = + Kernel::make_unique<MDHistoWorkspaceIterator>(ws, new SkipNothing); size_t numVertices; do { signal_t sig = it->getNormalizedSignal(); signal_t err = it->getNormalizedError(); - coord_t *vertexes = it->getVertexesArray(numVertices); - delete[] vertexes; + auto vertexes = it->getVertexesArray(numVertices); UNUSED_ARG(sig); UNUSED_ARG(err); } while (it->next()); - delete it; } /** ~Two million iterations */ void test_iterator_3D_withGetCenter() { - MDHistoWorkspaceIterator *it = - new MDHistoWorkspaceIterator(ws, new SkipNothing); + auto it = + Kernel::make_unique<MDHistoWorkspaceIterator>(ws, new SkipNothing); do { signal_t sig = it->getNormalizedSignal(); signal_t err = it->getNormalizedError(); @@ -1517,13 +1460,12 @@ public: UNUSED_ARG(sig); UNUSED_ARG(err); } while (it->next()); - delete it; } /** Use jumpTo() */ void test_iterator_3D_withGetCenter_usingJumpTo() { - MDHistoWorkspaceIterator *it = - new MDHistoWorkspaceIterator(ws, new SkipNothing); + auto it = + Kernel::make_unique<MDHistoWorkspaceIterator>(ws, new SkipNothing); int max = int(it->getDataSize()); for (int i = 0; i < max; i++) { it->jumpTo(size_t(i)); @@ -1533,7 +1475,6 @@ public: UNUSED_ARG(sig); UNUSED_ARG(err); } - delete it; } void test_masked_get_vertexes_call_throws() { diff --git a/Framework/DataObjects/test/MDHistoWorkspaceTest.h b/Framework/DataObjects/test/MDHistoWorkspaceTest.h index 684327f8c15..d0de735e34c 100644 --- a/Framework/DataObjects/test/MDHistoWorkspaceTest.h +++ b/Framework/DataObjects/test/MDHistoWorkspaceTest.h @@ -33,7 +33,7 @@ private: /// Helper function to return the number of masked bins in a workspace. TODO: /// move helper into test helpers size_t getNumberMasked(Mantid::API::IMDWorkspace_sptr ws) { - Mantid::API::IMDIterator *it = ws->createIterator(nullptr); + auto it = ws->createIterator(nullptr); size_t numberMasked = 0; size_t counter = 0; for (; counter < it->getDataSize(); ++counter) { @@ -42,7 +42,6 @@ private: } it->next(1); } - delete it; return numberMasked; } @@ -287,16 +286,14 @@ public: new MDHistoDimension("X", "x", frame, -10, 10, 5)); MDHistoWorkspace ws(dimX); size_t numVertices; - coord_t *v1 = ws.getVertexesArray(0, numVertices); + auto v1 = ws.getVertexesArray(0, numVertices); TS_ASSERT_EQUALS(numVertices, 2); TS_ASSERT_DELTA(v1[0], -10.0, 1e-5); TS_ASSERT_DELTA(v1[1], -6.0, 1e-5); - delete[] v1; - coord_t *v2 = ws.getVertexesArray(4, numVertices); + auto v2 = ws.getVertexesArray(4, numVertices); TS_ASSERT_DELTA(v2[0], 6.0, 1e-5); TS_ASSERT_DELTA(v2[1], 10.0, 1e-5); - delete[] v2; } //--------------------------------------------------------------------------------------------------- @@ -309,7 +306,7 @@ public: MDHistoWorkspace ws(dimX, dimY); size_t numVertices, i; - boost::scoped_array<coord_t> v1(ws.getVertexesArray(0, numVertices)); + auto v1 = ws.getVertexesArray(0, numVertices); TS_ASSERT_EQUALS(numVertices, 4); i = 0 * 2; TS_ASSERT_DELTA(v1[i + 0], -10.0, 1e-5); @@ -318,7 +315,7 @@ public: TS_ASSERT_DELTA(v1[i + 0], -6.0, 1e-5); TS_ASSERT_DELTA(v1[i + 1], -6.0, 1e-5); // The opposite corner - boost::scoped_array<coord_t> v2(ws.getVertexesArray(24, numVertices)); + auto v2 = ws.getVertexesArray(24, numVertices); i = 0 * 2; TS_ASSERT_DELTA(v2[i + 0], 6.0, 1e-5); TS_ASSERT_DELTA(v2[i + 1], 6.0, 1e-5); @@ -339,7 +336,7 @@ public: MDHistoWorkspace ws(dimX, dimY, dimZ); size_t numVertices, i; - boost::scoped_array<coord_t> v(ws.getVertexesArray(0, numVertices)); + auto v = ws.getVertexesArray(0, numVertices); TS_ASSERT_EQUALS(numVertices, 8); i = 0; TS_ASSERT_DELTA(v[i + 0], -10.0, 1e-5); @@ -413,17 +410,15 @@ public: MDHistoDimension_sptr dimZ( new MDHistoDimension("Z", "z", frame, -8, 10, 10)); MDHistoWorkspace ws(dimX, dimY, dimZ); - IMDIterator *it = ws.createIterator(); + auto it = ws.createIterator(); TS_ASSERT(it); MDHistoWorkspaceIterator *hwit = - dynamic_cast<MDHistoWorkspaceIterator *>(it); + dynamic_cast<MDHistoWorkspaceIterator *>(it.get()); TS_ASSERT(hwit); TS_ASSERT(it->next()); - delete it; boost::scoped_ptr<MDImplicitFunction> mdfunction(new MDImplicitFunction); it = ws.createIterator(mdfunction.get()); TS_ASSERT(it); - delete it; } //--------------------------------------------------------------------------------------------------- diff --git a/Framework/DataObjects/test/PeakTest.h b/Framework/DataObjects/test/PeakTest.h index 9c3404718fc..82ded86e3f9 100644 --- a/Framework/DataObjects/test/PeakTest.h +++ b/Framework/DataObjects/test/PeakTest.h @@ -601,8 +601,7 @@ private: void check_Contributing_Detectors(const Peak &peak, const std::vector<int> &expected) { auto peakIDs = peak.getContributingDetIDs(); - for (auto it = expected.begin(); it != expected.end(); ++it) { - const int id = *it; + for (int id : expected) { TSM_ASSERT_EQUALS("Expected " + boost::lexical_cast<std::string>(id) + " in contribution list", 1, peakIDs.count(id)) diff --git a/Framework/DataObjects/test/PeaksWorkspaceTest.h b/Framework/DataObjects/test/PeaksWorkspaceTest.h index 4d5f1d2724e..929e62a0174 100644 --- a/Framework/DataObjects/test/PeaksWorkspaceTest.h +++ b/Framework/DataObjects/test/PeaksWorkspaceTest.h @@ -56,7 +56,7 @@ public: /** Check that the PeaksWorkspace build by buildPW() is correct */ void checkPW(const PeaksWorkspace &pw) { - TS_ASSERT_EQUALS(pw.columnCount(), 17); + TS_ASSERT_EQUALS(pw.columnCount(), 18); TS_ASSERT_EQUALS(pw.rowCount(), 1); TS_ASSERT_EQUALS(pw.getNumberPeaks(), 1); if (pw.getNumberPeaks() != 1) diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt index a7f83f876fa..98e664cba7c 100644 --- a/Framework/Geometry/CMakeLists.txt +++ b/Framework/Geometry/CMakeLists.txt @@ -258,7 +258,7 @@ set ( INC_FILES inc/MantidGeometry/Objects/CSGObject.h inc/MantidGeometry/Objects/IObject.h inc/MantidGeometry/Objects/InstrumentRayTracer.h - inc/MantidGeometry/Objects/MeshObject.h + inc/MantidGeometry/Objects/MeshObject.h inc/MantidGeometry/Objects/Rules.h inc/MantidGeometry/Objects/ShapeFactory.h inc/MantidGeometry/Objects/Track.h @@ -391,7 +391,7 @@ set ( TEST_FILES SampleEnvironmentTest.h ScalarUtilsTest.h ShapeFactoryTest.h - ShapeInfoTest.h + ShapeInfoTest.h SpaceGroupFactoryTest.h SpaceGroupTest.h SphereTest.h diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h b/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h index 2b8afe94472..f900b5b7cb4 100644 --- a/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h +++ b/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h @@ -60,6 +60,7 @@ public: virtual void setWavelength(double wavelength) = 0; virtual double getWavelength() const = 0; virtual double getScattering() const = 0; + virtual double getAzimuthal() const = 0; virtual double getDSpacing() const = 0; virtual double getTOF() const = 0; @@ -78,6 +79,9 @@ public: virtual double getBinCount() const = 0; virtual void setBinCount(double m_BinCount) = 0; + virtual int getPeakNumber() const = 0; + virtual void setPeakNumber(int m_PeakNumber) = 0; + virtual Mantid::Kernel::Matrix<double> getGoniometerMatrix() const = 0; virtual void setGoniometerMatrix( const Mantid::Kernel::Matrix<double> &m_GoniometerMatrix) = 0; diff --git a/Framework/Geometry/inc/MantidGeometry/IObjComponent.h b/Framework/Geometry/inc/MantidGeometry/IObjComponent.h index d5a239686bd..2553ed3915c 100644 --- a/Framework/Geometry/inc/MantidGeometry/IObjComponent.h +++ b/Framework/Geometry/inc/MantidGeometry/IObjComponent.h @@ -59,6 +59,10 @@ public: IObjComponent(GeometryHandler *the_handler); + IObjComponent(const IObjComponent &); + + IObjComponent &operator=(const IObjComponent &rhs); + // Looking to get rid of the first of these constructors in due course (and // probably add others) ~IObjComponent() override; @@ -104,11 +108,6 @@ public: GeometryHandler *Handle() const { return handle; } protected: - /// Protected copy constructor - IObjComponent(const IObjComponent &); - /// Assignment operator - IObjComponent &operator=(const IObjComponent &); - /// Reset the current geometry handler void setGeometryHandler(GeometryHandler *h); diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentVisitor.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentVisitor.h index caa2b19eb06..548dbc62cbb 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentVisitor.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentVisitor.h @@ -49,6 +49,7 @@ public: virtual size_t registerInfiniteObjComponent(const IObjComponent &component) = 0; virtual size_t registerDetector(const IDetector &detector) = 0; + virtual size_t registerRectangularBank(const ICompAssembly &bank) = 0; virtual size_t registerStructuredBank(const ICompAssembly &bank) = 0; virtual size_t registerObjComponentAssembly(const ObjCompAssembly &obj) = 0; virtual ~ComponentVisitor() {} diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h b/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h index a6a365bbc84..ee23596428c 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentVisitor.h @@ -174,6 +174,9 @@ public: virtual size_t registerGenericObjComponent( const Mantid::Geometry::IObjComponent &objComponent) override; + virtual size_t + registerRectangularBank(const Mantid::Geometry::ICompAssembly &bank) override; + virtual size_t registerInfiniteObjComponent(const IObjComponent &objComponent) override; diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h b/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h index fdfb8b637d1..7939e9e0707 100644 --- a/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h +++ b/Framework/Geometry/inc/MantidGeometry/Instrument/StructuredDetector.h @@ -64,8 +64,8 @@ public: StructuredDetector(const StructuredDetector *base, const ParameterMap *map); /// Create all the detector pixels of this rectangular detector. - void initialize(size_t xPixels, size_t yPixels, const std::vector<double> &x, - const std::vector<double> &y, bool isZBeam, detid_t idStart, + void initialize(size_t xPixels, size_t yPixels, std::vector<double> &&x, + std::vector<double> &&y, bool isZBeam, detid_t idStart, bool idFillByFirstY, int idStepByRow, int idStep = 1); //! Make a clone of the present component diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h index a8ea0b2ae7d..26b173e33cc 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/CSGObject.h @@ -259,6 +259,7 @@ private: /// Geometry Handle for rendering boost::shared_ptr<GeometryHandler> m_handler; friend class GeometryHandler; + friend class GeometryRenderer; /// Is geometry caching enabled? bool bGeometryCaching; /// a pointer to a class for reading from the geometry cache diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h b/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h index 59cc8e269e5..92f4c32efe2 100644 --- a/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h +++ b/Framework/Geometry/inc/MantidGeometry/Objects/IObject.h @@ -96,7 +96,6 @@ public: virtual void GetObjectGeom(detail::ShapeInfo::GeometryShape &type, std::vector<Kernel::V3D> &vectors, double &myradius, double &myheight) const = 0; - // Rendering virtual void draw() const = 0; virtual void initDraw() const = 0; diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h index d166cc5a086..434c3100f1c 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryHandler.h @@ -15,8 +15,10 @@ namespace Mantid { namespace Geometry { class IObjComponent; class CSGObject; + class MeshObject; namespace detail { +class Renderer; class GeometryTriangulator; } @@ -55,21 +57,17 @@ private: protected: std::shared_ptr<detail::ShapeInfo> m_shapeInfo; std::unique_ptr<detail::GeometryTriangulator> m_triangulator; - RectangularDetector *m_rectDet = nullptr; MeshObject *m_meshObj = nullptr; ///< Mesh Object that uses this geometry handler - StructuredDetector *m_structDet = nullptr; IObjComponent *m_objComp = nullptr; ///< ObjComponent that uses this geometry handler CSGObject *m_csgObj = nullptr; ///< Object that uses this geometry handler public: - GeometryHandler(IObjComponent *comp); ///< Constructor - GeometryHandler(boost::shared_ptr<CSGObject> obj); ///< Constructor - GeometryHandler(CSGObject *obj); ///< Constructor - GeometryHandler(RectangularDetector *comp); + GeometryHandler(IObjComponent *comp); ///< Constructor + GeometryHandler(boost::shared_ptr<CSGObject> obj); ///< Constructor + GeometryHandler(CSGObject *obj); ///< Constructor GeometryHandler(boost::shared_ptr<MeshObject> obj); ///<Constructor GeometryHandler(MeshObject *obj); - GeometryHandler(StructuredDetector *comp); GeometryHandler(const GeometryHandler &handler); boost::shared_ptr<GeometryHandler> clone() const; ~GeometryHandler(); diff --git a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h index 75df0cbbf6f..e7a6b86a5fc 100644 --- a/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h +++ b/Framework/Geometry/inc/MantidGeometry/Rendering/GeometryTriangulator.h @@ -49,8 +49,10 @@ private: void checkTriangulated(); public: - GeometryTriangulator(const CSGObject *obj); + GeometryTriangulator(const CSGObject *obj = nullptr); GeometryTriangulator(const MeshObject *obj); + GeometryTriangulator(const GeometryTriangulator &) = delete; + GeometryTriangulator &operator=(const GeometryTriangulator &) = delete; ~GeometryTriangulator(); void triangulate(); void generateMesh(); diff --git a/Framework/Geometry/src/Instrument/ComponentInfo.cpp b/Framework/Geometry/src/Instrument/ComponentInfo.cpp index ad76cbcca0f..b8ec01fc27f 100644 --- a/Framework/Geometry/src/Instrument/ComponentInfo.cpp +++ b/Framework/Geometry/src/Instrument/ComponentInfo.cpp @@ -123,20 +123,27 @@ ComponentInfo::quadrilateralComponent(const size_t componentIndex) const { "in ComponentInfo::quadrilateralComponent."); QuadrilateralComponent corners; - auto innerRangeComp = - m_componentInfo->componentRangeInSubtree(componentIndex); + const auto &innerRangeComp = m_componentInfo->children(componentIndex); // nSubComponents, subtract off self hence -1. nSubComponents = number of // horizontal columns. - corners.nX = innerRangeComp.end() - innerRangeComp.begin() - 1; + corners.nX = innerRangeComp.size(); auto innerRangeDet = m_componentInfo->detectorRangeInSubtree(componentIndex); auto nSubDetectors = std::distance(innerRangeDet.begin(), innerRangeDet.end()); corners.nY = nSubDetectors / corners.nX; + auto firstComp = innerRangeComp.front(); + // The ranges contain the parent component as the last index + // therefore end() - 2 + auto lastComp = innerRangeComp.back(); + corners.bottomLeft = + *(m_componentInfo->detectorRangeInSubtree(firstComp).begin()); + corners.topRight = + *(m_componentInfo->detectorRangeInSubtree(lastComp).end() - 1); + corners.topLeft = + *(m_componentInfo->detectorRangeInSubtree(firstComp).end() - 1); + corners.bottomRight = + *m_componentInfo->detectorRangeInSubtree(lastComp).begin(); - corners.bottomLeft = *innerRangeDet.begin(); - corners.topRight = corners.bottomLeft + nSubDetectors - 1; - corners.topLeft = corners.bottomLeft + (corners.nY - 1); - corners.bottomRight = corners.topRight - (corners.nY - 1); return corners; } @@ -459,7 +466,8 @@ BoundingBox ComponentInfo::boundingBox(const size_t componentIndex, const auto compFlag = componentType(index); if (hasSource() && index == source()) { ++compIterator; - } else if (compFlag == Beamline::ComponentType::Rectangular) { + } else if (compFlag == Beamline::ComponentType::Rectangular || + compFlag == Beamline::ComponentType::Structured) { growBoundingBoxAsRectuangularBank(index, reference, absoluteBB, detExclusions, compIterator); } else if (compFlag == Beamline::ComponentType::OutlineComposite) { diff --git a/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp b/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp index 88776862dc2..41e50b97792 100644 --- a/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp +++ b/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp @@ -1587,8 +1587,8 @@ void InstrumentDefinitionParser::createStructuredDetector( bool isZBeam = m_instrument->getReferenceFrame()->isVectorPointingAlongBeam(zVector); // Now, initialize all the pixels in the bank - bank->initialize(xpixels, ypixels, xValues, yValues, isZBeam, idstart, - idfillbyfirst_y, idstepbyrow, idstep); + bank->initialize(xpixels, ypixels, std::move(xValues), std::move(yValues), + isZBeam, idstart, idfillbyfirst_y, idstepbyrow, idstep); // Loop through all detectors in the newly created bank and mark those in // the instrument. diff --git a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp index d8bc94059ff..719d9883b11 100644 --- a/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp +++ b/Framework/Geometry/src/Instrument/InstrumentVisitor.cpp @@ -253,6 +253,18 @@ size_t InstrumentVisitor::registerGenericObjComponent( return index; } +/** +* Register a structured bank +* @param bank : Rectangular Detector +* @return index assigned +*/ +size_t InstrumentVisitor::registerRectangularBank(const ICompAssembly &bank) { + auto index = registerComponentAssembly(bank); + size_t rangesIndex = index - m_orderedDetectorIds->size(); + (*m_componentType)[rangesIndex] = Beamline::ComponentType::Rectangular; + return index; +} + /** * @brief InstrumentVisitor::registerInfiniteObjComponent * @param objComponent : IObjComponent being visited @@ -267,13 +279,13 @@ size_t InstrumentVisitor::registerInfiniteObjComponent( /** * Register a structured bank - * @param bank : Rectangular Detector + * @param bank : Structured Detector * @return index assigned */ size_t InstrumentVisitor::registerStructuredBank(const ICompAssembly &bank) { auto index = registerComponentAssembly(bank); size_t rangesIndex = index - m_orderedDetectorIds->size(); - (*m_componentType)[rangesIndex] = Beamline::ComponentType::Rectangular; + (*m_componentType)[rangesIndex] = Beamline::ComponentType::Structured; return index; } diff --git a/Framework/Geometry/src/Instrument/RectangularDetector.cpp b/Framework/Geometry/src/Instrument/RectangularDetector.cpp index 21fa505d805..95793784ae3 100644 --- a/Framework/Geometry/src/Instrument/RectangularDetector.cpp +++ b/Framework/Geometry/src/Instrument/RectangularDetector.cpp @@ -734,7 +734,7 @@ const Kernel::Material RectangularDetector::material() const { size_t RectangularDetector::registerContents( ComponentVisitor &componentVisitor) const { - return componentVisitor.registerStructuredBank(*this); + return componentVisitor.registerRectangularBank(*this); } //------------------------------------------------------------------------------------------------- diff --git a/Framework/Geometry/src/Instrument/StructuredDetector.cpp b/Framework/Geometry/src/Instrument/StructuredDetector.cpp index 754b4aeb087..40ba6ba2edc 100644 --- a/Framework/Geometry/src/Instrument/StructuredDetector.cpp +++ b/Framework/Geometry/src/Instrument/StructuredDetector.cpp @@ -289,8 +289,8 @@ std::vector<double> const &StructuredDetector::getYValues() const { * */ void StructuredDetector::initialize(size_t xPixels, size_t yPixels, - const std::vector<double> &x, - const std::vector<double> &y, bool isZBeam, + std::vector<double> &&x, + std::vector<double> &&y, bool isZBeam, detid_t idStart, bool idFillByFirstY, int idStepByRow, int idStep) { if (m_map) @@ -328,8 +328,8 @@ void StructuredDetector::initialize(size_t xPixels, size_t yPixels, "z-axis aligned beams."); // Store vertices - m_xvalues = x; - m_yvalues = y; + m_xvalues = std::move(x); + m_yvalues = std::move(y); createDetectors(); } diff --git a/Framework/Geometry/src/Objects/CSGObject.cpp b/Framework/Geometry/src/Objects/CSGObject.cpp index ebfaabe2d75..ee88d010606 100644 --- a/Framework/Geometry/src/Objects/CSGObject.cpp +++ b/Framework/Geometry/src/Objects/CSGObject.cpp @@ -2092,8 +2092,8 @@ void CSGObject::setVtkGeometryCacheReader( } /** -* Returns the geometry handler -*/ + * Returns the geometry handler + */ boost::shared_ptr<GeometryHandler> CSGObject::getGeometryHandler() const { // Check if the geometry handler is upto dated with the cache, if not then // cache it now. diff --git a/Framework/Geometry/src/Objects/ShapeFactory.cpp b/Framework/Geometry/src/Objects/ShapeFactory.cpp index 439fb17c895..825101d50a7 100644 --- a/Framework/Geometry/src/Objects/ShapeFactory.cpp +++ b/Framework/Geometry/src/Objects/ShapeFactory.cpp @@ -163,11 +163,6 @@ ShapeFactory::createShape(Poco::XML::Element *pElem) { lastElement = pE; idMatching[idFromUser] = parseCylinder(pE, primitives, l_id); numPrimitives++; - } else if (primitiveName == "segmented-cylinder") { - lastElement = pE; - idMatching[idFromUser] = - parseSegmentedCylinder(pE, primitives, l_id); - numPrimitives++; } else if (primitiveName == "hollow-cylinder") { idMatching[idFromUser] = parseHollowCylinder(pE, primitives, l_id); numPrimitives++; @@ -1416,6 +1411,7 @@ ShapeFactory::createHexahedralShape(double xlb, double xlf, double xrf, shapeInfo.setHexahedron(hex.lbb, hex.lfb, hex.rfb, hex.rbb, hex.lbt, hex.lft, hex.rft, hex.rbt); + handler->setShapeInfo(std::move(shapeInfo)); shape->defineBoundingBox(std::max(xrb, xrf), yrf, ZDEPTH, std::min(xlf, xlb), diff --git a/Framework/Geometry/src/Rendering/GeometryHandler.cpp b/Framework/Geometry/src/Rendering/GeometryHandler.cpp index d33ad8c2fba..51a3f459eae 100644 --- a/Framework/Geometry/src/Rendering/GeometryHandler.cpp +++ b/Framework/Geometry/src/Rendering/GeometryHandler.cpp @@ -24,11 +24,6 @@ GeometryHandler::GeometryHandler(boost::shared_ptr<MeshObject> obj) GeometryHandler::GeometryHandler(MeshObject *obj) : m_triangulator(new detail::GeometryTriangulator(obj)), m_meshObj(obj) {} -GeometryHandler::GeometryHandler(RectangularDetector *comp) : m_rectDet(comp) {} - -GeometryHandler::GeometryHandler(StructuredDetector *comp) - : m_structDet(comp) {} - GeometryHandler::GeometryHandler(const GeometryHandler &handler) { if (handler.m_csgObj) { m_csgObj = handler.m_csgObj; @@ -39,10 +34,6 @@ GeometryHandler::GeometryHandler(const GeometryHandler &handler) { m_objComp = handler.m_objComp; if (handler.m_shapeInfo) m_shapeInfo = handler.m_shapeInfo; - if (handler.m_structDet) - m_structDet = handler.m_structDet; - if (handler.m_rectDet) - m_rectDet = handler.m_rectDet; } /// Destructor @@ -53,11 +44,7 @@ boost::shared_ptr<GeometryHandler> GeometryHandler::clone() const { } void GeometryHandler::render() const { - if (m_rectDet) - RenderingHelpers::renderBitmap(*m_rectDet); - else if (m_structDet) - RenderingHelpers::renderStructured(*m_structDet); - else if (m_shapeInfo) + if (m_shapeInfo) RenderingHelpers::renderShape(*m_shapeInfo); else if (m_objComp != nullptr) RenderingHelpers::renderIObjComponent(*m_objComp); @@ -119,4 +106,4 @@ void GeometryHandler::setShapeInfo(detail::ShapeInfo &&shapeInfo) { m_shapeInfo.reset(new detail::ShapeInfo(std::move(shapeInfo))); } } // namespace Geometry -} // namespace Mantid \ No newline at end of file +} // namespace Mantid diff --git a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp index dc43afa598f..ec15829f2b8 100644 --- a/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp +++ b/Framework/Geometry/src/Rendering/GeometryTriangulator.cpp @@ -101,7 +101,7 @@ const TopoDS_Shape &GeometryTriangulator::getOCSurface() { #endif void GeometryTriangulator::checkTriangulated() { - if (m_csgObj != nullptr) { + if (m_csgObj != nullptr || m_meshObj != nullptr) { if (!m_isTriangulated) { triangulate(); } diff --git a/Framework/Geometry/src/Rendering/RenderingHelpers.cpp b/Framework/Geometry/src/Rendering/RenderingHelpers.cpp index faae5965d9c..af230c87276 100644 --- a/Framework/Geometry/src/Rendering/RenderingHelpers.cpp +++ b/Framework/Geometry/src/Rendering/RenderingHelpers.cpp @@ -1,7 +1,9 @@ #include "MantidGeometry/Rendering/RenderingHelpers.h" #include "MantidGeometry/IObjComponent.h" -#include "MantidGeometry/Instrument/RectangularDetector.h" -#include "MantidGeometry/Instrument/StructuredDetector.h" +#include "MantidGeometry/Instrument/ComponentInfo.h" +#include "MantidGeometry/Objects/IObject.h" +#include "MantidGeometry/Objects/ShapeFactory.h" +#include "MantidGeometry/Rendering/GeometryHandler.h" #include "MantidGeometry/Rendering/GeometryTriangulator.h" #include "MantidGeometry/Rendering/ShapeInfo.h" #include "MantidGeometry/Surfaces/Cone.h" @@ -135,109 +137,6 @@ void render(const TopoDS_Shape &ObjSurf) { } #endif -// Render Bitmap for RectangularDetector -void render(const RectangularDetector &rectDet) { - // Because texture colours are combined with the geometry colour - // make sure the current colour is white - glColor3f(1.0f, 1.0f, 1.0f); - - // Nearest-neighbor scaling - GLint texParam = GL_NEAREST; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texParam); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texParam); - - glEnable(GL_TEXTURE_2D); // enable texture mapping - - int texx, texy; - rectDet.getTextureSize(texx, texy); - double tex_frac_x = (1.0 * rectDet.xpixels()) / (texx); - double tex_frac_y = (1.0 * rectDet.ypixels()) / (texy); - - glBegin(GL_QUADS); - - glTexCoord2f(0.0, 0.0); - V3D pos; - pos = rectDet.getRelativePosAtXY(0, 0); - pos += V3D(rectDet.xstep() * (-0.5), rectDet.ystep() * (-0.5), - 0.0); // Adjust to account for the size of a pixel - glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()), - static_cast<GLfloat>(pos.Z())); - - glTexCoord2f(static_cast<GLfloat>(tex_frac_x), 0.0); - pos = rectDet.getRelativePosAtXY(rectDet.xpixels() - 1, 0); - pos += V3D(rectDet.xstep() * (+0.5), rectDet.ystep() * (-0.5), - 0.0); // Adjust to account for the size of a pixel - glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()), - static_cast<GLfloat>(pos.Z())); - - glTexCoord2f(static_cast<GLfloat>(tex_frac_x), - static_cast<GLfloat>(tex_frac_y)); - pos = - rectDet.getRelativePosAtXY(rectDet.xpixels() - 1, rectDet.ypixels() - 1); - pos += V3D(rectDet.xstep() * (+0.5), rectDet.ystep() * (+0.5), - 0.0); // Adjust to account for the size of a pixel - glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()), - static_cast<GLfloat>(pos.Z())); - - glTexCoord2f(0.0, static_cast<GLfloat>(tex_frac_y)); - pos = rectDet.getRelativePosAtXY(0, rectDet.ypixels() - 1); - pos += V3D(rectDet.xstep() * (-0.5), rectDet.ystep() * (+0.5), - 0.0); // Adjust to account for the size of a pixel - glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()), - static_cast<GLfloat>(pos.Z())); - - glEnd(); - if (glGetError() > 0) - std::cout << "OpenGL error in doRender(const RectangularDetector &) \n"; - - glDisable( - GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. -} - -void render(const StructuredDetector &structDet) { - const auto &xVerts = structDet.getXValues(); - const auto &yVerts = structDet.getYValues(); - const auto &r = structDet.getR(); - const auto &g = structDet.getG(); - const auto &b = structDet.getB(); - - if (xVerts.size() != yVerts.size()) - return; - - auto w = structDet.xPixels() + 1; - auto h = structDet.yPixels() + 1; - - glBegin(GL_QUADS); - - for (size_t iy = 0; iy < h - 1; iy++) { - for (size_t ix = 0; ix < w - 1; ix++) { - - glColor3ub((GLubyte)r[(iy * (w - 1)) + ix], - (GLubyte)g[(iy * (w - 1)) + ix], - (GLubyte)b[(iy * (w - 1)) + ix]); - V3D pos; - pos = V3D(xVerts[(iy * w) + ix + w], yVerts[(iy * w) + ix + w], 0.0); - glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()), - static_cast<GLfloat>(pos.Z())); - pos = V3D(xVerts[(iy * w) + ix + w + 1], yVerts[(iy * w) + ix + w + 1], - 0.0); - glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()), - static_cast<GLfloat>(pos.Z())); - pos = V3D(xVerts[(iy * w) + ix + 1], yVerts[(iy * w) + ix + 1], 0.0); - glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()), - static_cast<GLfloat>(pos.Z())); - pos = V3D(xVerts[(iy * w) + ix], yVerts[(iy * w) + ix], 0.0); - glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()), - static_cast<GLfloat>(pos.Z())); - } - } - - glEnd(); - - if (glGetError() > 0) - std::cout << "OpenGL error in doRender(const StructuredDetector &) \n"; -} - void renderSphere(const detail::ShapeInfo &shapeInfo) { // create glu sphere GLUquadricObj *qobj = gluNewQuadric(); @@ -426,13 +325,6 @@ void renderShape(const detail::ShapeInfo &shapeInfo) { return; } } - -void renderBitmap(const RectangularDetector &rectDet) { render(rectDet); } - -void renderStructured(const StructuredDetector &structDet) { - render(structDet); -} - } // namespace RenderingHelpers } // namespace Geometry } // namespace Mantid diff --git a/Framework/Geometry/src/Rendering/ShapeInfo.cpp b/Framework/Geometry/src/Rendering/ShapeInfo.cpp index 3d595d3fecc..1c6b7ba2c08 100644 --- a/Framework/Geometry/src/Rendering/ShapeInfo.cpp +++ b/Framework/Geometry/src/Rendering/ShapeInfo.cpp @@ -68,6 +68,7 @@ bool ShapeInfo::operator==(const ShapeInfo &other) { return m_shape == other.m_shape && m_height == other.m_height && m_radius == other.m_radius && m_points == other.m_points; } + } // namespace detail } // namespace Geometry } // namespace Mantid \ No newline at end of file diff --git a/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp b/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp index e773eadcf65..1b770483367 100644 --- a/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp +++ b/Framework/Geometry/src/Rendering/vtkGeometryCacheReader.cpp @@ -128,8 +128,8 @@ void vtkGeometryCacheReader::readPoints(Poco::XML::Element *pEle, if (pEle->getAttribute("format") == "ascii") { // Read from Ascii std::stringstream buf; buf << pEle->innerText(); - for (size_t i = 0; i < points.size(); i++) { - buf >> points[i]; + for (double &point : points) { + buf >> point; } } // Read from binary otherwise @@ -155,8 +155,8 @@ void vtkGeometryCacheReader::readTriangles(Poco::XML::Element *pEle, if (pEle->getAttribute("format") == "ascii") { // Read from Ascii std::stringstream buf; buf << pEle->innerText(); - for (size_t i = 0; i < faces.size(); i++) { - buf >> faces[i]; + for (unsigned int &face : faces) { + buf >> face; } } // Read from binary otherwise diff --git a/Framework/Geometry/test/CSGObjectTest.h b/Framework/Geometry/test/CSGObjectTest.h index 6a343e1d357..0c9f7bb10e4 100644 --- a/Framework/Geometry/test/CSGObjectTest.h +++ b/Framework/Geometry/test/CSGObjectTest.h @@ -12,6 +12,7 @@ #include "MantidGeometry/Objects/Track.h" #include "MantidGeometry/Rendering/GeometryHandler.h" #include "MantidGeometry/Rendering/ShapeInfo.h" +#include "MantidGeometry/Rendering/ShapeInfo.h" #include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidKernel/make_unique.h" #include "MantidKernel/Material.h" @@ -1270,12 +1271,12 @@ private: SurfLine.push_back(SCompT(73, "s 0.6 0 0 0.4")); // Note that the testObject now manages the "new Plane" - for (auto vc = SurfLine.cbegin(); vc != SurfLine.cend(); ++vc) { - auto A = Geometry::SurfaceFactory::Instance()->processLine(vc->second); + for (const auto &vc : SurfLine) { + auto A = Geometry::SurfaceFactory::Instance()->processLine(vc.second); TSM_ASSERT("Expected a non-null surface from the factory", A); - A->setName(vc->first); - SMap.insert(STYPE::value_type(vc->first, - boost::shared_ptr<Surface>(A.release()))); + A->setName(vc.first); + SMap.insert( + STYPE::value_type(vc.first, boost::shared_ptr<Surface>(A.release()))); } return; diff --git a/Framework/Geometry/test/CenteringGroupTest.h b/Framework/Geometry/test/CenteringGroupTest.h index 16667f7f017..8db17e52a86 100644 --- a/Framework/Geometry/test/CenteringGroupTest.h +++ b/Framework/Geometry/test/CenteringGroupTest.h @@ -65,10 +65,10 @@ private: TSM_ASSERT_EQUALS("Unexpected number of operations for " + symbol, ops.size(), expectedOperations.size()); - for (auto it = expectedOperations.begin(); it != expectedOperations.end(); - ++it) { - TSM_ASSERT("Operation " + (*it).identifier() + " not found in " + symbol, - symOpExistsInCollection(*it, ops)); + for (const auto &expectedOperation : expectedOperations) { + TSM_ASSERT("Operation " + expectedOperation.identifier() + + " not found in " + symbol, + symOpExistsInCollection(expectedOperation, ops)); } CenteringGroup_const_sptr centeringGroup = diff --git a/Framework/Geometry/test/CompositeBraggScattererTest.h b/Framework/Geometry/test/CompositeBraggScattererTest.h index cb65396fb39..0ca949e6122 100644 --- a/Framework/Geometry/test/CompositeBraggScattererTest.h +++ b/Framework/Geometry/test/CompositeBraggScattererTest.h @@ -130,9 +130,9 @@ public: spaceGroup->getEquivalentPositions(V3D(0.2, 0.3, 0.4)); CompositeBraggScatterer_sptr coll = CompositeBraggScatterer::create(); - for (auto pos = positions.begin(); pos != positions.end(); ++pos) { + for (auto &position : positions) { std::ostringstream strm; - strm << (*pos); + strm << position; coll->addScatterer(getInitializedScatterer("Si", strm.str(), 0.01267)); } diff --git a/Framework/Geometry/test/GroupTransformationTest.h b/Framework/Geometry/test/GroupTransformationTest.h index e583286acb0..8d54c5029f0 100644 --- a/Framework/Geometry/test/GroupTransformationTest.h +++ b/Framework/Geometry/test/GroupTransformationTest.h @@ -51,9 +51,9 @@ public: */ std::unordered_set<std::string> elements; std::vector<SymmetryOperation> ops = transformed.getSymmetryOperations(); - for (auto op = ops.begin(); op != ops.end(); ++op) { + for (auto &op : ops) { SymmetryElement_sptr el = - SymmetryElementFactory::Instance().createSymElement(*op); + SymmetryElementFactory::Instance().createSymElement(op); // Check for identity SymmetryElementIdentity_sptr identity = diff --git a/Framework/Geometry/test/IndexingUtilsTest.h b/Framework/Geometry/test/IndexingUtilsTest.h index 200bd61e8ec..8c28ab07fc5 100644 --- a/Framework/Geometry/test/IndexingUtilsTest.h +++ b/Framework/Geometry/test/IndexingUtilsTest.h @@ -29,8 +29,8 @@ public: {-0.90478, -0.50667, 0.51072}, {-0.50387, -0.58561, 0.43502}}; // Dec 2011: Change convention for Q = 2 pi / wavelength - for (size_t i = 0; i < q_vectors.size(); i++) - q_vectors[i] *= (2.0 * M_PI); + for (auto &q_vector : q_vectors) + q_vector *= (2.0 * M_PI); return q_vectors; } @@ -232,8 +232,8 @@ public: void test_Optimize_Direction() { std::vector<int> index_values; int correct_indices[] = {1, 4, 2, 0, 1, 3, 0, -1, 0, -1, -2, -3}; - for (size_t i = 0; i < 12; i++) { - index_values.push_back(correct_indices[i]); + for (int correct_index : correct_indices) { + index_values.push_back(correct_index); } std::vector<V3D> q_vectors = getNatroliteQs(); @@ -372,8 +372,8 @@ public: {2.66668320, 5.29605670, 7.9653444}}; std::vector<V3D> directions; - for (size_t i = 0; i < 5; i++) - directions.emplace_back(vectors[i][0], vectors[i][1], vectors[i][2]); + for (auto &vector : vectors) + directions.emplace_back(vector[0], vector[1], vector[2]); double required_tolerance = 0.12; size_t a_index = 0; @@ -410,8 +410,8 @@ public: {2.66668320, 5.29605670, 7.9653444}}; std::vector<V3D> directions; - for (size_t i = 0; i < 5; i++) - directions.emplace_back(vectors[i][0], vectors[i][1], vectors[i][2]); + for (auto &vector : vectors) + directions.emplace_back(vector[0], vector[1], vector[2]); std::vector<V3D> q_vectors = getNatroliteQs(); double required_tolerance = 0.12; @@ -756,8 +756,8 @@ public: TS_ASSERT_DELTA(direction_list[7].Z(), -0.211325, 1e-5); double dot_prod; - for (size_t i = 0; i < direction_list.size(); i++) { - dot_prod = axis.scalar_prod(direction_list[i]); + for (const auto &direction : direction_list) { + dot_prod = axis.scalar_prod(direction); TS_ASSERT_DELTA(dot_prod, 0, 1e-10); } } diff --git a/Framework/Geometry/test/MockObjects.h b/Framework/Geometry/test/MockObjects.h index 3ac5a0a7278..168b8db8a00 100644 --- a/Framework/Geometry/test/MockObjects.h +++ b/Framework/Geometry/test/MockObjects.h @@ -66,7 +66,9 @@ public: MOCK_CONST_METHOD0(getDetector, Geometry::IDetector_const_sptr()); MOCK_CONST_METHOD0(getInstrument, Geometry::Instrument_const_sptr()); MOCK_CONST_METHOD0(getRunNumber, int()); + MOCK_CONST_METHOD0(getPeakNumber, int()); MOCK_METHOD1(setRunNumber, void(int m_RunNumber)); + MOCK_METHOD1(setPeakNumber, void(int m_PeakNumber)); MOCK_CONST_METHOD0(getMonitorCount, double()); MOCK_METHOD1(setMonitorCount, void(double m_MonitorCount)); MOCK_CONST_METHOD0(getH, double()); @@ -90,6 +92,7 @@ public: MOCK_METHOD1(setWavelength, void(double wavelength)); MOCK_CONST_METHOD0(getWavelength, double()); MOCK_CONST_METHOD0(getScattering, double()); + MOCK_CONST_METHOD0(getAzimuthal, double()); MOCK_CONST_METHOD0(getDSpacing, double()); MOCK_CONST_METHOD0(getTOF, double()); MOCK_CONST_METHOD0(getInitialEnergy, double()); diff --git a/Framework/Geometry/test/ObjCompAssemblyTest.h b/Framework/Geometry/test/ObjCompAssemblyTest.h index 66d74560a77..1c823495acf 100644 --- a/Framework/Geometry/test/ObjCompAssemblyTest.h +++ b/Framework/Geometry/test/ObjCompAssemblyTest.h @@ -371,13 +371,10 @@ public: void test_fail_CreateOutline_for_wrong_component_type() { std::stringstream obj_str; - obj_str << "<segmented-cylinder id=\"stick\">"; - obj_str << "<centre-of-bottom-base "; - obj_str << R"(x="0" y="0" z="0" />)"; - obj_str << R"(<axis x="0" y="1" z="0" /> )"; + obj_str << "<sphere id=\"A\">"; + obj_str << "<centre x=\"4.1\" y=\"2.1\" z=\"8.1\" />"; obj_str << "<radius val=\"0.1\" />"; - obj_str << "<height val=\"0.2\" />"; - obj_str << "</segmented-cylinder>"; + obj_str << "</sphere>"; auto s = Mantid::Geometry::ShapeFactory().createShape(obj_str.str()); ObjCompAssembly bank("BankName"); diff --git a/Framework/Geometry/test/ParObjCompAssemblyTest.h b/Framework/Geometry/test/ParObjCompAssemblyTest.h index 78dd1bbe2d7..6584f674df8 100644 --- a/Framework/Geometry/test/ParObjCompAssemblyTest.h +++ b/Framework/Geometry/test/ParObjCompAssemblyTest.h @@ -107,7 +107,6 @@ public: TS_ASSERT_EQUALS(pcomp.type(), "ObjCompAssembly"); } - void testCreateOutlineCylinder() { std::stringstream obj_str; obj_str << "<cylinder id=\"stick\">"; diff --git a/Framework/Geometry/test/PointGroupTest.h b/Framework/Geometry/test/PointGroupTest.h index 5976f6c1351..1165941734b 100644 --- a/Framework/Geometry/test/PointGroupTest.h +++ b/Framework/Geometry/test/PointGroupTest.h @@ -289,11 +289,11 @@ public: std::vector<PointGroup_sptr> pointgroups = getAllPointGroups(); - for (size_t i = 0; i < pointgroups.size(); ++i) { - TSM_ASSERT_EQUALS(pointgroups[i]->getSymbol() + + for (auto &pointgroup : pointgroups) { + TSM_ASSERT_EQUALS(pointgroup->getSymbol() + ": Unexpected crystal system.", - pointgroups[i]->crystalSystem(), - crystalSystemsMap[pointgroups[i]->getSymbol()]); + pointgroup->crystalSystem(), + crystalSystemsMap[pointgroup->getSymbol()]); } } @@ -446,8 +446,8 @@ private: t.reset(); int h = 0; for (size_t i = 0; i < 1000; ++i) { - for (auto hkl = hkls.begin(); hkl != hkls.end(); ++hkl) { - bool eq = pointGroup->isEquivalent(base, *hkl); + for (auto &hkl : hkls) { + bool eq = pointGroup->isEquivalent(base, hkl); if (eq) { ++h; } diff --git a/Framework/Geometry/test/ReflectionConditionTest.h b/Framework/Geometry/test/ReflectionConditionTest.h index c8841ae0fee..c3400542045 100644 --- a/Framework/Geometry/test/ReflectionConditionTest.h +++ b/Framework/Geometry/test/ReflectionConditionTest.h @@ -58,11 +58,11 @@ public: centeringSymbols.insert("H"); std::vector<ReflectionCondition_sptr> refs = getAllReflectionConditions(); - for (auto it = refs.begin(); it != refs.end(); ++it) { - TSM_ASSERT_DIFFERS((*it)->getSymbol(), - centeringSymbols.find((*it)->getSymbol()), + for (auto &ref : refs) { + TSM_ASSERT_DIFFERS(ref->getSymbol(), + centeringSymbols.find(ref->getSymbol()), centeringSymbols.end()); - centeringSymbols.erase((*it)->getSymbol()); + centeringSymbols.erase(ref->getSymbol()); } // All centering symbols are present if the set is empty. diff --git a/Framework/Geometry/test/ShapeInfoTest.h b/Framework/Geometry/test/ShapeInfoTest.h index 34f7029c25a..573a8b5f839 100644 --- a/Framework/Geometry/test/ShapeInfoTest.h +++ b/Framework/Geometry/test/ShapeInfoTest.h @@ -135,4 +135,4 @@ public: TS_ASSERT_EQUALS(shapeInfo2, m_shapeInfo); TS_ASSERT_DIFFERS(shapeInfo3, m_shapeInfo); } -}; \ No newline at end of file +}; diff --git a/Framework/Geometry/test/SpaceGroupTest.h b/Framework/Geometry/test/SpaceGroupTest.h index 4aa4df38b14..363d32d0d38 100644 --- a/Framework/Geometry/test/SpaceGroupTest.h +++ b/Framework/Geometry/test/SpaceGroupTest.h @@ -66,8 +66,8 @@ public: SpaceGroup spaceGroup(167, "R-3c", *(group * centering)); std::vector<V3D> byOperator = spaceGroup * V3D(0.3, 0.0, 0.25); - for (size_t i = 0; i < byOperator.size(); ++i) { - byOperator[i] = getWrappedVector(byOperator[i]); + for (auto &i : byOperator) { + i = getWrappedVector(i); } std::sort(byOperator.begin(), byOperator.end()); @@ -86,8 +86,8 @@ public: SpaceGroup spaceGroup = getSpaceGroupR3m(); std::vector<V3D> byOperator = spaceGroup * V3D(0.5, 0.0, 0.0); - for (size_t i = 0; i < byOperator.size(); ++i) { - byOperator[i] = getWrappedVector(byOperator[i]); + for (auto &i : byOperator) { + i = getWrappedVector(i); } std::sort(byOperator.begin(), byOperator.end()); diff --git a/Framework/Geometry/test/StructuredDetectorTest.h b/Framework/Geometry/test/StructuredDetectorTest.h index 996d0903d2a..e8d10f62026 100644 --- a/Framework/Geometry/test/StructuredDetectorTest.h +++ b/Framework/Geometry/test/StructuredDetectorTest.h @@ -125,7 +125,7 @@ public: std::vector<double> y{0, 0, 0, 1, 1, 1, 2, 2, 2}; // Initialize with these parameters - det->initialize(2, 2, x, y, true, 0, true, 2, 1); + det->initialize(2, 2, std::move(x), std::move(y), true, 0, true, 2, 1); do_test_on(det); @@ -145,10 +145,11 @@ public: std::vector<double> x{0, 1, 2, 0, 1, 2, 0, 1, 2}; std::vector<double> y{0, 0, 0, 1, 1, 1, 2, 2, 2}; - TSM_ASSERT_THROWS("StructuredDetectors created with beams not aligned " - "along the z-axis should fail.", - det->initialize(2, 2, x, y, false, 0, true, 2, 1), - std::invalid_argument); + TSM_ASSERT_THROWS( + "StructuredDetectors created with beams not aligned " + "along the z-axis should fail.", + det->initialize(2, 2, std::move(x), std::move(y), false, 0, true, 2, 1), + std::invalid_argument); delete det; } @@ -162,19 +163,27 @@ public: std::vector<double> x{0, 1, 2, 0, 1, 2}; std::vector<double> y{0, 0, 0, 1, 1, 1}; + auto x2 = x; + auto y2 = y; + // Initialize with these parameters - TS_ASSERT_THROWS(det->initialize(2, 2, x, y, true, 0, true, 2, 1), - std::invalid_argument); + TS_ASSERT_THROWS( + det->initialize(2, 2, std::move(x), std::move(y), true, 0, true, 2, 1), + std::invalid_argument); - x.resize(3); + x2.resize(3); + auto x3 = x2; + auto y3 = y2; - TS_ASSERT_THROWS(det->initialize(2, 2, x, y, true, 0, true, 2, 1), + TS_ASSERT_THROWS(det->initialize(2, 2, std::move(x2), std::move(y2), true, + 0, true, 2, 1), std::invalid_argument); - x.resize(0); - y.resize(0); + x3.resize(0); + y3.resize(0); - TS_ASSERT_THROWS(det->initialize(2, 2, x, y, true, 0, true, 2, 1), + TS_ASSERT_THROWS(det->initialize(2, 2, std::move(x3), std::move(y3), true, + 0, true, 2, 1), std::invalid_argument); delete det; diff --git a/Framework/Geometry/test/SymmetryOperationFactoryTest.h b/Framework/Geometry/test/SymmetryOperationFactoryTest.h index 7e425a0df07..978514be0ba 100644 --- a/Framework/Geometry/test/SymmetryOperationFactoryTest.h +++ b/Framework/Geometry/test/SymmetryOperationFactoryTest.h @@ -125,8 +125,8 @@ public: // Clear factory std::vector<std::string> allSymbols = SymmetryOperationFactory::Instance().subscribedSymbols(); - for (auto it = allSymbols.begin(); it != allSymbols.end(); ++it) { - SymmetryOperationFactory::Instance().unsubscribeSymOp(*it); + for (auto &symbol : allSymbols) { + SymmetryOperationFactory::Instance().unsubscribeSymOp(symbol); } // Subscribe two symmetry operations @@ -146,8 +146,8 @@ public: SymmetryOperationFactory::Instance().unsubscribeSymOp("-x,-y,-z"); // Restore factory - for (auto it = allSymbols.begin(); it != allSymbols.end(); ++it) { - SymmetryOperationFactory::Instance().subscribeSymOp(*it); + for (auto &symbol : allSymbols) { + SymmetryOperationFactory::Instance().subscribeSymOp(symbol); } } }; diff --git a/Framework/HistogramData/inc/MantidHistogramData/Histogram.h b/Framework/HistogramData/inc/MantidHistogramData/Histogram.h index 0b3d1c4ccc5..c1955f6deb7 100644 --- a/Framework/HistogramData/inc/MantidHistogramData/Histogram.h +++ b/Framework/HistogramData/inc/MantidHistogramData/Histogram.h @@ -239,7 +239,7 @@ Histogram::setUncertainties(const FrequencyStandardDeviations &e); @param y Optional Y data for the Histogram. Can be Counts or Frequencies. @param e Optional E data for the Histogram. Can be Variances or StandardDeviations for Counts or Frequencies. If not specified or null, the - standard deviations will be set as the suare root of the Y data. + standard deviations will be set as the square root of the Y data. */ template <class TX, class TY, class TE> Histogram::Histogram(const TX &x, const TY &y, const TE &e) { diff --git a/Framework/HistogramData/inc/MantidHistogramData/HistogramBuilder.h b/Framework/HistogramData/inc/MantidHistogramData/HistogramBuilder.h index f99d3a7b586..7442ee4845f 100644 --- a/Framework/HistogramData/inc/MantidHistogramData/HistogramBuilder.h +++ b/Framework/HistogramData/inc/MantidHistogramData/HistogramBuilder.h @@ -50,6 +50,10 @@ public: template <typename... T> void setE(T &&... data) { m_e = Kernel::make_cow<HistogramE>(std::forward<T>(data)...); } + /// Sets Dx information. Can be a length or actual Dx data. + template <typename... T> void setDx(T &&... data) { + d_x = Kernel::make_cow<HistogramDx>(std::forward<T>(data)...); + } void setDistribution(bool isDistribution); Histogram build() const; @@ -59,6 +63,7 @@ private: Kernel::cow_ptr<HistogramX> m_x{nullptr}; Kernel::cow_ptr<HistogramY> m_y{nullptr}; Kernel::cow_ptr<HistogramE> m_e{nullptr}; + Kernel::cow_ptr<HistogramDx> d_x{nullptr}; }; } // namespace HistogramData diff --git a/Framework/HistogramData/src/HistogramBuilder.cpp b/Framework/HistogramData/src/HistogramBuilder.cpp index 44932841a90..6f43a9f72df 100644 --- a/Framework/HistogramData/src/HistogramBuilder.cpp +++ b/Framework/HistogramData/src/HistogramBuilder.cpp @@ -34,6 +34,8 @@ Histogram HistogramBuilder::build() const { } if (m_e) histogram->setSharedE(m_e); + if (d_x) + histogram->setSharedDx(d_x); return *histogram; } diff --git a/Framework/HistogramData/test/HistogramBuilderTest.h b/Framework/HistogramData/test/HistogramBuilderTest.h index f70363696e1..861825d596b 100644 --- a/Framework/HistogramData/test/HistogramBuilderTest.h +++ b/Framework/HistogramData/test/HistogramBuilderTest.h @@ -39,6 +39,8 @@ public: TS_ASSERT_THROWS(builder.build(), std::logic_error); builder.setY(6); TS_ASSERT_THROWS(builder.build(), std::logic_error); + builder.setDx(3); + TS_ASSERT_THROWS(builder.build(), std::logic_error); } void test_build_from_size() { @@ -63,6 +65,31 @@ public: TS_ASSERT_EQUALS(hist.xMode(), Histogram::XMode::Points); TS_ASSERT_EQUALS(hist.yMode(), Histogram::YMode::Frequencies); } + + void test_build_Dx() { + HistogramBuilder builder; + builder.setX(5); + builder.setY(5); + builder.setDx(5); + const auto hist = builder.build(); + TS_ASSERT_EQUALS(hist.x().size(), 5); + TS_ASSERT_EQUALS(hist.y().size(), 5); + TS_ASSERT_EQUALS(hist.e().size(), 5); + TS_ASSERT_EQUALS(hist.dx().size(), 5); + } + + void test_build_Dx_with_bin_edges() { + HistogramBuilder builder; + builder.setX(5); + builder.setY(4); + builder.setDx(4); + const auto hist = builder.build(); + TS_ASSERT_EQUALS(hist.x().size(), 5); + TS_ASSERT_EQUALS(hist.y().size(), 4); + TS_ASSERT_EQUALS(hist.e().size(), 4); + TS_ASSERT_EQUALS(hist.dx().size(), 4); + TS_ASSERT_EQUALS(hist.xMode(), Histogram::XMode::BinEdges); + } }; #endif /* MANTID_HISTOGRAMDATA_HISTOGRAMBUILDERTEST_H_ */ diff --git a/Framework/ICat/inc/MantidICat/CatalogDownloadDataFiles.h b/Framework/ICat/inc/MantidICat/CatalogDownloadDataFiles.h index f26e863bc9c..1515f9f8d70 100644 --- a/Framework/ICat/inc/MantidICat/CatalogDownloadDataFiles.h +++ b/Framework/ICat/inc/MantidICat/CatalogDownloadDataFiles.h @@ -60,6 +60,9 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"DownloadFile", "CatalogGetDataFiles", "CatalogLogin"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Catalog"; diff --git a/Framework/ICat/inc/MantidICat/CatalogGetDataFiles.h b/Framework/ICat/inc/MantidICat/CatalogGetDataFiles.h index c84de8a944c..e533b041b74 100644 --- a/Framework/ICat/inc/MantidICat/CatalogGetDataFiles.h +++ b/Framework/ICat/inc/MantidICat/CatalogGetDataFiles.h @@ -57,6 +57,9 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CatalogDownloadDataFiles", "CatalogGetDataSets", "CatalogLogin"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Catalog"; diff --git a/Framework/ICat/inc/MantidICat/CatalogGetDataSets.h b/Framework/ICat/inc/MantidICat/CatalogGetDataSets.h index db6a9543185..283a9629a47 100644 --- a/Framework/ICat/inc/MantidICat/CatalogGetDataSets.h +++ b/Framework/ICat/inc/MantidICat/CatalogGetDataSets.h @@ -57,6 +57,9 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CatalogGetDataFiles", "CatalogDownloadDataFiles", "CatalogLogin"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Catalog"; diff --git a/Framework/ICat/inc/MantidICat/CatalogKeepAlive.h b/Framework/ICat/inc/MantidICat/CatalogKeepAlive.h index 5e042ba5b5a..2264f54c27e 100644 --- a/Framework/ICat/inc/MantidICat/CatalogKeepAlive.h +++ b/Framework/ICat/inc/MantidICat/CatalogKeepAlive.h @@ -53,6 +53,9 @@ public: } /// Algorithm's version for identification. int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CatalogLogin"}; + } /// Algorithm's category for identification. const std::string category() const override { return "DataHandling\\Catalog"; diff --git a/Framework/ICat/inc/MantidICat/CatalogListInstruments.h b/Framework/ICat/inc/MantidICat/CatalogListInstruments.h index 8a2e97ed352..38829e19b28 100644 --- a/Framework/ICat/inc/MantidICat/CatalogListInstruments.h +++ b/Framework/ICat/inc/MantidICat/CatalogListInstruments.h @@ -48,6 +48,9 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CatalogListInvestigationTypes"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Catalog"; diff --git a/Framework/ICat/inc/MantidICat/CatalogListInvestigationTypes.h b/Framework/ICat/inc/MantidICat/CatalogListInvestigationTypes.h index 52099cee675..277c03ac35f 100644 --- a/Framework/ICat/inc/MantidICat/CatalogListInvestigationTypes.h +++ b/Framework/ICat/inc/MantidICat/CatalogListInvestigationTypes.h @@ -50,6 +50,9 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CatalogListInstruments"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Catalog"; diff --git a/Framework/ICat/inc/MantidICat/CatalogLogin.h b/Framework/ICat/inc/MantidICat/CatalogLogin.h index f18ab9298d4..f40c9cd7777 100644 --- a/Framework/ICat/inc/MantidICat/CatalogLogin.h +++ b/Framework/ICat/inc/MantidICat/CatalogLogin.h @@ -54,6 +54,9 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CatalogLogout", "CatalogSearch", "CatalogPublish"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Catalog"; diff --git a/Framework/ICat/inc/MantidICat/CatalogLogout.h b/Framework/ICat/inc/MantidICat/CatalogLogout.h index c79808c0b3d..b8b48f74d79 100644 --- a/Framework/ICat/inc/MantidICat/CatalogLogout.h +++ b/Framework/ICat/inc/MantidICat/CatalogLogout.h @@ -51,6 +51,9 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CatalogLogin"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Catalog"; diff --git a/Framework/ICat/inc/MantidICat/CatalogMyDataSearch.h b/Framework/ICat/inc/MantidICat/CatalogMyDataSearch.h index fb3c806dfe2..6ba41b4702f 100644 --- a/Framework/ICat/inc/MantidICat/CatalogMyDataSearch.h +++ b/Framework/ICat/inc/MantidICat/CatalogMyDataSearch.h @@ -57,6 +57,9 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CatalogSearch"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Catalog"; diff --git a/Framework/ICat/inc/MantidICat/CatalogPublish.h b/Framework/ICat/inc/MantidICat/CatalogPublish.h index b98865b41ca..6bf0e884522 100644 --- a/Framework/ICat/inc/MantidICat/CatalogPublish.h +++ b/Framework/ICat/inc/MantidICat/CatalogPublish.h @@ -59,6 +59,9 @@ public: } /// Algorithm's version for identification. int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CatalogLogin"}; + } /// Algorithm's category for identification. const std::string category() const override { return "DataHandling\\Catalog"; diff --git a/Framework/ICat/inc/MantidICat/CatalogSearch.h b/Framework/ICat/inc/MantidICat/CatalogSearch.h index 9e235f557f2..d2e9b471c69 100644 --- a/Framework/ICat/inc/MantidICat/CatalogSearch.h +++ b/Framework/ICat/inc/MantidICat/CatalogSearch.h @@ -68,6 +68,10 @@ public: } /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CatalogMyDataSearch", "CatalogGetDataFiles", "CatalogLogin", + "CatalogPublish"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { return "DataHandling\\Catalog"; diff --git a/Framework/Indexing/src/IndexInfo.cpp b/Framework/Indexing/src/IndexInfo.cpp index ab3a15e754d..db12c33e2f0 100644 --- a/Framework/Indexing/src/IndexInfo.cpp +++ b/Framework/Indexing/src/IndexInfo.cpp @@ -90,7 +90,8 @@ IndexInfo::~IndexInfo() = default; IndexInfo &IndexInfo::operator=(const IndexInfo &other) { auto copy(other); - return *this = std::move(copy); + *this = std::move(copy); + return *this; } IndexInfo &IndexInfo::operator=(IndexInfo &&) noexcept = default; diff --git a/Framework/Kernel/CMakeLists.txt b/Framework/Kernel/CMakeLists.txt index 81ebe6576c5..04396eb710a 100644 --- a/Framework/Kernel/CMakeLists.txt +++ b/Framework/Kernel/CMakeLists.txt @@ -673,7 +673,7 @@ install ( TARGETS Kernel ${SYSTEM_PACKAGE_TARGET} DESTINATION ${LIB_DIR} ) # Create the properties file for the installer set ( MANTID_ROOT_BUILD ${MANTID_ROOT} ) -if ( APPLE ) +if ( APPLE AND ENABLE_MANTIDPLOT ) set ( MANTID_ROOT ../.. ) else () set ( MANTID_ROOT .. ) diff --git a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h index 3acb4f61207..dee6e74546c 100644 --- a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h +++ b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h @@ -76,7 +76,7 @@ public: std::string setDataItem(const boost::shared_ptr<DataItem> data) override; PropertyWithValue &operator=(const PropertyWithValue &right); PropertyWithValue &operator+=(Property const *right) override; - virtual TYPE &operator=(const TYPE &value); + virtual PropertyWithValue &operator=(const TYPE &value); virtual const TYPE &operator()() const; virtual operator const TYPE &() const; std::string isValid() const override; diff --git a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc index a4902017dbb..af580021274 100644 --- a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc +++ b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc @@ -259,7 +259,7 @@ operator+=(Property const *right) { * @return the reference to itself */ template <typename TYPE> -TYPE &PropertyWithValue<TYPE>::operator=(const TYPE &value) { +PropertyWithValue<TYPE> &PropertyWithValue<TYPE>::operator=(const TYPE &value) { TYPE oldValue = m_value; if (std::is_same<TYPE, std::string>::value) { std::string valueCopy = toString(value); @@ -272,10 +272,10 @@ TYPE &PropertyWithValue<TYPE>::operator=(const TYPE &value) { } std::string problem = this->isValid(); if (problem.empty()) { - return m_value; + return *this; } else if (problem == "_alias") { m_value = getValueForAlias(value); - return m_value; + return *this; } else { m_value = oldValue; throw std::invalid_argument(problem); diff --git a/Framework/Kernel/inc/MantidKernel/Statistics.h b/Framework/Kernel/inc/MantidKernel/Statistics.h index 0d3cd0a6143..af8d46e77ee 100644 --- a/Framework/Kernel/inc/MantidKernel/Statistics.h +++ b/Framework/Kernel/inc/MantidKernel/Statistics.h @@ -93,6 +93,9 @@ Statistics getStatistics(const std::vector<TYPE> &data, /// Return the Z score values for a dataset template <typename TYPE> std::vector<double> getZscore(const std::vector<TYPE> &data); +template <typename TYPE> +std::vector<double> getWeightedZscore(const std::vector<TYPE> &data, + const std::vector<TYPE> &weights); /// Return the modified Z score values for a dataset template <typename TYPE> std::vector<double> getModifiedZscore(const std::vector<TYPE> &data, diff --git a/Framework/Kernel/src/ConfigService.cpp b/Framework/Kernel/src/ConfigService.cpp index ff37f5e09b0..16a6189f438 100644 --- a/Framework/Kernel/src/ConfigService.cpp +++ b/Framework/Kernel/src/ConfigService.cpp @@ -1774,8 +1774,9 @@ std::string ConfigServiceImpl::getFacilityFilename(const std::string &fName) { // look through all the possible files for (; instrDir != directoryNames.end(); ++instrDir) { - std::string filename = (*instrDir) + "Facilities.xml"; - + Poco::Path p(*instrDir); + p.append("Facilities.xml"); + std::string filename = p.toString(); Poco::File fileObj(filename); // stop when you find the first one if (fileObj.exists()) diff --git a/Framework/Kernel/src/Statistics.cpp b/Framework/Kernel/src/Statistics.cpp index a42617046cc..42bf89c2a82 100644 --- a/Framework/Kernel/src/Statistics.cpp +++ b/Framework/Kernel/src/Statistics.cpp @@ -102,7 +102,43 @@ std::vector<double> getZscore(const vector<TYPE> &data) { } for (auto it = data.cbegin(); it != data.cend(); ++it) { double tmp = static_cast<double>(*it); - Zscore.push_back(fabs((tmp - stats.mean) / stats.standard_deviation)); + Zscore.push_back(fabs((stats.mean - tmp) / stats.standard_deviation)); + } + return Zscore; +} +/** + * There are enough special cases in determining the Z score where it useful to + * put it in a single function. + */ +template <typename TYPE> +std::vector<double> getWeightedZscore(const vector<TYPE> &data, + const vector<TYPE> &weights) { + if (data.size() < 3) { + std::vector<double> Zscore(data.size(), 0.); + return Zscore; + } + std::vector<double> Zscore; + Statistics stats = getStatistics(data); + if (stats.standard_deviation == 0.) { + std::vector<double> Zscore(data.size(), 0.); + return Zscore; + } + double sumWeights = 0.0; + double sumWeightedData = 0.0; + double weightedVariance = 0.0; + for (size_t it = 0; it != data.size(); ++it) { + sumWeights += static_cast<double>(weights[it]); + sumWeightedData += static_cast<double>(weights[it] * data[it]); + } + double weightedMean = sumWeightedData / sumWeights; + for (size_t it = 0; it != data.size(); ++it) { + weightedVariance += + std::pow(static_cast<double>(data[it]) - weightedMean, 2) * + std::pow(static_cast<double>(weights[it]) / sumWeights, 2); + } + for (auto it = data.cbegin(); it != data.cend(); ++it) { + Zscore.push_back(fabs((static_cast<double>(*it) - weightedMean) / + std::sqrt(weightedVariance))); } return Zscore; } @@ -406,6 +442,8 @@ std::vector<double> getMomentsAboutMean(const std::vector<TYPE> &x, getStatistics<TYPE>(const vector<TYPE> &, const unsigned int); \ template MANTID_KERNEL_DLL std::vector<double> getZscore<TYPE>( \ const vector<TYPE> &); \ + template MANTID_KERNEL_DLL std::vector<double> getWeightedZscore<TYPE>( \ + const vector<TYPE> &, const vector<TYPE> &); \ template MANTID_KERNEL_DLL std::vector<double> getModifiedZscore<TYPE>( \ const vector<TYPE> &, const bool); \ template MANTID_KERNEL_DLL std::vector<double> getMomentsAboutOrigin<TYPE>( \ diff --git a/Framework/Kernel/test/ArrayPropertyTest.h b/Framework/Kernel/test/ArrayPropertyTest.h index 75408b0d46d..f15f1f2ab2e 100644 --- a/Framework/Kernel/test/ArrayPropertyTest.h +++ b/Framework/Kernel/test/ArrayPropertyTest.h @@ -242,21 +242,24 @@ public: ArrayProperty<int> i("i"); TS_ASSERT(i.isDefault()) std::vector<int> ii(3, 4); - TS_ASSERT_EQUALS(i = ii, ii) + i = ii; + TS_ASSERT_EQUALS(i.operator()(), ii); TS_ASSERT_EQUALS(i.operator()()[1], 4) TS_ASSERT(!i.isDefault()) ArrayProperty<double> d("d"); TS_ASSERT(d.isDefault()) std::vector<double> dd(5, 9.99); - TS_ASSERT_EQUALS(d = dd, dd) + d = dd; + TS_ASSERT_EQUALS(d.operator()(), dd); TS_ASSERT_EQUALS(d.operator()()[3], 9.99) TS_ASSERT(!d.isDefault()) ArrayProperty<std::string> s("s"); TS_ASSERT(s.isDefault()) std::vector<std::string> ss(2, "zzz"); - TS_ASSERT_EQUALS(s = ss, ss) + s = ss; + TS_ASSERT_EQUALS(s.operator()(), ss) TS_ASSERT_EQUALS(s.operator()()[0], "zzz") TS_ASSERT(!s.isDefault()) } diff --git a/Framework/Kernel/test/ConfigServiceTest.h b/Framework/Kernel/test/ConfigServiceTest.h index bd2f247a1d1..0485fd2b6c0 100644 --- a/Framework/Kernel/test/ConfigServiceTest.h +++ b/Framework/Kernel/test/ConfigServiceTest.h @@ -352,9 +352,9 @@ public: ConfigService::Instance().getInstrumentDirectory()); // check all of the directory entries actually exist - for (auto it = directories.begin(); it != directories.end(); ++it) { - Poco::File directory(*it); - TSM_ASSERT(*it + " does not exist", directory.exists()); + for (auto &directoryPath : directories) { + Poco::File directory(directoryPath); + TSM_ASSERT(directoryPath + " does not exist", directory.exists()); } } diff --git a/Framework/Kernel/test/DiskBufferISaveableTest.h b/Framework/Kernel/test/DiskBufferISaveableTest.h index ea6dc040a3a..da1a11e7397 100644 --- a/Framework/Kernel/test/DiskBufferISaveableTest.h +++ b/Framework/Kernel/test/DiskBufferISaveableTest.h @@ -90,15 +90,14 @@ public: } void tearDown() override { - for (size_t i = 0; i < data.size(); i++) { - delete data[i]; - data[i] = nullptr; + for (auto &item : data) { + delete item; } - for (size_t i = 0; i < bigData.size(); i++) { - delete bigData[i]; - bigData[i] = nullptr; + for (auto &bigItem : bigData) { + delete bigItem; } + ISaveableTester::fakeFile = ""; } void testIsaveable() { @@ -435,9 +434,9 @@ public: void test_smallCache_writeBuffer() { CPUTimer tim; DiskBuffer dbuf(3); - for (size_t i = 0; i < data.size(); i++) { - dbuf.toWrite(data[i]); - data[i]->setBusy(false); + for (auto &i : data) { + dbuf.toWrite(i); + i->setBusy(false); } std::cout << " Elapsed : " << tim << " to load " << num << " into MRU.\n"; } @@ -445,13 +444,13 @@ public: void test_smallCache_no_writeBuffer() { CPUTimer tim; DiskBuffer dbuf(0); - for (size_t i = 0; i < data.size(); i++) { - data[i]->setBusy(true); // Items won't do any real saving + for (auto &i : data) { + i->setBusy(true); // Items won't do any real saving } - for (int i = 0; i < int(data.size()); i++) { - dbuf.toWrite(data[i]); - data[i]->setBusy(false); + for (auto &i : data) { + dbuf.toWrite(i); + i->setBusy(false); } std::cout << " Elapsed : " << tim << " to load " << num << " into MRU (no write cache).\n"; @@ -460,9 +459,9 @@ public: void test_largeCache_writeBuffer() { CPUTimer tim; DiskBuffer dbuf(1000); - for (int i = 0; i < int(data.size()); i++) { - dbuf.toWrite(data[i]); - data[i]->setBusy(false); + for (auto &i : data) { + dbuf.toWrite(i); + i->setBusy(false); } std::cout << tim << " to load " << num << " into MRU.\n"; } @@ -470,9 +469,9 @@ public: void test_largeCache_noWriteBuffer() { CPUTimer tim; DiskBuffer dbuf(0); - for (int i = 0; i < int(data.size()); i++) { - dbuf.toWrite(data[i]); - data[i]->setBusy(false); + for (auto &i : data) { + dbuf.toWrite(i); + i->setBusy(false); } std::cout << " Elapsed : " << tim << " to load " << num << " into MRU (no write buffer).\n"; diff --git a/Framework/Kernel/test/DiskBufferTest.h b/Framework/Kernel/test/DiskBufferTest.h index 8074ec68120..4911bcdaca6 100644 --- a/Framework/Kernel/test/DiskBufferTest.h +++ b/Framework/Kernel/test/DiskBufferTest.h @@ -115,9 +115,8 @@ public: } void tearDown() override { - for (size_t i = 0; i < data.size(); i++) { - delete data[i]; - data[i] = nullptr; + for (auto &i : data) { + delete i; } } void xest_nothing() { @@ -171,8 +170,8 @@ public: ////-------------------------------------------------------------------------------- ///** Sorts by file position when writing to a file */ void test_writesOutInFileOrder() { - for (size_t i = 0; i < data.size(); i++) { - data[i]->setDataChanged(); + for (auto &i : data) { + i->setDataChanged(); } // Room for 2 objects of size 2 in the to-write cache DiskBuffer dbuf(2 * 2); @@ -796,9 +795,9 @@ public: void test_withFakeSeeking_withWriteBuffer() { CPUTimer tim; DiskBuffer dbuf(10); - for (int i = 0; i < int(dataSeek.size()); i++) { + for (auto &i : dataSeek) { // Pretend you just loaded the data - dataSeek[i]->load(dbuf); + i->load(dbuf); } std::cout << tim << " to load " << dataSeek.size() << " into MRU with fake seeking. \n"; @@ -809,9 +808,9 @@ public: void test_withFakeSeeking_noWriteBuffer() { CPUTimer tim; DiskBuffer dbuf(0); - for (int i = 0; i < int(dataSeek.size()); i++) { + for (auto &i : dataSeek) { // Pretend you just loaded the data - dataSeek[i]->load(dbuf); + i->load(dbuf); } std::cout << tim << " to load " << dataSeek.size() << " into MRU with fake seeking. \n"; @@ -823,10 +822,10 @@ public: CPUTimer tim; DiskBuffer dbuf(20); dbuf.setFileLength(dataSeek.size()); - for (int i = 0; i < int(dataSeek.size()); i++) { + for (auto &i : dataSeek) { // Pretend you just loaded the data - dataSeek[i]->grow(dbuf, true); - dbuf.toWrite(dataSeek[i]); + i->grow(dbuf, true); + dbuf.toWrite(i); } std::cout << "About to flush the cache to finish writes.\n"; dbuf.flushCache(); @@ -840,10 +839,10 @@ public: void test_withFakeSeeking_growingData_savingWithoutUsingMRU() { CPUTimer tim; DiskBuffer dbuf(dataSeek.size()); - for (int i = 0; i < int(dataSeek.size()); i++) { + for (auto &i : dataSeek) { // Pretend you just loaded the data - dataSeek[i]->grow(dbuf, false); - dataSeek[i]->save(); + i->grow(dbuf, false); + i->save(); } std::cout << tim << " to grow " << dataSeek.size() << " into MRU with fake seeking. \n"; diff --git a/Framework/Kernel/test/FileDescriptorTest.h b/Framework/Kernel/test/FileDescriptorTest.h index ec7856f06e1..a3957fa4433 100644 --- a/Framework/Kernel/test/FileDescriptorTest.h +++ b/Framework/Kernel/test/FileDescriptorTest.h @@ -23,14 +23,14 @@ public: auto &cfg = Mantid::Kernel::ConfigService::Instance(); cfg.reset(); const auto &dataPaths = cfg.getDataSearchDirs(); - for (auto it = dataPaths.begin(); it != dataPaths.end(); ++it) { - Poco::Path nxsPath(*it, "CNCS_7860_event.nxs"); + for (const auto &dataPath : dataPaths) { + Poco::Path nxsPath(dataPath, "CNCS_7860_event.nxs"); if (Poco::File(nxsPath).exists()) m_testNexusPath = nxsPath.toString(); - Poco::Path nonNxsPath(*it, "CSP79590.raw"); + Poco::Path nonNxsPath(dataPath, "CSP79590.raw"); if (Poco::File(nonNxsPath).exists()) m_testNonNexusPath = nonNxsPath.toString(); - Poco::Path asciiPath(*it, "AsciiExample.txt"); + Poco::Path asciiPath(dataPath, "AsciiExample.txt"); if (Poco::File(asciiPath).exists()) m_testAsciiPath = asciiPath.toString(); diff --git a/Framework/Kernel/test/GlobTest.h b/Framework/Kernel/test/GlobTest.h index 1908edbff8e..92057289d2f 100644 --- a/Framework/Kernel/test/GlobTest.h +++ b/Framework/Kernel/test/GlobTest.h @@ -34,9 +34,8 @@ public: TS_ASSERT(files.size() > 0); size_t matches = 0; - for (std::set<std::string>::const_iterator f = files.begin(); - f != files.end(); ++f) { - Poco::Path path = *f; + for (const auto &file : files) { + Poco::Path path = file; std::string project = path[path.depth() - 1]; if (project == "API") ++matches; @@ -96,9 +95,8 @@ public: TS_ASSERT(files.size() > 0); size_t matches = 0; - for (std::set<std::string>::const_iterator f = files.begin(); - f != files.end(); ++f) { - Poco::Path path = *f; + for (const auto &file : files) { + Poco::Path path = file; std::string project = path[path.depth() - 1]; if (project == "API") ++matches; diff --git a/Framework/Kernel/test/InterpolationTest.h b/Framework/Kernel/test/InterpolationTest.h index a2ed45e607b..a54e36bb57a 100644 --- a/Framework/Kernel/test/InterpolationTest.h +++ b/Framework/Kernel/test/InterpolationTest.h @@ -206,13 +206,13 @@ public: Interpolation interpolationOne; interpolationOne.addPoint(200, 2.0); - for (size_t i = 0; i < m_tableXValues.size(); ++i) { + for (double m_tableXValue : m_tableXValues) { // When there are zero values in the interpolation, it returns 0.0 - checkValue(interpolationZero, m_tableXValues[i], 0.0, + checkValue(interpolationZero, m_tableXValue, 0.0, "zero interpolation values"); // With one value, it returns this one value for any x. - checkValue(interpolationOne, m_tableXValues[i], 2.0, + checkValue(interpolationOne, m_tableXValue, 2.0, "one interpolation value"); } } diff --git a/Framework/Kernel/test/MutexTest.h b/Framework/Kernel/test/MutexTest.h index b823f9e03fc..e85fac873cc 100644 --- a/Framework/Kernel/test/MutexTest.h +++ b/Framework/Kernel/test/MutexTest.h @@ -24,8 +24,7 @@ void reader() { Poco::ScopedReadRWLock lock(_access); // std::cout << "Read launching\n"; // do work here, without anyone having exclusive access - for (size_t i = 0; i < shared_data.size(); i++) { - double val = shared_data[i]; + for (double val : shared_data) { UNUSED_ARG(val) } // std::cout << "Read finished\n"; @@ -38,8 +37,8 @@ void unconditional_writer() { // do work here, with exclusive access shared_data.resize(shared_data.size() + 1, 2.345); // Dumb thing to slow down the writer - for (size_t i = 0; i < shared_data.size(); i++) - shared_data[i] = 4.567; + for (double &i : shared_data) + i = 4.567; // std::cout << "Write finished\n"; } diff --git a/Framework/Kernel/test/NDPseudoRandomNumberGeneratorTest.h b/Framework/Kernel/test/NDPseudoRandomNumberGeneratorTest.h index 18de5157a0f..197da2111b8 100644 --- a/Framework/Kernel/test/NDPseudoRandomNumberGeneratorTest.h +++ b/Framework/Kernel/test/NDPseudoRandomNumberGeneratorTest.h @@ -38,8 +38,8 @@ public: const double start(2.1), end(3.4); NDGenerator_sptr ndRand = createTestGenerator(12345, start, end); std::vector<double> firstPoint = ndRand->nextPoint(); - for (size_t i = 0; i < firstPoint.size(); ++i) { - TS_ASSERT(firstPoint[i] >= start && firstPoint[i] <= end); + for (double i : firstPoint) { + TS_ASSERT(i >= start && i <= end); } } diff --git a/Framework/Kernel/test/NexusDescriptorTest.h b/Framework/Kernel/test/NexusDescriptorTest.h index bf8f8944637..0238213b82a 100644 --- a/Framework/Kernel/test/NexusDescriptorTest.h +++ b/Framework/Kernel/test/NexusDescriptorTest.h @@ -28,16 +28,16 @@ public: NexusDescriptorTest() { using Mantid::Kernel::ConfigService; auto dataPaths = ConfigService::Instance().getDataSearchDirs(); - for (auto it = dataPaths.begin(); it != dataPaths.end(); ++it) { - Poco::Path hdf5Path(*it, "CNCS_7860_event.nxs"); + for (auto &dataPath : dataPaths) { + Poco::Path hdf5Path(dataPath, "CNCS_7860_event.nxs"); if (Poco::File(hdf5Path).exists()) m_testHDF5Path = hdf5Path.toString(); - Poco::Path hdf4Path(*it, "argus0026287.nxs"); + Poco::Path hdf4Path(dataPath, "argus0026287.nxs"); if (Poco::File(hdf4Path).exists()) m_testHDF4Path = hdf4Path.toString(); - Poco::Path nonhdf5Path(*it, "CSP79590.raw"); + Poco::Path nonhdf5Path(dataPath, "CSP79590.raw"); if (Poco::File(nonhdf5Path).exists()) m_testNonHDFPath = nonhdf5Path.toString(); diff --git a/Framework/Kernel/test/PropertyManagerTest.h b/Framework/Kernel/test/PropertyManagerTest.h index b8b496e8293..f23ad6e6fb3 100644 --- a/Framework/Kernel/test/PropertyManagerTest.h +++ b/Framework/Kernel/test/PropertyManagerTest.h @@ -90,12 +90,12 @@ public: TS_ASSERT_EQUALS(manager.propertyCount(), 3); const std::vector<Property *> &props = manager.getProperties(); - for (auto iter = props.begin(); iter != props.end(); ++iter) { - Property *prop = *iter; + for (auto iter : props) { + Property *prop = iter; std::string msg = "Property " + prop->name() + " has not been changed to a FilteredTimeSeries"; auto filteredProp = - dynamic_cast<FilteredTimeSeriesProperty<double> *>(*iter); + dynamic_cast<FilteredTimeSeriesProperty<double> *>(iter); TSM_ASSERT(msg, filteredProp); } diff --git a/Framework/Kernel/test/PropertyWithValueTest.h b/Framework/Kernel/test/PropertyWithValueTest.h index 0dd1155b140..6f3d65b5a80 100644 --- a/Framework/Kernel/test/PropertyWithValueTest.h +++ b/Framework/Kernel/test/PropertyWithValueTest.h @@ -690,9 +690,9 @@ public: auto values = property.allowedValues(); auto possibilities = OptionalBool::strToEmumMap(); TSM_ASSERT_EQUALS("3 states allowed", possibilities.size(), values.size()); - for (auto it = values.begin(); it != values.end(); ++it) { + for (auto &value : values) { TSM_ASSERT("value not a known state", - possibilities.find(*it) != possibilities.end()); + possibilities.find(value) != possibilities.end()); } } diff --git a/Framework/Kernel/test/SobolSequenceTest.h b/Framework/Kernel/test/SobolSequenceTest.h index 0a61b278d64..3abe083aa37 100644 --- a/Framework/Kernel/test/SobolSequenceTest.h +++ b/Framework/Kernel/test/SobolSequenceTest.h @@ -87,10 +87,10 @@ private: {0.75, 0.25, 0.75, 0.25, 0.75}, {0.25, 0.75, 0.25, 0.75, 0.25}, }; - for (std::size_t i = 0; i < 3; ++i) { + for (auto &expectedValue : expectedValues) { const std::vector<double> randPoint = randGen.nextPoint(); for (std::size_t j = 0; j < 5; ++j) { - TS_ASSERT_DELTA(randPoint[j], expectedValues[i][j], 1e-12); + TS_ASSERT_DELTA(randPoint[j], expectedValue[j], 1e-12); } } } diff --git a/Framework/Kernel/test/ThreadSchedulerTest.h b/Framework/Kernel/test/ThreadSchedulerTest.h index 587bb4e5707..60be77fbe9b 100644 --- a/Framework/Kernel/test/ThreadSchedulerTest.h +++ b/Framework/Kernel/test/ThreadSchedulerTest.h @@ -87,8 +87,8 @@ public: // And ThreadScheduler does not delete popped tasks in this way TS_ASSERT_EQUALS(ThreadSchedulerTest_numDestructed, 0); - for (size_t i = 0; i < 4; i++) { - delete tasks[i]; + for (auto &task : tasks) { + delete task; } } diff --git a/Framework/Kernel/test/UsageServiceTest.h b/Framework/Kernel/test/UsageServiceTest.h index fbf3fbf4f1b..022d88b7c38 100644 --- a/Framework/Kernel/test/UsageServiceTest.h +++ b/Framework/Kernel/test/UsageServiceTest.h @@ -101,11 +101,11 @@ public: } auto features = root["features"]; - for (Json::ArrayIndex i = 0; i < features.size(); i++) { - std::string name = features[i]["name"].asString(); - std::string type = features[i]["type"].asString(); - bool internal = features[i]["internal"].asBool(); - size_t count = features[i]["count"].asUInt(); + for (auto &feature : features) { + std::string name = feature["name"].asString(); + std::string type = feature["type"].asString(); + bool internal = feature["internal"].asBool(); + size_t count = feature["count"].asUInt(); bool correct = false; diff --git a/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISEventDAE.h b/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISEventDAE.h index d776a84d8e5..2f648a9df8f 100644 --- a/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISEventDAE.h +++ b/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISEventDAE.h @@ -55,6 +55,9 @@ public: const std::string category() const override { return "DataHandling\\DataAcquisition"; } + const std::vector<std::string> seeAlso() const override { + return {"FakeISISHistoDAE"}; + } /// Algorithm's summary const std::string summary() const override { diff --git a/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISHistoDAE.h b/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISHistoDAE.h index 35c4dff7a37..87a7dab447a 100644 --- a/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISHistoDAE.h +++ b/Framework/LiveData/inc/MantidLiveData/ISIS/FakeISISHistoDAE.h @@ -61,6 +61,9 @@ public: const std::string category() const override { return "DataHandling\\DataAcquisition"; } + const std::vector<std::string> seeAlso() const override { + return {"FakeISISEventDAE"}; + } /// Summary of algorithms purpose const std::string summary() const override { return "Simulates ISIS histogram DAE."; diff --git a/Framework/LiveData/inc/MantidLiveData/Kafka/KafkaEventListener.h b/Framework/LiveData/inc/MantidLiveData/Kafka/KafkaEventListener.h index ef4cd6231ea..e9410dced55 100644 --- a/Framework/LiveData/inc/MantidLiveData/Kafka/KafkaEventListener.h +++ b/Framework/LiveData/inc/MantidLiveData/Kafka/KafkaEventListener.h @@ -1,5 +1,5 @@ -#ifndef MANTID_LIVEDATA_ISISKAFKAEVENTLISTENER_H_ -#define MANTID_LIVEDATA_ISISKAFKAEVENTLISTENER_H_ +#ifndef MANTID_LIVEDATA_KAFKAEVENTLISTENER_H_ +#define MANTID_LIVEDATA_KAFKAEVENTLISTENER_H_ //---------------------------------------------------------------------- // Includes //---------------------------------------------------------------------- @@ -10,6 +10,11 @@ //---------------------------------------------------------------------- namespace Mantid { + +namespace API { +class IAlgorithm; +} + namespace LiveData { class KafkaEventStreamDecoder; @@ -38,8 +43,7 @@ class KafkaEventStreamDecoder; */ class DLLExport KafkaEventListener : public API::LiveListener { public: - KafkaEventListener(); - /// Destructor. Should handle termination of any socket connections. + KafkaEventListener() = default; ~KafkaEventListener() override = default; //---------------------------------------------------------------------- @@ -61,6 +65,7 @@ public: void start( Types::Core::DateAndTime startTime = Types::Core::DateAndTime()) override; boost::shared_ptr<API::Workspace> extractData() override; + void setAlgorithm(const Mantid::API::IAlgorithm &callingAlgorithm) override; //---------------------------------------------------------------------- // State flags @@ -71,9 +76,10 @@ public: private: std::unique_ptr<KafkaEventStreamDecoder> m_decoder = nullptr; + std::string m_instrumentName; }; } // namespace LiveData } // namespace Mantid -#endif /*MANTID_LIVEDATA_ISISKAFKAEVENTLISTENER_H_*/ +#endif /*MANTID_LIVEDATA_KAFKAEVENTLISTENER_H_*/ diff --git a/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h b/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h index 7b76f388e85..652b613e8a5 100644 --- a/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h +++ b/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h @@ -79,7 +79,7 @@ protected: bool rxPacket(const ADARA::VariableStringPkt &pkt) override; bool rxPacket(const ADARA::DeviceDescriptorPkt &pkt) override; bool rxPacket(const ADARA::AnnotationPkt &pkt) override; - // virtual bool rxPacket( const ADARA::RunInfoPkt &pkt); + bool rxPacket(const ADARA::RunInfoPkt &pkt) override; private: // Workspace initialization needs to happen in 2 steps. Part 1 must happen diff --git a/Framework/LiveData/src/Kafka/KafkaEventListener.cpp b/Framework/LiveData/src/Kafka/KafkaEventListener.cpp index 78fdb58efce..567a2a88380 100644 --- a/Framework/LiveData/src/Kafka/KafkaEventListener.cpp +++ b/Framework/LiveData/src/Kafka/KafkaEventListener.cpp @@ -1,7 +1,8 @@ #include "MantidLiveData/Kafka/KafkaEventListener.h" +#include "MantidAPI/IAlgorithm.h" #include "MantidAPI/LiveListenerFactory.h" -#include "MantidLiveData/Kafka/KafkaEventStreamDecoder.h" #include "MantidLiveData/Kafka/KafkaBroker.h" +#include "MantidLiveData/Kafka/KafkaEventStreamDecoder.h" #include "MantidLiveData/Kafka/KafkaTopicSubscriber.h" namespace { @@ -13,21 +14,32 @@ namespace LiveData { DECLARE_LISTENER(KafkaEventListener) -KafkaEventListener::KafkaEventListener() { - declareProperty("InstrumentName", ""); +void KafkaEventListener::setAlgorithm( + const Mantid::API::IAlgorithm &callingAlgorithm) { + this->updatePropertyValues(callingAlgorithm); + // Get the instrument name from StartLiveData so we can sub to correct topics + if (callingAlgorithm.existsProperty("Instrument")) { + m_instrumentName = callingAlgorithm.getPropertyValue("Instrument"); + } else { + g_log.error("KafkaEventListener requires Instrument property to be set in " + "calling algorithm"); + } } /// @copydoc ILiveListener::connect bool KafkaEventListener::connect(const Poco::Net::SocketAddress &address) { + if (m_instrumentName.empty()) { + g_log.error( + "KafkaEventListener::connect requires a non-empty instrument name"); + } auto broker = std::make_shared<KafkaBroker>(address.toString()); try { - std::string instrumentName = getProperty("InstrumentName"); - const std::string eventTopic(instrumentName + + const std::string eventTopic(m_instrumentName + KafkaTopicSubscriber::EVENT_TOPIC_SUFFIX), - runInfoTopic(instrumentName + KafkaTopicSubscriber::RUN_TOPIC_SUFFIX), - spDetInfoTopic(instrumentName + + runInfoTopic(m_instrumentName + KafkaTopicSubscriber::RUN_TOPIC_SUFFIX), + spDetInfoTopic(m_instrumentName + KafkaTopicSubscriber::DET_SPEC_TOPIC_SUFFIX), - sampleEnvTopic(instrumentName + + sampleEnvTopic(m_instrumentName + KafkaTopicSubscriber::SAMPLE_ENV_TOPIC_SUFFIX); m_decoder = Kernel::make_unique<KafkaEventStreamDecoder>( broker, eventTopic, runInfoTopic, spDetInfoTopic, sampleEnvTopic); diff --git a/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp b/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp index 6c79894cfd3..1de3cca7717 100644 --- a/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp +++ b/Framework/LiveData/src/Kafka/KafkaEventStreamDecoder.cpp @@ -507,22 +507,21 @@ void KafkaEventStreamDecoder::eventDataFromMessage(const std::string &buffer) { const auto &detData = *(eventMsg->detector_id()); auto nEvents = tofData.size(); - if (eventMsg->facility_specific_data_type() != FacilityData_ISISData) { - throw std::runtime_error("KafkaEventStreamDecoder only knows how to " - "deal with ISIS facility specific data"); - } - auto ISISMsg = - static_cast<const ISISData *>(eventMsg->facility_specific_data()); - + DataObjects::EventWorkspace_sptr periodBuffer; std::lock_guard<std::mutex> lock(m_mutex); - auto &periodBuffer = - *m_localEvents[static_cast<size_t>(ISISMsg->period_number())]; - auto &mutableRunInfo = periodBuffer.mutableRun(); - mutableRunInfo.getTimeSeriesProperty<double>(PROTON_CHARGE_PROPERTY) - ->addValue(pulseTime, ISISMsg->proton_charge()); + if (eventMsg->facility_specific_data_type() == FacilityData_ISISData) { + auto ISISMsg = + static_cast<const ISISData *>(eventMsg->facility_specific_data()); + periodBuffer = m_localEvents[static_cast<size_t>(ISISMsg->period_number())]; + auto &mutableRunInfo = periodBuffer->mutableRun(); + mutableRunInfo.getTimeSeriesProperty<double>(PROTON_CHARGE_PROPERTY) + ->addValue(pulseTime, ISISMsg->proton_charge()); + } else { + periodBuffer = m_localEvents[0]; + } for (decltype(nEvents) i = 0; i < nEvents; ++i) { - auto &spectrum = - periodBuffer.getSpectrum(m_specToIdx[static_cast<int32_t>(detData[i])]); + auto &spectrum = periodBuffer->getSpectrum( + m_specToIdx[static_cast<int32_t>(detData[i])]); spectrum.addEventQuickly(TofEvent(static_cast<double>(tofData[i]) * 1e-3, // nanoseconds to microseconds pulseTime)); diff --git a/Framework/LiveData/src/Kafka/private/Schema/flatbuffers/flatbuffers.h b/Framework/LiveData/src/Kafka/private/Schema/flatbuffers/flatbuffers.h index 2c57e5aa153..6ce57b8f32b 100644 --- a/Framework/LiveData/src/Kafka/private/Schema/flatbuffers/flatbuffers.h +++ b/Framework/LiveData/src/Kafka/private/Schema/flatbuffers/flatbuffers.h @@ -757,11 +757,11 @@ FLATBUFFERS_FINAL_CLASS auto vt_use = GetSize(); // See if we already have generated a vtable with this exact same // layout before. If so, make it point to the old one, remove this one. - for (auto it = vtables_.begin(); it != vtables_.end(); ++it) { - auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*it)); + for (unsigned int & vtable : vtables_) { + auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(vtable)); auto vt2_size = *vt2; if (vt1_size != vt2_size || memcmp(vt2, vt1, vt1_size)) continue; - vt_use = *it; + vt_use = vtable; buf_.pop(GetSize() - vtableoffsetloc); break; } diff --git a/Framework/LiveData/src/SNSLiveEventDataListener.cpp b/Framework/LiveData/src/SNSLiveEventDataListener.cpp index fb5f61f9406..6053943d2a1 100644 --- a/Framework/LiveData/src/SNSLiveEventDataListener.cpp +++ b/Framework/LiveData/src/SNSLiveEventDataListener.cpp @@ -50,6 +50,10 @@ const std::string PAUSE_PROPERTY("pause"); const std::string SCAN_PROPERTY("scan_index"); const std::string PROTON_CHARGE_PROPERTY("proton_charge"); +// These are names for some string properties (not time series) +const std::string RUN_TITLE_PROPERTY("run_title"); +const std::string EXPERIMENT_ID_PROPERTY("experiment_identifier"); + // Helper function to get a DateAndTime value from an ADARA packet header Mantid::Types::Core::DateAndTime timeFromPacket(const ADARA::PacketHeader &hdr) { @@ -1011,8 +1015,7 @@ bool SNSLiveEventDataListener::rxPacket(const ADARA::DeviceDescriptorPkt &pkt) { // Find the process_variables element // Note: for now, I'm ignoring the 'device_name' & 'enumeration' elements - // because I don't - // think I need them + // because I don't think I need them const Poco::XML::Node *node = deviceNode->firstChild(); while (node && node->nodeName() != "process_variables") { @@ -1193,6 +1196,97 @@ bool SNSLiveEventDataListener::rxPacket(const ADARA::AnnotationPkt &pkt) { return false; } +/// Parse a Run Information packet + +/// Overrides the default function defined in ADARA::Parser and processes +/// data from ADARA::RunInfoPkt packets. Specifically, it looks for the +/// proposal id and run title and stores those values in properties in the +/// workspace. +/// @param pkt The packet to be parsed +/// @return Returns false if there were no problems. Returns true if there +/// was an error and packet parsing should be interrupted +bool SNSLiveEventDataListener::rxPacket(const ADARA::RunInfoPkt &pkt) { + + // RunInfoPkts are mostly just blocks of XML. + Poco::XML::DOMParser parser; + Poco::AutoPtr<Poco::XML::Document> doc = parser.parseString(pkt.info()); + const Poco::XML::Node *runInfoNode = doc->firstChild(); + + // The root of the XML should be "runinfo". + while (runInfoNode && runInfoNode->nodeName() != "runinfo") { + runInfoNode = runInfoNode->nextSibling(); + } + + if (!runInfoNode) { + g_log.error("Run info packet did not contain a 'runinfo' element!! " + "This should never happen!"); + return false; + } + + // The two elements we're looking for (proposal_id and run_title) should + // be children of the runInfoNode. (Note that run_number is also in there, + // but we already get that from the RunStatusPkt.) + std::string proposalID; + std::string runTitle; + const Poco::XML::Node *node = runInfoNode->firstChild(); + while (node) { + // iterate through each individual variable... + if (node->nodeName() == "proposal_id") { + const Poco::XML::Node *textElement = node->firstChild(); + if (textElement) { + proposalID = textElement->nodeValue(); + } + } else if (node->nodeName() == "run_title") { + const Poco::XML::Node *textElement = node->firstChild(); + if (textElement) { + runTitle = textElement->nodeValue(); + } + } + + // If we've got everything we need, we can break out of the while loop + if (proposalID.length() && runTitle.length()) { + break; + } + + node = node->nextSibling(); + } + + if (proposalID.length()) { + Property *prop = + m_eventBuffer->mutableRun().getProperty(EXPERIMENT_ID_PROPERTY); + + // Sanity check: We're likely to get multiple RunInfo packets in a + // run, but the values shouldn't change mid-run... + std::string prevPropVal = prop->value(); + if (prevPropVal.length() && prevPropVal != proposalID) { + g_log.error("Proposal ID in the current run info packet has changed! " + "This shouldn't happen! (Keeping new ID value.)"); + } + prop->setValue(proposalID); + } else { + g_log.warning("Run info packet did not contain a proposal ID. " + "Property will be empty."); + } + + if (runTitle.length()) { + Property *prop = + m_eventBuffer->mutableRun().getProperty(RUN_TITLE_PROPERTY); + + // Sanity check + std::string prevPropVal = prop->value(); + if (prevPropVal.length() && prevPropVal != runTitle) { + g_log.error("The run title in the current run info packet has changed!" + " This shouldn't happen! (Keeping new title value.)"); + } + prop->setValue(runTitle); + } else { + g_log.warning("Run info packet did not contain a run title. " + "Property will be empty."); + } + + return false; +} + /// First part of the workspace initialization /// Performs various initialization steps that can (and, in some @@ -1213,6 +1307,12 @@ void SNSLiveEventDataListener::initWorkspacePart1() { prop = new TimeSeriesProperty<double>(PROTON_CHARGE_PROPERTY); prop->setUnits("picoCoulomb"); m_eventBuffer->mutableRun().addLogData(prop); + + // Same for a couple of other properties (that are not time series) + prop = new PropertyWithValue<std::string>(RUN_TITLE_PROPERTY, ""); + m_eventBuffer->mutableRun().addLogData(prop); + prop = new PropertyWithValue<std::string>(EXPERIMENT_ID_PROPERTY, ""); + m_eventBuffer->mutableRun().addLogData(prop); } /// Second part of the workspace initialization diff --git a/Framework/LiveData/test/KafkaEventStreamDecoderTest.h b/Framework/LiveData/test/KafkaEventStreamDecoderTest.h index a7f1e0e423d..6a83ccdd50f 100644 --- a/Framework/LiveData/test/KafkaEventStreamDecoderTest.h +++ b/Framework/LiveData/test/KafkaEventStreamDecoderTest.h @@ -54,7 +54,7 @@ public: //---------------------------------------------------------------------------- void test_Single_Period_Event_Stream() { using namespace ::testing; - using namespace ISISKafkaTesting; + using namespace KafkaTesting; using Mantid::API::Workspace_sptr; using Mantid::DataObjects::EventWorkspace; using namespace Mantid::LiveData; @@ -92,7 +92,7 @@ public: void test_Multiple_Period_Event_Stream() { using namespace ::testing; - using namespace ISISKafkaTesting; + using namespace KafkaTesting; using Mantid::API::Workspace_sptr; using Mantid::API::WorkspaceGroup; using Mantid::DataObjects::EventWorkspace; @@ -134,7 +134,7 @@ public: void test_End_Of_Run_Reported_After_Run_Stop_Reached() { using namespace ::testing; - using namespace ISISKafkaTesting; + using namespace KafkaTesting; using Mantid::API::Workspace_sptr; using Mantid::DataObjects::EventWorkspace; using namespace Mantid::LiveData; @@ -173,7 +173,7 @@ public: void test_Get_All_Run_Events_When_Run_Stop_Message_Received_Before_Last_Event_Message() { using namespace ::testing; - using namespace ISISKafkaTesting; + using namespace KafkaTesting; using Mantid::API::Workspace_sptr; using Mantid::DataObjects::EventWorkspace; using namespace Mantid::LiveData; @@ -211,7 +211,7 @@ public: void test_Sample_Log_From_Event_Stream() { using namespace ::testing; - using namespace ISISKafkaTesting; + using namespace KafkaTesting; using Mantid::API::Workspace_sptr; using Mantid::DataObjects::EventWorkspace; using namespace Mantid::LiveData; @@ -244,7 +244,7 @@ public: void test_Empty_Event_Stream_Waits() { using namespace ::testing; - using namespace ISISKafkaTesting; + using namespace KafkaTesting; auto mockBroker = std::make_shared<MockKafkaBroker>(); EXPECT_CALL(*mockBroker, subscribe_(_, _)) @@ -260,12 +260,44 @@ public: TS_ASSERT(!decoder->isCapturing()); } + void + test_No_Exception_When_Event_Message_Without_Facility_Data_Is_Processed() { + using namespace ::testing; + using namespace KafkaTesting; + using Mantid::API::Workspace_sptr; + using Mantid::DataObjects::EventWorkspace; + + auto mockBroker = std::make_shared<MockKafkaBroker>(); + EXPECT_CALL(*mockBroker, subscribe_(_, _)) + .Times(Exactly(3)) + .WillOnce(Return(new FakeEventSubscriber)) + .WillOnce(Return(new FakeRunInfoStreamSubscriber(1))) + .WillOnce(Return(new FakeISISSpDetStreamSubscriber)); + auto decoder = createTestDecoder(mockBroker); + startCapturing(*decoder, 2); + Workspace_sptr workspace; + TS_ASSERT_THROWS_NOTHING(workspace = decoder->extractData()); + TS_ASSERT_THROWS_NOTHING(decoder->stopCapture()); + TS_ASSERT(!decoder->isCapturing()); + + // Check we did process the event message and extract the events + TSM_ASSERT("Expected non-null workspace pointer from extractData()", + workspace); + auto eventWksp = boost::dynamic_pointer_cast<EventWorkspace>(workspace); + TSM_ASSERT( + "Expected an EventWorkspace from extractData(). Found something else", + eventWksp); + + TSM_ASSERT_EQUALS("Expected 3 events from the event message", 3, + eventWksp->getNumberEvents()); + } + //---------------------------------------------------------------------------- // Failure tests //---------------------------------------------------------------------------- void test_Error_In_Stream_Extraction_Throws_Error_On_ExtractData() { using namespace ::testing; - using namespace ISISKafkaTesting; + using namespace KafkaTesting; auto mockBroker = std::make_shared<MockKafkaBroker>(); EXPECT_CALL(*mockBroker, subscribe_(_, _)) @@ -283,7 +315,7 @@ public: void test_Empty_SpDet_Stream_Throws_Error_On_ExtractData() { using namespace ::testing; - using namespace ISISKafkaTesting; + using namespace KafkaTesting; auto mockBroker = std::make_shared<MockKafkaBroker>(); EXPECT_CALL(*mockBroker, subscribe_(_, _)) @@ -301,7 +333,7 @@ public: void test_Empty_RunInfo_Stream_Throws_Error_On_ExtractData() { using namespace ::testing; - using namespace ISISKafkaTesting; + using namespace KafkaTesting; auto mockBroker = std::make_shared<MockKafkaBroker>(); EXPECT_CALL(*mockBroker, subscribe_(_, _)) diff --git a/Framework/LiveData/test/KafkaTesting.h b/Framework/LiveData/test/KafkaTesting.h index b8a45780121..01e1d6b342b 100644 --- a/Framework/LiveData/test/KafkaTesting.h +++ b/Framework/LiveData/test/KafkaTesting.h @@ -18,7 +18,7 @@ GCC_DIAG_ON(conversion) #include <ctime> -namespace ISISKafkaTesting { +namespace KafkaTesting { // ----------------------------------------------------------------------------- // Mock broker to inject fake subscribers @@ -122,7 +122,7 @@ public: } }; -void fakeReceiveAnEventMessage(std::string *buffer, int32_t nextPeriod) { +void fakeReceiveAnISISEventMessage(std::string *buffer, int32_t nextPeriod) { flatbuffers::FlatBufferBuilder builder; std::vector<uint32_t> spec = {5, 4, 3, 2, 1, 2}; std::vector<uint32_t> tof = {11000, 10000, 9000, 8000, 7000, 6000}; @@ -143,6 +143,22 @@ void fakeReceiveAnEventMessage(std::string *buffer, int32_t nextPeriod) { builder.GetSize()); } +void fakeReceiveAnEventMessage(std::string *buffer) { + flatbuffers::FlatBufferBuilder builder; + std::vector<uint32_t> spec = {5, 4, 3}; + std::vector<uint32_t> tof = {11000, 10000, 9000}; + uint64_t frameTime = 1; + + auto messageFlatbuf = CreateEventMessage( + builder, builder.CreateString("KafkaTesting"), 0, frameTime, + builder.CreateVector(tof), builder.CreateVector(spec)); + FinishEventMessageBuffer(builder, messageFlatbuf); + + // Copy to provided buffer + buffer->assign(reinterpret_cast<const char *>(builder.GetBufferPointer()), + builder.GetSize()); +} + void fakeReceiveASampleEnvMessage(std::string *buffer) { flatbuffers::FlatBufferBuilder builder; // Sample environment log @@ -206,7 +222,7 @@ public: std::string &topic) override { assert(message); - fakeReceiveAnEventMessage(message, m_nextPeriod); + fakeReceiveAnISISEventMessage(message, m_nextPeriod); m_nextPeriod = ((m_nextPeriod + 1) % m_nperiods); UNUSED_ARG(offset); @@ -236,6 +252,58 @@ private: int32_t m_nextPeriod; }; +// --------------------------------------------------------------------------------------- +// Fake non-institution-specific event stream to provide event and sample +// environment data +// --------------------------------------------------------------------------------------- +class FakeEventSubscriber : public Mantid::LiveData::IKafkaStreamSubscriber { +public: + void subscribe() override {} + void subscribe(int64_t offset) override { UNUSED_ARG(offset) } + void consumeMessage(std::string *message, int64_t &offset, int32_t &partition, + std::string &topic) override { + assert(message); + + switch (m_nextOffset) { + case 0: + fakeReceiveARunStartMessage(message, 1000, "2016-08-31T12:07:42", + "HRPDTEST", 1); + break; + case 2: + fakeReceiveARunStopMessage(message, m_stopTime); + break; + default: + fakeReceiveAnEventMessage(message); + } + m_nextOffset++; + + UNUSED_ARG(offset); + UNUSED_ARG(partition); + UNUSED_ARG(topic); + } + std::unordered_map<std::string, std::vector<int64_t>> + getOffsetsForTimestamp(int64_t timestamp) override { + UNUSED_ARG(timestamp); + return {std::pair<std::string, std::vector<int64_t>>(m_topicName, {1})}; + } + std::unordered_map<std::string, std::vector<int64_t>> + getCurrentOffsets() override { + std::unordered_map<std::string, std::vector<int64_t>> offsets; + return {std::pair<std::string, std::vector<int64_t>>(m_topicName, {1})}; + } + void seek(const std::string &topic, uint32_t partition, + int64_t offset) override { + UNUSED_ARG(topic); + UNUSED_ARG(partition); + UNUSED_ARG(offset); + } + +private: + std::string m_topicName = "topic_name"; + int m_nextOffset = 0; + std::string m_stopTime = "2016-08-31T12:07:52"; +}; + // ----------------------------------------------------------------------------- // Fake event stream to provide sample environment data // ----------------------------------------------------------------------------- @@ -354,7 +422,7 @@ public: m_nperiods); break; default: - fakeReceiveAnEventMessage(buffer, 0); + fakeReceiveAnISISEventMessage(buffer, 0); } topic = "topic_name"; offset = m_nextOffset; @@ -441,6 +509,6 @@ private: // These match the detector numbers in HRPDTEST_Definition.xml std::vector<int32_t> m_detid = {1001, 1002, 1100, 901000, 10100}; }; -} // namespace ISISKafkaTesting +} // namespace KafkaTesting #endif // MANTID_LIVEDATA_ISISKAFKAEVENTSTREAMDECODERTESTMOCKS_H_ diff --git a/Framework/LiveData/test/LoadLiveDataTest.h b/Framework/LiveData/test/LoadLiveDataTest.h index 028cf8db44b..a8830030a22 100644 --- a/Framework/LiveData/test/LoadLiveDataTest.h +++ b/Framework/LiveData/test/LoadLiveDataTest.h @@ -180,8 +180,8 @@ public: TS_ASSERT_EQUALS(ws1->getNumberHistograms(), 2); double total; total = 0; - for (auto it = ws1->readY(0).begin(); it != ws1->readY(0).end(); it++) - total += *it; + for (double yValue : ws1->readY(0)) + total += yValue; TS_ASSERT_DELTA(total, 100.0, 1e-4); // Next one adds the histograms together @@ -191,8 +191,8 @@ public: // The new total signal is 200.0 total = 0; - for (auto it = ws1->readY(0).begin(); it != ws1->readY(0).end(); it++) - total += *it; + for (double yValue : ws1->readY(0)) + total += yValue; TS_ASSERT_DELTA(total, 200.0, 1e-4); TSM_ASSERT("Workspace being added stayed the same pointer", ws1 == ws2); diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AccumulateMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AccumulateMD.h index 2763c719ce6..cb6bddffcc8 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AccumulateMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AccumulateMD.h @@ -88,6 +88,9 @@ class DLLExport AccumulateMD : public API::DataProcessorAlgorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"MergeMD"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AndMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AndMD.h index 8158a032971..6a2ac1cef7a 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AndMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/AndMD.h @@ -38,6 +38,9 @@ class DLLExport AndMD : public BooleanBinaryOperationMD { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"XorMD", "OrMD", "NotMD"}; + } private: void execHistoHisto( diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinMD.h index d97ebc5c22f..ff47996ac36 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/BinMD.h @@ -44,6 +44,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"SliceMDHisto", "ProjectMD", "CutMD", "SliceMD"}; + } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\Slicing"; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h index 29e327cdfe6..a00c63a3bb4 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h @@ -37,6 +37,9 @@ public: CalculateCoverageDGS(); const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"SetGoniometer", "SetUB"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CentroidPeaksMD2.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CentroidPeaksMD2.h index a6239f7da84..642109658fb 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CentroidPeaksMD2.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CentroidPeaksMD2.h @@ -28,6 +28,9 @@ public: /// Algorithm's version for identification int version() const override { return 2; }; + const std::vector<std::string> seeAlso() const override { + return {"IntegratePeaksMD", "CentroidPeaks"}; + } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\Peaks"; } diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertMDHistoToMatrixWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertMDHistoToMatrixWorkspace.h index eb229efb9da..4071a31b648 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertMDHistoToMatrixWorkspace.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertMDHistoToMatrixWorkspace.h @@ -62,6 +62,10 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"ConvertToMD", "CreateMDHistoWorkspace", + "ConvertTableToMatrixWorkspace", "MDHistoToWorkspace2D"}; + } /// Algorithm's category for identification const std::string category() const override { return "Utility\\Workspaces;MDAlgorithms\\Transforms"; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDetectorFaceMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDetectorFaceMD.h index b59283a4daa..b81698b736a 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDetectorFaceMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDetectorFaceMD.h @@ -48,6 +48,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ConvertToMD"}; + } const std::string category() const override; private: diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace3.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace3.h index 15374ecf3f1..55bf4e3230f 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace3.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace3.h @@ -21,6 +21,9 @@ class DLLExport ConvertToDiffractionMDWorkspace3 public: /// Algorithm's version for identification int version() const override { return 3; } + const std::vector<std::string> seeAlso() const override { + return {"ConvertToMD", "SetSpecialCoordinates"}; + } private: void init() override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h index 8f7f443248d..4b3c7bb5c55 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMD.h @@ -64,6 +64,11 @@ public: /// Algorithm's version for identification int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ConvertToDiffractionMDWorkspace", "ConvertToMDMinMaxGlobal", + "ConvertToMDMinMaxLocal", "CreateMDWorkspace", + "SetSpecialCoordinates"}; + } private: std::map<std::string, std::string> validateInputs() override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxGlobal.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxGlobal.h index 31d9867bcef..018e6ad2c27 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxGlobal.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxGlobal.h @@ -43,6 +43,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ConvertToMD"}; + } const std::string category() const override; private: diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxLocal.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxLocal.h index 67f1f5a48e8..7f27270b0dd 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxLocal.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToMDMinMaxLocal.h @@ -41,6 +41,9 @@ public: } int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"ConvertToMD"}; + } protected: // for testing void findMinMaxValues(MDWSDescription &WSDescription, diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToReflectometryQ.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToReflectometryQ.h index b4e4c9dd97a..164fe699b78 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToReflectometryQ.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertToReflectometryQ.h @@ -43,6 +43,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ConvertUnits"}; + } const std::string category() const override; private: diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMD.h index a650274c89d..45dd364aea1 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMD.h @@ -45,6 +45,9 @@ class MANTID_MDALGORITHMS_DLL CreateMD : public API::DataProcessorAlgorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CreateMDWorkspace"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDHistoWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDHistoWorkspace.h index ec386117d67..4908e723d2f 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDHistoWorkspace.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDHistoWorkspace.h @@ -42,6 +42,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ConvertToMD", "CreateMDWorkspace"}; + } const std::string category() const override; private: diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDWorkspace.h index 5b9c8aaa67b..dc8041f778f 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDWorkspace.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CreateMDWorkspace.h @@ -36,6 +36,10 @@ public: /// Algorithm's version for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"ConvertToMD", "CreateMDHistoWorkspace", "FakeMDEventData", + "CreateMD"}; + } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\Creation"; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CutMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CutMD.h index 92aa260c570..39adbc42dab 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CutMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CutMD.h @@ -42,6 +42,9 @@ class DLLExport CutMD : public API::DataProcessorAlgorithm { public: const std::string name() const override { return "CutMD"; } int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"SliceMDHisto", "ProjectMD", "SliceMD", "BinMD"}; + } const std::string summary() const override { return "Slices multidimensional workspaces using input projection " "information and binning limits."; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/DivideMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/DivideMD.h index 2c1450dac3b..d95be8e2193 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/DivideMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/DivideMD.h @@ -42,6 +42,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"MinusMD", "MultiplyMD", "PlusMD", "PowerMD"}; + } private: /// Is the operation commutative? diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EqualToMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EqualToMD.h index 0facbbb0536..c6ca87f2652 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EqualToMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EqualToMD.h @@ -37,6 +37,9 @@ class DLLExport EqualToMD : public BooleanBinaryOperationMD { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"GreaterThanMD", "LessThanMD", "NotMD"}; + } private: void initExtraProperties() override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EvaluateMDFunction.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EvaluateMDFunction.h index 50bac7d0c14..3dd3d240522 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EvaluateMDFunction.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EvaluateMDFunction.h @@ -38,6 +38,9 @@ public: const std::string name() const override { return "EvaluateMDFunction"; } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CreateMDWorkspace", "FakeMDEventData"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ExponentialMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ExponentialMD.h index 84fa2e1abb4..ed0262ff09a 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ExponentialMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ExponentialMD.h @@ -42,6 +42,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"PowerMD", "LogarithmMD"}; + } private: /// Check the inputs and throw if the algorithm cannot be run diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FakeMDEventData.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FakeMDEventData.h index acb6ae49247..043e75aea38 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FakeMDEventData.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FakeMDEventData.h @@ -44,6 +44,9 @@ public: } /// Algorithm's verion for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"CreateMDWorkspace", "EvaluateMDFunction"}; + } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\Creation"; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FindPeaksMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FindPeaksMD.h index 6f21dbd40ae..cd8ce88a8d6 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FindPeaksMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/FindPeaksMD.h @@ -36,6 +36,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"FindPeaks"}; + } /// Algorithm's category for identification const std::string category() const override { return "Optimization\\PeakFinding;MDAlgorithms\\Peaks"; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/GreaterThanMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/GreaterThanMD.h index 6df08bee89d..89d2cbad0a0 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/GreaterThanMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/GreaterThanMD.h @@ -43,6 +43,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LessThanMD", "EqualToMD"}; + } private: bool acceptScalar() const override { return true; } diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDEventWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDEventWorkspace.h index 1be7c21e361..6d0b420318a 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDEventWorkspace.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDEventWorkspace.h @@ -45,6 +45,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ImportMDHistoWorkspace"}; + } const std::string category() const override; /// Flag used to indicate the dimension block in the file diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDHistoWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDHistoWorkspace.h index 61acba6d723..815c78243c8 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDHistoWorkspace.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ImportMDHistoWorkspace.h @@ -42,6 +42,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ImportMDEventWorkspace"}; + } const std::string category() const override; private: diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoids.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoids.h index 2a3c8dad79e..aa5f1fca905 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoids.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoids.h @@ -27,6 +27,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"IntegrateEllipsoidsTwoStep"}; + } const std::string category() const override; private: diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoidsTwoStep.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoidsTwoStep.h index 050e00a795a..674f9a3ff44 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoidsTwoStep.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoidsTwoStep.h @@ -45,6 +45,9 @@ public: const std::string name() const override; /// Get the version of this algorithm int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"IntegrateEllipsoids"}; + } /// Get the category of this algorithm const std::string category() const override; /// Summary of algorithms purpose diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateFlux.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateFlux.h index 281667f1de9..14d481f5ab2 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateFlux.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateFlux.h @@ -46,6 +46,9 @@ class DLLExport IntegrateFlux : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"Integration"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateMDHistoWorkspace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateMDHistoWorkspace.h index 813e82138b3..9901172d101 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateMDHistoWorkspace.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateMDHistoWorkspace.h @@ -37,6 +37,9 @@ class DLLExport IntegrateMDHistoWorkspace : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"SliceMDHisto"}; + } const std::string category() const override; const std::string summary() const override; std::map<std::string, std::string> validateInputs() override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksCWSD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksCWSD.h index 04360a2a6c4..5127fef4c8b 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksCWSD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksCWSD.h @@ -33,6 +33,10 @@ public: /// Algorithm's version for identification int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"IntegratePeaksHybrid", "IntegratePeaksMDHKL", "IntegratePeaksMD", + "IntegratePeaksUsingClusters"}; + } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\Peaks"; } diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h index eac3242ca28..8da44d60ff9 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h @@ -32,6 +32,10 @@ public: /// Algorithm's version for identification int version() const override { return 2; }; + const std::vector<std::string> seeAlso() const override { + return {"CentroidPeaksMD", "IntegratePeaksHybrid", "IntegratePeaksMDHKL", + "IntegratePeaksUsingClusters", "IntegratePeaksCWSD"}; + } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\Peaks"; } diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMDHKL.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMDHKL.h index b97d605f74c..a4cabeaf9e3 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMDHKL.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMDHKL.h @@ -29,6 +29,10 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"IntegratePeaksHybrid", "IntegratePeaksUsingClusters", + "IntegratePeaksMD", "IntegratePeaksCWSD"}; + } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\Peaks"; } diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LessThanMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LessThanMD.h index 0eb6c2c5a83..c478493573c 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LessThanMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LessThanMD.h @@ -37,6 +37,9 @@ class DLLExport LessThanMD : public BooleanBinaryOperationMD { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"GreaterThanMD", "EqualToMD"}; + } private: bool acceptScalar() const override { return true; } diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h index 45a2f6ab848..34be74d5752 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h @@ -51,6 +51,7 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { return {"SaveMD"}; } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\DataHandling"; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h index c770267191d..b4936899c25 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h @@ -47,6 +47,9 @@ class DLLExport LoadSQW2 : public API::IFileLoader<Kernel::FileDescriptor> { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LoadNXSPE", "SaveNXSPE"}; + } const std::string category() const override; const std::string summary() const override; int confidence(Kernel::FileDescriptor &descriptor) const override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LogarithmMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LogarithmMD.h index b018c748317..21ef39b0ec6 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LogarithmMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LogarithmMD.h @@ -42,6 +42,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"PowerMD", "ExponentialMD"}; + } private: void initExtraProperties() override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h index 9e05a140fe0..8239e467729 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h @@ -39,6 +39,9 @@ public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"MDNormSCD", "MDNormSCDPreprocessIncoherent"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h index 5b18915c292..749f6007e75 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h @@ -39,6 +39,9 @@ public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"MDNormSCDPreprocessIncoherent", "MDNormDirectSC"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MaskMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MaskMD.h index e1e0b6a9990..cd6106e261f 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MaskMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MaskMD.h @@ -47,6 +47,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"MaskDetectors"}; + } const std::string category() const override; private: diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMD.h index 8d8155f6335..39a0ac1b401 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMD.h @@ -43,6 +43,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"MergeMDFiles", "AccumulateMD"}; + } const std::string category() const override; private: diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMDFiles.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMDFiles.h index 04860beaa88..cac9e968713 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMDFiles.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MergeMDFiles.h @@ -54,6 +54,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"MergeMD"}; + } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\Creation"; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MinusMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MinusMD.h index 6acb7cb6aeb..d6d2baf9733 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MinusMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MinusMD.h @@ -42,6 +42,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"PlusMD", "MultiplyMD", "DivideMD", "PowerMD"}; + } private: /// Is the operation commutative? diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MultiplyMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MultiplyMD.h index 71655bf2409..5f69fcd6861 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MultiplyMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MultiplyMD.h @@ -43,6 +43,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"MinusMD", "PlusMD", "DivideMD", "PowerMD"}; + } private: /// Is the operation commutative? diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/NotMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/NotMD.h index cffce98eaf4..c855fbcbcc7 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/NotMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/NotMD.h @@ -42,6 +42,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"AndMD", "OrMD", "XorMD"}; + } private: /// Check the inputs and throw if the algorithm cannot be run diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/OrMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/OrMD.h index 4990ac1658e..5cbf604ad41 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/OrMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/OrMD.h @@ -37,6 +37,9 @@ class DLLExport OrMD : public BooleanBinaryOperationMD { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"AndMD", "XorMD", "NotMD"}; + } private: void execHistoHisto( diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PlusMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PlusMD.h index edfd89a6db9..5a34023e7c2 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PlusMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PlusMD.h @@ -47,6 +47,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"MinusMD", "MultiplyMD", "DivideMD", "PowerMD"}; + } private: /// Is the operation commutative? diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PowerMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PowerMD.h index 1f9070f74c1..f4d1e18e286 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PowerMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/PowerMD.h @@ -42,6 +42,10 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"MinusMD", "MultiplyMD", "DivideMD", + "PlusMD", "LogarithmMD", "ExponentialMD"}; + } private: void initExtraProperties() override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/FitResolutionConvolvedModel.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/FitResolutionConvolvedModel.h index dd236708ec2..e4eb5ed095f 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/FitResolutionConvolvedModel.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/FitResolutionConvolvedModel.h @@ -35,6 +35,9 @@ public: return "Fits a cuts/slices from an MDEventWorkspace using a resolution " "function convolved with a foreground model"; } + const std::vector<std::string> seeAlso() const override { + return {"SimulateResolutionConvolvedModel"}; + } int version() const override; const std::string category() const override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h index d869716128e..e068f43de12 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h @@ -43,7 +43,9 @@ public: const std::string summary() const override { return "Runs a simulation of a model with a selected resolution function"; } - + const std::vector<std::string> seeAlso() const override { + return {"FitResolutionConvolvedModel"}; + } int version() const override; private: diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ReplicateMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ReplicateMD.h index cf3cb6ce703..3c8286f0b35 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ReplicateMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ReplicateMD.h @@ -45,6 +45,9 @@ class MANTID_MDALGORITHMS_DLL ReplicateMD : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"CreateMDWorkspace", "MergeMD"}; + } const std::string category() const override; const std::string summary() const override; /// Valdiate the algorithm inputs diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveMD2.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveMD2.h index 0f64bd206d0..5f20735ef2e 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveMD2.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveMD2.h @@ -43,6 +43,9 @@ public: /// Algorithm's version for identification int version() const override { return 2; }; + const std::vector<std::string> seeAlso() const override { + return {"LoadMD", "SaveZODS"}; + } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\DataHandling"; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveZODS.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveZODS.h index 28aa7121849..dc49617eb41 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveZODS.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SaveZODS.h @@ -43,6 +43,7 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { return {"SaveMD"}; } const std::string category() const override; private: diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SliceMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SliceMD.h index 9b04faf63ee..4facc974e9e 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SliceMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SliceMD.h @@ -57,6 +57,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"SliceMDHisto", "ProjectMD", "CutMD", "BinMD"}; + } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\Slicing"; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SmoothMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SmoothMD.h index 1b5c16d16e8..4d42b9b57d1 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SmoothMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/SmoothMD.h @@ -46,6 +46,9 @@ class DLLExport SmoothMD : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"ThresholdMD"}; + } const std::string category() const override; const std::string summary() const override; std::map<std::string, std::string> validateInputs() override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ThresholdMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ThresholdMD.h index 6461f45ade8..46923478f9e 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ThresholdMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ThresholdMD.h @@ -39,6 +39,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"SmoothMD"}; + } const std::string category() const override; private: diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransformMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransformMD.h index c697d5e048d..10479c11f61 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransformMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransformMD.h @@ -42,6 +42,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"InvertMDDim"}; + } const std::string category() const override; private: diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransposeMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransposeMD.h index d1a9300c8ba..ac5308243e0 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransposeMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/TransposeMD.h @@ -35,6 +35,9 @@ class MANTID_MDALGORITHMS_DLL TransposeMD : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"Transpose3D", "Transpose"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/WeightedMeanMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/WeightedMeanMD.h index 6068aa04784..5e200f69f9e 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/WeightedMeanMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/WeightedMeanMD.h @@ -44,6 +44,9 @@ public: /// Algorithm's version for identification int version() const override { return 1; }; + const std::vector<std::string> seeAlso() const override { + return {"WeightedMean"}; + } private: /// Is the operation commutative? diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/XorMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/XorMD.h index 0456fc93eb2..ab39c4cf020 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/XorMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/XorMD.h @@ -37,6 +37,9 @@ class DLLExport XorMD : public BooleanBinaryOperationMD { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"AndMD", "OrMD", "NotMD"}; + } private: void execHistoHisto( diff --git a/Framework/MDAlgorithms/src/BinMD.cpp b/Framework/MDAlgorithms/src/BinMD.cpp index 3346daac0c5..e1c84d9b869 100644 --- a/Framework/MDAlgorithms/src/BinMD.cpp +++ b/Framework/MDAlgorithms/src/BinMD.cpp @@ -103,7 +103,7 @@ inline void BinMD::binMDBox(MDBox<MDE, nd> *box, const size_t *const chunkMin, // There is a check that the number of events is enough for it to make sense // to do all this processing. size_t numVertexes = 0; - coord_t *vertexes = box->getVertexesArray(numVertexes); + auto vertexes = box->getVertexesArray(numVertexes); // All vertexes have to be within THE SAME BIN = have the same linear index. size_t lastLinearIndex = 0; @@ -111,7 +111,7 @@ inline void BinMD::binMDBox(MDBox<MDE, nd> *box, const size_t *const chunkMin, for (size_t i = 0; i < numVertexes; i++) { // Cache the center of the event (again for speed) - const coord_t *inCenter = vertexes + i * nd; + const coord_t *inCenter = vertexes.get() + i * nd; // Now transform to the output dimensions m_transform->apply(inCenter, outCenter); @@ -154,8 +154,6 @@ inline void BinMD::binMDBox(MDBox<MDE, nd> *box, const size_t *const chunkMin, break; } // (for each vertex) - delete[] vertexes; - if (!badOne) { // Yes, the entire box is within a single bin // std::cout << "Box at " << box->getExtentsStr() << " is within a diff --git a/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp b/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp index 1b60b9fda5e..38e425b77bc 100644 --- a/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp +++ b/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp @@ -449,7 +449,7 @@ void ConvertCWPDMDToSpectra::binMD(API::IMDEventWorkspace_const_sptr mdws, << sourcepos.Y() << ", " << sourcepos.Z() << "\n"; // Go through all events to find out their positions - IMDIterator *mditer = mdws->createIterator(); + auto mditer = mdws->createIterator(); bool scancell = true; size_t nextindex = 1; int currRunIndex = -1; diff --git a/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp b/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp index f31c9245fc9..018851c2df6 100644 --- a/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp +++ b/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp @@ -175,7 +175,7 @@ void ConvertCWSDMDtoHKL::exportEvents( vec_event_det.resize(numevents); // Go through to get value - IMDIterator *mditer = mdws->createIterator(); + auto mditer = mdws->createIterator(); size_t nextindex = 1; bool scancell = true; size_t currindex = 0; diff --git a/Framework/MDAlgorithms/src/FindPeaksMD.cpp b/Framework/MDAlgorithms/src/FindPeaksMD.cpp index 309a9a590d7..9856bc510dc 100644 --- a/Framework/MDAlgorithms/src/FindPeaksMD.cpp +++ b/Framework/MDAlgorithms/src/FindPeaksMD.cpp @@ -746,6 +746,10 @@ void FindPeaksMD::exec() { criteria.push_back(std::pair<std::string, bool>("bincount", false)); peakWS->sort(criteria); + for (auto i = 0; i != peakWS->getNumberPeaks(); ++i) { + Peak &p = peakWS->getPeak(i); + p.setPeakNumber(i + 1); + } // Save the output setProperty("OutputWorkspace", peakWS); } diff --git a/Framework/MDAlgorithms/src/FitMD.cpp b/Framework/MDAlgorithms/src/FitMD.cpp index e3fbd3f0e29..959a88dd536 100644 --- a/Framework/MDAlgorithms/src/FitMD.cpp +++ b/Framework/MDAlgorithms/src/FitMD.cpp @@ -97,7 +97,6 @@ void FitMD::createDomain(boost::shared_ptr<API::FunctionDomain> &domain, setParameters(); auto iterator = m_IMDWorkspace->createIterator(); const size_t n = iterator->getDataSize(); - delete iterator; if (m_count == 0) { m_count = n; @@ -233,7 +232,6 @@ boost::shared_ptr<API::Workspace> FitMD::createEventOutputWorkspace( } ++resultValueIndex; } while (inputIter->next()); - delete inputIter; // This splits up all the boxes according to split thresholds and sizes. auto threadScheduler = new Kernel::ThreadSchedulerFIFO(); @@ -342,7 +340,6 @@ size_t FitMD::getDomainSize() const { throw std::runtime_error("FitMD: workspace wasn't defined"); auto iterator = m_IMDWorkspace->createIterator(); size_t n = iterator->getDataSize(); - delete iterator; if (m_count != 0) { if (m_startIndex + m_count > n) throw std::range_error("FitMD: index is out of range"); diff --git a/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp b/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp index 0446997a822..3299118922a 100644 --- a/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp +++ b/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp @@ -378,7 +378,7 @@ void GetSpiceDataRawCountsFromMD::getDetCounts( vecY.clear(); // Go through all events to find out their positions - IMDIterator *mditer = mdws->createIterator(); + auto mditer = mdws->createIterator(); bool scancell = true; size_t nextindex = 1; @@ -429,8 +429,6 @@ void GetSpiceDataRawCountsFromMD::getDetCounts( scancell = false; } } // ENDOF(while) - - delete (mditer); } //---------------------------------------------------------------------------------------------- diff --git a/Framework/MDAlgorithms/src/IntegrateMDHistoWorkspace.cpp b/Framework/MDAlgorithms/src/IntegrateMDHistoWorkspace.cpp index 7e516c8f369..301bd111b80 100644 --- a/Framework/MDAlgorithms/src/IntegrateMDHistoWorkspace.cpp +++ b/Framework/MDAlgorithms/src/IntegrateMDHistoWorkspace.cpp @@ -359,9 +359,8 @@ void IntegrateMDHistoWorkspace::exec() { PARALLEL_FOR_NO_WSP_CHECK() for (int i = 0; i < int(outIterators.size()); ++i) { // NOLINT PARALLEL_START_INTERUPT_REGION - boost::scoped_ptr<MDHistoWorkspaceIterator> outIterator( - dynamic_cast<MDHistoWorkspaceIterator *>(outIterators[i])); - + auto outIterator = + dynamic_cast<MDHistoWorkspaceIterator *>(outIterators[i].get()); if (!outIterator) { throw std::logic_error( "Failed to cast iterator to MDHistoWorkspaceIterator"); @@ -386,8 +385,10 @@ void IntegrateMDHistoWorkspace::exec() { double sumNEvents = 0; // Create a thread-local input iterator. - boost::scoped_ptr<MDHistoWorkspaceIterator> inIterator( - dynamic_cast<MDHistoWorkspaceIterator *>(inWS->createIterator())); + + auto iterator = inWS->createIterator(); + auto inIterator = + dynamic_cast<MDHistoWorkspaceIterator *>(iterator.get()); if (!inIterator) { throw std::runtime_error( "Could not convert IMDIterator to a MDHistoWorkspaceIterator"); @@ -401,7 +402,7 @@ void IntegrateMDHistoWorkspace::exec() { rather than iterating over the full set of boxes of the input workspace. */ inIterator->jumpToNearest(outIteratorCenter); - performWeightedSum(inIterator.get(), box, sumSignal, sumSQErrors, + performWeightedSum(inIterator, box, sumSignal, sumSQErrors, sumNEvents); // Use the present position. neighbours // below exclude the current position. // Look at all of the neighbours of our position. We previously @@ -410,7 +411,7 @@ void IntegrateMDHistoWorkspace::exec() { inIterator->findNeighbourIndexesByWidth(widthVector); for (auto neighbourIndex : neighbourIndexes) { inIterator->jumpTo(neighbourIndex); // Go to that neighbour - performWeightedSum(inIterator.get(), box, sumSignal, sumSQErrors, + performWeightedSum(inIterator, box, sumSignal, sumSQErrors, sumNEvents); } diff --git a/Framework/MDAlgorithms/src/IntegratePeaksCWSD.cpp b/Framework/MDAlgorithms/src/IntegratePeaksCWSD.cpp index 9dccb27505c..2f71a584d41 100644 --- a/Framework/MDAlgorithms/src/IntegratePeaksCWSD.cpp +++ b/Framework/MDAlgorithms/src/IntegratePeaksCWSD.cpp @@ -210,7 +210,7 @@ void IntegratePeaksCWSD::simplePeakIntegration( throw std::runtime_error("MDEventWorkspace is not defined."); // Go through to get value - API::IMDIterator *mditer = m_inputWS->createIterator(); + auto mditer = m_inputWS->createIterator(); size_t nextindex = 1; bool scancell = true; // size_t currindex = 0; diff --git a/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp b/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp index 6bb75c91ab3..1d4d421642d 100644 --- a/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp +++ b/Framework/MDAlgorithms/src/Quantification/Resolution/TobyFitResolutionModel.cpp @@ -521,7 +521,6 @@ void TobyFitResolutionModel::preprocess( } while (iterator->next()); g_log.debug() << "Done preprocessing loop:" << timer.elapsed() << " seconds\n"; - delete iterator; } /** diff --git a/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp b/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp index c4efecaad07..f757691d623 100644 --- a/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp +++ b/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp @@ -101,7 +101,7 @@ void ResolutionConvolvedCrossSection::function( "Expected FunctionDomainMD in ResolutionConvolvedCrossSection"); } - std::vector<API::IMDIterator *> iterators = m_inputWS->createIterators( + auto iterators = m_inputWS->createIterators( API::FrameworkManager::Instance().getNumOMPThreads()); const int nthreads = static_cast<int>(iterators.size()); std::vector<size_t> resultOffsets(nthreads, 0); @@ -126,7 +126,7 @@ void ResolutionConvolvedCrossSection::function( bool exceptionThrown = false; // required for *_PARALLEL_* macros PARALLEL_FOR_NO_WSP_CHECK() for (int i = 0; i < nthreads; ++i) { - API::IMDIterator *boxIterator = iterators[i]; + auto &boxIterator = iterators[i]; const size_t resultsOffset = resultOffsets[i]; size_t boxIndex(0); @@ -141,10 +141,6 @@ void ResolutionConvolvedCrossSection::function( } while (boxIterator->next()); } CHECK_PARALLEL_EXCEPTIONS // Not standard macros. See top of file for reason - - for (auto boxIterator : iterators) { - delete boxIterator; - } } /** diff --git a/Framework/MDAlgorithms/src/QueryMDWorkspace.cpp b/Framework/MDAlgorithms/src/QueryMDWorkspace.cpp index 4b5f8a242bf..a008b064c2a 100644 --- a/Framework/MDAlgorithms/src/QueryMDWorkspace.cpp +++ b/Framework/MDAlgorithms/src/QueryMDWorkspace.cpp @@ -211,7 +211,7 @@ void QueryMDWorkspace::exec() { output->getColumn(signalColumnName)->setPlotType(2); output->getColumn(errorColumnName)->setPlotType(5); - IMDIterator *it = input->createIterator(); + auto it = input->createIterator(); it->setNormalization(requestedNormalisation); bool bLimitRows = getProperty("LimitRows"); @@ -251,7 +251,6 @@ void QueryMDWorkspace::exec() { rowCounter++; } setProperty("OutputWorkspace", output); - delete it; // IMDEventWorkspace_sptr mdew; diff --git a/Framework/MDAlgorithms/src/ReplicateMD.cpp b/Framework/MDAlgorithms/src/ReplicateMD.cpp index 9966a1f2210..70133087d62 100644 --- a/Framework/MDAlgorithms/src/ReplicateMD.cpp +++ b/Framework/MDAlgorithms/src/ReplicateMD.cpp @@ -339,9 +339,6 @@ void ReplicateMD::exec() { // Create the output workspace from the shape. MDHistoWorkspace_sptr outputWS(shapeWS->clone()); - auto outIt = std::unique_ptr<MDHistoWorkspaceIterator>( - dynamic_cast<MDHistoWorkspaceIterator *>(outputWS->createIterator())); - const int nThreads = Mantid::API::FrameworkManager::Instance() .getNumOMPThreads(); // NThreads to Request @@ -352,8 +349,7 @@ void ReplicateMD::exec() { for (int it = 0; it < int(iterators.size()); ++it) { // NOLINT PARALLEL_START_INTERUPT_REGION - auto outIt = std::unique_ptr<MDHistoWorkspaceIterator>( - dynamic_cast<MDHistoWorkspaceIterator *>(iterators[it])); + auto outIt = dynamic_cast<MDHistoWorkspaceIterator *>(iterators[it].get()); // Iterate over the output workspace do { diff --git a/Framework/MDAlgorithms/src/SmoothMD.cpp b/Framework/MDAlgorithms/src/SmoothMD.cpp index 34d380cd7b6..33c3258aded 100644 --- a/Framework/MDAlgorithms/src/SmoothMD.cpp +++ b/Framework/MDAlgorithms/src/SmoothMD.cpp @@ -192,8 +192,8 @@ SmoothMD::hatSmooth(IMDHistoWorkspace_const_sptr toSmooth, for (int it = 0; it < int(iterators.size()); ++it) { // NOLINT PARALLEL_START_INTERUPT_REGION - boost::scoped_ptr<MDHistoWorkspaceIterator> iterator( - dynamic_cast<MDHistoWorkspaceIterator *>(iterators[it])); + auto iterator = + dynamic_cast<MDHistoWorkspaceIterator *>(iterators[it].get()); if (!iterator) { throw std::logic_error( @@ -318,9 +318,8 @@ SmoothMD::gaussianSmooth(IMDHistoWorkspace_const_sptr toSmooth, for (int it = 0; it < int(iterators.size()); ++it) { // NOLINT PARALLEL_START_INTERUPT_REGION - boost::scoped_ptr<MDHistoWorkspaceIterator> iterator( - dynamic_cast<MDHistoWorkspaceIterator *>(iterators[it])); - + auto iterator = + dynamic_cast<MDHistoWorkspaceIterator *>(iterators[it].get()); if (!iterator) { throw std::logic_error( "Failed to cast IMDIterator to MDHistoWorkspaceIterator"); diff --git a/Framework/MDAlgorithms/src/TransposeMD.cpp b/Framework/MDAlgorithms/src/TransposeMD.cpp index 81cebe92560..6f5d7b219a1 100644 --- a/Framework/MDAlgorithms/src/TransposeMD.cpp +++ b/Framework/MDAlgorithms/src/TransposeMD.cpp @@ -132,7 +132,7 @@ void TransposeMD::exec() { for (int it = 0; it < int(iterators.size()); ++it) { // NOLINT PARALLEL_START_INTERUPT_REGION - auto inIterator = std::unique_ptr<IMDIterator>(iterators[it]); + auto inIterator = iterators[it].get(); do { auto center = inIterator->getCenter(); const coord_t *incoords = center.getBareArray(); diff --git a/Framework/MDAlgorithms/src/WeightedMeanMD.cpp b/Framework/MDAlgorithms/src/WeightedMeanMD.cpp index 89f05670921..8f301e9faa4 100644 --- a/Framework/MDAlgorithms/src/WeightedMeanMD.cpp +++ b/Framework/MDAlgorithms/src/WeightedMeanMD.cpp @@ -28,10 +28,10 @@ void WeightedMeanMD::execHistoHisto( Mantid::DataObjects::MDHistoWorkspace_sptr out, Mantid::DataObjects::MDHistoWorkspace_const_sptr operand) { using DataObjects::MDHistoWorkspaceIterator; - MDHistoWorkspaceIterator *lhs_it = - dynamic_cast<MDHistoWorkspaceIterator *>(out->createIterator()); - MDHistoWorkspaceIterator *rhs_it = - dynamic_cast<MDHistoWorkspaceIterator *>(operand->createIterator()); + auto lhs = out->createIterator(); + auto lhs_it = dynamic_cast<MDHistoWorkspaceIterator *>(lhs.get()); + auto rhs = operand->createIterator(); + auto rhs_it = dynamic_cast<MDHistoWorkspaceIterator *>(rhs.get()); if (!lhs_it || !rhs_it) { throw std::logic_error("Histo iterators have wrong type."); @@ -63,9 +63,6 @@ void WeightedMeanMD::execHistoHisto( out->setSignalAt(pos, signal); out->setErrorSquaredAt(pos, error_sq); } while (lhs_it->next() && rhs_it->next()); - - delete lhs_it; - delete rhs_it; } //---------------------------------------------------------------------------------------------- diff --git a/Framework/MDAlgorithms/test/ConvertCWSDExpToMomentumTest.h b/Framework/MDAlgorithms/test/ConvertCWSDExpToMomentumTest.h index 9877a870edd..64ae9fa681f 100644 --- a/Framework/MDAlgorithms/test/ConvertCWSDExpToMomentumTest.h +++ b/Framework/MDAlgorithms/test/ConvertCWSDExpToMomentumTest.h @@ -118,7 +118,7 @@ public: AnalysisDataService::Instance().retrieve("QSampleMDEvents")); TS_ASSERT(outws); - IMDIterator *mditer = outws->createIterator(); + auto mditer = outws->createIterator(); TS_ASSERT_EQUALS(mditer->getNumEvents(), 7400); size_t numexpinfo = outws->getNumExperimentInfo(); @@ -157,7 +157,7 @@ public: AnalysisDataService::Instance().retrieve("QSampleMDEvents")); TS_ASSERT(outws); - IMDIterator *mditer = outws->createIterator(); + auto mditer = outws->createIterator(); TS_ASSERT_EQUALS(mditer->getNumEvents(), 7400); size_t numexpinfo = outws->getNumExperimentInfo(); diff --git a/Framework/MDAlgorithms/test/ConvertSpiceDataToRealSpaceTest.h b/Framework/MDAlgorithms/test/ConvertSpiceDataToRealSpaceTest.h index d01934b1b6b..8a762208e6c 100644 --- a/Framework/MDAlgorithms/test/ConvertSpiceDataToRealSpaceTest.h +++ b/Framework/MDAlgorithms/test/ConvertSpiceDataToRealSpaceTest.h @@ -143,7 +143,7 @@ public: size_t numevents = mdws->getNEvents(); TS_ASSERT_EQUALS(numevents, 44 * 61); - IMDIterator *mditer = mdws->createIterator(); + auto mditer = mdws->createIterator(); TS_ASSERT_EQUALS(mditer->getNumEvents(), 44 * 61); double y0 = mditer->getInnerSignal(0); @@ -333,7 +333,7 @@ public: size_t numevents = mdws->getNEvents(); TS_ASSERT_EQUALS(numevents, 44 * 61); - IMDIterator *mditer = mdws->createIterator(); + auto mditer = mdws->createIterator(); TS_ASSERT_EQUALS(mditer->getNumEvents(), 44 * 61); double y0 = mditer->getInnerSignal(0); diff --git a/Framework/MDAlgorithms/test/DivideMDTest.h b/Framework/MDAlgorithms/test/DivideMDTest.h index 7190173c818..fdc2633896f 100644 --- a/Framework/MDAlgorithms/test/DivideMDTest.h +++ b/Framework/MDAlgorithms/test/DivideMDTest.h @@ -64,7 +64,7 @@ public: TS_ASSERT(ws); if (!ws) return; - IMDIterator *it = ws->createIterator(nullptr); + auto it = ws->createIterator(nullptr); do { TS_ASSERT_EQUALS(it->getNumEvents(), 1); TS_ASSERT_DELTA(it->getInnerSignal(0), expectedSignal, 1e-5); diff --git a/Framework/MDAlgorithms/test/FakeMDEventDataTest.h b/Framework/MDAlgorithms/test/FakeMDEventDataTest.h index fbb8c4be9cc..9a90697ffcc 100644 --- a/Framework/MDAlgorithms/test/FakeMDEventDataTest.h +++ b/Framework/MDAlgorithms/test/FakeMDEventDataTest.h @@ -202,8 +202,6 @@ public: it->next(); ++counter; } - - delete it; } }; diff --git a/Framework/MDAlgorithms/test/FitMDTest.h b/Framework/MDAlgorithms/test/FitMDTest.h index d0f7421baa9..19d2f93a23b 100644 --- a/Framework/MDAlgorithms/test/FitMDTest.h +++ b/Framework/MDAlgorithms/test/FitMDTest.h @@ -36,9 +36,11 @@ public: signal_t getNormalizedError() const override; signal_t getSignal() const override { return 0; } signal_t getError() const override { return 0; } - coord_t *getVertexesArray(size_t &) const override { return nullptr; } - coord_t *getVertexesArray(size_t &, const size_t, - const bool *) const override { + std::unique_ptr<coord_t[]> getVertexesArray(size_t &) const override { + return nullptr; + } + std::unique_ptr<coord_t[]> getVertexesArray(size_t &, const size_t, + const bool *) const override { return nullptr; } Mantid::Kernel::VMD getCenter() const override; @@ -69,10 +71,15 @@ public: class IMDWorkspaceTester : public WorkspaceTester { public: - std::vector<IMDIterator *> + std::vector<std::unique_ptr<IMDIterator>> createIterators(size_t, Mantid::Geometry::MDImplicitFunction *) const override { - return std::vector<IMDIterator *>(1, new IMDWorkspaceTesterIterator(this)); + + std::vector<std::unique_ptr<IMDIterator>> ret; + auto ptr = std::unique_ptr<IMDIterator>{ + Kernel::make_unique<IMDWorkspaceTesterIterator>(this)}; + ret.push_back(std::move(ptr)); + return ret; } }; diff --git a/Framework/MDAlgorithms/test/LoadMDTest.h b/Framework/MDAlgorithms/test/LoadMDTest.h index b2f0dc21d15..3776ab48fa0 100644 --- a/Framework/MDAlgorithms/test/LoadMDTest.h +++ b/Framework/MDAlgorithms/test/LoadMDTest.h @@ -253,8 +253,8 @@ public: typename std::vector<API::IMDNode *> boxes; ws->getBox()->getBoxes(boxes, 1000, false); - for (size_t i = 0; i < boxes.size(); i++) { - MDBox<MDE, nd> *box = dynamic_cast<MDBox<MDE, nd> *>(boxes[i]); + for (auto &boxIt : boxes) { + MDBox<MDE, nd> *box = dynamic_cast<MDBox<MDE, nd> *>(boxIt); if (box) { TSM_ASSERT("Large box should not be in memory", box->getISaveable()->getDataMemorySize() == 0); diff --git a/Framework/MDAlgorithms/test/MDTransfModQTest.h b/Framework/MDAlgorithms/test/MDTransfModQTest.h index 8d4abe7cf82..1178b956b15 100644 --- a/Framework/MDAlgorithms/test/MDTransfModQTest.h +++ b/Framework/MDAlgorithms/test/MDTransfModQTest.h @@ -108,8 +108,8 @@ public: // the detectors parameters MDTransf.calcYDepCoordinates(locCoord, i); - for (size_t k = 0; k < range.size(); k++) { - MDTransf.calcMatrixCoord(range[k], locCoord, signal, errorSq); + for (double k : range) { + MDTransf.calcMatrixCoord(k, locCoord, signal, errorSq); for (size_t j = 0; j < nDims; j++) { if (locCoord[j] < minCoord[j]) minCoord[j] = locCoord[j]; diff --git a/Framework/MDAlgorithms/test/MDTransfQ3DTest.h b/Framework/MDAlgorithms/test/MDTransfQ3DTest.h index cfe87617ea4..81f46d2f193 100644 --- a/Framework/MDAlgorithms/test/MDTransfQ3DTest.h +++ b/Framework/MDAlgorithms/test/MDTransfQ3DTest.h @@ -116,8 +116,8 @@ public: // testing purposes here auto &TwoTheta = const_cast<std::vector<double> &>( WSDescr.m_PreprDetTable->getColVector<double>("TwoTheta")); - for (size_t i = 0; i < TwoTheta.size(); i++) { - TwoTheta[i] = 0; + for (double &i : TwoTheta) { + i = 0; } TSM_ASSERT_THROWS_NOTHING("should initialize properly: ", diff --git a/Framework/MDAlgorithms/test/MaskMDTest.h b/Framework/MDAlgorithms/test/MaskMDTest.h index 8cf01437735..95397908006 100644 --- a/Framework/MDAlgorithms/test/MaskMDTest.h +++ b/Framework/MDAlgorithms/test/MaskMDTest.h @@ -37,7 +37,7 @@ private: if (!ws) return; - IMDIterator *it = ws->createIterator(); + auto it = ws->createIterator(); size_t nMasked = 0; for (size_t i = 0; i < it->getDataSize(); ++i) { if (it->getIsMasked()) { diff --git a/Framework/MDAlgorithms/test/MergeMDFilesTest.h b/Framework/MDAlgorithms/test/MergeMDFilesTest.h index b62604f3fb8..f20739fa839 100644 --- a/Framework/MDAlgorithms/test/MergeMDFilesTest.h +++ b/Framework/MDAlgorithms/test/MergeMDFilesTest.h @@ -102,11 +102,11 @@ public: } // Cleanup generated input files - for (size_t i = 0; i < inWorkspaces.size(); i++) { - if (inWorkspaces[i]->getBoxController()->isFileBacked()) { + for (auto &inWorkspace : inWorkspaces) { + if (inWorkspace->getBoxController()->isFileBacked()) { std::string fileName = - inWorkspaces[i]->getBoxController()->getFileIO()->getFileName(); - inWorkspaces[i]->clearFileBacked(false); + inWorkspace->getBoxController()->getFileIO()->getFileName(); + inWorkspace->clearFileBacked(false); Poco::File(fileName).remove(); } } diff --git a/Framework/MDAlgorithms/test/MinusMDTest.h b/Framework/MDAlgorithms/test/MinusMDTest.h index 82ae75c7b7c..8daa5000cbb 100644 --- a/Framework/MDAlgorithms/test/MinusMDTest.h +++ b/Framework/MDAlgorithms/test/MinusMDTest.h @@ -105,7 +105,7 @@ public: TS_ASSERT_EQUALS(ws->getNPoints(), 10000); } - IMDIterator *it = ws->createIterator(); + auto it = ws->createIterator(); if (mask_ws_num == 0) { while (it->next()) { // Signal of all boxes is zero since they got subtracted diff --git a/Framework/MDAlgorithms/test/MultiplyMDTest.h b/Framework/MDAlgorithms/test/MultiplyMDTest.h index 83f874b003b..08725d35da0 100644 --- a/Framework/MDAlgorithms/test/MultiplyMDTest.h +++ b/Framework/MDAlgorithms/test/MultiplyMDTest.h @@ -63,7 +63,7 @@ public: TS_ASSERT(ws); if (!ws) return; - IMDIterator *it = ws->createIterator(nullptr); + auto it = ws->createIterator(nullptr); do { TS_ASSERT_EQUALS(it->getNumEvents(), 1); TS_ASSERT_DELTA(it->getInnerSignal(0), expectedSignal, 1e-5); diff --git a/Framework/MDAlgorithms/test/ReplicateMDTest.h b/Framework/MDAlgorithms/test/ReplicateMDTest.h index 56b24e96f43..68a25f36780 100644 --- a/Framework/MDAlgorithms/test/ReplicateMDTest.h +++ b/Framework/MDAlgorithms/test/ReplicateMDTest.h @@ -77,8 +77,8 @@ MDHistoWorkspace_sptr makeHistoWorkspace(const std::vector<int> &shape, // Generate the axis order 0, 1, 2 ... in reverse std::vector<int> axes(outWs->getNumDims()); Decreasing op(outWs->getNumDims()); - for (auto it = axes.begin(); it != axes.end(); ++it) { - *it = static_cast<int>(op()); + for (int &axis : axes) { + axis = static_cast<int>(op()); } IAlgorithm *transpose = diff --git a/Framework/MDAlgorithms/test/ResolutionConvolvedCrossSectionTest.h b/Framework/MDAlgorithms/test/ResolutionConvolvedCrossSectionTest.h index 03cd21691ed..497cd15840d 100644 --- a/Framework/MDAlgorithms/test/ResolutionConvolvedCrossSectionTest.h +++ b/Framework/MDAlgorithms/test/ResolutionConvolvedCrossSectionTest.h @@ -47,7 +47,7 @@ public: using namespace Mantid::MDAlgorithms; using namespace Mantid::API; Mantid::API::IMDWorkspace_sptr testWS = createTestMDWorkspace(); - Mantid::API::IMDIterator *box = testWS->createIterator(); + auto box = testWS->createIterator(); FunctionDomainMD mdDomain(testWS, 0, box->getDataSize()); FunctionValues output; @@ -55,7 +55,6 @@ public: crossSecResolution->setWorkspace(testWS); // TODO: Needs a better input workspace // TS_ASSERT_THROWS_NOTHING(crossSecResolution->function(mdDomain, output)); - delete box; delete crossSecResolution; } diff --git a/Framework/MDAlgorithms/test/TobyFitYVectorTest.h b/Framework/MDAlgorithms/test/TobyFitYVectorTest.h index 249061f556a..497046f3e93 100644 --- a/Framework/MDAlgorithms/test/TobyFitYVectorTest.h +++ b/Framework/MDAlgorithms/test/TobyFitYVectorTest.h @@ -45,8 +45,8 @@ public: "DetectorArea", "DetectionTime"}; TobyFitYVector yVector; - for (unsigned int i = 0; i < 8; ++i) { - yVector.setAttribute(attrs[i], IFunction::Attribute(false)); + for (auto &attr : attrs) { + yVector.setAttribute(attr, IFunction::Attribute(false)); } std::vector<double> randNums(yVector.requiredRandomNums(), 0.5); diff --git a/Framework/MDAlgorithms/test/TransformMDTest.h b/Framework/MDAlgorithms/test/TransformMDTest.h index 6ecf6571f7b..dfa6a35e8ad 100644 --- a/Framework/MDAlgorithms/test/TransformMDTest.h +++ b/Framework/MDAlgorithms/test/TransformMDTest.h @@ -64,8 +64,7 @@ public: } std::vector<API::IMDNode *> boxes; ws2->getBox()->getBoxes(boxes, 1000, true); - for (size_t i = 0; i < boxes.size(); i++) { - API::IMDNode *box = boxes[i]; + for (auto box : boxes) { TSM_ASSERT_LESS_THAN("Box extents was offset", 20.0, box->getExtents(0).getMin()); // More detailed tests are in MDBox, MDBoxBase and MDGridBox. diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h b/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h index 6a52ea528c8..eaa58ae1aea 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h @@ -68,6 +68,8 @@ public: const std::string summary() const override; /// Returns a category of the algorithm. const std::string category() const override; + /// Returns seeAlso related algorithms. + const std::vector<std::string> seeAlso() const override; /// Returns optional documentation URL of the algorithm const std::string helpURL() const override; /// Allow the isRunning method to be overridden diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp index 56fc63c961b..c71b84d7903 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp @@ -372,7 +372,11 @@ void export_ialgorithm() { .def("category", &IAlgorithm::category, arg("self"), "Returns the category containing the algorithm") .def("categories", &IAlgorithm::categories, arg("self"), + return_value_policy<VectorToNumpy>(), "Returns the list of categories this algorithm belongs to") + .def("seeAlso", &IAlgorithm::seeAlso, arg("self"), + return_value_policy<VectorToNumpy>(), + "Returns the list of similar algorithms") .def("summary", &IAlgorithm::summary, arg("self"), "Returns a summary message describing the algorithm") .def("helpURL", &IAlgorithm::helpURL, arg("self"), diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp index 67183097ad1..10de2206815 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp @@ -61,9 +61,16 @@ void export_IPeak() { "cache values related to it.") .def("getRunNumber", &IPeak::getRunNumber, arg("self"), "Return the run number this peak was measured at") + .def("getPeakNumber", &IPeak::getPeakNumber, arg("self"), + "Return the peak number for this peak") + .def("getBankName", &IPeak::getBankName, arg("self"), + "Return the bank name for this peak") .def("setRunNumber", &IPeak::setRunNumber, (arg("self"), arg("run_number")), "Set the run number that measured this peak") + .def("setPeakNumber", &IPeak::setPeakNumber, + (arg("self"), arg("peak_number")), + "Set the peak number for this peak") .def("getMonitorCount", &IPeak::getMonitorCount, arg("self"), "Get the monitor count set for this peak") .def("setMonitorCount", &IPeak::setMonitorCount, @@ -126,6 +133,8 @@ void export_IPeak() { "Return the incident wavelength") .def("getScattering", &IPeak::getScattering, arg("self"), "Calculate the scattering angle of the peak") + .def("getAzimuthal", &IPeak::getAzimuthal, arg("self"), + "Calculate the azimuthal angle of the peak") .def("getDSpacing", &IPeak::getDSpacing, arg("self"), "Calculate the d-spacing of the peak, in 1/Angstroms") .def("getTOF", &IPeak::getTOF, arg("self"), diff --git a/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp b/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp index 6d9358d85c2..2c9db0825e8 100644 --- a/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp +++ b/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp @@ -3,6 +3,7 @@ #include "MantidPythonInterface/kernel/Environment/WrapperHelpers.h" #include "MantidPythonInterface/kernel/Environment/CallMethod.h" #include "MantidPythonInterface/kernel/Environment/GlobalInterpreterLock.h" +#include "MantidPythonInterface/kernel/Converters/PySequenceToVector.h" #include "MantidAPI/DataProcessorAlgorithm.h" #include "MantidAPI/SerialAlgorithm.h" #include "MantidAPI/ParallelAlgorithm.h" @@ -92,6 +93,21 @@ const std::string AlgorithmAdapter<BaseAlgorithm>::category() const { return category; } +/** +* Returns seeAlso related algorithms. If not overridden +* it returns an empty vector of strings +*/ +template <typename BaseAlgorithm> +const std::vector<std::string> +AlgorithmAdapter<BaseAlgorithm>::seeAlso() const { + try { + auto seeAlsoPyList = callMethod<object>(getSelf(), "seeAlso"); + return Converters::PySequenceToVector<std::string>(seeAlsoPyList)(); + } catch (UndefinedAttributeError &) { + return {}; + } +} + /** * Returns the summary of the algorithm. If not overridden * it returns defaultSummary diff --git a/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp b/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp index ec12497997c..7987881b15b 100644 --- a/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp +++ b/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp @@ -72,8 +72,8 @@ public: const auto &spectrumDefinition = (*spectrumDefinitions)[i]; std::vector<size_t> detectorIndices; - for (size_t j = 0; j < spectrumDefinition.size(); ++j) { - size_t detectorIndex = spectrumDefinition[j].first; + for (const auto &j : spectrumDefinition) { + size_t detectorIndex = j.first; detectorIndices.emplace_back(std::move(detectorIndex)); } @@ -133,8 +133,7 @@ public: ws.setBinEdges(i, std::move(binEdgeData)); SpectrumDefinition specDef; - for (size_t j = 0; j < detectorIndices.size(); ++j) { - size_t detectorIndex = detectorIndices[j]; + for (auto detectorIndex : detectorIndices) { specDef.add(detectorIndex); } spectrumDefinitions.emplace_back(std::move(specDef)); diff --git a/Framework/PythonInterface/mantid/kernel/CMakeLists.txt b/Framework/PythonInterface/mantid/kernel/CMakeLists.txt index b7f0589931f..865b313bab4 100644 --- a/Framework/PythonInterface/mantid/kernel/CMakeLists.txt +++ b/Framework/PythonInterface/mantid/kernel/CMakeLists.txt @@ -179,7 +179,7 @@ copy_files_to_dir ( ${MPISETUP_PY}.py ${CMAKE_CURRENT_BINARY_DIR} ${OUTPUT_DIR} PYTHON_INSTALL_FILES ) # Package version -if ( WIN32 OR APPLE ) +if ( WIN32 OR (APPLE AND ENABLE_MANTIDPLOT) ) # NeXus library is in the same place relative to the Python library get_filename_component ( NEXUSLIB_FILE ${NEXUSLIB} NAME ) set ( NEXUSLIB ../../${NEXUSLIB_FILE} ) diff --git a/Framework/PythonInterface/mantid/simpleapi.py b/Framework/PythonInterface/mantid/simpleapi.py index 290fe3d9284..b5735128732 100644 --- a/Framework/PythonInterface/mantid/simpleapi.py +++ b/Framework/PythonInterface/mantid/simpleapi.py @@ -266,6 +266,10 @@ def StartLiveData(*args, **kwargs): try: if value is None: value = kwargs.pop(name) + else: + # We don't need the value, but still need to remove from kwargs + # so that this property isn't set again later + kwargs.pop(name, None) algm.setProperty(name, value) except ValueError as ve: diff --git a/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py b/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py index 4faee2742fa..11b3ee7637f 100644 --- a/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py +++ b/Framework/PythonInterface/plugins/algorithms/AlignAndFocusPowderFromFiles.py @@ -56,6 +56,9 @@ class AlignAndFocusPowderFromFiles(DistributedDataProcessorAlgorithm): def category(self): return "Diffraction\\Reduction" + def seeAlso(self): + return [ "AlignAndFocusPowder" ] + def name(self): return "AlignAndFocusPowderFromFiles" diff --git a/Framework/PythonInterface/plugins/algorithms/AlignComponents.py b/Framework/PythonInterface/plugins/algorithms/AlignComponents.py index fda95bd0c68..4232e5c6914 100644 --- a/Framework/PythonInterface/plugins/algorithms/AlignComponents.py +++ b/Framework/PythonInterface/plugins/algorithms/AlignComponents.py @@ -30,6 +30,9 @@ class AlignComponents(PythonAlgorithm): """ return "Diffraction" + def seeAlso(self): + return [ "GetDetOffsetsMultiPeaks","CalibrateRectangularDetectors" ] + def name(self): """ Mantid required diff --git a/Framework/PythonInterface/plugins/algorithms/ApplyDetectorScanEffCorr.py b/Framework/PythonInterface/plugins/algorithms/ApplyDetectorScanEffCorr.py index b0579735421..621de29ce97 100644 --- a/Framework/PythonInterface/plugins/algorithms/ApplyDetectorScanEffCorr.py +++ b/Framework/PythonInterface/plugins/algorithms/ApplyDetectorScanEffCorr.py @@ -11,6 +11,9 @@ class ApplyDetectorScanEffCorr(PythonAlgorithm): def category(self): return 'ILL\\Diffraction;Diffraction\\Utility' + def seeAlso(self): + return [ "PowderDiffILLDetEffCorr","LoadILLDiffraction" ] + def name(self): return 'ApplyDetectorScanEffCorr' diff --git a/Framework/PythonInterface/plugins/algorithms/BASISDiffraction.py b/Framework/PythonInterface/plugins/algorithms/BASISDiffraction.py index 23227fbd37c..1cc3cc472c2 100644 --- a/Framework/PythonInterface/plugins/algorithms/BASISDiffraction.py +++ b/Framework/PythonInterface/plugins/algorithms/BASISDiffraction.py @@ -103,6 +103,9 @@ class BASISDiffraction(DataProcessorAlgorithm): def summary(self): return "Multiple-file BASIS reduction for diffraction detectors." + def seeAlso(self): + return [ "AlignDetectors","DiffractionFocussing","SNSPowderReduction" ] + def PyInit(self): # Input validators array_length_three = FloatArrayLengthValidator(3) diff --git a/Framework/PythonInterface/plugins/algorithms/BASISReduction311.py b/Framework/PythonInterface/plugins/algorithms/BASISReduction311.py index 3b284a3b6a0..8a43ed1c89e 100644 --- a/Framework/PythonInterface/plugins/algorithms/BASISReduction311.py +++ b/Framework/PythonInterface/plugins/algorithms/BASISReduction311.py @@ -45,6 +45,9 @@ class BASISReduction311(PythonAlgorithm): def category(self): return "Inelastic\\Reduction" + def seeAlso(self): + return [ "BASISReduction" ] + def name(self): return "BASISReduction311" diff --git a/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py b/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py index 0c5d8382208..41caf00b743 100644 --- a/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py +++ b/Framework/PythonInterface/plugins/algorithms/CalculateSampleTransmission.py @@ -20,6 +20,9 @@ class CalculateSampleTransmission(PythonAlgorithm): def category(self): return 'Sample' + def seeAlso(self): + return [ "SetSampleMaterial" ] + def summary(self): return 'Calculates the scattering & transmission for a given sample material and size over a given wavelength range.' diff --git a/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py b/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py index 234a605e8d8..564fec0e0b6 100644 --- a/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py +++ b/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py @@ -52,6 +52,9 @@ class CalibrateRectangularDetectors(PythonAlgorithm): def category(self): return "Diffraction\\Calibration" + def seeAlso(self): + return [ "GetDetectorOffsets" ] + def name(self): return "CalibrateRectangularDetectors" diff --git a/Framework/PythonInterface/plugins/algorithms/CheckForSampleLogs.py b/Framework/PythonInterface/plugins/algorithms/CheckForSampleLogs.py index c474b0f7104..d9eca9bb05c 100644 --- a/Framework/PythonInterface/plugins/algorithms/CheckForSampleLogs.py +++ b/Framework/PythonInterface/plugins/algorithms/CheckForSampleLogs.py @@ -14,6 +14,9 @@ class CheckForSampleLogs(PythonAlgorithm): """ return "Utility\\Workspaces" + def seeAlso(self): + return [ "CompareSampleLogs","CopyLogs" ] + def name(self): """ Return name """ diff --git a/Framework/PythonInterface/plugins/algorithms/CleanFileCache.py b/Framework/PythonInterface/plugins/algorithms/CleanFileCache.py index 6aaabfdf879..b6baac7f332 100644 --- a/Framework/PythonInterface/plugins/algorithms/CleanFileCache.py +++ b/Framework/PythonInterface/plugins/algorithms/CleanFileCache.py @@ -17,6 +17,9 @@ class CleanFileCache(PythonAlgorithm): """ return "Workflow\\DataHandling" + def seeAlso(self): + return [ "ClearCache" ] + def name(self): """ """ diff --git a/Framework/PythonInterface/plugins/algorithms/CompareSampleLogs.py b/Framework/PythonInterface/plugins/algorithms/CompareSampleLogs.py index 2a7992709b7..e6a6bca8c7b 100644 --- a/Framework/PythonInterface/plugins/algorithms/CompareSampleLogs.py +++ b/Framework/PythonInterface/plugins/algorithms/CompareSampleLogs.py @@ -25,6 +25,9 @@ class CompareSampleLogs(PythonAlgorithm): """ return "Utility\\Workspaces" + def seeAlso(self): + return [ "CompareWorkspaces","CheckForSampleLogs","CopySample" ] + def name(self): """ Returns name diff --git a/Framework/PythonInterface/plugins/algorithms/ConjoinFiles.py b/Framework/PythonInterface/plugins/algorithms/ConjoinFiles.py index cefc7c15e54..869d8b5b149 100644 --- a/Framework/PythonInterface/plugins/algorithms/ConjoinFiles.py +++ b/Framework/PythonInterface/plugins/algorithms/ConjoinFiles.py @@ -11,6 +11,9 @@ class ConjoinFiles(PythonAlgorithm): def category(self): return "DataHandling\\Text" + def seeAlso(self): + return [ "ConjoinWorkspaces" ] + def name(self): return "ConjoinFiles" diff --git a/Framework/PythonInterface/plugins/algorithms/ConjoinSpectra.py b/Framework/PythonInterface/plugins/algorithms/ConjoinSpectra.py index cbc4405b21d..40240565811 100644 --- a/Framework/PythonInterface/plugins/algorithms/ConjoinSpectra.py +++ b/Framework/PythonInterface/plugins/algorithms/ConjoinSpectra.py @@ -17,6 +17,9 @@ class ConjoinSpectra(PythonAlgorithm): def category(self): return "Transforms\\Merging" + def seeAlso(self): + return [ "AppendSpectra","ConjoinWorkspaces" ] + def name(self): return "ConjoinSpectra" diff --git a/Framework/PythonInterface/plugins/algorithms/ConvertSnsRoiFileToMask.py b/Framework/PythonInterface/plugins/algorithms/ConvertSnsRoiFileToMask.py index 46ce04c74c2..db4ac9fec84 100644 --- a/Framework/PythonInterface/plugins/algorithms/ConvertSnsRoiFileToMask.py +++ b/Framework/PythonInterface/plugins/algorithms/ConvertSnsRoiFileToMask.py @@ -31,6 +31,9 @@ class ConvertSnsRoiFileToMask(api.PythonAlgorithm): """ return "Inelastic\\Utility" + def seeAlso(self): + return [ "MaskDetectors" ] + def name(self): """ Name of the algorithm. diff --git a/Framework/PythonInterface/plugins/algorithms/CorrectLogTimes.py b/Framework/PythonInterface/plugins/algorithms/CorrectLogTimes.py index f00d6a438e4..6ff0279085a 100644 --- a/Framework/PythonInterface/plugins/algorithms/CorrectLogTimes.py +++ b/Framework/PythonInterface/plugins/algorithms/CorrectLogTimes.py @@ -17,6 +17,9 @@ class CorrectLogTimes(mantid.api.PythonAlgorithm): """ return "DataHandling\\Logs" + def seeAlso(self): + return [ "ChangeLogTime","CreateLogTimeCorrection","ChangePulsetime","ShiftLogTime" ] + def name(self): """ Mantid required """ diff --git a/Framework/PythonInterface/plugins/algorithms/CorrectTOF.py b/Framework/PythonInterface/plugins/algorithms/CorrectTOF.py index 8d1d0e831e2..a4e2f8f1f10 100644 --- a/Framework/PythonInterface/plugins/algorithms/CorrectTOF.py +++ b/Framework/PythonInterface/plugins/algorithms/CorrectTOF.py @@ -21,6 +21,9 @@ class CorrectTOF (PythonAlgorithm): """ return "Workflow\\MLZ\\TOFTOF;Transforms\\Axes" + def seeAlso(self): + return [ "TOFTOFMergeRuns","TOFTOFCropWorkspace" ] + def name(self): """ Return name """ diff --git a/Framework/PythonInterface/plugins/algorithms/CreateEmptyTableWorkspace.py b/Framework/PythonInterface/plugins/algorithms/CreateEmptyTableWorkspace.py index 026393dc796..39f42a823d3 100644 --- a/Framework/PythonInterface/plugins/algorithms/CreateEmptyTableWorkspace.py +++ b/Framework/PythonInterface/plugins/algorithms/CreateEmptyTableWorkspace.py @@ -16,6 +16,9 @@ class CreateEmptyTableWorkspace(PythonAlgorithm): def category(self): return 'Utility\\Workspaces' + def seeAlso(self): + return [ "DeleteTableRows","SortTableWorkspace" ] + def PyInit(self): # Declare properties self.declareProperty(ITableWorkspaceProperty("OutputWorkspace", "", Direction.Output), diff --git a/Framework/PythonInterface/plugins/algorithms/CreateLeBailFitInput.py b/Framework/PythonInterface/plugins/algorithms/CreateLeBailFitInput.py index 579f1cc4802..6585d93e163 100644 --- a/Framework/PythonInterface/plugins/algorithms/CreateLeBailFitInput.py +++ b/Framework/PythonInterface/plugins/algorithms/CreateLeBailFitInput.py @@ -18,6 +18,9 @@ class CreateLeBailFitInput(PythonAlgorithm): """ return "Diffraction\\Fitting;Utility\\Workspaces" + def seeAlso(self): + return [ "LeBailFit" ] + def name(self): """ """ diff --git a/Framework/PythonInterface/plugins/algorithms/CropWorkspaceRagged.py b/Framework/PythonInterface/plugins/algorithms/CropWorkspaceRagged.py index 722feb44491..c4898987d93 100644 --- a/Framework/PythonInterface/plugins/algorithms/CropWorkspaceRagged.py +++ b/Framework/PythonInterface/plugins/algorithms/CropWorkspaceRagged.py @@ -11,6 +11,9 @@ class CropWorkspaceRagged(PythonAlgorithm): def category(self): return 'Transforms\\Splitting;Workflow' + def seeAlso(self): + return [ "CropWorkspace" ] + def name(self): return 'CropWorkspaceRagged' diff --git a/Framework/PythonInterface/plugins/algorithms/DNSComputeDetEffCorrCoefs.py b/Framework/PythonInterface/plugins/algorithms/DNSComputeDetEffCorrCoefs.py index 8851d3e351b..234be4b2ea8 100644 --- a/Framework/PythonInterface/plugins/algorithms/DNSComputeDetEffCorrCoefs.py +++ b/Framework/PythonInterface/plugins/algorithms/DNSComputeDetEffCorrCoefs.py @@ -29,6 +29,9 @@ class DNSComputeDetEffCorrCoefs(PythonAlgorithm): """ return 'Workflow\\MLZ\\DNS;CorrectionFunctions\\SpecialCorrections' + def seeAlso(self): + return [ "DNSFlippingRatioCorr" ] + def name(self): """ Returns name diff --git a/Framework/PythonInterface/plugins/algorithms/DNSFlippingRatioCorr.py b/Framework/PythonInterface/plugins/algorithms/DNSFlippingRatioCorr.py index 26e5b3b7132..d2c237c7e40 100644 --- a/Framework/PythonInterface/plugins/algorithms/DNSFlippingRatioCorr.py +++ b/Framework/PythonInterface/plugins/algorithms/DNSFlippingRatioCorr.py @@ -32,6 +32,9 @@ class DNSFlippingRatioCorr(PythonAlgorithm): """ return 'Workflow\\MLZ\\DNS;;CorrectionFunctions\\SpecialCorrections' + def seeAlso(self): + return [ "DNSComputeDetEffCorrCoefs" ] + def name(self): """ Returns name diff --git a/Framework/PythonInterface/plugins/algorithms/DNSMergeRuns.py b/Framework/PythonInterface/plugins/algorithms/DNSMergeRuns.py index 0a98575c21b..8110e19d9fe 100644 --- a/Framework/PythonInterface/plugins/algorithms/DNSMergeRuns.py +++ b/Framework/PythonInterface/plugins/algorithms/DNSMergeRuns.py @@ -30,6 +30,9 @@ class DNSMergeRuns(PythonAlgorithm): """ return 'Workflow\\MLZ\\DNS' + def seeAlso(self): + return [ "LoadDNSLegacy" ] + def name(self): """ Returns name diff --git a/Framework/PythonInterface/plugins/algorithms/EnggCalibrate.py b/Framework/PythonInterface/plugins/algorithms/EnggCalibrate.py index 2e8176f65d3..351f905d5cb 100644 --- a/Framework/PythonInterface/plugins/algorithms/EnggCalibrate.py +++ b/Framework/PythonInterface/plugins/algorithms/EnggCalibrate.py @@ -10,6 +10,9 @@ class EnggCalibrate(PythonAlgorithm): def category(self): return "Diffraction\\Engineering" + def seeAlso(self): + return [ "EnggCalibrateFull" ] + def name(self): return "EnggCalibrate" diff --git a/Framework/PythonInterface/plugins/algorithms/EnggCalibrateFull.py b/Framework/PythonInterface/plugins/algorithms/EnggCalibrateFull.py index df8ed01c126..c3b5e48c07e 100644 --- a/Framework/PythonInterface/plugins/algorithms/EnggCalibrateFull.py +++ b/Framework/PythonInterface/plugins/algorithms/EnggCalibrateFull.py @@ -12,6 +12,9 @@ class EnggCalibrateFull(PythonAlgorithm): def category(self): return "Diffraction\\Engineering" + def seeAlso(self): + return [ "EnggCalibrate" ] + def name(self): return "EnggCalibrateFull" diff --git a/Framework/PythonInterface/plugins/algorithms/EnggFitDIFCFromPeaks.py b/Framework/PythonInterface/plugins/algorithms/EnggFitDIFCFromPeaks.py index fab141ea1d2..5526e2a7cff 100644 --- a/Framework/PythonInterface/plugins/algorithms/EnggFitDIFCFromPeaks.py +++ b/Framework/PythonInterface/plugins/algorithms/EnggFitDIFCFromPeaks.py @@ -8,6 +8,9 @@ class EnggFitDIFCFromPeaks(PythonAlgorithm): def category(self): return "Diffraction\\Engineering;Diffraction\\Fitting" + def seeAlso(self): + return [ "EnggFitPeaks","GSASIIRefineFitPeaks","Fit" ] + def name(self): return "EnggFitPeaks" diff --git a/Framework/PythonInterface/plugins/algorithms/EnggFitPeaks.py b/Framework/PythonInterface/plugins/algorithms/EnggFitPeaks.py index 2a58c7e58ab..a951a7275f8 100644 --- a/Framework/PythonInterface/plugins/algorithms/EnggFitPeaks.py +++ b/Framework/PythonInterface/plugins/algorithms/EnggFitPeaks.py @@ -19,6 +19,9 @@ class EnggFitPeaks(PythonAlgorithm): def category(self): return "Diffraction\\Engineering;Diffraction\\Fitting" + def seeAlso(self): + return [ "EnggFitDIFCFromPeaks","GSASIIRefineFitPeaks","Fit" ] + def name(self): return "EnggFitPeaks" diff --git a/Framework/PythonInterface/plugins/algorithms/EnggFocus.py b/Framework/PythonInterface/plugins/algorithms/EnggFocus.py index 28ecf993a48..128ab3e7604 100644 --- a/Framework/PythonInterface/plugins/algorithms/EnggFocus.py +++ b/Framework/PythonInterface/plugins/algorithms/EnggFocus.py @@ -11,6 +11,9 @@ class EnggFocus(PythonAlgorithm): def category(self): return "Diffraction\\Engineering" + def seeAlso(self): + return [ "AlignDetectors","DiffractionFocussing" ] + def name(self): return "EnggFocus" diff --git a/Framework/PythonInterface/plugins/algorithms/ExportExperimentLog.py b/Framework/PythonInterface/plugins/algorithms/ExportExperimentLog.py index 82f6ca11e41..25167d7a36c 100644 --- a/Framework/PythonInterface/plugins/algorithms/ExportExperimentLog.py +++ b/Framework/PythonInterface/plugins/algorithms/ExportExperimentLog.py @@ -40,6 +40,9 @@ class ExportExperimentLog(PythonAlgorithm): """ return 'DataHandling\\Logs' + def seeAlso(self): + return [ "ExportSampleLogsToCSVFile" ] + def PyInit(self): """ Declaration of properties """ diff --git a/Framework/PythonInterface/plugins/algorithms/ExportGeometry.py b/Framework/PythonInterface/plugins/algorithms/ExportGeometry.py index dac0fb3c0d8..aca44bbbd21 100644 --- a/Framework/PythonInterface/plugins/algorithms/ExportGeometry.py +++ b/Framework/PythonInterface/plugins/algorithms/ExportGeometry.py @@ -46,6 +46,9 @@ class ExportGeometry(PythonAlgorithm): def category(self): return "Utility\\Instrument" + def seeAlso(self): + return [ "LoadInstrument" ] + def name(self): return "ExportGeometry" diff --git a/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToCSVFile.py b/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToCSVFile.py index be7dd8390cf..dad5fffe9e8 100644 --- a/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToCSVFile.py +++ b/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToCSVFile.py @@ -41,6 +41,9 @@ class ExportSampleLogsToCSVFile(PythonAlgorithm): """ return "DataHandling\\Logs" + def seeAlso(self): + return [ "ExportExperimentLog" ] + def name(self): """ Algorithm name """ diff --git a/Framework/PythonInterface/plugins/algorithms/ExportSpectraMask.py b/Framework/PythonInterface/plugins/algorithms/ExportSpectraMask.py index 69310ca255d..cc407f5afdd 100644 --- a/Framework/PythonInterface/plugins/algorithms/ExportSpectraMask.py +++ b/Framework/PythonInterface/plugins/algorithms/ExportSpectraMask.py @@ -165,6 +165,9 @@ class ExportSpectraMask(PythonAlgorithm): """ return "DataHandling\\Masking" + def seeAlso(self): + return [ "SaveMask","ExportSpectraMask" ] + def name(self): """ Return name """ diff --git a/Framework/PythonInterface/plugins/algorithms/ExtractMonitors.py b/Framework/PythonInterface/plugins/algorithms/ExtractMonitors.py index 15f1a2fcf43..54e3154eb24 100644 --- a/Framework/PythonInterface/plugins/algorithms/ExtractMonitors.py +++ b/Framework/PythonInterface/plugins/algorithms/ExtractMonitors.py @@ -11,6 +11,9 @@ class ExtractMonitors(DataProcessorAlgorithm): def summary(self): return 'Separates the monitors and/or detectors into separate workspaces.' + def seeAlso(self): + return [ "ExtractMonitorWorkspace" ] + def PyInit(self): self.declareProperty(MatrixWorkspaceProperty('InputWorkspace', '', direction=Direction.Input), diff --git a/Framework/PythonInterface/plugins/algorithms/FilterLogByTime.py b/Framework/PythonInterface/plugins/algorithms/FilterLogByTime.py index 450554a5dd5..5089d9fa7cc 100644 --- a/Framework/PythonInterface/plugins/algorithms/FilterLogByTime.py +++ b/Framework/PythonInterface/plugins/algorithms/FilterLogByTime.py @@ -12,6 +12,9 @@ class FilterLogByTime(PythonAlgorithm): def category(self): return "Events\\EventFiltering" + def seeAlso(self): + return [ "FilterByTime","FilterByLogValue" ] + def name(self): return "FilterLogByTime" diff --git a/Framework/PythonInterface/plugins/algorithms/FitGaussian.py b/Framework/PythonInterface/plugins/algorithms/FitGaussian.py index 8777631a52d..fe11460f638 100644 --- a/Framework/PythonInterface/plugins/algorithms/FitGaussian.py +++ b/Framework/PythonInterface/plugins/algorithms/FitGaussian.py @@ -11,6 +11,9 @@ class FitGaussian(PythonAlgorithm): def category(self): return "Optimization" + def seeAlso(self): + return [ "Fit" ] + def PyInit(self): # input self.declareProperty(MatrixWorkspaceProperty("Workspace", "", Direction.Input), diff --git a/Framework/PythonInterface/plugins/algorithms/GSASIIRefineFitPeaks.py b/Framework/PythonInterface/plugins/algorithms/GSASIIRefineFitPeaks.py index 93aa61dbf9f..1cbeb58f2eb 100644 --- a/Framework/PythonInterface/plugins/algorithms/GSASIIRefineFitPeaks.py +++ b/Framework/PythonInterface/plugins/algorithms/GSASIIRefineFitPeaks.py @@ -45,6 +45,9 @@ class GSASIIRefineFitPeaks(PythonAlgorithm): def category(self): return "Diffraction\\Engineering;Diffraction\\Fitting" + def seeAlso(self): + return [ "LoadGSS","SaveGSS","Fit","EnggFitPeaks" ] + def name(self): return "GSASIIRefineFitPeaks" diff --git a/Framework/PythonInterface/plugins/algorithms/GenerateGroupingSNSInelastic.py b/Framework/PythonInterface/plugins/algorithms/GenerateGroupingSNSInelastic.py index 6a712c3ec19..d0eaa513924 100644 --- a/Framework/PythonInterface/plugins/algorithms/GenerateGroupingSNSInelastic.py +++ b/Framework/PythonInterface/plugins/algorithms/GenerateGroupingSNSInelastic.py @@ -16,6 +16,9 @@ class GenerateGroupingSNSInelastic(mantid.api.PythonAlgorithm): """ return "Inelastic\\Utility;Transforms\\Grouping" + def seeAlso(self): + return [ "GroupWorkspaces" ] + def name(self): """ Mantid required """ diff --git a/Framework/PythonInterface/plugins/algorithms/GetEiT0atSNS.py b/Framework/PythonInterface/plugins/algorithms/GetEiT0atSNS.py index 0ad786a631a..7c84a9c231b 100644 --- a/Framework/PythonInterface/plugins/algorithms/GetEiT0atSNS.py +++ b/Framework/PythonInterface/plugins/algorithms/GetEiT0atSNS.py @@ -10,6 +10,9 @@ class GetEiT0atSNS(mantid.api.PythonAlgorithm): """ return "Inelastic\\Ei" + def seeAlso(self): + return [ "GetEi" ] + def name(self): """ Return name """ diff --git a/Framework/PythonInterface/plugins/algorithms/LoadAndMerge.py b/Framework/PythonInterface/plugins/algorithms/LoadAndMerge.py index 8e954c53f69..f119bb777a7 100644 --- a/Framework/PythonInterface/plugins/algorithms/LoadAndMerge.py +++ b/Framework/PythonInterface/plugins/algorithms/LoadAndMerge.py @@ -15,6 +15,9 @@ class LoadAndMerge(PythonAlgorithm): _prefix = '' _progress = None + def seeAlso(self): + return [ "Load","MergeRuns" ] + def name(self): return "LoadMergeRuns" diff --git a/Framework/PythonInterface/plugins/algorithms/LoadEmptyVesuvio.py b/Framework/PythonInterface/plugins/algorithms/LoadEmptyVesuvio.py index c48ad3107be..a8b82620cbc 100644 --- a/Framework/PythonInterface/plugins/algorithms/LoadEmptyVesuvio.py +++ b/Framework/PythonInterface/plugins/algorithms/LoadEmptyVesuvio.py @@ -29,6 +29,10 @@ class LoadEmptyVesuvio(PythonAlgorithm): return 'DataHandling\\Raw' #---------------------------------------------------------------------------------------- + def seeAlso(self): + return [ "LoadVesuvio" ] + +#---------------------------------------------------------------------------------------- def PyInit(self): self.declareProperty(FileProperty(INST_PAR_PROP, "", action=FileAction.OptionalLoad, extensions=["dat"]), diff --git a/Framework/PythonInterface/plugins/algorithms/LoadFullprofFile.py b/Framework/PythonInterface/plugins/algorithms/LoadFullprofFile.py index 86d686206b6..d389ab88683 100644 --- a/Framework/PythonInterface/plugins/algorithms/LoadFullprofFile.py +++ b/Framework/PythonInterface/plugins/algorithms/LoadFullprofFile.py @@ -21,6 +21,9 @@ class LoadFullprofFile(PythonAlgorithm): """ return "Diffraction\\DataHandling" + def seeAlso(self): + return [ "LoadFullprofResolution" ] + def name(self): """ """ diff --git a/Framework/PythonInterface/plugins/algorithms/LoadLogPropertyTable.py b/Framework/PythonInterface/plugins/algorithms/LoadLogPropertyTable.py index 22d6f03a55e..2b3cfd8b0da 100644 --- a/Framework/PythonInterface/plugins/algorithms/LoadLogPropertyTable.py +++ b/Framework/PythonInterface/plugins/algorithms/LoadLogPropertyTable.py @@ -18,6 +18,9 @@ class LoadLogPropertyTable(PythonAlgorithm): return "Creates a table of Run number against the log values for that run for a range of files.\ It can use a single log value or a list of log values." + def seeAlso(self): + return [ "LoadLog", "LoadMuonLog" ] + # same concept as built in "CreateLogPropertyTable" but loads its own workspaces and needn't hold all in memory at once # select log values to put in table (list) # special cases for: diff --git a/Framework/PythonInterface/plugins/algorithms/LoadMultipleGSS.py b/Framework/PythonInterface/plugins/algorithms/LoadMultipleGSS.py index a00fb3a26a6..cba8e48b6cd 100644 --- a/Framework/PythonInterface/plugins/algorithms/LoadMultipleGSS.py +++ b/Framework/PythonInterface/plugins/algorithms/LoadMultipleGSS.py @@ -14,6 +14,9 @@ class LoadMultipleGSS(PythonAlgorithm): def category(self): return "DataHandling\\Text" + def seeAlso(self): + return [ "LoadGSS" ] + def name(self): return "LoadMultipleGSS" diff --git a/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py b/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py index 9166c9e8e44..d452a23ab3a 100644 --- a/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py +++ b/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py @@ -107,6 +107,12 @@ class LoadVesuvio(LoadEmptyVesuvio): """ Defines the category the algorithm will be put in the algorithm browser """ return 'DataHandling\\Raw' + +#---------------------------------------------------------------------------------------- + + def seeAlso(self): + return [ "LoadEmptyVesuvio" ,"LoadRaw" ] + #---------------------------------------------------------------------------------------- def PyInit(self): diff --git a/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticBS.py b/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticBS.py index 6b965402ea7..371d7872146 100644 --- a/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticBS.py +++ b/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticBS.py @@ -16,6 +16,9 @@ class LoadVisionElasticBS(PythonAlgorithm): def category(self): return "DataHandling\\Nexus" + def seeAlso(self): + return [ "LoadVisionElasticEQ","LoadVisionInelastic" ] + def name(self): return "LoadVisionElasticBS" diff --git a/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticEQ.py b/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticEQ.py index 79b1af0f6eb..8ce8b6db34e 100644 --- a/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticEQ.py +++ b/Framework/PythonInterface/plugins/algorithms/LoadVisionElasticEQ.py @@ -16,6 +16,9 @@ class LoadVisionElasticEQ(PythonAlgorithm): def category(self): return "DataHandling\\Nexus" + def seeAlso(self): + return [ "LoadVisionElasticBS","LoadVisionInelastic" ] + def name(self): return "LoadVisionElasticEQ" diff --git a/Framework/PythonInterface/plugins/algorithms/LoadVisionInelastic.py b/Framework/PythonInterface/plugins/algorithms/LoadVisionInelastic.py index fdec94a4f92..8fe64569d07 100644 --- a/Framework/PythonInterface/plugins/algorithms/LoadVisionInelastic.py +++ b/Framework/PythonInterface/plugins/algorithms/LoadVisionInelastic.py @@ -16,6 +16,9 @@ class LoadVisionInelastic(PythonAlgorithm): def category(self): return "DataHandling\\Nexus" + def seeAlso(self): + return [ "LoadVisionElasticBS","LoadVisionElasticEQ" ] + def name(self): return "LoadVisionInelastic" diff --git a/Framework/PythonInterface/plugins/algorithms/MagnetismReflectometryReduction.py b/Framework/PythonInterface/plugins/algorithms/MagnetismReflectometryReduction.py index 596f1e40170..91be6ae1c85 100644 --- a/Framework/PythonInterface/plugins/algorithms/MagnetismReflectometryReduction.py +++ b/Framework/PythonInterface/plugins/algorithms/MagnetismReflectometryReduction.py @@ -477,29 +477,42 @@ class MagnetismReflectometryReduction(PythonAlgorithm): """ sample_length = self.getProperty("SampleLength").value - #TODO: Read the slit distances relative to the sample from the logs once - # they are available with the new DAS. - slits =[[ws.getRun().getProperty("S1HWidth").getStatistics().mean, 2600.], - [ws.getRun().getProperty("S2HWidth").getStatistics().mean, 2019.], - [ws.getRun().getProperty("S3HWidth").getStatistics().mean, 714.]] - theta = ws.getRun().getProperty("two_theta").value/2.0 + # In newer data files, the slit distances are part of the logs + if ws.getRun().hasProperty("S1Distance"): + s1_dist = ws.getRun().getProperty("S1Distance").value + s2_dist = ws.getRun().getProperty("S2Distance").value + s3_dist = ws.getRun().getProperty("S3Distance").value + else: + s1_dist = -2600. + s2_dist = -2019. + s3_dist = -714. + slits =[[ws.getRun().getProperty("S1HWidth").getStatistics().mean, s1_dist], + [ws.getRun().getProperty("S2HWidth").getStatistics().mean, s2_dist], + [ws.getRun().getProperty("S3HWidth").getStatistics().mean, s3_dist]] + theta = ws.getRun().getProperty("two_theta").value/2.0 * np.pi / 180.0 res=[] - s_width=sample_length*math.sin(theta) + s_width=sample_length*np.sin(theta) for width, dist in slits: # Calculate the maximum opening angle dTheta if s_width > 0.: - d_theta = math.atan((s_width/2.*(1.+width/s_width))/dist)*2. + d_theta = np.arctan((s_width/2.*(1.+width/s_width))/dist)*2. else: - d_theta = math.atan(width/2./dist)*2. + d_theta = np.arctan(width/2./dist)*2. # The standard deviation for a uniform angle distribution is delta/sqrt(12) res.append(d_theta*0.28867513) - dq_over_q = min(res) / math.tan(theta) + # Wavelength uncertainty + lambda_min = ws.getRun().getProperty("lambda_min").value + lambda_max = ws.getRun().getProperty("lambda_max").value + dq_over_q = min(res) / np.tan(theta) data_x = ws.dataX(0) data_dx = ws.dataDx(0) + dwl = (lambda_max - lambda_min) / len(data_x) / np.sqrt(12.0) for i in range(len(data_x)): - data_dx[i] = data_x[i] * dq_over_q + dq_theta = data_x[i] * dq_over_q + dq_wl = data_x[i]**2 * dwl / (4.0*np.pi*np.sin(theta)) + data_dx[i] = np.sqrt(dq_theta**2 + dq_wl**2) return ws diff --git a/Framework/PythonInterface/plugins/algorithms/MaskAngle.py b/Framework/PythonInterface/plugins/algorithms/MaskAngle.py index 772db73daec..5c5805a5369 100644 --- a/Framework/PythonInterface/plugins/algorithms/MaskAngle.py +++ b/Framework/PythonInterface/plugins/algorithms/MaskAngle.py @@ -15,6 +15,9 @@ class MaskAngle(mantid.api.PythonAlgorithm): """ return "Transforms\\Masking" + def seeAlso(self): + return [ "MaskDetectors" ] + def name(self): """ Mantid require """ diff --git a/Framework/PythonInterface/plugins/algorithms/MaskBTP.py b/Framework/PythonInterface/plugins/algorithms/MaskBTP.py index 071924945e8..e3bdc053705 100644 --- a/Framework/PythonInterface/plugins/algorithms/MaskBTP.py +++ b/Framework/PythonInterface/plugins/algorithms/MaskBTP.py @@ -24,6 +24,9 @@ class MaskBTP(mantid.api.PythonAlgorithm): """ return "Transforms\\Masking;Inelastic\\Utility" + def seeAlso(self): + return [ "MaskDetectors","MaskInstrument" ] + def name(self): """ Mantid required """ diff --git a/Framework/PythonInterface/plugins/algorithms/MaskWorkspaceToCalFile.py b/Framework/PythonInterface/plugins/algorithms/MaskWorkspaceToCalFile.py index 981b8b3d0a4..ae736dae55d 100644 --- a/Framework/PythonInterface/plugins/algorithms/MaskWorkspaceToCalFile.py +++ b/Framework/PythonInterface/plugins/algorithms/MaskWorkspaceToCalFile.py @@ -24,6 +24,10 @@ class MaskWorkspaceToCalFile(PythonAlgorithm): def category(self): return "DataHandling\\Text;Diffraction\\DataHandling;Diffraction\\Masking" + def seeAlso(self): + return [ "ReadGroupsFromFile","CreateDummyCalFile","CreateCalFileByNames", + "AlignDetectors","DiffractionFocussing","LoadCalFile","SaveCalFile","MergeCalFiles" ] + def name(self): return "MaskWorkspaceToCalFile" diff --git a/Framework/PythonInterface/plugins/algorithms/Mean.py b/Framework/PythonInterface/plugins/algorithms/Mean.py index 7b192ce4e89..59d8b93a16e 100644 --- a/Framework/PythonInterface/plugins/algorithms/Mean.py +++ b/Framework/PythonInterface/plugins/algorithms/Mean.py @@ -13,6 +13,9 @@ class Mean(PythonAlgorithm): def category(self): return "Arithmetic" + def seeAlso(self): + return [ "MostLikelyMean","WeightedMean","WeightedMeanOfWorkspace" ] + def name(self): return "Mean" diff --git a/Framework/PythonInterface/plugins/algorithms/MergeCalFiles.py b/Framework/PythonInterface/plugins/algorithms/MergeCalFiles.py index 8c2b116f84f..ea0382a6d58 100644 --- a/Framework/PythonInterface/plugins/algorithms/MergeCalFiles.py +++ b/Framework/PythonInterface/plugins/algorithms/MergeCalFiles.py @@ -9,6 +9,10 @@ class MergeCalFiles(PythonAlgorithm): def category(self): return "DataHandling\\Text;Diffraction\\DataHandling\\CalFiles" + def seeAlso(self): + return [ "ReadGroupsFromFile","CreateDummyCalFile","CreateCalFileByNames", + "AlignDetectors","DiffractionFocussing","LoadCalFile","SaveCalFile" ] + def name(self): return "MergeCalFiles" diff --git a/Framework/PythonInterface/plugins/algorithms/MuonMaxent.py b/Framework/PythonInterface/plugins/algorithms/MuonMaxent.py index 2ede9effc74..28eafd02a7f 100644 --- a/Framework/PythonInterface/plugins/algorithms/MuonMaxent.py +++ b/Framework/PythonInterface/plugins/algorithms/MuonMaxent.py @@ -35,6 +35,9 @@ class MuonMaxent(PythonAlgorithm): def category(self): return "Muon;Arithmetic\\FFT" + def seeAlso(self): + return [ "PhaseQuad","FFT" ] + def PyInit(self): self.declareProperty( WorkspaceProperty("InputWorkspace", diff --git a/Framework/PythonInterface/plugins/algorithms/PDToGUDRUN.py b/Framework/PythonInterface/plugins/algorithms/PDToGUDRUN.py index 71ee15fb52c..136152bbcc9 100644 --- a/Framework/PythonInterface/plugins/algorithms/PDToGUDRUN.py +++ b/Framework/PythonInterface/plugins/algorithms/PDToGUDRUN.py @@ -15,6 +15,9 @@ class PDToGUDRUN(DataProcessorAlgorithm): def category(self): return "Workflow\\Diffraction" + def seeAlso(self): + return [ "PDToPDFgetN" ] + def name(self): return "PDToGUDRUN" diff --git a/Framework/PythonInterface/plugins/algorithms/PDToPDFgetN.py b/Framework/PythonInterface/plugins/algorithms/PDToPDFgetN.py index b31a019a7a5..0e2e6709d0e 100644 --- a/Framework/PythonInterface/plugins/algorithms/PDToPDFgetN.py +++ b/Framework/PythonInterface/plugins/algorithms/PDToPDFgetN.py @@ -19,6 +19,9 @@ class PDToPDFgetN(DataProcessorAlgorithm): def category(self): return "Workflow\\Diffraction" + def seeAlso(self): + return [ "PDToGUDRUN" ] + def name(self): return "PDToPDFgetN" diff --git a/Framework/PythonInterface/plugins/algorithms/PearlMCAbsorption.py b/Framework/PythonInterface/plugins/algorithms/PearlMCAbsorption.py index 6d18bd5d01a..9f96154d37d 100644 --- a/Framework/PythonInterface/plugins/algorithms/PearlMCAbsorption.py +++ b/Framework/PythonInterface/plugins/algorithms/PearlMCAbsorption.py @@ -14,6 +14,10 @@ class PearlMCAbsorption(PythonAlgorithm): def summary(self): return "Loads pre-calculated or measured absorption correction files for Pearl." + def seeAlso(self): + return [ "MonteCarloAbsorption", "MayersSampleCorrection", + "MultipleScatteringCylinderAbsorption", "VesuvioCalculateMS" ] + def PyInit(self): # Input file self.declareProperty(FileProperty("Filename","", FileAction.Load, ['.out','.dat']), doc="The name of the input file.") diff --git a/Framework/PythonInterface/plugins/algorithms/PoldiCreatePeaksFromFile.py b/Framework/PythonInterface/plugins/algorithms/PoldiCreatePeaksFromFile.py index da350d1d7d0..a1207669b60 100644 --- a/Framework/PythonInterface/plugins/algorithms/PoldiCreatePeaksFromFile.py +++ b/Framework/PythonInterface/plugins/algorithms/PoldiCreatePeaksFromFile.py @@ -144,6 +144,9 @@ class PoldiCreatePeaksFromFile(PythonAlgorithm): def category(self): return "SINQ\\Poldi" + def seeAlso(self): + return [ "PoldiCreatePeaksFromCell" ] + def name(self): return "PoldiLoadCrystalData" diff --git a/Framework/PythonInterface/plugins/algorithms/RefLReduction.py b/Framework/PythonInterface/plugins/algorithms/RefLReduction.py deleted file mode 100644 index a6467a68d83..00000000000 --- a/Framework/PythonInterface/plugins/algorithms/RefLReduction.py +++ /dev/null @@ -1,390 +0,0 @@ -#pylint: disable=no-init,invalid-name -from __future__ import (absolute_import, division, print_function) -from mantid.api import * -from mantid.simpleapi import * -from mantid.kernel import * - -# import sfCalculator -import sys -import os -sys.path.insert(0,os.path.dirname(__file__)) -import sfCalculator # noqa -sys.path.pop(0) - - -class RefLReduction(PythonAlgorithm): - - def category(self): - return "Reflectometry\\SNS" - - def name(self): - return "RefLReduction" - - def version(self): - return 1 - - def summary(self): - return "Liquids Reflectometer (REFL) reduction" - - def PyInit(self): - self.declareProperty(IntArrayProperty("RunNumbers"), "List of run numbers to process") - self.declareProperty("NormalizationRunNumber", 0, "Run number of the normalization run to use") - self.declareProperty(IntArrayProperty("SignalPeakPixelRange"), "Pixel range defining the data peak") - self.declareProperty("SubtractSignalBackground", True, - doc='If true, the background will be subtracted from the data peak') - self.declareProperty(IntArrayProperty("SignalBackgroundPixelRange", [123, 137], - IntArrayLengthValidator(2), direction=Direction.Input), - "Pixelrange defining the background. Default:(123,137)") - self.declareProperty("NormFlag", True, doc="If true, the data will be normalized") - self.declareProperty(IntArrayProperty("NormPeakPixelRange", [127,133], - IntArrayLengthValidator(2), direction=Direction.Input), - "Pixel range defining the normalization peak") - self.declareProperty("SubtractNormBackground", True, - doc="If true, the background will be subtracted from the normalization peak") - self.declareProperty(IntArrayProperty("NormBackgroundPixelRange", [127,137], - IntArrayLengthValidator(2), direction=Direction.Input), - "Pixel range defining the background for the normalization") - self.declareProperty("LowResDataAxisPixelRangeFlag", True, - doc="If true, the low resolution direction of the data will be cropped according "+ - "to the lowResDataAxisPixelRange property") - self.declareProperty(IntArrayProperty("LowResDataAxisPixelRange", [115,210], - IntArrayLengthValidator(2), direction=Direction.Input), - "Pixel range to use in the low resolution direction of the data") - self.declareProperty("LowResNormAxisPixelRangeFlag", True, - doc="If true, the low resolution direction of the normalization run will be cropped "+ - "according to the LowResNormAxisPixelRange property") - self.declareProperty(IntArrayProperty("LowResNormAxisPixelRange", [115,210], - IntArrayLengthValidator(2), direction=Direction.Input), - "Pixel range to use in the low resolution direction of the normalizaion run") - self.declareProperty(FloatArrayProperty("TOFRange", [9000., 23600.], - FloatArrayLengthValidator(2), direction=Direction.Input), - "TOF range to use") - self.declareProperty("TofRangeFlag", True, - doc="If true, the TOF will be cropped according to the TOF range property") - self.declareProperty("QMin", 0.05, doc="Mnimum Q-value") - self.declareProperty("QStep", 0.02, doc="Step size in Q. Enter a negative value to get a log scale") - self.declareProperty("AngleOffset", 0.0, doc="angle offset (degrees)") - self.declareProperty("AngleOffsetError", 0.0, doc="Angle offset error (degrees)") - self.declareProperty(MatrixWorkspaceProperty("OutputWorkspace", "", Direction.Output), "Output workspace") -# self.declareProperty("", True, -# doc="Use Scaling Factor configuration file") - self.declareProperty("ScalingFactorFile", "", doc="Scaling factor configuration file") - self.declareProperty("SlitsWidthFlag", True, - doc="Looking for perfect match of slits width when using Scaling Factor file") - self.declareProperty("IncidentMediumSelected", "", doc="Incident medium used for those runs") - self.declareProperty("GeometryCorrectionFlag", False, doc="Use or not the geometry correction") - - #pylint: disable=too-many-locals, too-many-branches - def PyExec(self): - - print('-- > starting new Reflectometer Reduction ...') - - from reduction.instruments.reflectometer import wks_utility - - #remove all previous workspaces - list_mt = mtd.getObjectNames() - for _mt in list_mt: - if _mt.find('_scaled') != -1: - DeleteWorkspace(_mt) - if _mt.find('_reflectivity') != -1: - DeleteWorkspace(_mt) - - # retrieve settings from GUI - print('-> Retrieving settings from GUI') - - #print 'RunNumbers: ' + str(self.getProperty("RunNumbers").value) - #print 'NormalizationRunNumber: ' + str(self.getProperty("NormalizationRunNumber").value) - #print 'SignalPeakPixelRange: ' + str(self.getProperty("SignalPeakPixelRange").value) - #print 'SubtractSignalBackground: ' + str(self.getProperty("SubtractSignalBackground").value) - #print 'SignalBackgroundPixelRange: ' + str(self.getProperty("SignalBackgroundPixelRange").value) - #print "NormFlag: " + str(self.getProperty("NormFlag").value) - #print "NormPeakPixelRange: " + str(self.getProperty("NormPeakPixelRange").value) - #print "NormBackgroundPixelRange: " + str(self.getProperty("NormBackgroundPixelRange").value) - #print "SubtractNormBackground: " + str(self.getProperty("SubtractNormBackground").value) - #print "LowResDataAxisPixelRangeFlag: " + str(self.getProperty("LowResDataAxisPixelRangeFlag").value) - #print "LowResDataAxisPixelRange: " + str(self.getProperty("LowResDataAxisPixelRange").value) - #print "LowResNormAxisPixelRangeFlag: " + str(self.getProperty("LowResNormAxisPixelRangeFlag").value) - #print "LowResNormAxisPixelRange: " + str(self.getProperty("LowResNormAxisPixelRange").value) - #print "TOFRange: " + str(self.getProperty("TOFRange").value) - #print "IncidentMediumSelected: " + str(self.getProperty("incidentMediumSelected").value) - #print "GeometryCorrectionFlag: " + str(self.getProperty("GeometryCorrectionFlag").value) - #print "QMin: " + str(self.getProperty("QMin").value) - #print "QStep: " + str(self.getProperty("QStep").value) - #print "ScalingFactorFile: " + str(self.getProperty("ScalingFactorFile").value) - #print "SlitsWidthFlag: " + str(self.getProperty("SlitsWidthFlag").value) - #print "OutputWorkspace: " + str(self.getProperty("OutputWorkspace").value) - - # DATA - dataRunNumbers = self.getProperty("RunNumbers").value - dataPeakRange = self.getProperty("SignalPeakPixelRange").value - dataBackRange = self.getProperty("SignalBackgroundPixelRange").value - dataBackFlag = self.getProperty("SubtractSignalBackground").value - #Due to the frame effect, it's sometimes necessary to narrow the range - #over which we add all the pixels along the low resolution - #Parameter - dataLowResFlag = self.getProperty("LowResDataAxisPixelRangeFlag") - if dataLowResFlag: - dataLowResRange = self.getProperty("LowResDataAxisPixelRange").value - else: - dataLowResRange = [0,maxX-1] - - # NORM - normalizationRunNumber = self.getProperty("NormalizationRunNumber").value - # normFlag = self.getProperty("NormFlag") - normBackRange = self.getProperty("NormBackgroundPixelRange").value - normPeakRange = self.getProperty("NormPeakPixelRange").value - normBackFlag = self.getProperty("SubtractNormBackground").value - #Due to the frame effect, it's sometimes necessary to narrow the range - #over which we add all the pixels along the low resolution - #Parameter - normLowResFlag = self.getProperty("LowResNormAxisPixelRangeFlag") - if normLowResFlag: - normLowResRange = self.getProperty("LowResNormAxisPixelRange").value - else: - normLowResRange = [0,maxX-1] - - #GENERAL - TOFrangeFlag = self.getProperty("TofRangeFlag") - if TOFrangeFlag: - TOFrange = self.getProperty("TOFRange").value #microS - else: - TOFrange = [0, 200000] - # TOF binning parameters - binTOFrange = [0, 200000] - binTOFsteps = 40 - - # geometry correction - geometryCorrectionFlag = self.getProperty("GeometryCorrectionFlag").value - - qMin = self.getProperty("QMin").value - qStep = self.getProperty("QStep").value - if qStep > 0: #force logarithmic binning - qStep = -qStep - - # angle offset - angleOffsetDeg = self.getProperty("AngleOffset").value - - # sfCalculator settings - slitsValuePrecision = sfCalculator.PRECISION - sfFile = self.getProperty("ScalingFactorFile").value - - incidentMedium = self.getProperty("IncidentMediumSelected").value - slitsWidthFlag = self.getProperty("SlitsWidthFlag").value - # ==== done retrievin the settings ===== - - # ==== start reduction ==== - - # work with data - # load data - ws_event_data = wks_utility.loadNeXus(dataRunNumbers, 'data') - - is_nexus_detector_rotated_flag = wks_utility.isNexusTakeAfterRefDate(ws_event_data.getRun().getProperty('run_start').value) - print('-> is NeXus taken with new detector geometry: ' + str(is_nexus_detector_rotated_flag)) - - ## retrieve general informations - # calculate the central pixel (using weighted average) - print('-> retrieving general informations') - data_central_pixel = wks_utility.getCentralPixel(ws_event_data, - dataPeakRange, - is_nexus_detector_rotated_flag) - # get the distance moderator-detector and sample-detector - [dMD, dSD] = wks_utility.getDistances(ws_event_data) - # get theta - theta = wks_utility.getTheta(ws_event_data, angleOffsetDeg) - # get proton charge - pc = wks_utility.getProtonCharge(ws_event_data) - error_0 = 1. / pc - - # rebin data - ws_histo_data = wks_utility.rebinNeXus(ws_event_data, - [binTOFrange[0], binTOFsteps, binTOFrange[1]], - 'data') - - # get q range - q_range = wks_utility.getQrange(ws_histo_data, theta, dMD, qMin, qStep) - - # slit size - [first_slit_size, last_slit_size] = wks_utility.getSlitsSize(ws_histo_data) - - # keep only TOF range - ws_histo_data = wks_utility.cropTOF(ws_histo_data, - TOFrange[0], - TOFrange[1], - 'data') - - # normalize by current proton charge - ws_histo_data = wks_utility.normalizeNeXus(ws_histo_data, 'data') - - # integrate over low resolution range - [data_tof_axis, data_y_axis, data_y_error_axis] = wks_utility.integrateOverLowResRange(ws_histo_data, - dataLowResRange, - 'data', - is_nexus_detector_rotated_flag) - -# #DEBUG ONLY -# wks_utility.ouput_big_ascii_file( -#'/mnt/hgfs/j35/Matlab/DebugMantid/Strange0ValuesToData/data_file_after_low_resolution_integration.txt', -# data_tof_axis, -# data_y_axis, -# data_y_error_axis) - - tof_axis = data_tof_axis[0:-1].copy() - tof_axis_full = data_tof_axis.copy() - - # data_tof_axis.shape -> (62,) - # data_y_axis.shape -> (256,61) - - #substract background - [data_y_axis, data_y_error_axis] = wks_utility.substractBackground(tof_axis , - data_y_axis, - data_y_error_axis, - dataPeakRange, - dataBackFlag, - dataBackRange, - error_0, - 'data') -# #DEBUG ONLY -# wks_utility.ouput_big_ascii_file('/mnt/hgfs/j35/Matlab/DebugMantid/Strange0ValuesToData/data_file_back_sub_not_integrated.txt', -# data_tof_axis, -# data_y_axis, -# data_y_error_axis) - - # work with normalization - - # load normalization - ws_event_norm = wks_utility.loadNeXus(int(normalizationRunNumber), 'normalization') - - # get proton charge - pc = wks_utility.getProtonCharge(ws_event_norm) - error_0 = 1. / pc - - # rebin normalization - ws_histo_norm = wks_utility.rebinNeXus(ws_event_norm, - [binTOFrange[0], binTOFsteps, binTOFrange[1]], - 'normalization') - - # keep only TOF range - ws_histo_norm = wks_utility.cropTOF(ws_histo_norm, - TOFrange[0], - TOFrange[1], - 'normalization') - - # normalize by current proton charge - ws_histo_norm = wks_utility.normalizeNeXus(ws_histo_norm, 'normalization') - - # integrate over low resolution range - [norm_tof_axis, norm_y_axis, norm_y_error_axis] = wks_utility.integrateOverLowResRange(ws_histo_norm, - normLowResRange, - 'normalization', - is_nexus_detector_rotated_flag) - - # substract background - [norm_y_axis, norm_y_error_axis] = wks_utility.substractBackground(norm_tof_axis[0:-1], - norm_y_axis, - norm_y_error_axis, - normPeakRange, - normBackFlag, - normBackRange, - error_0, - 'normalization') - - [av_norm, av_norm_error] = wks_utility.fullSumWithError(norm_y_axis, - norm_y_error_axis) - -# ## DEBUGGING ONLY -# wks_utility.ouput_ascii_file('/mnt/hgfs/j35/Matlab/DebugMantid/Strange0ValuesToData/norm_file_back_sub_not_integrated.txt', -# norm_tof_axis, -# av_norm, -# av_norm_error) - - [final_data_y_axis, final_data_y_error_axis] = wks_utility.divideDataByNormalization(data_y_axis, - data_y_error_axis, - av_norm, - av_norm_error) - -# #DEBUG ONLY -# wks_utility.ouput_big_ascii_file('/mnt/hgfs/j35/Matlab/DebugMantid/Strange0ValuesToData/data_divided_by_norm_not_integrated.txt', -# data_tof_axis, -# final_data_y_axis, -# final_data_y_error_axis) - - # apply Scaling factor - [tof_axis_full, y_axis, y_error_axis, isSFfound] = wks_utility.applyScalingFactor(tof_axis_full, - final_data_y_axis, - final_data_y_error_axis, - incidentMedium, - sfFile, - slitsValuePrecision, - slitsWidthFlag) - -# #DEBUG ONLY -# wks_utility.ouput_big_ascii_file('/mnt/hgfs/j35/Matlab/DebugMantid/Strange0ValuesToData/after_applying_scaling_factor.txt', -# data_tof_axis, -# y_axis, -# y_error_axis) - - if geometryCorrectionFlag: # convert To Q with correction - [q_axis, y_axis, y_error_axis] = wks_utility.convertToQ(tof_axis_full, - y_axis, - y_error_axis, - peak_range = dataPeakRange, - central_pixel = data_central_pixel, - source_to_detector_distance = dMD, - sample_to_detector_distance = dSD, - theta = theta, - first_slit_size = first_slit_size, - last_slit_size = last_slit_size) - - else: # convert to Q without correction - - [q_axis, y_axis, y_error_axis] = wks_utility.convertToQWithoutCorrection(tof_axis_full, - y_axis, - y_error_axis, - peak_range = dataPeakRange, - source_to_detector_distance = dMD, - sample_to_detector_distance = dSD, - theta = theta, - first_slit_size = first_slit_size, - last_slit_size = last_slit_size) - - -# wks_utility.ouput_big_Q_ascii_file('/mnt/hgfs/j35/Matlab/DebugMantid/Strange0ValuesToData/after_conversion_to_q.txt', -# q_axis, -# y_axis, -# y_error_axis) - - # create workspace - q_workspace = wks_utility.createQworkspace(q_axis, y_axis, y_error_axis) - - q_rebin = Rebin(InputWorkspace=q_workspace, - Params=q_range, - PreserveEvents=True) - - # keep only the q values that have non zero counts - nonzero_q_rebin_wks = wks_utility.cropAxisToOnlyNonzeroElements(q_rebin, - dataPeakRange) - # integrate spectra (normal mean) and remove first and last Q value - [final_x_axis, final_y_axis, final_error_axis] = wks_utility.integrateOverPeakRange(nonzero_q_rebin_wks, dataPeakRange) - - # cleanup data - [final_y_axis, final_y_error_axis] = wks_utility.cleanupData1D(final_y_axis, - final_error_axis) - - # create final workspace - import time - _time = int(time.time()) - name_output_ws = self.getPropertyValue("OutputWorkspace") - name_output_ws = name_output_ws + '_#' + str(_time) + 'ts' - wks_utility.createFinalWorkspace(final_x_axis, - final_y_axis, - final_y_error_axis, - name_output_ws, - ws_event_data) - AddSampleLog(Workspace=name_output_ws, - LogName='isSFfound', - LOgText=str(isSFfound)) - - self.setProperty('OutputWorkspace', mtd[name_output_ws]) - - -AlgorithmFactory.subscribe(RefLReduction) diff --git a/Framework/PythonInterface/plugins/algorithms/RefinePowderDiffProfileSeq.py b/Framework/PythonInterface/plugins/algorithms/RefinePowderDiffProfileSeq.py index ce93bb8f87e..b666bdb7bd7 100644 --- a/Framework/PythonInterface/plugins/algorithms/RefinePowderDiffProfileSeq.py +++ b/Framework/PythonInterface/plugins/algorithms/RefinePowderDiffProfileSeq.py @@ -40,6 +40,9 @@ class RefinePowderDiffProfileSeq(PythonAlgorithm): """ return "Diffraction\\Fitting" + def seeAlso(self): + return [ "RefinePowderInstrumentParameters" ] + def name(self): """ Algorithm name """ diff --git a/Framework/PythonInterface/plugins/algorithms/RetrieveRunInfo.py b/Framework/PythonInterface/plugins/algorithms/RetrieveRunInfo.py index 112e1b8d5e5..20bb725b0ae 100644 --- a/Framework/PythonInterface/plugins/algorithms/RetrieveRunInfo.py +++ b/Framework/PythonInterface/plugins/algorithms/RetrieveRunInfo.py @@ -191,6 +191,9 @@ class RetrieveRunInfo(PythonAlgorithm): return "Given a range of run numbers and an output workspace name, will compile a table of info for "+\ "each run of the instrument you have set as default." + def seeAlso(self): + return [ "CreateLogPropertyTable" ] + def PyInit(self): # Declare algorithm properties. self.declareProperty( diff --git a/Framework/PythonInterface/plugins/algorithms/SANSSubtract.py b/Framework/PythonInterface/plugins/algorithms/SANSSubtract.py index 12684213282..325358d88c4 100644 --- a/Framework/PythonInterface/plugins/algorithms/SANSSubtract.py +++ b/Framework/PythonInterface/plugins/algorithms/SANSSubtract.py @@ -17,6 +17,9 @@ class SANSSubtract(PythonAlgorithm): """ return "SANS" + def seeAlso(self): + return [ "SANSStitch","SANSFitShiftScale" ] + def name(self): """ Return name diff --git a/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py b/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py index a2b6d8291ab..ba71273be7b 100644 --- a/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py +++ b/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py @@ -138,6 +138,9 @@ class SNSPowderReduction(DistributedDataProcessorAlgorithm): def category(self): return "Diffraction\\Reduction" + def seeAlso(self): + return [ "DiffractionFocussing","AlignAndFocusPowder" ] + def name(self): return "SNSPowderReduction" diff --git a/Framework/PythonInterface/plugins/algorithms/SaveNexusPD.py b/Framework/PythonInterface/plugins/algorithms/SaveNexusPD.py index 9d5498c1985..72c096474a3 100644 --- a/Framework/PythonInterface/plugins/algorithms/SaveNexusPD.py +++ b/Framework/PythonInterface/plugins/algorithms/SaveNexusPD.py @@ -27,6 +27,9 @@ class SaveNexusPD(mantid.api.PythonAlgorithm): def category(self): return "DataHandling\\Nexus" + def seeAlso(self): + return [ "SaveNexus" ] + def name(self): return "SaveNexusPD" diff --git a/Framework/PythonInterface/plugins/algorithms/SavePlot1DAsJson.py b/Framework/PythonInterface/plugins/algorithms/SavePlot1DAsJson.py index 6e4a62e6e0c..4cca8b79ae2 100644 --- a/Framework/PythonInterface/plugins/algorithms/SavePlot1DAsJson.py +++ b/Framework/PythonInterface/plugins/algorithms/SavePlot1DAsJson.py @@ -15,6 +15,9 @@ class SavePlot1DAsJson(PythonAlgorithm): """ return "DataHandling\\Plots" + def seeAlso(self): + return [ "SavePlot1D","StringToPng" ] + def name(self): """ """ diff --git a/Framework/PythonInterface/plugins/algorithms/SaveReflections.py b/Framework/PythonInterface/plugins/algorithms/SaveReflections.py index 894549a9f12..ef5b38c0c31 100644 --- a/Framework/PythonInterface/plugins/algorithms/SaveReflections.py +++ b/Framework/PythonInterface/plugins/algorithms/SaveReflections.py @@ -5,7 +5,7 @@ from mantid.simpleapi import SaveHKL # List of file format names supported by this algorithm SUPPORTED_FORMATS = ["Fullprof", "GSAS", "Jana", "SHELX"] -NUM_PEAKSWS_COLUMNS = 17 +NUM_PEAKSWS_COLUMNS = 18 def has_modulated_indexing(workspace): diff --git a/Framework/PythonInterface/plugins/algorithms/SortByQVectors.py b/Framework/PythonInterface/plugins/algorithms/SortByQVectors.py index 3b13cc9d5a5..fbd980e03f8 100644 --- a/Framework/PythonInterface/plugins/algorithms/SortByQVectors.py +++ b/Framework/PythonInterface/plugins/algorithms/SortByQVectors.py @@ -15,6 +15,9 @@ class SortByQVectors(PythonAlgorithm): def category(self): return "Transforms\\Merging;Utility\\Sorting" + def seeAlso(self): + return [ "SortDetectors" ] + def name(self): return "SortByQVectors" diff --git a/Framework/PythonInterface/plugins/algorithms/SortDetectors.py b/Framework/PythonInterface/plugins/algorithms/SortDetectors.py index 1a48cb09a4c..7951bead58b 100644 --- a/Framework/PythonInterface/plugins/algorithms/SortDetectors.py +++ b/Framework/PythonInterface/plugins/algorithms/SortDetectors.py @@ -16,6 +16,9 @@ class SortDetectors(PythonAlgorithm): """ return "Utility\\Sorting" + def seeAlso(self): + return [ "SortByQVectors","SortXAxis" ] + def name(self): """ Return name """ diff --git a/Framework/PythonInterface/plugins/algorithms/SortXAxis.py b/Framework/PythonInterface/plugins/algorithms/SortXAxis.py index ee803cb59e1..41c8dd04224 100644 --- a/Framework/PythonInterface/plugins/algorithms/SortXAxis.py +++ b/Framework/PythonInterface/plugins/algorithms/SortXAxis.py @@ -1,8 +1,8 @@ #pylint: disable=no-init,invalid-name from __future__ import (absolute_import, division, print_function) -from mantid.api import * -from mantid.kernel import * +from mantid.api import AlgorithmFactory, MatrixWorkspaceProperty, PythonAlgorithm +from mantid.kernel import Direction, StringListValidator import numpy as np @@ -11,6 +11,9 @@ class SortXAxis(PythonAlgorithm): def category(self): return "Transforms\\Axes;Utility\\Sorting" + def seeAlso(self): + return [ "SortDetectors" ] + def name(self): return "SortXAxis" @@ -22,6 +25,11 @@ class SortXAxis(PythonAlgorithm): doc="Input workspace") self.declareProperty(MatrixWorkspaceProperty("OutputWorkspace", defaultValue="", direction=Direction.Output), doc="Sorted Output Workspace") + self.declareProperty("Ordering", + defaultValue="Ascending", + validator=StringListValidator(["Ascending", "Descending"]), + direction=Direction.Input, + doc="Ascending or descending sorting") def PyExec(self): input_ws = self.getProperty('InputWorkspace').value @@ -40,9 +48,14 @@ class SortXAxis(PythonAlgorithm): y_data = input_ws.readY(i) e_data = input_ws.readE(i) - indexes = x_data.argsort() + indexes = x_data.argsort() + + if self.getPropertyValue("Ordering") == "Descending": + self.log().information("Sort descending") + indexes = indexes[::-1] x_ordered = x_data[indexes] + if input_ws.isHistogramData(): max_index = np.argmax(indexes) indexes = np.delete(indexes, max_index) @@ -54,7 +67,12 @@ class SortXAxis(PythonAlgorithm): output_ws.setY(i, y_ordered) output_ws.setE(i, e_ordered) + if input_ws.hasDx(i): + dx = input_ws.readDx(i) + dx_ordered = dx[indexes] + output_ws.setDx(i, dx_ordered) + self.setProperty('OutputWorkspace', output_ws) -AlgorithmFactory.subscribe(SortXAxis()) +AlgorithmFactory.subscribe(SortXAxis) diff --git a/Framework/PythonInterface/plugins/algorithms/StringToPng.py b/Framework/PythonInterface/plugins/algorithms/StringToPng.py index 184ea6cab96..0349445489a 100644 --- a/Framework/PythonInterface/plugins/algorithms/StringToPng.py +++ b/Framework/PythonInterface/plugins/algorithms/StringToPng.py @@ -11,6 +11,9 @@ class StringToPng(mantid.api.PythonAlgorithm): """ return "DataHandling\\Plots" + def seeAlso(self): + return [ "SavePlot1D" ] + def name(self): """ Algorithm name """ diff --git a/Framework/PythonInterface/plugins/algorithms/SuggestTibCNCS.py b/Framework/PythonInterface/plugins/algorithms/SuggestTibCNCS.py index 51a7993a62a..538ee9d1433 100644 --- a/Framework/PythonInterface/plugins/algorithms/SuggestTibCNCS.py +++ b/Framework/PythonInterface/plugins/algorithms/SuggestTibCNCS.py @@ -34,6 +34,9 @@ class SuggestTibCNCS(PythonAlgorithm): """ return "Inelastic\\Utility" + def seeAlso(self): + return [ "SuggestTibHYSPEC" ] + def name(self): """ Return name """ diff --git a/Framework/PythonInterface/plugins/algorithms/SuggestTibHYSPEC.py b/Framework/PythonInterface/plugins/algorithms/SuggestTibHYSPEC.py index e4f653aa559..b2354db6131 100644 --- a/Framework/PythonInterface/plugins/algorithms/SuggestTibHYSPEC.py +++ b/Framework/PythonInterface/plugins/algorithms/SuggestTibHYSPEC.py @@ -15,6 +15,9 @@ class SuggestTibHYSPEC(PythonAlgorithm): """ return "Inelastic\\Utility" + def seeAlso(self): + return [ "SuggestTibCNCS" ] + def name(self): """ Return name """ diff --git a/Framework/PythonInterface/plugins/algorithms/TOFTOFCropWorkspace.py b/Framework/PythonInterface/plugins/algorithms/TOFTOFCropWorkspace.py index 8c14b944c38..64706916799 100644 --- a/Framework/PythonInterface/plugins/algorithms/TOFTOFCropWorkspace.py +++ b/Framework/PythonInterface/plugins/algorithms/TOFTOFCropWorkspace.py @@ -17,6 +17,9 @@ class TOFTOFCropWorkspace(PythonAlgorithm): """ return "Workflow\\MLZ\\TOFTOF;Transforms\\Splitting" + def seeAlso(self): + return [ "TOFTOFMergeRuns","CorrectTOF" ] + def name(self): """ Return summary """ diff --git a/Framework/PythonInterface/plugins/algorithms/TOFTOFMergeRuns.py b/Framework/PythonInterface/plugins/algorithms/TOFTOFMergeRuns.py index 56f24da68de..69c9e7dd8f5 100644 --- a/Framework/PythonInterface/plugins/algorithms/TOFTOFMergeRuns.py +++ b/Framework/PythonInterface/plugins/algorithms/TOFTOFMergeRuns.py @@ -27,6 +27,9 @@ class TOFTOFMergeRuns(PythonAlgorithm): """ return "Workflow\\MLZ\\TOFTOF;Transforms\\Splitting" + def seeAlso(self): + return [ "TOFTOFCropWorkspace","CorrectTOF" ] + def name(self): """ Return summary """ diff --git a/Framework/PythonInterface/plugins/algorithms/USANSSimulation.py b/Framework/PythonInterface/plugins/algorithms/USANSSimulation.py index b86164900b2..e573c87116c 100644 --- a/Framework/PythonInterface/plugins/algorithms/USANSSimulation.py +++ b/Framework/PythonInterface/plugins/algorithms/USANSSimulation.py @@ -13,6 +13,9 @@ class USANSSimulation(PythonAlgorithm): def category(self): return "SANS" + def seeAlso(self): + return [ "USANSReduction" ] + def name(self): return "USANSSimulation" diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/AddSampleLogMultiple.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/AddSampleLogMultiple.py index d523aabcc4c..b76c01067cb 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/AddSampleLogMultiple.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/AddSampleLogMultiple.py @@ -14,6 +14,9 @@ class AddSampleLogMultiple(PythonAlgorithm): def summary(self): return 'Add multiple sample logs to a workspace' + def seeAlso(self): + return ["AddSampleLog"] + def PyInit(self): self.declareProperty(WorkspaceProperty('Workspace', '', direction=Direction.InOut), doc='Workspace to add logs to') diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CalculateMonteCarloAbsorption.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CalculateMonteCarloAbsorption.py index 00bb6453ebd..2d82b71a8c4 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CalculateMonteCarloAbsorption.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CalculateMonteCarloAbsorption.py @@ -51,6 +51,9 @@ class CalculateMonteCarloAbsorption(DataProcessorAlgorithm): def category(self): return "Workflow\\Inelastic;CorrectionFunctions\\AbsorptionCorrections;Workflow\\MIDAS" + def seeAlso(self): + return [ "MonteCarloAbsorption","SimpleShapeMonteCarloAbsorption" ] + def summary(self): return "Calculates indirect absorption corrections for a given sample shape, using a MonteCarlo simulation." diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ConvertMultipleRunsToSingleCrystalMD.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ConvertMultipleRunsToSingleCrystalMD.py index 16123503e88..bb5a9eb1aae 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ConvertMultipleRunsToSingleCrystalMD.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ConvertMultipleRunsToSingleCrystalMD.py @@ -17,6 +17,9 @@ class ConvertMultipleRunsToSingleCrystalMD(DataProcessorAlgorithm): def category(self): return "MDAlgorithms\\Creation" + def seeAlso(self): + return [ "ConvertToDiffractionMDWorkspace","ConvertToMD" ] + def name(self): return "ConvertMultipleRunsToSingleCrystalMD" diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLApplySelfShielding.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLApplySelfShielding.py index 19fcf7cb2a8..bc330f9f2e2 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLApplySelfShielding.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLApplySelfShielding.py @@ -42,6 +42,9 @@ class DirectILLApplySelfShielding(DataProcessorAlgorithm): """Return the algorithm's category.""" return common.CATEGORIES + def seeAlso(self): + return [ "DirectILLReduction" ] + def name(self): """Return the algorithm's name.""" return 'DirectILLApplySelfShielding' diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectData.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectData.py index afc256c8315..0bf3c901ec5 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectData.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLCollectData.py @@ -247,6 +247,9 @@ class DirectILLCollectData(DataProcessorAlgorithm): """Return the algorithm's category.""" return common.CATEGORIES + def seeAlso(self): + return [ "DirectILLReduction" ] + def name(self): """Return the algorithm's name.""" return 'DirectILLCollectData' diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLDiagnostics.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLDiagnostics.py index bb2a888e849..15482c1bd95 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLDiagnostics.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLDiagnostics.py @@ -309,6 +309,9 @@ class DirectILLDiagnostics(DataProcessorAlgorithm): """Return the algorithm's category.""" return common.CATEGORIES + def seeAlso(self): + return [ "DirectILLReduction" ] + def name(self): """Return the algorithm's name.""" return 'DirectILLDiagnostics' diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLIntegrateVanadium.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLIntegrateVanadium.py index 0d719a89e78..a19138f37f6 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLIntegrateVanadium.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLIntegrateVanadium.py @@ -22,6 +22,9 @@ class DirectILLIntegrateVanadium(DataProcessorAlgorithm): """Return the algorithm's category.""" return common.CATEGORIES + def seeAlso(self): + return [ "DirectILLReduction" ] + def name(self): """Return the algorithm's name.""" return 'DirectILLIntegrateVanadium' diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLReduction.py index 3d4b7bee8fb..55bd25376e7 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLReduction.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLReduction.py @@ -169,6 +169,10 @@ class DirectILLReduction(DataProcessorAlgorithm): """Return the algorithm's category.""" return common.CATEGORIES + def seeAlso(self): + return [ "DirectILLApplySelfShielding","DirectILLCollectData", + "DirectILLDiagnostics","DirectILLIntegrateVanadium","DirectILLSelfShielding" ] + def name(self): """Return the algorithm's name.""" return 'DirectILLReduction' diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLSelfShielding.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLSelfShielding.py index 5c1391a418e..2609db7937b 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLSelfShielding.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/DirectILLSelfShielding.py @@ -21,6 +21,9 @@ class DirectILLSelfShielding(DataProcessorAlgorithm): """Return the algorithm's category.""" return common.CATEGORIES + def seeAlso(self): + return [ "DirectILLReduction" ] + def name(self): """Return the algorithm's name.""" return 'DirectILLSelfShielding' diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ISISIndirectDiffractionReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ISISIndirectDiffractionReduction.py index a80ac5c10bc..86d73568ee1 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ISISIndirectDiffractionReduction.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ISISIndirectDiffractionReduction.py @@ -38,7 +38,10 @@ class ISISIndirectDiffractionReduction(DataProcessorAlgorithm): def summary(self): return 'Performs a diffraction reduction for a set of raw run files for an ISIS indirect spectrometer' - # ------------------------------------------------------------------------------ + def seeAlso(self): + return [ "AlignDetectors","DiffractionFocussing","SNSPowderReduction" ] + + # ------------------------------------------------------------------------------ def PyInit(self): self.declareProperty(StringArrayProperty(name='InputFiles'), diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLEnergyTransfer.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLEnergyTransfer.py index 37f75eb8838..fd2a0953387 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLEnergyTransfer.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLEnergyTransfer.py @@ -53,6 +53,9 @@ class IndirectILLEnergyTransfer(PythonAlgorithm): def summary(self): return 'Performs initial energy transfer reduction for ILL indirect geometry data, instrument IN16B.' + def seeAlso(self): + return [ "IndirectILLReductionQENS","IndirectILLReductionFWS" ] + def name(self): return "IndirectILLEnergyTransfer" diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionFWS.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionFWS.py index 35dbafe5676..7ddec145b25 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionFWS.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionFWS.py @@ -39,6 +39,9 @@ class IndirectILLReductionFWS(PythonAlgorithm): return 'Performs fixed-window scan (FWS) multiple file reduction (both elastic and inelastic) ' \ 'for ILL indirect geometry data, instrument IN16B.' + def seeAlso(self): + return [ "IndirectILLReductionQENS","IndirectILLEnergyTransfer" ] + def name(self): return "IndirectILLReductionFWS" diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionQENS.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionQENS.py index c6120c518af..85b1ab7b4dd 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionQENS.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReductionQENS.py @@ -36,6 +36,9 @@ class IndirectILLReductionQENS(PythonAlgorithm): return 'Performs quasi-elastic neutron scattering (QENS) multiple file reduction ' \ 'for ILL indirect geometry data, instrument IN16B.' + def seeAlso(self): + return [ "IndirectILLReductionFWS","IndirectILLEnergyTransfer" ] + def name(self): return "IndirectILLReductionQENS" diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MDNormSCDPreprocessIncoherent.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MDNormSCDPreprocessIncoherent.py index 5a124804281..1d5cd7025e4 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MDNormSCDPreprocessIncoherent.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MDNormSCDPreprocessIncoherent.py @@ -19,6 +19,9 @@ class MDNormSCDPreprocessIncoherent(DataProcessorAlgorithm): def category(self): return "MDAlgorithms\\Normalisation" + def seeAlso(self): + return [ "MDNormSCD","MDNormDirectSC" ] + def name(self): return "MDNormSCDPreprocessIncoherent" diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/OSIRISDiffractionReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/OSIRISDiffractionReduction.py index 3f49c6af191..dd4614d029f 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/OSIRISDiffractionReduction.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/OSIRISDiffractionReduction.py @@ -480,6 +480,9 @@ class OSIRISDiffractionReduction(PythonAlgorithm): def category(self): return 'Diffraction\\Reduction' + def seeAlso(self): + return [ "ISISIndirectDiffractionReduction" ] + def summary(self): return "This Python algorithm performs the operations necessary for the reduction of diffraction data " + \ "from the Osiris instrument at ISIS " + \ diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetEffCorr.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetEffCorr.py index 40f7d710823..d5444a4bab1 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetEffCorr.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetEffCorr.py @@ -37,6 +37,9 @@ class PowderDiffILLDetEffCorr(PythonAlgorithm): def summary(self): return "Performs detector efficiency correction calculation for powder diffraction instrument D20 at ILL." + def seeAlso(self): + return [ "ApplyDetectorScanEffCorr","PowderDiffILLReduction" ] + def name(self): return "PowderDiffILLDetEffCorr" diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReduction.py index 0fd2620d37e..3f9e6a8b605 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReduction.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLDetScanReduction.py @@ -15,6 +15,9 @@ class PowderDiffILLDetScanReduction(DataProcessorAlgorithm): def summary(self): return 'Performs powder diffraction data reduction for D2B and D20 (when doing a detector scan).' + def seeAlso(self): + return [ "PowderDiffILLReduction" ] + def name(self): return "PowderDiffILLDetScanReduction" diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLReduction.py index 699ec5e52f0..4930d763124 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLReduction.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PowderDiffILLReduction.py @@ -36,6 +36,9 @@ class PowderDiffILLReduction(PythonAlgorithm): def summary(self): return 'Performs powder diffraction data reduction for ILL instrument D20.' + def seeAlso(self): + return [ "PowderDiffILLDetScanReduction","PowderDiffILLDetEffCorr" ] + def name(self): return "PowderDiffILLReduction" diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/REFLReprocess.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/REFLReprocess.py deleted file mode 100644 index 3c0a7cca5f1..00000000000 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/REFLReprocess.py +++ /dev/null @@ -1,229 +0,0 @@ -#pylint: disable=no-init,invalid-name -from __future__ import (absolute_import, division, print_function) - -from mantid.api import * -from mantid.kernel import * -from mantid.simpleapi import * -import os -import math -import sys - -#pylint: disable=too-few-public-methods - - -class REFLOptions(object): - def __init__(self): - from reduction_gui.reduction.reflectometer.refl_data_script import DataSets as REFLDataSets - from reduction_gui.reduction.reflectometer.refl_data_series import DataSeries - self._state = DataSeries(data_class=REFLDataSets) - - def get_state(self): - return self._state - - -class REFLReprocess(PythonAlgorithm): - """ - Normalise detector counts by accelerator current and beam spectrum. - """ - - def category(self): - return "Workflow\\REFL" - - def name(self): - return "REFLReprocess" - - def summary(self): - return "Re-reduce REFL data for an entire experiment using saved parameters" - - def PyInit(self): - self.declareProperty("IPTS", '0', "IPTS number to process") - self.declareProperty(FileProperty(name="OutputDirectory",defaultValue="",action=FileAction.OptionalDirectory)) - self.declareProperty("LoadProcessed", False, "If True, data will be loaded instead of being processed") - self.declareProperty("Filter", "ts.txt", "String that the reduced data file name must contain") - - def PyExec(self): - from reduction_gui.reduction.reflectometer.refl_reduction import REFLReductionScripter - ipts = self.getProperty("IPTS").value - try: - ipts_number = int(ipts) - ipts = "IPTS-%s" % ipts_number - except: - pass - - Logger("REFLReprocess").notice("Processing %s" % ipts) - - # Locate the IPTS directory - ipts_dir = "/SNS/REF_L/%s/shared" % ipts - if not os.path.isdir(ipts_dir): - ipts_dir = ipts - - # Determine the output directory - output_dir = self.getProperty("OutputDirectory").value - if len(output_dir)==0: - output_dir = ipts_dir - - load_only = self.getProperty("LoadProcessed").value - if load_only: - return self.load_processed(output_dir) - - # Reprocess the data - if os.path.isdir(ipts_dir): - for item in os.listdir(ipts_dir): - if item.endswith('.xml'): - try: - Logger("REFLReprocess").notice("Processing %s" % os.path.join(ipts_dir, item)) - - refl = REFLReductionScripter() - options = REFLOptions() - refl.attach(options) - refl.from_xml(os.path.join(ipts_dir, item)) - code = refl.to_script() - exec(code, globals(), locals()) - self.stitch_data(os.path.join(ipts_dir, item), output_dir, - q_min=options.get_state().data_sets[0].q_min, - q_step=options.get_state().data_sets[0].q_step) - except: - Logger("REFLReprocess").error(str(sys.exc_info()[1])) - else: - Logger("REFLReprocess").error("%s not a valid directory" % ipts_dir) - - def load_processed(self, output_dir): - filter_string = self.getProperty("Filter").value - if not os.path.isdir(output_dir): - Logger("REFLReprocess").error("%s not a valid directory" % output_dir) - return - - for item in os.listdir(output_dir): - if item.endswith('.txt') and \ - (len(filter_string)==0 or item.find(filter_string)>=0): - basename, _ = os.path.splitext(item) - Load(Filename=os.path.join(output_dir, item), OutputWorkspace=basename) - (_name,_ts) = basename.split('_#') - CloneWorkspace(InputWorkspace=basename, OutputWorkspace=_name) - - def stitch_data(self, input_file, output_dir, q_min, q_step): - from LargeScaleStructures.data_stitching import DataSet, Stitcher#, RangeSelector - # Identify the data sets to stitch and order them - workspace_list = [] - _list_name = [] - _list_ts = [] - ws_list = AnalysisDataService.getObjectNames() - for item in ws_list: - if item.endswith('ts'): - (_name,_ts) = item.split('_#') - _list_name.append(item) - _list_ts.append(_ts) - - _name_ts = sorted(zip(_list_ts, _list_name)) - _ts_sorted, workspace_list = list(zip(*_name_ts)) - - # Stitch the data - s = Stitcher() - - q_max = 0 - for item in workspace_list: - data = DataSet(item) - data.load(True, True) - dummy_x_min, x_max = data.get_range() - if x_max > q_max: - q_max = x_max - s.append(data) - - s.set_reference(0) - s.compute() - - # Apply the scaling factors - for data in s._data_sets: - Scale(InputWorkspace=str(data), OutputWorkspace=data._ws_scaled, - Operation="Multiply", Factor=data.get_scale()) - SaveAscii(InputWorkspace=str(data), Filename=os.path.join(output_dir, '%s.txt' % str(data))) - - output_file = input_file.replace('.xml', '_reprocessed.txt') - Logger("REFLReprocess").notice("Saving to %s" % output_file) - - output_ws = _average_y_of_same_x_(q_min, q_step, q_max) - SaveAscii(InputWorkspace=output_ws, Filename=output_file) - - -def weightedMean(data_array, error_array): - """ - Code taken out as-is from base_ref_reduction.py - """ - sz = len(data_array) - - # calculate the numerator of mean - dataNum = 0 - for i in range(sz): - if not data_array[i] == 0: - tmpFactor = float(data_array[i]) / float((pow(error_array[i],2))) - dataNum += tmpFactor - - # calculate denominator - dataDen = 0 - for i in range(sz): - if not error_array[i] == 0: - tmpFactor = 1./float((pow(error_array[i],2))) - dataDen += tmpFactor - - if dataDen == 0: - mean = 0 - mean_error = 0 - else: - mean = float(dataNum) / float(dataDen) - mean_error = math.sqrt(1/dataDen) - - return [mean, mean_error] - - -def _average_y_of_same_x_(q_min, q_step, q_max=2): - """ - - Code taken out as-is from base_ref_reduction.py - - 2 y values sharing the same x-axis will be average using - the weighted mean - """ - - ws_list = AnalysisDataService.getObjectNames() - scaled_ws_list = [] - - # Get the list of scaled histos - for ws in ws_list: - if ws.endswith("_scaled"): - scaled_ws_list.append(ws) - - # get binning parameters - #_from_q = str(state.data_sets[0].q_min) - #_bin_size = str(state.data_sets[0].q_step) - #_bin_max = str(2) - #binning_parameters = _from_q + ',-' + _bin_size + ',' + _bin_max - binning_parameters = "%s,-%s,%s" % (q_min, q_step, q_max) - - # Convert each histo to histograms and rebin to final binning - for ws in scaled_ws_list: - new_name = "%s_histo" % ws - ConvertToHistogram(InputWorkspace=ws, OutputWorkspace=new_name) - Rebin(InputWorkspace=new_name, Params=binning_parameters, - OutputWorkspace=new_name) - - # Take the first rebinned histo as our output - data_y = mtd[scaled_ws_list[0]+'_histo'].dataY(0) - data_e = mtd[scaled_ws_list[0]+'_histo'].dataE(0) - - # Add in the other histos, averaging the overlaps - for i in range(1, len(scaled_ws_list)): - data_y_i = mtd[scaled_ws_list[i]+'_histo'].dataY(0) - data_e_i = mtd[scaled_ws_list[i]+'_histo'].dataE(0) - for j in range(len(data_y_i)): - if data_y[j]>0 and data_y_i[j]>0: - [data_y[j], data_e[j]] = weightedMean([data_y[j], data_y_i[j]], [data_e[j], data_e_i[j]]) - elif (data_y[j] == 0) and (data_y_i[j]>0): - data_y[j] = data_y_i[j] - data_e[j] = data_e_i[j] - - return scaled_ws_list[0]+'_histo' - -############################################################################################# - - -AlgorithmFactory.subscribe(REFLReprocess) diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ReactorSANSResolution.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ReactorSANSResolution.py index 8386bd6e2c8..c113cd2419a 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ReactorSANSResolution.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ReactorSANSResolution.py @@ -14,6 +14,9 @@ class ReactorSANSResolution(PythonAlgorithm): def category(self): return "SANS" + def seeAlso(self): + return [ "EQSANSResolution" ] + def name(self): return "ReactorSANSResolution" diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SavePlot1D.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SavePlot1D.py index f1e7aac4740..609eac3ad08 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SavePlot1D.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SavePlot1D.py @@ -24,6 +24,9 @@ class SavePlot1D(mantid.api.PythonAlgorithm): """ return "DataHandling\\Plots" + def seeAlso(self): + return [ "SavePlot1DAsJson","StringToPng" ] + def name(self): """ Algorithm name """ diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SaveVulcanGSS.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SaveVulcanGSS.py index b5b4ff4bd1b..acf57dd74f6 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SaveVulcanGSS.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SaveVulcanGSS.py @@ -20,6 +20,9 @@ class SaveVulcanGSS(PythonAlgorithm): """ return "Workflow\\Diffraction\\DataHandling" + def seeAlso(self): + return [ "SaveGSS" ] + def name(self): """ name of algorithm """ diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SimpleShapeMonteCarloAbsorption.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SimpleShapeMonteCarloAbsorption.py index 2abf5198c05..d3d6ec5964e 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SimpleShapeMonteCarloAbsorption.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SimpleShapeMonteCarloAbsorption.py @@ -39,6 +39,9 @@ class SimpleShapeMonteCarloAbsorption(DataProcessorAlgorithm): def category(self): return 'Workflow\\Inelastic;CorrectionFunctions\\AbsorptionCorrections;Workflow\\MIDAS' + def seeAlso(self): + return [ "CalculateMonteCarloAbsorption","MonteCarloAbsorption" ] + def summary(self): return 'Calculates absorption corrections for a given sample shape.' diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SingleCrystalDiffuseReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SingleCrystalDiffuseReduction.py index c40af07035c..c4862b3d183 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SingleCrystalDiffuseReduction.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SingleCrystalDiffuseReduction.py @@ -25,6 +25,9 @@ class SingleCrystalDiffuseReduction(DataProcessorAlgorithm): def category(self): return "Diffraction\\Reduction" + def seeAlso(self): + return [ "ConvertToMD","MDNormSCD" ] + def name(self): return "SingleCrystalDiffuseReduction" diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py index 441becd9231..9c29136b9a2 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py @@ -60,6 +60,9 @@ class TimeSlice(PythonAlgorithm): def summary(self): return 'Performa an integration on a raw file over a specified time of flight range' + def seeAlso(self): + return [ "Integration" ] + def PyInit(self): self.declareProperty(StringArrayProperty(name='InputFiles'), doc='Comma separated list of input files') diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/USANSReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/USANSReduction.py index 2258416e97f..8c1507ddbdd 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/USANSReduction.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/USANSReduction.py @@ -23,6 +23,9 @@ class USANSReduction(PythonAlgorithm): def category(self): return "SANS" + def seeAlso(self): + return [ "USANSSimulation" ] + def name(self): return "USANSReduction" diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/VesuvioDiffractionReduction.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/VesuvioDiffractionReduction.py index 20bba523daf..833f1460293 100644 --- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/VesuvioDiffractionReduction.py +++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/VesuvioDiffractionReduction.py @@ -25,6 +25,9 @@ class VesuvioDiffractionReduction(DataProcessorAlgorithm): def category(self): return 'Diffraction\\Reduction' + def seeAlso(self): + return [ "ISISIndirectDiffractionReduction" ] + def summary(self): return ('Performs diffraction reduction for VESUVIO. This algorithm is deprecated (April-2017).') diff --git a/Framework/PythonInterface/plugins/algorithms/sfCalculator.py b/Framework/PythonInterface/plugins/algorithms/sfCalculator.py deleted file mode 100644 index 35e94a2784e..00000000000 --- a/Framework/PythonInterface/plugins/algorithms/sfCalculator.py +++ /dev/null @@ -1,1441 +0,0 @@ -#pylint: disable=invalid-name,too-many-arguments,too-many-lines,too-many-instance-attributes, too-many-locals,too-many-branches -from __future__ import (absolute_import, division, print_function) -from mantid.simpleapi import * -import numpy as np -import os.path - -PRECISION = 0.020 - - -class sfCalculator(object): - - ref_date = '2014-10-01' # when the detector has been rotated - - INDEX = 0 - - tof_min = None #microS - tof_max = None #microS - - #range of x pixel to use in the X integration (we found out that there - #is a frame effect that introduces noise) - x_pixel_min = 0 #default is 90 - x_pixel_max = 255 #default is 190 (must be below 256) - - #from,width,to in microS - #rebin_parameters = '0,50,200000' - rebin_parameters = '0,50,100000' - - #turn on or off the plots - bPlot = False - bFittingPlot = False - - #size of detector - alpha_pixel_nbr = 256 - beta_pixel_nbr = 304 #will be integrated over this dimension - - #name of numerators and denominators - numerator = None #ex: AiD0 - denominator = None #ex: AiD1 - - y_axis_numerator = None - y_axis_error_numerator = None - y_axis_denominator = None - y_axis_error_denominator = None - x_axis = None - - #define the peak region - n_peak_pixel_min = 130 - n_peak_pixel_max = 135 - d_peak_pixel_min = 130 - d_peak_pixel_max = 135 - - peak_pixel_min = None - peak_pixel_max = None - back_pixel_min = None - back_pixel_max = None - - #define the background range used in the background subtraction - n_back_pixel_min = 125 - n_back_pixel_max = 140 - d_back_pixel_min = 125 - d_back_pixel_max = 140 - - y_axis_ratio = None - y_axis_error_ratio = None - x_axis_ratio = None - - is_nexus_detector_rotated_flag = True - - a = None - b = None - error_a = None - error_b = None - - def __init__(self, numerator=None, denominator=None, - tof_range=None): - - print('---> initialize calculation') - - if tof_range is None: - self.tof_min = 10000 - self.tof_max = 21600 - else: - self.tof_min = tof_range[0] - self.tof_max = tof_range[1] - - self.numerator = numerator - self.denominator = denominator - - self.x_axis_ratio = None - self.y_axis_error_ratio = None - self.y_axis_ratio = None - - def setNumerator(self, minPeak, maxPeak, minBack, maxBack): - - print('---> set numerator (' + self.numerator + ')') - - if minPeak != 0: - self.n_peak_pixel_min = minPeak - if maxPeak != 0 : - self.n_peak_pixel_max = maxPeak - if minBack != 0: - self.n_back_pixel_min = minBack - if maxBack != 0: - self.n_back_pixel_max = maxBack - - def setDenominator(self, minPeak, maxPeak, minBack, maxBack): - - print('---> set denominator (' + self.denominator + ')') - - if minPeak != 0: - self.d_peak_pixel_min = minPeak - if maxPeak != 0: - self.d_peak_pixel_max = maxPeak - if minBack != 0: - self.d_back_pixel_min = minBack - if maxBack != 0: - self.d_back_pixel_max = maxBack - - def run(self): - """ - Perform the calculation - - """ - - #perform calculation for numerator - self._calculateFinalYAxis(bNumerator=True) - -# #DEBUGGING -# -# #output the data to fit to DEBUG -# x_axis = self.x_axis_ratio -# y_axis = self.y_axis_numerator -# y_error_axis = self.y_axis_error_numerator -# -# print 'create sfOutputTest#' -# filename = "/SNS/users/j35/sfOutputTest#%d.txt" % sfCalculator.INDEX -# # filename = "/home/j35/Desktop/sfOutputTest#%d.txt" % sfCalculator.INDEX -# print filename -# sfCalculator.INDEX += 1 -# -# f=open(filename,'w') -# -# for i in range(len(x_axis)): -# f.write(str(x_axis[i]) + "," + str(y_axis[i]) + "," + str(y_error_axis[i]) + "\n"); -# -# f.close - #END of DEBUGGING - - #perform calculation for denominator - self._calculateFinalYAxis(bNumerator=False) - -# #DEBUGGING -# -# #output the data to fit to DEBUG -# x_axis = self.x_axis_ratio -# y_axis = self.y_axis_denominator -# y_error_axis = self.y_axis_error_denominator -# -# print 'create sfOutputTest#' -# filename = "/SNS/users/j35/sfOutputTest#%d.txt" % sfCalculator.INDEX -# # filename = "/home/j35/Desktop/sfOutputTest#%d.txt" % sfCalculator.INDEX -# print filename -# sfCalculator.INDEX += 1 -# -# f=open(filename,'w') -# -# for i in range(len(x_axis)): -# f.write(str(x_axis[i]) + "," + str(y_axis[i]) + "," + str(y_error_axis[i]) + "\n"); -# -# f.close -# #END of DEBUGGING - - #calculate y_axis of numerator/denominator -# self._x_axis_ratio = self._x_axis - - ## code to replace this - #self.y_axis_ratio = self.y_axis_numerator / self.y_axis_denominator - - sz = np.size(self.y_axis_numerator) - new_y_axis_ratio = np.zeros(sz) - for i in range(sz): - - if self.y_axis_denominator[i] == 0: - self.y_axis_denominator[i] = 1 - -# print i -# print self.y_axis_numerator[i] -# print self.y_axis_denominator[i] -# print - - new_y_axis_ratio[i] = float(self.y_axis_numerator[i]) / float(self.y_axis_denominator[i]) - self.y_axis_ratio = new_y_axis_ratio - - ## code to replace this -# self.y_axis_error_ratio = ((self.y_axis_error_numerator / -# self.y_axis_numerator) ** 2 + -# (self.y_axis_error_denominator / -# self.y_axis_denominator) ** 2) -# self.y_axis_error_ratio = np.sqrt(self.y_axis_error_ratio) -# self.y_axis_error_ratio *= self.y_axis_ratio - new_y_axis_error_ratio = np.zeros(sz) - for i in range(sz): - - if self.y_axis_numerator[i] == 0: - self.y_axis_numerator[i] = 1 - - tmp_value = (float(self.y_axis_error_numerator[i]) / float(self.y_axis_numerator[i])) **2 + \ - (float(self.y_axis_error_denominator[i]) / float(self.y_axis_denominator[i])) **2 - tmp_value = np.sqrt(tmp_value) - new_y_axis_error_ratio[i] = self.y_axis_ratio[i]* tmp_value - self.y_axis_error_ratio = new_y_axis_error_ratio - - def isNexusTakeAfterRefDate(self, nexus_date): - ''' - This function parses the output.date and returns true if this date is after the ref date - ''' - nexus_date_acquisition = nexus_date.split('T')[0] - - if nexus_date_acquisition > self.ref_date: - return True - else: - return False - - def _calculateFinalYAxis(self, bNumerator=True): - """ - run full calculation for numerator or denominator - """ - if bNumerator is True: - filen = self.numerator -# _id = self.id_numerator - self.peak_pixel_min = self.n_peak_pixel_min - self.peak_pixel_max = self.n_peak_pixel_max - self.back_pixel_min = self.n_back_pixel_min - self.back_pixel_max = self.n_back_pixel_max - else: - filen = self.denominator -# _id = self.id_denominator - self.peak_pixel_min = self.d_peak_pixel_min - self.peak_pixel_max = self.d_peak_pixel_max - self.back_pixel_min = self.d_back_pixel_min - self.back_pixel_max = self.d_back_pixel_max - - nexus_file_numerator = filen - print('----> loading nexus file: ' + nexus_file_numerator) - EventDataWks = LoadEventNexus(Filename=nexus_file_numerator) - - self.is_nexus_detector_rotated_flag = self.isNexusTakeAfterRefDate(EventDataWks.getRun().getProperty('run_start').value) - - if self.is_nexus_detector_rotated_flag: - self.alpha_pixel_nbr = 304 - self.beta_pixel_nbr = 256 - else: - self.alpha_pixel_nbr = 256 - self.beta_pixel_nbr = 304 #will be integrated over this dimension - - proton_charge = self._getProtonCharge(EventDataWks) - print('----> rebinning ') - HistoDataWks = Rebin(InputWorkspace=EventDataWks, - Params=self.rebin_parameters) - -# mt2 = mtd['HistoDataWks'] -# x_axis = mt2.readX(0)[:] - - x_axis = HistoDataWks.readX(0)[:] - self.x_axis = x_axis - - OutputWorkspace = self._createIntegratedWorkspace(InputWorkspace=HistoDataWks, - proton_charge=proton_charge, - from_pixel=self.peak_pixel_min, - to_pixel=self.peak_pixel_max) - - DataWks = self._removeBackground(InputWorkspace=OutputWorkspace, - from_peak=self.peak_pixel_min, - to_peak=self.peak_pixel_max, - from_back=self.back_pixel_min, - to_back=self.back_pixel_max, - tof_min = self.tof_min, - tof_max = self.tof_max) - -# print '----> Convert to histogram' -# IntegratedDataWks = ConvertToHistogram(InputWorkspace=OutputWorkspace) -# -# print '----> Transpose' -# TransposeIntegratedDataWks = Transpose(InputWorkspace=IntegratedDataWks) -# -# print '----> convert to histogram' -# TransposeIntegratedDataWks_t = ConvertToHistogram(InputWorkspace=TransposeIntegratedDataWks) -# -# print '----> flat background1' -# TransposeHistoFlatDataWks_1 = FlatBackground(InputWorkspace=TransposeIntegratedDataWks_t, -# StartX=self.back_pixel_min, -# EndX=self.peak_pixel_min, -# Mode='Mean', -# OutputMode="Return Background") -# -# print '----> flat background2' -# TransposeHistoFlatDataWks_2 = FlatBackground(InputWorkspace=TransposeIntegratedDataWks_t, -# StartX=self.peak_pixel_max, -# EndX=self.back_pixel_max, -# Mode='Mean', -# OutputMode="Return Background") -# -# print '----> transpose flat background 1 -> data1' -# DataWks_1 = Transpose(InputWorkspace=TransposeHistoFlatDataWks_1); -# -# print '----> transpose flat background 2 -> data2' -# DataWks_2 = Transpose(InputWorkspace=TransposeHistoFlatDataWks_2); -# -# print '----> convert to histogram data2' -# DataWks_1 = ConvertToHistogram(InputWorkspace=DataWks_1); -# -# print '----> convert to histogram data1' -# DataWks_2 = ConvertToHistogram(InputWorkspace=DataWks_2) -# -# print '----> rebin workspace data1' -# DataWks_1 = RebinToWorkspace(WorkspaceToRebin=DataWks_1, -# WorkspacetoMatch=IntegratedDataWks) -# -# print '----> rebin workspace data2' -# DataWks_2 = RebinToWorkspace(WorkspaceToRebin=DataWks_2, -# WorkspacetoMatch=IntegratedDataWks) -# -# print '----> weighted mean' -# DataWksWeightedMean = WeightedMean(InputWorkspace1=DataWks_1, -# InputWorkspace2=DataWks_2) -# -# print '----> minus' -# DataWks = Minus(LHSWorkspace=IntegratedDataWks, -# RHSWorkspace=DataWksWeightedMean) - -# if not bNumerator: -# import sys -# sys.exit("now we are working with denominator") - - -# mt3 = mtd['DataWks'] - self._calculateFinalAxis(Workspace=DataWks, - bNumerator=bNumerator) - print('done with _calculateFinalAxis and back in calculatefinalaxis') #REMOVEME - - #cleanup workspaces - DeleteWorkspace(EventDataWks) - DeleteWorkspace(HistoDataWks) -# DeleteWorkspace(IntegratedDataWks) -# DeleteWorkspace(TransposeIntegratedDataWks) -# DeleteWorkspace(TransposeIntegratedDataWks_t) -# DeleteWorkspace(TransposeHistoFlatDataWks_1) -# DeleteWorkspace(TransposeHistoFlatDataWks_2) - DeleteWorkspace(DataWks) - - print('done with cleaning workspaces in line 247') - - def _calculateFinalAxis(self, Workspace=None, bNumerator=None): - """ - this calculates the final y_axis and y_axis_error of numerator - and denominator - """ - - print('----> calculate final axis') - mt = Workspace - x_axis = mt.readX(0)[:] - self.x_axis = x_axis - - counts_vs_tof = mt.readY(0)[:] - counts_vs_tof_error = mt.readE(0)[:] - -## this is not use anymore as the integration is done in the previous step -# counts_vs_tof = np.zeros(len(x_axis)-1) -# counts_vs_tof_error = np.zeros(len(x_axis)-1) -# -# for x in range(self.alpha_pixel_nbr): -# counts_vs_tof += mt.readY(x)[:] -# counts_vs_tof_error += mt.readE(x)[:] ** 2 -# counts_vs_tof_error = np.sqrt(counts_vs_tof_error) - -# -# #for DEBUGGING -# #output data into ascii file -# f=open('/home/j35/Desktop/myASCII.txt','w') -# if (not bNumerator): -# f.write(self.denominator + "\n") -# -# for i in range(len(counts_vs_tof)): -# f.write(str(x_axis[i]) + "," + str(counts_vs_tof[i]) + "\n") -# f.close -# import sys -# sys.exit("Stop in _calculateFinalAxis") -## end of for DEBUGGING #so far, so good ! - - index_tof_min = self._getIndex(self.tof_min, x_axis) - index_tof_max = self._getIndex(self.tof_max, x_axis) - - if bNumerator is True: - self.y_axis_numerator = counts_vs_tof[index_tof_min:index_tof_max].copy() - self.y_axis_error_numerator = counts_vs_tof_error[index_tof_min:index_tof_max].copy() - self.x_axis_ratio = self.x_axis[index_tof_min:index_tof_max].copy() - else: - self.y_axis_denominator = counts_vs_tof[index_tof_min:index_tof_max].copy() - self.y_axis_error_denominator = counts_vs_tof_error[index_tof_min:index_tof_max].copy() - self.x_axis_ratio = self.x_axis[index_tof_min:index_tof_max].copy() - - print('done with _calculateFinalAxis') - - def _createIntegratedWorkspace(self, - InputWorkspace=None, - OutputWorkspace=None, - proton_charge=None, - from_pixel=0, - to_pixel=255): - """ - This creates the integrated workspace over the second pixel range - (beta_pixel_nbr here) and - returns the new workspace handle - """ - - print('-----> Create Integrated workspace ') - x_axis = InputWorkspace.readX(0)[:] - x_size = to_pixel - from_pixel + 1 - y_axis = np.zeros((self.alpha_pixel_nbr, len(x_axis) - 1)) - y_error_axis = np.zeros((self.alpha_pixel_nbr, len(x_axis) - 1)) - y_range = np.arange(x_size) + from_pixel - -# for x in range(self.beta_pixel_nbr): -# for y in y_range: -# index = int(self.alpha_pixel_nbr * x + y) -## y_axis[y, :] += InputWorkspace.readY(index)[:] -# y_axis[y, :] += InputWorkspace.readY(index)[:] -# y_error_axis[y, :] += ((InputWorkspace.readE(index)[:]) * -# (InputWorkspace.readE(index)[:])) - - if self.is_nexus_detector_rotated_flag: - for x in range(256): - for y in y_range: - index = int(y+x*304) - # y_axis[y, :] += InputWorkspace.readY(index)[:] - y_axis[y, :] += InputWorkspace.readY(index)[:] - y_error_axis[y, :] += ((InputWorkspace.readE(index)[:]) * - (InputWorkspace.readE(index)[:])) - - else: - for x in range(304): - for y in y_range: - index = int(y+x*256) - # y_axis[y, :] += InputWorkspace.readY(index)[:] - y_axis[y, :] += InputWorkspace.readY(index)[:] - y_error_axis[y, :] += ((InputWorkspace.readE(index)[:]) * - (InputWorkspace.readE(index)[:])) - -# #DEBUG -# f=open('/home/j35/myASCIIfromCode.txt','w') -# new_y_axis = np.zeros((len(x_axis)-1)) -# -# for y in range(256): -# new_y_axis += y_axis[y,:] -# -# for i in range(len(x_axis)-1): -# f.write(str(x_axis[i]) + "," + str(new_y_axis[i]) + "\n"); -# f.close -# -# print sum(new_y_axis) -# -# #END OF DEBUG - ## so far, worsk perfectly (tested with portal vs Mantid vs Matlab - - y_axis = y_axis.flatten() - y_error_axis = np.sqrt(y_error_axis) - #plot_y_error_axis = _y_error_axis #for output testing only - #plt.imshow(plot_y_error_axis, aspect='auto', origin='lower') - y_error_axis = y_error_axis.flatten() - - #normalization by proton beam - y_axis /= (proton_charge * 1e-12) - y_error_axis /= (proton_charge * 1e-12) - - OutputWorkspace = CreateWorkspace(DataX=x_axis, - DataY=y_axis, - DataE=y_error_axis, - Nspec=self.alpha_pixel_nbr) - - return OutputWorkspace - - def weighted_mean(self, data, error): - - sz = len(data) - - #calculate numerator - dataNum = 0 - for i in range(sz): - if data[i] != 0: - tmpFactor = float(data[i]) / (error[i]**2) - dataNum += tmpFactor - - #calculate denominator - dataDen = 0 - for i in range(sz): - if error[i] != 0: - tmpFactor = float(1) / (error[i]**2) - dataDen += tmpFactor - - if dataDen == 0: - dataDen = 1 - - mean = dataNum / dataDen - mean_error = np.sqrt(dataDen) - - return (mean, mean_error) - - def removeValueFromArray(self, data, background): - # Will remove the background value from each of the data - # element (data is an array) - - sz = len(data) - new_data = np.zeros(sz) - for i in range(sz): - new_data[i] = data[i] - background - - return new_data - - def removeValueFromArrayError(self, data_error, background_error): - # will calculate the new array of error when removing - # a single value from an array - - sz = len(data_error) - new_data_error = np.zeros(sz) - for i in range(sz): - new_data_error[i] = np.sqrt(data_error[i]**2 + background_error**2) - - return new_data_error - - def sumWithError(self, peak, peak_error): - # add the array element using their weight and return new error as well - - sz = len(peak) - sum_peak = 0 - sum_peak_error = 0 - for i in range(sz): - sum_peak += peak[i] - sum_peak_error += peak_error[i]**2 - - sum_peak_error = np.sqrt(sum_peak_error) - return [sum_peak, sum_peak_error] - - #pylint: disable=unused-argument - def _removeBackground(self, - InputWorkspace=None, - from_peak= 0, - to_peak=256, - from_back=0, - to_back=256, - tof_min = 0, - tof_max = 200000): - - # retrieve various axis - tof_axis = InputWorkspace.readX(0)[:] - nbr_tof = len(tof_axis)-1 - - # make big array of data - if self.is_nexus_detector_rotated_flag: - data = np.zeros((304,nbr_tof)) - error = np.zeros((304,nbr_tof)) - for x in range(304): - data[x,:] = InputWorkspace.readY(x)[:] - error[x,:] = InputWorkspace.readE(x)[:] - - else: - data = np.zeros((256,nbr_tof)) - error = np.zeros((256,nbr_tof)) - for x in range(256): - data[x,:] = InputWorkspace.readY(x)[:] - error[x,:] = InputWorkspace.readE(x)[:] - - peak_array = np.zeros(nbr_tof) - peak_array_error = np.zeros(nbr_tof) - - bMinBack = False - bMaxBack = False - - min_back = 0 - min_back_error = 0 - max_back = 0 - max_back_error = 0 - - for t in range(nbr_tof-1): - - _y_slice = data[:,t] - _y_error_slice = error[:,t] - - _y_slice = _y_slice.flatten() - _y_error_slice = _y_error_slice.flatten() - - if from_back < (from_peak-1): - range_back_min = _y_slice[from_back : from_peak] - range_back_error_min = _y_error_slice[from_back : from_peak] - [min_back, min_back_error] = self.weighted_mean(range_back_min, range_back_error_min) - bMinBack = True - - if (to_peak+1) < to_back: - range_back_max = _y_slice[to_peak+1: to_back+1] - range_back_error_max = _y_error_slice[to_peak+1: to_back+1] - [max_back, max_back_error] = self.weighted_mean(range_back_max, range_back_error_max) - bMaxBack = True - - # if we have a min and max background - if bMinBack & bMaxBack: - [background, background_error] = self.weighted_mean([min_back,max_back],[min_back_error,max_back_error]) -# - # if we don't have a max background, we use min background - if not bMaxBack: - background = min_back - background_error = min_back_error -# - # if we don't have a min background, we use max background - if not bMinBack: - background = max_back - background_error = max_back_error - - tmp_peak = _y_slice[from_peak:to_peak+1] - tmp_peak_error = _y_error_slice[from_peak:to_peak+1] - - new_tmp_peak = self.removeValueFromArray(tmp_peak, background) - new_tmp_peak_error = self.removeValueFromArrayError(tmp_peak_error, background_error) - - [final_value, final_error] = self.sumWithError(new_tmp_peak, new_tmp_peak_error) - - peak_array[t] = final_value - peak_array_error[t] = final_error - - # make new workspace - y_axis = peak_array.flatten() - y_error_axis = peak_array_error.flatten() - - DataWks = CreateWorkspace(DataX=tof_axis[0:-1], - DataY=y_axis, - DataE=y_error_axis, - Nspec=1) - -# import sys -# sys.exit("in _removeBackground... so far, so good!") - - return DataWks - - def _getIndex(self, value, array): - """ - returns the index where the value has been found - """ - return array.searchsorted(value) - - def _getProtonCharge(self, st=None): - """ - Returns the proton charge of the given workspace in picoCoulomb - """ - if st is not None: - mt_run = st.getRun() - proton_charge_mtd_unit = mt_run.getProperty('gd_prtn_chrg').value - proton_charge = proton_charge_mtd_unit / 2.77777778e-10 - return proton_charge - return None - - def __mul__(self, other): - """ - operator * between two instances of the class - """ - - product = sfCalculator() - - product.numerator = self.numerator + '*' + other.numerator - product.denominator = self.denominator + '*' + other.denominator - - product.x_axis_ratio = self.x_axis_ratio - - ## replace code by - #product.y_axis_ratio = self.y_axis_ratio * other.y_axis_ratio - sz = len(self.y_axis_ratio) - new_y_axis_ratio = np.zeros(sz) - for i in range(sz): - new_y_axis_ratio[i] = self.y_axis_ratio[i] * other.y_axis_ratio[i] - product.y_axis_ratio = new_y_axis_ratio - - ## replace code by - #product.y_axis_error_ratio = product.y_axis_ratio * np.sqrt((other.y_axis_error_ratio / other.y_axis_ratio)**2 +\ - # (self.y_axis_error_ratio / self.y_axis_ratio)**2) - new_y_axis_error_ratio = np.zeros(sz) - for i in range(sz): - - # make sure we don't divide b 0 - if other.y_axis_ratio[i] == 0: - other.y_axis_ratio[i] = 1 - if self.y_axis_ratio[i] == 0: - self.y_axis_ratio[i] = 1 - - tmp_product = (other.y_axis_error_ratio[i] / other.y_axis_ratio[i]) ** 2 + \ - (self.y_axis_error_ratio[i] / self.y_axis_ratio[i]) ** 2 - tmp_product = np.sqrt(tmp_product) - new_y_axis_error_ratio[i] = tmp_product * product.y_axis_ratio[i] - product.y_axis_error_ratio = new_y_axis_error_ratio - - return product - - def fit(self): - """ - This is going to fit the counts_vs_tof with a linear expression and return the a and - b coefficients (y=a+bx) - """ - - DataToFit = CreateWorkspace(DataX=self.x_axis_ratio, - DataY=self.y_axis_ratio, - DataE=self.y_axis_error_ratio, - Nspec=1) - - print('replaceSpecialValues') - DataToFit = ReplaceSpecialValues(InputWorkspace=DataToFit, - NaNValue=0, - NaNError=0, - InfinityValue=0, - InfinityError=0) - -# ResetNegatives(InputWorkspace='DataToFit', -# OutputWorkspace='DataToFit', -# AddMinimum=0) - -# #DEBUG -# #output the data to fit to DEBUG -# x_axis = DataToFit.readX(0)[:] -# y_axis = DataToFit.readY(0)[:] -# y_error_axis = DataToFit.readE(0)[:] -# -# print 'create sfOutputTest#' -# filename = "/home/j35/sfOutputTest#%d.txt" % sfCalculator.INDEX -# print filename -# sfCalculator.INDEX += 1 -# -# f=open(filename,'w') -# -# for i in range(len(x_axis)): -# f.write(str(x_axis[i]) + "," + str(y_axis[i]) + "," + str(y_error_axis[i]) + "\n"); -# -# f.close -# #END OF DEBUG - - try: - - Fit(InputWorkspace=DataToFit, - Function="name=UserFunction, Formula=a+b*x, a=1, b=2", - Output='res') - - except: - - xaxis = self.x_axis_ratio - sz = len(xaxis) - xmin = xaxis[0] - xmax = xaxis[sz/2] - - DataToFit = CropWorkspace(InputWorkspace=DataToFit, - XMin=xmin, - XMax=xmax) - - Fit(InputWorkspace=DataToFit, - Function='name=UserFunction, Formula=a+b*x, a=1, b=2', - Output='res') - - res = mtd['res_Parameters'] - - self.a = res.cell(0,1) - self.b = res.cell(1,1) - self.error_a = res.cell(0,2) - self.error_b = res.cell(1,2) - -# self.a = res.getDouble("Value", 0) -# self.b = res.getDouble("Value", 1) -# self.error_a = res.getDouble("Error", 0) -# self.error_b = res.getDouble("Error", 1) - - -def plotObject(instance): - -# return - -# print 'a: ' + str(instance.a[-1]) -# print 'b: ' + str(instance.b[-1]) - - figure() - errorbar(instance.x_axis_ratio, - instance.y_axis_ratio, - instance.y_axis_error_ratio, - marker='s', - mfc='red', - linestyle='', - label='Exp. data') - - if instance.a is not None: - x = linspace(10000, 22000, 100) - _label = "%.3f + x*%.2e" % (instance.a, instance.b) - plot(x, instance.a + instance.b * x, label=_label) - - xlabel("TOF (microsS)") - ylabel("Ratio") - - title(instance.numerator + '/' + instance.denominator) - show() - legend() - - -def recordSettings(a, b, error_a, error_b, name, instance): - """ - This function will record the various fitting parameters and the - name of the ratio - """ - print('--> recoding settings') - a.append(instance.a) - b.append(instance.b) - error_a.append(instance.error_a) - error_b.append(instance.error_b) - name.append(instance.numerator + '/' + instance.denominator) - - -def variable_value_splitter(variable_value): - """ - This function split the variable that looks like "LambdaRequested:3.75" - and returns a dictionnary of the variable name and value - """ - - _split = variable_value.split('=') - variable = _split[0] - value = _split[1] - return {'variable':variable, 'value':value} - - -def isWithinRange(value1, value2): - """ - This function checks if the two values and return true if their - difference is <= PRECISION - """ - diff = abs(float(value1)) - abs(float(value2)) - if abs(diff) <= PRECISION: - return True - else: - return False - - -def outputFittingParameters(a, b, error_a, error_b, - lambda_requested, - incident_medium, - S1H, S2H, - S1W, S2W, - output_file_name): - """ - Create an ascii file of the various fittings parameters - y=a+bx - 1st column: incident medium - 2nd column: lambda requested - 3rd column: S1H value - 4th column: S2H value - 5th column: S1W value - 6th column: S2W value - 7th column: a - 7th column: b - 8th column: error_a - 9th column: error_b - """ - - print('--> output fitting parameters') - - bFileExist = False - #First we need to check if the file already exist - if os.path.isfile(output_file_name): - bFileExist = True - - #then if it does, parse the file and check if following infos are - #already defined: - # lambda_requested, S1H, S2H, S1W, S2W - if bFileExist: - f = open(output_file_name, 'r') - text = f.readlines() -# split_lines = text.split('\n') - split_lines = text - - entry_list_to_add = [] - - try: - - sz = len(a) - for i in range(sz): - - _match = False - - for _line in split_lines: - if _line[0] == '#': - continue - - _line_split = _line.split(' ') - _incident_medium = variable_value_splitter(_line_split[0]) - - if _incident_medium['value'].strip() == incident_medium.strip(): - _lambdaRequested = variable_value_splitter(_line_split[1]) - if isWithinRange(_lambdaRequested['value'], lambda_requested): - _s1h = variable_value_splitter(_line_split[2]) - if isWithinRange(_s1h['value'], S1H[i]): - _s2h = variable_value_splitter(_line_split[3]) - if isWithinRange(_s2h['value'],S2H[i]): - _s1w = variable_value_splitter(_line_split[4]) - if isWithinRange(_s1w['value'],S1W[i]): - _s2w = variable_value_splitter(_line_split[5]) - if isWithinRange(_s2w['value'],S2W[i]): - _match = True - break - - if not _match: - entry_list_to_add.append(i) - - except: - #replace file because this one has the wrong format - _content = ['#y=a+bx\n', '#\n', - '#lambdaRequested[Angstroms] S1H[mm] (S2/Si)H[mm] S1W[mm] (S2/Si)W[mm] a b error_a error_b\n', '#\n'] - sz = len(a) - for i in range(sz): - - _line = 'IncidentMedium=' + incident_medium.strip() + ' ' - _line += 'LambdaRequested=' + str(lambda_requested) + ' ' - - _S1H = "{0:.2f}".format(abs(S1H[i])) - _S2H = "{0:.2f}".format(abs(S2H[i])) - _S1W = "{0:.2f}".format(abs(S1W[i])) - _S2W = "{0:.2f}".format(abs(S2W[i])) - _a = "{0:}".format(a[i]) - _b = "{0:}".format(b[i]) - _error_a = "{0:}".format(float(error_a[i])) - _error_b = "{0:}".format(float(error_b[i])) - - _line += 'S1H=' + _S1H + ' ' + 'S2H=' + _S2H + ' ' - _line += 'S1W=' + _S1W + ' ' + 'S2W=' + _S2W + ' ' - _line += 'a=' + _a + ' ' - _line += 'b=' + _b + ' ' - _line += 'error_a=' + _error_a + ' ' - _line += 'error_b=' + _error_b + '\n' - _content.append(_line) - - f = open(output_file_name, 'w') - f.writelines(_content) - f.close() - return - - _content = [] - for j in entry_list_to_add: - - _line = 'IncidentMedium=' + incident_medium + ' ' - _line += 'LambdaRequested=' + str(lambda_requested) + ' ' - - _S1H = "{0:.2f}".format(abs(S1H[j])) - _S2H = "{0:.2f}".format(abs(S2H[j])) - _S1W = "{0:.2f}".format(abs(S1W[j])) - _S2W = "{0:.2f}".format(abs(S2W[j])) - _a = "{0:}".format(a[j]) - _b = "{0:}".format(b[j]) - _error_a = "{0:}".format(float(error_a[j])) - _error_b = "{0:}".format(float(error_b[j])) - - _line += 'S1H=' + _S1H + ' ' + 'S2iH=' + _S2H + ' ' - _line += 'S1W=' + _S1W + ' ' + 'S2iW=' + _S2W + ' ' - _line += 'a=' + _a + ' ' - _line += 'b=' + _b + ' ' - _line += 'error_a=' + _error_a + ' ' - _line += 'error_b=' + _error_b + '\n' - _content.append(_line) - - f = open(output_file_name, 'a') - f.writelines(_content) - f.close() - - else: - - _content = ['#y=a+bx\n', '#\n', - '#lambdaRequested[Angstroms] S1H[mm] (S2/Si)H[mm] S1W[mm] (S2/Si)W[mm] a b error_a error_b\n', '#\n'] - sz = len(a) - for i in range(sz): - - _line = 'IncidentMedium=' + incident_medium.strip() + ' ' - _line += 'LambdaRequested=' + str(lambda_requested) + ' ' - - _S1H = "{0:.2f}".format(abs(S1H[i])) - _S2H = "{0:.2f}".format(abs(S2H[i])) - _S1W = "{0:.2f}".format(abs(S1W[i])) - _S2W = "{0:.2f}".format(abs(S2W[i])) - _a = "{0:}".format(a[i]) - _b = "{0:}".format(b[i]) - _error_a = "{0:}".format(float(error_a[i])) - _error_b = "{0:}".format(float(error_b[i])) - - _line += 'S1H=' + _S1H + ' ' + 'S2iH=' + _S2H + ' ' - _line += 'S1W=' + _S1W + ' ' + 'S2iW=' + _S2W + ' ' - _line += 'a=' + _a + ' ' - _line += 'b=' + _b + ' ' - _line += 'error_a=' + _error_a + ' ' - _line += 'error_b=' + _error_b + '\n' - _content.append(_line) - - f = open(output_file_name, 'w') - f.writelines(_content) - f.close() - - -def createIndividualList(string_list_files): - """ - Using the list_files, will produce a dictionary of the run - number and number of attenuator - ex: - list_files = "1000:0, 1001:1, 1002:1, 1003:2" - return {1000:0, 1001:1, 1002:2, 1003:2} - """ - if string_list_files == '': - return None - first_split = string_list_files.split(',') - - list_runs = [] - list_attenuator= [] - - _nbr_files = len(first_split) - for i in range(_nbr_files): - _second_split = first_split[i].split(':') - list_runs.append(_second_split[0].strip()) - list_attenuator.append(int(_second_split[1].strip())) - - return {'list_runs':list_runs, - 'list_attenuator':list_attenuator} - - -def getLambdaValue(mt): - """ - return the lambdaRequest value - """ - mt_run = mt.getRun() - _lambda = mt_run.getProperty('LambdaRequest').value - return _lambda - - -def getSh(mt, top_tag, bottom_tag): - """ - returns the height and units of the given slits - """ - mt_run = mt.getRun() - st = mt_run.getProperty(top_tag).value - sb = mt_run.getProperty(bottom_tag).value - sh = float(sb[0]) - float(st[0]) - units = mt_run.getProperty(top_tag).units - return sh, units - - -def getSheight(mt, index): - """ - return the DAS hardware slits height of slits # index - """ - mt_run = mt.getRun() - if index == '2': - try: - tag = 'SiVHeight' - value = mt_run.getProperty(tag).value - except: - tag = 'S2VHeight' - value = mt_run.getProperty(tag).value - else: - tag = 'S1VHeight' - value = mt_run.getProperty(tag).value - - return value[0] - - -def getS1h(mt=None): - """ - returns the height and units of the slit #1 - """ - if mt is not None: -# _h, units = getSh(mt, 's1t', 's1b') - _h = getSheight(mt, '1') - return _h - return None - - -def getS2h(mt=None): - """ - returns the height and units of the slit #2 - """ - if mt is not None: -# _h, units = getSh(mt, 's2t', 's2b') - _h = getSheight(mt, '2') - return _h - return None - - -def getSwidth(mt, index): - """ - returns the width and units of the given index slits - defined by the DAS hardware - """ - mt_run = mt.getRun() - if index == '2': - try: - tag = 'SiHWidth' - value = mt_run.getProperty(tag).value - except: - tag = 'S2HWidth' - value = mt_run.getProperty(tag).value - else: - tag = 'S1HWidth' - value = mt_run.getProperty(tag).value - return value[0] - - -def getSw(mt, left_tag, right_tag): - """ - returns the width and units of the given slits - """ - mt_run = mt.getRun() - sl = mt_run.getProperty(left_tag).value - sr = mt_run.getProperty(right_tag).value - sw = float(sl[0]) - float(sr[0]) - units = mt_run.getProperty(left_tag).units - return sw, units - - -def getS1w(mt=None): - """ - returns the width and units of the slit #1 - """ - if mt is not None: -# _w, units = getSw(mt, 's1l', 's1r') - _w = getSwidth(mt, '1') - return _w - return None - - -def getS2w(mt=None): - """ - returns the width and units of the slit #2 - """ - if mt is not None: -# _w, units = getSh(mt, 's2l', 's2r') - _w = getSwidth(mt, '2') - return _w - return None - - -def getSlitsValueAndLambda(full_list_runs, - S1H, S2H, - S1W, S2W, lambdaRequest): - """ - Retrieve the S1H (slit 1 height), - S2H (slit 2 height), - S1W (slit 1 width), - S2W (slit 2 width) and - lambda requested values - """ - _nbr_files = len(full_list_runs) - print('> Retrieving Slits and Lambda Requested for each file:') - for i in range(_nbr_files): - _full_file_name = full_list_runs[i] - print('-> ' + _full_file_name) - tmpWks = LoadEventNexus(Filename=_full_file_name, - MetaDataOnly='1') -# mt1 = mtd['tmpWks'] - _s1h_value = getS1h(tmpWks) - _s2h_value = getS2h(tmpWks) - S1H[i] = _s1h_value - S2H[i] = _s2h_value - - _s1w_value = getS1w(tmpWks) - _s2w_value = getS2w(tmpWks) - S1W[i] = _s1w_value - S2W[i] = _s2w_value - - _lambda_value = getLambdaValue(tmpWks) - lambdaRequest[i] = _lambda_value - - -def isRunsSorted(dummy_list_runs, S1H, S2H): - """ - Make sure the files have been sorted - """ - sz = len(S1H) - sTotal = np.zeros(sz) - for i in range(sz): - sTotal[i] = S1H[i] + S2H[i] - - sorted_sTotal = sorted(sTotal) - - for i in range(len(sTotal)): - _left = list(sTotal)[i] - _right = sorted_sTotal[i] - - _left_formated = "%2.1f" % _left - _right_formated = "%2.1f" % _right - if _left_formated != _right_formated: - return False - - return True - - -def calculateAndFit(numerator='', - denominator='', - list_peak_back_numerator=None, - list_peak_back_denominator=None, - list_objects=None, - tof_range=None): - if list_objects is None: - list_objects=[] - print('--> running calculate and fit algorithm') - - cal1 = sfCalculator(numerator=numerator, - denominator=denominator, - tof_range=tof_range) - - cal1.setNumerator(minPeak=list_peak_back_numerator[0], - maxPeak=list_peak_back_numerator[1], - minBack=list_peak_back_numerator[2], - maxBack=list_peak_back_numerator[3]) - - cal1.setDenominator(minPeak=list_peak_back_denominator[0], - maxPeak=list_peak_back_denominator[1], - minBack=list_peak_back_denominator[2], - maxBack=list_peak_back_denominator[3]) - - cal1.run() - print('Done with cal1.run()') - - if list_objects != [] and list_objects[-1] is not None: - new_cal1 = cal1 * list_objects[-1] - new_cal1.fit() - return new_cal1 - else: - cal1.fit() - return cal1 - - -def showhelp(): - """ - Here the user will have information about how the command line - works - """ - print('sfCalculator help:') - print() - print('example:') - print(' > sfCalculator.calculate(string_runs="55889:0, 55890:1, 55891:1, 55892:2",') - print(' list_') - -#if __name__ == '__main__': - - -def calculate(string_runs=None,\ - # list_attenuator=None, - list_peak_back=None, - incident_medium=None, - output_file_name=None, - tof_range=None): - """ - In this current version, the program will automatically calculates - the scaling function for up to, and included, 6 attenuators. - A output file will then be produced with the following format: - S1H S2H a b error_a error_b - .... - where y=a+bx - x axis is in microS - - The string runs has to be specified this way: - string_runs = "run#1:nbr_attenuator, run#2:nbr_attenuator...." - - the list_peak_back is specified this way: - list_peak_back = - [[peak_min_run1, peak_max_run1, back_min_run1, back_max_run1], - [peak_min_run2, peak_max_run2, back_min_run2, back_max_run2], - [...]] - - output_path = where the scaling factor files will be written - tof_range - - """ - - list_attenuator = None - - #use default string files if not provided - if string_runs is None: - #Input from user -# list_runs = ['55889', '55890', '55891', '55892', '55893', '55894', -# '55895', '55896', '55897', '55898', '55899', '55900', -# '55901', '55902'] - list_runs = ['55889', '55890', '55891', '55892', '55893', '55894'] - nexus_path = '/mnt/hgfs/j35/results/' - pre = 'REF_L_' - nexus_path_pre = nexus_path + pre - post = '_event.nxs' - - for (offset, item) in enumerate(list_runs): - list_runs[offset] = nexus_path_pre + item + post - - else: - dico = createIndividualList(string_runs) - list_runs = dico['list_runs'] - - for (offset, item) in enumerate(list_runs): - try: - _File = FileFinder.findRuns("REF_L%d" %int(item))[0] - list_runs[offset] = _File - except RuntimeError: - msg = "RefLReduction: could not find run %s\n" %item - msg += "Add your data folder to your User Data Directories in the File menu" - raise RuntimeError(msg) - - list_attenuator = dico['list_attenuator'] - - if incident_medium is None: - incident_medium = "H20" #default value - - if list_attenuator is None: -# list_attenuator = [0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4] - list_attenuator = [0, 1, 1, 1, 1, 1] - - if list_peak_back is None: - list_peak_back = np.zeros((len(list_runs), 4)) #[peak_min, peak_max, back_min, back_max] -# list_peak_back[9, ] = [128, 136, 120, 145] -# list_peak_back[11, ] = [125, 140, 115, 150] -# list_peak_back[10, ] = [128, 136, 120, 145] -# list_peak_back[13, ] = [120, 145, 105, 155] -# list_peak_back[12, ] = [125, 140, 115, 150] - - ##### - #Input file should be as it is here ! - ##### - - #retrieve the S1H and S2H val/units for each NeXus - #retrieve the lambdaRequest value (Angstrom) - S1H = {} - S2H = {} - S1W = {} - S2W = {} - lambdaRequest = {} - getSlitsValueAndLambda(list_runs, S1H, S2H, S1W, S2W, lambdaRequest) - - #Make sure all the lambdaRequested are identical within a given range - lambdaRequestPrecision = 0.01 #1% - - for i in lambdaRequest: - _localValue = float(lambdaRequest[i][0]) - _localValueRate = lambdaRequestPrecision * _localValue - _leftValue = _localValue - _localValueRate - _rightValue = _localValue + _localValueRate - - if (_localValue < _leftValue) or (_localValue > _rightValue): - raise Exception("lambda requested do not match !") - - #make sure the file are sorted from smaller to bigger openning - if isRunsSorted(list_runs, S1H, S2H): - - #initialize record fitting parameters arrays - a = [] - b = [] - error_a = [] - error_b = [] - name = [] - - finalS1H = [] - finalS2H = [] - - finalS1W = [] - finalS2W = [] - - #array of True/False flags that will allow us - #to rescale the calculation on the first attenuator - _first_A = [] - for dummy_j in range(len(np.unique(list_attenuator))): - _first_A.append(True) - - #array of index of first attenuator - _index_first_A = [] - for dummy_j in range(len(np.unique(list_attenuator))): - _index_first_A.append(-1) - - index_numerator = -1 - index_denominator = -1 - - list_objects = [] - - for i in range(len(list_runs)): - - print('> Working with index: ' + str(i)) - _attenuator = list_attenuator[i] - - if _attenuator == 0: - continue - else: - if _first_A[_attenuator] is True: - _first_A[_attenuator] = False - _index_first_A[_attenuator] = i - continue - else: - index_numerator = i - index_denominator = _index_first_A[_attenuator] - - print('-> numerator : ' + str(list_runs[index_numerator])) - print('-> denominator: ' + str(list_runs[index_denominator])) - cal = calculateAndFit(numerator=list_runs[index_numerator], - denominator=list_runs[index_denominator], - list_peak_back_numerator=list_peak_back[index_numerator], - list_peak_back_denominator=list_peak_back[index_denominator], - list_objects=list_objects, - tof_range=tof_range) - print('-> Done with Calculate and Fit') - - recordSettings(a, b, error_a, error_b, name, cal) - - if i < (len(list_runs) - 1) and list_attenuator[i + 1] == (_attenuator+1): - list_objects.append(cal) - - #record S1H and S2H - finalS1H.append(S1H[index_numerator]) - finalS2H.append(S2H[index_numerator]) - - #record S1W and S2W - finalS1W.append(S1W[index_numerator]) - finalS2W.append(S2W[index_numerator]) - - #output the fitting parameters in an ascii - _lambdaRequest = "{0:.2f}".format(lambdaRequest[0][0]) - -# output_pre = 'SFcalculator_lr' + str(_lambdaRequest) -# output_ext = '.txt' -# output_file = output_path + '/' + output_pre + output_ext - - if (output_file_name is None) or (output_file_name == ''): - output_file_name = "RefLsf.cfg" - - outputFittingParameters(a, b, error_a, error_b, - _lambdaRequest, - incident_medium, - finalS1H, finalS2H, - finalS1W, finalS2W, - output_file_name) - - print('Done !') - -# else: -# """ -# sort the files -# """ -# pass diff --git a/Framework/PythonInterface/test/python/mantid/api/AlgorithmTest.py b/Framework/PythonInterface/test/python/mantid/api/AlgorithmTest.py index 88bc8f31c32..2ac4ea055a8 100644 --- a/Framework/PythonInterface/test/python/mantid/api/AlgorithmTest.py +++ b/Framework/PythonInterface/test/python/mantid/api/AlgorithmTest.py @@ -22,6 +22,7 @@ class AlgorithmTest(unittest.TestCase): self.assertEquals(1, len(self._load.categories())) self.assertEquals('DataHandling', self._load.categories()[0]) self.assertEquals('', self._load.helpURL()) + self.assertEquals(["LoadNexus", "LoadRaw", "LoadBBY"], self._load.seeAlso()) def test_get_unknown_property_raises_error(self): self.assertRaises(RuntimeError, self._load.getProperty, "NotAProperty") diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/SaveReflectionsTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/SaveReflectionsTest.py index a977957f0ff..1310c3fa408 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/SaveReflectionsTest.py +++ b/Framework/PythonInterface/test/python/plugins/algorithms/SaveReflectionsTest.py @@ -54,7 +54,7 @@ class SaveReflectionsTest(unittest.TestCase): def _create_indexed_workspace(self, fractional_peaks, ndim, hklm): # Create table with the number of columns we need types = ['int', 'long64', 'double', 'double', 'double', 'double', 'double', 'double', - 'double', 'double', 'double', 'float', 'str', 'float', 'float', 'V3D', 'V3D'] + 'double', 'double', 'double', 'float', 'str', 'float', 'float', 'V3D', 'V3D', 'int'] indexed = CreateEmptyTableWorkspace() names = fractional_peaks.getColumnNames() diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/SortXAxisTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/SortXAxisTest.py index 211ba767192..9b43e770f95 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/SortXAxisTest.py +++ b/Framework/PythonInterface/test/python/plugins/algorithms/SortXAxisTest.py @@ -1,16 +1,16 @@ from __future__ import (absolute_import, division, print_function) import unittest -from mantid.kernel import * -from mantid.api import * -from mantid.simpleapi import * +from mantid.simpleapi import AlgorithmManager, CreateWorkspace, DeleteWorkspace, SortXAxis + class SortXAxisTest(unittest.TestCase): + def test_x_ascending(self): - dataX = [1, 2, 3] # In ascending order, so y and e will need to be reversed. - dataY = [1, 2, 3] - dataE = [1, 2, 3] + dataX = [1., 2., 3.] # In ascending order, so y and e will need to be reversed. + dataY = [1., 2., 3.] + dataE = [1., 2., 3.] unsortedws = CreateWorkspace(DataX=dataX,DataY=dataY,DataE=dataE,UnitX='TOF',Distribution=True) # Run the algorithm sortedws = SortXAxis(InputWorkspace=unsortedws) @@ -24,11 +24,10 @@ class SortXAxisTest(unittest.TestCase): DeleteWorkspace(unsortedws) DeleteWorkspace(sortedws) - def test_x_descending(self): - dataX = [3, 2, 1] # In descending order, so y and e will need to be reversed. - dataY = [1, 2, 3] - dataE = [1, 2, 3] + dataX = [3., 2., 1.] # In descending order, so y and e will need to be reversed. + dataY = [1., 2., 3.] + dataE = [1., 2., 3.] unsortedws = CreateWorkspace(DataX=dataX,DataY=dataY,DataE=dataE,UnitX='TOF',Distribution=True) # Run the algorithm sortedws = SortXAxis(InputWorkspace=unsortedws) @@ -45,9 +44,9 @@ class SortXAxisTest(unittest.TestCase): DeleteWorkspace(sortedws) def test_on_multiple_spectrum(self): - dataX = [3, 2, 1, 3, 2, 1] # In descending order, so y and e will need to be reversed. - dataY = [1, 2, 3, 1, 2, 3] - dataE = [1, 2, 3, 1, 2, 3] + dataX = [3., 2., 1., 3., 2., 1.] # In descending order, so y and e will need to be reversed. + dataY = [1., 2., 3., 1., 2., 3.] + dataE = [1., 2., 3., 1., 2., 3.] unsortedws = CreateWorkspace(DataX=dataX,DataY=dataY,DataE=dataE,UnitX='TOF',Distribution=True, NSpec=2) dataY.reverse() dataE.reverse() @@ -70,11 +69,10 @@ class SortXAxisTest(unittest.TestCase): DeleteWorkspace(unsortedws) DeleteWorkspace(sortedws) - def test_sorts_x_histogram_ascending(self): - dataX = [1, 2, 3, 4] - dataY = [1, 2, 3] - dataE = [1, 2, 3] + dataX = [1., 2., 3., 4.] + dataY = [1., 2., 3.] + dataE = [1., 2., 3.] unsortedws = CreateWorkspace(DataX=dataX,DataY=dataY,DataE=dataE,UnitX='TOF',Distribution=False) # Run the algorithm sortedws = SortXAxis(InputWorkspace=unsortedws) @@ -90,9 +88,9 @@ class SortXAxisTest(unittest.TestCase): DeleteWorkspace(sortedws) def test_sorts_x_histogram_descending(self): - dataX = [4, 3, 2, 1] - dataY = [1, 2, 3] - dataE = [1, 2, 3] + dataX = [4., 3., 2., 1.] + dataY = [1., 2., 3.] + dataE = [1., 2., 3.] unsortedws = CreateWorkspace(DataX=dataX,DataY=dataY,DataE=dataE,UnitX='TOF',Distribution=False) # Run the algorithm sortedws = SortXAxis(InputWorkspace=unsortedws) @@ -113,9 +111,9 @@ class SortXAxisTest(unittest.TestCase): # Create unsorted workspace parent = AlgorithmManager.createUnmanaged('Load') create_ws_alg = parent.createChildAlgorithm("CreateWorkspace") - dataX = [4, 3, 2, 1] - dataY = [1, 2, 3] - dataE = [1, 2, 3] + dataX = [4., 3., 2., 1.] + dataY = [1., 2., 3.] + dataE = [1., 2., 3.] create_ws_alg.setProperty("DataX", dataX) create_ws_alg.setProperty("DataY", dataY) create_ws_alg.setProperty("DataE", dataE) @@ -137,5 +135,49 @@ class SortXAxisTest(unittest.TestCase): self.assertEqual(dataY, sortedY.tolist()) self.assertEqual(dataE, sortedE.tolist()) + def test_dx_multiple_spectrum(self): + dataX = [3, 2, 1, 3, 2, 1] # In descending order, so y and e will need to be reversed. + dataY = [1, 2, 3, 1, 2, 3] + dx = [1, 2, 3, 1, 2, 3] + unsortedws = CreateWorkspace(DataX=dataX, DataY=dataY, Dx=dx, UnitX='TOF', Distribution=True, NSpec=2) + dx.reverse() + # Run the algorithm + sortedws = SortXAxis(InputWorkspace=unsortedws) + # Check the resulting data values for 1st spectrum. + sortedDx = sortedws.readDx(0) + self.assertEqual(dx[0:3], sortedDx.tolist()) + # Check the resulting data values for 2nd spectrum. + sortedDx = sortedws.readDx(1) + self.assertEqual(dx[3:], sortedDx.tolist()) + DeleteWorkspace(unsortedws) + DeleteWorkspace(sortedws) + + def test_dx_histogram_ascending(self): + dataX = [1., 2., 3., 4.] + dataY = [1., 2., 3.] + dx = [1., 2., 3.] + unsortedws = CreateWorkspace(DataX=dataX, DataY=dataY, Dx=dx, UnitX='TOF', Distribution=False) + # Run the algorithm + sortedws = SortXAxis(InputWorkspace=unsortedws) + sortedDx = sortedws.readDx(0) + # Check the resulting data values. Sorting operation should have resulted in no changes + self.assertEqual(dx, sortedDx.tolist()) + DeleteWorkspace(unsortedws) + DeleteWorkspace(sortedws) + + def test_sort_descending(self): + dataX = [1., 2., 3., 4.] + dataY = [1., 2., 3.] + unsortedws = CreateWorkspace(DataX=dataX, DataY=dataY, UnitX='TOF', Distribution=False) + # Run the algorithm + sortedws = SortXAxis(InputWorkspace=unsortedws, Ordering="Descending") + sortedX = sortedws.readX(0) + sortedY = sortedws.readY(0) + # Check the resulting data values. Sorting operation should have resulted in no changes + self.assertEqual([4., 3., 2., 1.], sortedX.tolist()) + self.assertEqual([3., 2., 1.], sortedY.tolist()) + DeleteWorkspace(unsortedws) + DeleteWorkspace(sortedws) + if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/Framework/RemoteAlgorithms/test/AbortRemoteJob2Test.h b/Framework/RemoteAlgorithms/test/AbortRemoteJob2Test.h index 747c3af568c..56c48dc08ff 100644 --- a/Framework/RemoteAlgorithms/test/AbortRemoteJob2Test.h +++ b/Framework/RemoteAlgorithms/test/AbortRemoteJob2Test.h @@ -98,9 +98,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); AbortRemoteJob2 ab; diff --git a/Framework/RemoteAlgorithms/test/AbortRemoteJobTest.h b/Framework/RemoteAlgorithms/test/AbortRemoteJobTest.h index 3bf0389ec81..5583ee32899 100644 --- a/Framework/RemoteAlgorithms/test/AbortRemoteJobTest.h +++ b/Framework/RemoteAlgorithms/test/AbortRemoteJobTest.h @@ -96,9 +96,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); AbortRemoteJob ab; diff --git a/Framework/RemoteAlgorithms/test/Authenticate2Test.h b/Framework/RemoteAlgorithms/test/Authenticate2Test.h index 8e048de0530..3dfb66430a7 100644 --- a/Framework/RemoteAlgorithms/test/Authenticate2Test.h +++ b/Framework/RemoteAlgorithms/test/Authenticate2Test.h @@ -99,9 +99,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); Authenticate2 auth; diff --git a/Framework/RemoteAlgorithms/test/AuthenticateTest.h b/Framework/RemoteAlgorithms/test/AuthenticateTest.h index 1014fded63a..f8a074242f2 100644 --- a/Framework/RemoteAlgorithms/test/AuthenticateTest.h +++ b/Framework/RemoteAlgorithms/test/AuthenticateTest.h @@ -99,9 +99,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); Authenticate auth; diff --git a/Framework/RemoteAlgorithms/test/DownloadRemoteFile2Test.h b/Framework/RemoteAlgorithms/test/DownloadRemoteFile2Test.h index 41ded2ee0ca..9d5dc8c4346 100644 --- a/Framework/RemoteAlgorithms/test/DownloadRemoteFile2Test.h +++ b/Framework/RemoteAlgorithms/test/DownloadRemoteFile2Test.h @@ -104,9 +104,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); DownloadRemoteFile2 dl; diff --git a/Framework/RemoteAlgorithms/test/DownloadRemoteFileTest.h b/Framework/RemoteAlgorithms/test/DownloadRemoteFileTest.h index 4b18bde6ea7..7ecc3244762 100644 --- a/Framework/RemoteAlgorithms/test/DownloadRemoteFileTest.h +++ b/Framework/RemoteAlgorithms/test/DownloadRemoteFileTest.h @@ -104,9 +104,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); DownloadRemoteFile dl; diff --git a/Framework/RemoteAlgorithms/test/Logout2Test.h b/Framework/RemoteAlgorithms/test/Logout2Test.h index 1b337710d58..fc271f6d8ac 100644 --- a/Framework/RemoteAlgorithms/test/Logout2Test.h +++ b/Framework/RemoteAlgorithms/test/Logout2Test.h @@ -72,9 +72,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); // test that job managers are created correctly for different facilities - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); Logout2 lo; diff --git a/Framework/RemoteAlgorithms/test/QueryAllRemoteJobs2Test.h b/Framework/RemoteAlgorithms/test/QueryAllRemoteJobs2Test.h index b845d38a213..6ec451c5658 100644 --- a/Framework/RemoteAlgorithms/test/QueryAllRemoteJobs2Test.h +++ b/Framework/RemoteAlgorithms/test/QueryAllRemoteJobs2Test.h @@ -81,9 +81,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const auto facName = testFacility.first; + const auto compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); QueryAllRemoteJobs2 qar; diff --git a/Framework/RemoteAlgorithms/test/QueryAllRemoteJobsTest.h b/Framework/RemoteAlgorithms/test/QueryAllRemoteJobsTest.h index 1d00df8c2c2..da759801f3c 100644 --- a/Framework/RemoteAlgorithms/test/QueryAllRemoteJobsTest.h +++ b/Framework/RemoteAlgorithms/test/QueryAllRemoteJobsTest.h @@ -81,9 +81,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); QueryAllRemoteJobs qar; diff --git a/Framework/RemoteAlgorithms/test/QueryRemoteFile2Test.h b/Framework/RemoteAlgorithms/test/QueryRemoteFile2Test.h index 691e371466f..3d02988843a 100644 --- a/Framework/RemoteAlgorithms/test/QueryRemoteFile2Test.h +++ b/Framework/RemoteAlgorithms/test/QueryRemoteFile2Test.h @@ -91,9 +91,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); QueryRemoteFile2 qrf; diff --git a/Framework/RemoteAlgorithms/test/QueryRemoteFileTest.h b/Framework/RemoteAlgorithms/test/QueryRemoteFileTest.h index 46d71b39742..04427da0791 100644 --- a/Framework/RemoteAlgorithms/test/QueryRemoteFileTest.h +++ b/Framework/RemoteAlgorithms/test/QueryRemoteFileTest.h @@ -91,9 +91,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); QueryRemoteFile qrf; diff --git a/Framework/RemoteAlgorithms/test/QueryRemoteJob2Test.h b/Framework/RemoteAlgorithms/test/QueryRemoteJob2Test.h index d8863c6d5d8..bd7403c5641 100644 --- a/Framework/RemoteAlgorithms/test/QueryRemoteJob2Test.h +++ b/Framework/RemoteAlgorithms/test/QueryRemoteJob2Test.h @@ -90,9 +90,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); QueryRemoteJob2 qr; diff --git a/Framework/RemoteAlgorithms/test/QueryRemoteJobTest.h b/Framework/RemoteAlgorithms/test/QueryRemoteJobTest.h index c5d2ea8d430..97cd9d135e0 100644 --- a/Framework/RemoteAlgorithms/test/QueryRemoteJobTest.h +++ b/Framework/RemoteAlgorithms/test/QueryRemoteJobTest.h @@ -88,9 +88,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); QueryRemoteJob qr; diff --git a/Framework/RemoteAlgorithms/test/StartRemoteTransaction2Test.h b/Framework/RemoteAlgorithms/test/StartRemoteTransaction2Test.h index ffadba3eac9..f6c86ce3195 100644 --- a/Framework/RemoteAlgorithms/test/StartRemoteTransaction2Test.h +++ b/Framework/RemoteAlgorithms/test/StartRemoteTransaction2Test.h @@ -91,9 +91,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); StartRemoteTransaction2 start; diff --git a/Framework/RemoteAlgorithms/test/StartRemoteTransactionTest.h b/Framework/RemoteAlgorithms/test/StartRemoteTransactionTest.h index 27a2dfa80f5..006b409dfc6 100644 --- a/Framework/RemoteAlgorithms/test/StartRemoteTransactionTest.h +++ b/Framework/RemoteAlgorithms/test/StartRemoteTransactionTest.h @@ -91,9 +91,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); StartRemoteTransaction start; diff --git a/Framework/RemoteAlgorithms/test/StopRemoteTransaction2Test.h b/Framework/RemoteAlgorithms/test/StopRemoteTransaction2Test.h index 9153fe74d25..1c3cf78170d 100644 --- a/Framework/RemoteAlgorithms/test/StopRemoteTransaction2Test.h +++ b/Framework/RemoteAlgorithms/test/StopRemoteTransaction2Test.h @@ -93,9 +93,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); StopRemoteTransaction2 stop; diff --git a/Framework/RemoteAlgorithms/test/StopRemoteTransactionTest.h b/Framework/RemoteAlgorithms/test/StopRemoteTransactionTest.h index 75c87b5ddeb..1449876e836 100644 --- a/Framework/RemoteAlgorithms/test/StopRemoteTransactionTest.h +++ b/Framework/RemoteAlgorithms/test/StopRemoteTransactionTest.h @@ -93,9 +93,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); StopRemoteTransaction stop; diff --git a/Framework/RemoteAlgorithms/test/SubmitRemoteJob2Test.h b/Framework/RemoteAlgorithms/test/SubmitRemoteJob2Test.h index 8e1ef644caf..edf6b121523 100644 --- a/Framework/RemoteAlgorithms/test/SubmitRemoteJob2Test.h +++ b/Framework/RemoteAlgorithms/test/SubmitRemoteJob2Test.h @@ -157,9 +157,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); diff --git a/Framework/RemoteAlgorithms/test/SubmitRemoteJobTest.h b/Framework/RemoteAlgorithms/test/SubmitRemoteJobTest.h index 520cb3d0ca8..cbe9053f8ad 100644 --- a/Framework/RemoteAlgorithms/test/SubmitRemoteJobTest.h +++ b/Framework/RemoteAlgorithms/test/SubmitRemoteJobTest.h @@ -157,9 +157,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); diff --git a/Framework/RemoteAlgorithms/test/UploadRemoteFile2Test.h b/Framework/RemoteAlgorithms/test/UploadRemoteFile2Test.h index ebdd6c318fd..18a8031f5f8 100644 --- a/Framework/RemoteAlgorithms/test/UploadRemoteFile2Test.h +++ b/Framework/RemoteAlgorithms/test/UploadRemoteFile2Test.h @@ -124,9 +124,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); diff --git a/Framework/RemoteAlgorithms/test/UploadRemoteFileTest.h b/Framework/RemoteAlgorithms/test/UploadRemoteFileTest.h index 2b0f241c2a6..1801ad928e0 100644 --- a/Framework/RemoteAlgorithms/test/UploadRemoteFileTest.h +++ b/Framework/RemoteAlgorithms/test/UploadRemoteFileTest.h @@ -124,9 +124,9 @@ public: const Mantid::Kernel::FacilityInfo &prevFac = Mantid::Kernel::ConfigService::Instance().getFacility(); - for (size_t fi = 0; fi < testFacilities.size(); fi++) { - const std::string facName = testFacilities[fi].first; - const std::string compName = testFacilities[fi].second; + for (auto &testFacility : testFacilities) { + const std::string facName = testFacility.first; + const std::string compName = testFacility.second; Mantid::Kernel::ConfigService::Instance().setFacility(facName); diff --git a/Framework/SINQ/inc/MantidSINQ/InvertMDDim.h b/Framework/SINQ/inc/MantidSINQ/InvertMDDim.h index 1a66516d486..1fa14856f81 100644 --- a/Framework/SINQ/inc/MantidSINQ/InvertMDDim.h +++ b/Framework/SINQ/inc/MantidSINQ/InvertMDDim.h @@ -44,6 +44,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"TransformMD"}; + } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\Transforms"; diff --git a/Framework/SINQ/inc/MantidSINQ/LoadFlexiNexus.h b/Framework/SINQ/inc/MantidSINQ/LoadFlexiNexus.h index 4efa2af544f..60103f10790 100644 --- a/Framework/SINQ/inc/MantidSINQ/LoadFlexiNexus.h +++ b/Framework/SINQ/inc/MantidSINQ/LoadFlexiNexus.h @@ -61,6 +61,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"LoadNexus"}; + } /// Algorithm's category for identification const std::string category() const override { return "DataHandling\\Nexus"; } diff --git a/Framework/SINQ/inc/MantidSINQ/MDHistoToWorkspace2D.h b/Framework/SINQ/inc/MantidSINQ/MDHistoToWorkspace2D.h index 6e0e2bf4361..df1acebf62d 100644 --- a/Framework/SINQ/inc/MantidSINQ/MDHistoToWorkspace2D.h +++ b/Framework/SINQ/inc/MantidSINQ/MDHistoToWorkspace2D.h @@ -49,6 +49,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"ConvertMDHistoToMatrixWorkspace"}; + } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\Transforms"; diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h b/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h index 4344c9b4c3d..d4302a39502 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiCreatePeaksFromCell.h @@ -45,6 +45,9 @@ class MANTID_SINQ_DLL PoldiCreatePeaksFromCell : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"PoldiCreatePeaksFromFile"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h b/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h index ac94ab78835..e462465b739 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h @@ -88,6 +88,9 @@ public: } int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"PoldiFitPeaks2D"}; + } const std::string category() const override; protected: diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h b/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h index c59149bb3b4..f74ce705f7a 100644 --- a/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h +++ b/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h @@ -56,6 +56,9 @@ class MANTID_SINQ_DLL PoldiFitPeaks2D : public API::Algorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"PoldiFitPeaks1D"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/SINQ/inc/MantidSINQ/ProjectMD.h b/Framework/SINQ/inc/MantidSINQ/ProjectMD.h index 8fbafa364e7..89de58f5554 100644 --- a/Framework/SINQ/inc/MantidSINQ/ProjectMD.h +++ b/Framework/SINQ/inc/MantidSINQ/ProjectMD.h @@ -43,6 +43,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"CutMD", "BinMD"}; + } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\Slicing"; diff --git a/Framework/SINQ/inc/MantidSINQ/SINQTranspose3D.h b/Framework/SINQ/inc/MantidSINQ/SINQTranspose3D.h index 52d9b8611a6..2905071f819 100644 --- a/Framework/SINQ/inc/MantidSINQ/SINQTranspose3D.h +++ b/Framework/SINQ/inc/MantidSINQ/SINQTranspose3D.h @@ -52,7 +52,9 @@ public: const std::string summary() const override { return "SINQ specific MD data reordering"; } - + const std::vector<std::string> seeAlso() const override { + return {"TransposeMD", "Transpose"}; + } /// Algorithm's version int version() const override { return (1); } /// Algorithm's category for identification diff --git a/Framework/SINQ/inc/MantidSINQ/SliceMDHisto.h b/Framework/SINQ/inc/MantidSINQ/SliceMDHisto.h index 4199b0bf83a..61f584a5769 100644 --- a/Framework/SINQ/inc/MantidSINQ/SliceMDHisto.h +++ b/Framework/SINQ/inc/MantidSINQ/SliceMDHisto.h @@ -46,6 +46,9 @@ public: /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SliceMD", "IntegrateMDHistoWorkspace"}; + } /// Algorithm's category for identification const std::string category() const override { return "MDAlgorithms\\Slicing"; diff --git a/Framework/SINQ/test/PoldiFitPeaks1D2Test.h b/Framework/SINQ/test/PoldiFitPeaks1D2Test.h index e4fd2201eee..9fd47f6fd0c 100644 --- a/Framework/SINQ/test/PoldiFitPeaks1D2Test.h +++ b/Framework/SINQ/test/PoldiFitPeaks1D2Test.h @@ -100,8 +100,8 @@ public: std::vector<Property *> properties = fitPeaks1D.getProperties(); std::unordered_set<std::string> names; - for (size_t i = 0; i < properties.size(); ++i) { - names.insert(properties[i]->name()); + for (auto &property : properties) { + names.insert(property->name()); } TS_ASSERT_EQUALS(names.count("InputWorkspace"), 1); diff --git a/Framework/SINQ/test/PoldiFitPeaks1DTest.h b/Framework/SINQ/test/PoldiFitPeaks1DTest.h index 5fef57ec078..e8ff092bb0c 100644 --- a/Framework/SINQ/test/PoldiFitPeaks1DTest.h +++ b/Framework/SINQ/test/PoldiFitPeaks1DTest.h @@ -102,8 +102,8 @@ public: std::vector<Property *> properties = fitPeaks1D.getProperties(); std::unordered_set<std::string> names; - for (size_t i = 0; i < properties.size(); ++i) { - names.insert(properties[i]->name()); + for (auto &property : properties) { + names.insert(property->name()); } TS_ASSERT_EQUALS(names.count("InputWorkspace"), 1); diff --git a/Framework/SINQ/test/PoldiIndexKnownCompoundsTest.h b/Framework/SINQ/test/PoldiIndexKnownCompoundsTest.h index b0906c2fa91..302ef9bc829 100644 --- a/Framework/SINQ/test/PoldiIndexKnownCompoundsTest.h +++ b/Framework/SINQ/test/PoldiIndexKnownCompoundsTest.h @@ -669,9 +669,9 @@ private: } void storeRandomWorkspaces(const std::vector<std::string> &wsNames) { - for (auto it = wsNames.begin(); it != wsNames.end(); ++it) { + for (const auto &wsName : wsNames) { WorkspaceCreationHelper::storeWS( - *it, WorkspaceCreationHelper::create1DWorkspaceRand(10, true)); + wsName, WorkspaceCreationHelper::create1DWorkspaceRand(10, true)); } } @@ -684,8 +684,8 @@ private: } void removeRandomWorkspaces(const std::vector<std::string> &wsNames) { - for (auto it = wsNames.begin(); it != wsNames.end(); ++it) { - WorkspaceCreationHelper::removeWS(*it); + for (const auto &wsName : wsNames) { + WorkspaceCreationHelper::removeWS(wsName); } } diff --git a/Framework/SINQ/test/PoldiPeakSearchTest.h b/Framework/SINQ/test/PoldiPeakSearchTest.h index 6cf85b25ef8..b4534d07500 100644 --- a/Framework/SINQ/test/PoldiPeakSearchTest.h +++ b/Framework/SINQ/test/PoldiPeakSearchTest.h @@ -123,10 +123,9 @@ public: std::vector<double> testXData(testYData.size()); double x = 0.0; - for (std::vector<double>::iterator iterX = testXData.begin(); - iterX != testXData.end(); ++iterX) { + for (double &iterX : testXData) { x += 1.0; - *iterX = x; + iterX = x; } std::list<std::vector<double>::const_iterator> maxima = diff --git a/Framework/ScriptRepository/test/ScriptRepositoryTestImpl.h b/Framework/ScriptRepository/test/ScriptRepositoryTestImpl.h index 48098cfef3b..d8fe26e372d 100644 --- a/Framework/ScriptRepository/test/ScriptRepositoryTestImpl.h +++ b/Framework/ScriptRepository/test/ScriptRepositoryTestImpl.h @@ -363,8 +363,8 @@ public: TS_ASSERT_THROWS_NOTHING(list_files = repo->listFiles()); TS_ASSERT(list_files.size() == 5); // check that all the files at the central repository are inside - for (int i = 0; i < 5; i++) - TSM_ASSERT_THROWS_NOTHING(test_entries[i], repo->info(test_entries[i])); + for (auto &test_entry : test_entries) + TSM_ASSERT_THROWS_NOTHING(test_entry, repo->info(test_entry)); } /** @@ -478,9 +478,8 @@ public: TS_ASSERT_THROWS_NOTHING(list_of_files = repo->listFiles()); std::cout << "After update, the files are: "; - for (std::vector<string>::iterator it = list_of_files.begin(); - it != list_of_files.end(); it++) { - std::cout << *it << ", "; + for (auto &list_of_file : list_of_files) { + std::cout << list_of_file << ", "; } std::cout << '\n'; TS_ASSERT(list_of_files.size() == 1); diff --git a/Framework/WorkflowAlgorithms/CMakeLists.txt b/Framework/WorkflowAlgorithms/CMakeLists.txt index 7bdb72de478..adbf431c165 100644 --- a/Framework/WorkflowAlgorithms/CMakeLists.txt +++ b/Framework/WorkflowAlgorithms/CMakeLists.txt @@ -29,7 +29,6 @@ set ( SRC_FILES src/MuonProcess.cpp src/MuonPairAsymmetryCalculator.cpp src/ProcessIndirectFitParameters.cpp - src/RefReduction.cpp src/RefRoi.cpp src/SANSBeamFinder.cpp src/SANSBeamFluxCorrection.cpp @@ -76,7 +75,6 @@ set ( INC_FILES inc/MantidWorkflowAlgorithms/MuonProcess.h inc/MantidWorkflowAlgorithms/MuonPairAsymmetryCalculator.h inc/MantidWorkflowAlgorithms/ProcessIndirectFitParameters.h - inc/MantidWorkflowAlgorithms/RefReduction.h inc/MantidWorkflowAlgorithms/RefRoi.h inc/MantidWorkflowAlgorithms/SANSBeamFinder.h inc/MantidWorkflowAlgorithms/SANSBeamFluxCorrection.h diff --git a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/AlignAndFocusPowder.h b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/AlignAndFocusPowder.h index a5c16c6eb34..241a2131006 100644 --- a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/AlignAndFocusPowder.h +++ b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/AlignAndFocusPowder.h @@ -65,6 +65,9 @@ public: /// Algorithm's version for identification overriding a virtual method int version() const override { return 1; } + const std::vector<std::string> seeAlso() const override { + return {"AlignAndFocusPowderFromFiles"}; + } /// Algorithm's category for identification overriding a virtual method const std::string category() const override { diff --git a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/LoadEventAndCompress.h b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/LoadEventAndCompress.h index ce8aaf3dba4..ec88cb90c0d 100644 --- a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/LoadEventAndCompress.h +++ b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/LoadEventAndCompress.h @@ -35,6 +35,9 @@ class DLLExport LoadEventAndCompress : public API::DataProcessorAlgorithm { public: const std::string name() const override; int version() const override; + const std::vector<std::string> seeAlso() const override { + return {"LoadEventNexus", "CompressEvents"}; + } const std::string category() const override; const std::string summary() const override; diff --git a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefReduction.h b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefReduction.h deleted file mode 100644 index 749f1f43c99..00000000000 --- a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefReduction.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef MANTID_ALGORITHMS_RefReduction_H_ -#define MANTID_ALGORITHMS_RefReduction_H_ - -//---------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------- -#include "MantidAPI/Algorithm.h" -#include "MantidAPI/MatrixWorkspace_fwd.h" -#include "MantidDataObjects/EventWorkspace.h" - -namespace Mantid { -namespace WorkflowAlgorithms { -/** - Data reduction for reflectometry - - Copyright © 2012 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge - National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - - File change history is stored at: <https://github.com/mantidproject/mantid> - Code Documentation is available at: <http://doxygen.mantidproject.org> -*/ - -class DLLExport RefReduction : public API::Algorithm { -public: - /// Algorithm's name - const std::string name() const override { return "RefReduction"; } - /// Summary of algorithms purpose - const std::string summary() const override { - return "Data reduction for reflectometry."; - } - /// Algorithm's version - int version() const override { return (1); } - /// Algorithm's category for identification - const std::string category() const override { - return "Workflow\\Reflectometry"; - } - -private: - /// Initialisation code - void init() override; - /// Execution code - void exec() override; - - static const std::string PolStateOffOff; - static const std::string PolStateOnOff; - static const std::string PolStateOffOn; - static const std::string PolStateOnOn; - static const std::string PolStateNone; - - static const int NX_PIXELS; - static const int NY_PIXELS; - static const double PIXEL_SIZE; - - std::string m_output_message; - - API::MatrixWorkspace_sptr processData(const std::string polarization); - API::MatrixWorkspace_sptr processNormalization(); - API::IEventWorkspace_sptr loadData(const std::string dataRun, - const std::string polarization); - double calculateAngleREFM(API::MatrixWorkspace_sptr workspace); - double calculateAngleREFL(API::MatrixWorkspace_sptr workspace); - API::MatrixWorkspace_sptr subtractBackground(API::MatrixWorkspace_sptr dataWS, - API::MatrixWorkspace_sptr rawWS, - int peakMin, int peakMax, - int bckMin, int bckMax, - int lowResMin, int lowResMax); -}; - -} // namespace Algorithms -} // namespace Mantid - -#endif /*MANTID_ALGORITHMS_RefReduction_H_*/ diff --git a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefRoi.h b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefRoi.h index 389114be907..fd629644542 100644 --- a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefRoi.h +++ b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/RefRoi.h @@ -48,6 +48,7 @@ public: } /// Algorithm's version int version() const override { return (1); } + /// Algorithm's category for identification const std::string category() const override { return "Workflow\\Reflectometry"; diff --git a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSBeamFluxCorrection.h b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSBeamFluxCorrection.h index 1c274a53cf6..3aa3e9b374c 100644 --- a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSBeamFluxCorrection.h +++ b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSBeamFluxCorrection.h @@ -24,6 +24,9 @@ public: } /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SANSSolidAngleCorrection"}; + } /// Algorithm's category for identification const std::string category() const override { return "Workflow\\SANS\\UsesPropertyManager;" diff --git a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSSolidAngleCorrection.h b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSSolidAngleCorrection.h index a161140b047..9a0fc2d782e 100644 --- a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSSolidAngleCorrection.h +++ b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SANSSolidAngleCorrection.h @@ -44,6 +44,9 @@ public: } /// Algorithm's version int version() const override { return (1); } + const std::vector<std::string> seeAlso() const override { + return {"SANSBeamFluxCorrection"}; + } /// Algorithm's category for identification const std::string category() const override { return "Workflow\\SANS\\UsesPropertyManager;" diff --git a/Framework/WorkflowAlgorithms/src/RefReduction.cpp b/Framework/WorkflowAlgorithms/src/RefReduction.cpp deleted file mode 100644 index 381da79c0b5..00000000000 --- a/Framework/WorkflowAlgorithms/src/RefReduction.cpp +++ /dev/null @@ -1,817 +0,0 @@ -#include "MantidWorkflowAlgorithms/RefReduction.h" -#include "MantidAPI/AnalysisDataService.h" -#include "MantidGeometry/Instrument/DetectorInfo.h" -#include "MantidAPI/FileFinder.h" -#include "MantidAPI/MatrixWorkspace.h" -#include "MantidAPI/Run.h" -#include "MantidDataObjects/EventWorkspace.h" -#include "MantidGeometry/Instrument.h" -#include "MantidKernel/ArrayProperty.h" -#include "MantidKernel/ListValidator.h" -#include "MantidKernel/TimeSeriesProperty.h" -#include "MantidKernel/VisibleWhenProperty.h" - -#include "Poco/File.h" -#include "Poco/NumberFormatter.h" -#include "Poco/String.h" -#include <algorithm> - -namespace Mantid { -namespace WorkflowAlgorithms { - -// Register the algorithm into the AlgorithmFactory -DECLARE_ALGORITHM(RefReduction) - -const std::string RefReduction::PolStateOffOff("entry-Off_Off"); -const std::string RefReduction::PolStateOnOff("entry-On_Off"); -const std::string RefReduction::PolStateOffOn("entry-Off_On"); -const std::string RefReduction::PolStateOnOn("entry-On_On"); -const std::string RefReduction::PolStateNone("entry"); - -const int RefReduction::NX_PIXELS(304); -const int RefReduction::NY_PIXELS(256); -const double RefReduction::PIXEL_SIZE(0.0007); - -using namespace Kernel; -using namespace API; -using namespace Geometry; -using namespace DataObjects; - -void RefReduction::init() { - declareProperty("DataRun", "", "Run number of the data set to be reduced"); - declareProperty(make_unique<ArrayProperty<int>>("SignalPeakPixelRange"), - "Pixel range for the signal peak"); - - declareProperty( - "SubtractSignalBackground", false, - "If true, the background will be subtracted from the signal peak"); - declareProperty(make_unique<ArrayProperty<int>>("SignalBackgroundPixelRange"), - "Pixel range for background around the signal peak"); - - declareProperty( - "CropLowResDataAxis", false, - "If true, the low-resolution pixel range will be limited to the" - " range given by the LowResDataAxisPixelRange property"); - declareProperty(make_unique<ArrayProperty<int>>("LowResDataAxisPixelRange"), - "Pixel range for the signal peak in the low-res direction"); - - declareProperty("PerformNormalization", true, - "If true, the normalization will be performed"); - declareProperty("NormalizationRun", "", - "Run number of the normalization data set"); - declareProperty(make_unique<ArrayProperty<int>>("NormPeakPixelRange"), - "Pixel range for the normalization peak"); - - declareProperty("SubtractNormBackground", false, - "It true, the background will be subtracted" - " from the normalization peak"); - declareProperty(make_unique<ArrayProperty<int>>("NormBackgroundPixelRange"), - "Pixel range for background around the normalization peak"); - - declareProperty("CropLowResNormAxis", false, - "If true, the low-resolution pixel range" - " will be limited to be the range given by the " - "LowResNormAxisPixelRange property"); - declareProperty( - make_unique<ArrayProperty<int>>("LowResNormAxisPixelRange"), - "Pixel range for the normalization peak in the low-res direction"); - - declareProperty("Theta", EMPTY_DBL(), - "Scattering angle (takes precedence over meta data)"); - declareProperty("TOFMin", EMPTY_DBL(), "Minimum TOF cut"); - declareProperty("TOFMax", EMPTY_DBL(), "Maximum TOF cut"); - - declareProperty("TOFStep", 400.0, "Step size of TOF histogram"); - declareProperty("NBins", EMPTY_INT(), "Number of bins in TOF histogram " - "(takes precedence over TOFStep if " - "given)"); - - declareProperty("ReflectivityPixel", EMPTY_DBL()); - declareProperty("DetectorAngle", EMPTY_DBL()); - declareProperty("DetectorAngle0", EMPTY_DBL()); - declareProperty("DirectPixel", EMPTY_DBL()); - declareProperty("PolarizedData", true, "If true, the algorithm will look for " - "polarization states in the data set"); - setPropertySettings( - "ReflectivityPixel", - make_unique<VisibleWhenProperty>("Instrument", IS_EQUAL_TO, "REF_M")); - setPropertySettings("DetectorAngle", make_unique<VisibleWhenProperty>( - "Instrument", IS_EQUAL_TO, "REF_M")); - setPropertySettings( - "DetectorAngle0", - make_unique<VisibleWhenProperty>("Instrument", IS_EQUAL_TO, "REF_M")); - setPropertySettings("DirectPixel", make_unique<VisibleWhenProperty>( - "Instrument", IS_EQUAL_TO, "REF_M")); - - declareProperty("AngleOffset", EMPTY_DBL(), - "Scattering angle offset in degrees"); - setPropertySettings("AngleOffset", make_unique<VisibleWhenProperty>( - "Instrument", IS_EQUAL_TO, "REF_L")); - - std::vector<std::string> instrOptions{"REF_L", "REF_M"}; - declareProperty("Instrument", "REF_M", - boost::make_shared<StringListValidator>(instrOptions), - "Instrument to reduce for"); - declareProperty("OutputWorkspacePrefix", "reflectivity", - "Prefix to give the output workspaces"); - declareProperty("OutputMessage", "", Direction::Output); -} - -/// Execute algorithm -void RefReduction::exec() { - const std::string instrument = getProperty("Instrument"); - m_output_message = "------ " + instrument + " reduction ------\n"; - - // Process each polarization state - if (getProperty("PolarizedData")) { - processData(PolStateOffOff); - processData(PolStateOnOff); - processData(PolStateOffOn); - processData(PolStateOnOn); - } else { - processData(PolStateNone); - } - setPropertyValue("OutputMessage", m_output_message); -} - -MatrixWorkspace_sptr RefReduction::processData(const std::string polarization) { - m_output_message += "Processing " + polarization + '\n'; - const std::string dataRun = getPropertyValue("DataRun"); - IEventWorkspace_sptr evtWS = loadData(dataRun, polarization); - // wrong entry name - if (!evtWS) - return nullptr; - - MatrixWorkspace_sptr dataWS = - boost::dynamic_pointer_cast<MatrixWorkspace>(evtWS); - MatrixWorkspace_sptr dataWSTof = - boost::dynamic_pointer_cast<MatrixWorkspace>(evtWS); - - // If we have no events, stop here - if (evtWS->getNumberEvents() == 0) - return dataWS; - - // Get low-res pixel range - int low_res_min = 0; - int low_res_max = 0; - const bool cropLowRes = getProperty("CropLowResDataAxis"); - const std::vector<int> lowResRange = getProperty("LowResDataAxisPixelRange"); - if (cropLowRes) { - if (lowResRange.size() < 2) { - g_log.error() << "LowResDataAxisPixelRange parameter should be a vector " - "of two values\n"; - throw std::invalid_argument("LowResDataAxisPixelRange parameter should " - "be a vector of two values"); - } - low_res_min = lowResRange[0]; - low_res_max = lowResRange[1]; - m_output_message += " |Cropping low-res axis: [" + - Poco::NumberFormatter::format(low_res_min) + ", " + - Poco::NumberFormatter::format(low_res_max) + "]\n"; - } - - // Get peak range - const std::vector<int> peakRange = getProperty("SignalPeakPixelRange"); - if (peakRange.size() < 2) { - g_log.error() - << "SignalPeakPixelRange parameter should be a vector of two values\n"; - throw std::invalid_argument( - "SignalPeakPixelRange parameter should be a vector of two values"); - } - - // Get scattering angle in degrees - double theta = getProperty("Theta"); - const std::string instrument = getProperty("Instrument"); - const bool integrateY = instrument == "REF_M"; - - // Get pixel ranges in real pixels - int xmin = 0; - int xmax = 0; - int ymin = 0; - int ymax = 0; - if (integrateY) { - if (isEmpty(theta)) - theta = calculateAngleREFM(dataWS); - if (!cropLowRes) - low_res_max = NY_PIXELS - 1; - xmin = 0; - xmax = NX_PIXELS - 1; - ymin = low_res_min; - ymax = low_res_max; - } else { - if (isEmpty(theta)) - theta = calculateAngleREFL(dataWS); - if (!cropLowRes) - low_res_max = NX_PIXELS - 1; - ymin = 0; - ymax = NY_PIXELS - 1; - xmin = low_res_min; - xmax = low_res_max; - } - m_output_message += " |Scattering angle: " + - Poco::NumberFormatter::format(theta, 6) + " deg\n"; - - // Subtract background - if (getProperty("SubtractSignalBackground")) { - // Get background range - const std::vector<int> bckRange = getProperty("SignalBackgroundPixelRange"); - if (bckRange.size() < 2) { - g_log.error() << "SignalBackgroundPixelRange parameter should be a " - "vector of two values\n"; - throw std::invalid_argument("SignalBackgroundPixelRange parameter should " - "be a vector of two values"); - } - - IAlgorithm_sptr convAlg = - createChildAlgorithm("ConvertToMatrixWorkspace", 0.50, 0.55); - convAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS); - convAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS); - convAlg->executeAsChildAlg(); - - dataWS = - subtractBackground(dataWS, dataWS, peakRange[0], peakRange[1], - bckRange[0], bckRange[1], low_res_min, low_res_max); - m_output_message += " |Subtracted background [" + - Poco::NumberFormatter::format(bckRange[0]) + ", " + - Poco::NumberFormatter::format(bckRange[1]) + "]\n"; - } - - // Process normalization run - if (getProperty("PerformNormalization")) { - MatrixWorkspace_sptr normWS = processNormalization(); - IAlgorithm_sptr rebinAlg = - createChildAlgorithm("RebinToWorkspace", 0.50, 0.55); - rebinAlg->setProperty<MatrixWorkspace_sptr>("WorkspaceToRebin", normWS); - rebinAlg->setProperty<MatrixWorkspace_sptr>("WorkspaceToMatch", dataWS); - rebinAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", normWS); - rebinAlg->executeAsChildAlg(); - normWS = rebinAlg->getProperty("OutputWorkspace"); - - IAlgorithm_sptr divAlg = createChildAlgorithm("Divide", 0.55, 0.65); - divAlg->setProperty<MatrixWorkspace_sptr>("LHSWorkspace", dataWS); - divAlg->setProperty<MatrixWorkspace_sptr>("RHSWorkspace", normWS); - divAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS); - divAlg->executeAsChildAlg(); - - IAlgorithm_sptr repAlg = - createChildAlgorithm("ReplaceSpecialValues", 0.55, 0.65); - repAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS); - repAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", dataWS); - repAlg->setProperty("NaNValue", 0.0); - repAlg->setProperty("NaNError", 0.0); - repAlg->setProperty("InfinityValue", 0.0); - repAlg->setProperty("InfinityError", 0.0); - repAlg->executeAsChildAlg(); - m_output_message += "Normalization completed\n"; - } - - // // Integrate over Y - // IAlgorithm_sptr refAlg = createChildAlgorithm("RefRoi", 0.90, 0.95); - // refAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS); - // refAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS); - // refAlg->setProperty("NXPixel", NX_PIXELS); - // refAlg->setProperty("NYPixel", NY_PIXELS); - // refAlg->setProperty("YPixelMin", ymin); - // refAlg->setProperty("YPixelMax", ymax); - // refAlg->setProperty("XPixelMin", xmin); - // refAlg->setProperty("XPixelMax", xmax); - // refAlg->setProperty("IntegrateY", integrateY); - // refAlg->setProperty("ScatteringAngle", theta); - // refAlg->executeAsChildAlg(); - // - // // Convert back to TOF - // IAlgorithm_sptr convAlgToTof = createChildAlgorithm("ConvertUnits", - // 0.85, 0.90); - // convAlgToTof->setProperty<MatrixWorkspace_sptr>("InputWorkspace", - // dataWS); - // convAlgToTof->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", - // dataWSTof); - // convAlgToTof->setProperty("Target", "TOF"); - // convAlgToTof->executeAsChildAlg(); - // - // MatrixWorkspace_sptr outputWS2 = - // convAlgToTof->getProperty("OutputWorkspace"); - // declareProperty(new WorkspaceProperty<>("OutputWorkspace_jc_" + - // polarization, "TOF_"+polarization, Direction::Output)); - // setProperty("OutputWorkspace_jc_" + polarization, outputWS2); - - // integrated over Y and keep in lambda scale - IAlgorithm_sptr refAlg1 = createChildAlgorithm("RefRoi", 0.90, 0.95); - refAlg1->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS); - refAlg1->setProperty("NXPixel", NX_PIXELS); - refAlg1->setProperty("NYPixel", NY_PIXELS); - refAlg1->setProperty("ConvertToQ", false); - refAlg1->setProperty("YPixelMin", ymin); - refAlg1->setProperty("YPixelMax", ymax); - refAlg1->setProperty("XPixelMin", xmin); - refAlg1->setProperty("XPixelMax", xmax); - refAlg1->setProperty("IntegrateY", integrateY); - refAlg1->setProperty("ScatteringAngle", theta); - refAlg1->executeAsChildAlg(); - MatrixWorkspace_sptr outputWS2 = refAlg1->getProperty("OutputWorkspace"); - std::string polarizationTranslation(polarization); - std::replace(polarizationTranslation.begin(), polarizationTranslation.end(), - '-', '_'); - declareProperty(Kernel::make_unique<WorkspaceProperty<>>( - "OutputWorkspace_jc_" + polarizationTranslation, "Lambda_" + polarization, - Direction::Output)); - setProperty("OutputWorkspace_jc_" + polarizationTranslation, outputWS2); - - // Conversion to Q - IAlgorithm_sptr refAlg = createChildAlgorithm("RefRoi", 0.90, 0.95); - refAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", dataWS); - refAlg->setProperty("NXPixel", NX_PIXELS); - refAlg->setProperty("NYPixel", NY_PIXELS); - refAlg->setProperty("ConvertToQ", true); - - refAlg->setProperty("YPixelMin", ymin); - refAlg->setProperty("YPixelMax", ymax); - refAlg->setProperty("XPixelMin", xmin); - refAlg->setProperty("XPixelMax", xmax); - refAlg->setProperty("IntegrateY", integrateY); - refAlg->setProperty("ScatteringAngle", theta); - refAlg->executeAsChildAlg(); - - MatrixWorkspace_sptr output2DWS = refAlg->getProperty("OutputWorkspace"); - std::vector<int> spectra; - for (int i = peakRange[0]; i < peakRange[1] + 1; i++) - spectra.push_back(i); - - IAlgorithm_sptr grpAlg = createChildAlgorithm("GroupDetectors", 0.95, 0.99); - grpAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", output2DWS); - grpAlg->setProperty("SpectraList", spectra); - grpAlg->executeAsChildAlg(); - - MatrixWorkspace_sptr outputWS = grpAlg->getProperty("OutputWorkspace"); - - const std::string prefix = getPropertyValue("OutputWorkspacePrefix"); - if (polarization == PolStateNone) { - declareProperty(Kernel::make_unique<WorkspaceProperty<>>( - "OutputWorkspace", prefix, Direction::Output)); - setProperty("OutputWorkspace", outputWS); - declareProperty(Kernel::make_unique<WorkspaceProperty<>>( - "OutputWorkspace2D", "2D_" + prefix, Direction::Output)); - setProperty("OutputWorkspace2D", output2DWS); - } else { - std::string wsName = prefix + polarization; - Poco::replaceInPlace(wsName, "entry", ""); - declareProperty(Kernel::make_unique<WorkspaceProperty<>>( - "OutputWorkspace_" + polarizationTranslation, wsName, - Direction::Output)); - setProperty("OutputWorkspace_" + polarizationTranslation, outputWS); - declareProperty(Kernel::make_unique<WorkspaceProperty<>>( - "OutputWorkspace2D_" + polarizationTranslation, "2D_" + wsName, - Direction::Output)); - setProperty("OutputWorkspace2D_" + polarizationTranslation, output2DWS); - } - m_output_message += "Reflectivity calculation completed\n"; - return outputWS; -} - -MatrixWorkspace_sptr RefReduction::processNormalization() { - m_output_message += "Processing normalization\n"; - - const std::string normRun = getPropertyValue("NormalizationRun"); - IEventWorkspace_sptr evtWS = loadData(normRun, PolStateNone); - MatrixWorkspace_sptr normWS = - boost::dynamic_pointer_cast<MatrixWorkspace>(evtWS); - - const std::vector<int> peakRange = getProperty("NormPeakPixelRange"); - - int low_res_min = 0; - int low_res_max = 0; - int xmin = 0; - int xmax = 0; - int ymin = 0; - int ymax = 0; - - const bool cropLowRes = getProperty("CropLowResNormAxis"); - const std::vector<int> lowResRange = getProperty("LowResNormAxisPixelRange"); - if (cropLowRes) { - if (lowResRange.size() < 2) { - g_log.error() << "LowResNormAxisPixelRange parameter should be a vector " - "of two values\n"; - throw std::invalid_argument("LowResNormAxisPixelRange parameter should " - "be a vector of two values"); - } - low_res_min = lowResRange[0]; - low_res_max = lowResRange[1]; - m_output_message + " |Cropping low-res axis: [" + - Poco::NumberFormatter::format(low_res_min) + ", " + - Poco::NumberFormatter::format(low_res_max) + "]\n"; - } - - const std::string instrument = getProperty("Instrument"); - const bool integrateY = instrument == "REF_M"; - if (integrateY) { - if (!cropLowRes) - low_res_max = NY_PIXELS - 1; - xmin = peakRange[0]; - xmax = peakRange[1]; - ymin = low_res_min; - ymax = low_res_max; - } else { - if (!cropLowRes) - low_res_max = NX_PIXELS - 1; - ymin = peakRange[0]; - ymax = peakRange[1]; - xmin = low_res_min; - xmax = low_res_max; - } - - if (getProperty("SubtractNormBackground")) { - // Get background range - const std::vector<int> bckRange = getProperty("NormBackgroundPixelRange"); - if (bckRange.size() < 2) { - g_log.error() << "NormBackgroundPixelRange parameter should be a vector " - "of two values\n"; - throw std::invalid_argument("NormBackgroundPixelRange parameter should " - "be a vector of two values"); - } - - IAlgorithm_sptr convAlg = - createChildAlgorithm("ConvertToMatrixWorkspace", 0.50, 0.55); - convAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", normWS); - convAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", normWS); - convAlg->executeAsChildAlg(); - - normWS = - subtractBackground(normWS, normWS, peakRange[0], peakRange[1], - bckRange[0], bckRange[1], low_res_min, low_res_max); - m_output_message += " |Subtracted background [" + - Poco::NumberFormatter::format(bckRange[0]) + ", " + - Poco::NumberFormatter::format(bckRange[1]) + "]\n"; - } - IAlgorithm_sptr refAlg = createChildAlgorithm("RefRoi", 0.6, 0.65); - refAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", normWS); - refAlg->setProperty("NXPixel", NX_PIXELS); - refAlg->setProperty("NYPixel", NY_PIXELS); - refAlg->setProperty("ConvertToQ", false); - refAlg->setProperty("SumPixels", true); - refAlg->setProperty("NormalizeSum", true); - refAlg->setProperty("AverageOverIntegratedAxis", integrateY); - refAlg->setProperty("YPixelMin", ymin); - refAlg->setProperty("YPixelMax", ymax); - refAlg->setProperty("XPixelMin", xmin); - refAlg->setProperty("XPixelMax", xmax); - refAlg->setProperty("IntegrateY", integrateY); - refAlg->executeAsChildAlg(); - - MatrixWorkspace_sptr outputNormWS = refAlg->getProperty("OutputWorkspace"); - return outputNormWS; -} - -IEventWorkspace_sptr RefReduction::loadData(const std::string dataRun, - const std::string polarization) { - const std::string instrument = getProperty("Instrument"); - - // Check whether dataRun refers to an existing workspace - // Create a good name for the raw workspace - std::string ws_name = "__ref_" + dataRun + "-" + polarization + "_raw"; - IEventWorkspace_sptr rawWS; - if (AnalysisDataService::Instance().doesExist(dataRun)) { - rawWS = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(dataRun); - g_log.notice() << "Found workspace: " << dataRun << '\n'; - m_output_message += " |Input data run is a workspace: " + dataRun + "\n"; - } else if (AnalysisDataService::Instance().doesExist(ws_name)) { - rawWS = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(ws_name); - g_log.notice() << "Using existing workspace: " << ws_name << '\n'; - m_output_message += - " |Found workspace from previous reduction: " + ws_name + "\n"; - } else { - // If we can't find a workspace, find a file to load - std::string path = FileFinder::Instance().getFullPath(dataRun); - - if (path.empty() || !Poco::File(path).exists()) { - try { - std::vector<std::string> paths = - FileFinder::Instance().findRuns(instrument + dataRun); - path = paths[0]; - } catch (Exception::NotFoundError &) { /* Pass. We report the missing file - later. */ - } - } - - if (path.empty() || !Poco::File(path).exists()) { - try { - std::vector<std::string> paths = - FileFinder::Instance().findRuns(dataRun); - path = paths[0]; - } catch (Exception::NotFoundError &) { /* Pass. We report the missing file - later. */ - } - } - - if (Poco::File(path).exists()) { - g_log.notice() << "Found: " << path << '\n'; - m_output_message += " |Loading from " + path + "\n"; - IAlgorithm_sptr loadAlg = createChildAlgorithm("LoadEventNexus", 0, 0.2); - loadAlg->setProperty("Filename", path); - if (polarization != PolStateNone) - loadAlg->setProperty("NXentryName", polarization); - try { - loadAlg->executeAsChildAlg(); - } catch (...) { - g_log.notice() << "Could not load polarization " << polarization; - return nullptr; - } - - Workspace_sptr temp = loadAlg->getProperty("OutputWorkspace"); - rawWS = boost::dynamic_pointer_cast<IEventWorkspace>(temp); - if (rawWS->getNumberEvents() == 0) { - g_log.notice() << "No data in " << polarization << '\n'; - m_output_message += " |No data for " + polarization + "\n"; - return rawWS; - } - - // Move the detector to the right position - if (instrument == "REF_M") { - const auto &detInfo = rawWS->detectorInfo(); - const size_t detIndex0 = detInfo.indexOf(0); - double det_distance = detInfo.position(detIndex0).Z(); - auto dp = rawWS->run().getTimeSeriesProperty<double>("SampleDetDis"); - double sdd = dp->getStatistics().mean / 1000.0; - IAlgorithm_sptr mvAlg = - createChildAlgorithm("MoveInstrumentComponent", 0.2, 0.25); - mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", rawWS); - mvAlg->setProperty("ComponentName", "detector1"); - mvAlg->setProperty("Z", sdd - det_distance); - mvAlg->setProperty("RelativePosition", true); - mvAlg->executeAsChildAlg(); - g_log.notice() << "Ensuring correct Z position: Correction = " - << Poco::NumberFormatter::format(sdd - det_distance) - << " m\n"; - } - AnalysisDataService::Instance().addOrReplace(ws_name, rawWS); - } else { - g_log.error() << "Could not find a data file for " << dataRun << '\n'; - throw std::invalid_argument( - "Could not find a data file for the given input"); - } - } - - // Crop TOF as needed and set binning - double tofMin = getProperty("TOFMin"); - double tofMax = getProperty("TOFMax"); - if (isEmpty(tofMin) || isEmpty(tofMax)) { - const auto &x = rawWS->x(0); - if (isEmpty(tofMin)) - tofMin = *std::min_element(x.begin(), x.end()); - if (isEmpty(tofMax)) - tofMax = *std::max_element(x.begin(), x.end()); - } - - int nBins = getProperty("NBins"); - double tofStep = getProperty("TOFStep"); - if (!isEmpty(nBins)) - tofStep = (tofMax - tofMin) / nBins; - else - nBins = static_cast<int>(floor((tofMax - tofMin) / tofStep)); - - std::vector<double> params; - params.push_back(tofMin); - params.push_back(tofStep); - params.push_back(tofMax); - - IAlgorithm_sptr rebinAlg = createChildAlgorithm("Rebin", 0.25, 0.3); - rebinAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", rawWS); - rebinAlg->setProperty("Params", params); - rebinAlg->setProperty("PreserveEvents", true); - rebinAlg->executeAsChildAlg(); - MatrixWorkspace_sptr outputWS = rebinAlg->getProperty("OutputWorkspace"); - m_output_message += " |TOF binning: " + - Poco::NumberFormatter::format(tofMin) + " to " + - Poco::NumberFormatter::format(tofMax) + " in steps of " + - Poco::NumberFormatter::format(tofStep) + " microsecs\n"; - - // Normalise by current - IAlgorithm_sptr normAlg = - createChildAlgorithm("NormaliseByCurrent", 0.3, 0.35); - normAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS); - normAlg->executeAsChildAlg(); - outputWS = normAlg->getProperty("OutputWorkspace"); - - // Convert to wavelength - IAlgorithm_sptr convAlg = createChildAlgorithm("ConvertUnits", 0.35, 0.4); - convAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS); - convAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS); - convAlg->setProperty("Target", "Wavelength"); - convAlg->executeAsChildAlg(); - - // Rebin in wavelength - const auto &x = outputWS->x(0); - double wlMin = *std::min_element(x.begin(), x.end()); - double wlMax = *std::max_element(x.begin(), x.end()); - - std::vector<double> wl_params; - wl_params.push_back(wlMin); - wl_params.push_back((wlMax - wlMin) / nBins); - wl_params.push_back(wlMax); - - IAlgorithm_sptr rebinAlg2 = createChildAlgorithm("Rebin", 0.25, 0.3); - rebinAlg2->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS); - rebinAlg2->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS); - rebinAlg2->setProperty("Params", wl_params); - rebinAlg2->setProperty("PreserveEvents", true); - rebinAlg2->executeAsChildAlg(); - - IEventWorkspace_sptr outputEvtWS = - boost::dynamic_pointer_cast<IEventWorkspace>(outputWS); - return outputEvtWS; -} - -double RefReduction::calculateAngleREFM(MatrixWorkspace_sptr workspace) { - double dangle = getProperty("DetectorAngle"); - if (isEmpty(dangle)) { - Mantid::Kernel::Property *prop = workspace->run().getProperty("DANGLE"); - if (!prop) - throw std::runtime_error("DetectorAngle property not given as input, and " - "could not find the log entry DANGLE either"); - Mantid::Kernel::TimeSeriesProperty<double> *dp = - dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double> *>(prop); - if (!dp) - throw std::runtime_error( - "The log entry DANGLE could not" - "be interpreted as a property of type time series of double"); - dangle = dp->getStatistics().mean; - } - - double dangle0 = getProperty("DetectorAngle0"); - if (isEmpty(dangle0)) { - Mantid::Kernel::Property *prop = workspace->run().getProperty("DANGLE0"); - if (!prop) - throw std::runtime_error("DetectorAngle0 property not given aas input, " - "and could not find the log entry DANGLE0 " - "either"); - Mantid::Kernel::TimeSeriesProperty<double> *dp = - dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double> *>(prop); - if (!dp) - throw std::runtime_error( - "The log entry DANGLE0 could not " - "be interpreted as a property of type time series of double values"); - dangle0 = dp->getStatistics().mean; - } - - Mantid::Kernel::Property *prop = workspace->run().getProperty("SampleDetDis"); - Mantid::Kernel::TimeSeriesProperty<double> *dp = - dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double> *>(prop); - if (!dp) - throw std::runtime_error("SampleDetDis was not a TimeSeriesProperty"); - const double det_distance = dp->getStatistics().mean / 1000.0; - - double direct_beam_pix = getProperty("DirectPixel"); - if (isEmpty(direct_beam_pix)) { - auto dp = workspace->run().getTimeSeriesProperty<double>("DIRPIX"); - direct_beam_pix = dp->getStatistics().mean; - } - - double ref_pix = getProperty("ReflectivityPixel"); - if (ref_pix == 0 || isEmpty(ref_pix)) { - const std::vector<int> peakRange = getProperty("SignalPeakPixelRange"); - if (peakRange.size() < 2) { - g_log.error() << "SignalPeakPixelRange parameter should be a vector of " - "two values\n"; - throw std::invalid_argument( - "SignalPeakPixelRange parameter should be a vector of two values"); - } - ref_pix = (peakRange[0] + peakRange[1]) / 2.0; - } - - double theta = - (dangle - dangle0) * M_PI / 180.0 / 2.0 + - ((direct_beam_pix - ref_pix) * PIXEL_SIZE) / (2.0 * det_distance); - - return theta * 180.0 / M_PI; -} - -double RefReduction::calculateAngleREFL(MatrixWorkspace_sptr workspace) { - auto dp = workspace->run().getTimeSeriesProperty<double>("ths"); - const double ths = dp->getStatistics().mean; - - dp = workspace->run().getTimeSeriesProperty<double>("tthd"); - const double tthd = dp->getStatistics().mean; - - double offset = getProperty("AngleOffset"); - if (isEmpty(offset)) - offset = 0.0; - return tthd - ths + offset; -} - -MatrixWorkspace_sptr RefReduction::subtractBackground( - MatrixWorkspace_sptr dataWS, MatrixWorkspace_sptr rawWS, int peakMin, - int peakMax, int bckMin, int bckMax, int lowResMin, int lowResMax) { - const std::string instrument = getProperty("Instrument"); - const bool integrateY = instrument == "REF_M"; - - int xmin = 0; - int xmax = 0; - int ymin = 0; - int ymax = 0; - if (integrateY) { - ymin = lowResMin; - ymax = lowResMax; - } else { - xmin = lowResMin; - xmax = lowResMax; - } - - // Look for overlap with data peak - if (bckMin < peakMin && bckMax > peakMax) { - // Background on the left - if (integrateY) { - xmin = bckMin; - xmax = peakMin - 1; - } else { - ymin = bckMin; - ymax = peakMin - 1; - } - IAlgorithm_sptr leftAlg = createChildAlgorithm("RefRoi", 0.6, 0.65); - leftAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", rawWS); - leftAlg->setProperty("NXPixel", NX_PIXELS); - leftAlg->setProperty("NYPixel", NY_PIXELS); - leftAlg->setProperty("ConvertToQ", false); - leftAlg->setProperty("SumPixels", true); - leftAlg->setProperty("NormalizeSum", true); - leftAlg->setProperty("AverageOverIntegratedAxis", integrateY); - leftAlg->setProperty("YPixelMin", ymin); - leftAlg->setProperty("YPixelMax", ymax); - leftAlg->setProperty("XPixelMin", xmin); - leftAlg->setProperty("XPixelMax", xmax); - leftAlg->setProperty("IntegrateY", integrateY); - leftAlg->executeAsChildAlg(); - - MatrixWorkspace_sptr leftWS = leftAlg->getProperty("OutputWorkspace"); - - // Background on the right - if (integrateY) { - xmin = peakMax + 1; - xmax = bckMax; - } else { - ymin = peakMax + 1; - ymax = bckMax; - } - IAlgorithm_sptr rightAlg = createChildAlgorithm("RefRoi", 0.6, 0.65); - rightAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", rawWS); - rightAlg->setProperty("NXPixel", NX_PIXELS); - rightAlg->setProperty("NYPixel", NY_PIXELS); - rightAlg->setProperty("ConvertToQ", false); - rightAlg->setProperty("SumPixels", true); - rightAlg->setProperty("NormalizeSum", true); - rightAlg->setProperty("AverageOverIntegratedAxis", integrateY); - rightAlg->setProperty("YPixelMin", ymin); - rightAlg->setProperty("YPixelMax", ymax); - rightAlg->setProperty("XPixelMin", xmin); - rightAlg->setProperty("XPixelMax", xmax); - rightAlg->setProperty("IntegrateY", integrateY); - rightAlg->executeAsChildAlg(); - - MatrixWorkspace_sptr rightWS = rightAlg->getProperty("OutputWorkspace"); - - // Average the two sides and subtract from peak - dataWS = dataWS - (leftWS + rightWS) / 2.0; - return dataWS; - - } else { - - // Check for overlaps - if (bckMax > peakMin && bckMax < peakMax) { - g_log.notice() << "Background range overlaps with peak\n"; - bckMax = peakMin - 1; - } - if (bckMin < peakMax && bckMin > peakMin) { - g_log.notice() << "Background range overlaps with peak\n"; - bckMin = peakMax + 1; - } - - if (integrateY) { - xmin = bckMin; - xmax = bckMax; - } else { - ymin = bckMin; - ymax = bckMax; - } - - IAlgorithm_sptr refAlg = createChildAlgorithm("RefRoi", 0.6, 0.65); - refAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", rawWS); - refAlg->setProperty("NXPixel", NX_PIXELS); - refAlg->setProperty("NYPixel", NY_PIXELS); - refAlg->setProperty("ConvertToQ", false); - refAlg->setProperty("SumPixels", true); - refAlg->setProperty("NormalizeSum", true); - refAlg->setProperty("AverageOverIntegratedAxis", integrateY); - refAlg->setProperty("YPixelMin", ymin); - refAlg->setProperty("YPixelMax", ymax); - refAlg->setProperty("XPixelMin", xmin); - refAlg->setProperty("XPixelMax", xmax); - refAlg->setProperty("IntegrateY", integrateY); - refAlg->executeAsChildAlg(); - - MatrixWorkspace_sptr cropWS = refAlg->getProperty("OutputWorkspace"); - - dataWS = dataWS - cropWS; - return dataWS; - } -} - -} // namespace Algorithms -} // namespace Mantid diff --git a/MantidPlot/src/ApplicationWindow.cpp b/MantidPlot/src/ApplicationWindow.cpp index 62178973d75..0da334bba9e 100644 --- a/MantidPlot/src/ApplicationWindow.cpp +++ b/MantidPlot/src/ApplicationWindow.cpp @@ -9825,9 +9825,10 @@ void ApplicationWindow::closeEvent(QCloseEvent *ce) { delete scriptingWindow; scriptingWindow = nullptr; } - /// Ensure interface python references are cleaned up before the interpreter - /// shuts down + // Ensure all python references are cleaned up before the interpreter shuts + // down delete m_iface_script; + delete m_interpreterDock; // Emit a shutting_down() signal that can be caught by // independent QMainWindow objects to know when MantidPlot diff --git a/Testing/SystemTests/tests/analysis/REFLReduction.py b/Testing/SystemTests/tests/analysis/REFLReduction.py deleted file mode 100644 index 695a73a25b6..00000000000 --- a/Testing/SystemTests/tests/analysis/REFLReduction.py +++ /dev/null @@ -1,44 +0,0 @@ -#pylint: disable=no-init,attribute-defined-outside-init -import stresstesting -from mantid import * -from mantid.simpleapi import * - - -class REFLReduction(stresstesting.MantidStressTest): - def runTest(self): - #TODO: The reduction algorithm should not require an absolute path - scaling_factor_file = FileFinder.getFullPath("directBeamDatabaseFall2014_IPTS_11601_2.cfg") - - RefLReduction(RunNumbers=[119814], - NormalizationRunNumber=119690, - SignalPeakPixelRange=[154, 166], - SubtractSignalBackground=True, - SignalBackgroundPixelRange=[151, 169], - NormFlag=True, - NormPeakPixelRange=[154, 160], - NormBackgroundPixelRange=[151, 163], - SubtractNormBackground=True, - LowResDataAxisPixelRangeFlag=True, - LowResDataAxisPixelRange=[99, 158], - LowResNormAxisPixelRangeFlag=True, - LowResNormAxisPixelRange=[98, 158], - TOFRange=[29623.0, 42438.0], - IncidentMediumSelected='2InDiamSi', - GeometryCorrectionFlag=False, - QMin=0.005, - QStep=0.01, - AngleOffset=0.009, - AngleOffsetError=0.001, - ScalingFactorFile=scaling_factor_file, - SlitsWidthFlag=True, - OutputWorkspace='reflectivity_119814') - - def validate(self): - # Be more tolerant with the output. - self.tolerance = 0.0001 - - self.disableChecking.append('Instrument') - self.disableChecking.append('Sample') - self.disableChecking.append('SpectraMap') - self.disableChecking.append('Axes') - return "reflectivity_119814", 'REFL_119814_combined_data.nxs' diff --git a/Testing/SystemTests/tests/analysis/REFLWithBackground.py b/Testing/SystemTests/tests/analysis/REFLWithBackground.py deleted file mode 100644 index 356ebf18a0e..00000000000 --- a/Testing/SystemTests/tests/analysis/REFLWithBackground.py +++ /dev/null @@ -1,44 +0,0 @@ -#pylint: disable=no-init,attribute-defined-outside-init -import stresstesting -from mantid import * -from mantid.simpleapi import * - - -class REFLWithBackground(stresstesting.MantidStressTest): - def runTest(self): - #TODO: The reduction algorithm should not require an absolute path - scaling_factor_file = FileFinder.getFullPath("directBeamDatabaseFall2014_IPTS_11601_2.cfg") - - RefLReduction(RunNumbers=[119816], - NormalizationRunNumber=119692, - SignalPeakPixelRange=[155, 165], - SubtractSignalBackground=True, - SignalBackgroundPixelRange=[146, 165], - NormFlag=True, - NormPeakPixelRange=[154, 162], - NormBackgroundPixelRange=[151, 165], - SubtractNormBackground=True, - LowResDataAxisPixelRangeFlag=True, - LowResDataAxisPixelRange=[99, 158], - LowResNormAxisPixelRangeFlag=True, - LowResNormAxisPixelRange=[118, 137], - TOFRange=[9610, 22425], - IncidentMediumSelected='2InDiamSi', - GeometryCorrectionFlag=False, - QMin=0.005, - QStep=0.01, - AngleOffset=0.009, - AngleOffsetError=0.001, - ScalingFactorFile=scaling_factor_file, - SlitsWidthFlag=True, - OutputWorkspace='reflectivity_119816') - - def validate(self): - # Be more tolerant with the output. - self.tolerance = 0.0001 - - self.disableChecking.append('Instrument') - self.disableChecking.append('Sample') - self.disableChecking.append('SpectraMap') - self.disableChecking.append('Axes') - return "reflectivity_119816", 'REFL_119816.nxs' diff --git a/Testing/SystemTests/tests/analysis/REFMReduction.py b/Testing/SystemTests/tests/analysis/REFMReduction.py deleted file mode 100644 index 0174b83145e..00000000000 --- a/Testing/SystemTests/tests/analysis/REFMReduction.py +++ /dev/null @@ -1,36 +0,0 @@ -#pylint: disable=no-init,attribute-defined-outside-init -import stresstesting -from mantid import * - -from mantid.simpleapi import * - - -class REFMReduction(stresstesting.MantidStressTest): - def runTest(self): - RefReduction(DataRun=str(9709), - NormalizationRun=str(9684), - SignalPeakPixelRange=[216, 224], - SubtractSignalBackground=True, - SignalBackgroundPixelRange=[172, 197], - PerformNormalization=True, - NormPeakPixelRange=[226, 238], - NormBackgroundPixelRange=[130, 183], - SubtractNormBackground=False, - CropLowResDataAxis=True, - CropLowResNormAxis=False, - LowResDataAxisPixelRange = [86, 159], - NBins=40, - Theta=0.086, - PolarizedData=True, - Instrument="REF_M", - OutputWorkspacePrefix='reflectivity') - - def validate(self): - # Be more tolerant with the output, mainly because of the errors. - # The following tolerance check the errors up to the third digit. - self.tolerance = 0.25 - self.disableChecking.append('Instrument') - self.disableChecking.append('Sample') - self.disableChecking.append('SpectraMap') - self.disableChecking.append('Axes') - return "reflectivity-Off_Off", 'REFMReduction_off_off.nxs' diff --git a/Testing/SystemTests/tests/analysis/SortHKLTest.py b/Testing/SystemTests/tests/analysis/SortHKLTest.py index 31618635e17..2360e0f09ec 100644 --- a/Testing/SystemTests/tests/analysis/SortHKLTest.py +++ b/Testing/SystemTests/tests/analysis/SortHKLTest.py @@ -116,9 +116,9 @@ class SortHKLTest(HKLStatisticsTestMixin, stresstesting.MantidStressTest): centering_name = self._centering_map[space_group[0]] # pylint: disable=unused-variable - sorted_hkls, chi2, statistics = SortHKL(InputWorkspace=reflections, - PointGroup=point_group_name, - LatticeCentering=centering_name) + sorted_hkls, chi2, statistics, equivInten = SortHKL(InputWorkspace=reflections, + PointGroup=point_group_name, + LatticeCentering=centering_name) return statistics.row(0), sorted_hkls diff --git a/Testing/SystemTests/tests/analysis/VesuvioCommandsTest.py b/Testing/SystemTests/tests/analysis/VesuvioCommandsTest.py index 43d0db3aa06..54709bc9922 100644 --- a/Testing/SystemTests/tests/analysis/VesuvioCommandsTest.py +++ b/Testing/SystemTests/tests/analysis/VesuvioCommandsTest.py @@ -22,6 +22,8 @@ def _is_old_boost_version(): if any(dist): if 'Red Hat' in dist[0] and dist[1].startswith('7'): return True + if 'Scientific Linux' in dist[0] and dist[1].startswith('7'): + return True if dist[0] == 'Ubuntu' and dist[1] == '14.04': return True diff --git a/Testing/SystemTests/tests/analysis/VesuvioCorrectionsTest.py b/Testing/SystemTests/tests/analysis/VesuvioCorrectionsTest.py index a91e3fcfa21..4f1d4f67a6e 100644 --- a/Testing/SystemTests/tests/analysis/VesuvioCorrectionsTest.py +++ b/Testing/SystemTests/tests/analysis/VesuvioCorrectionsTest.py @@ -53,6 +53,8 @@ def _is_old_boost_version(): if any(dist): if 'Red Hat' in dist[0] and dist[1].startswith('7'): return True + if 'Scientific Linux' in dist[0] and dist[1].startswith('7'): + return True if dist[0] == 'Ubuntu' and dist[1] == '14.04': return True diff --git a/buildconfig/CMake/DarwinSetup.cmake b/buildconfig/CMake/DarwinSetup.cmake index 4fb0b32f855..5f18b652f2b 100644 --- a/buildconfig/CMake/DarwinSetup.cmake +++ b/buildconfig/CMake/DarwinSetup.cmake @@ -84,10 +84,18 @@ if ( NOT TARGET mantidpython ) configure_file ( ${CMAKE_MODULE_PATH}/Packaging/osx/mantidpython_osx ${CMAKE_BINARY_DIR}/mantidpython_osx_install @ONLY ) endif () + +# directives similar to linux for conda framework-only build +set ( BIN_DIR bin ) +set ( ETC_DIR etc ) +set ( LIB_DIR lib ) +set ( PLUGINS_DIR plugins ) + + ########################################################################### # Mac-specific installation setup ########################################################################### - +if ( ENABLE_MANTIDPLOT ) set ( CMAKE_INSTALL_PREFIX "" ) set ( CPACK_PACKAGE_EXECUTABLES MantidPlot ) set ( INBUNDLE MantidPlot.app/ ) @@ -199,3 +207,4 @@ set ( MACOSX_BUNDLE_ICON_FILE MantidPlot.icns ) string (REPLACE " " "" CPACK_SYSTEM_NAME ${OSX_CODENAME}) set ( CPACK_GENERATOR DragNDrop ) +endif () \ No newline at end of file diff --git a/buildconfig/CMake/GoogleTest.in b/buildconfig/CMake/GoogleTest.in index 2db620992e6..e37efa6f5bf 100644 --- a/buildconfig/CMake/GoogleTest.in +++ b/buildconfig/CMake/GoogleTest.in @@ -15,6 +15,7 @@ ExternalProject_Add(googletest PATCH_COMMAND "@GIT_EXECUTABLE@" reset --hard ${_tag} COMMAND "@GIT_EXECUTABLE@" apply --whitespace fix "@CMAKE_SOURCE_DIR@/buildconfig/CMake/googletest_override.patch" COMMAND "@GIT_EXECUTABLE@" apply --whitespace fix "@CMAKE_SOURCE_DIR@/buildconfig/CMake/googletest_static.patch" + COMMAND "@GIT_EXECUTABLE@" apply --whitespace fix "@CMAKE_SOURCE_DIR@/buildconfig/CMake/googletest_msvc_cpp11.patch" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/buildconfig/CMake/googletest_msvc_cpp11.patch b/buildconfig/CMake/googletest_msvc_cpp11.patch new file mode 100644 index 00000000000..339251b3bcb --- /dev/null +++ b/buildconfig/CMake/googletest_msvc_cpp11.patch @@ -0,0 +1,41 @@ +diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h +index 5529ba544..331483e73 100644 +--- a/googletest/include/gtest/internal/gtest-port.h ++++ b/googletest/include/gtest/internal/gtest-port.h +@@ -325,7 +325,7 @@ + // -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a + // value for __cplusplus, and recent versions of clang, gcc, and + // probably other compilers set that too in C++11 mode. +-# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L ++# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L || _MSC_VER >= 1900 + // Compiling in at least C++11 mode. + # define GTEST_LANG_CXX11 1 + # else +@@ -357,12 +357,16 @@ + #if GTEST_STDLIB_CXX11 + # define GTEST_HAS_STD_BEGIN_AND_END_ 1 + # define GTEST_HAS_STD_FORWARD_LIST_ 1 +-# define GTEST_HAS_STD_FUNCTION_ 1 ++# if !defined(_MSC_VER) || (_MSC_FULL_VER >= 190023824) // works only with VS2015U2 and better ++# define GTEST_HAS_STD_FUNCTION_ 1 ++# endif + # define GTEST_HAS_STD_INITIALIZER_LIST_ 1 + # define GTEST_HAS_STD_MOVE_ 1 + # define GTEST_HAS_STD_SHARED_PTR_ 1 + # define GTEST_HAS_STD_TYPE_TRAITS_ 1 + # define GTEST_HAS_STD_UNIQUE_PTR_ 1 ++# define GTEST_HAS_UNORDERED_MAP_ 1 ++# define GTEST_HAS_UNORDERED_SET_ 1 + #endif + + // C++11 specifies that <tuple> provides std::tuple. +@@ -660,7 +664,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; + // support TR1 tuple. libc++ only provides std::tuple, in C++11 mode, + // and it can be used with some compilers that define __GNUC__. + # if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \ +- && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600 ++ && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) \ ++ || (_MSC_VER >= 1600 && _MSC_VER < 1900) + # define GTEST_ENV_HAS_TR1_TUPLE_ 1 + # endif + diff --git a/buildconfig/Jenkins/buildscript b/buildconfig/Jenkins/buildscript index ce0f5519f11..a5b7c34ce13 100755 --- a/buildconfig/Jenkins/buildscript +++ b/buildconfig/Jenkins/buildscript @@ -14,7 +14,7 @@ SCRIPT_DIR=$(dirname "$0") ############################################################################### # System discovery ############################################################################### -if [[ ${NODE_LABELS} == *rhel7* ]] || [[ ${NODE_LABELS} == *centos7* ]]; then +if [[ ${NODE_LABELS} == *rhel7* ]] || [[ ${NODE_LABELS} == *centos7* ]] || [[ ${NODE_LABELS} == *scilin7* ]]; then ON_RHEL7=true fi if [[ ${NODE_LABELS} == *ubuntu* ]]; then @@ -25,7 +25,7 @@ if [[ ${NODE_LABELS} == *osx* ]]; then fi ############################################################################### -# All nodes currently have PARAVIEW_DIR=5.2.0 and PARAVIEW_NEXT_DIR=5.3.0-RC1 +# All nodes currently have PARAVIEW_DIR and PARAVIEW_NEXT_DIR set ############################################################################### export PARAVIEW_DIR=${PARAVIEW_DIR} @@ -68,18 +68,36 @@ fi # For pull requests decide on what to build based on changeset and Jenkins # parameters. -BUILDPKG=true -SYSTEMTESTS=false +DO_BUILD_CODE=true +DO_UNITTESTS=true +DO_DOCTESTS_USER=true +DO_BUILD_DEVDOCS=true +DO_BUILD_PKG=true +DO_SYSTEMTESTS=false if [[ ${PRBUILD} == true ]]; then - if [[ -n ${BUILD_PACKAGE} ]]; then - BUILDPKG=${BUILD_PACKAGE} + if ${SCRIPT_DIR}/check_for_changes dev-docs-only || ${SCRIPT_DIR}/check_for_changes user-docs-only; then + DO_BUILD_CODE=false + DO_UNITTESTS=false fi + DO_DOCTESTS_USER=false + DO_BUILD_DEVDOCS=false + DO_BUILD_PKG=${BUILD_PACKAGE:-false} + DO_SYSTEMTESTS=false + if [[ ${ON_RHEL7} == true ]]; then - if ${SCRIPT_DIR}/check_for_changes docs-gui-only; then - SYSTEMTESTS=false + # rhel does system testing + if ! ${SCRIPT_DIR}/check_for_changes docs-gui-only; then + DO_BUILD_PKG=true + DO_SYSTEMTESTS=true + fi + elif [[ ${ON_UBUNTU} == true ]]; then + # ubuntu does the docs build + if ${SCRIPT_DIR}/check_for_changes dev-docs-only; then + DO_BUILD_CODE=false + DO_DOCTESTS_USER=false else - BUILDPKG=true - SYSTEMTESTS=true + DO_BUILD_CODE=true # code needs to be up to date + DO_DOCTESTS_USER=true fi fi fi @@ -183,7 +201,7 @@ fi ############################################################################### # Packaging options ############################################################################### -if [[ "$BUILDPKG" == true ]]; then +if [[ ${DO_BUILD_PKG} == true ]]; then PACKAGINGVARS="-DPACKAGE_DOCS=ON" # Set some variables relating to the linux packages if [[ "${ON_MACOS}" == true ]]; then @@ -266,11 +284,13 @@ fi ############################################################################### # Build step ############################################################################### -${CMAKE_EXE} --build . -- -j${BUILD_THREADS:?} -${CMAKE_EXE} --build . --target AllTests -- -j${BUILD_THREADS:?} +if [[ ${DO_BUILD_CODE} == true ]]; then + ${CMAKE_EXE} --build . -- -j${BUILD_THREADS:?} + ${CMAKE_EXE} --build . --target AllTests -- -j${BUILD_THREADS:?} +fi ############################################################################### -# static analysis builds stop here +# Static analysis builds or stop here ############################################################################### if [[ $USE_CLANG ]] && [[ ${JOB_NAME} == *clang_tidy* ]]; then exit 0 @@ -280,30 +300,43 @@ fi ############################################################################### # Run the unit tests ############################################################################### -# Remove any Mantid.user.properties file -userprops=~/.mantid/Mantid.user.properties -rm -f $userprops -$CTEST_EXE -j${BUILD_THREADS:?} --schedule-random --output-on-failure +if [[ ${DO_UNITTESTS} == true ]]; then + # Remove any Mantid.user.properties file + userprops=~/.mantid/Mantid.user.properties + rm -f $userprops + $CTEST_EXE -j${BUILD_THREADS:?} --schedule-random --output-on-failure +fi ############################################################################### -# Run the documentation tests on Ubuntu when doing a pull request build but not for python 3. +# User Documentation ############################################################################### -if [[ ${ON_UBUNTU} == true ]] && [[ ${PRBUILD} == true ]]; then +if [[ ${DO_DOCTESTS_USER} == true ]]; then # Remove doctrees directory so it forces a full reparse. It seems that # without this newly added doctests are not executed if [ -d $BUILD_DIR/docs/doctrees ]; then - rm -rf $BUILD_DIR/docs/doctrees/* + rm -fr $BUILD_DIR/docs/doctrees/* fi # Build HTML to verify that no referencing errors have crept in. ${CMAKE_EXE} --build . --target docs-html ${CMAKE_EXE} --build . --target docs-test fi +############################################################################### +# Developer Documentation +############################################################################### +# Uncomment this when the dev-docs are ready to build without warnings +# if [[ ${DO_BUILD_DEVDOCS} == true ]]; then +# if [ -d $BUILD_DIR/dev-docs/doctree ]; then +# rm -fr $BUILD_DIR/dev-docs/doctree/* +# fi +# ${CMAKE_EXE} --build . --target dev-docs-html +# fi + ############################################################################### # Create the install kit if required. This includes building the Qt help # documentation ############################################################################### -if [[ ${BUILDPKG} == true ]]; then +if [[ ${DO_BUILD_PKG} == true ]]; then # Workaround so that the target can find the properties file # CMake doesn't easily allow environment variables on custom targets if [[ ${ON_MACOS} == true ]]; then @@ -328,7 +361,7 @@ fi # Run the system tests if required. Run from a package to have at least one # Linux checks it install okay ############################################################################### -if [[ ${SYSTEMTESTS} == true ]]; then +if [[ ${DO_SYSTEMTESTS} == true ]]; then if [[ ${PRBUILD} == true ]]; then EXTRA_ARGS="--exclude-in-pull-requests" $SCRIPT_DIR/systemtests else diff --git a/buildconfig/Jenkins/check_for_changes b/buildconfig/Jenkins/check_for_changes index 27e070d4afe..8c51dc4e6c6 100755 --- a/buildconfig/Jenkins/check_for_changes +++ b/buildconfig/Jenkins/check_for_changes @@ -18,33 +18,35 @@ case "$TYPE" in exit $(git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.py) ;; cpp) - if $(! git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.h) - then - exit $FOUND - fi - if $(! git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.cpp) - then - exit $FOUND - fi - if $(! git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.cxx) - then + git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.h || exit $FOUND + git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.cpp || exit $FOUND + git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.cxx || exit $FOUND + git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.tcc || exit $FOUND + exit $NOTFOUND + ;; + # For the -only cases FOUND=1 means that there were other changes besides the case + # Note that these checks CANNOT be replaced with "git diff --quiet ... dev-docs" because this only + # checks if there were changes in a given directory and not if they are the ONLY changes + dev-docs-only) + if git diff --name-only ${BRANCH_TIP} ${BRANCH_BASE} -- | grep -q -E -v '^dev-docs/'; then exit $FOUND + else + exit $NOTFOUND fi - if $(! git diff --quiet ${BRANCH_TIP} ${BRANCH_BASE} -- \*\.tcc) - then + ;; + user-docs-only) + if git diff --name-only ${BRANCH_TIP} ${BRANCH_BASE} -- | grep -q -E -v '^docs/'; then exit $FOUND + else + exit $NOTFOUND fi - exit $NOTFOUND ;; docs-gui-only) - # FOUND=1 iff changes are limited to docs or GUI only - # Find all changed files and grep for required type. -v inverts match so grep=0 means - # there are other changes besides this - if git diff --name-only ${BRANCH_TIP} ${BRANCH_BASE} -- | grep -q -E -v '^docs/|^dev-docs/|^qt/|^MantidPlot/'; then - exit $FOUND - else - exit $NOTFOUND - fi + if git diff --name-only ${BRANCH_TIP} ${BRANCH_BASE} -- | grep -q -E -v '^docs/|^dev-docs/|^qt/|^MantidPlot/'; then + exit $FOUND + else + exit $NOTFOUND + fi ;; *) echo "do not have case for type \"$TYPE\"" diff --git a/buildconfig/Jenkins/jenkins-slave.sh b/buildconfig/Jenkins/jenkins-slave.sh index 8d94719c1b2..4fad34ad8a3 100755 --- a/buildconfig/Jenkins/jenkins-slave.sh +++ b/buildconfig/Jenkins/jenkins-slave.sh @@ -71,17 +71,18 @@ if [ -f ${HOME}/jenkins-linode/${JAR_FILE} ]; then elif [ -f ${HOME}/Jenkins/${JAR_FILE} ]; then JAR_FILE=${HOME}/Jenkins/${JAR_FILE} else - JAR_FILE=/tmp/${JAR_FILE} - if [ ! -f ${JAR_FILE} ]; then - echo "Downloading slave jar file to ${JAR_FILE}" + JAR_FILE_TMP=/tmp/${JAR_FILE} + if [ ! -f ${JAR_FILE_TMP} ]; then + echo "Downloading slave jar file to ${JAR_FILE_TMP}" if [ $(command -v curl) ]; then - echo "curl -o ${JAR_FILE} ${JENKINS_URL}/jnlpJars/${JAR_FILE}" - curl -o ${JAR_FILE} ${JENKINS_URL}/jnlpJars/${JAR_FILE} + echo "curl -o ${JAR_FILE_TMP} ${JENKINS_URL}/jnlpJars/${JAR_FILE}" + curl -o ${JAR_FILE_TMP} ${JENKINS_URL}/jnlpJars/${JAR_FILE} else echo "Need curl to download ${JENKINS_URL}/jnlpJars/${JAR_FILE}" exit -1 fi fi + JAR_FILE=${JAR_FILE_TMP} fi echo "starting ..." diff --git a/buildconfig/class_maker.py b/buildconfig/class_maker.py index e00641cfbc6..5c02dcada8e 100755 --- a/buildconfig/class_maker.py +++ b/buildconfig/class_maker.py @@ -254,7 +254,7 @@ def write_rst(subproject, classname, filename, args): .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/dev-docs/source/AutomatedBuildProcess.rst b/dev-docs/source/AutomatedBuildProcess.rst new file mode 100644 index 00000000000..09fd38e6887 --- /dev/null +++ b/dev-docs/source/AutomatedBuildProcess.rst @@ -0,0 +1,70 @@ +=========================== +The Automated Build Process +=========================== + +.. contents:: Contents + :local: + +Summary +^^^^^^^ + +If your changes break the master builds in any way, on any platform, +then it is your responsibility to fix the error immediately! + +The Details +^^^^^^^^^^^ + +You should follow the :ref:`GitWorkflow`. When you open a +pull request (or commit to an already open pull request) the automated +build process will start. There will be a different build for each +platform/job. A status will appear for each job in the pull request. + +The status for each build will be either pending, success or failed. + +.. image:: images/BuildStatuses.png + +To see the details of a particular build in Jenkins click on Details +next to the status. To restart a build, if it failed with a spurious +error not related to your code changes, then you can restart that +particular build by selecting Rebuild in Jenkins. Then press rebuild +again on the next screen while not changing any of the parameters. If +you don't have permission to restart builds in Jenkins you will have +to ask someone who does. + +.. image:: images/RestartBuild.png + +Other Notes +^^^^^^^^^^^ + +The build will fail if it cannot be cleanly merged with master. + +Leeroy will check every 10 minutes for any missed builds, should the +GitHub hooks fail to activate or the build server was down when the +pull request was opened. + +The pull request builder we are using is called `Leeroy +<https://github.com/mantidproject/leeroy>`_. + +You can find a list of all the pull request Jenkins jobs at `here +<http://builds.mantidproject.org/view/Pull%20Requests/>`_. + +Master Pipeline +^^^^^^^^^^^^^^^ + +The `master pipeline <http://builds.mantidproject.org/view/Master%20Pipeline/>`_ +is a series of jobs that periodically run against code on the ``master`` branch. +Their purpose is to provide reasonable assurance that the code currently in +``master`` is usable in its current state. + +The main tasks carried out by the pipeline are, for each supported platform: + +* Build Mantid and installers (``master_clean-PLATFORM``) +* Run automated testing (``master_clean-PLATFORM``, + ``master_systemtests-PLATFORM``, ``master_doctests``) +* Deploy installers to nightly download locations (``master_deploy``) + +The pipeline view in Jenkins shows the order of dependency between these jobs. + +The most upstream jobs (i.e. ``master_clean-PLATFORM``) are triggered to start +at midnight UTC assuming there were changes pushed to the ``master`` branch +since the last time they ran. diff --git a/dev-docs/source/BuildingOnOSX.rst b/dev-docs/source/BuildingOnOSX.rst new file mode 100644 index 00000000000..092a7724e68 --- /dev/null +++ b/dev-docs/source/BuildingOnOSX.rst @@ -0,0 +1,440 @@ +.. _BuildingOnOSX: + +================ +Building on OS X +================ + +.. contents:: + :local: + +The following are instructions to build on various versions of OS X: + +################################## +OS X 10.9 using clang and macports +################################## + +*Disclaimer* + +This instruction considers that you either use macports or need them for your other development projects. It also +considers that you need to compile Mantid by yourself. In other cases please either `download a Mantid dmg package <http://download.mantidproject.org/>`_ or follow the instructions below. Warning: +it is not recommended to have both, homebrew and macports installed simultaneously on one mac. + +Instruction +----------- +1. Install Xcode and macports following the instructions on https://guide.macports.org/chunked/installing.html if needed. + +2. Install Mantid prerequisites via ``sudo port install package_name`` + +3. Things to take care about: + +- By default, POCO libraries in macports are missing libCrypto and libNetSSL. If you have the POCO libraries already installed, uninstall them: ``sudo port uninstall poco``, then install as: ``sudo port install poco +ssl``. +- Install OpenCascade libraries as: ``sudo port install oce -tbb``. + +- libNeXus: macports do not contain libNeXus. + + 1. Download the source code from the `NeXus developers website <http://download.nexusformat.org/kits/>`_. + 2. Build and install it: + + .. code-block:: sh + + % ./configure --prefix=/opt/local + % make + % sudo make install + + You may need to install additional packages to be able to build libNeXus. + + 3. libNeXus must be recompiled after update of the macports if it's dependencies have been updated. Otherwise it may depend on some non-existent libraries. + +- jsoncpp: ``mantid/Code/Mantid/Framework/DataObjects/src/NoShape.cpp`` line 3 contains: ``#include <jsoncpp/json/json.h>`` but in macports there is no ``jsoncpp`` folder in the ``/opt/local/include``, ``json.h`` is located in ``/opt/local/include/json``. As a temporary solution, you may create a symbolic link: + + .. code-block:: sh + + % sudo mkdir /opt/local/include/jsoncpp + % cd /opt/local/include/jsoncpp + % sudo ln -s ../json + +4. Run cmake. It may be needed to specify the compiler as well as the path to include files. I use the following cmake options: + +.. code-block:: sh + + cmake -DCMAKE_C_COMPILER=/usr/bin/clang \ + -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -G 'Unix Makefiles' \ + -DCMAKE_PREFIX_PATH=/opt/local \ + -DCMAKE_BUILD_TYPE=Release \ + -DENABLE_CPACK=True \ + -DPOCO_INCLUDE_DIR=/opt/local/include \ + -DQWTPLOT3D_INCLUDE_DIR=/opt/local/include/qwtplot3d \ + -DJSONCPP_INCLUDE_DIR=/opt/local/include \ + -DOPENCASCADE_INCLUDE_DIR=/opt/local/include/oce \ + -DPYTHON_INCLUDE_DIR=/opt/local/Library/Frameworks/Python.framework/Headers \ + -DSIP_INCLUDE_DIR=/opt/local/Library/Frameworks/Python.framework/Headers \ + -DPYTHON_NUMPY_INCLUDE_DIR=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/core/include \ + -DPYTHON_EXECUTABLE=/opt/local/bin/python \ + -DPYLINT_EXECUTABLE=/opt/local/bin/pylint-2.7 \ + -DSPHINX_EXECUTABLE=/opt/local/bin/sphinx-build-2.7 \ + -DPACKAGE_DOCS=FALSE \ + -DDOCS_HTML=TRUE \ + -DPYQT4_PATH=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/PyQt4 \ + -DSITEPACKAGES_PATH=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages \ + -DOPENSSL_ROOT_DIR=/opt/local \ + -DMAKE_VATES=FALSE \ + -DMACPORTS=TRUE \ + -DCMAKE_INSTALL_PREFIX=path_where_to_install_mantid /path_to_repository/mantid/Code/Mantid + +5. Pay attention that packaging of the documentation is switched off. I did not manage to build it for the moment. +6. Build mantid running ``make`` or ``make -j number_of_threads`` +7. You may create the dmg package running the ``make package`` command +8. You may also install Mantid using the ``make install`` command. *Warning*: if you do not want to install Mantid in /Applications, correct the CMAKE_INSTALL_PREFIX in the ``cmake_install.cmake`` file in your build directory. + +Building VATES +-------------- +Starting from Mantid 3.4, it is possible to build it with VATES support using macports. + +1. Build Paraview using the following instruction: :ref:`BuildingVATES`. + +2. Set cmake option ``-DMAKE_VATES=TRUE`` + +3. Set path to the paraview build directory: ``-DParaView_DIR=/put_your_path_here`` + +4. Run steps 6-7(8) to build/install Mantid + + +########################################## +OS X 10.10 and 10.11 using clang and Xcode +########################################## +These instructions are from the assumptions of a blank newly installed Mac and want to use the system python. Other python distributions may work but have not been tested. + +1. First install Xcode and then clone the mantid git repository. + +- The last version to support OS X Mavericks is Xcode 6.2 +- The last version to support OS X Yosemite is Xcode 7.2.1 +- As of August 1, 2016, our OS X El Capitan build server is running Xcode 7.3.1 + +2. Install Apple's Command Line tools (without this then /usr/include will not exist) + +.. code-block:: sh + + xcode-select --install + +2. Install `Homebrew <http://brew.sh>`_. If you already have Homebrew and are upgrading the OS follow the `instructions here <http://ryantvenge.com/2014/09/ruby-homebrea-yosemite/>`_: + +.. code-block:: sh + + ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" + +3. Add the necessary 'taps'. The last 4 are to use qt4. + +In order to be able to 'tap' the ``mantidproject/mantid`` 'tap' we need to have a couple of packages installed + +.. code-block:: sh + + brew install git + brew install git-lfs + + brew tap homebrew/science + brew tap mantidproject/mantid + brew tap caskroom/cask + brew tap cartr/qt4 + brew tap-pin cartr/qt4 + +5. Install required dependencies (will make a mantid-developer formula soon) + If you plan on distributing your application bundle, change ``brew install`` to ``brew install --build-bottle`` + +.. code-block:: sh + + brew cask install xquartz + # mactex is optional, needed for parsing equations in qthelp documentation. + brew cask install mactex + brew install openssl + brew install cmake + brew install qt@4 --with-qt3support --build-bottle + # sip,pyqt and qscintilla2 bring in homebrew's python if + # installed with --build-bottle. And add --build-from-source. + brew install sip --build-from-source --without-python3 + brew install pyqt@4 --build-from-source --without-python3 + brew install qscintilla2qt4 --build-from-source + brew install qt --build-bottle + brew install pyqt --build-from-source + brew install qscintilla2 --build-from-source --without-python3 + brew install poco --c++11 + brew install boost --c++11 + # boost-python brings in homebrew's python if installed with --build-bottle. + brew install boost-python --c++11 --build-from-source + brew install gsl + brew install hdf5 --c++11 + brew install libmxml + brew install muparser + #Several unit tests fail with NeXus v4.4.2 + #https://github.com/mantidproject/mantid/issues/17001 + brew install nexusformat --c++11 + brew install jsoncpp + brew install tbb --c++11 + brew install opencascade --build-bottle + brew install qwt5 + brew install qwtplot3d + brew install google-perftools + brew install librdkafka + +6. Uninstall homebrew Python that some of the dependencies insist on installing + +.. code-block:: sh + + brew uninstall python + +6. Optional: for cmake-gui + +.. code-block:: sh + + brew cask install cmake + +7. Now to install the other python package dependencies: + +.. code-block:: sh + + sudo easy_install pip + sudo -H pip install sphinx + # https://github.com/mantidproject/mantid/issues/13481 + sudo -H pip install "ipython[notebook]==3.2.1" + # qtconsole only required with ipython 4+ + #sudo -H pip install qtconsole + sudo -H pip install qtpy + sudo -H pip install pygments + sudo -H pip install pyzmq + sudo -H pip install pycifrw + # Version matches Windows/RHEL/Ubuntu (trusty) + sudo -H pip install PyYAML==3.10 + # Version matches Windows/RHEL/Ubuntu (trusty) + sudo -H pip install mock==1.0.1 + +8. Install the theme for sphinx + +.. code-block:: sh + + sudo pip install sphinx_bootstrap_theme + +9. Install other python dependencies + + +.. code-block:: sh + + sudo pip install psutil + brew install h5py + +9. Add Homebrew’s site-packages to your python path. + +.. code-block:: sh + + mkdir -p ~/Library/Python/2.7/lib/python/site-packages + echo '/usr/local/lib/python2.7/site-packages' > ~/Library/Python/2.7/lib/python/site-packages/homebrew.pth + +10. Now you need to patch a header in your python! + +- If building on the command line with make or ninja. + + .. code-block:: sh + + cd /usr/include/python2.7 + + or + + .. code-block:: sh + + cd /System/Library/Frameworks/Python.framework/Headers + + then + + .. code-block:: sh + + sudo cp pyport.h pyport.h.original + sudo patch pyport.h $MANTIDCHECKOUTROOT/buildconfig/pyport.patch + +- If building with Xcode on OS X Yosemite + + .. code-block:: sh + + cd /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 + + + then + + .. code-block:: sh + + sudo cp pyport.h pyport.h.original + sudo patch pyport.h $MANTIDCHECKOUTROOT/buildconfig/pyport.patch + + **Note**: If Xcode updates for any reason, the patch will be lost. + + +11. Now run CMake and select the Xcode generator with the default native compilers. + +12. Now open the project in Xcode (doing this from the command line to ensure the PYTHONPATH is correctly picked up by Xcode). + + .. code-block:: sh + + cd /path/to/my/build/dir + open Mantid.xcodeproj + +Troubleshooting +--------------- +1. The main problem that can arise is due to python path issues. This usually either arises at the CMake or Run from Xcode steps. It is because the PYTHONPATH is not being picked up. +2. If you have upgraded to Mavericks (OS X 10.9) from a previous version of OS X with homebrew already installed then you may encounter some issues related to the fact that the default std lib has changed. The easiest way to avoid this is to remove and then re-install all your formulas. +3. You may find that if you build the ``MantidPlot`` target then you will get errors when you run, such as *Can't start python* and *Cannot load Curve Fitting Plugins*, this is due to the fact that the MantidPlot target does not contain all the dependencies. You are best, if you are unsure of the hierarchy, to just use the ALL_BUILD target and then just switch to the MantidPlot target in order to run. +4. NOTE that you might need to run ``./MantidPlot.app/Contents/MacOS/MantidPlot`` from the ``BUILD-DIR/bin`` (instead of ``open MantidPlot.app`` OR ``./MantidPlot`` from ``BUILD-DIR/bin/MantidPlot.app/Contents/MacOS/``) to get the library paths correct. Otherwise the issues above might show up (at least on OS X 10.11 El Capitan). +5. Upgrading HDF5 requires also rebuilding nexusformat, h5py, and ParaView. + + +########## +OS X 10.12 +########## +The following instructions setup the build environment for mantid using clang compiler and python provided by the system, and all the other dependencies installed with brew. The drawback is that one has little control over python version and OpenMP will not be found. Make sure you have Qt Creator IDE and optionally cmake (GUI) app installed. + +1. Install Xcode from AppStore +2. Install Xcode command line tools + +.. code-block:: sh + + xcode-select --install + +3. Install home-brew package manager + +.. code-block:: sh + + ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" + +4. Add the necessary 'taps' + +In order to be able to 'tap' the `mantidproject/mantid` 'tap' we need to have a couple of packages installed + +.. code-block:: sh + + brew install git + brew install git-lfs + + brew tap mantidproject/mantid + brew tap caskroom/cask + brew tap cartr/qt4 + brew tap-pin cartr/qt4 + +5. Install the necessary dependencies. Note that some of these will bring brew python with them as dependency. + +.. code-block:: sh + + brew cask install xquartz + brew cask install mactex + brew install openssl + brew install cmake + brew install ninja --without-test + brew install qt@4 --build-bottle + brew install sip --build-from-source --without-python + brew install pyqt@4 --build-from-source + brew install qscintilla2qt4 --build-from-source --without-python + brew install qt --build-bottle + brew install pyqt --build-from-source + brew install qscintilla2 --build-from-source --without-python + brew install poco + brew install boost --c++11 + brew install boost-python --c++11 --build-from-source + brew install gsl + brew install gcc + brew install hdf5 --c++11 + brew install libmxml + brew install muparser + brew install nexusformat --c++11 + brew install jsoncpp + brew install tbb --c++11 + brew install opencascade --build-bottle + brew install qwt5 + brew install qwtplot3d + brew install google-perftools + brew install librdkafka + +If, while configuring Mantid, cmake complains that it cannot find sip, uninstall the package by ``brew uninstall --ignore-dependencies sip``, reinstall it using the line above and follow the instructions on how to add Homebrew's site-packages to Python ``sys.path``. + + +6. Uninstall the brew python if it has been previously installed + +.. code-block:: sh + + brew uninstall --ignore-dependencies python3 + +7. Install pip python package manager + +.. code-block:: sh + + sudo easy_install pip + +8. Install necessary python packages with pip + +.. code-block:: sh + + sudo -H pip install sphinx --ignore-installed + sudo -H pip install "ipython[notebook]==3.2.1" + sudo -H pip install qtpy + sudo -H pip install pycifrw + sudo -H pip install PyYAML==3.10 + sudo -H pip install mock==1.0.1 + sudo pip install sphinx_bootstrap_theme + sudo pip install psutil + sudo pip install qtawesome + sudo pip install "matplotlib>=2.1.2" + +9. Install h5py + +.. code-block:: sh + + brew install h5py + +10. Add Homebrew’s site-packages to your python path. + +.. code-block:: sh + + mkdir -p ~/Library/Python/2.7/lib/python/site-packages + echo '/usr/local/lib/python2.7/site-packages' > ~/Library/Python/2.7/lib/python/site-packages/homebrew.pth + +11. Git clone the mantid repository + +12. Disable the system integrity protection (SIP). To do this + + - restart the computer + - before the apple logo appears press `Command+R` to enter the recovery mode + - when in recovery mode, go to `Utilities>Terminal` and type + + .. code-block:: sh + + csrutil disable + + - reboot again + +13. Now that SIP is disabled we can do the necessary patch: + +.. code-block:: sh + + cd /usr/include/python2.7 + sudo cp pyport.h pyport.h.original + sudo patch pyport.h $MANTIDCHECKOUTROOT/buildconfig/pyport.patch + +14. Enable again the system integrity protection by repeating Step 12 and typing this time: + +.. code-block:: sh + + csrutil enable + +15. Open mantid project from Qt Creator, and you should be able to run cmake and build, given the right environment: + +.. code-block:: sh + + CC=/usr/bin/clang + CXX=/usr/bin/clang++ + PATH=/usr/local/bin/:$PATH + +Local bin contains the symlink to the brew packages, which have to come first in path, before `/usr/bin`. That's why it is important not to have python or clang (with this setup) in brew. + + +16. Add to your `.profile` + +.. code-block:: sh + + export PYTHONPATH=$BUILDMANTID/bin + + +17. You should now be able to mantid. diff --git a/dev-docs/source/BuildingVATES.rst b/dev-docs/source/BuildingVATES.rst new file mode 100644 index 00000000000..8df1e0e1c99 --- /dev/null +++ b/dev-docs/source/BuildingVATES.rst @@ -0,0 +1,121 @@ +.. _BuildingVATES: + +============== +Building VATES +============== + +.. contents:: + :local: + +What Is the VSI? +---------------- + +The VSI stands for VATES Simple Interface. This is best thought of as the way to visualise 3D+ dimensional data in Mantid. Mantid stores n dimensional data in MDWorkspaces, which may be rendered using the ParaView visualisation tools. + +How Do I Get the VSI? +--------------------- + +The VSI components are part of the Mantid distribution. + +ParaView +-------- + +The visualisation components for the VSI require the ParaView visualisation platform. However, the CMake option ``MAKE_VATES``, can be used to turn off its use. The patch files used in this section as well as build scripts for Windows & OSX/Linux which automate the steps described below can be found `here <https://github.com/mantidproject/paraview-build>`__. + +- Execute the following lines from the command prompt + +.. code-block:: sh + + git clone https://gitlab.kitware.com/paraview/paraview.git <Your ParaView source root> + cd <Your ParaView source root> + git checkout v5.4.0 + git submodule init + git submodule update + +The VSI uses a custom data array layout to minimize memory copies. The name and header must be available to ParaView at compile time. + +.. code-block:: sh + + mkdir vtkMDHWSignalArray + cd vtkMDHWSignalArray + wget https://raw.githubusercontent.com/mantidproject/paraview-build/2b28ebc5fd40ad727ca66772522bf220b834c1f7/vtkMDHWSignalArray/vtkMDHWSignalArray.h + SIGNAL_NAME=vtkArrayDispatch_extra_arrays=vtkMDHWSignalArray\<double\> + SIGNAL_HEADER=vtkArrayDispatch_extra_headers=<path to vtkMDHWSignalArray.h> + +Everyone is encouraged to apply the `additional patchfiles <https://github.com/mantidproject/paraview-build/tree/875fe2a3c800996b75591c8dbe26909b51bdf963/patches>`__ in our buildscript. + +Building ParaView +------------------ + +This is the visualisation plugins to build and use. This works on Windows/Linux/Mac. Download the source code and build using CMake out of source. You'll need the Qt development libraries, in order to build the GUI and also python. For Windows user, the Third_Party directory contains qmake as well as all the development libraries you should need to build Paraview. + +The scripts and cmake cache files used by the build servers are available `here <https://github.com/mantidproject/paraview-build/tree/875fe2a3c800996b75591c8dbe26909b51bdf963>`__. + +.. code-block:: sh + + cd <Your paraview source root> + mkdir Build + cd Build + + cmake -D$SIGNAL_NAME -D$SIGNAL_HEADER -C<path to common.cmake> -C<path to platform specific cache file> .. + cmake --build . + +Building the VSI +---------------- + +- Get Paraview (see above) +- Edit the CMake configuration for Mantid + + - Via CMake enable ``MAKE_VATES`` (If editing from the GUI, press ``Configure`` after checking this) + - Via CMake set ``ParaView_DIR`` to the directory where paraview has been built. +- Make Mantid + +This should produce the VSI related binaries for Mantid as well as plugins usable by ParaView. + +Sample Mantid cmake command +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This build command enables the VSI: + +.. code-block:: sh + + cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DMAKE_VATES=TRUE -DParaView_DIR=~/Code/paraview/build ../Code/Mantid + cmake --build . + +Additional Libraries for Paraview/Mantid +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Ubuntu: The package list from :ref:`GettingStarted` contains all the required libraries. + +Using Paraview Plugins +---------------------- + +This section will be fleshed-out or appear as a separate page in the near future. + +- Launch the Paraview GUI +- Go to Tools -> Manage Plugins and load the MantidParaview... libraries listed above (except for MantidParaViewQtWidgets) +- There are several reasons why you may get a warning symbol when you try to load the plugins (see troubleshooting) +- Of those loaded plugins, you may wish to expand them using the (+) tree and assigning them as autoload, so that they are immediately available the next time Paraview is launched. +- You can now open a sqw file in Paraview. +- Use the Rebinning Cutter filter to rebin,integrate,rearrange,slice the workspace. + +Help +---- + +We suggest contacting the core Mantid development team if any problems are experienced. + +Troubleshooting +--------------- + +- Can't load plugins + + - Have you built both Mantid and Paraview to be either Debug or Release (both the same)? + - Do you have the Mantid binaries present and in the right order in the system path (windows)? + +- Can't start-up Paraview + + - Try deleting or temporarily renaming the ParaView directory in ``%APPDATA/Roaming%`` Paraview may be crashing as it's trying to autoload plugins that are causing problems. + +- Cannot complete the loading of a file + + - Check you have ``MANTIDPATH`` set correctly. diff --git a/dev-docs/source/BuildingWithCMake.rst b/dev-docs/source/BuildingWithCMake.rst new file mode 100644 index 00000000000..e5678263fcf --- /dev/null +++ b/dev-docs/source/BuildingWithCMake.rst @@ -0,0 +1,121 @@ +.. _BuildingWithCMake: + +=================== +Building with CMake +=================== + +.. contents:: + :local: + +CMake is the build system for the entirety of Mantid (Framework, MantidQt & MantidPlot). It is used to generate native build files for your platform, which can be Makefiles (for use with make, nmake or jom) for command line builds or project/solution files for an IDE (e.g. Visual Studio, Eclipse, Qt Creator, XCode). + +Environment +########### + +The :ref:`GettingStarted` page describes how to set up your environment to build Mantid. Follow those instructions and install the Mantid dependencies first. + +Also, if you use the Ninja generator then the executable is called ``ninja-build``. + +CCache +###### + +Mantid's cmake is configure to use the `ccache <https://ccache.samba.org/>`_ tool if it is available. It is highly recommended that this be used on Linux/macOS systems. + +For Linux either run either + +.. code-block:: sh + + sudo yum install ccache + +on Red Hat, or + +.. code-block:: sh + + sudo apt-get install ccache + +on Ubuntu. + +For macOS run: + +.. code-block:: sh + + brew install ccache + +After it is installed run ``ccache --max-size=20G`` to increase the size of the cache. + +If you're build with ``ccache`` exhibits warnings that are not usually present then try setting the ``ccache --set-config=run_second_cpp="true"`` config option (or set ``CCACHE_CPP2=yes`` environment variable on older versions). + +Network Drives +-------------- + +The default location for the cache directory is ``$HOME/.ccache``. If you're home directory is on a network-mounted drive then the location of this cache be moved to provide the best performance. On newer versions of ``ccache`` run ``ccache --set-config=cache_dir=PATH_TO_CACHE``. Older versions (<3.2) do not allow this and must fall back to setting the ``CCACHE_DIR`` environment variable in your shell profile. + +Configuring your build +###################### + +CMake encourages the use of 'out of source' builds. This means that all generated files are placed in a separate directory structure to the source files. This separation makes a full clean easier (you just delete everything) and means that you can have different types of build (Release, Debug, different compiler versions, ....) in separate places (N.B. For Visual Studio & XCode, you can still select the type of build from within the IDE). + +From the command line +--------------------- + +* If wanting an out of source build, create the directory you want to build in and ``cd`` into it. +* On Windows, you may need to be in a Visual Studio Command Prompt. +* Run ``cmake /path/to/Mantid``, or to ``/path/to/Mantid/Framework`` if you only want a build of the Framework (typically not recommended, but possible nonetheless). This will generate build files using the default generator for your platform (e.g. Unix Makefiles on Linux). +* If you want to use a specific generator (run ``cmake --help`` for a list of available generators for your platform), use the ``-G`` option, e.g. ``cmake -G"NMake Makefiles" /path/to/Mantid``. +* If you want to set the build type (e.g. Release, Debug) you can run cmake with the ``-i`` option or by passing the argument ``-DCMAKE_BUILD_TYPE=Debug`` to cmake. The default is Release. +* Please note that the executable is called ``cmake3`` on Red Hat 7 / CentOS7. + +From the CMake gui +------------------ + +* The cmake gui is available from, e.g., the Windows Program menu or the command line executable ``cmake-gui``. +* Start it and click the "Browse Source" button to point to ``/path/to/Mantid``, or to ``/path/to/Mantid/Framework`` if you only want a build of the Framework (typically not recommended, but possible nonetheless). +* Click "Browse Build" and point to the directory you want to build into - it's recommended that you create a new directory for this (see above), though it can be the same as the source directory. +* Click "Configure" down near the bottom of the window. +* A new window will appear asking which 'Generator' you want to use. Choose one and click OK (N.B. VS2010 = Visual Studio 10, and note that you should append Win64 to this for a 64 bit build). +* Wait a while.... +* You will be presented with a list of options in red that can in principle be changed. You probably don't want to change anything, except perhaps checking "MAKE_VATES" if you want to build that. +* Click "Configure" again and wait.... +* Finally, click "Generate". This will create the build files, e.g. there will be a Mantid.sln in the directory you selected as your build directory. + +Data Files Location +------------------- + +Mantid used the CMake ExternalData system for managing testing data. See :ref:`DataFilesForTesting` for further instructions. + +With Qt Creator +--------------- + +`Qt Creator <http://qt.nokia.com/products/developer-tools/>`_ has some really nice features (it's cross-platform, you can directly open Qt Designer within it, you can highlight a Qt type and go directly to it's help page, it knows about Qt types when debugging....). +The nice feature in this context is that it has CMake support built in. So you can just open the project by pointing to the main CMakeLists file and then run CMake all within the IDE itself. + +Building and working with CMake +############################### + +* You can now start your IDE and point to or import the generated solution/project files or run ``make``, ``nmake`` or ``jom`` to build the whole of Mantid (sub-targets are available - run ``make help`` to see them). +* '''Visual Studio users''': Use the ``visual-studio.bat`` generated in the build directory to start the IDE. This sets up the environment correctly. +* You should typically never have to run CMake manually again (unless you want to create a new, separate build) - it will be run automatically if one of the CMake input files changes. +* It should be rare that you will need to edit the CMake build (``CMakeLists.txt``) files. The most common occurrence will be when you add a new file. This must be added to the corresponding CMakeLists file, e.g. if you add a file to Kernel, edit ``Mantid/Framework/Kernel/CMakeLists.txt`` to add the source, header and test files to the long lists of filepaths at the top of the file. +* The class maker utility (:ref:`ToolsOverview`) can edit the ``CMakeList.txt`` for you automatically +* There are similar places in the Qt projects for ui files and files that need moc-ing. +* If you add a new dependency, that will need to be added (this is less straightforward - do ask for help). +* Cache variables can be added via the CMake Gui or by running ``ccmake``. + +Building the installer package +############################## + +* For Windows only, you first need to install NSIS, available at: http://nsis.sourceforge.net/Download. Ensure that the install directory is added to the PATH. You should be able to type ``makensis /?`` in a command prompt. +* Run CMake with "ENABLE_CPACK" enabled. If using the GUI you need to click the "Advanced" checkbox to see this option. +* You will now have a build target called "PACKAGE" available to create the installer package. + +Caveats and Known Issues +######################## + +* For Visual Studio & XCode, the libraries and executable are put into ``Mantid/bin/Release``, ``Debug``, etc. +* There is a known issue with using source control with Eclipse on an out of source build. Set the cache variable ``ECLIPSE_CDT4_GENERATE_SOURCE_PROJECT`` to true and CMake will generate a set of 'dummy' project files within the source tree so that you can import that project and use it for source control actions. + +Tips +#### + +* Running unit test executables directly with the CMake-generated ``Mantid.properties`` file will lead to a bunch of logging output to the console. You are encouraged to use CTest instead, which suppresses this output automatically. Otherwise, adding the line ``logging.channels.consoleChannel.class = NullChannel`` to your Mantid.user.properties file will turn if off. +* If you have more than one gcc and want to build with a version other than the default (e.g. on RedHat), setting CC & CXX environment variables is one way to make it so. diff --git a/dev-docs/source/DataFilesForTesting.rst b/dev-docs/source/DataFilesForTesting.rst new file mode 100644 index 00000000000..3f917e39c95 --- /dev/null +++ b/dev-docs/source/DataFilesForTesting.rst @@ -0,0 +1,282 @@ +.. _DataFilesForTesting: + +====================== +Data Files for Testing +====================== + +.. contents:: + :local: + +Summary +####### + +This page gives an overview of how data files are managed within Mantid. + + +Motivation +########## + +Some unit tests use a small amount of data that is created by the test +harness and others load data from a file. Take the example of +``ApplyCalibrationTest``. In its first test, testSimple, it creates a +workspace with 10 detectors using +``WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument()``. In +the second test, testComplex, it reads a file +**IDFs_for_UNIT_TESTING/MAPS_Definition_Reduced.xml**, which contains +the definition of a MAPS instrument with the number of detectors reduced +much to ensure it is read quickly but preserving the other properties of +this instrument. However, new tests should avoid even loading of this +nature unless there is a strong justification for doing so. + +Main issues: + +- need to store data, mainly for testing, alongside the code +- some data needs to be versioned +- merging system tests back with main code requires handling large data + files +- git is bad at handling binary files + +Possible solutions: + +- don't have any reference to data in git and force developers to + manage the data stored on a file server +- extensions to git, e.g. + `git-fat <https://github.com/jedbrown/git-fat>`__, + `git-annex <https://git-annex.branchable.com/>`__ to deal with large + files +- CMake's + `ExternalData <http://www.kitware.com/source/home/post/107>`__ + +We have chosen to use CMake as it is already in use as a build system +and it doesn't involve introducing extra work with git. + + +CMake's External Data +##################### + +.. figure:: images/ExternalDataSchematic.png + :alt: Image originated at http://www.kitware.com/source/home/post/107 + :align: center + + Image originated at http://www.kitware.com/source/home/post/107 + +Terminology: + +- content - the real data +- content link - text file containing a hash (MD5) of the real content. + The filename is the filename of the real data plus the ``.md5`` + extension +- object - a file that stores the real data and whose name is the MD5 + hash of the content + +Overview: + +- git does not store any content, it only stores content links +- content is stored on a remote server that can be accessed via a + ``http`` link +- running cmake sets up build rules so that the content is downloaded + when dependent projects are built + + +Local Object Store +################## + +CMake does not download content directly but stores the content in a +*Local Object Store*, whose location is defined by the +``ExternalData_OBJECT_STORES`` CMake variable. This allows it to share +content between build trees, especially useful for continuous +integration servers. + + +Binary Root +########### + +The final step is to create the *real* filename and symbolic link (copy +on windows) it to the object in the local object store. The location of +the *real* filenames is controlled by the ``ExternalData_BINARY_ROOT`` +CMake variable and defaults to ``build/ExternalData``. + + +Using Existing Data +################### + +There are two places files may be found: + +- `../mantid/Testing/Data/UnitTest <https://github.com/mantidproject/mantid/tree/master/Testing/Data/UnitTest>`__ +- `../mantid/instrument/IDFs_for_UNIT_TESTING <https://github.com/mantidproject/mantid/tree/master/instrument/IDFs_for_UNIT_TESTING>`__ + for test `IDF <IDF>`__ files + + +Adding A New File(s) +#################### + +A helper git command is defined called ``add-test-data``. It would be +called like this: + +.. code-block:: sh + + git add-test-data Testing/Data/UnitTest/INST12345.nxs + +This does the following: + +- computes the MD5 hash of the data, e.g. + ``d6948514d78db7fe251efb6cce4a9b83`` +- stores the MD5 hash in a file called + ``Testing/Data/UnitTest/INST12345.nxs.md5`` +- renames the original data file to + ``Testing/Data/UnitTest/d6948514d78db7fe251efb6cce4a9b83`` +- runs ``git add Testing/Data/UnitTest/INST12345.nxs.md5`` +- tells the user to upload the file(s), + ``d6948514d78db7fe251efb6cce4a9b83``, to the remote store (URL: + http://198.74.56.37/ftp/external-data/upload) +- re-run cmake + +Notes: + +- You need to use a shell to add & modify data files under Windows in + this way. Not every shell works as described, though `Github for + Windows <https://windows.github.com/>`__ shell would allow you to do + everything described here step by step without deviations. + Unfortunately, MINGW32 shell you have to select to do that is not the + most convenient shell under Windows. In addition to that, + ``add-test-data`` script is currently broken (at least was on + 20/11/2015) . This is why I would suggest to use small python script, + provided below, which would calculate md5 hash, create the ``.md5`` + file and rename your test or reference file according to the hash sum + calculated. You then have to manually put ``.md5`` file to requested + reference data location and add it to Git by usual means. The + hash-sum named file should be, as in the case of Unix, placed to the + `remote store <http://198.74.56.37/ftp/external-data/upload>`__ +- Note, that ILL test data should be placed under ``ILL/${INSTRUMENT}`` + subdirectories (e.g. ``ILL/IN16B``), and should not contain any + instrument prefix in the file name. + + +Developer Setup +############### + +**You need cmake 2.8.11+** + +To add the ``add-test-data`` command alias to git run + +.. code-block:: sh + + git config alias.add-test-data '!bash -c "tools/Development/git/git-add-test-data $*"' + +in the git bash shell. The single quotes are important so that bash +doesn't expand the exclamation mark as a variable. + +It is advised that CMake is told where to put the "real" data as the +default is ``$HOME/MantidExternalData`` on Linux/Mac or +``C:/MantidExternalData`` on Windows. Over time the store will grow so +it is recommended that it be placed on a disk with a large amount of +space. CMake uses the ``MANTID_DATA_STORE`` variable to define where the +data is stored. + +Example cmake command: + +Linux/Mac: + +.. code-block:: sh + + mkdir -p build + cmake -DMANTID_DATA_STORE=/home/mgigg/Data/LocalObjectStore ../Code/Mantid + +Windows: + +.. code-block:: sh + + mkdir build + cmake -DMANTID_DATA_STORE=D:/Data/LocalObjectStore ../Code/Mantid + +Setting With Dropbox: + +This is for people in the ORNL dropbox share and has the effect of +reducing external network traffic. There is a +`gist <http://gist.github.com/peterfpeterson/638490530e37c3d8dba5>`__ +for getting dropbox running on linux. + +.. code-block:: sh + + mkdir build + cmake -DMANTID_DATA_STORE=/home/mgigg/Dropbox\ \(ORNL\)/MantidExternalData ../Code/Mantid + +If you don't want to define the MANTID_DATA_STORE everytime you run +cmake, you can link the default data store location to the Dropbox one. + +.. code-block:: sh + + ln -s ~/Dropbox\ \(ORNL\)/MantidExternalData ~ + +Proxy Settings +-------------- + +If you are sitting behind a proxy server then the shell or Visual studio +needs to know about the proxy server. You must set the ``http_proxy`` +environment variable to ``http://HOSTNAME:PORT``. + +On Windows you go to **Control Panel->System and +Security->System->Advanced System settings->Environment Variables** and +click **New...** to add a variable. + +On Linux/Mac you will need to set the variable in the shell profile or +on Linux you can set it system wide in ``/etc/environment``. + +Troubleshooting +--------------- + +If you find that your tests cannot find the data they require check the +following gotchas: + +- Check that you have uploaded the original file renamed as a hash to + the Mantid file repository +- Check that you have re-run CMake in the build directory. +- Check that you have removed any user defined data search directories + in ~/.mantid +- Check that you have rebuilt the test executable you're trying to run +- Check that you have rebuilt the SystemTestData target + +Python script to produce hash files +----------------------------------- + +.. code:: python + + #!/usr/bin/python + import hashlib + import os,sys + + def md5sum(filename, blocksize=65536): + """Calculate md5 hash sum of a file provided """ + hash = hashlib.md5() + with open(filename, "rb") as f: + for block in iter(lambda: f.read(blocksize), b""): + hash.update(block) + return hash.hexdigest() + + def save_sum(filename,md_sum): + """Save hash sum into file with appropriate filename""" + md_fname = filename+'.md5' + with open(md_fname) as f: + f.write(md_sum) + + if __name__ == '__main__': + + if len(sys.argv)<2 or not os.path.isfile(sys.argv[1]): + print "Usage: hash_file.py file_name" + exit(1) + + filename = sys.argv[1] + + path,fname = os.path.split(filename) + hash_sum = md5sum(filename) + print "MD SUM FOR FILE: {0} is {1}".format(fname,hash_sum) + + # save hash sum in file with original file name and extension .md5 + save_sum(os.path.join(path,fname),hash_sum) + + # Rename hashed file into hash sum name. + hash_file = os.path.join(path,hash_sum) + if os.path.isfile(hash_file): + print "file: {0} already exist".format(hash_sum) + else: + os.rename(filename,hash_file) diff --git a/dev-docs/source/DebuggingUnitTests.rst b/dev-docs/source/DebuggingUnitTests.rst new file mode 100644 index 00000000000..0e84d56e6a5 --- /dev/null +++ b/dev-docs/source/DebuggingUnitTests.rst @@ -0,0 +1,101 @@ +Debugging Unit Tests +==================== + +.. contents:: + :local: + +Using gdb +--------- + +Debugging typically requires the test executable to be run directly, +rather than via ctest (which typically spawns off a separate process to +run the actual tests). So an example of debugging from the command line +using gdb would be:: + + $ gdb bin/AlgorithmsTest + (gdb) r RebinTest + +If you do need to run ctest in order to debug - if, for example, a test +is failing when run in ctest, but not if run directly - then you can +start the test off and then attach to the actual test executable from +another terminal (or your IDE). You may need to pause or slow down the +test using, e.g., the method described for Visual Studio debugging +below. + +If the issue is with a python unit test, the call is slightly more +complicated:: + + $  env PYTHONPATH=$PWD/bin gdb --args python2 /full/path/to/mantid/Framework/PythonInterface/test/python/mantid/kernel/TimeSeriesPropertyTest.py + (gdb) run + +Within Eclipse +-------------- + +#. Go to Run->Debug Configurations +#. Create a new Debug Configuration. I called mine "DataHandling Test + Debug". +#. For me, it worked best using the "Standard Create Process Launcher" + (bottom option on the "Main" tab) +#. Set the C/C++ application to the path to the test executable, e.g. + bin/DataHandlingTest +#. Under the "Arguments" tab, add the name of the test class you want to + debug under "Program arguments", e.g. LoadTest + + #. To only run one test in a class, you can add the particular test + to run, e.g. "LoadTest test_exec" + +#. Under "Common" you can put the debug config in your "favorites" menu. + +You can then run the debugger on this configuration from the Run menu or +the toolbar. + +Within Visual Studio (debugging run method) +------------------------------------------- + +I've found that this method works with Visual Studio Express (which does +not allow "attach to process"). + +- Right-click the test project, e.g. DataObjectsTest. +- Select Properties. + + - Under Debugging -> Command Arguments, type in the test suite and, + optionally, single test name. e.g. "EventListTest + test_MinusOperator_inPlace_3cases" in the screenshot below. + +.. figure:: images/VisualStudioTestDebugProperties.png + :alt: VisualStudioTestDebugProperties.png + + VisualStudioTestDebugProperties.png + +- Put a break point somewhere in the test code that will be run. +- Select the project and click Debug -> Start Debugging. +- Fun test debugging times! + +Within Visual Studio (attach to process version) +------------------------------------------------ + +The process here is not as straight forward as it is in eclipse. It +involves a few steps, but it does work! + +1. Edit the test to add a pause at the start of the test you are +interested in. This will make the test wait for keyboard input, all you +need to do is hit enter, but you can use this delay to attach to the +debugger to running process. +:: + + std::string s; + std::getline(std::cin,s); + +| 2. Run ctest with the appropriate arguments to run the test you are + investigating. +| 3. When the test pauses for input within visual studio select + Debug\Attach to Process... |AttachToProcess.png| +| 4. Select the test executable (e.g. DataHandlingTest.exe) from the + list and click attach. Visual studio will change to debug mode. +| 5. Set any breakpoints you want, go back to the runner.exe window and + hit enter to stop the pause. This should then ctach on any breakpoints + you have set. +| 6. VERY IMPORTANT - Clean up when you have done, and do not check in + with any paused tests! + +.. |AttachToProcess.png| image:: images/AttachToProcess.png diff --git a/dev-docs/source/Dependencies.rst b/dev-docs/source/Dependencies.rst deleted file mode 100644 index cb9da7b2d91..00000000000 --- a/dev-docs/source/Dependencies.rst +++ /dev/null @@ -1,41 +0,0 @@ -============ -Dependencies -============ - -The large external libraries that we use in Mantid (boost, Poco & Qt) -have overlapping functionality in certain areas. In this situation we -want to be consistent in only using one\ :sup:`\*` library for a -particular piece of functionality. The table below sets out what we use -in various areas. - -+-------------------------+-------+-------+----+-------------+ -| Functionality | Boost | Poco | Qt | Other | -+=========================+=======+=======+====+=============+ -| File / directories | | **X** | | | -+-------------------------+-------+-------+----+-------------+ -| Notifications / signals | | **X** | | | -+-------------------------+-------+-------+----+-------------+ -| Threads / threadpools | | **X** | X | | -+-------------------------+-------+-------+----+-------------+ -| Regular expressions | **X** | | | | -+-------------------------+-------+-------+----+-------------+ -| DateTime | **X** | | | | -+-------------------------+-------+-------+----+-------------+ -| Setting & Properties | | **X** | X | | -+-------------------------+-------+-------+----+-------------+ -| Logging | | **X** | | | -+-------------------------+-------+-------+----+-------------+ -| XML | | X | ?X | | -+-------------------------+-------+-------+----+-------------+ -| Triangulation | | | | OpenCascade | -+-------------------------+-------+-------+----+-------------+ -| Python | X | | | SIP | -+-------------------------+-------+-------+----+-------------+ - -:sup:`\*` In some (rare) cases we may want to use Qt for something up at -the graphical layer, and something different in the framework where Qt -is not available. - -Also noteworthy is the `Compiler -Support <http://en.cppreference.com/w/cpp/compiler_support>`__ for -various "advanced" language features. diff --git a/dev-docs/source/DesignDocumentGuides.rst b/dev-docs/source/DesignDocumentGuides.rst new file mode 100644 index 00000000000..4b5221765f5 --- /dev/null +++ b/dev-docs/source/DesignDocumentGuides.rst @@ -0,0 +1,121 @@ +.. _DesignDocumentGuidelines: + +========================== +Design Document Guidelines +========================== + +.. contents:: + :local: + +A good design document minimises unexpected complications by addressing +them before the code is written. A document will provide you, your +manager and your team with a common vocabulary for talking about the +project. Writing an effective design document can be tricky in itself +they often add unnecessary complexity if not done with care. These +guidelines are to help you generate effective and simple design +documents. + +Before starting, all Mantid design documents must be written in +`markdown <http://en.wikipedia.org/wiki/Markdown>`__ format with the md +extension. After approval from the the Mantid Project :ref:`TSC`, they should be stored +`here <https://github.com/mantidproject/documents/tree/master/Design>`__ +or in one of the subdirectories of that directory. This page covers what +happens between those points. + +Guidelines on Sections +###################### + +We want to avoid a prescriptive approach to design document layout. +Design documents are about communicating design ideas, not a box ticking +exercise, so developers are expected to use their own professional +judgement about what goes into them. We are not providing templates for +this reason. The following are guidelines for writing your design +document, to help give you some direction. + +Motivation +---------- + +- Why does this design document exist? +- What is the overview of the problem? +- What use cases exist showing the present issue? For example scripting + issues. +- How does this link in with long-term requirements such as SSC outputs +- **This section should be readable by non developers**. Not everyone + knows that the ADS stands for the Analysis Data Service and wider + stakeholders definitely will not + +Dictionary of Terms +------------------- + +Your opportunity to pair abbreviations to longer explanations. This is +not always necessary in documents where there are no special terms to +explain. If you need one, a two column table would be sufficient. + +Potential Solutions +------------------- + +It is important that you consider a wide range of possible solutions, +and don't just put forward your favourite. Remember that the design +document is a way of avoiding mistakes before coding, so spend some time +considering how several possibilities could be made to work. + +For each potential solution, you should probably consider: + +- Keep it brief and high-level at this stage +- What would the scope of the changes be? +- What are the pros/cons of this solution? + +Chosen Solution +--------------- + +You should provide logical reasons why you are choosing to adopt +solution A over solution B, C, D ... As the project grows in size, we +may need to be able to understand in the future the reasons why certain +designs have been adopted. If you are unsure which solution would be +best, you may submit the partially complete design document to the :ref:`TSC` for help. Design +is itself an iterative process and documents are frequently not accepted +first time around, so be prepared to make amendments, and don't take it +personally if corrections are required. + +How will we verify the design, what are the use cases that could be used +to verify the solution? + +Implementation Detail +--------------------- + +You could merge this section here with the one above if you wish. + +- Use feedback to correct and clarify. +- Add more implementation detail. Diagrams are great, but you don't + have to use strict UML, and use the appropriate UML diagrams + depending upon the solution. Diagrams should help you and readers to + understand the solution in a simple way, not make it more + complicated. +- Could someone else follow the design and implement it? You may not be + the one implementing this, and it's even more likely that you will + not be the only one maintaining it. + +Sign Off +-------- + +Design documents help us to manage risk and reduce cost to the project. +We have had some bad experiences in the past where high-risk changes +have been made ad-hoc. You must get approval from the :ref:`TSC` before embarking on the work outlined in the +design document. + +Cheat Sheet and Checklist +######################### + +The guidelines above do not need to be strictly followed, but the +following are necessary: + +#. Can non experts understand the motivation for these changes? +#. Are your design decisions traceable? Does your design document link + from requirements through to implementation details in a traceable + manner? +#. Can someone else implement this? +#. Has the :ref:`TSC` approved the design. +#. What use cases verify that this design work +#. Documents must be version controlled and live in a subdirectory of + `here <https://github.com/mantidproject/documents/tree/master/Design>`__ + as a `markdown <http://en.wikipedia.org/wiki/Markdown>`__ document diff --git a/dev-docs/source/DeveloperAccounts.rst b/dev-docs/source/DeveloperAccounts.rst new file mode 100644 index 00000000000..fbdebd33394 --- /dev/null +++ b/dev-docs/source/DeveloperAccounts.rst @@ -0,0 +1,63 @@ +.. _DeveloperAccounts: + +================== +Developer Accounts +================== + +.. contents:: + :local: + +User Names +---------- + +Simple, easy to recognise user names are preferred. For example "Nick Draper", or if spaces are not allowed "NickDraper". + +Account Creation +---------------- + +- Create a **Mantid Wiki** account; follow `this link <https://www.mantidproject.org/Special:RequestAccount>`__. +- Sign up to the **Mantid Developers** email list; follow `this link <http://lists.mantidproject.org/mailman/listinfo/mantid-developers>`__. +- Sign up for the **Mantid Slack** channel; follow `this link <https://mantid.slack.com/>`__. +- If you don't already have one, sign up for a **Github** account; follow `this link <https://github.com/>`__. + + Remember that your username should be easily identifiable. + + Contact one of the "Owners" on `this list <https://github.com/orgs/mantidproject/people?query=role%3Aowner>`__ to add you to the developer team. + + Set up Git on your workstation; see `this guide <https://help.github.com/articles/set-up-git/>`__. + + The Git workflow is described on the :ref:`GitWorkflow` page. + +- Consider signing up for **Skype**; follow `this link <https://www.skype.com/>`__. +- Sign up for a **Gravatar** account; follow `this link <https://en.gravatar.com/>`__. + +SNS Git +------- + +If you are based at SNS, in order to be able to ssh out of the lab, you need to do the following: + +- Install "Corkscrew" using your package manager. +- Add the following lines to ~/.ssh/config: + + +.. code:: bash + + ProxyCommand corkscrew snowman.ornl.gov 3128 %h %p + Host github.com + +Introducing Yourself +-------------------- + +- Post a short introduction of yourself to the rest of the team in the General chatroom on Mantid Slack. +- Add yourself together with your contact details and a photo (selfies are fine) to :ref:`DevelopmentTeam`. + +Admin Notes +----------- + +These are notes for account admins on how to add new users. + +- **Wiki** + + Go to the `special pages index <https://www.mantidproject.org/Special:SpecialPages>`_. + + Select Login/Create Account. + + Select the Create Account link at the top of the box. + + Username should be first name (space) surname. + + User will be sent an email to verify. + +- **Github** + - Add the username provided to the mantid-developers team at `https://github.com/organizations/mantidproject/teams <https://github.com/organizations/mantidproject/teams>`_. diff --git a/dev-docs/source/DevelopmentAndReleaseCycle.rst b/dev-docs/source/DevelopmentAndReleaseCycle.rst new file mode 100644 index 00000000000..9cb8dd18563 --- /dev/null +++ b/dev-docs/source/DevelopmentAndReleaseCycle.rst @@ -0,0 +1,27 @@ +.. _DevelopmentAndReleaseCycle: + +============================= +Development and Release Cycle +============================= + +Mantid makes 3 point releases per year. The list of current milestones, along with their +expected release dates, is shown at https://github.com/mantidproject/mantid/milestones. The rough +structure of the development cycle is shown in the following figure: + +.. figure:: images/DevelopmentAndReleaseCycle.png + :alt: Development and Release cycle + +Each release is divided, roughly, into: + +* a 3 month development period where new features and bugfixes are developed +* a 3 week code freeze where the code is tested and prepared for the next release + + * during the freeze a 2 week beta-test period is given to users to test the upcoming + release candidate (deployed in the form of a nightly build). + +Feature development occurs on the `master <https://github.com/mantidproject/mantid/tree/master>`__ branch. At the code +freeze, once all pull requests marked for the release have been merged, a new branch is created for the next release. Fixes +found during testing are merged to the release branch and the master remains open to changes not destined for this release. + +The maintenance period generally overlaps with the tail end of the code freeze. All maintenance tasks occur on the +master branch and should not disturb the release branch. diff --git a/dev-docs/source/DoxygenSetup.rst b/dev-docs/source/DoxygenSetup.rst new file mode 100644 index 00000000000..0c7f3b2d210 --- /dev/null +++ b/dev-docs/source/DoxygenSetup.rst @@ -0,0 +1,83 @@ +Doxygen Setup +============= + +Unix Console Doxygen Setup +-------------------------- + ++-----------------+-----------------------------------------------------------------------------------------+ +| | Check for | You may well already have doxygen installed but is it most likely | +| | doxygen | in your systems repositories. | +| | If not, build from source | +| | `here <http://www.stack.nl/~dimitri/doxygen/download.html#srcbin>`__. | ++-----------------+-----------------------------------------------------------------------------------------+ +| Run cmake | CMake will genereate the doyxgen config file | +| | in ${CMAKE_DIR}/Framework/Doxygen/Mantid.doxyfile | ++-----------------+-----------------------------------------------------------------------------------------+ +| | You're done! | - Type 'make doxygen' | +| | Try! | - This will run doxygen, showing the output in the console. You may | +| | want to pipe warnings to a file to make them easy to read later: | +| | 'make doxygen 2> doxygen_errors.log' | +| | - The documentation will go into a subdir doxygen/html of the | +| | directory where cmake was run from. | ++-----------------+-----------------------------------------------------------------------------------------+ + +Visual Studio Doxygen Setup +--------------------------- + ++-----------------+-----------------------------------------------------------------------------------------+ +| Install doxygen | Download the | +| binaries | `Windows binaries <http://www.stack.nl/~dimitri/doxygen/download.html#latestsrc>`__ | +| | and install them. I'll assume in the following you installed doxygen in | +| | c:\program files\doxygen | ++-----------------+-----------------------------------------------------------------------------------------+ +| Rerun CMake | Run cmake for the build to ensure that the Mantid.doxyfile is created | ++-----------------+-----------------------------------------------------------------------------------------+ +| Add VC++ Tool: | - Tools\External Tool then click Add | +| "DoxyGen" | - Title: &DoxyGen | +| | - Command: C:\Program Files\Doxygen\bin\doxygen.exe | +| | - Arguments: "$(SolutionDir)\Framework\Doxygen\Mantid.doxyfile" (include the quotes!) | +| | - Initial Directory: $(SolutionDir)\Build | +| | - Check the "Use output window" box | ++-----------------+-----------------------------------------------------------------------------------------+ +| Add VC++ Tool: | - Tools\External Tool then click Add | +| "view DoxyGen" | - Title: &View DoxyGen | +| | - Command your favorite browser, e.g. C:\program Files\internet Explorer\iexplore.exe | +| | or C:\Program Files (x86)\Google\Chrome\Application\chrome.exe | +| | - Arguments: "$(SolutionDir)doxygen\html\index.html" | +| | - Initial Directory: leave empty | ++-----------------+-----------------------------------------------------------------------------------------+ +| You're done! | - Choose Tools/DoxyGen from the menu, and watch the magic happen (DoxyGen will log | +| Try! "DoxyGen" | it's progress and complaints to the output window). Clicking on a warning message | +| | will take you to the location in the code of the warning. | +| | - Choose Tools/View DoxyGen to explore the documentation. | +| | - The "Main Page" is probably rather boring. Click on "Namespaces" in the menu line to | +| | browse your classes etc. | ++-----------------+-----------------------------------------------------------------------------------------+ + +Eclipse Doxygen Setup +--------------------- + ++-----------------+-----------------------------------------------------------------------------------------+ +| Check for | You may well already have doxygen installed, but if not you can install it at the same | +| doxygen | time as the plugin below via the update site | ++-----------------+-----------------------------------------------------------------------------------------+ +| Run cmake | This will generate the doxygen config file in | +| | ${CMake_DIR}/Framework/Doxygen/Mantid.doxygen | ++-----------------+-----------------------------------------------------------------------------------------+ +| Install Eclipse | - `Eclox <http://eclox.eu/>`_ is a frontend plugin for Eclipse. | +| plugin: "Eclox" | - Install it using the Eclipse Update Manager | +| | - To do this go to Help -> Software Updates... | +| | - Select the 'Available Software' tab then the 'Add Site...' button | +| | - Enter `http://download.gna.org/eclox/update` as the location | +| | - Eclipse will add the site to the list and you can open the tree to select and install | +| | Eclox | ++-----------------+-----------------------------------------------------------------------------------------+ +| You're done! | - You'll now have a 'build doxygen' button in your toolbar (a blue '@') | +| Try! | - The first time you click it you'll be prompted for the configuration file. Point it | +| | at ${CMake_DIR}/Framework/Doxygen/Mantid.doxygen | +| | - This will run doxygen, showing the output in the console and adding warnings symbols | +| | on the source files (as for compilation warnings). Hovering over these will show the | +| | warning. | +| | - The documentation will go into a subdir doxygen/html of the directory where cmake was | +| | run from. | ++-----------------+-----------------------------------------------------------------------------------------+ diff --git a/dev-docs/source/GUIDesignGuidelines.rst b/dev-docs/source/GUIDesignGuidelines.rst index 3f5790757a6..e545781ef22 100644 --- a/dev-docs/source/GUIDesignGuidelines.rst +++ b/dev-docs/source/GUIDesignGuidelines.rst @@ -1,3 +1,5 @@ +.. _GuiDesignGuidelines: + ===================== GUI Design Guidelines ===================== @@ -12,7 +14,7 @@ This page describes guidelines that should be followed when implementing an interface in MantidPlot. The aim is to encourage a consistent approach to developing interfaces. -.. _dev-docs-mvp-intro: +.. _GuiDesignGuidelinesMVPIntro: MVP (Model View Presenter) ########################## @@ -29,7 +31,7 @@ is given below. To illustrate MVP, a simple example of a calculator GUI has been created using Python (the concepts of MVP can be applied to any programming language). This example can be found in -:ref:`dev-docs-gui-calculator-example`, and you can run it with +:ref:`MVPCalculatorGUIExample`, and you can run it with ``python Calculator.py``. It is good practice to have model, view or presenter (as appropriate) @@ -55,7 +57,7 @@ maintenance easier. It is important to note that the values used in the calculations should be received from the presenter (more of which below). -.. _dev-docs-mvp-view: +.. _GuiDesignGuidelinesMVPView: View ---- @@ -276,7 +278,7 @@ file would look like: where ``FooGUI`` is the ``MainWindow`` for the interface. Some more detailed documentation on creating GUIs in Python can be found at -:ref:`dev-docs-mvp-python-views`. +:ref:`QtDesignerForPython`. Designer -------- diff --git a/dev-docs/source/GettingStarted.rst b/dev-docs/source/GettingStarted.rst index bfbbe1927dc..929dd0976f0 100644 --- a/dev-docs/source/GettingStarted.rst +++ b/dev-docs/source/GettingStarted.rst @@ -1,14 +1,16 @@ -=========================== -Getting Started with Mantid -=========================== +.. _GettingStarted: + +=============== +Getting Started +=============== .. contents:: :local: -Prerequisites -############# +Environment +########### -Some intial setup is required before being able to build the code. This is platform +Some initial setup is required before being able to build the code. This is platform specific and described here. Windows @@ -18,23 +20,26 @@ Install the following: * `Visual Studio 2015 Community Edition <https://go.microsoft.com/fwlink/?LinkId=532606&clcid=0x409>`_. If you are at RAL then ask for the location of the locally-cached offline version. -* `Git <https://git-scm.com/download/win>`_ -* `Git LFS <https://git-lfs.github.com/>`_ - - * After installation open Git Bash and run ``git lfs install`` - +* `Git <https://git-scm.com/>`_. After installation open Git Bash and run ``git lfs install``. * `CMake <https://cmake.org/download/>`_ -* `MiKTeX <https://miktex.org/download>`_. Instructions are available - `here <https://miktex.org/howto/install-miktex>`_. +* `MiKTeX <https://miktex.org/download>`_. Instructions are + `available here <https://miktex.org/howto/install-miktex>`_. * `NSIS <http://nsis.sourceforge.net/Download>`_ (optional). Used for building packages +`Graphviz <http://graphviz.org/download/>`__ is required to generate the workflow diagrams in the documentation. +Unfortunately CMake can't find it out of the box and the following steps are required to make this link + +* open regedit +* add a new key ``[HKEY_LOCAL_MACHINE\\SOFTWARE\\ATT\\Graphviz]`` +* create a new string value named ``InstallPath`` within this key and set the value + to point to the install directory of Graphviz. + Linux ----- Red Hat/Cent OS/Fedora -^^^^^^^^^^^^^^^^^^^^^^ - -Follow the instructions at http://download.mantidproject.org/redhat.html to add the +~~~~~~~~~~~~~~~~~~~~~~ +Follow the `Red Hat instructions <http://download.mantidproject.org/redhat.html>`_ to add the stable release yum repository and then install the ``mantid-developer`` package: .. code-block:: sh @@ -42,9 +47,8 @@ stable release yum repository and then install the ``mantid-developer`` package: yum install mantid-developer Ubuntu -^^^^^^ - -Follow the instructions at http://download.mantidproject.org/ubuntu.html to add the +~~~~~~ +Follow the `Ubuntu instructions <http://download.mantidproject.org/ubuntu.html>`_ to add the stable release repository and mantid ppa. Download the latest `mantid-developer <https://sourceforge.net/projects/mantid/files/developer>`_ package and install it: @@ -56,3 +60,41 @@ package and install it: where ``X.Y.Z`` should be replaced with the version that was downloaded. +OSX +--- +The build environment on OS X is described here :ref:`BuildingOnOSX`. + +Getting the Mantid code +############################ +We use `Git`_ as our version control system (VCS). The master copies of our repositories are located at `GitHub <http://github.com/mantidproject>`_. We have a number of repositories, of which the main one (the one containing all the source code for Mantid itself) is called simply `mantid <http://github.com/mantidproject/mantid>`_. + +If you are not already set up with Git, you can follow these `instructions <https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup>`_. + +If you are at RAL then please run the following commands before cloning the repository: + +.. code-block:: sh + + git config --global url.git@github.com:mantidproject.insteadOf http://mantidweb.nd.rl.ac.uk/mirror/git/ + +This will speed up the clone and intial cmake run considerably. + +There are a number of URLs via which the code can be checked out using various protocols. The easiest way to get the one you want is to select the protocol you want on the right side of the `mantid <http://github.com/mantidproject/mantid>`_ repository page on github and copy the url into your clipboard. The way to clone the repository via ssh on the command line, into a directory called Mantid, is: + +.. code-block:: sh + + git clone git@github.com:mantidproject/mantid.git + +If at RAL now remove the config section above + +.. code-block:: sh + + git config --global --unset url.git@github.com:mantidproject + + +Building Mantid +############### +See :ref:`BuildingWithCMake` for information about building Mantid. + +Building VATES +############## +See :ref:`BuildingVATES` for infromation about building VATES. diff --git a/dev-docs/source/GitWorkflow.rst b/dev-docs/source/GitWorkflow.rst new file mode 100644 index 00000000000..465c0266e34 --- /dev/null +++ b/dev-docs/source/GitWorkflow.rst @@ -0,0 +1,190 @@ +.. _GitWorkflow: + +=================== +Mantid Git Workflow +=================== + +.. contents:: Contents + :local: + +Summary +^^^^^^^ + +This page describes the workflow used in conjunction with `Git +<http://git-scm.com>`_ and `GitHub <https://www.github.com/>`_ for +those who have push access to the repository. + +Go `here +<https://services.github.com/on-demand/downloads/github-git-cheat-sheet.pdf>`__ +for a cheatsheet of Git commands. + +Go `here <https://github.com/k88hudson/git-flight-rules>`__ for a +(fairly) comprehensive guide to solving your various Git problems. + +Description +^^^^^^^^^^^ + +We follow the `GitHub flow +<https://guides.github.com/introduction/flow/index.html>`_, using +branches for new work and pull requests for verifying the work. + +The steps for a new piece of work can be summarised as follows: + +1. Push up or `create <https://guides.github.com/features/issues>`_ an + issue `here <https://github.com/mantidproject/mantid/issues>`__ +2. Create a branch from master, using the naming convention described + at :ref:`GitWorkflowPublicPrivateBranches` +3. Do the work and commit changes to the branch. Push the branch + regularly to GitHub to make sure no work is accidentally lost +4. When you are finished with the work, ensure that all of the unit + tests, documentation tests and system tests if necessary pass on + your own machine +5. Open a pull request (:ref:`GitWorkflowPullRequests`) + from the `GitHub branches + <https://github.com/mantidproject/mantid/branches/>`_ page + + - This will check with the buildservers for cross-platform + compatibility + - If any issues come up, continue working on your branch and push + to GitHub - the pull request will update automatically + +.. _GitWorkflowPublicPrivateBranches: + +Public and Private Branches +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When naming `public branches +<http://github.com/mantidproject/mantid/branches>`_ that will be +pushed to GitHub, please follow the convention of +``issuenumber_short_description``. This will allow others to discover +what the branch is for (issue number) and quickly know what is being +done there (short description). Please remember that public branches +should not be rebased. + +For private branches please follow the convention +``yourname/issuenumber_short_description``. You can sync these with +GitHub (for backup reasons) and rebase. Since the branch name is +prefixed with your name people will know, by convention, that it is a +private branch and can be rebased, deleted, etc at the owner's +whim. Changing a private branch is done by simply renaming the branch +to drop the prefix. + + +.. _GitWorkflowPullRequests: + +Pull Requests +^^^^^^^^^^^^^ + +For an general overview of using pull requests on GitHub look `here +<https://help.github.com/articles/using-pull-requests/>`__. + +When creating a pull request you should: + +- Ensure that the title succinctly describes the changes so it is easy + to read on the overview page + + - The title should **not** contain the issue number +- `Reference the issue which the pull request is closing <https://github.com/blog/1506-closing-issues-via-pull-requests>`_, using one of `these <https://help.github.com/articles/closing-issues-via-commit-messages>`_ keywords +- Ensure the description follows the format described by the `PR + template + <https://github.com/mantidproject/mantid/blob/master/.github/PULL_REQUEST_TEMPLATE.md>`_ + on GitHub + +A good example is `here <https://github.com/mantidproject/mantid/pull/18713>`__. + +Recommended reading: `How to Write the Perfect Pull Request +<https://github.com/blog/1943-how-to-write-the-perfect-pull-request>`_ + +Stale Pull Requests +------------------- + +Pull requests that go an extended period of time without any activity +are considered stale and will be picked up by a (partially) automated +bot which will notify those that are required to take action in order +to keep the review process going. + +This is also used to notify developers of pull requests that develop +conflicts with the base branch and that fail continuous integration +tests, in those two cases the age of the pull request is ignored. + +The reasons a pull request may be flagged up currently are: + +- Conflicts with base branch +- Failing CI +- Last developer has left the Mantid team +- Nobody has reviewed the PR +- An assigned reviewer has yet to complete a review +- A gatekeeper has not second reviewed an approved PR +- A review from a specific user was requested but that user has yet to complete a review +- The developer has yet to act on comments left in a review + + +(code for the bot is currently `here +<https://github.com/DanNixon/mantid_pr_bot>`__) + +Code Freeze +^^^^^^^^^^^ + +At the start of a *code freeze* before a major release there will be a +release branch created with the name ``release-vX.Y``, where ``X.Y`` +are the major and minor version numbers, respectively. At this point +only bugfixes should be applied to this release branch so that it can +be stabilized for the release. The release branch will be merged to +``master`` periodically so bugfixes do not need to be separately +merged to ``master``. + +New Branches +------------ + +During the code freeze it is important to ensure that a new branch is +created from the correct base branch depending on the scope of the +changes: + +- ``master``: maintenance fixes, new features. Command: ``git fetch -p && git checkout --no-track -b MYBRANCH_NAME origin/master`` +- ``release-vX.Y``: bugfixes. Command: ``git fetch -p && git checkout --no-track -b MYBRANCH_NAME origin/release-X.Y`` + +Pull Requests +------------- + +Open pull requests as normal to ask to merge your branch with its +intended target. + +.. image:: images/CodeFreezePR.png + +Fixing a PR with an Incorrect Base Branch +----------------------------------------- + +The target branch on GitHub needs to match the base branch used in the +commands above when the branch was initially created. If the compare +view shows changes other than your own it is most likely that the base +branch is incorrect and it needs to be fixed. + +As an example consider the scenario where a branch named ``topic`` has +been based off the ``master`` branch as follows: + +.. code-block:: bash + + o---o---o---o---o master + | \ + | o---o---o topic + \ + o---o---o---o---o release + +where we actually want the ``topic`` branch based off ``release`` +instead i.e. + +.. code-block:: bash + + o---o---o---o---o master + \ + o---o---o---o---o release + \ + o'---o'---o' topic + +To fix this situation we use the ``rebase`` command, providing the +``--onto`` option as follows: + +.. code-block:: bash + + git fetch + git rebase --onto origin/release origin/master topic diff --git a/dev-docs/source/IssueTracking.rst b/dev-docs/source/IssueTracking.rst new file mode 100644 index 00000000000..004dd47754f --- /dev/null +++ b/dev-docs/source/IssueTracking.rst @@ -0,0 +1,135 @@ +===================== +Mantid Issue Tracking +===================== + +Mantid uses GitHub issues to track new feature and bugfix +development. The issue tracker can be found at `GitHub +<https://github.com/mantidproject/mantid/issues>`_ + +.. contents:: Contents + :local: + +Workflow +^^^^^^^^ + +Every piece of work starts with an open issue. To find issues that are +assigned to you see the section +:ref:`IssueTrackingYourIssues`. How an issue is closed is +then dependent on its requirements: + +- Code changes required: generate a **pull request** + (:ref:`GitWorkflowPullRequests`) + + - Make sure the issue is referenced with ``#issue-number``. It will + then be closed when the pull request is merged +- No code changes required: Close the issue, with a comment explaining + why the issue should be closed, for example: + + - This is a duplicate of #1234 + - This works for me, when I try the following steps .... + - I've spoken to the author of this issue and it does not happen for + them either anymore + - Contacted the instrument scientists that raised this issue and it + has been solved since version 3.4 + - After further investigation we are not going to continue with this + for the following reasons ... The author of this ticket has been + informed. + - (If the issue is an **umbrella** issue, indicated by the + **Roadmap** label) All points in this issue have been addressed + elsewhere (see issues X, Y, Z) + +Creating an Issue +^^^^^^^^^^^^^^^^^ + +Go `here <https://github.com/mantidproject/mantid/issues/new>`__ to +create a new issue. Make sure you assign the appropriate labels (see +:ref:`IssueTrackingLabels`) and milestone. + +.. _IssueTrackingLabels: + +Labels +^^^^^^ + +GitHub allows you to assign various labels to your issues and pull +requests. Labelling your issues and pull requests adequately will +ensure that they are picked up by the right people. + +Labels fall into several groups: (*please note that 'ticket' is used +to refer to either an issue or a PR on this page*) + +- **Component** - which area of Mantid the ticket concerns. The ticket + may be relevant to more than one area. Some commonly used + **Component** labels are: + + - **Framework**: tickets relating to Algorithms, Workspaces and + SimpleAPI + - **GUI** - tickets relating either to the main MantidPlot GUI, or + one if its custom interfaces + - **Python** - whether the change will be implemented in + Python. This is useful for labelling PRs, as branches in which all + changes are in Python often don't need to be rebuilt to be tested, + so can be picked up more quickly +- **Group** - you may belong to a group within Mantid, such as the + Reflectometry group. Use the corresponding label so that others in + your group can easily find your work to review it +- **Misc** - some of the more common **misc** labels are described + below: + + - **Bug** - used for issues or PRs which reference a specific bug in + the software (as opposed to a new feature, or general + improvements) + - **Induction** - if you come across an issue that may be good for a + new starter (not too difficult, low risk, the relevant code is + comprehensively tested, low(ish) priority) don't hog it for + yourself! Put this label on it so that it can be picked up as an + introduction to the Mantid codebase + - **Roadmap** - useful when planning out a large piece of work - use + this to map out the steps you'll need to take along the way. This + will usually subsume several smaller issues +- **Priority** + + - **Priority: High** - use this if your ticket needs picking up + right away, for instance if it relates to a bug which affects a + large number of users +- **Patch candidate** - following a release, low-risk tickets with + high impact on users will be considered for a follow-up (or *patch* + release). If your ticket matches this description, consider + labelling it as a patch candidate +- **Quality** - not all of Mantid is well-written. Use one of these + labels if your ticket involves improving the quality of the Mantid + codebase (these changes will usually be invisible to users) +- **State: In Progress** - use this label on a PR if the work in that + PR is still ongoing, and you don't want a review yet. **REMEMBER TO + REMOVE IT ONCE YOUR WORK IS READY FOR REVIEW** + +Filtering Issues +^^^^^^^^^^^^^^^^ + +GitHub has a powerful issue filtering system that is described `here +<https://help.github.com/articles/searching-issues>`__. Below we list +some common searches that developers will need. It is advised to +bookmark these URLs. + +.. _IssueTrackingYourIssues: + +Your Issues +----------- + +You can view the issues assigned to you by visiting the `list of +issues <https://github.com/mantidproject/mantid/issues>`_, clicking on +the assignee drop down box and finding your name. + +For Review +---------- + +These are useful links to view when you are looking to review/test an +issue or pull request: + +- Go `here + <https://github.com/mantidproject/mantid/pulls?utf8=%E2%9C%93&q=-author%3AGITHUB-NAME-HERE+is%3Apr+is%3Aopen+-label%3A%22State%3A+In+Progress%22+no%3Aassignee+status%3Asuccess>`__ + for pull requests that you did not create and no one else is + assigned. Please replace GITHUB-NAME-HERE with your GitHub username +- Go `here + <https://github.com/mantidproject/mantid/issues?utf8=%E2%9C%93&q=-assignee%3AGITHUB-NAME-HERE+is%3Aissue+is%3Aopen+label%3A%22State%3A+Review+Required%22+>`__ + for issues with no code changes to review. Please replace + GITHUB-NAME-HERE with your GitHub username diff --git a/dev-docs/source/JenkinsConfiguration.rst b/dev-docs/source/JenkinsConfiguration.rst new file mode 100644 index 00000000000..cceb36dac91 --- /dev/null +++ b/dev-docs/source/JenkinsConfiguration.rst @@ -0,0 +1,460 @@ +.. _JenkinsConfiguration: + +===================== +Jenkins Configuration +===================== + +.. contents:: + :local: + +Summary +####### + +Mantid uses the `Jenkins <https://jenkins.io/>`__ automation server to +support the continuous integration requirements of Mantid. This document +aims to describe the general setup of the system. + +Introduction +############ + +Jenkins works on a 'master->slave' principle. The master node is +responsible for orchestrating jobs and managing the slave nodes, where the +work is actually performed. The master node is located at +http://builds.mantidproject.org and each facility is responsible for providing +hardware to act as slaves for the various required configurations. + +General Setup +############# + +The master node is set to a fixed TCP port for JNLP slave agents under +http://builds.mantidproject.org/configureSecurity. + +The anonymous jenkins user has the following rights: Overall Read, +Slave Connect, Job Read, View Read. + +Setting up a New Slave +###################### + +Machine Setup +------------- + +Set up a local ``builder`` account that will be used by the slave. + +Install the :ref:`required prerequisites <GettingStarted>` for the relevant OS. + +.. note:: + For Windows the `Command line Visual C++ build tools <http://landinghub.visualstudio.com/visual-cpp-build-tools>`__ + may be used in place of a full Visual Studio install from version 2017 onwards (the 2015 tools contain a broken `vcvarsall.bat`). + +Windows +------- + +* Ensure that the location of ``msbuild.exe`` (``C:\Windows\Microsoft.NET\Framework64\v4.0.30319``) is on the ``PATH`` + +Slave Connection +^^^^^^^^^^^^^^^^ + +There are following additional steps required to be able to connect a +Windows slave using JNLP as a Windows service : + +#. Setup the slave on the master node using "New Node" under + http://builds.mantidproject.org/computer/. If "New Node" is not visible + then you do not have the required permissions - ask an admin for help. It is + recommended that you copy from an existing node of a similar type. +#. Once configured on the master, remote desktop to the slave, open a browser and connect to the webpage of the + slave, .e.g. http://builds.mantidproject.org/computer/ornl-pc73896/ +#. Click on the **connect** button to launch the JNLP client. +#. Once the client is launched, you can select "Install as Windows + Service" from the clients menu. If you have a proxy then see the + section below for further configuration steps. +#. Once installed change the recovery behaviour for + the service. Do this by right-clicking on the Jenkins + service->Properties->Recovery. Change the first, second, subsequent + failures to restart the service. +#. Change the account that the service uses to log on by right-clicking + on the Jenkins service->Properties->Log On and enter the details in + the builder account +#. Change the "Startup type:" of the service to be "Automatic (Delayed Start)" +#. Ensure the msbuild directory is on the ``PATH`` +#. Finally reboot the slave (this is the easiest way for the Jenkins to + start trying to reconnect to it) + +Note that changes to ``PATH`` require restarting the Jenkins service in +order to be reflected in the build environment. + +Connecting Through a Proxy Server +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +It is a little more tricky to windows slaves connected through a +proxy.To do this you must modify the java arguments that are used to +start the ``jenkins-slave`` process. Once the "Install as a Windows +Service" has completed you should + +#. Find a directory on the machine such as ``C:\Jenkins``` or whatever + was configured in the slave config. +#. Open the ``jenkins-slave.xml`` file +#. Edit the tag and add ``-Dhttp.proxyHost=PROXYHOST`` + ``-Dhttp.proxyPort=PROXYPORT`` to the list +#. Save the file and restart the service (or machine) + + +Linux +----- + +Install an ssh server. + +Install ``ccache``. After installing run ``ccache --max-size=20G`` from the ``builder`` account. + +Install a vnc server and from the ``builder`` account run ``vncpasswd`` to set a password on the VNC server. It +can be any password. + +Ensure ``curl`` is installed + +Any machines acting as performance test servers will require ``mysqldb`` to be installed. + +Ubuntu +^^^^^^ + +Configure `automatic security updates <https://help.ubuntu.com/community/AutomaticSecurityUpdates>`__. + +Install ``gdebi-core`` package to allow installing ``.deb`` files. + +The ``builder`` account must be setup to be able to run ``gdebi`` non-interactively. Use ``visudo`` to add the following +exception got ``builder``:: + + # Allow no password for gdebi + builder ALL=(ALL)NOPASSWD:/usr/bin/gdebi, /usr/bin/dpkg + ## Disable tty requirement for gdebi and dpkg command + Defaults!/usr/bin/gdebi !requiretty + Defaults!/usr/bin/dpkg !requiretty + +Red Hat +^^^^^^^ + +The ``builder`` account must be setup to be able to run ``yum`` non-interactively. Use ``visudo`` to add the following +exception got ``builder``:: + + ## Allow no password for yum + builder ALL = NOPASSWD: /usr/bin/yum,/bin/rpm + ## Disable tty requirement for yum command + Defaults!/bin/rpm !requiretty + Defaults!/usr/bin/yum !requiretty + +Mac OS +------ + +Enable `SSH ("Remote Login") and VNC ("Remote Management") <https://apple.stackexchange.com/a/73919>`__. If you have +connection issues from a non-OS X client then try adjusting your color depth settings (True Color 32bpp works on Remmina). + +Install ``cppcheck`` from brew. + +The ``builder`` account must be setup to be able to run ``gdebi`` non-interactively. Use ``visudo`` to add the following +exception got ``builder``:: + + + # Allow builder to install packages without a password + builder ALL=(ALL)NOPASSWD:/usr/sbin/installer, /bin/rm + # Disable tty requirement + Defaults!/usr/sbin/installer !requiretty + Defaults!/bin/rm !requiretty + +In order to run the MantidPlot tests, which require a connection to the windowing system, the user that is running the jenkins slave must +have logged in. This is most easily done by VNC - connect, log in, +then disconnect. If you see errors such as:: + + _RegisterApplication(), FAILED TO establish the default connection to the WindowServer, + _CGSDefaultConnection() is NULL. + +then no one is logged in to the system. + +Linux/Mac Connection Notes +-------------------------- + +The jenkins JNLP connections are maintained by a crontab entry. The +script is in the `mantid repository +<https://github.com/mantidproject/mantid/blob/master/buildconfig/Jenkins/jenkins-slave.sh>`__. + +The comments at the top describe a typical crontab entry for the script. This needs to be manually set for each slave. Ensure the script is +marked executable after downloading it. Also ensure the entry in the crontab +has the correct ``PATH`` setting (by default cron uses a reduced ``PATH`` entry). On macOS ``latex`` and ``sysctl`` +should be available. + +Post-Connection Setup - All Systems +----------------------------------- + +Ensure the new machine is added to the relevant `ParaView build job <http://builds.mantidproject.org/view/ParaView/>`__ and build +ParaView. Set the ``PARAVIEW_DIR`` & ``PARAVIEW_NEXT_DIR`` variables +(it's easiest to just look at the configuration for one of the other +nodes of a similar type. + +Misc Groovy Scripts +################### + +The following is a collection of groovy scripts that can be run either +at http://builds.mantidproject.org/script (for master node) or on a +given node, e.g `isis-mantidx3 <http://builds.mantidproject.org/computer/isis-mantidlx3/script>`__. +You must have admin privileges to run them. + +https://github.com/jenkinsci/jenkins-scripts/tree/master/scriptler was helpful for coming up with some of these. + +Print the Value of an Environment Variable on All Nodes +------------------------------------------------------- + +.. code-block:: groovy + + import jenkins.model.* + import hudson.model.* + import hudson.slaves.* + + VARIABLE_NAME = "PARAVIEW_DIR" + + nodes = Jenkins.instance.getNodes() + println("Displaying values of " + VARIABLE_NAME + " on all nodes") + println() + for(node in nodes) { + node_props = node.nodeProperties.getAll(hudson.slaves.EnvironmentVariablesNodeProperty.class) + if(node_props.size() == 1) { + env_vars = node_props[0].getEnvVars() + if(env_vars.containsKey(VARIABLE_NAME)) { + pv_dir = env_vars.get(VARIABLE_NAME, "") + } else { + pv_dir = VARIABLE_NAME + " not set." + } + println(node.getDisplayName() + ": " + pv_dir) + } else { + pv_dir = VARIABLE_NAME + " not set." + } + } + +Update ParaView variables on nodes +---------------------------------- + +**After running this script the variables look like they are updated but +are in fact cached on the slaves so the new values don't take effect +without disconnecting and forcing each slave to reconnect** + +.. code-block:: groovy + + import jenkins.model.* + import hudson.model.* + import hudson.slaves.* + + VARIABLE_NAME = "PARAVIEW_NEXT_DIR" + VERSION = "ParaView-5.1.2" + + jenkins = Jenkins.instance + nodes = jenkins.getNodes() + println("Displaying values of " + VARIABLE_NAME + " on all nodes") + println() + for(node in nodes) { + node_props = node.nodeProperties.getAll(hudson.slaves.EnvironmentVariablesNodeProperty.class) + if(node_props.size() == 1) { + env_vars = node_props[0].getEnvVars() + if(env_vars.containsKey(VARIABLE_NAME)) { + def pv_dir = node.createPath(env_vars.get(VARIABLE_NAME, "")); + if(pv_dir) { + def pv_build_dir = pv_dir.getParent(); + def pv_dir_new = pv_build_dir.child(VERSION); + println(node.getDisplayName() + ": Updating $VARIABLE_NAME from '" + pv_dir.toString() + "' to '" + pv_dir_new.toString() + "'"); + env_vars.put(VARIABLE_NAME, pv_dir_new.toString()); + } + else { + println(node.getDisplayName() + " has variable set but " + env_vars.get(VARIABLE_NAME, "") + " does not exist"); + } + } else { + println(node.getDisplayName() + ": $VARIABLE_NAME " + "not set.") + } + } else { + println(node.getDisplayName() + ": $VARIABLE_NAME " + "not set.") + } + } + jenkins.save(); + +Check existence of ParaView builds +---------------------------------- + +.. code-block:: groovy + + import hudson.model.* + + nodes = Jenkins.instance.slaves + + PV_VERSION = "5.1.2" + + for (node in nodes) { + FilePath root = node.getRootPath(); + if(root) { + FilePath fp = root.getParent(); + // assume this is $HOME on osx/linux & drive: on Windows + if(fp.toString().startsWith("C:")) { + fp = fp.child("Builds") + } else { + fp = fp.child("build"); + } + fp = fp.child("ParaView-$PV_VERSION"); + if(!fp.exists()) { + println(node.getDisplayName() + " does not have PV 5.1.2") + } + } + } + +Remove directories across multiple nodes +---------------------------------------- + +It is advised to ensure nothing is running and pause the build queue. + +Master Incremental +^^^^^^^^^^^^^^^^^^ + +.. code-block:: groovy + + import hudson.model.* + + nodes = Jenkins.instance.slaves + + JOBNAME = "master_incremental" + + + for (node in nodes) { + labels = ["osx-10.10-build", "rhel6-build", "rhel7-build", "ubuntu-14.04-build", "ubuntu-16.04-build", "win7"]; + for (nodeLabel in labels) { + FilePath fp = node.createPath(node.getRootPath().toString() + File.separator + "workspace" + File.separator + JOBNAME + File.separator + "label" + File.separator + nodeLabel + File.separator + "build"); + if(fp!=null && fp.exists()) { + println(fp.toString()) + fp.deleteRecursive() + } + } + } + +Pull Requests +^^^^^^^^^^^^^ + +.. code-block:: groovy + + import hudson.model.* + + nodes = Jenkins.instance.slaves + + JOB_PREFIX = "pull_requests-" + suffixes = ["win7", "osx", "ubuntu", "ubuntu-python3", "rhel7"]; + + for (node in nodes) { + for (suffix in suffixes) { + FilePath fp = node.createPath(node.getRootPath().toString() + File.separator + "workspace" + File.separator + JOB_PREFIX + suffix + File.separator + "build"); + if(fp!=null && fp.exists()) { + println(fp.toString()) + fp.deleteRecursive() + } + } + } + +Update Branches For Jobs +------------------------ + +.. code-block:: groovy + + import hudson.plugins.git.GitSCM + import hudson.plugins.git.BranchSpec + import static com.google.common.collect.Lists.newArrayList; + + def NEW_BRANCH = "*/release-v3.8" + + // Access to the Hudson Singleton + def jenkins = jenkins.model.Jenkins.instance; + + // Retrieve matching jobs + def allItems = jenkins.items + def chosenJobs = allItems.findAll{job -> job.name =- /release_/}; + + println "Updating branch for chosen jobs to $NEW_BRANCH" + println "" + // Do work + chosenJobs.each { job -> + def scm = job.scm; + if (scm instanceof GitSCM && job.name != "release_nightly_deploy" ) { + //def newScm = scm.clone() + println "Updating branch for " + job.name + scm.branches = newArrayList(new BranchSpec(NEW_BRANCH)) + println "Branch for " + job.name + ": " + scm.branches + println "" + } + } + +List All SCM Urls +----------------- + +.. code-block:: groovy + + import jenkins.model.*; + import hudson.model.*; + import hudson.tasks.*; + import hudson.plugins.git.*; + import org.eclipse.jgit.transport.RemoteConfig; + import org.eclipse.jgit.transport.URIish; + + for(project in Hudson.instance.items) { + scm = project.scm; + if (scm instanceof hudson.plugins.git.GitSCM) { + for (RemoteConfig cfg : scm.getRepositories()) { + for (URIish uri : cfg.getURIs()) { + println("SCM " + uri.toString() + " for project " + project); + } + } + } + } + +Print All Loggers +----------------- + +.. code-block:: groovy + + import java.util.logging.*; + + LogManager.getLogManager().getLoggerNames().each() { + println "${it}"; + } + +Run a Process +------------- + +.. code-block:: groovy + + Process p = "cmd /c dir".execute() + println "${p.text}" + + # kill process on windows + Process p = "cmd /c Taskkill /F /IM MantidPlot.exe".execute() + println "${p.text}" + +Update default values for job parameters +---------------------------------------- + +.. code-block:: groovy + + import hudson.model.* + + def SUFFIX_VARIABLE = "PACKAGE_SUFFIX" + def NEW_SUFFIX = "nightly" + + // Access to the Hudson Singleton + def jenkins = jenkins.model.Jenkins.instance; + + // Retrieve matching jobs + def chosenJobs = ["release_clean-rhel7"] //, "release_clean-ubuntu-16.04", "release_clean-ubuntu"] + + println "Updating default package suffix for chosen jobs to ${NEW_SUFFIX}" + println "" + // Do work + chosenJobs.each { jobName -> + job = jenkins.getItem(jobName) + println(job) + paramsDef = job.getAction(ParametersDefinitionProperty) + params = paramsDef.getParameterDefinitions() + params.each { it -> + if(it.getName() == SUFFIX_VARIABLE) { + println("Updating default value of '${SUFFIX_VARIABLE}' variable to '${NEW_SUFFIX}'") + it.setDefaultValue(NEW_SUFFIX) + } + } + + } diff --git a/dev-docs/source/LoadAlgorithmHook.rst b/dev-docs/source/LoadAlgorithmHook.rst new file mode 100644 index 00000000000..3c9c0d92504 --- /dev/null +++ b/dev-docs/source/LoadAlgorithmHook.rst @@ -0,0 +1,63 @@ +=================== +Load Algorithm Hook +=================== + +.. contents:: + :local: + +The Load Algorithm +################## +This page describes how to register a new file loading algorithm so that it can be used through +the general-purpose :ref:`Load <algm-Load>` algorithm. +The :ref:`Load <algm-Load>` algorithm is a special algorithm as does very little work itself. +It instead tries to search for the most suitable algorithm for a given file and then uses this +algorithm as a child to load the file. An algorithm wishing to be included as part of the search +must register itself slightly differently and not use ``DECLARE_ALGORITHM`` macro. + +The process of searching for the correct loader needs to be fairly quick as it will be especially +noticeable in the GUI if the process takes a long time. To speed up the process the loaders are +currently split into 2 categories: + +- HDF - Currently only HDF4/5 +- NonHDF - The rest + +A quick check is performed, using ``HDFDescriptor::isHDF()``, to test whether the file looks like a +`HDF <http://www.hdfgroup.org/>`__ file. +If the check succeeds then only the HDF group of loaders are checked, otherwise only the NonHDF group are checked. + +Descriptors +########### +To avoid the file being opened/closed by each ``confidence`` method, a ``Descriptor`` object is provided. +The actual ``Descriptor`` class depends on whether the file is a HDF file or not. + +HDF +--- +To register an algorithm as a HDF loader use the IHDFLoader interface as a base class for your algorithm. +In your cpp file include the ``MantidAPI/RegisterFileLoader.h`` header and use the ``DECLARE_HDF_FILELOADER`` +macro *instead* of the standard ``DECLARE_ALGORITHM`` macro. + +The interface requires that the method ``virtual int confidence(Kernel::HDFDescriptor & descriptor) const = 0;`` +be overloaded in the inheriting class. It should use the provided descriptor to check whether the loader is +able to load the wrapped file and return a confidence level as an integer. + +HDFDescriptor +^^^^^^^^^^^^^ +This provides methods to query characteristics of the current file to avoid repeated accessing of the tree. + +Non-HDF +------- +To register an algorithm as a Non-HDF loader use the ``IFileLoader`` interface as a base class for your algorithm. +In your cpp file include the ``MantidAPI/RegisterFileLoader.h`` header and use the ``DECLARE_FILELOADER`` macro +*instead* of the standard ``DECLARE_ALGORITHM`` macro. + +The interface requires that the method ``virtual int confidence(Kernel::FileDescriptor & descriptor) const = 0;`` +be overloaded in the inheriting class. It should use the provided descriptor to check whether the loader is +able to load the wrapped file and return a confidence level as an integer. + +FileDescriptor +^^^^^^^^^^^^^^ + +This provides methods to query some characteristics of the current file and also access the open stream to avoid +repeated opening/closing of the file. *Avoid* closing the stream. The code calling the ``confidence`` method ensures +that the stream is back at the start of the file before checking the next loader so simply use the stream as +necessary and leave it as it is. diff --git a/dev-docs/source/Logging.rst b/dev-docs/source/Logging.rst index fcdb01019e5..da2fb4b3e1c 100644 --- a/dev-docs/source/Logging.rst +++ b/dev-docs/source/Logging.rst @@ -50,7 +50,8 @@ For the logging to work you will need to have configured the logging service. Th - Get a reference to the :code:`ConfigService` singleton When the framework is initialised, it attempts to read a file called :code:`Mantid.properties` that it assumes will be available in the current working directory. -This contains among other things the logging configuration. See :ref:`PropertiesFile <PropertiesFile>` for more information. +This contains among other things the logging configuration. See the :ref:`properties file <mantid:Properties File>` overview for more information. + Here is an example: .. code-block:: text diff --git a/dev-docs/source/MVPTutorial/CalculatorExample/index.rst b/dev-docs/source/MVPTutorial/CalculatorExample/index.rst index 87c9c8c32e2..f54745ec4bd 100644 --- a/dev-docs/source/MVPTutorial/CalculatorExample/index.rst +++ b/dev-docs/source/MVPTutorial/CalculatorExample/index.rst @@ -1,10 +1,10 @@ -.. _dev-docs-gui-calculator-example: +.. _MVPCalculatorGUIExample: ========================== MVP Calculator GUI Example ========================== -See the following files for the calculator GUI described in :ref:`dev-docs-mvp-intro`. +See the following files for the calculator GUI described in :ref:`GuiDesignGuidelinesMVPIntro`. - :download:`Main module <Calculator.py>` - :download:`Model.py <Model.py>` diff --git a/dev-docs/source/MVPTutorial/Introduction.rst b/dev-docs/source/MVPTutorial/Introduction.rst index 3eff0214525..1cca72c9170 100644 --- a/dev-docs/source/MVPTutorial/Introduction.rst +++ b/dev-docs/source/MVPTutorial/Introduction.rst @@ -23,4 +23,4 @@ open to interpretation if some files are classed as a View or a Model (this will be discussed in detail later). A more thorough explanation of MVP can be found at -:ref:`dev-docs-mvp-intro`. +:ref:`GuiDesignGuidelinesMVPIntro`. diff --git a/dev-docs/source/MultiThreadingInAlgorithms.rst b/dev-docs/source/MultiThreadingInAlgorithms.rst new file mode 100644 index 00000000000..61abaed070a --- /dev/null +++ b/dev-docs/source/MultiThreadingInAlgorithms.rst @@ -0,0 +1,65 @@ +============================ +Multithreading in Algorithms +============================ + +Mantid uses `OpenMP <http://openmp.org/wp/about-openmp/>`__ to improve +performance within algorithms by parallelizing ``for`` loops. A tutorial +devoted to the technology can be found `here <https://computing.llnl.gov/tutorials/openMP/>`__. + +Access to the OpenMP API is via a set of macros defined in +`MultiThreading.h <https://github.com/mantidproject/mantid/blob/master/Framework/Kernel/inc/MantidKernel/MultiThreaded.h>`__. +This accomplishes seamless fall-back to single-threaded behaviour for +compilers that don't have OpenMP available, as well as providing +protection against multithreading when non-thread-safe workspaces are in use. + +The canonical way to use OpenMP in an algorithm loop (typically +one over the spectra in a workspace) is as follows: + +.. code:: cpp + + PARALLEL_FOR_IF(Kernel::threadSafe(*inputWS, *outputWS)) + for (int i = 0; i < numSpec; ++i) + { + PARALLEL_START_INTERUPT_REGION + + // .... algorithm code .... + + PARALLEL_END_INTERUPT_REGION + } + PARALLEL_CHECK_INTERUPT_REGION + + +The main work is in the first statement, which contains the +instruction invoking OpenMP, but only if the workspaces given are +thread-safe. Analogous macros are available for zero, 2 or 3 workspaces. +Any workspace that is accessed within the loop should be included. There +is then also a set of slightly verbose interrupt instructions, which +prevent exceptions escaping from a parallel region (which would +otherwise cause program termination) - this includes dealing with +algorithm cancellation. + +Ensuring thread-safety +---------------------- + +The first rule is this: **Don't write to shared variables.** Or, if you +do, protect the write with PARALLEL\_CRITICAL or PARALLEL\_ATOMIC calls. +Note that a write to a workspace data spectrum selected by the loop +index is not typically a shared write (though see below). + +One gotcha comes from the use of copy-on-write pointers to store the +workspace data. Here's an example: + +.. code:: cpp + + // Get references to the x data + const auto& xIn = inputWS->x(i); + auto& xOut = outputWS->mutableX(i); + +This can cause problems in the case where the input and output +workspaces are the same. Although the call to ``outputWS->x()`` to get a +reference to the output data may look innocuous, in the case where +different spectra are pointing to the same underlying data array this +call will cause the array to be copied, which will invalidate the +reference obtained to the input data in the previous line. The solution +is to make sure the non-const calls come before the const ones (in this +case by reversing the two lines). diff --git a/dev-docs/source/PatchReleaseChecklist.rst b/dev-docs/source/PatchReleaseChecklist.rst new file mode 100644 index 00000000000..2cd82f12135 --- /dev/null +++ b/dev-docs/source/PatchReleaseChecklist.rst @@ -0,0 +1,151 @@ +.. _PatchReleaseChecklist: + +======================= +Patch Release Checklist +======================= + +.. contents:: + :local: + +These are the steps involved in performing a Mantid patch release. To +perform a full release look see :ref:`ReleaseChecklist`. + +Request +####### + +* Anyone may request a patch release, but that request must be intially + approved by Project manager (Nick) or one of the team leaders (Pete + or Mattieu). + +Authorisation +############# + +* The Project Manager and Team leaders must meet to authorise the patch + release. +* During the meeting other high value, low impact changes may be + considered for inclusion for the release. Any that are to be included + must be added to the patch release notes. +* The Project Manager will create a new milestone in github, and all + tickets to be included must be moved to that milestone. +* A developer will be nominated to be the main reviewer and compiler of + the patch. + +Development +########### + +The patch release will be prepared based off the branch used to +construct to most recent major point release, e.g. ``release-v3.9`` +would be used for any ``3.9.x`` patches. Changes for the patch should be made using the standard GitHub +workflow for merging code with ``master``. The issue and pull request should then have the ``PatchCandidate`` label applied to them. These +commits will then be cherry picked from ``master`` on to the release branch. + +Release Branch +############## + +The release branch will currently have its version fixed to exact +version of the last major/patch release. It is not a requirement but +advised to unfix the patch number while the patch is being compiled. +This prevents the nightly builds from generating a collection of packages that have +exactly the same version. The patch number can be unfixed by commenting the line in +https://www.github.com/mantidproject/mantid/blob/release-vX.Y/buildconfig/CMake/VersionNumber.cmake#L9, where +``X.Y`` should be replace with the appropriate numbers. + +Release Notes +------------- + +Once the patch version has been unfixed the main reviewer should +create a skeleton set of patch release notes on the release branch +using the `python helper tool <https://www.github.com/mantidproject/mantid/blob/master/tools/release_generator/patch.py>`__. + +Cherry Picking & Code Review +---------------------------- + +It is the job of the main reviewer of the release to review each +issue/pull request marked ``PatchCandiate`` and decide if the risks of +the changes are low enough to include in a release that will not +undergo full beta testing by scientists. If it is acceptable then on the release branch for each pull request: + +* find the list of commit ``SHA1`` values in that pull request +* check if any of these commits has altered the release notes for the + next major release +* if not then pass all commits in the order oldest->newest to + ``git cherry-pick -x`` +* if release notes were modified in a commit on their own then pass all + commits except this one in the order oldest->newest to + ``git cherry-pick -x`` +* if a commit has a mixture of code/release note changes then: + + * pass the list of commits up to but not including this commit to + ``git cherry-pick -x`` + * now pass this single commit to ``git cherry-pick -x -n`` and it + will not make a commit. Remove the major release note changes and + commit ``git add``/``git commit`` + * if there are any remaining commits after this then pass them to + ``git cherry-pick -x`` as before. + +* finally add a commit that updates the patch release notes with this + pull request link and description in the table. + +Once cherry picked the milestone of the original pull request should be +updated to the patch milestone. + +Nightly Builds +############## + +The `Jenkins Release Pipeline <http://builds.mantidproject.org/view/Release%20Pipeline/>`__ contains jobs +that check for changes on the current release branch each night (00:00 GMT). Any detected changes will cause a clean build of the code followed +by a run of the system tests. These jobs should be checked each morning +to confirm that everything is green. + +Release Day +########### + +On the day of release a few steps are required: + +* update the patch version: +* navigate to + {{site.mantidrepo}}/blob/release-X.Y./buildconfig/CMake/VersionNumber.cmake, + where ``X`` & ``Y`` are the major and minor release versions + respectively. +* edit the ``VERSION_PATCH`` to the required number for the patch and + commit the result. +* run a manual build of all of the OS jobs under {{ + site.mantidreleasebuilds }} and when asked for a suffix use an empty + string +* wait for the builds to finish (will take more than 1 cup of + tea/coffee/beverage of choice) + +While waiting for the builds create a new release on GitHub, using a tag +of the form ``v.X.Y.Z`` and populate with information from the release +notes (see a previous version of the format). + +Once the builds complete have the development team run unscripted +testing on the packages generated by the clean release builds. In +particular the issues intended to be fixed should be tested. + +Once the testing has passed: + +* Use the manual deploy job at {{ site.mantidreleasebuilds }} to deploy + packages and documentation to the public web. +* The windows binary will **not** be deployed and must be signed by + someone at ISIS and uploaded to sourceforge manually +* Put packages on GitHub +* RHEL 7 only: Build the suffix-package ``mantidXY`` by running another + clean RHEL 7 build at {{ site.mantidreleasebuilds }} but use the + suffix XY, where ``X`` is the major version and ``Y`` is the minor + version (currently used at SNS) +* Have someone at the SNS follow the instructions + `here <http://www.mantidproject.org/Fermi_cluster_at_ORNL>`__ to + deploy an MPI version of the patch release. +* Create new DOI using the scripts in the codebase and instructions on + :ref:`release checklist <ReleaseChecklist>`. +* Send an email, including the text of the release notes, to the + following lists +* ``mantid-announce@mantidproject.org`` +* ``mantid-developers@mantidproject.org`` +* ``nobugs@nobugsconference.org`` +* ``news@neutronsources.org`` +* ``neutron@neutronsources.org`` +* Add topic to the news page on the `forum <http://forum.mantidproject.org/>`__ +* Close the release milestone in github +* Remove the patch candidate tag from pull requests (if not already done) diff --git a/dev-docs/source/MVPPythonViews.rst b/dev-docs/source/QtDesignerForPython.rst similarity index 91% rename from dev-docs/source/MVPPythonViews.rst rename to dev-docs/source/QtDesignerForPython.rst index 40cc1adb477..1ff4b8845df 100644 --- a/dev-docs/source/MVPPythonViews.rst +++ b/dev-docs/source/QtDesignerForPython.rst @@ -1,7 +1,8 @@ -.. _dev-docs-mvp-python-views: +.. _QtDesignerForPython: -Using QtCreator to Generate Python GUI Layouts -============================================== +====================== +Qt Designer for Python +====================== Motivation ---------- @@ -9,7 +10,7 @@ Motivation Code for setting up individual widgets and the layout of a view can become large and difficult to maintain by hand. It usually easier to edit such code using a drag and drop WYSIWYG (What You See Is What You -Get) editor such as Qt Creator. However, doing so requires some +Get) editor such as Qt Creator/Designer. However, doing so requires some additional actions at build time. Implementation @@ -46,11 +47,11 @@ For example the following CMakeLists.txt: UiToPy(UI_FILES CompileUISANSDataProcessorInterface) Produces a cmake target ``CompileUISANSDataProcessorInterface`` which -when built runs +when built runs:: -| ``pyuic4 sans_data_processor_window.ui -o ui_sans_data_processor_window.py`` -| ``pyuic4 settings_diagnostic_tab.ui -o ui_settings_diagnostic_tab.py`` -| ``pyuic4 masking_table.ui -o ui_masking_table.py`` + pyuic4 sans_data_processor_window.ui -o ui_sans_data_processor_window.py + pyuic4 settings_diagnostic_tab.ui -o ui_settings_diagnostic_tab.py + pyuic4 masking_table.ui -o ui_masking_table.py The generated target also runs a script wrap_pyui.py which prepends ``#pylint: skip-file`` to the top of the generated file. @@ -64,8 +65,8 @@ Using the Generated Script -------------------------- When following the MVP design pattern as described at -:ref:`dev-docs-mvp-intro`, the generated file alone is not sufficient -as a :ref:`dev-docs-mvp-view`. Directly accessing the widgets and the +:ref:`GuiDesignGuidelinesMVPIntro`, the generated file alone is not sufficient +as a :ref:`GuiDesignGuidelinesMVPView`. Directly accessing the widgets and the signals defined on the view from the presenter moves the view implementation details into the presenter, which makes it harder to change the names and types of widgets used to display the @@ -188,8 +189,8 @@ the build, the output should contain a line similar to the following: ``[1/1] Generating scripts/Interface/ui/sans/ui_my_widget.py`` -8. Add a separate python file containing the `View -<dev-docs-mvp-view>`__ class which extends the generated one. +8. Add a separate python file containing the `View <GuiDesignGuidelinesMVPView>`__ +class which extends the generated one. .. code:: python diff --git a/dev-docs/source/ReleaseChecklist.rst b/dev-docs/source/ReleaseChecklist.rst new file mode 100644 index 00000000000..22f90135f14 --- /dev/null +++ b/dev-docs/source/ReleaseChecklist.rst @@ -0,0 +1,214 @@ +.. _ReleaseChecklist: + +================= +Release Checklist +================= + +.. contents:: + :local: + +These are the steps involved in performing a full Mantid release. To +request or perform a patch release look at the +`patch release +checklist <%7B%7B%20site.url%20%7D%7D/release_checklist/patch/>`__ + +Timeline +######## + +Releases are normally planned to occur on a Friday, therefore this +page will be refer to days assuming that is correct, if the final +release day is not planned to be Friday then the names of the days +will have to be changed + +Friday, Release-4 weeks +####################### + +**Task Priorities**: Development, Testing, Documentation. + +* Send an email to Mantid-developers reminding developers of the + impending release and stating that they have only 5 days left before + the code freeze. +* Send an email to beta test users explaining the dates for the + testing, and stating they will have more detail on the start of the + first day. +* Invite staff to the release presentation + +Friday, Release-3 weeks +####################### + +**Task Priorities**: Final Development until code freeze, Testing, +Documentation. + +Code Freeze +----------- + +* Send an email to Mantid-developers asking everyone to ensure they + have closed their tickets, stating the code freeze is in place, and + warning developers that non-blocker tickets will be moved from this + release on Monday. +* Final Testing afternoon, attempt to drive the pull requests for this + milestone down to 0. +* Collect all of the completed, fixed tickets for that iteration. +* Parse through the list and short list all of the "major points" that + may be important to the users. + +Monday, Release-2 weeks & 4 days +################################ + +**Task Priorities**: Blocker bug fixes, Testing, Release Notes. + +Unscripted and Final Testing (technical tasks) +---------------------------------------------- + +* Ensure the + `master build and system + test <http://builds.mantidproject.org/view/Master%20Builds/>`__ + jobs have passed for all build environments for this release. +* Complete any ticket testing remaining from Friday +* Run + `open-release-testing <http://builds.mantidproject.org/view/All/job/open-release-testing/>`__ + to create the release branch and prepare build jobs +* Enable and update the release branch name for + `merge\_release\_into\_master <http://builds.mantidproject.org/view/All/job/merge_release_into_master/>`__ +* Check state of all open pull requests for this milestone and update + the base branch to the new release branch accordingly. +* Create a skeleton set of release notes for the next version +* Perform unscripted testing following the instructions described + `here <https://www.mantidproject.org/Unscripted_Manual_Testing>`__. + +Tuesday, Release- 2 weeks & 3 days +################################## + +**Task Priorities**: Blocker bug fixes, Testing, Release Presentation +preparation, Release Notes, Next release development. + +Beta Test Open +-------------- + +* Before sending an email to users, ensure that the Usage data .zip + file containing usage data is up-to-date. This is done by downloading + the current .zip from sourceforge, adding any missing files, and + resending it. +* Send an email to beta test users explaining where to download the + installers and how to report issues. +* Developers to arrange to meet with their beta testers. + +Monday, Release- 4 days +####################### + +**Task Priorities**: Blocker bug fixes, Testing, Release Presentation +preparation, Release Notes, Next release development. + +Beta Test Closes +---------------- + +* At the end of the day email the beta test users thanking them. + +Wednesday, Release-2 days +######################### + +**Task Priorities**: Blocker bug fixes, Testing, Release Notes, Next +release development. + +Thursday, Release-1 day +----------------------- + +**Task Priorities**: Blocker bug fixes, Testing, Release Notes, Next +release development. + +Final Code Changes +------------------ + +* This is the final day for code changes to the build for blocker + tickets + +Friday, Release day +################### + +'''Task Priorities''': Blocker bug fixes, Testing, Release Notes, Next +release development. + +Release (technical tasks) +------------------------- + +Once the unscripted testing has passed: + +* Check the release notes and remove the "Under Construction" paragraph + on the main index page. +* Disable release deploy jobs by executing + `close-release-testing <http://builds.mantidproject.org/view/All/job/close-release-testing>`__ + job. +* On the ``release-vX.Y`` branch, update major & minor versions + accordingly in ``buildconfig/CMake/VersionNumber.cmake``. Also + uncomment ``VERSION_PATCH`` and set it to ``0``. +* Merge ``release`` branch back to ``master`` +* Comment out patch number on ``master`` branch +* Draft a `new + release <https://github.com/mantidproject/mantid/releases>`__ on + GitHub. The new tag should be created based of the release branch in + the form ``vX.Y.Z`` +* Hit build on `release kit + builds <http://builds.mantidproject.org/view/Release%20Pipeline/>`__ + and set the ``PACKAGE_SUFFIX`` parameter to an empty string +* After all of the packages have been smoke tested build the + ``release_deploy`` job to put the packages (not windows) on + Sourceforge. +* Kick off the build for ``mantidXY`` on RHEL7 for SNS: + http://builds.mantidproject.org/job/release_clean-rhel7/ with suffix + ``XY`` +* Make sure someone at ISIS signs the Windows binary and uploads this + manually to Sourceforge +* Set the default package for each OS to the new version +* Upload packages to GitHub once they are ready and have been checked +* Publish the page +* Update the `download <http://download.mantidproject.org>`__ page, + following the instructions + `here <https://github.com/mantidproject/download.mantidproject.org>`__ +* Publish the draft release on GitHub (this will create the tag too). + +Finalise +======== + +* Send an email, including the text of the release notes, to the + following lists +* ``mantid-announce@mantidproject.org`` +* ``mantid-developers@mantidproject.org`` +* ``nobugs@nobugsconference.org`` +* ``news@neutronsources.org`` +* ``neutron@neutronsources.org`` +* Create a new item on the forum news +* Close the release milestone in the issue tracker + +Generate DOI (technical tasks) +------------------------------ + +This requires that a tag has been created for this release, this is done +automatically if a new +`release <https://github.com/mantidproject/mantid/releases>`__ has been +created on GitHub. + +* Make sure that you have updated your local copy of git to grab the + new tag. ``git fetch -p`` +* If the script below fails you may need to update the authors list and + push the updates to master. Look for ``authors.py`` in the + ``tools/DOI`` directory. It does not matter that these are not on the + release branch. + +``python tools/DOI/doi.py --username=_____ X.Y.Z`` + +* Major/minor/patch version numbers must be supplied, as well as a + username which can be found in the `Protected + Information <http://www.mantidproject.org/Protected_Information>`__ + section. The script will prompt for the password. Note that only + MediaWiki admins have access rights to the page. +* A corresponding version tag must be present in the Mantid repo. + +Next release plan +----------------- + +* Prepare the Next release plan. +* Gather user descriptions of priority tickets from developers for the + next release. +* Decide on priority maintenance tasks for the next release. +* Inject Items from the Facility scientific computing strategic plans. +* Compile to a document and release diff --git a/dev-docs/source/RemoteJobSubmissionAPI.rst b/dev-docs/source/RemoteJobSubmissionAPI.rst new file mode 100644 index 00000000000..4133388f09f --- /dev/null +++ b/dev-docs/source/RemoteJobSubmissionAPI.rst @@ -0,0 +1,390 @@ +.. _RemoteJobSubmissionAPI: + +========================= +Remote Job Submission API +========================= + +.. contents:: + :local: + +This document describes the web service API that the Mantid Framework uses to submit algorithms to remote compute +resources. The API is designed to be flexible enough that it can be implemented for just about any compute resource at +nearly any facility. This document should hopefully contain enough detail for programmers & sysadmins at other +facilities to implement the API and allow Mantid users to submit jobs to compute resources at those other facilities. + +A 'compute resource' may be any computer capable of running the Mantid framework. This could range from a single large +server, to some sort of Beowulf cluster to machines with specialized hardware such as GPU's or Intel MIC's. The idea is +that the 'compute resource' will be used to execute tasks that are impractical to run on the user's local workstation. + +The reference implementation is the Fermi cluster at the Oak Ridge Spallation Neutron Source (fermi.ornl.gov). Specific +details of the implementation on Fermi are used as examples throughout this document. + +Basic Requirements For API Implementations +========================================== + +The Mantid framework has certain expectations for the API and it's the responsibility of API implementations to meet +these expectations: + +#. The API provides a mechanism for executing python scripts in an environment that includes the Mantid framework. (ie: + one where "from mantid.simpleapi import \*" works) (Note: exactly \*how\* this happens is purposely left up to the + implementor.) +#. Scripts are executed in a batch environment - interactive scripts are not supported and scripts must be able to run + without input from the user. +#. No mechanism for passing command line parameters to the python scripts is provided. Things like experiment and run + numbers must be hard-coded into the script. (We consider this acceptable because we expect a new script to be + auto-generated by MantidPlot for each job.) +#. Scripts can write output to what is the current working directory when the script starts. These output files will be + available for download back to MantidPlot (or wherever) once the script finishes. +#. Files that were uploaded prior to running the script will be available from the script's working directory. +#. Authentication is used to prevent individual users from interfering with others' jobs (or even reading their files) +#. Data from the various API calls is returned in two ways: the standard HTTP status codes (200, 404, 500, etc...) and + JSON text in the body. (Note: There's no HTML markup in the output.) In the case of error status codes, the JSON + output will contain a field called 'error_msg' who's value is a string describing the error. +#. Clients should assume that all parts of the URL - including query parameters - are case sensitive. However, servers + don't \*have\* to accept URL's with improper case, but may if it makes the code simpler. + +Versioning +========== + +A quick Google search shows that versioning web API's is tricky. The technique employed here will be to use a major +version plus optional extensions. + +Between major versions there are no guarantees of backwards or forwards compatibility. Changing the major version is +essentially starting over from scratch with a clean slate. The major version starts at 1 and will hopefully never +change. + +Backwards-compatible changes are handled by means of optional extensions. + +A server must implement all of the functions defined in the base level of the version and a client may assume those +functions exist. A server is NOT required to implement the extensions (they're optional) and a client may query the +server to discover which extensions are implemented. (Note that what the server returns is really just a name. It's up +to the client and server implementers to agree on exactly what that name means and then document it - presumably here in +this API doc.) + +Backwards-incompatible changes to the API are not allowed. That includes the URL itself, the GET or POST variables it +expects and the JSON that it outputs. If changes are needed, they can be handled through the extension mechanism. For +example, more GET or POST variables could be accepted by the server, so long as they are not required. An extension +should be created (and documented here) so that a client may query the server about whether it supports the new +variables. + +Old GET or POST variables cannot be deleted however. This would break clients that expect to use them. If there's a case +where old varibles no longer make sense, then a completely new URL should be created (and again, documented as an +extension). + +Similar rules apply to the JSON data returned by the API. Extra fields can be added to the JSON returned by a URL, but +original fields may not be removed. + +It's worth noting that it is possible for extensions to be mutually exclusive. + +Authentication +============== + +The initial API uses HTTP Basic-Auth name/password combo for authentication. (Other methods may be added via API +extensions as described above.) Upon successful authentication, a session cookie is created. All other URL's require +this session cookie. + +Because the Basic-Auth scheme does not encrypt the password when it is sent to the server, the use of the HTTPS protocol +is **STRONGLY** encouraged. + +Note that HTTP Basic-Auth is simply the mechanism for passing a username/password combo to the web service. Exactly how +the web service uses that combo to authenticate (and authorize) a user is not specified by the API. Individual +implementations are free to do what they like. (For example, the implementation on Fermi checks the username & password +against an LDAP server.) + +Transactions +============ + +The API details below mention starting & stopping transactions. It should be noted that in this context, the word +transaction doesn't really have anything to do with databases. In this context, transactions are a mechanism for the web +service to associate files with specific jobs. Multiple jobs may be submitted under a given transaction. + +Note that the API doesn't specify how this association occurs. That is a detail left up to the individual +implementation. However, remember the points in the Basic Requirements section above about scripts reading from and +writing to their current working directory while not allowing other users to see or modify their files. That implies +that each job will store files in its own directory and will execute scripts from that directory. (This is, in fact, how +the implementation on Fermi works.) + +A user must start a transaction after authenticating, but before transferring files or submitting job scripts. When the +user's job (or jobs) has finished and the user no longer needs the files associated with the transaction, he or she +should end the transaction. This will allow the web service to delete the files and recover the disk space. + +A Note About File Uploads +========================= + +It is generally assumed that the input files for the submitted python scripts are already available on the compute +resource (presumably via some kind of network filesystem). Thus, although the API allows for file uploads, this is +really intended for relatively small support files that a particular script might need. The HTTP protocol really isn't +intended or suitable for transferring the sort of multi-gigabyte files that are likely to be the inputs for these python +scripts. + +API v1 URL's +============ + +General notes: + +- All URL's expect GET requests unless otherwise noted. +- The session cookie returned by the authentication URL is required by all other URL's (except for the info URL) +- Success is indicated by an HTTP status code in the 200 range. (Typically, 200, but in some cases 201.) Errors are + indicated with error codes in the 400 and 500 range. +- In the case of errors, the JSON output will include a field named "Err_Msg" whose value is a text string describing + the particular error. + + +Information +----------- + ++--------------------------------+-------------------------------------------------------------------------------------+ +| Description | Returns information about the server including the API version and supported | +| | extensions. | ++--------------------------------+-------------------------------------------------------------------------------------+ +| URL | <base_url>/info | ++--------------------------------+-------------------------------------------------------------------------------------+ +| Query Parameters | None | ++--------------------------------+-------------------------------------------------------------------------------------+ +| JSON Output | API_Version : <integer> API_Extensions : [<extension_1>, <extensions_2>, .... ] | +| | Implementation_Specific_Post_Variables : [ <variable_1>, <variable_2>, .... ] | ++--------------------------------+-------------------------------------------------------------------------------------+ +| Notes | May be called without first authenticating. The | +| | 'Implementation_Specific_Submit_Variables' field lists the particular POST | +| | variables that this implementation requires when submitting a job. See the | +| | 'Job Submission <#Job_Submission>`__ URL. | ++--------------------------------+-------------------------------------------------------------------------------------+ + +Authentication +-------------- + ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Description | Authenticate to the web service. | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| URL | <base_url>/authenticate | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Query Parameters | None | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| JSON Output | None | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Notes | Username and password are passed in using HTTP Basic | +| | Authentication Returns a session cookie which must be | +| | passed to the other URL's | ++-----------------------------------------------------------+-----------------------------------------------------------+ + +Transactions +------------ + +This URL has two forms: one to start a new transaction and the other to end an existing transaction. + ++-------------------------------------------------+--------------------------------------------------------------------+ +| Description | Start a new transaction | ++-------------------------------------------------+--------------------------------------------------------------------+ +| URL | <base_url>/transaction | ++-------------------------------------------------+--------------------------------------------------------------------+ +| Query Parameters | Action=Start | ++-------------------------------------------------+--------------------------------------------------------------------+ +| JSON Output | TransID : <string> | ++-------------------------------------------------+--------------------------------------------------------------------+ +| Notes |  | ++-------------------------------------------------+--------------------------------------------------------------------+ + ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Description | End an existing transaction | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| URL | <base_url>/transaction | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Query Parameters | Action=Stop TransID=<transaction_id> | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| JSON Output | None | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Notes | Once a transaction is stopped, any files associated with | +| | it will no longer be available for download and the | +| | server is free to delete those files. | ++-----------------------------------------------------------+-----------------------------------------------------------+ + +File Transfer +------------- + ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Description | Transfer a file from the server back to the client | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| URL | <base_url>/download | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Query Parameters | TransID=<transaction ID> File=<filename> | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| JSON Output |  | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Notes | <filename> does not include any path information. The | +| | actual directory where the file is stored is chosen by | +| | the web service and hidden from the user | ++-----------------------------------------------------------+-----------------------------------------------------------+ + ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Description | Transfer one or more files from the client up to the | +| | server | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| URL | <base_url>/upload | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Query Parameters | None | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| JSON Output | None | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Notes | This is a POST method Multiple files may be submitted | +| | with one call | +| | File(s) are submitted as | +| | multipart form data (ie: "Content-Type: | +| | multipart/form-data" header) | +| | File names should not include | +| | any directory or path information. (Exactly where the | +| | file is stored is left to the web service to determine.) | +| | The transaction ID must also be | +| | specified as form data with a field name of "TransID" | +| | On success, returns a "201 - Created" status code | ++-----------------------------------------------------------+-----------------------------------------------------------+ + +File Listing +------------ + ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Description | Return a listing of files associated with the specified | +| | transaction | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| URL | <base_url>/files | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Query Parameters | TransID=<transaction ID> | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| JSON Output | Files : [ <file_1>, <file_2>, ... <file_n> ] | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Notes | No guarantees are made about the order files are listed | ++-----------------------------------------------------------+-----------------------------------------------------------+ + +Job Submission +-------------- + ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Description | Submit a python script for execution on the compute | +| | resource | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| URL | <base_url>/submit | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Query Parameters | None | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Mandatory POST Variables | TransID : <trans_id> | +| | ScriptName : <name_of_python_script> | +| | <name_of_python_script> : <python code> | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Optional POST Variables | JobName : <name> | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Implementation Specific POST Variables | NumNodes : <number_of_nodes> | +| | CoresPerNode: <cores_per_node> | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| JSON Output | JobID : <job_id> | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Notes | This is a POST method | +| | Request is submitted as multipart form data (ie: | +| | "Content-Type: multipart/form-data" header) | +| | POST variables listed above are individual form data | +| | fields | +| | The content of the "ScriptName" field specifies the name | +| | of the python script. There must be another field with | +| | this name that actually contains the python code. This | +| | allows the web service to keep track of multiple scripts | +| | associated with the same transaction. | +| | The JobName variable allows the user to specify a name | +| | for a job. The name is included in the output of queries. | +| | (Presumably, the user will pick a name that's more | +| | descriptive and easier to remember than the automatically | +| | assigned job ID.) | +| | The Implementation Specific Post Variables are - like the | +| | name says - specific to a particular implementation. They | +| | may not be applicable to all implementations and it's | +| | valid for an implementation to ignore those that aren't. | +| | Which variables are required by a specific implementation | +| | are listed in the `Information <#Information>`__ URL. | +| | (The two specified above are used by the Fermi | +| | implementation, and would probably be valid for all | +| | compute clusters.) | ++-----------------------------------------------------------+-----------------------------------------------------------+ + +Job Query +--------- + +This URL has two forms: one to query a specific job and one to query all of a user's jobs. + ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Description | Query all jobs submitted by the user | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| URL | <base_url>/query | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Query Parameters | None | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| JSON Output | <job_id> : <job_description_object> | +| | <job_id> : <job_description_object> | +| | <job_id> : <job_description_object> | +| | etc... | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Notes | See below for a description of the job_description_object | +| | The length of time the compute resource will 'remember' | +| | jobs is up to the implementer, but several days should be | +| | considered an absolute minimum. (A user should be able to | +| | submit a job on Friday and still be able to query it on | +| | Monday morning.) | ++-----------------------------------------------------------+-----------------------------------------------------------+ + ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Description | Query one specific job submitted by the user | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| URL | <base_url>/query | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Query Parameters | JobID : <job_id> | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| JSON Output | <job_id> : <job_description_object> | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Notes | See below for a description of the job_description_object | +| | The length of time the compute resource will 'remember' | +| | jobs is up to the implementer, but several days should be | +| | considered an absolute minimum. (A user should be able to | +| | submit a job on Friday and still be able to query it on | +| | Monday morning.) | ++-----------------------------------------------------------+-----------------------------------------------------------+ + +The job description object is a JSON object who's fields contain specific information about the job. The fields are: + +- TransID - The transaction ID the job is associated with +- JobName - The name that was given to the submit API +- ScriptName - The name of the python script that was executed +- JobStatus - The execution status of the job. Will be one of: RUNNING, QUEUED, COMPLETED, REMOVED, DEFERRED, IDLE or + UNKNOWN + +Job Abort +--------- + ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Description | Abort a previously submitted job. Jobs that are queued | +| | will be dequeued. Jobs that are running will be stopped | +| | immediately. Jobs that have already completed will simply | +| | be ignored. | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| URL | <base_url>/abort | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Query Parameters | JobID : <job_id> | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| JSON Output | None | ++-----------------------------------------------------------+-----------------------------------------------------------+ +| Notes | Returns a 400 error code if the job ID does not exist. | ++-----------------------------------------------------------+-----------------------------------------------------------+ + +API v1 Extensions +================= + +JOB_DATES +--------- + +The JOB_DATES extension adds three fields to the job_description_object that is returned by queries. The fields are +"SubmitDate", "StartDate" & "CompletionDate" which represent the dates (including time) that the job was first +submitted, when it started executing and when it stopped (either because it finished or because it was interrupted for +some reason). The values are ISO8601 strings suitable for importing into a Mantid DateAndTime object. + +AUTH_USER_NAME +-------------- + +The AUTH_USER_NAME extension adds a single field the the JSON text returned by the 'info' URL. The field name is +'Authenticated_As' and its value is either the name of the user that's been authenticated, or empty if no authentication +has taken place yet. + diff --git a/dev-docs/source/RunningTheUnitTests.rst b/dev-docs/source/RunningTheUnitTests.rst new file mode 100644 index 00000000000..eac7145fa91 --- /dev/null +++ b/dev-docs/source/RunningTheUnitTests.rst @@ -0,0 +1,135 @@ +.. _RunningTheUnitTests: + +====================== +Running the Unit Tests +====================== + +.. contents:: + :local: + +Overview +######## + +We use `CTest <http://www.cmake.org/cmake/help/ctest-2-8-docs.html>`__ +for building and running our unit tests. This wraps the underlying +`cxxtest <cxxtest>`__ or other (e.g. pyunit) test code. + +CMake/CTest: Command Line using a makefile generator +#################################################### + +The unit tests are currently excluded from the 'all' target. To build +the all the tests, including the dependent framework code (in all these +examples in parallel using 8 cores): + +.. code-block:: sh + + make -j8 AllTests + +To build only one package of tests (and its dependencies): + +.. code-block:: sh + + make -j8 KernelTest + +To run all the tests: + +.. code-block:: sh + + ctest -j8 + +To build and run all the tests in one shot: + +.. code-block:: sh + + make -j8 check + +To run a specific test or set of tests (will run all those that match +the search string): + +.. code-block:: sh + + ctest -R KernelTest_TimerTest + +So to run all tests in a suite (using a search string): + +.. code-block:: sh + + ctest -j8 -R KernelTest + +To exclude things from your tests (matches the string as with the -R +option) - useful for those building the performance tests: + +.. code-block:: sh + + ctest -j8 -E Performance + +Useful CTest Options +#################### + +``ctest -h`` gives the full list of command line arguments. Some useful +ones to note are: + +- ``--output-on-failure``: displays the log and any stderr output that + is otherwise hidden by CTest. +- ``--schedule-random``: run the tests in a random order. Useful to + weed out accidental dependencies +- ``--repeat-until-fail``\ : require each test to run times without + failing in order to pass. Useful to try and find random failures + +Running Unit Tests Manually +########################### + +Starting in your build folder (e.g. Mantid/Code/debug): + +- Running an entire test suite (e.g. KernelTest): + + .. code-block:: sh + + ctest -j8 -R KernelTest + bin/KernelTest + +- Running a specific test class. + + .. code-block:: sh + + ctest -R MyTestClassName + bin/KernelTest MyTestClassName + +- Running a specific test. + + .. code-block:: sh + + bin/KernelTest MyTestClassName MySingleTestName`` + + - Not possible with ctest. + +Visual Studio/ XCode note +######################### + +In Visual Studio the user can alter the properties of the subset of +tests (inside the unitTest directory (e.g. AlgorithmTest). In the +properties box it is possible to specify a specific test to run by +typing its name in the TargetName box. Then to execute the test, right +click the subset of tests and select debug and then start new instance. + +To run the tests under one of these environments then you will need to +open a command window and change to the build directory. Once there you +can run the tests by selecting the configuration; + +.. code-block:: sh + + ctest -C Debug -j4 + +This runs all tests in Debug mode (note that this will NOT build any +outdated libraries). To select a subset use the ``-R`` option: + +.. code-block:: sh + + ctest -C Release -R Kernel -j4 + + (-R Kernel), with 4 cores (-j4), in Release mode (-C Release). + +Debugging unit tests +#################### + +See the instructions `here <DebuggingUnitTests>`__ diff --git a/dev-docs/source/AlgorithmDocumentation.rst b/dev-docs/source/Standards/AlgorithmDocumentation.rst similarity index 100% rename from dev-docs/source/AlgorithmDocumentation.rst rename to dev-docs/source/Standards/AlgorithmDocumentation.rst diff --git a/dev-docs/source/AlgorithmUsageExamples.rst b/dev-docs/source/Standards/AlgorithmUsageExamples.rst similarity index 100% rename from dev-docs/source/AlgorithmUsageExamples.rst rename to dev-docs/source/Standards/AlgorithmUsageExamples.rst diff --git a/dev-docs/source/Standards/CPPStandards.rst b/dev-docs/source/Standards/CPPStandards.rst new file mode 100644 index 00000000000..89a81e6236a --- /dev/null +++ b/dev-docs/source/Standards/CPPStandards.rst @@ -0,0 +1,378 @@ +.. _CppCodingStandards: + +==================== +C++ Coding Standards +==================== + +.. contents:: Contents + :local: + +References +^^^^^^^^^^ + +- `LLVM Coding standard <http://llvm.org/docs/CodingStandards.html>`__ +- *The C++ Programming Language* (third edition), Bjarne Stroustrup +- `C++ ANSI Standards <http://www.open-std.org/jtc1/sc22/wg21/>`__ + +Overview +^^^^^^^^ + +Mantid follow the LLVM C++ coding standards and standards on this +page. Where these standards overlap the standards on this page take +precedence. + +`This page +<https://github.com/mantidproject/mantid/wiki/clang-format>`__ +describes a tool that you may find useful for checking your code +satisfies LLVM whitespace conventions. It's also useful to set up your +text editor to use `two spaces instead of tabs +<http://llvm.org/docs/CodingStandards.html#use-spaces-instead-of-tabs>`__. + +Files +^^^^^ + +- Header files will use the ``.h`` extension. +- Code body files will use the ``.cpp`` file extension. +- All ``.cpp`` files must have a corresponding ``.h`` file. + +Headers +^^^^^^^ + +Header Files +------------ + +All header files in a project must have a header comment. In many +cases this will be included as part of the class header, but any +header files that do not contain classes must include the same +information as a file header. The information that must be included +is: + +- class description +- Copyright +- GPL license text + +Layout of Header File +--------------------- + +The contents of the header file should be arranged in the following +order: + +- ``#include`` directives in the following order, where each section shold be + sorted alphabetically: + + - Main Module Header + - Mantid Headers from the same project + - Mantid headers from other projects + - 3rd party library headers + - System ``#include`` directives +- Forward declarations of other classes +- Global constants, enumerations & typedefs +- Doxygen class description +- Class definition: + + - Public constants, enumerations & types + - Public constructors & destructors + - Public functions & operators + - Protected functions + - Private constants, enumerations & types + - Private functions + - Private variables + - Bodies of inline functions and (for a template class) member + functions. + +In most cases header files should only contain a single class. The only +exceptions to this should be for internal utility classes, and extremely +small highly related classes such as exception classes. + +CPP file Headers +---------------- + +We will not be including body file headers. The relevant class file +header in the ``.h`` file will suffice. + +Function headers +---------------- + +These will follow the style put forward in the `Doxygen documentation +<http://www.stack.nl/~dimitri/doxygen/docblocks.html>`__. Headers +comments must be included above all functions definitions and should +describe the function, all parameters and returns values as a minimum. + +Where a function is declared in the header file and defined in the +``.cpp`` file the following approach should be taken: + +- The header file need only contain documentation for items that do + not appear in a ``.cpp`` file (e.g. the class itself, member + variables, inlined methods and templated classes). This keeps the + header files compact and easier to read. Brief comments can + optionally be included (as in the example below). + +Example header file function declaration + +.. code-block:: c++ + + /// Creates an instance of an algorithm + IAlgorithm* createAlgorithm(const std::string& algName, const int& version); + +Example CPP file function definition + +.. code-block:: c++ + + /** Creates and initialises an instance of an algorithm + * + * @param algName The name of the algorithm required + * @param version The version of the algorithm + * @return A pointer to the created algorithm + * + * @throw NotFoundError Thrown if algorithm requested is not registered + */ + IAlgorithm* FrameworkManagerImpl::createAlgorithm(const std::string& algName, const int& version) { + IAlgorithm* alg = AlgorithmManager::Instance().create(algName,version).get(); + return alg; + } + +Naming Conventions +^^^^^^^^^^^^^^^^^^ + +Names should be descriptive and meaningful, but not too long (say <20 +characters). This is helped by sensible and consistent (across the +project) use of abbreviations. + +- **Constants** (including static const members): All upper + case. Internal words separated by underscore eg: ``ERROR_NO_DATA`` +- **Classes, namespaces, structs, enums (and enum values) and typedefs**: + PascalCase (First letter upper case, then lower + case. Internal words begin with upper case letter). +- **Function Names**: function names will be in camelCase (starting + with a lower case character and capital for each later word). +- **Variable Names / Type Prefixes**: variables will be given sensible + descriptive names. Type prefixes will not be used. variable names + in Mantid are usually camelCase (starting with a lower case + character and capital for each later word). +- **Scope Prefixes** + - Static member variables use a ``g_`` prefix. + - Non-static member variables use an ``m_`` prefix. +- **Local variables used as integer loop counters** As an exception, + these may use very short names like ``i, j, k, l`` eg. ``for (int + i = 0; i < 5; i++)`` + +Preprocessor +^^^^^^^^^^^^ + +1. Use of the pre-processor should be minimised. Constants and type + aliases should be declared using ``const`` and ``typedef`` rather + than ``#define``, and functions should be used in favour of macros. +2. ``#include`` statements should use quotes (``""``) for inclusion of + Mantid code and angle brackets (``<>``) for system files (this + includes headers from ``Third_Party``) +3. All header files should have guards against repeated inclusion, + with the guard flags named consistently. (See `here + <https://en.wikipedia.org/wiki/Include_guard>`__ for an + explanation) +4. Header files should only include those other header files within + the project that are necessary (e.g. for definition of the base + class). In many cases a forward declaration of the form ``class + CPidClientObject;`` is sufficient, and this helps to avoid cyclical + inclusions of headers. +5. It should be possible to compile each header file + individually. That is, a file consisting solely of ``#include + "header.h"`` should compile without errors. This avoids + undocumented interdependencies between headers. + +Classes and Namespaces +^^^^^^^^^^^^^^^^^^^^^^ + +1. There should be only one class or namespace declared in each header + file. This recommendation should only be relaxed where classes are + closely tied together. +2. There should be only one class or namespace defined per body file + (unless classes are closely tied as in (1) above). All the + definitions for that class/namespace should be in the one file + (unless this yields a source file that is unmanageably large). +3. Data members should be private. Access to data from other classes + should only be through protected or public methods (or by + ‘friends’, but see item 8). Inside a large class, consider + reserving direct access to private data members for a smaller + manageable core of member functions. +4. All constructors for a class must initialise all its member variables + that do not have a default constructor (including primitive and + pointer types). +5. All base classes must have a virtual destructor. + + - This may be disregarded only in exceptional circumstances when + the overhead of a virtual-table would significantly affect + performance. Such a class must not be subclassed, and must be + adequately commented to warn other developers against subclassing + the class. + - In addition, it is recommended that where possible, programming + techniques are used to prevent inheritance of classes with a + non-virtual destructor. While comments may suffice they can + easily be ignored or misunderstood, particularly by inexperienced + developers + +6. Classes’ constructors and destructors must not call their own virtual + member functions, directly or indirectly. (C++ does not resolve such + function calls polymorphically.) +7. Do not define special members functions when they would be + identical to those automatically generated by the compiler. Use ``= + delete`` to remove invalid compiler-generated versions. Consider + following the `rule-of-zero <https://rmf.io/cxx11/rule-of-zero/>`__ + and writing an additional class for resource management. +8. The use of ``friend`` should be avoided and its use requires + justification. As an exception, overloads of the ``<<`` and ``>>`` + operators for serialising the class may be declared as ``friend``. +9. Use of multiple inheritance should be restricted to cases in which + the second and subsequent base classes are all interfaces. (An + interface in this context is a class consisting only of pure virtual + functions.). +10. Virtual inheritance should only be used when the base class + involved is an interface. +11. Unions and bitfields should only be used where essential for + performance, or where required for interfacing with a third party + library. + +Mantid Namespaces +----------------- + +All Mantid code lives within a minimum of a two tiered namespace. The +outer namespace for all Mantid code is Mantid, and this is followed by +a namespace identifying the library that contains the code. Third and +further level namespaces may be used to section code to further +improve readability and maintenance. + +Functions and Variables +^^^^^^^^^^^^^^^^^^^^^^^ + +1. Variables, functions parameters, and function return values must have + explicit types (no defaulting to ``int``). +2. A function declaration should not use ``void`` to indicate an empty + parameter list. +3. Parameters in function prototypes should include names, not just + their types. For example, use ``void eraseRange(int nFirst, int + nLast);`` rather than ``void eraseRange(int, int);`` as this + improves self-documentation. +4. Non-static member functions should be declared ``const`` if logically + they do not alter the state of the class instance. +5. Simple accessor functions may be inline (e.g. ``inline int + getCount() const { return m_nCount;}``). Otherwise, inline + functions should be avoided unless essential for performance. +6. Operators should be overloaded sparingly. Operator overloads should + behave in accordance with the semantics of the operator as applied + to primitive types, or according to established conventions + (e.g. ``<<`` and ``>>`` for serialisation). +7. ‘Magic numbers’ must not be used in the code. Constants and + enumerations must be used instead. + +Expressions and Statements +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +1. Integers should not be cast to Booleans. For example, prefer ``if (x + != 0)`` rather than ``if(x)`` +2. The new style type casting must be used in place of the old C style + type casts. If casting up or down an inheritance hierarchy, use + ``dynamic_cast`` (which performs a run-time type check) rather than + ``static_cast``. +3. Function calls with side effects, and the ``++``/``--``/assignment operators, + should only be called as a standalone statement rather than embedded + inside an expression. + + - It is permissible, although discouraged, to have a function call + with side effects as the right-operand of ``&&`` or ``||``. Any such + instances must be commented in detail to alert other developers to + the fact that the function is not always called. +4. ``for`` and ``while`` loops should not use ``break`` and + ``continue`` where they can be avoided. Where they are required, + comments should draw attention to them as an alternative exit point + from the loop. +5. A ``for`` loop should only have one control variable, and should + not modify it in the body. +6. ``switch`` statements must include a ``default`` clause, even if + only to catch errors. +7. Each ``case`` of a ``switch`` statement must either end with a + ``break``/``return``, or contain a clear comment to alert other + developers to the fact that execution will fall through to the next + case. Multiple ``case`` labels (with no code between them) are, + however, permitted for the same block of code. +8. ``goto`` must be avoided. When there is a need to break out of two + or more nested loops in one go, the loops should be moved to a + separate function where 'return' can be used instead. + +Comments +^^^^^^^^ + +1. Sufficient commenting (to the level mandated by this document) of a + piece of code must be performed at the same time as the code is + written. It must not be put off until the end of development. When + code is updated, all relevant comments must be updated as well + (including those in the header). +2. ‘Dead code’ must not be kept in the source code. (‘Dead code’ here + means code that has been commented out or unconditionally + suppressed in some other way, for example using ``#if 0`` + preprocessor directives.) + + - In the (rare) instances that dead code would serve an important + documentation purpose for ongoing development, the dead code must + be placed in an external location and may be referenced from the + ‘live’ source code. +3. Comments must be indented to the same level as the code to which + they refer. +4. The language used in comments must be professional and to the + point. Flippant or derogatory remarks must be avoided. +5. The collection of comments in a function must, on its own, be + sufficient that a competent C++ developer can pick up the function + for subsequent development. +6. Comments on a single line should use ``//`` rather than ``/* … */``. +7. No code block should exceed 20 statement lines without a comment of + some sort. In general all code should contain 15% comment lines. +8. The style of the comments is not mandated here. However the following + are general recommendations: + + - Comments should always be used to describe potential “difficult†+ sections of code utilising, for example, special algorithms + - Comments should be used in particular to explain branch conditions + in ``if ... else`` and ``switch { case ...``-like statements + - **Comments should be written at a higher level of abstraction + than the code to which they pertain, rather than merely + restating it** + +Error Handling +^^^^^^^^^^^^^^ + +The type of error handling needed depends on what the code is +doing. In daemon / service type of program almost nothing may be +allowed to cause the process to terminate, whereas in some utility +programs it may be acceptable to terminate for many error +conditions. This is a design issue and the strictness of application +of the following should take into account the use of the code. + +1. The developer should identify all errors that can be generated by a + function and ensure that they are dealt with appropriately at some + point in the system. This may be within the function itself or + higher up in the call stack. +2. All exceptions must be caught and handled properly. (This may + include terminating the program cleanly, for instance if no more + memory can be allocated.) +3. Public functions should check their input parameters before using + them. This checking may be made using the ``assert()`` macro or + similar mechanism, and so only checked in the debug build, in which + case comprehensive testing must be performed of the release build. +4. All error status values returned from a function call must be checked + or explicitly ignored. (To explicitly ignore a function call's return + value cast it to void, e.g. ``(void) f(a, b);``) +5. When using ``dynamic_cast`` on a pointer, a check must be made that + the result is not ``null`` (i.e. that the cast was successful). +6. Destructors must not throw any exceptions, directly or indirectly. + (Exceptions encountered while calling destructors during stack + unwinding from an earlier exception will cause immediate program + termination.) +7. Where the language permits it, and where the occurrence of errors + can be identified at coding time (e.g. opening a file), errors + should be trapped on an individual basis, rather than using a + catch-all error handler. +8. Error messages displayed to the user must be understandable and + informative. They must suggest an action to the user, which will + resolve the problem, for example: + + - No further action is required. + - Check the XYZ input data and then repeat the process. + - Contact the system administrator. diff --git a/dev-docs/source/DocumentationGuideForDevs.rst b/dev-docs/source/Standards/DocumentationGuideForDevs.rst similarity index 100% rename from dev-docs/source/DocumentationGuideForDevs.rst rename to dev-docs/source/Standards/DocumentationGuideForDevs.rst diff --git a/dev-docs/source/InterfaceDocumentation.rst b/dev-docs/source/Standards/InterfaceDocumentation.rst similarity index 100% rename from dev-docs/source/InterfaceDocumentation.rst rename to dev-docs/source/Standards/InterfaceDocumentation.rst diff --git a/dev-docs/source/Standards/Libraries.rst b/dev-docs/source/Standards/Libraries.rst new file mode 100644 index 00000000000..391175de080 --- /dev/null +++ b/dev-docs/source/Standards/Libraries.rst @@ -0,0 +1,53 @@ +.. _Libraries: + +========= +Libraries +========= + +.. contents:: Contents + :local: + +Summary +^^^^^^^ + +This page describes the preferred libraries used with the Mantid code +base. + +General +^^^^^^^ + +- Use libraries from `std <http://en.cppreference.com/w/cpp>`_ where possible. +- `Boost <http://www.boost.org>`_ header-only libraries are also + always available. The following compiled Boost libraries are + available: + + - regex + - date_time + - python + - serialization + - others required must be discussed with the TSC + +- Eigen is used for fast linear algebra calculations +- Poco is also used for: + + - asynchronous method support + - application configuration + - logging + - path handling (will eventually be replaced by std::filesystem) + - networking + - XML parsing + +Specific Recommendations +^^^^^^^^^^^^^^^^^^^^^^^^ + +Regex +----- + +Prefer ``boost::regex`` over ``std::regex`` (bugs in ``std::regex`` +until gcc 5 and some platforms still use gcc 4.8) + +String Algorithms (chop, ends_with etc) +--------------------------------------- + +- Prefer Boost algorithms if possible +- Some string utilities also exist in ``MantidKernel/Strings.h`` diff --git a/dev-docs/source/Standards/MantidStandards.rst b/dev-docs/source/Standards/MantidStandards.rst new file mode 100644 index 00000000000..adfa95c3bee --- /dev/null +++ b/dev-docs/source/Standards/MantidStandards.rst @@ -0,0 +1,119 @@ +================ +Mantid Standards +================ + +These standards relate specifically to the implementation of the +Mantid framework and the MantidPlot application. + +.. contents:: Contents + :local: + +General Notes on Naming +^^^^^^^^^^^^^^^^^^^^^^^ + +The items described on this page form part of the public interface to +Mantid, which means that their names are hard to change once they are +out in the wild. As naming is one of the most difficult tasks to `do +well <http://martinfowler.com/bliki/TwoHardThings.html>`_, it is +important to take time and care when choosing a name. Some guidance on +naming in a more code-related context can be found `here +<http://blog.codinghorror.com/i-shall-call-it-somethingmanager/>`_ but +the advice should still be applicable to naming Mantid concepts. + +Algorithms +^^^^^^^^^^ + +Standards to follow when implementing an `algorithm +<http://docs.mantidproject.org/nightly/concepts/Algorithm.html>`_ in +both C++ and Python. + +Naming +------ + +Algorithm names start with a capital letter and have a capital letter +for each new word, with no underscores. Use alphabet and numeric +characters only. Numbers are only allowed after the first character. + +Names should be descriptive but not too long (max 20 chars). If +possible, avoid abbreviations unless they are common and well +understood. To avoid a proliferation of different synonyms for +algorithms that have a common goal, e.g. Create... vs Generate..., we +standardise on a set of prefixes for common tasks: + ++-----------------------------------------------------------------------+------------------+--------------------+ +| Task | Preferred Prefix | Example | ++=======================================================================+==================+====================+ +| Creating a new object, e.g. workspace, with exception of file loaders | Create | CreateMDWorkspace | ++-----------------------------------------------------------------------+------------------+--------------------+ +| Loading a file | Load | LoadMappingTable | ++-----------------------------------------------------------------------+------------------+--------------------+ +| Applying a value to an existing object, e.g set UB matrix | Set | SetUB | ++-----------------------------------------------------------------------+------------------+--------------------+ +| Retrieve a value, e.g. Ei | Get | GetDetectorOffsets | ++-----------------------------------------------------------------------+------------------+--------------------+ +| Adding a new item to an existing list | Add | AddSampleLog | ++-----------------------------------------------------------------------+------------------+--------------------+ +| Search for something, e.g. peaks | Find | FindPeaks | ++-----------------------------------------------------------------------+------------------+--------------------+ + +Categories +---------- + +Plain english using `Title Case +<http://www.grammar-monster.com/lessons/capital_letters_title_case.htm>`_. Connecting +words should have lower case first letters. Use alphabet characters +only, numbers are not allowed, e.g. Muon or SANS. + +Properties +---------- + +Property names start with a capital letter and have a capital letter +for each new word, with no underscores. Use alphabet and numeric +characters only. Numbers are only allowed after the first character. + +Wherever possible and unambiguous, the primary input workspace should +be called ``InputWorkspace`` and the primary output workspace should +be called ``OutputWorkspace``. An algorithm with a single In/Out +workspace should name its property ``Workspace``. Certain groups of +algorithms have other standards to adhere to. + +Fit Functions +^^^^^^^^^^^^^ + +Standards to following when implementing a fitting function (both C++ +& Python). + +Naming +------ + +Function names start with a capital letter and have a capital letter +for each new word, with no underscores. Use alphabet and numeric +characters only. Numbers are only allowed after the first character. + + +Categories +---------- + +Plain english using `Title Case +<http://www.grammar-monster.com/lessons/capital_letters_title_case.htm>`_. Connecting +words should have lower case first letters. Numbers are not allowed. + +Parameters +---------- + +Parameter names must: + +- Start with a capital letter +- Have a capital letter for each new word (e.g. 'InputWorkspace') +- Use alphanumeric characters only (i.e. cannot contain any of these ``/,._-'\"`` or whitespace) +- Can contain numbers but only allowed after the first character. + +Notable exceptions to these rules are lattice constants (i.e. a, b, c, +alpha, beta, gamma). + +Workspace Names +^^^^^^^^^^^^^^^ + +No firm restrictions. The use of two underscores as a prefix will mark +the workspace as hidden. It is recommended to use only the alphabet, +numeric and the underscore characters. diff --git a/dev-docs/source/Standards/PythonStandards.rst b/dev-docs/source/Standards/PythonStandards.rst new file mode 100644 index 00000000000..605cb141fb1 --- /dev/null +++ b/dev-docs/source/Standards/PythonStandards.rst @@ -0,0 +1,65 @@ +======================= +Python Coding Standards +======================= + +.. contents:: Contents + :local: + +Style +^^^^^ + +- Unless otherwise specified, follow `PEP 8 + <https://www.python.org/dev/peps/pep-0008>`_; this means using + `snake_case <https://en.wikipedia.org/wiki/Snake_case>`_ +- Use `flake8 <http://flake8.pycqa.org/en/latest>`_ to check + for problems in this area. Remember that PEP 8 is only a guide, so + respect the style of the surrounding code as a primary goal +- Always use four spaces for indentation +- For docstrings please follow `Docstring Conventions PEP 257 + <https://www.python.org/dev/peps/pep-0257>`_ and document code to + aid `sphinx + <https://pythonhosted.org/an_example_pypi_project/sphinx.html#full-code-example>`_ + +None checks +----------- + +Prefer ``if obj is not None:`` over ``if obj:``. The latter invokes +``object.__nonzero__`` whereas the former simply compares that obj +references the same object as ``None``. + +Imports +------- + +Imports should be grouped in the following order: + +1. stdlib +2. third party libraries +3. local modules + +Each group should be alphabetically sorted and separate by a newline, e.g. + +.. code-block:: python + + import sys + + from qtpy.QtWidgets import QMainWindow + + from mypackage.subpkg import MyClass + +Python/Qt +^^^^^^^^^ + +Use the `qtpy <https://pypi.python.org/pypi/QtPy>`_ module to hide the +differences between PyQt versions. When working with signals, use the +new style. For naming new custom signals, use the ``sig_`` prefix: + +.. code-block:: python + + from qtpy.QtCore import Signal + ... + + class MyWidget(...): + """Funky new widget""" + + # Signals + sig_run_a_thing_happened = Signal(str, str, str, bool, bool) diff --git a/dev-docs/source/Standards/UnitTestStandards.rst b/dev-docs/source/Standards/UnitTestStandards.rst new file mode 100644 index 00000000000..04c82103bbe --- /dev/null +++ b/dev-docs/source/Standards/UnitTestStandards.rst @@ -0,0 +1,25 @@ +.. _UnitTestCodingStandards: + +========================== +Unit Test Coding Standards +========================== + +The code for unit test classes should follow the standards as set out +in :ref:`CppCodingStandards` with the following differences. + +- The file and class name should be of the form ``ClassNameTest``, for + example ``WorkspaceTest``, ``LoggerTest`` +- Test classes do not need to be included in a namespace. +- Test methods within the test classes must start with the word 'test' + and then describe the test. For example ``test_readXValues``, + ``test_invalidLogString`` +- Other utility methods may be used in test classes but must not start + with the word test +- During debugging Test methods may be disabled by prefixing the + method name with 'x'. However if any disabled tests are to be + checked in this must be accompanied with comments explaining why the + test is disabled and when it may be enabled again. +- Code headers are not required if the above standards are met as the + use of the class will be obvious from the class name and method + names. + diff --git a/dev-docs/source/Standards/index.rst b/dev-docs/source/Standards/index.rst new file mode 100644 index 00000000000..20709a3f984 --- /dev/null +++ b/dev-docs/source/Standards/index.rst @@ -0,0 +1,44 @@ +.. _Standards: + +========= +Standards +========= + +Coding Standards +---------------- + +Coding standards are vital for creating a maintainable and extensible +system. However in order for them to be effective they have to be +accepted and supported by the entire development team. + +Code produced by code generators is not covered directly by this +procedure. Programmers must apply the underlying principles of this +procedure in a sensible manner to code generated automatically. + +.. toctree:: + :maxdepth: 1 + + MantidStandards + CPPStandards + UnitTestStandards + PythonStandards + +Documentation Standards +----------------------- + +.. toctree:: + :maxdepth: 1 + + DocumentationGuideForDevs + AlgorithmDocumentation + AlgorithmUsageExamples + InterfaceDocumentation + + +Guidelines +---------- + +.. toctree:: + :maxdepth: 1 + + Libraries diff --git a/dev-docs/source/SystemTests.rst b/dev-docs/source/SystemTests.rst new file mode 100644 index 00000000000..faf2276d5cd --- /dev/null +++ b/dev-docs/source/SystemTests.rst @@ -0,0 +1,228 @@ +.. _SystemTests: + +============ +System Tests +============ + +.. contents:: + :local: + +Overview +######## + +System tests are high-level tests, which check that Mantid is able to +reproduce accepted, standardised results as part of its calculations, +when executing user stories. The system test suite is written against +Mantid's Python API. + +As part of our nightly-build and nightly-test procedure, Mantid's system +tests are run as acceptance tests. The nightly-test jobs deploy a +packaged version of Mantid to the target OS, before executing the system +tests scripts on that environment. + +Writing a Test +############## + +The (python) code for the system tests can be found in the git +repository at +`mantidproject/mantid <http://github.com/mantidproject/mantid>`__, under +the ``Testing/SystemTests`` directory. + +Like their 'stress' equivalents (`stress testing <Stress_Tests>`__), +system tests inherit from the stresstesting.MantidStressTest class. The +methods that need to be overridden are ``runTest(self)``, where the +python code that runs the test should be placed, and ``validate(self)``, +which should simply return a pair of strings: the name of the final +workspace that results from the ``runTest`` method and the name of a +nexus file that should be saved in the ReferenceResults sub-directory in +the repository. The test code itself is likely to be the output of a +*Save History* command, though it can be any python code. In the +unlikely case of files being used during a system test, implement the +method ``requiredFiles`` which should return a list of filenames without +paths. The file to validate against should be included as well. If any +of those files are missing the test will be marked as skipped. + +The tests should be added to the ``Testing/SystemTests/tests/analysis``, +with the template result going in the ``reference`` sub-folder. It will +then be included in the suite of tests from the following night. + +Specifying Validation +--------------------- + +You may need to inform the System Test Suite about the format of that +the benchmark workspace you wish to validate against. By default, the +system tests assume that the second argument returned by the validate +tuple is the name of a nexus file to validate against. However you can +override the validateMethod on a test with any one of three options. + +- WorkspaceToNexus (Benchmark workspace is stored as a Nexus file) + (default) +- WorkspaceToWorkspace (Benchmark workspace is stored as a workspace) +- ValidateAscii (Benchmark workspace is stored as an ascii file) + +For example: + +.. code-block:: python + + def validateMethod(self): + return 'WorkspaceToNeXus' + +No Workspace Validation +----------------------- + +If the system test does not need comparison/validation against a +standard workpace, then this step can be skipped. Simply omitting the + +.. code-block:: python + + def validate(self): + +method from the system test is sufficient. + +Skipping tests +-------------- + +Tests can be skipped based on arbitrary criteria by implementing the +``skipTests`` method and returning True if your criteria are met, and +False otherwise. Examples are the availability of a data file or of +certain python modules (e.g. for the XML validation tests). + +Target Platform Based on Free Memory +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some tests consume a large amount memory resources, and are therefore +best executed on hardware where enough memory is available. You can set +a minimum RAM specification by overriding requiredMemoryMB: + +.. code-block:: python + + def requiredMemoryMB(self): + return 2000 + +The above function limits the test to run on a machine where there is at +least 2GB of free memory. + +Target Platform Based on Free Memory +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some tests require very large files that cannot be placed in the shared +repository. The ``requiredFiles()`` method returns a list of these files +so that they test can check that they are all available. If all files +are not available then the tests are skipped. + +.. code-block:: python + + def requiredFiles(self): + return ['a.nxs', 'b.nxs'] + +The above function limits the test to run on a machine that can find the +files 'a.nxs' & 'b.nxs' + +Set the Tolerance +----------------- + +You may specialise the tolerance used by ``CompareWorkspace`` in your +system test. + +.. code-block:: python + + self.tolerance = 0.00000001 + +Disable Some Checks +------------------- + +You may disable some checks performed by the ``CompareWorkspaces`` +algorithm by appending them to the disableChecking list, which, by +default, is empty. + +.. code-block:: python + + # A list of things not to check when validating + self.disableChecking = [] + +Assertions +---------- + +Additional assertions can be used as the basis for your own comparison +tests. The following assertions are already implemented in the base +class. + +.. code-block:: python + + def assertTrue(self, value, msg=""): + def assertEqual(self, value, expected, msg=""): + def assertDelta(self, value, expected, delta, msg=""): + def assertLessThan(self, value, expected, msg=""): + def assertGreaterThan(self, value, expected, msg=""): + +Running Tests Locally +##################### + +CMake configures a script file called ``systemtest`` (``systemtest.bat`` +on Windows) in the root of the build directory. This file is the driver +script to execute the system tests that runs the lower-level +``Testing/SystemTests/scripts/runSystemTests.py`` script but ensures +that the environment is set up correctly for that particular build and +that the required test data has been updated. The script accepts a +``-h`` option to print out the standard usage information. + +Usage differs depending on whether you are using a single-configuration +generator with CMake, for example Makefiles/Ninja, or a +multi-configuration generator such as Visual Studio or Xcode. + +Visual Studio/Xcode +------------------- + +The user must first open command-prompt from, the build directory. The +script requires the developer to select the configuration that will be +used to execute the tests, one of: *Release*, *Debug*, *RelWithDebInfo* +or 'MinSizeRelease''. Note that the script does not build the code so +the chosen configuration must have already been built. An example to +execute all of the tests for the release configuration would be (in the +command-prompt): + +.. code-block:: sh + + > systemtest -C Release + +Makefile-like Generators +------------------------ + +The script requires no additional arguments as the configuration is +fixed when running CMake, e.g. + +.. code-block:: sh + + cd build + systemtest + +Selecting Tests To Run +---------------------- + +The most important option on the script is the ``-R`` option. This +restricts the tests that will run to those that match the given regex, +e.g. + +.. code-block:: sh + + cd build + systemtest -R SNS + # or for msvc/xcode + systemtest -C <cfg> -R SNS + +would run all of the tests whose name contains SNS. + +Adding New Data & References Files +---------------------------------- + +The data is managed by CMake's external data system that is described by +`Data_Files_in_Mantid <Data_Files_in_Mantid>`__. Please see `Adding a +new file <Data_Files_in_Mantid#Adding_A_New_File>`__ for how to add new +files. + +Best Practice +############# + +- Always check your test works locally before making it public. +- User stories should come from the users themselves where possible. +- Take care to set the tolerance to an acceptable level. diff --git a/dev-docs/source/TSC.rst b/dev-docs/source/TSC.rst new file mode 100644 index 00000000000..dcab065a261 --- /dev/null +++ b/dev-docs/source/TSC.rst @@ -0,0 +1,13 @@ +.. _TSC: + +============================ +Technical Steering Committee +============================ + +Please see the `TSC terms <https://github.com/mantidproject/documents/blob/master/Project-Management/TechnicalSteeringCommittee/TSC-Terms.md>`__ +for a description of the aims of this committee including a list of current members. + +Contact email: mantid-tech@mantidproject.org + +Minutes and reports from Technical Steering Committee meetings can be found +`here <http://github.com/mantidproject/documents/tree/master/Project-Management/TechnicalSteeringCommittee>`__. diff --git a/dev-docs/source/TestingUtilities.rst b/dev-docs/source/TestingUtilities.rst new file mode 100644 index 00000000000..5f109ed05d0 --- /dev/null +++ b/dev-docs/source/TestingUtilities.rst @@ -0,0 +1,50 @@ +.. _TestingUtilities: + +================= +Testing Utilities +================= + +.. contents:: + :local: + +Summary +####### + +This page will provide developers with details of testing utilities, such as helper files, which are +useful in creating unit tests. + + +Helper Functions +################ + +C++ +--- + +The following helper files have been found in the +`Mantid/Framework/TestHelpers <http://github.com/mantidproject/mantid/tree/master/Framework/TestHelpers>`__ +package: + +- `BinaryOperationMDTestHelper <http://doxygen.mantidproject.org/d1/d4f/namespaceBinaryOperationMDTestHelper.html>`__ +- ComponentCreationHelper + `ComponentCreationHelper <http://doxygen.mantidproject.org/d8/d8d/namespaceComponentCreationHelper.html>`__ + This creates instrument components that can then be used in a unit test. +- ICatTestHelper +- `MDEventsTestHelper <http://doxygen.mantidproject.org/d5/d75/namespaceMantid_1_1MDEvents_1_1MDEventsTestHelper.html>`__ +- `SANSInstrumentCreationHelper <http://doxygen.mantidproject.org/d9/dbf/classSANSInstrumentCreationHelper.html>`__ +- `ScopedFileHelper <http://doxygen.mantidproject.org/d7/d7f/classScopedFileHelper_1_1ScopedFile.html#details>`__ + This creates a file that is automatically deleted when no longer needed. +- `WorkspaceCreationHelper <http://doxygen.mantidproject.org/d1/db6/namespaceWorkspaceCreationHelper.html>`__ + This creates simple workspaces that can be used in a unit test. One of these workspaces has a full instrument. + +Python +------ + +There are some ``testhelpers`` which are only available in Python, they can +be found in the ``testhelpers``-package. + +- ``make_decorator`` - A function that returns a decorator for an + algorithm without executing it. +- ``TemporaryFileHelper`` - A class that creates named temporary files + and deletes them automatically when the object is deleted. Basically + a thin wrapper around `NamedTemporaryFile <https://docs.python.org/2/library/tempfile.html>`__ + from the tempfile package. diff --git a/dev-docs/source/UsefulTools.rst b/dev-docs/source/ToolsOverview.rst similarity index 98% rename from dev-docs/source/UsefulTools.rst rename to dev-docs/source/ToolsOverview.rst index e2c6e3c22f2..f16eee15b30 100644 --- a/dev-docs/source/UsefulTools.rst +++ b/dev-docs/source/ToolsOverview.rst @@ -1,5 +1,8 @@ -Useful Tools for Developers -=========================== +.. _ToolsOverview: + +============== +Tools Overview +============== Creating classes: class_maker.py -------------------------------- diff --git a/dev-docs/source/UnitTestGoodPractice.rst b/dev-docs/source/UnitTestGoodPractice.rst new file mode 100644 index 00000000000..4863ea92339 --- /dev/null +++ b/dev-docs/source/UnitTestGoodPractice.rst @@ -0,0 +1,191 @@ +.. _UnitTestGoodPractice: + +======================= +Unit Test Good Practice +======================= + +.. contents:: + :local: + +General Guidance +################ + +What to test +------------ + +Simply put you should test. + +- Every public member of a class. +- That the class can be cast to any of the interfaces or base classes + it inherits from. +- Any private or protected members. + + - That aren’t directly covered by a public method test. + - That do any significant processing. + +For each method you are testing you should include tests for the +following: + +- To confirm that the methods meet the requirements associated with + them. Thus the test should verify that the function does what it is + supposed to do. +- To confirm the expected behaviour for boundary and special values. +- To confirm that exceptions are thrown when expected. + +How to test private or protected members of a class +--------------------------------------------------- + +Testing the internals of a class can be considered harmful as it exposes +the internals of the class, which can arguably be freely changed (so +long as it does not affect the function of the public interface). +However there are cases where the internals of a class need unit tests +either due to complexity or tracking down specific bugs. + +In the circumstance where the implementation within the private/protected +methods of a class is sufficiently complex, such to require dedicated unit +tests, this code should be moved into a separate class(es). + +Protected +~~~~~~~~~ + +Within the test library you can add a new testable class that inherits +from the class you need to test. This class can simply expose any +protected methods as testable public methods. + +Private +~~~~~~~ + +There is no ideal way to test a private member of a class as they are +intentionally hidden from the class interface. There are two options to +consider in preference order: + +#. Change the protection level to protected and follow the approach + above. +#. Declare the test class as a friend, which can access private members. + +Good practices for writing tests +-------------------------------- + +The following are good practices for writing your unit tests. Many of +them are standard good coding practices. You will notice that in several +situations they can clash with each other, in this case common sense +needs to be applied. + +- Unit tests should test one method only. This allows you to easily + identify what failed if the test fails. +- Unit tests should not be coupled together, therefore one unit test + **CANNOT** rely on another unit test having completed first. + +These two often clash, in which case it is often better to compromise on +the first, and in fact we have relaxed this rule for Mantid (see below). + +- Units tests should use realistic data +- Unit tests should use small and simple data sets. + +Again these can often conflict. + +- Each test class should be named after the class it is testing (e.g. + tests for the ``AlgorithmFactory`` should go in a ``AlgorithmFactoryTest`` + class). +- Each test within a test class should use a descriptive test name, + prefixed with test (tests for the ``CreateAlgorithm`` method would be + included in ``testCreateAlgorithm``). If there are specific tests for + failure situations then these should be added to the end (e.g. + ``testCreateAlgorithmNoAlgorithmException``). THE AIM IS THAT FROM THE + TEST METHOD NAME ALONE, YOU SHOULD BE ABLE TO IDENTIFY THE PROBLEM. + +Other More General Points +~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Tests should be **fast**, ideally really fast - certainly not more + than a few seconds. Unit tests test functionality, performance tests + can be used to check stress and timings. +- Untestable code is a code-smell, if you can't get the code under test + it probably needs refactoring. +- Weight your testing to be destructive rather than demonstrative. + Destructive tests have a higher efficacy for finding bugs. + +Mantid-specific Guidelines +########################## + +- As noted above, you can assume that individual tests within a cxxtest + suite will be run in order. +- There must be **no relative paths** (or, more obviously, absolute + ones) used in tests as with CMake the code can be build anywhere with + respect to the source tree. Make use of the datasearch.directories + property (which CMake configures to hold correct paths for a given + build). +- Ideally, test suites should not have a constructor. If one is + required, the following boiler-plate code **must** be inserted in the + test class: + + .. code-block:: c++ + + static NameOfTest *createSuite() { return new NameOfTest(); } + static void destroySuite(NameOfTest *suite) { delete suite; } + + where ``NameOfTest`` is the name of the test class. Without this, the + class is turned into a static meaning that the constructor is run at + initialisation even if (via an argument) you are not going to run that + particular test suite. Also, this can cause problems if running tests in + parallel. + +- Be cautious in use of the ``setUp()``and ``tearDown()`` methods. Be aware + that if you use these in your suite they will be run before/after + **every single** individual test. That's fine if it's the behaviour + you really need, but we have found that to be rare - use the + constructor or set things up within the test. +- To avoid clashes, use unique names for workspaces that will go into + the [Analysis Data Service], perhaps by prepending the name of the + test suite. Even better, don't put workspaces into the ADS in the + first place: for example, an InputWorkspace property can be set via + pointer instead of by name. +- Clean up the ADS at (or before) the end of the test suite. + +Using files in Unit tests +------------------------- + +Files for unit tests bloat our repository and slow down the testing +process. Therefore unless the prime purpose of the algorithms is to load +or save a file then you should not use a file in your unit tests. + +How do I get a workspace filled with data? + Firstly you want to think about how much data you really need, unit + tests need to be fast so you don't want too much data. + Secondly you should use and extend helper classes (like + `1 <https://github.com/mantidproject/mantid/blob/master/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h>`__) + to provide the workspaces for you. Keep things as generic as you can + and it will help you and others for other tests. + More details of this will be provided at `Testing Utilities <TestingUtilities>`__. +I want a workspace with a valid instrument definition and Spectra-detector map + As above use or extend a method in one of the `helper classes <TestingUtilities>`__ + that actually creates a minimal workspace for you in code - it will + only hurt the first time but everyone will benefit. + Loading instrument XML files in debug **really** hurts performance; + avoid this like the plague. +What if it **really** needs a file + First justify your reasoning with the PM or Lead developer + Ensure the file is as small as possible. Perhaps edit the file to + only contain 2 spectra + Note: this is not the same as just loading 2 spectra from a large + file. + Do not use a relative path to a file + Used the `Scoped + File <https://github.com/mantidproject/mantid/blob/master/Framework/TestHelpers/inc/MantidTestHelpers/ScopedFileHelper.h>`__ + helper, to ensure that resources are cleaned-up in an exception safe + manner. + +Mocking +####### + +Mocking is a very powerful tool that allows you to simulate components +in your unit environment and check how your code operates within this +environment. Mocking allows you to avoid creating Fake objects of any +kind, and results in fast executing code with a very high test coverage. +See `Mocking <Mocking>`__ in Mantid to find out what it is and how it +works. + +.. figure:: images/Mocking.png + :alt: Object under test using Mocking to isolate the testing.|400px + + Object under test using Mocking to isolate the testing.|400px diff --git a/dev-docs/source/WritingAnAlgorithm.rst b/dev-docs/source/WritingAnAlgorithm.rst new file mode 100644 index 00000000000..01f567db695 --- /dev/null +++ b/dev-docs/source/WritingAnAlgorithm.rst @@ -0,0 +1,249 @@ +.. _WritingAnAlgorithm: + +Writing An Algorithm +==================== + +.. contents:: + :local: + +Introduction +############ + +Mantid's `plugin <https://www.mantidproject.org/Plugin>`__ architecture has been engineered so that it is easy for a user +to write their own algorithm. This page is a primer for the user about to write their first algorithm and assumes no +great knowledge of C++. +It covers the basics, with links to more advanced options where appropriate. Note if you are looking to add a +`plugin <https://www.mantidproject.org/Plugin>`__ fit function rather than an algorithm then see +`Writing a Fit Function <https://www.mantidproject.org/Writing_a_Fit_Function>`__. +There is special description for the case when you are looking to add a custom `MD conversion plugin <WritingCustomConvertToMDTransformation>`__. + +Alternatively, you can implement your algorithm in `Python <https://www.mantidproject.org/Extending_Mantid_With_Python>`__. +See `Python Vs C++ Algorithms <https://www.mantidproject.org/Python_Vs_C%2B%2B_Algorithms>`__ for a comparison of Mantid's +two programming languages. + +All `algorithms <https://www.mantidproject.org/Algorithm>`__ in Mantid `inherit <http://en.wikipedia.org/wiki/Inheritance_(computer_science)>`__ +from a base ``Algorithm`` class, which provides the support and services required for running a specific +algorithm and greatly simplifies the process of writing a new one. + +Getting Started +############### +The first step is to create a new directory, with any name of your choice, under your MantidInstall directory +(on Windows, probably located at ``C:\\MantidInstall``). Alternatively, you can just do everything in the +UserAlgorithms directory. The UserAlgorithms directory contains a simple Python script called ``createAlg.py``. +This can be used to create a new 'empty' algorithm - to create one called 'MyAlg' you should type ``python +createAlg.py myAlg category``, where category is an optional argument to set the algorithm's category. +To do the same thing 'by hand', create files called ``MyAlg.h`` and ``MyAlg.cpp`` and paste in the following +boilerplate C++ code (changing each occurrence of 'MyAlg' to your chosen algorithm name): + +**Header file (MyAlg.h)**: + +.. code-block:: cpp + + #ifndef MYALG_H_ + #define MYALG_H_ + + #include "MantidAPI/Algorithm.h" + + class MyAlg : public Mantid::API::Algorithm + { + public: + /// (Empty) Constructor + MyAlg() : Mantid::API::Algorithm() {} + /// Virtual destructor + virtual ~MyAlg() {} + /// Algorithm's name + virtual const std::string name() const { return "MyAlg"; } + /// Algorithm's version + virtual const int version() const { return (1); } + /// Algorithm's category for identification + virtual const std::string category() const { return "UserDefined"; } + + private: + /// Initialisation code + void init(); + /// Execution code + void exec(); + }; + + #endif /*MYALG_H_*/ + +**Source file (MyAlg.cpp)**: + +.. code-block:: cpp + + #include "MyAlg.h" + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(MyAlg); + + void MyAlg::init() + { + } + + void MyAlg::exec() + { + } + +At this point you will already have something that will compile and run. To do so (on Windows), copy the files +``build.bat`` & ``SConstruct`` from ``UserAlgorithms`` into the directory containing your code and execute ``build.bat``. +If you then start MantidPlot your algorithm will appear in the list of available algorithms and could be run. +But, of course, it won't do anything of interest until you have written some algorithm code... + +Coding the Algorithm +#################### + +You will see that the algorithm skeletons set up in the last section contain two methods/functions/subroutines +called ``init`` and ``exec``. It will be no surprise to discover that these will, respectively, contain the code to +initialise and execute the algorithm, which goes in the ``.cpp`` file between the curly brackets of each method. +Note that these are private methods (i.e. cannot be called directly); an algorithm is run by calling the base +class's ``initialize()`` and ``execute()`` methods, which provide additional services such as the validation of properties, +fetching workspaces from the ``AnalysisDataService``, handling errors and filling the workspace histories. + +Initialization +-------------- + +The initialization (init) method is executed by the ``FrameworkManager`` when an algorithm is requested and must +contain the declaration of the properties required by the algorithm. Atypically, it can also contain other +initialization code such as the calculation of constants used by the algorithm, so long as this does not +rely on the values of any of the properties. + +Calls to the ``declareProperty`` method are used to add a property to this algorithm. See the properties page +for more information on the types of properties supported and the example algorithms in ``UserAlgorithms`` +(especially `PropertyAlgorithm <http://svn.mantidproject.org/mantid/trunk/Code/Mantid/UserAlgorithms/PropertyAlgorithm.cpp>`__ +and `WorkspaceAlgorithm <http://svn.mantidproject.org/mantid/trunk/Code/Mantid/UserAlgorithms/WorkspaceAlgorithm.cpp>`__) +for further guidance on how to use them. + +For the simple types (integer, double or string), the basic syntax is:: + + declareProperty("UniquePropertyName",value); + +An optional `validator <https://www.mantidproject.org/Properties#Validators>`__ or +`directional argument <https://www.mantidproject.org/Properties#Direction>`__ (input, output or both) +can also be appended. The syntax for other property types (``WorkspaceProperty`` & ``ArrayProperty``) is more +complex - see the `properties <https://www.mantidproject.org/Properties#Direction>`__ page or the +example algorithms in `UserAlgorithms <https://www.mantidproject.org/UserAlgorithms>`__ for further details. + +Execution +######### + +Fetching properties +------------------- + +Before the data can be processed, the first task is likely to be to fetch the values of the input properties. +This uses the ``getProperty`` method as follows:: + + TYPE myProperty = getProperty("PropertyName"); + +where ``TYPE`` is the type of the property (``int``, ``double``, ``std::string``, ``std::vector``...). Note that the +value of a ``WorkspaceProperty`` is a `shared pointer <https://www.mantidproject.org/Shared_Pointer>`__ +to the workspace, which is referred to as ``Mantid::API::Workspace_sptr`` or ``Mantid::API::Workspace_const_sptr``. +The latter should be used for input workspaces that will not need to be changed in the course of the algorithm. + +If a handle is required on the property itself, rather than just its value, then the same method is used as follows:: + + Mantid::Kernel::Property* myProperty = getProperty("PropertyName"); + +This is useful, for example, for checking whether or not an optional property has been set (using Property's +``isDefault()`` method). + +Creating the output workspace +----------------------------- + +Usually, the result of an algorithm will be stored in another new workspace and the algorithm +will need to create that new workspace through a call to the ``WorkspaceFactory``. For the (common) +example where the output workspace should be of the same type and size as the input one, the code +would read as follows:: + + Mantid::API::Workspace_sptr outputWorkspace = Mantid::API::WorkspaceFactory::Instance().create(inputWorkspace); + +where ``inputWorkspace`` is a shared pointer to the input workspace. + +It is also important to, at some point, set the output workspace property to point at this workspace. +This is achieved through a call to the ``setProperty`` method as follows:: + + setProperty("OutputWorkspacePropertyName",outputWorkspace); + +where ``outputWorkspace`` is a shared pointer to the created output workspace. + +Using workspaces +---------------- + +The bulk of most algorithms will involve the manipulation of the data contained in workspaces +and information on how to interact with these is given `here <https://www.mantidproject.org/Interacting_with_Workspaces>`__. +The more advanced user may also want to refer to the full +`workspace documentation <http://doxygen.mantidproject.org/nightly/d3/de9/classMantid_1_1API_1_1Workspace.html>`__. + +Those familiar with C++ should make use of private methods and data members to break up the execution code into +more manageable and readable sections. + +Further Features +################ + +The advanced user is referred to the `full documentation page <http://doxygen.mantidproject.org/nightly/d3/de9/classMantid_1_1API_1_1Workspace.html>`__ +for the ``Algorithm`` base class to explore the full range of methods available for use within an algorithm. +A few aspects are highlighted below. + +Child Algorithms +---------------- + +Algorithms may wish to make use of the functionality of other algorithms as part of their execution. +For example, if a units change is required the ``ConvertUnits`` algorithm could be used. Mantid therefore +has the concept of a child algorithm and this is accessed through a call to the +``createChildAlgorithm`` method as follows:: + + Mantid::API::Algorithm_sptr childAlg = createChildAlgorithm("AlgorithmName"); + +This call will also initialise the algorithm, so the algorithm's properties can then be set and it can be executed:: + + childAlg->setPropertyValue("number", 0); + childAlg->setProperty<Workspace_sptr>("Workspace",workspacePointer); + childAlg->execute(); + +Logging +------- + +The ``g_log`` object enables access to the `logging <Logging>`__ facilities of Mantid, and is an invaluable +tool in understanding the running of your algorithms. + +Enhancing asynchronous running +------------------------------ + +Any algorithm can be run asynchronously (e.g. by MantidPlot) without modification. However, some features +are only enabled if code is added within the ``exec()`` method. ``Algorithm::interruption_point()`` should +be called at appropriate intervals so that the algorithm's execution can be interrupted. +``Algorithm::progress(double p)`` reports the progress of the algorithm. ``p`` must be between +0 (start) and 1 (finish). + +Exceptions +---------- + +It is fine to throw exceptions in your algorithms in the event of an unrecoverable failure. +These will be caught in the base Algorithm class, which will report the failure of the algorithm. + +Validation of inputs +-------------------- + +`Validators <https://www.mantidproject.org/Properties#Validators>`__ allow you to give feedback +to the user if the input of a property is incorrect (for example, typing non-numeric characters +in a number field). + +For more advanced validation, override the ``Algorithm::validateInputs()`` method. This is a +method that returns a map where: + +- The key is the name of the property that is in error. + +- The value is a string describing the error. + +This method allows you to provide validation that depends on several property values at once +(something that cannot be done with ``IValidator``). Its default implementation returns an empty map, +signifying no errors. + +It will be called in dialogs **after** parsing all inputs and setting the properties, but **before** executing. +It is also called again in the ``execute()`` call, which will throw if this returns something. + +In the MantidPlot GUI, this will set a "star" ``*`` label next to each property that is reporting an error. +This makes it easier for users to find where they went wrong. + +If your ``validateInputs()`` method validates an input workspace property, bear in mind that the user +could provide a ``WorkspaceGroup`` (or an unexpected type of workspace) - when retrieving the property, +check that casting it to its intended type succeeded before attempting to use it. diff --git a/dev-docs/source/WritingCustomConvertToMDTransformation.rst b/dev-docs/source/WritingCustomConvertToMDTransformation.rst new file mode 100644 index 00000000000..6267db5a208 --- /dev/null +++ b/dev-docs/source/WritingCustomConvertToMDTransformation.rst @@ -0,0 +1,197 @@ +.. _WritingCustomConvertToMDTransformation: + +Writing a Custom ConvertToMD Transformation +=========================================== + +.. contents:: + :local: + +Introduction +############ + +This information is intended for a developer who needs to write a customized +`ConvertToMD class <http://docs.mantidproject.org/nightly/algorithms/ConvertToMD.html>`__ (plugin). The +plugin then becomes automatically available to use in the +`ConvertToMD <http://docs.mantidproject.org/nightly/algorithms/ConvertToMD.html>`__ algorithm and via the +`Create MD workspaces <http://www.mantidproject.org/Create_MD_Workspace_GUI>`__ +interface to produce multidimensional workspace for further visualization and analysis. + +As the MD transformation factory is similar to the `Dynamic Factory <http://www.mantidproject.org/Dynamic_Factory>`__ +used for `converting units <http://docs.mantidproject.org/nightly/concepts/UnitFactory.html>`__, the +procedure of writing a custom ``ConvertToMD`` transformation is very similar to adding a new unit to use +with `ConvertUnits <http://docs.mantidproject.org/nightly/algorithms/ConvertUnits.html>`__ algorithm +or writing a new algorithm to use with Mantid. + +The plugin interface deals with the task of converting a generic n-dimensional point of a ``MatrixWorkspace`` +into a generic m-dimensional point of an ``MDWorkspace`` using the necessary parameters. + +Examples of such transformations could be a conversion of signal and error at detector num +at specific time of flight plus log values for temperature and pressure (**The instrument's +space**: 4 numbers + information about the detector) into 6-D point in the **Physical space +qx,qy,qz,dE,T,P** (qx,qy,qz -- the components of momentum transfer) or into 3-D point in +**Physical space \|Q\|,dE,Fugacity** (\|Q\| - modulus of momentum transfer). + +Writing a simple custom plugin +############################## + +Summary +------- + +If a single point of a ``MatrixWorkspace`` together with correspondent log files can be converted into a single +``MDEvent`` (multidimensional point of MD workspace), a simple custom plugin can be written to do this transformation. +The existing framework in this case deals with all other tasks, namely the iterations over source workspace, +conversion of the workspace units into the units of the conversion formula, defining the target workspace, +constructing ``MDEvent`` instances and adding these events to the ``MDWorkspace``. + +A ``ConvertToMD`` plugin implements ``MDTransfInterface``, so to write a plugin you must write a class +which inherits from this interface and register this class with ``MDTransfFactory``. The macro to +register the class with the factory is similar to the macro used to register an algorithm with +Mantid or a ``Unit`` class with the Unit conversion factory. The macro is located in ``MDTransfFactory.h``. + +The class inheriting from ``MDTransfInterface`` performs two tasks: + +- Define the target ``MDWorkspace`` and its dimensions (both the number of dimensions and the dimension units). + +- Initialize the transformation and define a formula to transform a single point of input data into output data. + +These two tasks are mainly independent, but implemented within a single class to be handled by the single dynamic factory. +**Note that the functions which define the target MDWorkspace are called before the MDTransfFactory initialize function.** +The ``initialize`` function accepts the ``MDWorkspace`` description and is expected to fully define all class variables used during +the transformation from a point of a ``MatrixWorkspace`` into an MD point of a target ``MDWorkspace``. + +Workflow +-------- +This workflow is implemented in the ``ConvertToMD`` algorithm's ``exec()`` function. + +#. Select a conversion and obtain additional algorithm parameters from the algorithm interface. + +#. Build ``MDWorkspace`` description (call ``MDTransfFactory`` and ask for the conversion plugin parameters). + +#. Build new ``MDWorkspace`` on the basis of its description (if new workspace is requested or check if existing workspace is suitable). + +#. Initialize the conversion plugin (using ``MDWSDescription``). + +#. Run the conversion itself by looping over detectors and their values (use ``MDTransfFactory`` and selected conversion plugin to convert + each input point into output MD point). + +The ``MDTransformationFactory`` is deployed twice during the conversion. The methods used during each conversion stage are clearly +specified in ``MDTransformationInterface.h``. + +Defining the target workspace +----------------------------- + +This describes steps 1-3 of the workflow. + +The input data at this stage are the name of the plugin and the outputs -- the information necessary for the transformation to work +including the number of output dimensions, units for the selected physical transformation formula, units of the target workspace, etc. + +The methods used while defining the workspace should not access or change anything accessed through this pointer of +the custom plugin. The result of the first stage is a ``MDWSDescription`` class, which can be considered +as a large XML string that provides a common interface to different data obtained from the algorithm's parameters. +Any data users want to transfer to the custom plugin can be added to this class, as long as this does not lead to +excessive memory usage or overhead. + +The ``MDWSDescription`` class is copy constructable and assignable and if these operators fail due to the changes +to the class, custom copy constructor and assignment operators have to be defined. + +Doing the transformation +------------------------ + +This describes steps 4-5 of the workflow. + +The input data at this stage are points of the "Experimental Space", e.g. coordinates of points in the input workspace and +additional information about these points, e.g. detectors coordinates and log files for values of interest. The output values +are the vectors of the coordinates of the selected points in the space of interest and (possibly) modified/corrected values of +the signal and error at this point. + +During the second stage of the transformation, the algorithm calculates the multidimensional coordinates of MD points in the +target workspace, places these coordinates into an MD vector of coordinates and modifies the neutron signal/error if necessary +(e.g. Lorentz corrections). This stage can be best described by the pseudo-code below. It describes performing the conversion +over the whole workspace: + +.. code-block:: cpp + + /** initialize all internal variables used for transformation of workspace into MD workspace + WorkspaceDescription -- the workspace description obtained on the first stage of the transformation */ + plugin->initialize(WorkspaceDescription); + /** calculate generic variables, which are usually placed in logs and do not depend on detectors positions + or neutron counts (e.g. temperature) and place these values into proper position in the coordinates vector. */ + if(!plugin->calcGenericVariables(std::vector<coord_t> &Coord, size_t N_Dimensions)) + return; // finish if these data are out of range requested + + for(i in array of detectors) + { + /** Here we calculate all MD coordinates which depend on detectors position only. The plugin also + changes the internal plugin values which depend on detector's position e.g. sets up the unit conversion */ + if(!plugin->calcYDepCoordinates(std::vector<coord_t> &Coord,size_t i)) + continue; // skip detector if these data are out of range requested + + /** obtain signal and error, array, corresponding to the i-th detector */ + spectra[i] = InputWorkspace->getSpectraCorrespondingToTheDetector(size_t i); + + /**Convert units into the units, requested by the plugin */ + MantidVector X = convertUnits(spectra[i].X_coordinates); + for(j in spectra[i]) + { + Signal = spectra[i].Signal[j]; + Error = spectra[i].Error[j]; + /**Calculate remaining MD coordinates and put them into vector of coordinates. + Modify Signal and error if the signal and error depends on Coord */ + plugin->calcMatrixCoordinates(const MantidVec& X, size_t i, size_t j, + std::vector<coord_t> &Coord, Signal, Error); + + /**Convert Coord signal and error to MD event with coordinate Coord and add the MDEvent to MD workspace*/ + AddPointToMDWorkspace(Coord,Signal,Error); + } + } + +PreprocessDetectorsToMD with custom plugins +------------------------------------------- + +Unit conversion uses the angular positions and sample-detector distances. +This information is usually expensive to calculate so it is calculated separately by the +`PreprocessDetectorsToMD <http://docs.mantidproject.org/nightly/algorithms/PreprocessDetectorsToMD-v1.html>`__ algorithm. +The detector information can be extracted directly from the input workspace, but consider checking the table workspace +returned by `PreprocessDetectorsToMD <http://docs.mantidproject.org/nightly/algorithms/PreprocessDetectorsToMD-v1.html>`__ +and check if the information is already provided there. + +`PreprocessDetectorsToMD <http://docs.mantidproject.org/nightly/algorithms/PreprocessDetectorsToMD-v1.html>`__ can also +be modified to add some additional detector information. This information can then be added to the resulting table workspace +and used in the custom plugin. +All currently existing plugins use the information about the detector's positions calculated by +`PreprocessDetectorsToMD <http://docs.mantidproject.org/nightly/algorithms/PreprocessDetectorsToMD-v1.html>`__. + +Complex Transformations +####################### + +It is possible that the approach of converting a single point of a ``MatrixWorkspace`` into a single ``MDEvent`` is +incorrect or inefficient for what is required. In this situation, more complex changes to the conversion framework +have to be implemented. +To make the changes one needs to understand the interaction between different classes involved in the conversion. + +The class diagram with all main classes involved in the conversion is presented below: + +.. figure:: images/ConvertToMDClassDiagram.gif + :alt: ConvertToMDClassDiagram.gif + +Two factories are involved into the conversion. ``MDTransfFactory`` deals with different formulae to +transform a single matrix point into an MD point. The other factory (``ConvToMDSelector`` and the algorithm inheriting +from ``ConvToMDBase``) deal with different kinds of workspaces. There are currently two workspaces that can be transformed +into an ``MDWorkspace``, namely ``EventWorkspace`` and ``MatrixWorkspace``. ``ConvToMDSelector`` identifies which algorithm to +deploy based on the input workspace. + +If the input workspace has some special properties (e.g. a workspace obtained for an experiment with a rotating crystal, +which has special units of time of flight with a special time series attached which describe a crystal position), +the ``ConvToMDSelector`` should be modified to identify such a workspace and an additional class inheriting from +``ConvToMDBase`` to deal with such workspaces has to be written. + +There are two other important classes in the diagram. The first one is ``MDWSDescription``, briefly mentioned above. +The purpose of this class is to collect all input information from the algorithm interface and transfer this information +through the common interface in a way convenient for a plugin to use. The user who is writing his own plugin is expected to +add all the information necessary for the plugin to work to this class. + +Another is the ``MDEventWSWrapper``. This class interfaces ``MDEventWorkspace``. The ``MDEventWorkspace`` is templated by number +of dimensions and the purpose of ``MDEventWSWrapper`` is to provide a unified interface to this workspace regardless of the +number of workspace dimensions calculated during the run. It uses ``MDEventWorkspace`` methods for which the +``IMDWorkspace`` interface to the ``MDEventWorkspace`` is not efficient. You do not usually need to modify this class unless +you are modifying ``MDEventWorkspace`` code. diff --git a/dev-docs/source/WritingPerformanceTests.rst b/dev-docs/source/WritingPerformanceTests.rst new file mode 100644 index 00000000000..d22a8bc8595 --- /dev/null +++ b/dev-docs/source/WritingPerformanceTests.rst @@ -0,0 +1,154 @@ +.. _WritingPerformanceTests: + +========================= +Writing Performance Tests +========================= + +.. contents:: + :local: + +Overview +######## + +The point of Performance Tests is to track the performance of a piece of +code through time, so that it will be easy to pinpoint any change that +reduced the performance of a particular bit of code. Performance Tests +will be built and run by a build job, that will track the history of +timing vs revision. The Jenkins job that runs the performance tests +sends out an email when the performance of a test is lowered by more +than a threshold percentage (currently 25%), relative to the average of +a few previous tests. + +How to Write C++ Performance Tests +################################## + +An ideal performance test is neither too fast, nor too slow. The +precision of timing will be insufficient if the test runs in much less +than a second; tests that run for several minutes should also be +avoided. + +C++ performance tests are written in the same way as unit tests, and in +the same file as the unit tests for a particular class, except that you +will add *Performance* to the end of the name of the test suite. For +example, in MyAlgorithmTest.h: + +.. code-block:: c++ + + class MyAlgorithmTest : public CxxTest::TestSuite { +   // Put in your usual, quick unit tests here + }; +   + class MyAlgorithmTestPerformance : public CxxTest::TestSuite { + public: + MatrixWorkspace_sptr WS; +   int numpixels; +    +   void setUp() { +      // Put in any code needed to set up your test, +      // but that should NOT be counted in the execution time. +   } +    +   void tearDown() { +   // Clean-up code, also NOT counted in execution time. +   } +    +   void test_slow_performance() { +      // Put in a unit test that will be slow. +   } + }; + +Only the presence/absence of the word Performance is used to determine +if it is a Performance test. As with unit tests, your suite name has to +match the file name. + +You may include ASSERT's in the same way as a unit test to check that +results are meaningful, but that is unnecessary since these tests are +for performance, not function. Avoid adding so many assert's that it +would slow down your test. + +Running Performance Tests +######################### + +Performance tests targets are not added by default when running +cmake/make. To add them as ctest targets, enable them with the flag: + +.. code-block:: sh + + cmake -DCXXTEST_ADD_PERFORMANCE=TRUE + +After re-building, you can then run performance tests with the command: + +.. code-block:: sh + + ctest [-C Release|Debug] -R Performance + +And run regular unit tests, excluding the slow performance ones, with: + +.. code-block:: sh + + ctest [-C Release|Debug] -E Performance + +where the -C option is required for multi-configuration builds like +Visual Studio & XCode. + +The resulting .XML files will contain the detailed timing (of just the +test portion without setUp/tearDown time). + +Note that newly added performance tests will not be registered with +ctest until cmake has been re-run. + +Running tests without ctest +--------------------------- + +The tests are still built into every test executable, even if you have +not set the flag. For example, + +.. code-block:: sh + + AlgorithmsTest --help-tests + +will list all the available tests. If you run + +.. code-block:: sh + + AlgorithmsTest + +alone, it will SKIP the Performance Tests. You have to give the name of +the specific test suite you want to run, e.g, + +.. code-block:: sh + + AlgorithmsTest MyAlgorithmPerformanceTest + +Best Practice Advice +#################### + +- Performance tests are not System Tests. They should test the code at + the same granularity as the unit test suite. +- Performance tests are not Unit Tests. There is no need to perform + lots of assertions on the test results. +- Performance tests should perform enough work such that statistically + significant performance differences can be measured. +- The performance tests are executed often, so ideally they should + typically take 0.2 - 2 seconds to run. +- Always perform test set-up outside of the test method. That way your + timings will only relate to the target code you wish to measure. + +Jobs that monitor performance +############################# + +There is a job in Jenkins (our continuous integration system) that runs +the performance test suite and generates output that enables us to +easily monitor timings. The job runs a set of `performance tests on the +master branch of +Mantid <http://builds.mantidproject.org/job/master_performancetests2/>`__. +This job runs on a machine at the ESS, everytime that changes are merged +into the Mantid master branch, and stores the timing information in a +database, also generating HTML output via a `set of python +scripts <https://github.com/mantidproject/mantid/tree/master/Testing/PerformanceTests>`__. + +The timing output of these jobs are typically monitored manually on a +weekly basis to pick up any notable performance degradation. Although +automatic checking is available within the python scripts, the level of +instability in the timings meant that it always produced way too many +false positives to be useful. diff --git a/dev-docs/source/conf.py b/dev-docs/source/conf.py index ad87f97943d..cebc195f782 100644 --- a/dev-docs/source/conf.py +++ b/dev-docs/source/conf.py @@ -127,9 +127,10 @@ html_theme_options = { 'navbar_site_name': "Mantid", # Add links to the nav bar. Third param of tuple is true to create absolute url. 'navbar_links': [ - ("Home", "http://www.mantidproject.org", True), + ("Home", "index"), ("Download", "http://download.mantidproject.org", True), - ("Documentation", "http://www.mantidproject.org/Documentation", True), + ("Wiki", "http://www.mantidproject.org", True), + ("User Documentation", "http://docs.mantidproject.org", True), ("Contact Us", "http://www.mantidproject.org/Contact", True), ], # Do not show the "Show source" button. diff --git a/dev-docs/source/images/AttachToProcess.png b/dev-docs/source/images/AttachToProcess.png new file mode 100644 index 0000000000000000000000000000000000000000..dd87f7ae7bab7ef8c594cdd96b02985e68125269 GIT binary patch literal 32164 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 literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/BuildStatuses.png b/dev-docs/source/images/BuildStatuses.png new file mode 100644 index 0000000000000000000000000000000000000000..348fba6f755f9f18891078bbd6053e6d1d126081 GIT binary patch literal 30343 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 literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/CodeFreezePR.png b/dev-docs/source/images/CodeFreezePR.png new file mode 100644 index 0000000000000000000000000000000000000000..610450cfd34335b1c9cae80101d5af16c893405f GIT binary patch literal 97943 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%0DeLtOad0YG+(E{2v5n`thj%Qa%-_c_S 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 Oj^azT7e(^sAO8#TQaSbj literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/ConvertToMDClassDiagram.gif b/dev-docs/source/images/ConvertToMDClassDiagram.gif new file mode 100644 index 0000000000000000000000000000000000000000..bbce84fddae74cf8a16b6a460ab4660d08168578 GIT binary patch literal 19417 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 K|NA)_5CA(6DF_|_ literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/DevelopmentAndReleaseCycle.png b/dev-docs/source/images/DevelopmentAndReleaseCycle.png new file mode 100644 index 0000000000000000000000000000000000000000..e221736354aaf8c81e08fedfceaaeb6a2294be4a GIT binary patch literal 26344 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�@vQ;5 zDs`50s!8pdYNd4W>Z)!Tp(N>b2;p!Ol$H?qF#n%p+hkWBQEz_z9Y}a(S?3qDz(F%* zF})?{W}%dZgL6$Ps+<&37|@g6qSG{*zH^#kb874xL~EDw47Yhuj~9;y^cEe6-eT<l ztG`DL#6EHei`0|3!H@}PTt^y8@14gZV7^@nD}(84nF$#hq;dBXoCZB|#}jfJki}3X z!PTa$6K(uQjV9Nv%jmPgpR0M(n;2S^!=mLS^Cz^lL|cHMsQ(n0t>3W`@0KXzt$M$J zg(vP?0-O%xg34*Qo3id`qtdsw^7QDDN0Trm*VSTW<pm0cwt&dCETDi%Z|;P|+U$>n z)Yu1UfQT!AAUyif35WG*=7-{WOZ<v-B>$CVUTwaqL)-`v=A@ozn1-cz-At+F<!fPh z2uLC_V6m_vRZZ(TJ-8ufNDBe2(}PP2hZRXm(gqAcvxzu3$Jg$8y<TQ1>sV!pJn#c; zN@E)ce!eaSm7Bs#hEw{PkRC-qj_Jd0m$4SG)HaaF$Cn2V9;YAeYY_JA63@XEa{5Mb ztCecmTPD4Axumb$iz6vdj?pbov~dG5kFj{Az9~eg<hxg*NjZqocEM&eST&5Zkhb*S zz*CU%DLr4m1ry{Y@fWEj3_QtfUV$AE@<o>-uH1h67>B-0g28k3&-=|WPzj`OF{l^_ zKWwJD0($iZgoD?~=NBDQp+(~G0f>n+b}^jnLLiUWdzJX*SOp}ia3fw!DRR|oQ}Pkg z&%e9Q?=0Jz-U#S0<1OtvdR3f}Z%oifwECDKUN|G?*jQt#J`;4faOa)Hf&f%4*?rNV zOhbMLItn&+KMUY{B(b$(djdjf=Ry;{UKXkb@Xgv30K`aM);s;60@APa*<msIIwElv zN1#w*sJqhK30@nkN_em+x4a)}q1GY<;8bhG7ENK|>YpVL)+nh!LxeaEc!=XrbMCGt zwZD++GsycAsV80(E2dWC0k|LO4pwZFSNVFw&PP&U?(UEk`W<248iMaYevYl|<m~`t zibQoxjPxVv_rnlYYeTs)46w5`<d@9XUONwtaHgaI!bYS$;)d_~umB|NAD=XMPY@3O zlxr!Ie3S}$K#0T`4o1HN7%qyHHQimP%mZ`?{{*62jM!^~#}@%ojNM$W4uOUs9#)eK zgvtT>yl6D=%_i`)%bT5_4P(M!MpD7+*@2kIm&y+3U4e+^zAHYt0NMSx`V@fN4Ks0( zK<-{7PC*sY*XN>`B*?m&pw;Pt7kH;n#$m+!=GwS-hIc^L)ykp~SkGh}On~{W59QOi zgHRT)N|2U!dH`_cNGvw_u=+*!2TJVFbI%JUS(iklQl<5(eQ1COtpMzOFm){D<hJxM zJJfBzrcWDHA3vSa&IM4Q)%u52b+tIP(Zq0O=)=ma|3)21n_-F5ilfHH1bhlVlE9nd hoT7coeS3YI7JoLjMRt%<2>O43Yw~LF3|S-3{{ot+K~(?% literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/ExternalDataSchematic.png b/dev-docs/source/images/ExternalDataSchematic.png new file mode 100644 index 0000000000000000000000000000000000000000..26617234da52eb7f6735ff369eede41a14009f4f GIT binary patch literal 30206 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 AEC2ui literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/Mocking.png b/dev-docs/source/images/Mocking.png new file mode 100644 index 0000000000000000000000000000000000000000..ec518c080c0b1fc9fb54d108f3eb00d5e3bd2322 GIT binary patch literal 17303 zcmb_^1yo#JmTut=fk1*+f_re+5Ii^(4k5U^2M<=kH4rR#0foD}1~1&*-6in&r@N>B z?&&wLXV$y5_ByAk?yY<FJ@)Orzg<r=Pb+{IvXU~A05~`}fYkE~@H7t)2cV;%prRn7 zqoSf>prd186TZO4!onsac!f(y38bc?08+fAVdQy7L(fV7mV#A`jgwD6SXh{v<%5j4 zpfrz=u)rTb0*8))fsKVt`r-wt038LL!2kGoY6IY+!uh~mAiz-o;Bny)aN(Z106+i$ z4(YkIe>C{72OK;CA`&tRDjGV*^9j{20Pt`K2=IsqNJxl?&u4o-e-A*!MZ$Z_CWib{ z*${=o0iWGJ<|iuU`|@@Im9Y~lj?az(Xy~tA6A}?q)6mk<GjMWo^YHTVi+_-il#-T_ zRaH|5X=rL`8yTCJnweWzIyt+zy19FJ27V0+4hand$Hv7cBqn`NPRYv7$<50zfD~3# zR#n&3*3~z3bar+3^!D`+j8DKOr>19S=T_I&H#WDncXszq&(1F{udZ)y@BYvW4uJ3% zwf<AHf6@#0Suc1*L<B^XKlFlwcY78DTtuX|Y{+<G$|!~oFDcmlQSsl${48%rqvTLI zA^7Y#hW?6*bCvq^57qudvwu&qfd7?d|EbvD^_l}<BEUU&9s({v1aM_Zm*t24KbC^L zc*$(oC}KQF@cJt$BXBqwze0r1ZrG1|r?|Ny2KMLzGEPMZ=zK&HC4r%Dz1ovD*fM+A z*B&_F0Z{=x0pnTGq<&K3a-vB1%Kx84#W@oxE89aIS!U?{^d~d_+fk%KhOlPJn;?c| zgopQjEMrPJs|}CAxhO(AaOPQH0Np>ydwX^(mMcfy)DwPCP^WcJ6!g=guyKz$oZ+{j z&zi)O0TZYKYOinuIwNNVr_unDZ<O~x#!l*bO@iqV(qYWp8|yJjn!oy4CML#fs*%=t z53I1c;60I@6GvKb(<ix9C!PSX45)6Vm;}BO-2YDE0aYq0qkp-W>pR_6_G?rHzPnL` zjcAIENf{O&Yug7%Qsw&3`|9^J=Q=e0iBt(cvWbf*e)Tq6bX$`e|9sdpG)Dq_{!Y^? zuGFBAdaehYoq$SSfyIswMZ@VzsY1`Bp*nJ9_X@`ag>E&5ihuwlP*rr!_e`^osFaks z%o<hRV?ZMi-3w(2e88UsPWvVXg}mCIjb=S%$9CEoQA5O$jm68<kLzM=&>P7dBoWjR zJW_+xY*Ad$$=5sON0s$si}pH5oU5Y{4>|+@!Hhd?P%^uXI(QUsVAHh%%Ydyk6Aa)F z(oqimZrAn<RZt<X>R=cs=U+ZPcvG-|#@n@bK%HHlp*+pGe(x_$_zK|O^5cx$k2zT- zLj|J{ZQZKL;YQw^1-4XhR~hVRdpz@pa;=qDzQIzL`<&CR?o#>cqK4+AX@iZYG_&sG z9`yn@&PQYPWSLy|q6FEm)XE(>Fq>)LhTcpZ-SKJMRVc&u`<Cwud*e&Rg?OBfGveur zG}WBTL>4K*rQGpQD%GxejiD7;DP2{SF+Ov?)!$nXVdI7z=Xe!(EM~1=_{tK1e-<eL z>!2T_Agg6R&vfto_nUG${E=(r>HV_}#DJ>Wwrjq-$pYHN+H@>4>TlTgzWj}La7xHH z_?TakBoq*^f76F~#qt%{8k*|bY;z&Ho*|?vAvOM3h)Sw95zZNSNaq0A;)WXsZGgxI z8p^4hM2Yd1ii7I+Rkh0AOpB28=>}#D)NoES`YrAd!SWY?vMyqFyv~3XqsVG*DJbGM z3C=qGydrtGY8}G6EkBA@=gS>dE8@2eK0=mqjmxZu`1gc7W!5h*GEKWfyFPl$YZt7B zOAu<u`v2o3S9>|Md3yUiXz8nhMS={MZ>{Q#)oNd7Vz<h6HP@L@U1u7XFR%j>>WX#? zDhfs@$IA~?WHbTEL>u>Bu!i*d%-uK8$urLEM=kO5+9!Z^Zoh<Hl0y8R?C3YUKG-9S zwpxn1YXY7?QRp70r=I#$7*g23>F)L36(x%MlMZmy$K|sKvU|4H+sg=Dou3=sMEyX& zw&Lbeo{kc?VibyIkAlZ{N0L=@>2aUs^!Hp(%N_yqKh6lW9;tR-88cUDXh`J``1_{m zmfx6V&aIZbvdTN&5{7#~a(<P99cP@WvpY4mUKjrIHbunq{!I&fhK%Bg)T`x}E@;cI zgvk@dX3Fh$=z(jmL$io{F?oTYCjk0|C>R;uPpF{nBEMf`>-AJw(W7o@bGpatZW&6E z-8s@ze;8!<)?a5%BkF=oJpiM$Qr34f^$Eb@OCH?7_ZDnS&m=>UvFd`T!BgapAT}w^ zT7A!yf3tGyap#<CSw6d9nTMPg8yJ=1_CPdV6rwcH?!WQEopbMOmhu$X+22*f)-wL> zQ(#*5%oD)*F=2<FrP`uoch|#=M(t$4=Zt(MO1nT!Wo+k{10kOZ81i}uWzwfPf`KlF z7J;UkHz=<XY0r|#RviTqWHOwY{Z<}eDb!J#zplQ~0`OkF0Ws<h(yzpc23vS;ryy(A zopOZ}gDuV$f*KOUr27Q7^SNFw=;Rzak+SA?o{Se_4c%Op_#BHj33Go_aqpc~0f=w^ zL?DC`zI9?PURx-2cAozFCi`I13+mff>6}#S$^-lyO+E4UEV&-3m3V^-h;GGZp|Ur3 zR9c>`1QOaDKI$CxA=sI7sp%81fd`)-%5I(aKGHl6RniFYPey7wBk;0#kBDh$$S!$f zKa@Dh&kZnY2{<2~a|u$|9zSr9b)Csj78iquU?tv`z!&b`TuQc|4DAXe*((tIX@tCS zn%zJRCe0CFL9T-}bgGt7+Cwdse772eP@$9!<(PgZ-R#f=OMbn>jdvkitx+FqqEwTq z8!+yB6eoo9YQ+$ZiO=sBUDqW~k<&~K#cdoNC^MR4?b&wc8jCdgjA^MAwF`KgUyBo8 zY?G+PR-_k{OW>=guKv^h0sjKEJ@3{^G0TsnT%<vSK?$%!Z=Q+FX}KuzCJ4nc77QqI zK|O0R(C%(1w*dNgI~yYta=o4%_v5=5mnNbzR;e!PaKnC>{!mU4)xbbxlhFUhB@;8$ z_6nG6*?SeRPMDk6MIMM;^gF14@Ye23SjjSHT!x`Wh+)Ii_qr0aR-p@5S<9D+?QLYz zZaF!zsqSJsldm_6NXGA6$R;4c!sahJoGfh^vy=##T|g$Jjhu80cn_w_g#W7`9;@4C zGc6y)3~9Qmsr+hJ!;Dn`lyK<Xgqc~ro2hbF$aYp(j>q$R0vL2;sfG(vdh&WEY+71w zMZi9DnI%~}K<<a_8Dn4%s`=gT5=^7K_;y}=$;j|T3Ar43@ry-J!gKV4$E!Y%-igcy ztLzD95+N?ZMiRA%#y$_Hn<+PlNXQ2_FF_jMO;oyG;<B&m_nL7*`L!3q6OIig$$Ne) z8EsCt(^}bIghs2{DrC@_QUPwmjvNQgjFNLR`Gc^O8B$Eu2*P}~BDSLMpxDijM)E;1 zN-(bym2$B;KSMa&jVi<(8j01FmG~FjLI2!4sAd6--^tOkwJ4))ObnwXJmSrl;7@<q z7qL#**|U1u&;nCZeUO`F>wLi=3U7GE$<@O=1pEEqwK6EsE!j3okr{HoZ1^tNQ)Kjr zqsK{|#r8c!)F-d9%I3q8yP0CWX@4xi!eT!ua8o_Mj-5?;VXA*o_dFj3jkhIWVWBaV zeq{UyLD7I1V+K^Ss%o)+&+4;)i}DC(mr_8xq_ApALrp=ZvC%GwO#+_x34pu5JnMOw zo<7C$xzPkvZ`u)lW#HLpgPwDMLoHJ@*IeCnQr958^nxdY)xK_<D=60r<oVs}8~v9q z4Tjs5s4t!%w@Qmj4++_nc%z!*Gk%X14hvN=qW0KVO5SLMCBW4x4SxBdtz>UQK@MRu z6XVr@)9}aYIqgN;uYS3qDxxC>mhC6K;W^XQMf+$6@&&a-N(zc7h&(?bDY~aNX@nlI zyJk&Ep2&z>G8?s4j4Cte$MZtdic-558OddAv5JN|q!@i$muck8+Iy2532XOEKjO0j z8>1cWGz{{~O^s%zQC0`<p>|!@wTzVCP~(g(qLTR5PfNurqAZQCi+9iZ`6w$1(Bo4r z)Z8lWOGj%Z@IfJje}X`NhC}~Q|BjrZ?At(JF+$K_m!cNot>*`Xs>@q_jJcxuX{$5w z3%?|BlTM~6M-Kouo*2z)g7`vgM?y;QbYArQ<6cZpZu0jNB!OAoA3T|H6ct})08Vk^ z_4hxZ0z+&i*;cJ0ZbL*vPL8^k8Ms^;0mBy7RdTMKefh}ZzZK7*Avb2LUDb>m!v>F@ z9vR$L*dB5#+T?Ma%GtRd)hzw`OL-B+#b4=<2c7_z5H16vojZzyhI%|*xW__Zaw|}F z{oMiAF}5B}T)qKGU+H8b;0dr#aVgw}eVPB$okOO=B=LddKFiVV2~dQxyL_5Gr=TsN zSsm1=qCZ}Il-_Uq+Y93ffMGev$1gvUlxlnas(~4&hhMniQN3!DmQwg*wiPfRYEGS= zMnywuWc%_ykGl7)gr{2=@#{|*CldFx(!&;2A6BGeOK{v(+0-?|J2<^Fx;o*=YXgo^ z^Acbuxlm1#lo521>h-H_3)3e+V)it7OSMT0t-FhX?R~7!2O6k)P^nXjhYt;h{f6z5 zl!2D#R;%IaJ$GHp_jf?5PY=W1fMT7}P*1+`?YfE0m%2Umnp6X?9`-rJPlC2;-MN+t z_!5?}2p~JzHByF$stge=nwEpPfl3N_G^gO*$=i45^tfy9Lh)=}`E4T_{U_X?0JBlM zdRUQBc{e^lT7_El?U1zF=trTD@tTs&NGi>B^ulcP%unb8N@m~HC1bUlwFpk*3Yt@2 zGYPz#uIDPIk?e;SK$AW(30npaEWpL`6Sr!oQdywqQ$l6_5p(~?AWQIH|K{MZiY4Zd z7IW+8%?G{vSxlGlvA&iv?5({oLvm4fw)V@7A|hAw^#`E4$%#va+3$~0!2OJU9qwq4 z*x)zQv@1lIDH2^MH#DlZQIFMbb6<e0C|T!PV{Uno#RH_@8@`R4!y2tnKlJOe72zxE zkp5wQAaY1jy+;pTN5qYmaA-XVo8P?~gI(N`FH#}OS%qht-D=n=4FY^bw{p7$bf?lR zCgde{u6Y%2J{CJ4YTF2J4558pksUm%z3jG?ax$|ay&k2)g|?lW)QMfUJyLixY-ML^ z?uAv{4G{h2c}ID=FU=W>R66?smHEp0%<tCqPA!-7@|JkmnbfE+#oJ|}Bcn%Km@opw zae+ALe$4bBXXHSZ`zue-!*(xMHf}e)x-1>-<gTnI2HE@kk*k2S&gQVo^+XE(-AUF8 zv5b7HXHNocFu0k3#rCKNIVfK|dse~(M?gXUJ*!@`RZ+G5n18f%F~;|gj<$!OgOVEm zeQl~(8PaN+J(&TWN=LA<BNG^v^Ul=ppLXTH7;1m9_TZHz)LUWJ7xPXIUiQ%+M8byY zxf8R&j;?Yl!w$MqVPBl6cv@#3f!_`_x@$Q6>y_@{7M=hM(Bd!h<?d$H<0~mzL_{E` zvmoKRi~I+cn)1it`UbHrgD_dygC>6%!251m05S}FGx9kRZ51LYNkL-Wcy~*1*h04F zS^rv?a&pT8m>7nA;N|I~{*$Mp8EJJMW1*AQ?3~9ZVP1KuO6^l(FJ~o_s;BH=#TdDT zu>V>HO6}Z**ENh;H7V#!0j2N>5Twz1iu44C%BdV<`fOzqZQIOuU-y`>=U#k|^;%(k zJKah^4J;SD$XKu$A)a+?e8CfJ^s0VOj1QV|dtEDbr=M(-V{xjb{YE-V7a(w-(jX~; zuOZnRN6#m0ddb1UIn%N<J<lU;giHUpw@nLF)f(>@<D<-V{^C}AUpE~qyqncF@0I+` zv%j57&@-@)2=Rwje30)^s)N>a`PxTF?>L0%5I?mVQ02zBvy8dwII*u`VD8uzx+)+= zTYs#_?#|I^@j8+7hhxjS2vp1r0!R3HDZzdja;()8Pf;ahqU%ai*_8JyO=`6#(1Yln zK`6fNR-0zU2f03@%KgXcWt&`po%576ybOa+$c<vH>``kKV9&C8vx{d;#>&3Mm_48* zFHbG;bnJ)nFNSxE)7L9^B4Y__FzBV1^fA*y6+3oFVfxDbR76DWoAs2{FNFG?UDtOk z=Ty9(aek`sJw$k#6kAeaEr1K1oFZm}xdS>U?IX)QOC=S+xc2lgWo^=bHNueO_U~<k zXOC=6a3x+0*6$#h4npP)v@r&?x@yiOyLFx4Af%M8&CIQfO}-`jh$#irc$>TDBh}d( z$IBWLhEgx+%ip6;YGPI$dB>}+5}WF_CA*X@Onypmp3z_|DnhCEyLljsw3g~r-yw7F z$_IGzxI2>UAQ&``FSuflCKRH*cyg2twc=nppKZ4?#z72hehj>WDW|I8d#2T=ljrQi zN~`RqOMfov$ZcWeY{M6;3lLrfEH$YQ><Y4Gf$0E$NKQ91K0w8Y62D3b+2*jIy=~<} zI3c_}GYPy$B}PFYw9j%jB8WR;B#L3;65R^5WJK28_*|c<y*TWpcDnagN2q|P1yzXN zGN^jy%L{j!Ql+>5%Ed#Mm7>5QN+e8iij^P2xz$*2^Gks;%(HJP<G1G;XDN=Q4__m3 zPb*W5R=Q!3!s6h80FF;yB3<h$@9D!K?_$2iGM)HXnWqnJMrNs;x|$Lg0QdwqS3iDL za%?mm|M(M$&=*fmV^;XvuaU}8=OPSoD?1}}Nimd7#MHZ#xR2vZ&Q?ZthPGuNG;1a= zi(sHBy(o5dGse87pAt$i7buUk{PcCX*uhZ$1OGJl69Dg`-;~v&Mx*xZN^`w;Usg5T z*?K(vRkgai#Qe$q@G!W&Z1Qq`OVStTcPyR<hb~r|7l6?rSy_$)2?0Wzs}gHI;Jk@q z_UIeE$4GPB%})^Z@WnE5@Brv`R-D{I?e0jQNOwg2y%7nClDA*@k|hUpFh!_+t`QDg zaAA+7qynjrMIZH266BprMib?@XkHyL^#ah>U2sA@nVSynjO>JS>4e@IB%N@|Iz%3* z*<V@-yyq$R_~|w>s5Q;~OW3B4v%xKl>rnQJzyP!Am7_4Z1v}B}`a^9EG2|-?0wV>v z`ZjG!E^222bA|YLlh(x6m>*^@V*$H54w`HVVkID7qWMnVs?lN{l?K}5m9IcCSd?e0 zMgGmYR_F2_+b%14Oq*XH%JhSi>Y=J@WWHP*?5js%HBj&IaHw}8k{?&o=S{Obe3u^Y zGG~Y}eI$lwMy|7`eh_);qmhBW-cUHl2-}-SGWv$=;DaVHW9Fk;`uEy=FIIjQCUJbL z*}~T&oQkTN5>lXSuX(MMd|A{U+(;OnzRt(2w+P++;-v4=s&>MXSCe#L>pVMxLW;ZB z5-tGV|C}Hy^D|loGn1WnN5Vv`$nlc@oL7GGYP!j!Qb(tJGCM@CBTbEo7TaNu;kPrn z=HD>nxad}#=M%tP?X`lsusV|{tvN3(!N86WM~G%iVvmkSMMHSTVqe?QHsKwtzFUC9 zTscj8Kv_f1sVb{bM>klPJOB!h+E>W-3Oq3VAfD%LrQr2jWkdYMs_16w9o>=DP{||B zO|P!f<Es-G#PaZKT`VOf&lx`4Zqi9nqQ<7NN{;JwDRD#aS%+4YN-X~QV2(SVwKL@j z6n2W!9cQ@FziOVFLG}CRq*!m>;!J^o#_3r>lJZF(6UvgDL&k&i6qkjU9C;!N=}Dyi zF}rWdY$B&3X75X?>jLVGH=%ch-rn+_SP4IQ7o-#xi+&yW(CprM@6=3lCLiiR++myE z13V%Lo+Sz1Mg=nx9{CDMug=1YLmhE$FN(fWBAKVogsba*yxn78qmyXMSC;q}4z%6~ zV?sm4oJ`Cg^XhPw)74JXNIwnd8oX+mim{xu0~*QGcIayJ^$yhseV(DX&&NdNixL+2 z0a54==R}E~iE)1t5nJFgeya^|nIOHU;!Z`zh5_>;6U+T5&<(j58IzsyyH0S}$z-*W zJr%G1n*Zy9KY5U4A%y}`xr_YXn_;03g|m6G-<T9hyr&U~6+dT<$6BvG;)~<m_-t(h zn`2i(XlF2eIrNs;o%9`6_=ZE)Y~(s?QOwPlvAx!7*K&Xz&EyqX(-cxZX0OWGlcWkS zjP$M~hXU+5{P?)GlY}WxMZk8ZWuwgcJxkp5RA*Sl!Z{ZYjAL|a>cf)=w6q9N-L=h1 zzLU#r$uoNu?{^a$9=4^cUN{(9G({yIcfZD^38H1n#rBt}rho3fno_c;In$c$wvLr7 z!NtckHX|x=T1$yr6}(eOF8Lwx1c)XJ`Ryh31jqyrq^enRMlPspO?7nS%s1M2SlIr+ zTmCq8#W6y-FxK-c8|JTXu)2tM-K#w0Td*G&BsDiit3Dzkdugh)rxuCYPOzPUJve*w zLvKO>p7J%q&dj4E7{b>r6o|wpjstSOh^=f*IIy05;5k_=8J{Y(UoVo~*gk<a$|FdZ z19uv1stlyN<-H&?ySoi%M}%;@Tf9WYhU*awTPr#iVGa=aT|3;iyEs3FLj~+P(qZ?8 z{p6bI;pGhrt2tRKPobXFVWXEU2so=kMS&F)O@=F*CN&dKE{rdU19Z%nw1GDoIXeBE z(M5_c!ba4v8i5h=A0Q9`Xh$%+^QYaa+}C5NK2hsdLheG9oz&GAq8SyfTBry4({uG* z6PLb(`kX0Y-XaPSeVTwyZlT5uCr}HOxN%BNigi3o5mh#gF!sWU;<_FQo6gV1SOCg? zq!m@_e0X}V@irzWrFOXW_Ob?vot=IVv%$x*Q9%p{88;l<S@{-165ks~E2*{^PJQf& zK><GJ<wQQgl<ajG-?iXYGN&q^tm+2}wpC_U--(9FoaU0Wa0XeGb|;y|dY|AS{Hm!> z*)+9+69W2Uht<t2I*bW~hVec-i=m|gCutisZm&JD&JnF#nTd=#VmdMJ+)AYy8`V_= zuoJd~*=iyl)U9vnk_NuL)vq6(+kzfdb9xausb>pvE=A~haJqu#n&X);mgiYSb_<>W z#C2b!^0y--ryrj^nwzStN6B@;UirN$n!Z6Y&!3#j9V7v-&k8TSC`C;C9zDGKc3W2| zpJO6BZ>^pHzCm=SSYf-qHqX^=$L-an@4mqs-lQtP5N!)muF-2uk&d*ztM^y#INM1J zE+Qw<TF&<_wZEUeziwBDr4NrfzRQ=-P1x{V)wOs6oG%?e0mz<js(1ss5;;G26gp{L zmDsximbX0tMtZNwoGcS75o(T*dr1{q*ENZ+Lk_Adw>z2a4c`26>gi<OZA7kYUDcWO ze*yrf8IP+iiM{|r(Lz+?KbbKD5%!heSx{Sim<qR#&mU4~RD7U5B<a>jvDq2_@*#k} zcaW_Az5;tzWU66s(REsC+?I=RSFq8_d7-!d0s$7+R!ZAcE2s5p>RJPQw1^`;Q*My| z1Slz5koPLJxbh+O3bwLf8U3K?=xEQehwP*(Td9~RB`NSOs^YF&Bz;$e%eQalWGc+< zRNTOqz	om$h6+K=7e7@XmkXT6l7Qw3`&SSeYX0O-EKZfT88bGXgOpNGN{K%j_4) zMdnwOF!kj`RW@)>gxCciF0RDgN%oW=PTSJeVYryrk#+xwq=0KfSr~fa)(t@%ZypZv zyzM7tzZM>D{w?8^W-menrO0S|`D+JbUY?|<_r`HX<R>TGqBw&hp8U&@ND0hhepbOi z6%FQ-IgO0ftq7`!`lg6_VgFEIW=Y<^j59LISpyvoJg2B1&|r|hT|N8|YisW!<kJdC zZ*v6UsV;%Qz^MiSE3OZ!;SOrWl*8?NR>tVaQdiCwdCi6Fsn`yxW1^9+kJDCoC=?l4 zeLdHPf{0vBsz9Dqt+{u^<-m(yPXJkD=Xhla_&<j^c@08|F%QPvzkM87oQ*b~<743G zf%!5loYaP{oRTNTLD1~|n8vn`YD-6_<{2uY+g^AE@K1lgsgz1;PYJMUV4jYy<U@Wr zA|&1Ga5z`L?diC!<051&5Xqj>IU@5e=rQU-=zU_LMUuQnp7x@2Be}WytT!4_kxPSM zUW%(3*{K-XNnqI{QFO*|0~W%g=qupmG4L^fp%#1r;VQ+}o9Tc{o?tuTB?*zO&DQQW z%ATE<k7B1&*CEdYS%{b~$ILRsxbt@0K}7mr7xkM~O`6>V7HOJaQ;b_IBu1wivf>cz zt9RU#cFdJtZ9Jojknb2Ju~N}!!c8aM-SXx&aR)Yupa}lh@D$yFfqR48?(!R>Po#>) z`U{qL>C&ceogVf}%O?&l<{gmIs$5S?PqNnPq?6W6M(0Mb%ANq`ZyrS_??o`(D@>Om zH|f$z4LXs&9FGL77GKy*>%Oa{{JwN=rJ8@hD<9v}zDmw{QF|TJ*6jx9jTH*<+~fj= z?%QuobSA1A=+<Jq6|eGIZ(Rq^CcU4SqLP~#&Zjb>(COU5y%>=#*3_Ztql`p+Jdni) zMRFwRkj8HZ=ND&f{I+iWH8ARo##CaUJx%kPIOl7EisRdB;U~aA6-}K1hr4Bfh32Wc z<FA`TbyT_{O5)3H{V(HB0KX(-ooVWOyRX%ZUpB*$lJ@es8ngOpQpm#L$}1L8b~UeR zpj4j-5Lw$*``%3Efz<$Te!TFJ243G4ikuVP3H)IG!ZzrCQCMk-cwuV^Zl_Esf0cd+ z`V2BlH0!11>fgh~GFW3y_$tL{sm4c!yqw&s&uGxq!dN}_V%8$p*5wrmoIZ&1x6Y_~ z2HcIlHwzz^yfm;@HxhyLJM7HqNZx5!e_R&#HofN+4u-5IIE6a}ymt)SSD8eXAx*D3 zuFP+ilhZ?q6u)x5&b{aNf>kLY8ki}13J<4WGULN#_!w4Kdu-ao^k4{(chq?`l6iH1 zBzENoC3-}@yR~?8py~PBYIHMH_J=0C5SGN1%22F?8LyN1QiuflQAjglePc^{2z9>u zJK2i)%{h-@kx0Amk9tT>1}}0AaNJ8fY7Yu)2H)U)`h-=2_8YBKQ(E17$k2VTBeCV( zsPV-1r&#)BI~I}2x*eai2(`~y#W4g{YK6yq+_pXVESqnFw<()t^!a|?9P8Y8Q@H!~ zfH-8VUiTv{__AT_;79=r2zEV1z*WqitaGLiJ3f)KU&7PClb1uvG362jvd0<|Od{*o z%GEW`%jE=vFNf%BtHBl?tI^J%;;T2`W!$_d8s7*O(yu%+``^MI>2A7nHQ!d9+&scs z>=H=n&!V3I+`=98=1oE+&q$&-s!8nAU1A=g3_(?IsPAsEpDS6sb0&_~iBJ3;?N{d^ z?vJ<8ZH?`FglAG)R+eRgz_lWg*XA*MuezABH|s(KyB;$XWtaamfbq9L20WNP>WzZH zD184l&a<0#0joOK!LtyRIg%f}y}1tMt+pR$F*T9u&f>oL3sK5u2iI!};IW2;O#vmv zW|?TFY3_4azrWDehII3$Fm5><m^%7)F1)Q=(4Mz2h2ja&)$4YTT+}Fd++(F7SIgE% z8d>O@hQRe~>mvR+mQ3q;o)OCMu1P1$VjPdclq94?QzL7`b2|NtB&ck<%H|V`3eTLP zbpX!UkfFhfkYLHOmfpePzR~F9`vN6aKpXy^u?kZ;Rj6YL9HJZk-NL#4T@b#?OE4lc z!OP*I<p+lN>vpl*_DqaYUi}2gwOdub{^DCZDjx(j3L+C*aV56%rDO#pjTeG>Rc|KR z?mMasD-jCUZ%0vtt;?`iQ<d!uTl6)+%dw+&s~qWhX#`o2`#O9$va~FwPYFHz>Vekz znFOo=Ozg>TYX*38?v7o9^f&?m6ko|TpPf+jGJnK-Q}<-vqaUW`hYCuSO0CUu+MssL z6THt)EY>QIi}hxp{CRV&f6Ik2Qt{s1gase>anI#pZ@Tl4{AgRL{*)y%hpSy!!F@6A zoLh(=PCrn0EU=(HXZGMTn^K32N;YaOekr5gGGyS!sV&9l>%J4CcgcZsOb>key_DUy zo;tq92P48F%08%eu7wlK?emxffuz`<oqwA8%%{|?L0^O%3Ki5Eu*!NA*`<B<o&f2S zl}r$P8>(;ue7s)@0Qe@;)$N<c^;J9a%ag0bWe#kf@XNazRv{#S)fd*2s+5`tFQ|Kr z{Mz1;md!Rv98te_{!iNcO!7-Rm7BM#gOHC6-a}idy;(i0Ng`1qP){n>UOPMqyswd5 z=-_NPQ9^)P72F2a3I9nM##(=uelTUmZ*=I~1M0Xv@e@F^xz6x+TcL=Oyk{;x+_1SY z!pU;*f?U2ud06j5P5iNMTY5&2Gs`y$cK%=xp$X+1@H1psOSww+J^9fsQ)<3*W}akM zV=lJp^nfz)JMKoK#DX81UYpkr(fmkVo90H3l3yVFRrQjYds<^+tE?r=q&7{qAqM6f z;r^K6R`5W6sx@IZxNzh1`&#PVweK8xxIpB33gBvhfy67c1iD^V8)FPs$Bb+yBoD60 zKjliR1s^sEQ1r3bezJ(UneVlO0&K?q<P#6cHPQd5F4Mm;mCcF}r#W4MeYnUm?#G^= zHXA0yq0ArlI<g)TF3<E`KY?M69irE4P6xq)IPw*ZX*W<z{?Kt~qs+C&aHh*1RiZ@f zrbaV8vT{2Z+*f#!c_>PBbp`NB8H;4~Gb*890k9&|oBt;VM&+e{oSeFCKJICq^OoN$ ztIWW0h+ILY(K&Ei%``2?8vRq1hevy+Nyg!a;t_lu+E770p+d|N!t=MlL+s_yHE0^w zZ>;xM<8AH1tC5z*@o^s;)XC@}z0OAxC-+?#5c7T`fhR!jtY3IOM8EgWhhRDYb=c|` zmkr*Qz-jRgi(!*$gLM45F9fK+Ry_aZ<C)Q!iw(Q^mI7gK?<2n_2p7_S1QU{-5h-r9 z37Qm|RvQuX3KEMMQceG@mcD&af}wO1IgvNSFrdf*@#uLU`GB*nLre|<hB6C}y&j|> zmBZy@@b(F=Qa7YEcAOkM#izfQjj7-=X|%w>?+TVt@U}c`4jrMSsiLUHfWcir6)3(E z`|zJxKDf4fo?h&$76$FGDP&48-q$%d^Lx#<PId&%T=N#|A@maK*L@=qnK_DjC`%~M z__<?=19S(I(Mlu^>1iMB$}+ex<QL&;YAbfSSL0yM54j1}Ojls7T%zY61qdgMFvM<e zM&_4>bgVu?581GKj{2VfZ3mvxpS+@mi}d!mU2%zQk3RbgB-t~5H3*(-qBIt!h*2$r zOL_vBLYRFBdd6>4(o4B|Jl?*v+jCM(&z__5)<7ZC^D3oljNJ#mWS$%<39+4ydxj{g zRT+kpg*727P;sr+$C*>P#zcX{#VFcQQfKnc(~@49ldXiTJSH1F?&G&au6J=mmP(L% zfuXPERl5?M7$gQBLd&<Pg$4fV?+XY4*hu_fMyJ6)!_oh!Z|0s(#=4&hQq_$2JMIt; ze6>-nDn~g%I4_CZT4R*6ur;-h=?Yqm5(V^gtqPM(v#1>FpN{%(w=`!QXd4T-y-vOb z7~L1X^5ZWJYoTnKbRqnLwtCR-;VRl_BI4kANL$uRJHM}2`n8G8VpRy8j2(t-crMSv z7jvI+a#eyL-Z<Jqs4efk#@Jfpp7;c~PQsN4qxyJWD}(}}I==yx1~+-HmA<kZxbqGE z{7rh8++)*3$cvj*u?%HjlsxKB%O5;QDojwoXf1+Vp8Gd@#DFx)5Q(dy4#AcW$8?j! zsv;hDDOR!D9dcV9;q+IsLGquibGxF1Ex4yN*(dv5v>oJB)Wy%{+t?9bmxmzkWBbK{ zrElnjoXM#{Cr^xF7+Mv!BhShcfWN-rrgrtX3+r|NR6aLH=0LIr-Un~>U@`LLTqjWU z;2MzB-DiO032-Q&$B3Skt|~c#mp1#!o0ljP$1SV8#6^=rizZP5Ox17d10Ybqd1YRU z2_c8r4nHu&iixDj#e)vUISb|W*=#(?xCl~{21t-jBN<?B=-Y_kY<5rMSkxYQcCAFV z^vfg{?>41{bQoa2Xr(c1e+J~3Sm$dbs!``TUR91j>Ll7RJOXa8K}KGl%KxCI%Pj2w zLJE1RAF}gbxtDM1ze|2KLm>!rai}{);c`-r4!9BACir2UZu~XfL9`#roSe!>bgaXD zf~5GP)zT&v&Pao@pvW23EIvH}@v3koW`e*nr3>kqi~+jCVS26Kll9?VcI|_V$dZzk zxDqAdB~4aEH~}p_{txY}?(}4QT1HH1Lc@SeqPuCz;u{0?lVQm3+SRf{w0?JdTlzh= z2e~`&#a9V*Rsq!^GX_iP-OhCer8q0KYeiH06vb{V_D>YB!;Q*#`vW+Wk#k^zGuusT z=Qz!2(cJo24&YHT57xw&y*JC#@P)npQK-)Dmy>4f7mkztmQAoT`8WFBedYVjyzpJe z!96Pri7SwKqtp5b)_h=^gt5?9OC6B}CynJ7)nuPljaH$;;*<_s6-S0Q&OjBbtlAsz z)dEzS&LP7k8N$cpZd+|lZB6k_t$7J}PsvPlKFdML!yPUi1SxHMN8hFSBPpWQV*tNy z31kf|Vsh4IjeXwF4kXg$D|^&KZw`Hn+O9>)bxOd7xAo)VpcyF(%<${)pzaT*3PW?( zPqhN?Vlk4CllxHwT9`G|RN9th6|5z^Cg7*Ds}Q?E-`;jNjbOKmVOJ~fRkGLuu^%T3 zq+;P{7g^yYa8f=MPRiH&Ch#Lf<^@27lZldW1te=bofu+WHWnXG$HQY|-Ab8l<Jx5@ zGCSl!ym*LBL5mo;dwd8Ip08R>sVj;=kT|v79}>P`o@r<Aa-2P^R}_hmD`IKQbT=X9 ziM%r>!P6z6P89AX`;C@+NZjb<fqzmK7ygz}W@iFa`FgFSmO9@*uhzfSyMVV=*JaMb zZq(?slyk!6+b%O_E6$CSV!|cwTl;GXfccVmGLhFiLcQ%82k-@&hWu$>gdKH9UlD$? zi6o%sX2WcBT4EK-BRj?%&aa*_AIuliKiGe1)DKma*CS1!A4pxGDjpkgms`co$crg( z4-1C)^m<Xoj!}ATA7?oAR(o<f6r1DXGtj}QVFKveHsA%uCpi9LMT`Wgg~!67ltUOI z9$Gv2dMyDPml??JvU_WCgK0!~N*Dt3^-+|N71Ecw(4h3(qT9qrvWeiN{65#JdWPZF zL%xmQNY3kek?Y+k62ZtnEFaFY?V-!U9Sw~Fj>=Bg8fV2h&3Pl@qxrOfQ}zn-dItGv z;c^DpQ3vK#`&&A&2<}SuXc97!ciI6Wh&Mh&<C-fU61kCleH2CBTV+mFB}`U@9e~_w z*-H>Z71aJfcI}qSIGn$M(urs5S}`UO>^TK+Kjxd|<+&pctiC2yw{n@irmaxaxg(<~ zvMIojnd(jy$Wt*gBSp~E=J|HXD0eYleb4vts9i-(@y97bfKa!UJNDVN=E;Q6mBD}$ zsbeiQ%=0(DdeO}X+t>u8?0$_mc!AAAW)}IMfh^>zov?t!M(FYW-K*Rt%v`59_4NRm zoc>*P&TsR2+V8l>l_@CWzl499ma{Q0WY+*sa!!tI53pcC7}*7MgvAc{Q^wTMS?K_D zZG`w${r}Jre<O#>YSSUSRMOY=txhR2Ug0BvdfNh-hd%d{w6jRzWA47OAEP4+lGFX& ze5;FW*sc9IJ|eJ#Tkz|JNhG82-6bBo*jk|?1Wy=LydP#<r|Zgz30^xNiVkoeGMLDf zUnnc~uvy|-RO)s<O+j{ZSa@rYD@_I3v5KjM<p4n8{K>YcnQ@s}5S@j@`SjqDzmlN; zE0Y@0j-r=DfD{QaP8Srk_HD>VPgaXU`e4<*>;-GrdHdx$!PK5|Q-jMd<uZ*}8g<%C zs!tjOnLF3S*ojka???tFhzNTeaR4}*T7y5*bc{+eDl|Rnzi8`Rax<@4m?G5^^%uJ8 zBb3X{&mXEdH$|>gT075C_76LySJ&oKRK5|qEfMKXiOgSnhv(bzE+2=5un#YFg{_UM zwroUUE3XKwVYyX@r0wL8&!TQ)5X;JPc<}kuq>B7yU22~RfR|6nX&A=^fp3K1K>vM% zp`Sn!CeE8Fkq|-J{2N!?jr<>uo!e=>zq~^-ub>^PQZxw+wrI7mrcMIlGjPxxxO(Ye z!?r4ovNKwLv5R<WarR?2b%LUp|2$MKXF<XVUD5V_HQEH5Ehfb`O!csV`FEY(5Y>kQ zG8qJl3PI#Uk>E9I#iJZ!6quRF6hv6-EH^hiS6;od;c!VN=Qop^J@<~<y;?OXMhyY^ zB(<e|(4WcsMtdqe$F8K@s48Bh4mt!;1-)tO%bZvO0;#ouRa%?{CA3X5(@B_a?5V3x z6Q^8@^AR;WLY2CpwBn>w`JV7m1}5c1Jmk%~5!r)7W01e32Pw!I=3(=)h;U!FRLEvd zadWim)E7*7GL>E&wxy>SgHE1&DLmP4k&Znjs7_(&^R_9GH)BgP>^4+5Fbij@Ap_4{ zbAPTS$=yVmEGIdUW@Na21ZA3Qd>tW@fsBVwUx(~PcQ4j^hNzxnw@D9*=7fZnG&8c? zrq8@adWG55rb}N<(LFF_GkU6yXwmCXGPJi!S!Q#2Z8^Y;)a6^}+_&l5JS!AaDOW|g zt=47aK{^kNu$M<Tx%P7kQAin~rc<xBB)$CFvl#%o_m2cqy`DLkycfj~i5_k<Tj46k zsqGN8(tTL7gam2(-Kok{KI-2Bf&W}iDeVW2R~}ghx^U&ngkNT2qD+KR1uFjz+yBW1 zIh5JR&jlFLr1nCJqAm7vOq{geQ;|X1;6^|Du^$zyy(Qs@X)m$e8qHoOnCC}%k7c+# zXH3p2fxrr)_-b0xk?kT!P_kN`L_3v6T`3iSKgyxd=RNAnKUw0qbejE!csk&KM;nc0 zOdgZa-U9Xy#5QFKj$gX#oPay};#Em`mHH;Mi;GOm<JVRd=Gv6{;<hY=(gkX%034@> zBCe9Pmg;~j%!72+JsjoqNh8&>OC7!g6F!*<v(YON|KfMZbIT=Z4klhUR8}_hxP6^) z^&2?7w^O>~sxk+|I}^D~jIlRaj~Byn3JrkLf&vXO=?67IaVuU>jO@aP^<cstwJSlK zsd$U?-hrOZ77opH>PfC<20H4BT2p^b&LiX_xceMe@=MhU4f7H7LfJ3Tt_@bIwXv5P z+33S{un<$CT`d(|&M~U7#F-s3rz3{w_@hCbuF2FZiy4?ljPj8!HLe)pVBZ1~L2i!b zyqI;7dBGb;V`Pp5KEA#Z3=OYRJS)~4*U|5XZ{Hpnpb#A?PLy4iN>4B!7F%akREb7+ zHEIyVn+?&LWbqd%tC{zlUFSlZ8gv_wk(lv8`Tsy9RF|7^%UhlPS>!yWG$6KPjxfX} zZ8jnNc5W$jrqkUYgW;s<)3e#uGJHX=<PhySS=4Bdgz~e5QESr08wfHbwvx;Hgk($- zc4-}%A+E)!+UTvd<8?DlD8bmR<9%43y^cd@Nz8otmES#R%6aikjEsmEsfL(v9xk%% zMgeWyu5Oo{VX1e9iUfOe`M@he#*9@%g%(p$VwqQh7fUP3B#ZscsL=j?bccwXQeO^P zZ_!^f2BTB1*={yDGhCbNc%D*(`;?yELYB~`KAnveo+p6Ixr(0oolmu|g_Gy_8aC#q zhYB3=U3DH>pqmpvZeC%jopYEV57%RPF4rXt?bWVy$RJ9>gKwG@YHrk24fB_z2xY(r z<sfxZx(mn>jOU{&*pgo8<KB=$cD#C$5&z`Ei91wt85iD5P0k$uB5Ql&gV=aMU%Vm_ z?~pVhc?ee+^<Yl&MG@$lmgqU2%RrC6DR!CrFMM}@CnUpXrU15ihZH3MsyZLJUDwj6 zvl1?g)Ra&}oIXj)f=fwbby{%t^+;nF&#d_Oy2xEuM%iqR{Q<}XKS>LJ-<H^Zh()>R z)~Rl>UJV@r*eR>8)Z<}tV8S;1MT4@kEtIh93$zcVPT@pf6%@X|bb2gPX<jSzUX2^~ zd$qT2HXz_qJk@$zhC`r#ce3I)nMxz%)SqeEY4CV(t~Mvbf<wkYN9jSbWj!^N`+Wvg zH+2-r$_h_G-b&oA8u@6kP%TU~nh!#U+iuwcKba4sZ7Q4I5@$?8qh!T6KouE>x?9Pe z%0oBC_TA)!vS=vzFtu8mMenAK>53CLbALt78Wj#_RK_Z9lwPOSh8|SEH0_jer>GnG zWkRMw)`+0{`NmGIF3kj1O`(PQiIQ*o7X4!XruJ%B!iX#B7{i7)pFvjPK+Pe6POJyb zb6%Bu+Oe;TPGzPa0PoH2H7)-6z^L~Nc)-f&^)GzzXjvVC#Sxad<I>j7uAICSHak5G z@6WzW{1AUh2eo(a-~;d<nuh??hXaSbw#(Z6*dsgxnksSvLo6t=jb>J{!n$#yFSY0F z7NY^Zxu0&5I$xz!zMp=_Kw{s9dU|f!a1$-*2X|TM8E#nN08<-ako`54pf#S7N|xNC zY3|DJ?o#y?VoNl$k<n9<Bgs9IYu<};YzeA>XG+)>R0VH>-luM=D5$y_r&#CMkV#ru zldjd*5q7@0;;Ob_a|pJ}Wyf&tr^KU~P|Whjr>dYj<2e2R%2faqT__>(ZJwRguS$p} zW&a{gDR)8pEWNWp+*{{A)(<!pB?)sZt{3^9eTb2s3c_^5V>qO`%;jMz9dr;K4kP95 z%Ll0^Ou25hROjWqK;0ll<o^?G{vQpL=h2%oK=^5*AQPR3`$zkV(NwvuO$v8kNveN1 zagl>%aT7DZNJsbf6EccW;kqRup^$``UZxba`$gdi<sjXDxRP?_bWnq;j~h`D_Z1}q z<B)#jD0WelC!%3r>^m-yPK|zjNtTYfaSzACeg@3iwHD)<OXVbeb17sAW93-Ou&~YT z9n`~0%eoc)N|cEXave&b4F?TXScjsk`Kv<ZL<9cXc4U4OUE-*N-xX}n(L17~n!?w> z1S33~?K|Q<;|OCtsOI!kK65XHe<IV7-^TSG<44l)X?n~djA(fq?PV5Z9Y)az23aWe zcw~hCzS?Fh!c7Fgax1YMIY*=wT#a?sDm79KFmOX<w|rNHqri|hITsV{iJg#QN8<Da z1_yC-W%KX2<_dGLpWvRn%=OSV0T7p47`qvVkFqgA-7#gLJD+h&L^r@D)pcRWQbQo~ z7iv7XL@y(=^0NHsn9CQ(iv<B)FDIIxR|jKxv!n%n>}sJVFII1cQwbpncIme8LwrD| zQ}BkvT%Lx;u4a;opjl+R_A)}dZ;Bs}dBM+QW91PpW&pJqb49I4u4a}W>vou0toudr z?S^j3LcRaIJwkvLjkmBQEg1bxc^!pl^|+SImiXhL;oR<Utnp9iy!0;zZ*$zw&yVvT z+|GaU!NC1d{}{c-ZgDY15)TG!+reymu;lVPSiNQP4Z6f%f{QGiHd9}U4kx@|@Z(2! zQ3l`2I<BPn&TG^w-;7d>t$?`m_GBoh^6Ov#L}Y?*LY)gDD4dus8F!~q+Pln>Z-Lsq zW!1bYQrZg<u9C0E{c*DX%H{i8S-?Vp{WU{29kQfYxp}qa$7+{NQo&GNbyV_NXm4?l zB!qB#S9Q*!E86u74D$=aS?`FEthL@<3M^pK=p*ruLB*p{%8WP#!y)yBs{^OGhQu%; zhgyO_U*hnqOcOp986{5`8tt&WJXw7V>OQ!Nv%~l6D0`Di!6Wf_O}$<xID&IjB;*n@ z-t}`>L>tjU?A`a)fxN=0@&qCwB(1+cIGMTUq>SO_ss(J}-C_%ybRr(~J<aFz7;PO1 zhij)}QKA}Ewz>Rj>-U?ZFQ*{6dDE-fB_DpgM1Ia;{65a$!ilDK-3{RN^8_0P$;(Ip zKD-fA!A?~f`!~{B|8N|O5?$}H`y|tp<%Zhb%3B!x(uzdeD$?#4?xp10@=s__e#x0` z-BY_(fsC7g7$eK12E6?2$C`*{BBI@FlaHNOtum=m1`PUGP&BGULHGu@fVNf)^f#03 zPbFUYyA3`&&xK;4_uRL2ndnzBM|^@)54fT02(8-NP#RqOUV>_}H4h^eECd#1^~b67 z<unQEvv;TdqTgN)P#8GrULMST4us0PeIYb7pn-Ja#}3wo2Z|25;@T>wUp7%FM_J|@ z*%FBLBIFumiX)oy)8)>z1f)p--T<6)|3sAfbK31lV{|s(MInYy`&A8__Vo)i{8O#h zAVf9>I-*>pr4xa0^=kY57~LuxCU&>A>VqSq5L!-D*mLf%|G$wr%&vQDhA+LwHKbzI z{yfeJjB8m$?X)Y+EHkgyq4IVW;(`5wlbHZQglFRE*niE%{M#Nxpm2mWYg=Cw|JC@j zA7A4Sl@LbtUlsWXToXbKt)jx;3y(iRAJEN-0$6gn5M%qqgfGV;_<Xm&7ba<YNKl$T z!}Uh<@cfkJ>Po#rDMjtxV4BE}FXZiJT6V7Pl#qgy!1&Jid;gDltlVVz*prjx$B|#I z8Y{IahXm0@BK4XIqM?I>LyYDJyRcEJQTaJ8Iw}75pyqkKK<61xu*q})_p6M{Yfmd5 zMc;$L7`no0#-r?BbSI6?yhZV_=Qg?KE4}&KJpS*>JUPM`dy5MtWaGqk1=*Bx>w!SR zZsygVxdE%Zm!Hb<F_%a$atlFDN4E+dyBdFwnf$Yj^Y6ds`c9E3Q~)=rzvathsK^=N zT9|X%ZM>uxfX$J}mx&RuA@J!O+=_<84j>qwACPl_?rR`%yTSW0{rk7Tha(*edr5W= z61+-w6ctIZRkOou<=yh*I5cuLxtoe(kIaJ%QGD2*tISX#`Q|h|<;SBQ=*+n{SlNj8 z3DOI-{NLtx|K&O*y_y-Hy!^uJLhTnQP{8Mfg+o)_NwmBL-uykb{;gCMZ7so&EkPwV z8-z-D4)Bh3d*2lS0W?&du<e22?v0qgXvo-~!eaj~y;b#UehSC$S(RKc?$IH<dK9bM z*mn6eaDbzKIi^4N8ih=>#Pe)&ZCGkwbns4hmddojT*q0~y9hjCVw{w+U#y#8egE12 z)z1HAj{kYS|KIBLB|l+-OV4YCa-4z|2^D%Q2~|`9fh8Cq3V3!${m=g)0MmW)4xH_j shZYEUouNAwfe+`G4ou|ZK~@~DKFl<i`X#nbs{T*A)qgX}5uRrM4<_#q)c^nh literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/RestartBuild.png b/dev-docs/source/images/RestartBuild.png new file mode 100644 index 0000000000000000000000000000000000000000..6c99976e3b7a86a66e48ef4c57ec22e73ea0a315 GIT binary patch literal 79478 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 literal 0 HcmV?d00001 diff --git a/dev-docs/source/images/VisualStudioTestDebugProperties.png b/dev-docs/source/images/VisualStudioTestDebugProperties.png new file mode 100644 index 0000000000000000000000000000000000000000..2f92b379d8c080b1624f924f3a316c5c91eabf7c GIT binary patch literal 96923 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 NoRqR;wfN_+{|94YD!%{# literal 0 HcmV?d00001 diff --git a/dev-docs/source/index.rst b/dev-docs/source/index.rst index ebf236f4ac0..0ac831a84b6 100644 --- a/dev-docs/source/index.rst +++ b/dev-docs/source/index.rst @@ -1,17 +1,18 @@ -.. Documentation master file - It contains a hidden root toctree directive so that Sphinx - has an internal index of all of the pages and doesn't - produce a plethora of warnings about most documents not being in - a toctree. - See http://sphinx-doc.org/tutorial.html#defining-document-structure - .. _contents: ======================= Developer Documentation ======================= -These pages contain the developer documentation for mantid version |release|. +.. toctree:: + :hidden: + + DevelopmentTeam + +These pages contain the developer documentation for mantid. They are aimed at those who are modifying the +source code of the project. For user documentation please see :ref:`here <mantid:contents>`. + +Meet the :ref:`team <DevelopmentTeam>`. ====== Guides @@ -20,10 +21,157 @@ Guides .. toctree:: :hidden: + DeveloperAccounts GettingStarted + BuildingOnOSX + BuildingWithCMake + BuildingVATES + Standards/index + DoxygenSetup + Python3 + +:doc:`DeveloperAccounts` + Details of the accounts required for developers. :doc:`GettingStarted` - Describes the process of obtaining and building the mantid code base + Describes the process of obtaining and building the mantid code base. + +:doc:`Standards <Standards/index>` + Details of coding and documentation standards for the project. Includes specifics regarding algorithms. + +:doc:`DoxygenSetup` + Configure a doxygen build locally. + +:doc:`Python3` + Building with Python 3 (Linux only). + +=================== +Development Process +=================== + +.. toctree:: + :hidden: + + DevelopmentAndReleaseCycle + Communication + IssueTracking + GitWorkflow + AutomatedBuildProcess + JenkinsConfiguration + ReleaseChecklist + PatchReleaseChecklist + TSC + DesignDocumentGuides + +:doc:`DevelopmentAndReleaseCycle` + An overview of the development cycle. + +:doc:`Communication` + Details various methods of communication used within the team. + +:doc:`IssueTracking` + Describes how issues are tracked over the project. + +:doc:`GitWorkflow` + Details the workflow used development with git and GitHub. + +:doc:`AutomatedBuildProcess` + Details the interaction of pull requests with the Jenkins CI builds. + +:doc:`JenkinsConfiguration` + Describes the setup of Jenkins system and how to add a new slave. + +:doc:`ReleaseChecklist` + How to perform a full release of Mantid. + +:doc:`PatchReleaseChecklist` + How to perform a patch release of Mantid. + +:doc:`TSC` + Overview of the role of the technical steering committee. + +:doc:`DesignDocumentGuides` + How to write a good design document. + +===== +Tools +===== + +.. toctree:: + :hidden: + + ToolsOverview + ProfilingWithValgrind + FlowchartCreation + VisualStudioBuildImpact + +:doc:`ToolsOverview` + Describes ``class_maker``, ``valgrind`` and related tools. + +:doc:`ProfilingWithValgrind` + How to use valgrind to profile your code. + +:doc:`FlowchartCreation` + Describes how to create a flow chart with dot. + +:doc:`VisualStudioBuildImpact` + Provides a script to reduce the impact of Visual Studio on machine performance. + +======= +Testing +======= + +.. toctree:: + :hidden: + + RunningTheUnitTests + DebuggingUnitTests + UnitTestGoodPractice + WritingPerformanceTests + SystemTests + DataFilesForTesting + TestingUtilities + +:doc:`RunningTheUnitTests` + Details on how to run the suite of unit tests. + +:doc:`DebuggingUnitTests` + Details on how to debug the suite of unit tests. + +:doc:`UnitTestGoodPractice` + Guidance on writing good unit tests. + +:doc:`WritingPerformanceTests` + A walk through of how to write a performance test. + +:doc:`SystemTests` + Guidance on working with the system tests. + +:doc:`DataFilesForTesting` + How to work with test data files in the mantid repository. + +:doc:`TestingUtilities` + Helper utlities used for testing. + +=============== +GUI Development +=============== + +.. toctree:: + :hidden: + + GUIDesignGuidelines + MVPTutorial/index + QtDesignerForPython + +:doc:`GUIDesignGuidelines` + Gives some guidelines to consider when developing a new graphical user interface. + +:doc:`MVP Tutorial <MVPTutorial/index>` + A hands-on tutorial on how to implement a user GUI using the Model-View-Presenter (MVP) pattern. + +:doc:`QtDesignerForPython` + Describes how to use the Qt designer to produce GUI views. =================== Component Overviews @@ -33,5 +181,14 @@ Component Overviews :maxdepth: 1 AlgorithmMPISupport + HandlingXML IndexProperty + InstrumentViewer ISISSANSReductionBackend + LoadAlgorithmHook + Logging + MultiThreadingInAlgorithms + PythonVSCppAlgorithms + RemoteJobSubmissionAPI + WritingAnAlgorithm + WritingCustomConvertToMDTransformation diff --git a/docs/source/algorithms/Abins-v1.rst b/docs/source/algorithms/Abins-v1.rst index 65eb426395c..99c1e7ed0d0 100644 --- a/docs/source/algorithms/Abins-v1.rst +++ b/docs/source/algorithms/Abins-v1.rst @@ -11,7 +11,7 @@ Contributors: .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AbortRemoteJob-v1.rst b/docs/source/algorithms/AbortRemoteJob-v1.rst index bf611d704d8..c921941466f 100644 --- a/docs/source/algorithms/AbortRemoteJob-v1.rst +++ b/docs/source/algorithms/AbortRemoteJob-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AbortRemoteJob-v2.rst b/docs/source/algorithms/AbortRemoteJob-v2.rst index 2d1f4dd5d10..460a24c0a64 100644 --- a/docs/source/algorithms/AbortRemoteJob-v2.rst +++ b/docs/source/algorithms/AbortRemoteJob-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AbsorptionCorrection-v1.rst b/docs/source/algorithms/AbsorptionCorrection-v1.rst index 7684c333232..7ee7e67caee 100644 --- a/docs/source/algorithms/AbsorptionCorrection-v1.rst +++ b/docs/source/algorithms/AbsorptionCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AccumulateMD-v1.rst b/docs/source/algorithms/AccumulateMD-v1.rst index fdd1a6c4f81..8b8b2ccb4ad 100644 --- a/docs/source/algorithms/AccumulateMD-v1.rst +++ b/docs/source/algorithms/AccumulateMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AddLogDerivative-v1.rst b/docs/source/algorithms/AddLogDerivative-v1.rst index c2880f978ff..dbb72ea3836 100644 --- a/docs/source/algorithms/AddLogDerivative-v1.rst +++ b/docs/source/algorithms/AddLogDerivative-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AddNote-v1.rst b/docs/source/algorithms/AddNote-v1.rst index d834faa4005..c25491208f0 100644 --- a/docs/source/algorithms/AddNote-v1.rst +++ b/docs/source/algorithms/AddNote-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AddPeak-v1.rst b/docs/source/algorithms/AddPeak-v1.rst index 6dae159033c..c92fc413894 100644 --- a/docs/source/algorithms/AddPeak-v1.rst +++ b/docs/source/algorithms/AddPeak-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AddPeakHKL-v1.rst b/docs/source/algorithms/AddPeakHKL-v1.rst index ee71dc1ce11..62ec2126ebf 100644 --- a/docs/source/algorithms/AddPeakHKL-v1.rst +++ b/docs/source/algorithms/AddPeakHKL-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AddSampleLog-v1.rst b/docs/source/algorithms/AddSampleLog-v1.rst index 6cad3c01270..86bcde338ab 100644 --- a/docs/source/algorithms/AddSampleLog-v1.rst +++ b/docs/source/algorithms/AddSampleLog-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AddSampleLogMultiple-v1.rst b/docs/source/algorithms/AddSampleLogMultiple-v1.rst index 0f445b1e1f7..e736057e43f 100644 --- a/docs/source/algorithms/AddSampleLogMultiple-v1.rst +++ b/docs/source/algorithms/AddSampleLogMultiple-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AddTimeSeriesLog-v1.rst b/docs/source/algorithms/AddTimeSeriesLog-v1.rst index 1ef19324053..8e3f3957f60 100644 --- a/docs/source/algorithms/AddTimeSeriesLog-v1.rst +++ b/docs/source/algorithms/AddTimeSeriesLog-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AlignAndFocusPowder-v1.rst b/docs/source/algorithms/AlignAndFocusPowder-v1.rst index 03ec09a13f1..78db7695af2 100644 --- a/docs/source/algorithms/AlignAndFocusPowder-v1.rst +++ b/docs/source/algorithms/AlignAndFocusPowder-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AlignAndFocusPowderFromFiles-v1.rst b/docs/source/algorithms/AlignAndFocusPowderFromFiles-v1.rst index 74130ed6f71..6449505cca4 100644 --- a/docs/source/algorithms/AlignAndFocusPowderFromFiles-v1.rst +++ b/docs/source/algorithms/AlignAndFocusPowderFromFiles-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AlignComponents-v1.rst b/docs/source/algorithms/AlignComponents-v1.rst index cc15126ce78..0507aa62031 100644 --- a/docs/source/algorithms/AlignComponents-v1.rst +++ b/docs/source/algorithms/AlignComponents-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AlignDetectors-v1.rst b/docs/source/algorithms/AlignDetectors-v1.rst index 74b8560ef5d..ab934df6daa 100644 --- a/docs/source/algorithms/AlignDetectors-v1.rst +++ b/docs/source/algorithms/AlignDetectors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AlphaCalc-v1.rst b/docs/source/algorithms/AlphaCalc-v1.rst index 10bea530d19..a633b115895 100644 --- a/docs/source/algorithms/AlphaCalc-v1.rst +++ b/docs/source/algorithms/AlphaCalc-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AndMD-v1.rst b/docs/source/algorithms/AndMD-v1.rst index b0aa2219756..273bd7896e7 100644 --- a/docs/source/algorithms/AndMD-v1.rst +++ b/docs/source/algorithms/AndMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AngularAutoCorrelationsSingleAxis-v1.rst b/docs/source/algorithms/AngularAutoCorrelationsSingleAxis-v1.rst index 83068dda4a8..fcc7eef89ef 100644 --- a/docs/source/algorithms/AngularAutoCorrelationsSingleAxis-v1.rst +++ b/docs/source/algorithms/AngularAutoCorrelationsSingleAxis-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AngularAutoCorrelationsTwoAxes-v1.rst b/docs/source/algorithms/AngularAutoCorrelationsTwoAxes-v1.rst index c6dd6717c61..644eae9ddfc 100644 --- a/docs/source/algorithms/AngularAutoCorrelationsTwoAxes-v1.rst +++ b/docs/source/algorithms/AngularAutoCorrelationsTwoAxes-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AnnularRingAbsorption-v1.rst b/docs/source/algorithms/AnnularRingAbsorption-v1.rst index 6fcc2deab20..212b9d069d7 100644 --- a/docs/source/algorithms/AnnularRingAbsorption-v1.rst +++ b/docs/source/algorithms/AnnularRingAbsorption-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AnvredCorrection-v1.rst b/docs/source/algorithms/AnvredCorrection-v1.rst index ed28378e627..cc95d0cd3ae 100644 --- a/docs/source/algorithms/AnvredCorrection-v1.rst +++ b/docs/source/algorithms/AnvredCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AppendGeometryToSNSNexus-v1.rst b/docs/source/algorithms/AppendGeometryToSNSNexus-v1.rst index 104ea18c9d3..d7ad2395c19 100644 --- a/docs/source/algorithms/AppendGeometryToSNSNexus-v1.rst +++ b/docs/source/algorithms/AppendGeometryToSNSNexus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AppendSpectra-v1.rst b/docs/source/algorithms/AppendSpectra-v1.rst index 2ad75355f1a..9a2fa0e1bb8 100644 --- a/docs/source/algorithms/AppendSpectra-v1.rst +++ b/docs/source/algorithms/AppendSpectra-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ApplyCalibration-v1.rst b/docs/source/algorithms/ApplyCalibration-v1.rst index 44f4c793399..5f599a50a1d 100644 --- a/docs/source/algorithms/ApplyCalibration-v1.rst +++ b/docs/source/algorithms/ApplyCalibration-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ApplyDeadTimeCorr-v1.rst b/docs/source/algorithms/ApplyDeadTimeCorr-v1.rst index 3234aa9f0e9..09c864e0d82 100644 --- a/docs/source/algorithms/ApplyDeadTimeCorr-v1.rst +++ b/docs/source/algorithms/ApplyDeadTimeCorr-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ApplyDetailedBalance-v1.rst b/docs/source/algorithms/ApplyDetailedBalance-v1.rst index 2b9603ffc68..4c7e957b96a 100644 --- a/docs/source/algorithms/ApplyDetailedBalance-v1.rst +++ b/docs/source/algorithms/ApplyDetailedBalance-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ApplyDetectorScanEffCorr-v1.rst b/docs/source/algorithms/ApplyDetectorScanEffCorr-v1.rst index e458f484659..f1de79c8897 100644 --- a/docs/source/algorithms/ApplyDetectorScanEffCorr-v1.rst +++ b/docs/source/algorithms/ApplyDetectorScanEffCorr-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst b/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst index 3e548a2644c..fe194338505 100644 --- a/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst +++ b/docs/source/algorithms/ApplyPaalmanPingsCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ApplyTransmissionCorrection-v1.rst b/docs/source/algorithms/ApplyTransmissionCorrection-v1.rst index 2d2524e4519..0e887cd4626 100644 --- a/docs/source/algorithms/ApplyTransmissionCorrection-v1.rst +++ b/docs/source/algorithms/ApplyTransmissionCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AsymmetryCalc-v1.rst b/docs/source/algorithms/AsymmetryCalc-v1.rst index 311e2821e3c..670fac8573e 100644 --- a/docs/source/algorithms/AsymmetryCalc-v1.rst +++ b/docs/source/algorithms/AsymmetryCalc-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Authenticate-v1.rst b/docs/source/algorithms/Authenticate-v1.rst index b53f067c189..664b7ea7fb2 100644 --- a/docs/source/algorithms/Authenticate-v1.rst +++ b/docs/source/algorithms/Authenticate-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Authenticate-v2.rst b/docs/source/algorithms/Authenticate-v2.rst index 785ed8e1011..ae46874065e 100644 --- a/docs/source/algorithms/Authenticate-v2.rst +++ b/docs/source/algorithms/Authenticate-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/AverageLogData-v1.rst b/docs/source/algorithms/AverageLogData-v1.rst index a987825908e..bec9ee6bc2d 100644 --- a/docs/source/algorithms/AverageLogData-v1.rst +++ b/docs/source/algorithms/AverageLogData-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/BASISDiffraction-v1.rst b/docs/source/algorithms/BASISDiffraction-v1.rst index 45855596945..138a4783f18 100644 --- a/docs/source/algorithms/BASISDiffraction-v1.rst +++ b/docs/source/algorithms/BASISDiffraction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -43,7 +43,7 @@ and isotropic scattering to determine instrument efficiency per detector. If no vanadium is provided, all detectors are assumed to have the same efficiency Determine Single Crystal Diffraction -==================================== +#################################### Creates a diffraction pattern from a set of runs implementing a rotational scan of the sample around the vertical axis. The @@ -52,7 +52,7 @@ corresponding goniometer's rotation should be logged under log name angle. Sample orientation -~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^ **VectorU**: Vector along k_i, when goniometer is at offset. @@ -60,7 +60,7 @@ Sample orientation offset. Diffraction preferences -~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^ Most of the scattering occurs in the plane defined by VectorU and VectorV. Please choose Uproj and Vproj defining a plane that is as close as possible diff --git a/docs/source/algorithms/BASISReduction-v1.rst b/docs/source/algorithms/BASISReduction-v1.rst index 93dc4a8b287..c0408383ab0 100644 --- a/docs/source/algorithms/BASISReduction-v1.rst +++ b/docs/source/algorithms/BASISReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/BASISReduction311-v1.rst b/docs/source/algorithms/BASISReduction311-v1.rst index 430fb2017b6..6ca9c90a268 100644 --- a/docs/source/algorithms/BASISReduction311-v1.rst +++ b/docs/source/algorithms/BASISReduction311-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -32,7 +32,7 @@ lower boundary the bin with the minimum momentum, the bin width, and the upper boundary ofthe bin with the maximum momentum. Reflection Selector -=================== +################### There are typical values for the properties of the 311 reflection: diff --git a/docs/source/algorithms/BayesQuasi-v1.rst b/docs/source/algorithms/BayesQuasi-v1.rst index 1fd36c075b1..720e00dc3fa 100644 --- a/docs/source/algorithms/BayesQuasi-v1.rst +++ b/docs/source/algorithms/BayesQuasi-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/BayesStretch-v1.rst b/docs/source/algorithms/BayesStretch-v1.rst index 5fdf7020a30..2fe36ac5484 100644 --- a/docs/source/algorithms/BayesStretch-v1.rst +++ b/docs/source/algorithms/BayesStretch-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Bin2DPowderDiffraction-v1.rst b/docs/source/algorithms/Bin2DPowderDiffraction-v1.rst index 32317820bc9..f890cf6ba46 100644 --- a/docs/source/algorithms/Bin2DPowderDiffraction-v1.rst +++ b/docs/source/algorithms/Bin2DPowderDiffraction-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/BinMD-v1.rst b/docs/source/algorithms/BinMD-v1.rst index d55794cbcd4..dd74733829f 100644 --- a/docs/source/algorithms/BinMD-v1.rst +++ b/docs/source/algorithms/BinMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/BinWidthAtX-v1.rst b/docs/source/algorithms/BinWidthAtX-v1.rst index 9d65bc04234..23434ef27e5 100644 --- a/docs/source/algorithms/BinWidthAtX-v1.rst +++ b/docs/source/algorithms/BinWidthAtX-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/BinaryOperateMasks-v1.rst b/docs/source/algorithms/BinaryOperateMasks-v1.rst index c8b284618f9..e43c3072522 100644 --- a/docs/source/algorithms/BinaryOperateMasks-v1.rst +++ b/docs/source/algorithms/BinaryOperateMasks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/BroadcastWorkspace-v1.rst b/docs/source/algorithms/BroadcastWorkspace-v1.rst index ac4e4c529d0..ca441f47ce6 100644 --- a/docs/source/algorithms/BroadcastWorkspace-v1.rst +++ b/docs/source/algorithms/BroadcastWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalMuonDeadTime-v1.rst b/docs/source/algorithms/CalMuonDeadTime-v1.rst index 25e721cd2a8..b34e67d8287 100644 --- a/docs/source/algorithms/CalMuonDeadTime-v1.rst +++ b/docs/source/algorithms/CalMuonDeadTime-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalMuonDetectorPhases-v1.rst b/docs/source/algorithms/CalMuonDetectorPhases-v1.rst index 45edeb93615..833c1738853 100644 --- a/docs/source/algorithms/CalMuonDetectorPhases-v1.rst +++ b/docs/source/algorithms/CalMuonDetectorPhases-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculateChiSquared-v1.rst b/docs/source/algorithms/CalculateChiSquared-v1.rst index 03ba5e7f4a0..e96c3a6b10e 100644 --- a/docs/source/algorithms/CalculateChiSquared-v1.rst +++ b/docs/source/algorithms/CalculateChiSquared-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -34,7 +34,7 @@ Finally, ChiSquaredWeightedDividedByDOF is :math:`\chi_{4}^{2} = \chi_{3}^{2} / DOF` Parameter errors -================ +################ Setting the Output property to a non-empty string makes the algorithm explore the surface of the :math:`\chi^{2}` around its minimum and estimate the standard deviations for the parameters. The value of the property is a base name diff --git a/docs/source/algorithms/CalculateCostFunction-v1.rst b/docs/source/algorithms/CalculateCostFunction-v1.rst index 5bd9729208f..eec1d6353e4 100644 --- a/docs/source/algorithms/CalculateCostFunction-v1.rst +++ b/docs/source/algorithms/CalculateCostFunction-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculateCountRate-v1.rst b/docs/source/algorithms/CalculateCountRate-v1.rst index acdaee775c5..4239df77670 100644 --- a/docs/source/algorithms/CalculateCountRate-v1.rst +++ b/docs/source/algorithms/CalculateCountRate-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculateCoverageDGS-v1.rst b/docs/source/algorithms/CalculateCoverageDGS-v1.rst index 7dad0cf83de..53b665d420b 100644 --- a/docs/source/algorithms/CalculateCoverageDGS-v1.rst +++ b/docs/source/algorithms/CalculateCoverageDGS-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculateDIFC-v1.rst b/docs/source/algorithms/CalculateDIFC-v1.rst index 6191fad9994..33baf51d2d5 100644 --- a/docs/source/algorithms/CalculateDIFC-v1.rst +++ b/docs/source/algorithms/CalculateDIFC-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculateEfficiency-v1.rst b/docs/source/algorithms/CalculateEfficiency-v1.rst index 28cf323f3d2..7de882a7149 100644 --- a/docs/source/algorithms/CalculateEfficiency-v1.rst +++ b/docs/source/algorithms/CalculateEfficiency-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculateFlatBackground-v1.rst b/docs/source/algorithms/CalculateFlatBackground-v1.rst index 10195afcb26..5c01a59b2dd 100644 --- a/docs/source/algorithms/CalculateFlatBackground-v1.rst +++ b/docs/source/algorithms/CalculateFlatBackground-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculateMonteCarloAbsorption-v1.rst b/docs/source/algorithms/CalculateMonteCarloAbsorption-v1.rst index 5a5e85e049c..a9c5d549076 100644 --- a/docs/source/algorithms/CalculateMonteCarloAbsorption-v1.rst +++ b/docs/source/algorithms/CalculateMonteCarloAbsorption-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculateMuonAsymmetry-v1.rst b/docs/source/algorithms/CalculateMuonAsymmetry-v1.rst index af7fda48208..21af76b939e 100644 --- a/docs/source/algorithms/CalculateMuonAsymmetry-v1.rst +++ b/docs/source/algorithms/CalculateMuonAsymmetry-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculatePeaksHKL-v1.rst b/docs/source/algorithms/CalculatePeaksHKL-v1.rst index 2d18a6150c5..bbcac2512cf 100644 --- a/docs/source/algorithms/CalculatePeaksHKL-v1.rst +++ b/docs/source/algorithms/CalculatePeaksHKL-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculatePolynomialBackground-v1.rst b/docs/source/algorithms/CalculatePolynomialBackground-v1.rst index 4887185a85b..06f99fc8f85 100644 --- a/docs/source/algorithms/CalculatePolynomialBackground-v1.rst +++ b/docs/source/algorithms/CalculatePolynomialBackground-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculateSampleTransmission-v1.rst b/docs/source/algorithms/CalculateSampleTransmission-v1.rst index f062723d18e..b1bef7feac5 100644 --- a/docs/source/algorithms/CalculateSampleTransmission-v1.rst +++ b/docs/source/algorithms/CalculateSampleTransmission-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculateSlits-v1.rst b/docs/source/algorithms/CalculateSlits-v1.rst index cca529d82ff..1b2967b0baa 100644 --- a/docs/source/algorithms/CalculateSlits-v1.rst +++ b/docs/source/algorithms/CalculateSlits-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculateTransmission-v1.rst b/docs/source/algorithms/CalculateTransmission-v1.rst index 5bfd0afedd1..461cfaa8fd6 100644 --- a/docs/source/algorithms/CalculateTransmission-v1.rst +++ b/docs/source/algorithms/CalculateTransmission-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculateTransmissionBeamSpreader-v1.rst b/docs/source/algorithms/CalculateTransmissionBeamSpreader-v1.rst index 71a50f3095f..010fbcf80f9 100644 --- a/docs/source/algorithms/CalculateTransmissionBeamSpreader-v1.rst +++ b/docs/source/algorithms/CalculateTransmissionBeamSpreader-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculateUMatrix-v1.rst b/docs/source/algorithms/CalculateUMatrix-v1.rst index f72fc909941..b729b1be1c6 100644 --- a/docs/source/algorithms/CalculateUMatrix-v1.rst +++ b/docs/source/algorithms/CalculateUMatrix-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalculateZscore-v1.rst b/docs/source/algorithms/CalculateZscore-v1.rst index d444025b3f1..b422c76d5c6 100644 --- a/docs/source/algorithms/CalculateZscore-v1.rst +++ b/docs/source/algorithms/CalculateZscore-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CalibrateRectangularDetectors-v1.rst b/docs/source/algorithms/CalibrateRectangularDetectors-v1.rst index 561db96cb82..21b98f4b420 100644 --- a/docs/source/algorithms/CalibrateRectangularDetectors-v1.rst +++ b/docs/source/algorithms/CalibrateRectangularDetectors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CatalogDownloadDataFiles-v1.rst b/docs/source/algorithms/CatalogDownloadDataFiles-v1.rst index d0ff2cba2be..462f7007d3e 100644 --- a/docs/source/algorithms/CatalogDownloadDataFiles-v1.rst +++ b/docs/source/algorithms/CatalogDownloadDataFiles-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CatalogGetDataFiles-v1.rst b/docs/source/algorithms/CatalogGetDataFiles-v1.rst index 3688e18d63a..661daf99a69 100644 --- a/docs/source/algorithms/CatalogGetDataFiles-v1.rst +++ b/docs/source/algorithms/CatalogGetDataFiles-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CatalogGetDataSets-v1.rst b/docs/source/algorithms/CatalogGetDataSets-v1.rst index 6727e74f9f2..fa5707b9145 100644 --- a/docs/source/algorithms/CatalogGetDataSets-v1.rst +++ b/docs/source/algorithms/CatalogGetDataSets-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CatalogKeepAlive-v1.rst b/docs/source/algorithms/CatalogKeepAlive-v1.rst index 755580feafb..ec38fc828ca 100644 --- a/docs/source/algorithms/CatalogKeepAlive-v1.rst +++ b/docs/source/algorithms/CatalogKeepAlive-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CatalogListInstruments-v1.rst b/docs/source/algorithms/CatalogListInstruments-v1.rst index 5fe41febc6d..8062a2c02b5 100644 --- a/docs/source/algorithms/CatalogListInstruments-v1.rst +++ b/docs/source/algorithms/CatalogListInstruments-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CatalogListInvestigationTypes-v1.rst b/docs/source/algorithms/CatalogListInvestigationTypes-v1.rst index 9a265490df9..85ed1401ced 100644 --- a/docs/source/algorithms/CatalogListInvestigationTypes-v1.rst +++ b/docs/source/algorithms/CatalogListInvestigationTypes-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CatalogLogin-v1.rst b/docs/source/algorithms/CatalogLogin-v1.rst index 34693f8be88..dbcca9fa7e4 100644 --- a/docs/source/algorithms/CatalogLogin-v1.rst +++ b/docs/source/algorithms/CatalogLogin-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CatalogLogout-v1.rst b/docs/source/algorithms/CatalogLogout-v1.rst index 4c5e02a01cd..9f4b99432b1 100644 --- a/docs/source/algorithms/CatalogLogout-v1.rst +++ b/docs/source/algorithms/CatalogLogout-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CatalogMyDataSearch-v1.rst b/docs/source/algorithms/CatalogMyDataSearch-v1.rst index 54a479042e5..798ae42d16c 100644 --- a/docs/source/algorithms/CatalogMyDataSearch-v1.rst +++ b/docs/source/algorithms/CatalogMyDataSearch-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CatalogPublish-v1.rst b/docs/source/algorithms/CatalogPublish-v1.rst index 3e17d508178..d7a82865bcb 100644 --- a/docs/source/algorithms/CatalogPublish-v1.rst +++ b/docs/source/algorithms/CatalogPublish-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CatalogSearch-v1.rst b/docs/source/algorithms/CatalogSearch-v1.rst index a57ff5abfc8..955cb0a4cde 100644 --- a/docs/source/algorithms/CatalogSearch-v1.rst +++ b/docs/source/algorithms/CatalogSearch-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CentroidPeaks-v1.rst b/docs/source/algorithms/CentroidPeaks-v1.rst index 29469ed3d93..68797211ba7 100644 --- a/docs/source/algorithms/CentroidPeaks-v1.rst +++ b/docs/source/algorithms/CentroidPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CentroidPeaksMD-v1.rst b/docs/source/algorithms/CentroidPeaksMD-v1.rst index e36680d16e9..fe919f273ec 100644 --- a/docs/source/algorithms/CentroidPeaksMD-v1.rst +++ b/docs/source/algorithms/CentroidPeaksMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CentroidPeaksMD-v2.rst b/docs/source/algorithms/CentroidPeaksMD-v2.rst index 72f79075cd1..98e01b64e9b 100644 --- a/docs/source/algorithms/CentroidPeaksMD-v2.rst +++ b/docs/source/algorithms/CentroidPeaksMD-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ChangeBinOffset-v1.rst b/docs/source/algorithms/ChangeBinOffset-v1.rst index 69738abb70a..9ee68e7ee1b 100644 --- a/docs/source/algorithms/ChangeBinOffset-v1.rst +++ b/docs/source/algorithms/ChangeBinOffset-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ChangeLogTime-v1.rst b/docs/source/algorithms/ChangeLogTime-v1.rst index 9e41dd1a69b..38f19d3efd0 100644 --- a/docs/source/algorithms/ChangeLogTime-v1.rst +++ b/docs/source/algorithms/ChangeLogTime-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ChangePulsetime-v1.rst b/docs/source/algorithms/ChangePulsetime-v1.rst index 00cd7903937..0ce29e0158c 100644 --- a/docs/source/algorithms/ChangePulsetime-v1.rst +++ b/docs/source/algorithms/ChangePulsetime-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ChangeQConvention-v1.rst b/docs/source/algorithms/ChangeQConvention-v1.rst index c76f26b1497..bef585d464e 100644 --- a/docs/source/algorithms/ChangeQConvention-v1.rst +++ b/docs/source/algorithms/ChangeQConvention-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ChangeTimeZero-v1.rst b/docs/source/algorithms/ChangeTimeZero-v1.rst index 79804c89430..bd81c0b1c16 100644 --- a/docs/source/algorithms/ChangeTimeZero-v1.rst +++ b/docs/source/algorithms/ChangeTimeZero-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CheckForSampleLogs-v1.rst b/docs/source/algorithms/CheckForSampleLogs-v1.rst index d97dbd87a67..de24be8a007 100644 --- a/docs/source/algorithms/CheckForSampleLogs-v1.rst +++ b/docs/source/algorithms/CheckForSampleLogs-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CheckMantidVersion-v1.rst b/docs/source/algorithms/CheckMantidVersion-v1.rst index bfb5768748c..595e956309b 100644 --- a/docs/source/algorithms/CheckMantidVersion-v1.rst +++ b/docs/source/algorithms/CheckMantidVersion-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CheckWorkspacesMatch-v1.rst b/docs/source/algorithms/CheckWorkspacesMatch-v1.rst index ce78cc7d3c4..34ba2f073a1 100644 --- a/docs/source/algorithms/CheckWorkspacesMatch-v1.rst +++ b/docs/source/algorithms/CheckWorkspacesMatch-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ChopData-v1.rst b/docs/source/algorithms/ChopData-v1.rst index 90ad0f94521..07a53ced0fa 100644 --- a/docs/source/algorithms/ChopData-v1.rst +++ b/docs/source/algorithms/ChopData-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CleanFileCache-v1.rst b/docs/source/algorithms/CleanFileCache-v1.rst index 236e24ec9ec..9e8c2fa0a75 100644 --- a/docs/source/algorithms/CleanFileCache-v1.rst +++ b/docs/source/algorithms/CleanFileCache-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ClearCache-v1.rst b/docs/source/algorithms/ClearCache-v1.rst index d630d350ad9..6f9ec08b869 100644 --- a/docs/source/algorithms/ClearCache-v1.rst +++ b/docs/source/algorithms/ClearCache-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ClearInstrumentParameters-v1.rst b/docs/source/algorithms/ClearInstrumentParameters-v1.rst index 6b46c307ead..221189b6a35 100644 --- a/docs/source/algorithms/ClearInstrumentParameters-v1.rst +++ b/docs/source/algorithms/ClearInstrumentParameters-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ClearMaskFlag-v1.rst b/docs/source/algorithms/ClearMaskFlag-v1.rst index a7954af4bf5..d3697d77a46 100644 --- a/docs/source/algorithms/ClearMaskFlag-v1.rst +++ b/docs/source/algorithms/ClearMaskFlag-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ClearMaskedSpectra-v1.rst b/docs/source/algorithms/ClearMaskedSpectra-v1.rst index 8574b039493..13a626fb6cd 100644 --- a/docs/source/algorithms/ClearMaskedSpectra-v1.rst +++ b/docs/source/algorithms/ClearMaskedSpectra-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ClearUB-v1.rst b/docs/source/algorithms/ClearUB-v1.rst index f7ddea6d04e..9edefe8e386 100644 --- a/docs/source/algorithms/ClearUB-v1.rst +++ b/docs/source/algorithms/ClearUB-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CloneMDWorkspace-v1.rst b/docs/source/algorithms/CloneMDWorkspace-v1.rst index 3978dd60277..664ba2239bb 100644 --- a/docs/source/algorithms/CloneMDWorkspace-v1.rst +++ b/docs/source/algorithms/CloneMDWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CloneWorkspace-v1.rst b/docs/source/algorithms/CloneWorkspace-v1.rst index d1b5458f355..51718eba501 100644 --- a/docs/source/algorithms/CloneWorkspace-v1.rst +++ b/docs/source/algorithms/CloneWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst b/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst index 8c4d91d2c0c..075932fc57e 100644 --- a/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst +++ b/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CombinePeaksWorkspaces-v1.rst b/docs/source/algorithms/CombinePeaksWorkspaces-v1.rst index 1d3bf040e34..f3f5534d12f 100644 --- a/docs/source/algorithms/CombinePeaksWorkspaces-v1.rst +++ b/docs/source/algorithms/CombinePeaksWorkspaces-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Comment-v1.rst b/docs/source/algorithms/Comment-v1.rst index aa250230abd..c592f7a2642 100644 --- a/docs/source/algorithms/Comment-v1.rst +++ b/docs/source/algorithms/Comment-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CompactMD-v1.rst b/docs/source/algorithms/CompactMD-v1.rst index b49816bfe2f..7eb52c0c5bf 100644 --- a/docs/source/algorithms/CompactMD-v1.rst +++ b/docs/source/algorithms/CompactMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CompareMDWorkspaces-v1.rst b/docs/source/algorithms/CompareMDWorkspaces-v1.rst index f9c5e19a6cf..6a95360b849 100644 --- a/docs/source/algorithms/CompareMDWorkspaces-v1.rst +++ b/docs/source/algorithms/CompareMDWorkspaces-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CompareSampleLogs-v1.rst b/docs/source/algorithms/CompareSampleLogs-v1.rst index ce743b9a154..6ba35f8a55e 100644 --- a/docs/source/algorithms/CompareSampleLogs-v1.rst +++ b/docs/source/algorithms/CompareSampleLogs-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CompareWorkspaces-v1.rst b/docs/source/algorithms/CompareWorkspaces-v1.rst index 10b56b5e7f3..edd066552cf 100644 --- a/docs/source/algorithms/CompareWorkspaces-v1.rst +++ b/docs/source/algorithms/CompareWorkspaces-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CompressEvents-v1.rst b/docs/source/algorithms/CompressEvents-v1.rst index b724fe24045..31d04b4c265 100644 --- a/docs/source/algorithms/CompressEvents-v1.rst +++ b/docs/source/algorithms/CompressEvents-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -16,7 +16,7 @@ resolution. This switch is made by specifying a Without pulsetime resolution -============================ +############################ This algorithm starts by sorting the event lists by TOF (or whatever the independent axis is) and ignoring the pulsetime. Therefore you may @@ -43,7 +43,7 @@ changes to its X values (unit conversion for example), you have to use your best judgement for the Tolerance value. With pulsetime resolution -========================= +######################### Similar to the version without pulsetime resolution with a few key differences: diff --git a/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst b/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst index 48e59b72e4b..0a224767475 100644 --- a/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst +++ b/docs/source/algorithms/ComputeCalibrationCoefVan-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ComputeIncoherentDOS-v1.rst b/docs/source/algorithms/ComputeIncoherentDOS-v1.rst index e6420dfc9ca..5d72a98029f 100644 --- a/docs/source/algorithms/ComputeIncoherentDOS-v1.rst +++ b/docs/source/algorithms/ComputeIncoherentDOS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ComputeSensitivity-v1.rst b/docs/source/algorithms/ComputeSensitivity-v1.rst index 4d634d01892..d8a46b16cef 100644 --- a/docs/source/algorithms/ComputeSensitivity-v1.rst +++ b/docs/source/algorithms/ComputeSensitivity-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConjoinFiles-v1.rst b/docs/source/algorithms/ConjoinFiles-v1.rst index eb087a5e9ff..18c5fc1b442 100644 --- a/docs/source/algorithms/ConjoinFiles-v1.rst +++ b/docs/source/algorithms/ConjoinFiles-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConjoinSpectra-v1.rst b/docs/source/algorithms/ConjoinSpectra-v1.rst index 5d12ae84847..1de5a0aff85 100644 --- a/docs/source/algorithms/ConjoinSpectra-v1.rst +++ b/docs/source/algorithms/ConjoinSpectra-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConjoinWorkspaces-v1.rst b/docs/source/algorithms/ConjoinWorkspaces-v1.rst index ab027b06f81..a29f7aa4ffa 100644 --- a/docs/source/algorithms/ConjoinWorkspaces-v1.rst +++ b/docs/source/algorithms/ConjoinWorkspaces-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConjoinXRuns-v1.rst b/docs/source/algorithms/ConjoinXRuns-v1.rst index 28b2c8b7803..97c0261bf53 100644 --- a/docs/source/algorithms/ConjoinXRuns-v1.rst +++ b/docs/source/algorithms/ConjoinXRuns-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertAxesToRealSpace-v1.rst b/docs/source/algorithms/ConvertAxesToRealSpace-v1.rst index fe11f4e7b47..018ae20ab4a 100644 --- a/docs/source/algorithms/ConvertAxesToRealSpace-v1.rst +++ b/docs/source/algorithms/ConvertAxesToRealSpace-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertAxisByFormula-v1.rst b/docs/source/algorithms/ConvertAxisByFormula-v1.rst index 60d703e14b4..88cb4d06612 100644 --- a/docs/source/algorithms/ConvertAxisByFormula-v1.rst +++ b/docs/source/algorithms/ConvertAxisByFormula-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst b/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst index a68b94e474b..39f63591a78 100644 --- a/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst +++ b/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst b/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst index f73282142aa..b369acddac2 100644 --- a/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst +++ b/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst b/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst index a5fe1e7dcea..5d07e1a6b65 100644 --- a/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst +++ b/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertDiffCal-v1.rst b/docs/source/algorithms/ConvertDiffCal-v1.rst index 37ddd84ceab..77f2f08a7b6 100644 --- a/docs/source/algorithms/ConvertDiffCal-v1.rst +++ b/docs/source/algorithms/ConvertDiffCal-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertEmptyToTof-v1.rst b/docs/source/algorithms/ConvertEmptyToTof-v1.rst index 917c8f09d34..a9f436b2c3d 100644 --- a/docs/source/algorithms/ConvertEmptyToTof-v1.rst +++ b/docs/source/algorithms/ConvertEmptyToTof-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertFromDistribution-v1.rst b/docs/source/algorithms/ConvertFromDistribution-v1.rst index d4254dcd47e..4e2a20cbf40 100644 --- a/docs/source/algorithms/ConvertFromDistribution-v1.rst +++ b/docs/source/algorithms/ConvertFromDistribution-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertMDHistoToMatrixWorkspace-v1.rst b/docs/source/algorithms/ConvertMDHistoToMatrixWorkspace-v1.rst index f43815f5267..20247520553 100644 --- a/docs/source/algorithms/ConvertMDHistoToMatrixWorkspace-v1.rst +++ b/docs/source/algorithms/ConvertMDHistoToMatrixWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertMultipleRunsToSingleCrystalMD-v1.rst b/docs/source/algorithms/ConvertMultipleRunsToSingleCrystalMD-v1.rst index 774bc579774..f26dd0f573f 100644 --- a/docs/source/algorithms/ConvertMultipleRunsToSingleCrystalMD-v1.rst +++ b/docs/source/algorithms/ConvertMultipleRunsToSingleCrystalMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertSnsRoiFileToMask-v1.rst b/docs/source/algorithms/ConvertSnsRoiFileToMask-v1.rst index e3315aae1c9..daa157d1a89 100644 --- a/docs/source/algorithms/ConvertSnsRoiFileToMask-v1.rst +++ b/docs/source/algorithms/ConvertSnsRoiFileToMask-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertSpectrumAxis-v1.rst b/docs/source/algorithms/ConvertSpectrumAxis-v1.rst index 84599ff4a65..b9f2664bfdb 100644 --- a/docs/source/algorithms/ConvertSpectrumAxis-v1.rst +++ b/docs/source/algorithms/ConvertSpectrumAxis-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertSpectrumAxis-v2.rst b/docs/source/algorithms/ConvertSpectrumAxis-v2.rst index 1e79f4ab6e5..862d0dae922 100644 --- a/docs/source/algorithms/ConvertSpectrumAxis-v2.rst +++ b/docs/source/algorithms/ConvertSpectrumAxis-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertSpiceDataToRealSpace-v1.rst b/docs/source/algorithms/ConvertSpiceDataToRealSpace-v1.rst index ab02f5f03b4..7b9e4474db0 100644 --- a/docs/source/algorithms/ConvertSpiceDataToRealSpace-v1.rst +++ b/docs/source/algorithms/ConvertSpiceDataToRealSpace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertTableToMatrixWorkspace-v1.rst b/docs/source/algorithms/ConvertTableToMatrixWorkspace-v1.rst index 8d86b1c18b6..cbafc32b82d 100644 --- a/docs/source/algorithms/ConvertTableToMatrixWorkspace-v1.rst +++ b/docs/source/algorithms/ConvertTableToMatrixWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToConstantL2-v1.rst b/docs/source/algorithms/ConvertToConstantL2-v1.rst index abfa265e013..34ed360392d 100644 --- a/docs/source/algorithms/ConvertToConstantL2-v1.rst +++ b/docs/source/algorithms/ConvertToConstantL2-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToDetectorFaceMD-v1.rst b/docs/source/algorithms/ConvertToDetectorFaceMD-v1.rst index 67ceea7278c..8d14fc3b38c 100644 --- a/docs/source/algorithms/ConvertToDetectorFaceMD-v1.rst +++ b/docs/source/algorithms/ConvertToDetectorFaceMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v1.rst b/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v1.rst index c3733997857..95f35cef4c4 100644 --- a/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v1.rst +++ b/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v2.rst b/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v2.rst index bd352ee6179..0b944bf3bf7 100644 --- a/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v2.rst +++ b/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v3.rst b/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v3.rst index 513558ad5e9..3f0ca34dd28 100644 --- a/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v3.rst +++ b/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v3.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToDistribution-v1.rst b/docs/source/algorithms/ConvertToDistribution-v1.rst index d753ba8c5d5..d1660ddaf72 100644 --- a/docs/source/algorithms/ConvertToDistribution-v1.rst +++ b/docs/source/algorithms/ConvertToDistribution-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToEventWorkspace-v1.rst b/docs/source/algorithms/ConvertToEventWorkspace-v1.rst index 15217a14e9c..b5ed0670cba 100644 --- a/docs/source/algorithms/ConvertToEventWorkspace-v1.rst +++ b/docs/source/algorithms/ConvertToEventWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToHistogram-v1.rst b/docs/source/algorithms/ConvertToHistogram-v1.rst index ba86710722e..a3a26052713 100644 --- a/docs/source/algorithms/ConvertToHistogram-v1.rst +++ b/docs/source/algorithms/ConvertToHistogram-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToMD-v1.rst b/docs/source/algorithms/ConvertToMD-v1.rst index e8223026825..35b37c45c04 100644 --- a/docs/source/algorithms/ConvertToMD-v1.rst +++ b/docs/source/algorithms/ConvertToMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToMDMinMaxGlobal-v1.rst b/docs/source/algorithms/ConvertToMDMinMaxGlobal-v1.rst index 974b11cc4ef..cbb9f6ad663 100644 --- a/docs/source/algorithms/ConvertToMDMinMaxGlobal-v1.rst +++ b/docs/source/algorithms/ConvertToMDMinMaxGlobal-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToMDMinMaxLocal-v1.rst b/docs/source/algorithms/ConvertToMDMinMaxLocal-v1.rst index 8974a0e5da4..66bf54e4e01 100644 --- a/docs/source/algorithms/ConvertToMDMinMaxLocal-v1.rst +++ b/docs/source/algorithms/ConvertToMDMinMaxLocal-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToMatrixWorkspace-v1.rst b/docs/source/algorithms/ConvertToMatrixWorkspace-v1.rst index 3aecaa2f8d8..a95ed0e480b 100644 --- a/docs/source/algorithms/ConvertToMatrixWorkspace-v1.rst +++ b/docs/source/algorithms/ConvertToMatrixWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToPointData-v1.rst b/docs/source/algorithms/ConvertToPointData-v1.rst index 2eff633e845..b9811d6ab5e 100644 --- a/docs/source/algorithms/ConvertToPointData-v1.rst +++ b/docs/source/algorithms/ConvertToPointData-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToReflectometryQ-v1.rst b/docs/source/algorithms/ConvertToReflectometryQ-v1.rst index f97a14c5583..a006f9bdc7c 100644 --- a/docs/source/algorithms/ConvertToReflectometryQ-v1.rst +++ b/docs/source/algorithms/ConvertToReflectometryQ-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertToYSpace-v1.rst b/docs/source/algorithms/ConvertToYSpace-v1.rst index b1cc08cc506..42981b13a1b 100644 --- a/docs/source/algorithms/ConvertToYSpace-v1.rst +++ b/docs/source/algorithms/ConvertToYSpace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertUnits-v1.rst b/docs/source/algorithms/ConvertUnits-v1.rst index c755f197ba7..1e37613ff86 100644 --- a/docs/source/algorithms/ConvertUnits-v1.rst +++ b/docs/source/algorithms/ConvertUnits-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvertUnitsUsingDetectorTable-v1.rst b/docs/source/algorithms/ConvertUnitsUsingDetectorTable-v1.rst index fc6e37b0c53..c1c2d5f3523 100644 --- a/docs/source/algorithms/ConvertUnitsUsingDetectorTable-v1.rst +++ b/docs/source/algorithms/ConvertUnitsUsingDetectorTable-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvolutionFitSequential-v1.rst b/docs/source/algorithms/ConvolutionFitSequential-v1.rst index df1d4afc731..92b2d66d6e9 100644 --- a/docs/source/algorithms/ConvolutionFitSequential-v1.rst +++ b/docs/source/algorithms/ConvolutionFitSequential-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ConvolveWorkspaces-v1.rst b/docs/source/algorithms/ConvolveWorkspaces-v1.rst index fd67dcf082c..2ead5bc0463 100644 --- a/docs/source/algorithms/ConvolveWorkspaces-v1.rst +++ b/docs/source/algorithms/ConvolveWorkspaces-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CopyDetectorMapping-v1.rst b/docs/source/algorithms/CopyDetectorMapping-v1.rst index d03fe81b083..f8b034681c9 100644 --- a/docs/source/algorithms/CopyDetectorMapping-v1.rst +++ b/docs/source/algorithms/CopyDetectorMapping-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CopyInstrumentParameters-v1.rst b/docs/source/algorithms/CopyInstrumentParameters-v1.rst index 434ea4a7f72..678de4f6968 100644 --- a/docs/source/algorithms/CopyInstrumentParameters-v1.rst +++ b/docs/source/algorithms/CopyInstrumentParameters-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CopyLogs-v1.rst b/docs/source/algorithms/CopyLogs-v1.rst index a9cb195add6..a003eee7564 100644 --- a/docs/source/algorithms/CopyLogs-v1.rst +++ b/docs/source/algorithms/CopyLogs-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CopySample-v1.rst b/docs/source/algorithms/CopySample-v1.rst index b86987f43c5..dd7c0c87dcd 100644 --- a/docs/source/algorithms/CopySample-v1.rst +++ b/docs/source/algorithms/CopySample-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CorelliCrossCorrelate-v1.rst b/docs/source/algorithms/CorelliCrossCorrelate-v1.rst index daec61b3836..0f4905988f9 100644 --- a/docs/source/algorithms/CorelliCrossCorrelate-v1.rst +++ b/docs/source/algorithms/CorelliCrossCorrelate-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CorrectKiKf-v1.rst b/docs/source/algorithms/CorrectKiKf-v1.rst index ec0daa197c7..77c39bb6e76 100644 --- a/docs/source/algorithms/CorrectKiKf-v1.rst +++ b/docs/source/algorithms/CorrectKiKf-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CorrectLogTimes-v1.rst b/docs/source/algorithms/CorrectLogTimes-v1.rst index 12bb2c85c6c..f460a676355 100644 --- a/docs/source/algorithms/CorrectLogTimes-v1.rst +++ b/docs/source/algorithms/CorrectLogTimes-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CorrectTOF-v1.rst b/docs/source/algorithms/CorrectTOF-v1.rst index 9fe776bc90b..16eb68c6f1a 100644 --- a/docs/source/algorithms/CorrectTOF-v1.rst +++ b/docs/source/algorithms/CorrectTOF-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CorrectTOFAxis-v1.rst b/docs/source/algorithms/CorrectTOFAxis-v1.rst index edebd7f668b..92464f500e6 100644 --- a/docs/source/algorithms/CorrectTOFAxis-v1.rst +++ b/docs/source/algorithms/CorrectTOFAxis-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CorrectToFile-v1.rst b/docs/source/algorithms/CorrectToFile-v1.rst index 08d0ec0525b..75b1473c888 100644 --- a/docs/source/algorithms/CorrectToFile-v1.rst +++ b/docs/source/algorithms/CorrectToFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CountReflections-v1.rst b/docs/source/algorithms/CountReflections-v1.rst index 5d404ab75c4..764b1c8fa26 100644 --- a/docs/source/algorithms/CountReflections-v1.rst +++ b/docs/source/algorithms/CountReflections-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateCacheFilename-v1.rst b/docs/source/algorithms/CreateCacheFilename-v1.rst index 4f292a71066..c27b7b290bc 100644 --- a/docs/source/algorithms/CreateCacheFilename-v1.rst +++ b/docs/source/algorithms/CreateCacheFilename-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateCalFileByNames-v1.rst b/docs/source/algorithms/CreateCalFileByNames-v1.rst index 35952daf80f..d1dce35d1bd 100644 --- a/docs/source/algorithms/CreateCalFileByNames-v1.rst +++ b/docs/source/algorithms/CreateCalFileByNames-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateChopperModel-v1.rst b/docs/source/algorithms/CreateChopperModel-v1.rst index 0494f9b68c4..441734571ed 100644 --- a/docs/source/algorithms/CreateChopperModel-v1.rst +++ b/docs/source/algorithms/CreateChopperModel-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateChunkingFromInstrument-v1.rst b/docs/source/algorithms/CreateChunkingFromInstrument-v1.rst index 3486c253d89..d457ce06b8c 100644 --- a/docs/source/algorithms/CreateChunkingFromInstrument-v1.rst +++ b/docs/source/algorithms/CreateChunkingFromInstrument-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateDummyCalFile-v1.rst b/docs/source/algorithms/CreateDummyCalFile-v1.rst index 385ce99d981..9f9f592fde7 100644 --- a/docs/source/algorithms/CreateDummyCalFile-v1.rst +++ b/docs/source/algorithms/CreateDummyCalFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateEPP-v1.rst b/docs/source/algorithms/CreateEPP-v1.rst index 43a4b5f9bb2..c450dbf8c90 100644 --- a/docs/source/algorithms/CreateEPP-v1.rst +++ b/docs/source/algorithms/CreateEPP-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateEmptyTableWorkspace-v1.rst b/docs/source/algorithms/CreateEmptyTableWorkspace-v1.rst index 73e10d17ab6..1f04900be24 100644 --- a/docs/source/algorithms/CreateEmptyTableWorkspace-v1.rst +++ b/docs/source/algorithms/CreateEmptyTableWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateFlatEventWorkspace-v1.rst b/docs/source/algorithms/CreateFlatEventWorkspace-v1.rst index 6dc23cbb88b..b2802e224aa 100644 --- a/docs/source/algorithms/CreateFlatEventWorkspace-v1.rst +++ b/docs/source/algorithms/CreateFlatEventWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateGroupingWorkspace-v1.rst b/docs/source/algorithms/CreateGroupingWorkspace-v1.rst index c472673786b..b8926c91a7a 100644 --- a/docs/source/algorithms/CreateGroupingWorkspace-v1.rst +++ b/docs/source/algorithms/CreateGroupingWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateLeBailFitInput-v1.rst b/docs/source/algorithms/CreateLeBailFitInput-v1.rst index c39b0896524..e9c4749f8a6 100644 --- a/docs/source/algorithms/CreateLeBailFitInput-v1.rst +++ b/docs/source/algorithms/CreateLeBailFitInput-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateLogPropertyTable-v1.rst b/docs/source/algorithms/CreateLogPropertyTable-v1.rst index ec6bb4ceac7..6cddc1a741b 100644 --- a/docs/source/algorithms/CreateLogPropertyTable-v1.rst +++ b/docs/source/algorithms/CreateLogPropertyTable-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateLogTimeCorrection-v1.rst b/docs/source/algorithms/CreateLogTimeCorrection-v1.rst index 1208abebe3d..dffd463ccc5 100644 --- a/docs/source/algorithms/CreateLogTimeCorrection-v1.rst +++ b/docs/source/algorithms/CreateLogTimeCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateMD-v1.rst b/docs/source/algorithms/CreateMD-v1.rst index c995b084e3d..826181d4ad5 100644 --- a/docs/source/algorithms/CreateMD-v1.rst +++ b/docs/source/algorithms/CreateMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateMDHistoWorkspace-v1.rst b/docs/source/algorithms/CreateMDHistoWorkspace-v1.rst index f7d5b533368..1fb31629c1a 100644 --- a/docs/source/algorithms/CreateMDHistoWorkspace-v1.rst +++ b/docs/source/algorithms/CreateMDHistoWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateMDWorkspace-v1.rst b/docs/source/algorithms/CreateMDWorkspace-v1.rst index 01682818c68..c39280179d6 100644 --- a/docs/source/algorithms/CreateMDWorkspace-v1.rst +++ b/docs/source/algorithms/CreateMDWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateModeratorModel-v1.rst b/docs/source/algorithms/CreateModeratorModel-v1.rst index b6419df33d8..e5aef2c96b8 100644 --- a/docs/source/algorithms/CreateModeratorModel-v1.rst +++ b/docs/source/algorithms/CreateModeratorModel-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreatePSDBleedMask-v1.rst b/docs/source/algorithms/CreatePSDBleedMask-v1.rst index 632ba9484bd..9b680d7c3c0 100644 --- a/docs/source/algorithms/CreatePSDBleedMask-v1.rst +++ b/docs/source/algorithms/CreatePSDBleedMask-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreatePeaksWorkspace-v1.rst b/docs/source/algorithms/CreatePeaksWorkspace-v1.rst index 7538196ffaf..573908fc554 100644 --- a/docs/source/algorithms/CreatePeaksWorkspace-v1.rst +++ b/docs/source/algorithms/CreatePeaksWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateSampleShape-v1.rst b/docs/source/algorithms/CreateSampleShape-v1.rst index e5ba9aff3f6..d4de5dbd5bf 100644 --- a/docs/source/algorithms/CreateSampleShape-v1.rst +++ b/docs/source/algorithms/CreateSampleShape-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateSampleWorkspace-v1.rst b/docs/source/algorithms/CreateSampleWorkspace-v1.rst index 3a1433919d7..088a661ce73 100644 --- a/docs/source/algorithms/CreateSampleWorkspace-v1.rst +++ b/docs/source/algorithms/CreateSampleWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -37,7 +37,7 @@ important set Random to false or uncheck the box. values should be set to a range symmetrical around x=0. Instrument -~~~~~~~~~~ +########## The instrument created by CreateSample workspace is very simple and looks like this. diff --git a/docs/source/algorithms/CreateSimulationWorkspace-v1.rst b/docs/source/algorithms/CreateSimulationWorkspace-v1.rst index 2f3bb5ede9a..3d072e28840 100644 --- a/docs/source/algorithms/CreateSimulationWorkspace-v1.rst +++ b/docs/source/algorithms/CreateSimulationWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateSingleValuedWorkspace-v1.rst b/docs/source/algorithms/CreateSingleValuedWorkspace-v1.rst index cdab8c58d71..a45cae2192a 100644 --- a/docs/source/algorithms/CreateSingleValuedWorkspace-v1.rst +++ b/docs/source/algorithms/CreateSingleValuedWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateTransmissionWorkspace-v1.rst b/docs/source/algorithms/CreateTransmissionWorkspace-v1.rst index d4a051e9964..fc581c9a254 100644 --- a/docs/source/algorithms/CreateTransmissionWorkspace-v1.rst +++ b/docs/source/algorithms/CreateTransmissionWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateTransmissionWorkspace-v2.rst b/docs/source/algorithms/CreateTransmissionWorkspace-v2.rst index 395469e382f..b4bc5f1ffcd 100644 --- a/docs/source/algorithms/CreateTransmissionWorkspace-v2.rst +++ b/docs/source/algorithms/CreateTransmissionWorkspace-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v1.rst b/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v1.rst index 57ac9a3c13c..f9e6e8527b4 100644 --- a/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v1.rst +++ b/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v2.rst b/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v2.rst index b599275fa98..7eee0bc60f8 100644 --- a/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v2.rst +++ b/docs/source/algorithms/CreateTransmissionWorkspaceAuto-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateUserDefinedBackground-v1.rst b/docs/source/algorithms/CreateUserDefinedBackground-v1.rst index 3e9ee3da127..3ad76d3d2f8 100644 --- a/docs/source/algorithms/CreateUserDefinedBackground-v1.rst +++ b/docs/source/algorithms/CreateUserDefinedBackground-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CreateWorkspace-v1.rst b/docs/source/algorithms/CreateWorkspace-v1.rst index 253adc45156..afdc4acb243 100644 --- a/docs/source/algorithms/CreateWorkspace-v1.rst +++ b/docs/source/algorithms/CreateWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -10,14 +10,15 @@ Description ----------- This algorithm constructs a :ref:`MatrixWorkspace <MatrixWorkspace>` -when passed a vector for each of the X, Y, and E data values. The unit -for the X Axis can optionally be specified as any of the units in the +when passed a vector for each of the X, Y and optionally E and Dx values. +The E values of the output workspace will be zero if not provided. +The unit for the X Axis can optionally be specified as any of the units in the Mantid `Unit Factory <http://www.mantidproject.org/Units>`__ (see `the list of units currently available <http://www.mantidproject.org/Units>`__). Multiple spectra may be created by supplying the NSpec Property (integer, default 1). When this is provided the vectors are split into equal-sized spectra (all -X, Y, E values must still be in a single vector for input). +X, Y, E, Dx values must still be in a single vector for input). When you use the input property ParentWorkspace, the new workspace is created with the same instrument (including its parameters), sample @@ -57,10 +58,17 @@ Usage dataX = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] dataY = [1,2,3,4,5,6,7,8,9,10,11,12] + + # The workspace will be named "dataWS1", error values will be zero. + dataWS1 = CreateWorkspace(DataX=dataX, DataY=dataY, NSpec=4, UnitX="Wavelength") + + # Create a workspace containing the following error values: dataE = [1,2,3,4,5,6,7,8,9,10,11,12] - - # The workspace will be named "dataWS" - dataWS = CreateWorkspace(DataX=dataX, DataY=dataY, DataE=dataE, NSpec=4,UnitX="Wavelength") + dataWS2 = CreateWorkspace(DataX=dataX, DataY=dataY, DataE=dataE, NSpec=4, UnitX="Wavelength") + + # Create a workspace containing Dx values: + dX = [1,2,3,4,5,6,7,8,9,10,11,12] + dataWS3 = CreateWorkspace(DataX=dataX, DataY=dataY, DataE=dataE, NSpec=4, UnitX="Wavelength", Dx=dX) .. categories:: diff --git a/docs/source/algorithms/CropToComponent-v1.rst b/docs/source/algorithms/CropToComponent-v1.rst index dd58e21b903..c4513c0e53e 100644 --- a/docs/source/algorithms/CropToComponent-v1.rst +++ b/docs/source/algorithms/CropToComponent-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CropWorkspace-v1.rst b/docs/source/algorithms/CropWorkspace-v1.rst index 7723bed4a49..e99c9817356 100644 --- a/docs/source/algorithms/CropWorkspace-v1.rst +++ b/docs/source/algorithms/CropWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CropWorkspaceRagged-v1.rst b/docs/source/algorithms/CropWorkspaceRagged-v1.rst index 85ce724eecd..f09113db9c8 100644 --- a/docs/source/algorithms/CropWorkspaceRagged-v1.rst +++ b/docs/source/algorithms/CropWorkspaceRagged-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CrossCorrelate-v1.rst b/docs/source/algorithms/CrossCorrelate-v1.rst index cfd7452b8dc..870f9b7398f 100644 --- a/docs/source/algorithms/CrossCorrelate-v1.rst +++ b/docs/source/algorithms/CrossCorrelate-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CrystalFieldEnergies-v1.rst b/docs/source/algorithms/CrystalFieldEnergies-v1.rst index cf102a0f030..90d81130f60 100644 --- a/docs/source/algorithms/CrystalFieldEnergies-v1.rst +++ b/docs/source/algorithms/CrystalFieldEnergies-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CuboidGaugeVolumeAbsorption-v1.rst b/docs/source/algorithms/CuboidGaugeVolumeAbsorption-v1.rst index 8b5b2668373..3bf69ee0e9b 100644 --- a/docs/source/algorithms/CuboidGaugeVolumeAbsorption-v1.rst +++ b/docs/source/algorithms/CuboidGaugeVolumeAbsorption-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CutMD-v1.rst b/docs/source/algorithms/CutMD-v1.rst index 7c77511cbc1..ee98fac154f 100644 --- a/docs/source/algorithms/CutMD-v1.rst +++ b/docs/source/algorithms/CutMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -22,19 +22,19 @@ is that the same number of output workspaces are also given so that CutMD knows what to call each output workspace created. MDEventWorkspaces -~~~~~~~~~~~~~~~~~~~ +################# For input of type :ref:`MDEventWorkspace <MDWorkspace>` the algorithm uses :ref:`algm-BinMD` or :ref:`algm-SliceMD` to achieve the binning of the data. The choice of child algorithm used for slicing in this case is controlled by the NoPix option. MDHistoWorkspaces -~~~~~~~~~~~~~~~~~~~ +################# If the input is an :ref:`MDHistoWorkspace <MDHistoWorkspace>` :ref:`algm-BinMD` and :ref:`algm-SliceMD` are not made available as they needto get hold of the original MDEvents associated with an :ref:`MDEventWorkspace <MDWorkspace>` in order to perform the rebinning. As this information is missing from the MDHistoWorkspace images, those operations are forbidden. Instead, a limited subset of the operations are allowed, and are performed via :ref:`algm-IntegrateMDHistoWorkspace`. In this case, the Projection and NoPix properties are ignored. See :ref:`algm-IntegrateMDHistoWorkspace` for how the binning parameters are used. Projection Binning -~~~~~~~~~~~~~~~~~~ +################## The 'PnBin' property, where n is between 1 and 5, is used to specify the binning for the nth dimension of the output workspace. The dimension will be truncated to have extents 'minimum' and 'maximum', with 'stepsize' specifying the size of the bins inbetween. @@ -64,7 +64,7 @@ For ease of use, when using the python interface only, the 'PBins' keyword can b PBins accepts a tuple, or list, of PnBins parameters. The position in the list determines the dimension it corresponds to. See the Usage_ examples below. Creating Projections -~~~~~~~~~~~~~~~~~~~~ +#################### Projections are used by CutMD to transform the multidimensional data prior to cutting it. Projections are provided to CutMD in the form of a :ref:`TableWorkspace <Table Workspaces>`. @@ -124,7 +124,7 @@ call the created workspace: CutMD(..., Projection=proj.createWorkspace(), ...) Workflow -~~~~~~~~ +######## .. diagram:: CutMD-v1_wkflw.dot diff --git a/docs/source/algorithms/CylinderAbsorption-v1.rst b/docs/source/algorithms/CylinderAbsorption-v1.rst index 8de3994299d..a45bd481bab 100644 --- a/docs/source/algorithms/CylinderAbsorption-v1.rst +++ b/docs/source/algorithms/CylinderAbsorption-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/CylinderPaalmanPingsCorrection-v2.rst b/docs/source/algorithms/CylinderPaalmanPingsCorrection-v2.rst index fdc45aeb0b0..f800ad52d14 100644 --- a/docs/source/algorithms/CylinderPaalmanPingsCorrection-v2.rst +++ b/docs/source/algorithms/CylinderPaalmanPingsCorrection-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DNSComputeDetEffCorrCoefs-v1.rst b/docs/source/algorithms/DNSComputeDetEffCorrCoefs-v1.rst index 70c207d35af..5d3dd875ebd 100644 --- a/docs/source/algorithms/DNSComputeDetEffCorrCoefs-v1.rst +++ b/docs/source/algorithms/DNSComputeDetEffCorrCoefs-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DNSFlippingRatioCorr-v1.rst b/docs/source/algorithms/DNSFlippingRatioCorr-v1.rst index 438f785749e..612a739a34c 100644 --- a/docs/source/algorithms/DNSFlippingRatioCorr-v1.rst +++ b/docs/source/algorithms/DNSFlippingRatioCorr-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DNSMergeRuns-v1.rst b/docs/source/algorithms/DNSMergeRuns-v1.rst index 5221c1f2fea..98aa84115fb 100644 --- a/docs/source/algorithms/DNSMergeRuns-v1.rst +++ b/docs/source/algorithms/DNSMergeRuns-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DPDFreduction-v1.rst b/docs/source/algorithms/DPDFreduction-v1.rst index 2c7841286a7..9785ef62655 100644 --- a/docs/source/algorithms/DPDFreduction-v1.rst +++ b/docs/source/algorithms/DPDFreduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DSFinterp-v1.rst b/docs/source/algorithms/DSFinterp-v1.rst index e91143ecbb9..cb029a2f452 100644 --- a/docs/source/algorithms/DSFinterp-v1.rst +++ b/docs/source/algorithms/DSFinterp-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DakotaChiSquared-v1.rst b/docs/source/algorithms/DakotaChiSquared-v1.rst index dd934df4d38..633f76d8ea0 100644 --- a/docs/source/algorithms/DakotaChiSquared-v1.rst +++ b/docs/source/algorithms/DakotaChiSquared-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DefineGaugeVolume-v1.rst b/docs/source/algorithms/DefineGaugeVolume-v1.rst index f3ed5b24a46..ac27a86068b 100644 --- a/docs/source/algorithms/DefineGaugeVolume-v1.rst +++ b/docs/source/algorithms/DefineGaugeVolume-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DeleteLog-v1.rst b/docs/source/algorithms/DeleteLog-v1.rst index 6b5a99beb9b..2809ddcab41 100644 --- a/docs/source/algorithms/DeleteLog-v1.rst +++ b/docs/source/algorithms/DeleteLog-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DeleteTableRows-v1.rst b/docs/source/algorithms/DeleteTableRows-v1.rst index bf2abca08f4..0bd251222d4 100644 --- a/docs/source/algorithms/DeleteTableRows-v1.rst +++ b/docs/source/algorithms/DeleteTableRows-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DeleteWorkspace-v1.rst b/docs/source/algorithms/DeleteWorkspace-v1.rst index 4f9263dc226..5c041cde4e1 100644 --- a/docs/source/algorithms/DeleteWorkspace-v1.rst +++ b/docs/source/algorithms/DeleteWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DeleteWorkspaces-v1.rst b/docs/source/algorithms/DeleteWorkspaces-v1.rst index e7284d9ffee..0c51ae0d55c 100644 --- a/docs/source/algorithms/DeleteWorkspaces-v1.rst +++ b/docs/source/algorithms/DeleteWorkspaces-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DeltaPDF3D-v1.rst b/docs/source/algorithms/DeltaPDF3D-v1.rst index bf8f9572f97..8469c064d83 100644 --- a/docs/source/algorithms/DeltaPDF3D-v1.rst +++ b/docs/source/algorithms/DeltaPDF3D-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DetectorDiagnostic-v1.rst b/docs/source/algorithms/DetectorDiagnostic-v1.rst index 9404c8d50f1..ac630bf0fcd 100644 --- a/docs/source/algorithms/DetectorDiagnostic-v1.rst +++ b/docs/source/algorithms/DetectorDiagnostic-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DetectorEfficiencyCor-v1.rst b/docs/source/algorithms/DetectorEfficiencyCor-v1.rst index 6fb7716cad4..339a831e674 100644 --- a/docs/source/algorithms/DetectorEfficiencyCor-v1.rst +++ b/docs/source/algorithms/DetectorEfficiencyCor-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DetectorEfficiencyCorUser-v1.rst b/docs/source/algorithms/DetectorEfficiencyCorUser-v1.rst index 4f35ff53463..2039b8cb1f1 100644 --- a/docs/source/algorithms/DetectorEfficiencyCorUser-v1.rst +++ b/docs/source/algorithms/DetectorEfficiencyCorUser-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DetectorEfficiencyVariation-v1.rst b/docs/source/algorithms/DetectorEfficiencyVariation-v1.rst index e6ba5d1f111..8a21005e672 100644 --- a/docs/source/algorithms/DetectorEfficiencyVariation-v1.rst +++ b/docs/source/algorithms/DetectorEfficiencyVariation-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DetectorFloodWeighting-v1.rst b/docs/source/algorithms/DetectorFloodWeighting-v1.rst index 062a0fa6332..35f13ab8f53 100644 --- a/docs/source/algorithms/DetectorFloodWeighting-v1.rst +++ b/docs/source/algorithms/DetectorFloodWeighting-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DetermineChunking-v1.rst b/docs/source/algorithms/DetermineChunking-v1.rst index b7b5c49d77d..adc7319c2c7 100644 --- a/docs/source/algorithms/DetermineChunking-v1.rst +++ b/docs/source/algorithms/DetermineChunking-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst b/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst index cf8ade09d03..1b11f02914b 100644 --- a/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst +++ b/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DgsConvertToEnergyTransfer-v1.rst b/docs/source/algorithms/DgsConvertToEnergyTransfer-v1.rst index 7d319df7841..392c82d4ac4 100644 --- a/docs/source/algorithms/DgsConvertToEnergyTransfer-v1.rst +++ b/docs/source/algorithms/DgsConvertToEnergyTransfer-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DgsDiagnose-v1.rst b/docs/source/algorithms/DgsDiagnose-v1.rst index 027400ea8ce..e5670303700 100644 --- a/docs/source/algorithms/DgsDiagnose-v1.rst +++ b/docs/source/algorithms/DgsDiagnose-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DgsPreprocessData-v1.rst b/docs/source/algorithms/DgsPreprocessData-v1.rst index 8a6bafdf208..5a8946e19eb 100644 --- a/docs/source/algorithms/DgsPreprocessData-v1.rst +++ b/docs/source/algorithms/DgsPreprocessData-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DgsProcessDetectorVanadium-v1.rst b/docs/source/algorithms/DgsProcessDetectorVanadium-v1.rst index 54312538606..d64d655e8f4 100644 --- a/docs/source/algorithms/DgsProcessDetectorVanadium-v1.rst +++ b/docs/source/algorithms/DgsProcessDetectorVanadium-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DgsReduction-v1.rst b/docs/source/algorithms/DgsReduction-v1.rst index 0c4d1378c9e..bb33cb66ae5 100644 --- a/docs/source/algorithms/DgsReduction-v1.rst +++ b/docs/source/algorithms/DgsReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DgsRemap-v1.rst b/docs/source/algorithms/DgsRemap-v1.rst index de6578e7a54..aab6dcabeef 100644 --- a/docs/source/algorithms/DgsRemap-v1.rst +++ b/docs/source/algorithms/DgsRemap-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DiffPeaksWorkspaces-v1.rst b/docs/source/algorithms/DiffPeaksWorkspaces-v1.rst index 38eb213b99c..2e32649c61c 100644 --- a/docs/source/algorithms/DiffPeaksWorkspaces-v1.rst +++ b/docs/source/algorithms/DiffPeaksWorkspaces-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DiffractionEventCalibrateDetectors-v1.rst b/docs/source/algorithms/DiffractionEventCalibrateDetectors-v1.rst index 2d780d5c823..a4b5d68e31b 100644 --- a/docs/source/algorithms/DiffractionEventCalibrateDetectors-v1.rst +++ b/docs/source/algorithms/DiffractionEventCalibrateDetectors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DiffractionFocussing-v1.rst b/docs/source/algorithms/DiffractionFocussing-v1.rst index 8f5b311be9a..f828f72e7db 100644 --- a/docs/source/algorithms/DiffractionFocussing-v1.rst +++ b/docs/source/algorithms/DiffractionFocussing-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DiffractionFocussing-v2.rst b/docs/source/algorithms/DiffractionFocussing-v2.rst index 70b7718cc59..52509fe6841 100644 --- a/docs/source/algorithms/DiffractionFocussing-v2.rst +++ b/docs/source/algorithms/DiffractionFocussing-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DirectILLApplySelfShielding-v1.rst b/docs/source/algorithms/DirectILLApplySelfShielding-v1.rst index 2db0d942e6f..99879060a62 100644 --- a/docs/source/algorithms/DirectILLApplySelfShielding-v1.rst +++ b/docs/source/algorithms/DirectILLApplySelfShielding-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DirectILLCollectData-v1.rst b/docs/source/algorithms/DirectILLCollectData-v1.rst index 1f5df795ea8..a50c673a5f6 100644 --- a/docs/source/algorithms/DirectILLCollectData-v1.rst +++ b/docs/source/algorithms/DirectILLCollectData-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DirectILLDiagnostics-v1.rst b/docs/source/algorithms/DirectILLDiagnostics-v1.rst index 8201ca8e4d2..116a1cbd1c0 100644 --- a/docs/source/algorithms/DirectILLDiagnostics-v1.rst +++ b/docs/source/algorithms/DirectILLDiagnostics-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DirectILLIntegrateVanadium-v1.rst b/docs/source/algorithms/DirectILLIntegrateVanadium-v1.rst index b96cba3937d..e5b620a4f35 100644 --- a/docs/source/algorithms/DirectILLIntegrateVanadium-v1.rst +++ b/docs/source/algorithms/DirectILLIntegrateVanadium-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DirectILLReduction-v1.rst b/docs/source/algorithms/DirectILLReduction-v1.rst index f43b36417cd..41ac4fad906 100644 --- a/docs/source/algorithms/DirectILLReduction-v1.rst +++ b/docs/source/algorithms/DirectILLReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DirectILLSelfShielding-v1.rst b/docs/source/algorithms/DirectILLSelfShielding-v1.rst index 6fe5566b416..c6461fd8364 100644 --- a/docs/source/algorithms/DirectILLSelfShielding-v1.rst +++ b/docs/source/algorithms/DirectILLSelfShielding-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Divide-v1.rst b/docs/source/algorithms/Divide-v1.rst index 1a4cc089430..02147daae8f 100644 --- a/docs/source/algorithms/Divide-v1.rst +++ b/docs/source/algorithms/Divide-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DivideMD-v1.rst b/docs/source/algorithms/DivideMD-v1.rst index 258ee5dc796..96f92643882 100644 --- a/docs/source/algorithms/DivideMD-v1.rst +++ b/docs/source/algorithms/DivideMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DownloadFile-v1.rst b/docs/source/algorithms/DownloadFile-v1.rst index 85d30aae197..cdb152d6862 100644 --- a/docs/source/algorithms/DownloadFile-v1.rst +++ b/docs/source/algorithms/DownloadFile-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DownloadInstrument-v1.rst b/docs/source/algorithms/DownloadInstrument-v1.rst index 979d7d67152..198d5a3d486 100644 --- a/docs/source/algorithms/DownloadInstrument-v1.rst +++ b/docs/source/algorithms/DownloadInstrument-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DownloadRemoteFile-v1.rst b/docs/source/algorithms/DownloadRemoteFile-v1.rst index baafb5ea5c9..5ad4690b169 100644 --- a/docs/source/algorithms/DownloadRemoteFile-v1.rst +++ b/docs/source/algorithms/DownloadRemoteFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/DownloadRemoteFile-v2.rst b/docs/source/algorithms/DownloadRemoteFile-v2.rst index 11687fb4cf8..12dede5c008 100644 --- a/docs/source/algorithms/DownloadRemoteFile-v2.rst +++ b/docs/source/algorithms/DownloadRemoteFile-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EQSANSAzimuthalAverage1D-v1.rst b/docs/source/algorithms/EQSANSAzimuthalAverage1D-v1.rst index e6f083dbe8d..f83a4eeea4e 100644 --- a/docs/source/algorithms/EQSANSAzimuthalAverage1D-v1.rst +++ b/docs/source/algorithms/EQSANSAzimuthalAverage1D-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v1.rst b/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v1.rst index 4e7f412815c..e371b8e32b3 100644 --- a/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v1.rst +++ b/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v2.rst b/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v2.rst index 2be799e69f6..9a4c6b31f2f 100644 --- a/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v2.rst +++ b/docs/source/algorithms/EQSANSDarkCurrentSubtraction-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EQSANSDirectBeamTransmission-v1.rst b/docs/source/algorithms/EQSANSDirectBeamTransmission-v1.rst index 21cbc6fb083..7400110992a 100644 --- a/docs/source/algorithms/EQSANSDirectBeamTransmission-v1.rst +++ b/docs/source/algorithms/EQSANSDirectBeamTransmission-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EQSANSLoad-v1.rst b/docs/source/algorithms/EQSANSLoad-v1.rst index 755d3e89472..545dac3422e 100644 --- a/docs/source/algorithms/EQSANSLoad-v1.rst +++ b/docs/source/algorithms/EQSANSLoad-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EQSANSMonitorTOF-v1.rst b/docs/source/algorithms/EQSANSMonitorTOF-v1.rst index 3c87c117223..8c1cdcc1f0c 100644 --- a/docs/source/algorithms/EQSANSMonitorTOF-v1.rst +++ b/docs/source/algorithms/EQSANSMonitorTOF-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EQSANSNormalise-v1.rst b/docs/source/algorithms/EQSANSNormalise-v1.rst index 698fd88ac8a..b54294e0ecd 100644 --- a/docs/source/algorithms/EQSANSNormalise-v1.rst +++ b/docs/source/algorithms/EQSANSNormalise-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EQSANSPatchSensitivity-v1.rst b/docs/source/algorithms/EQSANSPatchSensitivity-v1.rst index b33bf402a50..fbcf407733c 100644 --- a/docs/source/algorithms/EQSANSPatchSensitivity-v1.rst +++ b/docs/source/algorithms/EQSANSPatchSensitivity-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EQSANSQ2D-v1.rst b/docs/source/algorithms/EQSANSQ2D-v1.rst index ce876f73c03..5c90e3e9ecc 100644 --- a/docs/source/algorithms/EQSANSQ2D-v1.rst +++ b/docs/source/algorithms/EQSANSQ2D-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EQSANSResolution-v1.rst b/docs/source/algorithms/EQSANSResolution-v1.rst index 2bdcc43d8cd..8fa588e49a0 100644 --- a/docs/source/algorithms/EQSANSResolution-v1.rst +++ b/docs/source/algorithms/EQSANSResolution-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EQSANSTofStructure-v1.rst b/docs/source/algorithms/EQSANSTofStructure-v1.rst index 1316f72372d..5e7db7dcb46 100644 --- a/docs/source/algorithms/EQSANSTofStructure-v1.rst +++ b/docs/source/algorithms/EQSANSTofStructure-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EditInstrumentGeometry-v1.rst b/docs/source/algorithms/EditInstrumentGeometry-v1.rst index 5526e52a640..8773eb259d3 100644 --- a/docs/source/algorithms/EditInstrumentGeometry-v1.rst +++ b/docs/source/algorithms/EditInstrumentGeometry-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ElasticWindow-v1.rst b/docs/source/algorithms/ElasticWindow-v1.rst index 636cfe3af37..ca1f05c38ac 100644 --- a/docs/source/algorithms/ElasticWindow-v1.rst +++ b/docs/source/algorithms/ElasticWindow-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ElasticWindowMultiple-v1.rst b/docs/source/algorithms/ElasticWindowMultiple-v1.rst index a953d30b052..bbfbc8f62fc 100644 --- a/docs/source/algorithms/ElasticWindowMultiple-v1.rst +++ b/docs/source/algorithms/ElasticWindowMultiple-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EnergyWindowScan-v1.rst b/docs/source/algorithms/EnergyWindowScan-v1.rst index 71f91e40b69..c21ce61a4f4 100644 --- a/docs/source/algorithms/EnergyWindowScan-v1.rst +++ b/docs/source/algorithms/EnergyWindowScan-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EnggCalibrate-v1.rst b/docs/source/algorithms/EnggCalibrate-v1.rst index 0375eb44e53..0327a8c1d60 100644 --- a/docs/source/algorithms/EnggCalibrate-v1.rst +++ b/docs/source/algorithms/EnggCalibrate-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EnggCalibrateFull-v1.rst b/docs/source/algorithms/EnggCalibrateFull-v1.rst index 5cac4656139..ee01751308a 100644 --- a/docs/source/algorithms/EnggCalibrateFull-v1.rst +++ b/docs/source/algorithms/EnggCalibrateFull-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EnggFitDIFCFromPeaks-v1.rst b/docs/source/algorithms/EnggFitDIFCFromPeaks-v1.rst index 7a3f1c2a8f3..0faff5d7519 100644 --- a/docs/source/algorithms/EnggFitDIFCFromPeaks-v1.rst +++ b/docs/source/algorithms/EnggFitDIFCFromPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EnggFitPeaks-v1.rst b/docs/source/algorithms/EnggFitPeaks-v1.rst index 011bc6802ce..b94994f858a 100644 --- a/docs/source/algorithms/EnggFitPeaks-v1.rst +++ b/docs/source/algorithms/EnggFitPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EnggFocus-v1.rst b/docs/source/algorithms/EnggFocus-v1.rst index 12f2f1dd120..6883341f7be 100644 --- a/docs/source/algorithms/EnggFocus-v1.rst +++ b/docs/source/algorithms/EnggFocus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EnggVanadiumCorrections-v1.rst b/docs/source/algorithms/EnggVanadiumCorrections-v1.rst index f980ed5fb93..d1eae623244 100644 --- a/docs/source/algorithms/EnggVanadiumCorrections-v1.rst +++ b/docs/source/algorithms/EnggVanadiumCorrections-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EqualToMD-v1.rst b/docs/source/algorithms/EqualToMD-v1.rst index 847c6031f09..1a59830e967 100644 --- a/docs/source/algorithms/EqualToMD-v1.rst +++ b/docs/source/algorithms/EqualToMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EstimateDivergence-v1.rst b/docs/source/algorithms/EstimateDivergence-v1.rst index c7da0629930..7d370fec154 100644 --- a/docs/source/algorithms/EstimateDivergence-v1.rst +++ b/docs/source/algorithms/EstimateDivergence-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EstimateFitParameters-v1.rst b/docs/source/algorithms/EstimateFitParameters-v1.rst index 0d5f6b186e1..6a4c58ed6ec 100644 --- a/docs/source/algorithms/EstimateFitParameters-v1.rst +++ b/docs/source/algorithms/EstimateFitParameters-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EstimateMuonAsymmetryFromCounts-v1.rst b/docs/source/algorithms/EstimateMuonAsymmetryFromCounts-v1.rst index 7480c94af69..ce63f658d1e 100644 --- a/docs/source/algorithms/EstimateMuonAsymmetryFromCounts-v1.rst +++ b/docs/source/algorithms/EstimateMuonAsymmetryFromCounts-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EstimatePeakErrors-v1.rst b/docs/source/algorithms/EstimatePeakErrors-v1.rst index f4783163738..d8d424fca78 100644 --- a/docs/source/algorithms/EstimatePeakErrors-v1.rst +++ b/docs/source/algorithms/EstimatePeakErrors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst b/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst index e65e13f905c..ec5daa91322 100644 --- a/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst +++ b/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EvaluateFunction-v1.rst b/docs/source/algorithms/EvaluateFunction-v1.rst index 74ff2c7d9ca..41aa5710e36 100644 --- a/docs/source/algorithms/EvaluateFunction-v1.rst +++ b/docs/source/algorithms/EvaluateFunction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/EvaluateMDFunction-v1.rst b/docs/source/algorithms/EvaluateMDFunction-v1.rst index 91f8acc66df..0c0d2d28586 100644 --- a/docs/source/algorithms/EvaluateMDFunction-v1.rst +++ b/docs/source/algorithms/EvaluateMDFunction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExaminePowderDiffProfile-v1.rst b/docs/source/algorithms/ExaminePowderDiffProfile-v1.rst index 431f6369d1d..78612391ca1 100644 --- a/docs/source/algorithms/ExaminePowderDiffProfile-v1.rst +++ b/docs/source/algorithms/ExaminePowderDiffProfile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExampleSaveAscii-v1.rst b/docs/source/algorithms/ExampleSaveAscii-v1.rst index 6f061321b82..4236bf38c26 100644 --- a/docs/source/algorithms/ExampleSaveAscii-v1.rst +++ b/docs/source/algorithms/ExampleSaveAscii-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Exponential-v1.rst b/docs/source/algorithms/Exponential-v1.rst index a08913dde2c..46d725e7142 100644 --- a/docs/source/algorithms/Exponential-v1.rst +++ b/docs/source/algorithms/Exponential-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExponentialCorrection-v1.rst b/docs/source/algorithms/ExponentialCorrection-v1.rst index 369f24d942c..c060e683940 100644 --- a/docs/source/algorithms/ExponentialCorrection-v1.rst +++ b/docs/source/algorithms/ExponentialCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExponentialMD-v1.rst b/docs/source/algorithms/ExponentialMD-v1.rst index 2076609d36e..6207ef6a5ed 100644 --- a/docs/source/algorithms/ExponentialMD-v1.rst +++ b/docs/source/algorithms/ExponentialMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExportExperimentLog-v1.rst b/docs/source/algorithms/ExportExperimentLog-v1.rst index 25967655bf6..19be177823c 100644 --- a/docs/source/algorithms/ExportExperimentLog-v1.rst +++ b/docs/source/algorithms/ExportExperimentLog-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExportGeometry-v1.rst b/docs/source/algorithms/ExportGeometry-v1.rst index 53878c8d804..1318b1a7852 100644 --- a/docs/source/algorithms/ExportGeometry-v1.rst +++ b/docs/source/algorithms/ExportGeometry-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst b/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst index 51d77cd96ff..085c78f0e28 100644 --- a/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst +++ b/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -15,7 +15,7 @@ The header for the sample log csv file can also be created by this algorithm in a seperate *header* file. CSV File format -=============== +############### Sample logs are written to a csv file. A tab separates any two adjacent values. @@ -35,7 +35,7 @@ Here is the definition for the columns. *SampleLogNames* Header file -=========== +########### A sample log header file can be generated optionally. It contains theree lines described as below. @@ -46,7 +46,7 @@ It contains theree lines described as below. Usually it is the column names in the .csv file Time Zone -========= +######### The time stamps of sample logs are recorded as UTC time in SNS. Some users wants to see the exported sample log as the neutron facility's local time. diff --git a/docs/source/algorithms/ExportSpectraMask-v1.rst b/docs/source/algorithms/ExportSpectraMask-v1.rst index 92b65de4497..5bf6179e0cb 100644 --- a/docs/source/algorithms/ExportSpectraMask-v1.rst +++ b/docs/source/algorithms/ExportSpectraMask-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExportTimeSeriesLog-v1.rst b/docs/source/algorithms/ExportTimeSeriesLog-v1.rst index 3434bd092b5..139228477de 100644 --- a/docs/source/algorithms/ExportTimeSeriesLog-v1.rst +++ b/docs/source/algorithms/ExportTimeSeriesLog-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExtractFFTSpectrum-v1.rst b/docs/source/algorithms/ExtractFFTSpectrum-v1.rst index 7d75cd5a062..d87dd5f5888 100644 --- a/docs/source/algorithms/ExtractFFTSpectrum-v1.rst +++ b/docs/source/algorithms/ExtractFFTSpectrum-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExtractMask-v1.rst b/docs/source/algorithms/ExtractMask-v1.rst index 2a9dfa07dfa..78f5160f5b7 100644 --- a/docs/source/algorithms/ExtractMask-v1.rst +++ b/docs/source/algorithms/ExtractMask-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExtractMaskToTable-v1.rst b/docs/source/algorithms/ExtractMaskToTable-v1.rst index 35251f1b572..7dab0492890 100644 --- a/docs/source/algorithms/ExtractMaskToTable-v1.rst +++ b/docs/source/algorithms/ExtractMaskToTable-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExtractMonitorWorkspace-v1.rst b/docs/source/algorithms/ExtractMonitorWorkspace-v1.rst index 0185717cdff..626c243bbb2 100644 --- a/docs/source/algorithms/ExtractMonitorWorkspace-v1.rst +++ b/docs/source/algorithms/ExtractMonitorWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExtractMonitors-v1.rst b/docs/source/algorithms/ExtractMonitors-v1.rst index 6b758461ae9..d1c180bec8b 100644 --- a/docs/source/algorithms/ExtractMonitors-v1.rst +++ b/docs/source/algorithms/ExtractMonitors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExtractQENSMembers-v1.rst b/docs/source/algorithms/ExtractQENSMembers-v1.rst index 67f9613c6cc..8ea5b640408 100644 --- a/docs/source/algorithms/ExtractQENSMembers-v1.rst +++ b/docs/source/algorithms/ExtractQENSMembers-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExtractSingleSpectrum-v1.rst b/docs/source/algorithms/ExtractSingleSpectrum-v1.rst index 624dd7889b1..3dfb14755c4 100644 --- a/docs/source/algorithms/ExtractSingleSpectrum-v1.rst +++ b/docs/source/algorithms/ExtractSingleSpectrum-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExtractSpectra-v1.rst b/docs/source/algorithms/ExtractSpectra-v1.rst index 094704b06f8..361a05673b8 100644 --- a/docs/source/algorithms/ExtractSpectra-v1.rst +++ b/docs/source/algorithms/ExtractSpectra-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ExtractUnmaskedSpectra-v1.rst b/docs/source/algorithms/ExtractUnmaskedSpectra-v1.rst index 3d3a3ca9fc0..439e06812cb 100644 --- a/docs/source/algorithms/ExtractUnmaskedSpectra-v1.rst +++ b/docs/source/algorithms/ExtractUnmaskedSpectra-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FFT-v1.rst b/docs/source/algorithms/FFT-v1.rst index 23d8d392f4b..467c249b817 100644 --- a/docs/source/algorithms/FFT-v1.rst +++ b/docs/source/algorithms/FFT-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FFTDerivative-v1.rst b/docs/source/algorithms/FFTDerivative-v1.rst index fd926b6bbf5..4e15e3737e2 100644 --- a/docs/source/algorithms/FFTDerivative-v1.rst +++ b/docs/source/algorithms/FFTDerivative-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FFTSmooth-v1.rst b/docs/source/algorithms/FFTSmooth-v1.rst index 244a668c3db..277c3e01e78 100644 --- a/docs/source/algorithms/FFTSmooth-v1.rst +++ b/docs/source/algorithms/FFTSmooth-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FFTSmooth-v2.rst b/docs/source/algorithms/FFTSmooth-v2.rst index 1bef23441fa..9b44faa260f 100644 --- a/docs/source/algorithms/FFTSmooth-v2.rst +++ b/docs/source/algorithms/FFTSmooth-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FakeISISEventDAE-v1.rst b/docs/source/algorithms/FakeISISEventDAE-v1.rst index dd8ccf50f95..dfa1fd9e352 100644 --- a/docs/source/algorithms/FakeISISEventDAE-v1.rst +++ b/docs/source/algorithms/FakeISISEventDAE-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FakeISISHistoDAE-v1.rst b/docs/source/algorithms/FakeISISHistoDAE-v1.rst index 64be954cbce..8d65f2a33f5 100644 --- a/docs/source/algorithms/FakeISISHistoDAE-v1.rst +++ b/docs/source/algorithms/FakeISISHistoDAE-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FakeMDEventData-v1.rst b/docs/source/algorithms/FakeMDEventData-v1.rst index 2566749755e..ecc8148bcba 100644 --- a/docs/source/algorithms/FakeMDEventData-v1.rst +++ b/docs/source/algorithms/FakeMDEventData-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FilterBadPulses-v1.rst b/docs/source/algorithms/FilterBadPulses-v1.rst index d90b34fa8d4..b98e55478c0 100644 --- a/docs/source/algorithms/FilterBadPulses-v1.rst +++ b/docs/source/algorithms/FilterBadPulses-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FilterByLogValue-v1.rst b/docs/source/algorithms/FilterByLogValue-v1.rst index 757d3077511..0fa6a30a54a 100644 --- a/docs/source/algorithms/FilterByLogValue-v1.rst +++ b/docs/source/algorithms/FilterByLogValue-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FilterByTime-v1.rst b/docs/source/algorithms/FilterByTime-v1.rst index 075d9cd6d4c..c38d8a1d97a 100644 --- a/docs/source/algorithms/FilterByTime-v1.rst +++ b/docs/source/algorithms/FilterByTime-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FilterByXValue-v1.rst b/docs/source/algorithms/FilterByXValue-v1.rst index 120a8e3626f..78d3c576ea5 100644 --- a/docs/source/algorithms/FilterByXValue-v1.rst +++ b/docs/source/algorithms/FilterByXValue-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FilterEvents-v1.rst b/docs/source/algorithms/FilterEvents-v1.rst index 40f20b1ae09..b8032b1853d 100644 --- a/docs/source/algorithms/FilterEvents-v1.rst +++ b/docs/source/algorithms/FilterEvents-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FilterEventsByLogValuePreNexus-v2.rst b/docs/source/algorithms/FilterEventsByLogValuePreNexus-v2.rst index f561ec03ba6..38dad32fd64 100644 --- a/docs/source/algorithms/FilterEventsByLogValuePreNexus-v2.rst +++ b/docs/source/algorithms/FilterEventsByLogValuePreNexus-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FilterLogByTime-v1.rst b/docs/source/algorithms/FilterLogByTime-v1.rst index 3a59a1ecd32..cc472181d1f 100644 --- a/docs/source/algorithms/FilterLogByTime-v1.rst +++ b/docs/source/algorithms/FilterLogByTime-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FilterPeaks-v1.rst b/docs/source/algorithms/FilterPeaks-v1.rst index 0e2c5e8510f..60b68602faa 100644 --- a/docs/source/algorithms/FilterPeaks-v1.rst +++ b/docs/source/algorithms/FilterPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindCenterOfMassPosition-v1.rst b/docs/source/algorithms/FindCenterOfMassPosition-v1.rst index 089aeba786c..d3ce89a0510 100644 --- a/docs/source/algorithms/FindCenterOfMassPosition-v1.rst +++ b/docs/source/algorithms/FindCenterOfMassPosition-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindCenterOfMassPosition-v2.rst b/docs/source/algorithms/FindCenterOfMassPosition-v2.rst index 6e52fe5e4c5..807494f5f19 100644 --- a/docs/source/algorithms/FindCenterOfMassPosition-v2.rst +++ b/docs/source/algorithms/FindCenterOfMassPosition-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindClusterFaces-v1.rst b/docs/source/algorithms/FindClusterFaces-v1.rst index e9dc29408f4..2aaab72b277 100644 --- a/docs/source/algorithms/FindClusterFaces-v1.rst +++ b/docs/source/algorithms/FindClusterFaces-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindDeadDetectors-v1.rst b/docs/source/algorithms/FindDeadDetectors-v1.rst index 9b2e143ec19..61183a433f7 100644 --- a/docs/source/algorithms/FindDeadDetectors-v1.rst +++ b/docs/source/algorithms/FindDeadDetectors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindDetectorsInShape-v1.rst b/docs/source/algorithms/FindDetectorsInShape-v1.rst index 396988effb9..6a5e7072d7b 100644 --- a/docs/source/algorithms/FindDetectorsInShape-v1.rst +++ b/docs/source/algorithms/FindDetectorsInShape-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindDetectorsOutsideLimits-v1.rst b/docs/source/algorithms/FindDetectorsOutsideLimits-v1.rst index 1533d25ddaa..3b4d4cbeead 100644 --- a/docs/source/algorithms/FindDetectorsOutsideLimits-v1.rst +++ b/docs/source/algorithms/FindDetectorsOutsideLimits-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindDetectorsPar-v1.rst b/docs/source/algorithms/FindDetectorsPar-v1.rst index 4ba2c875bdd..26102ba8027 100644 --- a/docs/source/algorithms/FindDetectorsPar-v1.rst +++ b/docs/source/algorithms/FindDetectorsPar-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindEPP-v1.rst b/docs/source/algorithms/FindEPP-v1.rst index e3e3334e896..689deffb322 100644 --- a/docs/source/algorithms/FindEPP-v1.rst +++ b/docs/source/algorithms/FindEPP-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindEPP-v2.rst b/docs/source/algorithms/FindEPP-v2.rst index 5d21c8caf27..6d9bf273840 100644 --- a/docs/source/algorithms/FindEPP-v2.rst +++ b/docs/source/algorithms/FindEPP-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindPeakBackground-v1.rst b/docs/source/algorithms/FindPeakBackground-v1.rst index 74a0ba5dbc1..13fe933f2be 100644 --- a/docs/source/algorithms/FindPeakBackground-v1.rst +++ b/docs/source/algorithms/FindPeakBackground-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindPeaks-v1.rst b/docs/source/algorithms/FindPeaks-v1.rst index 065598ee6f0..7e0ca332f48 100644 --- a/docs/source/algorithms/FindPeaks-v1.rst +++ b/docs/source/algorithms/FindPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindPeaksMD-v1.rst b/docs/source/algorithms/FindPeaksMD-v1.rst index 5d799903afd..924f356c771 100644 --- a/docs/source/algorithms/FindPeaksMD-v1.rst +++ b/docs/source/algorithms/FindPeaksMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -145,24 +145,24 @@ file is availible in `Mantid system tests repository <https://github.com/mantidp def print_tableWS(pTWS,nRows): ''' Method to print part of the table workspace ''' - tab_names=pTWS.keys(); - + tab_names=pTWS.keys() + row = "" for name in tab_names: if len(name)>8: - name= name[0:8]; - print("| {0:8} ".format(name)) - print("|\n") - - for i in xrange(0,nRows): + name= name[:8] + row += "| {:8} ".format(name) + print(row + "|") + + for i in range(nRows): + row = "" for name in tab_names: col = pTWS.column(name); data2pr=col[i] if type(data2pr) is float: - print("| {0:>8.2f} ".format(data2pr)) + row += "| {:8.1f} ".format(data2pr) else: - print("| {0:>8} ".format(data2pr)) - print("|\n") - + row += "| {:8} ".format(str(data2pr)) + print(row + "|") # load test workspace Load(Filename=r'TOPAZ_3132_event.nxs',OutputWorkspace='TOPAZ_3132_event',LoadMonitors='1') @@ -183,17 +183,17 @@ file is availible in `Mantid system tests repository <https://github.com/mantidp #.. testoutput:: exFindPeaksMD - | RunNumbe | DetID | h | k | l | Waveleng | Energy | TOF | DSpacing | Intens | SigInt | BinCount | BankName | Row | Col | QLab | QSample | - | 3132 | 1124984 | 0.00 | 0.00 | 0.00 | 3.10 | 8.49 | 14482.29 | 2.02 | 0.00 | 0.00 | 1668.00 | bank17 | 120.00 | 42.00 | [1.57771,1.21779,2.37854] | [2.99396,0.815958,0.00317344] | - | 3132 | 1156753 | 0.00 | 0.00 | 0.00 | 2.08 | 18.82 | 9725.74 | 1.30 | 0.00 | 0.00 | 1060.00 | bank17 | 145.00 | 166.00 | [2.48964,1.45725,3.88666] | [4.52618,1.71025,0.129461] | - | 3132 | 1141777 | 0.00 | 0.00 | 0.00 | 1.71 | 28.09 | 7963.17 | 1.05 | 0.00 | 0.00 | 96.00 | bank17 | 17.00 | 108.00 | [2.60836,2.31423,4.86391] | [5.69122,1.79492,-0.452799] | - | 3132 | 1125241 | 0.00 | 0.00 | 0.00 | 1.55 | 33.86 | 7252.16 | 1.01 | 0.00 | 0.00 | 83.00 | bank17 | 121.00 | 43.00 | [3.15504,2.42573,4.75121] | [5.97829,1.63473,0.0118744] | - | 3132 | 1170598 | 0.00 | 0.00 | 0.00 | 1.55 | 34.12 | 7224.59 | 0.95 | 0.00 | 0.00 | 73.00 | bank17 | 166.00 | 220.00 | [3.43363,1.70178,5.39301] | [6.07726,2.59962,0.281759] | - | 3132 | 1214951 | 0.00 | 0.00 | 0.00 | 1.89 | 22.79 | 8839.55 | 1.68 | 0.00 | 0.00 | 719.00 | bank18 | 231.00 | 137.00 | [2.73683,1.43808,2.11574] | [3.5786,0.470838,1.00329] | - | 3132 | 1207827 | 0.00 | 0.00 | 0.00 | 1.71 | 27.89 | 7991.70 | 1.32 | 0.00 | 0.00 | 447.00 | bank18 | 19.00 | 110.00 | [2.80324,2.29519,3.09134] | [4.71517,0.554412,0.37714] | - | 3132 | 1232949 | 0.00 | 0.00 | 0.00 | 1.24 | 53.28 | 5782.14 | 0.93 | 0.00 | 0.00 | 45.00 | bank18 | 53.00 | 208.00 | [4.29033,2.63319,4.46168] | [6.52658,1.27985,1.00646] | - | 3132 | 1189484 | 0.00 | 0.00 | 0.00 | 1.14 | 63.42 | 5299.28 | 0.96 | 0.00 | 0.00 | 31.00 | bank18 | 108.00 | 38.00 | [4.02414,3.39659,3.83664] | [6.4679,0.298896,0.726133] | - | 3132 | 1218337 | 0.00 | 0.00 | 0.00 | 1.01 | 79.81 | 4724.05 | 0.77 | 0.00 | 0.00 | 15.00 | bank18 | 33.00 | 151.00 | [4.96622,3.61607,5.32554] | [7.99244,1.19363,0.892655] | + | RunNumbe | DetID | h | k | l | Waveleng | Energy | TOF | DSpacing | Intens | SigInt | BinCount | BankName | Row | Col | QLab | QSample | PeakNumb | + | 3132 | 1124984 | 0.0 | 0.0 | 0.0 | 3.1 | 8.5 | 14482.3 | 2.0 | 0.0 | 0.0 | 1668.0 | bank17 | 120.0 | 42.0 | [1.57771,1.21779,2.37854] | [2.99396,0.815958,0.00317344] | 1 | + | 3132 | 1156753 | 0.0 | 0.0 | 0.0 | 2.1 | 18.8 | 9725.7 | 1.3 | 0.0 | 0.0 | 1060.0 | bank17 | 145.0 | 166.0 | [2.48964,1.45725,3.88666] | [4.52618,1.71025,0.129461] | 2 | + | 3132 | 1141777 | 0.0 | 0.0 | 0.0 | 1.7 | 28.1 | 7963.2 | 1.0 | 0.0 | 0.0 | 96.0 | bank17 | 17.0 | 108.0 | [2.60836,2.31423,4.86391] | [5.69122,1.79492,-0.452799] | 3 | + | 3132 | 1125241 | 0.0 | 0.0 | 0.0 | 1.6 | 33.9 | 7252.2 | 1.0 | 0.0 | 0.0 | 83.0 | bank17 | 121.0 | 43.0 | [3.15504,2.42573,4.75121] | [5.97829,1.63473,0.0118744] | 4 | + | 3132 | 1170598 | 0.0 | 0.0 | 0.0 | 1.5 | 34.1 | 7224.6 | 0.9 | 0.0 | 0.0 | 73.0 | bank17 | 166.0 | 220.0 | [3.43363,1.70178,5.39301] | [6.07726,2.59962,0.281759] | 5 | + | 3132 | 1214951 | 0.0 | 0.0 | 0.0 | 1.9 | 22.8 | 8839.5 | 1.7 | 0.0 | 0.0 | 719.0 | bank18 | 231.0 | 137.0 | [2.73683,1.43808,2.11574] | [3.5786,0.470838,1.00329] | 6 | + | 3132 | 1207827 | 0.0 | 0.0 | 0.0 | 1.7 | 27.9 | 7991.7 | 1.3 | 0.0 | 0.0 | 447.0 | bank18 | 19.0 | 110.0 | [2.80324,2.29519,3.09134] | [4.71517,0.554412,0.37714] | 7 | + | 3132 | 1232949 | 0.0 | 0.0 | 0.0 | 1.2 | 53.3 | 5782.1 | 0.9 | 0.0 | 0.0 | 45.0 | bank18 | 53.0 | 208.0 | [4.29033,2.63319,4.46168] | [6.52658,1.27985,1.00646] | 8 | + | 3132 | 1189484 | 0.0 | 0.0 | 0.0 | 1.1 | 63.4 | 5299.3 | 1.0 | 0.0 | 0.0 | 31.0 | bank18 | 108.0 | 38.0 | [4.02414,3.39659,3.83664] | [6.4679,0.298896,0.726133] | 9 | + | 3132 | 1218337 | 0.0 | 0.0 | 0.0 | 1.0 | 79.8 | 4724.1 | 0.8 | 0.0 | 0.0 | 15.0 | bank18 | 33.0 | 151.0 | [4.96622,3.61607,5.32554] | [7.99244,1.19363,0.892655] | 10 | .. categories:: diff --git a/docs/source/algorithms/FindReflectometryLines-v1.rst b/docs/source/algorithms/FindReflectometryLines-v1.rst index 8658801e013..959852929a2 100644 --- a/docs/source/algorithms/FindReflectometryLines-v1.rst +++ b/docs/source/algorithms/FindReflectometryLines-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindSXPeaks-v1.rst b/docs/source/algorithms/FindSXPeaks-v1.rst index 91f6a7d0cf0..231ad55bb22 100644 --- a/docs/source/algorithms/FindSXPeaks-v1.rst +++ b/docs/source/algorithms/FindSXPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindUBUsingFFT-v1.rst b/docs/source/algorithms/FindUBUsingFFT-v1.rst index d28fab4eba2..20db2c2cc33 100644 --- a/docs/source/algorithms/FindUBUsingFFT-v1.rst +++ b/docs/source/algorithms/FindUBUsingFFT-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindUBUsingIndexedPeaks-v1.rst b/docs/source/algorithms/FindUBUsingIndexedPeaks-v1.rst index f642030abab..ca033741902 100644 --- a/docs/source/algorithms/FindUBUsingIndexedPeaks-v1.rst +++ b/docs/source/algorithms/FindUBUsingIndexedPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindUBUsingLatticeParameters-v1.rst b/docs/source/algorithms/FindUBUsingLatticeParameters-v1.rst index 1d8012832fd..bdf33137bce 100644 --- a/docs/source/algorithms/FindUBUsingLatticeParameters-v1.rst +++ b/docs/source/algorithms/FindUBUsingLatticeParameters-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FindUBUsingMinMaxD-v1.rst b/docs/source/algorithms/FindUBUsingMinMaxD-v1.rst index e3c3fac4117..f49ad16a667 100644 --- a/docs/source/algorithms/FindUBUsingMinMaxD-v1.rst +++ b/docs/source/algorithms/FindUBUsingMinMaxD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Fit-v1.rst b/docs/source/algorithms/Fit-v1.rst index 035b0430a80..1b2237850be 100644 --- a/docs/source/algorithms/Fit-v1.rst +++ b/docs/source/algorithms/Fit-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FitGaussian-v1.rst b/docs/source/algorithms/FitGaussian-v1.rst index 779dd6ba6da..c6f36f47c74 100644 --- a/docs/source/algorithms/FitGaussian-v1.rst +++ b/docs/source/algorithms/FitGaussian-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FitPeak-v1.rst b/docs/source/algorithms/FitPeak-v1.rst index 0149c2ebf09..47a93d71844 100644 --- a/docs/source/algorithms/FitPeak-v1.rst +++ b/docs/source/algorithms/FitPeak-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FitPowderDiffPeaks-v1.rst b/docs/source/algorithms/FitPowderDiffPeaks-v1.rst index 04796e007eb..ce7ec411564 100644 --- a/docs/source/algorithms/FitPowderDiffPeaks-v1.rst +++ b/docs/source/algorithms/FitPowderDiffPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FitResolutionConvolvedModel-v1.rst b/docs/source/algorithms/FitResolutionConvolvedModel-v1.rst index 2d8770ff4f1..992e88294ed 100644 --- a/docs/source/algorithms/FitResolutionConvolvedModel-v1.rst +++ b/docs/source/algorithms/FitResolutionConvolvedModel-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FixGSASInstrumentFile-v1.rst b/docs/source/algorithms/FixGSASInstrumentFile-v1.rst index fe76a35484b..e7c62fd3c16 100644 --- a/docs/source/algorithms/FixGSASInstrumentFile-v1.rst +++ b/docs/source/algorithms/FixGSASInstrumentFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FlatPlateAbsorption-v1.rst b/docs/source/algorithms/FlatPlateAbsorption-v1.rst index 1ef50855521..b7807180e3d 100644 --- a/docs/source/algorithms/FlatPlateAbsorption-v1.rst +++ b/docs/source/algorithms/FlatPlateAbsorption-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst b/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst index 1cf5a9118b4..fe854b26b83 100644 --- a/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst +++ b/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GSASIIRefineFitPeaks-v1.rst b/docs/source/algorithms/GSASIIRefineFitPeaks-v1.rst index 638d651e1f2..b0ebe932a37 100644 --- a/docs/source/algorithms/GSASIIRefineFitPeaks-v1.rst +++ b/docs/source/algorithms/GSASIIRefineFitPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GatherWorkspaces-v1.rst b/docs/source/algorithms/GatherWorkspaces-v1.rst index 3e58b64aef5..cdcd8907366 100644 --- a/docs/source/algorithms/GatherWorkspaces-v1.rst +++ b/docs/source/algorithms/GatherWorkspaces-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GeneralisedSecondDifference-v1.rst b/docs/source/algorithms/GeneralisedSecondDifference-v1.rst index 8d9c9a05ee1..94359793ffb 100644 --- a/docs/source/algorithms/GeneralisedSecondDifference-v1.rst +++ b/docs/source/algorithms/GeneralisedSecondDifference-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GenerateEventsFilter-v1.rst b/docs/source/algorithms/GenerateEventsFilter-v1.rst index f08d70e464c..d1f49e3ce32 100644 --- a/docs/source/algorithms/GenerateEventsFilter-v1.rst +++ b/docs/source/algorithms/GenerateEventsFilter-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GenerateGroupingPowder-v1.rst b/docs/source/algorithms/GenerateGroupingPowder-v1.rst index 1e60ca05e6f..fd0bf506a2b 100644 --- a/docs/source/algorithms/GenerateGroupingPowder-v1.rst +++ b/docs/source/algorithms/GenerateGroupingPowder-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GenerateGroupingSNSInelastic-v1.rst b/docs/source/algorithms/GenerateGroupingSNSInelastic-v1.rst index be4e371ec3f..9247cc1f73f 100644 --- a/docs/source/algorithms/GenerateGroupingSNSInelastic-v1.rst +++ b/docs/source/algorithms/GenerateGroupingSNSInelastic-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GenerateIPythonNotebook-v1.rst b/docs/source/algorithms/GenerateIPythonNotebook-v1.rst index 5f5d2f6066e..fe434664c10 100644 --- a/docs/source/algorithms/GenerateIPythonNotebook-v1.rst +++ b/docs/source/algorithms/GenerateIPythonNotebook-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GeneratePeaks-v1.rst b/docs/source/algorithms/GeneratePeaks-v1.rst index ba3f9dd6a80..bd8e69b466f 100644 --- a/docs/source/algorithms/GeneratePeaks-v1.rst +++ b/docs/source/algorithms/GeneratePeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GeneratePythonScript-v1.rst b/docs/source/algorithms/GeneratePythonScript-v1.rst index 120ec60cc48..d4e7b1958f7 100644 --- a/docs/source/algorithms/GeneratePythonScript-v1.rst +++ b/docs/source/algorithms/GeneratePythonScript-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GetAllEi-v1.rst b/docs/source/algorithms/GetAllEi-v1.rst index ac64d4a3fbe..b5585acaaea 100644 --- a/docs/source/algorithms/GetAllEi-v1.rst +++ b/docs/source/algorithms/GetAllEi-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst b/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst index 2f15f722ff0..cf7c75e13cc 100644 --- a/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst +++ b/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GetDetectorOffsets-v1.rst b/docs/source/algorithms/GetDetectorOffsets-v1.rst index c7e6cbc0225..79b10bfde4d 100644 --- a/docs/source/algorithms/GetDetectorOffsets-v1.rst +++ b/docs/source/algorithms/GetDetectorOffsets-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GetEi-v1.rst b/docs/source/algorithms/GetEi-v1.rst index f6f69d097d0..d977599197e 100644 --- a/docs/source/algorithms/GetEi-v1.rst +++ b/docs/source/algorithms/GetEi-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GetEi-v2.rst b/docs/source/algorithms/GetEi-v2.rst index d9e7061a00f..f18f493f479 100644 --- a/docs/source/algorithms/GetEi-v2.rst +++ b/docs/source/algorithms/GetEi-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GetEiMonDet-v1.rst b/docs/source/algorithms/GetEiMonDet-v1.rst index 163093133aa..3e4934fb1d4 100644 --- a/docs/source/algorithms/GetEiMonDet-v1.rst +++ b/docs/source/algorithms/GetEiMonDet-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GetEiMonDet-v2.rst b/docs/source/algorithms/GetEiMonDet-v2.rst index bb8169cd350..da019e1c2b0 100644 --- a/docs/source/algorithms/GetEiMonDet-v2.rst +++ b/docs/source/algorithms/GetEiMonDet-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GetEiT0atSNS-v1.rst b/docs/source/algorithms/GetEiT0atSNS-v1.rst index 94e0a89f2fc..d3872c02d6d 100644 --- a/docs/source/algorithms/GetEiT0atSNS-v1.rst +++ b/docs/source/algorithms/GetEiT0atSNS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GetIPTS-v1.rst b/docs/source/algorithms/GetIPTS-v1.rst index 67d94d2baef..88ba39f2e3a 100644 --- a/docs/source/algorithms/GetIPTS-v1.rst +++ b/docs/source/algorithms/GetIPTS-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GetQsInQENSData-v1.rst b/docs/source/algorithms/GetQsInQENSData-v1.rst index 62c6fd51566..f29900f1ce8 100644 --- a/docs/source/algorithms/GetQsInQENSData-v1.rst +++ b/docs/source/algorithms/GetQsInQENSData-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GetSpiceDataRawCountsFromMD-v1.rst b/docs/source/algorithms/GetSpiceDataRawCountsFromMD-v1.rst index 640c995a922..b9f6afae760 100644 --- a/docs/source/algorithms/GetSpiceDataRawCountsFromMD-v1.rst +++ b/docs/source/algorithms/GetSpiceDataRawCountsFromMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GetTimeSeriesLogInformation-v1.rst b/docs/source/algorithms/GetTimeSeriesLogInformation-v1.rst index 7cad594900f..bd1c6e92217 100644 --- a/docs/source/algorithms/GetTimeSeriesLogInformation-v1.rst +++ b/docs/source/algorithms/GetTimeSeriesLogInformation-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GoniometerAnglesFromPhiRotation-v1.rst b/docs/source/algorithms/GoniometerAnglesFromPhiRotation-v1.rst index 55f0eef6c72..c13a7586e6c 100644 --- a/docs/source/algorithms/GoniometerAnglesFromPhiRotation-v1.rst +++ b/docs/source/algorithms/GoniometerAnglesFromPhiRotation-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GreaterThanMD-v1.rst b/docs/source/algorithms/GreaterThanMD-v1.rst index 1b4bfccb923..1cc76e43f7e 100644 --- a/docs/source/algorithms/GreaterThanMD-v1.rst +++ b/docs/source/algorithms/GreaterThanMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GroupDetectors-v1.rst b/docs/source/algorithms/GroupDetectors-v1.rst index 1cb598e2ca4..248238931e7 100644 --- a/docs/source/algorithms/GroupDetectors-v1.rst +++ b/docs/source/algorithms/GroupDetectors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GroupDetectors-v2.rst b/docs/source/algorithms/GroupDetectors-v2.rst index f2cb66ff129..64c22b32792 100644 --- a/docs/source/algorithms/GroupDetectors-v2.rst +++ b/docs/source/algorithms/GroupDetectors-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/GroupWorkspaces-v1.rst b/docs/source/algorithms/GroupWorkspaces-v1.rst index 08bc6389d67..28ea510b27e 100644 --- a/docs/source/algorithms/GroupWorkspaces-v1.rst +++ b/docs/source/algorithms/GroupWorkspaces-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/HFIRDarkCurrentSubtraction-v1.rst b/docs/source/algorithms/HFIRDarkCurrentSubtraction-v1.rst index 1fa07f3cabb..cb4a74af464 100644 --- a/docs/source/algorithms/HFIRDarkCurrentSubtraction-v1.rst +++ b/docs/source/algorithms/HFIRDarkCurrentSubtraction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/HFIRLoad-v1.rst b/docs/source/algorithms/HFIRLoad-v1.rst index 8e54f84b8a5..ed9733f4b43 100644 --- a/docs/source/algorithms/HFIRLoad-v1.rst +++ b/docs/source/algorithms/HFIRLoad-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/HFIRSANSNormalise-v1.rst b/docs/source/algorithms/HFIRSANSNormalise-v1.rst index 600633def4b..019999cebd5 100644 --- a/docs/source/algorithms/HFIRSANSNormalise-v1.rst +++ b/docs/source/algorithms/HFIRSANSNormalise-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/HFIRSANSReduction-v1.rst b/docs/source/algorithms/HFIRSANSReduction-v1.rst index 76fc0da3670..1e332d17284 100644 --- a/docs/source/algorithms/HFIRSANSReduction-v1.rst +++ b/docs/source/algorithms/HFIRSANSReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/HRPDSlabCanAbsorption-v1.rst b/docs/source/algorithms/HRPDSlabCanAbsorption-v1.rst index 95be4bc13f0..845656a7c5c 100644 --- a/docs/source/algorithms/HRPDSlabCanAbsorption-v1.rst +++ b/docs/source/algorithms/HRPDSlabCanAbsorption-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/HasUB-v1.rst b/docs/source/algorithms/HasUB-v1.rst index 8c3a702a195..ed71dd485a2 100644 --- a/docs/source/algorithms/HasUB-v1.rst +++ b/docs/source/algorithms/HasUB-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/He3TubeEfficiency-v1.rst b/docs/source/algorithms/He3TubeEfficiency-v1.rst index 7d941a22e8d..945e7a90023 100644 --- a/docs/source/algorithms/He3TubeEfficiency-v1.rst +++ b/docs/source/algorithms/He3TubeEfficiency-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/HyspecScharpfCorrection-v1.rst b/docs/source/algorithms/HyspecScharpfCorrection-v1.rst index dff4da2f7eb..1ca4fb5fe2f 100644 --- a/docs/source/algorithms/HyspecScharpfCorrection-v1.rst +++ b/docs/source/algorithms/HyspecScharpfCorrection-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IQTransform-v1.rst b/docs/source/algorithms/IQTransform-v1.rst index c4979f152cf..e761d70aec6 100644 --- a/docs/source/algorithms/IQTransform-v1.rst +++ b/docs/source/algorithms/IQTransform-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ISISIndirectDiffractionReduction-v1.rst b/docs/source/algorithms/ISISIndirectDiffractionReduction-v1.rst index ce585d201e5..83fffd29bd1 100644 --- a/docs/source/algorithms/ISISIndirectDiffractionReduction-v1.rst +++ b/docs/source/algorithms/ISISIndirectDiffractionReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ISISIndirectEnergyTransfer-v1.rst b/docs/source/algorithms/ISISIndirectEnergyTransfer-v1.rst index 5780800c69e..2947a546a33 100644 --- a/docs/source/algorithms/ISISIndirectEnergyTransfer-v1.rst +++ b/docs/source/algorithms/ISISIndirectEnergyTransfer-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IdentifyNoisyDetectors-v1.rst b/docs/source/algorithms/IdentifyNoisyDetectors-v1.rst index dbe3eea3d27..1291957226a 100644 --- a/docs/source/algorithms/IdentifyNoisyDetectors-v1.rst +++ b/docs/source/algorithms/IdentifyNoisyDetectors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ImportMDEventWorkspace-v1.rst b/docs/source/algorithms/ImportMDEventWorkspace-v1.rst index 56876d7e7d7..3f052d10474 100644 --- a/docs/source/algorithms/ImportMDEventWorkspace-v1.rst +++ b/docs/source/algorithms/ImportMDEventWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ImportMDHistoWorkspace-v1.rst b/docs/source/algorithms/ImportMDHistoWorkspace-v1.rst index 91d96eedf71..fba81f8dc3e 100644 --- a/docs/source/algorithms/ImportMDHistoWorkspace-v1.rst +++ b/docs/source/algorithms/ImportMDHistoWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndexPeaks-v1.rst b/docs/source/algorithms/IndexPeaks-v1.rst index c67aa21333a..bd66a8b1827 100644 --- a/docs/source/algorithms/IndexPeaks-v1.rst +++ b/docs/source/algorithms/IndexPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndexSXPeaks-v1.rst b/docs/source/algorithms/IndexSXPeaks-v1.rst index 497e71748a6..189b1aee418 100644 --- a/docs/source/algorithms/IndexSXPeaks-v1.rst +++ b/docs/source/algorithms/IndexSXPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst b/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst index 3db9123cf87..c9ca3327bab 100644 --- a/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst +++ b/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectAnnulusAbsorption-v2.rst b/docs/source/algorithms/IndirectAnnulusAbsorption-v2.rst index 77c89e34e5c..b10c28f0930 100644 --- a/docs/source/algorithms/IndirectAnnulusAbsorption-v2.rst +++ b/docs/source/algorithms/IndirectAnnulusAbsorption-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectCalibration-v1.rst b/docs/source/algorithms/IndirectCalibration-v1.rst index cd1184579b0..ada37e779c3 100644 --- a/docs/source/algorithms/IndirectCalibration-v1.rst +++ b/docs/source/algorithms/IndirectCalibration-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst b/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst index e5973db26b9..9b3c2289fac 100644 --- a/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst +++ b/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectCylinderAbsorption-v2.rst b/docs/source/algorithms/IndirectCylinderAbsorption-v2.rst index a32f50957ca..25d58f1fbc4 100644 --- a/docs/source/algorithms/IndirectCylinderAbsorption-v2.rst +++ b/docs/source/algorithms/IndirectCylinderAbsorption-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectDiffScan-v1.rst b/docs/source/algorithms/IndirectDiffScan-v1.rst index d5358ad998d..ef8386c49ac 100644 --- a/docs/source/algorithms/IndirectDiffScan-v1.rst +++ b/docs/source/algorithms/IndirectDiffScan-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst b/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst index 844b49e9abd..e9c662cb20f 100644 --- a/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst +++ b/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectFlatPlateAbsorption-v2.rst b/docs/source/algorithms/IndirectFlatPlateAbsorption-v2.rst index f5cd723fcba..cf8d8dd6ca5 100644 --- a/docs/source/algorithms/IndirectFlatPlateAbsorption-v2.rst +++ b/docs/source/algorithms/IndirectFlatPlateAbsorption-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectILLEnergyTransfer-v1.rst b/docs/source/algorithms/IndirectILLEnergyTransfer-v1.rst index 1044f48fc7c..d94b96d4c93 100644 --- a/docs/source/algorithms/IndirectILLEnergyTransfer-v1.rst +++ b/docs/source/algorithms/IndirectILLEnergyTransfer-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectILLReductionFWS-v1.rst b/docs/source/algorithms/IndirectILLReductionFWS-v1.rst index 48e65b1f07a..94543460dbc 100644 --- a/docs/source/algorithms/IndirectILLReductionFWS-v1.rst +++ b/docs/source/algorithms/IndirectILLReductionFWS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectILLReductionQENS-v1.rst b/docs/source/algorithms/IndirectILLReductionQENS-v1.rst index a0d6bb85580..5910b816835 100644 --- a/docs/source/algorithms/IndirectILLReductionQENS-v1.rst +++ b/docs/source/algorithms/IndirectILLReductionQENS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -13,7 +13,7 @@ Performs a multiple-file QENS (Quasi-Elastic Neutron Scattering) data reduction It uses internally the :ref:`IndirectILLEnergyTransfer <algm-IndirectILLEnergyTransfer>` algorithm. Multiple File Reduction -~~~~~~~~~~~~~~~~~~~~~~~ +####################### The algorithm is capable of running over multiple files. Run property needs to be specified following the syntax in :py:obj:`MultipleFileProperty <mantid.api.MultipleFileProperty>`. @@ -24,7 +24,7 @@ ignored. Use **Added Range** and **Added Stepped Range** instead (see ``CalibrationRun``, ``CalibrationBackgroundRun`` and ``AlignmentRun`` all the runs will be automatically summed. Unmirror Options -~~~~~~~~~~~~~~~~ +################ **IN16B** can record data with mirror sense, where the spectra for the acceleration and deceleration phase of the Doppler drive are recorded separately, or without. @@ -62,7 +62,7 @@ Options 5 and 7 require the ``AlignmentRun`` (vanadium) to determine the peak po Note, that both detector calibration and background subtraction are performed wing-by-wing, i.e. unmirroring is the very final step. Vanadium Calibration -~~~~~~~~~~~~~~~~~~~~ +#################### Integration range can be specified to integrate over spectra in ``CalibrationRun``. Note, that before integration, the spectra will be centered at 0-energy transfer (see Unmirror Option 6 above) for the calibration run. diff --git a/docs/source/algorithms/IndirectQuickRun-v1.rst b/docs/source/algorithms/IndirectQuickRun-v1.rst index d8f19257054..93e79b5bfcb 100644 --- a/docs/source/algorithms/IndirectQuickRun-v1.rst +++ b/docs/source/algorithms/IndirectQuickRun-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectResolution-v1.rst b/docs/source/algorithms/IndirectResolution-v1.rst index 539852f2fcd..07249bd0273 100644 --- a/docs/source/algorithms/IndirectResolution-v1.rst +++ b/docs/source/algorithms/IndirectResolution-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectSampleChanger-v1.rst b/docs/source/algorithms/IndirectSampleChanger-v1.rst index c0f87a6e65c..93907aaa537 100644 --- a/docs/source/algorithms/IndirectSampleChanger-v1.rst +++ b/docs/source/algorithms/IndirectSampleChanger-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectTransmission-v1.rst b/docs/source/algorithms/IndirectTransmission-v1.rst index 142920a7bd8..eeafe31920a 100644 --- a/docs/source/algorithms/IndirectTransmission-v1.rst +++ b/docs/source/algorithms/IndirectTransmission-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst b/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst index 68f881ad280..9f9361a03eb 100644 --- a/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst +++ b/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IntegrateByComponent-v1.rst b/docs/source/algorithms/IntegrateByComponent-v1.rst index d961ed53eee..f2460e09aac 100644 --- a/docs/source/algorithms/IntegrateByComponent-v1.rst +++ b/docs/source/algorithms/IntegrateByComponent-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IntegrateEPP-v1.rst b/docs/source/algorithms/IntegrateEPP-v1.rst index fdcbce9792e..2e2c65a53e4 100644 --- a/docs/source/algorithms/IntegrateEPP-v1.rst +++ b/docs/source/algorithms/IntegrateEPP-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IntegrateEllipsoids-v1.rst b/docs/source/algorithms/IntegrateEllipsoids-v1.rst index 8e34678c0ef..23b4caf1dab 100644 --- a/docs/source/algorithms/IntegrateEllipsoids-v1.rst +++ b/docs/source/algorithms/IntegrateEllipsoids-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -273,17 +273,17 @@ file is availible in `Mantid system tests repository <https://github.com/mantidp .. code-block:: python :linenos: - | RunNumbe | DetID | h | k | l | Waveleng | Energy | TOF | DSpacing | Intens | SigInt | BinCount | BankName | Row | Col | QLab | QSample | - | 3132 | 1124984 | -2.0 | -1.0 | 2.0 | 3.1 | 8.5 | 14482.3 | 2.0 | 120486.0 | 375.8 | 1668.0 | bank17 | 120.0 | 42.0 | [1.57771,1.21779,2.37854] | [2.99396,0.815958,0.00317344] | - | 3132 | 1156753 | -3.0 | -2.0 | 3.0 | 2.1 | 18.8 | 9725.7 | 1.3 | 149543.0 | 393.0 | 1060.0 | bank17 | 145.0 | 166.0 | [2.48964,1.45725,3.88666] | [4.52618,1.71025,0.129461] | - | 3132 | 1141777 | -4.0 | -2.0 | 3.0 | 1.7 | 28.1 | 7963.2 | 1.0 | 8744.0 | 106.3 | 96.0 | bank17 | 17.0 | 108.0 | [2.60836,2.31423,4.86391] | [5.69122,1.79492,-0.452799] | - | 3132 | 1125241 | -4.0 | -2.0 | 4.0 | 1.6 | 33.9 | 7252.2 | 1.0 | 19740.0 | 146.2 | 83.0 | bank17 | 121.0 | 43.0 | [3.15504,2.42573,4.75121] | [5.97829,1.63473,0.0118744] | - | 3132 | 1170598 | -4.0 | -3.0 | 4.0 | 1.5 | 34.1 | 7224.6 | 0.9 | 15914.0 | 131.4 | 73.0 | bank17 | 166.0 | 220.0 | [3.43363,1.70178,5.39301] | [6.07726,2.59962,0.281759] | - | 3132 | 1214951 | -2.0 | -1.0 | 4.0 | 1.9 | 22.8 | 8839.5 | 1.7 | 121852.0 | 352.9 | 719.0 | bank18 | 231.0 | 137.0 | [2.73683,1.43808,2.11574] | [3.5786,0.470838,1.00329] | - | 3132 | 1207827 | -3.0 | -1.0 | 4.0 | 1.7 | 27.9 | 7991.7 | 1.3 | 64593.0 | 257.7 | 447.0 | bank18 | 19.0 | 110.0 | [2.80324,2.29519,3.09134] | [4.71517,0.554412,0.37714] | - | 3132 | 1232949 | -4.0 | -2.0 | 6.0 | 1.2 | 53.3 | 5782.1 | 0.9 | 18247.0 | 139.3 | 45.0 | bank18 | 53.0 | 208.0 | [4.29033,2.63319,4.46168] | [6.52658,1.27985,1.00646] | - | 3132 | 1189484 | -4.0 | -1.0 | 6.0 | 1.1 | 63.4 | 5299.3 | 1.0 | 13512.0 | 120.7 | 31.0 | bank18 | 108.0 | 38.0 | [4.02414,3.39659,3.83664] | [6.4679,0.298896,0.726133] | - | 3132 | 1218337 | -5.0 | -2.0 | 7.0 | 1.0 | 79.8 | 4724.1 | 0.8 | 7411.0 | 88.3 | 15.0 | bank18 | 33.0 | 151.0 | [4.96622,3.61607,5.32554] | [7.99244,1.19363,0.892655] | + | RunNumbe | DetID | h | k | l | Waveleng | Energy | TOF | DSpacing | Intens | SigInt | BinCount | BankName | Row | Col | QLab | QSample | PeakNumb | + | 3132 | 1124984 | -2.0 | -1.0 | 2.0 | 3.1 | 8.5 | 14482.3 | 2.0 | 120486.0 | 375.8 | 1668.0 | bank17 | 120.0 | 42.0 | [1.57771,1.21779,2.37854] | [2.99396,0.815958,0.00317344] | 1 | + | 3132 | 1156753 | -3.0 | -2.0 | 3.0 | 2.1 | 18.8 | 9725.7 | 1.3 | 149543.0 | 393.0 | 1060.0 | bank17 | 145.0 | 166.0 | [2.48964,1.45725,3.88666] | [4.52618,1.71025,0.129461] | 2 | + | 3132 | 1141777 | -4.0 | -2.0 | 3.0 | 1.7 | 28.1 | 7963.2 | 1.0 | 8744.0 | 106.3 | 96.0 | bank17 | 17.0 | 108.0 | [2.60836,2.31423,4.86391] | [5.69122,1.79492,-0.452799] | 3 | + | 3132 | 1125241 | -4.0 | -2.0 | 4.0 | 1.6 | 33.9 | 7252.2 | 1.0 | 19740.0 | 146.2 | 83.0 | bank17 | 121.0 | 43.0 | [3.15504,2.42573,4.75121] | [5.97829,1.63473,0.0118744] | 4 | + | 3132 | 1170598 | -4.0 | -3.0 | 4.0 | 1.5 | 34.1 | 7224.6 | 0.9 | 15914.0 | 131.4 | 73.0 | bank17 | 166.0 | 220.0 | [3.43363,1.70178,5.39301] | [6.07726,2.59962,0.281759] | 5 | + | 3132 | 1214951 | -2.0 | -1.0 | 4.0 | 1.9 | 22.8 | 8839.5 | 1.7 | 121852.0 | 352.9 | 719.0 | bank18 | 231.0 | 137.0 | [2.73683,1.43808,2.11574] | [3.5786,0.470838,1.00329] | 6 | + | 3132 | 1207827 | -3.0 | -1.0 | 4.0 | 1.7 | 27.9 | 7991.7 | 1.3 | 64593.0 | 257.7 | 447.0 | bank18 | 19.0 | 110.0 | [2.80324,2.29519,3.09134] | [4.71517,0.554412,0.37714] | 7 | + | 3132 | 1232949 | -4.0 | -2.0 | 6.0 | 1.2 | 53.3 | 5782.1 | 0.9 | 18247.0 | 139.3 | 45.0 | bank18 | 53.0 | 208.0 | [4.29033,2.63319,4.46168] | [6.52658,1.27985,1.00646] | 8 | + | 3132 | 1189484 | -4.0 | -1.0 | 6.0 | 1.1 | 63.4 | 5299.3 | 1.0 | 13512.0 | 120.7 | 31.0 | bank18 | 108.0 | 38.0 | [4.02414,3.39659,3.83664] | [6.4679,0.298896,0.726133] | 9 | + | 3132 | 1218337 | -5.0 | -2.0 | 7.0 | 1.0 | 79.8 | 4724.1 | 0.8 | 7411.0 | 88.3 | 15.0 | bank18 | 33.0 | 151.0 | [4.96622,3.61607,5.32554] | [7.99244,1.19363,0.892655] | 10 | .. categories:: diff --git a/docs/source/algorithms/IntegrateEllipsoidsTwoStep-v1.rst b/docs/source/algorithms/IntegrateEllipsoidsTwoStep-v1.rst index 8b7af21beb5..3104a0cd27e 100644 --- a/docs/source/algorithms/IntegrateEllipsoidsTwoStep-v1.rst +++ b/docs/source/algorithms/IntegrateEllipsoidsTwoStep-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -315,17 +315,17 @@ availible in `Mantid system tests repository .. code-block:: python :linenos: - | RunNumbe | DetID | h | k | l | Waveleng | Energy | TOF | DSpacing | Intens | SigInt | BinCount | BankName | Row | Col | QLab | QSample | - | 3132 | 1124984 | -2.0 | -1.0 | 2.0 | 3.1 | 8.5 | 14482.3 | 2.0 | 120486.0 | 375.8 | 1668.0 | bank17 | 120.0 | 42.0 | [1.57771,1.21779,2.37854] | [2.99396,0.815958,0.00317344] | - | 3132 | 1156753 | -3.0 | -2.0 | 3.0 | 2.1 | 18.8 | 9725.7 | 1.3 | 149543.0 | 393.0 | 1060.0 | bank17 | 145.0 | 166.0 | [2.48964,1.45725,3.88666] | [4.52618,1.71025,0.129461] | - | 3132 | 1141777 | -4.0 | -2.0 | 3.0 | 1.7 | 28.1 | 7963.2 | 1.0 | 8744.0 | 106.3 | 96.0 | bank17 | 17.0 | 108.0 | [2.60836,2.31423,4.86391] | [5.69122,1.79492,-0.452799] | - | 3132 | 1125241 | -4.0 | -2.0 | 4.0 | 1.6 | 33.9 | 7252.2 | 1.0 | 19740.0 | 146.2 | 83.0 | bank17 | 121.0 | 43.0 | [3.15504,2.42573,4.75121] | [5.97829,1.63473,0.0118744] | - | 3132 | 1170598 | -4.0 | -3.0 | 4.0 | 1.5 | 34.1 | 7224.6 | 0.9 | 15914.0 | 131.4 | 73.0 | bank17 | 166.0 | 220.0 | [3.43363,1.70178,5.39301] | [6.07726,2.59962,0.281759] | - | 3132 | 1214951 | -2.0 | -1.0 | 4.0 | 1.9 | 22.8 | 8839.5 | 1.7 | 121852.0 | 352.9 | 719.0 | bank18 | 231.0 | 137.0 | [2.73683,1.43808,2.11574] | [3.5786,0.470838,1.00329] | - | 3132 | 1207827 | -3.0 | -1.0 | 4.0 | 1.7 | 27.9 | 7991.7 | 1.3 | 64593.0 | 257.7 | 447.0 | bank18 | 19.0 | 110.0 | [2.80324,2.29519,3.09134] | [4.71517,0.554412,0.37714] | - | 3132 | 1232949 | -4.0 | -2.0 | 6.0 | 1.2 | 53.3 | 5782.1 | 0.9 | 18247.0 | 139.3 | 45.0 | bank18 | 53.0 | 208.0 | [4.29033,2.63319,4.46168] | [6.52658,1.27985,1.00646] | - | 3132 | 1189484 | -4.0 | -1.0 | 6.0 | 1.1 | 63.4 | 5299.3 | 1.0 | 13512.0 | 120.7 | 31.0 | bank18 | 108.0 | 38.0 | [4.02414,3.39659,3.83664] | [6.4679,0.298896,0.726133] | - | 3132 | 1218337 | -5.0 | -2.0 | 7.0 | 1.0 | 79.8 | 4724.1 | 0.8 | 7411.0 | 88.3 | 15.0 | bank18 | 33.0 | 151.0 | [4.96622,3.61607,5.32554] | [7.99244,1.19363,0.892655] | + | RunNumbe | DetID | h | k | l | Waveleng | Energy | TOF | DSpacing | Intens | SigInt | BinCount | BankName | Row | Col | QLab | QSample | PeakNumb | + | 3132 | 1124984 | -2.0 | -1.0 | 2.0 | 3.1 | 8.5 | 14482.3 | 2.0 | 120486.0 | 375.8 | 1668.0 | bank17 | 120.0 | 42.0 | [1.57771,1.21779,2.37854] | [2.99396,0.815958,0.00317344] | 1 | + | 3132 | 1156753 | -3.0 | -2.0 | 3.0 | 2.1 | 18.8 | 9725.7 | 1.3 | 149543.0 | 393.0 | 1060.0 | bank17 | 145.0 | 166.0 | [2.48964,1.45725,3.88666] | [4.52618,1.71025,0.129461] | 2 | + | 3132 | 1141777 | -4.0 | -2.0 | 3.0 | 1.7 | 28.1 | 7963.2 | 1.0 | 8744.0 | 106.3 | 96.0 | bank17 | 17.0 | 108.0 | [2.60836,2.31423,4.86391] | [5.69122,1.79492,-0.452799] | 3 | + | 3132 | 1125241 | -4.0 | -2.0 | 4.0 | 1.6 | 33.9 | 7252.2 | 1.0 | 19740.0 | 146.2 | 83.0 | bank17 | 121.0 | 43.0 | [3.15504,2.42573,4.75121] | [5.97829,1.63473,0.0118744] | 4 | + | 3132 | 1170598 | -4.0 | -3.0 | 4.0 | 1.5 | 34.1 | 7224.6 | 0.9 | 15914.0 | 131.4 | 73.0 | bank17 | 166.0 | 220.0 | [3.43363,1.70178,5.39301] | [6.07726,2.59962,0.281759] | 5 | + | 3132 | 1214951 | -2.0 | -1.0 | 4.0 | 1.9 | 22.8 | 8839.5 | 1.7 | 121852.0 | 352.9 | 719.0 | bank18 | 231.0 | 137.0 | [2.73683,1.43808,2.11574] | [3.5786,0.470838,1.00329] | 6 | + | 3132 | 1207827 | -3.0 | -1.0 | 4.0 | 1.7 | 27.9 | 7991.7 | 1.3 | 64593.0 | 257.7 | 447.0 | bank18 | 19.0 | 110.0 | [2.80324,2.29519,3.09134] | [4.71517,0.554412,0.37714] | 7 | + | 3132 | 1232949 | -4.0 | -2.0 | 6.0 | 1.2 | 53.3 | 5782.1 | 0.9 | 18247.0 | 139.3 | 45.0 | bank18 | 53.0 | 208.0 | [4.29033,2.63319,4.46168] | [6.52658,1.27985,1.00646] | 8 | + | 3132 | 1189484 | -4.0 | -1.0 | 6.0 | 1.1 | 63.4 | 5299.3 | 1.0 | 13512.0 | 120.7 | 31.0 | bank18 | 108.0 | 38.0 | [4.02414,3.39659,3.83664] | [6.4679,0.298896,0.726133] | 9 | + | 3132 | 1218337 | -5.0 | -2.0 | 7.0 | 1.0 | 79.8 | 4724.1 | 0.8 | 7411.0 | 88.3 | 15.0 | bank18 | 33.0 | 151.0 | [4.96622,3.61607,5.32554] | [7.99244,1.19363,0.892655] | 10 | .. categories:: diff --git a/docs/source/algorithms/IntegrateFlux-v1.rst b/docs/source/algorithms/IntegrateFlux-v1.rst index 04161a2ddd7..6bda273ccce 100644 --- a/docs/source/algorithms/IntegrateFlux-v1.rst +++ b/docs/source/algorithms/IntegrateFlux-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IntegrateMDHistoWorkspace-v1.rst b/docs/source/algorithms/IntegrateMDHistoWorkspace-v1.rst index 0f27858c11c..40bd6a3c80b 100644 --- a/docs/source/algorithms/IntegrateMDHistoWorkspace-v1.rst +++ b/docs/source/algorithms/IntegrateMDHistoWorkspace-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -13,12 +13,12 @@ Description Provides limited integration of a :ref:`MDHistoWorkspace <MDHistoWorkspace>` in n-dimensions. Integration is always axis-aligned. Dimensions can only be integrated out, but no finer rebinning is permitted. Dimensions that do not require further rebinning will be left intact provided that the the binning parameters for those dimensions are not specified. For dimensions that are integrated, limits should be provided to give the range of the data to keep. Binning -~~~~~~~ +####### The *P1Bin* corresponds to the first dimension of the MDHistoWorkspace, *P2Bin* to the second and so on. *P1Bin=[-1, 1]* indicates that we will integrate this dimension between -1 and 1. *P1Bins=[]* indicates that the shape of this dimension should be unchanged from the input. *P1Bins=[-1,0,1]* is a special case, the zero indicates that the same bin width as the input dimension would be used, but the minimum and maximum will also be used to crop the dimension. In this latter form, the limits may be expanded to ensure that there is no partial bins in the non-integrated dimension (see warning messages). Weights -~~~~~~~ +####### The algorithm works by creating the *OutputWorkspace* in the correct shape. Each bin in the OutputWorkspace is treated in turn. For each bin in the OutputWorkspace, we find those bins in the *InputWorkspace* that overlap and therefore could contribute to the OutputBin. For any contributing bin, we calculate the fraction overlap and treat this a weighting factor. For each contributing bin *Signal*, and :math:`Error^{2}`, and *Number of Events* values are extracted and multiplied by the weight. These values are summed for all contributing input bins before being assigned to the corresponding output bin. For plotting the *OutputWorkspace*, it is important to select the Number of Events normalization option to correctly account for the weights. diff --git a/docs/source/algorithms/IntegratePeakTimeSlices-v1.rst b/docs/source/algorithms/IntegratePeakTimeSlices-v1.rst index 7c95e0d49fd..b328a21255e 100644 --- a/docs/source/algorithms/IntegratePeakTimeSlices-v1.rst +++ b/docs/source/algorithms/IntegratePeakTimeSlices-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IntegratePeaksCWSD-v1.rst b/docs/source/algorithms/IntegratePeaksCWSD-v1.rst index 1f32f37597a..b6ec410b2a0 100644 --- a/docs/source/algorithms/IntegratePeaksCWSD-v1.rst +++ b/docs/source/algorithms/IntegratePeaksCWSD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IntegratePeaksHybrid-v1.rst b/docs/source/algorithms/IntegratePeaksHybrid-v1.rst index 23444e0a196..6c76bddc5fb 100644 --- a/docs/source/algorithms/IntegratePeaksHybrid-v1.rst +++ b/docs/source/algorithms/IntegratePeaksHybrid-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IntegratePeaksMD-v1.rst b/docs/source/algorithms/IntegratePeaksMD-v1.rst index b0fb9c10c75..6e728bd8f1b 100644 --- a/docs/source/algorithms/IntegratePeaksMD-v1.rst +++ b/docs/source/algorithms/IntegratePeaksMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IntegratePeaksMD-v2.rst b/docs/source/algorithms/IntegratePeaksMD-v2.rst index 9e159ed56c3..76b3bf4f930 100644 --- a/docs/source/algorithms/IntegratePeaksMD-v2.rst +++ b/docs/source/algorithms/IntegratePeaksMD-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -236,17 +236,17 @@ file is availible in `Mantid system tests repository <https://github.com/mantidp :linenos: - | RunNumbe | DetID | h | k | l | Waveleng | Energy | TOF | DSpacing | Intens | SigInt | BinCount | BankName | Row | Col | QLab | QSample | - | 3132 | 1168209 | 0.0 | 0.0 | 0.0 | 1.1 | 66.9 | 5158.0 | 0.7 | 2160.9 | 32.3 | 1326.0 | bank17 | 81.0 | 211.0 | [4.42961,2.81707,7.86314] | [8.75838,3.55459,-0.205083] | - | 3132 | 1124983 | 0.0 | 0.0 | 0.0 | 1.6 | 33.9 | 7250.6 | 1.0 | 1990.0 | 14.4 | 1060.0 | bank17 | 119.0 | 42.0 | [3.14813,2.43563,4.75389] | [5.9822,1.62965,0.00130101] | - | 3132 | 1141521 | 0.0 | 0.0 | 0.0 | 1.7 | 28.1 | 7959.1 | 1.0 | 644.6 | 7.3 | 1034.0 | bank17 | 17.0 | 107.0 | [2.60893,2.31831,4.86248] | [5.69311,1.79103,-0.453311] | - | 3132 | 1125238 | 0.0 | 0.0 | 0.0 | 3.1 | 8.4 | 14518.9 | 2.0 | 750.5 | 2.2 | 880.0 | bank17 | 118.0 | 43.0 | [1.57116,1.21649,2.37775] | [2.98926,0.816337,-0.00161709] | - | 3132 | 1170852 | 0.0 | 0.0 | 0.0 | 1.6 | 34.0 | 7235.3 | 1.0 | 1826.4 | 14.7 | 762.0 | bank17 | 164.0 | 221.0 | [3.4229,1.70246,5.39532] | [6.0734,2.6008,0.271523] | - | 3132 | 1156497 | 0.0 | 0.0 | 0.0 | 2.1 | 18.9 | 9718.2 | 1.3 | 5137.6 | 13.4 | 518.0 | bank17 | 145.0 | 165.0 | [2.49117,1.46093,3.88649] | [4.5291,1.70753,0.129446] | - | 3132 | 1207828 | 0.0 | 0.0 | 0.0 | 1.7 | 27.9 | 7989.1 | 1.3 | 3233.6 | 12.7 | 1024.0 | bank18 | 20.0 | 110.0 | [2.80538,2.29342,3.08833] | [4.71342,0.553533,0.380727] | - | 3132 | 1218593 | 0.0 | 0.0 | 0.0 | 1.0 | 79.6 | 4729.3 | 0.8 | 3018.1 | 35.4 | 756.0 | bank18 | 33.0 | 152.0 | [4.96533,3.60693,5.32436] | [7.98578,1.19927,0.895763] | - | 3132 | 1232694 | 0.0 | 0.0 | 0.0 | 1.2 | 53.4 | 5772.9 | 0.9 | 3464.5 | 25.9 | 631.0 | bank18 | 54.0 | 207.0 | [4.29539,2.63813,4.45945] | [6.53086,1.27477,1.00974] | - | 3132 | 1200023 | 0.0 | 0.0 | 0.0 | 0.7 | 159.1 | 3345.1 | 0.6 | 3796.1 | 71.1 | 509.0 | bank18 | 151.0 | 79.0 | [6.75629,4.8092,5.93224] | [10.0166,0.773518,1.74245] | + | RunNumbe | DetID | h | k | l | Waveleng | Energy | TOF | DSpacing | Intens | SigInt | BinCount | BankName | Row | Col | QLab | QSample | PeakNumb | + | 3132 | 1168209 | 0.0 | 0.0 | 0.0 | 1.1 | 66.9 | 5158.0 | 0.7 | 2160.9 | 32.3 | 1326.0 | bank17 | 81.0 | 211.0 | [4.42961,2.81707,7.86314] | [8.75838,3.55459,-0.205083] | 1 | + | 3132 | 1124983 | 0.0 | 0.0 | 0.0 | 1.6 | 33.9 | 7250.6 | 1.0 | 1990.0 | 14.4 | 1060.0 | bank17 | 119.0 | 42.0 | [3.14813,2.43563,4.75389] | [5.9822,1.62965,0.00130101] | 2 | + | 3132 | 1141521 | 0.0 | 0.0 | 0.0 | 1.7 | 28.1 | 7959.1 | 1.0 | 644.6 | 7.3 | 1034.0 | bank17 | 17.0 | 107.0 | [2.60893,2.31831,4.86248] | [5.69311,1.79103,-0.453311] | 3 | + | 3132 | 1125238 | 0.0 | 0.0 | 0.0 | 3.1 | 8.4 | 14518.9 | 2.0 | 750.5 | 2.2 | 880.0 | bank17 | 118.0 | 43.0 | [1.57116,1.21649,2.37775] | [2.98926,0.816337,-0.00161709] | 4 | + | 3132 | 1170852 | 0.0 | 0.0 | 0.0 | 1.6 | 34.0 | 7235.3 | 1.0 | 1826.4 | 14.7 | 762.0 | bank17 | 164.0 | 221.0 | [3.4229,1.70246,5.39532] | [6.0734,2.6008,0.271523] | 5 | + | 3132 | 1156497 | 0.0 | 0.0 | 0.0 | 2.1 | 18.9 | 9718.2 | 1.3 | 5137.6 | 13.4 | 518.0 | bank17 | 145.0 | 165.0 | [2.49117,1.46093,3.88649] | [4.5291,1.70753,0.129446] | 6 | + | 3132 | 1207828 | 0.0 | 0.0 | 0.0 | 1.7 | 27.9 | 7989.1 | 1.3 | 3233.6 | 12.7 | 1024.0 | bank18 | 20.0 | 110.0 | [2.80538,2.29342,3.08833] | [4.71342,0.553533,0.380727] | 7 | + | 3132 | 1218593 | 0.0 | 0.0 | 0.0 | 1.0 | 79.6 | 4729.3 | 0.8 | 3018.1 | 35.4 | 756.0 | bank18 | 33.0 | 152.0 | [4.96533,3.60693,5.32436] | [7.98578,1.19927,0.895763] | 8 | + | 3132 | 1232694 | 0.0 | 0.0 | 0.0 | 1.2 | 53.4 | 5772.9 | 0.9 | 3464.5 | 25.9 | 631.0 | bank18 | 54.0 | 207.0 | [4.29539,2.63813,4.45945] | [6.53086,1.27477,1.00974] | 9 | + | 3132 | 1200023 | 0.0 | 0.0 | 0.0 | 0.7 | 159.1 | 3345.1 | 0.6 | 3796.1 | 71.1 | 509.0 | bank18 | 151.0 | 79.0 | [6.75629,4.8092,5.93224] | [10.0166,0.773518,1.74245] | 10 | .. categories:: diff --git a/docs/source/algorithms/IntegratePeaksMDHKL-v1.rst b/docs/source/algorithms/IntegratePeaksMDHKL-v1.rst index af9d3208f2e..fecbb7bbb71 100644 --- a/docs/source/algorithms/IntegratePeaksMDHKL-v1.rst +++ b/docs/source/algorithms/IntegratePeaksMDHKL-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IntegratePeaksUsingClusters-v1.rst b/docs/source/algorithms/IntegratePeaksUsingClusters-v1.rst index a57d879043f..ed9b40a93df 100644 --- a/docs/source/algorithms/IntegratePeaksUsingClusters-v1.rst +++ b/docs/source/algorithms/IntegratePeaksUsingClusters-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Integration-v1.rst b/docs/source/algorithms/Integration-v1.rst index 5a98e9bc9d2..254e64df534 100644 --- a/docs/source/algorithms/Integration-v1.rst +++ b/docs/source/algorithms/Integration-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/InterpolatingRebin-v1.rst b/docs/source/algorithms/InterpolatingRebin-v1.rst index 6749b30292b..41e9ec068ae 100644 --- a/docs/source/algorithms/InterpolatingRebin-v1.rst +++ b/docs/source/algorithms/InterpolatingRebin-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/InvertMDDim-v1.rst b/docs/source/algorithms/InvertMDDim-v1.rst index eeb1dc83f56..e007c5c9601 100644 --- a/docs/source/algorithms/InvertMDDim-v1.rst +++ b/docs/source/algorithms/InvertMDDim-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/InvertMask-v1.rst b/docs/source/algorithms/InvertMask-v1.rst index 15441ddfb17..4f4d8ce2bdd 100644 --- a/docs/source/algorithms/InvertMask-v1.rst +++ b/docs/source/algorithms/InvertMask-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IqtFitMultiple-v1.rst b/docs/source/algorithms/IqtFitMultiple-v1.rst index 8f13a394d0d..6bbba0c5f27 100644 --- a/docs/source/algorithms/IqtFitMultiple-v1.rst +++ b/docs/source/algorithms/IqtFitMultiple-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/IqtFitSequential-v1.rst b/docs/source/algorithms/IqtFitSequential-v1.rst index 437d53abcad..6c62230170a 100644 --- a/docs/source/algorithms/IqtFitSequential-v1.rst +++ b/docs/source/algorithms/IqtFitSequential-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LRAutoReduction-v1.rst b/docs/source/algorithms/LRAutoReduction-v1.rst index 0ec12ae2ef3..7f8726567c2 100644 --- a/docs/source/algorithms/LRAutoReduction-v1.rst +++ b/docs/source/algorithms/LRAutoReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LRDirectBeamSort-v1.rst b/docs/source/algorithms/LRDirectBeamSort-v1.rst index 1fa9d386395..4b93e8c847f 100644 --- a/docs/source/algorithms/LRDirectBeamSort-v1.rst +++ b/docs/source/algorithms/LRDirectBeamSort-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LRPeakSelection-v1.rst b/docs/source/algorithms/LRPeakSelection-v1.rst index c295738b6f5..ec3e442da68 100644 --- a/docs/source/algorithms/LRPeakSelection-v1.rst +++ b/docs/source/algorithms/LRPeakSelection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LRPrimaryFraction-v1.rst b/docs/source/algorithms/LRPrimaryFraction-v1.rst index a3e47703b88..793948ac21b 100644 --- a/docs/source/algorithms/LRPrimaryFraction-v1.rst +++ b/docs/source/algorithms/LRPrimaryFraction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LRReflectivityOutput-v1.rst b/docs/source/algorithms/LRReflectivityOutput-v1.rst index dd826d0041a..ace259c22d1 100644 --- a/docs/source/algorithms/LRReflectivityOutput-v1.rst +++ b/docs/source/algorithms/LRReflectivityOutput-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LRScalingFactors-v1.rst b/docs/source/algorithms/LRScalingFactors-v1.rst index cb585ea7078..7b7f19534b2 100644 --- a/docs/source/algorithms/LRScalingFactors-v1.rst +++ b/docs/source/algorithms/LRScalingFactors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LRSubtractAverageBackground-v1.rst b/docs/source/algorithms/LRSubtractAverageBackground-v1.rst index 920fb7fb011..dc380f3d0ab 100644 --- a/docs/source/algorithms/LRSubtractAverageBackground-v1.rst +++ b/docs/source/algorithms/LRSubtractAverageBackground-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LeBailFit-v1.rst b/docs/source/algorithms/LeBailFit-v1.rst index f99d6824839..3cdafc2c941 100644 --- a/docs/source/algorithms/LeBailFit-v1.rst +++ b/docs/source/algorithms/LeBailFit-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LessThanMD-v1.rst b/docs/source/algorithms/LessThanMD-v1.rst index 380bfbe8846..d23afd077e2 100644 --- a/docs/source/algorithms/LessThanMD-v1.rst +++ b/docs/source/algorithms/LessThanMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LineProfile-v1.rst b/docs/source/algorithms/LineProfile-v1.rst index 7e6b73a9aca..001d49a0dba 100644 --- a/docs/source/algorithms/LineProfile-v1.rst +++ b/docs/source/algorithms/LineProfile-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LiquidsReflectometryReduction-v1.rst b/docs/source/algorithms/LiquidsReflectometryReduction-v1.rst index 16639389fdd..ffe35a7ac0d 100644 --- a/docs/source/algorithms/LiquidsReflectometryReduction-v1.rst +++ b/docs/source/algorithms/LiquidsReflectometryReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Load-v1.rst b/docs/source/algorithms/Load-v1.rst index 02ca8143598..6dc2e87c125 100644 --- a/docs/source/algorithms/Load-v1.rst +++ b/docs/source/algorithms/Load-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadAndMerge-v1.rst b/docs/source/algorithms/LoadAndMerge-v1.rst index 04ca1ab664c..bbc42f59fdd 100644 --- a/docs/source/algorithms/LoadAndMerge-v1.rst +++ b/docs/source/algorithms/LoadAndMerge-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadAscii-v1.rst b/docs/source/algorithms/LoadAscii-v1.rst index 9b7b2851204..46fe9904a6d 100644 --- a/docs/source/algorithms/LoadAscii-v1.rst +++ b/docs/source/algorithms/LoadAscii-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadAscii-v2.rst b/docs/source/algorithms/LoadAscii-v2.rst index 7060d3037ee..7420d024b07 100644 --- a/docs/source/algorithms/LoadAscii-v2.rst +++ b/docs/source/algorithms/LoadAscii-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadBBY-v1.rst b/docs/source/algorithms/LoadBBY-v1.rst index 09d00219fd5..7774d651ad4 100644 --- a/docs/source/algorithms/LoadBBY-v1.rst +++ b/docs/source/algorithms/LoadBBY-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadCIF-v1.rst b/docs/source/algorithms/LoadCIF-v1.rst index b92996f733f..7dd4c61516c 100644 --- a/docs/source/algorithms/LoadCIF-v1.rst +++ b/docs/source/algorithms/LoadCIF-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadCalFile-v1.rst b/docs/source/algorithms/LoadCalFile-v1.rst index 66e8c0a0fad..d96a583b525 100644 --- a/docs/source/algorithms/LoadCalFile-v1.rst +++ b/docs/source/algorithms/LoadCalFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadCanSAS1D-v1.rst b/docs/source/algorithms/LoadCanSAS1D-v1.rst index 67c40d640db..827e5ec4d7b 100644 --- a/docs/source/algorithms/LoadCanSAS1D-v1.rst +++ b/docs/source/algorithms/LoadCanSAS1D-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadCanSAS1D-v2.rst b/docs/source/algorithms/LoadCanSAS1D-v2.rst index 70e703c0341..94946cae452 100644 --- a/docs/source/algorithms/LoadCanSAS1D-v2.rst +++ b/docs/source/algorithms/LoadCanSAS1D-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadDNSLegacy-v1.rst b/docs/source/algorithms/LoadDNSLegacy-v1.rst index 4d55aa05bff..96aa684c782 100644 --- a/docs/source/algorithms/LoadDNSLegacy-v1.rst +++ b/docs/source/algorithms/LoadDNSLegacy-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadDaveGrp-v1.rst b/docs/source/algorithms/LoadDaveGrp-v1.rst index 355da06a843..bb13d04d66c 100644 --- a/docs/source/algorithms/LoadDaveGrp-v1.rst +++ b/docs/source/algorithms/LoadDaveGrp-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadDetectorInfo-v1.rst b/docs/source/algorithms/LoadDetectorInfo-v1.rst index 7a3545e0dbc..7fff57ebb66 100644 --- a/docs/source/algorithms/LoadDetectorInfo-v1.rst +++ b/docs/source/algorithms/LoadDetectorInfo-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadDetectorsGroupingFile-v1.rst b/docs/source/algorithms/LoadDetectorsGroupingFile-v1.rst index 8481ea8e301..d318557d986 100644 --- a/docs/source/algorithms/LoadDetectorsGroupingFile-v1.rst +++ b/docs/source/algorithms/LoadDetectorsGroupingFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadDiffCal-v1.rst b/docs/source/algorithms/LoadDiffCal-v1.rst index b2fc5741c14..b83edb746f3 100644 --- a/docs/source/algorithms/LoadDiffCal-v1.rst +++ b/docs/source/algorithms/LoadDiffCal-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadDspacemap-v1.rst b/docs/source/algorithms/LoadDspacemap-v1.rst index e92564e4930..e00b7562577 100644 --- a/docs/source/algorithms/LoadDspacemap-v1.rst +++ b/docs/source/algorithms/LoadDspacemap-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadEXED-v1.rst b/docs/source/algorithms/LoadEXED-v1.rst index 4682fdb07ff..3aa844d1bb8 100644 --- a/docs/source/algorithms/LoadEXED-v1.rst +++ b/docs/source/algorithms/LoadEXED-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadEmptyInstrument-v1.rst b/docs/source/algorithms/LoadEmptyInstrument-v1.rst index 16d29475666..7044a542d27 100644 --- a/docs/source/algorithms/LoadEmptyInstrument-v1.rst +++ b/docs/source/algorithms/LoadEmptyInstrument-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadEmptyVesuvio-v1.rst b/docs/source/algorithms/LoadEmptyVesuvio-v1.rst index 4b8909997c6..795ddea4ad7 100644 --- a/docs/source/algorithms/LoadEmptyVesuvio-v1.rst +++ b/docs/source/algorithms/LoadEmptyVesuvio-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadEventAndCompress-v1.rst b/docs/source/algorithms/LoadEventAndCompress-v1.rst index 7af29968e94..12e7da33071 100644 --- a/docs/source/algorithms/LoadEventAndCompress-v1.rst +++ b/docs/source/algorithms/LoadEventAndCompress-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadEventNexus-v1.rst b/docs/source/algorithms/LoadEventNexus-v1.rst index 06ac964a6a8..1fdbd426fdc 100644 --- a/docs/source/algorithms/LoadEventNexus-v1.rst +++ b/docs/source/algorithms/LoadEventNexus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadEventPreNexus-v2.rst b/docs/source/algorithms/LoadEventPreNexus-v2.rst index 9a27afe7943..9cbbe010eff 100644 --- a/docs/source/algorithms/LoadEventPreNexus-v2.rst +++ b/docs/source/algorithms/LoadEventPreNexus-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadFITS-v1.rst b/docs/source/algorithms/LoadFITS-v1.rst index fc1b672d2f3..fbd48295ac5 100644 --- a/docs/source/algorithms/LoadFITS-v1.rst +++ b/docs/source/algorithms/LoadFITS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadFlexiNexus-v1.rst b/docs/source/algorithms/LoadFlexiNexus-v1.rst index 4dede92da8d..061164de428 100644 --- a/docs/source/algorithms/LoadFlexiNexus-v1.rst +++ b/docs/source/algorithms/LoadFlexiNexus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadFullprofFile-v1.rst b/docs/source/algorithms/LoadFullprofFile-v1.rst index a3954d7bb30..1bd0a740c30 100644 --- a/docs/source/algorithms/LoadFullprofFile-v1.rst +++ b/docs/source/algorithms/LoadFullprofFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadFullprofResolution-v1.rst b/docs/source/algorithms/LoadFullprofResolution-v1.rst index 36fbfebb185..53081fe10c8 100644 --- a/docs/source/algorithms/LoadFullprofResolution-v1.rst +++ b/docs/source/algorithms/LoadFullprofResolution-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadGSASInstrumentFile-v1.rst b/docs/source/algorithms/LoadGSASInstrumentFile-v1.rst index 6d26c479f30..c42932baaeb 100644 --- a/docs/source/algorithms/LoadGSASInstrumentFile-v1.rst +++ b/docs/source/algorithms/LoadGSASInstrumentFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadGSS-v1.rst b/docs/source/algorithms/LoadGSS-v1.rst index 9b2162be728..025cc510df9 100644 --- a/docs/source/algorithms/LoadGSS-v1.rst +++ b/docs/source/algorithms/LoadGSS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadHKL-v1.rst b/docs/source/algorithms/LoadHKL-v1.rst index e772121e42e..6222531baef 100644 --- a/docs/source/algorithms/LoadHKL-v1.rst +++ b/docs/source/algorithms/LoadHKL-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -12,7 +12,7 @@ Description Loads an ASCII .hkl file to a PeaksWorkspace. HKL File Format -*************** +############### File has same format that works successfully in GSAS and SHELX from ISAW: diff --git a/docs/source/algorithms/LoadIDFFromNexus-v1.rst b/docs/source/algorithms/LoadIDFFromNexus-v1.rst index 09fdf94e69b..b707b491405 100644 --- a/docs/source/algorithms/LoadIDFFromNexus-v1.rst +++ b/docs/source/algorithms/LoadIDFFromNexus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadILLDiffraction-v1.rst b/docs/source/algorithms/LoadILLDiffraction-v1.rst index 95c3221834d..eae3c9c3926 100644 --- a/docs/source/algorithms/LoadILLDiffraction-v1.rst +++ b/docs/source/algorithms/LoadILLDiffraction-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadILLIndirect-v2.rst b/docs/source/algorithms/LoadILLIndirect-v2.rst index 9b4b44df190..43721433616 100644 --- a/docs/source/algorithms/LoadILLIndirect-v2.rst +++ b/docs/source/algorithms/LoadILLIndirect-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadILLPolarizationFactors-v1.rst b/docs/source/algorithms/LoadILLPolarizationFactors-v1.rst index 02ff134d610..60cfcc5cf33 100644 --- a/docs/source/algorithms/LoadILLPolarizationFactors-v1.rst +++ b/docs/source/algorithms/LoadILLPolarizationFactors-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadILLReflectometry-v1.rst b/docs/source/algorithms/LoadILLReflectometry-v1.rst index f3cf3ad31e7..c43ab4f05ba 100644 --- a/docs/source/algorithms/LoadILLReflectometry-v1.rst +++ b/docs/source/algorithms/LoadILLReflectometry-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadILLSANS-v1.rst b/docs/source/algorithms/LoadILLSANS-v1.rst index c0accafcb7f..2e51a0ba860 100644 --- a/docs/source/algorithms/LoadILLSANS-v1.rst +++ b/docs/source/algorithms/LoadILLSANS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadILLTOF-v2.rst b/docs/source/algorithms/LoadILLTOF-v2.rst index 6cac270c174..fb36d146be6 100644 --- a/docs/source/algorithms/LoadILLTOF-v2.rst +++ b/docs/source/algorithms/LoadILLTOF-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadISISNexus-v2.rst b/docs/source/algorithms/LoadISISNexus-v2.rst index 92d8cbe22f7..051bafc40f6 100644 --- a/docs/source/algorithms/LoadISISNexus-v2.rst +++ b/docs/source/algorithms/LoadISISNexus-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadInstrument-v1.rst b/docs/source/algorithms/LoadInstrument-v1.rst index 9bb17050731..742ede74498 100644 --- a/docs/source/algorithms/LoadInstrument-v1.rst +++ b/docs/source/algorithms/LoadInstrument-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadInstrumentFromNexus-v1.rst b/docs/source/algorithms/LoadInstrumentFromNexus-v1.rst index c7d47ac3c0d..d41423e0f7d 100644 --- a/docs/source/algorithms/LoadInstrumentFromNexus-v1.rst +++ b/docs/source/algorithms/LoadInstrumentFromNexus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadInstrumentFromRaw-v1.rst b/docs/source/algorithms/LoadInstrumentFromRaw-v1.rst index 8468aa33fd5..10277281419 100644 --- a/docs/source/algorithms/LoadInstrumentFromRaw-v1.rst +++ b/docs/source/algorithms/LoadInstrumentFromRaw-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadIsawDetCal-v1.rst b/docs/source/algorithms/LoadIsawDetCal-v1.rst index 39dc33620d6..65adcc7bab0 100644 --- a/docs/source/algorithms/LoadIsawDetCal-v1.rst +++ b/docs/source/algorithms/LoadIsawDetCal-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadIsawPeaks-v1.rst b/docs/source/algorithms/LoadIsawPeaks-v1.rst index 8a27cedbe85..754710cc558 100644 --- a/docs/source/algorithms/LoadIsawPeaks-v1.rst +++ b/docs/source/algorithms/LoadIsawPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadIsawSpectrum-v1.rst b/docs/source/algorithms/LoadIsawSpectrum-v1.rst index aa2b05caee8..a5fb4249857 100644 --- a/docs/source/algorithms/LoadIsawSpectrum-v1.rst +++ b/docs/source/algorithms/LoadIsawSpectrum-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadIsawUB-v1.rst b/docs/source/algorithms/LoadIsawUB-v1.rst index d0565e842f0..1112f519484 100644 --- a/docs/source/algorithms/LoadIsawUB-v1.rst +++ b/docs/source/algorithms/LoadIsawUB-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadLLB-v1.rst b/docs/source/algorithms/LoadLLB-v1.rst index 7fb60a344b9..6bf029c5a06 100644 --- a/docs/source/algorithms/LoadLLB-v1.rst +++ b/docs/source/algorithms/LoadLLB-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadLamp-v1.rst b/docs/source/algorithms/LoadLamp-v1.rst index d551753ff7a..ebcef6ad50a 100644 --- a/docs/source/algorithms/LoadLamp-v1.rst +++ b/docs/source/algorithms/LoadLamp-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadLiveData-v1.rst b/docs/source/algorithms/LoadLiveData-v1.rst index 2f0be8557dd..a8224c0e971 100644 --- a/docs/source/algorithms/LoadLiveData-v1.rst +++ b/docs/source/algorithms/LoadLiveData-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadLog-v1.rst b/docs/source/algorithms/LoadLog-v1.rst index 79315d77c3e..9dd0160c66b 100644 --- a/docs/source/algorithms/LoadLog-v1.rst +++ b/docs/source/algorithms/LoadLog-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadLogPropertyTable-v1.rst b/docs/source/algorithms/LoadLogPropertyTable-v1.rst index 11c227f673f..f34dde7c682 100644 --- a/docs/source/algorithms/LoadLogPropertyTable-v1.rst +++ b/docs/source/algorithms/LoadLogPropertyTable-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadMD-v1.rst b/docs/source/algorithms/LoadMD-v1.rst index add4525edef..377dd78987e 100644 --- a/docs/source/algorithms/LoadMD-v1.rst +++ b/docs/source/algorithms/LoadMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadMLZ-v1.rst b/docs/source/algorithms/LoadMLZ-v1.rst index fcbb25c2efc..8efb00dbc49 100644 --- a/docs/source/algorithms/LoadMLZ-v1.rst +++ b/docs/source/algorithms/LoadMLZ-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadMappingTable-v1.rst b/docs/source/algorithms/LoadMappingTable-v1.rst index 694ade0b836..f485e532664 100644 --- a/docs/source/algorithms/LoadMappingTable-v1.rst +++ b/docs/source/algorithms/LoadMappingTable-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadMask-v1.rst b/docs/source/algorithms/LoadMask-v1.rst index 223fcea04d3..572b110ace9 100644 --- a/docs/source/algorithms/LoadMask-v1.rst +++ b/docs/source/algorithms/LoadMask-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadMcStas-v1.rst b/docs/source/algorithms/LoadMcStas-v1.rst index b042f4d7742..3039803b2e5 100644 --- a/docs/source/algorithms/LoadMcStas-v1.rst +++ b/docs/source/algorithms/LoadMcStas-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadMcStasNexus-v1.rst b/docs/source/algorithms/LoadMcStasNexus-v1.rst index 230d0405dbb..02422e3aa85 100644 --- a/docs/source/algorithms/LoadMcStasNexus-v1.rst +++ b/docs/source/algorithms/LoadMcStasNexus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadMultipleGSS-v1.rst b/docs/source/algorithms/LoadMultipleGSS-v1.rst index 7aab060dd3d..4e3caa68595 100644 --- a/docs/source/algorithms/LoadMultipleGSS-v1.rst +++ b/docs/source/algorithms/LoadMultipleGSS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadMuonLog-v1.rst b/docs/source/algorithms/LoadMuonLog-v1.rst index e089716be96..b9116c5c531 100644 --- a/docs/source/algorithms/LoadMuonLog-v1.rst +++ b/docs/source/algorithms/LoadMuonLog-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadMuonNexus-v1.rst b/docs/source/algorithms/LoadMuonNexus-v1.rst index a798064a45b..489c79d9e72 100644 --- a/docs/source/algorithms/LoadMuonNexus-v1.rst +++ b/docs/source/algorithms/LoadMuonNexus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadMuonNexus-v2.rst b/docs/source/algorithms/LoadMuonNexus-v2.rst index a36ba6e4689..81fbbc40660 100644 --- a/docs/source/algorithms/LoadMuonNexus-v2.rst +++ b/docs/source/algorithms/LoadMuonNexus-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadNMoldyn3Ascii-v1.rst b/docs/source/algorithms/LoadNMoldyn3Ascii-v1.rst index 8d06bedd116..588dbb4aedd 100644 --- a/docs/source/algorithms/LoadNMoldyn3Ascii-v1.rst +++ b/docs/source/algorithms/LoadNMoldyn3Ascii-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadNMoldyn4Ascii-v1.rst b/docs/source/algorithms/LoadNMoldyn4Ascii-v1.rst index 72179b71098..3c7b6c43857 100644 --- a/docs/source/algorithms/LoadNMoldyn4Ascii-v1.rst +++ b/docs/source/algorithms/LoadNMoldyn4Ascii-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadNMoldyn4Ascii1D-v1.rst b/docs/source/algorithms/LoadNMoldyn4Ascii1D-v1.rst index 033966b156f..619825c4b5f 100644 --- a/docs/source/algorithms/LoadNMoldyn4Ascii1D-v1.rst +++ b/docs/source/algorithms/LoadNMoldyn4Ascii1D-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadNXSPE-v1.rst b/docs/source/algorithms/LoadNXSPE-v1.rst index 97930210ae7..3837d2d616c 100644 --- a/docs/source/algorithms/LoadNXSPE-v1.rst +++ b/docs/source/algorithms/LoadNXSPE-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadNXcanSAS-v1.rst b/docs/source/algorithms/LoadNXcanSAS-v1.rst index 8da99f48766..b0264acbbc7 100644 --- a/docs/source/algorithms/LoadNXcanSAS-v1.rst +++ b/docs/source/algorithms/LoadNXcanSAS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadNexus-v1.rst b/docs/source/algorithms/LoadNexus-v1.rst index 5ab2681bb8c..3a943ba388b 100644 --- a/docs/source/algorithms/LoadNexus-v1.rst +++ b/docs/source/algorithms/LoadNexus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadNexusLogs-v1.rst b/docs/source/algorithms/LoadNexusLogs-v1.rst index fd20fc6c673..b04d523dd59 100644 --- a/docs/source/algorithms/LoadNexusLogs-v1.rst +++ b/docs/source/algorithms/LoadNexusLogs-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadNexusMonitors-v1.rst b/docs/source/algorithms/LoadNexusMonitors-v1.rst index 8e8a3f6dfa2..1108b568428 100644 --- a/docs/source/algorithms/LoadNexusMonitors-v1.rst +++ b/docs/source/algorithms/LoadNexusMonitors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadNexusMonitors-v2.rst b/docs/source/algorithms/LoadNexusMonitors-v2.rst index 9a6fda08a2f..d115c204cc9 100644 --- a/docs/source/algorithms/LoadNexusMonitors-v2.rst +++ b/docs/source/algorithms/LoadNexusMonitors-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -24,7 +24,7 @@ workspace. As a side-effect of the fix, the contained individual workspaces for each of the periods are named slightly differently. Event monitor and histogram monitor -=================================== +################################### There are two types of monitors, event monitors and histograms monitors. Both of them are of class *NXmonitor* in NeXus file. @@ -39,14 +39,14 @@ Both of them are of class *NXmonitor* in NeXus file. * period_index ISIS event monitor -================== +################## ISIS monitor of event mode may contain entry *data*. In this case, the monitor of event mode can be loaded in histogram mode. Load NeXus file containing both event monitor and histogram monitor -=================================================================== +################################################################### There are a few use cases to load monitor's data if the NeXus file has coexisting event monitors and histogram monitors. diff --git a/docs/source/algorithms/LoadNexusProcessed-v1.rst b/docs/source/algorithms/LoadNexusProcessed-v1.rst index d807be0ba03..4ee1808037b 100644 --- a/docs/source/algorithms/LoadNexusProcessed-v1.rst +++ b/docs/source/algorithms/LoadNexusProcessed-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadPDFgetNFile-v1.rst b/docs/source/algorithms/LoadPDFgetNFile-v1.rst index fa232ab4999..227fe09f03d 100644 --- a/docs/source/algorithms/LoadPDFgetNFile-v1.rst +++ b/docs/source/algorithms/LoadPDFgetNFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadParameterFile-v1.rst b/docs/source/algorithms/LoadParameterFile-v1.rst index fda8e1da562..17836f3b9ca 100644 --- a/docs/source/algorithms/LoadParameterFile-v1.rst +++ b/docs/source/algorithms/LoadParameterFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadPreNexus-v1.rst b/docs/source/algorithms/LoadPreNexus-v1.rst index b78e915c4ee..23c4a16fe12 100644 --- a/docs/source/algorithms/LoadPreNexus-v1.rst +++ b/docs/source/algorithms/LoadPreNexus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadPreNexusLive-v1.rst b/docs/source/algorithms/LoadPreNexusLive-v1.rst index 674c3b5a99d..5e5ee718389 100644 --- a/docs/source/algorithms/LoadPreNexusLive-v1.rst +++ b/docs/source/algorithms/LoadPreNexusLive-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadPreNexusMonitors-v1.rst b/docs/source/algorithms/LoadPreNexusMonitors-v1.rst index 4f45a04ca08..80292f10472 100644 --- a/docs/source/algorithms/LoadPreNexusMonitors-v1.rst +++ b/docs/source/algorithms/LoadPreNexusMonitors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadQKK-v1.rst b/docs/source/algorithms/LoadQKK-v1.rst index 92721016f79..9942142869c 100644 --- a/docs/source/algorithms/LoadQKK-v1.rst +++ b/docs/source/algorithms/LoadQKK-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadRKH-v1.rst b/docs/source/algorithms/LoadRKH-v1.rst index 08d8e4c84ae..ad8cbce7608 100644 --- a/docs/source/algorithms/LoadRKH-v1.rst +++ b/docs/source/algorithms/LoadRKH-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadRaw-v3.rst b/docs/source/algorithms/LoadRaw-v3.rst index 4a67346b1de..7ccd96f0ad8 100644 --- a/docs/source/algorithms/LoadRaw-v3.rst +++ b/docs/source/algorithms/LoadRaw-v3.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadRawBin0-v1.rst b/docs/source/algorithms/LoadRawBin0-v1.rst index ac383e40ef0..277cfb7f18b 100644 --- a/docs/source/algorithms/LoadRawBin0-v1.rst +++ b/docs/source/algorithms/LoadRawBin0-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadRawSpectrum0-v1.rst b/docs/source/algorithms/LoadRawSpectrum0-v1.rst index 93003f14ec4..6ec923a6a92 100644 --- a/docs/source/algorithms/LoadRawSpectrum0-v1.rst +++ b/docs/source/algorithms/LoadRawSpectrum0-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSESANS-v1.rst b/docs/source/algorithms/LoadSESANS-v1.rst index eb1ca8b16b0..6d6126ae602 100644 --- a/docs/source/algorithms/LoadSESANS-v1.rst +++ b/docs/source/algorithms/LoadSESANS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSINQ-v1.rst b/docs/source/algorithms/LoadSINQ-v1.rst index 87fbda9bf56..9fb18dd5a80 100644 --- a/docs/source/algorithms/LoadSINQ-v1.rst +++ b/docs/source/algorithms/LoadSINQ-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSINQFile-v1.rst b/docs/source/algorithms/LoadSINQFile-v1.rst index 44fce4dd38f..773de1cbf46 100644 --- a/docs/source/algorithms/LoadSINQFile-v1.rst +++ b/docs/source/algorithms/LoadSINQFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSINQFocus-v1.rst b/docs/source/algorithms/LoadSINQFocus-v1.rst index c9693e0b067..91edd2507ee 100644 --- a/docs/source/algorithms/LoadSINQFocus-v1.rst +++ b/docs/source/algorithms/LoadSINQFocus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSNSspec-v1.rst b/docs/source/algorithms/LoadSNSspec-v1.rst index 1f5ccfbd558..0d356d3874d 100644 --- a/docs/source/algorithms/LoadSNSspec-v1.rst +++ b/docs/source/algorithms/LoadSNSspec-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSPE-v1.rst b/docs/source/algorithms/LoadSPE-v1.rst index cd8acb3fcba..3f3a7f8595c 100644 --- a/docs/source/algorithms/LoadSPE-v1.rst +++ b/docs/source/algorithms/LoadSPE-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSQW-v1.rst b/docs/source/algorithms/LoadSQW-v1.rst index 2420f3498c1..c2ef22d9fcd 100644 --- a/docs/source/algorithms/LoadSQW-v1.rst +++ b/docs/source/algorithms/LoadSQW-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSQW-v2.rst b/docs/source/algorithms/LoadSQW-v2.rst index f0a40db3c26..6651f7cef59 100644 --- a/docs/source/algorithms/LoadSQW-v2.rst +++ b/docs/source/algorithms/LoadSQW-v2.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSampleDetailsFromRaw-v1.rst b/docs/source/algorithms/LoadSampleDetailsFromRaw-v1.rst index 2b92c0b7005..9f5f4aea40c 100644 --- a/docs/source/algorithms/LoadSampleDetailsFromRaw-v1.rst +++ b/docs/source/algorithms/LoadSampleDetailsFromRaw-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSassena-v1.rst b/docs/source/algorithms/LoadSassena-v1.rst index 0680ea202de..a8978dffa8b 100644 --- a/docs/source/algorithms/LoadSassena-v1.rst +++ b/docs/source/algorithms/LoadSassena-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSpec-v1.rst b/docs/source/algorithms/LoadSpec-v1.rst index b37969d58cf..d846c9b0693 100644 --- a/docs/source/algorithms/LoadSpec-v1.rst +++ b/docs/source/algorithms/LoadSpec-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSpice2D-v1.rst b/docs/source/algorithms/LoadSpice2D-v1.rst index 857c87654c0..d5d607ffefa 100644 --- a/docs/source/algorithms/LoadSpice2D-v1.rst +++ b/docs/source/algorithms/LoadSpice2D-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSpiceAscii-v1.rst b/docs/source/algorithms/LoadSpiceAscii-v1.rst index 93662c3b272..6bb9f483ea1 100644 --- a/docs/source/algorithms/LoadSpiceAscii-v1.rst +++ b/docs/source/algorithms/LoadSpiceAscii-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSpiceXML2DDet-v1.rst b/docs/source/algorithms/LoadSpiceXML2DDet-v1.rst index 05c83f51010..64f4f0d70bc 100644 --- a/docs/source/algorithms/LoadSpiceXML2DDet-v1.rst +++ b/docs/source/algorithms/LoadSpiceXML2DDet-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadSwans-v1.rst b/docs/source/algorithms/LoadSwans-v1.rst index 4f288ccee20..839f640e4e3 100644 --- a/docs/source/algorithms/LoadSwans-v1.rst +++ b/docs/source/algorithms/LoadSwans-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadTBL-v1.rst b/docs/source/algorithms/LoadTBL-v1.rst index d0f355b638d..9951cb77d57 100644 --- a/docs/source/algorithms/LoadTBL-v1.rst +++ b/docs/source/algorithms/LoadTBL-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadTOFRawNexus-v1.rst b/docs/source/algorithms/LoadTOFRawNexus-v1.rst index c9709cb383d..bc902c6f2fb 100644 --- a/docs/source/algorithms/LoadTOFRawNexus-v1.rst +++ b/docs/source/algorithms/LoadTOFRawNexus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadVTK-v1.rst b/docs/source/algorithms/LoadVTK-v1.rst index 1ab52491815..d047f11c134 100644 --- a/docs/source/algorithms/LoadVTK-v1.rst +++ b/docs/source/algorithms/LoadVTK-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadVesuvio-v1.rst b/docs/source/algorithms/LoadVesuvio-v1.rst index 9adc889a649..a9953c686f4 100644 --- a/docs/source/algorithms/LoadVesuvio-v1.rst +++ b/docs/source/algorithms/LoadVesuvio-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadVisionElasticBS-v1.rst b/docs/source/algorithms/LoadVisionElasticBS-v1.rst index 2767b3a719d..0ee9821ec31 100644 --- a/docs/source/algorithms/LoadVisionElasticBS-v1.rst +++ b/docs/source/algorithms/LoadVisionElasticBS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadVisionElasticEQ-v1.rst b/docs/source/algorithms/LoadVisionElasticEQ-v1.rst index bb175164fc2..f7b468e4737 100644 --- a/docs/source/algorithms/LoadVisionElasticEQ-v1.rst +++ b/docs/source/algorithms/LoadVisionElasticEQ-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadVisionInelastic-v1.rst b/docs/source/algorithms/LoadVisionInelastic-v1.rst index 30a39cdd2ce..0d063c9125c 100644 --- a/docs/source/algorithms/LoadVisionInelastic-v1.rst +++ b/docs/source/algorithms/LoadVisionInelastic-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LoadVulcanCalFile-v1.rst b/docs/source/algorithms/LoadVulcanCalFile-v1.rst index 0a10aab6597..993e081745b 100644 --- a/docs/source/algorithms/LoadVulcanCalFile-v1.rst +++ b/docs/source/algorithms/LoadVulcanCalFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -17,7 +17,7 @@ By this algorithm, Vulcan's calibration file can be converted to the standard calibration file for SNSPowderReduction. Detector offset file -==================== +#################### There are :math:`62500` (:math:`50\times 1250`) rows in the offset file. In each row, the first value is the pixel ID; and the second is inner-module offset. @@ -35,14 +35,14 @@ from 0. - Line :math:`1250\times M_i + 1249`: pixel ID, inter bank correction Bad pixel file -============== +############## In bad pixel file, each line contains one and only one integer corresponding to the detector ID of a bad pixel. The bad pixels will be masked in the output MaskWorkspace. Conversion from offset in TOF to d-spacing -========================================== +########################################## With VULCAN's offsets in TOF, the calibration is done as the following. diff --git a/docs/source/algorithms/LoadWAND-v1.rst b/docs/source/algorithms/LoadWAND-v1.rst index 8d075bc5ef6..d5cd3e1a2db 100644 --- a/docs/source/algorithms/LoadWAND-v1.rst +++ b/docs/source/algorithms/LoadWAND-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Logarithm-v1.rst b/docs/source/algorithms/Logarithm-v1.rst index f73ddf933f3..b4293fb2fd1 100644 --- a/docs/source/algorithms/Logarithm-v1.rst +++ b/docs/source/algorithms/Logarithm-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LogarithmMD-v1.rst b/docs/source/algorithms/LogarithmMD-v1.rst index 8e569665a65..5164eabb242 100644 --- a/docs/source/algorithms/LogarithmMD-v1.rst +++ b/docs/source/algorithms/LogarithmMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/LorentzCorrection-v1.rst b/docs/source/algorithms/LorentzCorrection-v1.rst index 509cdbc7324..abd1e94191e 100644 --- a/docs/source/algorithms/LorentzCorrection-v1.rst +++ b/docs/source/algorithms/LorentzCorrection-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MDHistoToWorkspace2D-v1.rst b/docs/source/algorithms/MDHistoToWorkspace2D-v1.rst index 90c4d1cd41d..45ee32e6b9f 100644 --- a/docs/source/algorithms/MDHistoToWorkspace2D-v1.rst +++ b/docs/source/algorithms/MDHistoToWorkspace2D-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MDNormDirectSC-v1.rst b/docs/source/algorithms/MDNormDirectSC-v1.rst index c47842c280d..353dbdbe8a1 100644 --- a/docs/source/algorithms/MDNormDirectSC-v1.rst +++ b/docs/source/algorithms/MDNormDirectSC-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MDNormSCD-v1.rst b/docs/source/algorithms/MDNormSCD-v1.rst index c54e1efe10c..f99be5cb759 100644 --- a/docs/source/algorithms/MDNormSCD-v1.rst +++ b/docs/source/algorithms/MDNormSCD-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MDNormSCDPreprocessIncoherent-v1.rst b/docs/source/algorithms/MDNormSCDPreprocessIncoherent-v1.rst index 221ddcfbb61..3b0bc08dc90 100644 --- a/docs/source/algorithms/MDNormSCDPreprocessIncoherent-v1.rst +++ b/docs/source/algorithms/MDNormSCDPreprocessIncoherent-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MRFilterCrossSections-v1.rst b/docs/source/algorithms/MRFilterCrossSections-v1.rst index 3f214516448..75c7202df0c 100644 --- a/docs/source/algorithms/MRFilterCrossSections-v1.rst +++ b/docs/source/algorithms/MRFilterCrossSections-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MRInspectData-v1.rst b/docs/source/algorithms/MRInspectData-v1.rst index 657aab1595c..6fbd4f2e54a 100644 --- a/docs/source/algorithms/MRInspectData-v1.rst +++ b/docs/source/algorithms/MRInspectData-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MSDFit-v1.rst b/docs/source/algorithms/MSDFit-v1.rst index 96907467e77..f7b51e2cda4 100644 --- a/docs/source/algorithms/MSDFit-v1.rst +++ b/docs/source/algorithms/MSDFit-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MagFormFactorCorrection-v1.rst b/docs/source/algorithms/MagFormFactorCorrection-v1.rst index 3e27e393790..608b9cac232 100644 --- a/docs/source/algorithms/MagFormFactorCorrection-v1.rst +++ b/docs/source/algorithms/MagFormFactorCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MaskAngle-v1.rst b/docs/source/algorithms/MaskAngle-v1.rst index 0384c1e1da6..f981b9458f7 100644 --- a/docs/source/algorithms/MaskAngle-v1.rst +++ b/docs/source/algorithms/MaskAngle-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MaskBTP-v1.rst b/docs/source/algorithms/MaskBTP-v1.rst index 611797be603..bde4c6c2f85 100644 --- a/docs/source/algorithms/MaskBTP-v1.rst +++ b/docs/source/algorithms/MaskBTP-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MaskBins-v1.rst b/docs/source/algorithms/MaskBins-v1.rst index cbdeb1a00b1..9af7cb8ee3d 100644 --- a/docs/source/algorithms/MaskBins-v1.rst +++ b/docs/source/algorithms/MaskBins-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MaskBinsFromTable-v1.rst b/docs/source/algorithms/MaskBinsFromTable-v1.rst index 8ee464a6408..a83f9e89e42 100644 --- a/docs/source/algorithms/MaskBinsFromTable-v1.rst +++ b/docs/source/algorithms/MaskBinsFromTable-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MaskDetectors-v1.rst b/docs/source/algorithms/MaskDetectors-v1.rst index b22bb7a85ab..47ffae9c3c3 100644 --- a/docs/source/algorithms/MaskDetectors-v1.rst +++ b/docs/source/algorithms/MaskDetectors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MaskDetectorsIf-v1.rst b/docs/source/algorithms/MaskDetectorsIf-v1.rst index 276b40f34ea..a70292d2d40 100644 --- a/docs/source/algorithms/MaskDetectorsIf-v1.rst +++ b/docs/source/algorithms/MaskDetectorsIf-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MaskDetectorsInShape-v1.rst b/docs/source/algorithms/MaskDetectorsInShape-v1.rst index 109d854381e..8dbcc0d049a 100644 --- a/docs/source/algorithms/MaskDetectorsInShape-v1.rst +++ b/docs/source/algorithms/MaskDetectorsInShape-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MaskInstrument-v1.rst b/docs/source/algorithms/MaskInstrument-v1.rst index 5fbf7287866..b15ca478781 100644 --- a/docs/source/algorithms/MaskInstrument-v1.rst +++ b/docs/source/algorithms/MaskInstrument-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MaskMD-v1.rst b/docs/source/algorithms/MaskMD-v1.rst index d3b5086665f..6bb22cb9da5 100644 --- a/docs/source/algorithms/MaskMD-v1.rst +++ b/docs/source/algorithms/MaskMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MaskPeaksWorkspace-v1.rst b/docs/source/algorithms/MaskPeaksWorkspace-v1.rst index b771d01ddbd..5040e4f1f20 100644 --- a/docs/source/algorithms/MaskPeaksWorkspace-v1.rst +++ b/docs/source/algorithms/MaskPeaksWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MaskSpectra-v1.rst b/docs/source/algorithms/MaskSpectra-v1.rst index d7f8ada91ec..b234da9e4ff 100644 --- a/docs/source/algorithms/MaskSpectra-v1.rst +++ b/docs/source/algorithms/MaskSpectra-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MaskWorkspaceToCalFile-v1.rst b/docs/source/algorithms/MaskWorkspaceToCalFile-v1.rst index 11682c79abf..74dd984691c 100644 --- a/docs/source/algorithms/MaskWorkspaceToCalFile-v1.rst +++ b/docs/source/algorithms/MaskWorkspaceToCalFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MatchPeaks-v1.rst b/docs/source/algorithms/MatchPeaks-v1.rst index d245e56808a..c1fe7f9c15d 100644 --- a/docs/source/algorithms/MatchPeaks-v1.rst +++ b/docs/source/algorithms/MatchPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Max-v1.rst b/docs/source/algorithms/Max-v1.rst index e0b69bbb7ef..3cf69b9415d 100644 --- a/docs/source/algorithms/Max-v1.rst +++ b/docs/source/algorithms/Max-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MaxEnt-v1.rst b/docs/source/algorithms/MaxEnt-v1.rst index 1db090ec069..ffcb57b43c6 100644 --- a/docs/source/algorithms/MaxEnt-v1.rst +++ b/docs/source/algorithms/MaxEnt-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -100,33 +100,33 @@ the output workspaces whether the algorithm was evolving towards the correct sol On the other hand, the user must always check the validity of the solution by inspecting *EvolChi* and *EvolAngle*, whose values will be set to zero once the true maximum entropy solution is found. -.. table:: Table 1. Output workspaces for a real input workspace with M histograms and N bins +.. table:: Table 1. Output workspaces for a real input workspace with M histograms and N bins, taking J iterations. +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Workspace | Number of histograms | Number of bins | Description | +===================+==============================+================+====================================================================================================================================================================================================================================================================================================================+ - | EvolChi | M | MaxIterations | Evolution of :math:`\chi^2` until the solution is found. Then all values are set to zero. | + | EvolChi | M | J | For spectrum :math:`k` in the input workspace, evolution of :math:`\chi^2` until the solution is found | +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - | EvolAngle | M | MaxIterations | Evolution of the angle between :math:`\nabla S` and :math:`\nabla \chi^2`, until the solution is found. Then all values are set to zero. | + | EvolAngle | M | J | For spectrum :math:`k` in the input workspace, evolution of the angle between :math:`\nabla S` and :math:`\nabla \chi^2`, until the solution is found | +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - | ReconstructedImage| 2M | N | For spectrum :math:`s` in the input workspace, the reconstructed image is stored in spectra :math:`s` (real part) and :math:`s+M` (imaginary part) | + | ReconstructedImage| 2M | N | For spectrum :math:`k` in the input workspace, the reconstructed image is stored in spectra :math:`k` (real part) and :math:`k+M` (imaginary part) | +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - | ReconstructedData | 2M | N | For spectrum :math:`s` in the input workspace, the reconstructed data are stored in spectrum :math:`s` (real part) and :math:`s+M` (imaginary part). Note that although the input is real, the imaginary part is recorded for debugging purposes, it should be zero for all data points. | + | ReconstructedData | 2M | N | For spectrum :math:`k` in the input workspace, the reconstructed data are stored in spectrum :math:`k` (real part) and :math:`k+M` (imaginary part). Note that although the input is real, the imaginary part is recorded for debugging purposes, it should be zero for all data points. | +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -.. table:: Table 2. Output workspaces for a complex input workspace with 2M histograms and N bins. +.. table:: Table 2. Output workspaces for a complex input workspace with 2M histograms and N bins, taking J iterations. - +-------------------+------------------------------+----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+ - | Workspace | Number of histograms | Number of bins | Description | - +===================+==============================+================+============================================================================================================================================================+ - | EvolChi | M | MaxIterations | Evolution of :math:`\chi^2` until the solution is found. Then all values are set to zero. | - +-------------------+------------------------------+----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+ - | EvolAngle | M | MaxIterations | Evolution of the angle between :math:`\nabla S` and :math:`\nabla \chi^2`, until the solution is found. Then all values are set to zero. | - +-------------------+------------------------------+----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+ - | ReconstructedImage| 2M | :math:`N` | For spectrum :math:`(s, s+M)` in the input workspace, the reconstructed image is stored in spectra :math:`s` (real part) and :math:`s+M` (imaginary part) | - +-------------------+------------------------------+----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+ - | ReconstructedData | 2M | :math:`N` | For spectrum :math:`(s, s+M)` in the input workspace, the reconstructed data are stored in spectra :math:`s` (real part) and :math:`s+M` (imaginary part) | - +-------------------+------------------------------+----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ + | Workspace | Number of histograms | Number of bins | Description | + +===================+==============================+================+==============================================================================================================================================================+ + | EvolChi | M | J | For spectrum :math:`(k, k+M)` in the input workspace, evolution of :math:`\chi^2` until the solution is found | + +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ + | EvolAngle | M | J | For spectrum :math:`(k, k+M)` in the input workspace, evolution of the angle between :math:`\nabla S` and :math:`\nabla \chi^2`, until the solution is found | + +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ + | ReconstructedImage| 2M | :math:`N` | For spectrum :math:`(k, k+M)` in the input workspace, the reconstructed image is stored in spectra :math:`k` (real part) and :math:`k+M` (imaginary part) | + +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ + | ReconstructedData | 2M | :math:`N` | For spectrum :math:`(k, k+M)` in the input workspace, the reconstructed data are stored in spectra :math:`k` (real part) and :math:`k+M` (imaginary part) | + +-------------------+------------------------------+----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ Usage ----- @@ -380,6 +380,75 @@ where the first one refers to the real part of the entropy and the second one to about the image is available, as trying to reconstruct images that are inherently complex discarding the imaginary part will prevent the algorithm from converging. If the image is known to be real this property can be safely set to *False*. +Complex Data +------------ +If the input property "ComplexData* is set to *True*, the algorithm will assume complex data for the calculations with all the +real parts listed before all the imaginary parts. This means that if you have workspaces where the imaginary part immediately +follow the real part, such workspaces cannot be combined by using the :ref:`algm-AppendSpectra` algorithm because the resulting +output will not order the real and imaginary parts corrected as needed for this algorithm. The following usage example +shows how to combine two workspaces with complex data. + +.. testcode:: ExComplexData + + from math import pi, sin, cos + from random import random, seed + seed(0) + # Create complex data for a workspace + X = [] + YRe = [] + YIm = [] + E = [] + N = 200 + w = 3 + for i in range(0,N): + x = 2*pi*i/N + X.append(x) + YRe.append(cos(w*x)+(random()-0.5)*0.3) + YIm.append(sin(w*x)+(random()-0.5)*0.3) + E.append(0.1) + + seed(0) + # Create complex data for a second workspace + X2 = [] + YRe2 = [] + YIm2 = [] + E2 = [] + N2 = 200 + w2 = 4 + for i in range(0,N2): + x = 2*pi*i/N2 + X2.append(x) + YRe2.append(cos(w2*x)+(random()-0.5)*0.3) + YIm2.append(sin(w2*x)+(random()-0.5)*0.3) + E2.append(0.5) + + # Create two workspaces of one spectrum each + CreateWorkspace(OutputWorkspace='ws1',DataX=X+X,DataY=YRe+YIm,DataE=E+E,NSpec=2) + evolChiP, evolAngleP, imageP, dataP = MaxEnt(InputWorkspace='ws1', ComplexData=True, A=0.001, PositiveImage=True) + + print ("Number of iterations dataset1 separate: "+str( len(evolAngleP.readX(0)))) + + CreateWorkspace(OutputWorkspace='ws2',DataX=X2+X2,DataY=YRe2+YIm2,DataE=E2+E2,NSpec=2) + evolChiP2, evolAngleP2, imageP2, dataP2 = MaxEnt(InputWorkspace='ws2', ComplexData=True, A=0.001, PositiveImage=True) + + print ("Number of iterations dataset2 separate: "+str( len(evolAngleP2.readX(0)))) + + # Combine the two workspaces + CreateWorkspace(OutputWorkspace='wsCombined',DataX=X+X2+X+X2,DataY=YRe+YRe2+YIm+YIm2,DataE=E+E2+E+E2,NSpec=4) + evolChiC, evolAngleC, imageC, dataC = MaxEnt(InputWorkspace='wsCombined', ComplexData=True, A=0.001, PositiveImage=True) + + print ("Number of iterations dataset1 combined: "+str( len(evolAngleC.readX(0)))) + print ("Number of iterations dataset2 combined: "+str( len(evolAngleC.readX(1)))) + +Output: + +.. testoutput:: ExComplexData + + Number of iterations dataset1 separate: 11 + Number of iterations dataset2 separate: 7 + Number of iterations dataset1 combined: 11 + Number of iterations dataset2 combined: 7 + Increasing the number of points in the image -------------------------------------------- diff --git a/docs/source/algorithms/MaxMin-v1.rst b/docs/source/algorithms/MaxMin-v1.rst index 39961f5687b..8e335fd3a1d 100644 --- a/docs/source/algorithms/MaxMin-v1.rst +++ b/docs/source/algorithms/MaxMin-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MayersSampleCorrection-v1.rst b/docs/source/algorithms/MayersSampleCorrection-v1.rst index 7a1c489f293..a2163c2834e 100644 --- a/docs/source/algorithms/MayersSampleCorrection-v1.rst +++ b/docs/source/algorithms/MayersSampleCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Mean-v1.rst b/docs/source/algorithms/Mean-v1.rst index b73567b1784..d3452b87f5a 100644 --- a/docs/source/algorithms/Mean-v1.rst +++ b/docs/source/algorithms/Mean-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MedianBinWidth-v1.rst b/docs/source/algorithms/MedianBinWidth-v1.rst index 9198e8ed0c9..6d51bb1690a 100644 --- a/docs/source/algorithms/MedianBinWidth-v1.rst +++ b/docs/source/algorithms/MedianBinWidth-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MedianDetectorTest-v1.rst b/docs/source/algorithms/MedianDetectorTest-v1.rst index a995af4766e..dd467de839c 100644 --- a/docs/source/algorithms/MedianDetectorTest-v1.rst +++ b/docs/source/algorithms/MedianDetectorTest-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MergeCalFiles-v1.rst b/docs/source/algorithms/MergeCalFiles-v1.rst index 9a41a8f9224..410472900e8 100644 --- a/docs/source/algorithms/MergeCalFiles-v1.rst +++ b/docs/source/algorithms/MergeCalFiles-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MergeLogs-v1.rst b/docs/source/algorithms/MergeLogs-v1.rst index e4b257a2df5..f10702f4eac 100644 --- a/docs/source/algorithms/MergeLogs-v1.rst +++ b/docs/source/algorithms/MergeLogs-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MergeMD-v1.rst b/docs/source/algorithms/MergeMD-v1.rst index 2acf36e1fe8..263470105bb 100644 --- a/docs/source/algorithms/MergeMD-v1.rst +++ b/docs/source/algorithms/MergeMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MergeMDFiles-v1.rst b/docs/source/algorithms/MergeMDFiles-v1.rst index bbb7fa66d1c..eb383fc1db5 100644 --- a/docs/source/algorithms/MergeMDFiles-v1.rst +++ b/docs/source/algorithms/MergeMDFiles-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MergeRuns-v1.rst b/docs/source/algorithms/MergeRuns-v1.rst index 1ff0fbaf6a3..1c41b77e816 100644 --- a/docs/source/algorithms/MergeRuns-v1.rst +++ b/docs/source/algorithms/MergeRuns-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Min-v1.rst b/docs/source/algorithms/Min-v1.rst index 04328af539f..d36da60edf2 100644 --- a/docs/source/algorithms/Min-v1.rst +++ b/docs/source/algorithms/Min-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Minus-v1.rst b/docs/source/algorithms/Minus-v1.rst index 27d3ff7dc7f..77c371c156a 100644 --- a/docs/source/algorithms/Minus-v1.rst +++ b/docs/source/algorithms/Minus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MinusMD-v1.rst b/docs/source/algorithms/MinusMD-v1.rst index df468c76296..d55bb27197c 100644 --- a/docs/source/algorithms/MinusMD-v1.rst +++ b/docs/source/algorithms/MinusMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ModeratorTzero-v1.rst b/docs/source/algorithms/ModeratorTzero-v1.rst index 7ec77175e2a..b03a405bd4b 100644 --- a/docs/source/algorithms/ModeratorTzero-v1.rst +++ b/docs/source/algorithms/ModeratorTzero-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ModeratorTzeroLinear-v1.rst b/docs/source/algorithms/ModeratorTzeroLinear-v1.rst index f2352550059..7684fa4be21 100644 --- a/docs/source/algorithms/ModeratorTzeroLinear-v1.rst +++ b/docs/source/algorithms/ModeratorTzeroLinear-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ModifyDetectorDotDatFile-v1.rst b/docs/source/algorithms/ModifyDetectorDotDatFile-v1.rst index 58aef3d2ae2..0df84923b53 100644 --- a/docs/source/algorithms/ModifyDetectorDotDatFile-v1.rst +++ b/docs/source/algorithms/ModifyDetectorDotDatFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MolDyn-v1.rst b/docs/source/algorithms/MolDyn-v1.rst index c2928124702..c776859164c 100644 --- a/docs/source/algorithms/MolDyn-v1.rst +++ b/docs/source/algorithms/MolDyn-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MonitorEfficiencyCorUser-v1.rst b/docs/source/algorithms/MonitorEfficiencyCorUser-v1.rst index 0c96ec724c1..bbf858a58c9 100644 --- a/docs/source/algorithms/MonitorEfficiencyCorUser-v1.rst +++ b/docs/source/algorithms/MonitorEfficiencyCorUser-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MonitorLiveData-v1.rst b/docs/source/algorithms/MonitorLiveData-v1.rst index cb3401f0a2f..7545e231143 100644 --- a/docs/source/algorithms/MonitorLiveData-v1.rst +++ b/docs/source/algorithms/MonitorLiveData-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MonteCarloAbsorption-v1.rst b/docs/source/algorithms/MonteCarloAbsorption-v1.rst index eb8ae7c7eff..bdc1e59726f 100644 --- a/docs/source/algorithms/MonteCarloAbsorption-v1.rst +++ b/docs/source/algorithms/MonteCarloAbsorption-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MostLikelyMean-v1.rst b/docs/source/algorithms/MostLikelyMean-v1.rst index 0573e797c95..122cc8d600b 100644 --- a/docs/source/algorithms/MostLikelyMean-v1.rst +++ b/docs/source/algorithms/MostLikelyMean-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MoveInstrumentComponent-v1.rst b/docs/source/algorithms/MoveInstrumentComponent-v1.rst index 579eca2db37..7202f866af8 100644 --- a/docs/source/algorithms/MoveInstrumentComponent-v1.rst +++ b/docs/source/algorithms/MoveInstrumentComponent-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MultipleScatteringCylinderAbsorption-v1.rst b/docs/source/algorithms/MultipleScatteringCylinderAbsorption-v1.rst index 8ba34d07e08..bcb4b1ce649 100644 --- a/docs/source/algorithms/MultipleScatteringCylinderAbsorption-v1.rst +++ b/docs/source/algorithms/MultipleScatteringCylinderAbsorption-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Multiply-v1.rst b/docs/source/algorithms/Multiply-v1.rst index b8eb73ac9f9..06f738f55e7 100644 --- a/docs/source/algorithms/Multiply-v1.rst +++ b/docs/source/algorithms/Multiply-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MultiplyMD-v1.rst b/docs/source/algorithms/MultiplyMD-v1.rst index ab23a28de8f..e63c67fa070 100644 --- a/docs/source/algorithms/MultiplyMD-v1.rst +++ b/docs/source/algorithms/MultiplyMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MultiplyRange-v1.rst b/docs/source/algorithms/MultiplyRange-v1.rst index fe72fcb0080..284891de161 100644 --- a/docs/source/algorithms/MultiplyRange-v1.rst +++ b/docs/source/algorithms/MultiplyRange-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MuonGroupDetectors-v1.rst b/docs/source/algorithms/MuonGroupDetectors-v1.rst index dcf6a7d1d76..9a954992723 100644 --- a/docs/source/algorithms/MuonGroupDetectors-v1.rst +++ b/docs/source/algorithms/MuonGroupDetectors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MuonMaxent-v1.rst b/docs/source/algorithms/MuonMaxent-v1.rst index 5ea956f2d0d..c85399b6a5e 100644 --- a/docs/source/algorithms/MuonMaxent-v1.rst +++ b/docs/source/algorithms/MuonMaxent-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MuonProcess-v1.rst b/docs/source/algorithms/MuonProcess-v1.rst index 460e2348cfd..f24b88fc76d 100644 --- a/docs/source/algorithms/MuonProcess-v1.rst +++ b/docs/source/algorithms/MuonProcess-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MuscatData-v1.rst b/docs/source/algorithms/MuscatData-v1.rst index 810162435cd..e6a500e1efe 100644 --- a/docs/source/algorithms/MuscatData-v1.rst +++ b/docs/source/algorithms/MuscatData-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MuscatFunc-v1.rst b/docs/source/algorithms/MuscatFunc-v1.rst index 3c0bd184bd6..921e759ba69 100644 --- a/docs/source/algorithms/MuscatFunc-v1.rst +++ b/docs/source/algorithms/MuscatFunc-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/MuscatSofQW-v1.rst b/docs/source/algorithms/MuscatSofQW-v1.rst index 692b2bb76c7..3442b17a9d2 100644 --- a/docs/source/algorithms/MuscatSofQW-v1.rst +++ b/docs/source/algorithms/MuscatSofQW-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/NMoldyn4Interpolation-v1.rst b/docs/source/algorithms/NMoldyn4Interpolation-v1.rst index 6209957c9c0..ff3d0a10409 100644 --- a/docs/source/algorithms/NMoldyn4Interpolation-v1.rst +++ b/docs/source/algorithms/NMoldyn4Interpolation-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/NRCalculateSlitResolution-v1.rst b/docs/source/algorithms/NRCalculateSlitResolution-v1.rst index bdd830f369c..1f729b8c20c 100644 --- a/docs/source/algorithms/NRCalculateSlitResolution-v1.rst +++ b/docs/source/algorithms/NRCalculateSlitResolution-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -17,7 +17,7 @@ using the theta log name provided. The effective inverse of this algorithm is :ref:`algm-CalculateSlits`. Beam Divergence -*************** +############### .. figure:: ../images/collimation_diagram.png :scale: 50 % diff --git a/docs/source/algorithms/NexusTester-v1.rst b/docs/source/algorithms/NexusTester-v1.rst index 6314e9a18af..e2bac7eed2c 100644 --- a/docs/source/algorithms/NexusTester-v1.rst +++ b/docs/source/algorithms/NexusTester-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/NormaliseByCurrent-v1.rst b/docs/source/algorithms/NormaliseByCurrent-v1.rst index ad9fbc58e87..b306fee5c54 100644 --- a/docs/source/algorithms/NormaliseByCurrent-v1.rst +++ b/docs/source/algorithms/NormaliseByCurrent-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/NormaliseByDetector-v1.rst b/docs/source/algorithms/NormaliseByDetector-v1.rst index a9d47920055..b7d8f7d19c4 100644 --- a/docs/source/algorithms/NormaliseByDetector-v1.rst +++ b/docs/source/algorithms/NormaliseByDetector-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/NormaliseByPeakArea-v1.rst b/docs/source/algorithms/NormaliseByPeakArea-v1.rst index fb3e25279ae..b11b2e9f471 100644 --- a/docs/source/algorithms/NormaliseByPeakArea-v1.rst +++ b/docs/source/algorithms/NormaliseByPeakArea-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/NormaliseByThickness-v1.rst b/docs/source/algorithms/NormaliseByThickness-v1.rst index 437f5584ca7..362f9dff526 100644 --- a/docs/source/algorithms/NormaliseByThickness-v1.rst +++ b/docs/source/algorithms/NormaliseByThickness-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/NormaliseSpectra-v1.rst b/docs/source/algorithms/NormaliseSpectra-v1.rst index d7e428c0664..ef9b534a1f3 100644 --- a/docs/source/algorithms/NormaliseSpectra-v1.rst +++ b/docs/source/algorithms/NormaliseSpectra-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/NormaliseToMonitor-v1.rst b/docs/source/algorithms/NormaliseToMonitor-v1.rst index 520ea336220..79df1957337 100644 --- a/docs/source/algorithms/NormaliseToMonitor-v1.rst +++ b/docs/source/algorithms/NormaliseToMonitor-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/NormaliseToUnity-v1.rst b/docs/source/algorithms/NormaliseToUnity-v1.rst index 059fe586a09..637da1324fc 100644 --- a/docs/source/algorithms/NormaliseToUnity-v1.rst +++ b/docs/source/algorithms/NormaliseToUnity-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/NormaliseVanadium-v1.rst b/docs/source/algorithms/NormaliseVanadium-v1.rst index 4bf7490ef36..c441ac08356 100644 --- a/docs/source/algorithms/NormaliseVanadium-v1.rst +++ b/docs/source/algorithms/NormaliseVanadium-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/NotMD-v1.rst b/docs/source/algorithms/NotMD-v1.rst index 3c87a3ee903..49026f56f05 100644 --- a/docs/source/algorithms/NotMD-v1.rst +++ b/docs/source/algorithms/NotMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/OSIRISDiffractionReduction-v1.rst b/docs/source/algorithms/OSIRISDiffractionReduction-v1.rst index 87bf5b6dc36..c9bc8716db2 100644 --- a/docs/source/algorithms/OSIRISDiffractionReduction-v1.rst +++ b/docs/source/algorithms/OSIRISDiffractionReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/OneMinusExponentialCor-v1.rst b/docs/source/algorithms/OneMinusExponentialCor-v1.rst index a35ca4c9632..c82a12a3196 100644 --- a/docs/source/algorithms/OneMinusExponentialCor-v1.rst +++ b/docs/source/algorithms/OneMinusExponentialCor-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/OneStepMDEW-v1.rst b/docs/source/algorithms/OneStepMDEW-v1.rst index ab2b0dc463f..dc1664119db 100644 --- a/docs/source/algorithms/OneStepMDEW-v1.rst +++ b/docs/source/algorithms/OneStepMDEW-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/OptimizeCrystalPlacement-v1.rst b/docs/source/algorithms/OptimizeCrystalPlacement-v1.rst index 712f492abf2..d4527d6fdbf 100644 --- a/docs/source/algorithms/OptimizeCrystalPlacement-v1.rst +++ b/docs/source/algorithms/OptimizeCrystalPlacement-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/OptimizeLatticeForCellType-v1.rst b/docs/source/algorithms/OptimizeLatticeForCellType-v1.rst index fb3a18d2d23..d3badd33dc0 100644 --- a/docs/source/algorithms/OptimizeLatticeForCellType-v1.rst +++ b/docs/source/algorithms/OptimizeLatticeForCellType-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/OrMD-v1.rst b/docs/source/algorithms/OrMD-v1.rst index 6c32609d1c5..5731f041fcf 100644 --- a/docs/source/algorithms/OrMD-v1.rst +++ b/docs/source/algorithms/OrMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PDCalibration-v1.rst b/docs/source/algorithms/PDCalibration-v1.rst index a916066df11..fbaecc83cab 100644 --- a/docs/source/algorithms/PDCalibration-v1.rst +++ b/docs/source/algorithms/PDCalibration-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PDDetermineCharacterizations-v1.rst b/docs/source/algorithms/PDDetermineCharacterizations-v1.rst index d34d55bc560..3bbf4814847 100644 --- a/docs/source/algorithms/PDDetermineCharacterizations-v1.rst +++ b/docs/source/algorithms/PDDetermineCharacterizations-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PDFFourierTransform-v1.rst b/docs/source/algorithms/PDFFourierTransform-v1.rst index e1ab0936bfd..de892da208f 100644 --- a/docs/source/algorithms/PDFFourierTransform-v1.rst +++ b/docs/source/algorithms/PDFFourierTransform-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -32,7 +32,7 @@ Output Options -------------- **G(r)** -''''''''' +######## .. raw:: html @@ -84,7 +84,7 @@ otherwise **g(r)** -'''''''' +######## .. raw:: html @@ -111,7 +111,7 @@ transforms to **RDF(r)** -'''''''''' +########## .. raw:: html diff --git a/docs/source/algorithms/PDLoadCharacterizations-v1.rst b/docs/source/algorithms/PDLoadCharacterizations-v1.rst index 6fb3ad6727c..48454d9e290 100644 --- a/docs/source/algorithms/PDLoadCharacterizations-v1.rst +++ b/docs/source/algorithms/PDLoadCharacterizations-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PDToGUDRUN-v1.rst b/docs/source/algorithms/PDToGUDRUN-v1.rst index 5f242e390a5..1090a979c2e 100644 --- a/docs/source/algorithms/PDToGUDRUN-v1.rst +++ b/docs/source/algorithms/PDToGUDRUN-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PDToPDFgetN-v1.rst b/docs/source/algorithms/PDToPDFgetN-v1.rst index f37aae644e2..52236db5af2 100644 --- a/docs/source/algorithms/PDToPDFgetN-v1.rst +++ b/docs/source/algorithms/PDToPDFgetN-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PaddingAndApodization-v1.rst b/docs/source/algorithms/PaddingAndApodization-v1.rst index a2a6dd46e16..365c47df753 100644 --- a/docs/source/algorithms/PaddingAndApodization-v1.rst +++ b/docs/source/algorithms/PaddingAndApodization-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Pause-v1.rst b/docs/source/algorithms/Pause-v1.rst index 3608265c5ab..b8d05479ccd 100644 --- a/docs/source/algorithms/Pause-v1.rst +++ b/docs/source/algorithms/Pause-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PawleyFit-v1.rst b/docs/source/algorithms/PawleyFit-v1.rst index 2d595ce71e3..0304af84e33 100644 --- a/docs/source/algorithms/PawleyFit-v1.rst +++ b/docs/source/algorithms/PawleyFit-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PeakIntegration-v1.rst b/docs/source/algorithms/PeakIntegration-v1.rst index 5883750d5d0..10f147f712b 100644 --- a/docs/source/algorithms/PeakIntegration-v1.rst +++ b/docs/source/algorithms/PeakIntegration-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PeakIntensityVsRadius-v1.rst b/docs/source/algorithms/PeakIntensityVsRadius-v1.rst index 3c2dfb61ec1..5bbcab8f5fe 100644 --- a/docs/source/algorithms/PeakIntensityVsRadius-v1.rst +++ b/docs/source/algorithms/PeakIntensityVsRadius-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PeaksInRegion-v1.rst b/docs/source/algorithms/PeaksInRegion-v1.rst index d31f554b61c..416e628b744 100644 --- a/docs/source/algorithms/PeaksInRegion-v1.rst +++ b/docs/source/algorithms/PeaksInRegion-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PeaksOnSurface-v1.rst b/docs/source/algorithms/PeaksOnSurface-v1.rst index 2120e70924c..9863d8155b8 100644 --- a/docs/source/algorithms/PeaksOnSurface-v1.rst +++ b/docs/source/algorithms/PeaksOnSurface-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PearlMCAbsorption-v1.rst b/docs/source/algorithms/PearlMCAbsorption-v1.rst index 98d3162d441..160bb9d855f 100644 --- a/docs/source/algorithms/PearlMCAbsorption-v1.rst +++ b/docs/source/algorithms/PearlMCAbsorption-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PerformIndexOperations-v1.rst b/docs/source/algorithms/PerformIndexOperations-v1.rst index 8884f4c92dd..cc43e6c5599 100644 --- a/docs/source/algorithms/PerformIndexOperations-v1.rst +++ b/docs/source/algorithms/PerformIndexOperations-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PhaseQuad-v1.rst b/docs/source/algorithms/PhaseQuad-v1.rst index 30f6d6da89e..90ed1e09708 100644 --- a/docs/source/algorithms/PhaseQuad-v1.rst +++ b/docs/source/algorithms/PhaseQuad-v1.rst @@ -16,7 +16,7 @@ the dataset using the algorithm :ref:`algm-RRFMuon`. Both algorithms are fully d by T.M. Riseman and J.H. Brewer [Hyp. Int., 65, (1990), 1107]. -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PlotAsymmetryByLogValue-v1.rst b/docs/source/algorithms/PlotAsymmetryByLogValue-v1.rst index bcdd84cedb0..5f73a567df1 100644 --- a/docs/source/algorithms/PlotAsymmetryByLogValue-v1.rst +++ b/docs/source/algorithms/PlotAsymmetryByLogValue-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PlotPeakByLogValue-v1.rst b/docs/source/algorithms/PlotPeakByLogValue-v1.rst index 2abc311e9ed..aaa63fab9c6 100644 --- a/docs/source/algorithms/PlotPeakByLogValue-v1.rst +++ b/docs/source/algorithms/PlotPeakByLogValue-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Plus-v1.rst b/docs/source/algorithms/Plus-v1.rst index ae8542c8964..0e5ccdcf98e 100644 --- a/docs/source/algorithms/Plus-v1.rst +++ b/docs/source/algorithms/Plus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PlusMD-v1.rst b/docs/source/algorithms/PlusMD-v1.rst index b61fe857e8b..652d6a4f8b2 100644 --- a/docs/source/algorithms/PlusMD-v1.rst +++ b/docs/source/algorithms/PlusMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PointByPointVCorrection-v1.rst b/docs/source/algorithms/PointByPointVCorrection-v1.rst index 8cd77e9b2d9..9b5887582ea 100644 --- a/docs/source/algorithms/PointByPointVCorrection-v1.rst +++ b/docs/source/algorithms/PointByPointVCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoissonErrors-v1.rst b/docs/source/algorithms/PoissonErrors-v1.rst index ff71601af02..e2afcc45783 100644 --- a/docs/source/algorithms/PoissonErrors-v1.rst +++ b/docs/source/algorithms/PoissonErrors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PolarizationCorrection-v1.rst b/docs/source/algorithms/PolarizationCorrection-v1.rst index f3ad00bdb84..c42f2de3d7f 100644 --- a/docs/source/algorithms/PolarizationCorrection-v1.rst +++ b/docs/source/algorithms/PolarizationCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PolarizationEfficiencyCor-v1.rst b/docs/source/algorithms/PolarizationEfficiencyCor-v1.rst index 6768e8f5fdd..a34480a2307 100644 --- a/docs/source/algorithms/PolarizationEfficiencyCor-v1.rst +++ b/docs/source/algorithms/PolarizationEfficiencyCor-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoldiAnalyseResiduals-v1.rst b/docs/source/algorithms/PoldiAnalyseResiduals-v1.rst index db4d53d0236..4e7d1efd056 100644 --- a/docs/source/algorithms/PoldiAnalyseResiduals-v1.rst +++ b/docs/source/algorithms/PoldiAnalyseResiduals-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoldiAutoCorrelation-v5.rst b/docs/source/algorithms/PoldiAutoCorrelation-v5.rst index 06d1a4746d6..fab4797afc7 100644 --- a/docs/source/algorithms/PoldiAutoCorrelation-v5.rst +++ b/docs/source/algorithms/PoldiAutoCorrelation-v5.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoldiCreatePeaksFromCell-v1.rst b/docs/source/algorithms/PoldiCreatePeaksFromCell-v1.rst index 474852eb1f0..949ea1c1e2e 100644 --- a/docs/source/algorithms/PoldiCreatePeaksFromCell-v1.rst +++ b/docs/source/algorithms/PoldiCreatePeaksFromCell-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoldiCreatePeaksFromFile-v1.rst b/docs/source/algorithms/PoldiCreatePeaksFromFile-v1.rst index 5ed11c6b402..12f8f906cb0 100644 --- a/docs/source/algorithms/PoldiCreatePeaksFromFile-v1.rst +++ b/docs/source/algorithms/PoldiCreatePeaksFromFile-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoldiDataAnalysis-v1.rst b/docs/source/algorithms/PoldiDataAnalysis-v1.rst index 2ba86f8a52a..b3a40781d21 100644 --- a/docs/source/algorithms/PoldiDataAnalysis-v1.rst +++ b/docs/source/algorithms/PoldiDataAnalysis-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoldiFitPeaks1D-v1.rst b/docs/source/algorithms/PoldiFitPeaks1D-v1.rst index 97f082a76b1..3043e2daef1 100644 --- a/docs/source/algorithms/PoldiFitPeaks1D-v1.rst +++ b/docs/source/algorithms/PoldiFitPeaks1D-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoldiFitPeaks1D-v2.rst b/docs/source/algorithms/PoldiFitPeaks1D-v2.rst index 3bc77b32254..dabc74f453f 100644 --- a/docs/source/algorithms/PoldiFitPeaks1D-v2.rst +++ b/docs/source/algorithms/PoldiFitPeaks1D-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoldiFitPeaks2D-v1.rst b/docs/source/algorithms/PoldiFitPeaks2D-v1.rst index d2cc1729a4a..ebff26e1581 100644 --- a/docs/source/algorithms/PoldiFitPeaks2D-v1.rst +++ b/docs/source/algorithms/PoldiFitPeaks2D-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoldiIndexKnownCompounds-v1.rst b/docs/source/algorithms/PoldiIndexKnownCompounds-v1.rst index 615f830636c..7557517576c 100644 --- a/docs/source/algorithms/PoldiIndexKnownCompounds-v1.rst +++ b/docs/source/algorithms/PoldiIndexKnownCompounds-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoldiLoadRuns-v1.rst b/docs/source/algorithms/PoldiLoadRuns-v1.rst index 8fb355dd2a0..c2a82a3ce75 100644 --- a/docs/source/algorithms/PoldiLoadRuns-v1.rst +++ b/docs/source/algorithms/PoldiLoadRuns-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoldiMerge-v1.rst b/docs/source/algorithms/PoldiMerge-v1.rst index 43efce97d05..f1bb1e512c8 100644 --- a/docs/source/algorithms/PoldiMerge-v1.rst +++ b/docs/source/algorithms/PoldiMerge-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoldiPeakSearch-v1.rst b/docs/source/algorithms/PoldiPeakSearch-v1.rst index e5f4a535f6b..6051f20db58 100644 --- a/docs/source/algorithms/PoldiPeakSearch-v1.rst +++ b/docs/source/algorithms/PoldiPeakSearch-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoldiPeakSummary-v1.rst b/docs/source/algorithms/PoldiPeakSummary-v1.rst index 058e6408ae5..dda2634eabd 100644 --- a/docs/source/algorithms/PoldiPeakSummary-v1.rst +++ b/docs/source/algorithms/PoldiPeakSummary-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PoldiTruncateData-v1.rst b/docs/source/algorithms/PoldiTruncateData-v1.rst index a8ad7c8454f..3b29df5d33d 100644 --- a/docs/source/algorithms/PoldiTruncateData-v1.rst +++ b/docs/source/algorithms/PoldiTruncateData-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PolynomialCorrection-v1.rst b/docs/source/algorithms/PolynomialCorrection-v1.rst index 379471ffb86..00c0a3a0000 100644 --- a/docs/source/algorithms/PolynomialCorrection-v1.rst +++ b/docs/source/algorithms/PolynomialCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PowderDiffILLDetEffCorr-v1.rst b/docs/source/algorithms/PowderDiffILLDetEffCorr-v1.rst index 972a9b365e3..39733a221e4 100644 --- a/docs/source/algorithms/PowderDiffILLDetEffCorr-v1.rst +++ b/docs/source/algorithms/PowderDiffILLDetEffCorr-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PowderDiffILLDetScanReduction-v1.rst b/docs/source/algorithms/PowderDiffILLDetScanReduction-v1.rst index 3012609bb5c..ab7e09765d7 100644 --- a/docs/source/algorithms/PowderDiffILLDetScanReduction-v1.rst +++ b/docs/source/algorithms/PowderDiffILLDetScanReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PowderDiffILLReduction-v1.rst b/docs/source/algorithms/PowderDiffILLReduction-v1.rst index e176f63b647..0aa17c738a0 100644 --- a/docs/source/algorithms/PowderDiffILLReduction-v1.rst +++ b/docs/source/algorithms/PowderDiffILLReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Power-v1.rst b/docs/source/algorithms/Power-v1.rst index e265fc3f8be..a5e2355783b 100644 --- a/docs/source/algorithms/Power-v1.rst +++ b/docs/source/algorithms/Power-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PowerLawCorrection-v1.rst b/docs/source/algorithms/PowerLawCorrection-v1.rst index 2c0a331cae5..2c6b4295d78 100644 --- a/docs/source/algorithms/PowerLawCorrection-v1.rst +++ b/docs/source/algorithms/PowerLawCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PowerMD-v1.rst b/docs/source/algorithms/PowerMD-v1.rst index d9c9235dab8..cd3de950833 100644 --- a/docs/source/algorithms/PowerMD-v1.rst +++ b/docs/source/algorithms/PowerMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PredictFractionalPeaks-v1.rst b/docs/source/algorithms/PredictFractionalPeaks-v1.rst index 17cfee19137..665c80a9dd9 100644 --- a/docs/source/algorithms/PredictFractionalPeaks-v1.rst +++ b/docs/source/algorithms/PredictFractionalPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PredictPeaks-v1.rst b/docs/source/algorithms/PredictPeaks-v1.rst index e75114f7be9..e49f377c0b0 100644 --- a/docs/source/algorithms/PredictPeaks-v1.rst +++ b/docs/source/algorithms/PredictPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/PreprocessDetectorsToMD-v1.rst b/docs/source/algorithms/PreprocessDetectorsToMD-v1.rst index c33bc2138e4..d1827a3046c 100644 --- a/docs/source/algorithms/PreprocessDetectorsToMD-v1.rst +++ b/docs/source/algorithms/PreprocessDetectorsToMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ProcessBackground-v1.rst b/docs/source/algorithms/ProcessBackground-v1.rst index fbaa512aa39..3a9dfe1486c 100644 --- a/docs/source/algorithms/ProcessBackground-v1.rst +++ b/docs/source/algorithms/ProcessBackground-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ProcessIndirectFitParameters-v1.rst b/docs/source/algorithms/ProcessIndirectFitParameters-v1.rst index 9dac5faff47..3b6dae49d1a 100644 --- a/docs/source/algorithms/ProcessIndirectFitParameters-v1.rst +++ b/docs/source/algorithms/ProcessIndirectFitParameters-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ProjectMD-v1.rst b/docs/source/algorithms/ProjectMD-v1.rst index 81ca4aadbbc..926a93f09d8 100644 --- a/docs/source/algorithms/ProjectMD-v1.rst +++ b/docs/source/algorithms/ProjectMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Q1D-v2.rst b/docs/source/algorithms/Q1D-v2.rst index 58211b2be98..758cfa7e89f 100644 --- a/docs/source/algorithms/Q1D-v2.rst +++ b/docs/source/algorithms/Q1D-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Q1DWeighted-v1.rst b/docs/source/algorithms/Q1DWeighted-v1.rst index dc9a32533cb..a378348812a 100644 --- a/docs/source/algorithms/Q1DWeighted-v1.rst +++ b/docs/source/algorithms/Q1DWeighted-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/QueryAllRemoteJobs-v1.rst b/docs/source/algorithms/QueryAllRemoteJobs-v1.rst index cd0d0d952d0..e5fbcdff86d 100644 --- a/docs/source/algorithms/QueryAllRemoteJobs-v1.rst +++ b/docs/source/algorithms/QueryAllRemoteJobs-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/QueryAllRemoteJobs-v2.rst b/docs/source/algorithms/QueryAllRemoteJobs-v2.rst index 2f8f0e272da..927d6d70c54 100644 --- a/docs/source/algorithms/QueryAllRemoteJobs-v2.rst +++ b/docs/source/algorithms/QueryAllRemoteJobs-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/QueryMDWorkspace-v1.rst b/docs/source/algorithms/QueryMDWorkspace-v1.rst index a7e8b512695..5f44c2e97ae 100644 --- a/docs/source/algorithms/QueryMDWorkspace-v1.rst +++ b/docs/source/algorithms/QueryMDWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/QueryRemoteFile-v1.rst b/docs/source/algorithms/QueryRemoteFile-v1.rst index 91c5b712556..4c53fe12205 100644 --- a/docs/source/algorithms/QueryRemoteFile-v1.rst +++ b/docs/source/algorithms/QueryRemoteFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/QueryRemoteFile-v2.rst b/docs/source/algorithms/QueryRemoteFile-v2.rst index 41764288088..67173a6687c 100644 --- a/docs/source/algorithms/QueryRemoteFile-v2.rst +++ b/docs/source/algorithms/QueryRemoteFile-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/QueryRemoteJob-v1.rst b/docs/source/algorithms/QueryRemoteJob-v1.rst index b8d7c1be07c..44f6aa6fd59 100644 --- a/docs/source/algorithms/QueryRemoteJob-v1.rst +++ b/docs/source/algorithms/QueryRemoteJob-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/QueryRemoteJob-v2.rst b/docs/source/algorithms/QueryRemoteJob-v2.rst index 8f017f8c4a2..f52dac82412 100644 --- a/docs/source/algorithms/QueryRemoteJob-v2.rst +++ b/docs/source/algorithms/QueryRemoteJob-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Qxy-v1.rst b/docs/source/algorithms/Qxy-v1.rst index 7a191f7970c..378fff955dd 100644 --- a/docs/source/algorithms/Qxy-v1.rst +++ b/docs/source/algorithms/Qxy-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/REFLReprocess-v1.rst b/docs/source/algorithms/REFLReprocess-v1.rst deleted file mode 100644 index 3862660e274..00000000000 --- a/docs/source/algorithms/REFLReprocess-v1.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. algorithm:: - -.. summary:: - -.. alias:: - -.. properties:: - -Description ------------ - -Re-reduce REFL data for an entire experiment using saved parameters - -.. categories:: - -.. sourcelink:: diff --git a/docs/source/algorithms/RRFMuon-v1.rst b/docs/source/algorithms/RRFMuon-v1.rst index be04df98f4f..1ad5d6074e5 100644 --- a/docs/source/algorithms/RRFMuon-v1.rst +++ b/docs/source/algorithms/RRFMuon-v1.rst @@ -14,7 +14,7 @@ This algorithm is frequently run after making a phase quadrature transformation article by T.M. Riseman and J.H. Brewer [Hyp. Int., 65, (1990), 1107]. -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RadiusSum-v1.rst b/docs/source/algorithms/RadiusSum-v1.rst index 36b1513aa96..9242f12d3d3 100644 --- a/docs/source/algorithms/RadiusSum-v1.rst +++ b/docs/source/algorithms/RadiusSum-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RawFileInfo-v1.rst b/docs/source/algorithms/RawFileInfo-v1.rst index 48166101012..1d9a6904b32 100644 --- a/docs/source/algorithms/RawFileInfo-v1.rst +++ b/docs/source/algorithms/RawFileInfo-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RayTracerTester-v1.rst b/docs/source/algorithms/RayTracerTester-v1.rst index 251ee405ed5..9e3bbdcdb92 100644 --- a/docs/source/algorithms/RayTracerTester-v1.rst +++ b/docs/source/algorithms/RayTracerTester-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ReactorSANSResolution-v1.rst b/docs/source/algorithms/ReactorSANSResolution-v1.rst index d8e589d65db..905752dda9f 100644 --- a/docs/source/algorithms/ReactorSANSResolution-v1.rst +++ b/docs/source/algorithms/ReactorSANSResolution-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ReadGroupsFromFile-v1.rst b/docs/source/algorithms/ReadGroupsFromFile-v1.rst index ed1bf892686..1b67b1337ac 100644 --- a/docs/source/algorithms/ReadGroupsFromFile-v1.rst +++ b/docs/source/algorithms/ReadGroupsFromFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RealFFT-v1.rst b/docs/source/algorithms/RealFFT-v1.rst index f0da140e26f..65b63330ddc 100644 --- a/docs/source/algorithms/RealFFT-v1.rst +++ b/docs/source/algorithms/RealFFT-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Rebin-v1.rst b/docs/source/algorithms/Rebin-v1.rst index 593accdcd91..1da69119acf 100644 --- a/docs/source/algorithms/Rebin-v1.rst +++ b/docs/source/algorithms/Rebin-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -14,11 +14,11 @@ defines new boundaries in intervals :math:`x_i-x_{i+1}\,`. Positive :math:`\Delta x_i\,` make constant width bins, whilst negative ones create logarithmic binning using the formula :math:`x(j+1)=x(j)(1+|\Delta x_i|)\,` - + This algorithms is useful both in data reduction, but also in remapping :ref:`ragged workspace <Ragged_Workspace>` to a regular set of bin boundaries. - + Unless the FullBinsOnly option is enabled, the bin immediately before the specified boundaries :math:`x_2`, :math:`x_3`, ... :math:`x_i` is likely to have a different width from its neighbours because there can @@ -136,7 +136,7 @@ Output: The 2nd and 3rd rebinned X values are: [ 1.5 2.25] **Example - custom two regions rebinning:** - + .. testcode:: ExHistCustom # create histogram workspace diff --git a/docs/source/algorithms/Rebin2D-v1.rst b/docs/source/algorithms/Rebin2D-v1.rst index d9efd20d2ac..dda2cdb3205 100644 --- a/docs/source/algorithms/Rebin2D-v1.rst +++ b/docs/source/algorithms/Rebin2D-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RebinByPulseTimes-v1.rst b/docs/source/algorithms/RebinByPulseTimes-v1.rst index 827d09ab25d..7ace4e76528 100644 --- a/docs/source/algorithms/RebinByPulseTimes-v1.rst +++ b/docs/source/algorithms/RebinByPulseTimes-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RebinByTimeAtSample-v1.rst b/docs/source/algorithms/RebinByTimeAtSample-v1.rst index 166f073353a..e01c41d7798 100644 --- a/docs/source/algorithms/RebinByTimeAtSample-v1.rst +++ b/docs/source/algorithms/RebinByTimeAtSample-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RebinToWorkspace-v1.rst b/docs/source/algorithms/RebinToWorkspace-v1.rst index 400aa5a5559..fd20ffff3a8 100644 --- a/docs/source/algorithms/RebinToWorkspace-v1.rst +++ b/docs/source/algorithms/RebinToWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -13,7 +13,7 @@ Takes an input workspace and alters the binning so that all it's spectra match that of the **first spectrum** of the second workspace. This algorithm simply builds a parameter list that is passed to the :ref:`algm-Rebin` algorithm, which actually does the work. - + .. categories:: .. sourcelink:: diff --git a/docs/source/algorithms/Rebunch-v1.rst b/docs/source/algorithms/Rebunch-v1.rst index 6113649edc2..87dc9446d42 100644 --- a/docs/source/algorithms/Rebunch-v1.rst +++ b/docs/source/algorithms/Rebunch-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RecordPythonScript-v1.rst b/docs/source/algorithms/RecordPythonScript-v1.rst index b4b3c921b02..b095e41acf5 100644 --- a/docs/source/algorithms/RecordPythonScript-v1.rst +++ b/docs/source/algorithms/RecordPythonScript-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RefLReduction-v1.rst b/docs/source/algorithms/RefLReduction-v1.rst deleted file mode 100644 index 9a878fdd9b1..00000000000 --- a/docs/source/algorithms/RefLReduction-v1.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. algorithm:: - -.. summary:: - -.. alias:: - -.. properties:: - -Description ------------ - -Liquids Reflectometer (REFL) reduction - -.. categories:: - -.. sourcelink:: diff --git a/docs/source/algorithms/RefReduction-v1.rst b/docs/source/algorithms/RefReduction-v1.rst deleted file mode 100644 index 80dc19fc12e..00000000000 --- a/docs/source/algorithms/RefReduction-v1.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. algorithm:: - -.. summary:: - -.. alias:: - -.. properties:: - -Description ------------ - -Reflectivity reduction workflow. This workflow algorithm computes the -specular and off-specular reflectivity for both REFM and REFL -instruments. - -.. categories:: - -.. sourcelink:: diff --git a/docs/source/algorithms/RefRoi-v1.rst b/docs/source/algorithms/RefRoi-v1.rst index 857c87654c0..d5d607ffefa 100644 --- a/docs/source/algorithms/RefRoi-v1.rst +++ b/docs/source/algorithms/RefRoi-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RefinePowderDiffProfileSeq-v1.rst b/docs/source/algorithms/RefinePowderDiffProfileSeq-v1.rst index 187da08e143..a296eb204ba 100644 --- a/docs/source/algorithms/RefinePowderDiffProfileSeq-v1.rst +++ b/docs/source/algorithms/RefinePowderDiffProfileSeq-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RefinePowderInstrumentParameters-v3.rst b/docs/source/algorithms/RefinePowderInstrumentParameters-v3.rst index dabb9a33350..db10e6fa19a 100644 --- a/docs/source/algorithms/RefinePowderInstrumentParameters-v3.rst +++ b/docs/source/algorithms/RefinePowderInstrumentParameters-v3.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -19,7 +19,7 @@ FitPowderDiffPeaks(). Introduction -============ +############ In order to do Rietveld refinement to experimental data, the diffractometer’s profile should be calibrated by the standards, such as LaB6 or Ni, with known crystal structure and lattice parameters. @@ -45,8 +45,8 @@ Final Time-of-flight is calculated as: .. math:: TOF = n_{cross} TOF_e + (1-n_{cross}) TOF_t -Formular for calculating :math:`A(d)`, :math:`B(d)`, :math:`\sigma(d)` and :math:`\gamma(d)` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Formula for calculating :math:`A(d)`, :math:`B(d)`, :math:`\sigma(d)` and :math:`\gamma(d)` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :math:`\alpha(d)`: @@ -104,7 +104,7 @@ where Break down the problem -====================== +###################### If we can do the single peak fitting on each single diffraction peak in a certain range, then we can divide the optimization problem into 4 sub problems for :math:`X_0`, :math:`A`, @@ -136,13 +136,13 @@ with constraint: The coefficients in this function are strongly correlated to each other. Current Implementation -====================== +###################### Only the parameters of the function for :math:`X_0` are fitted in present implementation. Refinement Algorithm -==================== +#################### Two refinement algorithms, DirectFit and MonteCarlo, are provided. @@ -171,7 +171,7 @@ In future, constaint will be considered. How to use algorithm with other algorithms -========================================== +########################################## This algorithm is designed to work with other algorithms to do Le Bail fit. The introduction can be found in the wiki page of diff --git a/docs/source/algorithms/ReflectometryReductionOne-v2.rst b/docs/source/algorithms/ReflectometryReductionOne-v2.rst index 3c1db876906..fe6b4df8b6b 100644 --- a/docs/source/algorithms/ReflectometryReductionOne-v2.rst +++ b/docs/source/algorithms/ReflectometryReductionOne-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst b/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst index cfd80f250fd..4258f0d63cb 100644 --- a/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst +++ b/docs/source/algorithms/ReflectometryReductionOneAuto-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Regroup-v1.rst b/docs/source/algorithms/Regroup-v1.rst index 0a3cf86c539..daf32889ffc 100644 --- a/docs/source/algorithms/Regroup-v1.rst +++ b/docs/source/algorithms/Regroup-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RemoveBackground-v1.rst b/docs/source/algorithms/RemoveBackground-v1.rst index 87dd338d4d9..c4b3942aa40 100644 --- a/docs/source/algorithms/RemoveBackground-v1.rst +++ b/docs/source/algorithms/RemoveBackground-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RemoveBins-v1.rst b/docs/source/algorithms/RemoveBins-v1.rst index ec8d56cea2f..4953808f4a3 100644 --- a/docs/source/algorithms/RemoveBins-v1.rst +++ b/docs/source/algorithms/RemoveBins-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RemoveExpDecay-v1.rst b/docs/source/algorithms/RemoveExpDecay-v1.rst index 97985ff7e3a..4edaffbf4f4 100644 --- a/docs/source/algorithms/RemoveExpDecay-v1.rst +++ b/docs/source/algorithms/RemoveExpDecay-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RemoveLogs-v1.rst b/docs/source/algorithms/RemoveLogs-v1.rst index de038a5308a..4944a4e094e 100644 --- a/docs/source/algorithms/RemoveLogs-v1.rst +++ b/docs/source/algorithms/RemoveLogs-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RemoveLowResTOF-v1.rst b/docs/source/algorithms/RemoveLowResTOF-v1.rst index 9b4d0bdaafe..34a1c2c83c2 100644 --- a/docs/source/algorithms/RemoveLowResTOF-v1.rst +++ b/docs/source/algorithms/RemoveLowResTOF-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RemoveMaskedSpectra-v1.rst b/docs/source/algorithms/RemoveMaskedSpectra-v1.rst index eae7f4c961c..cb92f814c2d 100644 --- a/docs/source/algorithms/RemoveMaskedSpectra-v1.rst +++ b/docs/source/algorithms/RemoveMaskedSpectra-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RemovePromptPulse-v1.rst b/docs/source/algorithms/RemovePromptPulse-v1.rst index 8f41765299f..172346cc8a6 100644 --- a/docs/source/algorithms/RemovePromptPulse-v1.rst +++ b/docs/source/algorithms/RemovePromptPulse-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RemoveWorkspaceHistory-v1.rst b/docs/source/algorithms/RemoveWorkspaceHistory-v1.rst index 0c29f28a6d7..afe1bcfe38d 100644 --- a/docs/source/algorithms/RemoveWorkspaceHistory-v1.rst +++ b/docs/source/algorithms/RemoveWorkspaceHistory-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RenameLog-v1.rst b/docs/source/algorithms/RenameLog-v1.rst index 192fb28465e..83e74bcee0f 100644 --- a/docs/source/algorithms/RenameLog-v1.rst +++ b/docs/source/algorithms/RenameLog-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RenameWorkspace-v1.rst b/docs/source/algorithms/RenameWorkspace-v1.rst index 0eeb092d51c..c5d6e2d95e2 100644 --- a/docs/source/algorithms/RenameWorkspace-v1.rst +++ b/docs/source/algorithms/RenameWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RenameWorkspaces-v1.rst b/docs/source/algorithms/RenameWorkspaces-v1.rst index 002feebc6e7..c1fc0899d85 100644 --- a/docs/source/algorithms/RenameWorkspaces-v1.rst +++ b/docs/source/algorithms/RenameWorkspaces-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ReplaceSpecialValues-v1.rst b/docs/source/algorithms/ReplaceSpecialValues-v1.rst index d2015400dea..596da224c83 100644 --- a/docs/source/algorithms/ReplaceSpecialValues-v1.rst +++ b/docs/source/algorithms/ReplaceSpecialValues-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ReplicateMD-v1.rst b/docs/source/algorithms/ReplicateMD-v1.rst index ff6ac463e02..46b5d35df5b 100644 --- a/docs/source/algorithms/ReplicateMD-v1.rst +++ b/docs/source/algorithms/ReplicateMD-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ResNorm-v1.rst b/docs/source/algorithms/ResNorm-v1.rst index f611b50a596..22d14ef8272 100644 --- a/docs/source/algorithms/ResNorm-v1.rst +++ b/docs/source/algorithms/ResNorm-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ResNorm-v2.rst b/docs/source/algorithms/ResNorm-v2.rst index baa4ed715c2..fc31d42f508 100644 --- a/docs/source/algorithms/ResNorm-v2.rst +++ b/docs/source/algorithms/ResNorm-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ResampleX-v1.rst b/docs/source/algorithms/ResampleX-v1.rst index 96b4bbf0c95..eb4766d503d 100644 --- a/docs/source/algorithms/ResampleX-v1.rst +++ b/docs/source/algorithms/ResampleX-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ResetNegatives-v1.rst b/docs/source/algorithms/ResetNegatives-v1.rst index df5ea7243cd..f026d6ba210 100644 --- a/docs/source/algorithms/ResetNegatives-v1.rst +++ b/docs/source/algorithms/ResetNegatives-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ResizeRectangularDetector-v1.rst b/docs/source/algorithms/ResizeRectangularDetector-v1.rst index 12a4ea95279..57bcc563f8e 100644 --- a/docs/source/algorithms/ResizeRectangularDetector-v1.rst +++ b/docs/source/algorithms/ResizeRectangularDetector-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RetrieveRunInfo-v1.rst b/docs/source/algorithms/RetrieveRunInfo-v1.rst index 74efd6c926c..a15c206b9eb 100644 --- a/docs/source/algorithms/RetrieveRunInfo-v1.rst +++ b/docs/source/algorithms/RetrieveRunInfo-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RingProfile-v1.rst b/docs/source/algorithms/RingProfile-v1.rst index 565d0a4f98a..6128ab0c3d4 100644 --- a/docs/source/algorithms/RingProfile-v1.rst +++ b/docs/source/algorithms/RingProfile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RotateInstrumentComponent-v1.rst b/docs/source/algorithms/RotateInstrumentComponent-v1.rst index ec0fba77cb8..10b3d82729e 100644 --- a/docs/source/algorithms/RotateInstrumentComponent-v1.rst +++ b/docs/source/algorithms/RotateInstrumentComponent-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RotateSource-v1.rst b/docs/source/algorithms/RotateSource-v1.rst index a076165b662..3c4fd670436 100644 --- a/docs/source/algorithms/RotateSource-v1.rst +++ b/docs/source/algorithms/RotateSource-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/RunPythonScript-v1.rst b/docs/source/algorithms/RunPythonScript-v1.rst index 3ef644b912c..82c50218b7d 100644 --- a/docs/source/algorithms/RunPythonScript-v1.rst +++ b/docs/source/algorithms/RunPythonScript-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSAbsoluteScale-v1.rst b/docs/source/algorithms/SANSAbsoluteScale-v1.rst index 8f639082cdb..dfb8782b7d0 100644 --- a/docs/source/algorithms/SANSAbsoluteScale-v1.rst +++ b/docs/source/algorithms/SANSAbsoluteScale-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSAzimuthalAverage1D-v1.rst b/docs/source/algorithms/SANSAzimuthalAverage1D-v1.rst index 351c5c2bc17..d4270912970 100644 --- a/docs/source/algorithms/SANSAzimuthalAverage1D-v1.rst +++ b/docs/source/algorithms/SANSAzimuthalAverage1D-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSBeamFinder-v1.rst b/docs/source/algorithms/SANSBeamFinder-v1.rst index 336706fff43..985aaac9c55 100644 --- a/docs/source/algorithms/SANSBeamFinder-v1.rst +++ b/docs/source/algorithms/SANSBeamFinder-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSBeamFluxCorrection-v1.rst b/docs/source/algorithms/SANSBeamFluxCorrection-v1.rst index 28f5a224afd..89fa891a0ef 100644 --- a/docs/source/algorithms/SANSBeamFluxCorrection-v1.rst +++ b/docs/source/algorithms/SANSBeamFluxCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSBeamSpreaderTransmission-v1.rst b/docs/source/algorithms/SANSBeamSpreaderTransmission-v1.rst index f5ec4f3ea21..7ca608d099c 100644 --- a/docs/source/algorithms/SANSBeamSpreaderTransmission-v1.rst +++ b/docs/source/algorithms/SANSBeamSpreaderTransmission-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSCalculateTransmission-v1.rst b/docs/source/algorithms/SANSCalculateTransmission-v1.rst index 680e22aa1a6..a2a195773ab 100644 --- a/docs/source/algorithms/SANSCalculateTransmission-v1.rst +++ b/docs/source/algorithms/SANSCalculateTransmission-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSConvertToQ-v1.rst b/docs/source/algorithms/SANSConvertToQ-v1.rst index ae5eaf71e1d..50f3a9cb382 100644 --- a/docs/source/algorithms/SANSConvertToQ-v1.rst +++ b/docs/source/algorithms/SANSConvertToQ-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSConvertToWavelength-v1.rst b/docs/source/algorithms/SANSConvertToWavelength-v1.rst index e1809d3c9ea..8983cd04e78 100644 --- a/docs/source/algorithms/SANSConvertToWavelength-v1.rst +++ b/docs/source/algorithms/SANSConvertToWavelength-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSConvertToWavelengthAndRebin-v1.rst b/docs/source/algorithms/SANSConvertToWavelengthAndRebin-v1.rst index 3dc3f2e2dad..e4e63b6faf3 100644 --- a/docs/source/algorithms/SANSConvertToWavelengthAndRebin-v1.rst +++ b/docs/source/algorithms/SANSConvertToWavelengthAndRebin-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSCreateAdjustmentWorkspaces-v1.rst b/docs/source/algorithms/SANSCreateAdjustmentWorkspaces-v1.rst index d002ddc8f2b..5f44dc35200 100644 --- a/docs/source/algorithms/SANSCreateAdjustmentWorkspaces-v1.rst +++ b/docs/source/algorithms/SANSCreateAdjustmentWorkspaces-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSCreateWavelengthAndPixelAdjustment-v1.rst b/docs/source/algorithms/SANSCreateWavelengthAndPixelAdjustment-v1.rst index 8e7a78335a9..361a34ed1b9 100644 --- a/docs/source/algorithms/SANSCreateWavelengthAndPixelAdjustment-v1.rst +++ b/docs/source/algorithms/SANSCreateWavelengthAndPixelAdjustment-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSCrop-v1.rst b/docs/source/algorithms/SANSCrop-v1.rst index 340047d8648..f85e7c49526 100644 --- a/docs/source/algorithms/SANSCrop-v1.rst +++ b/docs/source/algorithms/SANSCrop-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSDarkRunBackgroundCorrection-v1.rst b/docs/source/algorithms/SANSDarkRunBackgroundCorrection-v1.rst index e047601d93a..44245466bb0 100644 --- a/docs/source/algorithms/SANSDarkRunBackgroundCorrection-v1.rst +++ b/docs/source/algorithms/SANSDarkRunBackgroundCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSDirectBeamTransmission-v1.rst b/docs/source/algorithms/SANSDirectBeamTransmission-v1.rst index 9e860bf4b11..dd4b153d066 100644 --- a/docs/source/algorithms/SANSDirectBeamTransmission-v1.rst +++ b/docs/source/algorithms/SANSDirectBeamTransmission-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSFitShiftScale-v1.rst b/docs/source/algorithms/SANSFitShiftScale-v1.rst index 63dbabb1a39..9456909f7fa 100644 --- a/docs/source/algorithms/SANSFitShiftScale-v1.rst +++ b/docs/source/algorithms/SANSFitShiftScale-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSLoad-v1.rst b/docs/source/algorithms/SANSLoad-v1.rst index 1ce6490e87c..67dffa65f4c 100644 --- a/docs/source/algorithms/SANSLoad-v1.rst +++ b/docs/source/algorithms/SANSLoad-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSMask-v1.rst b/docs/source/algorithms/SANSMask-v1.rst index 54678ab5806..1456c2085b4 100644 --- a/docs/source/algorithms/SANSMask-v1.rst +++ b/docs/source/algorithms/SANSMask-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSMaskWorkspace-v1.rst b/docs/source/algorithms/SANSMaskWorkspace-v1.rst index 8ab90994988..910cf7f1342 100644 --- a/docs/source/algorithms/SANSMaskWorkspace-v1.rst +++ b/docs/source/algorithms/SANSMaskWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSMove-v1.rst b/docs/source/algorithms/SANSMove-v1.rst index f9961d61393..9fd885cd2fb 100644 --- a/docs/source/algorithms/SANSMove-v1.rst +++ b/docs/source/algorithms/SANSMove-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSNormalizeToMonitor-v1.rst b/docs/source/algorithms/SANSNormalizeToMonitor-v1.rst index 1ae60263d7a..6428517cdce 100644 --- a/docs/source/algorithms/SANSNormalizeToMonitor-v1.rst +++ b/docs/source/algorithms/SANSNormalizeToMonitor-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSReduction-v1.rst b/docs/source/algorithms/SANSReduction-v1.rst index 572972a1d97..b971806dd52 100644 --- a/docs/source/algorithms/SANSReduction-v1.rst +++ b/docs/source/algorithms/SANSReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSSave-v1.rst b/docs/source/algorithms/SANSSave-v1.rst index 2c2cd936453..3bb80b67177 100644 --- a/docs/source/algorithms/SANSSave-v1.rst +++ b/docs/source/algorithms/SANSSave-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSScale-v1.rst b/docs/source/algorithms/SANSScale-v1.rst index d02b6ea156e..461a0fe4940 100644 --- a/docs/source/algorithms/SANSScale-v1.rst +++ b/docs/source/algorithms/SANSScale-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSSensitivityCorrection-v1.rst b/docs/source/algorithms/SANSSensitivityCorrection-v1.rst index 0281a60b75e..9b9381673ca 100644 --- a/docs/source/algorithms/SANSSensitivityCorrection-v1.rst +++ b/docs/source/algorithms/SANSSensitivityCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSSliceEvent-v1.rst b/docs/source/algorithms/SANSSliceEvent-v1.rst index 3016309f4a6..77aad4d01d1 100644 --- a/docs/source/algorithms/SANSSliceEvent-v1.rst +++ b/docs/source/algorithms/SANSSliceEvent-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSSolidAngleCorrection-v1.rst b/docs/source/algorithms/SANSSolidAngleCorrection-v1.rst index 2cd96afadf8..ad5c4cebaa0 100644 --- a/docs/source/algorithms/SANSSolidAngleCorrection-v1.rst +++ b/docs/source/algorithms/SANSSolidAngleCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSStitch-v1.rst b/docs/source/algorithms/SANSStitch-v1.rst index 938dd4683f8..9b20f09d441 100644 --- a/docs/source/algorithms/SANSStitch-v1.rst +++ b/docs/source/algorithms/SANSStitch-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSSubtract-v1.rst b/docs/source/algorithms/SANSSubtract-v1.rst index b74a65c7042..22674d01c9c 100644 --- a/docs/source/algorithms/SANSSubtract-v1.rst +++ b/docs/source/algorithms/SANSSubtract-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SANSWideAngleCorrection-v1.rst b/docs/source/algorithms/SANSWideAngleCorrection-v1.rst index b3e6aac35bd..f2fd5aa11cd 100644 --- a/docs/source/algorithms/SANSWideAngleCorrection-v1.rst +++ b/docs/source/algorithms/SANSWideAngleCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SCDCalibratePanels-v1.rst b/docs/source/algorithms/SCDCalibratePanels-v1.rst index 43dac886c24..c07c43128af 100644 --- a/docs/source/algorithms/SCDCalibratePanels-v1.rst +++ b/docs/source/algorithms/SCDCalibratePanels-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -37,7 +37,7 @@ The panels and packs' parameters are optimized in parallel. An option is available to adjust the panel widths and heights for Rectangular Detectors in a second iteration with all the other parameters fixed. OUTPUT workspaces and files: -============================ +############################ 1) The results are saved to an ISAW-like DetCal file and optionally in an xml file that can be used with the :ref:`LoadParameterFile <algm-LoadParameterFile>` algorithm. diff --git a/docs/source/algorithms/SNAPReduce-v1.rst b/docs/source/algorithms/SNAPReduce-v1.rst index 7d79a441b31..3923b002634 100644 --- a/docs/source/algorithms/SNAPReduce-v1.rst +++ b/docs/source/algorithms/SNAPReduce-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SNSPowderReduction-v1.rst b/docs/source/algorithms/SNSPowderReduction-v1.rst index c4cfe68c4f8..5ce240037e5 100644 --- a/docs/source/algorithms/SNSPowderReduction-v1.rst +++ b/docs/source/algorithms/SNSPowderReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SassenaFFT-v1.rst b/docs/source/algorithms/SassenaFFT-v1.rst index edcc923c834..910dcc900df 100644 --- a/docs/source/algorithms/SassenaFFT-v1.rst +++ b/docs/source/algorithms/SassenaFFT-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveANSTOAscii-v1.rst b/docs/source/algorithms/SaveANSTOAscii-v1.rst index 3f7e6cf70bb..b56cc467146 100644 --- a/docs/source/algorithms/SaveANSTOAscii-v1.rst +++ b/docs/source/algorithms/SaveANSTOAscii-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveAscii-v1.rst b/docs/source/algorithms/SaveAscii-v1.rst index c7c417429d5..2aa848631a3 100644 --- a/docs/source/algorithms/SaveAscii-v1.rst +++ b/docs/source/algorithms/SaveAscii-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveAscii-v2.rst b/docs/source/algorithms/SaveAscii-v2.rst index a03c8dc8ffe..a35e60f03bf 100644 --- a/docs/source/algorithms/SaveAscii-v2.rst +++ b/docs/source/algorithms/SaveAscii-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveCSV-v1.rst b/docs/source/algorithms/SaveCSV-v1.rst index 627b3ca3986..43c7a7253f0 100644 --- a/docs/source/algorithms/SaveCSV-v1.rst +++ b/docs/source/algorithms/SaveCSV-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveCalFile-v1.rst b/docs/source/algorithms/SaveCalFile-v1.rst index e2e9171111b..5efebfccc2b 100644 --- a/docs/source/algorithms/SaveCalFile-v1.rst +++ b/docs/source/algorithms/SaveCalFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveCanSAS1D-v1.rst b/docs/source/algorithms/SaveCanSAS1D-v1.rst index e13fe9d5b5a..016d4daafd2 100644 --- a/docs/source/algorithms/SaveCanSAS1D-v1.rst +++ b/docs/source/algorithms/SaveCanSAS1D-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveCanSAS1D-v2.rst b/docs/source/algorithms/SaveCanSAS1D-v2.rst index e704f271dc3..ed4ff014e3b 100644 --- a/docs/source/algorithms/SaveCanSAS1D-v2.rst +++ b/docs/source/algorithms/SaveCanSAS1D-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveDaveGrp-v1.rst b/docs/source/algorithms/SaveDaveGrp-v1.rst index a2267c636e0..40ce0af178b 100644 --- a/docs/source/algorithms/SaveDaveGrp-v1.rst +++ b/docs/source/algorithms/SaveDaveGrp-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveDetectorsGrouping-v1.rst b/docs/source/algorithms/SaveDetectorsGrouping-v1.rst index 5f356aca0f5..221ec51d2ef 100644 --- a/docs/source/algorithms/SaveDetectorsGrouping-v1.rst +++ b/docs/source/algorithms/SaveDetectorsGrouping-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveDiffCal-v1.rst b/docs/source/algorithms/SaveDiffCal-v1.rst index fa6f577ccbe..a2ebc766f3d 100644 --- a/docs/source/algorithms/SaveDiffCal-v1.rst +++ b/docs/source/algorithms/SaveDiffCal-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveDiffFittingAscii-v1.rst b/docs/source/algorithms/SaveDiffFittingAscii-v1.rst index 969d9245746..5997581c202 100644 --- a/docs/source/algorithms/SaveDiffFittingAscii-v1.rst +++ b/docs/source/algorithms/SaveDiffFittingAscii-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveDspacemap-v1.rst b/docs/source/algorithms/SaveDspacemap-v1.rst index 2ff397771fb..d49f557541d 100644 --- a/docs/source/algorithms/SaveDspacemap-v1.rst +++ b/docs/source/algorithms/SaveDspacemap-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveFITS-v1.rst b/docs/source/algorithms/SaveFITS-v1.rst index 9ab62318637..54337346cab 100644 --- a/docs/source/algorithms/SaveFITS-v1.rst +++ b/docs/source/algorithms/SaveFITS-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveFocusedXYE-v1.rst b/docs/source/algorithms/SaveFocusedXYE-v1.rst index 53a1c4186d3..d654cdfac33 100644 --- a/docs/source/algorithms/SaveFocusedXYE-v1.rst +++ b/docs/source/algorithms/SaveFocusedXYE-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveFullprofResolution-v1.rst b/docs/source/algorithms/SaveFullprofResolution-v1.rst index 621a9cc84bc..5f4203d5af4 100644 --- a/docs/source/algorithms/SaveFullprofResolution-v1.rst +++ b/docs/source/algorithms/SaveFullprofResolution-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveGSASInstrumentFile-v1.rst b/docs/source/algorithms/SaveGSASInstrumentFile-v1.rst index f2690b6d6e3..1b44511f1ab 100644 --- a/docs/source/algorithms/SaveGSASInstrumentFile-v1.rst +++ b/docs/source/algorithms/SaveGSASInstrumentFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveGSS-v1.rst b/docs/source/algorithms/SaveGSS-v1.rst index b94f8acfcaa..c6d2a2c0f8d 100644 --- a/docs/source/algorithms/SaveGSS-v1.rst +++ b/docs/source/algorithms/SaveGSS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveHKL-v1.rst b/docs/source/algorithms/SaveHKL-v1.rst index c2cc616f346..c293e2eee2c 100644 --- a/docs/source/algorithms/SaveHKL-v1.rst +++ b/docs/source/algorithms/SaveHKL-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveILLCosmosAscii-v1.rst b/docs/source/algorithms/SaveILLCosmosAscii-v1.rst index 41d27f23b35..8864a170eec 100644 --- a/docs/source/algorithms/SaveILLCosmosAscii-v1.rst +++ b/docs/source/algorithms/SaveILLCosmosAscii-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveISISNexus-v1.rst b/docs/source/algorithms/SaveISISNexus-v1.rst index 484ceecba5d..0454c048522 100644 --- a/docs/source/algorithms/SaveISISNexus-v1.rst +++ b/docs/source/algorithms/SaveISISNexus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveIsawDetCal-v1.rst b/docs/source/algorithms/SaveIsawDetCal-v1.rst index 39cb1d6e763..c88fbe53079 100644 --- a/docs/source/algorithms/SaveIsawDetCal-v1.rst +++ b/docs/source/algorithms/SaveIsawDetCal-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveIsawPeaks-v1.rst b/docs/source/algorithms/SaveIsawPeaks-v1.rst index 64357cacb45..212ba072dea 100644 --- a/docs/source/algorithms/SaveIsawPeaks-v1.rst +++ b/docs/source/algorithms/SaveIsawPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -30,6 +30,8 @@ Usage # Add two peaks to the peaks workspace AddPeak( pws, ws, TOF=100, DetectorID=101, Height=1 ) AddPeak( pws, ws, TOF=200, DetectorID=102, Height=2 ) + peak = pws.getPeak(1).setPeakNumber(2) + peak = pws.getPeak(2).setPeakNumber(3) # Save the peaks workspace to a file in the user's home directory isawPeaksFilePath = os.path.expanduser('~/MantidUsageExample_ISawFile.peaks') diff --git a/docs/source/algorithms/SaveIsawQvector-v1.rst b/docs/source/algorithms/SaveIsawQvector-v1.rst index be2e824c08e..eb32744a503 100644 --- a/docs/source/algorithms/SaveIsawQvector-v1.rst +++ b/docs/source/algorithms/SaveIsawQvector-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveIsawUB-v1.rst b/docs/source/algorithms/SaveIsawUB-v1.rst index 11415c868c8..f364b22c295 100644 --- a/docs/source/algorithms/SaveIsawUB-v1.rst +++ b/docs/source/algorithms/SaveIsawUB-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveLauenorm-v1.rst b/docs/source/algorithms/SaveLauenorm-v1.rst index 0ab304c5621..862f9533d37 100644 --- a/docs/source/algorithms/SaveLauenorm-v1.rst +++ b/docs/source/algorithms/SaveLauenorm-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveMD-v1.rst b/docs/source/algorithms/SaveMD-v1.rst index e0ff00e221e..ebda8ebaca7 100644 --- a/docs/source/algorithms/SaveMD-v1.rst +++ b/docs/source/algorithms/SaveMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveMD-v2.rst b/docs/source/algorithms/SaveMD-v2.rst index baf9a2f931a..443ec2b3c5d 100644 --- a/docs/source/algorithms/SaveMD-v2.rst +++ b/docs/source/algorithms/SaveMD-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveMDWorkspaceToVTK-v1.rst b/docs/source/algorithms/SaveMDWorkspaceToVTK-v1.rst index 19c90a8f328..83ff41c6bb5 100644 --- a/docs/source/algorithms/SaveMDWorkspaceToVTK-v1.rst +++ b/docs/source/algorithms/SaveMDWorkspaceToVTK-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveMask-v1.rst b/docs/source/algorithms/SaveMask-v1.rst index c94eb79e3ea..8dcb04c1733 100644 --- a/docs/source/algorithms/SaveMask-v1.rst +++ b/docs/source/algorithms/SaveMask-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveNISTDAT-v1.rst b/docs/source/algorithms/SaveNISTDAT-v1.rst index e9d30acff91..7019a91dea7 100644 --- a/docs/source/algorithms/SaveNISTDAT-v1.rst +++ b/docs/source/algorithms/SaveNISTDAT-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveNXSPE-v1.rst b/docs/source/algorithms/SaveNXSPE-v1.rst index 61dcc9d20b3..c51ff193f95 100644 --- a/docs/source/algorithms/SaveNXSPE-v1.rst +++ b/docs/source/algorithms/SaveNXSPE-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveNXTomo-v1.rst b/docs/source/algorithms/SaveNXTomo-v1.rst index 495f186f21c..9c0ac61c089 100644 --- a/docs/source/algorithms/SaveNXTomo-v1.rst +++ b/docs/source/algorithms/SaveNXTomo-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveNXcanSAS-v1.rst b/docs/source/algorithms/SaveNXcanSAS-v1.rst index 90a9535c6b2..426c54d9241 100644 --- a/docs/source/algorithms/SaveNXcanSAS-v1.rst +++ b/docs/source/algorithms/SaveNXcanSAS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveNexus-v1.rst b/docs/source/algorithms/SaveNexus-v1.rst index dd22495bd16..f9f19ce382b 100644 --- a/docs/source/algorithms/SaveNexus-v1.rst +++ b/docs/source/algorithms/SaveNexus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveNexusPD-v1.rst b/docs/source/algorithms/SaveNexusPD-v1.rst index 2b18441beaf..475405a9e57 100644 --- a/docs/source/algorithms/SaveNexusPD-v1.rst +++ b/docs/source/algorithms/SaveNexusPD-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveNexusProcessed-v1.rst b/docs/source/algorithms/SaveNexusProcessed-v1.rst index c0ee6990203..3f22356ced7 100644 --- a/docs/source/algorithms/SaveNexusProcessed-v1.rst +++ b/docs/source/algorithms/SaveNexusProcessed-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveOpenGenieAscii-v1.rst b/docs/source/algorithms/SaveOpenGenieAscii-v1.rst index 6d853c65781..b0c021f2d7e 100644 --- a/docs/source/algorithms/SaveOpenGenieAscii-v1.rst +++ b/docs/source/algorithms/SaveOpenGenieAscii-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SavePAR-v1.rst b/docs/source/algorithms/SavePAR-v1.rst index 11274afe87b..78db4aa3108 100644 --- a/docs/source/algorithms/SavePAR-v1.rst +++ b/docs/source/algorithms/SavePAR-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SavePDFGui-v1.rst b/docs/source/algorithms/SavePDFGui-v1.rst index 1b964b46487..92352598e21 100644 --- a/docs/source/algorithms/SavePDFGui-v1.rst +++ b/docs/source/algorithms/SavePDFGui-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SavePHX-v1.rst b/docs/source/algorithms/SavePHX-v1.rst index 49ff0e73bb5..09d5003a03a 100644 --- a/docs/source/algorithms/SavePHX-v1.rst +++ b/docs/source/algorithms/SavePHX-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveParameterFile-v1.rst b/docs/source/algorithms/SaveParameterFile-v1.rst index 3903cf34bd7..be2795351b6 100644 --- a/docs/source/algorithms/SaveParameterFile-v1.rst +++ b/docs/source/algorithms/SaveParameterFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SavePlot1D-v1.rst b/docs/source/algorithms/SavePlot1D-v1.rst index b5f9ad78c89..b29f32c4187 100644 --- a/docs/source/algorithms/SavePlot1D-v1.rst +++ b/docs/source/algorithms/SavePlot1D-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SavePlot1DAsJson-v1.rst b/docs/source/algorithms/SavePlot1DAsJson-v1.rst index 85bb7a8d062..414c7e478f7 100644 --- a/docs/source/algorithms/SavePlot1DAsJson-v1.rst +++ b/docs/source/algorithms/SavePlot1DAsJson-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveRKH-v1.rst b/docs/source/algorithms/SaveRKH-v1.rst index 30cb6726492..26c0ecdedb8 100644 --- a/docs/source/algorithms/SaveRKH-v1.rst +++ b/docs/source/algorithms/SaveRKH-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveReflCustomAscii-v1.rst b/docs/source/algorithms/SaveReflCustomAscii-v1.rst index 96a531afc3f..81d9b39b96f 100644 --- a/docs/source/algorithms/SaveReflCustomAscii-v1.rst +++ b/docs/source/algorithms/SaveReflCustomAscii-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveReflThreeColumnAscii-v1.rst b/docs/source/algorithms/SaveReflThreeColumnAscii-v1.rst index 842b7109033..7f25d60b8e4 100644 --- a/docs/source/algorithms/SaveReflThreeColumnAscii-v1.rst +++ b/docs/source/algorithms/SaveReflThreeColumnAscii-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveReflections-v1.rst b/docs/source/algorithms/SaveReflections-v1.rst index f1578a110c7..f4a9755cce7 100644 --- a/docs/source/algorithms/SaveReflections-v1.rst +++ b/docs/source/algorithms/SaveReflections-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveSESANS-v1.rst b/docs/source/algorithms/SaveSESANS-v1.rst index 1d53164654e..96b4819c112 100644 --- a/docs/source/algorithms/SaveSESANS-v1.rst +++ b/docs/source/algorithms/SaveSESANS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveSPE-v1.rst b/docs/source/algorithms/SaveSPE-v1.rst index 7cd4c44a9a0..fa29314aa71 100644 --- a/docs/source/algorithms/SaveSPE-v1.rst +++ b/docs/source/algorithms/SaveSPE-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveTBL-v1.rst b/docs/source/algorithms/SaveTBL-v1.rst index f17c7d9eb70..822c57f3c4a 100644 --- a/docs/source/algorithms/SaveTBL-v1.rst +++ b/docs/source/algorithms/SaveTBL-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveToSNSHistogramNexus-v1.rst b/docs/source/algorithms/SaveToSNSHistogramNexus-v1.rst index eb6f5f53a27..fb5c24ebd95 100644 --- a/docs/source/algorithms/SaveToSNSHistogramNexus-v1.rst +++ b/docs/source/algorithms/SaveToSNSHistogramNexus-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveVTK-v1.rst b/docs/source/algorithms/SaveVTK-v1.rst index b0bc1962e20..9e4f3cbd409 100644 --- a/docs/source/algorithms/SaveVTK-v1.rst +++ b/docs/source/algorithms/SaveVTK-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveVulcanGSS-v1.rst b/docs/source/algorithms/SaveVulcanGSS-v1.rst index 02dad60760f..db8f998453d 100644 --- a/docs/source/algorithms/SaveVulcanGSS-v1.rst +++ b/docs/source/algorithms/SaveVulcanGSS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveYDA-v1.rst b/docs/source/algorithms/SaveYDA-v1.rst index fd7e62d4519..a0c122544fc 100644 --- a/docs/source/algorithms/SaveYDA-v1.rst +++ b/docs/source/algorithms/SaveYDA-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SaveZODS-v1.rst b/docs/source/algorithms/SaveZODS-v1.rst index a8eae4a0181..b18e507c886 100644 --- a/docs/source/algorithms/SaveZODS-v1.rst +++ b/docs/source/algorithms/SaveZODS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Scale-v1.rst b/docs/source/algorithms/Scale-v1.rst index 2e9d1202974..0afc60473c3 100644 --- a/docs/source/algorithms/Scale-v1.rst +++ b/docs/source/algorithms/Scale-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ScaleX-v1.rst b/docs/source/algorithms/ScaleX-v1.rst index 443e864f69d..f73d22db3ed 100644 --- a/docs/source/algorithms/ScaleX-v1.rst +++ b/docs/source/algorithms/ScaleX-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Segfault-v1.rst b/docs/source/algorithms/Segfault-v1.rst index 46d811401c3..200d83f64c6 100644 --- a/docs/source/algorithms/Segfault-v1.rst +++ b/docs/source/algorithms/Segfault-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SelectCellOfType-v1.rst b/docs/source/algorithms/SelectCellOfType-v1.rst index 76a02f6b438..a0e36580cd4 100644 --- a/docs/source/algorithms/SelectCellOfType-v1.rst +++ b/docs/source/algorithms/SelectCellOfType-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SelectCellWithForm-v1.rst b/docs/source/algorithms/SelectCellWithForm-v1.rst index b85608ad3f8..67219f6beb9 100644 --- a/docs/source/algorithms/SelectCellWithForm-v1.rst +++ b/docs/source/algorithms/SelectCellWithForm-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SelectNexusFilesByMetadata-v1.rst b/docs/source/algorithms/SelectNexusFilesByMetadata-v1.rst index 6207b7c5591..905a4324444 100644 --- a/docs/source/algorithms/SelectNexusFilesByMetadata-v1.rst +++ b/docs/source/algorithms/SelectNexusFilesByMetadata-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetBeam-v1.rst b/docs/source/algorithms/SetBeam-v1.rst index 6bafc93088e..87cecd620e5 100644 --- a/docs/source/algorithms/SetBeam-v1.rst +++ b/docs/source/algorithms/SetBeam-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetDetScale-v1.rst b/docs/source/algorithms/SetDetScale-v1.rst index ca1a0e36a8a..466cf165cef 100644 --- a/docs/source/algorithms/SetDetScale-v1.rst +++ b/docs/source/algorithms/SetDetScale-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetGoniometer-v1.rst b/docs/source/algorithms/SetGoniometer-v1.rst index d8c47595fe3..c13b71b14b8 100644 --- a/docs/source/algorithms/SetGoniometer-v1.rst +++ b/docs/source/algorithms/SetGoniometer-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetInstrumentParameter-v1.rst b/docs/source/algorithms/SetInstrumentParameter-v1.rst index 07d3193ca4b..b3280db781e 100644 --- a/docs/source/algorithms/SetInstrumentParameter-v1.rst +++ b/docs/source/algorithms/SetInstrumentParameter-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetMDFrame-v1.rst b/docs/source/algorithms/SetMDFrame-v1.rst index a53653f95fe..c722fcadd94 100644 --- a/docs/source/algorithms/SetMDFrame-v1.rst +++ b/docs/source/algorithms/SetMDFrame-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetMDUsingMask-v1.rst b/docs/source/algorithms/SetMDUsingMask-v1.rst index 1c82ef7a038..97519a88c55 100644 --- a/docs/source/algorithms/SetMDUsingMask-v1.rst +++ b/docs/source/algorithms/SetMDUsingMask-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetSample-v1.rst b/docs/source/algorithms/SetSample-v1.rst index 50ed6a778b9..9d7e6155da6 100644 --- a/docs/source/algorithms/SetSample-v1.rst +++ b/docs/source/algorithms/SetSample-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetSampleMaterial-v1.rst b/docs/source/algorithms/SetSampleMaterial-v1.rst index 35cc486ecac..af4760a9cb0 100644 --- a/docs/source/algorithms/SetSampleMaterial-v1.rst +++ b/docs/source/algorithms/SetSampleMaterial-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetScalingPSD-v1.rst b/docs/source/algorithms/SetScalingPSD-v1.rst index 2e4d2165209..10f5f85cf35 100644 --- a/docs/source/algorithms/SetScalingPSD-v1.rst +++ b/docs/source/algorithms/SetScalingPSD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetSpecialCoordinates-v1.rst b/docs/source/algorithms/SetSpecialCoordinates-v1.rst index 8fc2df29a2f..e712aae43ef 100644 --- a/docs/source/algorithms/SetSpecialCoordinates-v1.rst +++ b/docs/source/algorithms/SetSpecialCoordinates-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetUB-v1.rst b/docs/source/algorithms/SetUB-v1.rst index b577dfa18ab..07961ff32cf 100644 --- a/docs/source/algorithms/SetUB-v1.rst +++ b/docs/source/algorithms/SetUB-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetUncertainties-v1.rst b/docs/source/algorithms/SetUncertainties-v1.rst index 0c6e4e66d99..ddd7b113893 100644 --- a/docs/source/algorithms/SetUncertainties-v1.rst +++ b/docs/source/algorithms/SetUncertainties-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetupEQSANSReduction-v1.rst b/docs/source/algorithms/SetupEQSANSReduction-v1.rst index 0473eefc42b..b4927b948fa 100644 --- a/docs/source/algorithms/SetupEQSANSReduction-v1.rst +++ b/docs/source/algorithms/SetupEQSANSReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetupHFIRReduction-v1.rst b/docs/source/algorithms/SetupHFIRReduction-v1.rst index c99561635ef..0ecfc4a76e1 100644 --- a/docs/source/algorithms/SetupHFIRReduction-v1.rst +++ b/docs/source/algorithms/SetupHFIRReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SetupILLD33Reduction-v1.rst b/docs/source/algorithms/SetupILLD33Reduction-v1.rst index 92d3513dd32..e5dbb866931 100644 --- a/docs/source/algorithms/SetupILLD33Reduction-v1.rst +++ b/docs/source/algorithms/SetupILLD33Reduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ShiftLogTime-v1.rst b/docs/source/algorithms/ShiftLogTime-v1.rst index 4c2a0abc090..d66c3df887a 100644 --- a/docs/source/algorithms/ShiftLogTime-v1.rst +++ b/docs/source/algorithms/ShiftLogTime-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ShowPeakHKLOffsets-v1.rst b/docs/source/algorithms/ShowPeakHKLOffsets-v1.rst index e3dedcf03ed..e22d8273d34 100644 --- a/docs/source/algorithms/ShowPeakHKLOffsets-v1.rst +++ b/docs/source/algorithms/ShowPeakHKLOffsets-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ShowPossibleCells-v1.rst b/docs/source/algorithms/ShowPossibleCells-v1.rst index 9ff6b3bdec5..8341b231a72 100644 --- a/docs/source/algorithms/ShowPossibleCells-v1.rst +++ b/docs/source/algorithms/ShowPossibleCells-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SignalOverError-v1.rst b/docs/source/algorithms/SignalOverError-v1.rst index ed1d90ef78b..2f883613529 100644 --- a/docs/source/algorithms/SignalOverError-v1.rst +++ b/docs/source/algorithms/SignalOverError-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SimpleShapeMonteCarloAbsorption-v1.rst b/docs/source/algorithms/SimpleShapeMonteCarloAbsorption-v1.rst index bd0fca8d81c..2df74518e4a 100644 --- a/docs/source/algorithms/SimpleShapeMonteCarloAbsorption-v1.rst +++ b/docs/source/algorithms/SimpleShapeMonteCarloAbsorption-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SimulateResolutionConvolvedModel-v1.rst b/docs/source/algorithms/SimulateResolutionConvolvedModel-v1.rst index 29ff13b3c9a..bd38f354277 100644 --- a/docs/source/algorithms/SimulateResolutionConvolvedModel-v1.rst +++ b/docs/source/algorithms/SimulateResolutionConvolvedModel-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SimulatedDensityOfStates-v1.rst b/docs/source/algorithms/SimulatedDensityOfStates-v1.rst index 4237e7c85e7..08639ea28bf 100644 --- a/docs/source/algorithms/SimulatedDensityOfStates-v1.rst +++ b/docs/source/algorithms/SimulatedDensityOfStates-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SingleCrystalDiffuseReduction-v1.rst b/docs/source/algorithms/SingleCrystalDiffuseReduction-v1.rst index 6efc6c78d5f..95a91fb389d 100644 --- a/docs/source/algorithms/SingleCrystalDiffuseReduction-v1.rst +++ b/docs/source/algorithms/SingleCrystalDiffuseReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SliceMD-v1.rst b/docs/source/algorithms/SliceMD-v1.rst index a8a1a78110e..5da7f957078 100644 --- a/docs/source/algorithms/SliceMD-v1.rst +++ b/docs/source/algorithms/SliceMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SliceMDHisto-v1.rst b/docs/source/algorithms/SliceMDHisto-v1.rst index 9014403ae15..aaafa5507b1 100644 --- a/docs/source/algorithms/SliceMDHisto-v1.rst +++ b/docs/source/algorithms/SliceMDHisto-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SmoothData-v1.rst b/docs/source/algorithms/SmoothData-v1.rst index c958fa0d90a..c6058b2799a 100644 --- a/docs/source/algorithms/SmoothData-v1.rst +++ b/docs/source/algorithms/SmoothData-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SmoothMD-v1.rst b/docs/source/algorithms/SmoothMD-v1.rst index f138b9f5cd9..7dca3269a72 100644 --- a/docs/source/algorithms/SmoothMD-v1.rst +++ b/docs/source/algorithms/SmoothMD-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SmoothNeighbours-v1.rst b/docs/source/algorithms/SmoothNeighbours-v1.rst index 3ade8959f58..83520295a0d 100644 --- a/docs/source/algorithms/SmoothNeighbours-v1.rst +++ b/docs/source/algorithms/SmoothNeighbours-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SofQW-v1.rst b/docs/source/algorithms/SofQW-v1.rst index fd6f42bb860..117edc41efe 100644 --- a/docs/source/algorithms/SofQW-v1.rst +++ b/docs/source/algorithms/SofQW-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SofQWCentre-v1.rst b/docs/source/algorithms/SofQWCentre-v1.rst index c98c26f5217..da9e7a8db99 100644 --- a/docs/source/algorithms/SofQWCentre-v1.rst +++ b/docs/source/algorithms/SofQWCentre-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SofQWMoments-v1.rst b/docs/source/algorithms/SofQWMoments-v1.rst index a1854bd96ae..2da6a995b36 100644 --- a/docs/source/algorithms/SofQWMoments-v1.rst +++ b/docs/source/algorithms/SofQWMoments-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SofQWMomentsScan-v1.rst b/docs/source/algorithms/SofQWMomentsScan-v1.rst index 643c8fc903a..161c38ac964 100644 --- a/docs/source/algorithms/SofQWMomentsScan-v1.rst +++ b/docs/source/algorithms/SofQWMomentsScan-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SofQWNormalisedPolygon-v1.rst b/docs/source/algorithms/SofQWNormalisedPolygon-v1.rst index 8be67c4e960..39c665271d0 100644 --- a/docs/source/algorithms/SofQWNormalisedPolygon-v1.rst +++ b/docs/source/algorithms/SofQWNormalisedPolygon-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SofQWPolygon-v1.rst b/docs/source/algorithms/SofQWPolygon-v1.rst index f07a5cd549d..de2e5385c06 100644 --- a/docs/source/algorithms/SofQWPolygon-v1.rst +++ b/docs/source/algorithms/SofQWPolygon-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SolidAngle-v1.rst b/docs/source/algorithms/SolidAngle-v1.rst index cf54086f2b7..632b576e013 100644 --- a/docs/source/algorithms/SolidAngle-v1.rst +++ b/docs/source/algorithms/SolidAngle-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SortByQVectors-v1.rst b/docs/source/algorithms/SortByQVectors-v1.rst index b290618a9e1..1759811c40b 100644 --- a/docs/source/algorithms/SortByQVectors-v1.rst +++ b/docs/source/algorithms/SortByQVectors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SortDetectors-v1.rst b/docs/source/algorithms/SortDetectors-v1.rst index 8e6a0fbf357..120169ba367 100644 --- a/docs/source/algorithms/SortDetectors-v1.rst +++ b/docs/source/algorithms/SortDetectors-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SortEvents-v1.rst b/docs/source/algorithms/SortEvents-v1.rst index 3d188ac2e6c..cc2d0d78bd0 100644 --- a/docs/source/algorithms/SortEvents-v1.rst +++ b/docs/source/algorithms/SortEvents-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SortHKL-v1.rst b/docs/source/algorithms/SortHKL-v1.rst index decf6733cfa..dd135aad819 100644 --- a/docs/source/algorithms/SortHKL-v1.rst +++ b/docs/source/algorithms/SortHKL-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -36,6 +36,15 @@ it belongs to, so that equivalent reflections have the same intensity and error Finally, the peaks in the output workspace are sorted by H, K and L. +The EquivalentsWorkspace contains specta that can be plotted for each set of +equivalent intensities. The X axis is the wavelength and the Y axis is the corrected intensity of the +peaks. The error is the difference in the intensity of that peak and the average for all equivalent +peaks. For example, see the 424 equivalent intensities in plot below. The intensity of the peak at +wavelength 0.5 is marked as an outlier by setting the error to the same value as the intensity. +The average intensity is 21903. + +.. figure:: /images/EquivalentIntensities.png + Usage ----- @@ -54,7 +63,7 @@ and rhombohedral centering: CellType='Hexagonal', Apply=True, Tolerance=0.2) # Run the SortHKL algorithm - sorted, chi2, statistics_table = SortHKL(peaks, PointGroup='-3m1 (Trigonal - Hexagonal)', + sorted, chi2, statistics_table, equivI = SortHKL(peaks, PointGroup='-3m1 (Trigonal - Hexagonal)', LatticeCentering='Rhombohedrally centred, obverse') statistics = statistics_table.row(0) diff --git a/docs/source/algorithms/SortPeaksWorkspace-v1.rst b/docs/source/algorithms/SortPeaksWorkspace-v1.rst index 778c0d233b5..96c37db8122 100644 --- a/docs/source/algorithms/SortPeaksWorkspace-v1.rst +++ b/docs/source/algorithms/SortPeaksWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SortTableWorkspace-v1.rst b/docs/source/algorithms/SortTableWorkspace-v1.rst index 1bc493ab2c0..0394b2223fa 100644 --- a/docs/source/algorithms/SortTableWorkspace-v1.rst +++ b/docs/source/algorithms/SortTableWorkspace-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SortXAxis-v1.rst b/docs/source/algorithms/SortXAxis-v1.rst index 7b14bd708d4..aaef5edd17e 100644 --- a/docs/source/algorithms/SortXAxis-v1.rst +++ b/docs/source/algorithms/SortXAxis-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -10,14 +10,12 @@ Description ----------- Clones the input :ref:`Matrix Workspaces <MatrixWorkspace>` and orders the -x-axis in an ascending fashion. Ensures that the y-axis and error data -is sorted in a consistent way with the x-axis. All x-values of the input -workspace MUST be in either a descending or ascending fashion before -passing to this algorithm. +x-axis in an ascending or descending fashion. Ensures that the y-axis and error data as well as optional Dx data +are sorted in a consistent way with the x-axis. This algorithm is for use with small workspaces loaded. It is particularly suitable for reformatting workspaces loaded via -:ref:`LoadAscii <algm-LoadAscii>`. Input workspaces must be a distribution. +:ref:`LoadAscii <algm-LoadAscii>`. Input workspaces must be point data. .. categories:: diff --git a/docs/source/algorithms/SpatialGrouping-v1.rst b/docs/source/algorithms/SpatialGrouping-v1.rst index 8093ac47e6f..2319b9bb8d5 100644 --- a/docs/source/algorithms/SpatialGrouping-v1.rst +++ b/docs/source/algorithms/SpatialGrouping-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SpecularReflectionCalculateTheta-v1.rst b/docs/source/algorithms/SpecularReflectionCalculateTheta-v1.rst index faf24f237d7..fccdd37e591 100644 --- a/docs/source/algorithms/SpecularReflectionCalculateTheta-v1.rst +++ b/docs/source/algorithms/SpecularReflectionCalculateTheta-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SpecularReflectionCalculateTheta-v2.rst b/docs/source/algorithms/SpecularReflectionCalculateTheta-v2.rst index 14916278a92..f5c58e38e25 100644 --- a/docs/source/algorithms/SpecularReflectionCalculateTheta-v2.rst +++ b/docs/source/algorithms/SpecularReflectionCalculateTheta-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SpecularReflectionPositionCorrect-v1.rst b/docs/source/algorithms/SpecularReflectionPositionCorrect-v1.rst index ae6d4ef34e1..a2d9cffa2c2 100644 --- a/docs/source/algorithms/SpecularReflectionPositionCorrect-v1.rst +++ b/docs/source/algorithms/SpecularReflectionPositionCorrect-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SpecularReflectionPositionCorrect-v2.rst b/docs/source/algorithms/SpecularReflectionPositionCorrect-v2.rst index 827a62c624b..1773378e953 100644 --- a/docs/source/algorithms/SpecularReflectionPositionCorrect-v2.rst +++ b/docs/source/algorithms/SpecularReflectionPositionCorrect-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SphericalAbsorption-v1.rst b/docs/source/algorithms/SphericalAbsorption-v1.rst index 3d137c98345..2f1262a5dda 100644 --- a/docs/source/algorithms/SphericalAbsorption-v1.rst +++ b/docs/source/algorithms/SphericalAbsorption-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SplineBackground-v1.rst b/docs/source/algorithms/SplineBackground-v1.rst index f42331afc3c..29e87dffd44 100644 --- a/docs/source/algorithms/SplineBackground-v1.rst +++ b/docs/source/algorithms/SplineBackground-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SplineInterpolation-v1.rst b/docs/source/algorithms/SplineInterpolation-v1.rst index 0eafdfb4828..3599cc0adee 100644 --- a/docs/source/algorithms/SplineInterpolation-v1.rst +++ b/docs/source/algorithms/SplineInterpolation-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SplineSmoothing-v1.rst b/docs/source/algorithms/SplineSmoothing-v1.rst index 1eaf64373a0..074d3dc8598 100644 --- a/docs/source/algorithms/SplineSmoothing-v1.rst +++ b/docs/source/algorithms/SplineSmoothing-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Squares-v1.rst b/docs/source/algorithms/Squares-v1.rst index 2edc154dd39..b958f9d217b 100644 --- a/docs/source/algorithms/Squares-v1.rst +++ b/docs/source/algorithms/Squares-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/StartLiveData-v1.rst b/docs/source/algorithms/StartLiveData-v1.rst index 8f4f36f5745..27df59b0e3d 100644 --- a/docs/source/algorithms/StartLiveData-v1.rst +++ b/docs/source/algorithms/StartLiveData-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/StartRemoteTransaction-v1.rst b/docs/source/algorithms/StartRemoteTransaction-v1.rst index a8ab4a1722e..130597d207c 100644 --- a/docs/source/algorithms/StartRemoteTransaction-v1.rst +++ b/docs/source/algorithms/StartRemoteTransaction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/StartRemoteTransaction-v2.rst b/docs/source/algorithms/StartRemoteTransaction-v2.rst index cade65226dd..830729b6a64 100644 --- a/docs/source/algorithms/StartRemoteTransaction-v2.rst +++ b/docs/source/algorithms/StartRemoteTransaction-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/StatisticsOfPeaksWorkspace-v1.rst b/docs/source/algorithms/StatisticsOfPeaksWorkspace-v1.rst index cade0d0e238..1006e3c2304 100644 --- a/docs/source/algorithms/StatisticsOfPeaksWorkspace-v1.rst +++ b/docs/source/algorithms/StatisticsOfPeaksWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -62,7 +62,7 @@ Usage CellType='Hexagonal', Apply=True, Tolerance=0.2) # Run the SortHKL algorithm - sorted, statistics_table = StatisticsOfPeaksWorkspace(peaks, PointGroup='-3m1 (Trigonal - Hexagonal)', + sorted, statistics_table, equivI = StatisticsOfPeaksWorkspace(peaks, PointGroup='-3m1 (Trigonal - Hexagonal)', LatticeCentering='Rhombohedrally centred, obverse', SortBy='Overall') diff --git a/docs/source/algorithms/StatisticsOfTableWorkspace-v1.rst b/docs/source/algorithms/StatisticsOfTableWorkspace-v1.rst index 5c2ac6f561f..c53256425cb 100644 --- a/docs/source/algorithms/StatisticsOfTableWorkspace-v1.rst +++ b/docs/source/algorithms/StatisticsOfTableWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/StepScan-v1.rst b/docs/source/algorithms/StepScan-v1.rst index a280ea67620..1bf845a392b 100644 --- a/docs/source/algorithms/StepScan-v1.rst +++ b/docs/source/algorithms/StepScan-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Stitch1D-v3.rst b/docs/source/algorithms/Stitch1D-v3.rst index 010ebcdb32a..f2286a97b30 100644 --- a/docs/source/algorithms/Stitch1D-v3.rst +++ b/docs/source/algorithms/Stitch1D-v3.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: @@ -73,52 +73,70 @@ Usage ----- **Example - a basic example using stitch1D to stitch two workspaces together.** -.. testcode:: ExStitch1DSimple +.. plot:: + :include-source: - import numpy as np + from mantid.simpleapi import * + import matplotlib.pyplot as plt + import numpy as np - def gaussian(x, mu, sigma): - """Creates a gaussian peak centered on mu and with width sigma.""" - return (1/ sigma * np.sqrt(2 * np.pi)) * np.exp( - (x-mu)**2 / (2*sigma**2)) + def gaussian(x, mu, sigma): + """Creates a gaussian peak centered on mu and with width sigma.""" + return (1/ sigma * np.sqrt(2 * np.pi)) * np.exp( - (x-mu)**2 / (2*sigma**2)) - #create two histograms with a single peak in each one - x1 = np.arange(-1, 1, 0.02) - x2 = np.arange(0.4, 1.6, 0.02) - ws1 = CreateWorkspace(UnitX="1/q", DataX=x1, DataY=gaussian(x1[:-1], 0, 0.1)+1) - ws2 = CreateWorkspace(UnitX="1/q", DataX=x2, DataY=gaussian(x2[:-1], 1, 0.05)+1) + #create two histograms with a single peak in each one + x1 = np.arange(-1, 1, 0.02) + x2 = np.arange(0.4, 1.6, 0.02) + ws1 = CreateWorkspace(UnitX="1/q", DataX=x1, DataY=gaussian(x1[:-1], 0, 0.1)+1) + ws2 = CreateWorkspace(UnitX="1/q", DataX=x2, DataY=gaussian(x2[:-1], 1, 0.05)+1) - #stitch the histograms together - stitched, scale = Stitch1D(LHSWorkspace=ws1, RHSWorkspace=ws2, StartOverlap=0.4, EndOverlap=0.6, Params=0.02) + #stitch the histograms together + stitched, scale = Stitch1D(LHSWorkspace=ws1, RHSWorkspace=ws2, StartOverlap=0.4, EndOverlap=0.6, Params=0.02) -Output: + # plot the individual workspaces alongside the stitched one + fig, axs = plt.subplots(nrows=1, ncols=2, subplot_kw={'projection':'mantid'}) -.. image:: /images/Stitch1D1.png - :scale: 65 % - :alt: Stitch1D output - :align: center + axs[0].plot(mtd['ws1'], wkspIndex=0, label='ws1') + axs[0].plot(mtd['ws2'], wkspIndex=0, label='ws2') + axs[0].legend() + axs[1].plot(mtd['stitched'], wkspIndex=0, color='k', label='stitched') + axs[1].legend() + # uncomment the following line to show the plot window + #fig.show() **Example - a practical example using reflectometry data and a scale factor.** -.. testcode:: ExStitch1DPractical +.. plot:: + :include-source: - trans1 = Load('INTER00013463') - trans2 = Load('INTER00013464') + from mantid.simpleapi import * + import matplotlib.pyplot as plt - trans1_wav = CreateTransmissionWorkspaceAuto(trans1) - trans2_wav = CreateTransmissionWorkspaceAuto(trans2) + trans1 = Load('INTER00013463') + trans2 = Load('INTER00013464') - stitched_wav, y = Stitch1D(trans1_wav, trans2_wav, UseManualScaleFactor=True, ManualScaleFactor=0.85) + trans1_wav = CreateTransmissionWorkspaceAuto(trans1) + trans2_wav = CreateTransmissionWorkspaceAuto(trans2) -Output: + stitched_wav, y = Stitch1D(trans1_wav, trans2_wav, UseManualScaleFactor=True, ManualScaleFactor=0.85) -.. image:: /images/Stitch1D2.png - :scale: 65 % - :alt: Stitch1D output - :align: center + # plot the individual and stitched workspaces next to each other + fig, axs = plt.subplots(nrows=1, ncols=2, subplot_kw={'projection':'mantid'}) + axs[0].plot(trans1_wav, wkspIndex=0, label=str(trans1_wav)) + axs[0].plot(trans2_wav, wkspIndex=0, label=str(trans2_wav)) + axs[0].legend() + # use same y scale on both plots + ylimits = axs[0].get_ylim() + axs[1].plot(stitched_wav, wkspIndex=0, color='k', label='stitched') + axs[1].legend() + axs[1].set_ylim(ylimits) + + # uncomment the following line to show the plot window + #fig.show() .. categories:: .. sourcelink:: - :filename: Stitch1D \ No newline at end of file + :filename: Stitch1D diff --git a/docs/source/algorithms/Stitch1DMany-v1.rst b/docs/source/algorithms/Stitch1DMany-v1.rst index 1b508dcb9c6..20d10f3058a 100644 --- a/docs/source/algorithms/Stitch1DMany-v1.rst +++ b/docs/source/algorithms/Stitch1DMany-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/StopRemoteTransaction-v1.rst b/docs/source/algorithms/StopRemoteTransaction-v1.rst index 125656b108f..9ac246ac891 100644 --- a/docs/source/algorithms/StopRemoteTransaction-v1.rst +++ b/docs/source/algorithms/StopRemoteTransaction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/StopRemoteTransaction-v2.rst b/docs/source/algorithms/StopRemoteTransaction-v2.rst index 70fbf3dabbf..cf35f859f7b 100644 --- a/docs/source/algorithms/StopRemoteTransaction-v2.rst +++ b/docs/source/algorithms/StopRemoteTransaction-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/StringToPng-v1.rst b/docs/source/algorithms/StringToPng-v1.rst index 8e4af71b1a7..9b4fc275e16 100644 --- a/docs/source/algorithms/StringToPng-v1.rst +++ b/docs/source/algorithms/StringToPng-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/StripPeaks-v1.rst b/docs/source/algorithms/StripPeaks-v1.rst index d78e605fca9..4f80cbf2666 100644 --- a/docs/source/algorithms/StripPeaks-v1.rst +++ b/docs/source/algorithms/StripPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/StripVanadiumPeaks-v1.rst b/docs/source/algorithms/StripVanadiumPeaks-v1.rst index 8f875087017..d3e4307fb67 100644 --- a/docs/source/algorithms/StripVanadiumPeaks-v1.rst +++ b/docs/source/algorithms/StripVanadiumPeaks-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/StripVanadiumPeaks-v2.rst b/docs/source/algorithms/StripVanadiumPeaks-v2.rst index 9e7e84e974c..57a03fdff2c 100644 --- a/docs/source/algorithms/StripVanadiumPeaks-v2.rst +++ b/docs/source/algorithms/StripVanadiumPeaks-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SubmitRemoteJob-v1.rst b/docs/source/algorithms/SubmitRemoteJob-v1.rst index 98739d05b7d..3f8281395e1 100644 --- a/docs/source/algorithms/SubmitRemoteJob-v1.rst +++ b/docs/source/algorithms/SubmitRemoteJob-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SubmitRemoteJob-v2.rst b/docs/source/algorithms/SubmitRemoteJob-v2.rst index cfc51ebbe41..bcb7b407bf9 100644 --- a/docs/source/algorithms/SubmitRemoteJob-v2.rst +++ b/docs/source/algorithms/SubmitRemoteJob-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SuggestTibCNCS-v1.rst b/docs/source/algorithms/SuggestTibCNCS-v1.rst index 04af26e480a..79fdb56fb35 100644 --- a/docs/source/algorithms/SuggestTibCNCS-v1.rst +++ b/docs/source/algorithms/SuggestTibCNCS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SuggestTibHYSPEC-v1.rst b/docs/source/algorithms/SuggestTibHYSPEC-v1.rst index b840407d0a4..eab72f85282 100644 --- a/docs/source/algorithms/SuggestTibHYSPEC-v1.rst +++ b/docs/source/algorithms/SuggestTibHYSPEC-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SumEventsByLogValue-v1.rst b/docs/source/algorithms/SumEventsByLogValue-v1.rst index 5dd2f94f0de..5ee1996f11b 100644 --- a/docs/source/algorithms/SumEventsByLogValue-v1.rst +++ b/docs/source/algorithms/SumEventsByLogValue-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SumNeighbours-v1.rst b/docs/source/algorithms/SumNeighbours-v1.rst index 628123ad700..eead73708f1 100644 --- a/docs/source/algorithms/SumNeighbours-v1.rst +++ b/docs/source/algorithms/SumNeighbours-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SumOverlappingTubes-v1.rst b/docs/source/algorithms/SumOverlappingTubes-v1.rst index 733646374c1..852392968b9 100644 --- a/docs/source/algorithms/SumOverlappingTubes-v1.rst +++ b/docs/source/algorithms/SumOverlappingTubes-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SumRowColumn-v1.rst b/docs/source/algorithms/SumRowColumn-v1.rst index 3515c060ba5..55804d31c43 100644 --- a/docs/source/algorithms/SumRowColumn-v1.rst +++ b/docs/source/algorithms/SumRowColumn-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SumSpectra-v1.rst b/docs/source/algorithms/SumSpectra-v1.rst index c25ddcdb0b8..824e84c11ba 100644 --- a/docs/source/algorithms/SumSpectra-v1.rst +++ b/docs/source/algorithms/SumSpectra-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/SwapWidths-v1.rst b/docs/source/algorithms/SwapWidths-v1.rst index 72bb112d729..c1360be6676 100644 --- a/docs/source/algorithms/SwapWidths-v1.rst +++ b/docs/source/algorithms/SwapWidths-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Symmetrise-v1.rst b/docs/source/algorithms/Symmetrise-v1.rst index 1ff18b6d42c..43edae0384d 100644 --- a/docs/source/algorithms/Symmetrise-v1.rst +++ b/docs/source/algorithms/Symmetrise-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/TOFSANSResolution-v1.rst b/docs/source/algorithms/TOFSANSResolution-v1.rst index 1de749e2a30..404c8dce40d 100644 --- a/docs/source/algorithms/TOFSANSResolution-v1.rst +++ b/docs/source/algorithms/TOFSANSResolution-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/TOFSANSResolutionByPixel-v1.rst b/docs/source/algorithms/TOFSANSResolutionByPixel-v1.rst index 4c651b60bb5..19c146448cf 100644 --- a/docs/source/algorithms/TOFSANSResolutionByPixel-v1.rst +++ b/docs/source/algorithms/TOFSANSResolutionByPixel-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/TOFTOFCropWorkspace-v1.rst b/docs/source/algorithms/TOFTOFCropWorkspace-v1.rst index 5401eb666ef..57c006727d5 100644 --- a/docs/source/algorithms/TOFTOFCropWorkspace-v1.rst +++ b/docs/source/algorithms/TOFTOFCropWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/TOFTOFMergeRuns-v1.rst b/docs/source/algorithms/TOFTOFMergeRuns-v1.rst index 9ebcd6ad5f0..b7b8c9b38f2 100644 --- a/docs/source/algorithms/TOFTOFMergeRuns-v1.rst +++ b/docs/source/algorithms/TOFTOFMergeRuns-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/TOSCABankCorrection-v1.rst b/docs/source/algorithms/TOSCABankCorrection-v1.rst index 246cd57c330..9f62e5ec8bb 100644 --- a/docs/source/algorithms/TOSCABankCorrection-v1.rst +++ b/docs/source/algorithms/TOSCABankCorrection-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/TestWorkspaceGroupProperty-v1.rst b/docs/source/algorithms/TestWorkspaceGroupProperty-v1.rst index 6697bc246c5..49761c3a3f3 100644 --- a/docs/source/algorithms/TestWorkspaceGroupProperty-v1.rst +++ b/docs/source/algorithms/TestWorkspaceGroupProperty-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ThresholdMD-v1.rst b/docs/source/algorithms/ThresholdMD-v1.rst index b093fe10fb3..d36b21dcb20 100644 --- a/docs/source/algorithms/ThresholdMD-v1.rst +++ b/docs/source/algorithms/ThresholdMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/TimeSlice-v1.rst b/docs/source/algorithms/TimeSlice-v1.rst index 1093650e891..fade6435453 100644 --- a/docs/source/algorithms/TimeSlice-v1.rst +++ b/docs/source/algorithms/TimeSlice-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/TransformHKL-v1.rst b/docs/source/algorithms/TransformHKL-v1.rst index f7259e66b77..c45332e0205 100644 --- a/docs/source/algorithms/TransformHKL-v1.rst +++ b/docs/source/algorithms/TransformHKL-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/TransformMD-v1.rst b/docs/source/algorithms/TransformMD-v1.rst index e2df2485a92..30d35a37f53 100644 --- a/docs/source/algorithms/TransformMD-v1.rst +++ b/docs/source/algorithms/TransformMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/TransformToIqt-v1.rst b/docs/source/algorithms/TransformToIqt-v1.rst index 65aa3e41c86..fd6e7093f6b 100644 --- a/docs/source/algorithms/TransformToIqt-v1.rst +++ b/docs/source/algorithms/TransformToIqt-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Transpose-v1.rst b/docs/source/algorithms/Transpose-v1.rst index 0f1b630b43a..84cf52e8f8d 100644 --- a/docs/source/algorithms/Transpose-v1.rst +++ b/docs/source/algorithms/Transpose-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/Transpose3D-v1.rst b/docs/source/algorithms/Transpose3D-v1.rst index ddb63add8e1..386411cd110 100644 --- a/docs/source/algorithms/Transpose3D-v1.rst +++ b/docs/source/algorithms/Transpose3D-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/TransposeMD-v1.rst b/docs/source/algorithms/TransposeMD-v1.rst index 3d2715ce1ee..72c3487cae2 100644 --- a/docs/source/algorithms/TransposeMD-v1.rst +++ b/docs/source/algorithms/TransposeMD-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/USANSReduction-v1.rst b/docs/source/algorithms/USANSReduction-v1.rst index 9f069271b9a..8779eac3736 100644 --- a/docs/source/algorithms/USANSReduction-v1.rst +++ b/docs/source/algorithms/USANSReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/USANSSimulation-v1.rst b/docs/source/algorithms/USANSSimulation-v1.rst index d785a71a2e2..c549f0bfd1f 100644 --- a/docs/source/algorithms/USANSSimulation-v1.rst +++ b/docs/source/algorithms/USANSSimulation-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/UnGroupWorkspace-v1.rst b/docs/source/algorithms/UnGroupWorkspace-v1.rst index 4e4a3c37951..8f84d2a36b2 100644 --- a/docs/source/algorithms/UnGroupWorkspace-v1.rst +++ b/docs/source/algorithms/UnGroupWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/UnwrapMonitor-v1.rst b/docs/source/algorithms/UnwrapMonitor-v1.rst index 946dfe93213..16c242f67f6 100644 --- a/docs/source/algorithms/UnwrapMonitor-v1.rst +++ b/docs/source/algorithms/UnwrapMonitor-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/UnwrapMonitorsInTOF-v1.rst b/docs/source/algorithms/UnwrapMonitorsInTOF-v1.rst index ac81cb41e13..4330b6de550 100644 --- a/docs/source/algorithms/UnwrapMonitorsInTOF-v1.rst +++ b/docs/source/algorithms/UnwrapMonitorsInTOF-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/UnwrapSNS-v1.rst b/docs/source/algorithms/UnwrapSNS-v1.rst index 2ebcc6c4e95..39b1d63ff8e 100644 --- a/docs/source/algorithms/UnwrapSNS-v1.rst +++ b/docs/source/algorithms/UnwrapSNS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/UpdateInstrumentFromFile-v1.rst b/docs/source/algorithms/UpdateInstrumentFromFile-v1.rst index 93ded29927b..81011f0bd5d 100644 --- a/docs/source/algorithms/UpdateInstrumentFromFile-v1.rst +++ b/docs/source/algorithms/UpdateInstrumentFromFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/UpdatePeakParameterTableValue-v1.rst b/docs/source/algorithms/UpdatePeakParameterTableValue-v1.rst index ac2bcafff2d..dea5efa30f2 100644 --- a/docs/source/algorithms/UpdatePeakParameterTableValue-v1.rst +++ b/docs/source/algorithms/UpdatePeakParameterTableValue-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/UpdateScriptRepository-v1.rst b/docs/source/algorithms/UpdateScriptRepository-v1.rst index a5800a9a217..72188b53aee 100644 --- a/docs/source/algorithms/UpdateScriptRepository-v1.rst +++ b/docs/source/algorithms/UpdateScriptRepository-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/UploadRemoteFile-v1.rst b/docs/source/algorithms/UploadRemoteFile-v1.rst index 651dca4bb1b..058a5b2e4c2 100644 --- a/docs/source/algorithms/UploadRemoteFile-v1.rst +++ b/docs/source/algorithms/UploadRemoteFile-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/UploadRemoteFile-v2.rst b/docs/source/algorithms/UploadRemoteFile-v2.rst index 64e73c925b4..83449f2f1d7 100644 --- a/docs/source/algorithms/UploadRemoteFile-v2.rst +++ b/docs/source/algorithms/UploadRemoteFile-v2.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/UserFunction1D-v1.rst b/docs/source/algorithms/UserFunction1D-v1.rst index 1d6a7543bf0..c0cd951ed5a 100644 --- a/docs/source/algorithms/UserFunction1D-v1.rst +++ b/docs/source/algorithms/UserFunction1D-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/VelocityAutoCorrelations-v1.rst b/docs/source/algorithms/VelocityAutoCorrelations-v1.rst index 79cc52d0f10..f7e87a97cef 100644 --- a/docs/source/algorithms/VelocityAutoCorrelations-v1.rst +++ b/docs/source/algorithms/VelocityAutoCorrelations-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/VelocityCrossCorrelations-v1.rst b/docs/source/algorithms/VelocityCrossCorrelations-v1.rst index 1921525dada..5dfdb25767a 100644 --- a/docs/source/algorithms/VelocityCrossCorrelations-v1.rst +++ b/docs/source/algorithms/VelocityCrossCorrelations-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/VesuvioCalculateGammaBackground-v1.rst b/docs/source/algorithms/VesuvioCalculateGammaBackground-v1.rst index 1f627b96cbc..635e2a8cf6d 100644 --- a/docs/source/algorithms/VesuvioCalculateGammaBackground-v1.rst +++ b/docs/source/algorithms/VesuvioCalculateGammaBackground-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/VesuvioCalculateMS-v1.rst b/docs/source/algorithms/VesuvioCalculateMS-v1.rst index cbdf3958755..8d767a4d48c 100644 --- a/docs/source/algorithms/VesuvioCalculateMS-v1.rst +++ b/docs/source/algorithms/VesuvioCalculateMS-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/VesuvioCorrections-v1.rst b/docs/source/algorithms/VesuvioCorrections-v1.rst index 44259cdf5b1..df786dfde68 100644 --- a/docs/source/algorithms/VesuvioCorrections-v1.rst +++ b/docs/source/algorithms/VesuvioCorrections-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/VesuvioDiffractionReduction-v1.rst b/docs/source/algorithms/VesuvioDiffractionReduction-v1.rst index 7e040f332f1..cfd9527e29f 100644 --- a/docs/source/algorithms/VesuvioDiffractionReduction-v1.rst +++ b/docs/source/algorithms/VesuvioDiffractionReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/VesuvioL1ThetaResolution-v1.rst b/docs/source/algorithms/VesuvioL1ThetaResolution-v1.rst index c27d0c3dc6d..66258996068 100644 --- a/docs/source/algorithms/VesuvioL1ThetaResolution-v1.rst +++ b/docs/source/algorithms/VesuvioL1ThetaResolution-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/VesuvioPeakPrediction-v1.rst b/docs/source/algorithms/VesuvioPeakPrediction-v1.rst index 1277abd0fcb..6404c8dc759 100644 --- a/docs/source/algorithms/VesuvioPeakPrediction-v1.rst +++ b/docs/source/algorithms/VesuvioPeakPrediction-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/VesuvioPreFit-v1.rst b/docs/source/algorithms/VesuvioPreFit-v1.rst index cd754da96cc..c58ca280e29 100644 --- a/docs/source/algorithms/VesuvioPreFit-v1.rst +++ b/docs/source/algorithms/VesuvioPreFit-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/VesuvioResolution-v1.rst b/docs/source/algorithms/VesuvioResolution-v1.rst index 96a8742deda..dd7dc085ca5 100644 --- a/docs/source/algorithms/VesuvioResolution-v1.rst +++ b/docs/source/algorithms/VesuvioResolution-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/VesuvioTOFFit-v1.rst b/docs/source/algorithms/VesuvioTOFFit-v1.rst index 44161ced368..559ad342a23 100644 --- a/docs/source/algorithms/VesuvioTOFFit-v1.rst +++ b/docs/source/algorithms/VesuvioTOFFit-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/VesuvioThickness-v1.rst b/docs/source/algorithms/VesuvioThickness-v1.rst index 9933d3fe52a..fa04a4cdd4c 100644 --- a/docs/source/algorithms/VesuvioThickness-v1.rst +++ b/docs/source/algorithms/VesuvioThickness-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/ViewBOA-v1.rst b/docs/source/algorithms/ViewBOA-v1.rst index 8593a7c111f..a32bba25f59 100644 --- a/docs/source/algorithms/ViewBOA-v1.rst +++ b/docs/source/algorithms/ViewBOA-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/VisionReduction-v1.rst b/docs/source/algorithms/VisionReduction-v1.rst index 505fb668826..318a948b85b 100644 --- a/docs/source/algorithms/VisionReduction-v1.rst +++ b/docs/source/algorithms/VisionReduction-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/WeightedMean-v1.rst b/docs/source/algorithms/WeightedMean-v1.rst index c442760088b..ac5a7caa55b 100644 --- a/docs/source/algorithms/WeightedMean-v1.rst +++ b/docs/source/algorithms/WeightedMean-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/WeightedMeanMD-v1.rst b/docs/source/algorithms/WeightedMeanMD-v1.rst index a3cfcda5467..d62a77c1e13 100644 --- a/docs/source/algorithms/WeightedMeanMD-v1.rst +++ b/docs/source/algorithms/WeightedMeanMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/WeightedMeanOfWorkspace-v1.rst b/docs/source/algorithms/WeightedMeanOfWorkspace-v1.rst index 637b0379f9d..25aee5bfda8 100644 --- a/docs/source/algorithms/WeightedMeanOfWorkspace-v1.rst +++ b/docs/source/algorithms/WeightedMeanOfWorkspace-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/WienerSmooth-v1.rst b/docs/source/algorithms/WienerSmooth-v1.rst index bc20a9709c7..6c71c5a4fd6 100644 --- a/docs/source/algorithms/WienerSmooth-v1.rst +++ b/docs/source/algorithms/WienerSmooth-v1.rst @@ -3,7 +3,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/WorkflowAlgorithmRunner-v1.rst b/docs/source/algorithms/WorkflowAlgorithmRunner-v1.rst index b8e98b33c73..026912cf567 100644 --- a/docs/source/algorithms/WorkflowAlgorithmRunner-v1.rst +++ b/docs/source/algorithms/WorkflowAlgorithmRunner-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/algorithms/XorMD-v1.rst b/docs/source/algorithms/XorMD-v1.rst index b25e5f071a2..20afc84b46b 100644 --- a/docs/source/algorithms/XorMD-v1.rst +++ b/docs/source/algorithms/XorMD-v1.rst @@ -2,7 +2,7 @@ .. summary:: -.. alias:: +.. relatedalgorithms:: .. properties:: diff --git a/docs/source/images/EnggDiffExampleGSASOutput.png b/docs/source/images/EnggDiffExampleGSASOutput.png new file mode 100644 index 0000000000000000000000000000000000000000..243e9b1a650f0db305ba2aed4e030806a3f3282d GIT binary patch literal 19419 zcmd742~?BU);?}qt+o!-YKzKL>p-mvA~J*_sbW=%fQlkhNHrotfCyoV3~9AWEki6S zQ-C-DB12?IFbqlSKx9aQ3<)Gasz3sS1R*4t`Tr(>+S_}-^}p*|zqLM>B1zu&oV}m@ z?0xp$=RLW4#N*(~Pd9wJXwjmTu7~y?TeN72!=gnW99i};@D6_F&sV^IAE1sM+_$Kb zVLS%BSRB09eea@0RoLaKQ%iu?pPWDBi(0g3)f3&n4`|5yXBI7TJMX%G@A3FR(SQ<b z!-WcFHP;_LgZrvccg|$0Cg9lDR`I({wn6sqUv1yKZ}rQZ)T{ffH(OT)ZQuV%HF?>! z-4{;desNv9M84}|_-X&A2DVRru9_P82}ygi^+f0ib{qsj2#n!2A&E+9)?kdU(7%jT znKZ`1cd7HsbYkoNcxT*NGxysc<GF^>;D+!@LS<fAx*ffXBHVi~l7Peot1afPSTyli zb<5gdGk$Q-$q#>+e=qoP#NJ>@E!maY(^tnEJVPBJOSyP9J>20wq7Ab=TKOiT|Mn0` z0Z$92i(<g0bGQ9OYxnMuk5N^1C+a?=Wd+x<<EStCQm)(Ko>m#`QZ}g`mDu@073m$d zHDhKDVswIofKGRZ9N-qx&5z>jTr)QVe_PsYg4aZ6nfTBA%;)n))2>-9-|g61&jA0C zcD{zYBN>hwesn+SLYKIte%T?r(rpV<A1Vxq-77fvJone{s(AxPNCrJIPw}{5YWjNV zCRz-&MZPCvj26Fv+V{!a9e-J^>EkC~VyrzKID%=VxU1yym|0;y)CHq@9vM!jOQrmr z;5xg3bykZPrfB>5A|tCiOZ&-%L7r5KX)Sz?HFL7Kd`pe5k899iC+DtPB=-3-`op>3 z|5*R^==|*uFDx#YzrY*&&OECZF7<J~=rR9!*};x^A%B!EbNFEH-Ez~t=5xRO)U)aT z^q}47SZ)A}XUkL!pbji(VtjqAX&}_*q!9tfP1<}_{fI69(O~7bOBOJBaO34E!y|)x zJe30lW6ez=5tTK69bdTludn)-8{lp2R!3(gRq+T&WTAHJsC#bO0Z|u@|E)vnkZ`E@ z{GR4SR(}NPt{AOlA@RkOWDA@uxxWD|-q;BJX#sHit*dv-8r(nK3a3t_s=>$mf5FME z_Qp<h;hgSIV9ku{47PRU$Yc9>(-X3K2=YtDR#J1>FAooXw;+n~b?}NtrTcT1-=e<B zh$X+mW3Dz<I7N)U;aIt-uh!x}WJDA=Utv(336QTB4Ek5j@Tngcr$7(7tzX-$Ig&u- z9<43nQ5wkw_FyC-oSk8`d`}7o`<{?N>w48K@n*3HuJy*;8_;+@YlDaW{HlpGBN$O5 z(-`aPNYJ!C6Sf+v80ekV>~Fdc+4^p><B$Ka_-;bGv%Nvo09i_<kV`+#==rXSm8JGC zygtMtb=5<PtrcsCl*F`6|4*2Nda+kPP;&^s>-^a@b7^FnRv|!wx{@}I&b_nQ(BT>Q zqeeIW#Y>D5I=v?br7Y(qeKqx1$zf9t=)-`kn7(a#(WDTjy&!4bPS}H2PXwDajXB&C zt`0cUA)nztAlLu!sl!~%Ko5GX{$Q|-K;fvQFl~&4gCN-Ov>F3b{SCiYx;;ilGxm4P z2N)Oo?-$48wf%y;$z(wTJ&vkuV$~*3kl44IOvmasFD|fN9X%(*^k=}hfeMsp5~Eep z<0ulStXK#P_v+}<f;h||IO3~$g@!lge{JAEoo$-5;b~GZ=P2q@Sm<C*kPlK-<avU_ z>unTxh5LtUQ+S9$N{H5+J{c3<M4k0i$Zkhg%PJx><)G#;Y{HPGjTT8n#&t<Qi)MV~ z?ECYr>vMpmod3;f^f0DcUBM1SP^1k=<e;WO<Pc7kHPE?)!CuuXyxLciiaac&G*yr< z3?<}wlDJfftjt|)&XY9r$3;|SBk+?x89j8yn}!wrp#F70e(W0#v&g%qZ0y1^hv2uW z+%5oA>B1v0Lq@zEsxH3a;Ol0-A$YZrqFzJoZG5?s+MD>wh}xy<?ZMhmO{6#((w3?Q z7PwpTN6&mvbcU~p_afREfbp{h7&|<EUs|AjZJ<4mNrTAc{FTTza=vH1nirZ}tGqrv zY?O!BUO%UN!LPHWJxvZw5MVXl-Dg&1V0s!~3bez?N%RUUS#Z6np-D8jsW16rWhD{^ zon}Oby%k!IKP*ASrI!&jP(IQY*>J%{BF6GW+GcKLUY+^?M-wj*o1dijaFc5YXn%>3 zKkc6Sj(P~fcItbO$`K499a$%Hnv<tdbQ&VbU>6j7@U>Ba!NIqzas1viI$7w?3#Clo zB+Mk=M^BBrN;=!rnl?)t&%(y;#>O!W89nAY?ipigYxbMW9r}V&idCOhC1goA4dS@T zhuJP2ppW*N&(Y98v=-eVrz4YV<ek}+?!+-TgzH4U(5afBaYVH|`JeoXlPBr^klx8S z8)P`RHv;pzg2{!*YCQAG>XILFJw%?#GWhJcaHuZ%bw$rqU1(@A#~i{<EN9Iw(i7;r zzl#o-^Bm>PGfP{{8*517tf%c+&1<IWl;jyimCH}D3y1Wp+Rc)y%CxTxF-`K{-Idrq z)Is7F?L&F483hJGs>=8WlbxH_lZ+7zE0nuVnM=_x-|6#m?drdhG!p#eI8`-bX$O1r z*zm3Y?dt$t)N|P>O+=3+7Hn>zjRKc9DaOm_FzWOVaqVoXMru7>H>u`vClg&H68!z1 zNm{f?r}Pke%f`|6N7^&Xbk5%5(mNP-lIxn8m<Dhvep|OvB>=P4WEtEJnz9VE<|1SD z;sU^DhEJ^p$S3dLCR_g(boW2rU0fjfEIMP3J+sJ9K}&#pz;U1M6*w&}*fckh+Gu0R z!|R({97_OS1azH~zn^;1BXe_I0ick<UcoZm3)d*EE)Mm_{{8mtKxl~KZu{Fz1OS7U z@c%quu-m75QdZ0<kQ|1rtz$Lhh<gyC&90R%{=1R>YtbfME-|9<7J$%!nO@5r1RF<< z_v-m0hUpl~_1HL?pK=SeSWjOvMh94g<K<f@)3?}az5oy>i`HIbpqDuuob!F<Nnng& z(%gXUzZw<y&yiA0lO0GvG<82ZNs#`&nS9_sL-JoM@;_sYl`bw|M&N{+EBx{CVl>C@ zWZ#3PhzPt?w0th;E9;tG4EkA~0OW4mqZ13hWv`%yFH<}qUyYWGxuar|xFl9Qr@z+D z`KS^|5}H2ATXtaSyt;NDGJM{@*JN+-tWjPc@@%Zq<z>*P4gyxjCjF8zJ4w0damw6v z`dB_dCF~bV3VeNhKgKWdM0UC}p-Hnw1vuCe=oP)s^ixIYv2|i`UEH$m0PZbrC>_&S ztD}n{CwPjA_E&YbZpYMg_gV9aF@Eqjf_CJ!EANpA&qLO+LYvzs*$6d2B)X1Bj~aQS zJCya;qBpNKx!o`|KCgQfp!?#RAr0QvXN_^?((9Yawt5J@-y8g;ch;Z59@08U3Z@K| zCT<3DR9zg?8*<I@Vv!#`Co-&><(WCm(Q6d5xZtjqEp4FCsZaVY-}+v3<Qs>*aYI1r zs$0>_A`-4QeX^}VDPs8z<jALp$(ftkd>wVlH;*3fSD)n%taLXG_;PRXo#l3SW9uOP zp7)04LXG@97dJ5x2nD7;6Qu*fdu_BS{;fdZ{<UHJy+Is8PkOEyOla;J6+TbhU;b}h zW4(!b>eKgB68#ekz>P*D8iBe&7to%#|9RH*c(M9l@cQ3ev-*5<-sTqKf*aQx5r7&4 zu#Wt^*TeN2gX5?Jeq~110HpyU#Lm0uzV~eSsqLoW32~i2A_jiokM#(^gyMPc|GU_~ z<PWH05fu^b%k1Iq06`X_=Ro>Nte)YCkGA!uU8`x}MO5^pum2#p+%+?xVLl4Iqo;x0 z65Q&j*ja7`vEFLaUuib3nTUm$9c>o~)K35*r(YKTXuXdiPHrH2+nrsUU$xaWN;JoS znl029->#fTGaOl6H>nrBcxd{+9SQY!E**H@Hvst9cyroM)-1rq2IgaR$3Q$#zv))3 z6x>DnGSEET|4+f*eyOz<#yY%B7x?r39{8EdY$dmLi?U<9__XY#_tv2I^jfbYC0~i6 zV=a}3G6U|;NBTo{KNQU+uZcMW>KFtW&q5E}I7*$d&)m%H`6oQUFl6eUhiQr;+V7ju zmH+hEc0d+VEp_w5!^ET1VcjTwZ%6rc0pz{`nBmJa9N6bR#hm-FC}Y=5!NglaK3(vm z2{9q{d^OAV>;vq-nk#x?B;VyWh;VqZ;yuE?T{(*9R}O>enX{-h(ZG7(B*bN3%UEC* zFus2Yr#US_)oY;yh^)t?D)W}a7nP9I)4#tycVBze>+0p8;9qX9iME5z^Y#>LAKj0e zQwo01-{89SgPRZZT{hzeG)J!a{&L6QR>RnQxHhQyGL*$>J}iBoP}@IssQIyG1sJ8E z2!$FZ%Rg?Vb63@Swpi_<zlRtOxT_wW@=c?Svn8XRINa@9HDz?g0Zp3oz&iK!^UMW6 zt@9wJ=Z+(|00s1@>sF8QD|Z^y-X(Jj6kg|gLY>uUzg=YHY7YpSK8qf%gP6}Ri`Gl> zg6wq^JJvzA1QxCg4U9dhsI)DJQ?iq)<+@e$gAL2RfA4bLfRp;bwEYu@HF21Wg%M{- zm)drZ9v&t(sBMGqyoW;5pJH*9gd{F(IA>%Hp%|wEG0j1jngCc}=K@SWp7@;?uwvZ1 zg@V0HPHMh9r_0>dMvIrf&E+tx58ZV^@FD}KRu@tr=577mi4*h0oX>(Fx-5t_7tMkX z)E|8tT*8nK4T<c-v!m}&emAR5jx!4(Vm<}c;n-6DclYzui4ij&cIUHCymEy@mlXic zaFPArlP_Z+bL1dmXGfd<-KU3N4rj{pf;zTM0B(Nq@AEL%dRT-I^a0?`zx!nU-e8Ug z0uW~UbKT1RF73q}_zqOpR1AoYzWOh~Y`T@t4b&;xxPMN8zRZY>g{0)k96S@^7fMB~ zhcaj-5Xbc?&AZ%t{RbocvOJw8TlAKEmt>~>6cv%6v(WVC3(JU(E3Q$1G`<MDk&n)z z*`t5YLaje+^=km+l;`~Wdx|;hf?FatyB5~`3joW$L5SQgG7|lDsx1B&Tc8i+atGp= zD|SfgYj^76=lj4q1t*cs$+nVf)zRgab_6#rcsU@~U+>Aq^o5CCD_g{a7lu)Ye_mtV z>3%FkM~_0>nBaIt!Di-*|8(g=otw=K=c*&kllQDKoi80J9L{sv-{H#zlA-j!eFS9e z0oQf#rM!pBFbF7J$Xj*XUbT=K0E=b|%Dclg%3TMqvA)z{t<g7@xwxF@OVKegT}~q0 zLG*<#R-j!SQ=z`B3m<}s0p@<#YuCyrvX9C*rXJFipn?9OLzzy&Iw;@ItgV;iu<OEw z%Wyv)2cULJD_OCA(=brN1*D3WdJ~=V#|_%*$-1?Hp;Lh7aFJnA+x}r&1ZJYn0cZ?D zlggER{gm*+-RII!_;J-{a`(TTRF}(!W&J7mQjWyvlu41?*bC2B9v7Im6p_q)dStt# zO!?vMwA>BZn_F!3UM5`T(11Z$YgaN}E&@t`giA9jWdFfS43*ofYr4qly8*I2G%3Ya z>w7|I-h!%8|M7s7Qi@>&`+*qUkASH8r#|O?$Qx}`hBH)cutzOm!)qDKb*Of}S??uu ztc?_V72r2#bCQ2N!F|#V5m;9k2Zsg#AzIIv@^41lFVc6vF@B1#yuR5$u<cT_{cI`2 zGt(^`^6-J^)Hq&}>z!e3V*z;5`T62N7h{#YSLK>ky@%R+uHVy4_KeZ=qjElKk<_Ul z-q*`0aD87!AJ>lDL$`wxOWQCwo%=ea$3d=pNR~J<k{(C|g-?tR6;eeh-xHk=tG)2% z#Jti-V1c`&bDF9<w<K@w;qL3|yB+QjbB`~kpZ#;XamhXJ_rwGo{y*Mgo8(cO8Vbu% zlz=@$ZM=qn+VbOh2izCu!qU|dS;hD@Ua(e!Af5S`&MBa4PRK67{)YRq%cYoqP8Dr; zMz_|U2~mKoq(!PD034u{*WChhw5FJOHTI}zxtF$E;97C^9q{_>`nfK1Xz83mogR0S z-v-DPwd!Rl({ozoj$b3X!!az@lrpdT(cfA6v*@$;aK)W^DAMs?5GgJ=ZMj2_@nb#o zwn+yT6mtuOA5M469Nw@HSO-@6>J}{D3#~s{GLl+BzX*0M%@l+y(#{$7P<BZ@ld`&- zbKVgX2#fVb)w-m;dgk~Cuzb5Z@3<YzQ>!*JxijluSUgAqn4#EFnr`)u835!9IE<Bk zNU=voRET}_hOHa3z5_k3eB2F@`W`caGkSs0^DYSw(I*{lUCgVcmLn;<7+ebv+mtyj z*@A0A-_8^q285!8)vaS-k3OR+8WTM2&YpHzCkQt*$GM0>?LQBrjqtuiN`GmdpSHgW zV46N80DYEyab4Xy<MIzY$}X3hb-p=<cj_^Yn$zk{{{!iWM^CpxkO34DpoQ>Mk1N)J zu-oo&)0qnGwdQQaa4G*<!Yb5P=)q=zcZFr#gJKpWPAA&Cv~f-}@@nxGggRvprQ6)o z=B+|?p-E&f8={5`2NpMd$N_pEzle)VbyaVB`gu!VA>`gv5g7ddG&~316#0a(t>8ha zlxczkV&!}@Xy??DinF>P&gTOmLY-2ply@im{T_E4IN(WE{C}^II&GOwI_)t$t0c!o zyp6D=B_;<Gk)9jc3<lWK{{CcuVcqovk5H^%%~BYIXo|oUo>nRSUV+Oqg}b!<8?1ZM z^bB&e{ab3Brzd#-jP=(#z*TNZe)!X?$R&+mZf5dS)`-^Qb~C=adrl&N^<(G!`T<~3 zuE)Y1vgxs(cB3d6EETv5z1la<-e6xGmg6vI-E+sUfZd7}p}O|fv$xs$4Lu{sW5N4< z01OA1C7Q;Nq~8D-r~R(cSi(f|SRN7Z`;Z4l_03*M#8@B(zIvO)xBg91vA_#6SPOn; z95tjWDO`$P(ZtA}pSW`BI1E@bTZjv3Qaw)ZC%f(D5Y-t1Z>LAcURx^IYwALfjPUWk zUd8pd5l;Vqb+uz)#?jYk9e~vGVAhS&h|vw6(jE>F6I16CiQ5g^gu3Pms*CySLl)*x z1Kv}O?ozBpJx`b5FPIKn%{ag!G`TiG|5VqyGu=y{0Pu_PtL2KESO{JrDVA;nh~0|V zYs!tEjHJxZT65+BfdwQ>esAN5yFQNO8o@{@lxVZgcSw1ncRq*X22m}3X2N-WnVD6T zErPFHr;Qh~fPs}>x-g`>z3akg>g?@yYDbB*iV4eurB-7bH+Ly_mP>2q<yP!iFZ7RE z1^CuNkFsN6*PM~3f*dPSDDh^G?O_e0vMxoAfUsTwkvcthF`BHat(4Y?I}x_Wahw!z zu#@HAIuY~!ObIKIb{I|qfdgSUknCqBQQ6Fy`rMHEOQGM&Nh5YS>m=%a>_ok#^HPA+ z`W})#YUj*RMb#$L4d9cU>&c}#Vd!(#=EPH<)q6itHrtd*dyMNTaQKdQx0jobCIUN{ zvv$rWPwIBe<zS#Ta)(aWlap9+JMT4|(uYEwMLDwDqGa13f!o`mBX^i_hel9b^QMGB zIJE3#(okNHBD7h$lQ7l0&W*V@bC?X$mnNS$;BD&IC+Y6@aGuD#G9i~l-1q5zyUQW7 z7aql46kpLtn(SctmJ3(qRR-&WOGmQhwFR6EP)eu$>^8yq!~cFBIw3OD$Ot|L0+K8{ zeUdd-Lh4(PaB5HP@B3bmiA&}UY{^u)%^Z`!&2}@6wOL9+9Em2VRYgE9!g%S!XDh6n z0wcKKu>pzcTd1uok;&<IcM{s57jzcaHxqr1cH~~Z8T1--kq1P&RUlarx>ePil2+3_ z-ImDl2&d({gybu4pzO2c#N-v&Y%a-D!MC|aLfAA;b_#EX4mo6pqoI|8U*@|^K-DW~ z;<X;ut`el(s#(6j27<Qy)#$#Ju2~jXIEJFIz%+62evHbc**7$K@XY&DT!}0&Ya1F# z;+iK(HXPy-Hw?y&Nq-<l7POHXE!e1i^L?erKdCR!vyd(IgHrAO?#?;BPEQ*vJDq^! z#{+yOzbFgFA5y&)eSTb$XbnZ0?8YTJ4BAyfD+p&F(0K^7e_*x{v~j-g1E4`3=8Y!C zKhGVF(324Dn+3a*y#e;%y3US~gN>qI)Hmt6G=jFvnX*gPwjr=mH|~Z*N?_c$G2#!> zf0ef?;}&X0Tc6C1lQyC(Hv;9ao`l0ezR6buPaAVBwo(%(x%SAx*a^@uU*OzhoDp;( z@zg}NO=AGpJW*(KO@@d8&_>)G{|DMz_6EPQ_@l95tObLs(Pg?!>+!+{x7WG)1QqSu z%uMm)-G~fmu#%4?@M0mj-y|jptH^RRuwKG*O<~DuOZ8L~cczhs_zGiko>RpBw#QsD z>qCZ(zYhvJvEE4U)qz=K*2xoYlAOo@#j%3^n0)9&vh5cFN11Vy1QGcFWZd>h*3xT< zh$j~doSg-yfL87lr6Hg!`mn}y`>fkt%buIMW|Tgs1~zdz2A;}*T4TEUFn$US%cHeZ zkC?}q1RFNs-Ji)boKyO9n1H+NXro;i1E|MmCNzH8_%T1X@<c^a`y)zZ1)S=QOQRe= zDFgN)-X)lDU89=(F^#e~iW^-K+Y~s!Owsh#g84B_rim$_{s{3KrDaQec}s250|cYX z2RvB?V^utZGn}Die#)H4r0XG$G6b=uk)-R1liy`3ML?zk)D^NV*SO8uuK;A_*<=4Y z?z0*Dp{lKLh@$mEVBv_wR2ekj=fv;tB0eBu*R$<%k?hdx=<o_WkZ8PXfV%0{{*<VR zRPM1^5Q|e#|79tLExeflM9x?sa@Gq3tFQnZ(|$M9*{3h$Px(k<W^PIworXY6{N%Yd zA?rt{40yY9!CfE;Y(7kTYAg}?h3_U*0NVg)@!Ya+y(!{a6ySy}F1cVtsHou)vx+6| zCjQElLo0n9ilNcmkfyeE4S9G+C%~G(Qj-zl#E4I;%AiyiW(RBXvBZLg5Q+_gsN9u4 z0HmkzVt8hxDjzMrU;zY^cNX2DTRu!%OD!YZ`UO62PBhD`F~2k@c9b`gR|MyLUsu3t zNUJK7lb^tux`g9ZPV>-VVU(k<<CW|nCt#~x5TU83SM-RV?1=@c0e67Pg7&G6g0Eet zyWb`-XLTVqiq~vd4T25w^O`w=c&}#oAyY{sD!=~A7u2@KE-TUL8a&dhGY5&L)KZ0T z^nH2aY11J3mUUR`N))A_+~i5y?m|f^31x>F;Il%_LO0YwqgjfQH28HCf1RKV*xXvc z4oDy8XDqgaw<IP1c^EE2HEtVn3!2Um6bu0<0{hkl86k!^b)xcGb7GsMNDVb>bD;~? zNWMW>{28A=_2#tW4k6mNSm0PFsZI)KV)ROayZ1yi^rBVvv0~$)L?ReK@?HL|M^en4 z3EBY?v~dFj$?N;Gr;2u?+a(_B*{8xhP@z{2(`r-c$(+HU{G#SW3CbLZdO0p34sq?~ z{G+UZi;)9EQ_o_3Sd!{?{G?yPV63=#=$mv(wPs`S6z3UZsJZ{KpL@iE5W}ATV&;v; z4_er6@6U{WJ2N;t=ine_TQd<$GvuD~Ww!0cP!J+C7i5Gz)y|1*$ZJLb#SqA%;AFS+ za6V9^w7$(P^L4xdwEcbuXm)wOadzUy{*(d184SaRJ)RLBkaGV1R+y!gNtcDKG9)28 zGRv>fE=^(vUsa?tD_UFR6R3<YFR2$hRmvq$1e43?i(dg}WpI1;1OhaoM~*e#5pNU# zn+(U_vWTxsgTbbP<lEmuF9ayQ&gz#Y+I0CSjghU<mGLX8Dtk=0k5<7^zsaC{V>oRN z=Pbd>Ig~+oj*1l)z~&G=mHK&Im@&12a6y>U6)OZybUKY~@j#7Alehl|Wm{-N{g%gz z+^}x2r<o0fgtHqE_#yXP#uwO)EMh&}NU|R1Rcl#*dVrm}yEEJp2#akJzA0i=(MaMI zex0{O&>-`<3qcA-Kr;a}#3rO;@Q_uSuVaK^myhVQB|BK$cqhV4r*Q9Eg+H#)D;%f3 zlbzuo6{h%_mBiR#e|Fs1P4KWRvhYkpub(-BX51AO=wc(kP+3Ybw);;LYuB<1Y1WuZ ziLBNv39STekYLFy7EuFrr`4q<OyZ#Vj@kFQG!Rf7&Tk=yx!Qg2^6^EF>8YGSB~i9* z2z8frvSuemneThPy&IIpICXN!sU^0G=)uYW6%)}tq0`a;c>9^!B2m%M#OeG7R$Mvg zMwVoK9?#F69X(oKLK-yy*54~r0okI`@cWbfY3y_D#C*wd?dR}(pd|ns?<emcpfG?U z-RfO-><47WiB1glz7u)>BL<wtP#p$VX9u%n*%>w6dy+-{r`lh3NWR%Au--!@I>Zim z`Ol;Ttz=JjNbs{2FUeT;Xh%Ss=5{@(*&gUEV7`GfXkbg%Or^f9qc7gi0daoX9z2}d zL+OuMHTGx=jr0uYe<5s&;DTSPGKrd`4U%6a&thxY00aQBp=B*>RJxUJ`y@JlOL5hc z=t@8LP%Kb)-`?@>q$p6L@KkULe}j!zj92qI(dpOqCY?F6+ZaH_?eea`&|%<|LA3NH zl9KHAh${tdG`h2G4>7eOrlK->!r02Ynnm@5n~nt#MI0;I9{zPw3jYfwkz(Z)-q0KB zrgUre32m>674ISnVu*Q3I7aRc?zGwl2V-)Eej_zjmcLZEGf_@#8!sLiqLr(z@Yma* zp}ziNcG?i<*=UU84J(>gK2U6@ysPnQfyEVVEU`RVRZu7D;yfx1XG?a17Npt(Ify>I z!MvSoaH@S%!FK*??ntA@srH@W2K4Q+Y=)hgV;zfR3D>v?Jc?zFmEK+`*YJ@1nlLwE zN?L+NGx2cq(6{a)G_>N1(AJsO;s@KUU{1-IFq{>&3Y{gjLC`Lvp$+$0#+;lXU3YHy z-A2|{o!6Ms-dxN?3c{7Owh^IRX`)+(dyMEb!dcLJ9Cw%-lr*zNkS6^MPLY#=K#v6# zTh-MTu!x`{*=@?1ik+OU$e@IZa9Fc(3Zo!Rc7MAvCEysYUDyR`8|q4~NZQ%l*yRvr zc$e)=sOULA(2NQYE*Es?KUNVz!O1~M^lD1K0r#0VuPO~x0JKM4#p7?w>Q10m8jeh} z{ATL=ZAjdZ3qm5Xh-s+`f5~_A@neE)r6ru(ita-8NRrZ)foH6d{3?3r#P?}#oF>)6 z7~6=KUu3g~!$)Epdb=-|?i`nideKk1v(q@;w!vUDFf)V~5hpgm$q=HHD4yWzR3{*3 zK~VT^qJY@qH}Lta)yK2J%3ltH%~7ElA?;f#P;K>{)s(Y9gWR0^?5_lVhpxwx+5fJI zuo(#SEkikjaaD{uNnYm`A~}4j$#SpU#|;`4mONMsK-!HDO&Rw}2s9LV4T(?ZLm-~J zMF(Mng$cjPfANyE3h!)HMBUxWDiWQx_RirPgBg3tAWy3#{9?_0cO_i%98o+ztx0Sc z=nG3Jg%Gjn^3U2LXOjxoSynuWjU-qcPC|!Qd)GZpO8ZmY2i|y{>DoOZA-B=|93r}D z`H!n3o=-pO1W1fDtf}k+9PL=y#=jNV$Mo(q_3RtUz2R^di&A=csvYd&^pGI!DC=n? zD#M+0*`Evir!KYKA@uT}S7Sqs(|c;51UF@Ow@$VpT1gL~VHtFHpp2>&aBUE3xjk9* zDlj}^9LuRS6XqSYI{_<mC8drh-mx4{$scE?b80QH{<}RwM7{P0BN`r^G%Ti^K_4DZ zjiEPM0A>o(_Q!(TRq}I&vkEsa_uV}y#QH6Kcz3gr<H7dZwch?Uv0)+IH>IM}sGZYR z*dS20AFzufSlD(Mjku;`RMe20N4Xn9B)9USr5weXdDToHjBH`ecPuM_5_0EGB|MEx zE3WUw!mnhc%Iqy*f|$~Z@>F%A311n~Fkx1+(=^{D&1TPFzofmQEnPxNt<bF$Rc1D5 zo-y|stM^nWQ+UUjSLrKc(mny0LVnT>GtK5mq}R}xw3DXSC+h%}n-x)#sa8tAJ&as1 zD^R+GpBgme%Ij;PhrwBMmy320T9l_7!Yq|ElI1fvq_|30zyk2Ygmf3h_>|!gpabEJ zw^2{4Y!EspXH)@TThg4e<cXch?N{F=;p^q;N7n(wL>JGxht)aaW{(A~$r2sK`Ijx1 zXgaHH$EVe#Q;3X~>YW7UY@4Qbz`~YxAc1~AU0phKECHMx>L#oPD_S}C+k{=QIg<yq zIi;1*<JcDNT|)V`Sp=WPHXe5qiB3y;pVXSc54flOPJ&}HfCw_NOEJwk2aHJqCAGv_ z#fx`^hSEwje#&b^MPmgtjDhnPVo9B&ZHQMnr9-WG)fFV??rfF|DfLg<h65PUn|?p{ zLECOKkqa@1{&^d`)yfSam21FGPjgysM<PToSP_T8+EWkQXqSn3{Z)BUY1OuhyUskb z-H_zg`<AqIHPCj7cgjqF;QP$s8*f`*AYG$m)_wB#+ay)n_r5@k0BlD}rN?#;^NB@p zVinJV#LuZ4Ap#EoRkcpF$`T9M&B?n(0vmFvbB1d%sg@y>P#VD`T08ctI`0K=c{2ks zEgRjAXjV*X`u#9{UkYPi<j$IV`5PN?iIi;sDIT2ys+yvs{;2x|XtYq3=mI<o0J$N$ zQxmH>(|v<>^FVkx+|jJ$Y(;T7Q`yGZ0?0GvQk-|cEZvIDnR0>iMMP1pX-zquO%y#O z!ALu;GU&A4n8s4_3ZS(IFORhXs_8V2y=`-POvqp$YnYa;2EyNs@S@0xfT5hI{Egga z{Hknt!DEgpGzLgdufN5^N{>gn<!4pUO5mbY&sqV^omiJzVKrS}1sKXZJIoNr@u9^! zY~@_ZFpy|st3b9$EKr8!$Pm&h6WacSFt(zVv`qp(4dJxLR71nkO{Bm&6vmdJ;Ayuh zi6&fhLKrY0X&0xfzWl0s8~6KQa74rmJ7b_HwrYJ%ETeNeXWLK?pmhYa5U3`uv?JVT zicpIRJiK8vjb?MUo7D{ZWh@`gwITo^*l8=$03j;fiNvZKo5GeOXxZUj+#;(3Idwgu zS7Z`dY!%uAo@Uhsk7}#W1M)ph?-ZO5XIf=!qiqW}oHa#(SlikKIl5?%NnYWaS+eku zWVGD@AdLyEj(h@%?E;cNchRF>q@j@{uh(LylJo2=pon_~xSg9akH`i`Bo5xt>p-$) z`;=(Ta16SVePI!RriwFzC(E#+B#uRWOncEDMVyrh41q^9jIu`ZGfOSg6r*ielWJ%* zAD+dJX^Bb$G_SA<6_oj!njJ`3N0eK^NvR3&5dpoz<a(M6MS_O;CM3G>X+6#0n;{Xz zn6XS*w>OEFJQ#@Bt_)QY71c@iw}R>-+5y!qy4Im~VB69)aDPVRRr!=WM|4MFFM)f8 zfJ+`i`*A2y@0pnq8@LoMzR(Z4;EKKcu19(;IcKR3fH7jBKPlVBg*E~R785m|qf4L# zTsSHeKtl#_>1<jplq3j8g&Edh!vT8i;)F_DVqa9;1tZ;ry@9*=7C>AlM@jPF9E$@2 zZ&r4a=#IneIkzm@%~d9KW%78UWM!@yz^sHS<GNUJe<KNM+^q_*;Xd1Omm-Vj=V9$= ziG|re)_+WtCE3SK6rs);p74S>5l|KB*?3_Gi$8OO`}09FFHsI^7araVxU5+WTv#Pa zgjBTEH(GKKN-uyuQQ1?SR?5PquG8dszHd~2Ww5v);JO=f-%zuSaj01huo&WE!m<HH zDZK`5vfChHs(Vs-31H%>&RB|vs0vyG4QuCiI%K4)J7cR(7-c1qOLyjy5YiXfv)G;; zL}<T}ImDAbos;Cl*dAs$8ybrGflpgW1hRxIw0m+u2)G$sQGjT-FE%!hix|j>q-+FA zk=9tN5YeMNBCYyqRCywmHE0okS|TXkgNYFMnDQ(hWW^|}ZA+}Um$p`z%w9v8wk2i& zSpl45DNM=0Z-^_kV&|c?$JO0FMQ-Cm{V$KW0~-q<o_<TW{g$LJ9MvR0m8jeP&d$sL zG<G_Pu*(YK4kWzP&_gB!Y9-*N;Q}Sve>bvCIZZB7_cFo_{iRjVvX$It#gs5N?h8|; zPERB)c{e2Xd82Kb`hH8gLY324F;Ui2o4Pa?d!n%9Y#<d#-|inZ6j%t>92hv_J_uvo zR02!|KTRy3Hg;>LwO91C_c3O>F0^y3;EYnx4LKREF(4Y-@hlNPNH|dm<>6+gq5Z_% z$|seq=C*Ld9_B+oo>jT?m2F)C2$A3nn5Nnw0NjB!zDm@QFA?>hV=AXfosC;bB^j<j z#14XnCzS6r7H(>x4eN5pfFC>L<>V$xXvEh8i5I#8pgdAVn=2$5=n%z8JM3ad)`ej1 z??f`WrlAdwW=Fo_nQ}da{f%4k!416+w#`Zu=gh3f+l0T@eIFhXXvihIh(xajr^qk9 zRNJ&EZd3ZJBU-EAcPz~??bB~k?Bm*1Di@C)hDmU%%BiXV3nkr5B8s3pm{xlN1HEJ; z9@1>SbObal?Tw{Z+saZhwkzA<t3;K89SArCmd%BSqsr4Ut4yQ7E^OpULE3tysM)y< zjsX0G2stZ3WWw4Kp@0unnABJzP#f|D0c}IHX09{<B`^seaj+v^4ssu~8_uu4E!h#7 z4L=m6?>jtdyj25i>I?a{ne+%u9dG<F<c|;c3W9QYHx7pjgq+w4OQfZ;EsvwgA#&D1 z6w_*WpM|ZRrpiQlD$l=GZ~!wQz-}i=NR75Klmy;Y4_(39iWp*Zre#%m)e-H9Y4-^x z*|RsZV&HrtIS599nHq6lfN9gcx7B$gQ$%%RMHqzWf~p8N<Jhx%K?XK>&Lg6HML4@( z`sjQ%obfCNDYCj3lQY{RqjBJv@}`O9DH&Hqs@`f_Ldz^dL`Kt(z$lPzZ`n<eTRYZl zgYdTCn}ON*?6V@pJyH=V^#PI7smgCC)ZQ?KGf)hx7!xo5K5$%rV+6zMrB68MY{a0q zkjX8{z^ZRYW}=$ELObX-9)|W^V(jSMaf!L)o`L$i4s!C)QY|^55@k}a%UG!1)-yS+ zRuaG&((C&hEeUk)G{<k?8WG+KfbN!bs)Bkp5LRgxn&xaXNMY2a5`lg>IPnpj$paU1 zX$r-2vso}<DpPUXzs!<b9D2IJ`($2d6b(27@q8nKfcIeo;bHvxNEI4WAzmkrs?3?S z60}I7M{SN!4z$LE`1)Hbrej3Cjp3~+#xAB$^xoWf%UWHkU?I<g!y`Vv$e6ip6ZF++ zK#A!3^G!L_;83PZR5@niQJ$CJ)9j3fRKafSmO^e~aR4{bH51z=Tlz)I@;cd|`K<mC z_&4c{T%Z{RJeica8NF-)5Vgvv0Hl9j3HZSD@%*ePEbyeXvF^zo-PHy!=Y1>pkk%qt zh5Ok+8_xIz*pAbGoT6_8SnL_?hin_3KU$cPu6quD{`BBqX{&YT73L2R=34=Nx^RZ@ zC+h?H=eIs0E6q&j4rfhUT>u^x2M$Akufdyc#k~v=@bh-kY`80#f~bI+ksPk>=cBU? zFXaIl2$C_%U-y$8X6J-&i==0v%E_PTjtV4xH5jIQJ(MT9B0zyE`=Z*zbw2}Y23{vx z&}{rO$iSewdyNX2z;JCKR{z|rpCL)Q*OBztClWF+Fo>@k9=JCm9-KV{h|&)X`kp|> zhzPwxX206~&!WL2{w`34jh+5<hrw_@FYFJi*QS5KX$gz4CX*jH#WpT|-8%)mA@G^} zVD6%)DGsKNgCE6D#2froHRSvgEn{}k+#AM1=dW}pAtXP)IYRsA5V|o7;7v>CwKE(4 zH$&*gM3v9}^j{fm{_N-ZX8qZWdBZc->BViBo*<Da_2ZgJzquXD^*)BcmSvfcFY~1u z?La4Cd&Hcj#`!ZGEE`rGZw3hP3eD;dqzNs@oPRpl-i4Fdi~>p?kfZ)$;Nmx400it% zuNZ};u<JyQcLghWAL&7ldnHbJ%uo650(=;`?8hZeO;-)NcaH{4D@@A<hz9l_juoGl ze0aEl?MMMPEq!>bap_Nvwy@n2<wgMHkAGwT^(BDl=6h_Y&5usZIrSOP(THEGaknEd z4oOQH*j8k;#k{on7gbw>TZE|cST^{twG#@3v3`yXk!HvH4R)fFGW054{`yRd@AUj< zp9&KU^yu_oo?hZZ`R?bQU2CHmiF4ZL|5U*{>%Va62V-?A!qAdO!%~oU1H$b5+G)#2 z#9Lhni?SI534e(#8^!&L!ES+gII%(Y0qqus4h^2Xgu*Ngud>59e0ys3!%x2@3~V7x zR&k)ppWs~s$IsZ=0xIs0-iV1q;hQu7ua=E!KEVsjR9pfC0AZgv*>vKyV#f3jzp=ne zeFzJTJD{&v;Q))uFr72yLzn4Q`Q|qbx)#R0n>qMVAF_H&RwI}e8YlY5V{dXz(}LXR z#oDd@y+QZ|QO#e93!eiNyb{_GKR8e3h9i_kZHC`G+;9bWG<ROuyGK6(ty#FK<SV@x zbBGqaN<Oy$`{o-Pv9pUT@~3Tjo0clnTL?^@rXK^r-KB%P<{88fr*Zq^sn%q<z2~=k z1y6-aG1KqWNAY@-ty}R+z6k)v;#vZkE+hmAd8GyMNdU8^znM(Y0dwefD<3dGOw&D9 z!XiQY0Ad%#p#0^WbD@I8l+8SKu3O_DKTA8*+~YX*c_AxhyhE6vO!?CUK6x1c{G;m; zn{5eH0T>gWVDQ)Dv1G(offzui!H*v8??hCo45+|w(bH^RCc6aC;;PCfUISTr>?ayp zoO<x>3GGMw|Ch(I3ok7#peo9!oW>!O$#cmn8YbT`>_SEtYNh_P_D_Q6&Ekan#$&hk z3M?rCXF5UEO4x%@)?v7+zm`J&T7oManh7Wo7|)&UuCCf>aC4K%o>A3R{F|%%Hkc+# z(lnVwkT=^={#*`p9mmKXOwio5XW%ZT-yU>0*O8n2g-uZ{ap}`GYiITtXzAR<VPWkq z!-tjv$5OTGNjsQU!Im#O%#?O7pP{NpV1YaISN*Z!_w<#H<_G;+k6vUDl0=Ba#f+5> zRA~irrJ`Umu|zJ8qjD3KT%K4qe^mR&is#K&py3_zS&VizM*BvPX9pb8%!5=)r{cw9 zXrIrcH4Lrd_XLV+3K9-}{in7DO=GIPC59Ne9UVbvBJI#WT`_k)yk__sD&WbGUgE!2 zTji!ZpFX)hx)>8M(}Sfpprc}X0>Tr4vzi3T1-52*fKKa@UF!iVmdWHy>}<dJq$b|m z?nf)UFU|Nd2n(qzpERXi=MR`+^LXb5vnoX{w1F2h0hXUQXr<=hrl}!}BA4GoRbG%h z#wdQ~^W-#bx%@d*(Iu{PDBBzS=}fg?Qg<qBgUD+y?+CrgN*O6pO!tBW+e=MQll|%; z-&PCB+;RM+@ayR#>wm}=41>Na6y^WEv`~<59J1};Ck|A_!MXFGsuw4zoJ1S>Z9`mH zEsVs@e~@e4oMjdo7>3Wu)_lXoOu6`KR}X}UfzzVnv)a)jbJ3J%o*|@r*3y&^#~%7L zZl#0v&2@Z;hQ1wkE_wC|{+wn2qhjV^6d5oiaFUa1qUn<E?nnSK?;<rwC$R;M0V=*1 zd${jQYzeP`{x8DjKDnpfF$pp<aANj+TmVDM#g7|RHwk-SV-p`WG&+YPKYv9clqHbS z+mv*=xn)zo8QwPoYGPgonQfA>D&Y7%z<YJh=qj`oj+SaxUxtwvnd3+zMRs0x;NkE% zK`E=p)L*2MtNb7{uOu>qrrr$gZ9_aPyH_lDJ<SRbr;(BPvX}|<uT!?_NOdPXK6z*M z#|3ze7R*+SY}b<HGkERyl5}Kp8F~t$#phur4{93t7%dgj<)lod=9op>0_z$F35zg2 zsJb!?9LsayROSh}J3cr5^b<SLNEH=>DX%~U+TmW-as1mP{f=?k_)h*GIm`$G9&0F) z+i%+;;?{*Cu&ed#H~z)lmKAJ{JG?b2i}7_Cr}gZ(ygSwGLgDtFn!+7jEi?x6gd?-K za?&g>xX)0juFw1ai%Q@O0w!5ShP)Z$O9|RBz5#fa%tuvVUUw0Ym7SVm^+$An&QeX5 z!5KAD{#_l^G=W*6`8{$s<aL(jG*Vgw=XEB2C4=|ZQZ6J(x-cDen7?+4s(hh2oUVAN zS_0~~9`BSjkxw$rluct+O_~zztpUv?ehDvA!5vc6&pfJ^M9`gaZVquL8<GkN@rY4{ zGu}Tmq0N7=lkEhFd*I2G_TQ3d(Q+&<8!|=aV>AU=8-iwlXJe+Of(KN04Yg>AnRb{E zr**mGiBVYBTw+)}cT?hIYu5(a*r|D#I5jiww<A@-+mEcsR*hZw(qpS_5*JlkNIl1O zD*V%G`LX-C9-pa0n!dOJHX9mqx1Ia`5BqO$VdYE@5-KMdbDe!pEm+^~9iBZkBR`() z9>l$y>yc$xG-XTf{sVoQ%F1HaOmOppcczZdS__5`xq*J@kWb9=dYqrT|1_hBv!QAy z`k)D%jF`|=S(%;PBolFmuxHZDsD!WNCEDTbs8j---`i)JFsYhE4)#-W2Bk_-Ec)<+ zhLeyZfTd#tyL@vK9;C{Pr8PX{pj2_(P)I4Z&4zN6phhh{4l7q9#e^1?v3NXtaRFXy zhv`uTYkQEf)Ia4{J)1gJ=Gu{^IPL3$03oUBGS9dn)iVJYVj9h7Z+lF28g2XN&)sjz zE?-7*5JUVVdA<YCtT$P6gXWPAif%97X<$8hktMR#v+Vo|+diK&J6kM}EtD=^+v#cw z1Dtxbo)bGrT3^DvdQ8(Ju={;-MWJ~HFYR|}_7Gc^!hu6j#Jz%G$c5QkU_~F(7Ee!? zRYOFurjAAk;VPxG5fhfbm&a?o7J7w&A~^TdS^lQAN*}0%_;sHU94R&8niBDoO4zx; zcrBEBkSE>en9L2#IFUhiOTehXib{5!AQhEZi)IV!1lIz9m_20<?n~4VDBUV0Qay>o z%#bjHm-8Vqn936P;sa$<rIrwg4w50GBYu@tQ<pEo0$ITNI&Zt#-mi$+m<{-Gg|tg$ z=VQ0bNgp8XZE;~cs<X}%QqT0YHBtJfbD|oYEJVm=5i0-2ww~s7)lSS_CphN5v&<TZ z_!JojLC0f;OY+!F;*vb9N{+X~6gGrlV3Nl@CnS%RVh&{5i-4#MjOR)6Wcw(V5Q{j( z#P5;QipKCCSIsJw>e;3aAPnAVay(ho<dp1Xn1rL*p4a>~neZ}3ltVxyk8euycPy#Z z*5eh=2a@wq=Pkwpm{<(BWJ>Vz@`SOOywotyFfjh5+}N)R<!m>qdV*CSm5dOQE96D9 znq-MtqX@P~`vR*rpid?ZU)OzY#DMs+=CWntso7gK2GWnU(M?~<+%x)+0$PN~5OasJ zk!YwTokbVkMj530cJs7dYT0v~KpQbim+Y@4H!(g0zHbQlbN&cG4}3v1(7|fWE1tfs z${Cj(D(;#rF%G_NLT|a<%+FO+H%46Fd6RZSnTv|LS7f|pRMnos>jU49vo+JS2j?+| z`J#}9ra$7StCYq3Cf|VsUNl=%AD0}jd~*gQdu|_>{0J=&-hs&L`2}WTB`G7^eJCru zFUN{7EF7FEZb09VtbedwQBU)B#MpYgc^Ox1=*eQ6%@)s|RT9a=%E=_JBoBYoa{?~` zXE(zB)&!3osNX!Qx{Fay@oVr&EFgTtLN&PA<XW=&5ABP@AsjD)qC4Gxk}}=HcY`UW zff6D)L1It3L|^-1u`EbyeaEpCUMH(#^lhNUXyLagVm@DkzQQP2x6Yc;V8dtG$88*w zij)n~V((UcHT%bl-ZOCD<m#KunOI-XVGIAh!-xlT?0W8?@yRo%p|FYyd(S>t?TDn2 zOL2_dWmuNBS{JNO^^}06rBcO=3Ee>5;h0xK1V`i+3dwtea{{}^>g>C;KYbG}NNNe4 zubCfyXz{g?<F&E+^4+7V8i=w+s<6aV%Ws=0TKF)Q;?YRH;ki#OvUOh?wP?}91Nw{0 zRya_B?{cuktA@?>Sr!F$OaJ*I#P_zg6C0!MUHZ5HGPMTsqH(%)JN+b8(ZgSZf3w)K zcgDCx;NUEnyZBoAO7vW+m@p_Q<Y!~#**K~kM;$xn7g#w4@?geXV9ezoUl|!q9|3jl zy~KEGsd{V~Jr<@oaeVF?o4K(HHyJfd-UcRKy6_b{=g<8wQ(a(leQxak_uoK7y2vmC z^5e&EzY^)|puBC|!_j+#zkUpySJJma0xqqNvUTrLX+LioU*tNDI-wKJ^?Q%~mHU3Y G`2PW1g$S$w literal 0 HcmV?d00001 diff --git a/docs/source/images/EquivalentIntensities.png b/docs/source/images/EquivalentIntensities.png new file mode 100644 index 0000000000000000000000000000000000000000..3ae944555dee084250097a0ab8ff84d6b1e0994a GIT binary patch literal 579717 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 literal 0 HcmV?d00001 diff --git a/docs/source/interfaces/Engineering Diffraction Test Guide.rst b/docs/source/interfaces/Engineering Diffraction Test Guide.rst index efd4167ac2a..3cc0464e99c 100644 --- a/docs/source/interfaces/Engineering Diffraction Test Guide.rst +++ b/docs/source/interfaces/Engineering Diffraction Test Guide.rst @@ -156,6 +156,43 @@ Negative Testing Ideas - Change any unlocked dialog boxes whilst `Fit` runs +.. _gsas-fitting-Engineering-Diffraction_test-ref: + +GSAS Fitting +^^^^^^^^^^^^ + +GSAS-style fitting allows the user to plot peaks from their focused +NeXuS file (obtained from +:ref:`focus-Engineering_Diffraction_test-ref`). + +After a fit has run, the plot should look something like below: + +.. image:: ../images/EnggDiffExampleGSASOutput.png + +If that fit output (the red line) is flat, or just follows the +background of the data, the fit was not unsuccessful. Make sure you're +using the right ``.cif`` and ``.prm`` files for your run. You can find +an example of files which work nicely together on most PRs related to +the GSAS tab or GSASIIRefineFitPeaks, or have a look `here +<https://github.com/mantidproject/mantid/files/1739753/GSASIIRefineFitPeaks.zip>`_. + +.. warning:: At the moment, you will also just get background if you + try to do a Pawley refinement, as this is still under + development, possibly requiring input from ENGINX + scientists or GSAS-II developers (probably both) + +You can navigate around the plot in the same way as the Fitting tab. + +Negative Testing Ideas +---------------------- + +- Using an unfocused .nxs file \- Mantid shouldn't crash +- Enter bad input into the text entries - this should be handled + elegantly +- Change any unlocked dialogs and click any unlocked buttons while + refinement is running +- Cancel the algorithm before exiting the GUI, and vice verse + .. _settings-Engineering_Diffraction_test-ref: Settings diff --git a/docs/source/interfaces/Engineering Diffraction.rst b/docs/source/interfaces/Engineering Diffraction.rst index 4885ad56c1d..fa846f2dc0c 100644 --- a/docs/source/interfaces/Engineering Diffraction.rst +++ b/docs/source/interfaces/Engineering Diffraction.rst @@ -451,6 +451,75 @@ User may plot single peak fitting workspace in separate window by using Plot To Separate Window button, if the *engggui_fitting_single_peaks* is available. +.. _gsas-Engineering_Diffraction-ref: + +GSAS Fitting +------------ + +.. warning:: This is a new capability that is currently in a very + early stage of definition and implementation. Not all + options may be supported and/or consistent at the moment. + +The GSAS tab provides a graphical interface to the Mantid algorithm +:ref:`GSASIIRefineFitPeaks <algm-GSASIIRefineFitPeaks>`. This allows +users to perform GSAS-style fitting on their data from Mantid. + +The user must input the following files: + +- **Focused run file(s)** - these must have been generated either by + the **Fitting** tab or :ref:`EnggFocus <algm-EnggFocus>`. +- **Instrument Parameter File** - contains DIFA and DIFC GSAS + constants, will probably be of ``.prm`` format +- **Phase file(s)** - contain crystallographic information about the + sample in question. Currently only ``.cif`` files are supported + +The following parameters are also required: + +- **New GSAS-II Project** - GSASIIRefineFitPeaks creates a new + ``.gpx`` project here, which can be opened and inspected from the + GSAS-II GUI +- **GSAS-II Installation Directory** + + - This is the directory containing the GSAS-II executables and + Python libraries. In particular, it must contain + ``GSASIIscriptable.py``. This directory will normally be called + `GSASII`, if GSAS-II was installed normally + - You must have a version of GSAS-II from at least **February 2018** + to use the GUI. See :ref:`Installing_GSASII` for how to install a + compatible version +- **Refinement method** - can either be **Pawley** or + **Rietveld**. Pawley refinement is currently under development, so + Rietveld is recommended. + +Optionally, you may also supply: + +- **XMin** and **XMax** - the limits (in TOF) to perform fitting + within +- **DMin** - the minimum dSpacing to use for refinement when + performing Pawley refinement +- **Negative weight** - The weight for a penalty function applied + during a Pawley refinement on resulting negative intensities. + +To do a refinement, take the following steps: + +1. Load a run by selecting the focused NeXuS file using the + corresponding **Browse** button, then clicking **Load**. The run + number and bank ID (for example ``123456_1``) should appear in the + **Run Number** list in the **Preview** section. Click the label, + and the run willl be plotted +2. Select your input files, and input any additional parameters in the + **GSASIIRefineFitPeaks Controls** section +3. Click **Run Refinement**. Once complete, fitted peaks for the run + should be overplotted in the fitting area. In addition, Rwp + (goodness of fit index), Sigma and Gamma (peak broadening + coefficients) and lattice parameters should be displayed in the + **Fit Results** section. + +You can toggle the fitted peaks on and off with the **Plot Fitted +Peaks** checkbox, remove runs from the list with the **Remove Run** +button, and plot the run and fitted peaks to a larger, separate plot +using **Plot to separate window**. + .. _setting-Engineering_Diffraction-ref: Settings diff --git a/docs/source/release/v3.13.0/diffraction.rst b/docs/source/release/v3.13.0/diffraction.rst index 283f33d9fb4..c775cd90b95 100644 --- a/docs/source/release/v3.13.0/diffraction.rst +++ b/docs/source/release/v3.13.0/diffraction.rst @@ -10,3 +10,13 @@ Diffraction Changes improvements, followed by bug fixes. :ref:`Release 3.13.0 <v3.13.0>` + +Single Crystal Diffraction +-------------------------- + +Improvements +############ + +- PeaksWorkspace has column added for the unique peak number so peaks can be found after sorting or filtering. + +- :ref:`StatisticsOfPeaksWorkspace <algm-StatisticsOfPeaksWorkspace>` has option to use a weighted Z score for determining which peaks are outliers and has a new output workspace for plotting intensities of equivalent peaks. diff --git a/docs/source/release/v3.13.0/framework.rst b/docs/source/release/v3.13.0/framework.rst index d998b9ccf0d..fdd7ddf0799 100644 --- a/docs/source/release/v3.13.0/framework.rst +++ b/docs/source/release/v3.13.0/framework.rst @@ -10,15 +10,31 @@ Framework Changes improvements, followed by bug fixes. -Bug fixes -######### - -- The documentation of the algorithm :ref:`algm-CreateSampleWorkspace` did not match its implementation. The axis in beam direction will now be correctly described as Z instead of X. Algorithms ---------- +New Features +############ + +- A list of Related Algorithms has been added to each algorithm, and is displayed in the documentation page of each algorithm as part of it's summary. + +New Algorithms +############## + + +Improved +######## + +- :ref:`Maxent <algm-Maxent>` when outputting the results of the iterations, it no longer pads with zeroes but + returns as many items as iterations done for each spectrum, making the iterations easy to count. - :ref:`ConvertToPointData <algm-ConvertToPointData>` and :ref:`ConvertToHistogram <algm-ConvertToHistogram>` now propagate the Dx errors to the output. +- The algorithm :ref:`CreateWorkspace <algm-CreateWorkspace>` can now optionally receive the Dx errors. +- The algorithm :ref:`SortXAxis <algm-SortXAxis>` has a new input option that allows ascending (default) and descending sorting. Furthermore, Dx values will be considered if present. The documentation needed to be corrected. + +Bug fixes +######### +- The documentation of the algorithm :ref:`algm-CreateSampleWorkspace` did not match its implementation. The axis in beam direction will now be correctly described as Z instead of X. :ref:`Release 3.13.0 <v3.13.0>` diff --git a/docs/source/release/v3.13.0/index.rst b/docs/source/release/v3.13.0/index.rst index a1dc52a6f36..ff34eec1b9c 100644 --- a/docs/source/release/v3.13.0/index.rst +++ b/docs/source/release/v3.13.0/index.rst @@ -36,6 +36,7 @@ Changes SANS <sans> Direct Inelastic <direct_inelastic> Indirect Inelastic <indirect_inelastic> + Instrument Visualization <instrument_view> Full Change Listings -------------------- diff --git a/docs/source/release/v3.13.0/instrument_view.rst b/docs/source/release/v3.13.0/instrument_view.rst new file mode 100644 index 00000000000..fadb882e2b0 --- /dev/null +++ b/docs/source/release/v3.13.0/instrument_view.rst @@ -0,0 +1,36 @@ +======================== +Instrument Visualization +======================== + +.. contents:: Table of Contents + :local: + +.. warning:: **Developers:** Sort changes under appropriate heading + putting new features at the top of the section, followed by + improvements, followed by bug fixes. + +Instrument View +--------------- + +The `Instrument View <https://www.mantidproject.org/MantidPlot:_Instrument_View>`__ visualization tool in Mantid has undergone some major changes under-the-hood which has resulted in a smoother, more responsive interface. +Instruments generally load faster as well. Below are a few noteworthy improvements to load times: + ++------------+-----------+ +| Instrument | Speedup | ++============+===========+ +| WISH | 5x | ++------------+-----------+ +| BASIS | 5x | ++------------+-----------+ +| GEM | 4x | ++------------+-----------+ +| SANS2D | 3x | ++------------+-----------+ +| POLARIS | 3x | ++------------+-----------+ +| CNCS | 2x | ++------------+-----------+ + +Tested on Windows 10. + +:ref:`Release 3.13.0 <v3.13.0>` \ No newline at end of file diff --git a/docs/sphinxext/mantiddoc/directives/__init__.py b/docs/sphinxext/mantiddoc/directives/__init__.py index f6e7c496ec6..7b4e06361b2 100644 --- a/docs/sphinxext/mantiddoc/directives/__init__.py +++ b/docs/sphinxext/mantiddoc/directives/__init__.py @@ -8,12 +8,12 @@ """ import mantiddoc.directives.algorithm -import mantiddoc.directives.alias import mantiddoc.directives.attributes import mantiddoc.directives.categories import mantiddoc.directives.diagram import mantiddoc.directives.interface import mantiddoc.directives.properties +import mantiddoc.directives.relatedalgorithms import mantiddoc.directives.sourcelink import mantiddoc.directives.summary @@ -25,11 +25,11 @@ def setup(app): app: The main Sphinx application object """ algorithm.setup(app) - alias.setup(app) attributes.setup(app) categories.setup(app) diagram.setup(app) interface.setup(app) properties.setup(app) + relatedalgorithms.setup(app) sourcelink.setup(app) summary.setup(app) diff --git a/docs/sphinxext/mantiddoc/directives/alias.py b/docs/sphinxext/mantiddoc/directives/alias.py deleted file mode 100644 index 5b6b6b9714c..00000000000 --- a/docs/sphinxext/mantiddoc/directives/alias.py +++ /dev/null @@ -1,34 +0,0 @@ -from mantiddoc.directives.base import AlgorithmBaseDirective #pylint: disable=unused-import - - -class AliasDirective(AlgorithmBaseDirective): - - """ - Obtains the alias for a given algorithm based on it's name. - """ - - required_arguments, optional_arguments = 0, 0 - - def execute(self): - """ - Called by Sphinx when the ..alias:: directive is encountered. - """ - alg = self.create_mantid_algorithm(self.algorithm_name(), self.algorithm_version()) - alias = alg.alias() - if len(alias) == 0: - return [] - - self.add_rst(self.make_header("Alias")) - format_str = "This algorithm is also known as: **%s**" - self.add_rst(format_str % alias) - - return [] - -def setup(app): - """ - Setup the directives when the extension is activated - - Args: - app: The main Sphinx application object - """ - app.add_directive('alias', AliasDirective) diff --git a/docs/sphinxext/mantiddoc/directives/base.py b/docs/sphinxext/mantiddoc/directives/base.py index 3c73c1a4022..7d1884f27f2 100644 --- a/docs/sphinxext/mantiddoc/directives/base.py +++ b/docs/sphinxext/mantiddoc/directives/base.py @@ -82,22 +82,32 @@ class BaseDirective(Directive): """ return self.state.document.settings.env.docname - def make_header(self, name, pagetitle=False): + def make_header(self, name, pagetitle=False, level=2): """ Makes a ReStructuredText title from the algorithm's name. Args: algorithm_name (str): The name of the algorithm to use for the title. - pagetitle (bool): If True, line is inserted above & below algorithm name. + pagetitle (bool): If True, this sets the level to 1 (overriding any other value). + level (int): 1-4 the level of the heading to be used. Returns: str: ReST formatted header with algorithm_name as content. """ + level_dict = {1:"=", 2:"-", 3:"#", 4:"^"} + if pagetitle: - line = "\n" + "=" * (len(name) + 1) + "\n" + level = 1 + if level not in level_dict: + env = self.state.document.settings.env + env.app.warn('base.make_header - Did not understand level ' +str(level)) + level = 2 + + line = "\n" + level_dict[level] * (len(name)) + "\n" + + if level == 1: return line + name + line else: - line = "\n" + "-" * len(name) + "\n" return name + line #---------------------------------------------------------------------------------------- @@ -178,6 +188,21 @@ class AlgorithmBaseDirective(BaseDirective): self._set_algorithm_name_and_version() return self.algm_version + def create_mantid_algorithm_by_name(self, algorithm_name): + """ + Create and initializes a Mantid algorithm using tha latest version. + + Args: + algorithm_name (str): The name of the algorithm to use for the title. + + Returns: + algorithm: An instance of a Mantid algorithm. + """ + from mantid.api import AlgorithmManager + alg = AlgorithmManager.createUnmanaged(algorithm_name) + alg.initialize() + return alg + def create_mantid_algorithm(self, algorithm_name, version): """ Create and initializes a Mantid algorithm. @@ -193,7 +218,7 @@ class AlgorithmBaseDirective(BaseDirective): alg = AlgorithmManager.createUnmanaged(algorithm_name, version) alg.initialize() return alg - + def create_mantid_ifunction(self, function_name): """ Create and initiializes a Mantid IFunction. diff --git a/docs/sphinxext/mantiddoc/directives/relatedalgorithms.py b/docs/sphinxext/mantiddoc/directives/relatedalgorithms.py new file mode 100644 index 00000000000..9b49d8dcc9f --- /dev/null +++ b/docs/sphinxext/mantiddoc/directives/relatedalgorithms.py @@ -0,0 +1,48 @@ +from mantiddoc.directives.base import AlgorithmBaseDirective #pylint: disable=unused-import + +class relatedalgorithmsDirective(AlgorithmBaseDirective): + + """ + Obtains the see also section for a given algorithm based on it's name. + This lists similar algorithms and aliases + """ + + required_arguments, optional_arguments = 0, 0 + + def execute(self): + """ + Called by Sphinx when the ..seealso:: directive is encountered. + """ + alg = self.create_mantid_algorithm(self.algorithm_name(), self.algorithm_version()) + seeAlsoList = alg.seeAlso() + alias = alg.alias() + link_rst = "" + if seeAlsoList: + for seeAlsoEntry in seeAlsoList: + #test the algorithm exists + try: + alg = self.create_mantid_algorithm_by_name(seeAlsoEntry) + link_rst += ":ref:`%s <algm-%s>`, " % (alg.name(), alg.name()) + except RuntimeError: + env = self.state.document.settings.env + env.app.warn('relatedalgorithms - Could not find algorithm "{0}" listed in the seeAlso for {1}.v{2}'.format( + seeAlsoEntry,self.algorithm_name(), self.algorithm_version())) + + if link_rst or alias: + self.add_rst(self.make_header("See Also",level=3)) + if link_rst: + link_rst = link_rst.rstrip(", ") # remove final separator + self.add_rst(link_rst + "\n\n") + if alias: + format_str = "This algorithm is also known as: **%s**" + self.add_rst(format_str % alias) + return [] + +def setup(app): + """ + Setup the directives when the extension is activated + + Args: + app: The main Sphinx application object + """ + app.add_directive('relatedalgorithms', relatedalgorithmsDirective) diff --git a/instrument/D2B_2018-03-01_Definition.xml b/instrument/D2B_2018-03-01_Definition.xml new file mode 100644 index 00000000000..ae591739459 --- /dev/null +++ b/instrument/D2B_2018-03-01_Definition.xml @@ -0,0 +1,324 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- For help on the notation used to specify an Instrument Definition File see http://www.mantidproject.org/IDF --> +<instrument xmlns="http://www.mantidproject.org/IDF/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 Schema/IDFSchema.xsd" name="D2B" valid-from="2018-03-01 23:59:59" +valid-to="2100-01-31 23:59:59" last-modified="2018-03-20 14:05:02"> + <!-- Author: bush@ill.fr --> + <defaults> + <length unit="meter" /> + <angle unit="degree" /> + <reference-frame> + <!-- The z-axis is set parallel to and in the direction of the beam. The y-axis points up and the coordinate system is right handed. --> + <along-beam axis="z" /> + <pointing-up axis="y" /> + <handedness val="right" /> + </reference-frame> + </defaults> + <!-- Source position --> + <component type="monochromator"> + <location z="-2.997" /> + </component> + <type name="monochromator" is="Source" /> + <!-- Monitor position --> + <component type="monitor" idlist="monitors"> + <location z="-1.594" name="monitor" /> + </component> + <type name="monitor" is="monitor"> + <cuboid id="shape"> + <left-front-bottom-point x="-0.005" y="-0.005" z="-0.005" /> + <left-front-top-point x="-0.005" y="0.005" z="-0.005" /> + <left-back-bottom-point x="-0.005" y="-0.005" z="0.005" /> + <right-front-bottom-point x="0.005" y="-0.005" z="-0.005" /> + </cuboid> + <algebra val="shape" /> + </type> + <idlist idname="monitors"> + <id val="0" /> + </idlist> + <!-- Sample position --> + <component type="sample-position"> + <location x="0.0" y="0.0" z="0.0" /> + </component> + <type name="sample-position" is="SamplePos" /> + <!-- Detector IDs --> + <idlist idname="detectors"> + <id start="1" end="16384" /> + </idlist> + <!-- Detector list def --> + <component type="detectors" idlist="detectors"> + <location x="0.0" y="0.0" z="0.0" /> + </component> + <type name="detectors"> + <component type="standard_tube"> + <location r="1.296" t="-6.25" name="tube_1" /> + <location r="1.296" t="-7.5" name="tube_2" /> + <location r="1.296" t="-8.75" name="tube_3" /> + <location r="1.296" t="-10.0" name="tube_4" /> + <location r="1.296" t="-11.25" name="tube_5" /> + <location r="1.296" t="-12.5" name="tube_6" /> + <location r="1.296" t="-13.75" name="tube_7" /> + <location r="1.296" t="-15.0" name="tube_8" /> + <location r="1.296" t="-16.25" name="tube_9" /> + <location r="1.296" t="-17.5" name="tube_10" /> + <location r="1.296" t="-18.75" name="tube_11" /> + <location r="1.296" t="-20.0" name="tube_12" /> + <location r="1.296" t="-21.25" name="tube_13" /> + <location r="1.296" t="-22.5" name="tube_14" /> + <location r="1.296" t="-23.75" name="tube_15" /> + <location r="1.296" t="-25.0" name="tube_16" /> + <location r="1.296" t="-26.25" name="tube_17" /> + <location r="1.296" t="-27.5" name="tube_18" /> + <location r="1.296" t="-28.75" name="tube_19" /> + <location r="1.296" t="-30.0" name="tube_20" /> + <location r="1.296" t="-31.25" name="tube_21" /> + <location r="1.296" t="-32.5" name="tube_22" /> + <location r="1.296" t="-33.75" name="tube_23" /> + <location r="1.296" t="-35.0" name="tube_24" /> + <location r="1.296" t="-36.25" name="tube_25" /> + <location r="1.296" t="-37.5" name="tube_26" /> + <location r="1.296" t="-38.75" name="tube_27" /> + <location r="1.296" t="-40.0" name="tube_28" /> + <location r="1.296" t="-41.25" name="tube_29" /> + <location r="1.296" t="-42.5" name="tube_30" /> + <location r="1.296" t="-43.75" name="tube_31" /> + <location r="1.296" t="-45.0" name="tube_32" /> + <location r="1.296" t="-46.25" name="tube_33" /> + <location r="1.296" t="-47.5" name="tube_34" /> + <location r="1.296" t="-48.75" name="tube_35" /> + <location r="1.296" t="-50.0" name="tube_36" /> + <location r="1.296" t="-51.25" name="tube_37" /> + <location r="1.296" t="-52.5" name="tube_38" /> + <location r="1.296" t="-53.75" name="tube_39" /> + <location r="1.296" t="-55.0" name="tube_40" /> + <location r="1.296" t="-56.25" name="tube_41" /> + <location r="1.296" t="-57.5" name="tube_42" /> + <location r="1.296" t="-58.75" name="tube_43" /> + <location r="1.296" t="-60.0" name="tube_44" /> + <location r="1.296" t="-61.25" name="tube_45" /> + <location r="1.296" t="-62.5" name="tube_46" /> + <location r="1.296" t="-63.75" name="tube_47" /> + <location r="1.296" t="-65.0" name="tube_48" /> + <location r="1.296" t="-66.25" name="tube_49" /> + <location r="1.296" t="-67.5" name="tube_50" /> + <location r="1.296" t="-68.75" name="tube_51" /> + <location r="1.296" t="-70.0" name="tube_52" /> + <location r="1.296" t="-71.25" name="tube_53" /> + <location r="1.296" t="-72.5" name="tube_54" /> + <location r="1.296" t="-73.75" name="tube_55" /> + <location r="1.296" t="-75.0" name="tube_56" /> + <location r="1.296" t="-76.25" name="tube_57" /> + <location r="1.296" t="-77.5" name="tube_58" /> + <location r="1.296" t="-78.75" name="tube_59" /> + <location r="1.296" t="-80.0" name="tube_60" /> + <location r="1.296" t="-81.25" name="tube_61" /> + <location r="1.296" t="-82.5" name="tube_62" /> + <location r="1.296" t="-83.75" name="tube_63" /> + <location r="1.296" t="-85.0" name="tube_64" /> + <location r="1.296" t="-86.25" name="tube_65" /> + <location r="1.296" t="-87.5" name="tube_66" /> + <location r="1.296" t="-88.75" name="tube_67" /> + <location r="1.296" t="-90.0" name="tube_68" /> + <location r="1.296" t="-91.25" name="tube_69" /> + <location r="1.296" t="-92.5" name="tube_70" /> + <location r="1.296" t="-93.75" name="tube_71" /> + <location r="1.296" t="-95.0" name="tube_72" /> + <location r="1.296" t="-96.25" name="tube_73" /> + <location r="1.296" t="-97.5" name="tube_74" /> + <location r="1.296" t="-98.75" name="tube_75" /> + <location r="1.296" t="-100.0" name="tube_76" /> + <location r="1.296" t="-101.25" name="tube_77" /> + <location r="1.296" t="-102.5" name="tube_78" /> + <location r="1.296" t="-103.75" name="tube_79" /> + <location r="1.296" t="-105.0" name="tube_80" /> + <location r="1.296" t="-106.25" name="tube_81" /> + <location r="1.296" t="-107.5" name="tube_82" /> + <location r="1.296" t="-108.75" name="tube_83" /> + <location r="1.296" t="-110.0" name="tube_84" /> + <location r="1.296" t="-111.25" name="tube_85" /> + <location r="1.296" t="-112.5" name="tube_86" /> + <location r="1.296" t="-113.75" name="tube_87" /> + <location r="1.296" t="-115.0" name="tube_88" /> + <location r="1.296" t="-116.25" name="tube_89" /> + <location r="1.296" t="-117.5" name="tube_90" /> + <location r="1.296" t="-118.75" name="tube_91" /> + <location r="1.296" t="-120.0" name="tube_92" /> + <location r="1.296" t="-121.25" name="tube_93" /> + <location r="1.296" t="-122.5" name="tube_94" /> + <location r="1.296" t="-123.75" name="tube_95" /> + <location r="1.296" t="-125.0" name="tube_96" /> + <location r="1.296" t="-126.25" name="tube_97" /> + <location r="1.296" t="-127.5" name="tube_98" /> + <location r="1.296" t="-128.75" name="tube_99" /> + <location r="1.296" t="-130.0" name="tube_100" /> + <location r="1.296" t="-131.25" name="tube_101" /> + <location r="1.296" t="-132.5" name="tube_102" /> + <location r="1.296" t="-133.75" name="tube_103" /> + <location r="1.296" t="-135.0" name="tube_104" /> + <location r="1.296" t="-136.25" name="tube_105" /> + <location r="1.296" t="-137.5" name="tube_106" /> + <location r="1.296" t="-138.75" name="tube_107" /> + <location r="1.296" t="-140.0" name="tube_108" /> + <location r="1.296" t="-141.25" name="tube_109" /> + <location r="1.296" t="-142.5" name="tube_110" /> + <location r="1.296" t="-143.75" name="tube_111" /> + <location r="1.296" t="-145.0" name="tube_112" /> + <location r="1.296" t="-146.25" name="tube_113" /> + <location r="1.296" t="-147.5" name="tube_114" /> + <location r="1.296" t="-148.75" name="tube_115" /> + <location r="1.296" t="-150.0" name="tube_116" /> + <location r="1.296" t="-151.25" name="tube_117" /> + <location r="1.296" t="-152.5" name="tube_118" /> + <location r="1.296" t="-153.75" name="tube_119" /> + <location r="1.296" t="-155.0" name="tube_120" /> + <location r="1.296" t="-156.25" name="tube_121" /> + <location r="1.296" t="-157.5" name="tube_122" /> + <location r="1.296" t="-158.75" name="tube_123" /> + <location r="1.296" t="-160.0" name="tube_124" /> + <location r="1.296" t="-161.25" name="tube_125" /> + <location r="1.296" t="-162.5" name="tube_126" /> + <location r="1.296" t="-163.75" name="tube_127" /> + <location r="1.296" t="-165.0" name="tube_128" /> + </component> + </type> + <!-- Definition of standard_tube --> + <type name="standard_tube" outline="yes"> + <component type="standard_pixel"> + <location y="-0.175865234375" /> + <location y="-0.173095703125" /> + <location y="-0.170326171875" /> + <location y="-0.167556640625" /> + <location y="-0.164787109375" /> + <location y="-0.162017578125" /> + <location y="-0.159248046875" /> + <location y="-0.156478515625" /> + <location y="-0.153708984375" /> + <location y="-0.150939453125" /> + <location y="-0.148169921875" /> + <location y="-0.145400390625" /> + <location y="-0.142630859375" /> + <location y="-0.139861328125" /> + <location y="-0.137091796875" /> + <location y="-0.134322265625" /> + <location y="-0.131552734375" /> + <location y="-0.128783203125" /> + <location y="-0.126013671875" /> + <location y="-0.123244140625" /> + <location y="-0.120474609375" /> + <location y="-0.117705078125" /> + <location y="-0.114935546875" /> + <location y="-0.112166015625" /> + <location y="-0.109396484375" /> + <location y="-0.106626953125" /> + <location y="-0.103857421875" /> + <location y="-0.101087890625" /> + <location y="-0.098318359375" /> + <location y="-0.095548828125" /> + <location y="-0.092779296875" /> + <location y="-0.090009765625" /> + <location y="-0.087240234375" /> + <location y="-0.084470703125" /> + <location y="-0.081701171875" /> + <location y="-0.078931640625" /> + <location y="-0.076162109375" /> + <location y="-0.073392578125" /> + <location y="-0.070623046875" /> + <location y="-0.067853515625" /> + <location y="-0.065083984375" /> + <location y="-0.062314453125" /> + <location y="-0.059544921875" /> + <location y="-0.056775390625" /> + <location y="-0.054005859375" /> + <location y="-0.051236328125" /> + <location y="-0.048466796875" /> + <location y="-0.045697265625" /> + <location y="-0.042927734375" /> + <location y="-0.040158203125" /> + <location y="-0.037388671875" /> + <location y="-0.034619140625" /> + <location y="-0.031849609375" /> + <location y="-0.029080078125" /> + <location y="-0.026310546875" /> + <location y="-0.023541015625" /> + <location y="-0.020771484375" /> + <location y="-0.018001953125" /> + <location y="-0.015232421875" /> + <location y="-0.012462890625" /> + <location y="-0.009693359375" /> + <location y="-0.006923828125" /> + <location y="-0.004154296875" /> + <location y="-0.001384765625" /> + <location y="0.001384765625" /> + <location y="0.004154296875" /> + <location y="0.006923828125" /> + <location y="0.009693359375" /> + <location y="0.012462890625" /> + <location y="0.015232421875" /> + <location y="0.018001953125" /> + <location y="0.020771484375" /> + <location y="0.023541015625" /> + <location y="0.026310546875" /> + <location y="0.029080078125" /> + <location y="0.031849609375" /> + <location y="0.034619140625" /> + <location y="0.037388671875" /> + <location y="0.040158203125" /> + <location y="0.042927734375" /> + <location y="0.045697265625" /> + <location y="0.048466796875" /> + <location y="0.051236328125" /> + <location y="0.054005859375" /> + <location y="0.056775390625" /> + <location y="0.059544921875" /> + <location y="0.062314453125" /> + <location y="0.065083984375" /> + <location y="0.067853515625" /> + <location y="0.070623046875" /> + <location y="0.073392578125" /> + <location y="0.076162109375" /> + <location y="0.078931640625" /> + <location y="0.081701171875" /> + <location y="0.084470703125" /> + <location y="0.087240234375" /> + <location y="0.090009765625" /> + <location y="0.092779296875" /> + <location y="0.095548828125" /> + <location y="0.098318359375" /> + <location y="0.101087890625" /> + <location y="0.103857421875" /> + <location y="0.106626953125" /> + <location y="0.109396484375" /> + <location y="0.112166015625" /> + <location y="0.114935546875" /> + <location y="0.117705078125" /> + <location y="0.120474609375" /> + <location y="0.123244140625" /> + <location y="0.126013671875" /> + <location y="0.128783203125" /> + <location y="0.131552734375" /> + <location y="0.134322265625" /> + <location y="0.137091796875" /> + <location y="0.139861328125" /> + <location y="0.142630859375" /> + <location y="0.145400390625" /> + <location y="0.148169921875" /> + <location y="0.150939453125" /> + <location y="0.153708984375" /> + <location y="0.156478515625" /> + <location y="0.159248046875" /> + <location y="0.162017578125" /> + <location y="0.164787109375" /> + <location y="0.167556640625" /> + <location y="0.170326171875" /> + <location y="0.173095703125" /> + <location y="0.175865234375" /> + </component> + </type> + <type name="standard_pixel" is="detector"> + <cylinder id="shape"> + <centre-of-bottom-base x="0.0" y="-0.001384765625" z="0.0" /> + <axis x="0.0" y="1.0" z="0.0" /> + <radius val="0.000565486605872" /> + <height val="0.00276953125" /> + </cylinder> + <algebra val="shape" /> + </type> +</instrument> diff --git a/qt/paraview_ext/PVPlugins/Sources/MDEWSource/vtkMDEWSource.cxx b/qt/paraview_ext/PVPlugins/Sources/MDEWSource/vtkMDEWSource.cxx index a1124c1485d..73df2744afc 100644 --- a/qt/paraview_ext/PVPlugins/Sources/MDEWSource/vtkMDEWSource.cxx +++ b/qt/paraview_ext/PVPlugins/Sources/MDEWSource/vtkMDEWSource.cxx @@ -38,7 +38,7 @@ vtkStandardNewMacro(vtkMDEWSource) } /// Destructor -vtkMDEWSource::~vtkMDEWSource() {} +vtkMDEWSource::~vtkMDEWSource() = default; /* Setter for the recursion depth diff --git a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Normalization.h b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Normalization.h index e85e8c1a0b3..f66f86b2721 100644 --- a/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Normalization.h +++ b/qt/paraview_ext/VatesAPI/inc/MantidVatesAPI/Normalization.h @@ -4,6 +4,8 @@ #include "MantidAPI/DllConfig.h" #include "MantidGeometry/MDGeometry/MDTypes.h" +#include <memory> + namespace Mantid { namespace API { @@ -50,7 +52,7 @@ NormFuncIMDNodePtr makeMDEventNormalizationFunction( Determine which normalization function will be called on an IMDIterator of an IMDWorkspace */ -DLLExport Mantid::API::IMDIterator * +DLLExport std::unique_ptr<Mantid::API::IMDIterator> createIteratorWithNormalization(const VisualNormalization normalizationOption, Mantid::API::IMDWorkspace const *const ws); } diff --git a/qt/paraview_ext/VatesAPI/src/Normalization.cpp b/qt/paraview_ext/VatesAPI/src/Normalization.cpp index bea3316f82c..46492b4e88a 100644 --- a/qt/paraview_ext/VatesAPI/src/Normalization.cpp +++ b/qt/paraview_ext/VatesAPI/src/Normalization.cpp @@ -46,7 +46,7 @@ Create iterators with correct normalization normalization to an IMDIterator. @param ws : workspace to fetch defaults from if needed @return new IMDIterator */ -DLLExport Mantid::API::IMDIterator * +DLLExport std::unique_ptr<Mantid::API::IMDIterator> createIteratorWithNormalization(const VisualNormalization normalizationOption, Mantid::API::IMDWorkspace const *const ws) { @@ -63,7 +63,7 @@ createIteratorWithNormalization(const VisualNormalization normalizationOption, } // Create the iterator - IMDIterator *iterator = ws->createIterator(); + auto iterator = ws->createIterator(); // Set normalization iterator->setNormalization(targetNormalization); // Return it diff --git a/qt/paraview_ext/VatesAPI/src/vtkMDHexFactory.cpp b/qt/paraview_ext/VatesAPI/src/vtkMDHexFactory.cpp index d4da34d2b69..ba303cfe6ac 100644 --- a/qt/paraview_ext/VatesAPI/src/vtkMDHexFactory.cpp +++ b/qt/paraview_ext/VatesAPI/src/vtkMDHexFactory.cpp @@ -128,11 +128,9 @@ void vtkMDHexFactory::doCreate( // If slicing down to 3D, specify which dimensions to keep. if (this->slice) { - coords = std::unique_ptr<coord_t[]>( - box->getVertexesArray(numVertexes, 3, this->sliceMask.get())); + coords = box->getVertexesArray(numVertexes, 3, this->sliceMask.get()); } else { - coords = - std::unique_ptr<coord_t[]>(box->getVertexesArray(numVertexes)); + coords = box->getVertexesArray(numVertexes); } if (numVertexes == 8) { std::copy_n(coords.get(), 24, std::next(pointsPtr, i * 24)); diff --git a/qt/paraview_ext/VatesAPI/src/vtkMDHistoQuadFactory.cpp b/qt/paraview_ext/VatesAPI/src/vtkMDHistoQuadFactory.cpp index 71e0e15560f..bbce429bbf8 100644 --- a/qt/paraview_ext/VatesAPI/src/vtkMDHistoQuadFactory.cpp +++ b/qt/paraview_ext/VatesAPI/src/vtkMDHistoQuadFactory.cpp @@ -88,10 +88,9 @@ vtkMDHistoQuadFactory::create(ProgressAction &progressUpdating) const { coord_t incrementX = (maxX - minX) / static_cast<coord_t>(nBinsX); coord_t incrementY = (maxY - minY) / static_cast<coord_t>(nBinsY); - boost::scoped_ptr<MDHistoWorkspaceIterator> iterator( - dynamic_cast<MDHistoWorkspaceIterator *>( - createIteratorWithNormalization(m_normalizationOption, - m_workspace.get()))); + auto it = createIteratorWithNormalization(m_normalizationOption, + m_workspace.get()); + auto iterator = dynamic_cast<MDHistoWorkspaceIterator *>(it.get()); if (!iterator) { throw std::runtime_error( "Could not convert IMDIterator to a MDHistoWorkspaceIterator"); diff --git a/qt/paraview_ext/VatesAPI/src/vtkMDLineFactory.cpp b/qt/paraview_ext/VatesAPI/src/vtkMDLineFactory.cpp index 3379a5bf4a5..38e144b2aec 100644 --- a/qt/paraview_ext/VatesAPI/src/vtkMDLineFactory.cpp +++ b/qt/paraview_ext/VatesAPI/src/vtkMDLineFactory.cpp @@ -75,8 +75,8 @@ vtkMDLineFactory::create(ProgressAction &progressUpdating) const { } // Ensure destruction in any event. - boost::scoped_ptr<IMDIterator> it( - createIteratorWithNormalization(m_normalizationOption, imdws.get())); + auto it = + createIteratorWithNormalization(m_normalizationOption, imdws.get()); // Create 2 points per box. vtkNew<vtkPoints> points; @@ -116,8 +116,8 @@ vtkMDLineFactory::create(ProgressAction &progressUpdating) const { useBox[iBox] = true; signals->InsertNextValue(static_cast<float>(signal_normalized)); - auto coords = std::unique_ptr<coord_t[]>( - it->getVertexesArray(nVertexes, nNonIntegrated, masks.get())); + auto coords = + it->getVertexesArray(nVertexes, nNonIntegrated, masks.get()); // Iterate through all coordinates. Candidate for speed improvement. for (size_t v = 0; v < nVertexes; ++v) { diff --git a/qt/paraview_ext/VatesAPI/src/vtkMDQuadFactory.cpp b/qt/paraview_ext/VatesAPI/src/vtkMDQuadFactory.cpp index 5fa55dc5f3f..77fd67e7b5b 100644 --- a/qt/paraview_ext/VatesAPI/src/vtkMDQuadFactory.cpp +++ b/qt/paraview_ext/VatesAPI/src/vtkMDQuadFactory.cpp @@ -71,8 +71,8 @@ vtkMDQuadFactory::create(ProgressAction &progressUpdating) const { // Make iterator, which will use the desired normalization. Ensure // destruction in any eventuality. - boost::scoped_ptr<IMDIterator> it( - createIteratorWithNormalization(m_normalizationOption, imdws.get())); + auto it = + createIteratorWithNormalization(m_normalizationOption, imdws.get()); // Create 4 points per box. vtkNew<vtkPoints> points; @@ -112,9 +112,8 @@ vtkMDQuadFactory::create(ProgressAction &progressUpdating) const { useBox[iBox] = true; signals->InsertNextValue(static_cast<float>(signal)); - auto coords = std::unique_ptr<coord_t[]>( - it->getVertexesArray(nVertexes, nNonIntegrated, masks.get())); - + auto coords = + it->getVertexesArray(nVertexes, nNonIntegrated, masks.get()); // Iterate through all coordinates. Candidate for speed improvement. for (size_t v = 0; v < nVertexes; ++v) { coord_t *coord = coords.get() + v * 2; diff --git a/qt/paraview_ext/VatesAPI/test/MockObjects.h b/qt/paraview_ext/VatesAPI/test/MockObjects.h index 25262bdcede..0a58626c34f 100644 --- a/qt/paraview_ext/VatesAPI/test/MockObjects.h +++ b/qt/paraview_ext/VatesAPI/test/MockObjects.h @@ -102,7 +102,7 @@ public: return line; } - std::vector<Mantid::API::IMDIterator *> createIterators( + std::vector<std::unique_ptr<Mantid::API::IMDIterator>> createIterators( size_t = 1, Mantid::Geometry::MDImplicitFunction * = NULL) const override { throw std::runtime_error("Not Implemented"); diff --git a/qt/python/mantidqt/utils/qt/testing/__init__.py b/qt/python/mantidqt/utils/qt/testing/__init__.py index ec30caa54e0..7aee12dd518 100644 --- a/qt/python/mantidqt/utils/qt/testing/__init__.py +++ b/qt/python/mantidqt/utils/qt/testing/__init__.py @@ -20,6 +20,7 @@ from __future__ import absolute_import from inspect import isfunction, ismethod +import gc from qtpy.QtCore import Qt from qtpy.QtWidgets import QApplication @@ -74,6 +75,7 @@ def _requires_qapp_impl(test_method): QAPP = QApplication(['']) test_method(self) QAPP.closeAllWindows() + gc.collect() return _wrapper diff --git a/qt/python/mantidqt/widgets/test/test_jupyterconsole.py b/qt/python/mantidqt/widgets/test/test_jupyterconsole.py index 411e9f4e2e2..c4f2d103ae6 100644 --- a/qt/python/mantidqt/widgets/test/test_jupyterconsole.py +++ b/qt/python/mantidqt/widgets/test/test_jupyterconsole.py @@ -34,16 +34,18 @@ class InProcessJupyterConsoleTest(unittest.TestCase): self.assertTrue(hasattr(widget, "kernel_manager")) self.assertTrue(hasattr(widget, "kernel_client")) self.assertTrue(len(widget.banner) > 0) + del widget def test_construction_with_banner_replaces_default(self): widget = InProcessJupyterConsole(banner="Hello!") self.assertEquals("Hello!", widget.banner) + del widget def test_construction_with_startup_code_adds_to_banner_and_executes(self): widget = InProcessJupyterConsole(startup_code="x = 1") self.assertTrue("x = 1" in widget.banner) self.assertEquals(1, widget.kernel_manager.kernel.shell.user_ns['x']) - + del widget if __name__ == '__main__': unittest.main() diff --git a/qt/widgets/common/test/FindFilesThreadPoolManagerTest.h b/qt/widgets/common/test/FindFilesThreadPoolManagerTest.h index 5d5996179b3..e1cc013e734 100644 --- a/qt/widgets/common/test/FindFilesThreadPoolManagerTest.h +++ b/qt/widgets/common/test/FindFilesThreadPoolManagerTest.h @@ -29,7 +29,7 @@ public: int argc = 1; char name[] = "DummyTestingApplication"; char *argv = name; - QApplication app(argc, &argv); + QCoreApplication app(argc, &argv); // Arrange FakeMWRunFiles *widget = new FakeMWRunFiles(); @@ -56,7 +56,7 @@ public: poolManager.createWorker(widget, parameters); // Block and wait for all the threads to process poolManager.waitForDone(); - QApplication::processEvents(); + QCoreApplication::processEvents(); // Assert const auto results = widget->getResults(); @@ -72,7 +72,7 @@ public: int argc = 1; char name[] = "DummyTestingApplication"; char *argv = name; - QApplication app(argc, &argv); + QCoreApplication app(argc, &argv); // Arrange FakeMWRunFiles widget; @@ -118,7 +118,7 @@ public: // Block and wait for all the threads to process poolManager.waitForDone(); - QApplication::processEvents(); + QCoreApplication::processEvents(); // Assert const auto results = widget.getResults(); diff --git a/qt/widgets/common/test/FindFilesWorkerTest.h b/qt/widgets/common/test/FindFilesWorkerTest.h index f491c72bc0e..6f146986100 100644 --- a/qt/widgets/common/test/FindFilesWorkerTest.h +++ b/qt/widgets/common/test/FindFilesWorkerTest.h @@ -28,7 +28,7 @@ public: int argc = 1; char name[] = "DummyTestingApplication"; char *argv = name; - QApplication app(argc, &argv); + QCoreApplication app(argc, &argv); auto parameters = createFileSearch("IRS26173"); auto worker = new FindFilesWorker(parameters); @@ -52,7 +52,7 @@ public: int argc = 1; char name[] = "DummyTestingApplication"; char *argv = name; - QApplication app(argc, &argv); + QCoreApplication app(argc, &argv); auto parameters = createFileSearch("IRS26173"); parameters.algorithmName = ""; @@ -79,7 +79,7 @@ public: int argc = 1; char name[] = "DummyTestingApplication"; char *argv = name; - QApplication app(argc, &argv); + QCoreApplication app(argc, &argv); auto parameters = createFileSearch("ThisFileDoesNotExist"); auto worker = new FindFilesWorker(parameters); @@ -100,7 +100,7 @@ public: int argc = 1; char name[] = "DummyTestingApplication"; char *argv = name; - QApplication app(argc, &argv); + QCoreApplication app(argc, &argv); auto parameters = createFileSearch(""); auto worker = new FindFilesWorker(parameters); @@ -121,7 +121,7 @@ public: int argc = 1; char name[] = "DummyTestingApplication"; char *argv = name; - QApplication app(argc, &argv); + QCoreApplication app(argc, &argv); auto parameters = createFileSearch(""); parameters.isOptional = true; diff --git a/qt/widgets/instrumentview/CMakeLists.txt b/qt/widgets/instrumentview/CMakeLists.txt index 190ed2d1703..acf4828ccf8 100644 --- a/qt/widgets/instrumentview/CMakeLists.txt +++ b/qt/widgets/instrumentview/CMakeLists.txt @@ -1,4 +1,5 @@ set ( SRC_FILES + src/BankRenderingHelpers.cpp src/BinDialog.cpp src/CollapsiblePanel.cpp src/ColorMapWidget.cpp @@ -12,6 +13,7 @@ set ( SRC_FILES src/InstrumentWidgetMaskTab.cpp src/InstrumentWidgetPickTab.cpp src/InstrumentWidgetRenderTab.cpp + src/InstrumentRenderer.cpp src/InstrumentWidgetTab.cpp src/InstrumentWidgetTreeTab.cpp src/MantidGLWidget.cpp @@ -62,6 +64,7 @@ set ( MOC_FILES ) set ( INC_FILES + inc/MantidQtWidgets/InstrumentView/BankRenderingHelpers.h inc/MantidQtWidgets/InstrumentView/BinDialog.h inc/MantidQtWidgets/InstrumentView/CollapsiblePanel.h inc/MantidQtWidgets/InstrumentView/ColorMapWidget.h @@ -73,6 +76,7 @@ set ( INC_FILES inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h inc/MantidQtWidgets/InstrumentView/InstrumentTreeWidget.h inc/MantidQtWidgets/InstrumentView/InstrumentWidget.h + inc/MantidQtWidgets/InstrumentView/InstrumentRenderer.h inc/MantidQtWidgets/InstrumentView/InstrumentWidgetMaskTab.h inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h inc/MantidQtWidgets/InstrumentView/InstrumentWidgetRenderTab.h diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BankRenderingHelpers.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BankRenderingHelpers.h new file mode 100644 index 00000000000..8a8fd3b296d --- /dev/null +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/BankRenderingHelpers.h @@ -0,0 +1,39 @@ +#ifndef BANKRENDERINGHELPERS_H +#define BANKRENDERINGHELPERS_H +#include "DllOption.h" +#include "MantidQtWidgets/InstrumentView/GLColor.h" +#include <vector> + +namespace Mantid { +namespace Geometry { +class ComponentInfo; +} +} // namespace Mantid + +namespace MantidQt { +namespace MantidWidgets { +namespace BankRenderingHelpers { + +EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW std::pair<size_t, size_t> +getCorrectedTextureSize(const size_t width, const size_t height); + +/** Render RectangularDetector Bank as bitmap texture +Makes OpenGL calls for drawing the bank in an OpenGL window. NB glBegin() and +glEnd() are called within this function. +*/ +EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW void +renderRectangularBank(const Mantid::Geometry::ComponentInfo &compInfo, + size_t index); + +/** Render Structured Detector Bank as quads +Makes OpenGL calls for drawing the bank in an OpenGL window. NB glBegin() and +glEnd() are called within this function. +*/ +EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW void +renderStructuredBank(const Mantid::Geometry::ComponentInfo &compInfo, + size_t index, const std::vector<GLColor> &color); +} // namespace RenderingHelpers +} // namespace MantidWidgets +} // namespace MantidQt + +#endif // BANKRENDERINGHELPERS_H \ No newline at end of file diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h index e10ff7ac24d..1a47db2898e 100644 --- a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentActor.h @@ -21,9 +21,7 @@ class MatrixWorkspace; class IMaskWorkspace; } namespace Geometry { -class IObjComponent; class Instrument; -class IDetector; class ComponentInfo; class DetectorInfo; } @@ -32,6 +30,8 @@ class DetectorInfo; namespace MantidQt { namespace MantidWidgets { +class InstrumentRenderer; + /** \class InstrumentActor \brief InstrumentActor class is wrapper actor for the instrument. @@ -81,6 +81,8 @@ public: void invertMaskWorkspace() const; /// Get the mask displayed but not yet applied as a IMaskWorkspace boost::shared_ptr<Mantid::API::IMaskWorkspace> getMaskWorkspace() const; + boost::shared_ptr<Mantid::API::IMaskWorkspace> + getMaskWorkspaceIfExists() const; /// Apply the mask in the attached mask workspace to the data. void applyMaskWorkspace(); /// Add a range of bins for masking @@ -158,9 +160,6 @@ public: /// Update the detector colors to match the integrated counts within the /// current integration range. void updateColors(); - /// Invalidate the OpenGL display lists to force full re-drawing of the - /// instrument and creation of new lists. - void invalidateDisplayLists() const; //{ m_scene.invalidateDisplayList(); } /// Toggle display of the guide and other non-detector instrument components void showGuides(bool); /// Get the guide visibility status @@ -178,10 +177,6 @@ public: const Mantid::Kernel::V3D &up, Mantid::Kernel::Quat &R); - /// Convert a "pick ID" to a colour to put into the pick image. - static GLColor makePickColor(size_t pickID); - /// Decode a pick colour and return corresponding "pick ID" - static size_t decodePickColor(const QRgb &c); /* Masking */ void initMaskHelper() const; @@ -197,12 +192,13 @@ public: void loadFromProject(const std::string &lines); /// Save the state of the actor to a Mantid project file. std::string saveToProject() const; + /// Returns indices of all non-detector components in Instrument. + const std::vector<size_t> &components() const { return m_components; } signals: void colorMapChanged(); private: - void doDraw(bool picking) const; void setUpWorkspace( boost::shared_ptr<const Mantid::API::MatrixWorkspace> sharedWorkspace, double scaleMin, double scaleMax); @@ -224,11 +220,6 @@ private: std::vector<double> &x, std::vector<double> &y, size_t size) const; - void setupPickColors(); - - boost::shared_ptr<Mantid::API::IMaskWorkspace> - getMaskWorkspaceIfExists() const; - /// The workspace whose data are shown const boost::weak_ptr<const Mantid::API::MatrixWorkspace> m_workspace; /// The helper masking workspace keeping the mask build in the mask tab but @@ -236,8 +227,6 @@ private: mutable boost::shared_ptr<Mantid::API::MatrixWorkspace> m_maskWorkspace; /// A helper object that keeps bin masking data. mutable MaskBinsData m_maskBinsData; - /// The colormap - MantidColorMap m_colorMap; QString m_currentColorMapFilename; /// integrated spectra std::vector<double> m_specIntegrs; @@ -263,25 +252,18 @@ private: const Mantid::Kernel::V3D m_defaultPos; /// Colors in order of component info - std::vector<GLColor> m_colors; std::vector<size_t> m_monitors; std::vector<size_t> m_components; - /// Colour of a masked detector - GLColor m_maskedColor; - /// Colour of a "failed" detector - GLColor m_failedColor; static double m_tolerance; - std::vector<GLColor> m_pickColors; std::vector<bool> m_isCompVisible; std::vector<size_t> m_detIndex2WsIndex; - // Two display lists for normal rendering and picking - mutable GLuint m_displayListId[2]; - mutable bool m_useDisplayList[2]; + bool m_isPhysicalInstrument; std::unique_ptr<Mantid::Geometry::ComponentInfo> m_physicalComponentInfo; std::unique_ptr<Mantid::Geometry::DetectorInfo> m_physicalDetectorInfo; + std::unique_ptr<InstrumentRenderer> m_renderer; }; } // MantidWidgets diff --git a/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentRenderer.h b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentRenderer.h new file mode 100644 index 00000000000..880cbc9e366 --- /dev/null +++ b/qt/widgets/instrumentview/inc/MantidQtWidgets/InstrumentView/InstrumentRenderer.h @@ -0,0 +1,74 @@ +#ifndef INSTRUMENTRENDERER_H_ +#define INSTRUMENTRENDERER_H_ + +#include "DllOption.h" +#include "GLColor.h" +#include "MantidGeometry/Rendering/OpenGL_Headers.h" +#include "MantidQtWidgets/LegacyQwt/MantidColorMap.h" +#include <QString> + +namespace MantidQt { +namespace MantidWidgets { +class InstrumentActor; + +class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentRenderer { +private: + const InstrumentActor &m_actor; + std::vector<GLColor> m_colors; + std::vector<GLColor> m_pickColors; + mutable GLuint m_displayListId[2]; + mutable bool m_useDisplayList[2]; + mutable std::vector<GLuint> m_textureIDs; + mutable std::vector<size_t> m_textureIndices; + mutable std::map<size_t, size_t> m_reverseTextureIndexMap; + mutable std::vector<std::vector<char>> colorTextures; + mutable std::vector<std::vector<char>> pickTextures; + std::vector<double> m_specIntegrs; + MantidColorMap m_colorMap; + +public: + InstrumentRenderer(const InstrumentActor &actor); + ~InstrumentRenderer(); + void renderInstrument(const std::vector<bool> &visibleComps, bool showGuides, + bool picking = false); + void reset(); + + void changeScaleType(int type); + + void changeNthPower(double nth_power); + + void loadColorMap(const QString &fname); + + const MantidColorMap &getColorMap() const { return m_colorMap; } + + GLColor getColor(size_t index) const; + + static GLColor makePickColor(size_t pickID); + + static size_t decodePickColor(const QRgb &c); + +private: + void resetColors(); + void resetPickColors(); + void draw(const std::vector<bool> &visibleComps, bool showGuides, + bool picking); + void drawRectangularBank(size_t bankIndex, bool picking); + void drawStructuredBank(size_t bankIndex, bool picking); + void drawTube(size_t bankIndex, bool picking); + void drawSingleDetector(size_t detIndex, bool picking); + void generateRectangularTexture(std::vector<char> &texture, + const std::vector<GLColor> &colors, + size_t bankIndex); + + void uploadRectangularTexture(const std::vector<char> &texture, + size_t textureIndex) const; + + void generateTubeTexture(std::vector<char> &texture, + const std::vector<GLColor> &colors, + size_t bankIndex); + void uploadTubeTexture(const std::vector<char> &texture, + size_t textureIndex) const; +}; +} // namespace MantidWidgets +} // namespace MantidQt +#endif // INSTRUMENTRENDERER_H_ \ No newline at end of file diff --git a/qt/widgets/instrumentview/src/BankRenderingHelpers.cpp b/qt/widgets/instrumentview/src/BankRenderingHelpers.cpp new file mode 100644 index 00000000000..230864bf005 --- /dev/null +++ b/qt/widgets/instrumentview/src/BankRenderingHelpers.cpp @@ -0,0 +1,170 @@ +#include "MantidQtWidgets/InstrumentView/BankRenderingHelpers.h" +#include "MantidGeometry/Instrument/ComponentInfo.h" +#include "MantidGeometry/Objects/IObject.h" +#include "MantidGeometry/Objects/ShapeFactory.h" +#include "MantidGeometry/Rendering/GeometryHandler.h" +#include "MantidGeometry/Rendering/OpenGL_Headers.h" +#include "MantidGeometry/Rendering/ShapeInfo.h" +#include "MantidKernel/Quat.h" + +namespace { +Mantid::Kernel::Logger g_log("BankRenderingHelpers"); + +// Round a number up to the nearest power of 2 +size_t roundToNearestPowerOfTwo(size_t val) { + size_t rounded = 2; + while (val > rounded) + rounded *= 2; + return rounded; +} + +void addVertex(const Mantid::Geometry::ComponentInfo &compInfo, size_t detIndex, + const Mantid::Kernel::V3D &basePos, double xstep, double ystep) { + auto pos = compInfo.position(detIndex) - basePos; + pos += Mantid::Kernel::V3D(xstep * (+0.5), ystep * (-0.5), + 0.0); // Adjust to account for the size of a pixel + glVertex3f(static_cast<GLfloat>(pos.X()), static_cast<GLfloat>(pos.Y()), + static_cast<GLfloat>(pos.Z())); +} + +void setBankNormal(const Mantid::Kernel::V3D &pos1, + const Mantid::Kernel::V3D &pos2, + const Mantid::Kernel::V3D &basePos) { + // Set the bank normal to facilitate lighting effects + auto vec1 = pos1 - basePos; + auto vec2 = pos2 - basePos; + auto normal = vec1.cross_prod(vec2); + normal.normalize(); + glNormal3f(static_cast<GLfloat>(normal.X()), static_cast<GLfloat>(normal.Y()), + static_cast<GLfloat>(normal.Z())); +} + +void extractHexahedron(const Mantid::Geometry::IObject &shape, + std::vector<Mantid::Kernel::V3D> &hex) { + const auto &shapeInfo = shape.getGeometryHandler()->shapeInfo(); + const auto &points = shapeInfo.points(); + hex.assign(points.begin(), points.begin() + 4); +} + +void rotateHexahedron(std::vector<Mantid::Kernel::V3D> &hex, + const Mantid::Kernel::Quat &rotation) { + for (auto &pos : hex) + rotation.rotate(pos); +} + +void offsetHexahedronPosition(std::vector<Mantid::Kernel::V3D> &hex, + const Mantid::Kernel::V3D &offset) { + for (auto &pos : hex) + pos += offset; +} +} // namespace + +namespace MantidQt { +namespace MantidWidgets { +namespace BankRenderingHelpers { + +std::pair<size_t, size_t> getCorrectedTextureSize(const size_t width, + const size_t height) { + return {roundToNearestPowerOfTwo(width), roundToNearestPowerOfTwo(height)}; +} + +void renderRectangularBank(const Mantid::Geometry::ComponentInfo &compInfo, + size_t index) { + auto bank = compInfo.quadrilateralComponent(index); + auto xstep = (compInfo.position(bank.bottomRight).X() - + compInfo.position(bank.bottomLeft).X()) / + static_cast<double>(bank.nX); + auto ystep = (compInfo.position(bank.topRight).Y() - + compInfo.position(bank.bottomLeft).Y()) / + static_cast<double>(bank.nY); + // Because texture colours are combined with the geometry colour + // make sure the current colour is white + glColor3f(1.0f, 1.0f, 1.0f); + + // Nearest-neighbor scaling + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glEnable(GL_TEXTURE_2D); // enable texture mapping + + size_t texx, texy; + auto res = getCorrectedTextureSize(bank.nX, bank.nY); + texx = res.first; + texy = res.second; + double tex_frac_x = static_cast<double>(bank.nX) / static_cast<double>(texx); + double tex_frac_y = static_cast<double>(bank.nY) / static_cast<double>(texy); + + glBegin(GL_QUADS); + + auto basePos = compInfo.position(bank.bottomLeft); + + // Set the bank normal to facilitate lighting effects + setBankNormal(compInfo.position(bank.bottomRight), + compInfo.position(bank.topLeft), basePos); + + glTexCoord2f(0.0, 0.0); + addVertex(compInfo, bank.bottomLeft, basePos, xstep, ystep); + + glTexCoord2f(static_cast<GLfloat>(tex_frac_x), 0.0); + addVertex(compInfo, bank.bottomRight, basePos, xstep, ystep); + + glTexCoord2f(static_cast<GLfloat>(tex_frac_x), + static_cast<GLfloat>(tex_frac_y)); + addVertex(compInfo, bank.topRight, basePos, xstep, ystep); + + glTexCoord2f(0.0, static_cast<GLfloat>(tex_frac_y)); + addVertex(compInfo, bank.topLeft, basePos, xstep, ystep); + + glEnd(); + + if (glGetError() > 0) + g_log.error() << "OpenGL error in renderRectangularBank() \n"; + + glDisable( + GL_TEXTURE_2D); // stop texture mapping - not sure if this is necessary. +} + +void renderStructuredBank(const Mantid::Geometry::ComponentInfo &compInfo, + size_t index, const std::vector<GLColor> &color) { + glBegin(GL_QUADS); + + const auto &columns = compInfo.children(index); + auto colWidth = (columns.size()) * 3; + auto baseIndex = compInfo.children(columns[0])[0]; + const auto &baseShapeInfo = + compInfo.shape(baseIndex).getGeometryHandler()->shapeInfo(); + auto basePos = baseShapeInfo.points()[0]; + std::vector<Mantid::Kernel::V3D> hex(4); + + setBankNormal(baseShapeInfo.points()[1], baseShapeInfo.points()[3], basePos); + + for (size_t x = 0; x < colWidth; x += 3) { + auto index = x / 3; + const auto &column = compInfo.children(columns[index]); + for (size_t y = 0; y < column.size() - 1; ++y) { + extractHexahedron(compInfo.shape(column[y]), hex); + offsetHexahedronPosition(hex, -basePos); + rotateHexahedron(hex, compInfo.rotation(column[y])); + offsetHexahedronPosition(hex, compInfo.position(column[y])); + + glColor3ub((GLubyte)color[column[y]].red(), + (GLubyte)color[column[y]].green(), + (GLubyte)color[column[y]].blue()); + glVertex3f(static_cast<GLfloat>(hex[0].X()), + static_cast<GLfloat>(hex[0].Y()), 0); + glVertex3f(static_cast<GLfloat>(hex[1].X()), + static_cast<GLfloat>(hex[1].Y()), 0); + glVertex3f(static_cast<GLfloat>(hex[2].X()), + static_cast<GLfloat>(hex[2].Y()), 0); + glVertex3f(static_cast<GLfloat>(hex[3].X()), + static_cast<GLfloat>(hex[3].Y()), 0); + } + } + + glEnd(); + + if (glGetError() > 0) + g_log.error() << "OpenGL error in renderStructuredBank() \n"; +} +} // namespace BankRenderingHelpers +} // namespace MantidWidgets +} // namespace MantidQt \ No newline at end of file diff --git a/qt/widgets/instrumentview/src/InstrumentActor.cpp b/qt/widgets/instrumentview/src/InstrumentActor.cpp index e304b6b59e9..6fa54662145 100644 --- a/qt/widgets/instrumentview/src/InstrumentActor.cpp +++ b/qt/widgets/instrumentview/src/InstrumentActor.cpp @@ -1,5 +1,6 @@ #include "MantidQtWidgets/InstrumentView/InstrumentActor.h" #include "MantidQtWidgets/Common/TSVSerialiser.h" +#include "MantidQtWidgets/InstrumentView/InstrumentRenderer.h" #include "MantidQtWidgets/InstrumentView/OpenGLError.h" #include "MantidAPI/AnalysisDataService.h" @@ -39,17 +40,6 @@ using namespace Mantid; namespace MantidQt { namespace MantidWidgets { namespace { -size_t decodePickColorRGB(unsigned char r, unsigned char g, unsigned char b) { - unsigned int index = r; - index *= 256; - index += g; - index *= 256; - index += b - 1; - return index; -} - -GLColor defaultDetectorColor() { return GLColor(200, 200, 200, 1); } - bool isPhysicalView() { std::string view = Mantid::Kernel::ConfigService::Instance().getString( "instrument.view.geometry"); @@ -83,7 +73,6 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, : m_workspace(AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( wsName.toStdString())), m_ragged(true), m_autoscaling(autoscaling), m_defaultPos(), - m_maskedColor(100, 100, 100), m_failedColor(200, 200, 200), m_isPhysicalInstrument(false) { // settings loadSettings(); @@ -103,13 +92,14 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, } m_isCompVisible.assign(componentInfo().size(), true); - setupPickColors(); + + m_renderer.reset(new InstrumentRenderer(*this)); + m_renderer->changeScaleType(m_scaleType); // set up the color map if (!m_currentColorMapFilename.isEmpty()) { loadColorMap(m_currentColorMapFilename, false); } - m_colorMap.changeScaleType(m_scaleType); // set up data ranges and colours setUpWorkspace(sharedWorkspace, scaleMin, scaleMax); @@ -120,30 +110,12 @@ InstrumentActor::InstrumentActor(const QString &wsName, bool autoscaling, "This instrument appears to contain no detectors", "OK"); } - - if (!m_showGuides) { - // hide guide and other components - showGuides(m_showGuides); - } - - m_displayListId[0] = 0; - m_displayListId[1] = 0; - m_useDisplayList[0] = false; - m_useDisplayList[1] = false; } /** * Destructor */ -InstrumentActor::~InstrumentActor() { - for (size_t i = 0; i < 2; ++i) { - if (m_displayListId[i] != 0) { - glDeleteLists(m_displayListId[i], 1); - } - } - - saveSettings(); -} +InstrumentActor::~InstrumentActor() { saveSettings(); } /** * Set up the workspace: calculate the value ranges, set the colours. @@ -156,36 +128,28 @@ InstrumentActor::~InstrumentActor() { void InstrumentActor::setUpWorkspace( boost::shared_ptr<const Mantid::API::MatrixWorkspace> sharedWorkspace, double scaleMin, double scaleMax) { - - const size_t nHist = sharedWorkspace->getNumberHistograms(); m_WkspBinMinValue = DBL_MAX; m_WkspBinMaxValue = -DBL_MAX; - for (size_t i = 0; i < nHist; ++i) { - const auto &values = sharedWorkspace->x(i); + const auto &spectrumInfo = sharedWorkspace->spectrumInfo(); + m_detIndex2WsIndex.resize(componentInfo().size(), INVALID_INDEX); + for (size_t wi = 0; wi < spectrumInfo.size(); ++wi) { + const auto &values = sharedWorkspace->x(wi); double xtest = values.front(); if (!std::isinf(xtest)) { - if (xtest < m_WkspBinMinValue) { + if (xtest < m_WkspBinMinValue) m_WkspBinMinValue = xtest; - } else if (xtest > m_WkspBinMaxValue) { + else if (xtest > m_WkspBinMaxValue) m_WkspBinMaxValue = xtest; - } else { - } } xtest = values.back(); if (!std::isinf(xtest)) { - if (xtest < m_WkspBinMinValue) { + if (xtest < m_WkspBinMinValue) m_WkspBinMinValue = xtest; - } else if (xtest > m_WkspBinMaxValue) { + else if (xtest > m_WkspBinMaxValue) m_WkspBinMaxValue = xtest; - } else { - } } - } - const auto &spectrumInfo = sharedWorkspace->spectrumInfo(); - m_detIndex2WsIndex.resize(componentInfo().size(), INVALID_INDEX); - for (size_t wi = 0; wi < spectrumInfo.size(); wi++) { const auto &specDef = spectrumInfo.spectrumDefinition(wi); for (auto info : specDef) m_detIndex2WsIndex[info.first] = wi; @@ -196,9 +160,9 @@ void InstrumentActor::setUpWorkspace( m_DataMinValue = -DBL_MAX; m_DataMaxValue = DBL_MAX; - if (!m_autoscaling) { + if (!m_autoscaling) setDataMinMaxRange(scaleMin, scaleMax); - } + setDataIntegrationRange(m_WkspBinMinValue, m_WkspBinMaxValue); resetColors(); @@ -231,7 +195,7 @@ void InstrumentActor::setComponentVisible(size_t componentIndex) { for (auto child : children) m_isCompVisible[child] = true; - invalidateDisplayLists(); + resetColors(); } void InstrumentActor::setChildVisibility(bool on) { @@ -392,7 +356,7 @@ Instrument_const_sptr InstrumentActor::getInstrument() const { } const MantidColorMap &InstrumentActor::getColorMap() const { - return m_colorMap; + return m_renderer->getColorMap(); } size_t InstrumentActor::getDetectorByDetID(Mantid::detid_t detID) const { @@ -643,41 +607,7 @@ void InstrumentActor::sumDetectorsRagged(const std::vector<size_t> &dets, * the masking information in .... */ void InstrumentActor::resetColors() { - QwtDoubleInterval qwtInterval(m_DataMinScaleValue, m_DataMaxScaleValue); - auto sharedWorkspace = getWorkspace(); - const auto &compInfo = componentInfo(); - const auto &detInfo = detectorInfo(); - auto color = m_colorMap.rgb(qwtInterval, 0); - m_colors.assign(compInfo.size(), - GLColor(qRed(color), qGreen(color), qBlue(color), 1)); - auto invalidColor = GLColor(100, 100, 100, 1); - - IMaskWorkspace_sptr mask = getMaskWorkspaceIfExists(); - const auto &detectorIDs = detInfo.detectorIDs(); - for (size_t det = 0; det < detInfo.size(); ++det) { - auto masked = false; - - if (mask) - masked = mask->isMasked(detectorIDs[det]); - if (detInfo.isMasked(det) || masked) - m_colors[det] = m_maskedColor; - else { - auto integratedValue = getIntegratedCounts(det); - if (integratedValue > -1) { - auto color = m_colorMap.rgb(qwtInterval, integratedValue); - m_colors[det] = GLColor( - qRed(color), qGreen(color), qBlue(color), - static_cast<int>(255 * (integratedValue / m_DataMaxScaleValue))); - } else - m_colors[det] = invalidColor; - } - } - - for (auto comp : m_components) - m_colors[comp] = defaultDetectorColor(); - - setupPickColors(); - invalidateDisplayLists(); + m_renderer->reset(); emit colorMapChanged(); } @@ -691,100 +621,26 @@ void InstrumentActor::updateColors() { */ void InstrumentActor::showGuides(bool on) { m_showGuides = on; - invalidateDisplayLists(); + resetColors(); } GLColor InstrumentActor::getColor(size_t index) const { - if (index <= m_colors.size() - 1) - return m_colors.at(index); - - return m_colors.front(); + return m_renderer->getColor(index); } void InstrumentActor::draw(bool picking) const { - if (std::none_of(m_isCompVisible.cbegin(), m_isCompVisible.cend(), - [](bool visible) { return visible; })) - return; - - OpenGLError::check("InstrumentActor::draw(0)"); - size_t i = picking ? 1 : 0; - if (m_useDisplayList[i]) { - glCallList(m_displayListId[i]); - } else { - m_displayListId[i] = glGenLists(1); - m_useDisplayList[i] = true; - glNewList(m_displayListId[i], - GL_COMPILE); // Construct display list for object representation - doDraw(picking); - glEndList(); - if (glGetError() == GL_OUT_OF_MEMORY) // Throw an exception - throw Mantid::Kernel::Exception::OpenGLError( - "OpenGL: Out of video memory"); - glCallList(m_displayListId[i]); - } - OpenGLError::check("InstrumentActor::draw()"); + m_renderer->renderInstrument(m_isCompVisible, m_showGuides, picking); } -void InstrumentActor::doDraw(bool picking) const { - const auto &compInfo = componentInfo(); - for (size_t i = 0; i < compInfo.size(); ++i) { - auto type = compInfo.componentType(i); - if ((!compInfo.isDetector(i) && !m_showGuides) || - type == Beamline::ComponentType::OutlineComposite || - type == Beamline::ComponentType::Infinite) - continue; - - if (compInfo.hasValidShape(i)) { - if (m_isCompVisible[i]) { - if (picking) - m_pickColors[i].paint(); - else - m_colors[i].paint(); - glPushMatrix(); - // Translate - auto pos = compInfo.position(i); - if (!pos.nullVector()) - glTranslated(pos[0], pos[1], pos[2]); - - // Rotate - auto rot = compInfo.rotation(i); - if (!rot.isNull()) { - double deg, ax0, ax1, ax2; - rot.getAngleAxis(deg, ax0, ax1, ax2); - glRotated(deg, ax0, ax1, ax2); - } - - // Scale - auto scale = compInfo.scaleFactor(i); - if (scale != Kernel::V3D(1, 1, 1)) - glScaled(scale[0], scale[1], scale[2]); - - compInfo.shape(i).draw(); - glPopMatrix(); - } - } - } -} /** * @param fname :: A color map file name. * @param reset_colors :: An option to reset the detector colors. */ void InstrumentActor::loadColorMap(const QString &fname, bool reset_colors) { - m_colorMap.loadMap(fname); + m_renderer->loadColorMap(fname); m_currentColorMapFilename = fname; - if (reset_colors) { + if (reset_colors) resetColors(); - } -} - -//------------------------------------------------------------------------------ -void InstrumentActor::setupPickColors() { - const auto &compInfo = componentInfo(); - m_pickColors.resize(compInfo.size()); - - for (size_t i = 0; i < compInfo.size(); ++i) { - m_pickColors[i] = makePickColor(i); - } } //------------------------------------------------------------------------------ @@ -810,12 +666,12 @@ const std::vector<Mantid::detid_t> &InstrumentActor::getAllDetIDs() const { * @param type :: 0 - linear, 1 - log10. */ void InstrumentActor::changeScaleType(int type) { - m_colorMap.changeScaleType(static_cast<GraphOptions::ScaleType>(type)); + m_renderer->changeScaleType(type); resetColors(); } void InstrumentActor::changeNthPower(double nth_power) { - m_colorMap.setNthPower(nth_power); + m_renderer->changeNthPower(nth_power); resetColors(); } @@ -835,7 +691,7 @@ void InstrumentActor::saveSettings() { QSettings settings; settings.beginGroup("Mantid/InstrumentWidget"); settings.setValue("ColormapFile", m_currentColorMapFilename); - settings.setValue("ScaleType", (int)m_colorMap.getScaleType()); + settings.setValue("ScaleType", (int)m_renderer->getColorMap().getScaleType()); settings.setValue("ShowGuides", m_showGuides); settings.endGroup(); } @@ -885,7 +741,6 @@ void InstrumentActor::setAutoscaling(bool on) { if (on) { m_DataMinScaleValue = m_DataMinValue; m_DataMaxScaleValue = m_DataMaxValue; - // setIntegrationRange(m_DataMinValue,m_DataMaxValue); resetColors(); } } @@ -1212,7 +1067,7 @@ void InstrumentActor::addMaskBinsData(const std::vector<size_t> &indices) { auto index = getWorkspaceIndex(det); if (index == INVALID_INDEX) continue; - wsIndices.push_back(index); + wsIndices.emplace_back(index); } if (!indices.empty()) { m_maskBinsData.addXRange(m_BinMinValue, m_BinMaxValue, wsIndices); @@ -1247,7 +1102,7 @@ QString InstrumentActor::getParameterInfo(size_t index) const { mapCmptToNameVector.emplace(paramCompId, std::vector<std::string>()); } // get the vector out and add the name - mapCmptToNameVector[paramCompId].push_back(paramName); + mapCmptToNameVector[paramCompId].emplace_back(paramName); } // walk out from the selected component @@ -1353,30 +1208,5 @@ const Mantid::Geometry::DetectorInfo &InstrumentActor::detectorInfo() const { else return getWorkspace()->detectorInfo(); } - -void InstrumentActor::invalidateDisplayLists() const { - for (size_t i = 0; i < 2; ++i) { - if (m_displayListId[i] != 0) { - glDeleteLists(m_displayListId[i], 1); - m_displayListId[i] = 0; - m_useDisplayList[i] = false; - } - } -} - -GLColor InstrumentActor::makePickColor(size_t pickID) { - pickID += 1; - unsigned char r, g, b; - r = static_cast<unsigned char>(pickID / 65536); - g = static_cast<unsigned char>((pickID % 65536) / 256); - b = static_cast<unsigned char>((pickID % 65536) % 256); - return GLColor(r, g, b); -} - -size_t InstrumentActor::decodePickColor(const QRgb &c) { - return decodePickColorRGB(static_cast<unsigned char>(qRed(c)), - static_cast<unsigned char>(qGreen(c)), - static_cast<unsigned char>(qBlue(c))); -} } // namespace MantidWidgets } // namespace MantidQt diff --git a/qt/widgets/instrumentview/src/InstrumentRenderer.cpp b/qt/widgets/instrumentview/src/InstrumentRenderer.cpp new file mode 100644 index 00000000000..ddebcee92ae --- /dev/null +++ b/qt/widgets/instrumentview/src/InstrumentRenderer.cpp @@ -0,0 +1,436 @@ +#include "MantidQtWidgets/InstrumentView/InstrumentRenderer.h" +#include "MantidAPI/IMaskWorkspace.h" +#include "MantidBeamline/ComponentType.h" +#include "MantidGeometry/Instrument/ComponentInfo.h" +#include "MantidGeometry/Instrument/DetectorInfo.h" +#include "MantidGeometry/Objects/IObject.h" +#include "MantidGeometry/Rendering/GeometryHandler.h" +#include "MantidGeometry/Rendering/ShapeInfo.h" +#include "MantidKernel/Exception.h" +#include "MantidKernel/Quat.h" +#include "MantidQtWidgets/InstrumentView/BankRenderingHelpers.h" +#include "MantidQtWidgets/InstrumentView/InstrumentActor.h" +#include "MantidQtWidgets/InstrumentView/OpenGLError.h" + +using namespace MantidQt::MantidWidgets; + +namespace MantidQt { +namespace MantidWidgets { + +namespace { +size_t decodePickColorRGB(unsigned char r, unsigned char g, unsigned char b) { + unsigned int index = r; + index *= 256; + index += g; + index *= 256; + index += b - 1; + return index; +} + +void updateVisited(std::vector<bool> &visited, + const std::vector<size_t> &components) { + for (auto component : components) + visited[component] = true; +} +} // namespace + +InstrumentRenderer::InstrumentRenderer(const InstrumentActor &actor) + : m_actor(actor) { + + m_displayListId[0] = 0; + m_displayListId[1] = 0; + m_useDisplayList[0] = false; + m_useDisplayList[1] = false; + + const auto &componentInfo = actor.componentInfo(); + size_t numTextures = 0; + for (size_t i = componentInfo.root(); !componentInfo.isDetector(i); --i) { + auto type = componentInfo.componentType(i); + if (type == Mantid::Beamline::ComponentType::Rectangular || + type == Mantid::Beamline::ComponentType::OutlineComposite) { + m_textureIndices.push_back(i); + m_reverseTextureIndexMap[i] = numTextures; + numTextures++; + } + } + + if (numTextures > 0) { + m_textureIDs.resize(numTextures, 0); + colorTextures.resize(numTextures); + pickTextures.resize(numTextures); + } +} + +InstrumentRenderer::~InstrumentRenderer() { + for (size_t i = 0; i < 2; ++i) { + if (m_displayListId[i] != 0) { + glDeleteLists(m_displayListId[i], 1); + } + } +} + +void InstrumentRenderer::renderInstrument(const std::vector<bool> &visibleComps, + bool showGuides, bool picking) { + if (std::none_of(visibleComps.cbegin(), visibleComps.cend(), + [](bool visible) { return visible; })) + return; + + OpenGLError::check("InstrumentActor::draw()"); + size_t i = picking ? 1 : 0; + if (m_useDisplayList[i]) { + glCallList(m_displayListId[i]); + } else { + m_displayListId[i] = glGenLists(1); + m_useDisplayList[i] = true; + glNewList(m_displayListId[i], + GL_COMPILE); // Construct display list for object representation + draw(visibleComps, showGuides, picking); + glEndList(); + if (glGetError() == GL_OUT_OF_MEMORY) // Throw an exception + throw Mantid::Kernel::Exception::OpenGLError( + "OpenGL: Out of video memory"); + glCallList(m_displayListId[i]); + } + OpenGLError::check("InstrumentActor::draw()"); +} + +void InstrumentRenderer::draw(const std::vector<bool> &visibleComps, + bool showGuides, bool picking) { + const auto &compInfo = m_actor.componentInfo(); + std::vector<bool> visited(compInfo.size(), false); + + for (size_t i = compInfo.root(); i != std::numeric_limits<size_t>::max(); + --i) { + auto type = compInfo.componentType(i); + if (type == Mantid::Beamline::ComponentType::Infinite) + continue; + + if (type == Mantid::Beamline::ComponentType::Rectangular) { + updateVisited(visited, compInfo.componentsInSubtree(i)); + if (visibleComps[i]) + drawRectangularBank(i, picking); + continue; + } + + if (type == Mantid::Beamline::ComponentType::OutlineComposite) { + updateVisited(visited, compInfo.componentsInSubtree(i)); + if (visibleComps[i]) + drawTube(i, picking); + continue; + } + + if (type == Mantid::Beamline::ComponentType::Structured) { + updateVisited(visited, compInfo.componentsInSubtree(i)); + if (visibleComps[i]) + drawStructuredBank(i, picking); + continue; + } + + if (!compInfo.isDetector(i) && !showGuides) { + visited[i] = true; + continue; + } + + if (compInfo.hasValidShape(i) && visibleComps[i] && !visited[i]) { + visited[i] = true; + drawSingleDetector(i, picking); + } + } +} + +void InstrumentRenderer::drawRectangularBank(size_t bankIndex, bool picking) { + const auto &compInfo = m_actor.componentInfo(); + glPushMatrix(); + + auto bank = compInfo.quadrilateralComponent(bankIndex); + auto pos = compInfo.position(bank.bottomLeft); + + auto scale = compInfo.scaleFactor(bankIndex); + glTranslated(pos.X(), pos.Y(), pos.Z()); + glScaled(scale[0], scale[1], scale[2]); + + auto ti = m_reverseTextureIndexMap[bankIndex]; + glBindTexture(GL_TEXTURE_2D, m_textureIDs[ti]); + uploadRectangularTexture(picking ? pickTextures[ti] : colorTextures[ti], + bankIndex); + + BankRenderingHelpers::renderRectangularBank(compInfo, bankIndex); + + glBindTexture(GL_TEXTURE_2D, 0); + glPopMatrix(); +} + +void InstrumentRenderer::drawStructuredBank(size_t bankIndex, bool picking) { + const auto &compInfo = m_actor.componentInfo(); + glPushMatrix(); + + auto bank = compInfo.quadrilateralComponent(bankIndex); + const auto &shapeInfo = + compInfo.shape(bank.bottomLeft).getGeometryHandler()->shapeInfo(); + auto pos = shapeInfo.points()[0]; + pos.setZ(compInfo.position(bank.bottomLeft).Z()); + auto scale = compInfo.scaleFactor(bankIndex); + glTranslated(pos.X(), pos.Y(), pos.Z()); + glScaled(scale[0], scale[1], scale[2]); + + BankRenderingHelpers::renderStructuredBank(compInfo, bankIndex, + picking ? m_pickColors : m_colors); + + glPopMatrix(); +} + +void InstrumentRenderer::drawTube(size_t bankIndex, bool picking) { + const auto &compInfo = m_actor.componentInfo(); + glPushMatrix(); + + auto pos = compInfo.position(bankIndex); + auto rot = compInfo.rotation(bankIndex); + auto scale = compInfo.scaleFactor(bankIndex); + glTranslated(pos.X(), pos.Y(), pos.Z()); + glScaled(scale[0], scale[1], scale[2]); + double deg, ax0, ax1, ax2; + rot.getAngleAxis(deg, ax0, ax1, ax2); + glRotated(deg, ax0, ax1, ax2); + + auto ti = m_reverseTextureIndexMap[bankIndex]; + glColor3f(1.0f, 1.0f, 1.0f); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, m_textureIDs[ti]); + uploadTubeTexture(picking ? pickTextures[ti] : colorTextures[ti], bankIndex); + + compInfo.shape(bankIndex).draw(); + + glBindTexture(GL_TEXTURE_2D, 0); + glPopMatrix(); +} + +void InstrumentRenderer::drawSingleDetector(size_t detIndex, bool picking) { + const auto &compInfo = m_actor.componentInfo(); + if (picking) + m_pickColors[detIndex].paint(); + else + m_colors[detIndex].paint(); + glPushMatrix(); + // Translate + auto pos = compInfo.position(detIndex); + if (!pos.nullVector()) + glTranslated(pos[0], pos[1], pos[2]); + + // Rotate + auto rot = compInfo.rotation(detIndex); + if (!rot.isNull()) { + double deg, ax0, ax1, ax2; + rot.getAngleAxis(deg, ax0, ax1, ax2); + glRotated(deg, ax0, ax1, ax2); + } + + // Scale + auto scale = compInfo.scaleFactor(detIndex); + if (scale != Mantid::Kernel::V3D(1, 1, 1)) + glScaled(scale[0], scale[1], scale[2]); + + compInfo.shape(detIndex).draw(); + glPopMatrix(); +} + +void InstrumentRenderer::reset() { + resetColors(); + resetPickColors(); + + if (m_textureIDs.size() > 0) { + const auto &compInfo = m_actor.componentInfo(); + for (size_t i = 0; i < m_textureIDs.size(); i++) { + auto type = compInfo.componentType(m_textureIndices[i]); + + if (type == Mantid::Beamline::ComponentType::Rectangular) { + generateRectangularTexture(colorTextures[i], m_colors, + m_textureIndices[i]); + generateRectangularTexture(pickTextures[i], m_pickColors, + m_textureIndices[i]); + } else if (type == Mantid::Beamline::ComponentType::OutlineComposite) { + generateTubeTexture(colorTextures[i], m_colors, m_textureIndices[i]); + generateTubeTexture(pickTextures[i], m_pickColors, m_textureIndices[i]); + } + } + } + + /// Invalidate the OpenGL display lists to force full re-drawing of the + /// instrument and creation of new lists. + for (size_t i = 0; i < 2; ++i) { + if (m_displayListId[i] != 0) { + glDeleteLists(m_displayListId[i], 1); + m_displayListId[i] = 0; + m_useDisplayList[i] = false; + } + } +} + +void InstrumentRenderer::resetColors() { + QwtDoubleInterval qwtInterval(m_actor.minValue(), m_actor.maxValue()); + auto sharedWorkspace = m_actor.getWorkspace(); + const auto &compInfo = m_actor.componentInfo(); + const auto &detInfo = m_actor.detectorInfo(); + auto color = m_colorMap.rgb(qwtInterval, 0); + m_colors.assign(compInfo.size(), + GLColor(qRed(color), qGreen(color), qBlue(color), 1)); + auto invalidColor = GLColor(80, 80, 80, 1); + auto maskedColor = GLColor(100, 100, 100, 1); + + Mantid::API::IMaskWorkspace_sptr mask = m_actor.getMaskWorkspaceIfExists(); + const auto &detectorIDs = detInfo.detectorIDs(); + for (size_t det = 0; det < detInfo.size(); ++det) { + auto masked = false; + + if (mask) + masked = mask->isMasked(detectorIDs[det]); + if (detInfo.isMasked(det) || masked) + m_colors[det] = maskedColor; + else { + auto integratedValue = m_actor.getIntegratedCounts(det); + if (integratedValue > -1) { + auto color = m_colorMap.rgb(qwtInterval, integratedValue); + m_colors[det] = GLColor( + qRed(color), qGreen(color), qBlue(color), + static_cast<int>(255 * (integratedValue / m_actor.maxValue()))); + } else + m_colors[det] = invalidColor; + } + } + + for (const auto comp : m_actor.components()) + m_colors[comp] = maskedColor; +} + +void InstrumentRenderer::resetPickColors() { + const auto &compInfo = m_actor.componentInfo(); + m_pickColors.resize(compInfo.size()); + + for (size_t i = 0; i < compInfo.size(); ++i) { + m_pickColors[i] = makePickColor(i); + } +} + +void InstrumentRenderer::changeScaleType(int type) { + m_colorMap.changeScaleType(static_cast<GraphOptions::ScaleType>(type)); +} + +void InstrumentRenderer::changeNthPower(double nth_power) { + m_colorMap.setNthPower(nth_power); +} + +GLColor InstrumentRenderer::getColor(size_t index) const { + if (index <= m_colors.size() - 1) + return m_colors.at(index); + + return m_colors.front(); +} + +GLColor InstrumentRenderer::makePickColor(size_t pickID) { + pickID += 1; + unsigned char r, g, b; + r = static_cast<unsigned char>(pickID / 65536); + g = static_cast<unsigned char>((pickID % 65536) / 256); + b = static_cast<unsigned char>((pickID % 65536) % 256); + return GLColor(r, g, b); +} + +size_t InstrumentRenderer::decodePickColor(const QRgb &c) { + return decodePickColorRGB(static_cast<unsigned char>(qRed(c)), + static_cast<unsigned char>(qGreen(c)), + static_cast<unsigned char>(qBlue(c))); +} + +void InstrumentRenderer::loadColorMap(const QString &fname) { + m_colorMap.loadMap(fname); +} + +void InstrumentRenderer::generateRectangularTexture( + std::vector<char> &texture, const std::vector<GLColor> &colors, + size_t bankIndex) { + const auto &compInfo = m_actor.componentInfo(); + auto bank = compInfo.quadrilateralComponent(bankIndex); + // Round size up to nearest power of 2 + auto res = BankRenderingHelpers::getCorrectedTextureSize(bank.nX, bank.nY); + auto texSizeX = res.first; + auto texSizeY = res.second; + + // Texture width is 3 times wider due to RGB values + texture.resize(texSizeX * texSizeY * 3, 0); // fill with black + + const auto &children = compInfo.children(bankIndex); + auto colWidth = children.size() * 3; + for (size_t x = 0; x < colWidth; x += 3) { + const auto &dets = compInfo.detectorsInSubtree(children[x / 3]); + for (size_t y = 0; y < dets.size(); ++y) { + auto det = dets[y]; + auto ti = (y * texSizeX * 3) + x; + texture[ti] = static_cast<char>(colors[det].red()); + texture[ti + 1] = static_cast<char>(colors[det].green()); + texture[ti + 2] = static_cast<char>(colors[det].blue()); + } + } +} + +void InstrumentRenderer::generateTubeTexture(std::vector<char> &texture, + const std::vector<GLColor> &colors, + size_t bankIndex) { + const auto &compInfo = m_actor.componentInfo(); + const auto &children = compInfo.children(bankIndex); + texture.resize(children.size() * 3); + + for (size_t i = 0; i < children.size(); ++i) { + auto col = colors[children[i]]; + auto pos = i * 3; + texture[pos] = static_cast<unsigned char>(col.red()); + texture[pos + 1] = static_cast<unsigned char>(col.green()); + texture[pos + 2] = static_cast<unsigned char>(col.blue()); + } +} + +void InstrumentRenderer::uploadRectangularTexture( + const std::vector<char> &texture, size_t textureIndex) const { + auto bank = m_actor.componentInfo().quadrilateralComponent(textureIndex); + auto res = BankRenderingHelpers::getCorrectedTextureSize(bank.nX, bank.nY); + auto xsize = res.first; + auto ysize = res.second; + + auto ti = m_reverseTextureIndexMap[textureIndex]; + if (m_textureIDs[ti] != 0) + glDeleteTextures(1, &m_textureIDs[ti]); + + glGenTextures(1, &m_textureIDs[ti]); + glBindTexture(GL_TEXTURE_2D, m_textureIDs[ti]); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + // Allow lighting effects + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, static_cast<GLsizei>(xsize), + static_cast<GLsizei>(ysize), 0, GL_RGB, GL_UNSIGNED_BYTE, + texture.data()); +} + +void InstrumentRenderer::uploadTubeTexture(const std::vector<char> &texture, + size_t textureIndex) const { + auto ti = m_reverseTextureIndexMap[textureIndex]; + if (m_textureIDs[ti] > 0) + glDeleteTextures(1, &m_textureIDs[ti]); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &m_textureIDs[ti]); + glBindTexture(GL_TEXTURE_2D, m_textureIDs[ti]); + + glTexImage2D(GL_TEXTURE_2D, 0, 3, 1, static_cast<GLsizei>(texture.size() / 3), + 0, GL_RGB, GL_UNSIGNED_BYTE, texture.data()); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +} + +} // namespace MantidWidgets +} // namespace MantidQt \ No newline at end of file diff --git a/qt/widgets/instrumentview/src/Projection3D.cpp b/qt/widgets/instrumentview/src/Projection3D.cpp index 206d9454024..d0bb629aa76 100644 --- a/qt/widgets/instrumentview/src/Projection3D.cpp +++ b/qt/widgets/instrumentview/src/Projection3D.cpp @@ -48,7 +48,6 @@ Projection3D::Projection3D(const InstrumentActor *rootActor, int winWidth, m_viewport.setProjection(minBounds, maxBounds); changeColorMap(); - rootActor->invalidateDisplayLists(); // create and connect the move input controller InputController3DMove *moveController = new InputController3DMove(this); diff --git a/qt/widgets/instrumentview/src/ProjectionSurface.cpp b/qt/widgets/instrumentview/src/ProjectionSurface.cpp index 696596f889e..3d1b1eb45b3 100644 --- a/qt/widgets/instrumentview/src/ProjectionSurface.cpp +++ b/qt/widgets/instrumentview/src/ProjectionSurface.cpp @@ -1,9 +1,10 @@ #include "MantidQtWidgets/InstrumentView/ProjectionSurface.h" #include "MantidQtWidgets/Common/InputController.h" +#include "MantidQtWidgets/Common/TSVSerialiser.h" #include "MantidQtWidgets/InstrumentView/GLColor.h" +#include "MantidQtWidgets/InstrumentView/InstrumentRenderer.h" #include "MantidQtWidgets/InstrumentView/MantidGLWidget.h" #include "MantidQtWidgets/InstrumentView/OpenGLError.h" -#include "MantidQtWidgets/Common/TSVSerialiser.h" #include "MantidAPI/Axis.h" #include "MantidAPI/IPeaksWorkspace.h" @@ -498,7 +499,7 @@ size_t ProjectionSurface::getPickID(int x, int y) const { if (!m_pickImage || !m_pickImage->valid(x, y)) return -1; QRgb pixel = m_pickImage->pixel(x, y); - return InstrumentActor::decodePickColor(pixel); + return InstrumentRenderer::decodePickColor(pixel); } /** diff --git a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp index 4cef31e6c1b..2e4efc1da70 100644 --- a/qt/widgets/instrumentview/src/UnwrappedSurface.cpp +++ b/qt/widgets/instrumentview/src/UnwrappedSurface.cpp @@ -1,5 +1,6 @@ #include "MantidQtWidgets/InstrumentView/UnwrappedSurface.h" #include "MantidQtWidgets/InstrumentView/GLColor.h" +#include "MantidQtWidgets/InstrumentView/InstrumentRenderer.h" #include "MantidQtWidgets/InstrumentView/MantidGLWidget.h" #include "MantidQtWidgets/InstrumentView/OpenGLError.h" #include "MantidQtWidgets/InstrumentView/PeakMarker2D.h" @@ -205,7 +206,7 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget, bool picking) const { */ void UnwrappedSurface::setColor(size_t index, bool picking) const { if (picking) { - auto c = InstrumentActor::makePickColor(index); + auto c = InstrumentRenderer::makePickColor(index); unsigned char r, g, b; c.get(r, g, b); glColor3ub(r, g, b); @@ -459,7 +460,7 @@ void UnwrappedSurface::drawSimpleToImage(QImage *image, bool picking) const { QColor color; int index = int(i); if (picking) { - GLColor c = InstrumentActor::makePickColor(index); + GLColor c = InstrumentRenderer::makePickColor(index); unsigned char r, g, b; c.get(r, g, b); color = QColor(r, g, b); diff --git a/qt/widgets/legacyqwt/inc/MantidQtWidgets/LegacyQwt/SignalRange.h b/qt/widgets/legacyqwt/inc/MantidQtWidgets/LegacyQwt/SignalRange.h index a505acc0a86..79cd4629b55 100644 --- a/qt/widgets/legacyqwt/inc/MantidQtWidgets/LegacyQwt/SignalRange.h +++ b/qt/widgets/legacyqwt/inc/MantidQtWidgets/LegacyQwt/SignalRange.h @@ -54,8 +54,8 @@ private: Mantid::Geometry::MDImplicitFunction *function); /// Get the range of signal, in parallel, given an iterator - QwtDoubleInterval - getRange(const std::vector<Mantid::API::IMDIterator *> &iterators); + QwtDoubleInterval getRange( + const std::vector<std::unique_ptr<Mantid::API::IMDIterator>> &iterators); /// Get the range of signal given an iterator QwtDoubleInterval getRange(Mantid::API::IMDIterator *it); diff --git a/qt/widgets/legacyqwt/src/SignalRange.cpp b/qt/widgets/legacyqwt/src/SignalRange.cpp index 62dc0730485..b1e9d8c4c25 100644 --- a/qt/widgets/legacyqwt/src/SignalRange.cpp +++ b/qt/widgets/legacyqwt/src/SignalRange.cpp @@ -65,12 +65,12 @@ void SignalRange::findFullRange( * @return the min/max range, or 0-1.0 if not found */ QwtDoubleInterval SignalRange::getRange( - const std::vector<Mantid::API::IMDIterator *> &iterators) { + const std::vector<std::unique_ptr<Mantid::API::IMDIterator>> &iterators) { std::vector<QwtDoubleInterval> intervals(iterators.size()); // cppcheck-suppress syntaxError PRAGMA_OMP( parallel for schedule(dynamic, 1)) for (int i = 0; i < int(iterators.size()); i++) { - Mantid::API::IMDIterator *it = iterators[i]; + auto it = iterators[i].get(); intervals[i] = this->getRange(it); // don't delete iterator in parallel. MSVC doesn't like it // when the iterator points to a mock object. @@ -80,8 +80,6 @@ QwtDoubleInterval SignalRange::getRange( double minSignal = DBL_MAX; double maxSignal = -DBL_MAX; for (size_t i = 0; i < iterators.size(); i++) { - delete iterators[i]; - double signal; signal = intervals[i].minValue(); if (!std::isfinite(signal)) diff --git a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h index d294d2cb368..4d41a695fbd 100644 --- a/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h +++ b/qt/widgets/sliceviewer/inc/MantidQtWidgets/SliceViewer/QPeaksTableModel.h @@ -116,6 +116,8 @@ public: static const QString QLAB; /// Label for Q-vector in the sample column static const QString QSAMPLE; + /// Label for Q-vector in the peak number column + static const QString PEAKNUM; private: /// Find the correct column name for this column index @@ -161,6 +163,8 @@ private: static const int COL_QLAB; /// Index for Q-vector in the sample column static const int COL_QSAMPLE; + /// Unique peak number + static const int COL_PEAKNUM; /// The number of digits past the decimal to display in the table int m_hklPrec; /// Map from column index to raw peak data diff --git a/qt/widgets/sliceviewer/src/QPeaksTableModel.cpp b/qt/widgets/sliceviewer/src/QPeaksTableModel.cpp index 966a4b29409..9ca18beb52f 100644 --- a/qt/widgets/sliceviewer/src/QPeaksTableModel.cpp +++ b/qt/widgets/sliceviewer/src/QPeaksTableModel.cpp @@ -62,6 +62,7 @@ const QString QPeaksTableModel::ROW("Row"); const QString QPeaksTableModel::COL("Col"); const QString QPeaksTableModel::QLAB = "QLab"; const QString QPeaksTableModel::QSAMPLE = "QSample"; +const QString QPeaksTableModel::PEAKNUM = "PeakNumber"; const int QPeaksTableModel::COL_RUNNUMBER(0); const int QPeaksTableModel::COL_DETID(1); @@ -83,6 +84,7 @@ const int QPeaksTableModel::COL_ROW(16); const int QPeaksTableModel::COL_COL(17); const int QPeaksTableModel::COL_QLAB(18); const int QPeaksTableModel::COL_QSAMPLE(19); +const int QPeaksTableModel::COL_PEAKNUM(20); /** * @param column The column to get the number of characters @@ -132,6 +134,8 @@ int QPeaksTableModel::numCharacters(const int column) const { return 3 * 6; else if (column == COL_QSAMPLE) return 3 * 6; + else if (column == COL_PEAKNUM) + return 6; else return 3; } @@ -162,7 +166,8 @@ QPeaksTableModel::QPeaksTableModel( {16, ROW}, {17, COL}, {18, QLAB}, - {19, QSAMPLE}}; + {19, QSAMPLE}, + {20, PEAKNUM}}; m_hklPrec = getHKLPrecision(); @@ -193,6 +198,7 @@ QPeaksTableModel::QPeaksTableModel( [](const IPeak &peak) { return QVariant(peak.getCol()); }, [](const IPeak &peak) { return QVariant(peak.getQLabFrame().norm()); }, [](const IPeak &peak) { return QVariant(peak.getQSampleFrame().norm()); }, + [](const IPeak &peak) { return QVariant(int(peak.getPeakNumber())); }, }; // Mapping member functions of the Peak object to a column index with @@ -244,6 +250,7 @@ QPeaksTableModel::QPeaksTableModel( [](const IPeak &peak) { return QString::number(peak.getCol()); }, [](const IPeak &peak) { return v3dAsString(peak.getQLabFrame()); }, [](const IPeak &peak) { return v3dAsString(peak.getQSampleFrame()); }, + [](const IPeak &peak) { return QString::number(peak.getPeakNumber()); }, }; } diff --git a/scripts/ExternalInterfaces/CMakeLists.txt b/scripts/ExternalInterfaces/CMakeLists.txt index 49b608f4bbd..9f8cee956a2 100644 --- a/scripts/ExternalInterfaces/CMakeLists.txt +++ b/scripts/ExternalInterfaces/CMakeLists.txt @@ -6,7 +6,7 @@ set ( _mslice_external_root ${CMAKE_CURRENT_BINARY_DIR}/mslice ) ExternalProject_Add ( mslice PREFIX ${_mslice_external_root} GIT_REPOSITORY "https://github.com/mantidproject/mslice.git" - GIT_TAG 560cc9351596b0078b201b9e1785e3c5a745f375 + GIT_TAG 01292c88ccc508acb16735aa5f96450e076161bb EXCLUDE_FROM_ALL 1 CONFIGURE_COMMAND "" diff --git a/scripts/Inelastic/CrystalField/fitting.py b/scripts/Inelastic/CrystalField/fitting.py index f07526d4cfd..91f1a34f1a7 100644 --- a/scripts/Inelastic/CrystalField/fitting.py +++ b/scripts/Inelastic/CrystalField/fitting.py @@ -327,7 +327,10 @@ class CrystalField(object): return out def makeMultiSpectrumFunction(self): - return re.sub(r'FWHM[X|Y]\d+=\(\),', '', str(self.function)) + fun = re.sub(r'FWHM[X|Y]\d+=\(\),', '', str(self.function)) + fun = re.sub(r'(name=.*?,)(.*?)(Temperatures=\(.*?\),)',r'\1\3\2', fun) + fun = re.sub(r'(name=.*?,)(.*?)(PhysicalProperties=\(.*?\),)',r'\1\3\2', fun) + return fun @property def Ion(self): @@ -1319,8 +1322,6 @@ class CrystalFieldFit(object): """ from mantid.api import AlgorithmManager fun = self.model.makeMultiSpectrumFunction() - if 'CrystalFieldMultiSpectrum' in fun: - fun = re.sub(r'(name=.*?,)(.*?)(PhysicalProperties=\(.*?\),)',r'\1\3\2', fun) alg = AlgorithmManager.createUnmanaged('EstimateFitParameters') alg.initialize() alg.setProperty('Function', fun) @@ -1375,8 +1376,6 @@ class CrystalFieldFit(object): fun = str(self.model.function) else: fun = self.model.makeMultiSpectrumFunction() - if 'CrystalFieldMultiSpectrum' in fun: - fun = re.sub(r'(name=.*?,)(.*?)(PhysicalProperties=\(.*?\),)',r'\1\3\2', fun) alg = AlgorithmManager.createUnmanaged('Fit') alg.initialize() alg.setProperty('Function', fun) diff --git a/scripts/Inelastic/CrystalField/function.py b/scripts/Inelastic/CrystalField/function.py index c92547e806a..38813e9d020 100644 --- a/scripts/Inelastic/CrystalField/function.py +++ b/scripts/Inelastic/CrystalField/function.py @@ -364,6 +364,10 @@ class ResolutionModel: self.model = [self._makeModel(m, xstart, xend, accuracy) for m in model] self.multi = True return + elif hasattr(model[0], 'model'): + self.model = [m.model for m in model] + self.multi = True + return elif isinstance(model[0], tuple): for m in model: self._checkModel(m) diff --git a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_script.py b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_script.py index ea3a3918235..38e32a99e77 100644 --- a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_script.py +++ b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_script.py @@ -1,8 +1,6 @@ -#pylint: disable=R0902, W0221, W0621 """ - Classes for each reduction step. Those are kept separately - from the the interface class so that the HFIRReduction class could - be used independently of the interface implementation + Legacy class that old LR reduction options. + This is still in use for backward compatibility. """ from __future__ import (absolute_import, division, print_function) import xml.dom.minidom @@ -77,62 +75,13 @@ class DataSets(BaseScriptElement): super(DataSets, self).__init__() self.reset() +#pylint: disable = unused-argument, arguments-differ def to_script(self, for_automated_reduction=False): """ Generate reduction script @param execute: if true, the script will be executed """ - -# if for_automated_reduction: -# script = "RefLReduction(RunNumbers=[%s],\n" % ','.join([str(i) for i in self.data_files]) -# else: -# script = "RefLReduction(RunNumbers=[int(%s)],\n" % str(self.data_files[0]) - script = "RefLReduction(RunNumbers=[%s],\n" % ','.join([str(i) for i in self.data_files]) - script += " NormalizationRunNumber=%d,\n" % self.norm_file - script += " SignalPeakPixelRange=%s,\n" % str(self.DataPeakPixels) - script += " SubtractSignalBackground=%s,\n" % str(self.DataBackgroundFlag) - script += " SignalBackgroundPixelRange=%s,\n" % str(self.DataBackgroundRoi[:2]) - script += " NormFlag=%s,\n" % str(self.NormFlag) - script += " NormPeakPixelRange=%s,\n" % str(self.NormPeakPixels) - script += " NormBackgroundPixelRange=%s,\n" % str(self.NormBackgroundRoi) - script += " SubtractNormBackground=%s,\n" % str(self.NormBackgroundFlag) - script += " LowResDataAxisPixelRangeFlag=%s,\n" % str(self.data_x_range_flag) - script += " LowResDataAxisPixelRange=%s,\n" % str(self.data_x_range) - script += " LowResNormAxisPixelRangeFlag=%s,\n" % str(self.norm_x_range_flag) - script += " LowResNormAxisPixelRange=%s,\n" % str(self.norm_x_range) - script += " TOFRange=%s,\n" % str(self.DataTofRange) - - _incident_medium_str = str(self.incident_medium_list[0]) - _list = _incident_medium_str.split(',') - - script += " IncidentMediumSelected='%s',\n" % str(_list[self.incident_medium_index_selected]) - script += " GeometryCorrectionFlag=%s,\n" % str(self.geometry_correction_switch) - script += " QMin=%s,\n" % str(self.q_min) - script += " QStep=%s,\n" % str(self.q_step) - - # Angle offset - if self.angle_offset != 0.0: - script += " AngleOffset=%s,\n" % str(self.angle_offset) - script += " AngleOffsetError=%s,\n" % str(self.angle_offset_error) - - # sf configuration file -# if self.scaling_factor_file != '': - if self.scaling_factor_file_flag: - script += "ScalingFactorFile='%s',\n" % str(self.scaling_factor_file) - else: - script += "ScalingFactorFile='',\n" - - script += "SlitsWidthFlag=%s,\n" % str(self.slits_width_flag) - - # The output should be slightly different if we are generating - # a script for the automated reduction - if for_automated_reduction: - script += " OutputWorkspace='reflectivity_'+%s)" % str(self.data_files[0]) - else: - script += " OutputWorkspace='reflectivity_%s')" % str(self.data_files[0]) - script += "\n" - - return script + raise RuntimeError("refl_data_script.DataSets.to_script is deprecated") def update(self): """ @@ -144,75 +93,75 @@ class DataSets(BaseScriptElement): """ Create XML from the current data. """ - xml = "<RefLData>\n" - xml += "<peak_selection_type>%s</peak_selection_type>\n" % self.DataPeakSelectionType - xml += "<from_peak_pixels>%s</from_peak_pixels>\n" % str(self.DataPeakPixels[0]) - xml += "<to_peak_pixels>%s</to_peak_pixels>\n" % str(self.DataPeakPixels[1]) - xml += "<peak_discrete_selection>%s</peak_discrete_selection>\n" % self.DataPeakDiscreteSelection - xml += "<background_flag>%s</background_flag>\n" % str(self.DataBackgroundFlag) - xml += "<back_roi1_from>%s</back_roi1_from>\n" % str(self.DataBackgroundRoi[0]) - xml += "<back_roi1_to>%s</back_roi1_to>\n" % str(self.DataBackgroundRoi[1]) - xml += "<back_roi2_from>%s</back_roi2_from>\n" % str(self.DataBackgroundRoi[2]) - xml += "<back_roi2_to>%s</back_roi2_to>\n" % str(self.DataBackgroundRoi[3]) - xml += "<tof_range_flag>%s</tof_range_flag>\n" % str(self.TofRangeFlag) - xml += "<from_tof_range>%s</from_tof_range>\n" % str(self.DataTofRange[0]) - xml += "<to_tof_range>%s</to_tof_range>\n" % str(self.DataTofRange[1]) - xml += "<data_sets>%s</data_sets>\n" % ','.join([str(i) for i in self.data_files]) - xml += "<x_min_pixel>%s</x_min_pixel>\n" % str(self.data_x_range[0]) - xml += "<x_max_pixel>%s</x_max_pixel>\n" % str(self.data_x_range[1]) - xml += "<x_range_flag>%s</x_range_flag>\n" % str(self.data_x_range_flag) - - xml += "<tthd_value>%s</tthd_value>\n" % str(self.tthd_value) - xml += "<ths_value>%s</ths_value>\n" % str(self.ths_value) - - xml += "<norm_flag>%s</norm_flag>\n" % str(self.NormFlag) - xml += "<norm_x_range_flag>%s</norm_x_range_flag>\n" % str(self.norm_x_range_flag) - xml += "<norm_x_max>%s</norm_x_max>\n" % str(self.norm_x_range[1]) - xml += "<norm_x_min>%s</norm_x_min>\n" % str(self.norm_x_range[0]) - - xml += "<norm_from_peak_pixels>%s</norm_from_peak_pixels>\n" % str(self.NormPeakPixels[0]) - xml += "<norm_to_peak_pixels>%s</norm_to_peak_pixels>\n" % str(self.NormPeakPixels[1]) - xml += "<norm_background_flag>%s</norm_background_flag>\n" % str(self.NormBackgroundFlag) - xml += "<norm_from_back_pixels>%s</norm_from_back_pixels>\n" % str(self.NormBackgroundRoi[0]) - xml += "<norm_to_back_pixels>%s</norm_to_back_pixels>\n" % str(self.NormBackgroundRoi[1]) - xml += "<norm_dataset>%s</norm_dataset>\n" % str(self.norm_file) + _xml = "<RefLData>\n" + _xml += "<peak_selection_type>%s</peak_selection_type>\n" % self.DataPeakSelectionType + _xml += "<from_peak_pixels>%s</from_peak_pixels>\n" % str(self.DataPeakPixels[0]) + _xml += "<to_peak_pixels>%s</to_peak_pixels>\n" % str(self.DataPeakPixels[1]) + _xml += "<peak_discrete_selection>%s</peak_discrete_selection>\n" % self.DataPeakDiscreteSelection + _xml += "<background_flag>%s</background_flag>\n" % str(self.DataBackgroundFlag) + _xml += "<back_roi1_from>%s</back_roi1_from>\n" % str(self.DataBackgroundRoi[0]) + _xml += "<back_roi1_to>%s</back_roi1_to>\n" % str(self.DataBackgroundRoi[1]) + _xml += "<back_roi2_from>%s</back_roi2_from>\n" % str(self.DataBackgroundRoi[2]) + _xml += "<back_roi2_to>%s</back_roi2_to>\n" % str(self.DataBackgroundRoi[3]) + _xml += "<tof_range_flag>%s</tof_range_flag>\n" % str(self.TofRangeFlag) + _xml += "<from_tof_range>%s</from_tof_range>\n" % str(self.DataTofRange[0]) + _xml += "<to_tof_range>%s</to_tof_range>\n" % str(self.DataTofRange[1]) + _xml += "<data_sets>%s</data_sets>\n" % ','.join([str(i) for i in self.data_files]) + _xml += "<x_min_pixel>%s</x_min_pixel>\n" % str(self.data_x_range[0]) + _xml += "<x_max_pixel>%s</x_max_pixel>\n" % str(self.data_x_range[1]) + _xml += "<x_range_flag>%s</x_range_flag>\n" % str(self.data_x_range_flag) + + _xml += "<tthd_value>%s</tthd_value>\n" % str(self.tthd_value) + _xml += "<ths_value>%s</ths_value>\n" % str(self.ths_value) + + _xml += "<norm_flag>%s</norm_flag>\n" % str(self.NormFlag) + _xml += "<norm_x_range_flag>%s</norm_x_range_flag>\n" % str(self.norm_x_range_flag) + _xml += "<norm_x_max>%s</norm_x_max>\n" % str(self.norm_x_range[1]) + _xml += "<norm_x_min>%s</norm_x_min>\n" % str(self.norm_x_range[0]) + + _xml += "<norm_from_peak_pixels>%s</norm_from_peak_pixels>\n" % str(self.NormPeakPixels[0]) + _xml += "<norm_to_peak_pixels>%s</norm_to_peak_pixels>\n" % str(self.NormPeakPixels[1]) + _xml += "<norm_background_flag>%s</norm_background_flag>\n" % str(self.NormBackgroundFlag) + _xml += "<norm_from_back_pixels>%s</norm_from_back_pixels>\n" % str(self.NormBackgroundRoi[0]) + _xml += "<norm_to_back_pixels>%s</norm_to_back_pixels>\n" % str(self.NormBackgroundRoi[1]) + _xml += "<norm_dataset>%s</norm_dataset>\n" % str(self.norm_file) # Q cut - xml += "<q_min>%s</q_min>\n" % str(self.q_min) - xml += "<q_step>%s</q_step>\n" % str(self.q_step) - xml += "<auto_q_binning>%s</auto_q_binning>\n" % str(self.auto_q_binning) - xml += "<overlap_lowest_error>%s</overlap_lowest_error>\n" % str(self.overlap_lowest_error) - xml += "<overlap_mean_value>%s</overlap_mean_value>\n" % str(self.overlap_mean_value) + _xml += "<q_min>%s</q_min>\n" % str(self.q_min) + _xml += "<q_step>%s</q_step>\n" % str(self.q_step) + _xml += "<auto_q_binning>%s</auto_q_binning>\n" % str(self.auto_q_binning) + _xml += "<overlap_lowest_error>%s</overlap_lowest_error>\n" % str(self.overlap_lowest_error) + _xml += "<overlap_mean_value>%s</overlap_mean_value>\n" % str(self.overlap_mean_value) # Angle offset - xml += "<angle_offset>%s</angle_offset>\n" % str(self.angle_offset) - xml += "<angle_offset_error>%s</angle_offset_error>\n" % str(self.angle_offset_error) + _xml += "<angle_offset>%s</angle_offset>\n" % str(self.angle_offset) + _xml += "<angle_offset_error>%s</angle_offset_error>\n" % str(self.angle_offset_error) # scaling factor file name - xml += "<scaling_factor_flag>%s</scaling_factor_flag>\n" % str(self.scaling_factor_file_flag) - xml += "<scaling_factor_file>%s</scaling_factor_file>\n" % str(self.scaling_factor_file) - xml += "<slits_width_flag>%s</slits_width_flag>\n" % str(self.slits_width_flag) + _xml += "<scaling_factor_flag>%s</scaling_factor_flag>\n" % str(self.scaling_factor_file_flag) + _xml += "<scaling_factor_file>%s</scaling_factor_file>\n" % str(self.scaling_factor_file) + _xml += "<slits_width_flag>%s</slits_width_flag>\n" % str(self.slits_width_flag) # geometry correction - xml += "<geometry_correction_switch>%s</geometry_correction_switch>\n" % str(self.geometry_correction_switch) + _xml += "<geometry_correction_switch>%s</geometry_correction_switch>\n" % str(self.geometry_correction_switch) #incident medium - xml += "<incident_medium_list>%s</incident_medium_list>\n" % str(self.incident_medium_list[0]) - xml += "<incident_medium_index_selected>%s</incident_medium_index_selected>\n" % str(self.incident_medium_index_selected) + _xml += "<incident_medium_list>%s</incident_medium_list>\n" % str(self.incident_medium_list[0]) + _xml += "<incident_medium_index_selected>%s</incident_medium_index_selected>\n" % str(self.incident_medium_index_selected) #fourth column precision - xml += "<fourth_column_flag>%s</fourth_column_flag>\n" % str(self.fourth_column_flag) - xml += "<fourth_column_dq0>%s</fourth_column_dq0>\n" % str(self.fourth_column_dq0) - xml += "<fourth_column_dq_over_q>%s</fourth_column_dq_over_q>\n" % str(self.fourth_column_dq_over_q) + _xml += "<fourth_column_flag>%s</fourth_column_flag>\n" % str(self.fourth_column_flag) + _xml += "<fourth_column_dq0>%s</fourth_column_dq0>\n" % str(self.fourth_column_dq0) + _xml += "<fourth_column_dq_over_q>%s</fourth_column_dq_over_q>\n" % str(self.fourth_column_dq_over_q) # Primary fraction if self.clocking_from is not None and self.clocking_to is not None: - xml += "<clocking_from>%s</clocking_from>\n" % str(self.clocking_from) - xml += "<clocking_to>%s</clocking_to>\n" % str(self.clocking_to) + _xml += "<clocking_from>%s</clocking_from>\n" % str(self.clocking_from) + _xml += "<clocking_to>%s</clocking_to>\n" % str(self.clocking_to) - xml += "</RefLData>\n" + _xml += "</RefLData>\n" - return xml + return _xml def from_xml(self, xml_str): self.reset() diff --git a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_series.py b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_series.py index 7061a8ec7e6..224d72ce088 100644 --- a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_series.py +++ b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_data_series.py @@ -7,7 +7,6 @@ from __future__ import (absolute_import, division, print_function) import xml.dom.minidom from reduction_gui.reduction.scripter import BaseScriptElement from reduction_gui.reduction.reflectometer.refl_data_script import DataSets as REFLDataSets -from reduction_gui.reduction.reflectometer.refm_data_script import DataSets as REFMDataSets class DataSeries(BaseScriptElement): @@ -24,18 +23,7 @@ class DataSeries(BaseScriptElement): Generate reduction script @param execute: if true, the script will be executed """ - script = "import os\n" - script += "import time\n" - script += "t0=time.time()\n" - script += "from reduction.command_interface import ReductionSingleton\n" - script += "ReductionSingleton.clean()\n" - - for item in self.data_sets: - script += item.to_script() - script += "\n" - script += "print \"Reduction time: %g\\n\" % (time.time()-t0)\n" - - return script + raise RuntimeError("refl_data_series.DataSeries.to_script is deprecated") def update(self): """ @@ -47,12 +35,12 @@ class DataSeries(BaseScriptElement): """ Create XML from the current data. """ - xml = "<DataSeries>\n" + _xml = "<DataSeries>\n" for item in self.data_sets: - xml += item.to_xml() - xml += "</DataSeries>\n" + _xml += item.to_xml() + _xml += "</DataSeries>\n" - return xml + return _xml def from_xml(self, xml_str): """ @@ -70,9 +58,6 @@ class DataSeries(BaseScriptElement): element_list = dom.getElementsByTagName("Data") if len(element_list)==0: element_list = dom.getElementsByTagName("RefLData") - if len(element_list)==0: - self._data_class = REFMDataSets - element_list = dom.getElementsByTagName("RefMData") if len(element_list)>0: for item in element_list: diff --git a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_reduction.py b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_reduction.py deleted file mode 100644 index 83201441fcc..00000000000 --- a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_reduction.py +++ /dev/null @@ -1,51 +0,0 @@ -#pylint: disable = invalid-name -""" - This class holds all the necessary information to create a reduction script. -""" -from __future__ import (absolute_import, division, print_function) -import time -from reduction_gui.reduction.scripter import BaseReductionScripter - - -class REFLReductionScripter(BaseReductionScripter): - """ - Reduction scripter for REFL - """ - - def __init__(self, name="REFL"): - super(REFLReductionScripter, self).__init__(name=name) - - def to_script(self, file_name=None): - """ - Spits out the text of a reduction script with the current state. - @param file_name: name of the file to write the script to - """ - """ - Spits out the text of a reduction script with the current state. - @param file_name: name of the file to write the script to - """ - script = "# %s reduction script\n" % self.instrument_name - script += "# Script automatically generated on %s\n\n" % time.ctime(time.time()) - - script += "import mantid\n" - script += "from mantid.simpleapi import *\n" - script += "\n" - script += "#remove all previous workspaces\n" - script += "list_mt = AnalysisDataService.getObjectNames()\n" - script += "for _mt in list_mt:\n" - script += " if _mt.find('_scaled') != -1:\n" - script += " AnalysisDataService.remove(_mt)\n" - script += " if _mt.find('reflectivity') != -1:\n" - script += " AnalysisDataService.remove(_mt)\n" - script += "\n" - - for item in self._observers: - if item.state() is not None: - script += str(item.state()) - - if file_name is not None: - f = open(file_name, 'w') - f.write(script) - f.close() - - return script diff --git a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator.py b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator.py deleted file mode 100644 index e7edad83b8f..00000000000 --- a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator.py +++ /dev/null @@ -1,179 +0,0 @@ -from __future__ import (absolute_import, division, print_function) - -# pylint: disable=invalid-name -""" - This class holds all the necessary information to create a reduction script. - This is a fake version of the Reducer for testing purposes. -""" -import time -from reduction_gui.reduction.scripter import BaseReductionScripter -import sys - -# Check whether Mantid is available -try: - import mantidplot # noqa - - HAS_MANTID = True -except: - HAS_MANTID = False - - -class REFLSFCalculatorScripter(BaseReductionScripter): - """ - Organizes the set of reduction parameters that will be used to - create a reduction script. Parameters are organized by groups that - will each have their own UI representation. - """ - - def __init__(self, name="REFL"): - super(REFLSFCalculatorScripter, self).__init__(name=name) - - def create_script(self, script_part2): - """ - This creates the special script for the sfCalculator algorithm - """ - algo = 'sfCalculator.calculate' - - script_split = script_part2.split('\n') - - run_number = [] - attenuator = [] - - peak_from = [] - peak_to = [] - back_from = [] - back_to = [] - - tof_range = [0.0, 200000.0] - incident_medium = '' - incident_medium_index = -1 - - scaling_factor_file = '' - - for _line in script_split: - if _line != '': - _line_split = _line.split(':') - _arg = _line_split[0] - _val = _line_split[1] - - if _arg == 'Scaling factor file' and scaling_factor_file == '': - scaling_factor_file = _val.strip() - - elif _arg == 'Run number': - run_number.append(_val) - - elif _arg == 'TOF from' and tof_range[0] == 0.0: - tof_range[0] = float(_val) - - elif _arg == 'TOF to' and tof_range[1] == 200000.0: - tof_range[1] = float(_val) - - elif _arg == 'Incident medium' and incident_medium.strip() == '': - incident_medium = _val[4:-3] - - elif _arg == 'Incident medium index' and incident_medium_index == -1: - incident_medium_index = int(_val) - - elif _arg == 'Number of attenuator': - attenuator.append(_val) - - elif _arg == 'Peak from pixel': - peak_from.append(_val) - - elif _arg == 'Peak to pixel': - peak_to.append(_val) - - elif _arg == 'Back from pixel': - back_from.append(_val) - - elif _arg == 'Back to pixel': - back_to.append(_val) - - run_attenuator = [run.strip() + ":" + att.strip() for (run, att) in zip(run_number, attenuator)] - join_string = ',' - script_run_attenuator = join_string.join(run_attenuator) - - list_peak_back = [[int(pixel) for pixel in line] for line in zip(peak_from, peak_to, back_from, back_to)] - - new_script = algo + '(string_runs="' + script_run_attenuator + '"' - new_script += ',list_peak_back=' + str(list_peak_back) - - # retrieve right incident medium - - incident_medium_list = incident_medium.split(',') - incident_medium = incident_medium_list[incident_medium_index] - new_script += ',incident_medium="' + incident_medium.strip() + '"' - - new_script += ',output_file_name="' + scaling_factor_file + '"' - - new_script += ',tof_range=' + str(tof_range) + ')' - - if scaling_factor_file == '': - return '' - - return new_script - - def to_script(self, file_name=None): - """ - Spits out the text of a reduction script with the current state. - @param file_name: name of the file to write the script to - """ - script = "# %s scaling factor calculation script\n" % self.instrument_name - script += "# Script automatically generated on %s\n\n" % time.ctime(time.time()) - - script += "import os\n" - script += "import mantid\n" - script += "from mantid.simpleapi import *\n" - script += "import sfCalculator\n" - - script += "REF_RED_OUTPUT_MESSAGE = ''\n\n" - - script_part2 = '' - for item in self._observers: - if item.state() is not None: - script_part2 += str(item.state()) - - _script = self.create_script(script_part2) - if _script == '': - print('Please define a Scaling Factor File Name') - raise RuntimeError - - script += _script - - if file_name is not None: - f = open(file_name, 'w') - f.write(script) - f.close() - - return script - - def apply(self): - """ - Apply the reduction process - """ - if HAS_MANTID: - script = self.to_script(None) - - print(script) - - try: - t0 = time.time() - exec (script) - delta_t = time.time() - t0 - print("SF calculation time: %5.2g sec" % delta_t) - # Update scripter - for item in self._observers: - if item.state() is not None: - item.state().update() - except: - # Update scripter [Duplicated code because we can't use 'finally' on python 2.4] - for item in self._observers: - if item.state() is not None: - # Things might be broken, so update what we can - try: - item.state().update() - except: - pass - raise RuntimeError(sys.exc_info()[1]) - else: - raise RuntimeError("SF calculation could not be executed: Mantid could not be imported") diff --git a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator_data_script.py b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator_data_script.py deleted file mode 100644 index 5f617c48111..00000000000 --- a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator_data_script.py +++ /dev/null @@ -1,150 +0,0 @@ -""" - Classes for each reduction step. Those are kept separately - from the the interface class so that the HFIRReduction class could - be used independently of the interface implementation -""" -from __future__ import (absolute_import, division, print_function) -import xml.dom.minidom -from reduction_gui.reduction.scripter import BaseScriptElement - - -class DataSets(BaseScriptElement): - - data_file = 0 - incident_medium_list = ['H2O'] - incident_medium_index_selected = 0 - number_attenuator = 0 - peak_selection = [0, 0] - back_selection = [0, 0] - lambda_requested = 'N/A' - s1h = 'N/A' - s2h = 'N/A' - s1w = 'N/A' - s2w = 'N/A' - scaling_factor_file = '' - tof_min = 0. - tof_max = 200000. - - def __init__(self): - super(DataSets, self).__init__() - self.reset() - - def to_script(self): - """ - Generate reduction script - @param execute: if true, the script will be executed - """ - script = 'Run number: %s \n' % str(self.data_file) - -# _u_list = self.incident_medium_list -# _list = str(_u_list[0]).split(',') - - script += 'Incident medium: %s \n' % str(self.incident_medium_list) -# script += 'Incident medium: %s \n' % str(self.incident_medium_list[self.incident_medium_index_selected]) -# script += 'Incident medium: %s \n' % str(_list[self.incident_medium_index_selected]) - script += 'Incident medium index: %s \n' % str(self.incident_medium_index_selected) - script += 'TOF from: %s \n' % str(self.tof_min) - script += 'TOF to: %s \n' % str(self.tof_max) - script += 'Scaling factor file: %s \n' % str(self.scaling_factor_file) - script += 'Number of attenuator: %s \n' % str(self.number_attenuator) - script += 'Peak from pixel: %s \n' % str(self.peak_selection[0]) - script += 'Peak to pixel: %s \n' % str(self.peak_selection[1]) - script += 'Back from pixel: %s \n' % str(self.back_selection[0]) - script += 'Back to pixel: %s \n' % str(self.back_selection[1]) - - return script - - def update(self): - """ - Update transmission from reduction output - """ - pass - - def to_xml(self): - """ - Create XML from the current data. - """ - xml = "<RefLSFCalculator>\n" -# xml += "<incident_medium_list>%s</incident_medium_list>\n" % ','.join([str(i) for i in self.incident_medium_list]) - xml += "<incident_medium_list>%s</incident_medium_list>\n" % str(self.incident_medium_list[0]) - xml += "<tof_min>%s</tof_min>\n" % str(self.tof_min) - xml += "<tof_max>%s</tof_max>\n" % str(self.tof_max) - xml += "<incident_medium_index_selected>%s</incident_medium_index_selected>\n" % str(self.incident_medium_index_selected) - xml += "<data_file>%s</data_file>\n" % str(self.data_file) - xml += "<number_attenuator>%s</number_attenuator>\n" % str(self.number_attenuator) - xml += "<peak_selection_from_pixel>%s</peak_selection_from_pixel>\n" % str(self.peak_selection[0]) - xml += "<peak_selection_to_pixel>%s</peak_selection_to_pixel>\n" % str(self.peak_selection[1]) - xml += "<back_selection_from_pixel>%s</back_selection_from_pixel>\n" % str(self.back_selection[0]) - xml += "<back_selection_to_pixel>%s</back_selection_to_pixel>\n" % str(self.back_selection[1]) - xml += "<lambda_requested>%s</lambda_requested>\n" % str(self.lambda_requested) - xml += "<s1h>%s</s1h>\n" % str(self.s1h) - xml += "<s2h>%s</s2h>\n" % str(self.s2h) - xml += "<s1w>%s</s1w>\n" % str(self.s1w) - xml += "<s2w>%s</s2w>\n" % str(self.s2w) - xml += "<scaling_factor_file>%s</scaling_factor_file>\n" % str(self.scaling_factor_file) - xml += "</RefLSFCalculator>\n" - - return xml - - def from_xml(self, xml_str): - self.reset() - dom = xml.dom.minidom.parseString(xml_str) - self.from_xml_element(dom) - dom.getElementsByTagName("RefLSFCalculator") - - def from_xml_element(self, instrument_dom): - """ - Read in data from XML - @param xml_str: text to read the data from - """ - # incident medium - self.incident_medium_list = BaseScriptElement.getStringList(instrument_dom, "incident_medium_list") - self.incident_medium_index_selected = BaseScriptElement.getIntElement(instrument_dom, "incident_medium_index_selected") - - self.tof_min = BaseScriptElement.getFloatElement(instrument_dom, "tof_min") - self.tof_max = BaseScriptElement.getFloatElement(instrument_dom, "tof_max") - - # run number - self.data_file = BaseScriptElement.getIntElement(instrument_dom, "data_file") - - # number of attenuator - self.number_attenuator = BaseScriptElement.getIntElement(instrument_dom, "number_attenuator") - - # peak selection from and to - self.peak_selection = [BaseScriptElement.getIntElement(instrument_dom, "peak_selection_from_pixel"), - BaseScriptElement.getIntElement(instrument_dom, "peak_selection_to_pixel")] - - # background flag and selection from and to - self.back_selection = [BaseScriptElement.getIntElement(instrument_dom, "back_selection_from_pixel"), - BaseScriptElement.getIntElement(instrument_dom, "back_selection_to_pixel")] - - # lambda requested - self.lambda_requested = BaseScriptElement.getStringElement(instrument_dom, "lambda_requested") - - # s1h, s2h, s1w, s2w - self.s1h = BaseScriptElement.getStringElement(instrument_dom, "s1h") - self.s2h = BaseScriptElement.getStringElement(instrument_dom, "s2h") - self.s1w = BaseScriptElement.getStringElement(instrument_dom, "s1w") - self.s2w = BaseScriptElement.getStringElement(instrument_dom, "s2w") - - # scaling factor file - self.scaling_factor_file = BaseScriptElement.getStringElement(instrument_dom, "scaling_factor_file") - - def reset(self): - """ - Reset state - """ - self.data_file = DataSets.data_file - self.incident_medium_list = DataSets.incident_medium_list - self.incident_medium_index_selected = DataSets.incident_medium_index_selected - self.number_attenuator = DataSets.number_attenuator - self.peak_selection = DataSets.peak_selection - self.back_selection = DataSets.back_selection - self.lambda_requested = DataSets.lambda_requested - self.s1h = DataSets.s1h - self.s2h = DataSets.s2h - self.s1w = DataSets.s1w - self.s2w = DataSets.s2w - self.tof_min = DataSets.tof_min - self.tof_max = DataSets.tof_max - self.scaling_factor_file = DataSets.scaling_factor_file diff --git a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator_data_series.py b/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator_data_series.py deleted file mode 100644 index 170889b7b4e..00000000000 --- a/scripts/Interface/reduction_gui/reduction/reflectometer/refl_sf_calculator_data_series.py +++ /dev/null @@ -1,82 +0,0 @@ -""" - Classes for each reduction step. Those are kept separately - from the the interface class so that the HFIRReduction class could - be used independently of the interface implementation -""" -from __future__ import (absolute_import, division, print_function) -import xml.dom.minidom -from reduction_gui.reduction.scripter import BaseScriptElement -from reduction_gui.reduction.reflectometer.refl_sf_calculator_data_script import DataSets as REFLDataSets - - -class DataSeries(BaseScriptElement): - - data_sets = [] - - def __init__(self, data_class=REFLDataSets): - super(DataSeries, self).__init__() - self._data_class = data_class - self.reset() - - def to_script(self): - """ - Generate reduction script - @param execute: if true, the script will be executed - """ - script = "" - for item in self.data_sets: - script += item.to_script() - script += "\n" - - return script - - def update(self): - """ - Update transmission from reduction output - """ - pass - - def to_xml(self): - """ - Create XML from the current data. - """ - - xml = "<DataSeries>\n" - for item in self.data_sets: - xml += item.to_xml() - xml += "</DataSeries>\n" - - return xml - - def from_xml(self, xml_str): - """ - Read in data from XML - @param xml_str: text to read the data from - """ - self.reset() - self.data_sets = [] - dom = xml.dom.minidom.parseString(xml_str) - -# # Get Mantid version -# mtd_version = BaseScriptElement.getMantidBuildVersion(dom) - - self._data_class = REFLDataSets - element_list = dom.getElementsByTagName("Data") - if len(element_list)==0: - element_list = dom.getElementsByTagName("RefLSFCalculator") - - if len(element_list)>0: - for item in element_list: - if item is not None: - data_set = self._data_class() - data_set.from_xml_element(item) - self.data_sets.append(data_set) - - if len(self.data_sets)==0: - self.data_sets = [self._data_class()] - - def reset(self): - """ - Reset state - """ - self.data_sets = [self._data_class()] diff --git a/scripts/Interface/reduction_gui/reduction/reflectometer/refm_data_script.py b/scripts/Interface/reduction_gui/reduction/reflectometer/refm_data_script.py deleted file mode 100644 index 4918bb40022..00000000000 --- a/scripts/Interface/reduction_gui/reduction/reflectometer/refm_data_script.py +++ /dev/null @@ -1,381 +0,0 @@ -""" - Reduction script for REFM -""" -from __future__ import (absolute_import, division, print_function) -import xml.dom.minidom -import os -from reduction_gui.reduction.scripter import BaseScriptElement - - -class DataSets(BaseScriptElement): - - DataPeakPixels = [215, 225] - DataBackgroundFlag = False - DataBackgroundRoi = [115, 137, 123, 137] - DataTofRange = [10700., 24500.] - crop_TOF_range = True - TOFstep = 400.0 - - data_x_range_flag = False - data_x_range = [115, 210] - - norm_x_range_flag = False - norm_x_range = [90, 160] - - NormFlag = True - NormPeakPixels = [120, 130] - NormBackgroundFlag = False - NormBackgroundRoi = [115, 137] - - # Data files - data_files = [0] - norm_file = 0 - - # Q range - q_min = 0.0025 - q_step = -0.01 - q_bins = 40 - q_log = True - - # scattering angle - theta = 0.0 - use_center_pixel = True - - # Sample log overwrites - set_detector_angle = False - detector_angle = 0.0 - set_detector_angle_offset = False - detector_angle_offset = 0.0 - set_direct_pixel = False - direct_pixel = 0.0 - - output_dir = '' - - def __init__(self): - super(DataSets, self).__init__() - self.reset() - - def to_script(self, for_automated_reduction=False): - """ - Generate reduction script - @param execute: if true, the script will be executed - """ - if for_automated_reduction: - return self._automated_reduction() - - script = "import mantid\n" - script += "from mantid.api import *\n" - script += "from mantid.kernel import *\n" - script += "from mantid.simpleapi import *\n" - - script = "a = RefReduction(DataRun='%s',\n" % ','.join([str(i) for i in self.data_files]) - script += " NormalizationRun='%s',\n" % str(self.norm_file) - script += " Instrument='REF_M',\n" - script += " PolarizedData=True,\n" - - script += " SignalPeakPixelRange=%s,\n" % str(self.DataPeakPixels) - script += " SubtractSignalBackground=%s,\n" % str(self.DataBackgroundFlag) - script += " SignalBackgroundPixelRange=%s,\n" % str(self.DataBackgroundRoi[:2]) - script += " PerformNormalization=%s,\n" % str(self.NormFlag) - script += " NormPeakPixelRange=%s,\n" % str(self.NormPeakPixels) - script += " NormBackgroundPixelRange=%s,\n" % str(self.NormBackgroundRoi) - script += " SubtractNormBackground=%s,\n" % str(self.NormBackgroundFlag) - - script += " CropLowResDataAxis=%s,\n" % str(self.data_x_range_flag) - if self.data_x_range_flag: - script += " LowResDataAxisPixelRange=%s,\n" % str(self.data_x_range) - - script += " CropLowResNormAxis=%s,\n" % str(self.norm_x_range_flag) - if self.norm_x_range_flag: - script += " LowResNormAxisPixelRange=%s,\n" % str(self.norm_x_range) - - if self.crop_TOF_range: - script += " TOFMin=%s,\n" % str(self.DataTofRange[0]) - script += " TOFMax=%s,\n" % str(self.DataTofRange[1]) - script += " TOFStep=%s,\n" % str(self.TOFstep) - else: - script += " NBins=%s,\n" % str(self.q_bins) - - # Scattering angle options - if self.use_center_pixel: - if self.set_detector_angle: - script += " DetectorAngle=%s,\n" % str(self.detector_angle) - if self.set_detector_angle_offset: - script += " DetectorAngle0=%s,\n" % str(self.detector_angle_offset) - if self.set_direct_pixel: - script += " DirectPixel=%s,\n" % str(self.direct_pixel) - - else: - script += " Theta=%s,\n" % str(self.theta) - - # The output should be slightly different if we are generating - # a script for the automated reduction - basename = os.path.basename(str(self.data_files[0])) - script += " OutputWorkspacePrefix='reflectivity_%s')\n" % basename - script += "\n" - - # Store the log output so it can be shown in the UI - script += "from reduction_workflow.command_interface import ReductionSingleton\n" - script += "reducer_log = ReductionSingleton()\n" - script += "output_log = 'Please make sure the new-style Python API is turned ON by default\\n'\n" - script += "output_log += 'In MantiPlot, go in View > Preferences > Mantid > Options '\n" - script += "output_log += 'and check the appropriate box at the bottom.'\n" - script += "for item in a:\n" - script += " if type(item)==str: output_log = item\n" - script += "reducer_log.log_text += output_log\n\n" - - # Save the reduced data - script += "ws_list = ['reflectivity_%s-Off_Off',\n" % basename - script += " 'reflectivity_%s-On_Off',\n" % basename - script += " 'reflectivity_%s-Off_On',\n" % basename - script += " 'reflectivity_%s-On_On']\n" % basename - - script += "outdir = '%s'\n" % self.output_dir - script += "if not os.path.isdir(outdir):\n" - script += " outdir = os.path.expanduser('~')\n\n" - - script += "for ws in ws_list:\n" - script += " if AnalysisDataService.doesExist(ws):\n" - script += " outpath = os.path.join(outdir, ws+'.txt')\n" - script += " SaveAscii(Filename=outpath, InputWorkspace=ws, Separator='Space')\n\n" - - return script - - def _automated_reduction(self): - script = "# REF_M automated reduction\n" - script += "RefReduction(DataRun='%s',\n" % ','.join([str(i) for i in self.data_files]) - script += " NormalizationRun='%s',\n" % str(self.norm_file) - script += " Instrument='REF_M',\n" - script += " PolarizedData=True,\n" - script += " SignalPeakPixelRange=%s,\n" % str(self.DataPeakPixels) - script += " SubtractSignalBackground=False,\n" - script += " PerformNormalization=%s,\n" % str(self.NormFlag) - script += " NormPeakPixelRange=%s,\n" % str(self.NormPeakPixels) - script += " SubtractNormBackground=False,\n" - - script += " CropLowResDataAxis=%s,\n" % str(self.data_x_range_flag) - if self.data_x_range_flag: - script += " LowResDataAxisPixelRange=%s,\n" % str(self.data_x_range) - - script += " CropLowResNormAxis=%s,\n" % str(self.norm_x_range_flag) - if self.norm_x_range_flag: - script += " LowResNormAxisPixelRange=%s,\n" % str(self.norm_x_range) - - # The output should be slightly different if we are generating - # a script for the automated reduction - basename = os.path.basename(str(self.data_files[0])) - script += " OutputWorkspacePrefix='reflectivity_'+%s)\n" % basename - - return script - - def update(self): - """ - Update transmission from reduction output - """ - pass - - def to_xml(self): - """ - Create XML from the current data. - """ - xml = "<RefMData>\n" - xml += "<from_peak_pixels>%s</from_peak_pixels>\n" % str(self.DataPeakPixels[0]) - xml += "<to_peak_pixels>%s</to_peak_pixels>\n" % str(self.DataPeakPixels[1]) - xml += "<background_flag>%s</background_flag>\n" % str(self.DataBackgroundFlag) - xml += "<back_roi1_from>%s</back_roi1_from>\n" % str(self.DataBackgroundRoi[0]) - xml += "<back_roi1_to>%s</back_roi1_to>\n" % str(self.DataBackgroundRoi[1]) - xml += "<back_roi2_from>%s</back_roi2_from>\n" % str(self.DataBackgroundRoi[2]) - xml += "<back_roi2_to>%s</back_roi2_to>\n" % str(self.DataBackgroundRoi[3]) - xml += "<crop_tof>%s</crop_tof>\n" % str(self.crop_TOF_range) - xml += "<from_tof_range>%s</from_tof_range>\n" % str(self.DataTofRange[0]) - xml += "<to_tof_range>%s</to_tof_range>\n" % str(self.DataTofRange[1]) - xml += "<tof_step>%s</tof_step>\n" % str(self.TOFstep) - xml += "<data_sets>%s</data_sets>\n" % ','.join([str(i) for i in self.data_files]) - xml += "<x_min_pixel>%s</x_min_pixel>\n" % str(self.data_x_range[0]) - xml += "<x_max_pixel>%s</x_max_pixel>\n" % str(self.data_x_range[1]) - xml += "<x_range_flag>%s</x_range_flag>\n" % str(self.data_x_range_flag) - - xml += "<norm_flag>%s</norm_flag>\n" % str(self.NormFlag) - xml += "<norm_x_range_flag>%s</norm_x_range_flag>\n" % str(self.norm_x_range_flag) - xml += "<norm_x_max>%s</norm_x_max>\n" % str(self.norm_x_range[1]) - xml += "<norm_x_min>%s</norm_x_min>\n" % str(self.norm_x_range[0]) - - xml += "<norm_from_peak_pixels>%s</norm_from_peak_pixels>\n" % str(self.NormPeakPixels[0]) - xml += "<norm_to_peak_pixels>%s</norm_to_peak_pixels>\n" % str(self.NormPeakPixels[1]) - xml += "<norm_background_flag>%s</norm_background_flag>\n" % str(self.NormBackgroundFlag) - xml += "<norm_from_back_pixels>%s</norm_from_back_pixels>\n" % str(self.NormBackgroundRoi[0]) - xml += "<norm_to_back_pixels>%s</norm_to_back_pixels>\n" % str(self.NormBackgroundRoi[1]) - xml += "<norm_dataset>%s</norm_dataset>\n" % str(self.norm_file) - - # Q cut - xml += "<q_min>%s</q_min>\n" % str(self.q_min) - xml += "<q_step>%s</q_step>\n" % str(self.q_step) - xml += "<q_bins>%s</q_bins>\n" % str(self.q_bins) - xml += "<q_log>%s</q_log>\n" % str(self.q_log) - - # Scattering angle - xml += "<theta>%s</theta>\n" % str(self.theta) - xml += "<use_center_pixel>%s</use_center_pixel>\n" % str(self.use_center_pixel) - - # Sample log overwrites - xml += "<set_detector_angle>%s</set_detector_angle>\n" % str(self.set_detector_angle) - xml += "<detector_angle>%s</detector_angle>\n" % str(self.detector_angle) - xml += "<set_detector_angle_offset>%s</set_detector_angle_offset>\n" % str(self.set_detector_angle_offset) - xml += "<detector_angle_offset>%s</detector_angle_offset>\n" % str(self.detector_angle_offset) - xml += "<set_direct_pixel>%s</set_direct_pixel>\n" % str(self.set_direct_pixel) - xml += "<direct_pixel>%s</direct_pixel>\n" % str(self.direct_pixel) - - xml += "<output_dir>%s</output_dir>\n" % str(self.output_dir) - - xml += "</RefMData>\n" - - return xml - - def from_xml(self, xml_str): - self.reset() - dom = xml.dom.minidom.parseString(xml_str) - self.from_xml_element(dom) - dom.getElementsByTagName("RefMData") - - def from_xml_element(self, instrument_dom): - """ - Read in data from XML - @param xml_str: text to read the data from - """ - # Peak from/to pixels - self.DataPeakPixels = [BaseScriptElement.getIntElement(instrument_dom, "from_peak_pixels"), - BaseScriptElement.getIntElement(instrument_dom, "to_peak_pixels")] - - # low resolution range - self.data_x_range_flag = BaseScriptElement.getBoolElement(instrument_dom, "x_range_flag", - default=DataSets.data_x_range_flag) - - self.data_x_range = [BaseScriptElement.getIntElement(instrument_dom, "x_min_pixel"), - BaseScriptElement.getIntElement(instrument_dom, "x_max_pixel")] - - self.norm_x_range_flag = BaseScriptElement.getBoolElement(instrument_dom, "norm_x_range_flag", - default=DataSets.norm_x_range_flag) - - self.norm_x_range = [BaseScriptElement.getIntElement(instrument_dom, "norm_x_min"), - BaseScriptElement.getIntElement(instrument_dom, "norm_x_max")] - - # discrete selection string - self.DataPeakDiscreteSelection = BaseScriptElement.getStringElement(instrument_dom, "peak_discrete_selection") - - # background flag - self.DataBackgroundFlag = BaseScriptElement.getBoolElement(instrument_dom, - "background_flag", - default=DataSets.DataBackgroundFlag) - - # background from/to pixels - self.DataBackgroundRoi = [BaseScriptElement.getIntElement(instrument_dom, "back_roi1_from"), - BaseScriptElement.getIntElement(instrument_dom, "back_roi1_to"), - BaseScriptElement.getIntElement(instrument_dom, "back_roi2_from"), - BaseScriptElement.getIntElement(instrument_dom, "back_roi2_to")] - - # from TOF and to TOF - # self.crop_TOF_range = BaseScriptElement.getBoolElement(instrument_dom, "crop_tof", - # default=DataSets.crop_TOF_range) - self.DataTofRange = [BaseScriptElement.getFloatElement(instrument_dom, "from_tof_range"), - BaseScriptElement.getFloatElement(instrument_dom, "to_tof_range")] - self.TOFstep = BaseScriptElement.getFloatElement(instrument_dom, "tof_step", - default=DataSets.TOFstep) - - self.data_files = BaseScriptElement.getStringList(instrument_dom, "data_sets") - - # with or without norm - self.NormFlag = BaseScriptElement.getBoolElement(instrument_dom, "norm_flag", - default=DataSets.NormFlag) - - # Peak from/to pixels - self.NormPeakPixels = [BaseScriptElement.getIntElement(instrument_dom, "norm_from_peak_pixels"), - BaseScriptElement.getIntElement(instrument_dom, "norm_to_peak_pixels")] - - # background flag - self.NormBackgroundFlag = BaseScriptElement.getBoolElement(instrument_dom, - "norm_background_flag", - default=DataSets.NormBackgroundFlag) - - # background from/to pixels - self.NormBackgroundRoi = [BaseScriptElement.getIntElement(instrument_dom, "norm_from_back_pixels"), - BaseScriptElement.getIntElement(instrument_dom, "norm_to_back_pixels")] - - self.norm_file = BaseScriptElement.getStringElement(instrument_dom, "norm_dataset") - - # Q cut - self.q_min = BaseScriptElement.getFloatElement(instrument_dom, "q_min", default=DataSets.q_min) - self.q_step = BaseScriptElement.getFloatElement(instrument_dom, "q_step", default=DataSets.q_step) - self.q_bins = BaseScriptElement.getIntElement(instrument_dom, "q_bins", default=DataSets.q_bins) - self.q_log = BaseScriptElement.getBoolElement(instrument_dom, "q_log", default=DataSets.q_log) - - # scattering angle - self.theta = BaseScriptElement.getFloatElement(instrument_dom, "theta", default=DataSets.theta) - # self.use_center_pixel = BaseScriptElement.getBoolElement(instrument_dom, - # "use_center_pixel", - # default=DataSets.use_center_pixel) - - # Sample log overwrites - self.set_detector_angle = BaseScriptElement.getBoolElement(instrument_dom, - "set_detector_angle", - default=DataSets.set_detector_angle) - self.detector_angle = BaseScriptElement.getFloatElement(instrument_dom, - "detector_angle", - default=DataSets.detector_angle) - self.set_detector_angle_offset = BaseScriptElement.getBoolElement(instrument_dom, - "set_detector_angle_offset", - default=DataSets.set_detector_angle_offset) - self.detector_angle_offset = BaseScriptElement.getFloatElement(instrument_dom, - "detector_angle_offset", - default=DataSets.detector_angle_offset) - self.set_direct_pixel = BaseScriptElement.getBoolElement(instrument_dom, - "set_direct_pixel", - default=DataSets.set_direct_pixel) - self.direct_pixel = BaseScriptElement.getFloatElement(instrument_dom, - "direct_pixel", - default=DataSets.direct_pixel) - - self.output_dir = BaseScriptElement.getStringElement(instrument_dom, - "output_dir", - default=DataSets.output_dir) - - def reset(self): - """ - Reset state - """ - self.DataBackgroundFlag = DataSets.DataBackgroundFlag - self.DataBackgroundRoi = DataSets.DataBackgroundRoi - self.DataPeakPixels = DataSets.DataPeakPixels - self.DataTofRange = DataSets.DataTofRange - self.TOFstep = DataSets.TOFstep - self.crop_TOF_range = DataSets.crop_TOF_range - self.data_files = DataSets.data_files - - self.NormFlag = DataSets.NormFlag - self.NormBackgroundFlag = DataSets.NormBackgroundFlag - self.NormBackgroundRoi = DataSets.NormBackgroundRoi - self.NormPeakPixels = DataSets.NormPeakPixels - self.norm_file = DataSets.norm_file - self.data_x_range_flag = DataSets.data_x_range_flag - self.data_x_range = DataSets.data_x_range - self.norm_x_range_flag = DataSets.norm_x_range_flag - self.norm_x_range = DataSets.norm_x_range - - # Q range - self.q_min = DataSets.q_min - self.q_step = DataSets.q_step - self.q_bins = DataSets.q_bins - self.q_log = DataSets.q_log - - # Scattering angle - self.theta = DataSets.theta - self.use_center_pixel = DataSets.use_center_pixel - - # Sample log overwrites - self.set_detector_angle = DataSets.set_detector_angle - self.detector_angle = DataSets.detector_angle - self.set_detector_angle_offset = DataSets.set_detector_angle_offset - self.detector_angle_offset = DataSets.detector_angle_offset - self.set_direct_pixel = DataSets.set_direct_pixel - self.direct_pixel = DataSets.direct_pixel - - self.output_dir = DataSets.output_dir diff --git a/scripts/LargeScaleStructures/ScalingFactorCalculation/sfCalculator.py b/scripts/LargeScaleStructures/ScalingFactorCalculation/sfCalculator.py deleted file mode 100644 index c40a9b791a8..00000000000 --- a/scripts/LargeScaleStructures/ScalingFactorCalculation/sfCalculator.py +++ /dev/null @@ -1,952 +0,0 @@ -from __future__ import (absolute_import, division, print_function) -from mantid import * -from mantid.simpleapi import * -from numpy import zeros -from pylab import * -import os.path - -PRECISION = 0.010 - - -class sfCalculator(): - - tof_min = None #microS - tof_max = None #microS - - #range of x pixel to use in the X integration (we found out that there - #is a frame effect that introduces noise) - x_pixel_min = 90 - x_pixel_max = 190 - - #from,width,to in microS - rebin_parameters = '0,200,200000' - - #turn on or off the plots - bPlot = False - bFittingPlot = False - - #size of detector - alpha_pixel_nbr = 256 - beta_pixel_nbr = 304 #will be integrated over this dimension - - #name of numerators and denominators - numerator = None #ex: AiD0 - denominator = None #ex: AiD1 - - y_axis_numerator = None - y_axis_error_numerator = None - y_axis_denominator = None - y_axis_error_denominator = None - x_axis = None - - #define the peak region - n_peak_pixel_min = 130 - n_peak_pixel_max = 135 - d_peak_pixel_min = 130 - d_peak_pixel_max = 135 - - peak_pixel_min = None - peak_pixel_max = None - back_pixel_min = None - back_pixel_max = None - - #define the background range used in the background subtraction - n_back_pixel_min = 125 - n_back_pixel_max = 140 - d_back_pixel_min = 125 - d_back_pixel_max = 140 - - y_axis_ratio = None - y_axis_error_ratio = None - x_axis_ratio = None - - def __init__(self, numerator=None, denominator=None, - tof_range=None): - - print('---> initialize calculation') - - if (tof_range is None): - self.tof_min = 10000 - self.tof_max = 21600 - else: - self.tof_min = tof_range[0] - self.tof_max = tof_range[1] - - self.numerator = numerator - self.denominator = denominator - - self.x_axis_ratio = None - self.y_axis_error_ratio = None - self.y_axis_ratio = None - - def setNumerator(self, minPeak, maxPeak, minBack, maxBack): - - print('---> set numerator (' + self.numerator + ')') - - if minPeak != 0: - self.n_peak_pixel_min = minPeak - if maxPeak != 0 : - self.n_peak_pixel_max = maxPeak - if minBack != 0: - self.n_back_pixel_min = minBack - if maxBack != 0: - self.n_back_pixel_max = maxBack - - def setDenominator(self, minPeak, maxPeak, minBack, maxBack): - - print('---> set denominator (' + self.denominator + ')') - - if minPeak != 0: - self.d_peak_pixel_min = minPeak - if maxPeak != 0: - self.d_peak_pixel_max = maxPeak - if minBack != 0: - self.d_back_pixel_min = minBack - if maxBack != 0: - self.d_back_pixel_max = maxBack - - def run(self): - """ - Perform the calculation - - """ - - #perform calculation for numerator - self._calculateFinalYAxis(bNumerator=True) - - #perform calculation for denominator - self._calculateFinalYAxis(bNumerator=False) - - #calculate y_axis of numerator/denominator -# self._x_axis_ratio = self._x_axis - self.y_axis_ratio = self.y_axis_numerator / self.y_axis_denominator - - self.y_axis_error_ratio = ((self.y_axis_error_numerator / - self.y_axis_numerator) ** 2 + - (self.y_axis_error_denominator / - self.y_axis_denominator) ** 2) - self.y_axis_error_ratio = sqrt(self.y_axis_error_ratio) - self.y_axis_error_ratio *= self.y_axis_ratio - - def _calculateFinalYAxis(self, bNumerator=True): - """ - run full calculation for numerator or denominator - """ - if bNumerator is True: - file = self.numerator -# _id = self.id_numerator - self.peak_pixel_min = self.n_peak_pixel_min - self.peak_pixel_max = self.n_peak_pixel_max - self.back_pixel_min = self.n_back_pixel_min - self.back_pixel_max = self.n_back_pixel_max - else: - file = self.denominator -# _id = self.id_denominator - self.peak_pixel_min = self.d_peak_pixel_min - self.peak_pixel_max = self.d_peak_pixel_max - self.back_pixel_min = self.d_back_pixel_min - self.back_pixel_max = self.d_back_pixel_max - - nexus_file_numerator = file - ws_event_data = LoadEventNexus(Filename=nexus_file_numerator, - OutputWorkspace='EventDataWks') - mt1 = mtd['EventDataWks'] - - is_nexus_detector_rotated_flag = wks_utility.isNexusTakeAfterRefDate(ws_event_data.getRun().getProperty('run_start').value) - if is_nexus_detector_rotated_flag: - self.alpha_pixel_nbr = 304 - self.beta_pixel_nbr = 256 - else: - self.alpha_pixel_nbr = 256 - self.beta_pixel_nbr = 304 - - proton_charge = self._getProtonCharge(mt1) - rebin(InputWorkspace='EventDataWks', - OutputWorkspace='HistoDataWks', - Params=self.rebin_parameters) - - mt2 = mtd['HistoDataWks'] - x_axis = mt2.readX(0)[:] - self.x_axis = x_axis - - self._createIntegratedWorkspace(InputWorkspace=mt2, - OutputWorkspace='IntegratedDataWks', - proton_charge=proton_charge, - from_pixel=self.x_pixel_min, - to_pixel=self.x_pixel_max) - ConvertToHistogram(InputWorkspace='IntegratedDataWks', - OutputWorkspace='IntegratedDataWks') - - Transpose(InputWorkspace='IntegratedDataWks', - OutputWorkspace='TransposeIntegratedDataWks') - - ConvertToHistogram(InputWorkspace='TransposeIntegratedDataWks', - OutputWorkspace='TransposeIntegratedDataWks_t') - - FlatBackground(InputWorkspace='TransposeIntegratedDataWks_t', - OutputWorkspace='TransposeHistoFlatDataWks_1', - StartX=self.back_pixel_min, - EndX=self.peak_pixel_min, - Mode='Mean', - OutputMode="Return Background") - - FlatBackground(InputWorkspace='TransposeIntegratedDataWks_t', - OutputWorkspace='TransposeHistoFlatDataWks_2', - StartX=self.peak_pixel_max, - EndX=self.back_pixel_max, - Mode='Mean', - OutputMode="Return Background") - - Transpose(InputWorkspace='TransposeHistoFlatDataWks_1', - OutputWorkspace='DataWks_1') - - Transpose(InputWorkspace='TransposeHistoFlatDataWks_2', - OutputWorkspace='DataWks_2') - - ConvertToHistogram(InputWorkspace='DataWks_1', - OutputWorkspace='DataWks_1') - - ConvertToHistogram(InputWorkspace='DataWks_2', - OutputWorkspace='DataWks_2') - - RebinToWorkspace(WorkspaceToRebin='DataWks_1', - WorkspacetoMatch='IntegratedDataWks', - OutputWorkspace='DataWks_1') - - RebinToWorkspace(WorkspaceToRebin='DataWks_2', - WorkspacetoMatch='IntegratedDataWks', - OutputWorkspace='DataWks_2') - - WeightedMean(InputWorkspace1='DataWks_1', - InputWorkspace2='DataWks_2', - OutputWorkspace='DataWks') - - Minus(LHSWorkspace='IntegratedDataWks', - RHSWorkspace='DataWks', - OutputWorkspace='DataWks') - - mt3 = mtd['DataWks'] - self._calculateFinalAxis(Workspace=mt3, - bNumerator=bNumerator) - - #cleanup workspaces - mtd.remove('EventDataWks') - mtd.remove('HistoDataWks') - mtd.remove('IntegratedDataWks') - mtd.remove('TransposeIntegratedDataWks') - mtd.remove('TransposeIntegratedDataWks_t') - mtd.remove('TransposeHistoFlatDataWks') - mtd.remove('DataWks') - - def _calculateFinalAxis(self, Workspace=None, bNumerator=None): - """ - this calculates the final y_axis and y_axis_error of numerator - and denominator - """ - mt = Workspace - x_axis = mt.readX(0)[:] - self.x_axis = x_axis - - counts_vs_tof = zeros(len(x_axis)-1) - counts_vs_tof_error = zeros(len(x_axis)-1) - - for x in range(self.alpha_pixel_nbr): - counts_vs_tof += mt.readY(x)[:] - counts_vs_tof_error += mt.readE(x)[:] ** 2 - counts_vs_tof_error = sqrt(counts_vs_tof_error) - index_tof_min = self._getIndex(self.tof_min, x_axis) - index_tof_max = self._getIndex(self.tof_max, x_axis) - - if (bNumerator is True): - self.y_axis_numerator = counts_vs_tof[index_tof_min:index_tof_max] - self.y_axis_error_numerator = counts_vs_tof_error[index_tof_min:index_tof_max] - self.x_axis_ratio = self.x_axis[index_tof_min:index_tof_max] - else: - self.y_axis_denominator = counts_vs_tof[index_tof_min:index_tof_max] - self.y_axis_error_denominator = counts_vs_tof_error[index_tof_min:index_tof_max] - self.x_axis_ratio = self.x_axis[index_tof_min:index_tof_max] - - def _createIntegratedWorkspace(self, - InputWorkspace=None, - OutputWorkspace=None, - proton_charge=None, - from_pixel=0, - to_pixel=303): - """ - This creates the integrated workspace over the second pixel range - (beta_pixel_nbr here) and - returns the new workspace handle - """ - - x_axis = InputWorkspace.readX(0)[:] - x_size = to_pixel - from_pixel + 1 - y_axis = zeros((self.alpha_pixel_nbr, len(x_axis) - 1)) - y_error_axis = zeros((self.alpha_pixel_nbr, len(x_axis) - 1)) - y_range = arange(x_size) + from_pixel - - for x in range(self.beta_pixel_nbr): - for y in y_range: - index = int(self.alpha_pixel_nbr * x + y) - y_axis[y, :] += InputWorkspace.readY(index)[:] - y_error_axis[y, :] += ((InputWorkspace.readE(index)[:]) * - (InputWorkspace.readE(index)[:])) - - y_axis = y_axis.flatten() - y_error_axis = sqrt(y_error_axis) - #plot_y_error_axis = _y_error_axis #for output testing only - #-> plt.imshow(plot_y_error_axis, aspect='auto', origin='lower') - y_error_axis = y_error_axis.flatten() - - #normalization by proton charge - y_axis /= (proton_charge * 1e-12) - - CreateWorkspace(OutputWorkspace=OutputWorkspace, - DataX=x_axis, - DataY=y_axis, - DataE=y_error_axis, - Nspec=self.alpha_pixel_nbr) -# mt3 = mtd[OutputWorkspace] -# return mt3 - - def _getIndex(self, value, array): - """ - returns the index where the value has been found - """ - return array.searchsorted(value) - - def _getProtonCharge(self, st=None): - """ - Returns the proton charge of the given workspace in picoCoulomb - """ - if st is not None: - mt_run = st.getRun() - proton_charge_mtd_unit = mt_run.getProperty('gd_prtn_chrg').value - proton_charge = proton_charge_mtd_unit / 2.77777778e-10 - return proton_charge - return None - - def __mul__(self, other): - """ - operator * between two instances of the class - """ - - product = sfCalculator() - - product.numerator = self.numerator + '*' + other.numerator - product.denominator = self.denominator + '*' + other.denominator - - product.x_axis_ratio = self.x_axis_ratio - product.y_axis_ratio = self.y_axis_ratio * other.y_axis_ratio - product.y_axis_error_ratio = sqrt((other.y_axis_ratio * self.y_axis_error_ratio) ** 2 + - (other.y_axis_error_ratio * self.y_axis_ratio) ** 2) - return product - - def fit(self): - """ - This is going to fit the counts_vs_tof with a linear expression and return the a and - b coefficients (y=a+bx) - """ - CreateWorkspace(OutputWorkspace='DataToFit', - DataX=self.x_axis_ratio, - DataY=self.y_axis_ratio, - DataE=self.y_axis_error_ratio, - Nspec=1) - - Fit(InputWorkspace='DataToFit', - Function="name=UserFunction, Formula=a+b*x, a=1, b=2", - Output='Res') - res = mtd['Res_Parameters'] - - self.a = res.getDouble("Value", 0) - self.b = res.getDouble("Value", 1) - self.error_a = res.getDouble("Error", 0) - self.error_b = res.getDouble("Error", 1) - - -def plotObject(instance): - -# return - -# print 'a: ' + str(instance.a[-1]) -# print 'b: ' + str(instance.b[-1]) - - figure() - errorbar(instance.x_axis_ratio, - instance.y_axis_ratio, - instance.y_axis_error_ratio, - marker='s', - mfc='red', - linestyle='', - label='Exp. data') - - if instance.a is not None: - x = linspace(10000, 22000, 100) - _label = "%.3f + x*%.2e" % (instance.a, instance.b) - plot(x, instance.a + instance.b * x, label=_label) - - xlabel("TOF (microsS)") - ylabel("Ratio") - - title(instance.numerator + '/' + instance.denominator) - show() - legend() - - -def recordSettings(a, b, error_a, error_b, name, instance): - """ - This function will record the various fitting parameters and the - name of the ratio - """ - a.append(instance.a) - b.append(instance.b) - error_a.append(instance.error_a) - error_b.append(instance.error_b) - name.append(instance.numerator + '/' + instance.denominator) - - -def variable_value_splitter(variable_value): - """ - This function split the variable that looks like "LambdaRequested:3.75" - and returns a dictionnary of the variable name and value - """ - - _split = variable_value.split('=') - variable = _split[0] - value = float(_split[1]) - return {'variable':variable, 'value':value} - - -def isWithinRange(value1, value2): - """ - This function checks if the two values and return true if their - difference is <= PRECISION - """ - print('value1: ' + str(value1)) - print('value2: ' + str(value2)) - - diff = abs(float(value1)) - abs(float(value2)) - if abs(diff) <= PRECISION: - return True - else: - return False - - -def outputFittingParameters(a, b, error_a, error_b, - lambda_requested, - incident_medium, - S1H, S2H, - S1W, S2W, - output_file_name): - """ - Create an ascii file of the various fittings parameters - y=a+bx - 1st column: incident medium - 2nd column: lambda requested - 3rd column: S1H value - 4th column: S2H value - 5th column: S1W value - 6th column: S2W value - 7th column: a - 7th column: b - 8th column: error_a - 9th column: error_b - """ - - bFileExist = False - #First we need to check if the file already exist - if os.path.isfile(output_file_name): - bFileExist = True - - #then if it does, parse the file and check if following infos are - #already defined: - # lambda_requested, S1H, S2H, S1W, S2W - if (bFileExist): - f = open(output_file_name, 'r') - text = f.readlines() -# split_lines = text.split('\n') - split_lines = text - - entry_list_to_add = [] - - sz = len(a) - for i in range(sz): - - _match = False - - for _line in split_lines: - if _line[0] == '#': - continue - - _line_split = _line.split(' ') - _incident_medium = _line_split[0] - if (_incident_medium == incident_medium): - _lambdaRequested = variable_value_splitter(_line_split[1]) - if (isWithinRange(_lambdaRequested['value'], lambda_requested)): - _s1h = variable_value_splitter(_line_split[2]) - if (isWithinRange(_s1h['value'], S1H[i])): - _s2h = variable_value_splitter(_line_split[3]) - if (isWithinRange(_s2h['value'],S2H[i])): - _s1w = variable_value_splitter(_line_split[4]) - if (isWithinRange(_s1w['value'],S1W[i])): - _s2w = variable_value_splitter(_line_split[5]) - if (isWithinRange(_s2w['value'],S2W[i])): - _match = True - break - - if not _match: - entry_list_to_add.append(i) - - _content = [] - for j in entry_list_to_add: - - _line = 'IncidentMedium=' + incident_medium + ' ' - _line += 'LambdaRequested=' + str(lambda_requested) + ' ' - - _S1H = "{0:.8f}".format(abs(S1H[j])) - _S2H = "{0:.8f}".format(abs(S2H[j])) - _S1W = "{0:.8f}".format(abs(S1W[j])) - _S2W = "{0:.8f}".format(abs(S2W[j])) - _a = "{0:.8f}".format(a[j]) - _b = "{0:.8f}".format(b[j]) - _error_a = "{0:.8f}".format(float(error_a[j])) - _error_b = "{0:.8f}".format(float(error_b[j])) - - _line += 'S1H=' + _S1H + ' ' + 'S2H=' + _S2H + ' ' - _line += 'S1W=' + _S1W + ' ' + 'S2W=' + _S2W + ' ' - _line += 'a=' + _a + ' ' - _line += 'b=' + _b + ' ' - _line += 'error_a=' + _error_a + ' ' - _line += 'error_b=' + _error_b + '\n' - _content.append(_line) - - f = open(output_file_name, 'a') - f.writelines(_content) - f.close() - - else: - - _content = ['#y=a+bx\n', '#\n', - '#lambdaRequested[Angstroms] S1H[mm] S2H[mm] S1W[mm] S2W[mm] a b error_a error_b\n', '#\n'] - sz = len(a) - for i in range(sz): - - _line = 'IncidentMedium=' + incident_medium.strip() + ' ' - _line += 'LambdaRequested=' + str(lambda_requested) + ' ' - - _S1H = "{0:.8f}".format(abs(S1H[i])) - _S2H = "{0:.8f}".format(abs(S2H[i])) - _S1W = "{0:.8f}".format(abs(S1W[i])) - _S2W = "{0:.8f}".format(abs(S2W[i])) - _a = "{0:.8f}".format(a[i]) - _b = "{0:.8f}".format(b[i]) - _error_a = "{0:.8f}".format(float(error_a[i])) - _error_b = "{0:.8f}".format(float(error_b[i])) - - _line += 'S1H=' + _S1H + ' ' + 'S2H=' + _S2H + ' ' - _line += 'S1W=' + _S1W + ' ' + 'S2W=' + _S2W + ' ' - _line += 'a=' + _a + ' ' - _line += 'b=' + _b + ' ' - _line += 'error_a=' + _error_a + ' ' - _line += 'error_b=' + _error_b + '\n' - _content.append(_line) - - f = open(output_file_name, 'w') - f.writelines(_content) - f.close() - - -def createIndividualList(string_list_files): - """ - Using the list_files, will produce a dictionary of the run - number and number of attenuator - ex: - list_files = "1000:0, 1001:1, 1002:1, 1003:2" - return {1000:0, 1001:1, 1002:2, 1003:2} - """ - if (string_list_files == ''): - return None - first_split = string_list_files.split(',') - - list_runs = [] - list_attenuator= [] - - _nbr_files = len(first_split) - for i in range(_nbr_files): - _second_split = first_split[i].split(':') - list_runs.append(_second_split[0].strip()) - list_attenuator.append(int(_second_split[1].strip())) - - return {'list_runs':list_runs, - 'list_attenuator':list_attenuator} - - -def getLambdaValue(mt): - """ - return the lambdaRequest value - """ - mt_run = mt.getRun() - _lambda = mt_run.getProperty('LambdaRequest').value - return _lambda - - -def getSh(mt, top_tag, bottom_tag): - """ - returns the height and units of the given slits - """ - mt_run = mt.getRun() - st = mt_run.getProperty(top_tag).value - sb = mt_run.getProperty(bottom_tag).value - sh = float(sb[0]) - float(st[0]) - units = mt_run.getProperty(top_tag).units - return sh, units - - -def getS1h(mt=None): - """ - returns the height and units of the slit #1 - """ - if mt is not None: - _h, units = getSh(mt, 's1t', 's1b') - return _h, units - return None, '' - - -def getS2h(mt=None): - """ - returns the height and units of the slit #2 - """ - if mt is not None: - _h, units = getSh(mt, 's2t', 's2b') - return _h, units - return None, None - - -def getSw(mt, left_tag, right_tag): - """ - returns the width and units of the given slits - """ - mt_run = mt.getRun() - sl = mt_run.getProperty(left_tag).value - sr = mt_run.getProperty(right_tag).value - sw = float(sl[0]) - float(sr[0]) - units = mt_run.getProperty(left_tag).units - return sw, units - - -def getS1w(mt=None): - """ - returns the width and units of the slit #1 - """ - if mt is not None: - _w, units = getSw(mt, 's1l', 's1r') - return _w, units - return None, '' - - -def getS2w(mt=None): - """ - returns the width and units of the slit #2 - """ - if mt is not None: - _w, units = getSh(mt, 's2l', 's2r') - return _w, units - return None, None - - -def getSlitsValueAndLambda(full_list_runs, - S1H, S2H, - S1W, S2W, lambdaRequest): - """ - Retrieve the S1H (slit 1 height), - S2H (slit 2 height), - S1W (slit 1 width), - S2W (slit 2 width) and - lambda requested values - """ - _nbr_files = len(full_list_runs) - print('> Retrieving Slits and Lambda Requested for each file:') - for i in range(_nbr_files): - _full_file_name = full_list_runs[i] - print('-> ' + _full_file_name) - LoadEventNexus(Filename=_full_file_name, - OutputWorkspace='tmpWks', - MetaDataOnly='1') - mt1 = mtd['tmpWks'] - _s1h_value, _s1h_units = getS1h(mt1) - _s2h_value, _s2h_units = getS2h(mt1) - S1H[i] = _s1h_value - S2H[i] = _s2h_value - - _s1w_value, _s1w_units = getS1w(mt1) - _s2w_value, _s2w_units = getS2w(mt1) - S1W[i] = _s1w_value - S2W[i] = _s2w_value - - _lambda_value = getLambdaValue(mt1) - lambdaRequest[i] = _lambda_value - - -def isRunsSorted(list_runs, S1H, S2H): - """ - Make sure the files have been sorted - """ - sz = len(S1H) - sTotal = zeros(sz) - for i in range(sz): - sTotal[i] = S1H[i] + S2H[i] - - sorted_sTotal = sorted(sTotal) - - for i in range(len(sTotal)): - _left = list(sTotal)[i] - _right = sorted_sTotal[i] - - _left_formated = "%2.1f" % _left - _right_formated = "%2.1f" % _right - if (_left_formated != _right_formated): - return False - - return True - - -def calculateAndFit(numerator='', - denominator='', - list_peak_back_numerator=None, - list_peak_back_denominator=None, - list_objects=[], - tof_range=None): - - print('--> running calculate and fit algorithm') - - cal1 = sfCalculator(numerator=numerator, - denominator=denominator, - tof_range=tof_range) - - cal1.setNumerator(minPeak=list_peak_back_numerator[0], - maxPeak=list_peak_back_numerator[1], - minBack=list_peak_back_numerator[2], - maxBack=list_peak_back_numerator[3]) - - cal1.setDenominator(minPeak=list_peak_back_denominator[0], - maxPeak=list_peak_back_denominator[1], - minBack=list_peak_back_denominator[2], - maxBack=list_peak_back_denominator[3]) - - cal1.run() - - if (list_objects != [] and list_objects[-1] is not None): - new_cal1 = cal1 * list_objects[-1] - new_cal1.fit() - return new_cal1 - else: - cal1.fit() - return cal1 - - -def help(): - """ - Here the user will have information about how the command line - works - """ - print('sfCalculator help:') - print() - print('example:') - print(' > sfCalculator.calculate(string_runs="55889:0, 55890:1, 55891:1, 55892:2",') - print(' list_') - - -#if __name__ == '__main__': -def calculate(string_runs=None, - # list_attenuator=None, - list_peak_back=None, - output_file_name=None, - incident_medium=None, - tof_range=None): - """ - In this current version, the program will automatically calculates - the scaling function for up to, and included, 6 attenuators. - A output file will then be produced with the following format: - S1H S2H a b error_a error_b - .... - where y=a+bx - x axis is in microS - - The string runs has to be specified this way: - string_runs = "run#1:nbr_attenuator, run#2:nbr_attenuator...." - - the list_peak_back is specified this way: - list_peak_back = - [[peak_min_run1, peak_max_run1, back_min_run1, back_max_run1], - [peak_min_run2, peak_max_run2, back_min_run2, back_max_run2], - [...]] - - output_path = where the scaling factor files will be written - tof_range - - """ - - list_attenuator = None - - #use default string files if not provided - if (string_runs is None): - #Input from user -# list_runs = ['55889', '55890', '55891', '55892', '55893', '55894', -# '55895', '55896', '55897', '55898', '55899', '55900', -# '55901', '55902'] - list_runs = ['55889', '55890', '55891', '55892', '55893', '55894'] - nexus_path = '/mnt/hgfs/j35/results/' - pre = 'REF_L_' - nexus_path_pre = nexus_path + pre - post = '_event.nxs' - - for (offset, item) in enumerate(list_runs): - list_runs[offset] = nexus_path_pre + item + post - - else: - dico = createIndividualList(string_runs) - list_runs = dico['list_runs'] - - for (offset, item) in enumerate(list_runs): - try: - _File = FileFinder.findRuns("REF_L%d" %int(item))[0] - list_runs[offset] = _File - except: - msg = "RefLReduction: could not find run %s\n" %item - msg += "Add your data folder to your User Data Directories in the File menu" - raise RuntimeError(msg) - - list_attenuator = dico['list_attenuator'] - - if (incident_medium is None): - incident_medium = "H20" #default value - - if (list_attenuator is None): -# list_attenuator = [0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4] - list_attenuator = [0, 1, 1, 1, 1, 1] - - if (list_peak_back is None): - list_peak_back = zeros((len(list_runs), 4)) #[peak_min, peak_max, back_min, back_max] -# list_peak_back[9, ] = [128, 136, 120, 145] -# list_peak_back[11, ] = [125, 140, 115, 150] -# list_peak_back[10, ] = [128, 136, 120, 145] -# list_peak_back[13, ] = [120, 145, 105, 155] -# list_peak_back[12, ] = [125, 140, 115, 150] - - ##### - #Input file should be as it is here ! - ##### - - #retrieve the S1H and S2H val/units for each NeXus - #retrieve the lambdaRequest value (Angstrom) - S1H = {} - S2H = {} - S1W = {} - S2W = {} - lambdaRequest = {} - getSlitsValueAndLambda(list_runs, S1H, S2H, S1W, S2W, lambdaRequest) - - #Make sure all the lambdaRequested are identical within a given range - lambdaRequestPrecision = 0.01 #1% - for i in lambdaRequest: - _localValue = float(lambdaRequest[i][0]) - _localValueRate = lambdaRequestPrecision * _localValue - _leftValue = _localValue - _localValueRate - _rightValue = _localValue + _localValueRate - - if (_localValue < _leftValue) or (_localValue > _rightValue): - raise Exception("lambda requested do not match !") - - #make sure the file are sorted from smaller to bigger openning - if isRunsSorted(list_runs, S1H, S2H): - - #initialize record fitting parameters arrays - a = [] - b = [] - error_a = [] - error_b = [] - name = [] - - finalS1H = [] - finalS2H = [] - - finalS1W = [] - finalS2W = [] - - #array of True/False flags that will allow us - #to rescale the calculation on the first attenuator - _first_A = [] - for j in range(len(unique(list_attenuator))): - _first_A.append(True) - - #array of index of first attenuator - _index_first_A = [] - for j in range(len(unique(list_attenuator))): - _index_first_A.append(-1) - - index_numerator = -1 - index_denominator = -1 - - list_objects = [] - - for i in range(len(list_runs)): - - print('> Working with index: ' + str(i)) - _attenuator = list_attenuator[i] - - if _attenuator == 0: - continue - else: - if _first_A[_attenuator] is True: - _first_A[_attenuator] = False - _index_first_A[_attenuator] = i - continue - else: - index_numerator = i - index_denominator = _index_first_A[_attenuator] - - print('-> numerator : ' + str(list_runs[index_numerator])) - print('-> denominator: ' + str(list_runs[index_denominator])) - cal = calculateAndFit(numerator=list_runs[index_numerator], - denominator=list_runs[index_denominator], - list_peak_back_numerator=list_peak_back[index_numerator], - list_peak_back_denominator=list_peak_back[index_denominator], - list_objects=list_objects, - tof_range=tof_range) - - recordSettings(a, b, error_a, error_b, name, cal) - - if (i < (len(list_runs) - 1) and list_attenuator[i + 1] == (_attenuator+1)): - list_objects.append(cal) - - #record S1H and S2H - finalS1H.append(S1H[index_numerator]) - finalS2H.append(S2H[index_numerator]) - - #record S1W and S2W - finalS1W.append(S1W[index_numerator]) - finalS2W.append(S2W[index_numerator]) - - #output the fitting parameters in an ascii - _lambdaRequest = "{0:.2f}".format(lambdaRequest[0][0]) - -# output_pre = 'SFcalculator_lr' + str(_lambdaRequest) -# output_ext = '.txt' -# output_file = output_path + '/' + output_pre + output_ext - - if output_file_name is None: - output_file_name = "/home/j35/Desktop/RefLsf.cfg" - - outputFittingParameters(a, b, error_a, error_b, - _lambdaRequest, - incident_medium, - finalS1H, finalS2H, - finalS1W, finalS2W, - output_file_name) - - print('Done !') - - else: - """ - sort the files - """ - pass diff --git a/scripts/REFL_Reduction.py b/scripts/REFL_Reduction.py deleted file mode 100644 index 2c459910603..00000000000 --- a/scripts/REFL_Reduction.py +++ /dev/null @@ -1,10 +0,0 @@ -#pylint: disable=invalid-name -""" - Script used to start the REFL reduction gui from Mantidplot -""" -from __future__ import (absolute_import, division, print_function) -from reduction_application import ReductionGUI - -reducer = ReductionGUI(instrument="REFL", instrument_list=["REFL"]) -if reducer.setup_layout(load_last=True): - reducer.show() diff --git a/scripts/REFL_SF_Calculator.py b/scripts/REFL_SF_Calculator.py deleted file mode 100644 index a6ce2764187..00000000000 --- a/scripts/REFL_SF_Calculator.py +++ /dev/null @@ -1,10 +0,0 @@ -#pylint: disable=invalid-name -""" - Script used to start the REFL SF calculator gui from Mantidplot -""" -from __future__ import (absolute_import, division, print_function) -from reduction_application import ReductionGUI - -reducer = ReductionGUI(instrument="REFLSF", instrument_list=["REFLSF"]) -if reducer.setup_layout(load_last=True): - reducer.show() diff --git a/scripts/REFM_Reduction.py b/scripts/REFM_Reduction.py deleted file mode 100644 index f755196eb03..00000000000 --- a/scripts/REFM_Reduction.py +++ /dev/null @@ -1,10 +0,0 @@ -#pylint: disable=invalid-name -""" - Script used to start the REFL reduction gui from Mantidplot -""" -from __future__ import (absolute_import, division, print_function) -from reduction_application import ReductionGUI - -reducer = ReductionGUI(instrument="REFM", instrument_list=["REFM"]) -if reducer.setup_layout(load_last=True): - reducer.show() diff --git a/scripts/reduction/instruments/reflectometer/__init__.py b/scripts/reduction/instruments/reflectometer/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/scripts/reduction/instruments/reflectometer/data_manipulation.py b/scripts/reduction/instruments/reflectometer/data_manipulation.py deleted file mode 100644 index eac12d1bba5..00000000000 --- a/scripts/reduction/instruments/reflectometer/data_manipulation.py +++ /dev/null @@ -1,226 +0,0 @@ -# pylint: disable=invalid-name -from __future__ import (absolute_import, division, print_function) -import os -from mantid.simpleapi import * - - -def tof_distribution(file_path, callback=None, - range_min=None, range_max=None): - """ - Plot counts as a function of TOF for a given REF_L data file - """ - - print('entering tof_distribution') - - basename = os.path.basename(file_path) - ws_raw = "__%s" % basename - ws = "__TOF_distribution" - - # if not mtd.workspaceExists(ws_raw): - LoadEventNexus(Filename=file_path, OutputWorkspace=ws_raw) - - Rebin(InputWorkspace=ws_raw, OutputWorkspace=ws, Params="0,200,200000") - SumSpectra(InputWorkspace=ws, OutputWorkspace=ws) - - # Get range of TOF where we have data - x = mtd[ws].readX(0) - y = mtd[ws].readY(0) - xmin = x[0] - xmax = None - for i in range(len(y)): - if y[i] == 0.0 and xmax is None: - xmin = x[i] - if y[i] > 0: - xmax = x[i] - - if callback is not None: - from LargeScaleStructures import data_stitching - data_stitching.RangeSelector.connect([ws], callback, - xmin=xmin, xmax=xmax, - range_min=range_min, - range_max=range_max) - - -def _load_entry(entry, ws_output_base, file_path, is_pixel_y, ws_list, tof_min, tof_max, title=""): - # 1D plot - ws_output = "%s %s" % (ws_output_base, title) - - ws = LoadEventNexus(Filename=file_path, NXentryName=entry) - - if ws.getNumberEvents() == 0: - print('No data in entry %s' % entry) - return - - instr_dir = config.getInstrumentDirectory() - - # check date of input file - date = mtd['ws'].getRun().getProperty('run_start').value - nexus_acquisition = date.split('T')[0] - if nexus_acquisition > '2014-10-01': - geo_base_file_x = "REFL_Detector_Grouping_Sum_X_rot.xml" - geo_base_file_y = "REFL_Detector_Grouping_Sum_Y_rot.xml" - else: - geo_base_file_x = "REFL_Detector_Grouping_Sum_X.xml" - geo_base_file_y = "REFL_Detector_Grouping_Sum_Y.xml" - - if is_pixel_y: - grouping_file = os.path.join(instr_dir, "Grouping", geo_base_file_x) - else: - grouping_file = os.path.join(instr_dir, "Grouping", geo_base_file_y) - - GroupDetectors(InputWorkspace=ws, OutputWorkspace=ws_output, MapFile=grouping_file) - ws_output = Transpose(InputWorkspace=ws_output) - - # Copy over the units - ws_list.append(ws_output) - - # 2D plot - output_2d = Rebin(InputWorkspace=ws, Params="%d,200,%d" % (tof_min, tof_max)) - - if is_pixel_y: - grouping_file = os.path.join(instr_dir, "Grouping", "REFL_Detector_Grouping_Sum_X.xml") - output_2d = GroupDetectors(InputWorkspace=output_2d, MapFile=grouping_file) - else: - grouping_file = os.path.join(instr_dir, "Grouping", "REFL_Detector_Grouping_Sum_Y.xml") - output_2d = GroupDetectors(InputWorkspace=output_2d, MapFile=grouping_file) - - return ws_list - - -def counts_vs_pixel_distribution(file_path, is_pixel_y=True, callback=None, - range_min=None, range_max=None, - high_res=True, instrument="REFL", - isPeak=True, - tof_min=None, tof_max=None): - """ - Display counts vs pixel of data or normalization data - - @param isPeak: are we working with peak or with background - - """ - basename = os.path.basename(file_path) - ws_base = "__%s" % basename - - ws_output_base = '' - if instrument == 'REFL': - if isPeak: - type = 'Peak' - else: - type = 'Background' - if is_pixel_y is False: - x_title = "X pixel" - else: - x_title = "Y pixel" - ws_output_base = type + " - " + basename + " - " + x_title - else: - ws_output_base = "Counts vs Y pixel - %s" % basename - x_title = "Y pixel" - if is_pixel_y is False: - ws_output_base = "Counts vs X pixel - %s" % basename - x_title = "X pixel" - - ws_list = [] - - if tof_min is None: - tof_min = 0 - if tof_max is None: - tof_max = 200000 - - if instrument == "REFM": - for p in ['Off_Off', 'On_Off', 'Off_On', 'On_On']: - ws_list = _load_entry(entry="entry-{0}".format(p), ws_output_base=ws_output_base, title=p, - file_path=file_path, is_pixel_y=is_pixel_y, ws_list=ws_list, tof_min=tof_min, - tof_max=tof_max) - else: - ws_list = _load_entry(entry="entry", ws_output_base=ws_output_base, title=p, file_path=file_path, - is_pixel_y=is_pixel_y, ws_list=ws_list, tof_min=tof_min, tof_max=tof_max) - - if callback is not None: - from LargeScaleStructures import data_stitching - data_stitching.RangeSelector.connect(ws_list, callback, - range_min=range_min, - range_max=range_max, - x_title=x_title, - log_scale=True, - ws_output_base=ws_output_base) - - # Estimate peak limits - ws_output = ws_base + '_all' - CloneWorkspace(InputWorkspace=ws_list[0], OutputWorkspace=ws_output) - for i in range(1, len(ws_list)): - Plus(LHSWorkspace=ws_output, RHSWorkspace=ws_list[i], - OutputWorkspace=ws_output) - - x = mtd[ws_output].readX(0) - if not high_res: - Rebin(InputWorkspace=ws_output, OutputWorkspace='__' + ws_output, - Params="0,10,%d" % len(x)) - ws_output = '__' + ws_output - x = mtd[ws_output].readX(0) - y = mtd[ws_output].readY(0) - - n = [] - slope_data = [] - sum = 0.0 - min_id = 0 - max_id = 0 - max_slope = 0 - min_slope = 0 - for i in range(len(y)): - sum += y[i] - n.append(sum) - if i > 0: - slope_data.append(y[i] - y[i - 1]) - if slope_data[i - 1] < min_slope: - min_slope = slope_data[i - 1] - min_id = x[i - 1] - if slope_data[i - 1] > max_slope: - max_slope = slope_data[i - 1] - max_id = x[i - 1] - - sigma = (min_id - max_id) / 2.0 - mean = (min_id + max_id) / 2.0 - return mean - 2 * sigma, mean + 2 * sigma - - -def get_logs(instrument, run): - sangle = 0 - dangle = 0 - dangle0 = 0 - direct_beam_pix = 0 - det_distance = 2.562 - - ws = "__%s_metadata" % run - if instrument == "REFM": - ws = '%s_%s' % (ws, 'Off_Off') - - if not mtd.workspaceExists(ws): - try: - f = FileFinder.findRuns("%s%s" % (instrument, run))[0] - - LoadEventNexus(Filename=f, OutputWorkspace=ws, - NXentryName='entry-Off_Off', MetaDataOnly=True) - except: - pass - - if mtd.workspaceExists(ws): - if mtd[ws].getRun().hasProperty("SANGLE"): - sangle = mtd[ws].getRun().getProperty("SANGLE").value[0] - - if mtd[ws].getRun().hasProperty("DANGLE"): - dangle = mtd[ws].getRun().getProperty("DANGLE").value[0] - - if mtd[ws].getRun().hasProperty("DANGLE0"): - dangle0 = mtd[ws].getRun().getProperty("DANGLE0").value[0] - - if mtd[ws].getRun().hasProperty("DIRPIX"): - direct_beam_pix = mtd[ws].getRun().getProperty("DIRPIX").value[0] - - if mtd[ws].getRun().hasProperty("SampleDetDis"): - det_distance = mtd[ws].getRun().getProperty("SampleDetDis").value[0] / 1000.0 - - return {"SANGLE": sangle, - "DANGLE": dangle, - "DANGLE0": dangle0, - "DIRPIX": direct_beam_pix, - "DET_DISTANCE": det_distance} diff --git a/scripts/reduction/instruments/reflectometer/wks_utility.py b/scripts/reduction/instruments/reflectometer/wks_utility.py deleted file mode 100644 index c1ec57fb120..00000000000 --- a/scripts/reduction/instruments/reflectometer/wks_utility.py +++ /dev/null @@ -1,1999 +0,0 @@ -#pylint: disable=too-many-lines,invalid-name,too-many-arguments, too-many-locals, unused-argument -from __future__ import (absolute_import, division, print_function) -from numpy import zeros, arctan2, arange, shape, sqrt, fliplr, asfarray, mean, sum, NAN -from mantid.simpleapi import * -import math -import os.path -from six.moves import range - -h = 6.626e-34 #m^2 kg s^-1 -m = 1.675e-27 #kg -ref_date = '2014-10-01' #when the detector has been rotated - - -def getSequenceRuns(run_numbers): - """ - This will return the sequence of runs - ex: - input: 10,11,12 - output: 10,11,12 - - input: 10,13-15 - output: 10,13,14,15 - """ - final_list = [] - for _run in run_numbers: - _run = str(_run) - _result = _run.find('-') - if _result == -1: - final_list.append(_run) - else: - _split = _run.split('-') - start = int(_split[0]) - end = int(_split[1]) - _range = arange(end-start+1)+start - for _r in _range: - final_list.append(_r) - return final_list - - -def getProtonCharge(st=None): - """ - Returns the proton charge of the given workspace in picoCoulomb - """ - if st is not None: - mt_run = st.getRun() - proton_charge_mtd_unit = mt_run.getProperty('gd_prtn_chrg').value -# proton_charge = proton_charge_mtd_unit / 2.77777778e-10 - return proton_charge_mtd_unit - return None - - -def getIndex(value, array): - """ - returns the index where the value has been found - """ -# sz = len(array) -# for i in range(sz): -# if value == array[i]: -# return i -# return -1 - return array.searchsorted(value) - - -def getSh(mt, top_tag, bottom_tag): - """ - returns the height and units of the given slit# - """ - mt_run = mt.getRun() - st = mt_run.getProperty(top_tag).value - sb = mt_run.getProperty(bottom_tag).value - sh = math.fabs(float(sb[0]) - float(st[0])) - units = mt_run.getProperty(top_tag).units - return sh, units - - -def getSheight(mt, index): - """ - return the DAS hardware slits height of slits # index - """ - mt_run = mt.getRun() - if index == 2: - isSi = False - try: - tag = 'SiVHeight' - value = mt_run.getProperty(tag).value - isSi = True - except: - tag = 'S2VHeight' - value = mt_run.getProperty(tag).value - return [isSi, value[0]] - else: - tag = 'S1VHeight' - value = mt_run.getProperty(tag).value - - return value[0] - - -def getS1h(mt=None): - """ - returns the height and units of the slit #1 - """ - if mt is not None: -# _h, units = getSh(mt, 's1t', 's1b') - _h = getSheight(mt, 1) - return _h - return None - - -def getS2h(mt=None): - """ - returns the height and units of the slit #2 - """ - if mt is not None: - [isSi, _h] = getSheight(mt, 2) - return [isSi,_h] - return [False, None] - - -def getSwidth(mt, index): - """ - returns the width and units of the given index slits - defined by the DAS hardware - """ - mt_run = mt.getRun() - if index==2: - isSi = False - try: - tag = 'SiHWidth' - value = mt_run.getProperty(tag).value - isSi = True - except: - tag = 'S2HWidth' - value = mt_run.getProperty(tag).value - return [isSi, value[0]] - else: - tag = 'S1HWidth' - value = mt_run.getProperty(tag).value - return value[0] - - -def getSw(mt, left_tag, right_tag): - """ - returns the width and units of the given slits - """ - mt_run = mt.getRun() - sl = mt_run.getProperty(left_tag).value - sr = mt_run.getProperty(right_tag).value - sw = math.fabs(float(sl[0]) - float(sr[0])) - units = mt_run.getProperty(left_tag).units - return sw, units - - -def getS1w(mt=None): - """ - returns the width and units of the slit #1 - """ - if mt is not None: -# _w, units = getSw(mt, 's1l', 's1r') - _w = getSwidth(mt, 1) - return _w - return None - - -def getS2w(mt=None): - """ - returns the width and units of the slit #2 - """ - if mt is not None: - [isSi, _w] = getSwidth(mt, 2) - return [isSi,_w] - return [False,None] - - -def getLambdaValue(mt_name): - """ - return the lambdaRequest value - """ - mt_run = mtd[mt_name].getRun() - _lambda = mt_run.getProperty('LambdaRequest').value - return _lambda - - -def getPixelXPixelY(mt1, maxX=304, maxY=256): - """ - returns the PixelX_vs_PixelY array of the workspace data specified - """ - pixelX_vs_pixelY = zeros((maxY, maxX)) - for x in range(maxX): - for y in range(maxY): - _index = maxY * x + y - _sum = sum(mt1.readY(_index)[:]) - pixelX_vs_pixelY[y, x] = _sum - return pixelX_vs_pixelY - - -def getPixelXPixelYError(mt1): - """ - returns the PixelX_vs_PixelY_error array of the workspace data specified - """ - pixel_error = zeros((256, 304)) - for x in range(304): - for y in range(256): - _index = 256 * x + y - _sum = sum(mt1.readE(_index)[:]) - pixel_error[y, x] = _sum - return pixel_error - - -def getPixelXTOF(mt1, maxX=304, maxY=256): - """ - returns the PixelX_vs_TOF array of the workspace data specified - """ - _init = mt1.readY(0)[:] - pixelX_vs_tof = zeros((maxY, len(_init))) - for x in range(maxX): - for y in range(maxY): - _index = maxY * x + y - _array = mt1.readY(_index)[:] - pixelX_vs_tof[y, :] += _array - return pixelX_vs_tof - - -def findQaxisMinMax(q_axis): - """ - Find the position of the common Qmin and Qmax in - each q array - """ - - nbr_row = shape(q_axis)[0] - nbr_col = shape(q_axis)[1] - q_min = min(q_axis[0]) - q_max = max(q_axis[0]) - - for i in arange(nbr_row - 1) + 1: - _q_min = q_axis[i][-1] - _q_max = q_axis[i][0] - if _q_min > q_min: - q_min = _q_min - if _q_max < q_max: - q_max = _q_max - - #find now the index of those min and max in each row - _q_axis_min_max_index = zeros((nbr_row, 2)) - for i in arange(nbr_row): - for j in arange(nbr_col - 1): - _q = q_axis[i, j] - _q_next = q_axis[i, j + 1] - if (_q >= q_max) and (_q_next <= q_max): - _q_axis_min_max_index[i, 0] = j - if (_q >= q_min) and (_q_next <= q_min): - _q_axis_min_max_index[i, 1] = j - - return _q_axis_min_max_index - - -def cleanup_data(InputWorkspace=None, - OutputWorkspace=None, - maxY=256): - mti = mtd[InputWorkspace] - _tof_axis = mti.readX(0)[:] - nbr_tof = shape(_tof_axis)[0]-1 - - _new_y = zeros((maxY, nbr_tof)) - _new_e = zeros((maxY, nbr_tof)) - for px in range(maxY): - for tof in range(nbr_tof-1): - _y = mti.readY(px)[tof] - if _y != 0: - _e = mti.readE(px)[tof] -# if _y < _e: - if _y < 0 or _y < _e: - _y = 0. - _e = 0. - _new_y[px,tof] = float(_y) - _new_e[px,tof] = float(_e) - - _y_error_axis = _new_e.flatten() - _y_axis = _new_y.flatten() - - CreateWorkspace(OutputWorkspace=OutputWorkspace, - DataX=_tof_axis, - DataY=_y_axis, - DataE=_y_error_axis, - Nspec=maxY, - UnitX="TOF", - ParentWorkspace=mti) - - -def createIntegratedWorkspace(mt1, - fromXpixel, toXpixel, - fromYpixel, toYpixel, - maxX=304, maxY=256, - bCleaning=False): - """ - This creates the integrated workspace over the second pixel range (304 here) and - returns the new workspace handle - """ - - _tof_axis = mt1.readX(0)[:] - - _fromXpixel = min([fromXpixel, toXpixel]) - _toXpixel = max([fromXpixel, toXpixel]) - fromXpixel = _fromXpixel - toXpixel = _toXpixel - - _fromYpixel = min([fromYpixel, toYpixel]) - _toYpixel = max([fromYpixel, toYpixel]) - fromYpixel = _fromYpixel - toYpixel = _toYpixel - - _y_axis = zeros((maxY, len(_tof_axis) - 1)) - _y_error_axis = zeros((maxY, len(_tof_axis) - 1)) - - x_size = toXpixel - fromXpixel + 1 - x_range = arange(x_size) + fromXpixel - - y_size = toYpixel - fromYpixel + 1 - y_range = arange(y_size) + fromYpixel - - for x in x_range: - for y in y_range: - _index = int((maxY) * x + y) - _y_axis[y, :] += mt1.readY(_index)[:] - _y_error_axis[y, :] += ((mt1.readE(_index)[:]) * (mt1.readE(_index)[:])) - - _y_axis = _y_axis.flatten() - _y_error_axis = sqrt(_y_error_axis) - _y_error_axis = _y_error_axis.flatten() - - outputWorkspace = CreateWorkspace(DataX=_tof_axis, - DataY=_y_axis, - DataE=_y_error_axis, - Nspec=maxY, - UnitX="TOF", - ParentWorkspace=mt1.name()) - - return outputWorkspace - - -def convertWorkspaceToQ(ws_data, - fromYpixel, toYpixel, - maxX=304, maxY=256, - cpix=None, - source_to_detector=None, - sample_to_detector=None, - theta=None, - geo_correction=False, - q_binning=None): - """ - This creates the integrated workspace over the second pixel range (304 here) and - returns the new workspace handle - """ - - mt1 = ws_data - _tof_axis = mt1.readX(0)[:] - _fromYpixel = min([fromYpixel, toYpixel]) - _toYpixel = max([fromYpixel, toYpixel]) - fromYpixel = _fromYpixel - toYpixel = _toYpixel - - if geo_correction: - - yrange = arange(toYpixel - fromYpixel + 1) + fromYpixel - _q_axis = convertToRvsQWithCorrection(mt1, - dMD=source_to_detector, - theta=theta, - tof=_tof_axis, - yrange=yrange, - cpix=cpix) - - #find the common Qmin and Qmax values and their index (position) - #in each _q_axis row - _q_axis_min_max_index = findQaxisMinMax(_q_axis) - - #replace the _q_axis of the yrange of interest by the new - #individual _q_axis - y_size = toYpixel - fromYpixel + 1 - y_range = arange(y_size) + fromYpixel - - _y_axis = zeros((y_size, len(_tof_axis) - 1)) - _y_error_axis = zeros((y_size, len(_tof_axis) - 1)) - - #now determine the y_axis - for _q_index in range(y_size): - - _tmp_q_axis = _q_axis[_q_index] - q_axis = _tmp_q_axis[::-1] #reverse the axis (now increasing order) - - _a = yrange[_q_index] - _y_axis_tmp = list(mt1.readY(int(_a))[:]) - _y_error_axis_tmp = list(mt1.readE(int(_a))[:]) - - #keep only the overlap region of Qs - _q_min = _q_axis_min_max_index[_q_index, 0] - if _q_min != 0: - _y_axis_tmp[0:_q_min] = 0 - _y_error_axis_tmp[0:_q_min] = 0 - - _q_max = int(_q_axis_min_max_index[_q_index, 1]) - sz = shape(_y_axis_tmp)[0] - if _q_max != sz: - _index_q_max_range = arange(sz - _q_max) + _q_max - for i in _index_q_max_range: - _y_axis_tmp[i] = 0 - _y_error_axis_tmp[i] = 0 - - _y_axis[_q_index, :] = _y_axis_tmp[::-1] - _y_error_axis[_q_index, :] = _y_error_axis_tmp[::-1] - - x_axis = q_axis.flatten() - y_axis = _y_axis.flatten() - y_error_axis = _y_error_axis.flatten() - - outputWorkspace = CreateWorkspace(DataX=x_axis, - DataY=y_axis, - DataE=y_error_axis, - Nspec=int(y_size), - UnitX="MomentumTransfer", - ParentWorkspace=mt1.name()) - - outputWorkspace.setDistribution(True) - - outputWorkspace = Rebin(InputWorkspace=outputWorkspace, - Params=q_binning) - - else: - - if source_to_detector is not None and theta is not None: - _const = float(4) * math.pi * m * source_to_detector / h - _q_axis = 1e-10 * _const * math.sin(theta) / (_tof_axis * 1e-6) - else: - _q_axis = _tof_axis - print('should not reach this condition !') - - y_size = toYpixel - fromYpixel + 1 - y_range = arange(y_size) + fromYpixel - - _y_axis = zeros((y_size, len(_q_axis) -1 )) - _y_error_axis = zeros((y_size, len(_q_axis) - 1)) - - for y in range(y_size): - - a = y_range[y] - - _tmp_y_axis = mt1.readY(int(a))[:] - _y_axis[int(y), :] = _tmp_y_axis - _tmp_y_error_axis = mt1.readE(int(a))[:] - _y_error_axis[int(y),:] = _tmp_y_error_axis - - _x_axis = _q_axis.flatten() - _y_axis = _y_axis.flatten() - _y_error_axis = _y_error_axis.flatten() - - # reverse order - _x_axis = _x_axis[::-1] - _y_axis = _y_axis[::-1] - _y_error_axis = _y_error_axis[::-1] - - outputWorkspace = CreateWorkspace(DataX=_x_axis, - DataY=_y_axis, - DataE=_y_error_axis, - Nspec=int(y_size), - UnitX="MomentumTransfer", - ParentWorkspace=mt1.name()) - - outputWorkspace.setDistribution(True) - - outputWorkspace = Rebin(InputWorkspace=outputWorkspace, - Params=q_binning) - - return outputWorkspace - - -def create_grouping(workspace=None, xmin=0, xmax=None, filename=".refl_grouping.xml"): - # This should be read from the - npix_x = 304 - npix_y = 256 - if workspace is not None: - if mtd[workspace].getInstrument().hasParameter("number-of-x-pixels"): - npix_x = int(mtd[workspace].getInstrument().getNumberParameter("number-of-x-pixels")[0]) - if mtd[workspace].getInstrument().hasParameter("number-of-y-pixels"): - npix_y = int(mtd[workspace].getInstrument().getNumberParameter("number-of-y-pixels")[0]) - - f = open(filename, 'w') - f.write("<detector-grouping description=\"Integrated over X\">\n") - - if xmax is None: - xmax = npix_x - - for y in range(npix_y): - # index = max_y * x + y - indices = [] - for x in range(xmin, xmax + 1): - indices.append(str(npix_y * x + y)) - - # Detector IDs start at zero, but spectrum numbers start at 1 - # Grouping works on spectrum numbers - indices_str = ','.join(indices) - f.write(" <group name='%d'>\n" % y) - f.write(" <ids val='%s'/>\n" % indices_str) - f.write(" </group>\n") - - f.write("</detector-grouping>\n") - f.close() - - -def angleUnitConversion(value, from_units='degree', to_units='rad'): - """ - This function converts the angle units - """ - - if from_units == to_units: - return value - - from_factor = 1.0 - #convert everything into rad - if from_units == 'degree': - from_factor = 1.745329252e-2 - value_rad = from_factor * value - - if to_units == 'rad': - return value_rad - else: - to_factor = 57.2957795 - return to_factor * value_rad - - -def convertToThetaVsLambda(_tof_axis, - _pixel_axis, - central_pixel, - pixel_size=0.0007, - theta= -1, - dSD= -1, - dMD= -1): - """ - This function converts the pixel/tof array - to theta/lambda - """ - # h = 6.626e-34 #m^2 kg s^-1 - # m = 1.675e-27 #kg - - #convert tof_axis into seconds - _tof_axis = _tof_axis * 1e-6 - - vel_array = dMD / _tof_axis #mm/ms = m/s - _lambda = h / (m * vel_array) #m - _lambda = _lambda * 1e10 #angstroms - - d_vec = (_pixel_axis - central_pixel) * pixel_size - theta_vec = arctan2(d_vec, dSD) + theta - - dico = {'lambda_vec': _lambda, 'theta_vec': theta_vec} - - return dico - - -def convertToRvsQWithCorrection(mt, dMD= -1, theta= -1.0, tof=None, yrange=None, cpix=None): - """ - This function converts the pixel/TOF array to the R(Q) array - using Q = (4.Pi.Mn)/h * L.sin(theta/2)/TOF - with L: distance central_pixel->source - TOF: TOF of pixel - theta: angle of detector - """ - - # h = 6.626e-34 #m^2 kg s^-1 - # m = 1.675e-27 #kg - - sample = mt.getInstrument().getSample() - - maxY = 256 - - dPS_array = zeros(maxY) - for y in range(maxY): - detector = mt.getDetector(y) - dPS_array[y] = sample.getDistance(detector) - - #distance sample->center of detector - dSD = dPS_array[maxY / 2] - - _const = float(4) * math.pi * m * dMD / h - sz_tof = len(tof) - q_array = zeros((len(yrange), sz_tof - 1)) - - for _px in range(len(yrange)): - dangle = ref_beamdiv_correct(cpix, mt, dSD, _px) - - if dangle is not None: - _theta = theta + dangle - else: - _theta = theta - - for t in range(sz_tof - 1): - tof1 = tof[t] - tof2 = tof[t+1] - tofm = (tof1+tof2)/2. - _Q = _const * math.sin(_theta) / (tofm*1e-6) - q_array[_px, t] = _Q * 1e-10 - - return q_array - - -def getQHisto(source_to_detector, theta, tof_array): - _const = float(4) * math.pi * m * source_to_detector / h - sz_tof = len(tof_array) - q_array = zeros(sz_tof) - for t in range(sz_tof): - _Q = _const * math.sin(theta) / (tof_array[t] * 1e-6) - q_array[t] = _Q * 1e-10 - - return q_array - - -def ref_beamdiv_correct(cpix, det_secondary, - pixel_index, - pixel_width = 0.0007, - first_slit_size = None, - last_slit_size = None): - """ - This function calculates the acceptance diagram, determines pixel overlap - and computes the offset to the scattering angle. - """ - - # This is currently set to the same number for both REF_L and REF_M - epsilon = 0.5 * 1.3 * 1.0e-3 - - # Set the center pixel - if cpix is None: - cpix = 133.5 - -# first_slit_size = getSheight(mt, '1') -# last_slit_size = getSheight(mt,'2') - - last_slit_dist = 0.654 #m - slit_dist = 0.885000050068 #m - - first_slit_size = float(first_slit_size) * 0.001 - last_slit_size = float(last_slit_size) * 0.001 - - _y = 0.5 * (first_slit_size + last_slit_size) - _x = slit_dist - gamma_plus = math.atan2(_y, _x) - - _y = 0.5 * (first_slit_size - last_slit_size) - _x = slit_dist - gamma_minus = math.atan2(_y, _x) - - half_last_aperture = 0.5 * last_slit_size - neg_half_last_aperture = -1.0 * half_last_aperture - - last_slit_to_det = last_slit_dist + det_secondary - dist_last_aper_det_sin_gamma_plus = last_slit_to_det * math.sin(gamma_plus) - dist_last_aper_det_sin_gamma_minus = last_slit_to_det * math.sin(gamma_minus) - - #set the delta theta coordinates of the acceptance polygon - accept_poly_x = [] - accept_poly_x.append(-1.0 * gamma_minus) - accept_poly_x.append(gamma_plus) - accept_poly_x.append(gamma_plus) - accept_poly_x.append(gamma_minus) - accept_poly_x.append(-1.0 * gamma_plus) - accept_poly_x.append(-1.0 * gamma_plus) - accept_poly_x.append(accept_poly_x[0]) - - #set the z coordinates of the acceptance polygon - accept_poly_y = [] - accept_poly_y.append(half_last_aperture - dist_last_aper_det_sin_gamma_minus + epsilon) - accept_poly_y.append(half_last_aperture + dist_last_aper_det_sin_gamma_plus + epsilon) - accept_poly_y.append(half_last_aperture + dist_last_aper_det_sin_gamma_plus - epsilon) - accept_poly_y.append(neg_half_last_aperture + dist_last_aper_det_sin_gamma_minus - epsilon) - accept_poly_y.append(neg_half_last_aperture - dist_last_aper_det_sin_gamma_plus - epsilon) - accept_poly_y.append(neg_half_last_aperture - dist_last_aper_det_sin_gamma_plus + epsilon) - accept_poly_y.append(accept_poly_y[0]) - - cur_index = pixel_index - - #set the z band for the pixel - xMinus = (cur_index - cpix - 0.5) * pixel_width - xPlus = (cur_index - cpix + 0.5) * pixel_width - - #calculate the intersection - yLeftCross = -1 - yRightCross = -1 - - xI = accept_poly_x[0] - yI = accept_poly_y[0] - - int_poly_x = [] - int_poly_y = [] - - for i in range(len(accept_poly_x)): - - xF = accept_poly_y[i] - yF = accept_poly_x[i] - - if xI < xF: - - if xI < xMinus and xF > xMinus: - yLeftCross = yI + (yF - yI) * (xMinus - xI) / (xF - xI) - int_poly_x.append(yLeftCross) - int_poly_y.append(xMinus) - - if xI < xPlus and xF >= xPlus: - yRightCross = yI + (yF - yI) * (xPlus - xI) / (xF - xI) - int_poly_x.append(yRightCross) - int_poly_y.append(xPlus) - - else: - - if xF < xPlus and xI >= xPlus: - yRightCross = yI + (yF - yI) * (xPlus - xI) / (xF - xI) - int_poly_x.append(yRightCross) - int_poly_y.append(xPlus) - - if xF < xMinus and xI >= xMinus: - yLeftCross = yI + (yF - yI) * (xMinus - xI) / (xF - xI) - int_poly_x.append(yLeftCross) - int_poly_y.append(xMinus) - - #This catches points on the polygon inside the range of interest - if xF >= xMinus and xF < xPlus: - int_poly_x.append(yF) - int_poly_y.append(xF) - - xI = xF - yI = yF - - if len(int_poly_x) > 2: - int_poly_x.append(int_poly_x[0]) - int_poly_y.append(int_poly_y[0]) - int_poly_x.append(int_poly_x[1]) - int_poly_y.append(int_poly_y[1]) - else: - #Intersection polygon is null, point or line, so has no area - #therefore there is no angle corrction - return None - - #Calculate intersection polygon area - area = calc_area_2D_polygon(int_poly_x, - int_poly_y, - len(int_poly_x) - 2) - - center_of_mass = calc_center_of_mass(int_poly_x, - int_poly_y, - area) - - return center_of_mass - - -def calc_area_2D_polygon(x_coord, y_coord, size_poly): - """ - Calculation of the area defined by the 2D polygon - """ - _range = arange(size_poly) + 1 - area = 0 - for i in _range: - area += (x_coord[i] * (y_coord[i + 1] - y_coord[i - 1])) - return area / 2. - - -def calc_center_of_mass(arr_x, arr_y, A): - """ - Function that calculates the center-of-mass for the given polygon - - @param arr_x: The array of polygon x coordinates - @param arr_y: The array of polygon y coordinates - @param A: The signed area of the polygon - - @return: The polygon center-of-mass - """ - - center_of_mass = 0.0 - SIXTH = 1. / 6. - for j in arange(len(arr_x) - 2): - center_of_mass += (arr_x[j] + arr_x[j + 1]) \ - * ((arr_x[j] * arr_y[j + 1]) - - (arr_x[j + 1] * arr_y[j])) - - if A != 0.0: - return (SIXTH * center_of_mass) / A - else: - return 0.0 - - -def getFieldValue(table, row, column): - _tag_value = table[row][column] - _tag_value_split = _tag_value.split('=') - return _tag_value_split[1] - - -def isWithinPrecisionRange(value_file, value_run, precision): - diff = abs(float(value_file)) - abs(float(value_run)) - if abs(diff) <= precision: - return True - else: - return False - - -def _applySFtoArray(workspace, a, b, a_error, b_error): - """ - This function will create for each x-axis value the corresponding - scaling factor using the formula y=a+bx and - """ - - mt = mtd[workspace] - x_axis = mt.readX(0)[:] - sz = len(x_axis) - x_axis_factors = zeros(sz) - x_axis_factors_error = zeros(sz) - for i in range(sz): - _x_value = float(x_axis[i]) - _factor = _x_value * b + a - x_axis_factors[i] = _factor - _factor_error = _x_value * b_error + a_error - x_axis_factors_error[i] = _factor_error - - #create workspace - CreateWorkspace(OutputWorkspace='sfWorkspace', - DataX=x_axis, - DataY=x_axis_factors, - DataE=x_axis_factors_error, - Nspec=1, - UnitX="TOF") - - Divide(workspace, 'sfWorkspace', workspace) - - return workspace - - -def loadNeXus(runNumbers, type): - """ - will retrieve the data from the runNumbers specify and will - add them or just return the workspace created - """ - - wks_name = '' - if type == 'data': - wks_name = 'ws_event_data' - else: - wks_name = 'ws_event_norm' - - print('-> loading ', type) - if (type == 'data') and len(runNumbers) > 1: - - _list = [] - for _run in runNumbers: - _list.append(str(_run)) - list_run = ','.join(_list) - print('--> working with runs:', str(list_run)) - - _index = 0 - for _run in runNumbers: - - # Find full path to event NeXus data file - try: - data_file = FileFinder.findRuns("REF_L%d" %_run)[0] - except RuntimeError: - msg = "RefLReduction: could not find run %d\n" % _run - msg += "Add your data folder to your User Data Directories in the File menu" - raise RuntimeError(msg) - - if _index == 0: - ws_event_data = LoadEventNexus(Filename=data_file,OutputWorskpace=wks_name) - _index += 1 - else: - tmp = LoadEventNexus(Filename=data_file) - Plus(LHSWorkspace=ws_event_data, - RHSWorkspace=tmp, - OutputWorkspace=wks_name) - DeleteWorkspace(tmp) - else: - - print('--> Working with run: ' + str(runNumbers)) - - try: - data_file = FileFinder.findRuns("REF_L%d" %runNumbers)[0] - except RuntimeError: - msg = "RefLReduction: could not find run %d\n" %runNumbers[0] - msg += "Add your data folder to your User Data Directories in the File menu" - raise RuntimeError(msg) - - ws_event_data = LoadEventNexus(Filename=data_file, OutputWorkspace=wks_name) - - return ws_event_data - - -def rebinNeXus(inputWorkspace, params, type): - """ - will rebin the event workspace according to the params - params[0]: min value - params[1]: bin size - params[2]: max value - """ - print('--> rebin ', type) - ws_histo_data = Rebin(InputWorkspace=inputWorkspace, - Params=params, - PreserveEvents=True) - return ws_histo_data - - -def cropTOF(inputWorkspace, min, max, type): - """ - will crop the nexus (workspace) using min and max value - used here to crop the TOF range - """ - print('--> crop ' , type , ' workspace in TOF') - ws_histo_data = CropWorkspace(InputWorkspace = inputWorkspace, - XMin = min, - XMax = max) - return ws_histo_data - - -def normalizeNeXus(inputWorkspace, type): - """ - normalize nexus by proton charge - """ - print('--> normalize ', type) - ws_histo_data = NormaliseByCurrent(InputWorkspace=inputWorkspace) - return ws_histo_data - - -def integrateOverLowResRange(mt1, - dataLowResRange, - type, - is_nexus_detector_rotated_flag): - """ - This creates the integrated workspace over the low resolution range leaving - us with a [256,nbr TOF] workspace - returns the new workspace handle - BUT this algorithm also makes sure that the error value is 1 when counts - is 0 ! - """ - - print('--> integrated over low res range of ', type) - _tof_axis = mt1.readX(0)[:].copy() -# t_range = arange(nbr_tof-1) - - # -1 to work with index directly - fromXpixel = min(dataLowResRange) - 1 - toXpixel = max(dataLowResRange) - 1 - - if is_nexus_detector_rotated_flag: - sz_y_axis = 304 - else: - sz_y_axis = 256 - - _y_axis = zeros((sz_y_axis, len(_tof_axis) - 1)) - _y_error_axis = zeros((sz_y_axis, len(_tof_axis) - 1)) - - x_size = toXpixel - fromXpixel + 1 - x_range = arange(x_size) + fromXpixel - - y_range = arange(sz_y_axis) - - for x in x_range: - for y in y_range: - _index = int((sz_y_axis) * x + y) - _y_axis[y, :] += mt1.readY(_index)[:].copy() - _tmp_error_axis = mt1.readE(_index)[:].copy() - # 0 -> 1 -# index_where_0 = where(_tmp_error_axis == 0) -# _tmp_error_axis[index_where_0] = 1 - - _y_error_axis[y, :] += _tmp_error_axis * _tmp_error_axis -# _y_error_axis[y, :] += ((mt1.readE(_index)[:]) * (mt1.readE(_index)[:])) - - _y_error_axis = sqrt(_y_error_axis) - - return [_tof_axis, _y_axis, _y_error_axis] - - -def substractBackground(tof_axis, y_axis, y_error_axis, - peakRange, backFlag, backRange, - error_0, type): - """ - shape of y_axis : [sz_y_axis, nbr_tof] - This routine will calculate the background, remove it from the peak - and will return only the range of peak -> [peak_size, nbr_tof] - - """ - - # give a friendly name to peak and back ranges - # -1 because we are working with 0 index arrays - peakMin = peakRange[0]-1 - peakMax = peakRange[1]-1 - backMin = backRange[0]-1 - backMax = backRange[1]-1 - - if not backFlag: - print('---> no ', type, ' background requested!') - return [y_axis[peakMin:peakMax+1,:], y_error_axis[peakMin:peakMax+1,:]] - - print('--> background subtraction of ', type) - - # retrieve data - _tofAxis = tof_axis - nbrTof = len(_tofAxis) - - # size peak - szPeak = peakMax - peakMin + 1 - - # init arrays - final_y_axis = zeros((szPeak, nbrTof)) - final_y_error_axis = zeros((szPeak, nbrTof)) - -# final_y_axis = empty((szPeak, nbrTof)) -# final_y_error_axis = empty((szPeak, nbrTof)) -# final_y_axis[:] = NAN -# final_y_error_axis[:] = NAN - - for t in range(nbrTof): - - # by default, no space for background subtraction below and above peak - bMinBack = False - bMaxBack = False - - if backMin < (peakMin): - bMinBack = True - _backMinArray = y_axis[backMin:peakMin, t] - _backMinErrorArray = y_error_axis[backMin:peakMin, t] - [_backMin, _backMinError] = weightedMean(_backMinArray, - _backMinErrorArray, error_0) - - if (peakMax) < backMax: - bMaxBack = True - _backMaxArray = y_axis[peakMax+1:backMax+1, t] - _backMaxErrorArray = y_error_axis[peakMax+1:backMax+1, t] - [_backMax, _backMaxError] = weightedMean(_backMaxArray, _backMaxErrorArray, error_0) - - # if no max background use min background - if not bMaxBack: - background = _backMin - background_error = _backMinError - - # if no min background use max background - if not bMinBack: - background = _backMax - background_error = _backMaxError - - if bMinBack and bMaxBack: - [background, background_error] = weightedMean([_backMin, _backMax], [_backMinError, _backMaxError], error_0) - - # remove background for each pixel of the peak - for x in range(szPeak): - final_y_axis[x,t] = float(y_axis[peakMin + x,t]) - float(background) - final_y_error_axis[x,t] = float(math.sqrt(pow(y_error_axis[peakMin+x,t],2) + pow(background_error,2))) - -# if t == nbrTof-2: -# print(float(y_axis[peakMin + x,t]) - float(background)) - - return [final_y_axis, final_y_error_axis] - - -def weightedMean(data_array, error_array, error_0): - - sz = len(data_array) - - # calculate the numerator of mean - dataNum = 0 - for i in range(sz): - if error_array[i] == 0: - error_array[i] = error_0 - - tmpFactor = float(data_array[i]) / float((pow(error_array[i],2))) - dataNum += tmpFactor - - # calculate denominator - dataDen = 0 - for i in range(sz): - if error_array[i] == 0: - error_array[i] = error_0 - tmpFactor = 1./float((pow(error_array[i],2))) - dataDen += tmpFactor - - if dataDen == 0: - data_mean = NAN - mean_error = NAN - else: - data_mean = float(dataNum) / float(dataDen) - mean_error = math.sqrt(1/dataDen) - - return [data_mean, mean_error] - - -def weightedMeanOfRange(norm_y_axis, norm_y_error_axis): - """ - will calculate the weighted Mean of the region given - """ - - # get nbr tof - dim = norm_y_axis.shape - nbr_tof = dim[1] - - final_array = zeros(nbr_tof) - final_array_error = zeros(nbr_tof) - - for t in range(nbr_tof): - _tmp_range = norm_y_axis[:, t] - _tmp_range_error = norm_y_error_axis[:,t] - [_mean,_mean_error] = weightedMean(_tmp_range, _tmp_range_error) - final_array[t] = _mean - final_array_error[t] = _mean_error - - return [final_array, final_array_error] - - -def meanOfRange(norm_y_axis, norm_y_error_axis): - """ - will calculate the mean of range - """ - - # get nbr tof - dim = norm_y_axis.shape - nbr_tof = dim[1] - - final_array = zeros(nbr_tof) - final_array_error = zeros(nbr_tof) - - for t in range(nbr_tof): - _tmp_range = norm_y_axis[:,t] - _tmp_range_error = norm_y_error_axis[:,t] - [_mean,_mean_error] = myMean(_tmp_range, _tmp_range_error) - final_array[t] = _mean - final_array_error[t] = _mean_error - - return [final_array, final_array_error] - - -def myMean(data_array, error_array): - - sz=size(data_array) - - _mean = mean(data_array) - _mean_error = sqrt(sum(_mean*_mean))/float(sz[0]) - - return [_mean, _mean_error] - - -def divideDataByNormalization(data_y_axis, - data_y_error_axis, - av_norm, - av_norm_error): - - print('-> divide data by normalization') - - data_size = data_y_axis.shape - nbr_pixel = data_size[0] - nbr_tof = data_size[1] - - new_data_y_axis = zeros((nbr_pixel, nbr_tof)) - new_data_y_error_axis = zeros((nbr_pixel, nbr_tof)) - - for t in range(nbr_tof): - for x in range(nbr_pixel): - - if (av_norm[t] != 0) and (data_y_axis[x, t] != 0): - - tmp_value = float(data_y_axis[x,t]) / float(av_norm[t]) - - tmp_error_1 = pow(float(data_y_error_axis[x,t]) / float(data_y_axis[x,t]),2) - tmp_error_2 = pow(float(av_norm_error[t]) / float(av_norm[t]),2) - tmp_error = sqrt(tmp_error_1 + tmp_error_2) * abs(float(data_y_axis[x,t]) / float(av_norm[t])) - - new_data_y_axis[x,t] = tmp_value - new_data_y_error_axis[x,t] = tmp_error - - return [new_data_y_axis, new_data_y_error_axis] - - -def sumWithError(value, error): - """ will sume the array of values and will return the sum and the - error that goes with it - """ - - sum_value = sum(value) - - tmp_sum_error = 0 - for i in range(len(value)): - tmp_value = pow(error[i],2) - tmp_sum_error += tmp_value - - sum_error = math.sqrt(tmp_sum_error) - - return [sum_value, sum_error] - - -def integratedOverPixelDim(data_y_axis, data_y_error_axis): - - size = data_y_axis.shape - nbr_tof = size[1] - - final_data = zeros(nbr_tof) - final_data_error = zeros(nbr_tof) - for t in range(nbr_tof): - [data, error] = sumWithError(data_y_axis[:,t], data_y_error_axis[:,t]) - final_data[t] = data - final_data_error[t] = error - - return [final_data, final_data_error] - - -def fullSumWithError(data_y_axis, data_y_error_axis): - size = data_y_axis.shape - nbr_tof = size[1] - - final_data = zeros(nbr_tof) - final_data_error = zeros(nbr_tof) -# final_data = empty(nbr_tof) -# final_data_error = empty(nbr_tof) -# final_data[:] = NAN -# final_data_error[:] = NAN - for t in range(nbr_tof): - [data, error] = sumWithError(data_y_axis[:,t], data_y_error_axis[:,t]) - final_data[t] = data - final_data_error[t] = error - - return [final_data, final_data_error] - - -def ouput_ascii_file(file_name, - x_axis, - y_axis, - y_error_axis): - - f=open(file_name,'w') - - sz_x_axis = len(x_axis) - for i in range(sz_x_axis-1): - f.write(str(x_axis[i]) + "," + str(y_axis[i]) + "," + str(y_error_axis[i]) + "\n") - - f.close() - - -def ouput_big_ascii_file(file_name, - x_axis, - y_axis, - y_error_axis): - - f=open(file_name,'w') - - sz = y_axis.shape # (nbr_pixel, nbr_tof) - nbr_tof = sz[1] - nbr_pixel = sz[0] - - for t in range(nbr_tof): - _tmp_str = str(x_axis[t]) - for x in range(nbr_pixel): - _tmp_str += ' ,' + str(y_axis[x,t]) + " ," + str(y_error_axis[x,t]) - - _tmp_str += '\n' - f.write(_tmp_str) - - f.close() - - -def ouput_big_Q_ascii_file(file_name, - x_axis, - y_axis, - y_error_axis): - - f=open(file_name,'w') - - sz = y_axis.shape # (nbr_pixel, nbr_tof) - nbr_tof = sz[1] - nbr_pixel = sz[0] - - for t in range(nbr_tof): - _tmp_str = '' - for x in range(nbr_pixel): - _tmp_str += str(x_axis[x,t]) + ',' + str(y_axis[x,t]) + " ," + str(y_error_axis[x,t]) + ',,' - _tmp_str += '\n' - f.write(_tmp_str) - - f.close() - - -def divideData1DbyNormalization(inte_data_y_axis, - inte_data_y_error_axis, - av_norm, - av_norm_error): - - print('-> divide data by normalization') - - nbrPixel = inte_data_y_axis.shape - - final_data = zeros(nbrPixel) - final_data_error = zeros(nbrPixel) - - for x in range(nbrPixel[0]): - if av_norm[x] != 0: - - final_data[x] = inte_data_y_axis[x] / av_norm[x] - - tmp1 = pow(float(inte_data_y_error_axis[x]) / float(inte_data_y_axis[x]),2) - tmp2 = pow(float(av_norm_error[x]) / float(av_norm[x]),2) - tmp_error = sqrt(tmp1 + tmp2) * (float(inte_data_y_axis[x] / av_norm[x])) - - final_data_error[x] = tmp_error - - return [final_data, final_data_error] - - -def applyScalingFactor(tof_axis, - y_data, - y_data_error, - incident_medium, - sf_file, - valuePrecision, - slitsWidthFlag): - """" - function that apply scaling factor to data using sfCalculator.txt - file created by the sfCalculator procedure - """ - isSFfound = False - - #sf_file = 'NaN' - if os.path.isfile(sf_file): - - print('-> scaling factor file FOUND! (', sf_file, ')') - - #parse file and put info into array - f = open(sf_file, 'r') - sfFactorTable = [] - for line in f.read().split('\n'): - if len(line) > 0 and line[0] != '#': - sfFactorTable.append(line.split(' ')) - f.close() - - sz_table = shape(sfFactorTable) - nbr_row = sz_table[0] - - _incidentMedium = incident_medium.strip() - - _lr = getLambdaValue('ws_event_data') - _lr_value = _lr[0] - _lr_value = float("{0:.2f}".format(_lr_value)) - - #retrieve s1h and s2h or sih values - s1h = getS1h(mtd['ws_event_data']) - [isSih, s2h] = getS2h(mtd['ws_event_data']) - - s1h_value = abs(s1h) - s2h_value = abs(s2h) - - #retrieve s1w and s2w values - s1w = getS1w(mtd['ws_event_data']) - [isSiw, s2w] = getS2w(mtd['ws_event_data']) - - s1w_value = abs(s1w) - s2w_value = abs(s2w) - - print('--> Data Lambda Requested: {0:2f}'.format(_lr_value)) - print('--> Data S1H: {0:2f}'.format(s1h_value)) - if isSih: - print('--> Data SiH: {0:2f}'.format(s2h_value)) - else: - print('--> Data S2H: {0:2f}'.format(s2h_value)) - print('--> Data S1W: {0:2f}'.format(s1w_value)) - if isSiw: - print('--> Data SiW: {0:2f}'.format(s2w_value)) - else: - print('--> Data S2W: {0:2f}'.format(s2w_value)) - - for i in range(nbr_row): - - _file_incidentMedium = getFieldValue(sfFactorTable,i,0) - if _file_incidentMedium.strip() == _incidentMedium.strip(): - print('*** incident medium match ***') - _file_lambdaRequested = getFieldValue(sfFactorTable,i,1) - if (isWithinPrecisionRange(_file_lambdaRequested, - _lr_value, - valuePrecision)): - print('*** lambda requested match ***') - _file_s1h = getFieldValue(sfFactorTable,i,2) - if(isWithinPrecisionRange(_file_s1h, - s1h_value, - valuePrecision)): - print('*** s1h match ***') - _file_s2h = getFieldValue(sfFactorTable,i,3) - if(isWithinPrecisionRange(_file_s2h, - s2h_value, - valuePrecision)): - print('*** s2h match ***') - if slitsWidthFlag: - print('*** (with slits width flag) ***') - _file_s1w = getFieldValue(sfFactorTable,i,4) - if(isWithinPrecisionRange(_file_s1w, - s1w_value, - valuePrecision)): - print('*** s1w match ***') - _file_s2w = getFieldValue(sfFactorTable,i,5) - if(isWithinPrecisionRange(_file_s2w, - s2w_value, - valuePrecision)): - print('*** s2w match ***') - - print('--> Found a perfect match') - a = float(getFieldValue(sfFactorTable,i,6)) - b = float(getFieldValue(sfFactorTable,i,7)) - a_error = float(getFieldValue(sfFactorTable,i,8)) - b_error = float(getFieldValue(sfFactorTable,i,9)) - - [y_data, y_data_error] = applyScalingFactorToArray(tof_axis, - y_data, - y_data_error, - a, b, - a_error, b_error) - - return [tof_axis, y_data, y_data_error, True] - - else: - - print('--> Found a perfect match') - a = float(getFieldValue(sfFactorTable,i,6)) - b = float(getFieldValue(sfFactorTable,i,7)) - a_error = float(getFieldValue(sfFactorTable,i,8)) - b_error = float(getFieldValue(sfFactorTable,i,9)) - - [y_data, y_data_error] = applyScalingFactorToArray(tof_axis, - y_data, - y_data_error, - a, b, - a_error, b_error) - isSFfound = True - - return [tof_axis, y_data, y_data_error, isSFfound] - - else: - - print('-> scaling factor file for requested lambda NOT FOUND!') - return [tof_axis, y_data, y_data_error] - - -def applyScalingFactorToArray(tof_axis, y_data, y_data_error, a, b, a_error, b_error): - """ - This function will create for each x-axis value the corresponding - scaling factor using the formula y=a+bx and - """ - - x_axis = tof_axis - nbr_tof = len(x_axis)-1 - x_axis_factors = zeros(nbr_tof) - x_axis_factors_error = zeros(nbr_tof) -# x_axis_factors = empty(nbr_tof) -# x_axis_factors_error = empty(nbr_tof) -# x_axis_factors[:] = NAN -# x_axis_factors_error[:] = NAN - for i in range(nbr_tof): - _x_value = float(x_axis[i]) - _factor = _x_value * b + a - x_axis_factors[i] = _factor - _factor_error = _x_value * b_error + a_error - x_axis_factors_error[i] = _factor_error - - sz = y_data.shape - nbr_pixel = sz[0] - - final_y_data = zeros((nbr_pixel, nbr_tof)) - final_y_data_error = zeros((nbr_pixel, nbr_tof)) -# final_y_data = empty((nbr_pixel, nbr_tof)) -# final_y_data_error = empty((nbr_pixel, nbr_tof)) -# final_y_data[:] = NAN -# final_y_data_error[:] = NAN - for x in range(nbr_pixel): - - [ratio_array, ratio_array_error] = divideArrays(y_data[x,:], - y_data_error[x,:], - x_axis_factors, - x_axis_factors_error) - - final_y_data[x,:] = ratio_array[:] - final_y_data_error[x,:] = ratio_array_error - - return [final_y_data, final_y_data_error] - - -def divideArrays(num_array, num_error_array, den_array, den_error_array): - """ - This function calculates the ratio of two arrays and calculate the - respective error values - """ - - sz = num_array.shape - nbr_elements = sz[0] - - # calculate the ratio array - ratio_array = zeros(nbr_elements) - for i in range(nbr_elements): - if den_array[i] is 0: - _tmp_ratio = 0 - else: - _tmp_ratio = num_array[i] / den_array[i] - ratio_array[i] = _tmp_ratio - - # calculate the error of the ratio array - ratio_error_array = zeros(nbr_elements) - for i in range(nbr_elements): - - if (num_array[i] == 0) or (den_array[i] == 0): - ratio_error_array[i] = 0 - else: - tmp1 = pow(num_error_array[i] / num_array[i],2) - tmp2 = pow(den_error_array[i] / den_array[i],2) - ratio_error_array[i] = sqrt(tmp1+tmp2)*(num_array[i]/den_array[i]) - - return [ratio_array, ratio_error_array] - - -def getCentralPixel(ws_event_data, dataPeakRange, is_new_geometry): - """ - This function will calculate the central pixel position - """ - - if is_new_geometry: - _maxX = 256 - _maxY = 304 - else: - _maxX = 304 - _maxY = 256 - - pixelXtof_data = getPixelXTOF(ws_event_data, maxX=_maxX, maxY=_maxY) - pixelXtof_1d = pixelXtof_data.sum(axis=1) - # Keep only range of pixels - pixelXtof_roi = pixelXtof_1d[dataPeakRange[0]:dataPeakRange[1]] - sz = pixelXtof_roi.size - _num = 0 - _den = 0 - start_pixel = dataPeakRange[0] - for i in range(sz): - _num += (start_pixel * pixelXtof_roi[i]) - start_pixel = start_pixel + 1 - _den += pixelXtof_roi[i] - data_cpix = _num / _den - print('--> central pixel is {0:.1f}'.format(data_cpix)) - - return data_cpix - - -def getDistances(ws_event_data): - """ - calculates the distance between the moderator and the detector (dMD) - and the distance between the sample and the detector - """ - - print('--> calculating dMD (moderator-detector) and dSD (sample-detector)') - sample = ws_event_data.getInstrument().getSample() - source = ws_event_data.getInstrument().getSource() - dSM = sample.getDistance(source) - - # Create array of distances pixel->sample - dPS_array = zeros((256, 304)) - for x in range(304): - for y in range(256): - _index = 256 * x + y - detector = ws_event_data.getDetector(_index) - dPS_array[y, x] = sample.getDistance(detector) - - # Distance sample->center of detector - dSD = dPS_array[256//2,304//2] - # Distance source->center of detector - dMD = dSD + dSM - - return [dMD, dSD] - - -def getTheta(ws_event_data, angleOffsetDeg): - """ - will calculate the theta angle offset - """ - print('--> retrieving thi and tthd') - mt_run = ws_event_data.getRun() - thi_value = mt_run.getProperty('thi').value[0] - thi_units = mt_run.getProperty('thi').units - tthd_value = mt_run.getProperty('tthd').value[0] - tthd_units = mt_run.getProperty('tthd').units - thi_rad = angleUnitConversion(value=thi_value, - from_units=thi_units, - to_units='rad') - print('---> thi (rad): ', thi_rad) - tthd_rad = angleUnitConversion(value=tthd_value, - from_units=tthd_units, - to_units='rad') - print('---> tthd (rad): ', tthd_rad) - - theta = math.fabs(tthd_rad - thi_rad)/2. - angleOffsetRad = (angleOffsetDeg * math.pi) / 180. - theta += angleOffsetRad - print('---> theta (rad): ', theta) - - return theta - - -def getSlitsSize(mt): - print('---> retrieving slits size') - first_slit_size = getSheight(mt, '1') - last_slit_size = getSheight(mt,'2') - print('----> first_slit_size: ' , first_slit_size) - print('----> last_slit_size: ' , last_slit_size) - return [first_slit_size, last_slit_size] - - -def getQrange(ws_histo_data, theta, dMD, q_min, q_step): - """ - will determine the true q axis according to the qMin and qStep specified - and the geometry of the instrument - """ - print('---> calculating Qrange') - _tof_axis = ws_histo_data.readX(0) - _const = float(4) * math.pi * m * dMD / h - sz_tof = shape(_tof_axis)[0] - _q_axis = zeros(sz_tof-1) - for t in range(sz_tof-1): - tof1 = _tof_axis[t] - tof2 = _tof_axis[t+1] - tofm = (tof1+tof2)/2. - _Q = _const * math.sin(theta) / (tofm*1e-6) - _q_axis[t] = _Q*1e-10 - q_max = max(_q_axis) - if q_min >= q_max: - q_min = min(_q_axis) - print('----> q_min: ', q_min) - print('----> q_step: ', q_step) - print('----> q_max: ', q_max) - - return [q_min, q_step, q_max] - - -def convertToQ(tof_axis, - y_axis, - y_error_axis, - peak_range = None, - central_pixel = None, - source_to_detector_distance = None, - sample_to_detector_distance = None, - theta = None, - first_slit_size = None, - last_slit_size = None): - """ - will convert the tof_axis into q_axis according to q range specified - """ - - y_size = (peak_range[1] - peak_range[0] + 1) - y_range = arange(y_size) + peak_range[0] - _q_axis = getQaxis(source_to_detector_distance, - sample_to_detector_distance, - theta, - tof_axis, - y_range, - central_pixel, - first_slit_size, - last_slit_size) - - _q_axis_min_max_index = findQaxisMinMax(_q_axis) - - # now we need to put the various counts from y_axis into the right - # boxes - _y_axis = zeros((y_size, len(tof_axis)-1)) - _y_error_axis = zeros((y_size, len(tof_axis)-1)) -# _y_axis = empty((y_size, len(tof_axis)-1)) -# _y_error_axis = empty((y_size, len(tof_axis)-1)) -# _y_axis[:] = NAN -# _y_error_axis[:] = NAN - - # now determine the _y_axis and _y_error_axis - for _y_index in range(y_size): - - # get the q_axis of the given peak pixel - _tmp_q_axis = _q_axis[_y_index] - _q_axis = _tmp_q_axis[::-1] #reverse the axis (now in increasing order) - - _y_axis_tmp = y_axis[_y_index,:] - _y_error_axis_tmp = y_error_axis[_y_index,:] - - # keep only the overlap region of Qs - _q_min = _q_axis_min_max_index[_y_index, 0] - if _q_min != 0: - _y_axis_tmp[0:_q_min] = 0 - _y_error_axis_tmp[0:_q_min] = 0 - - _q_max = int(_q_axis_min_max_index[_y_index, 1]) - sz = shape(_y_axis_tmp)[0] - if _q_max != sz: - _index_q_max_range = arange(sz - _q_max) + _q_max - for i in _index_q_max_range: - _y_axis_tmp[i] = 0 - _y_error_axis_tmp[i] = 0 - - _y_axis[_y_index, :] = _y_axis_tmp[::-1] - _y_error_axis[_y_index, :] = _y_error_axis_tmp[::-1] - - # reverse the _q_axis here as well - q_axis_reverse = reverseQAxis(_q_axis) - - return [q_axis_reverse, _y_axis, _y_error_axis] - - -def convertToQWithoutCorrection(tof_axis, - y_axis, - y_error_axis, - peak_range = None, - source_to_detector_distance = None, - sample_to_detector_distance = None, - theta = None, - first_slit_size = None, - last_slit_size = None): - """ - will convert the tof_axis into q_axis according to q range specified - but without using any geometry correction - """ - - _const = float(4) * math.pi * m * source_to_detector_distance / h - _q_axis = 1e-10 * _const * math.sin(theta) / (tof_axis[0:-1] * 1e-6) - - sz = y_axis.shape - nbr_pixel = sz[0] - - sz_q_axis = _q_axis.shape - nbr_q = sz_q_axis[0] - - q_axis_2d = zeros((nbr_pixel, nbr_q)) - for p in range(nbr_pixel): - q_axis_2d[p,:] = _q_axis - - q_axis_reverse = reverseQAxis(q_axis_2d) - y_axis_reverse = fliplr(y_axis) - y_error_axis_reverse = fliplr(y_error_axis) - - return [q_axis_reverse, y_axis_reverse, y_error_axis_reverse] - - -def reverseQAxis(q_axis): - """ - will reverse each q_axis for the respective pixels - """ - new_q_axis = fliplr(q_axis) - return new_q_axis - - -def getQaxis(dMD, dSD, theta, - tof_axis, y_range, central_pixel, - first_slit_size, - last_slit_size): - """ - This function converts the pixel/TOF array to the R(Q) array - using Q = (4.Pi.Mn)/h * L.sin(theta/2)/TOF - with L: distance central_pixel->source - TOF: TOF of pixel - theta: angle of detector - """ - - _const = float(4) * math.pi * m * dMD / h - sz_tof = len(tof_axis) - q_array = zeros((len(y_range), sz_tof)) - - for y in range(len(y_range)): - _px = y_range[y] - dangle = ref_beamdiv_correct(central_pixel, - dSD, - _px, - 0.0007, - first_slit_size, - last_slit_size) - - if dangle is not None: - _theta = theta + dangle - else: - _theta = theta - - for t in range(sz_tof): -# tof1 = tof_axis[t] -# tof2 = tof_axis[t+1] -# tofm = (tof1+tof2)/2. - tof = tof_axis[t] -# _Q = _const * math.sin(_theta) / (tofm*1e-6) - _Q = _const * math.sin(_theta) / (tof*1e-6) - q_array[y, t] = _Q * 1e-10 - - return q_array - - -def integrateOverPeakRange(wks, dataPeakRange): - """ - getting just the mean of the peak - """ - - final_x_axis = wks.readX(0)[:] - sz = final_x_axis.shape - nbr_q = sz[0] - - # make temp big array - nbrPixel = dataPeakRange[1] - dataPeakRange[0] + 1 - bigY = zeros((nbrPixel, nbr_q)) - bigE = zeros((nbrPixel, nbr_q)) -# bigY = empty((nbrPixel, nbr_q)) -# bigE = empty((nbrPixel, nbr_q)) -# bigY[:]= NAN -# bigE[:]= NAN - for x in range(nbrPixel): - _tmp_y = wks.readY(x)[:] - bigY[x,:] = _tmp_y - _tmp_e = wks.readE(x)[:] - bigE[x,:] = _tmp_e - - final_y_axis = zeros(nbr_q) - final_y_error_axis = zeros(nbr_q) -# -# final_y_axis = empty(nbr_q) -# final_y_error_axis = empty(nbr_q) -# final_y_axis[:] = NAN -# final_y_error_axis[:] = NAN - - # range(nbr_q -2) + 1 to get rid of first and last q values (edge effect) - rangeOfQ = arange(nbr_q-1) -# for q in rangeOfQ[1:-1]: - for q in rangeOfQ: - - _tmp_y = bigY[:,q] - _tmp_y_error = bigE[:,q] - -# [_y, _y_error] = myMean(_tmp_y, _tmp_y_error) - [_y, _y_error] = sumWithError(_tmp_y, _tmp_y_error) - - final_y_axis[q] = _y - final_y_error_axis[q] = _y_error - - return [final_x_axis, final_y_axis, final_y_error_axis] - - -def createQworkspace(q_axis, y_axis, y_error_axis): - - sz = q_axis.shape - nbr_pixel = sz[0] - - q_axis_1d = q_axis.flatten() - y_axis_1d = y_axis.flatten() - y_error_axis_1d = y_error_axis.flatten() - - q_workspace = CreateWorkspace(DataX=q_axis_1d, - DataY=y_axis_1d, - DataE=y_error_axis_1d, - Nspec=nbr_pixel, - UnitX="Wavelength") - q_workspace.setDistribution(True) - - return q_workspace - - -def createFinalWorkspace(q_axis, final_y_axis, final_error_axis, name_output_ws, parent_workspace): - - final_workspace = CreateWorkspace(OutputWorkspace=name_output_ws, - DataX=q_axis, - DataY=final_y_axis, - DataE=final_error_axis, - Nspec=1, - UnitX="Wavelength", - ParentWorkspace=parent_workspace) - final_workspace.setDistribution(True) - - return final_workspace - - -def cropAxisToOnlyNonzeroElements(q_rebin, dataPeakRange): - """ - This function will only keep the range of Q that have only nonzero counts - """ - nbrPixel = dataPeakRange[1] - dataPeakRange[0] + 1 - - x_axis = q_rebin.readX(0)[:] - sz = x_axis.shape[0]-1 - - index_first_non_zero_value = sz - index_last_non_zero_value = 0 - - for x in range(nbrPixel): - _pixel_axis = q_rebin.readY(x)[:] - - for t in range(sz): - _value = _pixel_axis[t] - if _value != float(0): - if index_first_non_zero_value > t: - index_first_non_zero_value = t - break - - for t in range(sz-1,-1,-1): - _value = _pixel_axis[t] - if _value != float(0): - if index_last_non_zero_value < t: - index_last_non_zero_value = t - break - - # crop data - new_x_axis = x_axis[index_first_non_zero_value:index_last_non_zero_value+1] - new_xrange = index_last_non_zero_value - index_first_non_zero_value + 1 - - new_y_axis = zeros((nbrPixel, new_xrange)) - new_y_error_axis = zeros((nbrPixel, new_xrange)) -# new_y_axis = empty((nbrPixel, new_xrange)) -# new_y_error_axis = empty((nbrPixel, new_xrange)) -# new_y_axis[:] = NAN -# new_y_error_axis[:] = NAN - - for x in range(nbrPixel): - _tmp = q_rebin.readY(x)[:] - _tmp_E = q_rebin.readE(x)[:] - new_y_axis[x,:] = _tmp[index_first_non_zero_value:index_last_non_zero_value+1] - new_y_error_axis[x,:] = _tmp_E[index_first_non_zero_value:index_last_non_zero_value+1] - - new_y_axis = new_y_axis.flatten() - new_y_error_axis = new_y_error_axis.flatten() - - new_x_axis = asfarray(new_x_axis) - new_y_axis = asfarray(new_y_axis) - new_y_error_axis = asfarray(new_y_error_axis) - - nonzero_q_rebin_wks = CreateWorkspace(DataX=new_x_axis, - DataY=new_y_axis, - DataE=new_y_error_axis, - Nspec=int(nbrPixel), - UnitX="Wavelength") - - return nonzero_q_rebin_wks - - -def cleanupData(final_data_y_axis, final_data_y_error_axis): - - sz = final_data_y_axis.shape - nbrPixel = sz[0] - nbrQ = sz[1] - - for x in range(nbrPixel): - for q in range(nbrQ): - - _data = final_data_y_axis[x,q] - _error = final_data_y_error_axis[x,q] - - # if error is > value, remove point - if _error >= _data: - _data = 0 - _error = 1 - - # if value is below 10^-12 - if _data < 1e-12: - _data = 0 - _error = 1 - - final_data_y_axis[x,q] = _data - final_data_y_error_axis[x,q] = _error - - return [final_data_y_axis, final_data_y_error_axis] - - -def cleanupData1D(final_data_y_axis, final_data_y_error_axis): - - sz = final_data_y_axis.shape - nbrTof = sz[0] - - notYetRemoved = True - - for t in range(nbrTof): - - _data = final_data_y_axis[t] - _error = final_data_y_error_axis[t] - - if _data > 0 and notYetRemoved: - notYetRemoved = False - final_data_y_axis[t] = 0 - final_data_y_error_axis[t] = 1 - continue - - # if error is > value, remove point - if abs(_error) >= abs(_data): - _data_tmp = 0 - _error_tmp = 1 - elif _data< 1e-12: - # if value is below 10^-12 - _data_tmp = 0 - _error_tmp = 1 - else: - _data_tmp = _data - _error_tmp = _error - - final_data_y_axis[t] = _data_tmp - final_data_y_error_axis[t] = _error_tmp - -# print('final_data_y_axis[t]: ' , _data_tmp , ' final_data_y_error_axis[t]: ' , _error_tmp) - - return [final_data_y_axis, final_data_y_error_axis] - - -def isNexusTakeAfterRefDate(nexus_date): - ''' - This function parses the output.date and returns true if this date is after the ref date - ''' - nexus_date_acquistion = nexus_date.split('T')[0] - - if nexus_date_acquistion > ref_date: - return True - else: - return False -- GitLab