/** * Generate the vtkDataSet from the objects input IMDEventWorkspace * @param progressUpdating : Reporting object to pass progress information up the stack. * @return fully constructed vtkDataSet. */ vtkDataSet* vtkSplatterPlotFactory::create(ProgressAction& progressUpdating) const { UNUSED_ARG(progressUpdating); // If initialize() wasn't run, we don't have a workspace. if(!m_workspace) { throw std::runtime_error("Invalid vtkSplatterPlotFactory. Workspace is null"); } size_t nd = m_workspace->getNumDims(); Mantid::Kernel::ReadLock lock(*m_workspace); if (nd > 3) { // Slice from >3D down to 3D this->slice = true; this->sliceMask = new bool[nd]; this->sliceImplicitFunction = new MDImplicitFunction(); // Make the mask of dimensions // TODO: Smarter mapping for (size_t d = 0; d < nd; d++) this->sliceMask[d] = (d < 3); // Define where the slice is in 4D // TODO: Where to slice? Right now is just 0 std::vector<coord_t> point(nd, 0); point[3] = coord_t(m_time); //Specifically for 4th/time dimension. // 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 0-thickness region to slice in. sliceImplicitFunction->addPlane(MDPlane(normal1, point)); sliceImplicitFunction->addPlane(MDPlane(normal2, point)); } else { // Direct 3D, so no slicing this->slice = false; } // Macro to call the right instance of the CALL_MDEVENT_FUNCTION(this->doCreate, m_workspace); // Clean up if (this->slice) { delete[] this->sliceMask; delete this->sliceImplicitFunction; } // The macro does not allow return calls, so we used a member variable. return this->dataSet; }
/** Execute the algorithm. */ void FakeMDEventData::exec() { IMDEventWorkspace_sptr in_ws = getProperty("InputWorkspace"); if (getPropertyValue("UniformParams") == "" && getPropertyValue("PeakParams") == "") throw std::invalid_argument( "You must specify at least one of PeakParams or UniformParams."); setupDetectorCache(*in_ws); CALL_MDEVENT_FUNCTION(this->addFakePeak, in_ws) CALL_MDEVENT_FUNCTION(this->addFakeUniformData, in_ws) // Mark that events were added, so the file back end (if any) needs updating in_ws->setFileNeedsUpdating(true); }
/** 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); }