예제 #1
0
/** Build meaningful dimension names for different conversion modes
 * @param TargWSDescription the class-container to keep the dimension names and
 dimension unints
 * @param FrameID -- the ID describing the target transformation frame (lab,
 sample, hkl)
 * @param ScaleID -- the scale ID which define how the dimensions are scaled

*/
void MDWSTransform::setQ3DDimensionsNames(
    MDWSDescription &TargWSDescription, CnvrtToMD::TargetFrame FrameID,
    CnvrtToMD::CoordScaling ScaleID) const {

  std::vector<Kernel::V3D> dimDirections;
  // set default dimension names:
  std::vector<std::string> dimNames = TargWSDescription.getDimNames();

  // define B-matrix and Lattice parameters to one in case if no OrientedLattice
  // is there
  Kernel::DblMatrix Bm(3, 3, true);
  std::vector<double> LatPar(3, 1);
  if (TargWSDescription.hasLattice()) { // redefine B-matrix and Lattice
                                        // parameters from real oriented lattice
                                        // if there is one
    auto spLatt = TargWSDescription.getLattice();
    Bm = spLatt->getB();
    for (int i = 0; i < 3; i++)
      LatPar[i] = spLatt->a(i);
  }
  if (FrameID == CnvrtToMD::AutoSelect)
    FrameID = findTargetFrame(TargWSDescription);

  switch (FrameID) {
  case (CnvrtToMD::LabFrame): {
    dimNames[0] = "Q_lab_x";
    dimNames[1] = "Q_lab_y";
    dimNames[2] = "Q_lab_z";
    TargWSDescription.setCoordinateSystem(Mantid::Kernel::QLab);
    TargWSDescription.setFrame(Geometry::QLab::QLabName);
    break;
  }
  case (CnvrtToMD::SampleFrame): {
    dimNames[0] = "Q_sample_x";
    dimNames[1] = "Q_sample_y";
    dimNames[2] = "Q_sample_z";
    TargWSDescription.setCoordinateSystem(Mantid::Kernel::QSample);
    TargWSDescription.setFrame(Geometry::QSample::QSampleName);
    break;
  }
  case (CnvrtToMD::HKLFrame): {
    dimNames[0] = "H";
    dimNames[1] = "K";
    dimNames[2] = "L";

    Kernel::MDUnit_uptr mdUnit(new Kernel::InverseAngstromsUnit);
    TargWSDescription.setCoordinateSystem(Mantid::Kernel::HKL);
    TargWSDescription.setFrame(Geometry::HKL::HKLName);
    break;
  }
  default:
    throw(std::invalid_argument(" Unknown or undefined Target Frame ID"));
  }

  dimDirections.resize(3);
  dimDirections[0] = m_UProj;
  dimDirections[1] = m_VProj;
  dimDirections[2] = m_WProj;
  if (ScaleID == OrthogonalHKLScale) {
    std::vector<Kernel::V3D> uv(2);
    uv[0] = m_UProj;
    uv[1] = m_VProj;
    dimDirections = Kernel::V3D::makeVectorsOrthogonal(uv);
  }
  // axis names:
  if ((FrameID == CnvrtToMD::LabFrame) || (FrameID == CnvrtToMD::SampleFrame))
    for (int i = 0; i < 3; i++)
      TargWSDescription.setDimName(i, dimNames[i]);
  else
    for (int i = 0; i < 3; i++)
      TargWSDescription.setDimName(
          i, MDAlgorithms::makeAxisName(dimDirections[i], dimNames));

  if (ScaleID == NoScaling) {
    for (int i = 0; i < 3; i++)
      TargWSDescription.setDimUnit(i, "A^-1");
  }
  if (ScaleID == SingleScale) {
    double dMax(-1.e+32);
    for (int i = 0; i < 3; i++)
      dMax = (dMax > LatPar[i]) ? (dMax) : (LatPar[i]);
    for (int i = 0; i < 3; i++)
      TargWSDescription.setDimUnit(
          i, "in " + MDAlgorithms::sprintfd(2 * M_PI / dMax, 1.e-3) + " A^-1");
  }
  if ((ScaleID == OrthogonalHKLScale) || (ScaleID == HKLScale)) {
    // get the length along each of the axes
    std::vector<double> len;
    Kernel::V3D x;
    x = Bm * dimDirections[0];
    len.push_back(2 * M_PI * x.norm());
    x = Bm * dimDirections[1];
    len.push_back(2 * M_PI * x.norm());
    x = Bm * dimDirections[2];
    len.push_back(2 * M_PI * x.norm());
    for (int i = 0; i < 3; i++)
      TargWSDescription.setDimUnit(
          i, "in " + MDAlgorithms::sprintfd(len[i], 1.e-3) + " A^-1");
  }
}
예제 #2
0
/**
 Method builds transformation Q=R*U*B*W*h where W-transf is W or WB or
 W*Unit*Lattice_param depending on inputs
*/
Kernel::DblMatrix
MDWSTransform::buildQTrahsf(MDWSDescription &TargWSDescription,
                            CnvrtToMD::CoordScaling ScaleID,
                            bool UnitUB) const {
  // implements strategy
  if (!(TargWSDescription.hasLattice() || UnitUB)) {
    throw(std::invalid_argument("this function should be called only on "
                                "workspace with defined oriented lattice"));
  }

  // if u,v us default, Wmat is unit transformation
  Kernel::DblMatrix Wmat(3, 3, true);
  // derive rotation from u0,v0 u0||ki to u,v
  if (!m_isUVdefault) {
    Wmat[0][0] = m_UProj[0];
    Wmat[1][0] = m_UProj[1];
    Wmat[2][0] = m_UProj[2];
    Wmat[0][1] = m_VProj[0];
    Wmat[1][1] = m_VProj[1];
    Wmat[2][1] = m_VProj[2];
    Wmat[0][2] = m_WProj[0];
    Wmat[1][2] = m_WProj[1];
    Wmat[2][2] = m_WProj[2];
  }
  if (ScaleID == OrthogonalHKLScale) {
    std::vector<Kernel::V3D> dim_directions;
    std::vector<Kernel::V3D> uv(2);
    uv[0] = m_UProj;
    uv[1] = m_VProj;
    dim_directions = Kernel::V3D::makeVectorsOrthogonal(uv);
    for (size_t i = 0; i < 3; ++i)
      for (size_t j = 0; j < 3; ++j)
        Wmat[i][j] = dim_directions[j][i];
  }
  // Now define lab frame to target frame transformation
  Kernel::DblMatrix Scale(3, 3, true);
  Kernel::DblMatrix Transf(3, 3, true);
  boost::shared_ptr<Geometry::OrientedLattice> spLatt;
  if (UnitUB)
    spLatt = boost::shared_ptr<Geometry::OrientedLattice>(
        new Geometry::OrientedLattice(1, 1, 1));
  else
    spLatt = TargWSDescription.getLattice();

  switch (ScaleID) {
  case NoScaling: //< momentums in A^-1
  {
    Transf = spLatt->getU();
    break;
  }
  case SingleScale: //< momentums divided by  2*Pi/Lattice -- equivalent to
    // d-spacing in some sense
    {
      double dMax(-1.e+32);
      for (int i = 0; i < 3; i++)
        dMax = (dMax > spLatt->a(i)) ? (dMax) : (spLatt->a(i));
      for (int i = 0; i < 3; i++)
        Scale[i][i] = (2 * M_PI) / dMax;
      Transf = spLatt->getU();
      break;
    }
  case OrthogonalHKLScale: //< each momentum component divided by appropriate
    // lattice parameter; equivalent to hkl for orthogonal
    // axis
    {
      if (spLatt) {
        for (int i = 0; i < 3; i++) {
          Scale[i][i] = (2 * M_PI) / spLatt->a(i);
        }
        Transf = spLatt->getU();
      }
      break;
    }
  case HKLScale: //< non-orthogonal system for non-orthogonal lattice
  {
    if (spLatt)
      Scale = spLatt->getUB() * (2 * M_PI);
    break;
  }

  default:
    throw(std::invalid_argument("unrecognized conversion mode"));
  }
  TargWSDescription.addProperty("W_MATRIX", Wmat.getVector(), true);
  return Transf * Scale * Wmat;
}