本文整理汇总了C++中api::MatrixWorkspace_sptr::readX方法的典型用法代码示例。如果您正苦于以下问题:C++ MatrixWorkspace_sptr::readX方法的具体用法?C++ MatrixWorkspace_sptr::readX怎么用?C++ MatrixWorkspace_sptr::readX使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类api::MatrixWorkspace_sptr
的用法示例。
在下文中一共展示了MatrixWorkspace_sptr::readX方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: pow
/** Smoothing using Butterworth filter.
* @param n :: The cutoff frequency control parameter.
* Cutoff frequency = my/n where my is the
* number of sample points in the data.
* As with the "Zeroing" case, the cutoff
* frequency is truncated to an integer value
* and set to 1 if the truncated value was zero.
* @param order :: The order of the Butterworth filter, 1, 2, etc.
* This must be a positive integer.
* @param unfilteredWS :: workspace for storing the unfiltered Fourier
* transform of the input spectrum
* @param filteredWS :: workspace for storing the filtered spectrum
*/
void FFTSmooth2::Butterworth(int n, int order,
API::MatrixWorkspace_sptr &unfilteredWS,
API::MatrixWorkspace_sptr &filteredWS) {
int mx = static_cast<int>(unfilteredWS->readX(0).size());
int my = static_cast<int>(unfilteredWS->readY(0).size());
int ny = my / n;
if (ny == 0)
ny = 1;
filteredWS =
API::WorkspaceFactory::Instance().create(unfilteredWS, 2, mx, my);
const Mantid::MantidVec &Yr = unfilteredWS->readY(0);
const Mantid::MantidVec &Yi = unfilteredWS->readY(1);
const Mantid::MantidVec &X = unfilteredWS->readX(0);
Mantid::MantidVec &yr = filteredWS->dataY(0);
Mantid::MantidVec &yi = filteredWS->dataY(1);
Mantid::MantidVec &xr = filteredWS->dataX(0);
Mantid::MantidVec &xi = filteredWS->dataX(1);
xr.assign(X.begin(), X.end());
xi.assign(X.begin(), X.end());
yr.assign(Yr.size(), 0);
yi.assign(Yr.size(), 0);
double cutoff = ny;
for (int i = 0; i < my; i++) {
double scale = 1.0 / (1.0 + pow(i / cutoff, 2 * order));
yr[i] = scale * Yr[i];
yi[i] = scale * Yi[i];
}
}
示例2:
/** Smoothing by zeroing.
* @param n :: The order of truncation
* @param unfilteredWS :: workspace for storing the unfiltered Fourier
* transform of the input spectrum
* @param filteredWS :: workspace for storing the filtered spectrum
*/
void FFTSmooth2::zero(int n, API::MatrixWorkspace_sptr &unfilteredWS,
API::MatrixWorkspace_sptr &filteredWS) {
int mx = static_cast<int>(unfilteredWS->readX(0).size());
int my = static_cast<int>(unfilteredWS->readY(0).size());
int ny = my / n;
if (ny == 0)
ny = 1;
filteredWS =
API::WorkspaceFactory::Instance().create(unfilteredWS, 2, mx, my);
const Mantid::MantidVec &Yr = unfilteredWS->readY(0);
const Mantid::MantidVec &Yi = unfilteredWS->readY(1);
const Mantid::MantidVec &X = unfilteredWS->readX(0);
Mantid::MantidVec &yr = filteredWS->dataY(0);
Mantid::MantidVec &yi = filteredWS->dataY(1);
Mantid::MantidVec &xr = filteredWS->dataX(0);
Mantid::MantidVec &xi = filteredWS->dataX(1);
xr.assign(X.begin(), X.end());
xi.assign(X.begin(), X.end());
yr.assign(Yr.size(), 0);
yi.assign(Yr.size(), 0);
for (int i = 0; i < ny; i++) {
yr[i] = Yr[i];
yi[i] = Yi[i];
}
}
示例3: checkInputsForNumericWorkspace
/**
* Validation of the inputs of the RingProfile algorithm.
*
* Inside this method, the Workspace is considered a 2D Matrix, where each
*spectrum is
* the rows of the matrix and have the variation in axis0. The columns of the
*matrix
* is the position of dataX(0)
*
* The main validation are:
* - the centre of the ring is inside the image it self.
* - The minimum ring is smaller than the limits of the image to allow
* @param inputWS: pointer to the input workspace
*/
void RingProfile::checkInputsForNumericWorkspace(
const API::MatrixWorkspace_sptr inputWS) {
g_log.notice() << "CheckingInputs For Numeric Workspace" << std::endl;
// The Axis0 is defined by the values of readX inside the spectra of the
// workspace.
// The limits of this axis will be get by inspection of the readX vector
// taking the first
// and the last value.
// check that centre is inside the range available for the instrument
const MantidVec &refX = inputWS->readX(inputWS->getNumberHistograms() / 2);
// get the limits of the axis 0 (X)
double min_v_x, max_v_x;
min_v_x = std::min(refX[0], refX[refX.size() - 1]);
max_v_x = std::max(refX[0], refX[refX.size() - 1]);
g_log.notice() << "Limits X = " << min_v_x << " " << max_v_x << std::endl;
// check centre is inside the X domain
if (centre_x < min_v_x || centre_x > max_v_x) {
std::stringstream s;
s << "The input value for centre (X=" << centre_x
<< ") is outside the limits of the instrument [" << min_v_x << ", "
<< max_v_x << "]";
throw std::invalid_argument(s.str());
}
// The Axis1 is defined by the spectra inside the workspace. Its limits and
// values are given by the
// ws->getAxis(1)
// get the limits of the axis1 (Y)
API::NumericAxis *oldAxis2 =
dynamic_cast<API::NumericAxis *>(inputWS->getAxis(1));
// we cannot have the positions in Y direction without a NumericAxis
if (!oldAxis2)
throw std::invalid_argument("Vertical axis is not a numeric axis. If it is "
"a spectra axis try running "
"ConvertSpectrumAxis first.");
double min_v_y = std::min(oldAxis2->getMin(), oldAxis2->getMax());
double max_v_y = std::max(oldAxis2->getMin(), oldAxis2->getMax());
g_log.notice() << "Limits Y = " << min_v_y << " " << max_v_y << std::endl;
// check centre is inside the Y domain
if (centre_y < min_v_y || centre_y > max_v_y) {
std::stringstream s;
s << "The input value for centre (Y=" << centre_y
<< ") is outside the limits of the instrument [" << min_v_y << ", "
<< max_v_y << "]";
throw std::invalid_argument(s.str());
}
g_log.notice() << "Centre: " << centre_x << " " << centre_y << std::endl;
// check minradius is inside the limits of the region of the instrument
if (centre_x - min_radius > max_v_x || centre_x + min_radius < min_v_x ||
centre_y - min_radius > max_v_y || centre_y + min_radius < min_v_y)
throw std::invalid_argument(
"The minimun radius is outside the region of the instrument");
}
示例4: getMinBinSizeForNumericImage
double RadiusSum::getMinBinSizeForNumericImage(API::MatrixWorkspace_sptr inWS) {
// The pixel dimensions:
// - width: image width/ number of pixels in one row
// - height: image height/ number of pixels in one column
// The minimum bin size is the smallest value between this two values.
std::vector<double> boundaries = getBoundariesOfNumericImage(inWS);
const MantidVec &refX = inWS->readX(inputWS->getNumberHistograms() / 2);
int nX = static_cast<int>(refX.size());
int nY = static_cast<int>(inWS->getAxis(1)->length());
// remembering boundaries is defined as { xMin, xMax, yMin, yMax}
return std::min(((boundaries[1] - boundaries[0]) / nX),
((boundaries[3] - boundaries[2]) / nY));
}
示例5: invalid_argument
/** Assuming that the input workspace is a Numeric Image where the pixel
*positions depend on their
* relative position inside the workspace, this function extracts the position
*of the first and last
* pixel of the image.
*
* It is important that the input workspace must be a numeric image, and not an
*instrument related workspace.
* The function will raise exception (std::invalid_argument) if an invalid
*input is give.
*
* @see RadiusSum::inputWorkspaceHasInstrumentAssociated for reference.
*
* @param inWS reference to the workspace
* @return a list of values that defines the limits of the image in this order:
*Xmin, Xmax, Ymin, Ymax
*/
std::vector<double>
RadiusSum::getBoundariesOfNumericImage(API::MatrixWorkspace_sptr inWS) {
// horizontal axis
// get the pixel position in the horizontal axis from the middle of the image.
const MantidVec &refX = inWS->readX(inWS->getNumberHistograms() / 2);
double min_x, max_x;
const double &first_x(refX[0]);
const double &last_x(refX[refX.size() - 1]);
if (first_x < last_x) {
min_x = first_x;
max_x = last_x;
} else {
min_x = last_x;
max_x = first_x;
}
// vertical axis
API::NumericAxis *verticalAxis =
dynamic_cast<API::NumericAxis *>(inWS->getAxis(1));
if (!verticalAxis)
throw std::invalid_argument("Vertical axis is not a numeric axis. Can not "
"find the limits of the image.");
double min_y, max_y;
min_y = verticalAxis->getMin();
max_y = verticalAxis->getMax();
// check the assumption made that verticalAxis will provide the correct
// answer.
if (min_y > max_y) {
throw std::logic_error("Failure to get the boundaries of this image. "
"Internal logic error. Please, inform MantidHelp");
}
std::vector<double> output(4); // output = {min_x, max_x, min_y, max_y}; not
// supported in all compilers
output[0] = min_x;
output[1] = max_x;
output[2] = min_y;
output[3] = max_y;
return output;
}
示例6: normaliseBinByBin
/** Carries out the bin-by-bin normalisation
* @param inputWorkspace The input workspace
* @param outputWorkspace The result workspace
*/
void NormaliseToMonitor::normaliseBinByBin(API::MatrixWorkspace_sptr inputWorkspace,
API::MatrixWorkspace_sptr& outputWorkspace)
{
EventWorkspace_sptr inputEvent = boost::dynamic_pointer_cast<EventWorkspace>(inputWorkspace);
EventWorkspace_sptr outputEvent;
// Only create output workspace if different to input one
if (outputWorkspace != inputWorkspace )
{
if (inputEvent)
{
//Make a brand new EventWorkspace
outputEvent = boost::dynamic_pointer_cast<EventWorkspace>(
API::WorkspaceFactory::Instance().create("EventWorkspace", inputEvent->getNumberHistograms(), 2, 1));
//Copy geometry and data
API::WorkspaceFactory::Instance().initializeFromParent(inputEvent, outputEvent, false);
outputEvent->copyDataFrom( (*inputEvent) );
outputWorkspace = boost::dynamic_pointer_cast<MatrixWorkspace>(outputEvent);
}
else
outputWorkspace = WorkspaceFactory::Instance().create(inputWorkspace);
}
// Get hold of the monitor spectrum
const MantidVec& monX = m_monitor->readX(0);
MantidVec& monY = m_monitor->dataY(0);
MantidVec& monE = m_monitor->dataE(0);
// Calculate the overall normalisation just the once if bins are all matching
if (m_commonBins) this->normalisationFactor(m_monitor->readX(0),&monY,&monE);
const size_t numHists = inputWorkspace->getNumberHistograms();
MantidVec::size_type specLength = inputWorkspace->blocksize();
Progress prog(this,0.0,1.0,numHists);
// Loop over spectra
PARALLEL_FOR3(inputWorkspace,outputWorkspace,m_monitor)
for (int64_t i = 0; i < int64_t(numHists); ++i)
{
PARALLEL_START_INTERUPT_REGION
prog.report();
const MantidVec& X = inputWorkspace->readX(i);
// If not rebinning, just point to our monitor spectra, otherwise create new vectors
MantidVec* Y = ( m_commonBins ? &monY : new MantidVec(specLength) );
MantidVec* E = ( m_commonBins ? &monE : new MantidVec(specLength) );
if (!m_commonBins)
{
// ConvertUnits can give X vectors of all zeroes - skip these, they cause problems
if (X.back() == 0.0 && X.front() == 0.0) continue;
// Rebin the monitor spectrum to match the binning of the current data spectrum
VectorHelper::rebinHistogram(monX,monY,monE,X,*Y,*E,false);
// Recalculate the overall normalisation factor
this->normalisationFactor(X,Y,E);
}
if (inputEvent)
{
// ----------------------------------- EventWorkspace ---------------------------------------
EventList & outEL = outputEvent->getEventList(i);
outEL.divide(X, *Y, *E);
}
else
{
// ----------------------------------- Workspace2D ---------------------------------------
const MantidVec& inY = inputWorkspace->readY(i);
const MantidVec& inE = inputWorkspace->readE(i);
MantidVec& YOut = outputWorkspace->dataY(i);
MantidVec& EOut = outputWorkspace->dataE(i);
outputWorkspace->dataX(i) = inputWorkspace->readX(i);
// The code below comes more or less straight out of Divide.cpp
for (MantidVec::size_type k = 0; k < specLength; ++k)
{
// Get references to the input Y's
const double& leftY = inY[k];
const double& rightY = (*Y)[k];
// Calculate result and store in local variable to avoid overwriting original data if
// output workspace is same as one of the input ones
const double newY = leftY/rightY;
if (fabs(rightY)>1.0e-12 && fabs(newY)>1.0e-12)
{
const double lhsFactor = (inE[k]<1.0e-12|| fabs(leftY)<1.0e-12) ? 0.0 : pow((inE[k]/leftY),2);
const double rhsFactor = (*E)[k]<1.0e-12 ? 0.0 : pow(((*E)[k]/rightY),2);
EOut[k] = std::abs(newY) * sqrt(lhsFactor+rhsFactor);
}
// Now store the result
YOut[k] = newY;
} // end Workspace2D case
} // end loop over current spectrum
if (!m_commonBins) { delete Y; delete E; }
PARALLEL_END_INTERUPT_REGION
} // end loop over spectra
//.........这里部分代码省略.........
示例7: exec
/** Executes the algorithm
*
*/
void SplineBackground::exec()
{
API::MatrixWorkspace_sptr inWS = getProperty("InputWorkspace");
int spec = getProperty("WorkspaceIndex");
if (spec > static_cast<int>(inWS->getNumberHistograms()))
throw std::out_of_range("WorkspaceIndex is out of range.");
const MantidVec& X = inWS->readX(spec);
const MantidVec& Y = inWS->readY(spec);
const MantidVec& E = inWS->readE(spec);
const bool isHistogram = inWS->isHistogramData();
const int ncoeffs = getProperty("NCoeff");
const int k = 4; // order of the spline + 1 (cubic)
const int nbreak = ncoeffs - (k - 2);
if (nbreak <= 0)
throw std::out_of_range("Too low NCoeff");
gsl_bspline_workspace *bw;
gsl_vector *B;
gsl_vector *c, *w, *x, *y;
gsl_matrix *Z, *cov;
gsl_multifit_linear_workspace *mw;
double chisq;
int n = static_cast<int>(Y.size());
bool isMasked = inWS->hasMaskedBins(spec);
std::vector<int> masked(Y.size());
if (isMasked)
{
for(API::MatrixWorkspace::MaskList::const_iterator it=inWS->maskedBins(spec).begin();it!=inWS->maskedBins(spec).end();++it)
masked[it->first] = 1;
n -= static_cast<int>(inWS->maskedBins(spec).size());
}
if (n < ncoeffs)
{
g_log.error("Too many basis functions (NCoeff)");
throw std::out_of_range("Too many basis functions (NCoeff)");
}
/* allocate a cubic bspline workspace (k = 4) */
bw = gsl_bspline_alloc(k, nbreak);
B = gsl_vector_alloc(ncoeffs);
x = gsl_vector_alloc(n);
y = gsl_vector_alloc(n);
Z = gsl_matrix_alloc(n, ncoeffs);
c = gsl_vector_alloc(ncoeffs);
w = gsl_vector_alloc(n);
cov = gsl_matrix_alloc(ncoeffs, ncoeffs);
mw = gsl_multifit_linear_alloc(n, ncoeffs);
/* this is the data to be fitted */
int j = 0;
for (MantidVec::size_type i = 0; i < Y.size(); ++i)
{
if (isMasked && masked[i]) continue;
gsl_vector_set(x, j, (isHistogram ? (0.5*(X[i]+X[i+1])) : X[i])); // Middle of the bins, if a histogram
gsl_vector_set(y, j, Y[i]);
gsl_vector_set(w, j, E[i]>0.?1./(E[i]*E[i]):0.);
++j;
}
if (n != j)
{
gsl_bspline_free(bw);
gsl_vector_free(B);
gsl_vector_free(x);
gsl_vector_free(y);
gsl_matrix_free(Z);
gsl_vector_free(c);
gsl_vector_free(w);
gsl_matrix_free(cov);
gsl_multifit_linear_free(mw);
throw std::runtime_error("Assertion failed: n != j");
}
double xStart = X.front();
double xEnd = X.back();
/* use uniform breakpoints */
gsl_bspline_knots_uniform(xStart, xEnd, bw);
/* construct the fit matrix X */
for (int i = 0; i < n; ++i)
{
double xi=gsl_vector_get(x, i);
/* compute B_j(xi) for all j */
gsl_bspline_eval(xi, B, bw);
//.........这里部分代码省略.........
示例8: exec
/** Executes the algorithm
* @throw Exception::FileError If the calibration file cannot be opened and
* read successfully
* @throw Exception::InstrumentDefinitionError If unable to obtain the
* source-sample distance
*/
void AlignDetectors::exec() {
// Get the input workspace
MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
this->getCalibrationWS(inputWS);
// Initialise the progress reporting object
m_numberOfSpectra = static_cast<int64_t>(inputWS->getNumberHistograms());
// Check if its an event workspace
EventWorkspace_const_sptr eventW =
boost::dynamic_pointer_cast<const EventWorkspace>(inputWS);
if (eventW != nullptr) {
this->execEvent();
return;
}
API::MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
// If input and output workspaces are not the same, create a new workspace for
// the output
if (outputWS != inputWS) {
outputWS = WorkspaceFactory::Instance().create(inputWS);
setProperty("OutputWorkspace", outputWS);
}
// Set the final unit that our output workspace will have
setXAxisUnits(outputWS);
ConversionFactors converter = ConversionFactors(m_calibrationWS);
Progress progress(this, 0.0, 1.0, m_numberOfSpectra);
// Loop over the histograms (detector spectra)
PARALLEL_FOR2(inputWS, outputWS)
for (int64_t i = 0; i < m_numberOfSpectra; ++i) {
PARALLEL_START_INTERUPT_REGION
try {
// Get the input spectrum number at this workspace index
auto inSpec = inputWS->getSpectrum(size_t(i));
auto toDspacing = converter.getConversionFunc(inSpec->getDetectorIDs());
// Get references to the x data
MantidVec &xOut = outputWS->dataX(i);
// Make sure reference to input X vector is obtained after output one
// because in the case
// where the input & output workspaces are the same, it might move if the
// vectors were shared.
const MantidVec &xIn = inSpec->readX();
std::transform(xIn.begin(), xIn.end(), xOut.begin(), toDspacing);
// Copy the Y&E data
outputWS->dataY(i) = inSpec->readY();
outputWS->dataE(i) = inSpec->readE();
} catch (Exception::NotFoundError &) {
// Zero the data in this case
outputWS->dataX(i).assign(outputWS->readX(i).size(), 0.0);
outputWS->dataY(i).assign(outputWS->readY(i).size(), 0.0);
outputWS->dataE(i).assign(outputWS->readE(i).size(), 0.0);
}
progress.report();
PARALLEL_END_INTERUPT_REGION
}
PARALLEL_CHECK_INTERUPT_REGION
}
示例9: copyInput
/**
* Execute smoothing of a single spectrum.
* @param inputWS :: A workspace to pick a spectrum from.
* @param wsIndex :: An index of a spectrum to smooth.
* @return :: A single-spectrum workspace with the smoothed data.
*/
API::MatrixWorkspace_sptr
WienerSmooth::smoothSingleSpectrum(API::MatrixWorkspace_sptr inputWS,
size_t wsIndex) {
size_t dataSize = inputWS->blocksize();
// it won't work for very small workspaces
if (dataSize < 4) {
g_log.debug() << "No smoothing, spectrum copied." << std::endl;
return copyInput(inputWS, wsIndex);
}
// Due to the way RealFFT works the input should be even-sized
const bool isOddSize = dataSize % 2 != 0;
if (isOddSize) {
// add a fake value to the end to make size even
inputWS = copyInput(inputWS, wsIndex);
wsIndex = 0;
auto &X = inputWS->dataX(wsIndex);
auto &Y = inputWS->dataY(wsIndex);
auto &E = inputWS->dataE(wsIndex);
double dx = X[dataSize - 1] - X[dataSize - 2];
X.push_back(X.back() + dx);
Y.push_back(Y.back());
E.push_back(E.back());
}
// the input vectors
auto &X = inputWS->readX(wsIndex);
auto &Y = inputWS->readY(wsIndex);
auto &E = inputWS->readE(wsIndex);
// Digital fourier transform works best for data oscillating around 0.
// Fit a spline with a small number of break points to the data.
// Make sure that the spline passes through the first and the last points
// of the data.
// The fitted spline will be subtracted from the data and the difference
// will be smoothed with the Wiener filter. After that the spline will be
// added to the smoothed data to produce the output.
// number of spline break points, must be smaller than the data size but
// between 2 and 10
size_t nbreak = 10;
if (nbreak * 3 > dataSize)
nbreak = dataSize / 3;
// NB. The spline mustn't fit too well to the data. If it does smoothing
// doesn't happen.
// TODO: it's possible that the spline is unnecessary and a simple linear
// function will
// do a better job.
g_log.debug() << "Spline break points " << nbreak << std::endl;
// define the spline
API::IFunction_sptr spline =
API::FunctionFactory::Instance().createFunction("BSpline");
auto xInterval = getStartEnd(X, inputWS->isHistogramData());
spline->setAttributeValue("StartX", xInterval.first);
spline->setAttributeValue("EndX", xInterval.second);
spline->setAttributeValue("NBreak", static_cast<int>(nbreak));
// fix the first and last parameters to the first and last data values
spline->setParameter(0, Y.front());
spline->fix(0);
size_t lastParamIndex = spline->nParams() - 1;
spline->setParameter(lastParamIndex, Y.back());
spline->fix(lastParamIndex);
// fit the spline to the data
auto fit = createChildAlgorithm("Fit");
fit->initialize();
fit->setProperty("Function", spline);
fit->setProperty("InputWorkspace", inputWS);
fit->setProperty("WorkspaceIndex", static_cast<int>(wsIndex));
fit->setProperty("CreateOutput", true);
fit->execute();
// get the fit output workspace; spectrum 2 contains the difference that is to
// be smoothed
API::MatrixWorkspace_sptr fitOut = fit->getProperty("OutputWorkspace");
// Fourier transform the difference spectrum
auto fourier = createChildAlgorithm("RealFFT");
fourier->initialize();
fourier->setProperty("InputWorkspace", fitOut);
fourier->setProperty("WorkspaceIndex", 2);
// we don't require bin linearity as we don't need the exact transform
fourier->setProperty("IgnoreXBins", true);
fourier->execute();
API::MatrixWorkspace_sptr fourierOut =
fourier->getProperty("OutputWorkspace");
// spectrum 2 of the transformed workspace has the transform modulus which is
// a square
//.........这里部分代码省略.........
示例10: calcIntAsymmetry
/** Calculate the integral asymmetry for a workspace (red & green).
* The calculation is done by MuonAsymmetryCalc and SimpleIntegration algorithms.
* @param ws_red :: The red workspace
* @param ws_green :: The green workspace
* @param Y :: Reference to a variable receiving the value of asymmetry
* @param E :: Reference to a variable receiving the value of the error
*/
void PlotAsymmetryByLogValue::calcIntAsymmetry(API::MatrixWorkspace_sptr ws_red,
API::MatrixWorkspace_sptr ws_green,double& Y, double& E)
{
if ( !m_autogroup )
{
groupDetectors(ws_red,m_backward_list);
groupDetectors(ws_red,m_forward_list);
groupDetectors(ws_green,m_backward_list);
groupDetectors(ws_green,m_forward_list);
}
Property* startXprop = getProperty("TimeMin");
Property* endXprop = getProperty("TimeMax");
bool setX = !startXprop->isDefault() && !endXprop->isDefault();
double startX(0.0),endX(0.0);
if (setX)
{
startX = getProperty("TimeMin");
endX = getProperty("TimeMax");
}
if (!m_int)
{ // "Differential asymmetry"
API::MatrixWorkspace_sptr tmpWS = API::WorkspaceFactory::Instance().create(
ws_red,1,ws_red->readX(0).size(),ws_red->readY(0).size());
for(size_t i=0; i<tmpWS->dataY(0).size(); i++)
{
double FNORM = ws_green->readY(0)[i] + ws_red->readY(0)[i];
FNORM = FNORM != 0.0 ? 1.0 / FNORM : 1.0;
double BNORM = ws_green->readY(1)[i] + ws_red->readY(1)[i];
BNORM = BNORM != 0.0 ? 1.0 / BNORM : 1.0;
double ZF = ( ws_green->readY(0)[i] - ws_red->readY(0)[i] ) * FNORM;
double ZB = ( ws_green->readY(1)[i] - ws_red->readY(1)[i] ) * BNORM;
tmpWS->dataY(0)[i] = ZB - ZF;
tmpWS->dataE(0)[i] = (1.0+ZF*ZF)*FNORM+(1.0+ZB*ZB)*BNORM;
}
IAlgorithm_sptr integr = createChildAlgorithm("Integration");
integr->setProperty("InputWorkspace",tmpWS);
integr->setPropertyValue("OutputWorkspace","tmp");
if (setX)
{
integr->setProperty("RangeLower",startX);
integr->setProperty("RangeUpper",endX);
}
integr->execute();
MatrixWorkspace_sptr out = integr->getProperty("OutputWorkspace");
Y = out->readY(0)[0] / static_cast<double>(tmpWS->dataY(0).size());
E = out->readE(0)[0] / static_cast<double>(tmpWS->dataY(0).size());
}
else
{
// "Integral asymmetry"
IAlgorithm_sptr integr = createChildAlgorithm("Integration");
integr->setProperty("InputWorkspace", ws_red);
integr->setPropertyValue("OutputWorkspace","tmp");
if (setX)
{
integr->setProperty("RangeLower",startX);
integr->setProperty("RangeUpper",endX);
}
integr->execute();
API::MatrixWorkspace_sptr intWS_red = integr->getProperty("OutputWorkspace");
integr = createChildAlgorithm("Integration");
integr->setProperty("InputWorkspace", ws_green);
integr->setPropertyValue("OutputWorkspace","tmp");
if (setX)
{
integr->setProperty("RangeLower",startX);
integr->setProperty("RangeUpper",endX);
}
integr->execute();
API::MatrixWorkspace_sptr intWS_green = integr->getProperty("OutputWorkspace");
double YIF = ( intWS_green->readY(0)[0] - intWS_red->readY(0)[0] ) / ( intWS_green->readY(0)[0] + intWS_red->readY(0)[0] );
double YIB = ( intWS_green->readY(1)[0] - intWS_red->readY(1)[0] ) / ( intWS_green->readY(1)[0] + intWS_red->readY(1)[0] );
Y = YIB - YIF;
double VARIF = (1.0 + YIF*YIF) / ( intWS_green->readY(0)[0] + intWS_red->readY(0)[0] );
double VARIB = (1.0 + YIB*YIB) / ( intWS_green->readY(1)[0] + intWS_red->readY(1)[0] );
E = sqrt( VARIF + VARIB );
}
}
示例11: exec
/** Executes the algorithm
* @throw Exception::FileError If the calibration file cannot be opened and read successfully
* @throw Exception::InstrumentDefinitionError If unable to obtain the source-sample distance
*/
void AlignDetectors::exec()
{
// Get the input workspace
MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
// Read in the calibration data
const std::string calFileName = getProperty("CalibrationFile");
OffsetsWorkspace_sptr offsetsWS = getProperty("OffsetsWorkspace");
progress(0.0,"Reading calibration file");
if (offsetsWS && !calFileName.empty())
throw std::invalid_argument("You must specify either CalibrationFile or OffsetsWorkspace but not both.");
if (!offsetsWS && calFileName.empty())
throw std::invalid_argument("You must specify either CalibrationFile or OffsetsWorkspace.");
if (!calFileName.empty())
{
// Load the .cal file
IAlgorithm_sptr alg = createChildAlgorithm("LoadCalFile");
alg->setPropertyValue("CalFilename", calFileName);
alg->setProperty("InputWorkspace", inputWS);
alg->setProperty<bool>("MakeGroupingWorkspace", false);
alg->setProperty<bool>("MakeOffsetsWorkspace", true);
alg->setProperty<bool>("MakeMaskWorkspace", false);
alg->setPropertyValue("WorkspaceName", "temp");
alg->executeAsChildAlg();
offsetsWS = alg->getProperty("OutputOffsetsWorkspace");
}
const int64_t numberOfSpectra = inputWS->getNumberHistograms();
// generate map of the tof->d conversion factors
this->tofToDmap = calcTofToD_ConversionMap(inputWS, offsetsWS);
//Check if its an event workspace
EventWorkspace_const_sptr eventW = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS);
if (eventW != NULL)
{
this->execEvent();
return;
}
API::MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
// If input and output workspaces are not the same, create a new workspace for the output
if (outputWS != inputWS )
{
outputWS = WorkspaceFactory::Instance().create(inputWS);
setProperty("OutputWorkspace",outputWS);
}
// Set the final unit that our output workspace will have
outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("dSpacing");
// Initialise the progress reporting object
Progress progress(this,0.0,1.0,numberOfSpectra);
// Loop over the histograms (detector spectra)
PARALLEL_FOR2(inputWS,outputWS)
for (int64_t i = 0; i < int64_t(numberOfSpectra); ++i)
{
PARALLEL_START_INTERUPT_REGION
try {
// Get the input spectrum number at this workspace index
const ISpectrum * inSpec = inputWS->getSpectrum(size_t(i));
const double factor = calcConversionFromMap(this->tofToDmap, inSpec->getDetectorIDs());
// Get references to the x data
MantidVec& xOut = outputWS->dataX(i);
// Make sure reference to input X vector is obtained after output one because in the case
// where the input & output workspaces are the same, it might move if the vectors were shared.
const MantidVec& xIn = inSpec->readX();
//std::transform( xIn.begin(), xIn.end(), xOut.begin(), std::bind2nd(std::multiplies<double>(), factor) );
// the above transform creates wrong output in parallel in debug in Visual Studio
for(size_t k = 0; k < xOut.size(); ++k)
{
xOut[k] = xIn[k] * factor;
}
// Copy the Y&E data
outputWS->dataY(i) = inSpec->readY();
outputWS->dataE(i) = inSpec->readE();
} catch (Exception::NotFoundError &) {
// Zero the data in this case
outputWS->dataX(i).assign(outputWS->readX(i).size(),0.0);
outputWS->dataY(i).assign(outputWS->readY(i).size(),0.0);
outputWS->dataE(i).assign(outputWS->readE(i).size(),0.0);
}
progress.report();
PARALLEL_END_INTERUPT_REGION
}
PARALLEL_CHECK_INTERUPT_REGION
}