void LoadDaveGrp::getData(std::vector<MantidVec *> &data, std::vector<MantidVec *> &errs) { double data_val = 0.0; double err_val = 0.0; API::Progress progress(this, 0.0, 1.0, this->nGroups); for(int j = 0; j < this->nGroups; j++) { // Skip the group comment line this->readLine(); // Read the data block MantidVec *d = new MantidVec(); MantidVec *e = new MantidVec(); for(std::size_t k = 0; k < static_cast<std::size_t>(this->xLength); k++) { this->readLine(); std::istringstream is(this->line); is >> data_val >> err_val; d->push_back(data_val); e->push_back(err_val); } data.push_back(d); errs.push_back(e); progress.report(); } }
/** * Find the overlap of the inputWS with the given polygon * @param oldAxis1 :: Axis 1 bin boundaries from the input grid * @param oldAxis2 :: Axis 2 bin boundaries from the input grid * @param newPoly :: The new polygon to test * @returns A list of intersection locations with weights of the overlap */ std::vector<Rebin2D::BinWithWeight> Rebin2D::findIntersections(const MantidVec & oldAxis1, const MantidVec & oldAxis2, const Geometry::ConvexPolygon & newPoly) const { std::vector<BinWithWeight> overlaps; overlaps.reserve(5); // Have a guess at a posible limit const size_t nxpoints(oldAxis1.size()-1), nypoints(oldAxis2.size()-1); const double yn_lo(newPoly[0].Y()), yn_hi(newPoly[1].Y()); const double xn_lo(newPoly[0].X()), xn_hi(newPoly[2].X()); for(size_t i = 0; i < nypoints; ++i) { const double yo_lo(oldAxis2[i]), yo_hi(oldAxis2[i+1]); // Check if there is a possibility of overlap if( yo_hi < yn_lo || yo_lo > yn_hi ) continue; for(size_t j = 0; j < nxpoints; ++j) { const double xo_lo(oldAxis1[j]), xo_hi(oldAxis1[j+1]); // Check if there is a possibility of overlap if( xo_hi < xn_lo || xo_lo > xn_hi ) continue; ConvexPolygon oldPoly(xo_lo, xo_hi, yo_lo, yo_hi); try { ConvexPolygon overlap = intersectionByLaszlo(newPoly, oldPoly); overlaps.push_back(BinWithWeight(i,j,overlap.area()/oldPoly.area())); } catch(Geometry::NoIntersectionException &) {} } } return overlaps; }
/** This is a slightly "clever" method as it makes some guesses about where is best * to look for the right Q bin based on the fact that the input Qs (calcualted from wavelengths) tend * to go down while the output Qs are always in accending order * @param[in] OutQs the array of output Q bin boundaries, this finds the bin that contains the QIn value * @param[in] QToFind the Q value to find the correct bin for * @param[in, out] loc points to the bin boundary (in the OutQs array) whos Q is higher than QToFind and higher by the smallest amount. Algorithm starts by checking the value of loc passed and then all the bins _downwards_ through the array */ void Q1D2::getQBinPlus1(const MantidVec & OutQs, const double QToFind, MantidVec::const_iterator & loc) const { if ( loc != OutQs.end() ) { while ( loc != OutQs.begin() ) { if ( (QToFind >= *(loc-1)) && (QToFind < *loc) ) { return; } --loc; } if ( QToFind < *loc ) { //QToFind is outside the array leave loc == OutQs.begin() return; } } else //loc == OutQs.end() { if ( OutQs.empty() || QToFind > *(loc-1) ) { //outside the array leave loc == OutQs.end() return; } } // we are lost, normally the order of the Q values means we only get here on the first iteration. It's slow loc = std::lower_bound(OutQs.begin(), OutQs.end(), QToFind); }
/** Deals with the (rare) case where the flightpath is longer than the reference * Note that in this case both T1 & T2 will be greater than Tmax */ std::pair<int, int> UnwrapMonitor::handleFrameOverlapped(const MantidVec &xdata, const double &Ld, std::vector<double> &tempX) { // Calculate the interval to exclude const double Dt = (m_Tmax - m_Tmin) * (1 - (m_LRef / Ld)); // This gives us new minimum & maximum tof values const double minT = m_Tmin + Dt; const double maxT = m_Tmax - Dt; // Can have situation where Ld is so much larger than Lref that everything // would be excluded. // This is an invalid input - warn and leave spectrum unwrapped if (minT > maxT) { g_log.warning() << "Invalid input, Ld (" << Ld << ") >> Lref (" << m_LRef << "). Current spectrum will not be unwrapped.\n"; return std::make_pair(0, static_cast<int>(xdata.size() - 1)); } int min = 0, max = static_cast<int>(xdata.size()); for (unsigned int j = 0; j < m_XSize; ++j) { const double T = xdata[j]; if (T < minT) { min = j + 1; tempX.erase(tempX.begin()); } else if (T > maxT) { tempX.erase(tempX.end() - (max - j), tempX.end()); max = j - 1; break; } } return std::make_pair(min, max); }
/** Calculates the rebin parameters in the case where the range of the second * workspace is * entirely within that of the first workspace. * 'Inclusion' is used in the sense of a set being included in anothre. * @param X1 :: The bin boundaries from the first workspace * @param i :: Indicates the index in X1 immediately before the overlap * region starts * @param X2 :: The bin boundaries from the second workspace * @param params :: A reference to the vector of rebinning parameters */ void MergeRuns::inclusionParams(const MantidVec &X1, int64_t &i, const MantidVec &X2, std::vector<double> ¶ms) const { // First calculate the number of bins in each workspace that are in the // overlap region int64_t overlapbins1, overlapbins2; for (overlapbins1 = 1; X1[i + overlapbins1] < X2.back(); ++overlapbins1) { } //++overlapbins1; overlapbins2 = X2.size() - 1; // In the overlap region, we want to use whichever one has the larger bins (on // average) if (overlapbins1 + 1 <= overlapbins2) { // In the case where the first workspace has larger bins it's easy // - just add the rest of X1's bins for (; i < static_cast<int64_t>(X1.size()); ++i) { params.push_back(X1[i] - X1[i - 1]); params.push_back(X1[i]); } } else { // In this case we want all of X2's bins first (without the first and last // boundaries) for (size_t j = 1; j < X2.size() - 1; ++j) { params.push_back(X2[j] - params.back()); params.push_back(X2[j]); } // And now those from X1 that lie above the overlap region i += overlapbins1; for (; i < static_cast<int64_t>(X1.size()); ++i) { params.push_back(X1[i] - params.back()); params.push_back(X1[i]); } } }
/** Calculates the rebin parameters in the case where the bins of the two * workspaces intersect. * 'Intersect' is used in the sense of two intersecting sets. * @param X1 :: The bin boundaries from the first workspace * @param i :: Indicates the index in X1 immediately before the overlap * region starts * @param X2 :: The bin boundaries from the second workspace * @param params :: A reference to the vector of rebinning parameters */ void MergeRuns::intersectionParams(const MantidVec &X1, int64_t &i, const MantidVec &X2, std::vector<double> ¶ms) const { // First calculate the number of bins in each workspace that are in the // overlap region int64_t overlapbins1, overlapbins2; overlapbins1 = X1.size() - i; for (overlapbins2 = 0; X2[overlapbins2] < X1.back(); ++overlapbins2) { } // We want to use whichever one has the larger bins (on average) if (overlapbins1 < overlapbins2) { // In this case we want the rest of the bins from the first workspace..... for (; i < static_cast<int64_t>(X1.size()); ++i) { params.push_back(X1[i] - X1[i - 1]); params.push_back(X1[i]); } // Now remove the last bin & boundary params.pop_back(); params.pop_back(); // ....and then the non-overlap ones from the second workspace for (size_t j = overlapbins2; j < X2.size(); ++j) { params.push_back(X2[j] - params.back()); params.push_back(X2[j]); } } else { // In this case we just have to add all the bins from the second workspace for (size_t j = 1; j < X2.size(); ++j) { params.push_back(X2[j] - params.back()); params.push_back(X2[j]); } } }
MantidVec operator()(const MantidVec &_Left, const MantidVec &_Right) const { // apply operator+ to operands MantidVec v(_Left.size()); std::transform(_Left.begin(), _Left.end(), _Right.begin(), v.begin(), SumGaussError<double>()); return (v); }
/** * load vectors onto a Workspace2D with 3 bins (the three components of the * vectors) * dataX for the origin of the vector (assumed (0,0,0) ) * dataY for the tip of the vector * dataE is assumed (0,0,0), no errors * @param h5file file identifier * @param gws pointer to WorkspaceGroup being filled * @param sorting_indexes permutation of qvmod indexes to render it in * increasing order of momemtum transfer */ const MantidVec LoadSassena::loadQvectors(const hid_t &h5file, API::WorkspaceGroup_sptr gws, std::vector<int> &sorting_indexes) { const std::string gwsName = this->getPropertyValue("OutputWorkspace"); const std::string setName("qvectors"); hsize_t dims[3]; if (dataSetInfo(h5file, setName, dims) < 0) { throw Kernel::Exception::FileError( "Unable to read " + setName + " dataset info:", m_filename); } int nq = static_cast<int>(dims[0]); // number of q-vectors double *buf = new double[nq * 3]; this->dataSetDouble(h5file, "qvectors", buf); MantidVec qvmod; // store the modulus of the vector double *curr = buf; for (int iq = 0; iq < nq; iq++) { qvmod.push_back( sqrt(curr[0] * curr[0] + curr[1] * curr[1] + curr[2] * curr[2])); curr += 3; } if (getProperty("SortByQVectors")) { std::vector<mypair> qvmodpair; for (int iq = 0; iq < nq; iq++) qvmodpair.push_back(mypair(qvmod[iq], iq)); std::sort(qvmodpair.begin(), qvmodpair.end(), compare); for (int iq = 0; iq < nq; iq++) sorting_indexes.push_back(qvmodpair[iq].second); std::sort(qvmod.begin(), qvmod.end()); } else for (int iq = 0; iq < nq; iq++) sorting_indexes.push_back(iq); DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>( API::WorkspaceFactory::Instance().create("Workspace2D", nq, 3, 3)); std::string wsName = gwsName + std::string("_") + setName; ws->setTitle(wsName); for (int iq = 0; iq < nq; iq++) { MantidVec &Y = ws->dataY(iq); const int index = sorting_indexes[iq]; curr = buf + 3 * index; Y.assign(curr, curr + 3); } delete[] buf; ws->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create( "MomentumTransfer"); // Set the Units this->registerWorkspace( gws, wsName, ws, "X-axis: origin of Q-vectors; Y-axis: tip of Q-vectors"); return qvmod; }
/** Calculates the overall normalization factor. * This multiplies result by (bin width * sum of monitor counts) / total frame * width. * @param X The X vector * @param Y The data vector * @param E The error vector */ void NormaliseToMonitor::normalisationFactor(const MantidVec &X, MantidVec *Y, MantidVec *E) { const double monitorSum = std::accumulate(Y->begin(), Y->end(), 0.0); const double range = X.back() - X.front(); MantidVec::size_type specLength = Y->size(); for (MantidVec::size_type j = 0; j < specLength; ++j) { const double factor = range / ((X[j + 1] - X[j]) * monitorSum); (*Y)[j] *= factor; (*E)[j] *= factor; } }
/// Returns vector with x-values of spectrum if MatrixWorkspace does not contain /// histogram data. MantidVec FunctionDomain1DSpectrumCreator::getVectorNonHistogram() const { const MantidVec wsXData = m_matrixWorkspace->readX(m_workspaceIndex); size_t wsXSize = wsXData.size(); if (wsXSize < 1) { throw std::invalid_argument( "Workspace2D with less than one x-value cannot be processed."); } return MantidVec(wsXData); }
/** * @param tofMin Return value for minimum tof to be masked * @param tofMax Return value for maximum tof to be masked * @param tofPeak time-of-flight of the single crystal peak * @param tof tof-of-flight axis for the spectrum where the peak supposedly * exists */ void MaskPeaksWorkspace::getTofRange(double &tofMin, double &tofMax, const double tofPeak, const MantidVec &tof) { tofMin = tof.front(); tofMax = tof.back() - 1; if (!isEmpty(m_tofMin)) { tofMin = tofPeak + m_tofMin; } if (!isEmpty(m_tofMax)) { tofMax = tofPeak + m_tofMax; } }
int UnwrapSNS::unwrapX(const MantidVec &datain, MantidVec &dataout, const double &Ld) { MantidVec tempX_L; // lower half - to be frame wrapped tempX_L.reserve(m_XSize); tempX_L.clear(); MantidVec tempX_U; // upper half - to not be frame wrapped tempX_U.reserve(m_XSize); tempX_U.clear(); double filterVal = m_Tmin * Ld / m_LRef; dataout.clear(); int specialBin = 0; for (int bin = 0; bin < m_XSize; ++bin) { // This is the time-of-flight value under consideration in the current // iteration of the loop const double tof = datain[bin]; if (tof < filterVal) { tempX_L.push_back(tof + m_frameWidth); // Record the bins that fall in this range for copying over the data & // errors if (specialBin < bin) specialBin = bin; } else { tempX_U.push_back(tof); } } // loop over X values // now put it back into the vector supplied dataout.clear(); dataout.insert(dataout.begin(), tempX_U.begin(), tempX_U.end()); dataout.insert(dataout.end(), tempX_L.begin(), tempX_L.end()); assert(datain.size() == dataout.size()); return specialBin; }
/** * Get the start and end of the x-interval. * @param X :: The x-vector of a spectrum. * @param isHistogram :: Is the x-vector comming form a histogram? If it's true * the bin * centres are used. * @return :: A pair of start x and end x. */ std::pair<double, double> WienerSmooth::getStartEnd(const MantidVec &X, bool isHistogram) const { const size_t n = X.size(); if (n < 3) { // 3 is the smallest number for this method to work without breaking throw std::runtime_error( "Number of bins/data points cannot be smaller than 3."); } if (isHistogram) { return std::make_pair((X[0] + X[1]) / 2, (X[n - 1] + X[n - 2]) / 2); } // else return std::make_pair(X.front(), X.back()); }
/// Retrieve and check the Start/EndX parameters, if set void Linear::setRange(const MantidVec& X, const MantidVec& Y) { //read in the values that the user selected double startX = getProperty("StartX"); double endX = getProperty("EndX"); //If the user didn't a start default to the start of the data if ( isEmpty(startX) ) startX = X.front(); //the default for the end is the end of the data if ( isEmpty(endX) ) endX = X.back(); // Check the validity of startX if ( startX < X.front() ) { g_log.warning("StartX out of range! Set to start of frame."); startX = X.front(); } // Now get the corresponding bin boundary that comes before (or coincides with) this value for (m_minX = 0; X[m_minX+1] < startX; ++m_minX) {} // Check the validity of endX and get the bin boundary that come after (or coincides with) it if ( endX >= X.back() || endX < startX ) { if ( endX != X.back() ) { g_log.warning("EndX out of range! Set to end of frame"); endX = X.back(); } m_maxX = static_cast<int>(Y.size()); } else { for (m_maxX = m_minX; X[m_maxX] < endX; ++m_maxX) {} } }
/** Execute the algorithm. */ void WeightedMeanOfWorkspace::exec() { MatrixWorkspace_sptr inputWS = this->getProperty("InputWorkspace"); // Check if it is an event workspace EventWorkspace_const_sptr eventW = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS); if (eventW != NULL) { throw std::runtime_error("WeightedMeanOfWorkspace cannot handle EventWorkspaces!"); } // Create the output workspace MatrixWorkspace_sptr singleValued = WorkspaceFactory::Instance().create("WorkspaceSingleValue", 1, 1, 1); // Calculate weighted mean std::size_t numHists = inputWS->getNumberHistograms(); double averageValue = 0.0; double weightSum = 0.0; for (std::size_t i = 0; i < numHists; ++i) { try { IDetector_const_sptr det = inputWS->getDetector(i); if( det->isMonitor() || det->isMasked() ) { continue; } } catch (...) { // Swallow these if no instrument is found ; } MantidVec y = inputWS->dataY(i); MantidVec e = inputWS->dataE(i); double weight = 0.0; for (std::size_t j = 0; j < y.size(); ++j) { if (!boost::math::isnan(y[j]) && !boost::math::isinf(y[j]) && !boost::math::isnan(e[j]) && !boost::math::isinf(e[j])) { weight = 1.0 / (e[j] * e[j]); averageValue += (y[j] * weight); weightSum += weight; } } } singleValued->dataX(0)[0] = 0.0; singleValued->dataY(0)[0] = averageValue / weightSum; singleValued->dataE(0)[0] = std::sqrt(weightSum); this->setProperty("OutputWorkspace", singleValued); }
/** * Create workspace to store the structure factor. * First spectrum is the real part, second spectrum is the imaginary part * X values are the modulus of the Q-vectors * @param h5file file identifier * @param gws pointer to WorkspaceGroup being filled * @param setName string name of dataset * @param qvmod vector of Q-vectors' moduli * @param sorting_indexes permutation of qvmod indexes to render it in increasing order of momemtum transfer */ void LoadSassena::loadFQ(const hid_t& h5file, API::WorkspaceGroup_sptr gws, const std::string setName, const MantidVec &qvmod, const std::vector<int> &sorting_indexes) { const std::string gwsName = this->getPropertyValue("OutputWorkspace"); int nq = static_cast<int>( qvmod.size() ); //number of q-vectors DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(API::WorkspaceFactory::Instance().create("Workspace2D", 2, nq, nq)); const std::string wsName = gwsName + std::string("_") + setName; ws->setTitle(wsName); double* buf = new double[nq*2]; this->dataSetDouble(h5file,setName,buf); MantidVec& re = ws->dataY(0); // store the real part ws->dataX(0) = qvmod; //X-axis values are the modulus of the q vector MantidVec& im = ws->dataY(1); // store the imaginary part ws->dataX(1) = qvmod; double *curr = buf; for(int iq=0; iq<nq; iq++){ const int index=sorting_indexes[iq]; re[index]=curr[0]; im[index]=curr[1]; curr+=2; } delete[] buf; // Set the Units ws->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("MomentumTransfer"); this->registerWorkspace(gws,wsName,ws, "X-axis: Q-vector modulus; Y-axis: intermediate structure factor"); }
void Divide::performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY, const MantidVec &lhsE, const MantidVec &rhsY, const MantidVec &rhsE, MantidVec &YOut, MantidVec &EOut) { (void)lhsX; // Avoid compiler warning const int bins = static_cast<int>(lhsE.size()); for (int j = 0; j < bins; ++j) { // Get references to the input Y's const double leftY = lhsY[j]; const double rightY = rhsY[j]; // error dividing two uncorrelated numbers, re-arrange so that you don't // get infinity if leftY==0 (when rightY=0 the Y value and the result will // both be infinity) // (Sa/a)2 + (Sb/b)2 = (Sc/c)2 // (Sa c/a)2 + (Sb c/b)2 = (Sc)2 // = (Sa 1/b)2 + (Sb (a/b2))2 // (Sc)2 = (1/b)2( (Sa)2 + (Sb a/b)2 ) EOut[j] = sqrt(pow(lhsE[j], 2) + pow(leftY * rhsE[j] / rightY, 2)) / fabs(rightY); // Copy the result last in case one of the input workspaces is also any // output YOut[j] = leftY / rightY; ; } }
void WeightedMean::performBinaryOperation(const MantidVec& lhsX, const MantidVec& lhsY, const MantidVec& lhsE, const double rhsY, const double rhsE, MantidVec& YOut, MantidVec& EOut) { UNUSED_ARG(lhsX); assert( lhsX.size() == 1 ); // If we get here we've got two single column workspaces so it's easy. if (lhsE[0] > 0.0 && rhsE > 0.0) { const double err1 = lhsE[0]*lhsE[0]; const double err2 = rhsE*rhsE; YOut[0] = (lhsY[0]/err1)+(rhsY/err2); EOut[0] = (err1*err2)/(err1+err2); YOut[0] *= EOut[0]; EOut[0] = sqrt(EOut[0]); } else if (lhsE[0] > 0.0 && rhsE <= 0.0) { YOut[0] = lhsY[0]; EOut[0] = lhsE[0]; } else if (lhsE[0] <= 0.0 && rhsE > 0.0) { YOut[0] = rhsY; EOut[0] = rhsE; } else { YOut[0] = 0.0; EOut[0] = 0.0; } }
/** * @param xValues The X data for the fitted spectrum */ void ComptonScatteringCountRate::createPositivityCM(const MantidVec &xValues) { // -- Constraint matrix for J(y) > 0 -- // The first N columns are filled with J(y) for each mass + N_h for the first // mass hermite // terms included + (n+1) for each termn the background of order n // The background columns are filled with x^j/error where j=(1,n+1) const size_t nrows(xValues.size()); size_t nColsCMatrix(m_fixedParamIndices.size()); m_cmatrix = Kernel::DblMatrix(nrows, nColsCMatrix); // Fill background values as they don't change at all if (m_bkgdPolyN > 0) { size_t polyStartCol = nColsCMatrix - m_bkgdPolyN - 1; for (size_t i = 0; i < nrows; ++i) // rows { double *row = m_cmatrix[i]; const double &xi = xValues[i]; const double &erri = m_errors[i]; size_t polyN = m_bkgdPolyN; for (size_t j = polyStartCol; j < nColsCMatrix; ++j) // cols { row[j] = std::pow(xi, static_cast<double>(polyN)) / erri; --polyN; } } } }
void Divide::performBinaryOperation(const MantidVec &lhsX, const MantidVec &lhsY, const MantidVec &lhsE, const double rhsY, const double rhsE, MantidVec &YOut, MantidVec &EOut) { (void)lhsX; // Avoid compiler warning if (rhsY == 0 && m_warnOnZeroDivide) g_log.warning() << "Division by zero: the RHS is a single-valued vector " "with value zero." << "\n"; // Do the right-hand part of the error calculation just once const double rhsFactor = pow(rhsE / rhsY, 2); const int bins = static_cast<int>(lhsE.size()); for (int j = 0; j < bins; ++j) { // Get reference to input Y const double leftY = lhsY[j]; // see comment in the function above for the error formula EOut[j] = sqrt(pow(lhsE[j], 2) + pow(leftY, 2) * rhsFactor) / fabs(rhsY); // Copy the result last in case one of the input workspaces is also any // output YOut[j] = leftY / rhsY; } }
/// Returns vector with x-values of spectrum if MatrixWorkspace contains /// histogram data. MantidVec FunctionDomain1DSpectrumCreator::getVectorHistogram() const { const MantidVec wsXData = m_matrixWorkspace->readX(m_workspaceIndex); size_t wsXSize = wsXData.size(); if (wsXSize < 2) { throw std::invalid_argument("Histogram Workspace2D with less than two " "x-values cannot be processed."); } MantidVec x(wsXSize - 1); for (size_t i = 0; i < x.size(); ++i) { x[i] = (wsXData[i] + wsXData[i + 1]) / 2.0; } return x; }
/** Read the specified number of entries from input file into the * the array that is passed * @param[in] nEntries the number of numbers to read * @param[out] output the contents of this will be replaced by the data read from the file */ void LoadRKH::readNumEntrys(const int nEntries, MantidVec & output) { output.resize(nEntries); for( int i = 0; i < nEntries; ++i ) { m_fileIn >> output[i]; } }
/** Calculates Sn as estimator of scale for given vector * * This method implements a naive calculation of Sn, as defined by Rousseeuw *and Croux (http://dx.doi.org/10.2307%2F2291267). * In contrast to standard deviation, this is more robust towards outliers. * * @param begin :: Beginning of vector. * @param end :: End of vector. * @return Sn of supplied data. */ double PoldiPeakSearch::getSn(MantidVec::const_iterator begin, MantidVec::const_iterator end) const { size_t numberOfPoints = std::distance(begin, end); MantidVec absoluteDifferenceMedians(numberOfPoints); PARALLEL_FOR_NO_WSP_CHECK() for (int i = 0; i < static_cast<int>(numberOfPoints); ++i) { double currentValue = *(begin + i); MantidVec temp; temp.reserve(numberOfPoints - 1); for (int j = 0; j < static_cast<int>(numberOfPoints); ++j) { if (j != i) { temp.push_back(fabs(*(begin + j) - currentValue)); } } std::sort(temp.begin(), temp.end()); absoluteDifferenceMedians[i] = getMedianFromSortedVector(temp.begin(), temp.end()); } std::sort(absoluteDifferenceMedians.begin(), absoluteDifferenceMedians.end()); return 1.1926 * getMedianFromSortedVector(absoluteDifferenceMedians.begin(), absoluteDifferenceMedians.end()); }
/** Retrieves a vector with all counts that belong to the background * * In this method, a vector is assembled which contains all count data that is *considered to be background. * Whether a point is considered background depends on its distance to the *given peak positions. * * @param peakPositions :: Peak positions. * @param correlationCounts :: Vector with the complete correlation spectrum. * @return Vector only with counts that belong to the background. */ MantidVec PoldiPeakSearch::getBackground( std::list<MantidVec::const_iterator> peakPositions, const MantidVec &correlationCounts) const { size_t backgroundPoints = getNumberOfBackgroundPoints(peakPositions, correlationCounts); MantidVec background; background.reserve(backgroundPoints); for (MantidVec::const_iterator point = correlationCounts.begin() + 1; point != correlationCounts.end() - 1; ++point) { if (distanceToPeaksGreaterThanMinimum(peakPositions, point)) { background.push_back(*point); } } return background; }
/** Write data in SLOG format */ void SaveGSS::writeSLOGdata(const int bank, const bool MultiplyByBinWidth, std::stringstream &out, const MantidVec &X, const MantidVec &Y, const MantidVec &E) const { const size_t datasize = Y.size(); double bc1 = X.front(); // minimum TOF in microseconds if (bc1 <= 0.) { throw std::runtime_error( "Cannot write out logarithmic data starting at zero"); } double bc2 = 0.5 * (*(X.rbegin()) + *(X.rbegin() + 1)); // maximum TOF (in microseconds?) double bc3 = (*(X.begin() + 1) - bc1) / bc1; // deltaT/T g_log.debug() << "SaveGSS(): Min TOF = " << bc1 << std::endl; writeBankLine(out, "SLOG", bank, datasize); out << std::fixed << " " << std::setprecision(0) << std::setw(10) << bc1 << std::fixed << " " << std::setprecision(0) << std::setw(10) << bc2 << std::fixed << " " << std::setprecision(7) << std::setw(10) << bc3 << std::fixed << " 0 FXYE" << std::endl; for (size_t i = 0; i < datasize; i++) { double y = Y[i]; double e = E[i]; if (MultiplyByBinWidth) { // Multiple by bin width as double delta = X[i + 1] - X[i]; y *= delta; e *= delta; } e = fixErrorValue(e); out << " " << std::fixed << std::setprecision(9) << std::setw(20) << 0.5 * (X[i] + X[i + 1]) << " " << std::fixed << std::setprecision(9) << std::setw(20) << y << " " << std::fixed << std::setprecision(9) << std::setw(20) << e << std::setw(12) << " " << "\n"; // let it flush its own buffer } out << std::flush; return; }
void PoissonErrors::performBinaryOperation(const MantidVec& lhsX, const MantidVec& lhsY, const MantidVec& lhsE, const double rhsY, const double rhsE, MantidVec& YOut, MantidVec& EOut) { (void) lhsE; (void) lhsX; //Avoid compiler warning assert( lhsX.size() == 1 ); // If we get here we've got two single column workspaces so it's easy. YOut[0] = lhsY[0]; const double fractional = rhsY ? rhsE/rhsY : 0.0; EOut[0] = fractional*lhsY[0]; }
/** * Returns the phase shift to apply * If "AutoShift" is set, calculates this automatically as -X[N/2] * Otherwise, returns user-supplied "Shift" (or zero if none set) * @param xValues :: [input] Reference to X values of input workspace * @returns :: Phase shift */ double FFT::getPhaseShift(const MantidVec &xValues) { double shift = 0.0; const bool autoshift = getProperty("AutoShift"); if (autoshift) { const size_t mid = xValues.size() / 2; shift = -xValues[mid]; } else { shift = getProperty("Shift"); } shift *= 2 * M_PI; return shift; }
/** Zeroes data (Y/E) at the end of a spectrum * @param start :: The index to start zeroing at * @param end :: The index to end zeroing at * @param Y :: The data vector * @param E :: The error vector */ void RemoveBins::RemoveFromEnds(int start, int end, MantidVec& Y, MantidVec& E) { if ( start ) --start; int size = static_cast<int>(Y.size()); if ( end > size ) end = size; for (int j = start; j < end; ++j) { Y[j] = 0.0; E[j] = 0.0; } return; }
/** Divides the number of counts in each output Q bin by the wrighting ("number that would expected to arrive") * The errors are propogated using the uncorrolated error estimate for multiplication/division * @param[in] normSum the weighting for each bin * @param[in] normError2 square of the error on the normalization * @param[in, out] counts counts in each bin * @param[in, out] errors input the _square_ of the error on each bin, output the total error (unsquared) */ void Q1D2::normalize(const MantidVec & normSum, const MantidVec & normError2, MantidVec & counts, MantidVec & errors) const { for (size_t k = 0; k < counts.size(); ++k) { // the normalisation is a = b/c where b = counts c =normalistion term const double c = normSum[k]; const double a = counts[k] /= c; // when a = b/c, the formula for Da, the error on a, in terms of Db, etc. is (Da/a)^2 = (Db/b)^2 + (Dc/c)^2 //(Da)^2 = ((Db/b)^2 + (Dc/c)^2)*(b^2/c^2) = ((Db/c)^2 + (b*Dc/c^2)^2) = (Db^2 + (b*Dc/c)^2)/c^2 = (Db^2 + (Dc*a)^2)/c^2 //this will work as long as c>0, but then the above formula above can't deal with 0 either const double aOverc = a/c; errors[k] = std::sqrt(errors[k]/(c*c) + normError2[k]*aOverc*aOverc); } }
/** * Calculate detector efficiency given a formula, the efficiency at the elastic line, * and a vector with energies. * Efficiency = f(Ei-DeltaE) / f(Ei) * Hope all compilers supports the NRVO (otherwise will copy the output vector) * @param eff0 :: calculated eff0 * @param formula :: formula to calculate efficiency (parsed from IDF) * @param xIn :: Energy bins vector (X axis) * @return a vector with the efficiencies */ MantidVec DetectorEfficiencyCorUser::calculateEfficiency(double eff0, const std::string& formula, const MantidVec& xIn) { MantidVec effOut(xIn.size() - 1); // x are bins and have more one value than y try { double e; mu::Parser p; p.DefineVar("e", &e); p.SetExpr(formula); // copied from Jaques Ollivier Code bool conditionForEnergy = std::min( std::abs( *std::min_element(xIn.begin(), xIn.end()) ) , m_Ei) < m_Ei; MantidVec::const_iterator xIn_it = xIn.begin(); // DeltaE MantidVec::iterator effOut_it = effOut.begin(); for (; effOut_it != effOut.end(); ++xIn_it, ++effOut_it) { if (conditionForEnergy ) { // cppcheck cannot see that this is used by reference by muparser e = std::fabs(m_Ei + *xIn_it); } else { // cppcheck cannot see that this is used by reference by muparser // cppcheck-suppress unreadVariable e = std::fabs(m_Ei - *xIn_it); } double eff = p.Eval(); *effOut_it = eff / eff0; } return effOut; } catch (mu::Parser::exception_type &e) { throw Kernel::Exception::InstrumentDefinitionError( "Error calculating formula from string. Muparser error message is: " + e.GetMsg()); } }