41 std::vector< proshade_double* > ret;
42 std::vector< proshade_double > nonPeakVals;
43 proshade_double* retHlp =
nullptr;
44 proshade_double pointHeight = 0.0;
45 proshade_signed x, y, z, peakX, peakY, peakZ, newIter, ptrIter;
46 proshade_signed xDim =
static_cast< proshade_signed
> ( std::pow ( dim, 2 ) );
47 proshade_signed yDim =
static_cast< proshade_signed
> ( dim );
51 for ( proshade_signed iter = 0; iter < static_cast< proshade_signed > ( pow(
static_cast<proshade_unsign
> ( dim ), 3 ) ); iter++ )
54 pointHeight = pow( map[iter][0], 2.0 ) + pow( map[iter][1], 2.0 );
57 x =
static_cast< proshade_signed
> ( std::floor ( iter / xDim ) );
58 y =
static_cast< proshade_signed
> ( std::floor ( ( iter - x * xDim ) / yDim ) );
59 z =
static_cast< proshade_signed
> ( iter - x * xDim - y * yDim );
62 if ( retHlp ==
nullptr )
64 retHlp =
new proshade_double[
static_cast<proshade_unsign
>( pow( ((peakSize*2)+1), 3) * 4 )];
71 for ( proshade_signed xCh = -peakSize; xCh <= +peakSize; xCh++ )
73 if ( breakPeak ) {
break; }
74 for ( proshade_signed yCh = -peakSize; yCh <= +peakSize; yCh++ )
76 if ( breakPeak ) {
break; }
77 for ( proshade_signed zCh = -peakSize; zCh <= +peakSize; zCh++ )
79 if ( breakPeak ) {
break; }
80 if ( ( xCh == 0 ) && ( yCh == 0 ) && ( zCh == 0 ) ) {
continue; }
83 peakX = x + xCh;
if ( peakX >= yDim ) { peakX = yDim - 1; };
if ( peakX < 0 ) { peakX = 0; }
84 peakY = y + yCh;
if ( peakY >= yDim ) { peakY = yDim - 1; };
if ( peakY < 0 ) { peakY = 0; }
85 peakZ = z + zCh;
if ( peakZ >= yDim ) { peakZ = yDim - 1; };
if ( peakZ < 0 ) { peakZ = 0; }
86 newIter = peakX * xDim + peakY * yDim + peakZ;
89 if ( ( pow ( map[newIter][0], 2.0 ) + pow( map[newIter][1], 2.0 ) ) > pointHeight ) { breakPeak =
true;
break; }
92 retHlp[ptrIter] =
static_cast<proshade_double
> ( peakX );
93 retHlp[ptrIter+1] =
static_cast<proshade_double
> ( peakY );
94 retHlp[ptrIter+2] =
static_cast<proshade_double
> ( peakZ );
95 retHlp[ptrIter+3] = pow ( map[newIter][0], 2.0 ) + pow( map[newIter][1], 2.0 );
103 retHlp[0] =
static_cast< proshade_double
> ( x );
104 retHlp[1] =
static_cast< proshade_double
> ( y );
105 retHlp[2] =
static_cast< proshade_double
> ( z );
106 retHlp[3] = pointHeight;
115 if ( retHlp !=
nullptr ) {
delete[] retHlp; }
135 proshade_double backgroundThreshold = std::min ( std::max ( medianIQR[0] + ( medianIQR[1] * noIQRs ), 0.05 ), 0.5 );
138 for ( proshade_signed iter =
static_cast<proshade_signed
> ( pointVec->size()-1 ); iter >= 0 ; iter-- )
140 if ( pointVec->at(
static_cast< size_t > ( iter ) )[3] <= backgroundThreshold )
142 delete[] pointVec->at(
static_cast< size_t > ( iter ) );
143 pointVec->erase ( pointVec->begin() + iter );
164 avgMat =
new proshade_double [9];
165 hlpMat =
new proshade_double [9];
166 eA =
new proshade_double;
167 eB =
new proshade_double;
168 eG =
new proshade_double;
169 uAV =
new proshade_double [18];
224 proshade_double *avgMat, *hlpMat, *eulA, *eulB, *eulG, *uAndV;
225 proshade_unsign noPoints =
static_cast< proshade_unsign
> ( std::pow( ( ( peakSize * 2 ) + 1 ), 3 ) * 4 );
226 proshade_double matWeight;
232 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( pointVec->size() ); iter++ )
235 for ( proshade_unsign i = 0; i < 9; i++ ) { avgMat[i] = 0.0; }
239 for ( proshade_unsign it = 0; it < noPoints; it += 4 )
242 ProSHADE_internal_maths::getEulerZYZFromSOFTPosition ( band,
static_cast< proshade_signed
> ( pointVec->at(iter)[it+0] ),
static_cast< proshade_signed
> ( pointVec->at(iter)[it+1] ),
static_cast< proshade_signed
> ( pointVec->at(iter)[it+2] ), eulA, eulB, eulG );
248 for ( proshade_unsign i = 0; i < 9; i++ ) { avgMat[i] += hlpMat[i] * pointVec->at(iter)[it+3]; }
251 matWeight += pointVec->at(iter)[it+3];
255 for ( proshade_unsign i = 0; i < 9; i++ ) { avgMat[i] /= matWeight; }
259 const FloatingPoint< proshade_double > lhs ( uAndV[0] ), rhs ( -777.7 );
260 if ( lhs.AlmostEquals ( rhs ) )
264 matWeight = pointVec->at(iter)[3];
265 pointVec->at(iter) =
new proshade_double [4];
267 pointVec->at(iter)[0] = *eulA;
268 pointVec->at(iter)[1] = *eulB;
269 pointVec->at(iter)[2] = *eulG;
270 pointVec->at(iter)[3] = matWeight;
276 for ( proshade_unsign i = 0; i < 9; i++ ) { avgMat[i] = 0.0; }
283 matWeight = pointVec->at(iter)[3];
284 delete[] pointVec->at(iter);
285 pointVec->at(iter) =
new proshade_double [4];
287 pointVec->at(iter)[0] = *eulA;
288 pointVec->at(iter)[1] = *eulB;
289 pointVec->at(iter)[2] = *eulG;
290 pointVec->at(iter)[3] = matWeight;
319 std::vector< proshade_double* > allHigherIndices;
320 proshade_double* nonPeakMedianIQR =
new proshade_double[2];
331 delete[] nonPeakMedianIQR;
334 return ( allHigherIndices );
361 std::stringstream hlpSSP;
362 hlpSSP <<
"Found " << allPeaks.size() <<
" possible peaks.";
366 if ( allPeaks.size() == 0 )
375 proshade_double highestPeak = 0.0;
376 proshade_unsign highestPeakIndex = 0;
377 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign>( allPeaks.size() ); iter++ )
379 if ( allPeaks.at(iter)[3] > highestPeak ) { highestPeak = allPeaks.at(iter)[3]; highestPeakIndex = iter; }
383 *eulA = allPeaks.at(highestPeakIndex)[0];
384 *eulB = allPeaks.at(highestPeakIndex)[1];
385 *eulG = allPeaks.at(highestPeakIndex)[2];
388 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( allPeaks.size() ); iter++ )
390 delete[] allPeaks.at(iter);
394 std::stringstream hlpSS;
395 hlpSS <<
"Optimal Euler angles are " << *eulA <<
" ; " << *eulB <<
" ; " << *eulG <<
" with peak height " << highestPeak;
419 void ProSHADE_internal_peakSearch::allocateSmoothingZScoreMemory ( proshade_unsign dim, proshade_double*& scoreOverVals, proshade_signed*& signals, proshade_double*& filteredY, proshade_double*& avgFilter, proshade_double*& stdFilter, proshade_double*& subVec, proshade_double*& medianIQR, proshade_double*& YZMap, proshade_double*& XZMap, proshade_double*& XYMap, proshade_unsign smLag )
422 signals =
new proshade_signed[dim];
423 scoreOverVals =
new proshade_double[dim];
424 filteredY =
new proshade_double[dim];
425 avgFilter =
new proshade_double[dim];
426 stdFilter =
new proshade_double[dim];
427 subVec =
new proshade_double[smLag];
428 medianIQR =
new proshade_double[2];
429 YZMap =
new proshade_double[dim * dim * dim];
430 XZMap =
new proshade_double[dim * dim * dim];
431 XYMap =
new proshade_double[dim * dim * dim];
463 void ProSHADE_internal_peakSearch::releaseSmoothingZScoreMemory ( proshade_double*& scoreOverVals, proshade_signed*& signals, proshade_double*& filteredY, proshade_double*& avgFilter, proshade_double*& stdFilter, proshade_double*& subVec, proshade_double*& medianIQR, proshade_double*& YZMap, proshade_double*& XZMap, proshade_double*& XYMap )
466 delete[] scoreOverVals;
501 void ProSHADE_internal_peakSearch::getSmoothedZScore1D ( proshade_unsign dim, proshade_unsign smoothingLag, proshade_double ZScoreThreshold, proshade_signed* signals, proshade_double* filteredY, proshade_double* avgFilter, proshade_double* stdFilter, proshade_double* subVec, proshade_double* medianIQR, proshade_double* scoreOverVals )
504 for ( proshade_unsign i = 0; i < dim; i++ ) { signals[i] = 0; avgFilter[i] = 0.0; stdFilter[i] = 0.0; filteredY[i] = 0.0; }
505 for ( proshade_unsign i = 0; i < smoothingLag; i++ ) { subVec[i] = scoreOverVals[i-smoothingLag+dim]; }
507 avgFilter[0] = medianIQR[0];
508 stdFilter[0] = medianIQR[1];
511 for ( proshade_unsign i = 0; i < dim; i++)
514 if ( std::abs ( scoreOverVals[i] - avgFilter[i]) > ZScoreThreshold * stdFilter[i] )
516 if ( scoreOverVals[i] > avgFilter[i] )
526 if ( i != 0 ) { filteredY[i] = 0.5 * scoreOverVals[i] + (1 - 0.5) * filteredY[i - 1]; }
527 else { filteredY[i] = 0.5 * scoreOverVals[i]; }
532 filteredY[i] = scoreOverVals[i];
536 for ( proshade_signed subIt = 0; subIt < static_cast<proshade_signed> ( smoothingLag ); subIt++ )
538 if ( (
static_cast<proshade_signed
>(i) +
static_cast<proshade_signed
>(subIt) -
static_cast<proshade_signed
>(smoothingLag) + 1 ) < 0 )
540 subVec[subIt] = scoreOverVals[( i +
static_cast< proshade_unsign
> ( subIt ) - smoothingLag + 1 ) + dim];
544 subVec[subIt] = filteredY[( i +
static_cast< proshade_unsign
> ( subIt ) - smoothingLag + 1 )];
548 avgFilter[i+1] = medianIQR[0];
549 stdFilter[i+1] = medianIQR[1];
576 void ProSHADE_internal_peakSearch::getXAxisArraysSmoothedZScorePeaks ( proshade_unsign dim, proshade_unsign smoothingLag, proshade_double ZScoreThreshold, proshade_signed* signals, proshade_double* filteredY, proshade_double* avgFilter, proshade_double* stdFilter, proshade_double* subVec, proshade_double* medianIQR, proshade_double* scoreOverVals, proshade_complex* map, proshade_double* YZMap )
579 for ( proshade_unsign yIt = 0; yIt < dim; yIt++ )
581 for ( proshade_unsign zIt = 0; zIt < dim; zIt++ )
584 for ( proshade_unsign xIt = 0; xIt < dim; xIt++ )
586 scoreOverVals[xIt] = pow ( map[xIt *
static_cast<proshade_unsign
>(4 * pow ( ( dim / 2 ), 2 )) + yIt * dim + zIt][0], 2.0 ) +
587 pow ( map[xIt *
static_cast<proshade_unsign
>(4 * pow ( ( dim / 2 ), 2 )) + yIt * dim + zIt][1], 2.0 );
591 getSmoothedZScore1D ( dim, smoothingLag, ZScoreThreshold, signals, filteredY, avgFilter, stdFilter, subVec, medianIQR, scoreOverVals );
594 for ( proshade_unsign xIt = 0; xIt < dim; xIt++ )
596 YZMap[xIt *
static_cast< proshade_unsign
> (4 * pow ( ( dim / 2 ), 2 )) + yIt * dim + zIt] =
static_cast< proshade_double
> ( signals[xIt] );
625 void ProSHADE_internal_peakSearch::getYAxisArraysSmoothedZScorePeaks ( proshade_unsign dim, proshade_unsign smoothingLag, proshade_double ZScoreThreshold, proshade_signed* signals, proshade_double* filteredY, proshade_double* avgFilter, proshade_double* stdFilter, proshade_double* subVec, proshade_double* medianIQR, proshade_double* scoreOverVals, proshade_complex* map, proshade_double* XZMap )
628 for ( proshade_unsign xIt = 0; xIt < dim; xIt++ )
630 for ( proshade_unsign zIt = 0; zIt < dim; zIt++ )
633 for ( proshade_unsign yIt = 0; yIt < dim; yIt++ )
635 scoreOverVals[yIt] = pow ( map[xIt *
static_cast<proshade_unsign
>(4 * pow ( ( dim / 2 ), 2 )) + yIt * dim + zIt][0], 2.0 ) +
636 pow ( map[xIt *
static_cast<proshade_unsign
>(4 * pow ( ( dim / 2 ), 2 )) + yIt * dim + zIt][1], 2.0 );
640 getSmoothedZScore1D ( dim, smoothingLag, ZScoreThreshold, signals, filteredY, avgFilter, stdFilter, subVec, medianIQR, scoreOverVals );
643 for ( proshade_unsign yIt = 0; yIt < dim; yIt++ )
645 XZMap[xIt *
static_cast< proshade_unsign
> (4 * pow ( ( dim / 2 ), 2 )) + yIt * dim + zIt] =
static_cast< proshade_double
> ( signals[xIt] );
674 void ProSHADE_internal_peakSearch::getZAxisArraysSmoothedZScorePeaks ( proshade_unsign dim, proshade_unsign smoothingLag, proshade_double ZScoreThreshold, proshade_signed* signals, proshade_double* filteredY, proshade_double* avgFilter, proshade_double* stdFilter, proshade_double* subVec, proshade_double* medianIQR, proshade_double* scoreOverVals, proshade_complex* map, proshade_double* XYMap )
677 for ( proshade_unsign xIt = 0; xIt < dim; xIt++ )
679 for ( proshade_unsign yIt = 0; yIt < dim; yIt++ )
682 for ( proshade_unsign zIt = 0; zIt < dim; zIt++ )
684 scoreOverVals[yIt] = pow ( map[xIt *
static_cast<proshade_unsign
>(4 * pow ( ( dim / 2 ), 2 )) + yIt * dim + zIt][0], 2.0 ) +
685 pow ( map[xIt *
static_cast<proshade_unsign
>(4 * pow ( ( dim / 2 ), 2 )) + yIt * dim + zIt][1], 2.0 );
689 getSmoothedZScore1D ( dim, smoothingLag, ZScoreThreshold, signals, filteredY, avgFilter, stdFilter, subVec, medianIQR, scoreOverVals );
692 for ( proshade_unsign zIt = 0; zIt < dim; zIt++ )
694 XYMap[xIt *
static_cast< proshade_unsign
> (4 * pow ( ( dim / 2 ), 2 )) + yIt * dim + zIt] =
static_cast< proshade_double
> ( signals[xIt] );
719 void ProSHADE_internal_peakSearch::findAllPointNeighbours ( proshade_double* YZMap, proshade_double* XZMap, proshade_double* XYMap, proshade_unsign* visitedMap, proshade_signed dim, proshade_signed x, proshade_signed y, proshade_signed z, std::vector< proshade_unsign >* retVals )
722 proshade_signed newIter = 0;
723 proshade_signed peakX, peakY, peakZ;
724 proshade_signed xDim =
static_cast<proshade_signed
>(4 * pow ( ( dim / 2 ), 2 ));
727 for ( proshade_signed xCh = -1; xCh <= +1; xCh++ )
729 for ( proshade_signed yCh = -1; yCh <= +1; yCh++ )
731 for ( proshade_signed zCh = -1; zCh <= +1; zCh++ )
734 if ( ( xCh == 0 ) && ( yCh == 0 ) && ( zCh == 0 ) ) {
continue; }
737 peakX = x + xCh;
if ( peakX >= dim ) { peakX -= dim; };
if ( peakX < 0 ) { peakX += dim; }
738 peakY = y + yCh;
if ( peakY >= dim ) { peakY -= dim; };
if ( peakY < 0 ) { peakY += dim; }
739 peakZ = z + zCh;
if ( peakZ >= dim ) { peakZ -= dim; };
if ( peakZ < 0 ) { peakZ += dim; }
740 newIter = peakX * xDim + peakY * dim + peakZ;
743 if ( visitedMap[newIter] == 1 ) {
continue; }
744 else { visitedMap[newIter] = 1; }
747 const FloatingPoint< proshade_double > lhs ( YZMap[newIter] + XZMap[newIter] + XYMap[newIter] ), rhs ( 3.0 );
748 if ( lhs.AlmostEquals ( rhs ) ) {
continue; }
781 std::vector< proshade_unsign > ret;
782 std::vector< proshade_unsign > thisIsland;
783 proshade_unsign* visitedMap =
new proshade_unsign[dim*dim*dim];
785 for ( proshade_unsign i = 0; i < ( dim * dim * dim ); i++ ) { visitedMap[i] = 0; }
786 proshade_unsign index, maxIndex;
787 proshade_double maxHeight;
790 for ( proshade_unsign xIt = 0; xIt < dim; xIt++ )
792 for ( proshade_unsign yIt = 0; yIt < dim; yIt++ )
794 for ( proshade_unsign zIt = 0; zIt < dim; zIt++ )
797 index = xIt *
static_cast<proshade_unsign
>(4 * pow ( ( dim / 2 ), 2 )) + yIt * dim + zIt;
800 if ( visitedMap[index] == 1 ) {
continue; }
801 else { visitedMap[index] = 1; }
804 const FloatingPoint< proshade_double > lhs ( YZMap[index] + XZMap[index] + XYMap[index] ), rhs ( 3.0 );
805 if ( !lhs.AlmostEquals ( rhs ) ) {
continue; }
808 thisIsland.clear ( );
812 findAllPointNeighbours ( YZMap, XZMap, XYMap, visitedMap,
static_cast<proshade_signed
>(dim),
static_cast<proshade_signed
>(xIt),
static_cast<proshade_signed
>(yIt),
static_cast<proshade_signed
>(zIt), &thisIsland );
817 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( thisIsland.size() ); iter++ )
819 if ( ( pow( map[thisIsland.at(iter)][0], 2.0 ) + pow( map[thisIsland.at(iter)][1], 2.0) ) > maxHeight )
821 maxHeight = pow( map[thisIsland.at(iter)][0], 2.0 ) + pow( map[thisIsland.at(iter)][1], 2.0 );
822 maxIndex = thisIsland.at(iter);
857 proshade_signed x, y, z, peakX, peakY, peakZ, newIter, ptrIter;
858 proshade_unsign noNeighbours =
static_cast< proshade_unsign
> ( std::pow( ( ( peakSize * 2 ) + 1 ), 3 ) * 4 );
861 std::vector < proshade_unsign > allPeaksRepresentatives;
865 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( allPeaksRepresentatives.size() ); iter++ )
871 z = (
static_cast< proshade_signed
> ( allPeaksRepresentatives.at(iter) ) % (dim*dim) ) % dim;
872 y = (
static_cast< proshade_signed
> ( allPeaksRepresentatives.at(iter) ) - z ) % (dim*dim) / dim;
873 x = (
static_cast< proshade_signed
> ( allPeaksRepresentatives.at(iter) ) - z - ( y * dim ) ) / (dim*dim);
876 proshade_double* neighbours =
new proshade_double[noNeighbours];
881 for ( proshade_signed xCh = -peakSize; xCh <= +peakSize; xCh++ )
883 for ( proshade_signed yCh = -peakSize; yCh <= +peakSize; yCh++ )
885 for ( proshade_signed zCh = -peakSize; zCh <= +peakSize; zCh++ )
888 peakX = x + xCh;
if ( peakX >= dim ) { peakX -= dim; };
if ( peakX < 0 ) { peakX += dim; }
889 peakY = y + yCh;
if ( peakY >= dim ) { peakY -= dim; };
if ( peakY < 0 ) { peakY += dim; }
890 peakZ = z + zCh;
if ( peakZ >= dim ) { peakZ -= dim; };
if ( peakZ < 0 ) { peakZ += dim; }
891 newIter = peakX * (dim*dim) + peakY * dim + peakZ;
894 allPeaksWithNeighbours->at(iter)[ptrIter] =
static_cast<proshade_double
> ( peakX );
895 allPeaksWithNeighbours->at(iter)[ptrIter+1] =
static_cast<proshade_double
> ( peakY );
896 allPeaksWithNeighbours->at(iter)[ptrIter+2] =
static_cast<proshade_double
> ( peakZ );
897 allPeaksWithNeighbours->at(iter)[ptrIter+3] = pow ( map[newIter][0], 2.0 ) + pow( map[newIter][1], 2.0 );
926 std::vector< proshade_double* > allHigherIndices;
927 proshade_unsign smoothingLag =
static_cast< proshade_unsign
> ( std::floor ( smoothingFraction *
static_cast< proshade_double
> ( dim ) ) );
928 proshade_double ZScoreThreshold = noIQRs;
929 proshade_signed *signals;
930 proshade_double *scoreOverVals, *filteredY, *avgFilter, *stdFilter, *subVec, *medianIQR, *YZMap, *XZMap, *XYMap;
933 if ( dim <= smoothingLag + 2)
939 allocateSmoothingZScoreMemory ( dim, scoreOverVals, signals, filteredY, avgFilter, stdFilter, subVec, medianIQR, YZMap, XZMap, XYMap, smoothingLag );
942 getXAxisArraysSmoothedZScorePeaks ( dim, smoothingLag, ZScoreThreshold, signals, filteredY, avgFilter, stdFilter, subVec, medianIQR, scoreOverVals, map, YZMap );
945 getYAxisArraysSmoothedZScorePeaks ( dim, smoothingLag, ZScoreThreshold, signals, filteredY, avgFilter, stdFilter, subVec, medianIQR, scoreOverVals, map, XZMap );
948 getZAxisArraysSmoothedZScorePeaks ( dim, smoothingLag, ZScoreThreshold, signals, filteredY, avgFilter, stdFilter, subVec, medianIQR, scoreOverVals, map, XYMap );
960 return ( allHigherIndices );
979 std::vector< proshade_double* > allPeaks =
getAllPeaksSmoothedZ ( map, dim, smoothingFraction, noIQRs, peakSize );
982 proshade_double highestPeak = 0.0;
983 proshade_unsign highestPeakIndex = 0;
984 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign>( allPeaks.size() ); iter++ )
986 if ( allPeaks.at(iter)[4] > highestPeak ) { highestPeak = allPeaks.at(iter)[4]; highestPeakIndex = iter; }
990 proshade_double* rotMat =
new proshade_double[9];
997 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( allPeaks.size() ); iter++ )
999 delete[] allPeaks.at(iter);