ProSHADE  0.7.6.6 (JUL 2022)
Protein Shape Detection
ProSHADE_symmetry.cpp File Reference

This source file contains all the functions required to detect symmetry axes and types from the inverse SOFT map. More...

Go to the source code of this file.

Functions

proshade_double determinePeakThreshold (std::vector< proshade_double > inArr, proshade_double noIQRsFromMedian, proshade_double startMinVal)
 This function takes a vector of values and determines the threshold for removing noise from it. More...
 
bool sortProSHADESymmetryByPeak (proshade_double *a, proshade_double *b)
 This function allows using std::sort to sort vectors of ProSHADE symmetry format.. More...
 
std::vector< std::pair< proshade_unsign, proshade_unsign > > findBestIcosDihedralPair (std::vector< proshade_double * > *CSymList, proshade_double minPeakHeight, proshade_double axErr)
 This function finds all the pairs of axes conforming to the icosahedron dihedral angle. More...
 
std::vector< std::pair< proshade_unsign, proshade_unsign > > findBestOctaDihedralPair (std::vector< proshade_double * > *CSymList, proshade_double minPeakHeight, proshade_double axErr)
 This function finds the best pair of axes conforming to the octahedron dihedral angle. More...
 
std::vector< std::pair< proshade_unsign, proshade_unsign > > findBestTetraDihedralPair (std::vector< proshade_double * > *CSymList, proshade_double minPeakHeight, proshade_double axErr)
 This function finds the best pair of axes conforming to the tetrahedron dihedral angle. More...
 

Detailed Description

This source file contains all the functions required to detect symmetry axes and types from the inverse SOFT map.

The functions in this source file are required to allow detection of symmetry axes and symmetries from the inverse SOFT map. The currect functionality can detect C, D, T, O and I symmetries with the C and D symmetries having their fold automatically detected as well.

Copyright by Michal Tykac and individual contributors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3) Neither the name of Michal Tykac nor the names of this code's contributors may be used to endorse or promote products derived from this software without specific prior written permission.

This software is provided by the copyright holder and contributors "as is" and any express or implied warranties, including, but not limitted to, the implied warranties of merchantibility and fitness for a particular purpose are disclaimed. In no event shall the copyright owner or the contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limitted to, procurement of substitute goods or services, loss of use, data or profits, or business interuption) however caused and on any theory of liability, whether in contract, strict liability or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.

Author
Michal Tykac
Garib N. Murshudov
Version
0.7.6.6
Date
JUL 2022

Definition in file ProSHADE_symmetry.cpp.

Function Documentation

◆ determinePeakThreshold()

proshade_double determinePeakThreshold ( std::vector< proshade_double >  inArr,
proshade_double  noIQRsFromMedian,
proshade_double  startMinVal 
)

This function takes a vector of values and determines the threshold for removing noise from it.

Parameters
[in]inArrA vector of values for which the threshold is to be determined.
[in]noIQRsFromMedianMow many times should the RMSD be added to the mean to get starting threshold.
[in]startMinValMinimum value for the threshold.
[out]retThe threshold.

Definition at line 73 of file ProSHADE_symmetry.cpp.

74 {
75  //================================================ Initialise variables
76  proshade_double ret = 0.0;
77  proshade_double rmsd = 0.0;
78  size_t vecSize = inArr.size();
79  proshade_unsign noVals = 0;
80  proshade_double mean = 0.0;
81 
82  //================================================ Deal with low number of input cases
83  if ( vecSize == 0 ) { return ( ret ); } // Return 0
84  if ( vecSize <= 4 ) { ret = std::accumulate ( inArr.begin(), inArr.end(), 0.0 ) / static_cast< proshade_double > ( vecSize ); return ( ret ); } // Return mean
85 
86  //================================================ Deal with reasonable number in input cases
87  else
88  {
89  //============================================ Find mean
90  mean = std::accumulate ( inArr.begin(), inArr.end(), 0.0 ) / static_cast< proshade_double > ( vecSize );
91 
92  //============================================ Get the RMS distance
93  for ( size_t i = 0; i < vecSize; i++ )
94  {
95  rmsd += std::pow ( ret - inArr.at(i), 2.0 );
96  }
97  rmsd = std::sqrt ( rmsd );
98 
99  //============================================ Get the threshold
100  ret = std::min ( mean + ( noIQRsFromMedian * rmsd ), startMinVal );
101  for ( size_t iter = 0; iter < inArr.size(); iter++ ) { if ( inArr.at(iter) > ret ) { noVals += 1; } }
102  while ( noVals > 1000)
103  {
104  noVals = 0;
105  ret += 0.01;
106  for ( size_t iter = 0; iter < inArr.size(); iter++ ) { if ( inArr.at(iter) > ret ) { noVals += 1; } }
107  }
108  if ( noVals == 0 ) { ret -= 0.01; }
109  }
110 
111  //================================================ Sanity checks
112  if ( ret > *( std::max_element ( inArr.begin(), inArr.end() ) ) )
113  {
114  ret = *( std::max_element ( inArr.begin(), inArr.end() ) );
115  }
116 
117  if ( ret > 0.85 ) { ret = 0.85; }
118 
119  //================================================ Done
120  return ( ret );
121 
122 }

◆ findBestIcosDihedralPair()

std::vector< std::pair< proshade_unsign, proshade_unsign > > findBestIcosDihedralPair ( std::vector< proshade_double * > *  CSymList,
proshade_double  minPeakHeight,
proshade_double  axErr 
)

This function finds all the pairs of axes conforming to the icosahedron dihedral angle.

Parameters
[in]CSymListA vector containing the already detected Cyclic symmetries.
[in]minPeakHeightThe minimum average peak height for axis to be considered.
[in]axErrThe error tolerance on angle matching.
[out]retVector of pairs containing the indices of all axes conforming to the required icosahedron dihedral angle.

Definition at line 1971 of file ProSHADE_symmetry.cpp.

1972 {
1973  //================================================ Initialise variables
1974  std::vector < std::pair< proshade_unsign, proshade_unsign > > ret;
1975  std::vector< proshade_unsign > C5List;
1976  proshade_double dotProduct;
1977 
1978  //================================================ Find all C5 symmetries
1979  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ ) { const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 5.0 ); if ( lhs1.AlmostEquals ( rhs1 ) && CSymList->at(cSym)[5] >= minPeakHeight ) { ProSHADE_internal_misc::addToUnsignVector ( &C5List, cSym ); } }
1980 
1981  //================================================ For each unique pair of C5 and C3
1982  for ( proshade_unsign c5 = 0; c5 < static_cast<proshade_unsign> ( C5List.size() ); c5++ )
1983  {
1984  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
1985  {
1986  //======================================== Compare only C3s to the C5List and only with decent average peak height
1987  const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
1988  if ( !lhs1.AlmostEquals ( rhs1 ) ) { continue; }
1989  if ( CSymList->at(cSym)[5] < minPeakHeight ) { continue; }
1990 
1991  //======================================== Check the angle between the C5 and C3 axes
1992  dotProduct = ProSHADE_internal_maths::computeDotProduct ( &CSymList->at(C5List.at(c5))[1],
1993  &CSymList->at(C5List.at(c5))[2],
1994  &CSymList->at(C5List.at(c5))[3],
1995  &CSymList->at(cSym)[1],
1996  &CSymList->at(cSym)[2],
1997  &CSymList->at(cSym)[3] );
1998 
1999  //======================================== Is the angle approximately the dihedral angle?
2000  if ( std::abs ( std::abs( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) - std::abs( dotProduct ) ) < axErr )
2001  {
2002  std::pair< proshade_unsign, proshade_unsign > hlp;
2003  hlp.first = C5List.at(c5);
2004  hlp.second = cSym;
2005  ret.emplace_back ( hlp );
2006  }
2007  }
2008  }
2009 
2010  //================================================ Done
2011  return ( ret );
2012 }

◆ findBestOctaDihedralPair()

std::vector< std::pair< proshade_unsign, proshade_unsign > > findBestOctaDihedralPair ( std::vector< proshade_double * > *  CSymList,
proshade_double  minPeakHeight,
proshade_double  axErr 
)

This function finds the best pair of axes conforming to the octahedron dihedral angle.

Parameters
[in]CSymListA vector containing the already detected Cyclic symmetries.
[in]minPeakHeightThe minimum average peak height for axis to be considered.
[in]axErrThe error tolerance on angle matching.
[out]retThe pair of axes with closest angle to the required icosahedron dihedral angle.

Definition at line 2150 of file ProSHADE_symmetry.cpp.

2151 {
2152  //================================================ Initialise variables
2153  std::vector < std::pair< proshade_unsign, proshade_unsign > > ret;
2154  std::vector< proshade_unsign > C4List;
2155  proshade_double dotProduct;
2156 
2157  //================================================ Find all C5 symmetries
2158  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ ) { const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 4.0 ); if ( lhs1.AlmostEquals ( rhs1 ) && CSymList->at(cSym)[5] >= minPeakHeight ) { ProSHADE_internal_misc::addToUnsignVector ( &C4List, cSym ); } }
2159 
2160  //================================================ For each unique pair of C5 and C3
2161  for ( proshade_unsign c4 = 0; c4 < static_cast<proshade_unsign> ( C4List.size() ); c4++ )
2162  {
2163  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
2164  {
2165  //======================================== Compare only C3s to the C5List and only with decent average peak height
2166  const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
2167  if ( !lhs1.AlmostEquals ( rhs1 ) ) { continue; }
2168  if ( CSymList->at(cSym)[5] < minPeakHeight ) { continue; }
2169 
2170  //======================================== Check the angle between the C5 and C3 axes
2171  dotProduct = ProSHADE_internal_maths::computeDotProduct ( &CSymList->at(C4List.at(c4))[1],
2172  &CSymList->at(C4List.at(c4))[2],
2173  &CSymList->at(C4List.at(c4))[3],
2174  &CSymList->at(cSym)[1],
2175  &CSymList->at(cSym)[2],
2176  &CSymList->at(cSym)[3] );
2177 
2178  //======================================== Is the angle approximately the dihedral angle?
2179  if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( std::abs( dotProduct ) - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( std::abs( dotProduct ) + axErr ) ) )
2180  {
2181  std::pair< proshade_unsign, proshade_unsign > hlp;
2182  hlp.first = C4List.at(c4);
2183  hlp.second = cSym;
2184  ret.emplace_back ( hlp );
2185  }
2186  }
2187  }
2188 
2189  //================================================ Done
2190  return ( ret );
2191 
2192 }

◆ findBestTetraDihedralPair()

std::vector< std::pair< proshade_unsign, proshade_unsign > > findBestTetraDihedralPair ( std::vector< proshade_double * > *  CSymList,
proshade_double  minPeakHeight,
proshade_double  axErr 
)

This function finds the best pair of axes conforming to the tetrahedron dihedral angle.

Parameters
[in]CSymListA vector containing the already detected Cyclic symmetries.
[in]minPeakHeightThe minimum average peak height for axis to be considered.
[in]axErrThe error tolerance on angle matching.
[out]retThe pair of axes with closest angle to the required icosahedron dihedral angle.

Definition at line 3487 of file ProSHADE_symmetry.cpp.

3488 {
3489  //================================================ Initialise variables
3490  std::vector < std::pair< proshade_unsign, proshade_unsign > > ret;
3491  std::vector< proshade_unsign > C3List;
3492  proshade_double dotProduct;
3493 
3494  //================================================ Find all C3 symmetries
3495  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ ) { const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 ); if ( lhs1.AlmostEquals ( rhs1 ) && CSymList->at(cSym)[5] >= minPeakHeight ) { ProSHADE_internal_misc::addToUnsignVector ( &C3List, cSym ); } }
3496 
3497  //================================================ For each unique pair of C3 and C2
3498  for ( proshade_unsign c3 = 0; c3 < static_cast<proshade_unsign> ( C3List.size() ); c3++ )
3499  {
3500  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
3501  {
3502  //======================================== Compare only C2s to the C3List and only with decent average peak height
3503  const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 2.0 );
3504  if ( !lhs1.AlmostEquals ( rhs1 ) ) { continue; }
3505  if ( CSymList->at(cSym)[5] < minPeakHeight ) { continue; }
3506 
3507  //======================================== Check the angle between the C5 and C3 axes
3508  dotProduct = ProSHADE_internal_maths::computeDotProduct ( &CSymList->at(C3List.at(c3))[1],
3509  &CSymList->at(C3List.at(c3))[2],
3510  &CSymList->at(C3List.at(c3))[3],
3511  &CSymList->at(cSym)[1],
3512  &CSymList->at(cSym)[2],
3513  &CSymList->at(cSym)[3] );
3514 
3515  //======================================== Is the angle approximately the dihedral angle?
3516  if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( std::abs( dotProduct ) - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( std::abs( dotProduct ) + axErr ) ) )
3517  {
3518  std::pair< proshade_unsign, proshade_unsign > hlp;
3519  hlp.first = C3List.at(c3);
3520  hlp.second = cSym;
3521  ret.emplace_back ( hlp );
3522  }
3523  }
3524  }
3525 
3526  //================================================ Done
3527  return ( ret );
3528 
3529 }

◆ sortProSHADESymmetryByPeak()

bool sortProSHADESymmetryByPeak ( proshade_double *  a,
proshade_double *  b 
)

This function allows using std::sort to sort vectors of ProSHADE symmetry format..

Parameters
[in]aPointer to a ProSHADE symmetry formatted array.
[in]bPointer to a ProSHADE symmetry formatted array.
[out]XBoolean whether a is larger than b.

Definition at line 2916 of file ProSHADE_symmetry.cpp.

2917 {
2918  //================================================ Done
2919  return ( a[5] > b[5] );
2920 
2921 }
ProSHADE_internal_maths::computeDotProduct
proshade_double computeDotProduct(proshade_double *x1, proshade_double *y1, proshade_double *z1, proshade_double *x2, proshade_double *y2, proshade_double *z2)
Simple 3D vector dot product computation.
Definition: ProSHADE_maths.cpp:1785
ProSHADE_internal_misc::addToUnsignVector
void addToUnsignVector(std::vector< proshade_unsign > *vecToAddTo, proshade_unsign elementToAdd)
Adds the element to the vector.
Definition: ProSHADE_misc.cpp:99