/** 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"); // Loop through fitting all spectra individually const static std::string success = "success"; for (int wsIndex = 0; wsIndex < nhist; wsIndex++) { reportProgress(wsIndex, nhist); 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() || status != success) { std::ostringstream error; error << "Fit failed for spectrum at workspace index " << wsIndex; error << ": " << status; throw std::runtime_error(error.str()); } 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') const auto &spectrum = ws->getSpectrum(static_cast<size_t>(wsIndex)); extractDetectorInfo(tab, resTab, spectrum.getSpectrumNo()); } }
/** 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)); } } }