void FindUBUsingIndexedPeaks::logLattice(OrientedLattice &o_lattice,
                                         int &ModDim) {
  // Show the modified lattice parameters
  g_log.notice() << o_lattice << "\n";
  g_log.notice() << "Modulation Dimension is: " << ModDim << "\n";
  for (int i = 0; i < ModDim; i++) {
    g_log.notice() << "Modulation Vector " << i + 1 << ": "
                   << o_lattice.getModVec(i) << "\n";
    g_log.notice() << "Modulation Vector " << i + 1
                   << " error: " << o_lattice.getVecErr(i) << "\n";
  }
}
/**
  @param  inname       Name of workspace containing peaks
  @param  params       optimized cell parameters
  @param  out          residuals from optimization
*/
void OptimizeLatticeForCellType::optLattice(std::string inname,
                                            std::vector<double> &params,
                                            double *out) {
  PeaksWorkspace_sptr ws = boost::dynamic_pointer_cast<PeaksWorkspace>(
      AnalysisDataService::Instance().retrieve(inname));
  const std::vector<Peak> &peaks = ws->getPeaks();
  size_t n_peaks = ws->getNumberPeaks();
  std::vector<V3D> q_vector;
  std::vector<V3D> hkl_vector;

  for (size_t i = 0; i < params.size(); i++)
    params[i] = std::abs(params[i]);
  for (size_t i = 0; i < n_peaks; i++) {
    q_vector.push_back(peaks[i].getQSampleFrame());
    hkl_vector.push_back(peaks[i].getHKL());
  }

  Mantid::API::IAlgorithm_sptr alg = createChildAlgorithm("CalculateUMatrix");
  alg->setPropertyValue("PeaksWorkspace", inname);
  alg->setProperty("a", params[0]);
  alg->setProperty("b", params[1]);
  alg->setProperty("c", params[2]);
  alg->setProperty("alpha", params[3]);
  alg->setProperty("beta", params[4]);
  alg->setProperty("gamma", params[5]);
  alg->executeAsChildAlg();

  ws = alg->getProperty("PeaksWorkspace");
  OrientedLattice latt = ws->mutableSample().getOrientedLattice();
  DblMatrix UB = latt.getUB();
  DblMatrix A = aMatrix(params);
  DblMatrix Bc = A;
  Bc.Invert();
  DblMatrix U1_B1 = UB * A;
  OrientedLattice o_lattice;
  o_lattice.setUB(U1_B1);
  DblMatrix U1 = o_lattice.getU();
  DblMatrix U1_Bc = U1 * Bc;

  for (size_t i = 0; i < hkl_vector.size(); i++) {
    V3D error = U1_Bc * hkl_vector[i] - q_vector[i] / (2.0 * M_PI);
    out[i] = error.norm2();
  }

  return;
}
Exemplo n.º 3
0
void LoadIsawUB::readModulatedUB(std::ifstream &in, DblMatrix &ub) {
  int ModDim = 0;
  Kernel::DblMatrix modub(3, 3);
  Kernel::DblMatrix ModVecErr(3, 3);
  int maxorder = 0;
  bool crossterm = false;
  std::string s;
  double val;
  s = getWord(in, true);
  if (!convert(s, val)) {
    readToEndOfLine(in, true);
    for (size_t row = 0; row < 3; row++) {
      for (size_t col = 0; col < 3; col++) {
        s = getWord(in, true);
        if (!convert(s, val))
          throw std::runtime_error(
              "The string '" + s +
              "' in the file was not understood as a number.");
        modub[row][col] = val;
      }
      readToEndOfLine(in, true);
      if (modub[row][0] != 0.0 || modub[row][1] != 0.0 || modub[row][2] != 0.0)
        ModDim++;
    }
  }

  readToEndOfLine(in, true);

  double latVals[6];
  for (double &latVal : latVals) {
    s = getWord(in, true);
    if (!convert(s, val))
      throw std::runtime_error("The string '" + s +
                               "' in the file was not understood as a number.");
    latVal = val;
  }

  if (ModDim > 0) {
    readToEndOfLine(in, true);
    readToEndOfLine(in, true);
    for (int i = 0; i < ModDim; i++) {
      readToEndOfLine(in, true);
      for (int j = 0; j < 4; j++)
        s = getWord(in, true);
      for (int j = 0; j < 3; j++) {
        s = getWord(in, true);
        if (!convert(s, val))
          throw std::runtime_error(
              "The string '" + s +
              "' in the file was not understood as a number.");
        ModVecErr[i][j] = val;
      }
      readToEndOfLine(in, true);
    }

    readToEndOfLine(in, true);
    for (int j = 0; j < 3; j++)
      s = getWord(in, true);
    if (!convert(s, val))
      throw std::runtime_error("The string '" + s +
                               "' in the file was not understood as a number.");
    maxorder = static_cast<int>(val);
    readToEndOfLine(in, true);
    for (int j = 0; j < 3; j++)
      s = getWord(in, true);
    bool valBool;
    if (!convert(s, valBool))
      throw std::runtime_error("The string '" + s +
                               "' in the file was not understood as a number.");
    crossterm = valBool;
  }
  // Adjust the UB by transposing
  ub = ub.Transpose();
  modub = modub.Transpose();

  /* The method in OrientedLattice gets both the lattice parameters and the U
   * matrix from the UB matrix.
   * This is compatible (same results) with the ISAW lattice parameters */
  OrientedLattice *latt = new OrientedLattice();
  latt->setUB(ub);
  latt->setError(latVals[0], latVals[1], latVals[2], latVals[3], latVals[4],
                 latVals[5]);
  latt->setModUB(modub);

  for (int i = 0; i < ModDim; i++)
    latt->setModerr(i, ModVecErr[i][0], ModVecErr[i][1], ModVecErr[i][2]);

  latt->setMaxOrder(maxorder);
  latt->setCrossTerm(crossterm);

  DblMatrix U = latt->getU();

  // Swap rows around to accound for IPNS convention
  DblMatrix U2 = U;
  // Swap rows around
  for (size_t r = 0; r < 3; r++) {
    U2[2][r] = U[0][r];
    U2[1][r] = U[2][r];
    U2[0][r] = U[1][r];
  }
  U = U2;
  const bool checkU = getProperty("CheckUMatrix");
  latt->setU(U, !checkU);

  // In and Out workspace.
  Workspace_sptr ws1 = getProperty("InputWorkspace");

  ExperimentInfo_sptr ws;
  MultipleExperimentInfos_sptr MDWS =
      boost::dynamic_pointer_cast<MultipleExperimentInfos>(ws1);
  if (MDWS != nullptr) {
    ws = MDWS->getExperimentInfo(0);
  } else {
    ws = boost::dynamic_pointer_cast<ExperimentInfo>(ws1);
  }
  if (!ws)
    throw std::invalid_argument("Must specify either a MatrixWorkspace or a "
                                "PeaksWorkspace or a MDWorkspace.");

  // Save it into the workspace
  ws->mutableSample().setOrientedLattice(latt);

  // Save it to every experiment info in MD workspaces
  if ((MDWS != nullptr) && (MDWS->getNumExperimentInfo() > 1)) {
    for (uint16_t i = 1; i < MDWS->getNumExperimentInfo(); i++) {
      ws = MDWS->getExperimentInfo(i);
      ws->mutableSample().setOrientedLattice(latt);
    }
  }

  delete latt;
  this->setProperty("InputWorkspace", ws1);
}
Exemplo n.º 4
0
  /** Execute the algorithm.
   */
  void SaveIsawUB::exec()
  {
   try
      {
        Workspace_sptr ws1 = getProperty("InputWorkspace");
        ExperimentInfo_sptr ws;
        IMDEventWorkspace_sptr MDWS=boost::dynamic_pointer_cast<IMDEventWorkspace>(ws1);
        if (MDWS != NULL)
        {
            ws = MDWS->getExperimentInfo(0);
        }
        else
        {
            ws = boost::dynamic_pointer_cast<ExperimentInfo>(ws1);
        }

        if (!ws)
          throw std::invalid_argument(
              "Must specify either a MatrixWorkspace or a PeaksWorkspace or a MDEventWorkspace.");

        if (!ws->sample().hasOrientedLattice()) throw
          std::invalid_argument("Workspace must have an oriented lattice to save");

        std::string Filename = getProperty("Filename");

        ofstream out;
        out.open(Filename.c_str());

        OrientedLattice lattice = ws->sample().getOrientedLattice();
        Kernel::DblMatrix ub = lattice.getUB();

        // Write the ISAW UB matrix
        const int beam = 2;
        const int up = 1;
        const int back = 0;
        out << fixed;

        for (size_t basis = 0; basis < 3; basis++)
        {
          out << setw(11) << setprecision(8) << ub[beam][basis] << setw(12) << setprecision(8)
              << ub[back][basis] << setw(12) << setprecision(8) << ub[up][basis] << " " << endl;

        }

        out << setw(11) << setprecision(4) << lattice.a() << setw(12) << setprecision(4) << lattice.b()
            << setw(12) << setprecision(4) << lattice.c() << setw(12) << setprecision(4)
            << lattice.alpha() << setw(12) << setprecision(4) << lattice.beta() << setw(12)
            << setprecision(4) << lattice.gamma() << setw(12) << setprecision(4) << lattice.volume()
            << " " << endl;
        double ErrorVolume =getErrorVolume(lattice);
        out << setw(11) << setprecision(4) << lattice.errora() << setw(12) << setprecision(4) << lattice.errorb()
                   << setw(12) << setprecision(4) << lattice.errorc() << setw(12) << setprecision(4)
                   << lattice.erroralpha() << setw(12) << setprecision(4) << lattice.errorbeta() << setw(12)
                   << setprecision(4) << lattice.errorgamma() << setw(12) << setprecision(4) << ErrorVolume
                   << " " << endl;

        out << endl << endl;

        out << "The above matrix is the Transpose of the UB Matrix. ";
        out << "The UB matrix maps the column" << endl;
        out << "vector (h,k,l ) to the column vector ";
        out << "(q'x,q'y,q'z)." << endl;
        out << "|Q'|=1/dspacing and its coordinates are a ";
        out << "right-hand coordinate system where" << endl;
        out << " x is the beam direction and z is vertically ";
        out << "upward.(IPNS convention)" << endl;

        out.close();

      } catch (exception &s)
      {
        throw std::invalid_argument(s.what());
      }

    }
Exemplo n.º 5
0
/** Execute the algorithm.
 */
void SaveIsawUB::exec() {
  try {
    Workspace_sptr ws1 = getProperty("InputWorkspace");
    ExperimentInfo_sptr ws;
    MultipleExperimentInfos_sptr MDWS =
        boost::dynamic_pointer_cast<MultipleExperimentInfos>(ws1);
    if (MDWS != nullptr) {
      ws = MDWS->getExperimentInfo(0);
    } else {
      ws = boost::dynamic_pointer_cast<ExperimentInfo>(ws1);
    }

    if (!ws)
      throw std::invalid_argument("Must specify either a MatrixWorkspace or a "
                                  "PeaksWorkspace or a MDWorkspace.");

    if (!ws->sample().hasOrientedLattice())
      throw std::invalid_argument(
          "Workspace must have an oriented lattice to save");

    std::string Filename = getProperty("Filename");

    ofstream out;
    out.open(Filename.c_str());

    OrientedLattice lattice = ws->sample().getOrientedLattice();
    Kernel::DblMatrix ub = lattice.getUB();
    Kernel::DblMatrix modub = lattice.getModUB();

    // Write the ISAW UB matrix
    const int beam = 2;
    const int up = 1;
    const int back = 0;
    out << fixed;

    for (size_t basis = 0; basis < 3; basis++) {
      out << setw(11) << setprecision(8) << ub[beam][basis] << setw(12)
          << setprecision(8) << ub[back][basis] << setw(12) << setprecision(8)
          << ub[up][basis] << " \n";
    }

    int ModDim = 0;
    for (int i = 0; i < 3; i++) {
      if (lattice.getModVec(i) == V3D(0, 0, 0))
        continue;
      else
        ModDim++;
    }

    if (ModDim > 0) {
      out << "ModUB: \n";
      for (size_t basis = 0; basis < 3; basis++) {
        out << setw(11) << setprecision(8) << modub[beam][basis] << setw(12)
            << setprecision(8) << modub[back][basis] << setw(12)
            << setprecision(8) << modub[up][basis] << " \n";
      }
    }

    //                out << "Lattice Parameters: \n";
    out << setw(11) << setprecision(4) << lattice.a() << setw(12)
        << setprecision(4) << lattice.b() << setw(12) << setprecision(4)
        << lattice.c() << setw(12) << setprecision(4) << lattice.alpha()
        << setw(12) << setprecision(4) << lattice.beta() << setw(12)
        << setprecision(4) << lattice.gamma() << setw(12) << setprecision(4)
        << lattice.volume() << " \n";
    double ErrorVolume = getErrorVolume(lattice);
    out << setw(11) << setprecision(4) << lattice.errora() << setw(12)
        << setprecision(4) << lattice.errorb() << setw(12) << setprecision(4)
        << lattice.errorc() << setw(12) << setprecision(4)
        << lattice.erroralpha() << setw(12) << setprecision(4)
        << lattice.errorbeta() << setw(12) << setprecision(4)
        << lattice.errorgamma() << setw(12) << setprecision(4) << ErrorVolume
        << " \n";

    out << "\n";
    if (ModDim >= 1) {
      out << "Modulation Vector 1:   " << setw(12) << setprecision(4)
          << lattice.getdh(0) << setw(12) << setprecision(4) << lattice.getdk(0)
          << setw(12) << setprecision(4) << lattice.getdl(0) << " \n";

      out << "Modulation Vector 1 error:   " << setw(6) << setprecision(4)
          << lattice.getdherr(0) << setw(12) << setprecision(4)
          << lattice.getdkerr(0) << setw(12) << setprecision(4)
          << lattice.getdlerr(0) << " \n\n";
    }
    if (ModDim >= 2) {
      out << "Modulation Vector 2:   " << setw(12) << setprecision(4)
          << lattice.getdh(1) << setw(12) << setprecision(4) << lattice.getdk(1)
          << setw(12) << setprecision(4) << lattice.getdl(1) << " \n";

      out << "Modulation Vector 2 error:   " << setw(6) << setprecision(4)
          << lattice.getdherr(1) << setw(12) << setprecision(4)
          << lattice.getdkerr(1) << setw(12) << setprecision(4)
          << lattice.getdlerr(1) << " \n\n";
    }
    if (ModDim == 3) {
      out << "Modulation Vector 3:   " << setw(12) << setprecision(4)
          << lattice.getdh(2) << setw(12) << setprecision(4) << lattice.getdk(2)
          << setw(12) << setprecision(4) << lattice.getdl(2) << " \n";

      out << "Modulation Vector 3 error:   " << setw(6) << setprecision(4)
          << lattice.getdherr(2) << setw(12) << setprecision(4)
          << lattice.getdkerr(2) << setw(12) << setprecision(4)
          << lattice.getdlerr(2) << " \n\n";
    }
    if (ModDim >= 1) {
      out << "Max Order:        " << lattice.getMaxOrder() << " \n";
      out << "Cross Terms:      " << lattice.getCrossTerm() << " \n";
    }

    out << "\n";

    if (ModDim == 0) {
      out << "The above matrix is the Transpose of the UB Matrix. ";
      out << "The UB matrix maps the column\n";
      out << "vector (h,k,l ) to the column vector ";
      out << "(q'x,q'y,q'z).\n";
      out << "|Q'|=1/dspacing and its coordinates are a ";
      out << "right-hand coordinate system where\n";
      out << " x is the beam direction and z is vertically ";
      out << "upward.(IPNS convention)\n";
    } else {
      out << "The above matrix is the Transpose of the UB Matrix and the "
             "Transpose of ModUB. ";
      out << "The UB matrix together with ModUB maps the column vector "
             "(h,k,l,m,n,p) \n";
      out << "to the column vector (q'x,q'y,q'z).\n";
      out << "The columns of ModUB are the coordinates of modulation vectors "
             "in Qlab. \n";
      out << "|Q'|=1/dspacing and its coordinates are a ";
      out << "right-hand coordinate system where";
      out << " x is the beam direction and z is vertically ";
      out << "upward.(IPNS convention)\n";
    }

    out.close();

  } catch (exception &s) {
    throw std::invalid_argument(s.what());
  }
}
Exemplo n.º 6
0
/** Execute the algorithm.
 */
void IntegrateEllipsoids::exec() {
  // get the input workspace
  MatrixWorkspace_sptr wksp = getProperty("InputWorkspace");

  EventWorkspace_sptr eventWS =
      boost::dynamic_pointer_cast<EventWorkspace>(wksp);
  Workspace2D_sptr histoWS = boost::dynamic_pointer_cast<Workspace2D>(wksp);
  if (!eventWS && !histoWS) {
    throw std::runtime_error("IntegrateEllipsoids needs either a "
                             "EventWorkspace or Workspace2D as input.");
  }

  // error out if there are not events
  if (eventWS && eventWS->getNumberEvents() <= 0) {
    throw std::runtime_error(
        "IntegrateEllipsoids does not work for empty event lists");
  }

  PeaksWorkspace_sptr in_peak_ws = getProperty("PeaksWorkspace");
  if (!in_peak_ws) {
    throw std::runtime_error("Could not read the peaks workspace");
  }

  double radius_m = getProperty("RegionRadius");
  double radius_s = getProperty("SatelliteRegionRadius");
  int numSigmas = getProperty("NumSigmas");
  double cutoffIsigI = getProperty("CutoffIsigI");
  bool specify_size = getProperty("SpecifySize");
  double peak_radius = getProperty("PeakSize");
  double sate_peak_radius = getProperty("SatellitePeakSize");
  double back_inner_radius = getProperty("BackgroundInnerSize");
  double sate_back_inner_radius = getProperty("SatelliteBackgroundInnerSize");
  double back_outer_radius = getProperty("BackgroundOuterSize");
  double sate_back_outer_radius = getProperty("SatelliteBackgroundOuterSize");
  bool hkl_integ = getProperty("IntegrateInHKL");
  bool integrateEdge = getProperty("IntegrateIfOnEdge");
  bool adaptiveQBackground = getProperty("AdaptiveQBackground");
  double adaptiveQMultiplier = getProperty("AdaptiveQMultiplier");
  double adaptiveQBackgroundMultiplier = 0.0;
  bool useOnePercentBackgroundCorrection =
      getProperty("UseOnePercentBackgroundCorrection");
  if (adaptiveQBackground)
    adaptiveQBackgroundMultiplier = adaptiveQMultiplier;
  if (!integrateEdge) {
    // This only fails in the unit tests which say that MaskBTP is not
    // registered
    try {
      runMaskDetectors(in_peak_ws, "Tube", "edges");
      runMaskDetectors(in_peak_ws, "Pixel", "edges");
    } catch (...) {
      g_log.error("Can't execute MaskBTP algorithm for this instrument to set "
                  "edge for IntegrateIfOnEdge option");
    }
    calculateE1(in_peak_ws->detectorInfo()); // fill E1Vec for use in detectorQ
  }

  Mantid::DataObjects::PeaksWorkspace_sptr peak_ws =
      getProperty("OutputWorkspace");
  if (peak_ws != in_peak_ws)
    peak_ws = in_peak_ws->clone();

  // get UBinv and the list of
  // peak Q's for the integrator
  std::vector<Peak> &peaks = peak_ws->getPeaks();
  size_t n_peaks = peak_ws->getNumberPeaks();
  size_t indexed_count = 0;
  std::vector<V3D> peak_q_list;
  std::vector<std::pair<double, V3D>> qList;
  std::vector<V3D> hkl_vectors;
  std::vector<V3D> mnp_vectors;
  int ModDim = 0;
  for (size_t i = 0; i < n_peaks; i++) // Note: we skip un-indexed peaks
  {
    V3D hkl(peaks[i].getIntHKL());
    V3D mnp(peaks[i].getIntMNP());

    if (mnp[0] != 0 && ModDim == 0)
      ModDim = 1;
    if (mnp[1] != 0 && ModDim == 1)
      ModDim = 2;
    if (mnp[2] != 0 && ModDim == 2)
      ModDim = 3;

    // use tolerance == 1 to just check for (0,0,0,0,0,0)
    if (Geometry::IndexingUtils::ValidIndex(hkl, 1.0)) {
      peak_q_list.emplace_back(peaks[i].getQLabFrame());
      qList.emplace_back(1., V3D(peaks[i].getQLabFrame()));
      hkl_vectors.push_back(hkl);
      mnp_vectors.push_back(mnp);
      indexed_count++;
    }
  }

  if (indexed_count < 3)
    throw std::runtime_error(
        "At least three linearly independent indexed peaks are needed.");

  // Get UB using indexed peaks and
  // lab-Q vectors
  Matrix<double> UB(3, 3, false);
  Matrix<double> modUB(3, 3, false);
  Matrix<double> modHKL(3, 3, false);
  Geometry::IndexingUtils::Optimize_6dUB(UB, modUB, hkl_vectors, mnp_vectors,
                                         ModDim, peak_q_list);

  int maxOrder = 0;
  bool CT = false;
  if (peak_ws->sample().hasOrientedLattice()) {
    OrientedLattice lattice = peak_ws->mutableSample().getOrientedLattice();
    lattice.setUB(UB);
    lattice.setModUB(modUB);
    modHKL = lattice.getModHKL();
    maxOrder = lattice.getMaxOrder();
    CT = lattice.getCrossTerm();
  }

  Matrix<double> UBinv(UB);
  UBinv.Invert();
  UBinv *= (1.0 / (2.0 * M_PI));

  std::vector<double> PeakRadiusVector(n_peaks, peak_radius);
  std::vector<double> BackgroundInnerRadiusVector(n_peaks, back_inner_radius);
  std::vector<double> BackgroundOuterRadiusVector(n_peaks, back_outer_radius);
  if (specify_size) {
    if (back_outer_radius > radius_m)
      throw std::runtime_error(
          "BackgroundOuterSize must be less than or equal to the RegionRadius");

    if (back_inner_radius >= back_outer_radius)
      throw std::runtime_error(
          "BackgroundInnerSize must be less BackgroundOuterSize");

    if (peak_radius > back_inner_radius)
      throw std::runtime_error(
          "PeakSize must be less than or equal to the BackgroundInnerSize");
  }

  // make the integrator
  Integrate3DEvents integrator(qList, hkl_vectors, mnp_vectors, UBinv, modHKL,
                               radius_m, radius_s, maxOrder, CT,
                               useOnePercentBackgroundCorrection);

  // get the events and add
  // them to the inegrator
  // set up a descripter of where we are going
  this->initTargetWSDescr(wksp);

  // set up the progress bar
  const size_t numSpectra = wksp->getNumberHistograms();
  Progress prog(this, 0.5, 1.0, numSpectra);

  if (eventWS) {
    // process as EventWorkspace
    qListFromEventWS(integrator, prog, eventWS, UBinv, hkl_integ);
  } else {
    // process as Workspace2D
    qListFromHistoWS(integrator, prog, histoWS, UBinv, hkl_integ);
  }

  double inti;
  double sigi;
  std::vector<double> principalaxis1, principalaxis2, principalaxis3;
  std::vector<double> sateprincipalaxis1, sateprincipalaxis2,
      sateprincipalaxis3;
  for (size_t i = 0; i < n_peaks; i++) {
    const V3D hkl(peaks[i].getIntHKL());
    const V3D mnp(peaks[i].getIntMNP());

    if (Geometry::IndexingUtils::ValidIndex(hkl, 1.0) ||
        Geometry::IndexingUtils::ValidIndex(mnp, 1.0)) {
      const V3D peak_q = peaks[i].getQLabFrame();
      // modulus of Q
      const double lenQpeak = adaptiveQMultiplier != 0.0 ? peak_q.norm() : 0.0;

      double adaptiveRadius = adaptiveQMultiplier * lenQpeak + peak_radius;
      if (mnp != V3D(0, 0, 0))
        adaptiveRadius = adaptiveQMultiplier * lenQpeak + sate_peak_radius;

      if (adaptiveRadius <= 0.0) {
        g_log.error() << "Error: Radius for integration sphere of peak " << i
                      << " is negative =  " << adaptiveRadius << '\n';
        peaks[i].setIntensity(0.0);
        peaks[i].setSigmaIntensity(0.0);
        PeakRadiusVector[i] = 0.0;
        BackgroundInnerRadiusVector[i] = 0.0;
        BackgroundOuterRadiusVector[i] = 0.0;
        continue;
      }

      double adaptiveBack_inner_radius;
      double adaptiveBack_outer_radius;
      if (mnp == V3D(0, 0, 0)) {
        adaptiveBack_inner_radius =
            adaptiveQBackgroundMultiplier * lenQpeak + back_inner_radius;
        adaptiveBack_outer_radius =
            adaptiveQBackgroundMultiplier * lenQpeak + back_outer_radius;
      } else {
        adaptiveBack_inner_radius =
            adaptiveQBackgroundMultiplier * lenQpeak + sate_back_inner_radius;
        adaptiveBack_outer_radius =
            adaptiveQBackgroundMultiplier * lenQpeak + sate_back_outer_radius;
      }
      PeakRadiusVector[i] = adaptiveRadius;
      BackgroundInnerRadiusVector[i] = adaptiveBack_inner_radius;
      BackgroundOuterRadiusVector[i] = adaptiveBack_outer_radius;

      std::vector<double> axes_radii;
      Mantid::Geometry::PeakShape_const_sptr shape =
          integrator.ellipseIntegrateModEvents(
              E1Vec, peak_q, hkl, mnp, specify_size, adaptiveRadius,
              adaptiveBack_inner_radius, adaptiveBack_outer_radius, axes_radii,
              inti, sigi);
      peaks[i].setIntensity(inti);
      peaks[i].setSigmaIntensity(sigi);
      peaks[i].setPeakShape(shape);
      if (axes_radii.size() == 3) {
        if (inti / sigi > cutoffIsigI || cutoffIsigI == EMPTY_DBL()) {
          if (mnp == V3D(0, 0, 0)) {
            principalaxis1.push_back(axes_radii[0]);
            principalaxis2.push_back(axes_radii[1]);
            principalaxis3.push_back(axes_radii[2]);
          } else {
            sateprincipalaxis1.push_back(axes_radii[0]);
            sateprincipalaxis2.push_back(axes_radii[1]);
            sateprincipalaxis3.push_back(axes_radii[2]);
          }
        }
      }
    } else {
      peaks[i].setIntensity(0.0);
      peaks[i].setSigmaIntensity(0.0);
    }
  }
  if (principalaxis1.size() > 1) {
    Statistics stats1 = getStatistics(principalaxis1);
    g_log.notice() << "principalaxis1: "
                   << " mean " << stats1.mean << " standard_deviation "
                   << stats1.standard_deviation << " minimum " << stats1.minimum
                   << " maximum " << stats1.maximum << " median "
                   << stats1.median << "\n";
    Statistics stats2 = getStatistics(principalaxis2);
    g_log.notice() << "principalaxis2: "
                   << " mean " << stats2.mean << " standard_deviation "
                   << stats2.standard_deviation << " minimum " << stats2.minimum
                   << " maximum " << stats2.maximum << " median "
                   << stats2.median << "\n";
    Statistics stats3 = getStatistics(principalaxis3);
    g_log.notice() << "principalaxis3: "
                   << " mean " << stats3.mean << " standard_deviation "
                   << stats3.standard_deviation << " minimum " << stats3.minimum
                   << " maximum " << stats3.maximum << " median "
                   << stats3.median << "\n";

    if (sateprincipalaxis1.size() > 1) {
      Statistics satestats1 = getStatistics(sateprincipalaxis1);
      g_log.notice() << "sateprincipalaxis1: "
                     << " mean " << satestats1.mean << " standard_deviation "
                     << satestats1.standard_deviation << " minimum "
                     << satestats1.minimum << " maximum " << satestats1.maximum
                     << " median " << satestats1.median << "\n";
      Statistics satestats2 = getStatistics(sateprincipalaxis2);
      g_log.notice() << "sateprincipalaxis2: "
                     << " mean " << satestats2.mean << " standard_deviation "
                     << satestats2.standard_deviation << " minimum "
                     << satestats2.minimum << " maximum " << satestats2.maximum
                     << " median " << satestats2.median << "\n";
      Statistics satestats3 = getStatistics(sateprincipalaxis3);
      g_log.notice() << "sateprincipalaxis3: "
                     << " mean " << satestats3.mean << " standard_deviation "
                     << satestats3.standard_deviation << " minimum "
                     << satestats3.minimum << " maximum " << satestats3.maximum
                     << " median " << satestats3.median << "\n";
    }

    constexpr size_t histogramNumber = 3;
    Workspace_sptr wsProfile = WorkspaceFactory::Instance().create(
        "Workspace2D", histogramNumber, principalaxis1.size(),
        principalaxis1.size());
    Workspace2D_sptr wsProfile2D =
        boost::dynamic_pointer_cast<Workspace2D>(wsProfile);
    AnalysisDataService::Instance().addOrReplace("EllipsoidAxes", wsProfile2D);

    // set output workspace
    Points points(principalaxis1.size(), LinearGenerator(0, 1));
    wsProfile2D->setHistogram(0, points, Counts(std::move(principalaxis1)));
    wsProfile2D->setHistogram(1, points, Counts(std::move(principalaxis2)));
    wsProfile2D->setHistogram(2, points, Counts(std::move(principalaxis3)));

    if (cutoffIsigI != EMPTY_DBL()) {
      principalaxis1.clear();
      principalaxis2.clear();
      principalaxis3.clear();
      sateprincipalaxis1.clear();
      sateprincipalaxis2.clear();
      sateprincipalaxis3.clear();
      specify_size = true;
      peak_radius = std::max(std::max(stats1.mean, stats2.mean), stats3.mean) +
                    numSigmas * std::max(std::max(stats1.standard_deviation,
                                                  stats2.standard_deviation),
                                         stats3.standard_deviation);
      back_inner_radius = peak_radius;
      back_outer_radius = peak_radius * 1.25992105; // A factor of 2 ^ (1/3)
      // will make the background
      // shell volume equal to the peak region volume.
      for (size_t i = 0; i < n_peaks; i++) {
        V3D hkl(peaks[i].getIntHKL());
        V3D mnp(peaks[i].getIntMNP());
        if (Geometry::IndexingUtils::ValidIndex(hkl, 1.0) ||
            Geometry::IndexingUtils::ValidIndex(mnp, 1.0)) {
          const V3D peak_q = peaks[i].getQLabFrame();
          std::vector<double> axes_radii;
          integrator.ellipseIntegrateModEvents(
              E1Vec, peak_q, hkl, mnp, specify_size, peak_radius,
              back_inner_radius, back_outer_radius, axes_radii, inti, sigi);
          peaks[i].setIntensity(inti);
          peaks[i].setSigmaIntensity(sigi);
          if (axes_radii.size() == 3) {
            if (mnp == V3D(0, 0, 0)) {
              principalaxis1.push_back(axes_radii[0]);
              principalaxis2.push_back(axes_radii[1]);
              principalaxis3.push_back(axes_radii[2]);
            } else {
              sateprincipalaxis1.push_back(axes_radii[0]);
              sateprincipalaxis2.push_back(axes_radii[1]);
              sateprincipalaxis3.push_back(axes_radii[2]);
            }
          }
        } else {
          peaks[i].setIntensity(0.0);
          peaks[i].setSigmaIntensity(0.0);
        }
      }
      if (principalaxis1.size() > 1) {
        Workspace_sptr wsProfile2 = WorkspaceFactory::Instance().create(
            "Workspace2D", histogramNumber, principalaxis1.size(),
            principalaxis1.size());
        Workspace2D_sptr wsProfile2D2 =
            boost::dynamic_pointer_cast<Workspace2D>(wsProfile2);
        AnalysisDataService::Instance().addOrReplace("EllipsoidAxes_2ndPass",
                                                     wsProfile2D2);

        Points profilePoints(principalaxis1.size(), LinearGenerator(0, 1));
        wsProfile2D->setHistogram(0, profilePoints,
                                  Counts(std::move(principalaxis1)));
        wsProfile2D->setHistogram(1, profilePoints,
                                  Counts(std::move(principalaxis2)));
        wsProfile2D->setHistogram(2, profilePoints,
                                  Counts(std::move(principalaxis3)));
      }
    }
  }

  // This flag is used by the PeaksWorkspace to evaluate whether it has been
  // integrated.
  peak_ws->mutableRun().addProperty("PeaksIntegrated", 1, true);
  // These flags are specific to the algorithm.
  peak_ws->mutableRun().addProperty("PeakRadius", PeakRadiusVector, true);
  peak_ws->mutableRun().addProperty("BackgroundInnerRadius",
                                    BackgroundInnerRadiusVector, true);
  peak_ws->mutableRun().addProperty("BackgroundOuterRadius",
                                    BackgroundOuterRadiusVector, true);

  setProperty("OutputWorkspace", peak_ws);
}