Example #1
0
/** Execute the algorithm.
 */
void TransformMD::exec() {
  Mantid::API::IMDWorkspace_sptr inWS;
  Mantid::API::IMDWorkspace_sptr outWS;

  inWS = getProperty("InputWorkspace");
  outWS = getProperty("OutputWorkspace");

  if (boost::dynamic_pointer_cast<MatrixWorkspace>(inWS))
    throw std::runtime_error("TransformMD can only transform a "
                             "MDHistoWorkspace or a MDEventWorkspace.");

  if (outWS != inWS) {
    // NOT in-place. So first we clone inWS into outWS
    IAlgorithm_sptr clone =
        this->createChildAlgorithm("CloneMDWorkspace", 0.0, 0.5, true);
    clone->setProperty("InputWorkspace", inWS);
    clone->executeAsChildAlg();
    outWS = clone->getProperty("OutputWorkspace");
  }

  if (!outWS)
    throw std::runtime_error("Invalid output workspace.");

  size_t nd = outWS->getNumDims();
  m_scaling = getProperty("Scaling");
  m_offset = getProperty("Offset");

  // Replicate single values
  if (m_scaling.size() == 1)
    m_scaling = std::vector<double>(nd, m_scaling[0]);
  if (m_offset.size() == 1)
    m_offset = std::vector<double>(nd, m_offset[0]);

  // Check the size
  if (m_scaling.size() != nd)
    throw std::invalid_argument("Scaling argument must be either length 1 or "
                                "match the number of dimensions.");
  if (m_offset.size() != nd)
    throw std::invalid_argument("Offset argument must be either length 1 or "
                                "match the number of dimensions.");

  // Transform the dimensions
  outWS->transformDimensions(m_scaling, m_offset);

  MDHistoWorkspace_sptr histo =
      boost::dynamic_pointer_cast<MDHistoWorkspace>(outWS);
  IMDEventWorkspace_sptr event =
      boost::dynamic_pointer_cast<IMDEventWorkspace>(outWS);

  if (histo) {
    // Recalculate all the values since the dimensions changed.
    histo->cacheValues();
  } else if (event) {
    // Call the method for this type of MDEventWorkspace.
    CALL_MDEVENT_FUNCTION(this->doTransform, outWS);
  }

  this->setProperty("OutputWorkspace", outWS);
}
Example #2
0
/**
Free helper function.
try to fetch the workspace index.
@param ws : The workspace to find the dimensions in
@param candidateNameOrId: Either the name or the id of a dimension in the
workspace.
@return the index of the dimension in the workspace.
@throws runtime_error if the requested dimension is unknown either by id, or by
name in the workspace.
*/
size_t tryFetchDimensionIndex(Mantid::API::IMDWorkspace_sptr ws,
                              const std::string &candidateNameOrId) {
  size_t dimWorkspaceIndex;
  try {
    dimWorkspaceIndex = ws->getDimensionIndexById(candidateNameOrId);
  } catch (const std::runtime_error &) {
    // this will throw if the name is unknown.
    dimWorkspaceIndex = ws->getDimensionIndexByName(candidateNameOrId);
  }
  return dimWorkspaceIndex;
}
    /**
     * Set the minimum and maximum of the workspace data. Code essentially copied from SignalRange.cpp
     * @param workspace Rreference to an IMD workspace
     * @returns The minimum and maximum value of the workspace dataset.
     */
    QwtDoubleInterval MetaDataExtractorUtils::getMinAndMax(Mantid::API::IMDWorkspace_sptr workspace)
    {
      if (!workspace)
        throw std::invalid_argument("The workspace is empty.");

      auto iterators = workspace->createIterators(PARALLEL_GET_MAX_THREADS, 0);

      std::vector<QwtDoubleInterval> intervals(iterators.size());
      // cppcheck-suppress syntaxError
      PRAGMA_OMP( parallel for schedule(dynamic, 1))
      for (int i=0; i < int(iterators.size()); i++)
      {
        Mantid::API::IMDIterator * it = iterators[i];

        QwtDoubleInterval range = this->getRange(it);
        intervals[i] = range;
        // don't delete iterator in parallel. MSVC doesn't like it
        // when the iterator points to a mock object.
      }

      // Combine the overall min/max
      double minSignal = DBL_MAX;
      double maxSignal = -DBL_MAX;

      auto inf = std::numeric_limits<double>::infinity();
      for (size_t i=0; i < iterators.size(); i++)
      {
        delete iterators[i];
        
        double signal;
        signal = intervals[i].minValue();
        if (signal != inf && signal < minSignal) minSignal = signal;

        signal = intervals[i].maxValue();
        if (signal != inf && signal > maxSignal) maxSignal = signal;
      }

      // Set the lowest element to the smallest non-zero element.
      if (minSignal == DBL_MAX)
      {
        minSignal = defaultMin;
        maxSignal = defaultMax;
      } 

      QwtDoubleInterval minMaxContainer;

      if (minSignal < maxSignal)
        minMaxContainer = QwtDoubleInterval(minSignal, maxSignal);
      else
      {
        if (minSignal != 0)
          // Possibly only one value in range
          minMaxContainer = QwtDoubleInterval(minSignal*0.5, minSignal*1.5);
        else
          // Other default value
          minMaxContainer = QwtDoubleInterval(defaultMin, defaultMax);
      }

      return minMaxContainer;
    }
Example #4
0
/** Set the workspace being sliced
 *
 * @param ws :: IMDWorkspace */
void LineViewer::setWorkspace(Mantid::API::IMDWorkspace_sptr ws)
{
  m_ws = ws;
  m_thickness = VMD(ws->getNumDims());
  createDimensionWidgets();
  // Update the dimensions shown in the original workspace
  m_lineOptions->setOriginalWorkspace(m_ws);
}
Example #5
0
/** Set the original workspace, to show the axes plot choice */
void LinePlotOptions::setOriginalWorkspace(Mantid::API::IMDWorkspace_sptr ws) {
  if (!ws)
    return;

  for (size_t d = 0; d < (ws->getNumDims()); d++) {
    IMDDimension_const_sptr dim = ws->getDimension(d);
    std::string text = dim->getName();
    std::string tooltip =
        "Use the " + dim->getName() + " dimension as the X plot axis.";
    const bool bIntegrated = dim->getIsIntegrated();
    // Index into the radio buttons array
    int index = int(d) + 2;
    if (m_radPlots.size() > index) {
      m_radPlots[index]->setText(QString::fromStdString(text));
      m_radPlots[index]->setToolTip(QString::fromStdString(tooltip));
    } else
      addPlotRadioButton(text, tooltip, bIntegrated);
  }
}
Example #6
0
/**
 * Check the inputs for invalid values
 * @returns A map with validation warnings.
 */
std::map<std::string, std::string> SetMDFrame::validateInputs() {
  std::map<std::string, std::string> invalidProperties;
  Mantid::API::IMDWorkspace_sptr ws = getProperty("InputWorkspace");

  if (!boost::dynamic_pointer_cast<Mantid::API::IMDEventWorkspace>(ws) &&
      !boost::dynamic_pointer_cast<Mantid::API::IMDHistoWorkspace>(ws)) {
    invalidProperties.insert(
        std::make_pair("InputWorkspace", "The input workspace has to be either "
                                         "an MDEvent or MDHisto Workspace."));
  }

  std::vector<int> axesInts = this->getProperty("Axes");
  Kernel::MDAxisValidator axisChecker(axesInts, ws->getNumDims(), true);
  auto axisErrors = axisChecker.validate();
  for (auto iter = axisErrors.begin(); iter != axisErrors.end(); iter++) {
    invalidProperties.insert(*iter);
  }

  return invalidProperties;
}
Example #7
0
/** Compare the dimensions etc. of two MDWorkspaces
*/
void CompareMDWorkspaces::compareMDGeometry(
    Mantid::API::IMDWorkspace_sptr ws1, Mantid::API::IMDWorkspace_sptr ws2) {
  compare(ws1->getNumDims(), ws2->getNumDims(),
          "Workspaces have a different number of dimensions");
  for (size_t d = 0; d < ws1->getNumDims(); d++) {
    IMDDimension_const_sptr dim1 = ws1->getDimension(d);
    IMDDimension_const_sptr dim2 = ws2->getDimension(d);
    compare(dim1->getName(), dim2->getName(),
            "Dimension #" + Strings::toString(d) + " has a different name");
    compare(dim1->getUnits(), dim2->getUnits(),
            "Dimension #" + Strings::toString(d) + " has different units");
    compare(dim1->getNBins(), dim2->getNBins(),
            "Dimension #" + Strings::toString(d) +
                " has a different number of bins");
    compareTol(dim1->getMinimum(), dim2->getMinimum(),
               "Dimension #" + Strings::toString(d) +
                   " has a different minimum");
    compareTol(dim1->getMaximum(), dim2->getMaximum(),
               "Dimension #" + Strings::toString(d) +
                   " has a different maximum");
  }
}
Example #8
0
/** Execute the algorithm.
 */
void TransformMD::exec() {
  Mantid::API::IMDWorkspace_sptr inWS;
  Mantid::API::IMDWorkspace_sptr outWS;

  inWS = getProperty("InputWorkspace");
  outWS = getProperty("OutputWorkspace");
  std::string outName = getPropertyValue("OutputWorkspace");

  if (boost::dynamic_pointer_cast<MatrixWorkspace>(inWS))
    throw std::runtime_error("TransformMD can only transform a "
                             "MDHistoWorkspace or a MDEventWorkspace.");

  if (outWS != inWS) {
    // NOT in-place. So first we clone inWS into outWS
    IAlgorithm_sptr clone =
        this->createChildAlgorithm("CloneMDWorkspace", 0.0, 0.5, true);
    clone->setProperty("InputWorkspace", inWS);
    clone->executeAsChildAlg();
    outWS = clone->getProperty("OutputWorkspace");
  }

  if (!outWS)
    throw std::runtime_error("Invalid output workspace.");

  size_t nd = outWS->getNumDims();
  m_scaling = getProperty("Scaling");
  m_offset = getProperty("Offset");

  // Replicate single values
  if (m_scaling.size() == 1)
    m_scaling = std::vector<double>(nd, m_scaling[0]);
  if (m_offset.size() == 1)
    m_offset = std::vector<double>(nd, m_offset[0]);

  // Check the size
  if (m_scaling.size() != nd)
    throw std::invalid_argument("Scaling argument must be either length 1 or "
                                "match the number of dimensions.");
  if (m_offset.size() != nd)
    throw std::invalid_argument("Offset argument must be either length 1 or "
                                "match the number of dimensions.");

  // Transform the dimensions
  outWS->transformDimensions(m_scaling, m_offset);

  MDHistoWorkspace_sptr histo =
      boost::dynamic_pointer_cast<MDHistoWorkspace>(outWS);
  IMDEventWorkspace_sptr event =
      boost::dynamic_pointer_cast<IMDEventWorkspace>(outWS);

  if (histo) {
    // Recalculate all the values since the dimensions changed.
    histo->cacheValues();
    // Expect first 3 dimensions to be -1 for changing conventions
    for (int i = 0; i < static_cast<int>(m_scaling.size()); i++)
      if (m_scaling[i] < 0) {
        std::vector<int> axes(m_scaling.size());        // vector with ints.
        std::iota(std::begin(axes), std::end(axes), 0); // Fill with 0, 1, ...
        axes[0] = i;
        axes[i] = 0;
        if (i > 0)
          histo = transposeMD(histo, axes);
        signal_t *signals = histo->getSignalArray();
        signal_t *errorsSq = histo->getErrorSquaredArray();
        signal_t *numEvents = histo->getNumEventsArray();

        // Find the extents
        size_t nPoints =
            static_cast<size_t>(histo->getDimension(0)->getNBins());
        size_t mPoints = 1;
        for (size_t k = 1; k < histo->getNumDims(); k++) {
          mPoints *= static_cast<size_t>(histo->getDimension(k)->getNBins());
        }
        // other dimensions
        for (size_t j = 0; j < mPoints; j++) {
          this->reverse(signals + j * nPoints, nPoints);
          this->reverse(errorsSq + j * nPoints, nPoints);
          this->reverse(numEvents + j * nPoints, nPoints);
        }

        histo = transposeMD(histo, axes);
      }

    // Pass on the display normalization from the input workspace
    histo->setDisplayNormalization(inWS->displayNormalizationHisto());

    this->setProperty("OutputWorkspace", histo);
  } else if (event) {
    // Call the method for this type of MDEventWorkspace.
    CALL_MDEVENT_FUNCTION(this->doTransform, outWS);
    Progress *prog2 = nullptr;
    ThreadScheduler *ts = new ThreadSchedulerFIFO();
    ThreadPool tp(ts, 0, prog2);
    event->splitAllIfNeeded(ts);
    // prog2->resetNumSteps( ts->size(), 0.4, 0.6);
    tp.joinAll();
    event->refreshCache();
    // Set the special coordinate system.
    IMDEventWorkspace_sptr inEvent =
        boost::dynamic_pointer_cast<IMDEventWorkspace>(inWS);
    event->setCoordinateSystem(inEvent->getSpecialCoordinateSystem());

    if (m_scaling[0] < 0) {
      // Only need these 2 algorithms for transforming with negative number
      std::vector<double> extents;
      std::vector<std::string> names, units;
      for (size_t d = 0; d < nd; d++) {
        Geometry::IMDDimension_const_sptr dim = event->getDimension(d);
        // Find the extents
        extents.push_back(dim->getMinimum());
        extents.push_back(dim->getMaximum());
        names.push_back(std::string(dim->getName()));
        units.push_back(dim->getUnits());
      }
      Algorithm_sptr create_alg = createChildAlgorithm("CreateMDWorkspace");
      create_alg->setProperty("Dimensions", static_cast<int>(nd));
      create_alg->setProperty("EventType", event->getEventTypeName());
      create_alg->setProperty("Extents", extents);
      create_alg->setProperty("Names", names);
      create_alg->setProperty("Units", units);
      create_alg->setPropertyValue("OutputWorkspace", "__none");
      create_alg->executeAsChildAlg();
      Workspace_sptr none = create_alg->getProperty("OutputWorkspace");

      AnalysisDataService::Instance().addOrReplace(outName, event);
      AnalysisDataService::Instance().addOrReplace("__none", none);
      Mantid::API::BoxController_sptr boxController = event->getBoxController();
      std::vector<int> splits;
      for (size_t d = 0; d < nd; d++) {
        splits.push_back(static_cast<int>(boxController->getSplitInto(d)));
      }
      Algorithm_sptr merge_alg = createChildAlgorithm("MergeMD");
      merge_alg->setPropertyValue("InputWorkspaces", outName + ",__none");
      merge_alg->setProperty("SplitInto", splits);
      merge_alg->setProperty(
          "SplitThreshold",
          static_cast<int>(boxController->getSplitThreshold()));
      merge_alg->setProperty("MaxRecursionDepth", 13);
      merge_alg->executeAsChildAlg();
      event = merge_alg->getProperty("OutputWorkspace");
      AnalysisDataService::Instance().remove("__none");
    }
    this->setProperty("OutputWorkspace", event);
  }
}