/*
    Execute the transformtion. Generates an output IMDEventWorkspace.
    @return the constructed IMDEventWorkspace following the transformation.
    @param ws: Input MatrixWorkspace const shared pointer
    */
    IMDEventWorkspace_sptr ReflectometryTransformQxQz::execute(MatrixWorkspace_const_sptr inputWs) const
    {
      const size_t nbinsx = 10;
      const size_t nbinsz = 10;

      auto ws = boost::make_shared<MDEventWorkspace<MDLeanEvent<2>,2> >();
      MDHistoDimension_sptr qxDim = MDHistoDimension_sptr(new MDHistoDimension("Qx","qx","(Ang^-1)", static_cast<Mantid::coord_t>(m_qxMin), static_cast<Mantid::coord_t>(m_qxMax), nbinsx)); 
      MDHistoDimension_sptr qzDim = MDHistoDimension_sptr(new MDHistoDimension("Qz","qz","(Ang^-1)", static_cast<Mantid::coord_t>(m_qzMin), static_cast<Mantid::coord_t>(m_qzMax), nbinsz)); 

      ws->addDimension(qxDim);
      ws->addDimension(qzDim);

      // Set some reasonable values for the box controller
      BoxController_sptr bc = ws->getBoxController();
      bc->setSplitInto(2);
      bc->setSplitThreshold(10);

      // Initialize the workspace.
      ws->initialize();

      // Start with a MDGridBox.
      ws->splitBox();

      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_QxCalculation.setThetaFinal(theta_final);
        m_QzCalculation.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 _qx = m_QxCalculation.execute(wavelength);
          double _qz = m_QzCalculation.execute(wavelength);
          double centers[2] = {_qx, _qz};

          ws->addEvent(MDLeanEvent<2>(float(counts[binIndex]), float(errors[binIndex]*errors[binIndex]), centers));
        }
        ws->splitAllIfNeeded(NULL);
      }
      return ws;
    }
Example #2
0
boost::optional<int> findRecursionDepthForTopLevelSplitting(
    const std::string &workspaceName,
    std::unique_ptr<WorkspaceProvider> workspaceProvider) {
  const int topLevelRecursionDepth = 1;
  boost::optional<int> recursionDepth;
  if (workspaceProvider->canProvideWorkspace(workspaceName)) {
    auto workspace =
        boost::dynamic_pointer_cast<Mantid::API::IMDEventWorkspace>(
            workspaceProvider->fetchWorkspace(workspaceName));
    auto boxController = workspace->getBoxController();
    boost::optional<std::vector<size_t>> topLevelSplits =
        boxController->getSplitTopInto();
    if (boxController->getSplitTopInto()) {
      recursionDepth = topLevelRecursionDepth;
    }
  }
  return recursionDepth;
}
/**
 * Creates an MD workspace
 * @param a : pointer to the first dimension of the MDWorkspace
  *@param b : pointer to the second dimension of the MDWorkspace
 * @param boxController : controls how the MDWorkspace will be split
 */
boost::shared_ptr<MDEventWorkspace2Lean>
ReflectometryTransform::createMDWorkspace(
    Mantid::Geometry::IMDDimension_sptr a,
    Mantid::Geometry::IMDDimension_sptr b,
    BoxController_sptr boxController) const {
  auto ws = boost::make_shared<MDEventWorkspace2Lean>();

  ws->addDimension(a);
  ws->addDimension(b);

  BoxController_sptr wsbc = ws->getBoxController(); // Get the box controller
  wsbc->setSplitInto(boxController->getSplitInto(0));
  wsbc->setMaxDepth(boxController->getMaxDepth());
  wsbc->setSplitThreshold(boxController->getSplitThreshold());

  // Initialize the workspace.
  ws->initialize();

  // Start with a MDGridBox.
  ws->splitBox();
  return ws;
}
Example #4
0
/**
 * Create an output event workspace filled with data simulated with the fitting
 * function.
 * @param baseName :: The base name for the workspace
 * @param inputWorkspace :: The input workspace.
 * @param values :: The calculated values
 * @param outputWorkspacePropertyName :: The property name
 */
boost::shared_ptr<API::Workspace> FitMD::createEventOutputWorkspace(
    const std::string &baseName, const API::IMDEventWorkspace &inputWorkspace,
    const API::FunctionValues &values,
    const std::string &outputWorkspacePropertyName) {
  auto outputWS =
      MDEventFactory::CreateMDWorkspace(inputWorkspace.getNumDims(), "MDEvent");
  // Add events
  // TODO: Generalize to ND (the current framework is a bit limiting)
  auto mdWS = boost::dynamic_pointer_cast<
      DataObjects::MDEventWorkspace<DataObjects::MDEvent<4>, 4>>(outputWS);
  if (!mdWS) {
    return boost::shared_ptr<API::Workspace>();
  }

  // Bins extents and meta data
  for (size_t i = 0; i < 4; ++i) {
    boost::shared_ptr<const Geometry::IMDDimension> inputDim =
        inputWorkspace.getDimension(i);
    Geometry::MDHistoDimensionBuilder builder;
    builder.setName(inputDim->getName());
    builder.setId(inputDim->getDimensionId());
    builder.setUnits(inputDim->getUnits());
    builder.setNumBins(inputDim->getNBins());
    builder.setMin(inputDim->getMinimum());
    builder.setMax(inputDim->getMaximum());
    builder.setFrameName(inputDim->getMDFrame().name());

    outputWS->addDimension(builder.create());
  }

  // Run information
  outputWS->copyExperimentInfos(inputWorkspace);
  // Coordinates
  outputWS->setCoordinateSystem(inputWorkspace.getSpecialCoordinateSystem());
  // Set sensible defaults for splitting behaviour
  BoxController_sptr bc = outputWS->getBoxController();
  bc->setSplitInto(3);
  bc->setSplitThreshold(3000);
  outputWS->initialize();
  outputWS->splitBox();

  auto inputIter = inputWorkspace.createIterator();
  size_t resultValueIndex(0);
  const float errorSq = 0.0;
  do {
    const size_t numEvents = inputIter->getNumEvents();
    const float signal =
        static_cast<float>(values.getCalculated(resultValueIndex));
    for (size_t i = 0; i < numEvents; ++i) {
      coord_t centers[4] = {
          inputIter->getInnerPosition(i, 0), inputIter->getInnerPosition(i, 1),
          inputIter->getInnerPosition(i, 2), inputIter->getInnerPosition(i, 3)};
      mdWS->addEvent(MDEvent<4>(signal, errorSq, inputIter->getInnerRunIndex(i),
                                inputIter->getInnerDetectorID(i), centers));
    }
    ++resultValueIndex;
  } while (inputIter->next());
  delete inputIter;

  // This splits up all the boxes according to split thresholds and sizes.
  auto threadScheduler = new Kernel::ThreadSchedulerFIFO();
  Kernel::ThreadPool threadPool(threadScheduler);
  outputWS->splitAllIfNeeded(threadScheduler);
  threadPool.joinAll();
  outputWS->refreshCache();

  // Store it
  if (!outputWorkspacePropertyName.empty()) {
    declareProperty(
        new API::WorkspaceProperty<API::IMDEventWorkspace>(
            outputWorkspacePropertyName, "", Direction::Output),
        "Name of the output Workspace holding resulting simulated spectrum");
    m_manager->setPropertyValue(outputWorkspacePropertyName,
                                baseName + "Workspace");
    m_manager->setProperty(outputWorkspacePropertyName, outputWS);
  }

  return outputWS;
}