Skip to content

Commit

Permalink
RE 7244_MantidEV_misses_Monoclinic_C
Browse files Browse the repository at this point in the history
Replaced ScalarUtils::GetSignRelatedUBs() with
ScalarUtils::GetRelatedUBs().  The new method not only tries
negating pairs of edges, but also forms a set of permutations
of the edges that both preserve handedness and could still
form Niggli cells to within experimental error.  With this
fix MantidEV now finds the Monoclinc C cell, so this fixes
the problem.
The test code still needs to be updated for this new
method.

refs #7244
  • Loading branch information
DennisMikkelson committed Jun 5, 2013
1 parent 1fe3a23 commit 79ec229
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,11 @@ class MANTID_GEOMETRY_DLL ScalarUtils
bool use_triclinic );

/// Get list of related cells obtained by reflecting pairs of sides with
/// nearly a 90 degree angle between the sides.
static std::vector<Kernel::DblMatrix> GetSignRelatedUBs(
const Kernel::DblMatrix & UB,
double angle_tolerance );
/// nearly a 90 degree angle between the sides, and permuting sides.
static std::vector<Kernel::DblMatrix> GetRelatedUBs(
const Kernel::DblMatrix & UB,
double factor,
double angle_tolerance );

private:
/// Add conventional cell to list if it has the least error for its form num
Expand Down
83 changes: 65 additions & 18 deletions Code/Mantid/Framework/Geometry/src/Crystal/ScalarUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,13 @@ std::vector<ConventionalCell> ScalarUtils::GetCells(
const std::string & cell_type,
const std::string & centering )
{
double angle_tolerance = 2.0f;
double angle_tolerance = 2.0;
double length_factor = 1.05;

std::vector<ConventionalCell> result;

std::vector<DblMatrix> UB_list = GetSignRelatedUBs( UB, angle_tolerance );
std::vector<DblMatrix> UB_list =
GetRelatedUBs( UB, length_factor, angle_tolerance );

for ( size_t k = 0; k < UB_list.size(); k++ )
{
Expand Down Expand Up @@ -221,15 +223,17 @@ ConventionalCell ScalarUtils::GetCellForForm( const DblMatrix & UB,
size_t form_num )
{
ConventionalCell info( UB );
double angle_tolerance = 2.0f;
double angle_tolerance = 2.0;
double length_factor = 1.05;
ReducedCell form_0;
ReducedCell form;

double error;
double min_error = 1e20; // errors are usually < 10, so this is big enough

std::vector<double> l_params;
std::vector<DblMatrix> UB_list = GetSignRelatedUBs( UB, angle_tolerance );
std::vector<DblMatrix> UB_list =
GetRelatedUBs( UB, angle_tolerance, length_factor );

for ( size_t i = 0; i < UB_list.size(); i++ )
{
Expand Down Expand Up @@ -331,8 +335,21 @@ ConventionalCell ScalarUtils::GetCellBestError(


/**
* Get a list of UB matrices that are related to the specified UB
* by reflecting pairs of the unit cell side vectors, a, b, c.
*
* Get a list of UB matrices that are related to the specified UB.
* The related UBs are generated by both reflecting pairs of
* of the unit cell edge vectors a,b,c and permuting the resulting
* edge vectors in ways that preserve the handedness of the cell.
* For example replacing a,b,c with b,c,a would preserve the handedness,
* but replacing a,b,c with a,c,b would not. In this case we would also
* need to negate side a, so we would replace a,b,c with -a,c,b. A
* permutation of the sides is only used provided the sides are still
* "essentially" in increasing order. The specified factor provides a
* tolerance to relax the restriction that |a|<=|b|<=|c|. As long as a
* side is less than or equal to the following side times the specified
* factor, it is considered less than or equal to the following side,
* for purposes of checking whether or not the list of sides could form
* a Niggli cell. This provides a tolerance for experimental error.
* Two sides will be reflected across the origin if the angle between
* them is within the specified angle_tolerance of 90 degrees. This will
* help find the correct Niggli cell for cases where the angle is near
Expand All @@ -343,20 +360,26 @@ ConventionalCell ScalarUtils::GetCellBestError(
* so it is also checked.
*
* @param UB The original matrix (should be for Niggli cell)
* @param factor Tolerance for error in real-space cell edge
* lengths.
* @param angle_tolerance Tolerance for angles near 90 degree.
*
* @return A vector of UB matrices related to the original UB matrix
* by reflections of pairs of the side vectors a, b, c.
*/
std::vector<DblMatrix> ScalarUtils::GetSignRelatedUBs(
std::vector<DblMatrix> ScalarUtils::GetRelatedUBs(
const DblMatrix & UB,
double factor,
double angle_tolerance )
{
std::vector<DblMatrix> result;

V3D a, b, c,
a_vec, b_vec, c_vec,
m_a_vec, m_b_vec, m_c_vec;
V3D a, b, c,
a_vec, b_vec, c_vec, // vectors for generating reflections
m_a_vec, m_b_vec, m_c_vec; // of pairs of sides

V3D a_temp, b_temp, c_temp, // vectors for generating handedness
m_a_temp,m_b_temp,m_c_temp; // preserving permutations of sides

IndexingUtils::GetABC( UB, a_vec, b_vec, c_vec );

Expand Down Expand Up @@ -386,14 +409,38 @@ std::vector<DblMatrix> ScalarUtils::GetSignRelatedUBs(
for ( size_t row = 0; row < 4; row++ )
{
if ( fabs(angles[row] - 90.0) < angle_tolerance ) // if nearly 90,
{ // try related cell
a = reflections[row][0]; // +cell <-> -cell
b = reflections[row][1];
c = reflections[row][2];

Matrix<double> temp_UB(3,3,false);
IndexingUtils::GetUB( temp_UB, a, b, c );
result.push_back( temp_UB );
{ // try related cell
a_temp = reflections[row][0]; // +cell <-> -cell
b_temp = reflections[row][1];
c_temp = reflections[row][2];
// for each accepted reflection, try all
// modified premutations that preserve the
// handedness AND keep the cell edges
// nearly ordered as a <= b <= c.
m_a_temp = a_temp * (-1.0);
m_b_temp = b_temp * (-1.0);
m_c_temp = c_temp * (-1.0);

V3D permutations[6][3] = { { a_temp, b_temp, c_temp },
{ m_a_temp, c_temp, b_temp },
{ b_temp, c_temp, a_temp },
{ m_b_temp, a_temp, c_temp },
{ c_temp, a_temp, b_temp },
{ m_c_temp, b_temp, a_temp } };

for ( size_t perm = 0; perm < 6; perm++ )
{
a = permutations[perm][0];
b = permutations[perm][1];
c = permutations[perm][2];
if ( a.norm() <= factor * b.norm() &&
b.norm() <= factor * c.norm() ) // could be Niggli within
{ // experimental error
Matrix<double> temp_UB(3,3,false);
IndexingUtils::GetUB( temp_UB, a, b, c );
result.push_back( temp_UB );
}
}
}
}

Expand Down

0 comments on commit 79ec229

Please sign in to comment.