Example #1
0
std::string makeAxisName(const Kernel::V3D &Dir,
                         const std::vector<std::string> &QNames) {
  double eps(1.e-3);
  Kernel::V3D absDir(fabs(Dir.X()), fabs(Dir.Y()), fabs(Dir.Z()));
  std::string mainName;

  if ((absDir[0] >= absDir[1]) && (absDir[0] >= absDir[2])) {
    mainName = QNames[0];
  } else if (absDir[1] >= absDir[2]) {
    mainName = QNames[1];
  } else {
    mainName = QNames[2];
  }

  std::string name("["), separator = ",";
  for (size_t i = 0; i < 3; i++) {

    if (i == 2)
      separator = "]";
    if (absDir[i] < eps) {
      name += "0" + separator;
      continue;
    }
    if (Dir[i] < 0) {
      name += "-";
    }
    if (std::fabs(absDir[i] - 1) < eps) {
      name.append(mainName).append(separator);
      continue;
    }
    name.append(sprintfd(absDir[i], eps)).append(mainName).append(separator);
  }

  return name;
}
Example #2
0
/**
 * Return the XML for a sphere.
 */
std::string sphereXML(double radius, const Kernel::V3D &centre, const std::string &id) {
    std::ostringstream xml;
    xml << "<sphere id=\"" << id << "\">"
        << "<centre x=\"" << centre.X() << "\"  y=\"" << centre.Y() << "\" z=\""
        << centre.Z() << "\" />"
        << "<radius val=\"" << radius << "\" />"
        << "</sphere>";
    return xml.str();
}
Example #3
0
/**
 * Return a local point in a cylinder shape
 *
 * @param basis a basis vector
 * @param alongAxis symmetry axis vector of a cylinder
 * @param polarAngle a polar angle (in radians) of a point in a cylinder
 * @param radialLength radial position of point in a cylinder
 * @return a local point inside the cylinder
 */
Kernel::V3D localPointInCylinder(const Kernel::V3D &basis,
                                 const Kernel::V3D &alongAxis,
                                 double polarAngle, double radialLength) {
  // Use basis to get a second perpendicular vector to define basis2
  Kernel::V3D basis2;
  if (basis.X() == 0) {
    basis2.setX(1.);
  } else if (basis.Y() == 0) {
    basis2.setY(1.);
  } else if (basis.Z() == 0) {
    basis2.setZ(1.);
  } else {
    basis2.setX(-basis.Y());
    basis2.setY(basis.X());
    basis2.normalize();
  }
  const Kernel::V3D basis3{basis.cross_prod(basis2)};
  const Kernel::V3D localPoint{
      ((basis2 * std::cos(polarAngle) + basis3 * std::sin(polarAngle)) *
       radialLength) +
      alongAxis};
  return localPoint;
}
/**
 * Returns the symmetry axis for the given matrix
 *
 * According to ITA, 11.2 the axis of a symmetry operation can be determined by
 * solving the Eigenvalue problem \f$Wu = u\f$ for rotations or \f$Wu = -u\f$
 * for rotoinversions. This is implemented using the general real non-symmetric
 * eigen-problem solver provided by the GSL.
 *
 * @param matrix :: Matrix of a SymmetryOperation
 * @return Axis of symmetry element.
 */
V3R SymmetryElementWithAxisGenerator::determineAxis(
    const Kernel::IntMatrix &matrix) const {
  gsl_matrix *eigenMatrix = getGSLMatrix(matrix);
  gsl_matrix *identityMatrix =
      getGSLIdentityMatrix(matrix.numRows(), matrix.numCols());

  gsl_eigen_genv_workspace *eigenWs = gsl_eigen_genv_alloc(matrix.numRows());

  gsl_vector_complex *alpha = gsl_vector_complex_alloc(3);
  gsl_vector *beta = gsl_vector_alloc(3);
  gsl_matrix_complex *eigenVectors = gsl_matrix_complex_alloc(3, 3);

  gsl_eigen_genv(eigenMatrix, identityMatrix, alpha, beta, eigenVectors,
                 eigenWs);
  gsl_eigen_genv_sort(alpha, beta, eigenVectors, GSL_EIGEN_SORT_ABS_DESC);

  double determinant = matrix.determinant();

  Kernel::V3D eigenVector;

  for (size_t i = 0; i < matrix.numCols(); ++i) {
    double eigenValue = GSL_REAL(gsl_complex_div_real(
        gsl_vector_complex_get(alpha, i), gsl_vector_get(beta, i)));

    if (fabs(eigenValue - determinant) < 1e-9) {
      for (size_t j = 0; j < matrix.numRows(); ++j) {
        double element = GSL_REAL(gsl_matrix_complex_get(eigenVectors, j, i));

        eigenVector[j] = element;
      }
    }
  }

  eigenVector *= determinant;

  double sumOfElements = eigenVector.X() + eigenVector.Y() + eigenVector.Z();

  if (sumOfElements < 0) {
    eigenVector *= -1.0;
  }

  gsl_matrix_free(eigenMatrix);
  gsl_matrix_free(identityMatrix);
  gsl_eigen_genv_free(eigenWs);
  gsl_vector_complex_free(alpha);
  gsl_vector_free(beta);
  gsl_matrix_complex_free(eigenVectors);

  double min = 1.0;
  for (size_t i = 0; i < 3; ++i) {
    double absoluteValue = fabs(eigenVector[i]);
    if (absoluteValue != 0.0 &&
        (eigenVector[i] < min && (absoluteValue - fabs(min)) < 1e-9)) {
      min = eigenVector[i];
    }
  }

  V3R axis;
  for (size_t i = 0; i < 3; ++i) {
    axis[i] = static_cast<int>(boost::math::round(eigenVector[i] / min));
  }

  return axis;
}
Example #5
0
/** method to cacluate the detectors parameters and add them to the detectors
*averages
*@param spDet    -- shared pointer to the Mantid Detector
*@param Observer -- sample position or the centre of the polar system of
*coordinates to calculate detector's parameters.
*/
void AvrgDetector::addDetInfo(const Geometry::IDetector_const_sptr &spDet,
                              const Kernel::V3D &Observer) {
  m_nComponents++;
  Kernel::V3D detPos = spDet->getPos();
  Kernel::V3D toDet = (detPos - Observer);

  double dist2Det, Polar, Azimut, ringPolar, ringAzim;
  // identify the detector' position in the beam coordinate system:
  toDet.getSpherical(dist2Det, Polar, Azimut);
  if (m_nComponents <= 1) {
    m_FlightPathSum = dist2Det;
    m_PolarSum = Polar;
    m_AzimutSum = Azimut;

    m_AzimBase = Polar;
    m_PolarBase = Azimut;
    ringPolar = Polar;
    ringAzim = Azimut;
  } else {
    ringPolar = nearAngle(m_AzimBase, Polar);
    ringAzim = nearAngle(m_PolarBase, Azimut);
    m_FlightPathSum += dist2Det;
    m_PolarSum += ringPolar;
    m_AzimutSum += ringAzim;
  }

  // centre of the azimuthal ring (the ring  detectors form around the beam)
  Kernel::V3D ringCentre(0, 0, toDet.Z());

  // Get the bounding box
  Geometry::BoundingBox bbox;
  std::vector<Kernel::V3D> coord(3);

  Kernel::V3D er(0, 1, 0), e_th,
      ez(0, 0, 1); // ez along beamline, which is always oz;
  if (dist2Det)
    er = toDet / dist2Det; // direction to the detector
  Kernel::V3D e_tg =
      er.cross_prod(ez); // tangential to the ring and anticloakwise;
  e_tg.normalize();
  // make orthogonal -- projections are calculated in this coordinate system
  ez = e_tg.cross_prod(er);

  coord[0] = er;   // new X
  coord[1] = ez;   // new y
  coord[2] = e_tg; // new z
  bbox.setBoxAlignment(ringCentre, coord);

  spDet->getBoundingBox(bbox);

  // linear extensions of the bounding box orientied tangentially to the equal
  // scattering angle circle
  double azimMin = bbox.zMin();
  double azimMax = bbox.zMax();
  double polarMin = bbox.yMin(); // bounding box has been rotated according to
                                 // coord above, so z is along e_tg
  double polarMax = bbox.yMax();

  if (m_useSphericalSizes) {
    if (dist2Det == 0)
      dist2Det = 1;

    // convert to angular units
    double polarHalfSize =
        rad2deg * atan2(0.5 * (polarMax - polarMin), dist2Det);
    double azimHalfSize = rad2deg * atan2(0.5 * (azimMax - azimMin), dist2Det);

    polarMin = ringPolar - polarHalfSize;
    polarMax = ringPolar + polarHalfSize;
    azimMin = ringAzim - azimHalfSize;
    azimMax = ringAzim + azimHalfSize;
  }
  if (m_AzimMin > azimMin)
    m_AzimMin = azimMin;
  if (m_AzimMax < azimMax)
    m_AzimMax = azimMax;

  if (m_PolarMin > polarMin)
    m_PolarMin = polarMin;
  if (m_PolarMax < polarMax)
    m_PolarMax = polarMax;
}
Example #6
0
/** Create output workspace
 * @brief ConvertCWSDExpToMomentum::createExperimentMDWorkspace
 * @return
 */
API::IMDEventWorkspace_sptr ConvertCWSDMDtoHKL::createHKLMDWorkspace(
    const std::vector<Kernel::V3D> &vec_hkl,
    const std::vector<signal_t> &vec_signal,
    const std::vector<detid_t> &vec_detid) {
  // Check
  if (vec_hkl.size() != vec_signal.size() ||
      vec_signal.size() != vec_detid.size())
    throw std::invalid_argument("Input vectors for HKL, signal and detector "
                                "IDs are of different size!");

  // Create workspace in Q_sample with dimenion as 3
  size_t nDimension = 3;
  IMDEventWorkspace_sptr mdws =
      MDEventFactory::CreateMDWorkspace(nDimension, "MDEvent");

  // Extract Dimensions and add to the output workspace.
  std::vector<std::string> vec_ID(3);
  vec_ID[0] = "H";
  vec_ID[1] = "K";
  vec_ID[2] = "L";

  std::vector<std::string> dimensionNames(3);
  dimensionNames[0] = "H";
  dimensionNames[1] = "K";
  dimensionNames[2] = "L";

  Mantid::Kernel::SpecialCoordinateSystem coordinateSystem =
      Mantid::Kernel::HKL;

  // Add dimensions
  std::vector<double> m_extentMins(3);
  std::vector<double> m_extentMaxs(3);
  std::vector<size_t> m_numBins(3, 100);
  getRange(vec_hkl, m_extentMins, m_extentMaxs);

  // Get MDFrame of HKL type with RLU
  auto unitFactory = makeMDUnitFactoryChain();
  auto unit = unitFactory->create(Units::Symbol::RLU.ascii());
  Mantid::Geometry::HKL frame(unit);

  for (size_t i = 0; i < nDimension; ++i) {
    std::string id = vec_ID[i];
    std::string name = dimensionNames[i];
    // std::string units = "A^-1";
    mdws->addDimension(
        Geometry::MDHistoDimension_sptr(new Geometry::MDHistoDimension(
            id, name, frame, static_cast<coord_t>(m_extentMins[i]),
            static_cast<coord_t>(m_extentMaxs[i]), m_numBins[i])));
  }

  // Set coordinate system
  mdws->setCoordinateSystem(coordinateSystem);

  // Creates a new instance of the MDEventInserter to output workspace
  MDEventWorkspace<MDEvent<3>, 3>::sptr mdws_mdevt_3 =
      boost::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(mdws);
  MDEventInserter<MDEventWorkspace<MDEvent<3>, 3>::sptr> inserter(mdws_mdevt_3);

  // Go though each spectrum to conver to MDEvent
  for (size_t iq = 0; iq < vec_hkl.size(); ++iq) {
    Kernel::V3D hkl = vec_hkl[iq];
    std::vector<Mantid::coord_t> millerindex(3);
    millerindex[0] = static_cast<float>(hkl.X());
    millerindex[1] = static_cast<float>(hkl.Y());
    millerindex[2] = static_cast<float>(hkl.Z());

    signal_t signal = vec_signal[iq];
    signal_t error = std::sqrt(signal);
    uint16_t runnumber = 1;
    detid_t detid = vec_detid[iq];

    // Insert
    inserter.insertMDEvent(
        static_cast<float>(signal), static_cast<float>(error * error),
        static_cast<uint16_t>(runnumber), detid, millerindex.data());
  }

  return mdws;
}
Example #7
0
double MeshObject2D::distanceToPlane(const Kernel::V3D &point) const {
  return ((point.X() * m_planeParameters.a) +
          (point.Y() * m_planeParameters.b) +
          (point.Z() * m_planeParameters.c) + m_planeParameters.k);
}