ProSHADE  0.7.6.1 (AUG 2021)
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)
 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::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::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.1
Date
AUG 2021

Definition in file ProSHADE_symmetry.cpp.

Function Documentation

◆ determinePeakThreshold()

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

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.
[out]retThe threshold.

Definition at line 71 of file ProSHADE_symmetry.cpp.

72 {
73  //================================================ Initialise variables
74  proshade_double ret = 0.0;
75  proshade_unsign vecSize = static_cast< proshade_unsign > ( inArr.size() );
76  proshade_double* meadianAndIQR = new proshade_double[2];
77 
78  //================================================ Deal with low number of input cases
79  if ( vecSize == 0 ) { delete[] meadianAndIQR; return ( ret ); } // Return 0
80  if ( vecSize <= 4 ) { ret = std::accumulate ( inArr.begin(), inArr.end(), 0.0 ) / static_cast< proshade_double > ( vecSize ); } // Return mean
81 
82  //================================================ Deal with reasonable number in input cases
83  else
84  {
85  //============================================ Allocate memory for median and IQR computation
86  ProSHADE_internal_misc::checkMemoryAllocation ( meadianAndIQR, __FILE__, __LINE__, __func__ );
87 
88  //============================================ Find median and IQR
89  ProSHADE_internal_maths::vectorMedianAndIQR ( &inArr, meadianAndIQR );
90 
91  //============================================ Get the threshold
92  ret = meadianAndIQR[0] + ( meadianAndIQR[1] * noIQRsFromMedian );
93  }
94 
95  //================================================ Sanity checks
96  if ( ret > *( std::max_element ( inArr.begin(), inArr.end() ) ) )
97  {
98  ret = *( std::max_element ( inArr.begin(), inArr.end() ) );
99  }
100 
101  //================================================ Release memory
102  delete[] meadianAndIQR;
103 
104  //================================================ Done
105  return ( ret );
106 
107 }

◆ 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 3079 of file ProSHADE_symmetry.cpp.

3080 {
3081  //================================================ Initialise variables
3082  std::vector < std::pair< proshade_unsign, proshade_unsign > > ret;
3083  std::vector< proshade_unsign > C5List;
3084  proshade_double dotProduct;
3085 
3086  //================================================ Find all C5 symmetries
3087  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 ); } }
3088 
3089  //================================================ For each unique pair of C5 and C3
3090  for ( proshade_unsign c5 = 0; c5 < static_cast<proshade_unsign> ( C5List.size() ); c5++ )
3091  {
3092  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
3093  {
3094  //======================================== Compare only C3s to the C5List and only with decent average peak height
3095  const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
3096  if ( !lhs1.AlmostEquals ( rhs1 ) ) { continue; }
3097  if ( CSymList->at(cSym)[5] < minPeakHeight ) { continue; }
3098 
3099  //======================================== Check the angle between the C5 and C3 axes
3100  dotProduct = ProSHADE_internal_maths::computeDotProduct ( &CSymList->at(C5List.at(c5))[1],
3101  &CSymList->at(C5List.at(c5))[2],
3102  &CSymList->at(C5List.at(c5))[3],
3103  &CSymList->at(cSym)[1],
3104  &CSymList->at(cSym)[2],
3105  &CSymList->at(cSym)[3] );
3106 
3107  //======================================== Is the angle approximately the dihedral angle?
3108  if ( std::abs ( std::abs( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) - std::abs( dotProduct ) ) < axErr )
3109  {
3110  std::pair< proshade_unsign, proshade_unsign > hlp;
3111  hlp.first = C5List.at(c5);
3112  hlp.second = cSym;
3113  ret.emplace_back ( hlp );
3114  }
3115  }
3116  }
3117 
3118  //================================================ Done
3119  return ( ret );
3120 }

◆ findBestOctaDihedralPair()

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 3258 of file ProSHADE_symmetry.cpp.

3259 {
3260  //================================================ Initialise variables
3261  std::pair< proshade_unsign, proshade_unsign > ret;
3262  std::vector< proshade_unsign > C4List;
3263  proshade_double bestHeightSum = 0.0;
3264  proshade_double dotProduct;
3265 
3266  //================================================ Find all C5 symmetries
3267  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 ); } }
3268 
3269  //================================================ For each unique pair of C5 and C3
3270  for ( proshade_unsign c4 = 0; c4 < static_cast<proshade_unsign> ( C4List.size() ); c4++ )
3271  {
3272  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
3273  {
3274  //======================================== Compare only C3s to the C5List and only with decent average peak height
3275  const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
3276  if ( !lhs1.AlmostEquals ( rhs1 ) ) { continue; }
3277  if ( CSymList->at(cSym)[5] < minPeakHeight ) { continue; }
3278 
3279  //======================================== Check the angle between the C5 and C3 axes
3280  dotProduct = ProSHADE_internal_maths::computeDotProduct ( &CSymList->at(C4List.at(c4))[1],
3281  &CSymList->at(C4List.at(c4))[2],
3282  &CSymList->at(C4List.at(c4))[3],
3283  &CSymList->at(cSym)[1],
3284  &CSymList->at(cSym)[2],
3285  &CSymList->at(cSym)[3] );
3286 
3287  //======================================== Is the angle approximately the dihedral angle?
3288  if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( std::abs( dotProduct ) - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( std::abs( dotProduct ) + axErr ) ) )
3289  {
3290  if ( bestHeightSum < ( CSymList->at(C4List.at(c4))[5] + CSymList->at(cSym)[5] ) )
3291  {
3292  bestHeightSum = ( CSymList->at(C4List.at(c4))[5] + CSymList->at(cSym)[5] );
3293  ret.first = C4List.at(c4);
3294  ret.second = cSym;
3295  }
3296  }
3297  }
3298  }
3299 
3300  //================================================ Done
3301  return ( ret );
3302 
3303 }

◆ findBestTetraDihedralPair()

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 4192 of file ProSHADE_symmetry.cpp.

4193 {
4194  //================================================ Initialise variables
4195  std::pair< proshade_unsign, proshade_unsign > ret;
4196  std::vector< proshade_unsign > C3List;
4197  proshade_double bestHeightSum = 0.0;
4198  proshade_double dotProduct;
4199 
4200  //================================================ Find all C3 symmetries
4201  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 ); } }
4202 
4203  //================================================ For each unique pair of C3 and C2
4204  for ( proshade_unsign c3 = 0; c3 < static_cast<proshade_unsign> ( C3List.size() ); c3++ )
4205  {
4206  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
4207  {
4208  //======================================== Compare only C2s to the C3List and only with decent average peak height
4209  const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 2.0 );
4210  if ( !lhs1.AlmostEquals ( rhs1 ) ) { continue; }
4211  if ( CSymList->at(cSym)[5] < minPeakHeight ) { continue; }
4212 
4213  //======================================== Check the angle between the C5 and C3 axes
4214  dotProduct = ProSHADE_internal_maths::computeDotProduct ( &CSymList->at(C3List.at(c3))[1],
4215  &CSymList->at(C3List.at(c3))[2],
4216  &CSymList->at(C3List.at(c3))[3],
4217  &CSymList->at(cSym)[1],
4218  &CSymList->at(cSym)[2],
4219  &CSymList->at(cSym)[3] );
4220 
4221  //======================================== Is the angle approximately the dihedral angle?
4222  if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( std::abs( dotProduct ) - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( std::abs( dotProduct ) + axErr ) ) )
4223  {
4224  if ( bestHeightSum < ( CSymList->at(C3List.at(c3))[5] + CSymList->at(cSym)[5] ) )
4225  {
4226  bestHeightSum = CSymList->at(C3List.at(c3))[5] + CSymList->at(cSym)[5];
4227  ret.first = C3List.at(c3);
4228  ret.second = cSym;
4229  }
4230  }
4231  }
4232  }
4233 
4234  //================================================ Done
4235  return ( ret );
4236 
4237 }

◆ 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 3872 of file ProSHADE_symmetry.cpp.

3873 {
3874  //================================================ Done
3875  return ( a[5] > b[5] );
3876 
3877 }
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:1773
ProSHADE_internal_misc::checkMemoryAllocation
void checkMemoryAllocation(chVar checkVar, std::string fileP, unsigned int lineP, std::string funcP, std::string infoP="This error may occurs when ProSHADE requests memory to be\n : allocated to it and this operation fails. This could\n : happen when not enough memory is available, either due to\n : other processes using a lot of memory, or when the machine\n : does not have sufficient memory available. Re-run to see\n : if this problem persists.")
Checks if memory was allocated properly.
Definition: ProSHADE_misc.hpp:67
ProSHADE_internal_maths::vectorMedianAndIQR
void vectorMedianAndIQR(std::vector< proshade_double > *vec, proshade_double *&ret)
Function to get vector median and inter-quartile range.
Definition: ProSHADE_maths.cpp:149
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