Exemple #1
0
  /**
  Overlay the overlap 1D workspace over the original 1D workspace. overlap shouuld overwrite values on the sum workspace.
  @param original : Original 1D workspace to be overwritten only in the region of the overlap.
  @param overlap : Overlap 1D workspace to overwrite with
  */
  void Stitch1DMD::overlayOverlap(MDHistoWorkspace_sptr original, IMDHistoWorkspace_sptr overlap)
  {
    const auto targetDim = original->getDimension(0);
    const double targetQMax = targetDim->getMaximum();
    const double targetQMin = targetDim->getMinimum();
    const size_t targetNbins = targetDim->getNBins();
    const double targetStep = double(targetNbins) / (targetQMax - targetQMin); 
    const double targetC = -1 * targetStep * targetQMin;

    const auto overlapDim = overlap->getDimension(0);
    const double overlapQMax = overlapDim->getMaximum();
    const double overlapQMin = overlapDim->getMinimum();
    const size_t overlapNBins = overlapDim->getNBins();
    const double overlapStep = (overlapQMax - overlapQMin) / double(overlapNBins);
    const double overlapC = overlapQMin;

    for(size_t i = 0; i < overlapNBins; ++i)
    {
      // Calculate the q value for each index in the overlap region.
      const double q = (overlapStep * double(i)) + overlapC;
      // Find the target index by recentering (adding 0.5) and then truncating to an integer.
      size_t targetIndex = size_t((targetStep * q) + targetC + 0.5) ;
      // Overwrite signal
      original->setSignalAt(targetIndex, overlap->signalAt(i));
      // Overwrite error
      original->setErrorSquaredAt(targetIndex, overlap->errorSquaredAt(i));
    }
  }
Exemple #2
0
void SliceMDHisto::cutData(Mantid::API::IMDHistoWorkspace_sptr inWS,
                           Mantid::API::IMDHistoWorkspace_sptr outWS,
                           Mantid::coord_t *sourceDim,
                           Mantid::coord_t *targetDim, std::vector<int> start,
                           std::vector<int> end, unsigned int dim) {
  int length;

  boost::shared_ptr<const IMDDimension> inDim = inWS->getDimension(dim);
  boost::shared_ptr<const IMDDimension> outDim = outWS->getDimension(dim);
  length = end[dim] - start[dim];
  if (dim == m_rank - 1) {
    MDHistoWorkspace_sptr outWSS =
        boost::dynamic_pointer_cast<MDHistoWorkspace>(outWS);
    for (int i = 0; i < length; i++) {
      sourceDim[dim] = inDim->getX(start[dim] + i);
      signal_t val = inWS->getSignalAtCoord(
          sourceDim, static_cast<Mantid::API::MDNormalization>(0));
      targetDim[dim] = outDim->getX(i);
      size_t idx = outWSS->getLinearIndexAtCoord(targetDim);
      outWS->setSignalAt(idx, val);
      outWS->setErrorSquaredAt(idx, val);
    }
  } else {
    for (int i = 0; i < length; i++) {
      sourceDim[dim] = inDim->getX(start[dim] + i);
      targetDim[dim] = outDim->getX(i);
      cutData(inWS, outWS, sourceDim, targetDim, start, end, dim + 1);
    }
  }
}
  /** Execute the algorithm.
   */
  void CreateMDHistoWorkspace::exec()
  {
     MDHistoWorkspace_sptr ws = this->createEmptyOutputWorkspace();
     double* signals = ws->getSignalArray();
     double* errors = ws->getErrorSquaredArray();

     std::vector<double> signalValues = getProperty("SignalInput");
     std::vector<double> errorValues = getProperty("ErrorInput");

     size_t binProduct = this->getBinProduct();
     std::stringstream stream;
     stream << binProduct;
     if(binProduct != signalValues.size())
     {
       throw std::invalid_argument("Expected size of the SignalInput is: " + stream.str() );
     }
     if(binProduct != errorValues.size())
     {
       throw std::invalid_argument("Expected size of the ErrorInput is: " + stream.str() );
     }

     //Copy from property
     std::copy(signalValues.begin(), signalValues.end(), signals);
     std::vector<double> empty;
     //Clean up.
     signalValues.swap(empty);
     //Copy from property
     std::for_each(errorValues.begin(), errorValues.end(), Square());
     std::copy(errorValues.begin(), errorValues.end(), errors);
     //Clean up
     errorValues.swap(empty);

     setProperty("OutputWorkspace", ws);

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

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

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

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

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

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

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

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

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

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

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

  this->setProperty("OutputWorkspace", outWS);
}
Exemple #5
0
/**
* Load a slab of double data into a bare array.
* Checks that the size is correct.
* @param name
* @param data bare pointer to double array
* @param ws
* @param dataType
*/
void LoadMD::loadSlab(std::string name, void *data, MDHistoWorkspace_sptr ws,
                      NeXus::NXnumtype dataType) {
  m_file->openData(name);
  if (m_file->getInfo().type != dataType)
    throw std::runtime_error("Unexpected data type for '" + name +
                             "' data set.'");

  int nPoints = 1;
  size_t numDims = m_file->getInfo().dims.size();
  std::vector<int> size(numDims);
  for (size_t d = 0; d < numDims; d++) {
    nPoints *= static_cast<int>(m_file->getInfo().dims[d]);
    size[d] = static_cast<int>(m_file->getInfo().dims[d]);
  }
  if (nPoints != static_cast<int>(ws->getNPoints()))
    throw std::runtime_error(
        "Inconsistency between the number of points in '" + name +
        "' and the number of bins defined by the dimensions.");
  std::vector<int> start(numDims, 0);
  try {
    m_file->getSlab(data, start, size);
  } catch (...) {
    std::cout << " start: " << start[0] << " size: " << size[0] << '\n';
  }
  m_file->closeData();
}
Exemple #6
0
void SINQHMListener::recurseDim(int *data, IMDHistoWorkspace_sptr ws,
                                int currentDim, coord_t *idx) {
  if (currentDim == rank) {
    int Cindex = calculateCAddress(idx);
    int val = data[Cindex];
    MDHistoWorkspace_sptr mdws =
        boost::dynamic_pointer_cast<MDHistoWorkspace>(ws);
    size_t F77index = mdws->getLinearIndexAtCoord(idx);
    mdws->setSignalAt(F77index, signal_t(val));
    mdws->setErrorSquaredAt(F77index, signal_t(val));
  } else {
    for (int i = 0; i < dim[currentDim]; i++) {
      idx[currentDim] = static_cast<coord_t>(i);
      recurseDim(data, ws, currentDim + 1, idx);
    }
  }
}
void SINQTranspose3D::doTRICS(IMDHistoWorkspace_sptr inWS)
{
	double *inVal, *inErr, *outVal, *outErr;
	size_t idxIn, idxOut;
	unsigned int xdim, ydim, zdim;

	boost::shared_ptr<const IMDDimension> x,y,z;
	x = inWS->getXDimension();
	y = inWS->getYDimension();
	z = inWS->getZDimension();

	std::vector<IMDDimension_sptr> dimensions;
    dimensions.push_back(boost::const_pointer_cast<IMDDimension>(x));
    dimensions.push_back(boost::const_pointer_cast<IMDDimension>(z));
    dimensions.push_back(boost::const_pointer_cast<IMDDimension>(y));

    MDHistoWorkspace_sptr outWS (new MDHistoWorkspace(dimensions));
    outWS->setTo(.0,.0,.0);

    inVal = inWS->getSignalArray();
    inErr = inWS->getErrorSquaredArray();
    outVal = outWS->getSignalArray();
    outErr = outWS->getErrorSquaredArray();
    xdim = static_cast<unsigned int>(x->getNBins());
    ydim = static_cast<unsigned int>(y->getNBins());
    zdim = static_cast<unsigned int>(z->getNBins());
    for(unsigned int xx = 0; xx < xdim; xx++){
    	for(unsigned int yy= 0; yy < ydim; yy++){
    		for(unsigned int zz = 0; zz <  zdim; zz++){
    			idxIn = ydim*zdim*xx + zdim*yy + zz; // this works for TRICS
    			idxOut = outWS->getLinearIndex(xx,zz,yy);
    			outVal[idxOut] = inVal[idxIn];
    			outErr[idxOut] = inErr[idxIn];
    		}
    	}
    }
    copyMetaData(inWS, outWS);

    // assign the workspace
	setProperty("OutputWorkspace",outWS);

}
void SINQTranspose3D::doYXZ(IMDHistoWorkspace_sptr inWS)
{
	double *inVal, *inErr, *outVal, *outErr;
	size_t idxIn, idxOut;

	boost::shared_ptr<const IMDDimension> x,y,z;
	x = inWS->getXDimension();
	y = inWS->getYDimension();
	z = inWS->getZDimension();

	std::vector<IMDDimension_sptr> dimensions;
    dimensions.push_back(boost::const_pointer_cast<IMDDimension>(y));
    dimensions.push_back(boost::const_pointer_cast<IMDDimension>(x));
    dimensions.push_back(boost::const_pointer_cast<IMDDimension>(z));

    MDHistoWorkspace_sptr outWS (new MDHistoWorkspace(dimensions));

    inVal = inWS->getSignalArray();
    inErr = inWS->getErrorSquaredArray();
    outVal = outWS->getSignalArray();
    outErr = outWS->getErrorSquaredArray();
    for(unsigned int xx = 0; xx < x->getNBins(); xx++){
    	for(unsigned int yy= 0; yy < y->getNBins(); yy++){
    		for(unsigned int zz = 0; zz <  z->getNBins(); zz++){
    			idxIn = inWS->getLinearIndex(xx,yy,zz);
    			idxOut = outWS->getLinearIndex(yy,xx,zz);
    			outVal[idxOut] = inVal[idxIn];
    			outErr[idxOut] = inErr[idxIn];
    		}
    	}
    }
    copyMetaData(inWS, outWS);

    // assign the workspace
	setProperty("OutputWorkspace",outWS);


}
void SINQTranspose3D::doAMOR(IMDHistoWorkspace_sptr inWS)
{
	double val, *inVal;
	unsigned int xdim, ydim, zdim, idx;

	boost::shared_ptr<const IMDDimension> x,y,z;
	x = inWS->getXDimension();
	y = inWS->getYDimension();
	z = inWS->getZDimension();

	std::vector<IMDDimension_sptr> dimensions;
    dimensions.push_back(boost::const_pointer_cast<IMDDimension>(y));
    dimensions.push_back(boost::const_pointer_cast<IMDDimension>(x));
    dimensions.push_back(boost::const_pointer_cast<IMDDimension>(z));

    MDHistoWorkspace_sptr outWS (new MDHistoWorkspace(dimensions));
    outWS->setTo(.0,.0,.0);

    xdim = static_cast<unsigned int>(x->getNBins());
    ydim = static_cast<unsigned int>(y->getNBins());
    zdim = static_cast<unsigned int>(z->getNBins());
    inVal = inWS->getSignalArray();
    for(unsigned int xx = 0; xx < xdim; xx++){
    	for(unsigned int yy = 0; yy < ydim; yy++){
    		for(unsigned zz = 0; zz < zdim; zz++){
    			//idx = ydim*zdim*xx + zdim*yy + zz;
    			idx = ydim*zdim*xx + zdim*yy + zz;
    			val = inVal[idx];
    			outWS->setSignalAt(outWS->getLinearIndex(yy,xx,zz),val);
    			outWS->setErrorSquaredAt(outWS->getLinearIndex(yy,xx,zz),val);
    		}
    	}
    }

    copyMetaData(inWS, outWS);

    // assign the workspace
	setProperty("OutputWorkspace",outWS);

}
Exemple #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);
  }
}
Exemple #11
0
/** Perform loading for a MDHistoWorkspace.
* The entry should be open already.
*/
void LoadMD::loadHisto() {
  // Create the initial MDHisto.
  MDHistoWorkspace_sptr ws;
  // If display normalization has been provided. Use that.
  if (m_visualNormalization) {
    ws = boost::make_shared<MDHistoWorkspace>(m_dims,
                                              m_visualNormalization.get());
  } else {
    ws = boost::make_shared<MDHistoWorkspace>(
        m_dims); // Whatever MDHistoWorkspace defaults to.
  }

  // Now the ExperimentInfo
  MDBoxFlatTree::loadExperimentInfos(m_file.get(), m_filename, ws);

  // Coordinate system
  ws->setCoordinateSystem(m_coordSystem);

  // Load the WorkspaceHistory "process"
  if (this->getProperty("LoadHistory")) {
    ws->history().loadNexus(m_file.get());
  }

  this->loadAffineMatricies(boost::dynamic_pointer_cast<IMDWorkspace>(ws));

  if (m_saveMDVersion == 2)
    m_file->openGroup("data", "NXdata");
  // Load each data slab
  this->loadSlab("signal", ws->getSignalArray(), ws, ::NeXus::FLOAT64);
  this->loadSlab("errors_squared", ws->getErrorSquaredArray(), ws,
                 ::NeXus::FLOAT64);
  this->loadSlab("num_events", ws->getNumEventsArray(), ws, ::NeXus::FLOAT64);
  this->loadSlab("mask", ws->getMaskArray(), ws, ::NeXus::INT8);

  m_file->close();

  // Check if a MDFrame adjustment is required
  checkForRequiredLegacyFixup(ws);
  if (m_requiresMDFrameCorrection) {
    setMDFrameOnWorkspaceFromLegacyFile(ws);
  }

  // Write out the Qconvention
  // ki-kf for Inelastic convention; kf-ki for Crystallography convention
  std::string pref_QConvention =
      Kernel::ConfigService::Instance().getString("Q.convention");
  g_log.information() << "Convention for Q in Preferences is "
                      << pref_QConvention
                      << "; Convention of Q in NeXus file is " << m_QConvention
                      << '\n';

  if (pref_QConvention != m_QConvention) {
    std::vector<double> scaling(m_numDims);
    scaling = qDimensions(ws);
    g_log.information() << "Transforming Q\n";
    Algorithm_sptr transform_alg = createChildAlgorithm("TransformMD");
    transform_alg->setProperty("InputWorkspace",
                               boost::dynamic_pointer_cast<IMDWorkspace>(ws));
    transform_alg->setProperty("Scaling", scaling);
    transform_alg->executeAsChildAlg();
    IMDWorkspace_sptr tmp = transform_alg->getProperty("OutputWorkspace");
    ws = boost::dynamic_pointer_cast<MDHistoWorkspace>(tmp);
  }

  // Save to output
  setProperty("OutputWorkspace", boost::dynamic_pointer_cast<IMDWorkspace>(ws));
}