Example #1
0
/** Make a demo data set for testing */
IMDWorkspace_sptr makeDemoData(bool binned = false) {
  // Create a fake workspace
  // size_t numBins = 100;

  // ---- Start with empty MDEW ----
  FrameworkManager::Instance().exec(
      "CreateMDWorkspace", 16, "Dimensions", "3", "Extents",
      "-10,10,-10,10,-10,10", "Names", "h,k,l", "Units",
      "lattice,lattice,lattice", "SplitInto", "5", "SplitThreshold", "100",
      "MaxRecursionDepth", "20", "OutputWorkspace", "mdew");
  addPeak(15000, 0, 0, 0, 3);
  addPeak(5000, 0, 0, 0, 0.3);
  addPeak(5000, 0, 0, 0, 0.2);
  addPeak(5000, 0, 0, 0, 0.1);
  addPeak(5000, 1, 0, 0, 0.3);
  addPeak(5000, 2, 0, 0, 0.3);
  addPeak(5000, 2, 1, 0, 0.3);
  //  addPeak(12000,0,0,0, 0.03);
  IMDEventWorkspace_sptr mdew = boost::dynamic_pointer_cast<IMDEventWorkspace>(
      AnalysisDataService::Instance().retrieve("mdew"));
  mdew->splitAllIfNeeded(NULL);
  if (binned) {
    // Bin aligned to original
    //    FrameworkManager::Instance().exec("BinMD", 12,
    //        "InputWorkspace", "mdew",
    //        "OutputWorkspace", "binned",
    //        "AxisAligned", "1",
    //        "AlignedDim0", "h, -10, 10, 100",
    //        "AlignedDim1", "k, -10, 10, 100",
    //        "AlignedDim2", "l, -10, 10, 100"
    //        );
    FrameworkManager::Instance().exec(
        "BinMD", 20, "InputWorkspace", "mdew", "OutputWorkspace", "binned",
        "AxisAligned", "0", "BasisVector0", "rx, m, 1.0, 0.0, 0.0",
        "BasisVector1", "ry, m, 0.0, 1.0, 0.0", "BasisVector2",
        "rz, m, 0.0, 0.0, 1.0", "ForceOrthogonal", "1", "Translation",
        "-5, -5, -5", "OutputExtents", "0, 10, 0,10, 0,10", "OutputBins",
        "100, 100, 100");

    FrameworkManager::Instance().exec(
        "BinMD", 12, "InputWorkspace", "mdew", "OutputWorkspace", "binned_al",
        "AxisAligned", "1", "AlignedDim0", "k, -5, 5, 100", "AlignedDim1",
        "l, -5, 5, 100", "AlignedDim2", "h, -5, 5, 100");

    FrameworkManager::Instance().exec("LoadEventNexus", 4, "Filename",
                                      "CNCS_7860_event.nxs", "OutputWorkspace",
                                      "workspace_2d");

    FrameworkManager::Instance().exec(
        "Rebin", 8, "Params", "40e3, 1e3, 70e3", "PreserveEvents", "1",
        "InputWorkspace", "workspace_2d", "OutputWorkspace", "workspace_2d");

    return boost::dynamic_pointer_cast<IMDWorkspace>(
        AnalysisDataService::Instance().retrieve("binned"));
  } else
    return boost::dynamic_pointer_cast<IMDWorkspace>(mdew);
}
/** Create output workspace
 * @brief ConvertCWSDExpToMomentum::createExperimentMDWorkspace
 * @return
 */
API::IMDEventWorkspace_sptr
ConvertCWSDExpToMomentum::createExperimentMDWorkspace() {

  // Create workspace in Q_sample with dimenion as 3
  size_t nDimension = 3;
  IMDEventWorkspace_sptr mdws =
      MDEventFactory::CreateMDWorkspace(nDimension, "MDEvent");

  // Extract Dimensions and add to the output workspace.
  std::vector<std::string> vec_ID(3);
  vec_ID[0] = "Q_sample_x";
  vec_ID[1] = "Q_sample_y";
  vec_ID[2] = "Q_sample_z";

  std::vector<std::string> dimensionNames(3);
  dimensionNames[0] = "Q_sample_x";
  dimensionNames[1] = "Q_sample_y";
  dimensionNames[2] = "Q_sample_z";

  Mantid::Kernel::SpecialCoordinateSystem coordinateSystem =
      Mantid::Kernel::QSample;

  // Add dimensions
  // FIXME - Should I give out a better value???
  if (m_extentMins.size() != 3 || m_extentMaxs.size() != 3 ||
      m_numBins.size() != 3) {
    // Default dimenion
    m_extentMins.resize(3, -10.0);
    m_extentMaxs.resize(3, 10.0);
    m_numBins.resize(3, 100);
  }
  // Sample-Q range
  m_minQVec.resize(3);
  m_maxQVec.resize(3);

  for (size_t d = 0; d < 3; ++d)
    g_log.debug() << "Direction " << d << ", Range = " << m_extentMins[d]
                  << ", " << m_extentMaxs[d] << "\n";

  // Set Q Sample frame
  Mantid::Geometry::QSample frame;

  for (size_t i = 0; i < nDimension; ++i) {
    std::string id = vec_ID[i];
    std::string name = dimensionNames[i];
    mdws->addDimension(
        Geometry::MDHistoDimension_sptr(new Geometry::MDHistoDimension(
            id, name, frame, static_cast<coord_t>(m_extentMins[i]),
            static_cast<coord_t>(m_extentMaxs[i]), m_numBins[i])));
  }

  // Set coordinate system
  mdws->setCoordinateSystem(coordinateSystem);

  return mdws;
}
Example #3
0
/*
Generate the vtkDataSet from the objects input IMDEventWorkspace
@param progressUpdating: Reporting object to pass progress information up the
stack.
@Return a fully constructed vtkUnstructuredGrid containing geometric and scalar
data.
*/
vtkSmartPointer<vtkDataSet>
vtkMDHexFactory::create(ProgressAction &progressUpdating) const {
  this->dataSet = tryDelegatingCreation<IMDEventWorkspace, 3>(
      m_workspace, progressUpdating, false);
  if (this->dataSet) {
    return this->dataSet;
  } else {
    IMDEventWorkspace_sptr imdws =
        this->castAndCheck<IMDEventWorkspace, 3>(m_workspace, false);

    size_t nd = imdws->getNumDims();
    if (nd > 3) {
      // Slice from >3D down to 3D
      this->slice = true;
      this->sliceMask = Mantid::Kernel::make_unique<bool[]>(nd);
      this->sliceImplicitFunction = boost::make_shared<MDImplicitFunction>();

      // Make the mask of dimensions
      for (size_t d = 0; d < nd; d++)
        this->sliceMask[d] = (d < 3);

      // Define where the slice is in 4D
      std::vector<coord_t> point(nd, 0);

      // Define two opposing planes that point in all higher dimensions
      std::vector<coord_t> normal1(nd, 0);
      std::vector<coord_t> normal2(nd, 0);
      for (size_t d = 3; d < nd; d++) {
        normal1[d] = +1.0;
        normal2[d] = -1.0;
      }
      // This creates a slice which is one bin thick in the 4th dimension
      // m_time assumed to satisfy: dim_min <= m_time < dim_max
      // but does not have to be a bin centre
      point[3] = getPreviousBinBoundary(imdws);
      sliceImplicitFunction->addPlane(MDPlane(normal1, point));
      point[3] = getNextBinBoundary(imdws);
      sliceImplicitFunction->addPlane(MDPlane(normal2, point));

    } else {
      // Direct 3D, so no slicing
      this->slice = false;
    }
    progressUpdating.eventRaised(0.1);
    // Macro to call the right instance of the
    CALL_MDEVENT_FUNCTION(this->doCreate, imdws);
    progressUpdating.eventRaised(1.0);

    // The macro does not allow return calls, so we used a member variable.
    return this->dataSet;
  }
}
Example #4
0
/** Export events from an MDEventWorkspace for future processing
 * It is a convenient algorithm if number of events are few relative to
 * number of detectors
 */
void ConvertCWSDMDtoHKL::exportEvents(
    IMDEventWorkspace_sptr mdws, std::vector<Kernel::V3D> &vec_event_qsample,
    std::vector<signal_t> &vec_event_signal,
    std::vector<detid_t> &vec_event_det) {
  // Set the size of the output vectors
  size_t numevents = mdws->getNEvents();
  g_log.information() << "Number of events = " << numevents << "\n";

  vec_event_qsample.resize(numevents);
  vec_event_signal.resize(numevents);
  vec_event_det.resize(numevents);

  // Go through to get value
  IMDIterator *mditer = mdws->createIterator();
  size_t nextindex = 1;
  bool scancell = true;
  size_t currindex = 0;
  while (scancell) {
    size_t numevent_cell = mditer->getNumEvents();
    for (size_t iev = 0; iev < numevent_cell; ++iev) {
      // Check
      if (currindex >= vec_event_qsample.size())
        throw std::runtime_error("Logic error in event size!");

      float tempx = mditer->getInnerPosition(iev, 0);
      float tempy = mditer->getInnerPosition(iev, 1);
      float tempz = mditer->getInnerPosition(iev, 2);
      signal_t signal = mditer->getInnerSignal(iev);
      detid_t detid = mditer->getInnerDetectorID(iev);
      Kernel::V3D qsample(tempx, tempy, tempz);
      vec_event_qsample[currindex] = qsample;
      vec_event_signal[currindex] = signal;
      vec_event_det[currindex] = detid;

      ++currindex;
    }

    // Advance to next cell
    if (mditer->next()) {
      // advance to next cell
      mditer->jumpTo(nextindex);
      ++nextindex;
    } else {
      // break the loop
      scancell = false;
    }
  }

  return;
}
Example #5
0
/*
 * Get the previous bin boundary, or the current one if m_time is on a boundary
 */
coord_t
vtkMDHexFactory::getPreviousBinBoundary(IMDEventWorkspace_sptr imdws) const {
  auto t_dim = imdws->getTDimension();
  coord_t bin_width = t_dim->getBinWidth();
  coord_t dim_min = t_dim->getMinimum();
  return roundDown(coord_t(m_time) - dim_min, bin_width) + dim_min;
}
    /**
     Executes any meta-data loading required.
    */
    void MDEWEventNexusLoadingPresenter::executeLoadMetadata()
    {
      using namespace Mantid::API;
      AnalysisDataService::Instance().remove("MD_EVENT_WS_ID");

      IAlgorithm_sptr alg = AlgorithmManager::Instance().create("LoadMD");
       
      alg->initialize();
      alg->setPropertyValue("Filename", this->m_filename);
      alg->setPropertyValue("OutputWorkspace", "MD_EVENT_WS_ID");
      alg->setProperty("MetadataOnly", true); //Don't load the events.
      alg->setProperty("FileBackEnd", false); //Only require metadata, so do it in memory.
      alg->execute();

      Workspace_sptr result=AnalysisDataService::Instance().retrieve("MD_EVENT_WS_ID");
      IMDEventWorkspace_sptr eventWs = boost::dynamic_pointer_cast<Mantid::API::IMDEventWorkspace>(result);
      m_wsTypeName = eventWs->id();
      //Call base-class extraction method.
      this->extractMetadata(eventWs);

      AnalysisDataService::Instance().remove("MD_EVENT_WS_ID");
    }
Example #7
0
/**
Create the vtkStructuredGrid from the provided workspace
@param progressUpdating: Reporting object to pass progress information up the
stack.
@return fully constructed vtkDataSet.
*/
vtkSmartPointer<vtkDataSet>
vtkMDLineFactory::create(ProgressAction &progressUpdating) const {
  auto product = tryDelegatingCreation<IMDEventWorkspace, 1>(m_workspace,
                                                             progressUpdating);
  if (product != nullptr) {
    return product;
  } else {
    g_log.warning() << "Factory " << this->getFactoryTypeName()
                    << " is being used. You are viewing data with less than "
                       "three dimensions in the VSI. \n";

    IMDEventWorkspace_sptr imdws =
        doInitialize<IMDEventWorkspace, 1>(m_workspace);
    // Acquire a scoped read-only lock to the workspace (prevent segfault from
    // algos modifying ws)
    Mantid::Kernel::ReadLock lock(*imdws);

    const size_t nDims = imdws->getNumDims();
    size_t nNonIntegrated = imdws->getNonIntegratedDimensions().size();

    /*
    Write mask array with correct order for each internal dimension.
    */
    auto masks = Mantid::Kernel::make_unique<bool[]>(nDims);
    for (size_t i_dim = 0; i_dim < nDims; ++i_dim) {
      bool bIntegrated = imdws->getDimension(i_dim)->getIsIntegrated();
      masks[i_dim] =
          !bIntegrated; // TRUE for unmaksed, integrated dimensions are masked.
    }

    // Ensure destruction in any event.
    boost::scoped_ptr<IMDIterator> it(
        createIteratorWithNormalization(m_normalizationOption, imdws.get()));

    // Create 2 points per box.
    vtkNew<vtkPoints> points;
    points->SetNumberOfPoints(it->getDataSize() * 2);

    // One scalar per box
    vtkNew<vtkFloatArray> signals;
    signals->Allocate(it->getDataSize());
    signals->SetName(vtkDataSetFactory::ScalarName.c_str());
    signals->SetNumberOfComponents(1);

    size_t nVertexes;

    auto visualDataSet = vtkSmartPointer<vtkUnstructuredGrid>::New();
    visualDataSet->Allocate(it->getDataSize());

    vtkNew<vtkIdList> linePointList;
    linePointList->SetNumberOfIds(2);

    Mantid::API::CoordTransform const *transform = NULL;
    if (m_useTransform) {
      transform = imdws->getTransformToOriginal();
    }

    Mantid::coord_t out[1];
    auto useBox = std::vector<bool>(it->getDataSize());

    double progressFactor = 0.5 / double(it->getDataSize());
    double progressOffset = 0.5;

    size_t iBox = 0;
    do {
      progressUpdating.eventRaised(double(iBox) * progressFactor);

      Mantid::signal_t signal_normalized = it->getNormalizedSignal();
      if (std::isfinite(signal_normalized) &&
          m_thresholdRange->inRange(signal_normalized)) {
        useBox[iBox] = true;
        signals->InsertNextValue(static_cast<float>(signal_normalized));

        auto coords = std::unique_ptr<coord_t[]>(
            it->getVertexesArray(nVertexes, nNonIntegrated, masks.get()));

        // Iterate through all coordinates. Candidate for speed improvement.
        for (size_t v = 0; v < nVertexes; ++v) {
          coord_t *coord = coords.get() + v * 1;
          size_t id = iBox * 2 + v;
          if (m_useTransform) {
            transform->apply(coord, out);
            points->SetPoint(id, out[0], 0, 0);
          } else {
            points->SetPoint(id, coord[0], 0, 0);
          }
        }
      } // valid number of vertexes returned
      else {
        useBox[iBox] = false;
      }
      ++iBox;
    } while (it->next());

    for (size_t ii = 0; ii < it->getDataSize(); ++ii) {
      progressUpdating.eventRaised((double(ii) * progressFactor) +
                                   progressOffset);

      if (useBox[ii] == true) {
        vtkIdType pointIds = ii * 2;

        linePointList->SetId(0, pointIds + 0); // xyx
        linePointList->SetId(1, pointIds + 1); // dxyz
        visualDataSet->InsertNextCell(VTK_LINE, linePointList.GetPointer());
      } // valid number of vertexes returned
    }

    signals->Squeeze();
    points->Squeeze();

    visualDataSet->SetPoints(points.GetPointer());
    visualDataSet->GetCellData()->SetScalars(signals.GetPointer());
    visualDataSet->Squeeze();

    // Hedge against empty data sets
    if (visualDataSet->GetNumberOfPoints() <= 0) {
      vtkNullUnstructuredGrid nullGrid;
      visualDataSet = nullGrid.createNullData();
    }

    vtkSmartPointer<vtkDataSet> dataset = visualDataSet;
    return dataset;
  }
}
Example #8
0
/** Create output workspace
 * @brief ConvertCWSDExpToMomentum::createExperimentMDWorkspace
 * @return
 */
API::IMDEventWorkspace_sptr ConvertCWSDMDtoHKL::createHKLMDWorkspace(
    const std::vector<Kernel::V3D> &vec_hkl,
    const std::vector<signal_t> &vec_signal,
    const std::vector<detid_t> &vec_detid) {
  // Check
  if (vec_hkl.size() != vec_signal.size() ||
      vec_signal.size() != vec_detid.size())
    throw std::invalid_argument("Input vectors for HKL, signal and detector "
                                "IDs are of different size!");

  // Create workspace in Q_sample with dimenion as 3
  size_t nDimension = 3;
  IMDEventWorkspace_sptr mdws =
      MDEventFactory::CreateMDWorkspace(nDimension, "MDEvent");

  // Extract Dimensions and add to the output workspace.
  std::vector<std::string> vec_ID(3);
  vec_ID[0] = "H";
  vec_ID[1] = "K";
  vec_ID[2] = "L";

  std::vector<std::string> dimensionNames(3);
  dimensionNames[0] = "H";
  dimensionNames[1] = "K";
  dimensionNames[2] = "L";

  Mantid::Kernel::SpecialCoordinateSystem coordinateSystem =
      Mantid::Kernel::HKL;

  // Add dimensions
  std::vector<double> m_extentMins(3);
  std::vector<double> m_extentMaxs(3);
  std::vector<size_t> m_numBins(3, 100);
  getRange(vec_hkl, m_extentMins, m_extentMaxs);

  // Get MDFrame of HKL type with RLU
  auto unitFactory = makeMDUnitFactoryChain();
  auto unit = unitFactory->create(Units::Symbol::RLU.ascii());
  Mantid::Geometry::HKL frame(unit);

  for (size_t i = 0; i < nDimension; ++i) {
    std::string id = vec_ID[i];
    std::string name = dimensionNames[i];
    // std::string units = "A^-1";
    mdws->addDimension(
        Geometry::MDHistoDimension_sptr(new Geometry::MDHistoDimension(
            id, name, frame, static_cast<coord_t>(m_extentMins[i]),
            static_cast<coord_t>(m_extentMaxs[i]), m_numBins[i])));
  }

  // Set coordinate system
  mdws->setCoordinateSystem(coordinateSystem);

  // Creates a new instance of the MDEventInserter to output workspace
  MDEventWorkspace<MDEvent<3>, 3>::sptr mdws_mdevt_3 =
      boost::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(mdws);
  MDEventInserter<MDEventWorkspace<MDEvent<3>, 3>::sptr> inserter(mdws_mdevt_3);

  // Go though each spectrum to conver to MDEvent
  for (size_t iq = 0; iq < vec_hkl.size(); ++iq) {
    Kernel::V3D hkl = vec_hkl[iq];
    std::vector<Mantid::coord_t> millerindex(3);
    millerindex[0] = static_cast<float>(hkl.X());
    millerindex[1] = static_cast<float>(hkl.Y());
    millerindex[2] = static_cast<float>(hkl.Z());

    signal_t signal = vec_signal[iq];
    signal_t error = std::sqrt(signal);
    uint16_t runnumber = 1;
    detid_t detid = vec_detid[iq];

    // Insert
    inserter.insertMDEvent(
        static_cast<float>(signal), static_cast<float>(error * error),
        static_cast<uint16_t>(runnumber), detid, millerindex.data());
  }

  return mdws;
}
Example #9
0
/** Execute the algorithm.
 */
void BinMD::exec() {
  // Input MDEventWorkspace/MDHistoWorkspace
  m_inWS = getProperty("InputWorkspace");
  // Look at properties, create either axis-aligned or general transform.
  // This (can) change m_inWS
  this->createTransform();

  // De serialize the implicit function
  std::string ImplicitFunctionXML = getPropertyValue("ImplicitFunctionXML");
  implicitFunction = nullptr;
  if (!ImplicitFunctionXML.empty())
    implicitFunction =
        Mantid::API::ImplicitFunctionFactory::Instance().createUnwrapped(
            ImplicitFunctionXML);

  // This gets deleted by the thread pool; don't delete it in here.
  prog = new Progress(this, 0, 1.0, 1);

  // Create the dense histogram. This allocates the memory
  outWS = MDHistoWorkspace_sptr(new MDHistoWorkspace(m_binDimensions));

  // Saves the geometry transformation from original to binned in the workspace
  outWS->setTransformFromOriginal(this->m_transformFromOriginal, 0);
  outWS->setTransformToOriginal(this->m_transformToOriginal, 0);
  for (size_t i = 0; i < m_bases.size(); i++)
    outWS->setBasisVector(i, m_bases[i]);
  outWS->setOrigin(this->m_translation);
  outWS->setOriginalWorkspace(m_inWS, 0);

  // And the intermediate WS one too, if any
  if (m_intermediateWS) {
    outWS->setOriginalWorkspace(m_intermediateWS, 1);
    outWS->setTransformFromOriginal(m_transformFromIntermediate, 1);
    outWS->setTransformToOriginal(m_transformToIntermediate, 1);
  }

  // Wrapper to cast to MDEventWorkspace then call the function
  bool IterateEvents = getProperty("IterateEvents");
  if (!IterateEvents) {
    g_log.warning() << "IterateEvents=False is no longer supported. Setting "
                       "IterateEvents=True.\n";
    IterateEvents = true;
  }

  /*
  We should fail noisily here. CALL_MDEVENT_FUNCTION will silently allow
  IMDHistoWorkspaces to cascade through to the end
  and result in an empty output. The only way we allow InputWorkspaces to be
  IMDHistoWorkspaces is if they also happen to contain original workspaces
  that are MDEventWorkspaces.
  */
  if (boost::dynamic_pointer_cast<IMDHistoWorkspace>(m_inWS)) {
    throw std::runtime_error(
        "Cannot rebin a workspace that is histogrammed and has no original "
        "workspace that is an MDEventWorkspace. "
        "Reprocess the input so that it contains full MDEvents.");
  }

  CALL_MDEVENT_FUNCTION(this->binByIterating, m_inWS);

  // Copy the coordinate system & experiment infos to the output
  IMDEventWorkspace_sptr inEWS =
      boost::dynamic_pointer_cast<IMDEventWorkspace>(m_inWS);
  if (inEWS) {
    outWS->setCoordinateSystem(inEWS->getSpecialCoordinateSystem());
    try {
      outWS->copyExperimentInfos(*inEWS);
    } catch (std::runtime_error &) {
      g_log.warning()
          << this->name()
          << " was not able to copy experiment info to output workspace "
          << outWS->getName() << '\n';
    }
  }

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

  outWS->updateSum();
  // Save the output
  setProperty("OutputWorkspace", boost::dynamic_pointer_cast<Workspace>(outWS));
}
Example #10
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);
  }
}
  /** 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));
  }
/** Execute the algorithm.
 */
void ConvertToDetectorFaceMD::exec() {
  // TODO convert matrix to event as needed
  MatrixWorkspace_sptr mws = this->getProperty("InputWorkspace");

  in_ws = boost::dynamic_pointer_cast<EventWorkspace>(mws);
  if (!in_ws)
    throw std::runtime_error("InputWorkspace is not an EventWorkspace");

  // Fill the map, throw if there are grouped pixels.
  m_detID_to_WI =
      in_ws->getDetectorIDToWorkspaceIndexVector(m_detID_to_WI_offset, true);

  // Get the map of the banks we'll display
  std::map<int, RectangularDetector_const_sptr> banks = this->getBanks();

  // Find the size in the TOF dimension
  double tof_min, tof_max;
  Axis *ax0 = in_ws->getAxis(0);
  in_ws->getXMinMax(tof_min, tof_max);
  if (ax0->getValue(0) < tof_min)
    tof_min = ax0->getValue(0);
  if (ax0->getValue(ax0->length() - 1) > tof_max)
    tof_max = ax0->getValue(ax0->length() - 1);

  // Get MDFrame of General Frame type
  Mantid::Geometry::GeneralFrame framePixel(
      Mantid::Geometry::GeneralFrame::GeneralFrameName, "pixel");
  Mantid::Geometry::GeneralFrame frameTOF(
      Mantid::Geometry::GeneralFrame::GeneralFrameName, ax0->unit()->label());

  // ------------------ Build all the dimensions ----------------------------
  MDHistoDimension_sptr dimX(
      new MDHistoDimension("x", "x", framePixel, static_cast<coord_t>(0),
                           static_cast<coord_t>(m_numXPixels), m_numXPixels));
  MDHistoDimension_sptr dimY(
      new MDHistoDimension("y", "y", framePixel, static_cast<coord_t>(0),
                           static_cast<coord_t>(m_numYPixels), m_numYPixels));
  std::string TOFname = ax0->title();
  if (TOFname.empty())
    TOFname = ax0->unit()->unitID();
  MDHistoDimension_sptr dimTOF(new MDHistoDimension(
      TOFname, TOFname, frameTOF, static_cast<coord_t>(tof_min),
      static_cast<coord_t>(tof_max), ax0->length()));

  std::vector<IMDDimension_sptr> dims{dimX, dimY, dimTOF};

  if (banks.size() > 1) {
    Mantid::Geometry::GeneralFrame frameNumber(
        Mantid::Geometry::GeneralFrame::GeneralFrameName, "number");
    int min = banks.begin()->first;
    int max = banks.rbegin()->first + 1;
    MDHistoDimension_sptr dimBanks(new MDHistoDimension(
        "bank", "bank", frameNumber, static_cast<coord_t>(min),
        static_cast<coord_t>(max), max - min));
    dims.push_back(dimBanks);
  }

  // --------- Create the workspace with the right number of dimensions
  // ----------
  size_t nd = dims.size();
  IMDEventWorkspace_sptr outWS =
      MDEventFactory::CreateMDWorkspace(nd, "MDEvent");
  outWS->initGeometry(dims);
  outWS->initialize();
  this->setBoxController(outWS->getBoxController(), mws->getInstrument());
  outWS->splitBox();

  MDEventWorkspace3::sptr outWS3 =
      boost::dynamic_pointer_cast<MDEventWorkspace3>(outWS);
  MDEventWorkspace4::sptr outWS4 =
      boost::dynamic_pointer_cast<MDEventWorkspace4>(outWS);

  // Copy ExperimentInfo (instrument, run, sample) to the output WS
  ExperimentInfo_sptr ei(in_ws->cloneExperimentInfo());
  uint16_t runIndex = outWS->addExperimentInfo(ei);

  // ---------------- Convert each bank --------------------------------------
  for (auto &bank : banks) {
    int bankNum = bank.first;
    RectangularDetector_const_sptr det = bank.second;
    for (int x = 0; x < det->xpixels(); x++)
      for (int y = 0; y < det->ypixels(); y++) {
        // Find the workspace index for this pixel coordinate
        detid_t detID = det->getDetectorIDAtXY(x, y);
        size_t wi = m_detID_to_WI[detID + m_detID_to_WI_offset];
        if (wi >= in_ws->getNumberHistograms())
          throw std::runtime_error("Invalid workspace index found in bank " +
                                   det->getName() + "!");

        coord_t xPos = static_cast<coord_t>(x);
        coord_t yPos = static_cast<coord_t>(y);
        coord_t bankPos = static_cast<coord_t>(bankNum);

        EventList &el = in_ws->getSpectrum(wi);

        // We want to bind to the right templated function, so we have to know
        // the type of TofEvent contained in the EventList.
        boost::function<void()> func;
        switch (el.getEventType()) {
        case TOF:
          if (nd == 3)
            this->convertEventList<TofEvent, MDEvent<3>, 3>(
                outWS3, wi, xPos, yPos, bankPos, runIndex, detID);
          else if (nd == 4)
            this->convertEventList<TofEvent, MDEvent<4>, 4>(
                outWS4, wi, xPos, yPos, bankPos, runIndex, detID);
          break;
        case WEIGHTED:
          if (nd == 3)
            this->convertEventList<WeightedEvent, MDEvent<3>, 3>(
                outWS3, wi, xPos, yPos, bankPos, runIndex, detID);
          else if (nd == 4)
            this->convertEventList<WeightedEvent, MDEvent<4>, 4>(
                outWS4, wi, xPos, yPos, bankPos, runIndex, detID);
          break;
        case WEIGHTED_NOTIME:
          if (nd == 3)
            this->convertEventList<WeightedEventNoTime, MDEvent<3>, 3>(
                outWS3, wi, xPos, yPos, bankPos, runIndex, detID);
          else if (nd == 4)
            this->convertEventList<WeightedEventNoTime, MDEvent<4>, 4>(
                outWS4, wi, xPos, yPos, bankPos, runIndex, detID);
          break;
        default:
          throw std::runtime_error("EventList had an unexpected data type!");
        }
      }
  }

  // ---------------------- Perform all box splitting ---------------
  ThreadScheduler *ts = new ThreadSchedulerLargestCost();
  ThreadPool tp(ts);
  outWS->splitAllIfNeeded(ts);
  tp.joinAll();
  outWS->refreshCache();

  // Save the output workspace
  this->setProperty("OutputWorkspace", outWS);
}
Example #13
0
    /**
    Create the vtkStructuredGrid from the provided workspace
    @param progressUpdating: Reporting object to pass progress information up the stack.
    @return fully constructed vtkDataSet.
    */
    vtkDataSet* vtkMDQuadFactory::create(ProgressAction& progressUpdating) const
    {
      vtkDataSet* product = tryDelegatingCreation<IMDEventWorkspace, 2>(m_workspace, progressUpdating);
      if(product != NULL)
      {
        return product;
      }
      else
      {
        IMDEventWorkspace_sptr imdws = this->castAndCheck<IMDEventWorkspace, 2>(m_workspace);
        // Acquire a scoped read-only lock to the workspace (prevent segfault from algos modifying ws)
        Mantid::Kernel::ReadLock lock(*imdws);

        const size_t nDims = imdws->getNumDims();
        size_t nNonIntegrated = imdws->getNonIntegratedDimensions().size();

        /*
        Write mask array with correct order for each internal dimension.
        */
        bool* masks = new bool[nDims];
        for(size_t i_dim = 0; i_dim < nDims; ++i_dim)
        {
          bool bIntegrated = imdws->getDimension(i_dim)->getIsIntegrated();
          masks[i_dim] = !bIntegrated; //TRUE for unmaksed, integrated dimensions are masked.
        }

        //Ensure destruction in any event.
        boost::scoped_ptr<IMDIterator> it(imdws->createIterator());

        // Create 4 points per box.
        vtkPoints *points = vtkPoints::New();
        points->SetNumberOfPoints(it->getDataSize() * 4);

        // One scalar per box
        vtkFloatArray * signals = vtkFloatArray::New();
        signals->Allocate(it->getDataSize());
        signals->SetName(m_scalarName.c_str());
        signals->SetNumberOfComponents(1);

        size_t nVertexes;

        vtkUnstructuredGrid *visualDataSet = vtkUnstructuredGrid::New();
        visualDataSet->Allocate(it->getDataSize());

        vtkIdList * quadPointList = vtkIdList::New();
        quadPointList->SetNumberOfIds(4);

        Mantid::API::CoordTransform* transform = NULL;
        if (m_useTransform)
        {
          transform = imdws->getTransformToOriginal();
        }

        Mantid::coord_t out[2];
        bool* useBox = new bool[it->getDataSize()];

        double progressFactor = 0.5/double(it->getDataSize());
        double progressOffset = 0.5;

        size_t iBox = 0;
        do
        {
          progressUpdating.eventRaised(progressFactor * double(iBox));

          Mantid::signal_t signal_normalized= it->getNormalizedSignal();
          if (!isSpecial( signal_normalized ) && m_thresholdRange->inRange(signal_normalized))
          {
            useBox[iBox] = true;
            signals->InsertNextValue(static_cast<float>(signal_normalized));

            coord_t* coords = it->getVertexesArray(nVertexes, nNonIntegrated, masks);
            delete [] coords;
            coords = it->getVertexesArray(nVertexes, nNonIntegrated, masks);

            //Iterate through all coordinates. Candidate for speed improvement.
            for(size_t v = 0; v < nVertexes; ++v)
            {
              coord_t * coord = coords + v*2;
              size_t id = iBox*4 + v;
              if(m_useTransform)
              {
                transform->apply(coord, out);
                points->SetPoint(id, out[0], out[1], 0);
              }
              else
              {
                points->SetPoint(id, coord[0], coord[1], 0);
              }
            }
            // Free memory
            delete [] coords;
          } // valid number of vertexes returned
          else
          {
            useBox[iBox] = false;
          }
          ++iBox;
        } while (it->next());

        delete[] masks;
        for(size_t ii = 0; ii < it->getDataSize() ; ++ii)
        {
          progressUpdating.eventRaised((progressFactor * double(ii)) + progressOffset);

          if (useBox[ii] == true)
          {
            vtkIdType pointIds = vtkIdType(ii * 4);

            quadPointList->SetId(0, pointIds + 0); //xyx
            quadPointList->SetId(1, pointIds + 1); //dxyz
            quadPointList->SetId(2, pointIds + 3); //dxdyz
            quadPointList->SetId(3, pointIds + 2); //xdyz
            visualDataSet->InsertNextCell(VTK_QUAD, quadPointList);
          } // valid number of vertexes returned
        }

        delete[] useBox;

        signals->Squeeze();
        points->Squeeze();

        visualDataSet->SetPoints(points);
        visualDataSet->GetCellData()->SetScalars(signals);
        visualDataSet->Squeeze();

        signals->Delete();
        points->Delete();
        quadPointList->Delete();

        return visualDataSet;
      }
    }
Example #14
0
void SliceMD::slice(typename MDEventWorkspace<MDE, nd>::sptr ws) {
  // Create the ouput workspace
  typename MDEventWorkspace<OMDE, ond>::sptr outWS(
      new MDEventWorkspace<OMDE, ond>());
  for (auto &binDimension : m_binDimensions) {
    outWS->addDimension(binDimension);
  }
  outWS->setCoordinateSystem(ws->getSpecialCoordinateSystem());
  outWS->initialize();
  // Copy settings from the original box controller
  BoxController_sptr bc = ws->getBoxController();

  // store wrute buffer size for the future
  // uint64_t writeBufSize =
  // bc->getFileIO()getDiskBuffer().getWriteBufferSize();
  // and disable write buffer (if any) for input MD Events for this algorithm
  // purposes;
  // bc->setCacheParameters(1,0);

  BoxController_sptr obc = outWS->getBoxController();
  // Use the "number of bins" as the "split into" parameter for the top level
  for (size_t od = 0; od < m_binDimensions.size(); od++) {
    obc->setSplitTopInto(od, m_binDimensions[od]->getNBins());
    obc->setSplitInto(od, bc->getSplitInto(od));
  }
  obc->setSplitThreshold(bc->getSplitThreshold());

  bool bTakeDepthFromInputWorkspace =
      getProperty("TakeMaxRecursionDepthFromInput");
  int tempDepth = getProperty("MaxRecursionDepth");
  size_t maxDepth =
      bTakeDepthFromInputWorkspace ? bc->getMaxDepth() : size_t(tempDepth);
  obc->setMaxDepth(maxDepth);

  // size_t outputSize = writeBufSize;
  // obc->setCacheParameters(sizeof(OMDE),outputSize);

  obc->resetNumBoxes();
  // Perform the first box splitting
  outWS->splitBox();
  size_t lastNumBoxes = obc->getTotalNumMDBoxes();

  // --- File back end ? ----------------
  std::string filename = getProperty("OutputFilename");
  if (!filename.empty()) {

    // First save to the NXS file
    g_log.notice() << "Running SaveMD to create file back-end\n";
    IAlgorithm_sptr alg = createChildAlgorithm("SaveMD");
    alg->setPropertyValue("Filename", filename);
    alg->setProperty("InputWorkspace", outWS);
    alg->setProperty("MakeFileBacked", true);
    alg->executeAsChildAlg();

    if (!obc->isFileBacked())
      throw std::runtime_error("SliceMD with file-backed output: Can not set "
                               "up file-backed output workspace ");

    auto IOptr = obc->getFileIO();
    size_t outBufSize = IOptr->getWriteBufferSize();
    // the buffer size for resulting workspace; reasonable size is at least 10
    // data chunk sizes (nice to verify)
    if (outBufSize < 10 * IOptr->getDataChunk()) {
      outBufSize = 10 * IOptr->getDataChunk();
      IOptr->setWriteBufferSize(outBufSize);
    }
  }

  // Function defining which events (in the input dimensions) to place in the
  // output
  MDImplicitFunction *function =
      this->getImplicitFunctionForChunk(nullptr, nullptr);

  std::vector<API::IMDNode *> boxes;
  // Leaf-only; no depth limit; with the implicit function passed to it.
  ws->getBox()->getBoxes(boxes, 1000, true, function);
  // Sort boxes by file position IF file backed. This reduces seeking time,
  // hopefully.
  bool fileBackedWS = bc->isFileBacked();
  if (fileBackedWS)
    API::IMDNode::sortObjByID(boxes);

  auto prog = new Progress(this, 0.0, 1.0, boxes.size());

  // The root of the output workspace
  MDBoxBase<OMDE, ond> *outRootBox = outWS->getBox();

  // if target workspace has events, we should count them as added
  uint64_t totalAdded = outWS->getNEvents();
  uint64_t numSinceSplit = 0;

  // Go through every box for this chunk.
  // PARALLEL_FOR_IF( !bc->isFileBacked() )
  for (int i = 0; i < int(boxes.size()); i++) {
    MDBox<MDE, nd> *box = dynamic_cast<MDBox<MDE, nd> *>(boxes[i]);
    // Perform the binning in this separate method.
    if (box && !box->getIsMasked()) {
      // An array to hold the rotated/transformed coordinates
      coord_t outCenter[ond];

      const std::vector<MDE> &events = box->getConstEvents();

      for (auto it = events.cbegin(); it != events.cend(); ++it) {
        // Cache the center of the event (again for speed)
        const coord_t *inCenter = it->getCenter();

        if (function->isPointContained(inCenter)) {
          // Now transform to the output dimensions
          m_transformFromOriginal->apply(inCenter, outCenter);

          // Create the event
          OMDE newEvent(it->getSignal(), it->getErrorSquared(), outCenter);
          // Copy extra data, if any
          copyEvent(*it, newEvent);
          // Add it to the workspace
          if (outRootBox->addEvent(newEvent))
            numSinceSplit++;
        }
      }
      box->releaseEvents();

      // Ask BC if one needs to split boxes
      if (obc->shouldSplitBoxes(totalAdded, numSinceSplit, lastNumBoxes))
      // if (numSinceSplit > 20000000 || (i == int(boxes.size()-1)))
      {
        // This splits up all the boxes according to split thresholds and sizes.
        Kernel::ThreadScheduler *ts = new ThreadSchedulerFIFO();
        ThreadPool tp(ts);
        outWS->splitAllIfNeeded(ts);
        tp.joinAll();
        // Accumulate stats
        totalAdded += numSinceSplit;
        numSinceSplit = 0;
        lastNumBoxes = obc->getTotalNumMDBoxes();
        // Progress reporting
        if (!fileBackedWS)
          prog->report(i);
      }
      if (fileBackedWS) {
        if (!(i % 10))
          prog->report(i);
      }
    } // is box

  } // for each box in the vector
  prog->report();

  outWS->splitAllIfNeeded(nullptr);
  // Refresh all cache.
  outWS->refreshCache();

  // Account for events that were added after the last split
  totalAdded += numSinceSplit;
  g_log.notice() << totalAdded << " " << OMDE::getTypeName()
                 << "s added to the output workspace.\n";

  if (outWS->isFileBacked()) {
    // Update the file-back-end
    g_log.notice() << "Running SaveMD\n";
    IAlgorithm_sptr alg = createChildAlgorithm("SaveMD");
    alg->setProperty("UpdateFileBackEnd", true);
    alg->setProperty("InputWorkspace", outWS);
    alg->executeAsChildAlg();
  }

  // Pass on the display normalization from the input event workspace to the
  // output event workspace
  IMDEventWorkspace_sptr outEvent =
      boost::dynamic_pointer_cast<IMDEventWorkspace>(outWS);
  outEvent->setDisplayNormalization(ws->displayNormalization());
  outEvent->setDisplayNormalizationHisto(ws->displayNormalizationHisto());
  // return the size of the input workspace write buffer to its initial value
  // bc->setCacheParameters(sizeof(MDE),writeBufSize);
  this->setProperty("OutputWorkspace", outEvent);
  delete prog;
}
Example #15
0
/** Execute the algorithm.
 */
void SaveIsawUB::exec() {
  try {
    Workspace_sptr ws1 = getProperty("InputWorkspace");
    ExperimentInfo_sptr ws;
    IMDEventWorkspace_sptr MDWS =
        boost::dynamic_pointer_cast<IMDEventWorkspace>(ws1);
    if (MDWS != nullptr) {
      ws = MDWS->getExperimentInfo(0);
    } else {
      ws = boost::dynamic_pointer_cast<ExperimentInfo>(ws1);
    }

    if (!ws)
      throw std::invalid_argument("Must specify either a MatrixWorkspace or a "
                                  "PeaksWorkspace or a MDEventWorkspace.");

    if (!ws->sample().hasOrientedLattice())
      throw std::invalid_argument(
          "Workspace must have an oriented lattice to save");

    std::string Filename = getProperty("Filename");

    ofstream out;
    out.open(Filename.c_str());

    OrientedLattice lattice = ws->sample().getOrientedLattice();
    Kernel::DblMatrix ub = lattice.getUB();

    // Write the ISAW UB matrix
    const int beam = 2;
    const int up = 1;
    const int back = 0;
    out << fixed;

    for (size_t basis = 0; basis < 3; basis++) {
      out << setw(11) << setprecision(8) << ub[beam][basis] << setw(12)
          << setprecision(8) << ub[back][basis] << setw(12) << setprecision(8)
          << ub[up][basis] << " \n";
    }

    out << setw(11) << setprecision(4) << lattice.a() << setw(12)
        << setprecision(4) << lattice.b() << setw(12) << setprecision(4)
        << lattice.c() << setw(12) << setprecision(4) << lattice.alpha()
        << setw(12) << setprecision(4) << lattice.beta() << setw(12)
        << setprecision(4) << lattice.gamma() << setw(12) << setprecision(4)
        << lattice.volume() << " \n";
    double ErrorVolume = getErrorVolume(lattice);
    out << setw(11) << setprecision(4) << lattice.errora() << setw(12)
        << setprecision(4) << lattice.errorb() << setw(12) << setprecision(4)
        << lattice.errorc() << setw(12) << setprecision(4)
        << lattice.erroralpha() << setw(12) << setprecision(4)
        << lattice.errorbeta() << setw(12) << setprecision(4)
        << lattice.errorgamma() << setw(12) << setprecision(4) << ErrorVolume
        << " \n";

    out << "\n\n";

    out << "The above matrix is the Transpose of the UB Matrix. ";
    out << "The UB matrix maps the column\n";
    out << "vector (h,k,l ) to the column vector ";
    out << "(q'x,q'y,q'z).\n";
    out << "|Q'|=1/dspacing and its coordinates are a ";
    out << "right-hand coordinate system where\n";
    out << " x is the beam direction and z is vertically ";
    out << "upward.(IPNS convention)\n";

    out.close();

  } catch (exception &s) {
    throw std::invalid_argument(s.what());
  }
}
/** 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);
}