/// Takes a d-based domain and creates a Q-based MatrixWorkspace. MatrixWorkspace_sptr PoldiFitPeaks2D::getQSpectrum(const FunctionDomain1D &domain, const FunctionValues &values) const { // Put result into workspace, based on Q MatrixWorkspace_sptr ws1D = WorkspaceFactory::Instance().create( "Workspace2D", 1, domain.size(), values.size()); auto &xData = ws1D->mutableX(0); auto &yData = ws1D->mutableY(0); size_t offset = values.size() - 1; for (size_t i = 0; i < values.size(); ++i) { xData[offset - i] = Conversions::dToQ(domain[i]); yData[offset - i] = values[i]; } ws1D->getAxis(0)->setUnit("MomentumTransfer"); return ws1D; }
/** * Calculates function values for domain. In contrast to CompositeFunction, the *summation * of values is performed in a different way: The values are set to zero once at *the beginning, * then it is expected of the member functions to use *FunctionValues::addToCalculated or add * their values otherwise, without erasing the values. * * @param domain :: Function domain which is passed on to the member functions. * @param values :: Function values. */ void Poldi2DFunction::function(const FunctionDomain &domain, FunctionValues &values) const { CompositeFunction::function(domain, values); if (m_iteration > 0) { for (size_t i = 0; i < values.size(); ++i) { values.setFitWeight(i, 1.0 / sqrt(values.getCalculated(i) + 0.1)); } } }
void PoldiSpectrumLinearBackground::poldiFunction1D( const std::vector<int> &indices, const FunctionDomain1D &domain, FunctionValues &values) const { double backgroundDetector = getParameter(0); double wireCount = static_cast<double>(indices.size()); double distributionFactor = wireCount * wireCount * static_cast<double>(m_timeBinCount) / (2.0 * static_cast<double>(domain.size())); double backgroundD = backgroundDetector * distributionFactor; for (size_t i = 0; i < values.size(); ++i) { values.addToCalculated(i, backgroundD); } }
/// Function you want to fit to. /// @param domain :: The buffer for writing the calculated values. Must be big enough to accept dataSize() values void MultiDomainFunction::function(const FunctionDomain& domain, FunctionValues& values)const { // works only on CompositeDomain if (!dynamic_cast<const CompositeDomain*>(&domain)) { throw std::invalid_argument("Non-CompositeDomain passed to MultiDomainFunction."); } const CompositeDomain& cd = dynamic_cast<const CompositeDomain&>(domain); // domain must not have less parts than m_maxIndex if (cd.getNParts() <= m_maxIndex) { throw std::invalid_argument("CompositeDomain has too few parts (" + boost::lexical_cast<std::string>(cd.getNParts()) + ") for MultiDomainFunction (max index " + boost::lexical_cast<std::string>(m_maxIndex) + ")."); } // domain and values must be consistent if (cd.size() != values.size()) { throw std::invalid_argument("MultiDomainFunction: domain and values have different sizes."); } countValueOffsets(cd); // evaluate member functions values.zeroCalculated(); for(size_t iFun = 0; iFun < nFunctions(); ++iFun) { // find the domains member function must be applied to std::vector<size_t> domains; getFunctionDomains(iFun, cd, domains); for(auto i = domains.begin(); i != domains.end(); ++i) { const FunctionDomain& d = cd.getDomain(*i); FunctionValues tmp(d); getFunction(iFun)->function( d, tmp ); values.addToCalculated(m_valueOffsets[*i],tmp); } } }