Exemple #1
0
    /**
     * 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;
    }
Exemple #2
0
/**
 * 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 &)
            {}
        }
    }
}
Exemple #3
0
    /**
     * 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;
    }