/** * 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; }
/** * 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::rebinToFractionalOutput(const Geometry::Quadrilateral & inputQ, MatrixWorkspace_const_sptr inputWS, const size_t i, const size_t j, RebinnedOutput_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(); // Don't do the overlap removal if already RebinnedOutput. // This wreaks havoc on the data. if(inputWS->isDistribution() && inputWS->id() != "RebinnedOutput") { yValue *= overlapWidth; eValue *= overlapWidth; } eValue *= eValue; PARALLEL_CRITICAL(overlap) { outputWS->dataY(qi)[ei] += yValue; outputWS->dataE(qi)[ei] += eValue; outputWS->dataF(qi)[ei] += weight; } } catch(Geometry::NoIntersectionException &) {} } } }
/** * 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<SofQW2::BinWithWeight> SofQW2::findIntersections(API::MatrixWorkspace_const_sptr inputWS, const Geometry::ConvexPolygon & newPoly) const { const MantidVec & oldAxis1 = inputWS->readX(0); // Find the X boundaries const double xn_lo(newPoly[0].X()), xn_hi(newPoly[2].X()); MantidVec::const_iterator start_it = std::upper_bound(oldAxis1.begin(), oldAxis1.end(), xn_lo); MantidVec::const_iterator end_it = std::upper_bound(oldAxis1.begin(), oldAxis1.end(), xn_hi); size_t start_index(0), end_index(oldAxis1.size() - 1); if( start_it != oldAxis1.begin() ) { start_index = (start_it - oldAxis1.begin() - 1); } if( end_it != oldAxis1.end() ) { end_index = end_it - oldAxis1.begin(); } const double yn_lo(newPoly[0].Y()), yn_hi(newPoly[1].Y()); std::vector<BinWithWeight> overlaps; overlaps.reserve(5); // Have a guess at a possible limit std::list<QRangeCache>::const_iterator iend = m_qcached.end(); for(std::list<QRangeCache>::const_iterator itr = m_qcached.begin(); itr != iend; ++itr) { for(size_t j = start_index; j < end_index; ++j) { const double xo_lo(oldAxis1[j]), xo_hi(oldAxis1[j+1]); const QValues & qold = itr->qValues[j]; if( qold.upperLeft < yn_lo || qold.upperRight < yn_lo || qold.lowerLeft > yn_hi || qold.lowerRight > yn_hi ) continue; Quadrilateral oldPoly(V2D(xo_lo, qold.lowerLeft), V2D(xo_hi, qold.lowerRight), V2D(xo_hi, qold.upperRight), V2D(xo_lo, qold.upperLeft)); try { ConvexPolygon overlap = intersectionByLaszlo(newPoly, oldPoly); // std::cerr << "Areas " << newPoly << " " << oldPoly << "\n"; // std::cerr << "Areas " << overlap.area() << " " << oldPoly.area() << "\n"; overlaps.push_back(BinWithWeight(itr->wsIndex,j,itr->weight*overlap.area()/oldPoly.area())); } catch(Geometry::NoIntersectionException &) {} } } return overlaps; }