/** Create an EventWorkspace containing fake data
 * of single-crystal diffraction.
 * Instrument is MINITOPAZ
 *
 * @return EventWorkspace_sptr
 */
EventWorkspace_sptr
createDiffractionEventWorkspace(int numEvents, int numPixels, int numBins) {
  double binDelta = 10.0;

  auto retVal = boost::make_shared<EventWorkspace>();
  retVal->initialize(numPixels, 1, 1);

  // --------- Load the instrument -----------
  const std::string filename = FileFinder::Instance().getFullPath(
      "IDFs_for_UNIT_TESTING/MINITOPAZ_Definition.xml");
  InstrumentDefinitionParser parser(filename, "MINITOPAZ",
                                    Strings::loadFile(filename));
  auto instrument = parser.parseXML(nullptr);
  retVal->populateInstrumentParameters();
  retVal->setInstrument(instrument);

  DateAndTime run_start("2010-01-01T00:00:00");

  for (int pix = 0; pix < numPixels; pix++) {
    for (int i = 0; i < numEvents; i++) {
      retVal->getSpectrum(pix) += Mantid::DataObjects::TofEvent(
          (i + 0.5) * binDelta, run_start + double(i));
    }
    retVal->getSpectrum(pix).addDetectorID(pix);
  }

  // Create the x-axis for histogramming.
  HistogramData::BinEdges x1(numBins);
  auto &xRef = x1.mutableData();
  for (int i = 0; i < numBins; ++i) {
    xRef[i] = i * binDelta;
  }

  // Set all the histograms at once.
  retVal->setAllX(x1);
  // Default unit: TOF.
  retVal->getAxis(0)->setUnit("TOF");

  // Give it a crystal and goniometer
  WorkspaceCreationHelper::setGoniometer(retVal, 0., 0., 0.);
  WorkspaceCreationHelper::setOrientedLattice(retVal, 1., 1., 1.);

  // Some sanity checks
  if (retVal->getInstrument()->getName() != "MINITOPAZ")
    throw std::runtime_error("MDEventsTestHelper::"
                             "createDiffractionEventWorkspace(): Wrong "
                             "instrument loaded.");
  Mantid::detid2det_map dets;
  retVal->getInstrument()->getDetectors(dets);
  if (dets.size() != 100 * 100)
    throw std::runtime_error("MDEventsTestHelper::"
                             "createDiffractionEventWorkspace(): Wrong "
                             "instrument size.");

  return retVal;
}
Example #2
0
/** Execute the algorithm.
 */
void ResampleX::exec() {
  // generically having access to the input workspace is a good idea
  MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
  MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
  bool inPlace = (inputWS == outputWS); // Rebinning in-place
  m_isDistribution = inputWS->isDistribution();
  m_isHistogram = inputWS->isHistogramData();
  const int numSpectra = static_cast<int>(inputWS->getNumberHistograms());

  // the easy parameters
  m_useLogBinning = getProperty("LogBinning");
  m_numBins = getProperty("NumberBins");
  m_preserveEvents = getProperty("PreserveEvents");

  // determine the xmin/xmax for the workspace
  vector<double> xmins = getProperty("XMin");
  vector<double> xmaxs = getProperty("XMax");
  string error = determineXMinMax(inputWS, xmins, xmaxs);
  if (!error.empty())
    throw std::runtime_error(error);

  bool common_limits = true;
  {
    double xmin_common = xmins[0];
    double xmax_common = xmaxs[0];
    for (size_t i = 1; i < xmins.size(); ++i) {
      if (xmins[i] != xmin_common) {
        common_limits = false;
        break;
      }
      if (xmaxs[i] != xmax_common) {
        common_limits = false;
        break;
      }
    }
  }
  if (common_limits) {
    g_log.debug() << "Common limits between all spectra\n";
  } else {
    g_log.debug() << "Does not have common limits between all spectra\n";
  }

  // start doing actual work
  EventWorkspace_const_sptr inputEventWS =
      boost::dynamic_pointer_cast<const EventWorkspace>(inputWS);
  if (inputEventWS != nullptr) {
    if (m_preserveEvents) {
      if (inPlace) {
        g_log.debug() << "Rebinning event workspace in place\n";
      } else {
        g_log.debug() << "Rebinning event workspace out of place\n";
        outputWS = inputWS->clone();
      }
      auto outputEventWS =
          boost::dynamic_pointer_cast<EventWorkspace>(outputWS);

      if (common_limits) {
        // get the delta from the first since they are all the same
        BinEdges xValues(0);
        const double delta = this->determineBinning(xValues.mutableRawData(),
                                                    xmins[0], xmaxs[0]);
        g_log.debug() << "delta = " << delta << "\n";
        outputEventWS->setAllX(xValues);
      } else {
        // initialize progress reporting.
        Progress prog(this, 0.0, 1.0, numSpectra);

        // do the rebinning
        PARALLEL_FOR_IF(Kernel::threadSafe(*inputEventWS, *outputWS))
        for (int wkspIndex = 0; wkspIndex < numSpectra; ++wkspIndex) {
          PARALLEL_START_INTERUPT_REGION
          BinEdges xValues(0);
          const double delta = this->determineBinning(
              xValues.mutableRawData(), xmins[wkspIndex], xmaxs[wkspIndex]);
          g_log.debug() << "delta[wkspindex=" << wkspIndex << "] = " << delta
                        << " xmin=" << xmins[wkspIndex]
                        << " xmax=" << xmaxs[wkspIndex] << "\n";
          outputEventWS->setHistogram(wkspIndex, xValues);
          prog.report(name()); // Report progress
          PARALLEL_END_INTERUPT_REGION
        }
        PARALLEL_CHECK_INTERUPT_REGION
      }
    }    // end if (m_preserveEvents)
    else // event workspace -> matrix workspace
    {
      //--------- Different output, OR you're inplace but not preserving Events
      g_log.information() << "Creating a Workspace2D from the EventWorkspace "
                          << inputEventWS->getName() << ".\n";
      outputWS = create<DataObjects::Workspace2D>(
          *inputWS, numSpectra, HistogramData::BinEdges(m_numBins + 1));

      // Initialize progress reporting.
      Progress prog(this, 0.0, 1.0, numSpectra);

      // Go through all the histograms and set the data
      PARALLEL_FOR_IF(Kernel::threadSafe(*inputEventWS, *outputWS))
      for (int wkspIndex = 0; wkspIndex < numSpectra; ++wkspIndex) {
        PARALLEL_START_INTERUPT_REGION

        // Set the X axis for each output histogram
        MantidVec xValues;
        const double delta =
            this->determineBinning(xValues, xmins[wkspIndex], xmaxs[wkspIndex]);
        g_log.debug() << "delta[wkspindex=" << wkspIndex << "] = " << delta
                      << "\n";
        outputWS->setBinEdges(wkspIndex, xValues);

        // Get a const event list reference. inputEventWS->dataY() doesn't work.
        const EventList &el = inputEventWS->getSpectrum(wkspIndex);
        MantidVec y_data, e_data;
        // The EventList takes care of histogramming.
        el.generateHistogram(xValues, y_data, e_data);

        // Copy the data over.
        outputWS->mutableY(wkspIndex) = std::move(y_data);
        outputWS->mutableE(wkspIndex) = std::move(e_data);

        // Report progress
        prog.report(name());
        PARALLEL_END_INTERUPT_REGION
      }
      PARALLEL_CHECK_INTERUPT_REGION

      // Copy all the axes
      for (int i = 1; i < inputWS->axes(); i++) {
        outputWS->replaceAxis(i, inputWS->getAxis(i)->clone(outputWS.get()));
        outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit();
      }

      // Copy the units over too.
      for (int i = 0; i < outputWS->axes(); ++i) {
        outputWS->getAxis(i)->unit() = inputWS->getAxis(i)->unit();
      }
      outputWS->setYUnit(inputEventWS->YUnit());
      outputWS->setYUnitLabel(inputEventWS->YUnitLabel());
    }
    // Assign it to the output workspace property
    setProperty("OutputWorkspace", outputWS);
    return;
  } else // (inputeventWS != NULL)