/** 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)); } }
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); }
/** 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); }
/** * 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(); }
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); }
/** 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); } }
/** 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)); }