Example #1
0
/** Create a new instance of the same type of workspace as that given as
 * argument.
 *  If the optional size parameters are given, the workspace will be initialised
 * using
 *  those; otherwise it will be initialised to the same size as the parent.
 *  This method should be used when you want to carry over the Workspace data
 * members
 *  relating to the Instrument, Spectra-Detector Map, Sample & Axes to the new
 * workspace.
 *  If the workspace is the same size as its parent, then the X data, axes and
 * mask list are
 *  copied. If its a different size then they are not.
 *  @param  parent    A shared pointer to the parent workspace
 *  @param  NVectors  (Optional) The number of vectors/histograms/detectors in
 * the workspace
 *  @param  XLength   (Optional) The number of X data points/bin boundaries in
 * each vector (must all be the same)
 *  @param  YLength   (Optional) The number of data/error points in each vector
 * (must all be the same)
 *  @return A shared pointer to the newly created instance
 *  @throw  std::out_of_range If invalid (0 or less) size arguments are given
 *  @throw  NotFoundException If the class is not registered in the factory
 */
MatrixWorkspace_sptr
WorkspaceFactoryImpl::create(const MatrixWorkspace_const_sptr &parent,
                             size_t NVectors, size_t XLength,
                             size_t YLength) const {
  bool differentSize(true);
  // Use the parent sizes if new ones are not specified
  if (NVectors == size_t(-1))
    NVectors = parent->getNumberHistograms();
  if (XLength == size_t(-1))
    XLength = parent->dataX(0).size();
  if (YLength == size_t(-1)) {
    differentSize = false;
    YLength = parent->blocksize();
  }

  // If the parent is an EventWorkspace, we want it to spawn a Workspace2D (or
  // managed variant) as a child
  std::string id(parent->id());
  if (id == "EventWorkspace")
    id = "Workspace2D";

  // Create an 'empty' workspace of the appropriate type and size
  MatrixWorkspace_sptr ws = create(id, NVectors, XLength, YLength);

  // Copy over certain parent data members
  initializeFromParent(parent, ws, differentSize);

  return ws;
}
Example #2
0
/**
 * 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());
}
Example #3
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 &)
            {}
        }
    }
}
Example #4
0
/**
 * This function creates the output workspace. In the case of a RebinnedOutput
 * workspace, the resulting workspace only needs to be a Workspace2D to handle
 * the integration. Other workspaces are handled normally.
 * @return the output workspace
 */
MatrixWorkspace_sptr Integration::getOutputWorkspace(MatrixWorkspace_const_sptr inWS)
{
  if (inWS->id() == "RebinnedOutput")
  {
    MatrixWorkspace_sptr outWS = API::WorkspaceFactory::Instance().create("Workspace2D",
                                                                          m_MaxSpec-m_MinSpec+1,2,1);
    API::WorkspaceFactory::Instance().initializeFromParent(inWS, outWS, true);
    return outWS;
  }
  else
  {
    return API::WorkspaceFactory::Instance().create(inWS, m_MaxSpec-m_MinSpec+1,
                                                    2, 1);
  }
}
Example #5
0
/** Executes the algorithm
 *
 */
void SumSpectra::exec()
{
  // Try and retrieve the optional properties
  m_MinSpec = getProperty("StartWorkspaceIndex");
  m_MaxSpec = getProperty("EndWorkspaceIndex");
  const std::vector<int> indices_list = getProperty("ListOfWorkspaceIndices");

  keepMonitors = getProperty("IncludeMonitors");

  // Get the input workspace
  MatrixWorkspace_const_sptr localworkspace = getProperty("InputWorkspace");

  numberOfSpectra = static_cast<int>(localworkspace->getNumberHistograms());
  this->yLength = static_cast<int>(localworkspace->blocksize());

  // Check 'StartSpectrum' is in range 0-numberOfSpectra
  if ( m_MinSpec > numberOfSpectra )
  {
    g_log.warning("StartWorkspaceIndex out of range! Set to 0.");
    m_MinSpec = 0;
  }

  if (indices_list.empty())
  {
    //If no list was given and no max, just do all.
    if ( isEmpty(m_MaxSpec) ) m_MaxSpec = numberOfSpectra-1;
  }

  //Something for m_MaxSpec was given but it is out of range?
  if (!isEmpty(m_MaxSpec) && ( m_MaxSpec > numberOfSpectra-1 || m_MaxSpec < m_MinSpec ))
  {
    g_log.warning("EndWorkspaceIndex out of range! Set to max Workspace Index");
    m_MaxSpec = numberOfSpectra;
  }

  //Make the set of indices to sum up from the list
  this->indices.insert(indices_list.begin(), indices_list.end());

  //And add the range too, if any
  if (!isEmpty(m_MaxSpec))
  {
    for (int i = m_MinSpec; i <= m_MaxSpec; i++)
      this->indices.insert(i);
  }

  //determine the output spectrum id
  m_outSpecId = this->getOutputSpecId(localworkspace);
  g_log.information() << "Spectra remapping gives single spectra with spectra number: "
                      << m_outSpecId << "\n";

  m_CalculateWeightedSum = getProperty("WeightedSum");

 
  EventWorkspace_const_sptr eventW = boost::dynamic_pointer_cast<const EventWorkspace>(localworkspace);
  if (eventW)
  {
    m_CalculateWeightedSum = false;
    this->execEvent(eventW, this->indices);
  }
  else
  {
    //-------Workspace 2D mode -----

    // Create the 2D workspace for the output
    MatrixWorkspace_sptr outputWorkspace = API::WorkspaceFactory::Instance().create(localworkspace,
                                                           1,localworkspace->readX(0).size(),this->yLength);
    size_t numSpectra(0); // total number of processed spectra
    size_t numMasked(0);  // total number of the masked and skipped spectra
    size_t numZeros(0);   // number of spectra which have 0 value in the first column (used in special cases of evaluating how good Puasonian statistics is)
  
    Progress progress(this, 0, 1, this->indices.size());

    // This is the (only) output spectrum
    ISpectrum * outSpec = outputWorkspace->getSpectrum(0);

    // Copy over the bin boundaries
    outSpec->dataX() = localworkspace->readX(0);

    //Build a new spectra map
    outSpec->setSpectrumNo(m_outSpecId);
    outSpec->clearDetectorIDs();

    if (localworkspace->id() == "RebinnedOutput")
    {
      this->doRebinnedOutput(outputWorkspace, progress,numSpectra,numMasked,numZeros);
    }
    else
    {
      this->doWorkspace2D(localworkspace, outSpec, progress,numSpectra,numMasked,numZeros);
    }

    // Pointer to sqrt function
    MantidVec& YError = outSpec->dataE();
    typedef double (*uf)(double);
    uf rs=std::sqrt;
    //take the square root of all the accumulated squared errors - Assumes Gaussian errors
    std::transform(YError.begin(), YError.end(), YError.begin(), rs);

    outputWorkspace->generateSpectraMap();
    // set up the summing statistics
    outputWorkspace->mutableRun().addProperty("NumAllSpectra",int(numSpectra),"",true);
    outputWorkspace->mutableRun().addProperty("NumMaskSpectra",int(numMasked),"",true);
    outputWorkspace->mutableRun().addProperty("NumZeroSpectra",int(numZeros),"",true);


    // Assign it to the output workspace property
    setProperty("OutputWorkspace", outputWorkspace);

  }
}