/** Creates grouping table from supplied forward and backward spectra * @param fwd :: [Input] Forward spectra * @param bwd :: [Input] Backward spectra * @return :: Workspace containing custom grouping */ Workspace_sptr PlotAsymmetryByLogValue::createCustomGrouping(const std::vector<int> &fwd, const std::vector<int> &bwd) { ITableWorkspace_sptr group = WorkspaceFactory::Instance().createTable("TableWorkspace"); group->addColumn("vector_int", "group"); TableRow row = group->appendRow(); row << fwd; row = group->appendRow(); row << bwd; return boost::dynamic_pointer_cast<Workspace>(group); }
/** * Parse the stream for the characterization file information. * * @param file The stream to parse. * @param wksp The table workspace to fill in. */ void PDLoadCharacterizations::readCharInfo(std::ifstream &file, ITableWorkspace_sptr &wksp) { // end early if already at the end of the file if (file.eof()) return; // parse the file for (std::string line = Strings::getLine(file); !file.eof(); line = Strings::getLine(file)) { line = Strings::strip(line); // skip empty lines and "comments" if (line.empty()) continue; if (line.substr(0,1) == "#") continue; // parse the line std::vector<std::string> splitted; boost::split(splitted, line, boost::is_any_of("\t "), boost::token_compress_on); while (splitted.size() < 10) splitted.push_back(ZERO); // extra values default to zero // add the row API::TableRow row = wksp->appendRow(); row << boost::lexical_cast<double>(splitted[0]); // frequency row << boost::lexical_cast<double>(splitted[1]); // wavelength row << boost::lexical_cast<int32_t>(splitted[2]); // bank row << boost::lexical_cast<int32_t>(splitted[3]); // vanadium row << boost::lexical_cast<int32_t>(splitted[4]); // container row << boost::lexical_cast<int32_t>(splitted[5]); // empty row << splitted[6]; // d_min row << splitted[7]; // d_max row << boost::lexical_cast<double>(splitted[8]); // tof_min row << boost::lexical_cast<double>(splitted[9]); // tof_max } }
/** Execute the algorithm. */ void ConvertDiffCal::exec() { OffsetsWorkspace_const_sptr offsetsWS = getProperty("OffsetsWorkspace"); // initial setup of new style config ITableWorkspace_sptr configWksp = boost::make_shared<TableWorkspace>(); configWksp->addColumn("int", "detid"); configWksp->addColumn("double", "difc"); configWksp->addColumn("double", "difa"); configWksp->addColumn("double", "tzero"); // create values in the table const size_t numberOfSpectra = offsetsWS->getNumberHistograms(); Progress progress(this, 0.0, 1.0, numberOfSpectra); for (size_t i = 0; i < numberOfSpectra; ++i) { API::TableRow newrow = configWksp->appendRow(); newrow << static_cast<int>(getDetID(offsetsWS, i)); newrow << calculateDIFC(offsetsWS, i); newrow << 0.; // difa newrow << 0.; // tzero progress.report(); } // sort the results IAlgorithm_sptr sortTable = createChildAlgorithm("SortTableWorkspace"); sortTable->setProperty("InputWorkspace", configWksp); sortTable->setProperty("OutputWorkspace", configWksp); sortTable->setPropertyValue("Columns", "detid"); sortTable->executeAsChildAlg(); // copy over the results configWksp = sortTable->getProperty("OutputWorkspace"); setProperty("OutputWorkspace", configWksp); }
/** * Creates an output workspace from calculated and observed values * * This method creates a table workspace for an ILatticeFunction, containing * observed and calculated d-values for each HKL, as well as the difference * between those two values. * * @param baseName :: Basename for output workspace. * @param function :: An ILatticeFunction * @param domain :: Pointer to LatticeDomain instance. * @param values :: Pointer to FunctionValues instance. * @param outputWorkspacePropertyName :: Name of output workspace property. * @return TableWorkspace with calculated and observed d-values. */ Workspace_sptr LatticeDomainCreator::createOutputWorkspace( const std::string &baseName, IFunction_sptr function, boost::shared_ptr<FunctionDomain> domain, boost::shared_ptr<FunctionValues> values, const std::string &outputWorkspacePropertyName) { boost::shared_ptr<LatticeDomain> latticeDomain = boost::dynamic_pointer_cast<LatticeDomain>(domain); if (!latticeDomain) { throw std::invalid_argument("LatticeDomain is required."); } ILatticeFunction_sptr latticeFunction = boost::dynamic_pointer_cast<ILatticeFunction>(function); if (!latticeFunction) { throw std::invalid_argument( "LatticeDomainCreator can only process ILatticeFunction."); } // Calculate function values again. latticeFunction->functionLattice(*latticeDomain, *values); ITableWorkspace_sptr tableWorkspace = WorkspaceFactory::Instance().createTable(); if (tableWorkspace) { tableWorkspace->addColumn("V3D", "HKL"); tableWorkspace->addColumn("double", "d(obs)"); tableWorkspace->addColumn("double", "d(calc)"); tableWorkspace->addColumn("double", "d(obs) - d(calc)"); for (size_t i = 0; i < values->size(); ++i) { double dObs = values->getFitData(i); double dCalc = values->getCalculated(i); TableRow newRow = tableWorkspace->appendRow(); newRow << (*latticeDomain)[i] << dObs << dCalc << dObs - dCalc; } } if (m_manager && !outputWorkspacePropertyName.empty()) { declareProperty( new WorkspaceProperty<ITableWorkspace>(outputWorkspacePropertyName, "", Kernel::Direction::Output), "Result workspace"); m_manager->setPropertyValue(outputWorkspacePropertyName, baseName + "Workspace"); m_manager->setProperty(outputWorkspacePropertyName, tableWorkspace); } return tableWorkspace; }
/// Returns a TableWorkspace with refined cell parameters and error. ITableWorkspace_sptr PoldiFitPeaks2D::getRefinedCellParameters( const IFunction_sptr &fitFunction) const { Poldi2DFunction_sptr poldi2DFunction = boost::dynamic_pointer_cast<Poldi2DFunction>(fitFunction); if (!poldi2DFunction || poldi2DFunction->nFunctions() < 1) { throw std::invalid_argument( "Cannot process function that is not a Poldi2DFunction."); } // Create a new table for lattice parameters ITableWorkspace_sptr latticeParameterTable = WorkspaceFactory::Instance().createTable(); latticeParameterTable->addColumn("str", "Parameter"); latticeParameterTable->addColumn("double", "Value"); latticeParameterTable->addColumn("double", "Error"); // The first function should be PoldiSpectrumPawleyFunction boost::shared_ptr<PoldiSpectrumPawleyFunction> poldiPawleyFunction = boost::dynamic_pointer_cast<PoldiSpectrumPawleyFunction>( poldi2DFunction->getFunction(0)); if (!poldiPawleyFunction) { throw std::invalid_argument("First function in Poldi2DFunction is not " "PoldiSpectrumPawleyFunction."); } // Get the actual PawleyFunction to extract parameters. IPawleyFunction_sptr pawleyFunction = boost::dynamic_pointer_cast<IPawleyFunction>( poldiPawleyFunction->getDecoratedFunction()); if (pawleyFunction) { CompositeFunction_sptr pawleyParts = boost::dynamic_pointer_cast<CompositeFunction>( pawleyFunction->getDecoratedFunction()); // The first function in PawleyFunction contains the parameters IFunction_sptr pawleyParameters = pawleyParts->getFunction(0); for (size_t i = 0; i < pawleyParameters->nParams(); ++i) { TableRow newRow = latticeParameterTable->appendRow(); newRow << pawleyParameters->parameterName(i) << pawleyParameters->getParameter(i) << pawleyParameters->getError(i); } } return latticeParameterTable; }
/** * 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]; } } }
/// Inserts statistics the supplied PeaksStatistics-objects into the supplied /// TableWorkspace. void SortHKL::insertStatisticsIntoTable( const ITableWorkspace_sptr &table, const PeaksStatistics &statistics) const { if (!table) { throw std::runtime_error("Can't store statistics into Null-table."); } std::string name = getProperty("RowName"); double completeness = 0.0; if (name.substr(0, 4) != "bank") { completeness = static_cast<double>(statistics.m_completeness); } // append to the table workspace API::TableRow newrow = table->appendRow(); newrow << name << statistics.m_uniqueReflections << statistics.m_dspacingMin << statistics.m_dspacingMax << statistics.m_redundancy << statistics.m_meanIOverSigma << 100.0 * statistics.m_rMerge << 100.0 * statistics.m_rPim << 100.0 * completeness; }
ITableWorkspace_sptr ALCBaselineModellingModel::exportSections() { if (!m_sections.empty()) { ITableWorkspace_sptr table = WorkspaceFactory::Instance().createTable("TableWorkspace"); table->addColumn("double", "Start X"); table->addColumn("double", "End X"); for (auto it = m_sections.begin(); it != m_sections.end(); ++it) { TableRow newRow = table->appendRow(); newRow << it->first << it->second; } return table; } else { return ITableWorkspace_sptr(); } }
/** Execute the algorithm. */ void CreateChunkingFromInstrument::exec() { // get the instrument Instrument_const_sptr inst = this->getInstrument(); // setup the output workspace ITableWorkspace_sptr strategy = WorkspaceFactory::Instance().createTable("TableWorkspace"); strategy->addColumn("str", "BankName"); this->setProperty("OutputWorkspace", strategy); // get the correct level of grouping string groupLevel = this->getPropertyValue(PARAM_CHUNK_BY); vector<string> groupNames = getGroupNames(this->getPropertyValue(PARAM_CHUNK_NAMES)); if (groupLevel.compare("All") == 0) { return; // nothing to do } else if (inst->getName().compare("SNAP") == 0 && groupLevel.compare("Group") == 0) { groupNames.clear(); groupNames.push_back("East"); groupNames.push_back("West"); } // set up a progress bar with the "correct" number of steps int maxBankNum = this->getProperty(PARAM_MAX_BANK_NUM); Progress progress(this, .2, 1., maxBankNum); // search the instrument for the bank names int maxRecurseDepth = this->getProperty(PARAM_MAX_RECURSE); map<string, vector<string>> grouping; // cppcheck-suppress syntaxError PRAGMA_OMP(parallel for schedule(dynamic, 1) ) for (int num = 0; num < maxBankNum; ++num) { PARALLEL_START_INTERUPT_REGION ostringstream mess; mess << "bank" << num; IComponent_const_sptr comp = inst->getComponentByName(mess.str(), maxRecurseDepth); PARALLEL_CRITICAL(grouping) if (comp) { // get the name of the correct parent string parent; if (groupNames.empty()) { parent = parentName(comp, groupLevel); } else { parent = parentName(comp, groupNames); } // add it to the correct chunk if (!parent.empty()) { if (grouping.count(parent) == 0) grouping[parent] = vector<string>(); grouping[parent].push_back(comp->getName()); } } progress.report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION // check to see that something happened if (grouping.empty()) throw std::runtime_error("Failed to find any banks in the instrument"); // fill in the table workspace for (auto group = grouping.begin(); group != grouping.end(); ++group) { stringstream banks; for (auto bank = group->second.begin(); bank != group->second.end(); ++bank) banks << (*bank) << ","; // remove the trailing comma string banksStr = banks.str(); banksStr = banksStr.substr(0, banksStr.size() - 1); // add it to the table TableRow row = strategy->appendRow(); row << banksStr; } }
/** * 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); }
void QueryMDWorkspace::getBoxData( typename Mantid::DataObjects::MDEventWorkspace<MDE, nd>::sptr ws) { if (this->getPropertyValue("BoxDataTable").empty()) return; ITableWorkspace_sptr output = WorkspaceFactory::Instance().createTable(); output->addColumn("int", "RecursionDepth"); output->addColumn("int", "NumBoxes"); output->addColumn("int", "NumWithEvents"); output->addColumn("double", "PctWithEvents"); output->addColumn("int", "TotalEvents"); output->addColumn("double", "AvgEventsPer"); output->addColumn("double", "TotalWeight"); output->addColumn("double", "TotalSignal"); output->addColumn("double", "TotalErrorSquared"); for (size_t d = 0; d < nd; d++) output->addColumn("double", "Dim" + Strings::toString(d)); size_t depth = ws->getBoxController()->getMaxDepth() + 1; std::vector<int> NumBoxes(depth, 0); std::vector<int> NumWithEvents(depth, 0); std::vector<int> TotalEvents(depth, 0); std::vector<double> TotalWeight(depth, 0); std::vector<double> TotalSignal(depth, 0); std::vector<double> TotalErrorSquared(depth, 0); std::vector<std::vector<double>> Dims(depth, std::vector<double>(nd, 0.0)); std::vector<API::IMDNode *> boxes; ws->getBox()->getBoxes(boxes, depth, true); for (size_t i = 0; i < boxes.size(); i++) { MDBoxBase<MDE, nd> *box = dynamic_cast<MDBoxBase<MDE, nd> *>(boxes[i]); if (!box) throw(std::runtime_error("Can not cast IMDNode to any type of boxes")); size_t d = box->getDepth(); NumBoxes[d] += 1; if (box->getNPoints() > 0) NumWithEvents[d] += 1; TotalEvents[d] += static_cast<int>(box->getNPoints()); TotalWeight[d] += box->getTotalWeight(); TotalSignal[d] += box->getSignal(); TotalErrorSquared[d] += box->getErrorSquared(); for (size_t dim = 0; dim < nd; dim++) Dims[d][dim] = double(box->getExtents(dim).getSize()); } int rowCounter = 0; for (size_t d = 0; d < depth; d++) { int col = 0; output->appendRow(); output->cell<int>(rowCounter, col++) = int(d); output->cell<int>(rowCounter, col++) = NumBoxes[d]; output->cell<int>(rowCounter, col++) = NumWithEvents[d]; output->cell<double>(rowCounter, col++) = 100.0 * double(NumWithEvents[d]) / double(NumBoxes[d]); output->cell<int>(rowCounter, col++) = TotalEvents[d]; output->cell<double>(rowCounter, col++) = double(TotalEvents[d]) / double(NumBoxes[d]); output->cell<double>(rowCounter, col++) = TotalWeight[d]; output->cell<double>(rowCounter, col++) = TotalSignal[d]; output->cell<double>(rowCounter, col++) = TotalErrorSquared[d]; for (size_t dim = 0; dim < nd; dim++) output->cell<double>(rowCounter, col++) = Dims[d][dim]; rowCounter++; } setProperty("BoxDataTable", output); }
/** * Loads a tomography parameterization file into a newly created table * workspace. The file must have the following syntax: * * @verbatim <NXentry name="entry1"> <NXprocess name="processing"> <NXnote name="id"> <values id="ID VALUE" params="..." name="..." cite="..."> </values> </NXnote> </NXprocess> </NXentry> @endverbatim * * @param fname name of the parameterization file * @param wsName name of workspace where to load the file data * * @return table workspace with parameters (plugins) found in the * loaded file */ ITableWorkspace_sptr LoadSavuTomoConfig::loadFile(std::string& fname, std::string& wsName) { // Throws an exception if there is a problem with file access //Mantid::NeXus::NXRoot root(fname); boost::shared_ptr<NeXus::File> f; if (!checkOpenFile(fname, f)) { throw std::runtime_error( "Failed to recognize this file as a NeXus file, cannot continue."); } ITableWorkspace_sptr ws = API::WorkspaceFactory::Instance().createTable(); if (!ws) throw std::runtime_error("Could not create TableWorkspace for " "workspace with name '" + wsName + "'"); // init workspace ws->setTitle("Table with tomography parameters from file " + fname); ws->addColumn("str", "ID"); ws->addColumn("str", "Parameters"); ws->addColumn("str", "Name"); ws->addColumn("str", "Cite"); // a bit of file consistency check, check at least there's a // 'entry1' // it could be more strict and demand entries.size()==1 std::map<std::string, std::string> entries = f->getEntries(); std::string mainEntryName = "entry"; auto it = entries.find(mainEntryName); if (entries.end() == it) { throw std::runtime_error("Could not find the '" + mainEntryName + "' " "entry. Even though this file looks like a valid NeXus file, it is " "not in the correct format for tomography reconstruction " "parameterization files."); } // go through the input file plugin entries f->openGroup(mainEntryName, "NXentry"); f->openGroup("process", "NXprocess"); size_t pluginsLen = f->getEntries().size(); for (size_t j=0; j<pluginsLen; j++) { API::TableRow table = ws->appendRow(); std::string entryIdx = boost::lexical_cast<std::string>(j); try { f->openGroup(entryIdx, "NXnote"); } catch(NeXus::Exception &e) { // detailed NeXus error message and throw... g_log.error() << "Failed to load plugin '" << j << "' from" "NeXus file. Error description: " << e.what() << std::endl; throw std::runtime_error("Could not load one or more plugin " "entries from the tomographic reconstruction parameterization " "file. Please check that the file is correct."); } // TODO: check final 'schema', get these 4 fields from the file std::string id = ""; std::string params = ""; std::string name = ""; std::string cite = ""; try { f->readData("data", params); f->readData("id", id); f->readData("name", name); // cite not available for now // f->readData("cite", cite); // This might be extended to an NXcite group that would be included // not here but inside an "intermediate" NXcollection group. That // NXcite would have 4 arrays: description, doi, endnote, bibtex. // But this is what we have so far. cite = "Not available"; } catch(NeXus::Exception &e) { // permissive, just error message but carry on g_log.warning() << "Failed to read some fields in tomographic " "reconstruction plugin line. The file seems to be wrong. Error " "description: " << e.what() << std::endl; } table << id << params << name << cite; f->closeGroup(); progress(static_cast<double>(j)/static_cast<double>(pluginsLen)); } f->close(); return ws; }
/** * Executes the algorithm */ void PlotPeakByLogValue::exec() { // Create a list of the input workspace const std::vector<InputData> wsNames = makeNames(); std::string fun = getPropertyValue("Function"); //int wi = getProperty("WorkspaceIndex"); std::string logName = getProperty("LogValue"); bool sequential = getPropertyValue("FitType") == "Sequential"; bool isDataName = false; // if true first output column is of type string and is the data source name ITableWorkspace_sptr result = WorkspaceFactory::Instance().createTable("TableWorkspace"); if (logName == "SourceName") { result->addColumn("str","Source name"); isDataName = true; } else if (logName.empty()) { result->addColumn("double","axis-1"); } else { result->addColumn("double",logName); } // Create an instance of the fitting function to obtain the names of fitting parameters IFitFunction* ifun = FunctionFactory::Instance().createInitialized(fun); if (!ifun) { throw std::invalid_argument("Fitting function failed to initialize"); } for(size_t iPar=0;iPar<ifun->nParams();++iPar) { result->addColumn("double",ifun->parameterName(iPar)); result->addColumn("double",ifun->parameterName(iPar)+"_Err"); } result->addColumn("double","Chi_squared"); delete ifun; setProperty("OutputWorkspace",result); double dProg = 1./static_cast<double>(wsNames.size()); double Prog = 0.; for(int i=0;i<static_cast<int>(wsNames.size());++i) { InputData data = getWorkspace(wsNames[i]); if (!data.ws) { g_log.warning() << "Cannot access workspace " << wsNames[i].name << '\n'; continue; } if (data.i < 0 && data.indx.empty()) { g_log.warning() << "Zero spectra selected for fitting in workspace " << wsNames[i].name << '\n'; continue; } int j,jend; if (data.i >= 0) { j = data.i; jend = j + 1; } else {// no need to check data.indx.empty() j = data.indx.front(); jend = data.indx.back() + 1; } dProg /= abs(jend - j); for(;j < jend;++j) { // Find the log value: it is either a log-file value or simply the workspace number double logValue; if (logName.empty()) { API::Axis* axis = data.ws->getAxis(1); logValue = (*axis)(j); } else if (logName != "SourceName") { Kernel::Property* prop = data.ws->run().getLogData(logName); if (!prop) { throw std::invalid_argument("Log value "+logName+" does not exist"); } TimeSeriesProperty<double>* logp = dynamic_cast<TimeSeriesProperty<double>*>(prop); logValue = logp->lastValue(); } std::string resFun = fun; std::vector<double> errors; double chi2; try { // Fit the function API::IAlgorithm_sptr fit = createSubAlgorithm("Fit"); fit->initialize(); fit->setProperty("InputWorkspace",data.ws); //fit->setPropertyValue("InputWorkspace",data.ws->getName()); fit->setProperty("WorkspaceIndex",j); fit->setPropertyValue("Function",fun); fit->setPropertyValue("StartX",getPropertyValue("StartX")); fit->setPropertyValue("EndX",getPropertyValue("EndX")); fit->setPropertyValue("Minimizer",getPropertyValue("Minimizer")); fit->setPropertyValue("CostFunction",getPropertyValue("CostFunction")); fit->execute(); resFun = fit->getPropertyValue("Function"); errors = fit->getProperty("Errors"); chi2 = fit->getProperty("OutputChi2overDoF"); } catch(...) { g_log.error("Error in Fit subalgorithm"); throw; } if (sequential) { fun = resFun; } // Extract the fitted parameters and put them into the result table TableRow row = result->appendRow(); if (isDataName) { row << wsNames[i].name; } else { row << logValue; } ifun = FunctionFactory::Instance().createInitialized(resFun); for(size_t iPar=0;iPar<ifun->nParams();++iPar) { row << ifun->getParameter(iPar) << errors[iPar]; } row << chi2; delete ifun; Prog += dProg; progress(Prog); interruption_point(); } // for(;j < jend;++j) } }
/** * 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++; } } }
/** Executes the algorithm. Reading in the file and creating and populating * the output workspace * * @throw Exception::FileError If the Nexus file cannot be found/opened * @throw std::invalid_argument If the optional properties are set to invalid values */ void PoldiLoadIPP::exec() { //////////////////////////////////////////////////////////////////////// // About the workspace //////////////////////////////////////////////////////////////////////// DataObjects::Workspace2D_sptr localWorkspace = this->getProperty("InputWorkspace"); //////////////////////////////////////////////////////////////////////// // Load the data into the workspace //////////////////////////////////////////////////////////////////////// try { ITableWorkspace_sptr outputws = WorkspaceFactory::Instance().createTable(); outputws->addColumn("str","param"); outputws->addColumn("str","unit"); outputws->addColumn("double","value"); Geometry::Instrument_const_sptr inst = localWorkspace->getInstrument(); double distChopSampl = localWorkspace->getInstrument()->getNumberParameter("dist-chopper-sample")[0]; g_log.debug() << "_poldi : param " << "dist-chopper-sample" << " : " << distChopSampl << std::endl; TableRow t0 = outputws->appendRow(); t0 << "dist-chopper-sample" << "[mm]" << distChopSampl ; double distSamplDet = localWorkspace->getInstrument()->getNumberParameter("dist-sample-detector")[0]; g_log.debug() << "_poldi : param " << "dist-sample-detector" << " : " << distSamplDet << std::endl; TableRow t1 = outputws->appendRow(); t1 << "dist-sample-detector" << "[mm]" << distSamplDet ; double x0det = localWorkspace->getInstrument()->getNumberParameter("x0det")[0]; g_log.debug() << "_poldi : param " << "x0det" << " : " << x0det << std::endl; TableRow t2 = outputws->appendRow(); t2 << "x0det" << "[mm]" << x0det ; double y0det = localWorkspace->getInstrument()->getNumberParameter("y0det")[0]; g_log.debug() << "_poldi : param " << "y0det" << " : " << y0det << std::endl; TableRow t3 = outputws->appendRow(); t3 << "y0det" << "[mm]" << y0det ; double twotheta = localWorkspace->getInstrument()->getNumberParameter("twothet")[0]; g_log.debug() << "_poldi : param " << "twothet" << " : " << twotheta << std::endl; TableRow t4 = outputws->appendRow(); t4 << "twothet" << "[deg]" << twotheta ; double tps0 = localWorkspace->getInstrument()->getNumberParameter("t0")[0]; g_log.debug() << "_poldi : param " << "t0" << " : " << tps0 << std::endl; TableRow t5 = outputws->appendRow(); t5 << "t0" << "[mysec]" << tps0 ; double tcycle = localWorkspace->getInstrument()->getNumberParameter("tconst")[0]; g_log.debug() << "_poldi : param " << "tconst" << " : " << tcycle << std::endl; TableRow t6 = outputws->appendRow(); t6 << "tconst" << "[mysec]" << tcycle ; double det_radius = localWorkspace->getInstrument()->getNumberParameter("det_radius")[0]; g_log.debug() << "_poldi : param " << "det_radius" << " : " << det_radius << std::endl; TableRow t8 = outputws->appendRow(); t8 << "det_radius" << "[mm]" << det_radius ; double det_nb_channel = localWorkspace->getInstrument()->getNumberParameter("det_nb_channel")[0]; g_log.debug() << "_poldi : param " << "det_nb_channel" << " : " << det_nb_channel << std::endl; TableRow t9 = outputws->appendRow(); t9 << "det_nb_channel" << "[]" << det_nb_channel ; double det_channel_resolution = localWorkspace->getInstrument()->getNumberParameter("det_channel_resolution")[0]; g_log.debug() << "_poldi : param " << "det_channel_resolution" << " : " << det_channel_resolution << std::endl; TableRow t10 = outputws->appendRow(); t10 << "det_channel_resolution" << "[mm]" << det_channel_resolution ; setProperty("PoldiIPP",outputws); } catch(Mantid::Kernel::Exception::NotFoundError& ) { throw std::runtime_error("Error when saving the PoldiIPP Results data to Workspace : NotFoundError"); } catch(std::runtime_error &) { throw std::runtime_error("Error when saving the PoldiIPP Results data to Workspace : runtime_error"); } }