/** * Computes the square root of the errors and if the input was a distribution * this divides by the new bin-width * @param outputWS The workspace containing the output data * @param inputWS The input workspace used for testing distribution state */ void Rebin2D::normaliseOutput(MatrixWorkspace_sptr outputWS, MatrixWorkspace_const_sptr inputWS) { //PARALLEL_FOR1(outputWS) for(int64_t i = 0; i < static_cast<int64_t>(outputWS->getNumberHistograms()); ++i) { PARALLEL_START_INTERUPT_REGION MantidVec & outputY = outputWS->dataY(i); MantidVec & outputE = outputWS->dataE(i); for(size_t j = 0; j < outputWS->blocksize(); ++j) { m_progress->report("Calculating errors"); const double binWidth = (outputWS->readX(i)[j+1] - outputWS->readX(i)[j]); double eValue = std::sqrt(outputE[j]); // Don't do this for a RebinnedOutput workspace. The fractions // take care of such things. if( inputWS->isDistribution() && inputWS->id() != "RebinnedOutput") { outputY[j] /= binWidth; eValue /= binWidth; } outputE[j] = eValue; } PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION outputWS->isDistribution(inputWS->isDistribution()); }
/** Populates the output workspaces * @param inWS :: [input] The input workspace * @param spec :: [input] The current spectrum being analyzed * @param nspec :: [input] The total number of histograms in the input workspace * @param result :: [input] The result to be written in the output workspace * @param outWS :: [input] The output workspace to populate */ void MaxEnt::populateDataWS(const MatrixWorkspace_sptr &inWS, size_t spec, size_t nspec, const std::vector<double> &result, MatrixWorkspace_sptr &outWS) { if (result.size() % 2) throw std::invalid_argument("Cannot write results to output workspaces"); int npoints = static_cast<int>(result.size() / 2); int npointsX = inWS->isHistogramData() ? npoints + 1 : npoints; MantidVec X(npointsX); MantidVec YR(npoints); MantidVec YI(npoints); MantidVec E(npoints, 0.); double x0 = inWS->readX(spec)[0]; double dx = inWS->readX(spec)[1] - x0; for (int i = 0; i < npoints; i++) { X[i] = x0 + i * dx; YR[i] = result[2 * i]; YI[i] = result[2 * i + 1]; } if (npointsX == npoints + 1) X[npoints] = x0 + npoints * dx; outWS->dataX(spec).assign(X.begin(), X.end()); outWS->dataY(spec).assign(YR.begin(), YR.end()); outWS->dataE(spec).assign(E.begin(), E.end()); outWS->dataX(nspec + spec).assign(X.begin(), X.end()); outWS->dataY(nspec + spec).assign(YI.begin(), YI.end()); outWS->dataE(nspec + spec).assign(E.begin(), E.end()); }
/** Rebins the distributions and sets error values. */ MatrixWorkspace_sptr VesuvioL1ThetaResolution::processDistribution(MatrixWorkspace_sptr ws, const double binWidth) { const size_t numHist = ws->getNumberHistograms(); double xMin(DBL_MAX); double xMax(DBL_MIN); for (size_t i = 0; i < numHist; i++) { const std::vector<double> &x = ws->readX(i); xMin = std::min(xMin, x.front()); xMax = std::max(xMax, x.back()); } std::stringstream binParams; binParams << xMin << "," << binWidth << "," << xMax; IAlgorithm_sptr rebin = AlgorithmManager::Instance().create("Rebin"); rebin->initialize(); rebin->setChild(true); rebin->setLogging(false); rebin->setProperty("InputWorkspace", ws); rebin->setProperty("OutputWorkspace", "__rebin"); rebin->setProperty("Params", binParams.str()); rebin->execute(); ws = rebin->getProperty("OutputWorkspace"); for (size_t i = 0; i < numHist; i++) { const std::vector<double> &y = ws->readY(i); std::vector<double> &e = ws->dataE(i); std::transform(y.begin(), y.end(), e.begin(), SquareRoot()); } return ws; }
/** * Replots the energy mini plot */ void ISISCalibration::calPlotEnergy() { if ( ! m_uiForm.leRunNo->isValid() ) { emit showMessageBox("Run number not valid."); return; } QString files = m_uiForm.leRunNo->getFilenames().join(","); QFileInfo fi(m_uiForm.leRunNo->getFirstFilename()); QString detRange = QString::number(m_dblManager->value(m_properties["ResSpecMin"])) + "," + QString::number(m_dblManager->value(m_properties["ResSpecMax"])); IAlgorithm_sptr reductionAlg = AlgorithmManager::Instance().create("ISISIndirectEnergyTransfer"); reductionAlg->initialize(); reductionAlg->setProperty("Instrument", getInstrumentConfiguration()->getInstrumentName().toStdString()); reductionAlg->setProperty("Analyser", getInstrumentConfiguration()->getAnalyserName().toStdString()); reductionAlg->setProperty("Reflection", getInstrumentConfiguration()->getReflectionName().toStdString()); reductionAlg->setProperty("InputFiles", files.toStdString()); reductionAlg->setProperty("OutputWorkspace", "__IndirectCalibration_reduction"); reductionAlg->setProperty("SpectraRange", detRange.toStdString()); reductionAlg->execute(); if(!reductionAlg->isExecuted()) { g_log.warning("Could not generate energy preview plot."); return; } WorkspaceGroup_sptr reductionOutputGroup = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>("__IndirectCalibration_reduction"); if(reductionOutputGroup->size() == 0) { g_log.warning("No result workspaces, cannot plot energy preview."); return; } MatrixWorkspace_sptr energyWs = boost::dynamic_pointer_cast<MatrixWorkspace>(reductionOutputGroup->getItem(0)); if(!energyWs) { g_log.warning("No result workspaces, cannot plot energy preview."); return; } const Mantid::MantidVec & dataX = energyWs->readX(0); QPair<double, double> range(dataX.front(), dataX.back()); auto resBackground = m_uiForm.ppResolution->getRangeSelector("ResBackground"); setPlotPropertyRange(resBackground, m_properties["ResStart"], m_properties["ResEnd"], range); m_uiForm.ppResolution->clear(); m_uiForm.ppResolution->addSpectrum("Energy", energyWs, 0); m_uiForm.ppResolution->resizeX(); calSetDefaultResolution(energyWs); m_uiForm.ppResolution->replot(); }
/** Calculate the integral asymmetry for a pair of workspaces (red & green). * @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(MatrixWorkspace_sptr ws_red, MatrixWorkspace_sptr ws_green, double &Y, double &E) { if (!m_int) { // "Differential asymmetry" MatrixWorkspace_sptr tmpWS = 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->setProperty("RangeLower", m_minTime); integr->setProperty("RangeUpper", m_maxTime); 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->setProperty("RangeLower", m_minTime); integr->setProperty("RangeUpper", m_maxTime); integr->execute(); MatrixWorkspace_sptr intWS_red = integr->getProperty("OutputWorkspace"); integr = createChildAlgorithm("Integration"); integr->setProperty("InputWorkspace", ws_green); integr->setProperty("RangeLower", m_minTime); integr->setProperty("RangeUpper", m_maxTime); integr->execute(); 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); } }
/** * Replots the raw data mini plot and the energy mini plot */ void ISISCalibration::calPlotRaw() { QString filename = m_uiForm.leRunNo->getFirstFilename(); // Don't do anything if the file we would plot has not changed if (filename == m_lastCalPlotFilename) return; m_lastCalPlotFilename = filename; if (filename.isEmpty()) { emit showMessageBox("Cannot plot raw data without filename"); return; } QFileInfo fi(filename); QString wsname = fi.baseName(); auto instDetails = getInstrumentDetails(); int specMin = instDetails["spectra-min"].toInt(); int specMax = instDetails["spectra-max"].toInt(); if (!loadFile(filename, wsname, specMin, specMax)) { emit showMessageBox("Unable to load file.\nCheck whether your file exists " "and matches the selected instrument in the Energy " "Transfer tab."); return; } MatrixWorkspace_sptr input = boost::dynamic_pointer_cast<MatrixWorkspace>( AnalysisDataService::Instance().retrieve(wsname.toStdString())); const Mantid::MantidVec &dataX = input->readX(0); QPair<double, double> range(dataX.front(), dataX.back()); m_uiForm.ppCalibration->clear(); m_uiForm.ppCalibration->addSpectrum("Raw", input, 0); m_uiForm.ppCalibration->resizeX(); auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak"); auto calBackground = m_uiForm.ppCalibration->getRangeSelector("CalBackground"); setPlotPropertyRange(calPeak, m_properties["CalELow"], m_properties["CalEHigh"], range); setPlotPropertyRange(calBackground, m_properties["CalStart"], m_properties["CalEnd"], range); setDefaultInstDetails(); m_uiForm.ppCalibration->replot(); // Also replot the energy calPlotEnergy(); }
/** * Checks the input workspace's X data structure is logical. * @param inputWS pointer to input workspace * @returns True if the X structure of the given input is what we expect, i.e. NX=NY+1 */ bool ConvertToPointData::isWorkspaceLogical(const MatrixWorkspace_sptr inputWS) const { const size_t numBins = inputWS->blocksize(); const size_t numBoundaries = inputWS->readX(0).size(); if( numBoundaries != (numBins + 1) ) { g_log.error() << "The number of bin boundaries must be one greater than the number of bins. " << "Found nbins=" << numBins << " and nBoundaries=" << numBoundaries << "\n"; return false; } return true; }
MatrixWorkspace_sptr PolarizationCorrection::copyShapeAndFill(MatrixWorkspace_sptr &base, const double &value) { MatrixWorkspace_sptr wsTemplate = WorkspaceFactory::Instance().create(base); // Copy the x-array across to the new workspace. for (size_t i = 0; i < wsTemplate->getNumberHistograms(); ++i) { wsTemplate->setX(i, base->readX(i)); } auto zeroed = this->multiply(wsTemplate, 0); auto filled = this->add(zeroed, value); return filled; }
/** Validate the input properties. */ std::map<std::string, std::string> MaxEnt::validateInputs() { std::map<std::string, std::string> result; MatrixWorkspace_sptr inWS = getProperty("InputWorkspace"); if (inWS) { // 1. X values in input workspace must be (almost) equally spaced const double warningLevel = 0.01; const double errorLevel = 0.5; bool printWarning = false; // Average spacing const MantidVec &X = inWS->readX(0); const double dx = (X[X.size() - 1] - X[0]) / static_cast<double>(X.size() - 1); for (size_t i = 1; i < X.size() - 1; i++) { // 1% accuracy exceeded, but data still usable if (std::abs(X[i] - X[0] - static_cast<double>(i) * dx) / dx > warningLevel) { printWarning = true; if (std::abs(X[i] - X[0] - static_cast<double>(i) * dx) / dx > errorLevel) { // 50% accuracy exceeded, data not usable printWarning = false; result["InputWorkspace"] = "X axis must be linear (all bins have same width)"; break; } } } if (printWarning) { g_log.warning() << "Bin widths differ by more than " << warningLevel * 100 << "% of average\n"; } // 2. If the input signal is complex, we expect an even number of histograms // in the input workspace size_t nhistograms = inWS->getNumberHistograms(); bool complex = getProperty("ComplexData"); if (complex && (nhistograms % 2)) result["InputWorkspace"] = "The number of histograms in the input " "workspace must be even for complex data"; } return result; }
/** * Rebin the input quadrilateral to the output grid * @param inputQ The input polygon * @param inputWS The input workspace containing the input intensity values * @param i The index in the vertical axis direction that inputQ references * @param j The index in the horizontal axis direction that inputQ references * @param outputWS A pointer to the output workspace that accumulates the data * @param verticalAxis A vector containing the output vertical axis bin boundaries */ void Rebin2D::rebinToOutput(const Geometry::Quadrilateral & inputQ, MatrixWorkspace_const_sptr inputWS, const size_t i, const size_t j, MatrixWorkspace_sptr outputWS, const std::vector<double> & verticalAxis) { const MantidVec & X = outputWS->readX(0); size_t qstart(0), qend(verticalAxis.size()-1), en_start(0), en_end(X.size() - 1); if( !getIntersectionRegion(outputWS, verticalAxis, inputQ, qstart, qend, en_start, en_end)) return; for( size_t qi = qstart; qi < qend; ++qi ) { const double vlo = verticalAxis[qi]; const double vhi = verticalAxis[qi+1]; for( size_t ei = en_start; ei < en_end; ++ei ) { const V2D ll(X[ei], vlo); const V2D lr(X[ei+1], vlo); const V2D ur(X[ei+1], vhi); const V2D ul(X[ei], vhi); const Quadrilateral outputQ(ll, lr, ur, ul); double yValue = inputWS->readY(i)[j]; if (boost::math::isnan(yValue)) { continue; } try { ConvexPolygon overlap = intersectionByLaszlo(outputQ, inputQ); const double weight = overlap.area()/inputQ.area(); yValue *= weight; double eValue = inputWS->readE(i)[j] * weight; const double overlapWidth = overlap.largestX() - overlap.smallestX(); if(inputWS->isDistribution()) { yValue *= overlapWidth; eValue *= overlapWidth; } eValue = eValue*eValue; PARALLEL_CRITICAL(overlap) { outputWS->dataY(qi)[ei] += yValue; outputWS->dataE(qi)[ei] += eValue; } } catch(Geometry::NoIntersectionException &) {} } } }
void IQTransform::exec() { MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); // Print a warning if the input workspace has more than one spectrum if ( inputWS->getNumberHistograms() > 1 ) { g_log.warning("This algorithm is intended for use on single-spectrum workspaces.\n" "Only the first spectrum will be transformed."); } // Do background subtraction from a workspace first because it doesn't like // potential conversion to point data that follows. Requires a temporary workspace. MatrixWorkspace_sptr tmpWS; MatrixWorkspace_sptr backgroundWS = getProperty("BackgroundWorkspace"); if ( backgroundWS ) tmpWS = subtractBackgroundWS(inputWS,backgroundWS); else tmpWS = inputWS; // Create the output workspace const size_t length = tmpWS->blocksize(); MatrixWorkspace_sptr outputWS = WorkspaceFactory::Instance().create(inputWS,1,length,length); m_label->setLabel(""); outputWS->setYUnit(""); // Copy the data over. Assume single spectrum input (output will be). // Take the mid-point of histogram bins if ( tmpWS->isHistogramData() ) { VectorHelper::convertToBinCentre(tmpWS->readX(0),outputWS->dataX(0)); } else { outputWS->setX(0,tmpWS->refX(0)); } MantidVec& Y = outputWS->dataY(0) = tmpWS->dataY(0); outputWS->dataE(0) = tmpWS->dataE(0); // Subtract a constant background if requested const double background = getProperty("BackgroundValue"); if ( background > 0.0 ) subtractBackgroundValue(Y,background); // Select the desired transformation function and call it TransformFunc f = m_transforms.find(getProperty("TransformType"))->second; (this->*f)(outputWS); // Need the generic label unit on this (unless the unit on the X axis hasn't changed) if ( ! m_label->caption().empty() ) outputWS->getAxis(0)->unit() = m_label; setProperty("OutputWorkspace",outputWS); }
/** Uses 'Linear' as a subalgorithm to fit the log of the exponential curve expected for the transmission. * @param WS :: The single-spectrum workspace to fit * @return A workspace containing the fit */ API::MatrixWorkspace_sptr CalculateTransmissionBeamSpreader::fitToData(API::MatrixWorkspace_sptr WS) { g_log.information("Fitting the experimental transmission curve"); Algorithm_sptr childAlg = createSubAlgorithm("Linear",0.6,1.0); childAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", WS); const double lambdaMin = getProperty("MinWavelength"); const double lambdaMax = getProperty("MaxWavelength"); childAlg->setProperty<double>("StartX",lambdaMin); childAlg->setProperty<double>("EndX",lambdaMax); childAlg->executeAsSubAlg(); std::string fitStatus = childAlg->getProperty("FitStatus"); if ( fitStatus != "success" ) { g_log.error("Unable to successfully fit the data: " + fitStatus); throw std::runtime_error("Unable to successfully fit the data"); } // Only get to here if successful MatrixWorkspace_sptr result = childAlg->getProperty("OutputWorkspace"); if (logFit) { // Need to transform back to 'unlogged' double b = childAlg->getProperty("FitIntercept"); double m = childAlg->getProperty("FitSlope"); b = std::pow(10,b); m = std::pow(10,m); const MantidVec & X = result->readX(0); MantidVec & Y = result->dataY(0); MantidVec & E = result->dataE(0); for (size_t i = 0; i < Y.size(); ++i) { Y[i] = b*(std::pow(m,0.5*(X[i]+X[i+1]))); E[i] = std::abs(E[i]*Y[i]); } } return result; }
/** * Groups the workspace according to grouping provided. * * @param ws :: Workspace to group * @param g :: The grouping information * @return Sptr to created grouped workspace */ MatrixWorkspace_sptr groupWorkspace(MatrixWorkspace_const_sptr ws, const Grouping& g) { // As I couldn't specify multiple groups for GroupDetectors, I am going down quite a complicated // route - for every group distinct grouped workspace is created using GroupDetectors. These // workspaces are then merged into the output workspace. // Create output workspace MatrixWorkspace_sptr outWs = WorkspaceFactory::Instance().create(ws, g.groups.size(), ws->readX(0).size(), ws->blocksize()); for(size_t gi = 0; gi < g.groups.size(); gi++) { Mantid::API::IAlgorithm_sptr alg = AlgorithmManager::Instance().create("GroupDetectors"); alg->setChild(true); // So Output workspace is not added to the ADS alg->initialize(); alg->setProperty("InputWorkspace", boost::const_pointer_cast<MatrixWorkspace>(ws)); alg->setPropertyValue("SpectraList", g.groups[gi]); alg->setPropertyValue("OutputWorkspace", "grouped"); // Is not actually used, just to make validators happy alg->execute(); MatrixWorkspace_sptr grouped = alg->getProperty("OutputWorkspace"); // Copy the spectrum *(outWs->getSpectrum(gi)) = *(grouped->getSpectrum(0)); // Update spectrum number outWs->getSpectrum(gi)->setSpectrumNo(static_cast<specid_t>(gi)); // Copy to the output workspace outWs->dataY(gi) = grouped->readY(0); outWs->dataX(gi) = grouped->readX(0); outWs->dataE(gi) = grouped->readE(0); } return outWs; }
/** Calculate a workspace that contains the result of the fit to the * transmission fraction that was calculated * @param raw [in] the workspace with the unfitted transmission ratio data * @param rebinParams [in] the parameters for rebinning * @param fitMethod [in] string can be Log, Linear, Poly2, Poly3, Poly4, Poly5, * Poly6 * @return a workspace that contains the evaluation of the fit * @throw runtime_error if the Linear or ExtractSpectrum algorithm fails during * execution */ API::MatrixWorkspace_sptr CalculateTransmission::fit(API::MatrixWorkspace_sptr raw, std::vector<double> rebinParams, const std::string fitMethod) { MatrixWorkspace_sptr output = this->extractSpectra(raw, std::vector<size_t>(1, 0)); Progress progress(this, m_done, 1.0, 4); progress.report("CalculateTransmission: Performing fit"); // these are calculated by the call to fit below double grad(0.0), offset(0.0); std::vector<double> coeficients; const bool logFit = (fitMethod == "Log"); if (logFit) { g_log.debug("Fitting to the logarithm of the transmission"); MantidVec &Y = output->dataY(0); MantidVec &E = output->dataE(0); double start = m_done; Progress prog2(this, start, m_done += 0.1, Y.size()); for (size_t i = 0; i < Y.size(); ++i) { // Take the log of each datapoint for fitting. Recalculate errors // remembering that d(log(a))/da = 1/a E[i] = std::abs(E[i] / Y[i]); Y[i] = std::log10(Y[i]); progress.report("Fitting to the logarithm of the transmission"); } // Now fit this to a straight line output = fitData(output, grad, offset); } // logFit true else if (fitMethod == "Linear") { // Linear fit g_log.debug("Fitting directly to the data (i.e. linearly)"); output = fitData(output, grad, offset); } else { // fitMethod Polynomial int order = getProperty("PolynomialOrder"); std::stringstream info; info << "Fitting the transmission to polynomial order=" << order; g_log.information(info.str()); output = fitPolynomial(output, order, coeficients); } progress.report("CalculateTransmission: Performing fit"); // if no rebin parameters were set the output workspace will have the same // binning as the input ones, otherwise rebin if (!rebinParams.empty()) { output = rebin(rebinParams, output); } progress.report("CalculateTransmission: Performing fit"); // if there was rebinnning or log fitting we need to recalculate the Ys, // otherwise we can just use the workspace kicked out by the fitData()'s call // to Linear if ((!rebinParams.empty()) || logFit) { const MantidVec &X = output->readX(0); MantidVec &Y = output->dataY(0); if (logFit) { // Need to transform back to 'unlogged' const double m(std::pow(10, grad)); const double factor(std::pow(10, offset)); MantidVec &E = output->dataE(0); for (size_t i = 0; i < Y.size(); ++i) { // the relationship between the grad and interspt of the log fit and the // un-logged value of Y contain this dependence on the X (bin center // values) Y[i] = factor * (std::pow(m, 0.5 * (X[i] + X[i + 1]))); E[i] = std::abs(E[i] * Y[i]); progress.report(); } } // end logFit else if (fitMethod == "Linear") { // the simpler linear situation for (size_t i = 0; i < Y.size(); ++i) { Y[i] = (grad * 0.5 * (X[i] + X[i + 1])) + offset; } } else { // the polynomial fit for (size_t i = 0; i < Y.size(); ++i) { double aux = 0; double x_v = 0.5 * (X[i] + X[i + 1]); for (int j = 0; j < static_cast<int>(coeficients.size()); ++j) { aux += coeficients[j] * std::pow(x_v, j); } Y[i] = aux; } } } progress.report("CalculateTransmission: Performing fit"); return output; }
/** Calls Gaussian1D as a child algorithm to fit the offset peak in a spectrum * * @param wi :: The Workspace Index to fit. * @param inputW :: Input workspace. * @param peakPositions :: Peak positions. * @param fitWindows :: Fit windows. * @param nparams :: Number of parameters. * @param minD :: Min distance. * @param maxD :: Max distance. * @param peakPosToFit :: Actual peak positions to fit (output). * @param peakPosFitted :: Actual peak positions fitted (output). * @param chisq :: chisq. * @param peakHeights :: vector for fitted heights of peaks * @param i_highestpeak:: index of the highest peak among all peaks * @param resolution :: spectrum's resolution delta(d)/d * @param dev_resolution :: standard deviation resolution * @return The number of peaks in range */ int GetDetOffsetsMultiPeaks::fitSpectra( const int64_t wi, MatrixWorkspace_sptr inputW, const std::vector<double> &peakPositions, const std::vector<double> &fitWindows, size_t &nparams, double &minD, double &maxD, std::vector<double> &peakPosToFit, std::vector<double> &peakPosFitted, std::vector<double> &chisq, std::vector<double> &peakHeights, int &i_highestpeak, double &resolution, double &dev_resolution) { // Default overall fit range is the whole spectrum const MantidVec &X = inputW->readX(wi); minD = X.front(); maxD = X.back(); // Trim in the edges based on where the data turns off of zero const MantidVec &Y = inputW->readY(wi); size_t minDindex = 0; for (; minDindex < Y.size(); ++minDindex) { if (Y[minDindex] > 0.) { minD = X[minDindex]; break; } } if (minD >= maxD) { // throw if minD >= maxD std::stringstream ess; ess << "Stuff went wrong with wkspIndex=" << wi << " specIndex=" << inputW->getSpectrum(wi)->getSpectrumNo(); throw std::runtime_error(ess.str()); } size_t maxDindex = Y.size() - 1; for (; maxDindex > minDindex; --maxDindex) { if (Y[maxDindex] > 0.) { maxD = X[maxDindex]; break; } } std::stringstream dbss; dbss << "D-RANGE[" << inputW->getSpectrum(wi)->getSpectrumNo() << "]: " << minD << " -> " << maxD; g_log.debug(dbss.str()); // Setup the fit windows bool useFitWindows = (!fitWindows.empty()); std::vector<double> fitWindowsToUse; for (int i = 0; i < static_cast<int>(peakPositions.size()); ++i) { if ((peakPositions[i] > minD) && (peakPositions[i] < maxD)) { if (m_useFitWindowTable) { fitWindowsToUse.push_back(std::max(m_vecFitWindow[wi][2 * i], minD)); fitWindowsToUse.push_back( std::min(m_vecFitWindow[wi][2 * i + 1], maxD)); } else if (useFitWindows) { fitWindowsToUse.push_back(std::max(fitWindows[2 * i], minD)); fitWindowsToUse.push_back(std::min(fitWindows[2 * i + 1], maxD)); } peakPosToFit.push_back(peakPositions[i]); } } int numPeaksInRange = static_cast<int>(peakPosToFit.size()); if (numPeaksInRange == 0) { std::stringstream outss; outss << "Spectrum " << wi << " has no peak in range (" << minD << ", " << maxD << ")"; g_log.information(outss.str()); return 0; } // Fit peaks API::IAlgorithm_sptr findpeaks = createChildAlgorithm("FindPeaks", -1, -1, false); findpeaks->setProperty("InputWorkspace", inputW); findpeaks->setProperty<int>("FWHM", 7); findpeaks->setProperty<int>("Tolerance", 4); // FindPeaks will do the checking on the validity of WorkspaceIndex findpeaks->setProperty("WorkspaceIndex", static_cast<int>(wi)); // Get the specified peak positions, which is optional findpeaks->setProperty("PeakPositions", peakPosToFit); if (useFitWindows) findpeaks->setProperty("FitWindows", fitWindowsToUse); findpeaks->setProperty<std::string>("PeakFunction", m_peakType); findpeaks->setProperty<std::string>("BackgroundType", m_backType); findpeaks->setProperty<bool>("HighBackground", this->getProperty("HighBackground")); findpeaks->setProperty<int>("MinGuessedPeakWidth", 4); findpeaks->setProperty<int>("MaxGuessedPeakWidth", 4); findpeaks->setProperty<double>("MinimumPeakHeight", m_minPeakHeight); findpeaks->setProperty("StartFromObservedPeakCentre", true); findpeaks->executeAsChildAlg(); // Collect fitting resutl of all peaks ITableWorkspace_sptr peakslist = findpeaks->getProperty("PeaksList"); // use tmpPeakPosToFit to shuffle the vectors std::vector<double> tmpPeakPosToFit; generatePeaksList(peakslist, static_cast<int>(wi), peakPosToFit, tmpPeakPosToFit, peakPosFitted, peakHeights, chisq, (useFitWindows || m_useFitWindowTable), fitWindowsToUse, minD, maxD, resolution, dev_resolution); peakPosToFit = tmpPeakPosToFit; nparams = peakPosFitted.size(); // Find the highest peak i_highestpeak = -1; double maxheight = 0; for (int i = 0; i < static_cast<int>(peakPosFitted.size()); ++i) { double tmpheight = peakHeights[i]; if (tmpheight > maxheight) { maxheight = tmpheight; i_highestpeak = i; } } return numPeaksInRange; }
//------------------------------------------------------------------------------------------------ /// @cond // Local function used within validateInputs() below in a call to // std::list::sort(compare) // to order the input workspaces by the start of their frame (i.e. the first X // value). static bool compare(MatrixWorkspace_sptr first, MatrixWorkspace_sptr second) { return (first->readX(0).front() < second->readX(0).front()); }
void TOFSANSResolutionByPixel::exec() { MatrixWorkspace_sptr inOutWS = getProperty("Workspace"); double deltaR = getProperty("DeltaR"); double R1 = getProperty("SourceApertureRadius"); double R2 = getProperty("SampleApertureRadius"); // Convert to meters deltaR /= 1000.0; R1 /= 1000.0; R2 /= 1000.0; const MatrixWorkspace_sptr sigmaModeratorVSwavelength = getProperty("SigmaModerator"); // create interpolation table from sigmaModeratorVSwavelength Kernel::Interpolation lookUpTable; const MantidVec xInterpolate = sigmaModeratorVSwavelength->readX(0); const MantidVec yInterpolate = sigmaModeratorVSwavelength->readY(0); // prefer the input to be a pointworkspace and create interpolation function if (sigmaModeratorVSwavelength->isHistogramData()) { g_log.notice() << "mid-points of SigmaModerator histogram bins will be " "used for interpolation."; for (size_t i = 0; i < xInterpolate.size() - 1; ++i) { const double midpoint = xInterpolate[i + 1] - xInterpolate[i]; lookUpTable.addPoint(midpoint, yInterpolate[i]); } } else { for (size_t i = 0; i < xInterpolate.size(); ++i) { lookUpTable.addPoint(xInterpolate[i], yInterpolate[i]); } } const V3D samplePos = inOutWS->getInstrument()->getSample()->getPos(); const V3D sourcePos = inOutWS->getInstrument()->getSource()->getPos(); const V3D SSD = samplePos - sourcePos; const double L1 = SSD.norm(); const int numberOfSpectra = static_cast<int>(inOutWS->getNumberHistograms()); Progress progress(this, 0.0, 1.0, numberOfSpectra); for (int i = 0; i < numberOfSpectra; i++) { IDetector_const_sptr det; try { det = inOutWS->getDetector(i); } catch (Exception::NotFoundError &) { g_log.information() << "Spectrum index " << i << " has no detector assigned to it - discarding" << std::endl; } // If no detector found or if it's masked or a monitor, skip onto the next // spectrum if (!det || det->isMonitor() || det->isMasked()) continue; // Get the flight path from the sample to the detector pixel const V3D scatteredFlightPathV3D = det->getPos() - samplePos; const double L2 = scatteredFlightPathV3D.norm(); const double Lsum = L1 + L2; // calculate part that is wavelenght independent const double dTheta2 = (4.0 * M_PI * M_PI / 12.0) * (3.0 * R1 * R1 / (L1 * L1) + 3.0 * R2 * R2 * Lsum * Lsum / (L1 * L1 * L2 * L2) + (deltaR * deltaR) / (L2 * L2)); // Multiplicative factor to go from lambda to Q // Don't get fooled by the function name... const double theta = inOutWS->detectorTwoTheta(det); const double factor = 4.0 * M_PI * sin(theta / 2.0); const MantidVec &xIn = inOutWS->readX(i); MantidVec &yIn = inOutWS->dataY(i); const size_t xLength = xIn.size(); // for each wavelenght bin of each pixel calculate a q-resolution for (size_t j = 0; j < xLength - 1; j++) { // use the midpoint of each bin const double wl = (xIn[j + 1] + xIn[j]) / 2.0; // Calculate q. Alternatively q could be calculated using ConvertUnit const double q = factor / wl; // wavelenght spread from bin assumed to be const double sigmaSpreadFromBin = xIn[j + 1] - xIn[j]; // wavelenght spread from moderatorm, converted from microseconds to // wavelengths const double sigmaModerator = lookUpTable.value(wl) * 3.9560 / (1000.0 * Lsum); // calculate wavelenght resolution from moderator and histogram time bin const double sigmaLambda = std::sqrt(sigmaSpreadFromBin * sigmaSpreadFromBin / 12.0 + sigmaModerator * sigmaModerator); // calculate sigmaQ for a given lambda and pixel const double sigmaOverLambdaTimesQ = q * sigmaLambda / wl; const double sigmaQ = std::sqrt( dTheta2 / (wl * wl) + sigmaOverLambdaTimesQ * sigmaOverLambdaTimesQ); // update inout workspace with this sigmaQ yIn[j] = sigmaQ; } progress.report("Computing Q resolution"); } }
double DiffractionEventCalibrateDetectors::intensity( double x, double y, double z, double rotx, double roty, double rotz, std::string detname, std::string inname, std::string outname, std::string peakOpt, std::string rb_param, std::string groupWSName) { EventWorkspace_sptr inputW = boost::dynamic_pointer_cast<EventWorkspace>( AnalysisDataService::Instance().retrieve(inname)); bool debug = true; CPUTimer tim; movedetector(x, y, z, rotx, roty, rotz, detname, inputW); if (debug) std::cout << tim << " to movedetector()\n"; IAlgorithm_sptr alg3 = createChildAlgorithm("ConvertUnits"); alg3->setProperty<EventWorkspace_sptr>("InputWorkspace", inputW); alg3->setPropertyValue("OutputWorkspace", outname); alg3->setPropertyValue("Target", "dSpacing"); alg3->executeAsChildAlg(); MatrixWorkspace_sptr outputW = alg3->getProperty("OutputWorkspace"); if (debug) std::cout << tim << " to ConvertUnits\n"; IAlgorithm_sptr alg4 = createChildAlgorithm("DiffractionFocussing"); alg4->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputW); alg4->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputW); alg4->setPropertyValue("GroupingFileName", ""); alg4->setPropertyValue("GroupingWorkspace", groupWSName); alg4->executeAsChildAlg(); outputW = alg4->getProperty("OutputWorkspace"); // Remove file if (debug) std::cout << tim << " to DiffractionFocussing\n"; IAlgorithm_sptr alg5 = createChildAlgorithm("Rebin"); alg5->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputW); alg5->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputW); alg5->setPropertyValue("Params", rb_param); alg5->executeAsChildAlg(); outputW = alg5->getProperty("OutputWorkspace"); if (debug) std::cout << tim << " to Rebin\n"; // Find point of peak centre const MantidVec &yValues = outputW->readY(0); auto it = std::max_element(yValues.begin(), yValues.end()); double peakHeight = *it; if (peakHeight == 0) return -0.000; double peakLoc = outputW->readX(0)[it - yValues.begin()]; IAlgorithm_sptr fit_alg; try { // set the ChildAlgorithm no to log as this will be run once per spectra fit_alg = createChildAlgorithm("Fit", -1, -1, false); } catch (Exception::NotFoundError &) { g_log.error("Can't locate Fit algorithm"); throw; } std::ostringstream fun_str; fun_str << "name=Gaussian,Height=" << peakHeight << ",Sigma=0.01,PeakCentre=" << peakLoc; fit_alg->setProperty("Function", fun_str.str()); fit_alg->setProperty("InputWorkspace", outputW); fit_alg->setProperty("WorkspaceIndex", 0); fit_alg->setProperty("StartX", outputW->readX(0)[0]); fit_alg->setProperty("EndX", outputW->readX(0)[outputW->blocksize()]); fit_alg->setProperty("MaxIterations", 200); fit_alg->setProperty("Output", "fit"); fit_alg->executeAsChildAlg(); if (debug) std::cout << tim << " to Fit\n"; std::vector<double> params; // = fit_alg->getProperty("Parameters"); Mantid::API::IFunction_sptr fun_res = fit_alg->getProperty("Function"); for (size_t i = 0; i < fun_res->nParams(); ++i) { params.push_back(fun_res->getParameter(i)); } peakHeight = params[0]; peakLoc = params[1]; movedetector(-x, -y, -z, -rotx, -roty, -rotz, detname, inputW); if (debug) std::cout << tim << " to movedetector()\n"; // Optimize C/peakheight + |peakLoc-peakOpt| where C is scaled by number of // events EventWorkspace_const_sptr inputE = boost::dynamic_pointer_cast<const EventWorkspace>(inputW); return (static_cast<int>(inputE->getNumberEvents()) / 1.e6) / peakHeight + std::fabs(peakLoc - boost::lexical_cast<double>(peakOpt)); }
/** Executes the algorithm * */ void CalculateEfficiency::exec() { // Minimum efficiency. Pixels with lower efficiency will be masked double min_eff = getProperty("MinEfficiency"); // Maximum efficiency. Pixels with higher efficiency will be masked double max_eff = getProperty("MaxEfficiency"); // Get the input workspace MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); MatrixWorkspace_sptr rebinnedWS;// = inputWS; // Now create the output workspace MatrixWorkspace_sptr outputWS;// = getProperty("OutputWorkspace"); // DataObjects::EventWorkspace_const_sptr inputEventWS = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS); // Sum up all the wavelength bins IAlgorithm_sptr childAlg = createChildAlgorithm("Integration", 0.0, 0.2); childAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", inputWS); childAlg->executeAsChildAlg(); rebinnedWS = childAlg->getProperty("OutputWorkspace"); outputWS = WorkspaceFactory::Instance().create(rebinnedWS); WorkspaceFactory::Instance().initializeFromParent(inputWS, outputWS, false); for (int i=0; i<(int)rebinnedWS->getNumberHistograms(); i++) { outputWS->dataX(i) = rebinnedWS->readX(i); } setProperty("OutputWorkspace",outputWS); double sum = 0.0; double err = 0.0; int npixels = 0; // Loop over spectra and sum all the counts to get normalization // Skip monitors and masked detectors sumUnmaskedDetectors(rebinnedWS, sum, err, npixels); // Normalize each detector pixel by the sum we just found to get the // relative efficiency. If the minimum and maximum efficiencies are // provided, the pixels falling outside this range will be marked // as 'masked' in both the input and output workspace. // We mask detectors in the input workspace so that we can resum the // counts to find a new normalization factor that takes into account // the newly masked detectors. normalizeDetectors(rebinnedWS, outputWS, sum, err, npixels, min_eff, max_eff); if ( !isEmpty(min_eff) || !isEmpty(max_eff) ) { // Recompute the normalization, excluding the pixels that were outside // the acceptable efficiency range. sumUnmaskedDetectors(rebinnedWS, sum, err, npixels); // Now that we have a normalization factor that excludes bad pixels, // recompute the relative efficiency. // We pass EMPTY_DBL() to avoid masking pixels that might end up high or low // after the new normalization. normalizeDetectors(rebinnedWS, outputWS, sum, err, npixels, EMPTY_DBL(), EMPTY_DBL()); } return; }
void TOFSANSResolutionByPixel::exec() { MatrixWorkspace_sptr inOutWS = getProperty("InputWorkspace"); double deltaR = getProperty("DeltaR"); double R1 = getProperty("SourceApertureRadius"); double R2 = getProperty("SampleApertureRadius"); // Convert to meters deltaR /= 1000.0; R1 /= 1000.0; R2 /= 1000.0; const double sigmaModeratorMicroSec = getProperty("SigmaModerator"); const V3D samplePos = inOutWS->getInstrument()->getSample()->getPos(); const V3D sourcePos = inOutWS->getInstrument()->getSource()->getPos(); const V3D SSD = samplePos - sourcePos; const double L1 = SSD.norm(); const int numberOfSpectra = static_cast<int>(inOutWS->getNumberHistograms()); Progress progress(this,0.0,1.0,numberOfSpectra); //PARALLEL_FOR1(inOutWS) for (int i = 0; i < numberOfSpectra; i++) { //PARALLEL_START_INTERUPT_REGION IDetector_const_sptr det; try { det = inOutWS->getDetector(i); } catch (Exception::NotFoundError&) { g_log.information() << "Spectrum index " << i << " has no detector assigned to it - discarding" << std::endl; // Catch if no detector. Next line tests whether this happened - test placed // outside here because Mac Intel compiler doesn't like 'continue' in a catch // in an openmp block. } // If no detector found or if it's masked or a monitor, skip onto the next spectrum if ( !det || det->isMonitor() || det->isMasked() ) continue; // Get the flight path from the sample to the detector pixel const V3D scatteredFlightPathV3D = det->getPos() - samplePos; const double L2 = scatteredFlightPathV3D.norm(); const double Lsum = L1+L2; // calculate part that is wavelenght independent const double dTheta2 = (4.0 * M_PI * M_PI / 12.0) * ( 3.0*R1*R1/(L1*L1) + 3.0*R2*R2*Lsum*Lsum/(L1*L1*L2*L2) + (deltaR*deltaR)/(L2*L2) ); // Multiplicative factor to go from lambda to Q // Don't get fooled by the function name... const double theta = inOutWS->detectorTwoTheta(det); const double factor = 4.0 * M_PI * sin( theta/2.0 ); const MantidVec& xIn = inOutWS->readX(i); MantidVec& yIn = inOutWS->dataY(i); const size_t xLength = xIn.size(); for ( size_t j = 0; j < xLength-1; j++) { // Calculate q. Alternatively q could be calculated using ConvertUnit const double wl = (xIn[j+1]+xIn[j])/2.0; const double q = factor/wl; // calculate wavelenght resolution from moderator and histogram time bin width and // convert to from unit of micro-seconds to Aangstrom const double sigmaLambda = sigmaModeratorMicroSec*3.9560/(1000.0*Lsum); // calculate sigmaQ for a given lambda and pixel const double sigmaOverLambdaTimesQ = q*sigmaLambda/wl; const double sigmaQ = std::sqrt(dTheta2/(wl*wl)+sigmaOverLambdaTimesQ*sigmaOverLambdaTimesQ); // update inout workspace with this sigmaQ yIn[j] = sigmaQ; } progress.report("Computing Q resolution"); //PARALLEL_END_INTERUPT_REGION } }
/** @ throw invalid_argument if the workspaces are not mututially compatible */ void Q1D2::exec() { m_dataWS = getProperty("DetBankWorkspace"); MatrixWorkspace_const_sptr waveAdj = getProperty("WavelengthAdj"); MatrixWorkspace_const_sptr pixelAdj = getProperty("PixelAdj"); MatrixWorkspace_const_sptr wavePixelAdj = getProperty("WavePixelAdj"); const bool doGravity = getProperty("AccountForGravity"); m_doSolidAngle = getProperty("SolidAngleWeighting"); //throws if we don't have common binning or another incompatibility Qhelper helper; helper.examineInput(m_dataWS, waveAdj, pixelAdj); // FIXME: how to examine the wavePixelAdj? g_log.debug() << "All input workspaces were found to be valid\n"; // normalization as a function of wavelength (i.e. centers of x-value bins) double const * const binNorms = waveAdj ? &(waveAdj->readY(0)[0]) : NULL; // error on the wavelength normalization double const * const binNormEs = waveAdj ? &(waveAdj->readE(0)[0]) : NULL; //define the (large number of) data objects that are going to be used in all iterations of the loop below // this will become the output workspace from this algorithm MatrixWorkspace_sptr outputWS = setUpOutputWorkspace(getProperty("OutputBinning")); const MantidVec & QOut = outputWS->readX(0); MantidVec & YOut = outputWS->dataY(0); MantidVec & EOutTo2 = outputWS->dataE(0); // normalisation that is applied to counts in each Q bin MantidVec normSum(YOut.size(), 0.0); // the error on the normalisation MantidVec normError2(YOut.size(), 0.0); const int numSpec = static_cast<int>(m_dataWS->getNumberHistograms()); Progress progress(this, 0.05, 1.0, numSpec+1); PARALLEL_FOR3(m_dataWS, outputWS, pixelAdj) for (int i = 0; i < numSpec; ++i) { PARALLEL_START_INTERUPT_REGION // Get the pixel relating to this spectrum IDetector_const_sptr det; try { det = m_dataWS->getDetector(i); } catch (Exception::NotFoundError&) { g_log.warning() << "Workspace index " << i << " (SpectrumIndex = " << m_dataWS->getSpectrum(i)->getSpectrumNo() << ") has no detector assigned to it - discarding" << std::endl; // Catch if no detector. Next line tests whether this happened - test placed // outside here because Mac Intel compiler doesn't like 'continue' in a catch // in an openmp block. } // If no detector found or if detector is masked shouldn't be included skip onto the next spectrum if ( !det || det->isMonitor() || det->isMasked() ) { continue; } //get the bins that are included inside the RadiusCut/WaveCutcut off, those to calculate for //const size_t wavStart = waveLengthCutOff(i); const size_t wavStart = helper.waveLengthCutOff(m_dataWS, getProperty("RadiusCut"), getProperty("WaveCut"), i); if (wavStart >= m_dataWS->readY(i).size()) { // all the spectra in this detector are out of range continue; } const size_t numWavbins = m_dataWS->readY(i).size()-wavStart; // make just one call to new to reduce CPU overhead on each thread, access to these // three "arrays" is via iterators MantidVec _noDirectUseStorage_(3*numWavbins); //normalization term MantidVec::iterator norms = _noDirectUseStorage_.begin(); // the error on these weights, it contributes to the error calculation on the output workspace MantidVec::iterator normETo2s = norms + numWavbins; // the Q values calculated from input wavelength workspace MantidVec::iterator QIn = normETo2s + numWavbins; // the weighting for this input spectrum that is added to the normalization calculateNormalization(wavStart, i, pixelAdj, wavePixelAdj, binNorms, binNormEs, norms, normETo2s); // now read the data from the input workspace, calculate Q for each bin convertWavetoQ(i, doGravity, wavStart, QIn); // Pointers to the counts data and it's error MantidVec::const_iterator YIn = m_dataWS->readY(i).begin()+wavStart; MantidVec::const_iterator EIn = m_dataWS->readE(i).begin()+wavStart; //when finding the output Q bin remember that the input Q bins (from the convert to wavelength) start high and reduce MantidVec::const_iterator loc = QOut.end(); // sum the Q contributions from each individual spectrum into the output array const MantidVec::const_iterator end = m_dataWS->readY(i).end(); for( ; YIn != end; ++YIn, ++EIn, ++QIn, ++norms, ++normETo2s) { //find the output bin that each input y-value will fall into, remembering there is one more bin boundary than bins getQBinPlus1(QOut, *QIn, loc); // ignore counts that are out of the output range if ( (loc != QOut.begin()) && (loc != QOut.end()) ) { // the actual Q-bin to add something to const size_t bin = loc - QOut.begin() - 1; PARALLEL_CRITICAL(q1d_counts_sum) { YOut[bin] += *YIn; normSum[bin] += *norms; //these are the errors squared which will be summed and square rooted at the end EOutTo2[bin] += (*EIn)*(*EIn); normError2[bin] += *normETo2s; } } } PARALLEL_CRITICAL(q1d_spectra_map) { progress.report("Computing I(Q)"); // Add up the detector IDs in the output spectrum at workspace index 0 const ISpectrum * inSpec = m_dataWS->getSpectrum(i); ISpectrum * outSpec = outputWS->getSpectrum(0); outSpec->addDetectorIDs( inSpec->getDetectorIDs() ); } PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION bool doOutputParts = getProperty("OutputParts"); if (doOutputParts) { MatrixWorkspace_sptr ws_sumOfCounts = WorkspaceFactory::Instance().create(outputWS); ws_sumOfCounts->dataX(0) = outputWS->dataX(0); ws_sumOfCounts->dataY(0) = outputWS->dataY(0); for (size_t i = 0; i < outputWS->dataE(0).size(); i++) { ws_sumOfCounts->dataE(0)[i] = sqrt(outputWS->dataE(0)[i]); } MatrixWorkspace_sptr ws_sumOfNormFactors = WorkspaceFactory::Instance().create(outputWS); ws_sumOfNormFactors->dataX(0) = outputWS->dataX(0); for (size_t i = 0; i < ws_sumOfNormFactors->dataY(0).size(); i++) { ws_sumOfNormFactors->dataY(0)[i] = normSum[i]; ws_sumOfNormFactors->dataE(0)[i] = sqrt(normError2[i]); } helper.outputParts(this, ws_sumOfCounts, ws_sumOfNormFactors); } progress.report("Normalizing I(Q)"); //finally divide the number of counts in each output Q bin by its weighting normalize(normSum, normError2, YOut, EOutTo2); outputWS->updateSpectraUsingMap(); setProperty("OutputWorkspace",outputWS); }
/** * Execute the algorithm. */ void SofQW3::exec() { MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); // Do the full check for common binning if( !WorkspaceHelpers::commonBoundaries(inputWS) ) { throw std::invalid_argument("The input workspace must have common binning across all spectra"); } RebinnedOutput_sptr outputWS = this->setUpOutputWorkspace(inputWS, getProperty("QAxisBinning"), m_Qout); g_log.debug() << "Workspace type: " << outputWS->id() << std::endl; setProperty("OutputWorkspace", outputWS); const size_t nEnergyBins = inputWS->blocksize(); const size_t nHistos = inputWS->getNumberHistograms(); // Progress reports & cancellation const size_t nreports(nHistos * nEnergyBins); m_progress = boost::shared_ptr<API::Progress>(new API::Progress(this, 0.0, 1.0, nreports)); // Compute input caches this->initCachedValues(inputWS); std::vector<double> par = inputWS->getInstrument()->getNumberParameter("detector-neighbour-offset"); if (par.empty()) { // Index theta cache this->initThetaCache(inputWS); } else { g_log.debug() << "Offset: " << par[0] << std::endl; this->m_detNeighbourOffset = static_cast<int>(par[0]); this->getValuesAndWidths(inputWS); } const MantidVec & X = inputWS->readX(0); PARALLEL_FOR2(inputWS, outputWS) for (int64_t i = 0; i < static_cast<int64_t>(nHistos); ++i) // signed for openmp { PARALLEL_START_INTERUPT_REGION DetConstPtr detector = inputWS->getDetector(i); if (detector->isMasked() || detector->isMonitor()) { continue; } double theta = this->m_theta[i]; double phi = 0.0; double thetaWidth = 0.0; double phiWidth = 0.0; // Non-PSD mode if (par.empty()) { thetaWidth = this->m_thetaWidth; } // PSD mode else { phi = this->m_phi[i]; thetaWidth = this->m_thetaWidths[i]; phiWidth = this->m_phiWidths[i]; } double thetaHalfWidth = 0.5 * thetaWidth; double phiHalfWidth = 0.5 * phiWidth; const double thetaLower = theta - thetaHalfWidth; const double thetaUpper = theta + thetaHalfWidth; const double phiLower = phi - phiHalfWidth; const double phiUpper = phi + phiHalfWidth; const double efixed = this->getEFixed(detector); for(size_t j = 0; j < nEnergyBins; ++j) { m_progress->report("Computing polygon intersections"); // For each input polygon test where it intersects with // the output grid and assign the appropriate weights of Y/E const double dE_j = X[j]; const double dE_jp1 = X[j+1]; const V2D ll(dE_j, this->calculateQ(efixed, dE_j, thetaLower, phiLower)); const V2D lr(dE_jp1, this->calculateQ(efixed, dE_jp1, thetaLower, phiLower)); const V2D ur(dE_jp1, this->calculateQ(efixed, dE_jp1, thetaUpper, phiUpper)); const V2D ul(dE_j, this->calculateQ(efixed, dE_j, thetaUpper, phiUpper)); Quadrilateral inputQ = Quadrilateral(ll, lr, ur, ul); this->rebinToFractionalOutput(inputQ, inputWS, i, j, outputWS, m_Qout); } PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION outputWS->finalize(); this->normaliseOutput(outputWS, inputWS); }
/** Convert a SPICE 2D Det MatrixWorkspace to MDEvents and append to an * MDEventWorkspace * It is optional to use a virtual instrument or copy from input data workspace * @brief ConvertCWSDExpToMomentum::convertSpiceMatrixToMomentumMDEvents * @param dataws :: data matrix workspace * @param usevirtual :: boolean flag to use virtual instrument * @param startdetid :: starting detid for detectors from this workspace mapping * to virtual instrument in MDEventWorkspace * @param runnumber :: run number for all MDEvents created from this matrix * workspace */ void ConvertCWSDExpToMomentum::convertSpiceMatrixToMomentumMDEvents( MatrixWorkspace_sptr dataws, bool usevirtual, const detid_t &startdetid, const int runnumber) { // Create transformation matrix from which the transformation is Kernel::DblMatrix rotationMatrix; setupTransferMatrix(dataws, rotationMatrix); g_log.information() << "Before insert new event, output workspace has " << m_outputWS->getNEvents() << "Events.\n"; // Creates a new instance of the MDEventInserte to output workspace MDEventWorkspace<MDEvent<3>, 3>::sptr mdws_mdevt_3 = boost::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(m_outputWS); MDEventInserter<MDEventWorkspace<MDEvent<3>, 3>::sptr> inserter(mdws_mdevt_3); // Calcualte k_i: it is assumed that all k_i are same for one Pt. // number, i.e., one 2D XML file Kernel::V3D sourcePos = dataws->getInstrument()->getSource()->getPos(); Kernel::V3D samplePos = dataws->getInstrument()->getSample()->getPos(); if (dataws->readX(0).size() != 2) throw std::runtime_error( "Input matrix workspace has wrong dimension in X-axis."); double momentum = 0.5 * (dataws->readX(0)[0] + dataws->readX(0)[1]); Kernel::V3D ki = (samplePos - sourcePos) * (momentum / sourcePos.norm()); g_log.debug() << "Source at " << sourcePos.toString() << ", Norm = " << sourcePos.norm() << ", momentum = " << momentum << "\n" << "k_i = " << ki.toString() << "\n"; // Go though each spectrum to conver to MDEvent size_t numspec = dataws->getNumberHistograms(); double maxsignal = 0; size_t nummdevents = 0; for (size_t iws = 0; iws < numspec; ++iws) { // Get detector positions and signal double signal = dataws->readY(iws)[0]; // Skip event with 0 signal if (signal < 0.001) continue; double error = dataws->readE(iws)[0]; Kernel::V3D detpos = dataws->getDetector(iws)->getPos(); std::vector<Mantid::coord_t> q_sample(3); // Calculate Q-sample and new detector ID in virtual instrument. Kernel::V3D qlab = convertToQSample(samplePos, ki, detpos, momentum, q_sample, rotationMatrix); detid_t native_detid = dataws->getDetector(iws)->getID(); detid_t detid = native_detid + startdetid; // Insert inserter.insertMDEvent( static_cast<float>(signal), static_cast<float>(error * error), static_cast<uint16_t>(runnumber), detid, q_sample.data()); updateQRange(q_sample); g_log.debug() << "Q-lab = " << qlab.toString() << "\n"; g_log.debug() << "Insert DetID " << detid << ", signal = " << signal << ", with q_sample = " << q_sample[0] << ", " << q_sample[1] << ", " << q_sample[2] << "\n"; // Update some statistical inforamtion if (signal > maxsignal) maxsignal = signal; ++nummdevents; } g_log.information() << "Imported Matrixworkspace: Max. Signal = " << maxsignal << ", Add " << nummdevents << " MDEvents " << "\n"; // Add experiment info including instrument, goniometer and run number ExperimentInfo_sptr expinfo = boost::make_shared<ExperimentInfo>(); if (usevirtual) expinfo->setInstrument(m_virtualInstrument); else { Geometry::Instrument_const_sptr tmp_inst = dataws->getInstrument(); expinfo->setInstrument(tmp_inst); } expinfo->mutableRun().setGoniometer(dataws->run().getGoniometer(), false); expinfo->mutableRun().addProperty("run_number", runnumber); // Add all the other propertys from original data workspace const std::vector<Kernel::Property *> vec_property = dataws->run().getProperties(); for (auto property : vec_property) { expinfo->mutableRun().addProperty(property->clone()); } m_outputWS->addExperimentInfo(expinfo); return; }
IEventWorkspace_sptr RefReduction::loadData(const std::string dataRun, const std::string polarization) { const std::string instrument = getProperty("Instrument"); // Check whether dataRun refers to an existing workspace // Create a good name for the raw workspace std::string ws_name = "__ref_"+dataRun+"-"+polarization+"_raw"; IEventWorkspace_sptr rawWS; if (AnalysisDataService::Instance().doesExist(dataRun)) { rawWS = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(dataRun); g_log.notice() << "Found workspace: " << dataRun << std::endl; m_output_message += " |Input data run is a workspace: " + dataRun + "\n"; } else if (AnalysisDataService::Instance().doesExist(ws_name)) { rawWS = AnalysisDataService::Instance().retrieveWS<EventWorkspace>(ws_name); g_log.notice() << "Using existing workspace: " << ws_name << std::endl; m_output_message += " |Found workspace from previous reduction: " + ws_name + "\n"; } else { // If we can't find a workspace, find a file to load std::string path = FileFinder::Instance().getFullPath(dataRun); if (path.size()==0 || !Poco::File(path).exists()) { try { std::vector<std::string> paths = FileFinder::Instance().findRuns(instrument+dataRun); path = paths[0]; } catch(Exception::NotFoundError&) { /* Pass. We report the missing file later. */ } } if (path.size()==0 || !Poco::File(path).exists()) { try { std::vector<std::string> paths = FileFinder::Instance().findRuns(dataRun); path = paths[0]; } catch(Exception::NotFoundError&) { /* Pass. We report the missing file later. */ } } if (Poco::File(path).exists()) { g_log.notice() << "Found: " << path << std::endl; m_output_message += " |Loading from " + path + "\n"; IAlgorithm_sptr loadAlg = createChildAlgorithm("LoadEventNexus", 0, 0.2); loadAlg->setProperty("Filename", path); if (polarization.compare(PolStateNone)!=0) loadAlg->setProperty("NXentryName", polarization); loadAlg->executeAsChildAlg(); rawWS = loadAlg->getProperty("OutputWorkspace"); if (rawWS->getNumberEvents()==0) { g_log.notice() << "No data in " << polarization << std::endl; m_output_message += " |No data for " + polarization + "\n"; return rawWS; } // Move the detector to the right position if (instrument.compare("REF_M")==0) { double det_distance = rawWS->getInstrument()->getDetector(0)->getPos().Z(); Mantid::Kernel::Property* prop = rawWS->run().getProperty("SampleDetDis"); Mantid::Kernel::TimeSeriesProperty<double>* dp = dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double>* >(prop); double sdd = dp->getStatistics().mean/1000.0; IAlgorithm_sptr mvAlg = createChildAlgorithm("MoveInstrumentComponent", 0.2, 0.25); mvAlg->setProperty<MatrixWorkspace_sptr>("Workspace", rawWS); mvAlg->setProperty("ComponentName", "detector1"); mvAlg->setProperty("Z", sdd-det_distance); mvAlg->setProperty("RelativePosition", true); mvAlg->executeAsChildAlg(); g_log.notice() << "Ensuring correct Z position: Correction = " << Poco::NumberFormatter::format(sdd-det_distance) << " m" << std::endl; } AnalysisDataService::Instance().addOrReplace(ws_name, rawWS); } else { g_log.error() << "Could not find a data file for " << dataRun << std::endl; throw std::invalid_argument("Could not find a data file for the given input"); } } // Crop TOF as needed and set binning double tofMin = getProperty("TOFMin"); double tofMax = getProperty("TOFMax"); if (isEmpty(tofMin) || isEmpty(tofMax)) { const MantidVec& x = rawWS->readX(0); if (isEmpty(tofMin)) tofMin = *std::min_element(x.begin(), x.end()); if (isEmpty(tofMax)) tofMax = *std::max_element(x.begin(), x.end()); } int nBins = getProperty("NBins"); double tofStep = getProperty("TOFStep"); if (!isEmpty(nBins)) tofStep = (tofMax-tofMin)/nBins; else nBins = (int)floor( (tofMax-tofMin)/tofStep ); std::vector<double> params; params.push_back(tofMin); params.push_back(tofStep); params.push_back(tofMax); IAlgorithm_sptr rebinAlg = createChildAlgorithm("Rebin", 0.25, 0.3); rebinAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", rawWS); rebinAlg->setProperty("Params", params); rebinAlg->setProperty("PreserveEvents", true); rebinAlg->executeAsChildAlg(); MatrixWorkspace_sptr outputWS = rebinAlg->getProperty("OutputWorkspace"); m_output_message += " |TOF binning: " + Poco::NumberFormatter::format(tofMin) + " to " + Poco::NumberFormatter::format(tofMax) + " in steps of " + Poco::NumberFormatter::format(tofStep) + " microsecs\n"; // Normalise by current IAlgorithm_sptr normAlg = createChildAlgorithm("NormaliseByCurrent", 0.3, 0.35); normAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS); //normAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS); normAlg->executeAsChildAlg(); outputWS = normAlg->getProperty("OutputWorkspace"); // Convert to wavelength IAlgorithm_sptr convAlg = createChildAlgorithm("ConvertUnits", 0.35, 0.4); convAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS); convAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS); convAlg->setProperty("Target", "Wavelength"); convAlg->executeAsChildAlg(); // Rebin in wavelength const MantidVec& x = outputWS->readX(0); double wlMin = *std::min_element(x.begin(), x.end()); double wlMax = *std::max_element(x.begin(), x.end()); std::vector<double> wl_params; wl_params.push_back(wlMin); wl_params.push_back((wlMax-wlMin)/nBins); wl_params.push_back(wlMax); IAlgorithm_sptr rebinAlg2 = createChildAlgorithm("Rebin", 0.25, 0.3); rebinAlg2->setProperty<MatrixWorkspace_sptr>("InputWorkspace", outputWS); rebinAlg2->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS); rebinAlg2->setProperty("Params", wl_params); rebinAlg2->setProperty("PreserveEvents", true); rebinAlg2->executeAsChildAlg(); IEventWorkspace_sptr outputEvtWS = boost::dynamic_pointer_cast<IEventWorkspace>(outputWS); return outputEvtWS; }
void FFTDerivative::execComplexFFT() { MatrixWorkspace_sptr inWS = getProperty("InputWorkspace"); MatrixWorkspace_sptr outWS; size_t n = inWS->getNumberHistograms(); API::Progress progress(this,0,1,n); size_t ny = inWS->readY(0).size(); size_t nx = inWS->readX(0).size(); // Workspace for holding a copy of a spectrum. Each spectrum is symmetrized to minimize // possible edge effects. MatrixWorkspace_sptr copyWS = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace> (Mantid::API::WorkspaceFactory::Instance().create(inWS,1,nx+ny,ny+ny)); bool isHist = (nx != ny); for(size_t spec = 0; spec < n; ++spec) { const Mantid::MantidVec& x0 = inWS->readX(spec); const Mantid::MantidVec& y0 = inWS->readY(spec); Mantid::MantidVec& x1 = copyWS->dataX(0); Mantid::MantidVec& y1 = copyWS->dataY(0); double xx = 2*x0[0]; x1[ny] = x0[0]; y1[ny] = y0[0]; for(size_t i = 1; i < ny; ++i) { size_t j1 = ny - i; size_t j2 = ny + i; x1[j1] = xx - x0[i]; x1[j2] = x0[i]; y1[j1] = y1[j2] = y0[i]; } x1[0] = 2*x1[1] - x1[2]; y1[0] = y0.back(); if (isHist) { x1[y1.size()] = x0[ny]; } // Transform symmetrized spectrum IAlgorithm_sptr fft = createChildAlgorithm("FFT"); fft->setProperty("InputWorkspace",copyWS); fft->setProperty("Real",0); fft->setProperty("Transform","Forward"); fft->execute(); MatrixWorkspace_sptr transWS = fft->getProperty("OutputWorkspace"); Mantid::MantidVec& nu = transWS->dataX(3); Mantid::MantidVec& re = transWS->dataY(3); Mantid::MantidVec& im = transWS->dataY(4); int dn = getProperty("Order"); bool swap_re_im = dn % 2 != 0; int sign_re = 1; int sign_im = -1; switch(dn % 4) { case 1: sign_re = 1; sign_im = -1; break; case 2: sign_re = -1; sign_im = -1; break; case 3: sign_re = -1; sign_im = 1; break; } // Multiply the transform by (2*pi*i*w)**dn for(size_t j=0; j < re.size(); ++j) { double w = 2 * M_PI * nu[j]; double ww = w; for(int k = dn; k > 1; --k) { ww *= w; } double a = sign_re * re[j]*ww; double b = sign_im * im[j]*ww; if (swap_re_im) { re[j] = b; im[j] = a; } else { re[j] = a; im[j] = b; } } // Inverse transform fft = createChildAlgorithm("FFT"); fft->setProperty("InputWorkspace",transWS); fft->setProperty("Real",3); fft->setProperty("Imaginary",4); fft->setProperty("Transform","Backward"); fft->execute(); transWS = fft->getProperty("OutputWorkspace"); size_t m2 = transWS->readY(0).size() / 2; //size_t my = m2 + (transWS->readY(0).size() % 2 ? 1 : 0); //size_t mx = my + (transWS->isHistogramData() ? 1 : 0); if (!outWS) { outWS = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace> //(Mantid::API::WorkspaceFactory::Instance().create(inWS,n,mx,my)); (Mantid::API::WorkspaceFactory::Instance().create(inWS)); } // Save the upper half of the inverse transform for output Mantid::MantidVec& x = outWS->dataX(spec); Mantid::MantidVec& y = outWS->dataY(spec); double dx = x1[m2]; std::copy(transWS->dataX(0).begin() + m2,transWS->dataX(0).end(),x.begin()); std::transform(x.begin(),x.end(),x.begin(),std::bind2nd(std::plus<double>(),dx)); std::copy(transWS->dataY(0).begin() + m2,transWS->dataY(0).end(),y.begin()); progress.report(); } setProperty("OutputWorkspace",outWS); }
void FFTDerivative::execRealFFT() { MatrixWorkspace_sptr inWS = getProperty("InputWorkspace"); MatrixWorkspace_sptr outWS; size_t n = inWS->getNumberHistograms(); API::Progress progress(this,0,1,n); size_t ny = inWS->readY(0).size(); size_t nx = inWS->readX(0).size(); // Workspace for holding a copy of a spectrum. Each spectrum is symmetrized to minimize // possible edge effects. MatrixWorkspace_sptr copyWS = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace> (Mantid::API::WorkspaceFactory::Instance().create(inWS,1,nx+ny,ny+ny)); bool isHist = (nx != ny); for(size_t spec = 0; spec < n; ++spec) { const Mantid::MantidVec& x0 = inWS->readX(spec); const Mantid::MantidVec& y0 = inWS->readY(spec); Mantid::MantidVec& x1 = copyWS->dataX(0); Mantid::MantidVec& y1 = copyWS->dataY(0); double xx = 2*x0[0]; x1[ny] = x0[0]; y1[ny] = y0[0]; for(size_t i = 1; i < ny; ++i) { size_t j1 = ny - i; size_t j2 = ny + i; x1[j1] = xx - x0[i]; x1[j2] = x0[i]; y1[j1] = y1[j2] = y0[i]; } x1[0] = 2*x1[1] - x1[2]; y1[0] = y0.back(); if (isHist) { x1[y1.size()] = x0[ny]; } // Transform symmetrized spectrum IAlgorithm_sptr fft = createChildAlgorithm("RealFFT"); fft->setProperty("InputWorkspace",copyWS); fft->setProperty("WorkspaceIndex",0); fft->setProperty("Transform","Forward"); fft->execute(); MatrixWorkspace_sptr transWS = fft->getProperty("OutputWorkspace"); Mantid::MantidVec& nu = transWS->dataX(0); Mantid::MantidVec& re = transWS->dataY(0); Mantid::MantidVec& im = transWS->dataY(1); int dn = getProperty("Order"); bool swap_re_im = dn % 2 != 0; int sign_re = 1; int sign_im = -1; switch(dn % 4) { case 1: sign_re = 1; sign_im = -1; break; case 2: sign_re = -1; sign_im = -1; break; case 3: sign_re = -1; sign_im = 1; break; } // Multiply the transform by (2*pi*i*w)**dn for(size_t j=0; j < re.size(); ++j) { double w = 2 * M_PI * nu[j]; double ww = w; for(int k = dn; k > 1; --k) { ww *= w; } double a = sign_re * re[j]*ww; double b = sign_im * im[j]*ww; if (swap_re_im) { re[j] = b; im[j] = a; } else { re[j] = a; im[j] = b; } } // Inverse transform fft = createChildAlgorithm("RealFFT"); fft->setProperty("InputWorkspace",transWS); fft->setProperty("Transform","Backward"); fft->execute(); transWS = fft->getProperty("OutputWorkspace"); size_t m2 = transWS->readY(0).size() / 2; size_t my = m2 + ((transWS->readY(0).size() % 2) ? 1 : 0); size_t mx = my + (transWS->isHistogramData() ? 1 : 0); if (!outWS) { outWS = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace> (Mantid::API::WorkspaceFactory::Instance().create(inWS,n,mx,my)); } // Save the upper half of the inverse transform for output Mantid::MantidVec& x = outWS->dataX(spec); Mantid::MantidVec& y = outWS->dataY(spec); double dx = x1[0]; std::copy(transWS->dataX(0).begin() + m2,transWS->dataX(0).end(),x.begin()); std::transform(x.begin(),x.end(),x.begin(),std::bind2nd(std::plus<double>(),dx)); std::copy(transWS->dataY(0).begin() + m2,transWS->dataY(0).end(),y.begin()); // shift the data to make x and x0 match. using linear interpolation. if (x.size() != x0.size() && false)// TODO: doesn't work at the moment. needs to be working { std::cerr << "(my != x0.size()) " << x0[0] << "!=" << x[0] << std::endl; dx = x0[0] - x[0]; assert(dx > 0.0); double f = (x0[0] - x[0]) / (x0[1] - x0[0]); for(size_t i = 0; i < my - 1; ++i) { y[i] += (y[i+1] - y[i]) * f; x[i] = x0[i]; } x.back() += dx; } progress.report(); } setProperty("OutputWorkspace",outWS); }
/** Checks input properties and compares them to previous values * @param is :: [output] Number of the first run * @param ie :: [output] Number of the last run */ void PlotAsymmetryByLogValue::checkProperties(size_t &is, size_t &ie) { // Log Value m_logName = getPropertyValue("LogValue"); // Get function to apply to logValue m_logFunc = getPropertyValue("Function"); // Get type of computation m_int = (getPropertyValue("Type") == "Integral"); // Get grouping properties m_forward_list = getProperty("ForwardSpectra"); m_backward_list = getProperty("BackwardSpectra"); // Get green and red periods m_red = getProperty("Red"); m_green = getProperty("Green"); // Get time min and time max m_minTime = getProperty("TimeMin"); m_maxTime = getProperty("TimeMax"); // Get type of dead-time corrections m_dtcType = getPropertyValue("DeadTimeCorrType"); m_dtcFile = getPropertyValue("DeadTimeCorrFile"); // Get runs std::string firstFN = getProperty("FirstRun"); std::string lastFN = getProperty("LastRun"); // Parse run names and get the number of runs parseRunNames(firstFN, lastFN, m_filenameBase, m_filenameExt, m_filenameZeros); is = atoi(firstFN.c_str()); // starting run number ie = atoi(lastFN.c_str()); // last run number if (ie < is) { throw std::runtime_error( "First run number is greater than last run number"); } // Create a string holding all the properties std::ostringstream ss; ss << m_filenameBase << "," << m_filenameExt << "," << m_filenameZeros << ","; ss << m_dtcType << "," << m_dtcFile << ","; ss << getPropertyValue("ForwardSpectra") << "," << getPropertyValue("BackwardSpectra") << ","; ss << m_int << "," << m_minTime << "," << m_maxTime << ","; ss << m_red << "," << m_green << ","; ss << m_logName << ", " << m_logFunc; m_allProperties = ss.str(); // Check if we can re-use results from previous run // We can reuse results if: // 1. There is a ws in the ADS with name m_currResName // 2. It is a MatrixWorkspace // 3. It has a title equatl to m_allProperties // This ws stores previous results as described below if (AnalysisDataService::Instance().doesExist(m_currResName)) { MatrixWorkspace_sptr prevResults = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( m_currResName); if (prevResults) { if (m_allProperties == prevResults->getTitle()) { // We can re-use results size_t nPoints = prevResults->blocksize(); size_t nHisto = prevResults->getNumberHistograms(); if (nHisto == 2) { // Only 'red' data for (size_t i = 0; i < nPoints; i++) { // The first spectrum contains: X -> run number, Y -> log value // The second spectrum contains: Y -> redY, E -> redE size_t run = static_cast<size_t>(prevResults->readX(0)[i]); if ((run >= is) && (run <= ie)) { m_logValue[run] = prevResults->readY(0)[i]; m_redY[run] = prevResults->readY(1)[i]; m_redE[run] = prevResults->readE(1)[i]; } } } else { // 'Red' and 'Green' data for (size_t i = 0; i < nPoints; i++) { // The first spectrum contains: X -> run number, Y -> log value // The second spectrum contains: Y -> diffY, E -> diffE // The third spectrum contains: Y -> redY, E -> redE // The fourth spectrum contains: Y -> greenY, E -> greeE // The fifth spectrum contains: Y -> sumY, E -> sumE size_t run = static_cast<size_t>(prevResults->readX(0)[i]); if ((run >= is) && (run <= ie)) { m_logValue[run] = prevResults->readY(0)[i]; m_diffY[run] = prevResults->readY(1)[i]; m_diffE[run] = prevResults->readE(1)[i]; m_redY[run] = prevResults->readY(2)[i]; m_redE[run] = prevResults->readE(2)[i]; m_greenY[run] = prevResults->readY(3)[i]; m_greenE[run] = prevResults->readE(3)[i]; m_sumY[run] = prevResults->readY(4)[i]; m_sumE[run] = prevResults->readE(4)[i]; } } } } } } }
/** * Executes the algorithm */ void ScaleX::exec() { //Get input workspace and offset const MatrixWorkspace_sptr inputW = getProperty("InputWorkspace"); factor = getProperty("Factor"); API::MatrixWorkspace_sptr outputW = createOutputWS(inputW); //Get number of histograms int histnumber = static_cast<int>(inputW->getNumberHistograms()); m_progress = new API::Progress(this, 0.0, 1.0, histnumber+1); m_progress->report("Scaling X"); wi_min = 0; wi_max = histnumber-1; //check if workspace indexes have been set int tempwi_min = getProperty("IndexMin"); int tempwi_max = getProperty("IndexMax"); if ( tempwi_max != Mantid::EMPTY_INT() ) { if ((wi_min <= tempwi_min) && (tempwi_min <= tempwi_max) && (tempwi_max <= wi_max)) { wi_min = tempwi_min; wi_max = tempwi_max; } else { g_log.error("Invalid Workspace Index min/max properties"); throw std::invalid_argument("Inconsistent properties defined"); } } //Check if its an event workspace EventWorkspace_const_sptr eventWS = boost::dynamic_pointer_cast<const EventWorkspace>(inputW); if (eventWS != NULL) { this->execEvent(); return; } // do the shift in X PARALLEL_FOR2(inputW, outputW) for (int i=0; i < histnumber; ++i) { PARALLEL_START_INTERUPT_REGION //Do the offsetting for (int j=0; j < static_cast<int>(inputW->readX(i).size()); ++j) { //Change bin value by offset if ((i >= wi_min) && (i <= wi_max)) outputW->dataX(i)[j] = inputW->readX(i)[j] * factor; else outputW->dataX(i)[j] = inputW->readX(i)[j]; } //Copy y and e data outputW->dataY(i) = inputW->dataY(i); outputW->dataE(i) = inputW->dataE(i); if( (i >= wi_min) && (i <= wi_max) && factor<0 ) { std::reverse( outputW->dataX(i).begin(), outputW->dataX(i).end() ); std::reverse( outputW->dataY(i).begin(), outputW->dataY(i).end() ); std::reverse( outputW->dataE(i).begin(), outputW->dataE(i).end() ); } m_progress->report("Scaling X"); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // Copy units if (outputW->getAxis(0)->unit().get()) outputW->getAxis(0)->unit() = inputW->getAxis(0)->unit(); try { if (inputW->getAxis(1)->unit().get()) outputW->getAxis(1)->unit() = inputW->getAxis(1)->unit(); } catch(Exception::IndexError &) { // OK, so this isn't a Workspace2D } // Assign it to the output workspace property setProperty("OutputWorkspace",outputW); }
/** * Plots raw time data from .raw file before any data conversion has been * performed. */ void ISISEnergyTransfer::plotRaw() { using Mantid::specnum_t; using MantidQt::API::BatchAlgorithmRunner; if (!m_uiForm.dsRunFiles->isValid()) { emit showMessageBox("You must select a run file."); return; } int detectorMin = m_uiForm.spPlotTimeSpecMin->value(); int detectorMax = m_uiForm.spPlotTimeSpecMax->value(); if (detectorMin > detectorMax) { emit showMessageBox( "Minimum spectra must be less than or equal to maximum spectra."); return; } const int startBack = m_uiForm.spBackgroundStart->value(); const int endBack = m_uiForm.spBackgroundEnd->value(); if (m_uiForm.ckBackgroundRemoval->isChecked() == true) { if (startBack > endBack) { emit showMessageBox("Background Start must be less than Background End"); return; } } QString rawFile = m_uiForm.dsRunFiles->getFirstFilename(); auto pos = rawFile.lastIndexOf("."); auto extension = rawFile.right(rawFile.length() - pos); QFileInfo rawFileInfo(rawFile); std::string name = rawFileInfo.baseName().toStdString(); IAlgorithm_sptr loadAlg = AlgorithmManager::Instance().create("Load"); loadAlg->initialize(); loadAlg->setProperty("Filename", rawFile.toStdString()); loadAlg->setProperty("OutputWorkspace", name); loadAlg->setProperty("LoadLogFiles", false); if (extension.compare(".nxs") == 0) { int64_t detectorMin = static_cast<int64_t>(m_uiForm.spPlotTimeSpecMin->value()); int64_t detectorMax = static_cast<int64_t>(m_uiForm.spPlotTimeSpecMax->value()); loadAlg->setProperty("SpectrumMin", detectorMin); loadAlg->setProperty("SpectrumMax", detectorMax); } else { loadAlg->setProperty("SpectrumMin", detectorMin); loadAlg->setProperty("SpectrumMax", detectorMax); } loadAlg->execute(); if (m_uiForm.ckBackgroundRemoval->isChecked()) { MatrixWorkspace_sptr tempWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(name); const double minBack = tempWs->readX(0)[0]; const double maxBack = tempWs->readX(0)[tempWs->blocksize()]; if (startBack < minBack) { emit showMessageBox("The Start of Background Removal is less than the " "minimum of the data range"); return; } if (endBack > maxBack) { emit showMessageBox("The End of Background Removal is more than the " "maximum of the data range"); return; } } // Rebin the workspace to its self to ensure constant binning BatchAlgorithmRunner::AlgorithmRuntimeProps inputToRebin; inputToRebin["WorkspaceToMatch"] = name; inputToRebin["WorkspaceToRebin"] = name; inputToRebin["OutputWorkspace"] = name; IAlgorithm_sptr rebinAlg = AlgorithmManager::Instance().create("RebinToWorkspace"); rebinAlg->initialize(); m_batchAlgoRunner->addAlgorithm(rebinAlg, inputToRebin); BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromRebin; inputFromRebin["InputWorkspace"] = name; std::vector<specnum_t> detectorList; for (specnum_t i = detectorMin; i <= detectorMax; i++) detectorList.push_back(i); if (m_uiForm.ckBackgroundRemoval->isChecked()) { std::vector<double> range; range.push_back(m_uiForm.spBackgroundStart->value()); range.push_back(m_uiForm.spBackgroundEnd->value()); IAlgorithm_sptr calcBackAlg = AlgorithmManager::Instance().create("CalculateFlatBackground"); calcBackAlg->initialize(); calcBackAlg->setProperty("OutputWorkspace", name + "_bg"); calcBackAlg->setProperty("Mode", "Mean"); calcBackAlg->setProperty("StartX", range[0]); calcBackAlg->setProperty("EndX", range[1]); m_batchAlgoRunner->addAlgorithm(calcBackAlg, inputFromRebin); BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromCalcBG; inputFromCalcBG["InputWorkspace"] = name + "_bg"; IAlgorithm_sptr groupAlg = AlgorithmManager::Instance().create("GroupDetectors"); groupAlg->initialize(); groupAlg->setProperty("OutputWorkspace", name + "_grp"); groupAlg->setProperty("DetectorList", detectorList); m_batchAlgoRunner->addAlgorithm(groupAlg, inputFromCalcBG); IAlgorithm_sptr rawGroupAlg = AlgorithmManager::Instance().create("GroupDetectors"); rawGroupAlg->initialize(); rawGroupAlg->setProperty("OutputWorkspace", name + "_grp_raw"); rawGroupAlg->setProperty("DetectorList", detectorList); m_batchAlgoRunner->addAlgorithm(rawGroupAlg, inputFromRebin); } else { IAlgorithm_sptr rawGroupAlg = AlgorithmManager::Instance().create("GroupDetectors"); rawGroupAlg->initialize(); rawGroupAlg->setProperty("OutputWorkspace", name + "_grp"); rawGroupAlg->setProperty("DetectorList", detectorList); m_batchAlgoRunner->addAlgorithm(rawGroupAlg, inputFromRebin); } disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmComplete(bool))); connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(plotRawComplete(bool))); m_batchAlgoRunner->executeBatchAsync(); }
/** Populates the output workspaces * @param inWS :: [input] The input workspace * @param spec :: [input] The current spectrum being analyzed * @param nspec :: [input] The total number of histograms in the input workspace * @param result :: [input] The result to be written in the output workspace * @param outWS :: [input] The output workspace to populate * @param autoShift :: [input] Whether or not to correct the phase shift */ void MaxEnt::populateImageWS(const MatrixWorkspace_sptr &inWS, size_t spec, size_t nspec, const std::vector<double> &result, MatrixWorkspace_sptr &outWS, bool autoShift) { if (result.size() % 2) throw std::invalid_argument("Cannot write results to output workspaces"); int npoints = static_cast<int>(result.size() / 2); int npointsX = inWS->isHistogramData() ? npoints + 1 : npoints; MantidVec X(npointsX); MantidVec YR(npoints); MantidVec YI(npoints); MantidVec E(npoints, 0.); double x0 = inWS->readX(spec)[0]; double dx = inWS->readX(spec)[1] - x0; double delta = 1. / dx / npoints; int isOdd = (inWS->blocksize() % 2) ? 1 : 0; double shift = x0 * 2 * M_PI; if (!autoShift) shift = 0; for (int i = 0; i < npoints; i++) { int j = (npoints / 2 + i + isOdd) % npoints; X[i] = delta * (-npoints / 2 + i); double xShift = X[i] * shift; double c = cos(xShift); double s = sin(xShift); YR[i] = result[2 * j] * c - result[2 * j + 1] * s; YI[i] = result[2 * j] * s + result[2 * j + 1] * c; YR[i] *= dx; YI[i] *= dx; } if (npointsX == npoints + 1) X[npoints] = X[npoints - 1] + delta; // Caption & label auto inputUnit = inWS->getAxis(0)->unit(); if (inputUnit) { boost::shared_ptr<Kernel::Units::Label> lblUnit = boost::dynamic_pointer_cast<Kernel::Units::Label>( UnitFactory::Instance().create("Label")); if (lblUnit) { lblUnit->setLabel( inverseCaption[inWS->getAxis(0)->unit()->caption()], inverseLabel[inWS->getAxis(0)->unit()->label().ascii()]); outWS->getAxis(0)->unit() = lblUnit; } } outWS->dataX(spec).assign(X.begin(), X.end()); outWS->dataY(spec).assign(YR.begin(), YR.end()); outWS->dataE(spec).assign(E.begin(), E.end()); outWS->dataX(nspec + spec).assign(X.begin(), X.end()); outWS->dataY(nspec + spec).assign(YI.begin(), YI.end()); outWS->dataE(nspec + spec).assign(E.begin(), E.end()); }