28 #if defined ( __GNUC__ )
29 #pragma GCC diagnostic push
30 #pragma GCC diagnostic ignored "-Wpedantic"
31 #pragma GCC diagnostic ignored "-Wshadow"
32 #pragma GCC diagnostic ignored "-Wall"
33 #pragma GCC diagnostic ignored "-Wextra"
34 #pragma GCC diagnostic ignored "-Wdouble-promotion"
35 #pragma GCC diagnostic ignored "-Wconversion"
39 #if defined ( __clang__ )
40 #pragma clang diagnostic push
41 #pragma clang diagnostic ignored "-Wpedantic"
42 #pragma clang diagnostic ignored "-Wshadow"
43 #pragma clang diagnostic ignored "-Wall"
44 #pragma clang diagnostic ignored "-Wextra"
45 #pragma clang diagnostic ignored "-Wdouble-promotion"
46 #pragma clang diagnostic ignored "-Weverything"
50 #if defined ( _MSC_VER )
51 #pragma warning ( disable:4996 )
55 #define GEMMI_WRITE_IMPLEMENTATION
56 #include <gemmi/to_pdb.hpp>
59 #if defined ( _MSC_VER )
60 #pragma warning ( default:4996 )
64 #if defined ( __GNUC__ )
65 #pragma GCC diagnostic pop
69 #if defined ( __clang__ )
70 #pragma clang diagnostic pop
76 proshade_signed
addAxisUnlessSame ( proshade_unsign fold, proshade_double axX, proshade_double axY, proshade_double axZ, proshade_double axHeight, proshade_double averageFSC, std::vector< proshade_double* >* prosp, proshade_double axErr );
82 bool checkElementAlreadyExists ( std::vector<std::vector< proshade_double > >* elements, std::vector< proshade_double >* elem, proshade_double matrixTolerance );
83 bool checkElementsFormGroup ( std::vector<std::vector< proshade_double > >* elements, proshade_double matrixTolerance );
99 this->
fileType = ProSHADE_internal_io::UNKNOWN;
164 this->
spherePos = std::vector<proshade_single> ( );
218 ProSHADE_internal_data::ProSHADE_data::ProSHADE_data ( std::string strName,
double *mapVals,
int len, proshade_single xDmSz, proshade_single yDmSz, proshade_single zDmSz, proshade_unsign xDmInd, proshade_unsign yDmInd, proshade_unsign zDmInd, proshade_signed xFr, proshade_signed yFr, proshade_signed zFr, proshade_signed xT, proshade_signed yT, proshade_signed zT, proshade_unsign inputO )
222 this->fileName = strName;
223 this->fileType = ProSHADE_internal_io::MAP;
226 this->internalMap =
nullptr;
229 this->xDimSize = xDmSz;
230 this->yDimSize = yDmSz;
231 this->zDimSize = zDmSz;
235 this->xDimIndices = xDmInd;
236 this->yDimIndices = yDmInd;
237 this->zDimIndices = zDmInd;
238 this->xGridIndices = xDmInd;
239 this->yGridIndices = yDmInd;
240 this->zGridIndices = zDmInd;
241 this->xAxisOrder = 1;
242 this->yAxisOrder = 2;
243 this->zAxisOrder = 3;
244 this->xAxisOrigin = xFr;
245 this->yAxisOrigin = yFr;
246 this->zAxisOrigin = zFr;
252 this->xDimSizeOriginal = 0.0;
253 this->yDimSizeOriginal = 0.0;
254 this->zDimSizeOriginal = 0.0;
255 this->xDimIndicesOriginal = 0;
256 this->yDimIndicesOriginal = 0;
257 this->zDimIndicesOriginal = 0;
258 this->xAxisOriginOriginal = 0;
259 this->yAxisOriginOriginal = 0;
260 this->zAxisOriginOriginal = 0;
261 this->originalMapXCom = 0.0;
262 this->originalMapYCom = 0.0;
263 this->originalMapZCom = 0.0;
264 this->mapMovFromsChangeX = 0.0;
265 this->mapMovFromsChangeY = 0.0;
266 this->mapMovFromsChangeZ = 0.0;
267 this->mapCOMProcessChangeX = 0.0;
268 this->mapCOMProcessChangeY = 0.0;
269 this->mapCOMProcessChangeZ = 0.0;
272 this->originalPdbRotCenX = 0.0;
273 this->originalPdbRotCenY = 0.0;
274 this->originalPdbRotCenZ = 0.0;
275 this->originalPdbTransX = 0.0;
276 this->originalPdbTransY = 0.0;
277 this->originalPdbTransZ = 0.0;
288 this->spherePos = std::vector<proshade_single> ( );
290 this->spheres =
nullptr;
291 this->sphericalHarmonics =
nullptr;
292 this->rotSphericalHarmonics =
nullptr;
293 this->maxShellBand = 0;
296 this->rrpMatrices =
nullptr;
297 this->eMatrices =
nullptr;
298 this->so3Coeffs =
nullptr;
299 this->so3CoeffsInverse =
nullptr;
300 this->wignerMatrices =
nullptr;
301 this->integrationWeight = 0.0;
302 this->maxEMatDim = 0;
303 this->translationMap =
nullptr;
306 this->isEmpty =
false;
307 this->inputOrder = inputO;
310 if (
static_cast<proshade_unsign
> ( len ) != ( xDmInd * yDmInd * zDmInd ) )
312 throw ProSHADE_exception (
"Structure class input map has wrong dimensions.",
"EP00044", __FILE__, __LINE__, __func__,
"The supplied map array size has different dimensions to\n : the required map dimensions." );
315 if ( (
static_cast<proshade_signed
> ( xT - xFr ) !=
static_cast<proshade_signed
> ( xDmInd - 1 ) ) ||
316 (
static_cast<proshade_signed
> ( yT - yFr ) !=
static_cast<proshade_signed
> ( yDmInd - 1 ) ) ||
317 (
static_cast<proshade_signed
> ( zT - zFr ) !=
static_cast<proshade_signed
> ( zDmInd - 1 ) ) )
319 throw ProSHADE_exception (
"Structure class input dimensions not in line with map\n : to/from indices.",
"EP00045", __FILE__, __LINE__, __func__,
"The supplied map information does not add up. The\n : dimensions are not in line with the indexing start/stop\n : position distances and therefore proper map indexing\n : cannot be done. Please check the input values." );
323 this->internalMap =
new proshade_double [this->xDimIndices * this->yDimIndices * this->zDimIndices];
327 proshade_unsign arrPos = 0;
328 for ( proshade_unsign xIt = 0; xIt < this->xDimIndices; xIt++ )
330 for ( proshade_unsign yIt = 0; yIt < this->yDimIndices; yIt++ )
332 for ( proshade_unsign zIt = 0; zIt < this->zDimIndices; zIt++ )
334 arrPos = zIt + this->zDimIndices * ( yIt + this->yDimIndices * xIt );
335 this->internalMap[arrPos] =
static_cast<proshade_double
> ( mapVals[arrPos] );
357 if ( this->internalMap !=
nullptr )
359 delete[] this->internalMap;
360 this->internalMap =
nullptr;
364 if ( this->spheres !=
nullptr )
366 for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
368 if ( this->spheres[iter] !=
nullptr )
370 delete this->spheres[iter];
371 this->spheres[iter] =
nullptr;
374 delete[] this->spheres;
378 if ( this->sphericalHarmonics !=
nullptr )
380 for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
382 if ( this->sphericalHarmonics[iter] !=
nullptr )
384 delete[] this->sphericalHarmonics[iter];
385 this->sphericalHarmonics[iter] =
nullptr;
388 delete[] this->sphericalHarmonics;
392 if ( this->rotSphericalHarmonics !=
nullptr )
394 for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
396 if ( this->rotSphericalHarmonics[iter] !=
nullptr )
398 delete[] this->rotSphericalHarmonics[iter];
399 this->rotSphericalHarmonics[iter] =
nullptr;
402 delete[] this->rotSphericalHarmonics;
406 if ( this->rrpMatrices !=
nullptr )
408 for ( proshade_unsign bwIt = 0; bwIt < this->maxShellBand; bwIt++ )
410 if ( this->rrpMatrices[bwIt] !=
nullptr )
412 for ( proshade_unsign shIt = 0; shIt < this->noSpheres; shIt++ )
414 if ( this->rrpMatrices[bwIt][shIt] !=
nullptr )
416 delete[] this->rrpMatrices[bwIt][shIt];
417 this->rrpMatrices[bwIt][shIt] =
nullptr;
421 delete[] this->rrpMatrices[bwIt];
425 delete[] this->rrpMatrices;
429 if ( this->eMatrices !=
nullptr )
431 for ( proshade_unsign bandIter = 0; bandIter < this->getEMatDim ( ); bandIter++ )
433 if ( this->eMatrices[bandIter] !=
nullptr )
435 for ( proshade_unsign band2Iter = 0; band2Iter < static_cast<proshade_unsign> ( ( bandIter * 2 ) + 1 ); band2Iter++ )
437 if ( this->eMatrices[bandIter][band2Iter] !=
nullptr )
439 delete[] this->eMatrices[bandIter][band2Iter];
440 this->eMatrices[bandIter][band2Iter] =
nullptr;
444 delete[] this->eMatrices[bandIter];
448 delete[] this->eMatrices;
452 if ( this->so3Coeffs !=
nullptr )
454 fftw_free ( this->so3Coeffs );
456 if ( this->so3CoeffsInverse !=
nullptr )
458 fftw_free ( this->so3CoeffsInverse );
462 if ( this->wignerMatrices !=
nullptr )
464 for ( proshade_unsign bandIter = 1; bandIter < this->maxEMatDim; bandIter++ )
466 if ( this->wignerMatrices[bandIter] !=
nullptr )
468 for ( proshade_unsign order1Iter = 0; order1Iter < ( (bandIter * 2) + 1 ); order1Iter++ )
470 if ( this->wignerMatrices[bandIter][order1Iter] !=
nullptr )
472 delete[] this->wignerMatrices[bandIter][order1Iter];
475 delete[] this->wignerMatrices[bandIter];
478 delete[] wignerMatrices;
482 if ( this->translationMap !=
nullptr )
484 fftw_free ( this->translationMap );
488 if ( this->sphereMappedRotFun.size() > 0 )
490 for ( proshade_unsign spIt = 0; spIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); spIt++ )
492 delete this->sphereMappedRotFun.at(spIt);
497 for (
size_t vIt = 0; vIt < this->cyclicSymmetries.size(); vIt++ ) {
if ( this->cyclicSymmetries.at(vIt) != nullptr ) {
delete[] this->cyclicSymmetries.at(vIt); } }
498 for (
size_t vIt = 0; vIt < this->recommendedSymmetryValues.size(); vIt++ ) {
if ( this->recommendedSymmetryValues.at(vIt) != nullptr ) {
delete[] this->recommendedSymmetryValues.at(vIt); } }
499 for (
size_t vIt = 0; vIt < this->tetrahedralSymmetries.size(); vIt++ ) {
if ( this->tetrahedralSymmetries.at(vIt) != nullptr ) {
delete[] this->tetrahedralSymmetries.at(vIt); } }
500 for (
size_t vIt = 0; vIt < this->octahedralSymmetries.size(); vIt++ ) {
if ( this->octahedralSymmetries.at(vIt) != nullptr ) {
delete[] this->octahedralSymmetries.at(vIt); } }
501 for (
size_t vIt = 0; vIt < this->icosahedralSymmetries.size(); vIt++ ) {
if ( this->icosahedralSymmetries.at(vIt) != nullptr ) {
delete[] this->icosahedralSymmetries.at(vIt); } }
502 for (
size_t vIt = 0; vIt < this->dihedralSymmetries.size(); vIt++ ) {
for (
size_t vIt2 = 0; vIt2 < this->dihedralSymmetries.at(vIt).size(); vIt2++ ) {
if ( this->dihedralSymmetries.at(vIt).at(vIt2) != nullptr ) {
delete[] this->dihedralSymmetries.at(vIt).at(vIt2); } } }
525 void ProSHADE_internal_data::ProSHADE_data::readInStructure ( std::string fName, proshade_unsign inputO,
ProSHADE_settings* settings, proshade_double* maskArr, proshade_unsign maskXDim, proshade_unsign maskYDim, proshade_unsign maskZDim, proshade_double* weightsArr, proshade_unsign weigXDim, proshade_unsign weigYDim, proshade_unsign weigZDim )
531 if ( !this->isEmpty )
533 throw ProSHADE_exception (
"Structure data class not empty.",
"E000005", __FILE__, __LINE__, __func__,
"Attempted to read in structure into a ProSHADE_data\n : object which already does have structure read in\n : i.e. " + this->fileName );
537 this->fileName = fName;
543 this->inputOrder = inputO;
546 switch ( this->fileType )
548 case ProSHADE_internal_io::UNKNOWN:
549 throw ProSHADE_exception (
"Unknown file type.",
"E000006", __FILE__, __LINE__, __func__,
"When attempting to read the file\n : " + this->fileName +
"\n : the file extension was determined as unknown. This could\n : mean either that the file does not exist, or that it is\n : not one of the supported extensions." );
551 case ProSHADE_internal_io::GEMMI:
552 throw ProSHADE_exception (
"Unknown file type.",
"E000006", __FILE__, __LINE__, __func__,
"When attempting to read the file\n : " + this->fileName +
"\n : the file extension was determined as unknown. This could\n : mean either that the file does not exist, or that it is\n : not one of the supported extensions." );
554 case ProSHADE_internal_io::PDB:
555 this->readInPDB ( settings );
558 case ProSHADE_internal_io::MAP:
559 this->readInMAP ( settings, maskArr, maskXDim, maskYDim, maskZDim, weightsArr, weigXDim, weigYDim, weigZDim );
564 this->isEmpty =
false;
586 std::stringstream ss;
587 ss <<
"Starting to load the structure from Gemmi object " << inputO;
591 if ( !this->isEmpty )
593 throw ProSHADE_exception (
"Structure data class not empty.",
"E000005", __FILE__, __LINE__, __func__,
"Attempted to read in structure into a ProSHADE_data\n : object which already does have structure read in\n : i.e. " + this->fileName );
597 this->fileName = gemmiStruct->name;
600 this->fileType = ProSHADE_internal_io::GEMMI;
603 this->inputOrder = inputO;
606 this->readInGemmi ( gemmiStruct, settings );
609 this->isEmpty =
false;
638 gemmi::Ccp4<float> map;
639 map.read_ccp4 ( gemmi::MaybeGzipped ( this->fileName.c_str() ) );
642 map.setup ( 0.0f, gemmi::MapSetup::ReorderOnly );
646 &this->xDimIndices, &this->yDimIndices, &this->zDimIndices,
647 &this->xDimSize, &this->yDimSize, &this->zDimSize,
648 &this->aAngle, &this->bAngle, &this->cAngle,
649 &this->xFrom, &this->yFrom, &this->zFrom,
650 &this->xAxisOrigin, &this->yAxisOrigin, &this->zAxisOrigin,
651 &this->xAxisOrder, &this->yAxisOrder, &this->zAxisOrder,
652 &this->xGridIndices, &this->yGridIndices, &this->zGridIndices );
655 ProSHADE_internal_io::readInMapData ( &map, this->internalMap, this->xDimIndices, this->yDimIndices, this->zDimIndices, this->xAxisOrder, this->yAxisOrder, this->zAxisOrder );
659 maskArr, maskXDim, maskYDim, maskZDim );
664 settings->
calcBounds.at(0) *= (
static_cast<proshade_double
> ( this->xDimSize ) /
static_cast<proshade_double
> ( this->xDimIndices ) );
665 settings->
calcBounds.at(1) *= (
static_cast<proshade_double
> ( this->yDimSize ) /
static_cast<proshade_double
> ( this->yDimIndices ) );
666 settings->
calcBounds.at(2) *= (
static_cast<proshade_double
> ( this->zDimSize ) /
static_cast<proshade_double
> ( this->zDimIndices ) );
671 weightsArr, weigXDim, weigYDim, weigZDim );
674 if ( settings->
removeNegativeDensity ) {
for (
size_t iter = 0; iter < static_cast< size_t > ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ ) {
if ( this->internalMap[iter] < 0.0 ) { this->internalMap[iter] = 0.0; } } }
679 settings->
setResolution ( std::min (
static_cast<proshade_single
> ( this->xDimSize ) /
static_cast<proshade_single
> ( this->xDimIndices ),
680 std::min (
static_cast<proshade_single
> ( this->yDimSize ) /
static_cast<proshade_single
> ( this->yDimIndices ),
681 static_cast<proshade_single
> ( this->zDimSize ) /
static_cast<proshade_single
> ( this->zDimIndices ) ) ) * 2.0f );
685 this->figureIndexStartStop ( );
688 this->reSampleMap ( settings );
691 this->xDimSizeOriginal = this->xDimSize;
692 this->yDimSizeOriginal = this->yDimSize;
693 this->zDimSizeOriginal = this->zDimSize;
696 this->xDimIndicesOriginal = this->xDimIndices;
697 this->yDimIndicesOriginal = this->yDimIndices;
698 this->zDimIndicesOriginal = this->zDimIndices;
701 this->xAxisOriginOriginal = this->xAxisOrigin;
702 this->yAxisOriginOriginal = this->yAxisOrigin;
703 this->zAxisOriginOriginal = this->zAxisOrigin;
706 this->findMapCOM ( );
707 this->originalMapXCom = this->xCom;
708 this->originalMapYCom = this->yCom;
709 this->originalMapZCom = this->zCom;
733 gemmi::Structure pdbFile = gemmi::read_structure ( gemmi::MaybeGzipped ( this->fileName ) );
736 this->readInGemmi ( &pdbFile, settings );
780 proshade_double xCOMPdb, yCOMPdb, zCOMPdb;
784 proshade_single xF = 0.0f, xT = 0.0f, yF = 0.0f, yT = 0.0f, zF = 0.0f, zT = 0.0f;
788 proshade_single xMov =
static_cast< proshade_single
> ( settings->
coOrdsExtraSpace - xF );
789 proshade_single yMov =
static_cast< proshade_single
> ( settings->
coOrdsExtraSpace - yF );
790 proshade_single zMov =
static_cast< proshade_single
> ( settings->
coOrdsExtraSpace - zF );
794 this->xDimSize =
static_cast< proshade_single
> ( xT - xF + ( 2.0f * settings->
coOrdsExtraSpace ) );
795 this->yDimSize =
static_cast< proshade_single
> ( yT - yF + ( 2.0f * settings->
coOrdsExtraSpace ) );
796 this->zDimSize =
static_cast< proshade_single
> ( zT - zF + ( 2.0f * settings->
coOrdsExtraSpace ) );
799 ProSHADE_internal_mapManip::generateMapFromPDB ( *gemmiStruct, this->internalMap, settings->
requestedResolution, this->xDimSize, this->yDimSize, this->zDimSize, &this->xTo, &this->yTo, &this->zTo, settings->
forceP1, settings->
firstModelOnly );
802 if ( settings->
removeNegativeDensity ) {
for (
size_t iter = 0; iter < static_cast< size_t > ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ ) {
if ( this->internalMap[iter] < 0.0 ) { this->internalMap[iter] = 0.0; } } }
805 this->setPDBMapValues ( );
809 &this->xFrom, &this->xTo, &this->yFrom, &this->yTo, &this->zFrom, &this->zTo,
810 &this->xAxisOrigin, &this->yAxisOrigin, &this->zAxisOrigin );
812 static_cast< proshade_signed
> ( this->xDimIndices ),
static_cast< proshade_signed
> ( this->yDimIndices ),
813 static_cast< proshade_signed
> ( this->zDimIndices ) );
816 this->reSampleMap ( settings );
819 this->xDimSizeOriginal = this->xDimSize;
820 this->yDimSizeOriginal = this->yDimSize;
821 this->zDimSizeOriginal = this->zDimSize;
824 this->xDimIndicesOriginal = this->xDimIndices;
825 this->yDimIndicesOriginal = this->yDimIndices;
826 this->zDimIndicesOriginal = this->zDimIndices;
829 this->xAxisOriginOriginal = this->xAxisOrigin;
830 this->yAxisOriginOriginal = this->yAxisOrigin;
831 this->zAxisOriginOriginal = this->zAxisOrigin;
834 this->findMapCOM ( );
835 this->originalMapXCom = this->xCom;
836 this->originalMapYCom = this->yCom;
837 this->originalMapZCom = this->zCom;
861 this->xDimIndices =
static_cast< proshade_unsign
> ( this->xTo );
862 this->yDimIndices =
static_cast< proshade_unsign
> ( this->yTo );
863 this->zDimIndices =
static_cast< proshade_unsign
> ( this->zTo );
871 this->xGridIndices = this->xDimIndices;
872 this->yGridIndices = this->yDimIndices;
873 this->zGridIndices = this->zDimIndices;
876 this->xAxisOrder = 1;
877 this->yAxisOrder = 2;
878 this->zAxisOrder = 3;
881 this->xAxisOrigin = this->xFrom;
882 this->yAxisOrigin = this->yFrom;
883 this->zAxisOrigin = this->zFrom;
897 this->xTo = this->xFrom +
static_cast< proshade_signed
> ( this->xDimIndices ) - 1;
898 this->yTo = this->yFrom +
static_cast< proshade_signed
> ( this->yDimIndices ) - 1;
899 this->zTo = this->zFrom +
static_cast< proshade_signed
> ( this->zDimIndices ) - 1;
919 gemmi::Grid<float> mapData;
920 mapData.set_unit_cell (
static_cast< double > ( this->xDimSize ),
static_cast< double > ( this->yDimSize ),
static_cast< double > ( this->zDimSize ),
static_cast< double > ( this->aAngle ),
static_cast< double > ( this->bAngle ),
static_cast< double > ( this->cAngle ) );
921 mapData.set_size_without_checking (
static_cast< int > ( this->xDimIndices ),
static_cast< int > ( this->yDimIndices ),
static_cast< int > ( this->zDimIndices ) );
922 mapData.axis_order = gemmi::AxisOrder::XYZ;
923 mapData.spacegroup = &gemmi::get_spacegroup_p1();
926 gemmi::Ccp4<float> map;
928 map.update_ccp4_header ( mode );
932 this->xDimIndices, this->yDimIndices, this->zDimIndices,
933 this->xDimSize, this->yDimSize, this->zDimSize,
934 this->aAngle, this->bAngle, this->cAngle,
935 this->xFrom, this->yFrom, this->zFrom,
936 this->xAxisOrigin, this->yAxisOrigin, this->zAxisOrigin,
937 this->xAxisOrder, this->yAxisOrder, this->zAxisOrder,
938 this->xGridIndices, this->yGridIndices, this->zGridIndices,
942 proshade_unsign arrPos = 0;
943 for ( proshade_unsign uIt = 0; uIt < this->xDimIndices; uIt++ )
945 for ( proshade_unsign vIt = 0; vIt < this->yDimIndices; vIt++ )
947 for ( proshade_unsign wIt = 0; wIt < this->zDimIndices; wIt++ )
949 arrPos = wIt + this->zDimIndices * ( vIt + this->yDimIndices * uIt );
950 map.grid.set_value (
static_cast< int > ( uIt ),
static_cast< int > ( vIt ),
static_cast< int > ( wIt ),
static_cast<float> ( this->internalMap[arrPos] ) );
956 map.update_ccp4_header ( mode,
true );
959 map.write_ccp4_map ( fName );
983 void ProSHADE_internal_data::ProSHADE_data::writePdb ( std::string fName, proshade_double euA, proshade_double euB, proshade_double euG, proshade_double trsX, proshade_double trsY, proshade_double trsZ, proshade_double rotX, proshade_double rotY, proshade_double rotZ,
bool firstModel )
988 throw ProSHADE_exception (
"Cannot write co-ordinate file if the input file did not contain co-ordinates.",
"EP00047", __FILE__, __LINE__, __func__,
"You have called the WritePDB function on structure which\n : was created by reading in a map. This is not allowed as\n : ProSHADE cannot create co-ordinates from map file." );
992 gemmi::Structure pdbFile = gemmi::read_structure ( gemmi::MaybeGzipped ( this->fileName ) );
995 this->writeGemmi ( fName, pdbFile, euA, euB, euG, trsX, trsY, trsZ, rotX, rotY, rotZ, firstModel );
1020 void ProSHADE_internal_data::ProSHADE_data::writeGemmi ( std::string fName, gemmi::Structure gemmiStruct, proshade_double euA, proshade_double euB, proshade_double euG, proshade_double trsX, proshade_double trsY, proshade_double trsZ, proshade_double rotX, proshade_double rotY, proshade_double rotZ,
bool firstModel )
1023 if ( ( euA != 0.0 ) || ( euB != 0.0 ) || ( euG != 0.0 ) )
1033 std::ofstream outCoOrdFile;
1034 outCoOrdFile.open ( fName.c_str() );
1036 if ( outCoOrdFile.is_open() )
1038 gemmi::PdbWriteOptions opt;
1039 write_pdb ( gemmiStruct, outCoOrdFile, opt );
1043 std::stringstream hlpMessage;
1044 hlpMessage <<
"Failed to open the PDB file " << fName <<
" for output.";
1045 throw ProSHADE_exception ( hlpMessage.str().c_str(),
"EP00048", __FILE__, __LINE__, __func__,
"ProSHADE has failed to open the PDB output file. This is\n : likely caused by either not having the write privileges\n : to the required output path, or by making a mistake in\n : the path." );
1048 outCoOrdFile.close ( );
1065 proshade_double* hlpMap =
new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1069 for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1071 hlpMap[iter] = this->internalMap[iter];
1072 this->internalMap[iter] = mask[iter];
1076 this->writeMap ( fName );
1079 for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1081 this->internalMap[iter] = hlpMap[iter];
1102 std::stringstream ss;
1103 ss <<
"Moving map box centre to " << settings->
boxCentre.at(0) <<
"; " << settings->
boxCentre.at(1) <<
"; " << settings->
boxCentre.at(2) <<
" .";
1107 proshade_double xSamplingRate =
static_cast<proshade_double
> ( this->xDimSize ) /
static_cast<proshade_double
> ( this->xDimIndices );
1108 proshade_double ySamplingRate =
static_cast<proshade_double
> ( this->yDimSize ) /
static_cast<proshade_double
> ( this->yDimIndices );
1109 proshade_double zSamplingRate =
static_cast<proshade_double
> ( this->zDimSize ) /
static_cast<proshade_double
> ( this->zDimIndices );
1112 proshade_double startCentreX = ( ( (
static_cast<proshade_double
> ( this->xTo ) -
static_cast<proshade_double
> ( this->xFrom ) ) / 2.0 ) * xSamplingRate );
1113 proshade_double startCentreY = ( ( (
static_cast<proshade_double
> ( this->yTo ) -
static_cast<proshade_double
> ( this->yFrom ) ) / 2.0 ) * ySamplingRate );
1114 proshade_double startCentreZ = ( ( (
static_cast<proshade_double
> ( this->zTo ) -
static_cast<proshade_double
> ( this->zFrom ) ) / 2.0 ) * zSamplingRate );
1117 proshade_double boxStartX = settings->
boxCentre.at(0) - (
static_cast<proshade_double
> ( this->xFrom ) * xSamplingRate );
1118 proshade_double boxStartY = settings->
boxCentre.at(1) - (
static_cast<proshade_double
> ( this->yFrom ) * ySamplingRate );
1119 proshade_double boxStartZ = settings->
boxCentre.at(2) - (
static_cast<proshade_double
> ( this->zFrom ) * zSamplingRate );
1122 proshade_double xShift = startCentreX - boxStartX;
1123 proshade_double yShift = startCentreY - boxStartY;
1124 proshade_double zShift = startCentreZ - boxStartZ;
1127 if ( ( ( settings->
boxCentre.at(0) < (
static_cast<proshade_double
> ( this->xFrom ) * xSamplingRate ) ) ||
1128 ( settings->
boxCentre.at(0) > (
static_cast<proshade_double
> ( this->xFrom ) * xSamplingRate +
static_cast<proshade_double
> ( this->xDimSize ) ) ) ) ||
1129 ( ( settings->
boxCentre.at(1) < (
static_cast<proshade_double
> ( this->yFrom ) * ySamplingRate ) ) ||
1130 ( settings->
boxCentre.at(1) > (
static_cast<proshade_double
> ( this->yFrom ) * ySamplingRate +
static_cast<proshade_double
> ( this->yDimSize ) ) ) ) ||
1131 ( ( settings->
boxCentre.at(2) < (
static_cast<proshade_double
> ( this->zFrom ) * zSamplingRate ) ) ||
1132 ( settings->
boxCentre.at(2) > (
static_cast<proshade_double
> ( this->zFrom ) * zSamplingRate +
static_cast<proshade_double
> ( this->zDimSize ) ) ) ) )
1139 static_cast< proshade_single
> ( xShift ),
1140 static_cast< proshade_single
> ( yShift ),
1141 static_cast< proshade_single
> ( zShift ),
1142 this->xDimSize, this->yDimSize, this->zDimSize,
1143 static_cast< proshade_signed
> ( this->xDimIndices ),
1144 static_cast< proshade_signed
> ( this->yDimIndices ),
1145 static_cast< proshade_signed
> ( this->zDimIndices ) );
1148 std::stringstream ss2;
1149 ss2 <<
"Position " << settings->
boxCentre.at(0) <<
"; " << settings->
boxCentre.at(1) <<
"; " << settings->
boxCentre.at(2) <<
" set at the centre of the map box.";
1167 std::stringstream ss;
1173 static_cast< proshade_single
> ( -settings->
centrePosition.at(0) ),
1174 static_cast< proshade_single
> ( -settings->
centrePosition.at(1) ),
1175 static_cast< proshade_single
> ( -settings->
centrePosition.at(2) ),
1176 this->xDimSize, this->yDimSize, this->zDimSize,
1177 static_cast< proshade_signed
> ( this->xDimIndices ),
1178 static_cast< proshade_signed
> ( this->yDimIndices ),
1179 static_cast< proshade_signed
> ( this->zDimIndices ) );
1187 std::stringstream ss2;
1188 ss2 <<
"Map rotation centre shifted.";
1217 proshade_signed arrayPos, invPos;
1220 proshade_double* hlpMap =
new proshade_double [this->xDimIndices * this->yDimIndices * this->zDimIndices];
1224 for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1226 hlpMap[iter] = this->internalMap[iter];
1230 for ( proshade_signed xIt = 0; xIt < static_cast<proshade_signed> ( this->xDimIndices ); xIt++ )
1232 for ( proshade_signed yIt = 0; yIt < static_cast<proshade_signed> ( this->yDimIndices ); yIt++ )
1234 for ( proshade_signed zIt = 0; zIt < static_cast<proshade_signed> ( this->zDimIndices ); zIt++ )
1237 arrayPos = zIt +
static_cast< proshade_signed
> ( this->zDimIndices ) * ( yIt +
static_cast< proshade_signed
> ( this->yDimIndices ) * xIt );
1238 invPos = (
static_cast< proshade_signed
> ( this->zDimIndices - 1 ) - zIt ) +
static_cast< proshade_signed
> ( this->zDimIndices ) * ( (
static_cast< proshade_signed
> ( this->yDimIndices - 1 ) - yIt ) +
static_cast< proshade_signed
> ( this->yDimIndices ) * (
static_cast< proshade_signed
> ( this->xDimIndices - 1 ) - xIt ) );
1241 this->internalMap[invPos] = hlpMap[arrayPos];
1271 std::vector<proshade_double> mapVals ( this->xDimIndices * this->yDimIndices * this->zDimIndices, 0.0 );
1274 for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1276 mapVals.at(iter) = this->internalMap[iter];
1280 proshade_double* meanSD =
new proshade_double[2];
1284 for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1286 this->internalMap[iter] = ( this->internalMap[iter] - meanSD[0] ) / meanSD[1];
1318 proshade_double* blurredMap =
new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1323 this->xDimSize, this->yDimSize, this->zDimSize, settings->
blurFactor );
1329 if ( settings->
saveMask ) {
if ( settings->
maskFileName ==
"" ) { this->writeMask (
"proshade_mask.map", blurredMap ); }
else { std::stringstream ss; ss << settings->
maskFileName <<
"_" << this->inputOrder <<
".map"; this->writeMask ( ss.str(), blurredMap ); } }
1332 delete[] blurredMap;
1360 for ( proshade_unsign iter = 0; iter < 6; iter++ ) { ret[iter] = settings->
forceBounds[iter]; }
1367 static_cast< proshade_signed
> ( this->xDimIndices ),
1368 static_cast< proshade_signed
> ( this->yDimIndices ),
1369 static_cast< proshade_signed
> ( this->zDimIndices ),
1374 this->xDimSize, this->yDimSize, this->zDimSize, ret, settings->
boundsExtraSpace );
1380 std::stringstream ssHlp;
1381 ssHlp <<
"New boundaries are: " << ret[1] - ret[0] + 1 <<
" x " << ret[3] - ret[2] + 1 <<
" x " << ret[5] - ret[4] + 1;
1387 for ( proshade_unsign iter = 0; iter < 6; iter++ ) { settings->
forceBounds[iter] = ret[iter]; }
1417 newStr->
fileType = ProSHADE_internal_io::MAP;
1420 newStr->
xDimIndices =
static_cast< proshade_unsign
> ( newBounds[1] ) -
static_cast< proshade_unsign
> ( newBounds[0] ) + 1;
1421 newStr->
yDimIndices =
static_cast< proshade_unsign
> ( newBounds[3] ) -
static_cast< proshade_unsign
> ( newBounds[2] ) + 1;
1422 newStr->
zDimIndices =
static_cast< proshade_unsign
> ( newBounds[5] ) -
static_cast< proshade_unsign
> ( newBounds[4] ) + 1;
1424 newStr->
aAngle = this->aAngle;
1425 newStr->
bAngle = this->aAngle;
1426 newStr->
cAngle = this->aAngle;
1428 newStr->
xDimSize =
static_cast<proshade_single
> ( newStr->
xDimIndices ) * ( this->xDimSize /
static_cast<proshade_single
> ( this->xDimIndices ) );
1429 newStr->
yDimSize =
static_cast<proshade_single
> ( newStr->
yDimIndices ) * ( this->yDimSize /
static_cast<proshade_single
> ( this->yDimIndices ) );
1430 newStr->
zDimSize =
static_cast<proshade_single
> ( newStr->
zDimIndices ) * ( this->zDimSize /
static_cast<proshade_single
> ( this->zDimIndices ) );
1440 newStr->
xAxisOrigin = this->xAxisOrigin + newBounds[0];
1441 newStr->
yAxisOrigin = this->yAxisOrigin + newBounds[2];
1442 newStr->
zAxisOrigin = this->zAxisOrigin + newBounds[4];
1444 newStr->
xFrom = this->xFrom + newBounds[0];
1445 newStr->
yFrom = this->yFrom + newBounds[2];
1446 newStr->
zFrom = this->zFrom + newBounds[4];
1448 newStr->
xTo = this->xTo - (
static_cast< proshade_signed
> ( this->xDimIndices - 1 ) - newBounds[1] );
1449 newStr->
yTo = this->yTo - (
static_cast< proshade_signed
> ( this->yDimIndices - 1 ) - newBounds[3] );
1450 newStr->
zTo = this->zTo - (
static_cast< proshade_signed
> ( this->zDimIndices - 1 ) - newBounds[5] );
1459 this->xDimIndices, this->yDimIndices, this->zDimIndices, newStr->
internalMap, this->internalMap );
1482 proshade_single* changeVals =
new proshade_single[6];
1485 proshade_double xMapCOMPreReSampl = 0.0, yMapCOMPreReSampl = 0.0, zMapCOMPreReSampl = 0.0;
1486 ProSHADE_internal_mapManip::findMAPCOMValues ( this->internalMap, &xMapCOMPreReSampl, &yMapCOMPreReSampl, &zMapCOMPreReSampl, this->xDimSize, this->yDimSize, this->zDimSize, this->xFrom, this->xTo, this->yFrom, this->yTo, this->zFrom, this->zTo, settings->
removeNegativeDensity );
1492 this->xDimSize, this->yDimSize, this->zDimSize, changeVals );
1502 this->xDimSize, this->yDimSize, this->zDimSize, changeVals );
1507 this->xDimIndices +=
static_cast<proshade_unsign
> ( changeVals[0] );
1508 this->yDimIndices +=
static_cast<proshade_unsign
> ( changeVals[1] );
1509 this->zDimIndices +=
static_cast<proshade_unsign
> ( changeVals[2] );
1511 this->xGridIndices = this->xDimIndices;
1512 this->yGridIndices = this->yDimIndices;
1513 this->zGridIndices = this->zDimIndices;
1515 this->xTo +=
static_cast<proshade_unsign
> ( changeVals[0] );
1516 this->yTo +=
static_cast<proshade_unsign
> ( changeVals[1] );
1517 this->zTo +=
static_cast<proshade_unsign
> ( changeVals[2] );
1519 this->xDimSize = changeVals[3];
1520 this->yDimSize = changeVals[4];
1521 this->zDimSize = changeVals[5];
1524 proshade_double xMapCOMPostReSampl = 0.0, yMapCOMPostReSampl = 0.0, zMapCOMPostReSampl = 0.0;
1525 ProSHADE_internal_mapManip::findMAPCOMValues ( this->internalMap, &xMapCOMPostReSampl, &yMapCOMPostReSampl, &zMapCOMPostReSampl, this->xDimSize, this->yDimSize, this->zDimSize, this->xFrom, this->xTo, this->yFrom, this->yTo, this->zFrom, this->zTo, settings->
removeNegativeDensity );
1528 proshade_single xMov =
static_cast< proshade_single
> ( xMapCOMPostReSampl - xMapCOMPreReSampl );
1529 proshade_single yMov =
static_cast< proshade_single
> ( yMapCOMPostReSampl - yMapCOMPreReSampl );
1530 proshade_single zMov =
static_cast< proshade_single
> ( zMapCOMPostReSampl - zMapCOMPreReSampl );
1534 &this->yFrom, &this->yTo, &this->zFrom, &this->zTo, &this->xAxisOrigin, &this->yAxisOrigin, &this->zAxisOrigin );
1537 static_cast< proshade_signed
> ( this->xDimIndices ),
static_cast< proshade_signed
> ( this->yDimIndices ),
static_cast< proshade_signed
> ( this->zDimIndices ) );
1540 delete[] changeVals;
1570 proshade_double xCOM = 0.0;
1571 proshade_double yCOM = 0.0;
1572 proshade_double zCOM = 0.0;
1576 this->xDimSize, this->yDimSize, this->zDimSize, this->xFrom,
1580 proshade_single xSampRate =
static_cast< proshade_single
> ( this->xDimSize ) /
static_cast< proshade_single
> ( this->xTo - this->xFrom + 1 );
1581 proshade_single ySampRate =
static_cast< proshade_single
> ( this->yDimSize ) /
static_cast< proshade_single
> ( this->yTo - this->yFrom + 1 );
1582 proshade_single zSampRate =
static_cast< proshade_single
> ( this->zDimSize ) /
static_cast< proshade_single
> ( this->zTo - this->zFrom + 1 );
1585 xCOM /=
static_cast< proshade_double
> ( xSampRate );
1586 yCOM /=
static_cast< proshade_double
> ( ySampRate );
1587 zCOM /=
static_cast< proshade_double
> ( zSampRate );
1589 xCOM -=
static_cast< proshade_double
> ( this->xFrom );
1590 yCOM -=
static_cast< proshade_double
> ( this->yFrom );
1591 zCOM -=
static_cast< proshade_double
> ( this->zFrom );
1594 proshade_double xDist = ( (
static_cast<proshade_double
> ( this->xDimIndices ) / 2.0 ) - xCOM ) *
static_cast<proshade_double
> ( this->xDimSize ) /
static_cast<proshade_double
> ( this->xDimIndices );
1595 proshade_double yDist = ( (
static_cast<proshade_double
> ( this->yDimIndices ) / 2.0 ) - yCOM ) *
static_cast<proshade_double
> ( this->yDimSize ) /
static_cast<proshade_double
> ( this->yDimIndices );
1596 proshade_double zDist = ( (
static_cast<proshade_double
> ( this->zDimIndices ) / 2.0 ) - zCOM ) *
static_cast<proshade_double
> ( this->zDimSize ) /
static_cast<proshade_double
> ( this->zDimIndices );
1600 static_cast< proshade_single
> ( xDist ),
1601 static_cast< proshade_single
> ( yDist ),
1602 static_cast< proshade_single
> ( zDist ),
1603 this->xDimSize, this->yDimSize, this->zDimSize,
1604 static_cast< proshade_signed
> ( this->xDimIndices ),
1605 static_cast< proshade_signed
> ( this->yDimIndices ),
1606 static_cast< proshade_signed
> ( this->zDimIndices ) );
1609 this->mapCOMProcessChangeX -= xDist;
1610 this->mapCOMProcessChangeY -= yDist;
1611 this->mapCOMProcessChangeZ -= zDist;
1632 std::stringstream hlpSS;
1633 hlpSS <<
"Adding extra " << settings->
addExtraSpace <<
" angstroms.";
1642 this->xDimSize += 2 *
static_cast<proshade_single
> ( xAddIndices ) * this->xDimSize /
static_cast<proshade_single
> ( this->xDimIndices );
1643 this->yDimSize += 2 *
static_cast<proshade_single
> ( yAddIndices ) * this->yDimSize /
static_cast<proshade_single
> ( this->yDimIndices );
1644 this->zDimSize += 2 *
static_cast<proshade_single
> ( zAddIndices ) * this->zDimSize /
static_cast<proshade_single
> ( this->zDimIndices );
1646 this->xDimIndices += 2 * xAddIndices;
1647 this->yDimIndices += 2 * yAddIndices;
1648 this->zDimIndices += 2 * zAddIndices;
1650 this->xGridIndices = this->xDimIndices;
1651 this->yGridIndices = this->yDimIndices;
1652 this->zGridIndices = this->zDimIndices;
1654 this->xAxisOrigin -= xAddIndices;
1655 this->yAxisOrigin -= yAddIndices;
1656 this->zAxisOrigin -= zAddIndices;
1658 this->xFrom -= xAddIndices;
1659 this->yFrom -= yAddIndices;
1660 this->zFrom -= zAddIndices;
1662 this->xTo += xAddIndices;
1663 this->yTo += yAddIndices;
1664 this->zTo += zAddIndices;
1667 proshade_double* newMap =
new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1671 for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1677 proshade_unsign newMapIndex, oldMapIndex;
1678 for ( proshade_unsign xIt = 0; xIt < (this->xDimIndices - xAddIndices); xIt++ )
1681 if ( xIt < xAddIndices ) {
continue; }
1683 for ( proshade_unsign yIt = 0; yIt < (this->yDimIndices - yAddIndices); yIt++ )
1686 if ( yIt < yAddIndices ) {
continue; }
1688 for ( proshade_unsign zIt = 0; zIt < (this->zDimIndices - zAddIndices); zIt++ )
1691 if ( zIt < zAddIndices ) {
continue; }
1694 newMapIndex = zIt + this->zDimIndices * ( yIt + this->yDimIndices * xIt );
1695 oldMapIndex = (zIt - zAddIndices) + (this->zDimIndices - ( 2 * zAddIndices ) ) * ( (yIt - yAddIndices) + (this->yDimIndices - ( 2 * yAddIndices ) ) * (xIt - xAddIndices) );
1697 newMap[newMapIndex] = this->internalMap[oldMapIndex];
1703 delete[] this->internalMap;
1705 this->internalMap =
new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1708 for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1710 this->internalMap[iter] = newMap[iter];
1742 if ( !( ( std::isinf ( settings->
boxCentre.at(0) ) ) || ( std::isinf ( settings->
boxCentre.at(1) ) ) || ( std::isinf ( settings->
boxCentre.at(2) ) ) ) ) { this->shiftToBoxCentre ( settings ); }
1746 if ( !( ( std::isinf ( settings->
centrePosition.at(0) ) ) || ( std::isinf ( settings->
centrePosition.at(1) ) ) || ( std::isinf ( settings->
centrePosition.at(2) ) ) ) ) { this->shiftToRotationCentre ( settings ); }
1750 if ( settings->
invertMap ) { this->invertMirrorMap ( settings ); }
1754 if ( settings->
normaliseMap ) { this->normaliseMap ( settings ); }
1758 if ( settings->
maskMap ) { this->maskMap ( settings ); }
1762 if ( settings->
moveToCOM ) { this->centreMapOnCOM ( settings ); }
1770 if ( settings->
addExtraSpace != 0.0f ) { this->addExtraSpace ( settings ); }
1793 if ( this->spherePos.size() != 0 )
1795 std::stringstream hlpSS;
1796 hlpSS <<
"The sphere distances were determined as " << this->spherePos.at(0);
1797 for ( proshade_unsign iter = 1; iter < static_cast<proshade_unsign> ( this->spherePos.size() ); iter++ ) { hlpSS <<
"; " << this->spherePos.at(iter); }
1798 hlpSS <<
" Angstroms.";
1804 proshade_unsign maxDim =
static_cast< proshade_unsign
> ( std::max ( this->xDimSize, std::max ( this->yDimSize, this->zDimSize ) ) );
1805 proshade_unsign minDim =
static_cast< proshade_unsign
> ( std::min ( this->xDimSize, std::min ( this->yDimSize, this->zDimSize ) ) );
1806 proshade_unsign midDim =
static_cast< proshade_unsign
> ( 0 );
1807 if ( ( this->xDimSize <
static_cast< proshade_single
> ( maxDim ) ) && ( this->xDimSize >
static_cast< proshade_single
> ( minDim ) ) ) { midDim =
static_cast< proshade_unsign
> ( this->xDimSize ); }
1808 else if ( ( this->yDimSize <
static_cast< proshade_single
> ( maxDim ) ) && ( this->yDimSize >
static_cast< proshade_single
> ( minDim ) ) ) { midDim =
static_cast< proshade_unsign
> ( this->yDimSize ); }
1809 else { midDim =
static_cast< proshade_unsign
> ( this->zDimSize ); }
1811 proshade_single maxDiag =
static_cast< proshade_single
> ( std::sqrt ( std::pow (
static_cast<proshade_single
> ( maxDim ), 2.0 ) +
1812 std::pow (
static_cast<proshade_single
> ( midDim ), 2.0 ) ) );
1815 for ( proshade_single iter = 0.5f; ( iter * settings->
maxSphereDists ) < ( maxDiag / 2.0f ); iter += 1.0f )
1818 if ( ( settings->
maxRadius > 0.0 ) && ( settings->
maxRadius <
static_cast< proshade_double
> ( maxDiag ) ) && (
static_cast< proshade_double
> ( iter * settings->
maxSphereDists ) > settings->
maxRadius ) ) {
break; }
1825 this->noSpheres =
static_cast<proshade_unsign
> ( this->spherePos.size() );
1828 std::stringstream hlpSS;
1829 hlpSS <<
"The sphere distances were determined as " << this->spherePos.at(0);
1830 for ( proshade_unsign iter = 1; iter < static_cast<proshade_unsign> ( this->spherePos.size() ); iter++ ) { hlpSS <<
"; " << this->spherePos.at(iter); }
1831 hlpSS <<
" Angstroms.";
1858 this->xDimSize, this->yDimSize, this->zDimSize );
1862 this->getSpherePositions ( settings );
1867 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( this->spherePos.size() ); iter++ )
1869 std::stringstream ss;
1870 ss <<
"Now mapping sphere " << iter <<
" .";
1874 this->xDimSize, this->yDimSize, this->zDimSize, iter,
1876 this->internalMap, &this->maxShellBand, &this->maxEMatDim );
1901 this->sphericalHarmonics =
new proshade_complex* [this->noSpheres];
1903 for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
1905 this->sphericalHarmonics[iter] =
new proshade_complex [( this->spheres[iter]->getLocalAngRes() ) * ( this->spheres[iter]->getLocalAngRes() )];
1907 for (
size_t it = 0; it < ( ( this->spheres[iter]->getLocalAngRes() ) * ( this->spheres[iter]->getLocalAngRes() ) ); it++ ) { this->sphericalHarmonics[iter][it][0] = 0.0; this->sphericalHarmonics[iter][it][1] = 0.0; }
1911 for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
1914 std::stringstream ss;
1915 ss <<
"Now decomposing sphere " << iter <<
". " <<
"( Band is: " << this->spheres[iter]->getLocalBandwidth() <<
").";
1939 return ( a[6] > b[6] );
1957 if ( settings->axisErrToleranceDefault )
1959 settings->
axisErrTolerance = std::min ( std::max ( 0.01, ( ( 2.0 * M_PI ) /
static_cast< proshade_double
> ( this->maxShellBand ) ) / 2.0 ), 0.05 );
1963 fftw_complex* fCoeffsCut;
1964 proshade_double **bindata, *fscByBin;
1965 proshade_signed *cutIndices, *binCounts, noBins, cutXDim, cutYDim, cutZDim;
1966 this->prepareFSCFourierMemory ( cutIndices, fCoeffsCut, &noBins, bindata, binCounts, fscByBin, settings->
requestedResolution, &cutXDim, &cutYDim, &cutZDim );
1972 std::stringstream hlpSS;
1977 proshade_double symThres = 0.0;
1978 this->cyclicSymmetries = this->findRequestedCSymmetryFromAngleAxis ( settings, settings->
requestedSymmetryFold, &symThres );
1981 for (
size_t cIt = 0; cIt < this->cyclicSymmetries.size(); cIt++ )
1983 const FloatingPoint< proshade_double > lhs ( this->cyclicSymmetries.at(cIt)[5] ), rhs ( -999.9 );
1984 if ( ( this->cyclicSymmetries.at(cIt)[5] > settings->
peakThresholdMin ) || ( lhs.AlmostEquals ( rhs ) ) )
1986 this->
computeFSC ( settings, &this->cyclicSymmetries, cIt, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
1994 if ( this->cyclicSymmetries.size() > 0 )
1996 bool passedTests =
false;
1997 for (
size_t cIt = 0; cIt < this->cyclicSymmetries.size(); cIt++ )
1999 if ( this->cyclicSymmetries.at(0)[6] > settings->
fscThreshold )
2001 this->recommendedSymmetryType =
"C";
2004 proshade_double* hlpSym =
new proshade_double[7];
2006 for (
size_t iter = 0; iter < 7; iter++ ) { hlpSym[iter] = this->cyclicSymmetries.at(cIt)[iter]; }
2016 this->recommendedSymmetryType =
"C";
2017 this->recommendedSymmetryFold = 1;
2022 this->recommendedSymmetryType =
"C";
2023 this->recommendedSymmetryFold = 1;
2027 for (
size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) {
delete[] bindata[binIt]; }
2031 delete[] cutIndices;
2032 fftw_free ( fCoeffsCut );
2042 this->cyclicSymmetries = getCyclicSymmetriesListFromAngleAxis ( settings );
2045 std::stringstream ss;
2046 ss <<
"Detected " << this->cyclicSymmetries.size() <<
" C symmetries.";
2050 if ( this->sphereMappedRotFun.size() < 1 )
2052 throw ProSHADE_exception (
"Rotation function was not converted into angle-axis space.",
"ES00062", __FILE__, __LINE__, __func__,
"It seems that the convertRotationFunction() function was\n : not yet called. Therefore, there are no data to detect the\n : symmetry from; please call the convertRotationFunction()\n : function before the detectSymmetryFromAngleAxisSpace()\n : function." );
2059 this->getDihedralSymmetriesList ( settings, &this->cyclicSymmetries );
2063 for (
size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) {
delete[] bindata[binIt]; }
2067 delete[] cutIndices;
2068 fftw_free ( fCoeffsCut );
2077 throw ProSHADE_exception (
"Requested symmetry supplied, but not recognised.",
"ES00032", __FILE__, __LINE__, __func__,
"There are only the following value allowed for the\n : symmetry type request: \"C\", \"D\", \"T\", \"O\" and \"I\". Any\n : other value will result in this error." );
2084 this->determineRecommendedSymmetry ( settings, -2.0, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2090 this->getDihedralSymmetriesList ( settings, &this->cyclicSymmetries );
2091 this->saveRequestedSymmetryD ( settings, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2097 this->getPredictedTetrahedralSymmetriesList ( settings, &this->cyclicSymmetries, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2099 if ( this->tetrahedralSymmetries.size() == 7 )
2102 proshade_double fscVal = 0.0;
2103 proshade_double fscValAvg = 0.0;
2106 for (
size_t tIt = 0; tIt < this->tetrahedralSymmetries.size(); tIt++ ) {
if ( this->tetrahedralSymmetries.at(tIt)[5] > settings->
peakThresholdMin ) { fscVal = this->
computeFSC ( settings, &this->tetrahedralSymmetries.at(tIt)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); fscValAvg += fscVal; } }
2113 this->recommendedSymmetryType =
"T";
2114 this->recommendedSymmetryFold = 0;
2123 this->getPredictedOctahedralSymmetriesList ( settings, &this->cyclicSymmetries, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2125 if ( this->octahedralSymmetries.size() == 13 )
2128 proshade_double fscVal = 0.0;
2129 proshade_double fscValAvg = 0.0;
2132 for (
size_t oIt = 0; oIt < this->octahedralSymmetries.size(); oIt++ ) {
if ( this->octahedralSymmetries.at(oIt)[5] > settings->
peakThresholdMin ) { fscVal = this->
computeFSC ( settings, &this->octahedralSymmetries.at(oIt)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); fscValAvg += fscVal; } }
2139 this->recommendedSymmetryType =
"O";
2140 this->recommendedSymmetryFold = 0;
2149 this->getPredictedIcosahedralSymmetriesList ( settings, &this->cyclicSymmetries, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2151 if ( this->icosahedralSymmetries.size() == 31 )
2154 proshade_double fscVal = 0.0;
2155 proshade_double fscValAvg = 0.0;
2158 for (
size_t iIt = 0; iIt < this->icosahedralSymmetries.size(); iIt++ ) {
if ( this->icosahedralSymmetries.at(iIt)[5] > settings->
peakThresholdMin ) { fscVal = this->
computeFSC ( settings, &this->icosahedralSymmetries.at(iIt)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); fscValAvg += fscVal; } }
2165 this->recommendedSymmetryType =
"I";
2166 this->recommendedSymmetryFold = 0;
2173 for (
size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) {
delete[] bindata[binIt]; }
2176 delete[] cutIndices;
2177 fftw_free ( fCoeffsCut );
2202 void ProSHADE_internal_data::ProSHADE_data::prepareFSCFourierMemory ( proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed* noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_single resolution, proshade_signed* cutXDim, proshade_signed* cutYDim, proshade_signed* cutZDim )
2205 std::vector< proshade_single > *resArray;
2206 proshade_signed* binIndexing =
nullptr;
2214 cutXDim, cutYDim, cutZDim,
2219 delete[] binIndexing;
2222 bindata =
new proshade_double*[*noBins];
2223 binCounts =
new proshade_signed [*noBins];
2224 fscByBin =
new proshade_double [*noBins];
2225 fftw_complex* mapData =
reinterpret_cast< fftw_complex*
> ( fftw_malloc (
sizeof ( fftw_complex ) * this->xDimIndices * this->yDimIndices * this->zDimIndices ) );
2226 fftw_complex* fCoeffs =
reinterpret_cast< fftw_complex*
> ( fftw_malloc (
sizeof ( fftw_complex ) * this->xDimIndices * this->yDimIndices * this->zDimIndices ) );
2227 fCoeffsCut =
reinterpret_cast< fftw_complex*
> ( fftw_malloc (
sizeof ( fftw_complex ) *
static_cast< proshade_unsign
> ( (*cutXDim) * (*cutYDim) * (*cutZDim) ) ) );
2238 for (
size_t binIt = 0; binIt < static_cast< size_t > ( *noBins ); binIt++ )
2240 bindata[binIt] =
new proshade_double[12];
2245 for (
size_t binIt = 0; binIt < static_cast< size_t > ( *noBins ); binIt++ ) {
for (
size_t it = 0; it < 12; it++ ) { bindata[binIt][it] = 0.0; } }
2246 for (
size_t binIt = 0; binIt < static_cast< size_t > ( *noBins ); binIt++ ) { binCounts[binIt] = 0; fscByBin[binIt] = 0.0; }
2247 for (
size_t mapIt = 0; mapIt < static_cast< size_t > ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); mapIt++ ) { mapData[mapIt][0] = 0.0; mapData[mapIt][1] = 0.0; fCoeffs[mapIt][0] = 0.0; fCoeffs[mapIt][1] = 0.0; }
2248 for (
size_t mapIt = 0; mapIt < static_cast< size_t > ( (*cutXDim) * (*cutYDim) * (*cutZDim) ); mapIt++ ) { fCoeffsCut[mapIt][0] = 0.0; fCoeffsCut[mapIt][1] = 0.0; }
2251 fftw_plan planForwardFourier = fftw_plan_dft_3d (
static_cast< int > ( this->xDimIndices ),
static_cast< int > ( this->yDimIndices ),
static_cast< int > ( this->zDimIndices ), mapData, fCoeffs, FFTW_FORWARD, FFTW_ESTIMATE );
2254 for (
size_t iter = 0; iter < static_cast< size_t > ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ ) { mapData[iter][0] = this->internalMap[iter]; mapData[iter][1] = 0.0; }
2255 ProSHADE_internal_mapManip::changeFourierOrder ( mapData,
static_cast< proshade_signed
> ( this->xDimIndices ),
static_cast< proshade_signed
> ( this->yDimIndices ),
static_cast< proshade_signed
> ( this->zDimIndices ),
true );
2256 fftw_execute ( planForwardFourier );
2257 ProSHADE_internal_mapManip::changeFourierOrder ( fCoeffs,
static_cast< proshade_signed
> ( this->xDimIndices ),
static_cast< proshade_signed
> ( this->yDimIndices ),
static_cast< proshade_signed
> ( this->zDimIndices ),
true );
2260 ProSHADE_internal_maths::cutArrayToResolution (
static_cast< proshade_signed
> ( this->xDimIndices ),
static_cast< proshade_signed
> ( this->yDimIndices ),
static_cast< proshade_signed
> ( this->zDimIndices ), *noBins, fCoeffs, fCoeffsCut );
2263 proshade_unsign arrPos = 0;
2264 for ( proshade_unsign xIt = 0; xIt < static_cast< proshade_unsign > ( *cutXDim ); xIt++ )
2266 for ( proshade_unsign yIt = 0; yIt < static_cast< proshade_unsign > ( *cutYDim ); yIt++ )
2268 for ( proshade_unsign zIt = 0; zIt < static_cast< proshade_unsign > ( *cutZDim ); zIt++ )
2270 arrPos = zIt +
static_cast< proshade_unsign
> ( *cutZDim ) * ( yIt +
static_cast< proshade_unsign
> ( *cutYDim ) * xIt );
2271 if ( ( cutIndices[arrPos] < 0 ) || ( cutIndices[arrPos] > (*noBins) ) ) { fCoeffsCut[arrPos][0] = 0.0; fCoeffsCut[arrPos][1] = 0.0; }
2277 fftw_destroy_plan ( planForwardFourier );
2278 fftw_free ( mapData );
2279 fftw_free ( fCoeffs );
2312 proshade_double
ProSHADE_internal_data::ProSHADE_data::computeFSC (
ProSHADE_settings* settings, std::vector< proshade_double* >* CSym,
size_t symIndex, proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim, proshade_unsign rotNumber )
2315 if ( symIndex >= CSym->size() )
2317 std::cerr <<
"The supplied symmetry axes vector does not contain element number " << symIndex <<
". Returning FSC 0.0." << std::endl;
2322 if ( CSym->at(symIndex)[6] > -2.0 ) {
return ( CSym->at(symIndex)[6] ); }
2325 std::stringstream ss2;
2326 ss2 <<
"Computing FSC for symmetry C" << CSym->at(symIndex)[0] <<
" ( " << CSym->at(symIndex)[1] <<
" ; " << CSym->at(symIndex)[2] <<
" ; " << CSym->at(symIndex)[3] <<
" ) with peak height " << CSym->at(symIndex)[5];
2330 fftw_complex *rotCoeffs;
2331 proshade_double averageFSC = 0.0;
2334 if ( rotNumber == 0 )
2336 for ( proshade_unsign rotIndex = 1; rotIndex < static_cast< proshade_unsign > ( CSym->at(symIndex)[0] ); rotIndex++ )
2339 this->rotateFourierCoeffs ( CSym->at(symIndex)[1], CSym->at(symIndex)[2], CSym->at(symIndex)[3], ( ( 2.0 * M_PI ) / CSym->at(symIndex)[0] ) *
static_cast< proshade_double
> ( rotIndex ), fCoeffsCut, rotCoeffs, xDim, yDim, zDim );
2345 fftw_free ( rotCoeffs );
2349 averageFSC /= ( CSym->at(symIndex)[0] - 1.0 );
2354 this->rotateFourierCoeffs ( CSym->at(symIndex)[1], CSym->at(symIndex)[2], CSym->at(symIndex)[3], ( ( 2.0 * M_PI ) / CSym->at(symIndex)[0] ) *
static_cast< proshade_double
> ( rotNumber ), fCoeffsCut, rotCoeffs, xDim, yDim, zDim );
2360 fftw_free ( rotCoeffs );
2364 CSym->at(symIndex)[6] = averageFSC;
2367 std::stringstream ss3;
2368 if ( rotNumber != 0 )
2370 ss3 <<
"FSC value for structure rotated by " << ( ( 2.0 * M_PI ) / CSym->at(symIndex)[0] ) *
static_cast< proshade_double
> ( rotNumber ) <<
" radians is " << averageFSC <<
" .";
2374 ss3 <<
"FSC value averaged over all " <<
static_cast< proshade_unsign
> ( CSym->at(symIndex)[0] - 1 ) <<
" rotations is " << averageFSC <<
" .";
2379 return ( averageFSC );
2408 proshade_double
ProSHADE_internal_data::ProSHADE_data::computeFSC (
ProSHADE_settings* settings, proshade_double* sym, proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim, proshade_unsign rotNumber )
2411 if ( sym[6] > -2.0 ) {
return ( sym[6] ); }
2414 std::stringstream ss2;
2415 ss2 <<
"Computing FSC for symmetry C" << sym[0] <<
" ( " << sym[1] <<
" ; " << sym[2] <<
" ; " << sym[3] <<
" ) with peak height " << sym[5];
2419 fftw_complex *rotCoeffs;
2420 proshade_double averageFSC = 0.0;
2423 if ( rotNumber == 0 )
2425 for ( proshade_unsign rotIndex = 1; rotIndex < static_cast< proshade_unsign > ( sym[0] ); rotIndex++ )
2428 this->rotateFourierCoeffs ( sym[1], sym[2], sym[3], ( ( 2.0 * M_PI ) / sym[0] ) *
static_cast< proshade_double
> ( rotIndex ), fCoeffsCut, rotCoeffs, xDim, yDim, zDim );
2434 fftw_free ( rotCoeffs );
2438 averageFSC /= ( sym[0] - 1.0 );
2443 this->rotateFourierCoeffs ( sym[1], sym[2], sym[3], ( ( 2.0 * M_PI ) / sym[0] ) *
static_cast< proshade_double
> ( rotNumber ), fCoeffsCut, rotCoeffs, xDim, yDim, zDim );
2449 fftw_free ( rotCoeffs );
2453 sym[6] = averageFSC;
2456 std::stringstream ss3;
2457 if ( rotNumber != 0 )
2459 ss3 <<
"FSC value for structure rotated by " << ( ( 2.0 * M_PI ) / sym[0] ) *
static_cast< proshade_double
> ( rotNumber ) <<
" radians is " << averageFSC <<
" .";
2463 ss3 <<
"FSC value averaged over all " <<
static_cast< proshade_unsign
> ( sym[0] - 1 ) <<
" rotations is " << averageFSC <<
" .";
2468 return ( averageFSC );
2502 void ProSHADE_internal_data::ProSHADE_data::determineRecommendedSymmetry (
ProSHADE_settings* settings, proshade_double threshold, proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_signed cutXDim, proshade_signed cutYDim, proshade_signed cutZDim )
2508 if ( this->cyclicSymmetries.size() == 0 )
2510 this->recommendedSymmetryType =
"C";
2511 this->recommendedSymmetryFold = 1;
2516 if ( threshold < -1.0 ) { threshold = settings->
fscThreshold; }
2519 this->recommendedSymmetryType =
"C";
2520 this->recommendedSymmetryFold = 1;
2521 for (
size_t it = 0; it < this->recommendedSymmetryValues.size(); it++ ) {
if ( this->recommendedSymmetryValues.at(it) !=
nullptr ) {
delete[] this->recommendedSymmetryValues.at(it); this->recommendedSymmetryValues.at(it) =
nullptr; } }
2522 this->recommendedSymmetryValues.clear ( );
2525 std::vector< proshade_double* > thresholdedCs;
2529 this->getDihedralSymmetriesList ( settings, &thresholdedCs );
2530 this->getPredictedTetrahedralSymmetriesList ( settings, &thresholdedCs, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2531 this->getPredictedOctahedralSymmetriesList ( settings, &thresholdedCs, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2532 this->getPredictedIcosahedralSymmetriesList ( settings, &thresholdedCs, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2535 proshade_double step = 0.01;
2536 proshade_double sigma = 0.3;
2537 proshade_signed windowSize = 9;
2538 proshade_double IFSCAverage = 0.0, OFSCAverage = 0.0, TFSCAverage = 0.0;
2539 bool IIsBest =
false, OIsBest =
false, TIsBest =
false;
2546 proshade_unsign noPassed = 0;
for (
size_t cIt = 0; cIt < thresholdedCs.size(); cIt++ ) {
if ( thresholdedCs.at(cIt)[5] > bestHistPeakStart ) { noPassed += 1; } }
2547 std::stringstream ss;
2548 ss <<
"Smoothening has resolved in " << noPassed <<
" C symmetries.";
2553 bool alreadyDecided =
false;
2554 if ( this->icosahedralSymmetries.size() == 31 )
2557 proshade_double fscVal = 0.0;
2558 proshade_double fscValAvg = 0.0;
2559 proshade_unsign lowFSC = 0;
2562 for (
size_t iIt = 0; iIt < this->icosahedralSymmetries.size(); iIt++ ) {
if ( !std::isinf ( this->icosahedralSymmetries.at(iIt)[6] ) ) { fscVal = this->icosahedralSymmetries.at(iIt)[6]; }
else { fscVal = this->
computeFSC ( settings, &this->icosahedralSymmetries.at(iIt)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); } fscValAvg += fscVal;
if ( fscVal < threshold ) { lowFSC++; } }
2564 IFSCAverage = fscValAvg;
2565 if ( ( IFSCAverage < threshold ) || ( lowFSC > 10 ) ) { IFSCAverage = 0.0; }
2569 if ( ( this->octahedralSymmetries.size() == 13 ) && !alreadyDecided )
2572 proshade_double fscVal = 0.0;
2573 proshade_double fscValAvg = 0.0;
2574 proshade_unsign lowFSC = 0;
2577 for (
size_t oIt = 0; oIt < this->octahedralSymmetries.size(); oIt++ ) {
if ( !std::isinf ( this->octahedralSymmetries.at(oIt)[6] ) ) { fscVal = this->octahedralSymmetries.at(oIt)[6]; }
else { fscVal = this->
computeFSC ( settings, &this->octahedralSymmetries.at(oIt)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); } fscValAvg += fscVal;
if ( fscVal < threshold ) { lowFSC++; } }
2579 OFSCAverage = fscValAvg;
2580 if ( ( OFSCAverage < threshold ) || ( lowFSC > 5 ) ) { OFSCAverage = 0.0; }
2584 if ( ( this->tetrahedralSymmetries.size() == 7 ) && !alreadyDecided )
2587 proshade_double fscVal = 0.0;
2588 proshade_double fscValAvg = 0.0;
2589 proshade_unsign lowFSC = 0;
2592 for (
size_t tIt = 0; tIt < this->tetrahedralSymmetries.size(); tIt++ ) {
if ( !std::isinf ( this->tetrahedralSymmetries.at(tIt)[6] ) ) { fscVal = this->tetrahedralSymmetries.at(tIt)[6]; }
else { fscVal = this->
computeFSC ( settings, &this->tetrahedralSymmetries.at(tIt)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); } fscValAvg += fscVal;
if ( fscVal < threshold ) { lowFSC++; } }
2594 TFSCAverage = fscValAvg;
2595 if ( ( TFSCAverage < threshold ) || ( lowFSC > 2 ) ) { TFSCAverage = 0.0; }
2599 proshade_double newThres = threshold;
2602 proshade_double phaselessStep = 0.01;
2603 proshade_double phaselessSigma = 0.005;
2604 proshade_signed phaselessWSize = 5;
2609 if ( ( IFSCAverage > std::max( OFSCAverage * 0.9, TFSCAverage * 0.7 ) ) && ( IFSCAverage > newThres ) ) { IIsBest =
true; }
2610 if ( ( OFSCAverage > std::max( IFSCAverage * 1.2, TFSCAverage * 0.7 ) ) && ( OFSCAverage > newThres ) ) { OIsBest =
true; }
2611 if ( ( TFSCAverage > std::max( IFSCAverage * 1.2, OFSCAverage * 1.1 ) ) && ( TFSCAverage > newThres ) ) { TIsBest =
true; }
2612 if ( !IIsBest && !OIsBest && !TIsBest && ( std::max( IFSCAverage, std::max( OFSCAverage, TFSCAverage ) ) > newThres ) )
2614 const FloatingPoint< proshade_double > lhsPolyI ( IFSCAverage ), lhsPolyO ( OFSCAverage ), lhsPolyT ( TFSCAverage ), rhsPolyMax ( std::max( IFSCAverage, std::max( OFSCAverage, TFSCAverage ) ) );
2615 if ( lhsPolyI.AlmostEquals( rhsPolyMax ) ) { IIsBest =
true; }
2616 if ( lhsPolyO.AlmostEquals( rhsPolyMax ) ) { OIsBest =
true; }
2617 if ( lhsPolyT.AlmostEquals( rhsPolyMax ) ) { TIsBest =
true; }
2624 this->recommendedSymmetryType =
"I";
2625 this->recommendedSymmetryFold = 0;
2629 alreadyDecided =
true;
2633 if ( OIsBest && !alreadyDecided )
2636 this->recommendedSymmetryType =
"O";
2637 this->recommendedSymmetryFold = 0;
2641 alreadyDecided =
true;
2645 if ( TIsBest && !alreadyDecided )
2648 this->recommendedSymmetryType =
"T";
2649 this->recommendedSymmetryFold = 0;
2653 alreadyDecided =
true;
2657 proshade_signed bestD = -1;
2658 if ( ( this->dihedralSymmetries.size() > 0 ) && !alreadyDecided )
2661 proshade_unsign bestFold = 0;
2662 proshade_double bestValFSC = -std::numeric_limits < proshade_double >::infinity();
2663 proshade_double bestValPeak = -std::numeric_limits < proshade_double >::infinity();
2666 for (
size_t dIt = 0; dIt < this->dihedralSymmetries.size(); dIt++ )
2669 const FloatingPoint< proshade_double > lhs999a ( this->dihedralSymmetries.at(dIt).at(0)[5] ), lhs999b ( this->dihedralSymmetries.at(dIt).at(1)[5] ), rhs999 (
static_cast< proshade_double
> ( -999.9 ) );
2670 if ( ( this->dihedralSymmetries.at(dIt).at(0)[5] < bestHistPeakStart ) && !( lhs999a.AlmostEquals( rhs999 ) ) ) {
continue; }
2671 if ( ( this->dihedralSymmetries.at(dIt).at(1)[5] < bestHistPeakStart ) && !( lhs999b.AlmostEquals( rhs999 ) ) ) {
continue; }
2674 if ( std::isinf ( this->dihedralSymmetries.at(dIt).at(0)[6] ) ) { this->
computeFSC ( settings, &this->dihedralSymmetries.at(dIt).at(0)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); }
2675 if ( std::isinf ( this->dihedralSymmetries.at(dIt).at(1)[6] ) ) { this->
computeFSC ( settings, &this->dihedralSymmetries.at(dIt).at(1)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); }
2679 std::vector< proshade_double* > smootheningHlp;
2680 for (
size_t dIt = 0; dIt < this->dihedralSymmetries.size(); dIt++ )
2683 if ( this->dihedralSymmetries.at(dIt).at(0)[6] < threshold ) {
continue; }
2684 if ( this->dihedralSymmetries.at(dIt).at(1)[6] < threshold ) {
continue; }
2687 proshade_double* sym =
new proshade_double[7];
2690 sym[0] = 0.0; sym[1] = 0.0; sym[2] = 0.0; sym[3] = 0.0; sym[4] = 0.0;
2691 sym[5] = ( this->dihedralSymmetries.at(dIt).at(0)[5] + this->dihedralSymmetries.at(dIt).at(1)[5] ) / 2.0;
2692 sym[6] = ( this->dihedralSymmetries.at(dIt).at(0)[6] + this->dihedralSymmetries.at(dIt).at(1)[6] ) / 2.0;
2706 for (
size_t axIt = 0; axIt < smootheningHlp.size(); axIt++ ) {
if ( smootheningHlp.at(axIt) !=
nullptr ) {
delete[] smootheningHlp.at(axIt); } }
2709 for (
size_t dIt = 0; dIt < this->dihedralSymmetries.size(); dIt++ )
2712 if ( this->dihedralSymmetries.at(dIt).at(0)[6] < threshold ) {
continue; }
2713 if ( this->dihedralSymmetries.at(dIt).at(1)[6] < threshold ) {
continue; }
2716 const FloatingPoint< proshade_double > lhs999a2 ( this->dihedralSymmetries.at(dIt).at(0)[5] ), lhs999b2 ( this->dihedralSymmetries.at(dIt).at(1)[5] ), rhs999 (
static_cast< proshade_double
> ( -999.9 ) );
2717 if ( ( this->dihedralSymmetries.at(dIt).at(0)[5] < bestHistPeakStart ) && !( lhs999a2.AlmostEquals( rhs999 ) ) ) {
continue; }
2718 if ( ( this->dihedralSymmetries.at(dIt).at(1)[5] < bestHistPeakStart ) && !( lhs999b2.AlmostEquals( rhs999 ) ) ) {
continue; }
2719 if ( std::min ( this->dihedralSymmetries.at(dIt).at(0)[5], this->dihedralSymmetries.at(dIt).at(1)[5] ) < ( std::max ( settings->
peakThresholdMin, onlyDPeakThreshold ) * 0.90 ) ) {
continue; }
2722 if ( ( this->dihedralSymmetries.at(dIt).at(0)[0] >
static_cast< proshade_double
> ( bestFold ) ) ||
2723 ( this->dihedralSymmetries.at(dIt).at(1)[0] >
static_cast< proshade_double
> ( bestFold ) ) )
2726 if ( ( this->dihedralSymmetries.at(dIt).at(0)[6] < std::max ( threshold, onlyDFSCThreshold ) ) &&
2727 ( this->dihedralSymmetries.at(dIt).at(1)[6] < std::max ( threshold, onlyDFSCThreshold ) ) ) {
continue; }
2728 if ( std::min ( this->dihedralSymmetries.at(dIt).at(0)[6], this->dihedralSymmetries.at(dIt).at(1)[6] ) < ( std::max ( threshold, onlyDFSCThreshold ) * 0.70 ) ) {
continue; }
2731 bestValPeak = ( ( this->dihedralSymmetries.at(dIt).at(0)[5] + this->dihedralSymmetries.at(dIt).at(1)[5] ) / 2.0 );
2732 bestValFSC = ( ( this->dihedralSymmetries.at(dIt).at(0)[6] + this->dihedralSymmetries.at(dIt).at(1)[6] ) / 2.0 );
2733 bestFold =
static_cast< proshade_unsign
> ( std::max ( this->dihedralSymmetries.at(dIt).at(0)[0], this->dihedralSymmetries.at(dIt).at(1)[0] ) );
2734 bestD =
static_cast< proshade_signed
> ( dIt );
2739 const FloatingPoint< proshade_double > lhs1 ( this->dihedralSymmetries.at(dIt).at(0)[0] ), lhs2 ( this->dihedralSymmetries.at(dIt).at(1)[0] ), rhs (
static_cast< proshade_double
> ( bestFold ) );
2740 if ( ( ( ( this->dihedralSymmetries.at(dIt).at(0)[6] + this->dihedralSymmetries.at(dIt).at(1)[6] ) / 2.0 ) > ( bestValFSC * 1.00 ) ) &&
2741 ( ( ( this->dihedralSymmetries.at(dIt).at(0)[5] + this->dihedralSymmetries.at(dIt).at(1)[5] ) / 2.0 ) > ( bestValPeak * 0.95 ) ) &&
2742 ( ( lhs1.AlmostEquals ( rhs ) ) || ( lhs2.AlmostEquals ( rhs ) ) ) )
2744 bestValPeak = ( ( this->dihedralSymmetries.at(dIt).at(0)[5] + this->dihedralSymmetries.at(dIt).at(1)[5] ) / 2.0 );
2745 bestValFSC = ( ( this->dihedralSymmetries.at(dIt).at(0)[6] + this->dihedralSymmetries.at(dIt).at(1)[6] ) / 2.0 );
2746 bestFold =
static_cast< proshade_unsign
> ( std::max ( this->dihedralSymmetries.at(dIt).at(0)[0], this->dihedralSymmetries.at(dIt).at(1)[0] ) );
2747 bestD =
static_cast< proshade_signed
> ( dIt );
2756 this->recommendedSymmetryType =
"D";
2757 this->recommendedSymmetryFold =
static_cast< proshade_unsign
> ( std::max ( this->dihedralSymmetries.at(
static_cast< size_t> ( bestD ) ).at(0)[0], this->dihedralSymmetries.at(
static_cast< size_t> ( bestD ) ).at(0)[1] ) );
2764 if ( ( this->cyclicSymmetries.size() > 0 ) && !alreadyDecided )
2767 proshade_signed bestC = -1;
2768 proshade_unsign bestFold = 0;
2771 for (
size_t cIt = 0; cIt < this->cyclicSymmetries.size(); cIt++ )
2774 if ( ( cIt > 20 ) && ( this->cyclicSymmetries.at(cIt)[5] < 0.95 ) ) {
break; }
2777 if ( this->cyclicSymmetries.at(cIt)[5] < bestHistPeakStart ) {
continue; }
2780 if ( std::isinf ( this->cyclicSymmetries.at(cIt)[6] ) ) { this->
computeFSC ( settings, &this->cyclicSymmetries.at(cIt)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); }
2785 if (
static_cast< proshade_signed
> ( threshold * 100.0 ) >
static_cast< proshade_signed
> ( settings->
fscThreshold * 100.0 ) ) { bestHistFSCStart = threshold; }
2788 for (
size_t cIt = 0; cIt < this->cyclicSymmetries.size(); cIt++ )
2791 if ( this->cyclicSymmetries.at(cIt)[0] >
static_cast< proshade_double
> ( bestFold ) )
2794 if ( this->cyclicSymmetries.at(cIt)[6] > std::max ( bestHistFSCStart, threshold ) )
2796 bestFold =
static_cast< proshade_unsign
> ( this->cyclicSymmetries.at(cIt)[0] );
2797 bestC =
static_cast< proshade_signed
> ( cIt );
2803 if ( ( bestC != -1 ) && ( this->recommendedSymmetryType ==
"D" ) )
2806 if ( ( ( this->cyclicSymmetries.at(
static_cast< size_t > ( bestC ) )[6] * 0.80 ) > std::min ( this->dihedralSymmetries.at(
static_cast< size_t > ( bestD ) ).at(0)[6], this->dihedralSymmetries.at(
static_cast< size_t > ( bestD ) ).at(1)[6] ) ) &&
2807 ( ( this->cyclicSymmetries.at(
static_cast< size_t > ( bestC ) )[5] * 0.95 ) > std::min ( this->dihedralSymmetries.at(
static_cast< size_t > ( bestD ) ).at(0)[5], this->dihedralSymmetries.at(
static_cast< size_t > ( bestD ) ).at(1)[5] ) ) )
2809 this->recommendedSymmetryType =
"C";
2810 this->recommendedSymmetryFold = 1;
2811 for (
size_t iter = 0; iter < this->recommendedSymmetryValues.size(); iter++ ) {
if ( this->recommendedSymmetryValues.at(iter) != nullptr ) {
delete[] this->recommendedSymmetryValues.at(iter); this->recommendedSymmetryValues.at(iter) =
nullptr; } }
2812 this->recommendedSymmetryValues.clear ( );
2815 if ( ( bestC != -1 ) && ( this->recommendedSymmetryType !=
"D" ) )
2818 this->recommendedSymmetryType =
"C";
2819 this->recommendedSymmetryFold =
static_cast< proshade_unsign
> ( this->cyclicSymmetries.at(
static_cast< size_t > ( bestC ) )[0] );
2823 alreadyDecided =
true;
2828 for (
size_t iter = 0; iter < thresholdedCs.size(); iter++ ) {
if ( thresholdedCs.at(iter) !=
nullptr ) {
delete[] thresholdedCs.at(iter); } }
2856 proshade_unsign bestIndex = 0;
2857 proshade_double highestSym = 0.0;
2860 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( this->dihedralSymmetries.size() ); iter++ )
2863 const FloatingPoint< proshade_double > lhs1 ( std::max ( this->dihedralSymmetries.at(iter).at(0)[0], this->dihedralSymmetries.at(iter).at(1)[0] ) ), rhs1 (
static_cast< proshade_double
> ( settings->
requestedSymmetryFold ) );
2864 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
2867 const FloatingPoint< proshade_double > lhs999a ( this->dihedralSymmetries.at(iter).at(0)[5] ), lhs999b ( this->dihedralSymmetries.at(iter).at(1)[5] ), rhs999 (
static_cast< proshade_double
> ( -999.9 ) );
2868 if ( ( this->dihedralSymmetries.at(iter).at(0)[5] < settings->
peakThresholdMin ) && !( lhs999a.AlmostEquals( rhs999 ) ) ) {
continue; }
2869 if ( ( this->dihedralSymmetries.at(iter).at(1)[5] < settings->
peakThresholdMin ) && !( lhs999b.AlmostEquals( rhs999 ) ) ) {
continue; }
2872 this->
computeFSC ( settings, &this->dihedralSymmetries.at(iter).at(0)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, xDim, yDim, zDim );
2873 this->
computeFSC ( settings, &this->dihedralSymmetries.at(iter).at(1)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, xDim, yDim, zDim );
2876 if ( ( this->dihedralSymmetries.at(iter).at(0)[6] + this->dihedralSymmetries.at(iter).at(1)[6] ) > highestSym )
2878 highestSym = ( this->dihedralSymmetries.at(iter).at(0)[6] + this->dihedralSymmetries.at(iter).at(1)[6] );
2884 if ( highestSym > 0.0 )
2886 this->recommendedSymmetryType =
"D";
2887 this->recommendedSymmetryFold =
static_cast< proshade_unsign
> ( std::max ( this->dihedralSymmetries.at(bestIndex).at(0)[0], this->dihedralSymmetries.at(bestIndex).at(1)[0] ) );
2894 this->recommendedSymmetryType =
"C";
2895 this->recommendedSymmetryFold = 1;
2914 std::vector< proshade_double > angList;
2915 std::vector<std::vector< proshade_double > > ret;
2918 proshade_double* rotMat =
new proshade_double[9];
2923 proshade_double normF = std::sqrt( std::pow ( xAx, 2.0 ) + std::pow ( yAx, 2.0 ) + std::pow ( zAx, 2.0 ) );
2929 if ( fold % 2 == 0 )
2932 for ( proshade_double iter =
static_cast < proshade_double
> ( -( ( fold / 2 ) - 1 ) ); iter <= static_cast < proshade_double > ( fold / 2 ); iter++ )
2940 for ( proshade_double iter =
static_cast < proshade_double
> ( -fold / 2 ); iter <= static_cast < proshade_double > ( fold / 2 ); iter++ )
2947 for ( proshade_unsign iter = 0; iter < static_cast < proshade_unsign > ( angList.size() ); iter++ )
2953 std::vector < proshade_double > retEl;
2954 for ( proshade_unsign matIt = 0; matIt < 9; matIt++ )
2978 if ( obtainedAxes != requiredAxes )
2980 std::stringstream hlpSS;
2981 hlpSS <<
"The supplied number of axes for group element\n : detection ( >" << obtainedAxes <<
"< ) does not match the group type ( >" << groupType <<
"< ).";
2982 throw ProSHADE_exception (
"Mismatch between supplied number of axes and\n : symmetry type.",
"ES00059", __FILE__, __LINE__, __func__, hlpSS.str() );
2997 bool checkElementAlreadyExists ( std::vector<std::vector< proshade_double > >* elements, std::vector< proshade_double >* elem, proshade_double matrixTolerance )
3000 bool elementFound =
false;
3003 for ( proshade_unsign elIt = 0; elIt < static_cast<proshade_unsign> ( elements->size() ); elIt++ )
3007 elementFound =
true;
3013 return ( elementFound );
3026 bool isGroup =
true;
3029 for ( proshade_unsign gr1 = 0; gr1 < static_cast<proshade_unsign> ( elements->size() ); gr1++ )
3031 for ( proshade_unsign gr2 = 1; gr2 < static_cast<proshade_unsign> ( elements->size() ); gr2++ )
3034 if ( gr1 >= gr2 ) {
continue; }
3048 if ( !isGroup ) {
break; }
3067 std::vector< std::vector< proshade_double > > ret;
3070 for ( proshade_unsign elIt = 0; elIt < static_cast<proshade_unsign> ( first->size() ); elIt++ )
3079 for ( proshade_unsign elIt = 0; elIt < static_cast<proshade_unsign> ( second->size() ); elIt++ )
3090 for ( proshade_unsign gr1 = 0; gr1 < static_cast<proshade_unsign> ( first->size() ); gr1++ )
3092 for ( proshade_unsign gr2 = 0; gr2 < static_cast<proshade_unsign> ( second->size() ); gr2++ )
3125 std::vector< std::vector< proshade_double > > hlpVec;
3126 std::vector< proshade_double > hlpVec2;
3127 for (
size_t it1 = 0; it1 < this->cyclicSymmetries.size(); it1++ )
3130 for (
size_t it2 = 0; it2 < 7; it2++ )
3138 std::vector< std::vector< proshade_double > > ret = this->getAllGroupElements ( &hlpVec, axesList, groupType, matrixTolerance );
3166 std::vector<std::vector< proshade_double > > ret;
3169 if ( groupType ==
"C" )
3176 allCs->at(axesList.at(0)).at(2),
3177 allCs->at(axesList.at(0)).at(3),
3178 static_cast< proshade_signed
> ( allCs->at(axesList.at(0)).at(0) ) );
3184 throw ProSHADE_exception (
"Computed point group elements do not form a group.",
"ES00060", __FILE__, __LINE__, __func__,
"The supplied cyclic groups list does not form a group and\n : therefore such group's elements cannot be obtained. Please\n : check the cyclic groups list supplied to the\n : getAllGroupElements() function." );
3187 else if ( groupType ==
"D" )
3194 allCs->at(axesList.at(0)).at(2),
3195 allCs->at(axesList.at(0)).at(3),
3196 static_cast< proshade_signed
> ( allCs->at(axesList.at(0)).at(0) ) );
3199 allCs->at(axesList.at(1)).at(2),
3200 allCs->at(axesList.at(1)).at(3),
3201 static_cast< proshade_signed
> ( allCs->at(axesList.at(1)).at(0) ) );
3210 throw ProSHADE_exception (
"Computed point group elements do not form a group.",
"ES00060", __FILE__, __LINE__, __func__,
"The supplied cyclic groups list does not form a group and\n : therefore such group's elements cannot be obtained. Please\n : check the cyclic groups list supplied to the\n : getAllGroupElements() function." );
3213 else if ( groupType ==
"T" )
3219 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3222 const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 3.0 );
3223 if ( lhs1.AlmostEquals ( rhs1 ) )
3227 allCs->at(axesList.at(grIt)).at(2),
3228 allCs->at(axesList.at(grIt)).at(3),
3229 static_cast< proshade_signed
> ( allCs->at(axesList.at(grIt)).at(0) ) );
3237 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3240 const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 2.0 );
3241 if ( lhs1.AlmostEquals ( rhs1 ) )
3245 allCs->at(axesList.at(grIt)).at(2),
3246 allCs->at(axesList.at(grIt)).at(3),
3247 static_cast< proshade_signed
> ( allCs->at(axesList.at(grIt)).at(0) ) );
3258 throw ProSHADE_exception (
"Computed point group elements do not form a group.",
"ES00060", __FILE__, __LINE__, __func__,
"The supplied cyclic groups list does not form a group and\n : therefore such group's elements cannot be obtained. Please\n : check the cyclic groups list supplied to the\n : getAllGroupElements() function." );
3261 else if ( groupType ==
"O" )
3267 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3270 const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 4.0 );
3271 if ( lhs1.AlmostEquals ( rhs1 ) )
3275 allCs->at(axesList.at(grIt)).at(2),
3276 allCs->at(axesList.at(grIt)).at(3),
3277 static_cast< proshade_signed
> ( allCs->at(axesList.at(grIt)).at(0) ) );
3285 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3288 const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 3.0 );
3289 if ( lhs1.AlmostEquals ( rhs1 ) )
3293 allCs->at(axesList.at(grIt)).at(2),
3294 allCs->at(axesList.at(grIt)).at(3),
3295 static_cast< proshade_signed
> ( allCs->at(axesList.at(grIt)).at(0) ) );
3303 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3306 const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 2.0 );
3307 if ( lhs1.AlmostEquals ( rhs1 ) )
3311 allCs->at(axesList.at(grIt)).at(2),
3312 allCs->at(axesList.at(grIt)).at(3),
3313 static_cast< proshade_signed
> ( allCs->at(axesList.at(grIt)).at(0) ) );
3324 throw ProSHADE_exception (
"Computed point group elements do not form a group.",
"ES00060", __FILE__, __LINE__, __func__,
"The supplied cyclic groups list does not form a group and\n : therefore such group's elements cannot be obtained. Please\n : check the cyclic groups list supplied to the\n : getAllGroupElements() function." );
3327 else if ( groupType ==
"I" )
3333 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3336 const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 5.0 );
3337 if ( lhs1.AlmostEquals ( rhs1 ) )
3341 allCs->at(axesList.at(grIt)).at(2),
3342 allCs->at(axesList.at(grIt)).at(3),
3343 static_cast< proshade_signed
> ( allCs->at(axesList.at(grIt)).at(0) ) );
3351 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3354 const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 3.0 );
3355 if ( lhs1.AlmostEquals ( rhs1 ) )
3359 allCs->at(axesList.at(grIt)).at(2),
3360 allCs->at(axesList.at(grIt)).at(3),
3361 static_cast< proshade_signed
> ( allCs->at(axesList.at(grIt)).at(0) ) );
3369 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3372 const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 2.0 );
3373 if ( lhs1.AlmostEquals ( rhs1 ) )
3377 allCs->at(axesList.at(grIt)).at(2),
3378 allCs->at(axesList.at(grIt)).at(3),
3379 static_cast< proshade_signed
> ( allCs->at(axesList.at(grIt)).at(0) ) );
3390 throw ProSHADE_exception (
"Computed point group elements do not form a group.",
"ES00060", __FILE__, __LINE__, __func__,
"The supplied cyclic groups list does not form a group and\n : therefore such group's elements cannot be obtained. Please\n : check the cyclic groups list supplied to the\n : getAllGroupElements() function." );
3393 else if ( groupType ==
"X" )
3396 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3400 allCs->at(axesList.at(grIt)).at(2),
3401 allCs->at(axesList.at(grIt)).at(3),
3402 static_cast< proshade_signed
> ( allCs->at(axesList.at(grIt)).at(0) ) );
3412 throw ProSHADE_exception (
"Computed point group elements do not form a group.",
"ES00060", __FILE__, __LINE__, __func__,
"The supplied cyclic groups list does not form a group and\n : therefore such group's elements cannot be obtained. Please\n : check the cyclic groups list supplied to the\n : getAllGroupElements() function." );
3417 std::stringstream hlpSS;
3418 hlpSS <<
"Unknown symmetry type: >" << groupType <<
"<";
3419 throw ProSHADE_exception ( hlpSS.str().c_str(),
"ES00058", __FILE__, __LINE__, __func__,
"Function getAllGroupElements was called with symmetry type\n : value outside of the allowed values C, D, T, O, I\n : or empty for using all supplied axes." );
3434 if ( saveTo !=
nullptr )
3441 saveTo =
new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
3447 for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
3449 saveTo[iter] = this->internalMap[iter];
3466 if ( this->recommendedSymmetryType ==
"" || ( this->recommendedSymmetryType ==
"C" && this->recommendedSymmetryFold == 1 ) )
3473 std::stringstream ssHlp;
3474 std::vector< proshade_double > comMove = this->getMapCOMProcessChange ( );
3475 ssHlp << std::endl <<
"Detected " << this->recommendedSymmetryType <<
" symmetry with fold " << this->recommendedSymmetryFold <<
" about point [" << comMove.at(0) <<
" , " << comMove.at(1) <<
" , " << comMove.at(2) <<
"] away from centre of mass .";
3478 if ( this->recommendedSymmetryValues.size() > 0 )
3480 ssHlp.clear(); ssHlp.str (
"" );
3481 ssHlp <<
" Fold X Y Z Angle Height Average FSC";
3484 for (
size_t symIt = 0; symIt < this->recommendedSymmetryValues.size(); symIt++ )
3486 ssHlp.clear(); ssHlp.str (
"" );
3487 ssHlp << std::showpos << std::fixed << std::setprecision(0) <<
" " << this->recommendedSymmetryValues.at(symIt)[0] << std::setprecision(5) <<
" " << this->recommendedSymmetryValues.at(symIt)[1] <<
" " << this->recommendedSymmetryValues.at(symIt)[2] <<
" " << this->recommendedSymmetryValues.at(symIt)[3] <<
" " << this->recommendedSymmetryValues.at(symIt)[4] <<
" " << this->recommendedSymmetryValues.at(symIt)[5] <<
" " << this->recommendedSymmetryValues.at(symIt)[6];
3492 std::stringstream ssHlp, hlpSS3;
3493 ssHlp.clear(); ssHlp.str (
"" );
3494 hlpSS3 << std::endl <<
"To facilitate manual checking for symmetries, the following is a list of all detected C symmetries:";
3497 if ( this->cyclicSymmetries.size() > 0 )
3499 ssHlp.clear(); ssHlp.str (
"" );
3500 ssHlp <<
" Fold X Y Z Angle Height Average FSC";
3503 for (
size_t symIt = 0; symIt < this->cyclicSymmetries.size(); symIt++ )
3505 ssHlp.clear(); ssHlp.str (
"" );
3506 ssHlp << std::showpos << std::fixed << std::setprecision(0) <<
" " << this->cyclicSymmetries.at(symIt)[0] << std::setprecision(5) <<
" " << this->cyclicSymmetries.at(symIt)[1] <<
" " << this->cyclicSymmetries.at(symIt)[2] <<
" " << this->cyclicSymmetries.at(symIt)[3] <<
" " << this->cyclicSymmetries.at(symIt)[4] <<
" " << this->cyclicSymmetries.at(symIt)[5] <<
" " << this->cyclicSymmetries.at(symIt)[6];
3531 void ProSHADE_internal_data::ProSHADE_data::reportCurrentSymmetryResults (
ProSHADE_settings* settings, proshade_double threshold, proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_signed cutXDim, proshade_signed cutYDim, proshade_signed cutZDim )
3534 proshade_signed origVerbose = settings->
verbose;
3536 this->determineRecommendedSymmetry ( settings, threshold, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
3537 settings->
verbose = origVerbose;
3540 if ( this->recommendedSymmetryType ==
"" || ( this->recommendedSymmetryType ==
"C" && this->recommendedSymmetryFold == 1 ) )
3542 std::stringstream ssHlp;
3543 ssHlp << std::showpos << std::fixed << std::setprecision(2) <<
" " << threshold <<
" C +1 +0.00000 +0.00000 +0.00000 +0.00000 +1.00000 +1.00000" << std::endl <<
"===========================================================================================================";
3548 for (
size_t symIt = 0; symIt < this->recommendedSymmetryValues.size(); symIt++ )
3550 std::stringstream ssHlp;
3551 ssHlp << std::showpos << std::fixed << std::setprecision(2) <<
" " << threshold <<
" " << this->recommendedSymmetryType <<
" " << std::showpos << std::fixed << std::setprecision(0) <<
" " << this->recommendedSymmetryValues.at(symIt)[0] << std::setprecision(5) <<
" " << this->recommendedSymmetryValues.at(symIt)[1] <<
" " << this->recommendedSymmetryValues.at(symIt)[2] <<
" " << this->recommendedSymmetryValues.at(symIt)[3] <<
" " << this->recommendedSymmetryValues.at(symIt)[4] <<
" " << this->recommendedSymmetryValues.at(symIt)[5] <<
" " << this->recommendedSymmetryValues.at(symIt)[6];
3554 std::stringstream ssHlp;
3555 ssHlp <<
"===========================================================================================================";
3572 std::stringstream ssHlp;
3573 std::vector< proshade_double > thrLevels;
3583 fftw_complex* fCoeffsCut;
3584 proshade_double **bindata, *fscByBin;
3585 proshade_signed *cutIndices, *binCounts, noBins, cutXDim, cutYDim, cutZDim;
3586 this->prepareFSCFourierMemory ( cutIndices, fCoeffsCut, &noBins, bindata, binCounts, fscByBin, settings->
requestedResolution, &cutXDim, &cutYDim, &cutZDim );
3589 ssHlp.clear(); ssHlp.str (
"" );
3590 std::vector< proshade_double > comMove = this->getMapCOMProcessChange ( );
3591 ssHlp << std::endl <<
"Detecting symmetries about point [" << comMove.at(0) <<
" , " << comMove.at(1) <<
" , " << comMove.at(2) <<
"] away from centre of mass .";
3595 proshade_signed origVerbose = settings->
verbose;
3597 this->determineRecommendedSymmetry ( settings, settings->
fscThreshold, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
3598 settings->
verbose = origVerbose;
3601 ssHlp.clear(); ssHlp.str (
"" );
3602 ssHlp << std::endl <<
"ProSHADE default symmetry detection algorithm claims the symmetry to be " << this->recommendedSymmetryType <<
"-" << this->recommendedSymmetryFold <<
" with axes:" << std::endl <<
"======================================================================================";
3605 if ( this->recommendedSymmetryValues.size() > 0 )
3607 ssHlp.clear(); ssHlp.str (
"" );
3608 ssHlp <<
" Type Fold X Y Z Angle Height Average FSC";
3613 ssHlp.clear(); ssHlp.str (
"" );
3614 ssHlp <<
" Type Fold X Y Z Angle Height Average FSC" << std::endl <<
" C +1 +0.00000 +0.00000 +0.00000 +0.00000 +1.00000 +1.00000";
3617 for (
size_t symIt = 0; symIt < this->recommendedSymmetryValues.size(); symIt++ )
3619 ssHlp.clear(); ssHlp.str (
"" );
3620 ssHlp <<
" " << this->recommendedSymmetryType <<
" " << std::showpos << std::fixed << std::setprecision(0) <<
" " << this->recommendedSymmetryValues.at(symIt)[0] << std::setprecision(5) <<
" " << this->recommendedSymmetryValues.at(symIt)[1] <<
" " << this->recommendedSymmetryValues.at(symIt)[2] <<
" " << this->recommendedSymmetryValues.at(symIt)[3] <<
" " << this->recommendedSymmetryValues.at(symIt)[4] <<
" " << this->recommendedSymmetryValues.at(symIt)[5] <<
" " << this->recommendedSymmetryValues.at(symIt)[6];
3625 ssHlp.clear(); ssHlp.str (
"" );
3626 ssHlp << std::endl << std::endl <<
"Symmetry detection results per FSC threshold levels:" << std::endl <<
"====================================================";;
3629 ssHlp.clear(); ssHlp.str (
"" );
3630 ssHlp << std::endl <<
" Threshold Type Fold X Y Z Angle Height Average FSC" << std::endl <<
"===========================================================================================================";
3634 for (
size_t lIt = 0; lIt < thrLevels.size(); lIt++ )
3636 this->reportCurrentSymmetryResults ( settings, thrLevels.at(lIt), cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
3640 for (
size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) {
delete[] bindata[binIt]; }
3643 delete[] cutIndices;
3644 fftw_free ( fCoeffsCut );
3647 ssHlp.clear(); ssHlp.str (
"" );
3648 ssHlp << std::endl << std::endl <<
"To facilitate manual checking for symmetries, the following is a list of all detected C symmetries:";
3651 if ( this->cyclicSymmetries.size() > 0 )
3653 ssHlp.clear(); ssHlp.str (
"" );
3654 ssHlp <<
" Type Fold X Y Z Angle Height Average FSC";
3657 for (
size_t symIt = 0; symIt < this->cyclicSymmetries.size(); symIt++ )
3659 ssHlp.clear(); ssHlp.str (
"" );
3660 ssHlp <<
" C " << std::showpos << std::fixed << std::setprecision(0) <<
" " << this->cyclicSymmetries.at(symIt)[0] << std::setprecision(5) <<
" " << this->cyclicSymmetries.at(symIt)[1] <<
" " << this->cyclicSymmetries.at(symIt)[2] <<
" " << this->cyclicSymmetries.at(symIt)[3] <<
" " << this->cyclicSymmetries.at(symIt)[4] <<
" " << this->cyclicSymmetries.at(symIt)[5] <<
" " << this->cyclicSymmetries.at(symIt)[6];
3678 proshade_double totNonZeroPoints = 0.0;
3679 proshade_signed mapIt = 0;
3682 for ( proshade_signed xIt = 0; xIt < static_cast<proshade_signed> ( this->xDimIndices ); xIt++ )
3684 for ( proshade_signed yIt = 0; yIt < static_cast<proshade_signed> ( this->yDimIndices ); yIt++ )
3686 for ( proshade_signed zIt = 0; zIt < static_cast<proshade_signed> ( this->zDimIndices ); zIt++ )
3689 mapIt = zIt +
static_cast< proshade_signed
> ( this->zDimIndices ) * ( yIt +
static_cast< proshade_signed
> ( this->yDimIndices ) * xIt );
3692 if ( this->internalMap[mapIt] <= 0.0 ) {
continue; }
3695 this->xCom += this->internalMap[mapIt] *
static_cast<proshade_double
> ( xIt + this->xFrom );
3696 this->yCom += this->internalMap[mapIt] *
static_cast<proshade_double
> ( yIt + this->yFrom );
3697 this->zCom += this->internalMap[mapIt] *
static_cast<proshade_double
> ( zIt + this->zFrom );
3698 totNonZeroPoints += this->internalMap[mapIt];
3703 this->xCom /= totNonZeroPoints;
3704 this->yCom /= totNonZeroPoints;
3705 this->zCom /= totNonZeroPoints;
3708 this->xCom =
static_cast< proshade_double
> ( (
static_cast< proshade_single
> ( this->xFrom ) * ( this->xDimSizeOriginal /
static_cast< proshade_single
> ( this->xDimIndicesOriginal ) ) ) +
3709 ( (
static_cast< proshade_single
> ( this->xCom ) -
static_cast< proshade_single
> ( this->xFrom ) ) *
3710 (
static_cast< proshade_single
> ( this->xDimSizeOriginal ) /
static_cast< proshade_single
> ( this->xDimIndicesOriginal ) ) ) );
3711 this->yCom =
static_cast< proshade_double
> ( (
static_cast< proshade_single
> ( this->yFrom ) * ( this->yDimSizeOriginal /
static_cast< proshade_single
> ( this->yDimIndicesOriginal ) ) ) +
3712 ( (
static_cast< proshade_single
> ( this->yCom ) -
static_cast< proshade_single
> ( this->yFrom ) ) *
3713 (
static_cast< proshade_single
> ( this->yDimSizeOriginal ) /
static_cast< proshade_single
> ( this->yDimIndicesOriginal ) ) ) );
3714 this->zCom =
static_cast< proshade_double
> ( (
static_cast< proshade_single
> ( this->zFrom ) * ( this->zDimSizeOriginal /
static_cast< proshade_single
> ( this->zDimIndicesOriginal ) ) ) +
3715 ( (
static_cast< proshade_single
> ( this->zCom ) -
static_cast< proshade_single
> ( this->zFrom ) ) *
3716 (
static_cast< proshade_single
> ( this->zDimSizeOriginal ) /
static_cast< proshade_single
> ( this->zDimIndicesOriginal ) ) ) );
3730 return ( this->noSpheres );
3741 return ( this->internalMap[pos] );
3751 return ( this->maxShellBand );
3761 return ( this->rrpMatrices[band][sh1][sh2] );
3776 if ( this->spheres[shell]->getLocalBandwidth( ) >= bandVal )
3800 fftw_complex* mapCoeffs =
reinterpret_cast< fftw_complex*
> ( fftw_malloc (
sizeof ( fftw_complex ) * this->xDimIndices * this->yDimIndices * this->zDimIndices ) );
3801 fftw_complex* pattersonMap =
reinterpret_cast< fftw_complex*
> ( fftw_malloc (
sizeof ( fftw_complex ) * this->xDimIndices * this->yDimIndices * this->zDimIndices ) );
3808 for ( proshade_unsign iter = 0; iter < (this->xDimIndices * this->yDimIndices * this->zDimIndices); iter++ )
3810 pattersonMap[iter][0] = this->internalMap[iter];
3811 pattersonMap[iter][1] = 0.0;
3815 fftw_plan forward = fftw_plan_dft_3d (
static_cast< int > ( this->xDimIndices ),
static_cast< int > ( this->yDimIndices ),
static_cast< int > ( this->zDimIndices ),
3816 pattersonMap, mapCoeffs, FFTW_FORWARD, FFTW_ESTIMATE );
3817 fftw_plan inverse = fftw_plan_dft_3d (
static_cast< int > ( this->xDimIndices ),
static_cast< int > ( this->yDimIndices ),
static_cast< int > ( this->zDimIndices ),
3818 mapCoeffs, pattersonMap, FFTW_BACKWARD, FFTW_ESTIMATE );
3821 fftw_execute ( forward );
3827 fftw_execute ( inverse );
3830 proshade_signed mapIt, patIt, patX, patY, patZ;
3831 for ( proshade_signed xIt = 0; xIt < static_cast<proshade_signed> ( this->xDimIndices ); xIt++ )
3833 for ( proshade_signed yIt = 0; yIt < static_cast<proshade_signed> ( this->yDimIndices ); yIt++ )
3835 for ( proshade_signed zIt = 0; zIt < static_cast<proshade_signed> ( this->zDimIndices ); zIt++ )
3838 patX = xIt - (
static_cast<proshade_signed
> ( this->xDimIndices ) / 2 );
if ( patX < 0 ) { patX += this->xDimIndices; }
3839 patY = yIt - (
static_cast<proshade_signed
> ( this->yDimIndices ) / 2 );
if ( patY < 0 ) { patY += this->yDimIndices; }
3840 patZ = zIt - (
static_cast<proshade_signed
> ( this->zDimIndices ) / 2 );
if ( patZ < 0 ) { patZ += this->zDimIndices; }
3843 mapIt = zIt +
static_cast< proshade_signed
> ( this->zDimIndices ) * ( yIt +
static_cast< proshade_signed
> ( this->yDimIndices ) * xIt );
3844 patIt = patZ +
static_cast< proshade_signed
> ( this->zDimIndices ) * ( patY +
static_cast< proshade_signed
> ( this->yDimIndices ) * patX );
3847 this->internalMap[mapIt] = pattersonMap[patIt][0];
3853 fftw_free ( mapCoeffs );
3854 fftw_free ( pattersonMap );
3857 fftw_destroy_plan ( forward );
3858 fftw_destroy_plan ( inverse );
3863 this->xDimSize *= 2.0f;
3864 this->yDimSize *= 2.0f;
3865 this->zDimSize *= 2.0f;
3888 return ( &this->sphericalHarmonics[shell][seanindex (
static_cast< int > ( order ) -
static_cast< int > ( band ),
3889 static_cast< int > ( band ),
3890 static_cast< int > ( this->spheres[shell]->getLocalBandwidth() ) )][0] );
3905 return ( &this->sphericalHarmonics[shell][seanindex (
static_cast< int > ( order ) -
static_cast< int > ( band ),
3906 static_cast< int > ( band ),
3907 static_cast< int > ( this->spheres[shell]->getLocalBandwidth() ) )][1] );
3918 return ( this->spheres[shell]->getShellRadius() );
3929 return ( this->integrationWeight );
3941 return ( this->spheres[shell]->getLocalBandwidth ( ) );
3953 return ( this->spherePos.at(shell) );
3965 return ( this->eMatrices[band] );
3980 *valueReal = this->eMatrices[band][order1][order2][0];
3981 *valueImag = this->eMatrices[band][order1][order2][1];
3995 return ( this->so3CoeffsInverse );
4006 return ( this->so3Coeffs );
4017 return ( this->maxEMatDim );
4032 *valueReal = this->wignerMatrices[band][order1][order2][0];
4033 *valueImag = this->wignerMatrices[band][order1][order2][1];
4047 return ( this->xDimSize );
4057 return ( this->yDimSize );
4067 return ( this->zDimSize );
4077 return ( this->xDimIndices );
4087 return ( this->yDimIndices );
4097 return ( this->zDimIndices );
4107 return ( &this->xFrom );
4117 return ( &this->yFrom );
4127 return ( &this->zFrom );
4137 return ( &this->xTo );
4147 return ( &this->yTo );
4157 return ( &this->zTo );
4168 return ( &this->xAxisOrigin );
4179 return ( &this->yAxisOrigin );
4190 return ( &this->zAxisOrigin );
4201 return ( this->internalMap );
4212 return ( this->translationMap );
4223 std::vector< proshade_double > ret;
4242 return ( &this->cyclicSymmetries );
4254 std::vector< proshade_double* > ret;
4257 for (
size_t aIt = 0; aIt < this->cyclicSymmetries.size(); aIt++ )
4274 return ( &this->dihedralSymmetries );
4285 std::vector< std::vector< proshade_double* > > ret;
4288 for (
size_t aIt = 0; aIt < this->dihedralSymmetries.size(); aIt++ )
4290 std::vector< proshade_double* > hlpVec;
4308 this->integrationWeight = intW;
4322 this->integrationWeight += intW;
4339 this->eMatrices[band][order1][order2][0] = val[0];
4340 this->eMatrices[band][order1][order2][1] = val[1];
4357 this->eMatrices[band][order1][order2][0] /= normF;
4358 this->eMatrices[band][order1][order2][1] /= normF;
4373 this->so3Coeffs[position][0] = val[0];
4374 this->so3Coeffs[position][1] = val[1];
4391 this->wignerMatrices[band][order1][order2][0] = val[0];
4392 this->wignerMatrices[band][order1][order2][1] = val[1];
4409 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4411 eMatsLMReal[iter] =
static_cast<double> ( this->eMatrices[band][order1][iter][0] );
4429 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4431 eMatsLMImag[iter] =
static_cast<double> ( this->eMatrices[band][order1][iter][1] );
4447 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4449 so3CoefsReal[iter] =
static_cast<double> ( this->so3Coeffs[iter][0] );
4465 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4467 so3CoefsImag[iter] =
static_cast<double> ( this->so3Coeffs[iter][1] );
4487 return (
static_cast<int> ( so3CoefLoc (
static_cast< int > ( order1 ),
static_cast< int > ( order2 ),
static_cast< int > ( band ),
static_cast< int > ( this->getEMatDim() ) ) ) );
4498 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4500 rotFunReal[iter] =
static_cast<double> ( this->so3CoeffsInverse[iter][0] );
4516 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4518 rotFunImag[iter] =
static_cast<double> ( this->so3CoeffsInverse[iter][1] );
4534 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4536 trsFunReal[iter] =
static_cast<double> ( this->translationMap[iter][0] );
4552 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4554 trsFunImag[iter] =
static_cast<double> ( this->translationMap[iter][1] );
4573 proshade_double eA, eB, eG;
4577 proshade_double* rMat =
nullptr;
4578 rMat =
new proshade_double[9];
4585 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4587 rotMat[iter] =
static_cast<double> ( rMat[iter] );
4603 return ( this->recommendedSymmetryType );
4612 return ( this->recommendedSymmetryFold );
4621 std::vector< proshade_double* > ret;
4624 for (
size_t aIt = 0; aIt < this->recommendedSymmetryValues.size(); aIt++ )
4641 return (
static_cast< proshade_unsign
> ( this->recommendedSymmetryValues.size() ) );
4653 if (
static_cast<proshade_unsign
> ( this->recommendedSymmetryValues.size() ) <= axisNo )
4656 return ( std::vector< std::string > ( ) );
4660 std::vector< std::string > ret;
4663 std::stringstream ssHlp;
4664 ssHlp << this->recommendedSymmetryValues.at(axisNo)[0];
4668 ssHlp << this->recommendedSymmetryValues.at(axisNo)[1];
4672 ssHlp << this->recommendedSymmetryValues.at(axisNo)[2];
4676 ssHlp << this->recommendedSymmetryValues.at(axisNo)[3];
4680 ssHlp << this->recommendedSymmetryValues.at(axisNo)[4];
4684 ssHlp << this->recommendedSymmetryValues.at(axisNo)[5];
4688 ssHlp << this->recommendedSymmetryValues.at(axisNo)[6];
4712 std::stringstream fNameHlp;
4714 this->writeMap ( fNameHlp.str() );
4721 this->writePdb ( fNameHlp.str(), eulA, eulB, eulG, ultimateTranslation->at(0), ultimateTranslation->at(1), ultimateTranslation->at(2), rotCentre->at(0), rotCentre->at(1), rotCentre->at(2), settings->
firstModelOnly );
4727 ultimateTranslation->at(0), ultimateTranslation->at(1), ultimateTranslation->at(2),
4749 std::stringstream rotCen; rotCen << std::setprecision (3) << std::showpos <<
"The rotation centre to origin translation vector is: " << -rotationCentre->at(0) <<
" " << -rotationCentre->at(1) <<
" " << -rotationCentre->at(2);
4753 proshade_double* rotMat =
new proshade_double[9];
4757 std::stringstream rotMatSS;
4758 rotMatSS << std::setprecision (3) << std::showpos <<
"The rotation matrix about origin is : " << rotMat[0] <<
" " << rotMat[1] <<
" " << rotMat[2] << std::endl;
4759 rotMatSS << std::setprecision (3) << std::showpos <<
" : " << rotMat[3] <<
" " << rotMat[4] <<
" " << rotMat[5] << std::endl;
4760 rotMatSS << std::setprecision (3) << std::showpos <<
" : " << rotMat[6] <<
" " << rotMat[7] <<
" " << rotMat[8];
4766 std::stringstream finTrs; finTrs << std::setprecision (3) << std::showpos <<
"The rotation centre to overlay translation vector is: " << finalTranslation->at(0) <<
" " << finalTranslation->at(1) <<
" " << finalTranslation->at(2);