/*
    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;
    }
예제 #2
0
  /** Creates a fake MDHistoWorkspace
   *
   * @param signal :: signal in every point
   * @param numDims :: number of dimensions to create. They will range from 0 to max
   * @param numBins :: bins in each dimensions
   * @param max :: max position in each dimension
   * @param errorSquared :: error squared in every point
   * @param name :: optional name
   * @param numEvents :: optional number of events in each bin. Default 1.0
   * @return the MDHisto
   */
  Mantid::MDEvents::MDHistoWorkspace_sptr makeFakeMDHistoWorkspace(double signal, size_t numDims, size_t numBins,
      coord_t max, double errorSquared, std::string name, double numEvents)
  {
    Mantid::MDEvents::MDHistoWorkspace * ws = NULL;
    if (numDims ==1)
    {
      ws = new Mantid::MDEvents::MDHistoWorkspace(
          MDHistoDimension_sptr(new MDHistoDimension("x","x","m", 0.0, max, numBins)) );
    }
    else if (numDims == 2)
    {
      ws = new Mantid::MDEvents::MDHistoWorkspace(
          MDHistoDimension_sptr(new MDHistoDimension("x","x","m", 0.0, max, numBins)),
          MDHistoDimension_sptr(new MDHistoDimension("y","y","m", 0.0, max, numBins))  );
    }
    else if (numDims == 3)
    {
      ws = new Mantid::MDEvents::MDHistoWorkspace(
          MDHistoDimension_sptr(new MDHistoDimension("x","x","m", 0.0, max, numBins)),
          MDHistoDimension_sptr(new MDHistoDimension("y","y","m", 0.0, max, numBins)),
          MDHistoDimension_sptr(new MDHistoDimension("z","z","m", 0.0, max, numBins))   );
    }
    else if (numDims == 4)
    {
      ws = new Mantid::MDEvents::MDHistoWorkspace(
          MDHistoDimension_sptr(new MDHistoDimension("x","x","m", 0.0, max, numBins)),
          MDHistoDimension_sptr(new MDHistoDimension("y","y","m", 0.0, max, numBins)),
          MDHistoDimension_sptr(new MDHistoDimension("z","z","m", 0.0, max, numBins)),
          MDHistoDimension_sptr(new MDHistoDimension("t","t","m", 0.0, max, numBins))
          );
    }

    if (!ws)
      throw std::runtime_error(" invalid or unsupported number of dimensions given");

    Mantid::MDEvents::MDHistoWorkspace_sptr ws_sptr(ws);
    ws_sptr->setTo(signal, errorSquared, numEvents);
    ws_sptr->addExperimentInfo(ExperimentInfo_sptr(new ExperimentInfo()));
    if (!name.empty())
      AnalysisDataService::Instance().addOrReplace(name, ws_sptr);
    return ws_sptr;
  }
예제 #3
0
IMDHistoWorkspace_sptr ReflectometryTransform::executeMDNormPoly(
    MatrixWorkspace_const_sptr inputWs) const {

  auto input_x_dim = inputWs->getXDimension();

  MDHistoDimension_sptr dim0 = MDHistoDimension_sptr(new MDHistoDimension(
      input_x_dim->getName(), input_x_dim->getDimensionId(),
      input_x_dim->getMDFrame(),
      static_cast<Mantid::coord_t>(input_x_dim->getMinimum()),
      static_cast<Mantid::coord_t>(input_x_dim->getMaximum()),
      input_x_dim->getNBins()));

  auto input_y_dim = inputWs->getYDimension();

  MDHistoDimension_sptr dim1 = MDHistoDimension_sptr(new MDHistoDimension(
      input_y_dim->getName(), input_y_dim->getDimensionId(),
      input_y_dim->getMDFrame(),
      static_cast<Mantid::coord_t>(input_y_dim->getMinimum()),
      static_cast<Mantid::coord_t>(input_y_dim->getMaximum()),
      input_y_dim->getNBins()));

  auto outWs = boost::make_shared<MDHistoWorkspace>(dim0, dim1);

  for (size_t nHistoIndex = 0; nHistoIndex < inputWs->getNumberHistograms();
       ++nHistoIndex) {
    const MantidVec X = inputWs->readX(nHistoIndex);
    const MantidVec Y = inputWs->readY(nHistoIndex);
    const MantidVec E = inputWs->readE(nHistoIndex);

    for (size_t nBinIndex = 0; nBinIndex < inputWs->blocksize(); ++nBinIndex) {
      auto value_index = outWs->getLinearIndex(nBinIndex, nHistoIndex);
      outWs->setSignalAt(value_index, Y[nBinIndex]);
      outWs->setErrorSquaredAt(value_index, E[nBinIndex] * E[nBinIndex]);
    }
  }
  return outWs;
}
예제 #4
0
  /** Creates a fake MDHistoWorkspace with more options
   *
   * @param numDims :: number of dimensions to create. They will range from 0 to max
   * @param signal :: signal in every point
   * @param errorSquared :: error squared in every point
   * @param numBins :: array of # of bins in each dimensions
   * @param min :: array of min position in each dimension
   * @param max :: array of max position in each dimension
   * @param names :: array of names for each dimension
   * @param name :: optional name
   * @return the MDHisto
   */
  Mantid::MDEvents::MDHistoWorkspace_sptr makeFakeMDHistoWorkspaceGeneral(size_t numDims,
      double signal, double errorSquared,
      size_t * numBins, coord_t * min, coord_t * max,
      std::vector<std::string> names, std::string name )
  {
    std::vector<Mantid::Geometry::MDHistoDimension_sptr> dimensions;
    for (size_t d=0; d<numDims; d++)
      dimensions.push_back(MDHistoDimension_sptr(new MDHistoDimension(names[d], names[d], "m", min[d], max[d], numBins[d])));

    Mantid::MDEvents::MDHistoWorkspace * ws = NULL;
    ws = new Mantid::MDEvents::MDHistoWorkspace(dimensions);
    Mantid::MDEvents::MDHistoWorkspace_sptr ws_sptr(ws);
    ws_sptr->setTo(signal, errorSquared, 1.0 /* num events */);
    if (!name.empty())
      AnalysisDataService::Instance().addOrReplace(name, ws_sptr);
    return ws_sptr;
  }
예제 #5
0
/** Creates a fake MDHistoWorkspace with more options
 *
 * @param numDims :: number of dimensions to create. They will range from 0 to
 *max
 * @param signal :: signal in every point
 * @param errorSquared :: error squared in every point
 * @param numBins :: array of # of bins in each dimensions
 * @param min :: array of min position in each dimension
 * @param max :: array of max position in each dimension
 * @param names :: array of names for each dimension
 * @param name :: optional name
 * @return the MDHisto
 */
MDHistoWorkspace_sptr makeFakeMDHistoWorkspaceGeneral(
    size_t numDims, double signal, double errorSquared, size_t *numBins,
    coord_t *min, coord_t *max, std::vector<std::string> names,
    std::string name) {
  std::vector<Mantid::Geometry::MDHistoDimension_sptr> dimensions;
  // Create MDFrame of General Frame type
  Mantid::Geometry::GeneralFrame frame(
      Mantid::Geometry::GeneralFrame::GeneralFrameDistance, "m");
  for (size_t d = 0; d < numDims; d++)
    dimensions.push_back(MDHistoDimension_sptr(new MDHistoDimension(
        names[d], names[d], frame, min[d], max[d], numBins[d])));

  MDHistoWorkspace_sptr ws_sptr =
      boost::make_shared<MDHistoWorkspace>(dimensions);
  ws_sptr->setTo(signal, errorSquared, 1.0 /* num events */);
  if (!name.empty())
    AnalysisDataService::Instance().addOrReplace(name, ws_sptr);
  return ws_sptr;
}
/** Create an empty output workspace from the generic properies. This gives a
new workspace with dimensions provided, but signal and
error arrays will not yet be set.
*/
MDHistoWorkspace_sptr ImportMDHistoWorkspaceBase::createEmptyOutputWorkspace() {
  // Fetch input properties
  size_t ndims;
  {
    int ndims_int = getProperty("Dimensionality");
    ndims = ndims_int;
  }
  std::vector<double> extents = getProperty("Extents");
  std::vector<int> nbins = getProperty("NumberOfBins");
  std::vector<std::string> names = getProperty("Names");
  std::vector<std::string> units = getProperty("Units");

  // Perform all validation on inputs
  if (extents.size() != ndims * 2)
    throw std::invalid_argument("You must specify twice as many extents "
                                "(min,max) as there are dimensions.");
  if (nbins.size() != ndims)
    throw std::invalid_argument(
        "You must specify as number of bins as there are dimensions.");
  if (names.size() != ndims)
    throw std::invalid_argument(
        "You must specify as many names as there are dimensions.");
  if (units.size() != ndims)
    throw std::invalid_argument(
        "You must specify as many units as there are dimensions.");

  // Fabricate new dimensions from inputs
  std::vector<MDHistoDimension_sptr> dimensions;
  for (size_t k = 0; k < ndims; ++k) {
    dimensions.push_back(MDHistoDimension_sptr(new MDHistoDimension(
        names[k], names[k], units[k], static_cast<coord_t>(extents[k * 2]),
        static_cast<coord_t>(extents[(k * 2) + 1]), nbins[k])));
  }

  // Calculate the total number of bins by multiplying across each dimension.
  Product answer = std::for_each(nbins.begin(), nbins.end(), Product());
  m_bin_product = answer.result;

  MDHistoWorkspace_sptr ws(new MDHistoWorkspace(dimensions));
  return ws;
}
예제 #7
0
  /** Execute the algorithm.
   */
  void CreateMDWorkspace::exec()
  {
    // Get the properties and validate them
    std::string eventType = getPropertyValue("EventType");
    int ndims_prop = getProperty("Dimensions");
    if (ndims_prop <= 0)
      throw std::invalid_argument("You must specify a number of dimensions >= 1.");
    int mind = this->getProperty("MinRecursionDepth");
    int maxd = this->getProperty("MaxRecursionDepth");
    if (mind > maxd)
      throw std::invalid_argument("MinRecursionDepth must be <= MaxRecursionDepth.");
    if (mind < 0 || maxd < 0)
      throw std::invalid_argument("MinRecursionDepth and MaxRecursionDepth must be positive.");

    size_t ndims = static_cast<size_t>(ndims_prop);

    std::vector<double> extents = getProperty("Extents");
    std::vector<std::string> names = getProperty("Names");
    std::vector<std::string> units = getProperty("Units");

    if (extents.size() != ndims*2)
      throw std::invalid_argument("You must specify twice as many extents (min,max) as there are dimensions.");
    if (names.size() != ndims)
      throw std::invalid_argument("You must specify as many names as there are dimensions.");
    if (units.size() != ndims)
      throw std::invalid_argument("You must specify as many units as there are dimensions.");

    // Have the factory create it
    IMDEventWorkspace_sptr out = MDEventFactory::CreateMDWorkspace(ndims, eventType);

    // Give all the dimensions
    for (size_t d=0; d<ndims; d++)
    {
      MDHistoDimension * dim = new MDHistoDimension(names[d], names[d], units[d], static_cast<coord_t>(extents[d*2]), static_cast<coord_t>(extents[d*2+1]), 1);
      out->addDimension(MDHistoDimension_sptr(dim));
    }

    // Initialize it using the dimension
    out->initialize();

    // Call the templated function to finish ints
    CALL_MDEVENT_FUNCTION(this->finish, out);

    // --- File back end ? ----------------
    std::string filename = getProperty("Filename");
    if (!filename.empty())
    {
      // First save to the NXS file
      g_log.notice() << "Running SaveMD" << std::endl;
      IAlgorithm_sptr alg = createChildAlgorithm("SaveMD");
      alg->setPropertyValue("Filename", filename);
      alg->setProperty("InputWorkspace", boost::dynamic_pointer_cast<IMDWorkspace>(out));
      alg->executeAsChildAlg();
      // And now re-load it with this file as the backing.
      g_log.notice() << "Running LoadMD" << std::endl;
      alg = createChildAlgorithm("LoadMD");
      alg->setPropertyValue("Filename", filename);
      alg->setProperty("FileBackEnd", true);
      alg->setPropertyValue("Memory", getPropertyValue("Memory"));
      alg->executeAsChildAlg();
      // Replace the workspace with the loaded, file-backed one
      IMDWorkspace_sptr temp;
      temp = alg->getProperty("OutputWorkspace");
      out = boost::dynamic_pointer_cast<IMDEventWorkspace>(temp);
    }

    // Save it on the output.
    setProperty("OutputWorkspace", boost::dynamic_pointer_cast<Workspace>(out));
  }
예제 #8
0
/** Execute the algorithm.
 */
void ImportMDEventWorkspace::exec() {
  std::string filename = getProperty("Filename");

  std::ifstream file;
  try {
    file.open(filename.c_str(), std::ios::in);
  } catch (std::ifstream::failure &e) {
    g_log.error() << "Cannot open file: " << filename;
    throw(e);
  }

  // Extract data from the file, excluding comment lines.
  std::string line;
  std::string lastLine;
  size_t nActualColumns = 0;
  while (std::getline(file, line)) {
    boost::algorithm::trim(line);
    if (std::string::npos == line.find_first_of(CommentLineStartFlag())) {
      std::stringstream buffer(line);
      std::copy(std::istream_iterator<std::string>(buffer),
                std::istream_iterator<std::string>(),
                std::back_inserter(m_file_data));

      if (lastLine == MDEventBlockFlag()) {
        std::vector<std::string> strVec;
        boost::algorithm::split(strVec, line, boost::is_any_of("\t "),
                                boost::token_compress_on);
        nActualColumns = strVec.size();
      }
    }
    lastLine = line;
  }

  file.close();

  // Check the file format.
  quickFileCheck();

  // Extract some well used posisions
  m_posDimStart =
      std::find(m_file_data.begin(), m_file_data.end(), DimensionBlockFlag());
  m_posMDEventStart =
      std::find(m_file_data.begin(), m_file_data.end(), MDEventBlockFlag());

  // Calculate the dimensionality
  int posDiffDims =
      static_cast<int>(std::distance(m_posDimStart, m_posMDEventStart));
  m_nDimensions = (posDiffDims - 1) / 4;

  // Calculate the actual number of columns in the MDEvent data.
  int posDiffMDEvent =
      static_cast<int>(std::distance(m_posMDEventStart, m_file_data.end()));
  const size_t columnsForFullEvents =
      m_nDimensions + 4; // signal, error, run_no, detector_no
  m_IsFullDataObjects = (nActualColumns == columnsForFullEvents);

  if (0 == nActualColumns) {
    m_nDataObjects = 0;
    g_log.warning() << "The number of actual columns found in the file "
                       "(exlcuding comments) is zero" << std::endl;
  } else {
    m_nDataObjects = posDiffMDEvent / nActualColumns;
  }

  // Get the min and max extents in each dimension.
  std::vector<double> extentMins(m_nDimensions);
  std::vector<double> extentMaxs(m_nDimensions);
  DataCollectionType::iterator mdEventEntriesIterator = m_posMDEventStart;
  for (size_t i = 0; i < m_nDataObjects; ++i) {
    mdEventEntriesIterator += 2;
    if (m_IsFullDataObjects) {
      mdEventEntriesIterator += 2;
    }
    for (size_t j = 0; j < m_nDimensions; ++j) {
      double coord = convert<double>(*(++mdEventEntriesIterator));
      extentMins[j] = coord < extentMins[j] ? coord : extentMins[j];
      extentMaxs[j] = coord > extentMaxs[j] ? coord : extentMaxs[j];
    }
  }

  // Create a target output workspace.
  IMDEventWorkspace_sptr outWs = MDEventFactory::CreateMDWorkspace(
      m_nDimensions, m_IsFullDataObjects ? "MDEvent" : "MDLeanEvent");

  // Extract Dimensions and add to the output workspace.
  DataCollectionType::iterator dimEntriesIterator = m_posDimStart;
  auto unitFactory = makeMDUnitFactoryChain();
  for (size_t i = 0; i < m_nDimensions; ++i) {
    std::string id = convert<std::string>(*(++dimEntriesIterator));
    std::string name = convert<std::string>(*(++dimEntriesIterator));
    std::string units = convert<std::string>(*(++dimEntriesIterator));
    int nbins = convert<int>(*(++dimEntriesIterator));

    auto mdUnit = unitFactory->create(units);
    Mantid::Geometry::GeneralFrame frame(
        Mantid::Geometry::GeneralFrame::GeneralFrameName, std::move(mdUnit));
    outWs->addDimension(MDHistoDimension_sptr(new MDHistoDimension(
        id, name, frame, static_cast<coord_t>(extentMins[i]),
        static_cast<coord_t>(extentMaxs[i]), nbins)));
  }

  CALL_MDEVENT_FUNCTION(this->addEventsData, outWs)

  // set output
  this->setProperty("OutputWorkspace", outWs);
}