/** Make dimensions from the currently selected input workspace. Also fills the inputs with default values. @param propertyPrefix: The prefix for the property in the algorithm, i.e. AxisAligned. @param owningLayout: The layout that will take ownership of the widgets once generated. @param format: function pointer to the formatting function @param history : Whether to remember of forget property history. */ void SlicingAlgorithmDialog::makeDimensionInputs( const QString &propertyPrefix, QLayout *owningLayout, QString (*format)(IMDDimension_const_sptr), History history) { // Remove excess dimensions from the tied properties and the stored property // values size_t indexRemoved = 0; QString propertyNameRemoved = propertyPrefix; propertyNameRemoved.append(QString().number(indexRemoved)); Mantid::Kernel::Property *propertyRemoved = getAlgorithmProperty(propertyNameRemoved); while (propertyRemoved) { untie(propertyNameRemoved); removePropertyValue(propertyNameRemoved); indexRemoved++; propertyNameRemoved = propertyPrefix; propertyNameRemoved.append(QString().number(indexRemoved)); propertyRemoved = getAlgorithmProperty(propertyNameRemoved); } const QString &txt = getCurrentInputWorkspaceName(); if (!txt.isEmpty()) { IMDWorkspace_sptr ws = boost::dynamic_pointer_cast<IMDWorkspace>( AnalysisDataService::Instance().retrieve(txt.toStdString())); size_t nDimensions = ws->getNumDims(); for (size_t index = 0; index < nDimensions; ++index) { Mantid::Geometry::IMDDimension_const_sptr dim = ws->getDimension(index); // Configure the label QString propertyName = propertyPrefix; propertyName.append(QString().number(index)); QLabel *dimensionLabel = new QLabel(propertyName); // Configure the default input. const QString dimensionInfo = format(dim); QLineEdit *txtDimension = new QLineEdit(dimensionInfo); // Create a widget to contain the dimension components. QHBoxLayout *layout = new QHBoxLayout; QWidget *w = new QWidget; w->setLayout(layout); tie(txtDimension, propertyName, layout, (history == Remember)); // Add components to the layout. layout->addWidget(dimensionLabel); layout->addWidget(txtDimension); owningLayout->addWidget(w); } } }
std::map<std::string, std::string> MaskMD::validateInputs() { // Create the map std::map<std::string, std::string> validation_output; // Get properties to validate IMDWorkspace_sptr ws = getProperty("Workspace"); std::string dimensions_string = getPropertyValue("Dimensions"); std::vector<double> extents = getProperty("Extents"); std::vector<std::string> dimensions = parseDimensionNames(dimensions_string); std::stringstream messageStream; // Check named dimensions can be found in workspace for (const auto &dimension_name : dimensions) { try { tryFetchDimensionIndex(ws, dimension_name); } catch (const std::runtime_error &) { messageStream << "Dimension '" << dimension_name << "' not found. "; } } if (messageStream.rdbuf()->in_avail() != 0) { validation_output["Dimensions"] = messageStream.str(); messageStream.str(std::string()); } size_t nDims = ws->getNumDims(); size_t nDimensionIds = dimensions.size(); // Check cardinality on names/ids if (nDimensionIds % nDims != 0) { messageStream << "Number of dimension ids/names must be n * " << nDims << ". The following names were given: "; for (const auto &name : dimensions) { messageStream << name << ", "; } validation_output["Dimensions"] = messageStream.str(); messageStream.str(std::string()); } // Check cardinality on extents if (extents.size() != (2 * dimensions.size())) { messageStream << "Number of extents must be " << 2 * dimensions.size() << ". "; validation_output["Extents"] = messageStream.str(); } // Check extent value provided. for (size_t i = 0; (i < nDimensionIds) && ((i * 2 + 1) < extents.size()); ++i) { double min = extents[i * 2]; double max = extents[(i * 2) + 1]; if (min > max) { messageStream << "Cannot have minimum extents " << min << " larger than maximum extents " << max << ". "; validation_output["Extents"] = messageStream.str(); } } return validation_output; }
/** Execute the algorithm. */ void MaskMD::exec() { IMDWorkspace_sptr ws = getProperty("Workspace"); std::string dimensions_string = getPropertyValue("Dimensions"); std::vector<double> extents = getProperty("Extents"); // Dimension names may contain brackets with commas (i.e. [H,0,0]) // so getProperty would return an incorrect vector of names; // instead get the string and parse it here std::vector<std::string> dimensions = parseDimensionNames(dimensions_string); // Report what dimension names were found g_log.debug() << "Dimension names parsed as: \n"; for (const auto &name : dimensions) { g_log.debug() << name << '\n'; } size_t nDims = ws->getNumDims(); size_t nDimensionIds = dimensions.size(); size_t nGroups = nDimensionIds / nDims; bool bClearExistingMasks = getProperty("ClearExistingMasks"); if (bClearExistingMasks) { ws->clearMDMasking(); } this->interruption_point(); this->progress(0.0); // Explicitly cast nGroups and group to double to avoid compiler warnings // loss of precision does not matter as we are only using the result // for reporting algorithm progress const double nGroups_double = static_cast<double>(nGroups); // Loop over all groups for (size_t group = 0; group < nGroups; ++group) { std::vector<InputArgument> arguments(nDims); // Loop over all arguments within the group. and construct InputArguments // for sorting. for (size_t i = 0; i < nDims; ++i) { size_t index = i + (group * nDims); InputArgument &arg = arguments[i]; // Try to get the index of the dimension in the workspace. arg.index = tryFetchDimensionIndex(ws, dimensions[index]); arg.min = extents[index * 2]; arg.max = extents[(index * 2) + 1]; } // Sort all the inputs by the dimension index. Without this it will not be // possible to construct the MDImplicit function property. LessThanIndex comparator; std::sort(arguments.begin(), arguments.end(), comparator); // Create inputs for a box implicit function VMD mins(nDims); VMD maxs(nDims); for (size_t i = 0; i < nDims; ++i) { mins[i] = float(arguments[i].min); maxs[i] = float(arguments[i].max); } // Add new masking. ws->setMDMasking(new MDBoxImplicitFunction(mins, maxs)); this->interruption_point(); double group_double = static_cast<double>(group); this->progress(group_double / nGroups_double); } this->progress(1.0); // Ensure algorithm progress is reported as complete }
//---------------------------------------------------------------------------------------------- /// Run the algorithm void QueryMDWorkspace::exec() { // Extract the required normalisation. std::string strNormalisation = getPropertyValue("Normalisation"); MDNormalization requestedNormalisation = whichNormalisation(strNormalisation); IMDWorkspace_sptr input = getProperty("InputWorkspace"); const bool transformCoordsToOriginal = getProperty("TransformCoordsToOriginal"); // Define a table workspace with a specific column schema. ITableWorkspace_sptr output = WorkspaceFactory::Instance().createTable(); const std::string signalColumnName = "Signal/" + strNormalisation; const std::string errorColumnName = "Error/" + strNormalisation; output->addColumn("double", signalColumnName); output->addColumn("double", errorColumnName); output->addColumn("int", "Number of Events"); const size_t ndims = input->getNumDims(); for (size_t index = 0; index < ndims; ++index) { Mantid::Geometry::IMDDimension_const_sptr dim = input->getDimension(index); std::string dimInUnit = dim->getName() + "/" + dim->getUnits().ascii(); output->addColumn("double", dimInUnit); // Magic numbers required to configure the X axis. output->getColumn(dimInUnit)->setPlotType(1); } // Magic numbers required to configure the Y axis. output->getColumn(signalColumnName)->setPlotType(2); output->getColumn(errorColumnName)->setPlotType(5); IMDIterator *it = input->createIterator(); it->setNormalization(requestedNormalisation); bool bLimitRows = getProperty("LimitRows"); int maxRows = 0; if (bLimitRows) { maxRows = getProperty("MaximumRows"); } // Use the iterator to loop through each MDBoxBase and create a row for each // entry. int rowCounter = 0; Progress progress(this, 0, 1, int64_t(input->getNPoints())); while (true) { size_t cellIndex = 0; output->appendRow(); output->cell<double>(rowCounter, cellIndex++) = it->getNormalizedSignal(); output->cell<double>(rowCounter, cellIndex++) = it->getNormalizedError(); output->cell<int>(rowCounter, cellIndex++) = int(it->getNumEvents()); VMD center = it->getCenter(); const size_t numberOriginal = input->getNumberTransformsToOriginal(); if (transformCoordsToOriginal && numberOriginal > 0) { const size_t index = numberOriginal - 1; CoordTransform const *transform = input->getTransformToOriginal(index); VMD temp = transform->applyVMD(center); center = temp; } for (size_t index = 0; index < ndims; ++index) { output->cell<double>(rowCounter, cellIndex++) = center[index]; } progress.report(); if (!it->next() || (bLimitRows && ((rowCounter + 1) >= maxRows))) { break; } rowCounter++; } setProperty("OutputWorkspace", output); delete it; // IMDEventWorkspace_sptr mdew; CALL_MDEVENT_FUNCTION(this->getBoxData, input); }
/** Execute the algorithm. */ void MaskMD::exec() { IMDWorkspace_sptr ws = getProperty("Workspace"); std::vector<std::string> dimensions = getProperty("Dimensions"); std::vector<double> extents = getProperty("Extents"); size_t nDims = ws->getNumDims(); size_t nDimensionIds = dimensions.size(); std::stringstream messageStream; // Check cardinality on names/ids if (nDimensionIds % nDims != 0) { messageStream << "Number of dimension ids/names must be n * " << nDims; this->g_log.error(messageStream.str()); throw std::invalid_argument(messageStream.str()); } // Check cardinality on extents if (extents.size() != (2 * dimensions.size())) { messageStream << "Number of extents must be " << 2 * dimensions.size(); this->g_log.error(messageStream.str()); throw std::invalid_argument(messageStream.str()); } // Check extent value provided. for (size_t i = 0; i < nDimensionIds; ++i) { double min = extents[i * 2]; double max = extents[(i * 2) + 1]; if (min > max) { messageStream << "Cannot have minimum extents " << min << " larger than maximum extents " << max; this->g_log.error(messageStream.str()); throw std::invalid_argument(messageStream.str()); } } size_t nGroups = nDimensionIds / nDims; bool bClearExistingMasks = getProperty("ClearExistingMasks"); if (bClearExistingMasks) { ws->clearMDMasking(); } // Loop over all groups for (size_t group = 0; group < nGroups; ++group) { std::vector<InputArgument> arguments(nDims); // Loop over all arguments within the group. and construct InputArguments // for sorting. for (size_t i = 0; i < nDims; ++i) { size_t index = i + (group * nDims); InputArgument &arg = arguments[i]; // Try to get the index of the dimension in the workspace. arg.index = tryFetchDimensionIndex(ws, dimensions[index]); arg.min = extents[index * 2]; arg.max = extents[(index * 2) + 1]; } // Sort all the inputs by the dimension index. Without this it will not be // possible to construct the MDImplicit function propertly. LessThanIndex comparitor; std::sort(arguments.begin(), arguments.end(), comparitor); // Create inputs for a box implicit function VMD mins(nDims); VMD maxs(nDims); for (size_t i = 0; i < nDims; ++i) { mins[i] = float(arguments[i].min); maxs[i] = float(arguments[i].max); } // Add new masking. ws->setMDMasking(new MDBoxImplicitFunction(mins, maxs)); } }