ProSHADE  0.7.5.3 (FEB 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...
 
std::pair< proshade_unsign, proshade_unsign > findBestIcosDihedralPair (std::vector< proshade_double * > *CSymList, proshade_double minPeakHeight, proshade_double axErr)
 This function finds the best pair 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...
 
bool sortProSHADESymmetryByPeak (proshade_double *a, proshade_double *b)
 This function allows using std::sort to sort vectors of ProSHADE symmetry format.. 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.5.3
Date
FEB 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 64 of file ProSHADE_symmetry.cpp.

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

◆ findBestIcosDihedralPair()

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

This function finds the best pair 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]retThe pair of axes with closest angle to the required icosahedron dihedral angle.

Definition at line 2899 of file ProSHADE_symmetry.cpp.

2900 {
2901  //================================================ Initialise variables
2902  std::pair< proshade_unsign, proshade_unsign > ret;
2903  std::vector< proshade_unsign > C5List;
2904  proshade_double bestDihedralAngle = 999.9;
2905  proshade_double dotProduct;
2906 
2907  //================================================ Find all C5 symmetries
2908  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ ) { if ( CSymList->at(cSym)[0] == 5 && CSymList->at(cSym)[5] >= minPeakHeight ) { ProSHADE_internal_misc::addToUnsignVector ( &C5List, cSym ); } }
2909 
2910  //================================================ For each unique pair of C5 and C3
2911  for ( proshade_unsign c5 = 0; c5 < static_cast<proshade_unsign> ( C5List.size() ); c5++ )
2912  {
2913  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
2914  {
2915  //======================================== Compare only C3s to the C5List and only with decent average peak height
2916  if ( CSymList->at(cSym)[0] != 3 ) { continue; }
2917  if ( CSymList->at(cSym)[5] < minPeakHeight ) { continue; }
2918 
2919  //======================================== Check the angle between the C5 and C3 axes
2920  dotProduct = ProSHADE_internal_maths::computeDotProduct ( &CSymList->at(C5List.at(c5))[1],
2921  &CSymList->at(C5List.at(c5))[2],
2922  &CSymList->at(C5List.at(c5))[3],
2923  &CSymList->at(cSym)[1],
2924  &CSymList->at(cSym)[2],
2925  &CSymList->at(cSym)[3] );
2926 
2927  //======================================== Is the angle approximately the dihedral angle?
2928  if ( std::abs ( std::abs( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) - std::abs( dotProduct ) ) < axErr )
2929  {
2930  if ( bestDihedralAngle > std::abs ( std::abs( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) - std::abs( dotProduct ) ) )
2931  {
2932  bestDihedralAngle = std::abs ( std::abs( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) - std::abs( dotProduct ) );
2933  ret.first = C5List.at(c5);
2934  ret.second = cSym;
2935  }
2936  }
2937  }
2938  }
2939 
2940  //================================================ Done
2941  return ( ret );
2942 }

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

3065 {
3066  //================================================ Initialise variables
3067  std::pair< proshade_unsign, proshade_unsign > ret;
3068  std::vector< proshade_unsign > C4List;
3069  proshade_double bestDihedralAngle = 999.9;
3070  proshade_double dotProduct;
3071 
3072  //================================================ Find all C5 symmetries
3073  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ ) { if ( CSymList->at(cSym)[0] == 4 && CSymList->at(cSym)[5] >= minPeakHeight ) { ProSHADE_internal_misc::addToUnsignVector ( &C4List, cSym ); } }
3074 
3075  //================================================ For each unique pair of C5 and C3
3076  for ( proshade_unsign c4 = 0; c4 < static_cast<proshade_unsign> ( C4List.size() ); c4++ )
3077  {
3078  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
3079  {
3080  //======================================== Compare only C3s to the C5List and only with decent average peak height
3081  if ( CSymList->at(cSym)[0] != 3 ) { continue; }
3082  if ( CSymList->at(cSym)[5] < minPeakHeight ) { continue; }
3083 
3084  //======================================== Check the angle between the C5 and C3 axes
3085  dotProduct = ProSHADE_internal_maths::computeDotProduct ( &CSymList->at(C4List.at(c4))[1],
3086  &CSymList->at(C4List.at(c4))[2],
3087  &CSymList->at(C4List.at(c4))[3],
3088  &CSymList->at(cSym)[1],
3089  &CSymList->at(cSym)[2],
3090  &CSymList->at(cSym)[3] );
3091 
3092  //======================================== Is the angle approximately the dihedral angle?
3093  if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( std::abs( dotProduct ) - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( std::abs( dotProduct ) + axErr ) ) )
3094  {
3095  if ( bestDihedralAngle > std::abs( ( 1.0 / sqrt ( 3.0 ) ) - std::abs( dotProduct ) ) )
3096  {
3097  bestDihedralAngle = std::abs( ( 1.0 / sqrt ( 3.0 ) ) - std::abs( dotProduct ) );
3098  ret.first = C4List.at(c4);
3099  ret.second = cSym;
3100  }
3101  }
3102  }
3103  }
3104 
3105  //================================================ Done
3106  return ( ret );
3107 
3108 }

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

3901 {
3902  //================================================ Initialise variables
3903  std::pair< proshade_unsign, proshade_unsign > ret;
3904  std::vector< proshade_unsign > C3List;
3905  proshade_double bestDihedralAngle = 999.9;
3906  proshade_double dotProduct;
3907 
3908  //================================================ Find all C5 symmetries
3909  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ ) { if ( CSymList->at(cSym)[0] == 3 && CSymList->at(cSym)[5] >= minPeakHeight ) { ProSHADE_internal_misc::addToUnsignVector ( &C3List, cSym ); } }
3910 
3911  //================================================ For each unique pair of C3 and C2
3912  for ( proshade_unsign c3 = 0; c3 < static_cast<proshade_unsign> ( C3List.size() ); c3++ )
3913  {
3914  for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
3915  {
3916  //======================================== Compare only C3s to the C5List and only with decent average peak height
3917  if ( CSymList->at(cSym)[0] != 2 ) { continue; }
3918  if ( CSymList->at(cSym)[5] < minPeakHeight ) { continue; }
3919 
3920  //======================================== Check the angle between the C5 and C3 axes
3921  dotProduct = ProSHADE_internal_maths::computeDotProduct ( &CSymList->at(C3List.at(c3))[1],
3922  &CSymList->at(C3List.at(c3))[2],
3923  &CSymList->at(C3List.at(c3))[3],
3924  &CSymList->at(cSym)[1],
3925  &CSymList->at(cSym)[2],
3926  &CSymList->at(cSym)[3] );
3927 
3928  //======================================== Is the angle approximately the dihedral angle?
3929  if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( std::abs( dotProduct ) - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( std::abs( dotProduct ) + axErr ) ) )
3930  {
3931  if ( bestDihedralAngle > std::abs( ( 1.0 / sqrt ( 3.0 ) ) - std::abs( dotProduct ) ) )
3932  {
3933  bestDihedralAngle = std::abs( ( 1.0 / sqrt ( 3.0 ) ) - std::abs( dotProduct ) );
3934  ret.first = C3List.at(c3);
3935  ret.second = cSym;
3936  }
3937  }
3938  }
3939  }
3940 
3941  //================================================ Done
3942  return ( ret );
3943 
3944 }

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

3670 {
3671  //================================================ Done
3672  return ( a[5] > b[5] );
3673 
3674 }
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:1705
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:65
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:147
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