예제 #1
0
파일: IDATab.cpp 프로젝트: trnielsen/mantid
  /**
   * Creates and returns a "mini plot", from the given QwtPlot and QwtPlotCurve objects, as well as the given workspace
   * and workspace index.
   *
   * @param plot      :: the QwtPlot object
   * @param curve     :: the QwtPlotCurve object
   * @param workspace :: the workspace to use
   * @param wsIndex   :: the workspace index
   *
   * @returns the resulting QwtPlotCurve object
   */
  QwtPlotCurve* IDATab::plotMiniplot(QwtPlot* plot, QwtPlotCurve* curve, const std::string & workspace, size_t wsIndex)
  {
    if ( curve != NULL )
    {
      curve->attach(0);
      delete curve;
      curve = 0;
    }

    Mantid::API::MatrixWorkspace_const_sptr ws = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(Mantid::API::AnalysisDataService::Instance().retrieve(workspace));

    size_t nhist = ws->getNumberHistograms();
    if ( wsIndex >= nhist )
    {
      showInformationBox("Error: Workspace index out of range.");
      return NULL;
    }

    using Mantid::MantidVec;
    const MantidVec & dataX = ws->readX(wsIndex);
    const MantidVec & dataY = ws->readY(wsIndex);

    curve = new QwtPlotCurve();
    curve->setData(&dataX[0], &dataY[0], static_cast<int>(ws->blocksize()));
    curve->attach(plot);

    plot->replot();

    return curve;
  }
예제 #2
0
/**
 * Convert to the output dimensions
 * @param inputWs : Input Matrix workspace
 * @return workspace group containing output matrix workspaces of ki and kf
 */
Mantid::API::MatrixWorkspace_sptr ReflectometryTransform::execute(
    Mantid::API::MatrixWorkspace_const_sptr inputWs) const {
  auto ws = boost::make_shared<Mantid::DataObjects::Workspace2D>();

  ws->initialize(m_d1NumBins, m_d0NumBins,
                 m_d0NumBins); // Create the output workspace as a distribution

  // Mapping so that d0 and d1 values calculated can be added to the matrix
  // workspace at the correct index.
  const double gradD0 =
      double(m_d0NumBins) / (m_d0Max - m_d0Min); // The x - axis
  const double gradD1 =
      double(m_d1NumBins) / (m_d1Max - m_d1Min); // Actually the y-axis
  const double cxToIndex = -gradD0 * m_d0Min;
  const double cyToIndex = -gradD1 * m_d1Min;
  const double cxToD0 = m_d0Min - (1 / gradD0);
  const double cyToD1 = m_d1Min - (1 / gradD1);

  // Create an X - Axis.
  MantidVec xAxisVec = createXAxis(ws.get(), gradD0, cxToD0, m_d0NumBins,
                                   m_d0Label, "1/Angstroms");
  // Create a Y (vertical) Axis
  createVerticalAxis(ws.get(), xAxisVec, gradD1, cyToD1, m_d1NumBins, m_d1Label,
                     "1/Angstroms");

  // Loop over all entries in the input workspace and calculate d0 and d1
  // for each.
  auto spectraAxis = inputWs->getAxis(1);
  for (size_t index = 0; index < inputWs->getNumberHistograms(); ++index) {
    auto counts = inputWs->readY(index);
    auto wavelengths = inputWs->readX(index);
    auto errors = inputWs->readE(index);
    const size_t nInputBins = wavelengths.size() - 1;
    const double theta_final = spectraAxis->getValue(index);
    m_calculator->setThetaFinal(theta_final);
    // Loop over all bins in spectra
    for (size_t binIndex = 0; binIndex < nInputBins; ++binIndex) {
      const double wavelength =
          0.5 * (wavelengths[binIndex] + wavelengths[binIndex + 1]);
      double _d0 = m_calculator->calculateDim0(wavelength);
      double _d1 = m_calculator->calculateDim1(wavelength);

      if (_d0 >= m_d0Min && _d0 <= m_d0Max && _d1 >= m_d1Min &&
          _d1 <= m_d1Max) // Check that the calculated ki and kf are in range
      {
        const int outIndexX = static_cast<int>((gradD0 * _d0) + cxToIndex);
        const int outIndexZ = static_cast<int>((gradD1 * _d1) + cyToIndex);

        ws->dataY(outIndexZ)[outIndexX] += counts[binIndex];
        ws->dataE(outIndexZ)[outIndexX] += errors[binIndex];
      }
    }
  }
  return ws;
}
예제 #3
0
/**
 * Sum counts in detectors for purposes of rough plotting against the units on the x-axis.
 * Assumes that all spectra share the x vector.
 *
 * @param dets :: A list of detector IDs to sum.
 * @param x :: (output) Time of flight values (or whatever values the x axis has) to plot against.
 * @param y :: (output) The sums of the counts for each bin.
 */
void InstrumentActor::sumDetectorsUniform(QList<int>& dets, std::vector<double>&x, std::vector<double>&y) const
{

    size_t wi;
    bool isDataEmpty = dets.isEmpty();

    if ( !isDataEmpty )
    {
        try {
            wi = getWorkspaceIndex( dets[0] );
        } catch (Mantid::Kernel::Exception::NotFoundError &) {
            isDataEmpty = true; // Detector doesn't have a workspace index relating to it
        }
    }

    if ( isDataEmpty )
    {
        x.clear();
        y.clear();
        return;
    }

    // find the bins inside the integration range
    size_t imin,imax;
    getBinMinMaxIndex(wi,imin,imax);

    Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace();
    const Mantid::MantidVec& X = ws->readX(wi);
    x.assign(X.begin() + imin, X.begin() + imax);
    if ( ws->isHistogramData() )
    {
        // calculate the bin centres
        std::transform(x.begin(),x.end(),X.begin() + imin + 1,x.begin(),std::plus<double>());
        std::transform(x.begin(),x.end(),x.begin(),std::bind2nd(std::divides<double>(),2.0));
    }
    y.resize(x.size(),0);
    // sum the spectra
    foreach(int id, dets)
    {
        try {
            size_t index = getWorkspaceIndex( id );
            const Mantid::MantidVec& Y = ws->readY(index);
            std::transform(y.begin(),y.end(),Y.begin() + imin,y.begin(),std::plus<double>());
        } catch (Mantid::Kernel::Exception::NotFoundError &) {
            continue; // Detector doesn't have a workspace index relating to it
        }
    }
}
예제 #4
0
void InstrumentWindowPickTab::getBinMinMaxIndex(size_t wi,size_t& imin, size_t& imax)
{
  InstrumentActor* instrActor = m_instrWindow->getInstrumentActor();
  Mantid::API::MatrixWorkspace_const_sptr ws = instrActor->getWorkspace();
  const Mantid::MantidVec& x = ws->readX(wi);
  if (instrActor->wholeRange())
  {
    imin = 0;
    imax = x.size() - 1;
  }
  else
  {
    Mantid::MantidVec::const_iterator x_begin = std::lower_bound(x.begin(),x.end(),instrActor->minBinValue());
    Mantid::MantidVec::const_iterator x_end = std::lower_bound(x.begin(),x.end(),instrActor->maxBinValue());
    imin = static_cast<size_t>(x_begin - x.begin());
    imax = static_cast<size_t>(x_end - x.begin()) - 1;
  }
}
예제 #5
0
/**
 * Plot data for a detector.
 * @param detid :: ID of the detector to be plotted.
 */
void InstrumentWindowPickTab::plotSingle(int detid)
{
  m_plot->clearLabels();
  InstrumentActor* instrActor = m_instrWindow->getInstrumentActor();
  Mantid::API::MatrixWorkspace_const_sptr ws = instrActor->getWorkspace();
  size_t wi;
  try {
    wi = instrActor->getWorkspaceIndex(detid);
  } catch (Mantid::Kernel::Exception::NotFoundError) {
    return; // Detector doesn't have a workspace index relating to it
  }
  // get the data
  const Mantid::MantidVec& x = ws->readX(wi);
  const Mantid::MantidVec& y = ws->readY(wi);

  // find min and max for x
  size_t imin,imax;
  getBinMinMaxIndex(wi,imin,imax);

  Mantid::MantidVec::const_iterator y_begin = y.begin() + imin;
  Mantid::MantidVec::const_iterator y_end = y.begin() + imax;

  m_plot->setXScale(x[imin],x[imax]);

  // fins min and max for y
  Mantid::MantidVec::const_iterator min_it = std::min_element(y_begin,y_end);
  Mantid::MantidVec::const_iterator max_it = std::max_element(y_begin,y_end);
  // set the data 
  m_plot->setData(&x[0],&y[0],static_cast<int>(y.size()));
  m_plot->setYScale(*min_it,*max_it);

  // find any markers
  ProjectionSurface* surface = mInstrumentDisplay->getSurface();
  if (surface)
  {
    QList<PeakMarker2D*> markers = surface->getMarkersWithID(detid);
    foreach(PeakMarker2D* marker,markers)
    {
      m_plot->addLabel(new PeakLabel(marker));
      //std::cerr << marker->getLabel().toStdString() << std::endl;
    }
  }
예제 #6
0
/**
 * Find the offsets in the spectrum's x vector of the bounds of integration.
 * @param wi :: The works[ace index of the spectrum.
 * @param imin :: Index of the lower bound: x_min == readX(wi)[imin]
 * @param imax :: Index of the upper bound: x_max == readX(wi)[imax]
 */
void InstrumentActor::getBinMinMaxIndex( size_t wi, size_t& imin, size_t& imax ) const
{
    Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace();
    const Mantid::MantidVec& x = ws->readX(wi);
    Mantid::MantidVec::const_iterator x_begin = x.begin();
    Mantid::MantidVec::const_iterator x_end = x.end();
    if (x_begin == x_end)
    {
        throw std::runtime_error("No bins found to plot");
    }
    if (ws->isHistogramData())
    {
        --x_end;
    }
    if ( wholeRange() )
    {
        imin = 0;
        imax = static_cast<size_t>(x_end - x_begin);
    }
    else
    {
        Mantid::MantidVec::const_iterator x_from = std::lower_bound( x_begin, x_end, minBinValue() );
        Mantid::MantidVec::const_iterator x_to = std::upper_bound( x_begin, x_end, maxBinValue() );
        imin = static_cast<size_t>(x_from - x_begin);
        imax = static_cast<size_t>(x_to - x_begin);
        if (imax <= imin)
        {
            if (x_from == x_end)
            {
                --x_from;
                x_to = x_end;
            }
            else
            {
                x_to = x_from + 1;
            }
            imin = static_cast<size_t>(x_from - x_begin);
            imax = static_cast<size_t>(x_to - x_begin);
        }
    }
}
예제 #7
0
/**
 * Performs centre-point rebinning and produces an MDWorkspace
 * @param inputWs : The workspace you wish to perform centre-point rebinning on.
 * @param boxController : controls how the MDWorkspace will be split
 * @param frame: the md frame for the two MDHistoDimensions
 * @returns An MDWorkspace based on centre-point rebinning of the inputWS
 */
Mantid::API::IMDEventWorkspace_sptr ReflectometryTransform::executeMD(
    Mantid::API::MatrixWorkspace_const_sptr inputWs,
    BoxController_sptr boxController,
    Mantid::Geometry::MDFrame_uptr frame) const {
  auto dim0 = boost::make_shared<MDHistoDimension>(
      m_d0Label, m_d0ID, *frame, static_cast<Mantid::coord_t>(m_d0Min),
      static_cast<Mantid::coord_t>(m_d0Max), m_d0NumBins);
  auto dim1 = boost::make_shared<MDHistoDimension>(
      m_d1Label, m_d1ID, *frame, static_cast<Mantid::coord_t>(m_d1Min),
      static_cast<Mantid::coord_t>(m_d1Max), m_d1NumBins);

  auto ws = createMDWorkspace(dim0, dim1, boxController);

  auto spectraAxis = inputWs->getAxis(1);
  for (size_t index = 0; index < inputWs->getNumberHistograms(); ++index) {
    auto counts = inputWs->readY(index);
    auto wavelengths = inputWs->readX(index);
    auto errors = inputWs->readE(index);
    const size_t nInputBins = wavelengths.size() - 1;
    const double theta_final = spectraAxis->getValue(index);
    m_calculator->setThetaFinal(theta_final);
    // Loop over all bins in spectra
    for (size_t binIndex = 0; binIndex < nInputBins; ++binIndex) {
      const double &wavelength =
          0.5 * (wavelengths[binIndex] + wavelengths[binIndex + 1]);
      double _d0 = m_calculator->calculateDim0(wavelength);
      double _d1 = m_calculator->calculateDim1(wavelength);
      double centers[2] = {_d0, _d1};

      ws->addEvent(MDLeanEvent<2>(float(counts[binIndex]),
                                  float(errors[binIndex] * errors[binIndex]),
                                  centers));
    }
  }
  ws->splitAllIfNeeded(nullptr);
  ws->refreshCache();
  return ws;
}
예제 #8
0
/**
 * Sum counts in detectors for purposes of rough plotting against the units on the x-axis.
 * Assumes that all spectra have different x vectors.
 *
 * @param dets :: A list of detector IDs to sum.
 * @param x :: (output) Time of flight values (or whatever values the x axis has) to plot against.
 * @param y :: (output) The sums of the counts for each bin.
 * @param size :: (input) Size of the output vectors.
 */
void InstrumentActor::sumDetectorsRagged(QList<int> &dets, std::vector<double> &x, std::vector<double> &y, size_t size) const
{
    if ( dets.isEmpty() || size == 0 )
    {
        x.clear();
        y.clear();
        return;
    }

    Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace();
    //  create a workspace to hold the data from the selected detectors
    Mantid::API::MatrixWorkspace_sptr dws = Mantid::API::WorkspaceFactory::Instance().create(ws,dets.size());

    // x-axis limits
    double xStart = maxBinValue();
    double xEnd = minBinValue();

    size_t nSpec = 0; // number of actual spectra to add
    // fill in the temp workspace with the data from the detectors
    foreach(int id, dets)
    {
        try {
            size_t index = getWorkspaceIndex( id );
            dws->dataX(nSpec) = ws->readX(index);
            dws->dataY(nSpec) = ws->readY(index);
            dws->dataE(nSpec) = ws->readE(index);
            double xmin = dws->readX(nSpec).front();
            double xmax = dws->readX(nSpec).back();
            if ( xmin < xStart )
            {
                xStart = xmin;
            }
            if ( xmax > xEnd )
            {
                xEnd = xmax;
            }
            ++nSpec;
        } catch (Mantid::Kernel::Exception::NotFoundError &) {
            continue; // Detector doesn't have a workspace index relating to it
        }
    }

    if ( nSpec == 0 )
    {
        x.clear();
        y.clear();
        return;
    }

    // limits should exceed the integration range
    if ( xStart < minBinValue() )
    {
        xStart = minBinValue();
    }

    if ( xEnd > maxBinValue() )
    {
        xEnd = maxBinValue();
    }

    double dx = (xEnd - xStart) / static_cast<double>(size - 1);
    std::string params = QString("%1,%2,%3").arg(xStart).arg(dx).arg(xEnd).toStdString();
    std::string outName = "_TMP_sumDetectorsRagged";

    try
    {
        // rebin all spectra to the same binning
        Mantid::API::IAlgorithm * alg = Mantid::API::FrameworkManager::Instance().createAlgorithm("Rebin",-1);
        alg->setProperty( "InputWorkspace", dws );
        alg->setPropertyValue( "OutputWorkspace", outName );
        alg->setPropertyValue( "Params", params );
        alg->execute();

        ws = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(Mantid::API::AnalysisDataService::Instance().retrieve(outName));
        Mantid::API::AnalysisDataService::Instance().remove( outName );

        x = ws->readX(0);
        y = ws->readY(0);
        // add the spectra
        for(size_t i = 0; i < nSpec; ++i)
        {
            const Mantid::MantidVec& Y = ws->readY(i);
            std::transform( y.begin(), y.end(), Y.begin(), y.begin(), std::plus<double>() );
        }
    }
    catch(std::invalid_argument&)
    {
        // wrong Params for any reason
        x.resize(size,(xEnd + xStart)/2);
        y.resize(size,0.0);
    }

}