/** * Register a workspace in the Analysis Data Service and add it to the * groupWorkspace * @param gws pointer to WorkspaceGroup being filled * @param wsName name of workspace to be added and registered * @param ws pointer to workspace to be added and registered * @param description */ void LoadSassena::registerWorkspace(API::WorkspaceGroup_sptr gws, const std::string wsName, DataObjects::Workspace2D_sptr ws, const std::string &description) { UNUSED_ARG(description); API::AnalysisDataService::Instance().add(wsName, ws); gws->addWorkspace(ws); }
/** * Create the output workspace group. * @param baseName :: The base name for the output workspace. Suffix "Workspace" * will be added to it. * @param function :: A function to calculate the values. Must be of the * MultiDomainFunction type. * @param domain :: Domain created earlier with this creator (unused) * @param values :: Values created earlier with this creator (unused) * @param outputWorkspacePropertyName :: Name for the property to hold the * output workspace. If * empty the property won't be created. * @return A shared pointer to the created workspace. */ boost::shared_ptr<API::Workspace> MultiDomainCreator::createOutputWorkspace( const std::string &baseName, API::IFunction_sptr function, boost::shared_ptr<API::FunctionDomain> domain, boost::shared_ptr<API::FunctionValues> values, const std::string &outputWorkspacePropertyName) { UNUSED_ARG(domain); UNUSED_ARG(values); auto mdFunction = boost::dynamic_pointer_cast<API::MultiDomainFunction>(function); if (!mdFunction) { throw std::runtime_error("A MultiDomainFunction is expected to be used " "with MultiDomainCreator."); } // split the function into independent parts std::vector<API::IFunction_sptr> functions = mdFunction->createEquivalentFunctions(); // there must be as many parts as there are domains if (functions.size() != m_creators.size()) { throw std::runtime_error("Number of functions and domains don't match"); } API::WorkspaceGroup_sptr outWS = API::WorkspaceGroup_sptr(new API::WorkspaceGroup()); for (size_t i = 0; i < functions.size(); ++i) { std::string localName = baseName + "Workspace_" + boost::lexical_cast<std::string>(i); auto fun = functions[i]; auto creator = m_creators[i]; boost::shared_ptr<API::FunctionDomain> localDomain; boost::shared_ptr<API::FunctionValues> localValues; fun->setUpForFit(); creator->createDomain(localDomain, localValues); creator->initFunction(fun); auto ws = creator->createOutputWorkspace(localName, fun, localDomain, localValues, ""); API::AnalysisDataService::Instance().addOrReplace(localName, ws); outWS->addWorkspace(ws); } if (!outputWorkspacePropertyName.empty()) { declareProperty( new API::WorkspaceProperty<API::WorkspaceGroup>( outputWorkspacePropertyName, "", Kernel::Direction::Output), "Name of the output Workspace holding resulting simulated spectrum"); m_manager->setPropertyValue(outputWorkspacePropertyName, baseName + "Workspaces"); m_manager->setProperty(outputWorkspacePropertyName, outWS); } return outWS; }
/** 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)); } } }