/** * Calculates binning parameters. */ void Iqt::calculateBinning() { using namespace Mantid::API; disconnect(m_dblManager, SIGNAL(valueChanged(QtProperty *, double)), this, SLOT(updatePropertyValues(QtProperty *, double))); QString wsName = m_uiForm.dsInput->getCurrentDataName(); QString resName = m_uiForm.dsResolution->getCurrentDataName(); if (wsName.isEmpty() || resName.isEmpty()) return; double energyMin = m_dblManager->value(m_properties["ELow"]); double energyMax = m_dblManager->value(m_properties["EHigh"]); double numBins = m_dblManager->value(m_properties["SampleBinning"]); if (numBins == 0) return; IAlgorithm_sptr furyAlg = AlgorithmManager::Instance().create("TransformToIqt"); furyAlg->initialize(); furyAlg->setProperty("SampleWorkspace", wsName.toStdString()); furyAlg->setProperty("ResolutionWorkspace", resName.toStdString()); furyAlg->setProperty("ParameterWorkspace", "__FuryProperties_temp"); furyAlg->setProperty("EnergyMin", energyMin); furyAlg->setProperty("EnergyMax", energyMax); furyAlg->setProperty("BinReductionFactor", numBins); furyAlg->setProperty("DryRun", true); furyAlg->execute(); // Get property table from algorithm ITableWorkspace_sptr propsTable = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>( "__FuryProperties_temp"); // Get data from property table double energyWidth = propsTable->getColumn("EnergyWidth")->cell<float>(0); int sampleBins = propsTable->getColumn("SampleOutputBins")->cell<int>(0); int resolutionBins = propsTable->getColumn("ResolutionBins")->cell<int>(0); // Update data in property editor m_dblManager->setValue(m_properties["EWidth"], energyWidth); m_dblManager->setValue(m_properties["ResolutionBins"], resolutionBins); m_dblManager->setValue(m_properties["SampleBins"], sampleBins); connect(m_dblManager, SIGNAL(valueChanged(QtProperty *, double)), this, SLOT(updatePropertyValues(QtProperty *, double))); // Warn for low number of resolution bins int numResolutionBins = static_cast<int>(m_dblManager->value(m_properties["ResolutionBins"])); if (numResolutionBins < 5) showMessageBox("Number of resolution bins is less than 5.\nResults may be " "inaccurate."); }
/** * Creates a domain from an ITableWorkspace * * This method creates a LatticeDomain from a table workspace that contains two * columns, HKL and d. HKL can either be a V3D-column or a string column, * containing three integers separated by space, comma, semi-colon and * optionally surrounded by []. The d-column can be double or a string that can * be parsed as a double number. * * @param workspace :: ITableWorkspace with format specified above. * @param domain :: Pointer to outgoing FunctionDomain instance. * @param values :: Pointer to outgoing FunctionValues object. * @param i0 :: Size offset for values object if it already contains data. */ void LatticeDomainCreator::createDomainFromPeakTable( const ITableWorkspace_sptr &workspace, boost::shared_ptr<FunctionDomain> &domain, boost::shared_ptr<FunctionValues> &values, size_t i0) { size_t peakCount = workspace->rowCount(); if (peakCount < 1) { throw std::range_error("Cannot create a domain for 0 peaks."); } try { Column_const_sptr hklColumn = workspace->getColumn("HKL"); Column_const_sptr dColumn = workspace->getColumn("d"); std::vector<V3D> hkls; hkls.reserve(peakCount); std::vector<double> dSpacings; dSpacings.reserve(peakCount); V3DFromHKLColumnExtractor extractor; for (size_t i = 0; i < peakCount; ++i) { try { V3D hkl = extractor(hklColumn, i); if (hkl != V3D(0, 0, 0)) { hkls.push_back(hkl); double d = (*dColumn)[i]; dSpacings.push_back(d); } } catch (const std::bad_alloc &) { // do nothing. } } domain = boost::make_shared<LatticeDomain>(hkls); if (!values) { values = boost::make_shared<FunctionValues>(*domain); } else { values->expand(i0 + domain->size()); } values->setFitData(dSpacings); values->setFitWeights(1.0); } catch (const std::runtime_error &) { // Column does not exist throw std::runtime_error("Can not process table, the following columns are " "required: HKL, d."); } }
/** * Removes error columns from the table if all errors are zero, * as these columns correspond to fixed parameters. * @param table :: [input, output] Pointer to TableWorkspace to edit */ void MuonAnalysisResultTableCreator::removeFixedParameterErrors( const ITableWorkspace_sptr table) const { assert(table); const size_t nRows = table->rowCount(); const auto colNames = table->getColumnNames(); std::vector<std::string> zeroErrorColumns; for (const auto &name : colNames) { // if name does not end with "Error", continue const size_t nameLength = name.length(); if (nameLength < ERROR_LENGTH || name.compare(nameLength - ERROR_LENGTH, ERROR_LENGTH, ERROR_STRING)) { continue; } auto col = table->getColumn(name); bool allZeros = true; // Check if all values in the column are zero for (size_t iRow = 0; iRow < nRows; ++iRow) { const double val = col->toDouble(iRow); if (std::abs(val) > std::numeric_limits<double>::epsilon()) { allZeros = false; break; } } if (allZeros) { zeroErrorColumns.push_back(name); } } for (const auto &name : zeroErrorColumns) { table->removeColumn(name); } }
void ConvertTableToMatrixWorkspace::exec() { ITableWorkspace_sptr inputWorkspace = getProperty("InputWorkspace"); std::string columnX = getProperty("ColumnX"); std::string columnY = getProperty("ColumnY"); std::string columnE = getProperty("ColumnE"); size_t nrows = inputWorkspace->rowCount(); std::vector<double> X(nrows); std::vector<double> Y(nrows); std::vector<double> E(nrows); inputWorkspace->getColumn(columnX)->numeric_fill(X); inputWorkspace->getColumn(columnY)->numeric_fill(Y); if (!columnE.empty()) { inputWorkspace->getColumn(columnE)->numeric_fill(E); } else { E.assign(X.size(),1.0); } MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create("Workspace2D",1,X.size(),X.size()); outputWorkspace->dataX(0).assign(X.begin(),X.end()); outputWorkspace->dataY(0).assign(Y.begin(),Y.end()); outputWorkspace->dataE(0).assign(E.begin(),E.end()); outputWorkspace->generateSpectraMap(); boost::shared_ptr<Kernel::Units::Label> labelX = boost::dynamic_pointer_cast<Kernel::Units::Label>( Kernel::UnitFactory::Instance().create("Label") ); labelX->setLabel(columnX); outputWorkspace->getAxis(0)->unit() = labelX; outputWorkspace->setYUnitLabel(columnY); setProperty("OutputWorkspace", outputWorkspace); }
/** * Handles completion of the preview algorithm. * * @param error If the algorithm failed */ void IndirectSymmetrise::previewAlgDone(bool error) { if (error) return; QString workspaceName = m_uiForm.dsInput->getCurrentDataName(); int spectrumNumber = static_cast<int>(m_dblManager->value(m_properties["PreviewSpec"])); MatrixWorkspace_sptr sampleWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( workspaceName.toStdString()); ITableWorkspace_sptr propsTable = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>( "__SymmetriseProps_temp"); MatrixWorkspace_sptr symmWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( "__Symmetrise_temp"); // Get the index of XCut on each side of zero int negativeIndex = propsTable->getColumn("NegativeXMinIndex")->cell<int>(0); int positiveIndex = propsTable->getColumn("PositiveXMinIndex")->cell<int>(0); // Get the Y values for each XCut and the difference between them double negativeY = sampleWS->dataY(0)[negativeIndex]; double positiveY = sampleWS->dataY(0)[positiveIndex]; double deltaY = fabs(negativeY - positiveY); // Show values in property tree m_dblManager->setValue(m_properties["NegativeYValue"], negativeY); m_dblManager->setValue(m_properties["PositiveYValue"], positiveY); m_dblManager->setValue(m_properties["DeltaY"], deltaY); // Set indicator positions m_uiForm.ppRawPlot->getRangeSelector("NegativeEMinYPos") ->setMinimum(negativeY); m_uiForm.ppRawPlot->getRangeSelector("PositiveEMinYPos") ->setMinimum(positiveY); // Plot preview plot size_t spectrumIndex = symmWS->getIndexFromSpectrumNumber(spectrumNumber); m_uiForm.ppPreviewPlot->clear(); m_uiForm.ppPreviewPlot->addSpectrum("Symmetrised", "__Symmetrise_temp", spectrumIndex); // Don't want this to trigger when the algorithm is run for all spectra disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(previewAlgDone(bool))); }
/** * Write log and parameter values to the table for the case of a single fit. * @param table :: [input, output] Table to write to * @param paramsByLabel :: [input] Map of <label name, <workspace name, * <parameter, value>>> * @param paramsToDisplay :: [input] List of parameters to display in table */ void MuonAnalysisResultTableCreator::writeDataForSingleFit( ITableWorkspace_sptr &table, const QMap<QString, WSParameterList> ¶msByLabel, const QStringList ¶msToDisplay) const { assert(!m_multiple); assert(m_logValues); for (const auto &wsName : m_items) { Mantid::API::TableRow row = table->appendRow(); row << wsName.toStdString(); // Get log values for this row const auto &logValues = m_logValues->value(wsName); // Write log values in each column for (int i = 0; i < m_logs.size(); ++i) { Mantid::API::Column_sptr col = table->getColumn(i); const auto &log = m_logs[i]; const QVariant &val = logValues[log]; QString valueToWrite; // Special case: if log is time in sec, subtract the first start time if (log.endsWith(" (s)")) { auto seconds = val.toDouble() - static_cast<double>(m_firstStart_ns) * 1.e-9; valueToWrite = QString::number(seconds); } else if (MuonAnalysisHelper::isNumber(val.toString()) && !log.endsWith(" (text)")) { valueToWrite = QString::number(val.toDouble()); } else { valueToWrite = val.toString(); } if (MuonAnalysisHelper::isNumber(val.toString()) && !log.endsWith(" (text)")) { row << valueToWrite.toDouble(); } else { row << valueToWrite.toStdString(); } } // Add param values (params same for all workspaces) QMap<QString, double> paramsList = paramsByLabel.begin()->value(wsName); for (const auto ¶mName : paramsToDisplay) { row << paramsList[paramName]; } } }
/** * Sets a new preview spectrum for the mini plot. * * @param value workspace index */ void ResNorm::previewSpecChanged(int value) { m_previewSpec = value; // Update vanadium plot if (m_uiForm.dsVanadium->isValid()) m_uiForm.ppPlot->addSpectrum( "Vanadium", m_uiForm.dsVanadium->getCurrentDataName(), m_previewSpec); // Update fit plot std::string fitWsGroupName(m_pythonExportWsName + "_Fit_Workspaces"); std::string fitParamsName(m_pythonExportWsName + "_Fit"); if (AnalysisDataService::Instance().doesExist(fitWsGroupName)) { WorkspaceGroup_sptr fitWorkspaces = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>( fitWsGroupName); ITableWorkspace_sptr fitParams = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>( fitParamsName); if (fitWorkspaces && fitParams) { Column_const_sptr scaleFactors = fitParams->getColumn("Scaling"); std::string fitWsName(fitWorkspaces->getItem(m_previewSpec)->name()); MatrixWorkspace_const_sptr fitWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>( fitWsName); MatrixWorkspace_sptr fit = WorkspaceFactory::Instance().create(fitWs, 1); fit->setX(0, fitWs->readX(1)); fit->getSpectrum(0)->setData(fitWs->readY(1), fitWs->readE(1)); for (size_t i = 0; i < fit->blocksize(); i++) fit->dataY(0)[i] /= scaleFactors->cell<double>(m_previewSpec); m_uiForm.ppPlot->addSpectrum("Fit", fit, 0, Qt::red); } } }
/** * Executes the algorithm. */ void LoadTBL::exec() { std::string filename = getProperty("Filename"); std::ifstream file(filename.c_str()); if (!file) { throw Exception::FileError("Unable to open file: ", filename); } std::string line; ITableWorkspace_sptr ws = WorkspaceFactory::Instance().createTable(); std::vector<std::string> columnHeadings; Kernel::Strings::extractToEOL(file, line); // We want to check if the first line contains an empty string or series of // ",,,,," // to see if we are loading a TBL file that actually contains data or not. boost::split(columnHeadings, line, boost::is_any_of(","), boost::token_compress_off); for (auto entry = columnHeadings.begin(); entry != columnHeadings.end();) { if (entry->empty()) { // erase the empty values entry = columnHeadings.erase(entry); } else { // keep any non-empty values ++entry; } } if (columnHeadings.empty()) { // we have an empty string or series of ",,,,," throw std::runtime_error("The file you are trying to load is Empty. \n " "Please load a non-empty TBL file"); } else { // set columns back to empty ready to populated with columnHeadings. columnHeadings.clear(); } // this will tell us if we need to just fill in the cell values // or whether we will have to create the column headings as well. bool isOld = getColumnHeadings(line, columnHeadings); std::vector<std::string> rowVec; if (isOld) { /**THIS IS ESSENTIALLY THE OLD LoadReflTBL CODE**/ // create the column headings auto colStitch = ws->addColumn("str", "StitchGroup"); auto colRuns = ws->addColumn("str", "Run(s)"); auto colTheta = ws->addColumn("str", "ThetaIn"); auto colTrans = ws->addColumn("str", "TransRun(s)"); auto colQmin = ws->addColumn("str", "Qmin"); auto colQmax = ws->addColumn("str", "Qmax"); auto colDqq = ws->addColumn("str", "dq/q"); auto colScale = ws->addColumn("str", "Scale"); auto colOptions = ws->addColumn("str", "Options"); auto colHiddenOptions = ws->addColumn("str", "HiddenOptions"); for (size_t i = 0; i < ws->columnCount(); i++) { auto col = ws->getColumn(i); col->setPlotType(0); } // we are using the old ReflTBL format // where all of the entries are on one line // so we must reset the stream to reread the first line. std::ifstream file(filename.c_str()); if (!file) { throw Exception::FileError("Unable to open file: ", filename); } std::string line; int stitchID = 1; while (Kernel::Strings::extractToEOL(file, line)) { if (line.empty() || line == ",,,,,,,,,,,,,,,,") { continue; } getCells(line, rowVec, 16, isOld); const std::string scaleStr = rowVec.at(16); const std::string stitchStr = boost::lexical_cast<std::string>(stitchID); // check if the first run in the row has any data associated with it // 0 = runs, 1 = theta, 2 = trans, 3 = qmin, 4 = qmax if (!rowVec[0].empty() || !rowVec[1].empty() || !rowVec[2].empty() || !rowVec[3].empty() || !rowVec[4].empty()) { TableRow row = ws->appendRow(); row << stitchStr; for (int i = 0; i < 5; ++i) { row << rowVec.at(i); } row << rowVec.at(15); row << scaleStr; } // check if the second run in the row has any data associated with it // 5 = runs, 6 = theta, 7 = trans, 8 = qmin, 9 = qmax if (!rowVec[5].empty() || !rowVec[6].empty() || !rowVec[7].empty() || !rowVec[8].empty() || !rowVec[9].empty()) { TableRow row = ws->appendRow(); row << stitchStr; for (int i = 5; i < 10; ++i) { row << rowVec.at(i); } row << rowVec.at(15); row << scaleStr; } // check if the third run in the row has any data associated with it // 10 = runs, 11 = theta, 12 = trans, 13 = qmin, 14 = qmax if (!rowVec[10].empty() || !rowVec[11].empty() || !rowVec[12].empty() || !rowVec[13].empty() || !rowVec[14].empty()) { TableRow row = ws->appendRow(); row << stitchStr; for (int i = 10; i < 17; ++i) { if (i == 16) row << scaleStr; else row << rowVec.at(i); } } ++stitchID; setProperty("OutputWorkspace", ws); } } else { // we have a TBL format that contains column headings // on the first row. These are now entries in the columns vector if (!columnHeadings.empty()) { // now we need to add the custom column headings from // the columns vector to the TableWorkspace for (auto heading = columnHeadings.begin(); heading != columnHeadings.end();) { if (heading->empty()) { // there is no need to have empty column headings. heading = columnHeadings.erase(heading); } else { Mantid::API::Column_sptr col; col = ws->addColumn("str", *heading); col->setPlotType(0); heading++; } } } size_t expectedCommas = columnHeadings.size() - 1; while (Kernel::Strings::extractToEOL(file, line)) { if (line.empty() || line == ",,,,,,,,,,,,,,,,") { // skip over any empty lines continue; } getCells(line, rowVec, columnHeadings.size() - 1, isOld); // populate the columns with their values for this row. TableRow row = ws->appendRow(); for (size_t i = 0; i < expectedCommas + 1; ++i) { row << rowVec.at(i); } } setProperty("OutputWorkspace", ws); } }
//---------------------------------------------------------------------------------------------- /// 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); }
/** * Write log and parameter values to the table for the case of multiple fits. * @param table :: [input, output] Table to write to * @param paramsByLabel :: [input] Map of <label name, <workspace name, * <parameter, value>>> * @param paramsToDisplay :: [input] List of parameters to display in table */ void MuonAnalysisResultTableCreator::writeDataForMultipleFits( ITableWorkspace_sptr &table, const QMap<QString, WSParameterList> ¶msByLabel, const QStringList ¶msToDisplay) const { assert(m_multiple); assert(m_logValues); // Add data to table for (const auto &labelName : m_items) { Mantid::API::TableRow row = table->appendRow(); size_t columnIndex(0); // Which column we are writing to row << labelName.toStdString(); columnIndex++; // Get log values for this row and write in table for (const auto &log : m_logs) { QStringList valuesPerWorkspace; for (const auto &wsName : paramsByLabel[labelName].keys()) { const auto &logValues = m_logValues->value(wsName); const auto &val = logValues[log]; auto dashIndex = val.toString().indexOf("-"); // Special case: if log is time in sec, subtract the first start time if (log.endsWith(" (s)")) { auto seconds = val.toDouble() - static_cast<double>(m_firstStart_ns) * 1.e-9; valuesPerWorkspace.append(QString::number(seconds)); } else if (dashIndex != 0 && dashIndex != -1) { valuesPerWorkspace.append(logValues[log].toString()); } else if (MuonAnalysisHelper::isNumber(val.toString()) && !log.endsWith(" (text)")) { valuesPerWorkspace.append(QString::number(val.toDouble())); } else { valuesPerWorkspace.append(logValues[log].toString()); } } // Range of values - use string comparison as works for numbers too // Why not use std::minmax_element? To avoid MSVC warning: QT bug 41092 // (https://bugreports.qt.io/browse/QTBUG-41092) valuesPerWorkspace.sort(); auto dashIndex = valuesPerWorkspace.front().toStdString().find_first_of("-"); if (dashIndex != std::string::npos && dashIndex != 0) { std::ostringstream oss; auto dad = valuesPerWorkspace.front().toStdString(); oss << valuesPerWorkspace.front().toStdString(); row << oss.str(); } else { if (MuonAnalysisHelper::isNumber(valuesPerWorkspace.front())) { const auto &min = valuesPerWorkspace.front().toDouble(); const auto &max = valuesPerWorkspace.back().toDouble(); if (min == max) { row << min; } else { std::ostringstream oss; oss << valuesPerWorkspace.front().toStdString() << "-" << valuesPerWorkspace.back().toStdString(); row << oss.str(); } } else { const auto &front = valuesPerWorkspace.front().toStdString(); const auto &back = valuesPerWorkspace.back().toStdString(); if (front == back) { row << front; } else { std::ostringstream oss; oss << valuesPerWorkspace[0].toStdString(); for (int k = 1; k < valuesPerWorkspace.size(); k++) { oss << ", " << valuesPerWorkspace[k].toStdString(); row << oss.str(); } } } } columnIndex++; } // Parse column name - could be param name or f[n].param const auto parseColumnName = [¶msToDisplay]( const std::string &columnName) -> std::pair<int, std::string> { if (paramsToDisplay.contains(QString::fromStdString(columnName))) { return {0, columnName}; } else { // column name is f[n].param size_t pos = columnName.find_first_of('.'); if (pos != std::string::npos) { try { const auto ¶mName = columnName.substr(pos + 1); const auto wsIndex = std::stoi(columnName.substr(1, pos)); return {wsIndex, paramName}; } catch (const std::exception &ex) { throw std::runtime_error("Failed to parse column name " + columnName + ": " + ex.what()); } } else { throw std::runtime_error("Failed to parse column name " + columnName); } } }; // Add param values const auto ¶ms = paramsByLabel[labelName]; while (columnIndex < table->columnCount()) { const auto &parsedColName = parseColumnName(table->getColumn(columnIndex)->name()); const QString wsName = params.keys().at(parsedColName.first); const QString ¶mName = QString::fromStdString(parsedColName.second); row << params[wsName].value(paramName); columnIndex++; } } }