void PoldiPeakCollection::peaksToTable(const TableWorkspace_sptr &table) { for (std::vector<PoldiPeak_sptr>::const_iterator peak = m_peaks.begin(); peak != m_peaks.end(); ++peak) { TableRow newRow = table->appendRow(); newRow << MillerIndicesIO::toString((*peak)->hkl()) << (*peak)->d().value() << (*peak)->d().error() << (*peak)->q().value() << (*peak)->q().error() << (*peak)->intensity().value() << (*peak)->intensity().error() << (*peak)->fwhm(PoldiPeak::Relative).value() << (*peak)->fwhm(PoldiPeak::Relative).error(); } }
TableWorkspace_sptr PoldiPeakSummary::getSummaryTable( const PoldiPeakCollection_sptr &peakCollection) const { if (!peakCollection) { throw std::invalid_argument( "Cannot create summary of a null PoldiPeakCollection."); } TableWorkspace_sptr peakResultWorkspace = getInitializedResultWorkspace(); for (size_t i = 0; i < peakCollection->peakCount(); ++i) { storePeakSummary(peakResultWorkspace->appendRow(), peakCollection->peak(i)); } return peakResultWorkspace; }
/** * Creates Dead Time Table using all the data between begin and end. * @param specToLoad :: vector containing the spectrum numbers to load * @param deadTimes :: vector containing the corresponding dead times * @return Dead Time Table create using the data */ TableWorkspace_sptr LoadMuonNexus1::createDeadTimeTable(std::vector<int> specToLoad, std::vector<double> deadTimes) { TableWorkspace_sptr deadTimeTable = boost::dynamic_pointer_cast<TableWorkspace>( WorkspaceFactory::Instance().createTable("TableWorkspace")); deadTimeTable->addColumn("int", "spectrum"); deadTimeTable->addColumn("double", "dead-time"); for (size_t i = 0; i<specToLoad.size(); i++) { TableRow row = deadTimeTable->appendRow(); row << specToLoad[i] << deadTimes[i]; } return deadTimeTable; }
/** Copy table workspace content from one workspace to another * @param sourceWS :: table workspace from which the content is copied; * @param targetWS :: table workspace to which the content is copied; */ void ExtractMaskToTable::copyTableWorkspaceContent( TableWorkspace_sptr sourceWS, TableWorkspace_sptr targetWS) { // Compare the column names. They must be exactly the same vector<string> sourcecolnames = sourceWS->getColumnNames(); vector<string> targetcolnames = targetWS->getColumnNames(); if (sourcecolnames.size() != targetcolnames.size()) { stringstream errmsg; errmsg << "Soruce table workspace " << sourceWS->name() << " has different number of columns (" << sourcecolnames.size() << ") than target table workspace's (" << targetcolnames.size() << ")"; throw runtime_error(errmsg.str()); } for (size_t i = 0; i < sourcecolnames.size(); ++i) { if (sourcecolnames[i].compare(targetcolnames[i])) { stringstream errss; errss << "Source and target have incompatible column name at column " << i << ". " << "Column name of source is " << sourcecolnames[i] << "; " << "Column name of target is " << targetcolnames[i]; throw runtime_error(errss.str()); } } // Copy over the content size_t numrows = sourceWS->rowCount(); for (size_t i = 0; i < numrows; ++i) { double xmin, xmax; string speclist; TableRow tmprow = sourceWS->getRow(i); tmprow >> xmin >> xmax >> speclist; TableRow newrow = targetWS->appendRow(); newrow << xmin << xmax << speclist; } return; }
/** Fit background function */ void ProcessBackground::fitBackgroundFunction(std::string bkgdfunctiontype) { // Get background type and create bakground function BackgroundFunction_sptr bkgdfunction = createBackgroundFunction(bkgdfunctiontype); int bkgdorder = getProperty("OutputBackgroundOrder"); bkgdfunction->setAttributeValue("n", bkgdorder); if (bkgdfunctiontype == "Chebyshev") { double xmin = m_outputWS->readX(0).front(); double xmax = m_outputWS->readX(0).back(); g_log.information() << "Chebyshev Fit range: " << xmin << ", " << xmax << "\n"; bkgdfunction->setAttributeValue("StartX", xmin); bkgdfunction->setAttributeValue("EndX", xmax); } g_log.information() << "Fit selected background " << bkgdfunctiontype << " to data workspace with " << m_outputWS->getNumberHistograms() << " spectra." << "\n"; // Fit input (a few) background pionts to get initial guess API::IAlgorithm_sptr fit; try { fit = this->createChildAlgorithm("Fit", 0.9, 1.0, true); } catch (Exception::NotFoundError &) { g_log.error() << "Requires CurveFitting library." << std::endl; throw; } g_log.information() << "Fitting background function: " << bkgdfunction->asString() << "\n"; double startx = m_lowerBound; double endx = m_upperBound; fit->setProperty("Function", boost::dynamic_pointer_cast<API::IFunction>(bkgdfunction)); fit->setProperty("InputWorkspace", m_outputWS); fit->setProperty("WorkspaceIndex", 0); fit->setProperty("MaxIterations", 500); fit->setProperty("StartX", startx); fit->setProperty("EndX", endx); fit->setProperty("Minimizer", "Levenberg-MarquardtMD"); fit->setProperty("CostFunction", "Least squares"); fit->executeAsChildAlg(); // Get fit status and chi^2 std::string fitStatus = fit->getProperty("OutputStatus"); bool allowedfailure = (fitStatus.find("cannot") < fitStatus.size()) && (fitStatus.find("tolerance") < fitStatus.size()); if (fitStatus.compare("success") != 0 && !allowedfailure) { g_log.error() << "ProcessBackground: Fit Status = " << fitStatus << ". Not to update fit result" << std::endl; throw std::runtime_error("Bad Fit"); } const double chi2 = fit->getProperty("OutputChi2overDoF"); g_log.information() << "Fit background: Fit Status = " << fitStatus << ", chi2 = " << chi2 << "\n"; // Get out the parameter names API::IFunction_sptr funcout = fit->getProperty("Function"); TableWorkspace_sptr outbkgdparws = boost::make_shared<TableWorkspace>(); outbkgdparws->addColumn("str", "Name"); outbkgdparws->addColumn("double", "Value"); TableRow typerow = outbkgdparws->appendRow(); typerow << bkgdfunctiontype << 0.; vector<string> parnames = funcout->getParameterNames(); size_t nparam = funcout->nParams(); for (size_t i = 0; i < nparam; ++i) { TableRow newrow = outbkgdparws->appendRow(); newrow << parnames[i] << funcout->getParameter(i); } TableRow chi2row = outbkgdparws->appendRow(); chi2row << "Chi-square" << chi2; g_log.information() << "Set table workspace (#row = " << outbkgdparws->rowCount() << ") to OutputBackgroundParameterTable. " << "\n"; setProperty("OutputBackgroundParameterWorkspace", outbkgdparws); // Set output workspace const MantidVec &vecX = m_outputWS->readX(0); const MantidVec &vecY = m_outputWS->readY(0); FunctionDomain1DVector domain(vecX); FunctionValues values(domain); funcout->function(domain, values); MantidVec &dataModel = m_outputWS->dataY(1); MantidVec &dataDiff = m_outputWS->dataY(2); for (size_t i = 0; i < dataModel.size(); ++i) { dataModel[i] = values[i]; dataDiff[i] = vecY[i] - dataModel[i]; } return; }
/** Add a list of spectra (detector IDs) to the output table workspace. * If a detector is masked in input MaskTableWorkspace, then it will not be * added to a new row * @param outws :: table workspace to write * @param maskeddetids :: vector of detector IDs of which detectors masked * @param xmin :: minumim x * @param xmax :: maximum x * @param prevmaskedids :: vector of previous masked detector IDs */ void ExtractMaskToTable::addToTableWorkspace(TableWorkspace_sptr outws, vector<detid_t> maskeddetids, double xmin, double xmax, vector<detid_t> prevmaskedids) { // Sort vector of detectors ID size_t numdetids = maskeddetids.size(); if (numdetids == 0) { stringstream warnss; warnss << "Attempting to add an empty vector of masked detectors IDs to " "output workspace. Operation failed."; g_log.warning(warnss.str()); return; } else { sort(maskeddetids.begin(), maskeddetids.end()); } // Exclude previously masked detectors IDs from masked detectors IDs if (prevmaskedids.size() > 0) { sort(prevmaskedids.begin(), prevmaskedids.end()); maskeddetids = subtractVector(maskeddetids, prevmaskedids); numdetids = maskeddetids.size(); } else { g_log.debug() << "[DB] There is no previously masked detectors." << ".\n"; } if (numdetids == 0) { // I don't know what should be done here throw std::runtime_error("Empty detector ID list"); } // Convert vector to string stringstream spectralist; detid_t previd = maskeddetids[0]; detid_t headid = maskeddetids[0]; for (size_t i = 1; i < numdetids; ++i) { detid_t tmpid = maskeddetids[i]; if (tmpid == previd + 1) { // Continuous ID previd = tmpid; } else if (tmpid > previd + 1) { // Skipped ID: make a pair if (previd == headid) { // Single item spectralist << " " << headid << ", "; } else { // Multiple items spectralist << " " << headid << "-" << previd << ", "; } // New head headid = tmpid; previd = tmpid; } else { g_log.error() << "Current ID = " << tmpid << ", Previous ID = " << previd << ", Head ID = " << headid << ".\n"; throw runtime_error("Impossible! Programming logic error!"); } } // ENDFOR (i) // Last one if (previd == headid) spectralist << " " << headid; else spectralist << " " << headid << "-" << previd; // Add to table workspace string specliststr = spectralist.str(); TableRow newrow = outws->appendRow(); newrow << xmin << xmax << specliststr; return; }
/** Fits each spectrum in the workspace to f(x) = A * sin( w * x + p) * @param ws :: [input] The workspace to fit * @param freq :: [input] Hint for the frequency (w) * @param groupName :: [input] The name of the output workspace group * @param resTab :: [output] Table workspace storing the asymmetries and phases * @param resGroup :: [output] Workspace group storing the fitting results */ void CalMuonDetectorPhases::fitWorkspace(const API::MatrixWorkspace_sptr &ws, double freq, std::string groupName, API::ITableWorkspace_sptr resTab, API::WorkspaceGroup_sptr &resGroup) { int nhist = static_cast<int>(ws->getNumberHistograms()); // Create the fitting function f(x) = A * sin ( w * x + p ) // The same function and initial parameters are used for each fit std::string funcStr = createFittingFunction(freq, true); // Set up results table resTab->addColumn("int", "Spectrum number"); resTab->addColumn("double", "Asymmetry"); resTab->addColumn("double", "Phase"); const auto &indexInfo = ws->indexInfo(); // Loop through fitting all spectra individually const static std::string success = "success"; for (int wsIndex = 0; wsIndex < nhist; wsIndex++) { reportProgress(wsIndex, nhist); const auto &yValues = ws->y(wsIndex); auto emptySpectrum = std::all_of(yValues.begin(), yValues.end(), [](double value) { return value == 0.; }); if (emptySpectrum) { g_log.warning("Spectrum " + std::to_string(wsIndex) + " is empty"); TableWorkspace_sptr tab = boost::make_shared<TableWorkspace>(); tab->addColumn("str", "Name"); tab->addColumn("double", "Value"); tab->addColumn("double", "Error"); for (int j = 0; j < 4; j++) { API::TableRow row = tab->appendRow(); if (j == PHASE_ROW) { row << "dummy" << 0.0 << 0.0; } else { row << "dummy" << ASYMM_ERROR << 0.0; } } extractDetectorInfo(*tab, *resTab, indexInfo.spectrumNumber(wsIndex)); } else { auto fit = createChildAlgorithm("Fit"); fit->initialize(); fit->setPropertyValue("Function", funcStr); fit->setProperty("InputWorkspace", ws); fit->setProperty("WorkspaceIndex", wsIndex); fit->setProperty("CreateOutput", true); fit->setPropertyValue("Output", groupName); fit->execute(); std::string status = fit->getProperty("OutputStatus"); if (!fit->isExecuted()) { std::ostringstream error; error << "Fit failed for spectrum at workspace index " << wsIndex; error << ": " << status; throw std::runtime_error(error.str()); } else if (status != success) { g_log.warning("Fit failed for spectrum at workspace index " + std::to_string(wsIndex) + ": " + status); } API::MatrixWorkspace_sptr fitOut = fit->getProperty("OutputWorkspace"); resGroup->addWorkspace(fitOut); API::ITableWorkspace_sptr tab = fit->getProperty("OutputParameters"); // Now we have our fitting results stored in tab // but we need to extract the relevant information, i.e. // the detector phases (parameter 'p') and asymmetries ('A') extractDetectorInfo(*tab, *resTab, indexInfo.spectrumNumber(wsIndex)); } } }