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