Newer
Older
/*********************************************************************************
* PLEASE READ THIS!!!!!!!
*
* This collection of functions MAY NOT be used in any test from a package
*below
* DataObjects (e.g. Kernel, Geometry, API).
* Conversely, this file MAY NOT be modified to use anything from a package
*higher
* than DataObjects (e.g. any algorithm), even if going via the factory.
*********************************************************************************/
Gigg, Martyn Anthony
committed
//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
#include "MantidTestHelpers/ComponentCreationHelper.h"
#include "MantidTestHelpers/InstrumentCreationHelper.h"
#include "MantidAPI/Run.h"
#include "MantidAPI/IAlgorithm.h"
#include "MantidAPI/Algorithm.h"
#include "MantidAPI/SpectraAxis.h"
#include "MantidAPI/NumericAxis.h"
#include "MantidDataObjects/PeaksWorkspace.h"
Gigg, Martyn Anthony
committed
#include "MantidGeometry/Instrument/Detector.h"
#include "MantidGeometry/Instrument/ParameterMap.h"
#include "MantidGeometry/Instrument/ReferenceFrame.h"
#include "MantidGeometry/Instrument/Component.h"
Gigg, Martyn Anthony
committed
#include "MantidGeometry/Objects/ShapeFactory.h"
#include "MantidGeometry/Crystal/OrientedLattice.h"
#include "MantidKernel/MersenneTwister.h"
Janik Zikovsky
committed
#include "MantidKernel/TimeSeriesProperty.h"
#include "MantidKernel/UnitFactory.h"
#include "MantidKernel/VectorHelper.h"
#include "MantidKernel/make_unique.h"
#include <sstream>
namespace WorkspaceCreationHelper {
using namespace Mantid;
using namespace Mantid::DataObjects;
using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::Geometry;
using Mantid::MantidVec;
using Mantid::MantidVecPtr;
MockAlgorithm::MockAlgorithm(size_t nSteps) {
m_Progress = Mantid::Kernel::make_unique<API::Progress>(this, 0, 1, nSteps);
/**
* @param name :: The name of the workspace
* @param ws :: The workspace object
*/
void storeWS(const std::string &name, Mantid::API::Workspace_sptr ws) {
Mantid::API::AnalysisDataService::Instance().add(name, ws);
}
Gigg, Martyn Anthony
committed
/**
* Deletes a workspace
* @param name :: The name of the workspace
*/
void removeWS(const std::string &name) {
Mantid::API::AnalysisDataService::Instance().remove(name);
}
Gigg, Martyn Anthony
committed
Workspace2D_sptr Create1DWorkspaceRand(int size) {
MantidVecPtr x1, y1, e1;
x1.access().resize(size, 1);
y1.access().resize(size);
Federico Montesino Pouzols
committed
MersenneTwister randomGen(DateAndTime::getCurrentTime().nanoseconds(), 0,
std::numeric_limits<int>::max());
auto randFunc = [&randomGen] { return randomGen.nextValue(); };
std::generate(y1.access().begin(), y1.access().end(), randFunc);
Federico Montesino Pouzols
committed
std::generate(e1.access().begin(), e1.access().end(), randFunc);
auto retVal = boost::make_shared<Workspace2D>();
retVal->initialize(1, size, size);
retVal->setX(0, x1);
retVal->setData(0, y1, e1);
return retVal;
}
Gigg, Martyn Anthony
committed
Workspace2D_sptr Create1DWorkspaceConstant(int size, double value,
double error) {
MantidVecPtr x1, y1, e1;
x1.access().resize(size, 1);
y1.access().resize(size, value);
e1.access().resize(size, error);
auto retVal = boost::make_shared<Workspace2D>();
retVal->initialize(1, size, size);
retVal->setX(0, x1);
retVal->setData(0, y1, e1);
return retVal;
}
Janik Zikovsky
committed
Workspace2D_sptr Create1DWorkspaceConstantWithXerror(int size, double value,
double error,
double xError) {
auto ws = Create1DWorkspaceConstant(size, value, error);
MantidVecPtr dx1;
dx1.access().resize(size, xError);
ws->setDx(0, dx1);
return ws;
}
Workspace2D_sptr Create1DWorkspaceFib(int size) {
MantidVecPtr x1, y1, e1;
x1.access().resize(size, 1);
y1.access().resize(size);
std::generate(y1.access().begin(), y1.access().end(), FibSeries<double>());
e1.access().resize(size);
auto retVal = boost::make_shared<Workspace2D>();
retVal->initialize(1, size, size);
retVal->setX(0, x1);
retVal->setData(0, y1, e1);
return retVal;
}
Gigg, Martyn Anthony
committed
Workspace2D_sptr Create2DWorkspace(int nhist, int numBoundaries) {
return Create2DWorkspaceBinned(nhist, numBoundaries);
}
Janik Zikovsky
committed
/** Create a Workspace2D where the Y value at each bin is
* == to the workspace index
* @param nhist :: # histograms
* @param numBoundaries :: # of bins
* @return Workspace2D
*/
Workspace2D_sptr Create2DWorkspaceWhereYIsWorkspaceIndex(int nhist,
int numBoundaries) {
Workspace2D_sptr out = Create2DWorkspaceBinned(nhist, numBoundaries);
for (int wi = 0; wi < nhist; wi++)
for (int x = 0; x < numBoundaries; x++)
out->dataY(wi)[x] = wi * 1.0;
return out;
}
Workspace2D_sptr create2DWorkspaceThetaVsTOF(int nHist, int nBins) {
Workspace2D_sptr outputWS = Create2DWorkspaceBinned(nHist, nBins);
auto const newAxis = new NumericAxis(nHist);
outputWS->replaceAxis(1, newAxis);
newAxis->unit() = boost::make_shared<Units::Degrees>();
for (int i = 0; i < nHist; ++i) {
newAxis->setValue(i, i + 1);
Gigg, Martyn Anthony
committed
Workspace2D_sptr
Create2DWorkspaceWithValues(int64_t nHist, int64_t nBins, bool isHist,
const std::set<int64_t> &maskedWorkspaceIndices,
double xVal, double yVal, double eVal) {
MantidVecPtr x1, y1, e1;
x1.access().resize(isHist ? nBins + 1 : nBins, xVal);
y1.access().resize(nBins, yVal);
e1.access().resize(nBins, eVal);
auto retVal = boost::make_shared<Workspace2D>();
retVal->initialize(nHist, isHist ? nBins + 1 : nBins, nBins);
for (int i = 0; i < nHist; i++) {
retVal->setX(i, x1);
retVal->setData(i, y1, e1);
retVal->getSpectrum(i)->setDetectorID(i);
retVal->getSpectrum(i)->setSpectrumNo(i);
Janik Zikovsky
committed
}
retVal = maskSpectra(retVal, maskedWorkspaceIndices);
return retVal;
}
Gigg, Martyn Anthony
committed
Workspace2D_sptr Create2DWorkspaceWithValuesAndXerror(
int64_t nHist, int64_t nBins, bool isHist, double xVal, double yVal,
double eVal, double dxVal,
const std::set<int64_t> &maskedWorkspaceIndices) {
auto ws = Create2DWorkspaceWithValues(
nHist, nBins, isHist, maskedWorkspaceIndices, xVal, yVal, eVal);
MantidVecPtr dx1;
dx1.access().resize(isHist ? nBins + 1 : nBins, dxVal);
for (int i = 0; i < nHist; i++) {
ws->setDx(i, dx1);
}
return ws;
}
Workspace2D_sptr
Create2DWorkspace123(int64_t nHist, int64_t nBins, bool isHist,
const std::set<int64_t> &maskedWorkspaceIndices) {
return Create2DWorkspaceWithValues(nHist, nBins, isHist,
maskedWorkspaceIndices, 1.0, 2.0, 3.0);
}
Gigg, Martyn Anthony
committed
Workspace2D_sptr
Create2DWorkspace154(int64_t nHist, int64_t nBins, bool isHist,
const std::set<int64_t> &maskedWorkspaceIndices) {
return Create2DWorkspaceWithValues(nHist, nBins, isHist,
maskedWorkspaceIndices, 1.0, 5.0, 4.0);
}
Janik Zikovsky
committed
Workspace2D_sptr maskSpectra(Workspace2D_sptr workspace,
const std::set<int64_t> &maskedWorkspaceIndices) {
const int nhist = static_cast<int>(workspace->getNumberHistograms());
if (workspace->getInstrument()->nelements() == 0) {
// We need detectors to be able to mask them.
auto instrument = boost::make_shared<Instrument>();
workspace->setInstrument(instrument);
Gigg, Martyn Anthony
committed
std::string xmlShape = "<sphere id=\"shape\"> ";
xmlShape += "<centre x=\"0.0\" y=\"0.0\" z=\"0.0\" /> ";
xmlShape += "<radius val=\"0.05\" /> ";
xmlShape += "</sphere>";
xmlShape += "<algebra val=\"shape\" /> ";
ShapeFactory sFactory;
boost::shared_ptr<Object> shape = sFactory.createShape(xmlShape);
for (int i = 0; i < nhist; ++i) {
Detector *det = new Detector("det", detid_t(i), shape, nullptr);
det->setPos(i, i + 1, 1);
instrument->add(det);
instrument->markAsDetector(det);
Gigg, Martyn Anthony
committed
}
workspace->setInstrument(instrument);
Gigg, Martyn Anthony
committed
}
ParameterMap &pmap = workspace->instrumentParameters();
for (int i = 0; i < nhist; ++i) {
if (maskedWorkspaceIndices.find(i) != maskedWorkspaceIndices.end()) {
IDetector_const_sptr det = workspace->getDetector(i);
pmap.addBool(det.get(), "masked", true);
Gigg, Martyn Anthony
committed
}
}
Gigg, Martyn Anthony
committed
/**
* Create a group with nEntries. It is added to the ADS with the given stem
*/
WorkspaceGroup_sptr CreateWorkspaceGroup(int nEntries, int nHist, int nBins,
const std::string &stem) {
auto group = boost::make_shared<WorkspaceGroup>();
AnalysisDataService::Instance().add(stem, group);
for (int i = 0; i < nEntries; ++i) {
Workspace2D_sptr ws = Create2DWorkspace(nHist, nBins);
std::ostringstream os;
os << stem << "_" << i;
AnalysisDataService::Instance().add(os.str(), ws);
group->add(os.str());
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
/** Create a 2D workspace with this many histograms and bins.
*/
Workspace2D_sptr Create2DWorkspaceBinned(int nhist, int nbins, double x0,
double deltax) {
MantidVecPtr x, y, e;
x.access().resize(nbins + 1);
y.access().resize(nbins, 2);
for (int i = 0; i < nbins + 1; ++i) {
x.access()[i] = x0 + i * deltax;
auto retVal = boost::make_shared<Workspace2D>();
retVal->initialize(nhist, nbins + 1, nbins);
for (int i = 0; i < nhist; i++) {
retVal->setX(i, x);
retVal->setData(i, y, e);
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
/** Create a 2D workspace with this many histograms and bins. The bins are
* assumed to be non-uniform and given by the input array
*/
Workspace2D_sptr Create2DWorkspaceBinned(int nhist, const int numBoundaries,
const double xBoundaries[]) {
MantidVecPtr x, y, e;
const int numBins = numBoundaries - 1;
x.access().resize(numBoundaries);
y.access().resize(numBins, 2);
for (int i = 0; i < numBoundaries; ++i) {
x.access()[i] = xBoundaries[i];
}
auto retVal = boost::make_shared<Workspace2D>();
retVal->initialize(nhist, numBins + 1, numBins);
for (int i = 0; i < nhist; i++) {
retVal->setX(i, x);
retVal->setData(i, y, e);
/**
* Add random noise to the signal
* @param ws :: The workspace to add the noise to
* @param noise :: The mean noise level
* @param lower :: The lower bound of the flucation (default=-0.5)
* @param upper:: The upper bound of the flucation (default=-0.5)
*/
void addNoise(Mantid::API::MatrixWorkspace_sptr ws, double noise,
const double lower, const double upper) {
const size_t seed(12345);
MersenneTwister randGen(seed, lower, upper);
for (size_t iSpec = 0; iSpec < ws->getNumberHistograms(); iSpec++) {
Mantid::MantidVec &Y = ws->dataY(iSpec);
Mantid::MantidVec &E = ws->dataE(iSpec);
for (size_t i = 0; i < Y.size(); i++) {
Y[i] += noise * randGen.nextValue();
E[i] += noise;
Janik Zikovsky
committed
}
}
Janik Zikovsky
committed
//================================================================================================================
/**
* Create a test workspace with a fully defined instrument
* Each spectra will have a cylindrical detector defined 2*cylinder_radius away
* from the centre of the
* previous.
* Data filled with: Y: 2.0, E: M_SQRT2, X: nbins of width 1 starting at 0
*/
Workspace2D_sptr
create2DWorkspaceWithFullInstrument(int nhist, int nbins, bool includeMonitors,
bool startYNegative, bool isHistogram,
const std::string &instrumentName) {
if (includeMonitors && nhist < 2) {
throw std::invalid_argument("Attempting to 2 include monitors for a "
"workspace with fewer than 2 histograms");
}
Workspace2D_sptr space;
if (isHistogram)
space = Create2DWorkspaceBinned(
nhist, nbins); // A 1:1 spectra is created by default
else
space = Create2DWorkspace123(nhist, nbins, false);
space->setTitle(
"Test histogram"); // actually adds a property call run_title to the logs
space->getAxis(0)->setUnit("TOF");
space->setYUnit("Counts");
InstrumentCreationHelper::addFullInstrumentToWorkspace(
*space, includeMonitors, startYNegative, instrumentName);
//================================================================================================================
/** Create an Workspace2D with an instrument that contains
*RectangularDetector's.
* Bins will be 0.0, 1.0, to numBins, filled with signal=2.0, M_SQRT2
*
* @param numBanks :: number of rectangular banks
* @param numPixels :: each bank will be numPixels*numPixels
* @param numBins :: each spectrum will have this # of bins
* @return The EventWorkspace
*/
Mantid::DataObjects::Workspace2D_sptr
create2DWorkspaceWithRectangularInstrument(int numBanks, int numPixels,
int numBins) {
Instrument_sptr inst =
ComponentCreationHelper::createTestInstrumentRectangular(numBanks,
numPixels);
Workspace2D_sptr ws =
Create2DWorkspaceBinned(numBanks * numPixels * numPixels, numBins);
ws->setInstrument(inst);
ws->getAxis(0)->setUnit("dSpacing");
for (size_t wi = 0; wi < ws->getNumberHistograms(); wi++) {
ws->getSpectrum(wi)->setDetectorID(detid_t(numPixels * numPixels + wi));
ws->getSpectrum(wi)->setSpectrumNo(specnum_t(wi));
//================================================================================================================
/** Create an Eventworkspace with an instrument that contains
*RectangularDetector's.
* X axis = 100 histogrammed bins from 0.0 in steps of 1.0.
* 200 events per pixel.
*
* @param numBanks :: number of rectangular banks
* @param numPixels :: each bank will be numPixels*numPixels
* @param clearEvents :: if true, erase the events from list
* @return The EventWorkspace
*/
Mantid::DataObjects::EventWorkspace_sptr
createEventWorkspaceWithFullInstrument(int numBanks, int numPixels,
bool clearEvents) {
Instrument_sptr inst =
ComponentCreationHelper::createTestInstrumentRectangular(numBanks,
numPixels);
EventWorkspace_sptr ws =
CreateEventWorkspace2(numBanks * numPixels * numPixels, 100);
ws->setInstrument(inst);
// Set the X axes
MantidVec x = ws->readX(0);
auto ax0 = new NumericAxis(x.size());
ax0->setUnit("dSpacing");
for (size_t i = 0; i < x.size(); i++) {
}
ws->replaceAxis(0, ax0);
// re-assign detector IDs to the rectangular detector
int detID = numPixels * numPixels;
for (int wi = 0; wi < static_cast<int>(ws->getNumberHistograms()); wi++) {
ws->getEventList(wi).clearDetectorIDs();
if (clearEvents)
ws->getEventList(wi).clear(true);
ws->getEventList(wi).setDetectorID(detID);
detID++;
}
return ws;
}
Mantid::DataObjects::EventWorkspace_sptr
createEventWorkspaceWithNonUniformInstrument(int numBanks, bool clearEvents) {
// Number of detectors in a bank as created by createTestInstrumentCylindrical
const int DETECTORS_PER_BANK(9);
V3D srcPos(0., 0., -10.), samplePos;
ComponentCreationHelper::createTestInstrumentCylindrical(
numBanks, srcPos, samplePos, 0.0025, 0.005);
EventWorkspace_sptr ws =
CreateEventWorkspace2(numBanks * DETECTORS_PER_BANK, 100);
ws->setInstrument(inst);
std::vector<detid_t> detectorIds = inst->getDetectorIDs();
// Should be equal if DETECTORS_PER_BANK is correct
assert(detectorIds.size() == ws->getNumberHistograms());
// Re-assign detector IDs
for (size_t wi = 0; wi < ws->getNumberHistograms(); wi++) {
ws->getEventList(wi).clearDetectorIDs();
if (clearEvents)
ws->getEventList(wi).clear(true);
ws->getEventList(wi).setDetectorID(detectorIds[wi]);
}
/**
* Create a very small 2D workspace for a virtual reflectometry instrument.
* @return workspace with instrument attached.
* @param startX : X Tof start value for the workspace.
*/
MatrixWorkspace_sptr
create2DWorkspaceWithReflectometryInstrument(double startX) {
Instrument_sptr instrument = boost::make_shared<Instrument>();
instrument->setReferenceFrame(
boost::make_shared<ReferenceFrame>(Y /*up*/, X /*along*/, Left, "0,0,0"));
ObjComponent *source = new ObjComponent("source");
source->setPos(V3D(0, 0, 0));
instrument->add(source);
instrument->markAsSource(source);
Detector *monitor = new Detector("Monitor", 1, nullptr);
monitor->setPos(14, 0, 0);
instrument->add(monitor);
instrument->markAsMonitor(monitor);
ObjComponent *sample = new ObjComponent("some-surface-holder");
instrument->add(sample);
instrument->markAsSamplePos(sample);
// Where 0.01 is half detector width etc.
Detector *det = new Detector(
"point-detector", 2,
ComponentCreationHelper::createCuboid(0.01, 0.02, 0.03), nullptr);
det->setPos(20, (20 - sample->getPos().X()), 0);
instrument->add(det);
instrument->markAsDetector(det);
const int nSpectra = 2;
const int nBins = 100;
const double deltaX = 2000; // TOF
auto workspace = Create2DWorkspaceBinned(nSpectra, nBins, startX, deltaX);
workspace->setTitle(
"Test histogram"); // actually adds a property call run_title to the logs
workspace->getAxis(0)->setUnit("TOF");
workspace->setYUnit("Counts");
workspace->setInstrument(instrument);
workspace->getSpectrum(0)->setDetectorID(det->getID());
workspace->getSpectrum(1)->setDetectorID(monitor->getID());
void createInstrumentForWorkspaceWithDistances(
MatrixWorkspace_sptr workspace, const V3D &samplePosition,
const V3D &sourcePosition, const std::vector<V3D> &detectorPositions) {
Instrument_sptr instrument = boost::make_shared<Instrument>();
instrument->setReferenceFrame(
boost::make_shared<ReferenceFrame>(Y, X, Left, "0,0,0"));
ObjComponent *source = new ObjComponent("source");
source->setPos(sourcePosition);
instrument->add(source);
instrument->markAsSource(source);
ObjComponent *sample = new ObjComponent("sample");
source->setPos(samplePosition);
instrument->add(sample);
instrument->markAsSamplePos(sample);
workspace->setInstrument(instrument);
for (int i = 0; i < static_cast<int>(detectorPositions.size()); ++i) {
std::stringstream buffer;
buffer << "detector_" << i;
Detector *det = new Detector(buffer.str(), i, nullptr);
det->setPos(detectorPositions[i]);
instrument->add(det);
instrument->markAsDetector(det);
// Link it to the workspace
workspace->getSpectrum(i)->addDetectorID(det->getID());
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
//================================================================================================================
WorkspaceSingleValue_sptr CreateWorkspaceSingleValue(double value) {
return boost::make_shared<WorkspaceSingleValue>(value, sqrt(value));
Gigg, Martyn Anthony
committed
WorkspaceSingleValue_sptr CreateWorkspaceSingleValueWithError(double value,
double error) {
return boost::make_shared<WorkspaceSingleValue>(value, error);
Gigg, Martyn Anthony
committed
/** Perform some finalization on event workspace stuff */
void EventWorkspace_Finalize(EventWorkspace_sptr ew) {
// get a proton charge
ew->mutableRun().integrateProtonCharge();
}
Gigg, Martyn Anthony
committed
/** Create event workspace with:
* 500 pixels
* 1000 histogrammed bins.
*/
EventWorkspace_sptr CreateEventWorkspace() {
return CreateEventWorkspace(500, 1001, 100, 1000);
}
Gigg, Martyn Anthony
committed
/** Create event workspace with:
* numPixels pixels
* numBins histogrammed bins from 0.0 in steps of 1.0
* 200 events; two in each bin, at time 0.5, 1.5, etc.
* PulseTime = 0 second x2, 1 second x2, 2 seconds x2, etc. after 2010-01-01
*/
EventWorkspace_sptr CreateEventWorkspace2(int numPixels, int numBins) {
return CreateEventWorkspace(numPixels, numBins, 100, 0.0, 1.0, 2);
}
/** Create event workspace
*/
EventWorkspace_sptr CreateEventWorkspace(int numPixels, int numBins,
int numEvents, double x0,
double binDelta, int eventPattern,
int start_at_pixelID) {
return CreateEventWorkspaceWithStartTime(
numPixels, numBins, numEvents, x0, binDelta, eventPattern,
start_at_pixelID, DateAndTime("2010-01-01T00:00:00"));
}
/**
* Create event workspace with defined start date time
*/
EventWorkspace_sptr
CreateEventWorkspaceWithStartTime(int numPixels, int numBins, int numEvents,
double x0, double binDelta, int eventPattern,
int start_at_pixelID, DateAndTime run_start) {
Gigg, Martyn Anthony
committed
// add one to the number of bins as this is histogram
numBins++;
auto retVal = boost::make_shared<EventWorkspace>();
retVal->initialize(numPixels, 1, 1);
Janik Zikovsky
committed
// Make fake events
if (eventPattern) // 0 == no events
{
size_t workspaceIndex = 0;
for (int pix = start_at_pixelID + 0; pix < start_at_pixelID + numPixels;
pix++) {
EventList &el = retVal->getEventList(workspaceIndex);
el.setSpectrumNo(pix);
el.setDetectorID(pix);
for (int i = 0; i < numEvents; i++) {
if (eventPattern == 1) // 0, 1 diagonal pattern
el += TofEvent((pix + i + 0.5) * binDelta, run_start + double(i));
else if (eventPattern == 2) // solid 2
{
el += TofEvent((i + 0.5) * binDelta, run_start + double(i));
el += TofEvent((i + 0.5) * binDelta, run_start + double(i));
} else if (eventPattern == 3) // solid 1
{
el += TofEvent((i + 0.5) * binDelta, run_start + double(i));
} else if (eventPattern == 4) // Number of events per bin = pixelId (aka
// workspace index in most cases)
{
for (int q = 0; q < pix; q++)
el += TofEvent((i + 0.5) * binDelta, run_start + double(i));
}
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
// Create the x-axis for histogramming.
MantidVecPtr x1;
MantidVec &xRef = x1.access();
xRef.resize(numBins);
for (int i = 0; i < numBins; ++i) {
xRef[i] = x0 + i * binDelta;
Gigg, Martyn Anthony
committed
}
// Set all the histograms at once.
retVal->setAllX(x1);
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
// =====================================================================================
/** Create event workspace, with several detector IDs in one event list.
*/
EventWorkspace_sptr
CreateGroupedEventWorkspace(std::vector<std::vector<int>> groups, int numBins,
double binDelta, double xOffset) {
auto retVal = boost::make_shared<EventWorkspace>();
retVal->initialize(1, 2, 1);
for (size_t g = 0; g < groups.size(); g++) {
retVal->getOrAddEventList(g).clearDetectorIDs();
std::vector<int> dets = groups[g];
for (int i = 0; i < numBins; i++)
retVal->getOrAddEventList(g) += TofEvent((i + 0.5) * binDelta, 1);
retVal->getOrAddEventList(g).addDetectorID(det);
}
}
Gigg, Martyn Anthony
committed
if (xOffset == 0.) {
// Create the x-axis for histogramming.
MantidVecPtr x1;
MantidVec &xRef = x1.access();
const double x0 = 0.;
xRef.resize(numBins);
for (int i = 0; i < numBins; ++i) {
xRef[i] = x0 + static_cast<double>(i) * binDelta;
}
// Set all the histograms at once.
retVal->setAllX(x1);
} else {
for (size_t g = 0; g < groups.size(); g++) {
// Create the x-axis for histogramming.
MantidVecPtr x1;
MantidVec &xRef = x1.access();
const double x0 = xOffset * static_cast<double>(g);
xRef.resize(numBins);
for (int i = 0; i < numBins; ++i) {
xRef[i] = x0 + static_cast<double>(i) * binDelta;
}
retVal->setX(g, x1);
}
}
// =====================================================================================
/** Create an event workspace with randomized TOF and pulsetimes
*
* @param numbins :: # of bins to set. This is also = # of events per EventList
* @param numpixels :: number of pixels
* @param bin_delta :: a constant offset to shift the bin bounds by
* @return EventWorkspace
*/
EventWorkspace_sptr CreateRandomEventWorkspace(size_t numbins, size_t numpixels,
double bin_delta) {
auto retVal = boost::make_shared<EventWorkspace>();
retVal->initialize(numpixels, numbins, numbins - 1);
// and X-axis for references:
auto pAxis0 = new NumericAxis(numbins);
// Create the original X axis to histogram on.
// Create the x-axis for histogramming.
Kernel::cow_ptr<MantidVec> axis;
MantidVec &xRef = axis.access();
xRef.resize(numbins);
for (int i = 0; i < static_cast<int>(numbins); ++i) {
xRef[i] = i * bin_delta;
pAxis0->setValue(i, xRef[i]);
}
pAxis0->setUnit("TOF");
Federico Montesino Pouzols
committed
MersenneTwister randomGen(DateAndTime::getCurrentTime().nanoseconds(), 0,
std::numeric_limits<int>::max());
// Make up some data for each pixels
for (size_t i = 0; i < numpixels; i++) {
// Create one event for each bin
EventList &events = retVal->getEventList(static_cast<detid_t>(i));
for (std::size_t ie = 0; ie < numbins; ie++) {
// Create a list of events, randomize
Federico Montesino Pouzols
committed
events += TofEvent(static_cast<double>(randomGen.nextValue()),
static_cast<int64_t>(randomGen.nextValue()));
}
events.addDetectorID(detid_t(i));
}
retVal->setAllX(axis);
retVal->replaceAxis(0, pAxis0);
// =====================================================================================
/** Create Workspace2d, with numHist spectra, each with 9 detectors,
* with IDs 1-9, 10-18, 19-27
*/
MatrixWorkspace_sptr CreateGroupedWorkspace2D(size_t numHist, int numBins,
double binDelta) {
Workspace2D_sptr retVal = Create2DWorkspaceBinned(static_cast<int>(numHist),
numBins, 0.0, binDelta);
retVal->setInstrument(
ComponentCreationHelper::createTestInstrumentCylindrical(
static_cast<int>(numHist)));
for (int g = 0; g < static_cast<int>(numHist); g++) {
ISpectrum *spec = retVal->getSpectrum(g);
for (int i = 1; i <= 9; i++)
spec->addDetectorID(g * 9 + i);
spec->setSpectrumNo(g + 1); // Match detector ID and spec NO
}
return boost::dynamic_pointer_cast<MatrixWorkspace>(retVal);
}
// =====================================================================================
// RootOfNumHist == square root of hystohram number;
MatrixWorkspace_sptr
CreateGroupedWorkspace2DWithRingsAndBoxes(size_t RootOfNumHist, int numBins,
double binDelta) {
size_t numHist = RootOfNumHist * RootOfNumHist;
Workspace2D_sptr retVal = Create2DWorkspaceBinned(static_cast<int>(numHist),
numBins, 0.0, binDelta);
retVal->setInstrument(
ComponentCreationHelper::createTestInstrumentCylindrical(
static_cast<int>(numHist)));
for (int g = 0; g < static_cast<int>(numHist); g++) {
ISpectrum *spec = retVal->getSpectrum(g);
for (int i = 1; i <= 9; i++)
spec->addDetectorID(g * 9 + i);
spec->setSpectrumNo(g + 1); // Match detector ID and spec NO
Gigg, Martyn Anthony
committed
}
return boost::dynamic_pointer_cast<MatrixWorkspace>(retVal);
}
Gigg, Martyn Anthony
committed
// not strictly creating a workspace, but really helpfull to see what one
// contains
void DisplayDataY(const MatrixWorkspace_sptr ws) {
const size_t numHists = ws->getNumberHistograms();
for (size_t i = 0; i < numHists; ++i) {
std::cout << "Histogram " << i << " = ";
for (size_t j = 0; j < ws->blocksize(); ++j) {
std::cout << ws->readY(i)[j] << " ";
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
}
}
void DisplayData(const MatrixWorkspace_sptr ws) { DisplayDataX(ws); }
// not strictly creating a workspace, but really helpfull to see what one
// contains
void DisplayDataX(const MatrixWorkspace_sptr ws) {
const size_t numHists = ws->getNumberHistograms();
for (size_t i = 0; i < numHists; ++i) {
std::cout << "Histogram " << i << " = ";
for (size_t j = 0; j < ws->blocksize(); ++j) {
std::cout << ws->readX(i)[j] << " ";
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
// not strictly creating a workspace, but really helpfull to see what one
// contains
void DisplayDataE(const MatrixWorkspace_sptr ws) {
const size_t numHists = ws->getNumberHistograms();
for (size_t i = 0; i < numHists; ++i) {
std::cout << "Histogram " << i << " = ";
for (size_t j = 0; j < ws->blocksize(); ++j) {
std::cout << ws->readE(i)[j] << " ";
}
std::cout << std::endl;
Janik Zikovsky
committed
}
Janik Zikovsky
committed
// =====================================================================================
/** Utility function to add a TimeSeriesProperty with a name and value
*
* @param runInfo :: Run to add to
* @param name :: property name
* @param val :: value
*/
void AddTSPEntry(Run &runInfo, std::string name, double val) {
TimeSeriesProperty<double> *tsp;
tsp = new TimeSeriesProperty<double>(name);
tsp->addValue("2011-05-24T00:00:00", val);
runInfo.addProperty(tsp);
}
// =====================================================================================
/** Sets the OrientedLattice in the crystal as an crystal with given lattice
*lengths, angles of 90 deg
*
* @param ws :: workspace to set
* @param a :: lattice length
* @param b :: lattice length
* @param c :: lattice length
*/
void SetOrientedLattice(Mantid::API::MatrixWorkspace_sptr ws, double a,
double b, double c) {
auto latt =
Mantid::Kernel::make_unique<OrientedLattice>(a, b, c, 90., 90., 90.);
ws->mutableSample().setOrientedLattice(latt.release());
}
// =====================================================================================
/** Create a default universal goniometer and set its angles
*
* @param ws :: workspace to set
* @param phi :: +Y rotation angle (deg)
* @param chi :: +X rotation angle (deg)
* @param omega :: +Y rotation angle (deg)
*/
void SetGoniometer(Mantid::API::MatrixWorkspace_sptr ws, double phi, double chi,
double omega) {
AddTSPEntry(ws->mutableRun(), "phi", phi);
AddTSPEntry(ws->mutableRun(), "chi", chi);
AddTSPEntry(ws->mutableRun(), "omega", omega);
Mantid::Geometry::Goniometer gm;
gm.makeUniversalGoniometer();
ws->mutableRun().setGoniometer(gm, true);
}
//
Mantid::API::MatrixWorkspace_sptr
createProcessedWorkspaceWithCylComplexInstrument(size_t numPixels,
size_t numBins,
bool has_oriented_lattice) {
size_t rHist = static_cast<size_t>(std::sqrt(static_cast<double>(numPixels)));
while (rHist * rHist < numPixels)
rHist++;
Mantid::API::MatrixWorkspace_sptr ws =
CreateGroupedWorkspace2DWithRingsAndBoxes(rHist, 10, 0.1);
auto pAxis0 = new NumericAxis(numBins);
for (size_t i = 0; i < numBins; i++) {
double dE = -1.0 + static_cast<double>(i) * 0.8;
pAxis0->setValue(i, dE);
}
pAxis0->setUnit("DeltaE");
ws->replaceAxis(0, pAxis0);
if (has_oriented_lattice) {
auto latt =
Mantid::Kernel::make_unique<OrientedLattice>(1, 1, 1, 90., 90., 90.);
ws->mutableSample().setOrientedLattice(latt.release());
Janik Zikovsky
committed
AddTSPEntry(ws->mutableRun(), "phi", 0);
AddTSPEntry(ws->mutableRun(), "chi", 0);
AddTSPEntry(ws->mutableRun(), "omega", 0);
Mantid::Geometry::Goniometer gm;
gm.makeUniversalGoniometer();
ws->mutableRun().setGoniometer(gm, true);
Janik Zikovsky
committed
}
/// Create a workspace with all components needed for inelastic analysis and 3
/// detectors in specific places
/// @param L2 -- the sample to detector flight path
/// @param polar -- the detector polar angle
/// @param azimutal -- the detector azimuthal
/// @param numBins -- the number of histogram bins for the workspace
/// @param Emin -- minimal energy transfer
/// @param Emax -- maxinal energy transfer
/// @param Ei -- input beam energy
Mantid::API::MatrixWorkspace_sptr
createProcessedInelasticWS(const std::vector<double> &L2,
const std::vector<double> &polar,
const std::vector<double> &azimutal, size_t numBins,
double Emin, double Emax, double Ei) {
// not used but interface needs it
std::set<int64_t> maskedWorkspaceIndices;
size_t numPixels = L2.size();
Mantid::API::MatrixWorkspace_sptr ws =
Create2DWorkspaceWithValues(uint64_t(numPixels), uint64_t(numBins), true,
maskedWorkspaceIndices, 0, 1, 0.1);
// detectors at L2, sample at 0 and source at -L2_min
ws->setInstrument(
ComponentCreationHelper::createCylInstrumentWithDetInGivenPositions(
L2, polar, azimutal));
for (int g = 0; g < static_cast<int>(numPixels); g++) {
ISpectrum *spec = ws->getSpectrum(g);
// we just made (in createCylInstrumentWithDetInGivenPosisions) det ID-s to
// start from 1
spec->setDetectorID(g + 1);
// and this is absolutely different nummer, corresponding to det ID just by
// chance ? -- some uncertainties remain
spec->setSpectrumNo(g + 1);
// spec->setSpectrumNo(g+1);
// spec->addDetectorID(g*9);
// spec->setSpectrumNo(g+1); // Match detector ID and spec NO
double dE = (Emax - Emin) / double(numBins);
for (size_t j = 0; j < numPixels; j++) {
MantidVec &E_transfer = ws->dataX(j);
for (size_t i = 0; i <= numBins; i++) {
double E = Emin + static_cast<double>(i) * dE;
E_transfer[i] = E;
}
// set axis, correspondent to the X-values
auto pAxis0 = new NumericAxis(numBins);
MantidVec &E_transfer = ws->dataX(0);
for (size_t i = 0; i < numBins; i++) {
double E = 0.5 * (E_transfer[i] + E_transfer[i + 1]);
pAxis0->setValue(i, E);
}
// define oriented lattice which requested for processed ws
auto latt =
Mantid::Kernel::make_unique<OrientedLattice>(1, 1, 1, 90., 90., 90.);
ws->mutableSample().setOrientedLattice(latt.release());
ws->mutableRun().addProperty(
new PropertyWithValue<std::string>("deltaE-mode", "Direct"), true);
ws->mutableRun().addProperty(new PropertyWithValue<double>("Ei", Ei), true);
// these properties have to be different -> specific for processed ws, as time
// now should be reconciled
AddTSPEntry(ws->mutableRun(), "phi", 0);
AddTSPEntry(ws->mutableRun(), "chi", 0);
AddTSPEntry(ws->mutableRun(), "omega", 0);
Mantid::Geometry::Goniometer gm;
gm.makeUniversalGoniometer();
ws->mutableRun().setGoniometer(gm, true);
Janik Zikovsky
committed
/*
* Create an EventWorkspace from a source EventWorkspace.
* The new workspace should be exactly the same as the source workspace but
* without any events
*/
Mantid::DataObjects::EventWorkspace_sptr
createEventWorkspace3(Mantid::DataObjects::EventWorkspace_const_sptr sourceWS,
std::string wsname, API::Algorithm *alg) {
UNUSED_ARG(wsname);
// 1. Initialize:use dummy numbers for arguments, for event workspace it
// doesn't matter
Mantid::DataObjects::EventWorkspace_sptr outputWS =
Mantid::DataObjects::EventWorkspace_sptr(
new DataObjects::EventWorkspace());
// outputWS->setName(wsname);
outputWS->initialize(1, 1, 1);
// 2. Set the units
outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
outputWS->setYUnit("Counts");
outputWS->setTitle("Empty_Title");
// 3. Add the run_start property:
int runnumber = sourceWS->getRunNumber();