Skip to content
Snippets Groups Projects
Commit 78ea6b4f authored by Savici, Andrei T.'s avatar Savici, Andrei T.
Browse files

Merge remote-tracking branch 'origin/feature/10462_sxdmdnorm_integration'

parents 12b36ad3 b000bd8c
No related merge requests found
Showing
with 861 additions and 117 deletions
...@@ -369,6 +369,44 @@ private: ...@@ -369,6 +369,44 @@ private:
} }
}; };
//===============================================================================================
/**
* A validator which checks whether data in each spectrum of the input workspace are monotonically increasing.
*/
class DLLExport IncreasingDataValidator : public MatrixWorkspaceValidator
{
public:
///Gets the type of the validator
std::string getType() const { return "increasingdata"; }
/// Clone the current state
Kernel::IValidator_sptr clone() const { return boost::make_shared<IncreasingDataValidator>(*this); }
private:
/** Validate a workspace.
* @param value :: The workspace to test
* @return A message for users with negative results, otherwise ""
*/
std::string checkValidity( const MatrixWorkspace_sptr& value ) const
{
if ( value->blocksize() < 2 )
{
return "Spectra must have two or more data points (bins).";
}
for(size_t spec = 0; spec < value->getNumberHistograms(); ++spec)
{
auto &Y = value->readY( spec );
double y = Y.front();
for(auto it = Y.begin() + 1; it != Y.end(); ++it)
{
if ( y > *it ) return "Data in the workspace must monotonically increase.";
y = *it;
}
}
return "";
}
};
} // namespace API } // namespace API
} // namespace Mantid } // namespace Mantid
......
...@@ -28,6 +28,7 @@ set ( SRC_FILES ...@@ -28,6 +28,7 @@ set ( SRC_FILES
src/FindPeaksMD.cpp src/FindPeaksMD.cpp
src/GreaterThanMD.cpp src/GreaterThanMD.cpp
src/IDynamicRebinning.cpp src/IDynamicRebinning.cpp
src/IntegrateFlux.cpp
src/IntegratePeaksMD.cpp src/IntegratePeaksMD.cpp
src/IntegratePeaksMD2.cpp src/IntegratePeaksMD2.cpp
src/InvalidParameter.cpp src/InvalidParameter.cpp
...@@ -63,7 +64,7 @@ set ( SRC_FILES ...@@ -63,7 +64,7 @@ set ( SRC_FILES
src/Quantification/Resolution/TobyFitYVector.cpp src/Quantification/Resolution/TobyFitYVector.cpp
src/Quantification/ResolutionConvolvedCrossSection.cpp src/Quantification/ResolutionConvolvedCrossSection.cpp
src/Quantification/SimulateResolutionConvolvedModel.cpp src/Quantification/SimulateResolutionConvolvedModel.cpp
src/SXDMDNorm.cpp src/MDNormSXD.cpp
src/SaveMD.cpp src/SaveMD.cpp
src/SaveZODS.cpp src/SaveZODS.cpp
src/SetMDUsingMask.cpp src/SetMDUsingMask.cpp
...@@ -103,13 +104,14 @@ set ( INC_FILES ...@@ -103,13 +104,14 @@ set ( INC_FILES
inc/MantidMDAlgorithms/DivideMD.h inc/MantidMDAlgorithms/DivideMD.h
inc/MantidMDAlgorithms/DllConfig.h inc/MantidMDAlgorithms/DllConfig.h
inc/MantidMDAlgorithms/EqualToMD.h inc/MantidMDAlgorithms/EqualToMD.h
inc/MantidMDAlgorithms/ExponentialMD.h
inc/MantidMDAlgorithms/EvaluateMDFunction.h inc/MantidMDAlgorithms/EvaluateMDFunction.h
inc/MantidMDAlgorithms/ExponentialMD.h
inc/MantidMDAlgorithms/FakeMDEventData.h inc/MantidMDAlgorithms/FakeMDEventData.h
inc/MantidMDAlgorithms/FindPeaksMD.h inc/MantidMDAlgorithms/FindPeaksMD.h
inc/MantidMDAlgorithms/GSLFunctions.h inc/MantidMDAlgorithms/GSLFunctions.h
inc/MantidMDAlgorithms/GreaterThanMD.h inc/MantidMDAlgorithms/GreaterThanMD.h
inc/MantidMDAlgorithms/IDynamicRebinning.h inc/MantidMDAlgorithms/IDynamicRebinning.h
inc/MantidMDAlgorithms/IntegrateFlux.h
inc/MantidMDAlgorithms/IntegratePeaksMD.h inc/MantidMDAlgorithms/IntegratePeaksMD.h
inc/MantidMDAlgorithms/IntegratePeaksMD2.h inc/MantidMDAlgorithms/IntegratePeaksMD2.h
inc/MantidMDAlgorithms/InvalidParameter.h inc/MantidMDAlgorithms/InvalidParameter.h
...@@ -145,7 +147,7 @@ set ( INC_FILES ...@@ -145,7 +147,7 @@ set ( INC_FILES
inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitYVector.h inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitYVector.h
inc/MantidMDAlgorithms/Quantification/ResolutionConvolvedCrossSection.h inc/MantidMDAlgorithms/Quantification/ResolutionConvolvedCrossSection.h
inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h
inc/MantidMDAlgorithms/SXDMDNorm.h inc/MantidMDAlgorithms/MDNormSXD.h
inc/MantidMDAlgorithms/SaveMD.h inc/MantidMDAlgorithms/SaveMD.h
inc/MantidMDAlgorithms/SaveZODS.h inc/MantidMDAlgorithms/SaveZODS.h
inc/MantidMDAlgorithms/SetMDUsingMask.h inc/MantidMDAlgorithms/SetMDUsingMask.h
...@@ -186,13 +188,14 @@ set ( TEST_FILES ...@@ -186,13 +188,14 @@ set ( TEST_FILES
CreateMDWorkspaceTest.h CreateMDWorkspaceTest.h
DivideMDTest.h DivideMDTest.h
EqualToMDTest.h EqualToMDTest.h
ExponentialMDTest.h
EvaluateMDFunctionTest.h EvaluateMDFunctionTest.h
ExponentialMDTest.h
FakeMDEventDataTest.h FakeMDEventDataTest.h
FindPeaksMDTest.h FindPeaksMDTest.h
FitResolutionConvolvedModelTest.h FitResolutionConvolvedModelTest.h
ForegroundModelTest.h ForegroundModelTest.h
GreaterThanMDTest.h GreaterThanMDTest.h
IntegrateFluxTest.h
IntegratePeaksMD2Test.h IntegratePeaksMD2Test.h
IntegratePeaksMDTest.h IntegratePeaksMDTest.h
InvalidParameterParserTest.h InvalidParameterParserTest.h
...@@ -215,7 +218,7 @@ set ( TEST_FILES ...@@ -215,7 +218,7 @@ set ( TEST_FILES
PowerMDTest.h PowerMDTest.h
PreprocessDetectorsToMDTest.h PreprocessDetectorsToMDTest.h
ResolutionConvolvedCrossSectionTest.h ResolutionConvolvedCrossSectionTest.h
SXDMDNormTest.h MDNormSXDTest.h
SaveMDTest.h SaveMDTest.h
SaveZODSTest.h SaveZODSTest.h
SetMDUsingMaskTest.h SetMDUsingMaskTest.h
......
#ifndef MANTID_MDALGORITHMS_INTEGRATEFLUX_H_
#define MANTID_MDALGORITHMS_INTEGRATEFLUX_H_
#include "MantidKernel/System.h"
#include "MantidAPI/Algorithm.h"
namespace Mantid
{
namespace DataObjects
{
class EventWorkspace;
}
namespace MDAlgorithms
{
/** Algorithm IntegrateFlux.
Calculates indefinite integral of the spectra in the input workspace sampled at a regular grid.
The input workspace is expected to be an event workspace with weighted-no-time events.
Copyright &copy; 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
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 IntegrateFlux : public API::Algorithm
{
public:
virtual const std::string name() const;
virtual int version() const;
virtual const std::string category() const;
virtual const std::string summary() const;
private:
void init();
void exec();
boost::shared_ptr<API::MatrixWorkspace> createOutputWorkspace( const DataObjects::EventWorkspace& eventWS, size_t nX ) const;
void integrateSpectra( const DataObjects::EventWorkspace& eventWS, API::MatrixWorkspace &integrWS );
};
} // namespace MDAlgorithms
} // namespace Mantid
#endif /* MANTID_MDALGORITHMS_INTEGRATEFLUX_H_ */
\ No newline at end of file
#ifndef MANTID_MDALGORITHMS_SXDMDNORM_H_ #ifndef MANTID_MDALGORITHMS_MDNORMSXD_H_
#define MANTID_MDALGORITHMS_SXDMDNORM_H_ #define MANTID_MDALGORITHMS_MDNORMSXD_H_
#include "MantidKernel/System.h" #include "MantidKernel/System.h"
#include "MantidAPI/Algorithm.h" #include "MantidAPI/Algorithm.h"
#include "MantidMDAlgorithms/SlicingAlgorithm.h" #include "MantidMDAlgorithms/SlicingAlgorithm.h"
namespace Mantid namespace Mantid
{ {
namespace DataObjects
{
class EventWorkspace;
}
namespace MDAlgorithms namespace MDAlgorithms
{ {
/** SXDMDNorm : Generate MD normalization for single crystal diffraction /** MDNormSXD : Generate MD normalization for single crystal diffraction
Copyright &copy; 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory Copyright &copy; 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
...@@ -31,13 +35,11 @@ namespace MDAlgorithms ...@@ -31,13 +35,11 @@ namespace MDAlgorithms
File change history is stored at: <https://github.com/mantidproject/mantid> File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org> Code Documentation is available at: <http://doxygen.mantidproject.org>
*/ */
bool compareMomentum(Mantid::Kernel::VMD v1, Mantid::Kernel::VMD v2); class DLLExport MDNormSXD :public SlicingAlgorithm
class DLLExport SXDMDNorm :public SlicingAlgorithm
{ {
public: public:
SXDMDNorm(); MDNormSXD();
virtual ~SXDMDNorm(); virtual ~MDNormSXD();
virtual const std::string name() const; virtual const std::string name() const;
virtual int version() const; virtual int version() const;
...@@ -50,6 +52,11 @@ namespace MDAlgorithms ...@@ -50,6 +52,11 @@ namespace MDAlgorithms
/// function to calculate intersections of teh trajectory with MDBoxes /// function to calculate intersections of teh trajectory with MDBoxes
std::vector<Mantid::Kernel::VMD> calculateIntersections(Mantid::Geometry::IDetector_const_sptr detector); std::vector<Mantid::Kernel::VMD> calculateIntersections(Mantid::Geometry::IDetector_const_sptr detector);
/// Integrate flux spectra
void integrateFlux( const DataObjects::EventWorkspace& flux, API::MatrixWorkspace &integrFlux );
/// Use interpolation to calculate integrals
void calcIntegralsForIntersections( const std::vector<double> &xValues, const API::MatrixWorkspace &integrFlux, size_t sp, std::vector<double> &yValues ) const;
/// number of MD dimensions /// number of MD dimensions
size_t m_nDims; size_t m_nDims;
/// Normalization workspace /// Normalization workspace
...@@ -74,4 +81,4 @@ namespace MDAlgorithms ...@@ -74,4 +81,4 @@ namespace MDAlgorithms
} // namespace MDAlgorithms } // namespace MDAlgorithms
} // namespace Mantid } // namespace Mantid
#endif /* MANTID_MDALGORITHMS_SXDMDNORM_H_ */ #endif /* MANTID_MDALGORITHMS_MDNORMSXD_H_ */
#include "MantidMDAlgorithms/IntegrateFlux.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidKernel/BoundedValidator.h"
#include <boost/make_shared.hpp>
namespace Mantid
{
namespace MDAlgorithms
{
using Mantid::Kernel::Direction;
using Mantid::API::WorkspaceProperty;
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(IntegrateFlux)
namespace{
/// Void deleter for shared pointers
class NoEventWorkspaceDeleting
{
public:
/// deleting operator. Does nothing
void operator()(const DataObjects::EventWorkspace*){}
};
}
//----------------------------------------------------------------------------------------------
/// Algorithms name for identification. @see Algorithm::name
const std::string IntegrateFlux::name() const { return "IntegrateFlux"; }
/// Algorithm's version for identification. @see Algorithm::version
int IntegrateFlux::version() const { return 1;};
/// Algorithm's category for identification. @see Algorithm::category
const std::string IntegrateFlux::category() const { return "MDAlgorithms";}
/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
const std::string IntegrateFlux::summary() const { return "Interates spectra in a matrix workspace at a set of points.";};
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void IntegrateFlux::init()
{
declareProperty(new WorkspaceProperty<DataObjects::EventWorkspace>("InputWorkspace","",Direction::Input), "An input workspace.");
auto validator = boost::make_shared<Kernel::BoundedValidator<int>>();
validator->setLower(2);
declareProperty("NPoints", 1000, validator, "Number of points per output spectrum.");
declareProperty(new WorkspaceProperty<API::Workspace>("OutputWorkspace","",Direction::Output), "An output workspace.");
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void IntegrateFlux::exec()
{
DataObjects::EventWorkspace_sptr inputWS = getProperty("InputWorkspace");
size_t nX = static_cast<size_t>( (int)getProperty("NPoints") );
auto outputWS = createOutputWorkspace( *inputWS, nX );
integrateSpectra( *inputWS, *outputWS );
setProperty("OutputWorkspace",outputWS);
}
/**
* Create an empty output workspace with required dimensions and defined x-values
* @param eventWS :: The input event workspace.
* @param nX :: Suggested size of the output spectra. It can change in the actual output.
*/
boost::shared_ptr<API::MatrixWorkspace> IntegrateFlux::createOutputWorkspace( const DataObjects::EventWorkspace& eventWS, size_t nX ) const
{
size_t nSpec = eventWS.getNumberHistograms();
if ( nSpec == 0 )
{
throw std::runtime_error("Input workspace has no data.");
}
// make sure the output spectrum size isn't too large
auto nEvents = eventWS.getEventList(0).getNumberEvents();
if ( nX > nEvents )
{
nX = nEvents;
}
// and not 0 or 1 as they are to be used for interpolation
if ( nX < 2 )
{
throw std::runtime_error("Failed to create output."
"Output spectra should have at least two points.");
}
// crate empty output workspace
API::MatrixWorkspace_sptr ws = API::WorkspaceFactory::Instance().create(
boost::shared_ptr<const DataObjects::EventWorkspace>(&eventWS,NoEventWorkspaceDeleting()),
nSpec, nX, nX );
// claculate the integration points and save them in the x-vactors of integrFlux
double xMin = eventWS.getEventXMin();
double xMax = eventWS.getEventXMax();
double dx = ( xMax - xMin ) / static_cast<double>( nX - 1 );
auto &X = ws->dataX(0);
auto ix = X.begin();
// x-values are equally spaced between the min and max tof in the first flux spectrum
for(double x = xMin; ix != X.end(); ++ix, x += dx)
{
*ix = x;
}
// share the xs for all spectra
auto xRef = ws->refX(0);
for(size_t sp = 1; sp < nSpec; ++sp)
{
ws->setX(sp,xRef);
}
return ws;
}
/**
* Integrate spectra in eventWS at x-values in integrWS and save the results in y-vectors of integrWS.
* @param eventWS :: A workspace to integrate. The events have to be weighted-no-time.
* @param integrWS :: A workspace to store the results.
*/
void IntegrateFlux::integrateSpectra( const DataObjects::EventWorkspace& eventWS, API::MatrixWorkspace &integrWS )
{
size_t nSpec = eventWS.getNumberHistograms();
assert( nSpec == integrWS.getNumberHistograms() );
auto &X = integrWS.readX(0);
// loop overr the spectra and integrate
for(size_t sp = 0; sp < nSpec; ++sp)
{
std::vector<Mantid::DataObjects::WeightedEventNoTime> el = eventWS.getEventList(sp).getWeightedEventsNoTime();
auto &outY = integrWS.dataY(sp);
double sum = 0;
auto x = X.begin() + 1;
size_t i = 1;
// the integral is a running sum of the event weights in the spectrum
for(auto evnt = el.begin(); evnt != el.end(); ++evnt)
{
double tof = evnt->tof();
while( x != X.end() && *x < tof )
{
outY[i] = sum;
++x; ++i;
}
if ( x == X.end() ) break;
sum += evnt->weight();
outY[i] = sum;
}
}
}
} // namespace MDAlgorithms
} // namespace Mantid
\ No newline at end of file
#include "MantidMDAlgorithms/SXDMDNorm.h" #include "MantidMDAlgorithms/MDNormSXD.h"
#include "MantidMDEvents/MDEventWorkspace.h" #include "MantidMDEvents/MDEventWorkspace.h"
#include "MantidMDEvents/MDHistoWorkspace.h" #include "MantidMDEvents/MDHistoWorkspace.h"
#include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/WorkspaceValidators.h"
...@@ -16,21 +16,28 @@ namespace MDAlgorithms ...@@ -16,21 +16,28 @@ namespace MDAlgorithms
using namespace Mantid::API; using namespace Mantid::API;
using namespace Mantid::Kernel; using namespace Mantid::Kernel;
namespace{
///function to compare two intersections (h,k,l,Momentum) by Momentum ///function to compare two intersections (h,k,l,Momentum) by Momentum
bool compareMomentum(const Mantid::Kernel::VMD &v1, const Mantid::Kernel::VMD &v2) bool compareMomentum(const Mantid::Kernel::VMD &v1, const Mantid::Kernel::VMD &v2)
{ {
return (v1[3]<v2[3]); return (v1[3]<v2[3]);
} }
// size of the interpolation tables for the integrated flux spectra
const size_t interpolationSize = 1000;
}
// Register the algorithm into the AlgorithmFactory // Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(SXDMDNorm) DECLARE_ALGORITHM(MDNormSXD)
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
/** Constructor /** Constructor
*/ */
SXDMDNorm::SXDMDNorm() MDNormSXD::MDNormSXD()
{ {
hIndex=-1; hIndex=-1;
kIndex=-1; kIndex=-1;
...@@ -47,7 +54,7 @@ namespace MDAlgorithms ...@@ -47,7 +54,7 @@ namespace MDAlgorithms
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
/** Destructor /** Destructor
*/ */
SXDMDNorm::~SXDMDNorm() MDNormSXD::~MDNormSXD()
{ {
} }
...@@ -56,21 +63,21 @@ namespace MDAlgorithms ...@@ -56,21 +63,21 @@ namespace MDAlgorithms
/// Algorithm's version for identification. @see Algorithm::version /// Algorithm's version for identification. @see Algorithm::version
int SXDMDNorm::version() const { return 1;} int MDNormSXD::version() const { return 1;}
/// Algorithm's category for identification. @see Algorithm::category /// Algorithm's category for identification. @see Algorithm::category
const std::string SXDMDNorm::category() const { return "MDAlgorithms";} const std::string MDNormSXD::category() const { return "MDAlgorithms";}
/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
const std::string SXDMDNorm::summary() const { return "Calculate normalization for an MDEvent workspace for single crystal diffraction.";} const std::string MDNormSXD::summary() const { return "Calculate normalization for an MDEvent workspace for single crystal diffraction.";}
/// Algorithm's name for use in the GUI and help. @see Algorithm::name /// Algorithm's name for use in the GUI and help. @see Algorithm::name
const std::string SXDMDNorm::name() const { return "SXDMDNorm";} const std::string MDNormSXD::name() const { return "MDNormSXD";}
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties. /** Initialize the algorithm's properties.
*/ */
void SXDMDNorm::init() void MDNormSXD::init()
{ {
declareProperty(new WorkspaceProperty<IMDEventWorkspace>("InputWorkspace","",Direction::Input), "An input MDWorkspace."); declareProperty(new WorkspaceProperty<IMDEventWorkspace>("InputWorkspace","",Direction::Input), "An input MDWorkspace.");
...@@ -85,13 +92,15 @@ namespace MDAlgorithms ...@@ -85,13 +92,15 @@ namespace MDAlgorithms
"Enter it as a comma-separated list of values with the format: 'name,minimum,maximum,number_of_bins'. Leave blank for NONE."); "Enter it as a comma-separated list of values with the format: 'name,minimum,maximum,number_of_bins'. Leave blank for NONE.");
} }
auto wsValidator = boost::make_shared<CompositeValidator>(); auto fluxValidator = boost::make_shared<CompositeValidator>();
wsValidator->add<WorkspaceUnitValidator>("Momentum"); fluxValidator->add<WorkspaceUnitValidator>("Momentum");
wsValidator->add<InstrumentValidator>(); fluxValidator->add<InstrumentValidator>();
wsValidator->add<CommonBinsValidator>(); fluxValidator->add<CommonBinsValidator>();
auto solidAngleValidator = fluxValidator->clone();
fluxValidator->add<IncreasingDataValidator>();
declareProperty(new WorkspaceProperty<>("FluxWorkspace","",Direction::Input,wsValidator), "An input workspace containing momentum dependent flux."); declareProperty(new WorkspaceProperty<>("FluxWorkspace","",Direction::Input,fluxValidator), "An input workspace containing integrated momentum dependent flux.");
declareProperty(new WorkspaceProperty<>("SolidAngleWorkspace","",Direction::Input,wsValidator->clone()), "An input workspace containing momentum integrated vanadium (a measure of the solid angle)."); declareProperty(new WorkspaceProperty<>("SolidAngleWorkspace","",Direction::Input,solidAngleValidator), "An input workspace containing momentum integrated vanadium (a measure of the solid angle).");
declareProperty(new WorkspaceProperty<Workspace>("OutputWorkspace","",Direction::Output), "A name for the output data MDHistoWorkspace."); declareProperty(new WorkspaceProperty<Workspace>("OutputWorkspace","",Direction::Output), "A name for the output data MDHistoWorkspace.");
declareProperty(new WorkspaceProperty<Workspace>("OutputNormalizationWorkspace","",Direction::Output), "A name for the output normalization MDHistoWorkspace."); declareProperty(new WorkspaceProperty<Workspace>("OutputNormalizationWorkspace","",Direction::Output), "A name for the output normalization MDHistoWorkspace.");
...@@ -100,7 +109,7 @@ namespace MDAlgorithms ...@@ -100,7 +109,7 @@ namespace MDAlgorithms
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
/** Execute the algorithm. /** Execute the algorithm.
*/ */
void SXDMDNorm::exec() void MDNormSXD::exec()
{ {
bool skipProcessing=false; bool skipProcessing=false;
m_inputWS=getProperty("InputWorkspace"); m_inputWS=getProperty("InputWorkspace");
...@@ -256,13 +265,10 @@ namespace MDAlgorithms ...@@ -256,13 +265,10 @@ namespace MDAlgorithms
m_lX[i] = lDim.getX(i); m_lX[i] = lDim.getX(i);
} }
Mantid::API::MatrixWorkspace_const_sptr fW=getProperty("FluxWorkspace"); Mantid::API::MatrixWorkspace_const_sptr integrFlux = getProperty("FluxWorkspace");
Mantid::DataObjects::EventWorkspace_const_sptr fluxW = boost::dynamic_pointer_cast<const Mantid::DataObjects::EventWorkspace>(fW); integrFlux->getXMinMax(KincidentMin,KincidentMax);
KincidentMin=fluxW->getEventXMin();
KincidentMax=fluxW->getEventXMax();
Mantid::API::MatrixWorkspace_const_sptr sA=getProperty("SolidAngleWorkspace"); Mantid::API::MatrixWorkspace_const_sptr sA=getProperty("SolidAngleWorkspace");
if (skipProcessing) if (skipProcessing)
{ {
g_log.warning("Binning limits are outside the limits of the MDWorkspace\n"); g_log.warning("Binning limits are outside the limits of the MDWorkspace\n");
...@@ -285,8 +291,8 @@ namespace MDAlgorithms ...@@ -285,8 +291,8 @@ namespace MDAlgorithms
std::vector<detid_t> detIDS=m_normWS->getExperimentInfo(0)->getInstrument()->getDetectorIDs(true); std::vector<detid_t> detIDS=m_normWS->getExperimentInfo(0)->getInstrument()->getDetectorIDs(true);
Mantid::API::Progress *prog=new Mantid::API::Progress(this,0.3,1,static_cast<int64_t>(detIDS.size())); Mantid::API::Progress *prog=new Mantid::API::Progress(this,0.3,1,static_cast<int64_t>(detIDS.size()));
const detid2index_map d2m=fluxW->getDetectorIDToWorkspaceIndexMap(); const detid2index_map d2m = integrFlux->getDetectorIDToWorkspaceIndexMap();
const detid2index_map d2mSA=sA->getDetectorIDToWorkspaceIndexMap(); const detid2index_map d2mSA = sA->getDetectorIDToWorkspaceIndexMap();
auto instrument = m_normWS->getExperimentInfo(0)->getInstrument(); auto instrument = m_normWS->getExperimentInfo(0)->getInstrument();
PARALLEL_FOR1(m_normWS) PARALLEL_FOR1(m_normWS)
...@@ -305,28 +311,44 @@ namespace MDAlgorithms ...@@ -305,28 +311,44 @@ namespace MDAlgorithms
//add to the correct signal at that particular index //add to the correct signal at that particular index
//NOTE: if parallel it has to be atomic/critical //NOTE: if parallel it has to be atomic/critical
//get event vector //get flux spectrum number
size_t sp=d2m.find(detIDS[i])->second; size_t sp=d2m.find(detIDS[i])->second;
std::vector<Mantid::DataObjects::WeightedEventNoTime> el=fluxW->getEventList(sp).getWeightedEventsNoTime(); // get the solid angle
//get iterator to the first event that has momentum >= (*intersections.begin())[3]
std::vector<Mantid::DataObjects::WeightedEventNoTime>::iterator start=el.begin();
// check that el isn't empty
if ( start == el.end() ) continue;
while((*start).tof()<(*intersections.begin())[3]) ++start;
double solid=sA->readY(d2mSA.find(detIDS[i])->second)[0]*PC; double solid=sA->readY(d2mSA.find(detIDS[i])->second)[0]*PC;
const size_t sizeOfMVD = intersections.front().size(); const size_t sizeOfMVD = intersections.front().size();
// pre-allocate for efficiency // pre-allocate for efficiency
std::vector<coord_t> pos( sizeOfMVD + otherValues.size() ); std::vector<coord_t> pos( sizeOfMVD + otherValues.size() );
for (auto it=intersections.begin()+1;it!=intersections.end();++it) auto intersectionsBegin = intersections.begin();
// calculate integrals for the intersection
// momentum values at intersections
std::vector<double> xValues( intersections.size() );
// buffer for the integrals
std::vector<double> yValues( intersections.size() );
{
// copy momenta to xValues
auto x = xValues.begin();
for (auto it = intersectionsBegin; it != intersections.end(); ++it, ++x)
{
*x = (*it)[3];
}
}
// calculate integrals at momenta from xValues by interpolating between points in spectrum sp
// of workspace integrFlux. The result is stored in yValues
calcIntegralsForIntersections( xValues, *integrFlux, sp, yValues );
for (auto it = intersectionsBegin + 1; it != intersections.end(); ++it)
{ {
//Mantid::Kernel::VMD deltav=(*it)-(*(it-1));//difference between consecutive intersections //Mantid::Kernel::VMD deltav=(*it)-(*(it-1));//difference between consecutive intersections
// the full vector isn't used so compute only what is necessary // the full vector isn't used so compute only what is necessary
double delta = (*it)[3] - (*(it-1))[3]; const double xStart = (*(it-1))[3];
const double xEnd = (*it)[3];
const double delta = xEnd - xStart;
const double eps=1e-7;//do not integrate if momemntum difference is smaller than eps, assume contribution is 0
double eps=1e-7;//do not integrate if momemntum difference is smaller than eps, assume contribution is 0
if (delta > eps) if (delta > eps)
{ {
//Mantid::Kernel::VMD avev=((*it)+(*(it-1)))*0.5;//average between two intersection (to get position) //Mantid::Kernel::VMD avev=((*it)+(*(it-1)))*0.5;//average between two intersection (to get position)
...@@ -342,14 +364,10 @@ namespace MDAlgorithms ...@@ -342,14 +364,10 @@ namespace MDAlgorithms
if(linIndex!=size_t(-1)) if(linIndex!=size_t(-1))
{ {
double signal=0.; // index of the current intersection
while((*start).tof()<(*it)[3]) size_t k = static_cast<size_t>( std::distance( intersectionsBegin, it ) );
{ // signal = integral between two consecutive intersections
if (start==el.end()) double signal = yValues[k] - yValues[k - 1];
break;
signal+=(*start).weight();
++start;
}
signal*=solid; signal*=solid;
PARALLEL_CRITICAL(updateMD) PARALLEL_CRITICAL(updateMD)
...@@ -375,7 +393,7 @@ namespace MDAlgorithms ...@@ -375,7 +393,7 @@ namespace MDAlgorithms
} }
std::vector<Mantid::Kernel::VMD> SXDMDNorm::calculateIntersections(Mantid::Geometry::IDetector_const_sptr detector) std::vector<Mantid::Kernel::VMD> MDNormSXD::calculateIntersections(Mantid::Geometry::IDetector_const_sptr detector)
{ {
std::vector<Mantid::Kernel::VMD> intersections; std::vector<Mantid::Kernel::VMD> intersections;
double th=detector->getTwoTheta(V3D(0,0,0),V3D(0,0,1)); double th=detector->getTwoTheta(V3D(0,0,0),V3D(0,0,1));
...@@ -568,5 +586,140 @@ namespace MDAlgorithms ...@@ -568,5 +586,140 @@ namespace MDAlgorithms
return intersections; return intersections;
} }
/**
* Integrate spectra in flux at x-values in integrFlux and save the results in y-vectors of integrFlux.
* @param flux :: A workspace to integrate.
* @param integrFlux :: A workspace to store the results.
*/
void MDNormSXD::integrateFlux( const DataObjects::EventWorkspace& flux, API::MatrixWorkspace &integrFlux )
{
size_t nSpec = flux.getNumberHistograms();
assert( nSpec == integrFlux.getNumberHistograms() );
// claculate the integration points and save them in the x-vactors of integrFlux
double xMin = flux.getEventXMin();
double xMax = flux.getEventXMax();
double dx = ( xMax - xMin ) / static_cast<double>( integrFlux.blocksize() - 1 );
auto &X = integrFlux.dataX(0);
auto ix = X.begin();
// x-values are equally spaced between the min and max tof in the first flux spectrum
for(double x = xMin; ix != X.end(); ++ix, x += dx)
{
*ix = x;
}
// loop overr the spectra and integrate
for(size_t sp = 0; sp < nSpec; ++sp)
{
if ( sp > 0 )
{
integrFlux.setX(sp,X);
}
std::vector<Mantid::DataObjects::WeightedEventNoTime> el = flux.getEventList(sp).getWeightedEventsNoTime();
auto &outY = integrFlux.dataY(sp);
double sum = 0;
auto x = X.begin() + 1;
size_t i = 1;
// the integral is a running sum of the event weights in the spectrum
for(auto evnt = el.begin(); evnt != el.end(); ++evnt)
{
double tof = evnt->tof();
while( x != X.end() && *x < tof )
{
++x; ++i;
}
if ( x == X.end() ) break;
sum += evnt->weight();
outY[i] = sum;
}
}
}
/**
* LInearly interpolate between the points in integrFlux at xValues and save the results in yValues.
* @param xValues :: X-values at which to interpolate
* @param integrFlux :: A workspace with the spectra to interpolate
* @param sp :: A workspace index for a spectrum in integrFlux to interpolate.
* @param yValues :: A vector to save the results.
*/
void MDNormSXD::calcIntegralsForIntersections( const std::vector<double> &xValues, const API::MatrixWorkspace &integrFlux, size_t sp, std::vector<double> &yValues ) const
{
assert( xValues.size() == yValues.size() );
// the x-data from the workspace
auto &xData = integrFlux.readX(sp);
const double xStart = xData.front();
const double xEnd = xData.back();
// the values in integrFlux are expected to be integrals of a non-negative function
// ie they must make a non-decreasing function
auto &yData = integrFlux.readY(sp);
size_t spSize = yData.size();
const double yMin = 0.0;
const double yMax = yData.back();
size_t nData = xValues.size();
// all integrals below xStart must be 0
if (xValues[nData-1] < xStart)
{
std::fill( yValues.begin(), yValues.end(), yMin );
return;
}
// all integrals above xEnd must be equal tp yMax
if ( xValues[0] > xEnd )
{
std::fill( yValues.begin(), yValues.end(), yMax );
return;
}
size_t i = 0;
// integrals below xStart must be 0
while(i < nData - 1 && xValues[i] < xStart)
{
yValues[i] = yMin;
i++;
}
size_t j = 0;
for(;i<nData;i++)
{
// integrals above xEnd must be equal tp yMax
if (j >= spSize - 1)
{
yValues[i] = yMax;
}
else
{
double xi = xValues[i];
while(j < spSize - 1 && xi > xData[j]) j++;
// if x falls onto an interpolation point return the corresponding y
if (xi == xData[j])
{
yValues[i] = yData[j];
}
else if (j == spSize - 1)
{
// if we get above xEnd it's yMax
yValues[i] = yMax;
}
else if (j > 0)
{
// interpolate between the consecutive points
double x0 = xData[j-1];
double x1 = xData[j];
double y0 = yData[j-1];
double y1 = yData[j];
yValues[i] = y0 + (y1 - y0)*(xi - x0)/(x1 - x0);
}
else // j == 0
{
yValues[i] = yMin;
}
}
}
}
} // namespace MDAlgorithms } // namespace MDAlgorithms
} // namespace Mantid } // namespace Mantid
#ifndef MANTID_MDALGORITHMS_INTEGRATEFLUXTEST_H_
#define MANTID_MDALGORITHMS_INTEGRATEFLUXTEST_H_
#include <cxxtest/TestSuite.h>
#include "MantidMDAlgorithms/IntegrateFlux.h"
#include "MantidAPI/AlgorithmManager.h"
using Mantid::MDAlgorithms::IntegrateFlux;
using namespace Mantid::API;
class IntegrateFluxTest : public CxxTest::TestSuite
{
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static IntegrateFluxTest *createSuite() { return new IntegrateFluxTest(); }
static void destroySuite( IntegrateFluxTest *suite )
{
delete suite;
}
void test_Init()
{
IntegrateFlux alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
}
void test_exec()
{
// Name of the input workspace.
std::string inWSName("IntegrateFluxTest_InputWS");
// Name of the output workspace.
std::string outWSName("IntegrateFluxTest_OutputWS");
// Create an input workspace
createInputWorkspace(inWSName);
IntegrateFlux alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace", inWSName) );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) );
TS_ASSERT_THROWS_NOTHING( alg.execute(); );
TS_ASSERT( alg.isExecuted() );
// Retrieve the workspace from data service. TODO: Change to your desired type
MatrixWorkspace_sptr ws;
TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(outWSName) );
TS_ASSERT(ws);
if (!ws) return;
auto inWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( inWSName );
TS_ASSERT( ws->getAxis(0)->unit() == inWS->getAxis(0)->unit() );
TS_ASSERT_EQUALS( ws->getNumberHistograms(), 4 );
auto &x = ws->readX(0);
auto &y = ws->readY(0);
TS_ASSERT_EQUALS( x.size(), 98 );
TS_ASSERT_EQUALS( x.size(), y.size() );
for(size_t i = 10; i < x.size(); ++i)
{
double t = x[i];
TS_ASSERT_DELTA( t*(t+1.0) / y[i], 1.0, 0.1 );
}
// Remove workspace from the data service.
AnalysisDataService::Instance().clear();
}
void test_two_interpolation_point()
{
// Name of the input workspace.
std::string inWSName("IntegrateFluxTest_InputWS");
// Name of the output workspace.
std::string outWSName("IntegrateFluxTest_OutputWS");
// Create an input workspace
createInputWorkspace(inWSName);
IntegrateFlux alg;
alg.initialize();
alg.setPropertyValue("InputWorkspace", inWSName);
alg.setPropertyValue("OutputWorkspace", outWSName);
alg.setProperty("NPoints", 2);
alg.execute();
TS_ASSERT( alg.isExecuted() );
// Retrieve the workspace from data service. TODO: Change to your desired type
MatrixWorkspace_sptr ws;
TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(outWSName) );
TS_ASSERT(ws);
if (!ws) return;
TS_ASSERT_EQUALS( ws->getNumberHistograms(), 4 );
auto &x = ws->readX(0);
auto &y = ws->readY(0);
TS_ASSERT_EQUALS( x.size(), y.size() );
TS_ASSERT_EQUALS( x.size(), 2 );
double t = x[1];
TS_ASSERT_DELTA( t*(t+1.0) / y[1], 1.0, 0.1 );
// Remove workspace from the data service.
AnalysisDataService::Instance().clear();
}
void test_one_interpolation_point()
{
// Name of the input workspace.
std::string inWSName("IntegrateFluxTest_InputWS");
// Name of the output workspace.
std::string outWSName("IntegrateFluxTest_OutputWS");
// Create an input workspace
createInputWorkspace(inWSName);
IntegrateFlux alg;
alg.initialize();
alg.setPropertyValue("InputWorkspace", inWSName);
alg.setPropertyValue("OutputWorkspace", outWSName);
TS_ASSERT_THROWS( alg.setProperty("NPoints", 1), std::invalid_argument );
// Remove workspace from the data service.
AnalysisDataService::Instance().clear();
}
void test_bad_input_workspace()
{
// Name of the input workspace.
std::string inWSName("IntegrateFluxTest_InputWS");
// Name of the output workspace.
std::string outWSName("IntegrateFluxTest_OutputWS");
// Create an input workspace
createBadInputWorkspace(inWSName);
IntegrateFlux alg;
alg.initialize();
alg.setRethrows(true);
alg.setPropertyValue("InputWorkspace", inWSName);
alg.setPropertyValue("OutputWorkspace", outWSName);
TS_ASSERT_THROWS( alg.execute(), std::runtime_error );
// Remove workspace from the data service.
AnalysisDataService::Instance().clear();
}
private:
void createInputWorkspace(const std::string& wsName)
{
auto alg = Mantid::API::AlgorithmManager::Instance().create("CreateSampleWorkspace");
alg->initialize();
alg->setPropertyValue("WorkspaceType","Event");
alg->setPropertyValue("Function","User Defined");
alg->setPropertyValue("UserDefinedFunction","name=LinearBackground,A0=1,A1=2");
alg->setProperty("NumEvents",10000);
alg->setProperty("NumBanks",1);
alg->setProperty("BankPixelWidth",2);
alg->setProperty("XMin",0.0);
alg->setProperty("XMax",100.0);
alg->setPropertyValue("XUnit","Momentum");
alg->setProperty("BinWidth",1.0);
alg->setProperty("OutputWorkspace",wsName);
alg->execute();
alg = Mantid::API::AlgorithmManager::Instance().create("CompressEvents");
alg->initialize();
alg->setPropertyValue("InputWorkspace",wsName);
alg->setPropertyValue("OutputWorkspace",wsName);
alg->setProperty("Tolerance",1.0);
alg->execute();
}
void createBadInputWorkspace(const std::string& wsName)
{
auto alg = Mantid::API::AlgorithmManager::Instance().create("CreateSampleWorkspace");
alg->initialize();
alg->setPropertyValue("WorkspaceType","Event");
alg->setPropertyValue("Function","User Defined");
alg->setPropertyValue("UserDefinedFunction","name=LinearBackground,A0=1,A1=2");
alg->setProperty("NumEvents",10000);
alg->setProperty("NumBanks",1);
alg->setProperty("BankPixelWidth",2);
alg->setProperty("XMin",0.0);
alg->setProperty("XMax",100.0);
alg->setPropertyValue("XUnit","Momentum");
alg->setProperty("BinWidth",1.0);
alg->setProperty("OutputWorkspace",wsName);
alg->execute();
}
};
#endif /* MANTID_MDALGORITHMS_INTEGRATEFLUXTEST_H_ */
\ No newline at end of file
#ifndef MANTID_MDALGORITHMS_MDNORMSXDTEST_H_
#define MANTID_MDALGORITHMS_MDNORMSXDTEST_H_
#include <cxxtest/TestSuite.h>
#include "MantidMDAlgorithms/MDNormSXD.h"
#include "MantidMDAlgorithms/CreateMDWorkspace.h"
#include "MantidAPI/IMDHistoWorkspace.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
using Mantid::MDAlgorithms::MDNormSXD;
using namespace Mantid::API;
class MDNormSXDTest : public CxxTest::TestSuite
{
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static MDNormSXDTest *createSuite() { return new MDNormSXDTest(); }
static void destroySuite( MDNormSXDTest *suite ) { delete suite; }
void test_Init()
{
MDNormSXD alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
}
void test_properties()
{
std::string mdWsName = "__temp_InputMDWorkspaceName";
createMDWorkspace(mdWsName);
std::string fluxGoodWsName = "__temp_InputGoodFluxWorkspaceName";
createGoodFluxWorkspace(fluxGoodWsName);
std::string fluxBadWsName = "__temp_InputBadFluxWorkspaceName";
createBadFluxWorkspace(fluxBadWsName);
std::string saWsName = "__temp_InputSAWorkspaceName";
createBadFluxWorkspace(saWsName);
MDNormSXD alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace", mdWsName) );
TS_ASSERT_THROWS_NOTHING( alg.setProperty("FluxWorkspace", fluxGoodWsName) );
TS_ASSERT_THROWS( alg.setProperty("FluxWorkspace", fluxBadWsName), std::invalid_argument );
TS_ASSERT_THROWS_NOTHING( alg.setProperty("SolidAngleWorkspace", saWsName) );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", "OutWSName") );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputNormalizationWorkspace", "OutNormWSName") );
AnalysisDataService::Instance().clear();
}
private:
void createMDWorkspace(const std::string& wsName)
{
const int ndims = 2;
std::string bins = "2,2";
std::string extents = "0,1,0,1";
std::vector<std::string> names(ndims);
names[0] = "A"; names[1] = "B";
std::vector<std::string> units(ndims);
units[0] = "a"; units[1] = "b";
Mantid::MDAlgorithms::CreateMDWorkspace alg;
alg.initialize();
TS_ASSERT_THROWS_NOTHING( alg.setProperty("Dimensions", ndims) );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Extents", extents) );
TS_ASSERT_THROWS_NOTHING( alg.setProperty("Names", names) );
TS_ASSERT_THROWS_NOTHING( alg.setProperty("Units", units) );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", wsName) );
alg.execute();
}
void createGoodFluxWorkspace(const std::string& wsName)
{
auto flux = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument( 2, 10 );
auto &x = flux->dataX(0);
auto &y1 = flux->dataY(1);
for(size_t i = 0; i < y1.size(); ++i)
{
y1[i] = 2 * x[i];
}
flux->setX(1,x);
flux->getAxis(0)->setUnit("Momentum");
AnalysisDataService::Instance().addOrReplace( wsName, flux );
}
void createBadFluxWorkspace(const std::string& wsName)
{
auto flux = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument( 2, 10 );
auto &x = flux->dataX(0);
auto &y1 = flux->dataY(1);
for(size_t i = 0; i < y1.size(); ++i)
{
y1[i] = -2 * x[i];
}
flux->setX(1,x);
flux->getAxis(0)->setUnit("Momentum");
AnalysisDataService::Instance().addOrReplace( wsName, flux );
}
void createSolidAngleWorkspace(const std::string& wsName)
{
auto sa = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument( 2, 10 );
AnalysisDataService::Instance().addOrReplace( wsName, sa );
}
};
#endif /* MANTID_MDALGORITHMS_MDNORMSXDTEST_H_ */
#ifndef MANTID_MDALGORITHMS_SXDMDNORMTEST_H_
#define MANTID_MDALGORITHMS_SXDMDNORMTEST_H_
#include <cxxtest/TestSuite.h>
#include "MantidMDAlgorithms/SXDMDNorm.h"
using Mantid::MDAlgorithms::SXDMDNorm;
using namespace Mantid::API;
class SXDMDNormTest : public CxxTest::TestSuite
{
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static SXDMDNormTest *createSuite() { return new SXDMDNormTest(); }
static void destroySuite( SXDMDNormTest *suite ) { delete suite; }
void test_Init()
{
SXDMDNorm alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
}
//No test for now. Should be part of ticket #9105
void test_exec()
{
// Name of the output workspace.
/*std::string outWSName("SXDMDNormTest_OutputWS");
SXDMDNorm alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("REPLACE_PROPERTY_NAME_HERE!!!!", "value") );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) );
TS_ASSERT_THROWS_NOTHING( alg.execute(); );
TS_ASSERT( alg.isExecuted() );
// Retrieve the workspace from data service. TODO: Change to your desired type
Workspace_sptr ws;
TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS<Workspace>(outWSName) );
TS_ASSERT(ws);
if (!ws) return;
// TODO: Check the results
// Remove workspace from the data service.
AnalysisDataService::Instance().remove(outWSName);*/
}
};
#endif /* MANTID_MDALGORITHMS_SXDMDNORMTEST_H_ */
.. algorithm::
.. summary::
.. alias::
.. properties::
Description
-----------
If a spectrum in the input workspace contains function :math:`f(x)` then the corresponding spectrum in
the output workspace has its indefinite integral:
:math:`\int_{x_0}^x f(\xi)d\xi`.
The input workspace is expected to be an event workspace with weighted-no-time events.
Usage
-----
**Example - IntegrateFlux**
.. testcode:: IntegrateFluxExample
# Create an event workspace
ws = CreateSampleWorkspace("Event")
# Make evet type weighted-no-time.
ws = CompressEvents( ws )
# Integrate all spectra.
wsOut = IntegrateFlux( ws )
# Print the result
print "The input workspace has %i spectra" % ws.getNumberHistograms()
print "The output workspace has %i spectra" % wsOut.getNumberHistograms()
Output:
.. testoutput:: IntegrateFluxExample
The input workspace has 200 spectra
The output workspace has 200 spectra
.. categories::
...@@ -22,9 +22,9 @@ Usage ...@@ -22,9 +22,9 @@ Usage
autotestdata\UsageData and the following tag unindented autotestdata\UsageData and the following tag unindented
.. include:: ../usagedata-note.txt .. include:: ../usagedata-note.txt
**Example - SXDMDNorm** **Example - MDNormSXD**
.. testcode:: SXDMDNormExample .. testcode:: MDNormSXDExample
try: try:
# Setting up the workspaces containing information about the flux and the solid angle (from a vanadium run) # Setting up the workspaces containing information about the flux and the solid angle (from a vanadium run)
...@@ -48,6 +48,7 @@ Usage ...@@ -48,6 +48,7 @@ Usage
el=flux.getEventList(i) el=flux.getEventList(i)
el.divide(flux.readY(i)[0],0) el.divide(flux.readY(i)[0],0)
flux=Rebin(InputWorkspace=flux,Params='1.85,10,10') flux=Rebin(InputWorkspace=flux,Params='1.85,10,10')
flux=IntegrateFlux(flux)
SaveNexus(InputWorkspace=flux, Filename="/home/3y9/Desktop/TOPAZ/spectra.nxs") SaveNexus(InputWorkspace=flux, Filename="/home/3y9/Desktop/TOPAZ/spectra.nxs")
#data #data
...@@ -65,7 +66,7 @@ Usage ...@@ -65,7 +66,7 @@ Usage
SaveMD(InputWorkspace=MDdata, Filename="/home/3y9/Desktop/TOPAZ/MDdata.nxs") SaveMD(InputWorkspace=MDdata, Filename="/home/3y9/Desktop/TOPAZ/MDdata.nxs")
#running the algorithm #running the algorithm
SXDMDNorm(InputWorkspace='MDdata', MDNormSXD(InputWorkspace='MDdata',
AlignedDim0='[H,0,0],-8,8,100', AlignedDim0='[H,0,0],-8,8,100',
AlignedDim1='[0,K,0],-8,8,100', AlignedDim1='[0,K,0],-8,8,100',
AlignedDim2='[0,0,L],-8,8,100', AlignedDim2='[0,0,L],-8,8,100',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment