#include "MantidAlgorithms/CreateTransmissionWorkspace2.h" #include "MantidAPI/WorkspaceUnitValidator.h" #include "MantidKernel/MandatoryValidator.h" using namespace Mantid::Kernel; using namespace Mantid::API; namespace Mantid { namespace Algorithms { // Register the algorithm into the AlgorithmFactory DECLARE_ALGORITHM(CreateTransmissionWorkspace2) //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name const std::string CreateTransmissionWorkspace2::name() const { return "CreateTransmissionWorkspace"; } /// Summary of algorithm's purpose const std::string CreateTransmissionWorkspace2::summary() const { return "Creates a transmission run workspace in wavelength from one or two " "input workspaces in TOF."; } /// Algorithm's version for identification. @see Algorithm::version int CreateTransmissionWorkspace2::version() const { return 2; } /// Algorithm's category for identification. @see Algorithm::category const std::string CreateTransmissionWorkspace2::category() const { return "Reflectometry"; } //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- /** Initialize the algorithm's properties. */ void CreateTransmissionWorkspace2::init() { auto inputValidator = boost::make_shared<WorkspaceUnitValidator>("TOF"); declareProperty(make_unique<WorkspaceProperty<MatrixWorkspace>>( "FirstTransmissionRun", "", Direction::Input, PropertyMode::Mandatory, inputValidator->clone()), "First transmission run. Corresponds to the low wavelength " "transmision run if a SecondTransmissionRun is also " "provided."); declareProperty(make_unique<WorkspaceProperty<MatrixWorkspace>>( "SecondTransmissionRun", "", Direction::Input, PropertyMode::Optional, inputValidator->clone()), "High wavelength transmission run. Optional. Causes the " "first transmission run to be treated as the low wavelength " "transmission run."); declareProperty(Kernel::make_unique<PropertyWithValue<std::string>>( "ProcessingInstructions", "", boost::make_shared<MandatoryValidator<std::string>>(), Direction::Input), "Grouping pattern on workspace indexes to yield only " "the detectors of interest. See GroupDetectors for details."); declareProperty(make_unique<PropertyWithValue<double>>( "WavelengthMin", Mantid::EMPTY_DBL(), boost::make_shared<MandatoryValidator<double>>(), Direction::Input), "Wavelength minimum in angstroms"); declareProperty(make_unique<PropertyWithValue<double>>( "WavelengthMax", Mantid::EMPTY_DBL(), boost::make_shared<MandatoryValidator<double>>(), Direction::Input), "Wavelength maximum in angstroms"); initMonitorProperties(); initStitchProperties(); declareProperty(make_unique<WorkspaceProperty<MatrixWorkspace>>( "OutputWorkspace", "", Direction::Output), "Output workspace in wavelength."); } /** Validate inputs * @return :: error message to show */ std::map<std::string, std::string> CreateTransmissionWorkspace2::validateInputs() { std::map<std::string, std::string> results; // Validate wavelength range // Validate monitor background range // Validate monitor integration range const auto wavelength = validateWavelengthRanges(); results.insert(wavelength.begin(), wavelength.end()); return results; } //---------------------------------------------------------------------------------------------- /** Execute the algorithm. */ void CreateTransmissionWorkspace2::exec() { MatrixWorkspace_sptr firstTransWS = getProperty("FirstTransmissionRun"); firstTransWS = normalizeDetectorsByMonitors(firstTransWS); firstTransWS = cropWavelength(firstTransWS); MatrixWorkspace_sptr secondTransWS = getProperty("SecondTransmissionRun"); if (secondTransWS) { secondTransWS = normalizeDetectorsByMonitors(secondTransWS); secondTransWS = cropWavelength(secondTransWS); // Stitch the results. auto stitch = createChildAlgorithm("Stitch1D"); stitch->initialize(); stitch->setProperty("LHSWorkspace", firstTransWS); stitch->setProperty("RHSWorkspace", secondTransWS); stitch->setPropertyValue("StartOverlap", getPropertyValue("StartOverlap")); stitch->setPropertyValue("EndOverlap", getPropertyValue("EndOverlap")); stitch->setPropertyValue("Params", getPropertyValue("Params")); stitch->execute(); MatrixWorkspace_sptr outWS = stitch->getProperty("OutputWorkspace"); setProperty("OutputWorkspace", outWS); } else { setProperty("OutputWorkspace", firstTransWS); } } /** Normalize detectors by monitors * @param IvsLam :: a workspace in wavelength that contains spectra for both * monitors and detectors * @return :: the normalized workspace */ MatrixWorkspace_sptr CreateTransmissionWorkspace2::normalizeDetectorsByMonitors( const MatrixWorkspace_sptr IvsLam) { // Detector workspace MatrixWorkspace_sptr detectorWS = makeDetectorWS(IvsLam); // Monitor workspace // Only if I0MonitorIndex, MonitorBackgroundWavelengthMin // and MonitorBackgroundWavelengthMax have been given Property *monProperty = getProperty("I0MonitorIndex"); Property *backgroundMinProperty = getProperty("MonitorBackgroundWavelengthMin"); Property *backgroundMaxProperty = getProperty("MonitorBackgroundWavelengthMin"); if (monProperty->isDefault() || backgroundMinProperty->isDefault() || backgroundMaxProperty->isDefault()) { return detectorWS; } // Normalization by integrated monitors // Only if both MonitorIntegrationWavelengthMin and // MonitorIntegrationWavelengthMax are have been given Property *intMinProperty = getProperty("MonitorIntegrationWavelengthMin"); Property *intMaxProperty = getProperty("MonitorIntegrationWavelengthMax"); const bool integratedMonitors = !(intMinProperty->isDefault() || intMaxProperty->isDefault()); auto monitorWS = makeMonitorWS(IvsLam, integratedMonitors); if (!integratedMonitors) detectorWS = rebinDetectorsToMonitors(detectorWS, monitorWS); return divide(detectorWS, monitorWS); } } // namespace Algorithms } // namespace Mantid