Beispiel #1
0
GeometryInfoFactory::GeometryInfoFactory(const MatrixWorkspace &workspace)
    : m_workspace(workspace), m_instrument(workspace.getInstrument()) {
  // Note: This does not seem possible currently (the instrument objects is
  // always allocated, even if it is empty), so this will not fail.
  if (!m_instrument)
    throw std::runtime_error("Workspace " + workspace.getName() +
                             " does not contain an instrument!");
}
/** Calculate smoothing of the data using the spline
 * Wraps CubicSpline function1D
 *
 * @param inputWorkspace :: The input workspace
 * @param outputWorkspace :: The output workspace
 * @param row :: The row of spectra to use
 */
void SplineSmoothing::calculateSmoothing(const MatrixWorkspace &inputWorkspace,
        MatrixWorkspace &outputWorkspace,
        size_t row) const {
    // define the spline's parameters
    const auto &xIn = inputWorkspace.x(row);
    const size_t nData = xIn.size();
    const double *xValues = &(xIn[0]);
    double *yValues = &(outputWorkspace.mutableY(row)[0]);

    // calculate the smoothing
    m_cspline->function1D(yValues, xValues, nData);
}
MatrixWorkspace_sptr MonteCarloAbsorption::createOutputWorkspace(
    const MatrixWorkspace &inputWS) const {
  MatrixWorkspace_sptr outputWS = inputWS.clone();
  // The algorithm computes the signal values at bin centres so they should
  // be treated as a distribution
  outputWS->setDistribution(true);
  outputWS->setYUnit("");
  outputWS->setYUnitLabel("Attenuation factor");
  return outputWS;
}
/** Calculate the derivatives of the newly smoothed data using the spline
 * Wraps CubicSpline derivative1D
 *
 * @param inputWorkspace :: The input workspace
 * @param outputWorkspace :: The output workspace
 * @param order :: The order of derivatives to calculate
 * @param row :: The row of spectra to use
 */
void SplineSmoothing::calculateDerivatives(
    const MatrixWorkspace &inputWorkspace,
    API::MatrixWorkspace &outputWorkspace, const int order,
    const size_t row) const {
    const auto &xIn = inputWorkspace.x(row);
    const double *xValues = &(xIn[0]);
    double *yValues = &(outputWorkspace.mutableY(order - 1)[0]);
    const size_t nData = xIn.size();

    m_cspline->derivative1D(yValues, xValues, nData, order);
}
/**
 * Get log value from a workspace. Convert to double if possible.
 *
 * @param ws :: [Input] The input workspace.
 * @return :: Log value.
 * @throw :: std::invalid_argument if the log cannot be converted to a double or
 *doesn't exist.
 */
double PlotAsymmetryByLogValue::getLogValue(MatrixWorkspace &ws) {

  const Run &run = ws.run();

  // Get the start & end time for the run
  Mantid::Kernel::DateAndTime start, end;
  if (run.hasProperty("run_start") && run.hasProperty("run_end")) {
    start = run.getProperty("run_start")->value();
    end = run.getProperty("run_end")->value();
  }

  auto *property = run.getLogData(m_logName);
  if (!property) {
    throw std::invalid_argument("Log " + m_logName + " does not exist.");
  }
  property->filterByTime(start, end);

  double value = 0;
  // try different property types
  if (convertLogToDouble<double>(property, value, m_logFunc))
    return value;
  if (convertLogToDouble<float>(property, value, m_logFunc))
    return value;
  if (convertLogToDouble<int>(property, value, m_logFunc))
    return value;
  if (convertLogToDouble<long>(property, value, m_logFunc))
    return value;
  if (convertLogToDouble<long long>(property, value, m_logFunc))
    return value;
  if (convertLogToDouble<unsigned int>(property, value, m_logFunc))
    return value;
  if (convertLogToDouble<unsigned long>(property, value, m_logFunc))
    return value;
  if (convertLogToDouble<unsigned long long>(property, value, m_logFunc))
    return value;
  // try if it's a string and can be lexically cast to double
  auto slog =
      dynamic_cast<const Mantid::Kernel::PropertyWithValue<std::string> *>(
          property);
  if (slog) {
    try {
      value = boost::lexical_cast<double>(slog->value());
      return value;
    } catch (std::exception &) {
      // do nothing, goto throw
    }
  }

  throw std::invalid_argument("Log " + m_logName +
                              " cannot be converted to a double type.");
}
/**
 * Fully masks one component named componentName
 * @param ws :: workspace with the respective instrument assigned
 * @param componentName :: must be a known CompAssembly.
 */
void CalculateEfficiency::maskComponent(MatrixWorkspace &ws,
                                        const std::string &componentName) {
  auto instrument = ws.getInstrument();
  try {
    boost::shared_ptr<const Geometry::ICompAssembly> component =
        boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(
            instrument->getComponentByName(componentName));
    if (!component) {
      g_log.warning("Component " + componentName +
                    " expected to be a CompAssembly, e.g., a bank. Component " +
                    componentName + " not masked!");
      return;
    }
    std::vector<detid_t> detectorList;
    for (int x = 0; x < component->nelements(); x++) {
      boost::shared_ptr<Geometry::ICompAssembly> xColumn =
          boost::dynamic_pointer_cast<Geometry::ICompAssembly>((*component)[x]);
      for (int y = 0; y < xColumn->nelements(); y++) {
        boost::shared_ptr<Geometry::Detector> detector =
            boost::dynamic_pointer_cast<Geometry::Detector>((*xColumn)[y]);
        if (detector) {
          auto detID = detector->getID();
          detectorList.push_back(detID);
        }
      }
    }
    auto indexList = ws.getIndicesFromDetectorIDs(detectorList);
    auto &spectrumInfo = ws.mutableSpectrumInfo();
    for (const auto &idx : indexList) {
      ws.getSpectrum(idx).clearData();
      spectrumInfo.setMasked(idx, true);
    }
  } catch (std::exception &) {
    g_log.warning("Expecting the component " + componentName +
                  " to be a CompAssembly, e.g., a bank. Component not masked!");
  }
}
Beispiel #7
0
/**
 * Checks if the spectra at the given index of either input workspace is masked.
 * If so then the output spectra has zeroed data
 * and is also masked.
 * @param lhsSpectrumInfo :: The LHS spectrum info object
 * @param rhsSpectrumInfo :: The RHS spectrum info object
 * @param index :: The workspace index to check
 * @param out :: A pointer to the output workspace
 * @param outSpectrumInfo :: The spectrum info object of `out`
 * @returns True if further processing is not required on the spectra, false if
 * the binary operation should be performed.
 */
bool BinaryOperation::propagateSpectraMask(const SpectrumInfo &lhsSpectrumInfo,
                                           const SpectrumInfo &rhsSpectrumInfo,
                                           const int64_t index,
                                           MatrixWorkspace &out,
                                           SpectrumInfo &outSpectrumInfo) {
  bool continueOp(true);

  if ((lhsSpectrumInfo.hasDetectors(index) &&
       lhsSpectrumInfo.isMasked(index)) ||
      (rhsSpectrumInfo.hasDetectors(index) &&
       rhsSpectrumInfo.isMasked(index))) {
    continueOp = false;
    out.getSpectrum(index).clearData();
    PARALLEL_CRITICAL(setMasked) { outSpectrumInfo.setMasked(index, true); }
  }
void addFullInstrumentToWorkspace(MatrixWorkspace &workspace,
                                  bool includeMonitors, bool startYNegative,
                                  const std::string &instrumentName) {
  auto instrument = boost::make_shared<Instrument>(instrumentName);
  instrument->setReferenceFrame(
      boost::make_shared<ReferenceFrame>(Y, Z, Right, ""));
  workspace.setInstrument(instrument);

  const double pixelRadius(0.05);
  Object_sptr pixelShape = ComponentCreationHelper::createCappedCylinder(
      pixelRadius, 0.02, V3D(0.0, 0.0, 0.0), V3D(0., 1.0, 0.), "tube");

  const double detZPos(5.0);
  // Careful! Do not use size_t or auto, the unisgned will break the -=2 below.
  int ndets = static_cast<int>(workspace.getNumberHistograms());
  if (includeMonitors)
    ndets -= 2;
  for (int i = 0; i < ndets; ++i) {
    std::ostringstream lexer;
    lexer << "pixel-" << i << ")";
    Detector *physicalPixel =
        new Detector(lexer.str(), workspace.getAxis(1)->spectraNo(i),
                     pixelShape, instrument.get());
    int ycount(i);
    if (startYNegative)
      ycount -= 1;
    const double ypos = ycount * 2.0 * pixelRadius;
    physicalPixel->setPos(0.0, ypos, detZPos);
    instrument->add(physicalPixel);
    instrument->markAsDetector(physicalPixel);
    workspace.getSpectrum(i).setDetectorID(physicalPixel->getID());
  }

  // Monitors last
  if (includeMonitors) // These occupy the last 2 spectra
  {
    Detector *monitor1 =
        new Detector("mon1", workspace.getAxis(1)->spectraNo(ndets),
                     Object_sptr(), instrument.get());
    monitor1->setPos(0.0, 0.0, -9.0);
    instrument->add(monitor1);
    instrument->markAsMonitor(monitor1);
    workspace.getSpectrum(ndets).setDetectorID(ndets + 1);

    Detector *monitor2 =
        new Detector("mon2", workspace.getAxis(1)->spectraNo(ndets) + 1,
                     Object_sptr(), instrument.get());
    monitor2->setPos(0.0, 0.0, -2.0);
    instrument->add(monitor2);
    instrument->markAsMonitor(monitor2);
    workspace.getSpectrum(ndets + 1).setDetectorID(ndets + 2);
  }

  // Define a source and sample position
  // Define a source component
  ObjComponent *source = new ObjComponent(
      "moderator",
      ComponentCreationHelper::createSphere(0.1, V3D(0, 0, 0), "1"),
      instrument.get());
  source->setPos(V3D(0.0, 0.0, -20.0));
  instrument->add(source);
  instrument->markAsSource(source);

  // Define a sample as a simple sphere
  ObjComponent *sample = new ObjComponent(
      "samplePos",
      ComponentCreationHelper::createSphere(0.1, V3D(0, 0, 0), "1"),
      instrument.get());
  instrument->setPos(0.0, 0.0, 0.0);
  instrument->add(sample);
  instrument->markAsSamplePos(sample);
  // chopper position
  Component *chop_pos = new Component("chopper-position",
                                      Kernel::V3D(0, 0, -10), instrument.get());
  instrument->add(chop_pos);
}
/** Defines the points used to make the spline by iteratively creating more
 *smoothing points
 * until all smoothing points fall within a certain error tolerance
 *
 * @param inputWorkspace :: The input workspace containing noisy data
 * @param row :: The row of spectra to use
 */
void SplineSmoothing::selectSmoothingPoints(
    const MatrixWorkspace &inputWorkspace, const size_t row) {
    std::set<int> smoothPts;
    const auto &xs = inputWorkspace.x(row);
    const auto &ys = inputWorkspace.y(row);

    // retrieving number of breaks
    int maxBreaks = static_cast<int>(getProperty("MaxNumberOfBreaks"));

    int xSize = static_cast<int>(xs.size());

    // evenly space initial points over data set
    int delta;

    // if retrieved value is default zero/default
    bool incBreaks = false;

    if (maxBreaks != 0) {
        // number of points to start with
        int numSmoothPts(maxBreaks);
        delta = xSize / numSmoothPts;
        // include maxBreaks when != 0
        incBreaks = true;
    } else {
        int numSmoothPts(M_START_SMOOTH_POINTS);
        delta = xSize / numSmoothPts;
    }

    for (int i = 0; i < xSize; i += delta) {
        smoothPts.insert(i);
    }
    smoothPts.insert(xSize - 1);

    bool resmooth(true);
    while (resmooth) {

        if (incBreaks) {
            if (smoothPts.size() > static_cast<unsigned>(maxBreaks + 2)) {
                break;
            }

        } else if (!incBreaks) {
            if (smoothPts.size() >= xs.size() - 1) {
                break;
            }
        }

        addSmoothingPoints(smoothPts, &xs[0], &ys[0]);
        resmooth = false;

        // calculate the spline and retrieve smoothed points
        boost::shared_array<double> ysmooth(new double[xSize]);
        m_cspline->function1D(ysmooth.get(), &xs[0], xSize);

        // iterate over smoothing points
        auto iter = smoothPts.cbegin();
        int start = *iter;

        for (++iter; iter != smoothPts.cend(); ++iter) {
            int end = *iter;

            // check each point falls within our range of error.
            bool accurate = checkSmoothingAccuracy(start, end, &ys[0], ysmooth.get());

            // if not, flag for resmoothing and add another point between these two
            // data points
            if (!accurate) {
                resmooth = true;
                smoothPts.insert((start + end) / 2);
            }

            start = end;
        }
    }
}
/** Initialize a workspace from its parent
 * This sets values such as title, instrument, units, sample, spectramap.
 * This does NOT copy any data.
 *
 * @deprecated Replaced by functions in MantidDataObjects/WorkspaceCreation.h
 * @param parent :: the parent workspace
 * @param child :: the child workspace
 * @param differentSize :: A flag to indicate if the two workspace will be
 *different sizes
 */
void WorkspaceFactoryImpl::initializeFromParent(
    const MatrixWorkspace &parent, MatrixWorkspace &child,
    const bool differentSize) const {
  child.setTitle(parent.getTitle());
  child.setComment(parent.getComment());
  child.copyExperimentInfoFrom(&parent);
  child.setYUnit(parent.m_YUnit);
  child.setYUnitLabel(parent.m_YUnitLabel);
  child.setDistribution(parent.isDistribution());

  // Only copy the axes over if new sizes are not given
  if (!differentSize) {
    // Only copy mask map if same size for now. Later will need to check
    // continued validity.
    child.m_masks = parent.m_masks;
  }

  // Same number of histograms = copy over the spectra data
  if (parent.getNumberHistograms() == child.getNumberHistograms()) {
    child.m_isInitialized = false;
    for (size_t i = 0; i < parent.getNumberHistograms(); ++i)
      child.getSpectrum(i).copyInfoFrom(parent.getSpectrum(i));
    child.m_isInitialized = true;
    // We use this variant without ISpectrum update to avoid costly rebuilds
    // triggered by setIndexInfo(). ISpectrum::copyInfoFrom sets invalid flags
    // for spectrum definitions, so it is important to call this *afterwards*,
    // since it clears the flags:
    child.setIndexInfoWithoutISpectrumUpdate(parent.indexInfo());
  }

  // deal with axis
  for (size_t i = 0; i < parent.m_axes.size(); ++i) {
    if (parent.m_axes[i]->isSpectra()) {
      // By default the child already has a spectra axis which
      // does not need to get cloned from the parent.
      continue;
    }
    const bool isBinEdge =
        dynamic_cast<const BinEdgeAxis *const>(parent.m_axes[i]) != nullptr;
    const size_t newAxisLength =
        child.m_axes[i]->length() + (isBinEdge ? 1 : 0);
    const size_t oldAxisLength = parent.m_axes[i]->length();

    // Need to delete the existing axis created in init above
    delete child.m_axes[i];
    child.m_axes[i] = nullptr;
    if (newAxisLength == oldAxisLength) {
      // Now set to a copy of the parent workspace's axis
      child.m_axes[i] = parent.m_axes[i]->clone(&child);
    } else {
      // Call the 'different length' clone variant
      child.m_axes[i] = parent.m_axes[i]->clone(newAxisLength, &child);
    }
  }
}