Beispiel #1
0
/**
 * 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));
    }
  }
}