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