/**
 * Removes exponential decay from a workspace
 * @param wsInput :: [input] Workspace to work on
 * @return :: Workspace with decay removed
 */
API::MatrixWorkspace_sptr CalMuonDetectorPhases::removeExpDecay(
    const API::MatrixWorkspace_sptr &wsInput) {
  API::IAlgorithm_sptr remove = createChildAlgorithm("RemoveExpDecay");
  remove->setProperty("InputWorkspace", wsInput);
  remove->executeAsChildAlg();
  API::MatrixWorkspace_sptr wsRem = remove->getProperty("OutputWorkspace");
  return wsRem;
}
/** Call diffraction focus to a matrix workspace.
  */
API::MatrixWorkspace_sptr
AlignAndFocusPowder::diffractionFocus(API::MatrixWorkspace_sptr ws) {
  if (!m_groupWS) {
    g_log.information() << "not focussing data\n";
    return ws;
  }

  g_log.information() << "running DiffractionFocussing. \n";

  API::IAlgorithm_sptr focusAlg = createChildAlgorithm("DiffractionFocussing");
  focusAlg->setProperty("InputWorkspace", ws);
  focusAlg->setProperty("OutputWorkspace", ws);
  focusAlg->setProperty("GroupingWorkspace", m_groupWS);
  focusAlg->setProperty("PreserveEvents", m_preserveEvents);
  focusAlg->executeAsChildAlg();
  ws = focusAlg->getProperty("OutputWorkspace");

  return ws;
}
/** Rebin
*/
API::MatrixWorkspace_sptr
AlignAndFocusPowder::rebin(API::MatrixWorkspace_sptr matrixws) {
  if (m_resampleX != 0) {
    // ResampleX
    g_log.information() << "running ResampleX(NumberBins=" << abs(m_resampleX)
                        << ", LogBinning=" << (m_resampleX < 0) << ", dMin("
                        << m_dmins.size() << "), dmax(" << m_dmaxs.size()
                        << ")) started at "
                        << Kernel::DateAndTime::getCurrentTime() << "\n";
    API::IAlgorithm_sptr alg = createChildAlgorithm("ResampleX");
    alg->setProperty("InputWorkspace", matrixws);
    alg->setProperty("OutputWorkspace", matrixws);
    if ((!m_dmins.empty()) && (!m_dmaxs.empty())) {
      size_t numHist = m_outputW->getNumberHistograms();
      if ((numHist == m_dmins.size()) && (numHist == m_dmaxs.size())) {
        alg->setProperty("XMin", m_dmins);
        alg->setProperty("XMax", m_dmaxs);
      } else {
        g_log.information()
            << "Number of dmin and dmax values don't match the "
            << "number of workspace indices. Ignoring the parameters.\n";
      }
    }
    alg->setProperty("NumberBins", abs(m_resampleX));
    alg->setProperty("LogBinning", (m_resampleX < 0));
    alg->executeAsChildAlg();
    matrixws = alg->getProperty("OutputWorkspace");
    return matrixws;
  } else {
    g_log.information() << "running Rebin( ";
    for (double param : m_params)
      g_log.information() << param << " ";
    g_log.information() << ") started at "
                        << Kernel::DateAndTime::getCurrentTime() << "\n";
    API::IAlgorithm_sptr rebin3Alg = createChildAlgorithm("Rebin");
    rebin3Alg->setProperty("InputWorkspace", matrixws);
    rebin3Alg->setProperty("OutputWorkspace", matrixws);
    rebin3Alg->setProperty("Params", m_params);
    rebin3Alg->executeAsChildAlg();
    matrixws = rebin3Alg->getProperty("OutputWorkspace");
    return matrixws;
  }
}
Exemple #4
0
void LoadILLSANS::moveDetectorVertical(double shift,
                                       const std::string &componentName) {

  API::IAlgorithm_sptr mover = createChildAlgorithm("MoveInstrumentComponent");
  V3D pos = getComponentPosition(componentName);
  try {
    mover->setProperty<MatrixWorkspace_sptr>("Workspace", m_localWorkspace);
    mover->setProperty("ComponentName", componentName);
    mover->setProperty("X", pos.X());
    mover->setProperty("Y", shift);
    mover->setProperty("Z", pos.Z());
    mover->setProperty("RelativePosition", false);
    mover->executeAsChildAlg();
    g_log.debug() << "Moving component '" << componentName
                  << "' to Y = " << shift << '\n';
  } catch (std::exception &e) {
    g_log.error() << "Cannot move the component '" << componentName
                  << "' to Y = " << shift << '\n';
    g_log.error() << e.what() << '\n';
  }
}
/** Call edit instrument geometry
  */
API::MatrixWorkspace_sptr AlignAndFocusPowder::editInstrument(
    API::MatrixWorkspace_sptr ws, std::vector<double> polars,
    std::vector<specnum_t> specids, std::vector<double> l2s,
    std::vector<double> phis) {
  g_log.information() << "running EditInstrumentGeometry started at "
                      << Kernel::DateAndTime::getCurrentTime() << "\n";

  API::IAlgorithm_sptr editAlg = createChildAlgorithm("EditInstrumentGeometry");
  editAlg->setProperty("Workspace", ws);
  if (m_l1 > 0.)
    editAlg->setProperty("PrimaryFlightPath", m_l1);
  if (!polars.empty())
    editAlg->setProperty("Polar", polars);
  if (!specids.empty())
    editAlg->setProperty("SpectrumIDs", specids);
  if (!l2s.empty())
    editAlg->setProperty("L2", l2s);
  if (!phis.empty())
    editAlg->setProperty("Azimuthal", phis);
  editAlg->executeAsChildAlg();

  ws = editAlg->getProperty("Workspace");

  return ws;
}
/** Perform SortHKL on the output workspaces
 *
 * @param ws :: any PeaksWorkspace
 * @param runName :: string to put in statistics table
 */
void StatisticsOfPeaksWorkspace::doSortHKL(Mantid::API::Workspace_sptr ws,
                                           std::string runName) {
  std::string pointGroup = getPropertyValue("PointGroup");
  std::string latticeCentering = getPropertyValue("LatticeCentering");
  std::string wkspName = getPropertyValue("OutputWorkspace");
  std::string tableName = getPropertyValue("StatisticsTable");
  API::IAlgorithm_sptr statsAlg = createChildAlgorithm("SortHKL");
  statsAlg->setProperty("InputWorkspace", ws);
  statsAlg->setPropertyValue("OutputWorkspace", wkspName);
  statsAlg->setPropertyValue("StatisticsTable", tableName);
  statsAlg->setProperty("PointGroup", pointGroup);
  statsAlg->setProperty("LatticeCentering", latticeCentering);
  statsAlg->setProperty("RowName", runName);
  if (runName.compare("Overall") != 0)
    statsAlg->setProperty("Append", true);
  statsAlg->executeAsChildAlg();
  PeaksWorkspace_sptr statsWksp = statsAlg->getProperty("OutputWorkspace");
  ITableWorkspace_sptr tablews = statsAlg->getProperty("StatisticsTable");
  if (runName.compare("Overall") == 0)
    setProperty("OutputWorkspace", statsWksp);
  setProperty("StatisticsTable", tablews);
}
Exemple #7
0
/**
 * Places the detector at the right sample_detector_distance
 */
void LoadSpice2D::moveDetector(double sample_detector_distance) {
  // Move the detector to the right position
  API::IAlgorithm_sptr mover = createChildAlgorithm("MoveInstrumentComponent");

  // Finding the name of the detector object.
  std::string detID =
      m_workspace->getInstrument()->getStringParameter("detector-name")[0];

  g_log.information("Moving " + detID);
  try {
    mover->setProperty<API::MatrixWorkspace_sptr>("Workspace", m_workspace);
    mover->setProperty("ComponentName", detID);
    mover->setProperty("Z", sample_detector_distance / 1000.0);
    mover->execute();
  } catch (std::invalid_argument &e) {
    g_log.error("Invalid argument to MoveInstrumentComponent Child Algorithm");
    g_log.error(e.what());
  } catch (std::runtime_error &e) {
    g_log.error(
        "Unable to successfully run MoveInstrumentComponent Child Algorithm");
    g_log.error(e.what());
  }
}
  /** Fit function
    * Minimizer: "Levenberg-MarquardtMD"/"Simplex"
   */
  bool RefinePowderInstrumentParameters2::doFitFunction(IFunction_sptr function, Workspace2D_sptr dataws, int wsindex,
                                                        string minimizer, int numiters, double& chi2, string& fitstatus)
  {
    // 0. Debug output
    stringstream outss;
    outss << "Fit function: " << m_positionFunc->asString() << endl << "Data To Fit: \n";
    for (size_t i = 0; i < dataws->readX(0).size(); ++i)
      outss << dataws->readX(wsindex)[i] << "\t\t" << dataws->readY(wsindex)[i] << "\t\t"
            << dataws->readE(wsindex)[i] << "\n";
    g_log.information() << outss.str();

    // 1. Create and setup fit algorithm
    API::IAlgorithm_sptr fitalg = createChildAlgorithm("Fit", 0.0, 0.2, true);
    fitalg->initialize();

    fitalg->setProperty("Function", function);
    fitalg->setProperty("InputWorkspace", dataws);
    fitalg->setProperty("WorkspaceIndex", wsindex);
    fitalg->setProperty("Minimizer", minimizer);
    fitalg->setProperty("CostFunction", "Least squares");
    fitalg->setProperty("MaxIterations", numiters);
    fitalg->setProperty("CalcErrors", true);

    // 2. Fit
    bool successfulfit = fitalg->execute();
    if (!fitalg->isExecuted() || ! successfulfit)
    {
      // Early return due to bad fit
      g_log.warning("Fitting to instrument geometry function failed. ");
      chi2 = DBL_MAX;
      fitstatus = "Minimizer throws exception.";
      return false;
    }

    // 3. Understand solution
    chi2 = fitalg->getProperty("OutputChi2overDoF");
    string tempfitstatus = fitalg->getProperty("OutputStatus");
    fitstatus = tempfitstatus;

    bool goodfit = fitstatus.compare("success") == 0;

    stringstream dbss;
    dbss << "Fit Result (GSL):  Chi^2 = " << chi2
         << "; Fit Status = " << fitstatus << ", Return Bool = " << goodfit << std::endl;
    vector<string> funcparnames = function->getParameterNames();
    for (size_t i = 0; i < funcparnames.size(); ++i)
      dbss << funcparnames[i] << " = " << setw(20) << function->getParameter(funcparnames[i])
           << " +/- " << function->getError(i) << "\n";
    g_log.debug() << dbss.str();

    return goodfit;
  }
Exemple #9
0
/// Run ConvertUnits as a sub-algorithm to convert to dSpacing
MatrixWorkspace_sptr DiffractionFocussing::convertUnitsToDSpacing(const API::MatrixWorkspace_sptr& workspace)
{
  const std::string CONVERSION_UNIT = "dSpacing";

  Unit_const_sptr xUnit = workspace->getAxis(0)->unit();

  g_log.information() << "Converting units from "<< xUnit->label() << " to " << CONVERSION_UNIT<<".\n";

  API::IAlgorithm_sptr childAlg = createSubAlgorithm("ConvertUnits", 0.34, 0.66);
  childAlg->setProperty("InputWorkspace", workspace);
  childAlg->setPropertyValue("Target",CONVERSION_UNIT);
  childAlg->executeAsSubAlg();

  return childAlg->getProperty("OutputWorkspace");
}
Exemple #10
0
/** Run the Child Algorithm LoadInstrument (as for LoadRaw)
 * @param inst_name :: The name written in the Nexus file
 * @param localWorkspace :: The workspace to insert the instrument into
 */
void LoadSpice2D::runLoadInstrument(
    const std::string &inst_name,
    DataObjects::Workspace2D_sptr localWorkspace) {

  API::IAlgorithm_sptr loadInst = createChildAlgorithm("LoadInstrument");

  // Now execute the Child Algorithm. Catch and log any error, but don't stop.
  try {
    loadInst->setPropertyValue("InstrumentName", inst_name);
    loadInst->setProperty<API::MatrixWorkspace_sptr>("Workspace",
                                                     localWorkspace);
    loadInst->setProperty("RewriteSpectraMap",
                          Mantid::Kernel::OptionalBool(true));
    loadInst->execute();
  } catch (std::invalid_argument &) {
    g_log.information("Invalid argument to LoadInstrument Child Algorithm");
  } catch (std::runtime_error &) {
    g_log.information(
        "Unable to successfully run LoadInstrument Child Algorithm");
  }
}
Exemple #11
0
/** Select background automatically
 */
DataObjects::Workspace2D_sptr
ProcessBackground::autoBackgroundSelection(Workspace2D_sptr bkgdWS) {
  // Get background type and create bakground function
  BackgroundFunction_sptr bkgdfunction = createBackgroundFunction(m_bkgdType);

  int bkgdorder = getProperty("BackgroundOrder");
  if (bkgdorder == 0)
    g_log.warning("(Input) background function order is 0.  It might not be "
                  "able to give a good estimation.");

  bkgdfunction->setAttributeValue("n", bkgdorder);
  bkgdfunction->initialize();

  g_log.information() << "Input background points has "
                      << bkgdWS->readX(0).size() << " data points for fit "
                      << bkgdorder << "-th order " << bkgdfunction->name()
                      << " (background) function" << bkgdfunction->asString()
                      << "\n";

  // Fit input (a few) background pionts to get initial guess
  API::IAlgorithm_sptr fit;
  try {
    fit = this->createChildAlgorithm("Fit", 0.0, 0.2, true);
  } catch (Exception::NotFoundError &) {
    g_log.error() << "Requires CurveFitting library." << std::endl;
    throw;
  }

  double startx = m_lowerBound;
  double endx = m_upperBound;
  fit->setProperty("Function",
                   boost::dynamic_pointer_cast<API::IFunction>(bkgdfunction));
  fit->setProperty("InputWorkspace", bkgdWS);
  fit->setProperty("WorkspaceIndex", 0);
  fit->setProperty("MaxIterations", 500);
  fit->setProperty("StartX", startx);
  fit->setProperty("EndX", endx);
  fit->setProperty("Minimizer", "Levenberg-Marquardt");
  fit->setProperty("CostFunction", "Least squares");

  fit->executeAsChildAlg();

  // Get fit result
  // a) Status
  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");
  }

  // b) check that chi2 got better
  const double chi2 = fit->getProperty("OutputChi2overDoF");
  g_log.information() << "Fit background: Fit Status = " << fitStatus
                      << ", chi2 = " << chi2 << "\n";

  // Filter and construct for the output workspace
  Workspace2D_sptr outws = filterForBackground(bkgdfunction);

  return outws;
} // END OF FUNCTION
Exemple #12
0
/** 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;
}
  void MaskBinsFromTable::exec()
  {
    MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
    DataObjects::TableWorkspace_sptr paramWS = getProperty("MaskingInformation");

    // 1. Check input table workspace and column order
    g_log.debug() << "Lines of parameters workspace = " << paramWS->rowCount() << std::endl;

    bool colname_specx = false;
    if (!paramWS)
    {
      throw std::invalid_argument("Input table workspace is not accepted.");
    }
    else
    {
      std::vector<std::string> colnames = paramWS->getColumnNames();
      // check colum name order
      if (colnames.size() < 3)
      {
        g_log.error() << "Input MaskingInformation table workspace has fewer than 3 columns.  " << colnames.size()
                      << " columns indeed" << std::endl;
        throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns.");
      }
      if (colnames[0].compare("XMin") == 0)
      {
          // 1. Style XMin, XMax, SpectraList. Check rest
          if (colnames[1].compare("XMax") != 0 || colnames[2].compare("SpectraList") != 0)
          {
              g_log.error() << "INput MaskingInformation table workspace has wrong column order. " << std::endl;
              throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns.");
          }
      }
      else if (colnames[0].compare("SpectraList") == 0)
      {
          // 2. Style SpectraList, XMin, XMax
          colname_specx = true;
          if (colnames[1].compare("XMin") != 0 || colnames[2].compare("XMax") != 0)
          {
              g_log.error() << "INput MaskingInformation table workspace has wrong column order. " << std::endl;
              throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns.");
          }
      }
      else
      {
          g_log.error() << "INput MaskingInformation table workspace has wrong column order. " << std::endl;
          throw std::invalid_argument("MaskingInformation (TableWorkspace) has too few columns.");
      }
    }

    // 2. Loop over all rows
    bool firstloop = true;
    API::MatrixWorkspace_sptr outputws = this->getProperty("OutputWorkspace");

    for (size_t ib = 0; ib < paramWS->rowCount(); ++ib)
    {
      API::TableRow therow = paramWS->getRow(ib);
      double xmin, xmax;
      std::string speclist;
      if (colname_specx)
      {
          therow >> speclist >> xmin >> xmax;
      }
      else
      {
          therow >> xmin >> xmax >> speclist;
      }

      g_log.debug() << "Row " << ib << " XMin = " << xmin << "  XMax = " << xmax << " SpectraList = " << speclist << std::endl;

      API::IAlgorithm_sptr maskbins = this->createChildAlgorithm("MaskBins", 0, 0.3, true);
      maskbins->initialize();
      if (firstloop)
      {
        maskbins->setProperty("InputWorkspace", inputWS);
        firstloop = false;
      }
      else
      {
        maskbins->setProperty("InputWorkspace", outputws);
      }
      maskbins->setProperty("OutputWorkspace", outputws);
      maskbins->setPropertyValue("SpectraList", speclist);
      maskbins->setProperty("XMin", xmin);
      maskbins->setProperty("XMax", xmax);

      bool isexec = maskbins->execute();
      if (!isexec)
      {
        g_log.error() << "MaskBins() is not executed for row " << ib << std::endl;
        throw std::runtime_error("MaskBins() is not executed");
      }

      outputws = maskbins->getProperty("OutputWorkspace");
      if (!outputws)
      {
        g_log.error() << "OutputWorkspace is not retrieved for row " << ib << ". " << std::endl;
        throw std::runtime_error("OutputWorkspace is not got from MaskBins");
      }
    }
    void GetDetOffsetsMultiPeaks::fitSpectra(const int64_t s, MatrixWorkspace_sptr inputW, const std::vector<double> &peakPositions,
                                             const std::vector<double> &fitWindows, size_t &nparams, double &minD, double &maxD,
                                             std::vector<double>&peakPosToFit, std::vector<double>&peakPosFitted,
                                             std::vector<double> &chisq)
    {
      const MantidVec & X = inputW->readX(s);
      minD = X.front();
      maxD = X.back();
      bool useFitWindows = (!fitWindows.empty());
      std::vector<double> fitWindowsToUse;
      for (int i = 0; i < static_cast<int>(peakPositions.size()); ++i)
      {
        if((peakPositions[i] > minD) && (peakPositions[i] < maxD))
        {
          peakPosToFit.push_back(peakPositions[i]);
          if (useFitWindows)
          {
            fitWindowsToUse.push_back(std::max(fitWindows[2*i], minD));
            fitWindowsToUse.push_back(std::min(fitWindows[2*i+1], maxD));
          }
        }
      }

      API::IAlgorithm_sptr findpeaks = createChildAlgorithm("FindPeaks", -1, -1, false);
      findpeaks->setProperty("InputWorkspace", inputW);
      findpeaks->setProperty<int>("FWHM",7);
      findpeaks->setProperty<int>("Tolerance",4);
      // FindPeaks will do the checking on the validity of WorkspaceIndex
      findpeaks->setProperty("WorkspaceIndex",static_cast<int>(s));
  
      //Get the specified peak positions, which is optional
      findpeaks->setProperty("PeakPositions", peakPosToFit);
      if (useFitWindows)
        findpeaks->setProperty("FitWindows", fitWindowsToUse);
      findpeaks->setProperty<std::string>("PeakFunction", m_peakType);
      findpeaks->setProperty<std::string>("BackgroundType", m_backType);
      findpeaks->setProperty<bool>("HighBackground", this->getProperty("HighBackground"));
      findpeaks->setProperty<int>("MinGuessedPeakWidth",4);
      findpeaks->setProperty<int>("MaxGuessedPeakWidth",4);
      findpeaks->executeAsChildAlg();
      ITableWorkspace_sptr peakslist = findpeaks->getProperty("PeaksList");
      std::vector<size_t> banned;
      std::vector<double> peakWidFitted;
      std::vector<double> peakHighFitted;
      std::vector<double> peakBackground;
      for (size_t i = 0; i < peakslist->rowCount(); ++i)
      {
        // peak value
        double centre = peakslist->getRef<double>("centre",i);
        double width = peakslist->getRef<double>("width",i);
        double height = peakslist->getRef<double>("height", i);

        // background value
        double back_intercept = peakslist->getRef<double>("backgroundintercept", i);
        double back_slope = peakslist->getRef<double>("backgroundslope", i);
        double back_quad = peakslist->getRef<double>("A2", i);
        double background = back_intercept + back_slope * centre
            + back_quad * centre * centre;

        // goodness of fit
        double chi2 = peakslist->getRef<double>("chi2",i);

        // Get references to the data
        peakPosFitted.push_back(centre);
        peakWidFitted.push_back(width);
        peakHighFitted.push_back(height);
        peakBackground.push_back(background);
        chisq.push_back(chi2);
      }

      // first remove things that just didn't fit (center outside of window, bad chisq, ...)
      for (size_t i = 0; i < peakslist->rowCount(); ++i)
      {
        if (peakPosFitted[i] <= minD || peakPosFitted[i] >= maxD)
        {
            banned.push_back(i);
            continue;
        }
        else if (useFitWindows) // be more restrictive if fit windows were specified
        {
          if (peakPosFitted[i] <= fitWindowsToUse[2*i]
              || peakPosFitted[i] >= fitWindowsToUse[2*i+1])
          {
            banned.push_back(i);
            continue;
          }
        }
        if (chisq[i] > m_maxChiSq)
        {
          banned.push_back(i);
          continue;
        }
      }
      // delete banned peaks
      g_log.debug() << "Deleting " << banned.size() << " of " << peakPosFitted.size()
                    << " peaks in wkspindex = " << s << "\n";
      deletePeaks(banned, peakPosToFit, peakPosFitted,
                  peakWidFitted, peakHighFitted, peakBackground,
                  chisq);

      // ban peaks that are low intensity compared to their widths
      for (size_t i = 0; i < peakWidFitted.size(); ++i)
      {
        if (peakHighFitted[i]  * FWHM_TO_SIGMA / peakWidFitted[i] < 5.)
        {
          g_log.debug() << "Banning peak at " << peakPosFitted[i] << " in wkspindex = " << s
                         << " I/sigma = " << (peakHighFitted[i] * FWHM_TO_SIGMA / peakWidFitted[i]) << "\n";
          banned.push_back(i);
          continue;
        }
      }
      // delete banned peaks
      g_log.debug() << "Deleting " << banned.size() << " of " << peakPosFitted.size()
                    << " peaks in wkspindex = " << s << "\n";
      deletePeaks(banned, peakPosToFit, peakPosFitted,
                  peakWidFitted, peakHighFitted, peakBackground,
                  chisq);

      // determine the (z-value) for constant "width" - (delta d)/d
      std::vector<double> widthDivPos(peakWidFitted.size(), 0.); // DELETEME
      for (size_t i = 0; i < peakWidFitted.size(); ++i)
      {
        widthDivPos[i] = peakWidFitted[i] / peakPosFitted[i]; // DELETEME
      }
      std::vector<double> Zscore = getZscore(widthDivPos);
      for (size_t i = 0; i < peakWidFitted.size(); ++i)
      {
        if (Zscore[i] > 2.0)
        {
          g_log.debug() << "Banning peak at " << peakPosFitted[i] << " in wkspindex = " << s
                         << " sigma/d = " << widthDivPos[i] << "\n";
          banned.push_back(i);
          continue;
        }
      }
      // delete banned peaks
      g_log.debug() << "Deleting " << banned.size() << " of " << peakPosFitted.size()
                    << " peaks in wkspindex = " << s << "\n";
      deletePeaks(banned, peakPosToFit, peakPosFitted,
                  peakWidFitted, peakHighFitted, peakBackground,
                  chisq);

      // ban peaks that are not outside of error bars for the background
      for (size_t i = 0; i < peakWidFitted.size(); ++i)
      {
        if (peakHighFitted[i] < 0.5 * std::sqrt(peakHighFitted[i] + peakBackground[i]))
        {
          g_log.debug() << "Banning peak at " << peakPosFitted[i] << " in wkspindex = " << s
                         << " " << peakHighFitted[i] << " < "
                         << 0.5 * std::sqrt(peakHighFitted[i] + peakBackground[i]) << "\n";
          banned.push_back(i);
          continue;
        }
      }
      // delete banned peaks
      g_log.debug() << "Deleting " << banned.size() << " of " << peakPosFitted.size()
                    << " peaks in wkspindex = " << s << "\n";
      deletePeaks(banned, peakPosToFit, peakPosFitted,
                  peakWidFitted, peakHighFitted, peakBackground,
                  chisq);

      nparams = peakPosFitted.size();
      return;
    }
Exemple #15
0
    /// Overwrites Algorithm exec method
    void LoadSpice2D::exec()
    {
      std::string fileName = getPropertyValue("Filename");

      const double wavelength_input = getProperty("Wavelength");
      const double wavelength_spread_input = getProperty("WavelengthSpread");

      // Set up the DOM parser and parse xml file
      DOMParser pParser;
      Document* pDoc;
      try
      {
        pDoc = pParser.parse(fileName);
      } catch (...)
      {
        throw Kernel::Exception::FileError("Unable to parse File:", fileName);
      }
      // Get pointer to root element
      Element* pRootElem = pDoc->documentElement();
      if (!pRootElem->hasChildNodes())
      {
        throw Kernel::Exception::NotFoundError("No root element in Spice XML file", fileName);
      }

      // Read in start time
      const std::string start_time = pRootElem->getAttribute("start_time");

      Element* sasEntryElem = pRootElem->getChildElement("Header");
      throwException(sasEntryElem, "Header", fileName);

      // Read in scan title
      Element* element = sasEntryElem->getChildElement("Scan_Title");
      throwException(element, "Scan_Title", fileName);
      std::string wsTitle = element->innerText();

      // Read in instrument name
      element = sasEntryElem->getChildElement("Instrument");
      throwException(element, "Instrument", fileName);
      std::string instrument = element->innerText();

      // Read sample thickness
      double sample_thickness = 0;
      from_element<double>(sample_thickness, sasEntryElem, "Sample_Thickness", fileName);

      double source_apert = 0.0;
      from_element<double>(source_apert, sasEntryElem, "source_aperture_size", fileName);

      double sample_apert = 0.0;
      from_element<double>(sample_apert, sasEntryElem, "sample_aperture_size", fileName);

      double source_distance = 0.0;
      from_element<double>(source_distance, sasEntryElem, "source_distance", fileName);

      // Read in wavelength and wavelength spread
      double wavelength = 0;
      double dwavelength = 0;
      if ( isEmpty(wavelength_input) ) {
        from_element<double>(wavelength, sasEntryElem, "wavelength", fileName);
        from_element<double>(dwavelength, sasEntryElem, "wavelength_spread", fileName);
      }
      else
      {
        wavelength = wavelength_input;
        dwavelength = wavelength_spread_input;
      }

      // Read in positions
      sasEntryElem = pRootElem->getChildElement("Motor_Positions");
      throwException(sasEntryElem, "Motor_Positions", fileName);

      // Read in the number of guides
      int nguides = 0;
      from_element<int>(nguides, sasEntryElem, "nguides", fileName);

      // Read in sample-detector distance in mm
      double distance = 0;
      from_element<double>(distance, sasEntryElem, "sample_det_dist", fileName);
      distance *= 1000.0;

      // Read in beam trap positions
      double highest_trap = 0;
      double trap_pos = 0;

      from_element<double>(trap_pos, sasEntryElem, "trap_y_25mm", fileName);
      double beam_trap_diam = 25.4;

      from_element<double>(highest_trap, sasEntryElem, "trap_y_101mm", fileName);
      if (trap_pos>highest_trap)
      {
        highest_trap = trap_pos;
        beam_trap_diam = 101.6;
      }

      from_element<double>(trap_pos, sasEntryElem, "trap_y_50mm", fileName);
      if (trap_pos>highest_trap)
      {
        highest_trap = trap_pos;
        beam_trap_diam = 50.8;
      }

      from_element<double>(trap_pos, sasEntryElem, "trap_y_76mm", fileName);
      if (trap_pos>highest_trap)
      {
        highest_trap = trap_pos;
        beam_trap_diam = 76.2;
      }

      // Read in counters
      sasEntryElem = pRootElem->getChildElement("Counters");
      throwException(sasEntryElem, "Counters", fileName);

      double countingTime = 0;
      from_element<double>(countingTime, sasEntryElem, "time", fileName);
      double monitorCounts = 0;
      from_element<double>(monitorCounts, sasEntryElem, "monitor", fileName);

      // Read in the data image
      Element* sasDataElem = pRootElem->getChildElement("Data");
      throwException(sasDataElem, "Data", fileName);

      // Read in the data buffer
      element = sasDataElem->getChildElement("Detector");
      throwException(element, "Detector", fileName);
      std::string data_str = element->innerText();

      // Read in the detector dimensions from the Detector tag
      int numberXPixels = 0;
      int numberYPixels = 0;
      std::string data_type = element->getAttribute("type");
      boost::regex b_re_sig("INT\\d+\\[(\\d+),(\\d+)\\]");
      if (boost::regex_match(data_type, b_re_sig))
      {
        boost::match_results<std::string::const_iterator> match;
        boost::regex_search(data_type, match, b_re_sig);
        // match[0] is the full string
        Kernel::Strings::convert(match[1], numberXPixels);
        Kernel::Strings::convert(match[2], numberYPixels);
      }
      if (numberXPixels==0 || numberYPixels==0)
        g_log.notice() << "Could not read in the number of pixels!" << std::endl;

      // We no longer read from the meta data because that data is wrong
      //from_element<int>(numberXPixels, sasEntryElem, "Number_of_X_Pixels", fileName);
      //from_element<int>(numberYPixels, sasEntryElem, "Number_of_Y_Pixels", fileName);

      // Store sample-detector distance
      declareProperty("SampleDetectorDistance", distance, Kernel::Direction::Output);

      // Create the output workspace

      // Number of bins: we use a single dummy TOF bin
      int nBins = 1;
      // Number of detectors: should be pulled from the geometry description. Use detector pixels for now.
      // The number of spectram also includes the monitor and the timer.
      int numSpectra = numberXPixels*numberYPixels + LoadSpice2D::nMonitors;

      DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
          API::WorkspaceFactory::Instance().create("Workspace2D", numSpectra, nBins+1, nBins));
      ws->setTitle(wsTitle);
      ws->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("Wavelength");
      ws->setYUnit("");
      API::Workspace_sptr workspace = boost::static_pointer_cast<API::Workspace>(ws);
      setProperty("OutputWorkspace", workspace);

      // Parse out each pixel. Pixels can be separated by white space, a tab, or an end-of-line character
      Poco::StringTokenizer pixels(data_str, " \n\t", Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY);
      Poco::StringTokenizer::Iterator pixel = pixels.begin();

      // Check that we don't keep within the size of the workspace
      size_t pixelcount = pixels.count();
      if( pixelcount != static_cast<size_t>(numberXPixels*numberYPixels) )
      {
        throw Kernel::Exception::FileError("Inconsistent data set: "
            "There were more data pixels found than declared in the Spice XML meta-data.", fileName);
      }
      if( numSpectra == 0 )
      {
        throw Kernel::Exception::FileError("Empty data set: the data file has no pixel data.", fileName);
      }

      // Go through all detectors/channels
      int ipixel = 0;

      // Store monitor count
      store_value(ws, ipixel++, monitorCounts, monitorCounts>0 ? sqrt(monitorCounts) : 0.0,
          wavelength, dwavelength);

      // Store counting time
      store_value(ws, ipixel++, countingTime, 0.0, wavelength, dwavelength);

      // Store detector pixels
      while (pixel != pixels.end())
      {
        //int ix = ipixel%npixelsx;
        //int iy = (int)ipixel/npixelsx;

        // Get the count value and assign it to the right bin
        double count = 0.0;
        from_string<double>(count, *pixel, std::dec);

        // Data uncertainties, computed according to the HFIR/IGOR reduction code
        // The following is what I would suggest instead...
        // error = count > 0 ? sqrt((double)count) : 0.0;
        double error = sqrt( 0.5 + fabs( count - 0.5 ));

        store_value(ws, ipixel, count, error, wavelength, dwavelength);

        // Set the spectrum number
        ws->getAxis(1)->setValue(ipixel, ipixel);

        ++pixel;
        ipixel++;
      }

      // run load instrument
      runLoadInstrument(instrument, ws);
      runLoadMappingTable(ws, numberXPixels, numberYPixels);

      // Set the run properties
      ws->mutableRun().addProperty("sample-detector-distance", distance, "mm", true);
      ws->mutableRun().addProperty("beam-trap-diameter", beam_trap_diam, "mm", true);
      ws->mutableRun().addProperty("number-of-guides", nguides, true);
      ws->mutableRun().addProperty("source-sample-distance", source_distance, "mm", true);
      ws->mutableRun().addProperty("source-aperture-diameter", source_apert, "mm", true);
      ws->mutableRun().addProperty("sample-aperture-diameter", sample_apert, "mm", true);
      ws->mutableRun().addProperty("sample-thickness", sample_thickness, "cm", true);
      ws->mutableRun().addProperty("wavelength", wavelength, "Angstrom", true);
      ws->mutableRun().addProperty("wavelength-spread", dwavelength, "Angstrom", true);
      ws->mutableRun().addProperty("timer", countingTime, "sec", true);
      ws->mutableRun().addProperty("monitor", monitorCounts, "", true);
      ws->mutableRun().addProperty("start_time", start_time, "", true);
      ws->mutableRun().addProperty("run_start", start_time, "", true);

      // Move the detector to the right position
      API::IAlgorithm_sptr mover = createChildAlgorithm("MoveInstrumentComponent");

      // Finding the name of the detector object.
      std::string detID = ws->getInstrument()->getStringParameter("detector-name")[0];

      g_log.information("Moving "+detID);
      try
      {
        mover->setProperty<API::MatrixWorkspace_sptr> ("Workspace", ws);
        mover->setProperty("ComponentName", detID);
        mover->setProperty("Z", distance/1000.0);
        mover->execute();
      } catch (std::invalid_argument& e)
      {
        g_log.error("Invalid argument to MoveInstrumentComponent Child Algorithm");
        g_log.error(e.what());
      } catch (std::runtime_error& e)
      {
        g_log.error("Unable to successfully run MoveInstrumentComponent Child Algorithm");
        g_log.error(e.what());
      }

      // Release the XML document memory
      pDoc->release();
    }
/** Executes the algorithm
 *  @throw Exception::FileError If the grouping file cannot be opened or read
 * successfully
 *  @throw runtime_error If unable to run one of the Child Algorithms
 * successfully
 */
void AlignAndFocusPowder::exec() {
  // retrieve the properties
  m_inputW = getProperty("InputWorkspace");
  m_inputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_inputW);
  m_instName = m_inputW->getInstrument()->getName();
  m_instName =
      Kernel::ConfigService::Instance().getInstrument(m_instName).shortName();
  std::string calFilename = getPropertyValue("CalFileName");
  std::string groupFilename = getPropertyValue("GroupFilename");
  m_calibrationWS = getProperty("CalibrationWorkspace");
  m_maskWS = getProperty("MaskWorkspace");
  m_groupWS = getProperty("GroupingWorkspace");
  DataObjects::TableWorkspace_sptr maskBinTableWS = getProperty("MaskBinTable");
  m_l1 = getProperty("PrimaryFlightPath");
  specids = getProperty("SpectrumIDs");
  l2s = getProperty("L2");
  tths = getProperty("Polar");
  phis = getProperty("Azimuthal");
  m_params = getProperty("Params");
  dspace = getProperty("DSpacing");
  auto dmin = getVecPropertyFromPmOrSelf("DMin", m_dmins);
  auto dmax = getVecPropertyFromPmOrSelf("DMax", m_dmaxs);
  LRef = getProperty("UnwrapRef");
  DIFCref = getProperty("LowResRef");
  minwl = getProperty("CropWavelengthMin");
  maxwl = getProperty("CropWavelengthMax");
  if (maxwl == 0.)
    maxwl = EMPTY_DBL(); // python can only specify 0 for unused
  tmin = getProperty("TMin");
  tmax = getProperty("TMax");
  m_preserveEvents = getProperty("PreserveEvents");
  m_resampleX = getProperty("ResampleX");
  // determine some bits about d-space and binning
  if (m_resampleX != 0) {
    m_params.clear(); // ignore the normal rebin parameters
  } else if (m_params.size() == 1) {
    if (dmax > 0.)
      dspace = true;
    else
      dspace = false;
  }
  if (dspace) {
    if (m_params.size() == 1 && dmax > 0) {
      double step = m_params[0];
      m_params.clear();
      if (step > 0 || dmin > 0) {
        m_params.push_back(dmin);
        m_params.push_back(step);
        m_params.push_back(dmax);
        g_log.information() << "d-Spacing Binning: " << m_params[0] << "  "
                            << m_params[1] << "  " << m_params[2] << "\n";
      }
    }
  } else {
    if (m_params.size() == 1 && tmax > 0) {
      double step = m_params[0];
      if (step > 0 || tmin > 0) {
        m_params[0] = tmin;
        m_params.push_back(step);
        m_params.push_back(tmax);
        g_log.information() << "TOF Binning: " << m_params[0] << "  "
                            << m_params[1] << "  " << m_params[2] << "\n";
      }
    }
  }
  xmin = 0.;
  xmax = 0.;
  if (tmin > 0.) {
    xmin = tmin;
  }
  if (tmax > 0.) {
    xmax = tmax;
  }
  if (!dspace && m_params.size() == 3) {
    xmin = m_params[0];
    xmax = m_params[2];
  }

  // Low resolution
  int lowresoffset = getProperty("LowResSpectrumOffset");
  if (lowresoffset < 0) {
    m_processLowResTOF = false;
  } else {
    m_processLowResTOF = true;
    m_lowResSpecOffset = static_cast<size_t>(lowresoffset);
  }

  loadCalFile(calFilename, groupFilename);

  // Now setup the output workspace
  m_outputW = getProperty("OutputWorkspace");
  if (m_inputEW) {
    if (m_outputW != m_inputW) {
      m_outputEW = m_inputEW->clone();
    }
    m_outputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW);
  } else {
    if (m_outputW != m_inputW) {
      m_outputW = WorkspaceFactory::Instance().create(m_inputW);
    }
  }

  if (m_processLowResTOF) {
    if (!m_inputEW) {
      throw std::runtime_error(
          "Input workspace is not EventWorkspace.  It is not supported now.");
    } else {
      // Make a brand new EventWorkspace
      m_lowResEW = boost::dynamic_pointer_cast<EventWorkspace>(
          WorkspaceFactory::Instance().create(
              "EventWorkspace", m_inputEW->getNumberHistograms(), 2, 1));

      // Cast to the matrixOutputWS and save it
      m_lowResW = boost::dynamic_pointer_cast<MatrixWorkspace>(m_lowResEW);
      // m_lowResW->setName(lowreswsname);
    }
  }

  // set up a progress bar with the "correct" number of steps
  m_progress = new Progress(this, 0., 1., 22);

  if (m_inputEW) {
    double tolerance = getProperty("CompressTolerance");
    if (tolerance > 0.) {
      g_log.information() << "running CompressEvents(Tolerance=" << tolerance
                          << ") started at "
                          << Kernel::DateAndTime::getCurrentTime() << "\n";
      API::IAlgorithm_sptr compressAlg = createChildAlgorithm("CompressEvents");
      compressAlg->setProperty("InputWorkspace", m_outputEW);
      compressAlg->setProperty("OutputWorkspace", m_outputEW);
      compressAlg->setProperty("OutputWorkspace", m_outputEW);
      compressAlg->setProperty("Tolerance", tolerance);
      compressAlg->executeAsChildAlg();
      m_outputEW = compressAlg->getProperty("OutputWorkspace");
      m_outputW = boost::dynamic_pointer_cast<MatrixWorkspace>(m_outputEW);
    } else {
      g_log.information() << "Not compressing event list\n";
      doSortEvents(m_outputW); // still sort to help some thing out
    }
  }
  m_progress->report();

  if (xmin > 0. || xmax > 0.) {
    double tempmin;
    double tempmax;
    m_outputW->getXMinMax(tempmin, tempmax);

    g_log.information() << "running CropWorkspace(TOFmin=" << xmin
                        << ", TOFmax=" << xmax << ") started at "
                        << Kernel::DateAndTime::getCurrentTime() << "\n";
    API::IAlgorithm_sptr cropAlg = createChildAlgorithm("CropWorkspace");
    cropAlg->setProperty("InputWorkspace", m_outputW);
    cropAlg->setProperty("OutputWorkspace", m_outputW);
    if ((xmin > 0.) && (xmin > tempmin))
      cropAlg->setProperty("Xmin", xmin);
    if ((xmax > 0.) && (xmax < tempmax))
      cropAlg->setProperty("Xmax", xmax);
    cropAlg->executeAsChildAlg();
    m_outputW = cropAlg->getProperty("OutputWorkspace");
    m_outputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW);
  }
  m_progress->report();

  // filter the input events if appropriate
  double removePromptPulseWidth = getProperty("RemovePromptPulseWidth");
  if (removePromptPulseWidth > 0.) {
    m_outputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW);
    if (m_outputEW->getNumberEvents() > 0) {
      g_log.information() << "running RemovePromptPulse(Width="
                          << removePromptPulseWidth << ") started at "
                          << Kernel::DateAndTime::getCurrentTime() << "\n";
      API::IAlgorithm_sptr filterPAlg =
          createChildAlgorithm("RemovePromptPulse");
      filterPAlg->setProperty("InputWorkspace", m_outputW);
      filterPAlg->setProperty("OutputWorkspace", m_outputW);
      filterPAlg->setProperty("Width", removePromptPulseWidth);
      filterPAlg->executeAsChildAlg();
      m_outputW = filterPAlg->getProperty("OutputWorkspace");
      m_outputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW);
    } else {
      g_log.information("skipping RemovePromptPulse on empty EventWorkspace");
    }
  }
  m_progress->report();

  if (maskBinTableWS) {
    g_log.information() << "running MaskBinsFromTable started at "
                        << Kernel::DateAndTime::getCurrentTime() << "\n";
    API::IAlgorithm_sptr alg = createChildAlgorithm("MaskBinsFromTable");
    alg->setProperty("InputWorkspace", m_outputW);
    alg->setProperty("OutputWorkspace", m_outputW);
    alg->setProperty("MaskingInformation", maskBinTableWS);
    alg->executeAsChildAlg();
    m_outputW = alg->getProperty("OutputWorkspace");
    m_outputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW);
  }
  m_progress->report();

  if (m_maskWS) {
    g_log.information() << "running MaskDetectors started at "
                        << Kernel::DateAndTime::getCurrentTime() << "\n";
    API::IAlgorithm_sptr maskAlg = createChildAlgorithm("MaskDetectors");
    maskAlg->setProperty("Workspace", m_outputW);
    maskAlg->setProperty("MaskedWorkspace", m_maskWS);
    maskAlg->executeAsChildAlg();
    Workspace_sptr tmpW = maskAlg->getProperty("Workspace");
    m_outputW = boost::dynamic_pointer_cast<MatrixWorkspace>(tmpW);
    m_outputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW);
  }
  m_progress->report();

  if (!dspace)
    m_outputW = rebin(m_outputW);
  m_progress->report();

  if (m_calibrationWS) {
    g_log.information() << "running AlignDetectors started at "
                        << Kernel::DateAndTime::getCurrentTime() << "\n";
    API::IAlgorithm_sptr alignAlg = createChildAlgorithm("AlignDetectors");
    alignAlg->setProperty("InputWorkspace", m_outputW);
    alignAlg->setProperty("OutputWorkspace", m_outputW);
    alignAlg->setProperty("CalibrationWorkspace", m_calibrationWS);
    alignAlg->executeAsChildAlg();
    m_outputW = alignAlg->getProperty("OutputWorkspace");
  } else {
    m_outputW = convertUnits(m_outputW, "dSpacing");
  }
  m_progress->report();

  if (LRef > 0. || minwl > 0. || DIFCref > 0. || (!isEmpty(maxwl))) {
    m_outputW = convertUnits(m_outputW, "TOF");
  }
  m_progress->report();

  // Beyond this point, low resolution TOF workspace is considered.
  if (LRef > 0.) {
    g_log.information() << "running UnwrapSNS(LRef=" << LRef << ",Tmin=" << tmin
                        << ",Tmax=" << tmax << ") started at "
                        << Kernel::DateAndTime::getCurrentTime() << "\n";
    API::IAlgorithm_sptr removeAlg = createChildAlgorithm("UnwrapSNS");
    removeAlg->setProperty("InputWorkspace", m_outputW);
    removeAlg->setProperty("OutputWorkspace", m_outputW);
    removeAlg->setProperty("LRef", LRef);
    if (tmin > 0.)
      removeAlg->setProperty("Tmin", tmin);
    if (tmax > tmin)
      removeAlg->setProperty("Tmax", tmax);
    removeAlg->executeAsChildAlg();
    m_outputW = removeAlg->getProperty("OutputWorkspace");
  }
  m_progress->report();

  if (minwl > 0. || (!isEmpty(maxwl))) { // just crop the worksapce
    // turn off the low res stuff
    m_processLowResTOF = false;

    EventWorkspace_sptr ews =
        boost::dynamic_pointer_cast<EventWorkspace>(m_outputW);
    if (ews)
      g_log.information() << "Number of events = " << ews->getNumberEvents()
                          << ". ";
    g_log.information("\n");

    m_outputW = convertUnits(m_outputW, "Wavelength");

    g_log.information() << "running CropWorkspace(WavelengthMin=" << minwl;
    if (!isEmpty(maxwl))
      g_log.information() << ", WavelengthMax=" << maxwl;
    g_log.information() << ") started at "
                        << Kernel::DateAndTime::getCurrentTime() << "\n";

    API::IAlgorithm_sptr removeAlg = createChildAlgorithm("CropWorkspace");
    removeAlg->setProperty("InputWorkspace", m_outputW);
    removeAlg->setProperty("OutputWorkspace", m_outputW);
    removeAlg->setProperty("XMin", minwl);
    removeAlg->setProperty("XMax", maxwl);
    removeAlg->executeAsChildAlg();
    m_outputW = removeAlg->getProperty("OutputWorkspace");
    if (ews)
      g_log.information() << "Number of events = " << ews->getNumberEvents()
                          << ".\n";
  } else if (DIFCref > 0.) {
    g_log.information() << "running RemoveLowResTof(RefDIFC=" << DIFCref
                        << ",K=3.22) started at "
                        << Kernel::DateAndTime::getCurrentTime() << "\n";
    EventWorkspace_sptr ews =
        boost::dynamic_pointer_cast<EventWorkspace>(m_outputW);
    if (ews)
      g_log.information() << "Number of events = " << ews->getNumberEvents()
                          << ". ";
    g_log.information("\n");

    API::IAlgorithm_sptr removeAlg = createChildAlgorithm("RemoveLowResTOF");
    removeAlg->setProperty("InputWorkspace", m_outputW);
    removeAlg->setProperty("OutputWorkspace", m_outputW);
    removeAlg->setProperty("ReferenceDIFC", DIFCref);
    removeAlg->setProperty("K", 3.22);
    if (tmin > 0.)
      removeAlg->setProperty("Tmin", tmin);
    if (m_processLowResTOF)
      removeAlg->setProperty("LowResTOFWorkspace", m_lowResW);

    removeAlg->executeAsChildAlg();
    m_outputW = removeAlg->getProperty("OutputWorkspace");
    if (m_processLowResTOF)
      m_lowResW = removeAlg->getProperty("LowResTOFWorkspace");
  }
  m_progress->report();

  EventWorkspace_sptr ews =
      boost::dynamic_pointer_cast<EventWorkspace>(m_outputW);
  if (ews) {
    size_t numhighevents = ews->getNumberEvents();
    if (m_processLowResTOF) {
      EventWorkspace_sptr lowes =
          boost::dynamic_pointer_cast<EventWorkspace>(m_lowResW);
      size_t numlowevents = lowes->getNumberEvents();
      g_log.information() << "Number of high TOF events = " << numhighevents
                          << "; "
                          << "Number of low TOF events = " << numlowevents
                          << ".\n";
    }
  }
  m_progress->report();

  // Convert units
  if (LRef > 0. || minwl > 0. || DIFCref > 0. || (!isEmpty(maxwl))) {
    m_outputW = convertUnits(m_outputW, "dSpacing");
    if (m_processLowResTOF)
      m_lowResW = convertUnits(m_lowResW, "dSpacing");
  }
  m_progress->report();

  if (dspace) {
    m_outputW = rebin(m_outputW);
    if (m_processLowResTOF)
      m_lowResW = rebin(m_lowResW);
  }
  m_progress->report();

  doSortEvents(m_outputW);
  if (m_processLowResTOF)
    doSortEvents(m_lowResW);
  m_progress->report();

  // Diffraction focus
  m_outputW = diffractionFocus(m_outputW);
  if (m_processLowResTOF)
    m_lowResW = diffractionFocus(m_lowResW);
  m_progress->report();

  doSortEvents(m_outputW);
  if (m_processLowResTOF)
    doSortEvents(m_lowResW);
  m_progress->report();

  // this next call should probably be in for rebin as well
  // but it changes the system tests
  if (dspace && m_resampleX != 0) {
    m_outputW = rebin(m_outputW);
    if (m_processLowResTOF)
      m_lowResW = rebin(m_lowResW);
  }
  m_progress->report();

  // edit the instrument geometry
  if (m_groupWS &&
      (m_l1 > 0 || !tths.empty() || !l2s.empty() || !phis.empty())) {
    size_t numreg = m_outputW->getNumberHistograms();

    try {
      // set up the vectors for doing everything
      auto specidsSplit = splitVectors(specids, numreg, "specids");
      auto tthsSplit = splitVectors(tths, numreg, "two-theta");
      auto l2sSplit = splitVectors(l2s, numreg, "L2");
      auto phisSplit = splitVectors(phis, numreg, "phi");

      // Edit instrument
      m_outputW = editInstrument(m_outputW, tthsSplit.reg, specidsSplit.reg,
                                 l2sSplit.reg, phisSplit.reg);

      if (m_processLowResTOF) {
        m_lowResW = editInstrument(m_lowResW, tthsSplit.low, specidsSplit.low,
                                   l2sSplit.low, phisSplit.low);
      }
    } catch (std::runtime_error &e) {
      g_log.warning("Not editing instrument geometry:");
      g_log.warning(e.what());
    }
  }
  m_progress->report();

  // Conjoin 2 workspaces if there is low resolution
  if (m_processLowResTOF) {
    m_outputW = conjoinWorkspaces(m_outputW, m_lowResW, m_lowResSpecOffset);
  }
  m_progress->report();

  // Convert units to TOF
  m_outputW = convertUnits(m_outputW, "TOF");
  m_progress->report();

  // compress again if appropriate
  double tolerance = getProperty("CompressTolerance");
  m_outputEW = boost::dynamic_pointer_cast<EventWorkspace>(m_outputW);
  if ((m_outputEW) && (tolerance > 0.)) {
    g_log.information() << "running CompressEvents(Tolerance=" << tolerance
                        << ") started at "
                        << Kernel::DateAndTime::getCurrentTime() << "\n";
    API::IAlgorithm_sptr compressAlg = createChildAlgorithm("CompressEvents");
    compressAlg->setProperty("InputWorkspace", m_outputEW);
    compressAlg->setProperty("OutputWorkspace", m_outputEW);
    compressAlg->setProperty("OutputWorkspace", m_outputEW);
    compressAlg->setProperty("Tolerance", tolerance);
    compressAlg->executeAsChildAlg();
    m_outputEW = compressAlg->getProperty("OutputWorkspace");
    m_outputW = boost::dynamic_pointer_cast<MatrixWorkspace>(m_outputEW);
  }
  m_progress->report();

  if ((!m_params.empty()) && (m_params.size() != 1)) {
    m_params.erase(m_params.begin());
    m_params.pop_back();
  }
  if (!m_dmins.empty())
    m_dmins.clear();
  if (!m_dmaxs.empty())
    m_dmaxs.clear();

  m_outputW = rebin(m_outputW);
  m_progress->report();

  // return the output workspace
  setProperty("OutputWorkspace", m_outputW);
}
/**
  * Gaussian fit to determine peak position if no user position given.
  *
  * @return :: detector position of the peak: Gaussian fit and position
  * of the maximum (serves as start value for the optimization)
  */
double LoadILLReflectometry::reflectometryPeak() {
  if (!isDefault("BeamCentre")) {
    return getProperty("BeamCentre");
  }
  size_t startIndex;
  size_t endIndex;
  std::tie(startIndex, endIndex) =
      fitIntegrationWSIndexRange(*m_localWorkspace);
  IAlgorithm_sptr integration = createChildAlgorithm("Integration");
  integration->initialize();
  integration->setProperty("InputWorkspace", m_localWorkspace);
  integration->setProperty("OutputWorkspace", "__unused_for_child");
  integration->setProperty("StartWorkspaceIndex", static_cast<int>(startIndex));
  integration->setProperty("EndWorkspaceIndex", static_cast<int>(endIndex));
  integration->execute();
  MatrixWorkspace_sptr integralWS = integration->getProperty("OutputWorkspace");
  IAlgorithm_sptr transpose = createChildAlgorithm("Transpose");
  transpose->initialize();
  transpose->setProperty("InputWorkspace", integralWS);
  transpose->setProperty("OutputWorkspace", "__unused_for_child");
  transpose->execute();
  integralWS = transpose->getProperty("OutputWorkspace");
  rebinIntegralWorkspace(*integralWS);
  // determine initial height: maximum value
  const auto maxValueIt =
      std::max_element(integralWS->y(0).cbegin(), integralWS->y(0).cend());
  const double height = *maxValueIt;
  // determine initial centre: index of the maximum value
  const size_t maxIndex = std::distance(integralWS->y(0).cbegin(), maxValueIt);
  const double centreByMax = static_cast<double>(maxIndex);
  g_log.debug() << "Peak maximum position: " << centreByMax << '\n';
  // determine sigma
  const auto &ys = integralWS->y(0);
  auto lessThanHalfMax = [height](const double x) { return x < 0.5 * height; };
  using IterType = HistogramData::HistogramY::const_iterator;
  std::reverse_iterator<IterType> revMaxValueIt{maxValueIt};
  auto revMinFwhmIt = std::find_if(revMaxValueIt, ys.crend(), lessThanHalfMax);
  auto maxFwhmIt = std::find_if(maxValueIt, ys.cend(), lessThanHalfMax);
  std::reverse_iterator<IterType> revMaxFwhmIt{maxFwhmIt};
  if (revMinFwhmIt == ys.crend() || maxFwhmIt == ys.cend()) {
    g_log.warning() << "Couldn't determine fwhm of beam, using position of max "
                       "value as beam center.\n";
    return centreByMax;
  }
  const double fwhm =
      static_cast<double>(std::distance(revMaxFwhmIt, revMinFwhmIt) + 1);
  g_log.debug() << "Initial fwhm (full width at half maximum): " << fwhm
                << '\n';
  // generate Gaussian
  auto func =
      API::FunctionFactory::Instance().createFunction("CompositeFunction");
  auto sum = boost::dynamic_pointer_cast<API::CompositeFunction>(func);
  func = API::FunctionFactory::Instance().createFunction("Gaussian");
  auto gaussian = boost::dynamic_pointer_cast<API::IPeakFunction>(func);
  gaussian->setHeight(height);
  gaussian->setCentre(centreByMax);
  gaussian->setFwhm(fwhm);
  sum->addFunction(gaussian);
  func = API::FunctionFactory::Instance().createFunction("LinearBackground");
  func->setParameter("A0", 0.);
  func->setParameter("A1", 0.);
  sum->addFunction(func);
  // call Fit child algorithm
  API::IAlgorithm_sptr fit = createChildAlgorithm("Fit");
  fit->initialize();
  fit->setProperty("Function",
                   boost::dynamic_pointer_cast<API::IFunction>(sum));
  fit->setProperty("InputWorkspace", integralWS);
  fit->setProperty("StartX", centreByMax - 3 * fwhm);
  fit->setProperty("EndX", centreByMax + 3 * fwhm);
  fit->execute();
  const std::string fitStatus = fit->getProperty("OutputStatus");
  if (fitStatus != "success") {
    g_log.warning("Fit not successful, using position of max value.\n");
    return centreByMax;
  }
  const auto centre = gaussian->centre();
  g_log.debug() << "Sigma: " << gaussian->fwhm() << '\n';
  g_log.debug() << "Estimated peak position: " << centre << '\n';
  return centre;
}
Exemple #18
0
/**
 * Execute the algorithm.
 */
void LoadBBY::exec() {
  // Delete the output workspace name if it existed
  std::string outName = getPropertyValue("OutputWorkspace");
  if (API::AnalysisDataService::Instance().doesExist(outName))
    API::AnalysisDataService::Instance().remove(outName);

  // Get the name of the data file.
  std::string filename = getPropertyValue(FilenameStr);
  ANSTO::Tar::File tarFile(filename);
  if (!tarFile.good())
    throw std::invalid_argument("invalid BBY file");

  // region of intreset
  std::vector<bool> roi = createRoiVector(getPropertyValue(MaskStr));

  double tofMinBoundary = getProperty(FilterByTofMinStr);
  double tofMaxBoundary = getProperty(FilterByTofMaxStr);

  double timeMinBoundary = getProperty(FilterByTimeStartStr);
  double timeMaxBoundary = getProperty(FilterByTimeStopStr);

  if (isEmpty(tofMaxBoundary))
    tofMaxBoundary = std::numeric_limits<double>::infinity();
  if (isEmpty(timeMaxBoundary))
    timeMaxBoundary = std::numeric_limits<double>::infinity();

  API::Progress prog(this, 0.0, 1.0, Progress_Total);
  prog.doReport("creating instrument");

  // create workspace
  DataObjects::EventWorkspace_sptr eventWS =
      boost::make_shared<DataObjects::EventWorkspace>();

  eventWS->initialize(HISTO_BINS_Y * HISTO_BINS_X,
                      2, // number of TOF bin boundaries
                      1);

  // set the units
  eventWS->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("TOF");
  eventWS->setYUnit("Counts");

  // set title
  const std::vector<std::string> &subFiles = tarFile.files();
  for (const auto &subFile : subFiles)
    if (subFile.compare(0, 3, "BBY") == 0) {
      std::string title = subFile;

      if (title.rfind(".hdf") == title.length() - 4)
        title.resize(title.length() - 4);

      if (title.rfind(".nx") == title.length() - 3)
        title.resize(title.length() - 3);

      eventWS->setTitle(title);
      break;
    }

  // create instrument
  InstrumentInfo instrumentInfo;

  // Geometry::Instrument_sptr instrument =
  createInstrument(tarFile, /* ref */ instrumentInfo);
  // eventWS->setInstrument(instrument);

  // load events
  size_t numberHistograms = eventWS->getNumberHistograms();

  std::vector<EventVector_pt> eventVectors(numberHistograms, nullptr);
  std::vector<size_t> eventCounts(numberHistograms, 0);

  // phase correction
  Kernel::Property *periodMasterProperty =
      getPointerToProperty(PeriodMasterStr);
  Kernel::Property *periodSlaveProperty = getPointerToProperty(PeriodSlaveStr);
  Kernel::Property *phaseSlaveProperty = getPointerToProperty(PhaseSlaveStr);

  double periodMaster;
  double periodSlave;
  double phaseSlave;

  if (periodMasterProperty->isDefault() || periodSlaveProperty->isDefault() ||
      phaseSlaveProperty->isDefault()) {

    if (!periodMasterProperty->isDefault() ||
        !periodSlaveProperty->isDefault() || !phaseSlaveProperty->isDefault()) {
      throw std::invalid_argument("Please specify PeriodMaster, PeriodSlave "
                                  "and PhaseSlave or none of them.");
    }

    // if values have not been specified in loader then use values from hdf file
    periodMaster = instrumentInfo.period_master;
    periodSlave = instrumentInfo.period_slave;
    phaseSlave = instrumentInfo.phase_slave;
  } else {
    periodMaster = getProperty(PeriodMasterStr);
    periodSlave = getProperty(PeriodSlaveStr);
    phaseSlave = getProperty(PhaseSlaveStr);

    if ((periodMaster < 0.0) || (periodSlave < 0.0))
      throw std::invalid_argument(
          "Please specify a positive value for PeriodMaster and PeriodSlave.");
  }

  double period = periodSlave;
  double shift = -1.0 / 6.0 * periodMaster - periodSlave * phaseSlave / 360.0;

  // count total events per pixel to reserve necessary memory
  ANSTO::EventCounter eventCounter(
      roi, HISTO_BINS_Y, period, shift, tofMinBoundary, tofMaxBoundary,
      timeMinBoundary, timeMaxBoundary, eventCounts);

  loadEvents(prog, "loading neutron counts", tarFile, eventCounter);

  // prepare event storage
  ANSTO::ProgressTracker progTracker(prog, "creating neutron event lists",
                                     numberHistograms, Progress_ReserveMemory);

  for (size_t i = 0; i != numberHistograms; ++i) {
    DataObjects::EventList &eventList = eventWS->getEventList(i);

    eventList.setSortOrder(DataObjects::PULSETIME_SORT);
    eventList.reserve(eventCounts[i]);

    eventList.setDetectorID(static_cast<detid_t>(i));
    eventList.setSpectrumNo(static_cast<detid_t>(i));

    DataObjects::getEventsFrom(eventList, eventVectors[i]);

    progTracker.update(i);
  }
  progTracker.complete();

  ANSTO::EventAssigner eventAssigner(
      roi, HISTO_BINS_Y, period, shift, tofMinBoundary, tofMaxBoundary,
      timeMinBoundary, timeMaxBoundary, eventVectors);

  loadEvents(prog, "loading neutron events", tarFile, eventAssigner);

  Kernel::cow_ptr<MantidVec> axis;
  MantidVec &xRef = axis.access();
  xRef.resize(2, 0.0);
  xRef[0] = std::max(
      0.0,
      floor(eventCounter.tofMin())); // just to make sure the bins hold it all
  xRef[1] = eventCounter.tofMax() + 1;
  eventWS->setAllX(axis);

  // count total number of masked bins
  size_t maskedBins = 0;
  for (size_t i = 0; i != roi.size(); i++)
    if (!roi[i])
      maskedBins++;

  if (maskedBins > 0) {
    // create list of masked bins
    std::vector<size_t> maskIndexList(maskedBins);
    size_t maskIndex = 0;

    for (size_t i = 0; i != roi.size(); i++)
      if (!roi[i])
        maskIndexList[maskIndex++] = i;

    API::IAlgorithm_sptr maskingAlg = createChildAlgorithm("MaskDetectors");
    maskingAlg->setProperty("Workspace", eventWS);
    maskingAlg->setProperty("WorkspaceIndexList", maskIndexList);
    maskingAlg->executeAsChildAlg();
  }

  // set log values
  API::LogManager &logManager = eventWS->mutableRun();

  logManager.addProperty("filename", filename);
  logManager.addProperty("att_pos", static_cast<int>(instrumentInfo.att_pos));
  logManager.addProperty("frame_count",
                         static_cast<int>(eventCounter.numFrames()));
  logManager.addProperty("period", period);

  // currently beam monitor counts are not available, instead number of frames
  // times period is used
  logManager.addProperty(
      "bm_counts", static_cast<double>(eventCounter.numFrames()) * period /
                       1.0e6); // static_cast<double>(instrumentInfo.bm_counts)

  // currently
  Kernel::time_duration duration =
      boost::posix_time::microseconds(static_cast<boost::int64_t>(
          static_cast<double>(eventCounter.numFrames()) * period));

  Kernel::DateAndTime start_time("2000-01-01T00:00:00");
  Kernel::DateAndTime end_time(start_time + duration);

  logManager.addProperty("start_time", start_time.toISO8601String());
  logManager.addProperty("end_time", end_time.toISO8601String());

  std::string time_str = start_time.toISO8601String();
  AddSinglePointTimeSeriesProperty(logManager, time_str, "L1_chopper_value",
                                   instrumentInfo.L1_chopper_value);
  AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_det_value",
                                   instrumentInfo.L2_det_value);
  AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_curtainl_value",
                                   instrumentInfo.L2_curtainl_value);
  AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_curtainr_value",
                                   instrumentInfo.L2_curtainr_value);
  AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_curtainu_value",
                                   instrumentInfo.L2_curtainu_value);
  AddSinglePointTimeSeriesProperty(logManager, time_str, "L2_curtaind_value",
                                   instrumentInfo.L2_curtaind_value);
  AddSinglePointTimeSeriesProperty(logManager, time_str, "D_det_value",
                                   instrumentInfo.D_det_value);
  AddSinglePointTimeSeriesProperty(logManager, time_str, "D_curtainl_value",
                                   instrumentInfo.D_curtainl_value);
  AddSinglePointTimeSeriesProperty(logManager, time_str, "D_curtainr_value",
                                   instrumentInfo.D_curtainr_value);
  AddSinglePointTimeSeriesProperty(logManager, time_str, "D_curtainu_value",
                                   instrumentInfo.D_curtainu_value);
  AddSinglePointTimeSeriesProperty(logManager, time_str, "D_curtaind_value",
                                   instrumentInfo.D_curtaind_value);
  AddSinglePointTimeSeriesProperty(logManager, time_str, "curtain_rotation",
                                   10.0);

  API::IAlgorithm_sptr loadInstrumentAlg =
      createChildAlgorithm("LoadInstrument");
  loadInstrumentAlg->setProperty("Workspace", eventWS);
  loadInstrumentAlg->setPropertyValue("InstrumentName", "BILBY");
  loadInstrumentAlg->setProperty("RewriteSpectraMap",
                                 Mantid::Kernel::OptionalBool(false));
  loadInstrumentAlg->executeAsChildAlg();

  setProperty("OutputWorkspace", eventWS);
}
/** Calls Gaussian1D as a child algorithm to fit the offset peak in a spectrum
  *
  * @param wi :: The Workspace Index to fit.
  * @param inputW :: Input workspace.
  * @param peakPositions :: Peak positions.
  * @param fitWindows :: Fit windows.
  * @param nparams :: Number of parameters.
  * @param minD :: Min distance.
  * @param maxD :: Max distance.
  * @param peakPosToFit :: Actual peak positions to fit (output).
  * @param peakPosFitted :: Actual peak positions fitted (output).
  * @param chisq :: chisq.
  * @param peakHeights :: vector for fitted heights of peaks
  * @param i_highestpeak:: index of the highest peak among all peaks
  * @param resolution :: spectrum's resolution delta(d)/d
  * @param dev_resolution :: standard deviation resolution
  * @return The number of peaks in range
  */
int GetDetOffsetsMultiPeaks::fitSpectra(
    const int64_t wi, MatrixWorkspace_sptr inputW,
    const std::vector<double> &peakPositions,
    const std::vector<double> &fitWindows, size_t &nparams, double &minD,
    double &maxD, std::vector<double> &peakPosToFit,
    std::vector<double> &peakPosFitted, std::vector<double> &chisq,
    std::vector<double> &peakHeights, int &i_highestpeak, double &resolution,
    double &dev_resolution) {
  // Default overall fit range is the whole spectrum
  const MantidVec &X = inputW->readX(wi);
  minD = X.front();
  maxD = X.back();

  // Trim in the edges based on where the data turns off of zero
  const MantidVec &Y = inputW->readY(wi);
  size_t minDindex = 0;
  for (; minDindex < Y.size(); ++minDindex) {
    if (Y[minDindex] > 0.) {
      minD = X[minDindex];
      break;
    }
  }
  if (minD >= maxD) {
    // throw if minD >= maxD
    std::stringstream ess;
    ess << "Stuff went wrong with wkspIndex=" << wi
        << " specIndex=" << inputW->getSpectrum(wi)->getSpectrumNo();
    throw std::runtime_error(ess.str());
  }

  size_t maxDindex = Y.size() - 1;
  for (; maxDindex > minDindex; --maxDindex) {
    if (Y[maxDindex] > 0.) {
      maxD = X[maxDindex];
      break;
    }
  }
  std::stringstream dbss;
  dbss << "D-RANGE[" << inputW->getSpectrum(wi)->getSpectrumNo()
       << "]: " << minD << " -> " << maxD;
  g_log.debug(dbss.str());

  // Setup the fit windows
  bool useFitWindows = (!fitWindows.empty());
  std::vector<double> fitWindowsToUse;
  for (int i = 0; i < static_cast<int>(peakPositions.size()); ++i) {
    if ((peakPositions[i] > minD) && (peakPositions[i] < maxD)) {
      if (m_useFitWindowTable) {
        fitWindowsToUse.push_back(std::max(m_vecFitWindow[wi][2 * i], minD));
        fitWindowsToUse.push_back(
            std::min(m_vecFitWindow[wi][2 * i + 1], maxD));
      } else if (useFitWindows) {
        fitWindowsToUse.push_back(std::max(fitWindows[2 * i], minD));
        fitWindowsToUse.push_back(std::min(fitWindows[2 * i + 1], maxD));
      }
      peakPosToFit.push_back(peakPositions[i]);
    }
  }
  int numPeaksInRange = static_cast<int>(peakPosToFit.size());
  if (numPeaksInRange == 0) {
    std::stringstream outss;
    outss << "Spectrum " << wi << " has no peak in range (" << minD << ", "
          << maxD << ")";
    g_log.information(outss.str());
    return 0;
  }

  // Fit peaks
  API::IAlgorithm_sptr findpeaks =
      createChildAlgorithm("FindPeaks", -1, -1, false);
  findpeaks->setProperty("InputWorkspace", inputW);
  findpeaks->setProperty<int>("FWHM", 7);
  findpeaks->setProperty<int>("Tolerance", 4);
  // FindPeaks will do the checking on the validity of WorkspaceIndex
  findpeaks->setProperty("WorkspaceIndex", static_cast<int>(wi));

  // Get the specified peak positions, which is optional
  findpeaks->setProperty("PeakPositions", peakPosToFit);
  if (useFitWindows)
    findpeaks->setProperty("FitWindows", fitWindowsToUse);
  findpeaks->setProperty<std::string>("PeakFunction", m_peakType);
  findpeaks->setProperty<std::string>("BackgroundType", m_backType);
  findpeaks->setProperty<bool>("HighBackground",
                               this->getProperty("HighBackground"));
  findpeaks->setProperty<int>("MinGuessedPeakWidth", 4);
  findpeaks->setProperty<int>("MaxGuessedPeakWidth", 4);
  findpeaks->setProperty<double>("MinimumPeakHeight", m_minPeakHeight);
  findpeaks->setProperty("StartFromObservedPeakCentre", true);
  findpeaks->executeAsChildAlg();

  // Collect fitting resutl of all peaks
  ITableWorkspace_sptr peakslist = findpeaks->getProperty("PeaksList");

  // use tmpPeakPosToFit to shuffle the vectors
  std::vector<double> tmpPeakPosToFit;
  generatePeaksList(peakslist, static_cast<int>(wi), peakPosToFit,
                    tmpPeakPosToFit, peakPosFitted, peakHeights, chisq,
                    (useFitWindows || m_useFitWindowTable), fitWindowsToUse,
                    minD, maxD, resolution, dev_resolution);
  peakPosToFit = tmpPeakPosToFit;

  nparams = peakPosFitted.size();

  // Find the highest peak
  i_highestpeak = -1;
  double maxheight = 0;
  for (int i = 0; i < static_cast<int>(peakPosFitted.size()); ++i) {
    double tmpheight = peakHeights[i];
    if (tmpheight > maxheight) {
      maxheight = tmpheight;
      i_highestpeak = i;
    }
  }

  return numPeaksInRange;
}
Exemple #20
0
    /** 
    *   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)
      }
    }
void GoniometerAnglesFromPhiRotation::exec() {

  PeaksWorkspace_sptr PeaksRun1 = getProperty("PeaksWorkspace1");
  PeaksWorkspace_sptr PeaksRun2 = getProperty("PeaksWorkspace2");

  double Tolerance = getProperty("Tolerance");

  Kernel::Matrix<double> Gon1(3, 3);
  Kernel::Matrix<double> Gon2(3, 3);
  if (!CheckForOneRun(PeaksRun1, Gon1) || !CheckForOneRun(PeaksRun2, Gon2)) {
    g_log.error("Each peaks workspace MUST have only one run");
    throw std::invalid_argument("Each peaks workspace MUST have only one run");
  }

  Kernel::Matrix<double> UB1;

  bool Run1HasOrientedLattice = true;
  if (!PeaksRun1->sample().hasOrientedLattice()) {

    Run1HasOrientedLattice = false;

    const std::string fft("FindUBUsingFFT");
    API::IAlgorithm_sptr findUB = this->createChildAlgorithm(fft);
    findUB->initialize();
    findUB->setProperty<PeaksWorkspace_sptr>("PeaksWorkspace",
                                             getProperty("PeaksWorkspace1"));
    findUB->setProperty("MIND", static_cast<double>(getProperty("MIND")));
    findUB->setProperty("MAXD", static_cast<double>(getProperty("MAXD")));
    findUB->setProperty("Tolerance", Tolerance);

    findUB->executeAsChildAlg();

    if (!PeaksRun1->sample().hasOrientedLattice()) {
      g_log.notice(std::string("Could not find UB for ") +
                   std::string(PeaksRun1->getName()));
      throw std::invalid_argument(std::string("Could not find UB for ") +
                                  std::string(PeaksRun1->getName()));
    }
  }
  //-------------get UB raw :No goniometer----------------

  UB1 = PeaksRun1->sample().getOrientedLattice().getUB();

  UB1 = getUBRaw(UB1, Gon1);

  int N1;
  double avErrIndx, avErrAll;
  IndexRaw(PeaksRun1, UB1, N1, avErrIndx, avErrAll, Tolerance);

  if (N1 < .6 * PeaksRun1->getNumberPeaks()) {
    g_log.notice(std::string("UB did not index well for ") +
                 std::string(PeaksRun1->getName()));
    throw std::invalid_argument(std::string("UB did not index well for ") +
                                std::string(PeaksRun1->getName()));
  }

  //----------------------------------------------

  Geometry::OrientedLattice lat2 = PeaksRun1->sample().getOrientedLattice();

  lat2.setUB(UB1);
  PeaksRun2->mutableSample().setOrientedLattice(&lat2);

  if (!Run1HasOrientedLattice)
    PeaksRun1->mutableSample().setOrientedLattice(nullptr);

  double dphi = static_cast<double>(getProperty("Phi2")) -
                static_cast<double>(getProperty("Run1Phi"));
  Kernel::Matrix<double> Gon22(3, 3, true);

  for (int i = 0; i < PeaksRun2->getNumberPeaks(); i++) {
    PeaksRun2->getPeak(i).setGoniometerMatrix(Gon22);
  }

  int RunNum = PeaksRun2->getPeak(0).getRunNumber();
  std::string RunNumStr = std::to_string(RunNum);
  int Npeaks = PeaksRun2->getNumberPeaks();

  // n indexed, av err, phi, chi,omega
  std::array<double, 5> MinData = {{0., 0., 0., 0., 0.}};
  MinData[0] = 0.0;
  std::vector<V3D> directionList = IndexingUtils::MakeHemisphereDirections(50);

  API::FrameworkManager::Instance();

  for (auto dir : directionList)
    for (int sgn = 1; sgn > -2; sgn -= 2) {
      dir.normalize();
      Quat Q(sgn * dphi, dir);
      Q.normalize();
      Kernel::Matrix<double> Rot(Q.getRotation());

      int Nindexed;
      double dummyAvErrIndx, dummyAvErrAll;
      IndexRaw(PeaksRun2, Rot * UB1, Nindexed, dummyAvErrIndx, dummyAvErrAll,
               Tolerance);

      if (Nindexed > MinData[0]) {
        MinData[0] = Nindexed;
        MinData[1] = sgn;
        MinData[2] = dir[0];

        MinData[3] = dir[1];
        MinData[4] = dir[2];
      }
    }

  g_log.debug() << "Best direction unOptimized is ("
                << (MinData[1] * MinData[2]) << "," << (MinData[1] * MinData[3])
                << "," << (MinData[1] * MinData[4]) << ")\n";

  //----------------------- Optimize around best----------------------------

  auto ws = createWorkspace<Workspace2D>(1, 3 * Npeaks, 3 * Npeaks);

  MantidVec Xvals;

  for (int i = 0; i < Npeaks; ++i) {
    Xvals.push_back(i);
    Xvals.push_back(i);
    Xvals.push_back(i);
  }

  ws->setPoints(0, Xvals);

  //--------------------Set up other Fit function arguments------------------
  V3D dir(MinData[2], MinData[3], MinData[4]);
  dir.normalize();
  Quat Q(MinData[1] * dphi, dir);
  Q.normalize();
  Kernel::Matrix<double> Rot(Q.getRotation());

  Goniometer Gon(Rot);
  std::vector<double> omchiphi = Gon.getEulerAngles("yzy");
  MinData[2] = omchiphi[2];
  MinData[3] = omchiphi[1];
  MinData[4] = omchiphi[0];

  std::string FunctionArgs =
      "name=PeakHKLErrors, PeakWorkspaceName=" + PeaksRun2->getName() +
      ",OptRuns=" + RunNumStr + ",phi" + RunNumStr + "=" +
      boost::lexical_cast<std::string>(MinData[2]) + ",chi" + RunNumStr + "=" +
      boost::lexical_cast<std::string>(MinData[3]) + ",omega" + RunNumStr +
      "=" + boost::lexical_cast<std::string>(MinData[4]);

  std::string Constr = boost::lexical_cast<std::string>(MinData[2] - 5) +
                       "<phi" + RunNumStr + "<" +
                       boost::lexical_cast<std::string>(MinData[2] + 5);
  Constr += "," + boost::lexical_cast<std::string>(MinData[3] - 5) + "<chi" +
            RunNumStr + "<" + boost::lexical_cast<std::string>(MinData[3] + 5) +
            ",";

  Constr += boost::lexical_cast<std::string>(MinData[4] - 5) + "<omega" +
            RunNumStr + "<" + boost::lexical_cast<std::string>(MinData[4] + 5);

  std::string Ties = "SampleXOffset=0.0,SampleYOffset=0.0,SampleZOffset=0.0,"
                     "GonRotx=0.0,GonRoty=0.0,GonRotz=0.0";

  boost::shared_ptr<Algorithm> Fit = createChildAlgorithm("Fit");

  Fit->initialize();
  Fit->setProperty("Function", FunctionArgs);
  Fit->setProperty("Ties", Ties);
  Fit->setProperty("Constraints", Constr);
  Fit->setProperty("InputWorkspace", ws);
  Fit->setProperty("CreateOutput", true);

  std::string outputName = "out";

  Fit->setProperty("Output", outputName);

  Fit->executeAsChildAlg();

  boost::shared_ptr<API::ITableWorkspace> results =
      Fit->getProperty("OutputParameters");
  double chisq = Fit->getProperty("OutputChi2overDoF");

  MinData[0] = chisq;
  MinData[2] = results->Double(6, 1);
  MinData[3] = results->Double(7, 1);
  MinData[4] = results->Double(8, 1);

  g_log.debug() << "Best direction Optimized is (" << (MinData[2]) << ","
                << (MinData[3]) << "," << (MinData[4]) << ")\n";

  //          ---------------------Find number indexed -----------------------
  Quat Q1 = Quat(MinData[4], V3D(0, 1, 0)) * Quat(MinData[3], V3D(0, 0, 1)) *
            Quat(MinData[2], V3D(0, 1, 0));

  int Nindexed;
  Kernel::Matrix<double> Mk(Q1.getRotation());
  IndexRaw(PeaksRun2, Mk * UB1, Nindexed, avErrIndx, avErrAll, Tolerance);

  //------------------------------------ Convert/Save Results
  //-----------------------------

  double deg, ax1, ax2, ax3;
  Q1.getAngleAxis(deg, ax1, ax2, ax3);
  if (dphi * deg < 0) {
    deg = -deg;
    ax1 = -ax1;
    ax2 = -ax2;
    ax3 = -ax3;
  }

  double phi2 = static_cast<double>(getProperty("Run1Phi")) + dphi;
  double chi2 = acos(ax2) / M_PI * 180;
  double omega2 = atan2(ax3, -ax1) / M_PI * 180;

  g_log.notice()
      << "============================ Results ============================\n";
  g_log.notice() << "     phi,chi, and omega= (" << phi2 << "," << chi2 << ","
                 << omega2 << ")\n";
  g_log.notice() << "     #indexed =" << Nindexed << '\n';
  g_log.notice()
      << "              ==============================================\n";

  setProperty("Phi2", phi2);
  setProperty("Chi2", chi2);
  setProperty("Omega2", omega2);

  setProperty("NIndexed", Nindexed);

  setProperty("AvErrIndex", avErrIndx);

  setProperty("AvErrAll", avErrAll);

  Q1 = Quat(omega2, V3D(0, 1, 0)) * Quat(chi2, V3D(0, 0, 1)) *
       Quat(phi2, V3D(0, 1, 0));
  Kernel::Matrix<double> Gon2a(Q1.getRotation());
  for (int i = 0; i < PeaksRun2->getNumberPeaks(); i++) {
    PeaksRun2->getPeak(i).setGoniometerMatrix(Gon2a);
  }

  OrientedLattice latt2(PeaksRun2->mutableSample().getOrientedLattice());
  // Kernel::Matrix<double> UB = latt2.getUB();
  Rot.Invert();
  Gon2a.Invert();
  latt2.setUB(Gon2a * Mk * UB1);

  PeaksRun2->mutableSample().setOrientedLattice(&latt2);
}
Exemple #22
0
/** Executes the algorithm
 *
 *  @throw Exception::FileError If the grouping file cannot be opened or read successfully
 *  @throw runtime_error If unable to run one of the sub-algorithms successfully
 */
void DiffractionFocussing::exec()
{
  // retrieve the properties
  std::string groupingFileName=getProperty("GroupingFileName");

  // Get the input workspace
  MatrixWorkspace_sptr inputW = getProperty("InputWorkspace");

  bool dist = inputW->isDistribution();

  //do this first to check that a valid file is available before doing any work
  std::multimap<int64_t,int64_t> detectorGroups;// <group, UDET>
  if (!readGroupingFile(groupingFileName, detectorGroups))
  {
    throw Exception::FileError("Error reading .cal file",groupingFileName);
  }

  //Convert to d-spacing units
  API::MatrixWorkspace_sptr tmpW = convertUnitsToDSpacing(inputW);

  //Rebin to a common set of bins
  RebinWorkspace(tmpW);

  std::set<int64_t> groupNumbers;
  for(std::multimap<int64_t,int64_t>::const_iterator d = detectorGroups.begin();d!=detectorGroups.end();d++)
  {
    if (groupNumbers.find(d->first) == groupNumbers.end())
    {
      groupNumbers.insert(d->first);
    }
  }

  int iprogress = 0;
  int iprogress_count = static_cast<int>(groupNumbers.size());
  int iprogress_step = iprogress_count / 100;
  if (iprogress_step == 0) iprogress_step = 1;
  std::vector<int64_t> resultIndeces;
  for(std::set<int64_t>::const_iterator g = groupNumbers.begin();g!=groupNumbers.end();g++)
  {
    if (iprogress++ % iprogress_step == 0)
    {
      progress(0.68 + double(iprogress)/iprogress_count/3);
    }
    std::multimap<int64_t,int64_t>::const_iterator from = detectorGroups.lower_bound(*g);
    std::multimap<int64_t,int64_t>::const_iterator to =   detectorGroups.upper_bound(*g);
    std::vector<detid_t> detectorList;
    for(std::multimap<int64_t,int64_t>::const_iterator d = from;d!=to;d++)
      detectorList.push_back(static_cast<detid_t>(d->second));
    // Want version 1 of GroupDetectors here
    API::IAlgorithm_sptr childAlg = createSubAlgorithm("GroupDetectors",-1.0,-1.0,true,1);
    childAlg->setProperty("Workspace", tmpW);
    childAlg->setProperty< std::vector<detid_t> >("DetectorList",detectorList);
    childAlg->executeAsSubAlg();
    try
    {
      // get the index of the combined spectrum
      int ri = childAlg->getProperty("ResultIndex");
      if (ri >= 0)
      {
        resultIndeces.push_back(ri);
      }
    }
    catch(...)
    {
      throw std::runtime_error("Unable to get Properties from GroupDetectors sub-algorithm");
    }
  }

  // Discard left-over spectra, but print warning message giving number discarded
  int discarded = 0;
  const int64_t oldHistNumber = tmpW->getNumberHistograms();
  API::Axis *spectraAxis = tmpW->getAxis(1);
  for(int64_t i=0; i < oldHistNumber; i++)
    if ( spectraAxis->spectraNo(i) >= 0 && find(resultIndeces.begin(),resultIndeces.end(),i) == resultIndeces.end())
    {
      ++discarded;
    }
  g_log.warning() << "Discarded " << discarded << " spectra that were not assigned to any group" << std::endl;

  // Running GroupDetectors leads to a load of redundant spectra
  // Create a new workspace that's the right size for the meaningful spectra and copy them in
  int64_t newSize = tmpW->blocksize();
  API::MatrixWorkspace_sptr outputW = API::WorkspaceFactory::Instance().create(tmpW,resultIndeces.size(),newSize+1,newSize);
  // Copy units
  outputW->getAxis(0)->unit() = tmpW->getAxis(0)->unit();
  outputW->getAxis(1)->unit() = tmpW->getAxis(1)->unit();

  API::Axis *spectraAxisNew = outputW->getAxis(1);

  for(int64_t hist=0; hist < static_cast<int64_t>(resultIndeces.size()); hist++)
  {
    int64_t i = resultIndeces[hist];
    double spNo = static_cast<double>(spectraAxis->spectraNo(i));
    MantidVec &tmpE = tmpW->dataE(i);
    MantidVec &outE = outputW->dataE(hist);
    MantidVec &tmpY = tmpW->dataY(i);
    MantidVec &outY = outputW->dataY(hist);
    MantidVec &tmpX = tmpW->dataX(i);
    MantidVec &outX = outputW->dataX(hist);
    outE.assign(tmpE.begin(),tmpE.end());
    outY.assign(tmpY.begin(),tmpY.end());
    outX.assign(tmpX.begin(),tmpX.end());
    spectraAxisNew->setValue(hist,spNo);
    spectraAxis->setValue(i,-1);
  }

  progress(1.);

  outputW->isDistribution(dist);

  // Assign it to the output workspace property
  setProperty("OutputWorkspace",outputW);

  return;
}
  /** Select background automatically
   */
  DataObjects::Workspace2D_sptr ProcessBackground::autoBackgroundSelection(Workspace2D_sptr bkgdWS)
  {
    // Get background type and create bakground function
    BackgroundFunction_sptr bkgdfunction = createBackgroundFunction(m_bkgdType);

    int bkgdorder = getProperty("BackgroundOrder");
    bkgdfunction->setAttributeValue("n", bkgdorder);

    g_log.debug() << "DBx622 Background Workspace has " << bkgdWS->readX(0).size()
                  << " data points." << std::endl;

    // Fit input (a few) background pionts to get initial guess
    API::IAlgorithm_sptr fit;
    try
    {
      fit = this->createChildAlgorithm("Fit", 0.0, 0.2, true);
    }
    catch (Exception::NotFoundError &)
    {
      g_log.error() << "Requires CurveFitting library." << std::endl;
      throw;
    }

    double startx = m_lowerBound;
    double endx = m_upperBound;
    fit->setProperty("Function", boost::dynamic_pointer_cast<API::IFunction>(bkgdfunction));
    fit->setProperty("InputWorkspace", bkgdWS);
    fit->setProperty("WorkspaceIndex", 0);
    fit->setProperty("MaxIterations", 500);
    fit->setProperty("StartX", startx);
    fit->setProperty("EndX", endx);
    fit->setProperty("Minimizer", "Levenberg-Marquardt");
    fit->setProperty("CostFunction", "Least squares");

    fit->executeAsChildAlg();

    // Get fit result
    // a) Status
    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");
    }

    // b) check that chi2 got better
    const double chi2 = fit->getProperty("OutputChi2overDoF");
    g_log.information() << "Fit background: Fit Status = " << fitStatus << ", chi2 = "
                        << chi2 << "\n";

    // c) get out the parameter names
    API::IFunction_sptr func = fit->getProperty("Function");
    /* Comment out as not being used
    std::vector<std::string> parnames = func->getParameterNames();
    std::map<std::string, double> parvalues;
    for (size_t iname = 0; iname < parnames.size(); ++iname)
    {
      double value = func->getParameter(parnames[iname]);
      parvalues.insert(std::make_pair(parnames[iname], value));
    }
    DataObject::Workspace2D_const_sptr theorybackground = AnalysisDataService::Instance().retrieve(wsname);
    */

    // Filter and construct for the output workspace
    Workspace2D_sptr outws = filterForBackground(bkgdfunction);

    return outws;
  } // END OF FUNCTION